aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-12-22 14:28:02 -0500
committerDave Airlie <airlied@redhat.com>2016-12-22 14:28:02 -0500
commit4a401ceeef7bf3bc55f5e913cbf19d6038cf83c6 (patch)
tree752e305ef740477c196102bc947cce48fdd74c86
parentd043835d08b297a41275e4dd499a33dd57243dee (diff)
parent6ba0566cf2afcdb17bff882e3a95cbbcb22c4a83 (diff)
Merge tag 'drm-intel-next-fixes-2016-12-22' of git://anongit.freedesktop.org/git/drm-intel into drm-fixes
First set of i915 fixes for code in next. * tag 'drm-intel-next-fixes-2016-12-22' of git://anongit.freedesktop.org/git/drm-intel: drm/i915: skip the first 4k of stolen memory on everything >= gen8 drm/i915: Fallback to single PAGE_SIZE segments for DMA remapping drm/i915: Fix use after free in logical_render_ring_init drm/i915: disable PSR by default on HSW/BDW drm/i915: Fix setting of boost freq tunable drm/i915: tune down the fast link training vs boot fail drm/i915: Reorder phys backing storage release drm/i915/gen9: Fix PCODE polling during SAGV disabling drm/i915/gen9: Fix PCODE polling during CDCLK change notification drm/i915/dsi: Fix chv_exec_gpio disabling the GPIOs it is setting drm/i915/dsi: Fix swapping of MIPI_SEQ_DEASSERT_RESET / MIPI_SEQ_ASSERT_RESET drm/i915/dsi: Do not clear DPOUNIT_CLOCK_GATE_DISABLE from vlv_init_display_clock_gating drm/i915: drop the struct_mutex when wedged or trying to reset
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c79
-rw-r--r--drivers/gpu/drm/i915/i915_gem_stolen.c5
-rw-r--r--drivers/gpu/drm/i915/i915_sysfs.c2
-rw-r--r--drivers/gpu/drm/i915/intel_bios.h12
-rw-r--r--drivers/gpu/drm/i915/intel_display.c31
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c4
-rw-r--r--drivers/gpu/drm/i915/intel_dsi_panel_vbt.c7
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c7
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c109
-rw-r--r--drivers/gpu/drm/i915/intel_psr.c10
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c13
12 files changed, 186 insertions, 95 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 56002a52936d..243224aeabf8 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3509,6 +3509,8 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
3509 3509
3510int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val); 3510int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
3511int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val); 3511int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val);
3512int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
3513 u32 reply_mask, u32 reply, int timeout_base_ms);
3512 3514
3513/* intel_sideband.c */ 3515/* intel_sideband.c */
3514u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr); 3516u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 412f3513f269..4a31b7a891ec 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -174,21 +174,35 @@ static struct sg_table *
174i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) 174i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
175{ 175{
176 struct address_space *mapping = obj->base.filp->f_mapping; 176 struct address_space *mapping = obj->base.filp->f_mapping;
177 char *vaddr = obj->phys_handle->vaddr; 177 drm_dma_handle_t *phys;
178 struct sg_table *st; 178 struct sg_table *st;
179 struct scatterlist *sg; 179 struct scatterlist *sg;
180 char *vaddr;
180 int i; 181 int i;
181 182
182 if (WARN_ON(i915_gem_object_needs_bit17_swizzle(obj))) 183 if (WARN_ON(i915_gem_object_needs_bit17_swizzle(obj)))
183 return ERR_PTR(-EINVAL); 184 return ERR_PTR(-EINVAL);
184 185
186 /* Always aligning to the object size, allows a single allocation
187 * to handle all possible callers, and given typical object sizes,
188 * the alignment of the buddy allocation will naturally match.
189 */
190 phys = drm_pci_alloc(obj->base.dev,
191 obj->base.size,
192 roundup_pow_of_two(obj->base.size));
193 if (!phys)
194 return ERR_PTR(-ENOMEM);
195
196 vaddr = phys->vaddr;
185 for (i = 0; i < obj->base.size / PAGE_SIZE; i++) { 197 for (i = 0; i < obj->base.size / PAGE_SIZE; i++) {
186 struct page *page; 198 struct page *page;
187 char *src; 199 char *src;
188 200
189 page = shmem_read_mapping_page(mapping, i); 201 page = shmem_read_mapping_page(mapping, i);
190 if (IS_ERR(page)) 202 if (IS_ERR(page)) {
191 return ERR_CAST(page); 203 st = ERR_CAST(page);
204 goto err_phys;
205 }
192 206
193 src = kmap_atomic(page); 207 src = kmap_atomic(page);
194 memcpy(vaddr, src, PAGE_SIZE); 208 memcpy(vaddr, src, PAGE_SIZE);
@@ -202,21 +216,29 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
202 i915_gem_chipset_flush(to_i915(obj->base.dev)); 216 i915_gem_chipset_flush(to_i915(obj->base.dev));
203 217
204 st = kmalloc(sizeof(*st), GFP_KERNEL); 218 st = kmalloc(sizeof(*st), GFP_KERNEL);
205 if (st == NULL) 219 if (!st) {
206 return ERR_PTR(-ENOMEM); 220 st = ERR_PTR(-ENOMEM);
221 goto err_phys;
222 }
207 223
208 if (sg_alloc_table(st, 1, GFP_KERNEL)) { 224 if (sg_alloc_table(st, 1, GFP_KERNEL)) {
209 kfree(st); 225 kfree(st);
210 return ERR_PTR(-ENOMEM); 226 st = ERR_PTR(-ENOMEM);
227 goto err_phys;
211 } 228 }
212 229
213 sg = st->sgl; 230 sg = st->sgl;
214 sg->offset = 0; 231 sg->offset = 0;
215 sg->length = obj->base.size; 232 sg->length = obj->base.size;
216 233
217 sg_dma_address(sg) = obj->phys_handle->busaddr; 234 sg_dma_address(sg) = phys->busaddr;
218 sg_dma_len(sg) = obj->base.size; 235 sg_dma_len(sg) = obj->base.size;
219 236
237 obj->phys_handle = phys;
238 return st;
239
240err_phys:
241 drm_pci_free(obj->base.dev, phys);
220 return st; 242 return st;
221} 243}
222 244
@@ -272,12 +294,13 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj,
272 294
273 sg_free_table(pages); 295 sg_free_table(pages);
274 kfree(pages); 296 kfree(pages);
297
298 drm_pci_free(obj->base.dev, obj->phys_handle);
275} 299}
276 300
277static void 301static void
278i915_gem_object_release_phys(struct drm_i915_gem_object *obj) 302i915_gem_object_release_phys(struct drm_i915_gem_object *obj)
279{ 303{
280 drm_pci_free(obj->base.dev, obj->phys_handle);
281 i915_gem_object_unpin_pages(obj); 304 i915_gem_object_unpin_pages(obj);
282} 305}
283 306
@@ -538,15 +561,13 @@ int
538i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, 561i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
539 int align) 562 int align)
540{ 563{
541 drm_dma_handle_t *phys;
542 int ret; 564 int ret;
543 565
544 if (obj->phys_handle) { 566 if (align > obj->base.size)
545 if ((unsigned long)obj->phys_handle->vaddr & (align -1)) 567 return -EINVAL;
546 return -EBUSY;
547 568
569 if (obj->ops == &i915_gem_phys_ops)
548 return 0; 570 return 0;
549 }
550 571
551 if (obj->mm.madv != I915_MADV_WILLNEED) 572 if (obj->mm.madv != I915_MADV_WILLNEED)
552 return -EFAULT; 573 return -EFAULT;
@@ -562,12 +583,6 @@ i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
562 if (obj->mm.pages) 583 if (obj->mm.pages)
563 return -EBUSY; 584 return -EBUSY;
564 585
565 /* create a new object */
566 phys = drm_pci_alloc(obj->base.dev, obj->base.size, align);
567 if (!phys)
568 return -ENOMEM;
569
570 obj->phys_handle = phys;
571 obj->ops = &i915_gem_phys_ops; 586 obj->ops = &i915_gem_phys_ops;
572 587
573 return i915_gem_object_pin_pages(obj); 588 return i915_gem_object_pin_pages(obj);
@@ -2326,7 +2341,8 @@ static struct sg_table *
2326i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) 2341i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
2327{ 2342{
2328 struct drm_i915_private *dev_priv = to_i915(obj->base.dev); 2343 struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
2329 int page_count, i; 2344 const unsigned long page_count = obj->base.size / PAGE_SIZE;
2345 unsigned long i;
2330 struct address_space *mapping; 2346 struct address_space *mapping;
2331 struct sg_table *st; 2347 struct sg_table *st;
2332 struct scatterlist *sg; 2348 struct scatterlist *sg;
@@ -2352,7 +2368,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
2352 if (st == NULL) 2368 if (st == NULL)
2353 return ERR_PTR(-ENOMEM); 2369 return ERR_PTR(-ENOMEM);
2354 2370
2355 page_count = obj->base.size / PAGE_SIZE; 2371rebuild_st:
2356 if (sg_alloc_table(st, page_count, GFP_KERNEL)) { 2372 if (sg_alloc_table(st, page_count, GFP_KERNEL)) {
2357 kfree(st); 2373 kfree(st);
2358 return ERR_PTR(-ENOMEM); 2374 return ERR_PTR(-ENOMEM);
@@ -2411,8 +2427,25 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
2411 i915_sg_trim(st); 2427 i915_sg_trim(st);
2412 2428
2413 ret = i915_gem_gtt_prepare_pages(obj, st); 2429 ret = i915_gem_gtt_prepare_pages(obj, st);
2414 if (ret) 2430 if (ret) {
2415 goto err_pages; 2431 /* DMA remapping failed? One possible cause is that
2432 * it could not reserve enough large entries, asking
2433 * for PAGE_SIZE chunks instead may be helpful.
2434 */
2435 if (max_segment > PAGE_SIZE) {
2436 for_each_sgt_page(page, sgt_iter, st)
2437 put_page(page);
2438 sg_free_table(st);
2439
2440 max_segment = PAGE_SIZE;
2441 goto rebuild_st;
2442 } else {
2443 dev_warn(&dev_priv->drm.pdev->dev,
2444 "Failed to DMA remap %lu pages\n",
2445 page_count);
2446 goto err_pages;
2447 }
2448 }
2416 2449
2417 if (i915_gem_object_needs_bit17_swizzle(obj)) 2450 if (i915_gem_object_needs_bit17_swizzle(obj))
2418 i915_gem_object_do_bit_17_swizzle(obj, st); 2451 i915_gem_object_do_bit_17_swizzle(obj, st);
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index ebaa941c83af..abc78bbfc1dc 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -55,10 +55,9 @@ int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *dev_priv,
55 return -ENODEV; 55 return -ENODEV;
56 56
57 /* See the comment at the drm_mm_init() call for more about this check. 57 /* See the comment at the drm_mm_init() call for more about this check.
58 * WaSkipStolenMemoryFirstPage:bdw,chv,kbl (incomplete) 58 * WaSkipStolenMemoryFirstPage:bdw+ (incomplete)
59 */ 59 */
60 if (start < 4096 && (IS_GEN8(dev_priv) || 60 if (start < 4096 && INTEL_GEN(dev_priv) >= 8)
61 IS_KBL_REVID(dev_priv, 0, KBL_REVID_A0)))
62 start = 4096; 61 start = 4096;
63 62
64 mutex_lock(&dev_priv->mm.stolen_lock); 63 mutex_lock(&dev_priv->mm.stolen_lock);
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index 47590ab08d7e..3df8d3dd31cd 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -460,7 +460,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
460 460
461static DEVICE_ATTR(gt_act_freq_mhz, S_IRUGO, gt_act_freq_mhz_show, NULL); 461static DEVICE_ATTR(gt_act_freq_mhz, S_IRUGO, gt_act_freq_mhz_show, NULL);
462static DEVICE_ATTR(gt_cur_freq_mhz, S_IRUGO, gt_cur_freq_mhz_show, NULL); 462static DEVICE_ATTR(gt_cur_freq_mhz, S_IRUGO, gt_cur_freq_mhz_show, NULL);
463static DEVICE_ATTR(gt_boost_freq_mhz, S_IRUGO, gt_boost_freq_mhz_show, gt_boost_freq_mhz_store); 463static DEVICE_ATTR(gt_boost_freq_mhz, S_IRUGO | S_IWUSR, gt_boost_freq_mhz_show, gt_boost_freq_mhz_store);
464static DEVICE_ATTR(gt_max_freq_mhz, S_IRUGO | S_IWUSR, gt_max_freq_mhz_show, gt_max_freq_mhz_store); 464static DEVICE_ATTR(gt_max_freq_mhz, S_IRUGO | S_IWUSR, gt_max_freq_mhz_show, gt_max_freq_mhz_store);
465static DEVICE_ATTR(gt_min_freq_mhz, S_IRUGO | S_IWUSR, gt_min_freq_mhz_show, gt_min_freq_mhz_store); 465static DEVICE_ATTR(gt_min_freq_mhz, S_IRUGO | S_IWUSR, gt_min_freq_mhz_show, gt_min_freq_mhz_store);
466 466
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 8405b5a367d7..7e3545f65257 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -46,14 +46,20 @@ struct edp_power_seq {
46 u16 t11_t12; 46 u16 t11_t12;
47} __packed; 47} __packed;
48 48
49/* MIPI Sequence Block definitions */ 49/*
50 * MIPI Sequence Block definitions
51 *
52 * Note the VBT spec has AssertReset / DeassertReset swapped from their
53 * usual naming, we use the proper names here to avoid confusion when
54 * reading the code.
55 */
50enum mipi_seq { 56enum mipi_seq {
51 MIPI_SEQ_END = 0, 57 MIPI_SEQ_END = 0,
52 MIPI_SEQ_ASSERT_RESET, 58 MIPI_SEQ_DEASSERT_RESET, /* Spec says MipiAssertResetPin */
53 MIPI_SEQ_INIT_OTP, 59 MIPI_SEQ_INIT_OTP,
54 MIPI_SEQ_DISPLAY_ON, 60 MIPI_SEQ_DISPLAY_ON,
55 MIPI_SEQ_DISPLAY_OFF, 61 MIPI_SEQ_DISPLAY_OFF,
56 MIPI_SEQ_DEASSERT_RESET, 62 MIPI_SEQ_ASSERT_RESET, /* Spec says MipiDeassertResetPin */
57 MIPI_SEQ_BACKLIGHT_ON, /* sequence block v2+ */ 63 MIPI_SEQ_BACKLIGHT_ON, /* sequence block v2+ */
58 MIPI_SEQ_BACKLIGHT_OFF, /* sequence block v2+ */ 64 MIPI_SEQ_BACKLIGHT_OFF, /* sequence block v2+ */
59 MIPI_SEQ_TEAR_ON, /* sequence block v2+ */ 65 MIPI_SEQ_TEAR_ON, /* sequence block v2+ */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index cf5cff7b03b8..6daad8613760 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6244,35 +6244,24 @@ skl_dpll0_disable(struct drm_i915_private *dev_priv)
6244 dev_priv->cdclk_pll.vco = 0; 6244 dev_priv->cdclk_pll.vco = 0;
6245} 6245}
6246 6246
6247static bool skl_cdclk_pcu_ready(struct drm_i915_private *dev_priv)
6248{
6249 int ret;
6250 u32 val;
6251
6252 /* inform PCU we want to change CDCLK */
6253 val = SKL_CDCLK_PREPARE_FOR_CHANGE;
6254 mutex_lock(&dev_priv->rps.hw_lock);
6255 ret = sandybridge_pcode_read(dev_priv, SKL_PCODE_CDCLK_CONTROL, &val);
6256 mutex_unlock(&dev_priv->rps.hw_lock);
6257
6258 return ret == 0 && (val & SKL_CDCLK_READY_FOR_CHANGE);
6259}
6260
6261static bool skl_cdclk_wait_for_pcu_ready(struct drm_i915_private *dev_priv)
6262{
6263 return _wait_for(skl_cdclk_pcu_ready(dev_priv), 3000, 10) == 0;
6264}
6265
6266static void skl_set_cdclk(struct drm_i915_private *dev_priv, int cdclk, int vco) 6247static void skl_set_cdclk(struct drm_i915_private *dev_priv, int cdclk, int vco)
6267{ 6248{
6268 u32 freq_select, pcu_ack; 6249 u32 freq_select, pcu_ack;
6250 int ret;
6269 6251
6270 WARN_ON((cdclk == 24000) != (vco == 0)); 6252 WARN_ON((cdclk == 24000) != (vco == 0));
6271 6253
6272 DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz (VCO %d kHz)\n", cdclk, vco); 6254 DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz (VCO %d kHz)\n", cdclk, vco);
6273 6255
6274 if (!skl_cdclk_wait_for_pcu_ready(dev_priv)) { 6256 mutex_lock(&dev_priv->rps.hw_lock);
6275 DRM_ERROR("failed to inform PCU about cdclk change\n"); 6257 ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL,
6258 SKL_CDCLK_PREPARE_FOR_CHANGE,
6259 SKL_CDCLK_READY_FOR_CHANGE,
6260 SKL_CDCLK_READY_FOR_CHANGE, 3);
6261 mutex_unlock(&dev_priv->rps.hw_lock);
6262 if (ret) {
6263 DRM_ERROR("Failed to inform PCU about cdclk change (%d)\n",
6264 ret);
6276 return; 6265 return;
6277 } 6266 }
6278 6267
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 90283edcafba..d9bc19be855e 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4014,8 +4014,8 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
4014 return; 4014 return;
4015 4015
4016 /* FIXME: we need to synchronize this sort of stuff with hardware 4016 /* FIXME: we need to synchronize this sort of stuff with hardware
4017 * readout */ 4017 * readout. Currently fast link training doesn't work on boot-up. */
4018 if (WARN_ON_ONCE(!intel_dp->lane_count)) 4018 if (!intel_dp->lane_count)
4019 return; 4019 return;
4020 4020
4021 /* if link training is requested we should perform it always */ 4021 /* if link training is requested we should perform it always */
diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
index 0d8ff0034b88..47cd1b20fb3e 100644
--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -300,7 +300,8 @@ static void chv_exec_gpio(struct drm_i915_private *dev_priv,
300 mutex_lock(&dev_priv->sb_lock); 300 mutex_lock(&dev_priv->sb_lock);
301 vlv_iosf_sb_write(dev_priv, port, cfg1, 0); 301 vlv_iosf_sb_write(dev_priv, port, cfg1, 0);
302 vlv_iosf_sb_write(dev_priv, port, cfg0, 302 vlv_iosf_sb_write(dev_priv, port, cfg0,
303 CHV_GPIO_GPIOCFG_GPO | CHV_GPIO_GPIOTXSTATE(value)); 303 CHV_GPIO_GPIOEN | CHV_GPIO_GPIOCFG_GPO |
304 CHV_GPIO_GPIOTXSTATE(value));
304 mutex_unlock(&dev_priv->sb_lock); 305 mutex_unlock(&dev_priv->sb_lock);
305} 306}
306 307
@@ -376,11 +377,11 @@ static const fn_mipi_elem_exec exec_elem[] = {
376 */ 377 */
377 378
378static const char * const seq_name[] = { 379static const char * const seq_name[] = {
379 [MIPI_SEQ_ASSERT_RESET] = "MIPI_SEQ_ASSERT_RESET", 380 [MIPI_SEQ_DEASSERT_RESET] = "MIPI_SEQ_DEASSERT_RESET",
380 [MIPI_SEQ_INIT_OTP] = "MIPI_SEQ_INIT_OTP", 381 [MIPI_SEQ_INIT_OTP] = "MIPI_SEQ_INIT_OTP",
381 [MIPI_SEQ_DISPLAY_ON] = "MIPI_SEQ_DISPLAY_ON", 382 [MIPI_SEQ_DISPLAY_ON] = "MIPI_SEQ_DISPLAY_ON",
382 [MIPI_SEQ_DISPLAY_OFF] = "MIPI_SEQ_DISPLAY_OFF", 383 [MIPI_SEQ_DISPLAY_OFF] = "MIPI_SEQ_DISPLAY_OFF",
383 [MIPI_SEQ_DEASSERT_RESET] = "MIPI_SEQ_DEASSERT_RESET", 384 [MIPI_SEQ_ASSERT_RESET] = "MIPI_SEQ_ASSERT_RESET",
384 [MIPI_SEQ_BACKLIGHT_ON] = "MIPI_SEQ_BACKLIGHT_ON", 385 [MIPI_SEQ_BACKLIGHT_ON] = "MIPI_SEQ_BACKLIGHT_ON",
385 [MIPI_SEQ_BACKLIGHT_OFF] = "MIPI_SEQ_BACKLIGHT_OFF", 386 [MIPI_SEQ_BACKLIGHT_OFF] = "MIPI_SEQ_BACKLIGHT_OFF",
386 [MIPI_SEQ_TEAR_ON] = "MIPI_SEQ_TEAR_ON", 387 [MIPI_SEQ_TEAR_ON] = "MIPI_SEQ_TEAR_ON",
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 0a09024d6ca3..d4961fa20c73 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1968,12 +1968,7 @@ int logical_render_ring_init(struct intel_engine_cs *engine)
1968 ret); 1968 ret);
1969 } 1969 }
1970 1970
1971 ret = logical_ring_init(engine); 1971 return logical_ring_init(engine);
1972 if (ret) {
1973 lrc_destroy_wa_ctx_obj(engine);
1974 }
1975
1976 return ret;
1977} 1972}
1978 1973
1979int logical_xcs_ring_init(struct intel_engine_cs *engine) 1974int logical_xcs_ring_init(struct intel_engine_cs *engine)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d67974eb127a..ae2c0bb4b2e8 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2964,24 +2964,10 @@ intel_enable_sagv(struct drm_i915_private *dev_priv)
2964 return 0; 2964 return 0;
2965} 2965}
2966 2966
2967static int
2968intel_do_sagv_disable(struct drm_i915_private *dev_priv)
2969{
2970 int ret;
2971 uint32_t temp = GEN9_SAGV_DISABLE;
2972
2973 ret = sandybridge_pcode_read(dev_priv, GEN9_PCODE_SAGV_CONTROL,
2974 &temp);
2975 if (ret)
2976 return ret;
2977 else
2978 return temp & GEN9_SAGV_IS_DISABLED;
2979}
2980
2981int 2967int
2982intel_disable_sagv(struct drm_i915_private *dev_priv) 2968intel_disable_sagv(struct drm_i915_private *dev_priv)
2983{ 2969{
2984 int ret, result; 2970 int ret;
2985 2971
2986 if (!intel_has_sagv(dev_priv)) 2972 if (!intel_has_sagv(dev_priv))
2987 return 0; 2973 return 0;
@@ -2993,25 +2979,23 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
2993 mutex_lock(&dev_priv->rps.hw_lock); 2979 mutex_lock(&dev_priv->rps.hw_lock);
2994 2980
2995 /* bspec says to keep retrying for at least 1 ms */ 2981 /* bspec says to keep retrying for at least 1 ms */
2996 ret = wait_for(result = intel_do_sagv_disable(dev_priv), 1); 2982 ret = skl_pcode_request(dev_priv, GEN9_PCODE_SAGV_CONTROL,
2983 GEN9_SAGV_DISABLE,
2984 GEN9_SAGV_IS_DISABLED, GEN9_SAGV_IS_DISABLED,
2985 1);
2997 mutex_unlock(&dev_priv->rps.hw_lock); 2986 mutex_unlock(&dev_priv->rps.hw_lock);
2998 2987
2999 if (ret == -ETIMEDOUT) {
3000 DRM_ERROR("Request to disable SAGV timed out\n");
3001 return -ETIMEDOUT;
3002 }
3003
3004 /* 2988 /*
3005 * Some skl systems, pre-release machines in particular, 2989 * Some skl systems, pre-release machines in particular,
3006 * don't actually have an SAGV. 2990 * don't actually have an SAGV.
3007 */ 2991 */
3008 if (IS_SKYLAKE(dev_priv) && result == -ENXIO) { 2992 if (IS_SKYLAKE(dev_priv) && ret == -ENXIO) {
3009 DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n"); 2993 DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n");
3010 dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED; 2994 dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED;
3011 return 0; 2995 return 0;
3012 } else if (result < 0) { 2996 } else if (ret < 0) {
3013 DRM_ERROR("Failed to disable the SAGV\n"); 2997 DRM_ERROR("Failed to disable the SAGV (%d)\n", ret);
3014 return result; 2998 return ret;
3015 } 2999 }
3016 3000
3017 dev_priv->sagv_status = I915_SAGV_DISABLED; 3001 dev_priv->sagv_status = I915_SAGV_DISABLED;
@@ -7890,6 +7874,81 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
7890 return 0; 7874 return 0;
7891} 7875}
7892 7876
7877static bool skl_pcode_try_request(struct drm_i915_private *dev_priv, u32 mbox,
7878 u32 request, u32 reply_mask, u32 reply,
7879 u32 *status)
7880{
7881 u32 val = request;
7882
7883 *status = sandybridge_pcode_read(dev_priv, mbox, &val);
7884
7885 return *status || ((val & reply_mask) == reply);
7886}
7887
7888/**
7889 * skl_pcode_request - send PCODE request until acknowledgment
7890 * @dev_priv: device private
7891 * @mbox: PCODE mailbox ID the request is targeted for
7892 * @request: request ID
7893 * @reply_mask: mask used to check for request acknowledgment
7894 * @reply: value used to check for request acknowledgment
7895 * @timeout_base_ms: timeout for polling with preemption enabled
7896 *
7897 * Keep resending the @request to @mbox until PCODE acknowledges it, PCODE
7898 * reports an error or an overall timeout of @timeout_base_ms+10 ms expires.
7899 * The request is acknowledged once the PCODE reply dword equals @reply after
7900 * applying @reply_mask. Polling is first attempted with preemption enabled
7901 * for @timeout_base_ms and if this times out for another 10 ms with
7902 * preemption disabled.
7903 *
7904 * Returns 0 on success, %-ETIMEDOUT in case of a timeout, <0 in case of some
7905 * other error as reported by PCODE.
7906 */
7907int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
7908 u32 reply_mask, u32 reply, int timeout_base_ms)
7909{
7910 u32 status;
7911 int ret;
7912
7913 WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
7914
7915#define COND skl_pcode_try_request(dev_priv, mbox, request, reply_mask, reply, \
7916 &status)
7917
7918 /*
7919 * Prime the PCODE by doing a request first. Normally it guarantees
7920 * that a subsequent request, at most @timeout_base_ms later, succeeds.
7921 * _wait_for() doesn't guarantee when its passed condition is evaluated
7922 * first, so send the first request explicitly.
7923 */
7924 if (COND) {
7925 ret = 0;
7926 goto out;
7927 }
7928 ret = _wait_for(COND, timeout_base_ms * 1000, 10);
7929 if (!ret)
7930 goto out;
7931
7932 /*
7933 * The above can time out if the number of requests was low (2 in the
7934 * worst case) _and_ PCODE was busy for some reason even after a
7935 * (queued) request and @timeout_base_ms delay. As a workaround retry
7936 * the poll with preemption disabled to maximize the number of
7937 * requests. Increase the timeout from @timeout_base_ms to 10ms to
7938 * account for interrupts that could reduce the number of these
7939 * requests.
7940 */
7941 DRM_DEBUG_KMS("PCODE timeout, retrying with preemption disabled\n");
7942 WARN_ON_ONCE(timeout_base_ms > 3);
7943 preempt_disable();
7944 ret = wait_for_atomic(COND, 10);
7945 preempt_enable();
7946
7947out:
7948 return ret ? ret : status;
7949#undef COND
7950}
7951
7893static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val) 7952static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
7894{ 7953{
7895 /* 7954 /*
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index 7b488e2793d9..c6be70686b4a 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -825,13 +825,9 @@ void intel_psr_init(struct drm_device *dev)
825 dev_priv->psr_mmio_base = IS_HASWELL(dev_priv) ? 825 dev_priv->psr_mmio_base = IS_HASWELL(dev_priv) ?
826 HSW_EDP_PSR_BASE : BDW_EDP_PSR_BASE; 826 HSW_EDP_PSR_BASE : BDW_EDP_PSR_BASE;
827 827
828 /* Per platform default */ 828 /* Per platform default: all disabled. */
829 if (i915.enable_psr == -1) { 829 if (i915.enable_psr == -1)
830 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) 830 i915.enable_psr = 0;
831 i915.enable_psr = 1;
832 else
833 i915.enable_psr = 0;
834 }
835 831
836 /* Set link_standby x link_off defaults */ 832 /* Set link_standby x link_off defaults */
837 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) 833 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 356c662ad453..87b4af092d54 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -1039,7 +1039,18 @@ static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
1039 1039
1040static void vlv_init_display_clock_gating(struct drm_i915_private *dev_priv) 1040static void vlv_init_display_clock_gating(struct drm_i915_private *dev_priv)
1041{ 1041{
1042 I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE); 1042 u32 val;
1043
1044 /*
1045 * On driver load, a pipe may be active and driving a DSI display.
1046 * Preserve DPOUNIT_CLOCK_GATE_DISABLE to avoid the pipe getting stuck
1047 * (and never recovering) in this case. intel_dsi_post_disable() will
1048 * clear it when we turn off the display.
1049 */
1050 val = I915_READ(DSPCLK_GATE_D);
1051 val &= DPOUNIT_CLOCK_GATE_DISABLE;
1052 val |= VRHUNIT_CLOCK_GATE_DISABLE;
1053 I915_WRITE(DSPCLK_GATE_D, val);
1043 1054
1044 /* 1055 /*
1045 * Disable trickle feed and enable pnd deadline calculation 1056 * Disable trickle feed and enable pnd deadline calculation