diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 79 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_stolen.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_sysfs.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_bios.h | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_lrc.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 109 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_psr.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_runtime_pm.c | 13 |
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 | ||
3510 | int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val); | 3510 | int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val); |
3511 | int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val); | 3511 | 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); | ||
3512 | 3514 | ||
3513 | /* intel_sideband.c */ | 3515 | /* intel_sideband.c */ |
3514 | u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr); | 3516 | u32 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 * | |||
174 | i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) | 174 | i915_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 | |||
240 | err_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 | ||
277 | static void | 301 | static void |
278 | i915_gem_object_release_phys(struct drm_i915_gem_object *obj) | 302 | i915_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 | |||
538 | i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, | 561 | i915_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 * | |||
2326 | i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) | 2341 | i915_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; | 2371 | rebuild_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 | ||
461 | static DEVICE_ATTR(gt_act_freq_mhz, S_IRUGO, gt_act_freq_mhz_show, NULL); | 461 | static DEVICE_ATTR(gt_act_freq_mhz, S_IRUGO, gt_act_freq_mhz_show, NULL); |
462 | static DEVICE_ATTR(gt_cur_freq_mhz, S_IRUGO, gt_cur_freq_mhz_show, NULL); | 462 | 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); |
464 | static DEVICE_ATTR(gt_max_freq_mhz, S_IRUGO | S_IWUSR, gt_max_freq_mhz_show, gt_max_freq_mhz_store); | 464 | static DEVICE_ATTR(gt_max_freq_mhz, S_IRUGO | S_IWUSR, gt_max_freq_mhz_show, gt_max_freq_mhz_store); |
465 | static DEVICE_ATTR(gt_min_freq_mhz, S_IRUGO | S_IWUSR, gt_min_freq_mhz_show, gt_min_freq_mhz_store); | 465 | static 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 | */ | ||
50 | enum mipi_seq { | 56 | enum 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 | ||
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 | |||
6266 | static void skl_set_cdclk(struct drm_i915_private *dev_priv, int cdclk, int vco) | 6247 | static 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 | ||
378 | static const char * const seq_name[] = { | 379 | static 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 | ||
1979 | int logical_xcs_ring_init(struct intel_engine_cs *engine) | 1974 | int 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 | ||
2967 | static int | ||
2968 | intel_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 | |||
2981 | int | 2967 | int |
2982 | intel_disable_sagv(struct drm_i915_private *dev_priv) | 2968 | intel_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 | ||
7877 | static 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 | */ | ||
7907 | int 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 | |||
7947 | out: | ||
7948 | return ret ? ret : status; | ||
7949 | #undef COND | ||
7950 | } | ||
7951 | |||
7893 | static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val) | 7952 | static 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 | ||
1040 | static void vlv_init_display_clock_gating(struct drm_i915_private *dev_priv) | 1040 | static 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 |