diff options
63 files changed, 2620 insertions, 1748 deletions
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index a34fa4705ebf..ac76a8b0baaa 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl | |||
@@ -3989,6 +3989,7 @@ int num_ioctls;</synopsis> | |||
3989 | <title>High Definition Audio</title> | 3989 | <title>High Definition Audio</title> |
3990 | !Pdrivers/gpu/drm/i915/intel_audio.c High Definition Audio over HDMI and Display Port | 3990 | !Pdrivers/gpu/drm/i915/intel_audio.c High Definition Audio over HDMI and Display Port |
3991 | !Idrivers/gpu/drm/i915/intel_audio.c | 3991 | !Idrivers/gpu/drm/i915/intel_audio.c |
3992 | !Iinclude/drm/i915_component.h | ||
3992 | </sect2> | 3993 | </sect2> |
3993 | <sect2> | 3994 | <sect2> |
3994 | <title>Panel Self Refresh PSR (PSR/SRD)</title> | 3995 | <title>Panel Self Refresh PSR (PSR/SRD)</title> |
diff --git a/drivers/gpu/drm/i915/dvo.h b/drivers/gpu/drm/i915/dvo.h index 312163379db9..0e2c1b9648a7 100644 --- a/drivers/gpu/drm/i915/dvo.h +++ b/drivers/gpu/drm/i915/dvo.h | |||
@@ -94,8 +94,8 @@ struct intel_dvo_dev_ops { | |||
94 | * after this function is called. | 94 | * after this function is called. |
95 | */ | 95 | */ |
96 | void (*mode_set)(struct intel_dvo_device *dvo, | 96 | void (*mode_set)(struct intel_dvo_device *dvo, |
97 | struct drm_display_mode *mode, | 97 | const struct drm_display_mode *mode, |
98 | struct drm_display_mode *adjusted_mode); | 98 | const struct drm_display_mode *adjusted_mode); |
99 | 99 | ||
100 | /* | 100 | /* |
101 | * Probe for a connected output, and return detect_status. | 101 | * Probe for a connected output, and return detect_status. |
diff --git a/drivers/gpu/drm/i915/dvo_ch7017.c b/drivers/gpu/drm/i915/dvo_ch7017.c index 86b27d1d90c2..cbb22027a3ce 100644 --- a/drivers/gpu/drm/i915/dvo_ch7017.c +++ b/drivers/gpu/drm/i915/dvo_ch7017.c | |||
@@ -255,8 +255,8 @@ static enum drm_mode_status ch7017_mode_valid(struct intel_dvo_device *dvo, | |||
255 | } | 255 | } |
256 | 256 | ||
257 | static void ch7017_mode_set(struct intel_dvo_device *dvo, | 257 | static void ch7017_mode_set(struct intel_dvo_device *dvo, |
258 | struct drm_display_mode *mode, | 258 | const struct drm_display_mode *mode, |
259 | struct drm_display_mode *adjusted_mode) | 259 | const struct drm_display_mode *adjusted_mode) |
260 | { | 260 | { |
261 | uint8_t lvds_pll_feedback_div, lvds_pll_vco_control; | 261 | uint8_t lvds_pll_feedback_div, lvds_pll_vco_control; |
262 | uint8_t outputs_enable, lvds_control_2, lvds_power_down; | 262 | uint8_t outputs_enable, lvds_control_2, lvds_power_down; |
diff --git a/drivers/gpu/drm/i915/dvo_ch7xxx.c b/drivers/gpu/drm/i915/dvo_ch7xxx.c index 80449f475960..4b4acc1a06fe 100644 --- a/drivers/gpu/drm/i915/dvo_ch7xxx.c +++ b/drivers/gpu/drm/i915/dvo_ch7xxx.c | |||
@@ -275,8 +275,8 @@ static enum drm_mode_status ch7xxx_mode_valid(struct intel_dvo_device *dvo, | |||
275 | } | 275 | } |
276 | 276 | ||
277 | static void ch7xxx_mode_set(struct intel_dvo_device *dvo, | 277 | static void ch7xxx_mode_set(struct intel_dvo_device *dvo, |
278 | struct drm_display_mode *mode, | 278 | const struct drm_display_mode *mode, |
279 | struct drm_display_mode *adjusted_mode) | 279 | const struct drm_display_mode *adjusted_mode) |
280 | { | 280 | { |
281 | uint8_t tvco, tpcp, tpd, tlpf, idf; | 281 | uint8_t tvco, tpcp, tpd, tlpf, idf; |
282 | 282 | ||
diff --git a/drivers/gpu/drm/i915/dvo_ivch.c b/drivers/gpu/drm/i915/dvo_ivch.c index 732ce8785945..ff9f1b077d83 100644 --- a/drivers/gpu/drm/i915/dvo_ivch.c +++ b/drivers/gpu/drm/i915/dvo_ivch.c | |||
@@ -394,8 +394,8 @@ static bool ivch_get_hw_state(struct intel_dvo_device *dvo) | |||
394 | } | 394 | } |
395 | 395 | ||
396 | static void ivch_mode_set(struct intel_dvo_device *dvo, | 396 | static void ivch_mode_set(struct intel_dvo_device *dvo, |
397 | struct drm_display_mode *mode, | 397 | const struct drm_display_mode *mode, |
398 | struct drm_display_mode *adjusted_mode) | 398 | const struct drm_display_mode *adjusted_mode) |
399 | { | 399 | { |
400 | struct ivch_priv *priv = dvo->dev_priv; | 400 | struct ivch_priv *priv = dvo->dev_priv; |
401 | uint16_t vr40 = 0; | 401 | uint16_t vr40 = 0; |
@@ -414,16 +414,16 @@ static void ivch_mode_set(struct intel_dvo_device *dvo, | |||
414 | vr40 = (VR40_STALL_ENABLE | VR40_VERTICAL_INTERP_ENABLE | | 414 | vr40 = (VR40_STALL_ENABLE | VR40_VERTICAL_INTERP_ENABLE | |
415 | VR40_HORIZONTAL_INTERP_ENABLE); | 415 | VR40_HORIZONTAL_INTERP_ENABLE); |
416 | 416 | ||
417 | if (mode->hdisplay != adjusted_mode->hdisplay || | 417 | if (mode->hdisplay != adjusted_mode->crtc_hdisplay || |
418 | mode->vdisplay != adjusted_mode->vdisplay) { | 418 | mode->vdisplay != adjusted_mode->crtc_vdisplay) { |
419 | uint16_t x_ratio, y_ratio; | 419 | uint16_t x_ratio, y_ratio; |
420 | 420 | ||
421 | vr01 |= VR01_PANEL_FIT_ENABLE; | 421 | vr01 |= VR01_PANEL_FIT_ENABLE; |
422 | vr40 |= VR40_CLOCK_GATING_ENABLE; | 422 | vr40 |= VR40_CLOCK_GATING_ENABLE; |
423 | x_ratio = (((mode->hdisplay - 1) << 16) / | 423 | x_ratio = (((mode->hdisplay - 1) << 16) / |
424 | (adjusted_mode->hdisplay - 1)) >> 2; | 424 | (adjusted_mode->crtc_hdisplay - 1)) >> 2; |
425 | y_ratio = (((mode->vdisplay - 1) << 16) / | 425 | y_ratio = (((mode->vdisplay - 1) << 16) / |
426 | (adjusted_mode->vdisplay - 1)) >> 2; | 426 | (adjusted_mode->crtc_vdisplay - 1)) >> 2; |
427 | ivch_write(dvo, VR42, x_ratio); | 427 | ivch_write(dvo, VR42, x_ratio); |
428 | ivch_write(dvo, VR41, y_ratio); | 428 | ivch_write(dvo, VR41, y_ratio); |
429 | } else { | 429 | } else { |
diff --git a/drivers/gpu/drm/i915/dvo_ns2501.c b/drivers/gpu/drm/i915/dvo_ns2501.c index 97ae8aa157e9..063859fff0f0 100644 --- a/drivers/gpu/drm/i915/dvo_ns2501.c +++ b/drivers/gpu/drm/i915/dvo_ns2501.c | |||
@@ -546,8 +546,8 @@ static enum drm_mode_status ns2501_mode_valid(struct intel_dvo_device *dvo, | |||
546 | } | 546 | } |
547 | 547 | ||
548 | static void ns2501_mode_set(struct intel_dvo_device *dvo, | 548 | static void ns2501_mode_set(struct intel_dvo_device *dvo, |
549 | struct drm_display_mode *mode, | 549 | const struct drm_display_mode *mode, |
550 | struct drm_display_mode *adjusted_mode) | 550 | const struct drm_display_mode *adjusted_mode) |
551 | { | 551 | { |
552 | const struct ns2501_configuration *conf; | 552 | const struct ns2501_configuration *conf; |
553 | struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv); | 553 | struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv); |
diff --git a/drivers/gpu/drm/i915/dvo_sil164.c b/drivers/gpu/drm/i915/dvo_sil164.c index fa0114967076..26f13eb634f9 100644 --- a/drivers/gpu/drm/i915/dvo_sil164.c +++ b/drivers/gpu/drm/i915/dvo_sil164.c | |||
@@ -190,8 +190,8 @@ static enum drm_mode_status sil164_mode_valid(struct intel_dvo_device *dvo, | |||
190 | } | 190 | } |
191 | 191 | ||
192 | static void sil164_mode_set(struct intel_dvo_device *dvo, | 192 | static void sil164_mode_set(struct intel_dvo_device *dvo, |
193 | struct drm_display_mode *mode, | 193 | const struct drm_display_mode *mode, |
194 | struct drm_display_mode *adjusted_mode) | 194 | const struct drm_display_mode *adjusted_mode) |
195 | { | 195 | { |
196 | /* As long as the basics are set up, since we don't have clock | 196 | /* As long as the basics are set up, since we don't have clock |
197 | * dependencies in the mode setup, we can just leave the | 197 | * dependencies in the mode setup, we can just leave the |
diff --git a/drivers/gpu/drm/i915/dvo_tfp410.c b/drivers/gpu/drm/i915/dvo_tfp410.c index 7853719a0e81..6f1a0a6d4e22 100644 --- a/drivers/gpu/drm/i915/dvo_tfp410.c +++ b/drivers/gpu/drm/i915/dvo_tfp410.c | |||
@@ -222,8 +222,8 @@ static enum drm_mode_status tfp410_mode_valid(struct intel_dvo_device *dvo, | |||
222 | } | 222 | } |
223 | 223 | ||
224 | static void tfp410_mode_set(struct intel_dvo_device *dvo, | 224 | static void tfp410_mode_set(struct intel_dvo_device *dvo, |
225 | struct drm_display_mode *mode, | 225 | const struct drm_display_mode *mode, |
226 | struct drm_display_mode *adjusted_mode) | 226 | const struct drm_display_mode *adjusted_mode) |
227 | { | 227 | { |
228 | /* As long as the basics are set up, since we don't have clock dependencies | 228 | /* As long as the basics are set up, since we don't have clock dependencies |
229 | * in the mode setup, we can just leave the registers alone and everything | 229 | * in the mode setup, we can just leave the registers alone and everything |
diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 09932cab1a3f..db58c8d664c2 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c | |||
@@ -448,6 +448,9 @@ static const struct drm_i915_reg_descriptor gen7_render_regs[] = { | |||
448 | REG32(GEN7_3DPRIM_INSTANCE_COUNT), | 448 | REG32(GEN7_3DPRIM_INSTANCE_COUNT), |
449 | REG32(GEN7_3DPRIM_START_INSTANCE), | 449 | REG32(GEN7_3DPRIM_START_INSTANCE), |
450 | REG32(GEN7_3DPRIM_BASE_VERTEX), | 450 | REG32(GEN7_3DPRIM_BASE_VERTEX), |
451 | REG32(GEN7_GPGPU_DISPATCHDIMX), | ||
452 | REG32(GEN7_GPGPU_DISPATCHDIMY), | ||
453 | REG32(GEN7_GPGPU_DISPATCHDIMZ), | ||
451 | REG64(GEN7_SO_NUM_PRIMS_WRITTEN(0)), | 454 | REG64(GEN7_SO_NUM_PRIMS_WRITTEN(0)), |
452 | REG64(GEN7_SO_NUM_PRIMS_WRITTEN(1)), | 455 | REG64(GEN7_SO_NUM_PRIMS_WRITTEN(1)), |
453 | REG64(GEN7_SO_NUM_PRIMS_WRITTEN(2)), | 456 | REG64(GEN7_SO_NUM_PRIMS_WRITTEN(2)), |
@@ -1214,6 +1217,7 @@ int i915_cmd_parser_get_version(void) | |||
1214 | * MI_PREDICATE_SRC1 registers. | 1217 | * MI_PREDICATE_SRC1 registers. |
1215 | * 3. Allow access to the GPGPU_THREADS_DISPATCHED register. | 1218 | * 3. Allow access to the GPGPU_THREADS_DISPATCHED register. |
1216 | * 4. L3 atomic chicken bits of HSW_SCRATCH1 and HSW_ROW_CHICKEN3. | 1219 | * 4. L3 atomic chicken bits of HSW_SCRATCH1 and HSW_ROW_CHICKEN3. |
1220 | * 5. GPGPU dispatch compute indirect registers. | ||
1217 | */ | 1221 | */ |
1218 | return 4; | 1222 | return 5; |
1219 | } | 1223 | } |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 84c7b6b294ee..3f2a7a7c7cd4 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -253,7 +253,11 @@ static int obj_rank_by_stolen(void *priv, | |||
253 | struct drm_i915_gem_object *b = | 253 | struct drm_i915_gem_object *b = |
254 | container_of(B, struct drm_i915_gem_object, obj_exec_link); | 254 | container_of(B, struct drm_i915_gem_object, obj_exec_link); |
255 | 255 | ||
256 | return a->stolen->start - b->stolen->start; | 256 | if (a->stolen->start < b->stolen->start) |
257 | return -1; | ||
258 | if (a->stolen->start > b->stolen->start) | ||
259 | return 1; | ||
260 | return 0; | ||
257 | } | 261 | } |
258 | 262 | ||
259 | static int i915_gem_stolen_list_info(struct seq_file *m, void *data) | 263 | static int i915_gem_stolen_list_info(struct seq_file *m, void *data) |
@@ -1308,6 +1312,10 @@ static int i915_frequency_info(struct seq_file *m, void *unused) | |||
1308 | seq_puts(m, "no P-state info available\n"); | 1312 | seq_puts(m, "no P-state info available\n"); |
1309 | } | 1313 | } |
1310 | 1314 | ||
1315 | seq_printf(m, "Current CD clock frequency: %d kHz\n", dev_priv->cdclk_freq); | ||
1316 | seq_printf(m, "Max CD clock frequency: %d kHz\n", dev_priv->max_cdclk_freq); | ||
1317 | seq_printf(m, "Max pixel clock frequency: %d kHz\n", dev_priv->max_dotclk_freq); | ||
1318 | |||
1311 | out: | 1319 | out: |
1312 | intel_runtime_pm_put(dev_priv); | 1320 | intel_runtime_pm_put(dev_priv); |
1313 | return ret; | 1321 | return ret; |
@@ -2230,10 +2238,9 @@ static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev) | |||
2230 | for_each_ring(ring, dev_priv, unused) { | 2238 | for_each_ring(ring, dev_priv, unused) { |
2231 | seq_printf(m, "%s\n", ring->name); | 2239 | seq_printf(m, "%s\n", ring->name); |
2232 | for (i = 0; i < 4; i++) { | 2240 | for (i = 0; i < 4; i++) { |
2233 | u32 offset = 0x270 + i * 8; | 2241 | u64 pdp = I915_READ(GEN8_RING_PDP_UDW(ring, i)); |
2234 | u64 pdp = I915_READ(ring->mmio_base + offset + 4); | ||
2235 | pdp <<= 32; | 2242 | pdp <<= 32; |
2236 | pdp |= I915_READ(ring->mmio_base + offset); | 2243 | pdp |= I915_READ(GEN8_RING_PDP_LDW(ring, i)); |
2237 | seq_printf(m, "\tPDP%d 0x%016llx\n", i, pdp); | 2244 | seq_printf(m, "\tPDP%d 0x%016llx\n", i, pdp); |
2238 | } | 2245 | } |
2239 | } | 2246 | } |
@@ -2290,18 +2297,21 @@ static int i915_ppgtt_info(struct seq_file *m, void *data) | |||
2290 | struct task_struct *task; | 2297 | struct task_struct *task; |
2291 | 2298 | ||
2292 | task = get_pid_task(file->pid, PIDTYPE_PID); | 2299 | task = get_pid_task(file->pid, PIDTYPE_PID); |
2293 | if (!task) | 2300 | if (!task) { |
2294 | return -ESRCH; | 2301 | ret = -ESRCH; |
2302 | goto out_put; | ||
2303 | } | ||
2295 | seq_printf(m, "\nproc: %s\n", task->comm); | 2304 | seq_printf(m, "\nproc: %s\n", task->comm); |
2296 | put_task_struct(task); | 2305 | put_task_struct(task); |
2297 | idr_for_each(&file_priv->context_idr, per_file_ctx, | 2306 | idr_for_each(&file_priv->context_idr, per_file_ctx, |
2298 | (void *)(unsigned long)m); | 2307 | (void *)(unsigned long)m); |
2299 | } | 2308 | } |
2300 | 2309 | ||
2310 | out_put: | ||
2301 | intel_runtime_pm_put(dev_priv); | 2311 | intel_runtime_pm_put(dev_priv); |
2302 | mutex_unlock(&dev->struct_mutex); | 2312 | mutex_unlock(&dev->struct_mutex); |
2303 | 2313 | ||
2304 | return 0; | 2314 | return ret; |
2305 | } | 2315 | } |
2306 | 2316 | ||
2307 | static int count_irq_waiters(struct drm_i915_private *i915) | 2317 | static int count_irq_waiters(struct drm_i915_private *i915) |
@@ -2909,7 +2919,7 @@ static bool cursor_active(struct drm_device *dev, int pipe) | |||
2909 | u32 state; | 2919 | u32 state; |
2910 | 2920 | ||
2911 | if (IS_845G(dev) || IS_I865G(dev)) | 2921 | if (IS_845G(dev) || IS_I865G(dev)) |
2912 | state = I915_READ(_CURACNTR) & CURSOR_ENABLE; | 2922 | state = I915_READ(CURCNTR(PIPE_A)) & CURSOR_ENABLE; |
2913 | else | 2923 | else |
2914 | state = I915_READ(CURCNTR(pipe)) & CURSOR_MODE; | 2924 | state = I915_READ(CURCNTR(pipe)) & CURSOR_MODE; |
2915 | 2925 | ||
@@ -3147,7 +3157,7 @@ static int i915_ddb_info(struct seq_file *m, void *unused) | |||
3147 | skl_ddb_entry_size(entry)); | 3157 | skl_ddb_entry_size(entry)); |
3148 | } | 3158 | } |
3149 | 3159 | ||
3150 | entry = &ddb->cursor[pipe]; | 3160 | entry = &ddb->plane[pipe][PLANE_CURSOR]; |
3151 | seq_printf(m, " %-13s%8u%8u%8u\n", "Cursor", entry->start, | 3161 | seq_printf(m, " %-13s%8u%8u%8u\n", "Cursor", entry->start, |
3152 | entry->end, skl_ddb_entry_size(entry)); | 3162 | entry->end, skl_ddb_entry_size(entry)); |
3153 | } | 3163 | } |
@@ -5040,13 +5050,38 @@ static void gen9_sseu_device_status(struct drm_device *dev, | |||
5040 | } | 5050 | } |
5041 | } | 5051 | } |
5042 | 5052 | ||
5053 | static void broadwell_sseu_device_status(struct drm_device *dev, | ||
5054 | struct sseu_dev_status *stat) | ||
5055 | { | ||
5056 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5057 | int s; | ||
5058 | u32 slice_info = I915_READ(GEN8_GT_SLICE_INFO); | ||
5059 | |||
5060 | stat->slice_total = hweight32(slice_info & GEN8_LSLICESTAT_MASK); | ||
5061 | |||
5062 | if (stat->slice_total) { | ||
5063 | stat->subslice_per_slice = INTEL_INFO(dev)->subslice_per_slice; | ||
5064 | stat->subslice_total = stat->slice_total * | ||
5065 | stat->subslice_per_slice; | ||
5066 | stat->eu_per_subslice = INTEL_INFO(dev)->eu_per_subslice; | ||
5067 | stat->eu_total = stat->eu_per_subslice * stat->subslice_total; | ||
5068 | |||
5069 | /* subtract fused off EU(s) from enabled slice(s) */ | ||
5070 | for (s = 0; s < stat->slice_total; s++) { | ||
5071 | u8 subslice_7eu = INTEL_INFO(dev)->subslice_7eu[s]; | ||
5072 | |||
5073 | stat->eu_total -= hweight8(subslice_7eu); | ||
5074 | } | ||
5075 | } | ||
5076 | } | ||
5077 | |||
5043 | static int i915_sseu_status(struct seq_file *m, void *unused) | 5078 | static int i915_sseu_status(struct seq_file *m, void *unused) |
5044 | { | 5079 | { |
5045 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 5080 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
5046 | struct drm_device *dev = node->minor->dev; | 5081 | struct drm_device *dev = node->minor->dev; |
5047 | struct sseu_dev_status stat; | 5082 | struct sseu_dev_status stat; |
5048 | 5083 | ||
5049 | if ((INTEL_INFO(dev)->gen < 8) || IS_BROADWELL(dev)) | 5084 | if (INTEL_INFO(dev)->gen < 8) |
5050 | return -ENODEV; | 5085 | return -ENODEV; |
5051 | 5086 | ||
5052 | seq_puts(m, "SSEU Device Info\n"); | 5087 | seq_puts(m, "SSEU Device Info\n"); |
@@ -5071,6 +5106,8 @@ static int i915_sseu_status(struct seq_file *m, void *unused) | |||
5071 | memset(&stat, 0, sizeof(stat)); | 5106 | memset(&stat, 0, sizeof(stat)); |
5072 | if (IS_CHERRYVIEW(dev)) { | 5107 | if (IS_CHERRYVIEW(dev)) { |
5073 | cherryview_sseu_device_status(dev, &stat); | 5108 | cherryview_sseu_device_status(dev, &stat); |
5109 | } else if (IS_BROADWELL(dev)) { | ||
5110 | broadwell_sseu_device_status(dev, &stat); | ||
5074 | } else if (INTEL_INFO(dev)->gen >= 9) { | 5111 | } else if (INTEL_INFO(dev)->gen >= 9) { |
5075 | gen9_sseu_device_status(dev, &stat); | 5112 | gen9_sseu_device_status(dev, &stat); |
5076 | } | 5113 | } |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 0eda746850ef..1e3d65743bd2 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -673,6 +673,82 @@ static void gen9_sseu_info_init(struct drm_device *dev) | |||
673 | info->has_eu_pg = (info->eu_per_subslice > 2); | 673 | info->has_eu_pg = (info->eu_per_subslice > 2); |
674 | } | 674 | } |
675 | 675 | ||
676 | static void broadwell_sseu_info_init(struct drm_device *dev) | ||
677 | { | ||
678 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
679 | struct intel_device_info *info; | ||
680 | const int s_max = 3, ss_max = 3, eu_max = 8; | ||
681 | int s, ss; | ||
682 | u32 fuse2, eu_disable[s_max], s_enable, ss_disable; | ||
683 | |||
684 | fuse2 = I915_READ(GEN8_FUSE2); | ||
685 | s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT; | ||
686 | ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >> GEN8_F2_SS_DIS_SHIFT; | ||
687 | |||
688 | eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) & GEN8_EU_DIS0_S0_MASK; | ||
689 | eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >> GEN8_EU_DIS0_S1_SHIFT) | | ||
690 | ((I915_READ(GEN8_EU_DISABLE1) & GEN8_EU_DIS1_S1_MASK) << | ||
691 | (32 - GEN8_EU_DIS0_S1_SHIFT)); | ||
692 | eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >> GEN8_EU_DIS1_S2_SHIFT) | | ||
693 | ((I915_READ(GEN8_EU_DISABLE2) & GEN8_EU_DIS2_S2_MASK) << | ||
694 | (32 - GEN8_EU_DIS1_S2_SHIFT)); | ||
695 | |||
696 | |||
697 | info = (struct intel_device_info *)&dev_priv->info; | ||
698 | info->slice_total = hweight32(s_enable); | ||
699 | |||
700 | /* | ||
701 | * The subslice disable field is global, i.e. it applies | ||
702 | * to each of the enabled slices. | ||
703 | */ | ||
704 | info->subslice_per_slice = ss_max - hweight32(ss_disable); | ||
705 | info->subslice_total = info->slice_total * info->subslice_per_slice; | ||
706 | |||
707 | /* | ||
708 | * Iterate through enabled slices and subslices to | ||
709 | * count the total enabled EU. | ||
710 | */ | ||
711 | for (s = 0; s < s_max; s++) { | ||
712 | if (!(s_enable & (0x1 << s))) | ||
713 | /* skip disabled slice */ | ||
714 | continue; | ||
715 | |||
716 | for (ss = 0; ss < ss_max; ss++) { | ||
717 | u32 n_disabled; | ||
718 | |||
719 | if (ss_disable & (0x1 << ss)) | ||
720 | /* skip disabled subslice */ | ||
721 | continue; | ||
722 | |||
723 | n_disabled = hweight8(eu_disable[s] >> (ss * eu_max)); | ||
724 | |||
725 | /* | ||
726 | * Record which subslices have 7 EUs. | ||
727 | */ | ||
728 | if (eu_max - n_disabled == 7) | ||
729 | info->subslice_7eu[s] |= 1 << ss; | ||
730 | |||
731 | info->eu_total += eu_max - n_disabled; | ||
732 | } | ||
733 | } | ||
734 | |||
735 | /* | ||
736 | * BDW is expected to always have a uniform distribution of EU across | ||
737 | * subslices with the exception that any one EU in any one subslice may | ||
738 | * be fused off for die recovery. | ||
739 | */ | ||
740 | info->eu_per_subslice = info->subslice_total ? | ||
741 | DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0; | ||
742 | |||
743 | /* | ||
744 | * BDW supports slice power gating on devices with more than | ||
745 | * one slice. | ||
746 | */ | ||
747 | info->has_slice_pg = (info->slice_total > 1); | ||
748 | info->has_subslice_pg = 0; | ||
749 | info->has_eu_pg = 0; | ||
750 | } | ||
751 | |||
676 | /* | 752 | /* |
677 | * Determine various intel_device_info fields at runtime. | 753 | * Determine various intel_device_info fields at runtime. |
678 | * | 754 | * |
@@ -743,6 +819,8 @@ static void intel_device_info_runtime_init(struct drm_device *dev) | |||
743 | /* Initialize slice/subslice/EU info */ | 819 | /* Initialize slice/subslice/EU info */ |
744 | if (IS_CHERRYVIEW(dev)) | 820 | if (IS_CHERRYVIEW(dev)) |
745 | cherryview_sseu_info_init(dev); | 821 | cherryview_sseu_info_init(dev); |
822 | else if (IS_BROADWELL(dev)) | ||
823 | broadwell_sseu_info_init(dev); | ||
746 | else if (INTEL_INFO(dev)->gen >= 9) | 824 | else if (INTEL_INFO(dev)->gen >= 9) |
747 | gen9_sseu_info_init(dev); | 825 | gen9_sseu_info_init(dev); |
748 | 826 | ||
@@ -818,6 +896,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
818 | mutex_init(&dev_priv->sb_lock); | 896 | mutex_init(&dev_priv->sb_lock); |
819 | mutex_init(&dev_priv->modeset_restore_lock); | 897 | mutex_init(&dev_priv->modeset_restore_lock); |
820 | mutex_init(&dev_priv->csr_lock); | 898 | mutex_init(&dev_priv->csr_lock); |
899 | mutex_init(&dev_priv->av_mutex); | ||
821 | 900 | ||
822 | intel_pm_setup(dev); | 901 | intel_pm_setup(dev); |
823 | 902 | ||
@@ -1045,12 +1124,9 @@ out_freecsr: | |||
1045 | put_bridge: | 1124 | put_bridge: |
1046 | pci_dev_put(dev_priv->bridge_dev); | 1125 | pci_dev_put(dev_priv->bridge_dev); |
1047 | free_priv: | 1126 | free_priv: |
1048 | if (dev_priv->requests) | 1127 | kmem_cache_destroy(dev_priv->requests); |
1049 | kmem_cache_destroy(dev_priv->requests); | 1128 | kmem_cache_destroy(dev_priv->vmas); |
1050 | if (dev_priv->vmas) | 1129 | kmem_cache_destroy(dev_priv->objects); |
1051 | kmem_cache_destroy(dev_priv->vmas); | ||
1052 | if (dev_priv->objects) | ||
1053 | kmem_cache_destroy(dev_priv->objects); | ||
1054 | kfree(dev_priv); | 1130 | kfree(dev_priv); |
1055 | return ret; | 1131 | return ret; |
1056 | } | 1132 | } |
@@ -1141,13 +1217,9 @@ int i915_driver_unload(struct drm_device *dev) | |||
1141 | if (dev_priv->regs != NULL) | 1217 | if (dev_priv->regs != NULL) |
1142 | pci_iounmap(dev->pdev, dev_priv->regs); | 1218 | pci_iounmap(dev->pdev, dev_priv->regs); |
1143 | 1219 | ||
1144 | if (dev_priv->requests) | 1220 | kmem_cache_destroy(dev_priv->requests); |
1145 | kmem_cache_destroy(dev_priv->requests); | 1221 | kmem_cache_destroy(dev_priv->vmas); |
1146 | if (dev_priv->vmas) | 1222 | kmem_cache_destroy(dev_priv->objects); |
1147 | kmem_cache_destroy(dev_priv->vmas); | ||
1148 | if (dev_priv->objects) | ||
1149 | kmem_cache_destroy(dev_priv->objects); | ||
1150 | |||
1151 | pci_dev_put(dev_priv->bridge_dev); | 1223 | pci_dev_put(dev_priv->bridge_dev); |
1152 | kfree(dev_priv); | 1224 | kfree(dev_priv); |
1153 | 1225 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index e6d7a69ec1bf..760e0ce4aa26 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -443,6 +443,34 @@ static const struct pci_device_id pciidlist[] = { /* aka */ | |||
443 | 443 | ||
444 | MODULE_DEVICE_TABLE(pci, pciidlist); | 444 | MODULE_DEVICE_TABLE(pci, pciidlist); |
445 | 445 | ||
446 | static enum intel_pch intel_virt_detect_pch(struct drm_device *dev) | ||
447 | { | ||
448 | enum intel_pch ret = PCH_NOP; | ||
449 | |||
450 | /* | ||
451 | * In a virtualized passthrough environment we can be in a | ||
452 | * setup where the ISA bridge is not able to be passed through. | ||
453 | * In this case, a south bridge can be emulated and we have to | ||
454 | * make an educated guess as to which PCH is really there. | ||
455 | */ | ||
456 | |||
457 | if (IS_GEN5(dev)) { | ||
458 | ret = PCH_IBX; | ||
459 | DRM_DEBUG_KMS("Assuming Ibex Peak PCH\n"); | ||
460 | } else if (IS_GEN6(dev) || IS_IVYBRIDGE(dev)) { | ||
461 | ret = PCH_CPT; | ||
462 | DRM_DEBUG_KMS("Assuming CouarPoint PCH\n"); | ||
463 | } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { | ||
464 | ret = PCH_LPT; | ||
465 | DRM_DEBUG_KMS("Assuming LynxPoint PCH\n"); | ||
466 | } else if (IS_SKYLAKE(dev)) { | ||
467 | ret = PCH_SPT; | ||
468 | DRM_DEBUG_KMS("Assuming SunrisePoint PCH\n"); | ||
469 | } | ||
470 | |||
471 | return ret; | ||
472 | } | ||
473 | |||
446 | void intel_detect_pch(struct drm_device *dev) | 474 | void intel_detect_pch(struct drm_device *dev) |
447 | { | 475 | { |
448 | struct drm_i915_private *dev_priv = dev->dev_private; | 476 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -503,6 +531,8 @@ void intel_detect_pch(struct drm_device *dev) | |||
503 | dev_priv->pch_type = PCH_SPT; | 531 | dev_priv->pch_type = PCH_SPT; |
504 | DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n"); | 532 | DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n"); |
505 | WARN_ON(!IS_SKYLAKE(dev)); | 533 | WARN_ON(!IS_SKYLAKE(dev)); |
534 | } else if (id == INTEL_PCH_P2X_DEVICE_ID_TYPE) { | ||
535 | dev_priv->pch_type = intel_virt_detect_pch(dev); | ||
506 | } else | 536 | } else |
507 | continue; | 537 | continue; |
508 | 538 | ||
@@ -608,6 +638,8 @@ static int i915_drm_suspend(struct drm_device *dev) | |||
608 | return error; | 638 | return error; |
609 | } | 639 | } |
610 | 640 | ||
641 | intel_guc_suspend(dev); | ||
642 | |||
611 | intel_suspend_gt_powersave(dev); | 643 | intel_suspend_gt_powersave(dev); |
612 | 644 | ||
613 | /* | 645 | /* |
@@ -737,6 +769,8 @@ static int i915_drm_resume(struct drm_device *dev) | |||
737 | } | 769 | } |
738 | mutex_unlock(&dev->struct_mutex); | 770 | mutex_unlock(&dev->struct_mutex); |
739 | 771 | ||
772 | intel_guc_resume(dev); | ||
773 | |||
740 | intel_modeset_init_hw(dev); | 774 | intel_modeset_init_hw(dev); |
741 | 775 | ||
742 | spin_lock_irq(&dev_priv->irq_lock); | 776 | spin_lock_irq(&dev_priv->irq_lock); |
@@ -1021,12 +1055,6 @@ static int skl_suspend_complete(struct drm_i915_private *dev_priv) | |||
1021 | { | 1055 | { |
1022 | /* Enabling DC6 is not a hard requirement to enter runtime D3 */ | 1056 | /* Enabling DC6 is not a hard requirement to enter runtime D3 */ |
1023 | 1057 | ||
1024 | /* | ||
1025 | * This is to ensure that CSR isn't identified as loaded before | ||
1026 | * CSR-loading program is called during runtime-resume. | ||
1027 | */ | ||
1028 | intel_csr_load_status_set(dev_priv, FW_UNINITIALIZED); | ||
1029 | |||
1030 | skl_uninit_cdclk(dev_priv); | 1058 | skl_uninit_cdclk(dev_priv); |
1031 | 1059 | ||
1032 | return 0; | 1060 | return 0; |
@@ -1476,6 +1504,8 @@ static int intel_runtime_suspend(struct device *device) | |||
1476 | i915_gem_release_all_mmaps(dev_priv); | 1504 | i915_gem_release_all_mmaps(dev_priv); |
1477 | mutex_unlock(&dev->struct_mutex); | 1505 | mutex_unlock(&dev->struct_mutex); |
1478 | 1506 | ||
1507 | intel_guc_suspend(dev); | ||
1508 | |||
1479 | intel_suspend_gt_powersave(dev); | 1509 | intel_suspend_gt_powersave(dev); |
1480 | intel_runtime_pm_disable_interrupts(dev_priv); | 1510 | intel_runtime_pm_disable_interrupts(dev_priv); |
1481 | 1511 | ||
@@ -1535,6 +1565,8 @@ static int intel_runtime_resume(struct device *device) | |||
1535 | intel_opregion_notify_adapter(dev, PCI_D0); | 1565 | intel_opregion_notify_adapter(dev, PCI_D0); |
1536 | dev_priv->pm.suspended = false; | 1566 | dev_priv->pm.suspended = false; |
1537 | 1567 | ||
1568 | intel_guc_resume(dev); | ||
1569 | |||
1538 | if (IS_GEN6(dev_priv)) | 1570 | if (IS_GEN6(dev_priv)) |
1539 | intel_init_pch_refclk(dev); | 1571 | intel_init_pch_refclk(dev); |
1540 | 1572 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0841ca569ccb..5adba06a85d1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -57,7 +57,7 @@ | |||
57 | 57 | ||
58 | #define DRIVER_NAME "i915" | 58 | #define DRIVER_NAME "i915" |
59 | #define DRIVER_DESC "Intel Graphics" | 59 | #define DRIVER_DESC "Intel Graphics" |
60 | #define DRIVER_DATE "20150928" | 60 | #define DRIVER_DATE "20151010" |
61 | 61 | ||
62 | #undef WARN_ON | 62 | #undef WARN_ON |
63 | /* Many gcc seem to no see through this and fall over :( */ | 63 | /* Many gcc seem to no see through this and fall over :( */ |
@@ -131,17 +131,17 @@ enum transcoder { | |||
131 | #define transcoder_name(t) ((t) + 'A') | 131 | #define transcoder_name(t) ((t) + 'A') |
132 | 132 | ||
133 | /* | 133 | /* |
134 | * This is the maximum (across all platforms) number of planes (primary + | 134 | * I915_MAX_PLANES in the enum below is the maximum (across all platforms) |
135 | * sprites) that can be active at the same time on one pipe. | 135 | * number of planes per CRTC. Not all platforms really have this many planes, |
136 | * | 136 | * which means some arrays of size I915_MAX_PLANES may have unused entries |
137 | * This value doesn't count the cursor plane. | 137 | * between the topmost sprite plane and the cursor plane. |
138 | */ | 138 | */ |
139 | #define I915_MAX_PLANES 4 | ||
140 | |||
141 | enum plane { | 139 | enum plane { |
142 | PLANE_A = 0, | 140 | PLANE_A = 0, |
143 | PLANE_B, | 141 | PLANE_B, |
144 | PLANE_C, | 142 | PLANE_C, |
143 | PLANE_CURSOR, | ||
144 | I915_MAX_PLANES, | ||
145 | }; | 145 | }; |
146 | #define plane_name(p) ((p) + 'A') | 146 | #define plane_name(p) ((p) + 'A') |
147 | 147 | ||
@@ -628,10 +628,6 @@ struct drm_i915_display_funcs { | |||
628 | struct dpll *match_clock, | 628 | struct dpll *match_clock, |
629 | struct dpll *best_clock); | 629 | struct dpll *best_clock); |
630 | void (*update_wm)(struct drm_crtc *crtc); | 630 | void (*update_wm)(struct drm_crtc *crtc); |
631 | void (*update_sprite_wm)(struct drm_plane *plane, | ||
632 | struct drm_crtc *crtc, | ||
633 | uint32_t sprite_width, uint32_t sprite_height, | ||
634 | int pixel_size, bool enable, bool scaled); | ||
635 | int (*modeset_calc_cdclk)(struct drm_atomic_state *state); | 631 | int (*modeset_calc_cdclk)(struct drm_atomic_state *state); |
636 | void (*modeset_commit_cdclk)(struct drm_atomic_state *state); | 632 | void (*modeset_commit_cdclk)(struct drm_atomic_state *state); |
637 | /* Returns the active state of the crtc, and if the crtc is active, | 633 | /* Returns the active state of the crtc, and if the crtc is active, |
@@ -646,7 +642,7 @@ struct drm_i915_display_funcs { | |||
646 | void (*crtc_disable)(struct drm_crtc *crtc); | 642 | void (*crtc_disable)(struct drm_crtc *crtc); |
647 | void (*audio_codec_enable)(struct drm_connector *connector, | 643 | void (*audio_codec_enable)(struct drm_connector *connector, |
648 | struct intel_encoder *encoder, | 644 | struct intel_encoder *encoder, |
649 | struct drm_display_mode *mode); | 645 | const struct drm_display_mode *adjusted_mode); |
650 | void (*audio_codec_disable)(struct intel_encoder *encoder); | 646 | void (*audio_codec_disable)(struct intel_encoder *encoder); |
651 | void (*fdi_link_train)(struct drm_crtc *crtc); | 647 | void (*fdi_link_train)(struct drm_crtc *crtc); |
652 | void (*init_clock_gating)(struct drm_device *dev); | 648 | void (*init_clock_gating)(struct drm_device *dev); |
@@ -664,15 +660,6 @@ struct drm_i915_display_funcs { | |||
664 | /* render clock increase/decrease */ | 660 | /* render clock increase/decrease */ |
665 | /* display clock increase/decrease */ | 661 | /* display clock increase/decrease */ |
666 | /* pll clock increase/decrease */ | 662 | /* pll clock increase/decrease */ |
667 | |||
668 | int (*setup_backlight)(struct intel_connector *connector, enum pipe pipe); | ||
669 | uint32_t (*get_backlight)(struct intel_connector *connector); | ||
670 | void (*set_backlight)(struct intel_connector *connector, | ||
671 | uint32_t level); | ||
672 | void (*disable_backlight)(struct intel_connector *connector); | ||
673 | void (*enable_backlight)(struct intel_connector *connector); | ||
674 | uint32_t (*backlight_hz_to_pwm)(struct intel_connector *connector, | ||
675 | uint32_t hz); | ||
676 | }; | 663 | }; |
677 | 664 | ||
678 | enum forcewake_domain_id { | 665 | enum forcewake_domain_id { |
@@ -1146,7 +1133,6 @@ struct intel_gen6_power_mgmt { | |||
1146 | u8 efficient_freq; /* AKA RPe. Pre-determined balanced frequency */ | 1133 | u8 efficient_freq; /* AKA RPe. Pre-determined balanced frequency */ |
1147 | u8 rp1_freq; /* "less than" RP0 power/freqency */ | 1134 | u8 rp1_freq; /* "less than" RP0 power/freqency */ |
1148 | u8 rp0_freq; /* Non-overclocked max frequency. */ | 1135 | u8 rp0_freq; /* Non-overclocked max frequency. */ |
1149 | u32 cz_freq; | ||
1150 | 1136 | ||
1151 | u8 up_threshold; /* Current %busy required to uplock */ | 1137 | u8 up_threshold; /* Current %busy required to uplock */ |
1152 | u8 down_threshold; /* Current %busy required to downclock */ | 1138 | u8 down_threshold; /* Current %busy required to downclock */ |
@@ -1588,8 +1574,7 @@ static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1, | |||
1588 | struct skl_ddb_allocation { | 1574 | struct skl_ddb_allocation { |
1589 | struct skl_ddb_entry pipe[I915_MAX_PIPES]; | 1575 | struct skl_ddb_entry pipe[I915_MAX_PIPES]; |
1590 | struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES]; /* packed/uv */ | 1576 | struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES]; /* packed/uv */ |
1591 | struct skl_ddb_entry y_plane[I915_MAX_PIPES][I915_MAX_PLANES]; /* y-plane */ | 1577 | struct skl_ddb_entry y_plane[I915_MAX_PIPES][I915_MAX_PLANES]; |
1592 | struct skl_ddb_entry cursor[I915_MAX_PIPES]; | ||
1593 | }; | 1578 | }; |
1594 | 1579 | ||
1595 | struct skl_wm_values { | 1580 | struct skl_wm_values { |
@@ -1597,18 +1582,13 @@ struct skl_wm_values { | |||
1597 | struct skl_ddb_allocation ddb; | 1582 | struct skl_ddb_allocation ddb; |
1598 | uint32_t wm_linetime[I915_MAX_PIPES]; | 1583 | uint32_t wm_linetime[I915_MAX_PIPES]; |
1599 | uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8]; | 1584 | uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8]; |
1600 | uint32_t cursor[I915_MAX_PIPES][8]; | ||
1601 | uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES]; | 1585 | uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES]; |
1602 | uint32_t cursor_trans[I915_MAX_PIPES]; | ||
1603 | }; | 1586 | }; |
1604 | 1587 | ||
1605 | struct skl_wm_level { | 1588 | struct skl_wm_level { |
1606 | bool plane_en[I915_MAX_PLANES]; | 1589 | bool plane_en[I915_MAX_PLANES]; |
1607 | bool cursor_en; | ||
1608 | uint16_t plane_res_b[I915_MAX_PLANES]; | 1590 | uint16_t plane_res_b[I915_MAX_PLANES]; |
1609 | uint8_t plane_res_l[I915_MAX_PLANES]; | 1591 | uint8_t plane_res_l[I915_MAX_PLANES]; |
1610 | uint16_t cursor_res_b; | ||
1611 | uint8_t cursor_res_l; | ||
1612 | }; | 1592 | }; |
1613 | 1593 | ||
1614 | /* | 1594 | /* |
@@ -1809,6 +1789,7 @@ struct drm_i915_private { | |||
1809 | unsigned int cdclk_freq, max_cdclk_freq; | 1789 | unsigned int cdclk_freq, max_cdclk_freq; |
1810 | unsigned int max_dotclk_freq; | 1790 | unsigned int max_dotclk_freq; |
1811 | unsigned int hpll_freq; | 1791 | unsigned int hpll_freq; |
1792 | unsigned int czclk_freq; | ||
1812 | 1793 | ||
1813 | /** | 1794 | /** |
1814 | * wq - Driver workqueue for GEM. | 1795 | * wq - Driver workqueue for GEM. |
@@ -1897,6 +1878,11 @@ struct drm_i915_private { | |||
1897 | /* hda/i915 audio component */ | 1878 | /* hda/i915 audio component */ |
1898 | struct i915_audio_component *audio_component; | 1879 | struct i915_audio_component *audio_component; |
1899 | bool audio_component_registered; | 1880 | bool audio_component_registered; |
1881 | /** | ||
1882 | * av_mutex - mutex for audio/video sync | ||
1883 | * | ||
1884 | */ | ||
1885 | struct mutex av_mutex; | ||
1900 | 1886 | ||
1901 | uint32_t hw_context_size; | 1887 | uint32_t hw_context_size; |
1902 | struct list_head context_list; | 1888 | struct list_head context_list; |
@@ -1959,6 +1945,9 @@ struct drm_i915_private { | |||
1959 | 1945 | ||
1960 | bool edp_low_vswing; | 1946 | bool edp_low_vswing; |
1961 | 1947 | ||
1948 | /* perform PHY state sanity checks? */ | ||
1949 | bool chv_phy_assert[2]; | ||
1950 | |||
1962 | /* | 1951 | /* |
1963 | * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch | 1952 | * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch |
1964 | * will be rejected. Instead look for a better place. | 1953 | * will be rejected. Instead look for a better place. |
@@ -2607,6 +2596,7 @@ struct drm_i915_cmd_table { | |||
2607 | #define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE 0x9c00 | 2596 | #define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE 0x9c00 |
2608 | #define INTEL_PCH_SPT_DEVICE_ID_TYPE 0xA100 | 2597 | #define INTEL_PCH_SPT_DEVICE_ID_TYPE 0xA100 |
2609 | #define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE 0x9D00 | 2598 | #define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE 0x9D00 |
2599 | #define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100 | ||
2610 | 2600 | ||
2611 | #define INTEL_PCH_TYPE(dev) (__I915__(dev)->pch_type) | 2601 | #define INTEL_PCH_TYPE(dev) (__I915__(dev)->pch_type) |
2612 | #define HAS_PCH_SPT(dev) (INTEL_PCH_TYPE(dev) == PCH_SPT) | 2602 | #define HAS_PCH_SPT(dev) (INTEL_PCH_TYPE(dev) == PCH_SPT) |
@@ -2824,6 +2814,8 @@ void i915_gem_vma_destroy(struct i915_vma *vma); | |||
2824 | #define PIN_OFFSET_BIAS (1<<3) | 2814 | #define PIN_OFFSET_BIAS (1<<3) |
2825 | #define PIN_USER (1<<4) | 2815 | #define PIN_USER (1<<4) |
2826 | #define PIN_UPDATE (1<<5) | 2816 | #define PIN_UPDATE (1<<5) |
2817 | #define PIN_ZONE_4G (1<<6) | ||
2818 | #define PIN_HIGH (1<<7) | ||
2827 | #define PIN_OFFSET_MASK (~4095) | 2819 | #define PIN_OFFSET_MASK (~4095) |
2828 | int __must_check | 2820 | int __must_check |
2829 | i915_gem_object_pin(struct drm_i915_gem_object *obj, | 2821 | i915_gem_object_pin(struct drm_i915_gem_object *obj, |
@@ -2839,6 +2831,11 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj, | |||
2839 | int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, | 2831 | int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, |
2840 | u32 flags); | 2832 | u32 flags); |
2841 | int __must_check i915_vma_unbind(struct i915_vma *vma); | 2833 | int __must_check i915_vma_unbind(struct i915_vma *vma); |
2834 | /* | ||
2835 | * BEWARE: Do not use the function below unless you can _absolutely_ | ||
2836 | * _guarantee_ VMA in question is _not in use_ anywhere. | ||
2837 | */ | ||
2838 | int __must_check __i915_vma_unbind_no_wait(struct i915_vma *vma); | ||
2842 | int i915_gem_object_put_pages(struct drm_i915_gem_object *obj); | 2839 | int i915_gem_object_put_pages(struct drm_i915_gem_object *obj); |
2843 | void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv); | 2840 | void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv); |
2844 | void i915_gem_release_mmap(struct drm_i915_gem_object *obj); | 2841 | void i915_gem_release_mmap(struct drm_i915_gem_object *obj); |
@@ -3167,7 +3164,6 @@ int __must_check i915_gem_evict_something(struct drm_device *dev, | |||
3167 | unsigned long end, | 3164 | unsigned long end, |
3168 | unsigned flags); | 3165 | unsigned flags); |
3169 | int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle); | 3166 | int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle); |
3170 | int i915_gem_evict_everything(struct drm_device *dev); | ||
3171 | 3167 | ||
3172 | /* belongs in i915_gem_gtt.h */ | 3168 | /* belongs in i915_gem_gtt.h */ |
3173 | static inline void i915_gem_chipset_flush(struct drm_device *dev) | 3169 | static inline void i915_gem_chipset_flush(struct drm_device *dev) |
@@ -3198,11 +3194,12 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, | |||
3198 | 3194 | ||
3199 | /* i915_gem_shrinker.c */ | 3195 | /* i915_gem_shrinker.c */ |
3200 | unsigned long i915_gem_shrink(struct drm_i915_private *dev_priv, | 3196 | unsigned long i915_gem_shrink(struct drm_i915_private *dev_priv, |
3201 | long target, | 3197 | unsigned long target, |
3202 | unsigned flags); | 3198 | unsigned flags); |
3203 | #define I915_SHRINK_PURGEABLE 0x1 | 3199 | #define I915_SHRINK_PURGEABLE 0x1 |
3204 | #define I915_SHRINK_UNBOUND 0x2 | 3200 | #define I915_SHRINK_UNBOUND 0x2 |
3205 | #define I915_SHRINK_BOUND 0x4 | 3201 | #define I915_SHRINK_BOUND 0x4 |
3202 | #define I915_SHRINK_ACTIVE 0x8 | ||
3206 | unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv); | 3203 | unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv); |
3207 | void i915_gem_shrinker_init(struct drm_i915_private *dev_priv); | 3204 | void i915_gem_shrinker_init(struct drm_i915_private *dev_priv); |
3208 | 3205 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bf5ef7a07878..1e67484fd5dc 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -3208,7 +3208,7 @@ static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj) | |||
3208 | old_write_domain); | 3208 | old_write_domain); |
3209 | } | 3209 | } |
3210 | 3210 | ||
3211 | int i915_vma_unbind(struct i915_vma *vma) | 3211 | static int __i915_vma_unbind(struct i915_vma *vma, bool wait) |
3212 | { | 3212 | { |
3213 | struct drm_i915_gem_object *obj = vma->obj; | 3213 | struct drm_i915_gem_object *obj = vma->obj; |
3214 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | 3214 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; |
@@ -3227,9 +3227,11 @@ int i915_vma_unbind(struct i915_vma *vma) | |||
3227 | 3227 | ||
3228 | BUG_ON(obj->pages == NULL); | 3228 | BUG_ON(obj->pages == NULL); |
3229 | 3229 | ||
3230 | ret = i915_gem_object_wait_rendering(obj, false); | 3230 | if (wait) { |
3231 | if (ret) | 3231 | ret = i915_gem_object_wait_rendering(obj, false); |
3232 | return ret; | 3232 | if (ret) |
3233 | return ret; | ||
3234 | } | ||
3233 | 3235 | ||
3234 | if (i915_is_ggtt(vma->vm) && | 3236 | if (i915_is_ggtt(vma->vm) && |
3235 | vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) { | 3237 | vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) { |
@@ -3274,6 +3276,16 @@ int i915_vma_unbind(struct i915_vma *vma) | |||
3274 | return 0; | 3276 | return 0; |
3275 | } | 3277 | } |
3276 | 3278 | ||
3279 | int i915_vma_unbind(struct i915_vma *vma) | ||
3280 | { | ||
3281 | return __i915_vma_unbind(vma, true); | ||
3282 | } | ||
3283 | |||
3284 | int __i915_vma_unbind_no_wait(struct i915_vma *vma) | ||
3285 | { | ||
3286 | return __i915_vma_unbind(vma, false); | ||
3287 | } | ||
3288 | |||
3277 | int i915_gpu_idle(struct drm_device *dev) | 3289 | int i915_gpu_idle(struct drm_device *dev) |
3278 | { | 3290 | { |
3279 | struct drm_i915_private *dev_priv = dev->dev_private; | 3291 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -3354,11 +3366,9 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, | |||
3354 | struct drm_device *dev = obj->base.dev; | 3366 | struct drm_device *dev = obj->base.dev; |
3355 | struct drm_i915_private *dev_priv = dev->dev_private; | 3367 | struct drm_i915_private *dev_priv = dev->dev_private; |
3356 | u32 fence_alignment, unfenced_alignment; | 3368 | u32 fence_alignment, unfenced_alignment; |
3369 | u32 search_flag, alloc_flag; | ||
3370 | u64 start, end; | ||
3357 | u64 size, fence_size; | 3371 | u64 size, fence_size; |
3358 | u64 start = | ||
3359 | flags & PIN_OFFSET_BIAS ? flags & PIN_OFFSET_MASK : 0; | ||
3360 | u64 end = | ||
3361 | flags & PIN_MAPPABLE ? dev_priv->gtt.mappable_end : vm->total; | ||
3362 | struct i915_vma *vma; | 3372 | struct i915_vma *vma; |
3363 | int ret; | 3373 | int ret; |
3364 | 3374 | ||
@@ -3398,6 +3408,13 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, | |||
3398 | size = flags & PIN_MAPPABLE ? fence_size : obj->base.size; | 3408 | size = flags & PIN_MAPPABLE ? fence_size : obj->base.size; |
3399 | } | 3409 | } |
3400 | 3410 | ||
3411 | start = flags & PIN_OFFSET_BIAS ? flags & PIN_OFFSET_MASK : 0; | ||
3412 | end = vm->total; | ||
3413 | if (flags & PIN_MAPPABLE) | ||
3414 | end = min_t(u64, end, dev_priv->gtt.mappable_end); | ||
3415 | if (flags & PIN_ZONE_4G) | ||
3416 | end = min_t(u64, end, (1ULL << 32)); | ||
3417 | |||
3401 | if (alignment == 0) | 3418 | if (alignment == 0) |
3402 | alignment = flags & PIN_MAPPABLE ? fence_alignment : | 3419 | alignment = flags & PIN_MAPPABLE ? fence_alignment : |
3403 | unfenced_alignment; | 3420 | unfenced_alignment; |
@@ -3433,13 +3450,21 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, | |||
3433 | if (IS_ERR(vma)) | 3450 | if (IS_ERR(vma)) |
3434 | goto err_unpin; | 3451 | goto err_unpin; |
3435 | 3452 | ||
3453 | if (flags & PIN_HIGH) { | ||
3454 | search_flag = DRM_MM_SEARCH_BELOW; | ||
3455 | alloc_flag = DRM_MM_CREATE_TOP; | ||
3456 | } else { | ||
3457 | search_flag = DRM_MM_SEARCH_DEFAULT; | ||
3458 | alloc_flag = DRM_MM_CREATE_DEFAULT; | ||
3459 | } | ||
3460 | |||
3436 | search_free: | 3461 | search_free: |
3437 | ret = drm_mm_insert_node_in_range_generic(&vm->mm, &vma->node, | 3462 | ret = drm_mm_insert_node_in_range_generic(&vm->mm, &vma->node, |
3438 | size, alignment, | 3463 | size, alignment, |
3439 | obj->cache_level, | 3464 | obj->cache_level, |
3440 | start, end, | 3465 | start, end, |
3441 | DRM_MM_SEARCH_DEFAULT, | 3466 | search_flag, |
3442 | DRM_MM_CREATE_DEFAULT); | 3467 | alloc_flag); |
3443 | if (ret) { | 3468 | if (ret) { |
3444 | ret = i915_gem_evict_something(dev, vm, size, alignment, | 3469 | ret = i915_gem_evict_something(dev, vm, size, alignment, |
3445 | obj->cache_level, | 3470 | obj->cache_level, |
@@ -4533,22 +4558,6 @@ void i915_gem_init_swizzling(struct drm_device *dev) | |||
4533 | BUG(); | 4558 | BUG(); |
4534 | } | 4559 | } |
4535 | 4560 | ||
4536 | static bool | ||
4537 | intel_enable_blt(struct drm_device *dev) | ||
4538 | { | ||
4539 | if (!HAS_BLT(dev)) | ||
4540 | return false; | ||
4541 | |||
4542 | /* The blitter was dysfunctional on early prototypes */ | ||
4543 | if (IS_GEN6(dev) && dev->pdev->revision < 8) { | ||
4544 | DRM_INFO("BLT not supported on this pre-production hardware;" | ||
4545 | " graphics performance will be degraded.\n"); | ||
4546 | return false; | ||
4547 | } | ||
4548 | |||
4549 | return true; | ||
4550 | } | ||
4551 | |||
4552 | static void init_unused_ring(struct drm_device *dev, u32 base) | 4561 | static void init_unused_ring(struct drm_device *dev, u32 base) |
4553 | { | 4562 | { |
4554 | struct drm_i915_private *dev_priv = dev->dev_private; | 4563 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -4591,7 +4600,7 @@ int i915_gem_init_rings(struct drm_device *dev) | |||
4591 | goto cleanup_render_ring; | 4600 | goto cleanup_render_ring; |
4592 | } | 4601 | } |
4593 | 4602 | ||
4594 | if (intel_enable_blt(dev)) { | 4603 | if (HAS_BLT(dev)) { |
4595 | ret = intel_init_blt_ring_buffer(dev); | 4604 | ret = intel_init_blt_ring_buffer(dev); |
4596 | if (ret) | 4605 | if (ret) |
4597 | goto cleanup_bsd_ring; | 4606 | goto cleanup_bsd_ring; |
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 74aa0c9929ba..8c688a5f1589 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
@@ -133,6 +133,23 @@ static int get_context_size(struct drm_device *dev) | |||
133 | return ret; | 133 | return ret; |
134 | } | 134 | } |
135 | 135 | ||
136 | static void i915_gem_context_clean(struct intel_context *ctx) | ||
137 | { | ||
138 | struct i915_hw_ppgtt *ppgtt = ctx->ppgtt; | ||
139 | struct i915_vma *vma, *next; | ||
140 | |||
141 | if (!ppgtt) | ||
142 | return; | ||
143 | |||
144 | WARN_ON(!list_empty(&ppgtt->base.active_list)); | ||
145 | |||
146 | list_for_each_entry_safe(vma, next, &ppgtt->base.inactive_list, | ||
147 | mm_list) { | ||
148 | if (WARN_ON(__i915_vma_unbind_no_wait(vma))) | ||
149 | break; | ||
150 | } | ||
151 | } | ||
152 | |||
136 | void i915_gem_context_free(struct kref *ctx_ref) | 153 | void i915_gem_context_free(struct kref *ctx_ref) |
137 | { | 154 | { |
138 | struct intel_context *ctx = container_of(ctx_ref, typeof(*ctx), ref); | 155 | struct intel_context *ctx = container_of(ctx_ref, typeof(*ctx), ref); |
@@ -142,6 +159,13 @@ void i915_gem_context_free(struct kref *ctx_ref) | |||
142 | if (i915.enable_execlists) | 159 | if (i915.enable_execlists) |
143 | intel_lr_context_free(ctx); | 160 | intel_lr_context_free(ctx); |
144 | 161 | ||
162 | /* | ||
163 | * This context is going away and we need to remove all VMAs still | ||
164 | * around. This is to handle imported shared objects for which | ||
165 | * destructor did not run when their handles were closed. | ||
166 | */ | ||
167 | i915_gem_context_clean(ctx); | ||
168 | |||
145 | i915_ppgtt_put(ctx->ppgtt); | 169 | i915_ppgtt_put(ctx->ppgtt); |
146 | 170 | ||
147 | if (ctx->legacy_hw_ctx.rcs_state) | 171 | if (ctx->legacy_hw_ctx.rcs_state) |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index d09e35ed9c9a..d71a133ceff5 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -237,48 +237,3 @@ int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle) | |||
237 | 237 | ||
238 | return 0; | 238 | return 0; |
239 | } | 239 | } |
240 | |||
241 | /** | ||
242 | * i915_gem_evict_everything - Try to evict all objects | ||
243 | * @dev: Device to evict objects for | ||
244 | * | ||
245 | * This functions tries to evict all gem objects from all address spaces. Used | ||
246 | * by the shrinker as a last-ditch effort and for suspend, before releasing the | ||
247 | * backing storage of all unbound objects. | ||
248 | */ | ||
249 | int | ||
250 | i915_gem_evict_everything(struct drm_device *dev) | ||
251 | { | ||
252 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
253 | struct i915_address_space *vm, *v; | ||
254 | bool lists_empty = true; | ||
255 | int ret; | ||
256 | |||
257 | list_for_each_entry(vm, &dev_priv->vm_list, global_link) { | ||
258 | lists_empty = (list_empty(&vm->inactive_list) && | ||
259 | list_empty(&vm->active_list)); | ||
260 | if (!lists_empty) | ||
261 | lists_empty = false; | ||
262 | } | ||
263 | |||
264 | if (lists_empty) | ||
265 | return -ENOSPC; | ||
266 | |||
267 | trace_i915_gem_evict_everything(dev); | ||
268 | |||
269 | /* The gpu_idle will flush everything in the write domain to the | ||
270 | * active list. Then we must move everything off the active list | ||
271 | * with retire requests. | ||
272 | */ | ||
273 | ret = i915_gpu_idle(dev); | ||
274 | if (ret) | ||
275 | return ret; | ||
276 | |||
277 | i915_gem_retire_requests(dev); | ||
278 | |||
279 | /* Having flushed everything, unbind() should never raise an error */ | ||
280 | list_for_each_entry_safe(vm, v, &dev_priv->vm_list, global_link) | ||
281 | WARN_ON(i915_gem_evict_vm(vm, false)); | ||
282 | |||
283 | return 0; | ||
284 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 67ef118ee160..6ed7d63a0688 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -590,10 +590,17 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, | |||
590 | flags |= PIN_GLOBAL; | 590 | flags |= PIN_GLOBAL; |
591 | 591 | ||
592 | if (!drm_mm_node_allocated(&vma->node)) { | 592 | if (!drm_mm_node_allocated(&vma->node)) { |
593 | /* Wa32bitGeneralStateOffset & Wa32bitInstructionBaseOffset, | ||
594 | * limit address to the first 4GBs for unflagged objects. | ||
595 | */ | ||
596 | if ((entry->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS) == 0) | ||
597 | flags |= PIN_ZONE_4G; | ||
593 | if (entry->flags & __EXEC_OBJECT_NEEDS_MAP) | 598 | if (entry->flags & __EXEC_OBJECT_NEEDS_MAP) |
594 | flags |= PIN_GLOBAL | PIN_MAPPABLE; | 599 | flags |= PIN_GLOBAL | PIN_MAPPABLE; |
595 | if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) | 600 | if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) |
596 | flags |= BATCH_OFFSET_BIAS | PIN_OFFSET_BIAS; | 601 | flags |= BATCH_OFFSET_BIAS | PIN_OFFSET_BIAS; |
602 | if ((flags & PIN_MAPPABLE) == 0) | ||
603 | flags |= PIN_HIGH; | ||
597 | } | 604 | } |
598 | 605 | ||
599 | ret = i915_gem_object_pin(obj, vma->vm, entry->alignment, flags); | 606 | ret = i915_gem_object_pin(obj, vma->vm, entry->alignment, flags); |
@@ -671,6 +678,10 @@ eb_vma_misplaced(struct i915_vma *vma) | |||
671 | if (entry->flags & __EXEC_OBJECT_NEEDS_MAP && !obj->map_and_fenceable) | 678 | if (entry->flags & __EXEC_OBJECT_NEEDS_MAP && !obj->map_and_fenceable) |
672 | return !only_mappable_for_reloc(entry->flags); | 679 | return !only_mappable_for_reloc(entry->flags); |
673 | 680 | ||
681 | if ((entry->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS) == 0 && | ||
682 | (vma->node.start + vma->node.size - 1) >> 32) | ||
683 | return true; | ||
684 | |||
674 | return false; | 685 | return false; |
675 | } | 686 | } |
676 | 687 | ||
@@ -934,7 +945,21 @@ i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec) | |||
934 | if (exec->flags & __I915_EXEC_UNKNOWN_FLAGS) | 945 | if (exec->flags & __I915_EXEC_UNKNOWN_FLAGS) |
935 | return false; | 946 | return false; |
936 | 947 | ||
937 | return ((exec->batch_start_offset | exec->batch_len) & 0x7) == 0; | 948 | /* Kernel clipping was a DRI1 misfeature */ |
949 | if (exec->num_cliprects || exec->cliprects_ptr) | ||
950 | return false; | ||
951 | |||
952 | if (exec->DR4 == 0xffffffff) { | ||
953 | DRM_DEBUG("UXA submitting garbage DR4, fixing up\n"); | ||
954 | exec->DR4 = 0; | ||
955 | } | ||
956 | if (exec->DR1 || exec->DR4) | ||
957 | return false; | ||
958 | |||
959 | if ((exec->batch_start_offset | exec->batch_len) & 0x7) | ||
960 | return false; | ||
961 | |||
962 | return true; | ||
938 | } | 963 | } |
939 | 964 | ||
940 | static int | 965 | static int |
@@ -1098,47 +1123,6 @@ i915_reset_gen7_sol_offsets(struct drm_device *dev, | |||
1098 | return 0; | 1123 | return 0; |
1099 | } | 1124 | } |
1100 | 1125 | ||
1101 | static int | ||
1102 | i915_emit_box(struct drm_i915_gem_request *req, | ||
1103 | struct drm_clip_rect *box, | ||
1104 | int DR1, int DR4) | ||
1105 | { | ||
1106 | struct intel_engine_cs *ring = req->ring; | ||
1107 | int ret; | ||
1108 | |||
1109 | if (box->y2 <= box->y1 || box->x2 <= box->x1 || | ||
1110 | box->y2 <= 0 || box->x2 <= 0) { | ||
1111 | DRM_ERROR("Bad box %d,%d..%d,%d\n", | ||
1112 | box->x1, box->y1, box->x2, box->y2); | ||
1113 | return -EINVAL; | ||
1114 | } | ||
1115 | |||
1116 | if (INTEL_INFO(ring->dev)->gen >= 4) { | ||
1117 | ret = intel_ring_begin(req, 4); | ||
1118 | if (ret) | ||
1119 | return ret; | ||
1120 | |||
1121 | intel_ring_emit(ring, GFX_OP_DRAWRECT_INFO_I965); | ||
1122 | intel_ring_emit(ring, (box->x1 & 0xffff) | box->y1 << 16); | ||
1123 | intel_ring_emit(ring, ((box->x2 - 1) & 0xffff) | (box->y2 - 1) << 16); | ||
1124 | intel_ring_emit(ring, DR4); | ||
1125 | } else { | ||
1126 | ret = intel_ring_begin(req, 6); | ||
1127 | if (ret) | ||
1128 | return ret; | ||
1129 | |||
1130 | intel_ring_emit(ring, GFX_OP_DRAWRECT_INFO); | ||
1131 | intel_ring_emit(ring, DR1); | ||
1132 | intel_ring_emit(ring, (box->x1 & 0xffff) | box->y1 << 16); | ||
1133 | intel_ring_emit(ring, ((box->x2 - 1) & 0xffff) | (box->y2 - 1) << 16); | ||
1134 | intel_ring_emit(ring, DR4); | ||
1135 | intel_ring_emit(ring, 0); | ||
1136 | } | ||
1137 | intel_ring_advance(ring); | ||
1138 | |||
1139 | return 0; | ||
1140 | } | ||
1141 | |||
1142 | static struct drm_i915_gem_object* | 1126 | static struct drm_i915_gem_object* |
1143 | i915_gem_execbuffer_parse(struct intel_engine_cs *ring, | 1127 | i915_gem_execbuffer_parse(struct intel_engine_cs *ring, |
1144 | struct drm_i915_gem_exec_object2 *shadow_exec_entry, | 1128 | struct drm_i915_gem_exec_object2 *shadow_exec_entry, |
@@ -1197,65 +1181,21 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params, | |||
1197 | struct drm_i915_gem_execbuffer2 *args, | 1181 | struct drm_i915_gem_execbuffer2 *args, |
1198 | struct list_head *vmas) | 1182 | struct list_head *vmas) |
1199 | { | 1183 | { |
1200 | struct drm_clip_rect *cliprects = NULL; | ||
1201 | struct drm_device *dev = params->dev; | 1184 | struct drm_device *dev = params->dev; |
1202 | struct intel_engine_cs *ring = params->ring; | 1185 | struct intel_engine_cs *ring = params->ring; |
1203 | struct drm_i915_private *dev_priv = dev->dev_private; | 1186 | struct drm_i915_private *dev_priv = dev->dev_private; |
1204 | u64 exec_start, exec_len; | 1187 | u64 exec_start, exec_len; |
1205 | int instp_mode; | 1188 | int instp_mode; |
1206 | u32 instp_mask; | 1189 | u32 instp_mask; |
1207 | int i, ret = 0; | 1190 | int ret; |
1208 | |||
1209 | if (args->num_cliprects != 0) { | ||
1210 | if (ring != &dev_priv->ring[RCS]) { | ||
1211 | DRM_DEBUG("clip rectangles are only valid with the render ring\n"); | ||
1212 | return -EINVAL; | ||
1213 | } | ||
1214 | |||
1215 | if (INTEL_INFO(dev)->gen >= 5) { | ||
1216 | DRM_DEBUG("clip rectangles are only valid on pre-gen5\n"); | ||
1217 | return -EINVAL; | ||
1218 | } | ||
1219 | |||
1220 | if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) { | ||
1221 | DRM_DEBUG("execbuf with %u cliprects\n", | ||
1222 | args->num_cliprects); | ||
1223 | return -EINVAL; | ||
1224 | } | ||
1225 | |||
1226 | cliprects = kcalloc(args->num_cliprects, | ||
1227 | sizeof(*cliprects), | ||
1228 | GFP_KERNEL); | ||
1229 | if (cliprects == NULL) { | ||
1230 | ret = -ENOMEM; | ||
1231 | goto error; | ||
1232 | } | ||
1233 | |||
1234 | if (copy_from_user(cliprects, | ||
1235 | to_user_ptr(args->cliprects_ptr), | ||
1236 | sizeof(*cliprects)*args->num_cliprects)) { | ||
1237 | ret = -EFAULT; | ||
1238 | goto error; | ||
1239 | } | ||
1240 | } else { | ||
1241 | if (args->DR4 == 0xffffffff) { | ||
1242 | DRM_DEBUG("UXA submitting garbage DR4, fixing up\n"); | ||
1243 | args->DR4 = 0; | ||
1244 | } | ||
1245 | |||
1246 | if (args->DR1 || args->DR4 || args->cliprects_ptr) { | ||
1247 | DRM_DEBUG("0 cliprects but dirt in cliprects fields\n"); | ||
1248 | return -EINVAL; | ||
1249 | } | ||
1250 | } | ||
1251 | 1191 | ||
1252 | ret = i915_gem_execbuffer_move_to_gpu(params->request, vmas); | 1192 | ret = i915_gem_execbuffer_move_to_gpu(params->request, vmas); |
1253 | if (ret) | 1193 | if (ret) |
1254 | goto error; | 1194 | return ret; |
1255 | 1195 | ||
1256 | ret = i915_switch_context(params->request); | 1196 | ret = i915_switch_context(params->request); |
1257 | if (ret) | 1197 | if (ret) |
1258 | goto error; | 1198 | return ret; |
1259 | 1199 | ||
1260 | WARN(params->ctx->ppgtt && params->ctx->ppgtt->pd_dirty_rings & (1<<ring->id), | 1200 | WARN(params->ctx->ppgtt && params->ctx->ppgtt->pd_dirty_rings & (1<<ring->id), |
1261 | "%s didn't clear reload\n", ring->name); | 1201 | "%s didn't clear reload\n", ring->name); |
@@ -1268,22 +1208,19 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params, | |||
1268 | case I915_EXEC_CONSTANTS_REL_SURFACE: | 1208 | case I915_EXEC_CONSTANTS_REL_SURFACE: |
1269 | if (instp_mode != 0 && ring != &dev_priv->ring[RCS]) { | 1209 | if (instp_mode != 0 && ring != &dev_priv->ring[RCS]) { |
1270 | DRM_DEBUG("non-0 rel constants mode on non-RCS\n"); | 1210 | DRM_DEBUG("non-0 rel constants mode on non-RCS\n"); |
1271 | ret = -EINVAL; | 1211 | return -EINVAL; |
1272 | goto error; | ||
1273 | } | 1212 | } |
1274 | 1213 | ||
1275 | if (instp_mode != dev_priv->relative_constants_mode) { | 1214 | if (instp_mode != dev_priv->relative_constants_mode) { |
1276 | if (INTEL_INFO(dev)->gen < 4) { | 1215 | if (INTEL_INFO(dev)->gen < 4) { |
1277 | DRM_DEBUG("no rel constants on pre-gen4\n"); | 1216 | DRM_DEBUG("no rel constants on pre-gen4\n"); |
1278 | ret = -EINVAL; | 1217 | return -EINVAL; |
1279 | goto error; | ||
1280 | } | 1218 | } |
1281 | 1219 | ||
1282 | if (INTEL_INFO(dev)->gen > 5 && | 1220 | if (INTEL_INFO(dev)->gen > 5 && |
1283 | instp_mode == I915_EXEC_CONSTANTS_REL_SURFACE) { | 1221 | instp_mode == I915_EXEC_CONSTANTS_REL_SURFACE) { |
1284 | DRM_DEBUG("rel surface constants mode invalid on gen5+\n"); | 1222 | DRM_DEBUG("rel surface constants mode invalid on gen5+\n"); |
1285 | ret = -EINVAL; | 1223 | return -EINVAL; |
1286 | goto error; | ||
1287 | } | 1224 | } |
1288 | 1225 | ||
1289 | /* The HW changed the meaning on this bit on gen6 */ | 1226 | /* The HW changed the meaning on this bit on gen6 */ |
@@ -1293,15 +1230,14 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params, | |||
1293 | break; | 1230 | break; |
1294 | default: | 1231 | default: |
1295 | DRM_DEBUG("execbuf with unknown constants: %d\n", instp_mode); | 1232 | DRM_DEBUG("execbuf with unknown constants: %d\n", instp_mode); |
1296 | ret = -EINVAL; | 1233 | return -EINVAL; |
1297 | goto error; | ||
1298 | } | 1234 | } |
1299 | 1235 | ||
1300 | if (ring == &dev_priv->ring[RCS] && | 1236 | if (ring == &dev_priv->ring[RCS] && |
1301 | instp_mode != dev_priv->relative_constants_mode) { | 1237 | instp_mode != dev_priv->relative_constants_mode) { |
1302 | ret = intel_ring_begin(params->request, 4); | 1238 | ret = intel_ring_begin(params->request, 4); |
1303 | if (ret) | 1239 | if (ret) |
1304 | goto error; | 1240 | return ret; |
1305 | 1241 | ||
1306 | intel_ring_emit(ring, MI_NOOP); | 1242 | intel_ring_emit(ring, MI_NOOP); |
1307 | intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); | 1243 | intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); |
@@ -1315,42 +1251,25 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params, | |||
1315 | if (args->flags & I915_EXEC_GEN7_SOL_RESET) { | 1251 | if (args->flags & I915_EXEC_GEN7_SOL_RESET) { |
1316 | ret = i915_reset_gen7_sol_offsets(dev, params->request); | 1252 | ret = i915_reset_gen7_sol_offsets(dev, params->request); |
1317 | if (ret) | 1253 | if (ret) |
1318 | goto error; | 1254 | return ret; |
1319 | } | 1255 | } |
1320 | 1256 | ||
1321 | exec_len = args->batch_len; | 1257 | exec_len = args->batch_len; |
1322 | exec_start = params->batch_obj_vm_offset + | 1258 | exec_start = params->batch_obj_vm_offset + |
1323 | params->args_batch_start_offset; | 1259 | params->args_batch_start_offset; |
1324 | 1260 | ||
1325 | if (cliprects) { | 1261 | ret = ring->dispatch_execbuffer(params->request, |
1326 | for (i = 0; i < args->num_cliprects; i++) { | 1262 | exec_start, exec_len, |
1327 | ret = i915_emit_box(params->request, &cliprects[i], | 1263 | params->dispatch_flags); |
1328 | args->DR1, args->DR4); | 1264 | if (ret) |
1329 | if (ret) | 1265 | return ret; |
1330 | goto error; | ||
1331 | |||
1332 | ret = ring->dispatch_execbuffer(params->request, | ||
1333 | exec_start, exec_len, | ||
1334 | params->dispatch_flags); | ||
1335 | if (ret) | ||
1336 | goto error; | ||
1337 | } | ||
1338 | } else { | ||
1339 | ret = ring->dispatch_execbuffer(params->request, | ||
1340 | exec_start, exec_len, | ||
1341 | params->dispatch_flags); | ||
1342 | if (ret) | ||
1343 | return ret; | ||
1344 | } | ||
1345 | 1266 | ||
1346 | trace_i915_gem_ring_dispatch(params->request, params->dispatch_flags); | 1267 | trace_i915_gem_ring_dispatch(params->request, params->dispatch_flags); |
1347 | 1268 | ||
1348 | i915_gem_execbuffer_move_to_active(vmas, params->request); | 1269 | i915_gem_execbuffer_move_to_active(vmas, params->request); |
1349 | i915_gem_execbuffer_retire_commands(params); | 1270 | i915_gem_execbuffer_retire_commands(params); |
1350 | 1271 | ||
1351 | error: | 1272 | return 0; |
1352 | kfree(cliprects); | ||
1353 | return ret; | ||
1354 | } | 1273 | } |
1355 | 1274 | ||
1356 | /** | 1275 | /** |
diff --git a/drivers/gpu/drm/i915/i915_gem_fence.c b/drivers/gpu/drm/i915/i915_gem_fence.c index ab80f7370ab7..40a10b25956c 100644 --- a/drivers/gpu/drm/i915/i915_gem_fence.c +++ b/drivers/gpu/drm/i915/i915_gem_fence.c | |||
@@ -59,19 +59,19 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg, | |||
59 | struct drm_i915_gem_object *obj) | 59 | struct drm_i915_gem_object *obj) |
60 | { | 60 | { |
61 | struct drm_i915_private *dev_priv = dev->dev_private; | 61 | struct drm_i915_private *dev_priv = dev->dev_private; |
62 | int fence_reg; | 62 | int fence_reg_lo, fence_reg_hi; |
63 | int fence_pitch_shift; | 63 | int fence_pitch_shift; |
64 | 64 | ||
65 | if (INTEL_INFO(dev)->gen >= 6) { | 65 | if (INTEL_INFO(dev)->gen >= 6) { |
66 | fence_reg = FENCE_REG_SANDYBRIDGE_0; | 66 | fence_reg_lo = FENCE_REG_GEN6_LO(reg); |
67 | fence_pitch_shift = SANDYBRIDGE_FENCE_PITCH_SHIFT; | 67 | fence_reg_hi = FENCE_REG_GEN6_HI(reg); |
68 | fence_pitch_shift = GEN6_FENCE_PITCH_SHIFT; | ||
68 | } else { | 69 | } else { |
69 | fence_reg = FENCE_REG_965_0; | 70 | fence_reg_lo = FENCE_REG_965_LO(reg); |
71 | fence_reg_hi = FENCE_REG_965_HI(reg); | ||
70 | fence_pitch_shift = I965_FENCE_PITCH_SHIFT; | 72 | fence_pitch_shift = I965_FENCE_PITCH_SHIFT; |
71 | } | 73 | } |
72 | 74 | ||
73 | fence_reg += reg * 8; | ||
74 | |||
75 | /* To w/a incoherency with non-atomic 64-bit register updates, | 75 | /* To w/a incoherency with non-atomic 64-bit register updates, |
76 | * we split the 64-bit update into two 32-bit writes. In order | 76 | * we split the 64-bit update into two 32-bit writes. In order |
77 | * for a partial fence not to be evaluated between writes, we | 77 | * for a partial fence not to be evaluated between writes, we |
@@ -81,8 +81,8 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg, | |||
81 | * For extra levels of paranoia, we make sure each step lands | 81 | * For extra levels of paranoia, we make sure each step lands |
82 | * before applying the next step. | 82 | * before applying the next step. |
83 | */ | 83 | */ |
84 | I915_WRITE(fence_reg, 0); | 84 | I915_WRITE(fence_reg_lo, 0); |
85 | POSTING_READ(fence_reg); | 85 | POSTING_READ(fence_reg_lo); |
86 | 86 | ||
87 | if (obj) { | 87 | if (obj) { |
88 | u32 size = i915_gem_obj_ggtt_size(obj); | 88 | u32 size = i915_gem_obj_ggtt_size(obj); |
@@ -103,14 +103,14 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg, | |||
103 | val |= 1 << I965_FENCE_TILING_Y_SHIFT; | 103 | val |= 1 << I965_FENCE_TILING_Y_SHIFT; |
104 | val |= I965_FENCE_REG_VALID; | 104 | val |= I965_FENCE_REG_VALID; |
105 | 105 | ||
106 | I915_WRITE(fence_reg + 4, val >> 32); | 106 | I915_WRITE(fence_reg_hi, val >> 32); |
107 | POSTING_READ(fence_reg + 4); | 107 | POSTING_READ(fence_reg_hi); |
108 | 108 | ||
109 | I915_WRITE(fence_reg + 0, val); | 109 | I915_WRITE(fence_reg_lo, val); |
110 | POSTING_READ(fence_reg); | 110 | POSTING_READ(fence_reg_lo); |
111 | } else { | 111 | } else { |
112 | I915_WRITE(fence_reg + 4, 0); | 112 | I915_WRITE(fence_reg_hi, 0); |
113 | POSTING_READ(fence_reg + 4); | 113 | POSTING_READ(fence_reg_hi); |
114 | } | 114 | } |
115 | } | 115 | } |
116 | 116 | ||
@@ -149,13 +149,8 @@ static void i915_write_fence_reg(struct drm_device *dev, int reg, | |||
149 | } else | 149 | } else |
150 | val = 0; | 150 | val = 0; |
151 | 151 | ||
152 | if (reg < 8) | 152 | I915_WRITE(FENCE_REG(reg), val); |
153 | reg = FENCE_REG_830_0 + reg * 4; | 153 | POSTING_READ(FENCE_REG(reg)); |
154 | else | ||
155 | reg = FENCE_REG_945_8 + (reg - 8) * 4; | ||
156 | |||
157 | I915_WRITE(reg, val); | ||
158 | POSTING_READ(reg); | ||
159 | } | 154 | } |
160 | 155 | ||
161 | static void i830_write_fence_reg(struct drm_device *dev, int reg, | 156 | static void i830_write_fence_reg(struct drm_device *dev, int reg, |
@@ -186,8 +181,8 @@ static void i830_write_fence_reg(struct drm_device *dev, int reg, | |||
186 | } else | 181 | } else |
187 | val = 0; | 182 | val = 0; |
188 | 183 | ||
189 | I915_WRITE(FENCE_REG_830_0 + reg * 4, val); | 184 | I915_WRITE(FENCE_REG(reg), val); |
190 | POSTING_READ(FENCE_REG_830_0 + reg * 4); | 185 | POSTING_READ(FENCE_REG(reg)); |
191 | } | 186 | } |
192 | 187 | ||
193 | inline static bool i915_gem_object_needs_mb(struct drm_i915_gem_object *obj) | 188 | inline static bool i915_gem_object_needs_mb(struct drm_i915_gem_object *obj) |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 47344d068f9a..620d57e2526b 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -2889,8 +2889,8 @@ static void bdw_setup_private_ppat(struct drm_i915_private *dev_priv) | |||
2889 | 2889 | ||
2890 | /* XXX: spec defines this as 2 distinct registers. It's unclear if a 64b | 2890 | /* XXX: spec defines this as 2 distinct registers. It's unclear if a 64b |
2891 | * write would work. */ | 2891 | * write would work. */ |
2892 | I915_WRITE(GEN8_PRIVATE_PAT, pat); | 2892 | I915_WRITE(GEN8_PRIVATE_PAT_LO, pat); |
2893 | I915_WRITE(GEN8_PRIVATE_PAT + 4, pat >> 32); | 2893 | I915_WRITE(GEN8_PRIVATE_PAT_HI, pat >> 32); |
2894 | } | 2894 | } |
2895 | 2895 | ||
2896 | static void chv_setup_private_ppat(struct drm_i915_private *dev_priv) | 2896 | static void chv_setup_private_ppat(struct drm_i915_private *dev_priv) |
@@ -2924,8 +2924,8 @@ static void chv_setup_private_ppat(struct drm_i915_private *dev_priv) | |||
2924 | GEN8_PPAT(6, CHV_PPAT_SNOOP) | | 2924 | GEN8_PPAT(6, CHV_PPAT_SNOOP) | |
2925 | GEN8_PPAT(7, CHV_PPAT_SNOOP); | 2925 | GEN8_PPAT(7, CHV_PPAT_SNOOP); |
2926 | 2926 | ||
2927 | I915_WRITE(GEN8_PRIVATE_PAT, pat); | 2927 | I915_WRITE(GEN8_PRIVATE_PAT_LO, pat); |
2928 | I915_WRITE(GEN8_PRIVATE_PAT + 4, pat >> 32); | 2928 | I915_WRITE(GEN8_PRIVATE_PAT_HI, pat >> 32); |
2929 | } | 2929 | } |
2930 | 2930 | ||
2931 | static int gen8_gmch_probe(struct drm_device *dev, | 2931 | static int gen8_gmch_probe(struct drm_device *dev, |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 9fbb07d6eaad..a216397ead52 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h | |||
@@ -394,7 +394,8 @@ struct i915_hw_ppgtt { | |||
394 | */ | 394 | */ |
395 | #define gen6_for_each_pde(pt, pd, start, length, temp, iter) \ | 395 | #define gen6_for_each_pde(pt, pd, start, length, temp, iter) \ |
396 | for (iter = gen6_pde_index(start); \ | 396 | for (iter = gen6_pde_index(start); \ |
397 | pt = (pd)->page_table[iter], length > 0 && iter < I915_PDES; \ | 397 | length > 0 && iter < I915_PDES ? \ |
398 | (pt = (pd)->page_table[iter]), 1 : 0; \ | ||
398 | iter++, \ | 399 | iter++, \ |
399 | temp = ALIGN(start+1, 1 << GEN6_PDE_SHIFT) - start, \ | 400 | temp = ALIGN(start+1, 1 << GEN6_PDE_SHIFT) - start, \ |
400 | temp = min_t(unsigned, temp, length), \ | 401 | temp = min_t(unsigned, temp, length), \ |
@@ -459,7 +460,8 @@ static inline uint32_t gen6_pde_index(uint32_t addr) | |||
459 | */ | 460 | */ |
460 | #define gen8_for_each_pde(pt, pd, start, length, temp, iter) \ | 461 | #define gen8_for_each_pde(pt, pd, start, length, temp, iter) \ |
461 | for (iter = gen8_pde_index(start); \ | 462 | for (iter = gen8_pde_index(start); \ |
462 | pt = (pd)->page_table[iter], length > 0 && iter < I915_PDES; \ | 463 | length > 0 && iter < I915_PDES ? \ |
464 | (pt = (pd)->page_table[iter]), 1 : 0; \ | ||
463 | iter++, \ | 465 | iter++, \ |
464 | temp = ALIGN(start+1, 1 << GEN8_PDE_SHIFT) - start, \ | 466 | temp = ALIGN(start+1, 1 << GEN8_PDE_SHIFT) - start, \ |
465 | temp = min(temp, length), \ | 467 | temp = min(temp, length), \ |
@@ -467,8 +469,8 @@ static inline uint32_t gen6_pde_index(uint32_t addr) | |||
467 | 469 | ||
468 | #define gen8_for_each_pdpe(pd, pdp, start, length, temp, iter) \ | 470 | #define gen8_for_each_pdpe(pd, pdp, start, length, temp, iter) \ |
469 | for (iter = gen8_pdpe_index(start); \ | 471 | for (iter = gen8_pdpe_index(start); \ |
470 | pd = (pdp)->page_directory[iter], \ | 472 | length > 0 && (iter < I915_PDPES_PER_PDP(dev)) ? \ |
471 | length > 0 && (iter < I915_PDPES_PER_PDP(dev)); \ | 473 | (pd = (pdp)->page_directory[iter]), 1 : 0; \ |
472 | iter++, \ | 474 | iter++, \ |
473 | temp = ALIGN(start+1, 1 << GEN8_PDPE_SHIFT) - start, \ | 475 | temp = ALIGN(start+1, 1 << GEN8_PDPE_SHIFT) - start, \ |
474 | temp = min(temp, length), \ | 476 | temp = min(temp, length), \ |
@@ -476,8 +478,8 @@ static inline uint32_t gen6_pde_index(uint32_t addr) | |||
476 | 478 | ||
477 | #define gen8_for_each_pml4e(pdp, pml4, start, length, temp, iter) \ | 479 | #define gen8_for_each_pml4e(pdp, pml4, start, length, temp, iter) \ |
478 | for (iter = gen8_pml4e_index(start); \ | 480 | for (iter = gen8_pml4e_index(start); \ |
479 | pdp = (pml4)->pdps[iter], \ | 481 | length > 0 && iter < GEN8_PML4ES_PER_PML4 ? \ |
480 | length > 0 && iter < GEN8_PML4ES_PER_PML4; \ | 482 | (pdp = (pml4)->pdps[iter]), 1 : 0; \ |
481 | iter++, \ | 483 | iter++, \ |
482 | temp = ALIGN(start+1, 1ULL << GEN8_PML4E_SHIFT) - start, \ | 484 | temp = ALIGN(start+1, 1ULL << GEN8_PML4E_SHIFT) - start, \ |
483 | temp = min(temp, length), \ | 485 | temp = min(temp, length), \ |
diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index f6ecbda2c604..f7df54a8ee2b 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c | |||
@@ -73,7 +73,7 @@ static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task) | |||
73 | */ | 73 | */ |
74 | unsigned long | 74 | unsigned long |
75 | i915_gem_shrink(struct drm_i915_private *dev_priv, | 75 | i915_gem_shrink(struct drm_i915_private *dev_priv, |
76 | long target, unsigned flags) | 76 | unsigned long target, unsigned flags) |
77 | { | 77 | { |
78 | const struct { | 78 | const struct { |
79 | struct list_head *list; | 79 | struct list_head *list; |
@@ -85,6 +85,9 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, | |||
85 | }, *phase; | 85 | }, *phase; |
86 | unsigned long count = 0; | 86 | unsigned long count = 0; |
87 | 87 | ||
88 | trace_i915_gem_shrink(dev_priv, target, flags); | ||
89 | i915_gem_retire_requests(dev_priv->dev); | ||
90 | |||
88 | /* | 91 | /* |
89 | * As we may completely rewrite the (un)bound list whilst unbinding | 92 | * As we may completely rewrite the (un)bound list whilst unbinding |
90 | * (due to retiring requests) we have to strictly process only | 93 | * (due to retiring requests) we have to strictly process only |
@@ -123,6 +126,9 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, | |||
123 | obj->madv != I915_MADV_DONTNEED) | 126 | obj->madv != I915_MADV_DONTNEED) |
124 | continue; | 127 | continue; |
125 | 128 | ||
129 | if ((flags & I915_SHRINK_ACTIVE) == 0 && obj->active) | ||
130 | continue; | ||
131 | |||
126 | drm_gem_object_reference(&obj->base); | 132 | drm_gem_object_reference(&obj->base); |
127 | 133 | ||
128 | /* For the unbound phase, this should be a no-op! */ | 134 | /* For the unbound phase, this should be a no-op! */ |
@@ -139,11 +145,13 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, | |||
139 | list_splice(&still_in_list, phase->list); | 145 | list_splice(&still_in_list, phase->list); |
140 | } | 146 | } |
141 | 147 | ||
148 | i915_gem_retire_requests(dev_priv->dev); | ||
149 | |||
142 | return count; | 150 | return count; |
143 | } | 151 | } |
144 | 152 | ||
145 | /** | 153 | /** |
146 | * i915_gem_shrink - Shrink buffer object caches completely | 154 | * i915_gem_shrink_all - Shrink buffer object caches completely |
147 | * @dev_priv: i915 device | 155 | * @dev_priv: i915 device |
148 | * | 156 | * |
149 | * This is a simple wraper around i915_gem_shrink() to aggressively shrink all | 157 | * This is a simple wraper around i915_gem_shrink() to aggressively shrink all |
@@ -158,9 +166,10 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, | |||
158 | */ | 166 | */ |
159 | unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv) | 167 | unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv) |
160 | { | 168 | { |
161 | i915_gem_evict_everything(dev_priv->dev); | 169 | return i915_gem_shrink(dev_priv, -1UL, |
162 | return i915_gem_shrink(dev_priv, LONG_MAX, | 170 | I915_SHRINK_BOUND | |
163 | I915_SHRINK_BOUND | I915_SHRINK_UNBOUND); | 171 | I915_SHRINK_UNBOUND | |
172 | I915_SHRINK_ACTIVE); | ||
164 | } | 173 | } |
165 | 174 | ||
166 | static bool i915_gem_shrinker_lock(struct drm_device *dev, bool *unlock) | 175 | static bool i915_gem_shrinker_lock(struct drm_device *dev, bool *unlock) |
@@ -213,7 +222,7 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) | |||
213 | count += obj->base.size >> PAGE_SHIFT; | 222 | count += obj->base.size >> PAGE_SHIFT; |
214 | 223 | ||
215 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { | 224 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { |
216 | if (obj->pages_pin_count == num_vma_bound(obj)) | 225 | if (!obj->active && obj->pages_pin_count == num_vma_bound(obj)) |
217 | count += obj->base.size >> PAGE_SHIFT; | 226 | count += obj->base.size >> PAGE_SHIFT; |
218 | } | 227 | } |
219 | 228 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 15207796e1b3..cdacf3f5b77a 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c | |||
@@ -30,6 +30,9 @@ | |||
30 | #include <drm/i915_drm.h> | 30 | #include <drm/i915_drm.h> |
31 | #include "i915_drv.h" | 31 | #include "i915_drv.h" |
32 | 32 | ||
33 | #define KB(x) ((x) * 1024) | ||
34 | #define MB(x) (KB(x) * 1024) | ||
35 | |||
33 | /* | 36 | /* |
34 | * The BIOS typically reserves some of the system's memory for the exclusive | 37 | * The BIOS typically reserves some of the system's memory for the exclusive |
35 | * use of the integrated graphics. This memory is no longer available for | 38 | * use of the integrated graphics. This memory is no longer available for |
@@ -51,6 +54,11 @@ int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *dev_priv, | |||
51 | if (!drm_mm_initialized(&dev_priv->mm.stolen)) | 54 | if (!drm_mm_initialized(&dev_priv->mm.stolen)) |
52 | return -ENODEV; | 55 | return -ENODEV; |
53 | 56 | ||
57 | /* See the comment at the drm_mm_init() call for more about this check. | ||
58 | * WaSkipStolenMemoryFirstPage:bdw,chv (incomplete) */ | ||
59 | if (INTEL_INFO(dev_priv)->gen == 8 && start < 4096) | ||
60 | start = 4096; | ||
61 | |||
54 | mutex_lock(&dev_priv->mm.stolen_lock); | 62 | mutex_lock(&dev_priv->mm.stolen_lock); |
55 | ret = drm_mm_insert_node_in_range(&dev_priv->mm.stolen, node, size, | 63 | ret = drm_mm_insert_node_in_range(&dev_priv->mm.stolen, node, size, |
56 | alignment, start, end, | 64 | alignment, start, end, |
@@ -86,24 +94,91 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) | |||
86 | /* Almost universally we can find the Graphics Base of Stolen Memory | 94 | /* Almost universally we can find the Graphics Base of Stolen Memory |
87 | * at offset 0x5c in the igfx configuration space. On a few (desktop) | 95 | * at offset 0x5c in the igfx configuration space. On a few (desktop) |
88 | * machines this is also mirrored in the bridge device at different | 96 | * machines this is also mirrored in the bridge device at different |
89 | * locations, or in the MCHBAR. On gen2, the layout is again slightly | 97 | * locations, or in the MCHBAR. |
90 | * different with the Graphics Segment immediately following Top of | 98 | * |
91 | * Memory (or Top of Usable DRAM). Note it appears that TOUD is only | 99 | * On 865 we just check the TOUD register. |
92 | * reported by 865g, so we just use the top of memory as determined | 100 | * |
93 | * by the e820 probe. | 101 | * On 830/845/85x the stolen memory base isn't available in any |
102 | * register. We need to calculate it as TOM-TSEG_SIZE-stolen_size. | ||
94 | * | 103 | * |
95 | * XXX However gen2 requires an unavailable symbol. | ||
96 | */ | 104 | */ |
97 | base = 0; | 105 | base = 0; |
98 | if (INTEL_INFO(dev)->gen >= 3) { | 106 | if (INTEL_INFO(dev)->gen >= 3) { |
99 | /* Read Graphics Base of Stolen Memory directly */ | 107 | /* Read Graphics Base of Stolen Memory directly */ |
100 | pci_read_config_dword(dev->pdev, 0x5c, &base); | 108 | pci_read_config_dword(dev->pdev, 0x5c, &base); |
101 | base &= ~((1<<20) - 1); | 109 | base &= ~((1<<20) - 1); |
102 | } else { /* GEN2 */ | 110 | } else if (IS_I865G(dev)) { |
103 | #if 0 | 111 | u16 toud = 0; |
104 | /* Stolen is immediately above Top of Memory */ | 112 | |
105 | base = max_low_pfn_mapped << PAGE_SHIFT; | 113 | /* |
106 | #endif | 114 | * FIXME is the graphics stolen memory region |
115 | * always at TOUD? Ie. is it always the last | ||
116 | * one to be allocated by the BIOS? | ||
117 | */ | ||
118 | pci_bus_read_config_word(dev->pdev->bus, PCI_DEVFN(0, 0), | ||
119 | I865_TOUD, &toud); | ||
120 | |||
121 | base = toud << 16; | ||
122 | } else if (IS_I85X(dev)) { | ||
123 | u32 tseg_size = 0; | ||
124 | u32 tom; | ||
125 | u8 tmp; | ||
126 | |||
127 | pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0), | ||
128 | I85X_ESMRAMC, &tmp); | ||
129 | |||
130 | if (tmp & TSEG_ENABLE) | ||
131 | tseg_size = MB(1); | ||
132 | |||
133 | pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 1), | ||
134 | I85X_DRB3, &tmp); | ||
135 | tom = tmp * MB(32); | ||
136 | |||
137 | base = tom - tseg_size - dev_priv->gtt.stolen_size; | ||
138 | } else if (IS_845G(dev)) { | ||
139 | u32 tseg_size = 0; | ||
140 | u32 tom; | ||
141 | u8 tmp; | ||
142 | |||
143 | pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0), | ||
144 | I845_ESMRAMC, &tmp); | ||
145 | |||
146 | if (tmp & TSEG_ENABLE) { | ||
147 | switch (tmp & I845_TSEG_SIZE_MASK) { | ||
148 | case I845_TSEG_SIZE_512K: | ||
149 | tseg_size = KB(512); | ||
150 | break; | ||
151 | case I845_TSEG_SIZE_1M: | ||
152 | tseg_size = MB(1); | ||
153 | break; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0), | ||
158 | I830_DRB3, &tmp); | ||
159 | tom = tmp * MB(32); | ||
160 | |||
161 | base = tom - tseg_size - dev_priv->gtt.stolen_size; | ||
162 | } else if (IS_I830(dev)) { | ||
163 | u32 tseg_size = 0; | ||
164 | u32 tom; | ||
165 | u8 tmp; | ||
166 | |||
167 | pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0), | ||
168 | I830_ESMRAMC, &tmp); | ||
169 | |||
170 | if (tmp & TSEG_ENABLE) { | ||
171 | if (tmp & I830_TSEG_SIZE_1M) | ||
172 | tseg_size = MB(1); | ||
173 | else | ||
174 | tseg_size = KB(512); | ||
175 | } | ||
176 | |||
177 | pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0), | ||
178 | I830_DRB3, &tmp); | ||
179 | tom = tmp * MB(32); | ||
180 | |||
181 | base = tom - tseg_size - dev_priv->gtt.stolen_size; | ||
107 | } | 182 | } |
108 | 183 | ||
109 | if (base == 0) | 184 | if (base == 0) |
@@ -393,7 +468,17 @@ int i915_gem_init_stolen(struct drm_device *dev) | |||
393 | dev_priv->gtt.stolen_usable_size = dev_priv->gtt.stolen_size - | 468 | dev_priv->gtt.stolen_usable_size = dev_priv->gtt.stolen_size - |
394 | reserved_total; | 469 | reserved_total; |
395 | 470 | ||
396 | /* Basic memrange allocator for stolen space */ | 471 | /* |
472 | * Basic memrange allocator for stolen space. | ||
473 | * | ||
474 | * TODO: Notice that some platforms require us to not use the first page | ||
475 | * of the stolen memory but their BIOSes may still put the framebuffer | ||
476 | * on the first page. So we don't reserve this page for now because of | ||
477 | * that. Our current solution is to just prevent new nodes from being | ||
478 | * inserted on the first page - see the check we have at | ||
479 | * i915_gem_stolen_insert_node_in_range(). We may want to fix the fbcon | ||
480 | * problem later. | ||
481 | */ | ||
397 | drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->gtt.stolen_usable_size); | 482 | drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->gtt.stolen_usable_size); |
398 | 483 | ||
399 | return 0; | 484 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index d11901d590ac..1b3b451b6658 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c | |||
@@ -50,7 +50,6 @@ struct i915_mmu_notifier { | |||
50 | struct mmu_notifier mn; | 50 | struct mmu_notifier mn; |
51 | struct rb_root objects; | 51 | struct rb_root objects; |
52 | struct list_head linear; | 52 | struct list_head linear; |
53 | unsigned long serial; | ||
54 | bool has_linear; | 53 | bool has_linear; |
55 | }; | 54 | }; |
56 | 55 | ||
@@ -59,13 +58,16 @@ struct i915_mmu_object { | |||
59 | struct interval_tree_node it; | 58 | struct interval_tree_node it; |
60 | struct list_head link; | 59 | struct list_head link; |
61 | struct drm_i915_gem_object *obj; | 60 | struct drm_i915_gem_object *obj; |
61 | struct work_struct work; | ||
62 | bool active; | ||
62 | bool is_linear; | 63 | bool is_linear; |
63 | }; | 64 | }; |
64 | 65 | ||
65 | static unsigned long cancel_userptr(struct drm_i915_gem_object *obj) | 66 | static void __cancel_userptr__worker(struct work_struct *work) |
66 | { | 67 | { |
68 | struct i915_mmu_object *mo = container_of(work, typeof(*mo), work); | ||
69 | struct drm_i915_gem_object *obj = mo->obj; | ||
67 | struct drm_device *dev = obj->base.dev; | 70 | struct drm_device *dev = obj->base.dev; |
68 | unsigned long end; | ||
69 | 71 | ||
70 | mutex_lock(&dev->struct_mutex); | 72 | mutex_lock(&dev->struct_mutex); |
71 | /* Cancel any active worker and force us to re-evaluate gup */ | 73 | /* Cancel any active worker and force us to re-evaluate gup */ |
@@ -88,45 +90,28 @@ static unsigned long cancel_userptr(struct drm_i915_gem_object *obj) | |||
88 | dev_priv->mm.interruptible = was_interruptible; | 90 | dev_priv->mm.interruptible = was_interruptible; |
89 | } | 91 | } |
90 | 92 | ||
91 | end = obj->userptr.ptr + obj->base.size; | ||
92 | |||
93 | drm_gem_object_unreference(&obj->base); | 93 | drm_gem_object_unreference(&obj->base); |
94 | mutex_unlock(&dev->struct_mutex); | 94 | mutex_unlock(&dev->struct_mutex); |
95 | |||
96 | return end; | ||
97 | } | 95 | } |
98 | 96 | ||
99 | static void *invalidate_range__linear(struct i915_mmu_notifier *mn, | 97 | static unsigned long cancel_userptr(struct i915_mmu_object *mo) |
100 | struct mm_struct *mm, | ||
101 | unsigned long start, | ||
102 | unsigned long end) | ||
103 | { | 98 | { |
104 | struct i915_mmu_object *mo; | 99 | unsigned long end = mo->obj->userptr.ptr + mo->obj->base.size; |
105 | unsigned long serial; | 100 | |
106 | 101 | /* The mmu_object is released late when destroying the | |
107 | restart: | 102 | * GEM object so it is entirely possible to gain a |
108 | serial = mn->serial; | 103 | * reference on an object in the process of being freed |
109 | list_for_each_entry(mo, &mn->linear, link) { | 104 | * since our serialisation is via the spinlock and not |
110 | struct drm_i915_gem_object *obj; | 105 | * the struct_mutex - and consequently use it after it |
111 | 106 | * is freed and then double free it. | |
112 | if (mo->it.last < start || mo->it.start > end) | 107 | */ |
113 | continue; | 108 | if (mo->active && kref_get_unless_zero(&mo->obj->base.refcount)) { |
114 | 109 | schedule_work(&mo->work); | |
115 | obj = mo->obj; | 110 | /* only schedule one work packet to avoid the refleak */ |
116 | 111 | mo->active = false; | |
117 | if (!kref_get_unless_zero(&obj->base.refcount)) | ||
118 | continue; | ||
119 | |||
120 | spin_unlock(&mn->lock); | ||
121 | |||
122 | cancel_userptr(obj); | ||
123 | |||
124 | spin_lock(&mn->lock); | ||
125 | if (serial != mn->serial) | ||
126 | goto restart; | ||
127 | } | 112 | } |
128 | 113 | ||
129 | return NULL; | 114 | return end; |
130 | } | 115 | } |
131 | 116 | ||
132 | static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn, | 117 | static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn, |
@@ -134,46 +119,32 @@ static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn, | |||
134 | unsigned long start, | 119 | unsigned long start, |
135 | unsigned long end) | 120 | unsigned long end) |
136 | { | 121 | { |
137 | struct i915_mmu_notifier *mn = container_of(_mn, struct i915_mmu_notifier, mn); | 122 | struct i915_mmu_notifier *mn = |
138 | struct interval_tree_node *it = NULL; | 123 | container_of(_mn, struct i915_mmu_notifier, mn); |
139 | unsigned long next = start; | 124 | struct i915_mmu_object *mo; |
140 | unsigned long serial = 0; | 125 | |
141 | 126 | /* interval ranges are inclusive, but invalidate range is exclusive */ | |
142 | end--; /* interval ranges are inclusive, but invalidate range is exclusive */ | 127 | end--; |
143 | while (next < end) { | 128 | |
144 | struct drm_i915_gem_object *obj = NULL; | 129 | spin_lock(&mn->lock); |
145 | 130 | if (mn->has_linear) { | |
146 | spin_lock(&mn->lock); | 131 | list_for_each_entry(mo, &mn->linear, link) { |
147 | if (mn->has_linear) | 132 | if (mo->it.last < start || mo->it.start > end) |
148 | it = invalidate_range__linear(mn, mm, start, end); | ||
149 | else if (serial == mn->serial) | ||
150 | it = interval_tree_iter_next(it, next, end); | ||
151 | else | ||
152 | it = interval_tree_iter_first(&mn->objects, start, end); | ||
153 | if (it != NULL) { | ||
154 | obj = container_of(it, struct i915_mmu_object, it)->obj; | ||
155 | |||
156 | /* The mmu_object is released late when destroying the | ||
157 | * GEM object so it is entirely possible to gain a | ||
158 | * reference on an object in the process of being freed | ||
159 | * since our serialisation is via the spinlock and not | ||
160 | * the struct_mutex - and consequently use it after it | ||
161 | * is freed and then double free it. | ||
162 | */ | ||
163 | if (!kref_get_unless_zero(&obj->base.refcount)) { | ||
164 | spin_unlock(&mn->lock); | ||
165 | serial = 0; | ||
166 | continue; | 133 | continue; |
167 | } | ||
168 | 134 | ||
169 | serial = mn->serial; | 135 | cancel_userptr(mo); |
170 | } | 136 | } |
171 | spin_unlock(&mn->lock); | 137 | } else { |
172 | if (obj == NULL) | 138 | struct interval_tree_node *it; |
173 | return; | ||
174 | 139 | ||
175 | next = cancel_userptr(obj); | 140 | it = interval_tree_iter_first(&mn->objects, start, end); |
141 | while (it) { | ||
142 | mo = container_of(it, struct i915_mmu_object, it); | ||
143 | start = cancel_userptr(mo); | ||
144 | it = interval_tree_iter_next(it, start, end); | ||
145 | } | ||
176 | } | 146 | } |
147 | spin_unlock(&mn->lock); | ||
177 | } | 148 | } |
178 | 149 | ||
179 | static const struct mmu_notifier_ops i915_gem_userptr_notifier = { | 150 | static const struct mmu_notifier_ops i915_gem_userptr_notifier = { |
@@ -193,7 +164,6 @@ i915_mmu_notifier_create(struct mm_struct *mm) | |||
193 | spin_lock_init(&mn->lock); | 164 | spin_lock_init(&mn->lock); |
194 | mn->mn.ops = &i915_gem_userptr_notifier; | 165 | mn->mn.ops = &i915_gem_userptr_notifier; |
195 | mn->objects = RB_ROOT; | 166 | mn->objects = RB_ROOT; |
196 | mn->serial = 1; | ||
197 | INIT_LIST_HEAD(&mn->linear); | 167 | INIT_LIST_HEAD(&mn->linear); |
198 | mn->has_linear = false; | 168 | mn->has_linear = false; |
199 | 169 | ||
@@ -207,12 +177,6 @@ i915_mmu_notifier_create(struct mm_struct *mm) | |||
207 | return mn; | 177 | return mn; |
208 | } | 178 | } |
209 | 179 | ||
210 | static void __i915_mmu_notifier_update_serial(struct i915_mmu_notifier *mn) | ||
211 | { | ||
212 | if (++mn->serial == 0) | ||
213 | mn->serial = 1; | ||
214 | } | ||
215 | |||
216 | static int | 180 | static int |
217 | i915_mmu_notifier_add(struct drm_device *dev, | 181 | i915_mmu_notifier_add(struct drm_device *dev, |
218 | struct i915_mmu_notifier *mn, | 182 | struct i915_mmu_notifier *mn, |
@@ -259,10 +223,9 @@ i915_mmu_notifier_add(struct drm_device *dev, | |||
259 | } else | 223 | } else |
260 | interval_tree_insert(&mo->it, &mn->objects); | 224 | interval_tree_insert(&mo->it, &mn->objects); |
261 | 225 | ||
262 | if (ret == 0) { | 226 | if (ret == 0) |
263 | list_add(&mo->link, &mn->linear); | 227 | list_add(&mo->link, &mn->linear); |
264 | __i915_mmu_notifier_update_serial(mn); | 228 | |
265 | } | ||
266 | spin_unlock(&mn->lock); | 229 | spin_unlock(&mn->lock); |
267 | mutex_unlock(&dev->struct_mutex); | 230 | mutex_unlock(&dev->struct_mutex); |
268 | 231 | ||
@@ -290,7 +253,6 @@ i915_mmu_notifier_del(struct i915_mmu_notifier *mn, | |||
290 | mn->has_linear = i915_mmu_notifier_has_linear(mn); | 253 | mn->has_linear = i915_mmu_notifier_has_linear(mn); |
291 | else | 254 | else |
292 | interval_tree_remove(&mo->it, &mn->objects); | 255 | interval_tree_remove(&mo->it, &mn->objects); |
293 | __i915_mmu_notifier_update_serial(mn); | ||
294 | spin_unlock(&mn->lock); | 256 | spin_unlock(&mn->lock); |
295 | } | 257 | } |
296 | 258 | ||
@@ -357,6 +319,7 @@ i915_gem_userptr_init__mmu_notifier(struct drm_i915_gem_object *obj, | |||
357 | mo->it.start = obj->userptr.ptr; | 319 | mo->it.start = obj->userptr.ptr; |
358 | mo->it.last = mo->it.start + obj->base.size - 1; | 320 | mo->it.last = mo->it.start + obj->base.size - 1; |
359 | mo->obj = obj; | 321 | mo->obj = obj; |
322 | INIT_WORK(&mo->work, __cancel_userptr__worker); | ||
360 | 323 | ||
361 | ret = i915_mmu_notifier_add(obj->base.dev, mn, mo); | 324 | ret = i915_mmu_notifier_add(obj->base.dev, mn, mo); |
362 | if (ret) { | 325 | if (ret) { |
@@ -565,31 +528,65 @@ __i915_gem_userptr_set_pages(struct drm_i915_gem_object *obj, | |||
565 | return ret; | 528 | return ret; |
566 | } | 529 | } |
567 | 530 | ||
531 | static int | ||
532 | __i915_gem_userptr_set_active(struct drm_i915_gem_object *obj, | ||
533 | bool value) | ||
534 | { | ||
535 | int ret = 0; | ||
536 | |||
537 | /* During mm_invalidate_range we need to cancel any userptr that | ||
538 | * overlaps the range being invalidated. Doing so requires the | ||
539 | * struct_mutex, and that risks recursion. In order to cause | ||
540 | * recursion, the user must alias the userptr address space with | ||
541 | * a GTT mmapping (possible with a MAP_FIXED) - then when we have | ||
542 | * to invalidate that mmaping, mm_invalidate_range is called with | ||
543 | * the userptr address *and* the struct_mutex held. To prevent that | ||
544 | * we set a flag under the i915_mmu_notifier spinlock to indicate | ||
545 | * whether this object is valid. | ||
546 | */ | ||
547 | #if defined(CONFIG_MMU_NOTIFIER) | ||
548 | if (obj->userptr.mmu_object == NULL) | ||
549 | return 0; | ||
550 | |||
551 | spin_lock(&obj->userptr.mmu_object->mn->lock); | ||
552 | /* In order to serialise get_pages with an outstanding | ||
553 | * cancel_userptr, we must drop the struct_mutex and try again. | ||
554 | */ | ||
555 | if (!value || !work_pending(&obj->userptr.mmu_object->work)) | ||
556 | obj->userptr.mmu_object->active = value; | ||
557 | else | ||
558 | ret = -EAGAIN; | ||
559 | spin_unlock(&obj->userptr.mmu_object->mn->lock); | ||
560 | #endif | ||
561 | |||
562 | return ret; | ||
563 | } | ||
564 | |||
568 | static void | 565 | static void |
569 | __i915_gem_userptr_get_pages_worker(struct work_struct *_work) | 566 | __i915_gem_userptr_get_pages_worker(struct work_struct *_work) |
570 | { | 567 | { |
571 | struct get_pages_work *work = container_of(_work, typeof(*work), work); | 568 | struct get_pages_work *work = container_of(_work, typeof(*work), work); |
572 | struct drm_i915_gem_object *obj = work->obj; | 569 | struct drm_i915_gem_object *obj = work->obj; |
573 | struct drm_device *dev = obj->base.dev; | 570 | struct drm_device *dev = obj->base.dev; |
574 | const int num_pages = obj->base.size >> PAGE_SHIFT; | 571 | const int npages = obj->base.size >> PAGE_SHIFT; |
575 | struct page **pvec; | 572 | struct page **pvec; |
576 | int pinned, ret; | 573 | int pinned, ret; |
577 | 574 | ||
578 | ret = -ENOMEM; | 575 | ret = -ENOMEM; |
579 | pinned = 0; | 576 | pinned = 0; |
580 | 577 | ||
581 | pvec = kmalloc(num_pages*sizeof(struct page *), | 578 | pvec = kmalloc(npages*sizeof(struct page *), |
582 | GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY); | 579 | GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY); |
583 | if (pvec == NULL) | 580 | if (pvec == NULL) |
584 | pvec = drm_malloc_ab(num_pages, sizeof(struct page *)); | 581 | pvec = drm_malloc_ab(npages, sizeof(struct page *)); |
585 | if (pvec != NULL) { | 582 | if (pvec != NULL) { |
586 | struct mm_struct *mm = obj->userptr.mm->mm; | 583 | struct mm_struct *mm = obj->userptr.mm->mm; |
587 | 584 | ||
588 | down_read(&mm->mmap_sem); | 585 | down_read(&mm->mmap_sem); |
589 | while (pinned < num_pages) { | 586 | while (pinned < npages) { |
590 | ret = get_user_pages(work->task, mm, | 587 | ret = get_user_pages(work->task, mm, |
591 | obj->userptr.ptr + pinned * PAGE_SIZE, | 588 | obj->userptr.ptr + pinned * PAGE_SIZE, |
592 | num_pages - pinned, | 589 | npages - pinned, |
593 | !obj->userptr.read_only, 0, | 590 | !obj->userptr.read_only, 0, |
594 | pvec + pinned, NULL); | 591 | pvec + pinned, NULL); |
595 | if (ret < 0) | 592 | if (ret < 0) |
@@ -601,20 +598,22 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) | |||
601 | } | 598 | } |
602 | 599 | ||
603 | mutex_lock(&dev->struct_mutex); | 600 | mutex_lock(&dev->struct_mutex); |
604 | if (obj->userptr.work != &work->work) { | 601 | if (obj->userptr.work == &work->work) { |
605 | ret = 0; | 602 | if (pinned == npages) { |
606 | } else if (pinned == num_pages) { | 603 | ret = __i915_gem_userptr_set_pages(obj, pvec, npages); |
607 | ret = __i915_gem_userptr_set_pages(obj, pvec, num_pages); | 604 | if (ret == 0) { |
608 | if (ret == 0) { | 605 | list_add_tail(&obj->global_list, |
609 | list_add_tail(&obj->global_list, &to_i915(dev)->mm.unbound_list); | 606 | &to_i915(dev)->mm.unbound_list); |
610 | obj->get_page.sg = obj->pages->sgl; | 607 | obj->get_page.sg = obj->pages->sgl; |
611 | obj->get_page.last = 0; | 608 | obj->get_page.last = 0; |
612 | 609 | pinned = 0; | |
613 | pinned = 0; | 610 | } |
614 | } | 611 | } |
612 | obj->userptr.work = ERR_PTR(ret); | ||
613 | if (ret) | ||
614 | __i915_gem_userptr_set_active(obj, false); | ||
615 | } | 615 | } |
616 | 616 | ||
617 | obj->userptr.work = ERR_PTR(ret); | ||
618 | obj->userptr.workers--; | 617 | obj->userptr.workers--; |
619 | drm_gem_object_unreference(&obj->base); | 618 | drm_gem_object_unreference(&obj->base); |
620 | mutex_unlock(&dev->struct_mutex); | 619 | mutex_unlock(&dev->struct_mutex); |
@@ -627,11 +626,60 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) | |||
627 | } | 626 | } |
628 | 627 | ||
629 | static int | 628 | static int |
629 | __i915_gem_userptr_get_pages_schedule(struct drm_i915_gem_object *obj, | ||
630 | bool *active) | ||
631 | { | ||
632 | struct get_pages_work *work; | ||
633 | |||
634 | /* Spawn a worker so that we can acquire the | ||
635 | * user pages without holding our mutex. Access | ||
636 | * to the user pages requires mmap_sem, and we have | ||
637 | * a strict lock ordering of mmap_sem, struct_mutex - | ||
638 | * we already hold struct_mutex here and so cannot | ||
639 | * call gup without encountering a lock inversion. | ||
640 | * | ||
641 | * Userspace will keep on repeating the operation | ||
642 | * (thanks to EAGAIN) until either we hit the fast | ||
643 | * path or the worker completes. If the worker is | ||
644 | * cancelled or superseded, the task is still run | ||
645 | * but the results ignored. (This leads to | ||
646 | * complications that we may have a stray object | ||
647 | * refcount that we need to be wary of when | ||
648 | * checking for existing objects during creation.) | ||
649 | * If the worker encounters an error, it reports | ||
650 | * that error back to this function through | ||
651 | * obj->userptr.work = ERR_PTR. | ||
652 | */ | ||
653 | if (obj->userptr.workers >= I915_GEM_USERPTR_MAX_WORKERS) | ||
654 | return -EAGAIN; | ||
655 | |||
656 | work = kmalloc(sizeof(*work), GFP_KERNEL); | ||
657 | if (work == NULL) | ||
658 | return -ENOMEM; | ||
659 | |||
660 | obj->userptr.work = &work->work; | ||
661 | obj->userptr.workers++; | ||
662 | |||
663 | work->obj = obj; | ||
664 | drm_gem_object_reference(&obj->base); | ||
665 | |||
666 | work->task = current; | ||
667 | get_task_struct(work->task); | ||
668 | |||
669 | INIT_WORK(&work->work, __i915_gem_userptr_get_pages_worker); | ||
670 | schedule_work(&work->work); | ||
671 | |||
672 | *active = true; | ||
673 | return -EAGAIN; | ||
674 | } | ||
675 | |||
676 | static int | ||
630 | i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) | 677 | i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) |
631 | { | 678 | { |
632 | const int num_pages = obj->base.size >> PAGE_SHIFT; | 679 | const int num_pages = obj->base.size >> PAGE_SHIFT; |
633 | struct page **pvec; | 680 | struct page **pvec; |
634 | int pinned, ret; | 681 | int pinned, ret; |
682 | bool active; | ||
635 | 683 | ||
636 | /* If userspace should engineer that these pages are replaced in | 684 | /* If userspace should engineer that these pages are replaced in |
637 | * the vma between us binding this page into the GTT and completion | 685 | * the vma between us binding this page into the GTT and completion |
@@ -649,6 +697,20 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) | |||
649 | * to the vma (discard or cloning) which should prevent the more | 697 | * to the vma (discard or cloning) which should prevent the more |
650 | * egregious cases from causing harm. | 698 | * egregious cases from causing harm. |
651 | */ | 699 | */ |
700 | if (IS_ERR(obj->userptr.work)) { | ||
701 | /* active flag will have been dropped already by the worker */ | ||
702 | ret = PTR_ERR(obj->userptr.work); | ||
703 | obj->userptr.work = NULL; | ||
704 | return ret; | ||
705 | } | ||
706 | if (obj->userptr.work) | ||
707 | /* active flag should still be held for the pending work */ | ||
708 | return -EAGAIN; | ||
709 | |||
710 | /* Let the mmu-notifier know that we have begun and need cancellation */ | ||
711 | ret = __i915_gem_userptr_set_active(obj, true); | ||
712 | if (ret) | ||
713 | return ret; | ||
652 | 714 | ||
653 | pvec = NULL; | 715 | pvec = NULL; |
654 | pinned = 0; | 716 | pinned = 0; |
@@ -657,73 +719,27 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) | |||
657 | GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY); | 719 | GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY); |
658 | if (pvec == NULL) { | 720 | if (pvec == NULL) { |
659 | pvec = drm_malloc_ab(num_pages, sizeof(struct page *)); | 721 | pvec = drm_malloc_ab(num_pages, sizeof(struct page *)); |
660 | if (pvec == NULL) | 722 | if (pvec == NULL) { |
723 | __i915_gem_userptr_set_active(obj, false); | ||
661 | return -ENOMEM; | 724 | return -ENOMEM; |
725 | } | ||
662 | } | 726 | } |
663 | 727 | ||
664 | pinned = __get_user_pages_fast(obj->userptr.ptr, num_pages, | 728 | pinned = __get_user_pages_fast(obj->userptr.ptr, num_pages, |
665 | !obj->userptr.read_only, pvec); | 729 | !obj->userptr.read_only, pvec); |
666 | } | 730 | } |
667 | if (pinned < num_pages) { | 731 | |
668 | if (pinned < 0) { | 732 | active = false; |
669 | ret = pinned; | 733 | if (pinned < 0) |
670 | pinned = 0; | 734 | ret = pinned, pinned = 0; |
671 | } else { | 735 | else if (pinned < num_pages) |
672 | /* Spawn a worker so that we can acquire the | 736 | ret = __i915_gem_userptr_get_pages_schedule(obj, &active); |
673 | * user pages without holding our mutex. Access | 737 | else |
674 | * to the user pages requires mmap_sem, and we have | ||
675 | * a strict lock ordering of mmap_sem, struct_mutex - | ||
676 | * we already hold struct_mutex here and so cannot | ||
677 | * call gup without encountering a lock inversion. | ||
678 | * | ||
679 | * Userspace will keep on repeating the operation | ||
680 | * (thanks to EAGAIN) until either we hit the fast | ||
681 | * path or the worker completes. If the worker is | ||
682 | * cancelled or superseded, the task is still run | ||
683 | * but the results ignored. (This leads to | ||
684 | * complications that we may have a stray object | ||
685 | * refcount that we need to be wary of when | ||
686 | * checking for existing objects during creation.) | ||
687 | * If the worker encounters an error, it reports | ||
688 | * that error back to this function through | ||
689 | * obj->userptr.work = ERR_PTR. | ||
690 | */ | ||
691 | ret = -EAGAIN; | ||
692 | if (obj->userptr.work == NULL && | ||
693 | obj->userptr.workers < I915_GEM_USERPTR_MAX_WORKERS) { | ||
694 | struct get_pages_work *work; | ||
695 | |||
696 | work = kmalloc(sizeof(*work), GFP_KERNEL); | ||
697 | if (work != NULL) { | ||
698 | obj->userptr.work = &work->work; | ||
699 | obj->userptr.workers++; | ||
700 | |||
701 | work->obj = obj; | ||
702 | drm_gem_object_reference(&obj->base); | ||
703 | |||
704 | work->task = current; | ||
705 | get_task_struct(work->task); | ||
706 | |||
707 | INIT_WORK(&work->work, __i915_gem_userptr_get_pages_worker); | ||
708 | schedule_work(&work->work); | ||
709 | } else | ||
710 | ret = -ENOMEM; | ||
711 | } else { | ||
712 | if (IS_ERR(obj->userptr.work)) { | ||
713 | ret = PTR_ERR(obj->userptr.work); | ||
714 | obj->userptr.work = NULL; | ||
715 | } | ||
716 | } | ||
717 | } | ||
718 | } else { | ||
719 | ret = __i915_gem_userptr_set_pages(obj, pvec, num_pages); | 738 | ret = __i915_gem_userptr_set_pages(obj, pvec, num_pages); |
720 | if (ret == 0) { | 739 | if (ret) { |
721 | obj->userptr.work = NULL; | 740 | __i915_gem_userptr_set_active(obj, active); |
722 | pinned = 0; | 741 | release_pages(pvec, pinned, 0); |
723 | } | ||
724 | } | 742 | } |
725 | |||
726 | release_pages(pvec, pinned, 0); | ||
727 | drm_free_large(pvec); | 743 | drm_free_large(pvec); |
728 | return ret; | 744 | return ret; |
729 | } | 745 | } |
@@ -734,6 +750,7 @@ i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj) | |||
734 | struct sg_page_iter sg_iter; | 750 | struct sg_page_iter sg_iter; |
735 | 751 | ||
736 | BUG_ON(obj->userptr.work != NULL); | 752 | BUG_ON(obj->userptr.work != NULL); |
753 | __i915_gem_userptr_set_active(obj, false); | ||
737 | 754 | ||
738 | if (obj->madv != I915_MADV_WILLNEED) | 755 | if (obj->madv != I915_MADV_WILLNEED) |
739 | obj->dirty = 0; | 756 | obj->dirty = 0; |
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index f95de05f793d..2f04e4f2ff35 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c | |||
@@ -792,20 +792,15 @@ static void i915_gem_record_fences(struct drm_device *dev, | |||
792 | int i; | 792 | int i; |
793 | 793 | ||
794 | if (IS_GEN3(dev) || IS_GEN2(dev)) { | 794 | if (IS_GEN3(dev) || IS_GEN2(dev)) { |
795 | for (i = 0; i < 8; i++) | ||
796 | error->fence[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); | ||
797 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) | ||
798 | for (i = 0; i < 8; i++) | ||
799 | error->fence[i+8] = I915_READ(FENCE_REG_945_8 + | ||
800 | (i * 4)); | ||
801 | } else if (IS_GEN5(dev) || IS_GEN4(dev)) | ||
802 | for (i = 0; i < 16; i++) | ||
803 | error->fence[i] = I915_READ64(FENCE_REG_965_0 + | ||
804 | (i * 8)); | ||
805 | else if (INTEL_INFO(dev)->gen >= 6) | ||
806 | for (i = 0; i < dev_priv->num_fence_regs; i++) | 795 | for (i = 0; i < dev_priv->num_fence_regs; i++) |
807 | error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + | 796 | error->fence[i] = I915_READ(FENCE_REG(i)); |
808 | (i * 8)); | 797 | } else if (IS_GEN5(dev) || IS_GEN4(dev)) { |
798 | for (i = 0; i < dev_priv->num_fence_regs; i++) | ||
799 | error->fence[i] = I915_READ64(FENCE_REG_965_LO(i)); | ||
800 | } else if (INTEL_INFO(dev)->gen >= 6) { | ||
801 | for (i = 0; i < dev_priv->num_fence_regs; i++) | ||
802 | error->fence[i] = I915_READ64(FENCE_REG_GEN6_LO(i)); | ||
803 | } | ||
809 | } | 804 | } |
810 | 805 | ||
811 | 806 | ||
@@ -891,7 +886,7 @@ static void i915_record_ring_state(struct drm_device *dev, | |||
891 | ering->faddr = I915_READ(DMA_FADD_I8XX); | 886 | ering->faddr = I915_READ(DMA_FADD_I8XX); |
892 | ering->ipeir = I915_READ(IPEIR); | 887 | ering->ipeir = I915_READ(IPEIR); |
893 | ering->ipehr = I915_READ(IPEHR); | 888 | ering->ipehr = I915_READ(IPEHR); |
894 | ering->instdone = I915_READ(INSTDONE); | 889 | ering->instdone = I915_READ(GEN2_INSTDONE); |
895 | } | 890 | } |
896 | 891 | ||
897 | ering->waiting = waitqueue_active(&ring->irq_queue); | 892 | ering->waiting = waitqueue_active(&ring->irq_queue); |
@@ -1393,12 +1388,12 @@ void i915_get_extra_instdone(struct drm_device *dev, uint32_t *instdone) | |||
1393 | memset(instdone, 0, sizeof(*instdone) * I915_NUM_INSTDONE_REG); | 1388 | memset(instdone, 0, sizeof(*instdone) * I915_NUM_INSTDONE_REG); |
1394 | 1389 | ||
1395 | if (IS_GEN2(dev) || IS_GEN3(dev)) | 1390 | if (IS_GEN2(dev) || IS_GEN3(dev)) |
1396 | instdone[0] = I915_READ(INSTDONE); | 1391 | instdone[0] = I915_READ(GEN2_INSTDONE); |
1397 | else if (IS_GEN4(dev) || IS_GEN5(dev) || IS_GEN6(dev)) { | 1392 | else if (IS_GEN4(dev) || IS_GEN5(dev) || IS_GEN6(dev)) { |
1398 | instdone[0] = I915_READ(INSTDONE_I965); | 1393 | instdone[0] = I915_READ(RING_INSTDONE(RENDER_RING_BASE)); |
1399 | instdone[1] = I915_READ(INSTDONE1); | 1394 | instdone[1] = I915_READ(GEN4_INSTDONE1); |
1400 | } else if (INTEL_INFO(dev)->gen >= 7) { | 1395 | } else if (INTEL_INFO(dev)->gen >= 7) { |
1401 | instdone[0] = I915_READ(GEN7_INSTDONE_1); | 1396 | instdone[0] = I915_READ(RING_INSTDONE(RENDER_RING_BASE)); |
1402 | instdone[1] = I915_READ(GEN7_SC_INSTDONE); | 1397 | instdone[1] = I915_READ(GEN7_SC_INSTDONE); |
1403 | instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE); | 1398 | instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE); |
1404 | instdone[3] = I915_READ(GEN7_ROW_INSTDONE); | 1399 | instdone[3] = I915_READ(GEN7_ROW_INSTDONE); |
diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h b/drivers/gpu/drm/i915/i915_guc_reg.h index 9d79a6b7cc2f..c4cb1c0c4d0d 100644 --- a/drivers/gpu/drm/i915/i915_guc_reg.h +++ b/drivers/gpu/drm/i915/i915_guc_reg.h | |||
@@ -37,10 +37,11 @@ | |||
37 | #define GS_UKERNEL_READY (0xF0 << GS_UKERNEL_SHIFT) | 37 | #define GS_UKERNEL_READY (0xF0 << GS_UKERNEL_SHIFT) |
38 | #define GS_MIA_SHIFT 16 | 38 | #define GS_MIA_SHIFT 16 |
39 | #define GS_MIA_MASK (0x07 << GS_MIA_SHIFT) | 39 | #define GS_MIA_MASK (0x07 << GS_MIA_SHIFT) |
40 | #define GS_MIA_CORE_STATE (1 << GS_MIA_SHIFT) | ||
40 | 41 | ||
41 | #define SOFT_SCRATCH(n) (0xc180 + ((n) * 4)) | 42 | #define SOFT_SCRATCH(n) (0xc180 + ((n) * 4)) |
42 | 43 | ||
43 | #define UOS_RSA_SCRATCH_0 0xc200 | 44 | #define UOS_RSA_SCRATCH(i) (0xc200 + (i) * 4) |
44 | #define DMA_ADDR_0_LOW 0xc300 | 45 | #define DMA_ADDR_0_LOW 0xc300 |
45 | #define DMA_ADDR_0_HIGH 0xc304 | 46 | #define DMA_ADDR_0_HIGH 0xc304 |
46 | #define DMA_ADDR_1_LOW 0xc308 | 47 | #define DMA_ADDR_1_LOW 0xc308 |
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 792d0b958a2c..036b42bae827 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c | |||
@@ -155,12 +155,21 @@ static int host2guc_sample_forcewake(struct intel_guc *guc, | |||
155 | struct i915_guc_client *client) | 155 | struct i915_guc_client *client) |
156 | { | 156 | { |
157 | struct drm_i915_private *dev_priv = guc_to_i915(guc); | 157 | struct drm_i915_private *dev_priv = guc_to_i915(guc); |
158 | struct drm_device *dev = dev_priv->dev; | ||
158 | u32 data[2]; | 159 | u32 data[2]; |
159 | 160 | ||
160 | data[0] = HOST2GUC_ACTION_SAMPLE_FORCEWAKE; | 161 | data[0] = HOST2GUC_ACTION_SAMPLE_FORCEWAKE; |
161 | data[1] = (intel_enable_rc6(dev_priv->dev)) ? 1 : 0; | 162 | /* WaRsDisableCoarsePowerGating:skl,bxt */ |
163 | if (!intel_enable_rc6(dev_priv->dev) || | ||
164 | (IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) || | ||
165 | (IS_SKL_GT3(dev) && (INTEL_REVID(dev) <= SKL_REVID_E0)) || | ||
166 | (IS_SKL_GT4(dev) && (INTEL_REVID(dev) <= SKL_REVID_E0))) | ||
167 | data[1] = 0; | ||
168 | else | ||
169 | /* bit 0 and 1 are for Render and Media domain separately */ | ||
170 | data[1] = GUC_FORCEWAKE_RENDER | GUC_FORCEWAKE_MEDIA; | ||
162 | 171 | ||
163 | return host2guc_action(guc, data, 2); | 172 | return host2guc_action(guc, data, ARRAY_SIZE(data)); |
164 | } | 173 | } |
165 | 174 | ||
166 | /* | 175 | /* |
@@ -914,3 +923,53 @@ void i915_guc_submission_fini(struct drm_device *dev) | |||
914 | gem_release_guc_obj(guc->ctx_pool_obj); | 923 | gem_release_guc_obj(guc->ctx_pool_obj); |
915 | guc->ctx_pool_obj = NULL; | 924 | guc->ctx_pool_obj = NULL; |
916 | } | 925 | } |
926 | |||
927 | /** | ||
928 | * intel_guc_suspend() - notify GuC entering suspend state | ||
929 | * @dev: drm device | ||
930 | */ | ||
931 | int intel_guc_suspend(struct drm_device *dev) | ||
932 | { | ||
933 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
934 | struct intel_guc *guc = &dev_priv->guc; | ||
935 | struct intel_context *ctx; | ||
936 | u32 data[3]; | ||
937 | |||
938 | if (!i915.enable_guc_submission) | ||
939 | return 0; | ||
940 | |||
941 | ctx = dev_priv->ring[RCS].default_context; | ||
942 | |||
943 | data[0] = HOST2GUC_ACTION_ENTER_S_STATE; | ||
944 | /* any value greater than GUC_POWER_D0 */ | ||
945 | data[1] = GUC_POWER_D1; | ||
946 | /* first page is shared data with GuC */ | ||
947 | data[2] = i915_gem_obj_ggtt_offset(ctx->engine[RCS].state); | ||
948 | |||
949 | return host2guc_action(guc, data, ARRAY_SIZE(data)); | ||
950 | } | ||
951 | |||
952 | |||
953 | /** | ||
954 | * intel_guc_resume() - notify GuC resuming from suspend state | ||
955 | * @dev: drm device | ||
956 | */ | ||
957 | int intel_guc_resume(struct drm_device *dev) | ||
958 | { | ||
959 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
960 | struct intel_guc *guc = &dev_priv->guc; | ||
961 | struct intel_context *ctx; | ||
962 | u32 data[3]; | ||
963 | |||
964 | if (!i915.enable_guc_submission) | ||
965 | return 0; | ||
966 | |||
967 | ctx = dev_priv->ring[RCS].default_context; | ||
968 | |||
969 | data[0] = HOST2GUC_ACTION_EXIT_S_STATE; | ||
970 | data[1] = GUC_POWER_D0; | ||
971 | /* first page is shared data with GuC */ | ||
972 | data[2] = i915_gem_obj_ggtt_offset(ctx->engine[RCS].state); | ||
973 | |||
974 | return host2guc_action(guc, data, ARRAY_SIZE(data)); | ||
975 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 45086e15459a..4fb8a2f56281 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -581,6 +581,7 @@ i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, | |||
581 | 581 | ||
582 | /** | 582 | /** |
583 | * i915_enable_asle_pipestat - enable ASLE pipestat for OpRegion | 583 | * i915_enable_asle_pipestat - enable ASLE pipestat for OpRegion |
584 | * @dev: drm device | ||
584 | */ | 585 | */ |
585 | static void i915_enable_asle_pipestat(struct drm_device *dev) | 586 | static void i915_enable_asle_pipestat(struct drm_device *dev) |
586 | { | 587 | { |
@@ -997,12 +998,16 @@ static bool vlv_c0_above(struct drm_i915_private *dev_priv, | |||
997 | int threshold) | 998 | int threshold) |
998 | { | 999 | { |
999 | u64 time, c0; | 1000 | u64 time, c0; |
1001 | unsigned int mul = 100; | ||
1000 | 1002 | ||
1001 | if (old->cz_clock == 0) | 1003 | if (old->cz_clock == 0) |
1002 | return false; | 1004 | return false; |
1003 | 1005 | ||
1006 | if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH) | ||
1007 | mul <<= 8; | ||
1008 | |||
1004 | time = now->cz_clock - old->cz_clock; | 1009 | time = now->cz_clock - old->cz_clock; |
1005 | time *= threshold * dev_priv->mem_freq; | 1010 | time *= threshold * dev_priv->czclk_freq; |
1006 | 1011 | ||
1007 | /* Workload can be split between render + media, e.g. SwapBuffers | 1012 | /* Workload can be split between render + media, e.g. SwapBuffers |
1008 | * being blitted in X after being rendered in mesa. To account for | 1013 | * being blitted in X after being rendered in mesa. To account for |
@@ -1010,7 +1015,7 @@ static bool vlv_c0_above(struct drm_i915_private *dev_priv, | |||
1010 | */ | 1015 | */ |
1011 | c0 = now->render_c0 - old->render_c0; | 1016 | c0 = now->render_c0 - old->render_c0; |
1012 | c0 += now->media_c0 - old->media_c0; | 1017 | c0 += now->media_c0 - old->media_c0; |
1013 | c0 *= 100 * VLV_CZ_CLOCK_TO_MILLI_SEC * 4 / 1000; | 1018 | c0 *= mul * VLV_CZ_CLOCK_TO_MILLI_SEC; |
1014 | 1019 | ||
1015 | return c0 >= time; | 1020 | return c0 >= time; |
1016 | } | 1021 | } |
@@ -2388,6 +2393,7 @@ static void i915_error_wake_up(struct drm_i915_private *dev_priv, | |||
2388 | 2393 | ||
2389 | /** | 2394 | /** |
2390 | * i915_reset_and_wakeup - do process context error handling work | 2395 | * i915_reset_and_wakeup - do process context error handling work |
2396 | * @dev: drm device | ||
2391 | * | 2397 | * |
2392 | * Fire an error uevent so userspace can see that a hang or error | 2398 | * Fire an error uevent so userspace can see that a hang or error |
2393 | * was detected. | 2399 | * was detected. |
@@ -2565,7 +2571,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev) | |||
2565 | * i915_handle_error - handle a gpu error | 2571 | * i915_handle_error - handle a gpu error |
2566 | * @dev: drm device | 2572 | * @dev: drm device |
2567 | * | 2573 | * |
2568 | * Do some basic checking of regsiter state at error time and | 2574 | * Do some basic checking of register state at error time and |
2569 | * dump it to the syslog. Also call i915_capture_error_state() to make | 2575 | * dump it to the syslog. Also call i915_capture_error_state() to make |
2570 | * sure we get a record and make it available in debugfs. Fire a uevent | 2576 | * sure we get a record and make it available in debugfs. Fire a uevent |
2571 | * so userspace knows something bad happened (should trigger collection | 2577 | * so userspace knows something bad happened (should trigger collection |
@@ -2778,6 +2784,26 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno) | |||
2778 | u64 offset = 0; | 2784 | u64 offset = 0; |
2779 | int i, backwards; | 2785 | int i, backwards; |
2780 | 2786 | ||
2787 | /* | ||
2788 | * This function does not support execlist mode - any attempt to | ||
2789 | * proceed further into this function will result in a kernel panic | ||
2790 | * when dereferencing ring->buffer, which is not set up in execlist | ||
2791 | * mode. | ||
2792 | * | ||
2793 | * The correct way of doing it would be to derive the currently | ||
2794 | * executing ring buffer from the current context, which is derived | ||
2795 | * from the currently running request. Unfortunately, to get the | ||
2796 | * current request we would have to grab the struct_mutex before doing | ||
2797 | * anything else, which would be ill-advised since some other thread | ||
2798 | * might have grabbed it already and managed to hang itself, causing | ||
2799 | * the hang checker to deadlock. | ||
2800 | * | ||
2801 | * Therefore, this function does not support execlist mode in its | ||
2802 | * current form. Just return NULL and move on. | ||
2803 | */ | ||
2804 | if (ring->buffer == NULL) | ||
2805 | return NULL; | ||
2806 | |||
2781 | ipehr = I915_READ(RING_IPEHR(ring->mmio_base)); | 2807 | ipehr = I915_READ(RING_IPEHR(ring->mmio_base)); |
2782 | if (!ipehr_is_semaphore_wait(ring->dev, ipehr)) | 2808 | if (!ipehr_is_semaphore_wait(ring->dev, ipehr)) |
2783 | return NULL; | 2809 | return NULL; |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 56157eb8719b..6be853d2233c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -105,7 +105,7 @@ | |||
105 | #define GRDOM_RESET_STATUS (1<<1) | 105 | #define GRDOM_RESET_STATUS (1<<1) |
106 | #define GRDOM_RESET_ENABLE (1<<0) | 106 | #define GRDOM_RESET_ENABLE (1<<0) |
107 | 107 | ||
108 | #define ILK_GDSR 0x2ca4 /* MCHBAR offset */ | 108 | #define ILK_GDSR (MCHBAR_MIRROR_BASE + 0x2ca4) |
109 | #define ILK_GRDOM_FULL (0<<1) | 109 | #define ILK_GRDOM_FULL (0<<1) |
110 | #define ILK_GRDOM_RENDER (1<<1) | 110 | #define ILK_GRDOM_RENDER (1<<1) |
111 | #define ILK_GRDOM_MEDIA (3<<1) | 111 | #define ILK_GRDOM_MEDIA (3<<1) |
@@ -536,6 +536,10 @@ | |||
536 | #define GEN7_3DPRIM_START_INSTANCE 0x243C | 536 | #define GEN7_3DPRIM_START_INSTANCE 0x243C |
537 | #define GEN7_3DPRIM_BASE_VERTEX 0x2440 | 537 | #define GEN7_3DPRIM_BASE_VERTEX 0x2440 |
538 | 538 | ||
539 | #define GEN7_GPGPU_DISPATCHDIMX 0x2500 | ||
540 | #define GEN7_GPGPU_DISPATCHDIMY 0x2504 | ||
541 | #define GEN7_GPGPU_DISPATCHDIMZ 0x2508 | ||
542 | |||
539 | #define OACONTROL 0x2360 | 543 | #define OACONTROL 0x2360 |
540 | 544 | ||
541 | #define _GEN7_PIPEA_DE_LOAD_SL 0x70068 | 545 | #define _GEN7_PIPEA_DE_LOAD_SL 0x70068 |
@@ -728,12 +732,13 @@ enum skl_disp_power_wells { | |||
728 | #define DSI_PLL_N1_DIV_MASK (3 << 16) | 732 | #define DSI_PLL_N1_DIV_MASK (3 << 16) |
729 | #define DSI_PLL_M1_DIV_SHIFT 0 | 733 | #define DSI_PLL_M1_DIV_SHIFT 0 |
730 | #define DSI_PLL_M1_DIV_MASK (0x1ff << 0) | 734 | #define DSI_PLL_M1_DIV_MASK (0x1ff << 0) |
735 | #define CCK_CZ_CLOCK_CONTROL 0x62 | ||
731 | #define CCK_DISPLAY_CLOCK_CONTROL 0x6b | 736 | #define CCK_DISPLAY_CLOCK_CONTROL 0x6b |
732 | #define DISPLAY_TRUNK_FORCE_ON (1 << 17) | 737 | #define CCK_TRUNK_FORCE_ON (1 << 17) |
733 | #define DISPLAY_TRUNK_FORCE_OFF (1 << 16) | 738 | #define CCK_TRUNK_FORCE_OFF (1 << 16) |
734 | #define DISPLAY_FREQUENCY_STATUS (0x1f << 8) | 739 | #define CCK_FREQUENCY_STATUS (0x1f << 8) |
735 | #define DISPLAY_FREQUENCY_STATUS_SHIFT 8 | 740 | #define CCK_FREQUENCY_STATUS_SHIFT 8 |
736 | #define DISPLAY_FREQUENCY_VALUES (0x1f << 0) | 741 | #define CCK_FREQUENCY_VALUES (0x1f << 0) |
737 | 742 | ||
738 | /** | 743 | /** |
739 | * DOC: DPIO | 744 | * DOC: DPIO |
@@ -1395,7 +1400,8 @@ enum skl_disp_power_wells { | |||
1395 | #define BXT_PORT_TX_DW3_LN0(port) _PORT3(port, _PORT_TX_DW3_LN0_A, \ | 1400 | #define BXT_PORT_TX_DW3_LN0(port) _PORT3(port, _PORT_TX_DW3_LN0_A, \ |
1396 | _PORT_TX_DW3_LN0_B, \ | 1401 | _PORT_TX_DW3_LN0_B, \ |
1397 | _PORT_TX_DW3_LN0_C) | 1402 | _PORT_TX_DW3_LN0_C) |
1398 | #define UNIQE_TRANGE_EN_METHOD (1 << 27) | 1403 | #define SCALE_DCOMP_METHOD (1 << 26) |
1404 | #define UNIQUE_TRANGE_EN_METHOD (1 << 27) | ||
1399 | 1405 | ||
1400 | #define _PORT_TX_DW4_LN0_A 0x162510 | 1406 | #define _PORT_TX_DW4_LN0_A 0x162510 |
1401 | #define _PORT_TX_DW4_LN0_B 0x6C510 | 1407 | #define _PORT_TX_DW4_LN0_B 0x6C510 |
@@ -1436,9 +1442,15 @@ enum skl_disp_power_wells { | |||
1436 | 1442 | ||
1437 | /* | 1443 | /* |
1438 | * Fence registers | 1444 | * Fence registers |
1445 | * [0-7] @ 0x2000 gen2,gen3 | ||
1446 | * [8-15] @ 0x3000 945,g33,pnv | ||
1447 | * | ||
1448 | * [0-15] @ 0x3000 gen4,gen5 | ||
1449 | * | ||
1450 | * [0-15] @ 0x100000 gen6,vlv,chv | ||
1451 | * [0-31] @ 0x100000 gen7+ | ||
1439 | */ | 1452 | */ |
1440 | #define FENCE_REG_830_0 0x2000 | 1453 | #define FENCE_REG(i) (0x2000 + (((i) & 8) << 9) + ((i) & 7) * 4) |
1441 | #define FENCE_REG_945_8 0x3000 | ||
1442 | #define I830_FENCE_START_MASK 0x07f80000 | 1454 | #define I830_FENCE_START_MASK 0x07f80000 |
1443 | #define I830_FENCE_TILING_Y_SHIFT 12 | 1455 | #define I830_FENCE_TILING_Y_SHIFT 12 |
1444 | #define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) | 1456 | #define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) |
@@ -1451,14 +1463,16 @@ enum skl_disp_power_wells { | |||
1451 | #define I915_FENCE_START_MASK 0x0ff00000 | 1463 | #define I915_FENCE_START_MASK 0x0ff00000 |
1452 | #define I915_FENCE_SIZE_BITS(size) ((ffs((size) >> 20) - 1) << 8) | 1464 | #define I915_FENCE_SIZE_BITS(size) ((ffs((size) >> 20) - 1) << 8) |
1453 | 1465 | ||
1454 | #define FENCE_REG_965_0 0x03000 | 1466 | #define FENCE_REG_965_LO(i) (0x03000 + (i) * 8) |
1467 | #define FENCE_REG_965_HI(i) (0x03000 + (i) * 8 + 4) | ||
1455 | #define I965_FENCE_PITCH_SHIFT 2 | 1468 | #define I965_FENCE_PITCH_SHIFT 2 |
1456 | #define I965_FENCE_TILING_Y_SHIFT 1 | 1469 | #define I965_FENCE_TILING_Y_SHIFT 1 |
1457 | #define I965_FENCE_REG_VALID (1<<0) | 1470 | #define I965_FENCE_REG_VALID (1<<0) |
1458 | #define I965_FENCE_MAX_PITCH_VAL 0x0400 | 1471 | #define I965_FENCE_MAX_PITCH_VAL 0x0400 |
1459 | 1472 | ||
1460 | #define FENCE_REG_SANDYBRIDGE_0 0x100000 | 1473 | #define FENCE_REG_GEN6_LO(i) (0x100000 + (i) * 8) |
1461 | #define SANDYBRIDGE_FENCE_PITCH_SHIFT 32 | 1474 | #define FENCE_REG_GEN6_HI(i) (0x100000 + (i) * 8 + 4) |
1475 | #define GEN6_FENCE_PITCH_SHIFT 32 | ||
1462 | #define GEN7_FENCE_MAX_PITCH_VAL 0x0800 | 1476 | #define GEN7_FENCE_MAX_PITCH_VAL 0x0800 |
1463 | 1477 | ||
1464 | 1478 | ||
@@ -1542,7 +1556,8 @@ enum skl_disp_power_wells { | |||
1542 | #define RING_FAULT_FAULT_TYPE(x) ((x >> 1) & 0x3) | 1556 | #define RING_FAULT_FAULT_TYPE(x) ((x >> 1) & 0x3) |
1543 | #define RING_FAULT_VALID (1<<0) | 1557 | #define RING_FAULT_VALID (1<<0) |
1544 | #define DONE_REG 0x40b0 | 1558 | #define DONE_REG 0x40b0 |
1545 | #define GEN8_PRIVATE_PAT 0x40e0 | 1559 | #define GEN8_PRIVATE_PAT_LO 0x40e0 |
1560 | #define GEN8_PRIVATE_PAT_HI (0x40e0 + 4) | ||
1546 | #define BSD_HWS_PGA_GEN7 (0x04180) | 1561 | #define BSD_HWS_PGA_GEN7 (0x04180) |
1547 | #define BLT_HWS_PGA_GEN7 (0x04280) | 1562 | #define BLT_HWS_PGA_GEN7 (0x04280) |
1548 | #define VEBOX_HWS_PGA_GEN7 (0x04380) | 1563 | #define VEBOX_HWS_PGA_GEN7 (0x04380) |
@@ -1582,14 +1597,17 @@ enum skl_disp_power_wells { | |||
1582 | #endif | 1597 | #endif |
1583 | #define IPEIR_I965 0x02064 | 1598 | #define IPEIR_I965 0x02064 |
1584 | #define IPEHR_I965 0x02068 | 1599 | #define IPEHR_I965 0x02068 |
1585 | #define INSTDONE_I965 0x0206c | ||
1586 | #define GEN7_INSTDONE_1 0x0206c | ||
1587 | #define GEN7_SC_INSTDONE 0x07100 | 1600 | #define GEN7_SC_INSTDONE 0x07100 |
1588 | #define GEN7_SAMPLER_INSTDONE 0x0e160 | 1601 | #define GEN7_SAMPLER_INSTDONE 0x0e160 |
1589 | #define GEN7_ROW_INSTDONE 0x0e164 | 1602 | #define GEN7_ROW_INSTDONE 0x0e164 |
1590 | #define I915_NUM_INSTDONE_REG 4 | 1603 | #define I915_NUM_INSTDONE_REG 4 |
1591 | #define RING_IPEIR(base) ((base)+0x64) | 1604 | #define RING_IPEIR(base) ((base)+0x64) |
1592 | #define RING_IPEHR(base) ((base)+0x68) | 1605 | #define RING_IPEHR(base) ((base)+0x68) |
1606 | /* | ||
1607 | * On GEN4, only the render ring INSTDONE exists and has a different | ||
1608 | * layout than the GEN7+ version. | ||
1609 | * The GEN2 counterpart of this register is GEN2_INSTDONE. | ||
1610 | */ | ||
1593 | #define RING_INSTDONE(base) ((base)+0x6c) | 1611 | #define RING_INSTDONE(base) ((base)+0x6c) |
1594 | #define RING_INSTPS(base) ((base)+0x70) | 1612 | #define RING_INSTPS(base) ((base)+0x70) |
1595 | #define RING_DMA_FADD(base) ((base)+0x78) | 1613 | #define RING_DMA_FADD(base) ((base)+0x78) |
@@ -1597,7 +1615,7 @@ enum skl_disp_power_wells { | |||
1597 | #define RING_INSTPM(base) ((base)+0xc0) | 1615 | #define RING_INSTPM(base) ((base)+0xc0) |
1598 | #define RING_MI_MODE(base) ((base)+0x9c) | 1616 | #define RING_MI_MODE(base) ((base)+0x9c) |
1599 | #define INSTPS 0x02070 /* 965+ only */ | 1617 | #define INSTPS 0x02070 /* 965+ only */ |
1600 | #define INSTDONE1 0x0207c /* 965+ only */ | 1618 | #define GEN4_INSTDONE1 0x0207c /* 965+ only, aka INSTDONE_2 on SNB */ |
1601 | #define ACTHD_I965 0x02074 | 1619 | #define ACTHD_I965 0x02074 |
1602 | #define HWS_PGA 0x02080 | 1620 | #define HWS_PGA 0x02080 |
1603 | #define HWS_ADDRESS_MASK 0xfffff000 | 1621 | #define HWS_ADDRESS_MASK 0xfffff000 |
@@ -1606,7 +1624,7 @@ enum skl_disp_power_wells { | |||
1606 | #define PWRCTX_EN (1<<0) | 1624 | #define PWRCTX_EN (1<<0) |
1607 | #define IPEIR 0x02088 | 1625 | #define IPEIR 0x02088 |
1608 | #define IPEHR 0x0208c | 1626 | #define IPEHR 0x0208c |
1609 | #define INSTDONE 0x02090 | 1627 | #define GEN2_INSTDONE 0x02090 |
1610 | #define NOPID 0x02094 | 1628 | #define NOPID 0x02094 |
1611 | #define HWSTAM 0x02098 | 1629 | #define HWSTAM 0x02098 |
1612 | #define DMA_FADD_I8XX 0x020d0 | 1630 | #define DMA_FADD_I8XX 0x020d0 |
@@ -1876,12 +1894,27 @@ enum skl_disp_power_wells { | |||
1876 | #define CHV_FGT_EU_DIS_SS1_R1_MASK (0xf << CHV_FGT_EU_DIS_SS1_R1_SHIFT) | 1894 | #define CHV_FGT_EU_DIS_SS1_R1_MASK (0xf << CHV_FGT_EU_DIS_SS1_R1_SHIFT) |
1877 | 1895 | ||
1878 | #define GEN8_FUSE2 0x9120 | 1896 | #define GEN8_FUSE2 0x9120 |
1897 | #define GEN8_F2_SS_DIS_SHIFT 21 | ||
1898 | #define GEN8_F2_SS_DIS_MASK (0x7 << GEN8_F2_SS_DIS_SHIFT) | ||
1879 | #define GEN8_F2_S_ENA_SHIFT 25 | 1899 | #define GEN8_F2_S_ENA_SHIFT 25 |
1880 | #define GEN8_F2_S_ENA_MASK (0x7 << GEN8_F2_S_ENA_SHIFT) | 1900 | #define GEN8_F2_S_ENA_MASK (0x7 << GEN8_F2_S_ENA_SHIFT) |
1881 | 1901 | ||
1882 | #define GEN9_F2_SS_DIS_SHIFT 20 | 1902 | #define GEN9_F2_SS_DIS_SHIFT 20 |
1883 | #define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT) | 1903 | #define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT) |
1884 | 1904 | ||
1905 | #define GEN8_EU_DISABLE0 0x9134 | ||
1906 | #define GEN8_EU_DIS0_S0_MASK 0xffffff | ||
1907 | #define GEN8_EU_DIS0_S1_SHIFT 24 | ||
1908 | #define GEN8_EU_DIS0_S1_MASK (0xff << GEN8_EU_DIS0_S1_SHIFT) | ||
1909 | |||
1910 | #define GEN8_EU_DISABLE1 0x9138 | ||
1911 | #define GEN8_EU_DIS1_S1_MASK 0xffff | ||
1912 | #define GEN8_EU_DIS1_S2_SHIFT 16 | ||
1913 | #define GEN8_EU_DIS1_S2_MASK (0xffff << GEN8_EU_DIS1_S2_SHIFT) | ||
1914 | |||
1915 | #define GEN8_EU_DISABLE2 0x913c | ||
1916 | #define GEN8_EU_DIS2_S2_MASK 0xff | ||
1917 | |||
1885 | #define GEN9_EU_DISABLE(slice) (0x9134 + (slice)*0x4) | 1918 | #define GEN9_EU_DISABLE(slice) (0x9134 + (slice)*0x4) |
1886 | 1919 | ||
1887 | #define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050 | 1920 | #define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050 |
@@ -2475,8 +2508,8 @@ enum skl_disp_power_wells { | |||
2475 | #define PALETTE_A_OFFSET 0xa000 | 2508 | #define PALETTE_A_OFFSET 0xa000 |
2476 | #define PALETTE_B_OFFSET 0xa800 | 2509 | #define PALETTE_B_OFFSET 0xa800 |
2477 | #define CHV_PALETTE_C_OFFSET 0xc000 | 2510 | #define CHV_PALETTE_C_OFFSET 0xc000 |
2478 | #define PALETTE(pipe) (dev_priv->info.palette_offsets[pipe] + \ | 2511 | #define PALETTE(pipe, i) (dev_priv->info.palette_offsets[pipe] + \ |
2479 | dev_priv->info.display_mmio_offset) | 2512 | dev_priv->info.display_mmio_offset + (i) * 4) |
2480 | 2513 | ||
2481 | /* MCH MMIO space */ | 2514 | /* MCH MMIO space */ |
2482 | 2515 | ||
@@ -2807,8 +2840,11 @@ enum skl_disp_power_wells { | |||
2807 | 2840 | ||
2808 | #define INTERVAL_1_28_US(us) (((us) * 100) >> 7) | 2841 | #define INTERVAL_1_28_US(us) (((us) * 100) >> 7) |
2809 | #define INTERVAL_1_33_US(us) (((us) * 3) >> 2) | 2842 | #define INTERVAL_1_33_US(us) (((us) * 3) >> 2) |
2843 | #define INTERVAL_0_833_US(us) (((us) * 6) / 5) | ||
2810 | #define GT_INTERVAL_FROM_US(dev_priv, us) (IS_GEN9(dev_priv) ? \ | 2844 | #define GT_INTERVAL_FROM_US(dev_priv, us) (IS_GEN9(dev_priv) ? \ |
2811 | INTERVAL_1_33_US(us) : \ | 2845 | (IS_BROXTON(dev_priv) ? \ |
2846 | INTERVAL_0_833_US(us) : \ | ||
2847 | INTERVAL_1_33_US(us)) : \ | ||
2812 | INTERVAL_1_28_US(us)) | 2848 | INTERVAL_1_28_US(us)) |
2813 | 2849 | ||
2814 | /* | 2850 | /* |
@@ -3264,7 +3300,9 @@ enum skl_disp_power_wells { | |||
3264 | #define GEN3_SDVOC 0x61160 | 3300 | #define GEN3_SDVOC 0x61160 |
3265 | #define GEN4_HDMIB GEN3_SDVOB | 3301 | #define GEN4_HDMIB GEN3_SDVOB |
3266 | #define GEN4_HDMIC GEN3_SDVOC | 3302 | #define GEN4_HDMIC GEN3_SDVOC |
3267 | #define CHV_HDMID 0x6116C | 3303 | #define VLV_HDMIB (VLV_DISPLAY_BASE + GEN4_HDMIB) |
3304 | #define VLV_HDMIC (VLV_DISPLAY_BASE + GEN4_HDMIC) | ||
3305 | #define CHV_HDMID (VLV_DISPLAY_BASE + 0x6116C) | ||
3268 | #define PCH_SDVOB 0xe1140 | 3306 | #define PCH_SDVOB 0xe1140 |
3269 | #define PCH_HDMIB PCH_SDVOB | 3307 | #define PCH_HDMIB PCH_SDVOB |
3270 | #define PCH_HDMIC 0xe1150 | 3308 | #define PCH_HDMIC 0xe1150 |
@@ -3596,17 +3634,29 @@ enum skl_disp_power_wells { | |||
3596 | #define UTIL_PIN_CTL 0x48400 | 3634 | #define UTIL_PIN_CTL 0x48400 |
3597 | #define UTIL_PIN_ENABLE (1 << 31) | 3635 | #define UTIL_PIN_ENABLE (1 << 31) |
3598 | 3636 | ||
3637 | #define UTIL_PIN_PIPE(x) ((x) << 29) | ||
3638 | #define UTIL_PIN_PIPE_MASK (3 << 29) | ||
3639 | #define UTIL_PIN_MODE_PWM (1 << 24) | ||
3640 | #define UTIL_PIN_MODE_MASK (0xf << 24) | ||
3641 | #define UTIL_PIN_POLARITY (1 << 22) | ||
3642 | |||
3599 | /* BXT backlight register definition. */ | 3643 | /* BXT backlight register definition. */ |
3600 | #define BXT_BLC_PWM_CTL1 0xC8250 | 3644 | #define _BXT_BLC_PWM_CTL1 0xC8250 |
3601 | #define BXT_BLC_PWM_ENABLE (1 << 31) | 3645 | #define BXT_BLC_PWM_ENABLE (1 << 31) |
3602 | #define BXT_BLC_PWM_POLARITY (1 << 29) | 3646 | #define BXT_BLC_PWM_POLARITY (1 << 29) |
3603 | #define BXT_BLC_PWM_FREQ1 0xC8254 | 3647 | #define _BXT_BLC_PWM_FREQ1 0xC8254 |
3604 | #define BXT_BLC_PWM_DUTY1 0xC8258 | 3648 | #define _BXT_BLC_PWM_DUTY1 0xC8258 |
3605 | 3649 | ||
3606 | #define BXT_BLC_PWM_CTL2 0xC8350 | 3650 | #define _BXT_BLC_PWM_CTL2 0xC8350 |
3607 | #define BXT_BLC_PWM_FREQ2 0xC8354 | 3651 | #define _BXT_BLC_PWM_FREQ2 0xC8354 |
3608 | #define BXT_BLC_PWM_DUTY2 0xC8358 | 3652 | #define _BXT_BLC_PWM_DUTY2 0xC8358 |
3609 | 3653 | ||
3654 | #define BXT_BLC_PWM_CTL(controller) _PIPE(controller, \ | ||
3655 | _BXT_BLC_PWM_CTL1, _BXT_BLC_PWM_CTL2) | ||
3656 | #define BXT_BLC_PWM_FREQ(controller) _PIPE(controller, \ | ||
3657 | _BXT_BLC_PWM_FREQ1, _BXT_BLC_PWM_FREQ2) | ||
3658 | #define BXT_BLC_PWM_DUTY(controller) _PIPE(controller, \ | ||
3659 | _BXT_BLC_PWM_DUTY1, _BXT_BLC_PWM_DUTY2) | ||
3610 | 3660 | ||
3611 | #define PCH_GTC_CTL 0xe7000 | 3661 | #define PCH_GTC_CTL 0xe7000 |
3612 | #define PCH_GTC_ENABLE (1 << 31) | 3662 | #define PCH_GTC_ENABLE (1 << 31) |
@@ -4093,6 +4143,10 @@ enum skl_disp_power_wells { | |||
4093 | #define DP_C 0x64200 | 4143 | #define DP_C 0x64200 |
4094 | #define DP_D 0x64300 | 4144 | #define DP_D 0x64300 |
4095 | 4145 | ||
4146 | #define VLV_DP_B (VLV_DISPLAY_BASE + DP_B) | ||
4147 | #define VLV_DP_C (VLV_DISPLAY_BASE + DP_C) | ||
4148 | #define CHV_DP_D (VLV_DISPLAY_BASE + DP_D) | ||
4149 | |||
4096 | #define DP_PORT_EN (1 << 31) | 4150 | #define DP_PORT_EN (1 << 31) |
4097 | #define DP_PIPEB_SELECT (1 << 30) | 4151 | #define DP_PIPEB_SELECT (1 << 30) |
4098 | #define DP_PIPE_MASK (1 << 30) | 4152 | #define DP_PIPE_MASK (1 << 30) |
@@ -5631,7 +5685,7 @@ enum skl_disp_power_wells { | |||
5631 | /* legacy palette */ | 5685 | /* legacy palette */ |
5632 | #define _LGC_PALETTE_A 0x4a000 | 5686 | #define _LGC_PALETTE_A 0x4a000 |
5633 | #define _LGC_PALETTE_B 0x4a800 | 5687 | #define _LGC_PALETTE_B 0x4a800 |
5634 | #define LGC_PALETTE(pipe) _PIPE(pipe, _LGC_PALETTE_A, _LGC_PALETTE_B) | 5688 | #define LGC_PALETTE(pipe, i) (_PIPE(pipe, _LGC_PALETTE_A, _LGC_PALETTE_B) + (i) * 4) |
5635 | 5689 | ||
5636 | #define _GAMMA_MODE_A 0x4a480 | 5690 | #define _GAMMA_MODE_A 0x4a480 |
5637 | #define _GAMMA_MODE_B 0x4ac80 | 5691 | #define _GAMMA_MODE_B 0x4ac80 |
@@ -6868,6 +6922,9 @@ enum skl_disp_power_wells { | |||
6868 | #define GEN6_RC6 3 | 6922 | #define GEN6_RC6 3 |
6869 | #define GEN6_RC7 4 | 6923 | #define GEN6_RC7 4 |
6870 | 6924 | ||
6925 | #define GEN8_GT_SLICE_INFO 0x138064 | ||
6926 | #define GEN8_LSLICESTAT_MASK 0x7 | ||
6927 | |||
6871 | #define CHV_POWER_SS0_SIG1 0xa720 | 6928 | #define CHV_POWER_SS0_SIG1 0xa720 |
6872 | #define CHV_POWER_SS1_SIG1 0xa728 | 6929 | #define CHV_POWER_SS1_SIG1 0xa728 |
6873 | #define CHV_SS_PG_ENABLE (1<<1) | 6930 | #define CHV_SS_PG_ENABLE (1<<1) |
@@ -7403,8 +7460,8 @@ enum skl_disp_power_wells { | |||
7403 | #define DPLL_CFGCR2_PDIV_7 (4<<2) | 7460 | #define DPLL_CFGCR2_PDIV_7 (4<<2) |
7404 | #define DPLL_CFGCR2_CENTRAL_FREQ_MASK (3) | 7461 | #define DPLL_CFGCR2_CENTRAL_FREQ_MASK (3) |
7405 | 7462 | ||
7406 | #define GET_CFG_CR1_REG(id) (DPLL1_CFGCR1 + (id - SKL_DPLL1) * 8) | 7463 | #define DPLL_CFGCR1(id) (DPLL1_CFGCR1 + ((id) - SKL_DPLL1) * 8) |
7407 | #define GET_CFG_CR2_REG(id) (DPLL1_CFGCR2 + (id - SKL_DPLL1) * 8) | 7464 | #define DPLL_CFGCR2(id) (DPLL1_CFGCR2 + ((id) - SKL_DPLL1) * 8) |
7408 | 7465 | ||
7409 | /* BXT display engine PLL */ | 7466 | /* BXT display engine PLL */ |
7410 | #define BXT_DE_PLL_CTL 0x6d000 | 7467 | #define BXT_DE_PLL_CTL 0x6d000 |
@@ -7509,6 +7566,68 @@ enum skl_disp_power_wells { | |||
7509 | 7566 | ||
7510 | #define _MIPI_PORT(port, a, c) _PORT3(port, a, 0, c) /* ports A and C only */ | 7567 | #define _MIPI_PORT(port, a, c) _PORT3(port, a, 0, c) /* ports A and C only */ |
7511 | 7568 | ||
7569 | /* BXT MIPI clock controls */ | ||
7570 | #define BXT_MAX_VAR_OUTPUT_KHZ 39500 | ||
7571 | |||
7572 | #define BXT_MIPI_CLOCK_CTL 0x46090 | ||
7573 | #define BXT_MIPI1_DIV_SHIFT 26 | ||
7574 | #define BXT_MIPI2_DIV_SHIFT 10 | ||
7575 | #define BXT_MIPI_DIV_SHIFT(port) \ | ||
7576 | _MIPI_PORT(port, BXT_MIPI1_DIV_SHIFT, \ | ||
7577 | BXT_MIPI2_DIV_SHIFT) | ||
7578 | /* Var clock divider to generate TX source. Result must be < 39.5 M */ | ||
7579 | #define BXT_MIPI1_ESCLK_VAR_DIV_MASK (0x3F << 26) | ||
7580 | #define BXT_MIPI2_ESCLK_VAR_DIV_MASK (0x3F << 10) | ||
7581 | #define BXT_MIPI_ESCLK_VAR_DIV_MASK(port) \ | ||
7582 | _MIPI_PORT(port, BXT_MIPI1_ESCLK_VAR_DIV_MASK, \ | ||
7583 | BXT_MIPI2_ESCLK_VAR_DIV_MASK) | ||
7584 | |||
7585 | #define BXT_MIPI_ESCLK_VAR_DIV(port, val) \ | ||
7586 | (val << BXT_MIPI_DIV_SHIFT(port)) | ||
7587 | /* TX control divider to select actual TX clock output from (8x/var) */ | ||
7588 | #define BXT_MIPI1_TX_ESCLK_SHIFT 21 | ||
7589 | #define BXT_MIPI2_TX_ESCLK_SHIFT 5 | ||
7590 | #define BXT_MIPI_TX_ESCLK_SHIFT(port) \ | ||
7591 | _MIPI_PORT(port, BXT_MIPI1_TX_ESCLK_SHIFT, \ | ||
7592 | BXT_MIPI2_TX_ESCLK_SHIFT) | ||
7593 | #define BXT_MIPI1_TX_ESCLK_FIXDIV_MASK (3 << 21) | ||
7594 | #define BXT_MIPI2_TX_ESCLK_FIXDIV_MASK (3 << 5) | ||
7595 | #define BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port) \ | ||
7596 | _MIPI_PORT(port, BXT_MIPI1_TX_ESCLK_FIXDIV_MASK, \ | ||
7597 | BXT_MIPI2_TX_ESCLK_FIXDIV_MASK) | ||
7598 | #define BXT_MIPI_TX_ESCLK_8XDIV_BY2(port) \ | ||
7599 | (0x0 << BXT_MIPI_TX_ESCLK_SHIFT(port)) | ||
7600 | #define BXT_MIPI_TX_ESCLK_8XDIV_BY4(port) \ | ||
7601 | (0x1 << BXT_MIPI_TX_ESCLK_SHIFT(port)) | ||
7602 | #define BXT_MIPI_TX_ESCLK_8XDIV_BY8(port) \ | ||
7603 | (0x2 << BXT_MIPI_TX_ESCLK_SHIFT(port)) | ||
7604 | /* RX control divider to select actual RX clock output from 8x*/ | ||
7605 | #define BXT_MIPI1_RX_ESCLK_SHIFT 19 | ||
7606 | #define BXT_MIPI2_RX_ESCLK_SHIFT 3 | ||
7607 | #define BXT_MIPI_RX_ESCLK_SHIFT(port) \ | ||
7608 | _MIPI_PORT(port, BXT_MIPI1_RX_ESCLK_SHIFT, \ | ||
7609 | BXT_MIPI2_RX_ESCLK_SHIFT) | ||
7610 | #define BXT_MIPI1_RX_ESCLK_FIXDIV_MASK (3 << 19) | ||
7611 | #define BXT_MIPI2_RX_ESCLK_FIXDIV_MASK (3 << 3) | ||
7612 | #define BXT_MIPI_RX_ESCLK_FIXDIV_MASK(port) \ | ||
7613 | (3 << BXT_MIPI_RX_ESCLK_SHIFT(port)) | ||
7614 | #define BXT_MIPI_RX_ESCLK_8X_BY2(port) \ | ||
7615 | (1 << BXT_MIPI_RX_ESCLK_SHIFT(port)) | ||
7616 | #define BXT_MIPI_RX_ESCLK_8X_BY3(port) \ | ||
7617 | (2 << BXT_MIPI_RX_ESCLK_SHIFT(port)) | ||
7618 | #define BXT_MIPI_RX_ESCLK_8X_BY4(port) \ | ||
7619 | (3 << BXT_MIPI_RX_ESCLK_SHIFT(port)) | ||
7620 | /* BXT-A WA: Always prog DPHY dividers to 00 */ | ||
7621 | #define BXT_MIPI1_DPHY_DIV_SHIFT 16 | ||
7622 | #define BXT_MIPI2_DPHY_DIV_SHIFT 0 | ||
7623 | #define BXT_MIPI_DPHY_DIV_SHIFT(port) \ | ||
7624 | _MIPI_PORT(port, BXT_MIPI1_DPHY_DIV_SHIFT, \ | ||
7625 | BXT_MIPI2_DPHY_DIV_SHIFT) | ||
7626 | #define BXT_MIPI_1_DPHY_DIVIDER_MASK (3 << 16) | ||
7627 | #define BXT_MIPI_2_DPHY_DIVIDER_MASK (3 << 0) | ||
7628 | #define BXT_MIPI_DPHY_DIVIDER_MASK(port) \ | ||
7629 | (3 << BXT_MIPI_DPHY_DIV_SHIFT(port)) | ||
7630 | |||
7512 | /* BXT MIPI mode configure */ | 7631 | /* BXT MIPI mode configure */ |
7513 | #define _BXT_MIPIA_TRANS_HACTIVE 0x6B0F8 | 7632 | #define _BXT_MIPIA_TRANS_HACTIVE 0x6B0F8 |
7514 | #define _BXT_MIPIC_TRANS_HACTIVE 0x6B8F8 | 7633 | #define _BXT_MIPIC_TRANS_HACTIVE 0x6B8F8 |
@@ -7550,6 +7669,13 @@ enum skl_disp_power_wells { | |||
7550 | #define _MIPIA_PORT_CTRL (VLV_DISPLAY_BASE + 0x61190) | 7669 | #define _MIPIA_PORT_CTRL (VLV_DISPLAY_BASE + 0x61190) |
7551 | #define _MIPIC_PORT_CTRL (VLV_DISPLAY_BASE + 0x61700) | 7670 | #define _MIPIC_PORT_CTRL (VLV_DISPLAY_BASE + 0x61700) |
7552 | #define MIPI_PORT_CTRL(port) _MIPI_PORT(port, _MIPIA_PORT_CTRL, _MIPIC_PORT_CTRL) | 7671 | #define MIPI_PORT_CTRL(port) _MIPI_PORT(port, _MIPIA_PORT_CTRL, _MIPIC_PORT_CTRL) |
7672 | |||
7673 | /* BXT port control */ | ||
7674 | #define _BXT_MIPIA_PORT_CTRL 0x6B0C0 | ||
7675 | #define _BXT_MIPIC_PORT_CTRL 0x6B8C0 | ||
7676 | #define BXT_MIPI_PORT_CTRL(tc) _MIPI_PORT(tc, _BXT_MIPIA_PORT_CTRL, \ | ||
7677 | _BXT_MIPIC_PORT_CTRL) | ||
7678 | |||
7553 | #define DPI_ENABLE (1 << 31) /* A + C */ | 7679 | #define DPI_ENABLE (1 << 31) /* A + C */ |
7554 | #define MIPIA_MIPI4DPHY_DELAY_COUNT_SHIFT 27 | 7680 | #define MIPIA_MIPI4DPHY_DELAY_COUNT_SHIFT 27 |
7555 | #define MIPIA_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 27) | 7681 | #define MIPIA_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 27) |
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 55bd04c6b939..50ce9ce2b269 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c | |||
@@ -39,7 +39,7 @@ static u32 calc_residency(struct drm_device *dev, const u32 reg) | |||
39 | { | 39 | { |
40 | struct drm_i915_private *dev_priv = dev->dev_private; | 40 | struct drm_i915_private *dev_priv = dev->dev_private; |
41 | u64 raw_time; /* 32b value may overflow during fixed point math */ | 41 | u64 raw_time; /* 32b value may overflow during fixed point math */ |
42 | u64 units = 128ULL, div = 100000ULL, bias = 100ULL; | 42 | u64 units = 128ULL, div = 100000ULL; |
43 | u32 ret; | 43 | u32 ret; |
44 | 44 | ||
45 | if (!intel_enable_rc6(dev)) | 45 | if (!intel_enable_rc6(dev)) |
@@ -49,41 +49,19 @@ static u32 calc_residency(struct drm_device *dev, const u32 reg) | |||
49 | 49 | ||
50 | /* On VLV and CHV, residency time is in CZ units rather than 1.28us */ | 50 | /* On VLV and CHV, residency time is in CZ units rather than 1.28us */ |
51 | if (IS_VALLEYVIEW(dev)) { | 51 | if (IS_VALLEYVIEW(dev)) { |
52 | u32 clk_reg, czcount_30ns; | 52 | units = 1; |
53 | 53 | div = dev_priv->czclk_freq; | |
54 | if (IS_CHERRYVIEW(dev)) | ||
55 | clk_reg = CHV_CLK_CTL1; | ||
56 | else | ||
57 | clk_reg = VLV_CLK_CTL2; | ||
58 | |||
59 | czcount_30ns = I915_READ(clk_reg) >> CLK_CTL2_CZCOUNT_30NS_SHIFT; | ||
60 | |||
61 | if (!czcount_30ns) { | ||
62 | WARN(!czcount_30ns, "bogus CZ count value"); | ||
63 | ret = 0; | ||
64 | goto out; | ||
65 | } | ||
66 | |||
67 | if (IS_CHERRYVIEW(dev) && czcount_30ns == 1) { | ||
68 | /* Special case for 320Mhz */ | ||
69 | div = 10000000ULL; | ||
70 | units = 3125ULL; | ||
71 | } else { | ||
72 | czcount_30ns += 1; | ||
73 | div = 1000000ULL; | ||
74 | units = DIV_ROUND_UP_ULL(30ULL * bias, czcount_30ns); | ||
75 | } | ||
76 | 54 | ||
77 | if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH) | 55 | if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH) |
78 | units <<= 8; | 56 | units <<= 8; |
79 | 57 | } else if (IS_BROXTON(dev)) { | |
80 | div = div * bias; | 58 | units = 1; |
59 | div = 1200; /* 833.33ns */ | ||
81 | } | 60 | } |
82 | 61 | ||
83 | raw_time = I915_READ(reg) * units; | 62 | raw_time = I915_READ(reg) * units; |
84 | ret = DIV_ROUND_UP_ULL(raw_time, div); | 63 | ret = DIV_ROUND_UP_ULL(raw_time, div); |
85 | 64 | ||
86 | out: | ||
87 | intel_runtime_pm_put(dev_priv); | 65 | intel_runtime_pm_put(dev_priv); |
88 | return ret; | 66 | return ret; |
89 | } | 67 | } |
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index d0993bc814ea..04fe8491c8b6 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h | |||
@@ -107,6 +107,26 @@ TRACE_EVENT(i915_gem_object_create, | |||
107 | TP_printk("obj=%p, size=%u", __entry->obj, __entry->size) | 107 | TP_printk("obj=%p, size=%u", __entry->obj, __entry->size) |
108 | ); | 108 | ); |
109 | 109 | ||
110 | TRACE_EVENT(i915_gem_shrink, | ||
111 | TP_PROTO(struct drm_i915_private *i915, unsigned long target, unsigned flags), | ||
112 | TP_ARGS(i915, target, flags), | ||
113 | |||
114 | TP_STRUCT__entry( | ||
115 | __field(int, dev) | ||
116 | __field(unsigned long, target) | ||
117 | __field(unsigned, flags) | ||
118 | ), | ||
119 | |||
120 | TP_fast_assign( | ||
121 | __entry->dev = i915->dev->primary->index; | ||
122 | __entry->target = target; | ||
123 | __entry->flags = flags; | ||
124 | ), | ||
125 | |||
126 | TP_printk("dev=%d, target=%lu, flags=%x", | ||
127 | __entry->dev, __entry->target, __entry->flags) | ||
128 | ); | ||
129 | |||
110 | TRACE_EVENT(i915_vma_bind, | 130 | TRACE_EVENT(i915_vma_bind, |
111 | TP_PROTO(struct i915_vma *vma, unsigned flags), | 131 | TP_PROTO(struct i915_vma *vma, unsigned flags), |
112 | TP_ARGS(vma, flags), | 132 | TP_ARGS(vma, flags), |
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index f1975f267710..05b12032d262 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c | |||
@@ -94,6 +94,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc) | |||
94 | __drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base); | 94 | __drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base); |
95 | 95 | ||
96 | crtc_state->update_pipe = false; | 96 | crtc_state->update_pipe = false; |
97 | crtc_state->disable_lp_wm = false; | ||
97 | 98 | ||
98 | return &crtc_state->base; | 99 | return &crtc_state->base; |
99 | } | 100 | } |
diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index e35997ebb331..56c2f54801c4 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c | |||
@@ -50,6 +50,11 @@ | |||
50 | * co-operation between the graphics and audio drivers is handled via audio | 50 | * co-operation between the graphics and audio drivers is handled via audio |
51 | * related registers. (The notable exception is the power management, not | 51 | * related registers. (The notable exception is the power management, not |
52 | * covered here.) | 52 | * covered here.) |
53 | * | ||
54 | * The struct i915_audio_component is used to interact between the graphics | ||
55 | * and audio drivers. The struct i915_audio_component_ops *ops in it is | ||
56 | * defined in graphics driver and called in audio driver. The | ||
57 | * struct i915_audio_component_audio_ops *audio_ops is called from i915 driver. | ||
53 | */ | 58 | */ |
54 | 59 | ||
55 | static const struct { | 60 | static const struct { |
@@ -68,18 +73,44 @@ static const struct { | |||
68 | { 148500, AUD_CONFIG_PIXEL_CLOCK_HDMI_148500 }, | 73 | { 148500, AUD_CONFIG_PIXEL_CLOCK_HDMI_148500 }, |
69 | }; | 74 | }; |
70 | 75 | ||
76 | /* HDMI N/CTS table */ | ||
77 | #define TMDS_297M 297000 | ||
78 | #define TMDS_296M DIV_ROUND_UP(297000 * 1000, 1001) | ||
79 | static const struct { | ||
80 | int sample_rate; | ||
81 | int clock; | ||
82 | int n; | ||
83 | int cts; | ||
84 | } aud_ncts[] = { | ||
85 | { 44100, TMDS_296M, 4459, 234375 }, | ||
86 | { 44100, TMDS_297M, 4704, 247500 }, | ||
87 | { 48000, TMDS_296M, 5824, 281250 }, | ||
88 | { 48000, TMDS_297M, 5120, 247500 }, | ||
89 | { 32000, TMDS_296M, 5824, 421875 }, | ||
90 | { 32000, TMDS_297M, 3072, 222750 }, | ||
91 | { 88200, TMDS_296M, 8918, 234375 }, | ||
92 | { 88200, TMDS_297M, 9408, 247500 }, | ||
93 | { 96000, TMDS_296M, 11648, 281250 }, | ||
94 | { 96000, TMDS_297M, 10240, 247500 }, | ||
95 | { 176400, TMDS_296M, 17836, 234375 }, | ||
96 | { 176400, TMDS_297M, 18816, 247500 }, | ||
97 | { 192000, TMDS_296M, 23296, 281250 }, | ||
98 | { 192000, TMDS_297M, 20480, 247500 }, | ||
99 | }; | ||
100 | |||
71 | /* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */ | 101 | /* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */ |
72 | static u32 audio_config_hdmi_pixel_clock(struct drm_display_mode *mode) | 102 | static u32 audio_config_hdmi_pixel_clock(const struct drm_display_mode *adjusted_mode) |
73 | { | 103 | { |
74 | int i; | 104 | int i; |
75 | 105 | ||
76 | for (i = 0; i < ARRAY_SIZE(hdmi_audio_clock); i++) { | 106 | for (i = 0; i < ARRAY_SIZE(hdmi_audio_clock); i++) { |
77 | if (mode->clock == hdmi_audio_clock[i].clock) | 107 | if (adjusted_mode->crtc_clock == hdmi_audio_clock[i].clock) |
78 | break; | 108 | break; |
79 | } | 109 | } |
80 | 110 | ||
81 | if (i == ARRAY_SIZE(hdmi_audio_clock)) { | 111 | if (i == ARRAY_SIZE(hdmi_audio_clock)) { |
82 | DRM_DEBUG_KMS("HDMI audio pixel clock setting for %d not found, falling back to defaults\n", mode->clock); | 112 | DRM_DEBUG_KMS("HDMI audio pixel clock setting for %d not found, falling back to defaults\n", |
113 | adjusted_mode->crtc_clock); | ||
83 | i = 1; | 114 | i = 1; |
84 | } | 115 | } |
85 | 116 | ||
@@ -90,6 +121,45 @@ static u32 audio_config_hdmi_pixel_clock(struct drm_display_mode *mode) | |||
90 | return hdmi_audio_clock[i].config; | 121 | return hdmi_audio_clock[i].config; |
91 | } | 122 | } |
92 | 123 | ||
124 | static int audio_config_get_n(const struct drm_display_mode *mode, int rate) | ||
125 | { | ||
126 | int i; | ||
127 | |||
128 | for (i = 0; i < ARRAY_SIZE(aud_ncts); i++) { | ||
129 | if ((rate == aud_ncts[i].sample_rate) && | ||
130 | (mode->clock == aud_ncts[i].clock)) { | ||
131 | return aud_ncts[i].n; | ||
132 | } | ||
133 | } | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static uint32_t audio_config_setup_n_reg(int n, uint32_t val) | ||
138 | { | ||
139 | int n_low, n_up; | ||
140 | uint32_t tmp = val; | ||
141 | |||
142 | n_low = n & 0xfff; | ||
143 | n_up = (n >> 12) & 0xff; | ||
144 | tmp &= ~(AUD_CONFIG_UPPER_N_MASK | AUD_CONFIG_LOWER_N_MASK); | ||
145 | tmp |= ((n_up << AUD_CONFIG_UPPER_N_SHIFT) | | ||
146 | (n_low << AUD_CONFIG_LOWER_N_SHIFT) | | ||
147 | AUD_CONFIG_N_PROG_ENABLE); | ||
148 | return tmp; | ||
149 | } | ||
150 | |||
151 | /* check whether N/CTS/M need be set manually */ | ||
152 | static bool audio_rate_need_prog(struct intel_crtc *crtc, | ||
153 | const struct drm_display_mode *mode) | ||
154 | { | ||
155 | if (((mode->clock == TMDS_297M) || | ||
156 | (mode->clock == TMDS_296M)) && | ||
157 | intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) | ||
158 | return true; | ||
159 | else | ||
160 | return false; | ||
161 | } | ||
162 | |||
93 | static bool intel_eld_uptodate(struct drm_connector *connector, | 163 | static bool intel_eld_uptodate(struct drm_connector *connector, |
94 | int reg_eldv, uint32_t bits_eldv, | 164 | int reg_eldv, uint32_t bits_eldv, |
95 | int reg_elda, uint32_t bits_elda, | 165 | int reg_elda, uint32_t bits_elda, |
@@ -138,7 +208,7 @@ static void g4x_audio_codec_disable(struct intel_encoder *encoder) | |||
138 | 208 | ||
139 | static void g4x_audio_codec_enable(struct drm_connector *connector, | 209 | static void g4x_audio_codec_enable(struct drm_connector *connector, |
140 | struct intel_encoder *encoder, | 210 | struct intel_encoder *encoder, |
141 | struct drm_display_mode *mode) | 211 | const struct drm_display_mode *adjusted_mode) |
142 | { | 212 | { |
143 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 213 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
144 | uint8_t *eld = connector->eld; | 214 | uint8_t *eld = connector->eld; |
@@ -184,6 +254,8 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder) | |||
184 | 254 | ||
185 | DRM_DEBUG_KMS("Disable audio codec on pipe %c\n", pipe_name(pipe)); | 255 | DRM_DEBUG_KMS("Disable audio codec on pipe %c\n", pipe_name(pipe)); |
186 | 256 | ||
257 | mutex_lock(&dev_priv->av_mutex); | ||
258 | |||
187 | /* Disable timestamps */ | 259 | /* Disable timestamps */ |
188 | tmp = I915_READ(HSW_AUD_CFG(pipe)); | 260 | tmp = I915_READ(HSW_AUD_CFG(pipe)); |
189 | tmp &= ~AUD_CONFIG_N_VALUE_INDEX; | 261 | tmp &= ~AUD_CONFIG_N_VALUE_INDEX; |
@@ -199,22 +271,31 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder) | |||
199 | tmp &= ~AUDIO_ELD_VALID(pipe); | 271 | tmp &= ~AUDIO_ELD_VALID(pipe); |
200 | tmp &= ~AUDIO_OUTPUT_ENABLE(pipe); | 272 | tmp &= ~AUDIO_OUTPUT_ENABLE(pipe); |
201 | I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); | 273 | I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); |
274 | |||
275 | mutex_unlock(&dev_priv->av_mutex); | ||
202 | } | 276 | } |
203 | 277 | ||
204 | static void hsw_audio_codec_enable(struct drm_connector *connector, | 278 | static void hsw_audio_codec_enable(struct drm_connector *connector, |
205 | struct intel_encoder *encoder, | 279 | struct intel_encoder *encoder, |
206 | struct drm_display_mode *mode) | 280 | const struct drm_display_mode *adjusted_mode) |
207 | { | 281 | { |
208 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 282 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
209 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); | 283 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
210 | enum pipe pipe = intel_crtc->pipe; | 284 | enum pipe pipe = intel_crtc->pipe; |
285 | struct i915_audio_component *acomp = dev_priv->audio_component; | ||
211 | const uint8_t *eld = connector->eld; | 286 | const uint8_t *eld = connector->eld; |
287 | struct intel_digital_port *intel_dig_port = | ||
288 | enc_to_dig_port(&encoder->base); | ||
289 | enum port port = intel_dig_port->port; | ||
212 | uint32_t tmp; | 290 | uint32_t tmp; |
213 | int len, i; | 291 | int len, i; |
292 | int n, rate; | ||
214 | 293 | ||
215 | DRM_DEBUG_KMS("Enable audio codec on pipe %c, %u bytes ELD\n", | 294 | DRM_DEBUG_KMS("Enable audio codec on pipe %c, %u bytes ELD\n", |
216 | pipe_name(pipe), drm_eld_size(eld)); | 295 | pipe_name(pipe), drm_eld_size(eld)); |
217 | 296 | ||
297 | mutex_lock(&dev_priv->av_mutex); | ||
298 | |||
218 | /* Enable audio presence detect, invalidate ELD */ | 299 | /* Enable audio presence detect, invalidate ELD */ |
219 | tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); | 300 | tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); |
220 | tmp |= AUDIO_OUTPUT_ENABLE(pipe); | 301 | tmp |= AUDIO_OUTPUT_ENABLE(pipe); |
@@ -246,13 +327,32 @@ static void hsw_audio_codec_enable(struct drm_connector *connector, | |||
246 | /* Enable timestamps */ | 327 | /* Enable timestamps */ |
247 | tmp = I915_READ(HSW_AUD_CFG(pipe)); | 328 | tmp = I915_READ(HSW_AUD_CFG(pipe)); |
248 | tmp &= ~AUD_CONFIG_N_VALUE_INDEX; | 329 | tmp &= ~AUD_CONFIG_N_VALUE_INDEX; |
249 | tmp &= ~AUD_CONFIG_N_PROG_ENABLE; | ||
250 | tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK; | 330 | tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK; |
251 | if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) | 331 | if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) |
252 | tmp |= AUD_CONFIG_N_VALUE_INDEX; | 332 | tmp |= AUD_CONFIG_N_VALUE_INDEX; |
253 | else | 333 | else |
254 | tmp |= audio_config_hdmi_pixel_clock(mode); | 334 | tmp |= audio_config_hdmi_pixel_clock(adjusted_mode); |
335 | |||
336 | tmp &= ~AUD_CONFIG_N_PROG_ENABLE; | ||
337 | if (audio_rate_need_prog(intel_crtc, adjusted_mode)) { | ||
338 | if (!acomp) | ||
339 | rate = 0; | ||
340 | else if (port >= PORT_A && port <= PORT_E) | ||
341 | rate = acomp->aud_sample_rate[port]; | ||
342 | else { | ||
343 | DRM_ERROR("invalid port: %d\n", port); | ||
344 | rate = 0; | ||
345 | } | ||
346 | n = audio_config_get_n(adjusted_mode, rate); | ||
347 | if (n != 0) | ||
348 | tmp = audio_config_setup_n_reg(n, tmp); | ||
349 | else | ||
350 | DRM_DEBUG_KMS("no suitable N value is found\n"); | ||
351 | } | ||
352 | |||
255 | I915_WRITE(HSW_AUD_CFG(pipe), tmp); | 353 | I915_WRITE(HSW_AUD_CFG(pipe), tmp); |
354 | |||
355 | mutex_unlock(&dev_priv->av_mutex); | ||
256 | } | 356 | } |
257 | 357 | ||
258 | static void ilk_audio_codec_disable(struct intel_encoder *encoder) | 358 | static void ilk_audio_codec_disable(struct intel_encoder *encoder) |
@@ -304,7 +404,7 @@ static void ilk_audio_codec_disable(struct intel_encoder *encoder) | |||
304 | 404 | ||
305 | static void ilk_audio_codec_enable(struct drm_connector *connector, | 405 | static void ilk_audio_codec_enable(struct drm_connector *connector, |
306 | struct intel_encoder *encoder, | 406 | struct intel_encoder *encoder, |
307 | struct drm_display_mode *mode) | 407 | const struct drm_display_mode *adjusted_mode) |
308 | { | 408 | { |
309 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 409 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
310 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); | 410 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
@@ -381,7 +481,7 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, | |||
381 | if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) | 481 | if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) |
382 | tmp |= AUD_CONFIG_N_VALUE_INDEX; | 482 | tmp |= AUD_CONFIG_N_VALUE_INDEX; |
383 | else | 483 | else |
384 | tmp |= audio_config_hdmi_pixel_clock(mode); | 484 | tmp |= audio_config_hdmi_pixel_clock(adjusted_mode); |
385 | I915_WRITE(aud_config, tmp); | 485 | I915_WRITE(aud_config, tmp); |
386 | } | 486 | } |
387 | 487 | ||
@@ -396,7 +496,7 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder) | |||
396 | { | 496 | { |
397 | struct drm_encoder *encoder = &intel_encoder->base; | 497 | struct drm_encoder *encoder = &intel_encoder->base; |
398 | struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); | 498 | struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); |
399 | struct drm_display_mode *mode = &crtc->config->base.adjusted_mode; | 499 | const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; |
400 | struct drm_connector *connector; | 500 | struct drm_connector *connector; |
401 | struct drm_device *dev = encoder->dev; | 501 | struct drm_device *dev = encoder->dev; |
402 | struct drm_i915_private *dev_priv = dev->dev_private; | 502 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -419,10 +519,11 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder) | |||
419 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) | 519 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) |
420 | connector->eld[5] |= (1 << 2); | 520 | connector->eld[5] |= (1 << 2); |
421 | 521 | ||
422 | connector->eld[6] = drm_av_sync_delay(connector, mode) / 2; | 522 | connector->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2; |
423 | 523 | ||
424 | if (dev_priv->display.audio_codec_enable) | 524 | if (dev_priv->display.audio_codec_enable) |
425 | dev_priv->display.audio_codec_enable(connector, intel_encoder, mode); | 525 | dev_priv->display.audio_codec_enable(connector, intel_encoder, |
526 | adjusted_mode); | ||
426 | 527 | ||
427 | if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) | 528 | if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) |
428 | acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port); | 529 | acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port); |
@@ -527,12 +628,91 @@ static int i915_audio_component_get_cdclk_freq(struct device *dev) | |||
527 | return ret; | 628 | return ret; |
528 | } | 629 | } |
529 | 630 | ||
631 | static int i915_audio_component_sync_audio_rate(struct device *dev, | ||
632 | int port, int rate) | ||
633 | { | ||
634 | struct drm_i915_private *dev_priv = dev_to_i915(dev); | ||
635 | struct drm_device *drm_dev = dev_priv->dev; | ||
636 | struct intel_encoder *intel_encoder; | ||
637 | struct intel_digital_port *intel_dig_port; | ||
638 | struct intel_crtc *crtc; | ||
639 | struct drm_display_mode *mode; | ||
640 | struct i915_audio_component *acomp = dev_priv->audio_component; | ||
641 | enum pipe pipe = -1; | ||
642 | u32 tmp; | ||
643 | int n; | ||
644 | |||
645 | /* HSW, BDW SKL need this fix */ | ||
646 | if (!IS_SKYLAKE(dev_priv) && | ||
647 | !IS_BROADWELL(dev_priv) && | ||
648 | !IS_HASWELL(dev_priv)) | ||
649 | return 0; | ||
650 | |||
651 | mutex_lock(&dev_priv->av_mutex); | ||
652 | /* 1. get the pipe */ | ||
653 | for_each_intel_encoder(drm_dev, intel_encoder) { | ||
654 | if (intel_encoder->type != INTEL_OUTPUT_HDMI) | ||
655 | continue; | ||
656 | intel_dig_port = enc_to_dig_port(&intel_encoder->base); | ||
657 | if (port == intel_dig_port->port) { | ||
658 | crtc = to_intel_crtc(intel_encoder->base.crtc); | ||
659 | if (!crtc) { | ||
660 | DRM_DEBUG_KMS("%s: crtc is NULL\n", __func__); | ||
661 | continue; | ||
662 | } | ||
663 | pipe = crtc->pipe; | ||
664 | break; | ||
665 | } | ||
666 | } | ||
667 | |||
668 | if (pipe == INVALID_PIPE) { | ||
669 | DRM_DEBUG_KMS("no pipe for the port %c\n", port_name(port)); | ||
670 | mutex_unlock(&dev_priv->av_mutex); | ||
671 | return -ENODEV; | ||
672 | } | ||
673 | DRM_DEBUG_KMS("pipe %c connects port %c\n", | ||
674 | pipe_name(pipe), port_name(port)); | ||
675 | mode = &crtc->config->base.adjusted_mode; | ||
676 | |||
677 | /* port must be valid now, otherwise the pipe will be invalid */ | ||
678 | acomp->aud_sample_rate[port] = rate; | ||
679 | |||
680 | /* 2. check whether to set the N/CTS/M manually or not */ | ||
681 | if (!audio_rate_need_prog(crtc, mode)) { | ||
682 | tmp = I915_READ(HSW_AUD_CFG(pipe)); | ||
683 | tmp &= ~AUD_CONFIG_N_PROG_ENABLE; | ||
684 | I915_WRITE(HSW_AUD_CFG(pipe), tmp); | ||
685 | mutex_unlock(&dev_priv->av_mutex); | ||
686 | return 0; | ||
687 | } | ||
688 | |||
689 | n = audio_config_get_n(mode, rate); | ||
690 | if (n == 0) { | ||
691 | DRM_DEBUG_KMS("Using automatic mode for N value on port %c\n", | ||
692 | port_name(port)); | ||
693 | tmp = I915_READ(HSW_AUD_CFG(pipe)); | ||
694 | tmp &= ~AUD_CONFIG_N_PROG_ENABLE; | ||
695 | I915_WRITE(HSW_AUD_CFG(pipe), tmp); | ||
696 | mutex_unlock(&dev_priv->av_mutex); | ||
697 | return 0; | ||
698 | } | ||
699 | |||
700 | /* 3. set the N/CTS/M */ | ||
701 | tmp = I915_READ(HSW_AUD_CFG(pipe)); | ||
702 | tmp = audio_config_setup_n_reg(n, tmp); | ||
703 | I915_WRITE(HSW_AUD_CFG(pipe), tmp); | ||
704 | |||
705 | mutex_unlock(&dev_priv->av_mutex); | ||
706 | return 0; | ||
707 | } | ||
708 | |||
530 | static const struct i915_audio_component_ops i915_audio_component_ops = { | 709 | static const struct i915_audio_component_ops i915_audio_component_ops = { |
531 | .owner = THIS_MODULE, | 710 | .owner = THIS_MODULE, |
532 | .get_power = i915_audio_component_get_power, | 711 | .get_power = i915_audio_component_get_power, |
533 | .put_power = i915_audio_component_put_power, | 712 | .put_power = i915_audio_component_put_power, |
534 | .codec_wake_override = i915_audio_component_codec_wake_override, | 713 | .codec_wake_override = i915_audio_component_codec_wake_override, |
535 | .get_cdclk_freq = i915_audio_component_get_cdclk_freq, | 714 | .get_cdclk_freq = i915_audio_component_get_cdclk_freq, |
715 | .sync_audio_rate = i915_audio_component_sync_audio_rate, | ||
536 | }; | 716 | }; |
537 | 717 | ||
538 | static int i915_audio_component_bind(struct device *i915_dev, | 718 | static int i915_audio_component_bind(struct device *i915_dev, |
@@ -540,6 +720,7 @@ static int i915_audio_component_bind(struct device *i915_dev, | |||
540 | { | 720 | { |
541 | struct i915_audio_component *acomp = data; | 721 | struct i915_audio_component *acomp = data; |
542 | struct drm_i915_private *dev_priv = dev_to_i915(i915_dev); | 722 | struct drm_i915_private *dev_priv = dev_to_i915(i915_dev); |
723 | int i; | ||
543 | 724 | ||
544 | if (WARN_ON(acomp->ops || acomp->dev)) | 725 | if (WARN_ON(acomp->ops || acomp->dev)) |
545 | return -EEXIST; | 726 | return -EEXIST; |
@@ -547,6 +728,9 @@ static int i915_audio_component_bind(struct device *i915_dev, | |||
547 | drm_modeset_lock_all(dev_priv->dev); | 728 | drm_modeset_lock_all(dev_priv->dev); |
548 | acomp->ops = &i915_audio_component_ops; | 729 | acomp->ops = &i915_audio_component_ops; |
549 | acomp->dev = i915_dev; | 730 | acomp->dev = i915_dev; |
731 | BUILD_BUG_ON(MAX_PORTS != I915_MAX_PORTS); | ||
732 | for (i = 0; i < ARRAY_SIZE(acomp->aud_sample_rate); i++) | ||
733 | acomp->aud_sample_rate[i] = 0; | ||
550 | dev_priv->audio_component = acomp; | 734 | dev_priv->audio_component = acomp; |
551 | drm_modeset_unlock_all(dev_priv->dev); | 735 | drm_modeset_unlock_all(dev_priv->dev); |
552 | 736 | ||
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 6ce38e3edf21..b84aaa0bb48a 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -158,7 +158,7 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode) | |||
158 | struct drm_i915_private *dev_priv = dev->dev_private; | 158 | struct drm_i915_private *dev_priv = dev->dev_private; |
159 | struct intel_crt *crt = intel_encoder_to_crt(encoder); | 159 | struct intel_crt *crt = intel_encoder_to_crt(encoder); |
160 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); | 160 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); |
161 | struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; | 161 | const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; |
162 | u32 adpa; | 162 | u32 adpa; |
163 | 163 | ||
164 | if (INTEL_INFO(dev)->gen >= 5) | 164 | if (INTEL_INFO(dev)->gen >= 5) |
@@ -890,7 +890,7 @@ void intel_crt_init(struct drm_device *dev) | |||
890 | u32 fdi_config = FDI_RX_POLARITY_REVERSED_LPT | | 890 | u32 fdi_config = FDI_RX_POLARITY_REVERSED_LPT | |
891 | FDI_RX_LINK_REVERSAL_OVERRIDE; | 891 | FDI_RX_LINK_REVERSAL_OVERRIDE; |
892 | 892 | ||
893 | dev_priv->fdi_rx_config = I915_READ(_FDI_RXA_CTL) & fdi_config; | 893 | dev_priv->fdi_rx_config = I915_READ(FDI_RX_CTL(PIPE_A)) & fdi_config; |
894 | } | 894 | } |
895 | 895 | ||
896 | intel_crt_reset(connector); | 896 | intel_crt_reset(connector); |
diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 3427dd41d682..9e530a739354 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c | |||
@@ -265,6 +265,15 @@ void intel_csr_load_program(struct drm_device *dev) | |||
265 | return; | 265 | return; |
266 | } | 266 | } |
267 | 267 | ||
268 | /* | ||
269 | * FIXME: Firmware gets lost on S3/S4, but not when entering system | ||
270 | * standby or suspend-to-idle (which is just like forced runtime pm). | ||
271 | * Unfortunately the ACPI subsystem doesn't yet give us a way to | ||
272 | * differentiate this, hence figure it out with this hack. | ||
273 | */ | ||
274 | if (I915_READ(CSR_PROGRAM(0))) | ||
275 | return; | ||
276 | |||
268 | mutex_lock(&dev_priv->csr_lock); | 277 | mutex_lock(&dev_priv->csr_lock); |
269 | fw_size = dev_priv->csr.dmc_fw_size; | 278 | fw_size = dev_priv->csr.dmc_fw_size; |
270 | for (i = 0; i < fw_size; i++) | 279 | for (i = 0; i < fw_size; i++) |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 9e640eafc50d..b25e99a432fb 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -256,9 +256,6 @@ struct bxt_ddi_buf_trans { | |||
256 | bool default_index; /* true if the entry represents default value */ | 256 | bool default_index; /* true if the entry represents default value */ |
257 | }; | 257 | }; |
258 | 258 | ||
259 | /* BSpec does not define separate vswing/pre-emphasis values for eDP. | ||
260 | * Using DP values for eDP as well. | ||
261 | */ | ||
262 | static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = { | 259 | static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = { |
263 | /* Idx NT mV diff db */ | 260 | /* Idx NT mV diff db */ |
264 | { 52, 0x9A, 0, 128, true }, /* 0: 400 0 */ | 261 | { 52, 0x9A, 0, 128, true }, /* 0: 400 0 */ |
@@ -273,6 +270,20 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = { | |||
273 | { 154, 0x9A, 1, 128, false }, /* 9: 1200 0 */ | 270 | { 154, 0x9A, 1, 128, false }, /* 9: 1200 0 */ |
274 | }; | 271 | }; |
275 | 272 | ||
273 | static const struct bxt_ddi_buf_trans bxt_ddi_translations_edp[] = { | ||
274 | /* Idx NT mV diff db */ | ||
275 | { 26, 0, 0, 128, false }, /* 0: 200 0 */ | ||
276 | { 38, 0, 0, 112, false }, /* 1: 200 1.5 */ | ||
277 | { 48, 0, 0, 96, false }, /* 2: 200 4 */ | ||
278 | { 54, 0, 0, 69, false }, /* 3: 200 6 */ | ||
279 | { 32, 0, 0, 128, false }, /* 4: 250 0 */ | ||
280 | { 48, 0, 0, 104, false }, /* 5: 250 1.5 */ | ||
281 | { 54, 0, 0, 85, false }, /* 6: 250 4 */ | ||
282 | { 43, 0, 0, 128, false }, /* 7: 300 0 */ | ||
283 | { 54, 0, 0, 101, false }, /* 8: 300 1.5 */ | ||
284 | { 48, 0, 0, 128, false }, /* 9: 300 0 */ | ||
285 | }; | ||
286 | |||
276 | /* BSpec has 2 recommended values - entries 0 and 8. | 287 | /* BSpec has 2 recommended values - entries 0 and 8. |
277 | * Using the entry with higher vswing. | 288 | * Using the entry with higher vswing. |
278 | */ | 289 | */ |
@@ -298,21 +309,26 @@ static void ddi_get_encoder_port(struct intel_encoder *intel_encoder, | |||
298 | enum port *port) | 309 | enum port *port) |
299 | { | 310 | { |
300 | struct drm_encoder *encoder = &intel_encoder->base; | 311 | struct drm_encoder *encoder = &intel_encoder->base; |
301 | int type = intel_encoder->type; | ||
302 | 312 | ||
303 | if (type == INTEL_OUTPUT_DP_MST) { | 313 | switch (intel_encoder->type) { |
314 | case INTEL_OUTPUT_DP_MST: | ||
304 | *dig_port = enc_to_mst(encoder)->primary; | 315 | *dig_port = enc_to_mst(encoder)->primary; |
305 | *port = (*dig_port)->port; | 316 | *port = (*dig_port)->port; |
306 | } else if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || | 317 | break; |
307 | type == INTEL_OUTPUT_HDMI || type == INTEL_OUTPUT_UNKNOWN) { | 318 | case INTEL_OUTPUT_DISPLAYPORT: |
319 | case INTEL_OUTPUT_EDP: | ||
320 | case INTEL_OUTPUT_HDMI: | ||
321 | case INTEL_OUTPUT_UNKNOWN: | ||
308 | *dig_port = enc_to_dig_port(encoder); | 322 | *dig_port = enc_to_dig_port(encoder); |
309 | *port = (*dig_port)->port; | 323 | *port = (*dig_port)->port; |
310 | } else if (type == INTEL_OUTPUT_ANALOG) { | 324 | break; |
325 | case INTEL_OUTPUT_ANALOG: | ||
311 | *dig_port = NULL; | 326 | *dig_port = NULL; |
312 | *port = PORT_E; | 327 | *port = PORT_E; |
313 | } else { | 328 | break; |
314 | DRM_ERROR("Invalid DDI encoder type %d\n", type); | 329 | default: |
315 | BUG(); | 330 | WARN(1, "Invalid DDI encoder type %d\n", intel_encoder->type); |
331 | break; | ||
316 | } | 332 | } |
317 | } | 333 | } |
318 | 334 | ||
@@ -542,8 +558,10 @@ void intel_prepare_ddi(struct drm_device *dev) | |||
542 | enum port port; | 558 | enum port port; |
543 | bool supports_hdmi; | 559 | bool supports_hdmi; |
544 | 560 | ||
545 | ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port); | 561 | if (intel_encoder->type == INTEL_OUTPUT_DSI) |
562 | continue; | ||
546 | 563 | ||
564 | ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port); | ||
547 | if (visited[port]) | 565 | if (visited[port]) |
548 | continue; | 566 | continue; |
549 | 567 | ||
@@ -592,7 +610,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) | |||
592 | * | 610 | * |
593 | * WaFDIAutoLinkSetTimingOverrride:hsw | 611 | * WaFDIAutoLinkSetTimingOverrride:hsw |
594 | */ | 612 | */ |
595 | I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) | | 613 | I915_WRITE(FDI_RX_MISC(PIPE_A), FDI_RX_PWRDN_LANE1_VAL(2) | |
596 | FDI_RX_PWRDN_LANE0_VAL(2) | | 614 | FDI_RX_PWRDN_LANE0_VAL(2) | |
597 | FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); | 615 | FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); |
598 | 616 | ||
@@ -600,13 +618,13 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) | |||
600 | rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE | | 618 | rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE | |
601 | FDI_RX_PLL_ENABLE | | 619 | FDI_RX_PLL_ENABLE | |
602 | FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes); | 620 | FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes); |
603 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); | 621 | I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val); |
604 | POSTING_READ(_FDI_RXA_CTL); | 622 | POSTING_READ(FDI_RX_CTL(PIPE_A)); |
605 | udelay(220); | 623 | udelay(220); |
606 | 624 | ||
607 | /* Switch from Rawclk to PCDclk */ | 625 | /* Switch from Rawclk to PCDclk */ |
608 | rx_ctl_val |= FDI_PCDCLK; | 626 | rx_ctl_val |= FDI_PCDCLK; |
609 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); | 627 | I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val); |
610 | 628 | ||
611 | /* Configure Port Clock Select */ | 629 | /* Configure Port Clock Select */ |
612 | I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel); | 630 | I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel); |
@@ -635,21 +653,21 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) | |||
635 | udelay(600); | 653 | udelay(600); |
636 | 654 | ||
637 | /* Program PCH FDI Receiver TU */ | 655 | /* Program PCH FDI Receiver TU */ |
638 | I915_WRITE(_FDI_RXA_TUSIZE1, TU_SIZE(64)); | 656 | I915_WRITE(FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64)); |
639 | 657 | ||
640 | /* Enable PCH FDI Receiver with auto-training */ | 658 | /* Enable PCH FDI Receiver with auto-training */ |
641 | rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO; | 659 | rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO; |
642 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); | 660 | I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val); |
643 | POSTING_READ(_FDI_RXA_CTL); | 661 | POSTING_READ(FDI_RX_CTL(PIPE_A)); |
644 | 662 | ||
645 | /* Wait for FDI receiver lane calibration */ | 663 | /* Wait for FDI receiver lane calibration */ |
646 | udelay(30); | 664 | udelay(30); |
647 | 665 | ||
648 | /* Unset FDI_RX_MISC pwrdn lanes */ | 666 | /* Unset FDI_RX_MISC pwrdn lanes */ |
649 | temp = I915_READ(_FDI_RXA_MISC); | 667 | temp = I915_READ(FDI_RX_MISC(PIPE_A)); |
650 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); | 668 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
651 | I915_WRITE(_FDI_RXA_MISC, temp); | 669 | I915_WRITE(FDI_RX_MISC(PIPE_A), temp); |
652 | POSTING_READ(_FDI_RXA_MISC); | 670 | POSTING_READ(FDI_RX_MISC(PIPE_A)); |
653 | 671 | ||
654 | /* Wait for FDI auto training time */ | 672 | /* Wait for FDI auto training time */ |
655 | udelay(5); | 673 | udelay(5); |
@@ -683,15 +701,15 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) | |||
683 | intel_wait_ddi_buf_idle(dev_priv, PORT_E); | 701 | intel_wait_ddi_buf_idle(dev_priv, PORT_E); |
684 | 702 | ||
685 | rx_ctl_val &= ~FDI_RX_ENABLE; | 703 | rx_ctl_val &= ~FDI_RX_ENABLE; |
686 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); | 704 | I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val); |
687 | POSTING_READ(_FDI_RXA_CTL); | 705 | POSTING_READ(FDI_RX_CTL(PIPE_A)); |
688 | 706 | ||
689 | /* Reset FDI_RX_MISC pwrdn lanes */ | 707 | /* Reset FDI_RX_MISC pwrdn lanes */ |
690 | temp = I915_READ(_FDI_RXA_MISC); | 708 | temp = I915_READ(FDI_RX_MISC(PIPE_A)); |
691 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); | 709 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
692 | temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2); | 710 | temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2); |
693 | I915_WRITE(_FDI_RXA_MISC, temp); | 711 | I915_WRITE(FDI_RX_MISC(PIPE_A), temp); |
694 | POSTING_READ(_FDI_RXA_MISC); | 712 | POSTING_READ(FDI_RX_MISC(PIPE_A)); |
695 | } | 713 | } |
696 | 714 | ||
697 | DRM_ERROR("FDI link training failed!\n"); | 715 | DRM_ERROR("FDI link training failed!\n"); |
@@ -953,8 +971,8 @@ static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv, | |||
953 | uint32_t cfgcr1_val, cfgcr2_val; | 971 | uint32_t cfgcr1_val, cfgcr2_val; |
954 | uint32_t p0, p1, p2, dco_freq; | 972 | uint32_t p0, p1, p2, dco_freq; |
955 | 973 | ||
956 | cfgcr1_reg = GET_CFG_CR1_REG(dpll); | 974 | cfgcr1_reg = DPLL_CFGCR1(dpll); |
957 | cfgcr2_reg = GET_CFG_CR2_REG(dpll); | 975 | cfgcr2_reg = DPLL_CFGCR2(dpll); |
958 | 976 | ||
959 | cfgcr1_val = I915_READ(cfgcr1_reg); | 977 | cfgcr1_val = I915_READ(cfgcr1_reg); |
960 | cfgcr2_val = I915_READ(cfgcr2_reg); | 978 | cfgcr2_val = I915_READ(cfgcr2_reg); |
@@ -2027,7 +2045,8 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder, | |||
2027 | void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc) | 2045 | void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc) |
2028 | { | 2046 | { |
2029 | struct drm_crtc *crtc = &intel_crtc->base; | 2047 | struct drm_crtc *crtc = &intel_crtc->base; |
2030 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; | 2048 | struct drm_device *dev = crtc->dev; |
2049 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2031 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); | 2050 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
2032 | enum port port = intel_ddi_get_encoder_port(intel_encoder); | 2051 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
2033 | enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; | 2052 | enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; |
@@ -2112,7 +2131,11 @@ static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level, | |||
2112 | u32 n_entries, i; | 2131 | u32 n_entries, i; |
2113 | uint32_t val; | 2132 | uint32_t val; |
2114 | 2133 | ||
2115 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { | 2134 | if (type == INTEL_OUTPUT_EDP && dev_priv->edp_low_vswing) { |
2135 | n_entries = ARRAY_SIZE(bxt_ddi_translations_edp); | ||
2136 | ddi_translations = bxt_ddi_translations_edp; | ||
2137 | } else if (type == INTEL_OUTPUT_DISPLAYPORT | ||
2138 | || type == INTEL_OUTPUT_EDP) { | ||
2116 | n_entries = ARRAY_SIZE(bxt_ddi_translations_dp); | 2139 | n_entries = ARRAY_SIZE(bxt_ddi_translations_dp); |
2117 | ddi_translations = bxt_ddi_translations_dp; | 2140 | ddi_translations = bxt_ddi_translations_dp; |
2118 | } else if (type == INTEL_OUTPUT_HDMI) { | 2141 | } else if (type == INTEL_OUTPUT_HDMI) { |
@@ -2150,9 +2173,13 @@ static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level, | |||
2150 | I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val); | 2173 | I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val); |
2151 | 2174 | ||
2152 | val = I915_READ(BXT_PORT_TX_DW3_LN0(port)); | 2175 | val = I915_READ(BXT_PORT_TX_DW3_LN0(port)); |
2153 | val &= ~UNIQE_TRANGE_EN_METHOD; | 2176 | val &= ~SCALE_DCOMP_METHOD; |
2154 | if (ddi_translations[level].enable) | 2177 | if (ddi_translations[level].enable) |
2155 | val |= UNIQE_TRANGE_EN_METHOD; | 2178 | val |= SCALE_DCOMP_METHOD; |
2179 | |||
2180 | if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD)) | ||
2181 | DRM_ERROR("Disabled scaling while ouniqetrangenmethod was set"); | ||
2182 | |||
2156 | I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val); | 2183 | I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val); |
2157 | 2184 | ||
2158 | val = I915_READ(BXT_PORT_TX_DW4_LN0(port)); | 2185 | val = I915_READ(BXT_PORT_TX_DW4_LN0(port)); |
@@ -2293,7 +2320,6 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) | |||
2293 | 2320 | ||
2294 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); | 2321 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
2295 | intel_dp_start_link_train(intel_dp); | 2322 | intel_dp_start_link_train(intel_dp); |
2296 | intel_dp_complete_link_train(intel_dp); | ||
2297 | if (port != PORT_A || INTEL_INFO(dev)->gen >= 9) | 2323 | if (port != PORT_A || INTEL_INFO(dev)->gen >= 9) |
2298 | intel_dp_stop_link_train(intel_dp); | 2324 | intel_dp_stop_link_train(intel_dp); |
2299 | } else if (type == INTEL_OUTPUT_HDMI) { | 2325 | } else if (type == INTEL_OUTPUT_HDMI) { |
@@ -2480,20 +2506,20 @@ static const struct skl_dpll_regs skl_dpll_regs[3] = { | |||
2480 | { | 2506 | { |
2481 | /* DPLL 1 */ | 2507 | /* DPLL 1 */ |
2482 | .ctl = LCPLL2_CTL, | 2508 | .ctl = LCPLL2_CTL, |
2483 | .cfgcr1 = DPLL1_CFGCR1, | 2509 | .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1), |
2484 | .cfgcr2 = DPLL1_CFGCR2, | 2510 | .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1), |
2485 | }, | 2511 | }, |
2486 | { | 2512 | { |
2487 | /* DPLL 2 */ | 2513 | /* DPLL 2 */ |
2488 | .ctl = WRPLL_CTL1, | 2514 | .ctl = WRPLL_CTL1, |
2489 | .cfgcr1 = DPLL2_CFGCR1, | 2515 | .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2), |
2490 | .cfgcr2 = DPLL2_CFGCR2, | 2516 | .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2), |
2491 | }, | 2517 | }, |
2492 | { | 2518 | { |
2493 | /* DPLL 3 */ | 2519 | /* DPLL 3 */ |
2494 | .ctl = WRPLL_CTL2, | 2520 | .ctl = WRPLL_CTL2, |
2495 | .cfgcr1 = DPLL3_CFGCR1, | 2521 | .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3), |
2496 | .cfgcr2 = DPLL3_CFGCR2, | 2522 | .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3), |
2497 | }, | 2523 | }, |
2498 | }; | 2524 | }; |
2499 | 2525 | ||
@@ -2999,22 +3025,22 @@ void intel_ddi_fdi_disable(struct drm_crtc *crtc) | |||
2999 | 3025 | ||
3000 | intel_ddi_post_disable(intel_encoder); | 3026 | intel_ddi_post_disable(intel_encoder); |
3001 | 3027 | ||
3002 | val = I915_READ(_FDI_RXA_CTL); | 3028 | val = I915_READ(FDI_RX_CTL(PIPE_A)); |
3003 | val &= ~FDI_RX_ENABLE; | 3029 | val &= ~FDI_RX_ENABLE; |
3004 | I915_WRITE(_FDI_RXA_CTL, val); | 3030 | I915_WRITE(FDI_RX_CTL(PIPE_A), val); |
3005 | 3031 | ||
3006 | val = I915_READ(_FDI_RXA_MISC); | 3032 | val = I915_READ(FDI_RX_MISC(PIPE_A)); |
3007 | val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); | 3033 | val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
3008 | val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2); | 3034 | val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2); |
3009 | I915_WRITE(_FDI_RXA_MISC, val); | 3035 | I915_WRITE(FDI_RX_MISC(PIPE_A), val); |
3010 | 3036 | ||
3011 | val = I915_READ(_FDI_RXA_CTL); | 3037 | val = I915_READ(FDI_RX_CTL(PIPE_A)); |
3012 | val &= ~FDI_PCDCLK; | 3038 | val &= ~FDI_PCDCLK; |
3013 | I915_WRITE(_FDI_RXA_CTL, val); | 3039 | I915_WRITE(FDI_RX_CTL(PIPE_A), val); |
3014 | 3040 | ||
3015 | val = I915_READ(_FDI_RXA_CTL); | 3041 | val = I915_READ(FDI_RX_CTL(PIPE_A)); |
3016 | val &= ~FDI_RX_PLL_ENABLE; | 3042 | val &= ~FDI_RX_PLL_ENABLE; |
3017 | I915_WRITE(_FDI_RXA_CTL, val); | 3043 | I915_WRITE(FDI_RX_CTL(PIPE_A), val); |
3018 | } | 3044 | } |
3019 | 3045 | ||
3020 | void intel_ddi_get_config(struct intel_encoder *encoder, | 3046 | void intel_ddi_get_config(struct intel_encoder *encoder, |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 184725770ae7..cddb0c692334 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -132,6 +132,42 @@ struct intel_limit { | |||
132 | intel_p2_t p2; | 132 | intel_p2_t p2; |
133 | }; | 133 | }; |
134 | 134 | ||
135 | /* returns HPLL frequency in kHz */ | ||
136 | static int valleyview_get_vco(struct drm_i915_private *dev_priv) | ||
137 | { | ||
138 | int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 }; | ||
139 | |||
140 | /* Obtain SKU information */ | ||
141 | mutex_lock(&dev_priv->sb_lock); | ||
142 | hpll_freq = vlv_cck_read(dev_priv, CCK_FUSE_REG) & | ||
143 | CCK_FUSE_HPLL_FREQ_MASK; | ||
144 | mutex_unlock(&dev_priv->sb_lock); | ||
145 | |||
146 | return vco_freq[hpll_freq] * 1000; | ||
147 | } | ||
148 | |||
149 | static int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv, | ||
150 | const char *name, u32 reg) | ||
151 | { | ||
152 | u32 val; | ||
153 | int divider; | ||
154 | |||
155 | if (dev_priv->hpll_freq == 0) | ||
156 | dev_priv->hpll_freq = valleyview_get_vco(dev_priv); | ||
157 | |||
158 | mutex_lock(&dev_priv->sb_lock); | ||
159 | val = vlv_cck_read(dev_priv, reg); | ||
160 | mutex_unlock(&dev_priv->sb_lock); | ||
161 | |||
162 | divider = val & CCK_FREQUENCY_VALUES; | ||
163 | |||
164 | WARN((val & CCK_FREQUENCY_STATUS) != | ||
165 | (divider << CCK_FREQUENCY_STATUS_SHIFT), | ||
166 | "%s change in progress\n", name); | ||
167 | |||
168 | return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, divider + 1); | ||
169 | } | ||
170 | |||
135 | int | 171 | int |
136 | intel_pch_rawclk(struct drm_device *dev) | 172 | intel_pch_rawclk(struct drm_device *dev) |
137 | { | 173 | { |
@@ -175,6 +211,17 @@ int intel_hrawclk(struct drm_device *dev) | |||
175 | } | 211 | } |
176 | } | 212 | } |
177 | 213 | ||
214 | static void intel_update_czclk(struct drm_i915_private *dev_priv) | ||
215 | { | ||
216 | if (!IS_VALLEYVIEW(dev_priv)) | ||
217 | return; | ||
218 | |||
219 | dev_priv->czclk_freq = vlv_get_cck_clock_hpll(dev_priv, "czclk", | ||
220 | CCK_CZ_CLOCK_CONTROL); | ||
221 | |||
222 | DRM_DEBUG_DRIVER("CZ clock rate: %d kHz\n", dev_priv->czclk_freq); | ||
223 | } | ||
224 | |||
178 | static inline u32 /* units of 100MHz */ | 225 | static inline u32 /* units of 100MHz */ |
179 | intel_fdi_link_freq(struct drm_device *dev) | 226 | intel_fdi_link_freq(struct drm_device *dev) |
180 | { | 227 | { |
@@ -1295,7 +1342,7 @@ static void assert_cursor(struct drm_i915_private *dev_priv, | |||
1295 | bool cur_state; | 1342 | bool cur_state; |
1296 | 1343 | ||
1297 | if (IS_845G(dev) || IS_I865G(dev)) | 1344 | if (IS_845G(dev) || IS_I865G(dev)) |
1298 | cur_state = I915_READ(_CURACNTR) & CURSOR_ENABLE; | 1345 | cur_state = I915_READ(CURCNTR(PIPE_A)) & CURSOR_ENABLE; |
1299 | else | 1346 | else |
1300 | cur_state = I915_READ(CURCNTR(pipe)) & CURSOR_MODE; | 1347 | cur_state = I915_READ(CURCNTR(pipe)) & CURSOR_MODE; |
1301 | 1348 | ||
@@ -2003,9 +2050,9 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv, | |||
2003 | assert_fdi_rx_enabled(dev_priv, TRANSCODER_A); | 2050 | assert_fdi_rx_enabled(dev_priv, TRANSCODER_A); |
2004 | 2051 | ||
2005 | /* Workaround: set timing override bit. */ | 2052 | /* Workaround: set timing override bit. */ |
2006 | val = I915_READ(_TRANSA_CHICKEN2); | 2053 | val = I915_READ(TRANS_CHICKEN2(PIPE_A)); |
2007 | val |= TRANS_CHICKEN2_TIMING_OVERRIDE; | 2054 | val |= TRANS_CHICKEN2_TIMING_OVERRIDE; |
2008 | I915_WRITE(_TRANSA_CHICKEN2, val); | 2055 | I915_WRITE(TRANS_CHICKEN2(PIPE_A), val); |
2009 | 2056 | ||
2010 | val = TRANS_ENABLE; | 2057 | val = TRANS_ENABLE; |
2011 | pipeconf_val = I915_READ(PIPECONF(cpu_transcoder)); | 2058 | pipeconf_val = I915_READ(PIPECONF(cpu_transcoder)); |
@@ -2063,9 +2110,9 @@ static void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv) | |||
2063 | DRM_ERROR("Failed to disable PCH transcoder\n"); | 2110 | DRM_ERROR("Failed to disable PCH transcoder\n"); |
2064 | 2111 | ||
2065 | /* Workaround: clear timing override bit. */ | 2112 | /* Workaround: clear timing override bit. */ |
2066 | val = I915_READ(_TRANSA_CHICKEN2); | 2113 | val = I915_READ(TRANS_CHICKEN2(PIPE_A)); |
2067 | val &= ~TRANS_CHICKEN2_TIMING_OVERRIDE; | 2114 | val &= ~TRANS_CHICKEN2_TIMING_OVERRIDE; |
2068 | I915_WRITE(_TRANSA_CHICKEN2, val); | 2115 | I915_WRITE(TRANS_CHICKEN2(PIPE_A), val); |
2069 | } | 2116 | } |
2070 | 2117 | ||
2071 | /** | 2118 | /** |
@@ -2498,6 +2545,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, | |||
2498 | struct intel_initial_plane_config *plane_config) | 2545 | struct intel_initial_plane_config *plane_config) |
2499 | { | 2546 | { |
2500 | struct drm_device *dev = crtc->base.dev; | 2547 | struct drm_device *dev = crtc->base.dev; |
2548 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2501 | struct drm_i915_gem_object *obj = NULL; | 2549 | struct drm_i915_gem_object *obj = NULL; |
2502 | struct drm_mode_fb_cmd2 mode_cmd = { 0 }; | 2550 | struct drm_mode_fb_cmd2 mode_cmd = { 0 }; |
2503 | struct drm_framebuffer *fb = &plane_config->fb->base; | 2551 | struct drm_framebuffer *fb = &plane_config->fb->base; |
@@ -2510,6 +2558,12 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, | |||
2510 | if (plane_config->size == 0) | 2558 | if (plane_config->size == 0) |
2511 | return false; | 2559 | return false; |
2512 | 2560 | ||
2561 | /* If the FB is too big, just don't use it since fbdev is not very | ||
2562 | * important and we should probably use that space with FBC or other | ||
2563 | * features. */ | ||
2564 | if (size_aligned * 2 > dev_priv->gtt.stolen_usable_size) | ||
2565 | return false; | ||
2566 | |||
2513 | obj = i915_gem_object_create_stolen_for_preallocated(dev, | 2567 | obj = i915_gem_object_create_stolen_for_preallocated(dev, |
2514 | base_aligned, | 2568 | base_aligned, |
2515 | base_aligned, | 2569 | base_aligned, |
@@ -3077,27 +3131,19 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc, | |||
3077 | fb->pixel_format); | 3131 | fb->pixel_format); |
3078 | surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj, 0); | 3132 | surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj, 0); |
3079 | 3133 | ||
3080 | /* | 3134 | WARN_ON(drm_rect_width(&plane_state->src) == 0); |
3081 | * FIXME: intel_plane_state->src, dst aren't set when transitional | 3135 | |
3082 | * update_plane helpers are called from legacy paths. | 3136 | scaler_id = plane_state->scaler_id; |
3083 | * Once full atomic crtc is available, below check can be avoided. | 3137 | src_x = plane_state->src.x1 >> 16; |
3084 | */ | 3138 | src_y = plane_state->src.y1 >> 16; |
3085 | if (drm_rect_width(&plane_state->src)) { | 3139 | src_w = drm_rect_width(&plane_state->src) >> 16; |
3086 | scaler_id = plane_state->scaler_id; | 3140 | src_h = drm_rect_height(&plane_state->src) >> 16; |
3087 | src_x = plane_state->src.x1 >> 16; | 3141 | dst_x = plane_state->dst.x1; |
3088 | src_y = plane_state->src.y1 >> 16; | 3142 | dst_y = plane_state->dst.y1; |
3089 | src_w = drm_rect_width(&plane_state->src) >> 16; | 3143 | dst_w = drm_rect_width(&plane_state->dst); |
3090 | src_h = drm_rect_height(&plane_state->src) >> 16; | 3144 | dst_h = drm_rect_height(&plane_state->dst); |
3091 | dst_x = plane_state->dst.x1; | 3145 | |
3092 | dst_y = plane_state->dst.y1; | 3146 | WARN_ON(x != src_x || y != src_y); |
3093 | dst_w = drm_rect_width(&plane_state->dst); | ||
3094 | dst_h = drm_rect_height(&plane_state->dst); | ||
3095 | |||
3096 | WARN_ON(x != src_x || y != src_y); | ||
3097 | } else { | ||
3098 | src_w = intel_crtc->config->pipe_src_w; | ||
3099 | src_h = intel_crtc->config->pipe_src_h; | ||
3100 | } | ||
3101 | 3147 | ||
3102 | if (intel_rotation_90_or_270(rotation)) { | 3148 | if (intel_rotation_90_or_270(rotation)) { |
3103 | /* stride = Surface height in tiles */ | 3149 | /* stride = Surface height in tiles */ |
@@ -4392,8 +4438,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, | |||
4392 | int skl_update_scaler_crtc(struct intel_crtc_state *state) | 4438 | int skl_update_scaler_crtc(struct intel_crtc_state *state) |
4393 | { | 4439 | { |
4394 | struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc); | 4440 | struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc); |
4395 | struct drm_display_mode *adjusted_mode = | 4441 | const struct drm_display_mode *adjusted_mode = &state->base.adjusted_mode; |
4396 | &state->base.adjusted_mode; | ||
4397 | 4442 | ||
4398 | DRM_DEBUG_KMS("Updating scaler for [CRTC:%i] scaler_user index %u.%u\n", | 4443 | DRM_DEBUG_KMS("Updating scaler for [CRTC:%i] scaler_user index %u.%u\n", |
4399 | intel_crtc->base.base.id, intel_crtc->pipe, SKL_CRTC_INDEX); | 4444 | intel_crtc->base.base.id, intel_crtc->pipe, SKL_CRTC_INDEX); |
@@ -4401,7 +4446,7 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state) | |||
4401 | return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX, | 4446 | return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX, |
4402 | &state->scaler_state.scaler_id, DRM_ROTATE_0, | 4447 | &state->scaler_state.scaler_id, DRM_ROTATE_0, |
4403 | state->pipe_src_w, state->pipe_src_h, | 4448 | state->pipe_src_w, state->pipe_src_h, |
4404 | adjusted_mode->hdisplay, adjusted_mode->vdisplay); | 4449 | adjusted_mode->crtc_hdisplay, adjusted_mode->crtc_vdisplay); |
4405 | } | 4450 | } |
4406 | 4451 | ||
4407 | /** | 4452 | /** |
@@ -4594,7 +4639,6 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc) | |||
4594 | struct drm_i915_private *dev_priv = dev->dev_private; | 4639 | struct drm_i915_private *dev_priv = dev->dev_private; |
4595 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 4640 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
4596 | enum pipe pipe = intel_crtc->pipe; | 4641 | enum pipe pipe = intel_crtc->pipe; |
4597 | int palreg = PALETTE(pipe); | ||
4598 | int i; | 4642 | int i; |
4599 | bool reenable_ips = false; | 4643 | bool reenable_ips = false; |
4600 | 4644 | ||
@@ -4609,10 +4653,6 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc) | |||
4609 | assert_pll_enabled(dev_priv, pipe); | 4653 | assert_pll_enabled(dev_priv, pipe); |
4610 | } | 4654 | } |
4611 | 4655 | ||
4612 | /* use legacy palette for Ironlake */ | ||
4613 | if (!HAS_GMCH_DISPLAY(dev)) | ||
4614 | palreg = LGC_PALETTE(pipe); | ||
4615 | |||
4616 | /* Workaround : Do not read or write the pipe palette/gamma data while | 4656 | /* Workaround : Do not read or write the pipe palette/gamma data while |
4617 | * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled. | 4657 | * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled. |
4618 | */ | 4658 | */ |
@@ -4624,7 +4664,14 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc) | |||
4624 | } | 4664 | } |
4625 | 4665 | ||
4626 | for (i = 0; i < 256; i++) { | 4666 | for (i = 0; i < 256; i++) { |
4627 | I915_WRITE(palreg + 4 * i, | 4667 | u32 palreg; |
4668 | |||
4669 | if (HAS_GMCH_DISPLAY(dev)) | ||
4670 | palreg = PALETTE(pipe, i); | ||
4671 | else | ||
4672 | palreg = LGC_PALETTE(pipe, i); | ||
4673 | |||
4674 | I915_WRITE(palreg, | ||
4628 | (intel_crtc->lut_r[i] << 16) | | 4675 | (intel_crtc->lut_r[i] << 16) | |
4629 | (intel_crtc->lut_g[i] << 8) | | 4676 | (intel_crtc->lut_g[i] << 8) | |
4630 | intel_crtc->lut_b[i]); | 4677 | intel_crtc->lut_b[i]); |
@@ -4757,7 +4804,6 @@ static void intel_post_plane_update(struct intel_crtc *crtc) | |||
4757 | struct intel_crtc_atomic_commit *atomic = &crtc->atomic; | 4804 | struct intel_crtc_atomic_commit *atomic = &crtc->atomic; |
4758 | struct drm_device *dev = crtc->base.dev; | 4805 | struct drm_device *dev = crtc->base.dev; |
4759 | struct drm_i915_private *dev_priv = dev->dev_private; | 4806 | struct drm_i915_private *dev_priv = dev->dev_private; |
4760 | struct drm_plane *plane; | ||
4761 | 4807 | ||
4762 | if (atomic->wait_vblank) | 4808 | if (atomic->wait_vblank) |
4763 | intel_wait_for_vblank(dev, crtc->pipe); | 4809 | intel_wait_for_vblank(dev, crtc->pipe); |
@@ -4776,10 +4822,6 @@ static void intel_post_plane_update(struct intel_crtc *crtc) | |||
4776 | if (atomic->post_enable_primary) | 4822 | if (atomic->post_enable_primary) |
4777 | intel_post_enable_primary(&crtc->base); | 4823 | intel_post_enable_primary(&crtc->base); |
4778 | 4824 | ||
4779 | drm_for_each_plane_mask(plane, dev, atomic->update_sprite_watermarks) | ||
4780 | intel_update_sprite_watermarks(plane, &crtc->base, | ||
4781 | 0, 0, 0, false, false); | ||
4782 | |||
4783 | memset(atomic, 0, sizeof(*atomic)); | 4825 | memset(atomic, 0, sizeof(*atomic)); |
4784 | } | 4826 | } |
4785 | 4827 | ||
@@ -4922,6 +4964,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) | |||
4922 | int pipe = intel_crtc->pipe, hsw_workaround_pipe; | 4964 | int pipe = intel_crtc->pipe, hsw_workaround_pipe; |
4923 | struct intel_crtc_state *pipe_config = | 4965 | struct intel_crtc_state *pipe_config = |
4924 | to_intel_crtc_state(crtc->state); | 4966 | to_intel_crtc_state(crtc->state); |
4967 | bool is_dsi = intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DSI); | ||
4925 | 4968 | ||
4926 | if (WARN_ON(intel_crtc->active)) | 4969 | if (WARN_ON(intel_crtc->active)) |
4927 | return; | 4970 | return; |
@@ -4951,9 +4994,12 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) | |||
4951 | intel_crtc->active = true; | 4994 | intel_crtc->active = true; |
4952 | 4995 | ||
4953 | intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); | 4996 | intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); |
4954 | for_each_encoder_on_crtc(dev, crtc, encoder) | 4997 | for_each_encoder_on_crtc(dev, crtc, encoder) { |
4998 | if (encoder->pre_pll_enable) | ||
4999 | encoder->pre_pll_enable(encoder); | ||
4955 | if (encoder->pre_enable) | 5000 | if (encoder->pre_enable) |
4956 | encoder->pre_enable(encoder); | 5001 | encoder->pre_enable(encoder); |
5002 | } | ||
4957 | 5003 | ||
4958 | if (intel_crtc->config->has_pch_encoder) { | 5004 | if (intel_crtc->config->has_pch_encoder) { |
4959 | intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A, | 5005 | intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A, |
@@ -4961,7 +5007,8 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) | |||
4961 | dev_priv->display.fdi_link_train(crtc); | 5007 | dev_priv->display.fdi_link_train(crtc); |
4962 | } | 5008 | } |
4963 | 5009 | ||
4964 | intel_ddi_enable_pipe_clock(intel_crtc); | 5010 | if (!is_dsi) |
5011 | intel_ddi_enable_pipe_clock(intel_crtc); | ||
4965 | 5012 | ||
4966 | if (INTEL_INFO(dev)->gen >= 9) | 5013 | if (INTEL_INFO(dev)->gen >= 9) |
4967 | skylake_pfit_enable(intel_crtc); | 5014 | skylake_pfit_enable(intel_crtc); |
@@ -4975,7 +5022,8 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) | |||
4975 | intel_crtc_load_lut(crtc); | 5022 | intel_crtc_load_lut(crtc); |
4976 | 5023 | ||
4977 | intel_ddi_set_pipe_settings(crtc); | 5024 | intel_ddi_set_pipe_settings(crtc); |
4978 | intel_ddi_enable_transcoder_func(crtc); | 5025 | if (!is_dsi) |
5026 | intel_ddi_enable_transcoder_func(crtc); | ||
4979 | 5027 | ||
4980 | intel_update_watermarks(crtc); | 5028 | intel_update_watermarks(crtc); |
4981 | intel_enable_pipe(intel_crtc); | 5029 | intel_enable_pipe(intel_crtc); |
@@ -4983,7 +5031,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) | |||
4983 | if (intel_crtc->config->has_pch_encoder) | 5031 | if (intel_crtc->config->has_pch_encoder) |
4984 | lpt_pch_enable(crtc); | 5032 | lpt_pch_enable(crtc); |
4985 | 5033 | ||
4986 | if (intel_crtc->config->dp_encoder_is_mst) | 5034 | if (intel_crtc->config->dp_encoder_is_mst && !is_dsi) |
4987 | intel_ddi_set_vc_payload_alloc(crtc, true); | 5035 | intel_ddi_set_vc_payload_alloc(crtc, true); |
4988 | 5036 | ||
4989 | assert_vblank_disabled(crtc); | 5037 | assert_vblank_disabled(crtc); |
@@ -5067,9 +5115,6 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) | |||
5067 | 5115 | ||
5068 | ironlake_fdi_pll_disable(intel_crtc); | 5116 | ironlake_fdi_pll_disable(intel_crtc); |
5069 | } | 5117 | } |
5070 | |||
5071 | intel_crtc->active = false; | ||
5072 | intel_update_watermarks(crtc); | ||
5073 | } | 5118 | } |
5074 | 5119 | ||
5075 | static void haswell_crtc_disable(struct drm_crtc *crtc) | 5120 | static void haswell_crtc_disable(struct drm_crtc *crtc) |
@@ -5079,6 +5124,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) | |||
5079 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 5124 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
5080 | struct intel_encoder *encoder; | 5125 | struct intel_encoder *encoder; |
5081 | enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; | 5126 | enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; |
5127 | bool is_dsi = intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DSI); | ||
5082 | 5128 | ||
5083 | for_each_encoder_on_crtc(dev, crtc, encoder) { | 5129 | for_each_encoder_on_crtc(dev, crtc, encoder) { |
5084 | intel_opregion_notify_encoder(encoder, false); | 5130 | intel_opregion_notify_encoder(encoder, false); |
@@ -5096,14 +5142,16 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) | |||
5096 | if (intel_crtc->config->dp_encoder_is_mst) | 5142 | if (intel_crtc->config->dp_encoder_is_mst) |
5097 | intel_ddi_set_vc_payload_alloc(crtc, false); | 5143 | intel_ddi_set_vc_payload_alloc(crtc, false); |
5098 | 5144 | ||
5099 | intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder); | 5145 | if (!is_dsi) |
5146 | intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder); | ||
5100 | 5147 | ||
5101 | if (INTEL_INFO(dev)->gen >= 9) | 5148 | if (INTEL_INFO(dev)->gen >= 9) |
5102 | skylake_scaler_disable(intel_crtc); | 5149 | skylake_scaler_disable(intel_crtc); |
5103 | else | 5150 | else |
5104 | ironlake_pfit_disable(intel_crtc, false); | 5151 | ironlake_pfit_disable(intel_crtc, false); |
5105 | 5152 | ||
5106 | intel_ddi_disable_pipe_clock(intel_crtc); | 5153 | if (!is_dsi) |
5154 | intel_ddi_disable_pipe_clock(intel_crtc); | ||
5107 | 5155 | ||
5108 | if (intel_crtc->config->has_pch_encoder) { | 5156 | if (intel_crtc->config->has_pch_encoder) { |
5109 | lpt_disable_pch_transcoder(dev_priv); | 5157 | lpt_disable_pch_transcoder(dev_priv); |
@@ -5113,9 +5161,6 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) | |||
5113 | for_each_encoder_on_crtc(dev, crtc, encoder) | 5161 | for_each_encoder_on_crtc(dev, crtc, encoder) |
5114 | if (encoder->post_disable) | 5162 | if (encoder->post_disable) |
5115 | encoder->post_disable(encoder); | 5163 | encoder->post_disable(encoder); |
5116 | |||
5117 | intel_crtc->active = false; | ||
5118 | intel_update_watermarks(crtc); | ||
5119 | } | 5164 | } |
5120 | 5165 | ||
5121 | static void i9xx_pfit_enable(struct intel_crtc *crtc) | 5166 | static void i9xx_pfit_enable(struct intel_crtc *crtc) |
@@ -5709,10 +5754,16 @@ void skl_uninit_cdclk(struct drm_i915_private *dev_priv) | |||
5709 | if (I915_READ(DBUF_CTL) & DBUF_POWER_STATE) | 5754 | if (I915_READ(DBUF_CTL) & DBUF_POWER_STATE) |
5710 | DRM_ERROR("DBuf power disable timeout\n"); | 5755 | DRM_ERROR("DBuf power disable timeout\n"); |
5711 | 5756 | ||
5712 | /* disable DPLL0 */ | 5757 | /* |
5713 | I915_WRITE(LCPLL1_CTL, I915_READ(LCPLL1_CTL) & ~LCPLL_PLL_ENABLE); | 5758 | * DMC assumes ownership of LCPLL and will get confused if we touch it. |
5714 | if (wait_for(!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_LOCK), 1)) | 5759 | */ |
5715 | DRM_ERROR("Couldn't disable DPLL0\n"); | 5760 | if (dev_priv->csr.dmc_payload) { |
5761 | /* disable DPLL0 */ | ||
5762 | I915_WRITE(LCPLL1_CTL, I915_READ(LCPLL1_CTL) & | ||
5763 | ~LCPLL_PLL_ENABLE); | ||
5764 | if (wait_for(!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_LOCK), 1)) | ||
5765 | DRM_ERROR("Couldn't disable DPLL0\n"); | ||
5766 | } | ||
5716 | 5767 | ||
5717 | intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); | 5768 | intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); |
5718 | } | 5769 | } |
@@ -5749,20 +5800,6 @@ void skl_init_cdclk(struct drm_i915_private *dev_priv) | |||
5749 | DRM_ERROR("DBuf power enable timeout\n"); | 5800 | DRM_ERROR("DBuf power enable timeout\n"); |
5750 | } | 5801 | } |
5751 | 5802 | ||
5752 | /* returns HPLL frequency in kHz */ | ||
5753 | static int valleyview_get_vco(struct drm_i915_private *dev_priv) | ||
5754 | { | ||
5755 | int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 }; | ||
5756 | |||
5757 | /* Obtain SKU information */ | ||
5758 | mutex_lock(&dev_priv->sb_lock); | ||
5759 | hpll_freq = vlv_cck_read(dev_priv, CCK_FUSE_REG) & | ||
5760 | CCK_FUSE_HPLL_FREQ_MASK; | ||
5761 | mutex_unlock(&dev_priv->sb_lock); | ||
5762 | |||
5763 | return vco_freq[hpll_freq] * 1000; | ||
5764 | } | ||
5765 | |||
5766 | /* Adjust CDclk dividers to allow high res or save power if possible */ | 5803 | /* Adjust CDclk dividers to allow high res or save power if possible */ |
5767 | static void valleyview_set_cdclk(struct drm_device *dev, int cdclk) | 5804 | static void valleyview_set_cdclk(struct drm_device *dev, int cdclk) |
5768 | { | 5805 | { |
@@ -5800,12 +5837,12 @@ static void valleyview_set_cdclk(struct drm_device *dev, int cdclk) | |||
5800 | 5837 | ||
5801 | /* adjust cdclk divider */ | 5838 | /* adjust cdclk divider */ |
5802 | val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL); | 5839 | val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL); |
5803 | val &= ~DISPLAY_FREQUENCY_VALUES; | 5840 | val &= ~CCK_FREQUENCY_VALUES; |
5804 | val |= divider; | 5841 | val |= divider; |
5805 | vlv_cck_write(dev_priv, CCK_DISPLAY_CLOCK_CONTROL, val); | 5842 | vlv_cck_write(dev_priv, CCK_DISPLAY_CLOCK_CONTROL, val); |
5806 | 5843 | ||
5807 | if (wait_for((vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL) & | 5844 | if (wait_for((vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL) & |
5808 | DISPLAY_FREQUENCY_STATUS) == (divider << DISPLAY_FREQUENCY_STATUS_SHIFT), | 5845 | CCK_FREQUENCY_STATUS) == (divider << CCK_FREQUENCY_STATUS_SHIFT), |
5809 | 50)) | 5846 | 50)) |
5810 | DRM_ERROR("timed out waiting for CDclk change\n"); | 5847 | DRM_ERROR("timed out waiting for CDclk change\n"); |
5811 | } | 5848 | } |
@@ -5983,7 +6020,7 @@ static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv) | |||
5983 | else | 6020 | else |
5984 | default_credits = PFI_CREDIT(8); | 6021 | default_credits = PFI_CREDIT(8); |
5985 | 6022 | ||
5986 | if (DIV_ROUND_CLOSEST(dev_priv->cdclk_freq, 1000) >= dev_priv->rps.cz_freq) { | 6023 | if (dev_priv->cdclk_freq >= dev_priv->czclk_freq) { |
5987 | /* CHV suggested value is 31 or 63 */ | 6024 | /* CHV suggested value is 31 or 63 */ |
5988 | if (IS_CHERRYVIEW(dev_priv)) | 6025 | if (IS_CHERRYVIEW(dev_priv)) |
5989 | credits = PFI_CREDIT_63; | 6026 | credits = PFI_CREDIT_63; |
@@ -6214,9 +6251,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) | |||
6214 | 6251 | ||
6215 | if (!IS_GEN2(dev)) | 6252 | if (!IS_GEN2(dev)) |
6216 | intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); | 6253 | intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); |
6217 | |||
6218 | intel_crtc->active = false; | ||
6219 | intel_update_watermarks(crtc); | ||
6220 | } | 6254 | } |
6221 | 6255 | ||
6222 | static void intel_crtc_disable_noatomic(struct drm_crtc *crtc) | 6256 | static void intel_crtc_disable_noatomic(struct drm_crtc *crtc) |
@@ -6236,6 +6270,8 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc) | |||
6236 | 6270 | ||
6237 | intel_crtc_disable_planes(crtc, crtc->state->plane_mask); | 6271 | intel_crtc_disable_planes(crtc, crtc->state->plane_mask); |
6238 | dev_priv->display.crtc_disable(crtc); | 6272 | dev_priv->display.crtc_disable(crtc); |
6273 | intel_crtc->active = false; | ||
6274 | intel_update_watermarks(crtc); | ||
6239 | intel_disable_shared_dpll(intel_crtc); | 6275 | intel_disable_shared_dpll(intel_crtc); |
6240 | 6276 | ||
6241 | domains = intel_crtc->enabled_power_domains; | 6277 | domains = intel_crtc->enabled_power_domains; |
@@ -6472,7 +6508,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc, | |||
6472 | struct intel_crtc_state *pipe_config) | 6508 | struct intel_crtc_state *pipe_config) |
6473 | { | 6509 | { |
6474 | struct drm_device *dev = intel_crtc->base.dev; | 6510 | struct drm_device *dev = intel_crtc->base.dev; |
6475 | struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; | 6511 | const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; |
6476 | int lane, link_bw, fdi_dotclock, ret; | 6512 | int lane, link_bw, fdi_dotclock, ret; |
6477 | bool needs_recompute = false; | 6513 | bool needs_recompute = false; |
6478 | 6514 | ||
@@ -6551,7 +6587,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc, | |||
6551 | { | 6587 | { |
6552 | struct drm_device *dev = crtc->base.dev; | 6588 | struct drm_device *dev = crtc->base.dev; |
6553 | struct drm_i915_private *dev_priv = dev->dev_private; | 6589 | struct drm_i915_private *dev_priv = dev->dev_private; |
6554 | struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; | 6590 | const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; |
6555 | 6591 | ||
6556 | /* FIXME should check pixel clock limits on all platforms */ | 6592 | /* FIXME should check pixel clock limits on all platforms */ |
6557 | if (INTEL_INFO(dev)->gen < 4) { | 6593 | if (INTEL_INFO(dev)->gen < 4) { |
@@ -6588,7 +6624,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc, | |||
6588 | * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw. | 6624 | * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw. |
6589 | */ | 6625 | */ |
6590 | if ((INTEL_INFO(dev)->gen > 4 || IS_G4X(dev)) && | 6626 | if ((INTEL_INFO(dev)->gen > 4 || IS_G4X(dev)) && |
6591 | adjusted_mode->hsync_start == adjusted_mode->hdisplay) | 6627 | adjusted_mode->crtc_hsync_start == adjusted_mode->crtc_hdisplay) |
6592 | return -EINVAL; | 6628 | return -EINVAL; |
6593 | 6629 | ||
6594 | if (HAS_IPS(dev)) | 6630 | if (HAS_IPS(dev)) |
@@ -6715,24 +6751,8 @@ static int haswell_get_display_clock_speed(struct drm_device *dev) | |||
6715 | 6751 | ||
6716 | static int valleyview_get_display_clock_speed(struct drm_device *dev) | 6752 | static int valleyview_get_display_clock_speed(struct drm_device *dev) |
6717 | { | 6753 | { |
6718 | struct drm_i915_private *dev_priv = dev->dev_private; | 6754 | return vlv_get_cck_clock_hpll(to_i915(dev), "cdclk", |
6719 | u32 val; | 6755 | CCK_DISPLAY_CLOCK_CONTROL); |
6720 | int divider; | ||
6721 | |||
6722 | if (dev_priv->hpll_freq == 0) | ||
6723 | dev_priv->hpll_freq = valleyview_get_vco(dev_priv); | ||
6724 | |||
6725 | mutex_lock(&dev_priv->sb_lock); | ||
6726 | val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL); | ||
6727 | mutex_unlock(&dev_priv->sb_lock); | ||
6728 | |||
6729 | divider = val & DISPLAY_FREQUENCY_VALUES; | ||
6730 | |||
6731 | WARN((val & DISPLAY_FREQUENCY_STATUS) != | ||
6732 | (divider << DISPLAY_FREQUENCY_STATUS_SHIFT), | ||
6733 | "cdclk change in progress\n"); | ||
6734 | |||
6735 | return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, divider + 1); | ||
6736 | } | 6756 | } |
6737 | 6757 | ||
6738 | static int ilk_get_display_clock_speed(struct drm_device *dev) | 6758 | static int ilk_get_display_clock_speed(struct drm_device *dev) |
@@ -7619,8 +7639,7 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc) | |||
7619 | struct drm_i915_private *dev_priv = dev->dev_private; | 7639 | struct drm_i915_private *dev_priv = dev->dev_private; |
7620 | enum pipe pipe = intel_crtc->pipe; | 7640 | enum pipe pipe = intel_crtc->pipe; |
7621 | enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; | 7641 | enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; |
7622 | struct drm_display_mode *adjusted_mode = | 7642 | const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode; |
7623 | &intel_crtc->config->base.adjusted_mode; | ||
7624 | uint32_t crtc_vtotal, crtc_vblank_end; | 7643 | uint32_t crtc_vtotal, crtc_vblank_end; |
7625 | int vsyncshift = 0; | 7644 | int vsyncshift = 0; |
7626 | 7645 | ||
@@ -9884,13 +9903,13 @@ static void i845_update_cursor(struct drm_crtc *crtc, u32 base) | |||
9884 | /* On these chipsets we can only modify the base/size/stride | 9903 | /* On these chipsets we can only modify the base/size/stride |
9885 | * whilst the cursor is disabled. | 9904 | * whilst the cursor is disabled. |
9886 | */ | 9905 | */ |
9887 | I915_WRITE(_CURACNTR, 0); | 9906 | I915_WRITE(CURCNTR(PIPE_A), 0); |
9888 | POSTING_READ(_CURACNTR); | 9907 | POSTING_READ(CURCNTR(PIPE_A)); |
9889 | intel_crtc->cursor_cntl = 0; | 9908 | intel_crtc->cursor_cntl = 0; |
9890 | } | 9909 | } |
9891 | 9910 | ||
9892 | if (intel_crtc->cursor_base != base) { | 9911 | if (intel_crtc->cursor_base != base) { |
9893 | I915_WRITE(_CURABASE, base); | 9912 | I915_WRITE(CURBASE(PIPE_A), base); |
9894 | intel_crtc->cursor_base = base; | 9913 | intel_crtc->cursor_base = base; |
9895 | } | 9914 | } |
9896 | 9915 | ||
@@ -9900,8 +9919,8 @@ static void i845_update_cursor(struct drm_crtc *crtc, u32 base) | |||
9900 | } | 9919 | } |
9901 | 9920 | ||
9902 | if (intel_crtc->cursor_cntl != cntl) { | 9921 | if (intel_crtc->cursor_cntl != cntl) { |
9903 | I915_WRITE(_CURACNTR, cntl); | 9922 | I915_WRITE(CURCNTR(PIPE_A), cntl); |
9904 | POSTING_READ(_CURACNTR); | 9923 | POSTING_READ(CURCNTR(PIPE_A)); |
9905 | intel_crtc->cursor_cntl = cntl; | 9924 | intel_crtc->cursor_cntl = cntl; |
9906 | } | 9925 | } |
9907 | } | 9926 | } |
@@ -11558,18 +11577,32 @@ retry: | |||
11558 | static bool intel_wm_need_update(struct drm_plane *plane, | 11577 | static bool intel_wm_need_update(struct drm_plane *plane, |
11559 | struct drm_plane_state *state) | 11578 | struct drm_plane_state *state) |
11560 | { | 11579 | { |
11561 | /* Update watermarks on tiling changes. */ | 11580 | struct intel_plane_state *new = to_intel_plane_state(state); |
11581 | struct intel_plane_state *cur = to_intel_plane_state(plane->state); | ||
11582 | |||
11583 | /* Update watermarks on tiling or size changes. */ | ||
11562 | if (!plane->state->fb || !state->fb || | 11584 | if (!plane->state->fb || !state->fb || |
11563 | plane->state->fb->modifier[0] != state->fb->modifier[0] || | 11585 | plane->state->fb->modifier[0] != state->fb->modifier[0] || |
11564 | plane->state->rotation != state->rotation) | 11586 | plane->state->rotation != state->rotation || |
11565 | return true; | 11587 | drm_rect_width(&new->src) != drm_rect_width(&cur->src) || |
11566 | 11588 | drm_rect_height(&new->src) != drm_rect_height(&cur->src) || | |
11567 | if (plane->state->crtc_w != state->crtc_w) | 11589 | drm_rect_width(&new->dst) != drm_rect_width(&cur->dst) || |
11590 | drm_rect_height(&new->dst) != drm_rect_height(&cur->dst)) | ||
11568 | return true; | 11591 | return true; |
11569 | 11592 | ||
11570 | return false; | 11593 | return false; |
11571 | } | 11594 | } |
11572 | 11595 | ||
11596 | static bool needs_scaling(struct intel_plane_state *state) | ||
11597 | { | ||
11598 | int src_w = drm_rect_width(&state->src) >> 16; | ||
11599 | int src_h = drm_rect_height(&state->src) >> 16; | ||
11600 | int dst_w = drm_rect_width(&state->dst); | ||
11601 | int dst_h = drm_rect_height(&state->dst); | ||
11602 | |||
11603 | return (src_w != dst_w || src_h != dst_h); | ||
11604 | } | ||
11605 | |||
11573 | int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, | 11606 | int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, |
11574 | struct drm_plane_state *plane_state) | 11607 | struct drm_plane_state *plane_state) |
11575 | { | 11608 | { |
@@ -11585,7 +11618,6 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, | |||
11585 | bool mode_changed = needs_modeset(crtc_state); | 11618 | bool mode_changed = needs_modeset(crtc_state); |
11586 | bool was_crtc_enabled = crtc->state->active; | 11619 | bool was_crtc_enabled = crtc->state->active; |
11587 | bool is_crtc_enabled = crtc_state->active; | 11620 | bool is_crtc_enabled = crtc_state->active; |
11588 | |||
11589 | bool turn_off, turn_on, visible, was_visible; | 11621 | bool turn_off, turn_on, visible, was_visible; |
11590 | struct drm_framebuffer *fb = plane_state->fb; | 11622 | struct drm_framebuffer *fb = plane_state->fb; |
11591 | 11623 | ||
@@ -11703,11 +11735,23 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, | |||
11703 | case DRM_PLANE_TYPE_CURSOR: | 11735 | case DRM_PLANE_TYPE_CURSOR: |
11704 | break; | 11736 | break; |
11705 | case DRM_PLANE_TYPE_OVERLAY: | 11737 | case DRM_PLANE_TYPE_OVERLAY: |
11706 | if (turn_off && !mode_changed) { | 11738 | /* |
11739 | * WaCxSRDisabledForSpriteScaling:ivb | ||
11740 | * | ||
11741 | * cstate->update_wm was already set above, so this flag will | ||
11742 | * take effect when we commit and program watermarks. | ||
11743 | */ | ||
11744 | if (IS_IVYBRIDGE(dev) && | ||
11745 | needs_scaling(to_intel_plane_state(plane_state)) && | ||
11746 | !needs_scaling(old_plane_state)) { | ||
11747 | to_intel_crtc_state(crtc_state)->disable_lp_wm = true; | ||
11748 | } else if (turn_off && !mode_changed) { | ||
11707 | intel_crtc->atomic.wait_vblank = true; | 11749 | intel_crtc->atomic.wait_vblank = true; |
11708 | intel_crtc->atomic.update_sprite_watermarks |= | 11750 | intel_crtc->atomic.update_sprite_watermarks |= |
11709 | 1 << i; | 11751 | 1 << i; |
11710 | } | 11752 | } |
11753 | |||
11754 | break; | ||
11711 | } | 11755 | } |
11712 | return 0; | 11756 | return 0; |
11713 | } | 11757 | } |
@@ -12571,8 +12615,8 @@ static void check_wm_state(struct drm_device *dev) | |||
12571 | } | 12615 | } |
12572 | 12616 | ||
12573 | /* cursor */ | 12617 | /* cursor */ |
12574 | hw_entry = &hw_ddb.cursor[pipe]; | 12618 | hw_entry = &hw_ddb.plane[pipe][PLANE_CURSOR]; |
12575 | sw_entry = &sw_ddb->cursor[pipe]; | 12619 | sw_entry = &sw_ddb->plane[pipe][PLANE_CURSOR]; |
12576 | 12620 | ||
12577 | if (skl_ddb_entry_equal(hw_entry, sw_entry)) | 12621 | if (skl_ddb_entry_equal(hw_entry, sw_entry)) |
12578 | continue; | 12622 | continue; |
@@ -12815,11 +12859,11 @@ static void update_scanline_offset(struct intel_crtc *crtc) | |||
12815 | * one to the value. | 12859 | * one to the value. |
12816 | */ | 12860 | */ |
12817 | if (IS_GEN2(dev)) { | 12861 | if (IS_GEN2(dev)) { |
12818 | const struct drm_display_mode *mode = &crtc->config->base.adjusted_mode; | 12862 | const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; |
12819 | int vtotal; | 12863 | int vtotal; |
12820 | 12864 | ||
12821 | vtotal = mode->crtc_vtotal; | 12865 | vtotal = adjusted_mode->crtc_vtotal; |
12822 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | 12866 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) |
12823 | vtotal /= 2; | 12867 | vtotal /= 2; |
12824 | 12868 | ||
12825 | crtc->scanline_offset = vtotal - 1; | 12869 | crtc->scanline_offset = vtotal - 1; |
@@ -13323,8 +13367,6 @@ static void intel_shared_dpll_init(struct drm_device *dev) | |||
13323 | { | 13367 | { |
13324 | struct drm_i915_private *dev_priv = dev->dev_private; | 13368 | struct drm_i915_private *dev_priv = dev->dev_private; |
13325 | 13369 | ||
13326 | intel_update_cdclk(dev); | ||
13327 | |||
13328 | if (HAS_DDI(dev)) | 13370 | if (HAS_DDI(dev)) |
13329 | intel_ddi_pll_init(dev); | 13371 | intel_ddi_pll_init(dev); |
13330 | else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) | 13372 | else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) |
@@ -13983,7 +14025,7 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
13983 | * On SKL pre-D0 the strap isn't connected, so we assume | 14025 | * On SKL pre-D0 the strap isn't connected, so we assume |
13984 | * it's there. | 14026 | * it's there. |
13985 | */ | 14027 | */ |
13986 | found = I915_READ(DDI_BUF_CTL_A) & DDI_INIT_DISPLAY_DETECTED; | 14028 | found = I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_INIT_DISPLAY_DETECTED; |
13987 | /* WaIgnoreDDIAStrap: skl */ | 14029 | /* WaIgnoreDDIAStrap: skl */ |
13988 | if (found || IS_SKYLAKE(dev)) | 14030 | if (found || IS_SKYLAKE(dev)) |
13989 | intel_ddi_init(dev, PORT_A); | 14031 | intel_ddi_init(dev, PORT_A); |
@@ -14044,29 +14086,26 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
14044 | * eDP ports. Consult the VBT as well as DP_DETECTED to | 14086 | * eDP ports. Consult the VBT as well as DP_DETECTED to |
14045 | * detect eDP ports. | 14087 | * detect eDP ports. |
14046 | */ | 14088 | */ |
14047 | if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIB) & SDVO_DETECTED && | 14089 | if (I915_READ(VLV_HDMIB) & SDVO_DETECTED && |
14048 | !intel_dp_is_edp(dev, PORT_B)) | 14090 | !intel_dp_is_edp(dev, PORT_B)) |
14049 | intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIB, | 14091 | intel_hdmi_init(dev, VLV_HDMIB, PORT_B); |
14050 | PORT_B); | 14092 | if (I915_READ(VLV_DP_B) & DP_DETECTED || |
14051 | if (I915_READ(VLV_DISPLAY_BASE + DP_B) & DP_DETECTED || | ||
14052 | intel_dp_is_edp(dev, PORT_B)) | 14093 | intel_dp_is_edp(dev, PORT_B)) |
14053 | intel_dp_init(dev, VLV_DISPLAY_BASE + DP_B, PORT_B); | 14094 | intel_dp_init(dev, VLV_DP_B, PORT_B); |
14054 | 14095 | ||
14055 | if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIC) & SDVO_DETECTED && | 14096 | if (I915_READ(VLV_HDMIC) & SDVO_DETECTED && |
14056 | !intel_dp_is_edp(dev, PORT_C)) | 14097 | !intel_dp_is_edp(dev, PORT_C)) |
14057 | intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIC, | 14098 | intel_hdmi_init(dev, VLV_HDMIC, PORT_C); |
14058 | PORT_C); | 14099 | if (I915_READ(VLV_DP_C) & DP_DETECTED || |
14059 | if (I915_READ(VLV_DISPLAY_BASE + DP_C) & DP_DETECTED || | ||
14060 | intel_dp_is_edp(dev, PORT_C)) | 14100 | intel_dp_is_edp(dev, PORT_C)) |
14061 | intel_dp_init(dev, VLV_DISPLAY_BASE + DP_C, PORT_C); | 14101 | intel_dp_init(dev, VLV_DP_C, PORT_C); |
14062 | 14102 | ||
14063 | if (IS_CHERRYVIEW(dev)) { | 14103 | if (IS_CHERRYVIEW(dev)) { |
14064 | if (I915_READ(VLV_DISPLAY_BASE + CHV_HDMID) & SDVO_DETECTED) | ||
14065 | intel_hdmi_init(dev, VLV_DISPLAY_BASE + CHV_HDMID, | ||
14066 | PORT_D); | ||
14067 | /* eDP not supported on port D, so don't check VBT */ | 14104 | /* eDP not supported on port D, so don't check VBT */ |
14068 | if (I915_READ(VLV_DISPLAY_BASE + DP_D) & DP_DETECTED) | 14105 | if (I915_READ(CHV_HDMID) & SDVO_DETECTED) |
14069 | intel_dp_init(dev, VLV_DISPLAY_BASE + DP_D, PORT_D); | 14106 | intel_hdmi_init(dev, CHV_HDMID, PORT_D); |
14107 | if (I915_READ(CHV_DP_D) & DP_DETECTED) | ||
14108 | intel_dp_init(dev, CHV_DP_D, PORT_D); | ||
14070 | } | 14109 | } |
14071 | 14110 | ||
14072 | intel_dsi_init(dev); | 14111 | intel_dsi_init(dev); |
@@ -14557,8 +14596,6 @@ static void intel_init_display(struct drm_device *dev) | |||
14557 | dev_priv->display.queue_flip = intel_default_queue_flip; | 14596 | dev_priv->display.queue_flip = intel_default_queue_flip; |
14558 | } | 14597 | } |
14559 | 14598 | ||
14560 | intel_panel_init_backlight_funcs(dev); | ||
14561 | |||
14562 | mutex_init(&dev_priv->pps_mutex); | 14599 | mutex_init(&dev_priv->pps_mutex); |
14563 | } | 14600 | } |
14564 | 14601 | ||
@@ -14836,6 +14873,9 @@ void intel_modeset_init(struct drm_device *dev) | |||
14836 | } | 14873 | } |
14837 | } | 14874 | } |
14838 | 14875 | ||
14876 | intel_update_czclk(dev_priv); | ||
14877 | intel_update_cdclk(dev); | ||
14878 | |||
14839 | intel_shared_dpll_init(dev); | 14879 | intel_shared_dpll_init(dev); |
14840 | 14880 | ||
14841 | /* Just disable it once at startup */ | 14881 | /* Just disable it once at startup */ |
@@ -15124,11 +15164,15 @@ static bool primary_get_hw_state(struct intel_plane *plane) | |||
15124 | /* FIXME read out full plane state for all planes */ | 15164 | /* FIXME read out full plane state for all planes */ |
15125 | static void readout_plane_state(struct intel_crtc *crtc) | 15165 | static void readout_plane_state(struct intel_crtc *crtc) |
15126 | { | 15166 | { |
15167 | struct drm_plane *primary = crtc->base.primary; | ||
15127 | struct intel_plane_state *plane_state = | 15168 | struct intel_plane_state *plane_state = |
15128 | to_intel_plane_state(crtc->base.primary->state); | 15169 | to_intel_plane_state(primary->state); |
15129 | 15170 | ||
15130 | plane_state->visible = | 15171 | plane_state->visible = |
15131 | primary_get_hw_state(to_intel_plane(crtc->base.primary)); | 15172 | primary_get_hw_state(to_intel_plane(primary)); |
15173 | |||
15174 | if (plane_state->visible) | ||
15175 | crtc->base.state->plane_mask |= 1 << drm_plane_index(primary); | ||
15132 | } | 15176 | } |
15133 | 15177 | ||
15134 | static void intel_modeset_readout_hw_state(struct drm_device *dev) | 15178 | static void intel_modeset_readout_hw_state(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 06a2b1046daf..18bcfbe0b8ba 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1587,7 +1587,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder) | |||
1587 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 1587 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
1588 | enum port port = dp_to_dig_port(intel_dp)->port; | 1588 | enum port port = dp_to_dig_port(intel_dp)->port; |
1589 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); | 1589 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); |
1590 | struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; | 1590 | const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; |
1591 | 1591 | ||
1592 | intel_dp_set_link_params(intel_dp, crtc->config); | 1592 | intel_dp_set_link_params(intel_dp, crtc->config); |
1593 | 1593 | ||
@@ -2604,7 +2604,6 @@ static void intel_enable_dp(struct intel_encoder *encoder) | |||
2604 | 2604 | ||
2605 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); | 2605 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
2606 | intel_dp_start_link_train(intel_dp); | 2606 | intel_dp_start_link_train(intel_dp); |
2607 | intel_dp_complete_link_train(intel_dp); | ||
2608 | intel_dp_stop_link_train(intel_dp); | 2607 | intel_dp_stop_link_train(intel_dp); |
2609 | 2608 | ||
2610 | if (crtc->config->has_audio) { | 2609 | if (crtc->config->has_audio) { |
@@ -3417,11 +3416,6 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp) | |||
3417 | vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val); | 3416 | vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val); |
3418 | } | 3417 | } |
3419 | 3418 | ||
3420 | /* LRC Bypass */ | ||
3421 | val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW30); | ||
3422 | val |= DPIO_LRC_BYPASS; | ||
3423 | vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW30, val); | ||
3424 | |||
3425 | mutex_unlock(&dev_priv->sb_lock); | 3419 | mutex_unlock(&dev_priv->sb_lock); |
3426 | 3420 | ||
3427 | return 0; | 3421 | return 0; |
@@ -3696,8 +3690,8 @@ static void intel_dp_set_idle_link_train(struct intel_dp *intel_dp) | |||
3696 | } | 3690 | } |
3697 | 3691 | ||
3698 | /* Enable corresponding port and start training pattern 1 */ | 3692 | /* Enable corresponding port and start training pattern 1 */ |
3699 | void | 3693 | static void |
3700 | intel_dp_start_link_train(struct intel_dp *intel_dp) | 3694 | intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) |
3701 | { | 3695 | { |
3702 | struct drm_encoder *encoder = &dp_to_dig_port(intel_dp)->base.base; | 3696 | struct drm_encoder *encoder = &dp_to_dig_port(intel_dp)->base.base; |
3703 | struct drm_device *dev = encoder->dev; | 3697 | struct drm_device *dev = encoder->dev; |
@@ -3810,8 +3804,8 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
3810 | intel_dp->DP = DP; | 3804 | intel_dp->DP = DP; |
3811 | } | 3805 | } |
3812 | 3806 | ||
3813 | void | 3807 | static void |
3814 | intel_dp_complete_link_train(struct intel_dp *intel_dp) | 3808 | intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) |
3815 | { | 3809 | { |
3816 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | 3810 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
3817 | struct drm_device *dev = dig_port->base.base.dev; | 3811 | struct drm_device *dev = dig_port->base.base.dev; |
@@ -3864,7 +3858,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
3864 | if (!drm_dp_clock_recovery_ok(link_status, | 3858 | if (!drm_dp_clock_recovery_ok(link_status, |
3865 | intel_dp->lane_count)) { | 3859 | intel_dp->lane_count)) { |
3866 | intel_dp->train_set_valid = false; | 3860 | intel_dp->train_set_valid = false; |
3867 | intel_dp_start_link_train(intel_dp); | 3861 | intel_dp_link_training_clock_recovery(intel_dp); |
3868 | intel_dp_set_link_train(intel_dp, &DP, | 3862 | intel_dp_set_link_train(intel_dp, &DP, |
3869 | training_pattern | | 3863 | training_pattern | |
3870 | DP_LINK_SCRAMBLING_DISABLE); | 3864 | DP_LINK_SCRAMBLING_DISABLE); |
@@ -3881,7 +3875,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
3881 | /* Try 5 times, then try clock recovery if that fails */ | 3875 | /* Try 5 times, then try clock recovery if that fails */ |
3882 | if (tries > 5) { | 3876 | if (tries > 5) { |
3883 | intel_dp->train_set_valid = false; | 3877 | intel_dp->train_set_valid = false; |
3884 | intel_dp_start_link_train(intel_dp); | 3878 | intel_dp_link_training_clock_recovery(intel_dp); |
3885 | intel_dp_set_link_train(intel_dp, &DP, | 3879 | intel_dp_set_link_train(intel_dp, &DP, |
3886 | training_pattern | | 3880 | training_pattern | |
3887 | DP_LINK_SCRAMBLING_DISABLE); | 3881 | DP_LINK_SCRAMBLING_DISABLE); |
@@ -3914,6 +3908,13 @@ void intel_dp_stop_link_train(struct intel_dp *intel_dp) | |||
3914 | DP_TRAINING_PATTERN_DISABLE); | 3908 | DP_TRAINING_PATTERN_DISABLE); |
3915 | } | 3909 | } |
3916 | 3910 | ||
3911 | void | ||
3912 | intel_dp_start_link_train(struct intel_dp *intel_dp) | ||
3913 | { | ||
3914 | intel_dp_link_training_clock_recovery(intel_dp); | ||
3915 | intel_dp_link_training_channel_equalization(intel_dp); | ||
3916 | } | ||
3917 | |||
3917 | static void | 3918 | static void |
3918 | intel_dp_link_down(struct intel_dp *intel_dp) | 3919 | intel_dp_link_down(struct intel_dp *intel_dp) |
3919 | { | 3920 | { |
@@ -4382,7 +4383,6 @@ go_again: | |||
4382 | !drm_dp_channel_eq_ok(&esi[10], intel_dp->lane_count)) { | 4383 | !drm_dp_channel_eq_ok(&esi[10], intel_dp->lane_count)) { |
4383 | DRM_DEBUG_KMS("channel EQ not ok, retraining\n"); | 4384 | DRM_DEBUG_KMS("channel EQ not ok, retraining\n"); |
4384 | intel_dp_start_link_train(intel_dp); | 4385 | intel_dp_start_link_train(intel_dp); |
4385 | intel_dp_complete_link_train(intel_dp); | ||
4386 | intel_dp_stop_link_train(intel_dp); | 4386 | intel_dp_stop_link_train(intel_dp); |
4387 | } | 4387 | } |
4388 | 4388 | ||
@@ -4473,7 +4473,6 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
4473 | DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", | 4473 | DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", |
4474 | intel_encoder->base.name); | 4474 | intel_encoder->base.name); |
4475 | intel_dp_start_link_train(intel_dp); | 4475 | intel_dp_start_link_train(intel_dp); |
4476 | intel_dp_complete_link_train(intel_dp); | ||
4477 | intel_dp_stop_link_train(intel_dp); | 4476 | intel_dp_stop_link_train(intel_dp); |
4478 | } | 4477 | } |
4479 | } | 4478 | } |
@@ -6000,7 +5999,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, | |||
6000 | } | 5999 | } |
6001 | 6000 | ||
6002 | intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); | 6001 | intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); |
6003 | intel_connector->panel.backlight_power = intel_edp_backlight_power; | 6002 | intel_connector->panel.backlight.power = intel_edp_backlight_power; |
6004 | intel_panel_setup_backlight(connector, pipe); | 6003 | intel_panel_setup_backlight(connector, pipe); |
6005 | 6004 | ||
6006 | return true; | 6005 | return true; |
@@ -6169,10 +6168,8 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) | |||
6169 | return; | 6168 | return; |
6170 | 6169 | ||
6171 | intel_connector = intel_connector_alloc(); | 6170 | intel_connector = intel_connector_alloc(); |
6172 | if (!intel_connector) { | 6171 | if (!intel_connector) |
6173 | kfree(intel_dig_port); | 6172 | goto err_connector_alloc; |
6174 | return; | ||
6175 | } | ||
6176 | 6173 | ||
6177 | intel_encoder = &intel_dig_port->base; | 6174 | intel_encoder = &intel_dig_port->base; |
6178 | encoder = &intel_encoder->base; | 6175 | encoder = &intel_encoder->base; |
@@ -6220,11 +6217,18 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) | |||
6220 | intel_dig_port->hpd_pulse = intel_dp_hpd_pulse; | 6217 | intel_dig_port->hpd_pulse = intel_dp_hpd_pulse; |
6221 | dev_priv->hotplug.irq_port[port] = intel_dig_port; | 6218 | dev_priv->hotplug.irq_port[port] = intel_dig_port; |
6222 | 6219 | ||
6223 | if (!intel_dp_init_connector(intel_dig_port, intel_connector)) { | 6220 | if (!intel_dp_init_connector(intel_dig_port, intel_connector)) |
6224 | drm_encoder_cleanup(encoder); | 6221 | goto err_init_connector; |
6225 | kfree(intel_dig_port); | 6222 | |
6226 | kfree(intel_connector); | 6223 | return; |
6227 | } | 6224 | |
6225 | err_init_connector: | ||
6226 | drm_encoder_cleanup(encoder); | ||
6227 | kfree(intel_connector); | ||
6228 | err_connector_alloc: | ||
6229 | kfree(intel_dig_port); | ||
6230 | |||
6231 | return; | ||
6228 | } | 6232 | } |
6229 | 6233 | ||
6230 | void intel_dp_mst_suspend(struct drm_device *dev) | 6234 | void intel_dp_mst_suspend(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 7ada76c5ecc5..0639275fc471 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c | |||
@@ -40,7 +40,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, | |||
40 | struct drm_atomic_state *state; | 40 | struct drm_atomic_state *state; |
41 | int bpp, i; | 41 | int bpp, i; |
42 | int lane_count, slots; | 42 | int lane_count, slots; |
43 | struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; | 43 | const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; |
44 | struct drm_connector *drm_connector; | 44 | struct drm_connector *drm_connector; |
45 | struct intel_connector *connector, *found = NULL; | 45 | struct intel_connector *connector, *found = NULL; |
46 | struct drm_connector_state *connector_state; | 46 | struct drm_connector_state *connector_state; |
@@ -78,7 +78,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, | |||
78 | return false; | 78 | return false; |
79 | } | 79 | } |
80 | 80 | ||
81 | mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->clock, bpp); | 81 | mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp); |
82 | 82 | ||
83 | pipe_config->pbn = mst_pbn; | 83 | pipe_config->pbn = mst_pbn; |
84 | slots = drm_dp_find_vcpi_slots(&intel_dp->mst_mgr, mst_pbn); | 84 | slots = drm_dp_find_vcpi_slots(&intel_dp->mst_mgr, mst_pbn); |
@@ -188,7 +188,6 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder) | |||
188 | 188 | ||
189 | 189 | ||
190 | intel_dp_start_link_train(intel_dp); | 190 | intel_dp_start_link_train(intel_dp); |
191 | intel_dp_complete_link_train(intel_dp); | ||
192 | intel_dp_stop_link_train(intel_dp); | 191 | intel_dp_stop_link_train(intel_dp); |
193 | } | 192 | } |
194 | 193 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index c96289dba380..91b6b4060333 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -179,12 +179,22 @@ struct intel_panel { | |||
179 | bool active_low_pwm; | 179 | bool active_low_pwm; |
180 | 180 | ||
181 | /* PWM chip */ | 181 | /* PWM chip */ |
182 | bool util_pin_active_low; /* bxt+ */ | ||
183 | u8 controller; /* bxt+ only */ | ||
182 | struct pwm_device *pwm; | 184 | struct pwm_device *pwm; |
183 | 185 | ||
184 | struct backlight_device *device; | 186 | struct backlight_device *device; |
185 | } backlight; | ||
186 | 187 | ||
187 | void (*backlight_power)(struct intel_connector *, bool enable); | 188 | /* Connector and platform specific backlight functions */ |
189 | int (*setup)(struct intel_connector *connector, enum pipe pipe); | ||
190 | uint32_t (*get)(struct intel_connector *connector); | ||
191 | void (*set)(struct intel_connector *connector, uint32_t level); | ||
192 | void (*disable)(struct intel_connector *connector); | ||
193 | void (*enable)(struct intel_connector *connector); | ||
194 | uint32_t (*hz_to_pwm)(struct intel_connector *connector, | ||
195 | uint32_t hz); | ||
196 | void (*power)(struct intel_connector *, bool enable); | ||
197 | } backlight; | ||
188 | }; | 198 | }; |
189 | 199 | ||
190 | struct intel_connector { | 200 | struct intel_connector { |
@@ -458,6 +468,9 @@ struct intel_crtc_state { | |||
458 | 468 | ||
459 | /* w/a for waiting 2 vblanks during crtc enable */ | 469 | /* w/a for waiting 2 vblanks during crtc enable */ |
460 | enum pipe hsw_workaround_pipe; | 470 | enum pipe hsw_workaround_pipe; |
471 | |||
472 | /* IVB sprite scaling w/a (WaCxSRDisabledForSpriteScaling:ivb) */ | ||
473 | bool disable_lp_wm; | ||
461 | }; | 474 | }; |
462 | 475 | ||
463 | struct vlv_wm_state { | 476 | struct vlv_wm_state { |
@@ -683,7 +696,7 @@ struct intel_hdmi { | |||
683 | const void *frame, ssize_t len); | 696 | const void *frame, ssize_t len); |
684 | void (*set_infoframes)(struct drm_encoder *encoder, | 697 | void (*set_infoframes)(struct drm_encoder *encoder, |
685 | bool enable, | 698 | bool enable, |
686 | struct drm_display_mode *adjusted_mode); | 699 | const struct drm_display_mode *adjusted_mode); |
687 | bool (*infoframe_enabled)(struct drm_encoder *encoder); | 700 | bool (*infoframe_enabled)(struct drm_encoder *encoder); |
688 | }; | 701 | }; |
689 | 702 | ||
@@ -1191,7 +1204,6 @@ bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port, | |||
1191 | void intel_dp_set_link_params(struct intel_dp *intel_dp, | 1204 | void intel_dp_set_link_params(struct intel_dp *intel_dp, |
1192 | const struct intel_crtc_state *pipe_config); | 1205 | const struct intel_crtc_state *pipe_config); |
1193 | void intel_dp_start_link_train(struct intel_dp *intel_dp); | 1206 | void intel_dp_start_link_train(struct intel_dp *intel_dp); |
1194 | void intel_dp_complete_link_train(struct intel_dp *intel_dp); | ||
1195 | void intel_dp_stop_link_train(struct intel_dp *intel_dp); | 1207 | void intel_dp_stop_link_train(struct intel_dp *intel_dp); |
1196 | void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode); | 1208 | void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode); |
1197 | void intel_dp_encoder_destroy(struct drm_encoder *encoder); | 1209 | void intel_dp_encoder_destroy(struct drm_encoder *encoder); |
@@ -1300,6 +1312,7 @@ int intel_connector_update_modes(struct drm_connector *connector, | |||
1300 | int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); | 1312 | int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); |
1301 | void intel_attach_force_audio_property(struct drm_connector *connector); | 1313 | void intel_attach_force_audio_property(struct drm_connector *connector); |
1302 | void intel_attach_broadcast_rgb_property(struct drm_connector *connector); | 1314 | void intel_attach_broadcast_rgb_property(struct drm_connector *connector); |
1315 | void intel_attach_aspect_ratio_property(struct drm_connector *connector); | ||
1303 | 1316 | ||
1304 | 1317 | ||
1305 | /* intel_overlay.c */ | 1318 | /* intel_overlay.c */ |
@@ -1332,7 +1345,6 @@ int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe) | |||
1332 | void intel_panel_enable_backlight(struct intel_connector *connector); | 1345 | void intel_panel_enable_backlight(struct intel_connector *connector); |
1333 | void intel_panel_disable_backlight(struct intel_connector *connector); | 1346 | void intel_panel_disable_backlight(struct intel_connector *connector); |
1334 | void intel_panel_destroy_backlight(struct drm_connector *connector); | 1347 | void intel_panel_destroy_backlight(struct drm_connector *connector); |
1335 | void intel_panel_init_backlight_funcs(struct drm_device *dev); | ||
1336 | enum drm_connector_status intel_panel_detect(struct drm_device *dev); | 1348 | enum drm_connector_status intel_panel_detect(struct drm_device *dev); |
1337 | extern struct drm_display_mode *intel_find_panel_downclock( | 1349 | extern struct drm_display_mode *intel_find_panel_downclock( |
1338 | struct drm_device *dev, | 1350 | struct drm_device *dev, |
@@ -1387,12 +1399,6 @@ void intel_init_clock_gating(struct drm_device *dev); | |||
1387 | void intel_suspend_hw(struct drm_device *dev); | 1399 | void intel_suspend_hw(struct drm_device *dev); |
1388 | int ilk_wm_max_level(const struct drm_device *dev); | 1400 | int ilk_wm_max_level(const struct drm_device *dev); |
1389 | void intel_update_watermarks(struct drm_crtc *crtc); | 1401 | void intel_update_watermarks(struct drm_crtc *crtc); |
1390 | void intel_update_sprite_watermarks(struct drm_plane *plane, | ||
1391 | struct drm_crtc *crtc, | ||
1392 | uint32_t sprite_width, | ||
1393 | uint32_t sprite_height, | ||
1394 | int pixel_size, | ||
1395 | bool enabled, bool scaled); | ||
1396 | void intel_init_pm(struct drm_device *dev); | 1402 | void intel_init_pm(struct drm_device *dev); |
1397 | void intel_pm_setup(struct drm_device *dev); | 1403 | void intel_pm_setup(struct drm_device *dev); |
1398 | void intel_gpu_ips_init(struct drm_i915_private *dev_priv); | 1404 | void intel_gpu_ips_init(struct drm_i915_private *dev_priv); |
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 61d69c214508..170ae6f4866e 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c | |||
@@ -282,58 +282,46 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder, | |||
282 | return true; | 282 | return true; |
283 | } | 283 | } |
284 | 284 | ||
285 | static void intel_dsi_port_enable(struct intel_encoder *encoder) | 285 | static void bxt_dsi_device_ready(struct intel_encoder *encoder) |
286 | { | 286 | { |
287 | struct drm_device *dev = encoder->base.dev; | 287 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
288 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
289 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); | ||
290 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); | 288 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); |
291 | enum port port; | 289 | enum port port; |
292 | u32 temp; | 290 | u32 val; |
293 | 291 | ||
294 | if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) { | 292 | DRM_DEBUG_KMS("\n"); |
295 | temp = I915_READ(VLV_CHICKEN_3); | ||
296 | temp &= ~PIXEL_OVERLAP_CNT_MASK | | ||
297 | intel_dsi->pixel_overlap << | ||
298 | PIXEL_OVERLAP_CNT_SHIFT; | ||
299 | I915_WRITE(VLV_CHICKEN_3, temp); | ||
300 | } | ||
301 | 293 | ||
294 | /* Exit Low power state in 4 steps*/ | ||
302 | for_each_dsi_port(port, intel_dsi->ports) { | 295 | for_each_dsi_port(port, intel_dsi->ports) { |
303 | temp = I915_READ(MIPI_PORT_CTRL(port)); | ||
304 | temp &= ~LANE_CONFIGURATION_MASK; | ||
305 | temp &= ~DUAL_LINK_MODE_MASK; | ||
306 | 296 | ||
307 | if (intel_dsi->ports == ((1 << PORT_A) | (1 << PORT_C))) { | 297 | /* 1. Enable MIPI PHY transparent latch */ |
308 | temp |= (intel_dsi->dual_link - 1) | 298 | val = I915_READ(BXT_MIPI_PORT_CTRL(port)); |
309 | << DUAL_LINK_MODE_SHIFT; | 299 | I915_WRITE(BXT_MIPI_PORT_CTRL(port), val | LP_OUTPUT_HOLD); |
310 | temp |= intel_crtc->pipe ? | 300 | usleep_range(2000, 2500); |
311 | LANE_CONFIGURATION_DUAL_LINK_B : | ||
312 | LANE_CONFIGURATION_DUAL_LINK_A; | ||
313 | } | ||
314 | /* assert ip_tg_enable signal */ | ||
315 | I915_WRITE(MIPI_PORT_CTRL(port), temp | DPI_ENABLE); | ||
316 | POSTING_READ(MIPI_PORT_CTRL(port)); | ||
317 | } | ||
318 | } | ||
319 | 301 | ||
320 | static void intel_dsi_port_disable(struct intel_encoder *encoder) | 302 | /* 2. Enter ULPS */ |
321 | { | 303 | val = I915_READ(MIPI_DEVICE_READY(port)); |
322 | struct drm_device *dev = encoder->base.dev; | 304 | val &= ~ULPS_STATE_MASK; |
323 | struct drm_i915_private *dev_priv = dev->dev_private; | 305 | val |= (ULPS_STATE_ENTER | DEVICE_READY); |
324 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); | 306 | I915_WRITE(MIPI_DEVICE_READY(port), val); |
325 | enum port port; | 307 | usleep_range(2, 3); |
326 | u32 temp; | 308 | |
309 | /* 3. Exit ULPS */ | ||
310 | val = I915_READ(MIPI_DEVICE_READY(port)); | ||
311 | val &= ~ULPS_STATE_MASK; | ||
312 | val |= (ULPS_STATE_EXIT | DEVICE_READY); | ||
313 | I915_WRITE(MIPI_DEVICE_READY(port), val); | ||
314 | usleep_range(1000, 1500); | ||
327 | 315 | ||
328 | for_each_dsi_port(port, intel_dsi->ports) { | 316 | /* Clear ULPS and set device ready */ |
329 | /* de-assert ip_tg_enable signal */ | 317 | val = I915_READ(MIPI_DEVICE_READY(port)); |
330 | temp = I915_READ(MIPI_PORT_CTRL(port)); | 318 | val &= ~ULPS_STATE_MASK; |
331 | I915_WRITE(MIPI_PORT_CTRL(port), temp & ~DPI_ENABLE); | 319 | val |= DEVICE_READY; |
332 | POSTING_READ(MIPI_PORT_CTRL(port)); | 320 | I915_WRITE(MIPI_DEVICE_READY(port), val); |
333 | } | 321 | } |
334 | } | 322 | } |
335 | 323 | ||
336 | static void intel_dsi_device_ready(struct intel_encoder *encoder) | 324 | static void vlv_dsi_device_ready(struct intel_encoder *encoder) |
337 | { | 325 | { |
338 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; | 326 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
339 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); | 327 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); |
@@ -372,6 +360,75 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder) | |||
372 | } | 360 | } |
373 | } | 361 | } |
374 | 362 | ||
363 | static void intel_dsi_device_ready(struct intel_encoder *encoder) | ||
364 | { | ||
365 | struct drm_device *dev = encoder->base.dev; | ||
366 | |||
367 | if (IS_VALLEYVIEW(dev)) | ||
368 | vlv_dsi_device_ready(encoder); | ||
369 | else if (IS_BROXTON(dev)) | ||
370 | bxt_dsi_device_ready(encoder); | ||
371 | } | ||
372 | |||
373 | static void intel_dsi_port_enable(struct intel_encoder *encoder) | ||
374 | { | ||
375 | struct drm_device *dev = encoder->base.dev; | ||
376 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
377 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); | ||
378 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); | ||
379 | enum port port; | ||
380 | u32 temp; | ||
381 | u32 port_ctrl; | ||
382 | |||
383 | if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) { | ||
384 | temp = I915_READ(VLV_CHICKEN_3); | ||
385 | temp &= ~PIXEL_OVERLAP_CNT_MASK | | ||
386 | intel_dsi->pixel_overlap << | ||
387 | PIXEL_OVERLAP_CNT_SHIFT; | ||
388 | I915_WRITE(VLV_CHICKEN_3, temp); | ||
389 | } | ||
390 | |||
391 | for_each_dsi_port(port, intel_dsi->ports) { | ||
392 | port_ctrl = IS_BROXTON(dev) ? BXT_MIPI_PORT_CTRL(port) : | ||
393 | MIPI_PORT_CTRL(port); | ||
394 | |||
395 | temp = I915_READ(port_ctrl); | ||
396 | |||
397 | temp &= ~LANE_CONFIGURATION_MASK; | ||
398 | temp &= ~DUAL_LINK_MODE_MASK; | ||
399 | |||
400 | if (intel_dsi->ports == ((1 << PORT_A) | (1 << PORT_C))) { | ||
401 | temp |= (intel_dsi->dual_link - 1) | ||
402 | << DUAL_LINK_MODE_SHIFT; | ||
403 | temp |= intel_crtc->pipe ? | ||
404 | LANE_CONFIGURATION_DUAL_LINK_B : | ||
405 | LANE_CONFIGURATION_DUAL_LINK_A; | ||
406 | } | ||
407 | /* assert ip_tg_enable signal */ | ||
408 | I915_WRITE(port_ctrl, temp | DPI_ENABLE); | ||
409 | POSTING_READ(port_ctrl); | ||
410 | } | ||
411 | } | ||
412 | |||
413 | static void intel_dsi_port_disable(struct intel_encoder *encoder) | ||
414 | { | ||
415 | struct drm_device *dev = encoder->base.dev; | ||
416 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
417 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); | ||
418 | enum port port; | ||
419 | u32 temp; | ||
420 | u32 port_ctrl; | ||
421 | |||
422 | for_each_dsi_port(port, intel_dsi->ports) { | ||
423 | /* de-assert ip_tg_enable signal */ | ||
424 | port_ctrl = IS_BROXTON(dev) ? BXT_MIPI_PORT_CTRL(port) : | ||
425 | MIPI_PORT_CTRL(port); | ||
426 | temp = I915_READ(port_ctrl); | ||
427 | I915_WRITE(port_ctrl, temp & ~DPI_ENABLE); | ||
428 | POSTING_READ(port_ctrl); | ||
429 | } | ||
430 | } | ||
431 | |||
375 | static void intel_dsi_enable(struct intel_encoder *encoder) | 432 | static void intel_dsi_enable(struct intel_encoder *encoder) |
376 | { | 433 | { |
377 | struct drm_device *dev = encoder->base.dev; | 434 | struct drm_device *dev = encoder->base.dev; |
@@ -419,19 +476,24 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder) | |||
419 | 476 | ||
420 | msleep(intel_dsi->panel_on_delay); | 477 | msleep(intel_dsi->panel_on_delay); |
421 | 478 | ||
422 | /* Disable DPOunit clock gating, can stall pipe | 479 | if (IS_VALLEYVIEW(dev)) { |
423 | * and we need DPLL REFA always enabled */ | 480 | /* |
424 | tmp = I915_READ(DPLL(pipe)); | 481 | * Disable DPOunit clock gating, can stall pipe |
425 | tmp |= DPLL_REF_CLK_ENABLE_VLV; | 482 | * and we need DPLL REFA always enabled |
426 | I915_WRITE(DPLL(pipe), tmp); | 483 | */ |
427 | 484 | tmp = I915_READ(DPLL(pipe)); | |
428 | /* update the hw state for DPLL */ | 485 | tmp |= DPLL_REF_CLK_ENABLE_VLV; |
429 | intel_crtc->config->dpll_hw_state.dpll = DPLL_INTEGRATED_REF_CLK_VLV | | 486 | I915_WRITE(DPLL(pipe), tmp); |
430 | DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS; | 487 | |
431 | 488 | /* update the hw state for DPLL */ | |
432 | tmp = I915_READ(DSPCLK_GATE_D); | 489 | intel_crtc->config->dpll_hw_state.dpll = |
433 | tmp |= DPOUNIT_CLOCK_GATE_DISABLE; | 490 | DPLL_INTEGRATED_REF_CLK_VLV | |
434 | I915_WRITE(DSPCLK_GATE_D, tmp); | 491 | DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS; |
492 | |||
493 | tmp = I915_READ(DSPCLK_GATE_D); | ||
494 | tmp |= DPOUNIT_CLOCK_GATE_DISABLE; | ||
495 | I915_WRITE(DSPCLK_GATE_D, tmp); | ||
496 | } | ||
435 | 497 | ||
436 | /* put device in ready state */ | 498 | /* put device in ready state */ |
437 | intel_dsi_device_ready(encoder); | 499 | intel_dsi_device_ready(encoder); |
@@ -495,12 +557,7 @@ static void intel_dsi_disable(struct intel_encoder *encoder) | |||
495 | /* Panel commands can be sent when clock is in LP11 */ | 557 | /* Panel commands can be sent when clock is in LP11 */ |
496 | I915_WRITE(MIPI_DEVICE_READY(port), 0x0); | 558 | I915_WRITE(MIPI_DEVICE_READY(port), 0x0); |
497 | 559 | ||
498 | temp = I915_READ(MIPI_CTRL(port)); | 560 | intel_dsi_reset_clocks(encoder, port); |
499 | temp &= ~ESCAPE_CLOCK_DIVIDER_MASK; | ||
500 | I915_WRITE(MIPI_CTRL(port), temp | | ||
501 | intel_dsi->escape_clk_div << | ||
502 | ESCAPE_CLOCK_DIVIDER_SHIFT); | ||
503 | |||
504 | I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP); | 561 | I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP); |
505 | 562 | ||
506 | temp = I915_READ(MIPI_DSI_FUNC_PRG(port)); | 563 | temp = I915_READ(MIPI_DSI_FUNC_PRG(port)); |
@@ -519,10 +576,12 @@ static void intel_dsi_disable(struct intel_encoder *encoder) | |||
519 | 576 | ||
520 | static void intel_dsi_clear_device_ready(struct intel_encoder *encoder) | 577 | static void intel_dsi_clear_device_ready(struct intel_encoder *encoder) |
521 | { | 578 | { |
579 | struct drm_device *dev = encoder->base.dev; | ||
522 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; | 580 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
523 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); | 581 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); |
524 | enum port port; | 582 | enum port port; |
525 | u32 val; | 583 | u32 val; |
584 | u32 port_ctrl = 0; | ||
526 | 585 | ||
527 | DRM_DEBUG_KMS("\n"); | 586 | DRM_DEBUG_KMS("\n"); |
528 | for_each_dsi_port(port, intel_dsi->ports) { | 587 | for_each_dsi_port(port, intel_dsi->ports) { |
@@ -539,18 +598,22 @@ static void intel_dsi_clear_device_ready(struct intel_encoder *encoder) | |||
539 | ULPS_STATE_ENTER); | 598 | ULPS_STATE_ENTER); |
540 | usleep_range(2000, 2500); | 599 | usleep_range(2000, 2500); |
541 | 600 | ||
601 | if (IS_BROXTON(dev)) | ||
602 | port_ctrl = BXT_MIPI_PORT_CTRL(port); | ||
603 | else if (IS_VALLEYVIEW(dev)) | ||
604 | /* Common bit for both MIPI Port A & MIPI Port C */ | ||
605 | port_ctrl = MIPI_PORT_CTRL(PORT_A); | ||
606 | |||
542 | /* Wait till Clock lanes are in LP-00 state for MIPI Port A | 607 | /* Wait till Clock lanes are in LP-00 state for MIPI Port A |
543 | * only. MIPI Port C has no similar bit for checking | 608 | * only. MIPI Port C has no similar bit for checking |
544 | */ | 609 | */ |
545 | if (wait_for(((I915_READ(MIPI_PORT_CTRL(PORT_A)) & AFE_LATCHOUT) | 610 | if (wait_for(((I915_READ(port_ctrl) & AFE_LATCHOUT) |
546 | == 0x00000), 30)) | 611 | == 0x00000), 30)) |
547 | DRM_ERROR("DSI LP not going Low\n"); | 612 | DRM_ERROR("DSI LP not going Low\n"); |
548 | 613 | ||
549 | /* Disable MIPI PHY transparent latch | 614 | /* Disable MIPI PHY transparent latch */ |
550 | * Common bit for both MIPI Port A & MIPI Port C | 615 | val = I915_READ(port_ctrl); |
551 | */ | 616 | I915_WRITE(port_ctrl, val & ~LP_OUTPUT_HOLD); |
552 | val = I915_READ(MIPI_PORT_CTRL(PORT_A)); | ||
553 | I915_WRITE(MIPI_PORT_CTRL(PORT_A), val & ~LP_OUTPUT_HOLD); | ||
554 | usleep_range(1000, 1500); | 617 | usleep_range(1000, 1500); |
555 | 618 | ||
556 | I915_WRITE(MIPI_DEVICE_READY(port), 0x00); | 619 | I915_WRITE(MIPI_DEVICE_READY(port), 0x00); |
@@ -593,7 +656,7 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, | |||
593 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); | 656 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); |
594 | struct drm_device *dev = encoder->base.dev; | 657 | struct drm_device *dev = encoder->base.dev; |
595 | enum intel_display_power_domain power_domain; | 658 | enum intel_display_power_domain power_domain; |
596 | u32 dpi_enabled, func; | 659 | u32 dpi_enabled, func, ctrl_reg; |
597 | enum port port; | 660 | enum port port; |
598 | 661 | ||
599 | DRM_DEBUG_KMS("\n"); | 662 | DRM_DEBUG_KMS("\n"); |
@@ -605,8 +668,9 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, | |||
605 | /* XXX: this only works for one DSI output */ | 668 | /* XXX: this only works for one DSI output */ |
606 | for_each_dsi_port(port, intel_dsi->ports) { | 669 | for_each_dsi_port(port, intel_dsi->ports) { |
607 | func = I915_READ(MIPI_DSI_FUNC_PRG(port)); | 670 | func = I915_READ(MIPI_DSI_FUNC_PRG(port)); |
608 | dpi_enabled = I915_READ(MIPI_PORT_CTRL(port)) & | 671 | ctrl_reg = IS_BROXTON(dev) ? BXT_MIPI_PORT_CTRL(port) : |
609 | DPI_ENABLE; | 672 | MIPI_PORT_CTRL(port); |
673 | dpi_enabled = I915_READ(ctrl_reg) & DPI_ENABLE; | ||
610 | 674 | ||
611 | /* Due to some hardware limitations on BYT, MIPI Port C DPI | 675 | /* Due to some hardware limitations on BYT, MIPI Port C DPI |
612 | * Enable bit does not get set. To check whether DSI Port C | 676 | * Enable bit does not get set. To check whether DSI Port C |
@@ -631,7 +695,7 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, | |||
631 | static void intel_dsi_get_config(struct intel_encoder *encoder, | 695 | static void intel_dsi_get_config(struct intel_encoder *encoder, |
632 | struct intel_crtc_state *pipe_config) | 696 | struct intel_crtc_state *pipe_config) |
633 | { | 697 | { |
634 | u32 pclk; | 698 | u32 pclk = 0; |
635 | DRM_DEBUG_KMS("\n"); | 699 | DRM_DEBUG_KMS("\n"); |
636 | 700 | ||
637 | /* | 701 | /* |
@@ -640,7 +704,11 @@ static void intel_dsi_get_config(struct intel_encoder *encoder, | |||
640 | */ | 704 | */ |
641 | pipe_config->dpll_hw_state.dpll_md = 0; | 705 | pipe_config->dpll_hw_state.dpll_md = 0; |
642 | 706 | ||
643 | pclk = vlv_get_dsi_pclk(encoder, pipe_config->pipe_bpp); | 707 | if (IS_BROXTON(encoder->base.dev)) |
708 | pclk = bxt_get_dsi_pclk(encoder, pipe_config->pipe_bpp); | ||
709 | else if (IS_VALLEYVIEW(encoder->base.dev)) | ||
710 | pclk = vlv_get_dsi_pclk(encoder, pipe_config->pipe_bpp); | ||
711 | |||
644 | if (!pclk) | 712 | if (!pclk) |
645 | return; | 713 | return; |
646 | 714 | ||
@@ -698,7 +766,7 @@ static u16 txbyteclkhs(u16 pixels, int bpp, int lane_count, | |||
698 | } | 766 | } |
699 | 767 | ||
700 | static void set_dsi_timings(struct drm_encoder *encoder, | 768 | static void set_dsi_timings(struct drm_encoder *encoder, |
701 | const struct drm_display_mode *mode) | 769 | const struct drm_display_mode *adjusted_mode) |
702 | { | 770 | { |
703 | struct drm_device *dev = encoder->dev; | 771 | struct drm_device *dev = encoder->dev; |
704 | struct drm_i915_private *dev_priv = dev->dev_private; | 772 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -710,10 +778,10 @@ static void set_dsi_timings(struct drm_encoder *encoder, | |||
710 | 778 | ||
711 | u16 hactive, hfp, hsync, hbp, vfp, vsync, vbp; | 779 | u16 hactive, hfp, hsync, hbp, vfp, vsync, vbp; |
712 | 780 | ||
713 | hactive = mode->hdisplay; | 781 | hactive = adjusted_mode->crtc_hdisplay; |
714 | hfp = mode->hsync_start - mode->hdisplay; | 782 | hfp = adjusted_mode->crtc_hsync_start - adjusted_mode->crtc_hdisplay; |
715 | hsync = mode->hsync_end - mode->hsync_start; | 783 | hsync = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; |
716 | hbp = mode->htotal - mode->hsync_end; | 784 | hbp = adjusted_mode->crtc_htotal - adjusted_mode->crtc_hsync_end; |
717 | 785 | ||
718 | if (intel_dsi->dual_link) { | 786 | if (intel_dsi->dual_link) { |
719 | hactive /= 2; | 787 | hactive /= 2; |
@@ -724,9 +792,9 @@ static void set_dsi_timings(struct drm_encoder *encoder, | |||
724 | hbp /= 2; | 792 | hbp /= 2; |
725 | } | 793 | } |
726 | 794 | ||
727 | vfp = mode->vsync_start - mode->vdisplay; | 795 | vfp = adjusted_mode->crtc_vsync_start - adjusted_mode->crtc_vdisplay; |
728 | vsync = mode->vsync_end - mode->vsync_start; | 796 | vsync = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start; |
729 | vbp = mode->vtotal - mode->vsync_end; | 797 | vbp = adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vsync_end; |
730 | 798 | ||
731 | /* horizontal values are in terms of high speed byte clock */ | 799 | /* horizontal values are in terms of high speed byte clock */ |
732 | hactive = txbyteclkhs(hactive, bpp, lane_count, | 800 | hactive = txbyteclkhs(hactive, bpp, lane_count, |
@@ -745,11 +813,11 @@ static void set_dsi_timings(struct drm_encoder *encoder, | |||
745 | * whereas these values should be based on resolution. | 813 | * whereas these values should be based on resolution. |
746 | */ | 814 | */ |
747 | I915_WRITE(BXT_MIPI_TRANS_HACTIVE(port), | 815 | I915_WRITE(BXT_MIPI_TRANS_HACTIVE(port), |
748 | mode->hdisplay); | 816 | adjusted_mode->crtc_hdisplay); |
749 | I915_WRITE(BXT_MIPI_TRANS_VACTIVE(port), | 817 | I915_WRITE(BXT_MIPI_TRANS_VACTIVE(port), |
750 | mode->vdisplay); | 818 | adjusted_mode->crtc_vdisplay); |
751 | I915_WRITE(BXT_MIPI_TRANS_VTOTAL(port), | 819 | I915_WRITE(BXT_MIPI_TRANS_VTOTAL(port), |
752 | mode->vtotal); | 820 | adjusted_mode->crtc_vtotal); |
753 | } | 821 | } |
754 | 822 | ||
755 | I915_WRITE(MIPI_HACTIVE_AREA_COUNT(port), hactive); | 823 | I915_WRITE(MIPI_HACTIVE_AREA_COUNT(port), hactive); |
@@ -774,8 +842,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) | |||
774 | struct drm_i915_private *dev_priv = dev->dev_private; | 842 | struct drm_i915_private *dev_priv = dev->dev_private; |
775 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 843 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
776 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); | 844 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); |
777 | struct drm_display_mode *adjusted_mode = | 845 | const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode; |
778 | &intel_crtc->config->base.adjusted_mode; | ||
779 | enum port port; | 846 | enum port port; |
780 | unsigned int bpp = intel_crtc->config->pipe_bpp; | 847 | unsigned int bpp = intel_crtc->config->pipe_bpp; |
781 | u32 val, tmp; | 848 | u32 val, tmp; |
@@ -783,7 +850,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) | |||
783 | 850 | ||
784 | DRM_DEBUG_KMS("pipe %c\n", pipe_name(intel_crtc->pipe)); | 851 | DRM_DEBUG_KMS("pipe %c\n", pipe_name(intel_crtc->pipe)); |
785 | 852 | ||
786 | mode_hdisplay = adjusted_mode->hdisplay; | 853 | mode_hdisplay = adjusted_mode->crtc_hdisplay; |
787 | 854 | ||
788 | if (intel_dsi->dual_link) { | 855 | if (intel_dsi->dual_link) { |
789 | mode_hdisplay /= 2; | 856 | mode_hdisplay /= 2; |
@@ -833,7 +900,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) | |||
833 | I915_WRITE(MIPI_DPHY_PARAM(port), intel_dsi->dphy_reg); | 900 | I915_WRITE(MIPI_DPHY_PARAM(port), intel_dsi->dphy_reg); |
834 | 901 | ||
835 | I915_WRITE(MIPI_DPI_RESOLUTION(port), | 902 | I915_WRITE(MIPI_DPI_RESOLUTION(port), |
836 | adjusted_mode->vdisplay << VERTICAL_ADDRESS_SHIFT | | 903 | adjusted_mode->crtc_vdisplay << VERTICAL_ADDRESS_SHIFT | |
837 | mode_hdisplay << HORIZONTAL_ADDRESS_SHIFT); | 904 | mode_hdisplay << HORIZONTAL_ADDRESS_SHIFT); |
838 | } | 905 | } |
839 | 906 | ||
@@ -879,15 +946,15 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) | |||
879 | if (is_vid_mode(intel_dsi) && | 946 | if (is_vid_mode(intel_dsi) && |
880 | intel_dsi->video_mode_format == VIDEO_MODE_BURST) { | 947 | intel_dsi->video_mode_format == VIDEO_MODE_BURST) { |
881 | I915_WRITE(MIPI_HS_TX_TIMEOUT(port), | 948 | I915_WRITE(MIPI_HS_TX_TIMEOUT(port), |
882 | txbyteclkhs(adjusted_mode->htotal, bpp, | 949 | txbyteclkhs(adjusted_mode->crtc_htotal, bpp, |
883 | intel_dsi->lane_count, | 950 | intel_dsi->lane_count, |
884 | intel_dsi->burst_mode_ratio) + 1); | 951 | intel_dsi->burst_mode_ratio) + 1); |
885 | } else { | 952 | } else { |
886 | I915_WRITE(MIPI_HS_TX_TIMEOUT(port), | 953 | I915_WRITE(MIPI_HS_TX_TIMEOUT(port), |
887 | txbyteclkhs(adjusted_mode->vtotal * | 954 | txbyteclkhs(adjusted_mode->crtc_vtotal * |
888 | adjusted_mode->htotal, | 955 | adjusted_mode->crtc_htotal, |
889 | bpp, intel_dsi->lane_count, | 956 | bpp, intel_dsi->lane_count, |
890 | intel_dsi->burst_mode_ratio) + 1); | 957 | intel_dsi->burst_mode_ratio) + 1); |
891 | } | 958 | } |
892 | I915_WRITE(MIPI_LP_RX_TIMEOUT(port), intel_dsi->lp_rx_timeout); | 959 | I915_WRITE(MIPI_LP_RX_TIMEOUT(port), intel_dsi->lp_rx_timeout); |
893 | I915_WRITE(MIPI_TURN_AROUND_TIMEOUT(port), | 960 | I915_WRITE(MIPI_TURN_AROUND_TIMEOUT(port), |
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 5cc46b4131f7..e6cb25239941 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h | |||
@@ -127,6 +127,9 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder) | |||
127 | extern void intel_enable_dsi_pll(struct intel_encoder *encoder); | 127 | extern void intel_enable_dsi_pll(struct intel_encoder *encoder); |
128 | extern void intel_disable_dsi_pll(struct intel_encoder *encoder); | 128 | extern void intel_disable_dsi_pll(struct intel_encoder *encoder); |
129 | extern u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp); | 129 | extern u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp); |
130 | extern u32 bxt_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp); | ||
131 | extern void intel_dsi_reset_clocks(struct intel_encoder *encoder, | ||
132 | enum port port); | ||
130 | 133 | ||
131 | struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id); | 134 | struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id); |
132 | 135 | ||
diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index f335e6cd4431..cb3cf3986212 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c | |||
@@ -384,6 +384,90 @@ u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp) | |||
384 | return pclk; | 384 | return pclk; |
385 | } | 385 | } |
386 | 386 | ||
387 | u32 bxt_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp) | ||
388 | { | ||
389 | u32 pclk; | ||
390 | u32 dsi_clk; | ||
391 | u32 dsi_ratio; | ||
392 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); | ||
393 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; | ||
394 | |||
395 | /* Divide by zero */ | ||
396 | if (!pipe_bpp) { | ||
397 | DRM_ERROR("Invalid BPP(0)\n"); | ||
398 | return 0; | ||
399 | } | ||
400 | |||
401 | dsi_ratio = I915_READ(BXT_DSI_PLL_CTL) & | ||
402 | BXT_DSI_PLL_RATIO_MASK; | ||
403 | |||
404 | /* Invalid DSI ratio ? */ | ||
405 | if (dsi_ratio < BXT_DSI_PLL_RATIO_MIN || | ||
406 | dsi_ratio > BXT_DSI_PLL_RATIO_MAX) { | ||
407 | DRM_ERROR("Invalid DSI pll ratio(%u) programmed\n", dsi_ratio); | ||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | dsi_clk = (dsi_ratio * BXT_REF_CLOCK_KHZ) / 2; | ||
412 | |||
413 | /* pixel_format and pipe_bpp should agree */ | ||
414 | assert_bpp_mismatch(intel_dsi->pixel_format, pipe_bpp); | ||
415 | |||
416 | pclk = DIV_ROUND_CLOSEST(dsi_clk * intel_dsi->lane_count, pipe_bpp); | ||
417 | |||
418 | DRM_DEBUG_DRIVER("Calculated pclk=%u\n", pclk); | ||
419 | return pclk; | ||
420 | } | ||
421 | |||
422 | static void vlv_dsi_reset_clocks(struct intel_encoder *encoder, enum port port) | ||
423 | { | ||
424 | u32 temp; | ||
425 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; | ||
426 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); | ||
427 | |||
428 | temp = I915_READ(MIPI_CTRL(port)); | ||
429 | temp &= ~ESCAPE_CLOCK_DIVIDER_MASK; | ||
430 | I915_WRITE(MIPI_CTRL(port), temp | | ||
431 | intel_dsi->escape_clk_div << | ||
432 | ESCAPE_CLOCK_DIVIDER_SHIFT); | ||
433 | } | ||
434 | |||
435 | /* Program BXT Mipi clocks and dividers */ | ||
436 | static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port) | ||
437 | { | ||
438 | u32 tmp; | ||
439 | u32 divider; | ||
440 | u32 dsi_rate; | ||
441 | u32 pll_ratio; | ||
442 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
443 | |||
444 | /* Clear old configurations */ | ||
445 | tmp = I915_READ(BXT_MIPI_CLOCK_CTL); | ||
446 | tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port)); | ||
447 | tmp &= ~(BXT_MIPI_RX_ESCLK_FIXDIV_MASK(port)); | ||
448 | tmp &= ~(BXT_MIPI_ESCLK_VAR_DIV_MASK(port)); | ||
449 | tmp &= ~(BXT_MIPI_DPHY_DIVIDER_MASK(port)); | ||
450 | |||
451 | /* Get the current DSI rate(actual) */ | ||
452 | pll_ratio = I915_READ(BXT_DSI_PLL_CTL) & | ||
453 | BXT_DSI_PLL_RATIO_MASK; | ||
454 | dsi_rate = (BXT_REF_CLOCK_KHZ * pll_ratio) / 2; | ||
455 | |||
456 | /* Max possible output of clock is 39.5 MHz, program value -1 */ | ||
457 | divider = (dsi_rate / BXT_MAX_VAR_OUTPUT_KHZ) - 1; | ||
458 | tmp |= BXT_MIPI_ESCLK_VAR_DIV(port, divider); | ||
459 | |||
460 | /* | ||
461 | * Tx escape clock must be as close to 20MHz possible, but should | ||
462 | * not exceed it. Hence select divide by 2 | ||
463 | */ | ||
464 | tmp |= BXT_MIPI_TX_ESCLK_8XDIV_BY2(port); | ||
465 | |||
466 | tmp |= BXT_MIPI_RX_ESCLK_8X_BY3(port); | ||
467 | |||
468 | I915_WRITE(BXT_MIPI_CLOCK_CTL, tmp); | ||
469 | } | ||
470 | |||
387 | static bool bxt_configure_dsi_pll(struct intel_encoder *encoder) | 471 | static bool bxt_configure_dsi_pll(struct intel_encoder *encoder) |
388 | { | 472 | { |
389 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; | 473 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
@@ -435,6 +519,8 @@ static bool bxt_configure_dsi_pll(struct intel_encoder *encoder) | |||
435 | static void bxt_enable_dsi_pll(struct intel_encoder *encoder) | 519 | static void bxt_enable_dsi_pll(struct intel_encoder *encoder) |
436 | { | 520 | { |
437 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; | 521 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
522 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); | ||
523 | enum port port; | ||
438 | u32 val; | 524 | u32 val; |
439 | 525 | ||
440 | DRM_DEBUG_KMS("\n"); | 526 | DRM_DEBUG_KMS("\n"); |
@@ -453,6 +539,10 @@ static void bxt_enable_dsi_pll(struct intel_encoder *encoder) | |||
453 | return; | 539 | return; |
454 | } | 540 | } |
455 | 541 | ||
542 | /* Program TX, RX, Dphy clocks */ | ||
543 | for_each_dsi_port(port, intel_dsi->ports) | ||
544 | bxt_dsi_program_clocks(encoder->base.dev, port); | ||
545 | |||
456 | /* Enable DSI PLL */ | 546 | /* Enable DSI PLL */ |
457 | val = I915_READ(BXT_DSI_PLL_ENABLE); | 547 | val = I915_READ(BXT_DSI_PLL_ENABLE); |
458 | val |= BXT_DSI_PLL_DO_ENABLE; | 548 | val |= BXT_DSI_PLL_DO_ENABLE; |
@@ -486,3 +576,29 @@ void intel_disable_dsi_pll(struct intel_encoder *encoder) | |||
486 | else if (IS_BROXTON(dev)) | 576 | else if (IS_BROXTON(dev)) |
487 | bxt_disable_dsi_pll(encoder); | 577 | bxt_disable_dsi_pll(encoder); |
488 | } | 578 | } |
579 | |||
580 | static void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port) | ||
581 | { | ||
582 | u32 tmp; | ||
583 | struct drm_device *dev = encoder->base.dev; | ||
584 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
585 | |||
586 | /* Clear old configurations */ | ||
587 | tmp = I915_READ(BXT_MIPI_CLOCK_CTL); | ||
588 | tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port)); | ||
589 | tmp &= ~(BXT_MIPI_RX_ESCLK_FIXDIV_MASK(port)); | ||
590 | tmp &= ~(BXT_MIPI_ESCLK_VAR_DIV_MASK(port)); | ||
591 | tmp &= ~(BXT_MIPI_DPHY_DIVIDER_MASK(port)); | ||
592 | I915_WRITE(BXT_MIPI_CLOCK_CTL, tmp); | ||
593 | I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP); | ||
594 | } | ||
595 | |||
596 | void intel_dsi_reset_clocks(struct intel_encoder *encoder, enum port port) | ||
597 | { | ||
598 | struct drm_device *dev = encoder->base.dev; | ||
599 | |||
600 | if (IS_BROXTON(dev)) | ||
601 | bxt_dsi_reset_clocks(encoder, port); | ||
602 | else if (IS_VALLEYVIEW(dev)) | ||
603 | vlv_dsi_reset_clocks(encoder, port); | ||
604 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index c80fe1f49ede..8492053e0ff0 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -97,7 +97,8 @@ struct intel_dvo { | |||
97 | 97 | ||
98 | struct intel_dvo_device dev; | 98 | struct intel_dvo_device dev; |
99 | 99 | ||
100 | struct drm_display_mode *panel_fixed_mode; | 100 | struct intel_connector *attached_connector; |
101 | |||
101 | bool panel_wants_dither; | 102 | bool panel_wants_dither; |
102 | }; | 103 | }; |
103 | 104 | ||
@@ -201,6 +202,8 @@ intel_dvo_mode_valid(struct drm_connector *connector, | |||
201 | struct drm_display_mode *mode) | 202 | struct drm_display_mode *mode) |
202 | { | 203 | { |
203 | struct intel_dvo *intel_dvo = intel_attached_dvo(connector); | 204 | struct intel_dvo *intel_dvo = intel_attached_dvo(connector); |
205 | const struct drm_display_mode *fixed_mode = | ||
206 | to_intel_connector(connector)->panel.fixed_mode; | ||
204 | int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; | 207 | int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; |
205 | int target_clock = mode->clock; | 208 | int target_clock = mode->clock; |
206 | 209 | ||
@@ -209,13 +212,13 @@ intel_dvo_mode_valid(struct drm_connector *connector, | |||
209 | 212 | ||
210 | /* XXX: Validate clock range */ | 213 | /* XXX: Validate clock range */ |
211 | 214 | ||
212 | if (intel_dvo->panel_fixed_mode) { | 215 | if (fixed_mode) { |
213 | if (mode->hdisplay > intel_dvo->panel_fixed_mode->hdisplay) | 216 | if (mode->hdisplay > fixed_mode->hdisplay) |
214 | return MODE_PANEL; | 217 | return MODE_PANEL; |
215 | if (mode->vdisplay > intel_dvo->panel_fixed_mode->vdisplay) | 218 | if (mode->vdisplay > fixed_mode->vdisplay) |
216 | return MODE_PANEL; | 219 | return MODE_PANEL; |
217 | 220 | ||
218 | target_clock = intel_dvo->panel_fixed_mode->clock; | 221 | target_clock = fixed_mode->clock; |
219 | } | 222 | } |
220 | 223 | ||
221 | if (target_clock > max_dotclk) | 224 | if (target_clock > max_dotclk) |
@@ -228,6 +231,8 @@ static bool intel_dvo_compute_config(struct intel_encoder *encoder, | |||
228 | struct intel_crtc_state *pipe_config) | 231 | struct intel_crtc_state *pipe_config) |
229 | { | 232 | { |
230 | struct intel_dvo *intel_dvo = enc_to_dvo(encoder); | 233 | struct intel_dvo *intel_dvo = enc_to_dvo(encoder); |
234 | const struct drm_display_mode *fixed_mode = | ||
235 | intel_dvo->attached_connector->panel.fixed_mode; | ||
231 | struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; | 236 | struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; |
232 | 237 | ||
233 | /* If we have timings from the BIOS for the panel, put them in | 238 | /* If we have timings from the BIOS for the panel, put them in |
@@ -235,21 +240,8 @@ static bool intel_dvo_compute_config(struct intel_encoder *encoder, | |||
235 | * with the panel scaling set up to source from the H/VDisplay | 240 | * with the panel scaling set up to source from the H/VDisplay |
236 | * of the original mode. | 241 | * of the original mode. |
237 | */ | 242 | */ |
238 | if (intel_dvo->panel_fixed_mode != NULL) { | 243 | if (fixed_mode) |
239 | #define C(x) adjusted_mode->x = intel_dvo->panel_fixed_mode->x | 244 | intel_fixed_panel_mode(fixed_mode, adjusted_mode); |
240 | C(hdisplay); | ||
241 | C(hsync_start); | ||
242 | C(hsync_end); | ||
243 | C(htotal); | ||
244 | C(vdisplay); | ||
245 | C(vsync_start); | ||
246 | C(vsync_end); | ||
247 | C(vtotal); | ||
248 | C(clock); | ||
249 | #undef C | ||
250 | |||
251 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
252 | } | ||
253 | 245 | ||
254 | return true; | 246 | return true; |
255 | } | 247 | } |
@@ -259,7 +251,7 @@ static void intel_dvo_pre_enable(struct intel_encoder *encoder) | |||
259 | struct drm_device *dev = encoder->base.dev; | 251 | struct drm_device *dev = encoder->base.dev; |
260 | struct drm_i915_private *dev_priv = dev->dev_private; | 252 | struct drm_i915_private *dev_priv = dev->dev_private; |
261 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); | 253 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); |
262 | struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; | 254 | const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; |
263 | struct intel_dvo *intel_dvo = enc_to_dvo(encoder); | 255 | struct intel_dvo *intel_dvo = enc_to_dvo(encoder); |
264 | int pipe = crtc->pipe; | 256 | int pipe = crtc->pipe; |
265 | u32 dvo_val; | 257 | u32 dvo_val; |
@@ -293,11 +285,11 @@ static void intel_dvo_pre_enable(struct intel_encoder *encoder) | |||
293 | dvo_val |= DVO_VSYNC_ACTIVE_HIGH; | 285 | dvo_val |= DVO_VSYNC_ACTIVE_HIGH; |
294 | 286 | ||
295 | /*I915_WRITE(DVOB_SRCDIM, | 287 | /*I915_WRITE(DVOB_SRCDIM, |
296 | (adjusted_mode->hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | | 288 | (adjusted_mode->crtc_hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | |
297 | (adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/ | 289 | (adjusted_mode->crtc_vdisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/ |
298 | I915_WRITE(dvo_srcdim_reg, | 290 | I915_WRITE(dvo_srcdim_reg, |
299 | (adjusted_mode->hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | | 291 | (adjusted_mode->crtc_hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | |
300 | (adjusted_mode->vdisplay << DVO_SRCDIM_VERTICAL_SHIFT)); | 292 | (adjusted_mode->crtc_vdisplay << DVO_SRCDIM_VERTICAL_SHIFT)); |
301 | /*I915_WRITE(DVOB, dvo_val);*/ | 293 | /*I915_WRITE(DVOB, dvo_val);*/ |
302 | I915_WRITE(dvo_reg, dvo_val); | 294 | I915_WRITE(dvo_reg, dvo_val); |
303 | } | 295 | } |
@@ -318,8 +310,9 @@ intel_dvo_detect(struct drm_connector *connector, bool force) | |||
318 | 310 | ||
319 | static int intel_dvo_get_modes(struct drm_connector *connector) | 311 | static int intel_dvo_get_modes(struct drm_connector *connector) |
320 | { | 312 | { |
321 | struct intel_dvo *intel_dvo = intel_attached_dvo(connector); | ||
322 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 313 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
314 | const struct drm_display_mode *fixed_mode = | ||
315 | to_intel_connector(connector)->panel.fixed_mode; | ||
323 | 316 | ||
324 | /* We should probably have an i2c driver get_modes function for those | 317 | /* We should probably have an i2c driver get_modes function for those |
325 | * devices which will have a fixed set of modes determined by the chip | 318 | * devices which will have a fixed set of modes determined by the chip |
@@ -331,9 +324,9 @@ static int intel_dvo_get_modes(struct drm_connector *connector) | |||
331 | if (!list_empty(&connector->probed_modes)) | 324 | if (!list_empty(&connector->probed_modes)) |
332 | return 1; | 325 | return 1; |
333 | 326 | ||
334 | if (intel_dvo->panel_fixed_mode != NULL) { | 327 | if (fixed_mode) { |
335 | struct drm_display_mode *mode; | 328 | struct drm_display_mode *mode; |
336 | mode = drm_mode_duplicate(connector->dev, intel_dvo->panel_fixed_mode); | 329 | mode = drm_mode_duplicate(connector->dev, fixed_mode); |
337 | if (mode) { | 330 | if (mode) { |
338 | drm_mode_probed_add(connector, mode); | 331 | drm_mode_probed_add(connector, mode); |
339 | return 1; | 332 | return 1; |
@@ -346,6 +339,7 @@ static int intel_dvo_get_modes(struct drm_connector *connector) | |||
346 | static void intel_dvo_destroy(struct drm_connector *connector) | 339 | static void intel_dvo_destroy(struct drm_connector *connector) |
347 | { | 340 | { |
348 | drm_connector_cleanup(connector); | 341 | drm_connector_cleanup(connector); |
342 | intel_panel_fini(&to_intel_connector(connector)->panel); | ||
349 | kfree(connector); | 343 | kfree(connector); |
350 | } | 344 | } |
351 | 345 | ||
@@ -372,8 +366,6 @@ static void intel_dvo_enc_destroy(struct drm_encoder *encoder) | |||
372 | if (intel_dvo->dev.dev_ops->destroy) | 366 | if (intel_dvo->dev.dev_ops->destroy) |
373 | intel_dvo->dev.dev_ops->destroy(&intel_dvo->dev); | 367 | intel_dvo->dev.dev_ops->destroy(&intel_dvo->dev); |
374 | 368 | ||
375 | kfree(intel_dvo->panel_fixed_mode); | ||
376 | |||
377 | intel_encoder_destroy(encoder); | 369 | intel_encoder_destroy(encoder); |
378 | } | 370 | } |
379 | 371 | ||
@@ -438,6 +430,8 @@ void intel_dvo_init(struct drm_device *dev) | |||
438 | return; | 430 | return; |
439 | } | 431 | } |
440 | 432 | ||
433 | intel_dvo->attached_connector = intel_connector; | ||
434 | |||
441 | intel_encoder = &intel_dvo->base; | 435 | intel_encoder = &intel_dvo->base; |
442 | drm_encoder_init(dev, &intel_encoder->base, | 436 | drm_encoder_init(dev, &intel_encoder->base, |
443 | &intel_dvo_enc_funcs, encoder_type); | 437 | &intel_dvo_enc_funcs, encoder_type); |
@@ -542,8 +536,9 @@ void intel_dvo_init(struct drm_device *dev) | |||
542 | * headers, likely), so for now, just get the current | 536 | * headers, likely), so for now, just get the current |
543 | * mode being output through DVO. | 537 | * mode being output through DVO. |
544 | */ | 538 | */ |
545 | intel_dvo->panel_fixed_mode = | 539 | intel_panel_init(&intel_connector->panel, |
546 | intel_dvo_get_current_mode(connector); | 540 | intel_dvo_get_current_mode(connector), |
541 | NULL); | ||
547 | intel_dvo->panel_wants_dither = true; | 542 | intel_dvo->panel_wants_dither = true; |
548 | } | 543 | } |
549 | 544 | ||
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 6777fbb25d07..cf47352b7b8e 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c | |||
@@ -41,6 +41,11 @@ | |||
41 | #include "intel_drv.h" | 41 | #include "intel_drv.h" |
42 | #include "i915_drv.h" | 42 | #include "i915_drv.h" |
43 | 43 | ||
44 | static inline bool fbc_supported(struct drm_i915_private *dev_priv) | ||
45 | { | ||
46 | return dev_priv->fbc.enable_fbc != NULL; | ||
47 | } | ||
48 | |||
44 | /* | 49 | /* |
45 | * In some platforms where the CRTC's x:0/y:0 coordinates doesn't match the | 50 | * In some platforms where the CRTC's x:0/y:0 coordinates doesn't match the |
46 | * frontbuffer's x:0/y:0 coordinates we lie to the hardware about the plane's | 51 | * frontbuffer's x:0/y:0 coordinates we lie to the hardware about the plane's |
@@ -439,7 +444,7 @@ static void __intel_fbc_disable(struct drm_i915_private *dev_priv) | |||
439 | */ | 444 | */ |
440 | void intel_fbc_disable(struct drm_i915_private *dev_priv) | 445 | void intel_fbc_disable(struct drm_i915_private *dev_priv) |
441 | { | 446 | { |
442 | if (!dev_priv->fbc.enable_fbc) | 447 | if (!fbc_supported(dev_priv)) |
443 | return; | 448 | return; |
444 | 449 | ||
445 | mutex_lock(&dev_priv->fbc.lock); | 450 | mutex_lock(&dev_priv->fbc.lock); |
@@ -457,7 +462,7 @@ void intel_fbc_disable_crtc(struct intel_crtc *crtc) | |||
457 | { | 462 | { |
458 | struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; | 463 | struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; |
459 | 464 | ||
460 | if (!dev_priv->fbc.enable_fbc) | 465 | if (!fbc_supported(dev_priv)) |
461 | return; | 466 | return; |
462 | 467 | ||
463 | mutex_lock(&dev_priv->fbc.lock); | 468 | mutex_lock(&dev_priv->fbc.lock); |
@@ -685,7 +690,7 @@ static void __intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv) | |||
685 | 690 | ||
686 | void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv) | 691 | void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv) |
687 | { | 692 | { |
688 | if (!dev_priv->fbc.enable_fbc) | 693 | if (!fbc_supported(dev_priv)) |
689 | return; | 694 | return; |
690 | 695 | ||
691 | mutex_lock(&dev_priv->fbc.lock); | 696 | mutex_lock(&dev_priv->fbc.lock); |
@@ -693,16 +698,61 @@ void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv) | |||
693 | mutex_unlock(&dev_priv->fbc.lock); | 698 | mutex_unlock(&dev_priv->fbc.lock); |
694 | } | 699 | } |
695 | 700 | ||
696 | static int intel_fbc_setup_cfb(struct drm_i915_private *dev_priv, int size, | 701 | /* |
697 | int fb_cpp) | 702 | * For SKL+, the plane source size used by the hardware is based on the value we |
703 | * write to the PLANE_SIZE register. For BDW-, the hardware looks at the value | ||
704 | * we wrote to PIPESRC. | ||
705 | */ | ||
706 | static void intel_fbc_get_plane_source_size(struct intel_crtc *crtc, | ||
707 | int *width, int *height) | ||
698 | { | 708 | { |
709 | struct intel_plane_state *plane_state = | ||
710 | to_intel_plane_state(crtc->base.primary->state); | ||
711 | int w, h; | ||
712 | |||
713 | if (intel_rotation_90_or_270(plane_state->base.rotation)) { | ||
714 | w = drm_rect_height(&plane_state->src) >> 16; | ||
715 | h = drm_rect_width(&plane_state->src) >> 16; | ||
716 | } else { | ||
717 | w = drm_rect_width(&plane_state->src) >> 16; | ||
718 | h = drm_rect_height(&plane_state->src) >> 16; | ||
719 | } | ||
720 | |||
721 | if (width) | ||
722 | *width = w; | ||
723 | if (height) | ||
724 | *height = h; | ||
725 | } | ||
726 | |||
727 | static int intel_fbc_calculate_cfb_size(struct intel_crtc *crtc) | ||
728 | { | ||
729 | struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; | ||
730 | struct drm_framebuffer *fb = crtc->base.primary->fb; | ||
731 | int lines; | ||
732 | |||
733 | intel_fbc_get_plane_source_size(crtc, NULL, &lines); | ||
734 | if (INTEL_INFO(dev_priv)->gen >= 7) | ||
735 | lines = min(lines, 2048); | ||
736 | |||
737 | return lines * fb->pitches[0]; | ||
738 | } | ||
739 | |||
740 | static int intel_fbc_setup_cfb(struct intel_crtc *crtc) | ||
741 | { | ||
742 | struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; | ||
743 | struct drm_framebuffer *fb = crtc->base.primary->fb; | ||
744 | int size, cpp; | ||
745 | |||
746 | size = intel_fbc_calculate_cfb_size(crtc); | ||
747 | cpp = drm_format_plane_cpp(fb->pixel_format, 0); | ||
748 | |||
699 | if (size <= dev_priv->fbc.uncompressed_size) | 749 | if (size <= dev_priv->fbc.uncompressed_size) |
700 | return 0; | 750 | return 0; |
701 | 751 | ||
702 | /* Release any current block */ | 752 | /* Release any current block */ |
703 | __intel_fbc_cleanup_cfb(dev_priv); | 753 | __intel_fbc_cleanup_cfb(dev_priv); |
704 | 754 | ||
705 | return intel_fbc_alloc_cfb(dev_priv, size, fb_cpp); | 755 | return intel_fbc_alloc_cfb(dev_priv, size, cpp); |
706 | } | 756 | } |
707 | 757 | ||
708 | static bool stride_is_valid(struct drm_i915_private *dev_priv, | 758 | static bool stride_is_valid(struct drm_i915_private *dev_priv, |
@@ -749,6 +799,35 @@ static bool pixel_format_is_valid(struct drm_framebuffer *fb) | |||
749 | } | 799 | } |
750 | } | 800 | } |
751 | 801 | ||
802 | /* | ||
803 | * For some reason, the hardware tracking starts looking at whatever we | ||
804 | * programmed as the display plane base address register. It does not look at | ||
805 | * the X and Y offset registers. That's why we look at the crtc->adjusted{x,y} | ||
806 | * variables instead of just looking at the pipe/plane size. | ||
807 | */ | ||
808 | static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc) | ||
809 | { | ||
810 | struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; | ||
811 | unsigned int effective_w, effective_h, max_w, max_h; | ||
812 | |||
813 | if (INTEL_INFO(dev_priv)->gen >= 8 || IS_HASWELL(dev_priv)) { | ||
814 | max_w = 4096; | ||
815 | max_h = 4096; | ||
816 | } else if (IS_G4X(dev_priv) || INTEL_INFO(dev_priv)->gen >= 5) { | ||
817 | max_w = 4096; | ||
818 | max_h = 2048; | ||
819 | } else { | ||
820 | max_w = 2048; | ||
821 | max_h = 1536; | ||
822 | } | ||
823 | |||
824 | intel_fbc_get_plane_source_size(crtc, &effective_w, &effective_h); | ||
825 | effective_w += crtc->adjusted_x; | ||
826 | effective_h += crtc->adjusted_y; | ||
827 | |||
828 | return effective_w <= max_w && effective_h <= max_h; | ||
829 | } | ||
830 | |||
752 | /** | 831 | /** |
753 | * __intel_fbc_update - enable/disable FBC as needed, unlocked | 832 | * __intel_fbc_update - enable/disable FBC as needed, unlocked |
754 | * @dev_priv: i915 device instance | 833 | * @dev_priv: i915 device instance |
@@ -775,7 +854,6 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv) | |||
775 | struct drm_framebuffer *fb; | 854 | struct drm_framebuffer *fb; |
776 | struct drm_i915_gem_object *obj; | 855 | struct drm_i915_gem_object *obj; |
777 | const struct drm_display_mode *adjusted_mode; | 856 | const struct drm_display_mode *adjusted_mode; |
778 | unsigned int max_width, max_height; | ||
779 | 857 | ||
780 | WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); | 858 | WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); |
781 | 859 | ||
@@ -824,21 +902,11 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv) | |||
824 | goto out_disable; | 902 | goto out_disable; |
825 | } | 903 | } |
826 | 904 | ||
827 | if (INTEL_INFO(dev_priv)->gen >= 8 || IS_HASWELL(dev_priv)) { | 905 | if (!intel_fbc_hw_tracking_covers_screen(intel_crtc)) { |
828 | max_width = 4096; | ||
829 | max_height = 4096; | ||
830 | } else if (IS_G4X(dev_priv) || INTEL_INFO(dev_priv)->gen >= 5) { | ||
831 | max_width = 4096; | ||
832 | max_height = 2048; | ||
833 | } else { | ||
834 | max_width = 2048; | ||
835 | max_height = 1536; | ||
836 | } | ||
837 | if (intel_crtc->config->pipe_src_w > max_width || | ||
838 | intel_crtc->config->pipe_src_h > max_height) { | ||
839 | set_no_fbc_reason(dev_priv, FBC_MODE_TOO_LARGE); | 906 | set_no_fbc_reason(dev_priv, FBC_MODE_TOO_LARGE); |
840 | goto out_disable; | 907 | goto out_disable; |
841 | } | 908 | } |
909 | |||
842 | if ((INTEL_INFO(dev_priv)->gen < 4 || HAS_DDI(dev_priv)) && | 910 | if ((INTEL_INFO(dev_priv)->gen < 4 || HAS_DDI(dev_priv)) && |
843 | intel_crtc->plane != PLANE_A) { | 911 | intel_crtc->plane != PLANE_A) { |
844 | set_no_fbc_reason(dev_priv, FBC_BAD_PLANE); | 912 | set_no_fbc_reason(dev_priv, FBC_BAD_PLANE); |
@@ -883,8 +951,7 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv) | |||
883 | goto out_disable; | 951 | goto out_disable; |
884 | } | 952 | } |
885 | 953 | ||
886 | if (intel_fbc_setup_cfb(dev_priv, obj->base.size, | 954 | if (intel_fbc_setup_cfb(intel_crtc)) { |
887 | drm_format_plane_cpp(fb->pixel_format, 0))) { | ||
888 | set_no_fbc_reason(dev_priv, FBC_STOLEN_TOO_SMALL); | 955 | set_no_fbc_reason(dev_priv, FBC_STOLEN_TOO_SMALL); |
889 | goto out_disable; | 956 | goto out_disable; |
890 | } | 957 | } |
@@ -948,7 +1015,7 @@ out_disable: | |||
948 | */ | 1015 | */ |
949 | void intel_fbc_update(struct drm_i915_private *dev_priv) | 1016 | void intel_fbc_update(struct drm_i915_private *dev_priv) |
950 | { | 1017 | { |
951 | if (!dev_priv->fbc.enable_fbc) | 1018 | if (!fbc_supported(dev_priv)) |
952 | return; | 1019 | return; |
953 | 1020 | ||
954 | mutex_lock(&dev_priv->fbc.lock); | 1021 | mutex_lock(&dev_priv->fbc.lock); |
@@ -962,7 +1029,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, | |||
962 | { | 1029 | { |
963 | unsigned int fbc_bits; | 1030 | unsigned int fbc_bits; |
964 | 1031 | ||
965 | if (!dev_priv->fbc.enable_fbc) | 1032 | if (!fbc_supported(dev_priv)) |
966 | return; | 1033 | return; |
967 | 1034 | ||
968 | if (origin == ORIGIN_GTT) | 1035 | if (origin == ORIGIN_GTT) |
@@ -989,7 +1056,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, | |||
989 | void intel_fbc_flush(struct drm_i915_private *dev_priv, | 1056 | void intel_fbc_flush(struct drm_i915_private *dev_priv, |
990 | unsigned int frontbuffer_bits, enum fb_op_origin origin) | 1057 | unsigned int frontbuffer_bits, enum fb_op_origin origin) |
991 | { | 1058 | { |
992 | if (!dev_priv->fbc.enable_fbc) | 1059 | if (!fbc_supported(dev_priv)) |
993 | return; | 1060 | return; |
994 | 1061 | ||
995 | if (origin == ORIGIN_GTT) | 1062 | if (origin == ORIGIN_GTT) |
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 65329127f0b9..4fd5fdfef6bd 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c | |||
@@ -121,8 +121,9 @@ static int intelfb_alloc(struct drm_fb_helper *helper, | |||
121 | container_of(helper, struct intel_fbdev, helper); | 121 | container_of(helper, struct intel_fbdev, helper); |
122 | struct drm_framebuffer *fb; | 122 | struct drm_framebuffer *fb; |
123 | struct drm_device *dev = helper->dev; | 123 | struct drm_device *dev = helper->dev; |
124 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
124 | struct drm_mode_fb_cmd2 mode_cmd = {}; | 125 | struct drm_mode_fb_cmd2 mode_cmd = {}; |
125 | struct drm_i915_gem_object *obj; | 126 | struct drm_i915_gem_object *obj = NULL; |
126 | int size, ret; | 127 | int size, ret; |
127 | 128 | ||
128 | /* we don't do packed 24bpp */ | 129 | /* we don't do packed 24bpp */ |
@@ -139,7 +140,12 @@ static int intelfb_alloc(struct drm_fb_helper *helper, | |||
139 | 140 | ||
140 | size = mode_cmd.pitches[0] * mode_cmd.height; | 141 | size = mode_cmd.pitches[0] * mode_cmd.height; |
141 | size = PAGE_ALIGN(size); | 142 | size = PAGE_ALIGN(size); |
142 | obj = i915_gem_object_create_stolen(dev, size); | 143 | |
144 | /* If the FB is too big, just don't use it since fbdev is not very | ||
145 | * important and we should probably use that space with FBC or other | ||
146 | * features. */ | ||
147 | if (size * 2 < dev_priv->gtt.stolen_usable_size) | ||
148 | obj = i915_gem_object_create_stolen(dev, size); | ||
143 | if (obj == NULL) | 149 | if (obj == NULL) |
144 | obj = i915_gem_alloc_object(dev, size); | 150 | obj = i915_gem_alloc_object(dev, size); |
145 | if (!obj) { | 151 | if (!obj) { |
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index 4ec2d27a557e..081d5f648d26 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h | |||
@@ -110,6 +110,8 @@ extern void intel_guc_ucode_init(struct drm_device *dev); | |||
110 | extern int intel_guc_ucode_load(struct drm_device *dev); | 110 | extern int intel_guc_ucode_load(struct drm_device *dev); |
111 | extern void intel_guc_ucode_fini(struct drm_device *dev); | 111 | extern void intel_guc_ucode_fini(struct drm_device *dev); |
112 | extern const char *intel_guc_fw_status_repr(enum intel_guc_fw_status status); | 112 | extern const char *intel_guc_fw_status_repr(enum intel_guc_fw_status status); |
113 | extern int intel_guc_suspend(struct drm_device *dev); | ||
114 | extern int intel_guc_resume(struct drm_device *dev); | ||
113 | 115 | ||
114 | /* i915_guc_submission.c */ | 116 | /* i915_guc_submission.c */ |
115 | int i915_guc_submission_init(struct drm_device *dev); | 117 | int i915_guc_submission_init(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h index e1f47ba2b4b0..593d2f585978 100644 --- a/drivers/gpu/drm/i915/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h | |||
@@ -218,12 +218,23 @@ struct guc_context_desc { | |||
218 | u64 desc_private; | 218 | u64 desc_private; |
219 | } __packed; | 219 | } __packed; |
220 | 220 | ||
221 | #define GUC_FORCEWAKE_RENDER (1 << 0) | ||
222 | #define GUC_FORCEWAKE_MEDIA (1 << 1) | ||
223 | |||
224 | #define GUC_POWER_UNSPECIFIED 0 | ||
225 | #define GUC_POWER_D0 1 | ||
226 | #define GUC_POWER_D1 2 | ||
227 | #define GUC_POWER_D2 3 | ||
228 | #define GUC_POWER_D3 4 | ||
229 | |||
221 | /* This Action will be programmed in C180 - SOFT_SCRATCH_O_REG */ | 230 | /* This Action will be programmed in C180 - SOFT_SCRATCH_O_REG */ |
222 | enum host2guc_action { | 231 | enum host2guc_action { |
223 | HOST2GUC_ACTION_DEFAULT = 0x0, | 232 | HOST2GUC_ACTION_DEFAULT = 0x0, |
224 | HOST2GUC_ACTION_SAMPLE_FORCEWAKE = 0x6, | 233 | HOST2GUC_ACTION_SAMPLE_FORCEWAKE = 0x6, |
225 | HOST2GUC_ACTION_ALLOCATE_DOORBELL = 0x10, | 234 | HOST2GUC_ACTION_ALLOCATE_DOORBELL = 0x10, |
226 | HOST2GUC_ACTION_DEALLOCATE_DOORBELL = 0x20, | 235 | HOST2GUC_ACTION_DEALLOCATE_DOORBELL = 0x20, |
236 | HOST2GUC_ACTION_ENTER_S_STATE = 0x501, | ||
237 | HOST2GUC_ACTION_EXIT_S_STATE = 0x502, | ||
227 | HOST2GUC_ACTION_SLPC_REQUEST = 0x3003, | 238 | HOST2GUC_ACTION_SLPC_REQUEST = 0x3003, |
228 | HOST2GUC_ACTION_LIMIT | 239 | HOST2GUC_ACTION_LIMIT |
229 | }; | 240 | }; |
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index e0601cc5a795..a17b6a56be83 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c | |||
@@ -90,9 +90,6 @@ static void direct_interrupts_to_host(struct drm_i915_private *dev_priv) | |||
90 | for_each_ring(ring, dev_priv, i) | 90 | for_each_ring(ring, dev_priv, i) |
91 | I915_WRITE(RING_MODE_GEN7(ring), irqs); | 91 | I915_WRITE(RING_MODE_GEN7(ring), irqs); |
92 | 92 | ||
93 | /* tell DE to send nothing to GuC */ | ||
94 | I915_WRITE(DE_GUCRMR, ~0); | ||
95 | |||
96 | /* route all GT interrupts to the host */ | 93 | /* route all GT interrupts to the host */ |
97 | I915_WRITE(GUC_BCS_RCS_IER, 0); | 94 | I915_WRITE(GUC_BCS_RCS_IER, 0); |
98 | I915_WRITE(GUC_VCS2_VCS1_IER, 0); | 95 | I915_WRITE(GUC_VCS2_VCS1_IER, 0); |
@@ -110,13 +107,6 @@ static void direct_interrupts_to_guc(struct drm_i915_private *dev_priv) | |||
110 | for_each_ring(ring, dev_priv, i) | 107 | for_each_ring(ring, dev_priv, i) |
111 | I915_WRITE(RING_MODE_GEN7(ring), irqs); | 108 | I915_WRITE(RING_MODE_GEN7(ring), irqs); |
112 | 109 | ||
113 | /* tell DE to send (all) flip_done to GuC */ | ||
114 | irqs = DERRMR_PIPEA_PRI_FLIP_DONE | DERRMR_PIPEA_SPR_FLIP_DONE | | ||
115 | DERRMR_PIPEB_PRI_FLIP_DONE | DERRMR_PIPEB_SPR_FLIP_DONE | | ||
116 | DERRMR_PIPEC_PRI_FLIP_DONE | DERRMR_PIPEC_SPR_FLIP_DONE; | ||
117 | /* Unmasked bits will cause GuC response message to be sent */ | ||
118 | I915_WRITE(DE_GUCRMR, ~irqs); | ||
119 | |||
120 | /* route USER_INTERRUPT to Host, all others are sent to GuC. */ | 110 | /* route USER_INTERRUPT to Host, all others are sent to GuC. */ |
121 | irqs = GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT | | 111 | irqs = GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT | |
122 | GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT; | 112 | GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT; |
@@ -209,9 +199,10 @@ static inline bool guc_ucode_response(struct drm_i915_private *dev_priv, | |||
209 | u32 *status) | 199 | u32 *status) |
210 | { | 200 | { |
211 | u32 val = I915_READ(GUC_STATUS); | 201 | u32 val = I915_READ(GUC_STATUS); |
202 | u32 uk_val = val & GS_UKERNEL_MASK; | ||
212 | *status = val; | 203 | *status = val; |
213 | return ((val & GS_UKERNEL_MASK) == GS_UKERNEL_READY || | 204 | return (uk_val == GS_UKERNEL_READY || |
214 | (val & GS_UKERNEL_MASK) == GS_UKERNEL_LAPIC_DONE); | 205 | ((val & GS_MIA_CORE_STATE) && uk_val == GS_UKERNEL_LAPIC_DONE)); |
215 | } | 206 | } |
216 | 207 | ||
217 | /* | 208 | /* |
@@ -257,7 +248,7 @@ static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv) | |||
257 | /* Copy RSA signature from the fw image to HW for verification */ | 248 | /* Copy RSA signature from the fw image to HW for verification */ |
258 | sg_pcopy_to_buffer(sg->sgl, sg->nents, rsa, UOS_RSA_SIG_SIZE, offset); | 249 | sg_pcopy_to_buffer(sg->sgl, sg->nents, rsa, UOS_RSA_SIG_SIZE, offset); |
259 | for (i = 0; i < UOS_RSA_SIG_SIZE / sizeof(u32); i++) | 250 | for (i = 0; i < UOS_RSA_SIG_SIZE / sizeof(u32); i++) |
260 | I915_WRITE(UOS_RSA_SCRATCH_0 + i * sizeof(u32), rsa[i]); | 251 | I915_WRITE(UOS_RSA_SCRATCH(i), rsa[i]); |
261 | 252 | ||
262 | /* Set the source address for the new blob */ | 253 | /* Set the source address for the new blob */ |
263 | offset = i915_gem_obj_ggtt_offset(fw_obj); | 254 | offset = i915_gem_obj_ggtt_offset(fw_obj); |
@@ -392,7 +383,6 @@ int intel_guc_ucode_load(struct drm_device *dev) | |||
392 | intel_guc_fw_status_repr(guc_fw->guc_fw_load_status)); | 383 | intel_guc_fw_status_repr(guc_fw->guc_fw_load_status)); |
393 | 384 | ||
394 | direct_interrupts_to_host(dev_priv); | 385 | direct_interrupts_to_host(dev_priv); |
395 | i915_guc_submission_disable(dev); | ||
396 | 386 | ||
397 | if (guc_fw->guc_fw_fetch_status == GUC_FIRMWARE_NONE) | 387 | if (guc_fw->guc_fw_fetch_status == GUC_FIRMWARE_NONE) |
398 | return 0; | 388 | return 0; |
@@ -442,6 +432,9 @@ int intel_guc_ucode_load(struct drm_device *dev) | |||
442 | intel_guc_fw_status_repr(guc_fw->guc_fw_load_status)); | 432 | intel_guc_fw_status_repr(guc_fw->guc_fw_load_status)); |
443 | 433 | ||
444 | if (i915.enable_guc_submission) { | 434 | if (i915.enable_guc_submission) { |
435 | /* The execbuf_client will be recreated. Release it first. */ | ||
436 | i915_guc_submission_disable(dev); | ||
437 | |||
445 | err = i915_guc_submission_enable(dev); | 438 | err = i915_guc_submission_enable(dev); |
446 | if (err) | 439 | if (err) |
447 | goto fail; | 440 | goto fail; |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index bb33c66b0b12..3b28ed3237d3 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -447,16 +447,13 @@ static void intel_write_infoframe(struct drm_encoder *encoder, | |||
447 | } | 447 | } |
448 | 448 | ||
449 | static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, | 449 | static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, |
450 | struct drm_display_mode *adjusted_mode) | 450 | const struct drm_display_mode *adjusted_mode) |
451 | { | 451 | { |
452 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | 452 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
453 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 453 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
454 | union hdmi_infoframe frame; | 454 | union hdmi_infoframe frame; |
455 | int ret; | 455 | int ret; |
456 | 456 | ||
457 | /* Set user selected PAR to incoming mode's member */ | ||
458 | adjusted_mode->picture_aspect_ratio = intel_hdmi->aspect_ratio; | ||
459 | |||
460 | ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, | 457 | ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, |
461 | adjusted_mode); | 458 | adjusted_mode); |
462 | if (ret < 0) { | 459 | if (ret < 0) { |
@@ -494,7 +491,7 @@ static void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder) | |||
494 | 491 | ||
495 | static void | 492 | static void |
496 | intel_hdmi_set_hdmi_infoframe(struct drm_encoder *encoder, | 493 | intel_hdmi_set_hdmi_infoframe(struct drm_encoder *encoder, |
497 | struct drm_display_mode *adjusted_mode) | 494 | const struct drm_display_mode *adjusted_mode) |
498 | { | 495 | { |
499 | union hdmi_infoframe frame; | 496 | union hdmi_infoframe frame; |
500 | int ret; | 497 | int ret; |
@@ -509,7 +506,7 @@ intel_hdmi_set_hdmi_infoframe(struct drm_encoder *encoder, | |||
509 | 506 | ||
510 | static void g4x_set_infoframes(struct drm_encoder *encoder, | 507 | static void g4x_set_infoframes(struct drm_encoder *encoder, |
511 | bool enable, | 508 | bool enable, |
512 | struct drm_display_mode *adjusted_mode) | 509 | const struct drm_display_mode *adjusted_mode) |
513 | { | 510 | { |
514 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | 511 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
515 | struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); | 512 | struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); |
@@ -661,7 +658,7 @@ static bool intel_hdmi_set_gcp_infoframe(struct drm_encoder *encoder) | |||
661 | 658 | ||
662 | static void ibx_set_infoframes(struct drm_encoder *encoder, | 659 | static void ibx_set_infoframes(struct drm_encoder *encoder, |
663 | bool enable, | 660 | bool enable, |
664 | struct drm_display_mode *adjusted_mode) | 661 | const struct drm_display_mode *adjusted_mode) |
665 | { | 662 | { |
666 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | 663 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
667 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 664 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
@@ -713,7 +710,7 @@ static void ibx_set_infoframes(struct drm_encoder *encoder, | |||
713 | 710 | ||
714 | static void cpt_set_infoframes(struct drm_encoder *encoder, | 711 | static void cpt_set_infoframes(struct drm_encoder *encoder, |
715 | bool enable, | 712 | bool enable, |
716 | struct drm_display_mode *adjusted_mode) | 713 | const struct drm_display_mode *adjusted_mode) |
717 | { | 714 | { |
718 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | 715 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
719 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 716 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
@@ -755,7 +752,7 @@ static void cpt_set_infoframes(struct drm_encoder *encoder, | |||
755 | 752 | ||
756 | static void vlv_set_infoframes(struct drm_encoder *encoder, | 753 | static void vlv_set_infoframes(struct drm_encoder *encoder, |
757 | bool enable, | 754 | bool enable, |
758 | struct drm_display_mode *adjusted_mode) | 755 | const struct drm_display_mode *adjusted_mode) |
759 | { | 756 | { |
760 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | 757 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
761 | struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); | 758 | struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); |
@@ -807,7 +804,7 @@ static void vlv_set_infoframes(struct drm_encoder *encoder, | |||
807 | 804 | ||
808 | static void hsw_set_infoframes(struct drm_encoder *encoder, | 805 | static void hsw_set_infoframes(struct drm_encoder *encoder, |
809 | bool enable, | 806 | bool enable, |
810 | struct drm_display_mode *adjusted_mode) | 807 | const struct drm_display_mode *adjusted_mode) |
811 | { | 808 | { |
812 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | 809 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
813 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 810 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
@@ -844,7 +841,7 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder) | |||
844 | struct drm_i915_private *dev_priv = dev->dev_private; | 841 | struct drm_i915_private *dev_priv = dev->dev_private; |
845 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); | 842 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); |
846 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); | 843 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); |
847 | struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; | 844 | const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; |
848 | u32 hdmi_val; | 845 | u32 hdmi_val; |
849 | 846 | ||
850 | hdmi_val = SDVO_ENCODING_HDMI; | 847 | hdmi_val = SDVO_ENCODING_HDMI; |
@@ -1312,6 +1309,9 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, | |||
1312 | return false; | 1309 | return false; |
1313 | } | 1310 | } |
1314 | 1311 | ||
1312 | /* Set user selected PAR to incoming mode's member */ | ||
1313 | adjusted_mode->picture_aspect_ratio = intel_hdmi->aspect_ratio; | ||
1314 | |||
1315 | return true; | 1315 | return true; |
1316 | } | 1316 | } |
1317 | 1317 | ||
@@ -1537,8 +1537,7 @@ static void intel_hdmi_pre_enable(struct intel_encoder *encoder) | |||
1537 | { | 1537 | { |
1538 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); | 1538 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); |
1539 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); | 1539 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
1540 | struct drm_display_mode *adjusted_mode = | 1540 | const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode; |
1541 | &intel_crtc->config->base.adjusted_mode; | ||
1542 | 1541 | ||
1543 | intel_hdmi_prepare(encoder); | 1542 | intel_hdmi_prepare(encoder); |
1544 | 1543 | ||
@@ -1555,8 +1554,7 @@ static void vlv_hdmi_pre_enable(struct intel_encoder *encoder) | |||
1555 | struct drm_i915_private *dev_priv = dev->dev_private; | 1554 | struct drm_i915_private *dev_priv = dev->dev_private; |
1556 | struct intel_crtc *intel_crtc = | 1555 | struct intel_crtc *intel_crtc = |
1557 | to_intel_crtc(encoder->base.crtc); | 1556 | to_intel_crtc(encoder->base.crtc); |
1558 | struct drm_display_mode *adjusted_mode = | 1557 | const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode; |
1559 | &intel_crtc->config->base.adjusted_mode; | ||
1560 | enum dpio_channel port = vlv_dport_to_channel(dport); | 1558 | enum dpio_channel port = vlv_dport_to_channel(dport); |
1561 | int pipe = intel_crtc->pipe; | 1559 | int pipe = intel_crtc->pipe; |
1562 | u32 val; | 1560 | u32 val; |
@@ -1822,8 +1820,7 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder) | |||
1822 | struct drm_i915_private *dev_priv = dev->dev_private; | 1820 | struct drm_i915_private *dev_priv = dev->dev_private; |
1823 | struct intel_crtc *intel_crtc = | 1821 | struct intel_crtc *intel_crtc = |
1824 | to_intel_crtc(encoder->base.crtc); | 1822 | to_intel_crtc(encoder->base.crtc); |
1825 | struct drm_display_mode *adjusted_mode = | 1823 | const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode; |
1826 | &intel_crtc->config->base.adjusted_mode; | ||
1827 | enum dpio_channel ch = vlv_dport_to_channel(dport); | 1824 | enum dpio_channel ch = vlv_dport_to_channel(dport); |
1828 | int pipe = intel_crtc->pipe; | 1825 | int pipe = intel_crtc->pipe; |
1829 | int data, i, stagger; | 1826 | int data, i, stagger; |
@@ -1955,11 +1952,6 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder) | |||
1955 | val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3; | 1952 | val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3; |
1956 | vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val); | 1953 | vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val); |
1957 | 1954 | ||
1958 | /* LRC Bypass */ | ||
1959 | val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW30); | ||
1960 | val |= DPIO_LRC_BYPASS; | ||
1961 | vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW30, val); | ||
1962 | |||
1963 | mutex_unlock(&dev_priv->sb_lock); | 1955 | mutex_unlock(&dev_priv->sb_lock); |
1964 | 1956 | ||
1965 | intel_hdmi->set_infoframes(&encoder->base, | 1957 | intel_hdmi->set_infoframes(&encoder->base, |
@@ -2007,15 +1999,6 @@ static const struct drm_encoder_funcs intel_hdmi_enc_funcs = { | |||
2007 | }; | 1999 | }; |
2008 | 2000 | ||
2009 | static void | 2001 | static void |
2010 | intel_attach_aspect_ratio_property(struct drm_connector *connector) | ||
2011 | { | ||
2012 | if (!drm_mode_create_aspect_ratio_property(connector->dev)) | ||
2013 | drm_object_attach_property(&connector->base, | ||
2014 | connector->dev->mode_config.aspect_ratio_property, | ||
2015 | DRM_MODE_PICTURE_ASPECT_NONE); | ||
2016 | } | ||
2017 | |||
2018 | static void | ||
2019 | intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector) | 2002 | intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector) |
2020 | { | 2003 | { |
2021 | intel_attach_force_audio_property(connector); | 2004 | intel_attach_force_audio_property(connector); |
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 825fa7a8df86..efb704ba248b 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c | |||
@@ -904,21 +904,6 @@ int intel_execlists_submission(struct i915_execbuffer_params *params, | |||
904 | return -EINVAL; | 904 | return -EINVAL; |
905 | } | 905 | } |
906 | 906 | ||
907 | if (args->num_cliprects != 0) { | ||
908 | DRM_DEBUG("clip rectangles are only valid on pre-gen5\n"); | ||
909 | return -EINVAL; | ||
910 | } else { | ||
911 | if (args->DR4 == 0xffffffff) { | ||
912 | DRM_DEBUG("UXA submitting garbage DR4, fixing up\n"); | ||
913 | args->DR4 = 0; | ||
914 | } | ||
915 | |||
916 | if (args->DR1 || args->DR4 || args->cliprects_ptr) { | ||
917 | DRM_DEBUG("0 cliprects but dirt in cliprects fields\n"); | ||
918 | return -EINVAL; | ||
919 | } | ||
920 | } | ||
921 | |||
922 | if (args->flags & I915_EXEC_GEN7_SOL_RESET) { | 907 | if (args->flags & I915_EXEC_GEN7_SOL_RESET) { |
923 | DRM_DEBUG("sol reset is gen7 only\n"); | 908 | DRM_DEBUG("sol reset is gen7 only\n"); |
924 | return -EINVAL; | 909 | return -EINVAL; |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 2c2d1f0737c8..5e70acf944c3 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -139,8 +139,7 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder) | |||
139 | struct drm_device *dev = encoder->base.dev; | 139 | struct drm_device *dev = encoder->base.dev; |
140 | struct drm_i915_private *dev_priv = dev->dev_private; | 140 | struct drm_i915_private *dev_priv = dev->dev_private; |
141 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); | 141 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); |
142 | const struct drm_display_mode *adjusted_mode = | 142 | const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; |
143 | &crtc->config->base.adjusted_mode; | ||
144 | int pipe = crtc->pipe; | 143 | int pipe = crtc->pipe; |
145 | u32 temp; | 144 | u32 temp; |
146 | 145 | ||
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 0e860f39933d..38a4c8ce7e63 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c | |||
@@ -126,3 +126,12 @@ intel_attach_broadcast_rgb_property(struct drm_connector *connector) | |||
126 | 126 | ||
127 | drm_object_attach_property(&connector->base, prop, 0); | 127 | drm_object_attach_property(&connector->base, prop, 0); |
128 | } | 128 | } |
129 | |||
130 | void | ||
131 | intel_attach_aspect_ratio_property(struct drm_connector *connector) | ||
132 | { | ||
133 | if (!drm_mode_create_aspect_ratio_property(connector->dev)) | ||
134 | drm_object_attach_property(&connector->base, | ||
135 | connector->dev->mode_config.aspect_ratio_property, | ||
136 | DRM_MODE_PICTURE_ASPECT_NONE); | ||
137 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index cb1c65739425..b706b4e750da 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c | |||
@@ -341,8 +341,12 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, | |||
341 | if (!HAS_DDI(dev)) | 341 | if (!HAS_DDI(dev)) |
342 | return 0; | 342 | return 0; |
343 | 343 | ||
344 | port = intel_ddi_get_encoder_port(intel_encoder); | 344 | if (intel_encoder->type == INTEL_OUTPUT_DSI) |
345 | if (port == PORT_E) { | 345 | port = 0; |
346 | else | ||
347 | port = intel_ddi_get_encoder_port(intel_encoder); | ||
348 | |||
349 | if (port == PORT_E) { | ||
346 | port = 0; | 350 | port = 0; |
347 | } else { | 351 | } else { |
348 | parm |= 1 << port; | 352 | parm |= 1 << port; |
@@ -363,6 +367,7 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, | |||
363 | type = DISPLAY_TYPE_EXTERNAL_FLAT_PANEL; | 367 | type = DISPLAY_TYPE_EXTERNAL_FLAT_PANEL; |
364 | break; | 368 | break; |
365 | case INTEL_OUTPUT_EDP: | 369 | case INTEL_OUTPUT_EDP: |
370 | case INTEL_OUTPUT_DSI: | ||
366 | type = DISPLAY_TYPE_INTERNAL_FLAT_PANEL; | 371 | type = DISPLAY_TYPE_INTERNAL_FLAT_PANEL; |
367 | break; | 372 | break; |
368 | default: | 373 | default: |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 2c11b4eedfc6..f30c996e882c 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -105,59 +105,55 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc, | |||
105 | struct intel_crtc_state *pipe_config, | 105 | struct intel_crtc_state *pipe_config, |
106 | int fitting_mode) | 106 | int fitting_mode) |
107 | { | 107 | { |
108 | struct drm_display_mode *adjusted_mode; | 108 | const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; |
109 | int x, y, width, height; | 109 | int x = 0, y = 0, width = 0, height = 0; |
110 | |||
111 | adjusted_mode = &pipe_config->base.adjusted_mode; | ||
112 | |||
113 | x = y = width = height = 0; | ||
114 | 110 | ||
115 | /* Native modes don't need fitting */ | 111 | /* Native modes don't need fitting */ |
116 | if (adjusted_mode->hdisplay == pipe_config->pipe_src_w && | 112 | if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w && |
117 | adjusted_mode->vdisplay == pipe_config->pipe_src_h) | 113 | adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h) |
118 | goto done; | 114 | goto done; |
119 | 115 | ||
120 | switch (fitting_mode) { | 116 | switch (fitting_mode) { |
121 | case DRM_MODE_SCALE_CENTER: | 117 | case DRM_MODE_SCALE_CENTER: |
122 | width = pipe_config->pipe_src_w; | 118 | width = pipe_config->pipe_src_w; |
123 | height = pipe_config->pipe_src_h; | 119 | height = pipe_config->pipe_src_h; |
124 | x = (adjusted_mode->hdisplay - width + 1)/2; | 120 | x = (adjusted_mode->crtc_hdisplay - width + 1)/2; |
125 | y = (adjusted_mode->vdisplay - height + 1)/2; | 121 | y = (adjusted_mode->crtc_vdisplay - height + 1)/2; |
126 | break; | 122 | break; |
127 | 123 | ||
128 | case DRM_MODE_SCALE_ASPECT: | 124 | case DRM_MODE_SCALE_ASPECT: |
129 | /* Scale but preserve the aspect ratio */ | 125 | /* Scale but preserve the aspect ratio */ |
130 | { | 126 | { |
131 | u32 scaled_width = adjusted_mode->hdisplay | 127 | u32 scaled_width = adjusted_mode->crtc_hdisplay |
132 | * pipe_config->pipe_src_h; | 128 | * pipe_config->pipe_src_h; |
133 | u32 scaled_height = pipe_config->pipe_src_w | 129 | u32 scaled_height = pipe_config->pipe_src_w |
134 | * adjusted_mode->vdisplay; | 130 | * adjusted_mode->crtc_vdisplay; |
135 | if (scaled_width > scaled_height) { /* pillar */ | 131 | if (scaled_width > scaled_height) { /* pillar */ |
136 | width = scaled_height / pipe_config->pipe_src_h; | 132 | width = scaled_height / pipe_config->pipe_src_h; |
137 | if (width & 1) | 133 | if (width & 1) |
138 | width++; | 134 | width++; |
139 | x = (adjusted_mode->hdisplay - width + 1) / 2; | 135 | x = (adjusted_mode->crtc_hdisplay - width + 1) / 2; |
140 | y = 0; | 136 | y = 0; |
141 | height = adjusted_mode->vdisplay; | 137 | height = adjusted_mode->crtc_vdisplay; |
142 | } else if (scaled_width < scaled_height) { /* letter */ | 138 | } else if (scaled_width < scaled_height) { /* letter */ |
143 | height = scaled_width / pipe_config->pipe_src_w; | 139 | height = scaled_width / pipe_config->pipe_src_w; |
144 | if (height & 1) | 140 | if (height & 1) |
145 | height++; | 141 | height++; |
146 | y = (adjusted_mode->vdisplay - height + 1) / 2; | 142 | y = (adjusted_mode->crtc_vdisplay - height + 1) / 2; |
147 | x = 0; | 143 | x = 0; |
148 | width = adjusted_mode->hdisplay; | 144 | width = adjusted_mode->crtc_hdisplay; |
149 | } else { | 145 | } else { |
150 | x = y = 0; | 146 | x = y = 0; |
151 | width = adjusted_mode->hdisplay; | 147 | width = adjusted_mode->crtc_hdisplay; |
152 | height = adjusted_mode->vdisplay; | 148 | height = adjusted_mode->crtc_vdisplay; |
153 | } | 149 | } |
154 | } | 150 | } |
155 | break; | 151 | break; |
156 | 152 | ||
157 | case DRM_MODE_SCALE_FULLSCREEN: | 153 | case DRM_MODE_SCALE_FULLSCREEN: |
158 | x = y = 0; | 154 | x = y = 0; |
159 | width = adjusted_mode->hdisplay; | 155 | width = adjusted_mode->crtc_hdisplay; |
160 | height = adjusted_mode->vdisplay; | 156 | height = adjusted_mode->crtc_vdisplay; |
161 | break; | 157 | break; |
162 | 158 | ||
163 | default: | 159 | default: |
@@ -172,46 +168,46 @@ done: | |||
172 | } | 168 | } |
173 | 169 | ||
174 | static void | 170 | static void |
175 | centre_horizontally(struct drm_display_mode *mode, | 171 | centre_horizontally(struct drm_display_mode *adjusted_mode, |
176 | int width) | 172 | int width) |
177 | { | 173 | { |
178 | u32 border, sync_pos, blank_width, sync_width; | 174 | u32 border, sync_pos, blank_width, sync_width; |
179 | 175 | ||
180 | /* keep the hsync and hblank widths constant */ | 176 | /* keep the hsync and hblank widths constant */ |
181 | sync_width = mode->crtc_hsync_end - mode->crtc_hsync_start; | 177 | sync_width = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; |
182 | blank_width = mode->crtc_hblank_end - mode->crtc_hblank_start; | 178 | blank_width = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start; |
183 | sync_pos = (blank_width - sync_width + 1) / 2; | 179 | sync_pos = (blank_width - sync_width + 1) / 2; |
184 | 180 | ||
185 | border = (mode->hdisplay - width + 1) / 2; | 181 | border = (adjusted_mode->crtc_hdisplay - width + 1) / 2; |
186 | border += border & 1; /* make the border even */ | 182 | border += border & 1; /* make the border even */ |
187 | 183 | ||
188 | mode->crtc_hdisplay = width; | 184 | adjusted_mode->crtc_hdisplay = width; |
189 | mode->crtc_hblank_start = width + border; | 185 | adjusted_mode->crtc_hblank_start = width + border; |
190 | mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width; | 186 | adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_hblank_start + blank_width; |
191 | 187 | ||
192 | mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; | 188 | adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hblank_start + sync_pos; |
193 | mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; | 189 | adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + sync_width; |
194 | } | 190 | } |
195 | 191 | ||
196 | static void | 192 | static void |
197 | centre_vertically(struct drm_display_mode *mode, | 193 | centre_vertically(struct drm_display_mode *adjusted_mode, |
198 | int height) | 194 | int height) |
199 | { | 195 | { |
200 | u32 border, sync_pos, blank_width, sync_width; | 196 | u32 border, sync_pos, blank_width, sync_width; |
201 | 197 | ||
202 | /* keep the vsync and vblank widths constant */ | 198 | /* keep the vsync and vblank widths constant */ |
203 | sync_width = mode->crtc_vsync_end - mode->crtc_vsync_start; | 199 | sync_width = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start; |
204 | blank_width = mode->crtc_vblank_end - mode->crtc_vblank_start; | 200 | blank_width = adjusted_mode->crtc_vblank_end - adjusted_mode->crtc_vblank_start; |
205 | sync_pos = (blank_width - sync_width + 1) / 2; | 201 | sync_pos = (blank_width - sync_width + 1) / 2; |
206 | 202 | ||
207 | border = (mode->vdisplay - height + 1) / 2; | 203 | border = (adjusted_mode->crtc_vdisplay - height + 1) / 2; |
208 | 204 | ||
209 | mode->crtc_vdisplay = height; | 205 | adjusted_mode->crtc_vdisplay = height; |
210 | mode->crtc_vblank_start = height + border; | 206 | adjusted_mode->crtc_vblank_start = height + border; |
211 | mode->crtc_vblank_end = mode->crtc_vblank_start + blank_width; | 207 | adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vblank_start + blank_width; |
212 | 208 | ||
213 | mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; | 209 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vblank_start + sync_pos; |
214 | mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; | 210 | adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + sync_width; |
215 | } | 211 | } |
216 | 212 | ||
217 | static inline u32 panel_fitter_scaling(u32 source, u32 target) | 213 | static inline u32 panel_fitter_scaling(u32 source, u32 target) |
@@ -230,11 +226,11 @@ static inline u32 panel_fitter_scaling(u32 source, u32 target) | |||
230 | static void i965_scale_aspect(struct intel_crtc_state *pipe_config, | 226 | static void i965_scale_aspect(struct intel_crtc_state *pipe_config, |
231 | u32 *pfit_control) | 227 | u32 *pfit_control) |
232 | { | 228 | { |
233 | struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; | 229 | const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; |
234 | u32 scaled_width = adjusted_mode->hdisplay * | 230 | u32 scaled_width = adjusted_mode->crtc_hdisplay * |
235 | pipe_config->pipe_src_h; | 231 | pipe_config->pipe_src_h; |
236 | u32 scaled_height = pipe_config->pipe_src_w * | 232 | u32 scaled_height = pipe_config->pipe_src_w * |
237 | adjusted_mode->vdisplay; | 233 | adjusted_mode->crtc_vdisplay; |
238 | 234 | ||
239 | /* 965+ is easy, it does everything in hw */ | 235 | /* 965+ is easy, it does everything in hw */ |
240 | if (scaled_width > scaled_height) | 236 | if (scaled_width > scaled_height) |
@@ -243,7 +239,7 @@ static void i965_scale_aspect(struct intel_crtc_state *pipe_config, | |||
243 | else if (scaled_width < scaled_height) | 239 | else if (scaled_width < scaled_height) |
244 | *pfit_control |= PFIT_ENABLE | | 240 | *pfit_control |= PFIT_ENABLE | |
245 | PFIT_SCALING_LETTER; | 241 | PFIT_SCALING_LETTER; |
246 | else if (adjusted_mode->hdisplay != pipe_config->pipe_src_w) | 242 | else if (adjusted_mode->crtc_hdisplay != pipe_config->pipe_src_w) |
247 | *pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO; | 243 | *pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO; |
248 | } | 244 | } |
249 | 245 | ||
@@ -252,10 +248,10 @@ static void i9xx_scale_aspect(struct intel_crtc_state *pipe_config, | |||
252 | u32 *border) | 248 | u32 *border) |
253 | { | 249 | { |
254 | struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; | 250 | struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; |
255 | u32 scaled_width = adjusted_mode->hdisplay * | 251 | u32 scaled_width = adjusted_mode->crtc_hdisplay * |
256 | pipe_config->pipe_src_h; | 252 | pipe_config->pipe_src_h; |
257 | u32 scaled_height = pipe_config->pipe_src_w * | 253 | u32 scaled_height = pipe_config->pipe_src_w * |
258 | adjusted_mode->vdisplay; | 254 | adjusted_mode->crtc_vdisplay; |
259 | u32 bits; | 255 | u32 bits; |
260 | 256 | ||
261 | /* | 257 | /* |
@@ -269,9 +265,9 @@ static void i9xx_scale_aspect(struct intel_crtc_state *pipe_config, | |||
269 | pipe_config->pipe_src_h); | 265 | pipe_config->pipe_src_h); |
270 | 266 | ||
271 | *border = LVDS_BORDER_ENABLE; | 267 | *border = LVDS_BORDER_ENABLE; |
272 | if (pipe_config->pipe_src_h != adjusted_mode->vdisplay) { | 268 | if (pipe_config->pipe_src_h != adjusted_mode->crtc_vdisplay) { |
273 | bits = panel_fitter_scaling(pipe_config->pipe_src_h, | 269 | bits = panel_fitter_scaling(pipe_config->pipe_src_h, |
274 | adjusted_mode->vdisplay); | 270 | adjusted_mode->crtc_vdisplay); |
275 | 271 | ||
276 | *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | | 272 | *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | |
277 | bits << PFIT_VERT_SCALE_SHIFT); | 273 | bits << PFIT_VERT_SCALE_SHIFT); |
@@ -285,9 +281,9 @@ static void i9xx_scale_aspect(struct intel_crtc_state *pipe_config, | |||
285 | pipe_config->pipe_src_w); | 281 | pipe_config->pipe_src_w); |
286 | 282 | ||
287 | *border = LVDS_BORDER_ENABLE; | 283 | *border = LVDS_BORDER_ENABLE; |
288 | if (pipe_config->pipe_src_w != adjusted_mode->hdisplay) { | 284 | if (pipe_config->pipe_src_w != adjusted_mode->crtc_hdisplay) { |
289 | bits = panel_fitter_scaling(pipe_config->pipe_src_w, | 285 | bits = panel_fitter_scaling(pipe_config->pipe_src_w, |
290 | adjusted_mode->hdisplay); | 286 | adjusted_mode->crtc_hdisplay); |
291 | 287 | ||
292 | *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | | 288 | *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | |
293 | bits << PFIT_VERT_SCALE_SHIFT); | 289 | bits << PFIT_VERT_SCALE_SHIFT); |
@@ -310,13 +306,11 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, | |||
310 | { | 306 | { |
311 | struct drm_device *dev = intel_crtc->base.dev; | 307 | struct drm_device *dev = intel_crtc->base.dev; |
312 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; | 308 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; |
313 | struct drm_display_mode *adjusted_mode; | 309 | struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; |
314 | |||
315 | adjusted_mode = &pipe_config->base.adjusted_mode; | ||
316 | 310 | ||
317 | /* Native modes don't need fitting */ | 311 | /* Native modes don't need fitting */ |
318 | if (adjusted_mode->hdisplay == pipe_config->pipe_src_w && | 312 | if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w && |
319 | adjusted_mode->vdisplay == pipe_config->pipe_src_h) | 313 | adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h) |
320 | goto out; | 314 | goto out; |
321 | 315 | ||
322 | switch (fitting_mode) { | 316 | switch (fitting_mode) { |
@@ -342,8 +336,8 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, | |||
342 | * Full scaling, even if it changes the aspect ratio. | 336 | * Full scaling, even if it changes the aspect ratio. |
343 | * Fortunately this is all done for us in hw. | 337 | * Fortunately this is all done for us in hw. |
344 | */ | 338 | */ |
345 | if (pipe_config->pipe_src_h != adjusted_mode->vdisplay || | 339 | if (pipe_config->pipe_src_h != adjusted_mode->crtc_vdisplay || |
346 | pipe_config->pipe_src_w != adjusted_mode->hdisplay) { | 340 | pipe_config->pipe_src_w != adjusted_mode->crtc_hdisplay) { |
347 | pfit_control |= PFIT_ENABLE; | 341 | pfit_control |= PFIT_ENABLE; |
348 | if (INTEL_INFO(dev)->gen >= 4) | 342 | if (INTEL_INFO(dev)->gen >= 4) |
349 | pfit_control |= PFIT_SCALING_AUTO; | 343 | pfit_control |= PFIT_SCALING_AUTO; |
@@ -542,9 +536,10 @@ static u32 vlv_get_backlight(struct intel_connector *connector) | |||
542 | static u32 bxt_get_backlight(struct intel_connector *connector) | 536 | static u32 bxt_get_backlight(struct intel_connector *connector) |
543 | { | 537 | { |
544 | struct drm_device *dev = connector->base.dev; | 538 | struct drm_device *dev = connector->base.dev; |
539 | struct intel_panel *panel = &connector->panel; | ||
545 | struct drm_i915_private *dev_priv = dev->dev_private; | 540 | struct drm_i915_private *dev_priv = dev->dev_private; |
546 | 541 | ||
547 | return I915_READ(BXT_BLC_PWM_DUTY1); | 542 | return I915_READ(BXT_BLC_PWM_DUTY(panel->backlight.controller)); |
548 | } | 543 | } |
549 | 544 | ||
550 | static u32 pwm_get_backlight(struct intel_connector *connector) | 545 | static u32 pwm_get_backlight(struct intel_connector *connector) |
@@ -566,7 +561,7 @@ static u32 intel_panel_get_backlight(struct intel_connector *connector) | |||
566 | mutex_lock(&dev_priv->backlight_lock); | 561 | mutex_lock(&dev_priv->backlight_lock); |
567 | 562 | ||
568 | if (panel->backlight.enabled) { | 563 | if (panel->backlight.enabled) { |
569 | val = dev_priv->display.get_backlight(connector); | 564 | val = panel->backlight.get(connector); |
570 | val = intel_panel_compute_brightness(connector, val); | 565 | val = intel_panel_compute_brightness(connector, val); |
571 | } | 566 | } |
572 | 567 | ||
@@ -640,8 +635,9 @@ static void bxt_set_backlight(struct intel_connector *connector, u32 level) | |||
640 | { | 635 | { |
641 | struct drm_device *dev = connector->base.dev; | 636 | struct drm_device *dev = connector->base.dev; |
642 | struct drm_i915_private *dev_priv = dev->dev_private; | 637 | struct drm_i915_private *dev_priv = dev->dev_private; |
638 | struct intel_panel *panel = &connector->panel; | ||
643 | 639 | ||
644 | I915_WRITE(BXT_BLC_PWM_DUTY1, level); | 640 | I915_WRITE(BXT_BLC_PWM_DUTY(panel->backlight.controller), level); |
645 | } | 641 | } |
646 | 642 | ||
647 | static void pwm_set_backlight(struct intel_connector *connector, u32 level) | 643 | static void pwm_set_backlight(struct intel_connector *connector, u32 level) |
@@ -655,13 +651,12 @@ static void pwm_set_backlight(struct intel_connector *connector, u32 level) | |||
655 | static void | 651 | static void |
656 | intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level) | 652 | intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level) |
657 | { | 653 | { |
658 | struct drm_device *dev = connector->base.dev; | 654 | struct intel_panel *panel = &connector->panel; |
659 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
660 | 655 | ||
661 | DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level); | 656 | DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level); |
662 | 657 | ||
663 | level = intel_panel_compute_brightness(connector, level); | 658 | level = intel_panel_compute_brightness(connector, level); |
664 | dev_priv->display.set_backlight(connector, level); | 659 | panel->backlight.set(connector, level); |
665 | } | 660 | } |
666 | 661 | ||
667 | /* set backlight brightness to level in range [0..max], scaling wrt hw min */ | 662 | /* set backlight brightness to level in range [0..max], scaling wrt hw min */ |
@@ -793,12 +788,20 @@ static void bxt_disable_backlight(struct intel_connector *connector) | |||
793 | { | 788 | { |
794 | struct drm_device *dev = connector->base.dev; | 789 | struct drm_device *dev = connector->base.dev; |
795 | struct drm_i915_private *dev_priv = dev->dev_private; | 790 | struct drm_i915_private *dev_priv = dev->dev_private; |
796 | u32 tmp; | 791 | struct intel_panel *panel = &connector->panel; |
792 | u32 tmp, val; | ||
797 | 793 | ||
798 | intel_panel_actually_set_backlight(connector, 0); | 794 | intel_panel_actually_set_backlight(connector, 0); |
799 | 795 | ||
800 | tmp = I915_READ(BXT_BLC_PWM_CTL1); | 796 | tmp = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller)); |
801 | I915_WRITE(BXT_BLC_PWM_CTL1, tmp & ~BXT_BLC_PWM_ENABLE); | 797 | I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), |
798 | tmp & ~BXT_BLC_PWM_ENABLE); | ||
799 | |||
800 | if (panel->backlight.controller == 1) { | ||
801 | val = I915_READ(UTIL_PIN_CTL); | ||
802 | val &= ~UTIL_PIN_ENABLE; | ||
803 | I915_WRITE(UTIL_PIN_CTL, val); | ||
804 | } | ||
802 | } | 805 | } |
803 | 806 | ||
804 | static void pwm_disable_backlight(struct intel_connector *connector) | 807 | static void pwm_disable_backlight(struct intel_connector *connector) |
@@ -836,7 +839,7 @@ void intel_panel_disable_backlight(struct intel_connector *connector) | |||
836 | if (panel->backlight.device) | 839 | if (panel->backlight.device) |
837 | panel->backlight.device->props.power = FB_BLANK_POWERDOWN; | 840 | panel->backlight.device->props.power = FB_BLANK_POWERDOWN; |
838 | panel->backlight.enabled = false; | 841 | panel->backlight.enabled = false; |
839 | dev_priv->display.disable_backlight(connector); | 842 | panel->backlight.disable(connector); |
840 | 843 | ||
841 | mutex_unlock(&dev_priv->backlight_lock); | 844 | mutex_unlock(&dev_priv->backlight_lock); |
842 | } | 845 | } |
@@ -1030,16 +1033,38 @@ static void bxt_enable_backlight(struct intel_connector *connector) | |||
1030 | struct drm_device *dev = connector->base.dev; | 1033 | struct drm_device *dev = connector->base.dev; |
1031 | struct drm_i915_private *dev_priv = dev->dev_private; | 1034 | struct drm_i915_private *dev_priv = dev->dev_private; |
1032 | struct intel_panel *panel = &connector->panel; | 1035 | struct intel_panel *panel = &connector->panel; |
1033 | u32 pwm_ctl; | 1036 | enum pipe pipe = intel_get_pipe_from_connector(connector); |
1037 | u32 pwm_ctl, val; | ||
1038 | |||
1039 | /* To use 2nd set of backlight registers, utility pin has to be | ||
1040 | * enabled with PWM mode. | ||
1041 | * The field should only be changed when the utility pin is disabled | ||
1042 | */ | ||
1043 | if (panel->backlight.controller == 1) { | ||
1044 | val = I915_READ(UTIL_PIN_CTL); | ||
1045 | if (val & UTIL_PIN_ENABLE) { | ||
1046 | DRM_DEBUG_KMS("util pin already enabled\n"); | ||
1047 | val &= ~UTIL_PIN_ENABLE; | ||
1048 | I915_WRITE(UTIL_PIN_CTL, val); | ||
1049 | } | ||
1050 | |||
1051 | val = 0; | ||
1052 | if (panel->backlight.util_pin_active_low) | ||
1053 | val |= UTIL_PIN_POLARITY; | ||
1054 | I915_WRITE(UTIL_PIN_CTL, val | UTIL_PIN_PIPE(pipe) | | ||
1055 | UTIL_PIN_MODE_PWM | UTIL_PIN_ENABLE); | ||
1056 | } | ||
1034 | 1057 | ||
1035 | pwm_ctl = I915_READ(BXT_BLC_PWM_CTL1); | 1058 | pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller)); |
1036 | if (pwm_ctl & BXT_BLC_PWM_ENABLE) { | 1059 | if (pwm_ctl & BXT_BLC_PWM_ENABLE) { |
1037 | DRM_DEBUG_KMS("backlight already enabled\n"); | 1060 | DRM_DEBUG_KMS("backlight already enabled\n"); |
1038 | pwm_ctl &= ~BXT_BLC_PWM_ENABLE; | 1061 | pwm_ctl &= ~BXT_BLC_PWM_ENABLE; |
1039 | I915_WRITE(BXT_BLC_PWM_CTL1, pwm_ctl); | 1062 | I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), |
1063 | pwm_ctl); | ||
1040 | } | 1064 | } |
1041 | 1065 | ||
1042 | I915_WRITE(BXT_BLC_PWM_FREQ1, panel->backlight.max); | 1066 | I915_WRITE(BXT_BLC_PWM_FREQ(panel->backlight.controller), |
1067 | panel->backlight.max); | ||
1043 | 1068 | ||
1044 | intel_panel_actually_set_backlight(connector, panel->backlight.level); | 1069 | intel_panel_actually_set_backlight(connector, panel->backlight.level); |
1045 | 1070 | ||
@@ -1047,9 +1072,10 @@ static void bxt_enable_backlight(struct intel_connector *connector) | |||
1047 | if (panel->backlight.active_low_pwm) | 1072 | if (panel->backlight.active_low_pwm) |
1048 | pwm_ctl |= BXT_BLC_PWM_POLARITY; | 1073 | pwm_ctl |= BXT_BLC_PWM_POLARITY; |
1049 | 1074 | ||
1050 | I915_WRITE(BXT_BLC_PWM_CTL1, pwm_ctl); | 1075 | I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), pwm_ctl); |
1051 | POSTING_READ(BXT_BLC_PWM_CTL1); | 1076 | POSTING_READ(BXT_BLC_PWM_CTL(panel->backlight.controller)); |
1052 | I915_WRITE(BXT_BLC_PWM_CTL1, pwm_ctl | BXT_BLC_PWM_ENABLE); | 1077 | I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), |
1078 | pwm_ctl | BXT_BLC_PWM_ENABLE); | ||
1053 | } | 1079 | } |
1054 | 1080 | ||
1055 | static void pwm_enable_backlight(struct intel_connector *connector) | 1081 | static void pwm_enable_backlight(struct intel_connector *connector) |
@@ -1085,7 +1111,7 @@ void intel_panel_enable_backlight(struct intel_connector *connector) | |||
1085 | panel->backlight.device->props.max_brightness); | 1111 | panel->backlight.device->props.max_brightness); |
1086 | } | 1112 | } |
1087 | 1113 | ||
1088 | dev_priv->display.enable_backlight(connector); | 1114 | panel->backlight.enable(connector); |
1089 | panel->backlight.enabled = true; | 1115 | panel->backlight.enabled = true; |
1090 | if (panel->backlight.device) | 1116 | if (panel->backlight.device) |
1091 | panel->backlight.device->props.power = FB_BLANK_UNBLANK; | 1117 | panel->backlight.device->props.power = FB_BLANK_UNBLANK; |
@@ -1113,10 +1139,10 @@ static int intel_backlight_device_update_status(struct backlight_device *bd) | |||
1113 | * callback needs to take this into account. | 1139 | * callback needs to take this into account. |
1114 | */ | 1140 | */ |
1115 | if (panel->backlight.enabled) { | 1141 | if (panel->backlight.enabled) { |
1116 | if (panel->backlight_power) { | 1142 | if (panel->backlight.power) { |
1117 | bool enable = bd->props.power == FB_BLANK_UNBLANK && | 1143 | bool enable = bd->props.power == FB_BLANK_UNBLANK && |
1118 | bd->props.brightness != 0; | 1144 | bd->props.brightness != 0; |
1119 | panel->backlight_power(connector, enable); | 1145 | panel->backlight.power(connector, enable); |
1120 | } | 1146 | } |
1121 | } else { | 1147 | } else { |
1122 | bd->props.power = FB_BLANK_POWERDOWN; | 1148 | bd->props.power = FB_BLANK_POWERDOWN; |
@@ -1341,6 +1367,7 @@ static u32 get_backlight_max_vbt(struct intel_connector *connector) | |||
1341 | { | 1367 | { |
1342 | struct drm_device *dev = connector->base.dev; | 1368 | struct drm_device *dev = connector->base.dev; |
1343 | struct drm_i915_private *dev_priv = dev->dev_private; | 1369 | struct drm_i915_private *dev_priv = dev->dev_private; |
1370 | struct intel_panel *panel = &connector->panel; | ||
1344 | u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz; | 1371 | u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz; |
1345 | u32 pwm; | 1372 | u32 pwm; |
1346 | 1373 | ||
@@ -1349,12 +1376,12 @@ static u32 get_backlight_max_vbt(struct intel_connector *connector) | |||
1349 | return 0; | 1376 | return 0; |
1350 | } | 1377 | } |
1351 | 1378 | ||
1352 | if (!dev_priv->display.backlight_hz_to_pwm) { | 1379 | if (!panel->backlight.hz_to_pwm) { |
1353 | DRM_DEBUG_KMS("backlight frequency setting from VBT currently not supported on this platform\n"); | 1380 | DRM_DEBUG_KMS("backlight frequency setting from VBT currently not supported on this platform\n"); |
1354 | return 0; | 1381 | return 0; |
1355 | } | 1382 | } |
1356 | 1383 | ||
1357 | pwm = dev_priv->display.backlight_hz_to_pwm(connector, pwm_freq_hz); | 1384 | pwm = panel->backlight.hz_to_pwm(connector, pwm_freq_hz); |
1358 | if (!pwm) { | 1385 | if (!pwm) { |
1359 | DRM_DEBUG_KMS("backlight frequency conversion failed\n"); | 1386 | DRM_DEBUG_KMS("backlight frequency conversion failed\n"); |
1360 | return 0; | 1387 | return 0; |
@@ -1568,10 +1595,28 @@ bxt_setup_backlight(struct intel_connector *connector, enum pipe unused) | |||
1568 | struct intel_panel *panel = &connector->panel; | 1595 | struct intel_panel *panel = &connector->panel; |
1569 | u32 pwm_ctl, val; | 1596 | u32 pwm_ctl, val; |
1570 | 1597 | ||
1571 | pwm_ctl = I915_READ(BXT_BLC_PWM_CTL1); | 1598 | /* |
1572 | panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY; | 1599 | * For BXT hard coding the Backlight controller to 0. |
1600 | * TODO : Read the controller value from VBT and generalize | ||
1601 | */ | ||
1602 | panel->backlight.controller = 0; | ||
1603 | |||
1604 | pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller)); | ||
1605 | |||
1606 | /* Keeping the check if controller 1 is to be programmed. | ||
1607 | * This will come into affect once the VBT parsing | ||
1608 | * is fixed for controller selection, and controller 1 is used | ||
1609 | * for a prticular display configuration. | ||
1610 | */ | ||
1611 | if (panel->backlight.controller == 1) { | ||
1612 | val = I915_READ(UTIL_PIN_CTL); | ||
1613 | panel->backlight.util_pin_active_low = | ||
1614 | val & UTIL_PIN_POLARITY; | ||
1615 | } | ||
1573 | 1616 | ||
1574 | panel->backlight.max = I915_READ(BXT_BLC_PWM_FREQ1); | 1617 | panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY; |
1618 | panel->backlight.max = | ||
1619 | I915_READ(BXT_BLC_PWM_FREQ(panel->backlight.controller)); | ||
1575 | 1620 | ||
1576 | if (!panel->backlight.max) | 1621 | if (!panel->backlight.max) |
1577 | panel->backlight.max = get_backlight_max_vbt(connector); | 1622 | panel->backlight.max = get_backlight_max_vbt(connector); |
@@ -1639,9 +1684,13 @@ int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe) | |||
1639 | } | 1684 | } |
1640 | } | 1685 | } |
1641 | 1686 | ||
1687 | /* ensure intel_panel has been initialized first */ | ||
1688 | if (WARN_ON(!panel->backlight.setup)) | ||
1689 | return -ENODEV; | ||
1690 | |||
1642 | /* set level and max in panel struct */ | 1691 | /* set level and max in panel struct */ |
1643 | mutex_lock(&dev_priv->backlight_lock); | 1692 | mutex_lock(&dev_priv->backlight_lock); |
1644 | ret = dev_priv->display.setup_backlight(intel_connector, pipe); | 1693 | ret = panel->backlight.setup(intel_connector, pipe); |
1645 | mutex_unlock(&dev_priv->backlight_lock); | 1694 | mutex_unlock(&dev_priv->backlight_lock); |
1646 | 1695 | ||
1647 | if (ret) { | 1696 | if (ret) { |
@@ -1673,62 +1722,66 @@ void intel_panel_destroy_backlight(struct drm_connector *connector) | |||
1673 | } | 1722 | } |
1674 | 1723 | ||
1675 | /* Set up chip specific backlight functions */ | 1724 | /* Set up chip specific backlight functions */ |
1676 | void intel_panel_init_backlight_funcs(struct drm_device *dev) | 1725 | static void |
1726 | intel_panel_init_backlight_funcs(struct intel_panel *panel) | ||
1677 | { | 1727 | { |
1728 | struct intel_connector *intel_connector = | ||
1729 | container_of(panel, struct intel_connector, panel); | ||
1730 | struct drm_device *dev = intel_connector->base.dev; | ||
1678 | struct drm_i915_private *dev_priv = dev->dev_private; | 1731 | struct drm_i915_private *dev_priv = dev->dev_private; |
1679 | 1732 | ||
1680 | if (IS_BROXTON(dev)) { | 1733 | if (IS_BROXTON(dev)) { |
1681 | dev_priv->display.setup_backlight = bxt_setup_backlight; | 1734 | panel->backlight.setup = bxt_setup_backlight; |
1682 | dev_priv->display.enable_backlight = bxt_enable_backlight; | 1735 | panel->backlight.enable = bxt_enable_backlight; |
1683 | dev_priv->display.disable_backlight = bxt_disable_backlight; | 1736 | panel->backlight.disable = bxt_disable_backlight; |
1684 | dev_priv->display.set_backlight = bxt_set_backlight; | 1737 | panel->backlight.set = bxt_set_backlight; |
1685 | dev_priv->display.get_backlight = bxt_get_backlight; | 1738 | panel->backlight.get = bxt_get_backlight; |
1686 | } else if (HAS_PCH_LPT(dev) || HAS_PCH_SPT(dev)) { | 1739 | } else if (HAS_PCH_LPT(dev) || HAS_PCH_SPT(dev)) { |
1687 | dev_priv->display.setup_backlight = lpt_setup_backlight; | 1740 | panel->backlight.setup = lpt_setup_backlight; |
1688 | dev_priv->display.enable_backlight = lpt_enable_backlight; | 1741 | panel->backlight.enable = lpt_enable_backlight; |
1689 | dev_priv->display.disable_backlight = lpt_disable_backlight; | 1742 | panel->backlight.disable = lpt_disable_backlight; |
1690 | dev_priv->display.set_backlight = lpt_set_backlight; | 1743 | panel->backlight.set = lpt_set_backlight; |
1691 | dev_priv->display.get_backlight = lpt_get_backlight; | 1744 | panel->backlight.get = lpt_get_backlight; |
1692 | if (HAS_PCH_LPT(dev)) | 1745 | if (HAS_PCH_LPT(dev)) |
1693 | dev_priv->display.backlight_hz_to_pwm = lpt_hz_to_pwm; | 1746 | panel->backlight.hz_to_pwm = lpt_hz_to_pwm; |
1694 | else | 1747 | else |
1695 | dev_priv->display.backlight_hz_to_pwm = spt_hz_to_pwm; | 1748 | panel->backlight.hz_to_pwm = spt_hz_to_pwm; |
1696 | } else if (HAS_PCH_SPLIT(dev)) { | 1749 | } else if (HAS_PCH_SPLIT(dev)) { |
1697 | dev_priv->display.setup_backlight = pch_setup_backlight; | 1750 | panel->backlight.setup = pch_setup_backlight; |
1698 | dev_priv->display.enable_backlight = pch_enable_backlight; | 1751 | panel->backlight.enable = pch_enable_backlight; |
1699 | dev_priv->display.disable_backlight = pch_disable_backlight; | 1752 | panel->backlight.disable = pch_disable_backlight; |
1700 | dev_priv->display.set_backlight = pch_set_backlight; | 1753 | panel->backlight.set = pch_set_backlight; |
1701 | dev_priv->display.get_backlight = pch_get_backlight; | 1754 | panel->backlight.get = pch_get_backlight; |
1702 | dev_priv->display.backlight_hz_to_pwm = pch_hz_to_pwm; | 1755 | panel->backlight.hz_to_pwm = pch_hz_to_pwm; |
1703 | } else if (IS_VALLEYVIEW(dev)) { | 1756 | } else if (IS_VALLEYVIEW(dev)) { |
1704 | if (dev_priv->vbt.has_mipi) { | 1757 | if (dev_priv->vbt.has_mipi) { |
1705 | dev_priv->display.setup_backlight = pwm_setup_backlight; | 1758 | panel->backlight.setup = pwm_setup_backlight; |
1706 | dev_priv->display.enable_backlight = pwm_enable_backlight; | 1759 | panel->backlight.enable = pwm_enable_backlight; |
1707 | dev_priv->display.disable_backlight = pwm_disable_backlight; | 1760 | panel->backlight.disable = pwm_disable_backlight; |
1708 | dev_priv->display.set_backlight = pwm_set_backlight; | 1761 | panel->backlight.set = pwm_set_backlight; |
1709 | dev_priv->display.get_backlight = pwm_get_backlight; | 1762 | panel->backlight.get = pwm_get_backlight; |
1710 | } else { | 1763 | } else { |
1711 | dev_priv->display.setup_backlight = vlv_setup_backlight; | 1764 | panel->backlight.setup = vlv_setup_backlight; |
1712 | dev_priv->display.enable_backlight = vlv_enable_backlight; | 1765 | panel->backlight.enable = vlv_enable_backlight; |
1713 | dev_priv->display.disable_backlight = vlv_disable_backlight; | 1766 | panel->backlight.disable = vlv_disable_backlight; |
1714 | dev_priv->display.set_backlight = vlv_set_backlight; | 1767 | panel->backlight.set = vlv_set_backlight; |
1715 | dev_priv->display.get_backlight = vlv_get_backlight; | 1768 | panel->backlight.get = vlv_get_backlight; |
1716 | dev_priv->display.backlight_hz_to_pwm = vlv_hz_to_pwm; | 1769 | panel->backlight.hz_to_pwm = vlv_hz_to_pwm; |
1717 | } | 1770 | } |
1718 | } else if (IS_GEN4(dev)) { | 1771 | } else if (IS_GEN4(dev)) { |
1719 | dev_priv->display.setup_backlight = i965_setup_backlight; | 1772 | panel->backlight.setup = i965_setup_backlight; |
1720 | dev_priv->display.enable_backlight = i965_enable_backlight; | 1773 | panel->backlight.enable = i965_enable_backlight; |
1721 | dev_priv->display.disable_backlight = i965_disable_backlight; | 1774 | panel->backlight.disable = i965_disable_backlight; |
1722 | dev_priv->display.set_backlight = i9xx_set_backlight; | 1775 | panel->backlight.set = i9xx_set_backlight; |
1723 | dev_priv->display.get_backlight = i9xx_get_backlight; | 1776 | panel->backlight.get = i9xx_get_backlight; |
1724 | dev_priv->display.backlight_hz_to_pwm = i965_hz_to_pwm; | 1777 | panel->backlight.hz_to_pwm = i965_hz_to_pwm; |
1725 | } else { | 1778 | } else { |
1726 | dev_priv->display.setup_backlight = i9xx_setup_backlight; | 1779 | panel->backlight.setup = i9xx_setup_backlight; |
1727 | dev_priv->display.enable_backlight = i9xx_enable_backlight; | 1780 | panel->backlight.enable = i9xx_enable_backlight; |
1728 | dev_priv->display.disable_backlight = i9xx_disable_backlight; | 1781 | panel->backlight.disable = i9xx_disable_backlight; |
1729 | dev_priv->display.set_backlight = i9xx_set_backlight; | 1782 | panel->backlight.set = i9xx_set_backlight; |
1730 | dev_priv->display.get_backlight = i9xx_get_backlight; | 1783 | panel->backlight.get = i9xx_get_backlight; |
1731 | dev_priv->display.backlight_hz_to_pwm = i9xx_hz_to_pwm; | 1784 | panel->backlight.hz_to_pwm = i9xx_hz_to_pwm; |
1732 | } | 1785 | } |
1733 | } | 1786 | } |
1734 | 1787 | ||
@@ -1736,6 +1789,8 @@ int intel_panel_init(struct intel_panel *panel, | |||
1736 | struct drm_display_mode *fixed_mode, | 1789 | struct drm_display_mode *fixed_mode, |
1737 | struct drm_display_mode *downclock_mode) | 1790 | struct drm_display_mode *downclock_mode) |
1738 | { | 1791 | { |
1792 | intel_panel_init_backlight_funcs(panel); | ||
1793 | |||
1739 | panel->fixed_mode = fixed_mode; | 1794 | panel->fixed_mode = fixed_mode; |
1740 | panel->downclock_mode = downclock_mode; | 1795 | panel->downclock_mode = downclock_mode; |
1741 | 1796 | ||
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index ab5ac5ee1825..d031d74abd27 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -71,20 +71,6 @@ static void skl_init_clock_gating(struct drm_device *dev) | |||
71 | 71 | ||
72 | gen9_init_clock_gating(dev); | 72 | gen9_init_clock_gating(dev); |
73 | 73 | ||
74 | if (INTEL_REVID(dev) <= SKL_REVID_B0) { | ||
75 | /* | ||
76 | * WaDisableSDEUnitClockGating:skl | ||
77 | * WaSetGAPSunitClckGateDisable:skl | ||
78 | */ | ||
79 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | | ||
80 | GEN8_GAPSUNIT_CLOCK_GATE_DISABLE | | ||
81 | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); | ||
82 | |||
83 | /* WaDisableVFUnitClockGating:skl */ | ||
84 | I915_WRITE(GEN6_UCGCTL2, I915_READ(GEN6_UCGCTL2) | | ||
85 | GEN6_VFUNIT_CLOCK_GATE_DISABLE); | ||
86 | } | ||
87 | |||
88 | if (INTEL_REVID(dev) <= SKL_REVID_D0) { | 74 | if (INTEL_REVID(dev) <= SKL_REVID_D0) { |
89 | /* WaDisableHDCInvalidation:skl */ | 75 | /* WaDisableHDCInvalidation:skl */ |
90 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | | 76 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | |
@@ -127,13 +113,10 @@ static void bxt_init_clock_gating(struct drm_device *dev) | |||
127 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | | 113 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | |
128 | GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); | 114 | GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); |
129 | 115 | ||
130 | if (INTEL_REVID(dev) == BXT_REVID_A0) { | 116 | /* WaStoreMultiplePTEenable:bxt */ |
131 | /* | 117 | /* This is a requirement according to Hardware specification */ |
132 | * Hardware specification requires this bit to be | 118 | if (INTEL_REVID(dev) == BXT_REVID_A0) |
133 | * set to 1 for A0 | ||
134 | */ | ||
135 | I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF); | 119 | I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF); |
136 | } | ||
137 | 120 | ||
138 | /* WaSetClckGatingDisableMedia:bxt */ | 121 | /* WaSetClckGatingDisableMedia:bxt */ |
139 | if (INTEL_REVID(dev) == BXT_REVID_A0) { | 122 | if (INTEL_REVID(dev) == BXT_REVID_A0) { |
@@ -703,12 +686,9 @@ static void pineview_update_wm(struct drm_crtc *unused_crtc) | |||
703 | 686 | ||
704 | crtc = single_enabled_crtc(dev); | 687 | crtc = single_enabled_crtc(dev); |
705 | if (crtc) { | 688 | if (crtc) { |
706 | const struct drm_display_mode *adjusted_mode; | 689 | const struct drm_display_mode *adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; |
707 | int pixel_size = crtc->primary->state->fb->bits_per_pixel / 8; | 690 | int pixel_size = crtc->primary->state->fb->bits_per_pixel / 8; |
708 | int clock; | 691 | int clock = adjusted_mode->crtc_clock; |
709 | |||
710 | adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; | ||
711 | clock = adjusted_mode->crtc_clock; | ||
712 | 692 | ||
713 | /* Display SR */ | 693 | /* Display SR */ |
714 | wm = intel_calculate_wm(clock, &pineview_display_wm, | 694 | wm = intel_calculate_wm(clock, &pineview_display_wm, |
@@ -1502,8 +1482,7 @@ static void i965_update_wm(struct drm_crtc *unused_crtc) | |||
1502 | if (crtc) { | 1482 | if (crtc) { |
1503 | /* self-refresh has much higher latency */ | 1483 | /* self-refresh has much higher latency */ |
1504 | static const int sr_latency_ns = 12000; | 1484 | static const int sr_latency_ns = 12000; |
1505 | const struct drm_display_mode *adjusted_mode = | 1485 | const struct drm_display_mode *adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; |
1506 | &to_intel_crtc(crtc)->config->base.adjusted_mode; | ||
1507 | int clock = adjusted_mode->crtc_clock; | 1486 | int clock = adjusted_mode->crtc_clock; |
1508 | int htotal = adjusted_mode->crtc_htotal; | 1487 | int htotal = adjusted_mode->crtc_htotal; |
1509 | int hdisplay = to_intel_crtc(crtc)->config->pipe_src_w; | 1488 | int hdisplay = to_intel_crtc(crtc)->config->pipe_src_w; |
@@ -1650,8 +1629,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) | |||
1650 | if (HAS_FW_BLC(dev) && enabled) { | 1629 | if (HAS_FW_BLC(dev) && enabled) { |
1651 | /* self-refresh has much higher latency */ | 1630 | /* self-refresh has much higher latency */ |
1652 | static const int sr_latency_ns = 6000; | 1631 | static const int sr_latency_ns = 6000; |
1653 | const struct drm_display_mode *adjusted_mode = | 1632 | const struct drm_display_mode *adjusted_mode = &to_intel_crtc(enabled)->config->base.adjusted_mode; |
1654 | &to_intel_crtc(enabled)->config->base.adjusted_mode; | ||
1655 | int clock = adjusted_mode->crtc_clock; | 1633 | int clock = adjusted_mode->crtc_clock; |
1656 | int htotal = adjusted_mode->crtc_htotal; | 1634 | int htotal = adjusted_mode->crtc_htotal; |
1657 | int hdisplay = to_intel_crtc(enabled)->config->pipe_src_w; | 1635 | int hdisplay = to_intel_crtc(enabled)->config->pipe_src_w; |
@@ -1787,23 +1765,6 @@ static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels, | |||
1787 | return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2; | 1765 | return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2; |
1788 | } | 1766 | } |
1789 | 1767 | ||
1790 | struct skl_pipe_wm_parameters { | ||
1791 | bool active; | ||
1792 | uint32_t pipe_htotal; | ||
1793 | uint32_t pixel_rate; /* in KHz */ | ||
1794 | struct intel_plane_wm_parameters plane[I915_MAX_PLANES]; | ||
1795 | struct intel_plane_wm_parameters cursor; | ||
1796 | }; | ||
1797 | |||
1798 | struct ilk_pipe_wm_parameters { | ||
1799 | bool active; | ||
1800 | uint32_t pipe_htotal; | ||
1801 | uint32_t pixel_rate; | ||
1802 | struct intel_plane_wm_parameters pri; | ||
1803 | struct intel_plane_wm_parameters spr; | ||
1804 | struct intel_plane_wm_parameters cur; | ||
1805 | }; | ||
1806 | |||
1807 | struct ilk_wm_maximums { | 1768 | struct ilk_wm_maximums { |
1808 | uint16_t pri; | 1769 | uint16_t pri; |
1809 | uint16_t spr; | 1770 | uint16_t spr; |
@@ -1822,26 +1783,26 @@ struct intel_wm_config { | |||
1822 | * For both WM_PIPE and WM_LP. | 1783 | * For both WM_PIPE and WM_LP. |
1823 | * mem_value must be in 0.1us units. | 1784 | * mem_value must be in 0.1us units. |
1824 | */ | 1785 | */ |
1825 | static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params, | 1786 | static uint32_t ilk_compute_pri_wm(const struct intel_crtc_state *cstate, |
1787 | const struct intel_plane_state *pstate, | ||
1826 | uint32_t mem_value, | 1788 | uint32_t mem_value, |
1827 | bool is_lp) | 1789 | bool is_lp) |
1828 | { | 1790 | { |
1791 | int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0; | ||
1829 | uint32_t method1, method2; | 1792 | uint32_t method1, method2; |
1830 | 1793 | ||
1831 | if (!params->active || !params->pri.enabled) | 1794 | if (!cstate->base.active || !pstate->visible) |
1832 | return 0; | 1795 | return 0; |
1833 | 1796 | ||
1834 | method1 = ilk_wm_method1(params->pixel_rate, | 1797 | method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value); |
1835 | params->pri.bytes_per_pixel, | ||
1836 | mem_value); | ||
1837 | 1798 | ||
1838 | if (!is_lp) | 1799 | if (!is_lp) |
1839 | return method1; | 1800 | return method1; |
1840 | 1801 | ||
1841 | method2 = ilk_wm_method2(params->pixel_rate, | 1802 | method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate), |
1842 | params->pipe_htotal, | 1803 | cstate->base.adjusted_mode.crtc_htotal, |
1843 | params->pri.horiz_pixels, | 1804 | drm_rect_width(&pstate->dst), |
1844 | params->pri.bytes_per_pixel, | 1805 | bpp, |
1845 | mem_value); | 1806 | mem_value); |
1846 | 1807 | ||
1847 | return min(method1, method2); | 1808 | return min(method1, method2); |
@@ -1851,21 +1812,21 @@ static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params, | |||
1851 | * For both WM_PIPE and WM_LP. | 1812 | * For both WM_PIPE and WM_LP. |
1852 | * mem_value must be in 0.1us units. | 1813 | * mem_value must be in 0.1us units. |
1853 | */ | 1814 | */ |
1854 | static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params, | 1815 | static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate, |
1816 | const struct intel_plane_state *pstate, | ||
1855 | uint32_t mem_value) | 1817 | uint32_t mem_value) |
1856 | { | 1818 | { |
1819 | int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0; | ||
1857 | uint32_t method1, method2; | 1820 | uint32_t method1, method2; |
1858 | 1821 | ||
1859 | if (!params->active || !params->spr.enabled) | 1822 | if (!cstate->base.active || !pstate->visible) |
1860 | return 0; | 1823 | return 0; |
1861 | 1824 | ||
1862 | method1 = ilk_wm_method1(params->pixel_rate, | 1825 | method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value); |
1863 | params->spr.bytes_per_pixel, | 1826 | method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate), |
1864 | mem_value); | 1827 | cstate->base.adjusted_mode.crtc_htotal, |
1865 | method2 = ilk_wm_method2(params->pixel_rate, | 1828 | drm_rect_width(&pstate->dst), |
1866 | params->pipe_htotal, | 1829 | bpp, |
1867 | params->spr.horiz_pixels, | ||
1868 | params->spr.bytes_per_pixel, | ||
1869 | mem_value); | 1830 | mem_value); |
1870 | return min(method1, method2); | 1831 | return min(method1, method2); |
1871 | } | 1832 | } |
@@ -1874,29 +1835,33 @@ static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params, | |||
1874 | * For both WM_PIPE and WM_LP. | 1835 | * For both WM_PIPE and WM_LP. |
1875 | * mem_value must be in 0.1us units. | 1836 | * mem_value must be in 0.1us units. |
1876 | */ | 1837 | */ |
1877 | static uint32_t ilk_compute_cur_wm(const struct ilk_pipe_wm_parameters *params, | 1838 | static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate, |
1839 | const struct intel_plane_state *pstate, | ||
1878 | uint32_t mem_value) | 1840 | uint32_t mem_value) |
1879 | { | 1841 | { |
1880 | if (!params->active || !params->cur.enabled) | 1842 | int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0; |
1843 | |||
1844 | if (!cstate->base.active || !pstate->visible) | ||
1881 | return 0; | 1845 | return 0; |
1882 | 1846 | ||
1883 | return ilk_wm_method2(params->pixel_rate, | 1847 | return ilk_wm_method2(ilk_pipe_pixel_rate(cstate), |
1884 | params->pipe_htotal, | 1848 | cstate->base.adjusted_mode.crtc_htotal, |
1885 | params->cur.horiz_pixels, | 1849 | drm_rect_width(&pstate->dst), |
1886 | params->cur.bytes_per_pixel, | 1850 | bpp, |
1887 | mem_value); | 1851 | mem_value); |
1888 | } | 1852 | } |
1889 | 1853 | ||
1890 | /* Only for WM_LP. */ | 1854 | /* Only for WM_LP. */ |
1891 | static uint32_t ilk_compute_fbc_wm(const struct ilk_pipe_wm_parameters *params, | 1855 | static uint32_t ilk_compute_fbc_wm(const struct intel_crtc_state *cstate, |
1856 | const struct intel_plane_state *pstate, | ||
1892 | uint32_t pri_val) | 1857 | uint32_t pri_val) |
1893 | { | 1858 | { |
1894 | if (!params->active || !params->pri.enabled) | 1859 | int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0; |
1860 | |||
1861 | if (!cstate->base.active || !pstate->visible) | ||
1895 | return 0; | 1862 | return 0; |
1896 | 1863 | ||
1897 | return ilk_wm_fbc(pri_val, | 1864 | return ilk_wm_fbc(pri_val, drm_rect_width(&pstate->dst), bpp); |
1898 | params->pri.horiz_pixels, | ||
1899 | params->pri.bytes_per_pixel); | ||
1900 | } | 1865 | } |
1901 | 1866 | ||
1902 | static unsigned int ilk_display_fifo_size(const struct drm_device *dev) | 1867 | static unsigned int ilk_display_fifo_size(const struct drm_device *dev) |
@@ -2061,10 +2026,12 @@ static bool ilk_validate_wm_level(int level, | |||
2061 | } | 2026 | } |
2062 | 2027 | ||
2063 | static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, | 2028 | static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, |
2029 | const struct intel_crtc *intel_crtc, | ||
2064 | int level, | 2030 | int level, |
2065 | const struct ilk_pipe_wm_parameters *p, | 2031 | struct intel_crtc_state *cstate, |
2066 | struct intel_wm_level *result) | 2032 | struct intel_wm_level *result) |
2067 | { | 2033 | { |
2034 | struct intel_plane *intel_plane; | ||
2068 | uint16_t pri_latency = dev_priv->wm.pri_latency[level]; | 2035 | uint16_t pri_latency = dev_priv->wm.pri_latency[level]; |
2069 | uint16_t spr_latency = dev_priv->wm.spr_latency[level]; | 2036 | uint16_t spr_latency = dev_priv->wm.spr_latency[level]; |
2070 | uint16_t cur_latency = dev_priv->wm.cur_latency[level]; | 2037 | uint16_t cur_latency = dev_priv->wm.cur_latency[level]; |
@@ -2076,10 +2043,29 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, | |||
2076 | cur_latency *= 5; | 2043 | cur_latency *= 5; |
2077 | } | 2044 | } |
2078 | 2045 | ||
2079 | result->pri_val = ilk_compute_pri_wm(p, pri_latency, level); | 2046 | for_each_intel_plane_on_crtc(dev_priv->dev, intel_crtc, intel_plane) { |
2080 | result->spr_val = ilk_compute_spr_wm(p, spr_latency); | 2047 | struct intel_plane_state *pstate = |
2081 | result->cur_val = ilk_compute_cur_wm(p, cur_latency); | 2048 | to_intel_plane_state(intel_plane->base.state); |
2082 | result->fbc_val = ilk_compute_fbc_wm(p, result->pri_val); | 2049 | |
2050 | switch (intel_plane->base.type) { | ||
2051 | case DRM_PLANE_TYPE_PRIMARY: | ||
2052 | result->pri_val = ilk_compute_pri_wm(cstate, pstate, | ||
2053 | pri_latency, | ||
2054 | level); | ||
2055 | result->fbc_val = ilk_compute_fbc_wm(cstate, pstate, | ||
2056 | result->pri_val); | ||
2057 | break; | ||
2058 | case DRM_PLANE_TYPE_OVERLAY: | ||
2059 | result->spr_val = ilk_compute_spr_wm(cstate, pstate, | ||
2060 | spr_latency); | ||
2061 | break; | ||
2062 | case DRM_PLANE_TYPE_CURSOR: | ||
2063 | result->cur_val = ilk_compute_cur_wm(cstate, pstate, | ||
2064 | cur_latency); | ||
2065 | break; | ||
2066 | } | ||
2067 | } | ||
2068 | |||
2083 | result->enable = true; | 2069 | result->enable = true; |
2084 | } | 2070 | } |
2085 | 2071 | ||
@@ -2088,7 +2074,7 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) | |||
2088 | { | 2074 | { |
2089 | struct drm_i915_private *dev_priv = dev->dev_private; | 2075 | struct drm_i915_private *dev_priv = dev->dev_private; |
2090 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 2076 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2091 | struct drm_display_mode *mode = &intel_crtc->config->base.adjusted_mode; | 2077 | const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode; |
2092 | u32 linetime, ips_linetime; | 2078 | u32 linetime, ips_linetime; |
2093 | 2079 | ||
2094 | if (!intel_crtc->active) | 2080 | if (!intel_crtc->active) |
@@ -2097,9 +2083,9 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) | |||
2097 | /* The WM are computed with base on how long it takes to fill a single | 2083 | /* The WM are computed with base on how long it takes to fill a single |
2098 | * row at the given clock rate, multiplied by 8. | 2084 | * row at the given clock rate, multiplied by 8. |
2099 | * */ | 2085 | * */ |
2100 | linetime = DIV_ROUND_CLOSEST(mode->crtc_htotal * 1000 * 8, | 2086 | linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8, |
2101 | mode->crtc_clock); | 2087 | adjusted_mode->crtc_clock); |
2102 | ips_linetime = DIV_ROUND_CLOSEST(mode->crtc_htotal * 1000 * 8, | 2088 | ips_linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8, |
2103 | dev_priv->cdclk_freq); | 2089 | dev_priv->cdclk_freq); |
2104 | 2090 | ||
2105 | return PIPE_WM_LINETIME_IPS_LINETIME(ips_linetime) | | 2091 | return PIPE_WM_LINETIME_IPS_LINETIME(ips_linetime) | |
@@ -2338,48 +2324,6 @@ static void skl_setup_wm_latency(struct drm_device *dev) | |||
2338 | intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency); | 2324 | intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency); |
2339 | } | 2325 | } |
2340 | 2326 | ||
2341 | static void ilk_compute_wm_parameters(struct drm_crtc *crtc, | ||
2342 | struct ilk_pipe_wm_parameters *p) | ||
2343 | { | ||
2344 | struct drm_device *dev = crtc->dev; | ||
2345 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
2346 | enum pipe pipe = intel_crtc->pipe; | ||
2347 | struct drm_plane *plane; | ||
2348 | |||
2349 | if (!intel_crtc->active) | ||
2350 | return; | ||
2351 | |||
2352 | p->active = true; | ||
2353 | p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal; | ||
2354 | p->pixel_rate = ilk_pipe_pixel_rate(intel_crtc->config); | ||
2355 | |||
2356 | if (crtc->primary->state->fb) | ||
2357 | p->pri.bytes_per_pixel = | ||
2358 | crtc->primary->state->fb->bits_per_pixel / 8; | ||
2359 | else | ||
2360 | p->pri.bytes_per_pixel = 4; | ||
2361 | |||
2362 | p->cur.bytes_per_pixel = 4; | ||
2363 | /* | ||
2364 | * TODO: for now, assume primary and cursor planes are always enabled. | ||
2365 | * Setting them to false makes the screen flicker. | ||
2366 | */ | ||
2367 | p->pri.enabled = true; | ||
2368 | p->cur.enabled = true; | ||
2369 | |||
2370 | p->pri.horiz_pixels = intel_crtc->config->pipe_src_w; | ||
2371 | p->cur.horiz_pixels = intel_crtc->base.cursor->state->crtc_w; | ||
2372 | |||
2373 | drm_for_each_legacy_plane(plane, dev) { | ||
2374 | struct intel_plane *intel_plane = to_intel_plane(plane); | ||
2375 | |||
2376 | if (intel_plane->pipe == pipe) { | ||
2377 | p->spr = intel_plane->wm; | ||
2378 | break; | ||
2379 | } | ||
2380 | } | ||
2381 | } | ||
2382 | |||
2383 | static void ilk_compute_wm_config(struct drm_device *dev, | 2327 | static void ilk_compute_wm_config(struct drm_device *dev, |
2384 | struct intel_wm_config *config) | 2328 | struct intel_wm_config *config) |
2385 | { | 2329 | { |
@@ -2399,34 +2343,47 @@ static void ilk_compute_wm_config(struct drm_device *dev, | |||
2399 | } | 2343 | } |
2400 | 2344 | ||
2401 | /* Compute new watermarks for the pipe */ | 2345 | /* Compute new watermarks for the pipe */ |
2402 | static bool intel_compute_pipe_wm(struct drm_crtc *crtc, | 2346 | static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate, |
2403 | const struct ilk_pipe_wm_parameters *params, | ||
2404 | struct intel_pipe_wm *pipe_wm) | 2347 | struct intel_pipe_wm *pipe_wm) |
2405 | { | 2348 | { |
2349 | struct drm_crtc *crtc = cstate->base.crtc; | ||
2406 | struct drm_device *dev = crtc->dev; | 2350 | struct drm_device *dev = crtc->dev; |
2407 | const struct drm_i915_private *dev_priv = dev->dev_private; | 2351 | const struct drm_i915_private *dev_priv = dev->dev_private; |
2352 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
2353 | struct intel_plane *intel_plane; | ||
2354 | struct intel_plane_state *sprstate = NULL; | ||
2408 | int level, max_level = ilk_wm_max_level(dev); | 2355 | int level, max_level = ilk_wm_max_level(dev); |
2409 | /* LP0 watermark maximums depend on this pipe alone */ | 2356 | /* LP0 watermark maximums depend on this pipe alone */ |
2410 | struct intel_wm_config config = { | 2357 | struct intel_wm_config config = { |
2411 | .num_pipes_active = 1, | 2358 | .num_pipes_active = 1, |
2412 | .sprites_enabled = params->spr.enabled, | ||
2413 | .sprites_scaled = params->spr.scaled, | ||
2414 | }; | 2359 | }; |
2415 | struct ilk_wm_maximums max; | 2360 | struct ilk_wm_maximums max; |
2416 | 2361 | ||
2417 | pipe_wm->pipe_enabled = params->active; | 2362 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { |
2418 | pipe_wm->sprites_enabled = params->spr.enabled; | 2363 | if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) { |
2419 | pipe_wm->sprites_scaled = params->spr.scaled; | 2364 | sprstate = to_intel_plane_state(intel_plane->base.state); |
2365 | break; | ||
2366 | } | ||
2367 | } | ||
2368 | |||
2369 | config.sprites_enabled = sprstate->visible; | ||
2370 | config.sprites_scaled = sprstate->visible && | ||
2371 | (drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 || | ||
2372 | drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16); | ||
2373 | |||
2374 | pipe_wm->pipe_enabled = cstate->base.active; | ||
2375 | pipe_wm->sprites_enabled = sprstate->visible; | ||
2376 | pipe_wm->sprites_scaled = config.sprites_scaled; | ||
2420 | 2377 | ||
2421 | /* ILK/SNB: LP2+ watermarks only w/o sprites */ | 2378 | /* ILK/SNB: LP2+ watermarks only w/o sprites */ |
2422 | if (INTEL_INFO(dev)->gen <= 6 && params->spr.enabled) | 2379 | if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible) |
2423 | max_level = 1; | 2380 | max_level = 1; |
2424 | 2381 | ||
2425 | /* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */ | 2382 | /* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */ |
2426 | if (params->spr.scaled) | 2383 | if (config.sprites_scaled) |
2427 | max_level = 0; | 2384 | max_level = 0; |
2428 | 2385 | ||
2429 | ilk_compute_wm_level(dev_priv, 0, params, &pipe_wm->wm[0]); | 2386 | ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, &pipe_wm->wm[0]); |
2430 | 2387 | ||
2431 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) | 2388 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
2432 | pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc); | 2389 | pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc); |
@@ -2443,7 +2400,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc, | |||
2443 | for (level = 1; level <= max_level; level++) { | 2400 | for (level = 1; level <= max_level; level++) { |
2444 | struct intel_wm_level wm = {}; | 2401 | struct intel_wm_level wm = {}; |
2445 | 2402 | ||
2446 | ilk_compute_wm_level(dev_priv, level, params, &wm); | 2403 | ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, &wm); |
2447 | 2404 | ||
2448 | /* | 2405 | /* |
2449 | * Disable any watermark level that exceeds the | 2406 | * Disable any watermark level that exceeds the |
@@ -2848,18 +2805,40 @@ static bool ilk_disable_lp_wm(struct drm_device *dev) | |||
2848 | #define SKL_DDB_SIZE 896 /* in blocks */ | 2805 | #define SKL_DDB_SIZE 896 /* in blocks */ |
2849 | #define BXT_DDB_SIZE 512 | 2806 | #define BXT_DDB_SIZE 512 |
2850 | 2807 | ||
2808 | /* | ||
2809 | * Return the index of a plane in the SKL DDB and wm result arrays. Primary | ||
2810 | * plane is always in slot 0, cursor is always in slot I915_MAX_PLANES-1, and | ||
2811 | * other universal planes are in indices 1..n. Note that this may leave unused | ||
2812 | * indices between the top "sprite" plane and the cursor. | ||
2813 | */ | ||
2814 | static int | ||
2815 | skl_wm_plane_id(const struct intel_plane *plane) | ||
2816 | { | ||
2817 | switch (plane->base.type) { | ||
2818 | case DRM_PLANE_TYPE_PRIMARY: | ||
2819 | return 0; | ||
2820 | case DRM_PLANE_TYPE_CURSOR: | ||
2821 | return PLANE_CURSOR; | ||
2822 | case DRM_PLANE_TYPE_OVERLAY: | ||
2823 | return plane->plane + 1; | ||
2824 | default: | ||
2825 | MISSING_CASE(plane->base.type); | ||
2826 | return plane->plane; | ||
2827 | } | ||
2828 | } | ||
2829 | |||
2851 | static void | 2830 | static void |
2852 | skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, | 2831 | skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, |
2853 | struct drm_crtc *for_crtc, | 2832 | const struct intel_crtc_state *cstate, |
2854 | const struct intel_wm_config *config, | 2833 | const struct intel_wm_config *config, |
2855 | const struct skl_pipe_wm_parameters *params, | ||
2856 | struct skl_ddb_entry *alloc /* out */) | 2834 | struct skl_ddb_entry *alloc /* out */) |
2857 | { | 2835 | { |
2836 | struct drm_crtc *for_crtc = cstate->base.crtc; | ||
2858 | struct drm_crtc *crtc; | 2837 | struct drm_crtc *crtc; |
2859 | unsigned int pipe_size, ddb_size; | 2838 | unsigned int pipe_size, ddb_size; |
2860 | int nth_active_pipe; | 2839 | int nth_active_pipe; |
2861 | 2840 | ||
2862 | if (!params->active) { | 2841 | if (!cstate->base.active) { |
2863 | alloc->start = 0; | 2842 | alloc->start = 0; |
2864 | alloc->end = 0; | 2843 | alloc->end = 0; |
2865 | return; | 2844 | return; |
@@ -2919,24 +2898,35 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, | |||
2919 | } | 2898 | } |
2920 | 2899 | ||
2921 | val = I915_READ(CUR_BUF_CFG(pipe)); | 2900 | val = I915_READ(CUR_BUF_CFG(pipe)); |
2922 | skl_ddb_entry_init_from_hw(&ddb->cursor[pipe], val); | 2901 | skl_ddb_entry_init_from_hw(&ddb->plane[pipe][PLANE_CURSOR], |
2902 | val); | ||
2923 | } | 2903 | } |
2924 | } | 2904 | } |
2925 | 2905 | ||
2926 | static unsigned int | 2906 | static unsigned int |
2927 | skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p, int y) | 2907 | skl_plane_relative_data_rate(const struct intel_crtc_state *cstate, |
2908 | const struct drm_plane_state *pstate, | ||
2909 | int y) | ||
2928 | { | 2910 | { |
2911 | struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); | ||
2912 | struct drm_framebuffer *fb = pstate->fb; | ||
2929 | 2913 | ||
2930 | /* for planar format */ | 2914 | /* for planar format */ |
2931 | if (p->y_bytes_per_pixel) { | 2915 | if (fb->pixel_format == DRM_FORMAT_NV12) { |
2932 | if (y) /* y-plane data rate */ | 2916 | if (y) /* y-plane data rate */ |
2933 | return p->horiz_pixels * p->vert_pixels * p->y_bytes_per_pixel; | 2917 | return intel_crtc->config->pipe_src_w * |
2918 | intel_crtc->config->pipe_src_h * | ||
2919 | drm_format_plane_cpp(fb->pixel_format, 0); | ||
2934 | else /* uv-plane data rate */ | 2920 | else /* uv-plane data rate */ |
2935 | return (p->horiz_pixels/2) * (p->vert_pixels/2) * p->bytes_per_pixel; | 2921 | return (intel_crtc->config->pipe_src_w/2) * |
2922 | (intel_crtc->config->pipe_src_h/2) * | ||
2923 | drm_format_plane_cpp(fb->pixel_format, 1); | ||
2936 | } | 2924 | } |
2937 | 2925 | ||
2938 | /* for packed formats */ | 2926 | /* for packed formats */ |
2939 | return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel; | 2927 | return intel_crtc->config->pipe_src_w * |
2928 | intel_crtc->config->pipe_src_h * | ||
2929 | drm_format_plane_cpp(fb->pixel_format, 0); | ||
2940 | } | 2930 | } |
2941 | 2931 | ||
2942 | /* | 2932 | /* |
@@ -2945,72 +2935,81 @@ skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p, int y) | |||
2945 | * 3 * 4096 * 8192 * 4 < 2^32 | 2935 | * 3 * 4096 * 8192 * 4 < 2^32 |
2946 | */ | 2936 | */ |
2947 | static unsigned int | 2937 | static unsigned int |
2948 | skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc, | 2938 | skl_get_total_relative_data_rate(const struct intel_crtc_state *cstate) |
2949 | const struct skl_pipe_wm_parameters *params) | ||
2950 | { | 2939 | { |
2940 | struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); | ||
2941 | struct drm_device *dev = intel_crtc->base.dev; | ||
2942 | const struct intel_plane *intel_plane; | ||
2951 | unsigned int total_data_rate = 0; | 2943 | unsigned int total_data_rate = 0; |
2952 | int plane; | ||
2953 | 2944 | ||
2954 | for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) { | 2945 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { |
2955 | const struct intel_plane_wm_parameters *p; | 2946 | const struct drm_plane_state *pstate = intel_plane->base.state; |
2956 | 2947 | ||
2957 | p = ¶ms->plane[plane]; | 2948 | if (pstate->fb == NULL) |
2958 | if (!p->enabled) | ||
2959 | continue; | 2949 | continue; |
2960 | 2950 | ||
2961 | total_data_rate += skl_plane_relative_data_rate(p, 0); /* packed/uv */ | 2951 | /* packed/uv */ |
2962 | if (p->y_bytes_per_pixel) { | 2952 | total_data_rate += skl_plane_relative_data_rate(cstate, |
2963 | total_data_rate += skl_plane_relative_data_rate(p, 1); /* y-plane */ | 2953 | pstate, |
2964 | } | 2954 | 0); |
2955 | |||
2956 | if (pstate->fb->pixel_format == DRM_FORMAT_NV12) | ||
2957 | /* y-plane */ | ||
2958 | total_data_rate += skl_plane_relative_data_rate(cstate, | ||
2959 | pstate, | ||
2960 | 1); | ||
2965 | } | 2961 | } |
2966 | 2962 | ||
2967 | return total_data_rate; | 2963 | return total_data_rate; |
2968 | } | 2964 | } |
2969 | 2965 | ||
2970 | static void | 2966 | static void |
2971 | skl_allocate_pipe_ddb(struct drm_crtc *crtc, | 2967 | skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, |
2972 | const struct intel_wm_config *config, | 2968 | const struct intel_wm_config *config, |
2973 | const struct skl_pipe_wm_parameters *params, | ||
2974 | struct skl_ddb_allocation *ddb /* out */) | 2969 | struct skl_ddb_allocation *ddb /* out */) |
2975 | { | 2970 | { |
2971 | struct drm_crtc *crtc = cstate->base.crtc; | ||
2976 | struct drm_device *dev = crtc->dev; | 2972 | struct drm_device *dev = crtc->dev; |
2977 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2978 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 2973 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2974 | struct intel_plane *intel_plane; | ||
2979 | enum pipe pipe = intel_crtc->pipe; | 2975 | enum pipe pipe = intel_crtc->pipe; |
2980 | struct skl_ddb_entry *alloc = &ddb->pipe[pipe]; | 2976 | struct skl_ddb_entry *alloc = &ddb->pipe[pipe]; |
2981 | uint16_t alloc_size, start, cursor_blocks; | 2977 | uint16_t alloc_size, start, cursor_blocks; |
2982 | uint16_t minimum[I915_MAX_PLANES]; | 2978 | uint16_t minimum[I915_MAX_PLANES]; |
2983 | uint16_t y_minimum[I915_MAX_PLANES]; | 2979 | uint16_t y_minimum[I915_MAX_PLANES]; |
2984 | unsigned int total_data_rate; | 2980 | unsigned int total_data_rate; |
2985 | int plane; | ||
2986 | 2981 | ||
2987 | skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, alloc); | 2982 | skl_ddb_get_pipe_allocation_limits(dev, cstate, config, alloc); |
2988 | alloc_size = skl_ddb_entry_size(alloc); | 2983 | alloc_size = skl_ddb_entry_size(alloc); |
2989 | if (alloc_size == 0) { | 2984 | if (alloc_size == 0) { |
2990 | memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); | 2985 | memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); |
2991 | memset(&ddb->cursor[pipe], 0, sizeof(ddb->cursor[pipe])); | 2986 | memset(&ddb->plane[pipe][PLANE_CURSOR], 0, |
2987 | sizeof(ddb->plane[pipe][PLANE_CURSOR])); | ||
2992 | return; | 2988 | return; |
2993 | } | 2989 | } |
2994 | 2990 | ||
2995 | cursor_blocks = skl_cursor_allocation(config); | 2991 | cursor_blocks = skl_cursor_allocation(config); |
2996 | ddb->cursor[pipe].start = alloc->end - cursor_blocks; | 2992 | ddb->plane[pipe][PLANE_CURSOR].start = alloc->end - cursor_blocks; |
2997 | ddb->cursor[pipe].end = alloc->end; | 2993 | ddb->plane[pipe][PLANE_CURSOR].end = alloc->end; |
2998 | 2994 | ||
2999 | alloc_size -= cursor_blocks; | 2995 | alloc_size -= cursor_blocks; |
3000 | alloc->end -= cursor_blocks; | 2996 | alloc->end -= cursor_blocks; |
3001 | 2997 | ||
3002 | /* 1. Allocate the mininum required blocks for each active plane */ | 2998 | /* 1. Allocate the mininum required blocks for each active plane */ |
3003 | for_each_plane(dev_priv, pipe, plane) { | 2999 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { |
3004 | const struct intel_plane_wm_parameters *p; | 3000 | struct drm_plane *plane = &intel_plane->base; |
3001 | struct drm_framebuffer *fb = plane->fb; | ||
3002 | int id = skl_wm_plane_id(intel_plane); | ||
3005 | 3003 | ||
3006 | p = ¶ms->plane[plane]; | 3004 | if (fb == NULL) |
3007 | if (!p->enabled) | 3005 | continue; |
3006 | if (plane->type == DRM_PLANE_TYPE_CURSOR) | ||
3008 | continue; | 3007 | continue; |
3009 | 3008 | ||
3010 | minimum[plane] = 8; | 3009 | minimum[id] = 8; |
3011 | alloc_size -= minimum[plane]; | 3010 | alloc_size -= minimum[id]; |
3012 | y_minimum[plane] = p->y_bytes_per_pixel ? 8 : 0; | 3011 | y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0; |
3013 | alloc_size -= y_minimum[plane]; | 3012 | alloc_size -= y_minimum[id]; |
3014 | } | 3013 | } |
3015 | 3014 | ||
3016 | /* | 3015 | /* |
@@ -3019,45 +3018,50 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc, | |||
3019 | * | 3018 | * |
3020 | * FIXME: we may not allocate every single block here. | 3019 | * FIXME: we may not allocate every single block here. |
3021 | */ | 3020 | */ |
3022 | total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params); | 3021 | total_data_rate = skl_get_total_relative_data_rate(cstate); |
3023 | 3022 | ||
3024 | start = alloc->start; | 3023 | start = alloc->start; |
3025 | for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) { | 3024 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { |
3026 | const struct intel_plane_wm_parameters *p; | 3025 | struct drm_plane *plane = &intel_plane->base; |
3026 | struct drm_plane_state *pstate = intel_plane->base.state; | ||
3027 | unsigned int data_rate, y_data_rate; | 3027 | unsigned int data_rate, y_data_rate; |
3028 | uint16_t plane_blocks, y_plane_blocks = 0; | 3028 | uint16_t plane_blocks, y_plane_blocks = 0; |
3029 | int id = skl_wm_plane_id(intel_plane); | ||
3029 | 3030 | ||
3030 | p = ¶ms->plane[plane]; | 3031 | if (pstate->fb == NULL) |
3031 | if (!p->enabled) | 3032 | continue; |
3033 | if (plane->type == DRM_PLANE_TYPE_CURSOR) | ||
3032 | continue; | 3034 | continue; |
3033 | 3035 | ||
3034 | data_rate = skl_plane_relative_data_rate(p, 0); | 3036 | data_rate = skl_plane_relative_data_rate(cstate, pstate, 0); |
3035 | 3037 | ||
3036 | /* | 3038 | /* |
3037 | * allocation for (packed formats) or (uv-plane part of planar format): | 3039 | * allocation for (packed formats) or (uv-plane part of planar format): |
3038 | * promote the expression to 64 bits to avoid overflowing, the | 3040 | * promote the expression to 64 bits to avoid overflowing, the |
3039 | * result is < available as data_rate / total_data_rate < 1 | 3041 | * result is < available as data_rate / total_data_rate < 1 |
3040 | */ | 3042 | */ |
3041 | plane_blocks = minimum[plane]; | 3043 | plane_blocks = minimum[id]; |
3042 | plane_blocks += div_u64((uint64_t)alloc_size * data_rate, | 3044 | plane_blocks += div_u64((uint64_t)alloc_size * data_rate, |
3043 | total_data_rate); | 3045 | total_data_rate); |
3044 | 3046 | ||
3045 | ddb->plane[pipe][plane].start = start; | 3047 | ddb->plane[pipe][id].start = start; |
3046 | ddb->plane[pipe][plane].end = start + plane_blocks; | 3048 | ddb->plane[pipe][id].end = start + plane_blocks; |
3047 | 3049 | ||
3048 | start += plane_blocks; | 3050 | start += plane_blocks; |
3049 | 3051 | ||
3050 | /* | 3052 | /* |
3051 | * allocation for y_plane part of planar format: | 3053 | * allocation for y_plane part of planar format: |
3052 | */ | 3054 | */ |
3053 | if (p->y_bytes_per_pixel) { | 3055 | if (pstate->fb->pixel_format == DRM_FORMAT_NV12) { |
3054 | y_data_rate = skl_plane_relative_data_rate(p, 1); | 3056 | y_data_rate = skl_plane_relative_data_rate(cstate, |
3055 | y_plane_blocks = y_minimum[plane]; | 3057 | pstate, |
3058 | 1); | ||
3059 | y_plane_blocks = y_minimum[id]; | ||
3056 | y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate, | 3060 | y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate, |
3057 | total_data_rate); | 3061 | total_data_rate); |
3058 | 3062 | ||
3059 | ddb->y_plane[pipe][plane].start = start; | 3063 | ddb->y_plane[pipe][id].start = start; |
3060 | ddb->y_plane[pipe][plane].end = start + y_plane_blocks; | 3064 | ddb->y_plane[pipe][id].end = start + y_plane_blocks; |
3061 | 3065 | ||
3062 | start += y_plane_blocks; | 3066 | start += y_plane_blocks; |
3063 | } | 3067 | } |
@@ -3133,8 +3137,8 @@ static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb, | |||
3133 | sizeof(new_ddb->plane[pipe]))) | 3137 | sizeof(new_ddb->plane[pipe]))) |
3134 | return true; | 3138 | return true; |
3135 | 3139 | ||
3136 | if (memcmp(&new_ddb->cursor[pipe], &cur_ddb->cursor[pipe], | 3140 | if (memcmp(&new_ddb->plane[pipe][PLANE_CURSOR], &cur_ddb->plane[pipe][PLANE_CURSOR], |
3137 | sizeof(new_ddb->cursor[pipe]))) | 3141 | sizeof(new_ddb->plane[pipe][PLANE_CURSOR]))) |
3138 | return true; | 3142 | return true; |
3139 | 3143 | ||
3140 | return false; | 3144 | return false; |
@@ -3144,87 +3148,21 @@ static void skl_compute_wm_global_parameters(struct drm_device *dev, | |||
3144 | struct intel_wm_config *config) | 3148 | struct intel_wm_config *config) |
3145 | { | 3149 | { |
3146 | struct drm_crtc *crtc; | 3150 | struct drm_crtc *crtc; |
3147 | struct drm_plane *plane; | ||
3148 | 3151 | ||
3149 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) | 3152 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) |
3150 | config->num_pipes_active += to_intel_crtc(crtc)->active; | 3153 | config->num_pipes_active += to_intel_crtc(crtc)->active; |
3151 | |||
3152 | /* FIXME: I don't think we need those two global parameters on SKL */ | ||
3153 | list_for_each_entry(plane, &dev->mode_config.plane_list, head) { | ||
3154 | struct intel_plane *intel_plane = to_intel_plane(plane); | ||
3155 | |||
3156 | config->sprites_enabled |= intel_plane->wm.enabled; | ||
3157 | config->sprites_scaled |= intel_plane->wm.scaled; | ||
3158 | } | ||
3159 | } | ||
3160 | |||
3161 | static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc, | ||
3162 | struct skl_pipe_wm_parameters *p) | ||
3163 | { | ||
3164 | struct drm_device *dev = crtc->dev; | ||
3165 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
3166 | enum pipe pipe = intel_crtc->pipe; | ||
3167 | struct drm_plane *plane; | ||
3168 | struct drm_framebuffer *fb; | ||
3169 | int i = 1; /* Index for sprite planes start */ | ||
3170 | |||
3171 | p->active = intel_crtc->active; | ||
3172 | if (p->active) { | ||
3173 | p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal; | ||
3174 | p->pixel_rate = skl_pipe_pixel_rate(intel_crtc->config); | ||
3175 | |||
3176 | fb = crtc->primary->state->fb; | ||
3177 | /* For planar: Bpp is for uv plane, y_Bpp is for y plane */ | ||
3178 | if (fb) { | ||
3179 | p->plane[0].enabled = true; | ||
3180 | p->plane[0].bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ? | ||
3181 | drm_format_plane_cpp(fb->pixel_format, 1) : | ||
3182 | drm_format_plane_cpp(fb->pixel_format, 0); | ||
3183 | p->plane[0].y_bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ? | ||
3184 | drm_format_plane_cpp(fb->pixel_format, 0) : 0; | ||
3185 | p->plane[0].tiling = fb->modifier[0]; | ||
3186 | } else { | ||
3187 | p->plane[0].enabled = false; | ||
3188 | p->plane[0].bytes_per_pixel = 0; | ||
3189 | p->plane[0].y_bytes_per_pixel = 0; | ||
3190 | p->plane[0].tiling = DRM_FORMAT_MOD_NONE; | ||
3191 | } | ||
3192 | p->plane[0].horiz_pixels = intel_crtc->config->pipe_src_w; | ||
3193 | p->plane[0].vert_pixels = intel_crtc->config->pipe_src_h; | ||
3194 | p->plane[0].rotation = crtc->primary->state->rotation; | ||
3195 | |||
3196 | fb = crtc->cursor->state->fb; | ||
3197 | p->cursor.y_bytes_per_pixel = 0; | ||
3198 | if (fb) { | ||
3199 | p->cursor.enabled = true; | ||
3200 | p->cursor.bytes_per_pixel = fb->bits_per_pixel / 8; | ||
3201 | p->cursor.horiz_pixels = crtc->cursor->state->crtc_w; | ||
3202 | p->cursor.vert_pixels = crtc->cursor->state->crtc_h; | ||
3203 | } else { | ||
3204 | p->cursor.enabled = false; | ||
3205 | p->cursor.bytes_per_pixel = 0; | ||
3206 | p->cursor.horiz_pixels = 64; | ||
3207 | p->cursor.vert_pixels = 64; | ||
3208 | } | ||
3209 | } | ||
3210 | |||
3211 | list_for_each_entry(plane, &dev->mode_config.plane_list, head) { | ||
3212 | struct intel_plane *intel_plane = to_intel_plane(plane); | ||
3213 | |||
3214 | if (intel_plane->pipe == pipe && | ||
3215 | plane->type == DRM_PLANE_TYPE_OVERLAY) | ||
3216 | p->plane[i++] = intel_plane->wm; | ||
3217 | } | ||
3218 | } | 3154 | } |
3219 | 3155 | ||
3220 | static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, | 3156 | static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, |
3221 | struct skl_pipe_wm_parameters *p, | 3157 | struct intel_crtc_state *cstate, |
3222 | struct intel_plane_wm_parameters *p_params, | 3158 | struct intel_plane *intel_plane, |
3223 | uint16_t ddb_allocation, | 3159 | uint16_t ddb_allocation, |
3224 | int level, | 3160 | int level, |
3225 | uint16_t *out_blocks, /* out */ | 3161 | uint16_t *out_blocks, /* out */ |
3226 | uint8_t *out_lines /* out */) | 3162 | uint8_t *out_lines /* out */) |
3227 | { | 3163 | { |
3164 | struct drm_plane *plane = &intel_plane->base; | ||
3165 | struct drm_framebuffer *fb = plane->state->fb; | ||
3228 | uint32_t latency = dev_priv->wm.skl_latency[level]; | 3166 | uint32_t latency = dev_priv->wm.skl_latency[level]; |
3229 | uint32_t method1, method2; | 3167 | uint32_t method1, method2; |
3230 | uint32_t plane_bytes_per_line, plane_blocks_per_line; | 3168 | uint32_t plane_bytes_per_line, plane_blocks_per_line; |
@@ -3232,31 +3170,35 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, | |||
3232 | uint32_t selected_result; | 3170 | uint32_t selected_result; |
3233 | uint8_t bytes_per_pixel; | 3171 | uint8_t bytes_per_pixel; |
3234 | 3172 | ||
3235 | if (latency == 0 || !p->active || !p_params->enabled) | 3173 | if (latency == 0 || !cstate->base.active || !fb) |
3236 | return false; | 3174 | return false; |
3237 | 3175 | ||
3238 | bytes_per_pixel = p_params->y_bytes_per_pixel ? | 3176 | bytes_per_pixel = (fb->pixel_format == DRM_FORMAT_NV12) ? |
3239 | p_params->y_bytes_per_pixel : | 3177 | drm_format_plane_cpp(DRM_FORMAT_NV12, 0) : |
3240 | p_params->bytes_per_pixel; | 3178 | drm_format_plane_cpp(DRM_FORMAT_NV12, 1); |
3241 | method1 = skl_wm_method1(p->pixel_rate, | 3179 | method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate), |
3242 | bytes_per_pixel, | 3180 | bytes_per_pixel, |
3243 | latency); | 3181 | latency); |
3244 | method2 = skl_wm_method2(p->pixel_rate, | 3182 | method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate), |
3245 | p->pipe_htotal, | 3183 | cstate->base.adjusted_mode.crtc_htotal, |
3246 | p_params->horiz_pixels, | 3184 | cstate->pipe_src_w, |
3247 | bytes_per_pixel, | 3185 | bytes_per_pixel, |
3248 | p_params->tiling, | 3186 | fb->modifier[0], |
3249 | latency); | 3187 | latency); |
3250 | 3188 | ||
3251 | plane_bytes_per_line = p_params->horiz_pixels * bytes_per_pixel; | 3189 | plane_bytes_per_line = cstate->pipe_src_w * bytes_per_pixel; |
3252 | plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); | 3190 | plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); |
3253 | 3191 | ||
3254 | if (p_params->tiling == I915_FORMAT_MOD_Y_TILED || | 3192 | if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || |
3255 | p_params->tiling == I915_FORMAT_MOD_Yf_TILED) { | 3193 | fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) { |
3256 | uint32_t min_scanlines = 4; | 3194 | uint32_t min_scanlines = 4; |
3257 | uint32_t y_tile_minimum; | 3195 | uint32_t y_tile_minimum; |
3258 | if (intel_rotation_90_or_270(p_params->rotation)) { | 3196 | if (intel_rotation_90_or_270(plane->state->rotation)) { |
3259 | switch (p_params->bytes_per_pixel) { | 3197 | int bpp = (fb->pixel_format == DRM_FORMAT_NV12) ? |
3198 | drm_format_plane_cpp(fb->pixel_format, 1) : | ||
3199 | drm_format_plane_cpp(fb->pixel_format, 0); | ||
3200 | |||
3201 | switch (bpp) { | ||
3260 | case 1: | 3202 | case 1: |
3261 | min_scanlines = 16; | 3203 | min_scanlines = 16; |
3262 | break; | 3204 | break; |
@@ -3280,8 +3222,8 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, | |||
3280 | res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line); | 3222 | res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line); |
3281 | 3223 | ||
3282 | if (level >= 1 && level <= 7) { | 3224 | if (level >= 1 && level <= 7) { |
3283 | if (p_params->tiling == I915_FORMAT_MOD_Y_TILED || | 3225 | if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || |
3284 | p_params->tiling == I915_FORMAT_MOD_Yf_TILED) | 3226 | fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) |
3285 | res_lines += 4; | 3227 | res_lines += 4; |
3286 | else | 3228 | else |
3287 | res_blocks++; | 3229 | res_blocks++; |
@@ -3298,83 +3240,80 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, | |||
3298 | 3240 | ||
3299 | static void skl_compute_wm_level(const struct drm_i915_private *dev_priv, | 3241 | static void skl_compute_wm_level(const struct drm_i915_private *dev_priv, |
3300 | struct skl_ddb_allocation *ddb, | 3242 | struct skl_ddb_allocation *ddb, |
3301 | struct skl_pipe_wm_parameters *p, | 3243 | struct intel_crtc_state *cstate, |
3302 | enum pipe pipe, | ||
3303 | int level, | 3244 | int level, |
3304 | int num_planes, | ||
3305 | struct skl_wm_level *result) | 3245 | struct skl_wm_level *result) |
3306 | { | 3246 | { |
3247 | struct drm_device *dev = dev_priv->dev; | ||
3248 | struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); | ||
3249 | struct intel_plane *intel_plane; | ||
3307 | uint16_t ddb_blocks; | 3250 | uint16_t ddb_blocks; |
3308 | int i; | 3251 | enum pipe pipe = intel_crtc->pipe; |
3252 | |||
3253 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { | ||
3254 | int i = skl_wm_plane_id(intel_plane); | ||
3309 | 3255 | ||
3310 | for (i = 0; i < num_planes; i++) { | ||
3311 | ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]); | 3256 | ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]); |
3312 | 3257 | ||
3313 | result->plane_en[i] = skl_compute_plane_wm(dev_priv, | 3258 | result->plane_en[i] = skl_compute_plane_wm(dev_priv, |
3314 | p, &p->plane[i], | 3259 | cstate, |
3260 | intel_plane, | ||
3315 | ddb_blocks, | 3261 | ddb_blocks, |
3316 | level, | 3262 | level, |
3317 | &result->plane_res_b[i], | 3263 | &result->plane_res_b[i], |
3318 | &result->plane_res_l[i]); | 3264 | &result->plane_res_l[i]); |
3319 | } | 3265 | } |
3320 | |||
3321 | ddb_blocks = skl_ddb_entry_size(&ddb->cursor[pipe]); | ||
3322 | result->cursor_en = skl_compute_plane_wm(dev_priv, p, &p->cursor, | ||
3323 | ddb_blocks, level, | ||
3324 | &result->cursor_res_b, | ||
3325 | &result->cursor_res_l); | ||
3326 | } | 3266 | } |
3327 | 3267 | ||
3328 | static uint32_t | 3268 | static uint32_t |
3329 | skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p) | 3269 | skl_compute_linetime_wm(struct intel_crtc_state *cstate) |
3330 | { | 3270 | { |
3331 | if (!to_intel_crtc(crtc)->active) | 3271 | if (!cstate->base.active) |
3332 | return 0; | 3272 | return 0; |
3333 | 3273 | ||
3334 | if (WARN_ON(p->pixel_rate == 0)) | 3274 | if (WARN_ON(skl_pipe_pixel_rate(cstate) == 0)) |
3335 | return 0; | 3275 | return 0; |
3336 | 3276 | ||
3337 | return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate); | 3277 | return DIV_ROUND_UP(8 * cstate->base.adjusted_mode.crtc_htotal * 1000, |
3278 | skl_pipe_pixel_rate(cstate)); | ||
3338 | } | 3279 | } |
3339 | 3280 | ||
3340 | static void skl_compute_transition_wm(struct drm_crtc *crtc, | 3281 | static void skl_compute_transition_wm(struct intel_crtc_state *cstate, |
3341 | struct skl_pipe_wm_parameters *params, | ||
3342 | struct skl_wm_level *trans_wm /* out */) | 3282 | struct skl_wm_level *trans_wm /* out */) |
3343 | { | 3283 | { |
3284 | struct drm_crtc *crtc = cstate->base.crtc; | ||
3344 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3285 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3345 | int i; | 3286 | struct intel_plane *intel_plane; |
3346 | 3287 | ||
3347 | if (!params->active) | 3288 | if (!cstate->base.active) |
3348 | return; | 3289 | return; |
3349 | 3290 | ||
3350 | /* Until we know more, just disable transition WMs */ | 3291 | /* Until we know more, just disable transition WMs */ |
3351 | for (i = 0; i < intel_num_planes(intel_crtc); i++) | 3292 | for_each_intel_plane_on_crtc(crtc->dev, intel_crtc, intel_plane) { |
3293 | int i = skl_wm_plane_id(intel_plane); | ||
3294 | |||
3352 | trans_wm->plane_en[i] = false; | 3295 | trans_wm->plane_en[i] = false; |
3353 | trans_wm->cursor_en = false; | 3296 | } |
3354 | } | 3297 | } |
3355 | 3298 | ||
3356 | static void skl_compute_pipe_wm(struct drm_crtc *crtc, | 3299 | static void skl_compute_pipe_wm(struct intel_crtc_state *cstate, |
3357 | struct skl_ddb_allocation *ddb, | 3300 | struct skl_ddb_allocation *ddb, |
3358 | struct skl_pipe_wm_parameters *params, | ||
3359 | struct skl_pipe_wm *pipe_wm) | 3301 | struct skl_pipe_wm *pipe_wm) |
3360 | { | 3302 | { |
3361 | struct drm_device *dev = crtc->dev; | 3303 | struct drm_device *dev = cstate->base.crtc->dev; |
3362 | const struct drm_i915_private *dev_priv = dev->dev_private; | 3304 | const struct drm_i915_private *dev_priv = dev->dev_private; |
3363 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
3364 | int level, max_level = ilk_wm_max_level(dev); | 3305 | int level, max_level = ilk_wm_max_level(dev); |
3365 | 3306 | ||
3366 | for (level = 0; level <= max_level; level++) { | 3307 | for (level = 0; level <= max_level; level++) { |
3367 | skl_compute_wm_level(dev_priv, ddb, params, intel_crtc->pipe, | 3308 | skl_compute_wm_level(dev_priv, ddb, cstate, |
3368 | level, intel_num_planes(intel_crtc), | 3309 | level, &pipe_wm->wm[level]); |
3369 | &pipe_wm->wm[level]); | ||
3370 | } | 3310 | } |
3371 | pipe_wm->linetime = skl_compute_linetime_wm(crtc, params); | 3311 | pipe_wm->linetime = skl_compute_linetime_wm(cstate); |
3372 | 3312 | ||
3373 | skl_compute_transition_wm(crtc, params, &pipe_wm->trans_wm); | 3313 | skl_compute_transition_wm(cstate, &pipe_wm->trans_wm); |
3374 | } | 3314 | } |
3375 | 3315 | ||
3376 | static void skl_compute_wm_results(struct drm_device *dev, | 3316 | static void skl_compute_wm_results(struct drm_device *dev, |
3377 | struct skl_pipe_wm_parameters *p, | ||
3378 | struct skl_pipe_wm *p_wm, | 3317 | struct skl_pipe_wm *p_wm, |
3379 | struct skl_wm_values *r, | 3318 | struct skl_wm_values *r, |
3380 | struct intel_crtc *intel_crtc) | 3319 | struct intel_crtc *intel_crtc) |
@@ -3399,13 +3338,13 @@ static void skl_compute_wm_results(struct drm_device *dev, | |||
3399 | 3338 | ||
3400 | temp = 0; | 3339 | temp = 0; |
3401 | 3340 | ||
3402 | temp |= p_wm->wm[level].cursor_res_l << PLANE_WM_LINES_SHIFT; | 3341 | temp |= p_wm->wm[level].plane_res_l[PLANE_CURSOR] << PLANE_WM_LINES_SHIFT; |
3403 | temp |= p_wm->wm[level].cursor_res_b; | 3342 | temp |= p_wm->wm[level].plane_res_b[PLANE_CURSOR]; |
3404 | 3343 | ||
3405 | if (p_wm->wm[level].cursor_en) | 3344 | if (p_wm->wm[level].plane_en[PLANE_CURSOR]) |
3406 | temp |= PLANE_WM_EN; | 3345 | temp |= PLANE_WM_EN; |
3407 | 3346 | ||
3408 | r->cursor[pipe][level] = temp; | 3347 | r->plane[pipe][PLANE_CURSOR][level] = temp; |
3409 | 3348 | ||
3410 | } | 3349 | } |
3411 | 3350 | ||
@@ -3421,12 +3360,12 @@ static void skl_compute_wm_results(struct drm_device *dev, | |||
3421 | } | 3360 | } |
3422 | 3361 | ||
3423 | temp = 0; | 3362 | temp = 0; |
3424 | temp |= p_wm->trans_wm.cursor_res_l << PLANE_WM_LINES_SHIFT; | 3363 | temp |= p_wm->trans_wm.plane_res_l[PLANE_CURSOR] << PLANE_WM_LINES_SHIFT; |
3425 | temp |= p_wm->trans_wm.cursor_res_b; | 3364 | temp |= p_wm->trans_wm.plane_res_b[PLANE_CURSOR]; |
3426 | if (p_wm->trans_wm.cursor_en) | 3365 | if (p_wm->trans_wm.plane_en[PLANE_CURSOR]) |
3427 | temp |= PLANE_WM_EN; | 3366 | temp |= PLANE_WM_EN; |
3428 | 3367 | ||
3429 | r->cursor_trans[pipe] = temp; | 3368 | r->plane_trans[pipe][PLANE_CURSOR] = temp; |
3430 | 3369 | ||
3431 | r->wm_linetime[pipe] = p_wm->linetime; | 3370 | r->wm_linetime[pipe] = p_wm->linetime; |
3432 | } | 3371 | } |
@@ -3460,12 +3399,13 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv, | |||
3460 | I915_WRITE(PLANE_WM(pipe, i, level), | 3399 | I915_WRITE(PLANE_WM(pipe, i, level), |
3461 | new->plane[pipe][i][level]); | 3400 | new->plane[pipe][i][level]); |
3462 | I915_WRITE(CUR_WM(pipe, level), | 3401 | I915_WRITE(CUR_WM(pipe, level), |
3463 | new->cursor[pipe][level]); | 3402 | new->plane[pipe][PLANE_CURSOR][level]); |
3464 | } | 3403 | } |
3465 | for (i = 0; i < intel_num_planes(crtc); i++) | 3404 | for (i = 0; i < intel_num_planes(crtc); i++) |
3466 | I915_WRITE(PLANE_WM_TRANS(pipe, i), | 3405 | I915_WRITE(PLANE_WM_TRANS(pipe, i), |
3467 | new->plane_trans[pipe][i]); | 3406 | new->plane_trans[pipe][i]); |
3468 | I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]); | 3407 | I915_WRITE(CUR_WM_TRANS(pipe), |
3408 | new->plane_trans[pipe][PLANE_CURSOR]); | ||
3469 | 3409 | ||
3470 | for (i = 0; i < intel_num_planes(crtc); i++) { | 3410 | for (i = 0; i < intel_num_planes(crtc); i++) { |
3471 | skl_ddb_entry_write(dev_priv, | 3411 | skl_ddb_entry_write(dev_priv, |
@@ -3477,7 +3417,7 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv, | |||
3477 | } | 3417 | } |
3478 | 3418 | ||
3479 | skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), | 3419 | skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), |
3480 | &new->ddb.cursor[pipe]); | 3420 | &new->ddb.plane[pipe][PLANE_CURSOR]); |
3481 | } | 3421 | } |
3482 | } | 3422 | } |
3483 | 3423 | ||
@@ -3617,16 +3557,15 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv, | |||
3617 | } | 3557 | } |
3618 | 3558 | ||
3619 | static bool skl_update_pipe_wm(struct drm_crtc *crtc, | 3559 | static bool skl_update_pipe_wm(struct drm_crtc *crtc, |
3620 | struct skl_pipe_wm_parameters *params, | ||
3621 | struct intel_wm_config *config, | 3560 | struct intel_wm_config *config, |
3622 | struct skl_ddb_allocation *ddb, /* out */ | 3561 | struct skl_ddb_allocation *ddb, /* out */ |
3623 | struct skl_pipe_wm *pipe_wm /* out */) | 3562 | struct skl_pipe_wm *pipe_wm /* out */) |
3624 | { | 3563 | { |
3625 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3564 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3565 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); | ||
3626 | 3566 | ||
3627 | skl_compute_wm_pipe_parameters(crtc, params); | 3567 | skl_allocate_pipe_ddb(cstate, config, ddb); |
3628 | skl_allocate_pipe_ddb(crtc, config, params, ddb); | 3568 | skl_compute_pipe_wm(cstate, ddb, pipe_wm); |
3629 | skl_compute_pipe_wm(crtc, ddb, params, pipe_wm); | ||
3630 | 3569 | ||
3631 | if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm))) | 3570 | if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm))) |
3632 | return false; | 3571 | return false; |
@@ -3659,7 +3598,6 @@ static void skl_update_other_pipe_wm(struct drm_device *dev, | |||
3659 | */ | 3598 | */ |
3660 | list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, | 3599 | list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, |
3661 | base.head) { | 3600 | base.head) { |
3662 | struct skl_pipe_wm_parameters params = {}; | ||
3663 | struct skl_pipe_wm pipe_wm = {}; | 3601 | struct skl_pipe_wm pipe_wm = {}; |
3664 | bool wm_changed; | 3602 | bool wm_changed; |
3665 | 3603 | ||
@@ -3669,8 +3607,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev, | |||
3669 | if (!intel_crtc->active) | 3607 | if (!intel_crtc->active) |
3670 | continue; | 3608 | continue; |
3671 | 3609 | ||
3672 | wm_changed = skl_update_pipe_wm(&intel_crtc->base, | 3610 | wm_changed = skl_update_pipe_wm(&intel_crtc->base, config, |
3673 | ¶ms, config, | ||
3674 | &r->ddb, &pipe_wm); | 3611 | &r->ddb, &pipe_wm); |
3675 | 3612 | ||
3676 | /* | 3613 | /* |
@@ -3680,7 +3617,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev, | |||
3680 | */ | 3617 | */ |
3681 | WARN_ON(!wm_changed); | 3618 | WARN_ON(!wm_changed); |
3682 | 3619 | ||
3683 | skl_compute_wm_results(dev, ¶ms, &pipe_wm, r, intel_crtc); | 3620 | skl_compute_wm_results(dev, &pipe_wm, r, intel_crtc); |
3684 | r->dirty[intel_crtc->pipe] = true; | 3621 | r->dirty[intel_crtc->pipe] = true; |
3685 | } | 3622 | } |
3686 | } | 3623 | } |
@@ -3690,10 +3627,9 @@ static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe) | |||
3690 | watermarks->wm_linetime[pipe] = 0; | 3627 | watermarks->wm_linetime[pipe] = 0; |
3691 | memset(watermarks->plane[pipe], 0, | 3628 | memset(watermarks->plane[pipe], 0, |
3692 | sizeof(uint32_t) * 8 * I915_MAX_PLANES); | 3629 | sizeof(uint32_t) * 8 * I915_MAX_PLANES); |
3693 | memset(watermarks->cursor[pipe], 0, sizeof(uint32_t) * 8); | ||
3694 | memset(watermarks->plane_trans[pipe], | 3630 | memset(watermarks->plane_trans[pipe], |
3695 | 0, sizeof(uint32_t) * I915_MAX_PLANES); | 3631 | 0, sizeof(uint32_t) * I915_MAX_PLANES); |
3696 | watermarks->cursor_trans[pipe] = 0; | 3632 | watermarks->plane_trans[pipe][PLANE_CURSOR] = 0; |
3697 | 3633 | ||
3698 | /* Clear ddb entries for pipe */ | 3634 | /* Clear ddb entries for pipe */ |
3699 | memset(&watermarks->ddb.pipe[pipe], 0, sizeof(struct skl_ddb_entry)); | 3635 | memset(&watermarks->ddb.pipe[pipe], 0, sizeof(struct skl_ddb_entry)); |
@@ -3701,7 +3637,8 @@ static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe) | |||
3701 | sizeof(struct skl_ddb_entry) * I915_MAX_PLANES); | 3637 | sizeof(struct skl_ddb_entry) * I915_MAX_PLANES); |
3702 | memset(&watermarks->ddb.y_plane[pipe], 0, | 3638 | memset(&watermarks->ddb.y_plane[pipe], 0, |
3703 | sizeof(struct skl_ddb_entry) * I915_MAX_PLANES); | 3639 | sizeof(struct skl_ddb_entry) * I915_MAX_PLANES); |
3704 | memset(&watermarks->ddb.cursor[pipe], 0, sizeof(struct skl_ddb_entry)); | 3640 | memset(&watermarks->ddb.plane[pipe][PLANE_CURSOR], 0, |
3641 | sizeof(struct skl_ddb_entry)); | ||
3705 | 3642 | ||
3706 | } | 3643 | } |
3707 | 3644 | ||
@@ -3710,7 +3647,6 @@ static void skl_update_wm(struct drm_crtc *crtc) | |||
3710 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3647 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3711 | struct drm_device *dev = crtc->dev; | 3648 | struct drm_device *dev = crtc->dev; |
3712 | struct drm_i915_private *dev_priv = dev->dev_private; | 3649 | struct drm_i915_private *dev_priv = dev->dev_private; |
3713 | struct skl_pipe_wm_parameters params = {}; | ||
3714 | struct skl_wm_values *results = &dev_priv->wm.skl_results; | 3650 | struct skl_wm_values *results = &dev_priv->wm.skl_results; |
3715 | struct skl_pipe_wm pipe_wm = {}; | 3651 | struct skl_pipe_wm pipe_wm = {}; |
3716 | struct intel_wm_config config = {}; | 3652 | struct intel_wm_config config = {}; |
@@ -3723,11 +3659,10 @@ static void skl_update_wm(struct drm_crtc *crtc) | |||
3723 | 3659 | ||
3724 | skl_compute_wm_global_parameters(dev, &config); | 3660 | skl_compute_wm_global_parameters(dev, &config); |
3725 | 3661 | ||
3726 | if (!skl_update_pipe_wm(crtc, ¶ms, &config, | 3662 | if (!skl_update_pipe_wm(crtc, &config, &results->ddb, &pipe_wm)) |
3727 | &results->ddb, &pipe_wm)) | ||
3728 | return; | 3663 | return; |
3729 | 3664 | ||
3730 | skl_compute_wm_results(dev, ¶ms, &pipe_wm, results, intel_crtc); | 3665 | skl_compute_wm_results(dev, &pipe_wm, results, intel_crtc); |
3731 | results->dirty[intel_crtc->pipe] = true; | 3666 | results->dirty[intel_crtc->pipe] = true; |
3732 | 3667 | ||
3733 | skl_update_other_pipe_wm(dev, crtc, &config, results); | 3668 | skl_update_other_pipe_wm(dev, crtc, &config, results); |
@@ -3738,55 +3673,34 @@ static void skl_update_wm(struct drm_crtc *crtc) | |||
3738 | dev_priv->wm.skl_hw = *results; | 3673 | dev_priv->wm.skl_hw = *results; |
3739 | } | 3674 | } |
3740 | 3675 | ||
3741 | static void | ||
3742 | skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc, | ||
3743 | uint32_t sprite_width, uint32_t sprite_height, | ||
3744 | int pixel_size, bool enabled, bool scaled) | ||
3745 | { | ||
3746 | struct intel_plane *intel_plane = to_intel_plane(plane); | ||
3747 | struct drm_framebuffer *fb = plane->state->fb; | ||
3748 | |||
3749 | intel_plane->wm.enabled = enabled; | ||
3750 | intel_plane->wm.scaled = scaled; | ||
3751 | intel_plane->wm.horiz_pixels = sprite_width; | ||
3752 | intel_plane->wm.vert_pixels = sprite_height; | ||
3753 | intel_plane->wm.tiling = DRM_FORMAT_MOD_NONE; | ||
3754 | |||
3755 | /* For planar: Bpp is for UV plane, y_Bpp is for Y plane */ | ||
3756 | intel_plane->wm.bytes_per_pixel = | ||
3757 | (fb && fb->pixel_format == DRM_FORMAT_NV12) ? | ||
3758 | drm_format_plane_cpp(plane->state->fb->pixel_format, 1) : pixel_size; | ||
3759 | intel_plane->wm.y_bytes_per_pixel = | ||
3760 | (fb && fb->pixel_format == DRM_FORMAT_NV12) ? | ||
3761 | drm_format_plane_cpp(plane->state->fb->pixel_format, 0) : 0; | ||
3762 | |||
3763 | /* | ||
3764 | * Framebuffer can be NULL on plane disable, but it does not | ||
3765 | * matter for watermarks if we assume no tiling in that case. | ||
3766 | */ | ||
3767 | if (fb) | ||
3768 | intel_plane->wm.tiling = fb->modifier[0]; | ||
3769 | intel_plane->wm.rotation = plane->state->rotation; | ||
3770 | |||
3771 | skl_update_wm(crtc); | ||
3772 | } | ||
3773 | |||
3774 | static void ilk_update_wm(struct drm_crtc *crtc) | 3676 | static void ilk_update_wm(struct drm_crtc *crtc) |
3775 | { | 3677 | { |
3776 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3678 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3679 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); | ||
3777 | struct drm_device *dev = crtc->dev; | 3680 | struct drm_device *dev = crtc->dev; |
3778 | struct drm_i915_private *dev_priv = dev->dev_private; | 3681 | struct drm_i915_private *dev_priv = dev->dev_private; |
3779 | struct ilk_wm_maximums max; | 3682 | struct ilk_wm_maximums max; |
3780 | struct ilk_pipe_wm_parameters params = {}; | ||
3781 | struct ilk_wm_values results = {}; | 3683 | struct ilk_wm_values results = {}; |
3782 | enum intel_ddb_partitioning partitioning; | 3684 | enum intel_ddb_partitioning partitioning; |
3783 | struct intel_pipe_wm pipe_wm = {}; | 3685 | struct intel_pipe_wm pipe_wm = {}; |
3784 | struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; | 3686 | struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; |
3785 | struct intel_wm_config config = {}; | 3687 | struct intel_wm_config config = {}; |
3786 | 3688 | ||
3787 | ilk_compute_wm_parameters(crtc, ¶ms); | 3689 | WARN_ON(cstate->base.active != intel_crtc->active); |
3690 | |||
3691 | /* | ||
3692 | * IVB workaround: must disable low power watermarks for at least | ||
3693 | * one frame before enabling scaling. LP watermarks can be re-enabled | ||
3694 | * when scaling is disabled. | ||
3695 | * | ||
3696 | * WaCxSRDisabledForSpriteScaling:ivb | ||
3697 | */ | ||
3698 | if (cstate->disable_lp_wm) { | ||
3699 | ilk_disable_lp_wm(dev); | ||
3700 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
3701 | } | ||
3788 | 3702 | ||
3789 | intel_compute_pipe_wm(crtc, ¶ms, &pipe_wm); | 3703 | intel_compute_pipe_wm(cstate, &pipe_wm); |
3790 | 3704 | ||
3791 | if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm))) | 3705 | if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm))) |
3792 | return; | 3706 | return; |
@@ -3817,34 +3731,6 @@ static void ilk_update_wm(struct drm_crtc *crtc) | |||
3817 | ilk_write_wm_values(dev_priv, &results); | 3731 | ilk_write_wm_values(dev_priv, &results); |
3818 | } | 3732 | } |
3819 | 3733 | ||
3820 | static void | ||
3821 | ilk_update_sprite_wm(struct drm_plane *plane, | ||
3822 | struct drm_crtc *crtc, | ||
3823 | uint32_t sprite_width, uint32_t sprite_height, | ||
3824 | int pixel_size, bool enabled, bool scaled) | ||
3825 | { | ||
3826 | struct drm_device *dev = plane->dev; | ||
3827 | struct intel_plane *intel_plane = to_intel_plane(plane); | ||
3828 | |||
3829 | intel_plane->wm.enabled = enabled; | ||
3830 | intel_plane->wm.scaled = scaled; | ||
3831 | intel_plane->wm.horiz_pixels = sprite_width; | ||
3832 | intel_plane->wm.vert_pixels = sprite_width; | ||
3833 | intel_plane->wm.bytes_per_pixel = pixel_size; | ||
3834 | |||
3835 | /* | ||
3836 | * IVB workaround: must disable low power watermarks for at least | ||
3837 | * one frame before enabling scaling. LP watermarks can be re-enabled | ||
3838 | * when scaling is disabled. | ||
3839 | * | ||
3840 | * WaCxSRDisabledForSpriteScaling:ivb | ||
3841 | */ | ||
3842 | if (IS_IVYBRIDGE(dev) && scaled && ilk_disable_lp_wm(dev)) | ||
3843 | intel_wait_for_vblank(dev, intel_plane->pipe); | ||
3844 | |||
3845 | ilk_update_wm(crtc); | ||
3846 | } | ||
3847 | |||
3848 | static void skl_pipe_wm_active_state(uint32_t val, | 3734 | static void skl_pipe_wm_active_state(uint32_t val, |
3849 | struct skl_pipe_wm *active, | 3735 | struct skl_pipe_wm *active, |
3850 | bool is_transwm, | 3736 | bool is_transwm, |
@@ -3863,10 +3749,10 @@ static void skl_pipe_wm_active_state(uint32_t val, | |||
3863 | (val >> PLANE_WM_LINES_SHIFT) & | 3749 | (val >> PLANE_WM_LINES_SHIFT) & |
3864 | PLANE_WM_LINES_MASK; | 3750 | PLANE_WM_LINES_MASK; |
3865 | } else { | 3751 | } else { |
3866 | active->wm[level].cursor_en = is_enabled; | 3752 | active->wm[level].plane_en[PLANE_CURSOR] = is_enabled; |
3867 | active->wm[level].cursor_res_b = | 3753 | active->wm[level].plane_res_b[PLANE_CURSOR] = |
3868 | val & PLANE_WM_BLOCKS_MASK; | 3754 | val & PLANE_WM_BLOCKS_MASK; |
3869 | active->wm[level].cursor_res_l = | 3755 | active->wm[level].plane_res_l[PLANE_CURSOR] = |
3870 | (val >> PLANE_WM_LINES_SHIFT) & | 3756 | (val >> PLANE_WM_LINES_SHIFT) & |
3871 | PLANE_WM_LINES_MASK; | 3757 | PLANE_WM_LINES_MASK; |
3872 | } | 3758 | } |
@@ -3879,10 +3765,10 @@ static void skl_pipe_wm_active_state(uint32_t val, | |||
3879 | (val >> PLANE_WM_LINES_SHIFT) & | 3765 | (val >> PLANE_WM_LINES_SHIFT) & |
3880 | PLANE_WM_LINES_MASK; | 3766 | PLANE_WM_LINES_MASK; |
3881 | } else { | 3767 | } else { |
3882 | active->trans_wm.cursor_en = is_enabled; | 3768 | active->trans_wm.plane_en[PLANE_CURSOR] = is_enabled; |
3883 | active->trans_wm.cursor_res_b = | 3769 | active->trans_wm.plane_res_b[PLANE_CURSOR] = |
3884 | val & PLANE_WM_BLOCKS_MASK; | 3770 | val & PLANE_WM_BLOCKS_MASK; |
3885 | active->trans_wm.cursor_res_l = | 3771 | active->trans_wm.plane_res_l[PLANE_CURSOR] = |
3886 | (val >> PLANE_WM_LINES_SHIFT) & | 3772 | (val >> PLANE_WM_LINES_SHIFT) & |
3887 | PLANE_WM_LINES_MASK; | 3773 | PLANE_WM_LINES_MASK; |
3888 | } | 3774 | } |
@@ -3908,12 +3794,12 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc) | |||
3908 | for (i = 0; i < intel_num_planes(intel_crtc); i++) | 3794 | for (i = 0; i < intel_num_planes(intel_crtc); i++) |
3909 | hw->plane[pipe][i][level] = | 3795 | hw->plane[pipe][i][level] = |
3910 | I915_READ(PLANE_WM(pipe, i, level)); | 3796 | I915_READ(PLANE_WM(pipe, i, level)); |
3911 | hw->cursor[pipe][level] = I915_READ(CUR_WM(pipe, level)); | 3797 | hw->plane[pipe][PLANE_CURSOR][level] = I915_READ(CUR_WM(pipe, level)); |
3912 | } | 3798 | } |
3913 | 3799 | ||
3914 | for (i = 0; i < intel_num_planes(intel_crtc); i++) | 3800 | for (i = 0; i < intel_num_planes(intel_crtc); i++) |
3915 | hw->plane_trans[pipe][i] = I915_READ(PLANE_WM_TRANS(pipe, i)); | 3801 | hw->plane_trans[pipe][i] = I915_READ(PLANE_WM_TRANS(pipe, i)); |
3916 | hw->cursor_trans[pipe] = I915_READ(CUR_WM_TRANS(pipe)); | 3802 | hw->plane_trans[pipe][PLANE_CURSOR] = I915_READ(CUR_WM_TRANS(pipe)); |
3917 | 3803 | ||
3918 | if (!intel_crtc->active) | 3804 | if (!intel_crtc->active) |
3919 | return; | 3805 | return; |
@@ -3928,7 +3814,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc) | |||
3928 | skl_pipe_wm_active_state(temp, active, false, | 3814 | skl_pipe_wm_active_state(temp, active, false, |
3929 | false, i, level); | 3815 | false, i, level); |
3930 | } | 3816 | } |
3931 | temp = hw->cursor[pipe][level]; | 3817 | temp = hw->plane[pipe][PLANE_CURSOR][level]; |
3932 | skl_pipe_wm_active_state(temp, active, false, true, i, level); | 3818 | skl_pipe_wm_active_state(temp, active, false, true, i, level); |
3933 | } | 3819 | } |
3934 | 3820 | ||
@@ -3937,7 +3823,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc) | |||
3937 | skl_pipe_wm_active_state(temp, active, true, false, i, 0); | 3823 | skl_pipe_wm_active_state(temp, active, true, false, i, 0); |
3938 | } | 3824 | } |
3939 | 3825 | ||
3940 | temp = hw->cursor_trans[pipe]; | 3826 | temp = hw->plane_trans[pipe][PLANE_CURSOR]; |
3941 | skl_pipe_wm_active_state(temp, active, true, true, i, 0); | 3827 | skl_pipe_wm_active_state(temp, active, true, true, i, 0); |
3942 | } | 3828 | } |
3943 | 3829 | ||
@@ -4222,21 +4108,6 @@ void intel_update_watermarks(struct drm_crtc *crtc) | |||
4222 | dev_priv->display.update_wm(crtc); | 4108 | dev_priv->display.update_wm(crtc); |
4223 | } | 4109 | } |
4224 | 4110 | ||
4225 | void intel_update_sprite_watermarks(struct drm_plane *plane, | ||
4226 | struct drm_crtc *crtc, | ||
4227 | uint32_t sprite_width, | ||
4228 | uint32_t sprite_height, | ||
4229 | int pixel_size, | ||
4230 | bool enabled, bool scaled) | ||
4231 | { | ||
4232 | struct drm_i915_private *dev_priv = plane->dev->dev_private; | ||
4233 | |||
4234 | if (dev_priv->display.update_sprite_wm) | ||
4235 | dev_priv->display.update_sprite_wm(plane, crtc, | ||
4236 | sprite_width, sprite_height, | ||
4237 | pixel_size, enabled, scaled); | ||
4238 | } | ||
4239 | |||
4240 | /** | 4111 | /** |
4241 | * Lock protecting IPS related data structures | 4112 | * Lock protecting IPS related data structures |
4242 | */ | 4113 | */ |
@@ -4886,7 +4757,6 @@ static void gen9_enable_rc6(struct drm_device *dev) | |||
4886 | I915_WRITE(GUC_MAX_IDLE_COUNT, 0xA); | 4757 | I915_WRITE(GUC_MAX_IDLE_COUNT, 0xA); |
4887 | 4758 | ||
4888 | I915_WRITE(GEN6_RC_SLEEP, 0); | 4759 | I915_WRITE(GEN6_RC_SLEEP, 0); |
4889 | I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */ | ||
4890 | 4760 | ||
4891 | /* 2c: Program Coarse Power Gating Policies. */ | 4761 | /* 2c: Program Coarse Power Gating Policies. */ |
4892 | I915_WRITE(GEN9_MEDIA_PG_IDLE_HYSTERESIS, 25); | 4762 | I915_WRITE(GEN9_MEDIA_PG_IDLE_HYSTERESIS, 25); |
@@ -4897,16 +4767,19 @@ static void gen9_enable_rc6(struct drm_device *dev) | |||
4897 | rc6_mask = GEN6_RC_CTL_RC6_ENABLE; | 4767 | rc6_mask = GEN6_RC_CTL_RC6_ENABLE; |
4898 | DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ? | 4768 | DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ? |
4899 | "on" : "off"); | 4769 | "on" : "off"); |
4900 | 4770 | /* WaRsUseTimeoutMode */ | |
4901 | if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) <= SKL_REVID_D0) || | 4771 | if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) <= SKL_REVID_D0) || |
4902 | (IS_BROXTON(dev) && INTEL_REVID(dev) <= BXT_REVID_A0)) | 4772 | (IS_BROXTON(dev) && INTEL_REVID(dev) <= BXT_REVID_A0)) { |
4773 | I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us */ | ||
4903 | I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | | 4774 | I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | |
4904 | GEN7_RC_CTL_TO_MODE | | 4775 | GEN7_RC_CTL_TO_MODE | |
4905 | rc6_mask); | 4776 | rc6_mask); |
4906 | else | 4777 | } else { |
4778 | I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */ | ||
4907 | I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | | 4779 | I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | |
4908 | GEN6_RC_CTL_EI_MODE(1) | | 4780 | GEN6_RC_CTL_EI_MODE(1) | |
4909 | rc6_mask); | 4781 | rc6_mask); |
4782 | } | ||
4910 | 4783 | ||
4911 | /* | 4784 | /* |
4912 | * 3b: Enable Coarse Power Gating only when RC6 is enabled. | 4785 | * 3b: Enable Coarse Power Gating only when RC6 is enabled. |
@@ -5215,32 +5088,27 @@ static int cherryview_rps_max_freq(struct drm_i915_private *dev_priv) | |||
5215 | struct drm_device *dev = dev_priv->dev; | 5088 | struct drm_device *dev = dev_priv->dev; |
5216 | u32 val, rp0; | 5089 | u32 val, rp0; |
5217 | 5090 | ||
5218 | if (dev->pdev->revision >= 0x20) { | 5091 | val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE); |
5219 | val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE); | ||
5220 | 5092 | ||
5221 | switch (INTEL_INFO(dev)->eu_total) { | 5093 | switch (INTEL_INFO(dev)->eu_total) { |
5222 | case 8: | 5094 | case 8: |
5223 | /* (2 * 4) config */ | 5095 | /* (2 * 4) config */ |
5224 | rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS4EU_FUSE_SHIFT); | 5096 | rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS4EU_FUSE_SHIFT); |
5225 | break; | 5097 | break; |
5226 | case 12: | 5098 | case 12: |
5227 | /* (2 * 6) config */ | 5099 | /* (2 * 6) config */ |
5228 | rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS6EU_FUSE_SHIFT); | 5100 | rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS6EU_FUSE_SHIFT); |
5229 | break; | 5101 | break; |
5230 | case 16: | 5102 | case 16: |
5231 | /* (2 * 8) config */ | 5103 | /* (2 * 8) config */ |
5232 | default: | 5104 | default: |
5233 | /* Setting (2 * 8) Min RP0 for any other combination */ | 5105 | /* Setting (2 * 8) Min RP0 for any other combination */ |
5234 | rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS8EU_FUSE_SHIFT); | 5106 | rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS8EU_FUSE_SHIFT); |
5235 | break; | 5107 | break; |
5236 | } | ||
5237 | rp0 = (rp0 & FB_GFX_FREQ_FUSE_MASK); | ||
5238 | } else { | ||
5239 | /* For pre-production hardware */ | ||
5240 | val = vlv_punit_read(dev_priv, PUNIT_GPU_STATUS_REG); | ||
5241 | rp0 = (val >> PUNIT_GPU_STATUS_MAX_FREQ_SHIFT) & | ||
5242 | PUNIT_GPU_STATUS_MAX_FREQ_MASK; | ||
5243 | } | 5108 | } |
5109 | |||
5110 | rp0 = (rp0 & FB_GFX_FREQ_FUSE_MASK); | ||
5111 | |||
5244 | return rp0; | 5112 | return rp0; |
5245 | } | 5113 | } |
5246 | 5114 | ||
@@ -5256,18 +5124,11 @@ static int cherryview_rps_rpe_freq(struct drm_i915_private *dev_priv) | |||
5256 | 5124 | ||
5257 | static int cherryview_rps_guar_freq(struct drm_i915_private *dev_priv) | 5125 | static int cherryview_rps_guar_freq(struct drm_i915_private *dev_priv) |
5258 | { | 5126 | { |
5259 | struct drm_device *dev = dev_priv->dev; | ||
5260 | u32 val, rp1; | 5127 | u32 val, rp1; |
5261 | 5128 | ||
5262 | if (dev->pdev->revision >= 0x20) { | 5129 | val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE); |
5263 | val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE); | 5130 | rp1 = (val & FB_GFX_FREQ_FUSE_MASK); |
5264 | rp1 = (val & FB_GFX_FREQ_FUSE_MASK); | 5131 | |
5265 | } else { | ||
5266 | /* For pre-production hardware */ | ||
5267 | val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); | ||
5268 | rp1 = ((val >> PUNIT_GPU_STATUS_MAX_FREQ_SHIFT) & | ||
5269 | PUNIT_GPU_STATUS_MAX_FREQ_MASK); | ||
5270 | } | ||
5271 | return rp1; | 5132 | return rp1; |
5272 | } | 5133 | } |
5273 | 5134 | ||
@@ -5482,25 +5343,10 @@ static void cherryview_init_gt_powersave(struct drm_device *dev) | |||
5482 | mutex_unlock(&dev_priv->sb_lock); | 5343 | mutex_unlock(&dev_priv->sb_lock); |
5483 | 5344 | ||
5484 | switch ((val >> 2) & 0x7) { | 5345 | switch ((val >> 2) & 0x7) { |
5485 | case 0: | ||
5486 | case 1: | ||
5487 | dev_priv->rps.cz_freq = 200; | ||
5488 | dev_priv->mem_freq = 1600; | ||
5489 | break; | ||
5490 | case 2: | ||
5491 | dev_priv->rps.cz_freq = 267; | ||
5492 | dev_priv->mem_freq = 1600; | ||
5493 | break; | ||
5494 | case 3: | 5346 | case 3: |
5495 | dev_priv->rps.cz_freq = 333; | ||
5496 | dev_priv->mem_freq = 2000; | 5347 | dev_priv->mem_freq = 2000; |
5497 | break; | 5348 | break; |
5498 | case 4: | 5349 | default: |
5499 | dev_priv->rps.cz_freq = 320; | ||
5500 | dev_priv->mem_freq = 1600; | ||
5501 | break; | ||
5502 | case 5: | ||
5503 | dev_priv->rps.cz_freq = 400; | ||
5504 | dev_priv->mem_freq = 1600; | 5350 | dev_priv->mem_freq = 1600; |
5505 | break; | 5351 | break; |
5506 | } | 5352 | } |
@@ -6677,8 +6523,8 @@ static void lpt_init_clock_gating(struct drm_device *dev) | |||
6677 | PCH_LP_PARTITION_LEVEL_DISABLE); | 6523 | PCH_LP_PARTITION_LEVEL_DISABLE); |
6678 | 6524 | ||
6679 | /* WADPOClockGatingDisable:hsw */ | 6525 | /* WADPOClockGatingDisable:hsw */ |
6680 | I915_WRITE(_TRANSA_CHICKEN1, | 6526 | I915_WRITE(TRANS_CHICKEN1(PIPE_A), |
6681 | I915_READ(_TRANSA_CHICKEN1) | | 6527 | I915_READ(TRANS_CHICKEN1(PIPE_A)) | |
6682 | TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); | 6528 | TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); |
6683 | } | 6529 | } |
6684 | 6530 | ||
@@ -7176,7 +7022,6 @@ void intel_init_pm(struct drm_device *dev) | |||
7176 | dev_priv->display.init_clock_gating = | 7022 | dev_priv->display.init_clock_gating = |
7177 | skl_init_clock_gating; | 7023 | skl_init_clock_gating; |
7178 | dev_priv->display.update_wm = skl_update_wm; | 7024 | dev_priv->display.update_wm = skl_update_wm; |
7179 | dev_priv->display.update_sprite_wm = skl_update_sprite_wm; | ||
7180 | } else if (HAS_PCH_SPLIT(dev)) { | 7025 | } else if (HAS_PCH_SPLIT(dev)) { |
7181 | ilk_setup_wm_latency(dev); | 7026 | ilk_setup_wm_latency(dev); |
7182 | 7027 | ||
@@ -7185,7 +7030,6 @@ void intel_init_pm(struct drm_device *dev) | |||
7185 | (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] && | 7030 | (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] && |
7186 | dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { | 7031 | dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { |
7187 | dev_priv->display.update_wm = ilk_update_wm; | 7032 | dev_priv->display.update_wm = ilk_update_wm; |
7188 | dev_priv->display.update_sprite_wm = ilk_update_sprite_wm; | ||
7189 | } else { | 7033 | } else { |
7190 | DRM_DEBUG_KMS("Failed to read display plane latency. " | 7034 | DRM_DEBUG_KMS("Failed to read display plane latency. " |
7191 | "Disable CxSR\n"); | 7035 | "Disable CxSR\n"); |
@@ -7327,7 +7171,7 @@ static int vlv_gpu_freq_div(unsigned int czclk_freq) | |||
7327 | 7171 | ||
7328 | static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val) | 7172 | static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val) |
7329 | { | 7173 | { |
7330 | int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->mem_freq, 4); | 7174 | int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000); |
7331 | 7175 | ||
7332 | div = vlv_gpu_freq_div(czclk_freq); | 7176 | div = vlv_gpu_freq_div(czclk_freq); |
7333 | if (div < 0) | 7177 | if (div < 0) |
@@ -7338,7 +7182,7 @@ static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val) | |||
7338 | 7182 | ||
7339 | static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val) | 7183 | static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val) |
7340 | { | 7184 | { |
7341 | int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->mem_freq, 4); | 7185 | int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000); |
7342 | 7186 | ||
7343 | mul = vlv_gpu_freq_div(czclk_freq); | 7187 | mul = vlv_gpu_freq_div(czclk_freq); |
7344 | if (mul < 0) | 7188 | if (mul < 0) |
@@ -7349,7 +7193,7 @@ static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val) | |||
7349 | 7193 | ||
7350 | static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val) | 7194 | static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val) |
7351 | { | 7195 | { |
7352 | int div, czclk_freq = dev_priv->rps.cz_freq; | 7196 | int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000); |
7353 | 7197 | ||
7354 | div = vlv_gpu_freq_div(czclk_freq) / 2; | 7198 | div = vlv_gpu_freq_div(czclk_freq) / 2; |
7355 | if (div < 0) | 7199 | if (div < 0) |
@@ -7360,7 +7204,7 @@ static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val) | |||
7360 | 7204 | ||
7361 | static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val) | 7205 | static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val) |
7362 | { | 7206 | { |
7363 | int mul, czclk_freq = dev_priv->rps.cz_freq; | 7207 | int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000); |
7364 | 7208 | ||
7365 | mul = vlv_gpu_freq_div(czclk_freq) / 2; | 7209 | mul = vlv_gpu_freq_div(czclk_freq) / 2; |
7366 | if (mul < 0) | 7210 | if (mul < 0) |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 16a4eada60a1..654ae991ea13 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -717,7 +717,7 @@ static int intel_ring_workarounds_emit(struct drm_i915_gem_request *req) | |||
717 | struct drm_i915_private *dev_priv = dev->dev_private; | 717 | struct drm_i915_private *dev_priv = dev->dev_private; |
718 | struct i915_workarounds *w = &dev_priv->workarounds; | 718 | struct i915_workarounds *w = &dev_priv->workarounds; |
719 | 719 | ||
720 | if (WARN_ON_ONCE(w->count == 0)) | 720 | if (w->count == 0) |
721 | return 0; | 721 | return 0; |
722 | 722 | ||
723 | ring->gpu_caches_dirty = true; | 723 | ring->gpu_caches_dirty = true; |
@@ -800,42 +800,29 @@ static int wa_add(struct drm_i915_private *dev_priv, | |||
800 | 800 | ||
801 | #define WA_WRITE(addr, val) WA_REG(addr, 0xffffffff, val) | 801 | #define WA_WRITE(addr, val) WA_REG(addr, 0xffffffff, val) |
802 | 802 | ||
803 | static int bdw_init_workarounds(struct intel_engine_cs *ring) | 803 | static int gen8_init_workarounds(struct intel_engine_cs *ring) |
804 | { | 804 | { |
805 | struct drm_device *dev = ring->dev; | 805 | struct drm_device *dev = ring->dev; |
806 | struct drm_i915_private *dev_priv = dev->dev_private; | 806 | struct drm_i915_private *dev_priv = dev->dev_private; |
807 | 807 | ||
808 | WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING); | 808 | WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING); |
809 | 809 | ||
810 | /* WaDisableAsyncFlipPerfMode:bdw */ | 810 | /* WaDisableAsyncFlipPerfMode:bdw,chv */ |
811 | WA_SET_BIT_MASKED(MI_MODE, ASYNC_FLIP_PERF_DISABLE); | 811 | WA_SET_BIT_MASKED(MI_MODE, ASYNC_FLIP_PERF_DISABLE); |
812 | 812 | ||
813 | /* WaDisablePartialInstShootdown:bdw */ | 813 | /* WaDisablePartialInstShootdown:bdw,chv */ |
814 | /* WaDisableThreadStallDopClockGating:bdw (pre-production) */ | ||
815 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, | 814 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, |
816 | PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE | | 815 | PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); |
817 | STALL_DOP_GATING_DISABLE); | ||
818 | |||
819 | /* WaDisableDopClockGating:bdw */ | ||
820 | WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, | ||
821 | DOP_CLOCK_GATING_DISABLE); | ||
822 | |||
823 | WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, | ||
824 | GEN8_SAMPLER_POWER_BYPASS_DIS); | ||
825 | 816 | ||
826 | /* Use Force Non-Coherent whenever executing a 3D context. This is a | 817 | /* Use Force Non-Coherent whenever executing a 3D context. This is a |
827 | * workaround for for a possible hang in the unlikely event a TLB | 818 | * workaround for for a possible hang in the unlikely event a TLB |
828 | * invalidation occurs during a PSD flush. | 819 | * invalidation occurs during a PSD flush. |
829 | */ | 820 | */ |
821 | /* WaForceEnableNonCoherent:bdw,chv */ | ||
822 | /* WaHdcDisableFetchWhenMasked:bdw,chv */ | ||
830 | WA_SET_BIT_MASKED(HDC_CHICKEN0, | 823 | WA_SET_BIT_MASKED(HDC_CHICKEN0, |
831 | /* WaForceEnableNonCoherent:bdw */ | ||
832 | HDC_FORCE_NON_COHERENT | | ||
833 | /* WaForceContextSaveRestoreNonCoherent:bdw */ | ||
834 | HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT | | ||
835 | /* WaHdcDisableFetchWhenMasked:bdw */ | ||
836 | HDC_DONOT_FETCH_MEM_WHEN_MASKED | | 824 | HDC_DONOT_FETCH_MEM_WHEN_MASKED | |
837 | /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */ | 825 | HDC_FORCE_NON_COHERENT); |
838 | (IS_BDW_GT3(dev) ? HDC_FENCE_DEST_SLM_DISABLE : 0)); | ||
839 | 826 | ||
840 | /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0: | 827 | /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0: |
841 | * "The Hierarchical Z RAW Stall Optimization allows non-overlapping | 828 | * "The Hierarchical Z RAW Stall Optimization allows non-overlapping |
@@ -843,13 +830,12 @@ static int bdw_init_workarounds(struct intel_engine_cs *ring) | |||
843 | * stalling waiting for the earlier ones to write to Hierarchical Z | 830 | * stalling waiting for the earlier ones to write to Hierarchical Z |
844 | * buffer." | 831 | * buffer." |
845 | * | 832 | * |
846 | * This optimization is off by default for Broadwell; turn it on. | 833 | * This optimization is off by default for BDW and CHV; turn it on. |
847 | */ | 834 | */ |
848 | WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE); | 835 | WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE); |
849 | 836 | ||
850 | /* Wa4x4STCOptimizationDisable:bdw */ | 837 | /* Wa4x4STCOptimizationDisable:bdw,chv */ |
851 | WA_SET_BIT_MASKED(CACHE_MODE_1, | 838 | WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE); |
852 | GEN8_4x4_STC_OPTIMIZATION_DISABLE); | ||
853 | 839 | ||
854 | /* | 840 | /* |
855 | * BSpec recommends 8x4 when MSAA is used, | 841 | * BSpec recommends 8x4 when MSAA is used, |
@@ -866,56 +852,51 @@ static int bdw_init_workarounds(struct intel_engine_cs *ring) | |||
866 | return 0; | 852 | return 0; |
867 | } | 853 | } |
868 | 854 | ||
869 | static int chv_init_workarounds(struct intel_engine_cs *ring) | 855 | static int bdw_init_workarounds(struct intel_engine_cs *ring) |
870 | { | 856 | { |
857 | int ret; | ||
871 | struct drm_device *dev = ring->dev; | 858 | struct drm_device *dev = ring->dev; |
872 | struct drm_i915_private *dev_priv = dev->dev_private; | 859 | struct drm_i915_private *dev_priv = dev->dev_private; |
873 | 860 | ||
874 | WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING); | 861 | ret = gen8_init_workarounds(ring); |
862 | if (ret) | ||
863 | return ret; | ||
875 | 864 | ||
876 | /* WaDisableAsyncFlipPerfMode:chv */ | 865 | /* WaDisableThreadStallDopClockGating:bdw (pre-production) */ |
877 | WA_SET_BIT_MASKED(MI_MODE, ASYNC_FLIP_PERF_DISABLE); | 866 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE); |
878 | 867 | ||
879 | /* WaDisablePartialInstShootdown:chv */ | 868 | /* WaDisableDopClockGating:bdw */ |
880 | /* WaDisableThreadStallDopClockGating:chv */ | 869 | WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, |
881 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, | 870 | DOP_CLOCK_GATING_DISABLE); |
882 | PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE | | 871 | |
883 | STALL_DOP_GATING_DISABLE); | 872 | WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, |
873 | GEN8_SAMPLER_POWER_BYPASS_DIS); | ||
884 | 874 | ||
885 | /* Use Force Non-Coherent whenever executing a 3D context. This is a | ||
886 | * workaround for a possible hang in the unlikely event a TLB | ||
887 | * invalidation occurs during a PSD flush. | ||
888 | */ | ||
889 | /* WaForceEnableNonCoherent:chv */ | ||
890 | /* WaHdcDisableFetchWhenMasked:chv */ | ||
891 | WA_SET_BIT_MASKED(HDC_CHICKEN0, | 875 | WA_SET_BIT_MASKED(HDC_CHICKEN0, |
892 | HDC_FORCE_NON_COHERENT | | 876 | /* WaForceContextSaveRestoreNonCoherent:bdw */ |
893 | HDC_DONOT_FETCH_MEM_WHEN_MASKED); | 877 | HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT | |
878 | /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */ | ||
879 | (IS_BDW_GT3(dev) ? HDC_FENCE_DEST_SLM_DISABLE : 0)); | ||
894 | 880 | ||
895 | /* According to the CACHE_MODE_0 default value documentation, some | 881 | return 0; |
896 | * CHV platforms disable this optimization by default. Turn it on. | 882 | } |
897 | */ | ||
898 | WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE); | ||
899 | 883 | ||
900 | /* Wa4x4STCOptimizationDisable:chv */ | 884 | static int chv_init_workarounds(struct intel_engine_cs *ring) |
901 | WA_SET_BIT_MASKED(CACHE_MODE_1, | 885 | { |
902 | GEN8_4x4_STC_OPTIMIZATION_DISABLE); | 886 | int ret; |
887 | struct drm_device *dev = ring->dev; | ||
888 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
889 | |||
890 | ret = gen8_init_workarounds(ring); | ||
891 | if (ret) | ||
892 | return ret; | ||
893 | |||
894 | /* WaDisableThreadStallDopClockGating:chv */ | ||
895 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE); | ||
903 | 896 | ||
904 | /* Improve HiZ throughput on CHV. */ | 897 | /* Improve HiZ throughput on CHV. */ |
905 | WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X); | 898 | WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X); |
906 | 899 | ||
907 | /* | ||
908 | * BSpec recommends 8x4 when MSAA is used, | ||
909 | * however in practice 16x4 seems fastest. | ||
910 | * | ||
911 | * Note that PS/WM thread counts depend on the WIZ hashing | ||
912 | * disable bit, which we don't touch here, but it's good | ||
913 | * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). | ||
914 | */ | ||
915 | WA_SET_FIELD_MASKED(GEN7_GT_MODE, | ||
916 | GEN6_WIZ_HASHING_MASK, | ||
917 | GEN6_WIZ_HASHING_16x4); | ||
918 | |||
919 | return 0; | 900 | return 0; |
920 | } | 901 | } |
921 | 902 | ||
@@ -961,10 +942,9 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) | |||
961 | } | 942 | } |
962 | 943 | ||
963 | /* Wa4x4STCOptimizationDisable:skl,bxt */ | 944 | /* Wa4x4STCOptimizationDisable:skl,bxt */ |
964 | WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE); | ||
965 | |||
966 | /* WaDisablePartialResolveInVc:skl,bxt */ | 945 | /* WaDisablePartialResolveInVc:skl,bxt */ |
967 | WA_SET_BIT_MASKED(CACHE_MODE_1, GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE); | 946 | WA_SET_BIT_MASKED(CACHE_MODE_1, (GEN8_4x4_STC_OPTIMIZATION_DISABLE | |
947 | GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE)); | ||
968 | 948 | ||
969 | /* WaCcsTlbPrefetchDisable:skl,bxt */ | 949 | /* WaCcsTlbPrefetchDisable:skl,bxt */ |
970 | WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, | 950 | WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, |
@@ -1041,10 +1021,13 @@ static int skl_tune_iz_hashing(struct intel_engine_cs *ring) | |||
1041 | 1021 | ||
1042 | static int skl_init_workarounds(struct intel_engine_cs *ring) | 1022 | static int skl_init_workarounds(struct intel_engine_cs *ring) |
1043 | { | 1023 | { |
1024 | int ret; | ||
1044 | struct drm_device *dev = ring->dev; | 1025 | struct drm_device *dev = ring->dev; |
1045 | struct drm_i915_private *dev_priv = dev->dev_private; | 1026 | struct drm_i915_private *dev_priv = dev->dev_private; |
1046 | 1027 | ||
1047 | gen9_init_workarounds(ring); | 1028 | ret = gen9_init_workarounds(ring); |
1029 | if (ret) | ||
1030 | return ret; | ||
1048 | 1031 | ||
1049 | /* WaDisablePowerCompilerClockGating:skl */ | 1032 | /* WaDisablePowerCompilerClockGating:skl */ |
1050 | if (INTEL_REVID(dev) == SKL_REVID_B0) | 1033 | if (INTEL_REVID(dev) == SKL_REVID_B0) |
@@ -1081,10 +1064,13 @@ static int skl_init_workarounds(struct intel_engine_cs *ring) | |||
1081 | 1064 | ||
1082 | static int bxt_init_workarounds(struct intel_engine_cs *ring) | 1065 | static int bxt_init_workarounds(struct intel_engine_cs *ring) |
1083 | { | 1066 | { |
1067 | int ret; | ||
1084 | struct drm_device *dev = ring->dev; | 1068 | struct drm_device *dev = ring->dev; |
1085 | struct drm_i915_private *dev_priv = dev->dev_private; | 1069 | struct drm_i915_private *dev_priv = dev->dev_private; |
1086 | 1070 | ||
1087 | gen9_init_workarounds(ring); | 1071 | ret = gen9_init_workarounds(ring); |
1072 | if (ret) | ||
1073 | return ret; | ||
1088 | 1074 | ||
1089 | /* WaDisableThreadStallDopClockGating:bxt */ | 1075 | /* WaDisableThreadStallDopClockGating:bxt */ |
1090 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, | 1076 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, |
@@ -2637,6 +2623,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
2637 | GEN8_RING_SEMAPHORE_INIT; | 2623 | GEN8_RING_SEMAPHORE_INIT; |
2638 | } | 2624 | } |
2639 | } else if (INTEL_INFO(dev)->gen >= 6) { | 2625 | } else if (INTEL_INFO(dev)->gen >= 6) { |
2626 | ring->init_context = intel_rcs_ctx_init; | ||
2640 | ring->add_request = gen6_add_request; | 2627 | ring->add_request = gen6_add_request; |
2641 | ring->flush = gen7_render_ring_flush; | 2628 | ring->flush = gen7_render_ring_flush; |
2642 | if (INTEL_INFO(dev)->gen == 6) | 2629 | if (INTEL_INFO(dev)->gen == 6) |
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index d194492263eb..ec010ee74050 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c | |||
@@ -657,9 +657,15 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, | |||
657 | } | 657 | } |
658 | } else { | 658 | } else { |
659 | if (enable_requested) { | 659 | if (enable_requested) { |
660 | I915_WRITE(HSW_PWR_WELL_DRIVER, tmp & ~req_mask); | 660 | if (IS_SKYLAKE(dev) && |
661 | POSTING_READ(HSW_PWR_WELL_DRIVER); | 661 | (power_well->data == SKL_DISP_PW_1) && |
662 | DRM_DEBUG_KMS("Disabling %s\n", power_well->name); | 662 | (intel_csr_load_status_get(dev_priv) == FW_LOADED)) |
663 | DRM_DEBUG_KMS("Not Disabling PW1, dmc will handle\n"); | ||
664 | else { | ||
665 | I915_WRITE(HSW_PWR_WELL_DRIVER, tmp & ~req_mask); | ||
666 | POSTING_READ(HSW_PWR_WELL_DRIVER); | ||
667 | DRM_DEBUG_KMS("Disabling %s\n", power_well->name); | ||
668 | } | ||
663 | 669 | ||
664 | if ((GEN9_ENABLE_DC5(dev) || SKL_ENABLE_DC6(dev)) && | 670 | if ((GEN9_ENABLE_DC5(dev) || SKL_ENABLE_DC6(dev)) && |
665 | power_well->data == SKL_DISP_PW_2) { | 671 | power_well->data == SKL_DISP_PW_2) { |
@@ -988,8 +994,29 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv) | |||
988 | lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_D); | 994 | lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_D); |
989 | u32 phy_control = dev_priv->chv_phy_control; | 995 | u32 phy_control = dev_priv->chv_phy_control; |
990 | u32 phy_status = 0; | 996 | u32 phy_status = 0; |
997 | u32 phy_status_mask = 0xffffffff; | ||
991 | u32 tmp; | 998 | u32 tmp; |
992 | 999 | ||
1000 | /* | ||
1001 | * The BIOS can leave the PHY is some weird state | ||
1002 | * where it doesn't fully power down some parts. | ||
1003 | * Disable the asserts until the PHY has been fully | ||
1004 | * reset (ie. the power well has been disabled at | ||
1005 | * least once). | ||
1006 | */ | ||
1007 | if (!dev_priv->chv_phy_assert[DPIO_PHY0]) | ||
1008 | phy_status_mask &= ~(PHY_STATUS_CMN_LDO(DPIO_PHY0, DPIO_CH0) | | ||
1009 | PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH0, 0) | | ||
1010 | PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH0, 1) | | ||
1011 | PHY_STATUS_CMN_LDO(DPIO_PHY0, DPIO_CH1) | | ||
1012 | PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH1, 0) | | ||
1013 | PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH1, 1)); | ||
1014 | |||
1015 | if (!dev_priv->chv_phy_assert[DPIO_PHY1]) | ||
1016 | phy_status_mask &= ~(PHY_STATUS_CMN_LDO(DPIO_PHY1, DPIO_CH0) | | ||
1017 | PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 0) | | ||
1018 | PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 1)); | ||
1019 | |||
993 | if (cmn_bc->ops->is_enabled(dev_priv, cmn_bc)) { | 1020 | if (cmn_bc->ops->is_enabled(dev_priv, cmn_bc)) { |
994 | phy_status |= PHY_POWERGOOD(DPIO_PHY0); | 1021 | phy_status |= PHY_POWERGOOD(DPIO_PHY0); |
995 | 1022 | ||
@@ -1050,11 +1077,13 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv) | |||
1050 | phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 1); | 1077 | phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 1); |
1051 | } | 1078 | } |
1052 | 1079 | ||
1080 | phy_status &= phy_status_mask; | ||
1081 | |||
1053 | /* | 1082 | /* |
1054 | * The PHY may be busy with some initial calibration and whatnot, | 1083 | * The PHY may be busy with some initial calibration and whatnot, |
1055 | * so the power state can take a while to actually change. | 1084 | * so the power state can take a while to actually change. |
1056 | */ | 1085 | */ |
1057 | if (wait_for((tmp = I915_READ(DISPLAY_PHY_STATUS)) == phy_status, 10)) | 1086 | if (wait_for((tmp = I915_READ(DISPLAY_PHY_STATUS) & phy_status_mask) == phy_status, 10)) |
1058 | WARN(phy_status != tmp, | 1087 | WARN(phy_status != tmp, |
1059 | "Unexpected PHY_STATUS 0x%08x, expected 0x%08x (PHY_CONTROL=0x%08x)\n", | 1088 | "Unexpected PHY_STATUS 0x%08x, expected 0x%08x (PHY_CONTROL=0x%08x)\n", |
1060 | tmp, phy_status, dev_priv->chv_phy_control); | 1089 | tmp, phy_status, dev_priv->chv_phy_control); |
@@ -1147,6 +1176,9 @@ static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, | |||
1147 | DRM_DEBUG_KMS("Disabled DPIO PHY%d (PHY_CONTROL=0x%08x)\n", | 1176 | DRM_DEBUG_KMS("Disabled DPIO PHY%d (PHY_CONTROL=0x%08x)\n", |
1148 | phy, dev_priv->chv_phy_control); | 1177 | phy, dev_priv->chv_phy_control); |
1149 | 1178 | ||
1179 | /* PHY is fully reset now, so we can enable the PHY state asserts */ | ||
1180 | dev_priv->chv_phy_assert[phy] = true; | ||
1181 | |||
1150 | assert_chv_phy_status(dev_priv); | 1182 | assert_chv_phy_status(dev_priv); |
1151 | } | 1183 | } |
1152 | 1184 | ||
@@ -1156,6 +1188,16 @@ static void assert_chv_phy_powergate(struct drm_i915_private *dev_priv, enum dpi | |||
1156 | enum pipe pipe = phy == DPIO_PHY0 ? PIPE_A : PIPE_C; | 1188 | enum pipe pipe = phy == DPIO_PHY0 ? PIPE_A : PIPE_C; |
1157 | u32 reg, val, expected, actual; | 1189 | u32 reg, val, expected, actual; |
1158 | 1190 | ||
1191 | /* | ||
1192 | * The BIOS can leave the PHY is some weird state | ||
1193 | * where it doesn't fully power down some parts. | ||
1194 | * Disable the asserts until the PHY has been fully | ||
1195 | * reset (ie. the power well has been disabled at | ||
1196 | * least once). | ||
1197 | */ | ||
1198 | if (!dev_priv->chv_phy_assert[phy]) | ||
1199 | return; | ||
1200 | |||
1159 | if (ch == DPIO_CH0) | 1201 | if (ch == DPIO_CH0) |
1160 | reg = _CHV_CMN_DW0_CH0; | 1202 | reg = _CHV_CMN_DW0_CH0; |
1161 | else | 1203 | else |
@@ -1823,7 +1865,6 @@ static void intel_runtime_pm_disable(struct drm_i915_private *dev_priv) | |||
1823 | 1865 | ||
1824 | /* Make sure we're not suspended first. */ | 1866 | /* Make sure we're not suspended first. */ |
1825 | pm_runtime_get_sync(device); | 1867 | pm_runtime_get_sync(device); |
1826 | pm_runtime_disable(device); | ||
1827 | } | 1868 | } |
1828 | 1869 | ||
1829 | /** | 1870 | /** |
@@ -1912,6 +1953,10 @@ static void chv_phy_control_init(struct drm_i915_private *dev_priv) | |||
1912 | PHY_CH_POWER_DOWN_OVRD(mask, DPIO_PHY0, DPIO_CH1); | 1953 | PHY_CH_POWER_DOWN_OVRD(mask, DPIO_PHY0, DPIO_CH1); |
1913 | 1954 | ||
1914 | dev_priv->chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(DPIO_PHY0); | 1955 | dev_priv->chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(DPIO_PHY0); |
1956 | |||
1957 | dev_priv->chv_phy_assert[DPIO_PHY0] = false; | ||
1958 | } else { | ||
1959 | dev_priv->chv_phy_assert[DPIO_PHY0] = true; | ||
1915 | } | 1960 | } |
1916 | 1961 | ||
1917 | if (cmn_d->ops->is_enabled(dev_priv, cmn_d)) { | 1962 | if (cmn_d->ops->is_enabled(dev_priv, cmn_d)) { |
@@ -1930,6 +1975,10 @@ static void chv_phy_control_init(struct drm_i915_private *dev_priv) | |||
1930 | PHY_CH_POWER_DOWN_OVRD(mask, DPIO_PHY1, DPIO_CH0); | 1975 | PHY_CH_POWER_DOWN_OVRD(mask, DPIO_PHY1, DPIO_CH0); |
1931 | 1976 | ||
1932 | dev_priv->chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(DPIO_PHY1); | 1977 | dev_priv->chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(DPIO_PHY1); |
1978 | |||
1979 | dev_priv->chv_phy_assert[DPIO_PHY1] = false; | ||
1980 | } else { | ||
1981 | dev_priv->chv_phy_assert[DPIO_PHY1] = true; | ||
1933 | } | 1982 | } |
1934 | 1983 | ||
1935 | I915_WRITE(DISPLAY_PHY_CONTROL, dev_priv->chv_phy_control); | 1984 | I915_WRITE(DISPLAY_PHY_CONTROL, dev_priv->chv_phy_control); |
@@ -2115,8 +2164,6 @@ void intel_runtime_pm_enable(struct drm_i915_private *dev_priv) | |||
2115 | if (!HAS_RUNTIME_PM(dev)) | 2164 | if (!HAS_RUNTIME_PM(dev)) |
2116 | return; | 2165 | return; |
2117 | 2166 | ||
2118 | pm_runtime_set_active(device); | ||
2119 | |||
2120 | /* | 2167 | /* |
2121 | * RPM depends on RC6 to save restore the GT HW context, so make RC6 a | 2168 | * RPM depends on RC6 to save restore the GT HW context, so make RC6 a |
2122 | * requirement. | 2169 | * requirement. |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 05521b5c6878..c42b636c2087 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -107,6 +107,11 @@ struct intel_sdvo { | |||
107 | bool color_range_auto; | 107 | bool color_range_auto; |
108 | 108 | ||
109 | /** | 109 | /** |
110 | * HDMI user specified aspect ratio | ||
111 | */ | ||
112 | enum hdmi_picture_aspect aspect_ratio; | ||
113 | |||
114 | /** | ||
110 | * This is set if we're going to treat the device as TV-out. | 115 | * This is set if we're going to treat the device as TV-out. |
111 | * | 116 | * |
112 | * While we have these nice friendly flags for output types that ought | 117 | * While we have these nice friendly flags for output types that ought |
@@ -603,11 +608,11 @@ log_fail: | |||
603 | return false; | 608 | return false; |
604 | } | 609 | } |
605 | 610 | ||
606 | static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) | 611 | static int intel_sdvo_get_pixel_multiplier(const struct drm_display_mode *adjusted_mode) |
607 | { | 612 | { |
608 | if (mode->clock >= 100000) | 613 | if (adjusted_mode->crtc_clock >= 100000) |
609 | return 1; | 614 | return 1; |
610 | else if (mode->clock >= 50000) | 615 | else if (adjusted_mode->crtc_clock >= 50000) |
611 | return 2; | 616 | return 2; |
612 | else | 617 | else |
613 | return 4; | 618 | return 4; |
@@ -1181,6 +1186,10 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder, | |||
1181 | if (intel_sdvo->is_tv) | 1186 | if (intel_sdvo->is_tv) |
1182 | i9xx_adjust_sdvo_tv_clock(pipe_config); | 1187 | i9xx_adjust_sdvo_tv_clock(pipe_config); |
1183 | 1188 | ||
1189 | /* Set user selected PAR to incoming mode's member */ | ||
1190 | if (intel_sdvo->is_hdmi) | ||
1191 | adjusted_mode->picture_aspect_ratio = intel_sdvo->aspect_ratio; | ||
1192 | |||
1184 | return true; | 1193 | return true; |
1185 | } | 1194 | } |
1186 | 1195 | ||
@@ -1189,8 +1198,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder) | |||
1189 | struct drm_device *dev = intel_encoder->base.dev; | 1198 | struct drm_device *dev = intel_encoder->base.dev; |
1190 | struct drm_i915_private *dev_priv = dev->dev_private; | 1199 | struct drm_i915_private *dev_priv = dev->dev_private; |
1191 | struct intel_crtc *crtc = to_intel_crtc(intel_encoder->base.crtc); | 1200 | struct intel_crtc *crtc = to_intel_crtc(intel_encoder->base.crtc); |
1192 | struct drm_display_mode *adjusted_mode = | 1201 | const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; |
1193 | &crtc->config->base.adjusted_mode; | ||
1194 | struct drm_display_mode *mode = &crtc->config->base.mode; | 1202 | struct drm_display_mode *mode = &crtc->config->base.mode; |
1195 | struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder); | 1203 | struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder); |
1196 | u32 sdvox; | 1204 | u32 sdvox; |
@@ -2044,6 +2052,23 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
2044 | goto done; | 2052 | goto done; |
2045 | } | 2053 | } |
2046 | 2054 | ||
2055 | if (property == connector->dev->mode_config.aspect_ratio_property) { | ||
2056 | switch (val) { | ||
2057 | case DRM_MODE_PICTURE_ASPECT_NONE: | ||
2058 | intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_NONE; | ||
2059 | break; | ||
2060 | case DRM_MODE_PICTURE_ASPECT_4_3: | ||
2061 | intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_4_3; | ||
2062 | break; | ||
2063 | case DRM_MODE_PICTURE_ASPECT_16_9: | ||
2064 | intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_16_9; | ||
2065 | break; | ||
2066 | default: | ||
2067 | return -EINVAL; | ||
2068 | } | ||
2069 | goto done; | ||
2070 | } | ||
2071 | |||
2047 | #define CHECK_PROPERTY(name, NAME) \ | 2072 | #define CHECK_PROPERTY(name, NAME) \ |
2048 | if (intel_sdvo_connector->name == property) { \ | 2073 | if (intel_sdvo_connector->name == property) { \ |
2049 | if (intel_sdvo_connector->cur_##name == temp_value) return 0; \ | 2074 | if (intel_sdvo_connector->cur_##name == temp_value) return 0; \ |
@@ -2383,6 +2408,8 @@ intel_sdvo_add_hdmi_properties(struct intel_sdvo *intel_sdvo, | |||
2383 | intel_attach_broadcast_rgb_property(&connector->base.base); | 2408 | intel_attach_broadcast_rgb_property(&connector->base.base); |
2384 | intel_sdvo->color_range_auto = true; | 2409 | intel_sdvo->color_range_auto = true; |
2385 | } | 2410 | } |
2411 | intel_attach_aspect_ratio_property(&connector->base.base); | ||
2412 | intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_NONE; | ||
2386 | } | 2413 | } |
2387 | 2414 | ||
2388 | static struct intel_sdvo_connector *intel_sdvo_connector_alloc(void) | 2415 | static struct intel_sdvo_connector *intel_sdvo_connector_alloc(void) |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 4349fde4b72c..dd2d5683fcb1 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
@@ -53,13 +53,15 @@ format_is_yuv(uint32_t format) | |||
53 | } | 53 | } |
54 | } | 54 | } |
55 | 55 | ||
56 | static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs) | 56 | static int usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, |
57 | int usecs) | ||
57 | { | 58 | { |
58 | /* paranoia */ | 59 | /* paranoia */ |
59 | if (!mode->crtc_htotal) | 60 | if (!adjusted_mode->crtc_htotal) |
60 | return 1; | 61 | return 1; |
61 | 62 | ||
62 | return DIV_ROUND_UP(usecs * mode->crtc_clock, 1000 * mode->crtc_htotal); | 63 | return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock, |
64 | 1000 * adjusted_mode->crtc_htotal); | ||
63 | } | 65 | } |
64 | 66 | ||
65 | /** | 67 | /** |
@@ -79,19 +81,19 @@ static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs) | |||
79 | void intel_pipe_update_start(struct intel_crtc *crtc) | 81 | void intel_pipe_update_start(struct intel_crtc *crtc) |
80 | { | 82 | { |
81 | struct drm_device *dev = crtc->base.dev; | 83 | struct drm_device *dev = crtc->base.dev; |
82 | const struct drm_display_mode *mode = &crtc->config->base.adjusted_mode; | 84 | const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; |
83 | enum pipe pipe = crtc->pipe; | 85 | enum pipe pipe = crtc->pipe; |
84 | long timeout = msecs_to_jiffies_timeout(1); | 86 | long timeout = msecs_to_jiffies_timeout(1); |
85 | int scanline, min, max, vblank_start; | 87 | int scanline, min, max, vblank_start; |
86 | wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base); | 88 | wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base); |
87 | DEFINE_WAIT(wait); | 89 | DEFINE_WAIT(wait); |
88 | 90 | ||
89 | vblank_start = mode->crtc_vblank_start; | 91 | vblank_start = adjusted_mode->crtc_vblank_start; |
90 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | 92 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) |
91 | vblank_start = DIV_ROUND_UP(vblank_start, 2); | 93 | vblank_start = DIV_ROUND_UP(vblank_start, 2); |
92 | 94 | ||
93 | /* FIXME needs to be calibrated sensibly */ | 95 | /* FIXME needs to be calibrated sensibly */ |
94 | min = vblank_start - usecs_to_scanlines(mode, 100); | 96 | min = vblank_start - usecs_to_scanlines(adjusted_mode, 100); |
95 | max = vblank_start - 1; | 97 | max = vblank_start - 1; |
96 | 98 | ||
97 | local_irq_disable(); | 99 | local_irq_disable(); |
@@ -190,7 +192,6 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc, | |||
190 | const int pipe = intel_plane->pipe; | 192 | const int pipe = intel_plane->pipe; |
191 | const int plane = intel_plane->plane + 1; | 193 | const int plane = intel_plane->plane + 1; |
192 | u32 plane_ctl, stride_div, stride; | 194 | u32 plane_ctl, stride_div, stride; |
193 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); | ||
194 | const struct drm_intel_sprite_colorkey *key = | 195 | const struct drm_intel_sprite_colorkey *key = |
195 | &to_intel_plane_state(drm_plane->state)->ckey; | 196 | &to_intel_plane_state(drm_plane->state)->ckey; |
196 | unsigned long surf_addr; | 197 | unsigned long surf_addr; |
@@ -209,10 +210,6 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc, | |||
209 | rotation = drm_plane->state->rotation; | 210 | rotation = drm_plane->state->rotation; |
210 | plane_ctl |= skl_plane_ctl_rotation(rotation); | 211 | plane_ctl |= skl_plane_ctl_rotation(rotation); |
211 | 212 | ||
212 | intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h, | ||
213 | pixel_size, true, | ||
214 | src_w != crtc_w || src_h != crtc_h); | ||
215 | |||
216 | stride_div = intel_fb_stride_alignment(dev, fb->modifier[0], | 213 | stride_div = intel_fb_stride_alignment(dev, fb->modifier[0], |
217 | fb->pixel_format); | 214 | fb->pixel_format); |
218 | 215 | ||
@@ -294,8 +291,6 @@ skl_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) | |||
294 | 291 | ||
295 | I915_WRITE(PLANE_SURF(pipe, plane), 0); | 292 | I915_WRITE(PLANE_SURF(pipe, plane), 0); |
296 | POSTING_READ(PLANE_SURF(pipe, plane)); | 293 | POSTING_READ(PLANE_SURF(pipe, plane)); |
297 | |||
298 | intel_update_sprite_watermarks(dplane, crtc, 0, 0, 0, false, false); | ||
299 | } | 294 | } |
300 | 295 | ||
301 | static void | 296 | static void |
@@ -538,10 +533,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
538 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) | 533 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
539 | sprctl |= SPRITE_PIPE_CSC_ENABLE; | 534 | sprctl |= SPRITE_PIPE_CSC_ENABLE; |
540 | 535 | ||
541 | intel_update_sprite_watermarks(plane, crtc, src_w, src_h, pixel_size, | ||
542 | true, | ||
543 | src_w != crtc_w || src_h != crtc_h); | ||
544 | |||
545 | /* Sizes are 0 based */ | 536 | /* Sizes are 0 based */ |
546 | src_w--; | 537 | src_w--; |
547 | src_h--; | 538 | src_h--; |
@@ -675,10 +666,6 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
675 | if (IS_GEN6(dev)) | 666 | if (IS_GEN6(dev)) |
676 | dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ | 667 | dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ |
677 | 668 | ||
678 | intel_update_sprite_watermarks(plane, crtc, src_w, src_h, | ||
679 | pixel_size, true, | ||
680 | src_w != crtc_w || src_h != crtc_h); | ||
681 | |||
682 | /* Sizes are 0 based */ | 669 | /* Sizes are 0 based */ |
683 | src_w--; | 670 | src_w--; |
684 | src_h--; | 671 | src_h--; |
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 14d0831c6156..b43c6d025ac3 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c | |||
@@ -1429,21 +1429,21 @@ static int ironlake_do_reset(struct drm_device *dev) | |||
1429 | struct drm_i915_private *dev_priv = dev->dev_private; | 1429 | struct drm_i915_private *dev_priv = dev->dev_private; |
1430 | int ret; | 1430 | int ret; |
1431 | 1431 | ||
1432 | I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, | 1432 | I915_WRITE(ILK_GDSR, |
1433 | ILK_GRDOM_RENDER | ILK_GRDOM_RESET_ENABLE); | 1433 | ILK_GRDOM_RENDER | ILK_GRDOM_RESET_ENABLE); |
1434 | ret = wait_for((I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & | 1434 | ret = wait_for((I915_READ(ILK_GDSR) & |
1435 | ILK_GRDOM_RESET_ENABLE) == 0, 500); | 1435 | ILK_GRDOM_RESET_ENABLE) == 0, 500); |
1436 | if (ret) | 1436 | if (ret) |
1437 | return ret; | 1437 | return ret; |
1438 | 1438 | ||
1439 | I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, | 1439 | I915_WRITE(ILK_GDSR, |
1440 | ILK_GRDOM_MEDIA | ILK_GRDOM_RESET_ENABLE); | 1440 | ILK_GRDOM_MEDIA | ILK_GRDOM_RESET_ENABLE); |
1441 | ret = wait_for((I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & | 1441 | ret = wait_for((I915_READ(ILK_GDSR) & |
1442 | ILK_GRDOM_RESET_ENABLE) == 0, 500); | 1442 | ILK_GRDOM_RESET_ENABLE) == 0, 500); |
1443 | if (ret) | 1443 | if (ret) |
1444 | return ret; | 1444 | return ret; |
1445 | 1445 | ||
1446 | I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, 0); | 1446 | I915_WRITE(ILK_GDSR, 0); |
1447 | 1447 | ||
1448 | return 0; | 1448 | return 0; |
1449 | } | 1449 | } |
diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h index b2d56dd483d9..30d89e0da2c6 100644 --- a/include/drm/i915_component.h +++ b/include/drm/i915_component.h | |||
@@ -24,27 +24,55 @@ | |||
24 | #ifndef _I915_COMPONENT_H_ | 24 | #ifndef _I915_COMPONENT_H_ |
25 | #define _I915_COMPONENT_H_ | 25 | #define _I915_COMPONENT_H_ |
26 | 26 | ||
27 | /* MAX_PORT is the number of port | ||
28 | * It must be sync with I915_MAX_PORTS defined i915_drv.h | ||
29 | * 5 should be enough as only HSW, BDW, SKL need such fix. | ||
30 | */ | ||
31 | #define MAX_PORTS 5 | ||
32 | |||
33 | /** | ||
34 | * struct i915_audio_component_ops - callbacks defined in gfx driver | ||
35 | * @owner: the module owner | ||
36 | * @get_power: get the POWER_DOMAIN_AUDIO power well | ||
37 | * @put_power: put the POWER_DOMAIN_AUDIO power well | ||
38 | * @codec_wake_override: Enable/Disable generating the codec wake signal | ||
39 | * @get_cdclk_freq: get the Core Display Clock in KHz | ||
40 | * @sync_audio_rate: set n/cts based on the sample rate | ||
41 | */ | ||
42 | struct i915_audio_component_ops { | ||
43 | struct module *owner; | ||
44 | void (*get_power)(struct device *); | ||
45 | void (*put_power)(struct device *); | ||
46 | void (*codec_wake_override)(struct device *, bool enable); | ||
47 | int (*get_cdclk_freq)(struct device *); | ||
48 | int (*sync_audio_rate)(struct device *, int port, int rate); | ||
49 | }; | ||
50 | |||
51 | struct i915_audio_component_audio_ops { | ||
52 | void *audio_ptr; | ||
53 | /** | ||
54 | * Call from i915 driver, notifying the HDA driver that | ||
55 | * pin sense and/or ELD information has changed. | ||
56 | * @audio_ptr: HDA driver object | ||
57 | * @port: Which port has changed (PORTA / PORTB / PORTC etc) | ||
58 | */ | ||
59 | void (*pin_eld_notify)(void *audio_ptr, int port); | ||
60 | }; | ||
61 | |||
62 | /** | ||
63 | * struct i915_audio_component - used for audio video interaction | ||
64 | * @dev: the device from gfx driver | ||
65 | * @aud_sample_rate: the array of audio sample rate per port | ||
66 | * @ops: callback for audio driver calling | ||
67 | * @audio_ops: Call from i915 driver | ||
68 | */ | ||
27 | struct i915_audio_component { | 69 | struct i915_audio_component { |
28 | struct device *dev; | 70 | struct device *dev; |
71 | int aud_sample_rate[MAX_PORTS]; | ||
72 | |||
73 | const struct i915_audio_component_ops *ops; | ||
29 | 74 | ||
30 | const struct i915_audio_component_ops { | 75 | const struct i915_audio_component_audio_ops *audio_ops; |
31 | struct module *owner; | ||
32 | void (*get_power)(struct device *); | ||
33 | void (*put_power)(struct device *); | ||
34 | void (*codec_wake_override)(struct device *, bool enable); | ||
35 | int (*get_cdclk_freq)(struct device *); | ||
36 | } *ops; | ||
37 | |||
38 | const struct i915_audio_component_audio_ops { | ||
39 | void *audio_ptr; | ||
40 | /** | ||
41 | * Call from i915 driver, notifying the HDA driver that | ||
42 | * pin sense and/or ELD information has changed. | ||
43 | * @audio_ptr: HDA driver object | ||
44 | * @port: Which port has changed (PORTA / PORTB / PORTC etc) | ||
45 | */ | ||
46 | void (*pin_eld_notify)(void *audio_ptr, int port); | ||
47 | } *audio_ops; | ||
48 | }; | 76 | }; |
49 | 77 | ||
50 | #endif /* _I915_COMPONENT_H_ */ | 78 | #endif /* _I915_COMPONENT_H_ */ |
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index fd5aa47bd689..484a9fb20479 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h | |||
@@ -690,7 +690,8 @@ struct drm_i915_gem_exec_object2 { | |||
690 | #define EXEC_OBJECT_NEEDS_FENCE (1<<0) | 690 | #define EXEC_OBJECT_NEEDS_FENCE (1<<0) |
691 | #define EXEC_OBJECT_NEEDS_GTT (1<<1) | 691 | #define EXEC_OBJECT_NEEDS_GTT (1<<1) |
692 | #define EXEC_OBJECT_WRITE (1<<2) | 692 | #define EXEC_OBJECT_WRITE (1<<2) |
693 | #define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_WRITE<<1) | 693 | #define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3) |
694 | #define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_SUPPORTS_48B_ADDRESS<<1) | ||
694 | __u64 flags; | 695 | __u64 flags; |
695 | 696 | ||
696 | __u64 rsvd1; | 697 | __u64 rsvd1; |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index acbfbe087ee8..3a2d4a5a1714 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -1775,6 +1775,16 @@ static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) | |||
1775 | return non_pcm; | 1775 | return non_pcm; |
1776 | } | 1776 | } |
1777 | 1777 | ||
1778 | /* There is a fixed mapping between audio pin node and display port | ||
1779 | * on current Intel platforms: | ||
1780 | * Pin Widget 5 - PORT B (port = 1 in i915 driver) | ||
1781 | * Pin Widget 6 - PORT C (port = 2 in i915 driver) | ||
1782 | * Pin Widget 7 - PORT D (port = 3 in i915 driver) | ||
1783 | */ | ||
1784 | static int intel_pin2port(hda_nid_t pin_nid) | ||
1785 | { | ||
1786 | return pin_nid - 4; | ||
1787 | } | ||
1778 | 1788 | ||
1779 | /* | 1789 | /* |
1780 | * HDMI callbacks | 1790 | * HDMI callbacks |
@@ -1791,6 +1801,8 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1791 | int pin_idx = hinfo_to_pin_index(codec, hinfo); | 1801 | int pin_idx = hinfo_to_pin_index(codec, hinfo); |
1792 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); | 1802 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); |
1793 | hda_nid_t pin_nid = per_pin->pin_nid; | 1803 | hda_nid_t pin_nid = per_pin->pin_nid; |
1804 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
1805 | struct i915_audio_component *acomp = codec->bus->core.audio_component; | ||
1794 | bool non_pcm; | 1806 | bool non_pcm; |
1795 | int pinctl; | 1807 | int pinctl; |
1796 | 1808 | ||
@@ -1807,6 +1819,13 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1807 | intel_not_share_assigned_cvt(codec, pin_nid, per_pin->mux_idx); | 1819 | intel_not_share_assigned_cvt(codec, pin_nid, per_pin->mux_idx); |
1808 | } | 1820 | } |
1809 | 1821 | ||
1822 | /* Call sync_audio_rate to set the N/CTS/M manually if necessary */ | ||
1823 | /* Todo: add DP1.2 MST audio support later */ | ||
1824 | if (acomp && acomp->ops && acomp->ops->sync_audio_rate) | ||
1825 | acomp->ops->sync_audio_rate(acomp->dev, | ||
1826 | intel_pin2port(pin_nid), | ||
1827 | runtime->rate); | ||
1828 | |||
1810 | non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); | 1829 | non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); |
1811 | mutex_lock(&per_pin->lock); | 1830 | mutex_lock(&per_pin->lock); |
1812 | per_pin->channels = substream->runtime->channels; | 1831 | per_pin->channels = substream->runtime->channels; |