Skip to content

Commit 4a401ce

Browse files
committed
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
2 parents d043835 + 6ba0566 commit 4a401ce

File tree

12 files changed

+186
-95
lines changed

12 files changed

+186
-95
lines changed

drivers/gpu/drm/i915/i915_drv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3509,6 +3509,8 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
35093509

35103510
int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
35113511
int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val);
3512+
int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
3513+
u32 reply_mask, u32 reply, int timeout_base_ms);
35123514

35133515
/* intel_sideband.c */
35143516
u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr);

drivers/gpu/drm/i915/i915_gem.c

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -174,21 +174,35 @@ static struct sg_table *
174174
i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
175175
{
176176
struct address_space *mapping = obj->base.filp->f_mapping;
177-
char *vaddr = obj->phys_handle->vaddr;
177+
drm_dma_handle_t *phys;
178178
struct sg_table *st;
179179
struct scatterlist *sg;
180+
char *vaddr;
180181
int i;
181182

182183
if (WARN_ON(i915_gem_object_needs_bit17_swizzle(obj)))
183184
return ERR_PTR(-EINVAL);
184185

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;
185197
for (i = 0; i < obj->base.size / PAGE_SIZE; i++) {
186198
struct page *page;
187199
char *src;
188200

189201
page = shmem_read_mapping_page(mapping, i);
190-
if (IS_ERR(page))
191-
return ERR_CAST(page);
202+
if (IS_ERR(page)) {
203+
st = ERR_CAST(page);
204+
goto err_phys;
205+
}
192206

193207
src = kmap_atomic(page);
194208
memcpy(vaddr, src, PAGE_SIZE);
@@ -202,21 +216,29 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
202216
i915_gem_chipset_flush(to_i915(obj->base.dev));
203217

204218
st = kmalloc(sizeof(*st), GFP_KERNEL);
205-
if (st == NULL)
206-
return ERR_PTR(-ENOMEM);
219+
if (!st) {
220+
st = ERR_PTR(-ENOMEM);
221+
goto err_phys;
222+
}
207223

208224
if (sg_alloc_table(st, 1, GFP_KERNEL)) {
209225
kfree(st);
210-
return ERR_PTR(-ENOMEM);
226+
st = ERR_PTR(-ENOMEM);
227+
goto err_phys;
211228
}
212229

213230
sg = st->sgl;
214231
sg->offset = 0;
215232
sg->length = obj->base.size;
216233

217-
sg_dma_address(sg) = obj->phys_handle->busaddr;
234+
sg_dma_address(sg) = phys->busaddr;
218235
sg_dma_len(sg) = obj->base.size;
219236

237+
obj->phys_handle = phys;
238+
return st;
239+
240+
err_phys:
241+
drm_pci_free(obj->base.dev, phys);
220242
return st;
221243
}
222244

@@ -272,12 +294,13 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj,
272294

273295
sg_free_table(pages);
274296
kfree(pages);
297+
298+
drm_pci_free(obj->base.dev, obj->phys_handle);
275299
}
276300

277301
static void
278302
i915_gem_object_release_phys(struct drm_i915_gem_object *obj)
279303
{
280-
drm_pci_free(obj->base.dev, obj->phys_handle);
281304
i915_gem_object_unpin_pages(obj);
282305
}
283306

@@ -538,15 +561,13 @@ int
538561
i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
539562
int align)
540563
{
541-
drm_dma_handle_t *phys;
542564
int ret;
543565

544-
if (obj->phys_handle) {
545-
if ((unsigned long)obj->phys_handle->vaddr & (align -1))
546-
return -EBUSY;
566+
if (align > obj->base.size)
567+
return -EINVAL;
547568

569+
if (obj->ops == &i915_gem_phys_ops)
548570
return 0;
549-
}
550571

551572
if (obj->mm.madv != I915_MADV_WILLNEED)
552573
return -EFAULT;
@@ -562,12 +583,6 @@ i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
562583
if (obj->mm.pages)
563584
return -EBUSY;
564585

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;
571586
obj->ops = &i915_gem_phys_ops;
572587

573588
return i915_gem_object_pin_pages(obj);
@@ -2326,7 +2341,8 @@ static struct sg_table *
23262341
i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
23272342
{
23282343
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;
23302346
struct address_space *mapping;
23312347
struct sg_table *st;
23322348
struct scatterlist *sg;
@@ -2352,7 +2368,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
23522368
if (st == NULL)
23532369
return ERR_PTR(-ENOMEM);
23542370

2355-
page_count = obj->base.size / PAGE_SIZE;
2371+
rebuild_st:
23562372
if (sg_alloc_table(st, page_count, GFP_KERNEL)) {
23572373
kfree(st);
23582374
return ERR_PTR(-ENOMEM);
@@ -2411,8 +2427,25 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
24112427
i915_sg_trim(st);
24122428

24132429
ret = i915_gem_gtt_prepare_pages(obj, st);
2414-
if (ret)
2415-
goto err_pages;
2430+
if (ret) {
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+
}
24162449

24172450
if (i915_gem_object_needs_bit17_swizzle(obj))
24182451
i915_gem_object_do_bit_17_swizzle(obj, st);

drivers/gpu/drm/i915/i915_gem_stolen.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,9 @@ int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *dev_priv,
5555
return -ENODEV;
5656

5757
/* See the comment at the drm_mm_init() call for more about this check.
58-
* WaSkipStolenMemoryFirstPage:bdw,chv,kbl (incomplete)
58+
* WaSkipStolenMemoryFirstPage:bdw+ (incomplete)
5959
*/
60-
if (start < 4096 && (IS_GEN8(dev_priv) ||
61-
IS_KBL_REVID(dev_priv, 0, KBL_REVID_A0)))
60+
if (start < 4096 && INTEL_GEN(dev_priv) >= 8)
6261
start = 4096;
6362

6463
mutex_lock(&dev_priv->mm.stolen_lock);

drivers/gpu/drm/i915/i915_sysfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
460460

461461
static DEVICE_ATTR(gt_act_freq_mhz, S_IRUGO, gt_act_freq_mhz_show, NULL);
462462
static DEVICE_ATTR(gt_cur_freq_mhz, S_IRUGO, gt_cur_freq_mhz_show, NULL);
463-
static DEVICE_ATTR(gt_boost_freq_mhz, S_IRUGO, gt_boost_freq_mhz_show, gt_boost_freq_mhz_store);
463+
static DEVICE_ATTR(gt_boost_freq_mhz, S_IRUGO | S_IWUSR, gt_boost_freq_mhz_show, gt_boost_freq_mhz_store);
464464
static DEVICE_ATTR(gt_max_freq_mhz, S_IRUGO | S_IWUSR, gt_max_freq_mhz_show, gt_max_freq_mhz_store);
465465
static DEVICE_ATTR(gt_min_freq_mhz, S_IRUGO | S_IWUSR, gt_min_freq_mhz_show, gt_min_freq_mhz_store);
466466

drivers/gpu/drm/i915/intel_bios.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,20 @@ struct edp_power_seq {
4646
u16 t11_t12;
4747
} __packed;
4848

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+
*/
5056
enum mipi_seq {
5157
MIPI_SEQ_END = 0,
52-
MIPI_SEQ_ASSERT_RESET,
58+
MIPI_SEQ_DEASSERT_RESET, /* Spec says MipiAssertResetPin */
5359
MIPI_SEQ_INIT_OTP,
5460
MIPI_SEQ_DISPLAY_ON,
5561
MIPI_SEQ_DISPLAY_OFF,
56-
MIPI_SEQ_DEASSERT_RESET,
62+
MIPI_SEQ_ASSERT_RESET, /* Spec says MipiDeassertResetPin */
5763
MIPI_SEQ_BACKLIGHT_ON, /* sequence block v2+ */
5864
MIPI_SEQ_BACKLIGHT_OFF, /* sequence block v2+ */
5965
MIPI_SEQ_TEAR_ON, /* sequence block v2+ */

drivers/gpu/drm/i915/intel_display.c

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6244,35 +6244,24 @@ skl_dpll0_disable(struct drm_i915_private *dev_priv)
62446244
dev_priv->cdclk_pll.vco = 0;
62456245
}
62466246

6247-
static 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-
6261-
static 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-
62666247
static void skl_set_cdclk(struct drm_i915_private *dev_priv, int cdclk, int vco)
62676248
{
62686249
u32 freq_select, pcu_ack;
6250+
int ret;
62696251

62706252
WARN_ON((cdclk == 24000) != (vco == 0));
62716253

62726254
DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz (VCO %d kHz)\n", cdclk, vco);
62736255

6274-
if (!skl_cdclk_wait_for_pcu_ready(dev_priv)) {
6275-
DRM_ERROR("failed to inform PCU about cdclk change\n");
6256+
mutex_lock(&dev_priv->rps.hw_lock);
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);
62766265
return;
62776266
}
62786267

drivers/gpu/drm/i915/intel_dp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4014,8 +4014,8 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
40144014
return;
40154015

40164016
/* FIXME: we need to synchronize this sort of stuff with hardware
4017-
* readout */
4018-
if (WARN_ON_ONCE(!intel_dp->lane_count))
4017+
* readout. Currently fast link training doesn't work on boot-up. */
4018+
if (!intel_dp->lane_count)
40194019
return;
40204020

40214021
/* if link training is requested we should perform it always */

drivers/gpu/drm/i915/intel_dsi_panel_vbt.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,8 @@ static void chv_exec_gpio(struct drm_i915_private *dev_priv,
300300
mutex_lock(&dev_priv->sb_lock);
301301
vlv_iosf_sb_write(dev_priv, port, cfg1, 0);
302302
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));
304305
mutex_unlock(&dev_priv->sb_lock);
305306
}
306307

@@ -376,11 +377,11 @@ static const fn_mipi_elem_exec exec_elem[] = {
376377
*/
377378

378379
static const char * const seq_name[] = {
379-
[MIPI_SEQ_ASSERT_RESET] = "MIPI_SEQ_ASSERT_RESET",
380+
[MIPI_SEQ_DEASSERT_RESET] = "MIPI_SEQ_DEASSERT_RESET",
380381
[MIPI_SEQ_INIT_OTP] = "MIPI_SEQ_INIT_OTP",
381382
[MIPI_SEQ_DISPLAY_ON] = "MIPI_SEQ_DISPLAY_ON",
382383
[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",
384385
[MIPI_SEQ_BACKLIGHT_ON] = "MIPI_SEQ_BACKLIGHT_ON",
385386
[MIPI_SEQ_BACKLIGHT_OFF] = "MIPI_SEQ_BACKLIGHT_OFF",
386387
[MIPI_SEQ_TEAR_ON] = "MIPI_SEQ_TEAR_ON",

drivers/gpu/drm/i915/intel_lrc.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1968,12 +1968,7 @@ int logical_render_ring_init(struct intel_engine_cs *engine)
19681968
ret);
19691969
}
19701970

1971-
ret = logical_ring_init(engine);
1972-
if (ret) {
1973-
lrc_destroy_wa_ctx_obj(engine);
1974-
}
1975-
1976-
return ret;
1971+
return logical_ring_init(engine);
19771972
}
19781973

19791974
int logical_xcs_ring_init(struct intel_engine_cs *engine)

0 commit comments

Comments
 (0)