diff options
| author | Dave Airlie <airlied@redhat.com> | 2016-11-10 18:25:32 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2016-11-10 18:25:32 -0500 |
| commit | db8feb6979e91c2e916631a75dbfe9f10f6b05e5 (patch) | |
| tree | b4aa5965f207c18d908a794e5f4e647604d77553 /drivers/gpu | |
| parent | afdd548f742ca454fc343696de472f3aaa5dc488 (diff) | |
| parent | 58e197d631d44f9f4817b8198b43132a40de1164 (diff) | |
Merge tag 'drm-intel-next-2016-11-08' of git://anongit.freedesktop.org/git/drm-intel into drm-next
- gpu idling rework for s/r (Imre)
- vlv mappable scanout fix
- speed up probing in resume (Lyude)
- dp audio workarounds for gen9 (Dhinakaran)
- more conversion to using dev_priv internally (Ville)
- more gen9+ wm fixes and cleanups (Maarten)
- shrinker cleanup&fixes (Chris)
- reorg plane init code (Ville)
- implement support for multiple timelines (prep work for scheduler)
from Chris and all
- untangle dev->struct_mutex locking as prep for multiple timelines
(Chris)
- refactor bxt phy code and collect it all in intel_dpio_phy.c (Ander)
- another gvt with bugfixes all over from Zhenyu
- piles of lspcon fixes from Imre
- 90/270 rotation fixes (Ville)
- guc log buffer support (Akash+Sagar)
- fbc fixes from Paulo
- untangle rpm vs. tiling-fences/mmaps (Chris)
- fix atomic commit to wait on the right fences (Daniel Stone)
* tag 'drm-intel-next-2016-11-08' of git://anongit.freedesktop.org/git/drm-intel: (181 commits)
drm/i915: Update DRIVER_DATE to 20161108
drm/i915: Mark CPU cache as dirty when used for rendering
drm/i915: Add assert for no pending GPU requests during suspend/resume in LR mode
drm/i915: Make sure engines are idle during GPU idling in LR mode
drm/i915: Avoid early GPU idling due to race with new request
drm/i915: Avoid early GPU idling due to already pending idle work
drm/i915: Limit Valleyview and earlier to only using mappable scanout
drm/i915: Round tile chunks up for constructing partial VMAs
drm/i915: Remove the vma from the object list upon close
drm/i915: Reinit polling before hpd when resuming
drm/i915: Remove redundant reprobe in i915_drm_resume
drm/i915/dp: Extend BDW DP audio workaround to GEN9 platforms
drm/i915/dp: BDW cdclk fix for DP audio
drm/i915: Fix pages pin counting around swizzle quirk
drm/i915: Fix test on inputs for vma_compare()
drm/i915/guc: Cache the client mapping
drm/i915: Tidy slab cache allocations
drm/i915: Introduce HAS_64BIT_RELOC
drm/i915: Show the execlist queue in debugfs/i915_engine_info
drm/i915: Unify global_list into global_link
...
Diffstat (limited to 'drivers/gpu')
77 files changed, 6751 insertions, 4782 deletions
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index 1c1b19ccb92f..df96aed6975a 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig | |||
| @@ -11,6 +11,7 @@ config DRM_I915 | |||
| 11 | select DRM_KMS_HELPER | 11 | select DRM_KMS_HELPER |
| 12 | select DRM_PANEL | 12 | select DRM_PANEL |
| 13 | select DRM_MIPI_DSI | 13 | select DRM_MIPI_DSI |
| 14 | select RELAY | ||
| 14 | # i915 depends on ACPI_VIDEO when ACPI is enabled | 15 | # i915 depends on ACPI_VIDEO when ACPI is enabled |
| 15 | # but for select to work, need to select ACPI_VIDEO's dependencies, ick | 16 | # but for select to work, need to select ACPI_VIDEO's dependencies, ick |
| 16 | select BACKLIGHT_LCD_SUPPORT if ACPI | 17 | select BACKLIGHT_LCD_SUPPORT if ACPI |
| @@ -24,16 +25,17 @@ config DRM_I915 | |||
| 24 | including 830M, 845G, 852GM, 855GM, 865G, 915G, 945G, 965G, | 25 | including 830M, 845G, 852GM, 855GM, 865G, 915G, 945G, 965G, |
| 25 | G35, G41, G43, G45 chipsets and Celeron, Pentium, Core i3, | 26 | G35, G41, G43, G45 chipsets and Celeron, Pentium, Core i3, |
| 26 | Core i5, Core i7 as well as Atom CPUs with integrated graphics. | 27 | Core i5, Core i7 as well as Atom CPUs with integrated graphics. |
| 27 | If M is selected, the module will be called i915. AGP support | 28 | |
| 28 | is required for this driver to work. This driver is used by | 29 | This driver is used by the Intel driver in X.org 6.8 and |
| 29 | the Intel driver in X.org 6.8 and XFree86 4.4 and above. It | 30 | XFree86 4.4 and above. It replaces the older i830 module that |
| 30 | replaces the older i830 module that supported a subset of the | 31 | supported a subset of the hardware in older X.org releases. |
| 31 | hardware in older X.org releases. | ||
| 32 | 32 | ||
| 33 | Note that the older i810/i815 chipsets require the use of the | 33 | Note that the older i810/i815 chipsets require the use of the |
| 34 | i810 driver instead, and the Atom z5xx series has an entirely | 34 | i810 driver instead, and the Atom z5xx series has an entirely |
| 35 | different implementation. | 35 | different implementation. |
| 36 | 36 | ||
| 37 | If "M" is selected, the module will be called i915. | ||
| 38 | |||
| 37 | config DRM_I915_PRELIMINARY_HW_SUPPORT | 39 | config DRM_I915_PRELIMINARY_HW_SUPPORT |
| 38 | bool "Enable preliminary support for prerelease Intel hardware by default" | 40 | bool "Enable preliminary support for prerelease Intel hardware by default" |
| 39 | depends on DRM_I915 | 41 | depends on DRM_I915 |
| @@ -85,6 +87,7 @@ config DRM_I915_USERPTR | |||
| 85 | config DRM_I915_GVT | 87 | config DRM_I915_GVT |
| 86 | bool "Enable Intel GVT-g graphics virtualization host support" | 88 | bool "Enable Intel GVT-g graphics virtualization host support" |
| 87 | depends on DRM_I915 | 89 | depends on DRM_I915 |
| 90 | depends on 64BIT | ||
| 88 | default n | 91 | default n |
| 89 | help | 92 | help |
| 90 | Choose this option if you want to enable Intel GVT-g graphics | 93 | Choose this option if you want to enable Intel GVT-g graphics |
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 612340097f4b..0857e5035f4d 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
| @@ -35,16 +35,19 @@ i915-y += i915_cmd_parser.o \ | |||
| 35 | i915_gem_execbuffer.o \ | 35 | i915_gem_execbuffer.o \ |
| 36 | i915_gem_fence.o \ | 36 | i915_gem_fence.o \ |
| 37 | i915_gem_gtt.o \ | 37 | i915_gem_gtt.o \ |
| 38 | i915_gem_internal.o \ | ||
| 38 | i915_gem.o \ | 39 | i915_gem.o \ |
| 39 | i915_gem_render_state.o \ | 40 | i915_gem_render_state.o \ |
| 40 | i915_gem_request.o \ | 41 | i915_gem_request.o \ |
| 41 | i915_gem_shrinker.o \ | 42 | i915_gem_shrinker.o \ |
| 42 | i915_gem_stolen.o \ | 43 | i915_gem_stolen.o \ |
| 43 | i915_gem_tiling.o \ | 44 | i915_gem_tiling.o \ |
| 45 | i915_gem_timeline.o \ | ||
| 44 | i915_gem_userptr.o \ | 46 | i915_gem_userptr.o \ |
| 45 | i915_trace_points.o \ | 47 | i915_trace_points.o \ |
| 46 | intel_breadcrumbs.o \ | 48 | intel_breadcrumbs.o \ |
| 47 | intel_engine_cs.o \ | 49 | intel_engine_cs.o \ |
| 50 | intel_hangcheck.o \ | ||
| 48 | intel_lrc.o \ | 51 | intel_lrc.o \ |
| 49 | intel_mocs.o \ | 52 | intel_mocs.o \ |
| 50 | intel_ringbuffer.o \ | 53 | intel_ringbuffer.o \ |
diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index aafb57e26288..0084ece8d8ff 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c | |||
| @@ -1145,7 +1145,7 @@ static int skl_decode_mi_display_flip(struct parser_exec_state *s, | |||
| 1145 | info->event = PRIMARY_B_FLIP_DONE; | 1145 | info->event = PRIMARY_B_FLIP_DONE; |
| 1146 | break; | 1146 | break; |
| 1147 | case MI_DISPLAY_FLIP_SKL_PLANE_1_C: | 1147 | case MI_DISPLAY_FLIP_SKL_PLANE_1_C: |
| 1148 | info->pipe = PIPE_B; | 1148 | info->pipe = PIPE_C; |
| 1149 | info->event = PRIMARY_C_FLIP_DONE; | 1149 | info->event = PRIMARY_C_FLIP_DONE; |
| 1150 | break; | 1150 | break; |
| 1151 | default: | 1151 | default: |
| @@ -1201,20 +1201,19 @@ static int gen8_update_plane_mmio_from_mi_display_flip( | |||
| 1201 | struct drm_i915_private *dev_priv = s->vgpu->gvt->dev_priv; | 1201 | struct drm_i915_private *dev_priv = s->vgpu->gvt->dev_priv; |
| 1202 | struct intel_vgpu *vgpu = s->vgpu; | 1202 | struct intel_vgpu *vgpu = s->vgpu; |
| 1203 | 1203 | ||
| 1204 | #define write_bits(reg, e, s, v) do { \ | 1204 | set_mask_bits(&vgpu_vreg(vgpu, info->surf_reg), GENMASK(31, 12), |
| 1205 | vgpu_vreg(vgpu, reg) &= ~GENMASK(e, s); \ | 1205 | info->surf_val << 12); |
| 1206 | vgpu_vreg(vgpu, reg) |= (v << s); \ | 1206 | if (IS_SKYLAKE(dev_priv)) { |
| 1207 | } while (0) | 1207 | set_mask_bits(&vgpu_vreg(vgpu, info->stride_reg), GENMASK(9, 0), |
| 1208 | 1208 | info->stride_val); | |
| 1209 | write_bits(info->surf_reg, 31, 12, info->surf_val); | 1209 | set_mask_bits(&vgpu_vreg(vgpu, info->ctrl_reg), GENMASK(12, 10), |
| 1210 | if (IS_SKYLAKE(dev_priv)) | 1210 | info->tile_val << 10); |
| 1211 | write_bits(info->stride_reg, 9, 0, info->stride_val); | 1211 | } else { |
| 1212 | else | 1212 | set_mask_bits(&vgpu_vreg(vgpu, info->stride_reg), GENMASK(15, 6), |
| 1213 | write_bits(info->stride_reg, 15, 6, info->stride_val); | 1213 | info->stride_val << 6); |
| 1214 | write_bits(info->ctrl_reg, IS_SKYLAKE(dev_priv) ? 12 : 10, | 1214 | set_mask_bits(&vgpu_vreg(vgpu, info->ctrl_reg), GENMASK(10, 10), |
| 1215 | 10, info->tile_val); | 1215 | info->tile_val << 10); |
| 1216 | 1216 | } | |
| 1217 | #undef write_bits | ||
| 1218 | 1217 | ||
| 1219 | vgpu_vreg(vgpu, PIPE_FRMCOUNT_G4X(info->pipe))++; | 1218 | vgpu_vreg(vgpu, PIPE_FRMCOUNT_G4X(info->pipe))++; |
| 1220 | intel_vgpu_trigger_virtual_event(vgpu, info->event); | 1219 | intel_vgpu_trigger_virtual_event(vgpu, info->event); |
diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 2cc761328569..6554da9f9f5b 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c | |||
| @@ -276,7 +276,7 @@ static u64 read_pte64(struct drm_i915_private *dev_priv, unsigned long index) | |||
| 276 | pte = readq(addr); | 276 | pte = readq(addr); |
| 277 | #else | 277 | #else |
| 278 | pte = ioread32(addr); | 278 | pte = ioread32(addr); |
| 279 | pte |= ioread32(addr + 4) << 32; | 279 | pte |= (u64)ioread32(addr + 4) << 32; |
| 280 | #endif | 280 | #endif |
| 281 | return pte; | 281 | return pte; |
| 282 | } | 282 | } |
| @@ -1944,7 +1944,7 @@ static int create_scratch_page(struct intel_vgpu *vgpu) | |||
| 1944 | mfn = intel_gvt_hypervisor_virt_to_mfn(vaddr); | 1944 | mfn = intel_gvt_hypervisor_virt_to_mfn(vaddr); |
| 1945 | 1945 | ||
| 1946 | if (mfn == INTEL_GVT_INVALID_ADDR) { | 1946 | if (mfn == INTEL_GVT_INVALID_ADDR) { |
| 1947 | gvt_err("fail to translate vaddr:0x%llx\n", (u64)vaddr); | 1947 | gvt_err("fail to translate vaddr: 0x%p\n", vaddr); |
| 1948 | __free_page(gtt->scratch_page); | 1948 | __free_page(gtt->scratch_page); |
| 1949 | gtt->scratch_page = NULL; | 1949 | gtt->scratch_page = NULL; |
| 1950 | return -ENXIO; | 1950 | return -ENXIO; |
diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c index 31b59d40f3fb..385969a89216 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.c +++ b/drivers/gpu/drm/i915/gvt/gvt.c | |||
| @@ -65,6 +65,8 @@ struct intel_gvt_io_emulation_ops intel_gvt_io_emulation_ops = { | |||
| 65 | */ | 65 | */ |
| 66 | int intel_gvt_init_host(void) | 66 | int intel_gvt_init_host(void) |
| 67 | { | 67 | { |
| 68 | int ret; | ||
| 69 | |||
| 68 | if (intel_gvt_host.initialized) | 70 | if (intel_gvt_host.initialized) |
| 69 | return 0; | 71 | return 0; |
| 70 | 72 | ||
| @@ -90,7 +92,8 @@ int intel_gvt_init_host(void) | |||
| 90 | return -EINVAL; | 92 | return -EINVAL; |
| 91 | 93 | ||
| 92 | /* Try to detect if we're running in host instead of VM. */ | 94 | /* Try to detect if we're running in host instead of VM. */ |
| 93 | if (!intel_gvt_hypervisor_detect_host()) | 95 | ret = intel_gvt_hypervisor_detect_host(); |
| 96 | if (ret) | ||
| 94 | return -ENODEV; | 97 | return -ENODEV; |
| 95 | 98 | ||
| 96 | gvt_dbg_core("Running with hypervisor %s in host mode\n", | 99 | gvt_dbg_core("Running with hypervisor %s in host mode\n", |
| @@ -103,19 +106,20 @@ int intel_gvt_init_host(void) | |||
| 103 | static void init_device_info(struct intel_gvt *gvt) | 106 | static void init_device_info(struct intel_gvt *gvt) |
| 104 | { | 107 | { |
| 105 | struct intel_gvt_device_info *info = &gvt->device_info; | 108 | struct intel_gvt_device_info *info = &gvt->device_info; |
| 109 | struct pci_dev *pdev = gvt->dev_priv->drm.pdev; | ||
| 106 | 110 | ||
| 107 | if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)) { | 111 | if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)) { |
| 108 | info->max_support_vgpus = 8; | 112 | info->max_support_vgpus = 8; |
| 109 | info->cfg_space_size = 256; | 113 | info->cfg_space_size = 256; |
| 110 | info->mmio_size = 2 * 1024 * 1024; | 114 | info->mmio_size = 2 * 1024 * 1024; |
| 111 | info->mmio_bar = 0; | 115 | info->mmio_bar = 0; |
| 112 | info->msi_cap_offset = IS_SKYLAKE(gvt->dev_priv) ? 0xac : 0x90; | ||
| 113 | info->gtt_start_offset = 8 * 1024 * 1024; | 116 | info->gtt_start_offset = 8 * 1024 * 1024; |
| 114 | info->gtt_entry_size = 8; | 117 | info->gtt_entry_size = 8; |
| 115 | info->gtt_entry_size_shift = 3; | 118 | info->gtt_entry_size_shift = 3; |
| 116 | info->gmadr_bytes_in_cmd = 8; | 119 | info->gmadr_bytes_in_cmd = 8; |
| 117 | info->max_surface_size = 36 * 1024 * 1024; | 120 | info->max_surface_size = 36 * 1024 * 1024; |
| 118 | } | 121 | } |
| 122 | info->msi_cap_offset = pdev->msi_cap; | ||
| 119 | } | 123 | } |
| 120 | 124 | ||
| 121 | static int gvt_service_thread(void *data) | 125 | static int gvt_service_thread(void *data) |
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 11df62b542b1..62fc9e3ac5c6 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h | |||
| @@ -382,6 +382,8 @@ void intel_vgpu_clean_opregion(struct intel_vgpu *vgpu); | |||
| 382 | int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa); | 382 | int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa); |
| 383 | 383 | ||
| 384 | int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci); | 384 | int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci); |
| 385 | int setup_vgpu_mmio(struct intel_vgpu *vgpu); | ||
| 386 | void populate_pvinfo_page(struct intel_vgpu *vgpu); | ||
| 385 | 387 | ||
| 386 | #include "mpt.h" | 388 | #include "mpt.h" |
| 387 | 389 | ||
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 3e74fb3d4aa9..9ab1f95dddc5 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c | |||
| @@ -239,7 +239,11 @@ static int handle_device_reset(struct intel_vgpu *vgpu, unsigned int offset, | |||
| 239 | vgpu->resetting = true; | 239 | vgpu->resetting = true; |
| 240 | 240 | ||
| 241 | intel_vgpu_stop_schedule(vgpu); | 241 | intel_vgpu_stop_schedule(vgpu); |
| 242 | if (scheduler->current_vgpu == vgpu) { | 242 | /* |
| 243 | * The current_vgpu will set to NULL after stopping the | ||
| 244 | * scheduler when the reset is triggered by current vgpu. | ||
| 245 | */ | ||
| 246 | if (scheduler->current_vgpu == NULL) { | ||
| 243 | mutex_unlock(&vgpu->gvt->lock); | 247 | mutex_unlock(&vgpu->gvt->lock); |
| 244 | intel_gvt_wait_vgpu_idle(vgpu); | 248 | intel_gvt_wait_vgpu_idle(vgpu); |
| 245 | mutex_lock(&vgpu->gvt->lock); | 249 | mutex_lock(&vgpu->gvt->lock); |
| @@ -247,6 +251,16 @@ static int handle_device_reset(struct intel_vgpu *vgpu, unsigned int offset, | |||
| 247 | 251 | ||
| 248 | intel_vgpu_reset_execlist(vgpu, bitmap); | 252 | intel_vgpu_reset_execlist(vgpu, bitmap); |
| 249 | 253 | ||
| 254 | /* full GPU reset */ | ||
| 255 | if (bitmap == 0xff) { | ||
| 256 | mutex_unlock(&vgpu->gvt->lock); | ||
| 257 | intel_vgpu_clean_gtt(vgpu); | ||
| 258 | mutex_lock(&vgpu->gvt->lock); | ||
| 259 | setup_vgpu_mmio(vgpu); | ||
| 260 | populate_pvinfo_page(vgpu); | ||
| 261 | intel_vgpu_init_gtt(vgpu); | ||
| 262 | } | ||
| 263 | |||
| 250 | vgpu->resetting = false; | 264 | vgpu->resetting = false; |
| 251 | 265 | ||
| 252 | return 0; | 266 | return 0; |
| @@ -258,6 +272,7 @@ static int gdrst_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, | |||
| 258 | u32 data; | 272 | u32 data; |
| 259 | u64 bitmap = 0; | 273 | u64 bitmap = 0; |
| 260 | 274 | ||
| 275 | write_vreg(vgpu, offset, p_data, bytes); | ||
| 261 | data = vgpu_vreg(vgpu, offset); | 276 | data = vgpu_vreg(vgpu, offset); |
| 262 | 277 | ||
| 263 | if (data & GEN6_GRDOM_FULL) { | 278 | if (data & GEN6_GRDOM_FULL) { |
| @@ -1305,7 +1320,7 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, | |||
| 1305 | int ring_id = render_mmio_to_ring_id(vgpu->gvt, offset); | 1320 | int ring_id = render_mmio_to_ring_id(vgpu->gvt, offset); |
| 1306 | struct intel_vgpu_execlist *execlist; | 1321 | struct intel_vgpu_execlist *execlist; |
| 1307 | u32 data = *(u32 *)p_data; | 1322 | u32 data = *(u32 *)p_data; |
| 1308 | int ret; | 1323 | int ret = 0; |
| 1309 | 1324 | ||
| 1310 | if (WARN_ON(ring_id < 0 || ring_id > I915_NUM_ENGINES - 1)) | 1325 | if (WARN_ON(ring_id < 0 || ring_id > I915_NUM_ENGINES - 1)) |
| 1311 | return -EINVAL; | 1326 | return -EINVAL; |
| @@ -1313,12 +1328,15 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, | |||
| 1313 | execlist = &vgpu->execlist[ring_id]; | 1328 | execlist = &vgpu->execlist[ring_id]; |
| 1314 | 1329 | ||
| 1315 | execlist->elsp_dwords.data[execlist->elsp_dwords.index] = data; | 1330 | execlist->elsp_dwords.data[execlist->elsp_dwords.index] = data; |
| 1316 | if (execlist->elsp_dwords.index == 3) | 1331 | if (execlist->elsp_dwords.index == 3) { |
| 1317 | ret = intel_vgpu_submit_execlist(vgpu, ring_id); | 1332 | ret = intel_vgpu_submit_execlist(vgpu, ring_id); |
| 1333 | if(ret) | ||
| 1334 | gvt_err("fail submit workload on ring %d\n", ring_id); | ||
| 1335 | } | ||
| 1318 | 1336 | ||
| 1319 | ++execlist->elsp_dwords.index; | 1337 | ++execlist->elsp_dwords.index; |
| 1320 | execlist->elsp_dwords.index &= 0x3; | 1338 | execlist->elsp_dwords.index &= 0x3; |
| 1321 | return 0; | 1339 | return ret; |
| 1322 | } | 1340 | } |
| 1323 | 1341 | ||
| 1324 | static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, | 1342 | static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, |
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c b/drivers/gpu/drm/i915/gvt/opregion.c index 973c8a9d0b15..95218913b0bc 100644 --- a/drivers/gpu/drm/i915/gvt/opregion.c +++ b/drivers/gpu/drm/i915/gvt/opregion.c | |||
| @@ -163,7 +163,7 @@ int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa) | |||
| 163 | */ | 163 | */ |
| 164 | void intel_gvt_clean_opregion(struct intel_gvt *gvt) | 164 | void intel_gvt_clean_opregion(struct intel_gvt *gvt) |
| 165 | { | 165 | { |
| 166 | iounmap(gvt->opregion.opregion_va); | 166 | memunmap(gvt->opregion.opregion_va); |
| 167 | gvt->opregion.opregion_va = NULL; | 167 | gvt->opregion.opregion_va = NULL; |
| 168 | } | 168 | } |
| 169 | 169 | ||
| @@ -181,8 +181,8 @@ int intel_gvt_init_opregion(struct intel_gvt *gvt) | |||
| 181 | pci_read_config_dword(gvt->dev_priv->drm.pdev, INTEL_GVT_PCI_OPREGION, | 181 | pci_read_config_dword(gvt->dev_priv->drm.pdev, INTEL_GVT_PCI_OPREGION, |
| 182 | &gvt->opregion.opregion_pa); | 182 | &gvt->opregion.opregion_pa); |
| 183 | 183 | ||
| 184 | gvt->opregion.opregion_va = acpi_os_ioremap(gvt->opregion.opregion_pa, | 184 | gvt->opregion.opregion_va = memremap(gvt->opregion.opregion_pa, |
| 185 | INTEL_GVT_OPREGION_SIZE); | 185 | INTEL_GVT_OPREGION_SIZE, MEMREMAP_WB); |
| 186 | if (!gvt->opregion.opregion_va) { | 186 | if (!gvt->opregion.opregion_va) { |
| 187 | gvt_err("fail to map host opregion\n"); | 187 | gvt_err("fail to map host opregion\n"); |
| 188 | return -EFAULT; | 188 | return -EFAULT; |
diff --git a/drivers/gpu/drm/i915/gvt/render.c b/drivers/gpu/drm/i915/gvt/render.c index feebb65ba641..3af894b3d257 100644 --- a/drivers/gpu/drm/i915/gvt/render.c +++ b/drivers/gpu/drm/i915/gvt/render.c | |||
| @@ -118,6 +118,7 @@ static u32 gen9_render_mocs_L3[32]; | |||
| 118 | static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id) | 118 | static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id) |
| 119 | { | 119 | { |
| 120 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | 120 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; |
| 121 | enum forcewake_domains fw; | ||
| 121 | i915_reg_t reg; | 122 | i915_reg_t reg; |
| 122 | u32 regs[] = { | 123 | u32 regs[] = { |
| 123 | [RCS] = 0x4260, | 124 | [RCS] = 0x4260, |
| @@ -135,11 +136,25 @@ static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id) | |||
| 135 | 136 | ||
| 136 | reg = _MMIO(regs[ring_id]); | 137 | reg = _MMIO(regs[ring_id]); |
| 137 | 138 | ||
| 138 | I915_WRITE(reg, 0x1); | 139 | /* WaForceWakeRenderDuringMmioTLBInvalidate:skl |
| 140 | * we need to put a forcewake when invalidating RCS TLB caches, | ||
| 141 | * otherwise device can go to RC6 state and interrupt invalidation | ||
| 142 | * process | ||
| 143 | */ | ||
| 144 | fw = intel_uncore_forcewake_for_reg(dev_priv, reg, | ||
| 145 | FW_REG_READ | FW_REG_WRITE); | ||
| 146 | if (ring_id == RCS && IS_SKYLAKE(dev_priv)) | ||
| 147 | fw |= FORCEWAKE_RENDER; | ||
| 139 | 148 | ||
| 140 | if (wait_for_atomic((I915_READ(reg) == 0), 50)) | 149 | intel_uncore_forcewake_get(dev_priv, fw); |
| 150 | |||
| 151 | I915_WRITE_FW(reg, 0x1); | ||
| 152 | |||
| 153 | if (wait_for_atomic((I915_READ_FW(reg) == 0), 50)) | ||
| 141 | gvt_err("timeout in invalidate ring (%d) tlb\n", ring_id); | 154 | gvt_err("timeout in invalidate ring (%d) tlb\n", ring_id); |
| 142 | 155 | ||
| 156 | intel_uncore_forcewake_put(dev_priv, fw); | ||
| 157 | |||
| 143 | gvt_dbg_core("invalidate TLB for ring %d\n", ring_id); | 158 | gvt_dbg_core("invalidate TLB for ring %d\n", ring_id); |
| 144 | } | 159 | } |
| 145 | 160 | ||
| @@ -162,6 +177,7 @@ static void load_mocs(struct intel_vgpu *vgpu, int ring_id) | |||
| 162 | if (!IS_SKYLAKE(dev_priv)) | 177 | if (!IS_SKYLAKE(dev_priv)) |
| 163 | return; | 178 | return; |
| 164 | 179 | ||
| 180 | offset.reg = regs[ring_id]; | ||
| 165 | for (i = 0; i < 64; i++) { | 181 | for (i = 0; i < 64; i++) { |
| 166 | gen9_render_mocs[ring_id][i] = I915_READ(offset); | 182 | gen9_render_mocs[ring_id][i] = I915_READ(offset); |
| 167 | I915_WRITE(offset, vgpu_vreg(vgpu, offset)); | 183 | I915_WRITE(offset, vgpu_vreg(vgpu, offset)); |
| @@ -199,6 +215,7 @@ static void restore_mocs(struct intel_vgpu *vgpu, int ring_id) | |||
| 199 | if (!IS_SKYLAKE(dev_priv)) | 215 | if (!IS_SKYLAKE(dev_priv)) |
| 200 | return; | 216 | return; |
| 201 | 217 | ||
| 218 | offset.reg = regs[ring_id]; | ||
| 202 | for (i = 0; i < 64; i++) { | 219 | for (i = 0; i < 64; i++) { |
| 203 | vgpu_vreg(vgpu, offset) = I915_READ(offset); | 220 | vgpu_vreg(vgpu, offset) = I915_READ(offset); |
| 204 | I915_WRITE(offset, gen9_render_mocs[ring_id][i]); | 221 | I915_WRITE(offset, gen9_render_mocs[ring_id][i]); |
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index e96eaeebeb0a..18acb45dd14d 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c | |||
| @@ -400,21 +400,27 @@ static int workload_thread(void *priv) | |||
| 400 | int ring_id = p->ring_id; | 400 | int ring_id = p->ring_id; |
| 401 | struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; | 401 | struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; |
| 402 | struct intel_vgpu_workload *workload = NULL; | 402 | struct intel_vgpu_workload *workload = NULL; |
| 403 | long lret; | ||
| 403 | int ret; | 404 | int ret; |
| 404 | bool need_force_wake = IS_SKYLAKE(gvt->dev_priv); | 405 | bool need_force_wake = IS_SKYLAKE(gvt->dev_priv); |
| 406 | DEFINE_WAIT_FUNC(wait, woken_wake_function); | ||
| 405 | 407 | ||
| 406 | kfree(p); | 408 | kfree(p); |
| 407 | 409 | ||
| 408 | gvt_dbg_core("workload thread for ring %d started\n", ring_id); | 410 | gvt_dbg_core("workload thread for ring %d started\n", ring_id); |
| 409 | 411 | ||
| 410 | while (!kthread_should_stop()) { | 412 | while (!kthread_should_stop()) { |
| 411 | ret = wait_event_interruptible(scheduler->waitq[ring_id], | 413 | add_wait_queue(&scheduler->waitq[ring_id], &wait); |
| 412 | kthread_should_stop() || | 414 | do { |
| 413 | (workload = pick_next_workload(gvt, ring_id))); | 415 | workload = pick_next_workload(gvt, ring_id); |
| 414 | 416 | if (workload) | |
| 415 | WARN_ON_ONCE(ret); | 417 | break; |
| 416 | 418 | wait_woken(&wait, TASK_INTERRUPTIBLE, | |
| 417 | if (kthread_should_stop()) | 419 | MAX_SCHEDULE_TIMEOUT); |
| 420 | } while (!kthread_should_stop()); | ||
| 421 | remove_wait_queue(&scheduler->waitq[ring_id], &wait); | ||
| 422 | |||
| 423 | if (!workload) | ||
| 418 | break; | 424 | break; |
| 419 | 425 | ||
| 420 | mutex_lock(&scheduler_mutex); | 426 | mutex_lock(&scheduler_mutex); |
| @@ -444,10 +450,12 @@ static int workload_thread(void *priv) | |||
| 444 | gvt_dbg_sched("ring id %d wait workload %p\n", | 450 | gvt_dbg_sched("ring id %d wait workload %p\n", |
| 445 | workload->ring_id, workload); | 451 | workload->ring_id, workload); |
| 446 | 452 | ||
| 447 | workload->status = i915_wait_request(workload->req, | 453 | lret = i915_wait_request(workload->req, |
| 448 | 0, NULL, NULL); | 454 | 0, MAX_SCHEDULE_TIMEOUT); |
| 449 | if (workload->status != 0) | 455 | if (lret < 0) { |
| 456 | workload->status = lret; | ||
| 450 | gvt_err("fail to wait workload, skip\n"); | 457 | gvt_err("fail to wait workload, skip\n"); |
| 458 | } | ||
| 451 | 459 | ||
| 452 | complete: | 460 | complete: |
| 453 | gvt_dbg_sched("will complete workload %p\n, status: %d\n", | 461 | gvt_dbg_sched("will complete workload %p\n, status: %d\n", |
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c index 9401436d721f..4f54005b976d 100644 --- a/drivers/gpu/drm/i915/gvt/vgpu.c +++ b/drivers/gpu/drm/i915/gvt/vgpu.c | |||
| @@ -41,7 +41,7 @@ static void clean_vgpu_mmio(struct intel_vgpu *vgpu) | |||
| 41 | vgpu->mmio.vreg = vgpu->mmio.sreg = NULL; | 41 | vgpu->mmio.vreg = vgpu->mmio.sreg = NULL; |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | static int setup_vgpu_mmio(struct intel_vgpu *vgpu) | 44 | int setup_vgpu_mmio(struct intel_vgpu *vgpu) |
| 45 | { | 45 | { |
| 46 | struct intel_gvt *gvt = vgpu->gvt; | 46 | struct intel_gvt *gvt = vgpu->gvt; |
| 47 | const struct intel_gvt_device_info *info = &gvt->device_info; | 47 | const struct intel_gvt_device_info *info = &gvt->device_info; |
| @@ -103,7 +103,7 @@ static void setup_vgpu_cfg_space(struct intel_vgpu *vgpu, | |||
| 103 | } | 103 | } |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | static void populate_pvinfo_page(struct intel_vgpu *vgpu) | 106 | void populate_pvinfo_page(struct intel_vgpu *vgpu) |
| 107 | { | 107 | { |
| 108 | /* setup the ballooning information */ | 108 | /* setup the ballooning information */ |
| 109 | vgpu_vreg64(vgpu, vgtif_reg(magic)) = VGT_MAGIC; | 109 | vgpu_vreg64(vgpu, vgtif_reg(magic)) = VGT_MAGIC; |
diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index f191d7b66b1d..f5039f4f988f 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c | |||
| @@ -1290,7 +1290,7 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine, | |||
| 1290 | } | 1290 | } |
| 1291 | 1291 | ||
| 1292 | if (ret == 0 && needs_clflush_after) | 1292 | if (ret == 0 && needs_clflush_after) |
| 1293 | drm_clflush_virt_range(shadow_batch_obj->mapping, batch_len); | 1293 | drm_clflush_virt_range(shadow_batch_obj->mm.mapping, batch_len); |
| 1294 | i915_gem_object_unpin_map(shadow_batch_obj); | 1294 | i915_gem_object_unpin_map(shadow_batch_obj); |
| 1295 | 1295 | ||
| 1296 | return ret; | 1296 | return ret; |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 20638d22bbad..c9465fbff2df 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
| @@ -107,12 +107,12 @@ static char get_tiling_flag(struct drm_i915_gem_object *obj) | |||
| 107 | 107 | ||
| 108 | static char get_global_flag(struct drm_i915_gem_object *obj) | 108 | static char get_global_flag(struct drm_i915_gem_object *obj) |
| 109 | { | 109 | { |
| 110 | return obj->fault_mappable ? 'g' : ' '; | 110 | return !list_empty(&obj->userfault_link) ? 'g' : ' '; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | static char get_pin_mapped_flag(struct drm_i915_gem_object *obj) | 113 | static char get_pin_mapped_flag(struct drm_i915_gem_object *obj) |
| 114 | { | 114 | { |
| 115 | return obj->mapping ? 'M' : ' '; | 115 | return obj->mm.mapping ? 'M' : ' '; |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | static u64 i915_gem_obj_total_ggtt_size(struct drm_i915_gem_object *obj) | 118 | static u64 i915_gem_obj_total_ggtt_size(struct drm_i915_gem_object *obj) |
| @@ -136,11 +136,10 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) | |||
| 136 | struct i915_vma *vma; | 136 | struct i915_vma *vma; |
| 137 | unsigned int frontbuffer_bits; | 137 | unsigned int frontbuffer_bits; |
| 138 | int pin_count = 0; | 138 | int pin_count = 0; |
| 139 | enum intel_engine_id id; | ||
| 140 | 139 | ||
| 141 | lockdep_assert_held(&obj->base.dev->struct_mutex); | 140 | lockdep_assert_held(&obj->base.dev->struct_mutex); |
| 142 | 141 | ||
| 143 | seq_printf(m, "%pK: %c%c%c%c%c %8zdKiB %02x %02x [ ", | 142 | seq_printf(m, "%pK: %c%c%c%c%c %8zdKiB %02x %02x %s%s%s", |
| 144 | &obj->base, | 143 | &obj->base, |
| 145 | get_active_flag(obj), | 144 | get_active_flag(obj), |
| 146 | get_pin_flag(obj), | 145 | get_pin_flag(obj), |
| @@ -149,17 +148,10 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) | |||
| 149 | get_pin_mapped_flag(obj), | 148 | get_pin_mapped_flag(obj), |
| 150 | obj->base.size / 1024, | 149 | obj->base.size / 1024, |
| 151 | obj->base.read_domains, | 150 | obj->base.read_domains, |
| 152 | obj->base.write_domain); | 151 | obj->base.write_domain, |
| 153 | for_each_engine(engine, dev_priv, id) | ||
| 154 | seq_printf(m, "%x ", | ||
| 155 | i915_gem_active_get_seqno(&obj->last_read[id], | ||
| 156 | &obj->base.dev->struct_mutex)); | ||
| 157 | seq_printf(m, "] %x %s%s%s", | ||
| 158 | i915_gem_active_get_seqno(&obj->last_write, | ||
| 159 | &obj->base.dev->struct_mutex), | ||
| 160 | i915_cache_level_str(dev_priv, obj->cache_level), | 152 | i915_cache_level_str(dev_priv, obj->cache_level), |
| 161 | obj->dirty ? " dirty" : "", | 153 | obj->mm.dirty ? " dirty" : "", |
| 162 | obj->madv == I915_MADV_DONTNEED ? " purgeable" : ""); | 154 | obj->mm.madv == I915_MADV_DONTNEED ? " purgeable" : ""); |
| 163 | if (obj->base.name) | 155 | if (obj->base.name) |
| 164 | seq_printf(m, " (name: %d)", obj->base.name); | 156 | seq_printf(m, " (name: %d)", obj->base.name); |
| 165 | list_for_each_entry(vma, &obj->vma_list, obj_link) { | 157 | list_for_each_entry(vma, &obj->vma_list, obj_link) { |
| @@ -187,8 +179,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) | |||
| 187 | if (obj->stolen) | 179 | if (obj->stolen) |
| 188 | seq_printf(m, " (stolen: %08llx)", obj->stolen->start); | 180 | seq_printf(m, " (stolen: %08llx)", obj->stolen->start); |
| 189 | 181 | ||
| 190 | engine = i915_gem_active_get_engine(&obj->last_write, | 182 | engine = i915_gem_object_last_write_engine(obj); |
| 191 | &dev_priv->drm.struct_mutex); | ||
| 192 | if (engine) | 183 | if (engine) |
| 193 | seq_printf(m, " (%s)", engine->name); | 184 | seq_printf(m, " (%s)", engine->name); |
| 194 | 185 | ||
| @@ -226,7 +217,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data) | |||
| 226 | return ret; | 217 | return ret; |
| 227 | 218 | ||
| 228 | total_obj_size = total_gtt_size = count = 0; | 219 | total_obj_size = total_gtt_size = count = 0; |
| 229 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { | 220 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_link) { |
| 230 | if (obj->stolen == NULL) | 221 | if (obj->stolen == NULL) |
| 231 | continue; | 222 | continue; |
| 232 | 223 | ||
| @@ -236,7 +227,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data) | |||
| 236 | total_gtt_size += i915_gem_obj_total_ggtt_size(obj); | 227 | total_gtt_size += i915_gem_obj_total_ggtt_size(obj); |
| 237 | count++; | 228 | count++; |
| 238 | } | 229 | } |
| 239 | list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) { | 230 | list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_link) { |
| 240 | if (obj->stolen == NULL) | 231 | if (obj->stolen == NULL) |
| 241 | continue; | 232 | continue; |
| 242 | 233 | ||
| @@ -399,16 +390,16 @@ static int i915_gem_object_info(struct seq_file *m, void *data) | |||
| 399 | size = count = 0; | 390 | size = count = 0; |
| 400 | mapped_size = mapped_count = 0; | 391 | mapped_size = mapped_count = 0; |
| 401 | purgeable_size = purgeable_count = 0; | 392 | purgeable_size = purgeable_count = 0; |
| 402 | list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) { | 393 | list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_link) { |
| 403 | size += obj->base.size; | 394 | size += obj->base.size; |
| 404 | ++count; | 395 | ++count; |
| 405 | 396 | ||
| 406 | if (obj->madv == I915_MADV_DONTNEED) { | 397 | if (obj->mm.madv == I915_MADV_DONTNEED) { |
| 407 | purgeable_size += obj->base.size; | 398 | purgeable_size += obj->base.size; |
| 408 | ++purgeable_count; | 399 | ++purgeable_count; |
| 409 | } | 400 | } |
| 410 | 401 | ||
| 411 | if (obj->mapping) { | 402 | if (obj->mm.mapping) { |
| 412 | mapped_count++; | 403 | mapped_count++; |
| 413 | mapped_size += obj->base.size; | 404 | mapped_size += obj->base.size; |
| 414 | } | 405 | } |
| @@ -416,7 +407,7 @@ static int i915_gem_object_info(struct seq_file *m, void *data) | |||
| 416 | seq_printf(m, "%u unbound objects, %llu bytes\n", count, size); | 407 | seq_printf(m, "%u unbound objects, %llu bytes\n", count, size); |
| 417 | 408 | ||
| 418 | size = count = dpy_size = dpy_count = 0; | 409 | size = count = dpy_size = dpy_count = 0; |
| 419 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { | 410 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_link) { |
| 420 | size += obj->base.size; | 411 | size += obj->base.size; |
| 421 | ++count; | 412 | ++count; |
| 422 | 413 | ||
| @@ -425,12 +416,12 @@ static int i915_gem_object_info(struct seq_file *m, void *data) | |||
| 425 | ++dpy_count; | 416 | ++dpy_count; |
| 426 | } | 417 | } |
| 427 | 418 | ||
| 428 | if (obj->madv == I915_MADV_DONTNEED) { | 419 | if (obj->mm.madv == I915_MADV_DONTNEED) { |
| 429 | purgeable_size += obj->base.size; | 420 | purgeable_size += obj->base.size; |
| 430 | ++purgeable_count; | 421 | ++purgeable_count; |
| 431 | } | 422 | } |
| 432 | 423 | ||
| 433 | if (obj->mapping) { | 424 | if (obj->mm.mapping) { |
| 434 | mapped_count++; | 425 | mapped_count++; |
| 435 | mapped_size += obj->base.size; | 426 | mapped_size += obj->base.size; |
| 436 | } | 427 | } |
| @@ -502,7 +493,7 @@ static int i915_gem_gtt_info(struct seq_file *m, void *data) | |||
| 502 | return ret; | 493 | return ret; |
| 503 | 494 | ||
| 504 | total_obj_size = total_gtt_size = count = 0; | 495 | total_obj_size = total_gtt_size = count = 0; |
| 505 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { | 496 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_link) { |
| 506 | if (show_pin_display_only && !obj->pin_display) | 497 | if (show_pin_display_only && !obj->pin_display) |
| 507 | continue; | 498 | continue; |
| 508 | 499 | ||
| @@ -561,7 +552,7 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data) | |||
| 561 | seq_printf(m, "Flip queued on %s at seqno %x, next seqno %x [current breadcrumb %x], completed? %d\n", | 552 | seq_printf(m, "Flip queued on %s at seqno %x, next seqno %x [current breadcrumb %x], completed? %d\n", |
| 562 | engine->name, | 553 | engine->name, |
| 563 | i915_gem_request_get_seqno(work->flip_queued_req), | 554 | i915_gem_request_get_seqno(work->flip_queued_req), |
| 564 | dev_priv->next_seqno, | 555 | atomic_read(&dev_priv->gt.global_timeline.next_seqno), |
| 565 | intel_engine_get_seqno(engine), | 556 | intel_engine_get_seqno(engine), |
| 566 | i915_gem_request_completed(work->flip_queued_req)); | 557 | i915_gem_request_completed(work->flip_queued_req)); |
| 567 | } else | 558 | } else |
| @@ -640,17 +631,10 @@ static void print_request(struct seq_file *m, | |||
| 640 | struct drm_i915_gem_request *rq, | 631 | struct drm_i915_gem_request *rq, |
| 641 | const char *prefix) | 632 | const char *prefix) |
| 642 | { | 633 | { |
| 643 | struct pid *pid = rq->ctx->pid; | 634 | seq_printf(m, "%s%x [%x:%x] @ %d: %s\n", prefix, |
| 644 | struct task_struct *task; | 635 | rq->global_seqno, rq->ctx->hw_id, rq->fence.seqno, |
| 645 | |||
| 646 | rcu_read_lock(); | ||
| 647 | task = pid ? pid_task(pid, PIDTYPE_PID) : NULL; | ||
| 648 | seq_printf(m, "%s%x [%x:%x] @ %d: %s [%d]\n", prefix, | ||
| 649 | rq->fence.seqno, rq->ctx->hw_id, rq->fence.seqno, | ||
| 650 | jiffies_to_msecs(jiffies - rq->emitted_jiffies), | 636 | jiffies_to_msecs(jiffies - rq->emitted_jiffies), |
| 651 | task ? task->comm : "<unknown>", | 637 | rq->timeline->common->name); |
| 652 | task ? task->pid : -1); | ||
| 653 | rcu_read_unlock(); | ||
| 654 | } | 638 | } |
| 655 | 639 | ||
| 656 | static int i915_gem_request_info(struct seq_file *m, void *data) | 640 | static int i915_gem_request_info(struct seq_file *m, void *data) |
| @@ -671,13 +655,13 @@ static int i915_gem_request_info(struct seq_file *m, void *data) | |||
| 671 | int count; | 655 | int count; |
| 672 | 656 | ||
| 673 | count = 0; | 657 | count = 0; |
| 674 | list_for_each_entry(req, &engine->request_list, link) | 658 | list_for_each_entry(req, &engine->timeline->requests, link) |
| 675 | count++; | 659 | count++; |
| 676 | if (count == 0) | 660 | if (count == 0) |
| 677 | continue; | 661 | continue; |
| 678 | 662 | ||
| 679 | seq_printf(m, "%s requests: %d\n", engine->name, count); | 663 | seq_printf(m, "%s requests: %d\n", engine->name, count); |
| 680 | list_for_each_entry(req, &engine->request_list, link) | 664 | list_for_each_entry(req, &engine->timeline->requests, link) |
| 681 | print_request(m, req, " "); | 665 | print_request(m, req, " "); |
| 682 | 666 | ||
| 683 | any++; | 667 | any++; |
| @@ -699,14 +683,14 @@ static void i915_ring_seqno_info(struct seq_file *m, | |||
| 699 | seq_printf(m, "Current sequence (%s): %x\n", | 683 | seq_printf(m, "Current sequence (%s): %x\n", |
| 700 | engine->name, intel_engine_get_seqno(engine)); | 684 | engine->name, intel_engine_get_seqno(engine)); |
| 701 | 685 | ||
| 702 | spin_lock(&b->lock); | 686 | spin_lock_irq(&b->lock); |
| 703 | for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) { | 687 | for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) { |
| 704 | struct intel_wait *w = container_of(rb, typeof(*w), node); | 688 | struct intel_wait *w = container_of(rb, typeof(*w), node); |
| 705 | 689 | ||
| 706 | seq_printf(m, "Waiting (%s): %s [%d] on %x\n", | 690 | seq_printf(m, "Waiting (%s): %s [%d] on %x\n", |
| 707 | engine->name, w->tsk->comm, w->tsk->pid, w->seqno); | 691 | engine->name, w->tsk->comm, w->tsk->pid, w->seqno); |
| 708 | } | 692 | } |
| 709 | spin_unlock(&b->lock); | 693 | spin_unlock_irq(&b->lock); |
| 710 | } | 694 | } |
| 711 | 695 | ||
| 712 | static int i915_gem_seqno_info(struct seq_file *m, void *data) | 696 | static int i915_gem_seqno_info(struct seq_file *m, void *data) |
| @@ -743,17 +727,32 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
| 743 | I915_READ(VLV_IIR_RW)); | 727 | I915_READ(VLV_IIR_RW)); |
| 744 | seq_printf(m, "Display IMR:\t%08x\n", | 728 | seq_printf(m, "Display IMR:\t%08x\n", |
| 745 | I915_READ(VLV_IMR)); | 729 | I915_READ(VLV_IMR)); |
| 746 | for_each_pipe(dev_priv, pipe) | 730 | for_each_pipe(dev_priv, pipe) { |
| 731 | enum intel_display_power_domain power_domain; | ||
| 732 | |||
| 733 | power_domain = POWER_DOMAIN_PIPE(pipe); | ||
| 734 | if (!intel_display_power_get_if_enabled(dev_priv, | ||
| 735 | power_domain)) { | ||
| 736 | seq_printf(m, "Pipe %c power disabled\n", | ||
| 737 | pipe_name(pipe)); | ||
| 738 | continue; | ||
| 739 | } | ||
| 740 | |||
| 747 | seq_printf(m, "Pipe %c stat:\t%08x\n", | 741 | seq_printf(m, "Pipe %c stat:\t%08x\n", |
| 748 | pipe_name(pipe), | 742 | pipe_name(pipe), |
| 749 | I915_READ(PIPESTAT(pipe))); | 743 | I915_READ(PIPESTAT(pipe))); |
| 750 | 744 | ||
| 745 | intel_display_power_put(dev_priv, power_domain); | ||
| 746 | } | ||
| 747 | |||
| 748 | intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); | ||
| 751 | seq_printf(m, "Port hotplug:\t%08x\n", | 749 | seq_printf(m, "Port hotplug:\t%08x\n", |
| 752 | I915_READ(PORT_HOTPLUG_EN)); | 750 | I915_READ(PORT_HOTPLUG_EN)); |
| 753 | seq_printf(m, "DPFLIPSTAT:\t%08x\n", | 751 | seq_printf(m, "DPFLIPSTAT:\t%08x\n", |
| 754 | I915_READ(VLV_DPFLIPSTAT)); | 752 | I915_READ(VLV_DPFLIPSTAT)); |
| 755 | seq_printf(m, "DPINVGTT:\t%08x\n", | 753 | seq_printf(m, "DPINVGTT:\t%08x\n", |
| 756 | I915_READ(DPINVGTT)); | 754 | I915_READ(DPINVGTT)); |
| 755 | intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); | ||
| 757 | 756 | ||
| 758 | for (i = 0; i < 4; i++) { | 757 | for (i = 0; i < 4; i++) { |
| 759 | seq_printf(m, "GT Interrupt IMR %d:\t%08x\n", | 758 | seq_printf(m, "GT Interrupt IMR %d:\t%08x\n", |
| @@ -1046,15 +1045,8 @@ static int | |||
| 1046 | i915_next_seqno_get(void *data, u64 *val) | 1045 | i915_next_seqno_get(void *data, u64 *val) |
| 1047 | { | 1046 | { |
| 1048 | struct drm_i915_private *dev_priv = data; | 1047 | struct drm_i915_private *dev_priv = data; |
| 1049 | int ret; | ||
| 1050 | |||
| 1051 | ret = mutex_lock_interruptible(&dev_priv->drm.struct_mutex); | ||
| 1052 | if (ret) | ||
| 1053 | return ret; | ||
| 1054 | |||
| 1055 | *val = dev_priv->next_seqno; | ||
| 1056 | mutex_unlock(&dev_priv->drm.struct_mutex); | ||
| 1057 | 1048 | ||
| 1049 | *val = atomic_read(&dev_priv->gt.global_timeline.next_seqno); | ||
| 1058 | return 0; | 1050 | return 0; |
| 1059 | } | 1051 | } |
| 1060 | 1052 | ||
| @@ -1069,7 +1061,7 @@ i915_next_seqno_set(void *data, u64 val) | |||
| 1069 | if (ret) | 1061 | if (ret) |
| 1070 | return ret; | 1062 | return ret; |
| 1071 | 1063 | ||
| 1072 | ret = i915_gem_set_seqno(dev, val); | 1064 | ret = i915_gem_set_global_seqno(dev, val); |
| 1073 | mutex_unlock(&dev->struct_mutex); | 1065 | mutex_unlock(&dev->struct_mutex); |
| 1074 | 1066 | ||
| 1075 | return ret; | 1067 | return ret; |
| @@ -1356,21 +1348,20 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) | |||
| 1356 | 1348 | ||
| 1357 | seq_printf(m, "%s:\n", engine->name); | 1349 | seq_printf(m, "%s:\n", engine->name); |
| 1358 | seq_printf(m, "\tseqno = %x [current %x, last %x]\n", | 1350 | seq_printf(m, "\tseqno = %x [current %x, last %x]\n", |
| 1359 | engine->hangcheck.seqno, | 1351 | engine->hangcheck.seqno, seqno[id], |
| 1360 | seqno[id], | 1352 | intel_engine_last_submit(engine)); |
| 1361 | engine->last_submitted_seqno); | ||
| 1362 | seq_printf(m, "\twaiters? %s, fake irq active? %s\n", | 1353 | seq_printf(m, "\twaiters? %s, fake irq active? %s\n", |
| 1363 | yesno(intel_engine_has_waiter(engine)), | 1354 | yesno(intel_engine_has_waiter(engine)), |
| 1364 | yesno(test_bit(engine->id, | 1355 | yesno(test_bit(engine->id, |
| 1365 | &dev_priv->gpu_error.missed_irq_rings))); | 1356 | &dev_priv->gpu_error.missed_irq_rings))); |
| 1366 | spin_lock(&b->lock); | 1357 | spin_lock_irq(&b->lock); |
| 1367 | for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) { | 1358 | for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) { |
| 1368 | struct intel_wait *w = container_of(rb, typeof(*w), node); | 1359 | struct intel_wait *w = container_of(rb, typeof(*w), node); |
| 1369 | 1360 | ||
| 1370 | seq_printf(m, "\t%s [%d] waiting for %x\n", | 1361 | seq_printf(m, "\t%s [%d] waiting for %x\n", |
| 1371 | w->tsk->comm, w->tsk->pid, w->seqno); | 1362 | w->tsk->comm, w->tsk->pid, w->seqno); |
| 1372 | } | 1363 | } |
| 1373 | spin_unlock(&b->lock); | 1364 | spin_unlock_irq(&b->lock); |
| 1374 | 1365 | ||
| 1375 | seq_printf(m, "\tACTHD = 0x%08llx [current 0x%08llx]\n", | 1366 | seq_printf(m, "\tACTHD = 0x%08llx [current 0x%08llx]\n", |
| 1376 | (long long)engine->hangcheck.acthd, | 1367 | (long long)engine->hangcheck.acthd, |
| @@ -1396,14 +1387,9 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) | |||
| 1396 | static int ironlake_drpc_info(struct seq_file *m) | 1387 | static int ironlake_drpc_info(struct seq_file *m) |
| 1397 | { | 1388 | { |
| 1398 | struct drm_i915_private *dev_priv = node_to_i915(m->private); | 1389 | struct drm_i915_private *dev_priv = node_to_i915(m->private); |
| 1399 | struct drm_device *dev = &dev_priv->drm; | ||
| 1400 | u32 rgvmodectl, rstdbyctl; | 1390 | u32 rgvmodectl, rstdbyctl; |
| 1401 | u16 crstandvid; | 1391 | u16 crstandvid; |
| 1402 | int ret; | ||
| 1403 | 1392 | ||
| 1404 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
| 1405 | if (ret) | ||
| 1406 | return ret; | ||
| 1407 | intel_runtime_pm_get(dev_priv); | 1393 | intel_runtime_pm_get(dev_priv); |
| 1408 | 1394 | ||
| 1409 | rgvmodectl = I915_READ(MEMMODECTL); | 1395 | rgvmodectl = I915_READ(MEMMODECTL); |
| @@ -1411,7 +1397,6 @@ static int ironlake_drpc_info(struct seq_file *m) | |||
| 1411 | crstandvid = I915_READ16(CRSTANDVID); | 1397 | crstandvid = I915_READ16(CRSTANDVID); |
| 1412 | 1398 | ||
| 1413 | intel_runtime_pm_put(dev_priv); | 1399 | intel_runtime_pm_put(dev_priv); |
| 1414 | mutex_unlock(&dev->struct_mutex); | ||
| 1415 | 1400 | ||
| 1416 | seq_printf(m, "HD boost: %s\n", yesno(rgvmodectl & MEMMODE_BOOST_EN)); | 1401 | seq_printf(m, "HD boost: %s\n", yesno(rgvmodectl & MEMMODE_BOOST_EN)); |
| 1417 | seq_printf(m, "Boost freq: %d\n", | 1402 | seq_printf(m, "Boost freq: %d\n", |
| @@ -1674,11 +1659,13 @@ static int i915_fbc_status(struct seq_file *m, void *unused) | |||
| 1674 | seq_printf(m, "FBC disabled: %s\n", | 1659 | seq_printf(m, "FBC disabled: %s\n", |
| 1675 | dev_priv->fbc.no_fbc_reason); | 1660 | dev_priv->fbc.no_fbc_reason); |
| 1676 | 1661 | ||
| 1677 | if (intel_fbc_is_active(dev_priv) && | 1662 | if (intel_fbc_is_active(dev_priv) && INTEL_GEN(dev_priv) >= 7) { |
| 1678 | INTEL_GEN(dev_priv) >= 7) | 1663 | uint32_t mask = INTEL_GEN(dev_priv) >= 8 ? |
| 1664 | BDW_FBC_COMPRESSION_MASK : | ||
| 1665 | IVB_FBC_COMPRESSION_MASK; | ||
| 1679 | seq_printf(m, "Compressing: %s\n", | 1666 | seq_printf(m, "Compressing: %s\n", |
| 1680 | yesno(I915_READ(FBC_STATUS2) & | 1667 | yesno(I915_READ(FBC_STATUS2) & mask)); |
| 1681 | FBC_COMPRESSION_MASK)); | 1668 | } |
| 1682 | 1669 | ||
| 1683 | mutex_unlock(&dev_priv->fbc.lock); | 1670 | mutex_unlock(&dev_priv->fbc.lock); |
| 1684 | intel_runtime_pm_put(dev_priv); | 1671 | intel_runtime_pm_put(dev_priv); |
| @@ -1757,6 +1744,7 @@ static int i915_sr_status(struct seq_file *m, void *unused) | |||
| 1757 | bool sr_enabled = false; | 1744 | bool sr_enabled = false; |
| 1758 | 1745 | ||
| 1759 | intel_runtime_pm_get(dev_priv); | 1746 | intel_runtime_pm_get(dev_priv); |
| 1747 | intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); | ||
| 1760 | 1748 | ||
| 1761 | if (HAS_PCH_SPLIT(dev_priv)) | 1749 | if (HAS_PCH_SPLIT(dev_priv)) |
| 1762 | sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN; | 1750 | sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN; |
| @@ -1770,6 +1758,7 @@ static int i915_sr_status(struct seq_file *m, void *unused) | |||
| 1770 | else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) | 1758 | else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) |
| 1771 | sr_enabled = I915_READ(FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; | 1759 | sr_enabled = I915_READ(FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; |
| 1772 | 1760 | ||
| 1761 | intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); | ||
| 1773 | intel_runtime_pm_put(dev_priv); | 1762 | intel_runtime_pm_put(dev_priv); |
| 1774 | 1763 | ||
| 1775 | seq_printf(m, "self-refresh: %s\n", | 1764 | seq_printf(m, "self-refresh: %s\n", |
| @@ -2015,7 +2004,7 @@ static void i915_dump_lrc_obj(struct seq_file *m, | |||
| 2015 | seq_printf(m, "\tBound in GGTT at 0x%08x\n", | 2004 | seq_printf(m, "\tBound in GGTT at 0x%08x\n", |
| 2016 | i915_ggtt_offset(vma)); | 2005 | i915_ggtt_offset(vma)); |
| 2017 | 2006 | ||
| 2018 | if (i915_gem_object_get_pages(vma->obj)) { | 2007 | if (i915_gem_object_pin_pages(vma->obj)) { |
| 2019 | seq_puts(m, "\tFailed to get pages for context object\n\n"); | 2008 | seq_puts(m, "\tFailed to get pages for context object\n\n"); |
| 2020 | return; | 2009 | return; |
| 2021 | } | 2010 | } |
| @@ -2034,6 +2023,7 @@ static void i915_dump_lrc_obj(struct seq_file *m, | |||
| 2034 | kunmap_atomic(reg_state); | 2023 | kunmap_atomic(reg_state); |
| 2035 | } | 2024 | } |
| 2036 | 2025 | ||
| 2026 | i915_gem_object_unpin_pages(vma->obj); | ||
| 2037 | seq_putc(m, '\n'); | 2027 | seq_putc(m, '\n'); |
| 2038 | } | 2028 | } |
| 2039 | 2029 | ||
| @@ -2091,12 +2081,7 @@ static const char *swizzle_string(unsigned swizzle) | |||
| 2091 | static int i915_swizzle_info(struct seq_file *m, void *data) | 2081 | static int i915_swizzle_info(struct seq_file *m, void *data) |
| 2092 | { | 2082 | { |
| 2093 | struct drm_i915_private *dev_priv = node_to_i915(m->private); | 2083 | struct drm_i915_private *dev_priv = node_to_i915(m->private); |
| 2094 | struct drm_device *dev = &dev_priv->drm; | ||
| 2095 | int ret; | ||
| 2096 | 2084 | ||
| 2097 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
| 2098 | if (ret) | ||
| 2099 | return ret; | ||
| 2100 | intel_runtime_pm_get(dev_priv); | 2085 | intel_runtime_pm_get(dev_priv); |
| 2101 | 2086 | ||
| 2102 | seq_printf(m, "bit6 swizzle for X-tiling = %s\n", | 2087 | seq_printf(m, "bit6 swizzle for X-tiling = %s\n", |
| @@ -2136,7 +2121,6 @@ static int i915_swizzle_info(struct seq_file *m, void *data) | |||
| 2136 | seq_puts(m, "L-shaped memory detected\n"); | 2121 | seq_puts(m, "L-shaped memory detected\n"); |
| 2137 | 2122 | ||
| 2138 | intel_runtime_pm_put(dev_priv); | 2123 | intel_runtime_pm_put(dev_priv); |
| 2139 | mutex_unlock(&dev->struct_mutex); | ||
| 2140 | 2124 | ||
| 2141 | return 0; | 2125 | return 0; |
| 2142 | } | 2126 | } |
| @@ -2292,8 +2276,8 @@ static int i915_rps_boost_info(struct seq_file *m, void *data) | |||
| 2292 | struct drm_file *file; | 2276 | struct drm_file *file; |
| 2293 | 2277 | ||
| 2294 | seq_printf(m, "RPS enabled? %d\n", dev_priv->rps.enabled); | 2278 | seq_printf(m, "RPS enabled? %d\n", dev_priv->rps.enabled); |
| 2295 | seq_printf(m, "GPU busy? %s [%x]\n", | 2279 | seq_printf(m, "GPU busy? %s [%d requests]\n", |
| 2296 | yesno(dev_priv->gt.awake), dev_priv->gt.active_engines); | 2280 | yesno(dev_priv->gt.awake), dev_priv->gt.active_requests); |
| 2297 | seq_printf(m, "CPU waiting? %d\n", count_irq_waiters(dev_priv)); | 2281 | seq_printf(m, "CPU waiting? %d\n", count_irq_waiters(dev_priv)); |
| 2298 | seq_printf(m, "Frequency requested %d\n", | 2282 | seq_printf(m, "Frequency requested %d\n", |
| 2299 | intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq)); | 2283 | intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq)); |
| @@ -2328,7 +2312,7 @@ static int i915_rps_boost_info(struct seq_file *m, void *data) | |||
| 2328 | 2312 | ||
| 2329 | if (INTEL_GEN(dev_priv) >= 6 && | 2313 | if (INTEL_GEN(dev_priv) >= 6 && |
| 2330 | dev_priv->rps.enabled && | 2314 | dev_priv->rps.enabled && |
| 2331 | dev_priv->gt.active_engines) { | 2315 | dev_priv->gt.active_requests) { |
| 2332 | u32 rpup, rpupei; | 2316 | u32 rpup, rpupei; |
| 2333 | u32 rpdown, rpdownei; | 2317 | u32 rpdown, rpdownei; |
| 2334 | 2318 | ||
| @@ -2409,6 +2393,32 @@ static int i915_guc_load_status_info(struct seq_file *m, void *data) | |||
| 2409 | return 0; | 2393 | return 0; |
| 2410 | } | 2394 | } |
| 2411 | 2395 | ||
| 2396 | static void i915_guc_log_info(struct seq_file *m, | ||
| 2397 | struct drm_i915_private *dev_priv) | ||
| 2398 | { | ||
| 2399 | struct intel_guc *guc = &dev_priv->guc; | ||
| 2400 | |||
| 2401 | seq_puts(m, "\nGuC logging stats:\n"); | ||
| 2402 | |||
| 2403 | seq_printf(m, "\tISR: flush count %10u, overflow count %10u\n", | ||
| 2404 | guc->log.flush_count[GUC_ISR_LOG_BUFFER], | ||
| 2405 | guc->log.total_overflow_count[GUC_ISR_LOG_BUFFER]); | ||
| 2406 | |||
| 2407 | seq_printf(m, "\tDPC: flush count %10u, overflow count %10u\n", | ||
| 2408 | guc->log.flush_count[GUC_DPC_LOG_BUFFER], | ||
| 2409 | guc->log.total_overflow_count[GUC_DPC_LOG_BUFFER]); | ||
| 2410 | |||
| 2411 | seq_printf(m, "\tCRASH: flush count %10u, overflow count %10u\n", | ||
| 2412 | guc->log.flush_count[GUC_CRASH_DUMP_LOG_BUFFER], | ||
| 2413 | guc->log.total_overflow_count[GUC_CRASH_DUMP_LOG_BUFFER]); | ||
| 2414 | |||
| 2415 | seq_printf(m, "\tTotal flush interrupt count: %u\n", | ||
| 2416 | guc->log.flush_interrupt_count); | ||
| 2417 | |||
| 2418 | seq_printf(m, "\tCapture miss count: %u\n", | ||
| 2419 | guc->log.capture_miss_count); | ||
| 2420 | } | ||
| 2421 | |||
| 2412 | static void i915_guc_client_info(struct seq_file *m, | 2422 | static void i915_guc_client_info(struct seq_file *m, |
| 2413 | struct drm_i915_private *dev_priv, | 2423 | struct drm_i915_private *dev_priv, |
| 2414 | struct i915_guc_client *client) | 2424 | struct i915_guc_client *client) |
| @@ -2482,6 +2492,8 @@ static int i915_guc_info(struct seq_file *m, void *data) | |||
| 2482 | seq_printf(m, "\nGuC execbuf client @ %p:\n", guc.execbuf_client); | 2492 | seq_printf(m, "\nGuC execbuf client @ %p:\n", guc.execbuf_client); |
| 2483 | i915_guc_client_info(m, dev_priv, &client); | 2493 | i915_guc_client_info(m, dev_priv, &client); |
| 2484 | 2494 | ||
| 2495 | i915_guc_log_info(m, dev_priv); | ||
| 2496 | |||
| 2485 | /* Add more as required ... */ | 2497 | /* Add more as required ... */ |
| 2486 | 2498 | ||
| 2487 | return 0; | 2499 | return 0; |
| @@ -2493,10 +2505,10 @@ static int i915_guc_log_dump(struct seq_file *m, void *data) | |||
| 2493 | struct drm_i915_gem_object *obj; | 2505 | struct drm_i915_gem_object *obj; |
| 2494 | int i = 0, pg; | 2506 | int i = 0, pg; |
| 2495 | 2507 | ||
| 2496 | if (!dev_priv->guc.log_vma) | 2508 | if (!dev_priv->guc.log.vma) |
| 2497 | return 0; | 2509 | return 0; |
| 2498 | 2510 | ||
| 2499 | obj = dev_priv->guc.log_vma->obj; | 2511 | obj = dev_priv->guc.log.vma->obj; |
| 2500 | for (pg = 0; pg < obj->base.size / PAGE_SIZE; pg++) { | 2512 | for (pg = 0; pg < obj->base.size / PAGE_SIZE; pg++) { |
| 2501 | u32 *log = kmap_atomic(i915_gem_object_get_page(obj, pg)); | 2513 | u32 *log = kmap_atomic(i915_gem_object_get_page(obj, pg)); |
| 2502 | 2514 | ||
| @@ -2513,6 +2525,44 @@ static int i915_guc_log_dump(struct seq_file *m, void *data) | |||
| 2513 | return 0; | 2525 | return 0; |
| 2514 | } | 2526 | } |
| 2515 | 2527 | ||
| 2528 | static int i915_guc_log_control_get(void *data, u64 *val) | ||
| 2529 | { | ||
| 2530 | struct drm_device *dev = data; | ||
| 2531 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 2532 | |||
| 2533 | if (!dev_priv->guc.log.vma) | ||
| 2534 | return -EINVAL; | ||
| 2535 | |||
| 2536 | *val = i915.guc_log_level; | ||
| 2537 | |||
| 2538 | return 0; | ||
| 2539 | } | ||
| 2540 | |||
| 2541 | static int i915_guc_log_control_set(void *data, u64 val) | ||
| 2542 | { | ||
| 2543 | struct drm_device *dev = data; | ||
| 2544 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 2545 | int ret; | ||
| 2546 | |||
| 2547 | if (!dev_priv->guc.log.vma) | ||
| 2548 | return -EINVAL; | ||
| 2549 | |||
| 2550 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
| 2551 | if (ret) | ||
| 2552 | return ret; | ||
| 2553 | |||
| 2554 | intel_runtime_pm_get(dev_priv); | ||
| 2555 | ret = i915_guc_log_control(dev_priv, val); | ||
| 2556 | intel_runtime_pm_put(dev_priv); | ||
| 2557 | |||
| 2558 | mutex_unlock(&dev->struct_mutex); | ||
| 2559 | return ret; | ||
| 2560 | } | ||
| 2561 | |||
| 2562 | DEFINE_SIMPLE_ATTRIBUTE(i915_guc_log_control_fops, | ||
| 2563 | i915_guc_log_control_get, i915_guc_log_control_set, | ||
| 2564 | "%lld\n"); | ||
| 2565 | |||
| 2516 | static int i915_edp_psr_status(struct seq_file *m, void *data) | 2566 | static int i915_edp_psr_status(struct seq_file *m, void *data) |
| 2517 | { | 2567 | { |
| 2518 | struct drm_i915_private *dev_priv = node_to_i915(m->private); | 2568 | struct drm_i915_private *dev_priv = node_to_i915(m->private); |
| @@ -2542,11 +2592,22 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) | |||
| 2542 | enabled = I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE; | 2592 | enabled = I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE; |
| 2543 | else { | 2593 | else { |
| 2544 | for_each_pipe(dev_priv, pipe) { | 2594 | for_each_pipe(dev_priv, pipe) { |
| 2595 | enum transcoder cpu_transcoder = | ||
| 2596 | intel_pipe_to_cpu_transcoder(dev_priv, pipe); | ||
| 2597 | enum intel_display_power_domain power_domain; | ||
| 2598 | |||
| 2599 | power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); | ||
| 2600 | if (!intel_display_power_get_if_enabled(dev_priv, | ||
| 2601 | power_domain)) | ||
| 2602 | continue; | ||
| 2603 | |||
| 2545 | stat[pipe] = I915_READ(VLV_PSRSTAT(pipe)) & | 2604 | stat[pipe] = I915_READ(VLV_PSRSTAT(pipe)) & |
| 2546 | VLV_EDP_PSR_CURR_STATE_MASK; | 2605 | VLV_EDP_PSR_CURR_STATE_MASK; |
| 2547 | if ((stat[pipe] == VLV_EDP_PSR_ACTIVE_NORFB_UP) || | 2606 | if ((stat[pipe] == VLV_EDP_PSR_ACTIVE_NORFB_UP) || |
| 2548 | (stat[pipe] == VLV_EDP_PSR_ACTIVE_SF_UPDATE)) | 2607 | (stat[pipe] == VLV_EDP_PSR_ACTIVE_SF_UPDATE)) |
| 2549 | enabled = true; | 2608 | enabled = true; |
| 2609 | |||
| 2610 | intel_display_power_put(dev_priv, power_domain); | ||
| 2550 | } | 2611 | } |
| 2551 | } | 2612 | } |
| 2552 | 2613 | ||
| @@ -3094,6 +3155,8 @@ static int i915_engine_info(struct seq_file *m, void *unused) | |||
| 3094 | struct intel_engine_cs *engine; | 3155 | struct intel_engine_cs *engine; |
| 3095 | enum intel_engine_id id; | 3156 | enum intel_engine_id id; |
| 3096 | 3157 | ||
| 3158 | intel_runtime_pm_get(dev_priv); | ||
| 3159 | |||
| 3097 | for_each_engine(engine, dev_priv, id) { | 3160 | for_each_engine(engine, dev_priv, id) { |
| 3098 | struct intel_breadcrumbs *b = &engine->breadcrumbs; | 3161 | struct intel_breadcrumbs *b = &engine->breadcrumbs; |
| 3099 | struct drm_i915_gem_request *rq; | 3162 | struct drm_i915_gem_request *rq; |
| @@ -3103,7 +3166,7 @@ static int i915_engine_info(struct seq_file *m, void *unused) | |||
| 3103 | seq_printf(m, "%s\n", engine->name); | 3166 | seq_printf(m, "%s\n", engine->name); |
| 3104 | seq_printf(m, "\tcurrent seqno %x, last %x, hangcheck %x [score %d]\n", | 3167 | seq_printf(m, "\tcurrent seqno %x, last %x, hangcheck %x [score %d]\n", |
| 3105 | intel_engine_get_seqno(engine), | 3168 | intel_engine_get_seqno(engine), |
| 3106 | engine->last_submitted_seqno, | 3169 | intel_engine_last_submit(engine), |
| 3107 | engine->hangcheck.seqno, | 3170 | engine->hangcheck.seqno, |
| 3108 | engine->hangcheck.score); | 3171 | engine->hangcheck.score); |
| 3109 | 3172 | ||
| @@ -3111,14 +3174,14 @@ static int i915_engine_info(struct seq_file *m, void *unused) | |||
| 3111 | 3174 | ||
| 3112 | seq_printf(m, "\tRequests:\n"); | 3175 | seq_printf(m, "\tRequests:\n"); |
| 3113 | 3176 | ||
| 3114 | rq = list_first_entry(&engine->request_list, | 3177 | rq = list_first_entry(&engine->timeline->requests, |
| 3115 | struct drm_i915_gem_request, link); | 3178 | struct drm_i915_gem_request, link); |
| 3116 | if (&rq->link != &engine->request_list) | 3179 | if (&rq->link != &engine->timeline->requests) |
| 3117 | print_request(m, rq, "\t\tfirst "); | 3180 | print_request(m, rq, "\t\tfirst "); |
| 3118 | 3181 | ||
| 3119 | rq = list_last_entry(&engine->request_list, | 3182 | rq = list_last_entry(&engine->timeline->requests, |
| 3120 | struct drm_i915_gem_request, link); | 3183 | struct drm_i915_gem_request, link); |
| 3121 | if (&rq->link != &engine->request_list) | 3184 | if (&rq->link != &engine->timeline->requests) |
| 3122 | print_request(m, rq, "\t\tlast "); | 3185 | print_request(m, rq, "\t\tlast "); |
| 3123 | 3186 | ||
| 3124 | rq = i915_gem_find_active_request(engine); | 3187 | rq = i915_gem_find_active_request(engine); |
| @@ -3192,6 +3255,12 @@ static int i915_engine_info(struct seq_file *m, void *unused) | |||
| 3192 | else | 3255 | else |
| 3193 | seq_printf(m, "\t\tELSP[1] idle\n"); | 3256 | seq_printf(m, "\t\tELSP[1] idle\n"); |
| 3194 | rcu_read_unlock(); | 3257 | rcu_read_unlock(); |
| 3258 | |||
| 3259 | spin_lock_irq(&engine->execlist_lock); | ||
| 3260 | list_for_each_entry(rq, &engine->execlist_queue, execlist_link) { | ||
| 3261 | print_request(m, rq, "\t\tQ "); | ||
| 3262 | } | ||
| 3263 | spin_unlock_irq(&engine->execlist_lock); | ||
| 3195 | } else if (INTEL_GEN(dev_priv) > 6) { | 3264 | } else if (INTEL_GEN(dev_priv) > 6) { |
| 3196 | seq_printf(m, "\tPP_DIR_BASE: 0x%08x\n", | 3265 | seq_printf(m, "\tPP_DIR_BASE: 0x%08x\n", |
| 3197 | I915_READ(RING_PP_DIR_BASE(engine))); | 3266 | I915_READ(RING_PP_DIR_BASE(engine))); |
| @@ -3201,18 +3270,20 @@ static int i915_engine_info(struct seq_file *m, void *unused) | |||
| 3201 | I915_READ(RING_PP_DIR_DCLV(engine))); | 3270 | I915_READ(RING_PP_DIR_DCLV(engine))); |
| 3202 | } | 3271 | } |
| 3203 | 3272 | ||
| 3204 | spin_lock(&b->lock); | 3273 | spin_lock_irq(&b->lock); |
| 3205 | for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) { | 3274 | for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) { |
| 3206 | struct intel_wait *w = container_of(rb, typeof(*w), node); | 3275 | struct intel_wait *w = container_of(rb, typeof(*w), node); |
| 3207 | 3276 | ||
| 3208 | seq_printf(m, "\t%s [%d] waiting for %x\n", | 3277 | seq_printf(m, "\t%s [%d] waiting for %x\n", |
| 3209 | w->tsk->comm, w->tsk->pid, w->seqno); | 3278 | w->tsk->comm, w->tsk->pid, w->seqno); |
| 3210 | } | 3279 | } |
| 3211 | spin_unlock(&b->lock); | 3280 | spin_unlock_irq(&b->lock); |
| 3212 | 3281 | ||
| 3213 | seq_puts(m, "\n"); | 3282 | seq_puts(m, "\n"); |
| 3214 | } | 3283 | } |
| 3215 | 3284 | ||
| 3285 | intel_runtime_pm_put(dev_priv); | ||
| 3286 | |||
| 3216 | return 0; | 3287 | return 0; |
| 3217 | } | 3288 | } |
| 3218 | 3289 | ||
| @@ -3274,15 +3345,6 @@ static int i915_semaphore_status(struct seq_file *m, void *unused) | |||
| 3274 | seq_putc(m, '\n'); | 3345 | seq_putc(m, '\n'); |
| 3275 | } | 3346 | } |
| 3276 | 3347 | ||
| 3277 | seq_puts(m, "\nSync seqno:\n"); | ||
| 3278 | for_each_engine(engine, dev_priv, id) { | ||
| 3279 | for (j = 0; j < num_rings; j++) | ||
| 3280 | seq_printf(m, " 0x%08x ", | ||
| 3281 | engine->semaphore.sync_seqno[j]); | ||
| 3282 | seq_putc(m, '\n'); | ||
| 3283 | } | ||
| 3284 | seq_putc(m, '\n'); | ||
| 3285 | |||
| 3286 | intel_runtime_pm_put(dev_priv); | 3348 | intel_runtime_pm_put(dev_priv); |
| 3287 | mutex_unlock(&dev->struct_mutex); | 3349 | mutex_unlock(&dev->struct_mutex); |
| 3288 | return 0; | 3350 | return 0; |
| @@ -3375,7 +3437,7 @@ static int i915_ddb_info(struct seq_file *m, void *unused) | |||
| 3375 | for_each_pipe(dev_priv, pipe) { | 3437 | for_each_pipe(dev_priv, pipe) { |
| 3376 | seq_printf(m, "Pipe %c\n", pipe_name(pipe)); | 3438 | seq_printf(m, "Pipe %c\n", pipe_name(pipe)); |
| 3377 | 3439 | ||
| 3378 | for_each_plane(dev_priv, pipe, plane) { | 3440 | for_each_universal_plane(dev_priv, pipe, plane) { |
| 3379 | entry = &ddb->plane[pipe][plane]; | 3441 | entry = &ddb->plane[pipe][plane]; |
| 3380 | seq_printf(m, " Plane%-8d%8u%8u%8u\n", plane + 1, | 3442 | seq_printf(m, " Plane%-8d%8u%8u%8u\n", plane + 1, |
| 3381 | entry->start, entry->end, | 3443 | entry->start, entry->end, |
| @@ -4009,8 +4071,7 @@ static void hsw_trans_edp_pipe_A_crc_wa(struct drm_i915_private *dev_priv, | |||
| 4009 | bool enable) | 4071 | bool enable) |
| 4010 | { | 4072 | { |
| 4011 | struct drm_device *dev = &dev_priv->drm; | 4073 | struct drm_device *dev = &dev_priv->drm; |
| 4012 | struct intel_crtc *crtc = | 4074 | struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_A); |
| 4013 | to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_A]); | ||
| 4014 | struct intel_crtc_state *pipe_config; | 4075 | struct intel_crtc_state *pipe_config; |
| 4015 | struct drm_atomic_state *state; | 4076 | struct drm_atomic_state *state; |
| 4016 | int ret = 0; | 4077 | int ret = 0; |
| @@ -4076,10 +4137,8 @@ static int pipe_crc_set_source(struct drm_i915_private *dev_priv, | |||
| 4076 | enum pipe pipe, | 4137 | enum pipe pipe, |
| 4077 | enum intel_pipe_crc_source source) | 4138 | enum intel_pipe_crc_source source) |
| 4078 | { | 4139 | { |
| 4079 | struct drm_device *dev = &dev_priv->drm; | ||
| 4080 | struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe]; | 4140 | struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe]; |
| 4081 | struct intel_crtc *crtc = | 4141 | struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
| 4082 | to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe)); | ||
| 4083 | enum intel_display_power_domain power_domain; | 4142 | enum intel_display_power_domain power_domain; |
| 4084 | u32 val = 0; /* shut up gcc */ | 4143 | u32 val = 0; /* shut up gcc */ |
| 4085 | int ret; | 4144 | int ret; |
| @@ -4150,15 +4209,15 @@ static int pipe_crc_set_source(struct drm_i915_private *dev_priv, | |||
| 4150 | /* real source -> none transition */ | 4209 | /* real source -> none transition */ |
| 4151 | if (source == INTEL_PIPE_CRC_SOURCE_NONE) { | 4210 | if (source == INTEL_PIPE_CRC_SOURCE_NONE) { |
| 4152 | struct intel_pipe_crc_entry *entries; | 4211 | struct intel_pipe_crc_entry *entries; |
| 4153 | struct intel_crtc *crtc = | 4212 | struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, |
| 4154 | to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); | 4213 | pipe); |
| 4155 | 4214 | ||
| 4156 | DRM_DEBUG_DRIVER("stopping CRCs for pipe %c\n", | 4215 | DRM_DEBUG_DRIVER("stopping CRCs for pipe %c\n", |
| 4157 | pipe_name(pipe)); | 4216 | pipe_name(pipe)); |
| 4158 | 4217 | ||
| 4159 | drm_modeset_lock(&crtc->base.mutex, NULL); | 4218 | drm_modeset_lock(&crtc->base.mutex, NULL); |
| 4160 | if (crtc->base.state->active) | 4219 | if (crtc->base.state->active) |
| 4161 | intel_wait_for_vblank(dev, pipe); | 4220 | intel_wait_for_vblank(dev_priv, pipe); |
| 4162 | drm_modeset_unlock(&crtc->base.mutex); | 4221 | drm_modeset_unlock(&crtc->base.mutex); |
| 4163 | 4222 | ||
| 4164 | spin_lock_irq(&pipe_crc->lock); | 4223 | spin_lock_irq(&pipe_crc->lock); |
| @@ -4798,13 +4857,9 @@ i915_wedged_set(void *data, u64 val) | |||
| 4798 | if (i915_reset_in_progress(&dev_priv->gpu_error)) | 4857 | if (i915_reset_in_progress(&dev_priv->gpu_error)) |
| 4799 | return -EAGAIN; | 4858 | return -EAGAIN; |
| 4800 | 4859 | ||
| 4801 | intel_runtime_pm_get(dev_priv); | ||
| 4802 | |||
| 4803 | i915_handle_error(dev_priv, val, | 4860 | i915_handle_error(dev_priv, val, |
| 4804 | "Manually setting wedged to %llu", val); | 4861 | "Manually setting wedged to %llu", val); |
| 4805 | 4862 | ||
| 4806 | intel_runtime_pm_put(dev_priv); | ||
| 4807 | |||
| 4808 | return 0; | 4863 | return 0; |
| 4809 | } | 4864 | } |
| 4810 | 4865 | ||
| @@ -4872,10 +4927,12 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_ring_test_irq_fops, | |||
| 4872 | #define DROP_BOUND 0x2 | 4927 | #define DROP_BOUND 0x2 |
| 4873 | #define DROP_RETIRE 0x4 | 4928 | #define DROP_RETIRE 0x4 |
| 4874 | #define DROP_ACTIVE 0x8 | 4929 | #define DROP_ACTIVE 0x8 |
| 4875 | #define DROP_ALL (DROP_UNBOUND | \ | 4930 | #define DROP_FREED 0x10 |
| 4876 | DROP_BOUND | \ | 4931 | #define DROP_ALL (DROP_UNBOUND | \ |
| 4877 | DROP_RETIRE | \ | 4932 | DROP_BOUND | \ |
| 4878 | DROP_ACTIVE) | 4933 | DROP_RETIRE | \ |
| 4934 | DROP_ACTIVE | \ | ||
| 4935 | DROP_FREED) | ||
| 4879 | static int | 4936 | static int |
| 4880 | i915_drop_caches_get(void *data, u64 *val) | 4937 | i915_drop_caches_get(void *data, u64 *val) |
| 4881 | { | 4938 | { |
| @@ -4919,6 +4976,11 @@ i915_drop_caches_set(void *data, u64 val) | |||
| 4919 | unlock: | 4976 | unlock: |
| 4920 | mutex_unlock(&dev->struct_mutex); | 4977 | mutex_unlock(&dev->struct_mutex); |
| 4921 | 4978 | ||
| 4979 | if (val & DROP_FREED) { | ||
| 4980 | synchronize_rcu(); | ||
| 4981 | flush_work(&dev_priv->mm.free_work); | ||
| 4982 | } | ||
| 4983 | |||
| 4922 | return ret; | 4984 | return ret; |
| 4923 | } | 4985 | } |
| 4924 | 4986 | ||
| @@ -5039,22 +5101,16 @@ static int | |||
| 5039 | i915_cache_sharing_get(void *data, u64 *val) | 5101 | i915_cache_sharing_get(void *data, u64 *val) |
| 5040 | { | 5102 | { |
| 5041 | struct drm_i915_private *dev_priv = data; | 5103 | struct drm_i915_private *dev_priv = data; |
| 5042 | struct drm_device *dev = &dev_priv->drm; | ||
| 5043 | u32 snpcr; | 5104 | u32 snpcr; |
| 5044 | int ret; | ||
| 5045 | 5105 | ||
| 5046 | if (!(IS_GEN6(dev_priv) || IS_GEN7(dev_priv))) | 5106 | if (!(IS_GEN6(dev_priv) || IS_GEN7(dev_priv))) |
| 5047 | return -ENODEV; | 5107 | return -ENODEV; |
| 5048 | 5108 | ||
| 5049 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
| 5050 | if (ret) | ||
| 5051 | return ret; | ||
| 5052 | intel_runtime_pm_get(dev_priv); | 5109 | intel_runtime_pm_get(dev_priv); |
| 5053 | 5110 | ||
| 5054 | snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); | 5111 | snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); |
| 5055 | 5112 | ||
| 5056 | intel_runtime_pm_put(dev_priv); | 5113 | intel_runtime_pm_put(dev_priv); |
| 5057 | mutex_unlock(&dev->struct_mutex); | ||
| 5058 | 5114 | ||
| 5059 | *val = (snpcr & GEN6_MBC_SNPCR_MASK) >> GEN6_MBC_SNPCR_SHIFT; | 5115 | *val = (snpcr & GEN6_MBC_SNPCR_MASK) >> GEN6_MBC_SNPCR_SHIFT; |
| 5060 | 5116 | ||
| @@ -5414,7 +5470,8 @@ static const struct i915_debugfs_files { | |||
| 5414 | {"i915_fbc_false_color", &i915_fbc_fc_fops}, | 5470 | {"i915_fbc_false_color", &i915_fbc_fc_fops}, |
| 5415 | {"i915_dp_test_data", &i915_displayport_test_data_fops}, | 5471 | {"i915_dp_test_data", &i915_displayport_test_data_fops}, |
| 5416 | {"i915_dp_test_type", &i915_displayport_test_type_fops}, | 5472 | {"i915_dp_test_type", &i915_displayport_test_type_fops}, |
| 5417 | {"i915_dp_test_active", &i915_displayport_test_active_fops} | 5473 | {"i915_dp_test_active", &i915_displayport_test_active_fops}, |
| 5474 | {"i915_guc_log_control", &i915_guc_log_control_fops} | ||
| 5418 | }; | 5475 | }; |
| 5419 | 5476 | ||
| 5420 | void intel_display_crc_init(struct drm_i915_private *dev_priv) | 5477 | void intel_display_crc_init(struct drm_i915_private *dev_priv) |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 912d5348e3e7..b72c24ff39c3 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -537,14 +537,17 @@ static const struct vga_switcheroo_client_ops i915_switcheroo_ops = { | |||
| 537 | .can_switch = i915_switcheroo_can_switch, | 537 | .can_switch = i915_switcheroo_can_switch, |
| 538 | }; | 538 | }; |
| 539 | 539 | ||
| 540 | static void i915_gem_fini(struct drm_device *dev) | 540 | static void i915_gem_fini(struct drm_i915_private *dev_priv) |
| 541 | { | 541 | { |
| 542 | mutex_lock(&dev->struct_mutex); | 542 | mutex_lock(&dev_priv->drm.struct_mutex); |
| 543 | i915_gem_cleanup_engines(dev); | 543 | i915_gem_cleanup_engines(&dev_priv->drm); |
| 544 | i915_gem_context_fini(dev); | 544 | i915_gem_context_fini(&dev_priv->drm); |
| 545 | mutex_unlock(&dev->struct_mutex); | 545 | mutex_unlock(&dev_priv->drm.struct_mutex); |
| 546 | |||
| 547 | rcu_barrier(); | ||
| 548 | flush_work(&dev_priv->mm.free_work); | ||
| 546 | 549 | ||
| 547 | WARN_ON(!list_empty(&to_i915(dev)->context_list)); | 550 | WARN_ON(!list_empty(&dev_priv->context_list)); |
| 548 | } | 551 | } |
| 549 | 552 | ||
| 550 | static int i915_load_modeset_init(struct drm_device *dev) | 553 | static int i915_load_modeset_init(struct drm_device *dev) |
| @@ -592,7 +595,9 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
| 592 | 595 | ||
| 593 | /* Important: The output setup functions called by modeset_init need | 596 | /* Important: The output setup functions called by modeset_init need |
| 594 | * working irqs for e.g. gmbus and dp aux transfers. */ | 597 | * working irqs for e.g. gmbus and dp aux transfers. */ |
| 595 | intel_modeset_init(dev); | 598 | ret = intel_modeset_init(dev); |
| 599 | if (ret) | ||
| 600 | goto cleanup_irq; | ||
| 596 | 601 | ||
| 597 | intel_guc_init(dev); | 602 | intel_guc_init(dev); |
| 598 | 603 | ||
| @@ -619,7 +624,7 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
| 619 | cleanup_gem: | 624 | cleanup_gem: |
| 620 | if (i915_gem_suspend(dev)) | 625 | if (i915_gem_suspend(dev)) |
| 621 | DRM_ERROR("failed to idle hardware; continuing to unload!\n"); | 626 | DRM_ERROR("failed to idle hardware; continuing to unload!\n"); |
| 622 | i915_gem_fini(dev); | 627 | i915_gem_fini(dev_priv); |
| 623 | cleanup_irq: | 628 | cleanup_irq: |
| 624 | intel_guc_fini(dev); | 629 | intel_guc_fini(dev); |
| 625 | drm_irq_uninstall(dev); | 630 | drm_irq_uninstall(dev); |
| @@ -825,10 +830,13 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, | |||
| 825 | intel_init_dpio(dev_priv); | 830 | intel_init_dpio(dev_priv); |
| 826 | intel_power_domains_init(dev_priv); | 831 | intel_power_domains_init(dev_priv); |
| 827 | intel_irq_init(dev_priv); | 832 | intel_irq_init(dev_priv); |
| 833 | intel_hangcheck_init(dev_priv); | ||
| 828 | intel_init_display_hooks(dev_priv); | 834 | intel_init_display_hooks(dev_priv); |
| 829 | intel_init_clock_gating_hooks(dev_priv); | 835 | intel_init_clock_gating_hooks(dev_priv); |
| 830 | intel_init_audio_hooks(dev_priv); | 836 | intel_init_audio_hooks(dev_priv); |
| 831 | i915_gem_load_init(&dev_priv->drm); | 837 | ret = i915_gem_load_init(&dev_priv->drm); |
| 838 | if (ret < 0) | ||
| 839 | goto err_gvt; | ||
| 832 | 840 | ||
| 833 | intel_display_crc_init(dev_priv); | 841 | intel_display_crc_init(dev_priv); |
| 834 | 842 | ||
| @@ -838,6 +846,8 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, | |||
| 838 | 846 | ||
| 839 | return 0; | 847 | return 0; |
| 840 | 848 | ||
| 849 | err_gvt: | ||
| 850 | intel_gvt_cleanup(dev_priv); | ||
| 841 | err_workqueues: | 851 | err_workqueues: |
| 842 | i915_workqueues_cleanup(dev_priv); | 852 | i915_workqueues_cleanup(dev_priv); |
| 843 | return ret; | 853 | return ret; |
| @@ -972,7 +982,6 @@ static void intel_sanitize_options(struct drm_i915_private *dev_priv) | |||
| 972 | static int i915_driver_init_hw(struct drm_i915_private *dev_priv) | 982 | static int i915_driver_init_hw(struct drm_i915_private *dev_priv) |
| 973 | { | 983 | { |
| 974 | struct pci_dev *pdev = dev_priv->drm.pdev; | 984 | struct pci_dev *pdev = dev_priv->drm.pdev; |
| 975 | struct drm_device *dev = &dev_priv->drm; | ||
| 976 | int ret; | 985 | int ret; |
| 977 | 986 | ||
| 978 | if (i915_inject_load_failure()) | 987 | if (i915_inject_load_failure()) |
| @@ -1030,7 +1039,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) | |||
| 1030 | * behaviour if any general state is accessed within a page above 4GB, | 1039 | * behaviour if any general state is accessed within a page above 4GB, |
| 1031 | * which also needs to be handled carefully. | 1040 | * which also needs to be handled carefully. |
| 1032 | */ | 1041 | */ |
| 1033 | if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) { | 1042 | if (IS_BROADWATER(dev_priv) || IS_CRESTLINE(dev_priv)) { |
| 1034 | ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); | 1043 | ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); |
| 1035 | 1044 | ||
| 1036 | if (ret) { | 1045 | if (ret) { |
| @@ -1111,6 +1120,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) | |||
| 1111 | /* Reveal our presence to userspace */ | 1120 | /* Reveal our presence to userspace */ |
| 1112 | if (drm_dev_register(dev, 0) == 0) { | 1121 | if (drm_dev_register(dev, 0) == 0) { |
| 1113 | i915_debugfs_register(dev_priv); | 1122 | i915_debugfs_register(dev_priv); |
| 1123 | i915_guc_register(dev_priv); | ||
| 1114 | i915_setup_sysfs(dev_priv); | 1124 | i915_setup_sysfs(dev_priv); |
| 1115 | } else | 1125 | } else |
| 1116 | DRM_ERROR("Failed to register driver for userspace access!\n"); | 1126 | DRM_ERROR("Failed to register driver for userspace access!\n"); |
| @@ -1149,6 +1159,7 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv) | |||
| 1149 | intel_opregion_unregister(dev_priv); | 1159 | intel_opregion_unregister(dev_priv); |
| 1150 | 1160 | ||
| 1151 | i915_teardown_sysfs(dev_priv); | 1161 | i915_teardown_sysfs(dev_priv); |
| 1162 | i915_guc_unregister(dev_priv); | ||
| 1152 | i915_debugfs_unregister(dev_priv); | 1163 | i915_debugfs_unregister(dev_priv); |
| 1153 | drm_dev_unregister(&dev_priv->drm); | 1164 | drm_dev_unregister(&dev_priv->drm); |
| 1154 | 1165 | ||
| @@ -1303,7 +1314,7 @@ void i915_driver_unload(struct drm_device *dev) | |||
| 1303 | drain_workqueue(dev_priv->wq); | 1314 | drain_workqueue(dev_priv->wq); |
| 1304 | 1315 | ||
| 1305 | intel_guc_fini(dev); | 1316 | intel_guc_fini(dev); |
| 1306 | i915_gem_fini(dev); | 1317 | i915_gem_fini(dev_priv); |
| 1307 | intel_fbc_cleanup_cfb(dev_priv); | 1318 | intel_fbc_cleanup_cfb(dev_priv); |
| 1308 | 1319 | ||
| 1309 | intel_power_domains_fini(dev_priv); | 1320 | intel_power_domains_fini(dev_priv); |
| @@ -1425,7 +1436,7 @@ static int i915_drm_suspend(struct drm_device *dev) | |||
| 1425 | 1436 | ||
| 1426 | intel_suspend_encoders(dev_priv); | 1437 | intel_suspend_encoders(dev_priv); |
| 1427 | 1438 | ||
| 1428 | intel_suspend_hw(dev); | 1439 | intel_suspend_hw(dev_priv); |
| 1429 | 1440 | ||
| 1430 | i915_gem_suspend_gtt_mappings(dev); | 1441 | i915_gem_suspend_gtt_mappings(dev); |
| 1431 | 1442 | ||
| @@ -1589,6 +1600,8 @@ static int i915_drm_resume(struct drm_device *dev) | |||
| 1589 | 1600 | ||
| 1590 | intel_display_resume(dev); | 1601 | intel_display_resume(dev); |
| 1591 | 1602 | ||
| 1603 | drm_kms_helper_poll_enable(dev); | ||
| 1604 | |||
| 1592 | /* | 1605 | /* |
| 1593 | * ... but also need to make sure that hotplug processing | 1606 | * ... but also need to make sure that hotplug processing |
| 1594 | * doesn't cause havoc. Like in the driver load code we don't | 1607 | * doesn't cause havoc. Like in the driver load code we don't |
| @@ -1596,8 +1609,6 @@ static int i915_drm_resume(struct drm_device *dev) | |||
| 1596 | * notifications. | 1609 | * notifications. |
| 1597 | * */ | 1610 | * */ |
| 1598 | intel_hpd_init(dev_priv); | 1611 | intel_hpd_init(dev_priv); |
| 1599 | /* Config may have changed between suspend and resume */ | ||
| 1600 | drm_helper_hpd_irq_event(dev); | ||
| 1601 | 1612 | ||
| 1602 | intel_opregion_register(dev_priv); | 1613 | intel_opregion_register(dev_priv); |
| 1603 | 1614 | ||
| @@ -1610,7 +1621,6 @@ static int i915_drm_resume(struct drm_device *dev) | |||
| 1610 | intel_opregion_notify_adapter(dev_priv, PCI_D0); | 1621 | intel_opregion_notify_adapter(dev_priv, PCI_D0); |
| 1611 | 1622 | ||
| 1612 | intel_autoenable_gt_powersave(dev_priv); | 1623 | intel_autoenable_gt_powersave(dev_priv); |
| 1613 | drm_kms_helper_poll_enable(dev); | ||
| 1614 | 1624 | ||
| 1615 | enable_rpm_wakeref_asserts(dev_priv); | 1625 | enable_rpm_wakeref_asserts(dev_priv); |
| 1616 | 1626 | ||
| @@ -2254,7 +2264,6 @@ err1: | |||
| 2254 | static int vlv_resume_prepare(struct drm_i915_private *dev_priv, | 2264 | static int vlv_resume_prepare(struct drm_i915_private *dev_priv, |
| 2255 | bool rpm_resume) | 2265 | bool rpm_resume) |
| 2256 | { | 2266 | { |
| 2257 | struct drm_device *dev = &dev_priv->drm; | ||
| 2258 | int err; | 2267 | int err; |
| 2259 | int ret; | 2268 | int ret; |
| 2260 | 2269 | ||
| @@ -2278,10 +2287,8 @@ static int vlv_resume_prepare(struct drm_i915_private *dev_priv, | |||
| 2278 | 2287 | ||
| 2279 | vlv_check_no_gt_access(dev_priv); | 2288 | vlv_check_no_gt_access(dev_priv); |
| 2280 | 2289 | ||
| 2281 | if (rpm_resume) { | 2290 | if (rpm_resume) |
| 2282 | intel_init_clock_gating(dev); | 2291 | intel_init_clock_gating(dev_priv); |
| 2283 | i915_gem_restore_fences(dev); | ||
| 2284 | } | ||
| 2285 | 2292 | ||
| 2286 | return ret; | 2293 | return ret; |
| 2287 | } | 2294 | } |
| @@ -2301,32 +2308,13 @@ static int intel_runtime_suspend(struct device *kdev) | |||
| 2301 | 2308 | ||
| 2302 | DRM_DEBUG_KMS("Suspending device\n"); | 2309 | DRM_DEBUG_KMS("Suspending device\n"); |
| 2303 | 2310 | ||
| 2304 | /* | ||
| 2305 | * We could deadlock here in case another thread holding struct_mutex | ||
| 2306 | * calls RPM suspend concurrently, since the RPM suspend will wait | ||
| 2307 | * first for this RPM suspend to finish. In this case the concurrent | ||
| 2308 | * RPM resume will be followed by its RPM suspend counterpart. Still | ||
| 2309 | * for consistency return -EAGAIN, which will reschedule this suspend. | ||
| 2310 | */ | ||
| 2311 | if (!mutex_trylock(&dev->struct_mutex)) { | ||
| 2312 | DRM_DEBUG_KMS("device lock contention, deffering suspend\n"); | ||
| 2313 | /* | ||
| 2314 | * Bump the expiration timestamp, otherwise the suspend won't | ||
| 2315 | * be rescheduled. | ||
| 2316 | */ | ||
| 2317 | pm_runtime_mark_last_busy(kdev); | ||
| 2318 | |||
| 2319 | return -EAGAIN; | ||
| 2320 | } | ||
| 2321 | |||
| 2322 | disable_rpm_wakeref_asserts(dev_priv); | 2311 | disable_rpm_wakeref_asserts(dev_priv); |
| 2323 | 2312 | ||
| 2324 | /* | 2313 | /* |
| 2325 | * We are safe here against re-faults, since the fault handler takes | 2314 | * We are safe here against re-faults, since the fault handler takes |
| 2326 | * an RPM reference. | 2315 | * an RPM reference. |
| 2327 | */ | 2316 | */ |
| 2328 | i915_gem_release_all_mmaps(dev_priv); | 2317 | i915_gem_runtime_suspend(dev_priv); |
| 2329 | mutex_unlock(&dev->struct_mutex); | ||
| 2330 | 2318 | ||
| 2331 | intel_guc_suspend(dev); | 2319 | intel_guc_suspend(dev); |
| 2332 | 2320 | ||
| @@ -2591,7 +2579,7 @@ static struct drm_driver driver = { | |||
| 2591 | .set_busid = drm_pci_set_busid, | 2579 | .set_busid = drm_pci_set_busid, |
| 2592 | 2580 | ||
| 2593 | .gem_close_object = i915_gem_close_object, | 2581 | .gem_close_object = i915_gem_close_object, |
| 2594 | .gem_free_object = i915_gem_free_object, | 2582 | .gem_free_object_unlocked = i915_gem_free_object, |
| 2595 | .gem_vm_ops = &i915_gem_vm_ops, | 2583 | .gem_vm_ops = &i915_gem_vm_ops, |
| 2596 | 2584 | ||
| 2597 | .prime_handle_to_fd = drm_gem_prime_handle_to_fd, | 2585 | .prime_handle_to_fd = drm_gem_prime_handle_to_fd, |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f022f438e5b9..80775b882b4a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #include <linux/intel-iommu.h> | 41 | #include <linux/intel-iommu.h> |
| 42 | #include <linux/kref.h> | 42 | #include <linux/kref.h> |
| 43 | #include <linux/pm_qos.h> | 43 | #include <linux/pm_qos.h> |
| 44 | #include <linux/reservation.h> | ||
| 44 | #include <linux/shmem_fs.h> | 45 | #include <linux/shmem_fs.h> |
| 45 | 46 | ||
| 46 | #include <drm/drmP.h> | 47 | #include <drm/drmP.h> |
| @@ -62,6 +63,7 @@ | |||
| 62 | #include "i915_gem_gtt.h" | 63 | #include "i915_gem_gtt.h" |
| 63 | #include "i915_gem_render_state.h" | 64 | #include "i915_gem_render_state.h" |
| 64 | #include "i915_gem_request.h" | 65 | #include "i915_gem_request.h" |
| 66 | #include "i915_gem_timeline.h" | ||
| 65 | 67 | ||
| 66 | #include "intel_gvt.h" | 68 | #include "intel_gvt.h" |
| 67 | 69 | ||
| @@ -70,8 +72,8 @@ | |||
| 70 | 72 | ||
| 71 | #define DRIVER_NAME "i915" | 73 | #define DRIVER_NAME "i915" |
| 72 | #define DRIVER_DESC "Intel Graphics" | 74 | #define DRIVER_DESC "Intel Graphics" |
| 73 | #define DRIVER_DATE "20161024" | 75 | #define DRIVER_DATE "20161108" |
| 74 | #define DRIVER_TIMESTAMP 1477290335 | 76 | #define DRIVER_TIMESTAMP 1478587895 |
| 75 | 77 | ||
| 76 | #undef WARN_ON | 78 | #undef WARN_ON |
| 77 | /* Many gcc seem to no see through this and fall over :( */ | 79 | /* Many gcc seem to no see through this and fall over :( */ |
| @@ -183,7 +185,7 @@ enum plane { | |||
| 183 | }; | 185 | }; |
| 184 | #define plane_name(p) ((p) + 'A') | 186 | #define plane_name(p) ((p) + 'A') |
| 185 | 187 | ||
| 186 | #define sprite_name(p, s) ((p) * INTEL_INFO(dev)->num_sprites[(p)] + (s) + 'A') | 188 | #define sprite_name(p, s) ((p) * INTEL_INFO(dev_priv)->num_sprites[(p)] + (s) + 'A') |
| 187 | 189 | ||
| 188 | enum port { | 190 | enum port { |
| 189 | PORT_NONE = -1, | 191 | PORT_NONE = -1, |
| @@ -312,7 +314,7 @@ struct i915_hotplug { | |||
| 312 | #define for_each_pipe_masked(__dev_priv, __p, __mask) \ | 314 | #define for_each_pipe_masked(__dev_priv, __p, __mask) \ |
| 313 | for ((__p) = 0; (__p) < INTEL_INFO(__dev_priv)->num_pipes; (__p)++) \ | 315 | for ((__p) = 0; (__p) < INTEL_INFO(__dev_priv)->num_pipes; (__p)++) \ |
| 314 | for_each_if ((__mask) & (1 << (__p))) | 316 | for_each_if ((__mask) & (1 << (__p))) |
| 315 | #define for_each_plane(__dev_priv, __pipe, __p) \ | 317 | #define for_each_universal_plane(__dev_priv, __pipe, __p) \ |
| 316 | for ((__p) = 0; \ | 318 | for ((__p) = 0; \ |
| 317 | (__p) < INTEL_INFO(__dev_priv)->num_sprites[(__pipe)] + 1; \ | 319 | (__p) < INTEL_INFO(__dev_priv)->num_sprites[(__pipe)] + 1; \ |
| 318 | (__p)++) | 320 | (__p)++) |
| @@ -492,8 +494,8 @@ struct intel_limit; | |||
| 492 | struct dpll; | 494 | struct dpll; |
| 493 | 495 | ||
| 494 | struct drm_i915_display_funcs { | 496 | struct drm_i915_display_funcs { |
| 495 | int (*get_display_clock_speed)(struct drm_device *dev); | 497 | int (*get_display_clock_speed)(struct drm_i915_private *dev_priv); |
| 496 | int (*get_fifo_size)(struct drm_device *dev, int plane); | 498 | int (*get_fifo_size)(struct drm_i915_private *dev_priv, int plane); |
| 497 | int (*compute_pipe_wm)(struct intel_crtc_state *cstate); | 499 | int (*compute_pipe_wm)(struct intel_crtc_state *cstate); |
| 498 | int (*compute_intermediate_wm)(struct drm_device *dev, | 500 | int (*compute_intermediate_wm)(struct drm_device *dev, |
| 499 | struct intel_crtc *intel_crtc, | 501 | struct intel_crtc *intel_crtc, |
| @@ -501,7 +503,7 @@ struct drm_i915_display_funcs { | |||
| 501 | void (*initial_watermarks)(struct intel_crtc_state *cstate); | 503 | void (*initial_watermarks)(struct intel_crtc_state *cstate); |
| 502 | void (*optimize_watermarks)(struct intel_crtc_state *cstate); | 504 | void (*optimize_watermarks)(struct intel_crtc_state *cstate); |
| 503 | int (*compute_global_watermarks)(struct drm_atomic_state *state); | 505 | int (*compute_global_watermarks)(struct drm_atomic_state *state); |
| 504 | void (*update_wm)(struct drm_crtc *crtc); | 506 | void (*update_wm)(struct intel_crtc *crtc); |
| 505 | int (*modeset_calc_cdclk)(struct drm_atomic_state *state); | 507 | int (*modeset_calc_cdclk)(struct drm_atomic_state *state); |
| 506 | void (*modeset_commit_cdclk)(struct drm_atomic_state *state); | 508 | void (*modeset_commit_cdclk)(struct drm_atomic_state *state); |
| 507 | /* Returns the active state of the crtc, and if the crtc is active, | 509 | /* Returns the active state of the crtc, and if the crtc is active, |
| @@ -523,7 +525,7 @@ struct drm_i915_display_funcs { | |||
| 523 | const struct drm_display_mode *adjusted_mode); | 525 | const struct drm_display_mode *adjusted_mode); |
| 524 | void (*audio_codec_disable)(struct intel_encoder *encoder); | 526 | void (*audio_codec_disable)(struct intel_encoder *encoder); |
| 525 | void (*fdi_link_train)(struct drm_crtc *crtc); | 527 | void (*fdi_link_train)(struct drm_crtc *crtc); |
| 526 | void (*init_clock_gating)(struct drm_device *dev); | 528 | void (*init_clock_gating)(struct drm_i915_private *dev_priv); |
| 527 | int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc, | 529 | int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc, |
| 528 | struct drm_framebuffer *fb, | 530 | struct drm_framebuffer *fb, |
| 529 | struct drm_i915_gem_object *obj, | 531 | struct drm_i915_gem_object *obj, |
| @@ -668,6 +670,7 @@ struct intel_csr { | |||
| 668 | func(is_kabylake); \ | 670 | func(is_kabylake); \ |
| 669 | func(is_preliminary); \ | 671 | func(is_preliminary); \ |
| 670 | /* Keep has_* in alphabetical order */ \ | 672 | /* Keep has_* in alphabetical order */ \ |
| 673 | func(has_64bit_reloc); \ | ||
| 671 | func(has_csr); \ | 674 | func(has_csr); \ |
| 672 | func(has_ddi); \ | 675 | func(has_ddi); \ |
| 673 | func(has_dp_mst); \ | 676 | func(has_dp_mst); \ |
| @@ -746,6 +749,8 @@ struct intel_display_error_state; | |||
| 746 | struct drm_i915_error_state { | 749 | struct drm_i915_error_state { |
| 747 | struct kref ref; | 750 | struct kref ref; |
| 748 | struct timeval time; | 751 | struct timeval time; |
| 752 | struct timeval boottime; | ||
| 753 | struct timeval uptime; | ||
| 749 | 754 | ||
| 750 | struct drm_i915_private *i915; | 755 | struct drm_i915_private *i915; |
| 751 | 756 | ||
| @@ -778,6 +783,7 @@ struct drm_i915_error_state { | |||
| 778 | struct intel_overlay_error_state *overlay; | 783 | struct intel_overlay_error_state *overlay; |
| 779 | struct intel_display_error_state *display; | 784 | struct intel_display_error_state *display; |
| 780 | struct drm_i915_error_object *semaphore; | 785 | struct drm_i915_error_object *semaphore; |
| 786 | struct drm_i915_error_object *guc_log; | ||
| 781 | 787 | ||
| 782 | struct drm_i915_error_engine { | 788 | struct drm_i915_error_engine { |
| 783 | int engine_id; | 789 | int engine_id; |
| @@ -797,7 +803,6 @@ struct drm_i915_error_state { | |||
| 797 | u32 cpu_ring_tail; | 803 | u32 cpu_ring_tail; |
| 798 | 804 | ||
| 799 | u32 last_seqno; | 805 | u32 last_seqno; |
| 800 | u32 semaphore_seqno[I915_NUM_ENGINES - 1]; | ||
| 801 | 806 | ||
| 802 | /* Register state */ | 807 | /* Register state */ |
| 803 | u32 start; | 808 | u32 start; |
| @@ -933,6 +938,7 @@ struct i915_gem_context { | |||
| 933 | struct drm_i915_file_private *file_priv; | 938 | struct drm_i915_file_private *file_priv; |
| 934 | struct i915_hw_ppgtt *ppgtt; | 939 | struct i915_hw_ppgtt *ppgtt; |
| 935 | struct pid *pid; | 940 | struct pid *pid; |
| 941 | const char *name; | ||
| 936 | 942 | ||
| 937 | struct i915_ctx_hang_stats hang_stats; | 943 | struct i915_ctx_hang_stats hang_stats; |
| 938 | 944 | ||
| @@ -1319,6 +1325,12 @@ struct i915_power_well { | |||
| 1319 | /* cached hw enabled state */ | 1325 | /* cached hw enabled state */ |
| 1320 | bool hw_enabled; | 1326 | bool hw_enabled; |
| 1321 | unsigned long domains; | 1327 | unsigned long domains; |
| 1328 | /* unique identifier for this power well */ | ||
| 1329 | unsigned long id; | ||
| 1330 | /* | ||
| 1331 | * Arbitraty data associated with this power well. Platform and power | ||
| 1332 | * well specific. | ||
| 1333 | */ | ||
| 1322 | unsigned long data; | 1334 | unsigned long data; |
| 1323 | const struct i915_power_well_ops *ops; | 1335 | const struct i915_power_well_ops *ops; |
| 1324 | }; | 1336 | }; |
| @@ -1356,11 +1368,22 @@ struct i915_gem_mm { | |||
| 1356 | struct list_head bound_list; | 1368 | struct list_head bound_list; |
| 1357 | /** | 1369 | /** |
| 1358 | * List of objects which are not bound to the GTT (thus | 1370 | * List of objects which are not bound to the GTT (thus |
| 1359 | * are idle and not used by the GPU) but still have | 1371 | * are idle and not used by the GPU). These objects may or may |
| 1360 | * (presumably uncached) pages still attached. | 1372 | * not actually have any pages attached. |
| 1361 | */ | 1373 | */ |
| 1362 | struct list_head unbound_list; | 1374 | struct list_head unbound_list; |
| 1363 | 1375 | ||
| 1376 | /** List of all objects in gtt_space, currently mmaped by userspace. | ||
| 1377 | * All objects within this list must also be on bound_list. | ||
| 1378 | */ | ||
| 1379 | struct list_head userfault_list; | ||
| 1380 | |||
| 1381 | /** | ||
| 1382 | * List of objects which are pending destruction. | ||
| 1383 | */ | ||
| 1384 | struct llist_head free_list; | ||
| 1385 | struct work_struct free_work; | ||
| 1386 | |||
| 1364 | /** Usable portion of the GTT for GEM */ | 1387 | /** Usable portion of the GTT for GEM */ |
| 1365 | unsigned long stolen_base; /* limited to low memory (32-bit) */ | 1388 | unsigned long stolen_base; /* limited to low memory (32-bit) */ |
| 1366 | 1389 | ||
| @@ -1409,6 +1432,9 @@ struct i915_error_state_file_priv { | |||
| 1409 | struct drm_i915_error_state *error; | 1432 | struct drm_i915_error_state *error; |
| 1410 | }; | 1433 | }; |
| 1411 | 1434 | ||
| 1435 | #define I915_RESET_TIMEOUT (10 * HZ) /* 10s */ | ||
| 1436 | #define I915_FENCE_TIMEOUT (10 * HZ) /* 10s */ | ||
| 1437 | |||
| 1412 | struct i915_gpu_error { | 1438 | struct i915_gpu_error { |
| 1413 | /* For hangcheck timer */ | 1439 | /* For hangcheck timer */ |
| 1414 | #define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */ | 1440 | #define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */ |
| @@ -1682,7 +1708,6 @@ struct skl_wm_level { | |||
| 1682 | */ | 1708 | */ |
| 1683 | struct i915_runtime_pm { | 1709 | struct i915_runtime_pm { |
| 1684 | atomic_t wakeref_count; | 1710 | atomic_t wakeref_count; |
| 1685 | atomic_t atomic_seq; | ||
| 1686 | bool suspended; | 1711 | bool suspended; |
| 1687 | bool irqs_enabled; | 1712 | bool irqs_enabled; |
| 1688 | }; | 1713 | }; |
| @@ -1807,7 +1832,6 @@ struct drm_i915_private { | |||
| 1807 | struct i915_gem_context *kernel_context; | 1832 | struct i915_gem_context *kernel_context; |
| 1808 | struct intel_engine_cs *engine[I915_NUM_ENGINES]; | 1833 | struct intel_engine_cs *engine[I915_NUM_ENGINES]; |
| 1809 | struct i915_vma *semaphore; | 1834 | struct i915_vma *semaphore; |
| 1810 | u32 next_seqno; | ||
| 1811 | 1835 | ||
| 1812 | struct drm_dma_handle *status_page_dmah; | 1836 | struct drm_dma_handle *status_page_dmah; |
| 1813 | struct resource mch_res; | 1837 | struct resource mch_res; |
| @@ -1832,8 +1856,10 @@ struct drm_i915_private { | |||
| 1832 | u32 de_irq_mask[I915_MAX_PIPES]; | 1856 | u32 de_irq_mask[I915_MAX_PIPES]; |
| 1833 | }; | 1857 | }; |
| 1834 | u32 gt_irq_mask; | 1858 | u32 gt_irq_mask; |
| 1835 | u32 pm_irq_mask; | 1859 | u32 pm_imr; |
| 1860 | u32 pm_ier; | ||
| 1836 | u32 pm_rps_events; | 1861 | u32 pm_rps_events; |
| 1862 | u32 pm_guc_events; | ||
| 1837 | u32 pipestat_irq_mask[I915_MAX_PIPES]; | 1863 | u32 pipestat_irq_mask[I915_MAX_PIPES]; |
| 1838 | 1864 | ||
| 1839 | struct i915_hotplug hotplug; | 1865 | struct i915_hotplug hotplug; |
| @@ -1910,8 +1936,8 @@ struct drm_i915_private { | |||
| 1910 | 1936 | ||
| 1911 | /* Kernel Modesetting */ | 1937 | /* Kernel Modesetting */ |
| 1912 | 1938 | ||
| 1913 | struct drm_crtc *plane_to_crtc_mapping[I915_MAX_PIPES]; | 1939 | struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES]; |
| 1914 | struct drm_crtc *pipe_to_crtc_mapping[I915_MAX_PIPES]; | 1940 | struct intel_crtc *pipe_to_crtc_mapping[I915_MAX_PIPES]; |
| 1915 | wait_queue_head_t pending_flip_queue; | 1941 | wait_queue_head_t pending_flip_queue; |
| 1916 | 1942 | ||
| 1917 | #ifdef CONFIG_DEBUG_FS | 1943 | #ifdef CONFIG_DEBUG_FS |
| @@ -2065,6 +2091,10 @@ struct drm_i915_private { | |||
| 2065 | void (*resume)(struct drm_i915_private *); | 2091 | void (*resume)(struct drm_i915_private *); |
| 2066 | void (*cleanup_engine)(struct intel_engine_cs *engine); | 2092 | void (*cleanup_engine)(struct intel_engine_cs *engine); |
| 2067 | 2093 | ||
| 2094 | struct list_head timelines; | ||
| 2095 | struct i915_gem_timeline global_timeline; | ||
| 2096 | u32 active_requests; | ||
| 2097 | |||
| 2068 | /** | 2098 | /** |
| 2069 | * Is the GPU currently considered idle, or busy executing | 2099 | * Is the GPU currently considered idle, or busy executing |
| 2070 | * userspace requests? Whilst idle, we allow runtime power | 2100 | * userspace requests? Whilst idle, we allow runtime power |
| @@ -2072,7 +2102,6 @@ struct drm_i915_private { | |||
| 2072 | * In order to reduce the effect on performance, there | 2102 | * In order to reduce the effect on performance, there |
| 2073 | * is a slight delay before we do so. | 2103 | * is a slight delay before we do so. |
| 2074 | */ | 2104 | */ |
| 2075 | unsigned int active_engines; | ||
| 2076 | bool awake; | 2105 | bool awake; |
| 2077 | 2106 | ||
| 2078 | /** | 2107 | /** |
| @@ -2092,6 +2121,8 @@ struct drm_i915_private { | |||
| 2092 | * off the idle_work. | 2121 | * off the idle_work. |
| 2093 | */ | 2122 | */ |
| 2094 | struct delayed_work idle_work; | 2123 | struct delayed_work idle_work; |
| 2124 | |||
| 2125 | ktime_t last_init_time; | ||
| 2095 | } gt; | 2126 | } gt; |
| 2096 | 2127 | ||
| 2097 | /* perform PHY state sanity checks? */ | 2128 | /* perform PHY state sanity checks? */ |
| @@ -2151,6 +2182,7 @@ enum hdmi_force_audio { | |||
| 2151 | struct drm_i915_gem_object_ops { | 2182 | struct drm_i915_gem_object_ops { |
| 2152 | unsigned int flags; | 2183 | unsigned int flags; |
| 2153 | #define I915_GEM_OBJECT_HAS_STRUCT_PAGE 0x1 | 2184 | #define I915_GEM_OBJECT_HAS_STRUCT_PAGE 0x1 |
| 2185 | #define I915_GEM_OBJECT_IS_SHRINKABLE 0x2 | ||
| 2154 | 2186 | ||
| 2155 | /* Interface between the GEM object and its backing storage. | 2187 | /* Interface between the GEM object and its backing storage. |
| 2156 | * get_pages() is called once prior to the use of the associated set | 2188 | * get_pages() is called once prior to the use of the associated set |
| @@ -2165,8 +2197,8 @@ struct drm_i915_gem_object_ops { | |||
| 2165 | * being released or under memory pressure (where we attempt to | 2197 | * being released or under memory pressure (where we attempt to |
| 2166 | * reap pages for the shrinker). | 2198 | * reap pages for the shrinker). |
| 2167 | */ | 2199 | */ |
| 2168 | int (*get_pages)(struct drm_i915_gem_object *); | 2200 | struct sg_table *(*get_pages)(struct drm_i915_gem_object *); |
| 2169 | void (*put_pages)(struct drm_i915_gem_object *); | 2201 | void (*put_pages)(struct drm_i915_gem_object *, struct sg_table *); |
| 2170 | 2202 | ||
| 2171 | int (*dmabuf_export)(struct drm_i915_gem_object *); | 2203 | int (*dmabuf_export)(struct drm_i915_gem_object *); |
| 2172 | void (*release)(struct drm_i915_gem_object *); | 2204 | void (*release)(struct drm_i915_gem_object *); |
| @@ -2200,10 +2232,20 @@ struct drm_i915_gem_object { | |||
| 2200 | 2232 | ||
| 2201 | /** List of VMAs backed by this object */ | 2233 | /** List of VMAs backed by this object */ |
| 2202 | struct list_head vma_list; | 2234 | struct list_head vma_list; |
| 2235 | struct rb_root vma_tree; | ||
| 2203 | 2236 | ||
| 2204 | /** Stolen memory for this object, instead of being backed by shmem. */ | 2237 | /** Stolen memory for this object, instead of being backed by shmem. */ |
| 2205 | struct drm_mm_node *stolen; | 2238 | struct drm_mm_node *stolen; |
| 2206 | struct list_head global_list; | 2239 | struct list_head global_link; |
| 2240 | union { | ||
| 2241 | struct rcu_head rcu; | ||
| 2242 | struct llist_node freed; | ||
| 2243 | }; | ||
| 2244 | |||
| 2245 | /** | ||
| 2246 | * Whether the object is currently in the GGTT mmap. | ||
| 2247 | */ | ||
| 2248 | struct list_head userfault_link; | ||
| 2207 | 2249 | ||
| 2208 | /** Used in execbuf to temporarily hold a ref */ | 2250 | /** Used in execbuf to temporarily hold a ref */ |
| 2209 | struct list_head obj_exec_link; | 2251 | struct list_head obj_exec_link; |
| @@ -2211,33 +2253,12 @@ struct drm_i915_gem_object { | |||
| 2211 | struct list_head batch_pool_link; | 2253 | struct list_head batch_pool_link; |
| 2212 | 2254 | ||
| 2213 | unsigned long flags; | 2255 | unsigned long flags; |
| 2214 | /** | ||
| 2215 | * This is set if the object is on the active lists (has pending | ||
| 2216 | * rendering and so a non-zero seqno), and is not set if it i s on | ||
| 2217 | * inactive (ready to be unbound) list. | ||
| 2218 | */ | ||
| 2219 | #define I915_BO_ACTIVE_SHIFT 0 | ||
| 2220 | #define I915_BO_ACTIVE_MASK ((1 << I915_NUM_ENGINES) - 1) | ||
| 2221 | #define __I915_BO_ACTIVE(bo) \ | ||
| 2222 | ((READ_ONCE((bo)->flags) >> I915_BO_ACTIVE_SHIFT) & I915_BO_ACTIVE_MASK) | ||
| 2223 | 2256 | ||
| 2224 | /** | 2257 | /** |
| 2225 | * This is set if the object has been written to since last bound | 2258 | * Have we taken a reference for the object for incomplete GPU |
| 2226 | * to the GTT | 2259 | * activity? |
| 2227 | */ | 2260 | */ |
| 2228 | unsigned int dirty:1; | 2261 | #define I915_BO_ACTIVE_REF 0 |
| 2229 | |||
| 2230 | /** | ||
| 2231 | * Advice: are the backing pages purgeable? | ||
| 2232 | */ | ||
| 2233 | unsigned int madv:2; | ||
| 2234 | |||
| 2235 | /** | ||
| 2236 | * Whether the current gtt mapping needs to be mappable (and isn't just | ||
| 2237 | * mappable by accident). Track pin and fault separate for a more | ||
| 2238 | * accurate mappable working set. | ||
| 2239 | */ | ||
| 2240 | unsigned int fault_mappable:1; | ||
| 2241 | 2262 | ||
| 2242 | /* | 2263 | /* |
| 2243 | * Is the object to be mapped as read-only to the GPU | 2264 | * Is the object to be mapped as read-only to the GPU |
| @@ -2258,15 +2279,41 @@ struct drm_i915_gem_object { | |||
| 2258 | 2279 | ||
| 2259 | /** Count of VMA actually bound by this object */ | 2280 | /** Count of VMA actually bound by this object */ |
| 2260 | unsigned int bind_count; | 2281 | unsigned int bind_count; |
| 2282 | unsigned int active_count; | ||
| 2261 | unsigned int pin_display; | 2283 | unsigned int pin_display; |
| 2262 | 2284 | ||
| 2263 | struct sg_table *pages; | 2285 | struct { |
| 2264 | int pages_pin_count; | 2286 | struct mutex lock; /* protects the pages and their use */ |
| 2265 | struct get_page { | 2287 | atomic_t pages_pin_count; |
| 2266 | struct scatterlist *sg; | 2288 | |
| 2267 | int last; | 2289 | struct sg_table *pages; |
| 2268 | } get_page; | 2290 | void *mapping; |
| 2269 | void *mapping; | 2291 | |
| 2292 | struct i915_gem_object_page_iter { | ||
| 2293 | struct scatterlist *sg_pos; | ||
| 2294 | unsigned int sg_idx; /* in pages, but 32bit eek! */ | ||
| 2295 | |||
| 2296 | struct radix_tree_root radix; | ||
| 2297 | struct mutex lock; /* protects this cache */ | ||
| 2298 | } get_page; | ||
| 2299 | |||
| 2300 | /** | ||
| 2301 | * Advice: are the backing pages purgeable? | ||
| 2302 | */ | ||
| 2303 | unsigned int madv:2; | ||
| 2304 | |||
| 2305 | /** | ||
| 2306 | * This is set if the object has been written to since the | ||
| 2307 | * pages were last acquired. | ||
| 2308 | */ | ||
| 2309 | bool dirty:1; | ||
| 2310 | |||
| 2311 | /** | ||
| 2312 | * This is set if the object has been pinned due to unknown | ||
| 2313 | * swizzling. | ||
| 2314 | */ | ||
| 2315 | bool quirked:1; | ||
| 2316 | } mm; | ||
| 2270 | 2317 | ||
| 2271 | /** Breadcrumb of last rendering to the buffer. | 2318 | /** Breadcrumb of last rendering to the buffer. |
| 2272 | * There can only be one writer, but we allow for multiple readers. | 2319 | * There can only be one writer, but we allow for multiple readers. |
| @@ -2278,8 +2325,7 @@ struct drm_i915_gem_object { | |||
| 2278 | * read request. This allows for the CPU to read from an active | 2325 | * read request. This allows for the CPU to read from an active |
| 2279 | * buffer by only waiting for the write to complete. | 2326 | * buffer by only waiting for the write to complete. |
| 2280 | */ | 2327 | */ |
| 2281 | struct i915_gem_active last_read[I915_NUM_ENGINES]; | 2328 | struct reservation_object *resv; |
| 2282 | struct i915_gem_active last_write; | ||
| 2283 | 2329 | ||
| 2284 | /** References from framebuffers, locks out tiling changes. */ | 2330 | /** References from framebuffers, locks out tiling changes. */ |
| 2285 | unsigned long framebuffer_references; | 2331 | unsigned long framebuffer_references; |
| @@ -2290,8 +2336,6 @@ struct drm_i915_gem_object { | |||
| 2290 | struct i915_gem_userptr { | 2336 | struct i915_gem_userptr { |
| 2291 | uintptr_t ptr; | 2337 | uintptr_t ptr; |
| 2292 | unsigned read_only :1; | 2338 | unsigned read_only :1; |
| 2293 | unsigned workers :4; | ||
| 2294 | #define I915_GEM_USERPTR_MAX_WORKERS 15 | ||
| 2295 | 2339 | ||
| 2296 | struct i915_mm_struct *mm; | 2340 | struct i915_mm_struct *mm; |
| 2297 | struct i915_mmu_object *mmu_object; | 2341 | struct i915_mmu_object *mmu_object; |
| @@ -2300,6 +2344,8 @@ struct drm_i915_gem_object { | |||
| 2300 | 2344 | ||
| 2301 | /** for phys allocated objects */ | 2345 | /** for phys allocated objects */ |
| 2302 | struct drm_dma_handle *phys_handle; | 2346 | struct drm_dma_handle *phys_handle; |
| 2347 | |||
| 2348 | struct reservation_object __builtin_resv; | ||
| 2303 | }; | 2349 | }; |
| 2304 | 2350 | ||
| 2305 | static inline struct drm_i915_gem_object * | 2351 | static inline struct drm_i915_gem_object * |
| @@ -2311,10 +2357,38 @@ to_intel_bo(struct drm_gem_object *gem) | |||
| 2311 | return container_of(gem, struct drm_i915_gem_object, base); | 2357 | return container_of(gem, struct drm_i915_gem_object, base); |
| 2312 | } | 2358 | } |
| 2313 | 2359 | ||
| 2360 | /** | ||
| 2361 | * i915_gem_object_lookup_rcu - look up a temporary GEM object from its handle | ||
| 2362 | * @filp: DRM file private date | ||
| 2363 | * @handle: userspace handle | ||
| 2364 | * | ||
| 2365 | * Returns: | ||
| 2366 | * | ||
| 2367 | * A pointer to the object named by the handle if such exists on @filp, NULL | ||
| 2368 | * otherwise. This object is only valid whilst under the RCU read lock, and | ||
| 2369 | * note carefully the object may be in the process of being destroyed. | ||
| 2370 | */ | ||
| 2371 | static inline struct drm_i915_gem_object * | ||
| 2372 | i915_gem_object_lookup_rcu(struct drm_file *file, u32 handle) | ||
| 2373 | { | ||
| 2374 | #ifdef CONFIG_LOCKDEP | ||
| 2375 | WARN_ON(debug_locks && !lock_is_held(&rcu_lock_map)); | ||
| 2376 | #endif | ||
| 2377 | return idr_find(&file->object_idr, handle); | ||
| 2378 | } | ||
| 2379 | |||
| 2314 | static inline struct drm_i915_gem_object * | 2380 | static inline struct drm_i915_gem_object * |
| 2315 | i915_gem_object_lookup(struct drm_file *file, u32 handle) | 2381 | i915_gem_object_lookup(struct drm_file *file, u32 handle) |
| 2316 | { | 2382 | { |
| 2317 | return to_intel_bo(drm_gem_object_lookup(file, handle)); | 2383 | struct drm_i915_gem_object *obj; |
| 2384 | |||
| 2385 | rcu_read_lock(); | ||
| 2386 | obj = i915_gem_object_lookup_rcu(file, handle); | ||
| 2387 | if (obj && !kref_get_unless_zero(&obj->base.refcount)) | ||
| 2388 | obj = NULL; | ||
| 2389 | rcu_read_unlock(); | ||
| 2390 | |||
| 2391 | return obj; | ||
| 2318 | } | 2392 | } |
| 2319 | 2393 | ||
| 2320 | __deprecated | 2394 | __deprecated |
| @@ -2336,59 +2410,61 @@ __attribute__((nonnull)) | |||
| 2336 | static inline void | 2410 | static inline void |
| 2337 | i915_gem_object_put(struct drm_i915_gem_object *obj) | 2411 | i915_gem_object_put(struct drm_i915_gem_object *obj) |
| 2338 | { | 2412 | { |
| 2339 | drm_gem_object_unreference(&obj->base); | 2413 | __drm_gem_object_unreference(&obj->base); |
| 2340 | } | 2414 | } |
| 2341 | 2415 | ||
| 2342 | __deprecated | 2416 | __deprecated |
| 2343 | extern void drm_gem_object_unreference(struct drm_gem_object *); | 2417 | extern void drm_gem_object_unreference(struct drm_gem_object *); |
| 2344 | 2418 | ||
| 2345 | __attribute__((nonnull)) | ||
| 2346 | static inline void | ||
| 2347 | i915_gem_object_put_unlocked(struct drm_i915_gem_object *obj) | ||
| 2348 | { | ||
| 2349 | drm_gem_object_unreference_unlocked(&obj->base); | ||
| 2350 | } | ||
| 2351 | |||
| 2352 | __deprecated | 2419 | __deprecated |
| 2353 | extern void drm_gem_object_unreference_unlocked(struct drm_gem_object *); | 2420 | extern void drm_gem_object_unreference_unlocked(struct drm_gem_object *); |
| 2354 | 2421 | ||
| 2355 | static inline bool | 2422 | static inline bool |
| 2423 | i915_gem_object_is_dead(const struct drm_i915_gem_object *obj) | ||
| 2424 | { | ||
| 2425 | return atomic_read(&obj->base.refcount.refcount) == 0; | ||
| 2426 | } | ||
| 2427 | |||
| 2428 | static inline bool | ||
| 2356 | i915_gem_object_has_struct_page(const struct drm_i915_gem_object *obj) | 2429 | i915_gem_object_has_struct_page(const struct drm_i915_gem_object *obj) |
| 2357 | { | 2430 | { |
| 2358 | return obj->ops->flags & I915_GEM_OBJECT_HAS_STRUCT_PAGE; | 2431 | return obj->ops->flags & I915_GEM_OBJECT_HAS_STRUCT_PAGE; |
| 2359 | } | 2432 | } |
| 2360 | 2433 | ||
| 2361 | static inline unsigned long | 2434 | static inline bool |
| 2362 | i915_gem_object_get_active(const struct drm_i915_gem_object *obj) | 2435 | i915_gem_object_is_shrinkable(const struct drm_i915_gem_object *obj) |
| 2363 | { | 2436 | { |
| 2364 | return (obj->flags >> I915_BO_ACTIVE_SHIFT) & I915_BO_ACTIVE_MASK; | 2437 | return obj->ops->flags & I915_GEM_OBJECT_IS_SHRINKABLE; |
| 2365 | } | 2438 | } |
| 2366 | 2439 | ||
| 2367 | static inline bool | 2440 | static inline bool |
| 2368 | i915_gem_object_is_active(const struct drm_i915_gem_object *obj) | 2441 | i915_gem_object_is_active(const struct drm_i915_gem_object *obj) |
| 2369 | { | 2442 | { |
| 2370 | return i915_gem_object_get_active(obj); | 2443 | return obj->active_count; |
| 2371 | } | 2444 | } |
| 2372 | 2445 | ||
| 2373 | static inline void | 2446 | static inline bool |
| 2374 | i915_gem_object_set_active(struct drm_i915_gem_object *obj, int engine) | 2447 | i915_gem_object_has_active_reference(const struct drm_i915_gem_object *obj) |
| 2375 | { | 2448 | { |
| 2376 | obj->flags |= BIT(engine + I915_BO_ACTIVE_SHIFT); | 2449 | return test_bit(I915_BO_ACTIVE_REF, &obj->flags); |
| 2377 | } | 2450 | } |
| 2378 | 2451 | ||
| 2379 | static inline void | 2452 | static inline void |
| 2380 | i915_gem_object_clear_active(struct drm_i915_gem_object *obj, int engine) | 2453 | i915_gem_object_set_active_reference(struct drm_i915_gem_object *obj) |
| 2381 | { | 2454 | { |
| 2382 | obj->flags &= ~BIT(engine + I915_BO_ACTIVE_SHIFT); | 2455 | lockdep_assert_held(&obj->base.dev->struct_mutex); |
| 2456 | __set_bit(I915_BO_ACTIVE_REF, &obj->flags); | ||
| 2383 | } | 2457 | } |
| 2384 | 2458 | ||
| 2385 | static inline bool | 2459 | static inline void |
| 2386 | i915_gem_object_has_active_engine(const struct drm_i915_gem_object *obj, | 2460 | i915_gem_object_clear_active_reference(struct drm_i915_gem_object *obj) |
| 2387 | int engine) | ||
| 2388 | { | 2461 | { |
| 2389 | return obj->flags & BIT(engine + I915_BO_ACTIVE_SHIFT); | 2462 | lockdep_assert_held(&obj->base.dev->struct_mutex); |
| 2463 | __clear_bit(I915_BO_ACTIVE_REF, &obj->flags); | ||
| 2390 | } | 2464 | } |
| 2391 | 2465 | ||
| 2466 | void __i915_gem_object_release_unless_active(struct drm_i915_gem_object *obj); | ||
| 2467 | |||
| 2392 | static inline unsigned int | 2468 | static inline unsigned int |
| 2393 | i915_gem_object_get_tiling(struct drm_i915_gem_object *obj) | 2469 | i915_gem_object_get_tiling(struct drm_i915_gem_object *obj) |
| 2394 | { | 2470 | { |
| @@ -2407,6 +2483,23 @@ i915_gem_object_get_stride(struct drm_i915_gem_object *obj) | |||
| 2407 | return obj->tiling_and_stride & STRIDE_MASK; | 2483 | return obj->tiling_and_stride & STRIDE_MASK; |
| 2408 | } | 2484 | } |
| 2409 | 2485 | ||
| 2486 | static inline struct intel_engine_cs * | ||
| 2487 | i915_gem_object_last_write_engine(struct drm_i915_gem_object *obj) | ||
| 2488 | { | ||
| 2489 | struct intel_engine_cs *engine = NULL; | ||
| 2490 | struct dma_fence *fence; | ||
| 2491 | |||
| 2492 | rcu_read_lock(); | ||
| 2493 | fence = reservation_object_get_excl_rcu(obj->resv); | ||
| 2494 | rcu_read_unlock(); | ||
| 2495 | |||
| 2496 | if (fence && dma_fence_is_i915(fence) && !dma_fence_is_signaled(fence)) | ||
| 2497 | engine = to_request(fence)->engine; | ||
| 2498 | dma_fence_put(fence); | ||
| 2499 | |||
| 2500 | return engine; | ||
| 2501 | } | ||
| 2502 | |||
| 2410 | static inline struct i915_vma *i915_vma_get(struct i915_vma *vma) | 2503 | static inline struct i915_vma *i915_vma_get(struct i915_vma *vma) |
| 2411 | { | 2504 | { |
| 2412 | i915_gem_object_get(vma->obj); | 2505 | i915_gem_object_get(vma->obj); |
| @@ -2415,7 +2508,6 @@ static inline struct i915_vma *i915_vma_get(struct i915_vma *vma) | |||
| 2415 | 2508 | ||
| 2416 | static inline void i915_vma_put(struct i915_vma *vma) | 2509 | static inline void i915_vma_put(struct i915_vma *vma) |
| 2417 | { | 2510 | { |
| 2418 | lockdep_assert_held(&vma->vm->dev->struct_mutex); | ||
| 2419 | i915_gem_object_put(vma->obj); | 2511 | i915_gem_object_put(vma->obj); |
| 2420 | } | 2512 | } |
| 2421 | 2513 | ||
| @@ -2445,6 +2537,14 @@ static __always_inline struct sgt_iter { | |||
| 2445 | return s; | 2537 | return s; |
| 2446 | } | 2538 | } |
| 2447 | 2539 | ||
| 2540 | static inline struct scatterlist *____sg_next(struct scatterlist *sg) | ||
| 2541 | { | ||
| 2542 | ++sg; | ||
| 2543 | if (unlikely(sg_is_chain(sg))) | ||
| 2544 | sg = sg_chain_ptr(sg); | ||
| 2545 | return sg; | ||
| 2546 | } | ||
| 2547 | |||
| 2448 | /** | 2548 | /** |
| 2449 | * __sg_next - return the next scatterlist entry in a list | 2549 | * __sg_next - return the next scatterlist entry in a list |
| 2450 | * @sg: The current sg entry | 2550 | * @sg: The current sg entry |
| @@ -2459,9 +2559,7 @@ static inline struct scatterlist *__sg_next(struct scatterlist *sg) | |||
| 2459 | #ifdef CONFIG_DEBUG_SG | 2559 | #ifdef CONFIG_DEBUG_SG |
| 2460 | BUG_ON(sg->sg_magic != SG_MAGIC); | 2560 | BUG_ON(sg->sg_magic != SG_MAGIC); |
| 2461 | #endif | 2561 | #endif |
| 2462 | return sg_is_last(sg) ? NULL : | 2562 | return sg_is_last(sg) ? NULL : ____sg_next(sg); |
| 2463 | likely(!sg_is_chain(++sg)) ? sg : | ||
| 2464 | sg_chain_ptr(sg); | ||
| 2465 | } | 2563 | } |
| 2466 | 2564 | ||
| 2467 | /** | 2565 | /** |
| @@ -2633,20 +2731,20 @@ struct drm_i915_cmd_table { | |||
| 2633 | 2731 | ||
| 2634 | #define IS_I830(dev_priv) (INTEL_DEVID(dev_priv) == 0x3577) | 2732 | #define IS_I830(dev_priv) (INTEL_DEVID(dev_priv) == 0x3577) |
| 2635 | #define IS_845G(dev_priv) (INTEL_DEVID(dev_priv) == 0x2562) | 2733 | #define IS_845G(dev_priv) (INTEL_DEVID(dev_priv) == 0x2562) |
| 2636 | #define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x) | 2734 | #define IS_I85X(dev_priv) ((dev_priv)->info.is_i85x) |
| 2637 | #define IS_I865G(dev_priv) (INTEL_DEVID(dev_priv) == 0x2572) | 2735 | #define IS_I865G(dev_priv) (INTEL_DEVID(dev_priv) == 0x2572) |
| 2638 | #define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) | 2736 | #define IS_I915G(dev_priv) ((dev_priv)->info.is_i915g) |
| 2639 | #define IS_I915GM(dev_priv) (INTEL_DEVID(dev_priv) == 0x2592) | 2737 | #define IS_I915GM(dev_priv) (INTEL_DEVID(dev_priv) == 0x2592) |
| 2640 | #define IS_I945G(dev_priv) (INTEL_DEVID(dev_priv) == 0x2772) | 2738 | #define IS_I945G(dev_priv) (INTEL_DEVID(dev_priv) == 0x2772) |
| 2641 | #define IS_I945GM(dev) (INTEL_INFO(dev)->is_i945gm) | 2739 | #define IS_I945GM(dev_priv) ((dev_priv)->info.is_i945gm) |
| 2642 | #define IS_BROADWATER(dev) (INTEL_INFO(dev)->is_broadwater) | 2740 | #define IS_BROADWATER(dev_priv) ((dev_priv)->info.is_broadwater) |
| 2643 | #define IS_CRESTLINE(dev) (INTEL_INFO(dev)->is_crestline) | 2741 | #define IS_CRESTLINE(dev_priv) ((dev_priv)->info.is_crestline) |
| 2644 | #define IS_GM45(dev_priv) (INTEL_DEVID(dev_priv) == 0x2A42) | 2742 | #define IS_GM45(dev_priv) (INTEL_DEVID(dev_priv) == 0x2A42) |
| 2645 | #define IS_G4X(dev_priv) ((dev_priv)->info.is_g4x) | 2743 | #define IS_G4X(dev_priv) ((dev_priv)->info.is_g4x) |
| 2646 | #define IS_PINEVIEW_G(dev_priv) (INTEL_DEVID(dev_priv) == 0xa001) | 2744 | #define IS_PINEVIEW_G(dev_priv) (INTEL_DEVID(dev_priv) == 0xa001) |
| 2647 | #define IS_PINEVIEW_M(dev_priv) (INTEL_DEVID(dev_priv) == 0xa011) | 2745 | #define IS_PINEVIEW_M(dev_priv) (INTEL_DEVID(dev_priv) == 0xa011) |
| 2648 | #define IS_PINEVIEW(dev) (INTEL_INFO(dev)->is_pineview) | 2746 | #define IS_PINEVIEW(dev_priv) ((dev_priv)->info.is_pineview) |
| 2649 | #define IS_G33(dev) (INTEL_INFO(dev)->is_g33) | 2747 | #define IS_G33(dev_priv) ((dev_priv)->info.is_g33) |
| 2650 | #define IS_IRONLAKE_M(dev_priv) (INTEL_DEVID(dev_priv) == 0x0046) | 2748 | #define IS_IRONLAKE_M(dev_priv) (INTEL_DEVID(dev_priv) == 0x0046) |
| 2651 | #define IS_IVYBRIDGE(dev_priv) ((dev_priv)->info.is_ivybridge) | 2749 | #define IS_IVYBRIDGE(dev_priv) ((dev_priv)->info.is_ivybridge) |
| 2652 | #define IS_IVB_GT1(dev_priv) (INTEL_DEVID(dev_priv) == 0x0156 || \ | 2750 | #define IS_IVB_GT1(dev_priv) (INTEL_DEVID(dev_priv) == 0x0156 || \ |
| @@ -2659,7 +2757,7 @@ struct drm_i915_cmd_table { | |||
| 2659 | #define IS_SKYLAKE(dev_priv) ((dev_priv)->info.is_skylake) | 2757 | #define IS_SKYLAKE(dev_priv) ((dev_priv)->info.is_skylake) |
| 2660 | #define IS_BROXTON(dev_priv) ((dev_priv)->info.is_broxton) | 2758 | #define IS_BROXTON(dev_priv) ((dev_priv)->info.is_broxton) |
| 2661 | #define IS_KABYLAKE(dev_priv) ((dev_priv)->info.is_kabylake) | 2759 | #define IS_KABYLAKE(dev_priv) ((dev_priv)->info.is_kabylake) |
| 2662 | #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) | 2760 | #define IS_MOBILE(dev_priv) ((dev_priv)->info.is_mobile) |
| 2663 | #define IS_HSW_EARLY_SDV(dev_priv) (IS_HASWELL(dev_priv) && \ | 2761 | #define IS_HSW_EARLY_SDV(dev_priv) (IS_HASWELL(dev_priv) && \ |
| 2664 | (INTEL_DEVID(dev_priv) & 0xFF00) == 0x0C00) | 2762 | (INTEL_DEVID(dev_priv) & 0xFF00) == 0x0C00) |
| 2665 | #define IS_BDW_ULT(dev_priv) (IS_BROADWELL(dev_priv) && \ | 2763 | #define IS_BDW_ULT(dev_priv) (IS_BROADWELL(dev_priv) && \ |
| @@ -2803,7 +2901,7 @@ struct drm_i915_cmd_table { | |||
| 2803 | #define SUPPORTS_TV(dev) (INTEL_INFO(dev)->supports_tv) | 2901 | #define SUPPORTS_TV(dev) (INTEL_INFO(dev)->supports_tv) |
| 2804 | #define I915_HAS_HOTPLUG(dev) (INTEL_INFO(dev)->has_hotplug) | 2902 | #define I915_HAS_HOTPLUG(dev) (INTEL_INFO(dev)->has_hotplug) |
| 2805 | 2903 | ||
| 2806 | #define HAS_FW_BLC(dev) (INTEL_INFO(dev)->gen > 2) | 2904 | #define HAS_FW_BLC(dev_priv) (INTEL_GEN(dev_priv) > 2) |
| 2807 | #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) | 2905 | #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) |
| 2808 | #define HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) | 2906 | #define HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) |
| 2809 | 2907 | ||
| @@ -2820,6 +2918,8 @@ struct drm_i915_cmd_table { | |||
| 2820 | #define HAS_CSR(dev) (INTEL_INFO(dev)->has_csr) | 2918 | #define HAS_CSR(dev) (INTEL_INFO(dev)->has_csr) |
| 2821 | 2919 | ||
| 2822 | #define HAS_RUNTIME_PM(dev_priv) ((dev_priv)->info.has_runtime_pm) | 2920 | #define HAS_RUNTIME_PM(dev_priv) ((dev_priv)->info.has_runtime_pm) |
| 2921 | #define HAS_64BIT_RELOC(dev_priv) ((dev_priv)->info.has_64bit_reloc) | ||
| 2922 | |||
| 2823 | /* | 2923 | /* |
| 2824 | * For now, anything with a GuC requires uCode loading, and then supports | 2924 | * For now, anything with a GuC requires uCode loading, and then supports |
| 2825 | * command submission once loaded. But these are logically independent | 2925 | * command submission once loaded. But these are logically independent |
| @@ -2912,6 +3012,7 @@ extern bool intel_has_gpu_reset(struct drm_i915_private *dev_priv); | |||
| 2912 | extern void i915_reset(struct drm_i915_private *dev_priv); | 3012 | extern void i915_reset(struct drm_i915_private *dev_priv); |
| 2913 | extern int intel_guc_reset(struct drm_i915_private *dev_priv); | 3013 | extern int intel_guc_reset(struct drm_i915_private *dev_priv); |
| 2914 | extern void intel_engine_init_hangcheck(struct intel_engine_cs *engine); | 3014 | extern void intel_engine_init_hangcheck(struct intel_engine_cs *engine); |
| 3015 | extern void intel_hangcheck_init(struct drm_i915_private *dev_priv); | ||
| 2915 | extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv); | 3016 | extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv); |
| 2916 | extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv); | 3017 | extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv); |
| 2917 | extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv); | 3018 | extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv); |
| @@ -3095,7 +3196,7 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, | |||
| 3095 | struct drm_file *file_priv); | 3196 | struct drm_file *file_priv); |
| 3096 | int i915_gem_wait_ioctl(struct drm_device *dev, void *data, | 3197 | int i915_gem_wait_ioctl(struct drm_device *dev, void *data, |
| 3097 | struct drm_file *file_priv); | 3198 | struct drm_file *file_priv); |
| 3098 | void i915_gem_load_init(struct drm_device *dev); | 3199 | int i915_gem_load_init(struct drm_device *dev); |
| 3099 | void i915_gem_load_cleanup(struct drm_device *dev); | 3200 | void i915_gem_load_cleanup(struct drm_device *dev); |
| 3100 | void i915_gem_load_init_fences(struct drm_i915_private *dev_priv); | 3201 | void i915_gem_load_init_fences(struct drm_i915_private *dev_priv); |
| 3101 | int i915_gem_freeze(struct drm_i915_private *dev_priv); | 3202 | int i915_gem_freeze(struct drm_i915_private *dev_priv); |
| @@ -3127,70 +3228,85 @@ void i915_vma_close(struct i915_vma *vma); | |||
| 3127 | void i915_vma_destroy(struct i915_vma *vma); | 3228 | void i915_vma_destroy(struct i915_vma *vma); |
| 3128 | 3229 | ||
| 3129 | int i915_gem_object_unbind(struct drm_i915_gem_object *obj); | 3230 | int i915_gem_object_unbind(struct drm_i915_gem_object *obj); |
| 3130 | int i915_gem_object_put_pages(struct drm_i915_gem_object *obj); | ||
| 3131 | void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv); | ||
| 3132 | void i915_gem_release_mmap(struct drm_i915_gem_object *obj); | 3231 | void i915_gem_release_mmap(struct drm_i915_gem_object *obj); |
| 3133 | 3232 | ||
| 3134 | int __must_check i915_gem_object_get_pages(struct drm_i915_gem_object *obj); | 3233 | void i915_gem_runtime_suspend(struct drm_i915_private *dev_priv); |
| 3135 | 3234 | ||
| 3136 | static inline int __sg_page_count(struct scatterlist *sg) | 3235 | static inline int __sg_page_count(const struct scatterlist *sg) |
| 3137 | { | 3236 | { |
| 3138 | return sg->length >> PAGE_SHIFT; | 3237 | return sg->length >> PAGE_SHIFT; |
| 3139 | } | 3238 | } |
| 3140 | 3239 | ||
| 3240 | struct scatterlist * | ||
| 3241 | i915_gem_object_get_sg(struct drm_i915_gem_object *obj, | ||
| 3242 | unsigned int n, unsigned int *offset); | ||
| 3243 | |||
| 3244 | struct page * | ||
| 3245 | i915_gem_object_get_page(struct drm_i915_gem_object *obj, | ||
| 3246 | unsigned int n); | ||
| 3247 | |||
| 3141 | struct page * | 3248 | struct page * |
| 3142 | i915_gem_object_get_dirty_page(struct drm_i915_gem_object *obj, int n); | 3249 | i915_gem_object_get_dirty_page(struct drm_i915_gem_object *obj, |
| 3250 | unsigned int n); | ||
| 3143 | 3251 | ||
| 3144 | static inline dma_addr_t | 3252 | dma_addr_t |
| 3145 | i915_gem_object_get_dma_address(struct drm_i915_gem_object *obj, int n) | 3253 | i915_gem_object_get_dma_address(struct drm_i915_gem_object *obj, |
| 3254 | unsigned long n); | ||
| 3255 | |||
| 3256 | void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, | ||
| 3257 | struct sg_table *pages); | ||
| 3258 | int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj); | ||
| 3259 | |||
| 3260 | static inline int __must_check | ||
| 3261 | i915_gem_object_pin_pages(struct drm_i915_gem_object *obj) | ||
| 3146 | { | 3262 | { |
| 3147 | if (n < obj->get_page.last) { | 3263 | might_lock(&obj->mm.lock); |
| 3148 | obj->get_page.sg = obj->pages->sgl; | ||
| 3149 | obj->get_page.last = 0; | ||
| 3150 | } | ||
| 3151 | 3264 | ||
| 3152 | while (obj->get_page.last + __sg_page_count(obj->get_page.sg) <= n) { | 3265 | if (atomic_inc_not_zero(&obj->mm.pages_pin_count)) |
| 3153 | obj->get_page.last += __sg_page_count(obj->get_page.sg++); | 3266 | return 0; |
| 3154 | if (unlikely(sg_is_chain(obj->get_page.sg))) | ||
| 3155 | obj->get_page.sg = sg_chain_ptr(obj->get_page.sg); | ||
| 3156 | } | ||
| 3157 | 3267 | ||
| 3158 | return sg_dma_address(obj->get_page.sg) + ((n - obj->get_page.last) << PAGE_SHIFT); | 3268 | return __i915_gem_object_get_pages(obj); |
| 3159 | } | 3269 | } |
| 3160 | 3270 | ||
| 3161 | static inline struct page * | 3271 | static inline void |
| 3162 | i915_gem_object_get_page(struct drm_i915_gem_object *obj, int n) | 3272 | __i915_gem_object_pin_pages(struct drm_i915_gem_object *obj) |
| 3163 | { | 3273 | { |
| 3164 | if (WARN_ON(n >= obj->base.size >> PAGE_SHIFT)) | 3274 | GEM_BUG_ON(!obj->mm.pages); |
| 3165 | return NULL; | ||
| 3166 | |||
| 3167 | if (n < obj->get_page.last) { | ||
| 3168 | obj->get_page.sg = obj->pages->sgl; | ||
| 3169 | obj->get_page.last = 0; | ||
| 3170 | } | ||
| 3171 | 3275 | ||
| 3172 | while (obj->get_page.last + __sg_page_count(obj->get_page.sg) <= n) { | 3276 | atomic_inc(&obj->mm.pages_pin_count); |
| 3173 | obj->get_page.last += __sg_page_count(obj->get_page.sg++); | 3277 | } |
| 3174 | if (unlikely(sg_is_chain(obj->get_page.sg))) | ||
| 3175 | obj->get_page.sg = sg_chain_ptr(obj->get_page.sg); | ||
| 3176 | } | ||
| 3177 | 3278 | ||
| 3178 | return nth_page(sg_page(obj->get_page.sg), n - obj->get_page.last); | 3279 | static inline bool |
| 3280 | i915_gem_object_has_pinned_pages(struct drm_i915_gem_object *obj) | ||
| 3281 | { | ||
| 3282 | return atomic_read(&obj->mm.pages_pin_count); | ||
| 3179 | } | 3283 | } |
| 3180 | 3284 | ||
| 3181 | static inline void i915_gem_object_pin_pages(struct drm_i915_gem_object *obj) | 3285 | static inline void |
| 3286 | __i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj) | ||
| 3182 | { | 3287 | { |
| 3183 | GEM_BUG_ON(obj->pages == NULL); | 3288 | GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); |
| 3184 | obj->pages_pin_count++; | 3289 | GEM_BUG_ON(!obj->mm.pages); |
| 3290 | |||
| 3291 | atomic_dec(&obj->mm.pages_pin_count); | ||
| 3292 | GEM_BUG_ON(atomic_read(&obj->mm.pages_pin_count) < obj->bind_count); | ||
| 3185 | } | 3293 | } |
| 3186 | 3294 | ||
| 3187 | static inline void i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj) | 3295 | static inline void |
| 3296 | i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj) | ||
| 3188 | { | 3297 | { |
| 3189 | GEM_BUG_ON(obj->pages_pin_count == 0); | 3298 | __i915_gem_object_unpin_pages(obj); |
| 3190 | obj->pages_pin_count--; | ||
| 3191 | GEM_BUG_ON(obj->pages_pin_count < obj->bind_count); | ||
| 3192 | } | 3299 | } |
| 3193 | 3300 | ||
| 3301 | enum i915_mm_subclass { /* lockdep subclass for obj->mm.lock */ | ||
| 3302 | I915_MM_NORMAL = 0, | ||
| 3303 | I915_MM_SHRINKER | ||
| 3304 | }; | ||
| 3305 | |||
| 3306 | void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj, | ||
| 3307 | enum i915_mm_subclass subclass); | ||
| 3308 | void __i915_gem_object_invalidate(struct drm_i915_gem_object *obj); | ||
| 3309 | |||
| 3194 | enum i915_map_type { | 3310 | enum i915_map_type { |
| 3195 | I915_MAP_WB = 0, | 3311 | I915_MAP_WB = 0, |
| 3196 | I915_MAP_WC, | 3312 | I915_MAP_WC, |
| @@ -3206,8 +3322,8 @@ enum i915_map_type { | |||
| 3206 | * the kernel address space. Based on the @type of mapping, the PTE will be | 3322 | * the kernel address space. Based on the @type of mapping, the PTE will be |
| 3207 | * set to either WriteBack or WriteCombine (via pgprot_t). | 3323 | * set to either WriteBack or WriteCombine (via pgprot_t). |
| 3208 | * | 3324 | * |
| 3209 | * The caller must hold the struct_mutex, and is responsible for calling | 3325 | * The caller is responsible for calling i915_gem_object_unpin_map() when the |
| 3210 | * i915_gem_object_unpin_map() when the mapping is no longer required. | 3326 | * mapping is no longer required. |
| 3211 | * | 3327 | * |
| 3212 | * Returns the pointer through which to access the mapped object, or an | 3328 | * Returns the pointer through which to access the mapped object, or an |
| 3213 | * ERR_PTR() on error. | 3329 | * ERR_PTR() on error. |
| @@ -3223,12 +3339,9 @@ void *__must_check i915_gem_object_pin_map(struct drm_i915_gem_object *obj, | |||
| 3223 | * with your access, call i915_gem_object_unpin_map() to release the pin | 3339 | * with your access, call i915_gem_object_unpin_map() to release the pin |
| 3224 | * upon the mapping. Once the pin count reaches zero, that mapping may be | 3340 | * upon the mapping. Once the pin count reaches zero, that mapping may be |
| 3225 | * removed. | 3341 | * removed. |
| 3226 | * | ||
| 3227 | * The caller must hold the struct_mutex. | ||
| 3228 | */ | 3342 | */ |
| 3229 | static inline void i915_gem_object_unpin_map(struct drm_i915_gem_object *obj) | 3343 | static inline void i915_gem_object_unpin_map(struct drm_i915_gem_object *obj) |
| 3230 | { | 3344 | { |
| 3231 | lockdep_assert_held(&obj->base.dev->struct_mutex); | ||
| 3232 | i915_gem_object_unpin_pages(obj); | 3345 | i915_gem_object_unpin_pages(obj); |
| 3233 | } | 3346 | } |
| 3234 | 3347 | ||
| @@ -3261,7 +3374,7 @@ void i915_gem_track_fb(struct drm_i915_gem_object *old, | |||
| 3261 | struct drm_i915_gem_object *new, | 3374 | struct drm_i915_gem_object *new, |
| 3262 | unsigned frontbuffer_bits); | 3375 | unsigned frontbuffer_bits); |
| 3263 | 3376 | ||
| 3264 | int __must_check i915_gem_set_seqno(struct drm_device *dev, u32 seqno); | 3377 | int __must_check i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno); |
| 3265 | 3378 | ||
| 3266 | struct drm_i915_gem_request * | 3379 | struct drm_i915_gem_request * |
| 3267 | i915_gem_find_active_request(struct intel_engine_cs *engine); | 3380 | i915_gem_find_active_request(struct intel_engine_cs *engine); |
| @@ -3300,9 +3413,10 @@ int __must_check i915_gem_wait_for_idle(struct drm_i915_private *dev_priv, | |||
| 3300 | int __must_check i915_gem_suspend(struct drm_device *dev); | 3413 | int __must_check i915_gem_suspend(struct drm_device *dev); |
| 3301 | void i915_gem_resume(struct drm_device *dev); | 3414 | void i915_gem_resume(struct drm_device *dev); |
| 3302 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); | 3415 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); |
| 3303 | int __must_check | 3416 | int i915_gem_object_wait(struct drm_i915_gem_object *obj, |
| 3304 | i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, | 3417 | unsigned int flags, |
| 3305 | bool readonly); | 3418 | long timeout, |
| 3419 | struct intel_rps_client *rps); | ||
| 3306 | int __must_check | 3420 | int __must_check |
| 3307 | i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, | 3421 | i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, |
| 3308 | bool write); | 3422 | bool write); |
| @@ -3384,6 +3498,7 @@ int __must_check i915_vma_put_fence(struct i915_vma *vma); | |||
| 3384 | static inline bool | 3498 | static inline bool |
| 3385 | i915_vma_pin_fence(struct i915_vma *vma) | 3499 | i915_vma_pin_fence(struct i915_vma *vma) |
| 3386 | { | 3500 | { |
| 3501 | lockdep_assert_held(&vma->vm->dev->struct_mutex); | ||
| 3387 | if (vma->fence) { | 3502 | if (vma->fence) { |
| 3388 | vma->fence->pin_count++; | 3503 | vma->fence->pin_count++; |
| 3389 | return true; | 3504 | return true; |
| @@ -3402,6 +3517,7 @@ i915_vma_pin_fence(struct i915_vma *vma) | |||
| 3402 | static inline void | 3517 | static inline void |
| 3403 | i915_vma_unpin_fence(struct i915_vma *vma) | 3518 | i915_vma_unpin_fence(struct i915_vma *vma) |
| 3404 | { | 3519 | { |
| 3520 | lockdep_assert_held(&vma->vm->dev->struct_mutex); | ||
| 3405 | if (vma->fence) { | 3521 | if (vma->fence) { |
| 3406 | GEM_BUG_ON(vma->fence->pin_count <= 0); | 3522 | GEM_BUG_ON(vma->fence->pin_count <= 0); |
| 3407 | vma->fence->pin_count--; | 3523 | vma->fence->pin_count--; |
| @@ -3411,8 +3527,10 @@ i915_vma_unpin_fence(struct i915_vma *vma) | |||
| 3411 | void i915_gem_restore_fences(struct drm_device *dev); | 3527 | void i915_gem_restore_fences(struct drm_device *dev); |
| 3412 | 3528 | ||
| 3413 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); | 3529 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); |
| 3414 | void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj); | 3530 | void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj, |
| 3415 | void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj); | 3531 | struct sg_table *pages); |
| 3532 | void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj, | ||
| 3533 | struct sg_table *pages); | ||
| 3416 | 3534 | ||
| 3417 | /* i915_gem_context.c */ | 3535 | /* i915_gem_context.c */ |
| 3418 | int __must_check i915_gem_context_init(struct drm_device *dev); | 3536 | int __must_check i915_gem_context_init(struct drm_device *dev); |
| @@ -3422,6 +3540,9 @@ int i915_gem_context_open(struct drm_device *dev, struct drm_file *file); | |||
| 3422 | void i915_gem_context_close(struct drm_device *dev, struct drm_file *file); | 3540 | void i915_gem_context_close(struct drm_device *dev, struct drm_file *file); |
| 3423 | int i915_switch_context(struct drm_i915_gem_request *req); | 3541 | int i915_switch_context(struct drm_i915_gem_request *req); |
| 3424 | int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv); | 3542 | int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv); |
| 3543 | struct i915_vma * | ||
| 3544 | i915_gem_context_pin_legacy(struct i915_gem_context *ctx, | ||
| 3545 | unsigned int flags); | ||
| 3425 | void i915_gem_context_free(struct kref *ctx_ref); | 3546 | void i915_gem_context_free(struct kref *ctx_ref); |
| 3426 | struct drm_i915_gem_object * | 3547 | struct drm_i915_gem_object * |
| 3427 | i915_gem_alloc_context_obj(struct drm_device *dev, size_t size); | 3548 | i915_gem_alloc_context_obj(struct drm_device *dev, size_t size); |
| @@ -3455,6 +3576,16 @@ static inline void i915_gem_context_put(struct i915_gem_context *ctx) | |||
| 3455 | kref_put(&ctx->ref, i915_gem_context_free); | 3576 | kref_put(&ctx->ref, i915_gem_context_free); |
| 3456 | } | 3577 | } |
| 3457 | 3578 | ||
| 3579 | static inline struct intel_timeline * | ||
| 3580 | i915_gem_context_lookup_timeline(struct i915_gem_context *ctx, | ||
| 3581 | struct intel_engine_cs *engine) | ||
| 3582 | { | ||
| 3583 | struct i915_address_space *vm; | ||
| 3584 | |||
| 3585 | vm = ctx->ppgtt ? &ctx->ppgtt->base : &ctx->i915->ggtt.base; | ||
| 3586 | return &vm->timeline.engine[engine->id]; | ||
| 3587 | } | ||
| 3588 | |||
| 3458 | static inline bool i915_gem_context_is_default(const struct i915_gem_context *c) | 3589 | static inline bool i915_gem_context_is_default(const struct i915_gem_context *c) |
| 3459 | { | 3590 | { |
| 3460 | return c->user_handle == DEFAULT_CONTEXT_HANDLE; | 3591 | return c->user_handle == DEFAULT_CONTEXT_HANDLE; |
| @@ -3508,6 +3639,11 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, | |||
| 3508 | u32 gtt_offset, | 3639 | u32 gtt_offset, |
| 3509 | u32 size); | 3640 | u32 size); |
| 3510 | 3641 | ||
| 3642 | /* i915_gem_internal.c */ | ||
| 3643 | struct drm_i915_gem_object * | ||
| 3644 | i915_gem_object_create_internal(struct drm_i915_private *dev_priv, | ||
| 3645 | unsigned int size); | ||
| 3646 | |||
| 3511 | /* i915_gem_shrinker.c */ | 3647 | /* i915_gem_shrinker.c */ |
| 3512 | unsigned long i915_gem_shrink(struct drm_i915_private *dev_priv, | 3648 | unsigned long i915_gem_shrink(struct drm_i915_private *dev_priv, |
| 3513 | unsigned long target, | 3649 | unsigned long target, |
| @@ -3690,7 +3826,7 @@ void intel_device_info_dump(struct drm_i915_private *dev_priv); | |||
| 3690 | 3826 | ||
| 3691 | /* modesetting */ | 3827 | /* modesetting */ |
| 3692 | extern void intel_modeset_init_hw(struct drm_device *dev); | 3828 | extern void intel_modeset_init_hw(struct drm_device *dev); |
| 3693 | extern void intel_modeset_init(struct drm_device *dev); | 3829 | extern int intel_modeset_init(struct drm_device *dev); |
| 3694 | extern void intel_modeset_gem_init(struct drm_device *dev); | 3830 | extern void intel_modeset_gem_init(struct drm_device *dev); |
| 3695 | extern void intel_modeset_cleanup(struct drm_device *dev); | 3831 | extern void intel_modeset_cleanup(struct drm_device *dev); |
| 3696 | extern int intel_connector_register(struct drm_connector *); | 3832 | extern int intel_connector_register(struct drm_connector *); |
| @@ -3745,6 +3881,23 @@ u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg); | |||
| 3745 | void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val); | 3881 | void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val); |
| 3746 | 3882 | ||
| 3747 | /* intel_dpio_phy.c */ | 3883 | /* intel_dpio_phy.c */ |
| 3884 | void bxt_port_to_phy_channel(enum port port, | ||
| 3885 | enum dpio_phy *phy, enum dpio_channel *ch); | ||
| 3886 | void bxt_ddi_phy_set_signal_level(struct drm_i915_private *dev_priv, | ||
| 3887 | enum port port, u32 margin, u32 scale, | ||
| 3888 | u32 enable, u32 deemphasis); | ||
| 3889 | void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy); | ||
| 3890 | void bxt_ddi_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy); | ||
| 3891 | bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv, | ||
| 3892 | enum dpio_phy phy); | ||
| 3893 | bool bxt_ddi_phy_verify_state(struct drm_i915_private *dev_priv, | ||
| 3894 | enum dpio_phy phy); | ||
| 3895 | uint8_t bxt_ddi_phy_calc_lane_lat_optim_mask(struct intel_encoder *encoder, | ||
| 3896 | uint8_t lane_count); | ||
| 3897 | void bxt_ddi_phy_set_lane_optim_mask(struct intel_encoder *encoder, | ||
| 3898 | uint8_t lane_lat_optim_mask); | ||
| 3899 | uint8_t bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder); | ||
| 3900 | |||
| 3748 | void chv_set_phy_signal_level(struct intel_encoder *encoder, | 3901 | void chv_set_phy_signal_level(struct intel_encoder *encoder, |
| 3749 | u32 deemph_reg_value, u32 margin_reg_value, | 3902 | u32 deemph_reg_value, u32 margin_reg_value, |
| 3750 | bool uniq_trans_scale); | 3903 | bool uniq_trans_scale); |
| @@ -3834,11 +3987,30 @@ __raw_write(64, q) | |||
| 3834 | #undef __raw_write | 3987 | #undef __raw_write |
| 3835 | 3988 | ||
| 3836 | /* These are untraced mmio-accessors that are only valid to be used inside | 3989 | /* These are untraced mmio-accessors that are only valid to be used inside |
| 3837 | * critical sections inside IRQ handlers where forcewake is explicitly | 3990 | * critical sections, such as inside IRQ handlers, where forcewake is explicitly |
| 3838 | * controlled. | 3991 | * controlled. |
| 3992 | * | ||
| 3839 | * Think twice, and think again, before using these. | 3993 | * Think twice, and think again, before using these. |
| 3840 | * Note: Should only be used between intel_uncore_forcewake_irqlock() and | 3994 | * |
| 3841 | * intel_uncore_forcewake_irqunlock(). | 3995 | * As an example, these accessors can possibly be used between: |
| 3996 | * | ||
| 3997 | * spin_lock_irq(&dev_priv->uncore.lock); | ||
| 3998 | * intel_uncore_forcewake_get__locked(); | ||
| 3999 | * | ||
| 4000 | * and | ||
| 4001 | * | ||
| 4002 | * intel_uncore_forcewake_put__locked(); | ||
| 4003 | * spin_unlock_irq(&dev_priv->uncore.lock); | ||
| 4004 | * | ||
| 4005 | * | ||
| 4006 | * Note: some registers may not need forcewake held, so | ||
| 4007 | * intel_uncore_forcewake_{get,put} can be omitted, see | ||
| 4008 | * intel_uncore_forcewake_for_reg(). | ||
| 4009 | * | ||
| 4010 | * Certain architectures will die if the same cacheline is concurrently accessed | ||
| 4011 | * by different clients (e.g. on Ivybridge). Access to registers should | ||
| 4012 | * therefore generally be serialised, by either the dev_priv->uncore.lock or | ||
| 4013 | * a more localised lock guarding all access to that bank of registers. | ||
| 3842 | */ | 4014 | */ |
| 3843 | #define I915_READ_FW(reg__) __raw_i915_read32(dev_priv, (reg__)) | 4015 | #define I915_READ_FW(reg__) __raw_i915_read32(dev_priv, (reg__)) |
| 3844 | #define I915_WRITE_FW(reg__, val__) __raw_i915_write32(dev_priv, (reg__), (val__)) | 4016 | #define I915_WRITE_FW(reg__, val__) __raw_i915_write32(dev_priv, (reg__), (val__)) |
| @@ -3915,7 +4087,7 @@ __i915_request_irq_complete(struct drm_i915_gem_request *req) | |||
| 3915 | /* Before we do the heavier coherent read of the seqno, | 4087 | /* Before we do the heavier coherent read of the seqno, |
| 3916 | * check the value (hopefully) in the CPU cacheline. | 4088 | * check the value (hopefully) in the CPU cacheline. |
| 3917 | */ | 4089 | */ |
| 3918 | if (i915_gem_request_completed(req)) | 4090 | if (__i915_gem_request_completed(req)) |
| 3919 | return true; | 4091 | return true; |
| 3920 | 4092 | ||
| 3921 | /* Ensure our read of the seqno is coherent so that we | 4093 | /* Ensure our read of the seqno is coherent so that we |
| @@ -3966,7 +4138,7 @@ __i915_request_irq_complete(struct drm_i915_gem_request *req) | |||
| 3966 | wake_up_process(tsk); | 4138 | wake_up_process(tsk); |
| 3967 | rcu_read_unlock(); | 4139 | rcu_read_unlock(); |
| 3968 | 4140 | ||
| 3969 | if (i915_gem_request_completed(req)) | 4141 | if (__i915_gem_request_completed(req)) |
| 3970 | return true; | 4142 | return true; |
| 3971 | } | 4143 | } |
| 3972 | 4144 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bf5e9064e02d..41e697e5dbcd 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -29,7 +29,6 @@ | |||
| 29 | #include <drm/drm_vma_manager.h> | 29 | #include <drm/drm_vma_manager.h> |
| 30 | #include <drm/i915_drm.h> | 30 | #include <drm/i915_drm.h> |
| 31 | #include "i915_drv.h" | 31 | #include "i915_drv.h" |
| 32 | #include "i915_gem_dmabuf.h" | ||
| 33 | #include "i915_vgpu.h" | 32 | #include "i915_vgpu.h" |
| 34 | #include "i915_trace.h" | 33 | #include "i915_trace.h" |
| 35 | #include "intel_drv.h" | 34 | #include "intel_drv.h" |
| @@ -42,6 +41,7 @@ | |||
| 42 | #include <linux/pci.h> | 41 | #include <linux/pci.h> |
| 43 | #include <linux/dma-buf.h> | 42 | #include <linux/dma-buf.h> |
| 44 | 43 | ||
| 44 | static void i915_gem_flush_free_objects(struct drm_i915_private *i915); | ||
| 45 | static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); | 45 | static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); |
| 46 | static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj); | 46 | static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj); |
| 47 | 47 | ||
| @@ -63,13 +63,13 @@ static bool cpu_write_needs_clflush(struct drm_i915_gem_object *obj) | |||
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | static int | 65 | static int |
| 66 | insert_mappable_node(struct drm_i915_private *i915, | 66 | insert_mappable_node(struct i915_ggtt *ggtt, |
| 67 | struct drm_mm_node *node, u32 size) | 67 | struct drm_mm_node *node, u32 size) |
| 68 | { | 68 | { |
| 69 | memset(node, 0, sizeof(*node)); | 69 | memset(node, 0, sizeof(*node)); |
| 70 | return drm_mm_insert_node_in_range_generic(&i915->ggtt.base.mm, node, | 70 | return drm_mm_insert_node_in_range_generic(&ggtt->base.mm, node, |
| 71 | size, 0, 0, 0, | 71 | size, 0, -1, |
| 72 | i915->ggtt.mappable_end, | 72 | 0, ggtt->mappable_end, |
| 73 | DRM_MM_SEARCH_DEFAULT, | 73 | DRM_MM_SEARCH_DEFAULT, |
| 74 | DRM_MM_CREATE_DEFAULT); | 74 | DRM_MM_CREATE_DEFAULT); |
| 75 | } | 75 | } |
| @@ -104,6 +104,8 @@ i915_gem_wait_for_error(struct i915_gpu_error *error) | |||
| 104 | { | 104 | { |
| 105 | int ret; | 105 | int ret; |
| 106 | 106 | ||
| 107 | might_sleep(); | ||
| 108 | |||
| 107 | if (!i915_reset_in_progress(error)) | 109 | if (!i915_reset_in_progress(error)) |
| 108 | return 0; | 110 | return 0; |
| 109 | 111 | ||
| @@ -114,7 +116,7 @@ i915_gem_wait_for_error(struct i915_gpu_error *error) | |||
| 114 | */ | 116 | */ |
| 115 | ret = wait_event_interruptible_timeout(error->reset_queue, | 117 | ret = wait_event_interruptible_timeout(error->reset_queue, |
| 116 | !i915_reset_in_progress(error), | 118 | !i915_reset_in_progress(error), |
| 117 | 10*HZ); | 119 | I915_RESET_TIMEOUT); |
| 118 | if (ret == 0) { | 120 | if (ret == 0) { |
| 119 | DRM_ERROR("Timed out waiting for the gpu reset to complete\n"); | 121 | DRM_ERROR("Timed out waiting for the gpu reset to complete\n"); |
| 120 | return -EIO; | 122 | return -EIO; |
| @@ -167,7 +169,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, | |||
| 167 | return 0; | 169 | return 0; |
| 168 | } | 170 | } |
| 169 | 171 | ||
| 170 | static int | 172 | static struct sg_table * |
| 171 | i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) | 173 | i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) |
| 172 | { | 174 | { |
| 173 | struct address_space *mapping = obj->base.filp->f_mapping; | 175 | struct address_space *mapping = obj->base.filp->f_mapping; |
| @@ -177,7 +179,7 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) | |||
| 177 | int i; | 179 | int i; |
| 178 | 180 | ||
| 179 | if (WARN_ON(i915_gem_object_needs_bit17_swizzle(obj))) | 181 | if (WARN_ON(i915_gem_object_needs_bit17_swizzle(obj))) |
| 180 | return -EINVAL; | 182 | return ERR_PTR(-EINVAL); |
| 181 | 183 | ||
| 182 | for (i = 0; i < obj->base.size / PAGE_SIZE; i++) { | 184 | for (i = 0; i < obj->base.size / PAGE_SIZE; i++) { |
| 183 | struct page *page; | 185 | struct page *page; |
| @@ -185,7 +187,7 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) | |||
| 185 | 187 | ||
| 186 | page = shmem_read_mapping_page(mapping, i); | 188 | page = shmem_read_mapping_page(mapping, i); |
| 187 | if (IS_ERR(page)) | 189 | if (IS_ERR(page)) |
| 188 | return PTR_ERR(page); | 190 | return ERR_CAST(page); |
| 189 | 191 | ||
| 190 | src = kmap_atomic(page); | 192 | src = kmap_atomic(page); |
| 191 | memcpy(vaddr, src, PAGE_SIZE); | 193 | memcpy(vaddr, src, PAGE_SIZE); |
| @@ -200,11 +202,11 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) | |||
| 200 | 202 | ||
| 201 | st = kmalloc(sizeof(*st), GFP_KERNEL); | 203 | st = kmalloc(sizeof(*st), GFP_KERNEL); |
| 202 | if (st == NULL) | 204 | if (st == NULL) |
| 203 | return -ENOMEM; | 205 | return ERR_PTR(-ENOMEM); |
| 204 | 206 | ||
| 205 | if (sg_alloc_table(st, 1, GFP_KERNEL)) { | 207 | if (sg_alloc_table(st, 1, GFP_KERNEL)) { |
| 206 | kfree(st); | 208 | kfree(st); |
| 207 | return -ENOMEM; | 209 | return ERR_PTR(-ENOMEM); |
| 208 | } | 210 | } |
| 209 | 211 | ||
| 210 | sg = st->sgl; | 212 | sg = st->sgl; |
| @@ -214,29 +216,31 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) | |||
| 214 | sg_dma_address(sg) = obj->phys_handle->busaddr; | 216 | sg_dma_address(sg) = obj->phys_handle->busaddr; |
| 215 | sg_dma_len(sg) = obj->base.size; | 217 | sg_dma_len(sg) = obj->base.size; |
| 216 | 218 | ||
| 217 | obj->pages = st; | 219 | return st; |
| 218 | return 0; | ||
| 219 | } | 220 | } |
| 220 | 221 | ||
| 221 | static void | 222 | static void |
| 222 | i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj) | 223 | __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj) |
| 223 | { | 224 | { |
| 224 | int ret; | 225 | GEM_BUG_ON(obj->mm.madv == __I915_MADV_PURGED); |
| 225 | 226 | ||
| 226 | BUG_ON(obj->madv == __I915_MADV_PURGED); | 227 | if (obj->mm.madv == I915_MADV_DONTNEED) |
| 228 | obj->mm.dirty = false; | ||
| 227 | 229 | ||
| 228 | ret = i915_gem_object_set_to_cpu_domain(obj, true); | 230 | if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) |
| 229 | if (WARN_ON(ret)) { | 231 | i915_gem_clflush_object(obj, false); |
| 230 | /* In the event of a disaster, abandon all caches and | ||
| 231 | * hope for the best. | ||
| 232 | */ | ||
| 233 | obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU; | ||
| 234 | } | ||
| 235 | 232 | ||
| 236 | if (obj->madv == I915_MADV_DONTNEED) | 233 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; |
| 237 | obj->dirty = 0; | 234 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; |
| 235 | } | ||
| 238 | 236 | ||
| 239 | if (obj->dirty) { | 237 | static void |
| 238 | i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj, | ||
| 239 | struct sg_table *pages) | ||
| 240 | { | ||
| 241 | __i915_gem_object_release_shmem(obj); | ||
| 242 | |||
| 243 | if (obj->mm.dirty) { | ||
| 240 | struct address_space *mapping = obj->base.filp->f_mapping; | 244 | struct address_space *mapping = obj->base.filp->f_mapping; |
| 241 | char *vaddr = obj->phys_handle->vaddr; | 245 | char *vaddr = obj->phys_handle->vaddr; |
| 242 | int i; | 246 | int i; |
| @@ -255,22 +259,23 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj) | |||
| 255 | kunmap_atomic(dst); | 259 | kunmap_atomic(dst); |
| 256 | 260 | ||
| 257 | set_page_dirty(page); | 261 | set_page_dirty(page); |
| 258 | if (obj->madv == I915_MADV_WILLNEED) | 262 | if (obj->mm.madv == I915_MADV_WILLNEED) |
| 259 | mark_page_accessed(page); | 263 | mark_page_accessed(page); |
| 260 | put_page(page); | 264 | put_page(page); |
| 261 | vaddr += PAGE_SIZE; | 265 | vaddr += PAGE_SIZE; |
| 262 | } | 266 | } |
| 263 | obj->dirty = 0; | 267 | obj->mm.dirty = false; |
| 264 | } | 268 | } |
| 265 | 269 | ||
| 266 | sg_free_table(obj->pages); | 270 | sg_free_table(pages); |
| 267 | kfree(obj->pages); | 271 | kfree(pages); |
| 268 | } | 272 | } |
| 269 | 273 | ||
| 270 | static void | 274 | static void |
| 271 | i915_gem_object_release_phys(struct drm_i915_gem_object *obj) | 275 | i915_gem_object_release_phys(struct drm_i915_gem_object *obj) |
| 272 | { | 276 | { |
| 273 | drm_pci_free(obj->base.dev, obj->phys_handle); | 277 | drm_pci_free(obj->base.dev, obj->phys_handle); |
| 278 | i915_gem_object_unpin_pages(obj); | ||
| 274 | } | 279 | } |
| 275 | 280 | ||
| 276 | static const struct drm_i915_gem_object_ops i915_gem_phys_ops = { | 281 | static const struct drm_i915_gem_object_ops i915_gem_phys_ops = { |
| @@ -292,7 +297,12 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj) | |||
| 292 | * must wait for all rendering to complete to the object (as unbinding | 297 | * must wait for all rendering to complete to the object (as unbinding |
| 293 | * must anyway), and retire the requests. | 298 | * must anyway), and retire the requests. |
| 294 | */ | 299 | */ |
| 295 | ret = i915_gem_object_wait_rendering(obj, false); | 300 | ret = i915_gem_object_wait(obj, |
| 301 | I915_WAIT_INTERRUPTIBLE | | ||
| 302 | I915_WAIT_LOCKED | | ||
| 303 | I915_WAIT_ALL, | ||
| 304 | MAX_SCHEDULE_TIMEOUT, | ||
| 305 | NULL); | ||
| 296 | if (ret) | 306 | if (ret) |
| 297 | return ret; | 307 | return ret; |
| 298 | 308 | ||
| @@ -311,88 +321,143 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj) | |||
| 311 | return ret; | 321 | return ret; |
| 312 | } | 322 | } |
| 313 | 323 | ||
| 314 | /** | 324 | static long |
| 315 | * Ensures that all rendering to the object has completed and the object is | 325 | i915_gem_object_wait_fence(struct dma_fence *fence, |
| 316 | * safe to unbind from the GTT or access from the CPU. | 326 | unsigned int flags, |
| 317 | * @obj: i915 gem object | 327 | long timeout, |
| 318 | * @readonly: waiting for just read access or read-write access | 328 | struct intel_rps_client *rps) |
| 319 | */ | ||
| 320 | int | ||
| 321 | i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, | ||
| 322 | bool readonly) | ||
| 323 | { | 329 | { |
| 324 | struct reservation_object *resv; | 330 | struct drm_i915_gem_request *rq; |
| 325 | struct i915_gem_active *active; | ||
| 326 | unsigned long active_mask; | ||
| 327 | int idx; | ||
| 328 | 331 | ||
| 329 | lockdep_assert_held(&obj->base.dev->struct_mutex); | 332 | BUILD_BUG_ON(I915_WAIT_INTERRUPTIBLE != 0x1); |
| 330 | 333 | ||
| 331 | if (!readonly) { | 334 | if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) |
| 332 | active = obj->last_read; | 335 | return timeout; |
| 333 | active_mask = i915_gem_object_get_active(obj); | ||
| 334 | } else { | ||
| 335 | active_mask = 1; | ||
| 336 | active = &obj->last_write; | ||
| 337 | } | ||
| 338 | 336 | ||
| 339 | for_each_active(active_mask, idx) { | 337 | if (!dma_fence_is_i915(fence)) |
| 340 | int ret; | 338 | return dma_fence_wait_timeout(fence, |
| 339 | flags & I915_WAIT_INTERRUPTIBLE, | ||
| 340 | timeout); | ||
| 341 | 341 | ||
| 342 | ret = i915_gem_active_wait(&active[idx], | 342 | rq = to_request(fence); |
| 343 | &obj->base.dev->struct_mutex); | 343 | if (i915_gem_request_completed(rq)) |
| 344 | if (ret) | 344 | goto out; |
| 345 | return ret; | 345 | |
| 346 | /* This client is about to stall waiting for the GPU. In many cases | ||
| 347 | * this is undesirable and limits the throughput of the system, as | ||
| 348 | * many clients cannot continue processing user input/output whilst | ||
| 349 | * blocked. RPS autotuning may take tens of milliseconds to respond | ||
| 350 | * to the GPU load and thus incurs additional latency for the client. | ||
| 351 | * We can circumvent that by promoting the GPU frequency to maximum | ||
| 352 | * before we wait. This makes the GPU throttle up much more quickly | ||
| 353 | * (good for benchmarks and user experience, e.g. window animations), | ||
| 354 | * but at a cost of spending more power processing the workload | ||
| 355 | * (bad for battery). Not all clients even want their results | ||
| 356 | * immediately and for them we should just let the GPU select its own | ||
| 357 | * frequency to maximise efficiency. To prevent a single client from | ||
| 358 | * forcing the clocks too high for the whole system, we only allow | ||
| 359 | * each client to waitboost once in a busy period. | ||
| 360 | */ | ||
| 361 | if (rps) { | ||
| 362 | if (INTEL_GEN(rq->i915) >= 6) | ||
| 363 | gen6_rps_boost(rq->i915, rps, rq->emitted_jiffies); | ||
| 364 | else | ||
| 365 | rps = NULL; | ||
| 346 | } | 366 | } |
| 347 | 367 | ||
| 348 | resv = i915_gem_object_get_dmabuf_resv(obj); | 368 | timeout = i915_wait_request(rq, flags, timeout); |
| 349 | if (resv) { | ||
| 350 | long err; | ||
| 351 | 369 | ||
| 352 | err = reservation_object_wait_timeout_rcu(resv, !readonly, true, | 370 | out: |
| 353 | MAX_SCHEDULE_TIMEOUT); | 371 | if (flags & I915_WAIT_LOCKED && i915_gem_request_completed(rq)) |
| 354 | if (err < 0) | 372 | i915_gem_request_retire_upto(rq); |
| 355 | return err; | 373 | |
| 374 | if (rps && rq->global_seqno == intel_engine_last_submit(rq->engine)) { | ||
| 375 | /* The GPU is now idle and this client has stalled. | ||
| 376 | * Since no other client has submitted a request in the | ||
| 377 | * meantime, assume that this client is the only one | ||
| 378 | * supplying work to the GPU but is unable to keep that | ||
| 379 | * work supplied because it is waiting. Since the GPU is | ||
| 380 | * then never kept fully busy, RPS autoclocking will | ||
| 381 | * keep the clocks relatively low, causing further delays. | ||
| 382 | * Compensate by giving the synchronous client credit for | ||
| 383 | * a waitboost next time. | ||
| 384 | */ | ||
| 385 | spin_lock(&rq->i915->rps.client_lock); | ||
| 386 | list_del_init(&rps->link); | ||
| 387 | spin_unlock(&rq->i915->rps.client_lock); | ||
| 356 | } | 388 | } |
| 357 | 389 | ||
| 358 | return 0; | 390 | return timeout; |
| 359 | } | 391 | } |
| 360 | 392 | ||
| 361 | /* A nonblocking variant of the above wait. Must be called prior to | 393 | static long |
| 362 | * acquiring the mutex for the object, as the object state may change | 394 | i915_gem_object_wait_reservation(struct reservation_object *resv, |
| 363 | * during this call. A reference must be held by the caller for the object. | 395 | unsigned int flags, |
| 364 | */ | 396 | long timeout, |
| 365 | static __must_check int | 397 | struct intel_rps_client *rps) |
| 366 | __unsafe_wait_rendering(struct drm_i915_gem_object *obj, | ||
| 367 | struct intel_rps_client *rps, | ||
| 368 | bool readonly) | ||
| 369 | { | 398 | { |
| 370 | struct i915_gem_active *active; | 399 | struct dma_fence *excl; |
| 371 | unsigned long active_mask; | ||
| 372 | int idx; | ||
| 373 | 400 | ||
| 374 | active_mask = __I915_BO_ACTIVE(obj); | 401 | if (flags & I915_WAIT_ALL) { |
| 375 | if (!active_mask) | 402 | struct dma_fence **shared; |
| 376 | return 0; | 403 | unsigned int count, i; |
| 377 | |||
| 378 | if (!readonly) { | ||
| 379 | active = obj->last_read; | ||
| 380 | } else { | ||
| 381 | active_mask = 1; | ||
| 382 | active = &obj->last_write; | ||
| 383 | } | ||
| 384 | |||
| 385 | for_each_active(active_mask, idx) { | ||
| 386 | int ret; | 404 | int ret; |
| 387 | 405 | ||
| 388 | ret = i915_gem_active_wait_unlocked(&active[idx], | 406 | ret = reservation_object_get_fences_rcu(resv, |
| 389 | I915_WAIT_INTERRUPTIBLE, | 407 | &excl, &count, &shared); |
| 390 | NULL, rps); | ||
| 391 | if (ret) | 408 | if (ret) |
| 392 | return ret; | 409 | return ret; |
| 410 | |||
| 411 | for (i = 0; i < count; i++) { | ||
| 412 | timeout = i915_gem_object_wait_fence(shared[i], | ||
| 413 | flags, timeout, | ||
| 414 | rps); | ||
| 415 | if (timeout <= 0) | ||
| 416 | break; | ||
| 417 | |||
| 418 | dma_fence_put(shared[i]); | ||
| 419 | } | ||
| 420 | |||
| 421 | for (; i < count; i++) | ||
| 422 | dma_fence_put(shared[i]); | ||
| 423 | kfree(shared); | ||
| 424 | } else { | ||
| 425 | excl = reservation_object_get_excl_rcu(resv); | ||
| 393 | } | 426 | } |
| 394 | 427 | ||
| 395 | return 0; | 428 | if (excl && timeout > 0) |
| 429 | timeout = i915_gem_object_wait_fence(excl, flags, timeout, rps); | ||
| 430 | |||
| 431 | dma_fence_put(excl); | ||
| 432 | |||
| 433 | return timeout; | ||
| 434 | } | ||
| 435 | |||
| 436 | /** | ||
| 437 | * Waits for rendering to the object to be completed | ||
| 438 | * @obj: i915 gem object | ||
| 439 | * @flags: how to wait (under a lock, for all rendering or just for writes etc) | ||
| 440 | * @timeout: how long to wait | ||
| 441 | * @rps: client (user process) to charge for any waitboosting | ||
| 442 | */ | ||
| 443 | int | ||
| 444 | i915_gem_object_wait(struct drm_i915_gem_object *obj, | ||
| 445 | unsigned int flags, | ||
| 446 | long timeout, | ||
| 447 | struct intel_rps_client *rps) | ||
| 448 | { | ||
| 449 | might_sleep(); | ||
| 450 | #if IS_ENABLED(CONFIG_LOCKDEP) | ||
| 451 | GEM_BUG_ON(debug_locks && | ||
| 452 | !!lockdep_is_held(&obj->base.dev->struct_mutex) != | ||
| 453 | !!(flags & I915_WAIT_LOCKED)); | ||
| 454 | #endif | ||
| 455 | GEM_BUG_ON(timeout < 0); | ||
| 456 | |||
| 457 | timeout = i915_gem_object_wait_reservation(obj->resv, | ||
| 458 | flags, timeout, | ||
| 459 | rps); | ||
| 460 | return timeout < 0 ? timeout : 0; | ||
| 396 | } | 461 | } |
| 397 | 462 | ||
| 398 | static struct intel_rps_client *to_rps_client(struct drm_file *file) | 463 | static struct intel_rps_client *to_rps_client(struct drm_file *file) |
| @@ -416,7 +481,7 @@ i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, | |||
| 416 | return 0; | 481 | return 0; |
| 417 | } | 482 | } |
| 418 | 483 | ||
| 419 | if (obj->madv != I915_MADV_WILLNEED) | 484 | if (obj->mm.madv != I915_MADV_WILLNEED) |
| 420 | return -EFAULT; | 485 | return -EFAULT; |
| 421 | 486 | ||
| 422 | if (obj->base.filp == NULL) | 487 | if (obj->base.filp == NULL) |
| @@ -426,9 +491,9 @@ i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, | |||
| 426 | if (ret) | 491 | if (ret) |
| 427 | return ret; | 492 | return ret; |
| 428 | 493 | ||
| 429 | ret = i915_gem_object_put_pages(obj); | 494 | __i915_gem_object_put_pages(obj, I915_MM_NORMAL); |
| 430 | if (ret) | 495 | if (obj->mm.pages) |
| 431 | return ret; | 496 | return -EBUSY; |
| 432 | 497 | ||
| 433 | /* create a new object */ | 498 | /* create a new object */ |
| 434 | phys = drm_pci_alloc(obj->base.dev, obj->base.size, align); | 499 | phys = drm_pci_alloc(obj->base.dev, obj->base.size, align); |
| @@ -438,23 +503,29 @@ i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, | |||
| 438 | obj->phys_handle = phys; | 503 | obj->phys_handle = phys; |
| 439 | obj->ops = &i915_gem_phys_ops; | 504 | obj->ops = &i915_gem_phys_ops; |
| 440 | 505 | ||
| 441 | return i915_gem_object_get_pages(obj); | 506 | return i915_gem_object_pin_pages(obj); |
| 442 | } | 507 | } |
| 443 | 508 | ||
| 444 | static int | 509 | static int |
| 445 | i915_gem_phys_pwrite(struct drm_i915_gem_object *obj, | 510 | i915_gem_phys_pwrite(struct drm_i915_gem_object *obj, |
| 446 | struct drm_i915_gem_pwrite *args, | 511 | struct drm_i915_gem_pwrite *args, |
| 447 | struct drm_file *file_priv) | 512 | struct drm_file *file) |
| 448 | { | 513 | { |
| 449 | struct drm_device *dev = obj->base.dev; | 514 | struct drm_device *dev = obj->base.dev; |
| 450 | void *vaddr = obj->phys_handle->vaddr + args->offset; | 515 | void *vaddr = obj->phys_handle->vaddr + args->offset; |
| 451 | char __user *user_data = u64_to_user_ptr(args->data_ptr); | 516 | char __user *user_data = u64_to_user_ptr(args->data_ptr); |
| 452 | int ret = 0; | 517 | int ret; |
| 453 | 518 | ||
| 454 | /* We manually control the domain here and pretend that it | 519 | /* We manually control the domain here and pretend that it |
| 455 | * remains coherent i.e. in the GTT domain, like shmem_pwrite. | 520 | * remains coherent i.e. in the GTT domain, like shmem_pwrite. |
| 456 | */ | 521 | */ |
| 457 | ret = i915_gem_object_wait_rendering(obj, false); | 522 | lockdep_assert_held(&obj->base.dev->struct_mutex); |
| 523 | ret = i915_gem_object_wait(obj, | ||
| 524 | I915_WAIT_INTERRUPTIBLE | | ||
| 525 | I915_WAIT_LOCKED | | ||
| 526 | I915_WAIT_ALL, | ||
| 527 | MAX_SCHEDULE_TIMEOUT, | ||
| 528 | to_rps_client(file)); | ||
| 458 | if (ret) | 529 | if (ret) |
| 459 | return ret; | 530 | return ret; |
| 460 | 531 | ||
| @@ -516,7 +587,7 @@ i915_gem_create(struct drm_file *file, | |||
| 516 | 587 | ||
| 517 | ret = drm_gem_handle_create(file, &obj->base, &handle); | 588 | ret = drm_gem_handle_create(file, &obj->base, &handle); |
| 518 | /* drop reference from allocate - handle holds it now */ | 589 | /* drop reference from allocate - handle holds it now */ |
| 519 | i915_gem_object_put_unlocked(obj); | 590 | i915_gem_object_put(obj); |
| 520 | if (ret) | 591 | if (ret) |
| 521 | return ret; | 592 | return ret; |
| 522 | 593 | ||
| @@ -548,6 +619,8 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, | |||
| 548 | { | 619 | { |
| 549 | struct drm_i915_gem_create *args = data; | 620 | struct drm_i915_gem_create *args = data; |
| 550 | 621 | ||
| 622 | i915_gem_flush_free_objects(to_i915(dev)); | ||
| 623 | |||
| 551 | return i915_gem_create(file, dev, | 624 | return i915_gem_create(file, dev, |
| 552 | args->size, &args->handle); | 625 | args->size, &args->handle); |
| 553 | } | 626 | } |
| @@ -614,21 +687,24 @@ int i915_gem_obj_prepare_shmem_read(struct drm_i915_gem_object *obj, | |||
| 614 | { | 687 | { |
| 615 | int ret; | 688 | int ret; |
| 616 | 689 | ||
| 617 | *needs_clflush = 0; | 690 | lockdep_assert_held(&obj->base.dev->struct_mutex); |
| 618 | 691 | ||
| 692 | *needs_clflush = 0; | ||
| 619 | if (!i915_gem_object_has_struct_page(obj)) | 693 | if (!i915_gem_object_has_struct_page(obj)) |
| 620 | return -ENODEV; | 694 | return -ENODEV; |
| 621 | 695 | ||
| 622 | ret = i915_gem_object_wait_rendering(obj, true); | 696 | ret = i915_gem_object_wait(obj, |
| 697 | I915_WAIT_INTERRUPTIBLE | | ||
| 698 | I915_WAIT_LOCKED, | ||
| 699 | MAX_SCHEDULE_TIMEOUT, | ||
| 700 | NULL); | ||
| 623 | if (ret) | 701 | if (ret) |
| 624 | return ret; | 702 | return ret; |
| 625 | 703 | ||
| 626 | ret = i915_gem_object_get_pages(obj); | 704 | ret = i915_gem_object_pin_pages(obj); |
| 627 | if (ret) | 705 | if (ret) |
| 628 | return ret; | 706 | return ret; |
| 629 | 707 | ||
| 630 | i915_gem_object_pin_pages(obj); | ||
| 631 | |||
| 632 | i915_gem_object_flush_gtt_write_domain(obj); | 708 | i915_gem_object_flush_gtt_write_domain(obj); |
| 633 | 709 | ||
| 634 | /* If we're not in the cpu read domain, set ourself into the gtt | 710 | /* If we're not in the cpu read domain, set ourself into the gtt |
| @@ -661,20 +737,25 @@ int i915_gem_obj_prepare_shmem_write(struct drm_i915_gem_object *obj, | |||
| 661 | { | 737 | { |
| 662 | int ret; | 738 | int ret; |
| 663 | 739 | ||
| 740 | lockdep_assert_held(&obj->base.dev->struct_mutex); | ||
| 741 | |||
| 664 | *needs_clflush = 0; | 742 | *needs_clflush = 0; |
| 665 | if (!i915_gem_object_has_struct_page(obj)) | 743 | if (!i915_gem_object_has_struct_page(obj)) |
| 666 | return -ENODEV; | 744 | return -ENODEV; |
| 667 | 745 | ||
| 668 | ret = i915_gem_object_wait_rendering(obj, false); | 746 | ret = i915_gem_object_wait(obj, |
| 747 | I915_WAIT_INTERRUPTIBLE | | ||
| 748 | I915_WAIT_LOCKED | | ||
| 749 | I915_WAIT_ALL, | ||
| 750 | MAX_SCHEDULE_TIMEOUT, | ||
| 751 | NULL); | ||
| 669 | if (ret) | 752 | if (ret) |
| 670 | return ret; | 753 | return ret; |
| 671 | 754 | ||
| 672 | ret = i915_gem_object_get_pages(obj); | 755 | ret = i915_gem_object_pin_pages(obj); |
| 673 | if (ret) | 756 | if (ret) |
| 674 | return ret; | 757 | return ret; |
| 675 | 758 | ||
| 676 | i915_gem_object_pin_pages(obj); | ||
| 677 | |||
| 678 | i915_gem_object_flush_gtt_write_domain(obj); | 759 | i915_gem_object_flush_gtt_write_domain(obj); |
| 679 | 760 | ||
| 680 | /* If we're not in the cpu write domain, set ourself into the | 761 | /* If we're not in the cpu write domain, set ourself into the |
| @@ -704,7 +785,7 @@ int i915_gem_obj_prepare_shmem_write(struct drm_i915_gem_object *obj, | |||
| 704 | obj->cache_dirty = true; | 785 | obj->cache_dirty = true; |
| 705 | 786 | ||
| 706 | intel_fb_obj_invalidate(obj, ORIGIN_CPU); | 787 | intel_fb_obj_invalidate(obj, ORIGIN_CPU); |
| 707 | obj->dirty = 1; | 788 | obj->mm.dirty = true; |
| 708 | /* return with the pages pinned */ | 789 | /* return with the pages pinned */ |
| 709 | return 0; | 790 | return 0; |
| 710 | 791 | ||
| @@ -713,32 +794,6 @@ err_unpin: | |||
| 713 | return ret; | 794 | return ret; |
| 714 | } | 795 | } |
| 715 | 796 | ||
| 716 | /* Per-page copy function for the shmem pread fastpath. | ||
| 717 | * Flushes invalid cachelines before reading the target if | ||
| 718 | * needs_clflush is set. */ | ||
| 719 | static int | ||
| 720 | shmem_pread_fast(struct page *page, int shmem_page_offset, int page_length, | ||
| 721 | char __user *user_data, | ||
| 722 | bool page_do_bit17_swizzling, bool needs_clflush) | ||
| 723 | { | ||
| 724 | char *vaddr; | ||
| 725 | int ret; | ||
| 726 | |||
| 727 | if (unlikely(page_do_bit17_swizzling)) | ||
| 728 | return -EINVAL; | ||
| 729 | |||
| 730 | vaddr = kmap_atomic(page); | ||
| 731 | if (needs_clflush) | ||
| 732 | drm_clflush_virt_range(vaddr + shmem_page_offset, | ||
| 733 | page_length); | ||
| 734 | ret = __copy_to_user_inatomic(user_data, | ||
| 735 | vaddr + shmem_page_offset, | ||
| 736 | page_length); | ||
| 737 | kunmap_atomic(vaddr); | ||
| 738 | |||
| 739 | return ret ? -EFAULT : 0; | ||
| 740 | } | ||
| 741 | |||
| 742 | static void | 797 | static void |
| 743 | shmem_clflush_swizzled_range(char *addr, unsigned long length, | 798 | shmem_clflush_swizzled_range(char *addr, unsigned long length, |
| 744 | bool swizzled) | 799 | bool swizzled) |
| @@ -764,7 +819,7 @@ shmem_clflush_swizzled_range(char *addr, unsigned long length, | |||
| 764 | /* Only difference to the fast-path function is that this can handle bit17 | 819 | /* Only difference to the fast-path function is that this can handle bit17 |
| 765 | * and uses non-atomic copy and kmap functions. */ | 820 | * and uses non-atomic copy and kmap functions. */ |
| 766 | static int | 821 | static int |
| 767 | shmem_pread_slow(struct page *page, int shmem_page_offset, int page_length, | 822 | shmem_pread_slow(struct page *page, int offset, int length, |
| 768 | char __user *user_data, | 823 | char __user *user_data, |
| 769 | bool page_do_bit17_swizzling, bool needs_clflush) | 824 | bool page_do_bit17_swizzling, bool needs_clflush) |
| 770 | { | 825 | { |
| @@ -773,60 +828,130 @@ shmem_pread_slow(struct page *page, int shmem_page_offset, int page_length, | |||
| 773 | 828 | ||
| 774 | vaddr = kmap(page); | 829 | vaddr = kmap(page); |
| 775 | if (needs_clflush) | 830 | if (needs_clflush) |
| 776 | shmem_clflush_swizzled_range(vaddr + shmem_page_offset, | 831 | shmem_clflush_swizzled_range(vaddr + offset, length, |
| 777 | page_length, | ||
| 778 | page_do_bit17_swizzling); | 832 | page_do_bit17_swizzling); |
| 779 | 833 | ||
| 780 | if (page_do_bit17_swizzling) | 834 | if (page_do_bit17_swizzling) |
| 781 | ret = __copy_to_user_swizzled(user_data, | 835 | ret = __copy_to_user_swizzled(user_data, vaddr, offset, length); |
| 782 | vaddr, shmem_page_offset, | ||
| 783 | page_length); | ||
| 784 | else | 836 | else |
| 785 | ret = __copy_to_user(user_data, | 837 | ret = __copy_to_user(user_data, vaddr + offset, length); |
| 786 | vaddr + shmem_page_offset, | ||
| 787 | page_length); | ||
| 788 | kunmap(page); | 838 | kunmap(page); |
| 789 | 839 | ||
| 790 | return ret ? - EFAULT : 0; | 840 | return ret ? - EFAULT : 0; |
| 791 | } | 841 | } |
| 792 | 842 | ||
| 793 | static inline unsigned long | 843 | static int |
| 794 | slow_user_access(struct io_mapping *mapping, | 844 | shmem_pread(struct page *page, int offset, int length, char __user *user_data, |
| 795 | uint64_t page_base, int page_offset, | 845 | bool page_do_bit17_swizzling, bool needs_clflush) |
| 796 | char __user *user_data, | 846 | { |
| 797 | unsigned long length, bool pwrite) | 847 | int ret; |
| 848 | |||
| 849 | ret = -ENODEV; | ||
| 850 | if (!page_do_bit17_swizzling) { | ||
| 851 | char *vaddr = kmap_atomic(page); | ||
| 852 | |||
| 853 | if (needs_clflush) | ||
| 854 | drm_clflush_virt_range(vaddr + offset, length); | ||
| 855 | ret = __copy_to_user_inatomic(user_data, vaddr + offset, length); | ||
| 856 | kunmap_atomic(vaddr); | ||
| 857 | } | ||
| 858 | if (ret == 0) | ||
| 859 | return 0; | ||
| 860 | |||
| 861 | return shmem_pread_slow(page, offset, length, user_data, | ||
| 862 | page_do_bit17_swizzling, needs_clflush); | ||
| 863 | } | ||
| 864 | |||
| 865 | static int | ||
| 866 | i915_gem_shmem_pread(struct drm_i915_gem_object *obj, | ||
| 867 | struct drm_i915_gem_pread *args) | ||
| 868 | { | ||
| 869 | char __user *user_data; | ||
| 870 | u64 remain; | ||
| 871 | unsigned int obj_do_bit17_swizzling; | ||
| 872 | unsigned int needs_clflush; | ||
| 873 | unsigned int idx, offset; | ||
| 874 | int ret; | ||
| 875 | |||
| 876 | obj_do_bit17_swizzling = 0; | ||
| 877 | if (i915_gem_object_needs_bit17_swizzle(obj)) | ||
| 878 | obj_do_bit17_swizzling = BIT(17); | ||
| 879 | |||
| 880 | ret = mutex_lock_interruptible(&obj->base.dev->struct_mutex); | ||
| 881 | if (ret) | ||
| 882 | return ret; | ||
| 883 | |||
| 884 | ret = i915_gem_obj_prepare_shmem_read(obj, &needs_clflush); | ||
| 885 | mutex_unlock(&obj->base.dev->struct_mutex); | ||
| 886 | if (ret) | ||
| 887 | return ret; | ||
| 888 | |||
| 889 | remain = args->size; | ||
| 890 | user_data = u64_to_user_ptr(args->data_ptr); | ||
| 891 | offset = offset_in_page(args->offset); | ||
| 892 | for (idx = args->offset >> PAGE_SHIFT; remain; idx++) { | ||
| 893 | struct page *page = i915_gem_object_get_page(obj, idx); | ||
| 894 | int length; | ||
| 895 | |||
| 896 | length = remain; | ||
| 897 | if (offset + length > PAGE_SIZE) | ||
| 898 | length = PAGE_SIZE - offset; | ||
| 899 | |||
| 900 | ret = shmem_pread(page, offset, length, user_data, | ||
| 901 | page_to_phys(page) & obj_do_bit17_swizzling, | ||
| 902 | needs_clflush); | ||
| 903 | if (ret) | ||
| 904 | break; | ||
| 905 | |||
| 906 | remain -= length; | ||
| 907 | user_data += length; | ||
| 908 | offset = 0; | ||
| 909 | } | ||
| 910 | |||
| 911 | i915_gem_obj_finish_shmem_access(obj); | ||
| 912 | return ret; | ||
| 913 | } | ||
| 914 | |||
| 915 | static inline bool | ||
| 916 | gtt_user_read(struct io_mapping *mapping, | ||
| 917 | loff_t base, int offset, | ||
| 918 | char __user *user_data, int length) | ||
| 798 | { | 919 | { |
| 799 | void __iomem *ioaddr; | ||
| 800 | void *vaddr; | 920 | void *vaddr; |
| 801 | uint64_t unwritten; | 921 | unsigned long unwritten; |
| 802 | 922 | ||
| 803 | ioaddr = io_mapping_map_wc(mapping, page_base, PAGE_SIZE); | ||
| 804 | /* We can use the cpu mem copy function because this is X86. */ | 923 | /* We can use the cpu mem copy function because this is X86. */ |
| 805 | vaddr = (void __force *)ioaddr + page_offset; | 924 | vaddr = (void __force *)io_mapping_map_atomic_wc(mapping, base); |
| 806 | if (pwrite) | 925 | unwritten = __copy_to_user_inatomic(user_data, vaddr + offset, length); |
| 807 | unwritten = __copy_from_user(vaddr, user_data, length); | 926 | io_mapping_unmap_atomic(vaddr); |
| 808 | else | 927 | if (unwritten) { |
| 809 | unwritten = __copy_to_user(user_data, vaddr, length); | 928 | vaddr = (void __force *) |
| 810 | 929 | io_mapping_map_wc(mapping, base, PAGE_SIZE); | |
| 811 | io_mapping_unmap(ioaddr); | 930 | unwritten = copy_to_user(user_data, vaddr + offset, length); |
| 931 | io_mapping_unmap(vaddr); | ||
| 932 | } | ||
| 812 | return unwritten; | 933 | return unwritten; |
| 813 | } | 934 | } |
| 814 | 935 | ||
| 815 | static int | 936 | static int |
| 816 | i915_gem_gtt_pread(struct drm_device *dev, | 937 | i915_gem_gtt_pread(struct drm_i915_gem_object *obj, |
| 817 | struct drm_i915_gem_object *obj, uint64_t size, | 938 | const struct drm_i915_gem_pread *args) |
| 818 | uint64_t data_offset, uint64_t data_ptr) | ||
| 819 | { | 939 | { |
| 820 | struct drm_i915_private *dev_priv = to_i915(dev); | 940 | struct drm_i915_private *i915 = to_i915(obj->base.dev); |
| 821 | struct i915_ggtt *ggtt = &dev_priv->ggtt; | 941 | struct i915_ggtt *ggtt = &i915->ggtt; |
| 822 | struct i915_vma *vma; | ||
| 823 | struct drm_mm_node node; | 942 | struct drm_mm_node node; |
| 824 | char __user *user_data; | 943 | struct i915_vma *vma; |
| 825 | uint64_t remain; | 944 | void __user *user_data; |
| 826 | uint64_t offset; | 945 | u64 remain, offset; |
| 827 | int ret; | 946 | int ret; |
| 828 | 947 | ||
| 829 | vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE); | 948 | ret = mutex_lock_interruptible(&i915->drm.struct_mutex); |
| 949 | if (ret) | ||
| 950 | return ret; | ||
| 951 | |||
| 952 | intel_runtime_pm_get(i915); | ||
| 953 | vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, | ||
| 954 | PIN_MAPPABLE | PIN_NONBLOCK); | ||
| 830 | if (!IS_ERR(vma)) { | 955 | if (!IS_ERR(vma)) { |
| 831 | node.start = i915_ggtt_offset(vma); | 956 | node.start = i915_ggtt_offset(vma); |
| 832 | node.allocated = false; | 957 | node.allocated = false; |
| @@ -837,35 +962,21 @@ i915_gem_gtt_pread(struct drm_device *dev, | |||
| 837 | } | 962 | } |
| 838 | } | 963 | } |
| 839 | if (IS_ERR(vma)) { | 964 | if (IS_ERR(vma)) { |
| 840 | ret = insert_mappable_node(dev_priv, &node, PAGE_SIZE); | 965 | ret = insert_mappable_node(ggtt, &node, PAGE_SIZE); |
| 841 | if (ret) | 966 | if (ret) |
| 842 | goto out; | 967 | goto out_unlock; |
| 843 | 968 | GEM_BUG_ON(!node.allocated); | |
| 844 | ret = i915_gem_object_get_pages(obj); | ||
| 845 | if (ret) { | ||
| 846 | remove_mappable_node(&node); | ||
| 847 | goto out; | ||
| 848 | } | ||
| 849 | |||
| 850 | i915_gem_object_pin_pages(obj); | ||
| 851 | } | 969 | } |
| 852 | 970 | ||
| 853 | ret = i915_gem_object_set_to_gtt_domain(obj, false); | 971 | ret = i915_gem_object_set_to_gtt_domain(obj, false); |
| 854 | if (ret) | 972 | if (ret) |
| 855 | goto out_unpin; | 973 | goto out_unpin; |
| 856 | 974 | ||
| 857 | user_data = u64_to_user_ptr(data_ptr); | 975 | mutex_unlock(&i915->drm.struct_mutex); |
| 858 | remain = size; | ||
| 859 | offset = data_offset; | ||
| 860 | 976 | ||
| 861 | mutex_unlock(&dev->struct_mutex); | 977 | user_data = u64_to_user_ptr(args->data_ptr); |
| 862 | if (likely(!i915.prefault_disable)) { | 978 | remain = args->size; |
| 863 | ret = fault_in_pages_writeable(user_data, remain); | 979 | offset = args->offset; |
| 864 | if (ret) { | ||
| 865 | mutex_lock(&dev->struct_mutex); | ||
| 866 | goto out_unpin; | ||
| 867 | } | ||
| 868 | } | ||
| 869 | 980 | ||
| 870 | while (remain > 0) { | 981 | while (remain > 0) { |
| 871 | /* Operation in this page | 982 | /* Operation in this page |
| @@ -882,19 +993,14 @@ i915_gem_gtt_pread(struct drm_device *dev, | |||
| 882 | wmb(); | 993 | wmb(); |
| 883 | ggtt->base.insert_page(&ggtt->base, | 994 | ggtt->base.insert_page(&ggtt->base, |
| 884 | i915_gem_object_get_dma_address(obj, offset >> PAGE_SHIFT), | 995 | i915_gem_object_get_dma_address(obj, offset >> PAGE_SHIFT), |
| 885 | node.start, | 996 | node.start, I915_CACHE_NONE, 0); |
| 886 | I915_CACHE_NONE, 0); | ||
| 887 | wmb(); | 997 | wmb(); |
| 888 | } else { | 998 | } else { |
| 889 | page_base += offset & PAGE_MASK; | 999 | page_base += offset & PAGE_MASK; |
| 890 | } | 1000 | } |
| 891 | /* This is a slow read/write as it tries to read from | 1001 | |
| 892 | * and write to user memory which may result into page | 1002 | if (gtt_user_read(&ggtt->mappable, page_base, page_offset, |
| 893 | * faults, and so we cannot perform this under struct_mutex. | 1003 | user_data, page_length)) { |
| 894 | */ | ||
| 895 | if (slow_user_access(&ggtt->mappable, page_base, | ||
| 896 | page_offset, user_data, | ||
| 897 | page_length, false)) { | ||
| 898 | ret = -EFAULT; | 1004 | ret = -EFAULT; |
| 899 | break; | 1005 | break; |
| 900 | } | 1006 | } |
| @@ -904,110 +1010,19 @@ i915_gem_gtt_pread(struct drm_device *dev, | |||
| 904 | offset += page_length; | 1010 | offset += page_length; |
| 905 | } | 1011 | } |
| 906 | 1012 | ||
| 907 | mutex_lock(&dev->struct_mutex); | 1013 | mutex_lock(&i915->drm.struct_mutex); |
| 908 | if (ret == 0 && (obj->base.read_domains & I915_GEM_DOMAIN_GTT) == 0) { | ||
| 909 | /* The user has modified the object whilst we tried | ||
| 910 | * reading from it, and we now have no idea what domain | ||
| 911 | * the pages should be in. As we have just been touching | ||
| 912 | * them directly, flush everything back to the GTT | ||
| 913 | * domain. | ||
| 914 | */ | ||
| 915 | ret = i915_gem_object_set_to_gtt_domain(obj, false); | ||
| 916 | } | ||
| 917 | |||
| 918 | out_unpin: | 1014 | out_unpin: |
| 919 | if (node.allocated) { | 1015 | if (node.allocated) { |
| 920 | wmb(); | 1016 | wmb(); |
| 921 | ggtt->base.clear_range(&ggtt->base, | 1017 | ggtt->base.clear_range(&ggtt->base, |
| 922 | node.start, node.size); | 1018 | node.start, node.size); |
| 923 | i915_gem_object_unpin_pages(obj); | ||
| 924 | remove_mappable_node(&node); | 1019 | remove_mappable_node(&node); |
| 925 | } else { | 1020 | } else { |
| 926 | i915_vma_unpin(vma); | 1021 | i915_vma_unpin(vma); |
| 927 | } | 1022 | } |
| 928 | out: | 1023 | out_unlock: |
| 929 | return ret; | 1024 | intel_runtime_pm_put(i915); |
| 930 | } | 1025 | mutex_unlock(&i915->drm.struct_mutex); |
| 931 | |||
| 932 | static int | ||
| 933 | i915_gem_shmem_pread(struct drm_device *dev, | ||
| 934 | struct drm_i915_gem_object *obj, | ||
| 935 | struct drm_i915_gem_pread *args, | ||
| 936 | struct drm_file *file) | ||
| 937 | { | ||
| 938 | char __user *user_data; | ||
| 939 | ssize_t remain; | ||
| 940 | loff_t offset; | ||
| 941 | int shmem_page_offset, page_length, ret = 0; | ||
| 942 | int obj_do_bit17_swizzling, page_do_bit17_swizzling; | ||
| 943 | int prefaulted = 0; | ||
| 944 | int needs_clflush = 0; | ||
| 945 | struct sg_page_iter sg_iter; | ||
| 946 | |||
| 947 | ret = i915_gem_obj_prepare_shmem_read(obj, &needs_clflush); | ||
| 948 | if (ret) | ||
| 949 | return ret; | ||
| 950 | |||
| 951 | obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); | ||
| 952 | user_data = u64_to_user_ptr(args->data_ptr); | ||
| 953 | offset = args->offset; | ||
| 954 | remain = args->size; | ||
| 955 | |||
| 956 | for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, | ||
| 957 | offset >> PAGE_SHIFT) { | ||
| 958 | struct page *page = sg_page_iter_page(&sg_iter); | ||
| 959 | |||
| 960 | if (remain <= 0) | ||
| 961 | break; | ||
| 962 | |||
| 963 | /* Operation in this page | ||
| 964 | * | ||
| 965 | * shmem_page_offset = offset within page in shmem file | ||
| 966 | * page_length = bytes to copy for this page | ||
| 967 | */ | ||
| 968 | shmem_page_offset = offset_in_page(offset); | ||
| 969 | page_length = remain; | ||
| 970 | if ((shmem_page_offset + page_length) > PAGE_SIZE) | ||
| 971 | page_length = PAGE_SIZE - shmem_page_offset; | ||
| 972 | |||
| 973 | page_do_bit17_swizzling = obj_do_bit17_swizzling && | ||
| 974 | (page_to_phys(page) & (1 << 17)) != 0; | ||
| 975 | |||
| 976 | ret = shmem_pread_fast(page, shmem_page_offset, page_length, | ||
| 977 | user_data, page_do_bit17_swizzling, | ||
| 978 | needs_clflush); | ||
| 979 | if (ret == 0) | ||
| 980 | goto next_page; | ||
| 981 | |||
| 982 | mutex_unlock(&dev->struct_mutex); | ||
| 983 | |||
| 984 | if (likely(!i915.prefault_disable) && !prefaulted) { | ||
| 985 | ret = fault_in_pages_writeable(user_data, remain); | ||
| 986 | /* Userspace is tricking us, but we've already clobbered | ||
| 987 | * its pages with the prefault and promised to write the | ||
| 988 | * data up to the first fault. Hence ignore any errors | ||
| 989 | * and just continue. */ | ||
| 990 | (void)ret; | ||
| 991 | prefaulted = 1; | ||
| 992 | } | ||
| 993 | |||
| 994 | ret = shmem_pread_slow(page, shmem_page_offset, page_length, | ||
| 995 | user_data, page_do_bit17_swizzling, | ||
| 996 | needs_clflush); | ||
| 997 | |||
| 998 | mutex_lock(&dev->struct_mutex); | ||
| 999 | |||
| 1000 | if (ret) | ||
| 1001 | goto out; | ||
| 1002 | |||
| 1003 | next_page: | ||
| 1004 | remain -= page_length; | ||
| 1005 | user_data += page_length; | ||
| 1006 | offset += page_length; | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | out: | ||
| 1010 | i915_gem_obj_finish_shmem_access(obj); | ||
| 1011 | 1026 | ||
| 1012 | return ret; | 1027 | return ret; |
| 1013 | } | 1028 | } |
| @@ -1026,7 +1041,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
| 1026 | { | 1041 | { |
| 1027 | struct drm_i915_gem_pread *args = data; | 1042 | struct drm_i915_gem_pread *args = data; |
| 1028 | struct drm_i915_gem_object *obj; | 1043 | struct drm_i915_gem_object *obj; |
| 1029 | int ret = 0; | 1044 | int ret; |
| 1030 | 1045 | ||
| 1031 | if (args->size == 0) | 1046 | if (args->size == 0) |
| 1032 | return 0; | 1047 | return 0; |
| @@ -1044,36 +1059,29 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
| 1044 | if (args->offset > obj->base.size || | 1059 | if (args->offset > obj->base.size || |
| 1045 | args->size > obj->base.size - args->offset) { | 1060 | args->size > obj->base.size - args->offset) { |
| 1046 | ret = -EINVAL; | 1061 | ret = -EINVAL; |
| 1047 | goto err; | 1062 | goto out; |
| 1048 | } | 1063 | } |
| 1049 | 1064 | ||
| 1050 | trace_i915_gem_object_pread(obj, args->offset, args->size); | 1065 | trace_i915_gem_object_pread(obj, args->offset, args->size); |
| 1051 | 1066 | ||
| 1052 | ret = __unsafe_wait_rendering(obj, to_rps_client(file), true); | 1067 | ret = i915_gem_object_wait(obj, |
| 1068 | I915_WAIT_INTERRUPTIBLE, | ||
| 1069 | MAX_SCHEDULE_TIMEOUT, | ||
| 1070 | to_rps_client(file)); | ||
| 1053 | if (ret) | 1071 | if (ret) |
| 1054 | goto err; | 1072 | goto out; |
| 1055 | 1073 | ||
| 1056 | ret = i915_mutex_lock_interruptible(dev); | 1074 | ret = i915_gem_object_pin_pages(obj); |
| 1057 | if (ret) | 1075 | if (ret) |
| 1058 | goto err; | 1076 | goto out; |
| 1059 | 1077 | ||
| 1060 | ret = i915_gem_shmem_pread(dev, obj, args, file); | 1078 | ret = i915_gem_shmem_pread(obj, args); |
| 1061 | 1079 | if (ret == -EFAULT || ret == -ENODEV) | |
| 1062 | /* pread for non shmem backed objects */ | 1080 | ret = i915_gem_gtt_pread(obj, args); |
| 1063 | if (ret == -EFAULT || ret == -ENODEV) { | ||
| 1064 | intel_runtime_pm_get(to_i915(dev)); | ||
| 1065 | ret = i915_gem_gtt_pread(dev, obj, args->size, | ||
| 1066 | args->offset, args->data_ptr); | ||
| 1067 | intel_runtime_pm_put(to_i915(dev)); | ||
| 1068 | } | ||
| 1069 | 1081 | ||
| 1082 | i915_gem_object_unpin_pages(obj); | ||
| 1083 | out: | ||
| 1070 | i915_gem_object_put(obj); | 1084 | i915_gem_object_put(obj); |
| 1071 | mutex_unlock(&dev->struct_mutex); | ||
| 1072 | |||
| 1073 | return ret; | ||
| 1074 | |||
| 1075 | err: | ||
| 1076 | i915_gem_object_put_unlocked(obj); | ||
| 1077 | return ret; | 1085 | return ret; |
| 1078 | } | 1086 | } |
| 1079 | 1087 | ||
| @@ -1081,51 +1089,52 @@ err: | |||
| 1081 | * page faults in the source data | 1089 | * page faults in the source data |
| 1082 | */ | 1090 | */ |
| 1083 | 1091 | ||
| 1084 | static inline int | 1092 | static inline bool |
| 1085 | fast_user_write(struct io_mapping *mapping, | 1093 | ggtt_write(struct io_mapping *mapping, |
| 1086 | loff_t page_base, int page_offset, | 1094 | loff_t base, int offset, |
| 1087 | char __user *user_data, | 1095 | char __user *user_data, int length) |
| 1088 | int length) | ||
| 1089 | { | 1096 | { |
| 1090 | void __iomem *vaddr_atomic; | ||
| 1091 | void *vaddr; | 1097 | void *vaddr; |
| 1092 | unsigned long unwritten; | 1098 | unsigned long unwritten; |
| 1093 | 1099 | ||
| 1094 | vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base); | ||
| 1095 | /* We can use the cpu mem copy function because this is X86. */ | 1100 | /* We can use the cpu mem copy function because this is X86. */ |
| 1096 | vaddr = (void __force*)vaddr_atomic + page_offset; | 1101 | vaddr = (void __force *)io_mapping_map_atomic_wc(mapping, base); |
| 1097 | unwritten = __copy_from_user_inatomic_nocache(vaddr, | 1102 | unwritten = __copy_from_user_inatomic_nocache(vaddr + offset, |
| 1098 | user_data, length); | 1103 | user_data, length); |
| 1099 | io_mapping_unmap_atomic(vaddr_atomic); | 1104 | io_mapping_unmap_atomic(vaddr); |
| 1105 | if (unwritten) { | ||
| 1106 | vaddr = (void __force *) | ||
| 1107 | io_mapping_map_wc(mapping, base, PAGE_SIZE); | ||
| 1108 | unwritten = copy_from_user(vaddr + offset, user_data, length); | ||
| 1109 | io_mapping_unmap(vaddr); | ||
| 1110 | } | ||
| 1111 | |||
| 1100 | return unwritten; | 1112 | return unwritten; |
| 1101 | } | 1113 | } |
| 1102 | 1114 | ||
| 1103 | /** | 1115 | /** |
| 1104 | * This is the fast pwrite path, where we copy the data directly from the | 1116 | * This is the fast pwrite path, where we copy the data directly from the |
| 1105 | * user into the GTT, uncached. | 1117 | * user into the GTT, uncached. |
| 1106 | * @i915: i915 device private data | 1118 | * @obj: i915 GEM object |
| 1107 | * @obj: i915 gem object | ||
| 1108 | * @args: pwrite arguments structure | 1119 | * @args: pwrite arguments structure |
| 1109 | * @file: drm file pointer | ||
| 1110 | */ | 1120 | */ |
| 1111 | static int | 1121 | static int |
| 1112 | i915_gem_gtt_pwrite_fast(struct drm_i915_private *i915, | 1122 | i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *obj, |
| 1113 | struct drm_i915_gem_object *obj, | 1123 | const struct drm_i915_gem_pwrite *args) |
| 1114 | struct drm_i915_gem_pwrite *args, | ||
| 1115 | struct drm_file *file) | ||
| 1116 | { | 1124 | { |
| 1125 | struct drm_i915_private *i915 = to_i915(obj->base.dev); | ||
| 1117 | struct i915_ggtt *ggtt = &i915->ggtt; | 1126 | struct i915_ggtt *ggtt = &i915->ggtt; |
| 1118 | struct drm_device *dev = obj->base.dev; | ||
| 1119 | struct i915_vma *vma; | ||
| 1120 | struct drm_mm_node node; | 1127 | struct drm_mm_node node; |
| 1121 | uint64_t remain, offset; | 1128 | struct i915_vma *vma; |
| 1122 | char __user *user_data; | 1129 | u64 remain, offset; |
| 1130 | void __user *user_data; | ||
| 1123 | int ret; | 1131 | int ret; |
| 1124 | bool hit_slow_path = false; | ||
| 1125 | 1132 | ||
| 1126 | if (i915_gem_object_is_tiled(obj)) | 1133 | ret = mutex_lock_interruptible(&i915->drm.struct_mutex); |
| 1127 | return -EFAULT; | 1134 | if (ret) |
| 1135 | return ret; | ||
| 1128 | 1136 | ||
| 1137 | intel_runtime_pm_get(i915); | ||
| 1129 | vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, | 1138 | vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, |
| 1130 | PIN_MAPPABLE | PIN_NONBLOCK); | 1139 | PIN_MAPPABLE | PIN_NONBLOCK); |
| 1131 | if (!IS_ERR(vma)) { | 1140 | if (!IS_ERR(vma)) { |
| @@ -1138,25 +1147,19 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_private *i915, | |||
| 1138 | } | 1147 | } |
| 1139 | } | 1148 | } |
| 1140 | if (IS_ERR(vma)) { | 1149 | if (IS_ERR(vma)) { |
| 1141 | ret = insert_mappable_node(i915, &node, PAGE_SIZE); | 1150 | ret = insert_mappable_node(ggtt, &node, PAGE_SIZE); |
| 1142 | if (ret) | 1151 | if (ret) |
| 1143 | goto out; | 1152 | goto out_unlock; |
| 1144 | 1153 | GEM_BUG_ON(!node.allocated); | |
| 1145 | ret = i915_gem_object_get_pages(obj); | ||
| 1146 | if (ret) { | ||
| 1147 | remove_mappable_node(&node); | ||
| 1148 | goto out; | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | i915_gem_object_pin_pages(obj); | ||
| 1152 | } | 1154 | } |
| 1153 | 1155 | ||
| 1154 | ret = i915_gem_object_set_to_gtt_domain(obj, true); | 1156 | ret = i915_gem_object_set_to_gtt_domain(obj, true); |
| 1155 | if (ret) | 1157 | if (ret) |
| 1156 | goto out_unpin; | 1158 | goto out_unpin; |
| 1157 | 1159 | ||
| 1160 | mutex_unlock(&i915->drm.struct_mutex); | ||
| 1161 | |||
| 1158 | intel_fb_obj_invalidate(obj, ORIGIN_CPU); | 1162 | intel_fb_obj_invalidate(obj, ORIGIN_CPU); |
| 1159 | obj->dirty = true; | ||
| 1160 | 1163 | ||
| 1161 | user_data = u64_to_user_ptr(args->data_ptr); | 1164 | user_data = u64_to_user_ptr(args->data_ptr); |
| 1162 | offset = args->offset; | 1165 | offset = args->offset; |
| @@ -1169,8 +1172,8 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_private *i915, | |||
| 1169 | * page_length = bytes to copy for this page | 1172 | * page_length = bytes to copy for this page |
| 1170 | */ | 1173 | */ |
| 1171 | u32 page_base = node.start; | 1174 | u32 page_base = node.start; |
| 1172 | unsigned page_offset = offset_in_page(offset); | 1175 | unsigned int page_offset = offset_in_page(offset); |
| 1173 | unsigned page_length = PAGE_SIZE - page_offset; | 1176 | unsigned int page_length = PAGE_SIZE - page_offset; |
| 1174 | page_length = remain < page_length ? remain : page_length; | 1177 | page_length = remain < page_length ? remain : page_length; |
| 1175 | if (node.allocated) { | 1178 | if (node.allocated) { |
| 1176 | wmb(); /* flush the write before we modify the GGTT */ | 1179 | wmb(); /* flush the write before we modify the GGTT */ |
| @@ -1187,91 +1190,36 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_private *i915, | |||
| 1187 | * If the object is non-shmem backed, we retry again with the | 1190 | * If the object is non-shmem backed, we retry again with the |
| 1188 | * path that handles page fault. | 1191 | * path that handles page fault. |
| 1189 | */ | 1192 | */ |
| 1190 | if (fast_user_write(&ggtt->mappable, page_base, | 1193 | if (ggtt_write(&ggtt->mappable, page_base, page_offset, |
| 1191 | page_offset, user_data, page_length)) { | 1194 | user_data, page_length)) { |
| 1192 | hit_slow_path = true; | 1195 | ret = -EFAULT; |
| 1193 | mutex_unlock(&dev->struct_mutex); | 1196 | break; |
| 1194 | if (slow_user_access(&ggtt->mappable, | ||
| 1195 | page_base, | ||
| 1196 | page_offset, user_data, | ||
| 1197 | page_length, true)) { | ||
| 1198 | ret = -EFAULT; | ||
| 1199 | mutex_lock(&dev->struct_mutex); | ||
| 1200 | goto out_flush; | ||
| 1201 | } | ||
| 1202 | |||
| 1203 | mutex_lock(&dev->struct_mutex); | ||
| 1204 | } | 1197 | } |
| 1205 | 1198 | ||
| 1206 | remain -= page_length; | 1199 | remain -= page_length; |
| 1207 | user_data += page_length; | 1200 | user_data += page_length; |
| 1208 | offset += page_length; | 1201 | offset += page_length; |
| 1209 | } | 1202 | } |
| 1210 | |||
| 1211 | out_flush: | ||
| 1212 | if (hit_slow_path) { | ||
| 1213 | if (ret == 0 && | ||
| 1214 | (obj->base.read_domains & I915_GEM_DOMAIN_GTT) == 0) { | ||
| 1215 | /* The user has modified the object whilst we tried | ||
| 1216 | * reading from it, and we now have no idea what domain | ||
| 1217 | * the pages should be in. As we have just been touching | ||
| 1218 | * them directly, flush everything back to the GTT | ||
| 1219 | * domain. | ||
| 1220 | */ | ||
| 1221 | ret = i915_gem_object_set_to_gtt_domain(obj, false); | ||
| 1222 | } | ||
| 1223 | } | ||
| 1224 | |||
| 1225 | intel_fb_obj_flush(obj, false, ORIGIN_CPU); | 1203 | intel_fb_obj_flush(obj, false, ORIGIN_CPU); |
| 1204 | |||
| 1205 | mutex_lock(&i915->drm.struct_mutex); | ||
| 1226 | out_unpin: | 1206 | out_unpin: |
| 1227 | if (node.allocated) { | 1207 | if (node.allocated) { |
| 1228 | wmb(); | 1208 | wmb(); |
| 1229 | ggtt->base.clear_range(&ggtt->base, | 1209 | ggtt->base.clear_range(&ggtt->base, |
| 1230 | node.start, node.size); | 1210 | node.start, node.size); |
| 1231 | i915_gem_object_unpin_pages(obj); | ||
| 1232 | remove_mappable_node(&node); | 1211 | remove_mappable_node(&node); |
| 1233 | } else { | 1212 | } else { |
| 1234 | i915_vma_unpin(vma); | 1213 | i915_vma_unpin(vma); |
| 1235 | } | 1214 | } |
| 1236 | out: | 1215 | out_unlock: |
| 1216 | intel_runtime_pm_put(i915); | ||
| 1217 | mutex_unlock(&i915->drm.struct_mutex); | ||
| 1237 | return ret; | 1218 | return ret; |
| 1238 | } | 1219 | } |
| 1239 | 1220 | ||
| 1240 | /* Per-page copy function for the shmem pwrite fastpath. | ||
| 1241 | * Flushes invalid cachelines before writing to the target if | ||
| 1242 | * needs_clflush_before is set and flushes out any written cachelines after | ||
| 1243 | * writing if needs_clflush is set. */ | ||
| 1244 | static int | 1221 | static int |
| 1245 | shmem_pwrite_fast(struct page *page, int shmem_page_offset, int page_length, | 1222 | shmem_pwrite_slow(struct page *page, int offset, int length, |
| 1246 | char __user *user_data, | ||
| 1247 | bool page_do_bit17_swizzling, | ||
| 1248 | bool needs_clflush_before, | ||
| 1249 | bool needs_clflush_after) | ||
| 1250 | { | ||
| 1251 | char *vaddr; | ||
| 1252 | int ret; | ||
| 1253 | |||
| 1254 | if (unlikely(page_do_bit17_swizzling)) | ||
| 1255 | return -EINVAL; | ||
| 1256 | |||
| 1257 | vaddr = kmap_atomic(page); | ||
| 1258 | if (needs_clflush_before) | ||
| 1259 | drm_clflush_virt_range(vaddr + shmem_page_offset, | ||
| 1260 | page_length); | ||
| 1261 | ret = __copy_from_user_inatomic(vaddr + shmem_page_offset, | ||
| 1262 | user_data, page_length); | ||
| 1263 | if (needs_clflush_after) | ||
| 1264 | drm_clflush_virt_range(vaddr + shmem_page_offset, | ||
| 1265 | page_length); | ||
| 1266 | kunmap_atomic(vaddr); | ||
| 1267 | |||
| 1268 | return ret ? -EFAULT : 0; | ||
| 1269 | } | ||
| 1270 | |||
| 1271 | /* Only difference to the fast-path function is that this can handle bit17 | ||
| 1272 | * and uses non-atomic copy and kmap functions. */ | ||
| 1273 | static int | ||
| 1274 | shmem_pwrite_slow(struct page *page, int shmem_page_offset, int page_length, | ||
| 1275 | char __user *user_data, | 1223 | char __user *user_data, |
| 1276 | bool page_do_bit17_swizzling, | 1224 | bool page_do_bit17_swizzling, |
| 1277 | bool needs_clflush_before, | 1225 | bool needs_clflush_before, |
| @@ -1282,124 +1230,114 @@ shmem_pwrite_slow(struct page *page, int shmem_page_offset, int page_length, | |||
| 1282 | 1230 | ||
| 1283 | vaddr = kmap(page); | 1231 | vaddr = kmap(page); |
| 1284 | if (unlikely(needs_clflush_before || page_do_bit17_swizzling)) | 1232 | if (unlikely(needs_clflush_before || page_do_bit17_swizzling)) |
| 1285 | shmem_clflush_swizzled_range(vaddr + shmem_page_offset, | 1233 | shmem_clflush_swizzled_range(vaddr + offset, length, |
| 1286 | page_length, | ||
| 1287 | page_do_bit17_swizzling); | 1234 | page_do_bit17_swizzling); |
| 1288 | if (page_do_bit17_swizzling) | 1235 | if (page_do_bit17_swizzling) |
| 1289 | ret = __copy_from_user_swizzled(vaddr, shmem_page_offset, | 1236 | ret = __copy_from_user_swizzled(vaddr, offset, user_data, |
| 1290 | user_data, | 1237 | length); |
| 1291 | page_length); | ||
| 1292 | else | 1238 | else |
| 1293 | ret = __copy_from_user(vaddr + shmem_page_offset, | 1239 | ret = __copy_from_user(vaddr + offset, user_data, length); |
| 1294 | user_data, | ||
| 1295 | page_length); | ||
| 1296 | if (needs_clflush_after) | 1240 | if (needs_clflush_after) |
| 1297 | shmem_clflush_swizzled_range(vaddr + shmem_page_offset, | 1241 | shmem_clflush_swizzled_range(vaddr + offset, length, |
| 1298 | page_length, | ||
| 1299 | page_do_bit17_swizzling); | 1242 | page_do_bit17_swizzling); |
| 1300 | kunmap(page); | 1243 | kunmap(page); |
| 1301 | 1244 | ||
| 1302 | return ret ? -EFAULT : 0; | 1245 | return ret ? -EFAULT : 0; |
| 1303 | } | 1246 | } |
| 1304 | 1247 | ||
| 1248 | /* Per-page copy function for the shmem pwrite fastpath. | ||
| 1249 | * Flushes invalid cachelines before writing to the target if | ||
| 1250 | * needs_clflush_before is set and flushes out any written cachelines after | ||
| 1251 | * writing if needs_clflush is set. | ||
| 1252 | */ | ||
| 1305 | static int | 1253 | static int |
| 1306 | i915_gem_shmem_pwrite(struct drm_device *dev, | 1254 | shmem_pwrite(struct page *page, int offset, int len, char __user *user_data, |
| 1307 | struct drm_i915_gem_object *obj, | 1255 | bool page_do_bit17_swizzling, |
| 1308 | struct drm_i915_gem_pwrite *args, | 1256 | bool needs_clflush_before, |
| 1309 | struct drm_file *file) | 1257 | bool needs_clflush_after) |
| 1310 | { | 1258 | { |
| 1311 | ssize_t remain; | 1259 | int ret; |
| 1312 | loff_t offset; | ||
| 1313 | char __user *user_data; | ||
| 1314 | int shmem_page_offset, page_length, ret = 0; | ||
| 1315 | int obj_do_bit17_swizzling, page_do_bit17_swizzling; | ||
| 1316 | int hit_slowpath = 0; | ||
| 1317 | unsigned int needs_clflush; | ||
| 1318 | struct sg_page_iter sg_iter; | ||
| 1319 | 1260 | ||
| 1320 | ret = i915_gem_obj_prepare_shmem_write(obj, &needs_clflush); | 1261 | ret = -ENODEV; |
| 1321 | if (ret) | 1262 | if (!page_do_bit17_swizzling) { |
| 1322 | return ret; | 1263 | char *vaddr = kmap_atomic(page); |
| 1323 | 1264 | ||
| 1324 | obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); | 1265 | if (needs_clflush_before) |
| 1325 | user_data = u64_to_user_ptr(args->data_ptr); | 1266 | drm_clflush_virt_range(vaddr + offset, len); |
| 1326 | offset = args->offset; | 1267 | ret = __copy_from_user_inatomic(vaddr + offset, user_data, len); |
| 1327 | remain = args->size; | 1268 | if (needs_clflush_after) |
| 1269 | drm_clflush_virt_range(vaddr + offset, len); | ||
| 1328 | 1270 | ||
| 1329 | for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, | 1271 | kunmap_atomic(vaddr); |
| 1330 | offset >> PAGE_SHIFT) { | 1272 | } |
| 1331 | struct page *page = sg_page_iter_page(&sg_iter); | 1273 | if (ret == 0) |
| 1332 | int partial_cacheline_write; | 1274 | return ret; |
| 1333 | 1275 | ||
| 1334 | if (remain <= 0) | 1276 | return shmem_pwrite_slow(page, offset, len, user_data, |
| 1335 | break; | 1277 | page_do_bit17_swizzling, |
| 1278 | needs_clflush_before, | ||
| 1279 | needs_clflush_after); | ||
| 1280 | } | ||
| 1336 | 1281 | ||
| 1337 | /* Operation in this page | 1282 | static int |
| 1338 | * | 1283 | i915_gem_shmem_pwrite(struct drm_i915_gem_object *obj, |
| 1339 | * shmem_page_offset = offset within page in shmem file | 1284 | const struct drm_i915_gem_pwrite *args) |
| 1340 | * page_length = bytes to copy for this page | 1285 | { |
| 1341 | */ | 1286 | struct drm_i915_private *i915 = to_i915(obj->base.dev); |
| 1342 | shmem_page_offset = offset_in_page(offset); | 1287 | void __user *user_data; |
| 1343 | 1288 | u64 remain; | |
| 1344 | page_length = remain; | 1289 | unsigned int obj_do_bit17_swizzling; |
| 1345 | if ((shmem_page_offset + page_length) > PAGE_SIZE) | 1290 | unsigned int partial_cacheline_write; |
| 1346 | page_length = PAGE_SIZE - shmem_page_offset; | 1291 | unsigned int needs_clflush; |
| 1347 | 1292 | unsigned int offset, idx; | |
| 1348 | /* If we don't overwrite a cacheline completely we need to be | 1293 | int ret; |
| 1349 | * careful to have up-to-date data by first clflushing. Don't | ||
| 1350 | * overcomplicate things and flush the entire patch. */ | ||
| 1351 | partial_cacheline_write = needs_clflush & CLFLUSH_BEFORE && | ||
| 1352 | ((shmem_page_offset | page_length) | ||
| 1353 | & (boot_cpu_data.x86_clflush_size - 1)); | ||
| 1354 | |||
| 1355 | page_do_bit17_swizzling = obj_do_bit17_swizzling && | ||
| 1356 | (page_to_phys(page) & (1 << 17)) != 0; | ||
| 1357 | |||
| 1358 | ret = shmem_pwrite_fast(page, shmem_page_offset, page_length, | ||
| 1359 | user_data, page_do_bit17_swizzling, | ||
| 1360 | partial_cacheline_write, | ||
| 1361 | needs_clflush & CLFLUSH_AFTER); | ||
| 1362 | if (ret == 0) | ||
| 1363 | goto next_page; | ||
| 1364 | |||
| 1365 | hit_slowpath = 1; | ||
| 1366 | mutex_unlock(&dev->struct_mutex); | ||
| 1367 | ret = shmem_pwrite_slow(page, shmem_page_offset, page_length, | ||
| 1368 | user_data, page_do_bit17_swizzling, | ||
| 1369 | partial_cacheline_write, | ||
| 1370 | needs_clflush & CLFLUSH_AFTER); | ||
| 1371 | 1294 | ||
| 1372 | mutex_lock(&dev->struct_mutex); | 1295 | ret = mutex_lock_interruptible(&i915->drm.struct_mutex); |
| 1296 | if (ret) | ||
| 1297 | return ret; | ||
| 1373 | 1298 | ||
| 1374 | if (ret) | 1299 | ret = i915_gem_obj_prepare_shmem_write(obj, &needs_clflush); |
| 1375 | goto out; | 1300 | mutex_unlock(&i915->drm.struct_mutex); |
| 1301 | if (ret) | ||
| 1302 | return ret; | ||
| 1376 | 1303 | ||
| 1377 | next_page: | 1304 | obj_do_bit17_swizzling = 0; |
| 1378 | remain -= page_length; | 1305 | if (i915_gem_object_needs_bit17_swizzle(obj)) |
| 1379 | user_data += page_length; | 1306 | obj_do_bit17_swizzling = BIT(17); |
| 1380 | offset += page_length; | ||
| 1381 | } | ||
| 1382 | 1307 | ||
| 1383 | out: | 1308 | /* If we don't overwrite a cacheline completely we need to be |
| 1384 | i915_gem_obj_finish_shmem_access(obj); | 1309 | * careful to have up-to-date data by first clflushing. Don't |
| 1310 | * overcomplicate things and flush the entire patch. | ||
| 1311 | */ | ||
| 1312 | partial_cacheline_write = 0; | ||
| 1313 | if (needs_clflush & CLFLUSH_BEFORE) | ||
| 1314 | partial_cacheline_write = boot_cpu_data.x86_clflush_size - 1; | ||
| 1385 | 1315 | ||
| 1386 | if (hit_slowpath) { | 1316 | user_data = u64_to_user_ptr(args->data_ptr); |
| 1387 | /* | 1317 | remain = args->size; |
| 1388 | * Fixup: Flush cpu caches in case we didn't flush the dirty | 1318 | offset = offset_in_page(args->offset); |
| 1389 | * cachelines in-line while writing and the object moved | 1319 | for (idx = args->offset >> PAGE_SHIFT; remain; idx++) { |
| 1390 | * out of the cpu write domain while we've dropped the lock. | 1320 | struct page *page = i915_gem_object_get_page(obj, idx); |
| 1391 | */ | 1321 | int length; |
| 1392 | if (!(needs_clflush & CLFLUSH_AFTER) && | 1322 | |
| 1393 | obj->base.write_domain != I915_GEM_DOMAIN_CPU) { | 1323 | length = remain; |
| 1394 | if (i915_gem_clflush_object(obj, obj->pin_display)) | 1324 | if (offset + length > PAGE_SIZE) |
| 1395 | needs_clflush |= CLFLUSH_AFTER; | 1325 | length = PAGE_SIZE - offset; |
| 1396 | } | 1326 | |
| 1397 | } | 1327 | ret = shmem_pwrite(page, offset, length, user_data, |
| 1328 | page_to_phys(page) & obj_do_bit17_swizzling, | ||
| 1329 | (offset | length) & partial_cacheline_write, | ||
| 1330 | needs_clflush & CLFLUSH_AFTER); | ||
| 1331 | if (ret) | ||
| 1332 | break; | ||
| 1398 | 1333 | ||
| 1399 | if (needs_clflush & CLFLUSH_AFTER) | 1334 | remain -= length; |
| 1400 | i915_gem_chipset_flush(to_i915(dev)); | 1335 | user_data += length; |
| 1336 | offset = 0; | ||
| 1337 | } | ||
| 1401 | 1338 | ||
| 1402 | intel_fb_obj_flush(obj, false, ORIGIN_CPU); | 1339 | intel_fb_obj_flush(obj, false, ORIGIN_CPU); |
| 1340 | i915_gem_obj_finish_shmem_access(obj); | ||
| 1403 | return ret; | 1341 | return ret; |
| 1404 | } | 1342 | } |
| 1405 | 1343 | ||
| @@ -1415,7 +1353,6 @@ int | |||
| 1415 | i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | 1353 | i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, |
| 1416 | struct drm_file *file) | 1354 | struct drm_file *file) |
| 1417 | { | 1355 | { |
| 1418 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 1419 | struct drm_i915_gem_pwrite *args = data; | 1356 | struct drm_i915_gem_pwrite *args = data; |
| 1420 | struct drm_i915_gem_object *obj; | 1357 | struct drm_i915_gem_object *obj; |
| 1421 | int ret; | 1358 | int ret; |
| @@ -1428,13 +1365,6 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
| 1428 | args->size)) | 1365 | args->size)) |
| 1429 | return -EFAULT; | 1366 | return -EFAULT; |
| 1430 | 1367 | ||
| 1431 | if (likely(!i915.prefault_disable)) { | ||
| 1432 | ret = fault_in_pages_readable(u64_to_user_ptr(args->data_ptr), | ||
| 1433 | args->size); | ||
| 1434 | if (ret) | ||
| 1435 | return -EFAULT; | ||
| 1436 | } | ||
| 1437 | |||
| 1438 | obj = i915_gem_object_lookup(file, args->handle); | 1368 | obj = i915_gem_object_lookup(file, args->handle); |
| 1439 | if (!obj) | 1369 | if (!obj) |
| 1440 | return -ENOENT; | 1370 | return -ENOENT; |
| @@ -1448,15 +1378,17 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
| 1448 | 1378 | ||
| 1449 | trace_i915_gem_object_pwrite(obj, args->offset, args->size); | 1379 | trace_i915_gem_object_pwrite(obj, args->offset, args->size); |
| 1450 | 1380 | ||
| 1451 | ret = __unsafe_wait_rendering(obj, to_rps_client(file), false); | 1381 | ret = i915_gem_object_wait(obj, |
| 1382 | I915_WAIT_INTERRUPTIBLE | | ||
| 1383 | I915_WAIT_ALL, | ||
| 1384 | MAX_SCHEDULE_TIMEOUT, | ||
| 1385 | to_rps_client(file)); | ||
| 1452 | if (ret) | 1386 | if (ret) |
| 1453 | goto err; | 1387 | goto err; |
| 1454 | 1388 | ||
| 1455 | intel_runtime_pm_get(dev_priv); | 1389 | ret = i915_gem_object_pin_pages(obj); |
| 1456 | |||
| 1457 | ret = i915_mutex_lock_interruptible(dev); | ||
| 1458 | if (ret) | 1390 | if (ret) |
| 1459 | goto err_rpm; | 1391 | goto err; |
| 1460 | 1392 | ||
| 1461 | ret = -EFAULT; | 1393 | ret = -EFAULT; |
| 1462 | /* We can only do the GTT pwrite on untiled buffers, as otherwise | 1394 | /* We can only do the GTT pwrite on untiled buffers, as otherwise |
| @@ -1466,30 +1398,23 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
| 1466 | * perspective, requiring manual detiling by the client. | 1398 | * perspective, requiring manual detiling by the client. |
| 1467 | */ | 1399 | */ |
| 1468 | if (!i915_gem_object_has_struct_page(obj) || | 1400 | if (!i915_gem_object_has_struct_page(obj) || |
| 1469 | cpu_write_needs_clflush(obj)) { | 1401 | cpu_write_needs_clflush(obj)) |
| 1470 | ret = i915_gem_gtt_pwrite_fast(dev_priv, obj, args, file); | ||
| 1471 | /* Note that the gtt paths might fail with non-page-backed user | 1402 | /* Note that the gtt paths might fail with non-page-backed user |
| 1472 | * pointers (e.g. gtt mappings when moving data between | 1403 | * pointers (e.g. gtt mappings when moving data between |
| 1473 | * textures). Fallback to the shmem path in that case. */ | 1404 | * textures). Fallback to the shmem path in that case. |
| 1474 | } | 1405 | */ |
| 1406 | ret = i915_gem_gtt_pwrite_fast(obj, args); | ||
| 1475 | 1407 | ||
| 1476 | if (ret == -EFAULT || ret == -ENOSPC) { | 1408 | if (ret == -EFAULT || ret == -ENOSPC) { |
| 1477 | if (obj->phys_handle) | 1409 | if (obj->phys_handle) |
| 1478 | ret = i915_gem_phys_pwrite(obj, args, file); | 1410 | ret = i915_gem_phys_pwrite(obj, args, file); |
| 1479 | else | 1411 | else |
| 1480 | ret = i915_gem_shmem_pwrite(dev, obj, args, file); | 1412 | ret = i915_gem_shmem_pwrite(obj, args); |
| 1481 | } | 1413 | } |
| 1482 | 1414 | ||
| 1483 | i915_gem_object_put(obj); | 1415 | i915_gem_object_unpin_pages(obj); |
| 1484 | mutex_unlock(&dev->struct_mutex); | ||
| 1485 | intel_runtime_pm_put(dev_priv); | ||
| 1486 | |||
| 1487 | return ret; | ||
| 1488 | |||
| 1489 | err_rpm: | ||
| 1490 | intel_runtime_pm_put(dev_priv); | ||
| 1491 | err: | 1416 | err: |
| 1492 | i915_gem_object_put_unlocked(obj); | 1417 | i915_gem_object_put(obj); |
| 1493 | return ret; | 1418 | return ret; |
| 1494 | } | 1419 | } |
| 1495 | 1420 | ||
| @@ -1500,6 +1425,30 @@ write_origin(struct drm_i915_gem_object *obj, unsigned domain) | |||
| 1500 | obj->frontbuffer_ggtt_origin : ORIGIN_CPU); | 1425 | obj->frontbuffer_ggtt_origin : ORIGIN_CPU); |
| 1501 | } | 1426 | } |
| 1502 | 1427 | ||
| 1428 | static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object *obj) | ||
| 1429 | { | ||
| 1430 | struct drm_i915_private *i915; | ||
| 1431 | struct list_head *list; | ||
| 1432 | struct i915_vma *vma; | ||
| 1433 | |||
| 1434 | list_for_each_entry(vma, &obj->vma_list, obj_link) { | ||
| 1435 | if (!i915_vma_is_ggtt(vma)) | ||
| 1436 | continue; | ||
| 1437 | |||
| 1438 | if (i915_vma_is_active(vma)) | ||
| 1439 | continue; | ||
| 1440 | |||
| 1441 | if (!drm_mm_node_allocated(&vma->node)) | ||
| 1442 | continue; | ||
| 1443 | |||
| 1444 | list_move_tail(&vma->vm_link, &vma->vm->inactive_list); | ||
| 1445 | } | ||
| 1446 | |||
| 1447 | i915 = to_i915(obj->base.dev); | ||
| 1448 | list = obj->bind_count ? &i915->mm.bound_list : &i915->mm.unbound_list; | ||
| 1449 | list_move_tail(&obj->global_link, list); | ||
| 1450 | } | ||
| 1451 | |||
| 1503 | /** | 1452 | /** |
| 1504 | * Called when user space prepares to use an object with the CPU, either | 1453 | * Called when user space prepares to use an object with the CPU, either |
| 1505 | * through the mmap ioctl's mapping or a GTT mapping. | 1454 | * through the mmap ioctl's mapping or a GTT mapping. |
| @@ -1515,7 +1464,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
| 1515 | struct drm_i915_gem_object *obj; | 1464 | struct drm_i915_gem_object *obj; |
| 1516 | uint32_t read_domains = args->read_domains; | 1465 | uint32_t read_domains = args->read_domains; |
| 1517 | uint32_t write_domain = args->write_domain; | 1466 | uint32_t write_domain = args->write_domain; |
| 1518 | int ret; | 1467 | int err; |
| 1519 | 1468 | ||
| 1520 | /* Only handle setting domains to types used by the CPU. */ | 1469 | /* Only handle setting domains to types used by the CPU. */ |
| 1521 | if ((write_domain | read_domains) & I915_GEM_GPU_DOMAINS) | 1470 | if ((write_domain | read_domains) & I915_GEM_GPU_DOMAINS) |
| @@ -1535,29 +1484,48 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
| 1535 | * We will repeat the flush holding the lock in the normal manner | 1484 | * We will repeat the flush holding the lock in the normal manner |
| 1536 | * to catch cases where we are gazumped. | 1485 | * to catch cases where we are gazumped. |
| 1537 | */ | 1486 | */ |
| 1538 | ret = __unsafe_wait_rendering(obj, to_rps_client(file), !write_domain); | 1487 | err = i915_gem_object_wait(obj, |
| 1539 | if (ret) | 1488 | I915_WAIT_INTERRUPTIBLE | |
| 1540 | goto err; | 1489 | (write_domain ? I915_WAIT_ALL : 0), |
| 1490 | MAX_SCHEDULE_TIMEOUT, | ||
| 1491 | to_rps_client(file)); | ||
| 1492 | if (err) | ||
| 1493 | goto out; | ||
| 1541 | 1494 | ||
| 1542 | ret = i915_mutex_lock_interruptible(dev); | 1495 | /* Flush and acquire obj->pages so that we are coherent through |
| 1543 | if (ret) | 1496 | * direct access in memory with previous cached writes through |
| 1544 | goto err; | 1497 | * shmemfs and that our cache domain tracking remains valid. |
| 1498 | * For example, if the obj->filp was moved to swap without us | ||
| 1499 | * being notified and releasing the pages, we would mistakenly | ||
| 1500 | * continue to assume that the obj remained out of the CPU cached | ||
| 1501 | * domain. | ||
| 1502 | */ | ||
| 1503 | err = i915_gem_object_pin_pages(obj); | ||
| 1504 | if (err) | ||
| 1505 | goto out; | ||
| 1506 | |||
| 1507 | err = i915_mutex_lock_interruptible(dev); | ||
| 1508 | if (err) | ||
| 1509 | goto out_unpin; | ||
| 1545 | 1510 | ||
| 1546 | if (read_domains & I915_GEM_DOMAIN_GTT) | 1511 | if (read_domains & I915_GEM_DOMAIN_GTT) |
| 1547 | ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); | 1512 | err = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); |
| 1548 | else | 1513 | else |
| 1549 | ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); | 1514 | err = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); |
| 1515 | |||
| 1516 | /* And bump the LRU for this access */ | ||
| 1517 | i915_gem_object_bump_inactive_ggtt(obj); | ||
| 1518 | |||
| 1519 | mutex_unlock(&dev->struct_mutex); | ||
| 1550 | 1520 | ||
| 1551 | if (write_domain != 0) | 1521 | if (write_domain != 0) |
| 1552 | intel_fb_obj_invalidate(obj, write_origin(obj, write_domain)); | 1522 | intel_fb_obj_invalidate(obj, write_origin(obj, write_domain)); |
| 1553 | 1523 | ||
| 1524 | out_unpin: | ||
| 1525 | i915_gem_object_unpin_pages(obj); | ||
| 1526 | out: | ||
| 1554 | i915_gem_object_put(obj); | 1527 | i915_gem_object_put(obj); |
| 1555 | mutex_unlock(&dev->struct_mutex); | 1528 | return err; |
| 1556 | return ret; | ||
| 1557 | |||
| 1558 | err: | ||
| 1559 | i915_gem_object_put_unlocked(obj); | ||
| 1560 | return ret; | ||
| 1561 | } | 1529 | } |
| 1562 | 1530 | ||
| 1563 | /** | 1531 | /** |
| @@ -1587,7 +1555,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, | |||
| 1587 | } | 1555 | } |
| 1588 | } | 1556 | } |
| 1589 | 1557 | ||
| 1590 | i915_gem_object_put_unlocked(obj); | 1558 | i915_gem_object_put(obj); |
| 1591 | return err; | 1559 | return err; |
| 1592 | } | 1560 | } |
| 1593 | 1561 | ||
| @@ -1633,7 +1601,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
| 1633 | * pages from. | 1601 | * pages from. |
| 1634 | */ | 1602 | */ |
| 1635 | if (!obj->base.filp) { | 1603 | if (!obj->base.filp) { |
| 1636 | i915_gem_object_put_unlocked(obj); | 1604 | i915_gem_object_put(obj); |
| 1637 | return -EINVAL; | 1605 | return -EINVAL; |
| 1638 | } | 1606 | } |
| 1639 | 1607 | ||
| @@ -1645,7 +1613,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
| 1645 | struct vm_area_struct *vma; | 1613 | struct vm_area_struct *vma; |
| 1646 | 1614 | ||
| 1647 | if (down_write_killable(&mm->mmap_sem)) { | 1615 | if (down_write_killable(&mm->mmap_sem)) { |
| 1648 | i915_gem_object_put_unlocked(obj); | 1616 | i915_gem_object_put(obj); |
| 1649 | return -EINTR; | 1617 | return -EINTR; |
| 1650 | } | 1618 | } |
| 1651 | vma = find_vma(mm, addr); | 1619 | vma = find_vma(mm, addr); |
| @@ -1659,7 +1627,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
| 1659 | /* This may race, but that's ok, it only gets set */ | 1627 | /* This may race, but that's ok, it only gets set */ |
| 1660 | WRITE_ONCE(obj->frontbuffer_ggtt_origin, ORIGIN_CPU); | 1628 | WRITE_ONCE(obj->frontbuffer_ggtt_origin, ORIGIN_CPU); |
| 1661 | } | 1629 | } |
| 1662 | i915_gem_object_put_unlocked(obj); | 1630 | i915_gem_object_put(obj); |
| 1663 | if (IS_ERR((void *)addr)) | 1631 | if (IS_ERR((void *)addr)) |
| 1664 | return addr; | 1632 | return addr; |
| 1665 | 1633 | ||
| @@ -1771,7 +1739,14 @@ int i915_gem_fault(struct vm_area_struct *area, struct vm_fault *vmf) | |||
| 1771 | * repeat the flush holding the lock in the normal manner to catch cases | 1739 | * repeat the flush holding the lock in the normal manner to catch cases |
| 1772 | * where we are gazumped. | 1740 | * where we are gazumped. |
| 1773 | */ | 1741 | */ |
| 1774 | ret = __unsafe_wait_rendering(obj, NULL, !write); | 1742 | ret = i915_gem_object_wait(obj, |
| 1743 | I915_WAIT_INTERRUPTIBLE, | ||
| 1744 | MAX_SCHEDULE_TIMEOUT, | ||
| 1745 | NULL); | ||
| 1746 | if (ret) | ||
| 1747 | goto err; | ||
| 1748 | |||
| 1749 | ret = i915_gem_object_pin_pages(obj); | ||
| 1775 | if (ret) | 1750 | if (ret) |
| 1776 | goto err; | 1751 | goto err; |
| 1777 | 1752 | ||
| @@ -1804,7 +1779,7 @@ int i915_gem_fault(struct vm_area_struct *area, struct vm_fault *vmf) | |||
| 1804 | /* Use a partial view if it is bigger than available space */ | 1779 | /* Use a partial view if it is bigger than available space */ |
| 1805 | chunk_size = MIN_CHUNK_PAGES; | 1780 | chunk_size = MIN_CHUNK_PAGES; |
| 1806 | if (i915_gem_object_is_tiled(obj)) | 1781 | if (i915_gem_object_is_tiled(obj)) |
| 1807 | chunk_size = max(chunk_size, tile_row_pages(obj)); | 1782 | chunk_size = roundup(chunk_size, tile_row_pages(obj)); |
| 1808 | 1783 | ||
| 1809 | memset(&view, 0, sizeof(view)); | 1784 | memset(&view, 0, sizeof(view)); |
| 1810 | view.type = I915_GGTT_VIEW_PARTIAL; | 1785 | view.type = I915_GGTT_VIEW_PARTIAL; |
| @@ -1839,22 +1814,25 @@ int i915_gem_fault(struct vm_area_struct *area, struct vm_fault *vmf) | |||
| 1839 | if (ret) | 1814 | if (ret) |
| 1840 | goto err_unpin; | 1815 | goto err_unpin; |
| 1841 | 1816 | ||
| 1817 | /* Mark as being mmapped into userspace for later revocation */ | ||
| 1818 | assert_rpm_wakelock_held(dev_priv); | ||
| 1819 | if (list_empty(&obj->userfault_link)) | ||
| 1820 | list_add(&obj->userfault_link, &dev_priv->mm.userfault_list); | ||
| 1821 | |||
| 1842 | /* Finally, remap it using the new GTT offset */ | 1822 | /* Finally, remap it using the new GTT offset */ |
| 1843 | ret = remap_io_mapping(area, | 1823 | ret = remap_io_mapping(area, |
| 1844 | area->vm_start + (vma->ggtt_view.params.partial.offset << PAGE_SHIFT), | 1824 | area->vm_start + (vma->ggtt_view.params.partial.offset << PAGE_SHIFT), |
| 1845 | (ggtt->mappable_base + vma->node.start) >> PAGE_SHIFT, | 1825 | (ggtt->mappable_base + vma->node.start) >> PAGE_SHIFT, |
| 1846 | min_t(u64, vma->size, area->vm_end - area->vm_start), | 1826 | min_t(u64, vma->size, area->vm_end - area->vm_start), |
| 1847 | &ggtt->mappable); | 1827 | &ggtt->mappable); |
| 1848 | if (ret) | ||
| 1849 | goto err_unpin; | ||
| 1850 | 1828 | ||
| 1851 | obj->fault_mappable = true; | ||
| 1852 | err_unpin: | 1829 | err_unpin: |
| 1853 | __i915_vma_unpin(vma); | 1830 | __i915_vma_unpin(vma); |
| 1854 | err_unlock: | 1831 | err_unlock: |
| 1855 | mutex_unlock(&dev->struct_mutex); | 1832 | mutex_unlock(&dev->struct_mutex); |
| 1856 | err_rpm: | 1833 | err_rpm: |
| 1857 | intel_runtime_pm_put(dev_priv); | 1834 | intel_runtime_pm_put(dev_priv); |
| 1835 | i915_gem_object_unpin_pages(obj); | ||
| 1858 | err: | 1836 | err: |
| 1859 | switch (ret) { | 1837 | switch (ret) { |
| 1860 | case -EIO: | 1838 | case -EIO: |
| @@ -1916,15 +1894,23 @@ err: | |||
| 1916 | void | 1894 | void |
| 1917 | i915_gem_release_mmap(struct drm_i915_gem_object *obj) | 1895 | i915_gem_release_mmap(struct drm_i915_gem_object *obj) |
| 1918 | { | 1896 | { |
| 1897 | struct drm_i915_private *i915 = to_i915(obj->base.dev); | ||
| 1898 | |||
| 1919 | /* Serialisation between user GTT access and our code depends upon | 1899 | /* Serialisation between user GTT access and our code depends upon |
| 1920 | * revoking the CPU's PTE whilst the mutex is held. The next user | 1900 | * revoking the CPU's PTE whilst the mutex is held. The next user |
| 1921 | * pagefault then has to wait until we release the mutex. | 1901 | * pagefault then has to wait until we release the mutex. |
| 1902 | * | ||
| 1903 | * Note that RPM complicates somewhat by adding an additional | ||
| 1904 | * requirement that operations to the GGTT be made holding the RPM | ||
| 1905 | * wakeref. | ||
| 1922 | */ | 1906 | */ |
| 1923 | lockdep_assert_held(&obj->base.dev->struct_mutex); | 1907 | lockdep_assert_held(&i915->drm.struct_mutex); |
| 1908 | intel_runtime_pm_get(i915); | ||
| 1924 | 1909 | ||
| 1925 | if (!obj->fault_mappable) | 1910 | if (list_empty(&obj->userfault_link)) |
| 1926 | return; | 1911 | goto out; |
| 1927 | 1912 | ||
| 1913 | list_del_init(&obj->userfault_link); | ||
| 1928 | drm_vma_node_unmap(&obj->base.vma_node, | 1914 | drm_vma_node_unmap(&obj->base.vma_node, |
| 1929 | obj->base.dev->anon_inode->i_mapping); | 1915 | obj->base.dev->anon_inode->i_mapping); |
| 1930 | 1916 | ||
| @@ -1937,16 +1923,45 @@ i915_gem_release_mmap(struct drm_i915_gem_object *obj) | |||
| 1937 | */ | 1923 | */ |
| 1938 | wmb(); | 1924 | wmb(); |
| 1939 | 1925 | ||
| 1940 | obj->fault_mappable = false; | 1926 | out: |
| 1927 | intel_runtime_pm_put(i915); | ||
| 1941 | } | 1928 | } |
| 1942 | 1929 | ||
| 1943 | void | 1930 | void i915_gem_runtime_suspend(struct drm_i915_private *dev_priv) |
| 1944 | i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv) | ||
| 1945 | { | 1931 | { |
| 1946 | struct drm_i915_gem_object *obj; | 1932 | struct drm_i915_gem_object *obj, *on; |
| 1933 | int i; | ||
| 1947 | 1934 | ||
| 1948 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) | 1935 | /* |
| 1949 | i915_gem_release_mmap(obj); | 1936 | * Only called during RPM suspend. All users of the userfault_list |
| 1937 | * must be holding an RPM wakeref to ensure that this can not | ||
| 1938 | * run concurrently with themselves (and use the struct_mutex for | ||
| 1939 | * protection between themselves). | ||
| 1940 | */ | ||
| 1941 | |||
| 1942 | list_for_each_entry_safe(obj, on, | ||
| 1943 | &dev_priv->mm.userfault_list, userfault_link) { | ||
| 1944 | list_del_init(&obj->userfault_link); | ||
| 1945 | drm_vma_node_unmap(&obj->base.vma_node, | ||
| 1946 | obj->base.dev->anon_inode->i_mapping); | ||
| 1947 | } | ||
| 1948 | |||
| 1949 | /* The fence will be lost when the device powers down. If any were | ||
| 1950 | * in use by hardware (i.e. they are pinned), we should not be powering | ||
| 1951 | * down! All other fences will be reacquired by the user upon waking. | ||
| 1952 | */ | ||
| 1953 | for (i = 0; i < dev_priv->num_fence_regs; i++) { | ||
| 1954 | struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; | ||
| 1955 | |||
| 1956 | if (WARN_ON(reg->pin_count)) | ||
| 1957 | continue; | ||
| 1958 | |||
| 1959 | if (!reg->vma) | ||
| 1960 | continue; | ||
| 1961 | |||
| 1962 | GEM_BUG_ON(!list_empty(®->vma->obj->userfault_link)); | ||
| 1963 | reg->dirty = true; | ||
| 1964 | } | ||
| 1950 | } | 1965 | } |
| 1951 | 1966 | ||
| 1952 | /** | 1967 | /** |
| @@ -2060,7 +2075,7 @@ i915_gem_mmap_gtt(struct drm_file *file, | |||
| 2060 | if (ret == 0) | 2075 | if (ret == 0) |
| 2061 | *offset = drm_vma_node_offset_addr(&obj->base.vma_node); | 2076 | *offset = drm_vma_node_offset_addr(&obj->base.vma_node); |
| 2062 | 2077 | ||
| 2063 | i915_gem_object_put_unlocked(obj); | 2078 | i915_gem_object_put(obj); |
| 2064 | return ret; | 2079 | return ret; |
| 2065 | } | 2080 | } |
| 2066 | 2081 | ||
| @@ -2103,16 +2118,18 @@ i915_gem_object_truncate(struct drm_i915_gem_object *obj) | |||
| 2103 | * backing pages, *now*. | 2118 | * backing pages, *now*. |
| 2104 | */ | 2119 | */ |
| 2105 | shmem_truncate_range(file_inode(obj->base.filp), 0, (loff_t)-1); | 2120 | shmem_truncate_range(file_inode(obj->base.filp), 0, (loff_t)-1); |
| 2106 | obj->madv = __I915_MADV_PURGED; | 2121 | obj->mm.madv = __I915_MADV_PURGED; |
| 2107 | } | 2122 | } |
| 2108 | 2123 | ||
| 2109 | /* Try to discard unwanted pages */ | 2124 | /* Try to discard unwanted pages */ |
| 2110 | static void | 2125 | void __i915_gem_object_invalidate(struct drm_i915_gem_object *obj) |
| 2111 | i915_gem_object_invalidate(struct drm_i915_gem_object *obj) | ||
| 2112 | { | 2126 | { |
| 2113 | struct address_space *mapping; | 2127 | struct address_space *mapping; |
| 2114 | 2128 | ||
| 2115 | switch (obj->madv) { | 2129 | lockdep_assert_held(&obj->mm.lock); |
| 2130 | GEM_BUG_ON(obj->mm.pages); | ||
| 2131 | |||
| 2132 | switch (obj->mm.madv) { | ||
| 2116 | case I915_MADV_DONTNEED: | 2133 | case I915_MADV_DONTNEED: |
| 2117 | i915_gem_object_truncate(obj); | 2134 | i915_gem_object_truncate(obj); |
| 2118 | case __I915_MADV_PURGED: | 2135 | case __I915_MADV_PURGED: |
| @@ -2127,82 +2144,83 @@ i915_gem_object_invalidate(struct drm_i915_gem_object *obj) | |||
| 2127 | } | 2144 | } |
| 2128 | 2145 | ||
| 2129 | static void | 2146 | static void |
| 2130 | i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj) | 2147 | i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj, |
| 2148 | struct sg_table *pages) | ||
| 2131 | { | 2149 | { |
| 2132 | struct sgt_iter sgt_iter; | 2150 | struct sgt_iter sgt_iter; |
| 2133 | struct page *page; | 2151 | struct page *page; |
| 2134 | int ret; | ||
| 2135 | 2152 | ||
| 2136 | BUG_ON(obj->madv == __I915_MADV_PURGED); | 2153 | __i915_gem_object_release_shmem(obj); |
| 2137 | 2154 | ||
| 2138 | ret = i915_gem_object_set_to_cpu_domain(obj, true); | 2155 | i915_gem_gtt_finish_pages(obj, pages); |
| 2139 | if (WARN_ON(ret)) { | ||
| 2140 | /* In the event of a disaster, abandon all caches and | ||
| 2141 | * hope for the best. | ||
| 2142 | */ | ||
| 2143 | i915_gem_clflush_object(obj, true); | ||
| 2144 | obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU; | ||
| 2145 | } | ||
| 2146 | |||
| 2147 | i915_gem_gtt_finish_object(obj); | ||
| 2148 | 2156 | ||
| 2149 | if (i915_gem_object_needs_bit17_swizzle(obj)) | 2157 | if (i915_gem_object_needs_bit17_swizzle(obj)) |
| 2150 | i915_gem_object_save_bit_17_swizzle(obj); | 2158 | i915_gem_object_save_bit_17_swizzle(obj, pages); |
| 2151 | |||
| 2152 | if (obj->madv == I915_MADV_DONTNEED) | ||
| 2153 | obj->dirty = 0; | ||
| 2154 | 2159 | ||
| 2155 | for_each_sgt_page(page, sgt_iter, obj->pages) { | 2160 | for_each_sgt_page(page, sgt_iter, pages) { |
| 2156 | if (obj->dirty) | 2161 | if (obj->mm.dirty) |
| 2157 | set_page_dirty(page); | 2162 | set_page_dirty(page); |
| 2158 | 2163 | ||
| 2159 | if (obj->madv == I915_MADV_WILLNEED) | 2164 | if (obj->mm.madv == I915_MADV_WILLNEED) |
| 2160 | mark_page_accessed(page); | 2165 | mark_page_accessed(page); |
| 2161 | 2166 | ||
| 2162 | put_page(page); | 2167 | put_page(page); |
| 2163 | } | 2168 | } |
| 2164 | obj->dirty = 0; | 2169 | obj->mm.dirty = false; |
| 2165 | 2170 | ||
| 2166 | sg_free_table(obj->pages); | 2171 | sg_free_table(pages); |
| 2167 | kfree(obj->pages); | 2172 | kfree(pages); |
| 2168 | } | 2173 | } |
| 2169 | 2174 | ||
| 2170 | int | 2175 | static void __i915_gem_object_reset_page_iter(struct drm_i915_gem_object *obj) |
| 2171 | i915_gem_object_put_pages(struct drm_i915_gem_object *obj) | ||
| 2172 | { | 2176 | { |
| 2173 | const struct drm_i915_gem_object_ops *ops = obj->ops; | 2177 | struct radix_tree_iter iter; |
| 2178 | void **slot; | ||
| 2174 | 2179 | ||
| 2175 | if (obj->pages == NULL) | 2180 | radix_tree_for_each_slot(slot, &obj->mm.get_page.radix, &iter, 0) |
| 2176 | return 0; | 2181 | radix_tree_delete(&obj->mm.get_page.radix, iter.index); |
| 2182 | } | ||
| 2177 | 2183 | ||
| 2178 | if (obj->pages_pin_count) | 2184 | void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj, |
| 2179 | return -EBUSY; | 2185 | enum i915_mm_subclass subclass) |
| 2186 | { | ||
| 2187 | struct sg_table *pages; | ||
| 2188 | |||
| 2189 | if (i915_gem_object_has_pinned_pages(obj)) | ||
| 2190 | return; | ||
| 2180 | 2191 | ||
| 2181 | GEM_BUG_ON(obj->bind_count); | 2192 | GEM_BUG_ON(obj->bind_count); |
| 2193 | if (!READ_ONCE(obj->mm.pages)) | ||
| 2194 | return; | ||
| 2195 | |||
| 2196 | /* May be called by shrinker from within get_pages() (on another bo) */ | ||
| 2197 | mutex_lock_nested(&obj->mm.lock, subclass); | ||
| 2198 | if (unlikely(atomic_read(&obj->mm.pages_pin_count))) | ||
| 2199 | goto unlock; | ||
| 2182 | 2200 | ||
| 2183 | /* ->put_pages might need to allocate memory for the bit17 swizzle | 2201 | /* ->put_pages might need to allocate memory for the bit17 swizzle |
| 2184 | * array, hence protect them from being reaped by removing them from gtt | 2202 | * array, hence protect them from being reaped by removing them from gtt |
| 2185 | * lists early. */ | 2203 | * lists early. */ |
| 2186 | list_del(&obj->global_list); | 2204 | pages = fetch_and_zero(&obj->mm.pages); |
| 2205 | GEM_BUG_ON(!pages); | ||
| 2187 | 2206 | ||
| 2188 | if (obj->mapping) { | 2207 | if (obj->mm.mapping) { |
| 2189 | void *ptr; | 2208 | void *ptr; |
| 2190 | 2209 | ||
| 2191 | ptr = ptr_mask_bits(obj->mapping); | 2210 | ptr = ptr_mask_bits(obj->mm.mapping); |
| 2192 | if (is_vmalloc_addr(ptr)) | 2211 | if (is_vmalloc_addr(ptr)) |
| 2193 | vunmap(ptr); | 2212 | vunmap(ptr); |
| 2194 | else | 2213 | else |
| 2195 | kunmap(kmap_to_page(ptr)); | 2214 | kunmap(kmap_to_page(ptr)); |
| 2196 | 2215 | ||
| 2197 | obj->mapping = NULL; | 2216 | obj->mm.mapping = NULL; |
| 2198 | } | 2217 | } |
| 2199 | 2218 | ||
| 2200 | ops->put_pages(obj); | 2219 | __i915_gem_object_reset_page_iter(obj); |
| 2201 | obj->pages = NULL; | ||
| 2202 | 2220 | ||
| 2203 | i915_gem_object_invalidate(obj); | 2221 | obj->ops->put_pages(obj, pages); |
| 2204 | 2222 | unlock: | |
| 2205 | return 0; | 2223 | mutex_unlock(&obj->mm.lock); |
| 2206 | } | 2224 | } |
| 2207 | 2225 | ||
| 2208 | static unsigned int swiotlb_max_size(void) | 2226 | static unsigned int swiotlb_max_size(void) |
| @@ -2214,7 +2232,7 @@ static unsigned int swiotlb_max_size(void) | |||
| 2214 | #endif | 2232 | #endif |
| 2215 | } | 2233 | } |
| 2216 | 2234 | ||
| 2217 | static int | 2235 | static struct sg_table * |
| 2218 | i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) | 2236 | i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) |
| 2219 | { | 2237 | { |
| 2220 | struct drm_i915_private *dev_priv = to_i915(obj->base.dev); | 2238 | struct drm_i915_private *dev_priv = to_i915(obj->base.dev); |
| @@ -2233,8 +2251,8 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) | |||
| 2233 | * wasn't in the GTT, there shouldn't be any way it could have been in | 2251 | * wasn't in the GTT, there shouldn't be any way it could have been in |
| 2234 | * a GPU cache | 2252 | * a GPU cache |
| 2235 | */ | 2253 | */ |
| 2236 | BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS); | 2254 | GEM_BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS); |
| 2237 | BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS); | 2255 | GEM_BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS); |
| 2238 | 2256 | ||
| 2239 | max_segment = swiotlb_max_size(); | 2257 | max_segment = swiotlb_max_size(); |
| 2240 | if (!max_segment) | 2258 | if (!max_segment) |
| @@ -2242,12 +2260,12 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) | |||
| 2242 | 2260 | ||
| 2243 | st = kmalloc(sizeof(*st), GFP_KERNEL); | 2261 | st = kmalloc(sizeof(*st), GFP_KERNEL); |
| 2244 | if (st == NULL) | 2262 | if (st == NULL) |
| 2245 | return -ENOMEM; | 2263 | return ERR_PTR(-ENOMEM); |
| 2246 | 2264 | ||
| 2247 | page_count = obj->base.size / PAGE_SIZE; | 2265 | page_count = obj->base.size / PAGE_SIZE; |
| 2248 | if (sg_alloc_table(st, page_count, GFP_KERNEL)) { | 2266 | if (sg_alloc_table(st, page_count, GFP_KERNEL)) { |
| 2249 | kfree(st); | 2267 | kfree(st); |
| 2250 | return -ENOMEM; | 2268 | return ERR_PTR(-ENOMEM); |
| 2251 | } | 2269 | } |
| 2252 | 2270 | ||
| 2253 | /* Get the list of pages out of our struct file. They'll be pinned | 2271 | /* Get the list of pages out of our struct file. They'll be pinned |
| @@ -2298,20 +2316,15 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) | |||
| 2298 | } | 2316 | } |
| 2299 | if (sg) /* loop terminated early; short sg table */ | 2317 | if (sg) /* loop terminated early; short sg table */ |
| 2300 | sg_mark_end(sg); | 2318 | sg_mark_end(sg); |
| 2301 | obj->pages = st; | ||
| 2302 | 2319 | ||
| 2303 | ret = i915_gem_gtt_prepare_object(obj); | 2320 | ret = i915_gem_gtt_prepare_pages(obj, st); |
| 2304 | if (ret) | 2321 | if (ret) |
| 2305 | goto err_pages; | 2322 | goto err_pages; |
| 2306 | 2323 | ||
| 2307 | if (i915_gem_object_needs_bit17_swizzle(obj)) | 2324 | if (i915_gem_object_needs_bit17_swizzle(obj)) |
| 2308 | i915_gem_object_do_bit_17_swizzle(obj); | 2325 | i915_gem_object_do_bit_17_swizzle(obj, st); |
| 2309 | |||
| 2310 | if (i915_gem_object_is_tiled(obj) && | ||
| 2311 | dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) | ||
| 2312 | i915_gem_object_pin_pages(obj); | ||
| 2313 | 2326 | ||
| 2314 | return 0; | 2327 | return st; |
| 2315 | 2328 | ||
| 2316 | err_pages: | 2329 | err_pages: |
| 2317 | sg_mark_end(sg); | 2330 | sg_mark_end(sg); |
| @@ -2331,43 +2344,73 @@ err_pages: | |||
| 2331 | if (ret == -ENOSPC) | 2344 | if (ret == -ENOSPC) |
| 2332 | ret = -ENOMEM; | 2345 | ret = -ENOMEM; |
| 2333 | 2346 | ||
| 2334 | return ret; | 2347 | return ERR_PTR(ret); |
| 2335 | } | 2348 | } |
| 2336 | 2349 | ||
| 2337 | /* Ensure that the associated pages are gathered from the backing storage | 2350 | void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, |
| 2338 | * and pinned into our object. i915_gem_object_get_pages() may be called | 2351 | struct sg_table *pages) |
| 2339 | * multiple times before they are released by a single call to | ||
| 2340 | * i915_gem_object_put_pages() - once the pages are no longer referenced | ||
| 2341 | * either as a result of memory pressure (reaping pages under the shrinker) | ||
| 2342 | * or as the object is itself released. | ||
| 2343 | */ | ||
| 2344 | int | ||
| 2345 | i915_gem_object_get_pages(struct drm_i915_gem_object *obj) | ||
| 2346 | { | 2352 | { |
| 2347 | struct drm_i915_private *dev_priv = to_i915(obj->base.dev); | 2353 | lockdep_assert_held(&obj->mm.lock); |
| 2348 | const struct drm_i915_gem_object_ops *ops = obj->ops; | ||
| 2349 | int ret; | ||
| 2350 | 2354 | ||
| 2351 | if (obj->pages) | 2355 | obj->mm.get_page.sg_pos = pages->sgl; |
| 2352 | return 0; | 2356 | obj->mm.get_page.sg_idx = 0; |
| 2357 | |||
| 2358 | obj->mm.pages = pages; | ||
| 2359 | |||
| 2360 | if (i915_gem_object_is_tiled(obj) && | ||
| 2361 | to_i915(obj->base.dev)->quirks & QUIRK_PIN_SWIZZLED_PAGES) { | ||
| 2362 | GEM_BUG_ON(obj->mm.quirked); | ||
| 2363 | __i915_gem_object_pin_pages(obj); | ||
| 2364 | obj->mm.quirked = true; | ||
| 2365 | } | ||
| 2366 | } | ||
| 2353 | 2367 | ||
| 2354 | if (obj->madv != I915_MADV_WILLNEED) { | 2368 | static int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj) |
| 2369 | { | ||
| 2370 | struct sg_table *pages; | ||
| 2371 | |||
| 2372 | GEM_BUG_ON(i915_gem_object_has_pinned_pages(obj)); | ||
| 2373 | |||
| 2374 | if (unlikely(obj->mm.madv != I915_MADV_WILLNEED)) { | ||
| 2355 | DRM_DEBUG("Attempting to obtain a purgeable object\n"); | 2375 | DRM_DEBUG("Attempting to obtain a purgeable object\n"); |
| 2356 | return -EFAULT; | 2376 | return -EFAULT; |
| 2357 | } | 2377 | } |
| 2358 | 2378 | ||
| 2359 | BUG_ON(obj->pages_pin_count); | 2379 | pages = obj->ops->get_pages(obj); |
| 2380 | if (unlikely(IS_ERR(pages))) | ||
| 2381 | return PTR_ERR(pages); | ||
| 2360 | 2382 | ||
| 2361 | ret = ops->get_pages(obj); | 2383 | __i915_gem_object_set_pages(obj, pages); |
| 2362 | if (ret) | 2384 | return 0; |
| 2363 | return ret; | 2385 | } |
| 2364 | 2386 | ||
| 2365 | list_add_tail(&obj->global_list, &dev_priv->mm.unbound_list); | 2387 | /* Ensure that the associated pages are gathered from the backing storage |
| 2388 | * and pinned into our object. i915_gem_object_pin_pages() may be called | ||
| 2389 | * multiple times before they are released by a single call to | ||
| 2390 | * i915_gem_object_unpin_pages() - once the pages are no longer referenced | ||
| 2391 | * either as a result of memory pressure (reaping pages under the shrinker) | ||
| 2392 | * or as the object is itself released. | ||
| 2393 | */ | ||
| 2394 | int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj) | ||
| 2395 | { | ||
| 2396 | int err; | ||
| 2366 | 2397 | ||
| 2367 | obj->get_page.sg = obj->pages->sgl; | 2398 | err = mutex_lock_interruptible(&obj->mm.lock); |
| 2368 | obj->get_page.last = 0; | 2399 | if (err) |
| 2400 | return err; | ||
| 2369 | 2401 | ||
| 2370 | return 0; | 2402 | if (unlikely(!obj->mm.pages)) { |
| 2403 | err = ____i915_gem_object_get_pages(obj); | ||
| 2404 | if (err) | ||
| 2405 | goto unlock; | ||
| 2406 | |||
| 2407 | smp_mb__before_atomic(); | ||
| 2408 | } | ||
| 2409 | atomic_inc(&obj->mm.pages_pin_count); | ||
| 2410 | |||
| 2411 | unlock: | ||
| 2412 | mutex_unlock(&obj->mm.lock); | ||
| 2413 | return err; | ||
| 2371 | } | 2414 | } |
| 2372 | 2415 | ||
| 2373 | /* The 'mapping' part of i915_gem_object_pin_map() below */ | 2416 | /* The 'mapping' part of i915_gem_object_pin_map() below */ |
| @@ -2375,7 +2418,7 @@ static void *i915_gem_object_map(const struct drm_i915_gem_object *obj, | |||
| 2375 | enum i915_map_type type) | 2418 | enum i915_map_type type) |
| 2376 | { | 2419 | { |
| 2377 | unsigned long n_pages = obj->base.size >> PAGE_SHIFT; | 2420 | unsigned long n_pages = obj->base.size >> PAGE_SHIFT; |
| 2378 | struct sg_table *sgt = obj->pages; | 2421 | struct sg_table *sgt = obj->mm.pages; |
| 2379 | struct sgt_iter sgt_iter; | 2422 | struct sgt_iter sgt_iter; |
| 2380 | struct page *page; | 2423 | struct page *page; |
| 2381 | struct page *stack_pages[32]; | 2424 | struct page *stack_pages[32]; |
| @@ -2426,21 +2469,31 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, | |||
| 2426 | void *ptr; | 2469 | void *ptr; |
| 2427 | int ret; | 2470 | int ret; |
| 2428 | 2471 | ||
| 2429 | lockdep_assert_held(&obj->base.dev->struct_mutex); | ||
| 2430 | GEM_BUG_ON(!i915_gem_object_has_struct_page(obj)); | 2472 | GEM_BUG_ON(!i915_gem_object_has_struct_page(obj)); |
| 2431 | 2473 | ||
| 2432 | ret = i915_gem_object_get_pages(obj); | 2474 | ret = mutex_lock_interruptible(&obj->mm.lock); |
| 2433 | if (ret) | 2475 | if (ret) |
| 2434 | return ERR_PTR(ret); | 2476 | return ERR_PTR(ret); |
| 2435 | 2477 | ||
| 2436 | i915_gem_object_pin_pages(obj); | 2478 | pinned = true; |
| 2437 | pinned = obj->pages_pin_count > 1; | 2479 | if (!atomic_inc_not_zero(&obj->mm.pages_pin_count)) { |
| 2480 | if (unlikely(!obj->mm.pages)) { | ||
| 2481 | ret = ____i915_gem_object_get_pages(obj); | ||
| 2482 | if (ret) | ||
| 2483 | goto err_unlock; | ||
| 2484 | |||
| 2485 | smp_mb__before_atomic(); | ||
| 2486 | } | ||
| 2487 | atomic_inc(&obj->mm.pages_pin_count); | ||
| 2488 | pinned = false; | ||
| 2489 | } | ||
| 2490 | GEM_BUG_ON(!obj->mm.pages); | ||
| 2438 | 2491 | ||
| 2439 | ptr = ptr_unpack_bits(obj->mapping, has_type); | 2492 | ptr = ptr_unpack_bits(obj->mm.mapping, has_type); |
| 2440 | if (ptr && has_type != type) { | 2493 | if (ptr && has_type != type) { |
| 2441 | if (pinned) { | 2494 | if (pinned) { |
| 2442 | ret = -EBUSY; | 2495 | ret = -EBUSY; |
| 2443 | goto err; | 2496 | goto err_unpin; |
| 2444 | } | 2497 | } |
| 2445 | 2498 | ||
| 2446 | if (is_vmalloc_addr(ptr)) | 2499 | if (is_vmalloc_addr(ptr)) |
| @@ -2448,59 +2501,28 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, | |||
| 2448 | else | 2501 | else |
| 2449 | kunmap(kmap_to_page(ptr)); | 2502 | kunmap(kmap_to_page(ptr)); |
| 2450 | 2503 | ||
| 2451 | ptr = obj->mapping = NULL; | 2504 | ptr = obj->mm.mapping = NULL; |
| 2452 | } | 2505 | } |
| 2453 | 2506 | ||
| 2454 | if (!ptr) { | 2507 | if (!ptr) { |
| 2455 | ptr = i915_gem_object_map(obj, type); | 2508 | ptr = i915_gem_object_map(obj, type); |
| 2456 | if (!ptr) { | 2509 | if (!ptr) { |
| 2457 | ret = -ENOMEM; | 2510 | ret = -ENOMEM; |
| 2458 | goto err; | 2511 | goto err_unpin; |
| 2459 | } | 2512 | } |
| 2460 | 2513 | ||
| 2461 | obj->mapping = ptr_pack_bits(ptr, type); | 2514 | obj->mm.mapping = ptr_pack_bits(ptr, type); |
| 2462 | } | 2515 | } |
| 2463 | 2516 | ||
| 2517 | out_unlock: | ||
| 2518 | mutex_unlock(&obj->mm.lock); | ||
| 2464 | return ptr; | 2519 | return ptr; |
| 2465 | 2520 | ||
| 2466 | err: | 2521 | err_unpin: |
| 2467 | i915_gem_object_unpin_pages(obj); | 2522 | atomic_dec(&obj->mm.pages_pin_count); |
| 2468 | return ERR_PTR(ret); | 2523 | err_unlock: |
| 2469 | } | 2524 | ptr = ERR_PTR(ret); |
| 2470 | 2525 | goto out_unlock; | |
| 2471 | static void | ||
| 2472 | i915_gem_object_retire__write(struct i915_gem_active *active, | ||
| 2473 | struct drm_i915_gem_request *request) | ||
| 2474 | { | ||
| 2475 | struct drm_i915_gem_object *obj = | ||
| 2476 | container_of(active, struct drm_i915_gem_object, last_write); | ||
| 2477 | |||
| 2478 | intel_fb_obj_flush(obj, true, ORIGIN_CS); | ||
| 2479 | } | ||
| 2480 | |||
| 2481 | static void | ||
| 2482 | i915_gem_object_retire__read(struct i915_gem_active *active, | ||
| 2483 | struct drm_i915_gem_request *request) | ||
| 2484 | { | ||
| 2485 | int idx = request->engine->id; | ||
| 2486 | struct drm_i915_gem_object *obj = | ||
| 2487 | container_of(active, struct drm_i915_gem_object, last_read[idx]); | ||
| 2488 | |||
| 2489 | GEM_BUG_ON(!i915_gem_object_has_active_engine(obj, idx)); | ||
| 2490 | |||
| 2491 | i915_gem_object_clear_active(obj, idx); | ||
| 2492 | if (i915_gem_object_is_active(obj)) | ||
| 2493 | return; | ||
| 2494 | |||
| 2495 | /* Bump our place on the bound list to keep it roughly in LRU order | ||
| 2496 | * so that we don't steal from recently used but inactive objects | ||
| 2497 | * (unless we are forced to ofc!) | ||
| 2498 | */ | ||
| 2499 | if (obj->bind_count) | ||
| 2500 | list_move_tail(&obj->global_list, | ||
| 2501 | &request->i915->mm.bound_list); | ||
| 2502 | |||
| 2503 | i915_gem_object_put(obj); | ||
| 2504 | } | 2526 | } |
| 2505 | 2527 | ||
| 2506 | static bool i915_context_is_banned(const struct i915_gem_context *ctx) | 2528 | static bool i915_context_is_banned(const struct i915_gem_context *ctx) |
| @@ -2547,13 +2569,10 @@ i915_gem_find_active_request(struct intel_engine_cs *engine) | |||
| 2547 | * extra delay for a recent interrupt is pointless. Hence, we do | 2569 | * extra delay for a recent interrupt is pointless. Hence, we do |
| 2548 | * not need an engine->irq_seqno_barrier() before the seqno reads. | 2570 | * not need an engine->irq_seqno_barrier() before the seqno reads. |
| 2549 | */ | 2571 | */ |
| 2550 | list_for_each_entry(request, &engine->request_list, link) { | 2572 | list_for_each_entry(request, &engine->timeline->requests, link) { |
| 2551 | if (i915_gem_request_completed(request)) | 2573 | if (__i915_gem_request_completed(request)) |
| 2552 | continue; | 2574 | continue; |
| 2553 | 2575 | ||
| 2554 | if (!i915_sw_fence_done(&request->submit)) | ||
| 2555 | break; | ||
| 2556 | |||
| 2557 | return request; | 2576 | return request; |
| 2558 | } | 2577 | } |
| 2559 | 2578 | ||
| @@ -2581,6 +2600,7 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine) | |||
| 2581 | { | 2600 | { |
| 2582 | struct drm_i915_gem_request *request; | 2601 | struct drm_i915_gem_request *request; |
| 2583 | struct i915_gem_context *incomplete_ctx; | 2602 | struct i915_gem_context *incomplete_ctx; |
| 2603 | struct intel_timeline *timeline; | ||
| 2584 | bool ring_hung; | 2604 | bool ring_hung; |
| 2585 | 2605 | ||
| 2586 | if (engine->irq_seqno_barrier) | 2606 | if (engine->irq_seqno_barrier) |
| @@ -2599,7 +2619,7 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine) | |||
| 2599 | return; | 2619 | return; |
| 2600 | 2620 | ||
| 2601 | DRM_DEBUG_DRIVER("resetting %s to restart from tail of request 0x%x\n", | 2621 | DRM_DEBUG_DRIVER("resetting %s to restart from tail of request 0x%x\n", |
| 2602 | engine->name, request->fence.seqno); | 2622 | engine->name, request->global_seqno); |
| 2603 | 2623 | ||
| 2604 | /* Setup the CS to resume from the breadcrumb of the hung request */ | 2624 | /* Setup the CS to resume from the breadcrumb of the hung request */ |
| 2605 | engine->reset_hw(engine, request); | 2625 | engine->reset_hw(engine, request); |
| @@ -2616,9 +2636,13 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine) | |||
| 2616 | if (i915_gem_context_is_default(incomplete_ctx)) | 2636 | if (i915_gem_context_is_default(incomplete_ctx)) |
| 2617 | return; | 2637 | return; |
| 2618 | 2638 | ||
| 2619 | list_for_each_entry_continue(request, &engine->request_list, link) | 2639 | list_for_each_entry_continue(request, &engine->timeline->requests, link) |
| 2620 | if (request->ctx == incomplete_ctx) | 2640 | if (request->ctx == incomplete_ctx) |
| 2621 | reset_request(request); | 2641 | reset_request(request); |
| 2642 | |||
| 2643 | timeline = i915_gem_context_lookup_timeline(incomplete_ctx, engine); | ||
| 2644 | list_for_each_entry(request, &timeline->requests, link) | ||
| 2645 | reset_request(request); | ||
| 2622 | } | 2646 | } |
| 2623 | 2647 | ||
| 2624 | void i915_gem_reset(struct drm_i915_private *dev_priv) | 2648 | void i915_gem_reset(struct drm_i915_private *dev_priv) |
| @@ -2626,6 +2650,8 @@ void i915_gem_reset(struct drm_i915_private *dev_priv) | |||
| 2626 | struct intel_engine_cs *engine; | 2650 | struct intel_engine_cs *engine; |
| 2627 | enum intel_engine_id id; | 2651 | enum intel_engine_id id; |
| 2628 | 2652 | ||
| 2653 | lockdep_assert_held(&dev_priv->drm.struct_mutex); | ||
| 2654 | |||
| 2629 | i915_gem_retire_requests(dev_priv); | 2655 | i915_gem_retire_requests(dev_priv); |
| 2630 | 2656 | ||
| 2631 | for_each_engine(engine, dev_priv, id) | 2657 | for_each_engine(engine, dev_priv, id) |
| @@ -2653,7 +2679,8 @@ static void i915_gem_cleanup_engine(struct intel_engine_cs *engine) | |||
| 2653 | * (lockless) lookup doesn't try and wait upon the request as we | 2679 | * (lockless) lookup doesn't try and wait upon the request as we |
| 2654 | * reset it. | 2680 | * reset it. |
| 2655 | */ | 2681 | */ |
| 2656 | intel_engine_init_seqno(engine, engine->last_submitted_seqno); | 2682 | intel_engine_init_global_seqno(engine, |
| 2683 | intel_engine_last_submit(engine)); | ||
| 2657 | 2684 | ||
| 2658 | /* | 2685 | /* |
| 2659 | * Clear the execlists queue up before freeing the requests, as those | 2686 | * Clear the execlists queue up before freeing the requests, as those |
| @@ -2669,8 +2696,6 @@ static void i915_gem_cleanup_engine(struct intel_engine_cs *engine) | |||
| 2669 | memset(engine->execlist_port, 0, sizeof(engine->execlist_port)); | 2696 | memset(engine->execlist_port, 0, sizeof(engine->execlist_port)); |
| 2670 | spin_unlock(&engine->execlist_lock); | 2697 | spin_unlock(&engine->execlist_lock); |
| 2671 | } | 2698 | } |
| 2672 | |||
| 2673 | engine->i915->gt.active_engines &= ~intel_engine_flag(engine); | ||
| 2674 | } | 2699 | } |
| 2675 | 2700 | ||
| 2676 | void i915_gem_set_wedged(struct drm_i915_private *dev_priv) | 2701 | void i915_gem_set_wedged(struct drm_i915_private *dev_priv) |
| @@ -2727,7 +2752,14 @@ i915_gem_idle_work_handler(struct work_struct *work) | |||
| 2727 | if (!READ_ONCE(dev_priv->gt.awake)) | 2752 | if (!READ_ONCE(dev_priv->gt.awake)) |
| 2728 | return; | 2753 | return; |
| 2729 | 2754 | ||
| 2730 | if (READ_ONCE(dev_priv->gt.active_engines)) | 2755 | /* |
| 2756 | * Wait for last execlists context complete, but bail out in case a | ||
| 2757 | * new request is submitted. | ||
| 2758 | */ | ||
| 2759 | wait_for(READ_ONCE(dev_priv->gt.active_requests) || | ||
| 2760 | intel_execlists_idle(dev_priv), 10); | ||
| 2761 | |||
| 2762 | if (READ_ONCE(dev_priv->gt.active_requests)) | ||
| 2731 | return; | 2763 | return; |
| 2732 | 2764 | ||
| 2733 | rearm_hangcheck = | 2765 | rearm_hangcheck = |
| @@ -2741,9 +2773,19 @@ i915_gem_idle_work_handler(struct work_struct *work) | |||
| 2741 | goto out_rearm; | 2773 | goto out_rearm; |
| 2742 | } | 2774 | } |
| 2743 | 2775 | ||
| 2744 | if (dev_priv->gt.active_engines) | 2776 | /* |
| 2777 | * New request retired after this work handler started, extend active | ||
| 2778 | * period until next instance of the work. | ||
| 2779 | */ | ||
| 2780 | if (work_pending(work)) | ||
| 2745 | goto out_unlock; | 2781 | goto out_unlock; |
| 2746 | 2782 | ||
| 2783 | if (dev_priv->gt.active_requests) | ||
| 2784 | goto out_unlock; | ||
| 2785 | |||
| 2786 | if (wait_for(intel_execlists_idle(dev_priv), 10)) | ||
| 2787 | DRM_ERROR("Timeout waiting for engines to idle\n"); | ||
| 2788 | |||
| 2747 | for_each_engine(engine, dev_priv, id) | 2789 | for_each_engine(engine, dev_priv, id) |
| 2748 | i915_gem_batch_pool_fini(&engine->batch_pool); | 2790 | i915_gem_batch_pool_fini(&engine->batch_pool); |
| 2749 | 2791 | ||
| @@ -2774,9 +2816,26 @@ void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file) | |||
| 2774 | list_for_each_entry_safe(vma, vn, &obj->vma_list, obj_link) | 2816 | list_for_each_entry_safe(vma, vn, &obj->vma_list, obj_link) |
| 2775 | if (vma->vm->file == fpriv) | 2817 | if (vma->vm->file == fpriv) |
| 2776 | i915_vma_close(vma); | 2818 | i915_vma_close(vma); |
| 2819 | |||
| 2820 | if (i915_gem_object_is_active(obj) && | ||
| 2821 | !i915_gem_object_has_active_reference(obj)) { | ||
| 2822 | i915_gem_object_set_active_reference(obj); | ||
| 2823 | i915_gem_object_get(obj); | ||
| 2824 | } | ||
| 2777 | mutex_unlock(&obj->base.dev->struct_mutex); | 2825 | mutex_unlock(&obj->base.dev->struct_mutex); |
| 2778 | } | 2826 | } |
| 2779 | 2827 | ||
| 2828 | static unsigned long to_wait_timeout(s64 timeout_ns) | ||
| 2829 | { | ||
| 2830 | if (timeout_ns < 0) | ||
| 2831 | return MAX_SCHEDULE_TIMEOUT; | ||
| 2832 | |||
| 2833 | if (timeout_ns == 0) | ||
| 2834 | return 0; | ||
| 2835 | |||
| 2836 | return nsecs_to_jiffies_timeout(timeout_ns); | ||
| 2837 | } | ||
| 2838 | |||
| 2780 | /** | 2839 | /** |
| 2781 | * i915_gem_wait_ioctl - implements DRM_IOCTL_I915_GEM_WAIT | 2840 | * i915_gem_wait_ioctl - implements DRM_IOCTL_I915_GEM_WAIT |
| 2782 | * @dev: drm device pointer | 2841 | * @dev: drm device pointer |
| @@ -2805,10 +2864,9 @@ int | |||
| 2805 | i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) | 2864 | i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) |
| 2806 | { | 2865 | { |
| 2807 | struct drm_i915_gem_wait *args = data; | 2866 | struct drm_i915_gem_wait *args = data; |
| 2808 | struct intel_rps_client *rps = to_rps_client(file); | ||
| 2809 | struct drm_i915_gem_object *obj; | 2867 | struct drm_i915_gem_object *obj; |
| 2810 | unsigned long active; | 2868 | ktime_t start; |
| 2811 | int idx, ret = 0; | 2869 | long ret; |
| 2812 | 2870 | ||
| 2813 | if (args->flags != 0) | 2871 | if (args->flags != 0) |
| 2814 | return -EINVAL; | 2872 | return -EINVAL; |
| @@ -2817,17 +2875,20 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) | |||
| 2817 | if (!obj) | 2875 | if (!obj) |
| 2818 | return -ENOENT; | 2876 | return -ENOENT; |
| 2819 | 2877 | ||
| 2820 | active = __I915_BO_ACTIVE(obj); | 2878 | start = ktime_get(); |
| 2821 | for_each_active(active, idx) { | 2879 | |
| 2822 | s64 *timeout = args->timeout_ns >= 0 ? &args->timeout_ns : NULL; | 2880 | ret = i915_gem_object_wait(obj, |
| 2823 | ret = i915_gem_active_wait_unlocked(&obj->last_read[idx], | 2881 | I915_WAIT_INTERRUPTIBLE | I915_WAIT_ALL, |
| 2824 | I915_WAIT_INTERRUPTIBLE, | 2882 | to_wait_timeout(args->timeout_ns), |
| 2825 | timeout, rps); | 2883 | to_rps_client(file)); |
| 2826 | if (ret) | 2884 | |
| 2827 | break; | 2885 | if (args->timeout_ns > 0) { |
| 2886 | args->timeout_ns -= ktime_to_ns(ktime_sub(ktime_get(), start)); | ||
| 2887 | if (args->timeout_ns < 0) | ||
| 2888 | args->timeout_ns = 0; | ||
| 2828 | } | 2889 | } |
| 2829 | 2890 | ||
| 2830 | i915_gem_object_put_unlocked(obj); | 2891 | i915_gem_object_put(obj); |
| 2831 | return ret; | 2892 | return ret; |
| 2832 | } | 2893 | } |
| 2833 | 2894 | ||
| @@ -2848,6 +2909,8 @@ int i915_vma_unbind(struct i915_vma *vma) | |||
| 2848 | unsigned long active; | 2909 | unsigned long active; |
| 2849 | int ret; | 2910 | int ret; |
| 2850 | 2911 | ||
| 2912 | lockdep_assert_held(&obj->base.dev->struct_mutex); | ||
| 2913 | |||
| 2851 | /* First wait upon any activity as retiring the request may | 2914 | /* First wait upon any activity as retiring the request may |
| 2852 | * have side-effects such as unpinning or even unbinding this vma. | 2915 | * have side-effects such as unpinning or even unbinding this vma. |
| 2853 | */ | 2916 | */ |
| @@ -2859,6 +2922,13 @@ int i915_vma_unbind(struct i915_vma *vma) | |||
| 2859 | * In order to prevent it from being recursively closed, | 2922 | * In order to prevent it from being recursively closed, |
| 2860 | * take a pin on the vma so that the second unbind is | 2923 | * take a pin on the vma so that the second unbind is |
| 2861 | * aborted. | 2924 | * aborted. |
| 2925 | * | ||
| 2926 | * Even more scary is that the retire callback may free | ||
| 2927 | * the object (last active vma). To prevent the explosion | ||
| 2928 | * we defer the actual object free to a worker that can | ||
| 2929 | * only proceed once it acquires the struct_mutex (which | ||
| 2930 | * we currently hold, therefore it cannot free this object | ||
| 2931 | * before we are finished). | ||
| 2862 | */ | 2932 | */ |
| 2863 | __i915_vma_pin(vma); | 2933 | __i915_vma_pin(vma); |
| 2864 | 2934 | ||
| @@ -2883,7 +2953,7 @@ int i915_vma_unbind(struct i915_vma *vma) | |||
| 2883 | goto destroy; | 2953 | goto destroy; |
| 2884 | 2954 | ||
| 2885 | GEM_BUG_ON(obj->bind_count == 0); | 2955 | GEM_BUG_ON(obj->bind_count == 0); |
| 2886 | GEM_BUG_ON(!obj->pages); | 2956 | GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); |
| 2887 | 2957 | ||
| 2888 | if (i915_vma_is_map_and_fenceable(vma)) { | 2958 | if (i915_vma_is_map_and_fenceable(vma)) { |
| 2889 | /* release the fence reg _after_ flushing */ | 2959 | /* release the fence reg _after_ flushing */ |
| @@ -2907,7 +2977,7 @@ int i915_vma_unbind(struct i915_vma *vma) | |||
| 2907 | drm_mm_remove_node(&vma->node); | 2977 | drm_mm_remove_node(&vma->node); |
| 2908 | list_move_tail(&vma->vm_link, &vma->vm->unbound_list); | 2978 | list_move_tail(&vma->vm_link, &vma->vm->unbound_list); |
| 2909 | 2979 | ||
| 2910 | if (vma->pages != obj->pages) { | 2980 | if (vma->pages != obj->mm.pages) { |
| 2911 | GEM_BUG_ON(!vma->pages); | 2981 | GEM_BUG_ON(!vma->pages); |
| 2912 | sg_free_table(vma->pages); | 2982 | sg_free_table(vma->pages); |
| 2913 | kfree(vma->pages); | 2983 | kfree(vma->pages); |
| @@ -2917,7 +2987,7 @@ int i915_vma_unbind(struct i915_vma *vma) | |||
| 2917 | /* Since the unbound list is global, only move to that list if | 2987 | /* Since the unbound list is global, only move to that list if |
| 2918 | * no more VMAs exist. */ | 2988 | * no more VMAs exist. */ |
| 2919 | if (--obj->bind_count == 0) | 2989 | if (--obj->bind_count == 0) |
| 2920 | list_move_tail(&obj->global_list, | 2990 | list_move_tail(&obj->global_link, |
| 2921 | &to_i915(obj->base.dev)->mm.unbound_list); | 2991 | &to_i915(obj->base.dev)->mm.unbound_list); |
| 2922 | 2992 | ||
| 2923 | /* And finally now the object is completely decoupled from this vma, | 2993 | /* And finally now the object is completely decoupled from this vma, |
| @@ -2933,18 +3003,26 @@ destroy: | |||
| 2933 | return 0; | 3003 | return 0; |
| 2934 | } | 3004 | } |
| 2935 | 3005 | ||
| 2936 | int i915_gem_wait_for_idle(struct drm_i915_private *dev_priv, | 3006 | static int wait_for_timeline(struct i915_gem_timeline *tl, unsigned int flags) |
| 2937 | unsigned int flags) | ||
| 2938 | { | 3007 | { |
| 2939 | struct intel_engine_cs *engine; | 3008 | int ret, i; |
| 2940 | enum intel_engine_id id; | ||
| 2941 | int ret; | ||
| 2942 | 3009 | ||
| 2943 | for_each_engine(engine, dev_priv, id) { | 3010 | for (i = 0; i < ARRAY_SIZE(tl->engine); i++) { |
| 2944 | if (engine->last_context == NULL) | 3011 | ret = i915_gem_active_wait(&tl->engine[i].last_request, flags); |
| 2945 | continue; | 3012 | if (ret) |
| 3013 | return ret; | ||
| 3014 | } | ||
| 3015 | |||
| 3016 | return 0; | ||
| 3017 | } | ||
| 2946 | 3018 | ||
| 2947 | ret = intel_engine_idle(engine, flags); | 3019 | int i915_gem_wait_for_idle(struct drm_i915_private *i915, unsigned int flags) |
| 3020 | { | ||
| 3021 | struct i915_gem_timeline *tl; | ||
| 3022 | int ret; | ||
| 3023 | |||
| 3024 | list_for_each_entry(tl, &i915->gt.timelines, link) { | ||
| 3025 | ret = wait_for_timeline(tl, flags); | ||
| 2948 | if (ret) | 3026 | if (ret) |
| 2949 | return ret; | 3027 | return ret; |
| 2950 | } | 3028 | } |
| @@ -3040,12 +3118,10 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags) | |||
| 3040 | return -E2BIG; | 3118 | return -E2BIG; |
| 3041 | } | 3119 | } |
| 3042 | 3120 | ||
| 3043 | ret = i915_gem_object_get_pages(obj); | 3121 | ret = i915_gem_object_pin_pages(obj); |
| 3044 | if (ret) | 3122 | if (ret) |
| 3045 | return ret; | 3123 | return ret; |
| 3046 | 3124 | ||
| 3047 | i915_gem_object_pin_pages(obj); | ||
| 3048 | |||
| 3049 | if (flags & PIN_OFFSET_FIXED) { | 3125 | if (flags & PIN_OFFSET_FIXED) { |
| 3050 | u64 offset = flags & PIN_OFFSET_MASK; | 3126 | u64 offset = flags & PIN_OFFSET_MASK; |
| 3051 | if (offset & (alignment - 1) || offset > end - size) { | 3127 | if (offset & (alignment - 1) || offset > end - size) { |
| @@ -3108,9 +3184,10 @@ search_free: | |||
| 3108 | } | 3184 | } |
| 3109 | GEM_BUG_ON(!i915_gem_valid_gtt_space(vma, obj->cache_level)); | 3185 | GEM_BUG_ON(!i915_gem_valid_gtt_space(vma, obj->cache_level)); |
| 3110 | 3186 | ||
| 3111 | list_move_tail(&obj->global_list, &dev_priv->mm.bound_list); | 3187 | list_move_tail(&obj->global_link, &dev_priv->mm.bound_list); |
| 3112 | list_move_tail(&vma->vm_link, &vma->vm->inactive_list); | 3188 | list_move_tail(&vma->vm_link, &vma->vm->inactive_list); |
| 3113 | obj->bind_count++; | 3189 | obj->bind_count++; |
| 3190 | GEM_BUG_ON(atomic_read(&obj->mm.pages_pin_count) < obj->bind_count); | ||
| 3114 | 3191 | ||
| 3115 | return 0; | 3192 | return 0; |
| 3116 | 3193 | ||
| @@ -3127,7 +3204,7 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj, | |||
| 3127 | * to GPU, and we can ignore the cache flush because it'll happen | 3204 | * to GPU, and we can ignore the cache flush because it'll happen |
| 3128 | * again at bind time. | 3205 | * again at bind time. |
| 3129 | */ | 3206 | */ |
| 3130 | if (obj->pages == NULL) | 3207 | if (!obj->mm.pages) |
| 3131 | return false; | 3208 | return false; |
| 3132 | 3209 | ||
| 3133 | /* | 3210 | /* |
| @@ -3151,7 +3228,7 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj, | |||
| 3151 | } | 3228 | } |
| 3152 | 3229 | ||
| 3153 | trace_i915_gem_object_clflush(obj); | 3230 | trace_i915_gem_object_clflush(obj); |
| 3154 | drm_clflush_sg(obj->pages); | 3231 | drm_clflush_sg(obj->mm.pages); |
| 3155 | obj->cache_dirty = false; | 3232 | obj->cache_dirty = false; |
| 3156 | 3233 | ||
| 3157 | return true; | 3234 | return true; |
| @@ -3211,24 +3288,6 @@ i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj) | |||
| 3211 | I915_GEM_DOMAIN_CPU); | 3288 | I915_GEM_DOMAIN_CPU); |
| 3212 | } | 3289 | } |
| 3213 | 3290 | ||
| 3214 | static void i915_gem_object_bump_inactive_ggtt(struct drm_i915_gem_object *obj) | ||
| 3215 | { | ||
| 3216 | struct i915_vma *vma; | ||
| 3217 | |||
| 3218 | list_for_each_entry(vma, &obj->vma_list, obj_link) { | ||
| 3219 | if (!i915_vma_is_ggtt(vma)) | ||
| 3220 | continue; | ||
| 3221 | |||
| 3222 | if (i915_vma_is_active(vma)) | ||
| 3223 | continue; | ||
| 3224 | |||
| 3225 | if (!drm_mm_node_allocated(&vma->node)) | ||
| 3226 | continue; | ||
| 3227 | |||
| 3228 | list_move_tail(&vma->vm_link, &vma->vm->inactive_list); | ||
| 3229 | } | ||
| 3230 | } | ||
| 3231 | |||
| 3232 | /** | 3291 | /** |
| 3233 | * Moves a single object to the GTT read, and possibly write domain. | 3292 | * Moves a single object to the GTT read, and possibly write domain. |
| 3234 | * @obj: object to act on | 3293 | * @obj: object to act on |
| @@ -3243,7 +3302,14 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) | |||
| 3243 | uint32_t old_write_domain, old_read_domains; | 3302 | uint32_t old_write_domain, old_read_domains; |
| 3244 | int ret; | 3303 | int ret; |
| 3245 | 3304 | ||
| 3246 | ret = i915_gem_object_wait_rendering(obj, !write); | 3305 | lockdep_assert_held(&obj->base.dev->struct_mutex); |
| 3306 | |||
| 3307 | ret = i915_gem_object_wait(obj, | ||
| 3308 | I915_WAIT_INTERRUPTIBLE | | ||
| 3309 | I915_WAIT_LOCKED | | ||
| 3310 | (write ? I915_WAIT_ALL : 0), | ||
| 3311 | MAX_SCHEDULE_TIMEOUT, | ||
| 3312 | NULL); | ||
| 3247 | if (ret) | 3313 | if (ret) |
| 3248 | return ret; | 3314 | return ret; |
| 3249 | 3315 | ||
| @@ -3258,7 +3324,7 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) | |||
| 3258 | * continue to assume that the obj remained out of the CPU cached | 3324 | * continue to assume that the obj remained out of the CPU cached |
| 3259 | * domain. | 3325 | * domain. |
| 3260 | */ | 3326 | */ |
| 3261 | ret = i915_gem_object_get_pages(obj); | 3327 | ret = i915_gem_object_pin_pages(obj); |
| 3262 | if (ret) | 3328 | if (ret) |
| 3263 | return ret; | 3329 | return ret; |
| 3264 | 3330 | ||
| @@ -3277,21 +3343,19 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) | |||
| 3277 | /* It should now be out of any other write domains, and we can update | 3343 | /* It should now be out of any other write domains, and we can update |
| 3278 | * the domain values for our changes. | 3344 | * the domain values for our changes. |
| 3279 | */ | 3345 | */ |
| 3280 | BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) != 0); | 3346 | GEM_BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) != 0); |
| 3281 | obj->base.read_domains |= I915_GEM_DOMAIN_GTT; | 3347 | obj->base.read_domains |= I915_GEM_DOMAIN_GTT; |
| 3282 | if (write) { | 3348 | if (write) { |
| 3283 | obj->base.read_domains = I915_GEM_DOMAIN_GTT; | 3349 | obj->base.read_domains = I915_GEM_DOMAIN_GTT; |
| 3284 | obj->base.write_domain = I915_GEM_DOMAIN_GTT; | 3350 | obj->base.write_domain = I915_GEM_DOMAIN_GTT; |
| 3285 | obj->dirty = 1; | 3351 | obj->mm.dirty = true; |
| 3286 | } | 3352 | } |
| 3287 | 3353 | ||
| 3288 | trace_i915_gem_object_change_domain(obj, | 3354 | trace_i915_gem_object_change_domain(obj, |
| 3289 | old_read_domains, | 3355 | old_read_domains, |
| 3290 | old_write_domain); | 3356 | old_write_domain); |
| 3291 | 3357 | ||
| 3292 | /* And bump the LRU for this access */ | 3358 | i915_gem_object_unpin_pages(obj); |
| 3293 | i915_gem_object_bump_inactive_ggtt(obj); | ||
| 3294 | |||
| 3295 | return 0; | 3359 | return 0; |
| 3296 | } | 3360 | } |
| 3297 | 3361 | ||
| @@ -3316,6 +3380,8 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, | |||
| 3316 | struct i915_vma *vma; | 3380 | struct i915_vma *vma; |
| 3317 | int ret = 0; | 3381 | int ret = 0; |
| 3318 | 3382 | ||
| 3383 | lockdep_assert_held(&obj->base.dev->struct_mutex); | ||
| 3384 | |||
| 3319 | if (obj->cache_level == cache_level) | 3385 | if (obj->cache_level == cache_level) |
| 3320 | goto out; | 3386 | goto out; |
| 3321 | 3387 | ||
| @@ -3360,7 +3426,12 @@ restart: | |||
| 3360 | * If we wait upon the object, we know that all the bound | 3426 | * If we wait upon the object, we know that all the bound |
| 3361 | * VMA are no longer active. | 3427 | * VMA are no longer active. |
| 3362 | */ | 3428 | */ |
| 3363 | ret = i915_gem_object_wait_rendering(obj, false); | 3429 | ret = i915_gem_object_wait(obj, |
| 3430 | I915_WAIT_INTERRUPTIBLE | | ||
| 3431 | I915_WAIT_LOCKED | | ||
| 3432 | I915_WAIT_ALL, | ||
| 3433 | MAX_SCHEDULE_TIMEOUT, | ||
| 3434 | NULL); | ||
| 3364 | if (ret) | 3435 | if (ret) |
| 3365 | return ret; | 3436 | return ret; |
| 3366 | 3437 | ||
| @@ -3428,10 +3499,14 @@ int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data, | |||
| 3428 | { | 3499 | { |
| 3429 | struct drm_i915_gem_caching *args = data; | 3500 | struct drm_i915_gem_caching *args = data; |
| 3430 | struct drm_i915_gem_object *obj; | 3501 | struct drm_i915_gem_object *obj; |
| 3502 | int err = 0; | ||
| 3431 | 3503 | ||
| 3432 | obj = i915_gem_object_lookup(file, args->handle); | 3504 | rcu_read_lock(); |
| 3433 | if (!obj) | 3505 | obj = i915_gem_object_lookup_rcu(file, args->handle); |
| 3434 | return -ENOENT; | 3506 | if (!obj) { |
| 3507 | err = -ENOENT; | ||
| 3508 | goto out; | ||
| 3509 | } | ||
| 3435 | 3510 | ||
| 3436 | switch (obj->cache_level) { | 3511 | switch (obj->cache_level) { |
| 3437 | case I915_CACHE_LLC: | 3512 | case I915_CACHE_LLC: |
| @@ -3447,15 +3522,15 @@ int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data, | |||
| 3447 | args->caching = I915_CACHING_NONE; | 3522 | args->caching = I915_CACHING_NONE; |
| 3448 | break; | 3523 | break; |
| 3449 | } | 3524 | } |
| 3450 | 3525 | out: | |
| 3451 | i915_gem_object_put_unlocked(obj); | 3526 | rcu_read_unlock(); |
| 3452 | return 0; | 3527 | return err; |
| 3453 | } | 3528 | } |
| 3454 | 3529 | ||
| 3455 | int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data, | 3530 | int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data, |
| 3456 | struct drm_file *file) | 3531 | struct drm_file *file) |
| 3457 | { | 3532 | { |
| 3458 | struct drm_i915_private *dev_priv = to_i915(dev); | 3533 | struct drm_i915_private *i915 = to_i915(dev); |
| 3459 | struct drm_i915_gem_caching *args = data; | 3534 | struct drm_i915_gem_caching *args = data; |
| 3460 | struct drm_i915_gem_object *obj; | 3535 | struct drm_i915_gem_object *obj; |
| 3461 | enum i915_cache_level level; | 3536 | enum i915_cache_level level; |
| @@ -3472,23 +3547,21 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data, | |||
| 3472 | * cacheline, whereas normally such cachelines would get | 3547 | * cacheline, whereas normally such cachelines would get |
| 3473 | * invalidated. | 3548 | * invalidated. |
| 3474 | */ | 3549 | */ |
| 3475 | if (!HAS_LLC(dev) && !HAS_SNOOP(dev)) | 3550 | if (!HAS_LLC(i915) && !HAS_SNOOP(i915)) |
| 3476 | return -ENODEV; | 3551 | return -ENODEV; |
| 3477 | 3552 | ||
| 3478 | level = I915_CACHE_LLC; | 3553 | level = I915_CACHE_LLC; |
| 3479 | break; | 3554 | break; |
| 3480 | case I915_CACHING_DISPLAY: | 3555 | case I915_CACHING_DISPLAY: |
| 3481 | level = HAS_WT(dev_priv) ? I915_CACHE_WT : I915_CACHE_NONE; | 3556 | level = HAS_WT(i915) ? I915_CACHE_WT : I915_CACHE_NONE; |
| 3482 | break; | 3557 | break; |
| 3483 | default: | 3558 | default: |
| 3484 | return -EINVAL; | 3559 | return -EINVAL; |
| 3485 | } | 3560 | } |
| 3486 | 3561 | ||
| 3487 | intel_runtime_pm_get(dev_priv); | ||
| 3488 | |||
| 3489 | ret = i915_mutex_lock_interruptible(dev); | 3562 | ret = i915_mutex_lock_interruptible(dev); |
| 3490 | if (ret) | 3563 | if (ret) |
| 3491 | goto rpm_put; | 3564 | return ret; |
| 3492 | 3565 | ||
| 3493 | obj = i915_gem_object_lookup(file, args->handle); | 3566 | obj = i915_gem_object_lookup(file, args->handle); |
| 3494 | if (!obj) { | 3567 | if (!obj) { |
| @@ -3497,13 +3570,9 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data, | |||
| 3497 | } | 3570 | } |
| 3498 | 3571 | ||
| 3499 | ret = i915_gem_object_set_cache_level(obj, level); | 3572 | ret = i915_gem_object_set_cache_level(obj, level); |
| 3500 | |||
| 3501 | i915_gem_object_put(obj); | 3573 | i915_gem_object_put(obj); |
| 3502 | unlock: | 3574 | unlock: |
| 3503 | mutex_unlock(&dev->struct_mutex); | 3575 | mutex_unlock(&dev->struct_mutex); |
| 3504 | rpm_put: | ||
| 3505 | intel_runtime_pm_put(dev_priv); | ||
| 3506 | |||
| 3507 | return ret; | 3576 | return ret; |
| 3508 | } | 3577 | } |
| 3509 | 3578 | ||
| @@ -3521,6 +3590,8 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, | |||
| 3521 | u32 old_read_domains, old_write_domain; | 3590 | u32 old_read_domains, old_write_domain; |
| 3522 | int ret; | 3591 | int ret; |
| 3523 | 3592 | ||
| 3593 | lockdep_assert_held(&obj->base.dev->struct_mutex); | ||
| 3594 | |||
| 3524 | /* Mark the pin_display early so that we account for the | 3595 | /* Mark the pin_display early so that we account for the |
| 3525 | * display coherency whilst setting up the cache domains. | 3596 | * display coherency whilst setting up the cache domains. |
| 3526 | */ | 3597 | */ |
| @@ -3554,8 +3625,22 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, | |||
| 3554 | if (view->type == I915_GGTT_VIEW_NORMAL) | 3625 | if (view->type == I915_GGTT_VIEW_NORMAL) |
| 3555 | vma = i915_gem_object_ggtt_pin(obj, view, 0, alignment, | 3626 | vma = i915_gem_object_ggtt_pin(obj, view, 0, alignment, |
| 3556 | PIN_MAPPABLE | PIN_NONBLOCK); | 3627 | PIN_MAPPABLE | PIN_NONBLOCK); |
| 3557 | if (IS_ERR(vma)) | 3628 | if (IS_ERR(vma)) { |
| 3558 | vma = i915_gem_object_ggtt_pin(obj, view, 0, alignment, 0); | 3629 | struct drm_i915_private *i915 = to_i915(obj->base.dev); |
| 3630 | unsigned int flags; | ||
| 3631 | |||
| 3632 | /* Valleyview is definitely limited to scanning out the first | ||
| 3633 | * 512MiB. Lets presume this behaviour was inherited from the | ||
| 3634 | * g4x display engine and that all earlier gen are similarly | ||
| 3635 | * limited. Testing suggests that it is a little more | ||
| 3636 | * complicated than this. For example, Cherryview appears quite | ||
| 3637 | * happy to scanout from anywhere within its global aperture. | ||
| 3638 | */ | ||
| 3639 | flags = 0; | ||
| 3640 | if (HAS_GMCH_DISPLAY(i915)) | ||
| 3641 | flags = PIN_MAPPABLE; | ||
| 3642 | vma = i915_gem_object_ggtt_pin(obj, view, 0, alignment, flags); | ||
| 3643 | } | ||
| 3559 | if (IS_ERR(vma)) | 3644 | if (IS_ERR(vma)) |
| 3560 | goto err_unpin_display; | 3645 | goto err_unpin_display; |
| 3561 | 3646 | ||
| @@ -3586,6 +3671,8 @@ err_unpin_display: | |||
| 3586 | void | 3671 | void |
| 3587 | i915_gem_object_unpin_from_display_plane(struct i915_vma *vma) | 3672 | i915_gem_object_unpin_from_display_plane(struct i915_vma *vma) |
| 3588 | { | 3673 | { |
| 3674 | lockdep_assert_held(&vma->vm->dev->struct_mutex); | ||
| 3675 | |||
| 3589 | if (WARN_ON(vma->obj->pin_display == 0)) | 3676 | if (WARN_ON(vma->obj->pin_display == 0)) |
| 3590 | return; | 3677 | return; |
| 3591 | 3678 | ||
| @@ -3613,7 +3700,14 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) | |||
| 3613 | uint32_t old_write_domain, old_read_domains; | 3700 | uint32_t old_write_domain, old_read_domains; |
| 3614 | int ret; | 3701 | int ret; |
| 3615 | 3702 | ||
| 3616 | ret = i915_gem_object_wait_rendering(obj, !write); | 3703 | lockdep_assert_held(&obj->base.dev->struct_mutex); |
| 3704 | |||
| 3705 | ret = i915_gem_object_wait(obj, | ||
| 3706 | I915_WAIT_INTERRUPTIBLE | | ||
| 3707 | I915_WAIT_LOCKED | | ||
| 3708 | (write ? I915_WAIT_ALL : 0), | ||
| 3709 | MAX_SCHEDULE_TIMEOUT, | ||
| 3710 | NULL); | ||
| 3617 | if (ret) | 3711 | if (ret) |
| 3618 | return ret; | 3712 | return ret; |
| 3619 | 3713 | ||
| @@ -3635,7 +3729,7 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) | |||
| 3635 | /* It should now be out of any other write domains, and we can update | 3729 | /* It should now be out of any other write domains, and we can update |
| 3636 | * the domain values for our changes. | 3730 | * the domain values for our changes. |
| 3637 | */ | 3731 | */ |
| 3638 | BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_CPU) != 0); | 3732 | GEM_BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_CPU) != 0); |
| 3639 | 3733 | ||
| 3640 | /* If we're writing through the CPU, then the GPU read domains will | 3734 | /* If we're writing through the CPU, then the GPU read domains will |
| 3641 | * need to be invalidated at next use. | 3735 | * need to be invalidated at next use. |
| @@ -3669,11 +3763,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) | |||
| 3669 | struct drm_i915_file_private *file_priv = file->driver_priv; | 3763 | struct drm_i915_file_private *file_priv = file->driver_priv; |
| 3670 | unsigned long recent_enough = jiffies - DRM_I915_THROTTLE_JIFFIES; | 3764 | unsigned long recent_enough = jiffies - DRM_I915_THROTTLE_JIFFIES; |
| 3671 | struct drm_i915_gem_request *request, *target = NULL; | 3765 | struct drm_i915_gem_request *request, *target = NULL; |
| 3672 | int ret; | 3766 | long ret; |
| 3673 | |||
| 3674 | ret = i915_gem_wait_for_error(&dev_priv->gpu_error); | ||
| 3675 | if (ret) | ||
| 3676 | return ret; | ||
| 3677 | 3767 | ||
| 3678 | /* ABI: return -EIO if already wedged */ | 3768 | /* ABI: return -EIO if already wedged */ |
| 3679 | if (i915_terminally_wedged(&dev_priv->gpu_error)) | 3769 | if (i915_terminally_wedged(&dev_priv->gpu_error)) |
| @@ -3700,10 +3790,12 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) | |||
| 3700 | if (target == NULL) | 3790 | if (target == NULL) |
| 3701 | return 0; | 3791 | return 0; |
| 3702 | 3792 | ||
| 3703 | ret = i915_wait_request(target, I915_WAIT_INTERRUPTIBLE, NULL, NULL); | 3793 | ret = i915_wait_request(target, |
| 3794 | I915_WAIT_INTERRUPTIBLE, | ||
| 3795 | MAX_SCHEDULE_TIMEOUT); | ||
| 3704 | i915_gem_request_put(target); | 3796 | i915_gem_request_put(target); |
| 3705 | 3797 | ||
| 3706 | return ret; | 3798 | return ret < 0 ? ret : 0; |
| 3707 | } | 3799 | } |
| 3708 | 3800 | ||
| 3709 | static bool | 3801 | static bool |
| @@ -3770,6 +3862,7 @@ int __i915_vma_do_pin(struct i915_vma *vma, | |||
| 3770 | unsigned int bound = vma->flags; | 3862 | unsigned int bound = vma->flags; |
| 3771 | int ret; | 3863 | int ret; |
| 3772 | 3864 | ||
| 3865 | lockdep_assert_held(&vma->vm->dev->struct_mutex); | ||
| 3773 | GEM_BUG_ON((flags & (PIN_GLOBAL | PIN_USER)) == 0); | 3866 | GEM_BUG_ON((flags & (PIN_GLOBAL | PIN_USER)) == 0); |
| 3774 | GEM_BUG_ON((flags & PIN_GLOBAL) && !i915_vma_is_ggtt(vma)); | 3867 | GEM_BUG_ON((flags & PIN_GLOBAL) && !i915_vma_is_ggtt(vma)); |
| 3775 | 3868 | ||
| @@ -3811,6 +3904,8 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj, | |||
| 3811 | struct i915_vma *vma; | 3904 | struct i915_vma *vma; |
| 3812 | int ret; | 3905 | int ret; |
| 3813 | 3906 | ||
| 3907 | lockdep_assert_held(&obj->base.dev->struct_mutex); | ||
| 3908 | |||
| 3814 | vma = i915_gem_obj_lookup_or_create_vma(obj, vm, view); | 3909 | vma = i915_gem_obj_lookup_or_create_vma(obj, vm, view); |
| 3815 | if (IS_ERR(vma)) | 3910 | if (IS_ERR(vma)) |
| 3816 | return vma; | 3911 | return vma; |
| @@ -3901,83 +3996,42 @@ static __always_inline unsigned int __busy_write_id(unsigned int id) | |||
| 3901 | } | 3996 | } |
| 3902 | 3997 | ||
| 3903 | static __always_inline unsigned int | 3998 | static __always_inline unsigned int |
| 3904 | __busy_set_if_active(const struct i915_gem_active *active, | 3999 | __busy_set_if_active(const struct dma_fence *fence, |
| 3905 | unsigned int (*flag)(unsigned int id)) | 4000 | unsigned int (*flag)(unsigned int id)) |
| 3906 | { | 4001 | { |
| 3907 | struct drm_i915_gem_request *request; | 4002 | struct drm_i915_gem_request *rq; |
| 3908 | 4003 | ||
| 3909 | request = rcu_dereference(active->request); | 4004 | /* We have to check the current hw status of the fence as the uABI |
| 3910 | if (!request || i915_gem_request_completed(request)) | 4005 | * guarantees forward progress. We could rely on the idle worker |
| 3911 | return 0; | 4006 | * to eventually flush us, but to minimise latency just ask the |
| 3912 | 4007 | * hardware. | |
| 3913 | /* This is racy. See __i915_gem_active_get_rcu() for an in detail | ||
| 3914 | * discussion of how to handle the race correctly, but for reporting | ||
| 3915 | * the busy state we err on the side of potentially reporting the | ||
| 3916 | * wrong engine as being busy (but we guarantee that the result | ||
| 3917 | * is at least self-consistent). | ||
| 3918 | * | ||
| 3919 | * As we use SLAB_DESTROY_BY_RCU, the request may be reallocated | ||
| 3920 | * whilst we are inspecting it, even under the RCU read lock as we are. | ||
| 3921 | * This means that there is a small window for the engine and/or the | ||
| 3922 | * seqno to have been overwritten. The seqno will always be in the | ||
| 3923 | * future compared to the intended, and so we know that if that | ||
| 3924 | * seqno is idle (on whatever engine) our request is idle and the | ||
| 3925 | * return 0 above is correct. | ||
| 3926 | * | 4008 | * |
| 3927 | * The issue is that if the engine is switched, it is just as likely | 4009 | * Note we only report on the status of native fences. |
| 3928 | * to report that it is busy (but since the switch happened, we know | ||
| 3929 | * the request should be idle). So there is a small chance that a busy | ||
| 3930 | * result is actually the wrong engine. | ||
| 3931 | * | ||
| 3932 | * So why don't we care? | ||
| 3933 | * | ||
| 3934 | * For starters, the busy ioctl is a heuristic that is by definition | ||
| 3935 | * racy. Even with perfect serialisation in the driver, the hardware | ||
| 3936 | * state is constantly advancing - the state we report to the user | ||
| 3937 | * is stale. | ||
| 3938 | * | ||
| 3939 | * The critical information for the busy-ioctl is whether the object | ||
| 3940 | * is idle as userspace relies on that to detect whether its next | ||
| 3941 | * access will stall, or if it has missed submitting commands to | ||
| 3942 | * the hardware allowing the GPU to stall. We never generate a | ||
| 3943 | * false-positive for idleness, thus busy-ioctl is reliable at the | ||
| 3944 | * most fundamental level, and we maintain the guarantee that a | ||
| 3945 | * busy object left to itself will eventually become idle (and stay | ||
| 3946 | * idle!). | ||
| 3947 | * | ||
| 3948 | * We allow ourselves the leeway of potentially misreporting the busy | ||
| 3949 | * state because that is an optimisation heuristic that is constantly | ||
| 3950 | * in flux. Being quickly able to detect the busy/idle state is much | ||
| 3951 | * more important than accurate logging of exactly which engines were | ||
| 3952 | * busy. | ||
| 3953 | * | ||
| 3954 | * For accuracy in reporting the engine, we could use | ||
| 3955 | * | ||
| 3956 | * result = 0; | ||
| 3957 | * request = __i915_gem_active_get_rcu(active); | ||
| 3958 | * if (request) { | ||
| 3959 | * if (!i915_gem_request_completed(request)) | ||
| 3960 | * result = flag(request->engine->exec_id); | ||
| 3961 | * i915_gem_request_put(request); | ||
| 3962 | * } | ||
| 3963 | * | ||
| 3964 | * but that still remains susceptible to both hardware and userspace | ||
| 3965 | * races. So we accept making the result of that race slightly worse, | ||
| 3966 | * given the rarity of the race and its low impact on the result. | ||
| 3967 | */ | 4010 | */ |
| 3968 | return flag(READ_ONCE(request->engine->exec_id)); | 4011 | if (!dma_fence_is_i915(fence)) |
| 4012 | return 0; | ||
| 4013 | |||
| 4014 | /* opencode to_request() in order to avoid const warnings */ | ||
| 4015 | rq = container_of(fence, struct drm_i915_gem_request, fence); | ||
| 4016 | if (i915_gem_request_completed(rq)) | ||
| 4017 | return 0; | ||
| 4018 | |||
| 4019 | return flag(rq->engine->exec_id); | ||
| 3969 | } | 4020 | } |
| 3970 | 4021 | ||
| 3971 | static __always_inline unsigned int | 4022 | static __always_inline unsigned int |
| 3972 | busy_check_reader(const struct i915_gem_active *active) | 4023 | busy_check_reader(const struct dma_fence *fence) |
| 3973 | { | 4024 | { |
| 3974 | return __busy_set_if_active(active, __busy_read_flag); | 4025 | return __busy_set_if_active(fence, __busy_read_flag); |
| 3975 | } | 4026 | } |
| 3976 | 4027 | ||
| 3977 | static __always_inline unsigned int | 4028 | static __always_inline unsigned int |
| 3978 | busy_check_writer(const struct i915_gem_active *active) | 4029 | busy_check_writer(const struct dma_fence *fence) |
| 3979 | { | 4030 | { |
| 3980 | return __busy_set_if_active(active, __busy_write_id); | 4031 | if (!fence) |
| 4032 | return 0; | ||
| 4033 | |||
| 4034 | return __busy_set_if_active(fence, __busy_write_id); | ||
| 3981 | } | 4035 | } |
| 3982 | 4036 | ||
| 3983 | int | 4037 | int |
| @@ -3986,64 +4040,58 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
| 3986 | { | 4040 | { |
| 3987 | struct drm_i915_gem_busy *args = data; | 4041 | struct drm_i915_gem_busy *args = data; |
| 3988 | struct drm_i915_gem_object *obj; | 4042 | struct drm_i915_gem_object *obj; |
| 3989 | unsigned long active; | 4043 | struct reservation_object_list *list; |
| 4044 | unsigned int seq; | ||
| 4045 | int err; | ||
| 3990 | 4046 | ||
| 3991 | obj = i915_gem_object_lookup(file, args->handle); | 4047 | err = -ENOENT; |
| 4048 | rcu_read_lock(); | ||
| 4049 | obj = i915_gem_object_lookup_rcu(file, args->handle); | ||
| 3992 | if (!obj) | 4050 | if (!obj) |
| 3993 | return -ENOENT; | 4051 | goto out; |
| 3994 | 4052 | ||
| 3995 | args->busy = 0; | 4053 | /* A discrepancy here is that we do not report the status of |
| 3996 | active = __I915_BO_ACTIVE(obj); | 4054 | * non-i915 fences, i.e. even though we may report the object as idle, |
| 3997 | if (active) { | 4055 | * a call to set-domain may still stall waiting for foreign rendering. |
| 3998 | int idx; | 4056 | * This also means that wait-ioctl may report an object as busy, |
| 4057 | * where busy-ioctl considers it idle. | ||
| 4058 | * | ||
| 4059 | * We trade the ability to warn of foreign fences to report on which | ||
| 4060 | * i915 engines are active for the object. | ||
| 4061 | * | ||
| 4062 | * Alternatively, we can trade that extra information on read/write | ||
| 4063 | * activity with | ||
| 4064 | * args->busy = | ||
| 4065 | * !reservation_object_test_signaled_rcu(obj->resv, true); | ||
| 4066 | * to report the overall busyness. This is what the wait-ioctl does. | ||
| 4067 | * | ||
| 4068 | */ | ||
| 4069 | retry: | ||
| 4070 | seq = raw_read_seqcount(&obj->resv->seq); | ||
| 3999 | 4071 | ||
| 4000 | /* Yes, the lookups are intentionally racy. | 4072 | /* Translate the exclusive fence to the READ *and* WRITE engine */ |
| 4001 | * | 4073 | args->busy = busy_check_writer(rcu_dereference(obj->resv->fence_excl)); |
| 4002 | * First, we cannot simply rely on __I915_BO_ACTIVE. We have | ||
| 4003 | * to regard the value as stale and as our ABI guarantees | ||
| 4004 | * forward progress, we confirm the status of each active | ||
| 4005 | * request with the hardware. | ||
| 4006 | * | ||
| 4007 | * Even though we guard the pointer lookup by RCU, that only | ||
| 4008 | * guarantees that the pointer and its contents remain | ||
| 4009 | * dereferencable and does *not* mean that the request we | ||
| 4010 | * have is the same as the one being tracked by the object. | ||
| 4011 | * | ||
| 4012 | * Consider that we lookup the request just as it is being | ||
| 4013 | * retired and freed. We take a local copy of the pointer, | ||
| 4014 | * but before we add its engine into the busy set, the other | ||
| 4015 | * thread reallocates it and assigns it to a task on another | ||
| 4016 | * engine with a fresh and incomplete seqno. Guarding against | ||
| 4017 | * that requires careful serialisation and reference counting, | ||
| 4018 | * i.e. using __i915_gem_active_get_request_rcu(). We don't, | ||
| 4019 | * instead we expect that if the result is busy, which engines | ||
| 4020 | * are busy is not completely reliable - we only guarantee | ||
| 4021 | * that the object was busy. | ||
| 4022 | */ | ||
| 4023 | rcu_read_lock(); | ||
| 4024 | 4074 | ||
| 4025 | for_each_active(active, idx) | 4075 | /* Translate shared fences to READ set of engines */ |
| 4026 | args->busy |= busy_check_reader(&obj->last_read[idx]); | 4076 | list = rcu_dereference(obj->resv->fence); |
| 4077 | if (list) { | ||
| 4078 | unsigned int shared_count = list->shared_count, i; | ||
| 4027 | 4079 | ||
| 4028 | /* For ABI sanity, we only care that the write engine is in | 4080 | for (i = 0; i < shared_count; ++i) { |
| 4029 | * the set of read engines. This should be ensured by the | 4081 | struct dma_fence *fence = |
| 4030 | * ordering of setting last_read/last_write in | 4082 | rcu_dereference(list->shared[i]); |
| 4031 | * i915_vma_move_to_active(), and then in reverse in retire. | ||
| 4032 | * However, for good measure, we always report the last_write | ||
| 4033 | * request as a busy read as well as being a busy write. | ||
| 4034 | * | ||
| 4035 | * We don't care that the set of active read/write engines | ||
| 4036 | * may change during construction of the result, as it is | ||
| 4037 | * equally liable to change before userspace can inspect | ||
| 4038 | * the result. | ||
| 4039 | */ | ||
| 4040 | args->busy |= busy_check_writer(&obj->last_write); | ||
| 4041 | 4083 | ||
| 4042 | rcu_read_unlock(); | 4084 | args->busy |= busy_check_reader(fence); |
| 4085 | } | ||
| 4043 | } | 4086 | } |
| 4044 | 4087 | ||
| 4045 | i915_gem_object_put_unlocked(obj); | 4088 | if (args->busy && read_seqcount_retry(&obj->resv->seq, seq)) |
| 4046 | return 0; | 4089 | goto retry; |
| 4090 | |||
| 4091 | err = 0; | ||
| 4092 | out: | ||
| 4093 | rcu_read_unlock(); | ||
| 4094 | return err; | ||
| 4047 | } | 4095 | } |
| 4048 | 4096 | ||
| 4049 | int | 4097 | int |
| @@ -4060,7 +4108,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, | |||
| 4060 | struct drm_i915_private *dev_priv = to_i915(dev); | 4108 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 4061 | struct drm_i915_gem_madvise *args = data; | 4109 | struct drm_i915_gem_madvise *args = data; |
| 4062 | struct drm_i915_gem_object *obj; | 4110 | struct drm_i915_gem_object *obj; |
| 4063 | int ret; | 4111 | int err; |
| 4064 | 4112 | ||
| 4065 | switch (args->madv) { | 4113 | switch (args->madv) { |
| 4066 | case I915_MADV_DONTNEED: | 4114 | case I915_MADV_DONTNEED: |
| @@ -4070,65 +4118,72 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, | |||
| 4070 | return -EINVAL; | 4118 | return -EINVAL; |
| 4071 | } | 4119 | } |
| 4072 | 4120 | ||
| 4073 | ret = i915_mutex_lock_interruptible(dev); | ||
| 4074 | if (ret) | ||
| 4075 | return ret; | ||
| 4076 | |||
| 4077 | obj = i915_gem_object_lookup(file_priv, args->handle); | 4121 | obj = i915_gem_object_lookup(file_priv, args->handle); |
| 4078 | if (!obj) { | 4122 | if (!obj) |
| 4079 | ret = -ENOENT; | 4123 | return -ENOENT; |
| 4080 | goto unlock; | ||
| 4081 | } | ||
| 4082 | 4124 | ||
| 4083 | if (obj->pages && | 4125 | err = mutex_lock_interruptible(&obj->mm.lock); |
| 4126 | if (err) | ||
| 4127 | goto out; | ||
| 4128 | |||
| 4129 | if (obj->mm.pages && | ||
| 4084 | i915_gem_object_is_tiled(obj) && | 4130 | i915_gem_object_is_tiled(obj) && |
| 4085 | dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) { | 4131 | dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) { |
| 4086 | if (obj->madv == I915_MADV_WILLNEED) | 4132 | if (obj->mm.madv == I915_MADV_WILLNEED) { |
| 4087 | i915_gem_object_unpin_pages(obj); | 4133 | GEM_BUG_ON(!obj->mm.quirked); |
| 4088 | if (args->madv == I915_MADV_WILLNEED) | 4134 | __i915_gem_object_unpin_pages(obj); |
| 4089 | i915_gem_object_pin_pages(obj); | 4135 | obj->mm.quirked = false; |
| 4136 | } | ||
| 4137 | if (args->madv == I915_MADV_WILLNEED) { | ||
| 4138 | GEM_BUG_ON(obj->mm.quirked); | ||
| 4139 | __i915_gem_object_pin_pages(obj); | ||
| 4140 | obj->mm.quirked = true; | ||
| 4141 | } | ||
| 4090 | } | 4142 | } |
| 4091 | 4143 | ||
| 4092 | if (obj->madv != __I915_MADV_PURGED) | 4144 | if (obj->mm.madv != __I915_MADV_PURGED) |
| 4093 | obj->madv = args->madv; | 4145 | obj->mm.madv = args->madv; |
| 4094 | 4146 | ||
| 4095 | /* if the object is no longer attached, discard its backing storage */ | 4147 | /* if the object is no longer attached, discard its backing storage */ |
| 4096 | if (obj->madv == I915_MADV_DONTNEED && obj->pages == NULL) | 4148 | if (obj->mm.madv == I915_MADV_DONTNEED && !obj->mm.pages) |
| 4097 | i915_gem_object_truncate(obj); | 4149 | i915_gem_object_truncate(obj); |
| 4098 | 4150 | ||
| 4099 | args->retained = obj->madv != __I915_MADV_PURGED; | 4151 | args->retained = obj->mm.madv != __I915_MADV_PURGED; |
| 4152 | mutex_unlock(&obj->mm.lock); | ||
| 4100 | 4153 | ||
| 4154 | out: | ||
| 4101 | i915_gem_object_put(obj); | 4155 | i915_gem_object_put(obj); |
| 4102 | unlock: | 4156 | return err; |
| 4103 | mutex_unlock(&dev->struct_mutex); | ||
| 4104 | return ret; | ||
| 4105 | } | 4157 | } |
| 4106 | 4158 | ||
| 4107 | void i915_gem_object_init(struct drm_i915_gem_object *obj, | 4159 | void i915_gem_object_init(struct drm_i915_gem_object *obj, |
| 4108 | const struct drm_i915_gem_object_ops *ops) | 4160 | const struct drm_i915_gem_object_ops *ops) |
| 4109 | { | 4161 | { |
| 4110 | int i; | 4162 | mutex_init(&obj->mm.lock); |
| 4111 | 4163 | ||
| 4112 | INIT_LIST_HEAD(&obj->global_list); | 4164 | INIT_LIST_HEAD(&obj->global_link); |
| 4113 | for (i = 0; i < I915_NUM_ENGINES; i++) | 4165 | INIT_LIST_HEAD(&obj->userfault_link); |
| 4114 | init_request_active(&obj->last_read[i], | ||
| 4115 | i915_gem_object_retire__read); | ||
| 4116 | init_request_active(&obj->last_write, | ||
| 4117 | i915_gem_object_retire__write); | ||
| 4118 | INIT_LIST_HEAD(&obj->obj_exec_link); | 4166 | INIT_LIST_HEAD(&obj->obj_exec_link); |
| 4119 | INIT_LIST_HEAD(&obj->vma_list); | 4167 | INIT_LIST_HEAD(&obj->vma_list); |
| 4120 | INIT_LIST_HEAD(&obj->batch_pool_link); | 4168 | INIT_LIST_HEAD(&obj->batch_pool_link); |
| 4121 | 4169 | ||
| 4122 | obj->ops = ops; | 4170 | obj->ops = ops; |
| 4123 | 4171 | ||
| 4172 | reservation_object_init(&obj->__builtin_resv); | ||
| 4173 | obj->resv = &obj->__builtin_resv; | ||
| 4174 | |||
| 4124 | obj->frontbuffer_ggtt_origin = ORIGIN_GTT; | 4175 | obj->frontbuffer_ggtt_origin = ORIGIN_GTT; |
| 4125 | obj->madv = I915_MADV_WILLNEED; | 4176 | |
| 4177 | obj->mm.madv = I915_MADV_WILLNEED; | ||
| 4178 | INIT_RADIX_TREE(&obj->mm.get_page.radix, GFP_KERNEL | __GFP_NOWARN); | ||
| 4179 | mutex_init(&obj->mm.get_page.lock); | ||
| 4126 | 4180 | ||
| 4127 | i915_gem_info_add_obj(to_i915(obj->base.dev), obj->base.size); | 4181 | i915_gem_info_add_obj(to_i915(obj->base.dev), obj->base.size); |
| 4128 | } | 4182 | } |
| 4129 | 4183 | ||
| 4130 | static const struct drm_i915_gem_object_ops i915_gem_object_ops = { | 4184 | static const struct drm_i915_gem_object_ops i915_gem_object_ops = { |
| 4131 | .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE, | 4185 | .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE | |
| 4186 | I915_GEM_OBJECT_IS_SHRINKABLE, | ||
| 4132 | .get_pages = i915_gem_object_get_pages_gtt, | 4187 | .get_pages = i915_gem_object_get_pages_gtt, |
| 4133 | .put_pages = i915_gem_object_put_pages_gtt, | 4188 | .put_pages = i915_gem_object_put_pages_gtt, |
| 4134 | }; | 4189 | }; |
| @@ -4140,6 +4195,7 @@ static const struct drm_i915_gem_object_ops i915_gem_object_ops = { | |||
| 4140 | struct drm_i915_gem_object * | 4195 | struct drm_i915_gem_object * |
| 4141 | i915_gem_object_create(struct drm_device *dev, u64 size) | 4196 | i915_gem_object_create(struct drm_device *dev, u64 size) |
| 4142 | { | 4197 | { |
| 4198 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 4143 | struct drm_i915_gem_object *obj; | 4199 | struct drm_i915_gem_object *obj; |
| 4144 | struct address_space *mapping; | 4200 | struct address_space *mapping; |
| 4145 | gfp_t mask; | 4201 | gfp_t mask; |
| @@ -4165,7 +4221,7 @@ i915_gem_object_create(struct drm_device *dev, u64 size) | |||
| 4165 | goto fail; | 4221 | goto fail; |
| 4166 | 4222 | ||
| 4167 | mask = GFP_HIGHUSER | __GFP_RECLAIMABLE; | 4223 | mask = GFP_HIGHUSER | __GFP_RECLAIMABLE; |
| 4168 | if (IS_CRESTLINE(dev) || IS_BROADWATER(dev)) { | 4224 | if (IS_CRESTLINE(dev_priv) || IS_BROADWATER(dev_priv)) { |
| 4169 | /* 965gm cannot relocate objects above 4GiB. */ | 4225 | /* 965gm cannot relocate objects above 4GiB. */ |
| 4170 | mask &= ~__GFP_HIGHMEM; | 4226 | mask &= ~__GFP_HIGHMEM; |
| 4171 | mask |= __GFP_DMA32; | 4227 | mask |= __GFP_DMA32; |
| @@ -4202,7 +4258,6 @@ i915_gem_object_create(struct drm_device *dev, u64 size) | |||
| 4202 | 4258 | ||
| 4203 | fail: | 4259 | fail: |
| 4204 | i915_gem_object_free(obj); | 4260 | i915_gem_object_free(obj); |
| 4205 | |||
| 4206 | return ERR_PTR(ret); | 4261 | return ERR_PTR(ret); |
| 4207 | } | 4262 | } |
| 4208 | 4263 | ||
| @@ -4214,7 +4269,7 @@ static bool discard_backing_storage(struct drm_i915_gem_object *obj) | |||
| 4214 | * back the contents from the GPU. | 4269 | * back the contents from the GPU. |
| 4215 | */ | 4270 | */ |
| 4216 | 4271 | ||
| 4217 | if (obj->madv != I915_MADV_WILLNEED) | 4272 | if (obj->mm.madv != I915_MADV_WILLNEED) |
| 4218 | return false; | 4273 | return false; |
| 4219 | 4274 | ||
| 4220 | if (obj->base.filp == NULL) | 4275 | if (obj->base.filp == NULL) |
| @@ -4230,16 +4285,72 @@ static bool discard_backing_storage(struct drm_i915_gem_object *obj) | |||
| 4230 | return atomic_long_read(&obj->base.filp->f_count) == 1; | 4285 | return atomic_long_read(&obj->base.filp->f_count) == 1; |
| 4231 | } | 4286 | } |
| 4232 | 4287 | ||
| 4233 | void i915_gem_free_object(struct drm_gem_object *gem_obj) | 4288 | static void __i915_gem_free_objects(struct drm_i915_private *i915, |
| 4289 | struct llist_node *freed) | ||
| 4234 | { | 4290 | { |
| 4235 | struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); | 4291 | struct drm_i915_gem_object *obj, *on; |
| 4236 | struct drm_device *dev = obj->base.dev; | ||
| 4237 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 4238 | struct i915_vma *vma, *next; | ||
| 4239 | 4292 | ||
| 4240 | intel_runtime_pm_get(dev_priv); | 4293 | mutex_lock(&i915->drm.struct_mutex); |
| 4294 | intel_runtime_pm_get(i915); | ||
| 4295 | llist_for_each_entry(obj, freed, freed) { | ||
| 4296 | struct i915_vma *vma, *vn; | ||
| 4241 | 4297 | ||
| 4242 | trace_i915_gem_object_destroy(obj); | 4298 | trace_i915_gem_object_destroy(obj); |
| 4299 | |||
| 4300 | GEM_BUG_ON(i915_gem_object_is_active(obj)); | ||
| 4301 | list_for_each_entry_safe(vma, vn, | ||
| 4302 | &obj->vma_list, obj_link) { | ||
| 4303 | GEM_BUG_ON(!i915_vma_is_ggtt(vma)); | ||
| 4304 | GEM_BUG_ON(i915_vma_is_active(vma)); | ||
| 4305 | vma->flags &= ~I915_VMA_PIN_MASK; | ||
| 4306 | i915_vma_close(vma); | ||
| 4307 | } | ||
| 4308 | GEM_BUG_ON(!list_empty(&obj->vma_list)); | ||
| 4309 | GEM_BUG_ON(!RB_EMPTY_ROOT(&obj->vma_tree)); | ||
| 4310 | |||
| 4311 | list_del(&obj->global_link); | ||
| 4312 | } | ||
| 4313 | intel_runtime_pm_put(i915); | ||
| 4314 | mutex_unlock(&i915->drm.struct_mutex); | ||
| 4315 | |||
| 4316 | llist_for_each_entry_safe(obj, on, freed, freed) { | ||
| 4317 | GEM_BUG_ON(obj->bind_count); | ||
| 4318 | GEM_BUG_ON(atomic_read(&obj->frontbuffer_bits)); | ||
| 4319 | |||
| 4320 | if (obj->ops->release) | ||
| 4321 | obj->ops->release(obj); | ||
| 4322 | |||
| 4323 | if (WARN_ON(i915_gem_object_has_pinned_pages(obj))) | ||
| 4324 | atomic_set(&obj->mm.pages_pin_count, 0); | ||
| 4325 | __i915_gem_object_put_pages(obj, I915_MM_NORMAL); | ||
| 4326 | GEM_BUG_ON(obj->mm.pages); | ||
| 4327 | |||
| 4328 | if (obj->base.import_attach) | ||
| 4329 | drm_prime_gem_destroy(&obj->base, NULL); | ||
| 4330 | |||
| 4331 | reservation_object_fini(&obj->__builtin_resv); | ||
| 4332 | drm_gem_object_release(&obj->base); | ||
| 4333 | i915_gem_info_remove_obj(i915, obj->base.size); | ||
| 4334 | |||
| 4335 | kfree(obj->bit_17); | ||
| 4336 | i915_gem_object_free(obj); | ||
| 4337 | } | ||
| 4338 | } | ||
| 4339 | |||
| 4340 | static void i915_gem_flush_free_objects(struct drm_i915_private *i915) | ||
| 4341 | { | ||
| 4342 | struct llist_node *freed; | ||
| 4343 | |||
| 4344 | freed = llist_del_all(&i915->mm.free_list); | ||
| 4345 | if (unlikely(freed)) | ||
| 4346 | __i915_gem_free_objects(i915, freed); | ||
| 4347 | } | ||
| 4348 | |||
| 4349 | static void __i915_gem_free_work(struct work_struct *work) | ||
| 4350 | { | ||
| 4351 | struct drm_i915_private *i915 = | ||
| 4352 | container_of(work, struct drm_i915_private, mm.free_work); | ||
| 4353 | struct llist_node *freed; | ||
| 4243 | 4354 | ||
| 4244 | /* All file-owned VMA should have been released by this point through | 4355 | /* All file-owned VMA should have been released by this point through |
| 4245 | * i915_gem_close_object(), or earlier by i915_gem_context_close(). | 4356 | * i915_gem_close_object(), or earlier by i915_gem_context_close(). |
| @@ -4248,47 +4359,62 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) | |||
| 4248 | * the GTT either for the user or for scanout). Those VMA still need to | 4359 | * the GTT either for the user or for scanout). Those VMA still need to |
| 4249 | * unbound now. | 4360 | * unbound now. |
| 4250 | */ | 4361 | */ |
| 4251 | list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link) { | ||
| 4252 | GEM_BUG_ON(!i915_vma_is_ggtt(vma)); | ||
| 4253 | GEM_BUG_ON(i915_vma_is_active(vma)); | ||
| 4254 | vma->flags &= ~I915_VMA_PIN_MASK; | ||
| 4255 | i915_vma_close(vma); | ||
| 4256 | } | ||
| 4257 | GEM_BUG_ON(obj->bind_count); | ||
| 4258 | 4362 | ||
| 4259 | /* Stolen objects don't hold a ref, but do hold pin count. Fix that up | 4363 | while ((freed = llist_del_all(&i915->mm.free_list))) |
| 4260 | * before progressing. */ | 4364 | __i915_gem_free_objects(i915, freed); |
| 4261 | if (obj->stolen) | 4365 | } |
| 4262 | i915_gem_object_unpin_pages(obj); | 4366 | |
| 4367 | static void __i915_gem_free_object_rcu(struct rcu_head *head) | ||
| 4368 | { | ||
| 4369 | struct drm_i915_gem_object *obj = | ||
| 4370 | container_of(head, typeof(*obj), rcu); | ||
| 4371 | struct drm_i915_private *i915 = to_i915(obj->base.dev); | ||
| 4372 | |||
| 4373 | /* We can't simply use call_rcu() from i915_gem_free_object() | ||
| 4374 | * as we need to block whilst unbinding, and the call_rcu | ||
| 4375 | * task may be called from softirq context. So we take a | ||
| 4376 | * detour through a worker. | ||
| 4377 | */ | ||
| 4378 | if (llist_add(&obj->freed, &i915->mm.free_list)) | ||
| 4379 | schedule_work(&i915->mm.free_work); | ||
| 4380 | } | ||
| 4263 | 4381 | ||
| 4264 | WARN_ON(atomic_read(&obj->frontbuffer_bits)); | 4382 | void i915_gem_free_object(struct drm_gem_object *gem_obj) |
| 4383 | { | ||
| 4384 | struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); | ||
| 4265 | 4385 | ||
| 4266 | if (obj->pages && obj->madv == I915_MADV_WILLNEED && | 4386 | if (obj->mm.quirked) |
| 4267 | dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES && | 4387 | __i915_gem_object_unpin_pages(obj); |
| 4268 | i915_gem_object_is_tiled(obj)) | ||
| 4269 | i915_gem_object_unpin_pages(obj); | ||
| 4270 | 4388 | ||
| 4271 | if (WARN_ON(obj->pages_pin_count)) | ||
| 4272 | obj->pages_pin_count = 0; | ||
| 4273 | if (discard_backing_storage(obj)) | 4389 | if (discard_backing_storage(obj)) |
| 4274 | obj->madv = I915_MADV_DONTNEED; | 4390 | obj->mm.madv = I915_MADV_DONTNEED; |
| 4275 | i915_gem_object_put_pages(obj); | ||
| 4276 | |||
| 4277 | BUG_ON(obj->pages); | ||
| 4278 | 4391 | ||
| 4279 | if (obj->base.import_attach) | 4392 | /* Before we free the object, make sure any pure RCU-only |
| 4280 | drm_prime_gem_destroy(&obj->base, NULL); | 4393 | * read-side critical sections are complete, e.g. |
| 4394 | * i915_gem_busy_ioctl(). For the corresponding synchronized | ||
| 4395 | * lookup see i915_gem_object_lookup_rcu(). | ||
| 4396 | */ | ||
| 4397 | call_rcu(&obj->rcu, __i915_gem_free_object_rcu); | ||
| 4398 | } | ||
| 4281 | 4399 | ||
| 4282 | if (obj->ops->release) | 4400 | void __i915_gem_object_release_unless_active(struct drm_i915_gem_object *obj) |
| 4283 | obj->ops->release(obj); | 4401 | { |
| 4402 | lockdep_assert_held(&obj->base.dev->struct_mutex); | ||
| 4284 | 4403 | ||
| 4285 | drm_gem_object_release(&obj->base); | 4404 | GEM_BUG_ON(i915_gem_object_has_active_reference(obj)); |
| 4286 | i915_gem_info_remove_obj(dev_priv, obj->base.size); | 4405 | if (i915_gem_object_is_active(obj)) |
| 4406 | i915_gem_object_set_active_reference(obj); | ||
| 4407 | else | ||
| 4408 | i915_gem_object_put(obj); | ||
| 4409 | } | ||
| 4287 | 4410 | ||
| 4288 | kfree(obj->bit_17); | 4411 | static void assert_kernel_context_is_current(struct drm_i915_private *dev_priv) |
| 4289 | i915_gem_object_free(obj); | 4412 | { |
| 4413 | struct intel_engine_cs *engine; | ||
| 4414 | enum intel_engine_id id; | ||
| 4290 | 4415 | ||
| 4291 | intel_runtime_pm_put(dev_priv); | 4416 | for_each_engine(engine, dev_priv, id) |
| 4417 | GEM_BUG_ON(engine->last_context != dev_priv->kernel_context); | ||
| 4292 | } | 4418 | } |
| 4293 | 4419 | ||
| 4294 | int i915_gem_suspend(struct drm_device *dev) | 4420 | int i915_gem_suspend(struct drm_device *dev) |
| @@ -4319,18 +4445,22 @@ int i915_gem_suspend(struct drm_device *dev) | |||
| 4319 | goto err; | 4445 | goto err; |
| 4320 | 4446 | ||
| 4321 | i915_gem_retire_requests(dev_priv); | 4447 | i915_gem_retire_requests(dev_priv); |
| 4448 | GEM_BUG_ON(dev_priv->gt.active_requests); | ||
| 4322 | 4449 | ||
| 4450 | assert_kernel_context_is_current(dev_priv); | ||
| 4323 | i915_gem_context_lost(dev_priv); | 4451 | i915_gem_context_lost(dev_priv); |
| 4324 | mutex_unlock(&dev->struct_mutex); | 4452 | mutex_unlock(&dev->struct_mutex); |
| 4325 | 4453 | ||
| 4326 | cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); | 4454 | cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); |
| 4327 | cancel_delayed_work_sync(&dev_priv->gt.retire_work); | 4455 | cancel_delayed_work_sync(&dev_priv->gt.retire_work); |
| 4328 | flush_delayed_work(&dev_priv->gt.idle_work); | 4456 | flush_delayed_work(&dev_priv->gt.idle_work); |
| 4457 | flush_work(&dev_priv->mm.free_work); | ||
| 4329 | 4458 | ||
| 4330 | /* Assert that we sucessfully flushed all the work and | 4459 | /* Assert that we sucessfully flushed all the work and |
| 4331 | * reset the GPU back to its idle, low power state. | 4460 | * reset the GPU back to its idle, low power state. |
| 4332 | */ | 4461 | */ |
| 4333 | WARN_ON(dev_priv->gt.awake); | 4462 | WARN_ON(dev_priv->gt.awake); |
| 4463 | WARN_ON(!intel_execlists_idle(dev_priv)); | ||
| 4334 | 4464 | ||
| 4335 | /* | 4465 | /* |
| 4336 | * Neither the BIOS, ourselves or any other kernel | 4466 | * Neither the BIOS, ourselves or any other kernel |
| @@ -4367,6 +4497,8 @@ void i915_gem_resume(struct drm_device *dev) | |||
| 4367 | { | 4497 | { |
| 4368 | struct drm_i915_private *dev_priv = to_i915(dev); | 4498 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 4369 | 4499 | ||
| 4500 | WARN_ON(dev_priv->gt.awake); | ||
| 4501 | |||
| 4370 | mutex_lock(&dev->struct_mutex); | 4502 | mutex_lock(&dev->struct_mutex); |
| 4371 | i915_gem_restore_gtt_mappings(dev); | 4503 | i915_gem_restore_gtt_mappings(dev); |
| 4372 | 4504 | ||
| @@ -4437,6 +4569,8 @@ i915_gem_init_hw(struct drm_device *dev) | |||
| 4437 | enum intel_engine_id id; | 4569 | enum intel_engine_id id; |
| 4438 | int ret; | 4570 | int ret; |
| 4439 | 4571 | ||
| 4572 | dev_priv->gt.last_init_time = ktime_get(); | ||
| 4573 | |||
| 4440 | /* Double layer security blanket, see i915_gem_init() */ | 4574 | /* Double layer security blanket, see i915_gem_init() */ |
| 4441 | intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); | 4575 | intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
| 4442 | 4576 | ||
| @@ -4615,33 +4749,43 @@ i915_gem_load_init_fences(struct drm_i915_private *dev_priv) | |||
| 4615 | i915_gem_detect_bit_6_swizzle(dev); | 4749 | i915_gem_detect_bit_6_swizzle(dev); |
| 4616 | } | 4750 | } |
| 4617 | 4751 | ||
| 4618 | void | 4752 | int |
| 4619 | i915_gem_load_init(struct drm_device *dev) | 4753 | i915_gem_load_init(struct drm_device *dev) |
| 4620 | { | 4754 | { |
| 4621 | struct drm_i915_private *dev_priv = to_i915(dev); | 4755 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 4756 | int err = -ENOMEM; | ||
| 4757 | |||
| 4758 | dev_priv->objects = KMEM_CACHE(drm_i915_gem_object, SLAB_HWCACHE_ALIGN); | ||
| 4759 | if (!dev_priv->objects) | ||
| 4760 | goto err_out; | ||
| 4761 | |||
| 4762 | dev_priv->vmas = KMEM_CACHE(i915_vma, SLAB_HWCACHE_ALIGN); | ||
| 4763 | if (!dev_priv->vmas) | ||
| 4764 | goto err_objects; | ||
| 4622 | 4765 | ||
| 4623 | dev_priv->objects = | 4766 | dev_priv->requests = KMEM_CACHE(drm_i915_gem_request, |
| 4624 | kmem_cache_create("i915_gem_object", | 4767 | SLAB_HWCACHE_ALIGN | |
| 4625 | sizeof(struct drm_i915_gem_object), 0, | 4768 | SLAB_RECLAIM_ACCOUNT | |
| 4626 | SLAB_HWCACHE_ALIGN, | 4769 | SLAB_DESTROY_BY_RCU); |
| 4627 | NULL); | 4770 | if (!dev_priv->requests) |
| 4628 | dev_priv->vmas = | 4771 | goto err_vmas; |
| 4629 | kmem_cache_create("i915_gem_vma", | 4772 | |
| 4630 | sizeof(struct i915_vma), 0, | 4773 | mutex_lock(&dev_priv->drm.struct_mutex); |
| 4631 | SLAB_HWCACHE_ALIGN, | 4774 | INIT_LIST_HEAD(&dev_priv->gt.timelines); |
| 4632 | NULL); | 4775 | err = i915_gem_timeline_init(dev_priv, |
| 4633 | dev_priv->requests = | 4776 | &dev_priv->gt.global_timeline, |
| 4634 | kmem_cache_create("i915_gem_request", | 4777 | "[execution]"); |
| 4635 | sizeof(struct drm_i915_gem_request), 0, | 4778 | mutex_unlock(&dev_priv->drm.struct_mutex); |
| 4636 | SLAB_HWCACHE_ALIGN | | 4779 | if (err) |
| 4637 | SLAB_RECLAIM_ACCOUNT | | 4780 | goto err_requests; |
| 4638 | SLAB_DESTROY_BY_RCU, | ||
| 4639 | NULL); | ||
| 4640 | 4781 | ||
| 4641 | INIT_LIST_HEAD(&dev_priv->context_list); | 4782 | INIT_LIST_HEAD(&dev_priv->context_list); |
| 4783 | INIT_WORK(&dev_priv->mm.free_work, __i915_gem_free_work); | ||
| 4784 | init_llist_head(&dev_priv->mm.free_list); | ||
| 4642 | INIT_LIST_HEAD(&dev_priv->mm.unbound_list); | 4785 | INIT_LIST_HEAD(&dev_priv->mm.unbound_list); |
| 4643 | INIT_LIST_HEAD(&dev_priv->mm.bound_list); | 4786 | INIT_LIST_HEAD(&dev_priv->mm.bound_list); |
| 4644 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); | 4787 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); |
| 4788 | INIT_LIST_HEAD(&dev_priv->mm.userfault_list); | ||
| 4645 | INIT_DELAYED_WORK(&dev_priv->gt.retire_work, | 4789 | INIT_DELAYED_WORK(&dev_priv->gt.retire_work, |
| 4646 | i915_gem_retire_work_handler); | 4790 | i915_gem_retire_work_handler); |
| 4647 | INIT_DELAYED_WORK(&dev_priv->gt.idle_work, | 4791 | INIT_DELAYED_WORK(&dev_priv->gt.idle_work, |
| @@ -4658,12 +4802,25 @@ i915_gem_load_init(struct drm_device *dev) | |||
| 4658 | atomic_set(&dev_priv->mm.bsd_engine_dispatch_index, 0); | 4802 | atomic_set(&dev_priv->mm.bsd_engine_dispatch_index, 0); |
| 4659 | 4803 | ||
| 4660 | spin_lock_init(&dev_priv->fb_tracking.lock); | 4804 | spin_lock_init(&dev_priv->fb_tracking.lock); |
| 4805 | |||
| 4806 | return 0; | ||
| 4807 | |||
| 4808 | err_requests: | ||
| 4809 | kmem_cache_destroy(dev_priv->requests); | ||
| 4810 | err_vmas: | ||
| 4811 | kmem_cache_destroy(dev_priv->vmas); | ||
| 4812 | err_objects: | ||
| 4813 | kmem_cache_destroy(dev_priv->objects); | ||
| 4814 | err_out: | ||
| 4815 | return err; | ||
| 4661 | } | 4816 | } |
| 4662 | 4817 | ||
| 4663 | void i915_gem_load_cleanup(struct drm_device *dev) | 4818 | void i915_gem_load_cleanup(struct drm_device *dev) |
| 4664 | { | 4819 | { |
| 4665 | struct drm_i915_private *dev_priv = to_i915(dev); | 4820 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 4666 | 4821 | ||
| 4822 | WARN_ON(!llist_empty(&dev_priv->mm.free_list)); | ||
| 4823 | |||
| 4667 | kmem_cache_destroy(dev_priv->requests); | 4824 | kmem_cache_destroy(dev_priv->requests); |
| 4668 | kmem_cache_destroy(dev_priv->vmas); | 4825 | kmem_cache_destroy(dev_priv->vmas); |
| 4669 | kmem_cache_destroy(dev_priv->objects); | 4826 | kmem_cache_destroy(dev_priv->objects); |
| @@ -4712,7 +4869,7 @@ int i915_gem_freeze_late(struct drm_i915_private *dev_priv) | |||
| 4712 | i915_gem_shrink(dev_priv, -1UL, I915_SHRINK_UNBOUND); | 4869 | i915_gem_shrink(dev_priv, -1UL, I915_SHRINK_UNBOUND); |
| 4713 | 4870 | ||
| 4714 | for (p = phases; *p; p++) { | 4871 | for (p = phases; *p; p++) { |
| 4715 | list_for_each_entry(obj, *p, global_list) { | 4872 | list_for_each_entry(obj, *p, global_link) { |
| 4716 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; | 4873 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; |
| 4717 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; | 4874 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; |
| 4718 | } | 4875 | } |
| @@ -4804,21 +4961,6 @@ void i915_gem_track_fb(struct drm_i915_gem_object *old, | |||
| 4804 | } | 4961 | } |
| 4805 | } | 4962 | } |
| 4806 | 4963 | ||
| 4807 | /* Like i915_gem_object_get_page(), but mark the returned page dirty */ | ||
| 4808 | struct page * | ||
| 4809 | i915_gem_object_get_dirty_page(struct drm_i915_gem_object *obj, int n) | ||
| 4810 | { | ||
| 4811 | struct page *page; | ||
| 4812 | |||
| 4813 | /* Only default objects have per-page dirty tracking */ | ||
| 4814 | if (WARN_ON(!i915_gem_object_has_struct_page(obj))) | ||
| 4815 | return NULL; | ||
| 4816 | |||
| 4817 | page = i915_gem_object_get_page(obj, n); | ||
| 4818 | set_page_dirty(page); | ||
| 4819 | return page; | ||
| 4820 | } | ||
| 4821 | |||
| 4822 | /* Allocate a new GEM object and fill it with the supplied data */ | 4964 | /* Allocate a new GEM object and fill it with the supplied data */ |
| 4823 | struct drm_i915_gem_object * | 4965 | struct drm_i915_gem_object * |
| 4824 | i915_gem_object_create_from_data(struct drm_device *dev, | 4966 | i915_gem_object_create_from_data(struct drm_device *dev, |
| @@ -4837,14 +4979,13 @@ i915_gem_object_create_from_data(struct drm_device *dev, | |||
| 4837 | if (ret) | 4979 | if (ret) |
| 4838 | goto fail; | 4980 | goto fail; |
| 4839 | 4981 | ||
| 4840 | ret = i915_gem_object_get_pages(obj); | 4982 | ret = i915_gem_object_pin_pages(obj); |
| 4841 | if (ret) | 4983 | if (ret) |
| 4842 | goto fail; | 4984 | goto fail; |
| 4843 | 4985 | ||
| 4844 | i915_gem_object_pin_pages(obj); | 4986 | sg = obj->mm.pages; |
| 4845 | sg = obj->pages; | ||
| 4846 | bytes = sg_copy_from_buffer(sg->sgl, sg->nents, (void *)data, size); | 4987 | bytes = sg_copy_from_buffer(sg->sgl, sg->nents, (void *)data, size); |
| 4847 | obj->dirty = 1; /* Backing store is now out of date */ | 4988 | obj->mm.dirty = true; /* Backing store is now out of date */ |
| 4848 | i915_gem_object_unpin_pages(obj); | 4989 | i915_gem_object_unpin_pages(obj); |
| 4849 | 4990 | ||
| 4850 | if (WARN_ON(bytes != size)) { | 4991 | if (WARN_ON(bytes != size)) { |
| @@ -4859,3 +5000,156 @@ fail: | |||
| 4859 | i915_gem_object_put(obj); | 5000 | i915_gem_object_put(obj); |
| 4860 | return ERR_PTR(ret); | 5001 | return ERR_PTR(ret); |
| 4861 | } | 5002 | } |
| 5003 | |||
| 5004 | struct scatterlist * | ||
| 5005 | i915_gem_object_get_sg(struct drm_i915_gem_object *obj, | ||
| 5006 | unsigned int n, | ||
| 5007 | unsigned int *offset) | ||
| 5008 | { | ||
| 5009 | struct i915_gem_object_page_iter *iter = &obj->mm.get_page; | ||
| 5010 | struct scatterlist *sg; | ||
| 5011 | unsigned int idx, count; | ||
| 5012 | |||
| 5013 | might_sleep(); | ||
| 5014 | GEM_BUG_ON(n >= obj->base.size >> PAGE_SHIFT); | ||
| 5015 | GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); | ||
| 5016 | |||
| 5017 | /* As we iterate forward through the sg, we record each entry in a | ||
| 5018 | * radixtree for quick repeated (backwards) lookups. If we have seen | ||
| 5019 | * this index previously, we will have an entry for it. | ||
| 5020 | * | ||
| 5021 | * Initial lookup is O(N), but this is amortized to O(1) for | ||
| 5022 | * sequential page access (where each new request is consecutive | ||
| 5023 | * to the previous one). Repeated lookups are O(lg(obj->base.size)), | ||
| 5024 | * i.e. O(1) with a large constant! | ||
| 5025 | */ | ||
| 5026 | if (n < READ_ONCE(iter->sg_idx)) | ||
| 5027 | goto lookup; | ||
| 5028 | |||
| 5029 | mutex_lock(&iter->lock); | ||
| 5030 | |||
| 5031 | /* We prefer to reuse the last sg so that repeated lookup of this | ||
| 5032 | * (or the subsequent) sg are fast - comparing against the last | ||
| 5033 | * sg is faster than going through the radixtree. | ||
| 5034 | */ | ||
| 5035 | |||
| 5036 | sg = iter->sg_pos; | ||
| 5037 | idx = iter->sg_idx; | ||
| 5038 | count = __sg_page_count(sg); | ||
| 5039 | |||
| 5040 | while (idx + count <= n) { | ||
| 5041 | unsigned long exception, i; | ||
| 5042 | int ret; | ||
| 5043 | |||
| 5044 | /* If we cannot allocate and insert this entry, or the | ||
| 5045 | * individual pages from this range, cancel updating the | ||
| 5046 | * sg_idx so that on this lookup we are forced to linearly | ||
| 5047 | * scan onwards, but on future lookups we will try the | ||
| 5048 | * insertion again (in which case we need to be careful of | ||
| 5049 | * the error return reporting that we have already inserted | ||
| 5050 | * this index). | ||
| 5051 | */ | ||
| 5052 | ret = radix_tree_insert(&iter->radix, idx, sg); | ||
| 5053 | if (ret && ret != -EEXIST) | ||
| 5054 | goto scan; | ||
| 5055 | |||
| 5056 | exception = | ||
| 5057 | RADIX_TREE_EXCEPTIONAL_ENTRY | | ||
| 5058 | idx << RADIX_TREE_EXCEPTIONAL_SHIFT; | ||
| 5059 | for (i = 1; i < count; i++) { | ||
| 5060 | ret = radix_tree_insert(&iter->radix, idx + i, | ||
| 5061 | (void *)exception); | ||
| 5062 | if (ret && ret != -EEXIST) | ||
| 5063 | goto scan; | ||
| 5064 | } | ||
| 5065 | |||
| 5066 | idx += count; | ||
| 5067 | sg = ____sg_next(sg); | ||
| 5068 | count = __sg_page_count(sg); | ||
| 5069 | } | ||
| 5070 | |||
| 5071 | scan: | ||
| 5072 | iter->sg_pos = sg; | ||
| 5073 | iter->sg_idx = idx; | ||
| 5074 | |||
| 5075 | mutex_unlock(&iter->lock); | ||
| 5076 | |||
| 5077 | if (unlikely(n < idx)) /* insertion completed by another thread */ | ||
| 5078 | goto lookup; | ||
| 5079 | |||
| 5080 | /* In case we failed to insert the entry into the radixtree, we need | ||
| 5081 | * to look beyond the current sg. | ||
| 5082 | */ | ||
| 5083 | while (idx + count <= n) { | ||
| 5084 | idx += count; | ||
| 5085 | sg = ____sg_next(sg); | ||
| 5086 | count = __sg_page_count(sg); | ||
| 5087 | } | ||
| 5088 | |||
| 5089 | *offset = n - idx; | ||
| 5090 | return sg; | ||
| 5091 | |||
| 5092 | lookup: | ||
| 5093 | rcu_read_lock(); | ||
| 5094 | |||
| 5095 | sg = radix_tree_lookup(&iter->radix, n); | ||
| 5096 | GEM_BUG_ON(!sg); | ||
| 5097 | |||
| 5098 | /* If this index is in the middle of multi-page sg entry, | ||
| 5099 | * the radixtree will contain an exceptional entry that points | ||
| 5100 | * to the start of that range. We will return the pointer to | ||
| 5101 | * the base page and the offset of this page within the | ||
| 5102 | * sg entry's range. | ||
| 5103 | */ | ||
| 5104 | *offset = 0; | ||
| 5105 | if (unlikely(radix_tree_exception(sg))) { | ||
| 5106 | unsigned long base = | ||
| 5107 | (unsigned long)sg >> RADIX_TREE_EXCEPTIONAL_SHIFT; | ||
| 5108 | |||
| 5109 | sg = radix_tree_lookup(&iter->radix, base); | ||
| 5110 | GEM_BUG_ON(!sg); | ||
| 5111 | |||
| 5112 | *offset = n - base; | ||
| 5113 | } | ||
| 5114 | |||
| 5115 | rcu_read_unlock(); | ||
| 5116 | |||
| 5117 | return sg; | ||
| 5118 | } | ||
| 5119 | |||
| 5120 | struct page * | ||
| 5121 | i915_gem_object_get_page(struct drm_i915_gem_object *obj, unsigned int n) | ||
| 5122 | { | ||
| 5123 | struct scatterlist *sg; | ||
| 5124 | unsigned int offset; | ||
| 5125 | |||
| 5126 | GEM_BUG_ON(!i915_gem_object_has_struct_page(obj)); | ||
| 5127 | |||
| 5128 | sg = i915_gem_object_get_sg(obj, n, &offset); | ||
| 5129 | return nth_page(sg_page(sg), offset); | ||
| 5130 | } | ||
| 5131 | |||
| 5132 | /* Like i915_gem_object_get_page(), but mark the returned page dirty */ | ||
| 5133 | struct page * | ||
| 5134 | i915_gem_object_get_dirty_page(struct drm_i915_gem_object *obj, | ||
| 5135 | unsigned int n) | ||
| 5136 | { | ||
| 5137 | struct page *page; | ||
| 5138 | |||
| 5139 | page = i915_gem_object_get_page(obj, n); | ||
| 5140 | if (!obj->mm.dirty) | ||
| 5141 | set_page_dirty(page); | ||
| 5142 | |||
| 5143 | return page; | ||
| 5144 | } | ||
| 5145 | |||
| 5146 | dma_addr_t | ||
| 5147 | i915_gem_object_get_dma_address(struct drm_i915_gem_object *obj, | ||
| 5148 | unsigned long n) | ||
| 5149 | { | ||
| 5150 | struct scatterlist *sg; | ||
| 5151 | unsigned int offset; | ||
| 5152 | |||
| 5153 | sg = i915_gem_object_get_sg(obj, n, &offset); | ||
| 5154 | return sg_dma_address(sg) + (offset << PAGE_SHIFT); | ||
| 5155 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.h b/drivers/gpu/drm/i915/i915_gem.h index 8292e797d9b5..735580d72eb1 100644 --- a/drivers/gpu/drm/i915/i915_gem.h +++ b/drivers/gpu/drm/i915/i915_gem.h | |||
| @@ -31,4 +31,6 @@ | |||
| 31 | #define GEM_BUG_ON(expr) | 31 | #define GEM_BUG_ON(expr) |
| 32 | #endif | 32 | #endif |
| 33 | 33 | ||
| 34 | #define I915_NUM_ENGINES 5 | ||
| 35 | |||
| 34 | #endif /* __I915_GEM_H__ */ | 36 | #endif /* __I915_GEM_H__ */ |
diff --git a/drivers/gpu/drm/i915/i915_gem_batch_pool.c b/drivers/gpu/drm/i915/i915_gem_batch_pool.c index ed989596d9a3..b3bc119ec1bb 100644 --- a/drivers/gpu/drm/i915/i915_gem_batch_pool.c +++ b/drivers/gpu/drm/i915/i915_gem_batch_pool.c | |||
| @@ -73,7 +73,7 @@ void i915_gem_batch_pool_fini(struct i915_gem_batch_pool *pool) | |||
| 73 | list_for_each_entry_safe(obj, next, | 73 | list_for_each_entry_safe(obj, next, |
| 74 | &pool->cache_list[n], | 74 | &pool->cache_list[n], |
| 75 | batch_pool_link) | 75 | batch_pool_link) |
| 76 | i915_gem_object_put(obj); | 76 | __i915_gem_object_release_unless_active(obj); |
| 77 | 77 | ||
| 78 | INIT_LIST_HEAD(&pool->cache_list[n]); | 78 | INIT_LIST_HEAD(&pool->cache_list[n]); |
| 79 | } | 79 | } |
| @@ -97,9 +97,9 @@ i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool, | |||
| 97 | size_t size) | 97 | size_t size) |
| 98 | { | 98 | { |
| 99 | struct drm_i915_gem_object *obj = NULL; | 99 | struct drm_i915_gem_object *obj = NULL; |
| 100 | struct drm_i915_gem_object *tmp, *next; | 100 | struct drm_i915_gem_object *tmp; |
| 101 | struct list_head *list; | 101 | struct list_head *list; |
| 102 | int n; | 102 | int n, ret; |
| 103 | 103 | ||
| 104 | lockdep_assert_held(&pool->engine->i915->drm.struct_mutex); | 104 | lockdep_assert_held(&pool->engine->i915->drm.struct_mutex); |
| 105 | 105 | ||
| @@ -112,40 +112,35 @@ i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool, | |||
| 112 | n = ARRAY_SIZE(pool->cache_list) - 1; | 112 | n = ARRAY_SIZE(pool->cache_list) - 1; |
| 113 | list = &pool->cache_list[n]; | 113 | list = &pool->cache_list[n]; |
| 114 | 114 | ||
| 115 | list_for_each_entry_safe(tmp, next, list, batch_pool_link) { | 115 | list_for_each_entry(tmp, list, batch_pool_link) { |
| 116 | /* The batches are strictly LRU ordered */ | 116 | /* The batches are strictly LRU ordered */ |
| 117 | if (!i915_gem_active_is_idle(&tmp->last_read[pool->engine->id], | 117 | if (i915_gem_object_is_active(tmp)) |
| 118 | &tmp->base.dev->struct_mutex)) | ||
| 119 | break; | 118 | break; |
| 120 | 119 | ||
| 121 | /* While we're looping, do some clean up */ | 120 | GEM_BUG_ON(!reservation_object_test_signaled_rcu(tmp->resv, |
| 122 | if (tmp->madv == __I915_MADV_PURGED) { | 121 | true)); |
| 123 | list_del(&tmp->batch_pool_link); | ||
| 124 | i915_gem_object_put(tmp); | ||
| 125 | continue; | ||
| 126 | } | ||
| 127 | 122 | ||
| 128 | if (tmp->base.size >= size) { | 123 | if (tmp->base.size >= size) { |
| 124 | /* Clear the set of shared fences early */ | ||
| 125 | ww_mutex_lock(&tmp->resv->lock, NULL); | ||
| 126 | reservation_object_add_excl_fence(tmp->resv, NULL); | ||
| 127 | ww_mutex_unlock(&tmp->resv->lock); | ||
| 128 | |||
| 129 | obj = tmp; | 129 | obj = tmp; |
| 130 | break; | 130 | break; |
| 131 | } | 131 | } |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | if (obj == NULL) { | 134 | if (obj == NULL) { |
| 135 | int ret; | 135 | obj = i915_gem_object_create_internal(pool->engine->i915, size); |
| 136 | |||
| 137 | obj = i915_gem_object_create(&pool->engine->i915->drm, size); | ||
| 138 | if (IS_ERR(obj)) | 136 | if (IS_ERR(obj)) |
| 139 | return obj; | 137 | return obj; |
| 140 | |||
| 141 | ret = i915_gem_object_get_pages(obj); | ||
| 142 | if (ret) | ||
| 143 | return ERR_PTR(ret); | ||
| 144 | |||
| 145 | obj->madv = I915_MADV_DONTNEED; | ||
| 146 | } | 138 | } |
| 147 | 139 | ||
| 140 | ret = i915_gem_object_pin_pages(obj); | ||
| 141 | if (ret) | ||
| 142 | return ERR_PTR(ret); | ||
| 143 | |||
| 148 | list_move_tail(&obj->batch_pool_link, list); | 144 | list_move_tail(&obj->batch_pool_link, list); |
| 149 | i915_gem_object_pin_pages(obj); | ||
| 150 | return obj; | 145 | return obj; |
| 151 | } | 146 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 5dca32ac1c67..6dd475735f0a 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
| @@ -155,9 +155,10 @@ void i915_gem_context_free(struct kref *ctx_ref) | |||
| 155 | if (ce->ring) | 155 | if (ce->ring) |
| 156 | intel_ring_free(ce->ring); | 156 | intel_ring_free(ce->ring); |
| 157 | 157 | ||
| 158 | i915_vma_put(ce->state); | 158 | __i915_gem_object_release_unless_active(ce->state->obj); |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | kfree(ctx->name); | ||
| 161 | put_pid(ctx->pid); | 162 | put_pid(ctx->pid); |
| 162 | list_del(&ctx->link); | 163 | list_del(&ctx->link); |
| 163 | 164 | ||
| @@ -303,19 +304,28 @@ __create_hw_context(struct drm_device *dev, | |||
| 303 | } | 304 | } |
| 304 | 305 | ||
| 305 | /* Default context will never have a file_priv */ | 306 | /* Default context will never have a file_priv */ |
| 306 | if (file_priv != NULL) { | 307 | ret = DEFAULT_CONTEXT_HANDLE; |
| 308 | if (file_priv) { | ||
| 307 | ret = idr_alloc(&file_priv->context_idr, ctx, | 309 | ret = idr_alloc(&file_priv->context_idr, ctx, |
| 308 | DEFAULT_CONTEXT_HANDLE, 0, GFP_KERNEL); | 310 | DEFAULT_CONTEXT_HANDLE, 0, GFP_KERNEL); |
| 309 | if (ret < 0) | 311 | if (ret < 0) |
| 310 | goto err_out; | 312 | goto err_out; |
| 311 | } else | 313 | } |
| 312 | ret = DEFAULT_CONTEXT_HANDLE; | 314 | ctx->user_handle = ret; |
| 313 | 315 | ||
| 314 | ctx->file_priv = file_priv; | 316 | ctx->file_priv = file_priv; |
| 315 | if (file_priv) | 317 | if (file_priv) { |
| 316 | ctx->pid = get_task_pid(current, PIDTYPE_PID); | 318 | ctx->pid = get_task_pid(current, PIDTYPE_PID); |
| 319 | ctx->name = kasprintf(GFP_KERNEL, "%s[%d]/%x", | ||
| 320 | current->comm, | ||
| 321 | pid_nr(ctx->pid), | ||
| 322 | ctx->user_handle); | ||
| 323 | if (!ctx->name) { | ||
| 324 | ret = -ENOMEM; | ||
| 325 | goto err_pid; | ||
| 326 | } | ||
| 327 | } | ||
| 317 | 328 | ||
| 318 | ctx->user_handle = ret; | ||
| 319 | /* NB: Mark all slices as needing a remap so that when the context first | 329 | /* NB: Mark all slices as needing a remap so that when the context first |
| 320 | * loads it will restore whatever remap state already exists. If there | 330 | * loads it will restore whatever remap state already exists. If there |
| 321 | * is no remap info, it will be a NOP. */ | 331 | * is no remap info, it will be a NOP. */ |
| @@ -329,6 +339,9 @@ __create_hw_context(struct drm_device *dev, | |||
| 329 | 339 | ||
| 330 | return ctx; | 340 | return ctx; |
| 331 | 341 | ||
| 342 | err_pid: | ||
| 343 | put_pid(ctx->pid); | ||
| 344 | idr_remove(&file_priv->context_idr, ctx->user_handle); | ||
| 332 | err_out: | 345 | err_out: |
| 333 | context_close(ctx); | 346 | context_close(ctx); |
| 334 | return ERR_PTR(ret); | 347 | return ERR_PTR(ret); |
| @@ -352,9 +365,9 @@ i915_gem_create_context(struct drm_device *dev, | |||
| 352 | return ctx; | 365 | return ctx; |
| 353 | 366 | ||
| 354 | if (USES_FULL_PPGTT(dev)) { | 367 | if (USES_FULL_PPGTT(dev)) { |
| 355 | struct i915_hw_ppgtt *ppgtt = | 368 | struct i915_hw_ppgtt *ppgtt; |
| 356 | i915_ppgtt_create(to_i915(dev), file_priv); | ||
| 357 | 369 | ||
| 370 | ppgtt = i915_ppgtt_create(to_i915(dev), file_priv, ctx->name); | ||
| 358 | if (IS_ERR(ppgtt)) { | 371 | if (IS_ERR(ppgtt)) { |
| 359 | DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n", | 372 | DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n", |
| 360 | PTR_ERR(ppgtt)); | 373 | PTR_ERR(ppgtt)); |
| @@ -751,12 +764,36 @@ needs_pd_load_post(struct i915_hw_ppgtt *ppgtt, | |||
| 751 | return false; | 764 | return false; |
| 752 | } | 765 | } |
| 753 | 766 | ||
| 767 | struct i915_vma * | ||
| 768 | i915_gem_context_pin_legacy(struct i915_gem_context *ctx, | ||
| 769 | unsigned int flags) | ||
| 770 | { | ||
| 771 | struct i915_vma *vma = ctx->engine[RCS].state; | ||
| 772 | int ret; | ||
| 773 | |||
| 774 | /* Clear this page out of any CPU caches for coherent swap-in/out. | ||
| 775 | * We only want to do this on the first bind so that we do not stall | ||
| 776 | * on an active context (which by nature is already on the GPU). | ||
| 777 | */ | ||
| 778 | if (!(vma->flags & I915_VMA_GLOBAL_BIND)) { | ||
| 779 | ret = i915_gem_object_set_to_gtt_domain(vma->obj, false); | ||
| 780 | if (ret) | ||
| 781 | return ERR_PTR(ret); | ||
| 782 | } | ||
| 783 | |||
| 784 | ret = i915_vma_pin(vma, 0, ctx->ggtt_alignment, PIN_GLOBAL | flags); | ||
| 785 | if (ret) | ||
| 786 | return ERR_PTR(ret); | ||
| 787 | |||
| 788 | return vma; | ||
| 789 | } | ||
| 790 | |||
| 754 | static int do_rcs_switch(struct drm_i915_gem_request *req) | 791 | static int do_rcs_switch(struct drm_i915_gem_request *req) |
| 755 | { | 792 | { |
| 756 | struct i915_gem_context *to = req->ctx; | 793 | struct i915_gem_context *to = req->ctx; |
| 757 | struct intel_engine_cs *engine = req->engine; | 794 | struct intel_engine_cs *engine = req->engine; |
| 758 | struct i915_hw_ppgtt *ppgtt = to->ppgtt ?: req->i915->mm.aliasing_ppgtt; | 795 | struct i915_hw_ppgtt *ppgtt = to->ppgtt ?: req->i915->mm.aliasing_ppgtt; |
| 759 | struct i915_vma *vma = to->engine[RCS].state; | 796 | struct i915_vma *vma; |
| 760 | struct i915_gem_context *from; | 797 | struct i915_gem_context *from; |
| 761 | u32 hw_flags; | 798 | u32 hw_flags; |
| 762 | int ret, i; | 799 | int ret, i; |
| @@ -764,17 +801,10 @@ static int do_rcs_switch(struct drm_i915_gem_request *req) | |||
| 764 | if (skip_rcs_switch(ppgtt, engine, to)) | 801 | if (skip_rcs_switch(ppgtt, engine, to)) |
| 765 | return 0; | 802 | return 0; |
| 766 | 803 | ||
| 767 | /* Clear this page out of any CPU caches for coherent swap-in/out. */ | ||
| 768 | if (!(vma->flags & I915_VMA_GLOBAL_BIND)) { | ||
| 769 | ret = i915_gem_object_set_to_gtt_domain(vma->obj, false); | ||
| 770 | if (ret) | ||
| 771 | return ret; | ||
| 772 | } | ||
| 773 | |||
| 774 | /* Trying to pin first makes error handling easier. */ | 804 | /* Trying to pin first makes error handling easier. */ |
| 775 | ret = i915_vma_pin(vma, 0, to->ggtt_alignment, PIN_GLOBAL); | 805 | vma = i915_gem_context_pin_legacy(to, 0); |
| 776 | if (ret) | 806 | if (IS_ERR(vma)) |
| 777 | return ret; | 807 | return PTR_ERR(vma); |
| 778 | 808 | ||
| 779 | /* | 809 | /* |
| 780 | * Pin can switch back to the default context if we end up calling into | 810 | * Pin can switch back to the default context if we end up calling into |
| @@ -931,22 +961,33 @@ int i915_switch_context(struct drm_i915_gem_request *req) | |||
| 931 | int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv) | 961 | int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv) |
| 932 | { | 962 | { |
| 933 | struct intel_engine_cs *engine; | 963 | struct intel_engine_cs *engine; |
| 964 | struct i915_gem_timeline *timeline; | ||
| 934 | enum intel_engine_id id; | 965 | enum intel_engine_id id; |
| 935 | 966 | ||
| 967 | lockdep_assert_held(&dev_priv->drm.struct_mutex); | ||
| 968 | |||
| 936 | for_each_engine(engine, dev_priv, id) { | 969 | for_each_engine(engine, dev_priv, id) { |
| 937 | struct drm_i915_gem_request *req; | 970 | struct drm_i915_gem_request *req; |
| 938 | int ret; | 971 | int ret; |
| 939 | 972 | ||
| 940 | if (engine->last_context == NULL) | ||
| 941 | continue; | ||
| 942 | |||
| 943 | if (engine->last_context == dev_priv->kernel_context) | ||
| 944 | continue; | ||
| 945 | |||
| 946 | req = i915_gem_request_alloc(engine, dev_priv->kernel_context); | 973 | req = i915_gem_request_alloc(engine, dev_priv->kernel_context); |
| 947 | if (IS_ERR(req)) | 974 | if (IS_ERR(req)) |
| 948 | return PTR_ERR(req); | 975 | return PTR_ERR(req); |
| 949 | 976 | ||
| 977 | /* Queue this switch after all other activity */ | ||
| 978 | list_for_each_entry(timeline, &dev_priv->gt.timelines, link) { | ||
| 979 | struct drm_i915_gem_request *prev; | ||
| 980 | struct intel_timeline *tl; | ||
| 981 | |||
| 982 | tl = &timeline->engine[engine->id]; | ||
| 983 | prev = i915_gem_active_raw(&tl->last_request, | ||
| 984 | &dev_priv->drm.struct_mutex); | ||
| 985 | if (prev) | ||
| 986 | i915_sw_fence_await_sw_fence_gfp(&req->submit, | ||
| 987 | &prev->submit, | ||
| 988 | GFP_KERNEL); | ||
| 989 | } | ||
| 990 | |||
| 950 | ret = i915_switch_context(req); | 991 | ret = i915_switch_context(req); |
| 951 | i915_add_request_no_flush(req); | 992 | i915_add_request_no_flush(req); |
| 952 | if (ret) | 993 | if (ret) |
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c index 97c9d68b45df..5e38299b5df6 100644 --- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c | |||
| @@ -44,51 +44,42 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme | |||
| 44 | struct scatterlist *src, *dst; | 44 | struct scatterlist *src, *dst; |
| 45 | int ret, i; | 45 | int ret, i; |
| 46 | 46 | ||
| 47 | ret = i915_mutex_lock_interruptible(obj->base.dev); | 47 | ret = i915_gem_object_pin_pages(obj); |
| 48 | if (ret) | 48 | if (ret) |
| 49 | goto err; | 49 | goto err; |
| 50 | 50 | ||
| 51 | ret = i915_gem_object_get_pages(obj); | ||
| 52 | if (ret) | ||
| 53 | goto err_unlock; | ||
| 54 | |||
| 55 | i915_gem_object_pin_pages(obj); | ||
| 56 | |||
| 57 | /* Copy sg so that we make an independent mapping */ | 51 | /* Copy sg so that we make an independent mapping */ |
| 58 | st = kmalloc(sizeof(struct sg_table), GFP_KERNEL); | 52 | st = kmalloc(sizeof(struct sg_table), GFP_KERNEL); |
| 59 | if (st == NULL) { | 53 | if (st == NULL) { |
| 60 | ret = -ENOMEM; | 54 | ret = -ENOMEM; |
| 61 | goto err_unpin; | 55 | goto err_unpin_pages; |
| 62 | } | 56 | } |
| 63 | 57 | ||
| 64 | ret = sg_alloc_table(st, obj->pages->nents, GFP_KERNEL); | 58 | ret = sg_alloc_table(st, obj->mm.pages->nents, GFP_KERNEL); |
| 65 | if (ret) | 59 | if (ret) |
| 66 | goto err_free; | 60 | goto err_free; |
| 67 | 61 | ||
| 68 | src = obj->pages->sgl; | 62 | src = obj->mm.pages->sgl; |
| 69 | dst = st->sgl; | 63 | dst = st->sgl; |
| 70 | for (i = 0; i < obj->pages->nents; i++) { | 64 | for (i = 0; i < obj->mm.pages->nents; i++) { |
| 71 | sg_set_page(dst, sg_page(src), src->length, 0); | 65 | sg_set_page(dst, sg_page(src), src->length, 0); |
| 72 | dst = sg_next(dst); | 66 | dst = sg_next(dst); |
| 73 | src = sg_next(src); | 67 | src = sg_next(src); |
| 74 | } | 68 | } |
| 75 | 69 | ||
| 76 | if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) { | 70 | if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) { |
| 77 | ret =-ENOMEM; | 71 | ret = -ENOMEM; |
| 78 | goto err_free_sg; | 72 | goto err_free_sg; |
| 79 | } | 73 | } |
| 80 | 74 | ||
| 81 | mutex_unlock(&obj->base.dev->struct_mutex); | ||
| 82 | return st; | 75 | return st; |
| 83 | 76 | ||
| 84 | err_free_sg: | 77 | err_free_sg: |
| 85 | sg_free_table(st); | 78 | sg_free_table(st); |
| 86 | err_free: | 79 | err_free: |
| 87 | kfree(st); | 80 | kfree(st); |
| 88 | err_unpin: | 81 | err_unpin_pages: |
| 89 | i915_gem_object_unpin_pages(obj); | 82 | i915_gem_object_unpin_pages(obj); |
| 90 | err_unlock: | ||
| 91 | mutex_unlock(&obj->base.dev->struct_mutex); | ||
| 92 | err: | 83 | err: |
| 93 | return ERR_PTR(ret); | 84 | return ERR_PTR(ret); |
| 94 | } | 85 | } |
| @@ -103,36 +94,21 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, | |||
| 103 | sg_free_table(sg); | 94 | sg_free_table(sg); |
| 104 | kfree(sg); | 95 | kfree(sg); |
| 105 | 96 | ||
| 106 | mutex_lock(&obj->base.dev->struct_mutex); | ||
| 107 | i915_gem_object_unpin_pages(obj); | 97 | i915_gem_object_unpin_pages(obj); |
| 108 | mutex_unlock(&obj->base.dev->struct_mutex); | ||
| 109 | } | 98 | } |
| 110 | 99 | ||
| 111 | static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf) | 100 | static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf) |
| 112 | { | 101 | { |
| 113 | struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); | 102 | struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); |
| 114 | struct drm_device *dev = obj->base.dev; | ||
| 115 | void *addr; | ||
| 116 | int ret; | ||
| 117 | 103 | ||
| 118 | ret = i915_mutex_lock_interruptible(dev); | 104 | return i915_gem_object_pin_map(obj, I915_MAP_WB); |
| 119 | if (ret) | ||
| 120 | return ERR_PTR(ret); | ||
| 121 | |||
| 122 | addr = i915_gem_object_pin_map(obj, I915_MAP_WB); | ||
| 123 | mutex_unlock(&dev->struct_mutex); | ||
| 124 | |||
| 125 | return addr; | ||
| 126 | } | 105 | } |
| 127 | 106 | ||
| 128 | static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr) | 107 | static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr) |
| 129 | { | 108 | { |
| 130 | struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); | 109 | struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); |
| 131 | struct drm_device *dev = obj->base.dev; | ||
| 132 | 110 | ||
| 133 | mutex_lock(&dev->struct_mutex); | ||
| 134 | i915_gem_object_unpin_map(obj); | 111 | i915_gem_object_unpin_map(obj); |
| 135 | mutex_unlock(&dev->struct_mutex); | ||
| 136 | } | 112 | } |
| 137 | 113 | ||
| 138 | static void *i915_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf, unsigned long page_num) | 114 | static void *i915_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf, unsigned long page_num) |
| @@ -179,32 +155,45 @@ static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, enum dma_data_dire | |||
| 179 | { | 155 | { |
| 180 | struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); | 156 | struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); |
| 181 | struct drm_device *dev = obj->base.dev; | 157 | struct drm_device *dev = obj->base.dev; |
| 182 | int ret; | ||
| 183 | bool write = (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE); | 158 | bool write = (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE); |
| 159 | int err; | ||
| 184 | 160 | ||
| 185 | ret = i915_mutex_lock_interruptible(dev); | 161 | err = i915_gem_object_pin_pages(obj); |
| 186 | if (ret) | 162 | if (err) |
| 187 | return ret; | 163 | return err; |
| 164 | |||
| 165 | err = i915_mutex_lock_interruptible(dev); | ||
| 166 | if (err) | ||
| 167 | goto out; | ||
| 188 | 168 | ||
| 189 | ret = i915_gem_object_set_to_cpu_domain(obj, write); | 169 | err = i915_gem_object_set_to_cpu_domain(obj, write); |
| 190 | mutex_unlock(&dev->struct_mutex); | 170 | mutex_unlock(&dev->struct_mutex); |
| 191 | return ret; | 171 | |
| 172 | out: | ||
| 173 | i915_gem_object_unpin_pages(obj); | ||
| 174 | return err; | ||
| 192 | } | 175 | } |
| 193 | 176 | ||
| 194 | static int i915_gem_end_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction) | 177 | static int i915_gem_end_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction) |
| 195 | { | 178 | { |
| 196 | struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); | 179 | struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); |
| 197 | struct drm_device *dev = obj->base.dev; | 180 | struct drm_device *dev = obj->base.dev; |
| 198 | int ret; | 181 | int err; |
| 199 | 182 | ||
| 200 | ret = i915_mutex_lock_interruptible(dev); | 183 | err = i915_gem_object_pin_pages(obj); |
| 201 | if (ret) | 184 | if (err) |
| 202 | return ret; | 185 | return err; |
| 203 | 186 | ||
| 204 | ret = i915_gem_object_set_to_gtt_domain(obj, false); | 187 | err = i915_mutex_lock_interruptible(dev); |
| 188 | if (err) | ||
| 189 | goto out; | ||
| 190 | |||
| 191 | err = i915_gem_object_set_to_gtt_domain(obj, false); | ||
| 205 | mutex_unlock(&dev->struct_mutex); | 192 | mutex_unlock(&dev->struct_mutex); |
| 206 | 193 | ||
| 207 | return ret; | 194 | out: |
| 195 | i915_gem_object_unpin_pages(obj); | ||
| 196 | return err; | ||
| 208 | } | 197 | } |
| 209 | 198 | ||
| 210 | static const struct dma_buf_ops i915_dmabuf_ops = { | 199 | static const struct dma_buf_ops i915_dmabuf_ops = { |
| @@ -222,60 +211,17 @@ static const struct dma_buf_ops i915_dmabuf_ops = { | |||
| 222 | .end_cpu_access = i915_gem_end_cpu_access, | 211 | .end_cpu_access = i915_gem_end_cpu_access, |
| 223 | }; | 212 | }; |
| 224 | 213 | ||
| 225 | static void export_fences(struct drm_i915_gem_object *obj, | ||
| 226 | struct dma_buf *dma_buf) | ||
| 227 | { | ||
| 228 | struct reservation_object *resv = dma_buf->resv; | ||
| 229 | struct drm_i915_gem_request *req; | ||
| 230 | unsigned long active; | ||
| 231 | int idx; | ||
| 232 | |||
| 233 | active = __I915_BO_ACTIVE(obj); | ||
| 234 | if (!active) | ||
| 235 | return; | ||
| 236 | |||
| 237 | /* Serialise with execbuf to prevent concurrent fence-loops */ | ||
| 238 | mutex_lock(&obj->base.dev->struct_mutex); | ||
| 239 | |||
| 240 | /* Mark the object for future fences before racily adding old fences */ | ||
| 241 | obj->base.dma_buf = dma_buf; | ||
| 242 | |||
| 243 | ww_mutex_lock(&resv->lock, NULL); | ||
| 244 | |||
| 245 | for_each_active(active, idx) { | ||
| 246 | req = i915_gem_active_get(&obj->last_read[idx], | ||
| 247 | &obj->base.dev->struct_mutex); | ||
| 248 | if (!req) | ||
| 249 | continue; | ||
| 250 | |||
| 251 | if (reservation_object_reserve_shared(resv) == 0) | ||
| 252 | reservation_object_add_shared_fence(resv, &req->fence); | ||
| 253 | |||
| 254 | i915_gem_request_put(req); | ||
| 255 | } | ||
| 256 | |||
| 257 | req = i915_gem_active_get(&obj->last_write, | ||
| 258 | &obj->base.dev->struct_mutex); | ||
| 259 | if (req) { | ||
| 260 | reservation_object_add_excl_fence(resv, &req->fence); | ||
| 261 | i915_gem_request_put(req); | ||
| 262 | } | ||
| 263 | |||
| 264 | ww_mutex_unlock(&resv->lock); | ||
| 265 | mutex_unlock(&obj->base.dev->struct_mutex); | ||
| 266 | } | ||
| 267 | |||
| 268 | struct dma_buf *i915_gem_prime_export(struct drm_device *dev, | 214 | struct dma_buf *i915_gem_prime_export(struct drm_device *dev, |
| 269 | struct drm_gem_object *gem_obj, int flags) | 215 | struct drm_gem_object *gem_obj, int flags) |
| 270 | { | 216 | { |
| 271 | struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); | 217 | struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); |
| 272 | DEFINE_DMA_BUF_EXPORT_INFO(exp_info); | 218 | DEFINE_DMA_BUF_EXPORT_INFO(exp_info); |
| 273 | struct dma_buf *dma_buf; | ||
| 274 | 219 | ||
| 275 | exp_info.ops = &i915_dmabuf_ops; | 220 | exp_info.ops = &i915_dmabuf_ops; |
| 276 | exp_info.size = gem_obj->size; | 221 | exp_info.size = gem_obj->size; |
| 277 | exp_info.flags = flags; | 222 | exp_info.flags = flags; |
| 278 | exp_info.priv = gem_obj; | 223 | exp_info.priv = gem_obj; |
| 224 | exp_info.resv = obj->resv; | ||
| 279 | 225 | ||
| 280 | if (obj->ops->dmabuf_export) { | 226 | if (obj->ops->dmabuf_export) { |
| 281 | int ret = obj->ops->dmabuf_export(obj); | 227 | int ret = obj->ops->dmabuf_export(obj); |
| @@ -283,30 +229,21 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev, | |||
| 283 | return ERR_PTR(ret); | 229 | return ERR_PTR(ret); |
| 284 | } | 230 | } |
| 285 | 231 | ||
| 286 | dma_buf = drm_gem_dmabuf_export(dev, &exp_info); | 232 | return drm_gem_dmabuf_export(dev, &exp_info); |
| 287 | if (IS_ERR(dma_buf)) | ||
| 288 | return dma_buf; | ||
| 289 | |||
| 290 | export_fences(obj, dma_buf); | ||
| 291 | return dma_buf; | ||
| 292 | } | 233 | } |
| 293 | 234 | ||
| 294 | static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj) | 235 | static struct sg_table * |
| 236 | i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj) | ||
| 295 | { | 237 | { |
| 296 | struct sg_table *sg; | 238 | return dma_buf_map_attachment(obj->base.import_attach, |
| 297 | 239 | DMA_BIDIRECTIONAL); | |
| 298 | sg = dma_buf_map_attachment(obj->base.import_attach, DMA_BIDIRECTIONAL); | ||
| 299 | if (IS_ERR(sg)) | ||
| 300 | return PTR_ERR(sg); | ||
| 301 | |||
| 302 | obj->pages = sg; | ||
| 303 | return 0; | ||
| 304 | } | 240 | } |
| 305 | 241 | ||
| 306 | static void i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object *obj) | 242 | static void i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object *obj, |
| 243 | struct sg_table *pages) | ||
| 307 | { | 244 | { |
| 308 | dma_buf_unmap_attachment(obj->base.import_attach, | 245 | dma_buf_unmap_attachment(obj->base.import_attach, pages, |
| 309 | obj->pages, DMA_BIDIRECTIONAL); | 246 | DMA_BIDIRECTIONAL); |
| 310 | } | 247 | } |
| 311 | 248 | ||
| 312 | static const struct drm_i915_gem_object_ops i915_gem_object_dmabuf_ops = { | 249 | static const struct drm_i915_gem_object_ops i915_gem_object_dmabuf_ops = { |
| @@ -350,6 +287,7 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev, | |||
| 350 | drm_gem_private_object_init(dev, &obj->base, dma_buf->size); | 287 | drm_gem_private_object_init(dev, &obj->base, dma_buf->size); |
| 351 | i915_gem_object_init(obj, &i915_gem_object_dmabuf_ops); | 288 | i915_gem_object_init(obj, &i915_gem_object_dmabuf_ops); |
| 352 | obj->base.import_attach = attach; | 289 | obj->base.import_attach = attach; |
| 290 | obj->resv = dma_buf->resv; | ||
| 353 | 291 | ||
| 354 | /* We use GTT as shorthand for a coherent domain, one that is | 292 | /* We use GTT as shorthand for a coherent domain, one that is |
| 355 | * neither in the GPU cache nor in the CPU cache, where all | 293 | * neither in the GPU cache nor in the CPU cache, where all |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index b5e9e669f50f..bd08814b015c 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
| @@ -33,14 +33,17 @@ | |||
| 33 | #include "intel_drv.h" | 33 | #include "intel_drv.h" |
| 34 | #include "i915_trace.h" | 34 | #include "i915_trace.h" |
| 35 | 35 | ||
| 36 | static bool | 36 | static bool ggtt_is_idle(struct drm_i915_private *dev_priv) |
| 37 | gpu_is_idle(struct drm_i915_private *dev_priv) | ||
| 38 | { | 37 | { |
| 38 | struct i915_ggtt *ggtt = &dev_priv->ggtt; | ||
| 39 | struct intel_engine_cs *engine; | 39 | struct intel_engine_cs *engine; |
| 40 | enum intel_engine_id id; | 40 | enum intel_engine_id id; |
| 41 | 41 | ||
| 42 | for_each_engine(engine, dev_priv, id) { | 42 | for_each_engine(engine, dev_priv, id) { |
| 43 | if (intel_engine_is_active(engine)) | 43 | struct intel_timeline *tl; |
| 44 | |||
| 45 | tl = &ggtt->base.timeline.engine[engine->id]; | ||
| 46 | if (i915_gem_active_isset(&tl->last_request)) | ||
| 44 | return false; | 47 | return false; |
| 45 | } | 48 | } |
| 46 | 49 | ||
| @@ -56,7 +59,7 @@ mark_free(struct i915_vma *vma, unsigned int flags, struct list_head *unwind) | |||
| 56 | if (WARN_ON(!list_empty(&vma->exec_list))) | 59 | if (WARN_ON(!list_empty(&vma->exec_list))) |
| 57 | return false; | 60 | return false; |
| 58 | 61 | ||
| 59 | if (flags & PIN_NONFAULT && vma->obj->fault_mappable) | 62 | if (flags & PIN_NONFAULT && !list_empty(&vma->obj->userfault_link)) |
| 60 | return false; | 63 | return false; |
| 61 | 64 | ||
| 62 | list_add(&vma->exec_list, unwind); | 65 | list_add(&vma->exec_list, unwind); |
| @@ -103,6 +106,7 @@ i915_gem_evict_something(struct i915_address_space *vm, | |||
| 103 | struct i915_vma *vma, *next; | 106 | struct i915_vma *vma, *next; |
| 104 | int ret; | 107 | int ret; |
| 105 | 108 | ||
| 109 | lockdep_assert_held(&vm->dev->struct_mutex); | ||
| 106 | trace_i915_gem_evict(vm, min_size, alignment, flags); | 110 | trace_i915_gem_evict(vm, min_size, alignment, flags); |
| 107 | 111 | ||
| 108 | /* | 112 | /* |
| @@ -153,7 +157,7 @@ search_again: | |||
| 153 | if (!i915_is_ggtt(vm) || flags & PIN_NONBLOCK) | 157 | if (!i915_is_ggtt(vm) || flags & PIN_NONBLOCK) |
| 154 | return -ENOSPC; | 158 | return -ENOSPC; |
| 155 | 159 | ||
| 156 | if (gpu_is_idle(dev_priv)) { | 160 | if (ggtt_is_idle(dev_priv)) { |
| 157 | /* If we still have pending pageflip completions, drop | 161 | /* If we still have pending pageflip completions, drop |
| 158 | * back to userspace to give our workqueues time to | 162 | * back to userspace to give our workqueues time to |
| 159 | * acquire our locks and unpin the old scanouts. | 163 | * acquire our locks and unpin the old scanouts. |
| @@ -213,6 +217,8 @@ i915_gem_evict_for_vma(struct i915_vma *target) | |||
| 213 | { | 217 | { |
| 214 | struct drm_mm_node *node, *next; | 218 | struct drm_mm_node *node, *next; |
| 215 | 219 | ||
| 220 | lockdep_assert_held(&target->vm->dev->struct_mutex); | ||
| 221 | |||
| 216 | list_for_each_entry_safe(node, next, | 222 | list_for_each_entry_safe(node, next, |
| 217 | &target->vm->mm.head_node.node_list, | 223 | &target->vm->mm.head_node.node_list, |
| 218 | node_list) { | 224 | node_list) { |
| @@ -266,7 +272,7 @@ int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle) | |||
| 266 | struct i915_vma *vma, *next; | 272 | struct i915_vma *vma, *next; |
| 267 | int ret; | 273 | int ret; |
| 268 | 274 | ||
| 269 | WARN_ON(!mutex_is_locked(&vm->dev->struct_mutex)); | 275 | lockdep_assert_held(&vm->dev->struct_mutex); |
| 270 | trace_i915_gem_evict_vm(vm); | 276 | trace_i915_gem_evict_vm(vm); |
| 271 | 277 | ||
| 272 | if (do_idle) { | 278 | if (do_idle) { |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index e52affdcc125..fb5b44339f71 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
| @@ -34,7 +34,6 @@ | |||
| 34 | #include <drm/i915_drm.h> | 34 | #include <drm/i915_drm.h> |
| 35 | 35 | ||
| 36 | #include "i915_drv.h" | 36 | #include "i915_drv.h" |
| 37 | #include "i915_gem_dmabuf.h" | ||
| 38 | #include "i915_trace.h" | 37 | #include "i915_trace.h" |
| 39 | #include "intel_drv.h" | 38 | #include "intel_drv.h" |
| 40 | #include "intel_frontbuffer.h" | 39 | #include "intel_frontbuffer.h" |
| @@ -332,7 +331,8 @@ static void reloc_cache_init(struct reloc_cache *cache, | |||
| 332 | cache->page = -1; | 331 | cache->page = -1; |
| 333 | cache->vaddr = 0; | 332 | cache->vaddr = 0; |
| 334 | cache->i915 = i915; | 333 | cache->i915 = i915; |
| 335 | cache->use_64bit_reloc = INTEL_GEN(cache->i915) >= 8; | 334 | /* Must be a variable in the struct to allow GCC to unroll. */ |
| 335 | cache->use_64bit_reloc = HAS_64BIT_RELOC(i915); | ||
| 336 | cache->node.allocated = false; | 336 | cache->node.allocated = false; |
| 337 | } | 337 | } |
| 338 | 338 | ||
| @@ -418,15 +418,6 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj, | |||
| 418 | unsigned long offset; | 418 | unsigned long offset; |
| 419 | void *vaddr; | 419 | void *vaddr; |
| 420 | 420 | ||
| 421 | if (cache->node.allocated) { | ||
| 422 | wmb(); | ||
| 423 | ggtt->base.insert_page(&ggtt->base, | ||
| 424 | i915_gem_object_get_dma_address(obj, page), | ||
| 425 | cache->node.start, I915_CACHE_NONE, 0); | ||
| 426 | cache->page = page; | ||
| 427 | return unmask_page(cache->vaddr); | ||
| 428 | } | ||
| 429 | |||
| 430 | if (cache->vaddr) { | 421 | if (cache->vaddr) { |
| 431 | io_mapping_unmap_atomic((void __force __iomem *) unmask_page(cache->vaddr)); | 422 | io_mapping_unmap_atomic((void __force __iomem *) unmask_page(cache->vaddr)); |
| 432 | } else { | 423 | } else { |
| @@ -466,6 +457,7 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj, | |||
| 466 | 457 | ||
| 467 | offset = cache->node.start; | 458 | offset = cache->node.start; |
| 468 | if (cache->node.allocated) { | 459 | if (cache->node.allocated) { |
| 460 | wmb(); | ||
| 469 | ggtt->base.insert_page(&ggtt->base, | 461 | ggtt->base.insert_page(&ggtt->base, |
| 470 | i915_gem_object_get_dma_address(obj, page), | 462 | i915_gem_object_get_dma_address(obj, page), |
| 471 | offset, I915_CACHE_NONE, 0); | 463 | offset, I915_CACHE_NONE, 0); |
| @@ -1109,44 +1101,20 @@ err: | |||
| 1109 | return ret; | 1101 | return ret; |
| 1110 | } | 1102 | } |
| 1111 | 1103 | ||
| 1112 | static unsigned int eb_other_engines(struct drm_i915_gem_request *req) | ||
| 1113 | { | ||
| 1114 | unsigned int mask; | ||
| 1115 | |||
| 1116 | mask = ~intel_engine_flag(req->engine) & I915_BO_ACTIVE_MASK; | ||
| 1117 | mask <<= I915_BO_ACTIVE_SHIFT; | ||
| 1118 | |||
| 1119 | return mask; | ||
| 1120 | } | ||
| 1121 | |||
| 1122 | static int | 1104 | static int |
| 1123 | i915_gem_execbuffer_move_to_gpu(struct drm_i915_gem_request *req, | 1105 | i915_gem_execbuffer_move_to_gpu(struct drm_i915_gem_request *req, |
| 1124 | struct list_head *vmas) | 1106 | struct list_head *vmas) |
| 1125 | { | 1107 | { |
| 1126 | const unsigned int other_rings = eb_other_engines(req); | ||
| 1127 | struct i915_vma *vma; | 1108 | struct i915_vma *vma; |
| 1128 | int ret; | 1109 | int ret; |
| 1129 | 1110 | ||
| 1130 | list_for_each_entry(vma, vmas, exec_list) { | 1111 | list_for_each_entry(vma, vmas, exec_list) { |
| 1131 | struct drm_i915_gem_object *obj = vma->obj; | 1112 | struct drm_i915_gem_object *obj = vma->obj; |
| 1132 | struct reservation_object *resv; | ||
| 1133 | 1113 | ||
| 1134 | if (obj->flags & other_rings) { | 1114 | ret = i915_gem_request_await_object |
| 1135 | ret = i915_gem_request_await_object | 1115 | (req, obj, obj->base.pending_write_domain); |
| 1136 | (req, obj, obj->base.pending_write_domain); | 1116 | if (ret) |
| 1137 | if (ret) | 1117 | return ret; |
| 1138 | return ret; | ||
| 1139 | } | ||
| 1140 | |||
| 1141 | resv = i915_gem_object_get_dmabuf_resv(obj); | ||
| 1142 | if (resv) { | ||
| 1143 | ret = i915_sw_fence_await_reservation | ||
| 1144 | (&req->submit, resv, &i915_fence_ops, | ||
| 1145 | obj->base.pending_write_domain, 10*HZ, | ||
| 1146 | GFP_KERNEL | __GFP_NOWARN); | ||
| 1147 | if (ret < 0) | ||
| 1148 | return ret; | ||
| 1149 | } | ||
| 1150 | 1118 | ||
| 1151 | if (obj->base.write_domain & I915_GEM_DOMAIN_CPU) | 1119 | if (obj->base.write_domain & I915_GEM_DOMAIN_CPU) |
| 1152 | i915_gem_clflush_object(obj, false); | 1120 | i915_gem_clflush_object(obj, false); |
| @@ -1279,6 +1247,12 @@ i915_gem_validate_context(struct drm_device *dev, struct drm_file *file, | |||
| 1279 | return ctx; | 1247 | return ctx; |
| 1280 | } | 1248 | } |
| 1281 | 1249 | ||
| 1250 | static bool gpu_write_needs_clflush(struct drm_i915_gem_object *obj) | ||
| 1251 | { | ||
| 1252 | return !(obj->cache_level == I915_CACHE_NONE || | ||
| 1253 | obj->cache_level == I915_CACHE_WT); | ||
| 1254 | } | ||
| 1255 | |||
| 1282 | void i915_vma_move_to_active(struct i915_vma *vma, | 1256 | void i915_vma_move_to_active(struct i915_vma *vma, |
| 1283 | struct drm_i915_gem_request *req, | 1257 | struct drm_i915_gem_request *req, |
| 1284 | unsigned int flags) | 1258 | unsigned int flags) |
| @@ -1288,8 +1262,6 @@ void i915_vma_move_to_active(struct i915_vma *vma, | |||
| 1288 | 1262 | ||
| 1289 | GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); | 1263 | GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); |
| 1290 | 1264 | ||
| 1291 | obj->dirty = 1; /* be paranoid */ | ||
| 1292 | |||
| 1293 | /* Add a reference if we're newly entering the active list. | 1265 | /* Add a reference if we're newly entering the active list. |
| 1294 | * The order in which we add operations to the retirement queue is | 1266 | * The order in which we add operations to the retirement queue is |
| 1295 | * vital here: mark_active adds to the start of the callback list, | 1267 | * vital here: mark_active adds to the start of the callback list, |
| @@ -1297,37 +1269,32 @@ void i915_vma_move_to_active(struct i915_vma *vma, | |||
| 1297 | * add the active reference first and queue for it to be dropped | 1269 | * add the active reference first and queue for it to be dropped |
| 1298 | * *last*. | 1270 | * *last*. |
| 1299 | */ | 1271 | */ |
| 1300 | if (!i915_gem_object_is_active(obj)) | 1272 | if (!i915_vma_is_active(vma)) |
| 1301 | i915_gem_object_get(obj); | 1273 | obj->active_count++; |
| 1302 | i915_gem_object_set_active(obj, idx); | 1274 | i915_vma_set_active(vma, idx); |
| 1303 | i915_gem_active_set(&obj->last_read[idx], req); | 1275 | i915_gem_active_set(&vma->last_read[idx], req); |
| 1276 | list_move_tail(&vma->vm_link, &vma->vm->active_list); | ||
| 1304 | 1277 | ||
| 1305 | if (flags & EXEC_OBJECT_WRITE) { | 1278 | if (flags & EXEC_OBJECT_WRITE) { |
| 1306 | i915_gem_active_set(&obj->last_write, req); | 1279 | i915_gem_active_set(&vma->last_write, req); |
| 1307 | 1280 | ||
| 1308 | intel_fb_obj_invalidate(obj, ORIGIN_CS); | 1281 | intel_fb_obj_invalidate(obj, ORIGIN_CS); |
| 1309 | 1282 | ||
| 1310 | /* update for the implicit flush after a batch */ | 1283 | /* update for the implicit flush after a batch */ |
| 1311 | obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS; | 1284 | obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS; |
| 1285 | if (!obj->cache_dirty && gpu_write_needs_clflush(obj)) | ||
| 1286 | obj->cache_dirty = true; | ||
| 1312 | } | 1287 | } |
| 1313 | 1288 | ||
| 1314 | if (flags & EXEC_OBJECT_NEEDS_FENCE) | 1289 | if (flags & EXEC_OBJECT_NEEDS_FENCE) |
| 1315 | i915_gem_active_set(&vma->last_fence, req); | 1290 | i915_gem_active_set(&vma->last_fence, req); |
| 1316 | |||
| 1317 | i915_vma_set_active(vma, idx); | ||
| 1318 | i915_gem_active_set(&vma->last_read[idx], req); | ||
| 1319 | list_move_tail(&vma->vm_link, &vma->vm->active_list); | ||
| 1320 | } | 1291 | } |
| 1321 | 1292 | ||
| 1322 | static void eb_export_fence(struct drm_i915_gem_object *obj, | 1293 | static void eb_export_fence(struct drm_i915_gem_object *obj, |
| 1323 | struct drm_i915_gem_request *req, | 1294 | struct drm_i915_gem_request *req, |
| 1324 | unsigned int flags) | 1295 | unsigned int flags) |
| 1325 | { | 1296 | { |
| 1326 | struct reservation_object *resv; | 1297 | struct reservation_object *resv = obj->resv; |
| 1327 | |||
| 1328 | resv = i915_gem_object_get_dmabuf_resv(obj); | ||
| 1329 | if (!resv) | ||
| 1330 | return; | ||
| 1331 | 1298 | ||
| 1332 | /* Ignore errors from failing to allocate the new fence, we can't | 1299 | /* Ignore errors from failing to allocate the new fence, we can't |
| 1333 | * handle an error right now. Worst case should be missed | 1300 | * handle an error right now. Worst case should be missed |
diff --git a/drivers/gpu/drm/i915/i915_gem_fence.c b/drivers/gpu/drm/i915/i915_gem_fence.c index a6daf2deab74..cd59dbc6588c 100644 --- a/drivers/gpu/drm/i915/i915_gem_fence.c +++ b/drivers/gpu/drm/i915/i915_gem_fence.c | |||
| @@ -343,6 +343,9 @@ i915_vma_get_fence(struct i915_vma *vma) | |||
| 343 | struct drm_i915_fence_reg *fence; | 343 | struct drm_i915_fence_reg *fence; |
| 344 | struct i915_vma *set = i915_gem_object_is_tiled(vma->obj) ? vma : NULL; | 344 | struct i915_vma *set = i915_gem_object_is_tiled(vma->obj) ? vma : NULL; |
| 345 | 345 | ||
| 346 | /* Note that we revoke fences on runtime suspend. Therefore the user | ||
| 347 | * must keep the device awake whilst using the fence. | ||
| 348 | */ | ||
| 346 | assert_rpm_wakelock_held(to_i915(vma->vm->dev)); | 349 | assert_rpm_wakelock_held(to_i915(vma->vm->dev)); |
| 347 | 350 | ||
| 348 | /* Just update our place in the LRU if our fence is getting reused. */ | 351 | /* Just update our place in the LRU if our fence is getting reused. */ |
| @@ -368,19 +371,14 @@ i915_vma_get_fence(struct i915_vma *vma) | |||
| 368 | * @dev: DRM device | 371 | * @dev: DRM device |
| 369 | * | 372 | * |
| 370 | * Restore the hw fence state to match the software tracking again, to be called | 373 | * Restore the hw fence state to match the software tracking again, to be called |
| 371 | * after a gpu reset and on resume. | 374 | * after a gpu reset and on resume. Note that on runtime suspend we only cancel |
| 375 | * the fences, to be reacquired by the user later. | ||
| 372 | */ | 376 | */ |
| 373 | void i915_gem_restore_fences(struct drm_device *dev) | 377 | void i915_gem_restore_fences(struct drm_device *dev) |
| 374 | { | 378 | { |
| 375 | struct drm_i915_private *dev_priv = to_i915(dev); | 379 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 376 | int i; | 380 | int i; |
| 377 | 381 | ||
| 378 | /* Note that this may be called outside of struct_mutex, by | ||
| 379 | * runtime suspend/resume. The barrier we require is enforced by | ||
| 380 | * rpm itself - all access to fences/GTT are only within an rpm | ||
| 381 | * wakeref, and to acquire that wakeref you must pass through here. | ||
| 382 | */ | ||
| 383 | |||
| 384 | for (i = 0; i < dev_priv->num_fence_regs; i++) { | 382 | for (i = 0; i < dev_priv->num_fence_regs; i++) { |
| 385 | struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; | 383 | struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; |
| 386 | struct i915_vma *vma = reg->vma; | 384 | struct i915_vma *vma = reg->vma; |
| @@ -391,7 +389,7 @@ void i915_gem_restore_fences(struct drm_device *dev) | |||
| 391 | */ | 389 | */ |
| 392 | if (vma && !i915_gem_object_is_tiled(vma->obj)) { | 390 | if (vma && !i915_gem_object_is_tiled(vma->obj)) { |
| 393 | GEM_BUG_ON(!reg->dirty); | 391 | GEM_BUG_ON(!reg->dirty); |
| 394 | GEM_BUG_ON(vma->obj->fault_mappable); | 392 | GEM_BUG_ON(!list_empty(&vma->obj->userfault_link)); |
| 395 | 393 | ||
| 396 | list_move(®->link, &dev_priv->mm.fence_list); | 394 | list_move(®->link, &dev_priv->mm.fence_list); |
| 397 | vma->fence = NULL; | 395 | vma->fence = NULL; |
| @@ -646,6 +644,7 @@ i915_gem_swizzle_page(struct page *page) | |||
| 646 | /** | 644 | /** |
| 647 | * i915_gem_object_do_bit_17_swizzle - fixup bit 17 swizzling | 645 | * i915_gem_object_do_bit_17_swizzle - fixup bit 17 swizzling |
| 648 | * @obj: i915 GEM buffer object | 646 | * @obj: i915 GEM buffer object |
| 647 | * @pages: the scattergather list of physical pages | ||
| 649 | * | 648 | * |
| 650 | * This function fixes up the swizzling in case any page frame number for this | 649 | * This function fixes up the swizzling in case any page frame number for this |
| 651 | * object has changed in bit 17 since that state has been saved with | 650 | * object has changed in bit 17 since that state has been saved with |
| @@ -656,7 +655,8 @@ i915_gem_swizzle_page(struct page *page) | |||
| 656 | * by swapping them out and back in again). | 655 | * by swapping them out and back in again). |
| 657 | */ | 656 | */ |
| 658 | void | 657 | void |
| 659 | i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj) | 658 | i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj, |
| 659 | struct sg_table *pages) | ||
| 660 | { | 660 | { |
| 661 | struct sgt_iter sgt_iter; | 661 | struct sgt_iter sgt_iter; |
| 662 | struct page *page; | 662 | struct page *page; |
| @@ -666,10 +666,9 @@ i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj) | |||
| 666 | return; | 666 | return; |
| 667 | 667 | ||
| 668 | i = 0; | 668 | i = 0; |
| 669 | for_each_sgt_page(page, sgt_iter, obj->pages) { | 669 | for_each_sgt_page(page, sgt_iter, pages) { |
| 670 | char new_bit_17 = page_to_phys(page) >> 17; | 670 | char new_bit_17 = page_to_phys(page) >> 17; |
| 671 | if ((new_bit_17 & 0x1) != | 671 | if ((new_bit_17 & 0x1) != (test_bit(i, obj->bit_17) != 0)) { |
| 672 | (test_bit(i, obj->bit_17) != 0)) { | ||
| 673 | i915_gem_swizzle_page(page); | 672 | i915_gem_swizzle_page(page); |
| 674 | set_page_dirty(page); | 673 | set_page_dirty(page); |
| 675 | } | 674 | } |
| @@ -680,17 +679,19 @@ i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj) | |||
| 680 | /** | 679 | /** |
| 681 | * i915_gem_object_save_bit_17_swizzle - save bit 17 swizzling | 680 | * i915_gem_object_save_bit_17_swizzle - save bit 17 swizzling |
| 682 | * @obj: i915 GEM buffer object | 681 | * @obj: i915 GEM buffer object |
| 682 | * @pages: the scattergather list of physical pages | ||
| 683 | * | 683 | * |
| 684 | * This function saves the bit 17 of each page frame number so that swizzling | 684 | * This function saves the bit 17 of each page frame number so that swizzling |
| 685 | * can be fixed up later on with i915_gem_object_do_bit_17_swizzle(). This must | 685 | * can be fixed up later on with i915_gem_object_do_bit_17_swizzle(). This must |
| 686 | * be called before the backing storage can be unpinned. | 686 | * be called before the backing storage can be unpinned. |
| 687 | */ | 687 | */ |
| 688 | void | 688 | void |
| 689 | i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj) | 689 | i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj, |
| 690 | struct sg_table *pages) | ||
| 690 | { | 691 | { |
| 692 | const unsigned int page_count = obj->base.size >> PAGE_SHIFT; | ||
| 691 | struct sgt_iter sgt_iter; | 693 | struct sgt_iter sgt_iter; |
| 692 | struct page *page; | 694 | struct page *page; |
| 693 | int page_count = obj->base.size >> PAGE_SHIFT; | ||
| 694 | int i; | 695 | int i; |
| 695 | 696 | ||
| 696 | if (obj->bit_17 == NULL) { | 697 | if (obj->bit_17 == NULL) { |
| @@ -705,7 +706,7 @@ i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj) | |||
| 705 | 706 | ||
| 706 | i = 0; | 707 | i = 0; |
| 707 | 708 | ||
| 708 | for_each_sgt_page(page, sgt_iter, obj->pages) { | 709 | for_each_sgt_page(page, sgt_iter, pages) { |
| 709 | if (page_to_phys(page) & (1 << 17)) | 710 | if (page_to_phys(page) & (1 << 17)) |
| 710 | __set_bit(i, obj->bit_17); | 711 | __set_bit(i, obj->bit_17); |
| 711 | else | 712 | else |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 062fb0ad75da..a5fafa3d4fc8 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include "i915_vgpu.h" | 31 | #include "i915_vgpu.h" |
| 32 | #include "i915_trace.h" | 32 | #include "i915_trace.h" |
| 33 | #include "intel_drv.h" | 33 | #include "intel_drv.h" |
| 34 | #include "intel_frontbuffer.h" | ||
| 34 | 35 | ||
| 35 | #define I915_GFP_DMA (GFP_KERNEL | __GFP_HIGHMEM) | 36 | #define I915_GFP_DMA (GFP_KERNEL | __GFP_HIGHMEM) |
| 36 | 37 | ||
| @@ -175,7 +176,7 @@ static int ppgtt_bind_vma(struct i915_vma *vma, | |||
| 175 | { | 176 | { |
| 176 | u32 pte_flags = 0; | 177 | u32 pte_flags = 0; |
| 177 | 178 | ||
| 178 | vma->pages = vma->obj->pages; | 179 | vma->pages = vma->obj->mm.pages; |
| 179 | 180 | ||
| 180 | /* Currently applicable only to VLV */ | 181 | /* Currently applicable only to VLV */ |
| 181 | if (vma->obj->gt_ro) | 182 | if (vma->obj->gt_ro) |
| @@ -706,6 +707,16 @@ static int gen8_48b_mm_switch(struct i915_hw_ppgtt *ppgtt, | |||
| 706 | return gen8_write_pdp(req, 0, px_dma(&ppgtt->pml4)); | 707 | return gen8_write_pdp(req, 0, px_dma(&ppgtt->pml4)); |
| 707 | } | 708 | } |
| 708 | 709 | ||
| 710 | /* PDE TLBs are a pain to invalidate on GEN8+. When we modify | ||
| 711 | * the page table structures, we mark them dirty so that | ||
| 712 | * context switching/execlist queuing code takes extra steps | ||
| 713 | * to ensure that tlbs are flushed. | ||
| 714 | */ | ||
| 715 | static void mark_tlbs_dirty(struct i915_hw_ppgtt *ppgtt) | ||
| 716 | { | ||
| 717 | ppgtt->pd_dirty_rings = INTEL_INFO(ppgtt->base.dev)->ring_mask; | ||
| 718 | } | ||
| 719 | |||
| 709 | /* Removes entries from a single page table, releasing it if it's empty. | 720 | /* Removes entries from a single page table, releasing it if it's empty. |
| 710 | * Caller can use the return value to update higher-level entries. | 721 | * Caller can use the return value to update higher-level entries. |
| 711 | */ | 722 | */ |
| @@ -715,9 +726,9 @@ static bool gen8_ppgtt_clear_pt(struct i915_address_space *vm, | |||
| 715 | uint64_t length) | 726 | uint64_t length) |
| 716 | { | 727 | { |
| 717 | struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm); | 728 | struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm); |
| 718 | unsigned int pte_start = gen8_pte_index(start); | ||
| 719 | unsigned int num_entries = gen8_pte_count(start, length); | 729 | unsigned int num_entries = gen8_pte_count(start, length); |
| 720 | uint64_t pte; | 730 | unsigned int pte = gen8_pte_index(start); |
| 731 | unsigned int pte_end = pte + num_entries; | ||
| 721 | gen8_pte_t *pt_vaddr; | 732 | gen8_pte_t *pt_vaddr; |
| 722 | gen8_pte_t scratch_pte = gen8_pte_encode(vm->scratch_page.daddr, | 733 | gen8_pte_t scratch_pte = gen8_pte_encode(vm->scratch_page.daddr, |
| 723 | I915_CACHE_LLC); | 734 | I915_CACHE_LLC); |
| @@ -725,7 +736,9 @@ static bool gen8_ppgtt_clear_pt(struct i915_address_space *vm, | |||
| 725 | if (WARN_ON(!px_page(pt))) | 736 | if (WARN_ON(!px_page(pt))) |
| 726 | return false; | 737 | return false; |
| 727 | 738 | ||
| 728 | bitmap_clear(pt->used_ptes, pte_start, num_entries); | 739 | GEM_BUG_ON(pte_end > GEN8_PTES); |
| 740 | |||
| 741 | bitmap_clear(pt->used_ptes, pte, num_entries); | ||
| 729 | 742 | ||
| 730 | if (bitmap_empty(pt->used_ptes, GEN8_PTES)) { | 743 | if (bitmap_empty(pt->used_ptes, GEN8_PTES)) { |
| 731 | free_pt(vm->dev, pt); | 744 | free_pt(vm->dev, pt); |
| @@ -734,8 +747,8 @@ static bool gen8_ppgtt_clear_pt(struct i915_address_space *vm, | |||
| 734 | 747 | ||
| 735 | pt_vaddr = kmap_px(pt); | 748 | pt_vaddr = kmap_px(pt); |
| 736 | 749 | ||
| 737 | for (pte = pte_start; pte < num_entries; pte++) | 750 | while (pte < pte_end) |
| 738 | pt_vaddr[pte] = scratch_pte; | 751 | pt_vaddr[pte++] = scratch_pte; |
| 739 | 752 | ||
| 740 | kunmap_px(ppgtt, pt_vaddr); | 753 | kunmap_px(ppgtt, pt_vaddr); |
| 741 | 754 | ||
| @@ -806,6 +819,8 @@ static bool gen8_ppgtt_clear_pdp(struct i915_address_space *vm, | |||
| 806 | } | 819 | } |
| 807 | } | 820 | } |
| 808 | 821 | ||
| 822 | mark_tlbs_dirty(ppgtt); | ||
| 823 | |||
| 809 | if (USES_FULL_48BIT_PPGTT(vm->dev) && | 824 | if (USES_FULL_48BIT_PPGTT(vm->dev) && |
| 810 | bitmap_empty(pdp->used_pdpes, I915_PDPES_PER_PDP(vm->dev))) { | 825 | bitmap_empty(pdp->used_pdpes, I915_PDPES_PER_PDP(vm->dev))) { |
| 811 | free_pdp(vm->dev, pdp); | 826 | free_pdp(vm->dev, pdp); |
| @@ -1280,16 +1295,6 @@ err_out: | |||
| 1280 | return -ENOMEM; | 1295 | return -ENOMEM; |
| 1281 | } | 1296 | } |
| 1282 | 1297 | ||
| 1283 | /* PDE TLBs are a pain to invalidate on GEN8+. When we modify | ||
| 1284 | * the page table structures, we mark them dirty so that | ||
| 1285 | * context switching/execlist queuing code takes extra steps | ||
| 1286 | * to ensure that tlbs are flushed. | ||
| 1287 | */ | ||
| 1288 | static void mark_tlbs_dirty(struct i915_hw_ppgtt *ppgtt) | ||
| 1289 | { | ||
| 1290 | ppgtt->pd_dirty_rings = INTEL_INFO(ppgtt->base.dev)->ring_mask; | ||
| 1291 | } | ||
| 1292 | |||
| 1293 | static int gen8_alloc_va_range_3lvl(struct i915_address_space *vm, | 1298 | static int gen8_alloc_va_range_3lvl(struct i915_address_space *vm, |
| 1294 | struct i915_page_directory_pointer *pdp, | 1299 | struct i915_page_directory_pointer *pdp, |
| 1295 | uint64_t start, | 1300 | uint64_t start, |
| @@ -2184,8 +2189,10 @@ static int __hw_ppgtt_init(struct i915_hw_ppgtt *ppgtt, | |||
| 2184 | } | 2189 | } |
| 2185 | 2190 | ||
| 2186 | static void i915_address_space_init(struct i915_address_space *vm, | 2191 | static void i915_address_space_init(struct i915_address_space *vm, |
| 2187 | struct drm_i915_private *dev_priv) | 2192 | struct drm_i915_private *dev_priv, |
| 2193 | const char *name) | ||
| 2188 | { | 2194 | { |
| 2195 | i915_gem_timeline_init(dev_priv, &vm->timeline, name); | ||
| 2189 | drm_mm_init(&vm->mm, vm->start, vm->total); | 2196 | drm_mm_init(&vm->mm, vm->start, vm->total); |
| 2190 | INIT_LIST_HEAD(&vm->active_list); | 2197 | INIT_LIST_HEAD(&vm->active_list); |
| 2191 | INIT_LIST_HEAD(&vm->inactive_list); | 2198 | INIT_LIST_HEAD(&vm->inactive_list); |
| @@ -2214,14 +2221,15 @@ static void gtt_write_workarounds(struct drm_device *dev) | |||
| 2214 | 2221 | ||
| 2215 | static int i915_ppgtt_init(struct i915_hw_ppgtt *ppgtt, | 2222 | static int i915_ppgtt_init(struct i915_hw_ppgtt *ppgtt, |
| 2216 | struct drm_i915_private *dev_priv, | 2223 | struct drm_i915_private *dev_priv, |
| 2217 | struct drm_i915_file_private *file_priv) | 2224 | struct drm_i915_file_private *file_priv, |
| 2225 | const char *name) | ||
| 2218 | { | 2226 | { |
| 2219 | int ret; | 2227 | int ret; |
| 2220 | 2228 | ||
| 2221 | ret = __hw_ppgtt_init(ppgtt, dev_priv); | 2229 | ret = __hw_ppgtt_init(ppgtt, dev_priv); |
| 2222 | if (ret == 0) { | 2230 | if (ret == 0) { |
| 2223 | kref_init(&ppgtt->ref); | 2231 | kref_init(&ppgtt->ref); |
| 2224 | i915_address_space_init(&ppgtt->base, dev_priv); | 2232 | i915_address_space_init(&ppgtt->base, dev_priv, name); |
| 2225 | ppgtt->base.file = file_priv; | 2233 | ppgtt->base.file = file_priv; |
| 2226 | } | 2234 | } |
| 2227 | 2235 | ||
| @@ -2257,7 +2265,8 @@ int i915_ppgtt_init_hw(struct drm_device *dev) | |||
| 2257 | 2265 | ||
| 2258 | struct i915_hw_ppgtt * | 2266 | struct i915_hw_ppgtt * |
| 2259 | i915_ppgtt_create(struct drm_i915_private *dev_priv, | 2267 | i915_ppgtt_create(struct drm_i915_private *dev_priv, |
| 2260 | struct drm_i915_file_private *fpriv) | 2268 | struct drm_i915_file_private *fpriv, |
| 2269 | const char *name) | ||
| 2261 | { | 2270 | { |
| 2262 | struct i915_hw_ppgtt *ppgtt; | 2271 | struct i915_hw_ppgtt *ppgtt; |
| 2263 | int ret; | 2272 | int ret; |
| @@ -2266,7 +2275,7 @@ i915_ppgtt_create(struct drm_i915_private *dev_priv, | |||
| 2266 | if (!ppgtt) | 2275 | if (!ppgtt) |
| 2267 | return ERR_PTR(-ENOMEM); | 2276 | return ERR_PTR(-ENOMEM); |
| 2268 | 2277 | ||
| 2269 | ret = i915_ppgtt_init(ppgtt, dev_priv, fpriv); | 2278 | ret = i915_ppgtt_init(ppgtt, dev_priv, fpriv, name); |
| 2270 | if (ret) { | 2279 | if (ret) { |
| 2271 | kfree(ppgtt); | 2280 | kfree(ppgtt); |
| 2272 | return ERR_PTR(ret); | 2281 | return ERR_PTR(ret); |
| @@ -2289,6 +2298,7 @@ void i915_ppgtt_release(struct kref *kref) | |||
| 2289 | WARN_ON(!list_empty(&ppgtt->base.inactive_list)); | 2298 | WARN_ON(!list_empty(&ppgtt->base.inactive_list)); |
| 2290 | WARN_ON(!list_empty(&ppgtt->base.unbound_list)); | 2299 | WARN_ON(!list_empty(&ppgtt->base.unbound_list)); |
| 2291 | 2300 | ||
| 2301 | i915_gem_timeline_fini(&ppgtt->base.timeline); | ||
| 2292 | list_del(&ppgtt->base.global_link); | 2302 | list_del(&ppgtt->base.global_link); |
| 2293 | drm_mm_takedown(&ppgtt->base.mm); | 2303 | drm_mm_takedown(&ppgtt->base.mm); |
| 2294 | 2304 | ||
| @@ -2370,14 +2380,15 @@ void i915_gem_suspend_gtt_mappings(struct drm_device *dev) | |||
| 2370 | i915_ggtt_flush(dev_priv); | 2380 | i915_ggtt_flush(dev_priv); |
| 2371 | } | 2381 | } |
| 2372 | 2382 | ||
| 2373 | int i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj) | 2383 | int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj, |
| 2384 | struct sg_table *pages) | ||
| 2374 | { | 2385 | { |
| 2375 | if (!dma_map_sg(&obj->base.dev->pdev->dev, | 2386 | if (dma_map_sg(&obj->base.dev->pdev->dev, |
| 2376 | obj->pages->sgl, obj->pages->nents, | 2387 | pages->sgl, pages->nents, |
| 2377 | PCI_DMA_BIDIRECTIONAL)) | 2388 | PCI_DMA_BIDIRECTIONAL)) |
| 2378 | return -ENOSPC; | 2389 | return 0; |
| 2379 | 2390 | ||
| 2380 | return 0; | 2391 | return -ENOSPC; |
| 2381 | } | 2392 | } |
| 2382 | 2393 | ||
| 2383 | static void gen8_set_pte(void __iomem *addr, gen8_pte_t pte) | 2394 | static void gen8_set_pte(void __iomem *addr, gen8_pte_t pte) |
| @@ -2395,16 +2406,11 @@ static void gen8_ggtt_insert_page(struct i915_address_space *vm, | |||
| 2395 | gen8_pte_t __iomem *pte = | 2406 | gen8_pte_t __iomem *pte = |
| 2396 | (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + | 2407 | (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + |
| 2397 | (offset >> PAGE_SHIFT); | 2408 | (offset >> PAGE_SHIFT); |
| 2398 | int rpm_atomic_seq; | ||
| 2399 | |||
| 2400 | rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv); | ||
| 2401 | 2409 | ||
| 2402 | gen8_set_pte(pte, gen8_pte_encode(addr, level)); | 2410 | gen8_set_pte(pte, gen8_pte_encode(addr, level)); |
| 2403 | 2411 | ||
| 2404 | I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); | 2412 | I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); |
| 2405 | POSTING_READ(GFX_FLSH_CNTL_GEN6); | 2413 | POSTING_READ(GFX_FLSH_CNTL_GEN6); |
| 2406 | |||
| 2407 | assert_rpm_atomic_end(dev_priv, rpm_atomic_seq); | ||
| 2408 | } | 2414 | } |
| 2409 | 2415 | ||
| 2410 | static void gen8_ggtt_insert_entries(struct i915_address_space *vm, | 2416 | static void gen8_ggtt_insert_entries(struct i915_address_space *vm, |
| @@ -2418,11 +2424,8 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm, | |||
| 2418 | gen8_pte_t __iomem *gtt_entries; | 2424 | gen8_pte_t __iomem *gtt_entries; |
| 2419 | gen8_pte_t gtt_entry; | 2425 | gen8_pte_t gtt_entry; |
| 2420 | dma_addr_t addr; | 2426 | dma_addr_t addr; |
| 2421 | int rpm_atomic_seq; | ||
| 2422 | int i = 0; | 2427 | int i = 0; |
| 2423 | 2428 | ||
| 2424 | rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv); | ||
| 2425 | |||
| 2426 | gtt_entries = (gen8_pte_t __iomem *)ggtt->gsm + (start >> PAGE_SHIFT); | 2429 | gtt_entries = (gen8_pte_t __iomem *)ggtt->gsm + (start >> PAGE_SHIFT); |
| 2427 | 2430 | ||
| 2428 | for_each_sgt_dma(addr, sgt_iter, st) { | 2431 | for_each_sgt_dma(addr, sgt_iter, st) { |
| @@ -2446,8 +2449,6 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm, | |||
| 2446 | */ | 2449 | */ |
| 2447 | I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); | 2450 | I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); |
| 2448 | POSTING_READ(GFX_FLSH_CNTL_GEN6); | 2451 | POSTING_READ(GFX_FLSH_CNTL_GEN6); |
| 2449 | |||
| 2450 | assert_rpm_atomic_end(dev_priv, rpm_atomic_seq); | ||
| 2451 | } | 2452 | } |
| 2452 | 2453 | ||
| 2453 | struct insert_entries { | 2454 | struct insert_entries { |
| @@ -2486,16 +2487,11 @@ static void gen6_ggtt_insert_page(struct i915_address_space *vm, | |||
| 2486 | gen6_pte_t __iomem *pte = | 2487 | gen6_pte_t __iomem *pte = |
| 2487 | (gen6_pte_t __iomem *)dev_priv->ggtt.gsm + | 2488 | (gen6_pte_t __iomem *)dev_priv->ggtt.gsm + |
| 2488 | (offset >> PAGE_SHIFT); | 2489 | (offset >> PAGE_SHIFT); |
| 2489 | int rpm_atomic_seq; | ||
| 2490 | |||
| 2491 | rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv); | ||
| 2492 | 2490 | ||
| 2493 | iowrite32(vm->pte_encode(addr, level, flags), pte); | 2491 | iowrite32(vm->pte_encode(addr, level, flags), pte); |
| 2494 | 2492 | ||
| 2495 | I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); | 2493 | I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); |
| 2496 | POSTING_READ(GFX_FLSH_CNTL_GEN6); | 2494 | POSTING_READ(GFX_FLSH_CNTL_GEN6); |
| 2497 | |||
| 2498 | assert_rpm_atomic_end(dev_priv, rpm_atomic_seq); | ||
| 2499 | } | 2495 | } |
| 2500 | 2496 | ||
| 2501 | /* | 2497 | /* |
| @@ -2515,11 +2511,8 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm, | |||
| 2515 | gen6_pte_t __iomem *gtt_entries; | 2511 | gen6_pte_t __iomem *gtt_entries; |
| 2516 | gen6_pte_t gtt_entry; | 2512 | gen6_pte_t gtt_entry; |
| 2517 | dma_addr_t addr; | 2513 | dma_addr_t addr; |
| 2518 | int rpm_atomic_seq; | ||
| 2519 | int i = 0; | 2514 | int i = 0; |
| 2520 | 2515 | ||
| 2521 | rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv); | ||
| 2522 | |||
| 2523 | gtt_entries = (gen6_pte_t __iomem *)ggtt->gsm + (start >> PAGE_SHIFT); | 2516 | gtt_entries = (gen6_pte_t __iomem *)ggtt->gsm + (start >> PAGE_SHIFT); |
| 2524 | 2517 | ||
| 2525 | for_each_sgt_dma(addr, sgt_iter, st) { | 2518 | for_each_sgt_dma(addr, sgt_iter, st) { |
| @@ -2542,8 +2535,6 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm, | |||
| 2542 | */ | 2535 | */ |
| 2543 | I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); | 2536 | I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); |
| 2544 | POSTING_READ(GFX_FLSH_CNTL_GEN6); | 2537 | POSTING_READ(GFX_FLSH_CNTL_GEN6); |
| 2545 | |||
| 2546 | assert_rpm_atomic_end(dev_priv, rpm_atomic_seq); | ||
| 2547 | } | 2538 | } |
| 2548 | 2539 | ||
| 2549 | static void nop_clear_range(struct i915_address_space *vm, | 2540 | static void nop_clear_range(struct i915_address_space *vm, |
| @@ -2554,7 +2545,6 @@ static void nop_clear_range(struct i915_address_space *vm, | |||
| 2554 | static void gen8_ggtt_clear_range(struct i915_address_space *vm, | 2545 | static void gen8_ggtt_clear_range(struct i915_address_space *vm, |
| 2555 | uint64_t start, uint64_t length) | 2546 | uint64_t start, uint64_t length) |
| 2556 | { | 2547 | { |
| 2557 | struct drm_i915_private *dev_priv = to_i915(vm->dev); | ||
| 2558 | struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm); | 2548 | struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm); |
| 2559 | unsigned first_entry = start >> PAGE_SHIFT; | 2549 | unsigned first_entry = start >> PAGE_SHIFT; |
| 2560 | unsigned num_entries = length >> PAGE_SHIFT; | 2550 | unsigned num_entries = length >> PAGE_SHIFT; |
| @@ -2562,9 +2552,6 @@ static void gen8_ggtt_clear_range(struct i915_address_space *vm, | |||
| 2562 | (gen8_pte_t __iomem *)ggtt->gsm + first_entry; | 2552 | (gen8_pte_t __iomem *)ggtt->gsm + first_entry; |
| 2563 | const int max_entries = ggtt_total_entries(ggtt) - first_entry; | 2553 | const int max_entries = ggtt_total_entries(ggtt) - first_entry; |
| 2564 | int i; | 2554 | int i; |
| 2565 | int rpm_atomic_seq; | ||
| 2566 | |||
| 2567 | rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv); | ||
| 2568 | 2555 | ||
| 2569 | if (WARN(num_entries > max_entries, | 2556 | if (WARN(num_entries > max_entries, |
| 2570 | "First entry = %d; Num entries = %d (max=%d)\n", | 2557 | "First entry = %d; Num entries = %d (max=%d)\n", |
| @@ -2576,15 +2563,12 @@ static void gen8_ggtt_clear_range(struct i915_address_space *vm, | |||
| 2576 | for (i = 0; i < num_entries; i++) | 2563 | for (i = 0; i < num_entries; i++) |
| 2577 | gen8_set_pte(>t_base[i], scratch_pte); | 2564 | gen8_set_pte(>t_base[i], scratch_pte); |
| 2578 | readl(gtt_base); | 2565 | readl(gtt_base); |
| 2579 | |||
| 2580 | assert_rpm_atomic_end(dev_priv, rpm_atomic_seq); | ||
| 2581 | } | 2566 | } |
| 2582 | 2567 | ||
| 2583 | static void gen6_ggtt_clear_range(struct i915_address_space *vm, | 2568 | static void gen6_ggtt_clear_range(struct i915_address_space *vm, |
| 2584 | uint64_t start, | 2569 | uint64_t start, |
| 2585 | uint64_t length) | 2570 | uint64_t length) |
| 2586 | { | 2571 | { |
| 2587 | struct drm_i915_private *dev_priv = to_i915(vm->dev); | ||
| 2588 | struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm); | 2572 | struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm); |
| 2589 | unsigned first_entry = start >> PAGE_SHIFT; | 2573 | unsigned first_entry = start >> PAGE_SHIFT; |
| 2590 | unsigned num_entries = length >> PAGE_SHIFT; | 2574 | unsigned num_entries = length >> PAGE_SHIFT; |
| @@ -2592,9 +2576,6 @@ static void gen6_ggtt_clear_range(struct i915_address_space *vm, | |||
| 2592 | (gen6_pte_t __iomem *)ggtt->gsm + first_entry; | 2576 | (gen6_pte_t __iomem *)ggtt->gsm + first_entry; |
| 2593 | const int max_entries = ggtt_total_entries(ggtt) - first_entry; | 2577 | const int max_entries = ggtt_total_entries(ggtt) - first_entry; |
| 2594 | int i; | 2578 | int i; |
| 2595 | int rpm_atomic_seq; | ||
| 2596 | |||
| 2597 | rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv); | ||
| 2598 | 2579 | ||
| 2599 | if (WARN(num_entries > max_entries, | 2580 | if (WARN(num_entries > max_entries, |
| 2600 | "First entry = %d; Num entries = %d (max=%d)\n", | 2581 | "First entry = %d; Num entries = %d (max=%d)\n", |
| @@ -2607,8 +2588,6 @@ static void gen6_ggtt_clear_range(struct i915_address_space *vm, | |||
| 2607 | for (i = 0; i < num_entries; i++) | 2588 | for (i = 0; i < num_entries; i++) |
| 2608 | iowrite32(scratch_pte, >t_base[i]); | 2589 | iowrite32(scratch_pte, >t_base[i]); |
| 2609 | readl(gtt_base); | 2590 | readl(gtt_base); |
| 2610 | |||
| 2611 | assert_rpm_atomic_end(dev_priv, rpm_atomic_seq); | ||
| 2612 | } | 2591 | } |
| 2613 | 2592 | ||
| 2614 | static void i915_ggtt_insert_page(struct i915_address_space *vm, | 2593 | static void i915_ggtt_insert_page(struct i915_address_space *vm, |
| @@ -2617,16 +2596,10 @@ static void i915_ggtt_insert_page(struct i915_address_space *vm, | |||
| 2617 | enum i915_cache_level cache_level, | 2596 | enum i915_cache_level cache_level, |
| 2618 | u32 unused) | 2597 | u32 unused) |
| 2619 | { | 2598 | { |
| 2620 | struct drm_i915_private *dev_priv = to_i915(vm->dev); | ||
| 2621 | unsigned int flags = (cache_level == I915_CACHE_NONE) ? | 2599 | unsigned int flags = (cache_level == I915_CACHE_NONE) ? |
| 2622 | AGP_USER_MEMORY : AGP_USER_CACHED_MEMORY; | 2600 | AGP_USER_MEMORY : AGP_USER_CACHED_MEMORY; |
| 2623 | int rpm_atomic_seq; | ||
| 2624 | |||
| 2625 | rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv); | ||
| 2626 | 2601 | ||
| 2627 | intel_gtt_insert_page(addr, offset >> PAGE_SHIFT, flags); | 2602 | intel_gtt_insert_page(addr, offset >> PAGE_SHIFT, flags); |
| 2628 | |||
| 2629 | assert_rpm_atomic_end(dev_priv, rpm_atomic_seq); | ||
| 2630 | } | 2603 | } |
| 2631 | 2604 | ||
| 2632 | static void i915_ggtt_insert_entries(struct i915_address_space *vm, | 2605 | static void i915_ggtt_insert_entries(struct i915_address_space *vm, |
| @@ -2634,39 +2607,25 @@ static void i915_ggtt_insert_entries(struct i915_address_space *vm, | |||
| 2634 | uint64_t start, | 2607 | uint64_t start, |
| 2635 | enum i915_cache_level cache_level, u32 unused) | 2608 | enum i915_cache_level cache_level, u32 unused) |
| 2636 | { | 2609 | { |
| 2637 | struct drm_i915_private *dev_priv = to_i915(vm->dev); | ||
| 2638 | unsigned int flags = (cache_level == I915_CACHE_NONE) ? | 2610 | unsigned int flags = (cache_level == I915_CACHE_NONE) ? |
| 2639 | AGP_USER_MEMORY : AGP_USER_CACHED_MEMORY; | 2611 | AGP_USER_MEMORY : AGP_USER_CACHED_MEMORY; |
| 2640 | int rpm_atomic_seq; | ||
| 2641 | |||
| 2642 | rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv); | ||
| 2643 | 2612 | ||
| 2644 | intel_gtt_insert_sg_entries(pages, start >> PAGE_SHIFT, flags); | 2613 | intel_gtt_insert_sg_entries(pages, start >> PAGE_SHIFT, flags); |
| 2645 | 2614 | ||
| 2646 | assert_rpm_atomic_end(dev_priv, rpm_atomic_seq); | ||
| 2647 | |||
| 2648 | } | 2615 | } |
| 2649 | 2616 | ||
| 2650 | static void i915_ggtt_clear_range(struct i915_address_space *vm, | 2617 | static void i915_ggtt_clear_range(struct i915_address_space *vm, |
| 2651 | uint64_t start, | 2618 | uint64_t start, |
| 2652 | uint64_t length) | 2619 | uint64_t length) |
| 2653 | { | 2620 | { |
| 2654 | struct drm_i915_private *dev_priv = to_i915(vm->dev); | 2621 | intel_gtt_clear_range(start >> PAGE_SHIFT, length >> PAGE_SHIFT); |
| 2655 | unsigned first_entry = start >> PAGE_SHIFT; | ||
| 2656 | unsigned num_entries = length >> PAGE_SHIFT; | ||
| 2657 | int rpm_atomic_seq; | ||
| 2658 | |||
| 2659 | rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv); | ||
| 2660 | |||
| 2661 | intel_gtt_clear_range(first_entry, num_entries); | ||
| 2662 | |||
| 2663 | assert_rpm_atomic_end(dev_priv, rpm_atomic_seq); | ||
| 2664 | } | 2622 | } |
| 2665 | 2623 | ||
| 2666 | static int ggtt_bind_vma(struct i915_vma *vma, | 2624 | static int ggtt_bind_vma(struct i915_vma *vma, |
| 2667 | enum i915_cache_level cache_level, | 2625 | enum i915_cache_level cache_level, |
| 2668 | u32 flags) | 2626 | u32 flags) |
| 2669 | { | 2627 | { |
| 2628 | struct drm_i915_private *i915 = to_i915(vma->vm->dev); | ||
| 2670 | struct drm_i915_gem_object *obj = vma->obj; | 2629 | struct drm_i915_gem_object *obj = vma->obj; |
| 2671 | u32 pte_flags = 0; | 2630 | u32 pte_flags = 0; |
| 2672 | int ret; | 2631 | int ret; |
| @@ -2679,8 +2638,10 @@ static int ggtt_bind_vma(struct i915_vma *vma, | |||
| 2679 | if (obj->gt_ro) | 2638 | if (obj->gt_ro) |
| 2680 | pte_flags |= PTE_READ_ONLY; | 2639 | pte_flags |= PTE_READ_ONLY; |
| 2681 | 2640 | ||
| 2641 | intel_runtime_pm_get(i915); | ||
| 2682 | vma->vm->insert_entries(vma->vm, vma->pages, vma->node.start, | 2642 | vma->vm->insert_entries(vma->vm, vma->pages, vma->node.start, |
| 2683 | cache_level, pte_flags); | 2643 | cache_level, pte_flags); |
| 2644 | intel_runtime_pm_put(i915); | ||
| 2684 | 2645 | ||
| 2685 | /* | 2646 | /* |
| 2686 | * Without aliasing PPGTT there's no difference between | 2647 | * Without aliasing PPGTT there's no difference between |
| @@ -2696,6 +2657,7 @@ static int aliasing_gtt_bind_vma(struct i915_vma *vma, | |||
| 2696 | enum i915_cache_level cache_level, | 2657 | enum i915_cache_level cache_level, |
| 2697 | u32 flags) | 2658 | u32 flags) |
| 2698 | { | 2659 | { |
| 2660 | struct drm_i915_private *i915 = to_i915(vma->vm->dev); | ||
| 2699 | u32 pte_flags; | 2661 | u32 pte_flags; |
| 2700 | int ret; | 2662 | int ret; |
| 2701 | 2663 | ||
| @@ -2710,14 +2672,15 @@ static int aliasing_gtt_bind_vma(struct i915_vma *vma, | |||
| 2710 | 2672 | ||
| 2711 | 2673 | ||
| 2712 | if (flags & I915_VMA_GLOBAL_BIND) { | 2674 | if (flags & I915_VMA_GLOBAL_BIND) { |
| 2675 | intel_runtime_pm_get(i915); | ||
| 2713 | vma->vm->insert_entries(vma->vm, | 2676 | vma->vm->insert_entries(vma->vm, |
| 2714 | vma->pages, vma->node.start, | 2677 | vma->pages, vma->node.start, |
| 2715 | cache_level, pte_flags); | 2678 | cache_level, pte_flags); |
| 2679 | intel_runtime_pm_put(i915); | ||
| 2716 | } | 2680 | } |
| 2717 | 2681 | ||
| 2718 | if (flags & I915_VMA_LOCAL_BIND) { | 2682 | if (flags & I915_VMA_LOCAL_BIND) { |
| 2719 | struct i915_hw_ppgtt *appgtt = | 2683 | struct i915_hw_ppgtt *appgtt = i915->mm.aliasing_ppgtt; |
| 2720 | to_i915(vma->vm->dev)->mm.aliasing_ppgtt; | ||
| 2721 | appgtt->base.insert_entries(&appgtt->base, | 2684 | appgtt->base.insert_entries(&appgtt->base, |
| 2722 | vma->pages, vma->node.start, | 2685 | vma->pages, vma->node.start, |
| 2723 | cache_level, pte_flags); | 2686 | cache_level, pte_flags); |
| @@ -2728,19 +2691,24 @@ static int aliasing_gtt_bind_vma(struct i915_vma *vma, | |||
| 2728 | 2691 | ||
| 2729 | static void ggtt_unbind_vma(struct i915_vma *vma) | 2692 | static void ggtt_unbind_vma(struct i915_vma *vma) |
| 2730 | { | 2693 | { |
| 2731 | struct i915_hw_ppgtt *appgtt = to_i915(vma->vm->dev)->mm.aliasing_ppgtt; | 2694 | struct drm_i915_private *i915 = to_i915(vma->vm->dev); |
| 2695 | struct i915_hw_ppgtt *appgtt = i915->mm.aliasing_ppgtt; | ||
| 2732 | const u64 size = min(vma->size, vma->node.size); | 2696 | const u64 size = min(vma->size, vma->node.size); |
| 2733 | 2697 | ||
| 2734 | if (vma->flags & I915_VMA_GLOBAL_BIND) | 2698 | if (vma->flags & I915_VMA_GLOBAL_BIND) { |
| 2699 | intel_runtime_pm_get(i915); | ||
| 2735 | vma->vm->clear_range(vma->vm, | 2700 | vma->vm->clear_range(vma->vm, |
| 2736 | vma->node.start, size); | 2701 | vma->node.start, size); |
| 2702 | intel_runtime_pm_put(i915); | ||
| 2703 | } | ||
| 2737 | 2704 | ||
| 2738 | if (vma->flags & I915_VMA_LOCAL_BIND && appgtt) | 2705 | if (vma->flags & I915_VMA_LOCAL_BIND && appgtt) |
| 2739 | appgtt->base.clear_range(&appgtt->base, | 2706 | appgtt->base.clear_range(&appgtt->base, |
| 2740 | vma->node.start, size); | 2707 | vma->node.start, size); |
| 2741 | } | 2708 | } |
| 2742 | 2709 | ||
| 2743 | void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj) | 2710 | void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj, |
| 2711 | struct sg_table *pages) | ||
| 2744 | { | 2712 | { |
| 2745 | struct drm_i915_private *dev_priv = to_i915(obj->base.dev); | 2713 | struct drm_i915_private *dev_priv = to_i915(obj->base.dev); |
| 2746 | struct device *kdev = &dev_priv->drm.pdev->dev; | 2714 | struct device *kdev = &dev_priv->drm.pdev->dev; |
| @@ -2754,8 +2722,7 @@ void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj) | |||
| 2754 | } | 2722 | } |
| 2755 | } | 2723 | } |
| 2756 | 2724 | ||
| 2757 | dma_unmap_sg(kdev, obj->pages->sgl, obj->pages->nents, | 2725 | dma_unmap_sg(kdev, pages->sgl, pages->nents, PCI_DMA_BIDIRECTIONAL); |
| 2758 | PCI_DMA_BIDIRECTIONAL); | ||
| 2759 | } | 2726 | } |
| 2760 | 2727 | ||
| 2761 | static void i915_gtt_color_adjust(struct drm_mm_node *node, | 2728 | static void i915_gtt_color_adjust(struct drm_mm_node *node, |
| @@ -3274,11 +3241,13 @@ int i915_ggtt_init_hw(struct drm_i915_private *dev_priv) | |||
| 3274 | /* Subtract the guard page before address space initialization to | 3241 | /* Subtract the guard page before address space initialization to |
| 3275 | * shrink the range used by drm_mm. | 3242 | * shrink the range used by drm_mm. |
| 3276 | */ | 3243 | */ |
| 3244 | mutex_lock(&dev_priv->drm.struct_mutex); | ||
| 3277 | ggtt->base.total -= PAGE_SIZE; | 3245 | ggtt->base.total -= PAGE_SIZE; |
| 3278 | i915_address_space_init(&ggtt->base, dev_priv); | 3246 | i915_address_space_init(&ggtt->base, dev_priv, "[global]"); |
| 3279 | ggtt->base.total += PAGE_SIZE; | 3247 | ggtt->base.total += PAGE_SIZE; |
| 3280 | if (!HAS_LLC(dev_priv)) | 3248 | if (!HAS_LLC(dev_priv)) |
| 3281 | ggtt->base.mm.color_adjust = i915_gtt_color_adjust; | 3249 | ggtt->base.mm.color_adjust = i915_gtt_color_adjust; |
| 3250 | mutex_unlock(&dev_priv->drm.struct_mutex); | ||
| 3282 | 3251 | ||
| 3283 | if (!io_mapping_init_wc(&dev_priv->ggtt.mappable, | 3252 | if (!io_mapping_init_wc(&dev_priv->ggtt.mappable, |
| 3284 | dev_priv->ggtt.mappable_base, | 3253 | dev_priv->ggtt.mappable_base, |
| @@ -3327,7 +3296,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) | |||
| 3327 | 3296 | ||
| 3328 | /* clflush objects bound into the GGTT and rebind them. */ | 3297 | /* clflush objects bound into the GGTT and rebind them. */ |
| 3329 | list_for_each_entry_safe(obj, on, | 3298 | list_for_each_entry_safe(obj, on, |
| 3330 | &dev_priv->mm.bound_list, global_list) { | 3299 | &dev_priv->mm.bound_list, global_link) { |
| 3331 | bool ggtt_bound = false; | 3300 | bool ggtt_bound = false; |
| 3332 | struct i915_vma *vma; | 3301 | struct i915_vma *vma; |
| 3333 | 3302 | ||
| @@ -3386,6 +3355,7 @@ i915_vma_retire(struct i915_gem_active *active, | |||
| 3386 | const unsigned int idx = rq->engine->id; | 3355 | const unsigned int idx = rq->engine->id; |
| 3387 | struct i915_vma *vma = | 3356 | struct i915_vma *vma = |
| 3388 | container_of(active, struct i915_vma, last_read[idx]); | 3357 | container_of(active, struct i915_vma, last_read[idx]); |
| 3358 | struct drm_i915_gem_object *obj = vma->obj; | ||
| 3389 | 3359 | ||
| 3390 | GEM_BUG_ON(!i915_vma_has_active_engine(vma, idx)); | 3360 | GEM_BUG_ON(!i915_vma_has_active_engine(vma, idx)); |
| 3391 | 3361 | ||
| @@ -3396,6 +3366,34 @@ i915_vma_retire(struct i915_gem_active *active, | |||
| 3396 | list_move_tail(&vma->vm_link, &vma->vm->inactive_list); | 3366 | list_move_tail(&vma->vm_link, &vma->vm->inactive_list); |
| 3397 | if (unlikely(i915_vma_is_closed(vma) && !i915_vma_is_pinned(vma))) | 3367 | if (unlikely(i915_vma_is_closed(vma) && !i915_vma_is_pinned(vma))) |
| 3398 | WARN_ON(i915_vma_unbind(vma)); | 3368 | WARN_ON(i915_vma_unbind(vma)); |
| 3369 | |||
| 3370 | GEM_BUG_ON(!i915_gem_object_is_active(obj)); | ||
| 3371 | if (--obj->active_count) | ||
| 3372 | return; | ||
| 3373 | |||
| 3374 | /* Bump our place on the bound list to keep it roughly in LRU order | ||
| 3375 | * so that we don't steal from recently used but inactive objects | ||
| 3376 | * (unless we are forced to ofc!) | ||
| 3377 | */ | ||
| 3378 | if (obj->bind_count) | ||
| 3379 | list_move_tail(&obj->global_link, &rq->i915->mm.bound_list); | ||
| 3380 | |||
| 3381 | obj->mm.dirty = true; /* be paranoid */ | ||
| 3382 | |||
| 3383 | if (i915_gem_object_has_active_reference(obj)) { | ||
| 3384 | i915_gem_object_clear_active_reference(obj); | ||
| 3385 | i915_gem_object_put(obj); | ||
| 3386 | } | ||
| 3387 | } | ||
| 3388 | |||
| 3389 | static void | ||
| 3390 | i915_ggtt_retire__write(struct i915_gem_active *active, | ||
| 3391 | struct drm_i915_gem_request *request) | ||
| 3392 | { | ||
| 3393 | struct i915_vma *vma = | ||
| 3394 | container_of(active, struct i915_vma, last_write); | ||
| 3395 | |||
| 3396 | intel_fb_obj_flush(vma->obj, true, ORIGIN_CS); | ||
| 3399 | } | 3397 | } |
| 3400 | 3398 | ||
| 3401 | void i915_vma_destroy(struct i915_vma *vma) | 3399 | void i915_vma_destroy(struct i915_vma *vma) |
| @@ -3417,17 +3415,40 @@ void i915_vma_close(struct i915_vma *vma) | |||
| 3417 | GEM_BUG_ON(i915_vma_is_closed(vma)); | 3415 | GEM_BUG_ON(i915_vma_is_closed(vma)); |
| 3418 | vma->flags |= I915_VMA_CLOSED; | 3416 | vma->flags |= I915_VMA_CLOSED; |
| 3419 | 3417 | ||
| 3420 | list_del_init(&vma->obj_link); | 3418 | list_del(&vma->obj_link); |
| 3419 | rb_erase(&vma->obj_node, &vma->obj->vma_tree); | ||
| 3420 | |||
| 3421 | if (!i915_vma_is_active(vma) && !i915_vma_is_pinned(vma)) | 3421 | if (!i915_vma_is_active(vma) && !i915_vma_is_pinned(vma)) |
| 3422 | WARN_ON(i915_vma_unbind(vma)); | 3422 | WARN_ON(i915_vma_unbind(vma)); |
| 3423 | } | 3423 | } |
| 3424 | 3424 | ||
| 3425 | static inline long vma_compare(struct i915_vma *vma, | ||
| 3426 | struct i915_address_space *vm, | ||
| 3427 | const struct i915_ggtt_view *view) | ||
| 3428 | { | ||
| 3429 | GEM_BUG_ON(view && !i915_is_ggtt(vm)); | ||
| 3430 | |||
| 3431 | if (vma->vm != vm) | ||
| 3432 | return vma->vm - vm; | ||
| 3433 | |||
| 3434 | if (!view) | ||
| 3435 | return vma->ggtt_view.type; | ||
| 3436 | |||
| 3437 | if (vma->ggtt_view.type != view->type) | ||
| 3438 | return vma->ggtt_view.type - view->type; | ||
| 3439 | |||
| 3440 | return memcmp(&vma->ggtt_view.params, | ||
| 3441 | &view->params, | ||
| 3442 | sizeof(view->params)); | ||
| 3443 | } | ||
| 3444 | |||
| 3425 | static struct i915_vma * | 3445 | static struct i915_vma * |
| 3426 | __i915_vma_create(struct drm_i915_gem_object *obj, | 3446 | __i915_vma_create(struct drm_i915_gem_object *obj, |
| 3427 | struct i915_address_space *vm, | 3447 | struct i915_address_space *vm, |
| 3428 | const struct i915_ggtt_view *view) | 3448 | const struct i915_ggtt_view *view) |
| 3429 | { | 3449 | { |
| 3430 | struct i915_vma *vma; | 3450 | struct i915_vma *vma; |
| 3451 | struct rb_node *rb, **p; | ||
| 3431 | int i; | 3452 | int i; |
| 3432 | 3453 | ||
| 3433 | GEM_BUG_ON(vm->closed); | 3454 | GEM_BUG_ON(vm->closed); |
| @@ -3439,6 +3460,8 @@ __i915_vma_create(struct drm_i915_gem_object *obj, | |||
| 3439 | INIT_LIST_HEAD(&vma->exec_list); | 3460 | INIT_LIST_HEAD(&vma->exec_list); |
| 3440 | for (i = 0; i < ARRAY_SIZE(vma->last_read); i++) | 3461 | for (i = 0; i < ARRAY_SIZE(vma->last_read); i++) |
| 3441 | init_request_active(&vma->last_read[i], i915_vma_retire); | 3462 | init_request_active(&vma->last_read[i], i915_vma_retire); |
| 3463 | init_request_active(&vma->last_write, | ||
| 3464 | i915_is_ggtt(vm) ? i915_ggtt_retire__write : NULL); | ||
| 3442 | init_request_active(&vma->last_fence, NULL); | 3465 | init_request_active(&vma->last_fence, NULL); |
| 3443 | list_add(&vma->vm_link, &vm->unbound_list); | 3466 | list_add(&vma->vm_link, &vm->unbound_list); |
| 3444 | vma->vm = vm; | 3467 | vma->vm = vm; |
| @@ -3459,33 +3482,28 @@ __i915_vma_create(struct drm_i915_gem_object *obj, | |||
| 3459 | 3482 | ||
| 3460 | if (i915_is_ggtt(vm)) { | 3483 | if (i915_is_ggtt(vm)) { |
| 3461 | vma->flags |= I915_VMA_GGTT; | 3484 | vma->flags |= I915_VMA_GGTT; |
| 3485 | list_add(&vma->obj_link, &obj->vma_list); | ||
| 3462 | } else { | 3486 | } else { |
| 3463 | i915_ppgtt_get(i915_vm_to_ppgtt(vm)); | 3487 | i915_ppgtt_get(i915_vm_to_ppgtt(vm)); |
| 3488 | list_add_tail(&vma->obj_link, &obj->vma_list); | ||
| 3464 | } | 3489 | } |
| 3465 | 3490 | ||
| 3466 | list_add_tail(&vma->obj_link, &obj->vma_list); | 3491 | rb = NULL; |
| 3467 | return vma; | 3492 | p = &obj->vma_tree.rb_node; |
| 3468 | } | 3493 | while (*p) { |
| 3469 | 3494 | struct i915_vma *pos; | |
| 3470 | static inline bool vma_matches(struct i915_vma *vma, | ||
| 3471 | struct i915_address_space *vm, | ||
| 3472 | const struct i915_ggtt_view *view) | ||
| 3473 | { | ||
| 3474 | if (vma->vm != vm) | ||
| 3475 | return false; | ||
| 3476 | 3495 | ||
| 3477 | if (!i915_vma_is_ggtt(vma)) | 3496 | rb = *p; |
| 3478 | return true; | 3497 | pos = rb_entry(rb, struct i915_vma, obj_node); |
| 3479 | 3498 | if (vma_compare(pos, vm, view) < 0) | |
| 3480 | if (!view) | 3499 | p = &rb->rb_right; |
| 3481 | return vma->ggtt_view.type == 0; | 3500 | else |
| 3482 | 3501 | p = &rb->rb_left; | |
| 3483 | if (vma->ggtt_view.type != view->type) | 3502 | } |
| 3484 | return false; | 3503 | rb_link_node(&vma->obj_node, rb, p); |
| 3504 | rb_insert_color(&vma->obj_node, &obj->vma_tree); | ||
| 3485 | 3505 | ||
| 3486 | return memcmp(&vma->ggtt_view.params, | 3506 | return vma; |
| 3487 | &view->params, | ||
| 3488 | sizeof(view->params)) == 0; | ||
| 3489 | } | 3507 | } |
| 3490 | 3508 | ||
| 3491 | struct i915_vma * | 3509 | struct i915_vma * |
| @@ -3493,6 +3511,7 @@ i915_vma_create(struct drm_i915_gem_object *obj, | |||
| 3493 | struct i915_address_space *vm, | 3511 | struct i915_address_space *vm, |
| 3494 | const struct i915_ggtt_view *view) | 3512 | const struct i915_ggtt_view *view) |
| 3495 | { | 3513 | { |
| 3514 | lockdep_assert_held(&obj->base.dev->struct_mutex); | ||
| 3496 | GEM_BUG_ON(view && !i915_is_ggtt(vm)); | 3515 | GEM_BUG_ON(view && !i915_is_ggtt(vm)); |
| 3497 | GEM_BUG_ON(i915_gem_obj_to_vma(obj, vm, view)); | 3516 | GEM_BUG_ON(i915_gem_obj_to_vma(obj, vm, view)); |
| 3498 | 3517 | ||
| @@ -3504,12 +3523,23 @@ i915_gem_obj_to_vma(struct drm_i915_gem_object *obj, | |||
| 3504 | struct i915_address_space *vm, | 3523 | struct i915_address_space *vm, |
| 3505 | const struct i915_ggtt_view *view) | 3524 | const struct i915_ggtt_view *view) |
| 3506 | { | 3525 | { |
| 3507 | struct i915_vma *vma; | 3526 | struct rb_node *rb; |
| 3527 | |||
| 3528 | rb = obj->vma_tree.rb_node; | ||
| 3529 | while (rb) { | ||
| 3530 | struct i915_vma *vma = rb_entry(rb, struct i915_vma, obj_node); | ||
| 3531 | long cmp; | ||
| 3508 | 3532 | ||
| 3509 | list_for_each_entry_reverse(vma, &obj->vma_list, obj_link) | 3533 | cmp = vma_compare(vma, vm, view); |
| 3510 | if (vma_matches(vma, vm, view)) | 3534 | if (cmp == 0) |
| 3511 | return vma; | 3535 | return vma; |
| 3512 | 3536 | ||
| 3537 | if (cmp < 0) | ||
| 3538 | rb = rb->rb_right; | ||
| 3539 | else | ||
| 3540 | rb = rb->rb_left; | ||
| 3541 | } | ||
| 3542 | |||
| 3513 | return NULL; | 3543 | return NULL; |
| 3514 | } | 3544 | } |
| 3515 | 3545 | ||
| @@ -3520,11 +3550,14 @@ i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj, | |||
| 3520 | { | 3550 | { |
| 3521 | struct i915_vma *vma; | 3551 | struct i915_vma *vma; |
| 3522 | 3552 | ||
| 3553 | lockdep_assert_held(&obj->base.dev->struct_mutex); | ||
| 3523 | GEM_BUG_ON(view && !i915_is_ggtt(vm)); | 3554 | GEM_BUG_ON(view && !i915_is_ggtt(vm)); |
| 3524 | 3555 | ||
| 3525 | vma = i915_gem_obj_to_vma(obj, vm, view); | 3556 | vma = i915_gem_obj_to_vma(obj, vm, view); |
| 3526 | if (!vma) | 3557 | if (!vma) { |
| 3527 | vma = __i915_vma_create(obj, vm, view); | 3558 | vma = __i915_vma_create(obj, vm, view); |
| 3559 | GEM_BUG_ON(vma != i915_gem_obj_to_vma(obj, vm, view)); | ||
| 3560 | } | ||
| 3528 | 3561 | ||
| 3529 | GEM_BUG_ON(i915_vma_is_closed(vma)); | 3562 | GEM_BUG_ON(i915_vma_is_closed(vma)); |
| 3530 | return vma; | 3563 | return vma; |
| @@ -3590,7 +3623,7 @@ intel_rotate_fb_obj_pages(const struct intel_rotation_info *rot_info, | |||
| 3590 | 3623 | ||
| 3591 | /* Populate source page list from the object. */ | 3624 | /* Populate source page list from the object. */ |
| 3592 | i = 0; | 3625 | i = 0; |
| 3593 | for_each_sgt_dma(dma_addr, sgt_iter, obj->pages) | 3626 | for_each_sgt_dma(dma_addr, sgt_iter, obj->mm.pages) |
| 3594 | page_addr_list[i++] = dma_addr; | 3627 | page_addr_list[i++] = dma_addr; |
| 3595 | 3628 | ||
| 3596 | GEM_BUG_ON(i != n_pages); | 3629 | GEM_BUG_ON(i != n_pages); |
| @@ -3626,35 +3659,47 @@ intel_partial_pages(const struct i915_ggtt_view *view, | |||
| 3626 | struct drm_i915_gem_object *obj) | 3659 | struct drm_i915_gem_object *obj) |
| 3627 | { | 3660 | { |
| 3628 | struct sg_table *st; | 3661 | struct sg_table *st; |
| 3629 | struct scatterlist *sg; | 3662 | struct scatterlist *sg, *iter; |
| 3630 | struct sg_page_iter obj_sg_iter; | 3663 | unsigned int count = view->params.partial.size; |
| 3664 | unsigned int offset; | ||
| 3631 | int ret = -ENOMEM; | 3665 | int ret = -ENOMEM; |
| 3632 | 3666 | ||
| 3633 | st = kmalloc(sizeof(*st), GFP_KERNEL); | 3667 | st = kmalloc(sizeof(*st), GFP_KERNEL); |
| 3634 | if (!st) | 3668 | if (!st) |
| 3635 | goto err_st_alloc; | 3669 | goto err_st_alloc; |
| 3636 | 3670 | ||
| 3637 | ret = sg_alloc_table(st, view->params.partial.size, GFP_KERNEL); | 3671 | ret = sg_alloc_table(st, count, GFP_KERNEL); |
| 3638 | if (ret) | 3672 | if (ret) |
| 3639 | goto err_sg_alloc; | 3673 | goto err_sg_alloc; |
| 3640 | 3674 | ||
| 3675 | iter = i915_gem_object_get_sg(obj, | ||
| 3676 | view->params.partial.offset, | ||
| 3677 | &offset); | ||
| 3678 | GEM_BUG_ON(!iter); | ||
| 3679 | |||
| 3641 | sg = st->sgl; | 3680 | sg = st->sgl; |
| 3642 | st->nents = 0; | 3681 | st->nents = 0; |
| 3643 | for_each_sg_page(obj->pages->sgl, &obj_sg_iter, obj->pages->nents, | 3682 | do { |
| 3644 | view->params.partial.offset) | 3683 | unsigned int len; |
| 3645 | { | ||
| 3646 | if (st->nents >= view->params.partial.size) | ||
| 3647 | break; | ||
| 3648 | 3684 | ||
| 3649 | sg_set_page(sg, NULL, PAGE_SIZE, 0); | 3685 | len = min(iter->length - (offset << PAGE_SHIFT), |
| 3650 | sg_dma_address(sg) = sg_page_iter_dma_address(&obj_sg_iter); | 3686 | count << PAGE_SHIFT); |
| 3651 | sg_dma_len(sg) = PAGE_SIZE; | 3687 | sg_set_page(sg, NULL, len, 0); |
| 3688 | sg_dma_address(sg) = | ||
| 3689 | sg_dma_address(iter) + (offset << PAGE_SHIFT); | ||
| 3690 | sg_dma_len(sg) = len; | ||
| 3652 | 3691 | ||
| 3653 | sg = sg_next(sg); | ||
| 3654 | st->nents++; | 3692 | st->nents++; |
| 3655 | } | 3693 | count -= len >> PAGE_SHIFT; |
| 3694 | if (count == 0) { | ||
| 3695 | sg_mark_end(sg); | ||
| 3696 | return st; | ||
| 3697 | } | ||
| 3656 | 3698 | ||
| 3657 | return st; | 3699 | sg = __sg_next(sg); |
| 3700 | iter = __sg_next(iter); | ||
| 3701 | offset = 0; | ||
| 3702 | } while (1); | ||
| 3658 | 3703 | ||
| 3659 | err_sg_alloc: | 3704 | err_sg_alloc: |
| 3660 | kfree(st); | 3705 | kfree(st); |
| @@ -3667,11 +3712,18 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma) | |||
| 3667 | { | 3712 | { |
| 3668 | int ret = 0; | 3713 | int ret = 0; |
| 3669 | 3714 | ||
| 3715 | /* The vma->pages are only valid within the lifespan of the borrowed | ||
| 3716 | * obj->mm.pages. When the obj->mm.pages sg_table is regenerated, so | ||
| 3717 | * must be the vma->pages. A simple rule is that vma->pages must only | ||
| 3718 | * be accessed when the obj->mm.pages are pinned. | ||
| 3719 | */ | ||
| 3720 | GEM_BUG_ON(!i915_gem_object_has_pinned_pages(vma->obj)); | ||
| 3721 | |||
| 3670 | if (vma->pages) | 3722 | if (vma->pages) |
| 3671 | return 0; | 3723 | return 0; |
| 3672 | 3724 | ||
| 3673 | if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) | 3725 | if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) |
| 3674 | vma->pages = vma->obj->pages; | 3726 | vma->pages = vma->obj->mm.pages; |
| 3675 | else if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED) | 3727 | else if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED) |
| 3676 | vma->pages = | 3728 | vma->pages = |
| 3677 | intel_rotate_fb_obj_pages(&vma->ggtt_view.params.rotated, vma->obj); | 3729 | intel_rotate_fb_obj_pages(&vma->ggtt_view.params.rotated, vma->obj); |
| @@ -3778,11 +3830,16 @@ void __iomem *i915_vma_pin_iomap(struct i915_vma *vma) | |||
| 3778 | void i915_vma_unpin_and_release(struct i915_vma **p_vma) | 3830 | void i915_vma_unpin_and_release(struct i915_vma **p_vma) |
| 3779 | { | 3831 | { |
| 3780 | struct i915_vma *vma; | 3832 | struct i915_vma *vma; |
| 3833 | struct drm_i915_gem_object *obj; | ||
| 3781 | 3834 | ||
| 3782 | vma = fetch_and_zero(p_vma); | 3835 | vma = fetch_and_zero(p_vma); |
| 3783 | if (!vma) | 3836 | if (!vma) |
| 3784 | return; | 3837 | return; |
| 3785 | 3838 | ||
| 3839 | obj = vma->obj; | ||
| 3840 | |||
| 3786 | i915_vma_unpin(vma); | 3841 | i915_vma_unpin(vma); |
| 3787 | i915_vma_put(vma); | 3842 | i915_vma_close(vma); |
| 3843 | |||
| 3844 | __i915_gem_object_release_unless_active(obj); | ||
| 3788 | } | 3845 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index c241d8143255..c23ef9db1f53 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h | |||
| @@ -211,6 +211,7 @@ struct i915_vma { | |||
| 211 | 211 | ||
| 212 | unsigned int active; | 212 | unsigned int active; |
| 213 | struct i915_gem_active last_read[I915_NUM_ENGINES]; | 213 | struct i915_gem_active last_read[I915_NUM_ENGINES]; |
| 214 | struct i915_gem_active last_write; | ||
| 214 | struct i915_gem_active last_fence; | 215 | struct i915_gem_active last_fence; |
| 215 | 216 | ||
| 216 | /** | 217 | /** |
| @@ -226,6 +227,7 @@ struct i915_vma { | |||
| 226 | struct list_head vm_link; | 227 | struct list_head vm_link; |
| 227 | 228 | ||
| 228 | struct list_head obj_link; /* Link in the object's VMA list */ | 229 | struct list_head obj_link; /* Link in the object's VMA list */ |
| 230 | struct rb_node obj_node; | ||
| 229 | 231 | ||
| 230 | /** This vma's place in the batchbuffer or on the eviction list */ | 232 | /** This vma's place in the batchbuffer or on the eviction list */ |
| 231 | struct list_head exec_list; | 233 | struct list_head exec_list; |
| @@ -341,6 +343,7 @@ struct i915_pml4 { | |||
| 341 | 343 | ||
| 342 | struct i915_address_space { | 344 | struct i915_address_space { |
| 343 | struct drm_mm mm; | 345 | struct drm_mm mm; |
| 346 | struct i915_gem_timeline timeline; | ||
| 344 | struct drm_device *dev; | 347 | struct drm_device *dev; |
| 345 | /* Every address space belongs to a struct file - except for the global | 348 | /* Every address space belongs to a struct file - except for the global |
| 346 | * GTT that is owned by the driver (and so @file is set to NULL). In | 349 | * GTT that is owned by the driver (and so @file is set to NULL). In |
| @@ -612,7 +615,8 @@ void i915_ggtt_cleanup_hw(struct drm_i915_private *dev_priv); | |||
| 612 | int i915_ppgtt_init_hw(struct drm_device *dev); | 615 | int i915_ppgtt_init_hw(struct drm_device *dev); |
| 613 | void i915_ppgtt_release(struct kref *kref); | 616 | void i915_ppgtt_release(struct kref *kref); |
| 614 | struct i915_hw_ppgtt *i915_ppgtt_create(struct drm_i915_private *dev_priv, | 617 | struct i915_hw_ppgtt *i915_ppgtt_create(struct drm_i915_private *dev_priv, |
| 615 | struct drm_i915_file_private *fpriv); | 618 | struct drm_i915_file_private *fpriv, |
| 619 | const char *name); | ||
| 616 | static inline void i915_ppgtt_get(struct i915_hw_ppgtt *ppgtt) | 620 | static inline void i915_ppgtt_get(struct i915_hw_ppgtt *ppgtt) |
| 617 | { | 621 | { |
| 618 | if (ppgtt) | 622 | if (ppgtt) |
| @@ -628,8 +632,10 @@ void i915_check_and_clear_faults(struct drm_i915_private *dev_priv); | |||
| 628 | void i915_gem_suspend_gtt_mappings(struct drm_device *dev); | 632 | void i915_gem_suspend_gtt_mappings(struct drm_device *dev); |
| 629 | void i915_gem_restore_gtt_mappings(struct drm_device *dev); | 633 | void i915_gem_restore_gtt_mappings(struct drm_device *dev); |
| 630 | 634 | ||
| 631 | int __must_check i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj); | 635 | int __must_check i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj, |
| 632 | void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj); | 636 | struct sg_table *pages); |
| 637 | void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj, | ||
| 638 | struct sg_table *pages); | ||
| 633 | 639 | ||
| 634 | /* Flags used by pin/bind&friends. */ | 640 | /* Flags used by pin/bind&friends. */ |
| 635 | #define PIN_NONBLOCK BIT(0) | 641 | #define PIN_NONBLOCK BIT(0) |
diff --git a/drivers/gpu/drm/i915/i915_gem_internal.c b/drivers/gpu/drm/i915/i915_gem_internal.c new file mode 100644 index 000000000000..4b3ff3e5b911 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_internal.c | |||
| @@ -0,0 +1,170 @@ | |||
| 1 | /* | ||
| 2 | * Copyright © 2014-2016 Intel Corporation | ||
| 3 | * | ||
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 5 | * copy of this software and associated documentation files (the "Software"), | ||
| 6 | * to deal in the Software without restriction, including without limitation | ||
| 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 9 | * Software is furnished to do so, subject to the following conditions: | ||
| 10 | * | ||
| 11 | * The above copyright notice and this permission notice (including the next | ||
| 12 | * paragraph) shall be included in all copies or substantial portions of the | ||
| 13 | * Software. | ||
| 14 | * | ||
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
| 21 | * IN THE SOFTWARE. | ||
| 22 | * | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <drm/drmP.h> | ||
| 26 | #include <drm/i915_drm.h> | ||
| 27 | #include "i915_drv.h" | ||
| 28 | |||
| 29 | #define QUIET (__GFP_NORETRY | __GFP_NOWARN) | ||
| 30 | |||
| 31 | /* convert swiotlb segment size into sensible units (pages)! */ | ||
| 32 | #define IO_TLB_SEGPAGES (IO_TLB_SEGSIZE << IO_TLB_SHIFT >> PAGE_SHIFT) | ||
| 33 | |||
| 34 | static void internal_free_pages(struct sg_table *st) | ||
| 35 | { | ||
| 36 | struct scatterlist *sg; | ||
| 37 | |||
| 38 | for (sg = st->sgl; sg; sg = __sg_next(sg)) | ||
| 39 | __free_pages(sg_page(sg), get_order(sg->length)); | ||
| 40 | |||
| 41 | sg_free_table(st); | ||
| 42 | kfree(st); | ||
| 43 | } | ||
| 44 | |||
| 45 | static struct sg_table * | ||
| 46 | i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj) | ||
| 47 | { | ||
| 48 | struct drm_i915_private *i915 = to_i915(obj->base.dev); | ||
| 49 | unsigned int npages = obj->base.size / PAGE_SIZE; | ||
| 50 | struct sg_table *st; | ||
| 51 | struct scatterlist *sg; | ||
| 52 | int max_order; | ||
| 53 | gfp_t gfp; | ||
| 54 | |||
| 55 | st = kmalloc(sizeof(*st), GFP_KERNEL); | ||
| 56 | if (!st) | ||
| 57 | return ERR_PTR(-ENOMEM); | ||
| 58 | |||
| 59 | if (sg_alloc_table(st, npages, GFP_KERNEL)) { | ||
| 60 | kfree(st); | ||
| 61 | return ERR_PTR(-ENOMEM); | ||
| 62 | } | ||
| 63 | |||
| 64 | sg = st->sgl; | ||
| 65 | st->nents = 0; | ||
| 66 | |||
| 67 | max_order = MAX_ORDER; | ||
| 68 | #ifdef CONFIG_SWIOTLB | ||
| 69 | if (swiotlb_nr_tbl()) /* minimum max swiotlb size is IO_TLB_SEGSIZE */ | ||
| 70 | max_order = min(max_order, ilog2(IO_TLB_SEGPAGES)); | ||
| 71 | #endif | ||
| 72 | |||
| 73 | gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_RECLAIMABLE; | ||
| 74 | if (IS_CRESTLINE(i915) || IS_BROADWATER(i915)) { | ||
| 75 | /* 965gm cannot relocate objects above 4GiB. */ | ||
| 76 | gfp &= ~__GFP_HIGHMEM; | ||
| 77 | gfp |= __GFP_DMA32; | ||
| 78 | } | ||
| 79 | |||
| 80 | do { | ||
| 81 | int order = min(fls(npages) - 1, max_order); | ||
| 82 | struct page *page; | ||
| 83 | |||
| 84 | do { | ||
| 85 | page = alloc_pages(gfp | (order ? QUIET : 0), order); | ||
| 86 | if (page) | ||
| 87 | break; | ||
| 88 | if (!order--) | ||
| 89 | goto err; | ||
| 90 | |||
| 91 | /* Limit subsequent allocations as well */ | ||
| 92 | max_order = order; | ||
| 93 | } while (1); | ||
| 94 | |||
| 95 | sg_set_page(sg, page, PAGE_SIZE << order, 0); | ||
| 96 | st->nents++; | ||
| 97 | |||
| 98 | npages -= 1 << order; | ||
| 99 | if (!npages) { | ||
| 100 | sg_mark_end(sg); | ||
| 101 | break; | ||
| 102 | } | ||
| 103 | |||
| 104 | sg = __sg_next(sg); | ||
| 105 | } while (1); | ||
| 106 | |||
| 107 | if (i915_gem_gtt_prepare_pages(obj, st)) | ||
| 108 | goto err; | ||
| 109 | |||
| 110 | /* Mark the pages as dontneed whilst they are still pinned. As soon | ||
| 111 | * as they are unpinned they are allowed to be reaped by the shrinker, | ||
| 112 | * and the caller is expected to repopulate - the contents of this | ||
| 113 | * object are only valid whilst active and pinned. | ||
| 114 | */ | ||
| 115 | obj->mm.madv = I915_MADV_DONTNEED; | ||
| 116 | return st; | ||
| 117 | |||
| 118 | err: | ||
| 119 | sg_mark_end(sg); | ||
| 120 | internal_free_pages(st); | ||
| 121 | return ERR_PTR(-ENOMEM); | ||
| 122 | } | ||
| 123 | |||
| 124 | static void i915_gem_object_put_pages_internal(struct drm_i915_gem_object *obj, | ||
| 125 | struct sg_table *pages) | ||
| 126 | { | ||
| 127 | i915_gem_gtt_finish_pages(obj, pages); | ||
| 128 | internal_free_pages(pages); | ||
| 129 | |||
| 130 | obj->mm.dirty = false; | ||
| 131 | obj->mm.madv = I915_MADV_WILLNEED; | ||
| 132 | } | ||
| 133 | |||
| 134 | static const struct drm_i915_gem_object_ops i915_gem_object_internal_ops = { | ||
| 135 | .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE | | ||
| 136 | I915_GEM_OBJECT_IS_SHRINKABLE, | ||
| 137 | .get_pages = i915_gem_object_get_pages_internal, | ||
| 138 | .put_pages = i915_gem_object_put_pages_internal, | ||
| 139 | }; | ||
| 140 | |||
| 141 | /** | ||
| 142 | * Creates a new object that wraps some internal memory for private use. | ||
| 143 | * This object is not backed by swappable storage, and as such its contents | ||
| 144 | * are volatile and only valid whilst pinned. If the object is reaped by the | ||
| 145 | * shrinker, its pages and data will be discarded. Equally, it is not a full | ||
| 146 | * GEM object and so not valid for access from userspace. This makes it useful | ||
| 147 | * for hardware interfaces like ringbuffers (which are pinned from the time | ||
| 148 | * the request is written to the time the hardware stops accessing it), but | ||
| 149 | * not for contexts (which need to be preserved when not active for later | ||
| 150 | * reuse). Note that it is not cleared upon allocation. | ||
| 151 | */ | ||
| 152 | struct drm_i915_gem_object * | ||
| 153 | i915_gem_object_create_internal(struct drm_i915_private *i915, | ||
| 154 | unsigned int size) | ||
| 155 | { | ||
| 156 | struct drm_i915_gem_object *obj; | ||
| 157 | |||
| 158 | obj = i915_gem_object_alloc(&i915->drm); | ||
| 159 | if (!obj) | ||
| 160 | return ERR_PTR(-ENOMEM); | ||
| 161 | |||
| 162 | drm_gem_private_object_init(&i915->drm, &obj->base, size); | ||
| 163 | i915_gem_object_init(obj, &i915_gem_object_internal_ops); | ||
| 164 | |||
| 165 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; | ||
| 166 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; | ||
| 167 | obj->cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE; | ||
| 168 | |||
| 169 | return obj; | ||
| 170 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c index a98c0f42badd..5af19b0bf713 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.c +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c | |||
| @@ -28,17 +28,19 @@ | |||
| 28 | #include "i915_drv.h" | 28 | #include "i915_drv.h" |
| 29 | #include "intel_renderstate.h" | 29 | #include "intel_renderstate.h" |
| 30 | 30 | ||
| 31 | struct render_state { | 31 | struct intel_render_state { |
| 32 | const struct intel_renderstate_rodata *rodata; | 32 | const struct intel_renderstate_rodata *rodata; |
| 33 | struct i915_vma *vma; | 33 | struct i915_vma *vma; |
| 34 | u32 aux_batch_size; | 34 | u32 batch_offset; |
| 35 | u32 aux_batch_offset; | 35 | u32 batch_size; |
| 36 | u32 aux_offset; | ||
| 37 | u32 aux_size; | ||
| 36 | }; | 38 | }; |
| 37 | 39 | ||
| 38 | static const struct intel_renderstate_rodata * | 40 | static const struct intel_renderstate_rodata * |
| 39 | render_state_get_rodata(const struct drm_i915_gem_request *req) | 41 | render_state_get_rodata(const struct intel_engine_cs *engine) |
| 40 | { | 42 | { |
| 41 | switch (INTEL_GEN(req->i915)) { | 43 | switch (INTEL_GEN(engine->i915)) { |
| 42 | case 6: | 44 | case 6: |
| 43 | return &gen6_null_state; | 45 | return &gen6_null_state; |
| 44 | case 7: | 46 | case 7: |
| @@ -63,29 +65,26 @@ render_state_get_rodata(const struct drm_i915_gem_request *req) | |||
| 63 | */ | 65 | */ |
| 64 | #define OUT_BATCH(batch, i, val) \ | 66 | #define OUT_BATCH(batch, i, val) \ |
| 65 | do { \ | 67 | do { \ |
| 66 | if (WARN_ON((i) >= PAGE_SIZE / sizeof(u32))) { \ | 68 | if ((i) >= PAGE_SIZE / sizeof(u32)) \ |
| 67 | ret = -ENOSPC; \ | 69 | goto err; \ |
| 68 | goto err_out; \ | ||
| 69 | } \ | ||
| 70 | (batch)[(i)++] = (val); \ | 70 | (batch)[(i)++] = (val); \ |
| 71 | } while(0) | 71 | } while(0) |
| 72 | 72 | ||
| 73 | static int render_state_setup(struct render_state *so) | 73 | static int render_state_setup(struct intel_render_state *so, |
| 74 | struct drm_i915_private *i915) | ||
| 74 | { | 75 | { |
| 75 | struct drm_i915_private *dev_priv = to_i915(so->vma->vm->dev); | ||
| 76 | const struct intel_renderstate_rodata *rodata = so->rodata; | 76 | const struct intel_renderstate_rodata *rodata = so->rodata; |
| 77 | const bool has_64bit_reloc = INTEL_GEN(dev_priv) >= 8; | 77 | struct drm_i915_gem_object *obj = so->vma->obj; |
| 78 | unsigned int i = 0, reloc_index = 0; | 78 | unsigned int i = 0, reloc_index = 0; |
| 79 | struct page *page; | 79 | unsigned int needs_clflush; |
| 80 | u32 *d; | 80 | u32 *d; |
| 81 | int ret; | 81 | int ret; |
| 82 | 82 | ||
| 83 | ret = i915_gem_object_set_to_cpu_domain(so->vma->obj, true); | 83 | ret = i915_gem_obj_prepare_shmem_write(obj, &needs_clflush); |
| 84 | if (ret) | 84 | if (ret) |
| 85 | return ret; | 85 | return ret; |
| 86 | 86 | ||
| 87 | page = i915_gem_object_get_dirty_page(so->vma->obj, 0); | 87 | d = kmap_atomic(i915_gem_object_get_dirty_page(obj, 0)); |
| 88 | d = kmap(page); | ||
| 89 | 88 | ||
| 90 | while (i < rodata->batch_items) { | 89 | while (i < rodata->batch_items) { |
| 91 | u32 s = rodata->batch[i]; | 90 | u32 s = rodata->batch[i]; |
| @@ -93,12 +92,10 @@ static int render_state_setup(struct render_state *so) | |||
| 93 | if (i * 4 == rodata->reloc[reloc_index]) { | 92 | if (i * 4 == rodata->reloc[reloc_index]) { |
| 94 | u64 r = s + so->vma->node.start; | 93 | u64 r = s + so->vma->node.start; |
| 95 | s = lower_32_bits(r); | 94 | s = lower_32_bits(r); |
| 96 | if (has_64bit_reloc) { | 95 | if (HAS_64BIT_RELOC(i915)) { |
| 97 | if (i + 1 >= rodata->batch_items || | 96 | if (i + 1 >= rodata->batch_items || |
| 98 | rodata->batch[i + 1] != 0) { | 97 | rodata->batch[i + 1] != 0) |
| 99 | ret = -EINVAL; | 98 | goto err; |
| 100 | goto err_out; | ||
| 101 | } | ||
| 102 | 99 | ||
| 103 | d[i++] = s; | 100 | d[i++] = s; |
| 104 | s = upper_32_bits(r); | 101 | s = upper_32_bits(r); |
| @@ -110,12 +107,20 @@ static int render_state_setup(struct render_state *so) | |||
| 110 | d[i++] = s; | 107 | d[i++] = s; |
| 111 | } | 108 | } |
| 112 | 109 | ||
| 110 | if (rodata->reloc[reloc_index] != -1) { | ||
| 111 | DRM_ERROR("only %d relocs resolved\n", reloc_index); | ||
| 112 | goto err; | ||
| 113 | } | ||
| 114 | |||
| 115 | so->batch_offset = so->vma->node.start; | ||
| 116 | so->batch_size = rodata->batch_items * sizeof(u32); | ||
| 117 | |||
| 113 | while (i % CACHELINE_DWORDS) | 118 | while (i % CACHELINE_DWORDS) |
| 114 | OUT_BATCH(d, i, MI_NOOP); | 119 | OUT_BATCH(d, i, MI_NOOP); |
| 115 | 120 | ||
| 116 | so->aux_batch_offset = i * sizeof(u32); | 121 | so->aux_offset = i * sizeof(u32); |
| 117 | 122 | ||
| 118 | if (HAS_POOLED_EU(dev_priv)) { | 123 | if (HAS_POOLED_EU(i915)) { |
| 119 | /* | 124 | /* |
| 120 | * We always program 3x6 pool config but depending upon which | 125 | * We always program 3x6 pool config but depending upon which |
| 121 | * subslice is disabled HW drops down to appropriate config | 126 | * subslice is disabled HW drops down to appropriate config |
| @@ -143,88 +148,133 @@ static int render_state_setup(struct render_state *so) | |||
| 143 | } | 148 | } |
| 144 | 149 | ||
| 145 | OUT_BATCH(d, i, MI_BATCH_BUFFER_END); | 150 | OUT_BATCH(d, i, MI_BATCH_BUFFER_END); |
| 146 | so->aux_batch_size = (i * sizeof(u32)) - so->aux_batch_offset; | 151 | so->aux_size = i * sizeof(u32) - so->aux_offset; |
| 147 | 152 | so->aux_offset += so->batch_offset; | |
| 148 | /* | 153 | /* |
| 149 | * Since we are sending length, we need to strictly conform to | 154 | * Since we are sending length, we need to strictly conform to |
| 150 | * all requirements. For Gen2 this must be a multiple of 8. | 155 | * all requirements. For Gen2 this must be a multiple of 8. |
| 151 | */ | 156 | */ |
| 152 | so->aux_batch_size = ALIGN(so->aux_batch_size, 8); | 157 | so->aux_size = ALIGN(so->aux_size, 8); |
| 153 | |||
| 154 | kunmap(page); | ||
| 155 | |||
| 156 | ret = i915_gem_object_set_to_gtt_domain(so->vma->obj, false); | ||
| 157 | if (ret) | ||
| 158 | return ret; | ||
| 159 | |||
| 160 | if (rodata->reloc[reloc_index] != -1) { | ||
| 161 | DRM_ERROR("only %d relocs resolved\n", reloc_index); | ||
| 162 | return -EINVAL; | ||
| 163 | } | ||
| 164 | 158 | ||
| 165 | return 0; | 159 | if (needs_clflush) |
| 160 | drm_clflush_virt_range(d, i * sizeof(u32)); | ||
| 161 | kunmap_atomic(d); | ||
| 166 | 162 | ||
| 167 | err_out: | 163 | ret = i915_gem_object_set_to_gtt_domain(obj, false); |
| 168 | kunmap(page); | 164 | out: |
| 165 | i915_gem_obj_finish_shmem_access(obj); | ||
| 169 | return ret; | 166 | return ret; |
| 167 | |||
| 168 | err: | ||
| 169 | kunmap_atomic(d); | ||
| 170 | ret = -EINVAL; | ||
| 171 | goto out; | ||
| 170 | } | 172 | } |
| 171 | 173 | ||
| 172 | #undef OUT_BATCH | 174 | #undef OUT_BATCH |
| 173 | 175 | ||
| 174 | int i915_gem_render_state_init(struct drm_i915_gem_request *req) | 176 | int i915_gem_render_state_init(struct intel_engine_cs *engine) |
| 175 | { | 177 | { |
| 176 | struct render_state so; | 178 | struct intel_render_state *so; |
| 179 | const struct intel_renderstate_rodata *rodata; | ||
| 177 | struct drm_i915_gem_object *obj; | 180 | struct drm_i915_gem_object *obj; |
| 178 | int ret; | 181 | int ret; |
| 179 | 182 | ||
| 180 | if (WARN_ON(req->engine->id != RCS)) | 183 | if (engine->id != RCS) |
| 181 | return -ENOENT; | 184 | return 0; |
| 182 | 185 | ||
| 183 | so.rodata = render_state_get_rodata(req); | 186 | rodata = render_state_get_rodata(engine); |
| 184 | if (!so.rodata) | 187 | if (!rodata) |
| 185 | return 0; | 188 | return 0; |
| 186 | 189 | ||
| 187 | if (so.rodata->batch_items * 4 > 4096) | 190 | if (rodata->batch_items * 4 > 4096) |
| 188 | return -EINVAL; | 191 | return -EINVAL; |
| 189 | 192 | ||
| 190 | obj = i915_gem_object_create(&req->i915->drm, 4096); | 193 | so = kmalloc(sizeof(*so), GFP_KERNEL); |
| 191 | if (IS_ERR(obj)) | 194 | if (!so) |
| 192 | return PTR_ERR(obj); | 195 | return -ENOMEM; |
| 193 | 196 | ||
| 194 | so.vma = i915_vma_create(obj, &req->i915->ggtt.base, NULL); | 197 | obj = i915_gem_object_create_internal(engine->i915, 4096); |
| 195 | if (IS_ERR(so.vma)) { | 198 | if (IS_ERR(obj)) { |
| 196 | ret = PTR_ERR(so.vma); | 199 | ret = PTR_ERR(obj); |
| 197 | goto err_obj; | 200 | goto err_free; |
| 198 | } | 201 | } |
| 199 | 202 | ||
| 200 | ret = i915_vma_pin(so.vma, 0, 0, PIN_GLOBAL); | 203 | so->vma = i915_vma_create(obj, &engine->i915->ggtt.base, NULL); |
| 201 | if (ret) | 204 | if (IS_ERR(so->vma)) { |
| 205 | ret = PTR_ERR(so->vma); | ||
| 202 | goto err_obj; | 206 | goto err_obj; |
| 207 | } | ||
| 208 | |||
| 209 | so->rodata = rodata; | ||
| 210 | engine->render_state = so; | ||
| 211 | return 0; | ||
| 212 | |||
| 213 | err_obj: | ||
| 214 | i915_gem_object_put(obj); | ||
| 215 | err_free: | ||
| 216 | kfree(so); | ||
| 217 | return ret; | ||
| 218 | } | ||
| 219 | |||
| 220 | int i915_gem_render_state_emit(struct drm_i915_gem_request *req) | ||
| 221 | { | ||
| 222 | struct intel_render_state *so; | ||
| 223 | int ret; | ||
| 224 | |||
| 225 | lockdep_assert_held(&req->i915->drm.struct_mutex); | ||
| 203 | 226 | ||
| 204 | ret = render_state_setup(&so); | 227 | so = req->engine->render_state; |
| 228 | if (!so) | ||
| 229 | return 0; | ||
| 230 | |||
| 231 | /* Recreate the page after shrinking */ | ||
| 232 | if (!so->vma->obj->mm.pages) | ||
| 233 | so->batch_offset = -1; | ||
| 234 | |||
| 235 | ret = i915_vma_pin(so->vma, 0, 0, PIN_GLOBAL | PIN_HIGH); | ||
| 205 | if (ret) | 236 | if (ret) |
| 206 | goto err_unpin; | 237 | return ret; |
| 238 | |||
| 239 | if (so->vma->node.start != so->batch_offset) { | ||
| 240 | ret = render_state_setup(so, req->i915); | ||
| 241 | if (ret) | ||
| 242 | goto err_unpin; | ||
| 243 | } | ||
| 207 | 244 | ||
| 208 | ret = req->engine->emit_bb_start(req, so.vma->node.start, | 245 | ret = req->engine->emit_bb_start(req, |
| 209 | so.rodata->batch_items * 4, | 246 | so->batch_offset, so->batch_size, |
| 210 | I915_DISPATCH_SECURE); | 247 | I915_DISPATCH_SECURE); |
| 211 | if (ret) | 248 | if (ret) |
| 212 | goto err_unpin; | 249 | goto err_unpin; |
| 213 | 250 | ||
| 214 | if (so.aux_batch_size > 8) { | 251 | if (so->aux_size > 8) { |
| 215 | ret = req->engine->emit_bb_start(req, | 252 | ret = req->engine->emit_bb_start(req, |
| 216 | (so.vma->node.start + | 253 | so->aux_offset, so->aux_size, |
| 217 | so.aux_batch_offset), | ||
| 218 | so.aux_batch_size, | ||
| 219 | I915_DISPATCH_SECURE); | 254 | I915_DISPATCH_SECURE); |
| 220 | if (ret) | 255 | if (ret) |
| 221 | goto err_unpin; | 256 | goto err_unpin; |
| 222 | } | 257 | } |
| 223 | 258 | ||
| 224 | i915_vma_move_to_active(so.vma, req, 0); | 259 | i915_vma_move_to_active(so->vma, req, 0); |
| 225 | err_unpin: | 260 | err_unpin: |
| 226 | i915_vma_unpin(so.vma); | 261 | i915_vma_unpin(so->vma); |
| 227 | err_obj: | ||
| 228 | i915_gem_object_put(obj); | ||
| 229 | return ret; | 262 | return ret; |
| 230 | } | 263 | } |
| 264 | |||
| 265 | void i915_gem_render_state_fini(struct intel_engine_cs *engine) | ||
| 266 | { | ||
| 267 | struct intel_render_state *so; | ||
| 268 | struct drm_i915_gem_object *obj; | ||
| 269 | |||
| 270 | so = fetch_and_zero(&engine->render_state); | ||
| 271 | if (!so) | ||
| 272 | return; | ||
| 273 | |||
| 274 | obj = so->vma->obj; | ||
| 275 | |||
| 276 | i915_vma_close(so->vma); | ||
| 277 | __i915_gem_object_release_unless_active(obj); | ||
| 278 | |||
| 279 | kfree(so); | ||
| 280 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.h b/drivers/gpu/drm/i915/i915_gem_render_state.h index 18cce3f06e9c..87481845799d 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.h +++ b/drivers/gpu/drm/i915/i915_gem_render_state.h | |||
| @@ -26,6 +26,8 @@ | |||
| 26 | 26 | ||
| 27 | struct drm_i915_gem_request; | 27 | struct drm_i915_gem_request; |
| 28 | 28 | ||
| 29 | int i915_gem_render_state_init(struct drm_i915_gem_request *req); | 29 | int i915_gem_render_state_init(struct intel_engine_cs *engine); |
| 30 | int i915_gem_render_state_emit(struct drm_i915_gem_request *req); | ||
| 31 | void i915_gem_render_state_fini(struct intel_engine_cs *engine); | ||
| 30 | 32 | ||
| 31 | #endif /* _I915_GEM_RENDER_STATE_H_ */ | 33 | #endif /* _I915_GEM_RENDER_STATE_H_ */ |
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index f9af2a00625e..0b3b051a5683 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | */ | 23 | */ |
| 24 | 24 | ||
| 25 | #include <linux/prefetch.h> | 25 | #include <linux/prefetch.h> |
| 26 | #include <linux/dma-fence-array.h> | ||
| 26 | 27 | ||
| 27 | #include "i915_drv.h" | 28 | #include "i915_drv.h" |
| 28 | 29 | ||
| @@ -33,13 +34,7 @@ static const char *i915_fence_get_driver_name(struct dma_fence *fence) | |||
| 33 | 34 | ||
| 34 | static const char *i915_fence_get_timeline_name(struct dma_fence *fence) | 35 | static const char *i915_fence_get_timeline_name(struct dma_fence *fence) |
| 35 | { | 36 | { |
| 36 | /* Timelines are bound by eviction to a VM. However, since | 37 | return to_request(fence)->timeline->common->name; |
| 37 | * we only have a global seqno at the moment, we only have | ||
| 38 | * a single timeline. Note that each timeline will have | ||
| 39 | * multiple execution contexts (fence contexts) as we allow | ||
| 40 | * engines within a single timeline to execute in parallel. | ||
| 41 | */ | ||
| 42 | return "global"; | ||
| 43 | } | 38 | } |
| 44 | 39 | ||
| 45 | static bool i915_fence_signaled(struct dma_fence *fence) | 40 | static bool i915_fence_signaled(struct dma_fence *fence) |
| @@ -58,43 +53,9 @@ static bool i915_fence_enable_signaling(struct dma_fence *fence) | |||
| 58 | 53 | ||
| 59 | static signed long i915_fence_wait(struct dma_fence *fence, | 54 | static signed long i915_fence_wait(struct dma_fence *fence, |
| 60 | bool interruptible, | 55 | bool interruptible, |
| 61 | signed long timeout_jiffies) | 56 | signed long timeout) |
| 62 | { | 57 | { |
| 63 | s64 timeout_ns, *timeout; | 58 | return i915_wait_request(to_request(fence), interruptible, timeout); |
| 64 | int ret; | ||
| 65 | |||
| 66 | if (timeout_jiffies != MAX_SCHEDULE_TIMEOUT) { | ||
| 67 | timeout_ns = jiffies_to_nsecs(timeout_jiffies); | ||
| 68 | timeout = &timeout_ns; | ||
| 69 | } else { | ||
| 70 | timeout = NULL; | ||
| 71 | } | ||
| 72 | |||
| 73 | ret = i915_wait_request(to_request(fence), | ||
| 74 | interruptible, timeout, | ||
| 75 | NO_WAITBOOST); | ||
| 76 | if (ret == -ETIME) | ||
| 77 | return 0; | ||
| 78 | |||
| 79 | if (ret < 0) | ||
| 80 | return ret; | ||
| 81 | |||
| 82 | if (timeout_jiffies != MAX_SCHEDULE_TIMEOUT) | ||
| 83 | timeout_jiffies = nsecs_to_jiffies(timeout_ns); | ||
| 84 | |||
| 85 | return timeout_jiffies; | ||
| 86 | } | ||
| 87 | |||
| 88 | static void i915_fence_value_str(struct dma_fence *fence, char *str, int size) | ||
| 89 | { | ||
| 90 | snprintf(str, size, "%u", fence->seqno); | ||
| 91 | } | ||
| 92 | |||
| 93 | static void i915_fence_timeline_value_str(struct dma_fence *fence, char *str, | ||
| 94 | int size) | ||
| 95 | { | ||
| 96 | snprintf(str, size, "%u", | ||
| 97 | intel_engine_get_seqno(to_request(fence)->engine)); | ||
| 98 | } | 59 | } |
| 99 | 60 | ||
| 100 | static void i915_fence_release(struct dma_fence *fence) | 61 | static void i915_fence_release(struct dma_fence *fence) |
| @@ -111,8 +72,6 @@ const struct dma_fence_ops i915_fence_ops = { | |||
| 111 | .signaled = i915_fence_signaled, | 72 | .signaled = i915_fence_signaled, |
| 112 | .wait = i915_fence_wait, | 73 | .wait = i915_fence_wait, |
| 113 | .release = i915_fence_release, | 74 | .release = i915_fence_release, |
| 114 | .fence_value_str = i915_fence_value_str, | ||
| 115 | .timeline_value_str = i915_fence_timeline_value_str, | ||
| 116 | }; | 75 | }; |
| 117 | 76 | ||
| 118 | int i915_gem_request_add_to_client(struct drm_i915_gem_request *req, | 77 | int i915_gem_request_add_to_client(struct drm_i915_gem_request *req, |
| @@ -164,8 +123,14 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request) | |||
| 164 | { | 123 | { |
| 165 | struct i915_gem_active *active, *next; | 124 | struct i915_gem_active *active, *next; |
| 166 | 125 | ||
| 126 | lockdep_assert_held(&request->i915->drm.struct_mutex); | ||
| 127 | GEM_BUG_ON(!i915_gem_request_completed(request)); | ||
| 128 | |||
| 167 | trace_i915_gem_request_retire(request); | 129 | trace_i915_gem_request_retire(request); |
| 168 | list_del(&request->link); | 130 | |
| 131 | spin_lock_irq(&request->engine->timeline->lock); | ||
| 132 | list_del_init(&request->link); | ||
| 133 | spin_unlock_irq(&request->engine->timeline->lock); | ||
| 169 | 134 | ||
| 170 | /* We know the GPU must have read the request to have | 135 | /* We know the GPU must have read the request to have |
| 171 | * sent us the seqno + interrupt, so use the position | 136 | * sent us the seqno + interrupt, so use the position |
| @@ -177,6 +142,7 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request) | |||
| 177 | */ | 142 | */ |
| 178 | list_del(&request->ring_link); | 143 | list_del(&request->ring_link); |
| 179 | request->ring->last_retired_head = request->postfix; | 144 | request->ring->last_retired_head = request->postfix; |
| 145 | request->i915->gt.active_requests--; | ||
| 180 | 146 | ||
| 181 | /* Walk through the active list, calling retire on each. This allows | 147 | /* Walk through the active list, calling retire on each. This allows |
| 182 | * objects to track their GPU activity and mark themselves as idle | 148 | * objects to track their GPU activity and mark themselves as idle |
| @@ -214,6 +180,8 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request) | |||
| 214 | } | 180 | } |
| 215 | 181 | ||
| 216 | i915_gem_context_put(request->ctx); | 182 | i915_gem_context_put(request->ctx); |
| 183 | |||
| 184 | dma_fence_signal(&request->fence); | ||
| 217 | i915_gem_request_put(request); | 185 | i915_gem_request_put(request); |
| 218 | } | 186 | } |
| 219 | 187 | ||
| @@ -223,10 +191,11 @@ void i915_gem_request_retire_upto(struct drm_i915_gem_request *req) | |||
| 223 | struct drm_i915_gem_request *tmp; | 191 | struct drm_i915_gem_request *tmp; |
| 224 | 192 | ||
| 225 | lockdep_assert_held(&req->i915->drm.struct_mutex); | 193 | lockdep_assert_held(&req->i915->drm.struct_mutex); |
| 226 | GEM_BUG_ON(list_empty(&req->link)); | 194 | if (list_empty(&req->link)) |
| 195 | return; | ||
| 227 | 196 | ||
| 228 | do { | 197 | do { |
| 229 | tmp = list_first_entry(&engine->request_list, | 198 | tmp = list_first_entry(&engine->timeline->requests, |
| 230 | typeof(*tmp), link); | 199 | typeof(*tmp), link); |
| 231 | 200 | ||
| 232 | i915_gem_request_retire(tmp); | 201 | i915_gem_request_retire(tmp); |
| @@ -253,40 +222,51 @@ static int i915_gem_check_wedge(struct drm_i915_private *dev_priv) | |||
| 253 | return 0; | 222 | return 0; |
| 254 | } | 223 | } |
| 255 | 224 | ||
| 256 | static int i915_gem_init_seqno(struct drm_i915_private *dev_priv, u32 seqno) | 225 | static int i915_gem_init_global_seqno(struct drm_i915_private *i915, u32 seqno) |
| 257 | { | 226 | { |
| 227 | struct i915_gem_timeline *timeline = &i915->gt.global_timeline; | ||
| 258 | struct intel_engine_cs *engine; | 228 | struct intel_engine_cs *engine; |
| 259 | enum intel_engine_id id; | 229 | enum intel_engine_id id; |
| 260 | int ret; | 230 | int ret; |
| 261 | 231 | ||
| 262 | /* Carefully retire all requests without writing to the rings */ | 232 | /* Carefully retire all requests without writing to the rings */ |
| 263 | for_each_engine(engine, dev_priv, id) { | 233 | ret = i915_gem_wait_for_idle(i915, |
| 264 | ret = intel_engine_idle(engine, | 234 | I915_WAIT_INTERRUPTIBLE | |
| 265 | I915_WAIT_INTERRUPTIBLE | | 235 | I915_WAIT_LOCKED); |
| 266 | I915_WAIT_LOCKED); | 236 | if (ret) |
| 267 | if (ret) | 237 | return ret; |
| 268 | return ret; | 238 | |
| 269 | } | 239 | i915_gem_retire_requests(i915); |
| 270 | i915_gem_retire_requests(dev_priv); | 240 | GEM_BUG_ON(i915->gt.active_requests > 1); |
| 271 | 241 | ||
| 272 | /* If the seqno wraps around, we need to clear the breadcrumb rbtree */ | 242 | /* If the seqno wraps around, we need to clear the breadcrumb rbtree */ |
| 273 | if (!i915_seqno_passed(seqno, dev_priv->next_seqno)) { | 243 | if (!i915_seqno_passed(seqno, atomic_read(&timeline->next_seqno))) { |
| 274 | while (intel_kick_waiters(dev_priv) || | 244 | while (intel_kick_waiters(i915) || intel_kick_signalers(i915)) |
| 275 | intel_kick_signalers(dev_priv)) | ||
| 276 | yield(); | 245 | yield(); |
| 246 | yield(); | ||
| 277 | } | 247 | } |
| 248 | atomic_set(&timeline->next_seqno, seqno); | ||
| 278 | 249 | ||
| 279 | /* Finally reset hw state */ | 250 | /* Finally reset hw state */ |
| 280 | for_each_engine(engine, dev_priv, id) | 251 | for_each_engine(engine, i915, id) |
| 281 | intel_engine_init_seqno(engine, seqno); | 252 | intel_engine_init_global_seqno(engine, seqno); |
| 253 | |||
| 254 | list_for_each_entry(timeline, &i915->gt.timelines, link) { | ||
| 255 | for_each_engine(engine, i915, id) { | ||
| 256 | struct intel_timeline *tl = &timeline->engine[id]; | ||
| 257 | |||
| 258 | memset(tl->sync_seqno, 0, sizeof(tl->sync_seqno)); | ||
| 259 | } | ||
| 260 | } | ||
| 282 | 261 | ||
| 283 | return 0; | 262 | return 0; |
| 284 | } | 263 | } |
| 285 | 264 | ||
| 286 | int i915_gem_set_seqno(struct drm_device *dev, u32 seqno) | 265 | int i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno) |
| 287 | { | 266 | { |
| 288 | struct drm_i915_private *dev_priv = to_i915(dev); | 267 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 289 | int ret; | 268 | |
| 269 | lockdep_assert_held(&dev_priv->drm.struct_mutex); | ||
| 290 | 270 | ||
| 291 | if (seqno == 0) | 271 | if (seqno == 0) |
| 292 | return -EINVAL; | 272 | return -EINVAL; |
| @@ -294,48 +274,84 @@ int i915_gem_set_seqno(struct drm_device *dev, u32 seqno) | |||
| 294 | /* HWS page needs to be set less than what we | 274 | /* HWS page needs to be set less than what we |
| 295 | * will inject to ring | 275 | * will inject to ring |
| 296 | */ | 276 | */ |
| 297 | ret = i915_gem_init_seqno(dev_priv, seqno - 1); | 277 | return i915_gem_init_global_seqno(dev_priv, seqno - 1); |
| 298 | if (ret) | ||
| 299 | return ret; | ||
| 300 | |||
| 301 | dev_priv->next_seqno = seqno; | ||
| 302 | return 0; | ||
| 303 | } | 278 | } |
| 304 | 279 | ||
| 305 | static int i915_gem_get_seqno(struct drm_i915_private *dev_priv, u32 *seqno) | 280 | static int reserve_global_seqno(struct drm_i915_private *i915) |
| 306 | { | 281 | { |
| 307 | /* reserve 0 for non-seqno */ | 282 | u32 active_requests = ++i915->gt.active_requests; |
| 308 | if (unlikely(dev_priv->next_seqno == 0)) { | 283 | u32 next_seqno = atomic_read(&i915->gt.global_timeline.next_seqno); |
| 309 | int ret; | 284 | int ret; |
| 310 | 285 | ||
| 311 | ret = i915_gem_init_seqno(dev_priv, 0); | 286 | /* Reservation is fine until we need to wrap around */ |
| 312 | if (ret) | 287 | if (likely(next_seqno + active_requests > next_seqno)) |
| 313 | return ret; | 288 | return 0; |
| 314 | 289 | ||
| 315 | dev_priv->next_seqno = 1; | 290 | ret = i915_gem_init_global_seqno(i915, 0); |
| 291 | if (ret) { | ||
| 292 | i915->gt.active_requests--; | ||
| 293 | return ret; | ||
| 316 | } | 294 | } |
| 317 | 295 | ||
| 318 | *seqno = dev_priv->next_seqno++; | ||
| 319 | return 0; | 296 | return 0; |
| 320 | } | 297 | } |
| 321 | 298 | ||
| 299 | static u32 __timeline_get_seqno(struct i915_gem_timeline *tl) | ||
| 300 | { | ||
| 301 | /* next_seqno only incremented under a mutex */ | ||
| 302 | return ++tl->next_seqno.counter; | ||
| 303 | } | ||
| 304 | |||
| 305 | static u32 timeline_get_seqno(struct i915_gem_timeline *tl) | ||
| 306 | { | ||
| 307 | return atomic_inc_return(&tl->next_seqno); | ||
| 308 | } | ||
| 309 | |||
| 322 | static int __i915_sw_fence_call | 310 | static int __i915_sw_fence_call |
| 323 | submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state) | 311 | submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state) |
| 324 | { | 312 | { |
| 325 | struct drm_i915_gem_request *request = | 313 | struct drm_i915_gem_request *request = |
| 326 | container_of(fence, typeof(*request), submit); | 314 | container_of(fence, typeof(*request), submit); |
| 315 | struct intel_engine_cs *engine = request->engine; | ||
| 316 | struct intel_timeline *timeline; | ||
| 317 | unsigned long flags; | ||
| 318 | u32 seqno; | ||
| 319 | |||
| 320 | if (state != FENCE_COMPLETE) | ||
| 321 | return NOTIFY_DONE; | ||
| 322 | |||
| 323 | /* Transfer from per-context onto the global per-engine timeline */ | ||
| 324 | timeline = engine->timeline; | ||
| 325 | GEM_BUG_ON(timeline == request->timeline); | ||
| 327 | 326 | ||
| 328 | /* Will be called from irq-context when using foreign DMA fences */ | 327 | /* Will be called from irq-context when using foreign DMA fences */ |
| 328 | spin_lock_irqsave(&timeline->lock, flags); | ||
| 329 | 329 | ||
| 330 | switch (state) { | 330 | seqno = timeline_get_seqno(timeline->common); |
| 331 | case FENCE_COMPLETE: | 331 | GEM_BUG_ON(!seqno); |
| 332 | request->engine->last_submitted_seqno = request->fence.seqno; | 332 | GEM_BUG_ON(i915_seqno_passed(intel_engine_get_seqno(engine), seqno)); |
| 333 | request->engine->submit_request(request); | ||
| 334 | break; | ||
| 335 | 333 | ||
| 336 | case FENCE_FREE: | 334 | GEM_BUG_ON(i915_seqno_passed(timeline->last_submitted_seqno, seqno)); |
| 337 | break; | 335 | request->previous_seqno = timeline->last_submitted_seqno; |
| 338 | } | 336 | timeline->last_submitted_seqno = seqno; |
| 337 | |||
| 338 | /* We may be recursing from the signal callback of another i915 fence */ | ||
| 339 | spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING); | ||
| 340 | request->global_seqno = seqno; | ||
| 341 | if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags)) | ||
| 342 | intel_engine_enable_signaling(request); | ||
| 343 | spin_unlock(&request->lock); | ||
| 344 | |||
| 345 | GEM_BUG_ON(!request->global_seqno); | ||
| 346 | engine->emit_breadcrumb(request, | ||
| 347 | request->ring->vaddr + request->postfix); | ||
| 348 | engine->submit_request(request); | ||
| 349 | |||
| 350 | spin_lock_nested(&request->timeline->lock, SINGLE_DEPTH_NESTING); | ||
| 351 | list_move_tail(&request->link, &timeline->requests); | ||
| 352 | spin_unlock(&request->timeline->lock); | ||
| 353 | |||
| 354 | spin_unlock_irqrestore(&timeline->lock, flags); | ||
| 339 | 355 | ||
| 340 | return NOTIFY_DONE; | 356 | return NOTIFY_DONE; |
| 341 | } | 357 | } |
| @@ -358,9 +374,10 @@ i915_gem_request_alloc(struct intel_engine_cs *engine, | |||
| 358 | { | 374 | { |
| 359 | struct drm_i915_private *dev_priv = engine->i915; | 375 | struct drm_i915_private *dev_priv = engine->i915; |
| 360 | struct drm_i915_gem_request *req; | 376 | struct drm_i915_gem_request *req; |
| 361 | u32 seqno; | ||
| 362 | int ret; | 377 | int ret; |
| 363 | 378 | ||
| 379 | lockdep_assert_held(&dev_priv->drm.struct_mutex); | ||
| 380 | |||
| 364 | /* ABI: Before userspace accesses the GPU (e.g. execbuffer), report | 381 | /* ABI: Before userspace accesses the GPU (e.g. execbuffer), report |
| 365 | * EIO if the GPU is already wedged, or EAGAIN to drop the struct_mutex | 382 | * EIO if the GPU is already wedged, or EAGAIN to drop the struct_mutex |
| 366 | * and restart. | 383 | * and restart. |
| @@ -369,10 +386,14 @@ i915_gem_request_alloc(struct intel_engine_cs *engine, | |||
| 369 | if (ret) | 386 | if (ret) |
| 370 | return ERR_PTR(ret); | 387 | return ERR_PTR(ret); |
| 371 | 388 | ||
| 389 | ret = reserve_global_seqno(dev_priv); | ||
| 390 | if (ret) | ||
| 391 | return ERR_PTR(ret); | ||
| 392 | |||
| 372 | /* Move the oldest request to the slab-cache (if not in use!) */ | 393 | /* Move the oldest request to the slab-cache (if not in use!) */ |
| 373 | req = list_first_entry_or_null(&engine->request_list, | 394 | req = list_first_entry_or_null(&engine->timeline->requests, |
| 374 | typeof(*req), link); | 395 | typeof(*req), link); |
| 375 | if (req && i915_gem_request_completed(req)) | 396 | if (req && __i915_gem_request_completed(req)) |
| 376 | i915_gem_request_retire(req); | 397 | i915_gem_request_retire(req); |
| 377 | 398 | ||
| 378 | /* Beware: Dragons be flying overhead. | 399 | /* Beware: Dragons be flying overhead. |
| @@ -383,7 +404,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine, | |||
| 383 | * of being read by __i915_gem_active_get_rcu(). As such, | 404 | * of being read by __i915_gem_active_get_rcu(). As such, |
| 384 | * we have to be very careful when overwriting the contents. During | 405 | * we have to be very careful when overwriting the contents. During |
| 385 | * the RCU lookup, we change chase the request->engine pointer, | 406 | * the RCU lookup, we change chase the request->engine pointer, |
| 386 | * read the request->fence.seqno and increment the reference count. | 407 | * read the request->global_seqno and increment the reference count. |
| 387 | * | 408 | * |
| 388 | * The reference count is incremented atomically. If it is zero, | 409 | * The reference count is incremented atomically. If it is zero, |
| 389 | * the lookup knows the request is unallocated and complete. Otherwise, | 410 | * the lookup knows the request is unallocated and complete. Otherwise, |
| @@ -404,19 +425,20 @@ i915_gem_request_alloc(struct intel_engine_cs *engine, | |||
| 404 | * Do not use kmem_cache_zalloc() here! | 425 | * Do not use kmem_cache_zalloc() here! |
| 405 | */ | 426 | */ |
| 406 | req = kmem_cache_alloc(dev_priv->requests, GFP_KERNEL); | 427 | req = kmem_cache_alloc(dev_priv->requests, GFP_KERNEL); |
| 407 | if (!req) | 428 | if (!req) { |
| 408 | return ERR_PTR(-ENOMEM); | 429 | ret = -ENOMEM; |
| 430 | goto err_unreserve; | ||
| 431 | } | ||
| 409 | 432 | ||
| 410 | ret = i915_gem_get_seqno(dev_priv, &seqno); | 433 | req->timeline = i915_gem_context_lookup_timeline(ctx, engine); |
| 411 | if (ret) | 434 | GEM_BUG_ON(req->timeline == engine->timeline); |
| 412 | goto err; | ||
| 413 | 435 | ||
| 414 | spin_lock_init(&req->lock); | 436 | spin_lock_init(&req->lock); |
| 415 | dma_fence_init(&req->fence, | 437 | dma_fence_init(&req->fence, |
| 416 | &i915_fence_ops, | 438 | &i915_fence_ops, |
| 417 | &req->lock, | 439 | &req->lock, |
| 418 | engine->fence_context, | 440 | req->timeline->fence_context, |
| 419 | seqno); | 441 | __timeline_get_seqno(req->timeline->common)); |
| 420 | 442 | ||
| 421 | i915_sw_fence_init(&req->submit, submit_notify); | 443 | i915_sw_fence_init(&req->submit, submit_notify); |
| 422 | 444 | ||
| @@ -426,6 +448,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine, | |||
| 426 | req->ctx = i915_gem_context_get(ctx); | 448 | req->ctx = i915_gem_context_get(ctx); |
| 427 | 449 | ||
| 428 | /* No zalloc, must clear what we need by hand */ | 450 | /* No zalloc, must clear what we need by hand */ |
| 451 | req->global_seqno = 0; | ||
| 429 | req->previous_context = NULL; | 452 | req->previous_context = NULL; |
| 430 | req->file_priv = NULL; | 453 | req->file_priv = NULL; |
| 431 | req->batch = NULL; | 454 | req->batch = NULL; |
| @@ -438,6 +461,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine, | |||
| 438 | * away, e.g. because a GPU scheduler has deferred it. | 461 | * away, e.g. because a GPU scheduler has deferred it. |
| 439 | */ | 462 | */ |
| 440 | req->reserved_space = MIN_SPACE_FOR_ADD_REQUEST; | 463 | req->reserved_space = MIN_SPACE_FOR_ADD_REQUEST; |
| 464 | GEM_BUG_ON(req->reserved_space < engine->emit_breadcrumb_sz); | ||
| 441 | 465 | ||
| 442 | if (i915.enable_execlists) | 466 | if (i915.enable_execlists) |
| 443 | ret = intel_logical_ring_alloc_request_extras(req); | 467 | ret = intel_logical_ring_alloc_request_extras(req); |
| @@ -457,8 +481,9 @@ i915_gem_request_alloc(struct intel_engine_cs *engine, | |||
| 457 | 481 | ||
| 458 | err_ctx: | 482 | err_ctx: |
| 459 | i915_gem_context_put(ctx); | 483 | i915_gem_context_put(ctx); |
| 460 | err: | ||
| 461 | kmem_cache_free(dev_priv->requests, req); | 484 | kmem_cache_free(dev_priv->requests, req); |
| 485 | err_unreserve: | ||
| 486 | dev_priv->gt.active_requests--; | ||
| 462 | return ERR_PTR(ret); | 487 | return ERR_PTR(ret); |
| 463 | } | 488 | } |
| 464 | 489 | ||
| @@ -466,15 +491,28 @@ static int | |||
| 466 | i915_gem_request_await_request(struct drm_i915_gem_request *to, | 491 | i915_gem_request_await_request(struct drm_i915_gem_request *to, |
| 467 | struct drm_i915_gem_request *from) | 492 | struct drm_i915_gem_request *from) |
| 468 | { | 493 | { |
| 469 | int idx, ret; | 494 | int ret; |
| 470 | 495 | ||
| 471 | GEM_BUG_ON(to == from); | 496 | GEM_BUG_ON(to == from); |
| 472 | 497 | ||
| 473 | if (to->engine == from->engine) | 498 | if (to->timeline == from->timeline) |
| 474 | return 0; | 499 | return 0; |
| 475 | 500 | ||
| 476 | idx = intel_engine_sync_index(from->engine, to->engine); | 501 | if (to->engine == from->engine) { |
| 477 | if (from->fence.seqno <= from->engine->semaphore.sync_seqno[idx]) | 502 | ret = i915_sw_fence_await_sw_fence_gfp(&to->submit, |
| 503 | &from->submit, | ||
| 504 | GFP_KERNEL); | ||
| 505 | return ret < 0 ? ret : 0; | ||
| 506 | } | ||
| 507 | |||
| 508 | if (!from->global_seqno) { | ||
| 509 | ret = i915_sw_fence_await_dma_fence(&to->submit, | ||
| 510 | &from->fence, 0, | ||
| 511 | GFP_KERNEL); | ||
| 512 | return ret < 0 ? ret : 0; | ||
| 513 | } | ||
| 514 | |||
| 515 | if (from->global_seqno <= to->timeline->sync_seqno[from->engine->id]) | ||
| 478 | return 0; | 516 | return 0; |
| 479 | 517 | ||
| 480 | trace_i915_gem_ring_sync_to(to, from); | 518 | trace_i915_gem_ring_sync_to(to, from); |
| @@ -492,7 +530,54 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to, | |||
| 492 | return ret; | 530 | return ret; |
| 493 | } | 531 | } |
| 494 | 532 | ||
| 495 | from->engine->semaphore.sync_seqno[idx] = from->fence.seqno; | 533 | to->timeline->sync_seqno[from->engine->id] = from->global_seqno; |
| 534 | return 0; | ||
| 535 | } | ||
| 536 | |||
| 537 | int | ||
| 538 | i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req, | ||
| 539 | struct dma_fence *fence) | ||
| 540 | { | ||
| 541 | struct dma_fence_array *array; | ||
| 542 | int ret; | ||
| 543 | int i; | ||
| 544 | |||
| 545 | if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) | ||
| 546 | return 0; | ||
| 547 | |||
| 548 | if (dma_fence_is_i915(fence)) | ||
| 549 | return i915_gem_request_await_request(req, to_request(fence)); | ||
| 550 | |||
| 551 | if (!dma_fence_is_array(fence)) { | ||
| 552 | ret = i915_sw_fence_await_dma_fence(&req->submit, | ||
| 553 | fence, I915_FENCE_TIMEOUT, | ||
| 554 | GFP_KERNEL); | ||
| 555 | return ret < 0 ? ret : 0; | ||
| 556 | } | ||
| 557 | |||
| 558 | /* Note that if the fence-array was created in signal-on-any mode, | ||
| 559 | * we should *not* decompose it into its individual fences. However, | ||
| 560 | * we don't currently store which mode the fence-array is operating | ||
| 561 | * in. Fortunately, the only user of signal-on-any is private to | ||
| 562 | * amdgpu and we should not see any incoming fence-array from | ||
| 563 | * sync-file being in signal-on-any mode. | ||
| 564 | */ | ||
| 565 | |||
| 566 | array = to_dma_fence_array(fence); | ||
| 567 | for (i = 0; i < array->num_fences; i++) { | ||
| 568 | struct dma_fence *child = array->fences[i]; | ||
| 569 | |||
| 570 | if (dma_fence_is_i915(child)) | ||
| 571 | ret = i915_gem_request_await_request(req, | ||
| 572 | to_request(child)); | ||
| 573 | else | ||
| 574 | ret = i915_sw_fence_await_dma_fence(&req->submit, | ||
| 575 | child, I915_FENCE_TIMEOUT, | ||
| 576 | GFP_KERNEL); | ||
| 577 | if (ret < 0) | ||
| 578 | return ret; | ||
| 579 | } | ||
| 580 | |||
| 496 | return 0; | 581 | return 0; |
| 497 | } | 582 | } |
| 498 | 583 | ||
| @@ -521,40 +606,47 @@ i915_gem_request_await_object(struct drm_i915_gem_request *to, | |||
| 521 | struct drm_i915_gem_object *obj, | 606 | struct drm_i915_gem_object *obj, |
| 522 | bool write) | 607 | bool write) |
| 523 | { | 608 | { |
| 524 | struct i915_gem_active *active; | 609 | struct dma_fence *excl; |
| 525 | unsigned long active_mask; | 610 | int ret = 0; |
| 526 | int idx; | ||
| 527 | 611 | ||
| 528 | if (write) { | 612 | if (write) { |
| 529 | active_mask = i915_gem_object_get_active(obj); | 613 | struct dma_fence **shared; |
| 530 | active = obj->last_read; | 614 | unsigned int count, i; |
| 615 | |||
| 616 | ret = reservation_object_get_fences_rcu(obj->resv, | ||
| 617 | &excl, &count, &shared); | ||
| 618 | if (ret) | ||
| 619 | return ret; | ||
| 620 | |||
| 621 | for (i = 0; i < count; i++) { | ||
| 622 | ret = i915_gem_request_await_dma_fence(to, shared[i]); | ||
| 623 | if (ret) | ||
| 624 | break; | ||
| 625 | |||
| 626 | dma_fence_put(shared[i]); | ||
| 627 | } | ||
| 628 | |||
| 629 | for (; i < count; i++) | ||
| 630 | dma_fence_put(shared[i]); | ||
| 631 | kfree(shared); | ||
| 531 | } else { | 632 | } else { |
| 532 | active_mask = 1; | 633 | excl = reservation_object_get_excl_rcu(obj->resv); |
| 533 | active = &obj->last_write; | ||
| 534 | } | 634 | } |
| 535 | 635 | ||
| 536 | for_each_active(active_mask, idx) { | 636 | if (excl) { |
| 537 | struct drm_i915_gem_request *request; | 637 | if (ret == 0) |
| 538 | int ret; | 638 | ret = i915_gem_request_await_dma_fence(to, excl); |
| 539 | |||
| 540 | request = i915_gem_active_peek(&active[idx], | ||
| 541 | &obj->base.dev->struct_mutex); | ||
| 542 | if (!request) | ||
| 543 | continue; | ||
| 544 | 639 | ||
| 545 | ret = i915_gem_request_await_request(to, request); | 640 | dma_fence_put(excl); |
| 546 | if (ret) | ||
| 547 | return ret; | ||
| 548 | } | 641 | } |
| 549 | 642 | ||
| 550 | return 0; | 643 | return ret; |
| 551 | } | 644 | } |
| 552 | 645 | ||
| 553 | static void i915_gem_mark_busy(const struct intel_engine_cs *engine) | 646 | static void i915_gem_mark_busy(const struct intel_engine_cs *engine) |
| 554 | { | 647 | { |
| 555 | struct drm_i915_private *dev_priv = engine->i915; | 648 | struct drm_i915_private *dev_priv = engine->i915; |
| 556 | 649 | ||
| 557 | dev_priv->gt.active_engines |= intel_engine_flag(engine); | ||
| 558 | if (dev_priv->gt.awake) | 650 | if (dev_priv->gt.awake) |
| 559 | return; | 651 | return; |
| 560 | 652 | ||
| @@ -580,11 +672,11 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches) | |||
| 580 | { | 672 | { |
| 581 | struct intel_engine_cs *engine = request->engine; | 673 | struct intel_engine_cs *engine = request->engine; |
| 582 | struct intel_ring *ring = request->ring; | 674 | struct intel_ring *ring = request->ring; |
| 675 | struct intel_timeline *timeline = request->timeline; | ||
| 583 | struct drm_i915_gem_request *prev; | 676 | struct drm_i915_gem_request *prev; |
| 584 | u32 request_start; | 677 | int err; |
| 585 | u32 reserved_tail; | ||
| 586 | int ret; | ||
| 587 | 678 | ||
| 679 | lockdep_assert_held(&request->i915->drm.struct_mutex); | ||
| 588 | trace_i915_gem_request_add(request); | 680 | trace_i915_gem_request_add(request); |
| 589 | 681 | ||
| 590 | /* | 682 | /* |
| @@ -592,8 +684,6 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches) | |||
| 592 | * should already have been reserved in the ring buffer. Let the ring | 684 | * should already have been reserved in the ring buffer. Let the ring |
| 593 | * know that it is time to use that space up. | 685 | * know that it is time to use that space up. |
| 594 | */ | 686 | */ |
| 595 | request_start = ring->tail; | ||
| 596 | reserved_tail = request->reserved_space; | ||
| 597 | request->reserved_space = 0; | 687 | request->reserved_space = 0; |
| 598 | 688 | ||
| 599 | /* | 689 | /* |
| @@ -604,10 +694,10 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches) | |||
| 604 | * what. | 694 | * what. |
| 605 | */ | 695 | */ |
| 606 | if (flush_caches) { | 696 | if (flush_caches) { |
| 607 | ret = engine->emit_flush(request, EMIT_FLUSH); | 697 | err = engine->emit_flush(request, EMIT_FLUSH); |
| 608 | 698 | ||
| 609 | /* Not allowed to fail! */ | 699 | /* Not allowed to fail! */ |
| 610 | WARN(ret, "engine->emit_flush() failed: %d!\n", ret); | 700 | WARN(err, "engine->emit_flush() failed: %d!\n", err); |
| 611 | } | 701 | } |
| 612 | 702 | ||
| 613 | /* Record the position of the start of the breadcrumb so that | 703 | /* Record the position of the start of the breadcrumb so that |
| @@ -615,20 +705,10 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches) | |||
| 615 | * GPU processing the request, we never over-estimate the | 705 | * GPU processing the request, we never over-estimate the |
| 616 | * position of the ring's HEAD. | 706 | * position of the ring's HEAD. |
| 617 | */ | 707 | */ |
| 708 | err = intel_ring_begin(request, engine->emit_breadcrumb_sz); | ||
| 709 | GEM_BUG_ON(err); | ||
| 618 | request->postfix = ring->tail; | 710 | request->postfix = ring->tail; |
| 619 | 711 | ring->tail += engine->emit_breadcrumb_sz * sizeof(u32); | |
| 620 | /* Not allowed to fail! */ | ||
| 621 | ret = engine->emit_request(request); | ||
| 622 | WARN(ret, "(%s)->emit_request failed: %d!\n", engine->name, ret); | ||
| 623 | |||
| 624 | /* Sanity check that the reserved size was large enough. */ | ||
| 625 | ret = ring->tail - request_start; | ||
| 626 | if (ret < 0) | ||
| 627 | ret += ring->size; | ||
| 628 | WARN_ONCE(ret > reserved_tail, | ||
| 629 | "Not enough space reserved (%d bytes) " | ||
| 630 | "for adding the request (%d bytes)\n", | ||
| 631 | reserved_tail, ret); | ||
| 632 | 712 | ||
| 633 | /* Seal the request and mark it as pending execution. Note that | 713 | /* Seal the request and mark it as pending execution. Note that |
| 634 | * we may inspect this state, without holding any locks, during | 714 | * we may inspect this state, without holding any locks, during |
| @@ -636,18 +716,24 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches) | |||
| 636 | * see a more recent value in the hws than we are tracking. | 716 | * see a more recent value in the hws than we are tracking. |
| 637 | */ | 717 | */ |
| 638 | 718 | ||
| 639 | prev = i915_gem_active_raw(&engine->last_request, | 719 | prev = i915_gem_active_raw(&timeline->last_request, |
| 640 | &request->i915->drm.struct_mutex); | 720 | &request->i915->drm.struct_mutex); |
| 641 | if (prev) | 721 | if (prev) |
| 642 | i915_sw_fence_await_sw_fence(&request->submit, &prev->submit, | 722 | i915_sw_fence_await_sw_fence(&request->submit, &prev->submit, |
| 643 | &request->submitq); | 723 | &request->submitq); |
| 644 | 724 | ||
| 645 | request->emitted_jiffies = jiffies; | 725 | spin_lock_irq(&timeline->lock); |
| 646 | request->previous_seqno = engine->last_pending_seqno; | 726 | list_add_tail(&request->link, &timeline->requests); |
| 647 | engine->last_pending_seqno = request->fence.seqno; | 727 | spin_unlock_irq(&timeline->lock); |
| 648 | i915_gem_active_set(&engine->last_request, request); | 728 | |
| 649 | list_add_tail(&request->link, &engine->request_list); | 729 | GEM_BUG_ON(i915_seqno_passed(timeline->last_submitted_seqno, |
| 730 | request->fence.seqno)); | ||
| 731 | |||
| 732 | timeline->last_submitted_seqno = request->fence.seqno; | ||
| 733 | i915_gem_active_set(&timeline->last_request, request); | ||
| 734 | |||
| 650 | list_add_tail(&request->ring_link, &ring->request_list); | 735 | list_add_tail(&request->ring_link, &ring->request_list); |
| 736 | request->emitted_jiffies = jiffies; | ||
| 651 | 737 | ||
| 652 | i915_gem_mark_busy(engine); | 738 | i915_gem_mark_busy(engine); |
| 653 | 739 | ||
| @@ -715,7 +801,7 @@ bool __i915_spin_request(const struct drm_i915_gem_request *req, | |||
| 715 | 801 | ||
| 716 | timeout_us += local_clock_us(&cpu); | 802 | timeout_us += local_clock_us(&cpu); |
| 717 | do { | 803 | do { |
| 718 | if (i915_gem_request_completed(req)) | 804 | if (__i915_gem_request_completed(req)) |
| 719 | return true; | 805 | return true; |
| 720 | 806 | ||
| 721 | if (signal_pending_state(state, current)) | 807 | if (signal_pending_state(state, current)) |
| @@ -730,76 +816,101 @@ bool __i915_spin_request(const struct drm_i915_gem_request *req, | |||
| 730 | return false; | 816 | return false; |
| 731 | } | 817 | } |
| 732 | 818 | ||
| 819 | static long | ||
| 820 | __i915_request_wait_for_submit(struct drm_i915_gem_request *request, | ||
| 821 | unsigned int flags, | ||
| 822 | long timeout) | ||
| 823 | { | ||
| 824 | const int state = flags & I915_WAIT_INTERRUPTIBLE ? | ||
| 825 | TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE; | ||
| 826 | wait_queue_head_t *q = &request->i915->gpu_error.wait_queue; | ||
| 827 | DEFINE_WAIT(reset); | ||
| 828 | DEFINE_WAIT(wait); | ||
| 829 | |||
| 830 | if (flags & I915_WAIT_LOCKED) | ||
| 831 | add_wait_queue(q, &reset); | ||
| 832 | |||
| 833 | do { | ||
| 834 | prepare_to_wait(&request->submit.wait, &wait, state); | ||
| 835 | |||
| 836 | if (i915_sw_fence_done(&request->submit)) | ||
| 837 | break; | ||
| 838 | |||
| 839 | if (flags & I915_WAIT_LOCKED && | ||
| 840 | i915_reset_in_progress(&request->i915->gpu_error)) { | ||
| 841 | __set_current_state(TASK_RUNNING); | ||
| 842 | i915_reset(request->i915); | ||
| 843 | reset_wait_queue(q, &reset); | ||
| 844 | continue; | ||
| 845 | } | ||
| 846 | |||
| 847 | if (signal_pending_state(state, current)) { | ||
| 848 | timeout = -ERESTARTSYS; | ||
| 849 | break; | ||
| 850 | } | ||
| 851 | |||
| 852 | timeout = io_schedule_timeout(timeout); | ||
| 853 | } while (timeout); | ||
| 854 | finish_wait(&request->submit.wait, &wait); | ||
| 855 | |||
| 856 | if (flags & I915_WAIT_LOCKED) | ||
| 857 | remove_wait_queue(q, &reset); | ||
| 858 | |||
| 859 | return timeout; | ||
| 860 | } | ||
| 861 | |||
| 733 | /** | 862 | /** |
| 734 | * i915_wait_request - wait until execution of request has finished | 863 | * i915_wait_request - wait until execution of request has finished |
| 735 | * @req: duh! | 864 | * @req: the request to wait upon |
| 736 | * @flags: how to wait | 865 | * @flags: how to wait |
| 737 | * @timeout: in - how long to wait (NULL forever); out - how much time remaining | 866 | * @timeout: how long to wait in jiffies |
| 738 | * @rps: client to charge for RPS boosting | 867 | * |
| 868 | * i915_wait_request() waits for the request to be completed, for a | ||
| 869 | * maximum of @timeout jiffies (with MAX_SCHEDULE_TIMEOUT implying an | ||
| 870 | * unbounded wait). | ||
| 739 | * | 871 | * |
| 740 | * Note: It is of utmost importance that the passed in seqno and reset_counter | 872 | * If the caller holds the struct_mutex, the caller must pass I915_WAIT_LOCKED |
| 741 | * values have been read by the caller in an smp safe manner. Where read-side | 873 | * in via the flags, and vice versa if the struct_mutex is not held, the caller |
| 742 | * locks are involved, it is sufficient to read the reset_counter before | 874 | * must not specify that the wait is locked. |
| 743 | * unlocking the lock that protects the seqno. For lockless tricks, the | ||
| 744 | * reset_counter _must_ be read before, and an appropriate smp_rmb must be | ||
| 745 | * inserted. | ||
| 746 | * | 875 | * |
| 747 | * Returns 0 if the request was found within the alloted time. Else returns the | 876 | * Returns the remaining time (in jiffies) if the request completed, which may |
| 748 | * errno with remaining time filled in timeout argument. | 877 | * be zero or -ETIME if the request is unfinished after the timeout expires. |
| 878 | * May return -EINTR is called with I915_WAIT_INTERRUPTIBLE and a signal is | ||
| 879 | * pending before the request completes. | ||
| 749 | */ | 880 | */ |
| 750 | int i915_wait_request(struct drm_i915_gem_request *req, | 881 | long i915_wait_request(struct drm_i915_gem_request *req, |
| 751 | unsigned int flags, | 882 | unsigned int flags, |
| 752 | s64 *timeout, | 883 | long timeout) |
| 753 | struct intel_rps_client *rps) | ||
| 754 | { | 884 | { |
| 755 | const int state = flags & I915_WAIT_INTERRUPTIBLE ? | 885 | const int state = flags & I915_WAIT_INTERRUPTIBLE ? |
| 756 | TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE; | 886 | TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE; |
| 757 | DEFINE_WAIT(reset); | 887 | DEFINE_WAIT(reset); |
| 758 | struct intel_wait wait; | 888 | struct intel_wait wait; |
| 759 | unsigned long timeout_remain; | ||
| 760 | int ret = 0; | ||
| 761 | 889 | ||
| 762 | might_sleep(); | 890 | might_sleep(); |
| 763 | #if IS_ENABLED(CONFIG_LOCKDEP) | 891 | #if IS_ENABLED(CONFIG_LOCKDEP) |
| 764 | GEM_BUG_ON(!!lockdep_is_held(&req->i915->drm.struct_mutex) != | 892 | GEM_BUG_ON(debug_locks && |
| 893 | !!lockdep_is_held(&req->i915->drm.struct_mutex) != | ||
| 765 | !!(flags & I915_WAIT_LOCKED)); | 894 | !!(flags & I915_WAIT_LOCKED)); |
| 766 | #endif | 895 | #endif |
| 896 | GEM_BUG_ON(timeout < 0); | ||
| 767 | 897 | ||
| 768 | if (i915_gem_request_completed(req)) | 898 | if (i915_gem_request_completed(req)) |
| 769 | return 0; | 899 | return timeout; |
| 770 | 900 | ||
| 771 | timeout_remain = MAX_SCHEDULE_TIMEOUT; | 901 | if (!timeout) |
| 772 | if (timeout) { | 902 | return -ETIME; |
| 773 | if (WARN_ON(*timeout < 0)) | ||
| 774 | return -EINVAL; | ||
| 775 | |||
| 776 | if (*timeout == 0) | ||
| 777 | return -ETIME; | ||
| 778 | |||
| 779 | /* Record current time in case interrupted, or wedged */ | ||
| 780 | timeout_remain = nsecs_to_jiffies_timeout(*timeout); | ||
| 781 | *timeout += ktime_get_raw_ns(); | ||
| 782 | } | ||
| 783 | 903 | ||
| 784 | trace_i915_gem_request_wait_begin(req); | 904 | trace_i915_gem_request_wait_begin(req); |
| 785 | 905 | ||
| 786 | /* This client is about to stall waiting for the GPU. In many cases | 906 | if (!i915_sw_fence_done(&req->submit)) { |
| 787 | * this is undesirable and limits the throughput of the system, as | 907 | timeout = __i915_request_wait_for_submit(req, flags, timeout); |
| 788 | * many clients cannot continue processing user input/output whilst | 908 | if (timeout < 0) |
| 789 | * blocked. RPS autotuning may take tens of milliseconds to respond | 909 | goto complete; |
| 790 | * to the GPU load and thus incurs additional latency for the client. | 910 | |
| 791 | * We can circumvent that by promoting the GPU frequency to maximum | 911 | GEM_BUG_ON(!i915_sw_fence_done(&req->submit)); |
| 792 | * before we wait. This makes the GPU throttle up much more quickly | 912 | } |
| 793 | * (good for benchmarks and user experience, e.g. window animations), | 913 | GEM_BUG_ON(!req->global_seqno); |
| 794 | * but at a cost of spending more power processing the workload | ||
| 795 | * (bad for battery). Not all clients even want their results | ||
| 796 | * immediately and for them we should just let the GPU select its own | ||
| 797 | * frequency to maximise efficiency. To prevent a single client from | ||
| 798 | * forcing the clocks too high for the whole system, we only allow | ||
| 799 | * each client to waitboost once in a busy period. | ||
| 800 | */ | ||
| 801 | if (IS_RPS_CLIENT(rps) && INTEL_GEN(req->i915) >= 6) | ||
| 802 | gen6_rps_boost(req->i915, rps, req->emitted_jiffies); | ||
| 803 | 914 | ||
| 804 | /* Optimistic short spin before touching IRQs */ | 915 | /* Optimistic short spin before touching IRQs */ |
| 805 | if (i915_spin_request(req, state, 5)) | 916 | if (i915_spin_request(req, state, 5)) |
| @@ -809,7 +920,7 @@ int i915_wait_request(struct drm_i915_gem_request *req, | |||
| 809 | if (flags & I915_WAIT_LOCKED) | 920 | if (flags & I915_WAIT_LOCKED) |
| 810 | add_wait_queue(&req->i915->gpu_error.wait_queue, &reset); | 921 | add_wait_queue(&req->i915->gpu_error.wait_queue, &reset); |
| 811 | 922 | ||
| 812 | intel_wait_init(&wait, req->fence.seqno); | 923 | intel_wait_init(&wait, req->global_seqno); |
| 813 | if (intel_engine_add_wait(req->engine, &wait)) | 924 | if (intel_engine_add_wait(req->engine, &wait)) |
| 814 | /* In order to check that we haven't missed the interrupt | 925 | /* In order to check that we haven't missed the interrupt |
| 815 | * as we enabled it, we need to kick ourselves to do a | 926 | * as we enabled it, we need to kick ourselves to do a |
| @@ -819,16 +930,17 @@ int i915_wait_request(struct drm_i915_gem_request *req, | |||
| 819 | 930 | ||
| 820 | for (;;) { | 931 | for (;;) { |
| 821 | if (signal_pending_state(state, current)) { | 932 | if (signal_pending_state(state, current)) { |
| 822 | ret = -ERESTARTSYS; | 933 | timeout = -ERESTARTSYS; |
| 823 | break; | 934 | break; |
| 824 | } | 935 | } |
| 825 | 936 | ||
| 826 | timeout_remain = io_schedule_timeout(timeout_remain); | 937 | if (!timeout) { |
| 827 | if (timeout_remain == 0) { | 938 | timeout = -ETIME; |
| 828 | ret = -ETIME; | ||
| 829 | break; | 939 | break; |
| 830 | } | 940 | } |
| 831 | 941 | ||
| 942 | timeout = io_schedule_timeout(timeout); | ||
| 943 | |||
| 832 | if (intel_wait_complete(&wait)) | 944 | if (intel_wait_complete(&wait)) |
| 833 | break; | 945 | break; |
| 834 | 946 | ||
| @@ -875,74 +987,39 @@ wakeup: | |||
| 875 | complete: | 987 | complete: |
| 876 | trace_i915_gem_request_wait_end(req); | 988 | trace_i915_gem_request_wait_end(req); |
| 877 | 989 | ||
| 878 | if (timeout) { | 990 | return timeout; |
| 879 | *timeout -= ktime_get_raw_ns(); | ||
| 880 | if (*timeout < 0) | ||
| 881 | *timeout = 0; | ||
| 882 | |||
| 883 | /* | ||
| 884 | * Apparently ktime isn't accurate enough and occasionally has a | ||
| 885 | * bit of mismatch in the jiffies<->nsecs<->ktime loop. So patch | ||
| 886 | * things up to make the test happy. We allow up to 1 jiffy. | ||
| 887 | * | ||
| 888 | * This is a regrssion from the timespec->ktime conversion. | ||
| 889 | */ | ||
| 890 | if (ret == -ETIME && *timeout < jiffies_to_usecs(1)*1000) | ||
| 891 | *timeout = 0; | ||
| 892 | } | ||
| 893 | |||
| 894 | if (IS_RPS_USER(rps) && | ||
| 895 | req->fence.seqno == req->engine->last_submitted_seqno) { | ||
| 896 | /* The GPU is now idle and this client has stalled. | ||
| 897 | * Since no other client has submitted a request in the | ||
| 898 | * meantime, assume that this client is the only one | ||
| 899 | * supplying work to the GPU but is unable to keep that | ||
| 900 | * work supplied because it is waiting. Since the GPU is | ||
| 901 | * then never kept fully busy, RPS autoclocking will | ||
| 902 | * keep the clocks relatively low, causing further delays. | ||
| 903 | * Compensate by giving the synchronous client credit for | ||
| 904 | * a waitboost next time. | ||
| 905 | */ | ||
| 906 | spin_lock(&req->i915->rps.client_lock); | ||
| 907 | list_del_init(&rps->link); | ||
| 908 | spin_unlock(&req->i915->rps.client_lock); | ||
| 909 | } | ||
| 910 | |||
| 911 | return ret; | ||
| 912 | } | 991 | } |
| 913 | 992 | ||
| 914 | static bool engine_retire_requests(struct intel_engine_cs *engine) | 993 | static void engine_retire_requests(struct intel_engine_cs *engine) |
| 915 | { | 994 | { |
| 916 | struct drm_i915_gem_request *request, *next; | 995 | struct drm_i915_gem_request *request, *next; |
| 917 | 996 | ||
| 918 | list_for_each_entry_safe(request, next, &engine->request_list, link) { | 997 | list_for_each_entry_safe(request, next, |
| 919 | if (!i915_gem_request_completed(request)) | 998 | &engine->timeline->requests, link) { |
| 920 | return false; | 999 | if (!__i915_gem_request_completed(request)) |
| 1000 | return; | ||
| 921 | 1001 | ||
| 922 | i915_gem_request_retire(request); | 1002 | i915_gem_request_retire(request); |
| 923 | } | 1003 | } |
| 924 | |||
| 925 | return true; | ||
| 926 | } | 1004 | } |
| 927 | 1005 | ||
| 928 | void i915_gem_retire_requests(struct drm_i915_private *dev_priv) | 1006 | void i915_gem_retire_requests(struct drm_i915_private *dev_priv) |
| 929 | { | 1007 | { |
| 930 | struct intel_engine_cs *engine; | 1008 | struct intel_engine_cs *engine; |
| 931 | unsigned int tmp; | 1009 | enum intel_engine_id id; |
| 932 | 1010 | ||
| 933 | lockdep_assert_held(&dev_priv->drm.struct_mutex); | 1011 | lockdep_assert_held(&dev_priv->drm.struct_mutex); |
| 934 | 1012 | ||
| 935 | if (dev_priv->gt.active_engines == 0) | 1013 | if (!dev_priv->gt.active_requests) |
| 936 | return; | 1014 | return; |
| 937 | 1015 | ||
| 938 | GEM_BUG_ON(!dev_priv->gt.awake); | 1016 | GEM_BUG_ON(!dev_priv->gt.awake); |
| 939 | 1017 | ||
| 940 | for_each_engine_masked(engine, dev_priv, dev_priv->gt.active_engines, tmp) | 1018 | for_each_engine(engine, dev_priv, id) |
| 941 | if (engine_retire_requests(engine)) | 1019 | engine_retire_requests(engine); |
| 942 | dev_priv->gt.active_engines &= ~intel_engine_flag(engine); | ||
| 943 | 1020 | ||
| 944 | if (dev_priv->gt.active_engines == 0) | 1021 | if (!dev_priv->gt.active_requests) |
| 945 | queue_delayed_work(dev_priv->wq, | 1022 | mod_delayed_work(dev_priv->wq, |
| 946 | &dev_priv->gt.idle_work, | 1023 | &dev_priv->gt.idle_work, |
| 947 | msecs_to_jiffies(100)); | 1024 | msecs_to_jiffies(100)); |
| 948 | } | 1025 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h index bceeaa3a5193..75f8360b3421 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.h +++ b/drivers/gpu/drm/i915/i915_gem_request.h | |||
| @@ -81,11 +81,14 @@ struct drm_i915_gem_request { | |||
| 81 | struct i915_gem_context *ctx; | 81 | struct i915_gem_context *ctx; |
| 82 | struct intel_engine_cs *engine; | 82 | struct intel_engine_cs *engine; |
| 83 | struct intel_ring *ring; | 83 | struct intel_ring *ring; |
| 84 | struct intel_timeline *timeline; | ||
| 84 | struct intel_signal_node signaling; | 85 | struct intel_signal_node signaling; |
| 85 | 86 | ||
| 86 | struct i915_sw_fence submit; | 87 | struct i915_sw_fence submit; |
| 87 | wait_queue_t submitq; | 88 | wait_queue_t submitq; |
| 88 | 89 | ||
| 90 | u32 global_seqno; | ||
| 91 | |||
| 89 | /** GEM sequence number associated with the previous request, | 92 | /** GEM sequence number associated with the previous request, |
| 90 | * when the HWS breadcrumb is equal to this the GPU is processing | 93 | * when the HWS breadcrumb is equal to this the GPU is processing |
| 91 | * this request. | 94 | * this request. |
| @@ -147,7 +150,7 @@ struct drm_i915_gem_request { | |||
| 147 | 150 | ||
| 148 | extern const struct dma_fence_ops i915_fence_ops; | 151 | extern const struct dma_fence_ops i915_fence_ops; |
| 149 | 152 | ||
| 150 | static inline bool fence_is_i915(struct dma_fence *fence) | 153 | static inline bool dma_fence_is_i915(const struct dma_fence *fence) |
| 151 | { | 154 | { |
| 152 | return fence->ops == &i915_fence_ops; | 155 | return fence->ops == &i915_fence_ops; |
| 153 | } | 156 | } |
| @@ -162,7 +165,7 @@ void i915_gem_request_retire_upto(struct drm_i915_gem_request *req); | |||
| 162 | static inline u32 | 165 | static inline u32 |
| 163 | i915_gem_request_get_seqno(struct drm_i915_gem_request *req) | 166 | i915_gem_request_get_seqno(struct drm_i915_gem_request *req) |
| 164 | { | 167 | { |
| 165 | return req ? req->fence.seqno : 0; | 168 | return req ? req->global_seqno : 0; |
| 166 | } | 169 | } |
| 167 | 170 | ||
| 168 | static inline struct intel_engine_cs * | 171 | static inline struct intel_engine_cs * |
| @@ -176,7 +179,7 @@ to_request(struct dma_fence *fence) | |||
| 176 | { | 179 | { |
| 177 | /* We assume that NULL fence/request are interoperable */ | 180 | /* We assume that NULL fence/request are interoperable */ |
| 178 | BUILD_BUG_ON(offsetof(struct drm_i915_gem_request, fence) != 0); | 181 | BUILD_BUG_ON(offsetof(struct drm_i915_gem_request, fence) != 0); |
| 179 | GEM_BUG_ON(fence && !fence_is_i915(fence)); | 182 | GEM_BUG_ON(fence && !dma_fence_is_i915(fence)); |
| 180 | return container_of(fence, struct drm_i915_gem_request, fence); | 183 | return container_of(fence, struct drm_i915_gem_request, fence); |
| 181 | } | 184 | } |
| 182 | 185 | ||
| @@ -214,6 +217,8 @@ int | |||
| 214 | i915_gem_request_await_object(struct drm_i915_gem_request *to, | 217 | i915_gem_request_await_object(struct drm_i915_gem_request *to, |
| 215 | struct drm_i915_gem_object *obj, | 218 | struct drm_i915_gem_object *obj, |
| 216 | bool write); | 219 | bool write); |
| 220 | int i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req, | ||
| 221 | struct dma_fence *fence); | ||
| 217 | 222 | ||
| 218 | void __i915_add_request(struct drm_i915_gem_request *req, bool flush_caches); | 223 | void __i915_add_request(struct drm_i915_gem_request *req, bool flush_caches); |
| 219 | #define i915_add_request(req) \ | 224 | #define i915_add_request(req) \ |
| @@ -226,13 +231,13 @@ struct intel_rps_client; | |||
| 226 | #define IS_RPS_CLIENT(p) (!IS_ERR(p)) | 231 | #define IS_RPS_CLIENT(p) (!IS_ERR(p)) |
| 227 | #define IS_RPS_USER(p) (!IS_ERR_OR_NULL(p)) | 232 | #define IS_RPS_USER(p) (!IS_ERR_OR_NULL(p)) |
| 228 | 233 | ||
| 229 | int i915_wait_request(struct drm_i915_gem_request *req, | 234 | long i915_wait_request(struct drm_i915_gem_request *req, |
| 230 | unsigned int flags, | 235 | unsigned int flags, |
| 231 | s64 *timeout, | 236 | long timeout) |
| 232 | struct intel_rps_client *rps) | ||
| 233 | __attribute__((nonnull(1))); | 237 | __attribute__((nonnull(1))); |
| 234 | #define I915_WAIT_INTERRUPTIBLE BIT(0) | 238 | #define I915_WAIT_INTERRUPTIBLE BIT(0) |
| 235 | #define I915_WAIT_LOCKED BIT(1) /* struct_mutex held, handle GPU reset */ | 239 | #define I915_WAIT_LOCKED BIT(1) /* struct_mutex held, handle GPU reset */ |
| 240 | #define I915_WAIT_ALL BIT(2) /* used by i915_gem_object_wait() */ | ||
| 236 | 241 | ||
| 237 | static inline u32 intel_engine_get_seqno(struct intel_engine_cs *engine); | 242 | static inline u32 intel_engine_get_seqno(struct intel_engine_cs *engine); |
| 238 | 243 | ||
| @@ -245,17 +250,37 @@ static inline bool i915_seqno_passed(u32 seq1, u32 seq2) | |||
| 245 | } | 250 | } |
| 246 | 251 | ||
| 247 | static inline bool | 252 | static inline bool |
| 248 | i915_gem_request_started(const struct drm_i915_gem_request *req) | 253 | __i915_gem_request_started(const struct drm_i915_gem_request *req) |
| 249 | { | 254 | { |
| 255 | GEM_BUG_ON(!req->global_seqno); | ||
| 250 | return i915_seqno_passed(intel_engine_get_seqno(req->engine), | 256 | return i915_seqno_passed(intel_engine_get_seqno(req->engine), |
| 251 | req->previous_seqno); | 257 | req->previous_seqno); |
| 252 | } | 258 | } |
| 253 | 259 | ||
| 254 | static inline bool | 260 | static inline bool |
| 255 | i915_gem_request_completed(const struct drm_i915_gem_request *req) | 261 | i915_gem_request_started(const struct drm_i915_gem_request *req) |
| 262 | { | ||
| 263 | if (!req->global_seqno) | ||
| 264 | return false; | ||
| 265 | |||
| 266 | return __i915_gem_request_started(req); | ||
| 267 | } | ||
| 268 | |||
| 269 | static inline bool | ||
| 270 | __i915_gem_request_completed(const struct drm_i915_gem_request *req) | ||
| 256 | { | 271 | { |
| 272 | GEM_BUG_ON(!req->global_seqno); | ||
| 257 | return i915_seqno_passed(intel_engine_get_seqno(req->engine), | 273 | return i915_seqno_passed(intel_engine_get_seqno(req->engine), |
| 258 | req->fence.seqno); | 274 | req->global_seqno); |
| 275 | } | ||
| 276 | |||
| 277 | static inline bool | ||
| 278 | i915_gem_request_completed(const struct drm_i915_gem_request *req) | ||
| 279 | { | ||
| 280 | if (!req->global_seqno) | ||
| 281 | return false; | ||
| 282 | |||
| 283 | return __i915_gem_request_completed(req); | ||
| 259 | } | 284 | } |
| 260 | 285 | ||
| 261 | bool __i915_spin_request(const struct drm_i915_gem_request *request, | 286 | bool __i915_spin_request(const struct drm_i915_gem_request *request, |
| @@ -263,7 +288,7 @@ bool __i915_spin_request(const struct drm_i915_gem_request *request, | |||
| 263 | static inline bool i915_spin_request(const struct drm_i915_gem_request *request, | 288 | static inline bool i915_spin_request(const struct drm_i915_gem_request *request, |
| 264 | int state, unsigned long timeout_us) | 289 | int state, unsigned long timeout_us) |
| 265 | { | 290 | { |
| 266 | return (i915_gem_request_started(request) && | 291 | return (__i915_gem_request_started(request) && |
| 267 | __i915_spin_request(request, state, timeout_us)); | 292 | __i915_spin_request(request, state, timeout_us)); |
| 268 | } | 293 | } |
| 269 | 294 | ||
| @@ -552,53 +577,13 @@ i915_gem_active_isset(const struct i915_gem_active *active) | |||
| 552 | } | 577 | } |
| 553 | 578 | ||
| 554 | /** | 579 | /** |
| 555 | * i915_gem_active_is_idle - report whether the active tracker is idle | ||
| 556 | * @active - the active tracker | ||
| 557 | * | ||
| 558 | * i915_gem_active_is_idle() returns true if the active tracker is currently | ||
| 559 | * unassigned or if the request is complete (but not yet retired). Requires | ||
| 560 | * the caller to hold struct_mutex (but that can be relaxed if desired). | ||
| 561 | */ | ||
| 562 | static inline bool | ||
| 563 | i915_gem_active_is_idle(const struct i915_gem_active *active, | ||
| 564 | struct mutex *mutex) | ||
| 565 | { | ||
| 566 | return !i915_gem_active_peek(active, mutex); | ||
| 567 | } | ||
| 568 | |||
| 569 | /** | ||
| 570 | * i915_gem_active_wait - waits until the request is completed | 580 | * i915_gem_active_wait - waits until the request is completed |
| 571 | * @active - the active request on which to wait | 581 | * @active - the active request on which to wait |
| 572 | * | ||
| 573 | * i915_gem_active_wait() waits until the request is completed before | ||
| 574 | * returning. Note that it does not guarantee that the request is | ||
| 575 | * retired first, see i915_gem_active_retire(). | ||
| 576 | * | ||
| 577 | * i915_gem_active_wait() returns immediately if the active | ||
| 578 | * request is already complete. | ||
| 579 | */ | ||
| 580 | static inline int __must_check | ||
| 581 | i915_gem_active_wait(const struct i915_gem_active *active, struct mutex *mutex) | ||
| 582 | { | ||
| 583 | struct drm_i915_gem_request *request; | ||
| 584 | |||
| 585 | request = i915_gem_active_peek(active, mutex); | ||
| 586 | if (!request) | ||
| 587 | return 0; | ||
| 588 | |||
| 589 | return i915_wait_request(request, | ||
| 590 | I915_WAIT_INTERRUPTIBLE | I915_WAIT_LOCKED, | ||
| 591 | NULL, NULL); | ||
| 592 | } | ||
| 593 | |||
| 594 | /** | ||
| 595 | * i915_gem_active_wait_unlocked - waits until the request is completed | ||
| 596 | * @active - the active request on which to wait | ||
| 597 | * @flags - how to wait | 582 | * @flags - how to wait |
| 598 | * @timeout - how long to wait at most | 583 | * @timeout - how long to wait at most |
| 599 | * @rps - userspace client to charge for a waitboost | 584 | * @rps - userspace client to charge for a waitboost |
| 600 | * | 585 | * |
| 601 | * i915_gem_active_wait_unlocked() waits until the request is completed before | 586 | * i915_gem_active_wait() waits until the request is completed before |
| 602 | * returning, without requiring any locks to be held. Note that it does not | 587 | * returning, without requiring any locks to be held. Note that it does not |
| 603 | * retire any requests before returning. | 588 | * retire any requests before returning. |
| 604 | * | 589 | * |
| @@ -614,21 +599,18 @@ i915_gem_active_wait(const struct i915_gem_active *active, struct mutex *mutex) | |||
| 614 | * Returns 0 if successful, or a negative error code. | 599 | * Returns 0 if successful, or a negative error code. |
| 615 | */ | 600 | */ |
| 616 | static inline int | 601 | static inline int |
| 617 | i915_gem_active_wait_unlocked(const struct i915_gem_active *active, | 602 | i915_gem_active_wait(const struct i915_gem_active *active, unsigned int flags) |
| 618 | unsigned int flags, | ||
| 619 | s64 *timeout, | ||
| 620 | struct intel_rps_client *rps) | ||
| 621 | { | 603 | { |
| 622 | struct drm_i915_gem_request *request; | 604 | struct drm_i915_gem_request *request; |
| 623 | int ret = 0; | 605 | long ret = 0; |
| 624 | 606 | ||
| 625 | request = i915_gem_active_get_unlocked(active); | 607 | request = i915_gem_active_get_unlocked(active); |
| 626 | if (request) { | 608 | if (request) { |
| 627 | ret = i915_wait_request(request, flags, timeout, rps); | 609 | ret = i915_wait_request(request, flags, MAX_SCHEDULE_TIMEOUT); |
| 628 | i915_gem_request_put(request); | 610 | i915_gem_request_put(request); |
| 629 | } | 611 | } |
| 630 | 612 | ||
| 631 | return ret; | 613 | return ret < 0 ? ret : 0; |
| 632 | } | 614 | } |
| 633 | 615 | ||
| 634 | /** | 616 | /** |
| @@ -645,7 +627,7 @@ i915_gem_active_retire(struct i915_gem_active *active, | |||
| 645 | struct mutex *mutex) | 627 | struct mutex *mutex) |
| 646 | { | 628 | { |
| 647 | struct drm_i915_gem_request *request; | 629 | struct drm_i915_gem_request *request; |
| 648 | int ret; | 630 | long ret; |
| 649 | 631 | ||
| 650 | request = i915_gem_active_raw(active, mutex); | 632 | request = i915_gem_active_raw(active, mutex); |
| 651 | if (!request) | 633 | if (!request) |
| @@ -653,8 +635,8 @@ i915_gem_active_retire(struct i915_gem_active *active, | |||
| 653 | 635 | ||
| 654 | ret = i915_wait_request(request, | 636 | ret = i915_wait_request(request, |
| 655 | I915_WAIT_INTERRUPTIBLE | I915_WAIT_LOCKED, | 637 | I915_WAIT_INTERRUPTIBLE | I915_WAIT_LOCKED, |
| 656 | NULL, NULL); | 638 | MAX_SCHEDULE_TIMEOUT); |
| 657 | if (ret) | 639 | if (ret < 0) |
| 658 | return ret; | 640 | return ret; |
| 659 | 641 | ||
| 660 | list_del_init(&active->link); | 642 | list_del_init(&active->link); |
| @@ -665,24 +647,6 @@ i915_gem_active_retire(struct i915_gem_active *active, | |||
| 665 | return 0; | 647 | return 0; |
| 666 | } | 648 | } |
| 667 | 649 | ||
| 668 | /* Convenience functions for peeking at state inside active's request whilst | ||
| 669 | * guarded by the struct_mutex. | ||
| 670 | */ | ||
| 671 | |||
| 672 | static inline uint32_t | ||
| 673 | i915_gem_active_get_seqno(const struct i915_gem_active *active, | ||
| 674 | struct mutex *mutex) | ||
| 675 | { | ||
| 676 | return i915_gem_request_get_seqno(i915_gem_active_peek(active, mutex)); | ||
| 677 | } | ||
| 678 | |||
| 679 | static inline struct intel_engine_cs * | ||
| 680 | i915_gem_active_get_engine(const struct i915_gem_active *active, | ||
| 681 | struct mutex *mutex) | ||
| 682 | { | ||
| 683 | return i915_gem_request_get_engine(i915_gem_active_peek(active, mutex)); | ||
| 684 | } | ||
| 685 | |||
| 686 | #define for_each_active(mask, idx) \ | 650 | #define for_each_active(mask, idx) \ |
| 687 | for (; mask ? idx = ffs(mask) - 1, 1 : 0; mask &= ~BIT(idx)) | 651 | for (; mask ? idx = ffs(mask) - 1, 1 : 0; mask &= ~BIT(idx)) |
| 688 | 652 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index de25b6e0a101..a6fc1bdc48af 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c | |||
| @@ -48,6 +48,20 @@ static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task) | |||
| 48 | #endif | 48 | #endif |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | static bool i915_gem_shrinker_lock(struct drm_device *dev, bool *unlock) | ||
| 52 | { | ||
| 53 | if (!mutex_trylock(&dev->struct_mutex)) { | ||
| 54 | if (!mutex_is_locked_by(&dev->struct_mutex, current)) | ||
| 55 | return false; | ||
| 56 | |||
| 57 | *unlock = false; | ||
| 58 | } else { | ||
| 59 | *unlock = true; | ||
| 60 | } | ||
| 61 | |||
| 62 | return true; | ||
| 63 | } | ||
| 64 | |||
| 51 | static bool any_vma_pinned(struct drm_i915_gem_object *obj) | 65 | static bool any_vma_pinned(struct drm_i915_gem_object *obj) |
| 52 | { | 66 | { |
| 53 | struct i915_vma *vma; | 67 | struct i915_vma *vma; |
| @@ -66,8 +80,11 @@ static bool swap_available(void) | |||
| 66 | 80 | ||
| 67 | static bool can_release_pages(struct drm_i915_gem_object *obj) | 81 | static bool can_release_pages(struct drm_i915_gem_object *obj) |
| 68 | { | 82 | { |
| 69 | /* Only shmemfs objects are backed by swap */ | 83 | if (!obj->mm.pages) |
| 70 | if (!obj->base.filp) | 84 | return false; |
| 85 | |||
| 86 | /* Consider only shrinkable ojects. */ | ||
| 87 | if (!i915_gem_object_is_shrinkable(obj)) | ||
| 71 | return false; | 88 | return false; |
| 72 | 89 | ||
| 73 | /* Only report true if by unbinding the object and putting its pages | 90 | /* Only report true if by unbinding the object and putting its pages |
| @@ -78,7 +95,7 @@ static bool can_release_pages(struct drm_i915_gem_object *obj) | |||
| 78 | * to the GPU, simply unbinding from the GPU is not going to succeed | 95 | * to the GPU, simply unbinding from the GPU is not going to succeed |
| 79 | * in releasing our pin count on the pages themselves. | 96 | * in releasing our pin count on the pages themselves. |
| 80 | */ | 97 | */ |
| 81 | if (obj->pages_pin_count > obj->bind_count) | 98 | if (atomic_read(&obj->mm.pages_pin_count) > obj->bind_count) |
| 82 | return false; | 99 | return false; |
| 83 | 100 | ||
| 84 | if (any_vma_pinned(obj)) | 101 | if (any_vma_pinned(obj)) |
| @@ -88,7 +105,14 @@ static bool can_release_pages(struct drm_i915_gem_object *obj) | |||
| 88 | * discard the contents (because the user has marked them as being | 105 | * discard the contents (because the user has marked them as being |
| 89 | * purgeable) or if we can move their contents out to swap. | 106 | * purgeable) or if we can move their contents out to swap. |
| 90 | */ | 107 | */ |
| 91 | return swap_available() || obj->madv == I915_MADV_DONTNEED; | 108 | return swap_available() || obj->mm.madv == I915_MADV_DONTNEED; |
| 109 | } | ||
| 110 | |||
| 111 | static bool unsafe_drop_pages(struct drm_i915_gem_object *obj) | ||
| 112 | { | ||
| 113 | if (i915_gem_object_unbind(obj) == 0) | ||
| 114 | __i915_gem_object_put_pages(obj, I915_MM_SHRINKER); | ||
| 115 | return !READ_ONCE(obj->mm.pages); | ||
| 92 | } | 116 | } |
| 93 | 117 | ||
| 94 | /** | 118 | /** |
| @@ -128,6 +152,10 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, | |||
| 128 | { NULL, 0 }, | 152 | { NULL, 0 }, |
| 129 | }, *phase; | 153 | }, *phase; |
| 130 | unsigned long count = 0; | 154 | unsigned long count = 0; |
| 155 | bool unlock; | ||
| 156 | |||
| 157 | if (!i915_gem_shrinker_lock(&dev_priv->drm, &unlock)) | ||
| 158 | return 0; | ||
| 131 | 159 | ||
| 132 | trace_i915_gem_shrink(dev_priv, target, flags); | 160 | trace_i915_gem_shrink(dev_priv, target, flags); |
| 133 | i915_gem_retire_requests(dev_priv); | 161 | i915_gem_retire_requests(dev_priv); |
| @@ -171,15 +199,19 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, | |||
| 171 | while (count < target && | 199 | while (count < target && |
| 172 | (obj = list_first_entry_or_null(phase->list, | 200 | (obj = list_first_entry_or_null(phase->list, |
| 173 | typeof(*obj), | 201 | typeof(*obj), |
| 174 | global_list))) { | 202 | global_link))) { |
| 175 | list_move_tail(&obj->global_list, &still_in_list); | 203 | list_move_tail(&obj->global_link, &still_in_list); |
| 204 | if (!obj->mm.pages) { | ||
| 205 | list_del_init(&obj->global_link); | ||
| 206 | continue; | ||
| 207 | } | ||
| 176 | 208 | ||
| 177 | if (flags & I915_SHRINK_PURGEABLE && | 209 | if (flags & I915_SHRINK_PURGEABLE && |
| 178 | obj->madv != I915_MADV_DONTNEED) | 210 | obj->mm.madv != I915_MADV_DONTNEED) |
| 179 | continue; | 211 | continue; |
| 180 | 212 | ||
| 181 | if (flags & I915_SHRINK_VMAPS && | 213 | if (flags & I915_SHRINK_VMAPS && |
| 182 | !is_vmalloc_addr(obj->mapping)) | 214 | !is_vmalloc_addr(obj->mm.mapping)) |
| 183 | continue; | 215 | continue; |
| 184 | 216 | ||
| 185 | if (!(flags & I915_SHRINK_ACTIVE) && | 217 | if (!(flags & I915_SHRINK_ACTIVE) && |
| @@ -190,22 +222,28 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, | |||
| 190 | if (!can_release_pages(obj)) | 222 | if (!can_release_pages(obj)) |
| 191 | continue; | 223 | continue; |
| 192 | 224 | ||
| 193 | i915_gem_object_get(obj); | 225 | if (unsafe_drop_pages(obj)) { |
| 194 | 226 | /* May arrive from get_pages on another bo */ | |
| 195 | /* For the unbound phase, this should be a no-op! */ | 227 | mutex_lock_nested(&obj->mm.lock, |
| 196 | i915_gem_object_unbind(obj); | 228 | I915_MM_SHRINKER); |
| 197 | if (i915_gem_object_put_pages(obj) == 0) | 229 | if (!obj->mm.pages) { |
| 198 | count += obj->base.size >> PAGE_SHIFT; | 230 | __i915_gem_object_invalidate(obj); |
| 199 | 231 | list_del_init(&obj->global_link); | |
| 200 | i915_gem_object_put(obj); | 232 | count += obj->base.size >> PAGE_SHIFT; |
| 233 | } | ||
| 234 | mutex_unlock(&obj->mm.lock); | ||
| 235 | } | ||
| 201 | } | 236 | } |
| 202 | list_splice(&still_in_list, phase->list); | 237 | list_splice_tail(&still_in_list, phase->list); |
| 203 | } | 238 | } |
| 204 | 239 | ||
| 205 | if (flags & I915_SHRINK_BOUND) | 240 | if (flags & I915_SHRINK_BOUND) |
| 206 | intel_runtime_pm_put(dev_priv); | 241 | intel_runtime_pm_put(dev_priv); |
| 207 | 242 | ||
| 208 | i915_gem_retire_requests(dev_priv); | 243 | i915_gem_retire_requests(dev_priv); |
| 244 | if (unlock) | ||
| 245 | mutex_unlock(&dev_priv->drm.struct_mutex); | ||
| 246 | |||
| 209 | /* expedite the RCU grace period to free some request slabs */ | 247 | /* expedite the RCU grace period to free some request slabs */ |
| 210 | synchronize_rcu_expedited(); | 248 | synchronize_rcu_expedited(); |
| 211 | 249 | ||
| @@ -239,19 +277,6 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv) | |||
| 239 | return freed; | 277 | return freed; |
| 240 | } | 278 | } |
| 241 | 279 | ||
| 242 | static bool i915_gem_shrinker_lock(struct drm_device *dev, bool *unlock) | ||
| 243 | { | ||
| 244 | if (!mutex_trylock(&dev->struct_mutex)) { | ||
| 245 | if (!mutex_is_locked_by(&dev->struct_mutex, current)) | ||
| 246 | return false; | ||
| 247 | |||
| 248 | *unlock = false; | ||
| 249 | } else | ||
| 250 | *unlock = true; | ||
| 251 | |||
| 252 | return true; | ||
| 253 | } | ||
| 254 | |||
| 255 | static unsigned long | 280 | static unsigned long |
| 256 | i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) | 281 | i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) |
| 257 | { | 282 | { |
| @@ -268,11 +293,11 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) | |||
| 268 | i915_gem_retire_requests(dev_priv); | 293 | i915_gem_retire_requests(dev_priv); |
| 269 | 294 | ||
| 270 | count = 0; | 295 | count = 0; |
| 271 | list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) | 296 | list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_link) |
| 272 | if (can_release_pages(obj)) | 297 | if (can_release_pages(obj)) |
| 273 | count += obj->base.size >> PAGE_SHIFT; | 298 | count += obj->base.size >> PAGE_SHIFT; |
| 274 | 299 | ||
| 275 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { | 300 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_link) { |
| 276 | if (!i915_gem_object_is_active(obj) && can_release_pages(obj)) | 301 | if (!i915_gem_object_is_active(obj) && can_release_pages(obj)) |
| 277 | count += obj->base.size >> PAGE_SHIFT; | 302 | count += obj->base.size >> PAGE_SHIFT; |
| 278 | } | 303 | } |
| @@ -373,13 +398,19 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr) | |||
| 373 | * being pointed to by hardware. | 398 | * being pointed to by hardware. |
| 374 | */ | 399 | */ |
| 375 | unbound = bound = unevictable = 0; | 400 | unbound = bound = unevictable = 0; |
| 376 | list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) { | 401 | list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_link) { |
| 402 | if (!obj->mm.pages) | ||
| 403 | continue; | ||
| 404 | |||
| 377 | if (!can_release_pages(obj)) | 405 | if (!can_release_pages(obj)) |
| 378 | unevictable += obj->base.size >> PAGE_SHIFT; | 406 | unevictable += obj->base.size >> PAGE_SHIFT; |
| 379 | else | 407 | else |
| 380 | unbound += obj->base.size >> PAGE_SHIFT; | 408 | unbound += obj->base.size >> PAGE_SHIFT; |
| 381 | } | 409 | } |
| 382 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { | 410 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_link) { |
| 411 | if (!obj->mm.pages) | ||
| 412 | continue; | ||
| 413 | |||
| 383 | if (!can_release_pages(obj)) | 414 | if (!can_release_pages(obj)) |
| 384 | unevictable += obj->base.size >> PAGE_SHIFT; | 415 | unevictable += obj->base.size >> PAGE_SHIFT; |
| 385 | else | 416 | else |
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index f4f6d3a48b05..b1d367dba347 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c | |||
| @@ -109,7 +109,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) | |||
| 109 | * | 109 | * |
| 110 | */ | 110 | */ |
| 111 | base = 0; | 111 | base = 0; |
| 112 | if (INTEL_INFO(dev)->gen >= 3) { | 112 | if (INTEL_GEN(dev_priv) >= 3) { |
| 113 | u32 bsm; | 113 | u32 bsm; |
| 114 | 114 | ||
| 115 | pci_read_config_dword(pdev, INTEL_BSM, &bsm); | 115 | pci_read_config_dword(pdev, INTEL_BSM, &bsm); |
| @@ -138,7 +138,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) | |||
| 138 | I865_TOUD, &toud); | 138 | I865_TOUD, &toud); |
| 139 | 139 | ||
| 140 | base = (toud << 16) + tseg_size; | 140 | base = (toud << 16) + tseg_size; |
| 141 | } else if (IS_I85X(dev)) { | 141 | } else if (IS_I85X(dev_priv)) { |
| 142 | u32 tseg_size = 0; | 142 | u32 tseg_size = 0; |
| 143 | u32 tom; | 143 | u32 tom; |
| 144 | u8 tmp; | 144 | u8 tmp; |
| @@ -546,25 +546,29 @@ i915_pages_create_for_stolen(struct drm_device *dev, | |||
| 546 | return st; | 546 | return st; |
| 547 | } | 547 | } |
| 548 | 548 | ||
| 549 | static int i915_gem_object_get_pages_stolen(struct drm_i915_gem_object *obj) | 549 | static struct sg_table * |
| 550 | i915_gem_object_get_pages_stolen(struct drm_i915_gem_object *obj) | ||
| 550 | { | 551 | { |
| 551 | BUG(); | 552 | return i915_pages_create_for_stolen(obj->base.dev, |
| 552 | return -EINVAL; | 553 | obj->stolen->start, |
| 554 | obj->stolen->size); | ||
| 553 | } | 555 | } |
| 554 | 556 | ||
| 555 | static void i915_gem_object_put_pages_stolen(struct drm_i915_gem_object *obj) | 557 | static void i915_gem_object_put_pages_stolen(struct drm_i915_gem_object *obj, |
| 558 | struct sg_table *pages) | ||
| 556 | { | 559 | { |
| 557 | /* Should only be called during free */ | 560 | /* Should only be called during free */ |
| 558 | sg_free_table(obj->pages); | 561 | sg_free_table(pages); |
| 559 | kfree(obj->pages); | 562 | kfree(pages); |
| 560 | } | 563 | } |
| 561 | 564 | ||
| 562 | |||
| 563 | static void | 565 | static void |
| 564 | i915_gem_object_release_stolen(struct drm_i915_gem_object *obj) | 566 | i915_gem_object_release_stolen(struct drm_i915_gem_object *obj) |
| 565 | { | 567 | { |
| 566 | struct drm_i915_private *dev_priv = to_i915(obj->base.dev); | 568 | struct drm_i915_private *dev_priv = to_i915(obj->base.dev); |
| 567 | 569 | ||
| 570 | __i915_gem_object_unpin_pages(obj); | ||
| 571 | |||
| 568 | if (obj->stolen) { | 572 | if (obj->stolen) { |
| 569 | i915_gem_stolen_remove_node(dev_priv, obj->stolen); | 573 | i915_gem_stolen_remove_node(dev_priv, obj->stolen); |
| 570 | kfree(obj->stolen); | 574 | kfree(obj->stolen); |
| @@ -590,20 +594,13 @@ _i915_gem_object_create_stolen(struct drm_device *dev, | |||
| 590 | drm_gem_private_object_init(dev, &obj->base, stolen->size); | 594 | drm_gem_private_object_init(dev, &obj->base, stolen->size); |
| 591 | i915_gem_object_init(obj, &i915_gem_object_stolen_ops); | 595 | i915_gem_object_init(obj, &i915_gem_object_stolen_ops); |
| 592 | 596 | ||
| 593 | obj->pages = i915_pages_create_for_stolen(dev, | ||
| 594 | stolen->start, stolen->size); | ||
| 595 | if (obj->pages == NULL) | ||
| 596 | goto cleanup; | ||
| 597 | |||
| 598 | obj->get_page.sg = obj->pages->sgl; | ||
| 599 | obj->get_page.last = 0; | ||
| 600 | |||
| 601 | i915_gem_object_pin_pages(obj); | ||
| 602 | obj->stolen = stolen; | 597 | obj->stolen = stolen; |
| 603 | |||
| 604 | obj->base.read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT; | 598 | obj->base.read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT; |
| 605 | obj->cache_level = HAS_LLC(dev) ? I915_CACHE_LLC : I915_CACHE_NONE; | 599 | obj->cache_level = HAS_LLC(dev) ? I915_CACHE_LLC : I915_CACHE_NONE; |
| 606 | 600 | ||
| 601 | if (i915_gem_object_pin_pages(obj)) | ||
| 602 | goto cleanup; | ||
| 603 | |||
| 607 | return obj; | 604 | return obj; |
| 608 | 605 | ||
| 609 | cleanup: | 606 | cleanup: |
| @@ -698,10 +695,14 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, | |||
| 698 | if (gtt_offset == I915_GTT_OFFSET_NONE) | 695 | if (gtt_offset == I915_GTT_OFFSET_NONE) |
| 699 | return obj; | 696 | return obj; |
| 700 | 697 | ||
| 698 | ret = i915_gem_object_pin_pages(obj); | ||
| 699 | if (ret) | ||
| 700 | goto err; | ||
| 701 | |||
| 701 | vma = i915_gem_obj_lookup_or_create_vma(obj, &ggtt->base, NULL); | 702 | vma = i915_gem_obj_lookup_or_create_vma(obj, &ggtt->base, NULL); |
| 702 | if (IS_ERR(vma)) { | 703 | if (IS_ERR(vma)) { |
| 703 | ret = PTR_ERR(vma); | 704 | ret = PTR_ERR(vma); |
| 704 | goto err; | 705 | goto err_pages; |
| 705 | } | 706 | } |
| 706 | 707 | ||
| 707 | /* To simplify the initialisation sequence between KMS and GTT, | 708 | /* To simplify the initialisation sequence between KMS and GTT, |
| @@ -715,20 +716,20 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, | |||
| 715 | ret = drm_mm_reserve_node(&ggtt->base.mm, &vma->node); | 716 | ret = drm_mm_reserve_node(&ggtt->base.mm, &vma->node); |
| 716 | if (ret) { | 717 | if (ret) { |
| 717 | DRM_DEBUG_KMS("failed to allocate stolen GTT space\n"); | 718 | DRM_DEBUG_KMS("failed to allocate stolen GTT space\n"); |
| 718 | goto err; | 719 | goto err_pages; |
| 719 | } | 720 | } |
| 720 | 721 | ||
| 721 | vma->pages = obj->pages; | 722 | vma->pages = obj->mm.pages; |
| 722 | vma->flags |= I915_VMA_GLOBAL_BIND; | 723 | vma->flags |= I915_VMA_GLOBAL_BIND; |
| 723 | __i915_vma_set_map_and_fenceable(vma); | 724 | __i915_vma_set_map_and_fenceable(vma); |
| 724 | list_move_tail(&vma->vm_link, &ggtt->base.inactive_list); | 725 | list_move_tail(&vma->vm_link, &ggtt->base.inactive_list); |
| 726 | list_move_tail(&obj->global_link, &dev_priv->mm.bound_list); | ||
| 725 | obj->bind_count++; | 727 | obj->bind_count++; |
| 726 | 728 | ||
| 727 | list_add_tail(&obj->global_list, &dev_priv->mm.bound_list); | ||
| 728 | i915_gem_object_pin_pages(obj); | ||
| 729 | |||
| 730 | return obj; | 729 | return obj; |
| 731 | 730 | ||
| 731 | err_pages: | ||
| 732 | i915_gem_object_unpin_pages(obj); | ||
| 732 | err: | 733 | err: |
| 733 | i915_gem_object_put(obj); | 734 | i915_gem_object_put(obj); |
| 734 | return NULL; | 735 | return NULL; |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index c21bc0068d20..251d51b01174 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
| @@ -201,12 +201,10 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
| 201 | 201 | ||
| 202 | if (!i915_tiling_ok(dev, | 202 | if (!i915_tiling_ok(dev, |
| 203 | args->stride, obj->base.size, args->tiling_mode)) { | 203 | args->stride, obj->base.size, args->tiling_mode)) { |
| 204 | i915_gem_object_put_unlocked(obj); | 204 | i915_gem_object_put(obj); |
| 205 | return -EINVAL; | 205 | return -EINVAL; |
| 206 | } | 206 | } |
| 207 | 207 | ||
| 208 | intel_runtime_pm_get(dev_priv); | ||
| 209 | |||
| 210 | mutex_lock(&dev->struct_mutex); | 208 | mutex_lock(&dev->struct_mutex); |
| 211 | if (obj->pin_display || obj->framebuffer_references) { | 209 | if (obj->pin_display || obj->framebuffer_references) { |
| 212 | err = -EBUSY; | 210 | err = -EBUSY; |
| @@ -261,14 +259,22 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
| 261 | if (!err) { | 259 | if (!err) { |
| 262 | struct i915_vma *vma; | 260 | struct i915_vma *vma; |
| 263 | 261 | ||
| 264 | if (obj->pages && | 262 | mutex_lock(&obj->mm.lock); |
| 265 | obj->madv == I915_MADV_WILLNEED && | 263 | if (obj->mm.pages && |
| 264 | obj->mm.madv == I915_MADV_WILLNEED && | ||
| 266 | dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) { | 265 | dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) { |
| 267 | if (args->tiling_mode == I915_TILING_NONE) | 266 | if (args->tiling_mode == I915_TILING_NONE) { |
| 268 | i915_gem_object_unpin_pages(obj); | 267 | GEM_BUG_ON(!obj->mm.quirked); |
| 269 | if (!i915_gem_object_is_tiled(obj)) | 268 | __i915_gem_object_unpin_pages(obj); |
| 270 | i915_gem_object_pin_pages(obj); | 269 | obj->mm.quirked = false; |
| 270 | } | ||
| 271 | if (!i915_gem_object_is_tiled(obj)) { | ||
| 272 | GEM_BUG_ON(!obj->mm.quirked); | ||
| 273 | __i915_gem_object_pin_pages(obj); | ||
| 274 | obj->mm.quirked = true; | ||
| 275 | } | ||
| 271 | } | 276 | } |
| 277 | mutex_unlock(&obj->mm.lock); | ||
| 272 | 278 | ||
| 273 | list_for_each_entry(vma, &obj->vma_list, obj_link) { | 279 | list_for_each_entry(vma, &obj->vma_list, obj_link) { |
| 274 | if (!vma->fence) | 280 | if (!vma->fence) |
| @@ -302,8 +308,6 @@ err: | |||
| 302 | i915_gem_object_put(obj); | 308 | i915_gem_object_put(obj); |
| 303 | mutex_unlock(&dev->struct_mutex); | 309 | mutex_unlock(&dev->struct_mutex); |
| 304 | 310 | ||
| 305 | intel_runtime_pm_put(dev_priv); | ||
| 306 | |||
| 307 | return err; | 311 | return err; |
| 308 | } | 312 | } |
| 309 | 313 | ||
| @@ -327,12 +331,19 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, | |||
| 327 | struct drm_i915_gem_get_tiling *args = data; | 331 | struct drm_i915_gem_get_tiling *args = data; |
| 328 | struct drm_i915_private *dev_priv = to_i915(dev); | 332 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 329 | struct drm_i915_gem_object *obj; | 333 | struct drm_i915_gem_object *obj; |
| 334 | int err = -ENOENT; | ||
| 335 | |||
| 336 | rcu_read_lock(); | ||
| 337 | obj = i915_gem_object_lookup_rcu(file, args->handle); | ||
| 338 | if (obj) { | ||
| 339 | args->tiling_mode = | ||
| 340 | READ_ONCE(obj->tiling_and_stride) & TILING_MASK; | ||
| 341 | err = 0; | ||
| 342 | } | ||
| 343 | rcu_read_unlock(); | ||
| 344 | if (unlikely(err)) | ||
| 345 | return err; | ||
| 330 | 346 | ||
| 331 | obj = i915_gem_object_lookup(file, args->handle); | ||
| 332 | if (!obj) | ||
| 333 | return -ENOENT; | ||
| 334 | |||
| 335 | args->tiling_mode = READ_ONCE(obj->tiling_and_stride) & TILING_MASK; | ||
| 336 | switch (args->tiling_mode) { | 347 | switch (args->tiling_mode) { |
| 337 | case I915_TILING_X: | 348 | case I915_TILING_X: |
| 338 | args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x; | 349 | args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x; |
| @@ -340,11 +351,10 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, | |||
| 340 | case I915_TILING_Y: | 351 | case I915_TILING_Y: |
| 341 | args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y; | 352 | args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y; |
| 342 | break; | 353 | break; |
| 354 | default: | ||
| 343 | case I915_TILING_NONE: | 355 | case I915_TILING_NONE: |
| 344 | args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; | 356 | args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; |
| 345 | break; | 357 | break; |
| 346 | default: | ||
| 347 | DRM_ERROR("unknown tiling mode\n"); | ||
| 348 | } | 358 | } |
| 349 | 359 | ||
| 350 | /* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */ | 360 | /* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */ |
| @@ -357,6 +367,5 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, | |||
| 357 | if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17) | 367 | if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17) |
| 358 | args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10; | 368 | args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10; |
| 359 | 369 | ||
| 360 | i915_gem_object_put_unlocked(obj); | ||
| 361 | return 0; | 370 | return 0; |
| 362 | } | 371 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.h b/drivers/gpu/drm/i915/i915_gem_timeline.c index 91315557e421..fc8f13a79f8f 100644 --- a/drivers/gpu/drm/i915/i915_gem_dmabuf.h +++ b/drivers/gpu/drm/i915/i915_gem_timeline.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright 2016 Intel Corporation | 2 | * Copyright © 2016 Intel Corporation |
| 3 | * | 3 | * |
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a | 4 | * Permission is hereby granted, free of charge, to any person obtaining a |
| 5 | * copy of this software and associated documentation files (the "Software"), | 5 | * copy of this software and associated documentation files (the "Software"), |
| @@ -17,29 +17,49 @@ | |||
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| 21 | * DEALINGS IN THE SOFTWARE. | 21 | * IN THE SOFTWARE. |
| 22 | * | 22 | * |
| 23 | */ | 23 | */ |
| 24 | 24 | ||
| 25 | #ifndef _I915_GEM_DMABUF_H_ | 25 | #include "i915_drv.h" |
| 26 | #define _I915_GEM_DMABUF_H_ | ||
| 27 | 26 | ||
| 28 | #include <linux/dma-buf.h> | 27 | int i915_gem_timeline_init(struct drm_i915_private *i915, |
| 29 | 28 | struct i915_gem_timeline *timeline, | |
| 30 | static inline struct reservation_object * | 29 | const char *name) |
| 31 | i915_gem_object_get_dmabuf_resv(struct drm_i915_gem_object *obj) | ||
| 32 | { | 30 | { |
| 33 | struct dma_buf *dma_buf; | 31 | unsigned int i; |
| 32 | u64 fences; | ||
| 33 | |||
| 34 | lockdep_assert_held(&i915->drm.struct_mutex); | ||
| 35 | |||
| 36 | timeline->i915 = i915; | ||
| 37 | timeline->name = kstrdup(name ?: "[kernel]", GFP_KERNEL); | ||
| 38 | if (!timeline->name) | ||
| 39 | return -ENOMEM; | ||
| 40 | |||
| 41 | list_add(&timeline->link, &i915->gt.timelines); | ||
| 42 | |||
| 43 | /* Called during early_init before we know how many engines there are */ | ||
| 44 | fences = dma_fence_context_alloc(ARRAY_SIZE(timeline->engine)); | ||
| 45 | for (i = 0; i < ARRAY_SIZE(timeline->engine); i++) { | ||
| 46 | struct intel_timeline *tl = &timeline->engine[i]; | ||
| 34 | 47 | ||
| 35 | if (obj->base.dma_buf) | 48 | tl->fence_context = fences++; |
| 36 | dma_buf = obj->base.dma_buf; | 49 | tl->common = timeline; |
| 37 | else if (obj->base.import_attach) | ||
| 38 | dma_buf = obj->base.import_attach->dmabuf; | ||
| 39 | else | ||
| 40 | return NULL; | ||
| 41 | 50 | ||
| 42 | return dma_buf->resv; | 51 | spin_lock_init(&tl->lock); |
| 52 | init_request_active(&tl->last_request, NULL); | ||
| 53 | INIT_LIST_HEAD(&tl->requests); | ||
| 54 | } | ||
| 55 | |||
| 56 | return 0; | ||
| 43 | } | 57 | } |
| 44 | 58 | ||
| 45 | #endif | 59 | void i915_gem_timeline_fini(struct i915_gem_timeline *tl) |
| 60 | { | ||
| 61 | lockdep_assert_held(&tl->i915->drm.struct_mutex); | ||
| 62 | |||
| 63 | list_del(&tl->link); | ||
| 64 | kfree(tl->name); | ||
| 65 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_gem_timeline.h new file mode 100644 index 000000000000..f2bf7b1d49a1 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_timeline.h | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | /* | ||
| 2 | * Copyright © 2016 Intel Corporation | ||
| 3 | * | ||
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 5 | * copy of this software and associated documentation files (the "Software"), | ||
| 6 | * to deal in the Software without restriction, including without limitation | ||
| 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 9 | * Software is furnished to do so, subject to the following conditions: | ||
| 10 | * | ||
| 11 | * The above copyright notice and this permission notice (including the next | ||
| 12 | * paragraph) shall be included in all copies or substantial portions of the | ||
| 13 | * Software. | ||
| 14 | * | ||
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
| 21 | * IN THE SOFTWARE. | ||
| 22 | * | ||
| 23 | */ | ||
| 24 | |||
| 25 | #ifndef I915_GEM_TIMELINE_H | ||
| 26 | #define I915_GEM_TIMELINE_H | ||
| 27 | |||
| 28 | #include <linux/list.h> | ||
| 29 | |||
| 30 | #include "i915_gem_request.h" | ||
| 31 | |||
| 32 | struct i915_gem_timeline; | ||
| 33 | |||
| 34 | struct intel_timeline { | ||
| 35 | u64 fence_context; | ||
| 36 | u32 last_submitted_seqno; | ||
| 37 | |||
| 38 | spinlock_t lock; | ||
| 39 | |||
| 40 | /** | ||
| 41 | * List of breadcrumbs associated with GPU requests currently | ||
| 42 | * outstanding. | ||
| 43 | */ | ||
| 44 | struct list_head requests; | ||
| 45 | |||
| 46 | /* Contains an RCU guarded pointer to the last request. No reference is | ||
| 47 | * held to the request, users must carefully acquire a reference to | ||
| 48 | * the request using i915_gem_active_get_request_rcu(), or hold the | ||
| 49 | * struct_mutex. | ||
| 50 | */ | ||
| 51 | struct i915_gem_active last_request; | ||
| 52 | u32 sync_seqno[I915_NUM_ENGINES]; | ||
| 53 | |||
| 54 | struct i915_gem_timeline *common; | ||
| 55 | }; | ||
| 56 | |||
| 57 | struct i915_gem_timeline { | ||
| 58 | struct list_head link; | ||
| 59 | atomic_t next_seqno; | ||
| 60 | |||
| 61 | struct drm_i915_private *i915; | ||
| 62 | const char *name; | ||
| 63 | |||
| 64 | struct intel_timeline engine[I915_NUM_ENGINES]; | ||
| 65 | }; | ||
| 66 | |||
| 67 | int i915_gem_timeline_init(struct drm_i915_private *i915, | ||
| 68 | struct i915_gem_timeline *tl, | ||
| 69 | const char *name); | ||
| 70 | void i915_gem_timeline_fini(struct i915_gem_timeline *tl); | ||
| 71 | |||
| 72 | #endif | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index c6f780f5abc9..64261639f547 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c | |||
| @@ -61,33 +61,26 @@ struct i915_mmu_object { | |||
| 61 | bool attached; | 61 | bool attached; |
| 62 | }; | 62 | }; |
| 63 | 63 | ||
| 64 | static void wait_rendering(struct drm_i915_gem_object *obj) | ||
| 65 | { | ||
| 66 | unsigned long active = __I915_BO_ACTIVE(obj); | ||
| 67 | int idx; | ||
| 68 | |||
| 69 | for_each_active(active, idx) | ||
| 70 | i915_gem_active_wait_unlocked(&obj->last_read[idx], | ||
| 71 | 0, NULL, NULL); | ||
| 72 | } | ||
| 73 | |||
| 74 | static void cancel_userptr(struct work_struct *work) | 64 | static void cancel_userptr(struct work_struct *work) |
| 75 | { | 65 | { |
| 76 | struct i915_mmu_object *mo = container_of(work, typeof(*mo), work); | 66 | struct i915_mmu_object *mo = container_of(work, typeof(*mo), work); |
| 77 | struct drm_i915_gem_object *obj = mo->obj; | 67 | struct drm_i915_gem_object *obj = mo->obj; |
| 78 | struct drm_device *dev = obj->base.dev; | 68 | struct drm_device *dev = obj->base.dev; |
| 79 | 69 | ||
| 80 | wait_rendering(obj); | 70 | i915_gem_object_wait(obj, I915_WAIT_ALL, MAX_SCHEDULE_TIMEOUT, NULL); |
| 81 | 71 | ||
| 82 | mutex_lock(&dev->struct_mutex); | 72 | mutex_lock(&dev->struct_mutex); |
| 83 | /* Cancel any active worker and force us to re-evaluate gup */ | 73 | /* Cancel any active worker and force us to re-evaluate gup */ |
| 84 | obj->userptr.work = NULL; | 74 | obj->userptr.work = NULL; |
| 85 | 75 | ||
| 86 | if (obj->pages != NULL) { | 76 | /* We are inside a kthread context and can't be interrupted */ |
| 87 | /* We are inside a kthread context and can't be interrupted */ | 77 | if (i915_gem_object_unbind(obj) == 0) |
| 88 | WARN_ON(i915_gem_object_unbind(obj)); | 78 | __i915_gem_object_put_pages(obj, I915_MM_NORMAL); |
| 89 | WARN_ON(i915_gem_object_put_pages(obj)); | 79 | WARN_ONCE(obj->mm.pages, |
| 90 | } | 80 | "Failed to release pages: bind_count=%d, pages_pin_count=%d, pin_display=%d\n", |
| 81 | obj->bind_count, | ||
| 82 | atomic_read(&obj->mm.pages_pin_count), | ||
| 83 | obj->pin_display); | ||
| 91 | 84 | ||
| 92 | i915_gem_object_put(obj); | 85 | i915_gem_object_put(obj); |
| 93 | mutex_unlock(&dev->struct_mutex); | 86 | mutex_unlock(&dev->struct_mutex); |
| @@ -436,24 +429,25 @@ err: | |||
| 436 | return ret; | 429 | return ret; |
| 437 | } | 430 | } |
| 438 | 431 | ||
| 439 | static int | 432 | static struct sg_table * |
| 440 | __i915_gem_userptr_set_pages(struct drm_i915_gem_object *obj, | 433 | __i915_gem_userptr_set_pages(struct drm_i915_gem_object *obj, |
| 441 | struct page **pvec, int num_pages) | 434 | struct page **pvec, int num_pages) |
| 442 | { | 435 | { |
| 436 | struct sg_table *pages; | ||
| 443 | int ret; | 437 | int ret; |
| 444 | 438 | ||
| 445 | ret = st_set_pages(&obj->pages, pvec, num_pages); | 439 | ret = st_set_pages(&pages, pvec, num_pages); |
| 446 | if (ret) | 440 | if (ret) |
| 447 | return ret; | 441 | return ERR_PTR(ret); |
| 448 | 442 | ||
| 449 | ret = i915_gem_gtt_prepare_object(obj); | 443 | ret = i915_gem_gtt_prepare_pages(obj, pages); |
| 450 | if (ret) { | 444 | if (ret) { |
| 451 | sg_free_table(obj->pages); | 445 | sg_free_table(pages); |
| 452 | kfree(obj->pages); | 446 | kfree(pages); |
| 453 | obj->pages = NULL; | 447 | return ERR_PTR(ret); |
| 454 | } | 448 | } |
| 455 | 449 | ||
| 456 | return ret; | 450 | return pages; |
| 457 | } | 451 | } |
| 458 | 452 | ||
| 459 | static int | 453 | static int |
| @@ -497,7 +491,6 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) | |||
| 497 | { | 491 | { |
| 498 | struct get_pages_work *work = container_of(_work, typeof(*work), work); | 492 | struct get_pages_work *work = container_of(_work, typeof(*work), work); |
| 499 | struct drm_i915_gem_object *obj = work->obj; | 493 | struct drm_i915_gem_object *obj = work->obj; |
| 500 | struct drm_device *dev = obj->base.dev; | ||
| 501 | const int npages = obj->base.size >> PAGE_SHIFT; | 494 | const int npages = obj->base.size >> PAGE_SHIFT; |
| 502 | struct page **pvec; | 495 | struct page **pvec; |
| 503 | int pinned, ret; | 496 | int pinned, ret; |
| @@ -533,33 +526,32 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) | |||
| 533 | } | 526 | } |
| 534 | } | 527 | } |
| 535 | 528 | ||
| 536 | mutex_lock(&dev->struct_mutex); | 529 | mutex_lock(&obj->mm.lock); |
| 537 | if (obj->userptr.work == &work->work) { | 530 | if (obj->userptr.work == &work->work) { |
| 531 | struct sg_table *pages = ERR_PTR(ret); | ||
| 532 | |||
| 538 | if (pinned == npages) { | 533 | if (pinned == npages) { |
| 539 | ret = __i915_gem_userptr_set_pages(obj, pvec, npages); | 534 | pages = __i915_gem_userptr_set_pages(obj, pvec, npages); |
| 540 | if (ret == 0) { | 535 | if (!IS_ERR(pages)) { |
| 541 | list_add_tail(&obj->global_list, | 536 | __i915_gem_object_set_pages(obj, pages); |
| 542 | &to_i915(dev)->mm.unbound_list); | ||
| 543 | obj->get_page.sg = obj->pages->sgl; | ||
| 544 | obj->get_page.last = 0; | ||
| 545 | pinned = 0; | 537 | pinned = 0; |
| 538 | pages = NULL; | ||
| 546 | } | 539 | } |
| 547 | } | 540 | } |
| 548 | obj->userptr.work = ERR_PTR(ret); | ||
| 549 | } | ||
| 550 | 541 | ||
| 551 | obj->userptr.workers--; | 542 | obj->userptr.work = ERR_CAST(pages); |
| 552 | i915_gem_object_put(obj); | 543 | } |
| 553 | mutex_unlock(&dev->struct_mutex); | 544 | mutex_unlock(&obj->mm.lock); |
| 554 | 545 | ||
| 555 | release_pages(pvec, pinned, 0); | 546 | release_pages(pvec, pinned, 0); |
| 556 | drm_free_large(pvec); | 547 | drm_free_large(pvec); |
| 557 | 548 | ||
| 549 | i915_gem_object_put(obj); | ||
| 558 | put_task_struct(work->task); | 550 | put_task_struct(work->task); |
| 559 | kfree(work); | 551 | kfree(work); |
| 560 | } | 552 | } |
| 561 | 553 | ||
| 562 | static int | 554 | static struct sg_table * |
| 563 | __i915_gem_userptr_get_pages_schedule(struct drm_i915_gem_object *obj, | 555 | __i915_gem_userptr_get_pages_schedule(struct drm_i915_gem_object *obj, |
| 564 | bool *active) | 556 | bool *active) |
| 565 | { | 557 | { |
| @@ -584,15 +576,11 @@ __i915_gem_userptr_get_pages_schedule(struct drm_i915_gem_object *obj, | |||
| 584 | * that error back to this function through | 576 | * that error back to this function through |
| 585 | * obj->userptr.work = ERR_PTR. | 577 | * obj->userptr.work = ERR_PTR. |
| 586 | */ | 578 | */ |
| 587 | if (obj->userptr.workers >= I915_GEM_USERPTR_MAX_WORKERS) | ||
| 588 | return -EAGAIN; | ||
| 589 | |||
| 590 | work = kmalloc(sizeof(*work), GFP_KERNEL); | 579 | work = kmalloc(sizeof(*work), GFP_KERNEL); |
| 591 | if (work == NULL) | 580 | if (work == NULL) |
| 592 | return -ENOMEM; | 581 | return ERR_PTR(-ENOMEM); |
| 593 | 582 | ||
| 594 | obj->userptr.work = &work->work; | 583 | obj->userptr.work = &work->work; |
| 595 | obj->userptr.workers++; | ||
| 596 | 584 | ||
| 597 | work->obj = i915_gem_object_get(obj); | 585 | work->obj = i915_gem_object_get(obj); |
| 598 | 586 | ||
| @@ -603,14 +591,15 @@ __i915_gem_userptr_get_pages_schedule(struct drm_i915_gem_object *obj, | |||
| 603 | schedule_work(&work->work); | 591 | schedule_work(&work->work); |
| 604 | 592 | ||
| 605 | *active = true; | 593 | *active = true; |
| 606 | return -EAGAIN; | 594 | return ERR_PTR(-EAGAIN); |
| 607 | } | 595 | } |
| 608 | 596 | ||
| 609 | static int | 597 | static struct sg_table * |
| 610 | i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) | 598 | i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) |
| 611 | { | 599 | { |
| 612 | const int num_pages = obj->base.size >> PAGE_SHIFT; | 600 | const int num_pages = obj->base.size >> PAGE_SHIFT; |
| 613 | struct page **pvec; | 601 | struct page **pvec; |
| 602 | struct sg_table *pages; | ||
| 614 | int pinned, ret; | 603 | int pinned, ret; |
| 615 | bool active; | 604 | bool active; |
| 616 | 605 | ||
| @@ -634,15 +623,15 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) | |||
| 634 | if (obj->userptr.work) { | 623 | if (obj->userptr.work) { |
| 635 | /* active flag should still be held for the pending work */ | 624 | /* active flag should still be held for the pending work */ |
| 636 | if (IS_ERR(obj->userptr.work)) | 625 | if (IS_ERR(obj->userptr.work)) |
| 637 | return PTR_ERR(obj->userptr.work); | 626 | return ERR_CAST(obj->userptr.work); |
| 638 | else | 627 | else |
| 639 | return -EAGAIN; | 628 | return ERR_PTR(-EAGAIN); |
| 640 | } | 629 | } |
| 641 | 630 | ||
| 642 | /* Let the mmu-notifier know that we have begun and need cancellation */ | 631 | /* Let the mmu-notifier know that we have begun and need cancellation */ |
| 643 | ret = __i915_gem_userptr_set_active(obj, true); | 632 | ret = __i915_gem_userptr_set_active(obj, true); |
| 644 | if (ret) | 633 | if (ret) |
| 645 | return ret; | 634 | return ERR_PTR(ret); |
| 646 | 635 | ||
| 647 | pvec = NULL; | 636 | pvec = NULL; |
| 648 | pinned = 0; | 637 | pinned = 0; |
| @@ -651,7 +640,7 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) | |||
| 651 | GFP_TEMPORARY); | 640 | GFP_TEMPORARY); |
| 652 | if (pvec == NULL) { | 641 | if (pvec == NULL) { |
| 653 | __i915_gem_userptr_set_active(obj, false); | 642 | __i915_gem_userptr_set_active(obj, false); |
| 654 | return -ENOMEM; | 643 | return ERR_PTR(-ENOMEM); |
| 655 | } | 644 | } |
| 656 | 645 | ||
| 657 | pinned = __get_user_pages_fast(obj->userptr.ptr, num_pages, | 646 | pinned = __get_user_pages_fast(obj->userptr.ptr, num_pages, |
| @@ -660,21 +649,22 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) | |||
| 660 | 649 | ||
| 661 | active = false; | 650 | active = false; |
| 662 | if (pinned < 0) | 651 | if (pinned < 0) |
| 663 | ret = pinned, pinned = 0; | 652 | pages = ERR_PTR(pinned), pinned = 0; |
| 664 | else if (pinned < num_pages) | 653 | else if (pinned < num_pages) |
| 665 | ret = __i915_gem_userptr_get_pages_schedule(obj, &active); | 654 | pages = __i915_gem_userptr_get_pages_schedule(obj, &active); |
| 666 | else | 655 | else |
| 667 | ret = __i915_gem_userptr_set_pages(obj, pvec, num_pages); | 656 | pages = __i915_gem_userptr_set_pages(obj, pvec, num_pages); |
| 668 | if (ret) { | 657 | if (IS_ERR(pages)) { |
| 669 | __i915_gem_userptr_set_active(obj, active); | 658 | __i915_gem_userptr_set_active(obj, active); |
| 670 | release_pages(pvec, pinned, 0); | 659 | release_pages(pvec, pinned, 0); |
| 671 | } | 660 | } |
| 672 | drm_free_large(pvec); | 661 | drm_free_large(pvec); |
| 673 | return ret; | 662 | return pages; |
| 674 | } | 663 | } |
| 675 | 664 | ||
| 676 | static void | 665 | static void |
| 677 | i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj) | 666 | i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj, |
| 667 | struct sg_table *pages) | ||
| 678 | { | 668 | { |
| 679 | struct sgt_iter sgt_iter; | 669 | struct sgt_iter sgt_iter; |
| 680 | struct page *page; | 670 | struct page *page; |
| @@ -682,22 +672,22 @@ i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj) | |||
| 682 | BUG_ON(obj->userptr.work != NULL); | 672 | BUG_ON(obj->userptr.work != NULL); |
| 683 | __i915_gem_userptr_set_active(obj, false); | 673 | __i915_gem_userptr_set_active(obj, false); |
| 684 | 674 | ||
| 685 | if (obj->madv != I915_MADV_WILLNEED) | 675 | if (obj->mm.madv != I915_MADV_WILLNEED) |
| 686 | obj->dirty = 0; | 676 | obj->mm.dirty = false; |
| 687 | 677 | ||
| 688 | i915_gem_gtt_finish_object(obj); | 678 | i915_gem_gtt_finish_pages(obj, pages); |
| 689 | 679 | ||
| 690 | for_each_sgt_page(page, sgt_iter, obj->pages) { | 680 | for_each_sgt_page(page, sgt_iter, pages) { |
| 691 | if (obj->dirty) | 681 | if (obj->mm.dirty) |
| 692 | set_page_dirty(page); | 682 | set_page_dirty(page); |
| 693 | 683 | ||
| 694 | mark_page_accessed(page); | 684 | mark_page_accessed(page); |
| 695 | put_page(page); | 685 | put_page(page); |
| 696 | } | 686 | } |
| 697 | obj->dirty = 0; | 687 | obj->mm.dirty = false; |
| 698 | 688 | ||
| 699 | sg_free_table(obj->pages); | 689 | sg_free_table(pages); |
| 700 | kfree(obj->pages); | 690 | kfree(pages); |
| 701 | } | 691 | } |
| 702 | 692 | ||
| 703 | static void | 693 | static void |
| @@ -717,7 +707,8 @@ i915_gem_userptr_dmabuf_export(struct drm_i915_gem_object *obj) | |||
| 717 | } | 707 | } |
| 718 | 708 | ||
| 719 | static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = { | 709 | static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = { |
| 720 | .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE, | 710 | .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE | |
| 711 | I915_GEM_OBJECT_IS_SHRINKABLE, | ||
| 721 | .get_pages = i915_gem_userptr_get_pages, | 712 | .get_pages = i915_gem_userptr_get_pages, |
| 722 | .put_pages = i915_gem_userptr_put_pages, | 713 | .put_pages = i915_gem_userptr_put_pages, |
| 723 | .dmabuf_export = i915_gem_userptr_dmabuf_export, | 714 | .dmabuf_export = i915_gem_userptr_dmabuf_export, |
| @@ -816,7 +807,7 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file | |||
| 816 | ret = drm_gem_handle_create(file, &obj->base, &handle); | 807 | ret = drm_gem_handle_create(file, &obj->base, &handle); |
| 817 | 808 | ||
| 818 | /* drop reference from allocate - handle holds it now */ | 809 | /* drop reference from allocate - handle holds it now */ |
| 819 | i915_gem_object_put_unlocked(obj); | 810 | i915_gem_object_put(obj); |
| 820 | if (ret) | 811 | if (ret) |
| 821 | return ret; | 812 | return ret; |
| 822 | 813 | ||
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 242b9a927899..204093f3eaa5 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c | |||
| @@ -415,17 +415,13 @@ static void error_print_engine(struct drm_i915_error_state_buf *m, | |||
| 415 | if (INTEL_GEN(m->i915) >= 6) { | 415 | if (INTEL_GEN(m->i915) >= 6) { |
| 416 | err_printf(m, " RC PSMI: 0x%08x\n", ee->rc_psmi); | 416 | err_printf(m, " RC PSMI: 0x%08x\n", ee->rc_psmi); |
| 417 | err_printf(m, " FAULT_REG: 0x%08x\n", ee->fault_reg); | 417 | err_printf(m, " FAULT_REG: 0x%08x\n", ee->fault_reg); |
| 418 | err_printf(m, " SYNC_0: 0x%08x [last synced 0x%08x]\n", | 418 | err_printf(m, " SYNC_0: 0x%08x\n", |
| 419 | ee->semaphore_mboxes[0], | 419 | ee->semaphore_mboxes[0]); |
| 420 | ee->semaphore_seqno[0]); | 420 | err_printf(m, " SYNC_1: 0x%08x\n", |
| 421 | err_printf(m, " SYNC_1: 0x%08x [last synced 0x%08x]\n", | 421 | ee->semaphore_mboxes[1]); |
| 422 | ee->semaphore_mboxes[1], | 422 | if (HAS_VEBOX(m->i915)) |
| 423 | ee->semaphore_seqno[1]); | 423 | err_printf(m, " SYNC_2: 0x%08x\n", |
| 424 | if (HAS_VEBOX(m->i915)) { | 424 | ee->semaphore_mboxes[2]); |
| 425 | err_printf(m, " SYNC_2: 0x%08x [last synced 0x%08x]\n", | ||
| 426 | ee->semaphore_mboxes[2], | ||
| 427 | ee->semaphore_seqno[2]); | ||
| 428 | } | ||
| 429 | } | 425 | } |
| 430 | if (USES_PPGTT(m->i915)) { | 426 | if (USES_PPGTT(m->i915)) { |
| 431 | err_printf(m, " GFX_MODE: 0x%08x\n", ee->vm_info.gfx_mode); | 427 | err_printf(m, " GFX_MODE: 0x%08x\n", ee->vm_info.gfx_mode); |
| @@ -546,9 +542,13 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | |||
| 546 | } | 542 | } |
| 547 | 543 | ||
| 548 | err_printf(m, "%s\n", error->error_msg); | 544 | err_printf(m, "%s\n", error->error_msg); |
| 549 | err_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, | ||
| 550 | error->time.tv_usec); | ||
| 551 | err_printf(m, "Kernel: " UTS_RELEASE "\n"); | 545 | err_printf(m, "Kernel: " UTS_RELEASE "\n"); |
| 546 | err_printf(m, "Time: %ld s %ld us\n", | ||
| 547 | error->time.tv_sec, error->time.tv_usec); | ||
| 548 | err_printf(m, "Boottime: %ld s %ld us\n", | ||
| 549 | error->boottime.tv_sec, error->boottime.tv_usec); | ||
| 550 | err_printf(m, "Uptime: %ld s %ld us\n", | ||
| 551 | error->uptime.tv_sec, error->uptime.tv_usec); | ||
| 552 | err_print_capabilities(m, &error->device_info); | 552 | err_print_capabilities(m, &error->device_info); |
| 553 | max_hangcheck_score = 0; | 553 | max_hangcheck_score = 0; |
| 554 | for (i = 0; i < ARRAY_SIZE(error->engine); i++) { | 554 | for (i = 0; i < ARRAY_SIZE(error->engine); i++) { |
| @@ -702,6 +702,8 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | |||
| 702 | 702 | ||
| 703 | print_error_obj(m, NULL, "Semaphores", error->semaphore); | 703 | print_error_obj(m, NULL, "Semaphores", error->semaphore); |
| 704 | 704 | ||
| 705 | print_error_obj(m, NULL, "GuC log buffer", error->guc_log); | ||
| 706 | |||
| 705 | if (error->overlay) | 707 | if (error->overlay) |
| 706 | intel_overlay_print_error_state(m, error->overlay); | 708 | intel_overlay_print_error_state(m, error->overlay); |
| 707 | 709 | ||
| @@ -782,6 +784,7 @@ static void i915_error_state_free(struct kref *error_ref) | |||
| 782 | } | 784 | } |
| 783 | 785 | ||
| 784 | i915_error_object_free(error->semaphore); | 786 | i915_error_object_free(error->semaphore); |
| 787 | i915_error_object_free(error->guc_log); | ||
| 785 | 788 | ||
| 786 | for (i = 0; i < ARRAY_SIZE(error->active_bo); i++) | 789 | for (i = 0; i < ARRAY_SIZE(error->active_bo); i++) |
| 787 | kfree(error->active_bo[i]); | 790 | kfree(error->active_bo[i]); |
| @@ -880,17 +883,17 @@ static void capture_bo(struct drm_i915_error_buffer *err, | |||
| 880 | err->name = obj->base.name; | 883 | err->name = obj->base.name; |
| 881 | 884 | ||
| 882 | for (i = 0; i < I915_NUM_ENGINES; i++) | 885 | for (i = 0; i < I915_NUM_ENGINES; i++) |
| 883 | err->rseqno[i] = __active_get_seqno(&obj->last_read[i]); | 886 | err->rseqno[i] = __active_get_seqno(&vma->last_read[i]); |
| 884 | err->wseqno = __active_get_seqno(&obj->last_write); | 887 | err->wseqno = __active_get_seqno(&vma->last_write); |
| 885 | err->engine = __active_get_engine_id(&obj->last_write); | 888 | err->engine = __active_get_engine_id(&vma->last_write); |
| 886 | 889 | ||
| 887 | err->gtt_offset = vma->node.start; | 890 | err->gtt_offset = vma->node.start; |
| 888 | err->read_domains = obj->base.read_domains; | 891 | err->read_domains = obj->base.read_domains; |
| 889 | err->write_domain = obj->base.write_domain; | 892 | err->write_domain = obj->base.write_domain; |
| 890 | err->fence_reg = vma->fence ? vma->fence->id : -1; | 893 | err->fence_reg = vma->fence ? vma->fence->id : -1; |
| 891 | err->tiling = i915_gem_object_get_tiling(obj); | 894 | err->tiling = i915_gem_object_get_tiling(obj); |
| 892 | err->dirty = obj->dirty; | 895 | err->dirty = obj->mm.dirty; |
| 893 | err->purgeable = obj->madv != I915_MADV_WILLNEED; | 896 | err->purgeable = obj->mm.madv != I915_MADV_WILLNEED; |
| 894 | err->userptr = obj->userptr.mm != NULL; | 897 | err->userptr = obj->userptr.mm != NULL; |
| 895 | err->cache_level = obj->cache_level; | 898 | err->cache_level = obj->cache_level; |
| 896 | } | 899 | } |
| @@ -965,6 +968,26 @@ static void i915_gem_record_fences(struct drm_i915_private *dev_priv, | |||
| 965 | } | 968 | } |
| 966 | } | 969 | } |
| 967 | 970 | ||
| 971 | static inline u32 | ||
| 972 | gen8_engine_sync_index(struct intel_engine_cs *engine, | ||
| 973 | struct intel_engine_cs *other) | ||
| 974 | { | ||
| 975 | int idx; | ||
| 976 | |||
| 977 | /* | ||
| 978 | * rcs -> 0 = vcs, 1 = bcs, 2 = vecs, 3 = vcs2; | ||
| 979 | * vcs -> 0 = bcs, 1 = vecs, 2 = vcs2, 3 = rcs; | ||
| 980 | * bcs -> 0 = vecs, 1 = vcs2. 2 = rcs, 3 = vcs; | ||
| 981 | * vecs -> 0 = vcs2, 1 = rcs, 2 = vcs, 3 = bcs; | ||
| 982 | * vcs2 -> 0 = rcs, 1 = vcs, 2 = bcs, 3 = vecs; | ||
| 983 | */ | ||
| 984 | |||
| 985 | idx = (other - engine) - 1; | ||
| 986 | if (idx < 0) | ||
| 987 | idx += I915_NUM_ENGINES; | ||
| 988 | |||
| 989 | return idx; | ||
| 990 | } | ||
| 968 | 991 | ||
| 969 | static void gen8_record_semaphore_state(struct drm_i915_error_state *error, | 992 | static void gen8_record_semaphore_state(struct drm_i915_error_state *error, |
| 970 | struct intel_engine_cs *engine, | 993 | struct intel_engine_cs *engine, |
| @@ -988,10 +1011,9 @@ static void gen8_record_semaphore_state(struct drm_i915_error_state *error, | |||
| 988 | signal_offset = | 1011 | signal_offset = |
| 989 | (GEN8_SIGNAL_OFFSET(engine, id) & (PAGE_SIZE - 1)) / 4; | 1012 | (GEN8_SIGNAL_OFFSET(engine, id) & (PAGE_SIZE - 1)) / 4; |
| 990 | tmp = error->semaphore->pages[0]; | 1013 | tmp = error->semaphore->pages[0]; |
| 991 | idx = intel_engine_sync_index(engine, to); | 1014 | idx = gen8_engine_sync_index(engine, to); |
| 992 | 1015 | ||
| 993 | ee->semaphore_mboxes[idx] = tmp[signal_offset]; | 1016 | ee->semaphore_mboxes[idx] = tmp[signal_offset]; |
| 994 | ee->semaphore_seqno[idx] = engine->semaphore.sync_seqno[idx]; | ||
| 995 | } | 1017 | } |
| 996 | } | 1018 | } |
| 997 | 1019 | ||
| @@ -1002,14 +1024,9 @@ static void gen6_record_semaphore_state(struct intel_engine_cs *engine, | |||
| 1002 | 1024 | ||
| 1003 | ee->semaphore_mboxes[0] = I915_READ(RING_SYNC_0(engine->mmio_base)); | 1025 | ee->semaphore_mboxes[0] = I915_READ(RING_SYNC_0(engine->mmio_base)); |
| 1004 | ee->semaphore_mboxes[1] = I915_READ(RING_SYNC_1(engine->mmio_base)); | 1026 | ee->semaphore_mboxes[1] = I915_READ(RING_SYNC_1(engine->mmio_base)); |
| 1005 | ee->semaphore_seqno[0] = engine->semaphore.sync_seqno[0]; | 1027 | if (HAS_VEBOX(dev_priv)) |
| 1006 | ee->semaphore_seqno[1] = engine->semaphore.sync_seqno[1]; | ||
| 1007 | |||
| 1008 | if (HAS_VEBOX(dev_priv)) { | ||
| 1009 | ee->semaphore_mboxes[2] = | 1028 | ee->semaphore_mboxes[2] = |
| 1010 | I915_READ(RING_SYNC_2(engine->mmio_base)); | 1029 | I915_READ(RING_SYNC_2(engine->mmio_base)); |
| 1011 | ee->semaphore_seqno[2] = engine->semaphore.sync_seqno[2]; | ||
| 1012 | } | ||
| 1013 | } | 1030 | } |
| 1014 | 1031 | ||
| 1015 | static void error_record_engine_waiters(struct intel_engine_cs *engine, | 1032 | static void error_record_engine_waiters(struct intel_engine_cs *engine, |
| @@ -1026,7 +1043,7 @@ static void error_record_engine_waiters(struct intel_engine_cs *engine, | |||
| 1026 | if (RB_EMPTY_ROOT(&b->waiters)) | 1043 | if (RB_EMPTY_ROOT(&b->waiters)) |
| 1027 | return; | 1044 | return; |
| 1028 | 1045 | ||
| 1029 | if (!spin_trylock(&b->lock)) { | 1046 | if (!spin_trylock_irq(&b->lock)) { |
| 1030 | ee->waiters = ERR_PTR(-EDEADLK); | 1047 | ee->waiters = ERR_PTR(-EDEADLK); |
| 1031 | return; | 1048 | return; |
| 1032 | } | 1049 | } |
| @@ -1034,7 +1051,7 @@ static void error_record_engine_waiters(struct intel_engine_cs *engine, | |||
| 1034 | count = 0; | 1051 | count = 0; |
| 1035 | for (rb = rb_first(&b->waiters); rb != NULL; rb = rb_next(rb)) | 1052 | for (rb = rb_first(&b->waiters); rb != NULL; rb = rb_next(rb)) |
| 1036 | count++; | 1053 | count++; |
| 1037 | spin_unlock(&b->lock); | 1054 | spin_unlock_irq(&b->lock); |
| 1038 | 1055 | ||
| 1039 | waiter = NULL; | 1056 | waiter = NULL; |
| 1040 | if (count) | 1057 | if (count) |
| @@ -1044,7 +1061,7 @@ static void error_record_engine_waiters(struct intel_engine_cs *engine, | |||
| 1044 | if (!waiter) | 1061 | if (!waiter) |
| 1045 | return; | 1062 | return; |
| 1046 | 1063 | ||
| 1047 | if (!spin_trylock(&b->lock)) { | 1064 | if (!spin_trylock_irq(&b->lock)) { |
| 1048 | kfree(waiter); | 1065 | kfree(waiter); |
| 1049 | ee->waiters = ERR_PTR(-EDEADLK); | 1066 | ee->waiters = ERR_PTR(-EDEADLK); |
| 1050 | return; | 1067 | return; |
| @@ -1062,7 +1079,7 @@ static void error_record_engine_waiters(struct intel_engine_cs *engine, | |||
| 1062 | if (++ee->num_waiters == count) | 1079 | if (++ee->num_waiters == count) |
| 1063 | break; | 1080 | break; |
| 1064 | } | 1081 | } |
| 1065 | spin_unlock(&b->lock); | 1082 | spin_unlock_irq(&b->lock); |
| 1066 | } | 1083 | } |
| 1067 | 1084 | ||
| 1068 | static void error_record_engine_registers(struct drm_i915_error_state *error, | 1085 | static void error_record_engine_registers(struct drm_i915_error_state *error, |
| @@ -1103,7 +1120,7 @@ static void error_record_engine_registers(struct drm_i915_error_state *error, | |||
| 1103 | ee->instpm = I915_READ(RING_INSTPM(engine->mmio_base)); | 1120 | ee->instpm = I915_READ(RING_INSTPM(engine->mmio_base)); |
| 1104 | ee->acthd = intel_engine_get_active_head(engine); | 1121 | ee->acthd = intel_engine_get_active_head(engine); |
| 1105 | ee->seqno = intel_engine_get_seqno(engine); | 1122 | ee->seqno = intel_engine_get_seqno(engine); |
| 1106 | ee->last_seqno = engine->last_submitted_seqno; | 1123 | ee->last_seqno = intel_engine_last_submit(engine); |
| 1107 | ee->start = I915_READ_START(engine); | 1124 | ee->start = I915_READ_START(engine); |
| 1108 | ee->head = I915_READ_HEAD(engine); | 1125 | ee->head = I915_READ_HEAD(engine); |
| 1109 | ee->tail = I915_READ_TAIL(engine); | 1126 | ee->tail = I915_READ_TAIL(engine); |
| @@ -1169,7 +1186,7 @@ static void record_request(struct drm_i915_gem_request *request, | |||
| 1169 | struct drm_i915_error_request *erq) | 1186 | struct drm_i915_error_request *erq) |
| 1170 | { | 1187 | { |
| 1171 | erq->context = request->ctx->hw_id; | 1188 | erq->context = request->ctx->hw_id; |
| 1172 | erq->seqno = request->fence.seqno; | 1189 | erq->seqno = request->global_seqno; |
| 1173 | erq->jiffies = request->emitted_jiffies; | 1190 | erq->jiffies = request->emitted_jiffies; |
| 1174 | erq->head = request->head; | 1191 | erq->head = request->head; |
| 1175 | erq->tail = request->tail; | 1192 | erq->tail = request->tail; |
| @@ -1188,7 +1205,7 @@ static void engine_record_requests(struct intel_engine_cs *engine, | |||
| 1188 | 1205 | ||
| 1189 | count = 0; | 1206 | count = 0; |
| 1190 | request = first; | 1207 | request = first; |
| 1191 | list_for_each_entry_from(request, &engine->request_list, link) | 1208 | list_for_each_entry_from(request, &engine->timeline->requests, link) |
| 1192 | count++; | 1209 | count++; |
| 1193 | if (!count) | 1210 | if (!count) |
| 1194 | return; | 1211 | return; |
| @@ -1201,7 +1218,7 @@ static void engine_record_requests(struct intel_engine_cs *engine, | |||
| 1201 | 1218 | ||
| 1202 | count = 0; | 1219 | count = 0; |
| 1203 | request = first; | 1220 | request = first; |
| 1204 | list_for_each_entry_from(request, &engine->request_list, link) { | 1221 | list_for_each_entry_from(request, &engine->timeline->requests, link) { |
| 1205 | if (count >= ee->num_requests) { | 1222 | if (count >= ee->num_requests) { |
| 1206 | /* | 1223 | /* |
| 1207 | * If the ring request list was changed in | 1224 | * If the ring request list was changed in |
| @@ -1408,6 +1425,17 @@ static void i915_capture_pinned_buffers(struct drm_i915_private *dev_priv, | |||
| 1408 | error->pinned_bo = bo; | 1425 | error->pinned_bo = bo; |
| 1409 | } | 1426 | } |
| 1410 | 1427 | ||
| 1428 | static void i915_gem_capture_guc_log_buffer(struct drm_i915_private *dev_priv, | ||
| 1429 | struct drm_i915_error_state *error) | ||
| 1430 | { | ||
| 1431 | /* Capturing log buf contents won't be useful if logging was disabled */ | ||
| 1432 | if (!dev_priv->guc.log.vma || (i915.guc_log_level < 0)) | ||
| 1433 | return; | ||
| 1434 | |||
| 1435 | error->guc_log = i915_error_object_create(dev_priv, | ||
| 1436 | dev_priv->guc.log.vma); | ||
| 1437 | } | ||
| 1438 | |||
| 1411 | /* Capture all registers which don't fit into another category. */ | 1439 | /* Capture all registers which don't fit into another category. */ |
| 1412 | static void i915_capture_reg_state(struct drm_i915_private *dev_priv, | 1440 | static void i915_capture_reg_state(struct drm_i915_private *dev_priv, |
| 1413 | struct drm_i915_error_state *error) | 1441 | struct drm_i915_error_state *error) |
| @@ -1532,8 +1560,13 @@ static int capture(void *data) | |||
| 1532 | i915_gem_record_rings(error->i915, error); | 1560 | i915_gem_record_rings(error->i915, error); |
| 1533 | i915_capture_active_buffers(error->i915, error); | 1561 | i915_capture_active_buffers(error->i915, error); |
| 1534 | i915_capture_pinned_buffers(error->i915, error); | 1562 | i915_capture_pinned_buffers(error->i915, error); |
| 1563 | i915_gem_capture_guc_log_buffer(error->i915, error); | ||
| 1535 | 1564 | ||
| 1536 | do_gettimeofday(&error->time); | 1565 | do_gettimeofday(&error->time); |
| 1566 | error->boottime = ktime_to_timeval(ktime_get_boottime()); | ||
| 1567 | error->uptime = | ||
| 1568 | ktime_to_timeval(ktime_sub(ktime_get(), | ||
| 1569 | error->i915->gt.last_init_time)); | ||
| 1537 | 1570 | ||
| 1538 | error->overlay = intel_overlay_capture_error_state(error->i915); | 1571 | error->overlay = intel_overlay_capture_error_state(error->i915); |
| 1539 | error->display = intel_display_capture_error_state(error->i915); | 1572 | error->display = intel_display_capture_error_state(error->i915); |
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index a1f76c8f8cde..666dab7a675a 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c | |||
| @@ -23,6 +23,8 @@ | |||
| 23 | */ | 23 | */ |
| 24 | #include <linux/firmware.h> | 24 | #include <linux/firmware.h> |
| 25 | #include <linux/circ_buf.h> | 25 | #include <linux/circ_buf.h> |
| 26 | #include <linux/debugfs.h> | ||
| 27 | #include <linux/relay.h> | ||
| 26 | #include "i915_drv.h" | 28 | #include "i915_drv.h" |
| 27 | #include "intel_guc.h" | 29 | #include "intel_guc.h" |
| 28 | 30 | ||
| @@ -85,6 +87,7 @@ static int host2guc_action(struct intel_guc *guc, u32 *data, u32 len) | |||
| 85 | if (WARN_ON(len < 1 || len > 15)) | 87 | if (WARN_ON(len < 1 || len > 15)) |
| 86 | return -EINVAL; | 88 | return -EINVAL; |
| 87 | 89 | ||
| 90 | mutex_lock(&guc->action_lock); | ||
| 88 | intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); | 91 | intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
| 89 | 92 | ||
| 90 | dev_priv->guc.action_count += 1; | 93 | dev_priv->guc.action_count += 1; |
| @@ -123,6 +126,7 @@ static int host2guc_action(struct intel_guc *guc, u32 *data, u32 len) | |||
| 123 | dev_priv->guc.action_status = status; | 126 | dev_priv->guc.action_status = status; |
| 124 | 127 | ||
| 125 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); | 128 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
| 129 | mutex_unlock(&guc->action_lock); | ||
| 126 | 130 | ||
| 127 | return ret; | 131 | return ret; |
| 128 | } | 132 | } |
| @@ -170,6 +174,35 @@ static int host2guc_sample_forcewake(struct intel_guc *guc, | |||
| 170 | return host2guc_action(guc, data, ARRAY_SIZE(data)); | 174 | return host2guc_action(guc, data, ARRAY_SIZE(data)); |
| 171 | } | 175 | } |
| 172 | 176 | ||
| 177 | static int host2guc_logbuffer_flush_complete(struct intel_guc *guc) | ||
| 178 | { | ||
| 179 | u32 data[1]; | ||
| 180 | |||
| 181 | data[0] = HOST2GUC_ACTION_LOG_BUFFER_FILE_FLUSH_COMPLETE; | ||
| 182 | |||
| 183 | return host2guc_action(guc, data, 1); | ||
| 184 | } | ||
| 185 | |||
| 186 | static int host2guc_force_logbuffer_flush(struct intel_guc *guc) | ||
| 187 | { | ||
| 188 | u32 data[2]; | ||
| 189 | |||
| 190 | data[0] = HOST2GUC_ACTION_FORCE_LOG_BUFFER_FLUSH; | ||
| 191 | data[1] = 0; | ||
| 192 | |||
| 193 | return host2guc_action(guc, data, 2); | ||
| 194 | } | ||
| 195 | |||
| 196 | static int host2guc_logging_control(struct intel_guc *guc, u32 control_val) | ||
| 197 | { | ||
| 198 | u32 data[2]; | ||
| 199 | |||
| 200 | data[0] = HOST2GUC_ACTION_UK_LOG_ENABLE_LOGGING; | ||
| 201 | data[1] = control_val; | ||
| 202 | |||
| 203 | return host2guc_action(guc, data, 2); | ||
| 204 | } | ||
| 205 | |||
| 173 | /* | 206 | /* |
| 174 | * Initialise, update, or clear doorbell data shared with the GuC | 207 | * Initialise, update, or clear doorbell data shared with the GuC |
| 175 | * | 208 | * |
| @@ -187,7 +220,7 @@ static int guc_update_doorbell_id(struct intel_guc *guc, | |||
| 187 | struct guc_context_desc desc; | 220 | struct guc_context_desc desc; |
| 188 | size_t len; | 221 | size_t len; |
| 189 | 222 | ||
| 190 | doorbell = client->client_base + client->doorbell_offset; | 223 | doorbell = client->vaddr + client->doorbell_offset; |
| 191 | 224 | ||
| 192 | if (client->doorbell_id != GUC_INVALID_DOORBELL_ID && | 225 | if (client->doorbell_id != GUC_INVALID_DOORBELL_ID && |
| 193 | test_bit(client->doorbell_id, doorbell_bitmap)) { | 226 | test_bit(client->doorbell_id, doorbell_bitmap)) { |
| @@ -293,7 +326,7 @@ static void guc_proc_desc_init(struct intel_guc *guc, | |||
| 293 | { | 326 | { |
| 294 | struct guc_process_desc *desc; | 327 | struct guc_process_desc *desc; |
| 295 | 328 | ||
| 296 | desc = client->client_base + client->proc_desc_offset; | 329 | desc = client->vaddr + client->proc_desc_offset; |
| 297 | 330 | ||
| 298 | memset(desc, 0, sizeof(*desc)); | 331 | memset(desc, 0, sizeof(*desc)); |
| 299 | 332 | ||
| @@ -380,8 +413,8 @@ static void guc_ctx_desc_init(struct intel_guc *guc, | |||
| 380 | gfx_addr = i915_ggtt_offset(client->vma); | 413 | gfx_addr = i915_ggtt_offset(client->vma); |
| 381 | desc.db_trigger_phy = sg_dma_address(client->vma->pages->sgl) + | 414 | desc.db_trigger_phy = sg_dma_address(client->vma->pages->sgl) + |
| 382 | client->doorbell_offset; | 415 | client->doorbell_offset; |
| 383 | desc.db_trigger_cpu = (uintptr_t)client->client_base + | 416 | desc.db_trigger_cpu = |
| 384 | client->doorbell_offset; | 417 | (uintptr_t)client->vaddr + client->doorbell_offset; |
| 385 | desc.db_trigger_uk = gfx_addr + client->doorbell_offset; | 418 | desc.db_trigger_uk = gfx_addr + client->doorbell_offset; |
| 386 | desc.process_desc = gfx_addr + client->proc_desc_offset; | 419 | desc.process_desc = gfx_addr + client->proc_desc_offset; |
| 387 | desc.wq_addr = gfx_addr + client->wq_offset; | 420 | desc.wq_addr = gfx_addr + client->wq_offset; |
| @@ -432,7 +465,7 @@ int i915_guc_wq_reserve(struct drm_i915_gem_request *request) | |||
| 432 | { | 465 | { |
| 433 | const size_t wqi_size = sizeof(struct guc_wq_item); | 466 | const size_t wqi_size = sizeof(struct guc_wq_item); |
| 434 | struct i915_guc_client *gc = request->i915->guc.execbuf_client; | 467 | struct i915_guc_client *gc = request->i915->guc.execbuf_client; |
| 435 | struct guc_process_desc *desc = gc->client_base + gc->proc_desc_offset; | 468 | struct guc_process_desc *desc = gc->vaddr + gc->proc_desc_offset; |
| 436 | u32 freespace; | 469 | u32 freespace; |
| 437 | int ret; | 470 | int ret; |
| 438 | 471 | ||
| @@ -473,10 +506,9 @@ static void guc_wq_item_append(struct i915_guc_client *gc, | |||
| 473 | struct intel_engine_cs *engine = rq->engine; | 506 | struct intel_engine_cs *engine = rq->engine; |
| 474 | struct guc_process_desc *desc; | 507 | struct guc_process_desc *desc; |
| 475 | struct guc_wq_item *wqi; | 508 | struct guc_wq_item *wqi; |
| 476 | void *base; | 509 | u32 freespace, tail, wq_off; |
| 477 | u32 freespace, tail, wq_off, wq_page; | ||
| 478 | 510 | ||
| 479 | desc = gc->client_base + gc->proc_desc_offset; | 511 | desc = gc->vaddr + gc->proc_desc_offset; |
| 480 | 512 | ||
| 481 | /* Free space is guaranteed, see i915_guc_wq_reserve() above */ | 513 | /* Free space is guaranteed, see i915_guc_wq_reserve() above */ |
| 482 | freespace = CIRC_SPACE(gc->wq_tail, desc->head, gc->wq_size); | 514 | freespace = CIRC_SPACE(gc->wq_tail, desc->head, gc->wq_size); |
| @@ -506,10 +538,7 @@ static void guc_wq_item_append(struct i915_guc_client *gc, | |||
| 506 | gc->wq_rsvd -= wqi_size; | 538 | gc->wq_rsvd -= wqi_size; |
| 507 | 539 | ||
| 508 | /* WQ starts from the page after doorbell / process_desc */ | 540 | /* WQ starts from the page after doorbell / process_desc */ |
| 509 | wq_page = (wq_off + GUC_DB_SIZE) >> PAGE_SHIFT; | 541 | wqi = gc->vaddr + wq_off + GUC_DB_SIZE; |
| 510 | wq_off &= PAGE_SIZE - 1; | ||
| 511 | base = kmap_atomic(i915_gem_object_get_page(gc->vma->obj, wq_page)); | ||
| 512 | wqi = (struct guc_wq_item *)((char *)base + wq_off); | ||
| 513 | 542 | ||
| 514 | /* Now fill in the 4-word work queue item */ | 543 | /* Now fill in the 4-word work queue item */ |
| 515 | wqi->header = WQ_TYPE_INORDER | | 544 | wqi->header = WQ_TYPE_INORDER | |
| @@ -521,9 +550,7 @@ static void guc_wq_item_append(struct i915_guc_client *gc, | |||
| 521 | wqi->context_desc = (u32)intel_lr_context_descriptor(rq->ctx, engine); | 550 | wqi->context_desc = (u32)intel_lr_context_descriptor(rq->ctx, engine); |
| 522 | 551 | ||
| 523 | wqi->ring_tail = tail << WQ_RING_TAIL_SHIFT; | 552 | wqi->ring_tail = tail << WQ_RING_TAIL_SHIFT; |
| 524 | wqi->fence_id = rq->fence.seqno; | 553 | wqi->fence_id = rq->global_seqno; |
| 525 | |||
| 526 | kunmap_atomic(base); | ||
| 527 | } | 554 | } |
| 528 | 555 | ||
| 529 | static int guc_ring_doorbell(struct i915_guc_client *gc) | 556 | static int guc_ring_doorbell(struct i915_guc_client *gc) |
| @@ -533,7 +560,7 @@ static int guc_ring_doorbell(struct i915_guc_client *gc) | |||
| 533 | union guc_doorbell_qw *db; | 560 | union guc_doorbell_qw *db; |
| 534 | int attempt = 2, ret = -EAGAIN; | 561 | int attempt = 2, ret = -EAGAIN; |
| 535 | 562 | ||
| 536 | desc = gc->client_base + gc->proc_desc_offset; | 563 | desc = gc->vaddr + gc->proc_desc_offset; |
| 537 | 564 | ||
| 538 | /* Update the tail so it is visible to GuC */ | 565 | /* Update the tail so it is visible to GuC */ |
| 539 | desc->tail = gc->wq_tail; | 566 | desc->tail = gc->wq_tail; |
| @@ -549,7 +576,7 @@ static int guc_ring_doorbell(struct i915_guc_client *gc) | |||
| 549 | db_exc.cookie = 1; | 576 | db_exc.cookie = 1; |
| 550 | 577 | ||
| 551 | /* pointer of current doorbell cacheline */ | 578 | /* pointer of current doorbell cacheline */ |
| 552 | db = gc->client_base + gc->doorbell_offset; | 579 | db = gc->vaddr + gc->doorbell_offset; |
| 553 | 580 | ||
| 554 | while (attempt--) { | 581 | while (attempt--) { |
| 555 | /* lets ring the doorbell */ | 582 | /* lets ring the doorbell */ |
| @@ -601,6 +628,7 @@ static int guc_ring_doorbell(struct i915_guc_client *gc) | |||
| 601 | */ | 628 | */ |
| 602 | static void i915_guc_submit(struct drm_i915_gem_request *rq) | 629 | static void i915_guc_submit(struct drm_i915_gem_request *rq) |
| 603 | { | 630 | { |
| 631 | struct drm_i915_private *dev_priv = rq->i915; | ||
| 604 | unsigned int engine_id = rq->engine->id; | 632 | unsigned int engine_id = rq->engine->id; |
| 605 | struct intel_guc *guc = &rq->i915->guc; | 633 | struct intel_guc *guc = &rq->i915->guc; |
| 606 | struct i915_guc_client *client = guc->execbuf_client; | 634 | struct i915_guc_client *client = guc->execbuf_client; |
| @@ -608,6 +636,11 @@ static void i915_guc_submit(struct drm_i915_gem_request *rq) | |||
| 608 | 636 | ||
| 609 | spin_lock(&client->wq_lock); | 637 | spin_lock(&client->wq_lock); |
| 610 | guc_wq_item_append(client, rq); | 638 | guc_wq_item_append(client, rq); |
| 639 | |||
| 640 | /* WA to flush out the pending GMADR writes to ring buffer. */ | ||
| 641 | if (i915_vma_is_map_and_fenceable(rq->ring->vma)) | ||
| 642 | POSTING_READ_FW(GUC_STATUS); | ||
| 643 | |||
| 611 | b_ret = guc_ring_doorbell(client); | 644 | b_ret = guc_ring_doorbell(client); |
| 612 | 645 | ||
| 613 | client->submissions[engine_id] += 1; | 646 | client->submissions[engine_id] += 1; |
| @@ -616,7 +649,7 @@ static void i915_guc_submit(struct drm_i915_gem_request *rq) | |||
| 616 | client->b_fail += 1; | 649 | client->b_fail += 1; |
| 617 | 650 | ||
| 618 | guc->submissions[engine_id] += 1; | 651 | guc->submissions[engine_id] += 1; |
| 619 | guc->last_seqno[engine_id] = rq->fence.seqno; | 652 | guc->last_seqno[engine_id] = rq->global_seqno; |
| 620 | spin_unlock(&client->wq_lock); | 653 | spin_unlock(&client->wq_lock); |
| 621 | } | 654 | } |
| 622 | 655 | ||
| @@ -685,14 +718,14 @@ guc_client_free(struct drm_i915_private *dev_priv, | |||
| 685 | * Be sure to drop any locks | 718 | * Be sure to drop any locks |
| 686 | */ | 719 | */ |
| 687 | 720 | ||
| 688 | if (client->client_base) { | 721 | if (client->vaddr) { |
| 689 | /* | 722 | /* |
| 690 | * If we got as far as setting up a doorbell, make sure we | 723 | * If we got as far as setting up a doorbell, make sure we |
| 691 | * shut it down before unmapping & deallocating the memory. | 724 | * shut it down before unmapping & deallocating the memory. |
| 692 | */ | 725 | */ |
| 693 | guc_disable_doorbell(guc, client); | 726 | guc_disable_doorbell(guc, client); |
| 694 | 727 | ||
| 695 | kunmap(kmap_to_page(client->client_base)); | 728 | i915_gem_object_unpin_map(client->vma->obj); |
| 696 | } | 729 | } |
| 697 | 730 | ||
| 698 | i915_vma_unpin_and_release(&client->vma); | 731 | i915_vma_unpin_and_release(&client->vma); |
| @@ -781,6 +814,7 @@ guc_client_alloc(struct drm_i915_private *dev_priv, | |||
| 781 | struct i915_guc_client *client; | 814 | struct i915_guc_client *client; |
| 782 | struct intel_guc *guc = &dev_priv->guc; | 815 | struct intel_guc *guc = &dev_priv->guc; |
| 783 | struct i915_vma *vma; | 816 | struct i915_vma *vma; |
| 817 | void *vaddr; | ||
| 784 | uint16_t db_id; | 818 | uint16_t db_id; |
| 785 | 819 | ||
| 786 | client = kzalloc(sizeof(*client), GFP_KERNEL); | 820 | client = kzalloc(sizeof(*client), GFP_KERNEL); |
| @@ -807,7 +841,12 @@ guc_client_alloc(struct drm_i915_private *dev_priv, | |||
| 807 | 841 | ||
| 808 | /* We'll keep just the first (doorbell/proc) page permanently kmap'd. */ | 842 | /* We'll keep just the first (doorbell/proc) page permanently kmap'd. */ |
| 809 | client->vma = vma; | 843 | client->vma = vma; |
| 810 | client->client_base = kmap(i915_vma_first_page(vma)); | 844 | |
| 845 | vaddr = i915_gem_object_pin_map(vma->obj, I915_MAP_WB); | ||
| 846 | if (IS_ERR(vaddr)) | ||
| 847 | goto err; | ||
| 848 | |||
| 849 | client->vaddr = vaddr; | ||
| 811 | 850 | ||
| 812 | spin_lock_init(&client->wq_lock); | 851 | spin_lock_init(&client->wq_lock); |
| 813 | client->wq_offset = GUC_DB_SIZE; | 852 | client->wq_offset = GUC_DB_SIZE; |
| @@ -847,15 +886,411 @@ err: | |||
| 847 | return NULL; | 886 | return NULL; |
| 848 | } | 887 | } |
| 849 | 888 | ||
| 889 | /* | ||
| 890 | * Sub buffer switch callback. Called whenever relay has to switch to a new | ||
| 891 | * sub buffer, relay stays on the same sub buffer if 0 is returned. | ||
| 892 | */ | ||
| 893 | static int subbuf_start_callback(struct rchan_buf *buf, | ||
| 894 | void *subbuf, | ||
| 895 | void *prev_subbuf, | ||
| 896 | size_t prev_padding) | ||
| 897 | { | ||
| 898 | /* Use no-overwrite mode by default, where relay will stop accepting | ||
| 899 | * new data if there are no empty sub buffers left. | ||
| 900 | * There is no strict synchronization enforced by relay between Consumer | ||
| 901 | * and Producer. In overwrite mode, there is a possibility of getting | ||
| 902 | * inconsistent/garbled data, the producer could be writing on to the | ||
| 903 | * same sub buffer from which Consumer is reading. This can't be avoided | ||
| 904 | * unless Consumer is fast enough and can always run in tandem with | ||
| 905 | * Producer. | ||
| 906 | */ | ||
| 907 | if (relay_buf_full(buf)) | ||
| 908 | return 0; | ||
| 909 | |||
| 910 | return 1; | ||
| 911 | } | ||
| 912 | |||
| 913 | /* | ||
| 914 | * file_create() callback. Creates relay file in debugfs. | ||
| 915 | */ | ||
| 916 | static struct dentry *create_buf_file_callback(const char *filename, | ||
| 917 | struct dentry *parent, | ||
| 918 | umode_t mode, | ||
| 919 | struct rchan_buf *buf, | ||
| 920 | int *is_global) | ||
| 921 | { | ||
| 922 | struct dentry *buf_file; | ||
| 923 | |||
| 924 | /* This to enable the use of a single buffer for the relay channel and | ||
| 925 | * correspondingly have a single file exposed to User, through which | ||
| 926 | * it can collect the logs in order without any post-processing. | ||
| 927 | * Need to set 'is_global' even if parent is NULL for early logging. | ||
| 928 | */ | ||
| 929 | *is_global = 1; | ||
| 930 | |||
| 931 | if (!parent) | ||
| 932 | return NULL; | ||
| 933 | |||
| 934 | /* Not using the channel filename passed as an argument, since for each | ||
| 935 | * channel relay appends the corresponding CPU number to the filename | ||
| 936 | * passed in relay_open(). This should be fine as relay just needs a | ||
| 937 | * dentry of the file associated with the channel buffer and that file's | ||
| 938 | * name need not be same as the filename passed as an argument. | ||
| 939 | */ | ||
| 940 | buf_file = debugfs_create_file("guc_log", mode, | ||
| 941 | parent, buf, &relay_file_operations); | ||
| 942 | return buf_file; | ||
| 943 | } | ||
| 944 | |||
| 945 | /* | ||
| 946 | * file_remove() default callback. Removes relay file in debugfs. | ||
| 947 | */ | ||
| 948 | static int remove_buf_file_callback(struct dentry *dentry) | ||
| 949 | { | ||
| 950 | debugfs_remove(dentry); | ||
| 951 | return 0; | ||
| 952 | } | ||
| 953 | |||
| 954 | /* relay channel callbacks */ | ||
| 955 | static struct rchan_callbacks relay_callbacks = { | ||
| 956 | .subbuf_start = subbuf_start_callback, | ||
| 957 | .create_buf_file = create_buf_file_callback, | ||
| 958 | .remove_buf_file = remove_buf_file_callback, | ||
| 959 | }; | ||
| 960 | |||
| 961 | static void guc_log_remove_relay_file(struct intel_guc *guc) | ||
| 962 | { | ||
| 963 | relay_close(guc->log.relay_chan); | ||
| 964 | } | ||
| 965 | |||
| 966 | static int guc_log_create_relay_channel(struct intel_guc *guc) | ||
| 967 | { | ||
| 968 | struct drm_i915_private *dev_priv = guc_to_i915(guc); | ||
| 969 | struct rchan *guc_log_relay_chan; | ||
| 970 | size_t n_subbufs, subbuf_size; | ||
| 971 | |||
| 972 | /* Keep the size of sub buffers same as shared log buffer */ | ||
| 973 | subbuf_size = guc->log.vma->obj->base.size; | ||
| 974 | |||
| 975 | /* Store up to 8 snapshots, which is large enough to buffer sufficient | ||
| 976 | * boot time logs and provides enough leeway to User, in terms of | ||
| 977 | * latency, for consuming the logs from relay. Also doesn't take | ||
| 978 | * up too much memory. | ||
| 979 | */ | ||
| 980 | n_subbufs = 8; | ||
| 981 | |||
| 982 | guc_log_relay_chan = relay_open(NULL, NULL, subbuf_size, | ||
| 983 | n_subbufs, &relay_callbacks, dev_priv); | ||
| 984 | if (!guc_log_relay_chan) { | ||
| 985 | DRM_ERROR("Couldn't create relay chan for GuC logging\n"); | ||
| 986 | return -ENOMEM; | ||
| 987 | } | ||
| 988 | |||
| 989 | GEM_BUG_ON(guc_log_relay_chan->subbuf_size < subbuf_size); | ||
| 990 | guc->log.relay_chan = guc_log_relay_chan; | ||
| 991 | return 0; | ||
| 992 | } | ||
| 993 | |||
| 994 | static int guc_log_create_relay_file(struct intel_guc *guc) | ||
| 995 | { | ||
| 996 | struct drm_i915_private *dev_priv = guc_to_i915(guc); | ||
| 997 | struct dentry *log_dir; | ||
| 998 | int ret; | ||
| 999 | |||
| 1000 | /* For now create the log file in /sys/kernel/debug/dri/0 dir */ | ||
| 1001 | log_dir = dev_priv->drm.primary->debugfs_root; | ||
| 1002 | |||
| 1003 | /* If /sys/kernel/debug/dri/0 location do not exist, then debugfs is | ||
| 1004 | * not mounted and so can't create the relay file. | ||
| 1005 | * The relay API seems to fit well with debugfs only, for availing relay | ||
| 1006 | * there are 3 requirements which can be met for debugfs file only in a | ||
| 1007 | * straightforward/clean manner :- | ||
| 1008 | * i) Need the associated dentry pointer of the file, while opening the | ||
| 1009 | * relay channel. | ||
| 1010 | * ii) Should be able to use 'relay_file_operations' fops for the file. | ||
| 1011 | * iii) Set the 'i_private' field of file's inode to the pointer of | ||
| 1012 | * relay channel buffer. | ||
| 1013 | */ | ||
| 1014 | if (!log_dir) { | ||
| 1015 | DRM_ERROR("Debugfs dir not available yet for GuC log file\n"); | ||
| 1016 | return -ENODEV; | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | ret = relay_late_setup_files(guc->log.relay_chan, "guc_log", log_dir); | ||
| 1020 | if (ret) { | ||
| 1021 | DRM_ERROR("Couldn't associate relay chan with file %d\n", ret); | ||
| 1022 | return ret; | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | return 0; | ||
| 1026 | } | ||
| 1027 | |||
| 1028 | static void guc_move_to_next_buf(struct intel_guc *guc) | ||
| 1029 | { | ||
| 1030 | /* Make sure the updates made in the sub buffer are visible when | ||
| 1031 | * Consumer sees the following update to offset inside the sub buffer. | ||
| 1032 | */ | ||
| 1033 | smp_wmb(); | ||
| 1034 | |||
| 1035 | /* All data has been written, so now move the offset of sub buffer. */ | ||
| 1036 | relay_reserve(guc->log.relay_chan, guc->log.vma->obj->base.size); | ||
| 1037 | |||
| 1038 | /* Switch to the next sub buffer */ | ||
| 1039 | relay_flush(guc->log.relay_chan); | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | static void *guc_get_write_buffer(struct intel_guc *guc) | ||
| 1043 | { | ||
| 1044 | if (!guc->log.relay_chan) | ||
| 1045 | return NULL; | ||
| 1046 | |||
| 1047 | /* Just get the base address of a new sub buffer and copy data into it | ||
| 1048 | * ourselves. NULL will be returned in no-overwrite mode, if all sub | ||
| 1049 | * buffers are full. Could have used the relay_write() to indirectly | ||
| 1050 | * copy the data, but that would have been bit convoluted, as we need to | ||
| 1051 | * write to only certain locations inside a sub buffer which cannot be | ||
| 1052 | * done without using relay_reserve() along with relay_write(). So its | ||
| 1053 | * better to use relay_reserve() alone. | ||
| 1054 | */ | ||
| 1055 | return relay_reserve(guc->log.relay_chan, 0); | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | static bool | ||
| 1059 | guc_check_log_buf_overflow(struct intel_guc *guc, | ||
| 1060 | enum guc_log_buffer_type type, unsigned int full_cnt) | ||
| 1061 | { | ||
| 1062 | unsigned int prev_full_cnt = guc->log.prev_overflow_count[type]; | ||
| 1063 | bool overflow = false; | ||
| 1064 | |||
| 1065 | if (full_cnt != prev_full_cnt) { | ||
| 1066 | overflow = true; | ||
| 1067 | |||
| 1068 | guc->log.prev_overflow_count[type] = full_cnt; | ||
| 1069 | guc->log.total_overflow_count[type] += full_cnt - prev_full_cnt; | ||
| 1070 | |||
| 1071 | if (full_cnt < prev_full_cnt) { | ||
| 1072 | /* buffer_full_cnt is a 4 bit counter */ | ||
| 1073 | guc->log.total_overflow_count[type] += 16; | ||
| 1074 | } | ||
| 1075 | DRM_ERROR_RATELIMITED("GuC log buffer overflow\n"); | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | return overflow; | ||
| 1079 | } | ||
| 1080 | |||
| 1081 | static unsigned int guc_get_log_buffer_size(enum guc_log_buffer_type type) | ||
| 1082 | { | ||
| 1083 | switch (type) { | ||
| 1084 | case GUC_ISR_LOG_BUFFER: | ||
| 1085 | return (GUC_LOG_ISR_PAGES + 1) * PAGE_SIZE; | ||
| 1086 | case GUC_DPC_LOG_BUFFER: | ||
| 1087 | return (GUC_LOG_DPC_PAGES + 1) * PAGE_SIZE; | ||
| 1088 | case GUC_CRASH_DUMP_LOG_BUFFER: | ||
| 1089 | return (GUC_LOG_CRASH_PAGES + 1) * PAGE_SIZE; | ||
| 1090 | default: | ||
| 1091 | MISSING_CASE(type); | ||
| 1092 | } | ||
| 1093 | |||
| 1094 | return 0; | ||
| 1095 | } | ||
| 1096 | |||
| 1097 | static void guc_read_update_log_buffer(struct intel_guc *guc) | ||
| 1098 | { | ||
| 1099 | unsigned int buffer_size, read_offset, write_offset, bytes_to_copy, full_cnt; | ||
| 1100 | struct guc_log_buffer_state *log_buf_state, *log_buf_snapshot_state; | ||
| 1101 | struct guc_log_buffer_state log_buf_state_local; | ||
| 1102 | enum guc_log_buffer_type type; | ||
| 1103 | void *src_data, *dst_data; | ||
| 1104 | bool new_overflow; | ||
| 1105 | |||
| 1106 | if (WARN_ON(!guc->log.buf_addr)) | ||
| 1107 | return; | ||
| 1108 | |||
| 1109 | /* Get the pointer to shared GuC log buffer */ | ||
| 1110 | log_buf_state = src_data = guc->log.buf_addr; | ||
| 1111 | |||
| 1112 | /* Get the pointer to local buffer to store the logs */ | ||
| 1113 | log_buf_snapshot_state = dst_data = guc_get_write_buffer(guc); | ||
| 1114 | |||
| 1115 | /* Actual logs are present from the 2nd page */ | ||
| 1116 | src_data += PAGE_SIZE; | ||
| 1117 | dst_data += PAGE_SIZE; | ||
| 1118 | |||
| 1119 | for (type = GUC_ISR_LOG_BUFFER; type < GUC_MAX_LOG_BUFFER; type++) { | ||
| 1120 | /* Make a copy of the state structure, inside GuC log buffer | ||
| 1121 | * (which is uncached mapped), on the stack to avoid reading | ||
| 1122 | * from it multiple times. | ||
| 1123 | */ | ||
| 1124 | memcpy(&log_buf_state_local, log_buf_state, | ||
| 1125 | sizeof(struct guc_log_buffer_state)); | ||
| 1126 | buffer_size = guc_get_log_buffer_size(type); | ||
| 1127 | read_offset = log_buf_state_local.read_ptr; | ||
| 1128 | write_offset = log_buf_state_local.sampled_write_ptr; | ||
| 1129 | full_cnt = log_buf_state_local.buffer_full_cnt; | ||
| 1130 | |||
| 1131 | /* Bookkeeping stuff */ | ||
| 1132 | guc->log.flush_count[type] += log_buf_state_local.flush_to_file; | ||
| 1133 | new_overflow = guc_check_log_buf_overflow(guc, type, full_cnt); | ||
| 1134 | |||
| 1135 | /* Update the state of shared log buffer */ | ||
| 1136 | log_buf_state->read_ptr = write_offset; | ||
| 1137 | log_buf_state->flush_to_file = 0; | ||
| 1138 | log_buf_state++; | ||
| 1139 | |||
| 1140 | if (unlikely(!log_buf_snapshot_state)) | ||
| 1141 | continue; | ||
| 1142 | |||
| 1143 | /* First copy the state structure in snapshot buffer */ | ||
| 1144 | memcpy(log_buf_snapshot_state, &log_buf_state_local, | ||
| 1145 | sizeof(struct guc_log_buffer_state)); | ||
| 1146 | |||
| 1147 | /* The write pointer could have been updated by GuC firmware, | ||
| 1148 | * after sending the flush interrupt to Host, for consistency | ||
| 1149 | * set write pointer value to same value of sampled_write_ptr | ||
| 1150 | * in the snapshot buffer. | ||
| 1151 | */ | ||
| 1152 | log_buf_snapshot_state->write_ptr = write_offset; | ||
| 1153 | log_buf_snapshot_state++; | ||
| 1154 | |||
| 1155 | /* Now copy the actual logs. */ | ||
| 1156 | if (unlikely(new_overflow)) { | ||
| 1157 | /* copy the whole buffer in case of overflow */ | ||
| 1158 | read_offset = 0; | ||
| 1159 | write_offset = buffer_size; | ||
| 1160 | } else if (unlikely((read_offset > buffer_size) || | ||
| 1161 | (write_offset > buffer_size))) { | ||
| 1162 | DRM_ERROR("invalid log buffer state\n"); | ||
| 1163 | /* copy whole buffer as offsets are unreliable */ | ||
| 1164 | read_offset = 0; | ||
| 1165 | write_offset = buffer_size; | ||
| 1166 | } | ||
| 1167 | |||
| 1168 | /* Just copy the newly written data */ | ||
| 1169 | if (read_offset > write_offset) { | ||
| 1170 | i915_memcpy_from_wc(dst_data, src_data, write_offset); | ||
| 1171 | bytes_to_copy = buffer_size - read_offset; | ||
| 1172 | } else { | ||
| 1173 | bytes_to_copy = write_offset - read_offset; | ||
| 1174 | } | ||
| 1175 | i915_memcpy_from_wc(dst_data + read_offset, | ||
| 1176 | src_data + read_offset, bytes_to_copy); | ||
| 1177 | |||
| 1178 | src_data += buffer_size; | ||
| 1179 | dst_data += buffer_size; | ||
| 1180 | } | ||
| 1181 | |||
| 1182 | if (log_buf_snapshot_state) | ||
| 1183 | guc_move_to_next_buf(guc); | ||
| 1184 | else { | ||
| 1185 | /* Used rate limited to avoid deluge of messages, logs might be | ||
| 1186 | * getting consumed by User at a slow rate. | ||
| 1187 | */ | ||
| 1188 | DRM_ERROR_RATELIMITED("no sub-buffer to capture logs\n"); | ||
| 1189 | guc->log.capture_miss_count++; | ||
| 1190 | } | ||
| 1191 | } | ||
| 1192 | |||
| 1193 | static void guc_capture_logs_work(struct work_struct *work) | ||
| 1194 | { | ||
| 1195 | struct drm_i915_private *dev_priv = | ||
| 1196 | container_of(work, struct drm_i915_private, guc.log.flush_work); | ||
| 1197 | |||
| 1198 | i915_guc_capture_logs(dev_priv); | ||
| 1199 | } | ||
| 1200 | |||
| 1201 | static void guc_log_cleanup(struct intel_guc *guc) | ||
| 1202 | { | ||
| 1203 | struct drm_i915_private *dev_priv = guc_to_i915(guc); | ||
| 1204 | |||
| 1205 | lockdep_assert_held(&dev_priv->drm.struct_mutex); | ||
| 1206 | |||
| 1207 | /* First disable the flush interrupt */ | ||
| 1208 | gen9_disable_guc_interrupts(dev_priv); | ||
| 1209 | |||
| 1210 | if (guc->log.flush_wq) | ||
| 1211 | destroy_workqueue(guc->log.flush_wq); | ||
| 1212 | |||
| 1213 | guc->log.flush_wq = NULL; | ||
| 1214 | |||
| 1215 | if (guc->log.relay_chan) | ||
| 1216 | guc_log_remove_relay_file(guc); | ||
| 1217 | |||
| 1218 | guc->log.relay_chan = NULL; | ||
| 1219 | |||
| 1220 | if (guc->log.buf_addr) | ||
| 1221 | i915_gem_object_unpin_map(guc->log.vma->obj); | ||
| 1222 | |||
| 1223 | guc->log.buf_addr = NULL; | ||
| 1224 | } | ||
| 1225 | |||
| 1226 | static int guc_log_create_extras(struct intel_guc *guc) | ||
| 1227 | { | ||
| 1228 | struct drm_i915_private *dev_priv = guc_to_i915(guc); | ||
| 1229 | void *vaddr; | ||
| 1230 | int ret; | ||
| 1231 | |||
| 1232 | lockdep_assert_held(&dev_priv->drm.struct_mutex); | ||
| 1233 | |||
| 1234 | /* Nothing to do */ | ||
| 1235 | if (i915.guc_log_level < 0) | ||
| 1236 | return 0; | ||
| 1237 | |||
| 1238 | if (!guc->log.buf_addr) { | ||
| 1239 | /* Create a WC (Uncached for read) vmalloc mapping of log | ||
| 1240 | * buffer pages, so that we can directly get the data | ||
| 1241 | * (up-to-date) from memory. | ||
| 1242 | */ | ||
| 1243 | vaddr = i915_gem_object_pin_map(guc->log.vma->obj, I915_MAP_WC); | ||
| 1244 | if (IS_ERR(vaddr)) { | ||
| 1245 | ret = PTR_ERR(vaddr); | ||
| 1246 | DRM_ERROR("Couldn't map log buffer pages %d\n", ret); | ||
| 1247 | return ret; | ||
| 1248 | } | ||
| 1249 | |||
| 1250 | guc->log.buf_addr = vaddr; | ||
| 1251 | } | ||
| 1252 | |||
| 1253 | if (!guc->log.relay_chan) { | ||
| 1254 | /* Create a relay channel, so that we have buffers for storing | ||
| 1255 | * the GuC firmware logs, the channel will be linked with a file | ||
| 1256 | * later on when debugfs is registered. | ||
| 1257 | */ | ||
| 1258 | ret = guc_log_create_relay_channel(guc); | ||
| 1259 | if (ret) | ||
| 1260 | return ret; | ||
| 1261 | } | ||
| 1262 | |||
| 1263 | if (!guc->log.flush_wq) { | ||
| 1264 | INIT_WORK(&guc->log.flush_work, guc_capture_logs_work); | ||
| 1265 | |||
| 1266 | /* | ||
| 1267 | * GuC log buffer flush work item has to do register access to | ||
| 1268 | * send the ack to GuC and this work item, if not synced before | ||
| 1269 | * suspend, can potentially get executed after the GFX device is | ||
| 1270 | * suspended. | ||
| 1271 | * By marking the WQ as freezable, we don't have to bother about | ||
| 1272 | * flushing of this work item from the suspend hooks, the pending | ||
| 1273 | * work item if any will be either executed before the suspend | ||
| 1274 | * or scheduled later on resume. This way the handling of work | ||
| 1275 | * item can be kept same between system suspend & rpm suspend. | ||
| 1276 | */ | ||
| 1277 | guc->log.flush_wq = alloc_ordered_workqueue("i915-guc_log", | ||
| 1278 | WQ_HIGHPRI | WQ_FREEZABLE); | ||
| 1279 | if (guc->log.flush_wq == NULL) { | ||
| 1280 | DRM_ERROR("Couldn't allocate the wq for GuC logging\n"); | ||
| 1281 | return -ENOMEM; | ||
| 1282 | } | ||
| 1283 | } | ||
| 1284 | |||
| 1285 | return 0; | ||
| 1286 | } | ||
| 1287 | |||
| 850 | static void guc_log_create(struct intel_guc *guc) | 1288 | static void guc_log_create(struct intel_guc *guc) |
| 851 | { | 1289 | { |
| 852 | struct i915_vma *vma; | 1290 | struct i915_vma *vma; |
| 853 | unsigned long offset; | 1291 | unsigned long offset; |
| 854 | uint32_t size, flags; | 1292 | uint32_t size, flags; |
| 855 | 1293 | ||
| 856 | if (i915.guc_log_level < GUC_LOG_VERBOSITY_MIN) | ||
| 857 | return; | ||
| 858 | |||
| 859 | if (i915.guc_log_level > GUC_LOG_VERBOSITY_MAX) | 1294 | if (i915.guc_log_level > GUC_LOG_VERBOSITY_MAX) |
| 860 | i915.guc_log_level = GUC_LOG_VERBOSITY_MAX; | 1295 | i915.guc_log_level = GUC_LOG_VERBOSITY_MAX; |
| 861 | 1296 | ||
| @@ -865,8 +1300,18 @@ static void guc_log_create(struct intel_guc *guc) | |||
| 865 | GUC_LOG_ISR_PAGES + 1 + | 1300 | GUC_LOG_ISR_PAGES + 1 + |
| 866 | GUC_LOG_CRASH_PAGES + 1) << PAGE_SHIFT; | 1301 | GUC_LOG_CRASH_PAGES + 1) << PAGE_SHIFT; |
| 867 | 1302 | ||
| 868 | vma = guc->log_vma; | 1303 | vma = guc->log.vma; |
| 869 | if (!vma) { | 1304 | if (!vma) { |
| 1305 | /* We require SSE 4.1 for fast reads from the GuC log buffer and | ||
| 1306 | * it should be present on the chipsets supporting GuC based | ||
| 1307 | * submisssions. | ||
| 1308 | */ | ||
| 1309 | if (WARN_ON(!i915_memcpy_from_wc(NULL, NULL, 0))) { | ||
| 1310 | /* logging will not be enabled */ | ||
| 1311 | i915.guc_log_level = -1; | ||
| 1312 | return; | ||
| 1313 | } | ||
| 1314 | |||
| 870 | vma = guc_allocate_vma(guc, size); | 1315 | vma = guc_allocate_vma(guc, size); |
| 871 | if (IS_ERR(vma)) { | 1316 | if (IS_ERR(vma)) { |
| 872 | /* logging will be off */ | 1317 | /* logging will be off */ |
| @@ -874,7 +1319,14 @@ static void guc_log_create(struct intel_guc *guc) | |||
| 874 | return; | 1319 | return; |
| 875 | } | 1320 | } |
| 876 | 1321 | ||
| 877 | guc->log_vma = vma; | 1322 | guc->log.vma = vma; |
| 1323 | |||
| 1324 | if (guc_log_create_extras(guc)) { | ||
| 1325 | guc_log_cleanup(guc); | ||
| 1326 | i915_vma_unpin_and_release(&guc->log.vma); | ||
| 1327 | i915.guc_log_level = -1; | ||
| 1328 | return; | ||
| 1329 | } | ||
| 878 | } | 1330 | } |
| 879 | 1331 | ||
| 880 | /* each allocated unit is a page */ | 1332 | /* each allocated unit is a page */ |
| @@ -884,7 +1336,37 @@ static void guc_log_create(struct intel_guc *guc) | |||
| 884 | (GUC_LOG_CRASH_PAGES << GUC_LOG_CRASH_SHIFT); | 1336 | (GUC_LOG_CRASH_PAGES << GUC_LOG_CRASH_SHIFT); |
| 885 | 1337 | ||
| 886 | offset = i915_ggtt_offset(vma) >> PAGE_SHIFT; /* in pages */ | 1338 | offset = i915_ggtt_offset(vma) >> PAGE_SHIFT; /* in pages */ |
| 887 | guc->log_flags = (offset << GUC_LOG_BUF_ADDR_SHIFT) | flags; | 1339 | guc->log.flags = (offset << GUC_LOG_BUF_ADDR_SHIFT) | flags; |
| 1340 | } | ||
| 1341 | |||
| 1342 | static int guc_log_late_setup(struct intel_guc *guc) | ||
| 1343 | { | ||
| 1344 | struct drm_i915_private *dev_priv = guc_to_i915(guc); | ||
| 1345 | int ret; | ||
| 1346 | |||
| 1347 | lockdep_assert_held(&dev_priv->drm.struct_mutex); | ||
| 1348 | |||
| 1349 | if (i915.guc_log_level < 0) | ||
| 1350 | return -EINVAL; | ||
| 1351 | |||
| 1352 | /* If log_level was set as -1 at boot time, then setup needed to | ||
| 1353 | * handle log buffer flush interrupts would not have been done yet, | ||
| 1354 | * so do that now. | ||
| 1355 | */ | ||
| 1356 | ret = guc_log_create_extras(guc); | ||
| 1357 | if (ret) | ||
| 1358 | goto err; | ||
| 1359 | |||
| 1360 | ret = guc_log_create_relay_file(guc); | ||
| 1361 | if (ret) | ||
| 1362 | goto err; | ||
| 1363 | |||
| 1364 | return 0; | ||
| 1365 | err: | ||
| 1366 | guc_log_cleanup(guc); | ||
| 1367 | /* logging will remain off */ | ||
| 1368 | i915.guc_log_level = -1; | ||
| 1369 | return ret; | ||
| 888 | } | 1370 | } |
| 889 | 1371 | ||
| 890 | static void guc_policies_init(struct guc_policies *policies) | 1372 | static void guc_policies_init(struct guc_policies *policies) |
| @@ -1006,6 +1488,7 @@ int i915_guc_submission_init(struct drm_i915_private *dev_priv) | |||
| 1006 | 1488 | ||
| 1007 | guc->ctx_pool_vma = vma; | 1489 | guc->ctx_pool_vma = vma; |
| 1008 | ida_init(&guc->ctx_ids); | 1490 | ida_init(&guc->ctx_ids); |
| 1491 | mutex_init(&guc->action_lock); | ||
| 1009 | guc_log_create(guc); | 1492 | guc_log_create(guc); |
| 1010 | guc_addon_create(guc); | 1493 | guc_addon_create(guc); |
| 1011 | 1494 | ||
| @@ -1039,7 +1522,8 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv) | |||
| 1039 | engine->submit_request = i915_guc_submit; | 1522 | engine->submit_request = i915_guc_submit; |
| 1040 | 1523 | ||
| 1041 | /* Replay the current set of previously submitted requests */ | 1524 | /* Replay the current set of previously submitted requests */ |
| 1042 | list_for_each_entry(request, &engine->request_list, link) { | 1525 | list_for_each_entry(request, |
| 1526 | &engine->timeline->requests, link) { | ||
| 1043 | client->wq_rsvd += sizeof(struct guc_wq_item); | 1527 | client->wq_rsvd += sizeof(struct guc_wq_item); |
| 1044 | if (i915_sw_fence_done(&request->submit)) | 1528 | if (i915_sw_fence_done(&request->submit)) |
| 1045 | i915_guc_submit(request); | 1529 | i915_guc_submit(request); |
| @@ -1068,7 +1552,7 @@ void i915_guc_submission_fini(struct drm_i915_private *dev_priv) | |||
| 1068 | struct intel_guc *guc = &dev_priv->guc; | 1552 | struct intel_guc *guc = &dev_priv->guc; |
| 1069 | 1553 | ||
| 1070 | i915_vma_unpin_and_release(&guc->ads_vma); | 1554 | i915_vma_unpin_and_release(&guc->ads_vma); |
| 1071 | i915_vma_unpin_and_release(&guc->log_vma); | 1555 | i915_vma_unpin_and_release(&guc->log.vma); |
| 1072 | 1556 | ||
| 1073 | if (guc->ctx_pool_vma) | 1557 | if (guc->ctx_pool_vma) |
| 1074 | ida_destroy(&guc->ctx_ids); | 1558 | ida_destroy(&guc->ctx_ids); |
| @@ -1089,6 +1573,8 @@ int intel_guc_suspend(struct drm_device *dev) | |||
| 1089 | if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS) | 1573 | if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS) |
| 1090 | return 0; | 1574 | return 0; |
| 1091 | 1575 | ||
| 1576 | gen9_disable_guc_interrupts(dev_priv); | ||
| 1577 | |||
| 1092 | ctx = dev_priv->kernel_context; | 1578 | ctx = dev_priv->kernel_context; |
| 1093 | 1579 | ||
| 1094 | data[0] = HOST2GUC_ACTION_ENTER_S_STATE; | 1580 | data[0] = HOST2GUC_ACTION_ENTER_S_STATE; |
| @@ -1115,6 +1601,9 @@ int intel_guc_resume(struct drm_device *dev) | |||
| 1115 | if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS) | 1601 | if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS) |
| 1116 | return 0; | 1602 | return 0; |
| 1117 | 1603 | ||
| 1604 | if (i915.guc_log_level >= 0) | ||
| 1605 | gen9_enable_guc_interrupts(dev_priv); | ||
| 1606 | |||
| 1118 | ctx = dev_priv->kernel_context; | 1607 | ctx = dev_priv->kernel_context; |
| 1119 | 1608 | ||
| 1120 | data[0] = HOST2GUC_ACTION_EXIT_S_STATE; | 1609 | data[0] = HOST2GUC_ACTION_EXIT_S_STATE; |
| @@ -1124,3 +1613,104 @@ int intel_guc_resume(struct drm_device *dev) | |||
| 1124 | 1613 | ||
| 1125 | return host2guc_action(guc, data, ARRAY_SIZE(data)); | 1614 | return host2guc_action(guc, data, ARRAY_SIZE(data)); |
| 1126 | } | 1615 | } |
| 1616 | |||
| 1617 | void i915_guc_capture_logs(struct drm_i915_private *dev_priv) | ||
| 1618 | { | ||
| 1619 | guc_read_update_log_buffer(&dev_priv->guc); | ||
| 1620 | |||
| 1621 | /* Generally device is expected to be active only at this | ||
| 1622 | * time, so get/put should be really quick. | ||
| 1623 | */ | ||
| 1624 | intel_runtime_pm_get(dev_priv); | ||
| 1625 | host2guc_logbuffer_flush_complete(&dev_priv->guc); | ||
| 1626 | intel_runtime_pm_put(dev_priv); | ||
| 1627 | } | ||
| 1628 | |||
| 1629 | void i915_guc_flush_logs(struct drm_i915_private *dev_priv) | ||
| 1630 | { | ||
| 1631 | if (!i915.enable_guc_submission || (i915.guc_log_level < 0)) | ||
| 1632 | return; | ||
| 1633 | |||
| 1634 | /* First disable the interrupts, will be renabled afterwards */ | ||
| 1635 | gen9_disable_guc_interrupts(dev_priv); | ||
| 1636 | |||
| 1637 | /* Before initiating the forceful flush, wait for any pending/ongoing | ||
| 1638 | * flush to complete otherwise forceful flush may not actually happen. | ||
| 1639 | */ | ||
| 1640 | flush_work(&dev_priv->guc.log.flush_work); | ||
| 1641 | |||
| 1642 | /* Ask GuC to update the log buffer state */ | ||
| 1643 | host2guc_force_logbuffer_flush(&dev_priv->guc); | ||
| 1644 | |||
| 1645 | /* GuC would have updated log buffer by now, so capture it */ | ||
| 1646 | i915_guc_capture_logs(dev_priv); | ||
| 1647 | } | ||
| 1648 | |||
| 1649 | void i915_guc_unregister(struct drm_i915_private *dev_priv) | ||
| 1650 | { | ||
| 1651 | if (!i915.enable_guc_submission) | ||
| 1652 | return; | ||
| 1653 | |||
| 1654 | mutex_lock(&dev_priv->drm.struct_mutex); | ||
| 1655 | guc_log_cleanup(&dev_priv->guc); | ||
| 1656 | mutex_unlock(&dev_priv->drm.struct_mutex); | ||
| 1657 | } | ||
| 1658 | |||
| 1659 | void i915_guc_register(struct drm_i915_private *dev_priv) | ||
| 1660 | { | ||
| 1661 | if (!i915.enable_guc_submission) | ||
| 1662 | return; | ||
| 1663 | |||
| 1664 | mutex_lock(&dev_priv->drm.struct_mutex); | ||
| 1665 | guc_log_late_setup(&dev_priv->guc); | ||
| 1666 | mutex_unlock(&dev_priv->drm.struct_mutex); | ||
| 1667 | } | ||
| 1668 | |||
| 1669 | int i915_guc_log_control(struct drm_i915_private *dev_priv, u64 control_val) | ||
| 1670 | { | ||
| 1671 | union guc_log_control log_param; | ||
| 1672 | int ret; | ||
| 1673 | |||
| 1674 | log_param.value = control_val; | ||
| 1675 | |||
| 1676 | if (log_param.verbosity < GUC_LOG_VERBOSITY_MIN || | ||
| 1677 | log_param.verbosity > GUC_LOG_VERBOSITY_MAX) | ||
| 1678 | return -EINVAL; | ||
| 1679 | |||
| 1680 | /* This combination doesn't make sense & won't have any effect */ | ||
| 1681 | if (!log_param.logging_enabled && (i915.guc_log_level < 0)) | ||
| 1682 | return 0; | ||
| 1683 | |||
| 1684 | ret = host2guc_logging_control(&dev_priv->guc, log_param.value); | ||
| 1685 | if (ret < 0) { | ||
| 1686 | DRM_DEBUG_DRIVER("host2guc action failed %d\n", ret); | ||
| 1687 | return ret; | ||
| 1688 | } | ||
| 1689 | |||
| 1690 | i915.guc_log_level = log_param.verbosity; | ||
| 1691 | |||
| 1692 | /* If log_level was set as -1 at boot time, then the relay channel file | ||
| 1693 | * wouldn't have been created by now and interrupts also would not have | ||
| 1694 | * been enabled. | ||
| 1695 | */ | ||
| 1696 | if (!dev_priv->guc.log.relay_chan) { | ||
| 1697 | ret = guc_log_late_setup(&dev_priv->guc); | ||
| 1698 | if (!ret) | ||
| 1699 | gen9_enable_guc_interrupts(dev_priv); | ||
| 1700 | } else if (!log_param.logging_enabled) { | ||
| 1701 | /* Once logging is disabled, GuC won't generate logs & send an | ||
| 1702 | * interrupt. But there could be some data in the log buffer | ||
| 1703 | * which is yet to be captured. So request GuC to update the log | ||
| 1704 | * buffer state and then collect the left over logs. | ||
| 1705 | */ | ||
| 1706 | i915_guc_flush_logs(dev_priv); | ||
| 1707 | |||
| 1708 | /* As logging is disabled, update log level to reflect that */ | ||
| 1709 | i915.guc_log_level = -1; | ||
| 1710 | } else { | ||
| 1711 | /* In case interrupts were disabled, enable them now */ | ||
| 1712 | gen9_enable_guc_interrupts(dev_priv); | ||
| 1713 | } | ||
| 1714 | |||
| 1715 | return ret; | ||
| 1716 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 23315e5461bf..6d7505b5c5e7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -170,6 +170,7 @@ static void gen5_assert_iir_is_zero(struct drm_i915_private *dev_priv, | |||
| 170 | } while (0) | 170 | } while (0) |
| 171 | 171 | ||
| 172 | static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir); | 172 | static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir); |
| 173 | static void gen9_guc_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir); | ||
| 173 | 174 | ||
| 174 | /* For display hotplug interrupt */ | 175 | /* For display hotplug interrupt */ |
| 175 | static inline void | 176 | static inline void |
| @@ -303,18 +304,18 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv, | |||
| 303 | 304 | ||
| 304 | assert_spin_locked(&dev_priv->irq_lock); | 305 | assert_spin_locked(&dev_priv->irq_lock); |
| 305 | 306 | ||
| 306 | new_val = dev_priv->pm_irq_mask; | 307 | new_val = dev_priv->pm_imr; |
| 307 | new_val &= ~interrupt_mask; | 308 | new_val &= ~interrupt_mask; |
| 308 | new_val |= (~enabled_irq_mask & interrupt_mask); | 309 | new_val |= (~enabled_irq_mask & interrupt_mask); |
| 309 | 310 | ||
| 310 | if (new_val != dev_priv->pm_irq_mask) { | 311 | if (new_val != dev_priv->pm_imr) { |
| 311 | dev_priv->pm_irq_mask = new_val; | 312 | dev_priv->pm_imr = new_val; |
| 312 | I915_WRITE(gen6_pm_imr(dev_priv), dev_priv->pm_irq_mask); | 313 | I915_WRITE(gen6_pm_imr(dev_priv), dev_priv->pm_imr); |
| 313 | POSTING_READ(gen6_pm_imr(dev_priv)); | 314 | POSTING_READ(gen6_pm_imr(dev_priv)); |
| 314 | } | 315 | } |
| 315 | } | 316 | } |
| 316 | 317 | ||
| 317 | void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) | 318 | void gen6_unmask_pm_irq(struct drm_i915_private *dev_priv, u32 mask) |
| 318 | { | 319 | { |
| 319 | if (WARN_ON(!intel_irqs_enabled(dev_priv))) | 320 | if (WARN_ON(!intel_irqs_enabled(dev_priv))) |
| 320 | return; | 321 | return; |
| @@ -322,28 +323,54 @@ void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) | |||
| 322 | snb_update_pm_irq(dev_priv, mask, mask); | 323 | snb_update_pm_irq(dev_priv, mask, mask); |
| 323 | } | 324 | } |
| 324 | 325 | ||
| 325 | static void __gen6_disable_pm_irq(struct drm_i915_private *dev_priv, | 326 | static void __gen6_mask_pm_irq(struct drm_i915_private *dev_priv, u32 mask) |
| 326 | uint32_t mask) | ||
| 327 | { | 327 | { |
| 328 | snb_update_pm_irq(dev_priv, mask, 0); | 328 | snb_update_pm_irq(dev_priv, mask, 0); |
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) | 331 | void gen6_mask_pm_irq(struct drm_i915_private *dev_priv, u32 mask) |
| 332 | { | 332 | { |
| 333 | if (WARN_ON(!intel_irqs_enabled(dev_priv))) | 333 | if (WARN_ON(!intel_irqs_enabled(dev_priv))) |
| 334 | return; | 334 | return; |
| 335 | 335 | ||
| 336 | __gen6_disable_pm_irq(dev_priv, mask); | 336 | __gen6_mask_pm_irq(dev_priv, mask); |
| 337 | } | 337 | } |
| 338 | 338 | ||
| 339 | void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv) | 339 | void gen6_reset_pm_iir(struct drm_i915_private *dev_priv, u32 reset_mask) |
| 340 | { | 340 | { |
| 341 | i915_reg_t reg = gen6_pm_iir(dev_priv); | 341 | i915_reg_t reg = gen6_pm_iir(dev_priv); |
| 342 | 342 | ||
| 343 | spin_lock_irq(&dev_priv->irq_lock); | 343 | assert_spin_locked(&dev_priv->irq_lock); |
| 344 | I915_WRITE(reg, dev_priv->pm_rps_events); | 344 | |
| 345 | I915_WRITE(reg, dev_priv->pm_rps_events); | 345 | I915_WRITE(reg, reset_mask); |
| 346 | I915_WRITE(reg, reset_mask); | ||
| 346 | POSTING_READ(reg); | 347 | POSTING_READ(reg); |
| 348 | } | ||
| 349 | |||
| 350 | void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, u32 enable_mask) | ||
| 351 | { | ||
| 352 | assert_spin_locked(&dev_priv->irq_lock); | ||
| 353 | |||
| 354 | dev_priv->pm_ier |= enable_mask; | ||
| 355 | I915_WRITE(gen6_pm_ier(dev_priv), dev_priv->pm_ier); | ||
| 356 | gen6_unmask_pm_irq(dev_priv, enable_mask); | ||
| 357 | /* unmask_pm_irq provides an implicit barrier (POSTING_READ) */ | ||
| 358 | } | ||
| 359 | |||
| 360 | void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, u32 disable_mask) | ||
| 361 | { | ||
| 362 | assert_spin_locked(&dev_priv->irq_lock); | ||
| 363 | |||
| 364 | dev_priv->pm_ier &= ~disable_mask; | ||
| 365 | __gen6_mask_pm_irq(dev_priv, disable_mask); | ||
| 366 | I915_WRITE(gen6_pm_ier(dev_priv), dev_priv->pm_ier); | ||
| 367 | /* though a barrier is missing here, but don't really need a one */ | ||
| 368 | } | ||
| 369 | |||
| 370 | void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv) | ||
| 371 | { | ||
| 372 | spin_lock_irq(&dev_priv->irq_lock); | ||
| 373 | gen6_reset_pm_iir(dev_priv, dev_priv->pm_rps_events); | ||
| 347 | dev_priv->rps.pm_iir = 0; | 374 | dev_priv->rps.pm_iir = 0; |
| 348 | spin_unlock_irq(&dev_priv->irq_lock); | 375 | spin_unlock_irq(&dev_priv->irq_lock); |
| 349 | } | 376 | } |
| @@ -357,8 +384,6 @@ void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv) | |||
| 357 | WARN_ON_ONCE(dev_priv->rps.pm_iir); | 384 | WARN_ON_ONCE(dev_priv->rps.pm_iir); |
| 358 | WARN_ON_ONCE(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events); | 385 | WARN_ON_ONCE(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events); |
| 359 | dev_priv->rps.interrupts_enabled = true; | 386 | dev_priv->rps.interrupts_enabled = true; |
| 360 | I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) | | ||
| 361 | dev_priv->pm_rps_events); | ||
| 362 | gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); | 387 | gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); |
| 363 | 388 | ||
| 364 | spin_unlock_irq(&dev_priv->irq_lock); | 389 | spin_unlock_irq(&dev_priv->irq_lock); |
| @@ -379,9 +404,7 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv) | |||
| 379 | 404 | ||
| 380 | I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0u)); | 405 | I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0u)); |
| 381 | 406 | ||
| 382 | __gen6_disable_pm_irq(dev_priv, dev_priv->pm_rps_events); | 407 | gen6_disable_pm_irq(dev_priv, dev_priv->pm_rps_events); |
| 383 | I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & | ||
| 384 | ~dev_priv->pm_rps_events); | ||
| 385 | 408 | ||
| 386 | spin_unlock_irq(&dev_priv->irq_lock); | 409 | spin_unlock_irq(&dev_priv->irq_lock); |
| 387 | synchronize_irq(dev_priv->drm.irq); | 410 | synchronize_irq(dev_priv->drm.irq); |
| @@ -395,6 +418,38 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv) | |||
| 395 | gen6_reset_rps_interrupts(dev_priv); | 418 | gen6_reset_rps_interrupts(dev_priv); |
| 396 | } | 419 | } |
| 397 | 420 | ||
| 421 | void gen9_reset_guc_interrupts(struct drm_i915_private *dev_priv) | ||
| 422 | { | ||
| 423 | spin_lock_irq(&dev_priv->irq_lock); | ||
| 424 | gen6_reset_pm_iir(dev_priv, dev_priv->pm_guc_events); | ||
| 425 | spin_unlock_irq(&dev_priv->irq_lock); | ||
| 426 | } | ||
| 427 | |||
| 428 | void gen9_enable_guc_interrupts(struct drm_i915_private *dev_priv) | ||
| 429 | { | ||
| 430 | spin_lock_irq(&dev_priv->irq_lock); | ||
| 431 | if (!dev_priv->guc.interrupts_enabled) { | ||
| 432 | WARN_ON_ONCE(I915_READ(gen6_pm_iir(dev_priv)) & | ||
| 433 | dev_priv->pm_guc_events); | ||
| 434 | dev_priv->guc.interrupts_enabled = true; | ||
| 435 | gen6_enable_pm_irq(dev_priv, dev_priv->pm_guc_events); | ||
| 436 | } | ||
| 437 | spin_unlock_irq(&dev_priv->irq_lock); | ||
| 438 | } | ||
| 439 | |||
| 440 | void gen9_disable_guc_interrupts(struct drm_i915_private *dev_priv) | ||
| 441 | { | ||
| 442 | spin_lock_irq(&dev_priv->irq_lock); | ||
| 443 | dev_priv->guc.interrupts_enabled = false; | ||
| 444 | |||
| 445 | gen6_disable_pm_irq(dev_priv, dev_priv->pm_guc_events); | ||
| 446 | |||
| 447 | spin_unlock_irq(&dev_priv->irq_lock); | ||
| 448 | synchronize_irq(dev_priv->drm.irq); | ||
| 449 | |||
| 450 | gen9_reset_guc_interrupts(dev_priv); | ||
| 451 | } | ||
| 452 | |||
| 398 | /** | 453 | /** |
| 399 | * bdw_update_port_irq - update DE port interrupt | 454 | * bdw_update_port_irq - update DE port interrupt |
| 400 | * @dev_priv: driver private | 455 | * @dev_priv: driver private |
| @@ -670,8 +725,8 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, unsigned int pipe) | |||
| 670 | struct drm_i915_private *dev_priv = to_i915(dev); | 725 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 671 | i915_reg_t high_frame, low_frame; | 726 | i915_reg_t high_frame, low_frame; |
| 672 | u32 high1, high2, low, pixel, vbl_start, hsync_start, htotal; | 727 | u32 high1, high2, low, pixel, vbl_start, hsync_start, htotal; |
| 673 | struct intel_crtc *intel_crtc = | 728 | struct intel_crtc *intel_crtc = intel_get_crtc_for_pipe(dev_priv, |
| 674 | to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); | 729 | pipe); |
| 675 | const struct drm_display_mode *mode = &intel_crtc->base.hwmode; | 730 | const struct drm_display_mode *mode = &intel_crtc->base.hwmode; |
| 676 | 731 | ||
| 677 | htotal = mode->crtc_htotal; | 732 | htotal = mode->crtc_htotal; |
| @@ -776,8 +831,8 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, | |||
| 776 | const struct drm_display_mode *mode) | 831 | const struct drm_display_mode *mode) |
| 777 | { | 832 | { |
| 778 | struct drm_i915_private *dev_priv = to_i915(dev); | 833 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 779 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | 834 | struct intel_crtc *intel_crtc = intel_get_crtc_for_pipe(dev_priv, |
| 780 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 835 | pipe); |
| 781 | int position; | 836 | int position; |
| 782 | int vbl_start, vbl_end, hsync_start, htotal, vtotal; | 837 | int vbl_start, vbl_end, hsync_start, htotal, vtotal; |
| 783 | bool in_vbl = true; | 838 | bool in_vbl = true; |
| @@ -912,21 +967,22 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, | |||
| 912 | struct timeval *vblank_time, | 967 | struct timeval *vblank_time, |
| 913 | unsigned flags) | 968 | unsigned flags) |
| 914 | { | 969 | { |
| 915 | struct drm_crtc *crtc; | 970 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 971 | struct intel_crtc *crtc; | ||
| 916 | 972 | ||
| 917 | if (pipe >= INTEL_INFO(dev)->num_pipes) { | 973 | if (pipe >= INTEL_INFO(dev_priv)->num_pipes) { |
| 918 | DRM_ERROR("Invalid crtc %u\n", pipe); | 974 | DRM_ERROR("Invalid crtc %u\n", pipe); |
| 919 | return -EINVAL; | 975 | return -EINVAL; |
| 920 | } | 976 | } |
| 921 | 977 | ||
| 922 | /* Get drm_crtc to timestamp: */ | 978 | /* Get drm_crtc to timestamp: */ |
| 923 | crtc = intel_get_crtc_for_pipe(dev, pipe); | 979 | crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
| 924 | if (crtc == NULL) { | 980 | if (crtc == NULL) { |
| 925 | DRM_ERROR("Invalid crtc %u\n", pipe); | 981 | DRM_ERROR("Invalid crtc %u\n", pipe); |
| 926 | return -EINVAL; | 982 | return -EINVAL; |
| 927 | } | 983 | } |
| 928 | 984 | ||
| 929 | if (!crtc->hwmode.crtc_clock) { | 985 | if (!crtc->base.hwmode.crtc_clock) { |
| 930 | DRM_DEBUG_KMS("crtc %u is disabled\n", pipe); | 986 | DRM_DEBUG_KMS("crtc %u is disabled\n", pipe); |
| 931 | return -EBUSY; | 987 | return -EBUSY; |
| 932 | } | 988 | } |
| @@ -934,7 +990,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, | |||
| 934 | /* Helper routine in DRM core does all the work: */ | 990 | /* Helper routine in DRM core does all the work: */ |
| 935 | return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, | 991 | return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, |
| 936 | vblank_time, flags, | 992 | vblank_time, flags, |
| 937 | &crtc->hwmode); | 993 | &crtc->base.hwmode); |
| 938 | } | 994 | } |
| 939 | 995 | ||
| 940 | static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) | 996 | static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) |
| @@ -1085,7 +1141,7 @@ static void gen6_pm_rps_work(struct work_struct *work) | |||
| 1085 | pm_iir = dev_priv->rps.pm_iir; | 1141 | pm_iir = dev_priv->rps.pm_iir; |
| 1086 | dev_priv->rps.pm_iir = 0; | 1142 | dev_priv->rps.pm_iir = 0; |
| 1087 | /* Make sure not to corrupt PMIMR state used by ringbuffer on GEN6 */ | 1143 | /* Make sure not to corrupt PMIMR state used by ringbuffer on GEN6 */ |
| 1088 | gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); | 1144 | gen6_unmask_pm_irq(dev_priv, dev_priv->pm_rps_events); |
| 1089 | client_boost = dev_priv->rps.client_boost; | 1145 | client_boost = dev_priv->rps.client_boost; |
| 1090 | dev_priv->rps.client_boost = false; | 1146 | dev_priv->rps.client_boost = false; |
| 1091 | spin_unlock_irq(&dev_priv->irq_lock); | 1147 | spin_unlock_irq(&dev_priv->irq_lock); |
| @@ -1324,11 +1380,13 @@ static irqreturn_t gen8_gt_irq_ack(struct drm_i915_private *dev_priv, | |||
| 1324 | DRM_ERROR("The master control interrupt lied (GT3)!\n"); | 1380 | DRM_ERROR("The master control interrupt lied (GT3)!\n"); |
| 1325 | } | 1381 | } |
| 1326 | 1382 | ||
| 1327 | if (master_ctl & GEN8_GT_PM_IRQ) { | 1383 | if (master_ctl & (GEN8_GT_PM_IRQ | GEN8_GT_GUC_IRQ)) { |
| 1328 | gt_iir[2] = I915_READ_FW(GEN8_GT_IIR(2)); | 1384 | gt_iir[2] = I915_READ_FW(GEN8_GT_IIR(2)); |
| 1329 | if (gt_iir[2] & dev_priv->pm_rps_events) { | 1385 | if (gt_iir[2] & (dev_priv->pm_rps_events | |
| 1386 | dev_priv->pm_guc_events)) { | ||
| 1330 | I915_WRITE_FW(GEN8_GT_IIR(2), | 1387 | I915_WRITE_FW(GEN8_GT_IIR(2), |
| 1331 | gt_iir[2] & dev_priv->pm_rps_events); | 1388 | gt_iir[2] & (dev_priv->pm_rps_events | |
| 1389 | dev_priv->pm_guc_events)); | ||
| 1332 | ret = IRQ_HANDLED; | 1390 | ret = IRQ_HANDLED; |
| 1333 | } else | 1391 | } else |
| 1334 | DRM_ERROR("The master control interrupt lied (PM)!\n"); | 1392 | DRM_ERROR("The master control interrupt lied (PM)!\n"); |
| @@ -1360,6 +1418,9 @@ static void gen8_gt_irq_handler(struct drm_i915_private *dev_priv, | |||
| 1360 | 1418 | ||
| 1361 | if (gt_iir[2] & dev_priv->pm_rps_events) | 1419 | if (gt_iir[2] & dev_priv->pm_rps_events) |
| 1362 | gen6_rps_irq_handler(dev_priv, gt_iir[2]); | 1420 | gen6_rps_irq_handler(dev_priv, gt_iir[2]); |
| 1421 | |||
| 1422 | if (gt_iir[2] & dev_priv->pm_guc_events) | ||
| 1423 | gen9_guc_irq_handler(dev_priv, gt_iir[2]); | ||
| 1363 | } | 1424 | } |
| 1364 | 1425 | ||
| 1365 | static bool bxt_port_hotplug_long_detect(enum port port, u32 val) | 1426 | static bool bxt_port_hotplug_long_detect(enum port port, u32 val) |
| @@ -1586,7 +1647,7 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) | |||
| 1586 | { | 1647 | { |
| 1587 | if (pm_iir & dev_priv->pm_rps_events) { | 1648 | if (pm_iir & dev_priv->pm_rps_events) { |
| 1588 | spin_lock(&dev_priv->irq_lock); | 1649 | spin_lock(&dev_priv->irq_lock); |
| 1589 | gen6_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events); | 1650 | gen6_mask_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events); |
| 1590 | if (dev_priv->rps.interrupts_enabled) { | 1651 | if (dev_priv->rps.interrupts_enabled) { |
| 1591 | dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events; | 1652 | dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events; |
| 1592 | schedule_work(&dev_priv->rps.work); | 1653 | schedule_work(&dev_priv->rps.work); |
| @@ -1606,6 +1667,41 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) | |||
| 1606 | } | 1667 | } |
| 1607 | } | 1668 | } |
| 1608 | 1669 | ||
| 1670 | static void gen9_guc_irq_handler(struct drm_i915_private *dev_priv, u32 gt_iir) | ||
| 1671 | { | ||
| 1672 | if (gt_iir & GEN9_GUC_TO_HOST_INT_EVENT) { | ||
| 1673 | /* Sample the log buffer flush related bits & clear them out now | ||
| 1674 | * itself from the message identity register to minimize the | ||
| 1675 | * probability of losing a flush interrupt, when there are back | ||
| 1676 | * to back flush interrupts. | ||
| 1677 | * There can be a new flush interrupt, for different log buffer | ||
| 1678 | * type (like for ISR), whilst Host is handling one (for DPC). | ||
| 1679 | * Since same bit is used in message register for ISR & DPC, it | ||
| 1680 | * could happen that GuC sets the bit for 2nd interrupt but Host | ||
| 1681 | * clears out the bit on handling the 1st interrupt. | ||
| 1682 | */ | ||
| 1683 | u32 msg, flush; | ||
| 1684 | |||
| 1685 | msg = I915_READ(SOFT_SCRATCH(15)); | ||
| 1686 | flush = msg & (GUC2HOST_MSG_CRASH_DUMP_POSTED | | ||
| 1687 | GUC2HOST_MSG_FLUSH_LOG_BUFFER); | ||
| 1688 | if (flush) { | ||
| 1689 | /* Clear the message bits that are handled */ | ||
| 1690 | I915_WRITE(SOFT_SCRATCH(15), msg & ~flush); | ||
| 1691 | |||
| 1692 | /* Handle flush interrupt in bottom half */ | ||
| 1693 | queue_work(dev_priv->guc.log.flush_wq, | ||
| 1694 | &dev_priv->guc.log.flush_work); | ||
| 1695 | |||
| 1696 | dev_priv->guc.log.flush_interrupt_count++; | ||
| 1697 | } else { | ||
| 1698 | /* Not clearing of unhandled event bits won't result in | ||
| 1699 | * re-triggering of the interrupt. | ||
| 1700 | */ | ||
| 1701 | } | ||
| 1702 | } | ||
| 1703 | } | ||
| 1704 | |||
| 1609 | static bool intel_pipe_handle_vblank(struct drm_i915_private *dev_priv, | 1705 | static bool intel_pipe_handle_vblank(struct drm_i915_private *dev_priv, |
| 1610 | enum pipe pipe) | 1706 | enum pipe pipe) |
| 1611 | { | 1707 | { |
| @@ -2408,7 +2504,7 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) | |||
| 2408 | fault_errors &= GEN8_DE_PIPE_IRQ_FAULT_ERRORS; | 2504 | fault_errors &= GEN8_DE_PIPE_IRQ_FAULT_ERRORS; |
| 2409 | 2505 | ||
| 2410 | if (fault_errors) | 2506 | if (fault_errors) |
| 2411 | DRM_ERROR("Fault errors on pipe %c\n: 0x%08x", | 2507 | DRM_ERROR("Fault errors on pipe %c: 0x%08x\n", |
| 2412 | pipe_name(pipe), | 2508 | pipe_name(pipe), |
| 2413 | fault_errors); | 2509 | fault_errors); |
| 2414 | } | 2510 | } |
| @@ -2752,420 +2848,6 @@ static void gen8_disable_vblank(struct drm_device *dev, unsigned int pipe) | |||
| 2752 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 2848 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
| 2753 | } | 2849 | } |
| 2754 | 2850 | ||
| 2755 | static bool | ||
| 2756 | ipehr_is_semaphore_wait(struct intel_engine_cs *engine, u32 ipehr) | ||
| 2757 | { | ||
| 2758 | if (INTEL_GEN(engine->i915) >= 8) { | ||
| 2759 | return (ipehr >> 23) == 0x1c; | ||
| 2760 | } else { | ||
| 2761 | ipehr &= ~MI_SEMAPHORE_SYNC_MASK; | ||
| 2762 | return ipehr == (MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE | | ||
| 2763 | MI_SEMAPHORE_REGISTER); | ||
| 2764 | } | ||
| 2765 | } | ||
| 2766 | |||
| 2767 | static struct intel_engine_cs * | ||
| 2768 | semaphore_wait_to_signaller_ring(struct intel_engine_cs *engine, u32 ipehr, | ||
| 2769 | u64 offset) | ||
| 2770 | { | ||
| 2771 | struct drm_i915_private *dev_priv = engine->i915; | ||
| 2772 | struct intel_engine_cs *signaller; | ||
| 2773 | enum intel_engine_id id; | ||
| 2774 | |||
| 2775 | if (INTEL_GEN(dev_priv) >= 8) { | ||
| 2776 | for_each_engine(signaller, dev_priv, id) { | ||
| 2777 | if (engine == signaller) | ||
| 2778 | continue; | ||
| 2779 | |||
| 2780 | if (offset == signaller->semaphore.signal_ggtt[engine->hw_id]) | ||
| 2781 | return signaller; | ||
| 2782 | } | ||
| 2783 | } else { | ||
| 2784 | u32 sync_bits = ipehr & MI_SEMAPHORE_SYNC_MASK; | ||
| 2785 | |||
| 2786 | for_each_engine(signaller, dev_priv, id) { | ||
| 2787 | if(engine == signaller) | ||
| 2788 | continue; | ||
| 2789 | |||
| 2790 | if (sync_bits == signaller->semaphore.mbox.wait[engine->hw_id]) | ||
| 2791 | return signaller; | ||
| 2792 | } | ||
| 2793 | } | ||
| 2794 | |||
| 2795 | DRM_DEBUG_DRIVER("No signaller ring found for %s, ipehr 0x%08x, offset 0x%016llx\n", | ||
| 2796 | engine->name, ipehr, offset); | ||
| 2797 | |||
| 2798 | return ERR_PTR(-ENODEV); | ||
| 2799 | } | ||
| 2800 | |||
| 2801 | static struct intel_engine_cs * | ||
| 2802 | semaphore_waits_for(struct intel_engine_cs *engine, u32 *seqno) | ||
| 2803 | { | ||
| 2804 | struct drm_i915_private *dev_priv = engine->i915; | ||
| 2805 | void __iomem *vaddr; | ||
| 2806 | u32 cmd, ipehr, head; | ||
| 2807 | u64 offset = 0; | ||
| 2808 | int i, backwards; | ||
| 2809 | |||
| 2810 | /* | ||
| 2811 | * This function does not support execlist mode - any attempt to | ||
| 2812 | * proceed further into this function will result in a kernel panic | ||
| 2813 | * when dereferencing ring->buffer, which is not set up in execlist | ||
| 2814 | * mode. | ||
| 2815 | * | ||
| 2816 | * The correct way of doing it would be to derive the currently | ||
| 2817 | * executing ring buffer from the current context, which is derived | ||
| 2818 | * from the currently running request. Unfortunately, to get the | ||
| 2819 | * current request we would have to grab the struct_mutex before doing | ||
| 2820 | * anything else, which would be ill-advised since some other thread | ||
| 2821 | * might have grabbed it already and managed to hang itself, causing | ||
| 2822 | * the hang checker to deadlock. | ||
| 2823 | * | ||
| 2824 | * Therefore, this function does not support execlist mode in its | ||
| 2825 | * current form. Just return NULL and move on. | ||
| 2826 | */ | ||
| 2827 | if (engine->buffer == NULL) | ||
| 2828 | return NULL; | ||
| 2829 | |||
| 2830 | ipehr = I915_READ(RING_IPEHR(engine->mmio_base)); | ||
| 2831 | if (!ipehr_is_semaphore_wait(engine, ipehr)) | ||
| 2832 | return NULL; | ||
| 2833 | |||
| 2834 | /* | ||
| 2835 | * HEAD is likely pointing to the dword after the actual command, | ||
| 2836 | * so scan backwards until we find the MBOX. But limit it to just 3 | ||
| 2837 | * or 4 dwords depending on the semaphore wait command size. | ||
| 2838 | * Note that we don't care about ACTHD here since that might | ||
| 2839 | * point at at batch, and semaphores are always emitted into the | ||
| 2840 | * ringbuffer itself. | ||
| 2841 | */ | ||
| 2842 | head = I915_READ_HEAD(engine) & HEAD_ADDR; | ||
| 2843 | backwards = (INTEL_GEN(dev_priv) >= 8) ? 5 : 4; | ||
| 2844 | vaddr = (void __iomem *)engine->buffer->vaddr; | ||
| 2845 | |||
| 2846 | for (i = backwards; i; --i) { | ||
| 2847 | /* | ||
| 2848 | * Be paranoid and presume the hw has gone off into the wild - | ||
| 2849 | * our ring is smaller than what the hardware (and hence | ||
| 2850 | * HEAD_ADDR) allows. Also handles wrap-around. | ||
| 2851 | */ | ||
| 2852 | head &= engine->buffer->size - 1; | ||
| 2853 | |||
| 2854 | /* This here seems to blow up */ | ||
| 2855 | cmd = ioread32(vaddr + head); | ||
| 2856 | if (cmd == ipehr) | ||
| 2857 | break; | ||
| 2858 | |||
| 2859 | head -= 4; | ||
| 2860 | } | ||
| 2861 | |||
| 2862 | if (!i) | ||
| 2863 | return NULL; | ||
| 2864 | |||
| 2865 | *seqno = ioread32(vaddr + head + 4) + 1; | ||
| 2866 | if (INTEL_GEN(dev_priv) >= 8) { | ||
| 2867 | offset = ioread32(vaddr + head + 12); | ||
| 2868 | offset <<= 32; | ||
| 2869 | offset |= ioread32(vaddr + head + 8); | ||
| 2870 | } | ||
| 2871 | return semaphore_wait_to_signaller_ring(engine, ipehr, offset); | ||
| 2872 | } | ||
| 2873 | |||
| 2874 | static int semaphore_passed(struct intel_engine_cs *engine) | ||
| 2875 | { | ||
| 2876 | struct drm_i915_private *dev_priv = engine->i915; | ||
| 2877 | struct intel_engine_cs *signaller; | ||
| 2878 | u32 seqno; | ||
| 2879 | |||
| 2880 | engine->hangcheck.deadlock++; | ||
| 2881 | |||
| 2882 | signaller = semaphore_waits_for(engine, &seqno); | ||
| 2883 | if (signaller == NULL) | ||
| 2884 | return -1; | ||
| 2885 | |||
| 2886 | if (IS_ERR(signaller)) | ||
| 2887 | return 0; | ||
| 2888 | |||
| 2889 | /* Prevent pathological recursion due to driver bugs */ | ||
| 2890 | if (signaller->hangcheck.deadlock >= I915_NUM_ENGINES) | ||
| 2891 | return -1; | ||
| 2892 | |||
| 2893 | if (i915_seqno_passed(intel_engine_get_seqno(signaller), seqno)) | ||
| 2894 | return 1; | ||
| 2895 | |||
| 2896 | /* cursory check for an unkickable deadlock */ | ||
| 2897 | if (I915_READ_CTL(signaller) & RING_WAIT_SEMAPHORE && | ||
| 2898 | semaphore_passed(signaller) < 0) | ||
| 2899 | return -1; | ||
| 2900 | |||
| 2901 | return 0; | ||
| 2902 | } | ||
| 2903 | |||
| 2904 | static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv) | ||
| 2905 | { | ||
| 2906 | struct intel_engine_cs *engine; | ||
| 2907 | enum intel_engine_id id; | ||
| 2908 | |||
| 2909 | for_each_engine(engine, dev_priv, id) | ||
| 2910 | engine->hangcheck.deadlock = 0; | ||
| 2911 | } | ||
| 2912 | |||
| 2913 | static bool instdone_unchanged(u32 current_instdone, u32 *old_instdone) | ||
| 2914 | { | ||
| 2915 | u32 tmp = current_instdone | *old_instdone; | ||
| 2916 | bool unchanged; | ||
| 2917 | |||
| 2918 | unchanged = tmp == *old_instdone; | ||
| 2919 | *old_instdone |= tmp; | ||
| 2920 | |||
| 2921 | return unchanged; | ||
| 2922 | } | ||
| 2923 | |||
| 2924 | static bool subunits_stuck(struct intel_engine_cs *engine) | ||
| 2925 | { | ||
| 2926 | struct drm_i915_private *dev_priv = engine->i915; | ||
| 2927 | struct intel_instdone instdone; | ||
| 2928 | struct intel_instdone *accu_instdone = &engine->hangcheck.instdone; | ||
| 2929 | bool stuck; | ||
| 2930 | int slice; | ||
| 2931 | int subslice; | ||
| 2932 | |||
| 2933 | if (engine->id != RCS) | ||
| 2934 | return true; | ||
| 2935 | |||
| 2936 | intel_engine_get_instdone(engine, &instdone); | ||
| 2937 | |||
| 2938 | /* There might be unstable subunit states even when | ||
| 2939 | * actual head is not moving. Filter out the unstable ones by | ||
| 2940 | * accumulating the undone -> done transitions and only | ||
| 2941 | * consider those as progress. | ||
| 2942 | */ | ||
| 2943 | stuck = instdone_unchanged(instdone.instdone, | ||
| 2944 | &accu_instdone->instdone); | ||
| 2945 | stuck &= instdone_unchanged(instdone.slice_common, | ||
| 2946 | &accu_instdone->slice_common); | ||
| 2947 | |||
| 2948 | for_each_instdone_slice_subslice(dev_priv, slice, subslice) { | ||
| 2949 | stuck &= instdone_unchanged(instdone.sampler[slice][subslice], | ||
| 2950 | &accu_instdone->sampler[slice][subslice]); | ||
| 2951 | stuck &= instdone_unchanged(instdone.row[slice][subslice], | ||
| 2952 | &accu_instdone->row[slice][subslice]); | ||
| 2953 | } | ||
| 2954 | |||
| 2955 | return stuck; | ||
| 2956 | } | ||
| 2957 | |||
| 2958 | static enum intel_engine_hangcheck_action | ||
| 2959 | head_stuck(struct intel_engine_cs *engine, u64 acthd) | ||
| 2960 | { | ||
| 2961 | if (acthd != engine->hangcheck.acthd) { | ||
| 2962 | |||
| 2963 | /* Clear subunit states on head movement */ | ||
| 2964 | memset(&engine->hangcheck.instdone, 0, | ||
| 2965 | sizeof(engine->hangcheck.instdone)); | ||
| 2966 | |||
| 2967 | return HANGCHECK_ACTIVE; | ||
| 2968 | } | ||
| 2969 | |||
| 2970 | if (!subunits_stuck(engine)) | ||
| 2971 | return HANGCHECK_ACTIVE; | ||
| 2972 | |||
| 2973 | return HANGCHECK_HUNG; | ||
| 2974 | } | ||
| 2975 | |||
| 2976 | static enum intel_engine_hangcheck_action | ||
| 2977 | engine_stuck(struct intel_engine_cs *engine, u64 acthd) | ||
| 2978 | { | ||
| 2979 | struct drm_i915_private *dev_priv = engine->i915; | ||
| 2980 | enum intel_engine_hangcheck_action ha; | ||
| 2981 | u32 tmp; | ||
| 2982 | |||
| 2983 | ha = head_stuck(engine, acthd); | ||
| 2984 | if (ha != HANGCHECK_HUNG) | ||
| 2985 | return ha; | ||
| 2986 | |||
| 2987 | if (IS_GEN2(dev_priv)) | ||
| 2988 | return HANGCHECK_HUNG; | ||
| 2989 | |||
| 2990 | /* Is the chip hanging on a WAIT_FOR_EVENT? | ||
| 2991 | * If so we can simply poke the RB_WAIT bit | ||
| 2992 | * and break the hang. This should work on | ||
| 2993 | * all but the second generation chipsets. | ||
| 2994 | */ | ||
| 2995 | tmp = I915_READ_CTL(engine); | ||
| 2996 | if (tmp & RING_WAIT) { | ||
| 2997 | i915_handle_error(dev_priv, 0, | ||
| 2998 | "Kicking stuck wait on %s", | ||
| 2999 | engine->name); | ||
| 3000 | I915_WRITE_CTL(engine, tmp); | ||
| 3001 | return HANGCHECK_KICK; | ||
| 3002 | } | ||
| 3003 | |||
| 3004 | if (INTEL_GEN(dev_priv) >= 6 && tmp & RING_WAIT_SEMAPHORE) { | ||
| 3005 | switch (semaphore_passed(engine)) { | ||
| 3006 | default: | ||
| 3007 | return HANGCHECK_HUNG; | ||
| 3008 | case 1: | ||
| 3009 | i915_handle_error(dev_priv, 0, | ||
| 3010 | "Kicking stuck semaphore on %s", | ||
| 3011 | engine->name); | ||
| 3012 | I915_WRITE_CTL(engine, tmp); | ||
| 3013 | return HANGCHECK_KICK; | ||
| 3014 | case 0: | ||
| 3015 | return HANGCHECK_WAIT; | ||
| 3016 | } | ||
| 3017 | } | ||
| 3018 | |||
| 3019 | return HANGCHECK_HUNG; | ||
| 3020 | } | ||
| 3021 | |||
| 3022 | /* | ||
| 3023 | * This is called when the chip hasn't reported back with completed | ||
| 3024 | * batchbuffers in a long time. We keep track per ring seqno progress and | ||
| 3025 | * if there are no progress, hangcheck score for that ring is increased. | ||
| 3026 | * Further, acthd is inspected to see if the ring is stuck. On stuck case | ||
| 3027 | * we kick the ring. If we see no progress on three subsequent calls | ||
| 3028 | * we assume chip is wedged and try to fix it by resetting the chip. | ||
| 3029 | */ | ||
| 3030 | static void i915_hangcheck_elapsed(struct work_struct *work) | ||
| 3031 | { | ||
| 3032 | struct drm_i915_private *dev_priv = | ||
| 3033 | container_of(work, typeof(*dev_priv), | ||
| 3034 | gpu_error.hangcheck_work.work); | ||
| 3035 | struct intel_engine_cs *engine; | ||
| 3036 | enum intel_engine_id id; | ||
| 3037 | unsigned int hung = 0, stuck = 0; | ||
| 3038 | int busy_count = 0; | ||
| 3039 | #define BUSY 1 | ||
| 3040 | #define KICK 5 | ||
| 3041 | #define HUNG 20 | ||
| 3042 | #define ACTIVE_DECAY 15 | ||
| 3043 | |||
| 3044 | if (!i915.enable_hangcheck) | ||
| 3045 | return; | ||
| 3046 | |||
| 3047 | if (!READ_ONCE(dev_priv->gt.awake)) | ||
| 3048 | return; | ||
| 3049 | |||
| 3050 | /* As enabling the GPU requires fairly extensive mmio access, | ||
| 3051 | * periodically arm the mmio checker to see if we are triggering | ||
| 3052 | * any invalid access. | ||
| 3053 | */ | ||
| 3054 | intel_uncore_arm_unclaimed_mmio_detection(dev_priv); | ||
| 3055 | |||
| 3056 | for_each_engine(engine, dev_priv, id) { | ||
| 3057 | bool busy = intel_engine_has_waiter(engine); | ||
| 3058 | u64 acthd; | ||
| 3059 | u32 seqno; | ||
| 3060 | u32 submit; | ||
| 3061 | |||
| 3062 | semaphore_clear_deadlocks(dev_priv); | ||
| 3063 | |||
| 3064 | /* We don't strictly need an irq-barrier here, as we are not | ||
| 3065 | * serving an interrupt request, be paranoid in case the | ||
| 3066 | * barrier has side-effects (such as preventing a broken | ||
| 3067 | * cacheline snoop) and so be sure that we can see the seqno | ||
| 3068 | * advance. If the seqno should stick, due to a stale | ||
| 3069 | * cacheline, we would erroneously declare the GPU hung. | ||
| 3070 | */ | ||
| 3071 | if (engine->irq_seqno_barrier) | ||
| 3072 | engine->irq_seqno_barrier(engine); | ||
| 3073 | |||
| 3074 | acthd = intel_engine_get_active_head(engine); | ||
| 3075 | seqno = intel_engine_get_seqno(engine); | ||
| 3076 | submit = READ_ONCE(engine->last_submitted_seqno); | ||
| 3077 | |||
| 3078 | if (engine->hangcheck.seqno == seqno) { | ||
| 3079 | if (i915_seqno_passed(seqno, submit)) { | ||
| 3080 | engine->hangcheck.action = HANGCHECK_IDLE; | ||
| 3081 | } else { | ||
| 3082 | /* We always increment the hangcheck score | ||
| 3083 | * if the engine is busy and still processing | ||
| 3084 | * the same request, so that no single request | ||
| 3085 | * can run indefinitely (such as a chain of | ||
| 3086 | * batches). The only time we do not increment | ||
| 3087 | * the hangcheck score on this ring, if this | ||
| 3088 | * engine is in a legitimate wait for another | ||
| 3089 | * engine. In that case the waiting engine is a | ||
| 3090 | * victim and we want to be sure we catch the | ||
| 3091 | * right culprit. Then every time we do kick | ||
| 3092 | * the ring, add a small increment to the | ||
| 3093 | * score so that we can catch a batch that is | ||
| 3094 | * being repeatedly kicked and so responsible | ||
| 3095 | * for stalling the machine. | ||
| 3096 | */ | ||
| 3097 | engine->hangcheck.action = | ||
| 3098 | engine_stuck(engine, acthd); | ||
| 3099 | |||
| 3100 | switch (engine->hangcheck.action) { | ||
| 3101 | case HANGCHECK_IDLE: | ||
| 3102 | case HANGCHECK_WAIT: | ||
| 3103 | break; | ||
| 3104 | case HANGCHECK_ACTIVE: | ||
| 3105 | engine->hangcheck.score += BUSY; | ||
| 3106 | break; | ||
| 3107 | case HANGCHECK_KICK: | ||
| 3108 | engine->hangcheck.score += KICK; | ||
| 3109 | break; | ||
| 3110 | case HANGCHECK_HUNG: | ||
| 3111 | engine->hangcheck.score += HUNG; | ||
| 3112 | break; | ||
| 3113 | } | ||
| 3114 | } | ||
| 3115 | |||
| 3116 | if (engine->hangcheck.score >= HANGCHECK_SCORE_RING_HUNG) { | ||
| 3117 | hung |= intel_engine_flag(engine); | ||
| 3118 | if (engine->hangcheck.action != HANGCHECK_HUNG) | ||
| 3119 | stuck |= intel_engine_flag(engine); | ||
| 3120 | } | ||
| 3121 | } else { | ||
| 3122 | engine->hangcheck.action = HANGCHECK_ACTIVE; | ||
| 3123 | |||
| 3124 | /* Gradually reduce the count so that we catch DoS | ||
| 3125 | * attempts across multiple batches. | ||
| 3126 | */ | ||
| 3127 | if (engine->hangcheck.score > 0) | ||
| 3128 | engine->hangcheck.score -= ACTIVE_DECAY; | ||
| 3129 | if (engine->hangcheck.score < 0) | ||
| 3130 | engine->hangcheck.score = 0; | ||
| 3131 | |||
| 3132 | /* Clear head and subunit states on seqno movement */ | ||
| 3133 | acthd = 0; | ||
| 3134 | |||
| 3135 | memset(&engine->hangcheck.instdone, 0, | ||
| 3136 | sizeof(engine->hangcheck.instdone)); | ||
| 3137 | } | ||
| 3138 | |||
| 3139 | engine->hangcheck.seqno = seqno; | ||
| 3140 | engine->hangcheck.acthd = acthd; | ||
| 3141 | busy_count += busy; | ||
| 3142 | } | ||
| 3143 | |||
| 3144 | if (hung) { | ||
| 3145 | char msg[80]; | ||
| 3146 | unsigned int tmp; | ||
| 3147 | int len; | ||
| 3148 | |||
| 3149 | /* If some rings hung but others were still busy, only | ||
| 3150 | * blame the hanging rings in the synopsis. | ||
| 3151 | */ | ||
| 3152 | if (stuck != hung) | ||
| 3153 | hung &= ~stuck; | ||
| 3154 | len = scnprintf(msg, sizeof(msg), | ||
| 3155 | "%s on ", stuck == hung ? "No progress" : "Hang"); | ||
| 3156 | for_each_engine_masked(engine, dev_priv, hung, tmp) | ||
| 3157 | len += scnprintf(msg + len, sizeof(msg) - len, | ||
| 3158 | "%s, ", engine->name); | ||
| 3159 | msg[len-2] = '\0'; | ||
| 3160 | |||
| 3161 | return i915_handle_error(dev_priv, hung, msg); | ||
| 3162 | } | ||
| 3163 | |||
| 3164 | /* Reset timer in case GPU hangs without another request being added */ | ||
| 3165 | if (busy_count) | ||
| 3166 | i915_queue_hangcheck(dev_priv); | ||
| 3167 | } | ||
| 3168 | |||
| 3169 | static void ibx_irq_reset(struct drm_device *dev) | 2851 | static void ibx_irq_reset(struct drm_device *dev) |
| 3170 | { | 2852 | { |
| 3171 | struct drm_i915_private *dev_priv = to_i915(dev); | 2853 | struct drm_i915_private *dev_priv = to_i915(dev); |
| @@ -3545,11 +3227,13 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev) | |||
| 3545 | * RPS interrupts will get enabled/disabled on demand when RPS | 3227 | * RPS interrupts will get enabled/disabled on demand when RPS |
| 3546 | * itself is enabled/disabled. | 3228 | * itself is enabled/disabled. |
| 3547 | */ | 3229 | */ |
| 3548 | if (HAS_VEBOX(dev)) | 3230 | if (HAS_VEBOX(dev_priv)) { |
| 3549 | pm_irqs |= PM_VEBOX_USER_INTERRUPT; | 3231 | pm_irqs |= PM_VEBOX_USER_INTERRUPT; |
| 3232 | dev_priv->pm_ier |= PM_VEBOX_USER_INTERRUPT; | ||
| 3233 | } | ||
| 3550 | 3234 | ||
| 3551 | dev_priv->pm_irq_mask = 0xffffffff; | 3235 | dev_priv->pm_imr = 0xffffffff; |
| 3552 | GEN5_IRQ_INIT(GEN6_PM, dev_priv->pm_irq_mask, pm_irqs); | 3236 | GEN5_IRQ_INIT(GEN6_PM, dev_priv->pm_imr, pm_irqs); |
| 3553 | } | 3237 | } |
| 3554 | } | 3238 | } |
| 3555 | 3239 | ||
| @@ -3669,14 +3353,15 @@ static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv) | |||
| 3669 | if (HAS_L3_DPF(dev_priv)) | 3353 | if (HAS_L3_DPF(dev_priv)) |
| 3670 | gt_interrupts[0] |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT; | 3354 | gt_interrupts[0] |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT; |
| 3671 | 3355 | ||
| 3672 | dev_priv->pm_irq_mask = 0xffffffff; | 3356 | dev_priv->pm_ier = 0x0; |
| 3357 | dev_priv->pm_imr = ~dev_priv->pm_ier; | ||
| 3673 | GEN8_IRQ_INIT_NDX(GT, 0, ~gt_interrupts[0], gt_interrupts[0]); | 3358 | GEN8_IRQ_INIT_NDX(GT, 0, ~gt_interrupts[0], gt_interrupts[0]); |
| 3674 | GEN8_IRQ_INIT_NDX(GT, 1, ~gt_interrupts[1], gt_interrupts[1]); | 3359 | GEN8_IRQ_INIT_NDX(GT, 1, ~gt_interrupts[1], gt_interrupts[1]); |
| 3675 | /* | 3360 | /* |
| 3676 | * RPS interrupts will get enabled/disabled on demand when RPS itself | 3361 | * RPS interrupts will get enabled/disabled on demand when RPS itself |
| 3677 | * is enabled/disabled. | 3362 | * is enabled/disabled. Same wil be the case for GuC interrupts. |
| 3678 | */ | 3363 | */ |
| 3679 | GEN8_IRQ_INIT_NDX(GT, 2, dev_priv->pm_irq_mask, 0); | 3364 | GEN8_IRQ_INIT_NDX(GT, 2, dev_priv->pm_imr, dev_priv->pm_ier); |
| 3680 | GEN8_IRQ_INIT_NDX(GT, 3, ~gt_interrupts[3], gt_interrupts[3]); | 3365 | GEN8_IRQ_INIT_NDX(GT, 3, ~gt_interrupts[3], gt_interrupts[3]); |
| 3681 | } | 3366 | } |
| 3682 | 3367 | ||
| @@ -4460,6 +4145,9 @@ void intel_irq_init(struct drm_i915_private *dev_priv) | |||
| 4460 | INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work); | 4145 | INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work); |
| 4461 | INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work); | 4146 | INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work); |
| 4462 | 4147 | ||
| 4148 | if (HAS_GUC_SCHED(dev)) | ||
| 4149 | dev_priv->pm_guc_events = GEN9_GUC_TO_HOST_INT_EVENT; | ||
| 4150 | |||
| 4463 | /* Let's track the enabled rps events */ | 4151 | /* Let's track the enabled rps events */ |
| 4464 | if (IS_VALLEYVIEW(dev_priv)) | 4152 | if (IS_VALLEYVIEW(dev_priv)) |
| 4465 | /* WaGsvRC0ResidencyMethod:vlv */ | 4153 | /* WaGsvRC0ResidencyMethod:vlv */ |
| @@ -4481,9 +4169,6 @@ void intel_irq_init(struct drm_i915_private *dev_priv) | |||
| 4481 | if (INTEL_INFO(dev_priv)->gen >= 8) | 4169 | if (INTEL_INFO(dev_priv)->gen >= 8) |
| 4482 | dev_priv->rps.pm_intr_keep |= GEN8_PMINTR_REDIRECT_TO_GUC; | 4170 | dev_priv->rps.pm_intr_keep |= GEN8_PMINTR_REDIRECT_TO_GUC; |
| 4483 | 4171 | ||
| 4484 | INIT_DELAYED_WORK(&dev_priv->gpu_error.hangcheck_work, | ||
| 4485 | i915_hangcheck_elapsed); | ||
| 4486 | |||
| 4487 | if (IS_GEN2(dev_priv)) { | 4172 | if (IS_GEN2(dev_priv)) { |
| 4488 | /* Gen2 doesn't have a hardware frame counter */ | 4173 | /* Gen2 doesn't have a hardware frame counter */ |
| 4489 | dev->max_vblank_count = 0; | 4174 | dev->max_vblank_count = 0; |
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 31e6edd08dd0..2a419500b81a 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c | |||
| @@ -288,7 +288,8 @@ static const struct intel_device_info intel_haswell_info = { | |||
| 288 | #define BDW_FEATURES \ | 288 | #define BDW_FEATURES \ |
| 289 | HSW_FEATURES, \ | 289 | HSW_FEATURES, \ |
| 290 | BDW_COLORS, \ | 290 | BDW_COLORS, \ |
| 291 | .has_logical_ring_contexts = 1 | 291 | .has_logical_ring_contexts = 1, \ |
| 292 | .has_64bit_reloc = 1 | ||
| 292 | 293 | ||
| 293 | static const struct intel_device_info intel_broadwell_info = { | 294 | static const struct intel_device_info intel_broadwell_info = { |
| 294 | BDW_FEATURES, | 295 | BDW_FEATURES, |
| @@ -308,6 +309,7 @@ static const struct intel_device_info intel_cherryview_info = { | |||
| 308 | .has_hotplug = 1, | 309 | .has_hotplug = 1, |
| 309 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, | 310 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, |
| 310 | .is_cherryview = 1, | 311 | .is_cherryview = 1, |
| 312 | .has_64bit_reloc = 1, | ||
| 311 | .has_psr = 1, | 313 | .has_psr = 1, |
| 312 | .has_runtime_pm = 1, | 314 | .has_runtime_pm = 1, |
| 313 | .has_resource_streamer = 1, | 315 | .has_resource_streamer = 1, |
| @@ -347,6 +349,7 @@ static const struct intel_device_info intel_broxton_info = { | |||
| 347 | .has_hotplug = 1, | 349 | .has_hotplug = 1, |
| 348 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, | 350 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, |
| 349 | .num_pipes = 3, | 351 | .num_pipes = 3, |
| 352 | .has_64bit_reloc = 1, | ||
| 350 | .has_ddi = 1, | 353 | .has_ddi = 1, |
| 351 | .has_fpga_dbg = 1, | 354 | .has_fpga_dbg = 1, |
| 352 | .has_fbc = 1, | 355 | .has_fbc = 1, |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 00efaa13974d..3361d7ffc63e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -830,96 +830,7 @@ enum skl_disp_power_wells { | |||
| 830 | #define CCK_FREQUENCY_STATUS_SHIFT 8 | 830 | #define CCK_FREQUENCY_STATUS_SHIFT 8 |
| 831 | #define CCK_FREQUENCY_VALUES (0x1f << 0) | 831 | #define CCK_FREQUENCY_VALUES (0x1f << 0) |
| 832 | 832 | ||
| 833 | /** | 833 | /* DPIO registers */ |
| 834 | * DOC: DPIO | ||
| 835 | * | ||
| 836 | * VLV, CHV and BXT have slightly peculiar display PHYs for driving DP/HDMI | ||
| 837 | * ports. DPIO is the name given to such a display PHY. These PHYs | ||
| 838 | * don't follow the standard programming model using direct MMIO | ||
| 839 | * registers, and instead their registers must be accessed trough IOSF | ||
| 840 | * sideband. VLV has one such PHY for driving ports B and C, and CHV | ||
| 841 | * adds another PHY for driving port D. Each PHY responds to specific | ||
| 842 | * IOSF-SB port. | ||
| 843 | * | ||
| 844 | * Each display PHY is made up of one or two channels. Each channel | ||
| 845 | * houses a common lane part which contains the PLL and other common | ||
| 846 | * logic. CH0 common lane also contains the IOSF-SB logic for the | ||
| 847 | * Common Register Interface (CRI) ie. the DPIO registers. CRI clock | ||
| 848 | * must be running when any DPIO registers are accessed. | ||
| 849 | * | ||
| 850 | * In addition to having their own registers, the PHYs are also | ||
| 851 | * controlled through some dedicated signals from the display | ||
| 852 | * controller. These include PLL reference clock enable, PLL enable, | ||
| 853 | * and CRI clock selection, for example. | ||
| 854 | * | ||
| 855 | * Eeach channel also has two splines (also called data lanes), and | ||
| 856 | * each spline is made up of one Physical Access Coding Sub-Layer | ||
| 857 | * (PCS) block and two TX lanes. So each channel has two PCS blocks | ||
| 858 | * and four TX lanes. The TX lanes are used as DP lanes or TMDS | ||
| 859 | * data/clock pairs depending on the output type. | ||
| 860 | * | ||
| 861 | * Additionally the PHY also contains an AUX lane with AUX blocks | ||
| 862 | * for each channel. This is used for DP AUX communication, but | ||
| 863 | * this fact isn't really relevant for the driver since AUX is | ||
| 864 | * controlled from the display controller side. No DPIO registers | ||
| 865 | * need to be accessed during AUX communication, | ||
| 866 | * | ||
| 867 | * Generally on VLV/CHV the common lane corresponds to the pipe and | ||
| 868 | * the spline (PCS/TX) corresponds to the port. | ||
| 869 | * | ||
| 870 | * For dual channel PHY (VLV/CHV): | ||
| 871 | * | ||
| 872 | * pipe A == CMN/PLL/REF CH0 | ||
| 873 | * | ||
| 874 | * pipe B == CMN/PLL/REF CH1 | ||
| 875 | * | ||
| 876 | * port B == PCS/TX CH0 | ||
| 877 | * | ||
| 878 | * port C == PCS/TX CH1 | ||
| 879 | * | ||
| 880 | * This is especially important when we cross the streams | ||
| 881 | * ie. drive port B with pipe B, or port C with pipe A. | ||
| 882 | * | ||
| 883 | * For single channel PHY (CHV): | ||
| 884 | * | ||
| 885 | * pipe C == CMN/PLL/REF CH0 | ||
| 886 | * | ||
| 887 | * port D == PCS/TX CH0 | ||
| 888 | * | ||
| 889 | * On BXT the entire PHY channel corresponds to the port. That means | ||
| 890 | * the PLL is also now associated with the port rather than the pipe, | ||
| 891 | * and so the clock needs to be routed to the appropriate transcoder. | ||
| 892 | * Port A PLL is directly connected to transcoder EDP and port B/C | ||
| 893 | * PLLs can be routed to any transcoder A/B/C. | ||
| 894 | * | ||
| 895 | * Note: DDI0 is digital port B, DD1 is digital port C, and DDI2 is | ||
| 896 | * digital port D (CHV) or port A (BXT). :: | ||
| 897 | * | ||
| 898 | * | ||
| 899 | * Dual channel PHY (VLV/CHV/BXT) | ||
| 900 | * --------------------------------- | ||
| 901 | * | CH0 | CH1 | | ||
| 902 | * | CMN/PLL/REF | CMN/PLL/REF | | ||
| 903 | * |---------------|---------------| Display PHY | ||
| 904 | * | PCS01 | PCS23 | PCS01 | PCS23 | | ||
| 905 | * |-------|-------|-------|-------| | ||
| 906 | * |TX0|TX1|TX2|TX3|TX0|TX1|TX2|TX3| | ||
| 907 | * --------------------------------- | ||
| 908 | * | DDI0 | DDI1 | DP/HDMI ports | ||
| 909 | * --------------------------------- | ||
| 910 | * | ||
| 911 | * Single channel PHY (CHV/BXT) | ||
| 912 | * ----------------- | ||
| 913 | * | CH0 | | ||
| 914 | * | CMN/PLL/REF | | ||
| 915 | * |---------------| Display PHY | ||
| 916 | * | PCS01 | PCS23 | | ||
| 917 | * |-------|-------| | ||
| 918 | * |TX0|TX1|TX2|TX3| | ||
| 919 | * ----------------- | ||
| 920 | * | DDI2 | DP/HDMI port | ||
| 921 | * ----------------- | ||
| 922 | */ | ||
| 923 | #define DPIO_DEVFN 0 | 834 | #define DPIO_DEVFN 0 |
| 924 | 835 | ||
| 925 | #define DPIO_CTL _MMIO(VLV_DISPLAY_BASE + 0x2110) | 836 | #define DPIO_CTL _MMIO(VLV_DISPLAY_BASE + 0x2110) |
| @@ -1275,7 +1186,19 @@ enum skl_disp_power_wells { | |||
| 1275 | #define DPIO_UPAR_SHIFT 30 | 1186 | #define DPIO_UPAR_SHIFT 30 |
| 1276 | 1187 | ||
| 1277 | /* BXT PHY registers */ | 1188 | /* BXT PHY registers */ |
| 1278 | #define _BXT_PHY(phy, a, b) _MMIO_PIPE((phy), (a), (b)) | 1189 | #define _BXT_PHY0_BASE 0x6C000 |
| 1190 | #define _BXT_PHY1_BASE 0x162000 | ||
| 1191 | #define BXT_PHY_BASE(phy) _PIPE((phy), _BXT_PHY0_BASE, \ | ||
| 1192 | _BXT_PHY1_BASE) | ||
| 1193 | |||
| 1194 | #define _BXT_PHY(phy, reg) \ | ||
| 1195 | _MMIO(BXT_PHY_BASE(phy) - _BXT_PHY0_BASE + (reg)) | ||
| 1196 | |||
| 1197 | #define _BXT_PHY_CH(phy, ch, reg_ch0, reg_ch1) \ | ||
| 1198 | (BXT_PHY_BASE(phy) + _PIPE((ch), (reg_ch0) - _BXT_PHY0_BASE, \ | ||
| 1199 | (reg_ch1) - _BXT_PHY0_BASE)) | ||
| 1200 | #define _MMIO_BXT_PHY_CH(phy, ch, reg_ch0, reg_ch1) \ | ||
| 1201 | _MMIO(_BXT_PHY_CH(phy, ch, reg_ch0, reg_ch1)) | ||
| 1279 | 1202 | ||
| 1280 | #define BXT_P_CR_GT_DISP_PWRON _MMIO(0x138090) | 1203 | #define BXT_P_CR_GT_DISP_PWRON _MMIO(0x138090) |
| 1281 | #define GT_DISPLAY_POWER_ON(phy) (1 << (phy)) | 1204 | #define GT_DISPLAY_POWER_ON(phy) (1 << (phy)) |
| @@ -1292,8 +1215,8 @@ enum skl_disp_power_wells { | |||
| 1292 | #define _PHY_CTL_FAMILY_EDP 0x64C80 | 1215 | #define _PHY_CTL_FAMILY_EDP 0x64C80 |
| 1293 | #define _PHY_CTL_FAMILY_DDI 0x64C90 | 1216 | #define _PHY_CTL_FAMILY_DDI 0x64C90 |
| 1294 | #define COMMON_RESET_DIS (1 << 31) | 1217 | #define COMMON_RESET_DIS (1 << 31) |
| 1295 | #define BXT_PHY_CTL_FAMILY(phy) _BXT_PHY((phy), _PHY_CTL_FAMILY_DDI, \ | 1218 | #define BXT_PHY_CTL_FAMILY(phy) _MMIO_PIPE((phy), _PHY_CTL_FAMILY_DDI, \ |
| 1296 | _PHY_CTL_FAMILY_EDP) | 1219 | _PHY_CTL_FAMILY_EDP) |
| 1297 | 1220 | ||
| 1298 | /* BXT PHY PLL registers */ | 1221 | /* BXT PHY PLL registers */ |
| 1299 | #define _PORT_PLL_A 0x46074 | 1222 | #define _PORT_PLL_A 0x46074 |
| @@ -1313,18 +1236,18 @@ enum skl_disp_power_wells { | |||
| 1313 | #define PORT_PLL_P2_SHIFT 8 | 1236 | #define PORT_PLL_P2_SHIFT 8 |
| 1314 | #define PORT_PLL_P2_MASK (0x1f << PORT_PLL_P2_SHIFT) | 1237 | #define PORT_PLL_P2_MASK (0x1f << PORT_PLL_P2_SHIFT) |
| 1315 | #define PORT_PLL_P2(x) ((x) << PORT_PLL_P2_SHIFT) | 1238 | #define PORT_PLL_P2(x) ((x) << PORT_PLL_P2_SHIFT) |
| 1316 | #define BXT_PORT_PLL_EBB_0(port) _MMIO_PORT3(port, _PORT_PLL_EBB_0_A, \ | 1239 | #define BXT_PORT_PLL_EBB_0(phy, ch) _MMIO_BXT_PHY_CH(phy, ch, \ |
| 1317 | _PORT_PLL_EBB_0_B, \ | 1240 | _PORT_PLL_EBB_0_B, \ |
| 1318 | _PORT_PLL_EBB_0_C) | 1241 | _PORT_PLL_EBB_0_C) |
| 1319 | 1242 | ||
| 1320 | #define _PORT_PLL_EBB_4_A 0x162038 | 1243 | #define _PORT_PLL_EBB_4_A 0x162038 |
| 1321 | #define _PORT_PLL_EBB_4_B 0x6C038 | 1244 | #define _PORT_PLL_EBB_4_B 0x6C038 |
| 1322 | #define _PORT_PLL_EBB_4_C 0x6C344 | 1245 | #define _PORT_PLL_EBB_4_C 0x6C344 |
| 1323 | #define PORT_PLL_10BIT_CLK_ENABLE (1 << 13) | 1246 | #define PORT_PLL_10BIT_CLK_ENABLE (1 << 13) |
| 1324 | #define PORT_PLL_RECALIBRATE (1 << 14) | 1247 | #define PORT_PLL_RECALIBRATE (1 << 14) |
| 1325 | #define BXT_PORT_PLL_EBB_4(port) _MMIO_PORT3(port, _PORT_PLL_EBB_4_A, \ | 1248 | #define BXT_PORT_PLL_EBB_4(phy, ch) _MMIO_BXT_PHY_CH(phy, ch, \ |
| 1326 | _PORT_PLL_EBB_4_B, \ | 1249 | _PORT_PLL_EBB_4_B, \ |
| 1327 | _PORT_PLL_EBB_4_C) | 1250 | _PORT_PLL_EBB_4_C) |
| 1328 | 1251 | ||
| 1329 | #define _PORT_PLL_0_A 0x162100 | 1252 | #define _PORT_PLL_0_A 0x162100 |
| 1330 | #define _PORT_PLL_0_B 0x6C100 | 1253 | #define _PORT_PLL_0_B 0x6C100 |
| @@ -1355,57 +1278,56 @@ enum skl_disp_power_wells { | |||
| 1355 | #define PORT_PLL_DCO_AMP_DEFAULT 15 | 1278 | #define PORT_PLL_DCO_AMP_DEFAULT 15 |
| 1356 | #define PORT_PLL_DCO_AMP_MASK 0x3c00 | 1279 | #define PORT_PLL_DCO_AMP_MASK 0x3c00 |
| 1357 | #define PORT_PLL_DCO_AMP(x) ((x)<<10) | 1280 | #define PORT_PLL_DCO_AMP(x) ((x)<<10) |
| 1358 | #define _PORT_PLL_BASE(port) _PORT3(port, _PORT_PLL_0_A, \ | 1281 | #define _PORT_PLL_BASE(phy, ch) _BXT_PHY_CH(phy, ch, \ |
| 1359 | _PORT_PLL_0_B, \ | 1282 | _PORT_PLL_0_B, \ |
| 1360 | _PORT_PLL_0_C) | 1283 | _PORT_PLL_0_C) |
| 1361 | #define BXT_PORT_PLL(port, idx) _MMIO(_PORT_PLL_BASE(port) + (idx) * 4) | 1284 | #define BXT_PORT_PLL(phy, ch, idx) _MMIO(_PORT_PLL_BASE(phy, ch) + \ |
| 1285 | (idx) * 4) | ||
| 1362 | 1286 | ||
| 1363 | /* BXT PHY common lane registers */ | 1287 | /* BXT PHY common lane registers */ |
| 1364 | #define _PORT_CL1CM_DW0_A 0x162000 | 1288 | #define _PORT_CL1CM_DW0_A 0x162000 |
| 1365 | #define _PORT_CL1CM_DW0_BC 0x6C000 | 1289 | #define _PORT_CL1CM_DW0_BC 0x6C000 |
| 1366 | #define PHY_POWER_GOOD (1 << 16) | 1290 | #define PHY_POWER_GOOD (1 << 16) |
| 1367 | #define PHY_RESERVED (1 << 7) | 1291 | #define PHY_RESERVED (1 << 7) |
| 1368 | #define BXT_PORT_CL1CM_DW0(phy) _BXT_PHY((phy), _PORT_CL1CM_DW0_BC, \ | 1292 | #define BXT_PORT_CL1CM_DW0(phy) _BXT_PHY((phy), _PORT_CL1CM_DW0_BC) |
| 1369 | _PORT_CL1CM_DW0_A) | ||
| 1370 | 1293 | ||
| 1371 | #define _PORT_CL1CM_DW9_A 0x162024 | 1294 | #define _PORT_CL1CM_DW9_A 0x162024 |
| 1372 | #define _PORT_CL1CM_DW9_BC 0x6C024 | 1295 | #define _PORT_CL1CM_DW9_BC 0x6C024 |
| 1373 | #define IREF0RC_OFFSET_SHIFT 8 | 1296 | #define IREF0RC_OFFSET_SHIFT 8 |
| 1374 | #define IREF0RC_OFFSET_MASK (0xFF << IREF0RC_OFFSET_SHIFT) | 1297 | #define IREF0RC_OFFSET_MASK (0xFF << IREF0RC_OFFSET_SHIFT) |
| 1375 | #define BXT_PORT_CL1CM_DW9(phy) _BXT_PHY((phy), _PORT_CL1CM_DW9_BC, \ | 1298 | #define BXT_PORT_CL1CM_DW9(phy) _BXT_PHY((phy), _PORT_CL1CM_DW9_BC) |
| 1376 | _PORT_CL1CM_DW9_A) | ||
| 1377 | 1299 | ||
| 1378 | #define _PORT_CL1CM_DW10_A 0x162028 | 1300 | #define _PORT_CL1CM_DW10_A 0x162028 |
| 1379 | #define _PORT_CL1CM_DW10_BC 0x6C028 | 1301 | #define _PORT_CL1CM_DW10_BC 0x6C028 |
| 1380 | #define IREF1RC_OFFSET_SHIFT 8 | 1302 | #define IREF1RC_OFFSET_SHIFT 8 |
| 1381 | #define IREF1RC_OFFSET_MASK (0xFF << IREF1RC_OFFSET_SHIFT) | 1303 | #define IREF1RC_OFFSET_MASK (0xFF << IREF1RC_OFFSET_SHIFT) |
| 1382 | #define BXT_PORT_CL1CM_DW10(phy) _BXT_PHY((phy), _PORT_CL1CM_DW10_BC, \ | 1304 | #define BXT_PORT_CL1CM_DW10(phy) _BXT_PHY((phy), _PORT_CL1CM_DW10_BC) |
| 1383 | _PORT_CL1CM_DW10_A) | ||
| 1384 | 1305 | ||
| 1385 | #define _PORT_CL1CM_DW28_A 0x162070 | 1306 | #define _PORT_CL1CM_DW28_A 0x162070 |
| 1386 | #define _PORT_CL1CM_DW28_BC 0x6C070 | 1307 | #define _PORT_CL1CM_DW28_BC 0x6C070 |
| 1387 | #define OCL1_POWER_DOWN_EN (1 << 23) | 1308 | #define OCL1_POWER_DOWN_EN (1 << 23) |
| 1388 | #define DW28_OLDO_DYN_PWR_DOWN_EN (1 << 22) | 1309 | #define DW28_OLDO_DYN_PWR_DOWN_EN (1 << 22) |
| 1389 | #define SUS_CLK_CONFIG 0x3 | 1310 | #define SUS_CLK_CONFIG 0x3 |
| 1390 | #define BXT_PORT_CL1CM_DW28(phy) _BXT_PHY((phy), _PORT_CL1CM_DW28_BC, \ | 1311 | #define BXT_PORT_CL1CM_DW28(phy) _BXT_PHY((phy), _PORT_CL1CM_DW28_BC) |
| 1391 | _PORT_CL1CM_DW28_A) | ||
| 1392 | 1312 | ||
| 1393 | #define _PORT_CL1CM_DW30_A 0x162078 | 1313 | #define _PORT_CL1CM_DW30_A 0x162078 |
| 1394 | #define _PORT_CL1CM_DW30_BC 0x6C078 | 1314 | #define _PORT_CL1CM_DW30_BC 0x6C078 |
| 1395 | #define OCL2_LDOFUSE_PWR_DIS (1 << 6) | 1315 | #define OCL2_LDOFUSE_PWR_DIS (1 << 6) |
| 1396 | #define BXT_PORT_CL1CM_DW30(phy) _BXT_PHY((phy), _PORT_CL1CM_DW30_BC, \ | 1316 | #define BXT_PORT_CL1CM_DW30(phy) _BXT_PHY((phy), _PORT_CL1CM_DW30_BC) |
| 1397 | _PORT_CL1CM_DW30_A) | ||
| 1398 | 1317 | ||
| 1399 | /* Defined for PHY0 only */ | 1318 | /* The spec defines this only for BXT PHY0, but lets assume that this |
| 1400 | #define BXT_PORT_CL2CM_DW6_BC _MMIO(0x6C358) | 1319 | * would exist for PHY1 too if it had a second channel. |
| 1320 | */ | ||
| 1321 | #define _PORT_CL2CM_DW6_A 0x162358 | ||
| 1322 | #define _PORT_CL2CM_DW6_BC 0x6C358 | ||
| 1323 | #define BXT_PORT_CL2CM_DW6(phy) _BXT_PHY((phy), _PORT_CL2CM_DW6_BC) | ||
| 1401 | #define DW6_OLDO_DYN_PWR_DOWN_EN (1 << 28) | 1324 | #define DW6_OLDO_DYN_PWR_DOWN_EN (1 << 28) |
| 1402 | 1325 | ||
| 1403 | /* BXT PHY Ref registers */ | 1326 | /* BXT PHY Ref registers */ |
| 1404 | #define _PORT_REF_DW3_A 0x16218C | 1327 | #define _PORT_REF_DW3_A 0x16218C |
| 1405 | #define _PORT_REF_DW3_BC 0x6C18C | 1328 | #define _PORT_REF_DW3_BC 0x6C18C |
| 1406 | #define GRC_DONE (1 << 22) | 1329 | #define GRC_DONE (1 << 22) |
| 1407 | #define BXT_PORT_REF_DW3(phy) _BXT_PHY((phy), _PORT_REF_DW3_BC, \ | 1330 | #define BXT_PORT_REF_DW3(phy) _BXT_PHY((phy), _PORT_REF_DW3_BC) |
| 1408 | _PORT_REF_DW3_A) | ||
| 1409 | 1331 | ||
| 1410 | #define _PORT_REF_DW6_A 0x162198 | 1332 | #define _PORT_REF_DW6_A 0x162198 |
| 1411 | #define _PORT_REF_DW6_BC 0x6C198 | 1333 | #define _PORT_REF_DW6_BC 0x6C198 |
| @@ -1416,15 +1338,13 @@ enum skl_disp_power_wells { | |||
| 1416 | #define GRC_CODE_SLOW_SHIFT 8 | 1338 | #define GRC_CODE_SLOW_SHIFT 8 |
| 1417 | #define GRC_CODE_SLOW_MASK (0xFF << GRC_CODE_SLOW_SHIFT) | 1339 | #define GRC_CODE_SLOW_MASK (0xFF << GRC_CODE_SLOW_SHIFT) |
| 1418 | #define GRC_CODE_NOM_MASK 0xFF | 1340 | #define GRC_CODE_NOM_MASK 0xFF |
| 1419 | #define BXT_PORT_REF_DW6(phy) _BXT_PHY((phy), _PORT_REF_DW6_BC, \ | 1341 | #define BXT_PORT_REF_DW6(phy) _BXT_PHY((phy), _PORT_REF_DW6_BC) |
| 1420 | _PORT_REF_DW6_A) | ||
| 1421 | 1342 | ||
| 1422 | #define _PORT_REF_DW8_A 0x1621A0 | 1343 | #define _PORT_REF_DW8_A 0x1621A0 |
| 1423 | #define _PORT_REF_DW8_BC 0x6C1A0 | 1344 | #define _PORT_REF_DW8_BC 0x6C1A0 |
| 1424 | #define GRC_DIS (1 << 15) | 1345 | #define GRC_DIS (1 << 15) |
| 1425 | #define GRC_RDY_OVRD (1 << 1) | 1346 | #define GRC_RDY_OVRD (1 << 1) |
| 1426 | #define BXT_PORT_REF_DW8(phy) _BXT_PHY((phy), _PORT_REF_DW8_BC, \ | 1347 | #define BXT_PORT_REF_DW8(phy) _BXT_PHY((phy), _PORT_REF_DW8_BC) |
| 1427 | _PORT_REF_DW8_A) | ||
| 1428 | 1348 | ||
| 1429 | /* BXT PHY PCS registers */ | 1349 | /* BXT PHY PCS registers */ |
| 1430 | #define _PORT_PCS_DW10_LN01_A 0x162428 | 1350 | #define _PORT_PCS_DW10_LN01_A 0x162428 |
| @@ -1433,12 +1353,13 @@ enum skl_disp_power_wells { | |||
| 1433 | #define _PORT_PCS_DW10_GRP_A 0x162C28 | 1353 | #define _PORT_PCS_DW10_GRP_A 0x162C28 |
| 1434 | #define _PORT_PCS_DW10_GRP_B 0x6CC28 | 1354 | #define _PORT_PCS_DW10_GRP_B 0x6CC28 |
| 1435 | #define _PORT_PCS_DW10_GRP_C 0x6CE28 | 1355 | #define _PORT_PCS_DW10_GRP_C 0x6CE28 |
| 1436 | #define BXT_PORT_PCS_DW10_LN01(port) _MMIO_PORT3(port, _PORT_PCS_DW10_LN01_A, \ | 1356 | #define BXT_PORT_PCS_DW10_LN01(phy, ch) _MMIO_BXT_PHY_CH(phy, ch, \ |
| 1437 | _PORT_PCS_DW10_LN01_B, \ | 1357 | _PORT_PCS_DW10_LN01_B, \ |
| 1438 | _PORT_PCS_DW10_LN01_C) | 1358 | _PORT_PCS_DW10_LN01_C) |
| 1439 | #define BXT_PORT_PCS_DW10_GRP(port) _MMIO_PORT3(port, _PORT_PCS_DW10_GRP_A, \ | 1359 | #define BXT_PORT_PCS_DW10_GRP(phy, ch) _MMIO_BXT_PHY_CH(phy, ch, \ |
| 1440 | _PORT_PCS_DW10_GRP_B, \ | 1360 | _PORT_PCS_DW10_GRP_B, \ |
| 1441 | _PORT_PCS_DW10_GRP_C) | 1361 | _PORT_PCS_DW10_GRP_C) |
| 1362 | |||
| 1442 | #define TX2_SWING_CALC_INIT (1 << 31) | 1363 | #define TX2_SWING_CALC_INIT (1 << 31) |
| 1443 | #define TX1_SWING_CALC_INIT (1 << 30) | 1364 | #define TX1_SWING_CALC_INIT (1 << 30) |
| 1444 | 1365 | ||
| @@ -1453,15 +1374,15 @@ enum skl_disp_power_wells { | |||
| 1453 | #define _PORT_PCS_DW12_GRP_C 0x6CE30 | 1374 | #define _PORT_PCS_DW12_GRP_C 0x6CE30 |
| 1454 | #define LANESTAGGER_STRAP_OVRD (1 << 6) | 1375 | #define LANESTAGGER_STRAP_OVRD (1 << 6) |
| 1455 | #define LANE_STAGGER_MASK 0x1F | 1376 | #define LANE_STAGGER_MASK 0x1F |
| 1456 | #define BXT_PORT_PCS_DW12_LN01(port) _MMIO_PORT3(port, _PORT_PCS_DW12_LN01_A, \ | 1377 | #define BXT_PORT_PCS_DW12_LN01(phy, ch) _MMIO_BXT_PHY_CH(phy, ch, \ |
| 1457 | _PORT_PCS_DW12_LN01_B, \ | 1378 | _PORT_PCS_DW12_LN01_B, \ |
| 1458 | _PORT_PCS_DW12_LN01_C) | 1379 | _PORT_PCS_DW12_LN01_C) |
| 1459 | #define BXT_PORT_PCS_DW12_LN23(port) _MMIO_PORT3(port, _PORT_PCS_DW12_LN23_A, \ | 1380 | #define BXT_PORT_PCS_DW12_LN23(phy, ch) _MMIO_BXT_PHY_CH(phy, ch, \ |
| 1460 | _PORT_PCS_DW12_LN23_B, \ | 1381 | _PORT_PCS_DW12_LN23_B, \ |
| 1461 | _PORT_PCS_DW12_LN23_C) | 1382 | _PORT_PCS_DW12_LN23_C) |
| 1462 | #define BXT_PORT_PCS_DW12_GRP(port) _MMIO_PORT3(port, _PORT_PCS_DW12_GRP_A, \ | 1383 | #define BXT_PORT_PCS_DW12_GRP(phy, ch) _MMIO_BXT_PHY_CH(phy, ch, \ |
| 1463 | _PORT_PCS_DW12_GRP_B, \ | 1384 | _PORT_PCS_DW12_GRP_B, \ |
| 1464 | _PORT_PCS_DW12_GRP_C) | 1385 | _PORT_PCS_DW12_GRP_C) |
| 1465 | 1386 | ||
| 1466 | /* BXT PHY TX registers */ | 1387 | /* BXT PHY TX registers */ |
| 1467 | #define _BXT_LANE_OFFSET(lane) (((lane) >> 1) * 0x200 + \ | 1388 | #define _BXT_LANE_OFFSET(lane) (((lane) >> 1) * 0x200 + \ |
| @@ -1473,12 +1394,12 @@ enum skl_disp_power_wells { | |||
| 1473 | #define _PORT_TX_DW2_GRP_A 0x162D08 | 1394 | #define _PORT_TX_DW2_GRP_A 0x162D08 |
| 1474 | #define _PORT_TX_DW2_GRP_B 0x6CD08 | 1395 | #define _PORT_TX_DW2_GRP_B 0x6CD08 |
| 1475 | #define _PORT_TX_DW2_GRP_C 0x6CF08 | 1396 | #define _PORT_TX_DW2_GRP_C 0x6CF08 |
| 1476 | #define BXT_PORT_TX_DW2_GRP(port) _MMIO_PORT3(port, _PORT_TX_DW2_GRP_A, \ | 1397 | #define BXT_PORT_TX_DW2_LN0(phy, ch) _MMIO_BXT_PHY_CH(phy, ch, \ |
| 1477 | _PORT_TX_DW2_GRP_B, \ | 1398 | _PORT_TX_DW2_LN0_B, \ |
| 1478 | _PORT_TX_DW2_GRP_C) | 1399 | _PORT_TX_DW2_LN0_C) |
| 1479 | #define BXT_PORT_TX_DW2_LN0(port) _MMIO_PORT3(port, _PORT_TX_DW2_LN0_A, \ | 1400 | #define BXT_PORT_TX_DW2_GRP(phy, ch) _MMIO_BXT_PHY_CH(phy, ch, \ |
| 1480 | _PORT_TX_DW2_LN0_B, \ | 1401 | _PORT_TX_DW2_GRP_B, \ |
| 1481 | _PORT_TX_DW2_LN0_C) | 1402 | _PORT_TX_DW2_GRP_C) |
| 1482 | #define MARGIN_000_SHIFT 16 | 1403 | #define MARGIN_000_SHIFT 16 |
| 1483 | #define MARGIN_000 (0xFF << MARGIN_000_SHIFT) | 1404 | #define MARGIN_000 (0xFF << MARGIN_000_SHIFT) |
| 1484 | #define UNIQ_TRANS_SCALE_SHIFT 8 | 1405 | #define UNIQ_TRANS_SCALE_SHIFT 8 |
| @@ -1490,12 +1411,12 @@ enum skl_disp_power_wells { | |||
| 1490 | #define _PORT_TX_DW3_GRP_A 0x162D0C | 1411 | #define _PORT_TX_DW3_GRP_A 0x162D0C |
| 1491 | #define _PORT_TX_DW3_GRP_B 0x6CD0C | 1412 | #define _PORT_TX_DW3_GRP_B 0x6CD0C |
| 1492 | #define _PORT_TX_DW3_GRP_C 0x6CF0C | 1413 | #define _PORT_TX_DW3_GRP_C 0x6CF0C |
| 1493 | #define BXT_PORT_TX_DW3_GRP(port) _MMIO_PORT3(port, _PORT_TX_DW3_GRP_A, \ | 1414 | #define BXT_PORT_TX_DW3_LN0(phy, ch) _MMIO_BXT_PHY_CH(phy, ch, \ |
| 1494 | _PORT_TX_DW3_GRP_B, \ | 1415 | _PORT_TX_DW3_LN0_B, \ |
| 1495 | _PORT_TX_DW3_GRP_C) | 1416 | _PORT_TX_DW3_LN0_C) |
| 1496 | #define BXT_PORT_TX_DW3_LN0(port) _MMIO_PORT3(port, _PORT_TX_DW3_LN0_A, \ | 1417 | #define BXT_PORT_TX_DW3_GRP(phy, ch) _MMIO_BXT_PHY_CH(phy, ch, \ |
| 1497 | _PORT_TX_DW3_LN0_B, \ | 1418 | _PORT_TX_DW3_GRP_B, \ |
| 1498 | _PORT_TX_DW3_LN0_C) | 1419 | _PORT_TX_DW3_GRP_C) |
| 1499 | #define SCALE_DCOMP_METHOD (1 << 26) | 1420 | #define SCALE_DCOMP_METHOD (1 << 26) |
| 1500 | #define UNIQUE_TRANGE_EN_METHOD (1 << 27) | 1421 | #define UNIQUE_TRANGE_EN_METHOD (1 << 27) |
| 1501 | 1422 | ||
| @@ -1505,12 +1426,12 @@ enum skl_disp_power_wells { | |||
| 1505 | #define _PORT_TX_DW4_GRP_A 0x162D10 | 1426 | #define _PORT_TX_DW4_GRP_A 0x162D10 |
| 1506 | #define _PORT_TX_DW4_GRP_B 0x6CD10 | 1427 | #define _PORT_TX_DW4_GRP_B 0x6CD10 |
| 1507 | #define _PORT_TX_DW4_GRP_C 0x6CF10 | 1428 | #define _PORT_TX_DW4_GRP_C 0x6CF10 |
| 1508 | #define BXT_PORT_TX_DW4_LN0(port) _MMIO_PORT3(port, _PORT_TX_DW4_LN0_A, \ | 1429 | #define BXT_PORT_TX_DW4_LN0(phy, ch) _MMIO_BXT_PHY_CH(phy, ch, \ |
| 1509 | _PORT_TX_DW4_LN0_B, \ | 1430 | _PORT_TX_DW4_LN0_B, \ |
| 1510 | _PORT_TX_DW4_LN0_C) | 1431 | _PORT_TX_DW4_LN0_C) |
| 1511 | #define BXT_PORT_TX_DW4_GRP(port) _MMIO_PORT3(port, _PORT_TX_DW4_GRP_A, \ | 1432 | #define BXT_PORT_TX_DW4_GRP(phy, ch) _MMIO_BXT_PHY_CH(phy, ch, \ |
| 1512 | _PORT_TX_DW4_GRP_B, \ | 1433 | _PORT_TX_DW4_GRP_B, \ |
| 1513 | _PORT_TX_DW4_GRP_C) | 1434 | _PORT_TX_DW4_GRP_C) |
| 1514 | #define DEEMPH_SHIFT 24 | 1435 | #define DEEMPH_SHIFT 24 |
| 1515 | #define DE_EMPHASIS (0xFF << DEEMPH_SHIFT) | 1436 | #define DE_EMPHASIS (0xFF << DEEMPH_SHIFT) |
| 1516 | 1437 | ||
| @@ -1519,10 +1440,10 @@ enum skl_disp_power_wells { | |||
| 1519 | #define _PORT_TX_DW14_LN0_C 0x6C938 | 1440 | #define _PORT_TX_DW14_LN0_C 0x6C938 |
| 1520 | #define LATENCY_OPTIM_SHIFT 30 | 1441 | #define LATENCY_OPTIM_SHIFT 30 |
| 1521 | #define LATENCY_OPTIM (1 << LATENCY_OPTIM_SHIFT) | 1442 | #define LATENCY_OPTIM (1 << LATENCY_OPTIM_SHIFT) |
| 1522 | #define BXT_PORT_TX_DW14_LN(port, lane) _MMIO(_PORT3((port), _PORT_TX_DW14_LN0_A, \ | 1443 | #define BXT_PORT_TX_DW14_LN(phy, ch, lane) \ |
| 1523 | _PORT_TX_DW14_LN0_B, \ | 1444 | _MMIO(_BXT_PHY_CH(phy, ch, _PORT_TX_DW14_LN0_B, \ |
| 1524 | _PORT_TX_DW14_LN0_C) + \ | 1445 | _PORT_TX_DW14_LN0_C) + \ |
| 1525 | _BXT_LANE_OFFSET(lane)) | 1446 | _BXT_LANE_OFFSET(lane)) |
| 1526 | 1447 | ||
| 1527 | /* UAIMI scratch pad register 1 */ | 1448 | /* UAIMI scratch pad register 1 */ |
| 1528 | #define UAIMI_SPR1 _MMIO(0x4F074) | 1449 | #define UAIMI_SPR1 _MMIO(0x4F074) |
| @@ -2188,8 +2109,9 @@ enum skl_disp_power_wells { | |||
| 2188 | #define FBC_FENCE_OFF _MMIO(0x3218) /* BSpec typo has 321Bh */ | 2109 | #define FBC_FENCE_OFF _MMIO(0x3218) /* BSpec typo has 321Bh */ |
| 2189 | #define FBC_TAG(i) _MMIO(0x3300 + (i) * 4) | 2110 | #define FBC_TAG(i) _MMIO(0x3300 + (i) * 4) |
| 2190 | 2111 | ||
| 2191 | #define FBC_STATUS2 _MMIO(0x43214) | 2112 | #define FBC_STATUS2 _MMIO(0x43214) |
| 2192 | #define FBC_COMPRESSION_MASK 0x7ff | 2113 | #define IVB_FBC_COMPRESSION_MASK 0x7ff |
| 2114 | #define BDW_FBC_COMPRESSION_MASK 0xfff | ||
| 2193 | 2115 | ||
| 2194 | #define FBC_LL_SIZE (1536) | 2116 | #define FBC_LL_SIZE (1536) |
| 2195 | 2117 | ||
| @@ -6015,6 +5937,7 @@ enum { | |||
| 6015 | #define GEN8_DE_PIPE_A_IRQ (1<<16) | 5937 | #define GEN8_DE_PIPE_A_IRQ (1<<16) |
| 6016 | #define GEN8_DE_PIPE_IRQ(pipe) (1<<(16+(pipe))) | 5938 | #define GEN8_DE_PIPE_IRQ(pipe) (1<<(16+(pipe))) |
| 6017 | #define GEN8_GT_VECS_IRQ (1<<6) | 5939 | #define GEN8_GT_VECS_IRQ (1<<6) |
| 5940 | #define GEN8_GT_GUC_IRQ (1<<5) | ||
| 6018 | #define GEN8_GT_PM_IRQ (1<<4) | 5941 | #define GEN8_GT_PM_IRQ (1<<4) |
| 6019 | #define GEN8_GT_VCS2_IRQ (1<<3) | 5942 | #define GEN8_GT_VCS2_IRQ (1<<3) |
| 6020 | #define GEN8_GT_VCS1_IRQ (1<<2) | 5943 | #define GEN8_GT_VCS1_IRQ (1<<2) |
| @@ -6026,6 +5949,16 @@ enum { | |||
| 6026 | #define GEN8_GT_IIR(which) _MMIO(0x44308 + (0x10 * (which))) | 5949 | #define GEN8_GT_IIR(which) _MMIO(0x44308 + (0x10 * (which))) |
| 6027 | #define GEN8_GT_IER(which) _MMIO(0x4430c + (0x10 * (which))) | 5950 | #define GEN8_GT_IER(which) _MMIO(0x4430c + (0x10 * (which))) |
| 6028 | 5951 | ||
| 5952 | #define GEN9_GUC_TO_HOST_INT_EVENT (1<<31) | ||
| 5953 | #define GEN9_GUC_EXEC_ERROR_EVENT (1<<30) | ||
| 5954 | #define GEN9_GUC_DISPLAY_EVENT (1<<29) | ||
| 5955 | #define GEN9_GUC_SEMA_SIGNAL_EVENT (1<<28) | ||
| 5956 | #define GEN9_GUC_IOMMU_MSG_EVENT (1<<27) | ||
| 5957 | #define GEN9_GUC_DB_RING_EVENT (1<<26) | ||
| 5958 | #define GEN9_GUC_DMA_DONE_EVENT (1<<25) | ||
| 5959 | #define GEN9_GUC_FATAL_ERROR_EVENT (1<<24) | ||
| 5960 | #define GEN9_GUC_NOTIFICATION_EVENT (1<<23) | ||
| 5961 | |||
| 6029 | #define GEN8_RCS_IRQ_SHIFT 0 | 5962 | #define GEN8_RCS_IRQ_SHIFT 0 |
| 6030 | #define GEN8_BCS_IRQ_SHIFT 16 | 5963 | #define GEN8_BCS_IRQ_SHIFT 16 |
| 6031 | #define GEN8_VCS1_IRQ_SHIFT 0 | 5964 | #define GEN8_VCS1_IRQ_SHIFT 0 |
| @@ -7358,6 +7291,13 @@ enum { | |||
| 7358 | #define _HSW_AUD_MISC_CTRL_B 0x65110 | 7291 | #define _HSW_AUD_MISC_CTRL_B 0x65110 |
| 7359 | #define HSW_AUD_MISC_CTRL(pipe) _MMIO_PIPE(pipe, _HSW_AUD_MISC_CTRL_A, _HSW_AUD_MISC_CTRL_B) | 7292 | #define HSW_AUD_MISC_CTRL(pipe) _MMIO_PIPE(pipe, _HSW_AUD_MISC_CTRL_A, _HSW_AUD_MISC_CTRL_B) |
| 7360 | 7293 | ||
| 7294 | #define _HSW_AUD_M_CTS_ENABLE_A 0x65028 | ||
| 7295 | #define _HSW_AUD_M_CTS_ENABLE_B 0x65128 | ||
| 7296 | #define HSW_AUD_M_CTS_ENABLE(pipe) _MMIO_PIPE(pipe, _HSW_AUD_M_CTS_ENABLE_A, _HSW_AUD_M_CTS_ENABLE_B) | ||
| 7297 | #define AUD_M_CTS_M_VALUE_INDEX (1 << 21) | ||
| 7298 | #define AUD_M_CTS_M_PROG_ENABLE (1 << 20) | ||
| 7299 | #define AUD_CONFIG_M_MASK 0xfffff | ||
| 7300 | |||
| 7361 | #define _HSW_AUD_DIP_ELD_CTRL_ST_A 0x650b4 | 7301 | #define _HSW_AUD_DIP_ELD_CTRL_ST_A 0x650b4 |
| 7362 | #define _HSW_AUD_DIP_ELD_CTRL_ST_B 0x651b4 | 7302 | #define _HSW_AUD_DIP_ELD_CTRL_ST_B 0x651b4 |
| 7363 | #define HSW_AUD_DIP_ELD_CTRL(pipe) _MMIO_PIPE(pipe, _HSW_AUD_DIP_ELD_CTRL_ST_A, _HSW_AUD_DIP_ELD_CTRL_ST_B) | 7303 | #define HSW_AUD_DIP_ELD_CTRL(pipe) _MMIO_PIPE(pipe, _HSW_AUD_DIP_ELD_CTRL_ST_A, _HSW_AUD_DIP_ELD_CTRL_ST_B) |
diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c index 8185002d7ec8..95f2f12e0917 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.c +++ b/drivers/gpu/drm/i915/i915_sw_fence.c | |||
| @@ -13,6 +13,8 @@ | |||
| 13 | 13 | ||
| 14 | #include "i915_sw_fence.h" | 14 | #include "i915_sw_fence.h" |
| 15 | 15 | ||
| 16 | #define I915_SW_FENCE_FLAG_ALLOC BIT(3) /* after WQ_FLAG_* for safety */ | ||
| 17 | |||
| 16 | static DEFINE_SPINLOCK(i915_sw_fence_lock); | 18 | static DEFINE_SPINLOCK(i915_sw_fence_lock); |
| 17 | 19 | ||
| 18 | static int __i915_sw_fence_notify(struct i915_sw_fence *fence, | 20 | static int __i915_sw_fence_notify(struct i915_sw_fence *fence, |
| @@ -135,6 +137,8 @@ static int i915_sw_fence_wake(wait_queue_t *wq, unsigned mode, int flags, void * | |||
| 135 | list_del(&wq->task_list); | 137 | list_del(&wq->task_list); |
| 136 | __i915_sw_fence_complete(wq->private, key); | 138 | __i915_sw_fence_complete(wq->private, key); |
| 137 | i915_sw_fence_put(wq->private); | 139 | i915_sw_fence_put(wq->private); |
| 140 | if (wq->flags & I915_SW_FENCE_FLAG_ALLOC) | ||
| 141 | kfree(wq); | ||
| 138 | return 0; | 142 | return 0; |
| 139 | } | 143 | } |
| 140 | 144 | ||
| @@ -192,9 +196,9 @@ static bool i915_sw_fence_check_if_after(struct i915_sw_fence *fence, | |||
| 192 | return err; | 196 | return err; |
| 193 | } | 197 | } |
| 194 | 198 | ||
| 195 | int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence, | 199 | static int __i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence, |
| 196 | struct i915_sw_fence *signaler, | 200 | struct i915_sw_fence *signaler, |
| 197 | wait_queue_t *wq) | 201 | wait_queue_t *wq, gfp_t gfp) |
| 198 | { | 202 | { |
| 199 | unsigned long flags; | 203 | unsigned long flags; |
| 200 | int pending; | 204 | int pending; |
| @@ -206,8 +210,22 @@ int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence, | |||
| 206 | if (unlikely(i915_sw_fence_check_if_after(fence, signaler))) | 210 | if (unlikely(i915_sw_fence_check_if_after(fence, signaler))) |
| 207 | return -EINVAL; | 211 | return -EINVAL; |
| 208 | 212 | ||
| 213 | pending = 0; | ||
| 214 | if (!wq) { | ||
| 215 | wq = kmalloc(sizeof(*wq), gfp); | ||
| 216 | if (!wq) { | ||
| 217 | if (!gfpflags_allow_blocking(gfp)) | ||
| 218 | return -ENOMEM; | ||
| 219 | |||
| 220 | i915_sw_fence_wait(signaler); | ||
| 221 | return 0; | ||
| 222 | } | ||
| 223 | |||
| 224 | pending |= I915_SW_FENCE_FLAG_ALLOC; | ||
| 225 | } | ||
| 226 | |||
| 209 | INIT_LIST_HEAD(&wq->task_list); | 227 | INIT_LIST_HEAD(&wq->task_list); |
| 210 | wq->flags = 0; | 228 | wq->flags = pending; |
| 211 | wq->func = i915_sw_fence_wake; | 229 | wq->func = i915_sw_fence_wake; |
| 212 | wq->private = i915_sw_fence_get(fence); | 230 | wq->private = i915_sw_fence_get(fence); |
| 213 | 231 | ||
| @@ -226,6 +244,20 @@ int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence, | |||
| 226 | return pending; | 244 | return pending; |
| 227 | } | 245 | } |
| 228 | 246 | ||
| 247 | int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence, | ||
| 248 | struct i915_sw_fence *signaler, | ||
| 249 | wait_queue_t *wq) | ||
| 250 | { | ||
| 251 | return __i915_sw_fence_await_sw_fence(fence, signaler, wq, 0); | ||
| 252 | } | ||
| 253 | |||
| 254 | int i915_sw_fence_await_sw_fence_gfp(struct i915_sw_fence *fence, | ||
| 255 | struct i915_sw_fence *signaler, | ||
| 256 | gfp_t gfp) | ||
| 257 | { | ||
| 258 | return __i915_sw_fence_await_sw_fence(fence, signaler, NULL, gfp); | ||
| 259 | } | ||
| 260 | |||
| 229 | struct i915_sw_dma_fence_cb { | 261 | struct i915_sw_dma_fence_cb { |
| 230 | struct dma_fence_cb base; | 262 | struct dma_fence_cb base; |
| 231 | struct i915_sw_fence *fence; | 263 | struct i915_sw_fence *fence; |
diff --git a/drivers/gpu/drm/i915/i915_sw_fence.h b/drivers/gpu/drm/i915/i915_sw_fence.h index cd239e92f67f..707dfc4f0da5 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.h +++ b/drivers/gpu/drm/i915/i915_sw_fence.h | |||
| @@ -46,6 +46,9 @@ void i915_sw_fence_commit(struct i915_sw_fence *fence); | |||
| 46 | int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence, | 46 | int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence, |
| 47 | struct i915_sw_fence *after, | 47 | struct i915_sw_fence *after, |
| 48 | wait_queue_t *wq); | 48 | wait_queue_t *wq); |
| 49 | int i915_sw_fence_await_sw_fence_gfp(struct i915_sw_fence *fence, | ||
| 50 | struct i915_sw_fence *after, | ||
| 51 | gfp_t gfp); | ||
| 49 | int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence, | 52 | int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence, |
| 50 | struct dma_fence *dma, | 53 | struct dma_fence *dma, |
| 51 | unsigned long timeout, | 54 | unsigned long timeout, |
| @@ -62,4 +65,9 @@ static inline bool i915_sw_fence_done(const struct i915_sw_fence *fence) | |||
| 62 | return atomic_read(&fence->pending) < 0; | 65 | return atomic_read(&fence->pending) < 0; |
| 63 | } | 66 | } |
| 64 | 67 | ||
| 68 | static inline void i915_sw_fence_wait(struct i915_sw_fence *fence) | ||
| 69 | { | ||
| 70 | wait_event(fence->wait, i915_sw_fence_done(fence)); | ||
| 71 | } | ||
| 72 | |||
| 65 | #endif /* _I915_SW_FENCE_H_ */ | 73 | #endif /* _I915_SW_FENCE_H_ */ |
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 5c912c25f7d3..c5d210ebaa9a 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h | |||
| @@ -466,7 +466,7 @@ TRACE_EVENT(i915_gem_ring_sync_to, | |||
| 466 | __entry->dev = from->i915->drm.primary->index; | 466 | __entry->dev = from->i915->drm.primary->index; |
| 467 | __entry->sync_from = from->engine->id; | 467 | __entry->sync_from = from->engine->id; |
| 468 | __entry->sync_to = to->engine->id; | 468 | __entry->sync_to = to->engine->id; |
| 469 | __entry->seqno = from->fence.seqno; | 469 | __entry->seqno = from->global_seqno; |
| 470 | ), | 470 | ), |
| 471 | 471 | ||
| 472 | TP_printk("dev=%u, sync-from=%u, sync-to=%u, seqno=%u", | 472 | TP_printk("dev=%u, sync-from=%u, sync-to=%u, seqno=%u", |
| @@ -489,7 +489,7 @@ TRACE_EVENT(i915_gem_ring_dispatch, | |||
| 489 | TP_fast_assign( | 489 | TP_fast_assign( |
| 490 | __entry->dev = req->i915->drm.primary->index; | 490 | __entry->dev = req->i915->drm.primary->index; |
| 491 | __entry->ring = req->engine->id; | 491 | __entry->ring = req->engine->id; |
| 492 | __entry->seqno = req->fence.seqno; | 492 | __entry->seqno = req->global_seqno; |
| 493 | __entry->flags = flags; | 493 | __entry->flags = flags; |
| 494 | dma_fence_enable_sw_signaling(&req->fence); | 494 | dma_fence_enable_sw_signaling(&req->fence); |
| 495 | ), | 495 | ), |
| @@ -534,7 +534,7 @@ DECLARE_EVENT_CLASS(i915_gem_request, | |||
| 534 | TP_fast_assign( | 534 | TP_fast_assign( |
| 535 | __entry->dev = req->i915->drm.primary->index; | 535 | __entry->dev = req->i915->drm.primary->index; |
| 536 | __entry->ring = req->engine->id; | 536 | __entry->ring = req->engine->id; |
| 537 | __entry->seqno = req->fence.seqno; | 537 | __entry->seqno = req->global_seqno; |
| 538 | ), | 538 | ), |
| 539 | 539 | ||
| 540 | TP_printk("dev=%u, ring=%u, seqno=%u", | 540 | TP_printk("dev=%u, ring=%u, seqno=%u", |
| @@ -596,7 +596,7 @@ TRACE_EVENT(i915_gem_request_wait_begin, | |||
| 596 | TP_fast_assign( | 596 | TP_fast_assign( |
| 597 | __entry->dev = req->i915->drm.primary->index; | 597 | __entry->dev = req->i915->drm.primary->index; |
| 598 | __entry->ring = req->engine->id; | 598 | __entry->ring = req->engine->id; |
| 599 | __entry->seqno = req->fence.seqno; | 599 | __entry->seqno = req->global_seqno; |
| 600 | __entry->blocking = | 600 | __entry->blocking = |
| 601 | mutex_is_locked(&req->i915->drm.struct_mutex); | 601 | mutex_is_locked(&req->i915->drm.struct_mutex); |
| 602 | ), | 602 | ), |
diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index c762ae549a1c..cb5594411bb6 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c | |||
| @@ -84,7 +84,6 @@ intel_plane_duplicate_state(struct drm_plane *plane) | |||
| 84 | state = &intel_state->base; | 84 | state = &intel_state->base; |
| 85 | 85 | ||
| 86 | __drm_atomic_helper_plane_duplicate_state(plane, state); | 86 | __drm_atomic_helper_plane_duplicate_state(plane, state); |
| 87 | intel_state->wait_req = NULL; | ||
| 88 | 87 | ||
| 89 | return state; | 88 | return state; |
| 90 | } | 89 | } |
| @@ -101,7 +100,6 @@ void | |||
| 101 | intel_plane_destroy_state(struct drm_plane *plane, | 100 | intel_plane_destroy_state(struct drm_plane *plane, |
| 102 | struct drm_plane_state *state) | 101 | struct drm_plane_state *state) |
| 103 | { | 102 | { |
| 104 | WARN_ON(state && to_intel_plane_state(state)->wait_req); | ||
| 105 | drm_atomic_helper_plane_destroy_state(plane, state); | 103 | drm_atomic_helper_plane_destroy_state(plane, state); |
| 106 | } | 104 | } |
| 107 | 105 | ||
diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 7093cfbb62b1..813fd74d9c8d 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c | |||
| @@ -57,6 +57,63 @@ | |||
| 57 | * struct &i915_audio_component_audio_ops @audio_ops is called from i915 driver. | 57 | * struct &i915_audio_component_audio_ops @audio_ops is called from i915 driver. |
| 58 | */ | 58 | */ |
| 59 | 59 | ||
| 60 | /* DP N/M table */ | ||
| 61 | #define LC_540M 540000 | ||
| 62 | #define LC_270M 270000 | ||
| 63 | #define LC_162M 162000 | ||
| 64 | |||
| 65 | struct dp_aud_n_m { | ||
| 66 | int sample_rate; | ||
| 67 | int clock; | ||
| 68 | u16 m; | ||
| 69 | u16 n; | ||
| 70 | }; | ||
| 71 | |||
| 72 | /* Values according to DP 1.4 Table 2-104 */ | ||
| 73 | static const struct dp_aud_n_m dp_aud_n_m[] = { | ||
| 74 | { 32000, LC_162M, 1024, 10125 }, | ||
| 75 | { 44100, LC_162M, 784, 5625 }, | ||
| 76 | { 48000, LC_162M, 512, 3375 }, | ||
| 77 | { 64000, LC_162M, 2048, 10125 }, | ||
| 78 | { 88200, LC_162M, 1568, 5625 }, | ||
| 79 | { 96000, LC_162M, 1024, 3375 }, | ||
| 80 | { 128000, LC_162M, 4096, 10125 }, | ||
| 81 | { 176400, LC_162M, 3136, 5625 }, | ||
| 82 | { 192000, LC_162M, 2048, 3375 }, | ||
| 83 | { 32000, LC_270M, 1024, 16875 }, | ||
| 84 | { 44100, LC_270M, 784, 9375 }, | ||
| 85 | { 48000, LC_270M, 512, 5625 }, | ||
| 86 | { 64000, LC_270M, 2048, 16875 }, | ||
| 87 | { 88200, LC_270M, 1568, 9375 }, | ||
| 88 | { 96000, LC_270M, 1024, 5625 }, | ||
| 89 | { 128000, LC_270M, 4096, 16875 }, | ||
| 90 | { 176400, LC_270M, 3136, 9375 }, | ||
| 91 | { 192000, LC_270M, 2048, 5625 }, | ||
| 92 | { 32000, LC_540M, 1024, 33750 }, | ||
| 93 | { 44100, LC_540M, 784, 18750 }, | ||
| 94 | { 48000, LC_540M, 512, 11250 }, | ||
| 95 | { 64000, LC_540M, 2048, 33750 }, | ||
| 96 | { 88200, LC_540M, 1568, 18750 }, | ||
| 97 | { 96000, LC_540M, 1024, 11250 }, | ||
| 98 | { 128000, LC_540M, 4096, 33750 }, | ||
| 99 | { 176400, LC_540M, 3136, 18750 }, | ||
| 100 | { 192000, LC_540M, 2048, 11250 }, | ||
| 101 | }; | ||
| 102 | |||
| 103 | static const struct dp_aud_n_m * | ||
| 104 | audio_config_dp_get_n_m(struct intel_crtc *intel_crtc, int rate) | ||
| 105 | { | ||
| 106 | int i; | ||
| 107 | |||
| 108 | for (i = 0; i < ARRAY_SIZE(dp_aud_n_m); i++) { | ||
| 109 | if (rate == dp_aud_n_m[i].sample_rate && | ||
| 110 | intel_crtc->config->port_clock == dp_aud_n_m[i].clock) | ||
| 111 | return &dp_aud_n_m[i]; | ||
| 112 | } | ||
| 113 | |||
| 114 | return NULL; | ||
| 115 | } | ||
| 116 | |||
| 60 | static const struct { | 117 | static const struct { |
| 61 | int clock; | 118 | int clock; |
| 62 | u32 config; | 119 | u32 config; |
| @@ -225,16 +282,43 @@ hsw_dp_audio_config_update(struct intel_crtc *intel_crtc, enum port port, | |||
| 225 | const struct drm_display_mode *adjusted_mode) | 282 | const struct drm_display_mode *adjusted_mode) |
| 226 | { | 283 | { |
| 227 | struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); | 284 | struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); |
| 285 | struct i915_audio_component *acomp = dev_priv->audio_component; | ||
| 286 | int rate = acomp ? acomp->aud_sample_rate[port] : 0; | ||
| 287 | const struct dp_aud_n_m *nm = audio_config_dp_get_n_m(intel_crtc, rate); | ||
| 228 | enum pipe pipe = intel_crtc->pipe; | 288 | enum pipe pipe = intel_crtc->pipe; |
| 229 | u32 tmp; | 289 | u32 tmp; |
| 230 | 290 | ||
| 291 | if (nm) | ||
| 292 | DRM_DEBUG_KMS("using Maud %u, Naud %u\n", nm->m, nm->n); | ||
| 293 | else | ||
| 294 | DRM_DEBUG_KMS("using automatic Maud, Naud\n"); | ||
| 295 | |||
| 231 | tmp = I915_READ(HSW_AUD_CFG(pipe)); | 296 | tmp = I915_READ(HSW_AUD_CFG(pipe)); |
| 232 | tmp &= ~AUD_CONFIG_N_VALUE_INDEX; | 297 | tmp &= ~AUD_CONFIG_N_VALUE_INDEX; |
| 233 | tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK; | 298 | tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK; |
| 234 | tmp &= ~AUD_CONFIG_N_PROG_ENABLE; | 299 | tmp &= ~AUD_CONFIG_N_PROG_ENABLE; |
| 235 | tmp |= AUD_CONFIG_N_VALUE_INDEX; | 300 | tmp |= AUD_CONFIG_N_VALUE_INDEX; |
| 236 | 301 | ||
| 302 | if (nm) { | ||
| 303 | tmp &= ~AUD_CONFIG_N_MASK; | ||
| 304 | tmp |= AUD_CONFIG_N(nm->n); | ||
| 305 | tmp |= AUD_CONFIG_N_PROG_ENABLE; | ||
| 306 | } | ||
| 307 | |||
| 237 | I915_WRITE(HSW_AUD_CFG(pipe), tmp); | 308 | I915_WRITE(HSW_AUD_CFG(pipe), tmp); |
| 309 | |||
| 310 | tmp = I915_READ(HSW_AUD_M_CTS_ENABLE(pipe)); | ||
| 311 | tmp &= ~AUD_CONFIG_M_MASK; | ||
| 312 | tmp &= ~AUD_M_CTS_M_VALUE_INDEX; | ||
| 313 | tmp &= ~AUD_M_CTS_M_PROG_ENABLE; | ||
| 314 | |||
| 315 | if (nm) { | ||
| 316 | tmp |= nm->m; | ||
| 317 | tmp |= AUD_M_CTS_M_VALUE_INDEX; | ||
| 318 | tmp |= AUD_M_CTS_M_PROG_ENABLE; | ||
| 319 | } | ||
| 320 | |||
| 321 | I915_WRITE(HSW_AUD_M_CTS_ENABLE(pipe), tmp); | ||
| 238 | } | 322 | } |
| 239 | 323 | ||
| 240 | static void | 324 | static void |
| @@ -254,19 +338,24 @@ hsw_hdmi_audio_config_update(struct intel_crtc *intel_crtc, enum port port, | |||
| 254 | tmp &= ~AUD_CONFIG_N_PROG_ENABLE; | 338 | tmp &= ~AUD_CONFIG_N_PROG_ENABLE; |
| 255 | tmp |= audio_config_hdmi_pixel_clock(adjusted_mode); | 339 | tmp |= audio_config_hdmi_pixel_clock(adjusted_mode); |
| 256 | 340 | ||
| 257 | if (adjusted_mode->crtc_clock == TMDS_296M || | 341 | n = audio_config_hdmi_get_n(adjusted_mode, rate); |
| 258 | adjusted_mode->crtc_clock == TMDS_297M) { | 342 | if (n != 0) { |
| 259 | n = audio_config_hdmi_get_n(adjusted_mode, rate); | 343 | DRM_DEBUG_KMS("using N %d\n", n); |
| 260 | if (n != 0) { | 344 | |
| 261 | tmp &= ~AUD_CONFIG_N_MASK; | 345 | tmp &= ~AUD_CONFIG_N_MASK; |
| 262 | tmp |= AUD_CONFIG_N(n); | 346 | tmp |= AUD_CONFIG_N(n); |
| 263 | tmp |= AUD_CONFIG_N_PROG_ENABLE; | 347 | tmp |= AUD_CONFIG_N_PROG_ENABLE; |
| 264 | } else { | 348 | } else { |
| 265 | DRM_DEBUG_KMS("no suitable N value is found\n"); | 349 | DRM_DEBUG_KMS("using automatic N\n"); |
| 266 | } | ||
| 267 | } | 350 | } |
| 268 | 351 | ||
| 269 | I915_WRITE(HSW_AUD_CFG(pipe), tmp); | 352 | I915_WRITE(HSW_AUD_CFG(pipe), tmp); |
| 353 | |||
| 354 | tmp = I915_READ(HSW_AUD_M_CTS_ENABLE(pipe)); | ||
| 355 | tmp &= ~AUD_CONFIG_M_MASK; | ||
| 356 | tmp &= ~AUD_M_CTS_M_VALUE_INDEX; | ||
| 357 | tmp |= AUD_M_CTS_M_PROG_ENABLE; | ||
| 358 | I915_WRITE(HSW_AUD_M_CTS_ENABLE(pipe), tmp); | ||
| 270 | } | 359 | } |
| 271 | 360 | ||
| 272 | static void | 361 | static void |
| @@ -687,7 +776,8 @@ static int i915_audio_component_sync_audio_rate(struct device *kdev, int port, | |||
| 687 | /* 1. get the pipe */ | 776 | /* 1. get the pipe */ |
| 688 | intel_encoder = get_saved_enc(dev_priv, port, pipe); | 777 | intel_encoder = get_saved_enc(dev_priv, port, pipe); |
| 689 | if (!intel_encoder || !intel_encoder->base.crtc || | 778 | if (!intel_encoder || !intel_encoder->base.crtc || |
| 690 | intel_encoder->type != INTEL_OUTPUT_HDMI) { | 779 | (intel_encoder->type != INTEL_OUTPUT_HDMI && |
| 780 | intel_encoder->type != INTEL_OUTPUT_DP)) { | ||
| 691 | DRM_DEBUG_KMS("Not valid for port %c\n", port_name(port)); | 781 | DRM_DEBUG_KMS("Not valid for port %c\n", port_name(port)); |
| 692 | err = -ENODEV; | 782 | err = -ENODEV; |
| 693 | goto unlock; | 783 | goto unlock; |
diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 56efcc507ea2..c410d3d6465f 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c | |||
| @@ -83,16 +83,18 @@ static void irq_enable(struct intel_engine_cs *engine) | |||
| 83 | */ | 83 | */ |
| 84 | engine->breadcrumbs.irq_posted = true; | 84 | engine->breadcrumbs.irq_posted = true; |
| 85 | 85 | ||
| 86 | spin_lock_irq(&engine->i915->irq_lock); | 86 | /* Caller disables interrupts */ |
| 87 | spin_lock(&engine->i915->irq_lock); | ||
| 87 | engine->irq_enable(engine); | 88 | engine->irq_enable(engine); |
| 88 | spin_unlock_irq(&engine->i915->irq_lock); | 89 | spin_unlock(&engine->i915->irq_lock); |
| 89 | } | 90 | } |
| 90 | 91 | ||
| 91 | static void irq_disable(struct intel_engine_cs *engine) | 92 | static void irq_disable(struct intel_engine_cs *engine) |
| 92 | { | 93 | { |
| 93 | spin_lock_irq(&engine->i915->irq_lock); | 94 | /* Caller disables interrupts */ |
| 95 | spin_lock(&engine->i915->irq_lock); | ||
| 94 | engine->irq_disable(engine); | 96 | engine->irq_disable(engine); |
| 95 | spin_unlock_irq(&engine->i915->irq_lock); | 97 | spin_unlock(&engine->i915->irq_lock); |
| 96 | 98 | ||
| 97 | engine->breadcrumbs.irq_posted = false; | 99 | engine->breadcrumbs.irq_posted = false; |
| 98 | } | 100 | } |
| @@ -293,9 +295,9 @@ bool intel_engine_add_wait(struct intel_engine_cs *engine, | |||
| 293 | struct intel_breadcrumbs *b = &engine->breadcrumbs; | 295 | struct intel_breadcrumbs *b = &engine->breadcrumbs; |
| 294 | bool first; | 296 | bool first; |
| 295 | 297 | ||
| 296 | spin_lock(&b->lock); | 298 | spin_lock_irq(&b->lock); |
| 297 | first = __intel_engine_add_wait(engine, wait); | 299 | first = __intel_engine_add_wait(engine, wait); |
| 298 | spin_unlock(&b->lock); | 300 | spin_unlock_irq(&b->lock); |
| 299 | 301 | ||
| 300 | return first; | 302 | return first; |
| 301 | } | 303 | } |
| @@ -326,7 +328,7 @@ void intel_engine_remove_wait(struct intel_engine_cs *engine, | |||
| 326 | if (RB_EMPTY_NODE(&wait->node)) | 328 | if (RB_EMPTY_NODE(&wait->node)) |
| 327 | return; | 329 | return; |
| 328 | 330 | ||
| 329 | spin_lock(&b->lock); | 331 | spin_lock_irq(&b->lock); |
| 330 | 332 | ||
| 331 | if (RB_EMPTY_NODE(&wait->node)) | 333 | if (RB_EMPTY_NODE(&wait->node)) |
| 332 | goto out_unlock; | 334 | goto out_unlock; |
| @@ -400,7 +402,7 @@ out_unlock: | |||
| 400 | GEM_BUG_ON(rb_first(&b->waiters) != | 402 | GEM_BUG_ON(rb_first(&b->waiters) != |
| 401 | (b->first_wait ? &b->first_wait->node : NULL)); | 403 | (b->first_wait ? &b->first_wait->node : NULL)); |
| 402 | GEM_BUG_ON(!rcu_access_pointer(b->irq_seqno_bh) ^ RB_EMPTY_ROOT(&b->waiters)); | 404 | GEM_BUG_ON(!rcu_access_pointer(b->irq_seqno_bh) ^ RB_EMPTY_ROOT(&b->waiters)); |
| 403 | spin_unlock(&b->lock); | 405 | spin_unlock_irq(&b->lock); |
| 404 | } | 406 | } |
| 405 | 407 | ||
| 406 | static bool signal_complete(struct drm_i915_gem_request *request) | 408 | static bool signal_complete(struct drm_i915_gem_request *request) |
| @@ -473,14 +475,14 @@ static int intel_breadcrumbs_signaler(void *arg) | |||
| 473 | * we just completed - so double check we are still | 475 | * we just completed - so double check we are still |
| 474 | * the oldest before picking the next one. | 476 | * the oldest before picking the next one. |
| 475 | */ | 477 | */ |
| 476 | spin_lock(&b->lock); | 478 | spin_lock_irq(&b->lock); |
| 477 | if (request == b->first_signal) { | 479 | if (request == b->first_signal) { |
| 478 | struct rb_node *rb = | 480 | struct rb_node *rb = |
| 479 | rb_next(&request->signaling.node); | 481 | rb_next(&request->signaling.node); |
| 480 | b->first_signal = rb ? to_signaler(rb) : NULL; | 482 | b->first_signal = rb ? to_signaler(rb) : NULL; |
| 481 | } | 483 | } |
| 482 | rb_erase(&request->signaling.node, &b->signals); | 484 | rb_erase(&request->signaling.node, &b->signals); |
| 483 | spin_unlock(&b->lock); | 485 | spin_unlock_irq(&b->lock); |
| 484 | 486 | ||
| 485 | i915_gem_request_put(request); | 487 | i915_gem_request_put(request); |
| 486 | } else { | 488 | } else { |
| @@ -502,11 +504,20 @@ void intel_engine_enable_signaling(struct drm_i915_gem_request *request) | |||
| 502 | struct rb_node *parent, **p; | 504 | struct rb_node *parent, **p; |
| 503 | bool first, wakeup; | 505 | bool first, wakeup; |
| 504 | 506 | ||
| 505 | /* locked by dma_fence_enable_sw_signaling() */ | 507 | /* Note that we may be called from an interrupt handler on another |
| 508 | * device (e.g. nouveau signaling a fence completion causing us | ||
| 509 | * to submit a request, and so enable signaling). As such, | ||
| 510 | * we need to make sure that all other users of b->lock protect | ||
| 511 | * against interrupts, i.e. use spin_lock_irqsave. | ||
| 512 | */ | ||
| 513 | |||
| 514 | /* locked by dma_fence_enable_sw_signaling() (irqsafe fence->lock) */ | ||
| 506 | assert_spin_locked(&request->lock); | 515 | assert_spin_locked(&request->lock); |
| 516 | if (!request->global_seqno) | ||
| 517 | return; | ||
| 507 | 518 | ||
| 508 | request->signaling.wait.tsk = b->signaler; | 519 | request->signaling.wait.tsk = b->signaler; |
| 509 | request->signaling.wait.seqno = request->fence.seqno; | 520 | request->signaling.wait.seqno = request->global_seqno; |
| 510 | i915_gem_request_get(request); | 521 | i915_gem_request_get(request); |
| 511 | 522 | ||
| 512 | spin_lock(&b->lock); | 523 | spin_lock(&b->lock); |
| @@ -530,8 +541,8 @@ void intel_engine_enable_signaling(struct drm_i915_gem_request *request) | |||
| 530 | p = &b->signals.rb_node; | 541 | p = &b->signals.rb_node; |
| 531 | while (*p) { | 542 | while (*p) { |
| 532 | parent = *p; | 543 | parent = *p; |
| 533 | if (i915_seqno_passed(request->fence.seqno, | 544 | if (i915_seqno_passed(request->global_seqno, |
| 534 | to_signaler(parent)->fence.seqno)) { | 545 | to_signaler(parent)->global_seqno)) { |
| 535 | p = &parent->rb_right; | 546 | p = &parent->rb_right; |
| 536 | first = false; | 547 | first = false; |
| 537 | } else { | 548 | } else { |
| @@ -592,7 +603,7 @@ void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine) | |||
| 592 | struct intel_breadcrumbs *b = &engine->breadcrumbs; | 603 | struct intel_breadcrumbs *b = &engine->breadcrumbs; |
| 593 | 604 | ||
| 594 | cancel_fake_irq(engine); | 605 | cancel_fake_irq(engine); |
| 595 | spin_lock(&b->lock); | 606 | spin_lock_irq(&b->lock); |
| 596 | 607 | ||
| 597 | __intel_breadcrumbs_disable_irq(b); | 608 | __intel_breadcrumbs_disable_irq(b); |
| 598 | if (intel_engine_has_waiter(engine)) { | 609 | if (intel_engine_has_waiter(engine)) { |
| @@ -605,7 +616,7 @@ void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine) | |||
| 605 | irq_disable(engine); | 616 | irq_disable(engine); |
| 606 | } | 617 | } |
| 607 | 618 | ||
| 608 | spin_unlock(&b->lock); | 619 | spin_unlock_irq(&b->lock); |
| 609 | } | 620 | } |
| 610 | 621 | ||
| 611 | void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine) | 622 | void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine) |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index a97151fcb9f4..30eb95b54dcf 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
| @@ -573,7 +573,7 @@ intel_crt_load_detect(struct intel_crt *crt, uint32_t pipe) | |||
| 573 | POSTING_READ(pipeconf_reg); | 573 | POSTING_READ(pipeconf_reg); |
| 574 | /* Wait for next Vblank to substitue | 574 | /* Wait for next Vblank to substitue |
| 575 | * border color for Color info */ | 575 | * border color for Color info */ |
| 576 | intel_wait_for_vblank(dev, pipe); | 576 | intel_wait_for_vblank(dev_priv, pipe); |
| 577 | st00 = I915_READ8(_VGA_MSR_WRITE); | 577 | st00 = I915_READ8(_VGA_MSR_WRITE); |
| 578 | status = ((st00 & (1 << 4)) != 0) ? | 578 | status = ((st00 & (1 << 4)) != 0) ? |
| 579 | connector_status_connected : | 579 | connector_status_connected : |
diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 1ea0e1f43397..d7a04bca8c28 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c | |||
| @@ -168,12 +168,6 @@ struct stepping_info { | |||
| 168 | char substepping; | 168 | char substepping; |
| 169 | }; | 169 | }; |
| 170 | 170 | ||
| 171 | static const struct stepping_info kbl_stepping_info[] = { | ||
| 172 | {'A', '0'}, {'B', '0'}, {'C', '0'}, | ||
| 173 | {'D', '0'}, {'E', '0'}, {'F', '0'}, | ||
| 174 | {'G', '0'}, {'H', '0'}, {'I', '0'}, | ||
| 175 | }; | ||
| 176 | |||
| 177 | static const struct stepping_info skl_stepping_info[] = { | 171 | static const struct stepping_info skl_stepping_info[] = { |
| 178 | {'A', '0'}, {'B', '0'}, {'C', '0'}, | 172 | {'A', '0'}, {'B', '0'}, {'C', '0'}, |
| 179 | {'D', '0'}, {'E', '0'}, {'F', '0'}, | 173 | {'D', '0'}, {'E', '0'}, {'F', '0'}, |
| @@ -194,10 +188,7 @@ intel_get_stepping_info(struct drm_i915_private *dev_priv) | |||
| 194 | const struct stepping_info *si; | 188 | const struct stepping_info *si; |
| 195 | unsigned int size; | 189 | unsigned int size; |
| 196 | 190 | ||
| 197 | if (IS_KABYLAKE(dev_priv)) { | 191 | if (IS_SKYLAKE(dev_priv)) { |
| 198 | size = ARRAY_SIZE(kbl_stepping_info); | ||
| 199 | si = kbl_stepping_info; | ||
| 200 | } else if (IS_SKYLAKE(dev_priv)) { | ||
| 201 | size = ARRAY_SIZE(skl_stepping_info); | 192 | size = ARRAY_SIZE(skl_stepping_info); |
| 202 | si = skl_stepping_info; | 193 | si = skl_stepping_info; |
| 203 | } else if (IS_BROXTON(dev_priv)) { | 194 | } else if (IS_BROXTON(dev_priv)) { |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index fb18d699ce10..938ac4dbcb45 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
| @@ -1547,7 +1547,6 @@ static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv, | |||
| 1547 | { | 1547 | { |
| 1548 | const struct bxt_ddi_buf_trans *ddi_translations; | 1548 | const struct bxt_ddi_buf_trans *ddi_translations; |
| 1549 | u32 n_entries, i; | 1549 | u32 n_entries, i; |
| 1550 | uint32_t val; | ||
| 1551 | 1550 | ||
| 1552 | if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) { | 1551 | if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) { |
| 1553 | n_entries = ARRAY_SIZE(bxt_ddi_translations_edp); | 1552 | n_entries = ARRAY_SIZE(bxt_ddi_translations_edp); |
| @@ -1576,38 +1575,11 @@ static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv, | |||
| 1576 | } | 1575 | } |
| 1577 | } | 1576 | } |
| 1578 | 1577 | ||
| 1579 | /* | 1578 | bxt_ddi_phy_set_signal_level(dev_priv, port, |
| 1580 | * While we write to the group register to program all lanes at once we | 1579 | ddi_translations[level].margin, |
| 1581 | * can read only lane registers and we pick lanes 0/1 for that. | 1580 | ddi_translations[level].scale, |
| 1582 | */ | 1581 | ddi_translations[level].enable, |
| 1583 | val = I915_READ(BXT_PORT_PCS_DW10_LN01(port)); | 1582 | ddi_translations[level].deemphasis); |
| 1584 | val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT); | ||
| 1585 | I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val); | ||
| 1586 | |||
| 1587 | val = I915_READ(BXT_PORT_TX_DW2_LN0(port)); | ||
| 1588 | val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE); | ||
| 1589 | val |= ddi_translations[level].margin << MARGIN_000_SHIFT | | ||
| 1590 | ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT; | ||
| 1591 | I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val); | ||
| 1592 | |||
| 1593 | val = I915_READ(BXT_PORT_TX_DW3_LN0(port)); | ||
| 1594 | val &= ~SCALE_DCOMP_METHOD; | ||
| 1595 | if (ddi_translations[level].enable) | ||
| 1596 | val |= SCALE_DCOMP_METHOD; | ||
| 1597 | |||
| 1598 | if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD)) | ||
| 1599 | DRM_ERROR("Disabled scaling while ouniqetrangenmethod was set"); | ||
| 1600 | |||
| 1601 | I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val); | ||
| 1602 | |||
| 1603 | val = I915_READ(BXT_PORT_TX_DW4_LN0(port)); | ||
| 1604 | val &= ~DE_EMPHASIS; | ||
| 1605 | val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT; | ||
| 1606 | I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val); | ||
| 1607 | |||
| 1608 | val = I915_READ(BXT_PORT_PCS_DW10_LN01(port)); | ||
| 1609 | val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT; | ||
| 1610 | I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val); | ||
| 1611 | } | 1583 | } |
| 1612 | 1584 | ||
| 1613 | static uint32_t translate_signal_level(int signal_levels) | 1585 | static uint32_t translate_signal_level(int signal_levels) |
| @@ -1923,332 +1895,14 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder, | |||
| 1923 | } | 1895 | } |
| 1924 | } | 1896 | } |
| 1925 | 1897 | ||
| 1926 | bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv, | ||
| 1927 | enum dpio_phy phy) | ||
| 1928 | { | ||
| 1929 | enum port port; | ||
| 1930 | |||
| 1931 | if (!(I915_READ(BXT_P_CR_GT_DISP_PWRON) & GT_DISPLAY_POWER_ON(phy))) | ||
| 1932 | return false; | ||
| 1933 | |||
| 1934 | if ((I915_READ(BXT_PORT_CL1CM_DW0(phy)) & | ||
| 1935 | (PHY_POWER_GOOD | PHY_RESERVED)) != PHY_POWER_GOOD) { | ||
| 1936 | DRM_DEBUG_DRIVER("DDI PHY %d powered, but power hasn't settled\n", | ||
| 1937 | phy); | ||
| 1938 | |||
| 1939 | return false; | ||
| 1940 | } | ||
| 1941 | |||
| 1942 | if (phy == DPIO_PHY1 && | ||
| 1943 | !(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE)) { | ||
| 1944 | DRM_DEBUG_DRIVER("DDI PHY 1 powered, but GRC isn't done\n"); | ||
| 1945 | |||
| 1946 | return false; | ||
| 1947 | } | ||
| 1948 | |||
| 1949 | if (!(I915_READ(BXT_PHY_CTL_FAMILY(phy)) & COMMON_RESET_DIS)) { | ||
| 1950 | DRM_DEBUG_DRIVER("DDI PHY %d powered, but still in reset\n", | ||
| 1951 | phy); | ||
| 1952 | |||
| 1953 | return false; | ||
| 1954 | } | ||
| 1955 | |||
| 1956 | for_each_port_masked(port, | ||
| 1957 | phy == DPIO_PHY0 ? BIT(PORT_B) | BIT(PORT_C) : | ||
| 1958 | BIT(PORT_A)) { | ||
| 1959 | u32 tmp = I915_READ(BXT_PHY_CTL(port)); | ||
| 1960 | |||
| 1961 | if (tmp & BXT_PHY_CMNLANE_POWERDOWN_ACK) { | ||
| 1962 | DRM_DEBUG_DRIVER("DDI PHY %d powered, but common lane " | ||
| 1963 | "for port %c powered down " | ||
| 1964 | "(PHY_CTL %08x)\n", | ||
| 1965 | phy, port_name(port), tmp); | ||
| 1966 | |||
| 1967 | return false; | ||
| 1968 | } | ||
| 1969 | } | ||
| 1970 | |||
| 1971 | return true; | ||
| 1972 | } | ||
| 1973 | |||
| 1974 | static u32 bxt_get_grc(struct drm_i915_private *dev_priv, enum dpio_phy phy) | ||
| 1975 | { | ||
| 1976 | u32 val = I915_READ(BXT_PORT_REF_DW6(phy)); | ||
| 1977 | |||
| 1978 | return (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT; | ||
| 1979 | } | ||
| 1980 | |||
| 1981 | static void bxt_phy_wait_grc_done(struct drm_i915_private *dev_priv, | ||
| 1982 | enum dpio_phy phy) | ||
| 1983 | { | ||
| 1984 | if (intel_wait_for_register(dev_priv, | ||
| 1985 | BXT_PORT_REF_DW3(phy), | ||
| 1986 | GRC_DONE, GRC_DONE, | ||
| 1987 | 10)) | ||
| 1988 | DRM_ERROR("timeout waiting for PHY%d GRC\n", phy); | ||
| 1989 | } | ||
| 1990 | |||
| 1991 | void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy) | ||
| 1992 | { | ||
| 1993 | u32 val; | ||
| 1994 | |||
| 1995 | if (bxt_ddi_phy_is_enabled(dev_priv, phy)) { | ||
| 1996 | /* Still read out the GRC value for state verification */ | ||
| 1997 | if (phy == DPIO_PHY0) | ||
| 1998 | dev_priv->bxt_phy_grc = bxt_get_grc(dev_priv, phy); | ||
| 1999 | |||
| 2000 | if (bxt_ddi_phy_verify_state(dev_priv, phy)) { | ||
| 2001 | DRM_DEBUG_DRIVER("DDI PHY %d already enabled, " | ||
| 2002 | "won't reprogram it\n", phy); | ||
| 2003 | |||
| 2004 | return; | ||
| 2005 | } | ||
| 2006 | |||
| 2007 | DRM_DEBUG_DRIVER("DDI PHY %d enabled with invalid state, " | ||
| 2008 | "force reprogramming it\n", phy); | ||
| 2009 | } | ||
| 2010 | |||
| 2011 | val = I915_READ(BXT_P_CR_GT_DISP_PWRON); | ||
| 2012 | val |= GT_DISPLAY_POWER_ON(phy); | ||
| 2013 | I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val); | ||
| 2014 | |||
| 2015 | /* | ||
| 2016 | * The PHY registers start out inaccessible and respond to reads with | ||
| 2017 | * all 1s. Eventually they become accessible as they power up, then | ||
| 2018 | * the reserved bit will give the default 0. Poll on the reserved bit | ||
| 2019 | * becoming 0 to find when the PHY is accessible. | ||
| 2020 | * HW team confirmed that the time to reach phypowergood status is | ||
| 2021 | * anywhere between 50 us and 100us. | ||
| 2022 | */ | ||
| 2023 | if (wait_for_us(((I915_READ(BXT_PORT_CL1CM_DW0(phy)) & | ||
| 2024 | (PHY_RESERVED | PHY_POWER_GOOD)) == PHY_POWER_GOOD), 100)) { | ||
| 2025 | DRM_ERROR("timeout during PHY%d power on\n", phy); | ||
| 2026 | } | ||
| 2027 | |||
| 2028 | /* Program PLL Rcomp code offset */ | ||
| 2029 | val = I915_READ(BXT_PORT_CL1CM_DW9(phy)); | ||
| 2030 | val &= ~IREF0RC_OFFSET_MASK; | ||
| 2031 | val |= 0xE4 << IREF0RC_OFFSET_SHIFT; | ||
| 2032 | I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val); | ||
| 2033 | |||
| 2034 | val = I915_READ(BXT_PORT_CL1CM_DW10(phy)); | ||
| 2035 | val &= ~IREF1RC_OFFSET_MASK; | ||
| 2036 | val |= 0xE4 << IREF1RC_OFFSET_SHIFT; | ||
| 2037 | I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val); | ||
| 2038 | |||
| 2039 | /* Program power gating */ | ||
| 2040 | val = I915_READ(BXT_PORT_CL1CM_DW28(phy)); | ||
| 2041 | val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN | | ||
| 2042 | SUS_CLK_CONFIG; | ||
| 2043 | I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val); | ||
| 2044 | |||
| 2045 | if (phy == DPIO_PHY0) { | ||
| 2046 | val = I915_READ(BXT_PORT_CL2CM_DW6_BC); | ||
| 2047 | val |= DW6_OLDO_DYN_PWR_DOWN_EN; | ||
| 2048 | I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val); | ||
| 2049 | } | ||
| 2050 | |||
| 2051 | val = I915_READ(BXT_PORT_CL1CM_DW30(phy)); | ||
| 2052 | val &= ~OCL2_LDOFUSE_PWR_DIS; | ||
| 2053 | /* | ||
| 2054 | * On PHY1 disable power on the second channel, since no port is | ||
| 2055 | * connected there. On PHY0 both channels have a port, so leave it | ||
| 2056 | * enabled. | ||
| 2057 | * TODO: port C is only connected on BXT-P, so on BXT0/1 we should | ||
| 2058 | * power down the second channel on PHY0 as well. | ||
| 2059 | * | ||
| 2060 | * FIXME: Clarify programming of the following, the register is | ||
| 2061 | * read-only with bit 6 fixed at 0 at least in stepping A. | ||
| 2062 | */ | ||
| 2063 | if (phy == DPIO_PHY1) | ||
| 2064 | val |= OCL2_LDOFUSE_PWR_DIS; | ||
| 2065 | I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val); | ||
| 2066 | |||
| 2067 | if (phy == DPIO_PHY0) { | ||
| 2068 | uint32_t grc_code; | ||
| 2069 | /* | ||
| 2070 | * PHY0 isn't connected to an RCOMP resistor so copy over | ||
| 2071 | * the corresponding calibrated value from PHY1, and disable | ||
| 2072 | * the automatic calibration on PHY0. | ||
| 2073 | */ | ||
| 2074 | val = dev_priv->bxt_phy_grc = bxt_get_grc(dev_priv, DPIO_PHY1); | ||
| 2075 | grc_code = val << GRC_CODE_FAST_SHIFT | | ||
| 2076 | val << GRC_CODE_SLOW_SHIFT | | ||
| 2077 | val; | ||
| 2078 | I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code); | ||
| 2079 | |||
| 2080 | val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0)); | ||
| 2081 | val |= GRC_DIS | GRC_RDY_OVRD; | ||
| 2082 | I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val); | ||
| 2083 | } | ||
| 2084 | |||
| 2085 | val = I915_READ(BXT_PHY_CTL_FAMILY(phy)); | ||
| 2086 | val |= COMMON_RESET_DIS; | ||
| 2087 | I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val); | ||
| 2088 | |||
| 2089 | if (phy == DPIO_PHY1) | ||
| 2090 | bxt_phy_wait_grc_done(dev_priv, DPIO_PHY1); | ||
| 2091 | } | ||
| 2092 | |||
| 2093 | void bxt_ddi_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy) | ||
| 2094 | { | ||
| 2095 | uint32_t val; | ||
| 2096 | |||
| 2097 | val = I915_READ(BXT_PHY_CTL_FAMILY(phy)); | ||
| 2098 | val &= ~COMMON_RESET_DIS; | ||
| 2099 | I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val); | ||
| 2100 | |||
| 2101 | val = I915_READ(BXT_P_CR_GT_DISP_PWRON); | ||
| 2102 | val &= ~GT_DISPLAY_POWER_ON(phy); | ||
| 2103 | I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val); | ||
| 2104 | } | ||
| 2105 | |||
| 2106 | static bool __printf(6, 7) | ||
| 2107 | __phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy, | ||
| 2108 | i915_reg_t reg, u32 mask, u32 expected, | ||
| 2109 | const char *reg_fmt, ...) | ||
| 2110 | { | ||
| 2111 | struct va_format vaf; | ||
| 2112 | va_list args; | ||
| 2113 | u32 val; | ||
| 2114 | |||
| 2115 | val = I915_READ(reg); | ||
| 2116 | if ((val & mask) == expected) | ||
| 2117 | return true; | ||
| 2118 | |||
| 2119 | va_start(args, reg_fmt); | ||
| 2120 | vaf.fmt = reg_fmt; | ||
| 2121 | vaf.va = &args; | ||
| 2122 | |||
| 2123 | DRM_DEBUG_DRIVER("DDI PHY %d reg %pV [%08x] state mismatch: " | ||
| 2124 | "current %08x, expected %08x (mask %08x)\n", | ||
| 2125 | phy, &vaf, reg.reg, val, (val & ~mask) | expected, | ||
| 2126 | mask); | ||
| 2127 | |||
| 2128 | va_end(args); | ||
| 2129 | |||
| 2130 | return false; | ||
| 2131 | } | ||
| 2132 | |||
| 2133 | bool bxt_ddi_phy_verify_state(struct drm_i915_private *dev_priv, | ||
| 2134 | enum dpio_phy phy) | ||
| 2135 | { | ||
| 2136 | uint32_t mask; | ||
| 2137 | bool ok; | ||
| 2138 | |||
| 2139 | #define _CHK(reg, mask, exp, fmt, ...) \ | ||
| 2140 | __phy_reg_verify_state(dev_priv, phy, reg, mask, exp, fmt, \ | ||
| 2141 | ## __VA_ARGS__) | ||
| 2142 | |||
| 2143 | if (!bxt_ddi_phy_is_enabled(dev_priv, phy)) | ||
| 2144 | return false; | ||
| 2145 | |||
| 2146 | ok = true; | ||
| 2147 | |||
| 2148 | /* PLL Rcomp code offset */ | ||
| 2149 | ok &= _CHK(BXT_PORT_CL1CM_DW9(phy), | ||
| 2150 | IREF0RC_OFFSET_MASK, 0xe4 << IREF0RC_OFFSET_SHIFT, | ||
| 2151 | "BXT_PORT_CL1CM_DW9(%d)", phy); | ||
| 2152 | ok &= _CHK(BXT_PORT_CL1CM_DW10(phy), | ||
| 2153 | IREF1RC_OFFSET_MASK, 0xe4 << IREF1RC_OFFSET_SHIFT, | ||
| 2154 | "BXT_PORT_CL1CM_DW10(%d)", phy); | ||
| 2155 | |||
| 2156 | /* Power gating */ | ||
| 2157 | mask = OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN | SUS_CLK_CONFIG; | ||
| 2158 | ok &= _CHK(BXT_PORT_CL1CM_DW28(phy), mask, mask, | ||
| 2159 | "BXT_PORT_CL1CM_DW28(%d)", phy); | ||
| 2160 | |||
| 2161 | if (phy == DPIO_PHY0) | ||
| 2162 | ok &= _CHK(BXT_PORT_CL2CM_DW6_BC, | ||
| 2163 | DW6_OLDO_DYN_PWR_DOWN_EN, DW6_OLDO_DYN_PWR_DOWN_EN, | ||
| 2164 | "BXT_PORT_CL2CM_DW6_BC"); | ||
| 2165 | |||
| 2166 | /* | ||
| 2167 | * TODO: Verify BXT_PORT_CL1CM_DW30 bit OCL2_LDOFUSE_PWR_DIS, | ||
| 2168 | * at least on stepping A this bit is read-only and fixed at 0. | ||
| 2169 | */ | ||
| 2170 | |||
| 2171 | if (phy == DPIO_PHY0) { | ||
| 2172 | u32 grc_code = dev_priv->bxt_phy_grc; | ||
| 2173 | |||
| 2174 | grc_code = grc_code << GRC_CODE_FAST_SHIFT | | ||
| 2175 | grc_code << GRC_CODE_SLOW_SHIFT | | ||
| 2176 | grc_code; | ||
| 2177 | mask = GRC_CODE_FAST_MASK | GRC_CODE_SLOW_MASK | | ||
| 2178 | GRC_CODE_NOM_MASK; | ||
| 2179 | ok &= _CHK(BXT_PORT_REF_DW6(DPIO_PHY0), mask, grc_code, | ||
| 2180 | "BXT_PORT_REF_DW6(%d)", DPIO_PHY0); | ||
| 2181 | |||
| 2182 | mask = GRC_DIS | GRC_RDY_OVRD; | ||
| 2183 | ok &= _CHK(BXT_PORT_REF_DW8(DPIO_PHY0), mask, mask, | ||
| 2184 | "BXT_PORT_REF_DW8(%d)", DPIO_PHY0); | ||
| 2185 | } | ||
| 2186 | |||
| 2187 | return ok; | ||
| 2188 | #undef _CHK | ||
| 2189 | } | ||
| 2190 | |||
| 2191 | static uint8_t | ||
| 2192 | bxt_ddi_phy_calc_lane_lat_optim_mask(struct intel_encoder *encoder, | ||
| 2193 | struct intel_crtc_state *pipe_config) | ||
| 2194 | { | ||
| 2195 | switch (pipe_config->lane_count) { | ||
| 2196 | case 1: | ||
| 2197 | return 0; | ||
| 2198 | case 2: | ||
| 2199 | return BIT(2) | BIT(0); | ||
| 2200 | case 4: | ||
| 2201 | return BIT(3) | BIT(2) | BIT(0); | ||
| 2202 | default: | ||
| 2203 | MISSING_CASE(pipe_config->lane_count); | ||
| 2204 | |||
| 2205 | return 0; | ||
| 2206 | } | ||
| 2207 | } | ||
| 2208 | |||
| 2209 | static void bxt_ddi_pre_pll_enable(struct intel_encoder *encoder, | 1898 | static void bxt_ddi_pre_pll_enable(struct intel_encoder *encoder, |
| 2210 | struct intel_crtc_state *pipe_config, | 1899 | struct intel_crtc_state *pipe_config, |
| 2211 | struct drm_connector_state *conn_state) | 1900 | struct drm_connector_state *conn_state) |
| 2212 | { | 1901 | { |
| 2213 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); | ||
| 2214 | struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev); | ||
| 2215 | enum port port = dport->port; | ||
| 2216 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); | 1902 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
| 2217 | int lane; | 1903 | uint8_t mask = intel_crtc->config->lane_lat_optim_mask; |
| 2218 | |||
| 2219 | for (lane = 0; lane < 4; lane++) { | ||
| 2220 | u32 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane)); | ||
| 2221 | |||
| 2222 | /* | ||
| 2223 | * Note that on CHV this flag is called UPAR, but has | ||
| 2224 | * the same function. | ||
| 2225 | */ | ||
| 2226 | val &= ~LATENCY_OPTIM; | ||
| 2227 | if (intel_crtc->config->lane_lat_optim_mask & BIT(lane)) | ||
| 2228 | val |= LATENCY_OPTIM; | ||
| 2229 | |||
| 2230 | I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val); | ||
| 2231 | } | ||
| 2232 | } | ||
| 2233 | |||
| 2234 | static uint8_t | ||
| 2235 | bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder) | ||
| 2236 | { | ||
| 2237 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); | ||
| 2238 | struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev); | ||
| 2239 | enum port port = dport->port; | ||
| 2240 | int lane; | ||
| 2241 | uint8_t mask; | ||
| 2242 | |||
| 2243 | mask = 0; | ||
| 2244 | for (lane = 0; lane < 4; lane++) { | ||
| 2245 | u32 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane)); | ||
| 2246 | |||
| 2247 | if (val & LATENCY_OPTIM) | ||
| 2248 | mask |= BIT(lane); | ||
| 2249 | } | ||
| 2250 | 1904 | ||
| 2251 | return mask; | 1905 | bxt_ddi_phy_set_lane_optim_mask(encoder, mask); |
| 2252 | } | 1906 | } |
| 2253 | 1907 | ||
| 2254 | void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp) | 1908 | void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp) |
| @@ -2417,7 +2071,7 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder, | |||
| 2417 | if (IS_BROXTON(dev_priv) && ret) | 2071 | if (IS_BROXTON(dev_priv) && ret) |
| 2418 | pipe_config->lane_lat_optim_mask = | 2072 | pipe_config->lane_lat_optim_mask = |
| 2419 | bxt_ddi_phy_calc_lane_lat_optim_mask(encoder, | 2073 | bxt_ddi_phy_calc_lane_lat_optim_mask(encoder, |
| 2420 | pipe_config); | 2074 | pipe_config->lane_count); |
| 2421 | 2075 | ||
| 2422 | return ret; | 2076 | return ret; |
| 2423 | 2077 | ||
diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index d6a8f11813d5..185e3bbc9ec9 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c | |||
| @@ -282,12 +282,13 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) | |||
| 282 | info->num_sprites[PIPE_A] = 2; | 282 | info->num_sprites[PIPE_A] = 2; |
| 283 | info->num_sprites[PIPE_B] = 2; | 283 | info->num_sprites[PIPE_B] = 2; |
| 284 | info->num_sprites[PIPE_C] = 1; | 284 | info->num_sprites[PIPE_C] = 1; |
| 285 | } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) | 285 | } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { |
| 286 | for_each_pipe(dev_priv, pipe) | 286 | for_each_pipe(dev_priv, pipe) |
| 287 | info->num_sprites[pipe] = 2; | 287 | info->num_sprites[pipe] = 2; |
| 288 | else | 288 | } else if (INTEL_GEN(dev_priv) >= 5) { |
| 289 | for_each_pipe(dev_priv, pipe) | 289 | for_each_pipe(dev_priv, pipe) |
| 290 | info->num_sprites[pipe] = 1; | 290 | info->num_sprites[pipe] = 1; |
| 291 | } | ||
| 291 | 292 | ||
| 292 | if (i915.disable_display) { | 293 | if (i915.disable_display) { |
| 293 | DRM_INFO("Display disabled (module parameter)\n"); | 294 | DRM_INFO("Display disabled (module parameter)\n"); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 895b3dc50e3f..92ab01f33208 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -37,7 +37,6 @@ | |||
| 37 | #include "intel_frontbuffer.h" | 37 | #include "intel_frontbuffer.h" |
| 38 | #include <drm/i915_drm.h> | 38 | #include <drm/i915_drm.h> |
| 39 | #include "i915_drv.h" | 39 | #include "i915_drv.h" |
| 40 | #include "i915_gem_dmabuf.h" | ||
| 41 | #include "intel_dsi.h" | 40 | #include "intel_dsi.h" |
| 42 | #include "i915_trace.h" | 41 | #include "i915_trace.h" |
| 43 | #include <drm/drm_atomic.h> | 42 | #include <drm/drm_atomic.h> |
| @@ -116,8 +115,9 @@ static void chv_prepare_pll(struct intel_crtc *crtc, | |||
| 116 | const struct intel_crtc_state *pipe_config); | 115 | const struct intel_crtc_state *pipe_config); |
| 117 | static void intel_begin_crtc_commit(struct drm_crtc *, struct drm_crtc_state *); | 116 | static void intel_begin_crtc_commit(struct drm_crtc *, struct drm_crtc_state *); |
| 118 | static void intel_finish_crtc_commit(struct drm_crtc *, struct drm_crtc_state *); | 117 | static void intel_finish_crtc_commit(struct drm_crtc *, struct drm_crtc_state *); |
| 119 | static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc, | 118 | static void skl_init_scalers(struct drm_i915_private *dev_priv, |
| 120 | struct intel_crtc_state *crtc_state); | 119 | struct intel_crtc *crtc, |
| 120 | struct intel_crtc_state *crtc_state); | ||
| 121 | static void skylake_pfit_enable(struct intel_crtc *crtc); | 121 | static void skylake_pfit_enable(struct intel_crtc *crtc); |
| 122 | static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force); | 122 | static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force); |
| 123 | static void ironlake_pfit_enable(struct intel_crtc *crtc); | 123 | static void ironlake_pfit_enable(struct intel_crtc *crtc); |
| @@ -1008,10 +1008,8 @@ bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock, | |||
| 1008 | target_clock, refclk, NULL, best_clock); | 1008 | target_clock, refclk, NULL, best_clock); |
| 1009 | } | 1009 | } |
| 1010 | 1010 | ||
| 1011 | bool intel_crtc_active(struct drm_crtc *crtc) | 1011 | bool intel_crtc_active(struct intel_crtc *crtc) |
| 1012 | { | 1012 | { |
| 1013 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
| 1014 | |||
| 1015 | /* Be paranoid as we can arrive here with only partial | 1013 | /* Be paranoid as we can arrive here with only partial |
| 1016 | * state retrieved from the hardware during setup. | 1014 | * state retrieved from the hardware during setup. |
| 1017 | * | 1015 | * |
| @@ -1025,17 +1023,16 @@ bool intel_crtc_active(struct drm_crtc *crtc) | |||
| 1025 | * crtc->state->active once we have proper CRTC states wired up | 1023 | * crtc->state->active once we have proper CRTC states wired up |
| 1026 | * for atomic. | 1024 | * for atomic. |
| 1027 | */ | 1025 | */ |
| 1028 | return intel_crtc->active && crtc->primary->state->fb && | 1026 | return crtc->active && crtc->base.primary->state->fb && |
| 1029 | intel_crtc->config->base.adjusted_mode.crtc_clock; | 1027 | crtc->config->base.adjusted_mode.crtc_clock; |
| 1030 | } | 1028 | } |
| 1031 | 1029 | ||
| 1032 | enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv, | 1030 | enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv, |
| 1033 | enum pipe pipe) | 1031 | enum pipe pipe) |
| 1034 | { | 1032 | { |
| 1035 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | 1033 | struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
| 1036 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
| 1037 | 1034 | ||
| 1038 | return intel_crtc->config->cpu_transcoder; | 1035 | return crtc->config->cpu_transcoder; |
| 1039 | } | 1036 | } |
| 1040 | 1037 | ||
| 1041 | static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe) | 1038 | static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe) |
| @@ -1788,8 +1785,8 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv, | |||
| 1788 | static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, | 1785 | static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, |
| 1789 | enum pipe pipe) | 1786 | enum pipe pipe) |
| 1790 | { | 1787 | { |
| 1791 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | 1788 | struct intel_crtc *intel_crtc = intel_get_crtc_for_pipe(dev_priv, |
| 1792 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1789 | pipe); |
| 1793 | i915_reg_t reg; | 1790 | i915_reg_t reg; |
| 1794 | uint32_t val, pipeconf_val; | 1791 | uint32_t val, pipeconf_val; |
| 1795 | 1792 | ||
| @@ -4253,6 +4250,7 @@ static void ironlake_fdi_disable(struct drm_crtc *crtc) | |||
| 4253 | 4250 | ||
| 4254 | bool intel_has_pending_fb_unpin(struct drm_device *dev) | 4251 | bool intel_has_pending_fb_unpin(struct drm_device *dev) |
| 4255 | { | 4252 | { |
| 4253 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 4256 | struct intel_crtc *crtc; | 4254 | struct intel_crtc *crtc; |
| 4257 | 4255 | ||
| 4258 | /* Note that we don't need to be called with mode_config.lock here | 4256 | /* Note that we don't need to be called with mode_config.lock here |
| @@ -4267,7 +4265,7 @@ bool intel_has_pending_fb_unpin(struct drm_device *dev) | |||
| 4267 | continue; | 4265 | continue; |
| 4268 | 4266 | ||
| 4269 | if (crtc->flip_work) | 4267 | if (crtc->flip_work) |
| 4270 | intel_wait_for_vblank(dev, crtc->pipe); | 4268 | intel_wait_for_vblank(dev_priv, crtc->pipe); |
| 4271 | 4269 | ||
| 4272 | return true; | 4270 | return true; |
| 4273 | } | 4271 | } |
| @@ -4944,7 +4942,7 @@ void hsw_disable_ips(struct intel_crtc *crtc) | |||
| 4944 | } | 4942 | } |
| 4945 | 4943 | ||
| 4946 | /* We need to wait for a vblank before we can disable the plane. */ | 4944 | /* We need to wait for a vblank before we can disable the plane. */ |
| 4947 | intel_wait_for_vblank(dev, crtc->pipe); | 4945 | intel_wait_for_vblank(dev_priv, crtc->pipe); |
| 4948 | } | 4946 | } |
| 4949 | 4947 | ||
| 4950 | static void intel_crtc_dpms_overlay_disable(struct intel_crtc *intel_crtc) | 4948 | static void intel_crtc_dpms_overlay_disable(struct intel_crtc *intel_crtc) |
| @@ -5056,7 +5054,7 @@ intel_pre_disable_primary_noatomic(struct drm_crtc *crtc) | |||
| 5056 | if (HAS_GMCH_DISPLAY(dev_priv)) { | 5054 | if (HAS_GMCH_DISPLAY(dev_priv)) { |
| 5057 | intel_set_memory_cxsr(dev_priv, false); | 5055 | intel_set_memory_cxsr(dev_priv, false); |
| 5058 | dev_priv->wm.vlv.cxsr = false; | 5056 | dev_priv->wm.vlv.cxsr = false; |
| 5059 | intel_wait_for_vblank(dev, pipe); | 5057 | intel_wait_for_vblank(dev_priv, pipe); |
| 5060 | } | 5058 | } |
| 5061 | } | 5059 | } |
| 5062 | 5060 | ||
| @@ -5075,7 +5073,7 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state) | |||
| 5075 | crtc->wm.cxsr_allowed = true; | 5073 | crtc->wm.cxsr_allowed = true; |
| 5076 | 5074 | ||
| 5077 | if (pipe_config->update_wm_post && pipe_config->base.active) | 5075 | if (pipe_config->update_wm_post && pipe_config->base.active) |
| 5078 | intel_update_watermarks(&crtc->base); | 5076 | intel_update_watermarks(crtc); |
| 5079 | 5077 | ||
| 5080 | if (old_pri_state) { | 5078 | if (old_pri_state) { |
| 5081 | struct intel_plane_state *primary_state = | 5079 | struct intel_plane_state *primary_state = |
| @@ -5133,7 +5131,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state) | |||
| 5133 | if (old_crtc_state->base.active) { | 5131 | if (old_crtc_state->base.active) { |
| 5134 | intel_set_memory_cxsr(dev_priv, false); | 5132 | intel_set_memory_cxsr(dev_priv, false); |
| 5135 | dev_priv->wm.vlv.cxsr = false; | 5133 | dev_priv->wm.vlv.cxsr = false; |
| 5136 | intel_wait_for_vblank(dev, crtc->pipe); | 5134 | intel_wait_for_vblank(dev_priv, crtc->pipe); |
| 5137 | } | 5135 | } |
| 5138 | } | 5136 | } |
| 5139 | 5137 | ||
| @@ -5146,7 +5144,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state) | |||
| 5146 | */ | 5144 | */ |
| 5147 | if (pipe_config->disable_lp_wm) { | 5145 | if (pipe_config->disable_lp_wm) { |
| 5148 | ilk_disable_lp_wm(dev); | 5146 | ilk_disable_lp_wm(dev); |
| 5149 | intel_wait_for_vblank(dev, crtc->pipe); | 5147 | intel_wait_for_vblank(dev_priv, crtc->pipe); |
| 5150 | } | 5148 | } |
| 5151 | 5149 | ||
| 5152 | /* | 5150 | /* |
| @@ -5173,7 +5171,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state) | |||
| 5173 | if (dev_priv->display.initial_watermarks != NULL) | 5171 | if (dev_priv->display.initial_watermarks != NULL) |
| 5174 | dev_priv->display.initial_watermarks(pipe_config); | 5172 | dev_priv->display.initial_watermarks(pipe_config); |
| 5175 | else if (pipe_config->update_wm_pre) | 5173 | else if (pipe_config->update_wm_pre) |
| 5176 | intel_update_watermarks(&crtc->base); | 5174 | intel_update_watermarks(crtc); |
| 5177 | } | 5175 | } |
| 5178 | 5176 | ||
| 5179 | static void intel_crtc_disable_planes(struct drm_crtc *crtc, unsigned plane_mask) | 5177 | static void intel_crtc_disable_planes(struct drm_crtc *crtc, unsigned plane_mask) |
| @@ -5401,7 +5399,7 @@ static void ironlake_crtc_enable(struct intel_crtc_state *pipe_config, | |||
| 5401 | 5399 | ||
| 5402 | /* Must wait for vblank to avoid spurious PCH FIFO underruns */ | 5400 | /* Must wait for vblank to avoid spurious PCH FIFO underruns */ |
| 5403 | if (intel_crtc->config->has_pch_encoder) | 5401 | if (intel_crtc->config->has_pch_encoder) |
| 5404 | intel_wait_for_vblank(dev, pipe); | 5402 | intel_wait_for_vblank(dev_priv, pipe); |
| 5405 | intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); | 5403 | intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); |
| 5406 | intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true); | 5404 | intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true); |
| 5407 | } | 5405 | } |
| @@ -5493,7 +5491,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config, | |||
| 5493 | if (dev_priv->display.initial_watermarks != NULL) | 5491 | if (dev_priv->display.initial_watermarks != NULL) |
| 5494 | dev_priv->display.initial_watermarks(pipe_config); | 5492 | dev_priv->display.initial_watermarks(pipe_config); |
| 5495 | else | 5493 | else |
| 5496 | intel_update_watermarks(crtc); | 5494 | intel_update_watermarks(intel_crtc); |
| 5497 | 5495 | ||
| 5498 | /* XXX: Do the pipe assertions at the right place for BXT DSI. */ | 5496 | /* XXX: Do the pipe assertions at the right place for BXT DSI. */ |
| 5499 | if (!transcoder_is_dsi(cpu_transcoder)) | 5497 | if (!transcoder_is_dsi(cpu_transcoder)) |
| @@ -5511,8 +5509,8 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config, | |||
| 5511 | intel_encoders_enable(crtc, pipe_config, old_state); | 5509 | intel_encoders_enable(crtc, pipe_config, old_state); |
| 5512 | 5510 | ||
| 5513 | if (intel_crtc->config->has_pch_encoder) { | 5511 | if (intel_crtc->config->has_pch_encoder) { |
| 5514 | intel_wait_for_vblank(dev, pipe); | 5512 | intel_wait_for_vblank(dev_priv, pipe); |
| 5515 | intel_wait_for_vblank(dev, pipe); | 5513 | intel_wait_for_vblank(dev_priv, pipe); |
| 5516 | intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); | 5514 | intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); |
| 5517 | intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A, | 5515 | intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A, |
| 5518 | true); | 5516 | true); |
| @@ -5522,8 +5520,8 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config, | |||
| 5522 | * to change the workaround. */ | 5520 | * to change the workaround. */ |
| 5523 | hsw_workaround_pipe = pipe_config->hsw_workaround_pipe; | 5521 | hsw_workaround_pipe = pipe_config->hsw_workaround_pipe; |
| 5524 | if (IS_HASWELL(dev_priv) && hsw_workaround_pipe != INVALID_PIPE) { | 5522 | if (IS_HASWELL(dev_priv) && hsw_workaround_pipe != INVALID_PIPE) { |
| 5525 | intel_wait_for_vblank(dev, hsw_workaround_pipe); | 5523 | intel_wait_for_vblank(dev_priv, hsw_workaround_pipe); |
| 5526 | intel_wait_for_vblank(dev, hsw_workaround_pipe); | 5524 | intel_wait_for_vblank(dev_priv, hsw_workaround_pipe); |
| 5527 | } | 5525 | } |
| 5528 | } | 5526 | } |
| 5529 | 5527 | ||
| @@ -5844,10 +5842,8 @@ static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv) | |||
| 5844 | 5842 | ||
| 5845 | static int skl_calc_cdclk(int max_pixclk, int vco); | 5843 | static int skl_calc_cdclk(int max_pixclk, int vco); |
| 5846 | 5844 | ||
| 5847 | static void intel_update_max_cdclk(struct drm_device *dev) | 5845 | static void intel_update_max_cdclk(struct drm_i915_private *dev_priv) |
| 5848 | { | 5846 | { |
| 5849 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 5850 | |||
| 5851 | if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { | 5847 | if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { |
| 5852 | u32 limit = I915_READ(SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK; | 5848 | u32 limit = I915_READ(SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK; |
| 5853 | int max_cdclk, vco; | 5849 | int max_cdclk, vco; |
| @@ -5905,11 +5901,9 @@ static void intel_update_max_cdclk(struct drm_device *dev) | |||
| 5905 | dev_priv->max_dotclk_freq); | 5901 | dev_priv->max_dotclk_freq); |
| 5906 | } | 5902 | } |
| 5907 | 5903 | ||
| 5908 | static void intel_update_cdclk(struct drm_device *dev) | 5904 | static void intel_update_cdclk(struct drm_i915_private *dev_priv) |
| 5909 | { | 5905 | { |
| 5910 | struct drm_i915_private *dev_priv = to_i915(dev); | 5906 | dev_priv->cdclk_freq = dev_priv->display.get_display_clock_speed(dev_priv); |
| 5911 | |||
| 5912 | dev_priv->cdclk_freq = dev_priv->display.get_display_clock_speed(dev); | ||
| 5913 | 5907 | ||
| 5914 | if (INTEL_GEN(dev_priv) >= 9) | 5908 | if (INTEL_GEN(dev_priv) >= 9) |
| 5915 | DRM_DEBUG_DRIVER("Current CD clock rate: %d kHz, VCO: %d kHz, ref: %d kHz\n", | 5909 | DRM_DEBUG_DRIVER("Current CD clock rate: %d kHz, VCO: %d kHz, ref: %d kHz\n", |
| @@ -6070,14 +6064,14 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, int cdclk) | |||
| 6070 | return; | 6064 | return; |
| 6071 | } | 6065 | } |
| 6072 | 6066 | ||
| 6073 | intel_update_cdclk(&dev_priv->drm); | 6067 | intel_update_cdclk(dev_priv); |
| 6074 | } | 6068 | } |
| 6075 | 6069 | ||
| 6076 | static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) | 6070 | static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) |
| 6077 | { | 6071 | { |
| 6078 | u32 cdctl, expected; | 6072 | u32 cdctl, expected; |
| 6079 | 6073 | ||
| 6080 | intel_update_cdclk(&dev_priv->drm); | 6074 | intel_update_cdclk(dev_priv); |
| 6081 | 6075 | ||
| 6082 | if (dev_priv->cdclk_pll.vco == 0 || | 6076 | if (dev_priv->cdclk_pll.vco == 0 || |
| 6083 | dev_priv->cdclk_freq == dev_priv->cdclk_pll.ref) | 6077 | dev_priv->cdclk_freq == dev_priv->cdclk_pll.ref) |
| @@ -6210,7 +6204,7 @@ void skl_set_preferred_cdclk_vco(struct drm_i915_private *dev_priv, int vco) | |||
| 6210 | dev_priv->skl_preferred_vco_freq = vco; | 6204 | dev_priv->skl_preferred_vco_freq = vco; |
| 6211 | 6205 | ||
| 6212 | if (changed) | 6206 | if (changed) |
| 6213 | intel_update_max_cdclk(&dev_priv->drm); | 6207 | intel_update_max_cdclk(dev_priv); |
| 6214 | } | 6208 | } |
| 6215 | 6209 | ||
| 6216 | static void | 6210 | static void |
| @@ -6296,7 +6290,6 @@ static bool skl_cdclk_wait_for_pcu_ready(struct drm_i915_private *dev_priv) | |||
| 6296 | 6290 | ||
| 6297 | static void skl_set_cdclk(struct drm_i915_private *dev_priv, int cdclk, int vco) | 6291 | static void skl_set_cdclk(struct drm_i915_private *dev_priv, int cdclk, int vco) |
| 6298 | { | 6292 | { |
| 6299 | struct drm_device *dev = &dev_priv->drm; | ||
| 6300 | u32 freq_select, pcu_ack; | 6293 | u32 freq_select, pcu_ack; |
| 6301 | 6294 | ||
| 6302 | WARN_ON((cdclk == 24000) != (vco == 0)); | 6295 | WARN_ON((cdclk == 24000) != (vco == 0)); |
| @@ -6347,7 +6340,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv, int cdclk, int vco) | |||
| 6347 | sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack); | 6340 | sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack); |
| 6348 | mutex_unlock(&dev_priv->rps.hw_lock); | 6341 | mutex_unlock(&dev_priv->rps.hw_lock); |
| 6349 | 6342 | ||
| 6350 | intel_update_cdclk(dev); | 6343 | intel_update_cdclk(dev_priv); |
| 6351 | } | 6344 | } |
| 6352 | 6345 | ||
| 6353 | static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv); | 6346 | static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv); |
| @@ -6394,7 +6387,7 @@ static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv) | |||
| 6394 | if ((I915_READ(SWF_ILK(0x18)) & 0x00FFFFFF) == 0) | 6387 | if ((I915_READ(SWF_ILK(0x18)) & 0x00FFFFFF) == 0) |
| 6395 | goto sanitize; | 6388 | goto sanitize; |
| 6396 | 6389 | ||
| 6397 | intel_update_cdclk(&dev_priv->drm); | 6390 | intel_update_cdclk(dev_priv); |
| 6398 | /* Is PLL enabled and locked ? */ | 6391 | /* Is PLL enabled and locked ? */ |
| 6399 | if (dev_priv->cdclk_pll.vco == 0 || | 6392 | if (dev_priv->cdclk_pll.vco == 0 || |
| 6400 | dev_priv->cdclk_freq == dev_priv->cdclk_pll.ref) | 6393 | dev_priv->cdclk_freq == dev_priv->cdclk_pll.ref) |
| @@ -6428,7 +6421,7 @@ static void valleyview_set_cdclk(struct drm_device *dev, int cdclk) | |||
| 6428 | struct drm_i915_private *dev_priv = to_i915(dev); | 6421 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 6429 | u32 val, cmd; | 6422 | u32 val, cmd; |
| 6430 | 6423 | ||
| 6431 | WARN_ON(dev_priv->display.get_display_clock_speed(dev) | 6424 | WARN_ON(dev_priv->display.get_display_clock_speed(dev_priv) |
| 6432 | != dev_priv->cdclk_freq); | 6425 | != dev_priv->cdclk_freq); |
| 6433 | 6426 | ||
| 6434 | if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */ | 6427 | if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */ |
| @@ -6485,7 +6478,7 @@ static void valleyview_set_cdclk(struct drm_device *dev, int cdclk) | |||
| 6485 | 6478 | ||
| 6486 | mutex_unlock(&dev_priv->sb_lock); | 6479 | mutex_unlock(&dev_priv->sb_lock); |
| 6487 | 6480 | ||
| 6488 | intel_update_cdclk(dev); | 6481 | intel_update_cdclk(dev_priv); |
| 6489 | } | 6482 | } |
| 6490 | 6483 | ||
| 6491 | static void cherryview_set_cdclk(struct drm_device *dev, int cdclk) | 6484 | static void cherryview_set_cdclk(struct drm_device *dev, int cdclk) |
| @@ -6493,7 +6486,7 @@ static void cherryview_set_cdclk(struct drm_device *dev, int cdclk) | |||
| 6493 | struct drm_i915_private *dev_priv = to_i915(dev); | 6486 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 6494 | u32 val, cmd; | 6487 | u32 val, cmd; |
| 6495 | 6488 | ||
| 6496 | WARN_ON(dev_priv->display.get_display_clock_speed(dev) | 6489 | WARN_ON(dev_priv->display.get_display_clock_speed(dev_priv) |
| 6497 | != dev_priv->cdclk_freq); | 6490 | != dev_priv->cdclk_freq); |
| 6498 | 6491 | ||
| 6499 | switch (cdclk) { | 6492 | switch (cdclk) { |
| @@ -6526,7 +6519,7 @@ static void cherryview_set_cdclk(struct drm_device *dev, int cdclk) | |||
| 6526 | } | 6519 | } |
| 6527 | mutex_unlock(&dev_priv->rps.hw_lock); | 6520 | mutex_unlock(&dev_priv->rps.hw_lock); |
| 6528 | 6521 | ||
| 6529 | intel_update_cdclk(dev); | 6522 | intel_update_cdclk(dev_priv); |
| 6530 | } | 6523 | } |
| 6531 | 6524 | ||
| 6532 | static int valleyview_calc_cdclk(struct drm_i915_private *dev_priv, | 6525 | static int valleyview_calc_cdclk(struct drm_i915_private *dev_priv, |
| @@ -6746,7 +6739,7 @@ static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config, | |||
| 6746 | 6739 | ||
| 6747 | intel_color_load_luts(&pipe_config->base); | 6740 | intel_color_load_luts(&pipe_config->base); |
| 6748 | 6741 | ||
| 6749 | intel_update_watermarks(crtc); | 6742 | intel_update_watermarks(intel_crtc); |
| 6750 | intel_enable_pipe(intel_crtc); | 6743 | intel_enable_pipe(intel_crtc); |
| 6751 | 6744 | ||
| 6752 | assert_vblank_disabled(crtc); | 6745 | assert_vblank_disabled(crtc); |
| @@ -6799,7 +6792,7 @@ static void i9xx_crtc_enable(struct intel_crtc_state *pipe_config, | |||
| 6799 | 6792 | ||
| 6800 | intel_color_load_luts(&pipe_config->base); | 6793 | intel_color_load_luts(&pipe_config->base); |
| 6801 | 6794 | ||
| 6802 | intel_update_watermarks(crtc); | 6795 | intel_update_watermarks(intel_crtc); |
| 6803 | intel_enable_pipe(intel_crtc); | 6796 | intel_enable_pipe(intel_crtc); |
| 6804 | 6797 | ||
| 6805 | assert_vblank_disabled(crtc); | 6798 | assert_vblank_disabled(crtc); |
| @@ -6837,7 +6830,7 @@ static void i9xx_crtc_disable(struct intel_crtc_state *old_crtc_state, | |||
| 6837 | * wait for planes to fully turn off before disabling the pipe. | 6830 | * wait for planes to fully turn off before disabling the pipe. |
| 6838 | */ | 6831 | */ |
| 6839 | if (IS_GEN2(dev_priv)) | 6832 | if (IS_GEN2(dev_priv)) |
| 6840 | intel_wait_for_vblank(dev, pipe); | 6833 | intel_wait_for_vblank(dev_priv, pipe); |
| 6841 | 6834 | ||
| 6842 | intel_encoders_disable(crtc, old_crtc_state, old_state); | 6835 | intel_encoders_disable(crtc, old_crtc_state, old_state); |
| 6843 | 6836 | ||
| @@ -6915,7 +6908,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc) | |||
| 6915 | encoder->base.crtc = NULL; | 6908 | encoder->base.crtc = NULL; |
| 6916 | 6909 | ||
| 6917 | intel_fbc_disable(intel_crtc); | 6910 | intel_fbc_disable(intel_crtc); |
| 6918 | intel_update_watermarks(crtc); | 6911 | intel_update_watermarks(intel_crtc); |
| 6919 | intel_disable_shared_dpll(intel_crtc); | 6912 | intel_disable_shared_dpll(intel_crtc); |
| 6920 | 6913 | ||
| 6921 | domains = intel_crtc->enabled_power_domains; | 6914 | domains = intel_crtc->enabled_power_domains; |
| @@ -7075,7 +7068,7 @@ static int ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, | |||
| 7075 | if (pipe_config->fdi_lanes <= 2) | 7068 | if (pipe_config->fdi_lanes <= 2) |
| 7076 | return 0; | 7069 | return 0; |
| 7077 | 7070 | ||
| 7078 | other_crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev, PIPE_C)); | 7071 | other_crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_C); |
| 7079 | other_crtc_state = | 7072 | other_crtc_state = |
| 7080 | intel_atomic_get_crtc_state(state, other_crtc); | 7073 | intel_atomic_get_crtc_state(state, other_crtc); |
| 7081 | if (IS_ERR(other_crtc_state)) | 7074 | if (IS_ERR(other_crtc_state)) |
| @@ -7094,7 +7087,7 @@ static int ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, | |||
| 7094 | return -EINVAL; | 7087 | return -EINVAL; |
| 7095 | } | 7088 | } |
| 7096 | 7089 | ||
| 7097 | other_crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev, PIPE_B)); | 7090 | other_crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_B); |
| 7098 | other_crtc_state = | 7091 | other_crtc_state = |
| 7099 | intel_atomic_get_crtc_state(state, other_crtc); | 7092 | intel_atomic_get_crtc_state(state, other_crtc); |
| 7100 | if (IS_ERR(other_crtc_state)) | 7093 | if (IS_ERR(other_crtc_state)) |
| @@ -7252,10 +7245,9 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc, | |||
| 7252 | return 0; | 7245 | return 0; |
| 7253 | } | 7246 | } |
| 7254 | 7247 | ||
| 7255 | static int skylake_get_display_clock_speed(struct drm_device *dev) | 7248 | static int skylake_get_display_clock_speed(struct drm_i915_private *dev_priv) |
| 7256 | { | 7249 | { |
| 7257 | struct drm_i915_private *dev_priv = to_i915(dev); | 7250 | u32 cdctl; |
| 7258 | uint32_t cdctl; | ||
| 7259 | 7251 | ||
| 7260 | skl_dpll0_update(dev_priv); | 7252 | skl_dpll0_update(dev_priv); |
| 7261 | 7253 | ||
| @@ -7314,9 +7306,8 @@ static void bxt_de_pll_update(struct drm_i915_private *dev_priv) | |||
| 7314 | dev_priv->cdclk_pll.ref; | 7306 | dev_priv->cdclk_pll.ref; |
| 7315 | } | 7307 | } |
| 7316 | 7308 | ||
| 7317 | static int broxton_get_display_clock_speed(struct drm_device *dev) | 7309 | static int broxton_get_display_clock_speed(struct drm_i915_private *dev_priv) |
| 7318 | { | 7310 | { |
| 7319 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7320 | u32 divider; | 7311 | u32 divider; |
| 7321 | int div, vco; | 7312 | int div, vco; |
| 7322 | 7313 | ||
| @@ -7349,9 +7340,8 @@ static int broxton_get_display_clock_speed(struct drm_device *dev) | |||
| 7349 | return DIV_ROUND_CLOSEST(vco, div); | 7340 | return DIV_ROUND_CLOSEST(vco, div); |
| 7350 | } | 7341 | } |
| 7351 | 7342 | ||
| 7352 | static int broadwell_get_display_clock_speed(struct drm_device *dev) | 7343 | static int broadwell_get_display_clock_speed(struct drm_i915_private *dev_priv) |
| 7353 | { | 7344 | { |
| 7354 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7355 | uint32_t lcpll = I915_READ(LCPLL_CTL); | 7345 | uint32_t lcpll = I915_READ(LCPLL_CTL); |
| 7356 | uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK; | 7346 | uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK; |
| 7357 | 7347 | ||
| @@ -7369,9 +7359,8 @@ static int broadwell_get_display_clock_speed(struct drm_device *dev) | |||
| 7369 | return 675000; | 7359 | return 675000; |
| 7370 | } | 7360 | } |
| 7371 | 7361 | ||
| 7372 | static int haswell_get_display_clock_speed(struct drm_device *dev) | 7362 | static int haswell_get_display_clock_speed(struct drm_i915_private *dev_priv) |
| 7373 | { | 7363 | { |
| 7374 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7375 | uint32_t lcpll = I915_READ(LCPLL_CTL); | 7364 | uint32_t lcpll = I915_READ(LCPLL_CTL); |
| 7376 | uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK; | 7365 | uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK; |
| 7377 | 7366 | ||
| @@ -7387,35 +7376,35 @@ static int haswell_get_display_clock_speed(struct drm_device *dev) | |||
| 7387 | return 540000; | 7376 | return 540000; |
| 7388 | } | 7377 | } |
| 7389 | 7378 | ||
| 7390 | static int valleyview_get_display_clock_speed(struct drm_device *dev) | 7379 | static int valleyview_get_display_clock_speed(struct drm_i915_private *dev_priv) |
| 7391 | { | 7380 | { |
| 7392 | return vlv_get_cck_clock_hpll(to_i915(dev), "cdclk", | 7381 | return vlv_get_cck_clock_hpll(dev_priv, "cdclk", |
| 7393 | CCK_DISPLAY_CLOCK_CONTROL); | 7382 | CCK_DISPLAY_CLOCK_CONTROL); |
| 7394 | } | 7383 | } |
| 7395 | 7384 | ||
| 7396 | static int ilk_get_display_clock_speed(struct drm_device *dev) | 7385 | static int ilk_get_display_clock_speed(struct drm_i915_private *dev_priv) |
| 7397 | { | 7386 | { |
| 7398 | return 450000; | 7387 | return 450000; |
| 7399 | } | 7388 | } |
| 7400 | 7389 | ||
| 7401 | static int i945_get_display_clock_speed(struct drm_device *dev) | 7390 | static int i945_get_display_clock_speed(struct drm_i915_private *dev_priv) |
| 7402 | { | 7391 | { |
| 7403 | return 400000; | 7392 | return 400000; |
| 7404 | } | 7393 | } |
| 7405 | 7394 | ||
| 7406 | static int i915_get_display_clock_speed(struct drm_device *dev) | 7395 | static int i915_get_display_clock_speed(struct drm_i915_private *dev_priv) |
| 7407 | { | 7396 | { |
| 7408 | return 333333; | 7397 | return 333333; |
| 7409 | } | 7398 | } |
| 7410 | 7399 | ||
| 7411 | static int i9xx_misc_get_display_clock_speed(struct drm_device *dev) | 7400 | static int i9xx_misc_get_display_clock_speed(struct drm_i915_private *dev_priv) |
| 7412 | { | 7401 | { |
| 7413 | return 200000; | 7402 | return 200000; |
| 7414 | } | 7403 | } |
| 7415 | 7404 | ||
| 7416 | static int pnv_get_display_clock_speed(struct drm_device *dev) | 7405 | static int pnv_get_display_clock_speed(struct drm_i915_private *dev_priv) |
| 7417 | { | 7406 | { |
| 7418 | struct pci_dev *pdev = dev->pdev; | 7407 | struct pci_dev *pdev = dev_priv->drm.pdev; |
| 7419 | u16 gcfgc = 0; | 7408 | u16 gcfgc = 0; |
| 7420 | 7409 | ||
| 7421 | pci_read_config_word(pdev, GCFGC, &gcfgc); | 7410 | pci_read_config_word(pdev, GCFGC, &gcfgc); |
| @@ -7438,9 +7427,9 @@ static int pnv_get_display_clock_speed(struct drm_device *dev) | |||
| 7438 | } | 7427 | } |
| 7439 | } | 7428 | } |
| 7440 | 7429 | ||
| 7441 | static int i915gm_get_display_clock_speed(struct drm_device *dev) | 7430 | static int i915gm_get_display_clock_speed(struct drm_i915_private *dev_priv) |
| 7442 | { | 7431 | { |
| 7443 | struct pci_dev *pdev = dev->pdev; | 7432 | struct pci_dev *pdev = dev_priv->drm.pdev; |
| 7444 | u16 gcfgc = 0; | 7433 | u16 gcfgc = 0; |
| 7445 | 7434 | ||
| 7446 | pci_read_config_word(pdev, GCFGC, &gcfgc); | 7435 | pci_read_config_word(pdev, GCFGC, &gcfgc); |
| @@ -7458,14 +7447,14 @@ static int i915gm_get_display_clock_speed(struct drm_device *dev) | |||
| 7458 | } | 7447 | } |
| 7459 | } | 7448 | } |
| 7460 | 7449 | ||
| 7461 | static int i865_get_display_clock_speed(struct drm_device *dev) | 7450 | static int i865_get_display_clock_speed(struct drm_i915_private *dev_priv) |
| 7462 | { | 7451 | { |
| 7463 | return 266667; | 7452 | return 266667; |
| 7464 | } | 7453 | } |
| 7465 | 7454 | ||
| 7466 | static int i85x_get_display_clock_speed(struct drm_device *dev) | 7455 | static int i85x_get_display_clock_speed(struct drm_i915_private *dev_priv) |
| 7467 | { | 7456 | { |
| 7468 | struct pci_dev *pdev = dev->pdev; | 7457 | struct pci_dev *pdev = dev_priv->drm.pdev; |
| 7469 | u16 hpllcc = 0; | 7458 | u16 hpllcc = 0; |
| 7470 | 7459 | ||
| 7471 | /* | 7460 | /* |
| @@ -7501,14 +7490,13 @@ static int i85x_get_display_clock_speed(struct drm_device *dev) | |||
| 7501 | return 0; | 7490 | return 0; |
| 7502 | } | 7491 | } |
| 7503 | 7492 | ||
| 7504 | static int i830_get_display_clock_speed(struct drm_device *dev) | 7493 | static int i830_get_display_clock_speed(struct drm_i915_private *dev_priv) |
| 7505 | { | 7494 | { |
| 7506 | return 133333; | 7495 | return 133333; |
| 7507 | } | 7496 | } |
| 7508 | 7497 | ||
| 7509 | static unsigned int intel_hpll_vco(struct drm_device *dev) | 7498 | static unsigned int intel_hpll_vco(struct drm_i915_private *dev_priv) |
| 7510 | { | 7499 | { |
| 7511 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7512 | static const unsigned int blb_vco[8] = { | 7500 | static const unsigned int blb_vco[8] = { |
| 7513 | [0] = 3200000, | 7501 | [0] = 3200000, |
| 7514 | [1] = 4000000, | 7502 | [1] = 4000000, |
| @@ -7555,16 +7543,16 @@ static unsigned int intel_hpll_vco(struct drm_device *dev) | |||
| 7555 | vco_table = ctg_vco; | 7543 | vco_table = ctg_vco; |
| 7556 | else if (IS_G4X(dev_priv)) | 7544 | else if (IS_G4X(dev_priv)) |
| 7557 | vco_table = elk_vco; | 7545 | vco_table = elk_vco; |
| 7558 | else if (IS_CRESTLINE(dev)) | 7546 | else if (IS_CRESTLINE(dev_priv)) |
| 7559 | vco_table = cl_vco; | 7547 | vco_table = cl_vco; |
| 7560 | else if (IS_PINEVIEW(dev)) | 7548 | else if (IS_PINEVIEW(dev_priv)) |
| 7561 | vco_table = pnv_vco; | 7549 | vco_table = pnv_vco; |
| 7562 | else if (IS_G33(dev)) | 7550 | else if (IS_G33(dev_priv)) |
| 7563 | vco_table = blb_vco; | 7551 | vco_table = blb_vco; |
| 7564 | else | 7552 | else |
| 7565 | return 0; | 7553 | return 0; |
| 7566 | 7554 | ||
| 7567 | tmp = I915_READ(IS_MOBILE(dev) ? HPLLVCO_MOBILE : HPLLVCO); | 7555 | tmp = I915_READ(IS_MOBILE(dev_priv) ? HPLLVCO_MOBILE : HPLLVCO); |
| 7568 | 7556 | ||
| 7569 | vco = vco_table[tmp & 0x7]; | 7557 | vco = vco_table[tmp & 0x7]; |
| 7570 | if (vco == 0) | 7558 | if (vco == 0) |
| @@ -7575,10 +7563,10 @@ static unsigned int intel_hpll_vco(struct drm_device *dev) | |||
| 7575 | return vco; | 7563 | return vco; |
| 7576 | } | 7564 | } |
| 7577 | 7565 | ||
| 7578 | static int gm45_get_display_clock_speed(struct drm_device *dev) | 7566 | static int gm45_get_display_clock_speed(struct drm_i915_private *dev_priv) |
| 7579 | { | 7567 | { |
| 7580 | struct pci_dev *pdev = dev->pdev; | 7568 | struct pci_dev *pdev = dev_priv->drm.pdev; |
| 7581 | unsigned int cdclk_sel, vco = intel_hpll_vco(dev); | 7569 | unsigned int cdclk_sel, vco = intel_hpll_vco(dev_priv); |
| 7582 | uint16_t tmp = 0; | 7570 | uint16_t tmp = 0; |
| 7583 | 7571 | ||
| 7584 | pci_read_config_word(pdev, GCFGC, &tmp); | 7572 | pci_read_config_word(pdev, GCFGC, &tmp); |
| @@ -7598,14 +7586,14 @@ static int gm45_get_display_clock_speed(struct drm_device *dev) | |||
| 7598 | } | 7586 | } |
| 7599 | } | 7587 | } |
| 7600 | 7588 | ||
| 7601 | static int i965gm_get_display_clock_speed(struct drm_device *dev) | 7589 | static int i965gm_get_display_clock_speed(struct drm_i915_private *dev_priv) |
| 7602 | { | 7590 | { |
| 7603 | struct pci_dev *pdev = dev->pdev; | 7591 | struct pci_dev *pdev = dev_priv->drm.pdev; |
| 7604 | static const uint8_t div_3200[] = { 16, 10, 8 }; | 7592 | static const uint8_t div_3200[] = { 16, 10, 8 }; |
| 7605 | static const uint8_t div_4000[] = { 20, 12, 10 }; | 7593 | static const uint8_t div_4000[] = { 20, 12, 10 }; |
| 7606 | static const uint8_t div_5333[] = { 24, 16, 14 }; | 7594 | static const uint8_t div_5333[] = { 24, 16, 14 }; |
| 7607 | const uint8_t *div_table; | 7595 | const uint8_t *div_table; |
| 7608 | unsigned int cdclk_sel, vco = intel_hpll_vco(dev); | 7596 | unsigned int cdclk_sel, vco = intel_hpll_vco(dev_priv); |
| 7609 | uint16_t tmp = 0; | 7597 | uint16_t tmp = 0; |
| 7610 | 7598 | ||
| 7611 | pci_read_config_word(pdev, GCFGC, &tmp); | 7599 | pci_read_config_word(pdev, GCFGC, &tmp); |
| @@ -7636,15 +7624,15 @@ fail: | |||
| 7636 | return 200000; | 7624 | return 200000; |
| 7637 | } | 7625 | } |
| 7638 | 7626 | ||
| 7639 | static int g33_get_display_clock_speed(struct drm_device *dev) | 7627 | static int g33_get_display_clock_speed(struct drm_i915_private *dev_priv) |
| 7640 | { | 7628 | { |
| 7641 | struct pci_dev *pdev = dev->pdev; | 7629 | struct pci_dev *pdev = dev_priv->drm.pdev; |
| 7642 | static const uint8_t div_3200[] = { 12, 10, 8, 7, 5, 16 }; | 7630 | static const uint8_t div_3200[] = { 12, 10, 8, 7, 5, 16 }; |
| 7643 | static const uint8_t div_4000[] = { 14, 12, 10, 8, 6, 20 }; | 7631 | static const uint8_t div_4000[] = { 14, 12, 10, 8, 6, 20 }; |
| 7644 | static const uint8_t div_4800[] = { 20, 14, 12, 10, 8, 24 }; | 7632 | static const uint8_t div_4800[] = { 20, 14, 12, 10, 8, 24 }; |
| 7645 | static const uint8_t div_5333[] = { 20, 16, 12, 12, 8, 28 }; | 7633 | static const uint8_t div_5333[] = { 20, 16, 12, 12, 8, 28 }; |
| 7646 | const uint8_t *div_table; | 7634 | const uint8_t *div_table; |
| 7647 | unsigned int cdclk_sel, vco = intel_hpll_vco(dev); | 7635 | unsigned int cdclk_sel, vco = intel_hpll_vco(dev_priv); |
| 7648 | uint16_t tmp = 0; | 7636 | uint16_t tmp = 0; |
| 7649 | 7637 | ||
| 7650 | pci_read_config_word(pdev, GCFGC, &tmp); | 7638 | pci_read_config_word(pdev, GCFGC, &tmp); |
| @@ -7733,10 +7721,10 @@ static void i9xx_update_pll_dividers(struct intel_crtc *crtc, | |||
| 7733 | struct intel_crtc_state *crtc_state, | 7721 | struct intel_crtc_state *crtc_state, |
| 7734 | struct dpll *reduced_clock) | 7722 | struct dpll *reduced_clock) |
| 7735 | { | 7723 | { |
| 7736 | struct drm_device *dev = crtc->base.dev; | 7724 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
| 7737 | u32 fp, fp2 = 0; | 7725 | u32 fp, fp2 = 0; |
| 7738 | 7726 | ||
| 7739 | if (IS_PINEVIEW(dev)) { | 7727 | if (IS_PINEVIEW(dev_priv)) { |
| 7740 | fp = pnv_dpll_compute_fp(&crtc_state->dpll); | 7728 | fp = pnv_dpll_compute_fp(&crtc_state->dpll); |
| 7741 | if (reduced_clock) | 7729 | if (reduced_clock) |
| 7742 | fp2 = pnv_dpll_compute_fp(reduced_clock); | 7730 | fp2 = pnv_dpll_compute_fp(reduced_clock); |
| @@ -8106,11 +8094,10 @@ static void chv_prepare_pll(struct intel_crtc *crtc, | |||
| 8106 | * in cases where we need the PLL enabled even when @pipe is not going to | 8094 | * in cases where we need the PLL enabled even when @pipe is not going to |
| 8107 | * be enabled. | 8095 | * be enabled. |
| 8108 | */ | 8096 | */ |
| 8109 | int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, | 8097 | int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, |
| 8110 | const struct dpll *dpll) | 8098 | const struct dpll *dpll) |
| 8111 | { | 8099 | { |
| 8112 | struct intel_crtc *crtc = | 8100 | struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
| 8113 | to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe)); | ||
| 8114 | struct intel_crtc_state *pipe_config; | 8101 | struct intel_crtc_state *pipe_config; |
| 8115 | 8102 | ||
| 8116 | pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL); | 8103 | pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL); |
| @@ -8121,7 +8108,7 @@ int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, | |||
| 8121 | pipe_config->pixel_multiplier = 1; | 8108 | pipe_config->pixel_multiplier = 1; |
| 8122 | pipe_config->dpll = *dpll; | 8109 | pipe_config->dpll = *dpll; |
| 8123 | 8110 | ||
| 8124 | if (IS_CHERRYVIEW(to_i915(dev))) { | 8111 | if (IS_CHERRYVIEW(dev_priv)) { |
| 8125 | chv_compute_dpll(crtc, pipe_config); | 8112 | chv_compute_dpll(crtc, pipe_config); |
| 8126 | chv_prepare_pll(crtc, pipe_config); | 8113 | chv_prepare_pll(crtc, pipe_config); |
| 8127 | chv_enable_pll(crtc, pipe_config); | 8114 | chv_enable_pll(crtc, pipe_config); |
| @@ -8144,20 +8131,19 @@ int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, | |||
| 8144 | * Disable the PLL for @pipe. To be used in cases where we need | 8131 | * Disable the PLL for @pipe. To be used in cases where we need |
| 8145 | * the PLL enabled even when @pipe is not going to be enabled. | 8132 | * the PLL enabled even when @pipe is not going to be enabled. |
| 8146 | */ | 8133 | */ |
| 8147 | void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe) | 8134 | void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe) |
| 8148 | { | 8135 | { |
| 8149 | if (IS_CHERRYVIEW(to_i915(dev))) | 8136 | if (IS_CHERRYVIEW(dev_priv)) |
| 8150 | chv_disable_pll(to_i915(dev), pipe); | 8137 | chv_disable_pll(dev_priv, pipe); |
| 8151 | else | 8138 | else |
| 8152 | vlv_disable_pll(to_i915(dev), pipe); | 8139 | vlv_disable_pll(dev_priv, pipe); |
| 8153 | } | 8140 | } |
| 8154 | 8141 | ||
| 8155 | static void i9xx_compute_dpll(struct intel_crtc *crtc, | 8142 | static void i9xx_compute_dpll(struct intel_crtc *crtc, |
| 8156 | struct intel_crtc_state *crtc_state, | 8143 | struct intel_crtc_state *crtc_state, |
| 8157 | struct dpll *reduced_clock) | 8144 | struct dpll *reduced_clock) |
| 8158 | { | 8145 | { |
| 8159 | struct drm_device *dev = crtc->base.dev; | 8146 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
| 8160 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 8161 | u32 dpll; | 8147 | u32 dpll; |
| 8162 | struct dpll *clock = &crtc_state->dpll; | 8148 | struct dpll *clock = &crtc_state->dpll; |
| 8163 | 8149 | ||
| @@ -8183,7 +8169,7 @@ static void i9xx_compute_dpll(struct intel_crtc *crtc, | |||
| 8183 | dpll |= DPLL_SDVO_HIGH_SPEED; | 8169 | dpll |= DPLL_SDVO_HIGH_SPEED; |
| 8184 | 8170 | ||
| 8185 | /* compute bitmask from p1 value */ | 8171 | /* compute bitmask from p1 value */ |
| 8186 | if (IS_PINEVIEW(dev)) | 8172 | if (IS_PINEVIEW(dev_priv)) |
| 8187 | dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW; | 8173 | dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW; |
| 8188 | else { | 8174 | else { |
| 8189 | dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; | 8175 | dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; |
| @@ -8204,7 +8190,7 @@ static void i9xx_compute_dpll(struct intel_crtc *crtc, | |||
| 8204 | dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14; | 8190 | dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14; |
| 8205 | break; | 8191 | break; |
| 8206 | } | 8192 | } |
| 8207 | if (INTEL_INFO(dev)->gen >= 4) | 8193 | if (INTEL_GEN(dev_priv) >= 4) |
| 8208 | dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); | 8194 | dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); |
| 8209 | 8195 | ||
| 8210 | if (crtc_state->sdvo_tv_clock) | 8196 | if (crtc_state->sdvo_tv_clock) |
| @@ -8218,7 +8204,7 @@ static void i9xx_compute_dpll(struct intel_crtc *crtc, | |||
| 8218 | dpll |= DPLL_VCO_ENABLE; | 8204 | dpll |= DPLL_VCO_ENABLE; |
| 8219 | crtc_state->dpll_hw_state.dpll = dpll; | 8205 | crtc_state->dpll_hw_state.dpll = dpll; |
| 8220 | 8206 | ||
| 8221 | if (INTEL_INFO(dev)->gen >= 4) { | 8207 | if (INTEL_GEN(dev_priv) >= 4) { |
| 8222 | u32 dpll_md = (crtc_state->pixel_multiplier - 1) | 8208 | u32 dpll_md = (crtc_state->pixel_multiplier - 1) |
| 8223 | << DPLL_MD_UDI_MULTIPLIER_SHIFT; | 8209 | << DPLL_MD_UDI_MULTIPLIER_SHIFT; |
| 8224 | crtc_state->dpll_hw_state.dpll_md = dpll_md; | 8210 | crtc_state->dpll_hw_state.dpll_md = dpll_md; |
| @@ -10191,7 +10177,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv) | |||
| 10191 | } | 10177 | } |
| 10192 | 10178 | ||
| 10193 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); | 10179 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
| 10194 | intel_update_cdclk(&dev_priv->drm); | 10180 | intel_update_cdclk(dev_priv); |
| 10195 | } | 10181 | } |
| 10196 | 10182 | ||
| 10197 | /* | 10183 | /* |
| @@ -10261,6 +10247,29 @@ static void bxt_modeset_commit_cdclk(struct drm_atomic_state *old_state) | |||
| 10261 | bxt_set_cdclk(to_i915(dev), req_cdclk); | 10247 | bxt_set_cdclk(to_i915(dev), req_cdclk); |
| 10262 | } | 10248 | } |
| 10263 | 10249 | ||
| 10250 | static int bdw_adjust_min_pipe_pixel_rate(struct intel_crtc_state *crtc_state, | ||
| 10251 | int pixel_rate) | ||
| 10252 | { | ||
| 10253 | struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); | ||
| 10254 | |||
| 10255 | /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */ | ||
| 10256 | if (IS_BROADWELL(dev_priv) && crtc_state->ips_enabled) | ||
| 10257 | pixel_rate = DIV_ROUND_UP(pixel_rate * 100, 95); | ||
| 10258 | |||
| 10259 | /* BSpec says "Do not use DisplayPort with CDCLK less than | ||
| 10260 | * 432 MHz, audio enabled, port width x4, and link rate | ||
| 10261 | * HBR2 (5.4 GHz), or else there may be audio corruption or | ||
| 10262 | * screen corruption." | ||
| 10263 | */ | ||
| 10264 | if (intel_crtc_has_dp_encoder(crtc_state) && | ||
| 10265 | crtc_state->has_audio && | ||
| 10266 | crtc_state->port_clock >= 540000 && | ||
| 10267 | crtc_state->lane_count == 4) | ||
| 10268 | pixel_rate = max(432000, pixel_rate); | ||
| 10269 | |||
| 10270 | return pixel_rate; | ||
| 10271 | } | ||
| 10272 | |||
| 10264 | /* compute the max rate for new configuration */ | 10273 | /* compute the max rate for new configuration */ |
| 10265 | static int ilk_max_pixel_rate(struct drm_atomic_state *state) | 10274 | static int ilk_max_pixel_rate(struct drm_atomic_state *state) |
| 10266 | { | 10275 | { |
| @@ -10286,9 +10295,9 @@ static int ilk_max_pixel_rate(struct drm_atomic_state *state) | |||
| 10286 | 10295 | ||
| 10287 | pixel_rate = ilk_pipe_pixel_rate(crtc_state); | 10296 | pixel_rate = ilk_pipe_pixel_rate(crtc_state); |
| 10288 | 10297 | ||
| 10289 | /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */ | 10298 | if (IS_BROADWELL(dev_priv) || IS_GEN9(dev_priv)) |
| 10290 | if (IS_BROADWELL(dev_priv) && crtc_state->ips_enabled) | 10299 | pixel_rate = bdw_adjust_min_pipe_pixel_rate(crtc_state, |
| 10291 | pixel_rate = DIV_ROUND_UP(pixel_rate * 100, 95); | 10300 | pixel_rate); |
| 10292 | 10301 | ||
| 10293 | intel_state->min_pixclk[i] = pixel_rate; | 10302 | intel_state->min_pixclk[i] = pixel_rate; |
| 10294 | } | 10303 | } |
| @@ -10371,7 +10380,7 @@ static void broadwell_set_cdclk(struct drm_device *dev, int cdclk) | |||
| 10371 | 10380 | ||
| 10372 | I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1); | 10381 | I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1); |
| 10373 | 10382 | ||
| 10374 | intel_update_cdclk(dev); | 10383 | intel_update_cdclk(dev_priv); |
| 10375 | 10384 | ||
| 10376 | WARN(cdclk != dev_priv->cdclk_freq, | 10385 | WARN(cdclk != dev_priv->cdclk_freq, |
| 10377 | "cdclk requested %d kHz but got %d kHz\n", | 10386 | "cdclk requested %d kHz but got %d kHz\n", |
| @@ -10736,10 +10745,8 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, | |||
| 10736 | I915_READ(GAMMA_MODE(crtc->pipe)) & GAMMA_MODE_MODE_MASK; | 10745 | I915_READ(GAMMA_MODE(crtc->pipe)) & GAMMA_MODE_MODE_MASK; |
| 10737 | 10746 | ||
| 10738 | if (INTEL_INFO(dev)->gen >= 9) { | 10747 | if (INTEL_INFO(dev)->gen >= 9) { |
| 10739 | skl_init_scalers(dev, crtc, pipe_config); | 10748 | skl_init_scalers(dev_priv, crtc, pipe_config); |
| 10740 | } | ||
| 10741 | 10749 | ||
| 10742 | if (INTEL_INFO(dev)->gen >= 9) { | ||
| 10743 | pipe_config->scaler_state.scaler_id = -1; | 10750 | pipe_config->scaler_state.scaler_id = -1; |
| 10744 | pipe_config->scaler_state.scaler_users &= ~(1 << SKL_CRTC_INDEX); | 10751 | pipe_config->scaler_state.scaler_users &= ~(1 << SKL_CRTC_INDEX); |
| 10745 | } | 10752 | } |
| @@ -11051,7 +11058,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev, | |||
| 11051 | 11058 | ||
| 11052 | fb = intel_framebuffer_create(dev, &mode_cmd, obj); | 11059 | fb = intel_framebuffer_create(dev, &mode_cmd, obj); |
| 11053 | if (IS_ERR(fb)) | 11060 | if (IS_ERR(fb)) |
| 11054 | i915_gem_object_put_unlocked(obj); | 11061 | i915_gem_object_put(obj); |
| 11055 | 11062 | ||
| 11056 | return fb; | 11063 | return fb; |
| 11057 | } | 11064 | } |
| @@ -11136,6 +11143,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, | |||
| 11136 | struct drm_encoder *encoder = &intel_encoder->base; | 11143 | struct drm_encoder *encoder = &intel_encoder->base; |
| 11137 | struct drm_crtc *crtc = NULL; | 11144 | struct drm_crtc *crtc = NULL; |
| 11138 | struct drm_device *dev = encoder->dev; | 11145 | struct drm_device *dev = encoder->dev; |
| 11146 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 11139 | struct drm_framebuffer *fb; | 11147 | struct drm_framebuffer *fb; |
| 11140 | struct drm_mode_config *config = &dev->mode_config; | 11148 | struct drm_mode_config *config = &dev->mode_config; |
| 11141 | struct drm_atomic_state *state = NULL, *restore_state = NULL; | 11149 | struct drm_atomic_state *state = NULL, *restore_state = NULL; |
| @@ -11288,7 +11296,7 @@ found: | |||
| 11288 | old->restore_state = restore_state; | 11296 | old->restore_state = restore_state; |
| 11289 | 11297 | ||
| 11290 | /* let the connector get through one full cycle before testing */ | 11298 | /* let the connector get through one full cycle before testing */ |
| 11291 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 11299 | intel_wait_for_vblank(dev_priv, intel_crtc->pipe); |
| 11292 | return true; | 11300 | return true; |
| 11293 | 11301 | ||
| 11294 | fail: | 11302 | fail: |
| @@ -11367,7 +11375,7 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc, | |||
| 11367 | fp = pipe_config->dpll_hw_state.fp1; | 11375 | fp = pipe_config->dpll_hw_state.fp1; |
| 11368 | 11376 | ||
| 11369 | clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; | 11377 | clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; |
| 11370 | if (IS_PINEVIEW(dev)) { | 11378 | if (IS_PINEVIEW(dev_priv)) { |
| 11371 | clock.n = ffs((fp & FP_N_PINEVIEW_DIV_MASK) >> FP_N_DIV_SHIFT) - 1; | 11379 | clock.n = ffs((fp & FP_N_PINEVIEW_DIV_MASK) >> FP_N_DIV_SHIFT) - 1; |
| 11372 | clock.m2 = (fp & FP_M2_PINEVIEW_DIV_MASK) >> FP_M2_DIV_SHIFT; | 11380 | clock.m2 = (fp & FP_M2_PINEVIEW_DIV_MASK) >> FP_M2_DIV_SHIFT; |
| 11373 | } else { | 11381 | } else { |
| @@ -11376,7 +11384,7 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc, | |||
| 11376 | } | 11384 | } |
| 11377 | 11385 | ||
| 11378 | if (!IS_GEN2(dev_priv)) { | 11386 | if (!IS_GEN2(dev_priv)) { |
| 11379 | if (IS_PINEVIEW(dev)) | 11387 | if (IS_PINEVIEW(dev_priv)) |
| 11380 | clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW) >> | 11388 | clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW) >> |
| 11381 | DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW); | 11389 | DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW); |
| 11382 | else | 11390 | else |
| @@ -11398,7 +11406,7 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc, | |||
| 11398 | return; | 11406 | return; |
| 11399 | } | 11407 | } |
| 11400 | 11408 | ||
| 11401 | if (IS_PINEVIEW(dev)) | 11409 | if (IS_PINEVIEW(dev_priv)) |
| 11402 | port_clock = pnv_calc_dpll_params(refclk, &clock); | 11410 | port_clock = pnv_calc_dpll_params(refclk, &clock); |
| 11403 | else | 11411 | else |
| 11404 | port_clock = i9xx_calc_dpll_params(refclk, &clock); | 11412 | port_clock = i9xx_calc_dpll_params(refclk, &clock); |
| @@ -11667,8 +11675,7 @@ static bool pageflip_finished(struct intel_crtc *crtc, | |||
| 11667 | void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe) | 11675 | void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe) |
| 11668 | { | 11676 | { |
| 11669 | struct drm_device *dev = &dev_priv->drm; | 11677 | struct drm_device *dev = &dev_priv->drm; |
| 11670 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | 11678 | struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
| 11671 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
| 11672 | struct intel_flip_work *work; | 11679 | struct intel_flip_work *work; |
| 11673 | unsigned long flags; | 11680 | unsigned long flags; |
| 11674 | 11681 | ||
| @@ -11681,12 +11688,12 @@ void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe) | |||
| 11681 | * lost pageflips) so needs the full irqsave spinlocks. | 11688 | * lost pageflips) so needs the full irqsave spinlocks. |
| 11682 | */ | 11689 | */ |
| 11683 | spin_lock_irqsave(&dev->event_lock, flags); | 11690 | spin_lock_irqsave(&dev->event_lock, flags); |
| 11684 | work = intel_crtc->flip_work; | 11691 | work = crtc->flip_work; |
| 11685 | 11692 | ||
| 11686 | if (work != NULL && | 11693 | if (work != NULL && |
| 11687 | !is_mmio_work(work) && | 11694 | !is_mmio_work(work) && |
| 11688 | pageflip_finished(intel_crtc, work)) | 11695 | pageflip_finished(crtc, work)) |
| 11689 | page_flip_completed(intel_crtc); | 11696 | page_flip_completed(crtc); |
| 11690 | 11697 | ||
| 11691 | spin_unlock_irqrestore(&dev->event_lock, flags); | 11698 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 11692 | } | 11699 | } |
| @@ -11694,8 +11701,7 @@ void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe) | |||
| 11694 | void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe) | 11701 | void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe) |
| 11695 | { | 11702 | { |
| 11696 | struct drm_device *dev = &dev_priv->drm; | 11703 | struct drm_device *dev = &dev_priv->drm; |
| 11697 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | 11704 | struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
| 11698 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
| 11699 | struct intel_flip_work *work; | 11705 | struct intel_flip_work *work; |
| 11700 | unsigned long flags; | 11706 | unsigned long flags; |
| 11701 | 11707 | ||
| @@ -11708,12 +11714,12 @@ void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe) | |||
| 11708 | * lost pageflips) so needs the full irqsave spinlocks. | 11714 | * lost pageflips) so needs the full irqsave spinlocks. |
| 11709 | */ | 11715 | */ |
| 11710 | spin_lock_irqsave(&dev->event_lock, flags); | 11716 | spin_lock_irqsave(&dev->event_lock, flags); |
| 11711 | work = intel_crtc->flip_work; | 11717 | work = crtc->flip_work; |
| 11712 | 11718 | ||
| 11713 | if (work != NULL && | 11719 | if (work != NULL && |
| 11714 | is_mmio_work(work) && | 11720 | is_mmio_work(work) && |
| 11715 | pageflip_finished(intel_crtc, work)) | 11721 | pageflip_finished(crtc, work)) |
| 11716 | page_flip_completed(intel_crtc); | 11722 | page_flip_completed(crtc); |
| 11717 | 11723 | ||
| 11718 | spin_unlock_irqrestore(&dev->event_lock, flags); | 11724 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 11719 | } | 11725 | } |
| @@ -11967,8 +11973,6 @@ static int intel_gen7_queue_flip(struct drm_device *dev, | |||
| 11967 | static bool use_mmio_flip(struct intel_engine_cs *engine, | 11973 | static bool use_mmio_flip(struct intel_engine_cs *engine, |
| 11968 | struct drm_i915_gem_object *obj) | 11974 | struct drm_i915_gem_object *obj) |
| 11969 | { | 11975 | { |
| 11970 | struct reservation_object *resv; | ||
| 11971 | |||
| 11972 | /* | 11976 | /* |
| 11973 | * This is not being used for older platforms, because | 11977 | * This is not being used for older platforms, because |
| 11974 | * non-availability of flip done interrupt forces us to use | 11978 | * non-availability of flip done interrupt forces us to use |
| @@ -11990,12 +11994,7 @@ static bool use_mmio_flip(struct intel_engine_cs *engine, | |||
| 11990 | else if (i915.enable_execlists) | 11994 | else if (i915.enable_execlists) |
| 11991 | return true; | 11995 | return true; |
| 11992 | 11996 | ||
| 11993 | resv = i915_gem_object_get_dmabuf_resv(obj); | 11997 | return engine != i915_gem_object_last_write_engine(obj); |
| 11994 | if (resv && !reservation_object_test_signaled_rcu(resv, false)) | ||
| 11995 | return true; | ||
| 11996 | |||
| 11997 | return engine != i915_gem_active_get_engine(&obj->last_write, | ||
| 11998 | &obj->base.dev->struct_mutex); | ||
| 11999 | } | 11998 | } |
| 12000 | 11999 | ||
| 12001 | static void skl_do_mmio_flip(struct intel_crtc *intel_crtc, | 12000 | static void skl_do_mmio_flip(struct intel_crtc *intel_crtc, |
| @@ -12068,17 +12067,8 @@ static void intel_mmio_flip_work_func(struct work_struct *w) | |||
| 12068 | struct intel_framebuffer *intel_fb = | 12067 | struct intel_framebuffer *intel_fb = |
| 12069 | to_intel_framebuffer(crtc->base.primary->fb); | 12068 | to_intel_framebuffer(crtc->base.primary->fb); |
| 12070 | struct drm_i915_gem_object *obj = intel_fb->obj; | 12069 | struct drm_i915_gem_object *obj = intel_fb->obj; |
| 12071 | struct reservation_object *resv; | ||
| 12072 | 12070 | ||
| 12073 | if (work->flip_queued_req) | 12071 | WARN_ON(i915_gem_object_wait(obj, 0, MAX_SCHEDULE_TIMEOUT, NULL) < 0); |
| 12074 | WARN_ON(i915_wait_request(work->flip_queued_req, | ||
| 12075 | 0, NULL, NO_WAITBOOST)); | ||
| 12076 | |||
| 12077 | /* For framebuffer backed by dmabuf, wait for fence */ | ||
| 12078 | resv = i915_gem_object_get_dmabuf_resv(obj); | ||
| 12079 | if (resv) | ||
| 12080 | WARN_ON(reservation_object_wait_timeout_rcu(resv, false, false, | ||
| 12081 | MAX_SCHEDULE_TIMEOUT) < 0); | ||
| 12082 | 12072 | ||
| 12083 | intel_pipe_update_start(crtc); | 12073 | intel_pipe_update_start(crtc); |
| 12084 | 12074 | ||
| @@ -12141,8 +12131,7 @@ static bool __pageflip_stall_check_cs(struct drm_i915_private *dev_priv, | |||
| 12141 | void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe) | 12131 | void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe) |
| 12142 | { | 12132 | { |
| 12143 | struct drm_device *dev = &dev_priv->drm; | 12133 | struct drm_device *dev = &dev_priv->drm; |
| 12144 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | 12134 | struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
| 12145 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
| 12146 | struct intel_flip_work *work; | 12135 | struct intel_flip_work *work; |
| 12147 | 12136 | ||
| 12148 | WARN_ON(!in_interrupt()); | 12137 | WARN_ON(!in_interrupt()); |
| @@ -12151,19 +12140,19 @@ void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe) | |||
| 12151 | return; | 12140 | return; |
| 12152 | 12141 | ||
| 12153 | spin_lock(&dev->event_lock); | 12142 | spin_lock(&dev->event_lock); |
| 12154 | work = intel_crtc->flip_work; | 12143 | work = crtc->flip_work; |
| 12155 | 12144 | ||
| 12156 | if (work != NULL && !is_mmio_work(work) && | 12145 | if (work != NULL && !is_mmio_work(work) && |
| 12157 | __pageflip_stall_check_cs(dev_priv, intel_crtc, work)) { | 12146 | __pageflip_stall_check_cs(dev_priv, crtc, work)) { |
| 12158 | WARN_ONCE(1, | 12147 | WARN_ONCE(1, |
| 12159 | "Kicking stuck page flip: queued at %d, now %d\n", | 12148 | "Kicking stuck page flip: queued at %d, now %d\n", |
| 12160 | work->flip_queued_vblank, intel_crtc_get_vblank_counter(intel_crtc)); | 12149 | work->flip_queued_vblank, intel_crtc_get_vblank_counter(crtc)); |
| 12161 | page_flip_completed(intel_crtc); | 12150 | page_flip_completed(crtc); |
| 12162 | work = NULL; | 12151 | work = NULL; |
| 12163 | } | 12152 | } |
| 12164 | 12153 | ||
| 12165 | if (work != NULL && !is_mmio_work(work) && | 12154 | if (work != NULL && !is_mmio_work(work) && |
| 12166 | intel_crtc_get_vblank_counter(intel_crtc) - work->flip_queued_vblank > 1) | 12155 | intel_crtc_get_vblank_counter(crtc) - work->flip_queued_vblank > 1) |
| 12167 | intel_queue_rps_boost_for_request(work->flip_queued_req); | 12156 | intel_queue_rps_boost_for_request(work->flip_queued_req); |
| 12168 | spin_unlock(&dev->event_lock); | 12157 | spin_unlock(&dev->event_lock); |
| 12169 | } | 12158 | } |
| @@ -12279,8 +12268,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
| 12279 | } else if (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)) { | 12268 | } else if (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)) { |
| 12280 | engine = dev_priv->engine[BCS]; | 12269 | engine = dev_priv->engine[BCS]; |
| 12281 | } else if (INTEL_INFO(dev)->gen >= 7) { | 12270 | } else if (INTEL_INFO(dev)->gen >= 7) { |
| 12282 | engine = i915_gem_active_get_engine(&obj->last_write, | 12271 | engine = i915_gem_object_last_write_engine(obj); |
| 12283 | &obj->base.dev->struct_mutex); | ||
| 12284 | if (engine == NULL || engine->id != RCS) | 12272 | if (engine == NULL || engine->id != RCS) |
| 12285 | engine = dev_priv->engine[BCS]; | 12273 | engine = dev_priv->engine[BCS]; |
| 12286 | } else { | 12274 | } else { |
| @@ -12312,9 +12300,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
| 12312 | 12300 | ||
| 12313 | if (mmio_flip) { | 12301 | if (mmio_flip) { |
| 12314 | INIT_WORK(&work->mmio_work, intel_mmio_flip_work_func); | 12302 | INIT_WORK(&work->mmio_work, intel_mmio_flip_work_func); |
| 12315 | |||
| 12316 | work->flip_queued_req = i915_gem_active_get(&obj->last_write, | ||
| 12317 | &obj->base.dev->struct_mutex); | ||
| 12318 | queue_work(system_unbound_wq, &work->mmio_work); | 12303 | queue_work(system_unbound_wq, &work->mmio_work); |
| 12319 | } else { | 12304 | } else { |
| 12320 | request = i915_gem_request_alloc(engine, engine->last_context); | 12305 | request = i915_gem_request_alloc(engine, engine->last_context); |
| @@ -12360,7 +12345,7 @@ cleanup: | |||
| 12360 | crtc->primary->fb = old_fb; | 12345 | crtc->primary->fb = old_fb; |
| 12361 | update_state_fb(crtc->primary); | 12346 | update_state_fb(crtc->primary); |
| 12362 | 12347 | ||
| 12363 | i915_gem_object_put_unlocked(obj); | 12348 | i915_gem_object_put(obj); |
| 12364 | drm_framebuffer_unreference(work->old_fb); | 12349 | drm_framebuffer_unreference(work->old_fb); |
| 12365 | 12350 | ||
| 12366 | spin_lock_irq(&dev->event_lock); | 12351 | spin_lock_irq(&dev->event_lock); |
| @@ -13479,13 +13464,13 @@ static void verify_wm_state(struct drm_crtc *crtc, | |||
| 13479 | return; | 13464 | return; |
| 13480 | 13465 | ||
| 13481 | skl_pipe_wm_get_hw_state(crtc, &hw_wm); | 13466 | skl_pipe_wm_get_hw_state(crtc, &hw_wm); |
| 13482 | sw_wm = &intel_crtc->wm.active.skl; | 13467 | sw_wm = &to_intel_crtc_state(new_state)->wm.skl.optimal; |
| 13483 | 13468 | ||
| 13484 | skl_ddb_get_hw_state(dev_priv, &hw_ddb); | 13469 | skl_ddb_get_hw_state(dev_priv, &hw_ddb); |
| 13485 | sw_ddb = &dev_priv->wm.skl_hw.ddb; | 13470 | sw_ddb = &dev_priv->wm.skl_hw.ddb; |
| 13486 | 13471 | ||
| 13487 | /* planes */ | 13472 | /* planes */ |
| 13488 | for_each_plane(dev_priv, pipe, plane) { | 13473 | for_each_universal_plane(dev_priv, pipe, plane) { |
| 13489 | hw_plane_wm = &hw_wm.planes[plane]; | 13474 | hw_plane_wm = &hw_wm.planes[plane]; |
| 13490 | sw_plane_wm = &sw_wm->planes[plane]; | 13475 | sw_plane_wm = &sw_wm->planes[plane]; |
| 13491 | 13476 | ||
| @@ -14154,13 +14139,10 @@ static int intel_atomic_check(struct drm_device *dev, | |||
| 14154 | } | 14139 | } |
| 14155 | 14140 | ||
| 14156 | static int intel_atomic_prepare_commit(struct drm_device *dev, | 14141 | static int intel_atomic_prepare_commit(struct drm_device *dev, |
| 14157 | struct drm_atomic_state *state, | 14142 | struct drm_atomic_state *state) |
| 14158 | bool nonblock) | ||
| 14159 | { | 14143 | { |
| 14160 | struct drm_i915_private *dev_priv = to_i915(dev); | 14144 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 14161 | struct drm_plane_state *plane_state; | ||
| 14162 | struct drm_crtc_state *crtc_state; | 14145 | struct drm_crtc_state *crtc_state; |
| 14163 | struct drm_plane *plane; | ||
| 14164 | struct drm_crtc *crtc; | 14146 | struct drm_crtc *crtc; |
| 14165 | int i, ret; | 14147 | int i, ret; |
| 14166 | 14148 | ||
| @@ -14183,28 +14165,6 @@ static int intel_atomic_prepare_commit(struct drm_device *dev, | |||
| 14183 | ret = drm_atomic_helper_prepare_planes(dev, state); | 14165 | ret = drm_atomic_helper_prepare_planes(dev, state); |
| 14184 | mutex_unlock(&dev->struct_mutex); | 14166 | mutex_unlock(&dev->struct_mutex); |
| 14185 | 14167 | ||
| 14186 | if (!ret && !nonblock) { | ||
| 14187 | for_each_plane_in_state(state, plane, plane_state, i) { | ||
| 14188 | struct intel_plane_state *intel_plane_state = | ||
| 14189 | to_intel_plane_state(plane_state); | ||
| 14190 | |||
| 14191 | if (!intel_plane_state->wait_req) | ||
| 14192 | continue; | ||
| 14193 | |||
| 14194 | ret = i915_wait_request(intel_plane_state->wait_req, | ||
| 14195 | I915_WAIT_INTERRUPTIBLE, | ||
| 14196 | NULL, NULL); | ||
| 14197 | if (ret) { | ||
| 14198 | /* Any hang should be swallowed by the wait */ | ||
| 14199 | WARN_ON(ret == -EIO); | ||
| 14200 | mutex_lock(&dev->struct_mutex); | ||
| 14201 | drm_atomic_helper_cleanup_planes(dev, state); | ||
| 14202 | mutex_unlock(&dev->struct_mutex); | ||
| 14203 | break; | ||
| 14204 | } | ||
| 14205 | } | ||
| 14206 | } | ||
| 14207 | |||
| 14208 | return ret; | 14168 | return ret; |
| 14209 | } | 14169 | } |
| 14210 | 14170 | ||
| @@ -14230,22 +14190,24 @@ static void intel_atomic_wait_for_vblanks(struct drm_device *dev, | |||
| 14230 | return; | 14190 | return; |
| 14231 | 14191 | ||
| 14232 | for_each_pipe(dev_priv, pipe) { | 14192 | for_each_pipe(dev_priv, pipe) { |
| 14233 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | 14193 | struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, |
| 14194 | pipe); | ||
| 14234 | 14195 | ||
| 14235 | if (!((1 << pipe) & crtc_mask)) | 14196 | if (!((1 << pipe) & crtc_mask)) |
| 14236 | continue; | 14197 | continue; |
| 14237 | 14198 | ||
| 14238 | ret = drm_crtc_vblank_get(crtc); | 14199 | ret = drm_crtc_vblank_get(&crtc->base); |
| 14239 | if (WARN_ON(ret != 0)) { | 14200 | if (WARN_ON(ret != 0)) { |
| 14240 | crtc_mask &= ~(1 << pipe); | 14201 | crtc_mask &= ~(1 << pipe); |
| 14241 | continue; | 14202 | continue; |
| 14242 | } | 14203 | } |
| 14243 | 14204 | ||
| 14244 | last_vblank_count[pipe] = drm_crtc_vblank_count(crtc); | 14205 | last_vblank_count[pipe] = drm_crtc_vblank_count(&crtc->base); |
| 14245 | } | 14206 | } |
| 14246 | 14207 | ||
| 14247 | for_each_pipe(dev_priv, pipe) { | 14208 | for_each_pipe(dev_priv, pipe) { |
| 14248 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | 14209 | struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, |
| 14210 | pipe); | ||
| 14249 | long lret; | 14211 | long lret; |
| 14250 | 14212 | ||
| 14251 | if (!((1 << pipe) & crtc_mask)) | 14213 | if (!((1 << pipe) & crtc_mask)) |
| @@ -14253,12 +14215,12 @@ static void intel_atomic_wait_for_vblanks(struct drm_device *dev, | |||
| 14253 | 14215 | ||
| 14254 | lret = wait_event_timeout(dev->vblank[pipe].queue, | 14216 | lret = wait_event_timeout(dev->vblank[pipe].queue, |
| 14255 | last_vblank_count[pipe] != | 14217 | last_vblank_count[pipe] != |
| 14256 | drm_crtc_vblank_count(crtc), | 14218 | drm_crtc_vblank_count(&crtc->base), |
| 14257 | msecs_to_jiffies(50)); | 14219 | msecs_to_jiffies(50)); |
| 14258 | 14220 | ||
| 14259 | WARN(!lret, "pipe %c vblank wait timed out\n", pipe_name(pipe)); | 14221 | WARN(!lret, "pipe %c vblank wait timed out\n", pipe_name(pipe)); |
| 14260 | 14222 | ||
| 14261 | drm_crtc_vblank_put(crtc); | 14223 | drm_crtc_vblank_put(&crtc->base); |
| 14262 | } | 14224 | } |
| 14263 | } | 14225 | } |
| 14264 | 14226 | ||
| @@ -14332,7 +14294,7 @@ static void intel_update_crtcs(struct drm_atomic_state *state, | |||
| 14332 | static void skl_update_crtcs(struct drm_atomic_state *state, | 14294 | static void skl_update_crtcs(struct drm_atomic_state *state, |
| 14333 | unsigned int *crtc_vblank_mask) | 14295 | unsigned int *crtc_vblank_mask) |
| 14334 | { | 14296 | { |
| 14335 | struct drm_device *dev = state->dev; | 14297 | struct drm_i915_private *dev_priv = to_i915(state->dev); |
| 14336 | struct intel_atomic_state *intel_state = to_intel_atomic_state(state); | 14298 | struct intel_atomic_state *intel_state = to_intel_atomic_state(state); |
| 14337 | struct drm_crtc *crtc; | 14299 | struct drm_crtc *crtc; |
| 14338 | struct intel_crtc *intel_crtc; | 14300 | struct intel_crtc *intel_crtc; |
| @@ -14383,7 +14345,7 @@ static void skl_update_crtcs(struct drm_atomic_state *state, | |||
| 14383 | crtc_vblank_mask); | 14345 | crtc_vblank_mask); |
| 14384 | 14346 | ||
| 14385 | if (vbl_wait) | 14347 | if (vbl_wait) |
| 14386 | intel_wait_for_vblank(dev, pipe); | 14348 | intel_wait_for_vblank(dev_priv, pipe); |
| 14387 | 14349 | ||
| 14388 | progress = true; | 14350 | progress = true; |
| 14389 | } | 14351 | } |
| @@ -14398,26 +14360,10 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) | |||
| 14398 | struct drm_crtc_state *old_crtc_state; | 14360 | struct drm_crtc_state *old_crtc_state; |
| 14399 | struct drm_crtc *crtc; | 14361 | struct drm_crtc *crtc; |
| 14400 | struct intel_crtc_state *intel_cstate; | 14362 | struct intel_crtc_state *intel_cstate; |
| 14401 | struct drm_plane *plane; | ||
| 14402 | struct drm_plane_state *plane_state; | ||
| 14403 | bool hw_check = intel_state->modeset; | 14363 | bool hw_check = intel_state->modeset; |
| 14404 | unsigned long put_domains[I915_MAX_PIPES] = {}; | 14364 | unsigned long put_domains[I915_MAX_PIPES] = {}; |
| 14405 | unsigned crtc_vblank_mask = 0; | 14365 | unsigned crtc_vblank_mask = 0; |
| 14406 | int i, ret; | 14366 | int i; |
| 14407 | |||
| 14408 | for_each_plane_in_state(state, plane, plane_state, i) { | ||
| 14409 | struct intel_plane_state *intel_plane_state = | ||
| 14410 | to_intel_plane_state(plane->state); | ||
| 14411 | |||
| 14412 | if (!intel_plane_state->wait_req) | ||
| 14413 | continue; | ||
| 14414 | |||
| 14415 | ret = i915_wait_request(intel_plane_state->wait_req, | ||
| 14416 | 0, NULL, NULL); | ||
| 14417 | /* EIO should be eaten, and we can't get interrupted in the | ||
| 14418 | * worker, and blocking commits have waited already. */ | ||
| 14419 | WARN_ON(ret); | ||
| 14420 | } | ||
| 14421 | 14367 | ||
| 14422 | drm_atomic_helper_wait_for_dependencies(state); | 14368 | drm_atomic_helper_wait_for_dependencies(state); |
| 14423 | 14369 | ||
| @@ -14462,7 +14408,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) | |||
| 14462 | intel_check_pch_fifo_underruns(dev_priv); | 14408 | intel_check_pch_fifo_underruns(dev_priv); |
| 14463 | 14409 | ||
| 14464 | if (!crtc->state->active) | 14410 | if (!crtc->state->active) |
| 14465 | intel_update_watermarks(crtc); | 14411 | intel_update_watermarks(intel_crtc); |
| 14466 | } | 14412 | } |
| 14467 | } | 14413 | } |
| 14468 | 14414 | ||
| @@ -14572,12 +14518,33 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) | |||
| 14572 | 14518 | ||
| 14573 | static void intel_atomic_commit_work(struct work_struct *work) | 14519 | static void intel_atomic_commit_work(struct work_struct *work) |
| 14574 | { | 14520 | { |
| 14575 | struct drm_atomic_state *state = container_of(work, | 14521 | struct drm_atomic_state *state = |
| 14576 | struct drm_atomic_state, | 14522 | container_of(work, struct drm_atomic_state, commit_work); |
| 14577 | commit_work); | 14523 | |
| 14578 | intel_atomic_commit_tail(state); | 14524 | intel_atomic_commit_tail(state); |
| 14579 | } | 14525 | } |
| 14580 | 14526 | ||
| 14527 | static int __i915_sw_fence_call | ||
| 14528 | intel_atomic_commit_ready(struct i915_sw_fence *fence, | ||
| 14529 | enum i915_sw_fence_notify notify) | ||
| 14530 | { | ||
| 14531 | struct intel_atomic_state *state = | ||
| 14532 | container_of(fence, struct intel_atomic_state, commit_ready); | ||
| 14533 | |||
| 14534 | switch (notify) { | ||
| 14535 | case FENCE_COMPLETE: | ||
| 14536 | if (state->base.commit_work.func) | ||
| 14537 | queue_work(system_unbound_wq, &state->base.commit_work); | ||
| 14538 | break; | ||
| 14539 | |||
| 14540 | case FENCE_FREE: | ||
| 14541 | drm_atomic_state_put(&state->base); | ||
| 14542 | break; | ||
| 14543 | } | ||
| 14544 | |||
| 14545 | return NOTIFY_DONE; | ||
| 14546 | } | ||
| 14547 | |||
| 14581 | static void intel_atomic_track_fbs(struct drm_atomic_state *state) | 14548 | static void intel_atomic_track_fbs(struct drm_atomic_state *state) |
| 14582 | { | 14549 | { |
| 14583 | struct drm_plane_state *old_plane_state; | 14550 | struct drm_plane_state *old_plane_state; |
| @@ -14623,11 +14590,14 @@ static int intel_atomic_commit(struct drm_device *dev, | |||
| 14623 | if (ret) | 14590 | if (ret) |
| 14624 | return ret; | 14591 | return ret; |
| 14625 | 14592 | ||
| 14626 | INIT_WORK(&state->commit_work, intel_atomic_commit_work); | 14593 | drm_atomic_state_get(state); |
| 14594 | i915_sw_fence_init(&intel_state->commit_ready, | ||
| 14595 | intel_atomic_commit_ready); | ||
| 14627 | 14596 | ||
| 14628 | ret = intel_atomic_prepare_commit(dev, state, nonblock); | 14597 | ret = intel_atomic_prepare_commit(dev, state); |
| 14629 | if (ret) { | 14598 | if (ret) { |
| 14630 | DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret); | 14599 | DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret); |
| 14600 | i915_sw_fence_commit(&intel_state->commit_ready); | ||
| 14631 | return ret; | 14601 | return ret; |
| 14632 | } | 14602 | } |
| 14633 | 14603 | ||
| @@ -14638,10 +14608,14 @@ static int intel_atomic_commit(struct drm_device *dev, | |||
| 14638 | intel_atomic_track_fbs(state); | 14608 | intel_atomic_track_fbs(state); |
| 14639 | 14609 | ||
| 14640 | drm_atomic_state_get(state); | 14610 | drm_atomic_state_get(state); |
| 14641 | if (nonblock) | 14611 | INIT_WORK(&state->commit_work, |
| 14642 | queue_work(system_unbound_wq, &state->commit_work); | 14612 | nonblock ? intel_atomic_commit_work : NULL); |
| 14643 | else | 14613 | |
| 14614 | i915_sw_fence_commit(&intel_state->commit_ready); | ||
| 14615 | if (!nonblock) { | ||
| 14616 | i915_sw_fence_wait(&intel_state->commit_ready); | ||
| 14644 | intel_atomic_commit_tail(state); | 14617 | intel_atomic_commit_tail(state); |
| 14618 | } | ||
| 14645 | 14619 | ||
| 14646 | return 0; | 14620 | return 0; |
| 14647 | } | 14621 | } |
| @@ -14753,20 +14727,22 @@ int | |||
| 14753 | intel_prepare_plane_fb(struct drm_plane *plane, | 14727 | intel_prepare_plane_fb(struct drm_plane *plane, |
| 14754 | struct drm_plane_state *new_state) | 14728 | struct drm_plane_state *new_state) |
| 14755 | { | 14729 | { |
| 14730 | struct intel_atomic_state *intel_state = | ||
| 14731 | to_intel_atomic_state(new_state->state); | ||
| 14756 | struct drm_device *dev = plane->dev; | 14732 | struct drm_device *dev = plane->dev; |
| 14757 | struct drm_i915_private *dev_priv = to_i915(dev); | 14733 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 14758 | struct drm_framebuffer *fb = new_state->fb; | 14734 | struct drm_framebuffer *fb = new_state->fb; |
| 14759 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); | 14735 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); |
| 14760 | struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->state->fb); | 14736 | struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->state->fb); |
| 14761 | struct reservation_object *resv; | 14737 | int ret; |
| 14762 | int ret = 0; | ||
| 14763 | 14738 | ||
| 14764 | if (!obj && !old_obj) | 14739 | if (!obj && !old_obj) |
| 14765 | return 0; | 14740 | return 0; |
| 14766 | 14741 | ||
| 14767 | if (old_obj) { | 14742 | if (old_obj) { |
| 14768 | struct drm_crtc_state *crtc_state = | 14743 | struct drm_crtc_state *crtc_state = |
| 14769 | drm_atomic_get_existing_crtc_state(new_state->state, plane->state->crtc); | 14744 | drm_atomic_get_existing_crtc_state(new_state->state, |
| 14745 | plane->state->crtc); | ||
| 14770 | 14746 | ||
| 14771 | /* Big Hammer, we also need to ensure that any pending | 14747 | /* Big Hammer, we also need to ensure that any pending |
| 14772 | * MI_WAIT_FOR_EVENT inside a user batch buffer on the | 14748 | * MI_WAIT_FOR_EVENT inside a user batch buffer on the |
| @@ -14779,52 +14755,56 @@ intel_prepare_plane_fb(struct drm_plane *plane, | |||
| 14779 | * This should only fail upon a hung GPU, in which case we | 14755 | * This should only fail upon a hung GPU, in which case we |
| 14780 | * can safely continue. | 14756 | * can safely continue. |
| 14781 | */ | 14757 | */ |
| 14782 | if (needs_modeset(crtc_state)) | 14758 | if (needs_modeset(crtc_state)) { |
| 14783 | ret = i915_gem_object_wait_rendering(old_obj, true); | 14759 | ret = i915_sw_fence_await_reservation(&intel_state->commit_ready, |
| 14784 | if (ret) { | 14760 | old_obj->resv, NULL, |
| 14785 | /* GPU hangs should have been swallowed by the wait */ | 14761 | false, 0, |
| 14786 | WARN_ON(ret == -EIO); | 14762 | GFP_KERNEL); |
| 14787 | return ret; | 14763 | if (ret < 0) |
| 14764 | return ret; | ||
| 14788 | } | 14765 | } |
| 14789 | } | 14766 | } |
| 14790 | 14767 | ||
| 14768 | if (new_state->fence) { /* explicit fencing */ | ||
| 14769 | ret = i915_sw_fence_await_dma_fence(&intel_state->commit_ready, | ||
| 14770 | new_state->fence, | ||
| 14771 | I915_FENCE_TIMEOUT, | ||
| 14772 | GFP_KERNEL); | ||
| 14773 | if (ret < 0) | ||
| 14774 | return ret; | ||
| 14775 | } | ||
| 14776 | |||
| 14791 | if (!obj) | 14777 | if (!obj) |
| 14792 | return 0; | 14778 | return 0; |
| 14793 | 14779 | ||
| 14794 | /* For framebuffer backed by dmabuf, wait for fence */ | 14780 | if (!new_state->fence) { /* implicit fencing */ |
| 14795 | resv = i915_gem_object_get_dmabuf_resv(obj); | 14781 | ret = i915_sw_fence_await_reservation(&intel_state->commit_ready, |
| 14796 | if (resv) { | 14782 | obj->resv, NULL, |
| 14797 | long lret; | 14783 | false, I915_FENCE_TIMEOUT, |
| 14798 | 14784 | GFP_KERNEL); | |
| 14799 | lret = reservation_object_wait_timeout_rcu(resv, false, true, | 14785 | if (ret < 0) |
| 14800 | MAX_SCHEDULE_TIMEOUT); | 14786 | return ret; |
| 14801 | if (lret == -ERESTARTSYS) | ||
| 14802 | return lret; | ||
| 14803 | |||
| 14804 | WARN(lret < 0, "waiting returns %li\n", lret); | ||
| 14805 | } | 14787 | } |
| 14806 | 14788 | ||
| 14807 | if (plane->type == DRM_PLANE_TYPE_CURSOR && | 14789 | if (plane->type == DRM_PLANE_TYPE_CURSOR && |
| 14808 | INTEL_INFO(dev)->cursor_needs_physical) { | 14790 | INTEL_INFO(dev)->cursor_needs_physical) { |
| 14809 | int align = IS_I830(dev_priv) ? 16 * 1024 : 256; | 14791 | int align = IS_I830(dev_priv) ? 16 * 1024 : 256; |
| 14810 | ret = i915_gem_object_attach_phys(obj, align); | 14792 | ret = i915_gem_object_attach_phys(obj, align); |
| 14811 | if (ret) | 14793 | if (ret) { |
| 14812 | DRM_DEBUG_KMS("failed to attach phys object\n"); | 14794 | DRM_DEBUG_KMS("failed to attach phys object\n"); |
| 14795 | return ret; | ||
| 14796 | } | ||
| 14813 | } else { | 14797 | } else { |
| 14814 | struct i915_vma *vma; | 14798 | struct i915_vma *vma; |
| 14815 | 14799 | ||
| 14816 | vma = intel_pin_and_fence_fb_obj(fb, new_state->rotation); | 14800 | vma = intel_pin_and_fence_fb_obj(fb, new_state->rotation); |
| 14817 | if (IS_ERR(vma)) | 14801 | if (IS_ERR(vma)) { |
| 14818 | ret = PTR_ERR(vma); | 14802 | DRM_DEBUG_KMS("failed to pin object\n"); |
| 14819 | } | 14803 | return PTR_ERR(vma); |
| 14820 | 14804 | } | |
| 14821 | if (ret == 0) { | ||
| 14822 | to_intel_plane_state(new_state)->wait_req = | ||
| 14823 | i915_gem_active_get(&obj->last_write, | ||
| 14824 | &obj->base.dev->struct_mutex); | ||
| 14825 | } | 14805 | } |
| 14826 | 14806 | ||
| 14827 | return ret; | 14807 | return 0; |
| 14828 | } | 14808 | } |
| 14829 | 14809 | ||
| 14830 | /** | 14810 | /** |
| @@ -14842,7 +14822,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane, | |||
| 14842 | { | 14822 | { |
| 14843 | struct drm_device *dev = plane->dev; | 14823 | struct drm_device *dev = plane->dev; |
| 14844 | struct intel_plane_state *old_intel_state; | 14824 | struct intel_plane_state *old_intel_state; |
| 14845 | struct intel_plane_state *intel_state = to_intel_plane_state(plane->state); | ||
| 14846 | struct drm_i915_gem_object *old_obj = intel_fb_obj(old_state->fb); | 14825 | struct drm_i915_gem_object *old_obj = intel_fb_obj(old_state->fb); |
| 14847 | struct drm_i915_gem_object *obj = intel_fb_obj(plane->state->fb); | 14826 | struct drm_i915_gem_object *obj = intel_fb_obj(plane->state->fb); |
| 14848 | 14827 | ||
| @@ -14854,9 +14833,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane, | |||
| 14854 | if (old_obj && (plane->type != DRM_PLANE_TYPE_CURSOR || | 14833 | if (old_obj && (plane->type != DRM_PLANE_TYPE_CURSOR || |
| 14855 | !INTEL_INFO(dev)->cursor_needs_physical)) | 14834 | !INTEL_INFO(dev)->cursor_needs_physical)) |
| 14856 | intel_unpin_fb_obj(old_state->fb, old_state->rotation); | 14835 | intel_unpin_fb_obj(old_state->fb, old_state->rotation); |
| 14857 | |||
| 14858 | i915_gem_request_assign(&intel_state->wait_req, NULL); | ||
| 14859 | i915_gem_request_assign(&old_intel_state->wait_req, NULL); | ||
| 14860 | } | 14836 | } |
| 14861 | 14837 | ||
| 14862 | int | 14838 | int |
| @@ -14976,9 +14952,6 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc, | |||
| 14976 | */ | 14952 | */ |
| 14977 | void intel_plane_destroy(struct drm_plane *plane) | 14953 | void intel_plane_destroy(struct drm_plane *plane) |
| 14978 | { | 14954 | { |
| 14979 | if (!plane) | ||
| 14980 | return; | ||
| 14981 | |||
| 14982 | drm_plane_cleanup(plane); | 14955 | drm_plane_cleanup(plane); |
| 14983 | kfree(to_intel_plane(plane)); | 14956 | kfree(to_intel_plane(plane)); |
| 14984 | } | 14957 | } |
| @@ -14992,13 +14965,11 @@ const struct drm_plane_funcs intel_plane_funcs = { | |||
| 14992 | .atomic_set_property = intel_plane_atomic_set_property, | 14965 | .atomic_set_property = intel_plane_atomic_set_property, |
| 14993 | .atomic_duplicate_state = intel_plane_duplicate_state, | 14966 | .atomic_duplicate_state = intel_plane_duplicate_state, |
| 14994 | .atomic_destroy_state = intel_plane_destroy_state, | 14967 | .atomic_destroy_state = intel_plane_destroy_state, |
| 14995 | |||
| 14996 | }; | 14968 | }; |
| 14997 | 14969 | ||
| 14998 | static struct drm_plane *intel_primary_plane_create(struct drm_device *dev, | 14970 | static struct intel_plane * |
| 14999 | int pipe) | 14971 | intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) |
| 15000 | { | 14972 | { |
| 15001 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 15002 | struct intel_plane *primary = NULL; | 14973 | struct intel_plane *primary = NULL; |
| 15003 | struct intel_plane_state *state = NULL; | 14974 | struct intel_plane_state *state = NULL; |
| 15004 | const uint32_t *intel_primary_formats; | 14975 | const uint32_t *intel_primary_formats; |
| @@ -15007,17 +14978,22 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev, | |||
| 15007 | int ret; | 14978 | int ret; |
| 15008 | 14979 | ||
| 15009 | primary = kzalloc(sizeof(*primary), GFP_KERNEL); | 14980 | primary = kzalloc(sizeof(*primary), GFP_KERNEL); |
| 15010 | if (!primary) | 14981 | if (!primary) { |
| 14982 | ret = -ENOMEM; | ||
| 15011 | goto fail; | 14983 | goto fail; |
| 14984 | } | ||
| 15012 | 14985 | ||
| 15013 | state = intel_create_plane_state(&primary->base); | 14986 | state = intel_create_plane_state(&primary->base); |
| 15014 | if (!state) | 14987 | if (!state) { |
| 14988 | ret = -ENOMEM; | ||
| 15015 | goto fail; | 14989 | goto fail; |
| 14990 | } | ||
| 14991 | |||
| 15016 | primary->base.state = &state->base; | 14992 | primary->base.state = &state->base; |
| 15017 | 14993 | ||
| 15018 | primary->can_scale = false; | 14994 | primary->can_scale = false; |
| 15019 | primary->max_downscale = 1; | 14995 | primary->max_downscale = 1; |
| 15020 | if (INTEL_INFO(dev)->gen >= 9) { | 14996 | if (INTEL_GEN(dev_priv) >= 9) { |
| 15021 | primary->can_scale = true; | 14997 | primary->can_scale = true; |
| 15022 | state->scaler_id = -1; | 14998 | state->scaler_id = -1; |
| 15023 | } | 14999 | } |
| @@ -15025,10 +15001,10 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev, | |||
| 15025 | primary->plane = pipe; | 15001 | primary->plane = pipe; |
| 15026 | primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe); | 15002 | primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe); |
| 15027 | primary->check_plane = intel_check_primary_plane; | 15003 | primary->check_plane = intel_check_primary_plane; |
| 15028 | if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4) | 15004 | if (HAS_FBC(dev_priv) && INTEL_GEN(dev_priv) < 4) |
| 15029 | primary->plane = !pipe; | 15005 | primary->plane = !pipe; |
| 15030 | 15006 | ||
| 15031 | if (INTEL_INFO(dev)->gen >= 9) { | 15007 | if (INTEL_GEN(dev_priv) >= 9) { |
| 15032 | intel_primary_formats = skl_primary_formats; | 15008 | intel_primary_formats = skl_primary_formats; |
| 15033 | num_formats = ARRAY_SIZE(skl_primary_formats); | 15009 | num_formats = ARRAY_SIZE(skl_primary_formats); |
| 15034 | 15010 | ||
| @@ -15040,7 +15016,7 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev, | |||
| 15040 | 15016 | ||
| 15041 | primary->update_plane = ironlake_update_primary_plane; | 15017 | primary->update_plane = ironlake_update_primary_plane; |
| 15042 | primary->disable_plane = i9xx_disable_primary_plane; | 15018 | primary->disable_plane = i9xx_disable_primary_plane; |
| 15043 | } else if (INTEL_INFO(dev)->gen >= 4) { | 15019 | } else if (INTEL_GEN(dev_priv) >= 4) { |
| 15044 | intel_primary_formats = i965_primary_formats; | 15020 | intel_primary_formats = i965_primary_formats; |
| 15045 | num_formats = ARRAY_SIZE(i965_primary_formats); | 15021 | num_formats = ARRAY_SIZE(i965_primary_formats); |
| 15046 | 15022 | ||
| @@ -15054,21 +15030,21 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev, | |||
| 15054 | primary->disable_plane = i9xx_disable_primary_plane; | 15030 | primary->disable_plane = i9xx_disable_primary_plane; |
| 15055 | } | 15031 | } |
| 15056 | 15032 | ||
| 15057 | if (INTEL_INFO(dev)->gen >= 9) | 15033 | if (INTEL_GEN(dev_priv) >= 9) |
| 15058 | ret = drm_universal_plane_init(dev, &primary->base, 0, | 15034 | ret = drm_universal_plane_init(&dev_priv->drm, &primary->base, |
| 15059 | &intel_plane_funcs, | 15035 | 0, &intel_plane_funcs, |
| 15060 | intel_primary_formats, num_formats, | 15036 | intel_primary_formats, num_formats, |
| 15061 | DRM_PLANE_TYPE_PRIMARY, | 15037 | DRM_PLANE_TYPE_PRIMARY, |
| 15062 | "plane 1%c", pipe_name(pipe)); | 15038 | "plane 1%c", pipe_name(pipe)); |
| 15063 | else if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) | 15039 | else if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) |
| 15064 | ret = drm_universal_plane_init(dev, &primary->base, 0, | 15040 | ret = drm_universal_plane_init(&dev_priv->drm, &primary->base, |
| 15065 | &intel_plane_funcs, | 15041 | 0, &intel_plane_funcs, |
| 15066 | intel_primary_formats, num_formats, | 15042 | intel_primary_formats, num_formats, |
| 15067 | DRM_PLANE_TYPE_PRIMARY, | 15043 | DRM_PLANE_TYPE_PRIMARY, |
| 15068 | "primary %c", pipe_name(pipe)); | 15044 | "primary %c", pipe_name(pipe)); |
| 15069 | else | 15045 | else |
| 15070 | ret = drm_universal_plane_init(dev, &primary->base, 0, | 15046 | ret = drm_universal_plane_init(&dev_priv->drm, &primary->base, |
| 15071 | &intel_plane_funcs, | 15047 | 0, &intel_plane_funcs, |
| 15072 | intel_primary_formats, num_formats, | 15048 | intel_primary_formats, num_formats, |
| 15073 | DRM_PLANE_TYPE_PRIMARY, | 15049 | DRM_PLANE_TYPE_PRIMARY, |
| 15074 | "plane %c", plane_name(primary->plane)); | 15050 | "plane %c", plane_name(primary->plane)); |
| @@ -15093,13 +15069,13 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev, | |||
| 15093 | 15069 | ||
| 15094 | drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs); | 15070 | drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs); |
| 15095 | 15071 | ||
| 15096 | return &primary->base; | 15072 | return primary; |
| 15097 | 15073 | ||
| 15098 | fail: | 15074 | fail: |
| 15099 | kfree(state); | 15075 | kfree(state); |
| 15100 | kfree(primary); | 15076 | kfree(primary); |
| 15101 | 15077 | ||
| 15102 | return NULL; | 15078 | return ERR_PTR(ret); |
| 15103 | } | 15079 | } |
| 15104 | 15080 | ||
| 15105 | static int | 15081 | static int |
| @@ -15195,21 +15171,25 @@ intel_update_cursor_plane(struct drm_plane *plane, | |||
| 15195 | intel_crtc_update_cursor(crtc, state); | 15171 | intel_crtc_update_cursor(crtc, state); |
| 15196 | } | 15172 | } |
| 15197 | 15173 | ||
| 15198 | static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev, | 15174 | static struct intel_plane * |
| 15199 | int pipe) | 15175 | intel_cursor_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) |
| 15200 | { | 15176 | { |
| 15201 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 15202 | struct intel_plane *cursor = NULL; | 15177 | struct intel_plane *cursor = NULL; |
| 15203 | struct intel_plane_state *state = NULL; | 15178 | struct intel_plane_state *state = NULL; |
| 15204 | int ret; | 15179 | int ret; |
| 15205 | 15180 | ||
| 15206 | cursor = kzalloc(sizeof(*cursor), GFP_KERNEL); | 15181 | cursor = kzalloc(sizeof(*cursor), GFP_KERNEL); |
| 15207 | if (!cursor) | 15182 | if (!cursor) { |
| 15183 | ret = -ENOMEM; | ||
| 15208 | goto fail; | 15184 | goto fail; |
| 15185 | } | ||
| 15209 | 15186 | ||
| 15210 | state = intel_create_plane_state(&cursor->base); | 15187 | state = intel_create_plane_state(&cursor->base); |
| 15211 | if (!state) | 15188 | if (!state) { |
| 15189 | ret = -ENOMEM; | ||
| 15212 | goto fail; | 15190 | goto fail; |
| 15191 | } | ||
| 15192 | |||
| 15213 | cursor->base.state = &state->base; | 15193 | cursor->base.state = &state->base; |
| 15214 | 15194 | ||
| 15215 | cursor->can_scale = false; | 15195 | cursor->can_scale = false; |
| @@ -15221,8 +15201,8 @@ static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev, | |||
| 15221 | cursor->update_plane = intel_update_cursor_plane; | 15201 | cursor->update_plane = intel_update_cursor_plane; |
| 15222 | cursor->disable_plane = intel_disable_cursor_plane; | 15202 | cursor->disable_plane = intel_disable_cursor_plane; |
| 15223 | 15203 | ||
| 15224 | ret = drm_universal_plane_init(dev, &cursor->base, 0, | 15204 | ret = drm_universal_plane_init(&dev_priv->drm, &cursor->base, |
| 15225 | &intel_plane_funcs, | 15205 | 0, &intel_plane_funcs, |
| 15226 | intel_cursor_formats, | 15206 | intel_cursor_formats, |
| 15227 | ARRAY_SIZE(intel_cursor_formats), | 15207 | ARRAY_SIZE(intel_cursor_formats), |
| 15228 | DRM_PLANE_TYPE_CURSOR, | 15208 | DRM_PLANE_TYPE_CURSOR, |
| @@ -15236,76 +15216,94 @@ static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev, | |||
| 15236 | DRM_ROTATE_0 | | 15216 | DRM_ROTATE_0 | |
| 15237 | DRM_ROTATE_180); | 15217 | DRM_ROTATE_180); |
| 15238 | 15218 | ||
| 15239 | if (INTEL_INFO(dev)->gen >=9) | 15219 | if (INTEL_GEN(dev_priv) >= 9) |
| 15240 | state->scaler_id = -1; | 15220 | state->scaler_id = -1; |
| 15241 | 15221 | ||
| 15242 | drm_plane_helper_add(&cursor->base, &intel_plane_helper_funcs); | 15222 | drm_plane_helper_add(&cursor->base, &intel_plane_helper_funcs); |
| 15243 | 15223 | ||
| 15244 | return &cursor->base; | 15224 | return cursor; |
| 15245 | 15225 | ||
| 15246 | fail: | 15226 | fail: |
| 15247 | kfree(state); | 15227 | kfree(state); |
| 15248 | kfree(cursor); | 15228 | kfree(cursor); |
| 15249 | 15229 | ||
| 15250 | return NULL; | 15230 | return ERR_PTR(ret); |
| 15251 | } | 15231 | } |
| 15252 | 15232 | ||
| 15253 | static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc, | 15233 | static void skl_init_scalers(struct drm_i915_private *dev_priv, |
| 15254 | struct intel_crtc_state *crtc_state) | 15234 | struct intel_crtc *crtc, |
| 15235 | struct intel_crtc_state *crtc_state) | ||
| 15255 | { | 15236 | { |
| 15237 | struct intel_crtc_scaler_state *scaler_state = | ||
| 15238 | &crtc_state->scaler_state; | ||
| 15256 | int i; | 15239 | int i; |
| 15257 | struct intel_scaler *intel_scaler; | ||
| 15258 | struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state; | ||
| 15259 | 15240 | ||
| 15260 | for (i = 0; i < intel_crtc->num_scalers; i++) { | 15241 | for (i = 0; i < crtc->num_scalers; i++) { |
| 15261 | intel_scaler = &scaler_state->scalers[i]; | 15242 | struct intel_scaler *scaler = &scaler_state->scalers[i]; |
| 15262 | intel_scaler->in_use = 0; | 15243 | |
| 15263 | intel_scaler->mode = PS_SCALER_MODE_DYN; | 15244 | scaler->in_use = 0; |
| 15245 | scaler->mode = PS_SCALER_MODE_DYN; | ||
| 15264 | } | 15246 | } |
| 15265 | 15247 | ||
| 15266 | scaler_state->scaler_id = -1; | 15248 | scaler_state->scaler_id = -1; |
| 15267 | } | 15249 | } |
| 15268 | 15250 | ||
| 15269 | static void intel_crtc_init(struct drm_device *dev, int pipe) | 15251 | static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe) |
| 15270 | { | 15252 | { |
| 15271 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 15272 | struct intel_crtc *intel_crtc; | 15253 | struct intel_crtc *intel_crtc; |
| 15273 | struct intel_crtc_state *crtc_state = NULL; | 15254 | struct intel_crtc_state *crtc_state = NULL; |
| 15274 | struct drm_plane *primary = NULL; | 15255 | struct intel_plane *primary = NULL; |
| 15275 | struct drm_plane *cursor = NULL; | 15256 | struct intel_plane *cursor = NULL; |
| 15276 | int ret; | 15257 | int sprite, ret; |
| 15277 | 15258 | ||
| 15278 | intel_crtc = kzalloc(sizeof(*intel_crtc), GFP_KERNEL); | 15259 | intel_crtc = kzalloc(sizeof(*intel_crtc), GFP_KERNEL); |
| 15279 | if (intel_crtc == NULL) | 15260 | if (!intel_crtc) |
| 15280 | return; | 15261 | return -ENOMEM; |
| 15281 | 15262 | ||
| 15282 | crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL); | 15263 | crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL); |
| 15283 | if (!crtc_state) | 15264 | if (!crtc_state) { |
| 15265 | ret = -ENOMEM; | ||
| 15284 | goto fail; | 15266 | goto fail; |
| 15267 | } | ||
| 15285 | intel_crtc->config = crtc_state; | 15268 | intel_crtc->config = crtc_state; |
| 15286 | intel_crtc->base.state = &crtc_state->base; | 15269 | intel_crtc->base.state = &crtc_state->base; |
| 15287 | crtc_state->base.crtc = &intel_crtc->base; | 15270 | crtc_state->base.crtc = &intel_crtc->base; |
| 15288 | 15271 | ||
| 15289 | /* initialize shared scalers */ | 15272 | /* initialize shared scalers */ |
| 15290 | if (INTEL_INFO(dev)->gen >= 9) { | 15273 | if (INTEL_GEN(dev_priv) >= 9) { |
| 15291 | if (pipe == PIPE_C) | 15274 | if (pipe == PIPE_C) |
| 15292 | intel_crtc->num_scalers = 1; | 15275 | intel_crtc->num_scalers = 1; |
| 15293 | else | 15276 | else |
| 15294 | intel_crtc->num_scalers = SKL_NUM_SCALERS; | 15277 | intel_crtc->num_scalers = SKL_NUM_SCALERS; |
| 15295 | 15278 | ||
| 15296 | skl_init_scalers(dev, intel_crtc, crtc_state); | 15279 | skl_init_scalers(dev_priv, intel_crtc, crtc_state); |
| 15297 | } | 15280 | } |
| 15298 | 15281 | ||
| 15299 | primary = intel_primary_plane_create(dev, pipe); | 15282 | primary = intel_primary_plane_create(dev_priv, pipe); |
| 15300 | if (!primary) | 15283 | if (IS_ERR(primary)) { |
| 15284 | ret = PTR_ERR(primary); | ||
| 15301 | goto fail; | 15285 | goto fail; |
| 15286 | } | ||
| 15287 | |||
| 15288 | for_each_sprite(dev_priv, pipe, sprite) { | ||
| 15289 | struct intel_plane *plane; | ||
| 15302 | 15290 | ||
| 15303 | cursor = intel_cursor_plane_create(dev, pipe); | 15291 | plane = intel_sprite_plane_create(dev_priv, pipe, sprite); |
| 15304 | if (!cursor) | 15292 | if (!plane) { |
| 15293 | ret = PTR_ERR(plane); | ||
| 15294 | goto fail; | ||
| 15295 | } | ||
| 15296 | } | ||
| 15297 | |||
| 15298 | cursor = intel_cursor_plane_create(dev_priv, pipe); | ||
| 15299 | if (!cursor) { | ||
| 15300 | ret = PTR_ERR(cursor); | ||
| 15305 | goto fail; | 15301 | goto fail; |
| 15302 | } | ||
| 15306 | 15303 | ||
| 15307 | ret = drm_crtc_init_with_planes(dev, &intel_crtc->base, primary, | 15304 | ret = drm_crtc_init_with_planes(&dev_priv->drm, &intel_crtc->base, |
| 15308 | cursor, &intel_crtc_funcs, | 15305 | &primary->base, &cursor->base, |
| 15306 | &intel_crtc_funcs, | ||
| 15309 | "pipe %c", pipe_name(pipe)); | 15307 | "pipe %c", pipe_name(pipe)); |
| 15310 | if (ret) | 15308 | if (ret) |
| 15311 | goto fail; | 15309 | goto fail; |
| @@ -15315,8 +15313,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
| 15315 | * is hooked to pipe B. Hence we want plane A feeding pipe B. | 15313 | * is hooked to pipe B. Hence we want plane A feeding pipe B. |
| 15316 | */ | 15314 | */ |
| 15317 | intel_crtc->pipe = pipe; | 15315 | intel_crtc->pipe = pipe; |
| 15318 | intel_crtc->plane = pipe; | 15316 | intel_crtc->plane = (enum plane) pipe; |
| 15319 | if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4) { | 15317 | if (HAS_FBC(dev_priv) && INTEL_GEN(dev_priv) < 4) { |
| 15320 | DRM_DEBUG_KMS("swapping pipes & planes for FBC\n"); | 15318 | DRM_DEBUG_KMS("swapping pipes & planes for FBC\n"); |
| 15321 | intel_crtc->plane = !pipe; | 15319 | intel_crtc->plane = !pipe; |
| 15322 | } | 15320 | } |
| @@ -15329,21 +15327,26 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
| 15329 | 15327 | ||
| 15330 | BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) || | 15328 | BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) || |
| 15331 | dev_priv->plane_to_crtc_mapping[intel_crtc->plane] != NULL); | 15329 | dev_priv->plane_to_crtc_mapping[intel_crtc->plane] != NULL); |
| 15332 | dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base; | 15330 | dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = intel_crtc; |
| 15333 | dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; | 15331 | dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = intel_crtc; |
| 15334 | 15332 | ||
| 15335 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); | 15333 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); |
| 15336 | 15334 | ||
| 15337 | intel_color_init(&intel_crtc->base); | 15335 | intel_color_init(&intel_crtc->base); |
| 15338 | 15336 | ||
| 15339 | WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); | 15337 | WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); |
| 15340 | return; | 15338 | |
| 15339 | return 0; | ||
| 15341 | 15340 | ||
| 15342 | fail: | 15341 | fail: |
| 15343 | intel_plane_destroy(primary); | 15342 | /* |
| 15344 | intel_plane_destroy(cursor); | 15343 | * drm_mode_config_cleanup() will free up any |
| 15344 | * crtcs/planes already initialized. | ||
| 15345 | */ | ||
| 15345 | kfree(crtc_state); | 15346 | kfree(crtc_state); |
| 15346 | kfree(intel_crtc); | 15347 | kfree(intel_crtc); |
| 15348 | |||
| 15349 | return ret; | ||
| 15347 | } | 15350 | } |
| 15348 | 15351 | ||
| 15349 | enum pipe intel_get_pipe_from_connector(struct intel_connector *connector) | 15352 | enum pipe intel_get_pipe_from_connector(struct intel_connector *connector) |
| @@ -15393,11 +15396,9 @@ static int intel_encoder_clones(struct intel_encoder *encoder) | |||
| 15393 | return index_mask; | 15396 | return index_mask; |
| 15394 | } | 15397 | } |
| 15395 | 15398 | ||
| 15396 | static bool has_edp_a(struct drm_device *dev) | 15399 | static bool has_edp_a(struct drm_i915_private *dev_priv) |
| 15397 | { | 15400 | { |
| 15398 | struct drm_i915_private *dev_priv = to_i915(dev); | 15401 | if (!IS_MOBILE(dev_priv)) |
| 15399 | |||
| 15400 | if (!IS_MOBILE(dev)) | ||
| 15401 | return false; | 15402 | return false; |
| 15402 | 15403 | ||
| 15403 | if ((I915_READ(DP_A) & DP_DETECTED) == 0) | 15404 | if ((I915_READ(DP_A) & DP_DETECTED) == 0) |
| @@ -15537,7 +15538,7 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
| 15537 | int found; | 15538 | int found; |
| 15538 | dpd_is_edp = intel_dp_is_edp(dev, PORT_D); | 15539 | dpd_is_edp = intel_dp_is_edp(dev, PORT_D); |
| 15539 | 15540 | ||
| 15540 | if (has_edp_a(dev)) | 15541 | if (has_edp_a(dev_priv)) |
| 15541 | intel_dp_init(dev, DP_A, PORT_A); | 15542 | intel_dp_init(dev, DP_A, PORT_A); |
| 15542 | 15543 | ||
| 15543 | if (I915_READ(PCH_HDMIB) & SDVO_DETECTED) { | 15544 | if (I915_READ(PCH_HDMIB) & SDVO_DETECTED) { |
| @@ -15929,7 +15930,7 @@ intel_user_framebuffer_create(struct drm_device *dev, | |||
| 15929 | 15930 | ||
| 15930 | fb = intel_framebuffer_create(dev, &mode_cmd, obj); | 15931 | fb = intel_framebuffer_create(dev, &mode_cmd, obj); |
| 15931 | if (IS_ERR(fb)) | 15932 | if (IS_ERR(fb)) |
| 15932 | i915_gem_object_put_unlocked(obj); | 15933 | i915_gem_object_put(obj); |
| 15933 | 15934 | ||
| 15934 | return fb; | 15935 | return fb; |
| 15935 | } | 15936 | } |
| @@ -16332,11 +16333,11 @@ void intel_modeset_init_hw(struct drm_device *dev) | |||
| 16332 | { | 16333 | { |
| 16333 | struct drm_i915_private *dev_priv = to_i915(dev); | 16334 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 16334 | 16335 | ||
| 16335 | intel_update_cdclk(dev); | 16336 | intel_update_cdclk(dev_priv); |
| 16336 | 16337 | ||
| 16337 | dev_priv->atomic_cdclk_freq = dev_priv->cdclk_freq; | 16338 | dev_priv->atomic_cdclk_freq = dev_priv->cdclk_freq; |
| 16338 | 16339 | ||
| 16339 | intel_init_clock_gating(dev); | 16340 | intel_init_clock_gating(dev_priv); |
| 16340 | } | 16341 | } |
| 16341 | 16342 | ||
| 16342 | /* | 16343 | /* |
| @@ -16420,11 +16421,10 @@ fail: | |||
| 16420 | drm_modeset_acquire_fini(&ctx); | 16421 | drm_modeset_acquire_fini(&ctx); |
| 16421 | } | 16422 | } |
| 16422 | 16423 | ||
| 16423 | void intel_modeset_init(struct drm_device *dev) | 16424 | int intel_modeset_init(struct drm_device *dev) |
| 16424 | { | 16425 | { |
| 16425 | struct drm_i915_private *dev_priv = to_i915(dev); | 16426 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 16426 | struct i915_ggtt *ggtt = &dev_priv->ggtt; | 16427 | struct i915_ggtt *ggtt = &dev_priv->ggtt; |
| 16427 | int sprite, ret; | ||
| 16428 | enum pipe pipe; | 16428 | enum pipe pipe; |
| 16429 | struct intel_crtc *crtc; | 16429 | struct intel_crtc *crtc; |
| 16430 | 16430 | ||
| @@ -16442,10 +16442,10 @@ void intel_modeset_init(struct drm_device *dev) | |||
| 16442 | 16442 | ||
| 16443 | intel_init_quirks(dev); | 16443 | intel_init_quirks(dev); |
| 16444 | 16444 | ||
| 16445 | intel_init_pm(dev); | 16445 | intel_init_pm(dev_priv); |
| 16446 | 16446 | ||
| 16447 | if (INTEL_INFO(dev)->num_pipes == 0) | 16447 | if (INTEL_INFO(dev)->num_pipes == 0) |
| 16448 | return; | 16448 | return 0; |
| 16449 | 16449 | ||
| 16450 | /* | 16450 | /* |
| 16451 | * There may be no VBT; and if the BIOS enabled SSC we can | 16451 | * There may be no VBT; and if the BIOS enabled SSC we can |
| @@ -16494,22 +16494,22 @@ void intel_modeset_init(struct drm_device *dev) | |||
| 16494 | INTEL_INFO(dev)->num_pipes > 1 ? "s" : ""); | 16494 | INTEL_INFO(dev)->num_pipes > 1 ? "s" : ""); |
| 16495 | 16495 | ||
| 16496 | for_each_pipe(dev_priv, pipe) { | 16496 | for_each_pipe(dev_priv, pipe) { |
| 16497 | intel_crtc_init(dev, pipe); | 16497 | int ret; |
| 16498 | for_each_sprite(dev_priv, pipe, sprite) { | 16498 | |
| 16499 | ret = intel_plane_init(dev, pipe, sprite); | 16499 | ret = intel_crtc_init(dev_priv, pipe); |
| 16500 | if (ret) | 16500 | if (ret) { |
| 16501 | DRM_DEBUG_KMS("pipe %c sprite %c init failed: %d\n", | 16501 | drm_mode_config_cleanup(dev); |
| 16502 | pipe_name(pipe), sprite_name(pipe, sprite), ret); | 16502 | return ret; |
| 16503 | } | 16503 | } |
| 16504 | } | 16504 | } |
| 16505 | 16505 | ||
| 16506 | intel_update_czclk(dev_priv); | 16506 | intel_update_czclk(dev_priv); |
| 16507 | intel_update_cdclk(dev); | 16507 | intel_update_cdclk(dev_priv); |
| 16508 | 16508 | ||
| 16509 | intel_shared_dpll_init(dev); | 16509 | intel_shared_dpll_init(dev); |
| 16510 | 16510 | ||
| 16511 | if (dev_priv->max_cdclk_freq == 0) | 16511 | if (dev_priv->max_cdclk_freq == 0) |
| 16512 | intel_update_max_cdclk(dev); | 16512 | intel_update_max_cdclk(dev_priv); |
| 16513 | 16513 | ||
| 16514 | /* Just disable it once at startup */ | 16514 | /* Just disable it once at startup */ |
| 16515 | i915_disable_vga(dev); | 16515 | i915_disable_vga(dev); |
| @@ -16548,6 +16548,8 @@ void intel_modeset_init(struct drm_device *dev) | |||
| 16548 | * since the watermark calculation done here will use pstate->fb. | 16548 | * since the watermark calculation done here will use pstate->fb. |
| 16549 | */ | 16549 | */ |
| 16550 | sanitize_watermarks(dev); | 16550 | sanitize_watermarks(dev); |
| 16551 | |||
| 16552 | return 0; | ||
| 16551 | } | 16553 | } |
| 16552 | 16554 | ||
| 16553 | static void intel_enable_pipe_a(struct drm_device *dev) | 16555 | static void intel_enable_pipe_a(struct drm_device *dev) |
| @@ -16877,7 +16879,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) | |||
| 16877 | pipe = 0; | 16879 | pipe = 0; |
| 16878 | 16880 | ||
| 16879 | if (encoder->get_hw_state(encoder, &pipe)) { | 16881 | if (encoder->get_hw_state(encoder, &pipe)) { |
| 16880 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); | 16882 | crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
| 16883 | |||
| 16881 | encoder->base.crtc = &crtc->base; | 16884 | encoder->base.crtc = &crtc->base; |
| 16882 | crtc->config->output_types |= 1 << encoder->type; | 16885 | crtc->config->output_types |= 1 << encoder->type; |
| 16883 | encoder->get_config(encoder, crtc->config); | 16886 | encoder->get_config(encoder, crtc->config); |
| @@ -16978,7 +16981,8 @@ intel_modeset_setup_hw_state(struct drm_device *dev) | |||
| 16978 | } | 16981 | } |
| 16979 | 16982 | ||
| 16980 | for_each_pipe(dev_priv, pipe) { | 16983 | for_each_pipe(dev_priv, pipe) { |
| 16981 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); | 16984 | crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
| 16985 | |||
| 16982 | intel_sanitize_crtc(crtc); | 16986 | intel_sanitize_crtc(crtc); |
| 16983 | intel_dump_pipe_config(crtc, crtc->config, | 16987 | intel_dump_pipe_config(crtc, crtc->config, |
| 16984 | "[setup_hw_state]"); | 16988 | "[setup_hw_state]"); |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3c2293bd24bf..9df331b3305b 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -213,6 +213,81 @@ intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp) | |||
| 213 | return max_dotclk; | 213 | return max_dotclk; |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | static int | ||
| 217 | intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates) | ||
| 218 | { | ||
| 219 | if (intel_dp->num_sink_rates) { | ||
| 220 | *sink_rates = intel_dp->sink_rates; | ||
| 221 | return intel_dp->num_sink_rates; | ||
| 222 | } | ||
| 223 | |||
| 224 | *sink_rates = default_rates; | ||
| 225 | |||
| 226 | return (intel_dp_max_link_bw(intel_dp) >> 3) + 1; | ||
| 227 | } | ||
| 228 | |||
| 229 | static int | ||
| 230 | intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates) | ||
| 231 | { | ||
| 232 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | ||
| 233 | struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); | ||
| 234 | int size; | ||
| 235 | |||
| 236 | if (IS_BROXTON(dev_priv)) { | ||
| 237 | *source_rates = bxt_rates; | ||
| 238 | size = ARRAY_SIZE(bxt_rates); | ||
| 239 | } else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { | ||
| 240 | *source_rates = skl_rates; | ||
| 241 | size = ARRAY_SIZE(skl_rates); | ||
| 242 | } else { | ||
| 243 | *source_rates = default_rates; | ||
| 244 | size = ARRAY_SIZE(default_rates); | ||
| 245 | } | ||
| 246 | |||
| 247 | /* This depends on the fact that 5.4 is last value in the array */ | ||
| 248 | if (!intel_dp_source_supports_hbr2(intel_dp)) | ||
| 249 | size--; | ||
| 250 | |||
| 251 | return size; | ||
| 252 | } | ||
| 253 | |||
| 254 | static int intersect_rates(const int *source_rates, int source_len, | ||
| 255 | const int *sink_rates, int sink_len, | ||
| 256 | int *common_rates) | ||
| 257 | { | ||
| 258 | int i = 0, j = 0, k = 0; | ||
| 259 | |||
| 260 | while (i < source_len && j < sink_len) { | ||
| 261 | if (source_rates[i] == sink_rates[j]) { | ||
| 262 | if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES)) | ||
| 263 | return k; | ||
| 264 | common_rates[k] = source_rates[i]; | ||
| 265 | ++k; | ||
| 266 | ++i; | ||
| 267 | ++j; | ||
| 268 | } else if (source_rates[i] < sink_rates[j]) { | ||
| 269 | ++i; | ||
| 270 | } else { | ||
| 271 | ++j; | ||
| 272 | } | ||
| 273 | } | ||
| 274 | return k; | ||
| 275 | } | ||
| 276 | |||
| 277 | static int intel_dp_common_rates(struct intel_dp *intel_dp, | ||
| 278 | int *common_rates) | ||
| 279 | { | ||
| 280 | const int *source_rates, *sink_rates; | ||
| 281 | int source_len, sink_len; | ||
| 282 | |||
| 283 | sink_len = intel_dp_sink_rates(intel_dp, &sink_rates); | ||
| 284 | source_len = intel_dp_source_rates(intel_dp, &source_rates); | ||
| 285 | |||
| 286 | return intersect_rates(source_rates, source_len, | ||
| 287 | sink_rates, sink_len, | ||
| 288 | common_rates); | ||
| 289 | } | ||
| 290 | |||
| 216 | static enum drm_mode_status | 291 | static enum drm_mode_status |
| 217 | intel_dp_mode_valid(struct drm_connector *connector, | 292 | intel_dp_mode_valid(struct drm_connector *connector, |
| 218 | struct drm_display_mode *mode) | 293 | struct drm_display_mode *mode) |
| @@ -320,8 +395,7 @@ static void | |||
| 320 | vlv_power_sequencer_kick(struct intel_dp *intel_dp) | 395 | vlv_power_sequencer_kick(struct intel_dp *intel_dp) |
| 321 | { | 396 | { |
| 322 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 397 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
| 323 | struct drm_device *dev = intel_dig_port->base.base.dev; | 398 | struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev); |
| 324 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 325 | enum pipe pipe = intel_dp->pps_pipe; | 399 | enum pipe pipe = intel_dp->pps_pipe; |
| 326 | bool pll_enabled, release_cl_override = false; | 400 | bool pll_enabled, release_cl_override = false; |
| 327 | enum dpio_phy phy = DPIO_PHY(pipe); | 401 | enum dpio_phy phy = DPIO_PHY(pipe); |
| @@ -359,7 +433,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp) | |||
| 359 | release_cl_override = IS_CHERRYVIEW(dev_priv) && | 433 | release_cl_override = IS_CHERRYVIEW(dev_priv) && |
| 360 | !chv_phy_powergate_ch(dev_priv, phy, ch, true); | 434 | !chv_phy_powergate_ch(dev_priv, phy, ch, true); |
| 361 | 435 | ||
| 362 | if (vlv_force_pll_on(dev, pipe, IS_CHERRYVIEW(dev_priv) ? | 436 | if (vlv_force_pll_on(dev_priv, pipe, IS_CHERRYVIEW(dev_priv) ? |
| 363 | &chv_dpll[0].dpll : &vlv_dpll[0].dpll)) { | 437 | &chv_dpll[0].dpll : &vlv_dpll[0].dpll)) { |
| 364 | DRM_ERROR("Failed to force on pll for pipe %c!\n", | 438 | DRM_ERROR("Failed to force on pll for pipe %c!\n", |
| 365 | pipe_name(pipe)); | 439 | pipe_name(pipe)); |
| @@ -383,7 +457,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp) | |||
| 383 | POSTING_READ(intel_dp->output_reg); | 457 | POSTING_READ(intel_dp->output_reg); |
| 384 | 458 | ||
| 385 | if (!pll_enabled) { | 459 | if (!pll_enabled) { |
| 386 | vlv_force_pll_off(dev, pipe); | 460 | vlv_force_pll_off(dev_priv, pipe); |
| 387 | 461 | ||
| 388 | if (release_cl_override) | 462 | if (release_cl_override) |
| 389 | chv_phy_powergate_ch(dev_priv, phy, ch, false); | 463 | chv_phy_powergate_ch(dev_priv, phy, ch, false); |
| @@ -1291,19 +1365,6 @@ intel_dp_aux_init(struct intel_dp *intel_dp) | |||
| 1291 | intel_dp->aux.transfer = intel_dp_aux_transfer; | 1365 | intel_dp->aux.transfer = intel_dp_aux_transfer; |
| 1292 | } | 1366 | } |
| 1293 | 1367 | ||
| 1294 | static int | ||
| 1295 | intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates) | ||
| 1296 | { | ||
| 1297 | if (intel_dp->num_sink_rates) { | ||
| 1298 | *sink_rates = intel_dp->sink_rates; | ||
| 1299 | return intel_dp->num_sink_rates; | ||
| 1300 | } | ||
| 1301 | |||
| 1302 | *sink_rates = default_rates; | ||
| 1303 | |||
| 1304 | return (intel_dp_max_link_bw(intel_dp) >> 3) + 1; | ||
| 1305 | } | ||
| 1306 | |||
| 1307 | bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp) | 1368 | bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp) |
| 1308 | { | 1369 | { |
| 1309 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | 1370 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
| @@ -1316,31 +1377,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp) | |||
| 1316 | return false; | 1377 | return false; |
| 1317 | } | 1378 | } |
| 1318 | 1379 | ||
| 1319 | static int | ||
| 1320 | intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates) | ||
| 1321 | { | ||
| 1322 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | ||
| 1323 | struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); | ||
| 1324 | int size; | ||
| 1325 | |||
| 1326 | if (IS_BROXTON(dev_priv)) { | ||
| 1327 | *source_rates = bxt_rates; | ||
| 1328 | size = ARRAY_SIZE(bxt_rates); | ||
| 1329 | } else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { | ||
| 1330 | *source_rates = skl_rates; | ||
| 1331 | size = ARRAY_SIZE(skl_rates); | ||
| 1332 | } else { | ||
| 1333 | *source_rates = default_rates; | ||
| 1334 | size = ARRAY_SIZE(default_rates); | ||
| 1335 | } | ||
| 1336 | |||
| 1337 | /* This depends on the fact that 5.4 is last value in the array */ | ||
| 1338 | if (!intel_dp_source_supports_hbr2(intel_dp)) | ||
| 1339 | size--; | ||
| 1340 | |||
| 1341 | return size; | ||
| 1342 | } | ||
| 1343 | |||
| 1344 | static void | 1380 | static void |
| 1345 | intel_dp_set_clock(struct intel_encoder *encoder, | 1381 | intel_dp_set_clock(struct intel_encoder *encoder, |
| 1346 | struct intel_crtc_state *pipe_config) | 1382 | struct intel_crtc_state *pipe_config) |
| @@ -1375,43 +1411,6 @@ intel_dp_set_clock(struct intel_encoder *encoder, | |||
| 1375 | } | 1411 | } |
| 1376 | } | 1412 | } |
| 1377 | 1413 | ||
| 1378 | static int intersect_rates(const int *source_rates, int source_len, | ||
| 1379 | const int *sink_rates, int sink_len, | ||
| 1380 | int *common_rates) | ||
| 1381 | { | ||
| 1382 | int i = 0, j = 0, k = 0; | ||
| 1383 | |||
| 1384 | while (i < source_len && j < sink_len) { | ||
| 1385 | if (source_rates[i] == sink_rates[j]) { | ||
| 1386 | if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES)) | ||
| 1387 | return k; | ||
| 1388 | common_rates[k] = source_rates[i]; | ||
| 1389 | ++k; | ||
| 1390 | ++i; | ||
| 1391 | ++j; | ||
| 1392 | } else if (source_rates[i] < sink_rates[j]) { | ||
| 1393 | ++i; | ||
| 1394 | } else { | ||
| 1395 | ++j; | ||
| 1396 | } | ||
| 1397 | } | ||
| 1398 | return k; | ||
| 1399 | } | ||
| 1400 | |||
| 1401 | static int intel_dp_common_rates(struct intel_dp *intel_dp, | ||
| 1402 | int *common_rates) | ||
| 1403 | { | ||
| 1404 | const int *source_rates, *sink_rates; | ||
| 1405 | int source_len, sink_len; | ||
| 1406 | |||
| 1407 | sink_len = intel_dp_sink_rates(intel_dp, &sink_rates); | ||
| 1408 | source_len = intel_dp_source_rates(intel_dp, &source_rates); | ||
| 1409 | |||
| 1410 | return intersect_rates(source_rates, source_len, | ||
| 1411 | sink_rates, sink_len, | ||
| 1412 | common_rates); | ||
| 1413 | } | ||
| 1414 | |||
| 1415 | static void snprintf_int_array(char *str, size_t len, | 1414 | static void snprintf_int_array(char *str, size_t len, |
| 1416 | const int *array, int nelem) | 1415 | const int *array, int nelem) |
| 1417 | { | 1416 | { |
| @@ -1451,40 +1450,35 @@ static void intel_dp_print_rates(struct intel_dp *intel_dp) | |||
| 1451 | DRM_DEBUG_KMS("common rates: %s\n", str); | 1450 | DRM_DEBUG_KMS("common rates: %s\n", str); |
| 1452 | } | 1451 | } |
| 1453 | 1452 | ||
| 1454 | static void intel_dp_print_hw_revision(struct intel_dp *intel_dp) | 1453 | bool |
| 1454 | __intel_dp_read_desc(struct intel_dp *intel_dp, struct intel_dp_desc *desc) | ||
| 1455 | { | 1455 | { |
| 1456 | uint8_t rev; | 1456 | u32 base = drm_dp_is_branch(intel_dp->dpcd) ? DP_BRANCH_OUI : |
| 1457 | int len; | 1457 | DP_SINK_OUI; |
| 1458 | |||
| 1459 | if ((drm_debug & DRM_UT_KMS) == 0) | ||
| 1460 | return; | ||
| 1461 | 1458 | ||
| 1462 | if (!drm_dp_is_branch(intel_dp->dpcd)) | 1459 | return drm_dp_dpcd_read(&intel_dp->aux, base, desc, sizeof(*desc)) == |
| 1463 | return; | 1460 | sizeof(*desc); |
| 1464 | |||
| 1465 | len = drm_dp_dpcd_read(&intel_dp->aux, DP_BRANCH_HW_REV, &rev, 1); | ||
| 1466 | if (len < 0) | ||
| 1467 | return; | ||
| 1468 | |||
| 1469 | DRM_DEBUG_KMS("sink hw revision: %d.%d\n", (rev & 0xf0) >> 4, rev & 0xf); | ||
| 1470 | } | 1461 | } |
| 1471 | 1462 | ||
| 1472 | static void intel_dp_print_sw_revision(struct intel_dp *intel_dp) | 1463 | bool intel_dp_read_desc(struct intel_dp *intel_dp) |
| 1473 | { | 1464 | { |
| 1474 | uint8_t rev[2]; | 1465 | struct intel_dp_desc *desc = &intel_dp->desc; |
| 1475 | int len; | 1466 | bool oui_sup = intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & |
| 1467 | DP_OUI_SUPPORT; | ||
| 1468 | int dev_id_len; | ||
| 1476 | 1469 | ||
| 1477 | if ((drm_debug & DRM_UT_KMS) == 0) | 1470 | if (!__intel_dp_read_desc(intel_dp, desc)) |
| 1478 | return; | 1471 | return false; |
| 1479 | |||
| 1480 | if (!drm_dp_is_branch(intel_dp->dpcd)) | ||
| 1481 | return; | ||
| 1482 | 1472 | ||
| 1483 | len = drm_dp_dpcd_read(&intel_dp->aux, DP_BRANCH_SW_REV, &rev, 2); | 1473 | dev_id_len = strnlen(desc->device_id, sizeof(desc->device_id)); |
| 1484 | if (len < 0) | 1474 | DRM_DEBUG_KMS("DP %s: OUI %*phD%s dev-ID %*pE HW-rev %d.%d SW-rev %d.%d\n", |
| 1485 | return; | 1475 | drm_dp_is_branch(intel_dp->dpcd) ? "branch" : "sink", |
| 1476 | (int)sizeof(desc->oui), desc->oui, oui_sup ? "" : "(NS)", | ||
| 1477 | dev_id_len, desc->device_id, | ||
| 1478 | desc->hw_rev >> 4, desc->hw_rev & 0xf, | ||
| 1479 | desc->sw_major_rev, desc->sw_minor_rev); | ||
| 1486 | 1480 | ||
| 1487 | DRM_DEBUG_KMS("sink sw revision: %d.%d\n", rev[0], rev[1]); | 1481 | return true; |
| 1488 | } | 1482 | } |
| 1489 | 1483 | ||
| 1490 | static int rate_to_index(int find, const int *rates) | 1484 | static int rate_to_index(int find, const int *rates) |
| @@ -2369,7 +2363,7 @@ static void ironlake_edp_pll_on(struct intel_dp *intel_dp, | |||
| 2369 | * 2. Program DP PLL enable | 2363 | * 2. Program DP PLL enable |
| 2370 | */ | 2364 | */ |
| 2371 | if (IS_GEN5(dev_priv)) | 2365 | if (IS_GEN5(dev_priv)) |
| 2372 | intel_wait_for_vblank_if_active(&dev_priv->drm, !crtc->pipe); | 2366 | intel_wait_for_vblank_if_active(dev_priv, !crtc->pipe); |
| 2373 | 2367 | ||
| 2374 | intel_dp->DP |= DP_PLL_ENABLE; | 2368 | intel_dp->DP |= DP_PLL_ENABLE; |
| 2375 | 2369 | ||
| @@ -3492,7 +3486,7 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
| 3492 | I915_WRITE(intel_dp->output_reg, DP); | 3486 | I915_WRITE(intel_dp->output_reg, DP); |
| 3493 | POSTING_READ(intel_dp->output_reg); | 3487 | POSTING_READ(intel_dp->output_reg); |
| 3494 | 3488 | ||
| 3495 | intel_wait_for_vblank_if_active(&dev_priv->drm, PIPE_A); | 3489 | intel_wait_for_vblank_if_active(dev_priv, PIPE_A); |
| 3496 | intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); | 3490 | intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); |
| 3497 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); | 3491 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); |
| 3498 | } | 3492 | } |
| @@ -3502,7 +3496,7 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
| 3502 | intel_dp->DP = DP; | 3496 | intel_dp->DP = DP; |
| 3503 | } | 3497 | } |
| 3504 | 3498 | ||
| 3505 | static bool | 3499 | bool |
| 3506 | intel_dp_read_dpcd(struct intel_dp *intel_dp) | 3500 | intel_dp_read_dpcd(struct intel_dp *intel_dp) |
| 3507 | { | 3501 | { |
| 3508 | if (drm_dp_dpcd_read(&intel_dp->aux, 0x000, intel_dp->dpcd, | 3502 | if (drm_dp_dpcd_read(&intel_dp->aux, 0x000, intel_dp->dpcd, |
| @@ -3526,6 +3520,8 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp) | |||
| 3526 | if (!intel_dp_read_dpcd(intel_dp)) | 3520 | if (!intel_dp_read_dpcd(intel_dp)) |
| 3527 | return false; | 3521 | return false; |
| 3528 | 3522 | ||
| 3523 | intel_dp_read_desc(intel_dp); | ||
| 3524 | |||
| 3529 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) | 3525 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) |
| 3530 | dev_priv->no_aux_handshake = intel_dp->dpcd[DP_MAX_DOWNSPREAD] & | 3526 | dev_priv->no_aux_handshake = intel_dp->dpcd[DP_MAX_DOWNSPREAD] & |
| 3531 | DP_NO_AUX_HANDSHAKE_LINK_TRAINING; | 3527 | DP_NO_AUX_HANDSHAKE_LINK_TRAINING; |
| @@ -3627,23 +3623,6 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) | |||
| 3627 | return true; | 3623 | return true; |
| 3628 | } | 3624 | } |
| 3629 | 3625 | ||
| 3630 | static void | ||
| 3631 | intel_dp_probe_oui(struct intel_dp *intel_dp) | ||
| 3632 | { | ||
| 3633 | u8 buf[3]; | ||
| 3634 | |||
| 3635 | if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) | ||
| 3636 | return; | ||
| 3637 | |||
| 3638 | if (drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_OUI, buf, 3) == 3) | ||
| 3639 | DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", | ||
| 3640 | buf[0], buf[1], buf[2]); | ||
| 3641 | |||
| 3642 | if (drm_dp_dpcd_read(&intel_dp->aux, DP_BRANCH_OUI, buf, 3) == 3) | ||
| 3643 | DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", | ||
| 3644 | buf[0], buf[1], buf[2]); | ||
| 3645 | } | ||
| 3646 | |||
| 3647 | static bool | 3626 | static bool |
| 3648 | intel_dp_can_mst(struct intel_dp *intel_dp) | 3627 | intel_dp_can_mst(struct intel_dp *intel_dp) |
| 3649 | { | 3628 | { |
| @@ -3687,7 +3666,7 @@ intel_dp_configure_mst(struct intel_dp *intel_dp) | |||
| 3687 | static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp) | 3666 | static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp) |
| 3688 | { | 3667 | { |
| 3689 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | 3668 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
| 3690 | struct drm_device *dev = dig_port->base.base.dev; | 3669 | struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); |
| 3691 | struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc); | 3670 | struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc); |
| 3692 | u8 buf; | 3671 | u8 buf; |
| 3693 | int ret = 0; | 3672 | int ret = 0; |
| @@ -3708,7 +3687,7 @@ static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp) | |||
| 3708 | } | 3687 | } |
| 3709 | 3688 | ||
| 3710 | do { | 3689 | do { |
| 3711 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 3690 | intel_wait_for_vblank(dev_priv, intel_crtc->pipe); |
| 3712 | 3691 | ||
| 3713 | if (drm_dp_dpcd_readb(&intel_dp->aux, | 3692 | if (drm_dp_dpcd_readb(&intel_dp->aux, |
| 3714 | DP_TEST_SINK_MISC, &buf) < 0) { | 3693 | DP_TEST_SINK_MISC, &buf) < 0) { |
| @@ -3731,7 +3710,7 @@ static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp) | |||
| 3731 | static int intel_dp_sink_crc_start(struct intel_dp *intel_dp) | 3710 | static int intel_dp_sink_crc_start(struct intel_dp *intel_dp) |
| 3732 | { | 3711 | { |
| 3733 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | 3712 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
| 3734 | struct drm_device *dev = dig_port->base.base.dev; | 3713 | struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); |
| 3735 | struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc); | 3714 | struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc); |
| 3736 | u8 buf; | 3715 | u8 buf; |
| 3737 | int ret; | 3716 | int ret; |
| @@ -3759,14 +3738,14 @@ static int intel_dp_sink_crc_start(struct intel_dp *intel_dp) | |||
| 3759 | return -EIO; | 3738 | return -EIO; |
| 3760 | } | 3739 | } |
| 3761 | 3740 | ||
| 3762 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 3741 | intel_wait_for_vblank(dev_priv, intel_crtc->pipe); |
| 3763 | return 0; | 3742 | return 0; |
| 3764 | } | 3743 | } |
| 3765 | 3744 | ||
| 3766 | int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) | 3745 | int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) |
| 3767 | { | 3746 | { |
| 3768 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | 3747 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
| 3769 | struct drm_device *dev = dig_port->base.base.dev; | 3748 | struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); |
| 3770 | struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc); | 3749 | struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc); |
| 3771 | u8 buf; | 3750 | u8 buf; |
| 3772 | int count, ret; | 3751 | int count, ret; |
| @@ -3777,7 +3756,7 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) | |||
| 3777 | return ret; | 3756 | return ret; |
| 3778 | 3757 | ||
| 3779 | do { | 3758 | do { |
| 3780 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 3759 | intel_wait_for_vblank(dev_priv, intel_crtc->pipe); |
| 3781 | 3760 | ||
| 3782 | if (drm_dp_dpcd_readb(&intel_dp->aux, | 3761 | if (drm_dp_dpcd_readb(&intel_dp->aux, |
| 3783 | DP_TEST_SINK_MISC, &buf) < 0) { | 3762 | DP_TEST_SINK_MISC, &buf) < 0) { |
| @@ -4010,7 +3989,7 @@ intel_dp_retrain_link(struct intel_dp *intel_dp) | |||
| 4010 | intel_dp_stop_link_train(intel_dp); | 3989 | intel_dp_stop_link_train(intel_dp); |
| 4011 | 3990 | ||
| 4012 | /* Keep underrun reporting disabled until things are stable */ | 3991 | /* Keep underrun reporting disabled until things are stable */ |
| 4013 | intel_wait_for_vblank(&dev_priv->drm, crtc->pipe); | 3992 | intel_wait_for_vblank(dev_priv, crtc->pipe); |
| 4014 | 3993 | ||
| 4015 | intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true); | 3994 | intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true); |
| 4016 | if (crtc->config->has_pch_encoder) | 3995 | if (crtc->config->has_pch_encoder) |
| @@ -4422,10 +4401,7 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) | |||
| 4422 | 4401 | ||
| 4423 | intel_dp_print_rates(intel_dp); | 4402 | intel_dp_print_rates(intel_dp); |
| 4424 | 4403 | ||
| 4425 | intel_dp_probe_oui(intel_dp); | 4404 | intel_dp_read_desc(intel_dp); |
| 4426 | |||
| 4427 | intel_dp_print_hw_revision(intel_dp); | ||
| 4428 | intel_dp_print_sw_revision(intel_dp); | ||
| 4429 | 4405 | ||
| 4430 | intel_dp_configure_mst(intel_dp); | 4406 | intel_dp_configure_mst(intel_dp); |
| 4431 | 4407 | ||
| @@ -4489,21 +4465,11 @@ static enum drm_connector_status | |||
| 4489 | intel_dp_detect(struct drm_connector *connector, bool force) | 4465 | intel_dp_detect(struct drm_connector *connector, bool force) |
| 4490 | { | 4466 | { |
| 4491 | struct intel_dp *intel_dp = intel_attached_dp(connector); | 4467 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
| 4492 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | ||
| 4493 | struct intel_encoder *intel_encoder = &intel_dig_port->base; | ||
| 4494 | enum drm_connector_status status = connector->status; | 4468 | enum drm_connector_status status = connector->status; |
| 4495 | 4469 | ||
| 4496 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", | 4470 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", |
| 4497 | connector->base.id, connector->name); | 4471 | connector->base.id, connector->name); |
| 4498 | 4472 | ||
| 4499 | if (intel_dp->is_mst) { | ||
| 4500 | /* MST devices are disconnected from a monitor POV */ | ||
| 4501 | intel_dp_unset_edid(intel_dp); | ||
| 4502 | if (intel_encoder->type != INTEL_OUTPUT_EDP) | ||
| 4503 | intel_encoder->type = INTEL_OUTPUT_DP; | ||
| 4504 | return connector_status_disconnected; | ||
| 4505 | } | ||
| 4506 | |||
| 4507 | /* If full detect is not performed yet, do a full detect */ | 4473 | /* If full detect is not performed yet, do a full detect */ |
| 4508 | if (!intel_dp->detect_done) | 4474 | if (!intel_dp->detect_done) |
| 4509 | status = intel_dp_long_pulse(intel_dp->attached_connector); | 4475 | status = intel_dp_long_pulse(intel_dp->attached_connector); |
diff --git a/drivers/gpu/drm/i915/intel_dpio_phy.c b/drivers/gpu/drm/i915/intel_dpio_phy.c index 047f48748944..7a8e82dabbf2 100644 --- a/drivers/gpu/drm/i915/intel_dpio_phy.c +++ b/drivers/gpu/drm/i915/intel_dpio_phy.c | |||
| @@ -23,6 +23,565 @@ | |||
| 23 | 23 | ||
| 24 | #include "intel_drv.h" | 24 | #include "intel_drv.h" |
| 25 | 25 | ||
| 26 | /** | ||
| 27 | * DOC: DPIO | ||
| 28 | * | ||
| 29 | * VLV, CHV and BXT have slightly peculiar display PHYs for driving DP/HDMI | ||
| 30 | * ports. DPIO is the name given to such a display PHY. These PHYs | ||
| 31 | * don't follow the standard programming model using direct MMIO | ||
| 32 | * registers, and instead their registers must be accessed trough IOSF | ||
| 33 | * sideband. VLV has one such PHY for driving ports B and C, and CHV | ||
| 34 | * adds another PHY for driving port D. Each PHY responds to specific | ||
| 35 | * IOSF-SB port. | ||
| 36 | * | ||
| 37 | * Each display PHY is made up of one or two channels. Each channel | ||
| 38 | * houses a common lane part which contains the PLL and other common | ||
| 39 | * logic. CH0 common lane also contains the IOSF-SB logic for the | ||
| 40 | * Common Register Interface (CRI) ie. the DPIO registers. CRI clock | ||
| 41 | * must be running when any DPIO registers are accessed. | ||
| 42 | * | ||
| 43 | * In addition to having their own registers, the PHYs are also | ||
| 44 | * controlled through some dedicated signals from the display | ||
| 45 | * controller. These include PLL reference clock enable, PLL enable, | ||
| 46 | * and CRI clock selection, for example. | ||
| 47 | * | ||
| 48 | * Eeach channel also has two splines (also called data lanes), and | ||
| 49 | * each spline is made up of one Physical Access Coding Sub-Layer | ||
| 50 | * (PCS) block and two TX lanes. So each channel has two PCS blocks | ||
| 51 | * and four TX lanes. The TX lanes are used as DP lanes or TMDS | ||
| 52 | * data/clock pairs depending on the output type. | ||
| 53 | * | ||
| 54 | * Additionally the PHY also contains an AUX lane with AUX blocks | ||
| 55 | * for each channel. This is used for DP AUX communication, but | ||
| 56 | * this fact isn't really relevant for the driver since AUX is | ||
| 57 | * controlled from the display controller side. No DPIO registers | ||
| 58 | * need to be accessed during AUX communication, | ||
| 59 | * | ||
| 60 | * Generally on VLV/CHV the common lane corresponds to the pipe and | ||
| 61 | * the spline (PCS/TX) corresponds to the port. | ||
| 62 | * | ||
| 63 | * For dual channel PHY (VLV/CHV): | ||
| 64 | * | ||
| 65 | * pipe A == CMN/PLL/REF CH0 | ||
| 66 | * | ||
| 67 | * pipe B == CMN/PLL/REF CH1 | ||
| 68 | * | ||
| 69 | * port B == PCS/TX CH0 | ||
| 70 | * | ||
| 71 | * port C == PCS/TX CH1 | ||
| 72 | * | ||
| 73 | * This is especially important when we cross the streams | ||
| 74 | * ie. drive port B with pipe B, or port C with pipe A. | ||
| 75 | * | ||
| 76 | * For single channel PHY (CHV): | ||
| 77 | * | ||
| 78 | * pipe C == CMN/PLL/REF CH0 | ||
| 79 | * | ||
| 80 | * port D == PCS/TX CH0 | ||
| 81 | * | ||
| 82 | * On BXT the entire PHY channel corresponds to the port. That means | ||
| 83 | * the PLL is also now associated with the port rather than the pipe, | ||
| 84 | * and so the clock needs to be routed to the appropriate transcoder. | ||
| 85 | * Port A PLL is directly connected to transcoder EDP and port B/C | ||
| 86 | * PLLs can be routed to any transcoder A/B/C. | ||
| 87 | * | ||
| 88 | * Note: DDI0 is digital port B, DD1 is digital port C, and DDI2 is | ||
| 89 | * digital port D (CHV) or port A (BXT). :: | ||
| 90 | * | ||
| 91 | * | ||
| 92 | * Dual channel PHY (VLV/CHV/BXT) | ||
| 93 | * --------------------------------- | ||
| 94 | * | CH0 | CH1 | | ||
| 95 | * | CMN/PLL/REF | CMN/PLL/REF | | ||
| 96 | * |---------------|---------------| Display PHY | ||
| 97 | * | PCS01 | PCS23 | PCS01 | PCS23 | | ||
| 98 | * |-------|-------|-------|-------| | ||
| 99 | * |TX0|TX1|TX2|TX3|TX0|TX1|TX2|TX3| | ||
| 100 | * --------------------------------- | ||
| 101 | * | DDI0 | DDI1 | DP/HDMI ports | ||
| 102 | * --------------------------------- | ||
| 103 | * | ||
| 104 | * Single channel PHY (CHV/BXT) | ||
| 105 | * ----------------- | ||
| 106 | * | CH0 | | ||
| 107 | * | CMN/PLL/REF | | ||
| 108 | * |---------------| Display PHY | ||
| 109 | * | PCS01 | PCS23 | | ||
| 110 | * |-------|-------| | ||
| 111 | * |TX0|TX1|TX2|TX3| | ||
| 112 | * ----------------- | ||
| 113 | * | DDI2 | DP/HDMI port | ||
| 114 | * ----------------- | ||
| 115 | */ | ||
| 116 | |||
| 117 | /** | ||
| 118 | * struct bxt_ddi_phy_info - Hold info for a broxton DDI phy | ||
| 119 | */ | ||
| 120 | struct bxt_ddi_phy_info { | ||
| 121 | /** | ||
| 122 | * @dual_channel: true if this phy has a second channel. | ||
| 123 | */ | ||
| 124 | bool dual_channel; | ||
| 125 | |||
| 126 | /** | ||
| 127 | * @rcomp_phy: If -1, indicates this phy has its own rcomp resistor. | ||
| 128 | * Otherwise the GRC value will be copied from the phy indicated by | ||
| 129 | * this field. | ||
| 130 | */ | ||
| 131 | enum dpio_phy rcomp_phy; | ||
| 132 | |||
| 133 | /** | ||
| 134 | * @channel: struct containing per channel information. | ||
| 135 | */ | ||
| 136 | struct { | ||
| 137 | /** | ||
| 138 | * @port: which port maps to this channel. | ||
| 139 | */ | ||
| 140 | enum port port; | ||
| 141 | } channel[2]; | ||
| 142 | }; | ||
| 143 | |||
| 144 | static const struct bxt_ddi_phy_info bxt_ddi_phy_info[] = { | ||
| 145 | [DPIO_PHY0] = { | ||
| 146 | .dual_channel = true, | ||
| 147 | .rcomp_phy = DPIO_PHY1, | ||
| 148 | |||
| 149 | .channel = { | ||
| 150 | [DPIO_CH0] = { .port = PORT_B }, | ||
| 151 | [DPIO_CH1] = { .port = PORT_C }, | ||
| 152 | } | ||
| 153 | }, | ||
| 154 | [DPIO_PHY1] = { | ||
| 155 | .dual_channel = false, | ||
| 156 | .rcomp_phy = -1, | ||
| 157 | |||
| 158 | .channel = { | ||
| 159 | [DPIO_CH0] = { .port = PORT_A }, | ||
| 160 | } | ||
| 161 | }, | ||
| 162 | }; | ||
| 163 | |||
| 164 | static u32 bxt_phy_port_mask(const struct bxt_ddi_phy_info *phy_info) | ||
| 165 | { | ||
| 166 | return (phy_info->dual_channel * BIT(phy_info->channel[DPIO_CH1].port)) | | ||
| 167 | BIT(phy_info->channel[DPIO_CH0].port); | ||
| 168 | } | ||
| 169 | |||
| 170 | void bxt_port_to_phy_channel(enum port port, | ||
| 171 | enum dpio_phy *phy, enum dpio_channel *ch) | ||
| 172 | { | ||
| 173 | const struct bxt_ddi_phy_info *phy_info; | ||
| 174 | int i; | ||
| 175 | |||
| 176 | for (i = 0; i < ARRAY_SIZE(bxt_ddi_phy_info); i++) { | ||
| 177 | phy_info = &bxt_ddi_phy_info[i]; | ||
| 178 | |||
| 179 | if (port == phy_info->channel[DPIO_CH0].port) { | ||
| 180 | *phy = i; | ||
| 181 | *ch = DPIO_CH0; | ||
| 182 | return; | ||
| 183 | } | ||
| 184 | |||
| 185 | if (phy_info->dual_channel && | ||
| 186 | port == phy_info->channel[DPIO_CH1].port) { | ||
| 187 | *phy = i; | ||
| 188 | *ch = DPIO_CH1; | ||
| 189 | return; | ||
| 190 | } | ||
| 191 | } | ||
| 192 | |||
| 193 | WARN(1, "PHY not found for PORT %c", port_name(port)); | ||
| 194 | *phy = DPIO_PHY0; | ||
| 195 | *ch = DPIO_CH0; | ||
| 196 | } | ||
| 197 | |||
| 198 | void bxt_ddi_phy_set_signal_level(struct drm_i915_private *dev_priv, | ||
| 199 | enum port port, u32 margin, u32 scale, | ||
| 200 | u32 enable, u32 deemphasis) | ||
| 201 | { | ||
| 202 | u32 val; | ||
| 203 | enum dpio_phy phy; | ||
| 204 | enum dpio_channel ch; | ||
| 205 | |||
| 206 | bxt_port_to_phy_channel(port, &phy, &ch); | ||
| 207 | |||
| 208 | /* | ||
| 209 | * While we write to the group register to program all lanes at once we | ||
| 210 | * can read only lane registers and we pick lanes 0/1 for that. | ||
| 211 | */ | ||
| 212 | val = I915_READ(BXT_PORT_PCS_DW10_LN01(phy, ch)); | ||
| 213 | val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT); | ||
| 214 | I915_WRITE(BXT_PORT_PCS_DW10_GRP(phy, ch), val); | ||
| 215 | |||
| 216 | val = I915_READ(BXT_PORT_TX_DW2_LN0(phy, ch)); | ||
| 217 | val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE); | ||
| 218 | val |= margin << MARGIN_000_SHIFT | scale << UNIQ_TRANS_SCALE_SHIFT; | ||
| 219 | I915_WRITE(BXT_PORT_TX_DW2_GRP(phy, ch), val); | ||
| 220 | |||
| 221 | val = I915_READ(BXT_PORT_TX_DW3_LN0(phy, ch)); | ||
| 222 | val &= ~SCALE_DCOMP_METHOD; | ||
| 223 | if (enable) | ||
| 224 | val |= SCALE_DCOMP_METHOD; | ||
| 225 | |||
| 226 | if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD)) | ||
| 227 | DRM_ERROR("Disabled scaling while ouniqetrangenmethod was set"); | ||
| 228 | |||
| 229 | I915_WRITE(BXT_PORT_TX_DW3_GRP(phy, ch), val); | ||
| 230 | |||
| 231 | val = I915_READ(BXT_PORT_TX_DW4_LN0(phy, ch)); | ||
| 232 | val &= ~DE_EMPHASIS; | ||
| 233 | val |= deemphasis << DEEMPH_SHIFT; | ||
| 234 | I915_WRITE(BXT_PORT_TX_DW4_GRP(phy, ch), val); | ||
| 235 | |||
| 236 | val = I915_READ(BXT_PORT_PCS_DW10_LN01(phy, ch)); | ||
| 237 | val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT; | ||
| 238 | I915_WRITE(BXT_PORT_PCS_DW10_GRP(phy, ch), val); | ||
| 239 | } | ||
| 240 | |||
| 241 | bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv, | ||
| 242 | enum dpio_phy phy) | ||
| 243 | { | ||
| 244 | const struct bxt_ddi_phy_info *phy_info = &bxt_ddi_phy_info[phy]; | ||
| 245 | enum port port; | ||
| 246 | |||
| 247 | if (!(I915_READ(BXT_P_CR_GT_DISP_PWRON) & GT_DISPLAY_POWER_ON(phy))) | ||
| 248 | return false; | ||
| 249 | |||
| 250 | if ((I915_READ(BXT_PORT_CL1CM_DW0(phy)) & | ||
| 251 | (PHY_POWER_GOOD | PHY_RESERVED)) != PHY_POWER_GOOD) { | ||
| 252 | DRM_DEBUG_DRIVER("DDI PHY %d powered, but power hasn't settled\n", | ||
| 253 | phy); | ||
| 254 | |||
| 255 | return false; | ||
| 256 | } | ||
| 257 | |||
| 258 | if (phy_info->rcomp_phy == -1 && | ||
| 259 | !(I915_READ(BXT_PORT_REF_DW3(phy)) & GRC_DONE)) { | ||
| 260 | DRM_DEBUG_DRIVER("DDI PHY %d powered, but GRC isn't done\n", | ||
| 261 | phy); | ||
| 262 | |||
| 263 | return false; | ||
| 264 | } | ||
| 265 | |||
| 266 | if (!(I915_READ(BXT_PHY_CTL_FAMILY(phy)) & COMMON_RESET_DIS)) { | ||
| 267 | DRM_DEBUG_DRIVER("DDI PHY %d powered, but still in reset\n", | ||
| 268 | phy); | ||
| 269 | |||
| 270 | return false; | ||
| 271 | } | ||
| 272 | |||
| 273 | for_each_port_masked(port, bxt_phy_port_mask(phy_info)) { | ||
| 274 | u32 tmp = I915_READ(BXT_PHY_CTL(port)); | ||
| 275 | |||
| 276 | if (tmp & BXT_PHY_CMNLANE_POWERDOWN_ACK) { | ||
| 277 | DRM_DEBUG_DRIVER("DDI PHY %d powered, but common lane " | ||
| 278 | "for port %c powered down " | ||
| 279 | "(PHY_CTL %08x)\n", | ||
| 280 | phy, port_name(port), tmp); | ||
| 281 | |||
| 282 | return false; | ||
| 283 | } | ||
| 284 | } | ||
| 285 | |||
| 286 | return true; | ||
| 287 | } | ||
| 288 | |||
| 289 | static u32 bxt_get_grc(struct drm_i915_private *dev_priv, enum dpio_phy phy) | ||
| 290 | { | ||
| 291 | u32 val = I915_READ(BXT_PORT_REF_DW6(phy)); | ||
| 292 | |||
| 293 | return (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT; | ||
| 294 | } | ||
| 295 | |||
| 296 | static void bxt_phy_wait_grc_done(struct drm_i915_private *dev_priv, | ||
| 297 | enum dpio_phy phy) | ||
| 298 | { | ||
| 299 | if (intel_wait_for_register(dev_priv, | ||
| 300 | BXT_PORT_REF_DW3(phy), | ||
| 301 | GRC_DONE, GRC_DONE, | ||
| 302 | 10)) | ||
| 303 | DRM_ERROR("timeout waiting for PHY%d GRC\n", phy); | ||
| 304 | } | ||
| 305 | |||
| 306 | static void _bxt_ddi_phy_init(struct drm_i915_private *dev_priv, | ||
| 307 | enum dpio_phy phy) | ||
| 308 | { | ||
| 309 | const struct bxt_ddi_phy_info *phy_info = &bxt_ddi_phy_info[phy]; | ||
| 310 | u32 val; | ||
| 311 | |||
| 312 | if (bxt_ddi_phy_is_enabled(dev_priv, phy)) { | ||
| 313 | /* Still read out the GRC value for state verification */ | ||
| 314 | if (phy_info->rcomp_phy != -1) | ||
| 315 | dev_priv->bxt_phy_grc = bxt_get_grc(dev_priv, phy); | ||
| 316 | |||
| 317 | if (bxt_ddi_phy_verify_state(dev_priv, phy)) { | ||
| 318 | DRM_DEBUG_DRIVER("DDI PHY %d already enabled, " | ||
| 319 | "won't reprogram it\n", phy); | ||
| 320 | |||
| 321 | return; | ||
| 322 | } | ||
| 323 | |||
| 324 | DRM_DEBUG_DRIVER("DDI PHY %d enabled with invalid state, " | ||
| 325 | "force reprogramming it\n", phy); | ||
| 326 | } | ||
| 327 | |||
| 328 | val = I915_READ(BXT_P_CR_GT_DISP_PWRON); | ||
| 329 | val |= GT_DISPLAY_POWER_ON(phy); | ||
| 330 | I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val); | ||
| 331 | |||
| 332 | /* | ||
| 333 | * The PHY registers start out inaccessible and respond to reads with | ||
| 334 | * all 1s. Eventually they become accessible as they power up, then | ||
| 335 | * the reserved bit will give the default 0. Poll on the reserved bit | ||
| 336 | * becoming 0 to find when the PHY is accessible. | ||
| 337 | * HW team confirmed that the time to reach phypowergood status is | ||
| 338 | * anywhere between 50 us and 100us. | ||
| 339 | */ | ||
| 340 | if (wait_for_us(((I915_READ(BXT_PORT_CL1CM_DW0(phy)) & | ||
| 341 | (PHY_RESERVED | PHY_POWER_GOOD)) == PHY_POWER_GOOD), 100)) { | ||
| 342 | DRM_ERROR("timeout during PHY%d power on\n", phy); | ||
| 343 | } | ||
| 344 | |||
| 345 | /* Program PLL Rcomp code offset */ | ||
| 346 | val = I915_READ(BXT_PORT_CL1CM_DW9(phy)); | ||
| 347 | val &= ~IREF0RC_OFFSET_MASK; | ||
| 348 | val |= 0xE4 << IREF0RC_OFFSET_SHIFT; | ||
| 349 | I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val); | ||
| 350 | |||
| 351 | val = I915_READ(BXT_PORT_CL1CM_DW10(phy)); | ||
| 352 | val &= ~IREF1RC_OFFSET_MASK; | ||
| 353 | val |= 0xE4 << IREF1RC_OFFSET_SHIFT; | ||
| 354 | I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val); | ||
| 355 | |||
| 356 | /* Program power gating */ | ||
| 357 | val = I915_READ(BXT_PORT_CL1CM_DW28(phy)); | ||
| 358 | val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN | | ||
| 359 | SUS_CLK_CONFIG; | ||
| 360 | I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val); | ||
| 361 | |||
| 362 | if (phy_info->dual_channel) { | ||
| 363 | val = I915_READ(BXT_PORT_CL2CM_DW6(phy)); | ||
| 364 | val |= DW6_OLDO_DYN_PWR_DOWN_EN; | ||
| 365 | I915_WRITE(BXT_PORT_CL2CM_DW6(phy), val); | ||
| 366 | } | ||
| 367 | |||
| 368 | if (phy_info->rcomp_phy != -1) { | ||
| 369 | uint32_t grc_code; | ||
| 370 | /* | ||
| 371 | * PHY0 isn't connected to an RCOMP resistor so copy over | ||
| 372 | * the corresponding calibrated value from PHY1, and disable | ||
| 373 | * the automatic calibration on PHY0. | ||
| 374 | */ | ||
| 375 | val = dev_priv->bxt_phy_grc = bxt_get_grc(dev_priv, | ||
| 376 | phy_info->rcomp_phy); | ||
| 377 | grc_code = val << GRC_CODE_FAST_SHIFT | | ||
| 378 | val << GRC_CODE_SLOW_SHIFT | | ||
| 379 | val; | ||
| 380 | I915_WRITE(BXT_PORT_REF_DW6(phy), grc_code); | ||
| 381 | |||
| 382 | val = I915_READ(BXT_PORT_REF_DW8(phy)); | ||
| 383 | val |= GRC_DIS | GRC_RDY_OVRD; | ||
| 384 | I915_WRITE(BXT_PORT_REF_DW8(phy), val); | ||
| 385 | } | ||
| 386 | |||
| 387 | val = I915_READ(BXT_PHY_CTL_FAMILY(phy)); | ||
| 388 | val |= COMMON_RESET_DIS; | ||
| 389 | I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val); | ||
| 390 | |||
| 391 | if (phy_info->rcomp_phy == -1) | ||
| 392 | bxt_phy_wait_grc_done(dev_priv, phy); | ||
| 393 | |||
| 394 | } | ||
| 395 | |||
| 396 | void bxt_ddi_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy) | ||
| 397 | { | ||
| 398 | uint32_t val; | ||
| 399 | |||
| 400 | val = I915_READ(BXT_PHY_CTL_FAMILY(phy)); | ||
| 401 | val &= ~COMMON_RESET_DIS; | ||
| 402 | I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val); | ||
| 403 | |||
| 404 | val = I915_READ(BXT_P_CR_GT_DISP_PWRON); | ||
| 405 | val &= ~GT_DISPLAY_POWER_ON(phy); | ||
| 406 | I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val); | ||
| 407 | } | ||
| 408 | |||
| 409 | void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy) | ||
| 410 | { | ||
| 411 | const struct bxt_ddi_phy_info *phy_info = &bxt_ddi_phy_info[phy]; | ||
| 412 | enum dpio_phy rcomp_phy = phy_info->rcomp_phy; | ||
| 413 | bool was_enabled; | ||
| 414 | |||
| 415 | lockdep_assert_held(&dev_priv->power_domains.lock); | ||
| 416 | |||
| 417 | if (rcomp_phy != -1) { | ||
| 418 | was_enabled = bxt_ddi_phy_is_enabled(dev_priv, rcomp_phy); | ||
| 419 | |||
| 420 | /* | ||
| 421 | * We need to copy the GRC calibration value from rcomp_phy, | ||
| 422 | * so make sure it's powered up. | ||
| 423 | */ | ||
| 424 | if (!was_enabled) | ||
| 425 | _bxt_ddi_phy_init(dev_priv, rcomp_phy); | ||
| 426 | } | ||
| 427 | |||
| 428 | _bxt_ddi_phy_init(dev_priv, phy); | ||
| 429 | |||
| 430 | if (rcomp_phy != -1 && !was_enabled) | ||
| 431 | bxt_ddi_phy_uninit(dev_priv, phy_info->rcomp_phy); | ||
| 432 | } | ||
| 433 | |||
| 434 | static bool __printf(6, 7) | ||
| 435 | __phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy, | ||
| 436 | i915_reg_t reg, u32 mask, u32 expected, | ||
| 437 | const char *reg_fmt, ...) | ||
| 438 | { | ||
| 439 | struct va_format vaf; | ||
| 440 | va_list args; | ||
| 441 | u32 val; | ||
| 442 | |||
| 443 | val = I915_READ(reg); | ||
| 444 | if ((val & mask) == expected) | ||
| 445 | return true; | ||
| 446 | |||
| 447 | va_start(args, reg_fmt); | ||
| 448 | vaf.fmt = reg_fmt; | ||
| 449 | vaf.va = &args; | ||
| 450 | |||
| 451 | DRM_DEBUG_DRIVER("DDI PHY %d reg %pV [%08x] state mismatch: " | ||
| 452 | "current %08x, expected %08x (mask %08x)\n", | ||
| 453 | phy, &vaf, reg.reg, val, (val & ~mask) | expected, | ||
| 454 | mask); | ||
| 455 | |||
| 456 | va_end(args); | ||
| 457 | |||
| 458 | return false; | ||
| 459 | } | ||
| 460 | |||
| 461 | bool bxt_ddi_phy_verify_state(struct drm_i915_private *dev_priv, | ||
| 462 | enum dpio_phy phy) | ||
| 463 | { | ||
| 464 | const struct bxt_ddi_phy_info *phy_info = &bxt_ddi_phy_info[phy]; | ||
| 465 | uint32_t mask; | ||
| 466 | bool ok; | ||
| 467 | |||
| 468 | #define _CHK(reg, mask, exp, fmt, ...) \ | ||
| 469 | __phy_reg_verify_state(dev_priv, phy, reg, mask, exp, fmt, \ | ||
| 470 | ## __VA_ARGS__) | ||
| 471 | |||
| 472 | if (!bxt_ddi_phy_is_enabled(dev_priv, phy)) | ||
| 473 | return false; | ||
| 474 | |||
| 475 | ok = true; | ||
| 476 | |||
| 477 | /* PLL Rcomp code offset */ | ||
| 478 | ok &= _CHK(BXT_PORT_CL1CM_DW9(phy), | ||
| 479 | IREF0RC_OFFSET_MASK, 0xe4 << IREF0RC_OFFSET_SHIFT, | ||
| 480 | "BXT_PORT_CL1CM_DW9(%d)", phy); | ||
| 481 | ok &= _CHK(BXT_PORT_CL1CM_DW10(phy), | ||
| 482 | IREF1RC_OFFSET_MASK, 0xe4 << IREF1RC_OFFSET_SHIFT, | ||
| 483 | "BXT_PORT_CL1CM_DW10(%d)", phy); | ||
| 484 | |||
| 485 | /* Power gating */ | ||
| 486 | mask = OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN | SUS_CLK_CONFIG; | ||
| 487 | ok &= _CHK(BXT_PORT_CL1CM_DW28(phy), mask, mask, | ||
| 488 | "BXT_PORT_CL1CM_DW28(%d)", phy); | ||
| 489 | |||
| 490 | if (phy_info->dual_channel) | ||
| 491 | ok &= _CHK(BXT_PORT_CL2CM_DW6(phy), | ||
| 492 | DW6_OLDO_DYN_PWR_DOWN_EN, DW6_OLDO_DYN_PWR_DOWN_EN, | ||
| 493 | "BXT_PORT_CL2CM_DW6(%d)", phy); | ||
| 494 | |||
| 495 | if (phy_info->rcomp_phy != -1) { | ||
| 496 | u32 grc_code = dev_priv->bxt_phy_grc; | ||
| 497 | |||
| 498 | grc_code = grc_code << GRC_CODE_FAST_SHIFT | | ||
| 499 | grc_code << GRC_CODE_SLOW_SHIFT | | ||
| 500 | grc_code; | ||
| 501 | mask = GRC_CODE_FAST_MASK | GRC_CODE_SLOW_MASK | | ||
| 502 | GRC_CODE_NOM_MASK; | ||
| 503 | ok &= _CHK(BXT_PORT_REF_DW6(phy), mask, grc_code, | ||
| 504 | "BXT_PORT_REF_DW6(%d)", phy); | ||
| 505 | |||
| 506 | mask = GRC_DIS | GRC_RDY_OVRD; | ||
| 507 | ok &= _CHK(BXT_PORT_REF_DW8(phy), mask, mask, | ||
| 508 | "BXT_PORT_REF_DW8(%d)", phy); | ||
| 509 | } | ||
| 510 | |||
| 511 | return ok; | ||
| 512 | #undef _CHK | ||
| 513 | } | ||
| 514 | |||
| 515 | uint8_t | ||
| 516 | bxt_ddi_phy_calc_lane_lat_optim_mask(struct intel_encoder *encoder, | ||
| 517 | uint8_t lane_count) | ||
| 518 | { | ||
| 519 | switch (lane_count) { | ||
| 520 | case 1: | ||
| 521 | return 0; | ||
| 522 | case 2: | ||
| 523 | return BIT(2) | BIT(0); | ||
| 524 | case 4: | ||
| 525 | return BIT(3) | BIT(2) | BIT(0); | ||
| 526 | default: | ||
| 527 | MISSING_CASE(lane_count); | ||
| 528 | |||
| 529 | return 0; | ||
| 530 | } | ||
| 531 | } | ||
| 532 | |||
| 533 | void bxt_ddi_phy_set_lane_optim_mask(struct intel_encoder *encoder, | ||
| 534 | uint8_t lane_lat_optim_mask) | ||
| 535 | { | ||
| 536 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); | ||
| 537 | struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev); | ||
| 538 | enum port port = dport->port; | ||
| 539 | enum dpio_phy phy; | ||
| 540 | enum dpio_channel ch; | ||
| 541 | int lane; | ||
| 542 | |||
| 543 | bxt_port_to_phy_channel(port, &phy, &ch); | ||
| 544 | |||
| 545 | for (lane = 0; lane < 4; lane++) { | ||
| 546 | u32 val = I915_READ(BXT_PORT_TX_DW14_LN(phy, ch, lane)); | ||
| 547 | |||
| 548 | /* | ||
| 549 | * Note that on CHV this flag is called UPAR, but has | ||
| 550 | * the same function. | ||
| 551 | */ | ||
| 552 | val &= ~LATENCY_OPTIM; | ||
| 553 | if (lane_lat_optim_mask & BIT(lane)) | ||
| 554 | val |= LATENCY_OPTIM; | ||
| 555 | |||
| 556 | I915_WRITE(BXT_PORT_TX_DW14_LN(phy, ch, lane), val); | ||
| 557 | } | ||
| 558 | } | ||
| 559 | |||
| 560 | uint8_t | ||
| 561 | bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder) | ||
| 562 | { | ||
| 563 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); | ||
| 564 | struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev); | ||
| 565 | enum port port = dport->port; | ||
| 566 | enum dpio_phy phy; | ||
| 567 | enum dpio_channel ch; | ||
| 568 | int lane; | ||
| 569 | uint8_t mask; | ||
| 570 | |||
| 571 | bxt_port_to_phy_channel(port, &phy, &ch); | ||
| 572 | |||
| 573 | mask = 0; | ||
| 574 | for (lane = 0; lane < 4; lane++) { | ||
| 575 | u32 val = I915_READ(BXT_PORT_TX_DW14_LN(phy, ch, lane)); | ||
| 576 | |||
| 577 | if (val & LATENCY_OPTIM) | ||
| 578 | mask |= BIT(lane); | ||
| 579 | } | ||
| 580 | |||
| 581 | return mask; | ||
| 582 | } | ||
| 583 | |||
| 584 | |||
| 26 | void chv_set_phy_signal_level(struct intel_encoder *encoder, | 585 | void chv_set_phy_signal_level(struct intel_encoder *encoder, |
| 27 | u32 deemph_reg_value, u32 margin_reg_value, | 586 | u32 deemph_reg_value, u32 margin_reg_value, |
| 28 | bool uniq_trans_scale) | 587 | bool uniq_trans_scale) |
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 605d0b509f24..21853a17b6d9 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c | |||
| @@ -1371,6 +1371,10 @@ static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv, | |||
| 1371 | { | 1371 | { |
| 1372 | uint32_t temp; | 1372 | uint32_t temp; |
| 1373 | enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */ | 1373 | enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */ |
| 1374 | enum dpio_phy phy; | ||
| 1375 | enum dpio_channel ch; | ||
| 1376 | |||
| 1377 | bxt_port_to_phy_channel(port, &phy, &ch); | ||
| 1374 | 1378 | ||
| 1375 | /* Non-SSC reference */ | 1379 | /* Non-SSC reference */ |
| 1376 | temp = I915_READ(BXT_PORT_PLL_ENABLE(port)); | 1380 | temp = I915_READ(BXT_PORT_PLL_ENABLE(port)); |
| @@ -1378,72 +1382,72 @@ static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv, | |||
| 1378 | I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp); | 1382 | I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp); |
| 1379 | 1383 | ||
| 1380 | /* Disable 10 bit clock */ | 1384 | /* Disable 10 bit clock */ |
| 1381 | temp = I915_READ(BXT_PORT_PLL_EBB_4(port)); | 1385 | temp = I915_READ(BXT_PORT_PLL_EBB_4(phy, ch)); |
| 1382 | temp &= ~PORT_PLL_10BIT_CLK_ENABLE; | 1386 | temp &= ~PORT_PLL_10BIT_CLK_ENABLE; |
| 1383 | I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp); | 1387 | I915_WRITE(BXT_PORT_PLL_EBB_4(phy, ch), temp); |
| 1384 | 1388 | ||
| 1385 | /* Write P1 & P2 */ | 1389 | /* Write P1 & P2 */ |
| 1386 | temp = I915_READ(BXT_PORT_PLL_EBB_0(port)); | 1390 | temp = I915_READ(BXT_PORT_PLL_EBB_0(phy, ch)); |
| 1387 | temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK); | 1391 | temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK); |
| 1388 | temp |= pll->config.hw_state.ebb0; | 1392 | temp |= pll->config.hw_state.ebb0; |
| 1389 | I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp); | 1393 | I915_WRITE(BXT_PORT_PLL_EBB_0(phy, ch), temp); |
| 1390 | 1394 | ||
| 1391 | /* Write M2 integer */ | 1395 | /* Write M2 integer */ |
| 1392 | temp = I915_READ(BXT_PORT_PLL(port, 0)); | 1396 | temp = I915_READ(BXT_PORT_PLL(phy, ch, 0)); |
| 1393 | temp &= ~PORT_PLL_M2_MASK; | 1397 | temp &= ~PORT_PLL_M2_MASK; |
| 1394 | temp |= pll->config.hw_state.pll0; | 1398 | temp |= pll->config.hw_state.pll0; |
| 1395 | I915_WRITE(BXT_PORT_PLL(port, 0), temp); | 1399 | I915_WRITE(BXT_PORT_PLL(phy, ch, 0), temp); |
| 1396 | 1400 | ||
| 1397 | /* Write N */ | 1401 | /* Write N */ |
| 1398 | temp = I915_READ(BXT_PORT_PLL(port, 1)); | 1402 | temp = I915_READ(BXT_PORT_PLL(phy, ch, 1)); |
| 1399 | temp &= ~PORT_PLL_N_MASK; | 1403 | temp &= ~PORT_PLL_N_MASK; |
| 1400 | temp |= pll->config.hw_state.pll1; | 1404 | temp |= pll->config.hw_state.pll1; |
| 1401 | I915_WRITE(BXT_PORT_PLL(port, 1), temp); | 1405 | I915_WRITE(BXT_PORT_PLL(phy, ch, 1), temp); |
| 1402 | 1406 | ||
| 1403 | /* Write M2 fraction */ | 1407 | /* Write M2 fraction */ |
| 1404 | temp = I915_READ(BXT_PORT_PLL(port, 2)); | 1408 | temp = I915_READ(BXT_PORT_PLL(phy, ch, 2)); |
| 1405 | temp &= ~PORT_PLL_M2_FRAC_MASK; | 1409 | temp &= ~PORT_PLL_M2_FRAC_MASK; |
| 1406 | temp |= pll->config.hw_state.pll2; | 1410 | temp |= pll->config.hw_state.pll2; |
| 1407 | I915_WRITE(BXT_PORT_PLL(port, 2), temp); | 1411 | I915_WRITE(BXT_PORT_PLL(phy, ch, 2), temp); |
| 1408 | 1412 | ||
| 1409 | /* Write M2 fraction enable */ | 1413 | /* Write M2 fraction enable */ |
| 1410 | temp = I915_READ(BXT_PORT_PLL(port, 3)); | 1414 | temp = I915_READ(BXT_PORT_PLL(phy, ch, 3)); |
| 1411 | temp &= ~PORT_PLL_M2_FRAC_ENABLE; | 1415 | temp &= ~PORT_PLL_M2_FRAC_ENABLE; |
| 1412 | temp |= pll->config.hw_state.pll3; | 1416 | temp |= pll->config.hw_state.pll3; |
| 1413 | I915_WRITE(BXT_PORT_PLL(port, 3), temp); | 1417 | I915_WRITE(BXT_PORT_PLL(phy, ch, 3), temp); |
| 1414 | 1418 | ||
| 1415 | /* Write coeff */ | 1419 | /* Write coeff */ |
| 1416 | temp = I915_READ(BXT_PORT_PLL(port, 6)); | 1420 | temp = I915_READ(BXT_PORT_PLL(phy, ch, 6)); |
| 1417 | temp &= ~PORT_PLL_PROP_COEFF_MASK; | 1421 | temp &= ~PORT_PLL_PROP_COEFF_MASK; |
| 1418 | temp &= ~PORT_PLL_INT_COEFF_MASK; | 1422 | temp &= ~PORT_PLL_INT_COEFF_MASK; |
| 1419 | temp &= ~PORT_PLL_GAIN_CTL_MASK; | 1423 | temp &= ~PORT_PLL_GAIN_CTL_MASK; |
| 1420 | temp |= pll->config.hw_state.pll6; | 1424 | temp |= pll->config.hw_state.pll6; |
| 1421 | I915_WRITE(BXT_PORT_PLL(port, 6), temp); | 1425 | I915_WRITE(BXT_PORT_PLL(phy, ch, 6), temp); |
| 1422 | 1426 | ||
| 1423 | /* Write calibration val */ | 1427 | /* Write calibration val */ |
| 1424 | temp = I915_READ(BXT_PORT_PLL(port, 8)); | 1428 | temp = I915_READ(BXT_PORT_PLL(phy, ch, 8)); |
| 1425 | temp &= ~PORT_PLL_TARGET_CNT_MASK; | 1429 | temp &= ~PORT_PLL_TARGET_CNT_MASK; |
| 1426 | temp |= pll->config.hw_state.pll8; | 1430 | temp |= pll->config.hw_state.pll8; |
| 1427 | I915_WRITE(BXT_PORT_PLL(port, 8), temp); | 1431 | I915_WRITE(BXT_PORT_PLL(phy, ch, 8), temp); |
| 1428 | 1432 | ||
| 1429 | temp = I915_READ(BXT_PORT_PLL(port, 9)); | 1433 | temp = I915_READ(BXT_PORT_PLL(phy, ch, 9)); |
| 1430 | temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK; | 1434 | temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK; |
| 1431 | temp |= pll->config.hw_state.pll9; | 1435 | temp |= pll->config.hw_state.pll9; |
| 1432 | I915_WRITE(BXT_PORT_PLL(port, 9), temp); | 1436 | I915_WRITE(BXT_PORT_PLL(phy, ch, 9), temp); |
| 1433 | 1437 | ||
| 1434 | temp = I915_READ(BXT_PORT_PLL(port, 10)); | 1438 | temp = I915_READ(BXT_PORT_PLL(phy, ch, 10)); |
| 1435 | temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H; | 1439 | temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H; |
| 1436 | temp &= ~PORT_PLL_DCO_AMP_MASK; | 1440 | temp &= ~PORT_PLL_DCO_AMP_MASK; |
| 1437 | temp |= pll->config.hw_state.pll10; | 1441 | temp |= pll->config.hw_state.pll10; |
| 1438 | I915_WRITE(BXT_PORT_PLL(port, 10), temp); | 1442 | I915_WRITE(BXT_PORT_PLL(phy, ch, 10), temp); |
| 1439 | 1443 | ||
| 1440 | /* Recalibrate with new settings */ | 1444 | /* Recalibrate with new settings */ |
| 1441 | temp = I915_READ(BXT_PORT_PLL_EBB_4(port)); | 1445 | temp = I915_READ(BXT_PORT_PLL_EBB_4(phy, ch)); |
| 1442 | temp |= PORT_PLL_RECALIBRATE; | 1446 | temp |= PORT_PLL_RECALIBRATE; |
| 1443 | I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp); | 1447 | I915_WRITE(BXT_PORT_PLL_EBB_4(phy, ch), temp); |
| 1444 | temp &= ~PORT_PLL_10BIT_CLK_ENABLE; | 1448 | temp &= ~PORT_PLL_10BIT_CLK_ENABLE; |
| 1445 | temp |= pll->config.hw_state.ebb4; | 1449 | temp |= pll->config.hw_state.ebb4; |
| 1446 | I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp); | 1450 | I915_WRITE(BXT_PORT_PLL_EBB_4(phy, ch), temp); |
| 1447 | 1451 | ||
| 1448 | /* Enable PLL */ | 1452 | /* Enable PLL */ |
| 1449 | temp = I915_READ(BXT_PORT_PLL_ENABLE(port)); | 1453 | temp = I915_READ(BXT_PORT_PLL_ENABLE(port)); |
| @@ -1459,11 +1463,11 @@ static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv, | |||
| 1459 | * While we write to the group register to program all lanes at once we | 1463 | * While we write to the group register to program all lanes at once we |
| 1460 | * can read only lane registers and we pick lanes 0/1 for that. | 1464 | * can read only lane registers and we pick lanes 0/1 for that. |
| 1461 | */ | 1465 | */ |
| 1462 | temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port)); | 1466 | temp = I915_READ(BXT_PORT_PCS_DW12_LN01(phy, ch)); |
| 1463 | temp &= ~LANE_STAGGER_MASK; | 1467 | temp &= ~LANE_STAGGER_MASK; |
| 1464 | temp &= ~LANESTAGGER_STRAP_OVRD; | 1468 | temp &= ~LANESTAGGER_STRAP_OVRD; |
| 1465 | temp |= pll->config.hw_state.pcsdw12; | 1469 | temp |= pll->config.hw_state.pcsdw12; |
| 1466 | I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp); | 1470 | I915_WRITE(BXT_PORT_PCS_DW12_GRP(phy, ch), temp); |
| 1467 | } | 1471 | } |
| 1468 | 1472 | ||
| 1469 | static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv, | 1473 | static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv, |
| @@ -1485,6 +1489,10 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, | |||
| 1485 | enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */ | 1489 | enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */ |
| 1486 | uint32_t val; | 1490 | uint32_t val; |
| 1487 | bool ret; | 1491 | bool ret; |
| 1492 | enum dpio_phy phy; | ||
| 1493 | enum dpio_channel ch; | ||
| 1494 | |||
| 1495 | bxt_port_to_phy_channel(port, &phy, &ch); | ||
| 1488 | 1496 | ||
| 1489 | if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) | 1497 | if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) |
| 1490 | return false; | 1498 | return false; |
| @@ -1495,36 +1503,36 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, | |||
| 1495 | if (!(val & PORT_PLL_ENABLE)) | 1503 | if (!(val & PORT_PLL_ENABLE)) |
| 1496 | goto out; | 1504 | goto out; |
| 1497 | 1505 | ||
| 1498 | hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port)); | 1506 | hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(phy, ch)); |
| 1499 | hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK; | 1507 | hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK; |
| 1500 | 1508 | ||
| 1501 | hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port)); | 1509 | hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(phy, ch)); |
| 1502 | hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE; | 1510 | hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE; |
| 1503 | 1511 | ||
| 1504 | hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0)); | 1512 | hw_state->pll0 = I915_READ(BXT_PORT_PLL(phy, ch, 0)); |
| 1505 | hw_state->pll0 &= PORT_PLL_M2_MASK; | 1513 | hw_state->pll0 &= PORT_PLL_M2_MASK; |
| 1506 | 1514 | ||
| 1507 | hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1)); | 1515 | hw_state->pll1 = I915_READ(BXT_PORT_PLL(phy, ch, 1)); |
| 1508 | hw_state->pll1 &= PORT_PLL_N_MASK; | 1516 | hw_state->pll1 &= PORT_PLL_N_MASK; |
| 1509 | 1517 | ||
| 1510 | hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2)); | 1518 | hw_state->pll2 = I915_READ(BXT_PORT_PLL(phy, ch, 2)); |
| 1511 | hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK; | 1519 | hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK; |
| 1512 | 1520 | ||
| 1513 | hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3)); | 1521 | hw_state->pll3 = I915_READ(BXT_PORT_PLL(phy, ch, 3)); |
| 1514 | hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE; | 1522 | hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE; |
| 1515 | 1523 | ||
| 1516 | hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6)); | 1524 | hw_state->pll6 = I915_READ(BXT_PORT_PLL(phy, ch, 6)); |
| 1517 | hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK | | 1525 | hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK | |
| 1518 | PORT_PLL_INT_COEFF_MASK | | 1526 | PORT_PLL_INT_COEFF_MASK | |
| 1519 | PORT_PLL_GAIN_CTL_MASK; | 1527 | PORT_PLL_GAIN_CTL_MASK; |
| 1520 | 1528 | ||
| 1521 | hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8)); | 1529 | hw_state->pll8 = I915_READ(BXT_PORT_PLL(phy, ch, 8)); |
| 1522 | hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK; | 1530 | hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK; |
| 1523 | 1531 | ||
| 1524 | hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9)); | 1532 | hw_state->pll9 = I915_READ(BXT_PORT_PLL(phy, ch, 9)); |
| 1525 | hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK; | 1533 | hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK; |
| 1526 | 1534 | ||
| 1527 | hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10)); | 1535 | hw_state->pll10 = I915_READ(BXT_PORT_PLL(phy, ch, 10)); |
| 1528 | hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H | | 1536 | hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H | |
| 1529 | PORT_PLL_DCO_AMP_MASK; | 1537 | PORT_PLL_DCO_AMP_MASK; |
| 1530 | 1538 | ||
| @@ -1533,11 +1541,11 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, | |||
| 1533 | * can read only lane registers. We configure all lanes the same way, so | 1541 | * can read only lane registers. We configure all lanes the same way, so |
| 1534 | * here just read out lanes 0/1 and output a note if lanes 2/3 differ. | 1542 | * here just read out lanes 0/1 and output a note if lanes 2/3 differ. |
| 1535 | */ | 1543 | */ |
| 1536 | hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port)); | 1544 | hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(phy, ch)); |
| 1537 | if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12) | 1545 | if (I915_READ(BXT_PORT_PCS_DW12_LN23(phy, ch)) != hw_state->pcsdw12) |
| 1538 | DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n", | 1546 | DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n", |
| 1539 | hw_state->pcsdw12, | 1547 | hw_state->pcsdw12, |
| 1540 | I915_READ(BXT_PORT_PCS_DW12_LN23(port))); | 1548 | I915_READ(BXT_PORT_PCS_DW12_LN23(phy, ch))); |
| 1541 | hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD; | 1549 | hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD; |
| 1542 | 1550 | ||
| 1543 | ret = true; | 1551 | ret = true; |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4e90b0760f3f..398195bf6dd1 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -365,6 +365,8 @@ struct intel_atomic_state { | |||
| 365 | 365 | ||
| 366 | /* Gen9+ only */ | 366 | /* Gen9+ only */ |
| 367 | struct skl_wm_values wm_results; | 367 | struct skl_wm_values wm_results; |
| 368 | |||
| 369 | struct i915_sw_fence commit_ready; | ||
| 368 | }; | 370 | }; |
| 369 | 371 | ||
| 370 | struct intel_plane_state { | 372 | struct intel_plane_state { |
| @@ -401,9 +403,6 @@ struct intel_plane_state { | |||
| 401 | int scaler_id; | 403 | int scaler_id; |
| 402 | 404 | ||
| 403 | struct drm_intel_sprite_colorkey ckey; | 405 | struct drm_intel_sprite_colorkey ckey; |
| 404 | |||
| 405 | /* async flip related structures */ | ||
| 406 | struct drm_i915_gem_request *wait_req; | ||
| 407 | }; | 406 | }; |
| 408 | 407 | ||
| 409 | struct intel_initial_plane_config { | 408 | struct intel_initial_plane_config { |
| @@ -501,14 +500,6 @@ struct intel_crtc_wm_state { | |||
| 501 | /* gen9+ only needs 1-step wm programming */ | 500 | /* gen9+ only needs 1-step wm programming */ |
| 502 | struct skl_pipe_wm optimal; | 501 | struct skl_pipe_wm optimal; |
| 503 | struct skl_ddb_entry ddb; | 502 | struct skl_ddb_entry ddb; |
| 504 | |||
| 505 | /* cached plane data rate */ | ||
| 506 | unsigned plane_data_rate[I915_MAX_PLANES]; | ||
| 507 | unsigned plane_y_data_rate[I915_MAX_PLANES]; | ||
| 508 | |||
| 509 | /* minimum block allocation */ | ||
| 510 | uint16_t minimum_blocks[I915_MAX_PLANES]; | ||
| 511 | uint16_t minimum_y_blocks[I915_MAX_PLANES]; | ||
| 512 | } skl; | 503 | } skl; |
| 513 | }; | 504 | }; |
| 514 | 505 | ||
| @@ -731,7 +722,6 @@ struct intel_crtc { | |||
| 731 | /* watermarks currently being used */ | 722 | /* watermarks currently being used */ |
| 732 | union { | 723 | union { |
| 733 | struct intel_pipe_wm ilk; | 724 | struct intel_pipe_wm ilk; |
| 734 | struct skl_pipe_wm skl; | ||
| 735 | } active; | 725 | } active; |
| 736 | 726 | ||
| 737 | /* allow CxSR on this pipe */ | 727 | /* allow CxSR on this pipe */ |
| @@ -883,6 +873,14 @@ enum link_m_n_set { | |||
| 883 | M2_N2 | 873 | M2_N2 |
| 884 | }; | 874 | }; |
| 885 | 875 | ||
| 876 | struct intel_dp_desc { | ||
| 877 | u8 oui[3]; | ||
| 878 | u8 device_id[6]; | ||
| 879 | u8 hw_rev; | ||
| 880 | u8 sw_major_rev; | ||
| 881 | u8 sw_minor_rev; | ||
| 882 | } __packed; | ||
| 883 | |||
| 886 | struct intel_dp { | 884 | struct intel_dp { |
| 887 | i915_reg_t output_reg; | 885 | i915_reg_t output_reg; |
| 888 | i915_reg_t aux_ch_ctl_reg; | 886 | i915_reg_t aux_ch_ctl_reg; |
| @@ -905,6 +903,8 @@ struct intel_dp { | |||
| 905 | /* sink rates as reported by DP_SUPPORTED_LINK_RATES */ | 903 | /* sink rates as reported by DP_SUPPORTED_LINK_RATES */ |
| 906 | uint8_t num_sink_rates; | 904 | uint8_t num_sink_rates; |
| 907 | int sink_rates[DP_MAX_SUPPORTED_RATES]; | 905 | int sink_rates[DP_MAX_SUPPORTED_RATES]; |
| 906 | /* sink or branch descriptor */ | ||
| 907 | struct intel_dp_desc desc; | ||
| 908 | struct drm_dp_aux aux; | 908 | struct drm_dp_aux aux; |
| 909 | uint8_t train_set[4]; | 909 | uint8_t train_set[4]; |
| 910 | int panel_power_up_delay; | 910 | int panel_power_up_delay; |
| @@ -964,7 +964,7 @@ struct intel_dp { | |||
| 964 | struct intel_lspcon { | 964 | struct intel_lspcon { |
| 965 | bool active; | 965 | bool active; |
| 966 | enum drm_lspcon_mode mode; | 966 | enum drm_lspcon_mode mode; |
| 967 | struct drm_dp_aux *aux; | 967 | bool desc_valid; |
| 968 | }; | 968 | }; |
| 969 | 969 | ||
| 970 | struct intel_digital_port { | 970 | struct intel_digital_port { |
| @@ -1028,17 +1028,15 @@ vlv_pipe_to_channel(enum pipe pipe) | |||
| 1028 | } | 1028 | } |
| 1029 | } | 1029 | } |
| 1030 | 1030 | ||
| 1031 | static inline struct drm_crtc * | 1031 | static inline struct intel_crtc * |
| 1032 | intel_get_crtc_for_pipe(struct drm_device *dev, int pipe) | 1032 | intel_get_crtc_for_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) |
| 1033 | { | 1033 | { |
| 1034 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 1035 | return dev_priv->pipe_to_crtc_mapping[pipe]; | 1034 | return dev_priv->pipe_to_crtc_mapping[pipe]; |
| 1036 | } | 1035 | } |
| 1037 | 1036 | ||
| 1038 | static inline struct drm_crtc * | 1037 | static inline struct intel_crtc * |
| 1039 | intel_get_crtc_for_plane(struct drm_device *dev, int plane) | 1038 | intel_get_crtc_for_plane(struct drm_i915_private *dev_priv, enum plane plane) |
| 1040 | { | 1039 | { |
| 1041 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 1042 | return dev_priv->plane_to_crtc_mapping[plane]; | 1040 | return dev_priv->plane_to_crtc_mapping[plane]; |
| 1043 | } | 1041 | } |
| 1044 | 1042 | ||
| @@ -1098,15 +1096,6 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi) | |||
| 1098 | return container_of(intel_hdmi, struct intel_digital_port, hdmi); | 1096 | return container_of(intel_hdmi, struct intel_digital_port, hdmi); |
| 1099 | } | 1097 | } |
| 1100 | 1098 | ||
| 1101 | /* | ||
| 1102 | * Returns the number of planes for this pipe, ie the number of sprites + 1 | ||
| 1103 | * (primary plane). This doesn't count the cursor plane then. | ||
| 1104 | */ | ||
| 1105 | static inline unsigned int intel_num_planes(struct intel_crtc *crtc) | ||
| 1106 | { | ||
| 1107 | return INTEL_INFO(crtc->base.dev)->num_sprites[crtc->pipe] + 1; | ||
| 1108 | } | ||
| 1109 | |||
| 1110 | /* intel_fifo_underrun.c */ | 1099 | /* intel_fifo_underrun.c */ |
| 1111 | bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv, | 1100 | bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv, |
| 1112 | enum pipe pipe, bool enable); | 1101 | enum pipe pipe, bool enable); |
| @@ -1123,6 +1112,9 @@ void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv); | |||
| 1123 | /* i915_irq.c */ | 1112 | /* i915_irq.c */ |
| 1124 | void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); | 1113 | void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); |
| 1125 | void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); | 1114 | void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); |
| 1115 | void gen6_reset_pm_iir(struct drm_i915_private *dev_priv, u32 mask); | ||
| 1116 | void gen6_mask_pm_irq(struct drm_i915_private *dev_priv, u32 mask); | ||
| 1117 | void gen6_unmask_pm_irq(struct drm_i915_private *dev_priv, u32 mask); | ||
| 1126 | void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); | 1118 | void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); |
| 1127 | void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); | 1119 | void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); |
| 1128 | void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv); | 1120 | void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv); |
| @@ -1145,6 +1137,9 @@ void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, | |||
| 1145 | unsigned int pipe_mask); | 1137 | unsigned int pipe_mask); |
| 1146 | void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, | 1138 | void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, |
| 1147 | unsigned int pipe_mask); | 1139 | unsigned int pipe_mask); |
| 1140 | void gen9_reset_guc_interrupts(struct drm_i915_private *dev_priv); | ||
| 1141 | void gen9_enable_guc_interrupts(struct drm_i915_private *dev_priv); | ||
| 1142 | void gen9_disable_guc_interrupts(struct drm_i915_private *dev_priv); | ||
| 1148 | 1143 | ||
| 1149 | /* intel_crt.c */ | 1144 | /* intel_crt.c */ |
| 1150 | void intel_crt_init(struct drm_device *dev); | 1145 | void intel_crt_init(struct drm_device *dev); |
| @@ -1247,18 +1242,17 @@ intel_crtc_has_dp_encoder(const struct intel_crtc_state *crtc_state) | |||
| 1247 | (1 << INTEL_OUTPUT_EDP)); | 1242 | (1 << INTEL_OUTPUT_EDP)); |
| 1248 | } | 1243 | } |
| 1249 | static inline void | 1244 | static inline void |
| 1250 | intel_wait_for_vblank(struct drm_device *dev, int pipe) | 1245 | intel_wait_for_vblank(struct drm_i915_private *dev_priv, enum pipe pipe) |
| 1251 | { | 1246 | { |
| 1252 | drm_wait_one_vblank(dev, pipe); | 1247 | drm_wait_one_vblank(&dev_priv->drm, pipe); |
| 1253 | } | 1248 | } |
| 1254 | static inline void | 1249 | static inline void |
| 1255 | intel_wait_for_vblank_if_active(struct drm_device *dev, int pipe) | 1250 | intel_wait_for_vblank_if_active(struct drm_i915_private *dev_priv, int pipe) |
| 1256 | { | 1251 | { |
| 1257 | const struct intel_crtc *crtc = | 1252 | const struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
| 1258 | to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe)); | ||
| 1259 | 1253 | ||
| 1260 | if (crtc->active) | 1254 | if (crtc->active) |
| 1261 | intel_wait_for_vblank(dev, pipe); | 1255 | intel_wait_for_vblank(dev_priv, pipe); |
| 1262 | } | 1256 | } |
| 1263 | 1257 | ||
| 1264 | u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc); | 1258 | u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc); |
| @@ -1305,9 +1299,9 @@ unsigned int intel_tile_height(const struct drm_i915_private *dev_priv, | |||
| 1305 | void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv, | 1299 | void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv, |
| 1306 | enum pipe pipe); | 1300 | enum pipe pipe); |
| 1307 | 1301 | ||
| 1308 | int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, | 1302 | int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, |
| 1309 | const struct dpll *dpll); | 1303 | const struct dpll *dpll); |
| 1310 | void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe); | 1304 | void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe); |
| 1311 | int lpt_get_iclkip(struct drm_i915_private *dev_priv); | 1305 | int lpt_get_iclkip(struct drm_i915_private *dev_priv); |
| 1312 | 1306 | ||
| 1313 | /* modesetting asserts */ | 1307 | /* modesetting asserts */ |
| @@ -1335,12 +1329,6 @@ void hsw_enable_pc8(struct drm_i915_private *dev_priv); | |||
| 1335 | void hsw_disable_pc8(struct drm_i915_private *dev_priv); | 1329 | void hsw_disable_pc8(struct drm_i915_private *dev_priv); |
| 1336 | void bxt_init_cdclk(struct drm_i915_private *dev_priv); | 1330 | void bxt_init_cdclk(struct drm_i915_private *dev_priv); |
| 1337 | void bxt_uninit_cdclk(struct drm_i915_private *dev_priv); | 1331 | void bxt_uninit_cdclk(struct drm_i915_private *dev_priv); |
| 1338 | void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy); | ||
| 1339 | void bxt_ddi_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy); | ||
| 1340 | bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv, | ||
| 1341 | enum dpio_phy phy); | ||
| 1342 | bool bxt_ddi_phy_verify_state(struct drm_i915_private *dev_priv, | ||
| 1343 | enum dpio_phy phy); | ||
| 1344 | void gen9_sanitize_dc_state(struct drm_i915_private *dev_priv); | 1332 | void gen9_sanitize_dc_state(struct drm_i915_private *dev_priv); |
| 1345 | void bxt_enable_dc9(struct drm_i915_private *dev_priv); | 1333 | void bxt_enable_dc9(struct drm_i915_private *dev_priv); |
| 1346 | void bxt_disable_dc9(struct drm_i915_private *dev_priv); | 1334 | void bxt_disable_dc9(struct drm_i915_private *dev_priv); |
| @@ -1358,7 +1346,7 @@ bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock, | |||
| 1358 | struct dpll *best_clock); | 1346 | struct dpll *best_clock); |
| 1359 | int chv_calc_dpll_params(int refclk, struct dpll *pll_clock); | 1347 | int chv_calc_dpll_params(int refclk, struct dpll *pll_clock); |
| 1360 | 1348 | ||
| 1361 | bool intel_crtc_active(struct drm_crtc *crtc); | 1349 | bool intel_crtc_active(struct intel_crtc *crtc); |
| 1362 | void hsw_enable_ips(struct intel_crtc *crtc); | 1350 | void hsw_enable_ips(struct intel_crtc *crtc); |
| 1363 | void hsw_disable_ips(struct intel_crtc *crtc); | 1351 | void hsw_disable_ips(struct intel_crtc *crtc); |
| 1364 | enum intel_display_power_domain | 1352 | enum intel_display_power_domain |
| @@ -1451,6 +1439,11 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count) | |||
| 1451 | return ~((1 << lane_count) - 1) & 0xf; | 1439 | return ~((1 << lane_count) - 1) & 0xf; |
| 1452 | } | 1440 | } |
| 1453 | 1441 | ||
| 1442 | bool intel_dp_read_dpcd(struct intel_dp *intel_dp); | ||
| 1443 | bool __intel_dp_read_desc(struct intel_dp *intel_dp, | ||
| 1444 | struct intel_dp_desc *desc); | ||
| 1445 | bool intel_dp_read_desc(struct intel_dp *intel_dp); | ||
| 1446 | |||
| 1454 | /* intel_dp_aux_backlight.c */ | 1447 | /* intel_dp_aux_backlight.c */ |
| 1455 | int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector); | 1448 | int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector); |
| 1456 | 1449 | ||
| @@ -1655,23 +1648,6 @@ assert_rpm_wakelock_held(struct drm_i915_private *dev_priv) | |||
| 1655 | DRM_DEBUG_DRIVER("RPM wakelock ref not held during HW access"); | 1648 | DRM_DEBUG_DRIVER("RPM wakelock ref not held during HW access"); |
| 1656 | } | 1649 | } |
| 1657 | 1650 | ||
| 1658 | static inline int | ||
| 1659 | assert_rpm_atomic_begin(struct drm_i915_private *dev_priv) | ||
| 1660 | { | ||
| 1661 | int seq = atomic_read(&dev_priv->pm.atomic_seq); | ||
| 1662 | |||
| 1663 | assert_rpm_wakelock_held(dev_priv); | ||
| 1664 | |||
| 1665 | return seq; | ||
| 1666 | } | ||
| 1667 | |||
| 1668 | static inline void | ||
| 1669 | assert_rpm_atomic_end(struct drm_i915_private *dev_priv, int begin_seq) | ||
| 1670 | { | ||
| 1671 | WARN_ONCE(atomic_read(&dev_priv->pm.atomic_seq) != begin_seq, | ||
| 1672 | "HW access outside of RPM atomic section\n"); | ||
| 1673 | } | ||
| 1674 | |||
| 1675 | /** | 1651 | /** |
| 1676 | * disable_rpm_wakeref_asserts - disable the RPM assert checks | 1652 | * disable_rpm_wakeref_asserts - disable the RPM assert checks |
| 1677 | * @dev_priv: i915 device instance | 1653 | * @dev_priv: i915 device instance |
| @@ -1727,11 +1703,11 @@ bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy, | |||
| 1727 | 1703 | ||
| 1728 | 1704 | ||
| 1729 | /* intel_pm.c */ | 1705 | /* intel_pm.c */ |
| 1730 | void intel_init_clock_gating(struct drm_device *dev); | 1706 | void intel_init_clock_gating(struct drm_i915_private *dev_priv); |
| 1731 | void intel_suspend_hw(struct drm_device *dev); | 1707 | void intel_suspend_hw(struct drm_i915_private *dev_priv); |
| 1732 | int ilk_wm_max_level(const struct drm_i915_private *dev_priv); | 1708 | int ilk_wm_max_level(const struct drm_i915_private *dev_priv); |
| 1733 | void intel_update_watermarks(struct drm_crtc *crtc); | 1709 | void intel_update_watermarks(struct intel_crtc *crtc); |
| 1734 | void intel_init_pm(struct drm_device *dev); | 1710 | void intel_init_pm(struct drm_i915_private *dev_priv); |
| 1735 | void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv); | 1711 | void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv); |
| 1736 | void intel_pm_setup(struct drm_device *dev); | 1712 | void intel_pm_setup(struct drm_device *dev); |
| 1737 | void intel_gpu_ips_init(struct drm_i915_private *dev_priv); | 1713 | void intel_gpu_ips_init(struct drm_i915_private *dev_priv); |
| @@ -1790,7 +1766,8 @@ bool intel_sdvo_init(struct drm_device *dev, | |||
| 1790 | /* intel_sprite.c */ | 1766 | /* intel_sprite.c */ |
| 1791 | int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, | 1767 | int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, |
| 1792 | int usecs); | 1768 | int usecs); |
| 1793 | int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane); | 1769 | struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv, |
| 1770 | enum pipe pipe, int plane); | ||
| 1794 | int intel_sprite_set_colorkey(struct drm_device *dev, void *data, | 1771 | int intel_sprite_set_colorkey(struct drm_device *dev, void *data, |
| 1795 | struct drm_file *file_priv); | 1772 | struct drm_file *file_priv); |
| 1796 | void intel_pipe_update_start(struct intel_crtc *crtc); | 1773 | void intel_pipe_update_start(struct intel_crtc *crtc); |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index cd574900cd8d..708645443046 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
| @@ -393,12 +393,12 @@ intel_dvo_get_current_mode(struct drm_connector *connector) | |||
| 393 | * its timings to get how the BIOS set up the panel. | 393 | * its timings to get how the BIOS set up the panel. |
| 394 | */ | 394 | */ |
| 395 | if (dvo_val & DVO_ENABLE) { | 395 | if (dvo_val & DVO_ENABLE) { |
| 396 | struct drm_crtc *crtc; | 396 | struct intel_crtc *crtc; |
| 397 | int pipe = (dvo_val & DVO_PIPE_B_SELECT) ? 1 : 0; | 397 | int pipe = (dvo_val & DVO_PIPE_B_SELECT) ? 1 : 0; |
| 398 | 398 | ||
| 399 | crtc = intel_get_crtc_for_pipe(dev, pipe); | 399 | crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
| 400 | if (crtc) { | 400 | if (crtc) { |
| 401 | mode = intel_crtc_mode_get(dev, crtc); | 401 | mode = intel_crtc_mode_get(dev, &crtc->base); |
| 402 | if (mode) { | 402 | if (mode) { |
| 403 | mode->type |= DRM_MODE_TYPE_PREFERRED; | 403 | mode->type |= DRM_MODE_TYPE_PREFERRED; |
| 404 | if (dvo_val & DVO_HSYNC_ACTIVE_HIGH) | 404 | if (dvo_val & DVO_HSYNC_ACTIVE_HIGH) |
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 8cceb345aa0f..841f8d1e1410 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c | |||
| @@ -174,7 +174,7 @@ cleanup: | |||
| 174 | return ret; | 174 | return ret; |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | void intel_engine_init_seqno(struct intel_engine_cs *engine, u32 seqno) | 177 | void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno) |
| 178 | { | 178 | { |
| 179 | struct drm_i915_private *dev_priv = engine->i915; | 179 | struct drm_i915_private *dev_priv = engine->i915; |
| 180 | 180 | ||
| @@ -204,13 +204,13 @@ void intel_engine_init_seqno(struct intel_engine_cs *engine, u32 seqno) | |||
| 204 | I915_NUM_ENGINES * gen8_semaphore_seqno_size); | 204 | I915_NUM_ENGINES * gen8_semaphore_seqno_size); |
| 205 | kunmap(page); | 205 | kunmap(page); |
| 206 | } | 206 | } |
| 207 | memset(engine->semaphore.sync_seqno, 0, | ||
| 208 | sizeof(engine->semaphore.sync_seqno)); | ||
| 209 | 207 | ||
| 210 | intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno); | 208 | intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno); |
| 211 | if (engine->irq_seqno_barrier) | 209 | if (engine->irq_seqno_barrier) |
| 212 | engine->irq_seqno_barrier(engine); | 210 | engine->irq_seqno_barrier(engine); |
| 213 | engine->last_submitted_seqno = seqno; | 211 | |
| 212 | GEM_BUG_ON(i915_gem_active_isset(&engine->timeline->last_request)); | ||
| 213 | engine->timeline->last_submitted_seqno = seqno; | ||
| 214 | 214 | ||
| 215 | engine->hangcheck.seqno = seqno; | 215 | engine->hangcheck.seqno = seqno; |
| 216 | 216 | ||
| @@ -220,15 +220,9 @@ void intel_engine_init_seqno(struct intel_engine_cs *engine, u32 seqno) | |||
| 220 | intel_engine_wakeup(engine); | 220 | intel_engine_wakeup(engine); |
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | void intel_engine_init_hangcheck(struct intel_engine_cs *engine) | 223 | static void intel_engine_init_timeline(struct intel_engine_cs *engine) |
| 224 | { | ||
| 225 | memset(&engine->hangcheck, 0, sizeof(engine->hangcheck)); | ||
| 226 | } | ||
| 227 | |||
| 228 | static void intel_engine_init_requests(struct intel_engine_cs *engine) | ||
| 229 | { | 224 | { |
| 230 | init_request_active(&engine->last_request, NULL); | 225 | engine->timeline = &engine->i915->gt.global_timeline.engine[engine->id]; |
| 231 | INIT_LIST_HEAD(&engine->request_list); | ||
| 232 | } | 226 | } |
| 233 | 227 | ||
| 234 | /** | 228 | /** |
| @@ -245,9 +239,7 @@ void intel_engine_setup_common(struct intel_engine_cs *engine) | |||
| 245 | INIT_LIST_HEAD(&engine->execlist_queue); | 239 | INIT_LIST_HEAD(&engine->execlist_queue); |
| 246 | spin_lock_init(&engine->execlist_lock); | 240 | spin_lock_init(&engine->execlist_lock); |
| 247 | 241 | ||
| 248 | engine->fence_context = dma_fence_context_alloc(1); | 242 | intel_engine_init_timeline(engine); |
| 249 | |||
| 250 | intel_engine_init_requests(engine); | ||
| 251 | intel_engine_init_hangcheck(engine); | 243 | intel_engine_init_hangcheck(engine); |
| 252 | i915_gem_batch_pool_init(engine, &engine->batch_pool); | 244 | i915_gem_batch_pool_init(engine, &engine->batch_pool); |
| 253 | 245 | ||
| @@ -264,7 +256,7 @@ int intel_engine_create_scratch(struct intel_engine_cs *engine, int size) | |||
| 264 | 256 | ||
| 265 | obj = i915_gem_object_create_stolen(&engine->i915->drm, size); | 257 | obj = i915_gem_object_create_stolen(&engine->i915->drm, size); |
| 266 | if (!obj) | 258 | if (!obj) |
| 267 | obj = i915_gem_object_create(&engine->i915->drm, size); | 259 | obj = i915_gem_object_create_internal(engine->i915, size); |
| 268 | if (IS_ERR(obj)) { | 260 | if (IS_ERR(obj)) { |
| 269 | DRM_ERROR("Failed to allocate scratch page\n"); | 261 | DRM_ERROR("Failed to allocate scratch page\n"); |
| 270 | return PTR_ERR(obj); | 262 | return PTR_ERR(obj); |
| @@ -314,6 +306,10 @@ int intel_engine_init_common(struct intel_engine_cs *engine) | |||
| 314 | if (ret) | 306 | if (ret) |
| 315 | return ret; | 307 | return ret; |
| 316 | 308 | ||
| 309 | ret = i915_gem_render_state_init(engine); | ||
| 310 | if (ret) | ||
| 311 | return ret; | ||
| 312 | |||
| 317 | return 0; | 313 | return 0; |
| 318 | } | 314 | } |
| 319 | 315 | ||
| @@ -328,6 +324,7 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine) | |||
| 328 | { | 324 | { |
| 329 | intel_engine_cleanup_scratch(engine); | 325 | intel_engine_cleanup_scratch(engine); |
| 330 | 326 | ||
| 327 | i915_gem_render_state_fini(engine); | ||
| 331 | intel_engine_fini_breadcrumbs(engine); | 328 | intel_engine_fini_breadcrumbs(engine); |
| 332 | intel_engine_cleanup_cmd_parser(engine); | 329 | intel_engine_cleanup_cmd_parser(engine); |
| 333 | i915_gem_batch_pool_fini(&engine->batch_pool); | 330 | i915_gem_batch_pool_fini(&engine->batch_pool); |
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index cbe2ebda4c40..e230d480c5e6 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c | |||
| @@ -1306,7 +1306,7 @@ void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv) | |||
| 1306 | return; | 1306 | return; |
| 1307 | 1307 | ||
| 1308 | for_each_intel_crtc(&dev_priv->drm, crtc) | 1308 | for_each_intel_crtc(&dev_priv->drm, crtc) |
| 1309 | if (intel_crtc_active(&crtc->base) && | 1309 | if (intel_crtc_active(crtc) && |
| 1310 | to_intel_plane_state(crtc->base.primary->state)->base.visible) | 1310 | to_intel_plane_state(crtc->base.primary->state)->base.visible) |
| 1311 | dev_priv->fbc.visible_pipes_mask |= (1 << crtc->pipe); | 1311 | dev_priv->fbc.visible_pipes_mask |= (1 << crtc->pipe); |
| 1312 | } | 1312 | } |
diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c index 3018f4f589c8..e660d8b4bbc3 100644 --- a/drivers/gpu/drm/i915/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c | |||
| @@ -57,7 +57,7 @@ static bool ivb_can_enable_err_int(struct drm_device *dev) | |||
| 57 | assert_spin_locked(&dev_priv->irq_lock); | 57 | assert_spin_locked(&dev_priv->irq_lock); |
| 58 | 58 | ||
| 59 | for_each_pipe(dev_priv, pipe) { | 59 | for_each_pipe(dev_priv, pipe) { |
| 60 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); | 60 | crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
| 61 | 61 | ||
| 62 | if (crtc->cpu_fifo_underrun_disabled) | 62 | if (crtc->cpu_fifo_underrun_disabled) |
| 63 | return false; | 63 | return false; |
| @@ -75,7 +75,7 @@ static bool cpt_can_enable_serr_int(struct drm_device *dev) | |||
| 75 | assert_spin_locked(&dev_priv->irq_lock); | 75 | assert_spin_locked(&dev_priv->irq_lock); |
| 76 | 76 | ||
| 77 | for_each_pipe(dev_priv, pipe) { | 77 | for_each_pipe(dev_priv, pipe) { |
| 78 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); | 78 | crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
| 79 | 79 | ||
| 80 | if (crtc->pch_fifo_underrun_disabled) | 80 | if (crtc->pch_fifo_underrun_disabled) |
| 81 | return false; | 81 | return false; |
| @@ -245,14 +245,13 @@ static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, | |||
| 245 | enum pipe pipe, bool enable) | 245 | enum pipe pipe, bool enable) |
| 246 | { | 246 | { |
| 247 | struct drm_i915_private *dev_priv = to_i915(dev); | 247 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 248 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | 248 | struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
| 249 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
| 250 | bool old; | 249 | bool old; |
| 251 | 250 | ||
| 252 | assert_spin_locked(&dev_priv->irq_lock); | 251 | assert_spin_locked(&dev_priv->irq_lock); |
| 253 | 252 | ||
| 254 | old = !intel_crtc->cpu_fifo_underrun_disabled; | 253 | old = !crtc->cpu_fifo_underrun_disabled; |
| 255 | intel_crtc->cpu_fifo_underrun_disabled = !enable; | 254 | crtc->cpu_fifo_underrun_disabled = !enable; |
| 256 | 255 | ||
| 257 | if (HAS_GMCH_DISPLAY(dev_priv)) | 256 | if (HAS_GMCH_DISPLAY(dev_priv)) |
| 258 | i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old); | 257 | i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old); |
| @@ -314,8 +313,8 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, | |||
| 314 | enum transcoder pch_transcoder, | 313 | enum transcoder pch_transcoder, |
| 315 | bool enable) | 314 | bool enable) |
| 316 | { | 315 | { |
| 317 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pch_transcoder]; | 316 | struct intel_crtc *crtc = |
| 318 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 317 | intel_get_crtc_for_pipe(dev_priv, (enum pipe) pch_transcoder); |
| 319 | unsigned long flags; | 318 | unsigned long flags; |
| 320 | bool old; | 319 | bool old; |
| 321 | 320 | ||
| @@ -330,8 +329,8 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, | |||
| 330 | 329 | ||
| 331 | spin_lock_irqsave(&dev_priv->irq_lock, flags); | 330 | spin_lock_irqsave(&dev_priv->irq_lock, flags); |
| 332 | 331 | ||
| 333 | old = !intel_crtc->pch_fifo_underrun_disabled; | 332 | old = !crtc->pch_fifo_underrun_disabled; |
| 334 | intel_crtc->pch_fifo_underrun_disabled = !enable; | 333 | crtc->pch_fifo_underrun_disabled = !enable; |
| 335 | 334 | ||
| 336 | if (HAS_PCH_IBX(dev_priv)) | 335 | if (HAS_PCH_IBX(dev_priv)) |
| 337 | ibx_set_fifo_underrun_reporting(&dev_priv->drm, | 336 | ibx_set_fifo_underrun_reporting(&dev_priv->drm, |
| @@ -358,7 +357,7 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, | |||
| 358 | void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, | 357 | void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, |
| 359 | enum pipe pipe) | 358 | enum pipe pipe) |
| 360 | { | 359 | { |
| 361 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | 360 | struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
| 362 | 361 | ||
| 363 | /* We may be called too early in init, thanks BIOS! */ | 362 | /* We may be called too early in init, thanks BIOS! */ |
| 364 | if (crtc == NULL) | 363 | if (crtc == NULL) |
| @@ -366,7 +365,7 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, | |||
| 366 | 365 | ||
| 367 | /* GMCH can't disable fifo underruns, filter them. */ | 366 | /* GMCH can't disable fifo underruns, filter them. */ |
| 368 | if (HAS_GMCH_DISPLAY(dev_priv) && | 367 | if (HAS_GMCH_DISPLAY(dev_priv) && |
| 369 | to_intel_crtc(crtc)->cpu_fifo_underrun_disabled) | 368 | crtc->cpu_fifo_underrun_disabled) |
| 370 | return; | 369 | return; |
| 371 | 370 | ||
| 372 | if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) | 371 | if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) |
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index 5cdf7aa75be5..0053258e03d3 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h | |||
| @@ -64,7 +64,7 @@ struct drm_i915_gem_request; | |||
| 64 | */ | 64 | */ |
| 65 | struct i915_guc_client { | 65 | struct i915_guc_client { |
| 66 | struct i915_vma *vma; | 66 | struct i915_vma *vma; |
| 67 | void *client_base; /* first page (only) of above */ | 67 | void *vaddr; |
| 68 | struct i915_gem_context *owner; | 68 | struct i915_gem_context *owner; |
| 69 | struct intel_guc *guc; | 69 | struct intel_guc *guc; |
| 70 | 70 | ||
| @@ -123,10 +123,28 @@ struct intel_guc_fw { | |||
| 123 | uint32_t ucode_offset; | 123 | uint32_t ucode_offset; |
| 124 | }; | 124 | }; |
| 125 | 125 | ||
| 126 | struct intel_guc_log { | ||
| 127 | uint32_t flags; | ||
| 128 | struct i915_vma *vma; | ||
| 129 | void *buf_addr; | ||
| 130 | struct workqueue_struct *flush_wq; | ||
| 131 | struct work_struct flush_work; | ||
| 132 | struct rchan *relay_chan; | ||
| 133 | |||
| 134 | /* logging related stats */ | ||
| 135 | u32 capture_miss_count; | ||
| 136 | u32 flush_interrupt_count; | ||
| 137 | u32 prev_overflow_count[GUC_MAX_LOG_BUFFER]; | ||
| 138 | u32 total_overflow_count[GUC_MAX_LOG_BUFFER]; | ||
| 139 | u32 flush_count[GUC_MAX_LOG_BUFFER]; | ||
| 140 | }; | ||
| 141 | |||
| 126 | struct intel_guc { | 142 | struct intel_guc { |
| 127 | struct intel_guc_fw guc_fw; | 143 | struct intel_guc_fw guc_fw; |
| 128 | uint32_t log_flags; | 144 | struct intel_guc_log log; |
| 129 | struct i915_vma *log_vma; | 145 | |
| 146 | /* GuC2Host interrupt related state */ | ||
| 147 | bool interrupts_enabled; | ||
| 130 | 148 | ||
| 131 | struct i915_vma *ads_vma; | 149 | struct i915_vma *ads_vma; |
| 132 | struct i915_vma *ctx_pool_vma; | 150 | struct i915_vma *ctx_pool_vma; |
| @@ -146,6 +164,9 @@ struct intel_guc { | |||
| 146 | 164 | ||
| 147 | uint64_t submissions[I915_NUM_ENGINES]; | 165 | uint64_t submissions[I915_NUM_ENGINES]; |
| 148 | uint32_t last_seqno[I915_NUM_ENGINES]; | 166 | uint32_t last_seqno[I915_NUM_ENGINES]; |
| 167 | |||
| 168 | /* To serialize the Host2GuC actions */ | ||
| 169 | struct mutex action_lock; | ||
| 149 | }; | 170 | }; |
| 150 | 171 | ||
| 151 | /* intel_guc_loader.c */ | 172 | /* intel_guc_loader.c */ |
| @@ -163,5 +184,10 @@ int i915_guc_wq_reserve(struct drm_i915_gem_request *rq); | |||
| 163 | void i915_guc_wq_unreserve(struct drm_i915_gem_request *request); | 184 | void i915_guc_wq_unreserve(struct drm_i915_gem_request *request); |
| 164 | void i915_guc_submission_disable(struct drm_i915_private *dev_priv); | 185 | void i915_guc_submission_disable(struct drm_i915_private *dev_priv); |
| 165 | void i915_guc_submission_fini(struct drm_i915_private *dev_priv); | 186 | void i915_guc_submission_fini(struct drm_i915_private *dev_priv); |
| 187 | void i915_guc_capture_logs(struct drm_i915_private *dev_priv); | ||
| 188 | void i915_guc_flush_logs(struct drm_i915_private *dev_priv); | ||
| 189 | void i915_guc_register(struct drm_i915_private *dev_priv); | ||
| 190 | void i915_guc_unregister(struct drm_i915_private *dev_priv); | ||
| 191 | int i915_guc_log_control(struct drm_i915_private *dev_priv, u64 control_val); | ||
| 166 | 192 | ||
| 167 | #endif | 193 | #endif |
diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h index e40db2d2ae99..324ea902558b 100644 --- a/drivers/gpu/drm/i915/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h | |||
| @@ -104,9 +104,9 @@ | |||
| 104 | #define GUC_LOG_ALLOC_IN_MEGABYTE (1 << 3) | 104 | #define GUC_LOG_ALLOC_IN_MEGABYTE (1 << 3) |
| 105 | #define GUC_LOG_CRASH_PAGES 1 | 105 | #define GUC_LOG_CRASH_PAGES 1 |
| 106 | #define GUC_LOG_CRASH_SHIFT 4 | 106 | #define GUC_LOG_CRASH_SHIFT 4 |
| 107 | #define GUC_LOG_DPC_PAGES 3 | 107 | #define GUC_LOG_DPC_PAGES 7 |
| 108 | #define GUC_LOG_DPC_SHIFT 6 | 108 | #define GUC_LOG_DPC_SHIFT 6 |
| 109 | #define GUC_LOG_ISR_PAGES 3 | 109 | #define GUC_LOG_ISR_PAGES 7 |
| 110 | #define GUC_LOG_ISR_SHIFT 9 | 110 | #define GUC_LOG_ISR_SHIFT 9 |
| 111 | #define GUC_LOG_BUF_ADDR_SHIFT 12 | 111 | #define GUC_LOG_BUF_ADDR_SHIFT 12 |
| 112 | 112 | ||
| @@ -419,15 +419,87 @@ struct guc_ads { | |||
| 419 | u32 reserved2[4]; | 419 | u32 reserved2[4]; |
| 420 | } __packed; | 420 | } __packed; |
| 421 | 421 | ||
| 422 | /* GuC logging structures */ | ||
| 423 | |||
| 424 | enum guc_log_buffer_type { | ||
| 425 | GUC_ISR_LOG_BUFFER, | ||
| 426 | GUC_DPC_LOG_BUFFER, | ||
| 427 | GUC_CRASH_DUMP_LOG_BUFFER, | ||
| 428 | GUC_MAX_LOG_BUFFER | ||
| 429 | }; | ||
| 430 | |||
| 431 | /** | ||
| 432 | * DOC: GuC Log buffer Layout | ||
| 433 | * | ||
| 434 | * Page0 +-------------------------------+ | ||
| 435 | * | ISR state header (32 bytes) | | ||
| 436 | * | DPC state header | | ||
| 437 | * | Crash dump state header | | ||
| 438 | * Page1 +-------------------------------+ | ||
| 439 | * | ISR logs | | ||
| 440 | * Page9 +-------------------------------+ | ||
| 441 | * | DPC logs | | ||
| 442 | * Page17 +-------------------------------+ | ||
| 443 | * | Crash Dump logs | | ||
| 444 | * +-------------------------------+ | ||
| 445 | * | ||
| 446 | * Below state structure is used for coordination of retrieval of GuC firmware | ||
| 447 | * logs. Separate state is maintained for each log buffer type. | ||
| 448 | * read_ptr points to the location where i915 read last in log buffer and | ||
| 449 | * is read only for GuC firmware. write_ptr is incremented by GuC with number | ||
| 450 | * of bytes written for each log entry and is read only for i915. | ||
| 451 | * When any type of log buffer becomes half full, GuC sends a flush interrupt. | ||
| 452 | * GuC firmware expects that while it is writing to 2nd half of the buffer, | ||
| 453 | * first half would get consumed by Host and then get a flush completed | ||
| 454 | * acknowledgment from Host, so that it does not end up doing any overwrite | ||
| 455 | * causing loss of logs. So when buffer gets half filled & i915 has requested | ||
| 456 | * for interrupt, GuC will set flush_to_file field, set the sampled_write_ptr | ||
| 457 | * to the value of write_ptr and raise the interrupt. | ||
| 458 | * On receiving the interrupt i915 should read the buffer, clear flush_to_file | ||
| 459 | * field and also update read_ptr with the value of sample_write_ptr, before | ||
| 460 | * sending an acknowledgment to GuC. marker & version fields are for internal | ||
| 461 | * usage of GuC and opaque to i915. buffer_full_cnt field is incremented every | ||
| 462 | * time GuC detects the log buffer overflow. | ||
| 463 | */ | ||
| 464 | struct guc_log_buffer_state { | ||
| 465 | u32 marker[2]; | ||
| 466 | u32 read_ptr; | ||
| 467 | u32 write_ptr; | ||
| 468 | u32 size; | ||
| 469 | u32 sampled_write_ptr; | ||
| 470 | union { | ||
| 471 | struct { | ||
| 472 | u32 flush_to_file:1; | ||
| 473 | u32 buffer_full_cnt:4; | ||
| 474 | u32 reserved:27; | ||
| 475 | }; | ||
| 476 | u32 flags; | ||
| 477 | }; | ||
| 478 | u32 version; | ||
| 479 | } __packed; | ||
| 480 | |||
| 481 | union guc_log_control { | ||
| 482 | struct { | ||
| 483 | u32 logging_enabled:1; | ||
| 484 | u32 reserved1:3; | ||
| 485 | u32 verbosity:4; | ||
| 486 | u32 reserved2:24; | ||
| 487 | }; | ||
| 488 | u32 value; | ||
| 489 | } __packed; | ||
| 490 | |||
| 422 | /* This Action will be programmed in C180 - SOFT_SCRATCH_O_REG */ | 491 | /* This Action will be programmed in C180 - SOFT_SCRATCH_O_REG */ |
| 423 | enum host2guc_action { | 492 | enum host2guc_action { |
| 424 | HOST2GUC_ACTION_DEFAULT = 0x0, | 493 | HOST2GUC_ACTION_DEFAULT = 0x0, |
| 425 | HOST2GUC_ACTION_SAMPLE_FORCEWAKE = 0x6, | 494 | HOST2GUC_ACTION_SAMPLE_FORCEWAKE = 0x6, |
| 426 | HOST2GUC_ACTION_ALLOCATE_DOORBELL = 0x10, | 495 | HOST2GUC_ACTION_ALLOCATE_DOORBELL = 0x10, |
| 427 | HOST2GUC_ACTION_DEALLOCATE_DOORBELL = 0x20, | 496 | HOST2GUC_ACTION_DEALLOCATE_DOORBELL = 0x20, |
| 497 | HOST2GUC_ACTION_LOG_BUFFER_FILE_FLUSH_COMPLETE = 0x30, | ||
| 498 | HOST2GUC_ACTION_FORCE_LOG_BUFFER_FLUSH = 0x302, | ||
| 428 | HOST2GUC_ACTION_ENTER_S_STATE = 0x501, | 499 | HOST2GUC_ACTION_ENTER_S_STATE = 0x501, |
| 429 | HOST2GUC_ACTION_EXIT_S_STATE = 0x502, | 500 | HOST2GUC_ACTION_EXIT_S_STATE = 0x502, |
| 430 | HOST2GUC_ACTION_SLPC_REQUEST = 0x3003, | 501 | HOST2GUC_ACTION_SLPC_REQUEST = 0x3003, |
| 502 | HOST2GUC_ACTION_UK_LOG_ENABLE_LOGGING = 0x0E000, | ||
| 431 | HOST2GUC_ACTION_LIMIT | 503 | HOST2GUC_ACTION_LIMIT |
| 432 | }; | 504 | }; |
| 433 | 505 | ||
| @@ -449,4 +521,10 @@ enum guc2host_status { | |||
| 449 | GUC2HOST_STATUS_GENERIC_FAIL = GUC2HOST_STATUS(0x0000F000) | 521 | GUC2HOST_STATUS_GENERIC_FAIL = GUC2HOST_STATUS(0x0000F000) |
| 450 | }; | 522 | }; |
| 451 | 523 | ||
| 524 | /* This action will be programmed in C1BC - SOFT_SCRATCH_15_REG */ | ||
| 525 | enum guc2host_message { | ||
| 526 | GUC2HOST_MSG_CRASH_DUMP_POSTED = (1 << 1), | ||
| 527 | GUC2HOST_MSG_FLUSH_LOG_BUFFER = (1 << 3) | ||
| 528 | }; | ||
| 529 | |||
| 452 | #endif | 530 | #endif |
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index 3c8eaae13732..1aa85236b788 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c | |||
| @@ -211,11 +211,13 @@ static void guc_params_init(struct drm_i915_private *dev_priv) | |||
| 211 | params[GUC_CTL_FEATURE] |= GUC_CTL_DISABLE_SCHEDULER | | 211 | params[GUC_CTL_FEATURE] |= GUC_CTL_DISABLE_SCHEDULER | |
| 212 | GUC_CTL_VCS2_ENABLED; | 212 | GUC_CTL_VCS2_ENABLED; |
| 213 | 213 | ||
| 214 | params[GUC_CTL_LOG_PARAMS] = guc->log.flags; | ||
| 215 | |||
| 214 | if (i915.guc_log_level >= 0) { | 216 | if (i915.guc_log_level >= 0) { |
| 215 | params[GUC_CTL_LOG_PARAMS] = guc->log_flags; | ||
| 216 | params[GUC_CTL_DEBUG] = | 217 | params[GUC_CTL_DEBUG] = |
| 217 | i915.guc_log_level << GUC_LOG_VERBOSITY_SHIFT; | 218 | i915.guc_log_level << GUC_LOG_VERBOSITY_SHIFT; |
| 218 | } | 219 | } else |
| 220 | params[GUC_CTL_DEBUG] = GUC_LOG_DISABLED; | ||
| 219 | 221 | ||
| 220 | if (guc->ads_vma) { | 222 | if (guc->ads_vma) { |
| 221 | u32 ads = i915_ggtt_offset(guc->ads_vma) >> PAGE_SHIFT; | 223 | u32 ads = i915_ggtt_offset(guc->ads_vma) >> PAGE_SHIFT; |
| @@ -483,6 +485,7 @@ int intel_guc_setup(struct drm_device *dev) | |||
| 483 | } | 485 | } |
| 484 | 486 | ||
| 485 | guc_interrupts_release(dev_priv); | 487 | guc_interrupts_release(dev_priv); |
| 488 | gen9_reset_guc_interrupts(dev_priv); | ||
| 486 | 489 | ||
| 487 | guc_fw->guc_fw_load_status = GUC_FIRMWARE_PENDING; | 490 | guc_fw->guc_fw_load_status = GUC_FIRMWARE_PENDING; |
| 488 | 491 | ||
| @@ -527,6 +530,9 @@ int intel_guc_setup(struct drm_device *dev) | |||
| 527 | intel_guc_fw_status_repr(guc_fw->guc_fw_load_status)); | 530 | intel_guc_fw_status_repr(guc_fw->guc_fw_load_status)); |
| 528 | 531 | ||
| 529 | if (i915.enable_guc_submission) { | 532 | if (i915.enable_guc_submission) { |
| 533 | if (i915.guc_log_level >= 0) | ||
| 534 | gen9_enable_guc_interrupts(dev_priv); | ||
| 535 | |||
| 530 | err = i915_guc_submission_enable(dev_priv); | 536 | err = i915_guc_submission_enable(dev_priv); |
| 531 | if (err) | 537 | if (err) |
| 532 | goto fail; | 538 | goto fail; |
diff --git a/drivers/gpu/drm/i915/intel_hangcheck.c b/drivers/gpu/drm/i915/intel_hangcheck.c new file mode 100644 index 000000000000..53df5b11bff4 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_hangcheck.c | |||
| @@ -0,0 +1,450 @@ | |||
| 1 | /* | ||
| 2 | * Copyright © 2016 Intel Corporation | ||
| 3 | * | ||
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 5 | * copy of this software and associated documentation files (the "Software"), | ||
| 6 | * to deal in the Software without restriction, including without limitation | ||
| 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 9 | * Software is furnished to do so, subject to the following conditions: | ||
| 10 | * | ||
| 11 | * The above copyright notice and this permission notice (including the next | ||
| 12 | * paragraph) shall be included in all copies or substantial portions of the | ||
| 13 | * Software. | ||
| 14 | * | ||
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
| 21 | * IN THE SOFTWARE. | ||
| 22 | * | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include "i915_drv.h" | ||
| 26 | |||
| 27 | static bool | ||
| 28 | ipehr_is_semaphore_wait(struct intel_engine_cs *engine, u32 ipehr) | ||
| 29 | { | ||
| 30 | if (INTEL_GEN(engine->i915) >= 8) { | ||
| 31 | return (ipehr >> 23) == 0x1c; | ||
| 32 | } else { | ||
| 33 | ipehr &= ~MI_SEMAPHORE_SYNC_MASK; | ||
| 34 | return ipehr == (MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE | | ||
| 35 | MI_SEMAPHORE_REGISTER); | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | static struct intel_engine_cs * | ||
| 40 | semaphore_wait_to_signaller_ring(struct intel_engine_cs *engine, u32 ipehr, | ||
| 41 | u64 offset) | ||
| 42 | { | ||
| 43 | struct drm_i915_private *dev_priv = engine->i915; | ||
| 44 | struct intel_engine_cs *signaller; | ||
| 45 | enum intel_engine_id id; | ||
| 46 | |||
| 47 | if (INTEL_GEN(dev_priv) >= 8) { | ||
| 48 | for_each_engine(signaller, dev_priv, id) { | ||
| 49 | if (engine == signaller) | ||
| 50 | continue; | ||
| 51 | |||
| 52 | if (offset == signaller->semaphore.signal_ggtt[engine->hw_id]) | ||
| 53 | return signaller; | ||
| 54 | } | ||
| 55 | } else { | ||
| 56 | u32 sync_bits = ipehr & MI_SEMAPHORE_SYNC_MASK; | ||
| 57 | |||
| 58 | for_each_engine(signaller, dev_priv, id) { | ||
| 59 | if(engine == signaller) | ||
| 60 | continue; | ||
| 61 | |||
| 62 | if (sync_bits == signaller->semaphore.mbox.wait[engine->hw_id]) | ||
| 63 | return signaller; | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | DRM_DEBUG_DRIVER("No signaller ring found for %s, ipehr 0x%08x, offset 0x%016llx\n", | ||
| 68 | engine->name, ipehr, offset); | ||
| 69 | |||
| 70 | return ERR_PTR(-ENODEV); | ||
| 71 | } | ||
| 72 | |||
| 73 | static struct intel_engine_cs * | ||
| 74 | semaphore_waits_for(struct intel_engine_cs *engine, u32 *seqno) | ||
| 75 | { | ||
| 76 | struct drm_i915_private *dev_priv = engine->i915; | ||
| 77 | void __iomem *vaddr; | ||
| 78 | u32 cmd, ipehr, head; | ||
| 79 | u64 offset = 0; | ||
| 80 | int i, backwards; | ||
| 81 | |||
| 82 | /* | ||
| 83 | * This function does not support execlist mode - any attempt to | ||
| 84 | * proceed further into this function will result in a kernel panic | ||
| 85 | * when dereferencing ring->buffer, which is not set up in execlist | ||
| 86 | * mode. | ||
| 87 | * | ||
| 88 | * The correct way of doing it would be to derive the currently | ||
| 89 | * executing ring buffer from the current context, which is derived | ||
| 90 | * from the currently running request. Unfortunately, to get the | ||
| 91 | * current request we would have to grab the struct_mutex before doing | ||
| 92 | * anything else, which would be ill-advised since some other thread | ||
| 93 | * might have grabbed it already and managed to hang itself, causing | ||
| 94 | * the hang checker to deadlock. | ||
| 95 | * | ||
| 96 | * Therefore, this function does not support execlist mode in its | ||
| 97 | * current form. Just return NULL and move on. | ||
| 98 | */ | ||
| 99 | if (engine->buffer == NULL) | ||
| 100 | return NULL; | ||
| 101 | |||
| 102 | ipehr = I915_READ(RING_IPEHR(engine->mmio_base)); | ||
| 103 | if (!ipehr_is_semaphore_wait(engine, ipehr)) | ||
| 104 | return NULL; | ||
| 105 | |||
| 106 | /* | ||
| 107 | * HEAD is likely pointing to the dword after the actual command, | ||
| 108 | * so scan backwards until we find the MBOX. But limit it to just 3 | ||
| 109 | * or 4 dwords depending on the semaphore wait command size. | ||
| 110 | * Note that we don't care about ACTHD here since that might | ||
| 111 | * point at at batch, and semaphores are always emitted into the | ||
| 112 | * ringbuffer itself. | ||
| 113 | */ | ||
| 114 | head = I915_READ_HEAD(engine) & HEAD_ADDR; | ||
| 115 | backwards = (INTEL_GEN(dev_priv) >= 8) ? 5 : 4; | ||
| 116 | vaddr = (void __iomem *)engine->buffer->vaddr; | ||
| 117 | |||
| 118 | for (i = backwards; i; --i) { | ||
| 119 | /* | ||
| 120 | * Be paranoid and presume the hw has gone off into the wild - | ||
| 121 | * our ring is smaller than what the hardware (and hence | ||
| 122 | * HEAD_ADDR) allows. Also handles wrap-around. | ||
| 123 | */ | ||
| 124 | head &= engine->buffer->size - 1; | ||
| 125 | |||
| 126 | /* This here seems to blow up */ | ||
| 127 | cmd = ioread32(vaddr + head); | ||
| 128 | if (cmd == ipehr) | ||
| 129 | break; | ||
| 130 | |||
| 131 | head -= 4; | ||
| 132 | } | ||
| 133 | |||
| 134 | if (!i) | ||
| 135 | return NULL; | ||
| 136 | |||
| 137 | *seqno = ioread32(vaddr + head + 4) + 1; | ||
| 138 | if (INTEL_GEN(dev_priv) >= 8) { | ||
| 139 | offset = ioread32(vaddr + head + 12); | ||
| 140 | offset <<= 32; | ||
| 141 | offset |= ioread32(vaddr + head + 8); | ||
| 142 | } | ||
| 143 | return semaphore_wait_to_signaller_ring(engine, ipehr, offset); | ||
| 144 | } | ||
| 145 | |||
| 146 | static int semaphore_passed(struct intel_engine_cs *engine) | ||
| 147 | { | ||
| 148 | struct drm_i915_private *dev_priv = engine->i915; | ||
| 149 | struct intel_engine_cs *signaller; | ||
| 150 | u32 seqno; | ||
| 151 | |||
| 152 | engine->hangcheck.deadlock++; | ||
| 153 | |||
| 154 | signaller = semaphore_waits_for(engine, &seqno); | ||
| 155 | if (signaller == NULL) | ||
| 156 | return -1; | ||
| 157 | |||
| 158 | if (IS_ERR(signaller)) | ||
| 159 | return 0; | ||
| 160 | |||
| 161 | /* Prevent pathological recursion due to driver bugs */ | ||
| 162 | if (signaller->hangcheck.deadlock >= I915_NUM_ENGINES) | ||
| 163 | return -1; | ||
| 164 | |||
| 165 | if (i915_seqno_passed(intel_engine_get_seqno(signaller), seqno)) | ||
| 166 | return 1; | ||
| 167 | |||
| 168 | /* cursory check for an unkickable deadlock */ | ||
| 169 | if (I915_READ_CTL(signaller) & RING_WAIT_SEMAPHORE && | ||
| 170 | semaphore_passed(signaller) < 0) | ||
| 171 | return -1; | ||
| 172 | |||
| 173 | return 0; | ||
| 174 | } | ||
| 175 | |||
| 176 | static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv) | ||
| 177 | { | ||
| 178 | struct intel_engine_cs *engine; | ||
| 179 | enum intel_engine_id id; | ||
| 180 | |||
| 181 | for_each_engine(engine, dev_priv, id) | ||
| 182 | engine->hangcheck.deadlock = 0; | ||
| 183 | } | ||
| 184 | |||
| 185 | static bool instdone_unchanged(u32 current_instdone, u32 *old_instdone) | ||
| 186 | { | ||
| 187 | u32 tmp = current_instdone | *old_instdone; | ||
| 188 | bool unchanged; | ||
| 189 | |||
| 190 | unchanged = tmp == *old_instdone; | ||
| 191 | *old_instdone |= tmp; | ||
| 192 | |||
| 193 | return unchanged; | ||
| 194 | } | ||
| 195 | |||
| 196 | static bool subunits_stuck(struct intel_engine_cs *engine) | ||
| 197 | { | ||
| 198 | struct drm_i915_private *dev_priv = engine->i915; | ||
| 199 | struct intel_instdone instdone; | ||
| 200 | struct intel_instdone *accu_instdone = &engine->hangcheck.instdone; | ||
| 201 | bool stuck; | ||
| 202 | int slice; | ||
| 203 | int subslice; | ||
| 204 | |||
| 205 | if (engine->id != RCS) | ||
| 206 | return true; | ||
| 207 | |||
| 208 | intel_engine_get_instdone(engine, &instdone); | ||
| 209 | |||
| 210 | /* There might be unstable subunit states even when | ||
| 211 | * actual head is not moving. Filter out the unstable ones by | ||
| 212 | * accumulating the undone -> done transitions and only | ||
| 213 | * consider those as progress. | ||
| 214 | */ | ||
| 215 | stuck = instdone_unchanged(instdone.instdone, | ||
| 216 | &accu_instdone->instdone); | ||
| 217 | stuck &= instdone_unchanged(instdone.slice_common, | ||
| 218 | &accu_instdone->slice_common); | ||
| 219 | |||
| 220 | for_each_instdone_slice_subslice(dev_priv, slice, subslice) { | ||
| 221 | stuck &= instdone_unchanged(instdone.sampler[slice][subslice], | ||
| 222 | &accu_instdone->sampler[slice][subslice]); | ||
| 223 | stuck &= instdone_unchanged(instdone.row[slice][subslice], | ||
| 224 | &accu_instdone->row[slice][subslice]); | ||
| 225 | } | ||
| 226 | |||
| 227 | return stuck; | ||
| 228 | } | ||
| 229 | |||
| 230 | static enum intel_engine_hangcheck_action | ||
| 231 | head_stuck(struct intel_engine_cs *engine, u64 acthd) | ||
| 232 | { | ||
| 233 | if (acthd != engine->hangcheck.acthd) { | ||
| 234 | |||
| 235 | /* Clear subunit states on head movement */ | ||
| 236 | memset(&engine->hangcheck.instdone, 0, | ||
| 237 | sizeof(engine->hangcheck.instdone)); | ||
| 238 | |||
| 239 | return HANGCHECK_ACTIVE; | ||
| 240 | } | ||
| 241 | |||
| 242 | if (!subunits_stuck(engine)) | ||
| 243 | return HANGCHECK_ACTIVE; | ||
| 244 | |||
| 245 | return HANGCHECK_HUNG; | ||
| 246 | } | ||
| 247 | |||
| 248 | static enum intel_engine_hangcheck_action | ||
| 249 | engine_stuck(struct intel_engine_cs *engine, u64 acthd) | ||
| 250 | { | ||
| 251 | struct drm_i915_private *dev_priv = engine->i915; | ||
| 252 | enum intel_engine_hangcheck_action ha; | ||
| 253 | u32 tmp; | ||
| 254 | |||
| 255 | ha = head_stuck(engine, acthd); | ||
| 256 | if (ha != HANGCHECK_HUNG) | ||
| 257 | return ha; | ||
| 258 | |||
| 259 | if (IS_GEN2(dev_priv)) | ||
| 260 | return HANGCHECK_HUNG; | ||
| 261 | |||
| 262 | /* Is the chip hanging on a WAIT_FOR_EVENT? | ||
| 263 | * If so we can simply poke the RB_WAIT bit | ||
| 264 | * and break the hang. This should work on | ||
| 265 | * all but the second generation chipsets. | ||
| 266 | */ | ||
| 267 | tmp = I915_READ_CTL(engine); | ||
| 268 | if (tmp & RING_WAIT) { | ||
| 269 | i915_handle_error(dev_priv, 0, | ||
| 270 | "Kicking stuck wait on %s", | ||
| 271 | engine->name); | ||
| 272 | I915_WRITE_CTL(engine, tmp); | ||
| 273 | return HANGCHECK_KICK; | ||
| 274 | } | ||
| 275 | |||
| 276 | if (INTEL_GEN(dev_priv) >= 6 && tmp & RING_WAIT_SEMAPHORE) { | ||
| 277 | switch (semaphore_passed(engine)) { | ||
| 278 | default: | ||
| 279 | return HANGCHECK_HUNG; | ||
| 280 | case 1: | ||
| 281 | i915_handle_error(dev_priv, 0, | ||
| 282 | "Kicking stuck semaphore on %s", | ||
| 283 | engine->name); | ||
| 284 | I915_WRITE_CTL(engine, tmp); | ||
| 285 | return HANGCHECK_KICK; | ||
| 286 | case 0: | ||
| 287 | return HANGCHECK_WAIT; | ||
| 288 | } | ||
| 289 | } | ||
| 290 | |||
| 291 | return HANGCHECK_HUNG; | ||
| 292 | } | ||
| 293 | |||
| 294 | /* | ||
| 295 | * This is called when the chip hasn't reported back with completed | ||
| 296 | * batchbuffers in a long time. We keep track per ring seqno progress and | ||
| 297 | * if there are no progress, hangcheck score for that ring is increased. | ||
| 298 | * Further, acthd is inspected to see if the ring is stuck. On stuck case | ||
| 299 | * we kick the ring. If we see no progress on three subsequent calls | ||
| 300 | * we assume chip is wedged and try to fix it by resetting the chip. | ||
| 301 | */ | ||
| 302 | static void i915_hangcheck_elapsed(struct work_struct *work) | ||
| 303 | { | ||
| 304 | struct drm_i915_private *dev_priv = | ||
| 305 | container_of(work, typeof(*dev_priv), | ||
| 306 | gpu_error.hangcheck_work.work); | ||
| 307 | struct intel_engine_cs *engine; | ||
| 308 | enum intel_engine_id id; | ||
| 309 | unsigned int hung = 0, stuck = 0; | ||
| 310 | int busy_count = 0; | ||
| 311 | #define BUSY 1 | ||
| 312 | #define KICK 5 | ||
| 313 | #define HUNG 20 | ||
| 314 | #define ACTIVE_DECAY 15 | ||
| 315 | |||
| 316 | if (!i915.enable_hangcheck) | ||
| 317 | return; | ||
| 318 | |||
| 319 | if (!READ_ONCE(dev_priv->gt.awake)) | ||
| 320 | return; | ||
| 321 | |||
| 322 | /* As enabling the GPU requires fairly extensive mmio access, | ||
| 323 | * periodically arm the mmio checker to see if we are triggering | ||
| 324 | * any invalid access. | ||
| 325 | */ | ||
| 326 | intel_uncore_arm_unclaimed_mmio_detection(dev_priv); | ||
| 327 | |||
| 328 | for_each_engine(engine, dev_priv, id) { | ||
| 329 | bool busy = intel_engine_has_waiter(engine); | ||
| 330 | u64 acthd; | ||
| 331 | u32 seqno; | ||
| 332 | u32 submit; | ||
| 333 | |||
| 334 | semaphore_clear_deadlocks(dev_priv); | ||
| 335 | |||
| 336 | /* We don't strictly need an irq-barrier here, as we are not | ||
| 337 | * serving an interrupt request, be paranoid in case the | ||
| 338 | * barrier has side-effects (such as preventing a broken | ||
| 339 | * cacheline snoop) and so be sure that we can see the seqno | ||
| 340 | * advance. If the seqno should stick, due to a stale | ||
| 341 | * cacheline, we would erroneously declare the GPU hung. | ||
| 342 | */ | ||
| 343 | if (engine->irq_seqno_barrier) | ||
| 344 | engine->irq_seqno_barrier(engine); | ||
| 345 | |||
| 346 | acthd = intel_engine_get_active_head(engine); | ||
| 347 | seqno = intel_engine_get_seqno(engine); | ||
| 348 | submit = intel_engine_last_submit(engine); | ||
| 349 | |||
| 350 | if (engine->hangcheck.seqno == seqno) { | ||
| 351 | if (i915_seqno_passed(seqno, submit)) { | ||
| 352 | engine->hangcheck.action = HANGCHECK_IDLE; | ||
| 353 | } else { | ||
| 354 | /* We always increment the hangcheck score | ||
| 355 | * if the engine is busy and still processing | ||
| 356 | * the same request, so that no single request | ||
| 357 | * can run indefinitely (such as a chain of | ||
| 358 | * batches). The only time we do not increment | ||
| 359 | * the hangcheck score on this ring, if this | ||
| 360 | * engine is in a legitimate wait for another | ||
| 361 | * engine. In that case the waiting engine is a | ||
| 362 | * victim and we want to be sure we catch the | ||
| 363 | * right culprit. Then every time we do kick | ||
| 364 | * the ring, add a small increment to the | ||
| 365 | * score so that we can catch a batch that is | ||
| 366 | * being repeatedly kicked and so responsible | ||
| 367 | * for stalling the machine. | ||
| 368 | */ | ||
| 369 | engine->hangcheck.action = | ||
| 370 | engine_stuck(engine, acthd); | ||
| 371 | |||
| 372 | switch (engine->hangcheck.action) { | ||
| 373 | case HANGCHECK_IDLE: | ||
| 374 | case HANGCHECK_WAIT: | ||
| 375 | break; | ||
| 376 | case HANGCHECK_ACTIVE: | ||
| 377 | engine->hangcheck.score += BUSY; | ||
| 378 | break; | ||
| 379 | case HANGCHECK_KICK: | ||
| 380 | engine->hangcheck.score += KICK; | ||
| 381 | break; | ||
| 382 | case HANGCHECK_HUNG: | ||
| 383 | engine->hangcheck.score += HUNG; | ||
| 384 | break; | ||
| 385 | } | ||
| 386 | } | ||
| 387 | |||
| 388 | if (engine->hangcheck.score >= HANGCHECK_SCORE_RING_HUNG) { | ||
| 389 | hung |= intel_engine_flag(engine); | ||
| 390 | if (engine->hangcheck.action != HANGCHECK_HUNG) | ||
| 391 | stuck |= intel_engine_flag(engine); | ||
| 392 | } | ||
| 393 | } else { | ||
| 394 | engine->hangcheck.action = HANGCHECK_ACTIVE; | ||
| 395 | |||
| 396 | /* Gradually reduce the count so that we catch DoS | ||
| 397 | * attempts across multiple batches. | ||
| 398 | */ | ||
| 399 | if (engine->hangcheck.score > 0) | ||
| 400 | engine->hangcheck.score -= ACTIVE_DECAY; | ||
| 401 | if (engine->hangcheck.score < 0) | ||
| 402 | engine->hangcheck.score = 0; | ||
| 403 | |||
| 404 | /* Clear head and subunit states on seqno movement */ | ||
| 405 | acthd = 0; | ||
| 406 | |||
| 407 | memset(&engine->hangcheck.instdone, 0, | ||
| 408 | sizeof(engine->hangcheck.instdone)); | ||
| 409 | } | ||
| 410 | |||
| 411 | engine->hangcheck.seqno = seqno; | ||
| 412 | engine->hangcheck.acthd = acthd; | ||
| 413 | busy_count += busy; | ||
| 414 | } | ||
| 415 | |||
| 416 | if (hung) { | ||
| 417 | char msg[80]; | ||
| 418 | unsigned int tmp; | ||
| 419 | int len; | ||
| 420 | |||
| 421 | /* If some rings hung but others were still busy, only | ||
| 422 | * blame the hanging rings in the synopsis. | ||
| 423 | */ | ||
| 424 | if (stuck != hung) | ||
| 425 | hung &= ~stuck; | ||
| 426 | len = scnprintf(msg, sizeof(msg), | ||
| 427 | "%s on ", stuck == hung ? "No progress" : "Hang"); | ||
| 428 | for_each_engine_masked(engine, dev_priv, hung, tmp) | ||
| 429 | len += scnprintf(msg + len, sizeof(msg) - len, | ||
| 430 | "%s, ", engine->name); | ||
| 431 | msg[len-2] = '\0'; | ||
| 432 | |||
| 433 | return i915_handle_error(dev_priv, hung, msg); | ||
| 434 | } | ||
| 435 | |||
| 436 | /* Reset timer in case GPU hangs without another request being added */ | ||
| 437 | if (busy_count) | ||
| 438 | i915_queue_hangcheck(dev_priv); | ||
| 439 | } | ||
| 440 | |||
| 441 | void intel_engine_init_hangcheck(struct intel_engine_cs *engine) | ||
| 442 | { | ||
| 443 | memset(&engine->hangcheck, 0, sizeof(engine->hangcheck)); | ||
| 444 | } | ||
| 445 | |||
| 446 | void intel_hangcheck_init(struct drm_i915_private *i915) | ||
| 447 | { | ||
| 448 | INIT_DELAYED_WORK(&i915->gpu_error.hangcheck_work, | ||
| 449 | i915_hangcheck_elapsed); | ||
| 450 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index af8715f31807..35ada4e1c6cf 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
| @@ -1164,7 +1164,7 @@ static void intel_disable_hdmi(struct intel_encoder *encoder, | |||
| 1164 | I915_WRITE(intel_hdmi->hdmi_reg, temp); | 1164 | I915_WRITE(intel_hdmi->hdmi_reg, temp); |
| 1165 | POSTING_READ(intel_hdmi->hdmi_reg); | 1165 | POSTING_READ(intel_hdmi->hdmi_reg); |
| 1166 | 1166 | ||
| 1167 | intel_wait_for_vblank_if_active(&dev_priv->drm, PIPE_A); | 1167 | intel_wait_for_vblank_if_active(dev_priv, PIPE_A); |
| 1168 | intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); | 1168 | intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); |
| 1169 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); | 1169 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); |
| 1170 | } | 1170 | } |
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index bc86585b9fbb..dde04b7643b1 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c | |||
| @@ -365,7 +365,7 @@ static u64 execlists_update_context(struct drm_i915_gem_request *rq) | |||
| 365 | struct i915_hw_ppgtt *ppgtt = rq->ctx->ppgtt; | 365 | struct i915_hw_ppgtt *ppgtt = rq->ctx->ppgtt; |
| 366 | u32 *reg_state = ce->lrc_reg_state; | 366 | u32 *reg_state = ce->lrc_reg_state; |
| 367 | 367 | ||
| 368 | reg_state[CTX_RING_TAIL+1] = intel_ring_offset(rq->ring, rq->tail); | 368 | reg_state[CTX_RING_TAIL+1] = rq->tail; |
| 369 | 369 | ||
| 370 | /* True 32b PPGTT with dynamic page allocation: update PDP | 370 | /* True 32b PPGTT with dynamic page allocation: update PDP |
| 371 | * registers and point the unallocated PDPs to scratch page. | 371 | * registers and point the unallocated PDPs to scratch page. |
| @@ -440,7 +440,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) | |||
| 440 | if (last) | 440 | if (last) |
| 441 | /* WaIdleLiteRestore:bdw,skl | 441 | /* WaIdleLiteRestore:bdw,skl |
| 442 | * Apply the wa NOOPs to prevent ring:HEAD == req:TAIL | 442 | * Apply the wa NOOPs to prevent ring:HEAD == req:TAIL |
| 443 | * as we resubmit the request. See gen8_emit_request() | 443 | * as we resubmit the request. See gen8_emit_breadcrumb() |
| 444 | * for where we prepare the padding after the end of the | 444 | * for where we prepare the padding after the end of the |
| 445 | * request. | 445 | * request. |
| 446 | */ | 446 | */ |
| @@ -522,6 +522,28 @@ static bool execlists_elsp_idle(struct intel_engine_cs *engine) | |||
| 522 | return !engine->execlist_port[0].request; | 522 | return !engine->execlist_port[0].request; |
| 523 | } | 523 | } |
| 524 | 524 | ||
| 525 | /** | ||
| 526 | * intel_execlists_idle() - Determine if all engine submission ports are idle | ||
| 527 | * @dev_priv: i915 device private | ||
| 528 | * | ||
| 529 | * Return true if there are no requests pending on any of the submission ports | ||
| 530 | * of any engines. | ||
| 531 | */ | ||
| 532 | bool intel_execlists_idle(struct drm_i915_private *dev_priv) | ||
| 533 | { | ||
| 534 | struct intel_engine_cs *engine; | ||
| 535 | enum intel_engine_id id; | ||
| 536 | |||
| 537 | if (!i915.enable_execlists) | ||
| 538 | return true; | ||
| 539 | |||
| 540 | for_each_engine(engine, dev_priv, id) | ||
| 541 | if (!execlists_elsp_idle(engine)) | ||
| 542 | return false; | ||
| 543 | |||
| 544 | return true; | ||
| 545 | } | ||
| 546 | |||
| 525 | static bool execlists_elsp_ready(struct intel_engine_cs *engine) | 547 | static bool execlists_elsp_ready(struct intel_engine_cs *engine) |
| 526 | { | 548 | { |
| 527 | int port; | 549 | int port; |
| @@ -599,6 +621,15 @@ static void execlists_submit_request(struct drm_i915_gem_request *request) | |||
| 599 | 621 | ||
| 600 | spin_lock_irqsave(&engine->execlist_lock, flags); | 622 | spin_lock_irqsave(&engine->execlist_lock, flags); |
| 601 | 623 | ||
| 624 | /* We keep the previous context alive until we retire the following | ||
| 625 | * request. This ensures that any the context object is still pinned | ||
| 626 | * for any residual writes the HW makes into it on the context switch | ||
| 627 | * into the next object following the breadcrumb. Otherwise, we may | ||
| 628 | * retire the context too early. | ||
| 629 | */ | ||
| 630 | request->previous_context = engine->last_context; | ||
| 631 | engine->last_context = request->ctx; | ||
| 632 | |||
| 602 | list_add_tail(&request->execlist_link, &engine->execlist_queue); | 633 | list_add_tail(&request->execlist_link, &engine->execlist_queue); |
| 603 | if (execlists_elsp_idle(engine)) | 634 | if (execlists_elsp_idle(engine)) |
| 604 | tasklet_hi_schedule(&engine->irq_tasklet); | 635 | tasklet_hi_schedule(&engine->irq_tasklet); |
| @@ -671,46 +702,6 @@ err_unpin: | |||
| 671 | return ret; | 702 | return ret; |
| 672 | } | 703 | } |
| 673 | 704 | ||
| 674 | /* | ||
| 675 | * intel_logical_ring_advance() - advance the tail and prepare for submission | ||
| 676 | * @request: Request to advance the logical ringbuffer of. | ||
| 677 | * | ||
| 678 | * The tail is updated in our logical ringbuffer struct, not in the actual context. What | ||
| 679 | * really happens during submission is that the context and current tail will be placed | ||
| 680 | * on a queue waiting for the ELSP to be ready to accept a new context submission. At that | ||
| 681 | * point, the tail *inside* the context is updated and the ELSP written to. | ||
| 682 | */ | ||
| 683 | static int | ||
| 684 | intel_logical_ring_advance(struct drm_i915_gem_request *request) | ||
| 685 | { | ||
| 686 | struct intel_ring *ring = request->ring; | ||
| 687 | struct intel_engine_cs *engine = request->engine; | ||
| 688 | |||
| 689 | intel_ring_advance(ring); | ||
| 690 | request->tail = ring->tail; | ||
| 691 | |||
| 692 | /* | ||
| 693 | * Here we add two extra NOOPs as padding to avoid | ||
| 694 | * lite restore of a context with HEAD==TAIL. | ||
| 695 | * | ||
| 696 | * Caller must reserve WA_TAIL_DWORDS for us! | ||
| 697 | */ | ||
| 698 | intel_ring_emit(ring, MI_NOOP); | ||
| 699 | intel_ring_emit(ring, MI_NOOP); | ||
| 700 | intel_ring_advance(ring); | ||
| 701 | request->wa_tail = ring->tail; | ||
| 702 | |||
| 703 | /* We keep the previous context alive until we retire the following | ||
| 704 | * request. This ensures that any the context object is still pinned | ||
| 705 | * for any residual writes the HW makes into it on the context switch | ||
| 706 | * into the next object following the breadcrumb. Otherwise, we may | ||
| 707 | * retire the context too early. | ||
| 708 | */ | ||
| 709 | request->previous_context = engine->last_context; | ||
| 710 | engine->last_context = request->ctx; | ||
| 711 | return 0; | ||
| 712 | } | ||
| 713 | |||
| 714 | static int intel_lr_context_pin(struct i915_gem_context *ctx, | 705 | static int intel_lr_context_pin(struct i915_gem_context *ctx, |
| 715 | struct intel_engine_cs *engine) | 706 | struct intel_engine_cs *engine) |
| 716 | { | 707 | { |
| @@ -744,7 +735,7 @@ static int intel_lr_context_pin(struct i915_gem_context *ctx, | |||
| 744 | ce->lrc_reg_state[CTX_RING_BUFFER_START+1] = | 735 | ce->lrc_reg_state[CTX_RING_BUFFER_START+1] = |
| 745 | i915_ggtt_offset(ce->ring->vma); | 736 | i915_ggtt_offset(ce->ring->vma); |
| 746 | 737 | ||
| 747 | ce->state->obj->dirty = true; | 738 | ce->state->obj->mm.dirty = true; |
| 748 | 739 | ||
| 749 | /* Invalidate GuC TLB. */ | 740 | /* Invalidate GuC TLB. */ |
| 750 | if (i915.enable_guc_submission) { | 741 | if (i915.enable_guc_submission) { |
| @@ -1566,39 +1557,35 @@ static void bxt_a_seqno_barrier(struct intel_engine_cs *engine) | |||
| 1566 | * used as a workaround for not being allowed to do lite | 1557 | * used as a workaround for not being allowed to do lite |
| 1567 | * restore with HEAD==TAIL (WaIdleLiteRestore). | 1558 | * restore with HEAD==TAIL (WaIdleLiteRestore). |
| 1568 | */ | 1559 | */ |
| 1569 | 1560 | static void gen8_emit_wa_tail(struct drm_i915_gem_request *request, u32 *out) | |
| 1570 | static int gen8_emit_request(struct drm_i915_gem_request *request) | ||
| 1571 | { | 1561 | { |
| 1572 | struct intel_ring *ring = request->ring; | 1562 | *out++ = MI_NOOP; |
| 1573 | int ret; | 1563 | *out++ = MI_NOOP; |
| 1574 | 1564 | request->wa_tail = intel_ring_offset(request->ring, out); | |
| 1575 | ret = intel_ring_begin(request, 6 + WA_TAIL_DWORDS); | 1565 | } |
| 1576 | if (ret) | ||
| 1577 | return ret; | ||
| 1578 | 1566 | ||
| 1567 | static void gen8_emit_breadcrumb(struct drm_i915_gem_request *request, | ||
| 1568 | u32 *out) | ||
| 1569 | { | ||
| 1579 | /* w/a: bit 5 needs to be zero for MI_FLUSH_DW address. */ | 1570 | /* w/a: bit 5 needs to be zero for MI_FLUSH_DW address. */ |
| 1580 | BUILD_BUG_ON(I915_GEM_HWS_INDEX_ADDR & (1 << 5)); | 1571 | BUILD_BUG_ON(I915_GEM_HWS_INDEX_ADDR & (1 << 5)); |
| 1581 | 1572 | ||
| 1582 | intel_ring_emit(ring, (MI_FLUSH_DW + 1) | MI_FLUSH_DW_OP_STOREDW); | 1573 | *out++ = (MI_FLUSH_DW + 1) | MI_FLUSH_DW_OP_STOREDW; |
| 1583 | intel_ring_emit(ring, | 1574 | *out++ = intel_hws_seqno_address(request->engine) | MI_FLUSH_DW_USE_GTT; |
| 1584 | intel_hws_seqno_address(request->engine) | | 1575 | *out++ = 0; |
| 1585 | MI_FLUSH_DW_USE_GTT); | 1576 | *out++ = request->global_seqno; |
| 1586 | intel_ring_emit(ring, 0); | 1577 | *out++ = MI_USER_INTERRUPT; |
| 1587 | intel_ring_emit(ring, request->fence.seqno); | 1578 | *out++ = MI_NOOP; |
| 1588 | intel_ring_emit(ring, MI_USER_INTERRUPT); | 1579 | request->tail = intel_ring_offset(request->ring, out); |
| 1589 | intel_ring_emit(ring, MI_NOOP); | 1580 | |
| 1590 | return intel_logical_ring_advance(request); | 1581 | gen8_emit_wa_tail(request, out); |
| 1591 | } | 1582 | } |
| 1592 | 1583 | ||
| 1593 | static int gen8_emit_request_render(struct drm_i915_gem_request *request) | 1584 | static const int gen8_emit_breadcrumb_sz = 6 + WA_TAIL_DWORDS; |
| 1594 | { | ||
| 1595 | struct intel_ring *ring = request->ring; | ||
| 1596 | int ret; | ||
| 1597 | |||
| 1598 | ret = intel_ring_begin(request, 8 + WA_TAIL_DWORDS); | ||
| 1599 | if (ret) | ||
| 1600 | return ret; | ||
| 1601 | 1585 | ||
| 1586 | static void gen8_emit_breadcrumb_render(struct drm_i915_gem_request *request, | ||
| 1587 | u32 *out) | ||
| 1588 | { | ||
| 1602 | /* We're using qword write, seqno should be aligned to 8 bytes. */ | 1589 | /* We're using qword write, seqno should be aligned to 8 bytes. */ |
| 1603 | BUILD_BUG_ON(I915_GEM_HWS_INDEX & 1); | 1590 | BUILD_BUG_ON(I915_GEM_HWS_INDEX & 1); |
| 1604 | 1591 | ||
| @@ -1606,21 +1593,24 @@ static int gen8_emit_request_render(struct drm_i915_gem_request *request) | |||
| 1606 | * need a prior CS_STALL, which is emitted by the flush | 1593 | * need a prior CS_STALL, which is emitted by the flush |
| 1607 | * following the batch. | 1594 | * following the batch. |
| 1608 | */ | 1595 | */ |
| 1609 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(6)); | 1596 | *out++ = GFX_OP_PIPE_CONTROL(6); |
| 1610 | intel_ring_emit(ring, | 1597 | *out++ = (PIPE_CONTROL_GLOBAL_GTT_IVB | |
| 1611 | (PIPE_CONTROL_GLOBAL_GTT_IVB | | 1598 | PIPE_CONTROL_CS_STALL | |
| 1612 | PIPE_CONTROL_CS_STALL | | 1599 | PIPE_CONTROL_QW_WRITE); |
| 1613 | PIPE_CONTROL_QW_WRITE)); | 1600 | *out++ = intel_hws_seqno_address(request->engine); |
| 1614 | intel_ring_emit(ring, intel_hws_seqno_address(request->engine)); | 1601 | *out++ = 0; |
| 1615 | intel_ring_emit(ring, 0); | 1602 | *out++ = request->global_seqno; |
| 1616 | intel_ring_emit(ring, i915_gem_request_get_seqno(request)); | ||
| 1617 | /* We're thrashing one dword of HWS. */ | 1603 | /* We're thrashing one dword of HWS. */ |
| 1618 | intel_ring_emit(ring, 0); | 1604 | *out++ = 0; |
| 1619 | intel_ring_emit(ring, MI_USER_INTERRUPT); | 1605 | *out++ = MI_USER_INTERRUPT; |
| 1620 | intel_ring_emit(ring, MI_NOOP); | 1606 | *out++ = MI_NOOP; |
| 1621 | return intel_logical_ring_advance(request); | 1607 | request->tail = intel_ring_offset(request->ring, out); |
| 1608 | |||
| 1609 | gen8_emit_wa_tail(request, out); | ||
| 1622 | } | 1610 | } |
| 1623 | 1611 | ||
| 1612 | static const int gen8_emit_breadcrumb_render_sz = 8 + WA_TAIL_DWORDS; | ||
| 1613 | |||
| 1624 | static int gen8_init_rcs_context(struct drm_i915_gem_request *req) | 1614 | static int gen8_init_rcs_context(struct drm_i915_gem_request *req) |
| 1625 | { | 1615 | { |
| 1626 | int ret; | 1616 | int ret; |
| @@ -1637,7 +1627,7 @@ static int gen8_init_rcs_context(struct drm_i915_gem_request *req) | |||
| 1637 | if (ret) | 1627 | if (ret) |
| 1638 | DRM_ERROR("MOCS failed to program: expect performance issues.\n"); | 1628 | DRM_ERROR("MOCS failed to program: expect performance issues.\n"); |
| 1639 | 1629 | ||
| 1640 | return i915_gem_render_state_init(req); | 1630 | return i915_gem_render_state_emit(req); |
| 1641 | } | 1631 | } |
| 1642 | 1632 | ||
| 1643 | /** | 1633 | /** |
| @@ -1694,7 +1684,8 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine) | |||
| 1694 | engine->init_hw = gen8_init_common_ring; | 1684 | engine->init_hw = gen8_init_common_ring; |
| 1695 | engine->reset_hw = reset_common_ring; | 1685 | engine->reset_hw = reset_common_ring; |
| 1696 | engine->emit_flush = gen8_emit_flush; | 1686 | engine->emit_flush = gen8_emit_flush; |
| 1697 | engine->emit_request = gen8_emit_request; | 1687 | engine->emit_breadcrumb = gen8_emit_breadcrumb; |
| 1688 | engine->emit_breadcrumb_sz = gen8_emit_breadcrumb_sz; | ||
| 1698 | engine->submit_request = execlists_submit_request; | 1689 | engine->submit_request = execlists_submit_request; |
| 1699 | 1690 | ||
| 1700 | engine->irq_enable = gen8_logical_ring_enable_irq; | 1691 | engine->irq_enable = gen8_logical_ring_enable_irq; |
| @@ -1816,7 +1807,8 @@ int logical_render_ring_init(struct intel_engine_cs *engine) | |||
| 1816 | engine->init_hw = gen8_init_render_ring; | 1807 | engine->init_hw = gen8_init_render_ring; |
| 1817 | engine->init_context = gen8_init_rcs_context; | 1808 | engine->init_context = gen8_init_rcs_context; |
| 1818 | engine->emit_flush = gen8_emit_flush_render; | 1809 | engine->emit_flush = gen8_emit_flush_render; |
| 1819 | engine->emit_request = gen8_emit_request_render; | 1810 | engine->emit_breadcrumb = gen8_emit_breadcrumb_render; |
| 1811 | engine->emit_breadcrumb_sz = gen8_emit_breadcrumb_render_sz; | ||
| 1820 | 1812 | ||
| 1821 | ret = intel_engine_create_scratch(engine, 4096); | 1813 | ret = intel_engine_create_scratch(engine, 4096); |
| 1822 | if (ret) | 1814 | if (ret) |
| @@ -2042,7 +2034,7 @@ populate_lr_context(struct i915_gem_context *ctx, | |||
| 2042 | DRM_DEBUG_DRIVER("Could not map object pages! (%d)\n", ret); | 2034 | DRM_DEBUG_DRIVER("Could not map object pages! (%d)\n", ret); |
| 2043 | return ret; | 2035 | return ret; |
| 2044 | } | 2036 | } |
| 2045 | ctx_obj->dirty = true; | 2037 | ctx_obj->mm.dirty = true; |
| 2046 | 2038 | ||
| 2047 | /* The second page of the context object contains some fields which must | 2039 | /* The second page of the context object contains some fields which must |
| 2048 | * be set up prior to the first execution. */ | 2040 | * be set up prior to the first execution. */ |
| @@ -2180,7 +2172,7 @@ void intel_lr_context_resume(struct drm_i915_private *dev_priv) | |||
| 2180 | reg[CTX_RING_HEAD+1] = 0; | 2172 | reg[CTX_RING_HEAD+1] = 0; |
| 2181 | reg[CTX_RING_TAIL+1] = 0; | 2173 | reg[CTX_RING_TAIL+1] = 0; |
| 2182 | 2174 | ||
| 2183 | ce->state->obj->dirty = true; | 2175 | ce->state->obj->mm.dirty = true; |
| 2184 | i915_gem_object_unpin_map(ce->state->obj); | 2176 | i915_gem_object_unpin_map(ce->state->obj); |
| 2185 | 2177 | ||
| 2186 | ce->ring->head = ce->ring->tail = 0; | 2178 | ce->ring->head = ce->ring->tail = 0; |
diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 4fed8165f98a..c1f546180ba2 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h | |||
| @@ -95,5 +95,6 @@ uint64_t intel_lr_context_descriptor(struct i915_gem_context *ctx, | |||
| 95 | int intel_sanitize_enable_execlists(struct drm_i915_private *dev_priv, | 95 | int intel_sanitize_enable_execlists(struct drm_i915_private *dev_priv, |
| 96 | int enable_execlists); | 96 | int enable_execlists); |
| 97 | void intel_execlists_enable_submission(struct drm_i915_private *dev_priv); | 97 | void intel_execlists_enable_submission(struct drm_i915_private *dev_priv); |
| 98 | bool intel_execlists_idle(struct drm_i915_private *dev_priv); | ||
| 98 | 99 | ||
| 99 | #endif /* _INTEL_LRC_H_ */ | 100 | #endif /* _INTEL_LRC_H_ */ |
diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c index 632149c6b3ad..daa523410953 100644 --- a/drivers/gpu/drm/i915/intel_lspcon.c +++ b/drivers/gpu/drm/i915/intel_lspcon.c | |||
| @@ -27,10 +27,18 @@ | |||
| 27 | #include <drm/drm_dp_dual_mode_helper.h> | 27 | #include <drm/drm_dp_dual_mode_helper.h> |
| 28 | #include "intel_drv.h" | 28 | #include "intel_drv.h" |
| 29 | 29 | ||
| 30 | static struct intel_dp *lspcon_to_intel_dp(struct intel_lspcon *lspcon) | ||
| 31 | { | ||
| 32 | struct intel_digital_port *dig_port = | ||
| 33 | container_of(lspcon, struct intel_digital_port, lspcon); | ||
| 34 | |||
| 35 | return &dig_port->dp; | ||
| 36 | } | ||
| 37 | |||
| 30 | static enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon) | 38 | static enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon) |
| 31 | { | 39 | { |
| 32 | enum drm_lspcon_mode current_mode = DRM_LSPCON_MODE_INVALID; | 40 | enum drm_lspcon_mode current_mode = DRM_LSPCON_MODE_INVALID; |
| 33 | struct i2c_adapter *adapter = &lspcon->aux->ddc; | 41 | struct i2c_adapter *adapter = &lspcon_to_intel_dp(lspcon)->aux.ddc; |
| 34 | 42 | ||
| 35 | if (drm_lspcon_get_mode(adapter, ¤t_mode)) | 43 | if (drm_lspcon_get_mode(adapter, ¤t_mode)) |
| 36 | DRM_ERROR("Error reading LSPCON mode\n"); | 44 | DRM_ERROR("Error reading LSPCON mode\n"); |
| @@ -45,7 +53,7 @@ static int lspcon_change_mode(struct intel_lspcon *lspcon, | |||
| 45 | { | 53 | { |
| 46 | int err; | 54 | int err; |
| 47 | enum drm_lspcon_mode current_mode; | 55 | enum drm_lspcon_mode current_mode; |
| 48 | struct i2c_adapter *adapter = &lspcon->aux->ddc; | 56 | struct i2c_adapter *adapter = &lspcon_to_intel_dp(lspcon)->aux.ddc; |
| 49 | 57 | ||
| 50 | err = drm_lspcon_get_mode(adapter, ¤t_mode); | 58 | err = drm_lspcon_get_mode(adapter, ¤t_mode); |
| 51 | if (err) { | 59 | if (err) { |
| @@ -72,7 +80,7 @@ static int lspcon_change_mode(struct intel_lspcon *lspcon, | |||
| 72 | static bool lspcon_probe(struct intel_lspcon *lspcon) | 80 | static bool lspcon_probe(struct intel_lspcon *lspcon) |
| 73 | { | 81 | { |
| 74 | enum drm_dp_dual_mode_type adaptor_type; | 82 | enum drm_dp_dual_mode_type adaptor_type; |
| 75 | struct i2c_adapter *adapter = &lspcon->aux->ddc; | 83 | struct i2c_adapter *adapter = &lspcon_to_intel_dp(lspcon)->aux.ddc; |
| 76 | 84 | ||
| 77 | /* Lets probe the adaptor and check its type */ | 85 | /* Lets probe the adaptor and check its type */ |
| 78 | adaptor_type = drm_dp_dual_mode_detect(adapter); | 86 | adaptor_type = drm_dp_dual_mode_detect(adapter); |
| @@ -89,8 +97,43 @@ static bool lspcon_probe(struct intel_lspcon *lspcon) | |||
| 89 | return true; | 97 | return true; |
| 90 | } | 98 | } |
| 91 | 99 | ||
| 100 | static void lspcon_resume_in_pcon_wa(struct intel_lspcon *lspcon) | ||
| 101 | { | ||
| 102 | struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); | ||
| 103 | unsigned long start = jiffies; | ||
| 104 | |||
| 105 | if (!lspcon->desc_valid) | ||
| 106 | return; | ||
| 107 | |||
| 108 | while (1) { | ||
| 109 | struct intel_dp_desc desc; | ||
| 110 | |||
| 111 | /* | ||
| 112 | * The w/a only applies in PCON mode and we don't expect any | ||
| 113 | * AUX errors. | ||
| 114 | */ | ||
| 115 | if (!__intel_dp_read_desc(intel_dp, &desc)) | ||
| 116 | return; | ||
| 117 | |||
| 118 | if (!memcmp(&intel_dp->desc, &desc, sizeof(desc))) { | ||
| 119 | DRM_DEBUG_KMS("LSPCON recovering in PCON mode after %u ms\n", | ||
| 120 | jiffies_to_msecs(jiffies - start)); | ||
| 121 | return; | ||
| 122 | } | ||
| 123 | |||
| 124 | if (time_after(jiffies, start + msecs_to_jiffies(1000))) | ||
| 125 | break; | ||
| 126 | |||
| 127 | usleep_range(10000, 15000); | ||
| 128 | } | ||
| 129 | |||
| 130 | DRM_DEBUG_KMS("LSPCON DP descriptor mismatch after resume\n"); | ||
| 131 | } | ||
| 132 | |||
| 92 | void lspcon_resume(struct intel_lspcon *lspcon) | 133 | void lspcon_resume(struct intel_lspcon *lspcon) |
| 93 | { | 134 | { |
| 135 | lspcon_resume_in_pcon_wa(lspcon); | ||
| 136 | |||
| 94 | if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON, true)) | 137 | if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON, true)) |
| 95 | DRM_ERROR("LSPCON resume failed\n"); | 138 | DRM_ERROR("LSPCON resume failed\n"); |
| 96 | else | 139 | else |
| @@ -111,7 +154,6 @@ bool lspcon_init(struct intel_digital_port *intel_dig_port) | |||
| 111 | 154 | ||
| 112 | lspcon->active = false; | 155 | lspcon->active = false; |
| 113 | lspcon->mode = DRM_LSPCON_MODE_INVALID; | 156 | lspcon->mode = DRM_LSPCON_MODE_INVALID; |
| 114 | lspcon->aux = &dp->aux; | ||
| 115 | 157 | ||
| 116 | if (!lspcon_probe(lspcon)) { | 158 | if (!lspcon_probe(lspcon)) { |
| 117 | DRM_ERROR("Failed to probe lspcon\n"); | 159 | DRM_ERROR("Failed to probe lspcon\n"); |
| @@ -131,6 +173,13 @@ bool lspcon_init(struct intel_digital_port *intel_dig_port) | |||
| 131 | } | 173 | } |
| 132 | } | 174 | } |
| 133 | 175 | ||
| 176 | if (!intel_dp_read_dpcd(dp)) { | ||
| 177 | DRM_ERROR("LSPCON DPCD read failed\n"); | ||
| 178 | return false; | ||
| 179 | } | ||
| 180 | |||
| 181 | lspcon->desc_valid = intel_dp_read_desc(dp); | ||
| 182 | |||
| 134 | DRM_DEBUG_KMS("Success: LSPCON init\n"); | 183 | DRM_DEBUG_KMS("Success: LSPCON init\n"); |
| 135 | return true; | 184 | return true; |
| 136 | } | 185 | } |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 199b90c7907a..de7b3e6ed477 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -985,7 +985,7 @@ void intel_lvds_init(struct drm_device *dev) | |||
| 985 | struct drm_display_mode *fixed_mode = NULL; | 985 | struct drm_display_mode *fixed_mode = NULL; |
| 986 | struct drm_display_mode *downclock_mode = NULL; | 986 | struct drm_display_mode *downclock_mode = NULL; |
| 987 | struct edid *edid; | 987 | struct edid *edid; |
| 988 | struct drm_crtc *crtc; | 988 | struct intel_crtc *crtc; |
| 989 | i915_reg_t lvds_reg; | 989 | i915_reg_t lvds_reg; |
| 990 | u32 lvds; | 990 | u32 lvds; |
| 991 | int pipe; | 991 | int pipe; |
| @@ -1163,10 +1163,10 @@ void intel_lvds_init(struct drm_device *dev) | |||
| 1163 | goto failed; | 1163 | goto failed; |
| 1164 | 1164 | ||
| 1165 | pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; | 1165 | pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; |
| 1166 | crtc = intel_get_crtc_for_pipe(dev, pipe); | 1166 | crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
| 1167 | 1167 | ||
| 1168 | if (crtc && (lvds & LVDS_PORT_EN)) { | 1168 | if (crtc && (lvds & LVDS_PORT_EN)) { |
| 1169 | fixed_mode = intel_crtc_mode_get(dev, crtc); | 1169 | fixed_mode = intel_crtc_mode_get(dev, &crtc->base); |
| 1170 | if (fixed_mode) { | 1170 | if (fixed_mode) { |
| 1171 | DRM_DEBUG_KMS("using current (BIOS) mode: "); | 1171 | DRM_DEBUG_KMS("using current (BIOS) mode: "); |
| 1172 | drm_mode_debug_printmodeline(fixed_mode); | 1172 | drm_mode_debug_printmodeline(fixed_mode); |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 25bcd4a178d3..fd0e4dac7cc1 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
| @@ -1222,7 +1222,7 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data, | |||
| 1222 | out_unlock: | 1222 | out_unlock: |
| 1223 | mutex_unlock(&dev->struct_mutex); | 1223 | mutex_unlock(&dev->struct_mutex); |
| 1224 | drm_modeset_unlock_all(dev); | 1224 | drm_modeset_unlock_all(dev); |
| 1225 | i915_gem_object_put_unlocked(new_bo); | 1225 | i915_gem_object_put(new_bo); |
| 1226 | out_free: | 1226 | out_free: |
| 1227 | kfree(params); | 1227 | kfree(params); |
| 1228 | 1228 | ||
| @@ -1466,7 +1466,7 @@ void intel_cleanup_overlay(struct drm_i915_private *dev_priv) | |||
| 1466 | * hardware should be off already */ | 1466 | * hardware should be off already */ |
| 1467 | WARN_ON(dev_priv->overlay->active); | 1467 | WARN_ON(dev_priv->overlay->active); |
| 1468 | 1468 | ||
| 1469 | i915_gem_object_put_unlocked(dev_priv->overlay->reg_bo); | 1469 | i915_gem_object_put(dev_priv->overlay->reg_bo); |
| 1470 | kfree(dev_priv->overlay); | 1470 | kfree(dev_priv->overlay); |
| 1471 | } | 1471 | } |
| 1472 | 1472 | ||
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 560fc7af8267..cc9e0c0f445f 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include "intel_drv.h" | 31 | #include "intel_drv.h" |
| 32 | #include "../../../platform/x86/intel_ips.h" | 32 | #include "../../../platform/x86/intel_ips.h" |
| 33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
| 34 | #include <drm/drm_atomic_helper.h> | ||
| 34 | 35 | ||
| 35 | /** | 36 | /** |
| 36 | * DOC: RC6 | 37 | * DOC: RC6 |
| @@ -55,10 +56,8 @@ | |||
| 55 | #define INTEL_RC6p_ENABLE (1<<1) | 56 | #define INTEL_RC6p_ENABLE (1<<1) |
| 56 | #define INTEL_RC6pp_ENABLE (1<<2) | 57 | #define INTEL_RC6pp_ENABLE (1<<2) |
| 57 | 58 | ||
| 58 | static void gen9_init_clock_gating(struct drm_device *dev) | 59 | static void gen9_init_clock_gating(struct drm_i915_private *dev_priv) |
| 59 | { | 60 | { |
| 60 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 61 | |||
| 62 | /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl */ | 61 | /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl */ |
| 63 | I915_WRITE(CHICKEN_PAR1_1, | 62 | I915_WRITE(CHICKEN_PAR1_1, |
| 64 | I915_READ(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP); | 63 | I915_READ(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP); |
| @@ -81,11 +80,9 @@ static void gen9_init_clock_gating(struct drm_device *dev) | |||
| 81 | ILK_DPFC_DISABLE_DUMMY0); | 80 | ILK_DPFC_DISABLE_DUMMY0); |
| 82 | } | 81 | } |
| 83 | 82 | ||
| 84 | static void bxt_init_clock_gating(struct drm_device *dev) | 83 | static void bxt_init_clock_gating(struct drm_i915_private *dev_priv) |
| 85 | { | 84 | { |
| 86 | struct drm_i915_private *dev_priv = to_i915(dev); | 85 | gen9_init_clock_gating(dev_priv); |
| 87 | |||
| 88 | gen9_init_clock_gating(dev); | ||
| 89 | 86 | ||
| 90 | /* WaDisableSDEUnitClockGating:bxt */ | 87 | /* WaDisableSDEUnitClockGating:bxt */ |
| 91 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | | 88 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | |
| @@ -107,9 +104,8 @@ static void bxt_init_clock_gating(struct drm_device *dev) | |||
| 107 | PWM1_GATING_DIS | PWM2_GATING_DIS); | 104 | PWM1_GATING_DIS | PWM2_GATING_DIS); |
| 108 | } | 105 | } |
| 109 | 106 | ||
| 110 | static void i915_pineview_get_mem_freq(struct drm_device *dev) | 107 | static void i915_pineview_get_mem_freq(struct drm_i915_private *dev_priv) |
| 111 | { | 108 | { |
| 112 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 113 | u32 tmp; | 109 | u32 tmp; |
| 114 | 110 | ||
| 115 | tmp = I915_READ(CLKCFG); | 111 | tmp = I915_READ(CLKCFG); |
| @@ -146,9 +142,8 @@ static void i915_pineview_get_mem_freq(struct drm_device *dev) | |||
| 146 | dev_priv->is_ddr3 = (tmp & CSHRDDR3CTL_DDR3) ? 1 : 0; | 142 | dev_priv->is_ddr3 = (tmp & CSHRDDR3CTL_DDR3) ? 1 : 0; |
| 147 | } | 143 | } |
| 148 | 144 | ||
| 149 | static void i915_ironlake_get_mem_freq(struct drm_device *dev) | 145 | static void i915_ironlake_get_mem_freq(struct drm_i915_private *dev_priv) |
| 150 | { | 146 | { |
| 151 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 152 | u16 ddrpll, csipll; | 147 | u16 ddrpll, csipll; |
| 153 | 148 | ||
| 154 | ddrpll = I915_READ16(DDRMPLL1); | 149 | ddrpll = I915_READ16(DDRMPLL1); |
| @@ -319,7 +314,6 @@ static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable) | |||
| 319 | 314 | ||
| 320 | void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable) | 315 | void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable) |
| 321 | { | 316 | { |
| 322 | struct drm_device *dev = &dev_priv->drm; | ||
| 323 | u32 val; | 317 | u32 val; |
| 324 | 318 | ||
| 325 | if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { | 319 | if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { |
| @@ -329,7 +323,7 @@ void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable) | |||
| 329 | } else if (IS_G4X(dev_priv) || IS_CRESTLINE(dev_priv)) { | 323 | } else if (IS_G4X(dev_priv) || IS_CRESTLINE(dev_priv)) { |
| 330 | I915_WRITE(FW_BLC_SELF, enable ? FW_BLC_SELF_EN : 0); | 324 | I915_WRITE(FW_BLC_SELF, enable ? FW_BLC_SELF_EN : 0); |
| 331 | POSTING_READ(FW_BLC_SELF); | 325 | POSTING_READ(FW_BLC_SELF); |
| 332 | } else if (IS_PINEVIEW(dev)) { | 326 | } else if (IS_PINEVIEW(dev_priv)) { |
| 333 | val = I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN; | 327 | val = I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN; |
| 334 | val |= enable ? PINEVIEW_SELF_REFRESH_EN : 0; | 328 | val |= enable ? PINEVIEW_SELF_REFRESH_EN : 0; |
| 335 | I915_WRITE(DSPFW3, val); | 329 | I915_WRITE(DSPFW3, val); |
| @@ -377,10 +371,9 @@ static const int pessimal_latency_ns = 5000; | |||
| 377 | #define VLV_FIFO_START(dsparb, dsparb2, lo_shift, hi_shift) \ | 371 | #define VLV_FIFO_START(dsparb, dsparb2, lo_shift, hi_shift) \ |
| 378 | ((((dsparb) >> (lo_shift)) & 0xff) | ((((dsparb2) >> (hi_shift)) & 0x1) << 8)) | 372 | ((((dsparb) >> (lo_shift)) & 0xff) | ((((dsparb2) >> (hi_shift)) & 0x1) << 8)) |
| 379 | 373 | ||
| 380 | static int vlv_get_fifo_size(struct drm_device *dev, | 374 | static int vlv_get_fifo_size(struct drm_i915_private *dev_priv, |
| 381 | enum pipe pipe, int plane) | 375 | enum pipe pipe, int plane) |
| 382 | { | 376 | { |
| 383 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 384 | int sprite0_start, sprite1_start, size; | 377 | int sprite0_start, sprite1_start, size; |
| 385 | 378 | ||
| 386 | switch (pipe) { | 379 | switch (pipe) { |
| @@ -429,9 +422,8 @@ static int vlv_get_fifo_size(struct drm_device *dev, | |||
| 429 | return size; | 422 | return size; |
| 430 | } | 423 | } |
| 431 | 424 | ||
| 432 | static int i9xx_get_fifo_size(struct drm_device *dev, int plane) | 425 | static int i9xx_get_fifo_size(struct drm_i915_private *dev_priv, int plane) |
| 433 | { | 426 | { |
| 434 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 435 | uint32_t dsparb = I915_READ(DSPARB); | 427 | uint32_t dsparb = I915_READ(DSPARB); |
| 436 | int size; | 428 | int size; |
| 437 | 429 | ||
| @@ -445,9 +437,8 @@ static int i9xx_get_fifo_size(struct drm_device *dev, int plane) | |||
| 445 | return size; | 437 | return size; |
| 446 | } | 438 | } |
| 447 | 439 | ||
| 448 | static int i830_get_fifo_size(struct drm_device *dev, int plane) | 440 | static int i830_get_fifo_size(struct drm_i915_private *dev_priv, int plane) |
| 449 | { | 441 | { |
| 450 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 451 | uint32_t dsparb = I915_READ(DSPARB); | 442 | uint32_t dsparb = I915_READ(DSPARB); |
| 452 | int size; | 443 | int size; |
| 453 | 444 | ||
| @@ -462,9 +453,8 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane) | |||
| 462 | return size; | 453 | return size; |
| 463 | } | 454 | } |
| 464 | 455 | ||
| 465 | static int i845_get_fifo_size(struct drm_device *dev, int plane) | 456 | static int i845_get_fifo_size(struct drm_i915_private *dev_priv, int plane) |
| 466 | { | 457 | { |
| 467 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 468 | uint32_t dsparb = I915_READ(DSPARB); | 458 | uint32_t dsparb = I915_READ(DSPARB); |
| 469 | int size; | 459 | int size; |
| 470 | 460 | ||
| @@ -624,11 +614,11 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | |||
| 624 | return wm_size; | 614 | return wm_size; |
| 625 | } | 615 | } |
| 626 | 616 | ||
| 627 | static struct drm_crtc *single_enabled_crtc(struct drm_device *dev) | 617 | static struct intel_crtc *single_enabled_crtc(struct drm_i915_private *dev_priv) |
| 628 | { | 618 | { |
| 629 | struct drm_crtc *crtc, *enabled = NULL; | 619 | struct intel_crtc *crtc, *enabled = NULL; |
| 630 | 620 | ||
| 631 | for_each_crtc(dev, crtc) { | 621 | for_each_intel_crtc(&dev_priv->drm, crtc) { |
| 632 | if (intel_crtc_active(crtc)) { | 622 | if (intel_crtc_active(crtc)) { |
| 633 | if (enabled) | 623 | if (enabled) |
| 634 | return NULL; | 624 | return NULL; |
| @@ -639,11 +629,10 @@ static struct drm_crtc *single_enabled_crtc(struct drm_device *dev) | |||
| 639 | return enabled; | 629 | return enabled; |
| 640 | } | 630 | } |
| 641 | 631 | ||
| 642 | static void pineview_update_wm(struct drm_crtc *unused_crtc) | 632 | static void pineview_update_wm(struct intel_crtc *unused_crtc) |
| 643 | { | 633 | { |
| 644 | struct drm_device *dev = unused_crtc->dev; | 634 | struct drm_i915_private *dev_priv = to_i915(unused_crtc->base.dev); |
| 645 | struct drm_i915_private *dev_priv = to_i915(dev); | 635 | struct intel_crtc *crtc; |
| 646 | struct drm_crtc *crtc; | ||
| 647 | const struct cxsr_latency *latency; | 636 | const struct cxsr_latency *latency; |
| 648 | u32 reg; | 637 | u32 reg; |
| 649 | unsigned long wm; | 638 | unsigned long wm; |
| @@ -658,10 +647,13 @@ static void pineview_update_wm(struct drm_crtc *unused_crtc) | |||
| 658 | return; | 647 | return; |
| 659 | } | 648 | } |
| 660 | 649 | ||
| 661 | crtc = single_enabled_crtc(dev); | 650 | crtc = single_enabled_crtc(dev_priv); |
| 662 | if (crtc) { | 651 | if (crtc) { |
| 663 | const struct drm_display_mode *adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; | 652 | const struct drm_display_mode *adjusted_mode = |
| 664 | int cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0); | 653 | &crtc->config->base.adjusted_mode; |
| 654 | const struct drm_framebuffer *fb = | ||
| 655 | crtc->base.primary->state->fb; | ||
| 656 | int cpp = drm_format_plane_cpp(fb->pixel_format, 0); | ||
| 665 | int clock = adjusted_mode->crtc_clock; | 657 | int clock = adjusted_mode->crtc_clock; |
| 666 | 658 | ||
| 667 | /* Display SR */ | 659 | /* Display SR */ |
| @@ -708,7 +700,7 @@ static void pineview_update_wm(struct drm_crtc *unused_crtc) | |||
| 708 | } | 700 | } |
| 709 | } | 701 | } |
| 710 | 702 | ||
| 711 | static bool g4x_compute_wm0(struct drm_device *dev, | 703 | static bool g4x_compute_wm0(struct drm_i915_private *dev_priv, |
| 712 | int plane, | 704 | int plane, |
| 713 | const struct intel_watermark_params *display, | 705 | const struct intel_watermark_params *display, |
| 714 | int display_latency_ns, | 706 | int display_latency_ns, |
| @@ -717,24 +709,26 @@ static bool g4x_compute_wm0(struct drm_device *dev, | |||
| 717 | int *plane_wm, | 709 | int *plane_wm, |
| 718 | int *cursor_wm) | 710 | int *cursor_wm) |
| 719 | { | 711 | { |
| 720 | struct drm_crtc *crtc; | 712 | struct intel_crtc *crtc; |
| 721 | const struct drm_display_mode *adjusted_mode; | 713 | const struct drm_display_mode *adjusted_mode; |
| 714 | const struct drm_framebuffer *fb; | ||
| 722 | int htotal, hdisplay, clock, cpp; | 715 | int htotal, hdisplay, clock, cpp; |
| 723 | int line_time_us, line_count; | 716 | int line_time_us, line_count; |
| 724 | int entries, tlb_miss; | 717 | int entries, tlb_miss; |
| 725 | 718 | ||
| 726 | crtc = intel_get_crtc_for_plane(dev, plane); | 719 | crtc = intel_get_crtc_for_plane(dev_priv, plane); |
| 727 | if (!intel_crtc_active(crtc)) { | 720 | if (!intel_crtc_active(crtc)) { |
| 728 | *cursor_wm = cursor->guard_size; | 721 | *cursor_wm = cursor->guard_size; |
| 729 | *plane_wm = display->guard_size; | 722 | *plane_wm = display->guard_size; |
| 730 | return false; | 723 | return false; |
| 731 | } | 724 | } |
| 732 | 725 | ||
| 733 | adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; | 726 | adjusted_mode = &crtc->config->base.adjusted_mode; |
| 727 | fb = crtc->base.primary->state->fb; | ||
| 734 | clock = adjusted_mode->crtc_clock; | 728 | clock = adjusted_mode->crtc_clock; |
| 735 | htotal = adjusted_mode->crtc_htotal; | 729 | htotal = adjusted_mode->crtc_htotal; |
| 736 | hdisplay = to_intel_crtc(crtc)->config->pipe_src_w; | 730 | hdisplay = crtc->config->pipe_src_w; |
| 737 | cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0); | 731 | cpp = drm_format_plane_cpp(fb->pixel_format, 0); |
| 738 | 732 | ||
| 739 | /* Use the small buffer method to calculate plane watermark */ | 733 | /* Use the small buffer method to calculate plane watermark */ |
| 740 | entries = ((clock * cpp / 1000) * display_latency_ns) / 1000; | 734 | entries = ((clock * cpp / 1000) * display_latency_ns) / 1000; |
| @@ -749,7 +743,7 @@ static bool g4x_compute_wm0(struct drm_device *dev, | |||
| 749 | /* Use the large buffer method to calculate cursor watermark */ | 743 | /* Use the large buffer method to calculate cursor watermark */ |
| 750 | line_time_us = max(htotal * 1000 / clock, 1); | 744 | line_time_us = max(htotal * 1000 / clock, 1); |
| 751 | line_count = (cursor_latency_ns / line_time_us + 1000) / 1000; | 745 | line_count = (cursor_latency_ns / line_time_us + 1000) / 1000; |
| 752 | entries = line_count * crtc->cursor->state->crtc_w * cpp; | 746 | entries = line_count * crtc->base.cursor->state->crtc_w * cpp; |
| 753 | tlb_miss = cursor->fifo_size*cursor->cacheline_size - hdisplay * 8; | 747 | tlb_miss = cursor->fifo_size*cursor->cacheline_size - hdisplay * 8; |
| 754 | if (tlb_miss > 0) | 748 | if (tlb_miss > 0) |
| 755 | entries += tlb_miss; | 749 | entries += tlb_miss; |
| @@ -768,7 +762,7 @@ static bool g4x_compute_wm0(struct drm_device *dev, | |||
| 768 | * can be programmed into the associated watermark register, that watermark | 762 | * can be programmed into the associated watermark register, that watermark |
| 769 | * must be disabled. | 763 | * must be disabled. |
| 770 | */ | 764 | */ |
| 771 | static bool g4x_check_srwm(struct drm_device *dev, | 765 | static bool g4x_check_srwm(struct drm_i915_private *dev_priv, |
| 772 | int display_wm, int cursor_wm, | 766 | int display_wm, int cursor_wm, |
| 773 | const struct intel_watermark_params *display, | 767 | const struct intel_watermark_params *display, |
| 774 | const struct intel_watermark_params *cursor) | 768 | const struct intel_watermark_params *cursor) |
| @@ -796,15 +790,16 @@ static bool g4x_check_srwm(struct drm_device *dev, | |||
| 796 | return true; | 790 | return true; |
| 797 | } | 791 | } |
| 798 | 792 | ||
| 799 | static bool g4x_compute_srwm(struct drm_device *dev, | 793 | static bool g4x_compute_srwm(struct drm_i915_private *dev_priv, |
| 800 | int plane, | 794 | int plane, |
| 801 | int latency_ns, | 795 | int latency_ns, |
| 802 | const struct intel_watermark_params *display, | 796 | const struct intel_watermark_params *display, |
| 803 | const struct intel_watermark_params *cursor, | 797 | const struct intel_watermark_params *cursor, |
| 804 | int *display_wm, int *cursor_wm) | 798 | int *display_wm, int *cursor_wm) |
| 805 | { | 799 | { |
| 806 | struct drm_crtc *crtc; | 800 | struct intel_crtc *crtc; |
| 807 | const struct drm_display_mode *adjusted_mode; | 801 | const struct drm_display_mode *adjusted_mode; |
| 802 | const struct drm_framebuffer *fb; | ||
| 808 | int hdisplay, htotal, cpp, clock; | 803 | int hdisplay, htotal, cpp, clock; |
| 809 | unsigned long line_time_us; | 804 | unsigned long line_time_us; |
| 810 | int line_count, line_size; | 805 | int line_count, line_size; |
| @@ -816,12 +811,13 @@ static bool g4x_compute_srwm(struct drm_device *dev, | |||
| 816 | return false; | 811 | return false; |
| 817 | } | 812 | } |
| 818 | 813 | ||
| 819 | crtc = intel_get_crtc_for_plane(dev, plane); | 814 | crtc = intel_get_crtc_for_plane(dev_priv, plane); |
| 820 | adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; | 815 | adjusted_mode = &crtc->config->base.adjusted_mode; |
| 816 | fb = crtc->base.primary->state->fb; | ||
| 821 | clock = adjusted_mode->crtc_clock; | 817 | clock = adjusted_mode->crtc_clock; |
| 822 | htotal = adjusted_mode->crtc_htotal; | 818 | htotal = adjusted_mode->crtc_htotal; |
| 823 | hdisplay = to_intel_crtc(crtc)->config->pipe_src_w; | 819 | hdisplay = crtc->config->pipe_src_w; |
| 824 | cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0); | 820 | cpp = drm_format_plane_cpp(fb->pixel_format, 0); |
| 825 | 821 | ||
| 826 | line_time_us = max(htotal * 1000 / clock, 1); | 822 | line_time_us = max(htotal * 1000 / clock, 1); |
| 827 | line_count = (latency_ns / line_time_us + 1000) / 1000; | 823 | line_count = (latency_ns / line_time_us + 1000) / 1000; |
| @@ -835,11 +831,11 @@ static bool g4x_compute_srwm(struct drm_device *dev, | |||
| 835 | *display_wm = entries + display->guard_size; | 831 | *display_wm = entries + display->guard_size; |
| 836 | 832 | ||
| 837 | /* calculate the self-refresh watermark for display cursor */ | 833 | /* calculate the self-refresh watermark for display cursor */ |
| 838 | entries = line_count * cpp * crtc->cursor->state->crtc_w; | 834 | entries = line_count * cpp * crtc->base.cursor->state->crtc_w; |
| 839 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); | 835 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); |
| 840 | *cursor_wm = entries + cursor->guard_size; | 836 | *cursor_wm = entries + cursor->guard_size; |
| 841 | 837 | ||
| 842 | return g4x_check_srwm(dev, | 838 | return g4x_check_srwm(dev_priv, |
| 843 | *display_wm, *cursor_wm, | 839 | *display_wm, *cursor_wm, |
| 844 | display, cursor); | 840 | display, cursor); |
| 845 | } | 841 | } |
| @@ -939,10 +935,8 @@ static unsigned int vlv_wm_method2(unsigned int pixel_rate, | |||
| 939 | return ret; | 935 | return ret; |
| 940 | } | 936 | } |
| 941 | 937 | ||
| 942 | static void vlv_setup_wm_latency(struct drm_device *dev) | 938 | static void vlv_setup_wm_latency(struct drm_i915_private *dev_priv) |
| 943 | { | 939 | { |
| 944 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 945 | |||
| 946 | /* all latencies in usec */ | 940 | /* all latencies in usec */ |
| 947 | dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM2] = 3; | 941 | dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM2] = 3; |
| 948 | 942 | ||
| @@ -1329,20 +1323,19 @@ static void vlv_merge_wm(struct drm_device *dev, | |||
| 1329 | } | 1323 | } |
| 1330 | } | 1324 | } |
| 1331 | 1325 | ||
| 1332 | static void vlv_update_wm(struct drm_crtc *crtc) | 1326 | static void vlv_update_wm(struct intel_crtc *crtc) |
| 1333 | { | 1327 | { |
| 1334 | struct drm_device *dev = crtc->dev; | 1328 | struct drm_device *dev = crtc->base.dev; |
| 1335 | struct drm_i915_private *dev_priv = to_i915(dev); | 1329 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 1336 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1330 | enum pipe pipe = crtc->pipe; |
| 1337 | enum pipe pipe = intel_crtc->pipe; | ||
| 1338 | struct vlv_wm_values wm = {}; | 1331 | struct vlv_wm_values wm = {}; |
| 1339 | 1332 | ||
| 1340 | vlv_compute_wm(intel_crtc); | 1333 | vlv_compute_wm(crtc); |
| 1341 | vlv_merge_wm(dev, &wm); | 1334 | vlv_merge_wm(dev, &wm); |
| 1342 | 1335 | ||
| 1343 | if (memcmp(&dev_priv->wm.vlv, &wm, sizeof(wm)) == 0) { | 1336 | if (memcmp(&dev_priv->wm.vlv, &wm, sizeof(wm)) == 0) { |
| 1344 | /* FIXME should be part of crtc atomic commit */ | 1337 | /* FIXME should be part of crtc atomic commit */ |
| 1345 | vlv_pipe_set_fifo_size(intel_crtc); | 1338 | vlv_pipe_set_fifo_size(crtc); |
| 1346 | return; | 1339 | return; |
| 1347 | } | 1340 | } |
| 1348 | 1341 | ||
| @@ -1358,9 +1351,9 @@ static void vlv_update_wm(struct drm_crtc *crtc) | |||
| 1358 | intel_set_memory_cxsr(dev_priv, false); | 1351 | intel_set_memory_cxsr(dev_priv, false); |
| 1359 | 1352 | ||
| 1360 | /* FIXME should be part of crtc atomic commit */ | 1353 | /* FIXME should be part of crtc atomic commit */ |
| 1361 | vlv_pipe_set_fifo_size(intel_crtc); | 1354 | vlv_pipe_set_fifo_size(crtc); |
| 1362 | 1355 | ||
| 1363 | vlv_write_wm_values(intel_crtc, &wm); | 1356 | vlv_write_wm_values(crtc, &wm); |
| 1364 | 1357 | ||
| 1365 | DRM_DEBUG_KMS("Setting FIFO watermarks - %c: plane=%d, cursor=%d, " | 1358 | DRM_DEBUG_KMS("Setting FIFO watermarks - %c: plane=%d, cursor=%d, " |
| 1366 | "sprite0=%d, sprite1=%d, SR: plane=%d, cursor=%d level=%d cxsr=%d\n", | 1359 | "sprite0=%d, sprite1=%d, SR: plane=%d, cursor=%d level=%d cxsr=%d\n", |
| @@ -1384,30 +1377,29 @@ static void vlv_update_wm(struct drm_crtc *crtc) | |||
| 1384 | 1377 | ||
| 1385 | #define single_plane_enabled(mask) is_power_of_2(mask) | 1378 | #define single_plane_enabled(mask) is_power_of_2(mask) |
| 1386 | 1379 | ||
| 1387 | static void g4x_update_wm(struct drm_crtc *crtc) | 1380 | static void g4x_update_wm(struct intel_crtc *crtc) |
| 1388 | { | 1381 | { |
| 1389 | struct drm_device *dev = crtc->dev; | 1382 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
| 1390 | static const int sr_latency_ns = 12000; | 1383 | static const int sr_latency_ns = 12000; |
| 1391 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 1392 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; | 1384 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; |
| 1393 | int plane_sr, cursor_sr; | 1385 | int plane_sr, cursor_sr; |
| 1394 | unsigned int enabled = 0; | 1386 | unsigned int enabled = 0; |
| 1395 | bool cxsr_enabled; | 1387 | bool cxsr_enabled; |
| 1396 | 1388 | ||
| 1397 | if (g4x_compute_wm0(dev, PIPE_A, | 1389 | if (g4x_compute_wm0(dev_priv, PIPE_A, |
| 1398 | &g4x_wm_info, pessimal_latency_ns, | 1390 | &g4x_wm_info, pessimal_latency_ns, |
| 1399 | &g4x_cursor_wm_info, pessimal_latency_ns, | 1391 | &g4x_cursor_wm_info, pessimal_latency_ns, |
| 1400 | &planea_wm, &cursora_wm)) | 1392 | &planea_wm, &cursora_wm)) |
| 1401 | enabled |= 1 << PIPE_A; | 1393 | enabled |= 1 << PIPE_A; |
| 1402 | 1394 | ||
| 1403 | if (g4x_compute_wm0(dev, PIPE_B, | 1395 | if (g4x_compute_wm0(dev_priv, PIPE_B, |
| 1404 | &g4x_wm_info, pessimal_latency_ns, | 1396 | &g4x_wm_info, pessimal_latency_ns, |
| 1405 | &g4x_cursor_wm_info, pessimal_latency_ns, | 1397 | &g4x_cursor_wm_info, pessimal_latency_ns, |
| 1406 | &planeb_wm, &cursorb_wm)) | 1398 | &planeb_wm, &cursorb_wm)) |
| 1407 | enabled |= 1 << PIPE_B; | 1399 | enabled |= 1 << PIPE_B; |
| 1408 | 1400 | ||
| 1409 | if (single_plane_enabled(enabled) && | 1401 | if (single_plane_enabled(enabled) && |
| 1410 | g4x_compute_srwm(dev, ffs(enabled) - 1, | 1402 | g4x_compute_srwm(dev_priv, ffs(enabled) - 1, |
| 1411 | sr_latency_ns, | 1403 | sr_latency_ns, |
| 1412 | &g4x_wm_info, | 1404 | &g4x_wm_info, |
| 1413 | &g4x_cursor_wm_info, | 1405 | &g4x_cursor_wm_info, |
| @@ -1442,25 +1434,27 @@ static void g4x_update_wm(struct drm_crtc *crtc) | |||
| 1442 | intel_set_memory_cxsr(dev_priv, true); | 1434 | intel_set_memory_cxsr(dev_priv, true); |
| 1443 | } | 1435 | } |
| 1444 | 1436 | ||
| 1445 | static void i965_update_wm(struct drm_crtc *unused_crtc) | 1437 | static void i965_update_wm(struct intel_crtc *unused_crtc) |
| 1446 | { | 1438 | { |
| 1447 | struct drm_device *dev = unused_crtc->dev; | 1439 | struct drm_i915_private *dev_priv = to_i915(unused_crtc->base.dev); |
| 1448 | struct drm_i915_private *dev_priv = to_i915(dev); | 1440 | struct intel_crtc *crtc; |
| 1449 | struct drm_crtc *crtc; | ||
| 1450 | int srwm = 1; | 1441 | int srwm = 1; |
| 1451 | int cursor_sr = 16; | 1442 | int cursor_sr = 16; |
| 1452 | bool cxsr_enabled; | 1443 | bool cxsr_enabled; |
| 1453 | 1444 | ||
| 1454 | /* Calc sr entries for one plane configs */ | 1445 | /* Calc sr entries for one plane configs */ |
| 1455 | crtc = single_enabled_crtc(dev); | 1446 | crtc = single_enabled_crtc(dev_priv); |
| 1456 | if (crtc) { | 1447 | if (crtc) { |
| 1457 | /* self-refresh has much higher latency */ | 1448 | /* self-refresh has much higher latency */ |
| 1458 | static const int sr_latency_ns = 12000; | 1449 | static const int sr_latency_ns = 12000; |
| 1459 | const struct drm_display_mode *adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; | 1450 | const struct drm_display_mode *adjusted_mode = |
| 1451 | &crtc->config->base.adjusted_mode; | ||
| 1452 | const struct drm_framebuffer *fb = | ||
| 1453 | crtc->base.primary->state->fb; | ||
| 1460 | int clock = adjusted_mode->crtc_clock; | 1454 | int clock = adjusted_mode->crtc_clock; |
| 1461 | int htotal = adjusted_mode->crtc_htotal; | 1455 | int htotal = adjusted_mode->crtc_htotal; |
| 1462 | int hdisplay = to_intel_crtc(crtc)->config->pipe_src_w; | 1456 | int hdisplay = crtc->config->pipe_src_w; |
| 1463 | int cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0); | 1457 | int cpp = drm_format_plane_cpp(fb->pixel_format, 0); |
| 1464 | unsigned long line_time_us; | 1458 | unsigned long line_time_us; |
| 1465 | int entries; | 1459 | int entries; |
| 1466 | 1460 | ||
| @@ -1478,7 +1472,7 @@ static void i965_update_wm(struct drm_crtc *unused_crtc) | |||
| 1478 | entries, srwm); | 1472 | entries, srwm); |
| 1479 | 1473 | ||
| 1480 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * | 1474 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
| 1481 | cpp * crtc->cursor->state->crtc_w; | 1475 | cpp * crtc->base.cursor->state->crtc_w; |
| 1482 | entries = DIV_ROUND_UP(entries, | 1476 | entries = DIV_ROUND_UP(entries, |
| 1483 | i965_cursor_wm_info.cacheline_size); | 1477 | i965_cursor_wm_info.cacheline_size); |
| 1484 | cursor_sr = i965_cursor_wm_info.fifo_size - | 1478 | cursor_sr = i965_cursor_wm_info.fifo_size - |
| @@ -1516,34 +1510,38 @@ static void i965_update_wm(struct drm_crtc *unused_crtc) | |||
| 1516 | 1510 | ||
| 1517 | #undef FW_WM | 1511 | #undef FW_WM |
| 1518 | 1512 | ||
| 1519 | static void i9xx_update_wm(struct drm_crtc *unused_crtc) | 1513 | static void i9xx_update_wm(struct intel_crtc *unused_crtc) |
| 1520 | { | 1514 | { |
| 1521 | struct drm_device *dev = unused_crtc->dev; | 1515 | struct drm_i915_private *dev_priv = to_i915(unused_crtc->base.dev); |
| 1522 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 1523 | const struct intel_watermark_params *wm_info; | 1516 | const struct intel_watermark_params *wm_info; |
| 1524 | uint32_t fwater_lo; | 1517 | uint32_t fwater_lo; |
| 1525 | uint32_t fwater_hi; | 1518 | uint32_t fwater_hi; |
| 1526 | int cwm, srwm = 1; | 1519 | int cwm, srwm = 1; |
| 1527 | int fifo_size; | 1520 | int fifo_size; |
| 1528 | int planea_wm, planeb_wm; | 1521 | int planea_wm, planeb_wm; |
| 1529 | struct drm_crtc *crtc, *enabled = NULL; | 1522 | struct intel_crtc *crtc, *enabled = NULL; |
| 1530 | 1523 | ||
| 1531 | if (IS_I945GM(dev)) | 1524 | if (IS_I945GM(dev_priv)) |
| 1532 | wm_info = &i945_wm_info; | 1525 | wm_info = &i945_wm_info; |
| 1533 | else if (!IS_GEN2(dev_priv)) | 1526 | else if (!IS_GEN2(dev_priv)) |
| 1534 | wm_info = &i915_wm_info; | 1527 | wm_info = &i915_wm_info; |
| 1535 | else | 1528 | else |
| 1536 | wm_info = &i830_a_wm_info; | 1529 | wm_info = &i830_a_wm_info; |
| 1537 | 1530 | ||
| 1538 | fifo_size = dev_priv->display.get_fifo_size(dev, 0); | 1531 | fifo_size = dev_priv->display.get_fifo_size(dev_priv, 0); |
| 1539 | crtc = intel_get_crtc_for_plane(dev, 0); | 1532 | crtc = intel_get_crtc_for_plane(dev_priv, 0); |
| 1540 | if (intel_crtc_active(crtc)) { | 1533 | if (intel_crtc_active(crtc)) { |
| 1541 | const struct drm_display_mode *adjusted_mode; | 1534 | const struct drm_display_mode *adjusted_mode = |
| 1542 | int cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0); | 1535 | &crtc->config->base.adjusted_mode; |
| 1536 | const struct drm_framebuffer *fb = | ||
| 1537 | crtc->base.primary->state->fb; | ||
| 1538 | int cpp; | ||
| 1539 | |||
| 1543 | if (IS_GEN2(dev_priv)) | 1540 | if (IS_GEN2(dev_priv)) |
| 1544 | cpp = 4; | 1541 | cpp = 4; |
| 1542 | else | ||
| 1543 | cpp = drm_format_plane_cpp(fb->pixel_format, 0); | ||
| 1545 | 1544 | ||
| 1546 | adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; | ||
| 1547 | planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock, | 1545 | planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock, |
| 1548 | wm_info, fifo_size, cpp, | 1546 | wm_info, fifo_size, cpp, |
| 1549 | pessimal_latency_ns); | 1547 | pessimal_latency_ns); |
| @@ -1557,15 +1555,20 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) | |||
| 1557 | if (IS_GEN2(dev_priv)) | 1555 | if (IS_GEN2(dev_priv)) |
| 1558 | wm_info = &i830_bc_wm_info; | 1556 | wm_info = &i830_bc_wm_info; |
| 1559 | 1557 | ||
| 1560 | fifo_size = dev_priv->display.get_fifo_size(dev, 1); | 1558 | fifo_size = dev_priv->display.get_fifo_size(dev_priv, 1); |
| 1561 | crtc = intel_get_crtc_for_plane(dev, 1); | 1559 | crtc = intel_get_crtc_for_plane(dev_priv, 1); |
| 1562 | if (intel_crtc_active(crtc)) { | 1560 | if (intel_crtc_active(crtc)) { |
| 1563 | const struct drm_display_mode *adjusted_mode; | 1561 | const struct drm_display_mode *adjusted_mode = |
| 1564 | int cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0); | 1562 | &crtc->config->base.adjusted_mode; |
| 1563 | const struct drm_framebuffer *fb = | ||
| 1564 | crtc->base.primary->state->fb; | ||
| 1565 | int cpp; | ||
| 1566 | |||
| 1565 | if (IS_GEN2(dev_priv)) | 1567 | if (IS_GEN2(dev_priv)) |
| 1566 | cpp = 4; | 1568 | cpp = 4; |
| 1569 | else | ||
| 1570 | cpp = drm_format_plane_cpp(fb->pixel_format, 0); | ||
| 1567 | 1571 | ||
| 1568 | adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; | ||
| 1569 | planeb_wm = intel_calculate_wm(adjusted_mode->crtc_clock, | 1572 | planeb_wm = intel_calculate_wm(adjusted_mode->crtc_clock, |
| 1570 | wm_info, fifo_size, cpp, | 1573 | wm_info, fifo_size, cpp, |
| 1571 | pessimal_latency_ns); | 1574 | pessimal_latency_ns); |
| @@ -1584,7 +1587,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) | |||
| 1584 | if (IS_I915GM(dev_priv) && enabled) { | 1587 | if (IS_I915GM(dev_priv) && enabled) { |
| 1585 | struct drm_i915_gem_object *obj; | 1588 | struct drm_i915_gem_object *obj; |
| 1586 | 1589 | ||
| 1587 | obj = intel_fb_obj(enabled->primary->state->fb); | 1590 | obj = intel_fb_obj(enabled->base.primary->state->fb); |
| 1588 | 1591 | ||
| 1589 | /* self-refresh seems busted with untiled */ | 1592 | /* self-refresh seems busted with untiled */ |
| 1590 | if (!i915_gem_object_is_tiled(obj)) | 1593 | if (!i915_gem_object_is_tiled(obj)) |
| @@ -1600,19 +1603,24 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) | |||
| 1600 | intel_set_memory_cxsr(dev_priv, false); | 1603 | intel_set_memory_cxsr(dev_priv, false); |
| 1601 | 1604 | ||
| 1602 | /* Calc sr entries for one plane configs */ | 1605 | /* Calc sr entries for one plane configs */ |
| 1603 | if (HAS_FW_BLC(dev) && enabled) { | 1606 | if (HAS_FW_BLC(dev_priv) && enabled) { |
| 1604 | /* self-refresh has much higher latency */ | 1607 | /* self-refresh has much higher latency */ |
| 1605 | static const int sr_latency_ns = 6000; | 1608 | static const int sr_latency_ns = 6000; |
| 1606 | const struct drm_display_mode *adjusted_mode = &to_intel_crtc(enabled)->config->base.adjusted_mode; | 1609 | const struct drm_display_mode *adjusted_mode = |
| 1610 | &enabled->config->base.adjusted_mode; | ||
| 1611 | const struct drm_framebuffer *fb = | ||
| 1612 | enabled->base.primary->state->fb; | ||
| 1607 | int clock = adjusted_mode->crtc_clock; | 1613 | int clock = adjusted_mode->crtc_clock; |
| 1608 | int htotal = adjusted_mode->crtc_htotal; | 1614 | int htotal = adjusted_mode->crtc_htotal; |
| 1609 | int hdisplay = to_intel_crtc(enabled)->config->pipe_src_w; | 1615 | int hdisplay = enabled->config->pipe_src_w; |
| 1610 | int cpp = drm_format_plane_cpp(enabled->primary->state->fb->pixel_format, 0); | 1616 | int cpp; |
| 1611 | unsigned long line_time_us; | 1617 | unsigned long line_time_us; |
| 1612 | int entries; | 1618 | int entries; |
| 1613 | 1619 | ||
| 1614 | if (IS_I915GM(dev_priv) || IS_I945GM(dev_priv)) | 1620 | if (IS_I915GM(dev_priv) || IS_I945GM(dev_priv)) |
| 1615 | cpp = 4; | 1621 | cpp = 4; |
| 1622 | else | ||
| 1623 | cpp = drm_format_plane_cpp(fb->pixel_format, 0); | ||
| 1616 | 1624 | ||
| 1617 | line_time_us = max(htotal * 1000 / clock, 1); | 1625 | line_time_us = max(htotal * 1000 / clock, 1); |
| 1618 | 1626 | ||
| @@ -1649,23 +1657,22 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) | |||
| 1649 | intel_set_memory_cxsr(dev_priv, true); | 1657 | intel_set_memory_cxsr(dev_priv, true); |
| 1650 | } | 1658 | } |
| 1651 | 1659 | ||
| 1652 | static void i845_update_wm(struct drm_crtc *unused_crtc) | 1660 | static void i845_update_wm(struct intel_crtc *unused_crtc) |
| 1653 | { | 1661 | { |
| 1654 | struct drm_device *dev = unused_crtc->dev; | 1662 | struct drm_i915_private *dev_priv = to_i915(unused_crtc->base.dev); |
| 1655 | struct drm_i915_private *dev_priv = to_i915(dev); | 1663 | struct intel_crtc *crtc; |
| 1656 | struct drm_crtc *crtc; | ||
| 1657 | const struct drm_display_mode *adjusted_mode; | 1664 | const struct drm_display_mode *adjusted_mode; |
| 1658 | uint32_t fwater_lo; | 1665 | uint32_t fwater_lo; |
| 1659 | int planea_wm; | 1666 | int planea_wm; |
| 1660 | 1667 | ||
| 1661 | crtc = single_enabled_crtc(dev); | 1668 | crtc = single_enabled_crtc(dev_priv); |
| 1662 | if (crtc == NULL) | 1669 | if (crtc == NULL) |
| 1663 | return; | 1670 | return; |
| 1664 | 1671 | ||
| 1665 | adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; | 1672 | adjusted_mode = &crtc->config->base.adjusted_mode; |
| 1666 | planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock, | 1673 | planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock, |
| 1667 | &i845_wm_info, | 1674 | &i845_wm_info, |
| 1668 | dev_priv->display.get_fifo_size(dev, 0), | 1675 | dev_priv->display.get_fifo_size(dev_priv, 0), |
| 1669 | 4, pessimal_latency_ns); | 1676 | 4, pessimal_latency_ns); |
| 1670 | fwater_lo = I915_READ(FW_BLC) & ~0xfff; | 1677 | fwater_lo = I915_READ(FW_BLC) & ~0xfff; |
| 1671 | fwater_lo |= (3<<8) | planea_wm; | 1678 | fwater_lo |= (3<<8) | planea_wm; |
| @@ -2078,10 +2085,9 @@ hsw_compute_linetime_wm(const struct intel_crtc_state *cstate) | |||
| 2078 | PIPE_WM_LINETIME_TIME(linetime); | 2085 | PIPE_WM_LINETIME_TIME(linetime); |
| 2079 | } | 2086 | } |
| 2080 | 2087 | ||
| 2081 | static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8]) | 2088 | static void intel_read_wm_latency(struct drm_i915_private *dev_priv, |
| 2089 | uint16_t wm[8]) | ||
| 2082 | { | 2090 | { |
| 2083 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 2084 | |||
| 2085 | if (IS_GEN9(dev_priv)) { | 2091 | if (IS_GEN9(dev_priv)) { |
| 2086 | uint32_t val; | 2092 | uint32_t val; |
| 2087 | int ret, i; | 2093 | int ret, i; |
| @@ -2167,14 +2173,14 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8]) | |||
| 2167 | wm[2] = (sskpd >> 12) & 0xFF; | 2173 | wm[2] = (sskpd >> 12) & 0xFF; |
| 2168 | wm[3] = (sskpd >> 20) & 0x1FF; | 2174 | wm[3] = (sskpd >> 20) & 0x1FF; |
| 2169 | wm[4] = (sskpd >> 32) & 0x1FF; | 2175 | wm[4] = (sskpd >> 32) & 0x1FF; |
| 2170 | } else if (INTEL_INFO(dev)->gen >= 6) { | 2176 | } else if (INTEL_GEN(dev_priv) >= 6) { |
| 2171 | uint32_t sskpd = I915_READ(MCH_SSKPD); | 2177 | uint32_t sskpd = I915_READ(MCH_SSKPD); |
| 2172 | 2178 | ||
| 2173 | wm[0] = (sskpd >> SSKPD_WM0_SHIFT) & SSKPD_WM_MASK; | 2179 | wm[0] = (sskpd >> SSKPD_WM0_SHIFT) & SSKPD_WM_MASK; |
| 2174 | wm[1] = (sskpd >> SSKPD_WM1_SHIFT) & SSKPD_WM_MASK; | 2180 | wm[1] = (sskpd >> SSKPD_WM1_SHIFT) & SSKPD_WM_MASK; |
| 2175 | wm[2] = (sskpd >> SSKPD_WM2_SHIFT) & SSKPD_WM_MASK; | 2181 | wm[2] = (sskpd >> SSKPD_WM2_SHIFT) & SSKPD_WM_MASK; |
| 2176 | wm[3] = (sskpd >> SSKPD_WM3_SHIFT) & SSKPD_WM_MASK; | 2182 | wm[3] = (sskpd >> SSKPD_WM3_SHIFT) & SSKPD_WM_MASK; |
| 2177 | } else if (INTEL_INFO(dev)->gen >= 5) { | 2183 | } else if (INTEL_GEN(dev_priv) >= 5) { |
| 2178 | uint32_t mltr = I915_READ(MLTR_ILK); | 2184 | uint32_t mltr = I915_READ(MLTR_ILK); |
| 2179 | 2185 | ||
| 2180 | /* ILK primary LP0 latency is 700 ns */ | 2186 | /* ILK primary LP0 latency is 700 ns */ |
| @@ -2262,9 +2268,8 @@ static bool ilk_increase_wm_latency(struct drm_i915_private *dev_priv, | |||
| 2262 | return true; | 2268 | return true; |
| 2263 | } | 2269 | } |
| 2264 | 2270 | ||
| 2265 | static void snb_wm_latency_quirk(struct drm_device *dev) | 2271 | static void snb_wm_latency_quirk(struct drm_i915_private *dev_priv) |
| 2266 | { | 2272 | { |
| 2267 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 2268 | bool changed; | 2273 | bool changed; |
| 2269 | 2274 | ||
| 2270 | /* | 2275 | /* |
| @@ -2284,11 +2289,9 @@ static void snb_wm_latency_quirk(struct drm_device *dev) | |||
| 2284 | intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency); | 2289 | intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency); |
| 2285 | } | 2290 | } |
| 2286 | 2291 | ||
| 2287 | static void ilk_setup_wm_latency(struct drm_device *dev) | 2292 | static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv) |
| 2288 | { | 2293 | { |
| 2289 | struct drm_i915_private *dev_priv = to_i915(dev); | 2294 | intel_read_wm_latency(dev_priv, dev_priv->wm.pri_latency); |
| 2290 | |||
| 2291 | intel_read_wm_latency(dev, dev_priv->wm.pri_latency); | ||
| 2292 | 2295 | ||
| 2293 | memcpy(dev_priv->wm.spr_latency, dev_priv->wm.pri_latency, | 2296 | memcpy(dev_priv->wm.spr_latency, dev_priv->wm.pri_latency, |
| 2294 | sizeof(dev_priv->wm.pri_latency)); | 2297 | sizeof(dev_priv->wm.pri_latency)); |
| @@ -2303,14 +2306,12 @@ static void ilk_setup_wm_latency(struct drm_device *dev) | |||
| 2303 | intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency); | 2306 | intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency); |
| 2304 | 2307 | ||
| 2305 | if (IS_GEN6(dev_priv)) | 2308 | if (IS_GEN6(dev_priv)) |
| 2306 | snb_wm_latency_quirk(dev); | 2309 | snb_wm_latency_quirk(dev_priv); |
| 2307 | } | 2310 | } |
| 2308 | 2311 | ||
| 2309 | static void skl_setup_wm_latency(struct drm_device *dev) | 2312 | static void skl_setup_wm_latency(struct drm_i915_private *dev_priv) |
| 2310 | { | 2313 | { |
| 2311 | struct drm_i915_private *dev_priv = to_i915(dev); | 2314 | intel_read_wm_latency(dev_priv, dev_priv->wm.skl_latency); |
| 2312 | |||
| 2313 | intel_read_wm_latency(dev, dev_priv->wm.skl_latency); | ||
| 2314 | intel_print_wm_latency(dev_priv, "Gen9 Plane", dev_priv->wm.skl_latency); | 2315 | intel_print_wm_latency(dev_priv, "Gen9 Plane", dev_priv->wm.skl_latency); |
| 2315 | } | 2316 | } |
| 2316 | 2317 | ||
| @@ -3041,7 +3042,7 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state) | |||
| 3041 | 3042 | ||
| 3042 | /* Since we're now guaranteed to only have one active CRTC... */ | 3043 | /* Since we're now guaranteed to only have one active CRTC... */ |
| 3043 | pipe = ffs(intel_state->active_crtcs) - 1; | 3044 | pipe = ffs(intel_state->active_crtcs) - 1; |
| 3044 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); | 3045 | crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
| 3045 | cstate = to_intel_crtc_state(crtc->base.state); | 3046 | cstate = to_intel_crtc_state(crtc->base.state); |
| 3046 | 3047 | ||
| 3047 | if (crtc->base.state->adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) | 3048 | if (crtc->base.state->adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) |
| @@ -3160,7 +3161,7 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, | |||
| 3160 | if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) | 3161 | if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) |
| 3161 | continue; | 3162 | continue; |
| 3162 | 3163 | ||
| 3163 | for_each_plane(dev_priv, pipe, plane) { | 3164 | for_each_universal_plane(dev_priv, pipe, plane) { |
| 3164 | val = I915_READ(PLANE_BUF_CFG(pipe, plane)); | 3165 | val = I915_READ(PLANE_BUF_CFG(pipe, plane)); |
| 3165 | skl_ddb_entry_init_from_hw(&ddb->plane[pipe][plane], | 3166 | skl_ddb_entry_init_from_hw(&ddb->plane[pipe][plane], |
| 3166 | val); | 3167 | val); |
| @@ -3262,49 +3263,39 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate, | |||
| 3262 | * 3 * 4096 * 8192 * 4 < 2^32 | 3263 | * 3 * 4096 * 8192 * 4 < 2^32 |
| 3263 | */ | 3264 | */ |
| 3264 | static unsigned int | 3265 | static unsigned int |
| 3265 | skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate) | 3266 | skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate, |
| 3267 | unsigned *plane_data_rate, | ||
| 3268 | unsigned *plane_y_data_rate) | ||
| 3266 | { | 3269 | { |
| 3267 | struct drm_crtc_state *cstate = &intel_cstate->base; | 3270 | struct drm_crtc_state *cstate = &intel_cstate->base; |
| 3268 | struct drm_atomic_state *state = cstate->state; | 3271 | struct drm_atomic_state *state = cstate->state; |
| 3269 | struct drm_crtc *crtc = cstate->crtc; | 3272 | struct drm_plane *plane; |
| 3270 | struct drm_device *dev = crtc->dev; | ||
| 3271 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
| 3272 | const struct drm_plane *plane; | ||
| 3273 | const struct intel_plane *intel_plane; | 3273 | const struct intel_plane *intel_plane; |
| 3274 | struct drm_plane_state *pstate; | 3274 | const struct drm_plane_state *pstate; |
| 3275 | unsigned int rate, total_data_rate = 0; | 3275 | unsigned int rate, total_data_rate = 0; |
| 3276 | int id; | 3276 | int id; |
| 3277 | int i; | ||
| 3278 | 3277 | ||
| 3279 | if (WARN_ON(!state)) | 3278 | if (WARN_ON(!state)) |
| 3280 | return 0; | 3279 | return 0; |
| 3281 | 3280 | ||
| 3282 | /* Calculate and cache data rate for each plane */ | 3281 | /* Calculate and cache data rate for each plane */ |
| 3283 | for_each_plane_in_state(state, plane, pstate, i) { | 3282 | drm_atomic_crtc_state_for_each_plane_state(plane, pstate, cstate) { |
| 3284 | id = skl_wm_plane_id(to_intel_plane(plane)); | 3283 | id = skl_wm_plane_id(to_intel_plane(plane)); |
| 3285 | intel_plane = to_intel_plane(plane); | 3284 | intel_plane = to_intel_plane(plane); |
| 3286 | 3285 | ||
| 3287 | if (intel_plane->pipe != intel_crtc->pipe) | ||
| 3288 | continue; | ||
| 3289 | |||
| 3290 | /* packed/uv */ | 3286 | /* packed/uv */ |
| 3291 | rate = skl_plane_relative_data_rate(intel_cstate, | 3287 | rate = skl_plane_relative_data_rate(intel_cstate, |
| 3292 | pstate, 0); | 3288 | pstate, 0); |
| 3293 | intel_cstate->wm.skl.plane_data_rate[id] = rate; | 3289 | plane_data_rate[id] = rate; |
| 3290 | |||
| 3291 | total_data_rate += rate; | ||
| 3294 | 3292 | ||
| 3295 | /* y-plane */ | 3293 | /* y-plane */ |
| 3296 | rate = skl_plane_relative_data_rate(intel_cstate, | 3294 | rate = skl_plane_relative_data_rate(intel_cstate, |
| 3297 | pstate, 1); | 3295 | pstate, 1); |
| 3298 | intel_cstate->wm.skl.plane_y_data_rate[id] = rate; | 3296 | plane_y_data_rate[id] = rate; |
| 3299 | } | ||
| 3300 | 3297 | ||
| 3301 | /* Calculate CRTC's total data rate from cached values */ | 3298 | total_data_rate += rate; |
| 3302 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { | ||
| 3303 | int id = skl_wm_plane_id(intel_plane); | ||
| 3304 | |||
| 3305 | /* packed/uv */ | ||
| 3306 | total_data_rate += intel_cstate->wm.skl.plane_data_rate[id]; | ||
| 3307 | total_data_rate += intel_cstate->wm.skl.plane_y_data_rate[id]; | ||
| 3308 | } | 3299 | } |
| 3309 | 3300 | ||
| 3310 | return total_data_rate; | 3301 | return total_data_rate; |
| @@ -3373,6 +3364,30 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate, | |||
| 3373 | return DIV_ROUND_UP((4 * src_w * plane_bpp), 512) * min_scanlines/4 + 3; | 3364 | return DIV_ROUND_UP((4 * src_w * plane_bpp), 512) * min_scanlines/4 + 3; |
| 3374 | } | 3365 | } |
| 3375 | 3366 | ||
| 3367 | static void | ||
| 3368 | skl_ddb_calc_min(const struct intel_crtc_state *cstate, int num_active, | ||
| 3369 | uint16_t *minimum, uint16_t *y_minimum) | ||
| 3370 | { | ||
| 3371 | const struct drm_plane_state *pstate; | ||
| 3372 | struct drm_plane *plane; | ||
| 3373 | |||
| 3374 | drm_atomic_crtc_state_for_each_plane_state(plane, pstate, &cstate->base) { | ||
| 3375 | struct intel_plane *intel_plane = to_intel_plane(plane); | ||
| 3376 | int id = skl_wm_plane_id(intel_plane); | ||
| 3377 | |||
| 3378 | if (id == PLANE_CURSOR) | ||
| 3379 | continue; | ||
| 3380 | |||
| 3381 | if (!pstate->visible) | ||
| 3382 | continue; | ||
| 3383 | |||
| 3384 | minimum[id] = skl_ddb_min_alloc(pstate, 0); | ||
| 3385 | y_minimum[id] = skl_ddb_min_alloc(pstate, 1); | ||
| 3386 | } | ||
| 3387 | |||
| 3388 | minimum[PLANE_CURSOR] = skl_cursor_allocation(num_active); | ||
| 3389 | } | ||
| 3390 | |||
| 3376 | static int | 3391 | static int |
| 3377 | skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, | 3392 | skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, |
| 3378 | struct skl_ddb_allocation *ddb /* out */) | 3393 | struct skl_ddb_allocation *ddb /* out */) |
| @@ -3381,17 +3396,16 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, | |||
| 3381 | struct drm_crtc *crtc = cstate->base.crtc; | 3396 | struct drm_crtc *crtc = cstate->base.crtc; |
| 3382 | struct drm_device *dev = crtc->dev; | 3397 | struct drm_device *dev = crtc->dev; |
| 3383 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3398 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 3384 | struct intel_plane *intel_plane; | ||
| 3385 | struct drm_plane *plane; | ||
| 3386 | struct drm_plane_state *pstate; | ||
| 3387 | enum pipe pipe = intel_crtc->pipe; | 3399 | enum pipe pipe = intel_crtc->pipe; |
| 3388 | struct skl_ddb_entry *alloc = &cstate->wm.skl.ddb; | 3400 | struct skl_ddb_entry *alloc = &cstate->wm.skl.ddb; |
| 3389 | uint16_t alloc_size, start, cursor_blocks; | 3401 | uint16_t alloc_size, start; |
| 3390 | uint16_t *minimum = cstate->wm.skl.minimum_blocks; | 3402 | uint16_t minimum[I915_MAX_PLANES] = {}; |
| 3391 | uint16_t *y_minimum = cstate->wm.skl.minimum_y_blocks; | 3403 | uint16_t y_minimum[I915_MAX_PLANES] = {}; |
| 3392 | unsigned int total_data_rate; | 3404 | unsigned int total_data_rate; |
| 3393 | int num_active; | 3405 | int num_active; |
| 3394 | int id, i; | 3406 | int id, i; |
| 3407 | unsigned plane_data_rate[I915_MAX_PLANES] = {}; | ||
| 3408 | unsigned plane_y_data_rate[I915_MAX_PLANES] = {}; | ||
| 3395 | 3409 | ||
| 3396 | /* Clear the partitioning for disabled planes. */ | 3410 | /* Clear the partitioning for disabled planes. */ |
| 3397 | memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); | 3411 | memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); |
| @@ -3412,57 +3426,43 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, | |||
| 3412 | return 0; | 3426 | return 0; |
| 3413 | } | 3427 | } |
| 3414 | 3428 | ||
| 3415 | cursor_blocks = skl_cursor_allocation(num_active); | 3429 | skl_ddb_calc_min(cstate, num_active, minimum, y_minimum); |
| 3416 | ddb->plane[pipe][PLANE_CURSOR].start = alloc->end - cursor_blocks; | ||
| 3417 | ddb->plane[pipe][PLANE_CURSOR].end = alloc->end; | ||
| 3418 | |||
| 3419 | alloc_size -= cursor_blocks; | ||
| 3420 | |||
| 3421 | /* 1. Allocate the mininum required blocks for each active plane */ | ||
| 3422 | for_each_plane_in_state(state, plane, pstate, i) { | ||
| 3423 | intel_plane = to_intel_plane(plane); | ||
| 3424 | id = skl_wm_plane_id(intel_plane); | ||
| 3425 | |||
| 3426 | if (intel_plane->pipe != pipe) | ||
| 3427 | continue; | ||
| 3428 | |||
| 3429 | if (!to_intel_plane_state(pstate)->base.visible) { | ||
| 3430 | minimum[id] = 0; | ||
| 3431 | y_minimum[id] = 0; | ||
| 3432 | continue; | ||
| 3433 | } | ||
| 3434 | if (plane->type == DRM_PLANE_TYPE_CURSOR) { | ||
| 3435 | minimum[id] = 0; | ||
| 3436 | y_minimum[id] = 0; | ||
| 3437 | continue; | ||
| 3438 | } | ||
| 3439 | 3430 | ||
| 3440 | minimum[id] = skl_ddb_min_alloc(pstate, 0); | 3431 | /* |
| 3441 | y_minimum[id] = skl_ddb_min_alloc(pstate, 1); | 3432 | * 1. Allocate the mininum required blocks for each active plane |
| 3442 | } | 3433 | * and allocate the cursor, it doesn't require extra allocation |
| 3434 | * proportional to the data rate. | ||
| 3435 | */ | ||
| 3443 | 3436 | ||
| 3444 | for (i = 0; i < PLANE_CURSOR; i++) { | 3437 | for (i = 0; i < I915_MAX_PLANES; i++) { |
| 3445 | alloc_size -= minimum[i]; | 3438 | alloc_size -= minimum[i]; |
| 3446 | alloc_size -= y_minimum[i]; | 3439 | alloc_size -= y_minimum[i]; |
| 3447 | } | 3440 | } |
| 3448 | 3441 | ||
| 3442 | ddb->plane[pipe][PLANE_CURSOR].start = alloc->end - minimum[PLANE_CURSOR]; | ||
| 3443 | ddb->plane[pipe][PLANE_CURSOR].end = alloc->end; | ||
| 3444 | |||
| 3449 | /* | 3445 | /* |
| 3450 | * 2. Distribute the remaining space in proportion to the amount of | 3446 | * 2. Distribute the remaining space in proportion to the amount of |
| 3451 | * data each plane needs to fetch from memory. | 3447 | * data each plane needs to fetch from memory. |
| 3452 | * | 3448 | * |
| 3453 | * FIXME: we may not allocate every single block here. | 3449 | * FIXME: we may not allocate every single block here. |
| 3454 | */ | 3450 | */ |
| 3455 | total_data_rate = skl_get_total_relative_data_rate(cstate); | 3451 | total_data_rate = skl_get_total_relative_data_rate(cstate, |
| 3452 | plane_data_rate, | ||
| 3453 | plane_y_data_rate); | ||
| 3456 | if (total_data_rate == 0) | 3454 | if (total_data_rate == 0) |
| 3457 | return 0; | 3455 | return 0; |
| 3458 | 3456 | ||
| 3459 | start = alloc->start; | 3457 | start = alloc->start; |
| 3460 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { | 3458 | for (id = 0; id < I915_MAX_PLANES; id++) { |
| 3461 | unsigned int data_rate, y_data_rate; | 3459 | unsigned int data_rate, y_data_rate; |
| 3462 | uint16_t plane_blocks, y_plane_blocks = 0; | 3460 | uint16_t plane_blocks, y_plane_blocks = 0; |
| 3463 | int id = skl_wm_plane_id(intel_plane); | ||
| 3464 | 3461 | ||
| 3465 | data_rate = cstate->wm.skl.plane_data_rate[id]; | 3462 | if (id == PLANE_CURSOR) |
| 3463 | continue; | ||
| 3464 | |||
| 3465 | data_rate = plane_data_rate[id]; | ||
| 3466 | 3466 | ||
| 3467 | /* | 3467 | /* |
| 3468 | * allocation for (packed formats) or (uv-plane part of planar format): | 3468 | * allocation for (packed formats) or (uv-plane part of planar format): |
| @@ -3484,7 +3484,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, | |||
| 3484 | /* | 3484 | /* |
| 3485 | * allocation for y_plane part of planar format: | 3485 | * allocation for y_plane part of planar format: |
| 3486 | */ | 3486 | */ |
| 3487 | y_data_rate = cstate->wm.skl.plane_y_data_rate[id]; | 3487 | y_data_rate = plane_y_data_rate[id]; |
| 3488 | 3488 | ||
| 3489 | y_plane_blocks = y_minimum[id]; | 3489 | y_plane_blocks = y_minimum[id]; |
| 3490 | y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate, | 3490 | y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate, |
| @@ -3930,11 +3930,11 @@ bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state, | |||
| 3930 | } | 3930 | } |
| 3931 | 3931 | ||
| 3932 | static int skl_update_pipe_wm(struct drm_crtc_state *cstate, | 3932 | static int skl_update_pipe_wm(struct drm_crtc_state *cstate, |
| 3933 | struct skl_ddb_allocation *ddb, /* out */ | 3933 | const struct skl_pipe_wm *old_pipe_wm, |
| 3934 | struct skl_pipe_wm *pipe_wm, /* out */ | 3934 | struct skl_pipe_wm *pipe_wm, /* out */ |
| 3935 | struct skl_ddb_allocation *ddb, /* out */ | ||
| 3935 | bool *changed /* out */) | 3936 | bool *changed /* out */) |
| 3936 | { | 3937 | { |
| 3937 | struct intel_crtc *intel_crtc = to_intel_crtc(cstate->crtc); | ||
| 3938 | struct intel_crtc_state *intel_cstate = to_intel_crtc_state(cstate); | 3938 | struct intel_crtc_state *intel_cstate = to_intel_crtc_state(cstate); |
| 3939 | int ret; | 3939 | int ret; |
| 3940 | 3940 | ||
| @@ -3942,7 +3942,7 @@ static int skl_update_pipe_wm(struct drm_crtc_state *cstate, | |||
| 3942 | if (ret) | 3942 | if (ret) |
| 3943 | return ret; | 3943 | return ret; |
| 3944 | 3944 | ||
| 3945 | if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm))) | 3945 | if (!memcmp(old_pipe_wm, pipe_wm, sizeof(*pipe_wm))) |
| 3946 | *changed = false; | 3946 | *changed = false; |
| 3947 | else | 3947 | else |
| 3948 | *changed = true; | 3948 | *changed = true; |
| @@ -3981,7 +3981,7 @@ skl_ddb_add_affected_planes(struct intel_crtc_state *cstate) | |||
| 3981 | 3981 | ||
| 3982 | WARN_ON(!drm_atomic_get_existing_crtc_state(state, crtc)); | 3982 | WARN_ON(!drm_atomic_get_existing_crtc_state(state, crtc)); |
| 3983 | 3983 | ||
| 3984 | drm_for_each_plane_mask(plane, dev, crtc->state->plane_mask) { | 3984 | drm_for_each_plane_mask(plane, dev, cstate->base.plane_mask) { |
| 3985 | id = skl_wm_plane_id(to_intel_plane(plane)); | 3985 | id = skl_wm_plane_id(to_intel_plane(plane)); |
| 3986 | 3986 | ||
| 3987 | if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][id], | 3987 | if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][id], |
| @@ -4096,45 +4096,31 @@ skl_print_wm_changes(const struct drm_atomic_state *state) | |||
| 4096 | to_intel_atomic_state(state); | 4096 | to_intel_atomic_state(state); |
| 4097 | const struct drm_crtc *crtc; | 4097 | const struct drm_crtc *crtc; |
| 4098 | const struct drm_crtc_state *cstate; | 4098 | const struct drm_crtc_state *cstate; |
| 4099 | const struct drm_plane *plane; | ||
| 4100 | const struct intel_plane *intel_plane; | 4099 | const struct intel_plane *intel_plane; |
| 4101 | const struct drm_plane_state *pstate; | ||
| 4102 | const struct skl_ddb_allocation *old_ddb = &dev_priv->wm.skl_hw.ddb; | 4100 | const struct skl_ddb_allocation *old_ddb = &dev_priv->wm.skl_hw.ddb; |
| 4103 | const struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb; | 4101 | const struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb; |
| 4104 | enum pipe pipe; | ||
| 4105 | int id; | 4102 | int id; |
| 4106 | int i, j; | 4103 | int i; |
| 4107 | 4104 | ||
| 4108 | for_each_crtc_in_state(state, crtc, cstate, i) { | 4105 | for_each_crtc_in_state(state, crtc, cstate, i) { |
| 4109 | pipe = to_intel_crtc(crtc)->pipe; | 4106 | const struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 4107 | enum pipe pipe = intel_crtc->pipe; | ||
| 4110 | 4108 | ||
| 4111 | for_each_plane_in_state(state, plane, pstate, j) { | 4109 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { |
| 4112 | const struct skl_ddb_entry *old, *new; | 4110 | const struct skl_ddb_entry *old, *new; |
| 4113 | 4111 | ||
| 4114 | intel_plane = to_intel_plane(plane); | ||
| 4115 | id = skl_wm_plane_id(intel_plane); | 4112 | id = skl_wm_plane_id(intel_plane); |
| 4116 | old = &old_ddb->plane[pipe][id]; | 4113 | old = &old_ddb->plane[pipe][id]; |
| 4117 | new = &new_ddb->plane[pipe][id]; | 4114 | new = &new_ddb->plane[pipe][id]; |
| 4118 | 4115 | ||
| 4119 | if (intel_plane->pipe != pipe) | ||
| 4120 | continue; | ||
| 4121 | |||
| 4122 | if (skl_ddb_entry_equal(old, new)) | 4116 | if (skl_ddb_entry_equal(old, new)) |
| 4123 | continue; | 4117 | continue; |
| 4124 | 4118 | ||
| 4125 | if (id != PLANE_CURSOR) { | 4119 | DRM_DEBUG_ATOMIC("[PLANE:%d:%s] ddb (%d - %d) -> (%d - %d)\n", |
| 4126 | DRM_DEBUG_ATOMIC("[PLANE:%d:plane %d%c] ddb (%d - %d) -> (%d - %d)\n", | 4120 | intel_plane->base.base.id, |
| 4127 | plane->base.id, id + 1, | 4121 | intel_plane->base.name, |
| 4128 | pipe_name(pipe), | 4122 | old->start, old->end, |
| 4129 | old->start, old->end, | 4123 | new->start, new->end); |
| 4130 | new->start, new->end); | ||
| 4131 | } else { | ||
| 4132 | DRM_DEBUG_ATOMIC("[PLANE:%d:cursor %c] ddb (%d - %d) -> (%d - %d)\n", | ||
| 4133 | plane->base.id, | ||
| 4134 | pipe_name(pipe), | ||
| 4135 | old->start, old->end, | ||
| 4136 | new->start, new->end); | ||
| 4137 | } | ||
| 4138 | } | 4124 | } |
| 4139 | } | 4125 | } |
| 4140 | } | 4126 | } |
| @@ -4183,10 +4169,12 @@ skl_compute_wm(struct drm_atomic_state *state) | |||
| 4183 | for_each_crtc_in_state(state, crtc, cstate, i) { | 4169 | for_each_crtc_in_state(state, crtc, cstate, i) { |
| 4184 | struct intel_crtc_state *intel_cstate = | 4170 | struct intel_crtc_state *intel_cstate = |
| 4185 | to_intel_crtc_state(cstate); | 4171 | to_intel_crtc_state(cstate); |
| 4172 | const struct skl_pipe_wm *old_pipe_wm = | ||
| 4173 | &to_intel_crtc_state(crtc->state)->wm.skl.optimal; | ||
| 4186 | 4174 | ||
| 4187 | pipe_wm = &intel_cstate->wm.skl.optimal; | 4175 | pipe_wm = &intel_cstate->wm.skl.optimal; |
| 4188 | ret = skl_update_pipe_wm(cstate, &results->ddb, pipe_wm, | 4176 | ret = skl_update_pipe_wm(cstate, old_pipe_wm, pipe_wm, |
| 4189 | &changed); | 4177 | &results->ddb, &changed); |
| 4190 | if (ret) | 4178 | if (ret) |
| 4191 | return ret; | 4179 | return ret; |
| 4192 | 4180 | ||
| @@ -4205,22 +4193,19 @@ skl_compute_wm(struct drm_atomic_state *state) | |||
| 4205 | return 0; | 4193 | return 0; |
| 4206 | } | 4194 | } |
| 4207 | 4195 | ||
| 4208 | static void skl_update_wm(struct drm_crtc *crtc) | 4196 | static void skl_update_wm(struct intel_crtc *intel_crtc) |
| 4209 | { | 4197 | { |
| 4210 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 4198 | struct drm_device *dev = intel_crtc->base.dev; |
| 4211 | struct drm_device *dev = crtc->dev; | ||
| 4212 | struct drm_i915_private *dev_priv = to_i915(dev); | 4199 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 4213 | struct skl_wm_values *results = &dev_priv->wm.skl_results; | 4200 | struct skl_wm_values *results = &dev_priv->wm.skl_results; |
| 4214 | struct skl_wm_values *hw_vals = &dev_priv->wm.skl_hw; | 4201 | struct skl_wm_values *hw_vals = &dev_priv->wm.skl_hw; |
| 4215 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); | 4202 | struct intel_crtc_state *cstate = to_intel_crtc_state(intel_crtc->base.state); |
| 4216 | struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal; | 4203 | struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal; |
| 4217 | enum pipe pipe = intel_crtc->pipe; | 4204 | enum pipe pipe = intel_crtc->pipe; |
| 4218 | 4205 | ||
| 4219 | if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0) | 4206 | if ((results->dirty_pipes & drm_crtc_mask(&intel_crtc->base)) == 0) |
| 4220 | return; | 4207 | return; |
| 4221 | 4208 | ||
| 4222 | intel_crtc->wm.active.skl = *pipe_wm; | ||
| 4223 | |||
| 4224 | mutex_lock(&dev_priv->wm.wm_mutex); | 4209 | mutex_lock(&dev_priv->wm.wm_mutex); |
| 4225 | 4210 | ||
| 4226 | /* | 4211 | /* |
| @@ -4229,10 +4214,10 @@ static void skl_update_wm(struct drm_crtc *crtc) | |||
| 4229 | * the pipe's shut off, just do so here. Already active pipes will have | 4214 | * the pipe's shut off, just do so here. Already active pipes will have |
| 4230 | * their watermarks updated once we update their planes. | 4215 | * their watermarks updated once we update their planes. |
| 4231 | */ | 4216 | */ |
| 4232 | if (crtc->state->active_changed) { | 4217 | if (intel_crtc->base.state->active_changed) { |
| 4233 | int plane; | 4218 | int plane; |
| 4234 | 4219 | ||
| 4235 | for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) | 4220 | for_each_universal_plane(dev_priv, pipe, plane) |
| 4236 | skl_write_plane_wm(intel_crtc, &pipe_wm->planes[plane], | 4221 | skl_write_plane_wm(intel_crtc, &pipe_wm->planes[plane], |
| 4237 | &results->ddb, plane); | 4222 | &results->ddb, plane); |
| 4238 | 4223 | ||
| @@ -4388,10 +4373,8 @@ void skl_wm_get_hw_state(struct drm_device *dev) | |||
| 4388 | 4373 | ||
| 4389 | skl_pipe_wm_get_hw_state(crtc, &cstate->wm.skl.optimal); | 4374 | skl_pipe_wm_get_hw_state(crtc, &cstate->wm.skl.optimal); |
| 4390 | 4375 | ||
| 4391 | if (intel_crtc->active) { | 4376 | if (intel_crtc->active) |
| 4392 | hw->dirty_pipes |= drm_crtc_mask(crtc); | 4377 | hw->dirty_pipes |= drm_crtc_mask(crtc); |
| 4393 | intel_crtc->wm.active.skl = cstate->wm.skl.optimal; | ||
| 4394 | } | ||
| 4395 | } | 4378 | } |
| 4396 | 4379 | ||
| 4397 | if (dev_priv->active_crtcs) { | 4380 | if (dev_priv->active_crtcs) { |
| @@ -4553,11 +4536,11 @@ void vlv_wm_get_hw_state(struct drm_device *dev) | |||
| 4553 | plane->wm.fifo_size = 63; | 4536 | plane->wm.fifo_size = 63; |
| 4554 | break; | 4537 | break; |
| 4555 | case DRM_PLANE_TYPE_PRIMARY: | 4538 | case DRM_PLANE_TYPE_PRIMARY: |
| 4556 | plane->wm.fifo_size = vlv_get_fifo_size(dev, plane->pipe, 0); | 4539 | plane->wm.fifo_size = vlv_get_fifo_size(dev_priv, plane->pipe, 0); |
| 4557 | break; | 4540 | break; |
| 4558 | case DRM_PLANE_TYPE_OVERLAY: | 4541 | case DRM_PLANE_TYPE_OVERLAY: |
| 4559 | sprite = plane->plane; | 4542 | sprite = plane->plane; |
| 4560 | plane->wm.fifo_size = vlv_get_fifo_size(dev, plane->pipe, sprite + 1); | 4543 | plane->wm.fifo_size = vlv_get_fifo_size(dev_priv, plane->pipe, sprite + 1); |
| 4561 | break; | 4544 | break; |
| 4562 | } | 4545 | } |
| 4563 | } | 4546 | } |
| @@ -4670,9 +4653,9 @@ void ilk_wm_get_hw_state(struct drm_device *dev) | |||
| 4670 | * We don't use the sprite, so we can ignore that. And on Crestline we have | 4653 | * We don't use the sprite, so we can ignore that. And on Crestline we have |
| 4671 | * to set the non-SR watermarks to 8. | 4654 | * to set the non-SR watermarks to 8. |
| 4672 | */ | 4655 | */ |
| 4673 | void intel_update_watermarks(struct drm_crtc *crtc) | 4656 | void intel_update_watermarks(struct intel_crtc *crtc) |
| 4674 | { | 4657 | { |
| 4675 | struct drm_i915_private *dev_priv = to_i915(crtc->dev); | 4658 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
| 4676 | 4659 | ||
| 4677 | if (dev_priv->display.update_wm) | 4660 | if (dev_priv->display.update_wm) |
| 4678 | dev_priv->display.update_wm(crtc); | 4661 | dev_priv->display.update_wm(crtc); |
| @@ -5878,7 +5861,7 @@ static void valleyview_cleanup_pctx(struct drm_i915_private *dev_priv) | |||
| 5878 | if (WARN_ON(!dev_priv->vlv_pctx)) | 5861 | if (WARN_ON(!dev_priv->vlv_pctx)) |
| 5879 | return; | 5862 | return; |
| 5880 | 5863 | ||
| 5881 | i915_gem_object_put_unlocked(dev_priv->vlv_pctx); | 5864 | i915_gem_object_put(dev_priv->vlv_pctx); |
| 5882 | dev_priv->vlv_pctx = NULL; | 5865 | dev_priv->vlv_pctx = NULL; |
| 5883 | } | 5866 | } |
| 5884 | 5867 | ||
| @@ -6862,10 +6845,8 @@ void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv) | |||
| 6862 | } | 6845 | } |
| 6863 | } | 6846 | } |
| 6864 | 6847 | ||
| 6865 | static void ibx_init_clock_gating(struct drm_device *dev) | 6848 | static void ibx_init_clock_gating(struct drm_i915_private *dev_priv) |
| 6866 | { | 6849 | { |
| 6867 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 6868 | |||
| 6869 | /* | 6850 | /* |
| 6870 | * On Ibex Peak and Cougar Point, we need to disable clock | 6851 | * On Ibex Peak and Cougar Point, we need to disable clock |
| 6871 | * gating for the panel power sequencer or it will fail to | 6852 | * gating for the panel power sequencer or it will fail to |
| @@ -6874,9 +6855,8 @@ static void ibx_init_clock_gating(struct drm_device *dev) | |||
| 6874 | I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); | 6855 | I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); |
| 6875 | } | 6856 | } |
| 6876 | 6857 | ||
| 6877 | static void g4x_disable_trickle_feed(struct drm_device *dev) | 6858 | static void g4x_disable_trickle_feed(struct drm_i915_private *dev_priv) |
| 6878 | { | 6859 | { |
| 6879 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 6880 | enum pipe pipe; | 6860 | enum pipe pipe; |
| 6881 | 6861 | ||
| 6882 | for_each_pipe(dev_priv, pipe) { | 6862 | for_each_pipe(dev_priv, pipe) { |
| @@ -6889,10 +6869,8 @@ static void g4x_disable_trickle_feed(struct drm_device *dev) | |||
| 6889 | } | 6869 | } |
| 6890 | } | 6870 | } |
| 6891 | 6871 | ||
| 6892 | static void ilk_init_lp_watermarks(struct drm_device *dev) | 6872 | static void ilk_init_lp_watermarks(struct drm_i915_private *dev_priv) |
| 6893 | { | 6873 | { |
| 6894 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 6895 | |||
| 6896 | I915_WRITE(WM3_LP_ILK, I915_READ(WM3_LP_ILK) & ~WM1_LP_SR_EN); | 6874 | I915_WRITE(WM3_LP_ILK, I915_READ(WM3_LP_ILK) & ~WM1_LP_SR_EN); |
| 6897 | I915_WRITE(WM2_LP_ILK, I915_READ(WM2_LP_ILK) & ~WM1_LP_SR_EN); | 6875 | I915_WRITE(WM2_LP_ILK, I915_READ(WM2_LP_ILK) & ~WM1_LP_SR_EN); |
| 6898 | I915_WRITE(WM1_LP_ILK, I915_READ(WM1_LP_ILK) & ~WM1_LP_SR_EN); | 6876 | I915_WRITE(WM1_LP_ILK, I915_READ(WM1_LP_ILK) & ~WM1_LP_SR_EN); |
| @@ -6903,9 +6881,8 @@ static void ilk_init_lp_watermarks(struct drm_device *dev) | |||
| 6903 | */ | 6881 | */ |
| 6904 | } | 6882 | } |
| 6905 | 6883 | ||
| 6906 | static void ironlake_init_clock_gating(struct drm_device *dev) | 6884 | static void ironlake_init_clock_gating(struct drm_i915_private *dev_priv) |
| 6907 | { | 6885 | { |
| 6908 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 6909 | uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; | 6886 | uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; |
| 6910 | 6887 | ||
| 6911 | /* | 6888 | /* |
| @@ -6937,7 +6914,7 @@ static void ironlake_init_clock_gating(struct drm_device *dev) | |||
| 6937 | (I915_READ(DISP_ARB_CTL) | | 6914 | (I915_READ(DISP_ARB_CTL) | |
| 6938 | DISP_FBC_WM_DIS)); | 6915 | DISP_FBC_WM_DIS)); |
| 6939 | 6916 | ||
| 6940 | ilk_init_lp_watermarks(dev); | 6917 | ilk_init_lp_watermarks(dev_priv); |
| 6941 | 6918 | ||
| 6942 | /* | 6919 | /* |
| 6943 | * Based on the document from hardware guys the following bits | 6920 | * Based on the document from hardware guys the following bits |
| @@ -6972,14 +6949,13 @@ static void ironlake_init_clock_gating(struct drm_device *dev) | |||
| 6972 | /* WaDisable_RenderCache_OperationalFlush:ilk */ | 6949 | /* WaDisable_RenderCache_OperationalFlush:ilk */ |
| 6973 | I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); | 6950 | I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); |
| 6974 | 6951 | ||
| 6975 | g4x_disable_trickle_feed(dev); | 6952 | g4x_disable_trickle_feed(dev_priv); |
| 6976 | 6953 | ||
| 6977 | ibx_init_clock_gating(dev); | 6954 | ibx_init_clock_gating(dev_priv); |
| 6978 | } | 6955 | } |
| 6979 | 6956 | ||
| 6980 | static void cpt_init_clock_gating(struct drm_device *dev) | 6957 | static void cpt_init_clock_gating(struct drm_i915_private *dev_priv) |
| 6981 | { | 6958 | { |
| 6982 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 6983 | int pipe; | 6959 | int pipe; |
| 6984 | uint32_t val; | 6960 | uint32_t val; |
| 6985 | 6961 | ||
| @@ -7014,9 +6990,8 @@ static void cpt_init_clock_gating(struct drm_device *dev) | |||
| 7014 | } | 6990 | } |
| 7015 | } | 6991 | } |
| 7016 | 6992 | ||
| 7017 | static void gen6_check_mch_setup(struct drm_device *dev) | 6993 | static void gen6_check_mch_setup(struct drm_i915_private *dev_priv) |
| 7018 | { | 6994 | { |
| 7019 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7020 | uint32_t tmp; | 6995 | uint32_t tmp; |
| 7021 | 6996 | ||
| 7022 | tmp = I915_READ(MCH_SSKPD); | 6997 | tmp = I915_READ(MCH_SSKPD); |
| @@ -7025,9 +7000,8 @@ static void gen6_check_mch_setup(struct drm_device *dev) | |||
| 7025 | tmp); | 7000 | tmp); |
| 7026 | } | 7001 | } |
| 7027 | 7002 | ||
| 7028 | static void gen6_init_clock_gating(struct drm_device *dev) | 7003 | static void gen6_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7029 | { | 7004 | { |
| 7030 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7031 | uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; | 7005 | uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; |
| 7032 | 7006 | ||
| 7033 | I915_WRITE(ILK_DSPCLK_GATE_D, dspclk_gate); | 7007 | I915_WRITE(ILK_DSPCLK_GATE_D, dspclk_gate); |
| @@ -7054,7 +7028,7 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
| 7054 | I915_WRITE(GEN6_GT_MODE, | 7028 | I915_WRITE(GEN6_GT_MODE, |
| 7055 | _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4)); | 7029 | _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4)); |
| 7056 | 7030 | ||
| 7057 | ilk_init_lp_watermarks(dev); | 7031 | ilk_init_lp_watermarks(dev_priv); |
| 7058 | 7032 | ||
| 7059 | I915_WRITE(CACHE_MODE_0, | 7033 | I915_WRITE(CACHE_MODE_0, |
| 7060 | _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB)); | 7034 | _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB)); |
| @@ -7115,11 +7089,11 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
| 7115 | ILK_DPARBUNIT_CLOCK_GATE_ENABLE | | 7089 | ILK_DPARBUNIT_CLOCK_GATE_ENABLE | |
| 7116 | ILK_DPFDUNIT_CLOCK_GATE_ENABLE); | 7090 | ILK_DPFDUNIT_CLOCK_GATE_ENABLE); |
| 7117 | 7091 | ||
| 7118 | g4x_disable_trickle_feed(dev); | 7092 | g4x_disable_trickle_feed(dev_priv); |
| 7119 | 7093 | ||
| 7120 | cpt_init_clock_gating(dev); | 7094 | cpt_init_clock_gating(dev_priv); |
| 7121 | 7095 | ||
| 7122 | gen6_check_mch_setup(dev); | 7096 | gen6_check_mch_setup(dev_priv); |
| 7123 | } | 7097 | } |
| 7124 | 7098 | ||
| 7125 | static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv) | 7099 | static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv) |
| @@ -7140,10 +7114,8 @@ static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv) | |||
| 7140 | I915_WRITE(GEN7_FF_THREAD_MODE, reg); | 7114 | I915_WRITE(GEN7_FF_THREAD_MODE, reg); |
| 7141 | } | 7115 | } |
| 7142 | 7116 | ||
| 7143 | static void lpt_init_clock_gating(struct drm_device *dev) | 7117 | static void lpt_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7144 | { | 7118 | { |
| 7145 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7146 | |||
| 7147 | /* | 7119 | /* |
| 7148 | * TODO: this bit should only be enabled when really needed, then | 7120 | * TODO: this bit should only be enabled when really needed, then |
| 7149 | * disabled when not needed anymore in order to save power. | 7121 | * disabled when not needed anymore in order to save power. |
| @@ -7159,10 +7131,8 @@ static void lpt_init_clock_gating(struct drm_device *dev) | |||
| 7159 | TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); | 7131 | TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); |
| 7160 | } | 7132 | } |
| 7161 | 7133 | ||
| 7162 | static void lpt_suspend_hw(struct drm_device *dev) | 7134 | static void lpt_suspend_hw(struct drm_i915_private *dev_priv) |
| 7163 | { | 7135 | { |
| 7164 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7165 | |||
| 7166 | if (HAS_PCH_LPT_LP(dev_priv)) { | 7136 | if (HAS_PCH_LPT_LP(dev_priv)) { |
| 7167 | uint32_t val = I915_READ(SOUTH_DSPCLK_GATE_D); | 7137 | uint32_t val = I915_READ(SOUTH_DSPCLK_GATE_D); |
| 7168 | 7138 | ||
| @@ -7194,11 +7164,9 @@ static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv, | |||
| 7194 | I915_WRITE(GEN7_MISCCPCTL, misccpctl); | 7164 | I915_WRITE(GEN7_MISCCPCTL, misccpctl); |
| 7195 | } | 7165 | } |
| 7196 | 7166 | ||
| 7197 | static void kabylake_init_clock_gating(struct drm_device *dev) | 7167 | static void kabylake_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7198 | { | 7168 | { |
| 7199 | struct drm_i915_private *dev_priv = dev->dev_private; | 7169 | gen9_init_clock_gating(dev_priv); |
| 7200 | |||
| 7201 | gen9_init_clock_gating(dev); | ||
| 7202 | 7170 | ||
| 7203 | /* WaDisableSDEUnitClockGating:kbl */ | 7171 | /* WaDisableSDEUnitClockGating:kbl */ |
| 7204 | if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0)) | 7172 | if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0)) |
| @@ -7215,11 +7183,9 @@ static void kabylake_init_clock_gating(struct drm_device *dev) | |||
| 7215 | ILK_DPFC_NUKE_ON_ANY_MODIFICATION); | 7183 | ILK_DPFC_NUKE_ON_ANY_MODIFICATION); |
| 7216 | } | 7184 | } |
| 7217 | 7185 | ||
| 7218 | static void skylake_init_clock_gating(struct drm_device *dev) | 7186 | static void skylake_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7219 | { | 7187 | { |
| 7220 | struct drm_i915_private *dev_priv = dev->dev_private; | 7188 | gen9_init_clock_gating(dev_priv); |
| 7221 | |||
| 7222 | gen9_init_clock_gating(dev); | ||
| 7223 | 7189 | ||
| 7224 | /* WAC6entrylatency:skl */ | 7190 | /* WAC6entrylatency:skl */ |
| 7225 | I915_WRITE(FBC_LLC_READ_CTRL, I915_READ(FBC_LLC_READ_CTRL) | | 7191 | I915_WRITE(FBC_LLC_READ_CTRL, I915_READ(FBC_LLC_READ_CTRL) | |
| @@ -7230,12 +7196,11 @@ static void skylake_init_clock_gating(struct drm_device *dev) | |||
| 7230 | ILK_DPFC_NUKE_ON_ANY_MODIFICATION); | 7196 | ILK_DPFC_NUKE_ON_ANY_MODIFICATION); |
| 7231 | } | 7197 | } |
| 7232 | 7198 | ||
| 7233 | static void broadwell_init_clock_gating(struct drm_device *dev) | 7199 | static void broadwell_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7234 | { | 7200 | { |
| 7235 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7236 | enum pipe pipe; | 7201 | enum pipe pipe; |
| 7237 | 7202 | ||
| 7238 | ilk_init_lp_watermarks(dev); | 7203 | ilk_init_lp_watermarks(dev_priv); |
| 7239 | 7204 | ||
| 7240 | /* WaSwitchSolVfFArbitrationPriority:bdw */ | 7205 | /* WaSwitchSolVfFArbitrationPriority:bdw */ |
| 7241 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); | 7206 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); |
| @@ -7278,14 +7243,12 @@ static void broadwell_init_clock_gating(struct drm_device *dev) | |||
| 7278 | I915_WRITE(CHICKEN_PAR2_1, I915_READ(CHICKEN_PAR2_1) | 7243 | I915_WRITE(CHICKEN_PAR2_1, I915_READ(CHICKEN_PAR2_1) |
| 7279 | | KVM_CONFIG_CHANGE_NOTIFICATION_SELECT); | 7244 | | KVM_CONFIG_CHANGE_NOTIFICATION_SELECT); |
| 7280 | 7245 | ||
| 7281 | lpt_init_clock_gating(dev); | 7246 | lpt_init_clock_gating(dev_priv); |
| 7282 | } | 7247 | } |
| 7283 | 7248 | ||
| 7284 | static void haswell_init_clock_gating(struct drm_device *dev) | 7249 | static void haswell_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7285 | { | 7250 | { |
| 7286 | struct drm_i915_private *dev_priv = to_i915(dev); | 7251 | ilk_init_lp_watermarks(dev_priv); |
| 7287 | |||
| 7288 | ilk_init_lp_watermarks(dev); | ||
| 7289 | 7252 | ||
| 7290 | /* L3 caching of data atomics doesn't work -- disable it. */ | 7253 | /* L3 caching of data atomics doesn't work -- disable it. */ |
| 7291 | I915_WRITE(HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE); | 7254 | I915_WRITE(HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE); |
| @@ -7334,15 +7297,14 @@ static void haswell_init_clock_gating(struct drm_device *dev) | |||
| 7334 | I915_WRITE(CHICKEN_PAR1_1, | 7297 | I915_WRITE(CHICKEN_PAR1_1, |
| 7335 | I915_READ(CHICKEN_PAR1_1) | FORCE_ARB_IDLE_PLANES); | 7298 | I915_READ(CHICKEN_PAR1_1) | FORCE_ARB_IDLE_PLANES); |
| 7336 | 7299 | ||
| 7337 | lpt_init_clock_gating(dev); | 7300 | lpt_init_clock_gating(dev_priv); |
| 7338 | } | 7301 | } |
| 7339 | 7302 | ||
| 7340 | static void ivybridge_init_clock_gating(struct drm_device *dev) | 7303 | static void ivybridge_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7341 | { | 7304 | { |
| 7342 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7343 | uint32_t snpcr; | 7305 | uint32_t snpcr; |
| 7344 | 7306 | ||
| 7345 | ilk_init_lp_watermarks(dev); | 7307 | ilk_init_lp_watermarks(dev_priv); |
| 7346 | 7308 | ||
| 7347 | I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); | 7309 | I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); |
| 7348 | 7310 | ||
| @@ -7399,7 +7361,7 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) | |||
| 7399 | I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | | 7361 | I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | |
| 7400 | GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); | 7362 | GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); |
| 7401 | 7363 | ||
| 7402 | g4x_disable_trickle_feed(dev); | 7364 | g4x_disable_trickle_feed(dev_priv); |
| 7403 | 7365 | ||
| 7404 | gen7_setup_fixed_func_scheduler(dev_priv); | 7366 | gen7_setup_fixed_func_scheduler(dev_priv); |
| 7405 | 7367 | ||
| @@ -7430,15 +7392,13 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) | |||
| 7430 | I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr); | 7392 | I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr); |
| 7431 | 7393 | ||
| 7432 | if (!HAS_PCH_NOP(dev_priv)) | 7394 | if (!HAS_PCH_NOP(dev_priv)) |
| 7433 | cpt_init_clock_gating(dev); | 7395 | cpt_init_clock_gating(dev_priv); |
| 7434 | 7396 | ||
| 7435 | gen6_check_mch_setup(dev); | 7397 | gen6_check_mch_setup(dev_priv); |
| 7436 | } | 7398 | } |
| 7437 | 7399 | ||
| 7438 | static void valleyview_init_clock_gating(struct drm_device *dev) | 7400 | static void valleyview_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7439 | { | 7401 | { |
| 7440 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7441 | |||
| 7442 | /* WaDisableEarlyCull:vlv */ | 7402 | /* WaDisableEarlyCull:vlv */ |
| 7443 | I915_WRITE(_3D_CHICKEN3, | 7403 | I915_WRITE(_3D_CHICKEN3, |
| 7444 | _MASKED_BIT_ENABLE(_3D_CHICKEN_SF_DISABLE_OBJEND_CULL)); | 7404 | _MASKED_BIT_ENABLE(_3D_CHICKEN_SF_DISABLE_OBJEND_CULL)); |
| @@ -7517,10 +7477,8 @@ static void valleyview_init_clock_gating(struct drm_device *dev) | |||
| 7517 | I915_WRITE(VLV_GUNIT_CLOCK_GATE, GCFG_DIS); | 7477 | I915_WRITE(VLV_GUNIT_CLOCK_GATE, GCFG_DIS); |
| 7518 | } | 7478 | } |
| 7519 | 7479 | ||
| 7520 | static void cherryview_init_clock_gating(struct drm_device *dev) | 7480 | static void cherryview_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7521 | { | 7481 | { |
| 7522 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7523 | |||
| 7524 | /* WaVSRefCountFullforceMissDisable:chv */ | 7482 | /* WaVSRefCountFullforceMissDisable:chv */ |
| 7525 | /* WaDSRefCountFullforceMissDisable:chv */ | 7483 | /* WaDSRefCountFullforceMissDisable:chv */ |
| 7526 | I915_WRITE(GEN7_FF_THREAD_MODE, | 7484 | I915_WRITE(GEN7_FF_THREAD_MODE, |
| @@ -7553,9 +7511,8 @@ static void cherryview_init_clock_gating(struct drm_device *dev) | |||
| 7553 | I915_WRITE(HSW_GTT_CACHE_EN, GTT_CACHE_EN_ALL); | 7511 | I915_WRITE(HSW_GTT_CACHE_EN, GTT_CACHE_EN_ALL); |
| 7554 | } | 7512 | } |
| 7555 | 7513 | ||
| 7556 | static void g4x_init_clock_gating(struct drm_device *dev) | 7514 | static void g4x_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7557 | { | 7515 | { |
| 7558 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7559 | uint32_t dspclk_gate; | 7516 | uint32_t dspclk_gate; |
| 7560 | 7517 | ||
| 7561 | I915_WRITE(RENCLK_GATE_D1, 0); | 7518 | I915_WRITE(RENCLK_GATE_D1, 0); |
| @@ -7577,13 +7534,11 @@ static void g4x_init_clock_gating(struct drm_device *dev) | |||
| 7577 | /* WaDisable_RenderCache_OperationalFlush:g4x */ | 7534 | /* WaDisable_RenderCache_OperationalFlush:g4x */ |
| 7578 | I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); | 7535 | I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); |
| 7579 | 7536 | ||
| 7580 | g4x_disable_trickle_feed(dev); | 7537 | g4x_disable_trickle_feed(dev_priv); |
| 7581 | } | 7538 | } |
| 7582 | 7539 | ||
| 7583 | static void crestline_init_clock_gating(struct drm_device *dev) | 7540 | static void crestline_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7584 | { | 7541 | { |
| 7585 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7586 | |||
| 7587 | I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); | 7542 | I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); |
| 7588 | I915_WRITE(RENCLK_GATE_D2, 0); | 7543 | I915_WRITE(RENCLK_GATE_D2, 0); |
| 7589 | I915_WRITE(DSPCLK_GATE_D, 0); | 7544 | I915_WRITE(DSPCLK_GATE_D, 0); |
| @@ -7596,10 +7551,8 @@ static void crestline_init_clock_gating(struct drm_device *dev) | |||
| 7596 | I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); | 7551 | I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); |
| 7597 | } | 7552 | } |
| 7598 | 7553 | ||
| 7599 | static void broadwater_init_clock_gating(struct drm_device *dev) | 7554 | static void broadwater_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7600 | { | 7555 | { |
| 7601 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7602 | |||
| 7603 | I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | | 7556 | I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | |
| 7604 | I965_RCC_CLOCK_GATE_DISABLE | | 7557 | I965_RCC_CLOCK_GATE_DISABLE | |
| 7605 | I965_RCPB_CLOCK_GATE_DISABLE | | 7558 | I965_RCPB_CLOCK_GATE_DISABLE | |
| @@ -7613,16 +7566,15 @@ static void broadwater_init_clock_gating(struct drm_device *dev) | |||
| 7613 | I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); | 7566 | I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); |
| 7614 | } | 7567 | } |
| 7615 | 7568 | ||
| 7616 | static void gen3_init_clock_gating(struct drm_device *dev) | 7569 | static void gen3_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7617 | { | 7570 | { |
| 7618 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7619 | u32 dstate = I915_READ(D_STATE); | 7571 | u32 dstate = I915_READ(D_STATE); |
| 7620 | 7572 | ||
| 7621 | dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING | | 7573 | dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING | |
| 7622 | DSTATE_DOT_CLOCK_GATING; | 7574 | DSTATE_DOT_CLOCK_GATING; |
| 7623 | I915_WRITE(D_STATE, dstate); | 7575 | I915_WRITE(D_STATE, dstate); |
| 7624 | 7576 | ||
| 7625 | if (IS_PINEVIEW(dev)) | 7577 | if (IS_PINEVIEW(dev_priv)) |
| 7626 | I915_WRITE(ECOSKPD, _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY)); | 7578 | I915_WRITE(ECOSKPD, _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY)); |
| 7627 | 7579 | ||
| 7628 | /* IIR "flip pending" means done if this bit is set */ | 7580 | /* IIR "flip pending" means done if this bit is set */ |
| @@ -7638,10 +7590,8 @@ static void gen3_init_clock_gating(struct drm_device *dev) | |||
| 7638 | _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); | 7590 | _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); |
| 7639 | } | 7591 | } |
| 7640 | 7592 | ||
| 7641 | static void i85x_init_clock_gating(struct drm_device *dev) | 7593 | static void i85x_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7642 | { | 7594 | { |
| 7643 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7644 | |||
| 7645 | I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); | 7595 | I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); |
| 7646 | 7596 | ||
| 7647 | /* interrupts should cause a wake up from C3 */ | 7597 | /* interrupts should cause a wake up from C3 */ |
| @@ -7652,10 +7602,8 @@ static void i85x_init_clock_gating(struct drm_device *dev) | |||
| 7652 | _MASKED_BIT_ENABLE(MEM_DISPLAY_TRICKLE_FEED_DISABLE)); | 7602 | _MASKED_BIT_ENABLE(MEM_DISPLAY_TRICKLE_FEED_DISABLE)); |
| 7653 | } | 7603 | } |
| 7654 | 7604 | ||
| 7655 | static void i830_init_clock_gating(struct drm_device *dev) | 7605 | static void i830_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7656 | { | 7606 | { |
| 7657 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7658 | |||
| 7659 | I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); | 7607 | I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); |
| 7660 | 7608 | ||
| 7661 | I915_WRITE(MEM_MODE, | 7609 | I915_WRITE(MEM_MODE, |
| @@ -7663,20 +7611,18 @@ static void i830_init_clock_gating(struct drm_device *dev) | |||
| 7663 | _MASKED_BIT_ENABLE(MEM_DISPLAY_B_TRICKLE_FEED_DISABLE)); | 7611 | _MASKED_BIT_ENABLE(MEM_DISPLAY_B_TRICKLE_FEED_DISABLE)); |
| 7664 | } | 7612 | } |
| 7665 | 7613 | ||
| 7666 | void intel_init_clock_gating(struct drm_device *dev) | 7614 | void intel_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7667 | { | 7615 | { |
| 7668 | struct drm_i915_private *dev_priv = to_i915(dev); | 7616 | dev_priv->display.init_clock_gating(dev_priv); |
| 7669 | |||
| 7670 | dev_priv->display.init_clock_gating(dev); | ||
| 7671 | } | 7617 | } |
| 7672 | 7618 | ||
| 7673 | void intel_suspend_hw(struct drm_device *dev) | 7619 | void intel_suspend_hw(struct drm_i915_private *dev_priv) |
| 7674 | { | 7620 | { |
| 7675 | if (HAS_PCH_LPT(to_i915(dev))) | 7621 | if (HAS_PCH_LPT(dev_priv)) |
| 7676 | lpt_suspend_hw(dev); | 7622 | lpt_suspend_hw(dev_priv); |
| 7677 | } | 7623 | } |
| 7678 | 7624 | ||
| 7679 | static void nop_init_clock_gating(struct drm_device *dev) | 7625 | static void nop_init_clock_gating(struct drm_i915_private *dev_priv) |
| 7680 | { | 7626 | { |
| 7681 | DRM_DEBUG_KMS("No clock gating settings or workarounds applied.\n"); | 7627 | DRM_DEBUG_KMS("No clock gating settings or workarounds applied.\n"); |
| 7682 | } | 7628 | } |
| @@ -7731,25 +7677,23 @@ void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv) | |||
| 7731 | } | 7677 | } |
| 7732 | 7678 | ||
| 7733 | /* Set up chip specific power management-related functions */ | 7679 | /* Set up chip specific power management-related functions */ |
| 7734 | void intel_init_pm(struct drm_device *dev) | 7680 | void intel_init_pm(struct drm_i915_private *dev_priv) |
| 7735 | { | 7681 | { |
| 7736 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 7737 | |||
| 7738 | intel_fbc_init(dev_priv); | 7682 | intel_fbc_init(dev_priv); |
| 7739 | 7683 | ||
| 7740 | /* For cxsr */ | 7684 | /* For cxsr */ |
| 7741 | if (IS_PINEVIEW(dev)) | 7685 | if (IS_PINEVIEW(dev_priv)) |
| 7742 | i915_pineview_get_mem_freq(dev); | 7686 | i915_pineview_get_mem_freq(dev_priv); |
| 7743 | else if (IS_GEN5(dev_priv)) | 7687 | else if (IS_GEN5(dev_priv)) |
| 7744 | i915_ironlake_get_mem_freq(dev); | 7688 | i915_ironlake_get_mem_freq(dev_priv); |
| 7745 | 7689 | ||
| 7746 | /* For FIFO watermark updates */ | 7690 | /* For FIFO watermark updates */ |
| 7747 | if (INTEL_INFO(dev)->gen >= 9) { | 7691 | if (INTEL_GEN(dev_priv) >= 9) { |
| 7748 | skl_setup_wm_latency(dev); | 7692 | skl_setup_wm_latency(dev_priv); |
| 7749 | dev_priv->display.update_wm = skl_update_wm; | 7693 | dev_priv->display.update_wm = skl_update_wm; |
| 7750 | dev_priv->display.compute_global_watermarks = skl_compute_wm; | 7694 | dev_priv->display.compute_global_watermarks = skl_compute_wm; |
| 7751 | } else if (HAS_PCH_SPLIT(dev_priv)) { | 7695 | } else if (HAS_PCH_SPLIT(dev_priv)) { |
| 7752 | ilk_setup_wm_latency(dev); | 7696 | ilk_setup_wm_latency(dev_priv); |
| 7753 | 7697 | ||
| 7754 | if ((IS_GEN5(dev_priv) && dev_priv->wm.pri_latency[1] && | 7698 | if ((IS_GEN5(dev_priv) && dev_priv->wm.pri_latency[1] && |
| 7755 | dev_priv->wm.spr_latency[1] && dev_priv->wm.cur_latency[1]) || | 7699 | dev_priv->wm.spr_latency[1] && dev_priv->wm.cur_latency[1]) || |
| @@ -7767,12 +7711,12 @@ void intel_init_pm(struct drm_device *dev) | |||
| 7767 | "Disable CxSR\n"); | 7711 | "Disable CxSR\n"); |
| 7768 | } | 7712 | } |
| 7769 | } else if (IS_CHERRYVIEW(dev_priv)) { | 7713 | } else if (IS_CHERRYVIEW(dev_priv)) { |
| 7770 | vlv_setup_wm_latency(dev); | 7714 | vlv_setup_wm_latency(dev_priv); |
| 7771 | dev_priv->display.update_wm = vlv_update_wm; | 7715 | dev_priv->display.update_wm = vlv_update_wm; |
| 7772 | } else if (IS_VALLEYVIEW(dev_priv)) { | 7716 | } else if (IS_VALLEYVIEW(dev_priv)) { |
| 7773 | vlv_setup_wm_latency(dev); | 7717 | vlv_setup_wm_latency(dev_priv); |
| 7774 | dev_priv->display.update_wm = vlv_update_wm; | 7718 | dev_priv->display.update_wm = vlv_update_wm; |
| 7775 | } else if (IS_PINEVIEW(dev)) { | 7719 | } else if (IS_PINEVIEW(dev_priv)) { |
| 7776 | if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev_priv), | 7720 | if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev_priv), |
| 7777 | dev_priv->is_ddr3, | 7721 | dev_priv->is_ddr3, |
| 7778 | dev_priv->fsb_freq, | 7722 | dev_priv->fsb_freq, |
| @@ -7795,7 +7739,7 @@ void intel_init_pm(struct drm_device *dev) | |||
| 7795 | dev_priv->display.update_wm = i9xx_update_wm; | 7739 | dev_priv->display.update_wm = i9xx_update_wm; |
| 7796 | dev_priv->display.get_fifo_size = i9xx_get_fifo_size; | 7740 | dev_priv->display.get_fifo_size = i9xx_get_fifo_size; |
| 7797 | } else if (IS_GEN2(dev_priv)) { | 7741 | } else if (IS_GEN2(dev_priv)) { |
| 7798 | if (INTEL_INFO(dev)->num_pipes == 1) { | 7742 | if (INTEL_INFO(dev_priv)->num_pipes == 1) { |
| 7799 | dev_priv->display.update_wm = i845_update_wm; | 7743 | dev_priv->display.update_wm = i845_update_wm; |
| 7800 | dev_priv->display.get_fifo_size = i845_get_fifo_size; | 7744 | dev_priv->display.get_fifo_size = i845_get_fifo_size; |
| 7801 | } else { | 7745 | } else { |
| @@ -8043,5 +7987,4 @@ void intel_pm_setup(struct drm_device *dev) | |||
| 8043 | 7987 | ||
| 8044 | dev_priv->pm.suspended = false; | 7988 | dev_priv->pm.suspended = false; |
| 8045 | atomic_set(&dev_priv->pm.wakeref_count, 0); | 7989 | atomic_set(&dev_priv->pm.wakeref_count, 0); |
| 8046 | atomic_set(&dev_priv->pm.atomic_seq, 0); | ||
| 8047 | } | 7990 | } |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 32786ba199b9..700e93d80616 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
| @@ -648,7 +648,7 @@ static int intel_rcs_ctx_init(struct drm_i915_gem_request *req) | |||
| 648 | if (ret != 0) | 648 | if (ret != 0) |
| 649 | return ret; | 649 | return ret; |
| 650 | 650 | ||
| 651 | ret = i915_gem_render_state_init(req); | 651 | ret = i915_gem_render_state_emit(req); |
| 652 | if (ret) | 652 | if (ret) |
| 653 | return ret; | 653 | return ret; |
| 654 | 654 | ||
| @@ -1213,90 +1213,62 @@ static void render_ring_cleanup(struct intel_engine_cs *engine) | |||
| 1213 | i915_vma_unpin_and_release(&dev_priv->semaphore); | 1213 | i915_vma_unpin_and_release(&dev_priv->semaphore); |
| 1214 | } | 1214 | } |
| 1215 | 1215 | ||
| 1216 | static int gen8_rcs_signal(struct drm_i915_gem_request *req) | 1216 | static u32 *gen8_rcs_signal(struct drm_i915_gem_request *req, u32 *out) |
| 1217 | { | 1217 | { |
| 1218 | struct intel_ring *ring = req->ring; | ||
| 1219 | struct drm_i915_private *dev_priv = req->i915; | 1218 | struct drm_i915_private *dev_priv = req->i915; |
| 1220 | struct intel_engine_cs *waiter; | 1219 | struct intel_engine_cs *waiter; |
| 1221 | enum intel_engine_id id; | 1220 | enum intel_engine_id id; |
| 1222 | int ret, num_rings; | ||
| 1223 | |||
| 1224 | num_rings = INTEL_INFO(dev_priv)->num_rings; | ||
| 1225 | ret = intel_ring_begin(req, (num_rings-1) * 8); | ||
| 1226 | if (ret) | ||
| 1227 | return ret; | ||
| 1228 | 1221 | ||
| 1229 | for_each_engine(waiter, dev_priv, id) { | 1222 | for_each_engine(waiter, dev_priv, id) { |
| 1230 | u64 gtt_offset = req->engine->semaphore.signal_ggtt[id]; | 1223 | u64 gtt_offset = req->engine->semaphore.signal_ggtt[id]; |
| 1231 | if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID) | 1224 | if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID) |
| 1232 | continue; | 1225 | continue; |
| 1233 | 1226 | ||
| 1234 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(6)); | 1227 | *out++ = GFX_OP_PIPE_CONTROL(6); |
| 1235 | intel_ring_emit(ring, | 1228 | *out++ = (PIPE_CONTROL_GLOBAL_GTT_IVB | |
| 1236 | PIPE_CONTROL_GLOBAL_GTT_IVB | | 1229 | PIPE_CONTROL_QW_WRITE | |
| 1237 | PIPE_CONTROL_QW_WRITE | | 1230 | PIPE_CONTROL_CS_STALL); |
| 1238 | PIPE_CONTROL_CS_STALL); | 1231 | *out++ = lower_32_bits(gtt_offset); |
| 1239 | intel_ring_emit(ring, lower_32_bits(gtt_offset)); | 1232 | *out++ = upper_32_bits(gtt_offset); |
| 1240 | intel_ring_emit(ring, upper_32_bits(gtt_offset)); | 1233 | *out++ = req->global_seqno; |
| 1241 | intel_ring_emit(ring, req->fence.seqno); | 1234 | *out++ = 0; |
| 1242 | intel_ring_emit(ring, 0); | 1235 | *out++ = (MI_SEMAPHORE_SIGNAL | |
| 1243 | intel_ring_emit(ring, | 1236 | MI_SEMAPHORE_TARGET(waiter->hw_id)); |
| 1244 | MI_SEMAPHORE_SIGNAL | | 1237 | *out++ = 0; |
| 1245 | MI_SEMAPHORE_TARGET(waiter->hw_id)); | ||
| 1246 | intel_ring_emit(ring, 0); | ||
| 1247 | } | 1238 | } |
| 1248 | intel_ring_advance(ring); | ||
| 1249 | 1239 | ||
| 1250 | return 0; | 1240 | return out; |
| 1251 | } | 1241 | } |
| 1252 | 1242 | ||
| 1253 | static int gen8_xcs_signal(struct drm_i915_gem_request *req) | 1243 | static u32 *gen8_xcs_signal(struct drm_i915_gem_request *req, u32 *out) |
| 1254 | { | 1244 | { |
| 1255 | struct intel_ring *ring = req->ring; | ||
| 1256 | struct drm_i915_private *dev_priv = req->i915; | 1245 | struct drm_i915_private *dev_priv = req->i915; |
| 1257 | struct intel_engine_cs *waiter; | 1246 | struct intel_engine_cs *waiter; |
| 1258 | enum intel_engine_id id; | 1247 | enum intel_engine_id id; |
| 1259 | int ret, num_rings; | ||
| 1260 | |||
| 1261 | num_rings = INTEL_INFO(dev_priv)->num_rings; | ||
| 1262 | ret = intel_ring_begin(req, (num_rings-1) * 6); | ||
| 1263 | if (ret) | ||
| 1264 | return ret; | ||
| 1265 | 1248 | ||
| 1266 | for_each_engine(waiter, dev_priv, id) { | 1249 | for_each_engine(waiter, dev_priv, id) { |
| 1267 | u64 gtt_offset = req->engine->semaphore.signal_ggtt[id]; | 1250 | u64 gtt_offset = req->engine->semaphore.signal_ggtt[id]; |
| 1268 | if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID) | 1251 | if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID) |
| 1269 | continue; | 1252 | continue; |
| 1270 | 1253 | ||
| 1271 | intel_ring_emit(ring, | 1254 | *out++ = (MI_FLUSH_DW + 1) | MI_FLUSH_DW_OP_STOREDW; |
| 1272 | (MI_FLUSH_DW + 1) | MI_FLUSH_DW_OP_STOREDW); | 1255 | *out++ = lower_32_bits(gtt_offset) | MI_FLUSH_DW_USE_GTT; |
| 1273 | intel_ring_emit(ring, | 1256 | *out++ = upper_32_bits(gtt_offset); |
| 1274 | lower_32_bits(gtt_offset) | | 1257 | *out++ = req->global_seqno; |
| 1275 | MI_FLUSH_DW_USE_GTT); | 1258 | *out++ = (MI_SEMAPHORE_SIGNAL | |
| 1276 | intel_ring_emit(ring, upper_32_bits(gtt_offset)); | 1259 | MI_SEMAPHORE_TARGET(waiter->hw_id)); |
| 1277 | intel_ring_emit(ring, req->fence.seqno); | 1260 | *out++ = 0; |
| 1278 | intel_ring_emit(ring, | ||
| 1279 | MI_SEMAPHORE_SIGNAL | | ||
| 1280 | MI_SEMAPHORE_TARGET(waiter->hw_id)); | ||
| 1281 | intel_ring_emit(ring, 0); | ||
| 1282 | } | 1261 | } |
| 1283 | intel_ring_advance(ring); | ||
| 1284 | 1262 | ||
| 1285 | return 0; | 1263 | return out; |
| 1286 | } | 1264 | } |
| 1287 | 1265 | ||
| 1288 | static int gen6_signal(struct drm_i915_gem_request *req) | 1266 | static u32 *gen6_signal(struct drm_i915_gem_request *req, u32 *out) |
| 1289 | { | 1267 | { |
| 1290 | struct intel_ring *ring = req->ring; | ||
| 1291 | struct drm_i915_private *dev_priv = req->i915; | 1268 | struct drm_i915_private *dev_priv = req->i915; |
| 1292 | struct intel_engine_cs *engine; | 1269 | struct intel_engine_cs *engine; |
| 1293 | enum intel_engine_id id; | 1270 | enum intel_engine_id id; |
| 1294 | int ret, num_rings; | 1271 | int num_rings = 0; |
| 1295 | |||
| 1296 | num_rings = INTEL_INFO(dev_priv)->num_rings; | ||
| 1297 | ret = intel_ring_begin(req, round_up((num_rings-1) * 3, 2)); | ||
| 1298 | if (ret) | ||
| 1299 | return ret; | ||
| 1300 | 1272 | ||
| 1301 | for_each_engine(engine, dev_priv, id) { | 1273 | for_each_engine(engine, dev_priv, id) { |
| 1302 | i915_reg_t mbox_reg; | 1274 | i915_reg_t mbox_reg; |
| @@ -1306,101 +1278,78 @@ static int gen6_signal(struct drm_i915_gem_request *req) | |||
| 1306 | 1278 | ||
| 1307 | mbox_reg = req->engine->semaphore.mbox.signal[engine->hw_id]; | 1279 | mbox_reg = req->engine->semaphore.mbox.signal[engine->hw_id]; |
| 1308 | if (i915_mmio_reg_valid(mbox_reg)) { | 1280 | if (i915_mmio_reg_valid(mbox_reg)) { |
| 1309 | intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); | 1281 | *out++ = MI_LOAD_REGISTER_IMM(1); |
| 1310 | intel_ring_emit_reg(ring, mbox_reg); | 1282 | *out++ = i915_mmio_reg_offset(mbox_reg); |
| 1311 | intel_ring_emit(ring, req->fence.seqno); | 1283 | *out++ = req->global_seqno; |
| 1284 | num_rings++; | ||
| 1312 | } | 1285 | } |
| 1313 | } | 1286 | } |
| 1287 | if (num_rings & 1) | ||
| 1288 | *out++ = MI_NOOP; | ||
| 1314 | 1289 | ||
| 1315 | /* If num_dwords was rounded, make sure the tail pointer is correct */ | 1290 | return out; |
| 1316 | if (num_rings % 2 == 0) | ||
| 1317 | intel_ring_emit(ring, MI_NOOP); | ||
| 1318 | intel_ring_advance(ring); | ||
| 1319 | |||
| 1320 | return 0; | ||
| 1321 | } | 1291 | } |
| 1322 | 1292 | ||
| 1323 | static void i9xx_submit_request(struct drm_i915_gem_request *request) | 1293 | static void i9xx_submit_request(struct drm_i915_gem_request *request) |
| 1324 | { | 1294 | { |
| 1325 | struct drm_i915_private *dev_priv = request->i915; | 1295 | struct drm_i915_private *dev_priv = request->i915; |
| 1326 | 1296 | ||
| 1327 | I915_WRITE_TAIL(request->engine, | 1297 | I915_WRITE_TAIL(request->engine, request->tail); |
| 1328 | intel_ring_offset(request->ring, request->tail)); | ||
| 1329 | } | 1298 | } |
| 1330 | 1299 | ||
| 1331 | static int i9xx_emit_request(struct drm_i915_gem_request *req) | 1300 | static void i9xx_emit_breadcrumb(struct drm_i915_gem_request *req, |
| 1301 | u32 *out) | ||
| 1332 | { | 1302 | { |
| 1333 | struct intel_ring *ring = req->ring; | 1303 | *out++ = MI_STORE_DWORD_INDEX; |
| 1334 | int ret; | 1304 | *out++ = I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT; |
| 1305 | *out++ = req->global_seqno; | ||
| 1306 | *out++ = MI_USER_INTERRUPT; | ||
| 1335 | 1307 | ||
| 1336 | ret = intel_ring_begin(req, 4); | 1308 | req->tail = intel_ring_offset(req->ring, out); |
| 1337 | if (ret) | ||
| 1338 | return ret; | ||
| 1339 | |||
| 1340 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); | ||
| 1341 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | ||
| 1342 | intel_ring_emit(ring, req->fence.seqno); | ||
| 1343 | intel_ring_emit(ring, MI_USER_INTERRUPT); | ||
| 1344 | intel_ring_advance(ring); | ||
| 1345 | |||
| 1346 | req->tail = ring->tail; | ||
| 1347 | |||
| 1348 | return 0; | ||
| 1349 | } | 1309 | } |
| 1350 | 1310 | ||
| 1311 | static const int i9xx_emit_breadcrumb_sz = 4; | ||
| 1312 | |||
| 1351 | /** | 1313 | /** |
| 1352 | * gen6_sema_emit_request - Update the semaphore mailbox registers | 1314 | * gen6_sema_emit_breadcrumb - Update the semaphore mailbox registers |
| 1353 | * | 1315 | * |
| 1354 | * @request - request to write to the ring | 1316 | * @request - request to write to the ring |
| 1355 | * | 1317 | * |
| 1356 | * Update the mailbox registers in the *other* rings with the current seqno. | 1318 | * Update the mailbox registers in the *other* rings with the current seqno. |
| 1357 | * This acts like a signal in the canonical semaphore. | 1319 | * This acts like a signal in the canonical semaphore. |
| 1358 | */ | 1320 | */ |
| 1359 | static int gen6_sema_emit_request(struct drm_i915_gem_request *req) | 1321 | static void gen6_sema_emit_breadcrumb(struct drm_i915_gem_request *req, |
| 1322 | u32 *out) | ||
| 1360 | { | 1323 | { |
| 1361 | int ret; | 1324 | return i9xx_emit_breadcrumb(req, |
| 1362 | 1325 | req->engine->semaphore.signal(req, out)); | |
| 1363 | ret = req->engine->semaphore.signal(req); | ||
| 1364 | if (ret) | ||
| 1365 | return ret; | ||
| 1366 | |||
| 1367 | return i9xx_emit_request(req); | ||
| 1368 | } | 1326 | } |
| 1369 | 1327 | ||
| 1370 | static int gen8_render_emit_request(struct drm_i915_gem_request *req) | 1328 | static void gen8_render_emit_breadcrumb(struct drm_i915_gem_request *req, |
| 1329 | u32 *out) | ||
| 1371 | { | 1330 | { |
| 1372 | struct intel_engine_cs *engine = req->engine; | 1331 | struct intel_engine_cs *engine = req->engine; |
| 1373 | struct intel_ring *ring = req->ring; | ||
| 1374 | int ret; | ||
| 1375 | 1332 | ||
| 1376 | if (engine->semaphore.signal) { | 1333 | if (engine->semaphore.signal) |
| 1377 | ret = engine->semaphore.signal(req); | 1334 | out = engine->semaphore.signal(req, out); |
| 1378 | if (ret) | ||
| 1379 | return ret; | ||
| 1380 | } | ||
| 1381 | 1335 | ||
| 1382 | ret = intel_ring_begin(req, 8); | 1336 | *out++ = GFX_OP_PIPE_CONTROL(6); |
| 1383 | if (ret) | 1337 | *out++ = (PIPE_CONTROL_GLOBAL_GTT_IVB | |
| 1384 | return ret; | ||
| 1385 | |||
| 1386 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(6)); | ||
| 1387 | intel_ring_emit(ring, (PIPE_CONTROL_GLOBAL_GTT_IVB | | ||
| 1388 | PIPE_CONTROL_CS_STALL | | 1338 | PIPE_CONTROL_CS_STALL | |
| 1389 | PIPE_CONTROL_QW_WRITE)); | 1339 | PIPE_CONTROL_QW_WRITE); |
| 1390 | intel_ring_emit(ring, intel_hws_seqno_address(engine)); | 1340 | *out++ = intel_hws_seqno_address(engine); |
| 1391 | intel_ring_emit(ring, 0); | 1341 | *out++ = 0; |
| 1392 | intel_ring_emit(ring, i915_gem_request_get_seqno(req)); | 1342 | *out++ = req->global_seqno; |
| 1393 | /* We're thrashing one dword of HWS. */ | 1343 | /* We're thrashing one dword of HWS. */ |
| 1394 | intel_ring_emit(ring, 0); | 1344 | *out++ = 0; |
| 1395 | intel_ring_emit(ring, MI_USER_INTERRUPT); | 1345 | *out++ = MI_USER_INTERRUPT; |
| 1396 | intel_ring_emit(ring, MI_NOOP); | 1346 | *out++ = MI_NOOP; |
| 1397 | intel_ring_advance(ring); | ||
| 1398 | 1347 | ||
| 1399 | req->tail = ring->tail; | 1348 | req->tail = intel_ring_offset(req->ring, out); |
| 1400 | |||
| 1401 | return 0; | ||
| 1402 | } | 1349 | } |
| 1403 | 1350 | ||
| 1351 | static const int gen8_render_emit_breadcrumb_sz = 8; | ||
| 1352 | |||
| 1404 | /** | 1353 | /** |
| 1405 | * intel_ring_sync - sync the waiter to the signaller on seqno | 1354 | * intel_ring_sync - sync the waiter to the signaller on seqno |
| 1406 | * | 1355 | * |
| @@ -1427,7 +1376,7 @@ gen8_ring_sync_to(struct drm_i915_gem_request *req, | |||
| 1427 | MI_SEMAPHORE_WAIT | | 1376 | MI_SEMAPHORE_WAIT | |
| 1428 | MI_SEMAPHORE_GLOBAL_GTT | | 1377 | MI_SEMAPHORE_GLOBAL_GTT | |
| 1429 | MI_SEMAPHORE_SAD_GTE_SDD); | 1378 | MI_SEMAPHORE_SAD_GTE_SDD); |
| 1430 | intel_ring_emit(ring, signal->fence.seqno); | 1379 | intel_ring_emit(ring, signal->global_seqno); |
| 1431 | intel_ring_emit(ring, lower_32_bits(offset)); | 1380 | intel_ring_emit(ring, lower_32_bits(offset)); |
| 1432 | intel_ring_emit(ring, upper_32_bits(offset)); | 1381 | intel_ring_emit(ring, upper_32_bits(offset)); |
| 1433 | intel_ring_advance(ring); | 1382 | intel_ring_advance(ring); |
| @@ -1465,7 +1414,7 @@ gen6_ring_sync_to(struct drm_i915_gem_request *req, | |||
| 1465 | * seqno is >= the last seqno executed. However for hardware the | 1414 | * seqno is >= the last seqno executed. However for hardware the |
| 1466 | * comparison is strictly greater than. | 1415 | * comparison is strictly greater than. |
| 1467 | */ | 1416 | */ |
| 1468 | intel_ring_emit(ring, signal->fence.seqno - 1); | 1417 | intel_ring_emit(ring, signal->global_seqno - 1); |
| 1469 | intel_ring_emit(ring, 0); | 1418 | intel_ring_emit(ring, 0); |
| 1470 | intel_ring_emit(ring, MI_NOOP); | 1419 | intel_ring_emit(ring, MI_NOOP); |
| 1471 | intel_ring_advance(ring); | 1420 | intel_ring_advance(ring); |
| @@ -1608,7 +1557,7 @@ hsw_vebox_irq_enable(struct intel_engine_cs *engine) | |||
| 1608 | struct drm_i915_private *dev_priv = engine->i915; | 1557 | struct drm_i915_private *dev_priv = engine->i915; |
| 1609 | 1558 | ||
| 1610 | I915_WRITE_IMR(engine, ~engine->irq_enable_mask); | 1559 | I915_WRITE_IMR(engine, ~engine->irq_enable_mask); |
| 1611 | gen6_enable_pm_irq(dev_priv, engine->irq_enable_mask); | 1560 | gen6_unmask_pm_irq(dev_priv, engine->irq_enable_mask); |
| 1612 | } | 1561 | } |
| 1613 | 1562 | ||
| 1614 | static void | 1563 | static void |
| @@ -1617,7 +1566,7 @@ hsw_vebox_irq_disable(struct intel_engine_cs *engine) | |||
| 1617 | struct drm_i915_private *dev_priv = engine->i915; | 1566 | struct drm_i915_private *dev_priv = engine->i915; |
| 1618 | 1567 | ||
| 1619 | I915_WRITE_IMR(engine, ~0); | 1568 | I915_WRITE_IMR(engine, ~0); |
| 1620 | gen6_disable_pm_irq(dev_priv, engine->irq_enable_mask); | 1569 | gen6_mask_pm_irq(dev_priv, engine->irq_enable_mask); |
| 1621 | } | 1570 | } |
| 1622 | 1571 | ||
| 1623 | static void | 1572 | static void |
| @@ -1762,14 +1711,19 @@ static void cleanup_phys_status_page(struct intel_engine_cs *engine) | |||
| 1762 | static void cleanup_status_page(struct intel_engine_cs *engine) | 1711 | static void cleanup_status_page(struct intel_engine_cs *engine) |
| 1763 | { | 1712 | { |
| 1764 | struct i915_vma *vma; | 1713 | struct i915_vma *vma; |
| 1714 | struct drm_i915_gem_object *obj; | ||
| 1765 | 1715 | ||
| 1766 | vma = fetch_and_zero(&engine->status_page.vma); | 1716 | vma = fetch_and_zero(&engine->status_page.vma); |
| 1767 | if (!vma) | 1717 | if (!vma) |
| 1768 | return; | 1718 | return; |
| 1769 | 1719 | ||
| 1720 | obj = vma->obj; | ||
| 1721 | |||
| 1770 | i915_vma_unpin(vma); | 1722 | i915_vma_unpin(vma); |
| 1771 | i915_gem_object_unpin_map(vma->obj); | 1723 | i915_vma_close(vma); |
| 1772 | i915_vma_put(vma); | 1724 | |
| 1725 | i915_gem_object_unpin_map(obj); | ||
| 1726 | __i915_gem_object_release_unless_active(obj); | ||
| 1773 | } | 1727 | } |
| 1774 | 1728 | ||
| 1775 | static int init_status_page(struct intel_engine_cs *engine) | 1729 | static int init_status_page(struct intel_engine_cs *engine) |
| @@ -1777,9 +1731,10 @@ static int init_status_page(struct intel_engine_cs *engine) | |||
| 1777 | struct drm_i915_gem_object *obj; | 1731 | struct drm_i915_gem_object *obj; |
| 1778 | struct i915_vma *vma; | 1732 | struct i915_vma *vma; |
| 1779 | unsigned int flags; | 1733 | unsigned int flags; |
| 1734 | void *vaddr; | ||
| 1780 | int ret; | 1735 | int ret; |
| 1781 | 1736 | ||
| 1782 | obj = i915_gem_object_create(&engine->i915->drm, 4096); | 1737 | obj = i915_gem_object_create_internal(engine->i915, 4096); |
| 1783 | if (IS_ERR(obj)) { | 1738 | if (IS_ERR(obj)) { |
| 1784 | DRM_ERROR("Failed to allocate status page\n"); | 1739 | DRM_ERROR("Failed to allocate status page\n"); |
| 1785 | return PTR_ERR(obj); | 1740 | return PTR_ERR(obj); |
| @@ -1812,15 +1767,22 @@ static int init_status_page(struct intel_engine_cs *engine) | |||
| 1812 | if (ret) | 1767 | if (ret) |
| 1813 | goto err; | 1768 | goto err; |
| 1814 | 1769 | ||
| 1770 | vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); | ||
| 1771 | if (IS_ERR(vaddr)) { | ||
| 1772 | ret = PTR_ERR(vaddr); | ||
| 1773 | goto err_unpin; | ||
| 1774 | } | ||
| 1775 | |||
| 1815 | engine->status_page.vma = vma; | 1776 | engine->status_page.vma = vma; |
| 1816 | engine->status_page.ggtt_offset = i915_ggtt_offset(vma); | 1777 | engine->status_page.ggtt_offset = i915_ggtt_offset(vma); |
| 1817 | engine->status_page.page_addr = | 1778 | engine->status_page.page_addr = memset(vaddr, 0, 4096); |
| 1818 | i915_gem_object_pin_map(obj, I915_MAP_WB); | ||
| 1819 | 1779 | ||
| 1820 | DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n", | 1780 | DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n", |
| 1821 | engine->name, i915_ggtt_offset(vma)); | 1781 | engine->name, i915_ggtt_offset(vma)); |
| 1822 | return 0; | 1782 | return 0; |
| 1823 | 1783 | ||
| 1784 | err_unpin: | ||
| 1785 | i915_vma_unpin(vma); | ||
| 1824 | err: | 1786 | err: |
| 1825 | i915_gem_object_put(obj); | 1787 | i915_gem_object_put(obj); |
| 1826 | return ret; | 1788 | return ret; |
| @@ -1967,7 +1929,11 @@ intel_engine_create_ring(struct intel_engine_cs *engine, int size) | |||
| 1967 | void | 1929 | void |
| 1968 | intel_ring_free(struct intel_ring *ring) | 1930 | intel_ring_free(struct intel_ring *ring) |
| 1969 | { | 1931 | { |
| 1970 | i915_vma_put(ring->vma); | 1932 | struct drm_i915_gem_object *obj = ring->vma->obj; |
| 1933 | |||
| 1934 | i915_vma_close(ring->vma); | ||
| 1935 | __i915_gem_object_release_unless_active(obj); | ||
| 1936 | |||
| 1971 | kfree(ring); | 1937 | kfree(ring); |
| 1972 | } | 1938 | } |
| 1973 | 1939 | ||
| @@ -1983,14 +1949,13 @@ static int intel_ring_context_pin(struct i915_gem_context *ctx, | |||
| 1983 | return 0; | 1949 | return 0; |
| 1984 | 1950 | ||
| 1985 | if (ce->state) { | 1951 | if (ce->state) { |
| 1986 | ret = i915_gem_object_set_to_gtt_domain(ce->state->obj, false); | 1952 | struct i915_vma *vma; |
| 1987 | if (ret) | ||
| 1988 | goto error; | ||
| 1989 | 1953 | ||
| 1990 | ret = i915_vma_pin(ce->state, 0, ctx->ggtt_alignment, | 1954 | vma = i915_gem_context_pin_legacy(ctx, PIN_HIGH); |
| 1991 | PIN_GLOBAL | PIN_HIGH); | 1955 | if (IS_ERR(vma)) { |
| 1992 | if (ret) | 1956 | ret = PTR_ERR(vma); |
| 1993 | goto error; | 1957 | goto error; |
| 1958 | } | ||
| 1994 | } | 1959 | } |
| 1995 | 1960 | ||
| 1996 | /* The kernel context is only used as a placeholder for flushing the | 1961 | /* The kernel context is only used as a placeholder for flushing the |
| @@ -2037,9 +2002,6 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine) | |||
| 2037 | 2002 | ||
| 2038 | intel_engine_setup_common(engine); | 2003 | intel_engine_setup_common(engine); |
| 2039 | 2004 | ||
| 2040 | memset(engine->semaphore.sync_seqno, 0, | ||
| 2041 | sizeof(engine->semaphore.sync_seqno)); | ||
| 2042 | |||
| 2043 | ret = intel_engine_init_common(engine); | 2005 | ret = intel_engine_init_common(engine); |
| 2044 | if (ret) | 2006 | if (ret) |
| 2045 | goto error; | 2007 | goto error; |
| @@ -2155,7 +2117,9 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes) | |||
| 2155 | { | 2117 | { |
| 2156 | struct intel_ring *ring = req->ring; | 2118 | struct intel_ring *ring = req->ring; |
| 2157 | struct drm_i915_gem_request *target; | 2119 | struct drm_i915_gem_request *target; |
| 2158 | int ret; | 2120 | long timeout; |
| 2121 | |||
| 2122 | lockdep_assert_held(&req->i915->drm.struct_mutex); | ||
| 2159 | 2123 | ||
| 2160 | intel_ring_update_space(ring); | 2124 | intel_ring_update_space(ring); |
| 2161 | if (ring->space >= bytes) | 2125 | if (ring->space >= bytes) |
| @@ -2185,11 +2149,11 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes) | |||
| 2185 | if (WARN_ON(&target->ring_link == &ring->request_list)) | 2149 | if (WARN_ON(&target->ring_link == &ring->request_list)) |
| 2186 | return -ENOSPC; | 2150 | return -ENOSPC; |
| 2187 | 2151 | ||
| 2188 | ret = i915_wait_request(target, | 2152 | timeout = i915_wait_request(target, |
| 2189 | I915_WAIT_INTERRUPTIBLE | I915_WAIT_LOCKED, | 2153 | I915_WAIT_INTERRUPTIBLE | I915_WAIT_LOCKED, |
| 2190 | NULL, NO_WAITBOOST); | 2154 | MAX_SCHEDULE_TIMEOUT); |
| 2191 | if (ret) | 2155 | if (timeout < 0) |
| 2192 | return ret; | 2156 | return timeout; |
| 2193 | 2157 | ||
| 2194 | i915_gem_request_retire_upto(target); | 2158 | i915_gem_request_retire_upto(target); |
| 2195 | 2159 | ||
| @@ -2618,9 +2582,22 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, | |||
| 2618 | engine->init_hw = init_ring_common; | 2582 | engine->init_hw = init_ring_common; |
| 2619 | engine->reset_hw = reset_ring_common; | 2583 | engine->reset_hw = reset_ring_common; |
| 2620 | 2584 | ||
| 2621 | engine->emit_request = i9xx_emit_request; | 2585 | engine->emit_breadcrumb = i9xx_emit_breadcrumb; |
| 2622 | if (i915.semaphores) | 2586 | engine->emit_breadcrumb_sz = i9xx_emit_breadcrumb_sz; |
| 2623 | engine->emit_request = gen6_sema_emit_request; | 2587 | if (i915.semaphores) { |
| 2588 | int num_rings; | ||
| 2589 | |||
| 2590 | engine->emit_breadcrumb = gen6_sema_emit_breadcrumb; | ||
| 2591 | |||
| 2592 | num_rings = hweight32(INTEL_INFO(dev_priv)->ring_mask) - 1; | ||
| 2593 | if (INTEL_GEN(dev_priv) >= 8) { | ||
| 2594 | engine->emit_breadcrumb_sz += num_rings * 6; | ||
| 2595 | } else { | ||
| 2596 | engine->emit_breadcrumb_sz += num_rings * 3; | ||
| 2597 | if (num_rings & 1) | ||
| 2598 | engine->emit_breadcrumb_sz++; | ||
| 2599 | } | ||
| 2600 | } | ||
| 2624 | engine->submit_request = i9xx_submit_request; | 2601 | engine->submit_request = i9xx_submit_request; |
| 2625 | 2602 | ||
| 2626 | if (INTEL_GEN(dev_priv) >= 8) | 2603 | if (INTEL_GEN(dev_priv) >= 8) |
| @@ -2647,10 +2624,18 @@ int intel_init_render_ring_buffer(struct intel_engine_cs *engine) | |||
| 2647 | 2624 | ||
| 2648 | if (INTEL_GEN(dev_priv) >= 8) { | 2625 | if (INTEL_GEN(dev_priv) >= 8) { |
| 2649 | engine->init_context = intel_rcs_ctx_init; | 2626 | engine->init_context = intel_rcs_ctx_init; |
| 2650 | engine->emit_request = gen8_render_emit_request; | 2627 | engine->emit_breadcrumb = gen8_render_emit_breadcrumb; |
| 2628 | engine->emit_breadcrumb_sz = gen8_render_emit_breadcrumb_sz; | ||
| 2651 | engine->emit_flush = gen8_render_ring_flush; | 2629 | engine->emit_flush = gen8_render_ring_flush; |
| 2652 | if (i915.semaphores) | 2630 | if (i915.semaphores) { |
| 2631 | int num_rings; | ||
| 2632 | |||
| 2653 | engine->semaphore.signal = gen8_rcs_signal; | 2633 | engine->semaphore.signal = gen8_rcs_signal; |
| 2634 | |||
| 2635 | num_rings = | ||
| 2636 | hweight32(INTEL_INFO(dev_priv)->ring_mask) - 1; | ||
| 2637 | engine->emit_breadcrumb_sz += num_rings * 6; | ||
| 2638 | } | ||
| 2654 | } else if (INTEL_GEN(dev_priv) >= 6) { | 2639 | } else if (INTEL_GEN(dev_priv) >= 6) { |
| 2655 | engine->init_context = intel_rcs_ctx_init; | 2640 | engine->init_context = intel_rcs_ctx_init; |
| 2656 | engine->emit_flush = gen7_render_ring_flush; | 2641 | engine->emit_flush = gen7_render_ring_flush; |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 32b2e6332ccf..642b54692d0d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include <linux/hashtable.h> | 4 | #include <linux/hashtable.h> |
| 5 | #include "i915_gem_batch_pool.h" | 5 | #include "i915_gem_batch_pool.h" |
| 6 | #include "i915_gem_request.h" | 6 | #include "i915_gem_request.h" |
| 7 | #include "i915_gem_timeline.h" | ||
| 7 | 8 | ||
| 8 | #define I915_CMD_HASH_ORDER 9 | 9 | #define I915_CMD_HASH_ORDER 9 |
| 9 | 10 | ||
| @@ -157,6 +158,7 @@ struct i915_ctx_workarounds { | |||
| 157 | }; | 158 | }; |
| 158 | 159 | ||
| 159 | struct drm_i915_gem_request; | 160 | struct drm_i915_gem_request; |
| 161 | struct intel_render_state; | ||
| 160 | 162 | ||
| 161 | struct intel_engine_cs { | 163 | struct intel_engine_cs { |
| 162 | struct drm_i915_private *i915; | 164 | struct drm_i915_private *i915; |
| @@ -168,7 +170,6 @@ struct intel_engine_cs { | |||
| 168 | VCS2, /* Keep instances of the same type engine together. */ | 170 | VCS2, /* Keep instances of the same type engine together. */ |
| 169 | VECS | 171 | VECS |
| 170 | } id; | 172 | } id; |
| 171 | #define I915_NUM_ENGINES 5 | ||
| 172 | #define _VCS(n) (VCS + (n)) | 173 | #define _VCS(n) (VCS + (n)) |
| 173 | unsigned int exec_id; | 174 | unsigned int exec_id; |
| 174 | enum intel_engine_hw_id { | 175 | enum intel_engine_hw_id { |
| @@ -179,10 +180,12 @@ struct intel_engine_cs { | |||
| 179 | VCS2_HW | 180 | VCS2_HW |
| 180 | } hw_id; | 181 | } hw_id; |
| 181 | enum intel_engine_hw_id guc_id; /* XXX same as hw_id? */ | 182 | enum intel_engine_hw_id guc_id; /* XXX same as hw_id? */ |
| 182 | u64 fence_context; | ||
| 183 | u32 mmio_base; | 183 | u32 mmio_base; |
| 184 | unsigned int irq_shift; | 184 | unsigned int irq_shift; |
| 185 | struct intel_ring *buffer; | 185 | struct intel_ring *buffer; |
| 186 | struct intel_timeline *timeline; | ||
| 187 | |||
| 188 | struct intel_render_state *render_state; | ||
| 186 | 189 | ||
| 187 | /* Rather than have every client wait upon all user interrupts, | 190 | /* Rather than have every client wait upon all user interrupts, |
| 188 | * with the herd waking after every interrupt and each doing the | 191 | * with the herd waking after every interrupt and each doing the |
| @@ -204,7 +207,7 @@ struct intel_engine_cs { | |||
| 204 | struct task_struct __rcu *irq_seqno_bh; /* bh for interrupts */ | 207 | struct task_struct __rcu *irq_seqno_bh; /* bh for interrupts */ |
| 205 | bool irq_posted; | 208 | bool irq_posted; |
| 206 | 209 | ||
| 207 | spinlock_t lock; /* protects the lists of requests */ | 210 | spinlock_t lock; /* protects the lists of requests; irqsafe */ |
| 208 | struct rb_root waiters; /* sorted by retirement, priority */ | 211 | struct rb_root waiters; /* sorted by retirement, priority */ |
| 209 | struct rb_root signals; /* sorted by retirement */ | 212 | struct rb_root signals; /* sorted by retirement */ |
| 210 | struct intel_wait *first_wait; /* oldest waiter by retirement */ | 213 | struct intel_wait *first_wait; /* oldest waiter by retirement */ |
| @@ -252,7 +255,9 @@ struct intel_engine_cs { | |||
| 252 | #define I915_DISPATCH_SECURE BIT(0) | 255 | #define I915_DISPATCH_SECURE BIT(0) |
| 253 | #define I915_DISPATCH_PINNED BIT(1) | 256 | #define I915_DISPATCH_PINNED BIT(1) |
| 254 | #define I915_DISPATCH_RS BIT(2) | 257 | #define I915_DISPATCH_RS BIT(2) |
| 255 | int (*emit_request)(struct drm_i915_gem_request *req); | 258 | void (*emit_breadcrumb)(struct drm_i915_gem_request *req, |
| 259 | u32 *out); | ||
| 260 | int emit_breadcrumb_sz; | ||
| 256 | 261 | ||
| 257 | /* Pass the request to the hardware queue (e.g. directly into | 262 | /* Pass the request to the hardware queue (e.g. directly into |
| 258 | * the legacy ringbuffer or to the end of an execlist). | 263 | * the legacy ringbuffer or to the end of an execlist). |
| @@ -309,8 +314,6 @@ struct intel_engine_cs { | |||
| 309 | * ie. transpose of f(x, y) | 314 | * ie. transpose of f(x, y) |
| 310 | */ | 315 | */ |
| 311 | struct { | 316 | struct { |
| 312 | u32 sync_seqno[I915_NUM_ENGINES-1]; | ||
| 313 | |||
| 314 | union { | 317 | union { |
| 315 | #define GEN6_SEMAPHORE_LAST VECS_HW | 318 | #define GEN6_SEMAPHORE_LAST VECS_HW |
| 316 | #define GEN6_NUM_SEMAPHORES (GEN6_SEMAPHORE_LAST + 1) | 319 | #define GEN6_NUM_SEMAPHORES (GEN6_SEMAPHORE_LAST + 1) |
| @@ -327,7 +330,7 @@ struct intel_engine_cs { | |||
| 327 | /* AKA wait() */ | 330 | /* AKA wait() */ |
| 328 | int (*sync_to)(struct drm_i915_gem_request *req, | 331 | int (*sync_to)(struct drm_i915_gem_request *req, |
| 329 | struct drm_i915_gem_request *signal); | 332 | struct drm_i915_gem_request *signal); |
| 330 | int (*signal)(struct drm_i915_gem_request *req); | 333 | u32 *(*signal)(struct drm_i915_gem_request *req, u32 *out); |
| 331 | } semaphore; | 334 | } semaphore; |
| 332 | 335 | ||
| 333 | /* Execlists */ | 336 | /* Execlists */ |
| @@ -343,27 +346,6 @@ struct intel_engine_cs { | |||
| 343 | bool preempt_wa; | 346 | bool preempt_wa; |
| 344 | u32 ctx_desc_template; | 347 | u32 ctx_desc_template; |
| 345 | 348 | ||
| 346 | /** | ||
| 347 | * List of breadcrumbs associated with GPU requests currently | ||
| 348 | * outstanding. | ||
| 349 | */ | ||
| 350 | struct list_head request_list; | ||
| 351 | |||
| 352 | /** | ||
| 353 | * Seqno of request most recently submitted to request_list. | ||
| 354 | * Used exclusively by hang checker to avoid grabbing lock while | ||
| 355 | * inspecting request list. | ||
| 356 | */ | ||
| 357 | u32 last_submitted_seqno; | ||
| 358 | u32 last_pending_seqno; | ||
| 359 | |||
| 360 | /* An RCU guarded pointer to the last request. No reference is | ||
| 361 | * held to the request, users must carefully acquire a reference to | ||
| 362 | * the request using i915_gem_active_get_rcu(), or hold the | ||
| 363 | * struct_mutex. | ||
| 364 | */ | ||
| 365 | struct i915_gem_active last_request; | ||
| 366 | |||
| 367 | struct i915_gem_context *last_context; | 349 | struct i915_gem_context *last_context; |
| 368 | 350 | ||
| 369 | struct intel_engine_hangcheck hangcheck; | 351 | struct intel_engine_hangcheck hangcheck; |
| @@ -401,27 +383,6 @@ intel_engine_flag(const struct intel_engine_cs *engine) | |||
| 401 | return 1 << engine->id; | 383 | return 1 << engine->id; |
| 402 | } | 384 | } |
| 403 | 385 | ||
| 404 | static inline u32 | ||
| 405 | intel_engine_sync_index(struct intel_engine_cs *engine, | ||
| 406 | struct intel_engine_cs *other) | ||
| 407 | { | ||
| 408 | int idx; | ||
| 409 | |||
| 410 | /* | ||
| 411 | * rcs -> 0 = vcs, 1 = bcs, 2 = vecs, 3 = vcs2; | ||
| 412 | * vcs -> 0 = bcs, 1 = vecs, 2 = vcs2, 3 = rcs; | ||
| 413 | * bcs -> 0 = vecs, 1 = vcs2. 2 = rcs, 3 = vcs; | ||
| 414 | * vecs -> 0 = vcs2, 1 = rcs, 2 = vcs, 3 = bcs; | ||
| 415 | * vcs2 -> 0 = rcs, 1 = vcs, 2 = bcs, 3 = vecs; | ||
| 416 | */ | ||
| 417 | |||
| 418 | idx = (other->id - engine->id) - 1; | ||
| 419 | if (idx < 0) | ||
| 420 | idx += I915_NUM_ENGINES; | ||
| 421 | |||
| 422 | return idx; | ||
| 423 | } | ||
| 424 | |||
| 425 | static inline void | 386 | static inline void |
| 426 | intel_flush_status_page(struct intel_engine_cs *engine, int reg) | 387 | intel_flush_status_page(struct intel_engine_cs *engine, int reg) |
| 427 | { | 388 | { |
| @@ -504,30 +465,23 @@ static inline void intel_ring_advance(struct intel_ring *ring) | |||
| 504 | */ | 465 | */ |
| 505 | } | 466 | } |
| 506 | 467 | ||
| 507 | static inline u32 intel_ring_offset(struct intel_ring *ring, u32 value) | 468 | static inline u32 intel_ring_offset(struct intel_ring *ring, void *addr) |
| 508 | { | 469 | { |
| 509 | /* Don't write ring->size (equivalent to 0) as that hangs some GPUs. */ | 470 | /* Don't write ring->size (equivalent to 0) as that hangs some GPUs. */ |
| 510 | return value & (ring->size - 1); | 471 | u32 offset = addr - ring->vaddr; |
| 472 | return offset & (ring->size - 1); | ||
| 511 | } | 473 | } |
| 512 | 474 | ||
| 513 | int __intel_ring_space(int head, int tail, int size); | 475 | int __intel_ring_space(int head, int tail, int size); |
| 514 | void intel_ring_update_space(struct intel_ring *ring); | 476 | void intel_ring_update_space(struct intel_ring *ring); |
| 515 | 477 | ||
| 516 | void intel_engine_init_seqno(struct intel_engine_cs *engine, u32 seqno); | 478 | void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno); |
| 517 | 479 | ||
| 518 | void intel_engine_setup_common(struct intel_engine_cs *engine); | 480 | void intel_engine_setup_common(struct intel_engine_cs *engine); |
| 519 | int intel_engine_init_common(struct intel_engine_cs *engine); | 481 | int intel_engine_init_common(struct intel_engine_cs *engine); |
| 520 | int intel_engine_create_scratch(struct intel_engine_cs *engine, int size); | 482 | int intel_engine_create_scratch(struct intel_engine_cs *engine, int size); |
| 521 | void intel_engine_cleanup_common(struct intel_engine_cs *engine); | 483 | void intel_engine_cleanup_common(struct intel_engine_cs *engine); |
| 522 | 484 | ||
| 523 | static inline int intel_engine_idle(struct intel_engine_cs *engine, | ||
| 524 | unsigned int flags) | ||
| 525 | { | ||
| 526 | /* Wait upon the last request to be completed */ | ||
| 527 | return i915_gem_active_wait_unlocked(&engine->last_request, | ||
| 528 | flags, NULL, NULL); | ||
| 529 | } | ||
| 530 | |||
| 531 | int intel_init_render_ring_buffer(struct intel_engine_cs *engine); | 485 | int intel_init_render_ring_buffer(struct intel_engine_cs *engine); |
| 532 | int intel_init_bsd_ring_buffer(struct intel_engine_cs *engine); | 486 | int intel_init_bsd_ring_buffer(struct intel_engine_cs *engine); |
| 533 | int intel_init_bsd2_ring_buffer(struct intel_engine_cs *engine); | 487 | int intel_init_bsd2_ring_buffer(struct intel_engine_cs *engine); |
| @@ -542,6 +496,18 @@ static inline u32 intel_engine_get_seqno(struct intel_engine_cs *engine) | |||
| 542 | return intel_read_status_page(engine, I915_GEM_HWS_INDEX); | 496 | return intel_read_status_page(engine, I915_GEM_HWS_INDEX); |
| 543 | } | 497 | } |
| 544 | 498 | ||
| 499 | static inline u32 intel_engine_last_submit(struct intel_engine_cs *engine) | ||
| 500 | { | ||
| 501 | /* We are only peeking at the tail of the submit queue (and not the | ||
| 502 | * queue itself) in order to gain a hint as to the current active | ||
| 503 | * state of the engine. Callers are not expected to be taking | ||
| 504 | * engine->timeline->lock, nor are they expected to be concerned | ||
| 505 | * wtih serialising this hint with anything, so document it as | ||
| 506 | * a hint and nothing more. | ||
| 507 | */ | ||
| 508 | return READ_ONCE(engine->timeline->last_submitted_seqno); | ||
| 509 | } | ||
| 510 | |||
| 545 | int init_workarounds_ring(struct intel_engine_cs *engine); | 511 | int init_workarounds_ring(struct intel_engine_cs *engine); |
| 546 | 512 | ||
| 547 | void intel_engine_get_instdone(struct intel_engine_cs *engine, | 513 | void intel_engine_get_instdone(struct intel_engine_cs *engine, |
| @@ -615,9 +581,4 @@ void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine); | |||
| 615 | unsigned int intel_kick_waiters(struct drm_i915_private *i915); | 581 | unsigned int intel_kick_waiters(struct drm_i915_private *i915); |
| 616 | unsigned int intel_kick_signalers(struct drm_i915_private *i915); | 582 | unsigned int intel_kick_signalers(struct drm_i915_private *i915); |
| 617 | 583 | ||
| 618 | static inline bool intel_engine_is_active(struct intel_engine_cs *engine) | ||
| 619 | { | ||
| 620 | return i915_gem_active_isset(&engine->last_request); | ||
| 621 | } | ||
| 622 | |||
| 623 | #endif /* _INTEL_RINGBUFFER_H_ */ | 584 | #endif /* _INTEL_RINGBUFFER_H_ */ |
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index ee56a8756c07..05994083e161 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c | |||
| @@ -330,7 +330,7 @@ static void skl_power_well_post_enable(struct drm_i915_private *dev_priv, | |||
| 330 | * sure vgacon can keep working normally without triggering interrupts | 330 | * sure vgacon can keep working normally without triggering interrupts |
| 331 | * and error messages. | 331 | * and error messages. |
| 332 | */ | 332 | */ |
| 333 | if (power_well->data == SKL_DISP_PW_2) { | 333 | if (power_well->id == SKL_DISP_PW_2) { |
| 334 | vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO); | 334 | vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO); |
| 335 | outb(inb(VGA_MSR_READ), VGA_MSR_WRITE); | 335 | outb(inb(VGA_MSR_READ), VGA_MSR_WRITE); |
| 336 | vga_put(pdev, VGA_RSRC_LEGACY_IO); | 336 | vga_put(pdev, VGA_RSRC_LEGACY_IO); |
| @@ -343,7 +343,7 @@ static void skl_power_well_post_enable(struct drm_i915_private *dev_priv, | |||
| 343 | static void skl_power_well_pre_disable(struct drm_i915_private *dev_priv, | 343 | static void skl_power_well_pre_disable(struct drm_i915_private *dev_priv, |
| 344 | struct i915_power_well *power_well) | 344 | struct i915_power_well *power_well) |
| 345 | { | 345 | { |
| 346 | if (power_well->data == SKL_DISP_PW_2) | 346 | if (power_well->id == SKL_DISP_PW_2) |
| 347 | gen8_irq_power_well_pre_disable(dev_priv, | 347 | gen8_irq_power_well_pre_disable(dev_priv, |
| 348 | 1 << PIPE_C | 1 << PIPE_B); | 348 | 1 << PIPE_C | 1 << PIPE_B); |
| 349 | } | 349 | } |
| @@ -658,7 +658,7 @@ static void | |||
| 658 | gen9_sanitize_power_well_requests(struct drm_i915_private *dev_priv, | 658 | gen9_sanitize_power_well_requests(struct drm_i915_private *dev_priv, |
| 659 | struct i915_power_well *power_well) | 659 | struct i915_power_well *power_well) |
| 660 | { | 660 | { |
| 661 | enum skl_disp_power_wells power_well_id = power_well->data; | 661 | enum skl_disp_power_wells power_well_id = power_well->id; |
| 662 | u32 val; | 662 | u32 val; |
| 663 | u32 mask; | 663 | u32 mask; |
| 664 | 664 | ||
| @@ -703,7 +703,7 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, | |||
| 703 | tmp = I915_READ(HSW_PWR_WELL_DRIVER); | 703 | tmp = I915_READ(HSW_PWR_WELL_DRIVER); |
| 704 | fuse_status = I915_READ(SKL_FUSE_STATUS); | 704 | fuse_status = I915_READ(SKL_FUSE_STATUS); |
| 705 | 705 | ||
| 706 | switch (power_well->data) { | 706 | switch (power_well->id) { |
| 707 | case SKL_DISP_PW_1: | 707 | case SKL_DISP_PW_1: |
| 708 | if (intel_wait_for_register(dev_priv, | 708 | if (intel_wait_for_register(dev_priv, |
| 709 | SKL_FUSE_STATUS, | 709 | SKL_FUSE_STATUS, |
| @@ -727,13 +727,13 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, | |||
| 727 | case SKL_DISP_PW_MISC_IO: | 727 | case SKL_DISP_PW_MISC_IO: |
| 728 | break; | 728 | break; |
| 729 | default: | 729 | default: |
| 730 | WARN(1, "Unknown power well %lu\n", power_well->data); | 730 | WARN(1, "Unknown power well %lu\n", power_well->id); |
| 731 | return; | 731 | return; |
| 732 | } | 732 | } |
| 733 | 733 | ||
| 734 | req_mask = SKL_POWER_WELL_REQ(power_well->data); | 734 | req_mask = SKL_POWER_WELL_REQ(power_well->id); |
| 735 | enable_requested = tmp & req_mask; | 735 | enable_requested = tmp & req_mask; |
| 736 | state_mask = SKL_POWER_WELL_STATE(power_well->data); | 736 | state_mask = SKL_POWER_WELL_STATE(power_well->id); |
| 737 | is_enabled = tmp & state_mask; | 737 | is_enabled = tmp & state_mask; |
| 738 | 738 | ||
| 739 | if (!enable && enable_requested) | 739 | if (!enable && enable_requested) |
| @@ -769,14 +769,14 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, | |||
| 769 | power_well->name, enable ? "enable" : "disable"); | 769 | power_well->name, enable ? "enable" : "disable"); |
| 770 | 770 | ||
| 771 | if (check_fuse_status) { | 771 | if (check_fuse_status) { |
| 772 | if (power_well->data == SKL_DISP_PW_1) { | 772 | if (power_well->id == SKL_DISP_PW_1) { |
| 773 | if (intel_wait_for_register(dev_priv, | 773 | if (intel_wait_for_register(dev_priv, |
| 774 | SKL_FUSE_STATUS, | 774 | SKL_FUSE_STATUS, |
| 775 | SKL_FUSE_PG1_DIST_STATUS, | 775 | SKL_FUSE_PG1_DIST_STATUS, |
| 776 | SKL_FUSE_PG1_DIST_STATUS, | 776 | SKL_FUSE_PG1_DIST_STATUS, |
| 777 | 1)) | 777 | 1)) |
| 778 | DRM_ERROR("PG1 distributing status timeout\n"); | 778 | DRM_ERROR("PG1 distributing status timeout\n"); |
| 779 | } else if (power_well->data == SKL_DISP_PW_2) { | 779 | } else if (power_well->id == SKL_DISP_PW_2) { |
| 780 | if (intel_wait_for_register(dev_priv, | 780 | if (intel_wait_for_register(dev_priv, |
| 781 | SKL_FUSE_STATUS, | 781 | SKL_FUSE_STATUS, |
| 782 | SKL_FUSE_PG2_DIST_STATUS, | 782 | SKL_FUSE_PG2_DIST_STATUS, |
| @@ -818,8 +818,8 @@ static void hsw_power_well_disable(struct drm_i915_private *dev_priv, | |||
| 818 | static bool skl_power_well_enabled(struct drm_i915_private *dev_priv, | 818 | static bool skl_power_well_enabled(struct drm_i915_private *dev_priv, |
| 819 | struct i915_power_well *power_well) | 819 | struct i915_power_well *power_well) |
| 820 | { | 820 | { |
| 821 | uint32_t mask = SKL_POWER_WELL_REQ(power_well->data) | | 821 | uint32_t mask = SKL_POWER_WELL_REQ(power_well->id) | |
| 822 | SKL_POWER_WELL_STATE(power_well->data); | 822 | SKL_POWER_WELL_STATE(power_well->id); |
| 823 | 823 | ||
| 824 | return (I915_READ(HSW_PWR_WELL_DRIVER) & mask) == mask; | 824 | return (I915_READ(HSW_PWR_WELL_DRIVER) & mask) == mask; |
| 825 | } | 825 | } |
| @@ -845,45 +845,22 @@ static void skl_power_well_disable(struct drm_i915_private *dev_priv, | |||
| 845 | skl_set_power_well(dev_priv, power_well, false); | 845 | skl_set_power_well(dev_priv, power_well, false); |
| 846 | } | 846 | } |
| 847 | 847 | ||
| 848 | static enum dpio_phy bxt_power_well_to_phy(struct i915_power_well *power_well) | ||
| 849 | { | ||
| 850 | enum skl_disp_power_wells power_well_id = power_well->data; | ||
| 851 | |||
| 852 | return power_well_id == BXT_DPIO_CMN_A ? DPIO_PHY1 : DPIO_PHY0; | ||
| 853 | } | ||
| 854 | |||
| 855 | static void bxt_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, | 848 | static void bxt_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, |
| 856 | struct i915_power_well *power_well) | 849 | struct i915_power_well *power_well) |
| 857 | { | 850 | { |
| 858 | enum skl_disp_power_wells power_well_id = power_well->data; | 851 | bxt_ddi_phy_init(dev_priv, power_well->data); |
| 859 | struct i915_power_well *cmn_a_well = NULL; | ||
| 860 | |||
| 861 | if (power_well_id == BXT_DPIO_CMN_BC) { | ||
| 862 | /* | ||
| 863 | * We need to copy the GRC calibration value from the eDP PHY, | ||
| 864 | * so make sure it's powered up. | ||
| 865 | */ | ||
| 866 | cmn_a_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_A); | ||
| 867 | intel_power_well_get(dev_priv, cmn_a_well); | ||
| 868 | } | ||
| 869 | |||
| 870 | bxt_ddi_phy_init(dev_priv, bxt_power_well_to_phy(power_well)); | ||
| 871 | |||
| 872 | if (cmn_a_well) | ||
| 873 | intel_power_well_put(dev_priv, cmn_a_well); | ||
| 874 | } | 852 | } |
| 875 | 853 | ||
| 876 | static void bxt_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, | 854 | static void bxt_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, |
| 877 | struct i915_power_well *power_well) | 855 | struct i915_power_well *power_well) |
| 878 | { | 856 | { |
| 879 | bxt_ddi_phy_uninit(dev_priv, bxt_power_well_to_phy(power_well)); | 857 | bxt_ddi_phy_uninit(dev_priv, power_well->data); |
| 880 | } | 858 | } |
| 881 | 859 | ||
| 882 | static bool bxt_dpio_cmn_power_well_enabled(struct drm_i915_private *dev_priv, | 860 | static bool bxt_dpio_cmn_power_well_enabled(struct drm_i915_private *dev_priv, |
| 883 | struct i915_power_well *power_well) | 861 | struct i915_power_well *power_well) |
| 884 | { | 862 | { |
| 885 | return bxt_ddi_phy_is_enabled(dev_priv, | 863 | return bxt_ddi_phy_is_enabled(dev_priv, power_well->data); |
| 886 | bxt_power_well_to_phy(power_well)); | ||
| 887 | } | 864 | } |
| 888 | 865 | ||
| 889 | static void bxt_dpio_cmn_power_well_sync_hw(struct drm_i915_private *dev_priv, | 866 | static void bxt_dpio_cmn_power_well_sync_hw(struct drm_i915_private *dev_priv, |
| @@ -902,13 +879,11 @@ static void bxt_verify_ddi_phy_power_wells(struct drm_i915_private *dev_priv) | |||
| 902 | 879 | ||
| 903 | power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_A); | 880 | power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_A); |
| 904 | if (power_well->count > 0) | 881 | if (power_well->count > 0) |
| 905 | bxt_ddi_phy_verify_state(dev_priv, | 882 | bxt_ddi_phy_verify_state(dev_priv, power_well->data); |
| 906 | bxt_power_well_to_phy(power_well)); | ||
| 907 | 883 | ||
| 908 | power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_BC); | 884 | power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_BC); |
| 909 | if (power_well->count > 0) | 885 | if (power_well->count > 0) |
| 910 | bxt_ddi_phy_verify_state(dev_priv, | 886 | bxt_ddi_phy_verify_state(dev_priv, power_well->data); |
| 911 | bxt_power_well_to_phy(power_well)); | ||
| 912 | } | 887 | } |
| 913 | 888 | ||
| 914 | static bool gen9_dc_off_power_well_enabled(struct drm_i915_private *dev_priv, | 889 | static bool gen9_dc_off_power_well_enabled(struct drm_i915_private *dev_priv, |
| @@ -932,7 +907,7 @@ static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv, | |||
| 932 | gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); | 907 | gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); |
| 933 | 908 | ||
| 934 | WARN_ON(dev_priv->cdclk_freq != | 909 | WARN_ON(dev_priv->cdclk_freq != |
| 935 | dev_priv->display.get_display_clock_speed(&dev_priv->drm)); | 910 | dev_priv->display.get_display_clock_speed(dev_priv)); |
| 936 | 911 | ||
| 937 | gen9_assert_dbuf_enabled(dev_priv); | 912 | gen9_assert_dbuf_enabled(dev_priv); |
| 938 | 913 | ||
| @@ -975,7 +950,7 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv, | |||
| 975 | static void vlv_set_power_well(struct drm_i915_private *dev_priv, | 950 | static void vlv_set_power_well(struct drm_i915_private *dev_priv, |
| 976 | struct i915_power_well *power_well, bool enable) | 951 | struct i915_power_well *power_well, bool enable) |
| 977 | { | 952 | { |
| 978 | enum punit_power_well power_well_id = power_well->data; | 953 | enum punit_power_well power_well_id = power_well->id; |
| 979 | u32 mask; | 954 | u32 mask; |
| 980 | u32 state; | 955 | u32 state; |
| 981 | u32 ctrl; | 956 | u32 ctrl; |
| @@ -1029,7 +1004,7 @@ static void vlv_power_well_disable(struct drm_i915_private *dev_priv, | |||
| 1029 | static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv, | 1004 | static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv, |
| 1030 | struct i915_power_well *power_well) | 1005 | struct i915_power_well *power_well) |
| 1031 | { | 1006 | { |
| 1032 | int power_well_id = power_well->data; | 1007 | int power_well_id = power_well->id; |
| 1033 | bool enabled = false; | 1008 | bool enabled = false; |
| 1034 | u32 mask; | 1009 | u32 mask; |
| 1035 | u32 state; | 1010 | u32 state; |
| @@ -1138,13 +1113,15 @@ static void vlv_display_power_well_deinit(struct drm_i915_private *dev_priv) | |||
| 1138 | 1113 | ||
| 1139 | intel_power_sequencer_reset(dev_priv); | 1114 | intel_power_sequencer_reset(dev_priv); |
| 1140 | 1115 | ||
| 1141 | intel_hpd_poll_init(dev_priv); | 1116 | /* Prevent us from re-enabling polling on accident in late suspend */ |
| 1117 | if (!dev_priv->drm.dev->power.is_suspended) | ||
| 1118 | intel_hpd_poll_init(dev_priv); | ||
| 1142 | } | 1119 | } |
| 1143 | 1120 | ||
| 1144 | static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv, | 1121 | static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv, |
| 1145 | struct i915_power_well *power_well) | 1122 | struct i915_power_well *power_well) |
| 1146 | { | 1123 | { |
| 1147 | WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D); | 1124 | WARN_ON_ONCE(power_well->id != PUNIT_POWER_WELL_DISP2D); |
| 1148 | 1125 | ||
| 1149 | vlv_set_power_well(dev_priv, power_well, true); | 1126 | vlv_set_power_well(dev_priv, power_well, true); |
| 1150 | 1127 | ||
| @@ -1154,7 +1131,7 @@ static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv, | |||
| 1154 | static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv, | 1131 | static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv, |
| 1155 | struct i915_power_well *power_well) | 1132 | struct i915_power_well *power_well) |
| 1156 | { | 1133 | { |
| 1157 | WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D); | 1134 | WARN_ON_ONCE(power_well->id != PUNIT_POWER_WELL_DISP2D); |
| 1158 | 1135 | ||
| 1159 | vlv_display_power_well_deinit(dev_priv); | 1136 | vlv_display_power_well_deinit(dev_priv); |
| 1160 | 1137 | ||
| @@ -1164,7 +1141,7 @@ static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv, | |||
| 1164 | static void vlv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, | 1141 | static void vlv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, |
| 1165 | struct i915_power_well *power_well) | 1142 | struct i915_power_well *power_well) |
| 1166 | { | 1143 | { |
| 1167 | WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC); | 1144 | WARN_ON_ONCE(power_well->id != PUNIT_POWER_WELL_DPIO_CMN_BC); |
| 1168 | 1145 | ||
| 1169 | /* since ref/cri clock was enabled */ | 1146 | /* since ref/cri clock was enabled */ |
| 1170 | udelay(1); /* >10ns for cmnreset, >0ns for sidereset */ | 1147 | udelay(1); /* >10ns for cmnreset, >0ns for sidereset */ |
| @@ -1190,7 +1167,7 @@ static void vlv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, | |||
| 1190 | { | 1167 | { |
| 1191 | enum pipe pipe; | 1168 | enum pipe pipe; |
| 1192 | 1169 | ||
| 1193 | WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC); | 1170 | WARN_ON_ONCE(power_well->id != PUNIT_POWER_WELL_DPIO_CMN_BC); |
| 1194 | 1171 | ||
| 1195 | for_each_pipe(dev_priv, pipe) | 1172 | for_each_pipe(dev_priv, pipe) |
| 1196 | assert_pll_disabled(dev_priv, pipe); | 1173 | assert_pll_disabled(dev_priv, pipe); |
| @@ -1213,7 +1190,7 @@ static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_pr | |||
| 1213 | struct i915_power_well *power_well; | 1190 | struct i915_power_well *power_well; |
| 1214 | 1191 | ||
| 1215 | power_well = &power_domains->power_wells[i]; | 1192 | power_well = &power_domains->power_wells[i]; |
| 1216 | if (power_well->data == power_well_id) | 1193 | if (power_well->id == power_well_id) |
| 1217 | return power_well; | 1194 | return power_well; |
| 1218 | } | 1195 | } |
| 1219 | 1196 | ||
| @@ -1337,10 +1314,10 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, | |||
| 1337 | enum pipe pipe; | 1314 | enum pipe pipe; |
| 1338 | uint32_t tmp; | 1315 | uint32_t tmp; |
| 1339 | 1316 | ||
| 1340 | WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC && | 1317 | WARN_ON_ONCE(power_well->id != PUNIT_POWER_WELL_DPIO_CMN_BC && |
| 1341 | power_well->data != PUNIT_POWER_WELL_DPIO_CMN_D); | 1318 | power_well->id != PUNIT_POWER_WELL_DPIO_CMN_D); |
| 1342 | 1319 | ||
| 1343 | if (power_well->data == PUNIT_POWER_WELL_DPIO_CMN_BC) { | 1320 | if (power_well->id == PUNIT_POWER_WELL_DPIO_CMN_BC) { |
| 1344 | pipe = PIPE_A; | 1321 | pipe = PIPE_A; |
| 1345 | phy = DPIO_PHY0; | 1322 | phy = DPIO_PHY0; |
| 1346 | } else { | 1323 | } else { |
| @@ -1368,7 +1345,7 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, | |||
| 1368 | DPIO_SUS_CLK_CONFIG_GATE_CLKREQ; | 1345 | DPIO_SUS_CLK_CONFIG_GATE_CLKREQ; |
| 1369 | vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW28, tmp); | 1346 | vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW28, tmp); |
| 1370 | 1347 | ||
| 1371 | if (power_well->data == PUNIT_POWER_WELL_DPIO_CMN_BC) { | 1348 | if (power_well->id == PUNIT_POWER_WELL_DPIO_CMN_BC) { |
| 1372 | tmp = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW6_CH1); | 1349 | tmp = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW6_CH1); |
| 1373 | tmp |= DPIO_DYNPWRDOWNEN_CH1; | 1350 | tmp |= DPIO_DYNPWRDOWNEN_CH1; |
| 1374 | vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW6_CH1, tmp); | 1351 | vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW6_CH1, tmp); |
| @@ -1399,10 +1376,10 @@ static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, | |||
| 1399 | { | 1376 | { |
| 1400 | enum dpio_phy phy; | 1377 | enum dpio_phy phy; |
| 1401 | 1378 | ||
| 1402 | WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC && | 1379 | WARN_ON_ONCE(power_well->id != PUNIT_POWER_WELL_DPIO_CMN_BC && |
| 1403 | power_well->data != PUNIT_POWER_WELL_DPIO_CMN_D); | 1380 | power_well->id != PUNIT_POWER_WELL_DPIO_CMN_D); |
| 1404 | 1381 | ||
| 1405 | if (power_well->data == PUNIT_POWER_WELL_DPIO_CMN_BC) { | 1382 | if (power_well->id == PUNIT_POWER_WELL_DPIO_CMN_BC) { |
| 1406 | phy = DPIO_PHY0; | 1383 | phy = DPIO_PHY0; |
| 1407 | assert_pll_disabled(dev_priv, PIPE_A); | 1384 | assert_pll_disabled(dev_priv, PIPE_A); |
| 1408 | assert_pll_disabled(dev_priv, PIPE_B); | 1385 | assert_pll_disabled(dev_priv, PIPE_B); |
| @@ -1551,7 +1528,7 @@ void chv_phy_powergate_lanes(struct intel_encoder *encoder, | |||
| 1551 | static bool chv_pipe_power_well_enabled(struct drm_i915_private *dev_priv, | 1528 | static bool chv_pipe_power_well_enabled(struct drm_i915_private *dev_priv, |
| 1552 | struct i915_power_well *power_well) | 1529 | struct i915_power_well *power_well) |
| 1553 | { | 1530 | { |
| 1554 | enum pipe pipe = power_well->data; | 1531 | enum pipe pipe = power_well->id; |
| 1555 | bool enabled; | 1532 | bool enabled; |
| 1556 | u32 state, ctrl; | 1533 | u32 state, ctrl; |
| 1557 | 1534 | ||
| @@ -1581,7 +1558,7 @@ static void chv_set_pipe_power_well(struct drm_i915_private *dev_priv, | |||
| 1581 | struct i915_power_well *power_well, | 1558 | struct i915_power_well *power_well, |
| 1582 | bool enable) | 1559 | bool enable) |
| 1583 | { | 1560 | { |
| 1584 | enum pipe pipe = power_well->data; | 1561 | enum pipe pipe = power_well->id; |
| 1585 | u32 state; | 1562 | u32 state; |
| 1586 | u32 ctrl; | 1563 | u32 ctrl; |
| 1587 | 1564 | ||
| @@ -1614,7 +1591,7 @@ out: | |||
| 1614 | static void chv_pipe_power_well_sync_hw(struct drm_i915_private *dev_priv, | 1591 | static void chv_pipe_power_well_sync_hw(struct drm_i915_private *dev_priv, |
| 1615 | struct i915_power_well *power_well) | 1592 | struct i915_power_well *power_well) |
| 1616 | { | 1593 | { |
| 1617 | WARN_ON_ONCE(power_well->data != PIPE_A); | 1594 | WARN_ON_ONCE(power_well->id != PIPE_A); |
| 1618 | 1595 | ||
| 1619 | chv_set_pipe_power_well(dev_priv, power_well, power_well->count > 0); | 1596 | chv_set_pipe_power_well(dev_priv, power_well, power_well->count > 0); |
| 1620 | } | 1597 | } |
| @@ -1622,7 +1599,7 @@ static void chv_pipe_power_well_sync_hw(struct drm_i915_private *dev_priv, | |||
| 1622 | static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv, | 1599 | static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv, |
| 1623 | struct i915_power_well *power_well) | 1600 | struct i915_power_well *power_well) |
| 1624 | { | 1601 | { |
| 1625 | WARN_ON_ONCE(power_well->data != PIPE_A); | 1602 | WARN_ON_ONCE(power_well->id != PIPE_A); |
| 1626 | 1603 | ||
| 1627 | chv_set_pipe_power_well(dev_priv, power_well, true); | 1604 | chv_set_pipe_power_well(dev_priv, power_well, true); |
| 1628 | 1605 | ||
| @@ -1632,7 +1609,7 @@ static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv, | |||
| 1632 | static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv, | 1609 | static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv, |
| 1633 | struct i915_power_well *power_well) | 1610 | struct i915_power_well *power_well) |
| 1634 | { | 1611 | { |
| 1635 | WARN_ON_ONCE(power_well->data != PIPE_A); | 1612 | WARN_ON_ONCE(power_well->id != PIPE_A); |
| 1636 | 1613 | ||
| 1637 | vlv_display_power_well_deinit(dev_priv); | 1614 | vlv_display_power_well_deinit(dev_priv); |
| 1638 | 1615 | ||
| @@ -1976,12 +1953,12 @@ static struct i915_power_well vlv_power_wells[] = { | |||
| 1976 | .always_on = 1, | 1953 | .always_on = 1, |
| 1977 | .domains = POWER_DOMAIN_MASK, | 1954 | .domains = POWER_DOMAIN_MASK, |
| 1978 | .ops = &i9xx_always_on_power_well_ops, | 1955 | .ops = &i9xx_always_on_power_well_ops, |
| 1979 | .data = PUNIT_POWER_WELL_ALWAYS_ON, | 1956 | .id = PUNIT_POWER_WELL_ALWAYS_ON, |
| 1980 | }, | 1957 | }, |
| 1981 | { | 1958 | { |
| 1982 | .name = "display", | 1959 | .name = "display", |
| 1983 | .domains = VLV_DISPLAY_POWER_DOMAINS, | 1960 | .domains = VLV_DISPLAY_POWER_DOMAINS, |
| 1984 | .data = PUNIT_POWER_WELL_DISP2D, | 1961 | .id = PUNIT_POWER_WELL_DISP2D, |
| 1985 | .ops = &vlv_display_power_well_ops, | 1962 | .ops = &vlv_display_power_well_ops, |
| 1986 | }, | 1963 | }, |
| 1987 | { | 1964 | { |
| @@ -1991,7 +1968,7 @@ static struct i915_power_well vlv_power_wells[] = { | |||
| 1991 | VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | | 1968 | VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | |
| 1992 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, | 1969 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, |
| 1993 | .ops = &vlv_dpio_power_well_ops, | 1970 | .ops = &vlv_dpio_power_well_ops, |
| 1994 | .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_01, | 1971 | .id = PUNIT_POWER_WELL_DPIO_TX_B_LANES_01, |
| 1995 | }, | 1972 | }, |
| 1996 | { | 1973 | { |
| 1997 | .name = "dpio-tx-b-23", | 1974 | .name = "dpio-tx-b-23", |
| @@ -2000,7 +1977,7 @@ static struct i915_power_well vlv_power_wells[] = { | |||
| 2000 | VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | | 1977 | VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | |
| 2001 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, | 1978 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, |
| 2002 | .ops = &vlv_dpio_power_well_ops, | 1979 | .ops = &vlv_dpio_power_well_ops, |
| 2003 | .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_23, | 1980 | .id = PUNIT_POWER_WELL_DPIO_TX_B_LANES_23, |
| 2004 | }, | 1981 | }, |
| 2005 | { | 1982 | { |
| 2006 | .name = "dpio-tx-c-01", | 1983 | .name = "dpio-tx-c-01", |
| @@ -2009,7 +1986,7 @@ static struct i915_power_well vlv_power_wells[] = { | |||
| 2009 | VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | | 1986 | VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | |
| 2010 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, | 1987 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, |
| 2011 | .ops = &vlv_dpio_power_well_ops, | 1988 | .ops = &vlv_dpio_power_well_ops, |
| 2012 | .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_01, | 1989 | .id = PUNIT_POWER_WELL_DPIO_TX_C_LANES_01, |
| 2013 | }, | 1990 | }, |
| 2014 | { | 1991 | { |
| 2015 | .name = "dpio-tx-c-23", | 1992 | .name = "dpio-tx-c-23", |
| @@ -2018,12 +1995,12 @@ static struct i915_power_well vlv_power_wells[] = { | |||
| 2018 | VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | | 1995 | VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | |
| 2019 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, | 1996 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, |
| 2020 | .ops = &vlv_dpio_power_well_ops, | 1997 | .ops = &vlv_dpio_power_well_ops, |
| 2021 | .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23, | 1998 | .id = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23, |
| 2022 | }, | 1999 | }, |
| 2023 | { | 2000 | { |
| 2024 | .name = "dpio-common", | 2001 | .name = "dpio-common", |
| 2025 | .domains = VLV_DPIO_CMN_BC_POWER_DOMAINS, | 2002 | .domains = VLV_DPIO_CMN_BC_POWER_DOMAINS, |
| 2026 | .data = PUNIT_POWER_WELL_DPIO_CMN_BC, | 2003 | .id = PUNIT_POWER_WELL_DPIO_CMN_BC, |
| 2027 | .ops = &vlv_dpio_cmn_power_well_ops, | 2004 | .ops = &vlv_dpio_cmn_power_well_ops, |
| 2028 | }, | 2005 | }, |
| 2029 | }; | 2006 | }; |
| @@ -2043,19 +2020,19 @@ static struct i915_power_well chv_power_wells[] = { | |||
| 2043 | * required for any pipe to work. | 2020 | * required for any pipe to work. |
| 2044 | */ | 2021 | */ |
| 2045 | .domains = CHV_DISPLAY_POWER_DOMAINS, | 2022 | .domains = CHV_DISPLAY_POWER_DOMAINS, |
| 2046 | .data = PIPE_A, | 2023 | .id = PIPE_A, |
| 2047 | .ops = &chv_pipe_power_well_ops, | 2024 | .ops = &chv_pipe_power_well_ops, |
| 2048 | }, | 2025 | }, |
| 2049 | { | 2026 | { |
| 2050 | .name = "dpio-common-bc", | 2027 | .name = "dpio-common-bc", |
| 2051 | .domains = CHV_DPIO_CMN_BC_POWER_DOMAINS, | 2028 | .domains = CHV_DPIO_CMN_BC_POWER_DOMAINS, |
| 2052 | .data = PUNIT_POWER_WELL_DPIO_CMN_BC, | 2029 | .id = PUNIT_POWER_WELL_DPIO_CMN_BC, |
| 2053 | .ops = &chv_dpio_cmn_power_well_ops, | 2030 | .ops = &chv_dpio_cmn_power_well_ops, |
| 2054 | }, | 2031 | }, |
| 2055 | { | 2032 | { |
| 2056 | .name = "dpio-common-d", | 2033 | .name = "dpio-common-d", |
| 2057 | .domains = CHV_DPIO_CMN_D_POWER_DOMAINS, | 2034 | .domains = CHV_DPIO_CMN_D_POWER_DOMAINS, |
| 2058 | .data = PUNIT_POWER_WELL_DPIO_CMN_D, | 2035 | .id = PUNIT_POWER_WELL_DPIO_CMN_D, |
| 2059 | .ops = &chv_dpio_cmn_power_well_ops, | 2036 | .ops = &chv_dpio_cmn_power_well_ops, |
| 2060 | }, | 2037 | }, |
| 2061 | }; | 2038 | }; |
| @@ -2078,57 +2055,57 @@ static struct i915_power_well skl_power_wells[] = { | |||
| 2078 | .always_on = 1, | 2055 | .always_on = 1, |
| 2079 | .domains = POWER_DOMAIN_MASK, | 2056 | .domains = POWER_DOMAIN_MASK, |
| 2080 | .ops = &i9xx_always_on_power_well_ops, | 2057 | .ops = &i9xx_always_on_power_well_ops, |
| 2081 | .data = SKL_DISP_PW_ALWAYS_ON, | 2058 | .id = SKL_DISP_PW_ALWAYS_ON, |
| 2082 | }, | 2059 | }, |
| 2083 | { | 2060 | { |
| 2084 | .name = "power well 1", | 2061 | .name = "power well 1", |
| 2085 | /* Handled by the DMC firmware */ | 2062 | /* Handled by the DMC firmware */ |
| 2086 | .domains = 0, | 2063 | .domains = 0, |
| 2087 | .ops = &skl_power_well_ops, | 2064 | .ops = &skl_power_well_ops, |
| 2088 | .data = SKL_DISP_PW_1, | 2065 | .id = SKL_DISP_PW_1, |
| 2089 | }, | 2066 | }, |
| 2090 | { | 2067 | { |
| 2091 | .name = "MISC IO power well", | 2068 | .name = "MISC IO power well", |
| 2092 | /* Handled by the DMC firmware */ | 2069 | /* Handled by the DMC firmware */ |
| 2093 | .domains = 0, | 2070 | .domains = 0, |
| 2094 | .ops = &skl_power_well_ops, | 2071 | .ops = &skl_power_well_ops, |
| 2095 | .data = SKL_DISP_PW_MISC_IO, | 2072 | .id = SKL_DISP_PW_MISC_IO, |
| 2096 | }, | 2073 | }, |
| 2097 | { | 2074 | { |
| 2098 | .name = "DC off", | 2075 | .name = "DC off", |
| 2099 | .domains = SKL_DISPLAY_DC_OFF_POWER_DOMAINS, | 2076 | .domains = SKL_DISPLAY_DC_OFF_POWER_DOMAINS, |
| 2100 | .ops = &gen9_dc_off_power_well_ops, | 2077 | .ops = &gen9_dc_off_power_well_ops, |
| 2101 | .data = SKL_DISP_PW_DC_OFF, | 2078 | .id = SKL_DISP_PW_DC_OFF, |
| 2102 | }, | 2079 | }, |
| 2103 | { | 2080 | { |
| 2104 | .name = "power well 2", | 2081 | .name = "power well 2", |
| 2105 | .domains = SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS, | 2082 | .domains = SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS, |
| 2106 | .ops = &skl_power_well_ops, | 2083 | .ops = &skl_power_well_ops, |
| 2107 | .data = SKL_DISP_PW_2, | 2084 | .id = SKL_DISP_PW_2, |
| 2108 | }, | 2085 | }, |
| 2109 | { | 2086 | { |
| 2110 | .name = "DDI A/E power well", | 2087 | .name = "DDI A/E power well", |
| 2111 | .domains = SKL_DISPLAY_DDI_A_E_POWER_DOMAINS, | 2088 | .domains = SKL_DISPLAY_DDI_A_E_POWER_DOMAINS, |
| 2112 | .ops = &skl_power_well_ops, | 2089 | .ops = &skl_power_well_ops, |
| 2113 | .data = SKL_DISP_PW_DDI_A_E, | 2090 | .id = SKL_DISP_PW_DDI_A_E, |
| 2114 | }, | 2091 | }, |
| 2115 | { | 2092 | { |
| 2116 | .name = "DDI B power well", | 2093 | .name = "DDI B power well", |
| 2117 | .domains = SKL_DISPLAY_DDI_B_POWER_DOMAINS, | 2094 | .domains = SKL_DISPLAY_DDI_B_POWER_DOMAINS, |
| 2118 | .ops = &skl_power_well_ops, | 2095 | .ops = &skl_power_well_ops, |
| 2119 | .data = SKL_DISP_PW_DDI_B, | 2096 | .id = SKL_DISP_PW_DDI_B, |
| 2120 | }, | 2097 | }, |
| 2121 | { | 2098 | { |
| 2122 | .name = "DDI C power well", | 2099 | .name = "DDI C power well", |
| 2123 | .domains = SKL_DISPLAY_DDI_C_POWER_DOMAINS, | 2100 | .domains = SKL_DISPLAY_DDI_C_POWER_DOMAINS, |
| 2124 | .ops = &skl_power_well_ops, | 2101 | .ops = &skl_power_well_ops, |
| 2125 | .data = SKL_DISP_PW_DDI_C, | 2102 | .id = SKL_DISP_PW_DDI_C, |
| 2126 | }, | 2103 | }, |
| 2127 | { | 2104 | { |
| 2128 | .name = "DDI D power well", | 2105 | .name = "DDI D power well", |
| 2129 | .domains = SKL_DISPLAY_DDI_D_POWER_DOMAINS, | 2106 | .domains = SKL_DISPLAY_DDI_D_POWER_DOMAINS, |
| 2130 | .ops = &skl_power_well_ops, | 2107 | .ops = &skl_power_well_ops, |
| 2131 | .data = SKL_DISP_PW_DDI_D, | 2108 | .id = SKL_DISP_PW_DDI_D, |
| 2132 | }, | 2109 | }, |
| 2133 | }; | 2110 | }; |
| 2134 | 2111 | ||
| @@ -2143,31 +2120,33 @@ static struct i915_power_well bxt_power_wells[] = { | |||
| 2143 | .name = "power well 1", | 2120 | .name = "power well 1", |
| 2144 | .domains = 0, | 2121 | .domains = 0, |
| 2145 | .ops = &skl_power_well_ops, | 2122 | .ops = &skl_power_well_ops, |
| 2146 | .data = SKL_DISP_PW_1, | 2123 | .id = SKL_DISP_PW_1, |
| 2147 | }, | 2124 | }, |
| 2148 | { | 2125 | { |
| 2149 | .name = "DC off", | 2126 | .name = "DC off", |
| 2150 | .domains = BXT_DISPLAY_DC_OFF_POWER_DOMAINS, | 2127 | .domains = BXT_DISPLAY_DC_OFF_POWER_DOMAINS, |
| 2151 | .ops = &gen9_dc_off_power_well_ops, | 2128 | .ops = &gen9_dc_off_power_well_ops, |
| 2152 | .data = SKL_DISP_PW_DC_OFF, | 2129 | .id = SKL_DISP_PW_DC_OFF, |
| 2153 | }, | 2130 | }, |
| 2154 | { | 2131 | { |
| 2155 | .name = "power well 2", | 2132 | .name = "power well 2", |
| 2156 | .domains = BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS, | 2133 | .domains = BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS, |
| 2157 | .ops = &skl_power_well_ops, | 2134 | .ops = &skl_power_well_ops, |
| 2158 | .data = SKL_DISP_PW_2, | 2135 | .id = SKL_DISP_PW_2, |
| 2159 | }, | 2136 | }, |
| 2160 | { | 2137 | { |
| 2161 | .name = "dpio-common-a", | 2138 | .name = "dpio-common-a", |
| 2162 | .domains = BXT_DPIO_CMN_A_POWER_DOMAINS, | 2139 | .domains = BXT_DPIO_CMN_A_POWER_DOMAINS, |
| 2163 | .ops = &bxt_dpio_cmn_power_well_ops, | 2140 | .ops = &bxt_dpio_cmn_power_well_ops, |
| 2164 | .data = BXT_DPIO_CMN_A, | 2141 | .id = BXT_DPIO_CMN_A, |
| 2142 | .data = DPIO_PHY1, | ||
| 2165 | }, | 2143 | }, |
| 2166 | { | 2144 | { |
| 2167 | .name = "dpio-common-bc", | 2145 | .name = "dpio-common-bc", |
| 2168 | .domains = BXT_DPIO_CMN_BC_POWER_DOMAINS, | 2146 | .domains = BXT_DPIO_CMN_BC_POWER_DOMAINS, |
| 2169 | .ops = &bxt_dpio_cmn_power_well_ops, | 2147 | .ops = &bxt_dpio_cmn_power_well_ops, |
| 2170 | .data = BXT_DPIO_CMN_BC, | 2148 | .id = BXT_DPIO_CMN_BC, |
| 2149 | .data = DPIO_PHY0, | ||
| 2171 | }, | 2150 | }, |
| 2172 | }; | 2151 | }; |
| 2173 | 2152 | ||
| @@ -2736,8 +2715,7 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv) | |||
| 2736 | struct device *kdev = &pdev->dev; | 2715 | struct device *kdev = &pdev->dev; |
| 2737 | 2716 | ||
| 2738 | assert_rpm_wakelock_held(dev_priv); | 2717 | assert_rpm_wakelock_held(dev_priv); |
| 2739 | if (atomic_dec_and_test(&dev_priv->pm.wakeref_count)) | 2718 | atomic_dec(&dev_priv->pm.wakeref_count); |
| 2740 | atomic_inc(&dev_priv->pm.atomic_seq); | ||
| 2741 | 2719 | ||
| 2742 | pm_runtime_mark_last_busy(kdev); | 2720 | pm_runtime_mark_last_busy(kdev); |
| 2743 | pm_runtime_put_autosuspend(kdev); | 2721 | pm_runtime_put_autosuspend(kdev); |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 49fb95d03d74..3990c805a5b5 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
| @@ -1472,7 +1472,7 @@ static void intel_disable_sdvo(struct intel_encoder *encoder, | |||
| 1472 | temp &= ~SDVO_ENABLE; | 1472 | temp &= ~SDVO_ENABLE; |
| 1473 | intel_sdvo_write_sdvox(intel_sdvo, temp); | 1473 | intel_sdvo_write_sdvox(intel_sdvo, temp); |
| 1474 | 1474 | ||
| 1475 | intel_wait_for_vblank_if_active(&dev_priv->drm, PIPE_A); | 1475 | intel_wait_for_vblank_if_active(dev_priv, PIPE_A); |
| 1476 | intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); | 1476 | intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); |
| 1477 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); | 1477 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); |
| 1478 | } | 1478 | } |
| @@ -1509,7 +1509,7 @@ static void intel_enable_sdvo(struct intel_encoder *encoder, | |||
| 1509 | intel_sdvo_write_sdvox(intel_sdvo, temp); | 1509 | intel_sdvo_write_sdvox(intel_sdvo, temp); |
| 1510 | 1510 | ||
| 1511 | for (i = 0; i < 2; i++) | 1511 | for (i = 0; i < 2; i++) |
| 1512 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 1512 | intel_wait_for_vblank(dev_priv, intel_crtc->pipe); |
| 1513 | 1513 | ||
| 1514 | success = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2); | 1514 | success = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2); |
| 1515 | /* Warn if the device reported failure to sync. | 1515 | /* Warn if the device reported failure to sync. |
| @@ -2411,10 +2411,10 @@ static void | |||
| 2411 | intel_sdvo_add_hdmi_properties(struct intel_sdvo *intel_sdvo, | 2411 | intel_sdvo_add_hdmi_properties(struct intel_sdvo *intel_sdvo, |
| 2412 | struct intel_sdvo_connector *connector) | 2412 | struct intel_sdvo_connector *connector) |
| 2413 | { | 2413 | { |
| 2414 | struct drm_device *dev = connector->base.base.dev; | 2414 | struct drm_i915_private *dev_priv = to_i915(connector->base.base.dev); |
| 2415 | 2415 | ||
| 2416 | intel_attach_force_audio_property(&connector->base.base); | 2416 | intel_attach_force_audio_property(&connector->base.base); |
| 2417 | if (INTEL_INFO(dev)->gen >= 4 && IS_MOBILE(dev)) { | 2417 | if (INTEL_GEN(dev_priv) >= 4 && IS_MOBILE(dev_priv)) { |
| 2418 | intel_attach_broadcast_rgb_property(&connector->base.base); | 2418 | intel_attach_broadcast_rgb_property(&connector->base.base); |
| 2419 | intel_sdvo->color_range_auto = true; | 2419 | intel_sdvo->color_range_auto = true; |
| 2420 | } | 2420 | } |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 43d0350856e7..df0fbb4b15a3 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
| @@ -1042,10 +1042,10 @@ static uint32_t skl_plane_formats[] = { | |||
| 1042 | DRM_FORMAT_VYUY, | 1042 | DRM_FORMAT_VYUY, |
| 1043 | }; | 1043 | }; |
| 1044 | 1044 | ||
| 1045 | int | 1045 | struct intel_plane * |
| 1046 | intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) | 1046 | intel_sprite_plane_create(struct drm_i915_private *dev_priv, |
| 1047 | enum pipe pipe, int plane) | ||
| 1047 | { | 1048 | { |
| 1048 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
| 1049 | struct intel_plane *intel_plane = NULL; | 1049 | struct intel_plane *intel_plane = NULL; |
| 1050 | struct intel_plane_state *state = NULL; | 1050 | struct intel_plane_state *state = NULL; |
| 1051 | unsigned long possible_crtcs; | 1051 | unsigned long possible_crtcs; |
| @@ -1054,9 +1054,6 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) | |||
| 1054 | int num_plane_formats; | 1054 | int num_plane_formats; |
| 1055 | int ret; | 1055 | int ret; |
| 1056 | 1056 | ||
| 1057 | if (INTEL_INFO(dev)->gen < 5) | ||
| 1058 | return -ENODEV; | ||
| 1059 | |||
| 1060 | intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL); | 1057 | intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL); |
| 1061 | if (!intel_plane) { | 1058 | if (!intel_plane) { |
| 1062 | ret = -ENOMEM; | 1059 | ret = -ENOMEM; |
| @@ -1070,25 +1067,25 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) | |||
| 1070 | } | 1067 | } |
| 1071 | intel_plane->base.state = &state->base; | 1068 | intel_plane->base.state = &state->base; |
| 1072 | 1069 | ||
| 1073 | switch (INTEL_INFO(dev)->gen) { | 1070 | if (INTEL_GEN(dev_priv) >= 9) { |
| 1074 | case 5: | ||
| 1075 | case 6: | ||
| 1076 | intel_plane->can_scale = true; | 1071 | intel_plane->can_scale = true; |
| 1077 | intel_plane->max_downscale = 16; | 1072 | state->scaler_id = -1; |
| 1078 | intel_plane->update_plane = ilk_update_plane; | ||
| 1079 | intel_plane->disable_plane = ilk_disable_plane; | ||
| 1080 | 1073 | ||
| 1081 | if (IS_GEN6(dev_priv)) { | 1074 | intel_plane->update_plane = skl_update_plane; |
| 1082 | plane_formats = snb_plane_formats; | 1075 | intel_plane->disable_plane = skl_disable_plane; |
| 1083 | num_plane_formats = ARRAY_SIZE(snb_plane_formats); | ||
| 1084 | } else { | ||
| 1085 | plane_formats = ilk_plane_formats; | ||
| 1086 | num_plane_formats = ARRAY_SIZE(ilk_plane_formats); | ||
| 1087 | } | ||
| 1088 | break; | ||
| 1089 | 1076 | ||
| 1090 | case 7: | 1077 | plane_formats = skl_plane_formats; |
| 1091 | case 8: | 1078 | num_plane_formats = ARRAY_SIZE(skl_plane_formats); |
| 1079 | } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { | ||
| 1080 | intel_plane->can_scale = false; | ||
| 1081 | intel_plane->max_downscale = 1; | ||
| 1082 | |||
| 1083 | intel_plane->update_plane = vlv_update_plane; | ||
| 1084 | intel_plane->disable_plane = vlv_disable_plane; | ||
| 1085 | |||
| 1086 | plane_formats = vlv_plane_formats; | ||
| 1087 | num_plane_formats = ARRAY_SIZE(vlv_plane_formats); | ||
| 1088 | } else if (INTEL_GEN(dev_priv) >= 7) { | ||
| 1092 | if (IS_IVYBRIDGE(dev_priv)) { | 1089 | if (IS_IVYBRIDGE(dev_priv)) { |
| 1093 | intel_plane->can_scale = true; | 1090 | intel_plane->can_scale = true; |
| 1094 | intel_plane->max_downscale = 2; | 1091 | intel_plane->max_downscale = 2; |
| @@ -1097,33 +1094,25 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) | |||
| 1097 | intel_plane->max_downscale = 1; | 1094 | intel_plane->max_downscale = 1; |
| 1098 | } | 1095 | } |
| 1099 | 1096 | ||
| 1100 | if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { | 1097 | intel_plane->update_plane = ivb_update_plane; |
| 1101 | intel_plane->update_plane = vlv_update_plane; | 1098 | intel_plane->disable_plane = ivb_disable_plane; |
| 1102 | intel_plane->disable_plane = vlv_disable_plane; | ||
| 1103 | 1099 | ||
| 1104 | plane_formats = vlv_plane_formats; | 1100 | plane_formats = snb_plane_formats; |
| 1105 | num_plane_formats = ARRAY_SIZE(vlv_plane_formats); | 1101 | num_plane_formats = ARRAY_SIZE(snb_plane_formats); |
| 1106 | } else { | 1102 | } else { |
| 1107 | intel_plane->update_plane = ivb_update_plane; | 1103 | intel_plane->can_scale = true; |
| 1108 | intel_plane->disable_plane = ivb_disable_plane; | 1104 | intel_plane->max_downscale = 16; |
| 1105 | |||
| 1106 | intel_plane->update_plane = ilk_update_plane; | ||
| 1107 | intel_plane->disable_plane = ilk_disable_plane; | ||
| 1109 | 1108 | ||
| 1109 | if (IS_GEN6(dev_priv)) { | ||
| 1110 | plane_formats = snb_plane_formats; | 1110 | plane_formats = snb_plane_formats; |
| 1111 | num_plane_formats = ARRAY_SIZE(snb_plane_formats); | 1111 | num_plane_formats = ARRAY_SIZE(snb_plane_formats); |
| 1112 | } else { | ||
| 1113 | plane_formats = ilk_plane_formats; | ||
| 1114 | num_plane_formats = ARRAY_SIZE(ilk_plane_formats); | ||
| 1112 | } | 1115 | } |
| 1113 | break; | ||
| 1114 | case 9: | ||
| 1115 | intel_plane->can_scale = true; | ||
| 1116 | intel_plane->update_plane = skl_update_plane; | ||
| 1117 | intel_plane->disable_plane = skl_disable_plane; | ||
| 1118 | state->scaler_id = -1; | ||
| 1119 | |||
| 1120 | plane_formats = skl_plane_formats; | ||
| 1121 | num_plane_formats = ARRAY_SIZE(skl_plane_formats); | ||
| 1122 | break; | ||
| 1123 | default: | ||
| 1124 | MISSING_CASE(INTEL_INFO(dev)->gen); | ||
| 1125 | ret = -ENODEV; | ||
| 1126 | goto fail; | ||
| 1127 | } | 1116 | } |
| 1128 | 1117 | ||
| 1129 | if (INTEL_GEN(dev_priv) >= 9) { | 1118 | if (INTEL_GEN(dev_priv) >= 9) { |
| @@ -1142,15 +1131,15 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) | |||
| 1142 | 1131 | ||
| 1143 | possible_crtcs = (1 << pipe); | 1132 | possible_crtcs = (1 << pipe); |
| 1144 | 1133 | ||
| 1145 | if (INTEL_INFO(dev)->gen >= 9) | 1134 | if (INTEL_GEN(dev_priv) >= 9) |
| 1146 | ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs, | 1135 | ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base, |
| 1147 | &intel_plane_funcs, | 1136 | possible_crtcs, &intel_plane_funcs, |
| 1148 | plane_formats, num_plane_formats, | 1137 | plane_formats, num_plane_formats, |
| 1149 | DRM_PLANE_TYPE_OVERLAY, | 1138 | DRM_PLANE_TYPE_OVERLAY, |
| 1150 | "plane %d%c", plane + 2, pipe_name(pipe)); | 1139 | "plane %d%c", plane + 2, pipe_name(pipe)); |
| 1151 | else | 1140 | else |
| 1152 | ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs, | 1141 | ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base, |
| 1153 | &intel_plane_funcs, | 1142 | possible_crtcs, &intel_plane_funcs, |
| 1154 | plane_formats, num_plane_formats, | 1143 | plane_formats, num_plane_formats, |
| 1155 | DRM_PLANE_TYPE_OVERLAY, | 1144 | DRM_PLANE_TYPE_OVERLAY, |
| 1156 | "sprite %c", sprite_name(pipe, plane)); | 1145 | "sprite %c", sprite_name(pipe, plane)); |
| @@ -1163,11 +1152,11 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) | |||
| 1163 | 1152 | ||
| 1164 | drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs); | 1153 | drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs); |
| 1165 | 1154 | ||
| 1166 | return 0; | 1155 | return intel_plane; |
| 1167 | 1156 | ||
| 1168 | fail: | 1157 | fail: |
| 1169 | kfree(state); | 1158 | kfree(state); |
| 1170 | kfree(intel_plane); | 1159 | kfree(intel_plane); |
| 1171 | 1160 | ||
| 1172 | return ret; | 1161 | return ERR_PTR(ret); |
| 1173 | } | 1162 | } |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 7118fb55f57f..9212f00d5752 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
| @@ -856,7 +856,7 @@ intel_enable_tv(struct intel_encoder *encoder, | |||
| 856 | struct drm_i915_private *dev_priv = to_i915(dev); | 856 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 857 | 857 | ||
| 858 | /* Prevents vblank waits from timing out in intel_tv_detect_type() */ | 858 | /* Prevents vblank waits from timing out in intel_tv_detect_type() */ |
| 859 | intel_wait_for_vblank(encoder->base.dev, | 859 | intel_wait_for_vblank(dev_priv, |
| 860 | to_intel_crtc(encoder->base.crtc)->pipe); | 860 | to_intel_crtc(encoder->base.crtc)->pipe); |
| 861 | 861 | ||
| 862 | I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE); | 862 | I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE); |
| @@ -1238,7 +1238,7 @@ intel_tv_detect_type(struct intel_tv *intel_tv, | |||
| 1238 | I915_WRITE(TV_DAC, tv_dac); | 1238 | I915_WRITE(TV_DAC, tv_dac); |
| 1239 | POSTING_READ(TV_DAC); | 1239 | POSTING_READ(TV_DAC); |
| 1240 | 1240 | ||
| 1241 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 1241 | intel_wait_for_vblank(dev_priv, intel_crtc->pipe); |
| 1242 | 1242 | ||
| 1243 | type = -1; | 1243 | type = -1; |
| 1244 | tv_dac = I915_READ(TV_DAC); | 1244 | tv_dac = I915_READ(TV_DAC); |
| @@ -1268,7 +1268,7 @@ intel_tv_detect_type(struct intel_tv *intel_tv, | |||
| 1268 | POSTING_READ(TV_CTL); | 1268 | POSTING_READ(TV_CTL); |
| 1269 | 1269 | ||
| 1270 | /* For unknown reasons the hw barfs if we don't do this vblank wait. */ | 1270 | /* For unknown reasons the hw barfs if we don't do this vblank wait. */ |
| 1271 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 1271 | intel_wait_for_vblank(dev_priv, intel_crtc->pipe); |
| 1272 | 1272 | ||
| 1273 | /* Restore interrupt config */ | 1273 | /* Restore interrupt config */ |
| 1274 | if (connector->polled & DRM_CONNECTOR_POLL_HPD) { | 1274 | if (connector->polled & DRM_CONNECTOR_POLL_HPD) { |
