diff options
author | Dave Airlie <airlied@redhat.com> | 2017-12-03 18:40:35 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-12-03 19:56:53 -0500 |
commit | ca797d29cd63e7b71b4eea29aff3b1cefd1ecb59 (patch) | |
tree | db1ada69f713da68b43c828bd15f90e250f86ab7 | |
parent | 2c1c55cb75a9c72f9726fabb8c3607947711a8df (diff) | |
parent | 010d118c20617021025a930bc8e90f371ab99da5 (diff) |
Merge tag 'drm-intel-next-2017-11-17-1' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
More change sets for 4.16:
- Many improvements for selftests and other igt tests (Chris)
- Forcewake with PUNIT->PMIC bus fixes and robustness (Hans)
- Define an engine class for uABI (Tvrtko)
- Context switch fixes and improvements (Chris)
- GT powersavings and power gating simplification and fixes (Chris)
- Other general driver clean-ups (Chris, Lucas, Ville)
- Removing old, useless and/or bad workarounds (Chris, Oscar, Radhakrishna)
- IPS, pipe config, etc in preparation for another Fast Boot attempt (Maarten)
- OA perf fixes and support to Coffee Lake and Cannonlake (Lionel)
- Fixes around GPU fault registers (Michel)
- GEM Proxy (Tina)
- Refactor of Geminilake and Cannonlake plane color handling (James)
- Generalize transcoder loop (Mika Kahola)
- New HW Workaround for Cannonlake and Geminilake (Rodrigo)
- Resume GuC before using GEM (Chris)
- Stolen Memory handling improvements (Ville)
- Initialize entry in PPAT for older compilers (Chris)
- Other fixes and robustness improvements on execbuf (Chris)
- Improve logs of GEM_BUG_ON (Mika Kuoppala)
- Rework with massive rename of GuC functions and files (Sagar)
- Don't sanitize frame start delay if pipe is off (Ville)
- Cannonlake clock fixes (Rodrigo)
- Cannonlake HDMI 2.0 support (Rodrigo)
- Add a GuC doorbells selftest (Michel)
- Add might_sleep() check to our wait_for() (Chris)
Many GVT changes for 4.16:
- CSB HWSP update support (Weinan)
- GVT debug helpers, dyndbg and debugfs (Chuanxiao, Shuo)
- full virtualized opregion (Xiaolin)
- VM health check for sane fallback (Fred)
- workload submission code refactor for future enabling (Zhi)
- Updated repo URL in MAINTAINERS (Zhenyu)
- other many misc fixes
* tag 'drm-intel-next-2017-11-17-1' of git://anongit.freedesktop.org/drm/drm-intel: (260 commits)
drm/i915: Update DRIVER_DATE to 20171117
drm/i915: Add a policy note for removing workarounds
drm/i915/selftests: Report ENOMEM clearly for an allocation failure
Revert "drm/i915: Display WA #1133 WaFbcSkipSegments:cnl, glk"
drm/i915: Calculate g4x intermediate watermarks correctly
drm/i915: Calculate vlv/chv intermediate watermarks correctly, v3.
drm/i915: Pass crtc_state to ips toggle functions, v2
drm/i915: Pass idle crtc_state to intel_dp_sink_crc
drm/i915: Enable FIFO underrun reporting after initial fastset, v4.
drm/i915: Mark the userptr invalidate workqueue as WQ_MEM_RECLAIM
drm/i915: Add might_sleep() check to wait_for()
drm/i915/selftests: Add a GuC doorbells selftest
drm/i915/cnl: Extend HDMI 2.0 support to CNL.
drm/i915/cnl: Simplify dco_fraction calculation.
drm/i915/cnl: Don't blindly replace qdiv.
drm/i915/cnl: Fix wrpll math for higher freqs.
drm/i915/cnl: Fix, simplify and unify wrpll variable sizes.
drm/i915/cnl: Remove useless conversion.
drm/i915/cnl: Remove spurious central_freq.
drm/i915/selftests: exercise_ggtt may have nothing to do
...
129 files changed, 6526 insertions, 3154 deletions
diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst index 2e7ee0313c1c..21577eabaf78 100644 --- a/Documentation/gpu/i915.rst +++ b/Documentation/gpu/i915.rst | |||
@@ -350,10 +350,10 @@ GuC-specific firmware loader | |||
350 | GuC-based command submission | 350 | GuC-based command submission |
351 | ---------------------------- | 351 | ---------------------------- |
352 | 352 | ||
353 | .. kernel-doc:: drivers/gpu/drm/i915/i915_guc_submission.c | 353 | .. kernel-doc:: drivers/gpu/drm/i915/intel_guc_submission.c |
354 | :doc: GuC-based command submission | 354 | :doc: GuC-based command submission |
355 | 355 | ||
356 | .. kernel-doc:: drivers/gpu/drm/i915/i915_guc_submission.c | 356 | .. kernel-doc:: drivers/gpu/drm/i915/intel_guc_submission.c |
357 | :internal: | 357 | :internal: |
358 | 358 | ||
359 | GuC Firmware Layout | 359 | GuC Firmware Layout |
diff --git a/MAINTAINERS b/MAINTAINERS index d7eedb15be85..069ba63190b2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -7030,7 +7030,7 @@ M: Zhi Wang <zhi.a.wang@intel.com> | |||
7030 | L: intel-gvt-dev@lists.freedesktop.org | 7030 | L: intel-gvt-dev@lists.freedesktop.org |
7031 | L: intel-gfx@lists.freedesktop.org | 7031 | L: intel-gfx@lists.freedesktop.org |
7032 | W: https://01.org/igvt-g | 7032 | W: https://01.org/igvt-g |
7033 | T: git https://github.com/01org/gvt-linux.git | 7033 | T: git https://github.com/intel/gvt-linux.git |
7034 | S: Supported | 7034 | S: Supported |
7035 | F: drivers/gpu/drm/i915/gvt/ | 7035 | F: drivers/gpu/drm/i915/gvt/ |
7036 | 7036 | ||
diff --git a/arch/x86/include/asm/iosf_mbi.h b/arch/x86/include/asm/iosf_mbi.h index 7d87437bd030..3de0489deade 100644 --- a/arch/x86/include/asm/iosf_mbi.h +++ b/arch/x86/include/asm/iosf_mbi.h | |||
@@ -147,6 +147,18 @@ int iosf_mbi_register_pmic_bus_access_notifier(struct notifier_block *nb); | |||
147 | int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb); | 147 | int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb); |
148 | 148 | ||
149 | /** | 149 | /** |
150 | * iosf_mbi_unregister_pmic_bus_access_notifier_unlocked - Unregister PMIC bus | ||
151 | * notifier, unlocked | ||
152 | * | ||
153 | * Like iosf_mbi_unregister_pmic_bus_access_notifier(), but for use when the | ||
154 | * caller has already called iosf_mbi_punit_acquire() itself. | ||
155 | * | ||
156 | * @nb: notifier_block to unregister | ||
157 | */ | ||
158 | int iosf_mbi_unregister_pmic_bus_access_notifier_unlocked( | ||
159 | struct notifier_block *nb); | ||
160 | |||
161 | /** | ||
150 | * iosf_mbi_call_pmic_bus_access_notifier_chain - Call PMIC bus notifier chain | 162 | * iosf_mbi_call_pmic_bus_access_notifier_chain - Call PMIC bus notifier chain |
151 | * | 163 | * |
152 | * @val: action to pass into listener's notifier_call function | 164 | * @val: action to pass into listener's notifier_call function |
@@ -154,6 +166,11 @@ int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb); | |||
154 | */ | 166 | */ |
155 | int iosf_mbi_call_pmic_bus_access_notifier_chain(unsigned long val, void *v); | 167 | int iosf_mbi_call_pmic_bus_access_notifier_chain(unsigned long val, void *v); |
156 | 168 | ||
169 | /** | ||
170 | * iosf_mbi_assert_punit_acquired - Assert that the P-Unit has been acquired. | ||
171 | */ | ||
172 | void iosf_mbi_assert_punit_acquired(void); | ||
173 | |||
157 | #else /* CONFIG_IOSF_MBI is not enabled */ | 174 | #else /* CONFIG_IOSF_MBI is not enabled */ |
158 | static inline | 175 | static inline |
159 | bool iosf_mbi_available(void) | 176 | bool iosf_mbi_available(void) |
@@ -197,12 +214,20 @@ int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb) | |||
197 | return 0; | 214 | return 0; |
198 | } | 215 | } |
199 | 216 | ||
217 | static inline int | ||
218 | iosf_mbi_unregister_pmic_bus_access_notifier_unlocked(struct notifier_block *nb) | ||
219 | { | ||
220 | return 0; | ||
221 | } | ||
222 | |||
200 | static inline | 223 | static inline |
201 | int iosf_mbi_call_pmic_bus_access_notifier_chain(unsigned long val, void *v) | 224 | int iosf_mbi_call_pmic_bus_access_notifier_chain(unsigned long val, void *v) |
202 | { | 225 | { |
203 | return 0; | 226 | return 0; |
204 | } | 227 | } |
205 | 228 | ||
229 | static inline void iosf_mbi_assert_punit_acquired(void) {} | ||
230 | |||
206 | #endif /* CONFIG_IOSF_MBI */ | 231 | #endif /* CONFIG_IOSF_MBI */ |
207 | 232 | ||
208 | #endif /* IOSF_MBI_SYMS_H */ | 233 | #endif /* IOSF_MBI_SYMS_H */ |
diff --git a/arch/x86/platform/intel/iosf_mbi.c b/arch/x86/platform/intel/iosf_mbi.c index a952ac199741..6f37a2137a79 100644 --- a/arch/x86/platform/intel/iosf_mbi.c +++ b/arch/x86/platform/intel/iosf_mbi.c | |||
@@ -218,14 +218,23 @@ int iosf_mbi_register_pmic_bus_access_notifier(struct notifier_block *nb) | |||
218 | } | 218 | } |
219 | EXPORT_SYMBOL(iosf_mbi_register_pmic_bus_access_notifier); | 219 | EXPORT_SYMBOL(iosf_mbi_register_pmic_bus_access_notifier); |
220 | 220 | ||
221 | int iosf_mbi_unregister_pmic_bus_access_notifier_unlocked( | ||
222 | struct notifier_block *nb) | ||
223 | { | ||
224 | iosf_mbi_assert_punit_acquired(); | ||
225 | |||
226 | return blocking_notifier_chain_unregister( | ||
227 | &iosf_mbi_pmic_bus_access_notifier, nb); | ||
228 | } | ||
229 | EXPORT_SYMBOL(iosf_mbi_unregister_pmic_bus_access_notifier_unlocked); | ||
230 | |||
221 | int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb) | 231 | int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb) |
222 | { | 232 | { |
223 | int ret; | 233 | int ret; |
224 | 234 | ||
225 | /* Wait for the bus to go inactive before unregistering */ | 235 | /* Wait for the bus to go inactive before unregistering */ |
226 | mutex_lock(&iosf_mbi_punit_mutex); | 236 | mutex_lock(&iosf_mbi_punit_mutex); |
227 | ret = blocking_notifier_chain_unregister( | 237 | ret = iosf_mbi_unregister_pmic_bus_access_notifier_unlocked(nb); |
228 | &iosf_mbi_pmic_bus_access_notifier, nb); | ||
229 | mutex_unlock(&iosf_mbi_punit_mutex); | 238 | mutex_unlock(&iosf_mbi_punit_mutex); |
230 | 239 | ||
231 | return ret; | 240 | return ret; |
@@ -239,6 +248,12 @@ int iosf_mbi_call_pmic_bus_access_notifier_chain(unsigned long val, void *v) | |||
239 | } | 248 | } |
240 | EXPORT_SYMBOL(iosf_mbi_call_pmic_bus_access_notifier_chain); | 249 | EXPORT_SYMBOL(iosf_mbi_call_pmic_bus_access_notifier_chain); |
241 | 250 | ||
251 | void iosf_mbi_assert_punit_acquired(void) | ||
252 | { | ||
253 | WARN_ON(!mutex_is_locked(&iosf_mbi_punit_mutex)); | ||
254 | } | ||
255 | EXPORT_SYMBOL(iosf_mbi_assert_punit_acquired); | ||
256 | |||
242 | #ifdef CONFIG_IOSF_MBI_DEBUG | 257 | #ifdef CONFIG_IOSF_MBI_DEBUG |
243 | static u32 dbg_mdr; | 258 | static u32 dbg_mdr; |
244 | static u32 dbg_mcr; | 259 | static u32 dbg_mcr; |
diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug index aed7d207ea84..9e53edbc713b 100644 --- a/drivers/gpu/drm/i915/Kconfig.debug +++ b/drivers/gpu/drm/i915/Kconfig.debug | |||
@@ -28,6 +28,7 @@ config DRM_I915_DEBUG | |||
28 | select SW_SYNC # signaling validation framework (igt/syncobj*) | 28 | select SW_SYNC # signaling validation framework (igt/syncobj*) |
29 | select DRM_I915_SW_FENCE_DEBUG_OBJECTS | 29 | select DRM_I915_SW_FENCE_DEBUG_OBJECTS |
30 | select DRM_I915_SELFTEST | 30 | select DRM_I915_SELFTEST |
31 | select DRM_I915_TRACE_GEM | ||
31 | default n | 32 | default n |
32 | help | 33 | help |
33 | Choose this option to turn on extra driver debugging that may affect | 34 | Choose this option to turn on extra driver debugging that may affect |
@@ -49,6 +50,19 @@ config DRM_I915_DEBUG_GEM | |||
49 | 50 | ||
50 | If in doubt, say "N". | 51 | If in doubt, say "N". |
51 | 52 | ||
53 | config DRM_I915_TRACE_GEM | ||
54 | bool "Insert extra ftrace output from the GEM internals" | ||
55 | select TRACING | ||
56 | default n | ||
57 | help | ||
58 | Enable additional and verbose debugging output that will spam | ||
59 | ordinary tests, but may be vital for post-mortem debugging when | ||
60 | used with /proc/sys/kernel/ftrace_dump_on_oops | ||
61 | |||
62 | Recommended for driver developers only. | ||
63 | |||
64 | If in doubt, say "N". | ||
65 | |||
52 | config DRM_I915_SW_FENCE_DEBUG_OBJECTS | 66 | config DRM_I915_SW_FENCE_DEBUG_OBJECTS |
53 | bool "Enable additional driver debugging for fence objects" | 67 | bool "Enable additional driver debugging for fence objects" |
54 | depends on DRM_I915 | 68 | depends on DRM_I915 |
@@ -90,6 +104,20 @@ config DRM_I915_SELFTEST | |||
90 | 104 | ||
91 | If in doubt, say "N". | 105 | If in doubt, say "N". |
92 | 106 | ||
107 | config DRM_I915_SELFTEST_BROKEN | ||
108 | bool "Enable broken and dangerous selftests" | ||
109 | depends on DRM_I915_SELFTEST | ||
110 | depends on BROKEN | ||
111 | default n | ||
112 | help | ||
113 | This option enables the execution of selftests that are "dangerous" | ||
114 | and may trigger unintended HW side-effects as they break strict | ||
115 | rules given in the HW specification. For science. | ||
116 | |||
117 | Recommended for masochistic driver developers only. | ||
118 | |||
119 | If in doubt, say "N". | ||
120 | |||
93 | config DRM_I915_LOW_LEVEL_TRACEPOINTS | 121 | config DRM_I915_LOW_LEVEL_TRACEPOINTS |
94 | bool "Enable low level request tracing events" | 122 | bool "Enable low level request tracing events" |
95 | depends on DRM_I915 | 123 | depends on DRM_I915 |
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 2acf3b3c5f9d..49b9535e40d1 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -3,7 +3,26 @@ | |||
3 | # Makefile for the drm device driver. This driver provides support for the | 3 | # Makefile for the drm device driver. This driver provides support for the |
4 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. | 4 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. |
5 | 5 | ||
6 | subdir-ccflags-$(CONFIG_DRM_I915_WERROR) := -Werror | 6 | # Add a set of useful warning flags and enable -Werror for CI to prevent |
7 | # trivial mistakes from creeping in. We have to do this piecemeal as we reject | ||
8 | # any patch that isn't warning clean, so turning on -Wall -Wextra (or W=1) we | ||
9 | # need to filter out dubious warnings. Still it is our interest | ||
10 | # to keep running locally with W=1 C=1 until we are completely clean. | ||
11 | # | ||
12 | # Note the danger in using -Wall -Wextra is that when CI updates gcc we | ||
13 | # will most likely get a sudden build breakage... Hopefully we will fix | ||
14 | # new warnings before CI updates! | ||
15 | subdir-ccflags-y := -Wall -Wextra | ||
16 | subdir-ccflags-y += $(call cc-disable-warning, unused-parameter) | ||
17 | subdir-ccflags-y += $(call cc-disable-warning, type-limits) | ||
18 | subdir-ccflags-y += $(call cc-disable-warning, missing-field-initializers) | ||
19 | subdir-ccflags-y += $(call cc-disable-warning, implicit-fallthrough) | ||
20 | subdir-ccflags-$(CONFIG_DRM_I915_WERROR) += -Werror | ||
21 | |||
22 | # Fine grained warnings disable | ||
23 | CFLAGS_i915_pci.o = $(call cc-disable-warning, override-init) | ||
24 | CFLAGS_intel_fbdev.o = $(call cc-disable-warning, override-init) | ||
25 | |||
7 | subdir-ccflags-y += \ | 26 | subdir-ccflags-y += \ |
8 | $(call as-instr,movntdqa (%eax)$(comma)%xmm0,-DCONFIG_AS_MOVNTDQA) | 27 | $(call as-instr,movntdqa (%eax)$(comma)%xmm0,-DCONFIG_AS_MOVNTDQA) |
9 | 28 | ||
@@ -64,10 +83,10 @@ i915-y += intel_uc.o \ | |||
64 | intel_uc_fw.o \ | 83 | intel_uc_fw.o \ |
65 | intel_guc.o \ | 84 | intel_guc.o \ |
66 | intel_guc_ct.o \ | 85 | intel_guc_ct.o \ |
67 | intel_guc_log.o \ | ||
68 | intel_guc_fw.o \ | 86 | intel_guc_fw.o \ |
69 | intel_huc.o \ | 87 | intel_guc_log.o \ |
70 | i915_guc_submission.o | 88 | intel_guc_submission.o \ |
89 | intel_huc.o | ||
71 | 90 | ||
72 | # autogenerated null render state | 91 | # autogenerated null render state |
73 | i915-y += intel_renderstate_gen6.o \ | 92 | i915-y += intel_renderstate_gen6.o \ |
@@ -144,7 +163,9 @@ i915-y += i915_perf.o \ | |||
144 | i915_oa_kblgt2.o \ | 163 | i915_oa_kblgt2.o \ |
145 | i915_oa_kblgt3.o \ | 164 | i915_oa_kblgt3.o \ |
146 | i915_oa_glk.o \ | 165 | i915_oa_glk.o \ |
147 | i915_oa_cflgt2.o | 166 | i915_oa_cflgt2.o \ |
167 | i915_oa_cflgt3.o \ | ||
168 | i915_oa_cnl.o | ||
148 | 169 | ||
149 | ifeq ($(CONFIG_DRM_I915_GVT),y) | 170 | ifeq ($(CONFIG_DRM_I915_GVT),y) |
150 | i915-y += intel_gvt.o | 171 | i915-y += intel_gvt.o |
diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile index 2641ba510a61..18e1c172e792 100644 --- a/drivers/gpu/drm/i915/gvt/Makefile +++ b/drivers/gpu/drm/i915/gvt/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | GVT_DIR := gvt | 2 | GVT_DIR := gvt |
3 | GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \ | 3 | GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \ |
4 | interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \ | 4 | interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \ |
5 | execlist.o scheduler.o sched_policy.o render.o cmd_parser.o | 5 | execlist.o scheduler.o sched_policy.o render.o cmd_parser.o debugfs.o |
6 | 6 | ||
7 | ccflags-y += -I$(src) -I$(src)/$(GVT_DIR) | 7 | ccflags-y += -I$(src) -I$(src)/$(GVT_DIR) |
8 | i915-y += $(addprefix $(GVT_DIR)/, $(GVT_SOURCE)) | 8 | i915-y += $(addprefix $(GVT_DIR)/, $(GVT_SOURCE)) |
diff --git a/drivers/gpu/drm/i915/gvt/cfg_space.c b/drivers/gpu/drm/i915/gvt/cfg_space.c index ab19545d59a1..4ce2e6bd0680 100644 --- a/drivers/gpu/drm/i915/gvt/cfg_space.c +++ b/drivers/gpu/drm/i915/gvt/cfg_space.c | |||
@@ -208,6 +208,20 @@ static int emulate_pci_command_write(struct intel_vgpu *vgpu, | |||
208 | return 0; | 208 | return 0; |
209 | } | 209 | } |
210 | 210 | ||
211 | static int emulate_pci_rom_bar_write(struct intel_vgpu *vgpu, | ||
212 | unsigned int offset, void *p_data, unsigned int bytes) | ||
213 | { | ||
214 | u32 *pval = (u32 *)(vgpu_cfg_space(vgpu) + offset); | ||
215 | u32 new = *(u32 *)(p_data); | ||
216 | |||
217 | if ((new & PCI_ROM_ADDRESS_MASK) == PCI_ROM_ADDRESS_MASK) | ||
218 | /* We don't have rom, return size of 0. */ | ||
219 | *pval = 0; | ||
220 | else | ||
221 | vgpu_pci_cfg_mem_write(vgpu, offset, p_data, bytes); | ||
222 | return 0; | ||
223 | } | ||
224 | |||
211 | static int emulate_pci_bar_write(struct intel_vgpu *vgpu, unsigned int offset, | 225 | static int emulate_pci_bar_write(struct intel_vgpu *vgpu, unsigned int offset, |
212 | void *p_data, unsigned int bytes) | 226 | void *p_data, unsigned int bytes) |
213 | { | 227 | { |
@@ -300,6 +314,11 @@ int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset, | |||
300 | } | 314 | } |
301 | 315 | ||
302 | switch (rounddown(offset, 4)) { | 316 | switch (rounddown(offset, 4)) { |
317 | case PCI_ROM_ADDRESS: | ||
318 | if (WARN_ON(!IS_ALIGNED(offset, 4))) | ||
319 | return -EINVAL; | ||
320 | return emulate_pci_rom_bar_write(vgpu, offset, p_data, bytes); | ||
321 | |||
303 | case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_5: | 322 | case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_5: |
304 | if (WARN_ON(!IS_ALIGNED(offset, 4))) | 323 | if (WARN_ON(!IS_ALIGNED(offset, 4))) |
305 | return -EINVAL; | 324 | return -EINVAL; |
@@ -375,6 +394,8 @@ void intel_vgpu_init_cfg_space(struct intel_vgpu *vgpu, | |||
375 | pci_resource_len(gvt->dev_priv->drm.pdev, 0); | 394 | pci_resource_len(gvt->dev_priv->drm.pdev, 0); |
376 | vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].size = | 395 | vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].size = |
377 | pci_resource_len(gvt->dev_priv->drm.pdev, 2); | 396 | pci_resource_len(gvt->dev_priv->drm.pdev, 2); |
397 | |||
398 | memset(vgpu_cfg_space(vgpu) + PCI_ROM_ADDRESS, 0, 4); | ||
378 | } | 399 | } |
379 | 400 | ||
380 | /** | 401 | /** |
diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index 85d4c57870fb..18c45734c7a2 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c | |||
@@ -709,18 +709,13 @@ static void parser_exec_state_dump(struct parser_exec_state *s) | |||
709 | 709 | ||
710 | print_opcode(cmd_val(s, 0), s->ring_id); | 710 | print_opcode(cmd_val(s, 0), s->ring_id); |
711 | 711 | ||
712 | /* print the whole page to trace */ | ||
713 | pr_err(" ip_va=%p: %08x %08x %08x %08x\n", | ||
714 | s->ip_va, cmd_val(s, 0), cmd_val(s, 1), | ||
715 | cmd_val(s, 2), cmd_val(s, 3)); | ||
716 | |||
717 | s->ip_va = (u32 *)((((u64)s->ip_va) >> 12) << 12); | 712 | s->ip_va = (u32 *)((((u64)s->ip_va) >> 12) << 12); |
718 | 713 | ||
719 | while (cnt < 1024) { | 714 | while (cnt < 1024) { |
720 | pr_err("ip_va=%p: ", s->ip_va); | 715 | gvt_dbg_cmd("ip_va=%p: ", s->ip_va); |
721 | for (i = 0; i < 8; i++) | 716 | for (i = 0; i < 8; i++) |
722 | pr_err("%08x ", cmd_val(s, i)); | 717 | gvt_dbg_cmd("%08x ", cmd_val(s, i)); |
723 | pr_err("\n"); | 718 | gvt_dbg_cmd("\n"); |
724 | 719 | ||
725 | s->ip_va += 8 * sizeof(u32); | 720 | s->ip_va += 8 * sizeof(u32); |
726 | cnt += 8; | 721 | cnt += 8; |
@@ -825,7 +820,7 @@ static int force_nonpriv_reg_handler(struct parser_exec_state *s, | |||
825 | if (!intel_gvt_in_force_nonpriv_whitelist(gvt, data)) { | 820 | if (!intel_gvt_in_force_nonpriv_whitelist(gvt, data)) { |
826 | gvt_err("Unexpected forcenonpriv 0x%x LRI write, value=0x%x\n", | 821 | gvt_err("Unexpected forcenonpriv 0x%x LRI write, value=0x%x\n", |
827 | offset, data); | 822 | offset, data); |
828 | return -EINVAL; | 823 | return -EPERM; |
829 | } | 824 | } |
830 | return 0; | 825 | return 0; |
831 | } | 826 | } |
@@ -839,7 +834,7 @@ static int cmd_reg_handler(struct parser_exec_state *s, | |||
839 | if (offset + 4 > gvt->device_info.mmio_size) { | 834 | if (offset + 4 > gvt->device_info.mmio_size) { |
840 | gvt_vgpu_err("%s access to (%x) outside of MMIO range\n", | 835 | gvt_vgpu_err("%s access to (%x) outside of MMIO range\n", |
841 | cmd, offset); | 836 | cmd, offset); |
842 | return -EINVAL; | 837 | return -EFAULT; |
843 | } | 838 | } |
844 | 839 | ||
845 | if (!intel_gvt_mmio_is_cmd_access(gvt, offset)) { | 840 | if (!intel_gvt_mmio_is_cmd_access(gvt, offset)) { |
@@ -854,8 +849,8 @@ static int cmd_reg_handler(struct parser_exec_state *s, | |||
854 | } | 849 | } |
855 | 850 | ||
856 | if (is_force_nonpriv_mmio(offset) && | 851 | if (is_force_nonpriv_mmio(offset) && |
857 | force_nonpriv_reg_handler(s, offset, index)) | 852 | force_nonpriv_reg_handler(s, offset, index)) |
858 | return -EINVAL; | 853 | return -EPERM; |
859 | 854 | ||
860 | if (offset == i915_mmio_reg_offset(DERRMR) || | 855 | if (offset == i915_mmio_reg_offset(DERRMR) || |
861 | offset == i915_mmio_reg_offset(FORCEWAKE_MT)) { | 856 | offset == i915_mmio_reg_offset(FORCEWAKE_MT)) { |
@@ -894,11 +889,14 @@ static int cmd_handler_lri(struct parser_exec_state *s) | |||
894 | i915_mmio_reg_offset(DERRMR)) | 889 | i915_mmio_reg_offset(DERRMR)) |
895 | ret |= 0; | 890 | ret |= 0; |
896 | else | 891 | else |
897 | ret |= (cmd_reg_inhibit(s, i)) ? -EINVAL : 0; | 892 | ret |= (cmd_reg_inhibit(s, i)) ? |
893 | -EBADRQC : 0; | ||
898 | } | 894 | } |
899 | if (ret) | 895 | if (ret) |
900 | break; | 896 | break; |
901 | ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "lri"); | 897 | ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "lri"); |
898 | if (ret) | ||
899 | break; | ||
902 | } | 900 | } |
903 | return ret; | 901 | return ret; |
904 | } | 902 | } |
@@ -912,11 +910,15 @@ static int cmd_handler_lrr(struct parser_exec_state *s) | |||
912 | if (IS_BROADWELL(s->vgpu->gvt->dev_priv)) | 910 | if (IS_BROADWELL(s->vgpu->gvt->dev_priv)) |
913 | ret |= ((cmd_reg_inhibit(s, i) || | 911 | ret |= ((cmd_reg_inhibit(s, i) || |
914 | (cmd_reg_inhibit(s, i + 1)))) ? | 912 | (cmd_reg_inhibit(s, i + 1)))) ? |
915 | -EINVAL : 0; | 913 | -EBADRQC : 0; |
916 | if (ret) | 914 | if (ret) |
917 | break; | 915 | break; |
918 | ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "lrr-src"); | 916 | ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "lrr-src"); |
917 | if (ret) | ||
918 | break; | ||
919 | ret |= cmd_reg_handler(s, cmd_reg(s, i + 1), i, "lrr-dst"); | 919 | ret |= cmd_reg_handler(s, cmd_reg(s, i + 1), i, "lrr-dst"); |
920 | if (ret) | ||
921 | break; | ||
920 | } | 922 | } |
921 | return ret; | 923 | return ret; |
922 | } | 924 | } |
@@ -934,15 +936,19 @@ static int cmd_handler_lrm(struct parser_exec_state *s) | |||
934 | 936 | ||
935 | for (i = 1; i < cmd_len;) { | 937 | for (i = 1; i < cmd_len;) { |
936 | if (IS_BROADWELL(gvt->dev_priv)) | 938 | if (IS_BROADWELL(gvt->dev_priv)) |
937 | ret |= (cmd_reg_inhibit(s, i)) ? -EINVAL : 0; | 939 | ret |= (cmd_reg_inhibit(s, i)) ? -EBADRQC : 0; |
938 | if (ret) | 940 | if (ret) |
939 | break; | 941 | break; |
940 | ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "lrm"); | 942 | ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "lrm"); |
943 | if (ret) | ||
944 | break; | ||
941 | if (cmd_val(s, 0) & (1 << 22)) { | 945 | if (cmd_val(s, 0) & (1 << 22)) { |
942 | gma = cmd_gma(s, i + 1); | 946 | gma = cmd_gma(s, i + 1); |
943 | if (gmadr_bytes == 8) | 947 | if (gmadr_bytes == 8) |
944 | gma |= (cmd_gma_hi(s, i + 2)) << 32; | 948 | gma |= (cmd_gma_hi(s, i + 2)) << 32; |
945 | ret |= cmd_address_audit(s, gma, sizeof(u32), false); | 949 | ret |= cmd_address_audit(s, gma, sizeof(u32), false); |
950 | if (ret) | ||
951 | break; | ||
946 | } | 952 | } |
947 | i += gmadr_dw_number(s) + 1; | 953 | i += gmadr_dw_number(s) + 1; |
948 | } | 954 | } |
@@ -958,11 +964,15 @@ static int cmd_handler_srm(struct parser_exec_state *s) | |||
958 | 964 | ||
959 | for (i = 1; i < cmd_len;) { | 965 | for (i = 1; i < cmd_len;) { |
960 | ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "srm"); | 966 | ret |= cmd_reg_handler(s, cmd_reg(s, i), i, "srm"); |
967 | if (ret) | ||
968 | break; | ||
961 | if (cmd_val(s, 0) & (1 << 22)) { | 969 | if (cmd_val(s, 0) & (1 << 22)) { |
962 | gma = cmd_gma(s, i + 1); | 970 | gma = cmd_gma(s, i + 1); |
963 | if (gmadr_bytes == 8) | 971 | if (gmadr_bytes == 8) |
964 | gma |= (cmd_gma_hi(s, i + 2)) << 32; | 972 | gma |= (cmd_gma_hi(s, i + 2)) << 32; |
965 | ret |= cmd_address_audit(s, gma, sizeof(u32), false); | 973 | ret |= cmd_address_audit(s, gma, sizeof(u32), false); |
974 | if (ret) | ||
975 | break; | ||
966 | } | 976 | } |
967 | i += gmadr_dw_number(s) + 1; | 977 | i += gmadr_dw_number(s) + 1; |
968 | } | 978 | } |
@@ -1116,7 +1126,7 @@ static int gen8_decode_mi_display_flip(struct parser_exec_state *s, | |||
1116 | 1126 | ||
1117 | v = (dword0 & GENMASK(21, 19)) >> 19; | 1127 | v = (dword0 & GENMASK(21, 19)) >> 19; |
1118 | if (WARN_ON(v >= ARRAY_SIZE(gen8_plane_code))) | 1128 | if (WARN_ON(v >= ARRAY_SIZE(gen8_plane_code))) |
1119 | return -EINVAL; | 1129 | return -EBADRQC; |
1120 | 1130 | ||
1121 | info->pipe = gen8_plane_code[v].pipe; | 1131 | info->pipe = gen8_plane_code[v].pipe; |
1122 | info->plane = gen8_plane_code[v].plane; | 1132 | info->plane = gen8_plane_code[v].plane; |
@@ -1136,7 +1146,7 @@ static int gen8_decode_mi_display_flip(struct parser_exec_state *s, | |||
1136 | info->surf_reg = SPRSURF(info->pipe); | 1146 | info->surf_reg = SPRSURF(info->pipe); |
1137 | } else { | 1147 | } else { |
1138 | WARN_ON(1); | 1148 | WARN_ON(1); |
1139 | return -EINVAL; | 1149 | return -EBADRQC; |
1140 | } | 1150 | } |
1141 | return 0; | 1151 | return 0; |
1142 | } | 1152 | } |
@@ -1185,7 +1195,7 @@ static int skl_decode_mi_display_flip(struct parser_exec_state *s, | |||
1185 | 1195 | ||
1186 | default: | 1196 | default: |
1187 | gvt_vgpu_err("unknown plane code %d\n", plane); | 1197 | gvt_vgpu_err("unknown plane code %d\n", plane); |
1188 | return -EINVAL; | 1198 | return -EBADRQC; |
1189 | } | 1199 | } |
1190 | 1200 | ||
1191 | info->stride_val = (dword1 & GENMASK(15, 6)) >> 6; | 1201 | info->stride_val = (dword1 & GENMASK(15, 6)) >> 6; |
@@ -1348,10 +1358,13 @@ static unsigned long get_gma_bb_from_cmd(struct parser_exec_state *s, int index) | |||
1348 | { | 1358 | { |
1349 | unsigned long addr; | 1359 | unsigned long addr; |
1350 | unsigned long gma_high, gma_low; | 1360 | unsigned long gma_high, gma_low; |
1351 | int gmadr_bytes = s->vgpu->gvt->device_info.gmadr_bytes_in_cmd; | 1361 | struct intel_vgpu *vgpu = s->vgpu; |
1362 | int gmadr_bytes = vgpu->gvt->device_info.gmadr_bytes_in_cmd; | ||
1352 | 1363 | ||
1353 | if (WARN_ON(gmadr_bytes != 4 && gmadr_bytes != 8)) | 1364 | if (WARN_ON(gmadr_bytes != 4 && gmadr_bytes != 8)) { |
1365 | gvt_vgpu_err("invalid gma bytes %d\n", gmadr_bytes); | ||
1354 | return INTEL_GVT_INVALID_ADDR; | 1366 | return INTEL_GVT_INVALID_ADDR; |
1367 | } | ||
1355 | 1368 | ||
1356 | gma_low = cmd_val(s, index) & BATCH_BUFFER_ADDR_MASK; | 1369 | gma_low = cmd_val(s, index) & BATCH_BUFFER_ADDR_MASK; |
1357 | if (gmadr_bytes == 4) { | 1370 | if (gmadr_bytes == 4) { |
@@ -1374,16 +1387,16 @@ static inline int cmd_address_audit(struct parser_exec_state *s, | |||
1374 | if (op_size > max_surface_size) { | 1387 | if (op_size > max_surface_size) { |
1375 | gvt_vgpu_err("command address audit fail name %s\n", | 1388 | gvt_vgpu_err("command address audit fail name %s\n", |
1376 | s->info->name); | 1389 | s->info->name); |
1377 | return -EINVAL; | 1390 | return -EFAULT; |
1378 | } | 1391 | } |
1379 | 1392 | ||
1380 | if (index_mode) { | 1393 | if (index_mode) { |
1381 | if (guest_gma >= GTT_PAGE_SIZE / sizeof(u64)) { | 1394 | if (guest_gma >= I915_GTT_PAGE_SIZE / sizeof(u64)) { |
1382 | ret = -EINVAL; | 1395 | ret = -EFAULT; |
1383 | goto err; | 1396 | goto err; |
1384 | } | 1397 | } |
1385 | } else if (!intel_gvt_ggtt_validate_range(vgpu, guest_gma, op_size)) { | 1398 | } else if (!intel_gvt_ggtt_validate_range(vgpu, guest_gma, op_size)) { |
1386 | ret = -EINVAL; | 1399 | ret = -EFAULT; |
1387 | goto err; | 1400 | goto err; |
1388 | } | 1401 | } |
1389 | 1402 | ||
@@ -1439,7 +1452,7 @@ static inline int unexpected_cmd(struct parser_exec_state *s) | |||
1439 | 1452 | ||
1440 | gvt_vgpu_err("Unexpected %s in command buffer!\n", s->info->name); | 1453 | gvt_vgpu_err("Unexpected %s in command buffer!\n", s->info->name); |
1441 | 1454 | ||
1442 | return -EINVAL; | 1455 | return -EBADRQC; |
1443 | } | 1456 | } |
1444 | 1457 | ||
1445 | static int cmd_handler_mi_semaphore_wait(struct parser_exec_state *s) | 1458 | static int cmd_handler_mi_semaphore_wait(struct parser_exec_state *s) |
@@ -1545,10 +1558,10 @@ static int copy_gma_to_hva(struct intel_vgpu *vgpu, struct intel_vgpu_mm *mm, | |||
1545 | return -EFAULT; | 1558 | return -EFAULT; |
1546 | } | 1559 | } |
1547 | 1560 | ||
1548 | offset = gma & (GTT_PAGE_SIZE - 1); | 1561 | offset = gma & (I915_GTT_PAGE_SIZE - 1); |
1549 | 1562 | ||
1550 | copy_len = (end_gma - gma) >= (GTT_PAGE_SIZE - offset) ? | 1563 | copy_len = (end_gma - gma) >= (I915_GTT_PAGE_SIZE - offset) ? |
1551 | GTT_PAGE_SIZE - offset : end_gma - gma; | 1564 | I915_GTT_PAGE_SIZE - offset : end_gma - gma; |
1552 | 1565 | ||
1553 | intel_gvt_hypervisor_read_gpa(vgpu, gpa, va + len, copy_len); | 1566 | intel_gvt_hypervisor_read_gpa(vgpu, gpa, va + len, copy_len); |
1554 | 1567 | ||
@@ -1576,110 +1589,113 @@ static int batch_buffer_needs_scan(struct parser_exec_state *s) | |||
1576 | return 1; | 1589 | return 1; |
1577 | } | 1590 | } |
1578 | 1591 | ||
1579 | static int find_bb_size(struct parser_exec_state *s) | 1592 | static int find_bb_size(struct parser_exec_state *s, unsigned long *bb_size) |
1580 | { | 1593 | { |
1581 | unsigned long gma = 0; | 1594 | unsigned long gma = 0; |
1582 | struct cmd_info *info; | 1595 | struct cmd_info *info; |
1583 | int bb_size = 0; | ||
1584 | uint32_t cmd_len = 0; | 1596 | uint32_t cmd_len = 0; |
1585 | bool met_bb_end = false; | 1597 | bool bb_end = false; |
1586 | struct intel_vgpu *vgpu = s->vgpu; | 1598 | struct intel_vgpu *vgpu = s->vgpu; |
1587 | u32 cmd; | 1599 | u32 cmd; |
1588 | 1600 | ||
1601 | *bb_size = 0; | ||
1602 | |||
1589 | /* get the start gm address of the batch buffer */ | 1603 | /* get the start gm address of the batch buffer */ |
1590 | gma = get_gma_bb_from_cmd(s, 1); | 1604 | gma = get_gma_bb_from_cmd(s, 1); |
1591 | cmd = cmd_val(s, 0); | 1605 | if (gma == INTEL_GVT_INVALID_ADDR) |
1606 | return -EFAULT; | ||
1592 | 1607 | ||
1608 | cmd = cmd_val(s, 0); | ||
1593 | info = get_cmd_info(s->vgpu->gvt, cmd, s->ring_id); | 1609 | info = get_cmd_info(s->vgpu->gvt, cmd, s->ring_id); |
1594 | if (info == NULL) { | 1610 | if (info == NULL) { |
1595 | gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x\n", | 1611 | gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x\n", |
1596 | cmd, get_opcode(cmd, s->ring_id)); | 1612 | cmd, get_opcode(cmd, s->ring_id)); |
1597 | return -EINVAL; | 1613 | return -EBADRQC; |
1598 | } | 1614 | } |
1599 | do { | 1615 | do { |
1600 | copy_gma_to_hva(s->vgpu, s->vgpu->gtt.ggtt_mm, | 1616 | if (copy_gma_to_hva(s->vgpu, s->vgpu->gtt.ggtt_mm, |
1601 | gma, gma + 4, &cmd); | 1617 | gma, gma + 4, &cmd) < 0) |
1618 | return -EFAULT; | ||
1602 | info = get_cmd_info(s->vgpu->gvt, cmd, s->ring_id); | 1619 | info = get_cmd_info(s->vgpu->gvt, cmd, s->ring_id); |
1603 | if (info == NULL) { | 1620 | if (info == NULL) { |
1604 | gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x\n", | 1621 | gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x\n", |
1605 | cmd, get_opcode(cmd, s->ring_id)); | 1622 | cmd, get_opcode(cmd, s->ring_id)); |
1606 | return -EINVAL; | 1623 | return -EBADRQC; |
1607 | } | 1624 | } |
1608 | 1625 | ||
1609 | if (info->opcode == OP_MI_BATCH_BUFFER_END) { | 1626 | if (info->opcode == OP_MI_BATCH_BUFFER_END) { |
1610 | met_bb_end = true; | 1627 | bb_end = true; |
1611 | } else if (info->opcode == OP_MI_BATCH_BUFFER_START) { | 1628 | } else if (info->opcode == OP_MI_BATCH_BUFFER_START) { |
1612 | if (BATCH_BUFFER_2ND_LEVEL_BIT(cmd) == 0) { | 1629 | if (BATCH_BUFFER_2ND_LEVEL_BIT(cmd) == 0) |
1613 | /* chained batch buffer */ | 1630 | /* chained batch buffer */ |
1614 | met_bb_end = true; | 1631 | bb_end = true; |
1615 | } | ||
1616 | } | 1632 | } |
1617 | cmd_len = get_cmd_length(info, cmd) << 2; | 1633 | cmd_len = get_cmd_length(info, cmd) << 2; |
1618 | bb_size += cmd_len; | 1634 | *bb_size += cmd_len; |
1619 | gma += cmd_len; | 1635 | gma += cmd_len; |
1636 | } while (!bb_end); | ||
1620 | 1637 | ||
1621 | } while (!met_bb_end); | 1638 | return 0; |
1622 | |||
1623 | return bb_size; | ||
1624 | } | 1639 | } |
1625 | 1640 | ||
1626 | static int perform_bb_shadow(struct parser_exec_state *s) | 1641 | static int perform_bb_shadow(struct parser_exec_state *s) |
1627 | { | 1642 | { |
1628 | struct intel_shadow_bb_entry *entry_obj; | ||
1629 | struct intel_vgpu *vgpu = s->vgpu; | 1643 | struct intel_vgpu *vgpu = s->vgpu; |
1644 | struct intel_vgpu_shadow_bb *bb; | ||
1630 | unsigned long gma = 0; | 1645 | unsigned long gma = 0; |
1631 | int bb_size; | 1646 | unsigned long bb_size; |
1632 | void *dst = NULL; | ||
1633 | int ret = 0; | 1647 | int ret = 0; |
1634 | 1648 | ||
1635 | /* get the start gm address of the batch buffer */ | 1649 | /* get the start gm address of the batch buffer */ |
1636 | gma = get_gma_bb_from_cmd(s, 1); | 1650 | gma = get_gma_bb_from_cmd(s, 1); |
1651 | if (gma == INTEL_GVT_INVALID_ADDR) | ||
1652 | return -EFAULT; | ||
1637 | 1653 | ||
1638 | /* get the size of the batch buffer */ | 1654 | ret = find_bb_size(s, &bb_size); |
1639 | bb_size = find_bb_size(s); | 1655 | if (ret) |
1640 | if (bb_size < 0) | 1656 | return ret; |
1641 | return -EINVAL; | ||
1642 | 1657 | ||
1643 | /* allocate shadow batch buffer */ | 1658 | bb = kzalloc(sizeof(*bb), GFP_KERNEL); |
1644 | entry_obj = kmalloc(sizeof(*entry_obj), GFP_KERNEL); | 1659 | if (!bb) |
1645 | if (entry_obj == NULL) | ||
1646 | return -ENOMEM; | 1660 | return -ENOMEM; |
1647 | 1661 | ||
1648 | entry_obj->obj = | 1662 | bb->obj = i915_gem_object_create(s->vgpu->gvt->dev_priv, |
1649 | i915_gem_object_create(s->vgpu->gvt->dev_priv, | 1663 | roundup(bb_size, PAGE_SIZE)); |
1650 | roundup(bb_size, PAGE_SIZE)); | 1664 | if (IS_ERR(bb->obj)) { |
1651 | if (IS_ERR(entry_obj->obj)) { | 1665 | ret = PTR_ERR(bb->obj); |
1652 | ret = PTR_ERR(entry_obj->obj); | 1666 | goto err_free_bb; |
1653 | goto free_entry; | ||
1654 | } | 1667 | } |
1655 | entry_obj->len = bb_size; | ||
1656 | INIT_LIST_HEAD(&entry_obj->list); | ||
1657 | 1668 | ||
1658 | dst = i915_gem_object_pin_map(entry_obj->obj, I915_MAP_WB); | 1669 | ret = i915_gem_obj_prepare_shmem_write(bb->obj, &bb->clflush); |
1659 | if (IS_ERR(dst)) { | 1670 | if (ret) |
1660 | ret = PTR_ERR(dst); | 1671 | goto err_free_obj; |
1661 | goto put_obj; | ||
1662 | } | ||
1663 | 1672 | ||
1664 | ret = i915_gem_object_set_to_cpu_domain(entry_obj->obj, false); | 1673 | bb->va = i915_gem_object_pin_map(bb->obj, I915_MAP_WB); |
1665 | if (ret) { | 1674 | if (IS_ERR(bb->va)) { |
1666 | gvt_vgpu_err("failed to set shadow batch to CPU\n"); | 1675 | ret = PTR_ERR(bb->va); |
1667 | goto unmap_src; | 1676 | goto err_finish_shmem_access; |
1668 | } | 1677 | } |
1669 | 1678 | ||
1670 | entry_obj->va = dst; | 1679 | if (bb->clflush & CLFLUSH_BEFORE) { |
1671 | entry_obj->bb_start_cmd_va = s->ip_va; | 1680 | drm_clflush_virt_range(bb->va, bb->obj->base.size); |
1681 | bb->clflush &= ~CLFLUSH_BEFORE; | ||
1682 | } | ||
1672 | 1683 | ||
1673 | /* copy batch buffer to shadow batch buffer*/ | ||
1674 | ret = copy_gma_to_hva(s->vgpu, s->vgpu->gtt.ggtt_mm, | 1684 | ret = copy_gma_to_hva(s->vgpu, s->vgpu->gtt.ggtt_mm, |
1675 | gma, gma + bb_size, | 1685 | gma, gma + bb_size, |
1676 | dst); | 1686 | bb->va); |
1677 | if (ret < 0) { | 1687 | if (ret < 0) { |
1678 | gvt_vgpu_err("fail to copy guest ring buffer\n"); | 1688 | gvt_vgpu_err("fail to copy guest ring buffer\n"); |
1679 | goto unmap_src; | 1689 | ret = -EFAULT; |
1690 | goto err_unmap; | ||
1680 | } | 1691 | } |
1681 | 1692 | ||
1682 | list_add(&entry_obj->list, &s->workload->shadow_bb); | 1693 | INIT_LIST_HEAD(&bb->list); |
1694 | list_add(&bb->list, &s->workload->shadow_bb); | ||
1695 | |||
1696 | bb->accessing = true; | ||
1697 | bb->bb_start_cmd_va = s->ip_va; | ||
1698 | |||
1683 | /* | 1699 | /* |
1684 | * ip_va saves the virtual address of the shadow batch buffer, while | 1700 | * ip_va saves the virtual address of the shadow batch buffer, while |
1685 | * ip_gma saves the graphics address of the original batch buffer. | 1701 | * ip_gma saves the graphics address of the original batch buffer. |
@@ -1688,17 +1704,17 @@ static int perform_bb_shadow(struct parser_exec_state *s) | |||
1688 | * buffer's gma in pair. After all, we don't want to pin the shadow | 1704 | * buffer's gma in pair. After all, we don't want to pin the shadow |
1689 | * buffer here (too early). | 1705 | * buffer here (too early). |
1690 | */ | 1706 | */ |
1691 | s->ip_va = dst; | 1707 | s->ip_va = bb->va; |
1692 | s->ip_gma = gma; | 1708 | s->ip_gma = gma; |
1693 | |||
1694 | return 0; | 1709 | return 0; |
1695 | 1710 | err_unmap: | |
1696 | unmap_src: | 1711 | i915_gem_object_unpin_map(bb->obj); |
1697 | i915_gem_object_unpin_map(entry_obj->obj); | 1712 | err_finish_shmem_access: |
1698 | put_obj: | 1713 | i915_gem_obj_finish_shmem_access(bb->obj); |
1699 | i915_gem_object_put(entry_obj->obj); | 1714 | err_free_obj: |
1700 | free_entry: | 1715 | i915_gem_object_put(bb->obj); |
1701 | kfree(entry_obj); | 1716 | err_free_bb: |
1717 | kfree(bb); | ||
1702 | return ret; | 1718 | return ret; |
1703 | } | 1719 | } |
1704 | 1720 | ||
@@ -1710,13 +1726,13 @@ static int cmd_handler_mi_batch_buffer_start(struct parser_exec_state *s) | |||
1710 | 1726 | ||
1711 | if (s->buf_type == BATCH_BUFFER_2ND_LEVEL) { | 1727 | if (s->buf_type == BATCH_BUFFER_2ND_LEVEL) { |
1712 | gvt_vgpu_err("Found MI_BATCH_BUFFER_START in 2nd level BB\n"); | 1728 | gvt_vgpu_err("Found MI_BATCH_BUFFER_START in 2nd level BB\n"); |
1713 | return -EINVAL; | 1729 | return -EFAULT; |
1714 | } | 1730 | } |
1715 | 1731 | ||
1716 | second_level = BATCH_BUFFER_2ND_LEVEL_BIT(cmd_val(s, 0)) == 1; | 1732 | second_level = BATCH_BUFFER_2ND_LEVEL_BIT(cmd_val(s, 0)) == 1; |
1717 | if (second_level && (s->buf_type != BATCH_BUFFER_INSTRUCTION)) { | 1733 | if (second_level && (s->buf_type != BATCH_BUFFER_INSTRUCTION)) { |
1718 | gvt_vgpu_err("Jumping to 2nd level BB from RB is not allowed\n"); | 1734 | gvt_vgpu_err("Jumping to 2nd level BB from RB is not allowed\n"); |
1719 | return -EINVAL; | 1735 | return -EFAULT; |
1720 | } | 1736 | } |
1721 | 1737 | ||
1722 | s->saved_buf_addr_type = s->buf_addr_type; | 1738 | s->saved_buf_addr_type = s->buf_addr_type; |
@@ -1740,7 +1756,6 @@ static int cmd_handler_mi_batch_buffer_start(struct parser_exec_state *s) | |||
1740 | if (ret < 0) | 1756 | if (ret < 0) |
1741 | return ret; | 1757 | return ret; |
1742 | } | 1758 | } |
1743 | |||
1744 | return ret; | 1759 | return ret; |
1745 | } | 1760 | } |
1746 | 1761 | ||
@@ -2430,7 +2445,7 @@ static int cmd_parser_exec(struct parser_exec_state *s) | |||
2430 | if (info == NULL) { | 2445 | if (info == NULL) { |
2431 | gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x\n", | 2446 | gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x\n", |
2432 | cmd, get_opcode(cmd, s->ring_id)); | 2447 | cmd, get_opcode(cmd, s->ring_id)); |
2433 | return -EINVAL; | 2448 | return -EBADRQC; |
2434 | } | 2449 | } |
2435 | 2450 | ||
2436 | s->info = info; | 2451 | s->info = info; |
@@ -2465,6 +2480,10 @@ static inline bool gma_out_of_range(unsigned long gma, | |||
2465 | return (gma > gma_tail) && (gma < gma_head); | 2480 | return (gma > gma_tail) && (gma < gma_head); |
2466 | } | 2481 | } |
2467 | 2482 | ||
2483 | /* Keep the consistent return type, e.g EBADRQC for unknown | ||
2484 | * cmd, EFAULT for invalid address, EPERM for nonpriv. later | ||
2485 | * works as the input of VM healthy status. | ||
2486 | */ | ||
2468 | static int command_scan(struct parser_exec_state *s, | 2487 | static int command_scan(struct parser_exec_state *s, |
2469 | unsigned long rb_head, unsigned long rb_tail, | 2488 | unsigned long rb_head, unsigned long rb_tail, |
2470 | unsigned long rb_start, unsigned long rb_len) | 2489 | unsigned long rb_start, unsigned long rb_len) |
@@ -2487,7 +2506,7 @@ static int command_scan(struct parser_exec_state *s, | |||
2487 | s->ip_gma, rb_start, | 2506 | s->ip_gma, rb_start, |
2488 | gma_bottom); | 2507 | gma_bottom); |
2489 | parser_exec_state_dump(s); | 2508 | parser_exec_state_dump(s); |
2490 | return -EINVAL; | 2509 | return -EFAULT; |
2491 | } | 2510 | } |
2492 | if (gma_out_of_range(s->ip_gma, gma_head, gma_tail)) { | 2511 | if (gma_out_of_range(s->ip_gma, gma_head, gma_tail)) { |
2493 | gvt_vgpu_err("ip_gma %lx out of range." | 2512 | gvt_vgpu_err("ip_gma %lx out of range." |
@@ -2516,7 +2535,7 @@ static int scan_workload(struct intel_vgpu_workload *workload) | |||
2516 | int ret = 0; | 2535 | int ret = 0; |
2517 | 2536 | ||
2518 | /* ring base is page aligned */ | 2537 | /* ring base is page aligned */ |
2519 | if (WARN_ON(!IS_ALIGNED(workload->rb_start, GTT_PAGE_SIZE))) | 2538 | if (WARN_ON(!IS_ALIGNED(workload->rb_start, I915_GTT_PAGE_SIZE))) |
2520 | return -EINVAL; | 2539 | return -EINVAL; |
2521 | 2540 | ||
2522 | gma_head = workload->rb_start + workload->rb_head; | 2541 | gma_head = workload->rb_start + workload->rb_head; |
@@ -2565,7 +2584,8 @@ static int scan_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx) | |||
2565 | wa_ctx); | 2584 | wa_ctx); |
2566 | 2585 | ||
2567 | /* ring base is page aligned */ | 2586 | /* ring base is page aligned */ |
2568 | if (WARN_ON(!IS_ALIGNED(wa_ctx->indirect_ctx.guest_gma, GTT_PAGE_SIZE))) | 2587 | if (WARN_ON(!IS_ALIGNED(wa_ctx->indirect_ctx.guest_gma, |
2588 | I915_GTT_PAGE_SIZE))) | ||
2569 | return -EINVAL; | 2589 | return -EINVAL; |
2570 | 2590 | ||
2571 | ring_tail = wa_ctx->indirect_ctx.size + 3 * sizeof(uint32_t); | 2591 | ring_tail = wa_ctx->indirect_ctx.size + 3 * sizeof(uint32_t); |
@@ -2604,6 +2624,7 @@ out: | |||
2604 | static int shadow_workload_ring_buffer(struct intel_vgpu_workload *workload) | 2624 | static int shadow_workload_ring_buffer(struct intel_vgpu_workload *workload) |
2605 | { | 2625 | { |
2606 | struct intel_vgpu *vgpu = workload->vgpu; | 2626 | struct intel_vgpu *vgpu = workload->vgpu; |
2627 | struct intel_vgpu_submission *s = &vgpu->submission; | ||
2607 | unsigned long gma_head, gma_tail, gma_top, guest_rb_size; | 2628 | unsigned long gma_head, gma_tail, gma_top, guest_rb_size; |
2608 | void *shadow_ring_buffer_va; | 2629 | void *shadow_ring_buffer_va; |
2609 | int ring_id = workload->ring_id; | 2630 | int ring_id = workload->ring_id; |
@@ -2619,19 +2640,21 @@ static int shadow_workload_ring_buffer(struct intel_vgpu_workload *workload) | |||
2619 | gma_tail = workload->rb_start + workload->rb_tail; | 2640 | gma_tail = workload->rb_start + workload->rb_tail; |
2620 | gma_top = workload->rb_start + guest_rb_size; | 2641 | gma_top = workload->rb_start + guest_rb_size; |
2621 | 2642 | ||
2622 | if (workload->rb_len > vgpu->reserve_ring_buffer_size[ring_id]) { | 2643 | if (workload->rb_len > s->ring_scan_buffer_size[ring_id]) { |
2623 | void *va = vgpu->reserve_ring_buffer_va[ring_id]; | 2644 | void *p; |
2645 | |||
2624 | /* realloc the new ring buffer if needed */ | 2646 | /* realloc the new ring buffer if needed */ |
2625 | vgpu->reserve_ring_buffer_va[ring_id] = | 2647 | p = krealloc(s->ring_scan_buffer[ring_id], workload->rb_len, |
2626 | krealloc(va, workload->rb_len, GFP_KERNEL); | 2648 | GFP_KERNEL); |
2627 | if (!vgpu->reserve_ring_buffer_va[ring_id]) { | 2649 | if (!p) { |
2628 | gvt_vgpu_err("fail to alloc reserve ring buffer\n"); | 2650 | gvt_vgpu_err("fail to re-alloc ring scan buffer\n"); |
2629 | return -ENOMEM; | 2651 | return -ENOMEM; |
2630 | } | 2652 | } |
2631 | vgpu->reserve_ring_buffer_size[ring_id] = workload->rb_len; | 2653 | s->ring_scan_buffer[ring_id] = p; |
2654 | s->ring_scan_buffer_size[ring_id] = workload->rb_len; | ||
2632 | } | 2655 | } |
2633 | 2656 | ||
2634 | shadow_ring_buffer_va = vgpu->reserve_ring_buffer_va[ring_id]; | 2657 | shadow_ring_buffer_va = s->ring_scan_buffer[ring_id]; |
2635 | 2658 | ||
2636 | /* get shadow ring buffer va */ | 2659 | /* get shadow ring buffer va */ |
2637 | workload->shadow_ring_buffer_va = shadow_ring_buffer_va; | 2660 | workload->shadow_ring_buffer_va = shadow_ring_buffer_va; |
diff --git a/drivers/gpu/drm/i915/gvt/debug.h b/drivers/gpu/drm/i915/gvt/debug.h index b0cff4dc2684..c6027125c1ec 100644 --- a/drivers/gpu/drm/i915/gvt/debug.h +++ b/drivers/gpu/drm/i915/gvt/debug.h | |||
@@ -25,41 +25,41 @@ | |||
25 | #define __GVT_DEBUG_H__ | 25 | #define __GVT_DEBUG_H__ |
26 | 26 | ||
27 | #define gvt_err(fmt, args...) \ | 27 | #define gvt_err(fmt, args...) \ |
28 | DRM_ERROR("gvt: "fmt, ##args) | 28 | pr_err("gvt: "fmt, ##args) |
29 | 29 | ||
30 | #define gvt_vgpu_err(fmt, args...) \ | 30 | #define gvt_vgpu_err(fmt, args...) \ |
31 | do { \ | 31 | do { \ |
32 | if (IS_ERR_OR_NULL(vgpu)) \ | 32 | if (IS_ERR_OR_NULL(vgpu)) \ |
33 | DRM_DEBUG_DRIVER("gvt: "fmt, ##args); \ | 33 | pr_err("gvt: "fmt, ##args); \ |
34 | else \ | 34 | else \ |
35 | DRM_DEBUG_DRIVER("gvt: vgpu %d: "fmt, vgpu->id, ##args);\ | 35 | pr_err("gvt: vgpu %d: "fmt, vgpu->id, ##args);\ |
36 | } while (0) | 36 | } while (0) |
37 | 37 | ||
38 | #define gvt_dbg_core(fmt, args...) \ | 38 | #define gvt_dbg_core(fmt, args...) \ |
39 | DRM_DEBUG_DRIVER("gvt: core: "fmt, ##args) | 39 | pr_debug("gvt: core: "fmt, ##args) |
40 | 40 | ||
41 | #define gvt_dbg_irq(fmt, args...) \ | 41 | #define gvt_dbg_irq(fmt, args...) \ |
42 | DRM_DEBUG_DRIVER("gvt: irq: "fmt, ##args) | 42 | pr_debug("gvt: irq: "fmt, ##args) |
43 | 43 | ||
44 | #define gvt_dbg_mm(fmt, args...) \ | 44 | #define gvt_dbg_mm(fmt, args...) \ |
45 | DRM_DEBUG_DRIVER("gvt: mm: "fmt, ##args) | 45 | pr_debug("gvt: mm: "fmt, ##args) |
46 | 46 | ||
47 | #define gvt_dbg_mmio(fmt, args...) \ | 47 | #define gvt_dbg_mmio(fmt, args...) \ |
48 | DRM_DEBUG_DRIVER("gvt: mmio: "fmt, ##args) | 48 | pr_debug("gvt: mmio: "fmt, ##args) |
49 | 49 | ||
50 | #define gvt_dbg_dpy(fmt, args...) \ | 50 | #define gvt_dbg_dpy(fmt, args...) \ |
51 | DRM_DEBUG_DRIVER("gvt: dpy: "fmt, ##args) | 51 | pr_debug("gvt: dpy: "fmt, ##args) |
52 | 52 | ||
53 | #define gvt_dbg_el(fmt, args...) \ | 53 | #define gvt_dbg_el(fmt, args...) \ |
54 | DRM_DEBUG_DRIVER("gvt: el: "fmt, ##args) | 54 | pr_debug("gvt: el: "fmt, ##args) |
55 | 55 | ||
56 | #define gvt_dbg_sched(fmt, args...) \ | 56 | #define gvt_dbg_sched(fmt, args...) \ |
57 | DRM_DEBUG_DRIVER("gvt: sched: "fmt, ##args) | 57 | pr_debug("gvt: sched: "fmt, ##args) |
58 | 58 | ||
59 | #define gvt_dbg_render(fmt, args...) \ | 59 | #define gvt_dbg_render(fmt, args...) \ |
60 | DRM_DEBUG_DRIVER("gvt: render: "fmt, ##args) | 60 | pr_debug("gvt: render: "fmt, ##args) |
61 | 61 | ||
62 | #define gvt_dbg_cmd(fmt, args...) \ | 62 | #define gvt_dbg_cmd(fmt, args...) \ |
63 | DRM_DEBUG_DRIVER("gvt: cmd: "fmt, ##args) | 63 | pr_debug("gvt: cmd: "fmt, ##args) |
64 | 64 | ||
65 | #endif | 65 | #endif |
diff --git a/drivers/gpu/drm/i915/gvt/debugfs.c b/drivers/gpu/drm/i915/gvt/debugfs.c new file mode 100644 index 000000000000..32a66dfdf112 --- /dev/null +++ b/drivers/gpu/drm/i915/gvt/debugfs.c | |||
@@ -0,0 +1,212 @@ | |||
1 | /* | ||
2 | * Copyright(c) 2011-2017 Intel Corporation. All rights reserved. | ||
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 FROM, | ||
20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
21 | * SOFTWARE. | ||
22 | */ | ||
23 | #include <linux/debugfs.h> | ||
24 | #include <linux/list_sort.h> | ||
25 | #include "i915_drv.h" | ||
26 | #include "gvt.h" | ||
27 | |||
28 | struct mmio_diff_param { | ||
29 | struct intel_vgpu *vgpu; | ||
30 | int total; | ||
31 | int diff; | ||
32 | struct list_head diff_mmio_list; | ||
33 | }; | ||
34 | |||
35 | struct diff_mmio { | ||
36 | struct list_head node; | ||
37 | u32 offset; | ||
38 | u32 preg; | ||
39 | u32 vreg; | ||
40 | }; | ||
41 | |||
42 | /* Compare two diff_mmio items. */ | ||
43 | static int mmio_offset_compare(void *priv, | ||
44 | struct list_head *a, struct list_head *b) | ||
45 | { | ||
46 | struct diff_mmio *ma; | ||
47 | struct diff_mmio *mb; | ||
48 | |||
49 | ma = container_of(a, struct diff_mmio, node); | ||
50 | mb = container_of(b, struct diff_mmio, node); | ||
51 | if (ma->offset < mb->offset) | ||
52 | return -1; | ||
53 | else if (ma->offset > mb->offset) | ||
54 | return 1; | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | static inline int mmio_diff_handler(struct intel_gvt *gvt, | ||
59 | u32 offset, void *data) | ||
60 | { | ||
61 | struct drm_i915_private *dev_priv = gvt->dev_priv; | ||
62 | struct mmio_diff_param *param = data; | ||
63 | struct diff_mmio *node; | ||
64 | u32 preg, vreg; | ||
65 | |||
66 | preg = I915_READ_NOTRACE(_MMIO(offset)); | ||
67 | vreg = vgpu_vreg(param->vgpu, offset); | ||
68 | |||
69 | if (preg != vreg) { | ||
70 | node = kmalloc(sizeof(*node), GFP_KERNEL); | ||
71 | if (!node) | ||
72 | return -ENOMEM; | ||
73 | |||
74 | node->offset = offset; | ||
75 | node->preg = preg; | ||
76 | node->vreg = vreg; | ||
77 | list_add(&node->node, ¶m->diff_mmio_list); | ||
78 | param->diff++; | ||
79 | } | ||
80 | param->total++; | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | /* Show the all the different values of tracked mmio. */ | ||
85 | static int vgpu_mmio_diff_show(struct seq_file *s, void *unused) | ||
86 | { | ||
87 | struct intel_vgpu *vgpu = s->private; | ||
88 | struct intel_gvt *gvt = vgpu->gvt; | ||
89 | struct mmio_diff_param param = { | ||
90 | .vgpu = vgpu, | ||
91 | .total = 0, | ||
92 | .diff = 0, | ||
93 | }; | ||
94 | struct diff_mmio *node, *next; | ||
95 | |||
96 | INIT_LIST_HEAD(¶m.diff_mmio_list); | ||
97 | |||
98 | mutex_lock(&gvt->lock); | ||
99 | spin_lock_bh(&gvt->scheduler.mmio_context_lock); | ||
100 | |||
101 | mmio_hw_access_pre(gvt->dev_priv); | ||
102 | /* Recognize all the diff mmios to list. */ | ||
103 | intel_gvt_for_each_tracked_mmio(gvt, mmio_diff_handler, ¶m); | ||
104 | mmio_hw_access_post(gvt->dev_priv); | ||
105 | |||
106 | spin_unlock_bh(&gvt->scheduler.mmio_context_lock); | ||
107 | mutex_unlock(&gvt->lock); | ||
108 | |||
109 | /* In an ascending order by mmio offset. */ | ||
110 | list_sort(NULL, ¶m.diff_mmio_list, mmio_offset_compare); | ||
111 | |||
112 | seq_printf(s, "%-8s %-8s %-8s %-8s\n", "Offset", "HW", "vGPU", "Diff"); | ||
113 | list_for_each_entry_safe(node, next, ¶m.diff_mmio_list, node) { | ||
114 | u32 diff = node->preg ^ node->vreg; | ||
115 | |||
116 | seq_printf(s, "%08x %08x %08x %*pbl\n", | ||
117 | node->offset, node->preg, node->vreg, | ||
118 | 32, &diff); | ||
119 | list_del(&node->node); | ||
120 | kfree(node); | ||
121 | } | ||
122 | seq_printf(s, "Total: %d, Diff: %d\n", param.total, param.diff); | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static int vgpu_mmio_diff_open(struct inode *inode, struct file *file) | ||
127 | { | ||
128 | return single_open(file, vgpu_mmio_diff_show, inode->i_private); | ||
129 | } | ||
130 | |||
131 | static const struct file_operations vgpu_mmio_diff_fops = { | ||
132 | .open = vgpu_mmio_diff_open, | ||
133 | .read = seq_read, | ||
134 | .llseek = seq_lseek, | ||
135 | .release = single_release, | ||
136 | }; | ||
137 | |||
138 | /** | ||
139 | * intel_gvt_debugfs_add_vgpu - register debugfs entries for a vGPU | ||
140 | * @vgpu: a vGPU | ||
141 | * | ||
142 | * Returns: | ||
143 | * Zero on success, negative error code if failed. | ||
144 | */ | ||
145 | int intel_gvt_debugfs_add_vgpu(struct intel_vgpu *vgpu) | ||
146 | { | ||
147 | struct dentry *ent; | ||
148 | char name[10] = ""; | ||
149 | |||
150 | sprintf(name, "vgpu%d", vgpu->id); | ||
151 | vgpu->debugfs = debugfs_create_dir(name, vgpu->gvt->debugfs_root); | ||
152 | if (!vgpu->debugfs) | ||
153 | return -ENOMEM; | ||
154 | |||
155 | ent = debugfs_create_bool("active", 0444, vgpu->debugfs, | ||
156 | &vgpu->active); | ||
157 | if (!ent) | ||
158 | return -ENOMEM; | ||
159 | |||
160 | ent = debugfs_create_file("mmio_diff", 0444, vgpu->debugfs, | ||
161 | vgpu, &vgpu_mmio_diff_fops); | ||
162 | if (!ent) | ||
163 | return -ENOMEM; | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | /** | ||
169 | * intel_gvt_debugfs_remove_vgpu - remove debugfs entries of a vGPU | ||
170 | * @vgpu: a vGPU | ||
171 | */ | ||
172 | void intel_gvt_debugfs_remove_vgpu(struct intel_vgpu *vgpu) | ||
173 | { | ||
174 | debugfs_remove_recursive(vgpu->debugfs); | ||
175 | vgpu->debugfs = NULL; | ||
176 | } | ||
177 | |||
178 | /** | ||
179 | * intel_gvt_debugfs_init - register gvt debugfs root entry | ||
180 | * @gvt: GVT device | ||
181 | * | ||
182 | * Returns: | ||
183 | * zero on success, negative if failed. | ||
184 | */ | ||
185 | int intel_gvt_debugfs_init(struct intel_gvt *gvt) | ||
186 | { | ||
187 | struct drm_minor *minor = gvt->dev_priv->drm.primary; | ||
188 | struct dentry *ent; | ||
189 | |||
190 | gvt->debugfs_root = debugfs_create_dir("gvt", minor->debugfs_root); | ||
191 | if (!gvt->debugfs_root) { | ||
192 | gvt_err("Cannot create debugfs dir\n"); | ||
193 | return -ENOMEM; | ||
194 | } | ||
195 | |||
196 | ent = debugfs_create_ulong("num_tracked_mmio", 0444, gvt->debugfs_root, | ||
197 | &gvt->mmio.num_tracked_mmio); | ||
198 | if (!ent) | ||
199 | return -ENOMEM; | ||
200 | |||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | /** | ||
205 | * intel_gvt_debugfs_clean - remove debugfs entries | ||
206 | * @gvt: GVT device | ||
207 | */ | ||
208 | void intel_gvt_debugfs_clean(struct intel_gvt *gvt) | ||
209 | { | ||
210 | debugfs_remove_recursive(gvt->debugfs_root); | ||
211 | gvt->debugfs_root = NULL; | ||
212 | } | ||
diff --git a/drivers/gpu/drm/i915/gvt/execlist.c b/drivers/gpu/drm/i915/gvt/execlist.c index 940cdaaa3f24..c9fa0fb488d3 100644 --- a/drivers/gpu/drm/i915/gvt/execlist.c +++ b/drivers/gpu/drm/i915/gvt/execlist.c | |||
@@ -46,8 +46,6 @@ | |||
46 | #define same_context(a, b) (((a)->context_id == (b)->context_id) && \ | 46 | #define same_context(a, b) (((a)->context_id == (b)->context_id) && \ |
47 | ((a)->lrca == (b)->lrca)) | 47 | ((a)->lrca == (b)->lrca)) |
48 | 48 | ||
49 | static void clean_workloads(struct intel_vgpu *vgpu, unsigned long engine_mask); | ||
50 | |||
51 | static int context_switch_events[] = { | 49 | static int context_switch_events[] = { |
52 | [RCS] = RCS_AS_CONTEXT_SWITCH, | 50 | [RCS] = RCS_AS_CONTEXT_SWITCH, |
53 | [BCS] = BCS_AS_CONTEXT_SWITCH, | 51 | [BCS] = BCS_AS_CONTEXT_SWITCH, |
@@ -135,6 +133,8 @@ static void emulate_csb_update(struct intel_vgpu_execlist *execlist, | |||
135 | struct execlist_context_status_pointer_format ctx_status_ptr; | 133 | struct execlist_context_status_pointer_format ctx_status_ptr; |
136 | u32 write_pointer; | 134 | u32 write_pointer; |
137 | u32 ctx_status_ptr_reg, ctx_status_buf_reg, offset; | 135 | u32 ctx_status_ptr_reg, ctx_status_buf_reg, offset; |
136 | unsigned long hwsp_gpa; | ||
137 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | ||
138 | 138 | ||
139 | ctx_status_ptr_reg = execlist_ring_mmio(vgpu->gvt, ring_id, | 139 | ctx_status_ptr_reg = execlist_ring_mmio(vgpu->gvt, ring_id, |
140 | _EL_OFFSET_STATUS_PTR); | 140 | _EL_OFFSET_STATUS_PTR); |
@@ -160,6 +160,20 @@ static void emulate_csb_update(struct intel_vgpu_execlist *execlist, | |||
160 | ctx_status_ptr.write_ptr = write_pointer; | 160 | ctx_status_ptr.write_ptr = write_pointer; |
161 | vgpu_vreg(vgpu, ctx_status_ptr_reg) = ctx_status_ptr.dw; | 161 | vgpu_vreg(vgpu, ctx_status_ptr_reg) = ctx_status_ptr.dw; |
162 | 162 | ||
163 | /* Update the CSB and CSB write pointer in HWSP */ | ||
164 | hwsp_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, | ||
165 | vgpu->hws_pga[ring_id]); | ||
166 | if (hwsp_gpa != INTEL_GVT_INVALID_ADDR) { | ||
167 | intel_gvt_hypervisor_write_gpa(vgpu, | ||
168 | hwsp_gpa + I915_HWS_CSB_BUF0_INDEX * 4 + | ||
169 | write_pointer * 8, | ||
170 | status, 8); | ||
171 | intel_gvt_hypervisor_write_gpa(vgpu, | ||
172 | hwsp_gpa + | ||
173 | intel_hws_csb_write_index(dev_priv) * 4, | ||
174 | &write_pointer, 4); | ||
175 | } | ||
176 | |||
163 | gvt_dbg_el("vgpu%d: w pointer %u reg %x csb l %x csb h %x\n", | 177 | gvt_dbg_el("vgpu%d: w pointer %u reg %x csb l %x csb h %x\n", |
164 | vgpu->id, write_pointer, offset, status->ldw, status->udw); | 178 | vgpu->id, write_pointer, offset, status->ldw, status->udw); |
165 | 179 | ||
@@ -358,218 +372,47 @@ static int emulate_execlist_schedule_in(struct intel_vgpu_execlist *execlist, | |||
358 | return 0; | 372 | return 0; |
359 | } | 373 | } |
360 | 374 | ||
361 | static void free_workload(struct intel_vgpu_workload *workload) | ||
362 | { | ||
363 | intel_vgpu_unpin_mm(workload->shadow_mm); | ||
364 | intel_gvt_mm_unreference(workload->shadow_mm); | ||
365 | kmem_cache_free(workload->vgpu->workloads, workload); | ||
366 | } | ||
367 | |||
368 | #define get_desc_from_elsp_dwords(ed, i) \ | 375 | #define get_desc_from_elsp_dwords(ed, i) \ |
369 | ((struct execlist_ctx_descriptor_format *)&((ed)->data[i * 2])) | 376 | ((struct execlist_ctx_descriptor_format *)&((ed)->data[i * 2])) |
370 | 377 | ||
371 | static int prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload) | ||
372 | { | ||
373 | const int gmadr_bytes = workload->vgpu->gvt->device_info.gmadr_bytes_in_cmd; | ||
374 | struct intel_shadow_bb_entry *entry_obj; | ||
375 | |||
376 | /* pin the gem object to ggtt */ | ||
377 | list_for_each_entry(entry_obj, &workload->shadow_bb, list) { | ||
378 | struct i915_vma *vma; | ||
379 | |||
380 | vma = i915_gem_object_ggtt_pin(entry_obj->obj, NULL, 0, 4, 0); | ||
381 | if (IS_ERR(vma)) { | ||
382 | return PTR_ERR(vma); | ||
383 | } | ||
384 | |||
385 | /* FIXME: we are not tracking our pinned VMA leaving it | ||
386 | * up to the core to fix up the stray pin_count upon | ||
387 | * free. | ||
388 | */ | ||
389 | |||
390 | /* update the relocate gma with shadow batch buffer*/ | ||
391 | entry_obj->bb_start_cmd_va[1] = i915_ggtt_offset(vma); | ||
392 | if (gmadr_bytes == 8) | ||
393 | entry_obj->bb_start_cmd_va[2] = 0; | ||
394 | } | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static int update_wa_ctx_2_shadow_ctx(struct intel_shadow_wa_ctx *wa_ctx) | ||
399 | { | ||
400 | struct intel_vgpu_workload *workload = container_of(wa_ctx, | ||
401 | struct intel_vgpu_workload, | ||
402 | wa_ctx); | ||
403 | int ring_id = workload->ring_id; | ||
404 | struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx; | ||
405 | struct drm_i915_gem_object *ctx_obj = | ||
406 | shadow_ctx->engine[ring_id].state->obj; | ||
407 | struct execlist_ring_context *shadow_ring_context; | ||
408 | struct page *page; | ||
409 | |||
410 | page = i915_gem_object_get_page(ctx_obj, LRC_STATE_PN); | ||
411 | shadow_ring_context = kmap_atomic(page); | ||
412 | |||
413 | shadow_ring_context->bb_per_ctx_ptr.val = | ||
414 | (shadow_ring_context->bb_per_ctx_ptr.val & | ||
415 | (~PER_CTX_ADDR_MASK)) | wa_ctx->per_ctx.shadow_gma; | ||
416 | shadow_ring_context->rcs_indirect_ctx.val = | ||
417 | (shadow_ring_context->rcs_indirect_ctx.val & | ||
418 | (~INDIRECT_CTX_ADDR_MASK)) | wa_ctx->indirect_ctx.shadow_gma; | ||
419 | |||
420 | kunmap_atomic(shadow_ring_context); | ||
421 | return 0; | ||
422 | } | ||
423 | |||
424 | static int prepare_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx) | ||
425 | { | ||
426 | struct i915_vma *vma; | ||
427 | unsigned char *per_ctx_va = | ||
428 | (unsigned char *)wa_ctx->indirect_ctx.shadow_va + | ||
429 | wa_ctx->indirect_ctx.size; | ||
430 | |||
431 | if (wa_ctx->indirect_ctx.size == 0) | ||
432 | return 0; | ||
433 | |||
434 | vma = i915_gem_object_ggtt_pin(wa_ctx->indirect_ctx.obj, NULL, | ||
435 | 0, CACHELINE_BYTES, 0); | ||
436 | if (IS_ERR(vma)) { | ||
437 | return PTR_ERR(vma); | ||
438 | } | ||
439 | |||
440 | /* FIXME: we are not tracking our pinned VMA leaving it | ||
441 | * up to the core to fix up the stray pin_count upon | ||
442 | * free. | ||
443 | */ | ||
444 | |||
445 | wa_ctx->indirect_ctx.shadow_gma = i915_ggtt_offset(vma); | ||
446 | |||
447 | wa_ctx->per_ctx.shadow_gma = *((unsigned int *)per_ctx_va + 1); | ||
448 | memset(per_ctx_va, 0, CACHELINE_BYTES); | ||
449 | |||
450 | update_wa_ctx_2_shadow_ctx(wa_ctx); | ||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload) | ||
455 | { | ||
456 | /* release all the shadow batch buffer */ | ||
457 | if (!list_empty(&workload->shadow_bb)) { | ||
458 | struct intel_shadow_bb_entry *entry_obj = | ||
459 | list_first_entry(&workload->shadow_bb, | ||
460 | struct intel_shadow_bb_entry, | ||
461 | list); | ||
462 | struct intel_shadow_bb_entry *temp; | ||
463 | |||
464 | list_for_each_entry_safe(entry_obj, temp, &workload->shadow_bb, | ||
465 | list) { | ||
466 | i915_gem_object_unpin_map(entry_obj->obj); | ||
467 | i915_gem_object_put(entry_obj->obj); | ||
468 | list_del(&entry_obj->list); | ||
469 | kfree(entry_obj); | ||
470 | } | ||
471 | } | ||
472 | } | ||
473 | |||
474 | static int prepare_execlist_workload(struct intel_vgpu_workload *workload) | 378 | static int prepare_execlist_workload(struct intel_vgpu_workload *workload) |
475 | { | 379 | { |
476 | struct intel_vgpu *vgpu = workload->vgpu; | 380 | struct intel_vgpu *vgpu = workload->vgpu; |
381 | struct intel_vgpu_submission *s = &vgpu->submission; | ||
477 | struct execlist_ctx_descriptor_format ctx[2]; | 382 | struct execlist_ctx_descriptor_format ctx[2]; |
478 | int ring_id = workload->ring_id; | 383 | int ring_id = workload->ring_id; |
479 | int ret; | 384 | int ret; |
480 | 385 | ||
481 | ret = intel_vgpu_pin_mm(workload->shadow_mm); | ||
482 | if (ret) { | ||
483 | gvt_vgpu_err("fail to vgpu pin mm\n"); | ||
484 | goto out; | ||
485 | } | ||
486 | |||
487 | ret = intel_vgpu_sync_oos_pages(workload->vgpu); | ||
488 | if (ret) { | ||
489 | gvt_vgpu_err("fail to vgpu sync oos pages\n"); | ||
490 | goto err_unpin_mm; | ||
491 | } | ||
492 | |||
493 | ret = intel_vgpu_flush_post_shadow(workload->vgpu); | ||
494 | if (ret) { | ||
495 | gvt_vgpu_err("fail to flush post shadow\n"); | ||
496 | goto err_unpin_mm; | ||
497 | } | ||
498 | |||
499 | ret = intel_gvt_generate_request(workload); | ||
500 | if (ret) { | ||
501 | gvt_vgpu_err("fail to generate request\n"); | ||
502 | goto err_unpin_mm; | ||
503 | } | ||
504 | |||
505 | ret = prepare_shadow_batch_buffer(workload); | ||
506 | if (ret) { | ||
507 | gvt_vgpu_err("fail to prepare_shadow_batch_buffer\n"); | ||
508 | goto err_unpin_mm; | ||
509 | } | ||
510 | |||
511 | ret = prepare_shadow_wa_ctx(&workload->wa_ctx); | ||
512 | if (ret) { | ||
513 | gvt_vgpu_err("fail to prepare_shadow_wa_ctx\n"); | ||
514 | goto err_shadow_batch; | ||
515 | } | ||
516 | |||
517 | if (!workload->emulate_schedule_in) | 386 | if (!workload->emulate_schedule_in) |
518 | return 0; | 387 | return 0; |
519 | 388 | ||
520 | ctx[0] = *get_desc_from_elsp_dwords(&workload->elsp_dwords, 1); | 389 | ctx[0] = *get_desc_from_elsp_dwords(&workload->elsp_dwords, 0); |
521 | ctx[1] = *get_desc_from_elsp_dwords(&workload->elsp_dwords, 0); | 390 | ctx[1] = *get_desc_from_elsp_dwords(&workload->elsp_dwords, 1); |
522 | 391 | ||
523 | ret = emulate_execlist_schedule_in(&vgpu->execlist[ring_id], ctx); | 392 | ret = emulate_execlist_schedule_in(&s->execlist[ring_id], ctx); |
524 | if (!ret) | 393 | if (ret) { |
525 | goto out; | ||
526 | else | ||
527 | gvt_vgpu_err("fail to emulate execlist schedule in\n"); | 394 | gvt_vgpu_err("fail to emulate execlist schedule in\n"); |
528 | 395 | return ret; | |
529 | release_shadow_wa_ctx(&workload->wa_ctx); | 396 | } |
530 | err_shadow_batch: | 397 | return 0; |
531 | release_shadow_batch_buffer(workload); | ||
532 | err_unpin_mm: | ||
533 | intel_vgpu_unpin_mm(workload->shadow_mm); | ||
534 | out: | ||
535 | return ret; | ||
536 | } | 398 | } |
537 | 399 | ||
538 | static int complete_execlist_workload(struct intel_vgpu_workload *workload) | 400 | static int complete_execlist_workload(struct intel_vgpu_workload *workload) |
539 | { | 401 | { |
540 | struct intel_vgpu *vgpu = workload->vgpu; | 402 | struct intel_vgpu *vgpu = workload->vgpu; |
541 | int ring_id = workload->ring_id; | 403 | int ring_id = workload->ring_id; |
542 | struct intel_vgpu_execlist *execlist = &vgpu->execlist[ring_id]; | 404 | struct intel_vgpu_submission *s = &vgpu->submission; |
405 | struct intel_vgpu_execlist *execlist = &s->execlist[ring_id]; | ||
543 | struct intel_vgpu_workload *next_workload; | 406 | struct intel_vgpu_workload *next_workload; |
544 | struct list_head *next = workload_q_head(vgpu, ring_id)->next; | 407 | struct list_head *next = workload_q_head(vgpu, ring_id)->next; |
545 | bool lite_restore = false; | 408 | bool lite_restore = false; |
546 | int ret; | 409 | int ret = 0; |
547 | 410 | ||
548 | gvt_dbg_el("complete workload %p status %d\n", workload, | 411 | gvt_dbg_el("complete workload %p status %d\n", workload, |
549 | workload->status); | 412 | workload->status); |
550 | 413 | ||
551 | if (!workload->status) { | 414 | if (workload->status || (vgpu->resetting_eng & ENGINE_MASK(ring_id))) |
552 | release_shadow_batch_buffer(workload); | ||
553 | release_shadow_wa_ctx(&workload->wa_ctx); | ||
554 | } | ||
555 | |||
556 | if (workload->status || (vgpu->resetting_eng & ENGINE_MASK(ring_id))) { | ||
557 | /* if workload->status is not successful means HW GPU | ||
558 | * has occurred GPU hang or something wrong with i915/GVT, | ||
559 | * and GVT won't inject context switch interrupt to guest. | ||
560 | * So this error is a vGPU hang actually to the guest. | ||
561 | * According to this we should emunlate a vGPU hang. If | ||
562 | * there are pending workloads which are already submitted | ||
563 | * from guest, we should clean them up like HW GPU does. | ||
564 | * | ||
565 | * if it is in middle of engine resetting, the pending | ||
566 | * workloads won't be submitted to HW GPU and will be | ||
567 | * cleaned up during the resetting process later, so doing | ||
568 | * the workload clean up here doesn't have any impact. | ||
569 | **/ | ||
570 | clean_workloads(vgpu, ENGINE_MASK(ring_id)); | ||
571 | goto out; | 415 | goto out; |
572 | } | ||
573 | 416 | ||
574 | if (!list_empty(workload_q_head(vgpu, ring_id))) { | 417 | if (!list_empty(workload_q_head(vgpu, ring_id))) { |
575 | struct execlist_ctx_descriptor_format *this_desc, *next_desc; | 418 | struct execlist_ctx_descriptor_format *this_desc, *next_desc; |
@@ -584,213 +427,60 @@ static int complete_execlist_workload(struct intel_vgpu_workload *workload) | |||
584 | 427 | ||
585 | if (lite_restore) { | 428 | if (lite_restore) { |
586 | gvt_dbg_el("next context == current - no schedule-out\n"); | 429 | gvt_dbg_el("next context == current - no schedule-out\n"); |
587 | free_workload(workload); | 430 | goto out; |
588 | return 0; | ||
589 | } | 431 | } |
590 | 432 | ||
591 | ret = emulate_execlist_ctx_schedule_out(execlist, &workload->ctx_desc); | 433 | ret = emulate_execlist_ctx_schedule_out(execlist, &workload->ctx_desc); |
592 | if (ret) | ||
593 | goto err; | ||
594 | out: | 434 | out: |
595 | free_workload(workload); | 435 | intel_vgpu_unpin_mm(workload->shadow_mm); |
596 | return 0; | 436 | intel_vgpu_destroy_workload(workload); |
597 | err: | ||
598 | free_workload(workload); | ||
599 | return ret; | 437 | return ret; |
600 | } | 438 | } |
601 | 439 | ||
602 | #define RING_CTX_OFF(x) \ | ||
603 | offsetof(struct execlist_ring_context, x) | ||
604 | |||
605 | static void read_guest_pdps(struct intel_vgpu *vgpu, | ||
606 | u64 ring_context_gpa, u32 pdp[8]) | ||
607 | { | ||
608 | u64 gpa; | ||
609 | int i; | ||
610 | |||
611 | gpa = ring_context_gpa + RING_CTX_OFF(pdp3_UDW.val); | ||
612 | |||
613 | for (i = 0; i < 8; i++) | ||
614 | intel_gvt_hypervisor_read_gpa(vgpu, | ||
615 | gpa + i * 8, &pdp[7 - i], 4); | ||
616 | } | ||
617 | |||
618 | static int prepare_mm(struct intel_vgpu_workload *workload) | ||
619 | { | ||
620 | struct execlist_ctx_descriptor_format *desc = &workload->ctx_desc; | ||
621 | struct intel_vgpu_mm *mm; | ||
622 | struct intel_vgpu *vgpu = workload->vgpu; | ||
623 | int page_table_level; | ||
624 | u32 pdp[8]; | ||
625 | |||
626 | if (desc->addressing_mode == 1) { /* legacy 32-bit */ | ||
627 | page_table_level = 3; | ||
628 | } else if (desc->addressing_mode == 3) { /* legacy 64 bit */ | ||
629 | page_table_level = 4; | ||
630 | } else { | ||
631 | gvt_vgpu_err("Advanced Context mode(SVM) is not supported!\n"); | ||
632 | return -EINVAL; | ||
633 | } | ||
634 | |||
635 | read_guest_pdps(workload->vgpu, workload->ring_context_gpa, pdp); | ||
636 | |||
637 | mm = intel_vgpu_find_ppgtt_mm(workload->vgpu, page_table_level, pdp); | ||
638 | if (mm) { | ||
639 | intel_gvt_mm_reference(mm); | ||
640 | } else { | ||
641 | |||
642 | mm = intel_vgpu_create_mm(workload->vgpu, INTEL_GVT_MM_PPGTT, | ||
643 | pdp, page_table_level, 0); | ||
644 | if (IS_ERR(mm)) { | ||
645 | gvt_vgpu_err("fail to create mm object.\n"); | ||
646 | return PTR_ERR(mm); | ||
647 | } | ||
648 | } | ||
649 | workload->shadow_mm = mm; | ||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | #define get_last_workload(q) \ | ||
654 | (list_empty(q) ? NULL : container_of(q->prev, \ | ||
655 | struct intel_vgpu_workload, list)) | ||
656 | |||
657 | static int submit_context(struct intel_vgpu *vgpu, int ring_id, | 440 | static int submit_context(struct intel_vgpu *vgpu, int ring_id, |
658 | struct execlist_ctx_descriptor_format *desc, | 441 | struct execlist_ctx_descriptor_format *desc, |
659 | bool emulate_schedule_in) | 442 | bool emulate_schedule_in) |
660 | { | 443 | { |
661 | struct list_head *q = workload_q_head(vgpu, ring_id); | 444 | struct intel_vgpu_submission *s = &vgpu->submission; |
662 | struct intel_vgpu_workload *last_workload = get_last_workload(q); | ||
663 | struct intel_vgpu_workload *workload = NULL; | 445 | struct intel_vgpu_workload *workload = NULL; |
664 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | ||
665 | u64 ring_context_gpa; | ||
666 | u32 head, tail, start, ctl, ctx_ctl, per_ctx, indirect_ctx; | ||
667 | int ret; | ||
668 | |||
669 | ring_context_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, | ||
670 | (u32)((desc->lrca + 1) << GTT_PAGE_SHIFT)); | ||
671 | if (ring_context_gpa == INTEL_GVT_INVALID_ADDR) { | ||
672 | gvt_vgpu_err("invalid guest context LRCA: %x\n", desc->lrca); | ||
673 | return -EINVAL; | ||
674 | } | ||
675 | |||
676 | intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + | ||
677 | RING_CTX_OFF(ring_header.val), &head, 4); | ||
678 | 446 | ||
679 | intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + | 447 | workload = intel_vgpu_create_workload(vgpu, ring_id, desc); |
680 | RING_CTX_OFF(ring_tail.val), &tail, 4); | 448 | if (IS_ERR(workload)) |
449 | return PTR_ERR(workload); | ||
681 | 450 | ||
682 | head &= RB_HEAD_OFF_MASK; | ||
683 | tail &= RB_TAIL_OFF_MASK; | ||
684 | |||
685 | if (last_workload && same_context(&last_workload->ctx_desc, desc)) { | ||
686 | gvt_dbg_el("ring id %d cur workload == last\n", ring_id); | ||
687 | gvt_dbg_el("ctx head %x real head %lx\n", head, | ||
688 | last_workload->rb_tail); | ||
689 | /* | ||
690 | * cannot use guest context head pointer here, | ||
691 | * as it might not be updated at this time | ||
692 | */ | ||
693 | head = last_workload->rb_tail; | ||
694 | } | ||
695 | |||
696 | gvt_dbg_el("ring id %d begin a new workload\n", ring_id); | ||
697 | |||
698 | workload = kmem_cache_zalloc(vgpu->workloads, GFP_KERNEL); | ||
699 | if (!workload) | ||
700 | return -ENOMEM; | ||
701 | |||
702 | /* record some ring buffer register values for scan and shadow */ | ||
703 | intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + | ||
704 | RING_CTX_OFF(rb_start.val), &start, 4); | ||
705 | intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + | ||
706 | RING_CTX_OFF(rb_ctrl.val), &ctl, 4); | ||
707 | intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + | ||
708 | RING_CTX_OFF(ctx_ctrl.val), &ctx_ctl, 4); | ||
709 | |||
710 | INIT_LIST_HEAD(&workload->list); | ||
711 | INIT_LIST_HEAD(&workload->shadow_bb); | ||
712 | |||
713 | init_waitqueue_head(&workload->shadow_ctx_status_wq); | ||
714 | atomic_set(&workload->shadow_ctx_active, 0); | ||
715 | |||
716 | workload->vgpu = vgpu; | ||
717 | workload->ring_id = ring_id; | ||
718 | workload->ctx_desc = *desc; | ||
719 | workload->ring_context_gpa = ring_context_gpa; | ||
720 | workload->rb_head = head; | ||
721 | workload->rb_tail = tail; | ||
722 | workload->rb_start = start; | ||
723 | workload->rb_ctl = ctl; | ||
724 | workload->prepare = prepare_execlist_workload; | 451 | workload->prepare = prepare_execlist_workload; |
725 | workload->complete = complete_execlist_workload; | 452 | workload->complete = complete_execlist_workload; |
726 | workload->status = -EINPROGRESS; | ||
727 | workload->emulate_schedule_in = emulate_schedule_in; | 453 | workload->emulate_schedule_in = emulate_schedule_in; |
728 | workload->shadowed = false; | ||
729 | |||
730 | if (ring_id == RCS) { | ||
731 | intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + | ||
732 | RING_CTX_OFF(bb_per_ctx_ptr.val), &per_ctx, 4); | ||
733 | intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + | ||
734 | RING_CTX_OFF(rcs_indirect_ctx.val), &indirect_ctx, 4); | ||
735 | |||
736 | workload->wa_ctx.indirect_ctx.guest_gma = | ||
737 | indirect_ctx & INDIRECT_CTX_ADDR_MASK; | ||
738 | workload->wa_ctx.indirect_ctx.size = | ||
739 | (indirect_ctx & INDIRECT_CTX_SIZE_MASK) * | ||
740 | CACHELINE_BYTES; | ||
741 | workload->wa_ctx.per_ctx.guest_gma = | ||
742 | per_ctx & PER_CTX_ADDR_MASK; | ||
743 | workload->wa_ctx.per_ctx.valid = per_ctx & 1; | ||
744 | } | ||
745 | 454 | ||
746 | if (emulate_schedule_in) | 455 | if (emulate_schedule_in) |
747 | workload->elsp_dwords = vgpu->execlist[ring_id].elsp_dwords; | 456 | workload->elsp_dwords = s->execlist[ring_id].elsp_dwords; |
748 | |||
749 | gvt_dbg_el("workload %p ring id %d head %x tail %x start %x ctl %x\n", | ||
750 | workload, ring_id, head, tail, start, ctl); | ||
751 | 457 | ||
752 | gvt_dbg_el("workload %p emulate schedule_in %d\n", workload, | 458 | gvt_dbg_el("workload %p emulate schedule_in %d\n", workload, |
753 | emulate_schedule_in); | 459 | emulate_schedule_in); |
754 | 460 | ||
755 | ret = prepare_mm(workload); | ||
756 | if (ret) { | ||
757 | kmem_cache_free(vgpu->workloads, workload); | ||
758 | return ret; | ||
759 | } | ||
760 | |||
761 | /* Only scan and shadow the first workload in the queue | ||
762 | * as there is only one pre-allocated buf-obj for shadow. | ||
763 | */ | ||
764 | if (list_empty(workload_q_head(vgpu, ring_id))) { | ||
765 | intel_runtime_pm_get(dev_priv); | ||
766 | mutex_lock(&dev_priv->drm.struct_mutex); | ||
767 | intel_gvt_scan_and_shadow_workload(workload); | ||
768 | mutex_unlock(&dev_priv->drm.struct_mutex); | ||
769 | intel_runtime_pm_put(dev_priv); | ||
770 | } | ||
771 | |||
772 | queue_workload(workload); | 461 | queue_workload(workload); |
773 | return 0; | 462 | return 0; |
774 | } | 463 | } |
775 | 464 | ||
776 | int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int ring_id) | 465 | int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int ring_id) |
777 | { | 466 | { |
778 | struct intel_vgpu_execlist *execlist = &vgpu->execlist[ring_id]; | 467 | struct intel_vgpu_submission *s = &vgpu->submission; |
779 | struct execlist_ctx_descriptor_format desc[2]; | 468 | struct intel_vgpu_execlist *execlist = &s->execlist[ring_id]; |
469 | struct execlist_ctx_descriptor_format *desc[2]; | ||
780 | int i, ret; | 470 | int i, ret; |
781 | 471 | ||
782 | desc[0] = *get_desc_from_elsp_dwords(&execlist->elsp_dwords, 1); | 472 | desc[0] = get_desc_from_elsp_dwords(&execlist->elsp_dwords, 0); |
783 | desc[1] = *get_desc_from_elsp_dwords(&execlist->elsp_dwords, 0); | 473 | desc[1] = get_desc_from_elsp_dwords(&execlist->elsp_dwords, 1); |
784 | 474 | ||
785 | if (!desc[0].valid) { | 475 | if (!desc[0]->valid) { |
786 | gvt_vgpu_err("invalid elsp submission, desc0 is invalid\n"); | 476 | gvt_vgpu_err("invalid elsp submission, desc0 is invalid\n"); |
787 | goto inv_desc; | 477 | goto inv_desc; |
788 | } | 478 | } |
789 | 479 | ||
790 | for (i = 0; i < ARRAY_SIZE(desc); i++) { | 480 | for (i = 0; i < ARRAY_SIZE(desc); i++) { |
791 | if (!desc[i].valid) | 481 | if (!desc[i]->valid) |
792 | continue; | 482 | continue; |
793 | if (!desc[i].privilege_access) { | 483 | if (!desc[i]->privilege_access) { |
794 | gvt_vgpu_err("unexpected GGTT elsp submission\n"); | 484 | gvt_vgpu_err("unexpected GGTT elsp submission\n"); |
795 | goto inv_desc; | 485 | goto inv_desc; |
796 | } | 486 | } |
@@ -798,9 +488,9 @@ int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int ring_id) | |||
798 | 488 | ||
799 | /* submit workload */ | 489 | /* submit workload */ |
800 | for (i = 0; i < ARRAY_SIZE(desc); i++) { | 490 | for (i = 0; i < ARRAY_SIZE(desc); i++) { |
801 | if (!desc[i].valid) | 491 | if (!desc[i]->valid) |
802 | continue; | 492 | continue; |
803 | ret = submit_context(vgpu, ring_id, &desc[i], i == 0); | 493 | ret = submit_context(vgpu, ring_id, desc[i], i == 0); |
804 | if (ret) { | 494 | if (ret) { |
805 | gvt_vgpu_err("failed to submit desc %d\n", i); | 495 | gvt_vgpu_err("failed to submit desc %d\n", i); |
806 | return ret; | 496 | return ret; |
@@ -811,13 +501,14 @@ int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int ring_id) | |||
811 | 501 | ||
812 | inv_desc: | 502 | inv_desc: |
813 | gvt_vgpu_err("descriptors content: desc0 %08x %08x desc1 %08x %08x\n", | 503 | gvt_vgpu_err("descriptors content: desc0 %08x %08x desc1 %08x %08x\n", |
814 | desc[0].udw, desc[0].ldw, desc[1].udw, desc[1].ldw); | 504 | desc[0]->udw, desc[0]->ldw, desc[1]->udw, desc[1]->ldw); |
815 | return -EINVAL; | 505 | return -EINVAL; |
816 | } | 506 | } |
817 | 507 | ||
818 | static void init_vgpu_execlist(struct intel_vgpu *vgpu, int ring_id) | 508 | static void init_vgpu_execlist(struct intel_vgpu *vgpu, int ring_id) |
819 | { | 509 | { |
820 | struct intel_vgpu_execlist *execlist = &vgpu->execlist[ring_id]; | 510 | struct intel_vgpu_submission *s = &vgpu->submission; |
511 | struct intel_vgpu_execlist *execlist = &s->execlist[ring_id]; | ||
821 | struct execlist_context_status_pointer_format ctx_status_ptr; | 512 | struct execlist_context_status_pointer_format ctx_status_ptr; |
822 | u32 ctx_status_ptr_reg; | 513 | u32 ctx_status_ptr_reg; |
823 | 514 | ||
@@ -837,91 +528,40 @@ static void init_vgpu_execlist(struct intel_vgpu *vgpu, int ring_id) | |||
837 | vgpu_vreg(vgpu, ctx_status_ptr_reg) = ctx_status_ptr.dw; | 528 | vgpu_vreg(vgpu, ctx_status_ptr_reg) = ctx_status_ptr.dw; |
838 | } | 529 | } |
839 | 530 | ||
840 | static void clean_workloads(struct intel_vgpu *vgpu, unsigned long engine_mask) | 531 | void clean_execlist(struct intel_vgpu *vgpu) |
841 | { | ||
842 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | ||
843 | struct intel_engine_cs *engine; | ||
844 | struct intel_vgpu_workload *pos, *n; | ||
845 | unsigned int tmp; | ||
846 | |||
847 | /* free the unsubmited workloads in the queues. */ | ||
848 | for_each_engine_masked(engine, dev_priv, engine_mask, tmp) { | ||
849 | list_for_each_entry_safe(pos, n, | ||
850 | &vgpu->workload_q_head[engine->id], list) { | ||
851 | list_del_init(&pos->list); | ||
852 | free_workload(pos); | ||
853 | } | ||
854 | |||
855 | clear_bit(engine->id, vgpu->shadow_ctx_desc_updated); | ||
856 | } | ||
857 | } | ||
858 | |||
859 | void intel_vgpu_clean_execlist(struct intel_vgpu *vgpu) | ||
860 | { | 532 | { |
861 | enum intel_engine_id i; | 533 | enum intel_engine_id i; |
862 | struct intel_engine_cs *engine; | 534 | struct intel_engine_cs *engine; |
863 | 535 | ||
864 | clean_workloads(vgpu, ALL_ENGINES); | ||
865 | kmem_cache_destroy(vgpu->workloads); | ||
866 | |||
867 | for_each_engine(engine, vgpu->gvt->dev_priv, i) { | 536 | for_each_engine(engine, vgpu->gvt->dev_priv, i) { |
868 | kfree(vgpu->reserve_ring_buffer_va[i]); | 537 | struct intel_vgpu_submission *s = &vgpu->submission; |
869 | vgpu->reserve_ring_buffer_va[i] = NULL; | ||
870 | vgpu->reserve_ring_buffer_size[i] = 0; | ||
871 | } | ||
872 | 538 | ||
873 | } | 539 | kfree(s->ring_scan_buffer[i]); |
874 | 540 | s->ring_scan_buffer[i] = NULL; | |
875 | #define RESERVE_RING_BUFFER_SIZE ((1 * PAGE_SIZE)/8) | 541 | s->ring_scan_buffer_size[i] = 0; |
876 | int intel_vgpu_init_execlist(struct intel_vgpu *vgpu) | ||
877 | { | ||
878 | enum intel_engine_id i; | ||
879 | struct intel_engine_cs *engine; | ||
880 | |||
881 | /* each ring has a virtual execlist engine */ | ||
882 | for_each_engine(engine, vgpu->gvt->dev_priv, i) { | ||
883 | init_vgpu_execlist(vgpu, i); | ||
884 | INIT_LIST_HEAD(&vgpu->workload_q_head[i]); | ||
885 | } | ||
886 | |||
887 | vgpu->workloads = kmem_cache_create("gvt-g_vgpu_workload", | ||
888 | sizeof(struct intel_vgpu_workload), 0, | ||
889 | SLAB_HWCACHE_ALIGN, | ||
890 | NULL); | ||
891 | |||
892 | if (!vgpu->workloads) | ||
893 | return -ENOMEM; | ||
894 | |||
895 | /* each ring has a shadow ring buffer until vgpu destroyed */ | ||
896 | for_each_engine(engine, vgpu->gvt->dev_priv, i) { | ||
897 | vgpu->reserve_ring_buffer_va[i] = | ||
898 | kmalloc(RESERVE_RING_BUFFER_SIZE, GFP_KERNEL); | ||
899 | if (!vgpu->reserve_ring_buffer_va[i]) { | ||
900 | gvt_vgpu_err("fail to alloc reserve ring buffer\n"); | ||
901 | goto out; | ||
902 | } | ||
903 | vgpu->reserve_ring_buffer_size[i] = RESERVE_RING_BUFFER_SIZE; | ||
904 | } | 542 | } |
905 | return 0; | ||
906 | out: | ||
907 | for_each_engine(engine, vgpu->gvt->dev_priv, i) { | ||
908 | if (vgpu->reserve_ring_buffer_size[i]) { | ||
909 | kfree(vgpu->reserve_ring_buffer_va[i]); | ||
910 | vgpu->reserve_ring_buffer_va[i] = NULL; | ||
911 | vgpu->reserve_ring_buffer_size[i] = 0; | ||
912 | } | ||
913 | } | ||
914 | return -ENOMEM; | ||
915 | } | 543 | } |
916 | 544 | ||
917 | void intel_vgpu_reset_execlist(struct intel_vgpu *vgpu, | 545 | void reset_execlist(struct intel_vgpu *vgpu, |
918 | unsigned long engine_mask) | 546 | unsigned long engine_mask) |
919 | { | 547 | { |
920 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | 548 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; |
921 | struct intel_engine_cs *engine; | 549 | struct intel_engine_cs *engine; |
922 | unsigned int tmp; | 550 | unsigned int tmp; |
923 | 551 | ||
924 | clean_workloads(vgpu, engine_mask); | ||
925 | for_each_engine_masked(engine, dev_priv, engine_mask, tmp) | 552 | for_each_engine_masked(engine, dev_priv, engine_mask, tmp) |
926 | init_vgpu_execlist(vgpu, engine->id); | 553 | init_vgpu_execlist(vgpu, engine->id); |
927 | } | 554 | } |
555 | |||
556 | int init_execlist(struct intel_vgpu *vgpu) | ||
557 | { | ||
558 | reset_execlist(vgpu, ALL_ENGINES); | ||
559 | return 0; | ||
560 | } | ||
561 | |||
562 | const struct intel_vgpu_submission_ops intel_vgpu_execlist_submission_ops = { | ||
563 | .name = "execlist", | ||
564 | .init = init_execlist, | ||
565 | .reset = reset_execlist, | ||
566 | .clean = clean_execlist, | ||
567 | }; | ||
diff --git a/drivers/gpu/drm/i915/gvt/execlist.h b/drivers/gpu/drm/i915/gvt/execlist.h index 7eced40a1e30..427e40e64d41 100644 --- a/drivers/gpu/drm/i915/gvt/execlist.h +++ b/drivers/gpu/drm/i915/gvt/execlist.h | |||
@@ -37,10 +37,6 @@ | |||
37 | 37 | ||
38 | struct execlist_ctx_descriptor_format { | 38 | struct execlist_ctx_descriptor_format { |
39 | union { | 39 | union { |
40 | u32 udw; | ||
41 | u32 context_id; | ||
42 | }; | ||
43 | union { | ||
44 | u32 ldw; | 40 | u32 ldw; |
45 | struct { | 41 | struct { |
46 | u32 valid : 1; | 42 | u32 valid : 1; |
@@ -54,6 +50,10 @@ struct execlist_ctx_descriptor_format { | |||
54 | u32 lrca : 20; | 50 | u32 lrca : 20; |
55 | }; | 51 | }; |
56 | }; | 52 | }; |
53 | union { | ||
54 | u32 udw; | ||
55 | u32 context_id; | ||
56 | }; | ||
57 | }; | 57 | }; |
58 | 58 | ||
59 | struct execlist_status_format { | 59 | struct execlist_status_format { |
diff --git a/drivers/gpu/drm/i915/gvt/firmware.c b/drivers/gpu/drm/i915/gvt/firmware.c index a26c1705430e..a73e1d418c22 100644 --- a/drivers/gpu/drm/i915/gvt/firmware.c +++ b/drivers/gpu/drm/i915/gvt/firmware.c | |||
@@ -66,20 +66,23 @@ static struct bin_attribute firmware_attr = { | |||
66 | .mmap = NULL, | 66 | .mmap = NULL, |
67 | }; | 67 | }; |
68 | 68 | ||
69 | static int expose_firmware_sysfs(struct intel_gvt *gvt) | 69 | static int mmio_snapshot_handler(struct intel_gvt *gvt, u32 offset, void *data) |
70 | { | 70 | { |
71 | struct drm_i915_private *dev_priv = gvt->dev_priv; | 71 | struct drm_i915_private *dev_priv = gvt->dev_priv; |
72 | |||
73 | *(u32 *)(data + offset) = I915_READ_NOTRACE(_MMIO(offset)); | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static int expose_firmware_sysfs(struct intel_gvt *gvt) | ||
78 | { | ||
72 | struct intel_gvt_device_info *info = &gvt->device_info; | 79 | struct intel_gvt_device_info *info = &gvt->device_info; |
73 | struct pci_dev *pdev = gvt->dev_priv->drm.pdev; | 80 | struct pci_dev *pdev = gvt->dev_priv->drm.pdev; |
74 | struct intel_gvt_mmio_info *e; | ||
75 | struct gvt_mmio_block *block = gvt->mmio.mmio_block; | ||
76 | int num = gvt->mmio.num_mmio_block; | ||
77 | struct gvt_firmware_header *h; | 81 | struct gvt_firmware_header *h; |
78 | void *firmware; | 82 | void *firmware; |
79 | void *p; | 83 | void *p; |
80 | unsigned long size, crc32_start; | 84 | unsigned long size, crc32_start; |
81 | int i, j; | 85 | int i, ret; |
82 | int ret; | ||
83 | 86 | ||
84 | size = sizeof(*h) + info->mmio_size + info->cfg_space_size; | 87 | size = sizeof(*h) + info->mmio_size + info->cfg_space_size; |
85 | firmware = vzalloc(size); | 88 | firmware = vzalloc(size); |
@@ -104,15 +107,8 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt) | |||
104 | 107 | ||
105 | p = firmware + h->mmio_offset; | 108 | p = firmware + h->mmio_offset; |
106 | 109 | ||
107 | hash_for_each(gvt->mmio.mmio_info_table, i, e, node) | 110 | /* Take a snapshot of hw mmio registers. */ |
108 | *(u32 *)(p + e->offset) = I915_READ_NOTRACE(_MMIO(e->offset)); | 111 | intel_gvt_for_each_tracked_mmio(gvt, mmio_snapshot_handler, p); |
109 | |||
110 | for (i = 0; i < num; i++, block++) { | ||
111 | for (j = 0; j < block->size; j += 4) | ||
112 | *(u32 *)(p + INTEL_GVT_MMIO_OFFSET(block->offset) + j) = | ||
113 | I915_READ_NOTRACE(_MMIO(INTEL_GVT_MMIO_OFFSET( | ||
114 | block->offset) + j)); | ||
115 | } | ||
116 | 112 | ||
117 | memcpy(gvt->firmware.mmio, p, info->mmio_size); | 113 | memcpy(gvt->firmware.mmio, p, info->mmio_size); |
118 | 114 | ||
diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 8e331142badb..71a0f2b87b3a 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c | |||
@@ -94,12 +94,12 @@ int intel_gvt_ggtt_index_g2h(struct intel_vgpu *vgpu, unsigned long g_index, | |||
94 | u64 h_addr; | 94 | u64 h_addr; |
95 | int ret; | 95 | int ret; |
96 | 96 | ||
97 | ret = intel_gvt_ggtt_gmadr_g2h(vgpu, g_index << GTT_PAGE_SHIFT, | 97 | ret = intel_gvt_ggtt_gmadr_g2h(vgpu, g_index << I915_GTT_PAGE_SHIFT, |
98 | &h_addr); | 98 | &h_addr); |
99 | if (ret) | 99 | if (ret) |
100 | return ret; | 100 | return ret; |
101 | 101 | ||
102 | *h_index = h_addr >> GTT_PAGE_SHIFT; | 102 | *h_index = h_addr >> I915_GTT_PAGE_SHIFT; |
103 | return 0; | 103 | return 0; |
104 | } | 104 | } |
105 | 105 | ||
@@ -109,12 +109,12 @@ int intel_gvt_ggtt_h2g_index(struct intel_vgpu *vgpu, unsigned long h_index, | |||
109 | u64 g_addr; | 109 | u64 g_addr; |
110 | int ret; | 110 | int ret; |
111 | 111 | ||
112 | ret = intel_gvt_ggtt_gmadr_h2g(vgpu, h_index << GTT_PAGE_SHIFT, | 112 | ret = intel_gvt_ggtt_gmadr_h2g(vgpu, h_index << I915_GTT_PAGE_SHIFT, |
113 | &g_addr); | 113 | &g_addr); |
114 | if (ret) | 114 | if (ret) |
115 | return ret; | 115 | return ret; |
116 | 116 | ||
117 | *g_index = g_addr >> GTT_PAGE_SHIFT; | 117 | *g_index = g_addr >> I915_GTT_PAGE_SHIFT; |
118 | return 0; | 118 | return 0; |
119 | } | 119 | } |
120 | 120 | ||
@@ -156,13 +156,15 @@ int intel_gvt_ggtt_h2g_index(struct intel_vgpu *vgpu, unsigned long h_index, | |||
156 | 156 | ||
157 | struct gtt_type_table_entry { | 157 | struct gtt_type_table_entry { |
158 | int entry_type; | 158 | int entry_type; |
159 | int pt_type; | ||
159 | int next_pt_type; | 160 | int next_pt_type; |
160 | int pse_entry_type; | 161 | int pse_entry_type; |
161 | }; | 162 | }; |
162 | 163 | ||
163 | #define GTT_TYPE_TABLE_ENTRY(type, e_type, npt_type, pse_type) \ | 164 | #define GTT_TYPE_TABLE_ENTRY(type, e_type, cpt_type, npt_type, pse_type) \ |
164 | [type] = { \ | 165 | [type] = { \ |
165 | .entry_type = e_type, \ | 166 | .entry_type = e_type, \ |
167 | .pt_type = cpt_type, \ | ||
166 | .next_pt_type = npt_type, \ | 168 | .next_pt_type = npt_type, \ |
167 | .pse_entry_type = pse_type, \ | 169 | .pse_entry_type = pse_type, \ |
168 | } | 170 | } |
@@ -170,55 +172,68 @@ struct gtt_type_table_entry { | |||
170 | static struct gtt_type_table_entry gtt_type_table[] = { | 172 | static struct gtt_type_table_entry gtt_type_table[] = { |
171 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_ROOT_L4_ENTRY, | 173 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_ROOT_L4_ENTRY, |
172 | GTT_TYPE_PPGTT_ROOT_L4_ENTRY, | 174 | GTT_TYPE_PPGTT_ROOT_L4_ENTRY, |
175 | GTT_TYPE_INVALID, | ||
173 | GTT_TYPE_PPGTT_PML4_PT, | 176 | GTT_TYPE_PPGTT_PML4_PT, |
174 | GTT_TYPE_INVALID), | 177 | GTT_TYPE_INVALID), |
175 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PML4_PT, | 178 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PML4_PT, |
176 | GTT_TYPE_PPGTT_PML4_ENTRY, | 179 | GTT_TYPE_PPGTT_PML4_ENTRY, |
180 | GTT_TYPE_PPGTT_PML4_PT, | ||
177 | GTT_TYPE_PPGTT_PDP_PT, | 181 | GTT_TYPE_PPGTT_PDP_PT, |
178 | GTT_TYPE_INVALID), | 182 | GTT_TYPE_INVALID), |
179 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PML4_ENTRY, | 183 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PML4_ENTRY, |
180 | GTT_TYPE_PPGTT_PML4_ENTRY, | 184 | GTT_TYPE_PPGTT_PML4_ENTRY, |
185 | GTT_TYPE_PPGTT_PML4_PT, | ||
181 | GTT_TYPE_PPGTT_PDP_PT, | 186 | GTT_TYPE_PPGTT_PDP_PT, |
182 | GTT_TYPE_INVALID), | 187 | GTT_TYPE_INVALID), |
183 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PDP_PT, | 188 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PDP_PT, |
184 | GTT_TYPE_PPGTT_PDP_ENTRY, | 189 | GTT_TYPE_PPGTT_PDP_ENTRY, |
190 | GTT_TYPE_PPGTT_PDP_PT, | ||
185 | GTT_TYPE_PPGTT_PDE_PT, | 191 | GTT_TYPE_PPGTT_PDE_PT, |
186 | GTT_TYPE_PPGTT_PTE_1G_ENTRY), | 192 | GTT_TYPE_PPGTT_PTE_1G_ENTRY), |
187 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_ROOT_L3_ENTRY, | 193 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_ROOT_L3_ENTRY, |
188 | GTT_TYPE_PPGTT_ROOT_L3_ENTRY, | 194 | GTT_TYPE_PPGTT_ROOT_L3_ENTRY, |
195 | GTT_TYPE_INVALID, | ||
189 | GTT_TYPE_PPGTT_PDE_PT, | 196 | GTT_TYPE_PPGTT_PDE_PT, |
190 | GTT_TYPE_PPGTT_PTE_1G_ENTRY), | 197 | GTT_TYPE_PPGTT_PTE_1G_ENTRY), |
191 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PDP_ENTRY, | 198 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PDP_ENTRY, |
192 | GTT_TYPE_PPGTT_PDP_ENTRY, | 199 | GTT_TYPE_PPGTT_PDP_ENTRY, |
200 | GTT_TYPE_PPGTT_PDP_PT, | ||
193 | GTT_TYPE_PPGTT_PDE_PT, | 201 | GTT_TYPE_PPGTT_PDE_PT, |
194 | GTT_TYPE_PPGTT_PTE_1G_ENTRY), | 202 | GTT_TYPE_PPGTT_PTE_1G_ENTRY), |
195 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PDE_PT, | 203 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PDE_PT, |
196 | GTT_TYPE_PPGTT_PDE_ENTRY, | 204 | GTT_TYPE_PPGTT_PDE_ENTRY, |
205 | GTT_TYPE_PPGTT_PDE_PT, | ||
197 | GTT_TYPE_PPGTT_PTE_PT, | 206 | GTT_TYPE_PPGTT_PTE_PT, |
198 | GTT_TYPE_PPGTT_PTE_2M_ENTRY), | 207 | GTT_TYPE_PPGTT_PTE_2M_ENTRY), |
199 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PDE_ENTRY, | 208 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PDE_ENTRY, |
200 | GTT_TYPE_PPGTT_PDE_ENTRY, | 209 | GTT_TYPE_PPGTT_PDE_ENTRY, |
210 | GTT_TYPE_PPGTT_PDE_PT, | ||
201 | GTT_TYPE_PPGTT_PTE_PT, | 211 | GTT_TYPE_PPGTT_PTE_PT, |
202 | GTT_TYPE_PPGTT_PTE_2M_ENTRY), | 212 | GTT_TYPE_PPGTT_PTE_2M_ENTRY), |
203 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PTE_PT, | 213 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PTE_PT, |
204 | GTT_TYPE_PPGTT_PTE_4K_ENTRY, | 214 | GTT_TYPE_PPGTT_PTE_4K_ENTRY, |
215 | GTT_TYPE_PPGTT_PTE_PT, | ||
205 | GTT_TYPE_INVALID, | 216 | GTT_TYPE_INVALID, |
206 | GTT_TYPE_INVALID), | 217 | GTT_TYPE_INVALID), |
207 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PTE_4K_ENTRY, | 218 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PTE_4K_ENTRY, |
208 | GTT_TYPE_PPGTT_PTE_4K_ENTRY, | 219 | GTT_TYPE_PPGTT_PTE_4K_ENTRY, |
220 | GTT_TYPE_PPGTT_PTE_PT, | ||
209 | GTT_TYPE_INVALID, | 221 | GTT_TYPE_INVALID, |
210 | GTT_TYPE_INVALID), | 222 | GTT_TYPE_INVALID), |
211 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PTE_2M_ENTRY, | 223 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PTE_2M_ENTRY, |
212 | GTT_TYPE_PPGTT_PDE_ENTRY, | 224 | GTT_TYPE_PPGTT_PDE_ENTRY, |
225 | GTT_TYPE_PPGTT_PDE_PT, | ||
213 | GTT_TYPE_INVALID, | 226 | GTT_TYPE_INVALID, |
214 | GTT_TYPE_PPGTT_PTE_2M_ENTRY), | 227 | GTT_TYPE_PPGTT_PTE_2M_ENTRY), |
215 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PTE_1G_ENTRY, | 228 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_PPGTT_PTE_1G_ENTRY, |
216 | GTT_TYPE_PPGTT_PDP_ENTRY, | 229 | GTT_TYPE_PPGTT_PDP_ENTRY, |
230 | GTT_TYPE_PPGTT_PDP_PT, | ||
217 | GTT_TYPE_INVALID, | 231 | GTT_TYPE_INVALID, |
218 | GTT_TYPE_PPGTT_PTE_1G_ENTRY), | 232 | GTT_TYPE_PPGTT_PTE_1G_ENTRY), |
219 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_GGTT_PTE, | 233 | GTT_TYPE_TABLE_ENTRY(GTT_TYPE_GGTT_PTE, |
220 | GTT_TYPE_GGTT_PTE, | 234 | GTT_TYPE_GGTT_PTE, |
221 | GTT_TYPE_INVALID, | 235 | GTT_TYPE_INVALID, |
236 | GTT_TYPE_INVALID, | ||
222 | GTT_TYPE_INVALID), | 237 | GTT_TYPE_INVALID), |
223 | }; | 238 | }; |
224 | 239 | ||
@@ -227,6 +242,11 @@ static inline int get_next_pt_type(int type) | |||
227 | return gtt_type_table[type].next_pt_type; | 242 | return gtt_type_table[type].next_pt_type; |
228 | } | 243 | } |
229 | 244 | ||
245 | static inline int get_pt_type(int type) | ||
246 | { | ||
247 | return gtt_type_table[type].pt_type; | ||
248 | } | ||
249 | |||
230 | static inline int get_entry_type(int type) | 250 | static inline int get_entry_type(int type) |
231 | { | 251 | { |
232 | return gtt_type_table[type].entry_type; | 252 | return gtt_type_table[type].entry_type; |
@@ -351,7 +371,7 @@ static bool gen8_gtt_test_pse(struct intel_gvt_gtt_entry *e) | |||
351 | return false; | 371 | return false; |
352 | 372 | ||
353 | e->type = get_entry_type(e->type); | 373 | e->type = get_entry_type(e->type); |
354 | if (!(e->val64 & (1 << 7))) | 374 | if (!(e->val64 & BIT(7))) |
355 | return false; | 375 | return false; |
356 | 376 | ||
357 | e->type = get_pse_type(e->type); | 377 | e->type = get_pse_type(e->type); |
@@ -369,12 +389,17 @@ static bool gen8_gtt_test_present(struct intel_gvt_gtt_entry *e) | |||
369 | || e->type == GTT_TYPE_PPGTT_ROOT_L4_ENTRY) | 389 | || e->type == GTT_TYPE_PPGTT_ROOT_L4_ENTRY) |
370 | return (e->val64 != 0); | 390 | return (e->val64 != 0); |
371 | else | 391 | else |
372 | return (e->val64 & (1 << 0)); | 392 | return (e->val64 & BIT(0)); |
373 | } | 393 | } |
374 | 394 | ||
375 | static void gtt_entry_clear_present(struct intel_gvt_gtt_entry *e) | 395 | static void gtt_entry_clear_present(struct intel_gvt_gtt_entry *e) |
376 | { | 396 | { |
377 | e->val64 &= ~(1 << 0); | 397 | e->val64 &= ~BIT(0); |
398 | } | ||
399 | |||
400 | static void gtt_entry_set_present(struct intel_gvt_gtt_entry *e) | ||
401 | { | ||
402 | e->val64 |= BIT(0); | ||
378 | } | 403 | } |
379 | 404 | ||
380 | /* | 405 | /* |
@@ -382,7 +407,7 @@ static void gtt_entry_clear_present(struct intel_gvt_gtt_entry *e) | |||
382 | */ | 407 | */ |
383 | static unsigned long gma_to_ggtt_pte_index(unsigned long gma) | 408 | static unsigned long gma_to_ggtt_pte_index(unsigned long gma) |
384 | { | 409 | { |
385 | unsigned long x = (gma >> GTT_PAGE_SHIFT); | 410 | unsigned long x = (gma >> I915_GTT_PAGE_SHIFT); |
386 | 411 | ||
387 | trace_gma_index(__func__, gma, x); | 412 | trace_gma_index(__func__, gma, x); |
388 | return x; | 413 | return x; |
@@ -406,6 +431,7 @@ static struct intel_gvt_gtt_pte_ops gen8_gtt_pte_ops = { | |||
406 | .get_entry = gtt_get_entry64, | 431 | .get_entry = gtt_get_entry64, |
407 | .set_entry = gtt_set_entry64, | 432 | .set_entry = gtt_set_entry64, |
408 | .clear_present = gtt_entry_clear_present, | 433 | .clear_present = gtt_entry_clear_present, |
434 | .set_present = gtt_entry_set_present, | ||
409 | .test_present = gen8_gtt_test_present, | 435 | .test_present = gen8_gtt_test_present, |
410 | .test_pse = gen8_gtt_test_pse, | 436 | .test_pse = gen8_gtt_test_pse, |
411 | .get_pfn = gen8_gtt_get_pfn, | 437 | .get_pfn = gen8_gtt_get_pfn, |
@@ -494,7 +520,7 @@ static inline int ppgtt_spt_get_entry( | |||
494 | return -EINVAL; | 520 | return -EINVAL; |
495 | 521 | ||
496 | ret = ops->get_entry(page_table, e, index, guest, | 522 | ret = ops->get_entry(page_table, e, index, guest, |
497 | spt->guest_page.gfn << GTT_PAGE_SHIFT, | 523 | spt->guest_page.track.gfn << I915_GTT_PAGE_SHIFT, |
498 | spt->vgpu); | 524 | spt->vgpu); |
499 | if (ret) | 525 | if (ret) |
500 | return ret; | 526 | return ret; |
@@ -516,7 +542,7 @@ static inline int ppgtt_spt_set_entry( | |||
516 | return -EINVAL; | 542 | return -EINVAL; |
517 | 543 | ||
518 | return ops->set_entry(page_table, e, index, guest, | 544 | return ops->set_entry(page_table, e, index, guest, |
519 | spt->guest_page.gfn << GTT_PAGE_SHIFT, | 545 | spt->guest_page.track.gfn << I915_GTT_PAGE_SHIFT, |
520 | spt->vgpu); | 546 | spt->vgpu); |
521 | } | 547 | } |
522 | 548 | ||
@@ -537,88 +563,103 @@ static inline int ppgtt_spt_set_entry( | |||
537 | spt->shadow_page.type, e, index, false) | 563 | spt->shadow_page.type, e, index, false) |
538 | 564 | ||
539 | /** | 565 | /** |
540 | * intel_vgpu_init_guest_page - init a guest page data structure | 566 | * intel_vgpu_init_page_track - init a page track data structure |
541 | * @vgpu: a vGPU | 567 | * @vgpu: a vGPU |
542 | * @p: a guest page data structure | 568 | * @t: a page track data structure |
543 | * @gfn: guest memory page frame number | 569 | * @gfn: guest memory page frame number |
544 | * @handler: function will be called when target guest memory page has | 570 | * @handler: the function will be called when target guest memory page has |
545 | * been modified. | 571 | * been modified. |
546 | * | 572 | * |
547 | * This function is called when user wants to track a guest memory page. | 573 | * This function is called when a user wants to prepare a page track data |
574 | * structure to track a guest memory page. | ||
548 | * | 575 | * |
549 | * Returns: | 576 | * Returns: |
550 | * Zero on success, negative error code if failed. | 577 | * Zero on success, negative error code if failed. |
551 | */ | 578 | */ |
552 | int intel_vgpu_init_guest_page(struct intel_vgpu *vgpu, | 579 | int intel_vgpu_init_page_track(struct intel_vgpu *vgpu, |
553 | struct intel_vgpu_guest_page *p, | 580 | struct intel_vgpu_page_track *t, |
554 | unsigned long gfn, | 581 | unsigned long gfn, |
555 | int (*handler)(void *, u64, void *, int), | 582 | int (*handler)(void *, u64, void *, int), |
556 | void *data) | 583 | void *data) |
557 | { | 584 | { |
558 | INIT_HLIST_NODE(&p->node); | 585 | INIT_HLIST_NODE(&t->node); |
559 | 586 | ||
560 | p->writeprotection = false; | 587 | t->tracked = false; |
561 | p->gfn = gfn; | 588 | t->gfn = gfn; |
562 | p->handler = handler; | 589 | t->handler = handler; |
563 | p->data = data; | 590 | t->data = data; |
564 | p->oos_page = NULL; | ||
565 | p->write_cnt = 0; | ||
566 | 591 | ||
567 | hash_add(vgpu->gtt.guest_page_hash_table, &p->node, p->gfn); | 592 | hash_add(vgpu->gtt.tracked_guest_page_hash_table, &t->node, t->gfn); |
568 | return 0; | 593 | return 0; |
569 | } | 594 | } |
570 | 595 | ||
571 | static int detach_oos_page(struct intel_vgpu *vgpu, | ||
572 | struct intel_vgpu_oos_page *oos_page); | ||
573 | |||
574 | /** | 596 | /** |
575 | * intel_vgpu_clean_guest_page - release the resource owned by guest page data | 597 | * intel_vgpu_clean_page_track - release a page track data structure |
576 | * structure | ||
577 | * @vgpu: a vGPU | 598 | * @vgpu: a vGPU |
578 | * @p: a tracked guest page | 599 | * @t: a page track data structure |
579 | * | 600 | * |
580 | * This function is called when user tries to stop tracking a guest memory | 601 | * This function is called before a user frees a page track data structure. |
581 | * page. | ||
582 | */ | 602 | */ |
583 | void intel_vgpu_clean_guest_page(struct intel_vgpu *vgpu, | 603 | void intel_vgpu_clean_page_track(struct intel_vgpu *vgpu, |
584 | struct intel_vgpu_guest_page *p) | 604 | struct intel_vgpu_page_track *t) |
585 | { | 605 | { |
586 | if (!hlist_unhashed(&p->node)) | 606 | if (!hlist_unhashed(&t->node)) |
587 | hash_del(&p->node); | 607 | hash_del(&t->node); |
588 | |||
589 | if (p->oos_page) | ||
590 | detach_oos_page(vgpu, p->oos_page); | ||
591 | 608 | ||
592 | if (p->writeprotection) | 609 | if (t->tracked) |
593 | intel_gvt_hypervisor_unset_wp_page(vgpu, p); | 610 | intel_gvt_hypervisor_disable_page_track(vgpu, t); |
594 | } | 611 | } |
595 | 612 | ||
596 | /** | 613 | /** |
597 | * intel_vgpu_find_guest_page - find a guest page data structure by GFN. | 614 | * intel_vgpu_find_tracked_page - find a tracked guest page |
598 | * @vgpu: a vGPU | 615 | * @vgpu: a vGPU |
599 | * @gfn: guest memory page frame number | 616 | * @gfn: guest memory page frame number |
600 | * | 617 | * |
601 | * This function is called when emulation logic wants to know if a trapped GFN | 618 | * This function is called when the emulation layer wants to figure out if a |
602 | * is a tracked guest page. | 619 | * trapped GFN is a tracked guest page. |
603 | * | 620 | * |
604 | * Returns: | 621 | * Returns: |
605 | * Pointer to guest page data structure, NULL if failed. | 622 | * Pointer to page track data structure, NULL if not found. |
606 | */ | 623 | */ |
607 | struct intel_vgpu_guest_page *intel_vgpu_find_guest_page( | 624 | struct intel_vgpu_page_track *intel_vgpu_find_tracked_page( |
608 | struct intel_vgpu *vgpu, unsigned long gfn) | 625 | struct intel_vgpu *vgpu, unsigned long gfn) |
609 | { | 626 | { |
610 | struct intel_vgpu_guest_page *p; | 627 | struct intel_vgpu_page_track *t; |
611 | 628 | ||
612 | hash_for_each_possible(vgpu->gtt.guest_page_hash_table, | 629 | hash_for_each_possible(vgpu->gtt.tracked_guest_page_hash_table, |
613 | p, node, gfn) { | 630 | t, node, gfn) { |
614 | if (p->gfn == gfn) | 631 | if (t->gfn == gfn) |
615 | return p; | 632 | return t; |
616 | } | 633 | } |
617 | return NULL; | 634 | return NULL; |
618 | } | 635 | } |
619 | 636 | ||
637 | static int init_guest_page(struct intel_vgpu *vgpu, | ||
638 | struct intel_vgpu_guest_page *p, | ||
639 | unsigned long gfn, | ||
640 | int (*handler)(void *, u64, void *, int), | ||
641 | void *data) | ||
642 | { | ||
643 | p->oos_page = NULL; | ||
644 | p->write_cnt = 0; | ||
645 | |||
646 | return intel_vgpu_init_page_track(vgpu, &p->track, gfn, handler, data); | ||
647 | } | ||
648 | |||
649 | static int detach_oos_page(struct intel_vgpu *vgpu, | ||
650 | struct intel_vgpu_oos_page *oos_page); | ||
651 | |||
652 | static void clean_guest_page(struct intel_vgpu *vgpu, | ||
653 | struct intel_vgpu_guest_page *p) | ||
654 | { | ||
655 | if (p->oos_page) | ||
656 | detach_oos_page(vgpu, p->oos_page); | ||
657 | |||
658 | intel_vgpu_clean_page_track(vgpu, &p->track); | ||
659 | } | ||
660 | |||
620 | static inline int init_shadow_page(struct intel_vgpu *vgpu, | 661 | static inline int init_shadow_page(struct intel_vgpu *vgpu, |
621 | struct intel_vgpu_shadow_page *p, int type) | 662 | struct intel_vgpu_shadow_page *p, int type, bool hash) |
622 | { | 663 | { |
623 | struct device *kdev = &vgpu->gvt->dev_priv->drm.pdev->dev; | 664 | struct device *kdev = &vgpu->gvt->dev_priv->drm.pdev->dev; |
624 | dma_addr_t daddr; | 665 | dma_addr_t daddr; |
@@ -634,8 +675,9 @@ static inline int init_shadow_page(struct intel_vgpu *vgpu, | |||
634 | 675 | ||
635 | INIT_HLIST_NODE(&p->node); | 676 | INIT_HLIST_NODE(&p->node); |
636 | 677 | ||
637 | p->mfn = daddr >> GTT_PAGE_SHIFT; | 678 | p->mfn = daddr >> I915_GTT_PAGE_SHIFT; |
638 | hash_add(vgpu->gtt.shadow_page_hash_table, &p->node, p->mfn); | 679 | if (hash) |
680 | hash_add(vgpu->gtt.shadow_page_hash_table, &p->node, p->mfn); | ||
639 | return 0; | 681 | return 0; |
640 | } | 682 | } |
641 | 683 | ||
@@ -644,7 +686,7 @@ static inline void clean_shadow_page(struct intel_vgpu *vgpu, | |||
644 | { | 686 | { |
645 | struct device *kdev = &vgpu->gvt->dev_priv->drm.pdev->dev; | 687 | struct device *kdev = &vgpu->gvt->dev_priv->drm.pdev->dev; |
646 | 688 | ||
647 | dma_unmap_page(kdev, p->mfn << GTT_PAGE_SHIFT, 4096, | 689 | dma_unmap_page(kdev, p->mfn << I915_GTT_PAGE_SHIFT, 4096, |
648 | PCI_DMA_BIDIRECTIONAL); | 690 | PCI_DMA_BIDIRECTIONAL); |
649 | 691 | ||
650 | if (!hlist_unhashed(&p->node)) | 692 | if (!hlist_unhashed(&p->node)) |
@@ -664,6 +706,9 @@ static inline struct intel_vgpu_shadow_page *find_shadow_page( | |||
664 | return NULL; | 706 | return NULL; |
665 | } | 707 | } |
666 | 708 | ||
709 | #define page_track_to_guest_page(ptr) \ | ||
710 | container_of(ptr, struct intel_vgpu_guest_page, track) | ||
711 | |||
667 | #define guest_page_to_ppgtt_spt(ptr) \ | 712 | #define guest_page_to_ppgtt_spt(ptr) \ |
668 | container_of(ptr, struct intel_vgpu_ppgtt_spt, guest_page) | 713 | container_of(ptr, struct intel_vgpu_ppgtt_spt, guest_page) |
669 | 714 | ||
@@ -697,7 +742,7 @@ static void ppgtt_free_shadow_page(struct intel_vgpu_ppgtt_spt *spt) | |||
697 | trace_spt_free(spt->vgpu->id, spt, spt->shadow_page.type); | 742 | trace_spt_free(spt->vgpu->id, spt, spt->shadow_page.type); |
698 | 743 | ||
699 | clean_shadow_page(spt->vgpu, &spt->shadow_page); | 744 | clean_shadow_page(spt->vgpu, &spt->shadow_page); |
700 | intel_vgpu_clean_guest_page(spt->vgpu, &spt->guest_page); | 745 | clean_guest_page(spt->vgpu, &spt->guest_page); |
701 | list_del_init(&spt->post_shadow_list); | 746 | list_del_init(&spt->post_shadow_list); |
702 | 747 | ||
703 | free_spt(spt); | 748 | free_spt(spt); |
@@ -713,22 +758,24 @@ static void ppgtt_free_all_shadow_page(struct intel_vgpu *vgpu) | |||
713 | ppgtt_free_shadow_page(shadow_page_to_ppgtt_spt(sp)); | 758 | ppgtt_free_shadow_page(shadow_page_to_ppgtt_spt(sp)); |
714 | } | 759 | } |
715 | 760 | ||
716 | static int ppgtt_handle_guest_write_page_table_bytes(void *gp, | 761 | static int ppgtt_handle_guest_write_page_table_bytes( |
762 | struct intel_vgpu_guest_page *gpt, | ||
717 | u64 pa, void *p_data, int bytes); | 763 | u64 pa, void *p_data, int bytes); |
718 | 764 | ||
719 | static int ppgtt_write_protection_handler(void *gp, u64 pa, | 765 | static int ppgtt_write_protection_handler(void *data, u64 pa, |
720 | void *p_data, int bytes) | 766 | void *p_data, int bytes) |
721 | { | 767 | { |
722 | struct intel_vgpu_guest_page *gpt = (struct intel_vgpu_guest_page *)gp; | 768 | struct intel_vgpu_page_track *t = data; |
769 | struct intel_vgpu_guest_page *p = page_track_to_guest_page(t); | ||
723 | int ret; | 770 | int ret; |
724 | 771 | ||
725 | if (bytes != 4 && bytes != 8) | 772 | if (bytes != 4 && bytes != 8) |
726 | return -EINVAL; | 773 | return -EINVAL; |
727 | 774 | ||
728 | if (!gpt->writeprotection) | 775 | if (!t->tracked) |
729 | return -EINVAL; | 776 | return -EINVAL; |
730 | 777 | ||
731 | ret = ppgtt_handle_guest_write_page_table_bytes(gp, | 778 | ret = ppgtt_handle_guest_write_page_table_bytes(p, |
732 | pa, p_data, bytes); | 779 | pa, p_data, bytes); |
733 | if (ret) | 780 | if (ret) |
734 | return ret; | 781 | return ret; |
@@ -762,13 +809,13 @@ retry: | |||
762 | * TODO: guest page type may be different with shadow page type, | 809 | * TODO: guest page type may be different with shadow page type, |
763 | * when we support PSE page in future. | 810 | * when we support PSE page in future. |
764 | */ | 811 | */ |
765 | ret = init_shadow_page(vgpu, &spt->shadow_page, type); | 812 | ret = init_shadow_page(vgpu, &spt->shadow_page, type, true); |
766 | if (ret) { | 813 | if (ret) { |
767 | gvt_vgpu_err("fail to initialize shadow page for spt\n"); | 814 | gvt_vgpu_err("fail to initialize shadow page for spt\n"); |
768 | goto err; | 815 | goto err; |
769 | } | 816 | } |
770 | 817 | ||
771 | ret = intel_vgpu_init_guest_page(vgpu, &spt->guest_page, | 818 | ret = init_guest_page(vgpu, &spt->guest_page, |
772 | gfn, ppgtt_write_protection_handler, NULL); | 819 | gfn, ppgtt_write_protection_handler, NULL); |
773 | if (ret) { | 820 | if (ret) { |
774 | gvt_vgpu_err("fail to initialize guest page for spt\n"); | 821 | gvt_vgpu_err("fail to initialize guest page for spt\n"); |
@@ -798,7 +845,7 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_find_shadow_page( | |||
798 | ((spt)->vgpu->gvt->device_info.gtt_entry_size_shift) | 845 | ((spt)->vgpu->gvt->device_info.gtt_entry_size_shift) |
799 | 846 | ||
800 | #define pt_entries(spt) \ | 847 | #define pt_entries(spt) \ |
801 | (GTT_PAGE_SIZE >> pt_entry_size_shift(spt)) | 848 | (I915_GTT_PAGE_SIZE >> pt_entry_size_shift(spt)) |
802 | 849 | ||
803 | #define for_each_present_guest_entry(spt, e, i) \ | 850 | #define for_each_present_guest_entry(spt, e, i) \ |
804 | for (i = 0; i < pt_entries(spt); i++) \ | 851 | for (i = 0; i < pt_entries(spt); i++) \ |
@@ -856,7 +903,7 @@ static int ppgtt_invalidate_shadow_page(struct intel_vgpu_ppgtt_spt *spt) | |||
856 | int v = atomic_read(&spt->refcount); | 903 | int v = atomic_read(&spt->refcount); |
857 | 904 | ||
858 | trace_spt_change(spt->vgpu->id, "die", spt, | 905 | trace_spt_change(spt->vgpu->id, "die", spt, |
859 | spt->guest_page.gfn, spt->shadow_page.type); | 906 | spt->guest_page.track.gfn, spt->shadow_page.type); |
860 | 907 | ||
861 | trace_spt_refcount(spt->vgpu->id, "dec", spt, v, (v - 1)); | 908 | trace_spt_refcount(spt->vgpu->id, "dec", spt, v, (v - 1)); |
862 | 909 | ||
@@ -878,7 +925,7 @@ static int ppgtt_invalidate_shadow_page(struct intel_vgpu_ppgtt_spt *spt) | |||
878 | } | 925 | } |
879 | release: | 926 | release: |
880 | trace_spt_change(spt->vgpu->id, "release", spt, | 927 | trace_spt_change(spt->vgpu->id, "release", spt, |
881 | spt->guest_page.gfn, spt->shadow_page.type); | 928 | spt->guest_page.track.gfn, spt->shadow_page.type); |
882 | ppgtt_free_shadow_page(spt); | 929 | ppgtt_free_shadow_page(spt); |
883 | return 0; | 930 | return 0; |
884 | fail: | 931 | fail: |
@@ -895,6 +942,7 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_populate_shadow_page_by_guest_entry( | |||
895 | struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops; | 942 | struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops; |
896 | struct intel_vgpu_ppgtt_spt *s = NULL; | 943 | struct intel_vgpu_ppgtt_spt *s = NULL; |
897 | struct intel_vgpu_guest_page *g; | 944 | struct intel_vgpu_guest_page *g; |
945 | struct intel_vgpu_page_track *t; | ||
898 | int ret; | 946 | int ret; |
899 | 947 | ||
900 | if (WARN_ON(!gtt_type_is_pt(get_next_pt_type(we->type)))) { | 948 | if (WARN_ON(!gtt_type_is_pt(get_next_pt_type(we->type)))) { |
@@ -902,8 +950,9 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_populate_shadow_page_by_guest_entry( | |||
902 | goto fail; | 950 | goto fail; |
903 | } | 951 | } |
904 | 952 | ||
905 | g = intel_vgpu_find_guest_page(vgpu, ops->get_pfn(we)); | 953 | t = intel_vgpu_find_tracked_page(vgpu, ops->get_pfn(we)); |
906 | if (g) { | 954 | if (t) { |
955 | g = page_track_to_guest_page(t); | ||
907 | s = guest_page_to_ppgtt_spt(g); | 956 | s = guest_page_to_ppgtt_spt(g); |
908 | ppgtt_get_shadow_page(s); | 957 | ppgtt_get_shadow_page(s); |
909 | } else { | 958 | } else { |
@@ -915,7 +964,8 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_populate_shadow_page_by_guest_entry( | |||
915 | goto fail; | 964 | goto fail; |
916 | } | 965 | } |
917 | 966 | ||
918 | ret = intel_gvt_hypervisor_set_wp_page(vgpu, &s->guest_page); | 967 | ret = intel_gvt_hypervisor_enable_page_track(vgpu, |
968 | &s->guest_page.track); | ||
919 | if (ret) | 969 | if (ret) |
920 | goto fail; | 970 | goto fail; |
921 | 971 | ||
@@ -923,7 +973,7 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_populate_shadow_page_by_guest_entry( | |||
923 | if (ret) | 973 | if (ret) |
924 | goto fail; | 974 | goto fail; |
925 | 975 | ||
926 | trace_spt_change(vgpu->id, "new", s, s->guest_page.gfn, | 976 | trace_spt_change(vgpu->id, "new", s, s->guest_page.track.gfn, |
927 | s->shadow_page.type); | 977 | s->shadow_page.type); |
928 | } | 978 | } |
929 | return s; | 979 | return s; |
@@ -953,7 +1003,7 @@ static int ppgtt_populate_shadow_page(struct intel_vgpu_ppgtt_spt *spt) | |||
953 | int ret; | 1003 | int ret; |
954 | 1004 | ||
955 | trace_spt_change(spt->vgpu->id, "born", spt, | 1005 | trace_spt_change(spt->vgpu->id, "born", spt, |
956 | spt->guest_page.gfn, spt->shadow_page.type); | 1006 | spt->guest_page.track.gfn, spt->shadow_page.type); |
957 | 1007 | ||
958 | if (gtt_type_is_pte_pt(spt->shadow_page.type)) { | 1008 | if (gtt_type_is_pte_pt(spt->shadow_page.type)) { |
959 | for_each_present_guest_entry(spt, &ge, i) { | 1009 | for_each_present_guest_entry(spt, &ge, i) { |
@@ -1078,11 +1128,11 @@ static int sync_oos_page(struct intel_vgpu *vgpu, | |||
1078 | old.type = new.type = get_entry_type(spt->guest_page_type); | 1128 | old.type = new.type = get_entry_type(spt->guest_page_type); |
1079 | old.val64 = new.val64 = 0; | 1129 | old.val64 = new.val64 = 0; |
1080 | 1130 | ||
1081 | for (index = 0; index < (GTT_PAGE_SIZE >> info->gtt_entry_size_shift); | 1131 | for (index = 0; index < (I915_GTT_PAGE_SIZE >> |
1082 | index++) { | 1132 | info->gtt_entry_size_shift); index++) { |
1083 | ops->get_entry(oos_page->mem, &old, index, false, 0, vgpu); | 1133 | ops->get_entry(oos_page->mem, &old, index, false, 0, vgpu); |
1084 | ops->get_entry(NULL, &new, index, true, | 1134 | ops->get_entry(NULL, &new, index, true, |
1085 | oos_page->guest_page->gfn << PAGE_SHIFT, vgpu); | 1135 | oos_page->guest_page->track.gfn << PAGE_SHIFT, vgpu); |
1086 | 1136 | ||
1087 | if (old.val64 == new.val64 | 1137 | if (old.val64 == new.val64 |
1088 | && !test_and_clear_bit(index, spt->post_shadow_bitmap)) | 1138 | && !test_and_clear_bit(index, spt->post_shadow_bitmap)) |
@@ -1132,8 +1182,9 @@ static int attach_oos_page(struct intel_vgpu *vgpu, | |||
1132 | struct intel_gvt *gvt = vgpu->gvt; | 1182 | struct intel_gvt *gvt = vgpu->gvt; |
1133 | int ret; | 1183 | int ret; |
1134 | 1184 | ||
1135 | ret = intel_gvt_hypervisor_read_gpa(vgpu, gpt->gfn << GTT_PAGE_SHIFT, | 1185 | ret = intel_gvt_hypervisor_read_gpa(vgpu, |
1136 | oos_page->mem, GTT_PAGE_SIZE); | 1186 | gpt->track.gfn << I915_GTT_PAGE_SHIFT, |
1187 | oos_page->mem, I915_GTT_PAGE_SIZE); | ||
1137 | if (ret) | 1188 | if (ret) |
1138 | return ret; | 1189 | return ret; |
1139 | 1190 | ||
@@ -1152,7 +1203,7 @@ static int ppgtt_set_guest_page_sync(struct intel_vgpu *vgpu, | |||
1152 | { | 1203 | { |
1153 | int ret; | 1204 | int ret; |
1154 | 1205 | ||
1155 | ret = intel_gvt_hypervisor_set_wp_page(vgpu, gpt); | 1206 | ret = intel_gvt_hypervisor_enable_page_track(vgpu, &gpt->track); |
1156 | if (ret) | 1207 | if (ret) |
1157 | return ret; | 1208 | return ret; |
1158 | 1209 | ||
@@ -1200,7 +1251,7 @@ static int ppgtt_set_guest_page_oos(struct intel_vgpu *vgpu, | |||
1200 | gpt, guest_page_to_ppgtt_spt(gpt)->guest_page_type); | 1251 | gpt, guest_page_to_ppgtt_spt(gpt)->guest_page_type); |
1201 | 1252 | ||
1202 | list_add_tail(&oos_page->vm_list, &vgpu->gtt.oos_page_list_head); | 1253 | list_add_tail(&oos_page->vm_list, &vgpu->gtt.oos_page_list_head); |
1203 | return intel_gvt_hypervisor_unset_wp_page(vgpu, gpt); | 1254 | return intel_gvt_hypervisor_disable_page_track(vgpu, &gpt->track); |
1204 | } | 1255 | } |
1205 | 1256 | ||
1206 | /** | 1257 | /** |
@@ -1335,10 +1386,10 @@ int intel_vgpu_flush_post_shadow(struct intel_vgpu *vgpu) | |||
1335 | return 0; | 1386 | return 0; |
1336 | } | 1387 | } |
1337 | 1388 | ||
1338 | static int ppgtt_handle_guest_write_page_table_bytes(void *gp, | 1389 | static int ppgtt_handle_guest_write_page_table_bytes( |
1390 | struct intel_vgpu_guest_page *gpt, | ||
1339 | u64 pa, void *p_data, int bytes) | 1391 | u64 pa, void *p_data, int bytes) |
1340 | { | 1392 | { |
1341 | struct intel_vgpu_guest_page *gpt = (struct intel_vgpu_guest_page *)gp; | ||
1342 | struct intel_vgpu_ppgtt_spt *spt = guest_page_to_ppgtt_spt(gpt); | 1393 | struct intel_vgpu_ppgtt_spt *spt = guest_page_to_ppgtt_spt(gpt); |
1343 | struct intel_vgpu *vgpu = spt->vgpu; | 1394 | struct intel_vgpu *vgpu = spt->vgpu; |
1344 | struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops; | 1395 | struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops; |
@@ -1415,7 +1466,7 @@ static int gen8_mm_alloc_page_table(struct intel_vgpu_mm *mm) | |||
1415 | mm->shadow_page_table = mem + mm->page_table_entry_size; | 1466 | mm->shadow_page_table = mem + mm->page_table_entry_size; |
1416 | } else if (mm->type == INTEL_GVT_MM_GGTT) { | 1467 | } else if (mm->type == INTEL_GVT_MM_GGTT) { |
1417 | mm->page_table_entry_cnt = | 1468 | mm->page_table_entry_cnt = |
1418 | (gvt_ggtt_gm_sz(gvt) >> GTT_PAGE_SHIFT); | 1469 | (gvt_ggtt_gm_sz(gvt) >> I915_GTT_PAGE_SHIFT); |
1419 | mm->page_table_entry_size = mm->page_table_entry_cnt * | 1470 | mm->page_table_entry_size = mm->page_table_entry_cnt * |
1420 | info->gtt_entry_size; | 1471 | info->gtt_entry_size; |
1421 | mem = vzalloc(mm->page_table_entry_size); | 1472 | mem = vzalloc(mm->page_table_entry_size); |
@@ -1737,8 +1788,8 @@ unsigned long intel_vgpu_gma_to_gpa(struct intel_vgpu_mm *mm, unsigned long gma) | |||
1737 | gma_ops->gma_to_ggtt_pte_index(gma)); | 1788 | gma_ops->gma_to_ggtt_pte_index(gma)); |
1738 | if (ret) | 1789 | if (ret) |
1739 | goto err; | 1790 | goto err; |
1740 | gpa = (pte_ops->get_pfn(&e) << GTT_PAGE_SHIFT) | 1791 | gpa = (pte_ops->get_pfn(&e) << I915_GTT_PAGE_SHIFT) |
1741 | + (gma & ~GTT_PAGE_MASK); | 1792 | + (gma & ~I915_GTT_PAGE_MASK); |
1742 | 1793 | ||
1743 | trace_gma_translate(vgpu->id, "ggtt", 0, 0, gma, gpa); | 1794 | trace_gma_translate(vgpu->id, "ggtt", 0, 0, gma, gpa); |
1744 | return gpa; | 1795 | return gpa; |
@@ -1790,8 +1841,8 @@ unsigned long intel_vgpu_gma_to_gpa(struct intel_vgpu_mm *mm, unsigned long gma) | |||
1790 | } | 1841 | } |
1791 | } | 1842 | } |
1792 | 1843 | ||
1793 | gpa = (pte_ops->get_pfn(&e) << GTT_PAGE_SHIFT) | 1844 | gpa = (pte_ops->get_pfn(&e) << I915_GTT_PAGE_SHIFT) |
1794 | + (gma & ~GTT_PAGE_MASK); | 1845 | + (gma & ~I915_GTT_PAGE_MASK); |
1795 | 1846 | ||
1796 | trace_gma_translate(vgpu->id, "ppgtt", 0, | 1847 | trace_gma_translate(vgpu->id, "ppgtt", 0, |
1797 | mm->page_table_level, gma, gpa); | 1848 | mm->page_table_level, gma, gpa); |
@@ -1859,7 +1910,7 @@ static int emulate_gtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, | |||
1859 | if (bytes != 4 && bytes != 8) | 1910 | if (bytes != 4 && bytes != 8) |
1860 | return -EINVAL; | 1911 | return -EINVAL; |
1861 | 1912 | ||
1862 | gma = g_gtt_index << GTT_PAGE_SHIFT; | 1913 | gma = g_gtt_index << I915_GTT_PAGE_SHIFT; |
1863 | 1914 | ||
1864 | /* the VM may configure the whole GM space when ballooning is used */ | 1915 | /* the VM may configure the whole GM space when ballooning is used */ |
1865 | if (!vgpu_gmadr_is_valid(vgpu, gma)) | 1916 | if (!vgpu_gmadr_is_valid(vgpu, gma)) |
@@ -1878,11 +1929,11 @@ static int emulate_gtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, | |||
1878 | * update the entry in this situation p2m will fail | 1929 | * update the entry in this situation p2m will fail |
1879 | * settting the shadow entry to point to a scratch page | 1930 | * settting the shadow entry to point to a scratch page |
1880 | */ | 1931 | */ |
1881 | ops->set_pfn(&m, gvt->gtt.scratch_ggtt_mfn); | 1932 | ops->set_pfn(&m, gvt->gtt.scratch_mfn); |
1882 | } | 1933 | } |
1883 | } else { | 1934 | } else { |
1884 | m = e; | 1935 | m = e; |
1885 | ops->set_pfn(&m, gvt->gtt.scratch_ggtt_mfn); | 1936 | ops->set_pfn(&m, gvt->gtt.scratch_mfn); |
1886 | } | 1937 | } |
1887 | 1938 | ||
1888 | ggtt_set_shadow_entry(ggtt_mm, &m, g_gtt_index); | 1939 | ggtt_set_shadow_entry(ggtt_mm, &m, g_gtt_index); |
@@ -1922,7 +1973,7 @@ static int alloc_scratch_pages(struct intel_vgpu *vgpu, | |||
1922 | { | 1973 | { |
1923 | struct intel_vgpu_gtt *gtt = &vgpu->gtt; | 1974 | struct intel_vgpu_gtt *gtt = &vgpu->gtt; |
1924 | struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops; | 1975 | struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops; |
1925 | int page_entry_num = GTT_PAGE_SIZE >> | 1976 | int page_entry_num = I915_GTT_PAGE_SIZE >> |
1926 | vgpu->gvt->device_info.gtt_entry_size_shift; | 1977 | vgpu->gvt->device_info.gtt_entry_size_shift; |
1927 | void *scratch_pt; | 1978 | void *scratch_pt; |
1928 | int i; | 1979 | int i; |
@@ -1946,7 +1997,7 @@ static int alloc_scratch_pages(struct intel_vgpu *vgpu, | |||
1946 | return -ENOMEM; | 1997 | return -ENOMEM; |
1947 | } | 1998 | } |
1948 | gtt->scratch_pt[type].page_mfn = | 1999 | gtt->scratch_pt[type].page_mfn = |
1949 | (unsigned long)(daddr >> GTT_PAGE_SHIFT); | 2000 | (unsigned long)(daddr >> I915_GTT_PAGE_SHIFT); |
1950 | gtt->scratch_pt[type].page = virt_to_page(scratch_pt); | 2001 | gtt->scratch_pt[type].page = virt_to_page(scratch_pt); |
1951 | gvt_dbg_mm("vgpu%d create scratch_pt: type %d mfn=0x%lx\n", | 2002 | gvt_dbg_mm("vgpu%d create scratch_pt: type %d mfn=0x%lx\n", |
1952 | vgpu->id, type, gtt->scratch_pt[type].page_mfn); | 2003 | vgpu->id, type, gtt->scratch_pt[type].page_mfn); |
@@ -1989,7 +2040,7 @@ static int release_scratch_page_tree(struct intel_vgpu *vgpu) | |||
1989 | for (i = GTT_TYPE_PPGTT_PTE_PT; i < GTT_TYPE_MAX; i++) { | 2040 | for (i = GTT_TYPE_PPGTT_PTE_PT; i < GTT_TYPE_MAX; i++) { |
1990 | if (vgpu->gtt.scratch_pt[i].page != NULL) { | 2041 | if (vgpu->gtt.scratch_pt[i].page != NULL) { |
1991 | daddr = (dma_addr_t)(vgpu->gtt.scratch_pt[i].page_mfn << | 2042 | daddr = (dma_addr_t)(vgpu->gtt.scratch_pt[i].page_mfn << |
1992 | GTT_PAGE_SHIFT); | 2043 | I915_GTT_PAGE_SHIFT); |
1993 | dma_unmap_page(dev, daddr, 4096, PCI_DMA_BIDIRECTIONAL); | 2044 | dma_unmap_page(dev, daddr, 4096, PCI_DMA_BIDIRECTIONAL); |
1994 | __free_page(vgpu->gtt.scratch_pt[i].page); | 2045 | __free_page(vgpu->gtt.scratch_pt[i].page); |
1995 | vgpu->gtt.scratch_pt[i].page = NULL; | 2046 | vgpu->gtt.scratch_pt[i].page = NULL; |
@@ -2032,7 +2083,7 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu) | |||
2032 | struct intel_vgpu_gtt *gtt = &vgpu->gtt; | 2083 | struct intel_vgpu_gtt *gtt = &vgpu->gtt; |
2033 | struct intel_vgpu_mm *ggtt_mm; | 2084 | struct intel_vgpu_mm *ggtt_mm; |
2034 | 2085 | ||
2035 | hash_init(gtt->guest_page_hash_table); | 2086 | hash_init(gtt->tracked_guest_page_hash_table); |
2036 | hash_init(gtt->shadow_page_hash_table); | 2087 | hash_init(gtt->shadow_page_hash_table); |
2037 | 2088 | ||
2038 | INIT_LIST_HEAD(>t->mm_list_head); | 2089 | INIT_LIST_HEAD(>t->mm_list_head); |
@@ -2285,15 +2336,16 @@ int intel_gvt_init_gtt(struct intel_gvt *gvt) | |||
2285 | __free_page(virt_to_page(page)); | 2336 | __free_page(virt_to_page(page)); |
2286 | return -ENOMEM; | 2337 | return -ENOMEM; |
2287 | } | 2338 | } |
2288 | gvt->gtt.scratch_ggtt_page = virt_to_page(page); | 2339 | |
2289 | gvt->gtt.scratch_ggtt_mfn = (unsigned long)(daddr >> GTT_PAGE_SHIFT); | 2340 | gvt->gtt.scratch_page = virt_to_page(page); |
2341 | gvt->gtt.scratch_mfn = (unsigned long)(daddr >> I915_GTT_PAGE_SHIFT); | ||
2290 | 2342 | ||
2291 | if (enable_out_of_sync) { | 2343 | if (enable_out_of_sync) { |
2292 | ret = setup_spt_oos(gvt); | 2344 | ret = setup_spt_oos(gvt); |
2293 | if (ret) { | 2345 | if (ret) { |
2294 | gvt_err("fail to initialize SPT oos\n"); | 2346 | gvt_err("fail to initialize SPT oos\n"); |
2295 | dma_unmap_page(dev, daddr, 4096, PCI_DMA_BIDIRECTIONAL); | 2347 | dma_unmap_page(dev, daddr, 4096, PCI_DMA_BIDIRECTIONAL); |
2296 | __free_page(gvt->gtt.scratch_ggtt_page); | 2348 | __free_page(gvt->gtt.scratch_page); |
2297 | return ret; | 2349 | return ret; |
2298 | } | 2350 | } |
2299 | } | 2351 | } |
@@ -2312,12 +2364,12 @@ int intel_gvt_init_gtt(struct intel_gvt *gvt) | |||
2312 | void intel_gvt_clean_gtt(struct intel_gvt *gvt) | 2364 | void intel_gvt_clean_gtt(struct intel_gvt *gvt) |
2313 | { | 2365 | { |
2314 | struct device *dev = &gvt->dev_priv->drm.pdev->dev; | 2366 | struct device *dev = &gvt->dev_priv->drm.pdev->dev; |
2315 | dma_addr_t daddr = (dma_addr_t)(gvt->gtt.scratch_ggtt_mfn << | 2367 | dma_addr_t daddr = (dma_addr_t)(gvt->gtt.scratch_mfn << |
2316 | GTT_PAGE_SHIFT); | 2368 | I915_GTT_PAGE_SHIFT); |
2317 | 2369 | ||
2318 | dma_unmap_page(dev, daddr, 4096, PCI_DMA_BIDIRECTIONAL); | 2370 | dma_unmap_page(dev, daddr, 4096, PCI_DMA_BIDIRECTIONAL); |
2319 | 2371 | ||
2320 | __free_page(gvt->gtt.scratch_ggtt_page); | 2372 | __free_page(gvt->gtt.scratch_page); |
2321 | 2373 | ||
2322 | if (enable_out_of_sync) | 2374 | if (enable_out_of_sync) |
2323 | clean_spt_oos(gvt); | 2375 | clean_spt_oos(gvt); |
@@ -2343,7 +2395,7 @@ void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu) | |||
2343 | 2395 | ||
2344 | memset(&e, 0, sizeof(struct intel_gvt_gtt_entry)); | 2396 | memset(&e, 0, sizeof(struct intel_gvt_gtt_entry)); |
2345 | e.type = GTT_TYPE_GGTT_PTE; | 2397 | e.type = GTT_TYPE_GGTT_PTE; |
2346 | ops->set_pfn(&e, gvt->gtt.scratch_ggtt_mfn); | 2398 | ops->set_pfn(&e, gvt->gtt.scratch_mfn); |
2347 | e.val64 |= _PAGE_PRESENT; | 2399 | e.val64 |= _PAGE_PRESENT; |
2348 | 2400 | ||
2349 | index = vgpu_aperture_gmadr_base(vgpu) >> PAGE_SHIFT; | 2401 | index = vgpu_aperture_gmadr_base(vgpu) >> PAGE_SHIFT; |
@@ -2369,8 +2421,6 @@ void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu) | |||
2369 | */ | 2421 | */ |
2370 | void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu) | 2422 | void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu) |
2371 | { | 2423 | { |
2372 | int i; | ||
2373 | |||
2374 | ppgtt_free_all_shadow_page(vgpu); | 2424 | ppgtt_free_all_shadow_page(vgpu); |
2375 | 2425 | ||
2376 | /* Shadow pages are only created when there is no page | 2426 | /* Shadow pages are only created when there is no page |
@@ -2380,11 +2430,4 @@ void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu) | |||
2380 | intel_vgpu_free_mm(vgpu, INTEL_GVT_MM_PPGTT); | 2430 | intel_vgpu_free_mm(vgpu, INTEL_GVT_MM_PPGTT); |
2381 | 2431 | ||
2382 | intel_vgpu_reset_ggtt(vgpu); | 2432 | intel_vgpu_reset_ggtt(vgpu); |
2383 | |||
2384 | /* clear scratch page for security */ | ||
2385 | for (i = GTT_TYPE_PPGTT_PTE_PT; i < GTT_TYPE_MAX; i++) { | ||
2386 | if (vgpu->gtt.scratch_pt[i].page != NULL) | ||
2387 | memset(page_address(vgpu->gtt.scratch_pt[i].page), | ||
2388 | 0, PAGE_SIZE); | ||
2389 | } | ||
2390 | } | 2433 | } |
diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h index 30a4c8d16026..f98c1c19b4cb 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.h +++ b/drivers/gpu/drm/i915/gvt/gtt.h | |||
@@ -34,9 +34,8 @@ | |||
34 | #ifndef _GVT_GTT_H_ | 34 | #ifndef _GVT_GTT_H_ |
35 | #define _GVT_GTT_H_ | 35 | #define _GVT_GTT_H_ |
36 | 36 | ||
37 | #define GTT_PAGE_SHIFT 12 | 37 | #define I915_GTT_PAGE_SHIFT 12 |
38 | #define GTT_PAGE_SIZE (1UL << GTT_PAGE_SHIFT) | 38 | #define I915_GTT_PAGE_MASK (~(I915_GTT_PAGE_SIZE - 1)) |
39 | #define GTT_PAGE_MASK (~(GTT_PAGE_SIZE-1)) | ||
40 | 39 | ||
41 | struct intel_vgpu_mm; | 40 | struct intel_vgpu_mm; |
42 | 41 | ||
@@ -63,6 +62,7 @@ struct intel_gvt_gtt_pte_ops { | |||
63 | struct intel_vgpu *vgpu); | 62 | struct intel_vgpu *vgpu); |
64 | bool (*test_present)(struct intel_gvt_gtt_entry *e); | 63 | bool (*test_present)(struct intel_gvt_gtt_entry *e); |
65 | void (*clear_present)(struct intel_gvt_gtt_entry *e); | 64 | void (*clear_present)(struct intel_gvt_gtt_entry *e); |
65 | void (*set_present)(struct intel_gvt_gtt_entry *e); | ||
66 | bool (*test_pse)(struct intel_gvt_gtt_entry *e); | 66 | bool (*test_pse)(struct intel_gvt_gtt_entry *e); |
67 | void (*set_pfn)(struct intel_gvt_gtt_entry *e, unsigned long pfn); | 67 | void (*set_pfn)(struct intel_gvt_gtt_entry *e, unsigned long pfn); |
68 | unsigned long (*get_pfn)(struct intel_gvt_gtt_entry *e); | 68 | unsigned long (*get_pfn)(struct intel_gvt_gtt_entry *e); |
@@ -86,8 +86,8 @@ struct intel_gvt_gtt { | |||
86 | struct list_head oos_page_free_list_head; | 86 | struct list_head oos_page_free_list_head; |
87 | struct list_head mm_lru_list_head; | 87 | struct list_head mm_lru_list_head; |
88 | 88 | ||
89 | struct page *scratch_ggtt_page; | 89 | struct page *scratch_page; |
90 | unsigned long scratch_ggtt_mfn; | 90 | unsigned long scratch_mfn; |
91 | }; | 91 | }; |
92 | 92 | ||
93 | enum { | 93 | enum { |
@@ -193,18 +193,16 @@ struct intel_vgpu_scratch_pt { | |||
193 | unsigned long page_mfn; | 193 | unsigned long page_mfn; |
194 | }; | 194 | }; |
195 | 195 | ||
196 | |||
197 | struct intel_vgpu_gtt { | 196 | struct intel_vgpu_gtt { |
198 | struct intel_vgpu_mm *ggtt_mm; | 197 | struct intel_vgpu_mm *ggtt_mm; |
199 | unsigned long active_ppgtt_mm_bitmap; | 198 | unsigned long active_ppgtt_mm_bitmap; |
200 | struct list_head mm_list_head; | 199 | struct list_head mm_list_head; |
201 | DECLARE_HASHTABLE(shadow_page_hash_table, INTEL_GVT_GTT_HASH_BITS); | 200 | DECLARE_HASHTABLE(shadow_page_hash_table, INTEL_GVT_GTT_HASH_BITS); |
202 | DECLARE_HASHTABLE(guest_page_hash_table, INTEL_GVT_GTT_HASH_BITS); | 201 | DECLARE_HASHTABLE(tracked_guest_page_hash_table, INTEL_GVT_GTT_HASH_BITS); |
203 | atomic_t n_write_protected_guest_page; | 202 | atomic_t n_tracked_guest_page; |
204 | struct list_head oos_page_list_head; | 203 | struct list_head oos_page_list_head; |
205 | struct list_head post_shadow_list_head; | 204 | struct list_head post_shadow_list_head; |
206 | struct intel_vgpu_scratch_pt scratch_pt[GTT_TYPE_MAX]; | 205 | struct intel_vgpu_scratch_pt scratch_pt[GTT_TYPE_MAX]; |
207 | |||
208 | }; | 206 | }; |
209 | 207 | ||
210 | extern int intel_vgpu_init_gtt(struct intel_vgpu *vgpu); | 208 | extern int intel_vgpu_init_gtt(struct intel_vgpu *vgpu); |
@@ -228,12 +226,16 @@ struct intel_vgpu_shadow_page { | |||
228 | unsigned long mfn; | 226 | unsigned long mfn; |
229 | }; | 227 | }; |
230 | 228 | ||
231 | struct intel_vgpu_guest_page { | 229 | struct intel_vgpu_page_track { |
232 | struct hlist_node node; | 230 | struct hlist_node node; |
233 | bool writeprotection; | 231 | bool tracked; |
234 | unsigned long gfn; | 232 | unsigned long gfn; |
235 | int (*handler)(void *, u64, void *, int); | 233 | int (*handler)(void *, u64, void *, int); |
236 | void *data; | 234 | void *data; |
235 | }; | ||
236 | |||
237 | struct intel_vgpu_guest_page { | ||
238 | struct intel_vgpu_page_track track; | ||
237 | unsigned long write_cnt; | 239 | unsigned long write_cnt; |
238 | struct intel_vgpu_oos_page *oos_page; | 240 | struct intel_vgpu_oos_page *oos_page; |
239 | }; | 241 | }; |
@@ -243,7 +245,7 @@ struct intel_vgpu_oos_page { | |||
243 | struct list_head list; | 245 | struct list_head list; |
244 | struct list_head vm_list; | 246 | struct list_head vm_list; |
245 | int id; | 247 | int id; |
246 | unsigned char mem[GTT_PAGE_SIZE]; | 248 | unsigned char mem[I915_GTT_PAGE_SIZE]; |
247 | }; | 249 | }; |
248 | 250 | ||
249 | #define GTT_ENTRY_NUM_IN_ONE_PAGE 512 | 251 | #define GTT_ENTRY_NUM_IN_ONE_PAGE 512 |
@@ -258,22 +260,16 @@ struct intel_vgpu_ppgtt_spt { | |||
258 | struct list_head post_shadow_list; | 260 | struct list_head post_shadow_list; |
259 | }; | 261 | }; |
260 | 262 | ||
261 | int intel_vgpu_init_guest_page(struct intel_vgpu *vgpu, | 263 | int intel_vgpu_init_page_track(struct intel_vgpu *vgpu, |
262 | struct intel_vgpu_guest_page *guest_page, | 264 | struct intel_vgpu_page_track *t, |
263 | unsigned long gfn, | 265 | unsigned long gfn, |
264 | int (*handler)(void *gp, u64, void *, int), | 266 | int (*handler)(void *gp, u64, void *, int), |
265 | void *data); | 267 | void *data); |
266 | 268 | ||
267 | void intel_vgpu_clean_guest_page(struct intel_vgpu *vgpu, | 269 | void intel_vgpu_clean_page_track(struct intel_vgpu *vgpu, |
268 | struct intel_vgpu_guest_page *guest_page); | 270 | struct intel_vgpu_page_track *t); |
269 | |||
270 | int intel_vgpu_set_guest_page_writeprotection(struct intel_vgpu *vgpu, | ||
271 | struct intel_vgpu_guest_page *guest_page); | ||
272 | |||
273 | void intel_vgpu_clear_guest_page_writeprotection(struct intel_vgpu *vgpu, | ||
274 | struct intel_vgpu_guest_page *guest_page); | ||
275 | 271 | ||
276 | struct intel_vgpu_guest_page *intel_vgpu_find_guest_page( | 272 | struct intel_vgpu_page_track *intel_vgpu_find_tracked_page( |
277 | struct intel_vgpu *vgpu, unsigned long gfn); | 273 | struct intel_vgpu *vgpu, unsigned long gfn); |
278 | 274 | ||
279 | int intel_vgpu_sync_oos_pages(struct intel_vgpu *vgpu); | 275 | int intel_vgpu_sync_oos_pages(struct intel_vgpu *vgpu); |
diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c index aaa347f8620c..3a74a408a966 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.c +++ b/drivers/gpu/drm/i915/gvt/gvt.c | |||
@@ -36,6 +36,8 @@ | |||
36 | 36 | ||
37 | #include "i915_drv.h" | 37 | #include "i915_drv.h" |
38 | #include "gvt.h" | 38 | #include "gvt.h" |
39 | #include <linux/vfio.h> | ||
40 | #include <linux/mdev.h> | ||
39 | 41 | ||
40 | struct intel_gvt_host intel_gvt_host; | 42 | struct intel_gvt_host intel_gvt_host; |
41 | 43 | ||
@@ -44,6 +46,129 @@ static const char * const supported_hypervisors[] = { | |||
44 | [INTEL_GVT_HYPERVISOR_KVM] = "KVM", | 46 | [INTEL_GVT_HYPERVISOR_KVM] = "KVM", |
45 | }; | 47 | }; |
46 | 48 | ||
49 | static struct intel_vgpu_type *intel_gvt_find_vgpu_type(struct intel_gvt *gvt, | ||
50 | const char *name) | ||
51 | { | ||
52 | int i; | ||
53 | struct intel_vgpu_type *t; | ||
54 | const char *driver_name = dev_driver_string( | ||
55 | &gvt->dev_priv->drm.pdev->dev); | ||
56 | |||
57 | for (i = 0; i < gvt->num_types; i++) { | ||
58 | t = &gvt->types[i]; | ||
59 | if (!strncmp(t->name, name + strlen(driver_name) + 1, | ||
60 | sizeof(t->name))) | ||
61 | return t; | ||
62 | } | ||
63 | |||
64 | return NULL; | ||
65 | } | ||
66 | |||
67 | static ssize_t available_instances_show(struct kobject *kobj, | ||
68 | struct device *dev, char *buf) | ||
69 | { | ||
70 | struct intel_vgpu_type *type; | ||
71 | unsigned int num = 0; | ||
72 | void *gvt = kdev_to_i915(dev)->gvt; | ||
73 | |||
74 | type = intel_gvt_find_vgpu_type(gvt, kobject_name(kobj)); | ||
75 | if (!type) | ||
76 | num = 0; | ||
77 | else | ||
78 | num = type->avail_instance; | ||
79 | |||
80 | return sprintf(buf, "%u\n", num); | ||
81 | } | ||
82 | |||
83 | static ssize_t device_api_show(struct kobject *kobj, struct device *dev, | ||
84 | char *buf) | ||
85 | { | ||
86 | return sprintf(buf, "%s\n", VFIO_DEVICE_API_PCI_STRING); | ||
87 | } | ||
88 | |||
89 | static ssize_t description_show(struct kobject *kobj, struct device *dev, | ||
90 | char *buf) | ||
91 | { | ||
92 | struct intel_vgpu_type *type; | ||
93 | void *gvt = kdev_to_i915(dev)->gvt; | ||
94 | |||
95 | type = intel_gvt_find_vgpu_type(gvt, kobject_name(kobj)); | ||
96 | if (!type) | ||
97 | return 0; | ||
98 | |||
99 | return sprintf(buf, "low_gm_size: %dMB\nhigh_gm_size: %dMB\n" | ||
100 | "fence: %d\nresolution: %s\n" | ||
101 | "weight: %d\n", | ||
102 | BYTES_TO_MB(type->low_gm_size), | ||
103 | BYTES_TO_MB(type->high_gm_size), | ||
104 | type->fence, vgpu_edid_str(type->resolution), | ||
105 | type->weight); | ||
106 | } | ||
107 | |||
108 | static MDEV_TYPE_ATTR_RO(available_instances); | ||
109 | static MDEV_TYPE_ATTR_RO(device_api); | ||
110 | static MDEV_TYPE_ATTR_RO(description); | ||
111 | |||
112 | static struct attribute *gvt_type_attrs[] = { | ||
113 | &mdev_type_attr_available_instances.attr, | ||
114 | &mdev_type_attr_device_api.attr, | ||
115 | &mdev_type_attr_description.attr, | ||
116 | NULL, | ||
117 | }; | ||
118 | |||
119 | static struct attribute_group *gvt_vgpu_type_groups[] = { | ||
120 | [0 ... NR_MAX_INTEL_VGPU_TYPES - 1] = NULL, | ||
121 | }; | ||
122 | |||
123 | static bool intel_get_gvt_attrs(struct attribute ***type_attrs, | ||
124 | struct attribute_group ***intel_vgpu_type_groups) | ||
125 | { | ||
126 | *type_attrs = gvt_type_attrs; | ||
127 | *intel_vgpu_type_groups = gvt_vgpu_type_groups; | ||
128 | return true; | ||
129 | } | ||
130 | |||
131 | static bool intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt) | ||
132 | { | ||
133 | int i, j; | ||
134 | struct intel_vgpu_type *type; | ||
135 | struct attribute_group *group; | ||
136 | |||
137 | for (i = 0; i < gvt->num_types; i++) { | ||
138 | type = &gvt->types[i]; | ||
139 | |||
140 | group = kzalloc(sizeof(struct attribute_group), GFP_KERNEL); | ||
141 | if (WARN_ON(!group)) | ||
142 | goto unwind; | ||
143 | |||
144 | group->name = type->name; | ||
145 | group->attrs = gvt_type_attrs; | ||
146 | gvt_vgpu_type_groups[i] = group; | ||
147 | } | ||
148 | |||
149 | return true; | ||
150 | |||
151 | unwind: | ||
152 | for (j = 0; j < i; j++) { | ||
153 | group = gvt_vgpu_type_groups[j]; | ||
154 | kfree(group); | ||
155 | } | ||
156 | |||
157 | return false; | ||
158 | } | ||
159 | |||
160 | static void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt) | ||
161 | { | ||
162 | int i; | ||
163 | struct attribute_group *group; | ||
164 | |||
165 | for (i = 0; i < gvt->num_types; i++) { | ||
166 | group = gvt_vgpu_type_groups[i]; | ||
167 | gvt_vgpu_type_groups[i] = NULL; | ||
168 | kfree(group); | ||
169 | } | ||
170 | } | ||
171 | |||
47 | static const struct intel_gvt_ops intel_gvt_ops = { | 172 | static const struct intel_gvt_ops intel_gvt_ops = { |
48 | .emulate_cfg_read = intel_vgpu_emulate_cfg_read, | 173 | .emulate_cfg_read = intel_vgpu_emulate_cfg_read, |
49 | .emulate_cfg_write = intel_vgpu_emulate_cfg_write, | 174 | .emulate_cfg_write = intel_vgpu_emulate_cfg_write, |
@@ -54,6 +179,8 @@ static const struct intel_gvt_ops intel_gvt_ops = { | |||
54 | .vgpu_reset = intel_gvt_reset_vgpu, | 179 | .vgpu_reset = intel_gvt_reset_vgpu, |
55 | .vgpu_activate = intel_gvt_activate_vgpu, | 180 | .vgpu_activate = intel_gvt_activate_vgpu, |
56 | .vgpu_deactivate = intel_gvt_deactivate_vgpu, | 181 | .vgpu_deactivate = intel_gvt_deactivate_vgpu, |
182 | .gvt_find_vgpu_type = intel_gvt_find_vgpu_type, | ||
183 | .get_gvt_attrs = intel_get_gvt_attrs, | ||
57 | }; | 184 | }; |
58 | 185 | ||
59 | /** | 186 | /** |
@@ -191,17 +318,18 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv) | |||
191 | if (WARN_ON(!gvt)) | 318 | if (WARN_ON(!gvt)) |
192 | return; | 319 | return; |
193 | 320 | ||
321 | intel_gvt_debugfs_clean(gvt); | ||
194 | clean_service_thread(gvt); | 322 | clean_service_thread(gvt); |
195 | intel_gvt_clean_cmd_parser(gvt); | 323 | intel_gvt_clean_cmd_parser(gvt); |
196 | intel_gvt_clean_sched_policy(gvt); | 324 | intel_gvt_clean_sched_policy(gvt); |
197 | intel_gvt_clean_workload_scheduler(gvt); | 325 | intel_gvt_clean_workload_scheduler(gvt); |
198 | intel_gvt_clean_opregion(gvt); | ||
199 | intel_gvt_clean_gtt(gvt); | 326 | intel_gvt_clean_gtt(gvt); |
200 | intel_gvt_clean_irq(gvt); | 327 | intel_gvt_clean_irq(gvt); |
201 | intel_gvt_clean_mmio_info(gvt); | 328 | intel_gvt_clean_mmio_info(gvt); |
202 | intel_gvt_free_firmware(gvt); | 329 | intel_gvt_free_firmware(gvt); |
203 | 330 | ||
204 | intel_gvt_hypervisor_host_exit(&dev_priv->drm.pdev->dev, gvt); | 331 | intel_gvt_hypervisor_host_exit(&dev_priv->drm.pdev->dev, gvt); |
332 | intel_gvt_cleanup_vgpu_type_groups(gvt); | ||
205 | intel_gvt_clean_vgpu_types(gvt); | 333 | intel_gvt_clean_vgpu_types(gvt); |
206 | 334 | ||
207 | idr_destroy(&gvt->vgpu_idr); | 335 | idr_destroy(&gvt->vgpu_idr); |
@@ -268,13 +396,9 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv) | |||
268 | if (ret) | 396 | if (ret) |
269 | goto out_clean_irq; | 397 | goto out_clean_irq; |
270 | 398 | ||
271 | ret = intel_gvt_init_opregion(gvt); | ||
272 | if (ret) | ||
273 | goto out_clean_gtt; | ||
274 | |||
275 | ret = intel_gvt_init_workload_scheduler(gvt); | 399 | ret = intel_gvt_init_workload_scheduler(gvt); |
276 | if (ret) | 400 | if (ret) |
277 | goto out_clean_opregion; | 401 | goto out_clean_gtt; |
278 | 402 | ||
279 | ret = intel_gvt_init_sched_policy(gvt); | 403 | ret = intel_gvt_init_sched_policy(gvt); |
280 | if (ret) | 404 | if (ret) |
@@ -292,6 +416,12 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv) | |||
292 | if (ret) | 416 | if (ret) |
293 | goto out_clean_thread; | 417 | goto out_clean_thread; |
294 | 418 | ||
419 | ret = intel_gvt_init_vgpu_type_groups(gvt); | ||
420 | if (ret == false) { | ||
421 | gvt_err("failed to init vgpu type groups: %d\n", ret); | ||
422 | goto out_clean_types; | ||
423 | } | ||
424 | |||
295 | ret = intel_gvt_hypervisor_host_init(&dev_priv->drm.pdev->dev, gvt, | 425 | ret = intel_gvt_hypervisor_host_init(&dev_priv->drm.pdev->dev, gvt, |
296 | &intel_gvt_ops); | 426 | &intel_gvt_ops); |
297 | if (ret) { | 427 | if (ret) { |
@@ -307,6 +437,10 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv) | |||
307 | } | 437 | } |
308 | gvt->idle_vgpu = vgpu; | 438 | gvt->idle_vgpu = vgpu; |
309 | 439 | ||
440 | ret = intel_gvt_debugfs_init(gvt); | ||
441 | if (ret) | ||
442 | gvt_err("debugfs registeration failed, go on.\n"); | ||
443 | |||
310 | gvt_dbg_core("gvt device initialization is done\n"); | 444 | gvt_dbg_core("gvt device initialization is done\n"); |
311 | dev_priv->gvt = gvt; | 445 | dev_priv->gvt = gvt; |
312 | return 0; | 446 | return 0; |
@@ -321,8 +455,6 @@ out_clean_sched_policy: | |||
321 | intel_gvt_clean_sched_policy(gvt); | 455 | intel_gvt_clean_sched_policy(gvt); |
322 | out_clean_workload_scheduler: | 456 | out_clean_workload_scheduler: |
323 | intel_gvt_clean_workload_scheduler(gvt); | 457 | intel_gvt_clean_workload_scheduler(gvt); |
324 | out_clean_opregion: | ||
325 | intel_gvt_clean_opregion(gvt); | ||
326 | out_clean_gtt: | 458 | out_clean_gtt: |
327 | intel_gvt_clean_gtt(gvt); | 459 | intel_gvt_clean_gtt(gvt); |
328 | out_clean_irq: | 460 | out_clean_irq: |
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 9c2e7c0aa38f..393066726993 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h | |||
@@ -125,7 +125,6 @@ struct intel_vgpu_irq { | |||
125 | struct intel_vgpu_opregion { | 125 | struct intel_vgpu_opregion { |
126 | void *va; | 126 | void *va; |
127 | u32 gfn[INTEL_GVT_OPREGION_PAGES]; | 127 | u32 gfn[INTEL_GVT_OPREGION_PAGES]; |
128 | struct page *pages[INTEL_GVT_OPREGION_PAGES]; | ||
129 | }; | 128 | }; |
130 | 129 | ||
131 | #define vgpu_opregion(vgpu) (&(vgpu->opregion)) | 130 | #define vgpu_opregion(vgpu) (&(vgpu->opregion)) |
@@ -142,6 +141,33 @@ struct vgpu_sched_ctl { | |||
142 | int weight; | 141 | int weight; |
143 | }; | 142 | }; |
144 | 143 | ||
144 | enum { | ||
145 | INTEL_VGPU_EXECLIST_SUBMISSION = 1, | ||
146 | INTEL_VGPU_GUC_SUBMISSION, | ||
147 | }; | ||
148 | |||
149 | struct intel_vgpu_submission_ops { | ||
150 | const char *name; | ||
151 | int (*init)(struct intel_vgpu *vgpu); | ||
152 | void (*clean)(struct intel_vgpu *vgpu); | ||
153 | void (*reset)(struct intel_vgpu *vgpu, unsigned long engine_mask); | ||
154 | }; | ||
155 | |||
156 | struct intel_vgpu_submission { | ||
157 | struct intel_vgpu_execlist execlist[I915_NUM_ENGINES]; | ||
158 | struct list_head workload_q_head[I915_NUM_ENGINES]; | ||
159 | struct kmem_cache *workloads; | ||
160 | atomic_t running_workload_num; | ||
161 | struct i915_gem_context *shadow_ctx; | ||
162 | DECLARE_BITMAP(shadow_ctx_desc_updated, I915_NUM_ENGINES); | ||
163 | DECLARE_BITMAP(tlb_handle_pending, I915_NUM_ENGINES); | ||
164 | void *ring_scan_buffer[I915_NUM_ENGINES]; | ||
165 | int ring_scan_buffer_size[I915_NUM_ENGINES]; | ||
166 | const struct intel_vgpu_submission_ops *ops; | ||
167 | int virtual_submission_interface; | ||
168 | bool active; | ||
169 | }; | ||
170 | |||
145 | struct intel_vgpu { | 171 | struct intel_vgpu { |
146 | struct intel_gvt *gvt; | 172 | struct intel_gvt *gvt; |
147 | int id; | 173 | int id; |
@@ -161,16 +187,10 @@ struct intel_vgpu { | |||
161 | struct intel_vgpu_gtt gtt; | 187 | struct intel_vgpu_gtt gtt; |
162 | struct intel_vgpu_opregion opregion; | 188 | struct intel_vgpu_opregion opregion; |
163 | struct intel_vgpu_display display; | 189 | struct intel_vgpu_display display; |
164 | struct intel_vgpu_execlist execlist[I915_NUM_ENGINES]; | 190 | struct intel_vgpu_submission submission; |
165 | struct list_head workload_q_head[I915_NUM_ENGINES]; | 191 | u32 hws_pga[I915_NUM_ENGINES]; |
166 | struct kmem_cache *workloads; | 192 | |
167 | atomic_t running_workload_num; | 193 | struct dentry *debugfs; |
168 | /* 1/2K for each reserve ring buffer */ | ||
169 | void *reserve_ring_buffer_va[I915_NUM_ENGINES]; | ||
170 | int reserve_ring_buffer_size[I915_NUM_ENGINES]; | ||
171 | DECLARE_BITMAP(tlb_handle_pending, I915_NUM_ENGINES); | ||
172 | struct i915_gem_context *shadow_ctx; | ||
173 | DECLARE_BITMAP(shadow_ctx_desc_updated, I915_NUM_ENGINES); | ||
174 | 194 | ||
175 | #if IS_ENABLED(CONFIG_DRM_I915_GVT_KVMGT) | 195 | #if IS_ENABLED(CONFIG_DRM_I915_GVT_KVMGT) |
176 | struct { | 196 | struct { |
@@ -190,6 +210,10 @@ struct intel_vgpu { | |||
190 | #endif | 210 | #endif |
191 | }; | 211 | }; |
192 | 212 | ||
213 | /* validating GM healthy status*/ | ||
214 | #define vgpu_is_vm_unhealthy(ret_val) \ | ||
215 | (((ret_val) == -EBADRQC) || ((ret_val) == -EFAULT)) | ||
216 | |||
193 | struct intel_gvt_gm { | 217 | struct intel_gvt_gm { |
194 | unsigned long vgpu_allocated_low_gm_size; | 218 | unsigned long vgpu_allocated_low_gm_size; |
195 | unsigned long vgpu_allocated_high_gm_size; | 219 | unsigned long vgpu_allocated_high_gm_size; |
@@ -231,7 +255,7 @@ struct intel_gvt_mmio { | |||
231 | unsigned int num_mmio_block; | 255 | unsigned int num_mmio_block; |
232 | 256 | ||
233 | DECLARE_HASHTABLE(mmio_info_table, INTEL_GVT_MMIO_HASH_BITS); | 257 | DECLARE_HASHTABLE(mmio_info_table, INTEL_GVT_MMIO_HASH_BITS); |
234 | unsigned int num_tracked_mmio; | 258 | unsigned long num_tracked_mmio; |
235 | }; | 259 | }; |
236 | 260 | ||
237 | struct intel_gvt_firmware { | 261 | struct intel_gvt_firmware { |
@@ -240,11 +264,6 @@ struct intel_gvt_firmware { | |||
240 | bool firmware_loaded; | 264 | bool firmware_loaded; |
241 | }; | 265 | }; |
242 | 266 | ||
243 | struct intel_gvt_opregion { | ||
244 | void *opregion_va; | ||
245 | u32 opregion_pa; | ||
246 | }; | ||
247 | |||
248 | #define NR_MAX_INTEL_VGPU_TYPES 20 | 267 | #define NR_MAX_INTEL_VGPU_TYPES 20 |
249 | struct intel_vgpu_type { | 268 | struct intel_vgpu_type { |
250 | char name[16]; | 269 | char name[16]; |
@@ -268,7 +287,6 @@ struct intel_gvt { | |||
268 | struct intel_gvt_firmware firmware; | 287 | struct intel_gvt_firmware firmware; |
269 | struct intel_gvt_irq irq; | 288 | struct intel_gvt_irq irq; |
270 | struct intel_gvt_gtt gtt; | 289 | struct intel_gvt_gtt gtt; |
271 | struct intel_gvt_opregion opregion; | ||
272 | struct intel_gvt_workload_scheduler scheduler; | 290 | struct intel_gvt_workload_scheduler scheduler; |
273 | struct notifier_block shadow_ctx_notifier_block[I915_NUM_ENGINES]; | 291 | struct notifier_block shadow_ctx_notifier_block[I915_NUM_ENGINES]; |
274 | DECLARE_HASHTABLE(cmd_table, GVT_CMD_HASH_BITS); | 292 | DECLARE_HASHTABLE(cmd_table, GVT_CMD_HASH_BITS); |
@@ -279,6 +297,8 @@ struct intel_gvt { | |||
279 | struct task_struct *service_thread; | 297 | struct task_struct *service_thread; |
280 | wait_queue_head_t service_thread_wq; | 298 | wait_queue_head_t service_thread_wq; |
281 | unsigned long service_request; | 299 | unsigned long service_request; |
300 | |||
301 | struct dentry *debugfs_root; | ||
282 | }; | 302 | }; |
283 | 303 | ||
284 | static inline struct intel_gvt *to_gvt(struct drm_i915_private *i915) | 304 | static inline struct intel_gvt *to_gvt(struct drm_i915_private *i915) |
@@ -484,9 +504,6 @@ static inline u64 intel_vgpu_get_bar_gpa(struct intel_vgpu *vgpu, int bar) | |||
484 | PCI_BASE_ADDRESS_MEM_MASK; | 504 | PCI_BASE_ADDRESS_MEM_MASK; |
485 | } | 505 | } |
486 | 506 | ||
487 | void intel_gvt_clean_opregion(struct intel_gvt *gvt); | ||
488 | int intel_gvt_init_opregion(struct intel_gvt *gvt); | ||
489 | |||
490 | void intel_vgpu_clean_opregion(struct intel_vgpu *vgpu); | 507 | void intel_vgpu_clean_opregion(struct intel_vgpu *vgpu); |
491 | int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa); | 508 | int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa); |
492 | 509 | ||
@@ -494,6 +511,7 @@ int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci); | |||
494 | void populate_pvinfo_page(struct intel_vgpu *vgpu); | 511 | void populate_pvinfo_page(struct intel_vgpu *vgpu); |
495 | 512 | ||
496 | int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload); | 513 | int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload); |
514 | void enter_failsafe_mode(struct intel_vgpu *vgpu, int reason); | ||
497 | 515 | ||
498 | struct intel_gvt_ops { | 516 | struct intel_gvt_ops { |
499 | int (*emulate_cfg_read)(struct intel_vgpu *, unsigned int, void *, | 517 | int (*emulate_cfg_read)(struct intel_vgpu *, unsigned int, void *, |
@@ -510,12 +528,17 @@ struct intel_gvt_ops { | |||
510 | void (*vgpu_reset)(struct intel_vgpu *); | 528 | void (*vgpu_reset)(struct intel_vgpu *); |
511 | void (*vgpu_activate)(struct intel_vgpu *); | 529 | void (*vgpu_activate)(struct intel_vgpu *); |
512 | void (*vgpu_deactivate)(struct intel_vgpu *); | 530 | void (*vgpu_deactivate)(struct intel_vgpu *); |
531 | struct intel_vgpu_type *(*gvt_find_vgpu_type)(struct intel_gvt *gvt, | ||
532 | const char *name); | ||
533 | bool (*get_gvt_attrs)(struct attribute ***type_attrs, | ||
534 | struct attribute_group ***intel_vgpu_type_groups); | ||
513 | }; | 535 | }; |
514 | 536 | ||
515 | 537 | ||
516 | enum { | 538 | enum { |
517 | GVT_FAILSAFE_UNSUPPORTED_GUEST, | 539 | GVT_FAILSAFE_UNSUPPORTED_GUEST, |
518 | GVT_FAILSAFE_INSUFFICIENT_RESOURCE, | 540 | GVT_FAILSAFE_INSUFFICIENT_RESOURCE, |
541 | GVT_FAILSAFE_GUEST_ERR, | ||
519 | }; | 542 | }; |
520 | 543 | ||
521 | static inline void mmio_hw_access_pre(struct drm_i915_private *dev_priv) | 544 | static inline void mmio_hw_access_pre(struct drm_i915_private *dev_priv) |
@@ -591,6 +614,12 @@ static inline bool intel_gvt_mmio_has_mode_mask( | |||
591 | return gvt->mmio.mmio_attribute[offset >> 2] & F_MODE_MASK; | 614 | return gvt->mmio.mmio_attribute[offset >> 2] & F_MODE_MASK; |
592 | } | 615 | } |
593 | 616 | ||
617 | int intel_gvt_debugfs_add_vgpu(struct intel_vgpu *vgpu); | ||
618 | void intel_gvt_debugfs_remove_vgpu(struct intel_vgpu *vgpu); | ||
619 | int intel_gvt_debugfs_init(struct intel_gvt *gvt); | ||
620 | void intel_gvt_debugfs_clean(struct intel_gvt *gvt); | ||
621 | |||
622 | |||
594 | #include "trace.h" | 623 | #include "trace.h" |
595 | #include "mpt.h" | 624 | #include "mpt.h" |
596 | 625 | ||
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 44cd5ff5e97d..94fc04210bac 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c | |||
@@ -137,17 +137,26 @@ static int new_mmio_info(struct intel_gvt *gvt, | |||
137 | return 0; | 137 | return 0; |
138 | } | 138 | } |
139 | 139 | ||
140 | static int render_mmio_to_ring_id(struct intel_gvt *gvt, unsigned int reg) | 140 | /** |
141 | * intel_gvt_render_mmio_to_ring_id - convert a mmio offset into ring id | ||
142 | * @gvt: a GVT device | ||
143 | * @offset: register offset | ||
144 | * | ||
145 | * Returns: | ||
146 | * Ring ID on success, negative error code if failed. | ||
147 | */ | ||
148 | int intel_gvt_render_mmio_to_ring_id(struct intel_gvt *gvt, | ||
149 | unsigned int offset) | ||
141 | { | 150 | { |
142 | enum intel_engine_id id; | 151 | enum intel_engine_id id; |
143 | struct intel_engine_cs *engine; | 152 | struct intel_engine_cs *engine; |
144 | 153 | ||
145 | reg &= ~GENMASK(11, 0); | 154 | offset &= ~GENMASK(11, 0); |
146 | for_each_engine(engine, gvt->dev_priv, id) { | 155 | for_each_engine(engine, gvt->dev_priv, id) { |
147 | if (engine->mmio_base == reg) | 156 | if (engine->mmio_base == offset) |
148 | return id; | 157 | return id; |
149 | } | 158 | } |
150 | return -1; | 159 | return -ENODEV; |
151 | } | 160 | } |
152 | 161 | ||
153 | #define offset_to_fence_num(offset) \ | 162 | #define offset_to_fence_num(offset) \ |
@@ -157,7 +166,7 @@ static int render_mmio_to_ring_id(struct intel_gvt *gvt, unsigned int reg) | |||
157 | (num * 8 + i915_mmio_reg_offset(FENCE_REG_GEN6_LO(0))) | 166 | (num * 8 + i915_mmio_reg_offset(FENCE_REG_GEN6_LO(0))) |
158 | 167 | ||
159 | 168 | ||
160 | static void enter_failsafe_mode(struct intel_vgpu *vgpu, int reason) | 169 | void enter_failsafe_mode(struct intel_vgpu *vgpu, int reason) |
161 | { | 170 | { |
162 | switch (reason) { | 171 | switch (reason) { |
163 | case GVT_FAILSAFE_UNSUPPORTED_GUEST: | 172 | case GVT_FAILSAFE_UNSUPPORTED_GUEST: |
@@ -165,6 +174,8 @@ static void enter_failsafe_mode(struct intel_vgpu *vgpu, int reason) | |||
165 | break; | 174 | break; |
166 | case GVT_FAILSAFE_INSUFFICIENT_RESOURCE: | 175 | case GVT_FAILSAFE_INSUFFICIENT_RESOURCE: |
167 | pr_err("Graphics resource is not enough for the guest\n"); | 176 | pr_err("Graphics resource is not enough for the guest\n"); |
177 | case GVT_FAILSAFE_GUEST_ERR: | ||
178 | pr_err("GVT Internal error for the guest\n"); | ||
168 | default: | 179 | default: |
169 | break; | 180 | break; |
170 | } | 181 | } |
@@ -1369,6 +1380,34 @@ static int mailbox_write(struct intel_vgpu *vgpu, unsigned int offset, | |||
1369 | return intel_vgpu_default_mmio_write(vgpu, offset, &value, bytes); | 1380 | return intel_vgpu_default_mmio_write(vgpu, offset, &value, bytes); |
1370 | } | 1381 | } |
1371 | 1382 | ||
1383 | static int hws_pga_write(struct intel_vgpu *vgpu, unsigned int offset, | ||
1384 | void *p_data, unsigned int bytes) | ||
1385 | { | ||
1386 | u32 value = *(u32 *)p_data; | ||
1387 | int ring_id = intel_gvt_render_mmio_to_ring_id(vgpu->gvt, offset); | ||
1388 | |||
1389 | if (!intel_gvt_ggtt_validate_range(vgpu, value, I915_GTT_PAGE_SIZE)) { | ||
1390 | gvt_vgpu_err("VM(%d) write invalid HWSP address, reg:0x%x, value:0x%x\n", | ||
1391 | vgpu->id, offset, value); | ||
1392 | return -EINVAL; | ||
1393 | } | ||
1394 | /* | ||
1395 | * Need to emulate all the HWSP register write to ensure host can | ||
1396 | * update the VM CSB status correctly. Here listed registers can | ||
1397 | * support BDW, SKL or other platforms with same HWSP registers. | ||
1398 | */ | ||
1399 | if (unlikely(ring_id < 0 || ring_id > I915_NUM_ENGINES)) { | ||
1400 | gvt_vgpu_err("VM(%d) access unknown hardware status page register:0x%x\n", | ||
1401 | vgpu->id, offset); | ||
1402 | return -EINVAL; | ||
1403 | } | ||
1404 | vgpu->hws_pga[ring_id] = value; | ||
1405 | gvt_dbg_mmio("VM(%d) write: 0x%x to HWSP: 0x%x\n", | ||
1406 | vgpu->id, value, offset); | ||
1407 | |||
1408 | return intel_vgpu_default_mmio_write(vgpu, offset, &value, bytes); | ||
1409 | } | ||
1410 | |||
1372 | static int skl_power_well_ctl_write(struct intel_vgpu *vgpu, | 1411 | static int skl_power_well_ctl_write(struct intel_vgpu *vgpu, |
1373 | unsigned int offset, void *p_data, unsigned int bytes) | 1412 | unsigned int offset, void *p_data, unsigned int bytes) |
1374 | { | 1413 | { |
@@ -1398,18 +1437,36 @@ static int skl_lcpll_write(struct intel_vgpu *vgpu, unsigned int offset, | |||
1398 | static int mmio_read_from_hw(struct intel_vgpu *vgpu, | 1437 | static int mmio_read_from_hw(struct intel_vgpu *vgpu, |
1399 | unsigned int offset, void *p_data, unsigned int bytes) | 1438 | unsigned int offset, void *p_data, unsigned int bytes) |
1400 | { | 1439 | { |
1401 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | 1440 | struct intel_gvt *gvt = vgpu->gvt; |
1441 | struct drm_i915_private *dev_priv = gvt->dev_priv; | ||
1442 | int ring_id; | ||
1443 | u32 ring_base; | ||
1444 | |||
1445 | ring_id = intel_gvt_render_mmio_to_ring_id(gvt, offset); | ||
1446 | /** | ||
1447 | * Read HW reg in following case | ||
1448 | * a. the offset isn't a ring mmio | ||
1449 | * b. the offset's ring is running on hw. | ||
1450 | * c. the offset is ring time stamp mmio | ||
1451 | */ | ||
1452 | if (ring_id >= 0) | ||
1453 | ring_base = dev_priv->engine[ring_id]->mmio_base; | ||
1454 | |||
1455 | if (ring_id < 0 || vgpu == gvt->scheduler.engine_owner[ring_id] || | ||
1456 | offset == i915_mmio_reg_offset(RING_TIMESTAMP(ring_base)) || | ||
1457 | offset == i915_mmio_reg_offset(RING_TIMESTAMP_UDW(ring_base))) { | ||
1458 | mmio_hw_access_pre(dev_priv); | ||
1459 | vgpu_vreg(vgpu, offset) = I915_READ(_MMIO(offset)); | ||
1460 | mmio_hw_access_post(dev_priv); | ||
1461 | } | ||
1402 | 1462 | ||
1403 | mmio_hw_access_pre(dev_priv); | ||
1404 | vgpu_vreg(vgpu, offset) = I915_READ(_MMIO(offset)); | ||
1405 | mmio_hw_access_post(dev_priv); | ||
1406 | return intel_vgpu_default_mmio_read(vgpu, offset, p_data, bytes); | 1463 | return intel_vgpu_default_mmio_read(vgpu, offset, p_data, bytes); |
1407 | } | 1464 | } |
1408 | 1465 | ||
1409 | static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, | 1466 | static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, |
1410 | void *p_data, unsigned int bytes) | 1467 | void *p_data, unsigned int bytes) |
1411 | { | 1468 | { |
1412 | int ring_id = render_mmio_to_ring_id(vgpu->gvt, offset); | 1469 | int ring_id = intel_gvt_render_mmio_to_ring_id(vgpu->gvt, offset); |
1413 | struct intel_vgpu_execlist *execlist; | 1470 | struct intel_vgpu_execlist *execlist; |
1414 | u32 data = *(u32 *)p_data; | 1471 | u32 data = *(u32 *)p_data; |
1415 | int ret = 0; | 1472 | int ret = 0; |
@@ -1417,9 +1474,9 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, | |||
1417 | if (WARN_ON(ring_id < 0 || ring_id > I915_NUM_ENGINES - 1)) | 1474 | if (WARN_ON(ring_id < 0 || ring_id > I915_NUM_ENGINES - 1)) |
1418 | return -EINVAL; | 1475 | return -EINVAL; |
1419 | 1476 | ||
1420 | execlist = &vgpu->execlist[ring_id]; | 1477 | execlist = &vgpu->submission.execlist[ring_id]; |
1421 | 1478 | ||
1422 | execlist->elsp_dwords.data[execlist->elsp_dwords.index] = data; | 1479 | execlist->elsp_dwords.data[3 - execlist->elsp_dwords.index] = data; |
1423 | if (execlist->elsp_dwords.index == 3) { | 1480 | if (execlist->elsp_dwords.index == 3) { |
1424 | ret = intel_vgpu_submit_execlist(vgpu, ring_id); | 1481 | ret = intel_vgpu_submit_execlist(vgpu, ring_id); |
1425 | if(ret) | 1482 | if(ret) |
@@ -1435,9 +1492,11 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, | |||
1435 | static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, | 1492 | static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, |
1436 | void *p_data, unsigned int bytes) | 1493 | void *p_data, unsigned int bytes) |
1437 | { | 1494 | { |
1495 | struct intel_vgpu_submission *s = &vgpu->submission; | ||
1438 | u32 data = *(u32 *)p_data; | 1496 | u32 data = *(u32 *)p_data; |
1439 | int ring_id = render_mmio_to_ring_id(vgpu->gvt, offset); | 1497 | int ring_id = intel_gvt_render_mmio_to_ring_id(vgpu->gvt, offset); |
1440 | bool enable_execlist; | 1498 | bool enable_execlist; |
1499 | int ret; | ||
1441 | 1500 | ||
1442 | write_vreg(vgpu, offset, p_data, bytes); | 1501 | write_vreg(vgpu, offset, p_data, bytes); |
1443 | 1502 | ||
@@ -1459,8 +1518,18 @@ static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, | |||
1459 | (enable_execlist ? "enabling" : "disabling"), | 1518 | (enable_execlist ? "enabling" : "disabling"), |
1460 | ring_id); | 1519 | ring_id); |
1461 | 1520 | ||
1462 | if (enable_execlist) | 1521 | if (!enable_execlist) |
1463 | intel_vgpu_start_schedule(vgpu); | 1522 | return 0; |
1523 | |||
1524 | if (s->active) | ||
1525 | return 0; | ||
1526 | |||
1527 | ret = intel_vgpu_select_submission_ops(vgpu, | ||
1528 | INTEL_VGPU_EXECLIST_SUBMISSION); | ||
1529 | if (ret) | ||
1530 | return ret; | ||
1531 | |||
1532 | intel_vgpu_start_schedule(vgpu); | ||
1464 | } | 1533 | } |
1465 | return 0; | 1534 | return 0; |
1466 | } | 1535 | } |
@@ -1492,7 +1561,7 @@ static int gvt_reg_tlb_control_handler(struct intel_vgpu *vgpu, | |||
1492 | default: | 1561 | default: |
1493 | return -EINVAL; | 1562 | return -EINVAL; |
1494 | } | 1563 | } |
1495 | set_bit(id, (void *)vgpu->tlb_handle_pending); | 1564 | set_bit(id, (void *)vgpu->submission.tlb_handle_pending); |
1496 | 1565 | ||
1497 | return 0; | 1566 | return 0; |
1498 | } | 1567 | } |
@@ -2478,7 +2547,7 @@ static int init_broadwell_mmio_info(struct intel_gvt *gvt) | |||
2478 | MMIO_RING_F(RING_REG, 32, 0, 0, 0, D_BDW_PLUS, NULL, NULL); | 2547 | MMIO_RING_F(RING_REG, 32, 0, 0, 0, D_BDW_PLUS, NULL, NULL); |
2479 | #undef RING_REG | 2548 | #undef RING_REG |
2480 | 2549 | ||
2481 | MMIO_RING_GM_RDR(RING_HWS_PGA, D_BDW_PLUS, NULL, NULL); | 2550 | MMIO_RING_GM_RDR(RING_HWS_PGA, D_BDW_PLUS, NULL, hws_pga_write); |
2482 | 2551 | ||
2483 | MMIO_DFH(HDC_CHICKEN0, D_BDW_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); | 2552 | MMIO_DFH(HDC_CHICKEN0, D_BDW_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); |
2484 | 2553 | ||
@@ -2879,14 +2948,46 @@ int intel_gvt_setup_mmio_info(struct intel_gvt *gvt) | |||
2879 | gvt->mmio.mmio_block = mmio_blocks; | 2948 | gvt->mmio.mmio_block = mmio_blocks; |
2880 | gvt->mmio.num_mmio_block = ARRAY_SIZE(mmio_blocks); | 2949 | gvt->mmio.num_mmio_block = ARRAY_SIZE(mmio_blocks); |
2881 | 2950 | ||
2882 | gvt_dbg_mmio("traced %u virtual mmio registers\n", | ||
2883 | gvt->mmio.num_tracked_mmio); | ||
2884 | return 0; | 2951 | return 0; |
2885 | err: | 2952 | err: |
2886 | intel_gvt_clean_mmio_info(gvt); | 2953 | intel_gvt_clean_mmio_info(gvt); |
2887 | return ret; | 2954 | return ret; |
2888 | } | 2955 | } |
2889 | 2956 | ||
2957 | /** | ||
2958 | * intel_gvt_for_each_tracked_mmio - iterate each tracked mmio | ||
2959 | * @gvt: a GVT device | ||
2960 | * @handler: the handler | ||
2961 | * @data: private data given to handler | ||
2962 | * | ||
2963 | * Returns: | ||
2964 | * Zero on success, negative error code if failed. | ||
2965 | */ | ||
2966 | int intel_gvt_for_each_tracked_mmio(struct intel_gvt *gvt, | ||
2967 | int (*handler)(struct intel_gvt *gvt, u32 offset, void *data), | ||
2968 | void *data) | ||
2969 | { | ||
2970 | struct gvt_mmio_block *block = gvt->mmio.mmio_block; | ||
2971 | struct intel_gvt_mmio_info *e; | ||
2972 | int i, j, ret; | ||
2973 | |||
2974 | hash_for_each(gvt->mmio.mmio_info_table, i, e, node) { | ||
2975 | ret = handler(gvt, e->offset, data); | ||
2976 | if (ret) | ||
2977 | return ret; | ||
2978 | } | ||
2979 | |||
2980 | for (i = 0; i < gvt->mmio.num_mmio_block; i++, block++) { | ||
2981 | for (j = 0; j < block->size; j += 4) { | ||
2982 | ret = handler(gvt, | ||
2983 | INTEL_GVT_MMIO_OFFSET(block->offset) + j, | ||
2984 | data); | ||
2985 | if (ret) | ||
2986 | return ret; | ||
2987 | } | ||
2988 | } | ||
2989 | return 0; | ||
2990 | } | ||
2890 | 2991 | ||
2891 | /** | 2992 | /** |
2892 | * intel_vgpu_default_mmio_read - default MMIO read handler | 2993 | * intel_vgpu_default_mmio_read - default MMIO read handler |
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 96060920a6fe..110f07e8bcfb 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c | |||
@@ -248,120 +248,6 @@ static void gvt_cache_destroy(struct intel_vgpu *vgpu) | |||
248 | } | 248 | } |
249 | } | 249 | } |
250 | 250 | ||
251 | static struct intel_vgpu_type *intel_gvt_find_vgpu_type(struct intel_gvt *gvt, | ||
252 | const char *name) | ||
253 | { | ||
254 | int i; | ||
255 | struct intel_vgpu_type *t; | ||
256 | const char *driver_name = dev_driver_string( | ||
257 | &gvt->dev_priv->drm.pdev->dev); | ||
258 | |||
259 | for (i = 0; i < gvt->num_types; i++) { | ||
260 | t = &gvt->types[i]; | ||
261 | if (!strncmp(t->name, name + strlen(driver_name) + 1, | ||
262 | sizeof(t->name))) | ||
263 | return t; | ||
264 | } | ||
265 | |||
266 | return NULL; | ||
267 | } | ||
268 | |||
269 | static ssize_t available_instances_show(struct kobject *kobj, | ||
270 | struct device *dev, char *buf) | ||
271 | { | ||
272 | struct intel_vgpu_type *type; | ||
273 | unsigned int num = 0; | ||
274 | void *gvt = kdev_to_i915(dev)->gvt; | ||
275 | |||
276 | type = intel_gvt_find_vgpu_type(gvt, kobject_name(kobj)); | ||
277 | if (!type) | ||
278 | num = 0; | ||
279 | else | ||
280 | num = type->avail_instance; | ||
281 | |||
282 | return sprintf(buf, "%u\n", num); | ||
283 | } | ||
284 | |||
285 | static ssize_t device_api_show(struct kobject *kobj, struct device *dev, | ||
286 | char *buf) | ||
287 | { | ||
288 | return sprintf(buf, "%s\n", VFIO_DEVICE_API_PCI_STRING); | ||
289 | } | ||
290 | |||
291 | static ssize_t description_show(struct kobject *kobj, struct device *dev, | ||
292 | char *buf) | ||
293 | { | ||
294 | struct intel_vgpu_type *type; | ||
295 | void *gvt = kdev_to_i915(dev)->gvt; | ||
296 | |||
297 | type = intel_gvt_find_vgpu_type(gvt, kobject_name(kobj)); | ||
298 | if (!type) | ||
299 | return 0; | ||
300 | |||
301 | return sprintf(buf, "low_gm_size: %dMB\nhigh_gm_size: %dMB\n" | ||
302 | "fence: %d\nresolution: %s\n" | ||
303 | "weight: %d\n", | ||
304 | BYTES_TO_MB(type->low_gm_size), | ||
305 | BYTES_TO_MB(type->high_gm_size), | ||
306 | type->fence, vgpu_edid_str(type->resolution), | ||
307 | type->weight); | ||
308 | } | ||
309 | |||
310 | static MDEV_TYPE_ATTR_RO(available_instances); | ||
311 | static MDEV_TYPE_ATTR_RO(device_api); | ||
312 | static MDEV_TYPE_ATTR_RO(description); | ||
313 | |||
314 | static struct attribute *type_attrs[] = { | ||
315 | &mdev_type_attr_available_instances.attr, | ||
316 | &mdev_type_attr_device_api.attr, | ||
317 | &mdev_type_attr_description.attr, | ||
318 | NULL, | ||
319 | }; | ||
320 | |||
321 | static struct attribute_group *intel_vgpu_type_groups[] = { | ||
322 | [0 ... NR_MAX_INTEL_VGPU_TYPES - 1] = NULL, | ||
323 | }; | ||
324 | |||
325 | static bool intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt) | ||
326 | { | ||
327 | int i, j; | ||
328 | struct intel_vgpu_type *type; | ||
329 | struct attribute_group *group; | ||
330 | |||
331 | for (i = 0; i < gvt->num_types; i++) { | ||
332 | type = &gvt->types[i]; | ||
333 | |||
334 | group = kzalloc(sizeof(struct attribute_group), GFP_KERNEL); | ||
335 | if (WARN_ON(!group)) | ||
336 | goto unwind; | ||
337 | |||
338 | group->name = type->name; | ||
339 | group->attrs = type_attrs; | ||
340 | intel_vgpu_type_groups[i] = group; | ||
341 | } | ||
342 | |||
343 | return true; | ||
344 | |||
345 | unwind: | ||
346 | for (j = 0; j < i; j++) { | ||
347 | group = intel_vgpu_type_groups[j]; | ||
348 | kfree(group); | ||
349 | } | ||
350 | |||
351 | return false; | ||
352 | } | ||
353 | |||
354 | static void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt) | ||
355 | { | ||
356 | int i; | ||
357 | struct attribute_group *group; | ||
358 | |||
359 | for (i = 0; i < gvt->num_types; i++) { | ||
360 | group = intel_vgpu_type_groups[i]; | ||
361 | kfree(group); | ||
362 | } | ||
363 | } | ||
364 | |||
365 | static void kvmgt_protect_table_init(struct kvmgt_guest_info *info) | 251 | static void kvmgt_protect_table_init(struct kvmgt_guest_info *info) |
366 | { | 252 | { |
367 | hash_init(info->ptable); | 253 | hash_init(info->ptable); |
@@ -441,7 +327,7 @@ static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev) | |||
441 | pdev = mdev_parent_dev(mdev); | 327 | pdev = mdev_parent_dev(mdev); |
442 | gvt = kdev_to_i915(pdev)->gvt; | 328 | gvt = kdev_to_i915(pdev)->gvt; |
443 | 329 | ||
444 | type = intel_gvt_find_vgpu_type(gvt, kobject_name(kobj)); | 330 | type = intel_gvt_ops->gvt_find_vgpu_type(gvt, kobject_name(kobj)); |
445 | if (!type) { | 331 | if (!type) { |
446 | gvt_vgpu_err("failed to find type %s to create\n", | 332 | gvt_vgpu_err("failed to find type %s to create\n", |
447 | kobject_name(kobj)); | 333 | kobject_name(kobj)); |
@@ -1188,7 +1074,7 @@ hw_id_show(struct device *dev, struct device_attribute *attr, | |||
1188 | struct intel_vgpu *vgpu = (struct intel_vgpu *) | 1074 | struct intel_vgpu *vgpu = (struct intel_vgpu *) |
1189 | mdev_get_drvdata(mdev); | 1075 | mdev_get_drvdata(mdev); |
1190 | return sprintf(buf, "%u\n", | 1076 | return sprintf(buf, "%u\n", |
1191 | vgpu->shadow_ctx->hw_id); | 1077 | vgpu->submission.shadow_ctx->hw_id); |
1192 | } | 1078 | } |
1193 | return sprintf(buf, "\n"); | 1079 | return sprintf(buf, "\n"); |
1194 | } | 1080 | } |
@@ -1212,8 +1098,7 @@ static const struct attribute_group *intel_vgpu_groups[] = { | |||
1212 | NULL, | 1098 | NULL, |
1213 | }; | 1099 | }; |
1214 | 1100 | ||
1215 | static const struct mdev_parent_ops intel_vgpu_ops = { | 1101 | static struct mdev_parent_ops intel_vgpu_ops = { |
1216 | .supported_type_groups = intel_vgpu_type_groups, | ||
1217 | .mdev_attr_groups = intel_vgpu_groups, | 1102 | .mdev_attr_groups = intel_vgpu_groups, |
1218 | .create = intel_vgpu_create, | 1103 | .create = intel_vgpu_create, |
1219 | .remove = intel_vgpu_remove, | 1104 | .remove = intel_vgpu_remove, |
@@ -1229,17 +1114,20 @@ static const struct mdev_parent_ops intel_vgpu_ops = { | |||
1229 | 1114 | ||
1230 | static int kvmgt_host_init(struct device *dev, void *gvt, const void *ops) | 1115 | static int kvmgt_host_init(struct device *dev, void *gvt, const void *ops) |
1231 | { | 1116 | { |
1232 | if (!intel_gvt_init_vgpu_type_groups(gvt)) | 1117 | struct attribute **kvm_type_attrs; |
1233 | return -EFAULT; | 1118 | struct attribute_group **kvm_vgpu_type_groups; |
1234 | 1119 | ||
1235 | intel_gvt_ops = ops; | 1120 | intel_gvt_ops = ops; |
1121 | if (!intel_gvt_ops->get_gvt_attrs(&kvm_type_attrs, | ||
1122 | &kvm_vgpu_type_groups)) | ||
1123 | return -EFAULT; | ||
1124 | intel_vgpu_ops.supported_type_groups = kvm_vgpu_type_groups; | ||
1236 | 1125 | ||
1237 | return mdev_register_device(dev, &intel_vgpu_ops); | 1126 | return mdev_register_device(dev, &intel_vgpu_ops); |
1238 | } | 1127 | } |
1239 | 1128 | ||
1240 | static void kvmgt_host_exit(struct device *dev, void *gvt) | 1129 | static void kvmgt_host_exit(struct device *dev, void *gvt) |
1241 | { | 1130 | { |
1242 | intel_gvt_cleanup_vgpu_type_groups(gvt); | ||
1243 | mdev_unregister_device(dev); | 1131 | mdev_unregister_device(dev); |
1244 | } | 1132 | } |
1245 | 1133 | ||
diff --git a/drivers/gpu/drm/i915/gvt/mmio.c b/drivers/gpu/drm/i915/gvt/mmio.c index 1e1310f50289..4ea0feb5f04d 100644 --- a/drivers/gpu/drm/i915/gvt/mmio.c +++ b/drivers/gpu/drm/i915/gvt/mmio.c | |||
@@ -117,18 +117,18 @@ static void failsafe_emulate_mmio_rw(struct intel_vgpu *vgpu, uint64_t pa, | |||
117 | else | 117 | else |
118 | memcpy(pt, p_data, bytes); | 118 | memcpy(pt, p_data, bytes); |
119 | 119 | ||
120 | } else if (atomic_read(&vgpu->gtt.n_write_protected_guest_page)) { | 120 | } else if (atomic_read(&vgpu->gtt.n_tracked_guest_page)) { |
121 | struct intel_vgpu_guest_page *gp; | 121 | struct intel_vgpu_page_track *t; |
122 | 122 | ||
123 | /* Since we enter the failsafe mode early during guest boot, | 123 | /* Since we enter the failsafe mode early during guest boot, |
124 | * guest may not have chance to set up its ppgtt table, so | 124 | * guest may not have chance to set up its ppgtt table, so |
125 | * there should not be any wp pages for guest. Keep the wp | 125 | * there should not be any wp pages for guest. Keep the wp |
126 | * related code here in case we need to handle it in furture. | 126 | * related code here in case we need to handle it in furture. |
127 | */ | 127 | */ |
128 | gp = intel_vgpu_find_guest_page(vgpu, pa >> PAGE_SHIFT); | 128 | t = intel_vgpu_find_tracked_page(vgpu, pa >> PAGE_SHIFT); |
129 | if (gp) { | 129 | if (t) { |
130 | /* remove write protection to prevent furture traps */ | 130 | /* remove write protection to prevent furture traps */ |
131 | intel_vgpu_clean_guest_page(vgpu, gp); | 131 | intel_vgpu_clean_page_track(vgpu, t); |
132 | if (read) | 132 | if (read) |
133 | intel_gvt_hypervisor_read_gpa(vgpu, pa, | 133 | intel_gvt_hypervisor_read_gpa(vgpu, pa, |
134 | p_data, bytes); | 134 | p_data, bytes); |
@@ -170,17 +170,17 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa, | |||
170 | return ret; | 170 | return ret; |
171 | } | 171 | } |
172 | 172 | ||
173 | if (atomic_read(&vgpu->gtt.n_write_protected_guest_page)) { | 173 | if (atomic_read(&vgpu->gtt.n_tracked_guest_page)) { |
174 | struct intel_vgpu_guest_page *gp; | 174 | struct intel_vgpu_page_track *t; |
175 | 175 | ||
176 | gp = intel_vgpu_find_guest_page(vgpu, pa >> PAGE_SHIFT); | 176 | t = intel_vgpu_find_tracked_page(vgpu, pa >> PAGE_SHIFT); |
177 | if (gp) { | 177 | if (t) { |
178 | ret = intel_gvt_hypervisor_read_gpa(vgpu, pa, | 178 | ret = intel_gvt_hypervisor_read_gpa(vgpu, pa, |
179 | p_data, bytes); | 179 | p_data, bytes); |
180 | if (ret) { | 180 | if (ret) { |
181 | gvt_vgpu_err("guest page read error %d, " | 181 | gvt_vgpu_err("guest page read error %d, " |
182 | "gfn 0x%lx, pa 0x%llx, var 0x%x, len %d\n", | 182 | "gfn 0x%lx, pa 0x%llx, var 0x%x, len %d\n", |
183 | ret, gp->gfn, pa, *(u32 *)p_data, | 183 | ret, t->gfn, pa, *(u32 *)p_data, |
184 | bytes); | 184 | bytes); |
185 | } | 185 | } |
186 | mutex_unlock(&gvt->lock); | 186 | mutex_unlock(&gvt->lock); |
@@ -267,17 +267,17 @@ int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, uint64_t pa, | |||
267 | return ret; | 267 | return ret; |
268 | } | 268 | } |
269 | 269 | ||
270 | if (atomic_read(&vgpu->gtt.n_write_protected_guest_page)) { | 270 | if (atomic_read(&vgpu->gtt.n_tracked_guest_page)) { |
271 | struct intel_vgpu_guest_page *gp; | 271 | struct intel_vgpu_page_track *t; |
272 | 272 | ||
273 | gp = intel_vgpu_find_guest_page(vgpu, pa >> PAGE_SHIFT); | 273 | t = intel_vgpu_find_tracked_page(vgpu, pa >> PAGE_SHIFT); |
274 | if (gp) { | 274 | if (t) { |
275 | ret = gp->handler(gp, pa, p_data, bytes); | 275 | ret = t->handler(t, pa, p_data, bytes); |
276 | if (ret) { | 276 | if (ret) { |
277 | gvt_err("guest page write error %d, " | 277 | gvt_err("guest page write error %d, " |
278 | "gfn 0x%lx, pa 0x%llx, " | 278 | "gfn 0x%lx, pa 0x%llx, " |
279 | "var 0x%x, len %d\n", | 279 | "var 0x%x, len %d\n", |
280 | ret, gp->gfn, pa, | 280 | ret, t->gfn, pa, |
281 | *(u32 *)p_data, bytes); | 281 | *(u32 *)p_data, bytes); |
282 | } | 282 | } |
283 | mutex_unlock(&gvt->lock); | 283 | mutex_unlock(&gvt->lock); |
diff --git a/drivers/gpu/drm/i915/gvt/mmio.h b/drivers/gpu/drm/i915/gvt/mmio.h index 32cd64ddad26..62709ac351cd 100644 --- a/drivers/gpu/drm/i915/gvt/mmio.h +++ b/drivers/gpu/drm/i915/gvt/mmio.h | |||
@@ -65,11 +65,17 @@ struct intel_gvt_mmio_info { | |||
65 | struct hlist_node node; | 65 | struct hlist_node node; |
66 | }; | 66 | }; |
67 | 67 | ||
68 | int intel_gvt_render_mmio_to_ring_id(struct intel_gvt *gvt, | ||
69 | unsigned int reg); | ||
68 | unsigned long intel_gvt_get_device_type(struct intel_gvt *gvt); | 70 | unsigned long intel_gvt_get_device_type(struct intel_gvt *gvt); |
69 | bool intel_gvt_match_device(struct intel_gvt *gvt, unsigned long device); | 71 | bool intel_gvt_match_device(struct intel_gvt *gvt, unsigned long device); |
70 | 72 | ||
71 | int intel_gvt_setup_mmio_info(struct intel_gvt *gvt); | 73 | int intel_gvt_setup_mmio_info(struct intel_gvt *gvt); |
72 | void intel_gvt_clean_mmio_info(struct intel_gvt *gvt); | 74 | void intel_gvt_clean_mmio_info(struct intel_gvt *gvt); |
75 | int intel_gvt_for_each_tracked_mmio(struct intel_gvt *gvt, | ||
76 | int (*handler)(struct intel_gvt *gvt, u32 offset, void *data), | ||
77 | void *data); | ||
78 | |||
73 | 79 | ||
74 | #define INTEL_GVT_MMIO_OFFSET(reg) ({ \ | 80 | #define INTEL_GVT_MMIO_OFFSET(reg) ({ \ |
75 | typeof(reg) __reg = reg; \ | 81 | typeof(reg) __reg = reg; \ |
diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h index f0e5487e6688..c436e20ea59e 100644 --- a/drivers/gpu/drm/i915/gvt/mpt.h +++ b/drivers/gpu/drm/i915/gvt/mpt.h | |||
@@ -154,51 +154,53 @@ static inline unsigned long intel_gvt_hypervisor_virt_to_mfn(void *p) | |||
154 | } | 154 | } |
155 | 155 | ||
156 | /** | 156 | /** |
157 | * intel_gvt_hypervisor_set_wp_page - set a guest page to write-protected | 157 | * intel_gvt_hypervisor_enable - set a guest page to write-protected |
158 | * @vgpu: a vGPU | 158 | * @vgpu: a vGPU |
159 | * @p: intel_vgpu_guest_page | 159 | * @t: page track data structure |
160 | * | 160 | * |
161 | * Returns: | 161 | * Returns: |
162 | * Zero on success, negative error code if failed. | 162 | * Zero on success, negative error code if failed. |
163 | */ | 163 | */ |
164 | static inline int intel_gvt_hypervisor_set_wp_page(struct intel_vgpu *vgpu, | 164 | static inline int intel_gvt_hypervisor_enable_page_track( |
165 | struct intel_vgpu_guest_page *p) | 165 | struct intel_vgpu *vgpu, |
166 | struct intel_vgpu_page_track *t) | ||
166 | { | 167 | { |
167 | int ret; | 168 | int ret; |
168 | 169 | ||
169 | if (p->writeprotection) | 170 | if (t->tracked) |
170 | return 0; | 171 | return 0; |
171 | 172 | ||
172 | ret = intel_gvt_host.mpt->set_wp_page(vgpu->handle, p->gfn); | 173 | ret = intel_gvt_host.mpt->set_wp_page(vgpu->handle, t->gfn); |
173 | if (ret) | 174 | if (ret) |
174 | return ret; | 175 | return ret; |
175 | p->writeprotection = true; | 176 | t->tracked = true; |
176 | atomic_inc(&vgpu->gtt.n_write_protected_guest_page); | 177 | atomic_inc(&vgpu->gtt.n_tracked_guest_page); |
177 | return 0; | 178 | return 0; |
178 | } | 179 | } |
179 | 180 | ||
180 | /** | 181 | /** |
181 | * intel_gvt_hypervisor_unset_wp_page - remove the write-protection of a | 182 | * intel_gvt_hypervisor_disable_page_track - remove the write-protection of a |
182 | * guest page | 183 | * guest page |
183 | * @vgpu: a vGPU | 184 | * @vgpu: a vGPU |
184 | * @p: intel_vgpu_guest_page | 185 | * @t: page track data structure |
185 | * | 186 | * |
186 | * Returns: | 187 | * Returns: |
187 | * Zero on success, negative error code if failed. | 188 | * Zero on success, negative error code if failed. |
188 | */ | 189 | */ |
189 | static inline int intel_gvt_hypervisor_unset_wp_page(struct intel_vgpu *vgpu, | 190 | static inline int intel_gvt_hypervisor_disable_page_track( |
190 | struct intel_vgpu_guest_page *p) | 191 | struct intel_vgpu *vgpu, |
192 | struct intel_vgpu_page_track *t) | ||
191 | { | 193 | { |
192 | int ret; | 194 | int ret; |
193 | 195 | ||
194 | if (!p->writeprotection) | 196 | if (!t->tracked) |
195 | return 0; | 197 | return 0; |
196 | 198 | ||
197 | ret = intel_gvt_host.mpt->unset_wp_page(vgpu->handle, p->gfn); | 199 | ret = intel_gvt_host.mpt->unset_wp_page(vgpu->handle, t->gfn); |
198 | if (ret) | 200 | if (ret) |
199 | return ret; | 201 | return ret; |
200 | p->writeprotection = false; | 202 | t->tracked = false; |
201 | atomic_dec(&vgpu->gtt.n_write_protected_guest_page); | 203 | atomic_dec(&vgpu->gtt.n_tracked_guest_page); |
202 | return 0; | 204 | return 0; |
203 | } | 205 | } |
204 | 206 | ||
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c b/drivers/gpu/drm/i915/gvt/opregion.c index 311799136d7f..80720e59723a 100644 --- a/drivers/gpu/drm/i915/gvt/opregion.c +++ b/drivers/gpu/drm/i915/gvt/opregion.c | |||
@@ -25,36 +25,247 @@ | |||
25 | #include "i915_drv.h" | 25 | #include "i915_drv.h" |
26 | #include "gvt.h" | 26 | #include "gvt.h" |
27 | 27 | ||
28 | static int init_vgpu_opregion(struct intel_vgpu *vgpu, u32 gpa) | 28 | /* |
29 | * Note: Only for GVT-g virtual VBT generation, other usage must | ||
30 | * not do like this. | ||
31 | */ | ||
32 | #define _INTEL_BIOS_PRIVATE | ||
33 | #include "intel_vbt_defs.h" | ||
34 | |||
35 | #define OPREGION_SIGNATURE "IntelGraphicsMem" | ||
36 | #define MBOX_VBT (1<<3) | ||
37 | |||
38 | /* device handle */ | ||
39 | #define DEVICE_TYPE_CRT 0x01 | ||
40 | #define DEVICE_TYPE_EFP1 0x04 | ||
41 | #define DEVICE_TYPE_EFP2 0x40 | ||
42 | #define DEVICE_TYPE_EFP3 0x20 | ||
43 | #define DEVICE_TYPE_EFP4 0x10 | ||
44 | |||
45 | #define DEV_SIZE 38 | ||
46 | |||
47 | struct opregion_header { | ||
48 | u8 signature[16]; | ||
49 | u32 size; | ||
50 | u32 opregion_ver; | ||
51 | u8 bios_ver[32]; | ||
52 | u8 vbios_ver[16]; | ||
53 | u8 driver_ver[16]; | ||
54 | u32 mboxes; | ||
55 | u32 driver_model; | ||
56 | u32 pcon; | ||
57 | u8 dver[32]; | ||
58 | u8 rsvd[124]; | ||
59 | } __packed; | ||
60 | |||
61 | struct bdb_data_header { | ||
62 | u8 id; | ||
63 | u16 size; /* data size */ | ||
64 | } __packed; | ||
65 | |||
66 | struct efp_child_device_config { | ||
67 | u16 handle; | ||
68 | u16 device_type; | ||
69 | u16 device_class; | ||
70 | u8 i2c_speed; | ||
71 | u8 dp_onboard_redriver; /* 158 */ | ||
72 | u8 dp_ondock_redriver; /* 158 */ | ||
73 | u8 hdmi_level_shifter_value:4; /* 169 */ | ||
74 | u8 hdmi_max_data_rate:4; /* 204 */ | ||
75 | u16 dtd_buf_ptr; /* 161 */ | ||
76 | u8 edidless_efp:1; /* 161 */ | ||
77 | u8 compression_enable:1; /* 198 */ | ||
78 | u8 compression_method:1; /* 198 */ | ||
79 | u8 ganged_edp:1; /* 202 */ | ||
80 | u8 skip0:4; | ||
81 | u8 compression_structure_index:4; /* 198 */ | ||
82 | u8 skip1:4; | ||
83 | u8 slave_port; /* 202 */ | ||
84 | u8 skip2; | ||
85 | u8 dvo_port; | ||
86 | u8 i2c_pin; /* for add-in card */ | ||
87 | u8 slave_addr; /* for add-in card */ | ||
88 | u8 ddc_pin; | ||
89 | u16 edid_ptr; | ||
90 | u8 dvo_config; | ||
91 | u8 efp_docked_port:1; /* 158 */ | ||
92 | u8 lane_reversal:1; /* 184 */ | ||
93 | u8 onboard_lspcon:1; /* 192 */ | ||
94 | u8 iboost_enable:1; /* 196 */ | ||
95 | u8 hpd_invert:1; /* BXT 196 */ | ||
96 | u8 slip3:3; | ||
97 | u8 hdmi_compat:1; | ||
98 | u8 dp_compat:1; | ||
99 | u8 tmds_compat:1; | ||
100 | u8 skip4:5; | ||
101 | u8 aux_channel; | ||
102 | u8 dongle_detect; | ||
103 | u8 pipe_cap:2; | ||
104 | u8 sdvo_stall:1; /* 158 */ | ||
105 | u8 hpd_status:2; | ||
106 | u8 integrated_encoder:1; | ||
107 | u8 skip5:2; | ||
108 | u8 dvo_wiring; | ||
109 | u8 mipi_bridge_type; /* 171 */ | ||
110 | u16 device_class_ext; | ||
111 | u8 dvo_function; | ||
112 | u8 dp_usb_type_c:1; /* 195 */ | ||
113 | u8 skip6:7; | ||
114 | u8 dp_usb_type_c_2x_gpio_index; /* 195 */ | ||
115 | u16 dp_usb_type_c_2x_gpio_pin; /* 195 */ | ||
116 | u8 iboost_dp:4; /* 196 */ | ||
117 | u8 iboost_hdmi:4; /* 196 */ | ||
118 | } __packed; | ||
119 | |||
120 | struct vbt { | ||
121 | /* header->bdb_offset point to bdb_header offset */ | ||
122 | struct vbt_header header; | ||
123 | struct bdb_header bdb_header; | ||
124 | |||
125 | struct bdb_data_header general_features_header; | ||
126 | struct bdb_general_features general_features; | ||
127 | |||
128 | struct bdb_data_header general_definitions_header; | ||
129 | struct bdb_general_definitions general_definitions; | ||
130 | |||
131 | struct efp_child_device_config child0; | ||
132 | struct efp_child_device_config child1; | ||
133 | struct efp_child_device_config child2; | ||
134 | struct efp_child_device_config child3; | ||
135 | |||
136 | struct bdb_data_header driver_features_header; | ||
137 | struct bdb_driver_features driver_features; | ||
138 | }; | ||
139 | |||
140 | static void virt_vbt_generation(struct vbt *v) | ||
29 | { | 141 | { |
30 | u8 *buf; | 142 | int num_child; |
31 | int i; | 143 | |
144 | memset(v, 0, sizeof(struct vbt)); | ||
145 | |||
146 | v->header.signature[0] = '$'; | ||
147 | v->header.signature[1] = 'V'; | ||
148 | v->header.signature[2] = 'B'; | ||
149 | v->header.signature[3] = 'T'; | ||
150 | |||
151 | /* there's features depending on version! */ | ||
152 | v->header.version = 155; | ||
153 | v->header.header_size = sizeof(v->header); | ||
154 | v->header.vbt_size = sizeof(struct vbt) - sizeof(v->header); | ||
155 | v->header.bdb_offset = offsetof(struct vbt, bdb_header); | ||
156 | |||
157 | strcpy(&v->bdb_header.signature[0], "BIOS_DATA_BLOCK"); | ||
158 | v->bdb_header.version = 186; /* child_dev_size = 38 */ | ||
159 | v->bdb_header.header_size = sizeof(v->bdb_header); | ||
160 | |||
161 | v->bdb_header.bdb_size = sizeof(struct vbt) - sizeof(struct vbt_header) | ||
162 | - sizeof(struct bdb_header); | ||
163 | |||
164 | /* general features */ | ||
165 | v->general_features_header.id = BDB_GENERAL_FEATURES; | ||
166 | v->general_features_header.size = sizeof(struct bdb_general_features); | ||
167 | v->general_features.int_crt_support = 0; | ||
168 | v->general_features.int_tv_support = 0; | ||
169 | |||
170 | /* child device */ | ||
171 | num_child = 4; /* each port has one child */ | ||
172 | v->general_definitions_header.id = BDB_GENERAL_DEFINITIONS; | ||
173 | /* size will include child devices */ | ||
174 | v->general_definitions_header.size = | ||
175 | sizeof(struct bdb_general_definitions) + num_child * DEV_SIZE; | ||
176 | v->general_definitions.child_dev_size = DEV_SIZE; | ||
177 | |||
178 | /* portA */ | ||
179 | v->child0.handle = DEVICE_TYPE_EFP1; | ||
180 | v->child0.device_type = DEVICE_TYPE_DP; | ||
181 | v->child0.dvo_port = DVO_PORT_DPA; | ||
182 | v->child0.aux_channel = DP_AUX_A; | ||
183 | v->child0.dp_compat = true; | ||
184 | v->child0.integrated_encoder = true; | ||
185 | |||
186 | /* portB */ | ||
187 | v->child1.handle = DEVICE_TYPE_EFP2; | ||
188 | v->child1.device_type = DEVICE_TYPE_DP; | ||
189 | v->child1.dvo_port = DVO_PORT_DPB; | ||
190 | v->child1.aux_channel = DP_AUX_B; | ||
191 | v->child1.dp_compat = true; | ||
192 | v->child1.integrated_encoder = true; | ||
193 | |||
194 | /* portC */ | ||
195 | v->child2.handle = DEVICE_TYPE_EFP3; | ||
196 | v->child2.device_type = DEVICE_TYPE_DP; | ||
197 | v->child2.dvo_port = DVO_PORT_DPC; | ||
198 | v->child2.aux_channel = DP_AUX_C; | ||
199 | v->child2.dp_compat = true; | ||
200 | v->child2.integrated_encoder = true; | ||
201 | |||
202 | /* portD */ | ||
203 | v->child3.handle = DEVICE_TYPE_EFP4; | ||
204 | v->child3.device_type = DEVICE_TYPE_DP; | ||
205 | v->child3.dvo_port = DVO_PORT_DPD; | ||
206 | v->child3.aux_channel = DP_AUX_D; | ||
207 | v->child3.dp_compat = true; | ||
208 | v->child3.integrated_encoder = true; | ||
209 | |||
210 | /* driver features */ | ||
211 | v->driver_features_header.id = BDB_DRIVER_FEATURES; | ||
212 | v->driver_features_header.size = sizeof(struct bdb_driver_features); | ||
213 | v->driver_features.lvds_config = BDB_DRIVER_FEATURE_NO_LVDS; | ||
214 | } | ||
32 | 215 | ||
33 | if (WARN((vgpu_opregion(vgpu)->va), | 216 | static int alloc_and_init_virt_opregion(struct intel_vgpu *vgpu) |
34 | "vgpu%d: opregion has been initialized already.\n", | 217 | { |
35 | vgpu->id)) | 218 | u8 *buf; |
36 | return -EINVAL; | 219 | struct opregion_header *header; |
220 | struct vbt v; | ||
37 | 221 | ||
222 | gvt_dbg_core("init vgpu%d opregion\n", vgpu->id); | ||
38 | vgpu_opregion(vgpu)->va = (void *)__get_free_pages(GFP_KERNEL | | 223 | vgpu_opregion(vgpu)->va = (void *)__get_free_pages(GFP_KERNEL | |
39 | __GFP_ZERO, | 224 | __GFP_ZERO, |
40 | get_order(INTEL_GVT_OPREGION_SIZE)); | 225 | get_order(INTEL_GVT_OPREGION_SIZE)); |
41 | 226 | if (!vgpu_opregion(vgpu)->va) { | |
42 | if (!vgpu_opregion(vgpu)->va) | 227 | gvt_err("fail to get memory for vgpu virt opregion\n"); |
43 | return -ENOMEM; | 228 | return -ENOMEM; |
229 | } | ||
44 | 230 | ||
45 | memcpy(vgpu_opregion(vgpu)->va, vgpu->gvt->opregion.opregion_va, | 231 | /* emulated opregion with VBT mailbox only */ |
46 | INTEL_GVT_OPREGION_SIZE); | 232 | buf = (u8 *)vgpu_opregion(vgpu)->va; |
47 | 233 | header = (struct opregion_header *)buf; | |
48 | for (i = 0; i < INTEL_GVT_OPREGION_PAGES; i++) | 234 | memcpy(header->signature, OPREGION_SIGNATURE, |
49 | vgpu_opregion(vgpu)->gfn[i] = (gpa >> PAGE_SHIFT) + i; | 235 | sizeof(OPREGION_SIGNATURE)); |
236 | header->size = 0x8; | ||
237 | header->opregion_ver = 0x02000000; | ||
238 | header->mboxes = MBOX_VBT; | ||
50 | 239 | ||
51 | /* for unknown reason, the value in LID field is incorrect | 240 | /* for unknown reason, the value in LID field is incorrect |
52 | * which block the windows guest, so workaround it by force | 241 | * which block the windows guest, so workaround it by force |
53 | * setting it to "OPEN" | 242 | * setting it to "OPEN" |
54 | */ | 243 | */ |
55 | buf = (u8 *)vgpu_opregion(vgpu)->va; | ||
56 | buf[INTEL_GVT_OPREGION_CLID] = 0x3; | 244 | buf[INTEL_GVT_OPREGION_CLID] = 0x3; |
57 | 245 | ||
246 | /* emulated vbt from virt vbt generation */ | ||
247 | virt_vbt_generation(&v); | ||
248 | memcpy(buf + INTEL_GVT_OPREGION_VBT_OFFSET, &v, sizeof(struct vbt)); | ||
249 | |||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | static int init_vgpu_opregion(struct intel_vgpu *vgpu, u32 gpa) | ||
254 | { | ||
255 | int i, ret; | ||
256 | |||
257 | if (WARN((vgpu_opregion(vgpu)->va), | ||
258 | "vgpu%d: opregion has been initialized already.\n", | ||
259 | vgpu->id)) | ||
260 | return -EINVAL; | ||
261 | |||
262 | ret = alloc_and_init_virt_opregion(vgpu); | ||
263 | if (ret < 0) | ||
264 | return ret; | ||
265 | |||
266 | for (i = 0; i < INTEL_GVT_OPREGION_PAGES; i++) | ||
267 | vgpu_opregion(vgpu)->gfn[i] = (gpa >> PAGE_SHIFT) + i; | ||
268 | |||
58 | return 0; | 269 | return 0; |
59 | } | 270 | } |
60 | 271 | ||
@@ -132,40 +343,6 @@ int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa) | |||
132 | return 0; | 343 | return 0; |
133 | } | 344 | } |
134 | 345 | ||
135 | /** | ||
136 | * intel_gvt_clean_opregion - clean host opergion related stuffs | ||
137 | * @gvt: a GVT device | ||
138 | * | ||
139 | */ | ||
140 | void intel_gvt_clean_opregion(struct intel_gvt *gvt) | ||
141 | { | ||
142 | memunmap(gvt->opregion.opregion_va); | ||
143 | gvt->opregion.opregion_va = NULL; | ||
144 | } | ||
145 | |||
146 | /** | ||
147 | * intel_gvt_init_opregion - initialize host opergion related stuffs | ||
148 | * @gvt: a GVT device | ||
149 | * | ||
150 | * Returns: | ||
151 | * Zero on success, negative error code if failed. | ||
152 | */ | ||
153 | int intel_gvt_init_opregion(struct intel_gvt *gvt) | ||
154 | { | ||
155 | gvt_dbg_core("init host opregion\n"); | ||
156 | |||
157 | pci_read_config_dword(gvt->dev_priv->drm.pdev, INTEL_GVT_PCI_OPREGION, | ||
158 | &gvt->opregion.opregion_pa); | ||
159 | |||
160 | gvt->opregion.opregion_va = memremap(gvt->opregion.opregion_pa, | ||
161 | INTEL_GVT_OPREGION_SIZE, MEMREMAP_WB); | ||
162 | if (!gvt->opregion.opregion_va) { | ||
163 | gvt_err("fail to map host opregion\n"); | ||
164 | return -EFAULT; | ||
165 | } | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | #define GVT_OPREGION_FUNC(scic) \ | 346 | #define GVT_OPREGION_FUNC(scic) \ |
170 | ({ \ | 347 | ({ \ |
171 | u32 __ret; \ | 348 | u32 __ret; \ |
diff --git a/drivers/gpu/drm/i915/gvt/reg.h b/drivers/gpu/drm/i915/gvt/reg.h index 7d01c77a0f7a..d4f7ce6dc1d7 100644 --- a/drivers/gpu/drm/i915/gvt/reg.h +++ b/drivers/gpu/drm/i915/gvt/reg.h | |||
@@ -51,6 +51,9 @@ | |||
51 | 51 | ||
52 | #define INTEL_GVT_OPREGION_PAGES 2 | 52 | #define INTEL_GVT_OPREGION_PAGES 2 |
53 | #define INTEL_GVT_OPREGION_SIZE (INTEL_GVT_OPREGION_PAGES * PAGE_SIZE) | 53 | #define INTEL_GVT_OPREGION_SIZE (INTEL_GVT_OPREGION_PAGES * PAGE_SIZE) |
54 | #define INTEL_GVT_OPREGION_VBT_OFFSET 0x400 | ||
55 | #define INTEL_GVT_OPREGION_VBT_SIZE \ | ||
56 | (INTEL_GVT_OPREGION_SIZE - INTEL_GVT_OPREGION_VBT_OFFSET) | ||
54 | 57 | ||
55 | #define VGT_SPRSTRIDE(pipe) _PIPE(pipe, _SPRA_STRIDE, _PLANE_STRIDE_2_B) | 58 | #define VGT_SPRSTRIDE(pipe) _PIPE(pipe, _SPRA_STRIDE, _PLANE_STRIDE_2_B) |
56 | 59 | ||
@@ -71,6 +74,7 @@ | |||
71 | #define RB_HEAD_OFF_MASK ((1U << 21) - (1U << 2)) | 74 | #define RB_HEAD_OFF_MASK ((1U << 21) - (1U << 2)) |
72 | #define RB_TAIL_OFF_MASK ((1U << 21) - (1U << 3)) | 75 | #define RB_TAIL_OFF_MASK ((1U << 21) - (1U << 3)) |
73 | #define RB_TAIL_SIZE_MASK ((1U << 21) - (1U << 12)) | 76 | #define RB_TAIL_SIZE_MASK ((1U << 21) - (1U << 12)) |
74 | #define _RING_CTL_BUF_SIZE(ctl) (((ctl) & RB_TAIL_SIZE_MASK) + GTT_PAGE_SIZE) | 77 | #define _RING_CTL_BUF_SIZE(ctl) (((ctl) & RB_TAIL_SIZE_MASK) + \ |
78 | I915_GTT_PAGE_SIZE) | ||
75 | 79 | ||
76 | #endif | 80 | #endif |
diff --git a/drivers/gpu/drm/i915/gvt/render.c b/drivers/gpu/drm/i915/gvt/render.c index 6d066cf35478..0672178548ef 100644 --- a/drivers/gpu/drm/i915/gvt/render.c +++ b/drivers/gpu/drm/i915/gvt/render.c | |||
@@ -147,6 +147,7 @@ static u32 gen9_render_mocs_L3[32]; | |||
147 | static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id) | 147 | static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id) |
148 | { | 148 | { |
149 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | 149 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; |
150 | struct intel_vgpu_submission *s = &vgpu->submission; | ||
150 | enum forcewake_domains fw; | 151 | enum forcewake_domains fw; |
151 | i915_reg_t reg; | 152 | i915_reg_t reg; |
152 | u32 regs[] = { | 153 | u32 regs[] = { |
@@ -160,7 +161,7 @@ static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id) | |||
160 | if (WARN_ON(ring_id >= ARRAY_SIZE(regs))) | 161 | if (WARN_ON(ring_id >= ARRAY_SIZE(regs))) |
161 | return; | 162 | return; |
162 | 163 | ||
163 | if (!test_and_clear_bit(ring_id, (void *)vgpu->tlb_handle_pending)) | 164 | if (!test_and_clear_bit(ring_id, (void *)s->tlb_handle_pending)) |
164 | return; | 165 | return; |
165 | 166 | ||
166 | reg = _MMIO(regs[ring_id]); | 167 | reg = _MMIO(regs[ring_id]); |
@@ -208,7 +209,7 @@ static void load_mocs(struct intel_vgpu *vgpu, int ring_id) | |||
208 | offset.reg = regs[ring_id]; | 209 | offset.reg = regs[ring_id]; |
209 | for (i = 0; i < 64; i++) { | 210 | for (i = 0; i < 64; i++) { |
210 | gen9_render_mocs[ring_id][i] = I915_READ_FW(offset); | 211 | gen9_render_mocs[ring_id][i] = I915_READ_FW(offset); |
211 | I915_WRITE(offset, vgpu_vreg(vgpu, offset)); | 212 | I915_WRITE_FW(offset, vgpu_vreg(vgpu, offset)); |
212 | offset.reg += 4; | 213 | offset.reg += 4; |
213 | } | 214 | } |
214 | 215 | ||
@@ -261,14 +262,15 @@ static void restore_mocs(struct intel_vgpu *vgpu, int ring_id) | |||
261 | static void switch_mmio_to_vgpu(struct intel_vgpu *vgpu, int ring_id) | 262 | static void switch_mmio_to_vgpu(struct intel_vgpu *vgpu, int ring_id) |
262 | { | 263 | { |
263 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | 264 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; |
264 | struct render_mmio *mmio; | 265 | struct intel_vgpu_submission *s = &vgpu->submission; |
265 | u32 v; | 266 | u32 *reg_state = s->shadow_ctx->engine[ring_id].lrc_reg_state; |
266 | int i, array_size; | ||
267 | u32 *reg_state = vgpu->shadow_ctx->engine[ring_id].lrc_reg_state; | ||
268 | u32 ctx_ctrl = reg_state[CTX_CONTEXT_CONTROL_VAL]; | 267 | u32 ctx_ctrl = reg_state[CTX_CONTEXT_CONTROL_VAL]; |
269 | u32 inhibit_mask = | 268 | u32 inhibit_mask = |
270 | _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT); | 269 | _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT); |
271 | i915_reg_t last_reg = _MMIO(0); | 270 | i915_reg_t last_reg = _MMIO(0); |
271 | struct render_mmio *mmio; | ||
272 | u32 v; | ||
273 | int i, array_size; | ||
272 | 274 | ||
273 | if (IS_SKYLAKE(vgpu->gvt->dev_priv) | 275 | if (IS_SKYLAKE(vgpu->gvt->dev_priv) |
274 | || IS_KABYLAKE(vgpu->gvt->dev_priv)) { | 276 | || IS_KABYLAKE(vgpu->gvt->dev_priv)) { |
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index 3ac1dc97a7a0..d6177a0baeec 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c | |||
@@ -57,7 +57,7 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload) | |||
57 | struct intel_vgpu *vgpu = workload->vgpu; | 57 | struct intel_vgpu *vgpu = workload->vgpu; |
58 | struct intel_gvt *gvt = vgpu->gvt; | 58 | struct intel_gvt *gvt = vgpu->gvt; |
59 | int ring_id = workload->ring_id; | 59 | int ring_id = workload->ring_id; |
60 | struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx; | 60 | struct i915_gem_context *shadow_ctx = vgpu->submission.shadow_ctx; |
61 | struct drm_i915_gem_object *ctx_obj = | 61 | struct drm_i915_gem_object *ctx_obj = |
62 | shadow_ctx->engine[ring_id].state->obj; | 62 | shadow_ctx->engine[ring_id].state->obj; |
63 | struct execlist_ring_context *shadow_ring_context; | 63 | struct execlist_ring_context *shadow_ring_context; |
@@ -81,16 +81,16 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload) | |||
81 | while (i < context_page_num) { | 81 | while (i < context_page_num) { |
82 | context_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, | 82 | context_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, |
83 | (u32)((workload->ctx_desc.lrca + i) << | 83 | (u32)((workload->ctx_desc.lrca + i) << |
84 | GTT_PAGE_SHIFT)); | 84 | I915_GTT_PAGE_SHIFT)); |
85 | if (context_gpa == INTEL_GVT_INVALID_ADDR) { | 85 | if (context_gpa == INTEL_GVT_INVALID_ADDR) { |
86 | gvt_vgpu_err("Invalid guest context descriptor\n"); | 86 | gvt_vgpu_err("Invalid guest context descriptor\n"); |
87 | return -EINVAL; | 87 | return -EFAULT; |
88 | } | 88 | } |
89 | 89 | ||
90 | page = i915_gem_object_get_page(ctx_obj, LRC_HEADER_PAGES + i); | 90 | page = i915_gem_object_get_page(ctx_obj, LRC_HEADER_PAGES + i); |
91 | dst = kmap(page); | 91 | dst = kmap(page); |
92 | intel_gvt_hypervisor_read_gpa(vgpu, context_gpa, dst, | 92 | intel_gvt_hypervisor_read_gpa(vgpu, context_gpa, dst, |
93 | GTT_PAGE_SIZE); | 93 | I915_GTT_PAGE_SIZE); |
94 | kunmap(page); | 94 | kunmap(page); |
95 | i++; | 95 | i++; |
96 | } | 96 | } |
@@ -120,7 +120,7 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload) | |||
120 | sizeof(*shadow_ring_context), | 120 | sizeof(*shadow_ring_context), |
121 | (void *)shadow_ring_context + | 121 | (void *)shadow_ring_context + |
122 | sizeof(*shadow_ring_context), | 122 | sizeof(*shadow_ring_context), |
123 | GTT_PAGE_SIZE - sizeof(*shadow_ring_context)); | 123 | I915_GTT_PAGE_SIZE - sizeof(*shadow_ring_context)); |
124 | 124 | ||
125 | kunmap(page); | 125 | kunmap(page); |
126 | return 0; | 126 | return 0; |
@@ -131,6 +131,20 @@ static inline bool is_gvt_request(struct drm_i915_gem_request *req) | |||
131 | return i915_gem_context_force_single_submission(req->ctx); | 131 | return i915_gem_context_force_single_submission(req->ctx); |
132 | } | 132 | } |
133 | 133 | ||
134 | static void save_ring_hw_state(struct intel_vgpu *vgpu, int ring_id) | ||
135 | { | ||
136 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | ||
137 | u32 ring_base = dev_priv->engine[ring_id]->mmio_base; | ||
138 | i915_reg_t reg; | ||
139 | |||
140 | reg = RING_INSTDONE(ring_base); | ||
141 | vgpu_vreg(vgpu, i915_mmio_reg_offset(reg)) = I915_READ_FW(reg); | ||
142 | reg = RING_ACTHD(ring_base); | ||
143 | vgpu_vreg(vgpu, i915_mmio_reg_offset(reg)) = I915_READ_FW(reg); | ||
144 | reg = RING_ACTHD_UDW(ring_base); | ||
145 | vgpu_vreg(vgpu, i915_mmio_reg_offset(reg)) = I915_READ_FW(reg); | ||
146 | } | ||
147 | |||
134 | static int shadow_context_status_change(struct notifier_block *nb, | 148 | static int shadow_context_status_change(struct notifier_block *nb, |
135 | unsigned long action, void *data) | 149 | unsigned long action, void *data) |
136 | { | 150 | { |
@@ -176,6 +190,7 @@ static int shadow_context_status_change(struct notifier_block *nb, | |||
176 | break; | 190 | break; |
177 | case INTEL_CONTEXT_SCHEDULE_OUT: | 191 | case INTEL_CONTEXT_SCHEDULE_OUT: |
178 | case INTEL_CONTEXT_SCHEDULE_PREEMPTED: | 192 | case INTEL_CONTEXT_SCHEDULE_PREEMPTED: |
193 | save_ring_hw_state(workload->vgpu, ring_id); | ||
179 | atomic_set(&workload->shadow_ctx_active, 0); | 194 | atomic_set(&workload->shadow_ctx_active, 0); |
180 | break; | 195 | break; |
181 | default: | 196 | default: |
@@ -250,11 +265,12 @@ void release_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx) | |||
250 | */ | 265 | */ |
251 | int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload) | 266 | int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload) |
252 | { | 267 | { |
268 | struct intel_vgpu *vgpu = workload->vgpu; | ||
269 | struct intel_vgpu_submission *s = &vgpu->submission; | ||
270 | struct i915_gem_context *shadow_ctx = s->shadow_ctx; | ||
271 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | ||
253 | int ring_id = workload->ring_id; | 272 | int ring_id = workload->ring_id; |
254 | struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx; | ||
255 | struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv; | ||
256 | struct intel_engine_cs *engine = dev_priv->engine[ring_id]; | 273 | struct intel_engine_cs *engine = dev_priv->engine[ring_id]; |
257 | struct intel_vgpu *vgpu = workload->vgpu; | ||
258 | struct intel_ring *ring; | 274 | struct intel_ring *ring; |
259 | int ret; | 275 | int ret; |
260 | 276 | ||
@@ -267,7 +283,7 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload) | |||
267 | shadow_ctx->desc_template |= workload->ctx_desc.addressing_mode << | 283 | shadow_ctx->desc_template |= workload->ctx_desc.addressing_mode << |
268 | GEN8_CTX_ADDRESSING_MODE_SHIFT; | 284 | GEN8_CTX_ADDRESSING_MODE_SHIFT; |
269 | 285 | ||
270 | if (!test_and_set_bit(ring_id, vgpu->shadow_ctx_desc_updated)) | 286 | if (!test_and_set_bit(ring_id, s->shadow_ctx_desc_updated)) |
271 | shadow_context_descriptor_update(shadow_ctx, | 287 | shadow_context_descriptor_update(shadow_ctx, |
272 | dev_priv->engine[ring_id]); | 288 | dev_priv->engine[ring_id]); |
273 | 289 | ||
@@ -310,14 +326,15 @@ err_scan: | |||
310 | return ret; | 326 | return ret; |
311 | } | 327 | } |
312 | 328 | ||
313 | int intel_gvt_generate_request(struct intel_vgpu_workload *workload) | 329 | static int intel_gvt_generate_request(struct intel_vgpu_workload *workload) |
314 | { | 330 | { |
315 | int ring_id = workload->ring_id; | 331 | int ring_id = workload->ring_id; |
316 | struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv; | 332 | struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv; |
317 | struct intel_engine_cs *engine = dev_priv->engine[ring_id]; | 333 | struct intel_engine_cs *engine = dev_priv->engine[ring_id]; |
318 | struct drm_i915_gem_request *rq; | 334 | struct drm_i915_gem_request *rq; |
319 | struct intel_vgpu *vgpu = workload->vgpu; | 335 | struct intel_vgpu *vgpu = workload->vgpu; |
320 | struct i915_gem_context *shadow_ctx = vgpu->shadow_ctx; | 336 | struct intel_vgpu_submission *s = &vgpu->submission; |
337 | struct i915_gem_context *shadow_ctx = s->shadow_ctx; | ||
321 | int ret; | 338 | int ret; |
322 | 339 | ||
323 | rq = i915_gem_request_alloc(dev_priv->engine[ring_id], shadow_ctx); | 340 | rq = i915_gem_request_alloc(dev_priv->engine[ring_id], shadow_ctx); |
@@ -341,11 +358,203 @@ err_unpin: | |||
341 | return ret; | 358 | return ret; |
342 | } | 359 | } |
343 | 360 | ||
361 | static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload); | ||
362 | |||
363 | static int prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload) | ||
364 | { | ||
365 | struct intel_gvt *gvt = workload->vgpu->gvt; | ||
366 | const int gmadr_bytes = gvt->device_info.gmadr_bytes_in_cmd; | ||
367 | struct intel_vgpu_shadow_bb *bb; | ||
368 | int ret; | ||
369 | |||
370 | list_for_each_entry(bb, &workload->shadow_bb, list) { | ||
371 | bb->vma = i915_gem_object_ggtt_pin(bb->obj, NULL, 0, 0, 0); | ||
372 | if (IS_ERR(bb->vma)) { | ||
373 | ret = PTR_ERR(bb->vma); | ||
374 | goto err; | ||
375 | } | ||
376 | |||
377 | /* relocate shadow batch buffer */ | ||
378 | bb->bb_start_cmd_va[1] = i915_ggtt_offset(bb->vma); | ||
379 | if (gmadr_bytes == 8) | ||
380 | bb->bb_start_cmd_va[2] = 0; | ||
381 | |||
382 | /* No one is going to touch shadow bb from now on. */ | ||
383 | if (bb->clflush & CLFLUSH_AFTER) { | ||
384 | drm_clflush_virt_range(bb->va, bb->obj->base.size); | ||
385 | bb->clflush &= ~CLFLUSH_AFTER; | ||
386 | } | ||
387 | |||
388 | ret = i915_gem_object_set_to_gtt_domain(bb->obj, false); | ||
389 | if (ret) | ||
390 | goto err; | ||
391 | |||
392 | i915_gem_obj_finish_shmem_access(bb->obj); | ||
393 | bb->accessing = false; | ||
394 | |||
395 | i915_vma_move_to_active(bb->vma, workload->req, 0); | ||
396 | } | ||
397 | return 0; | ||
398 | err: | ||
399 | release_shadow_batch_buffer(workload); | ||
400 | return ret; | ||
401 | } | ||
402 | |||
403 | static int update_wa_ctx_2_shadow_ctx(struct intel_shadow_wa_ctx *wa_ctx) | ||
404 | { | ||
405 | struct intel_vgpu_workload *workload = container_of(wa_ctx, | ||
406 | struct intel_vgpu_workload, | ||
407 | wa_ctx); | ||
408 | int ring_id = workload->ring_id; | ||
409 | struct intel_vgpu_submission *s = &workload->vgpu->submission; | ||
410 | struct i915_gem_context *shadow_ctx = s->shadow_ctx; | ||
411 | struct drm_i915_gem_object *ctx_obj = | ||
412 | shadow_ctx->engine[ring_id].state->obj; | ||
413 | struct execlist_ring_context *shadow_ring_context; | ||
414 | struct page *page; | ||
415 | |||
416 | page = i915_gem_object_get_page(ctx_obj, LRC_STATE_PN); | ||
417 | shadow_ring_context = kmap_atomic(page); | ||
418 | |||
419 | shadow_ring_context->bb_per_ctx_ptr.val = | ||
420 | (shadow_ring_context->bb_per_ctx_ptr.val & | ||
421 | (~PER_CTX_ADDR_MASK)) | wa_ctx->per_ctx.shadow_gma; | ||
422 | shadow_ring_context->rcs_indirect_ctx.val = | ||
423 | (shadow_ring_context->rcs_indirect_ctx.val & | ||
424 | (~INDIRECT_CTX_ADDR_MASK)) | wa_ctx->indirect_ctx.shadow_gma; | ||
425 | |||
426 | kunmap_atomic(shadow_ring_context); | ||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | static int prepare_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx) | ||
431 | { | ||
432 | struct i915_vma *vma; | ||
433 | unsigned char *per_ctx_va = | ||
434 | (unsigned char *)wa_ctx->indirect_ctx.shadow_va + | ||
435 | wa_ctx->indirect_ctx.size; | ||
436 | |||
437 | if (wa_ctx->indirect_ctx.size == 0) | ||
438 | return 0; | ||
439 | |||
440 | vma = i915_gem_object_ggtt_pin(wa_ctx->indirect_ctx.obj, NULL, | ||
441 | 0, CACHELINE_BYTES, 0); | ||
442 | if (IS_ERR(vma)) | ||
443 | return PTR_ERR(vma); | ||
444 | |||
445 | /* FIXME: we are not tracking our pinned VMA leaving it | ||
446 | * up to the core to fix up the stray pin_count upon | ||
447 | * free. | ||
448 | */ | ||
449 | |||
450 | wa_ctx->indirect_ctx.shadow_gma = i915_ggtt_offset(vma); | ||
451 | |||
452 | wa_ctx->per_ctx.shadow_gma = *((unsigned int *)per_ctx_va + 1); | ||
453 | memset(per_ctx_va, 0, CACHELINE_BYTES); | ||
454 | |||
455 | update_wa_ctx_2_shadow_ctx(wa_ctx); | ||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload) | ||
460 | { | ||
461 | struct intel_vgpu *vgpu = workload->vgpu; | ||
462 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | ||
463 | struct intel_vgpu_shadow_bb *bb, *pos; | ||
464 | |||
465 | if (list_empty(&workload->shadow_bb)) | ||
466 | return; | ||
467 | |||
468 | bb = list_first_entry(&workload->shadow_bb, | ||
469 | struct intel_vgpu_shadow_bb, list); | ||
470 | |||
471 | mutex_lock(&dev_priv->drm.struct_mutex); | ||
472 | |||
473 | list_for_each_entry_safe(bb, pos, &workload->shadow_bb, list) { | ||
474 | if (bb->obj) { | ||
475 | if (bb->accessing) | ||
476 | i915_gem_obj_finish_shmem_access(bb->obj); | ||
477 | |||
478 | if (bb->va && !IS_ERR(bb->va)) | ||
479 | i915_gem_object_unpin_map(bb->obj); | ||
480 | |||
481 | if (bb->vma && !IS_ERR(bb->vma)) { | ||
482 | i915_vma_unpin(bb->vma); | ||
483 | i915_vma_close(bb->vma); | ||
484 | } | ||
485 | __i915_gem_object_release_unless_active(bb->obj); | ||
486 | } | ||
487 | list_del(&bb->list); | ||
488 | kfree(bb); | ||
489 | } | ||
490 | |||
491 | mutex_unlock(&dev_priv->drm.struct_mutex); | ||
492 | } | ||
493 | |||
494 | static int prepare_workload(struct intel_vgpu_workload *workload) | ||
495 | { | ||
496 | struct intel_vgpu *vgpu = workload->vgpu; | ||
497 | int ret = 0; | ||
498 | |||
499 | ret = intel_vgpu_pin_mm(workload->shadow_mm); | ||
500 | if (ret) { | ||
501 | gvt_vgpu_err("fail to vgpu pin mm\n"); | ||
502 | return ret; | ||
503 | } | ||
504 | |||
505 | ret = intel_vgpu_sync_oos_pages(workload->vgpu); | ||
506 | if (ret) { | ||
507 | gvt_vgpu_err("fail to vgpu sync oos pages\n"); | ||
508 | goto err_unpin_mm; | ||
509 | } | ||
510 | |||
511 | ret = intel_vgpu_flush_post_shadow(workload->vgpu); | ||
512 | if (ret) { | ||
513 | gvt_vgpu_err("fail to flush post shadow\n"); | ||
514 | goto err_unpin_mm; | ||
515 | } | ||
516 | |||
517 | ret = intel_gvt_generate_request(workload); | ||
518 | if (ret) { | ||
519 | gvt_vgpu_err("fail to generate request\n"); | ||
520 | goto err_unpin_mm; | ||
521 | } | ||
522 | |||
523 | ret = prepare_shadow_batch_buffer(workload); | ||
524 | if (ret) { | ||
525 | gvt_vgpu_err("fail to prepare_shadow_batch_buffer\n"); | ||
526 | goto err_unpin_mm; | ||
527 | } | ||
528 | |||
529 | ret = prepare_shadow_wa_ctx(&workload->wa_ctx); | ||
530 | if (ret) { | ||
531 | gvt_vgpu_err("fail to prepare_shadow_wa_ctx\n"); | ||
532 | goto err_shadow_batch; | ||
533 | } | ||
534 | |||
535 | if (workload->prepare) { | ||
536 | ret = workload->prepare(workload); | ||
537 | if (ret) | ||
538 | goto err_shadow_wa_ctx; | ||
539 | } | ||
540 | |||
541 | return 0; | ||
542 | err_shadow_wa_ctx: | ||
543 | release_shadow_wa_ctx(&workload->wa_ctx); | ||
544 | err_shadow_batch: | ||
545 | release_shadow_batch_buffer(workload); | ||
546 | err_unpin_mm: | ||
547 | intel_vgpu_unpin_mm(workload->shadow_mm); | ||
548 | return ret; | ||
549 | } | ||
550 | |||
344 | static int dispatch_workload(struct intel_vgpu_workload *workload) | 551 | static int dispatch_workload(struct intel_vgpu_workload *workload) |
345 | { | 552 | { |
553 | struct intel_vgpu *vgpu = workload->vgpu; | ||
554 | struct intel_vgpu_submission *s = &vgpu->submission; | ||
555 | struct i915_gem_context *shadow_ctx = s->shadow_ctx; | ||
556 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | ||
346 | int ring_id = workload->ring_id; | 557 | int ring_id = workload->ring_id; |
347 | struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx; | ||
348 | struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv; | ||
349 | struct intel_engine_cs *engine = dev_priv->engine[ring_id]; | 558 | struct intel_engine_cs *engine = dev_priv->engine[ring_id]; |
350 | int ret = 0; | 559 | int ret = 0; |
351 | 560 | ||
@@ -358,12 +567,10 @@ static int dispatch_workload(struct intel_vgpu_workload *workload) | |||
358 | if (ret) | 567 | if (ret) |
359 | goto out; | 568 | goto out; |
360 | 569 | ||
361 | if (workload->prepare) { | 570 | ret = prepare_workload(workload); |
362 | ret = workload->prepare(workload); | 571 | if (ret) { |
363 | if (ret) { | 572 | engine->context_unpin(engine, shadow_ctx); |
364 | engine->context_unpin(engine, shadow_ctx); | 573 | goto out; |
365 | goto out; | ||
366 | } | ||
367 | } | 574 | } |
368 | 575 | ||
369 | out: | 576 | out: |
@@ -431,7 +638,7 @@ static struct intel_vgpu_workload *pick_next_workload( | |||
431 | 638 | ||
432 | gvt_dbg_sched("ring id %d pick new workload %p\n", ring_id, workload); | 639 | gvt_dbg_sched("ring id %d pick new workload %p\n", ring_id, workload); |
433 | 640 | ||
434 | atomic_inc(&workload->vgpu->running_workload_num); | 641 | atomic_inc(&workload->vgpu->submission.running_workload_num); |
435 | out: | 642 | out: |
436 | mutex_unlock(&gvt->lock); | 643 | mutex_unlock(&gvt->lock); |
437 | return workload; | 644 | return workload; |
@@ -441,8 +648,9 @@ static void update_guest_context(struct intel_vgpu_workload *workload) | |||
441 | { | 648 | { |
442 | struct intel_vgpu *vgpu = workload->vgpu; | 649 | struct intel_vgpu *vgpu = workload->vgpu; |
443 | struct intel_gvt *gvt = vgpu->gvt; | 650 | struct intel_gvt *gvt = vgpu->gvt; |
651 | struct intel_vgpu_submission *s = &vgpu->submission; | ||
652 | struct i915_gem_context *shadow_ctx = s->shadow_ctx; | ||
444 | int ring_id = workload->ring_id; | 653 | int ring_id = workload->ring_id; |
445 | struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx; | ||
446 | struct drm_i915_gem_object *ctx_obj = | 654 | struct drm_i915_gem_object *ctx_obj = |
447 | shadow_ctx->engine[ring_id].state->obj; | 655 | shadow_ctx->engine[ring_id].state->obj; |
448 | struct execlist_ring_context *shadow_ring_context; | 656 | struct execlist_ring_context *shadow_ring_context; |
@@ -466,7 +674,7 @@ static void update_guest_context(struct intel_vgpu_workload *workload) | |||
466 | while (i < context_page_num) { | 674 | while (i < context_page_num) { |
467 | context_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, | 675 | context_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, |
468 | (u32)((workload->ctx_desc.lrca + i) << | 676 | (u32)((workload->ctx_desc.lrca + i) << |
469 | GTT_PAGE_SHIFT)); | 677 | I915_GTT_PAGE_SHIFT)); |
470 | if (context_gpa == INTEL_GVT_INVALID_ADDR) { | 678 | if (context_gpa == INTEL_GVT_INVALID_ADDR) { |
471 | gvt_vgpu_err("invalid guest context descriptor\n"); | 679 | gvt_vgpu_err("invalid guest context descriptor\n"); |
472 | return; | 680 | return; |
@@ -475,7 +683,7 @@ static void update_guest_context(struct intel_vgpu_workload *workload) | |||
475 | page = i915_gem_object_get_page(ctx_obj, LRC_HEADER_PAGES + i); | 683 | page = i915_gem_object_get_page(ctx_obj, LRC_HEADER_PAGES + i); |
476 | src = kmap(page); | 684 | src = kmap(page); |
477 | intel_gvt_hypervisor_write_gpa(vgpu, context_gpa, src, | 685 | intel_gvt_hypervisor_write_gpa(vgpu, context_gpa, src, |
478 | GTT_PAGE_SIZE); | 686 | I915_GTT_PAGE_SIZE); |
479 | kunmap(page); | 687 | kunmap(page); |
480 | i++; | 688 | i++; |
481 | } | 689 | } |
@@ -500,23 +708,41 @@ static void update_guest_context(struct intel_vgpu_workload *workload) | |||
500 | sizeof(*shadow_ring_context), | 708 | sizeof(*shadow_ring_context), |
501 | (void *)shadow_ring_context + | 709 | (void *)shadow_ring_context + |
502 | sizeof(*shadow_ring_context), | 710 | sizeof(*shadow_ring_context), |
503 | GTT_PAGE_SIZE - sizeof(*shadow_ring_context)); | 711 | I915_GTT_PAGE_SIZE - sizeof(*shadow_ring_context)); |
504 | 712 | ||
505 | kunmap(page); | 713 | kunmap(page); |
506 | } | 714 | } |
507 | 715 | ||
716 | static void clean_workloads(struct intel_vgpu *vgpu, unsigned long engine_mask) | ||
717 | { | ||
718 | struct intel_vgpu_submission *s = &vgpu->submission; | ||
719 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | ||
720 | struct intel_engine_cs *engine; | ||
721 | struct intel_vgpu_workload *pos, *n; | ||
722 | unsigned int tmp; | ||
723 | |||
724 | /* free the unsubmited workloads in the queues. */ | ||
725 | for_each_engine_masked(engine, dev_priv, engine_mask, tmp) { | ||
726 | list_for_each_entry_safe(pos, n, | ||
727 | &s->workload_q_head[engine->id], list) { | ||
728 | list_del_init(&pos->list); | ||
729 | intel_vgpu_destroy_workload(pos); | ||
730 | } | ||
731 | clear_bit(engine->id, s->shadow_ctx_desc_updated); | ||
732 | } | ||
733 | } | ||
734 | |||
508 | static void complete_current_workload(struct intel_gvt *gvt, int ring_id) | 735 | static void complete_current_workload(struct intel_gvt *gvt, int ring_id) |
509 | { | 736 | { |
510 | struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; | 737 | struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; |
511 | struct intel_vgpu_workload *workload; | 738 | struct intel_vgpu_workload *workload = |
512 | struct intel_vgpu *vgpu; | 739 | scheduler->current_workload[ring_id]; |
740 | struct intel_vgpu *vgpu = workload->vgpu; | ||
741 | struct intel_vgpu_submission *s = &vgpu->submission; | ||
513 | int event; | 742 | int event; |
514 | 743 | ||
515 | mutex_lock(&gvt->lock); | 744 | mutex_lock(&gvt->lock); |
516 | 745 | ||
517 | workload = scheduler->current_workload[ring_id]; | ||
518 | vgpu = workload->vgpu; | ||
519 | |||
520 | /* For the workload w/ request, needs to wait for the context | 746 | /* For the workload w/ request, needs to wait for the context |
521 | * switch to make sure request is completed. | 747 | * switch to make sure request is completed. |
522 | * For the workload w/o request, directly complete the workload. | 748 | * For the workload w/o request, directly complete the workload. |
@@ -553,7 +779,7 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id) | |||
553 | } | 779 | } |
554 | mutex_lock(&dev_priv->drm.struct_mutex); | 780 | mutex_lock(&dev_priv->drm.struct_mutex); |
555 | /* unpin shadow ctx as the shadow_ctx update is done */ | 781 | /* unpin shadow ctx as the shadow_ctx update is done */ |
556 | engine->context_unpin(engine, workload->vgpu->shadow_ctx); | 782 | engine->context_unpin(engine, s->shadow_ctx); |
557 | mutex_unlock(&dev_priv->drm.struct_mutex); | 783 | mutex_unlock(&dev_priv->drm.struct_mutex); |
558 | } | 784 | } |
559 | 785 | ||
@@ -563,9 +789,32 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id) | |||
563 | scheduler->current_workload[ring_id] = NULL; | 789 | scheduler->current_workload[ring_id] = NULL; |
564 | 790 | ||
565 | list_del_init(&workload->list); | 791 | list_del_init(&workload->list); |
792 | |||
793 | if (!workload->status) { | ||
794 | release_shadow_batch_buffer(workload); | ||
795 | release_shadow_wa_ctx(&workload->wa_ctx); | ||
796 | } | ||
797 | |||
798 | if (workload->status || (vgpu->resetting_eng & ENGINE_MASK(ring_id))) { | ||
799 | /* if workload->status is not successful means HW GPU | ||
800 | * has occurred GPU hang or something wrong with i915/GVT, | ||
801 | * and GVT won't inject context switch interrupt to guest. | ||
802 | * So this error is a vGPU hang actually to the guest. | ||
803 | * According to this we should emunlate a vGPU hang. If | ||
804 | * there are pending workloads which are already submitted | ||
805 | * from guest, we should clean them up like HW GPU does. | ||
806 | * | ||
807 | * if it is in middle of engine resetting, the pending | ||
808 | * workloads won't be submitted to HW GPU and will be | ||
809 | * cleaned up during the resetting process later, so doing | ||
810 | * the workload clean up here doesn't have any impact. | ||
811 | **/ | ||
812 | clean_workloads(vgpu, ENGINE_MASK(ring_id)); | ||
813 | } | ||
814 | |||
566 | workload->complete(workload); | 815 | workload->complete(workload); |
567 | 816 | ||
568 | atomic_dec(&vgpu->running_workload_num); | 817 | atomic_dec(&s->running_workload_num); |
569 | wake_up(&scheduler->workload_complete_wq); | 818 | wake_up(&scheduler->workload_complete_wq); |
570 | 819 | ||
571 | if (gvt->scheduler.need_reschedule) | 820 | if (gvt->scheduler.need_reschedule) |
@@ -648,20 +897,23 @@ complete: | |||
648 | FORCEWAKE_ALL); | 897 | FORCEWAKE_ALL); |
649 | 898 | ||
650 | intel_runtime_pm_put(gvt->dev_priv); | 899 | intel_runtime_pm_put(gvt->dev_priv); |
900 | if (ret && (vgpu_is_vm_unhealthy(ret))) | ||
901 | enter_failsafe_mode(vgpu, GVT_FAILSAFE_GUEST_ERR); | ||
651 | } | 902 | } |
652 | return 0; | 903 | return 0; |
653 | } | 904 | } |
654 | 905 | ||
655 | void intel_gvt_wait_vgpu_idle(struct intel_vgpu *vgpu) | 906 | void intel_gvt_wait_vgpu_idle(struct intel_vgpu *vgpu) |
656 | { | 907 | { |
908 | struct intel_vgpu_submission *s = &vgpu->submission; | ||
657 | struct intel_gvt *gvt = vgpu->gvt; | 909 | struct intel_gvt *gvt = vgpu->gvt; |
658 | struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; | 910 | struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; |
659 | 911 | ||
660 | if (atomic_read(&vgpu->running_workload_num)) { | 912 | if (atomic_read(&s->running_workload_num)) { |
661 | gvt_dbg_sched("wait vgpu idle\n"); | 913 | gvt_dbg_sched("wait vgpu idle\n"); |
662 | 914 | ||
663 | wait_event(scheduler->workload_complete_wq, | 915 | wait_event(scheduler->workload_complete_wq, |
664 | !atomic_read(&vgpu->running_workload_num)); | 916 | !atomic_read(&s->running_workload_num)); |
665 | } | 917 | } |
666 | } | 918 | } |
667 | 919 | ||
@@ -726,23 +978,354 @@ err: | |||
726 | return ret; | 978 | return ret; |
727 | } | 979 | } |
728 | 980 | ||
729 | void intel_vgpu_clean_gvt_context(struct intel_vgpu *vgpu) | 981 | /** |
982 | * intel_vgpu_clean_submission - free submission-related resource for vGPU | ||
983 | * @vgpu: a vGPU | ||
984 | * | ||
985 | * This function is called when a vGPU is being destroyed. | ||
986 | * | ||
987 | */ | ||
988 | void intel_vgpu_clean_submission(struct intel_vgpu *vgpu) | ||
989 | { | ||
990 | struct intel_vgpu_submission *s = &vgpu->submission; | ||
991 | |||
992 | intel_vgpu_select_submission_ops(vgpu, 0); | ||
993 | i915_gem_context_put(s->shadow_ctx); | ||
994 | kmem_cache_destroy(s->workloads); | ||
995 | } | ||
996 | |||
997 | |||
998 | /** | ||
999 | * intel_vgpu_reset_submission - reset submission-related resource for vGPU | ||
1000 | * @vgpu: a vGPU | ||
1001 | * @engine_mask: engines expected to be reset | ||
1002 | * | ||
1003 | * This function is called when a vGPU is being destroyed. | ||
1004 | * | ||
1005 | */ | ||
1006 | void intel_vgpu_reset_submission(struct intel_vgpu *vgpu, | ||
1007 | unsigned long engine_mask) | ||
730 | { | 1008 | { |
731 | i915_gem_context_put(vgpu->shadow_ctx); | 1009 | struct intel_vgpu_submission *s = &vgpu->submission; |
1010 | |||
1011 | if (!s->active) | ||
1012 | return; | ||
1013 | |||
1014 | clean_workloads(vgpu, engine_mask); | ||
1015 | s->ops->reset(vgpu, engine_mask); | ||
732 | } | 1016 | } |
733 | 1017 | ||
734 | int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu) | 1018 | /** |
1019 | * intel_vgpu_setup_submission - setup submission-related resource for vGPU | ||
1020 | * @vgpu: a vGPU | ||
1021 | * | ||
1022 | * This function is called when a vGPU is being created. | ||
1023 | * | ||
1024 | * Returns: | ||
1025 | * Zero on success, negative error code if failed. | ||
1026 | * | ||
1027 | */ | ||
1028 | int intel_vgpu_setup_submission(struct intel_vgpu *vgpu) | ||
735 | { | 1029 | { |
736 | atomic_set(&vgpu->running_workload_num, 0); | 1030 | struct intel_vgpu_submission *s = &vgpu->submission; |
1031 | enum intel_engine_id i; | ||
1032 | struct intel_engine_cs *engine; | ||
1033 | int ret; | ||
737 | 1034 | ||
738 | vgpu->shadow_ctx = i915_gem_context_create_gvt( | 1035 | s->shadow_ctx = i915_gem_context_create_gvt( |
739 | &vgpu->gvt->dev_priv->drm); | 1036 | &vgpu->gvt->dev_priv->drm); |
740 | if (IS_ERR(vgpu->shadow_ctx)) | 1037 | if (IS_ERR(s->shadow_ctx)) |
741 | return PTR_ERR(vgpu->shadow_ctx); | 1038 | return PTR_ERR(s->shadow_ctx); |
1039 | |||
1040 | bitmap_zero(s->shadow_ctx_desc_updated, I915_NUM_ENGINES); | ||
1041 | |||
1042 | s->workloads = kmem_cache_create("gvt-g_vgpu_workload", | ||
1043 | sizeof(struct intel_vgpu_workload), 0, | ||
1044 | SLAB_HWCACHE_ALIGN, | ||
1045 | NULL); | ||
1046 | |||
1047 | if (!s->workloads) { | ||
1048 | ret = -ENOMEM; | ||
1049 | goto out_shadow_ctx; | ||
1050 | } | ||
1051 | |||
1052 | for_each_engine(engine, vgpu->gvt->dev_priv, i) | ||
1053 | INIT_LIST_HEAD(&s->workload_q_head[i]); | ||
1054 | |||
1055 | atomic_set(&s->running_workload_num, 0); | ||
1056 | bitmap_zero(s->tlb_handle_pending, I915_NUM_ENGINES); | ||
1057 | |||
1058 | return 0; | ||
1059 | |||
1060 | out_shadow_ctx: | ||
1061 | i915_gem_context_put(s->shadow_ctx); | ||
1062 | return ret; | ||
1063 | } | ||
1064 | |||
1065 | /** | ||
1066 | * intel_vgpu_select_submission_ops - select virtual submission interface | ||
1067 | * @vgpu: a vGPU | ||
1068 | * @interface: expected vGPU virtual submission interface | ||
1069 | * | ||
1070 | * This function is called when guest configures submission interface. | ||
1071 | * | ||
1072 | * Returns: | ||
1073 | * Zero on success, negative error code if failed. | ||
1074 | * | ||
1075 | */ | ||
1076 | int intel_vgpu_select_submission_ops(struct intel_vgpu *vgpu, | ||
1077 | unsigned int interface) | ||
1078 | { | ||
1079 | struct intel_vgpu_submission *s = &vgpu->submission; | ||
1080 | const struct intel_vgpu_submission_ops *ops[] = { | ||
1081 | [INTEL_VGPU_EXECLIST_SUBMISSION] = | ||
1082 | &intel_vgpu_execlist_submission_ops, | ||
1083 | }; | ||
1084 | int ret; | ||
1085 | |||
1086 | if (WARN_ON(interface >= ARRAY_SIZE(ops))) | ||
1087 | return -EINVAL; | ||
1088 | |||
1089 | if (s->active) { | ||
1090 | s->ops->clean(vgpu); | ||
1091 | s->active = false; | ||
1092 | gvt_dbg_core("vgpu%d: de-select ops [ %s ] \n", | ||
1093 | vgpu->id, s->ops->name); | ||
1094 | } | ||
1095 | |||
1096 | if (interface == 0) { | ||
1097 | s->ops = NULL; | ||
1098 | s->virtual_submission_interface = 0; | ||
1099 | gvt_dbg_core("vgpu%d: no submission ops\n", vgpu->id); | ||
1100 | return 0; | ||
1101 | } | ||
1102 | |||
1103 | ret = ops[interface]->init(vgpu); | ||
1104 | if (ret) | ||
1105 | return ret; | ||
1106 | |||
1107 | s->ops = ops[interface]; | ||
1108 | s->virtual_submission_interface = interface; | ||
1109 | s->active = true; | ||
1110 | |||
1111 | gvt_dbg_core("vgpu%d: activate ops [ %s ]\n", | ||
1112 | vgpu->id, s->ops->name); | ||
1113 | |||
1114 | return 0; | ||
1115 | } | ||
1116 | |||
1117 | /** | ||
1118 | * intel_vgpu_destroy_workload - destroy a vGPU workload | ||
1119 | * @vgpu: a vGPU | ||
1120 | * | ||
1121 | * This function is called when destroy a vGPU workload. | ||
1122 | * | ||
1123 | */ | ||
1124 | void intel_vgpu_destroy_workload(struct intel_vgpu_workload *workload) | ||
1125 | { | ||
1126 | struct intel_vgpu_submission *s = &workload->vgpu->submission; | ||
1127 | |||
1128 | if (workload->shadow_mm) | ||
1129 | intel_gvt_mm_unreference(workload->shadow_mm); | ||
1130 | |||
1131 | kmem_cache_free(s->workloads, workload); | ||
1132 | } | ||
1133 | |||
1134 | static struct intel_vgpu_workload * | ||
1135 | alloc_workload(struct intel_vgpu *vgpu) | ||
1136 | { | ||
1137 | struct intel_vgpu_submission *s = &vgpu->submission; | ||
1138 | struct intel_vgpu_workload *workload; | ||
742 | 1139 | ||
743 | vgpu->shadow_ctx->engine[RCS].initialised = true; | 1140 | workload = kmem_cache_zalloc(s->workloads, GFP_KERNEL); |
1141 | if (!workload) | ||
1142 | return ERR_PTR(-ENOMEM); | ||
744 | 1143 | ||
745 | bitmap_zero(vgpu->shadow_ctx_desc_updated, I915_NUM_ENGINES); | 1144 | INIT_LIST_HEAD(&workload->list); |
1145 | INIT_LIST_HEAD(&workload->shadow_bb); | ||
746 | 1146 | ||
1147 | init_waitqueue_head(&workload->shadow_ctx_status_wq); | ||
1148 | atomic_set(&workload->shadow_ctx_active, 0); | ||
1149 | |||
1150 | workload->status = -EINPROGRESS; | ||
1151 | workload->shadowed = false; | ||
1152 | workload->vgpu = vgpu; | ||
1153 | |||
1154 | return workload; | ||
1155 | } | ||
1156 | |||
1157 | #define RING_CTX_OFF(x) \ | ||
1158 | offsetof(struct execlist_ring_context, x) | ||
1159 | |||
1160 | static void read_guest_pdps(struct intel_vgpu *vgpu, | ||
1161 | u64 ring_context_gpa, u32 pdp[8]) | ||
1162 | { | ||
1163 | u64 gpa; | ||
1164 | int i; | ||
1165 | |||
1166 | gpa = ring_context_gpa + RING_CTX_OFF(pdp3_UDW.val); | ||
1167 | |||
1168 | for (i = 0; i < 8; i++) | ||
1169 | intel_gvt_hypervisor_read_gpa(vgpu, | ||
1170 | gpa + i * 8, &pdp[7 - i], 4); | ||
1171 | } | ||
1172 | |||
1173 | static int prepare_mm(struct intel_vgpu_workload *workload) | ||
1174 | { | ||
1175 | struct execlist_ctx_descriptor_format *desc = &workload->ctx_desc; | ||
1176 | struct intel_vgpu_mm *mm; | ||
1177 | struct intel_vgpu *vgpu = workload->vgpu; | ||
1178 | int page_table_level; | ||
1179 | u32 pdp[8]; | ||
1180 | |||
1181 | if (desc->addressing_mode == 1) { /* legacy 32-bit */ | ||
1182 | page_table_level = 3; | ||
1183 | } else if (desc->addressing_mode == 3) { /* legacy 64 bit */ | ||
1184 | page_table_level = 4; | ||
1185 | } else { | ||
1186 | gvt_vgpu_err("Advanced Context mode(SVM) is not supported!\n"); | ||
1187 | return -EINVAL; | ||
1188 | } | ||
1189 | |||
1190 | read_guest_pdps(workload->vgpu, workload->ring_context_gpa, pdp); | ||
1191 | |||
1192 | mm = intel_vgpu_find_ppgtt_mm(workload->vgpu, page_table_level, pdp); | ||
1193 | if (mm) { | ||
1194 | intel_gvt_mm_reference(mm); | ||
1195 | } else { | ||
1196 | |||
1197 | mm = intel_vgpu_create_mm(workload->vgpu, INTEL_GVT_MM_PPGTT, | ||
1198 | pdp, page_table_level, 0); | ||
1199 | if (IS_ERR(mm)) { | ||
1200 | gvt_vgpu_err("fail to create mm object.\n"); | ||
1201 | return PTR_ERR(mm); | ||
1202 | } | ||
1203 | } | ||
1204 | workload->shadow_mm = mm; | ||
747 | return 0; | 1205 | return 0; |
748 | } | 1206 | } |
1207 | |||
1208 | #define same_context(a, b) (((a)->context_id == (b)->context_id) && \ | ||
1209 | ((a)->lrca == (b)->lrca)) | ||
1210 | |||
1211 | #define get_last_workload(q) \ | ||
1212 | (list_empty(q) ? NULL : container_of(q->prev, \ | ||
1213 | struct intel_vgpu_workload, list)) | ||
1214 | /** | ||
1215 | * intel_vgpu_create_workload - create a vGPU workload | ||
1216 | * @vgpu: a vGPU | ||
1217 | * @desc: a guest context descriptor | ||
1218 | * | ||
1219 | * This function is called when creating a vGPU workload. | ||
1220 | * | ||
1221 | * Returns: | ||
1222 | * struct intel_vgpu_workload * on success, negative error code in | ||
1223 | * pointer if failed. | ||
1224 | * | ||
1225 | */ | ||
1226 | struct intel_vgpu_workload * | ||
1227 | intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id, | ||
1228 | struct execlist_ctx_descriptor_format *desc) | ||
1229 | { | ||
1230 | struct intel_vgpu_submission *s = &vgpu->submission; | ||
1231 | struct list_head *q = workload_q_head(vgpu, ring_id); | ||
1232 | struct intel_vgpu_workload *last_workload = get_last_workload(q); | ||
1233 | struct intel_vgpu_workload *workload = NULL; | ||
1234 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; | ||
1235 | u64 ring_context_gpa; | ||
1236 | u32 head, tail, start, ctl, ctx_ctl, per_ctx, indirect_ctx; | ||
1237 | int ret; | ||
1238 | |||
1239 | ring_context_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, | ||
1240 | (u32)((desc->lrca + 1) << I915_GTT_PAGE_SHIFT)); | ||
1241 | if (ring_context_gpa == INTEL_GVT_INVALID_ADDR) { | ||
1242 | gvt_vgpu_err("invalid guest context LRCA: %x\n", desc->lrca); | ||
1243 | return ERR_PTR(-EINVAL); | ||
1244 | } | ||
1245 | |||
1246 | intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + | ||
1247 | RING_CTX_OFF(ring_header.val), &head, 4); | ||
1248 | |||
1249 | intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + | ||
1250 | RING_CTX_OFF(ring_tail.val), &tail, 4); | ||
1251 | |||
1252 | head &= RB_HEAD_OFF_MASK; | ||
1253 | tail &= RB_TAIL_OFF_MASK; | ||
1254 | |||
1255 | if (last_workload && same_context(&last_workload->ctx_desc, desc)) { | ||
1256 | gvt_dbg_el("ring id %d cur workload == last\n", ring_id); | ||
1257 | gvt_dbg_el("ctx head %x real head %lx\n", head, | ||
1258 | last_workload->rb_tail); | ||
1259 | /* | ||
1260 | * cannot use guest context head pointer here, | ||
1261 | * as it might not be updated at this time | ||
1262 | */ | ||
1263 | head = last_workload->rb_tail; | ||
1264 | } | ||
1265 | |||
1266 | gvt_dbg_el("ring id %d begin a new workload\n", ring_id); | ||
1267 | |||
1268 | /* record some ring buffer register values for scan and shadow */ | ||
1269 | intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + | ||
1270 | RING_CTX_OFF(rb_start.val), &start, 4); | ||
1271 | intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + | ||
1272 | RING_CTX_OFF(rb_ctrl.val), &ctl, 4); | ||
1273 | intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + | ||
1274 | RING_CTX_OFF(ctx_ctrl.val), &ctx_ctl, 4); | ||
1275 | |||
1276 | workload = alloc_workload(vgpu); | ||
1277 | if (IS_ERR(workload)) | ||
1278 | return workload; | ||
1279 | |||
1280 | workload->ring_id = ring_id; | ||
1281 | workload->ctx_desc = *desc; | ||
1282 | workload->ring_context_gpa = ring_context_gpa; | ||
1283 | workload->rb_head = head; | ||
1284 | workload->rb_tail = tail; | ||
1285 | workload->rb_start = start; | ||
1286 | workload->rb_ctl = ctl; | ||
1287 | |||
1288 | if (ring_id == RCS) { | ||
1289 | intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + | ||
1290 | RING_CTX_OFF(bb_per_ctx_ptr.val), &per_ctx, 4); | ||
1291 | intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa + | ||
1292 | RING_CTX_OFF(rcs_indirect_ctx.val), &indirect_ctx, 4); | ||
1293 | |||
1294 | workload->wa_ctx.indirect_ctx.guest_gma = | ||
1295 | indirect_ctx & INDIRECT_CTX_ADDR_MASK; | ||
1296 | workload->wa_ctx.indirect_ctx.size = | ||
1297 | (indirect_ctx & INDIRECT_CTX_SIZE_MASK) * | ||
1298 | CACHELINE_BYTES; | ||
1299 | workload->wa_ctx.per_ctx.guest_gma = | ||
1300 | per_ctx & PER_CTX_ADDR_MASK; | ||
1301 | workload->wa_ctx.per_ctx.valid = per_ctx & 1; | ||
1302 | } | ||
1303 | |||
1304 | gvt_dbg_el("workload %p ring id %d head %x tail %x start %x ctl %x\n", | ||
1305 | workload, ring_id, head, tail, start, ctl); | ||
1306 | |||
1307 | ret = prepare_mm(workload); | ||
1308 | if (ret) { | ||
1309 | kmem_cache_free(s->workloads, workload); | ||
1310 | return ERR_PTR(ret); | ||
1311 | } | ||
1312 | |||
1313 | /* Only scan and shadow the first workload in the queue | ||
1314 | * as there is only one pre-allocated buf-obj for shadow. | ||
1315 | */ | ||
1316 | if (list_empty(workload_q_head(vgpu, ring_id))) { | ||
1317 | intel_runtime_pm_get(dev_priv); | ||
1318 | mutex_lock(&dev_priv->drm.struct_mutex); | ||
1319 | ret = intel_gvt_scan_and_shadow_workload(workload); | ||
1320 | mutex_unlock(&dev_priv->drm.struct_mutex); | ||
1321 | intel_runtime_pm_put(dev_priv); | ||
1322 | } | ||
1323 | |||
1324 | if (ret && (vgpu_is_vm_unhealthy(ret))) { | ||
1325 | enter_failsafe_mode(vgpu, GVT_FAILSAFE_GUEST_ERR); | ||
1326 | intel_vgpu_destroy_workload(workload); | ||
1327 | return ERR_PTR(ret); | ||
1328 | } | ||
1329 | |||
1330 | return workload; | ||
1331 | } | ||
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.h b/drivers/gpu/drm/i915/gvt/scheduler.h index b9f872204d7e..e4a9f9acd4a9 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.h +++ b/drivers/gpu/drm/i915/gvt/scheduler.h | |||
@@ -112,17 +112,18 @@ struct intel_vgpu_workload { | |||
112 | struct intel_shadow_wa_ctx wa_ctx; | 112 | struct intel_shadow_wa_ctx wa_ctx; |
113 | }; | 113 | }; |
114 | 114 | ||
115 | /* Intel shadow batch buffer is a i915 gem object */ | 115 | struct intel_vgpu_shadow_bb { |
116 | struct intel_shadow_bb_entry { | ||
117 | struct list_head list; | 116 | struct list_head list; |
118 | struct drm_i915_gem_object *obj; | 117 | struct drm_i915_gem_object *obj; |
118 | struct i915_vma *vma; | ||
119 | void *va; | 119 | void *va; |
120 | unsigned long len; | ||
121 | u32 *bb_start_cmd_va; | 120 | u32 *bb_start_cmd_va; |
121 | unsigned int clflush; | ||
122 | bool accessing; | ||
122 | }; | 123 | }; |
123 | 124 | ||
124 | #define workload_q_head(vgpu, ring_id) \ | 125 | #define workload_q_head(vgpu, ring_id) \ |
125 | (&(vgpu->workload_q_head[ring_id])) | 126 | (&(vgpu->submission.workload_q_head[ring_id])) |
126 | 127 | ||
127 | #define queue_workload(workload) do { \ | 128 | #define queue_workload(workload) do { \ |
128 | list_add_tail(&workload->list, \ | 129 | list_add_tail(&workload->list, \ |
@@ -137,12 +138,23 @@ void intel_gvt_clean_workload_scheduler(struct intel_gvt *gvt); | |||
137 | 138 | ||
138 | void intel_gvt_wait_vgpu_idle(struct intel_vgpu *vgpu); | 139 | void intel_gvt_wait_vgpu_idle(struct intel_vgpu *vgpu); |
139 | 140 | ||
140 | int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu); | 141 | int intel_vgpu_setup_submission(struct intel_vgpu *vgpu); |
141 | 142 | ||
142 | void intel_vgpu_clean_gvt_context(struct intel_vgpu *vgpu); | 143 | void intel_vgpu_reset_submission(struct intel_vgpu *vgpu, |
144 | unsigned long engine_mask); | ||
143 | 145 | ||
144 | void release_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx); | 146 | void intel_vgpu_clean_submission(struct intel_vgpu *vgpu); |
145 | 147 | ||
146 | int intel_gvt_generate_request(struct intel_vgpu_workload *workload); | 148 | int intel_vgpu_select_submission_ops(struct intel_vgpu *vgpu, |
149 | unsigned int interface); | ||
150 | |||
151 | extern const struct intel_vgpu_submission_ops | ||
152 | intel_vgpu_execlist_submission_ops; | ||
153 | |||
154 | struct intel_vgpu_workload * | ||
155 | intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id, | ||
156 | struct execlist_ctx_descriptor_format *desc); | ||
157 | |||
158 | void intel_vgpu_destroy_workload(struct intel_vgpu_workload *workload); | ||
147 | 159 | ||
148 | #endif | 160 | #endif |
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c index 02c61a1ad56a..c6b82d1ba7de 100644 --- a/drivers/gpu/drm/i915/gvt/vgpu.c +++ b/drivers/gpu/drm/i915/gvt/vgpu.c | |||
@@ -43,7 +43,10 @@ void populate_pvinfo_page(struct intel_vgpu *vgpu) | |||
43 | vgpu_vreg(vgpu, vgtif_reg(version_minor)) = 0; | 43 | vgpu_vreg(vgpu, vgtif_reg(version_minor)) = 0; |
44 | vgpu_vreg(vgpu, vgtif_reg(display_ready)) = 0; | 44 | vgpu_vreg(vgpu, vgtif_reg(display_ready)) = 0; |
45 | vgpu_vreg(vgpu, vgtif_reg(vgt_id)) = vgpu->id; | 45 | vgpu_vreg(vgpu, vgtif_reg(vgt_id)) = vgpu->id; |
46 | |||
46 | vgpu_vreg(vgpu, vgtif_reg(vgt_caps)) = VGT_CAPS_FULL_48BIT_PPGTT; | 47 | vgpu_vreg(vgpu, vgtif_reg(vgt_caps)) = VGT_CAPS_FULL_48BIT_PPGTT; |
48 | vgpu_vreg(vgpu, vgtif_reg(vgt_caps)) |= VGT_CAPS_HWSP_EMULATION; | ||
49 | |||
47 | vgpu_vreg(vgpu, vgtif_reg(avail_rs.mappable_gmadr.base)) = | 50 | vgpu_vreg(vgpu, vgtif_reg(avail_rs.mappable_gmadr.base)) = |
48 | vgpu_aperture_gmadr_base(vgpu); | 51 | vgpu_aperture_gmadr_base(vgpu); |
49 | vgpu_vreg(vgpu, vgtif_reg(avail_rs.mappable_gmadr.size)) = | 52 | vgpu_vreg(vgpu, vgtif_reg(avail_rs.mappable_gmadr.size)) = |
@@ -226,7 +229,7 @@ void intel_gvt_deactivate_vgpu(struct intel_vgpu *vgpu) | |||
226 | 229 | ||
227 | vgpu->active = false; | 230 | vgpu->active = false; |
228 | 231 | ||
229 | if (atomic_read(&vgpu->running_workload_num)) { | 232 | if (atomic_read(&vgpu->submission.running_workload_num)) { |
230 | mutex_unlock(&gvt->lock); | 233 | mutex_unlock(&gvt->lock); |
231 | intel_gvt_wait_vgpu_idle(vgpu); | 234 | intel_gvt_wait_vgpu_idle(vgpu); |
232 | mutex_lock(&gvt->lock); | 235 | mutex_lock(&gvt->lock); |
@@ -252,10 +255,10 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu) | |||
252 | 255 | ||
253 | WARN(vgpu->active, "vGPU is still active!\n"); | 256 | WARN(vgpu->active, "vGPU is still active!\n"); |
254 | 257 | ||
258 | intel_gvt_debugfs_remove_vgpu(vgpu); | ||
255 | idr_remove(&gvt->vgpu_idr, vgpu->id); | 259 | idr_remove(&gvt->vgpu_idr, vgpu->id); |
256 | intel_vgpu_clean_sched_policy(vgpu); | 260 | intel_vgpu_clean_sched_policy(vgpu); |
257 | intel_vgpu_clean_gvt_context(vgpu); | 261 | intel_vgpu_clean_submission(vgpu); |
258 | intel_vgpu_clean_execlist(vgpu); | ||
259 | intel_vgpu_clean_display(vgpu); | 262 | intel_vgpu_clean_display(vgpu); |
260 | intel_vgpu_clean_opregion(vgpu); | 263 | intel_vgpu_clean_opregion(vgpu); |
261 | intel_vgpu_clean_gtt(vgpu); | 264 | intel_vgpu_clean_gtt(vgpu); |
@@ -293,7 +296,7 @@ struct intel_vgpu *intel_gvt_create_idle_vgpu(struct intel_gvt *gvt) | |||
293 | vgpu->gvt = gvt; | 296 | vgpu->gvt = gvt; |
294 | 297 | ||
295 | for (i = 0; i < I915_NUM_ENGINES; i++) | 298 | for (i = 0; i < I915_NUM_ENGINES; i++) |
296 | INIT_LIST_HEAD(&vgpu->workload_q_head[i]); | 299 | INIT_LIST_HEAD(&vgpu->submission.workload_q_head[i]); |
297 | 300 | ||
298 | ret = intel_vgpu_init_sched_policy(vgpu); | 301 | ret = intel_vgpu_init_sched_policy(vgpu); |
299 | if (ret) | 302 | if (ret) |
@@ -346,7 +349,6 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt, | |||
346 | vgpu->handle = param->handle; | 349 | vgpu->handle = param->handle; |
347 | vgpu->gvt = gvt; | 350 | vgpu->gvt = gvt; |
348 | vgpu->sched_ctl.weight = param->weight; | 351 | vgpu->sched_ctl.weight = param->weight; |
349 | bitmap_zero(vgpu->tlb_handle_pending, I915_NUM_ENGINES); | ||
350 | 352 | ||
351 | intel_vgpu_init_cfg_space(vgpu, param->primary); | 353 | intel_vgpu_init_cfg_space(vgpu, param->primary); |
352 | 354 | ||
@@ -372,26 +374,26 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt, | |||
372 | if (ret) | 374 | if (ret) |
373 | goto out_clean_gtt; | 375 | goto out_clean_gtt; |
374 | 376 | ||
375 | ret = intel_vgpu_init_execlist(vgpu); | 377 | ret = intel_vgpu_setup_submission(vgpu); |
376 | if (ret) | 378 | if (ret) |
377 | goto out_clean_display; | 379 | goto out_clean_display; |
378 | 380 | ||
379 | ret = intel_vgpu_init_gvt_context(vgpu); | 381 | ret = intel_vgpu_init_sched_policy(vgpu); |
380 | if (ret) | 382 | if (ret) |
381 | goto out_clean_execlist; | 383 | goto out_clean_submission; |
382 | 384 | ||
383 | ret = intel_vgpu_init_sched_policy(vgpu); | 385 | ret = intel_gvt_debugfs_add_vgpu(vgpu); |
384 | if (ret) | 386 | if (ret) |
385 | goto out_clean_shadow_ctx; | 387 | goto out_clean_sched_policy; |
386 | 388 | ||
387 | mutex_unlock(&gvt->lock); | 389 | mutex_unlock(&gvt->lock); |
388 | 390 | ||
389 | return vgpu; | 391 | return vgpu; |
390 | 392 | ||
391 | out_clean_shadow_ctx: | 393 | out_clean_sched_policy: |
392 | intel_vgpu_clean_gvt_context(vgpu); | 394 | intel_vgpu_clean_sched_policy(vgpu); |
393 | out_clean_execlist: | 395 | out_clean_submission: |
394 | intel_vgpu_clean_execlist(vgpu); | 396 | intel_vgpu_clean_submission(vgpu); |
395 | out_clean_display: | 397 | out_clean_display: |
396 | intel_vgpu_clean_display(vgpu); | 398 | intel_vgpu_clean_display(vgpu); |
397 | out_clean_gtt: | 399 | out_clean_gtt: |
@@ -500,10 +502,10 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr, | |||
500 | mutex_lock(&gvt->lock); | 502 | mutex_lock(&gvt->lock); |
501 | } | 503 | } |
502 | 504 | ||
503 | intel_vgpu_reset_execlist(vgpu, resetting_eng); | 505 | intel_vgpu_reset_submission(vgpu, resetting_eng); |
504 | |||
505 | /* full GPU reset or device model level reset */ | 506 | /* full GPU reset or device model level reset */ |
506 | if (engine_mask == ALL_ENGINES || dmlr) { | 507 | if (engine_mask == ALL_ENGINES || dmlr) { |
508 | intel_vgpu_select_submission_ops(vgpu, 0); | ||
507 | 509 | ||
508 | /*fence will not be reset during virtual reset */ | 510 | /*fence will not be reset during virtual reset */ |
509 | if (dmlr) { | 511 | if (dmlr) { |
diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 8ba932b22f7c..b11629beeb63 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c | |||
@@ -798,22 +798,15 @@ struct cmd_node { | |||
798 | */ | 798 | */ |
799 | static inline u32 cmd_header_key(u32 x) | 799 | static inline u32 cmd_header_key(u32 x) |
800 | { | 800 | { |
801 | u32 shift; | ||
802 | |||
803 | switch (x >> INSTR_CLIENT_SHIFT) { | 801 | switch (x >> INSTR_CLIENT_SHIFT) { |
804 | default: | 802 | default: |
805 | case INSTR_MI_CLIENT: | 803 | case INSTR_MI_CLIENT: |
806 | shift = STD_MI_OPCODE_SHIFT; | 804 | return x >> STD_MI_OPCODE_SHIFT; |
807 | break; | ||
808 | case INSTR_RC_CLIENT: | 805 | case INSTR_RC_CLIENT: |
809 | shift = STD_3D_OPCODE_SHIFT; | 806 | return x >> STD_3D_OPCODE_SHIFT; |
810 | break; | ||
811 | case INSTR_BC_CLIENT: | 807 | case INSTR_BC_CLIENT: |
812 | shift = STD_2D_OPCODE_SHIFT; | 808 | return x >> STD_2D_OPCODE_SHIFT; |
813 | break; | ||
814 | } | 809 | } |
815 | |||
816 | return x >> shift; | ||
817 | } | 810 | } |
818 | 811 | ||
819 | static int init_hash_table(struct intel_engine_cs *engine, | 812 | static int init_hash_table(struct intel_engine_cs *engine, |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index c65e381b85f3..df3852c02a35 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/sort.h> | 30 | #include <linux/sort.h> |
31 | #include <linux/sched/mm.h> | 31 | #include <linux/sched/mm.h> |
32 | #include "intel_drv.h" | 32 | #include "intel_drv.h" |
33 | #include "i915_guc_submission.h" | 33 | #include "intel_guc_submission.h" |
34 | 34 | ||
35 | static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node) | 35 | static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node) |
36 | { | 36 | { |
@@ -1974,7 +1974,6 @@ static int i915_context_status(struct seq_file *m, void *unused) | |||
1974 | struct intel_context *ce = &ctx->engine[engine->id]; | 1974 | struct intel_context *ce = &ctx->engine[engine->id]; |
1975 | 1975 | ||
1976 | seq_printf(m, "%s: ", engine->name); | 1976 | seq_printf(m, "%s: ", engine->name); |
1977 | seq_putc(m, ce->initialised ? 'I' : 'i'); | ||
1978 | if (ce->state) | 1977 | if (ce->state) |
1979 | describe_obj(m, ce->state->obj); | 1978 | describe_obj(m, ce->state->obj); |
1980 | if (ce->ring) | 1979 | if (ce->ring) |
@@ -2434,7 +2433,7 @@ static void i915_guc_log_info(struct seq_file *m, | |||
2434 | 2433 | ||
2435 | static void i915_guc_client_info(struct seq_file *m, | 2434 | static void i915_guc_client_info(struct seq_file *m, |
2436 | struct drm_i915_private *dev_priv, | 2435 | struct drm_i915_private *dev_priv, |
2437 | struct i915_guc_client *client) | 2436 | struct intel_guc_client *client) |
2438 | { | 2437 | { |
2439 | struct intel_engine_cs *engine; | 2438 | struct intel_engine_cs *engine; |
2440 | enum intel_engine_id id; | 2439 | enum intel_engine_id id; |
@@ -2484,6 +2483,8 @@ static int i915_guc_info(struct seq_file *m, void *data) | |||
2484 | 2483 | ||
2485 | seq_printf(m, "\nGuC execbuf client @ %p:\n", guc->execbuf_client); | 2484 | seq_printf(m, "\nGuC execbuf client @ %p:\n", guc->execbuf_client); |
2486 | i915_guc_client_info(m, dev_priv, guc->execbuf_client); | 2485 | i915_guc_client_info(m, dev_priv, guc->execbuf_client); |
2486 | seq_printf(m, "\nGuC preempt client @ %p:\n", guc->preempt_client); | ||
2487 | i915_guc_client_info(m, dev_priv, guc->preempt_client); | ||
2487 | 2488 | ||
2488 | i915_guc_log_info(m, dev_priv); | 2489 | i915_guc_log_info(m, dev_priv); |
2489 | 2490 | ||
@@ -2497,7 +2498,7 @@ static int i915_guc_stage_pool(struct seq_file *m, void *data) | |||
2497 | struct drm_i915_private *dev_priv = node_to_i915(m->private); | 2498 | struct drm_i915_private *dev_priv = node_to_i915(m->private); |
2498 | const struct intel_guc *guc = &dev_priv->guc; | 2499 | const struct intel_guc *guc = &dev_priv->guc; |
2499 | struct guc_stage_desc *desc = guc->stage_desc_pool_vaddr; | 2500 | struct guc_stage_desc *desc = guc->stage_desc_pool_vaddr; |
2500 | struct i915_guc_client *client = guc->execbuf_client; | 2501 | struct intel_guc_client *client = guc->execbuf_client; |
2501 | unsigned int tmp; | 2502 | unsigned int tmp; |
2502 | int index; | 2503 | int index; |
2503 | 2504 | ||
@@ -2734,39 +2735,76 @@ static int i915_sink_crc(struct seq_file *m, void *data) | |||
2734 | struct intel_connector *connector; | 2735 | struct intel_connector *connector; |
2735 | struct drm_connector_list_iter conn_iter; | 2736 | struct drm_connector_list_iter conn_iter; |
2736 | struct intel_dp *intel_dp = NULL; | 2737 | struct intel_dp *intel_dp = NULL; |
2738 | struct drm_modeset_acquire_ctx ctx; | ||
2737 | int ret; | 2739 | int ret; |
2738 | u8 crc[6]; | 2740 | u8 crc[6]; |
2739 | 2741 | ||
2740 | drm_modeset_lock_all(dev); | 2742 | drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); |
2743 | |||
2741 | drm_connector_list_iter_begin(dev, &conn_iter); | 2744 | drm_connector_list_iter_begin(dev, &conn_iter); |
2745 | |||
2742 | for_each_intel_connector_iter(connector, &conn_iter) { | 2746 | for_each_intel_connector_iter(connector, &conn_iter) { |
2743 | struct drm_crtc *crtc; | 2747 | struct drm_crtc *crtc; |
2748 | struct drm_connector_state *state; | ||
2749 | struct intel_crtc_state *crtc_state; | ||
2744 | 2750 | ||
2745 | if (!connector->base.state->best_encoder) | 2751 | if (connector->base.connector_type != DRM_MODE_CONNECTOR_eDP) |
2746 | continue; | 2752 | continue; |
2747 | 2753 | ||
2748 | crtc = connector->base.state->crtc; | 2754 | retry: |
2749 | if (!crtc->state->active) | 2755 | ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx); |
2756 | if (ret) | ||
2757 | goto err; | ||
2758 | |||
2759 | state = connector->base.state; | ||
2760 | if (!state->best_encoder) | ||
2750 | continue; | 2761 | continue; |
2751 | 2762 | ||
2752 | if (connector->base.connector_type != DRM_MODE_CONNECTOR_eDP) | 2763 | crtc = state->crtc; |
2764 | ret = drm_modeset_lock(&crtc->mutex, &ctx); | ||
2765 | if (ret) | ||
2766 | goto err; | ||
2767 | |||
2768 | crtc_state = to_intel_crtc_state(crtc->state); | ||
2769 | if (!crtc_state->base.active) | ||
2753 | continue; | 2770 | continue; |
2754 | 2771 | ||
2755 | intel_dp = enc_to_intel_dp(connector->base.state->best_encoder); | 2772 | /* |
2773 | * We need to wait for all crtc updates to complete, to make | ||
2774 | * sure any pending modesets and plane updates are completed. | ||
2775 | */ | ||
2776 | if (crtc_state->base.commit) { | ||
2777 | ret = wait_for_completion_interruptible(&crtc_state->base.commit->hw_done); | ||
2756 | 2778 | ||
2757 | ret = intel_dp_sink_crc(intel_dp, crc); | 2779 | if (ret) |
2780 | goto err; | ||
2781 | } | ||
2782 | |||
2783 | intel_dp = enc_to_intel_dp(state->best_encoder); | ||
2784 | |||
2785 | ret = intel_dp_sink_crc(intel_dp, crtc_state, crc); | ||
2758 | if (ret) | 2786 | if (ret) |
2759 | goto out; | 2787 | goto err; |
2760 | 2788 | ||
2761 | seq_printf(m, "%02x%02x%02x%02x%02x%02x\n", | 2789 | seq_printf(m, "%02x%02x%02x%02x%02x%02x\n", |
2762 | crc[0], crc[1], crc[2], | 2790 | crc[0], crc[1], crc[2], |
2763 | crc[3], crc[4], crc[5]); | 2791 | crc[3], crc[4], crc[5]); |
2764 | goto out; | 2792 | goto out; |
2793 | |||
2794 | err: | ||
2795 | if (ret == -EDEADLK) { | ||
2796 | ret = drm_modeset_backoff(&ctx); | ||
2797 | if (!ret) | ||
2798 | goto retry; | ||
2799 | } | ||
2800 | goto out; | ||
2765 | } | 2801 | } |
2766 | ret = -ENODEV; | 2802 | ret = -ENODEV; |
2767 | out: | 2803 | out: |
2768 | drm_connector_list_iter_end(&conn_iter); | 2804 | drm_connector_list_iter_end(&conn_iter); |
2769 | drm_modeset_unlock_all(dev); | 2805 | drm_modeset_drop_locks(&ctx); |
2806 | drm_modeset_acquire_fini(&ctx); | ||
2807 | |||
2770 | return ret; | 2808 | return ret; |
2771 | } | 2809 | } |
2772 | 2810 | ||
@@ -3049,7 +3087,7 @@ static void intel_connector_info(struct seq_file *m, | |||
3049 | break; | 3087 | break; |
3050 | case DRM_MODE_CONNECTOR_HDMIA: | 3088 | case DRM_MODE_CONNECTOR_HDMIA: |
3051 | if (intel_encoder->type == INTEL_OUTPUT_HDMI || | 3089 | if (intel_encoder->type == INTEL_OUTPUT_HDMI || |
3052 | intel_encoder->type == INTEL_OUTPUT_UNKNOWN) | 3090 | intel_encoder->type == INTEL_OUTPUT_DDI) |
3053 | intel_hdmi_info(m, intel_connector); | 3091 | intel_hdmi_info(m, intel_connector); |
3054 | break; | 3092 | break; |
3055 | default: | 3093 | default: |
@@ -3244,6 +3282,8 @@ static int i915_engine_info(struct seq_file *m, void *unused) | |||
3244 | yesno(dev_priv->gt.awake)); | 3282 | yesno(dev_priv->gt.awake)); |
3245 | seq_printf(m, "Global active requests: %d\n", | 3283 | seq_printf(m, "Global active requests: %d\n", |
3246 | dev_priv->gt.active_requests); | 3284 | dev_priv->gt.active_requests); |
3285 | seq_printf(m, "CS timestamp frequency: %u kHz\n", | ||
3286 | dev_priv->info.cs_timestamp_frequency_khz); | ||
3247 | 3287 | ||
3248 | p = drm_seq_file_printer(m); | 3288 | p = drm_seq_file_printer(m); |
3249 | for_each_engine(engine, dev_priv, id) | 3289 | for_each_engine(engine, dev_priv, id) |
@@ -3601,7 +3641,7 @@ static int i915_dp_mst_info(struct seq_file *m, void *unused) | |||
3601 | continue; | 3641 | continue; |
3602 | 3642 | ||
3603 | seq_printf(m, "MST Source Port %c\n", | 3643 | seq_printf(m, "MST Source Port %c\n", |
3604 | port_name(intel_dig_port->port)); | 3644 | port_name(intel_dig_port->base.port)); |
3605 | drm_dp_mst_dump_topology(m, &intel_dig_port->dp.mst_mgr); | 3645 | drm_dp_mst_dump_topology(m, &intel_dig_port->dp.mst_mgr); |
3606 | } | 3646 | } |
3607 | drm_connector_list_iter_end(&conn_iter); | 3647 | drm_connector_list_iter_end(&conn_iter); |
@@ -4448,6 +4488,61 @@ static void cherryview_sseu_device_status(struct drm_i915_private *dev_priv, | |||
4448 | } | 4488 | } |
4449 | } | 4489 | } |
4450 | 4490 | ||
4491 | static void gen10_sseu_device_status(struct drm_i915_private *dev_priv, | ||
4492 | struct sseu_dev_info *sseu) | ||
4493 | { | ||
4494 | const struct intel_device_info *info = INTEL_INFO(dev_priv); | ||
4495 | int s_max = 6, ss_max = 4; | ||
4496 | int s, ss; | ||
4497 | u32 s_reg[s_max], eu_reg[2 * s_max], eu_mask[2]; | ||
4498 | |||
4499 | for (s = 0; s < s_max; s++) { | ||
4500 | /* | ||
4501 | * FIXME: Valid SS Mask respects the spec and read | ||
4502 | * only valid bits for those registers, excluding reserverd | ||
4503 | * although this seems wrong because it would leave many | ||
4504 | * subslices without ACK. | ||
4505 | */ | ||
4506 | s_reg[s] = I915_READ(GEN10_SLICE_PGCTL_ACK(s)) & | ||
4507 | GEN10_PGCTL_VALID_SS_MASK(s); | ||
4508 | eu_reg[2 * s] = I915_READ(GEN10_SS01_EU_PGCTL_ACK(s)); | ||
4509 | eu_reg[2 * s + 1] = I915_READ(GEN10_SS23_EU_PGCTL_ACK(s)); | ||
4510 | } | ||
4511 | |||
4512 | eu_mask[0] = GEN9_PGCTL_SSA_EU08_ACK | | ||
4513 | GEN9_PGCTL_SSA_EU19_ACK | | ||
4514 | GEN9_PGCTL_SSA_EU210_ACK | | ||
4515 | GEN9_PGCTL_SSA_EU311_ACK; | ||
4516 | eu_mask[1] = GEN9_PGCTL_SSB_EU08_ACK | | ||
4517 | GEN9_PGCTL_SSB_EU19_ACK | | ||
4518 | GEN9_PGCTL_SSB_EU210_ACK | | ||
4519 | GEN9_PGCTL_SSB_EU311_ACK; | ||
4520 | |||
4521 | for (s = 0; s < s_max; s++) { | ||
4522 | if ((s_reg[s] & GEN9_PGCTL_SLICE_ACK) == 0) | ||
4523 | /* skip disabled slice */ | ||
4524 | continue; | ||
4525 | |||
4526 | sseu->slice_mask |= BIT(s); | ||
4527 | sseu->subslice_mask = info->sseu.subslice_mask; | ||
4528 | |||
4529 | for (ss = 0; ss < ss_max; ss++) { | ||
4530 | unsigned int eu_cnt; | ||
4531 | |||
4532 | if (!(s_reg[s] & (GEN9_PGCTL_SS_ACK(ss)))) | ||
4533 | /* skip disabled subslice */ | ||
4534 | continue; | ||
4535 | |||
4536 | eu_cnt = 2 * hweight32(eu_reg[2 * s + ss / 2] & | ||
4537 | eu_mask[ss % 2]); | ||
4538 | sseu->eu_total += eu_cnt; | ||
4539 | sseu->eu_per_subslice = max_t(unsigned int, | ||
4540 | sseu->eu_per_subslice, | ||
4541 | eu_cnt); | ||
4542 | } | ||
4543 | } | ||
4544 | } | ||
4545 | |||
4451 | static void gen9_sseu_device_status(struct drm_i915_private *dev_priv, | 4546 | static void gen9_sseu_device_status(struct drm_i915_private *dev_priv, |
4452 | struct sseu_dev_info *sseu) | 4547 | struct sseu_dev_info *sseu) |
4453 | { | 4548 | { |
@@ -4483,7 +4578,7 @@ static void gen9_sseu_device_status(struct drm_i915_private *dev_priv, | |||
4483 | 4578 | ||
4484 | sseu->slice_mask |= BIT(s); | 4579 | sseu->slice_mask |= BIT(s); |
4485 | 4580 | ||
4486 | if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) | 4581 | if (IS_GEN9_BC(dev_priv)) |
4487 | sseu->subslice_mask = | 4582 | sseu->subslice_mask = |
4488 | INTEL_INFO(dev_priv)->sseu.subslice_mask; | 4583 | INTEL_INFO(dev_priv)->sseu.subslice_mask; |
4489 | 4584 | ||
@@ -4589,8 +4684,10 @@ static int i915_sseu_status(struct seq_file *m, void *unused) | |||
4589 | cherryview_sseu_device_status(dev_priv, &sseu); | 4684 | cherryview_sseu_device_status(dev_priv, &sseu); |
4590 | } else if (IS_BROADWELL(dev_priv)) { | 4685 | } else if (IS_BROADWELL(dev_priv)) { |
4591 | broadwell_sseu_device_status(dev_priv, &sseu); | 4686 | broadwell_sseu_device_status(dev_priv, &sseu); |
4592 | } else if (INTEL_GEN(dev_priv) >= 9) { | 4687 | } else if (IS_GEN9(dev_priv)) { |
4593 | gen9_sseu_device_status(dev_priv, &sseu); | 4688 | gen9_sseu_device_status(dev_priv, &sseu); |
4689 | } else if (INTEL_GEN(dev_priv) >= 10) { | ||
4690 | gen10_sseu_device_status(dev_priv, &sseu); | ||
4594 | } | 4691 | } |
4595 | 4692 | ||
4596 | intel_runtime_pm_put(dev_priv); | 4693 | intel_runtime_pm_put(dev_priv); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2cf10d17acfb..5170a8ea83d4 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -372,9 +372,8 @@ static int i915_getparam(struct drm_device *dev, void *data, | |||
372 | value |= I915_SCHEDULER_CAP_ENABLED; | 372 | value |= I915_SCHEDULER_CAP_ENABLED; |
373 | value |= I915_SCHEDULER_CAP_PRIORITY; | 373 | value |= I915_SCHEDULER_CAP_PRIORITY; |
374 | 374 | ||
375 | if (INTEL_INFO(dev_priv)->has_logical_ring_preemption && | 375 | if (HAS_LOGICAL_RING_PREEMPTION(dev_priv) && |
376 | i915_modparams.enable_execlists && | 376 | i915_modparams.enable_execlists) |
377 | !i915_modparams.enable_guc_submission) | ||
378 | value |= I915_SCHEDULER_CAP_PREEMPTION; | 377 | value |= I915_SCHEDULER_CAP_PREEMPTION; |
379 | } | 378 | } |
380 | break; | 379 | break; |
@@ -407,6 +406,9 @@ static int i915_getparam(struct drm_device *dev, void *data, | |||
407 | */ | 406 | */ |
408 | value = 1; | 407 | value = 1; |
409 | break; | 408 | break; |
409 | case I915_PARAM_HAS_CONTEXT_ISOLATION: | ||
410 | value = intel_engines_has_context_isolation(dev_priv); | ||
411 | break; | ||
410 | case I915_PARAM_SLICE_MASK: | 412 | case I915_PARAM_SLICE_MASK: |
411 | value = INTEL_INFO(dev_priv)->sseu.slice_mask; | 413 | value = INTEL_INFO(dev_priv)->sseu.slice_mask; |
412 | if (!value) | 414 | if (!value) |
@@ -417,6 +419,9 @@ static int i915_getparam(struct drm_device *dev, void *data, | |||
417 | if (!value) | 419 | if (!value) |
418 | return -ENODEV; | 420 | return -ENODEV; |
419 | break; | 421 | break; |
422 | case I915_PARAM_CS_TIMESTAMP_FREQUENCY: | ||
423 | value = 1000 * INTEL_INFO(dev_priv)->cs_timestamp_frequency_khz; | ||
424 | break; | ||
420 | default: | 425 | default: |
421 | DRM_DEBUG("Unknown parameter %d\n", param->param); | 426 | DRM_DEBUG("Unknown parameter %d\n", param->param); |
422 | return -EINVAL; | 427 | return -EINVAL; |
@@ -677,7 +682,7 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
677 | if (ret) | 682 | if (ret) |
678 | goto cleanup_uc; | 683 | goto cleanup_uc; |
679 | 684 | ||
680 | intel_modeset_gem_init(dev); | 685 | intel_setup_overlay(dev_priv); |
681 | 686 | ||
682 | if (INTEL_INFO(dev_priv)->num_pipes == 0) | 687 | if (INTEL_INFO(dev_priv)->num_pipes == 0) |
683 | return 0; | 688 | return 0; |
@@ -838,6 +843,11 @@ static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv) | |||
838 | * We don't keep the workarounds for pre-production hardware, so we expect our | 843 | * We don't keep the workarounds for pre-production hardware, so we expect our |
839 | * driver to fail on these machines in one way or another. A little warning on | 844 | * driver to fail on these machines in one way or another. A little warning on |
840 | * dmesg may help both the user and the bug triagers. | 845 | * dmesg may help both the user and the bug triagers. |
846 | * | ||
847 | * Our policy for removing pre-production workarounds is to keep the | ||
848 | * current gen workarounds as a guide to the bring-up of the next gen | ||
849 | * (workarounds have a habit of persisting!). Anything older than that | ||
850 | * should be removed along with the complications they introduce. | ||
841 | */ | 851 | */ |
842 | static void intel_detect_preproduction_hw(struct drm_i915_private *dev_priv) | 852 | static void intel_detect_preproduction_hw(struct drm_i915_private *dev_priv) |
843 | { | 853 | { |
@@ -892,7 +902,6 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, | |||
892 | mutex_init(&dev_priv->backlight_lock); | 902 | mutex_init(&dev_priv->backlight_lock); |
893 | spin_lock_init(&dev_priv->uncore.lock); | 903 | spin_lock_init(&dev_priv->uncore.lock); |
894 | 904 | ||
895 | spin_lock_init(&dev_priv->mm.object_stat_lock); | ||
896 | mutex_init(&dev_priv->sb_lock); | 905 | mutex_init(&dev_priv->sb_lock); |
897 | mutex_init(&dev_priv->modeset_restore_lock); | 906 | mutex_init(&dev_priv->modeset_restore_lock); |
898 | mutex_init(&dev_priv->av_mutex); | 907 | mutex_init(&dev_priv->av_mutex); |
@@ -1682,8 +1691,6 @@ static int i915_drm_resume(struct drm_device *dev) | |||
1682 | 1691 | ||
1683 | intel_csr_ucode_resume(dev_priv); | 1692 | intel_csr_ucode_resume(dev_priv); |
1684 | 1693 | ||
1685 | i915_gem_resume(dev_priv); | ||
1686 | |||
1687 | i915_restore_state(dev_priv); | 1694 | i915_restore_state(dev_priv); |
1688 | intel_pps_unlock_regs_wa(dev_priv); | 1695 | intel_pps_unlock_regs_wa(dev_priv); |
1689 | intel_opregion_setup(dev_priv); | 1696 | intel_opregion_setup(dev_priv); |
@@ -1704,14 +1711,7 @@ static int i915_drm_resume(struct drm_device *dev) | |||
1704 | 1711 | ||
1705 | drm_mode_config_reset(dev); | 1712 | drm_mode_config_reset(dev); |
1706 | 1713 | ||
1707 | mutex_lock(&dev->struct_mutex); | 1714 | i915_gem_resume(dev_priv); |
1708 | if (i915_gem_init_hw(dev_priv)) { | ||
1709 | DRM_ERROR("failed to re-initialize GPU, declaring wedged!\n"); | ||
1710 | i915_gem_set_wedged(dev_priv); | ||
1711 | } | ||
1712 | mutex_unlock(&dev->struct_mutex); | ||
1713 | |||
1714 | intel_guc_resume(dev_priv); | ||
1715 | 1715 | ||
1716 | intel_modeset_init_hw(dev); | 1716 | intel_modeset_init_hw(dev); |
1717 | intel_init_clock_gating(dev_priv); | 1717 | intel_init_clock_gating(dev_priv); |
@@ -1745,8 +1745,6 @@ static int i915_drm_resume(struct drm_device *dev) | |||
1745 | 1745 | ||
1746 | intel_opregion_notify_adapter(dev_priv, PCI_D0); | 1746 | intel_opregion_notify_adapter(dev_priv, PCI_D0); |
1747 | 1747 | ||
1748 | intel_autoenable_gt_powersave(dev_priv); | ||
1749 | |||
1750 | enable_rpm_wakeref_asserts(dev_priv); | 1748 | enable_rpm_wakeref_asserts(dev_priv); |
1751 | 1749 | ||
1752 | return 0; | 1750 | return 0; |
@@ -1952,6 +1950,12 @@ error: | |||
1952 | goto finish; | 1950 | goto finish; |
1953 | } | 1951 | } |
1954 | 1952 | ||
1953 | static inline int intel_gt_reset_engine(struct drm_i915_private *dev_priv, | ||
1954 | struct intel_engine_cs *engine) | ||
1955 | { | ||
1956 | return intel_gpu_reset(dev_priv, intel_engine_flag(engine)); | ||
1957 | } | ||
1958 | |||
1955 | /** | 1959 | /** |
1956 | * i915_reset_engine - reset GPU engine to recover from a hang | 1960 | * i915_reset_engine - reset GPU engine to recover from a hang |
1957 | * @engine: engine to reset | 1961 | * @engine: engine to reset |
@@ -1986,10 +1990,14 @@ int i915_reset_engine(struct intel_engine_cs *engine, unsigned int flags) | |||
1986 | goto out; | 1990 | goto out; |
1987 | } | 1991 | } |
1988 | 1992 | ||
1989 | ret = intel_gpu_reset(engine->i915, intel_engine_flag(engine)); | 1993 | if (!engine->i915->guc.execbuf_client) |
1994 | ret = intel_gt_reset_engine(engine->i915, engine); | ||
1995 | else | ||
1996 | ret = intel_guc_reset_engine(&engine->i915->guc, engine); | ||
1990 | if (ret) { | 1997 | if (ret) { |
1991 | /* If we fail here, we expect to fallback to a global reset */ | 1998 | /* If we fail here, we expect to fallback to a global reset */ |
1992 | DRM_DEBUG_DRIVER("Failed to reset %s, ret=%d\n", | 1999 | DRM_DEBUG_DRIVER("%sFailed to reset %s, ret=%d\n", |
2000 | engine->i915->guc.execbuf_client ? "GuC " : "", | ||
1993 | engine->name, ret); | 2001 | engine->name, ret); |
1994 | goto out; | 2002 | goto out; |
1995 | } | 2003 | } |
@@ -2524,6 +2532,8 @@ static int intel_runtime_suspend(struct device *kdev) | |||
2524 | 2532 | ||
2525 | intel_runtime_pm_disable_interrupts(dev_priv); | 2533 | intel_runtime_pm_disable_interrupts(dev_priv); |
2526 | 2534 | ||
2535 | intel_uncore_suspend(dev_priv); | ||
2536 | |||
2527 | ret = 0; | 2537 | ret = 0; |
2528 | if (IS_GEN9_LP(dev_priv)) { | 2538 | if (IS_GEN9_LP(dev_priv)) { |
2529 | bxt_display_core_uninit(dev_priv); | 2539 | bxt_display_core_uninit(dev_priv); |
@@ -2536,6 +2546,8 @@ static int intel_runtime_suspend(struct device *kdev) | |||
2536 | 2546 | ||
2537 | if (ret) { | 2547 | if (ret) { |
2538 | DRM_ERROR("Runtime suspend failed, disabling it (%d)\n", ret); | 2548 | DRM_ERROR("Runtime suspend failed, disabling it (%d)\n", ret); |
2549 | intel_uncore_runtime_resume(dev_priv); | ||
2550 | |||
2539 | intel_runtime_pm_enable_interrupts(dev_priv); | 2551 | intel_runtime_pm_enable_interrupts(dev_priv); |
2540 | 2552 | ||
2541 | enable_rpm_wakeref_asserts(dev_priv); | 2553 | enable_rpm_wakeref_asserts(dev_priv); |
@@ -2543,8 +2555,6 @@ static int intel_runtime_suspend(struct device *kdev) | |||
2543 | return ret; | 2555 | return ret; |
2544 | } | 2556 | } |
2545 | 2557 | ||
2546 | intel_uncore_suspend(dev_priv); | ||
2547 | |||
2548 | enable_rpm_wakeref_asserts(dev_priv); | 2558 | enable_rpm_wakeref_asserts(dev_priv); |
2549 | WARN_ON_ONCE(atomic_read(&dev_priv->runtime_pm.wakeref_count)); | 2559 | WARN_ON_ONCE(atomic_read(&dev_priv->runtime_pm.wakeref_count)); |
2550 | 2560 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 54b5d4c582b6..36bb4927484a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -67,7 +67,6 @@ | |||
67 | #include "i915_gem_fence_reg.h" | 67 | #include "i915_gem_fence_reg.h" |
68 | #include "i915_gem_object.h" | 68 | #include "i915_gem_object.h" |
69 | #include "i915_gem_gtt.h" | 69 | #include "i915_gem_gtt.h" |
70 | #include "i915_gem_render_state.h" | ||
71 | #include "i915_gem_request.h" | 70 | #include "i915_gem_request.h" |
72 | #include "i915_gem_timeline.h" | 71 | #include "i915_gem_timeline.h" |
73 | 72 | ||
@@ -80,8 +79,8 @@ | |||
80 | 79 | ||
81 | #define DRIVER_NAME "i915" | 80 | #define DRIVER_NAME "i915" |
82 | #define DRIVER_DESC "Intel Graphics" | 81 | #define DRIVER_DESC "Intel Graphics" |
83 | #define DRIVER_DATE "20171023" | 82 | #define DRIVER_DATE "20171117" |
84 | #define DRIVER_TIMESTAMP 1508748913 | 83 | #define DRIVER_TIMESTAMP 1510958822 |
85 | 84 | ||
86 | /* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and | 85 | /* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and |
87 | * WARN_ON()) for hw state sanity checks to check for unexpected conditions | 86 | * WARN_ON()) for hw state sanity checks to check for unexpected conditions |
@@ -726,10 +725,12 @@ struct drm_i915_display_funcs { | |||
726 | void (*crtc_disable)(struct intel_crtc_state *old_crtc_state, | 725 | void (*crtc_disable)(struct intel_crtc_state *old_crtc_state, |
727 | struct drm_atomic_state *old_state); | 726 | struct drm_atomic_state *old_state); |
728 | void (*update_crtcs)(struct drm_atomic_state *state); | 727 | void (*update_crtcs)(struct drm_atomic_state *state); |
729 | void (*audio_codec_enable)(struct drm_connector *connector, | 728 | void (*audio_codec_enable)(struct intel_encoder *encoder, |
730 | struct intel_encoder *encoder, | 729 | const struct intel_crtc_state *crtc_state, |
731 | const struct drm_display_mode *adjusted_mode); | 730 | const struct drm_connector_state *conn_state); |
732 | void (*audio_codec_disable)(struct intel_encoder *encoder); | 731 | void (*audio_codec_disable)(struct intel_encoder *encoder, |
732 | const struct intel_crtc_state *old_crtc_state, | ||
733 | const struct drm_connector_state *old_conn_state); | ||
733 | void (*fdi_link_train)(struct intel_crtc *crtc, | 734 | void (*fdi_link_train)(struct intel_crtc *crtc, |
734 | const struct intel_crtc_state *crtc_state); | 735 | const struct intel_crtc_state *crtc_state); |
735 | void (*init_clock_gating)(struct drm_i915_private *dev_priv); | 736 | void (*init_clock_gating)(struct drm_i915_private *dev_priv); |
@@ -884,6 +885,8 @@ struct intel_device_info { | |||
884 | /* Slice/subslice/EU info */ | 885 | /* Slice/subslice/EU info */ |
885 | struct sseu_dev_info sseu; | 886 | struct sseu_dev_info sseu; |
886 | 887 | ||
888 | u32 cs_timestamp_frequency_khz; | ||
889 | |||
887 | struct color_luts { | 890 | struct color_luts { |
888 | u16 degamma_lut_size; | 891 | u16 degamma_lut_size; |
889 | u16 gamma_lut_size; | 892 | u16 gamma_lut_size; |
@@ -911,6 +914,12 @@ struct i915_gpu_state { | |||
911 | struct intel_device_info device_info; | 914 | struct intel_device_info device_info; |
912 | struct i915_params params; | 915 | struct i915_params params; |
913 | 916 | ||
917 | struct i915_error_uc { | ||
918 | struct intel_uc_fw guc_fw; | ||
919 | struct intel_uc_fw huc_fw; | ||
920 | struct drm_i915_error_object *guc_log; | ||
921 | } uc; | ||
922 | |||
914 | /* Generic register state */ | 923 | /* Generic register state */ |
915 | u32 eir; | 924 | u32 eir; |
916 | u32 pgtbl_er; | 925 | u32 pgtbl_er; |
@@ -934,7 +943,6 @@ struct i915_gpu_state { | |||
934 | struct intel_overlay_error_state *overlay; | 943 | struct intel_overlay_error_state *overlay; |
935 | struct intel_display_error_state *display; | 944 | struct intel_display_error_state *display; |
936 | struct drm_i915_error_object *semaphore; | 945 | struct drm_i915_error_object *semaphore; |
937 | struct drm_i915_error_object *guc_log; | ||
938 | 946 | ||
939 | struct drm_i915_error_engine { | 947 | struct drm_i915_error_engine { |
940 | int engine_id; | 948 | int engine_id; |
@@ -1386,7 +1394,6 @@ struct intel_gen6_power_mgmt { | |||
1386 | struct intel_rps rps; | 1394 | struct intel_rps rps; |
1387 | struct intel_rc6 rc6; | 1395 | struct intel_rc6 rc6; |
1388 | struct intel_llc_pstate llc_pstate; | 1396 | struct intel_llc_pstate llc_pstate; |
1389 | struct delayed_work autoenable_work; | ||
1390 | }; | 1397 | }; |
1391 | 1398 | ||
1392 | /* defined intel_pm.c */ | 1399 | /* defined intel_pm.c */ |
@@ -1698,6 +1705,8 @@ enum modeset_restore { | |||
1698 | #define DDC_PIN_D 0x06 | 1705 | #define DDC_PIN_D 0x06 |
1699 | 1706 | ||
1700 | struct ddi_vbt_port_info { | 1707 | struct ddi_vbt_port_info { |
1708 | int max_tmds_clock; | ||
1709 | |||
1701 | /* | 1710 | /* |
1702 | * This is an index in the HDMI/DVI DDI buffer translation table. | 1711 | * This is an index in the HDMI/DVI DDI buffer translation table. |
1703 | * The special value HDMI_LEVEL_SHIFT_UNKNOWN means the VBT didn't | 1712 | * The special value HDMI_LEVEL_SHIFT_UNKNOWN means the VBT didn't |
@@ -2228,6 +2237,7 @@ struct i915_oa_ops { | |||
2228 | 2237 | ||
2229 | struct intel_cdclk_state { | 2238 | struct intel_cdclk_state { |
2230 | unsigned int cdclk, vco, ref; | 2239 | unsigned int cdclk, vco, ref; |
2240 | u8 voltage_level; | ||
2231 | }; | 2241 | }; |
2232 | 2242 | ||
2233 | struct drm_i915_private { | 2243 | struct drm_i915_private { |
@@ -2339,6 +2349,7 @@ struct drm_i915_private { | |||
2339 | unsigned int max_dotclk_freq; | 2349 | unsigned int max_dotclk_freq; |
2340 | unsigned int rawclk_freq; | 2350 | unsigned int rawclk_freq; |
2341 | unsigned int hpll_freq; | 2351 | unsigned int hpll_freq; |
2352 | unsigned int fdi_pll_freq; | ||
2342 | unsigned int czclk_freq; | 2353 | unsigned int czclk_freq; |
2343 | 2354 | ||
2344 | struct { | 2355 | struct { |
@@ -2415,6 +2426,8 @@ struct drm_i915_private { | |||
2415 | unsigned int active_crtcs; | 2426 | unsigned int active_crtcs; |
2416 | /* minimum acceptable cdclk for each pipe */ | 2427 | /* minimum acceptable cdclk for each pipe */ |
2417 | int min_cdclk[I915_MAX_PIPES]; | 2428 | int min_cdclk[I915_MAX_PIPES]; |
2429 | /* minimum acceptable voltage level for each pipe */ | ||
2430 | u8 min_voltage_level[I915_MAX_PIPES]; | ||
2418 | 2431 | ||
2419 | int dpio_phy_iosf_port[I915_NUM_PHYS_VLV]; | 2432 | int dpio_phy_iosf_port[I915_NUM_PHYS_VLV]; |
2420 | 2433 | ||
@@ -3046,6 +3059,8 @@ intel_info(const struct drm_i915_private *dev_priv) | |||
3046 | (INTEL_DEVID(dev_priv) & 0x00F0) == 0x00A0) | 3059 | (INTEL_DEVID(dev_priv) & 0x00F0) == 0x00A0) |
3047 | #define IS_CFL_GT2(dev_priv) (IS_COFFEELAKE(dev_priv) && \ | 3060 | #define IS_CFL_GT2(dev_priv) (IS_COFFEELAKE(dev_priv) && \ |
3048 | (dev_priv)->info.gt == 2) | 3061 | (dev_priv)->info.gt == 2) |
3062 | #define IS_CFL_GT3(dev_priv) (IS_COFFEELAKE(dev_priv) && \ | ||
3063 | (dev_priv)->info.gt == 3) | ||
3049 | 3064 | ||
3050 | #define IS_ALPHA_SUPPORT(intel_info) ((intel_info)->is_alpha_support) | 3065 | #define IS_ALPHA_SUPPORT(intel_info) ((intel_info)->is_alpha_support) |
3051 | 3066 | ||
@@ -3137,6 +3152,8 @@ intel_info(const struct drm_i915_private *dev_priv) | |||
3137 | 3152 | ||
3138 | #define HAS_LOGICAL_RING_CONTEXTS(dev_priv) \ | 3153 | #define HAS_LOGICAL_RING_CONTEXTS(dev_priv) \ |
3139 | ((dev_priv)->info.has_logical_ring_contexts) | 3154 | ((dev_priv)->info.has_logical_ring_contexts) |
3155 | #define HAS_LOGICAL_RING_PREEMPTION(dev_priv) \ | ||
3156 | ((dev_priv)->info.has_logical_ring_preemption) | ||
3140 | #define USES_PPGTT(dev_priv) (i915_modparams.enable_ppgtt) | 3157 | #define USES_PPGTT(dev_priv) (i915_modparams.enable_ppgtt) |
3141 | #define USES_FULL_PPGTT(dev_priv) (i915_modparams.enable_ppgtt >= 2) | 3158 | #define USES_FULL_PPGTT(dev_priv) (i915_modparams.enable_ppgtt >= 2) |
3142 | #define USES_FULL_48BIT_PPGTT(dev_priv) (i915_modparams.enable_ppgtt == 3) | 3159 | #define USES_FULL_48BIT_PPGTT(dev_priv) (i915_modparams.enable_ppgtt == 3) |
@@ -3315,7 +3332,9 @@ extern int i915_reset_engine(struct intel_engine_cs *engine, | |||
3315 | unsigned int flags); | 3332 | unsigned int flags); |
3316 | 3333 | ||
3317 | extern bool intel_has_reset_engine(struct drm_i915_private *dev_priv); | 3334 | extern bool intel_has_reset_engine(struct drm_i915_private *dev_priv); |
3318 | extern int intel_guc_reset(struct drm_i915_private *dev_priv); | 3335 | extern int intel_reset_guc(struct drm_i915_private *dev_priv); |
3336 | extern int intel_guc_reset_engine(struct intel_guc *guc, | ||
3337 | struct intel_engine_cs *engine); | ||
3319 | extern void intel_engine_init_hangcheck(struct intel_engine_cs *engine); | 3338 | extern void intel_engine_init_hangcheck(struct intel_engine_cs *engine); |
3320 | extern void intel_hangcheck_init(struct drm_i915_private *dev_priv); | 3339 | extern void intel_hangcheck_init(struct drm_i915_private *dev_priv); |
3321 | extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv); | 3340 | extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv); |
@@ -4107,7 +4126,6 @@ void intel_device_info_dump(struct drm_i915_private *dev_priv); | |||
4107 | /* modesetting */ | 4126 | /* modesetting */ |
4108 | extern void intel_modeset_init_hw(struct drm_device *dev); | 4127 | extern void intel_modeset_init_hw(struct drm_device *dev); |
4109 | extern int intel_modeset_init(struct drm_device *dev); | 4128 | extern int intel_modeset_init(struct drm_device *dev); |
4110 | extern void intel_modeset_gem_init(struct drm_device *dev); | ||
4111 | extern void intel_modeset_cleanup(struct drm_device *dev); | 4129 | extern void intel_modeset_cleanup(struct drm_device *dev); |
4112 | extern int intel_connector_register(struct drm_connector *); | 4130 | extern int intel_connector_register(struct drm_connector *); |
4113 | extern void intel_connector_unregister(struct drm_connector *); | 4131 | extern void intel_connector_unregister(struct drm_connector *); |
@@ -4174,8 +4192,7 @@ bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv, | |||
4174 | enum dpio_phy phy); | 4192 | enum dpio_phy phy); |
4175 | bool bxt_ddi_phy_verify_state(struct drm_i915_private *dev_priv, | 4193 | bool bxt_ddi_phy_verify_state(struct drm_i915_private *dev_priv, |
4176 | enum dpio_phy phy); | 4194 | enum dpio_phy phy); |
4177 | uint8_t bxt_ddi_phy_calc_lane_lat_optim_mask(struct intel_encoder *encoder, | 4195 | uint8_t bxt_ddi_phy_calc_lane_lat_optim_mask(uint8_t lane_count); |
4178 | uint8_t lane_count); | ||
4179 | void bxt_ddi_phy_set_lane_optim_mask(struct intel_encoder *encoder, | 4196 | void bxt_ddi_phy_set_lane_optim_mask(struct intel_encoder *encoder, |
4180 | uint8_t lane_lat_optim_mask); | 4197 | uint8_t lane_lat_optim_mask); |
4181 | uint8_t bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder); | 4198 | uint8_t bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder); |
@@ -4184,18 +4201,25 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, | |||
4184 | u32 deemph_reg_value, u32 margin_reg_value, | 4201 | u32 deemph_reg_value, u32 margin_reg_value, |
4185 | bool uniq_trans_scale); | 4202 | bool uniq_trans_scale); |
4186 | void chv_data_lane_soft_reset(struct intel_encoder *encoder, | 4203 | void chv_data_lane_soft_reset(struct intel_encoder *encoder, |
4204 | const struct intel_crtc_state *crtc_state, | ||
4187 | bool reset); | 4205 | bool reset); |
4188 | void chv_phy_pre_pll_enable(struct intel_encoder *encoder); | 4206 | void chv_phy_pre_pll_enable(struct intel_encoder *encoder, |
4189 | void chv_phy_pre_encoder_enable(struct intel_encoder *encoder); | 4207 | const struct intel_crtc_state *crtc_state); |
4208 | void chv_phy_pre_encoder_enable(struct intel_encoder *encoder, | ||
4209 | const struct intel_crtc_state *crtc_state); | ||
4190 | void chv_phy_release_cl2_override(struct intel_encoder *encoder); | 4210 | void chv_phy_release_cl2_override(struct intel_encoder *encoder); |
4191 | void chv_phy_post_pll_disable(struct intel_encoder *encoder); | 4211 | void chv_phy_post_pll_disable(struct intel_encoder *encoder, |
4212 | const struct intel_crtc_state *old_crtc_state); | ||
4192 | 4213 | ||
4193 | void vlv_set_phy_signal_level(struct intel_encoder *encoder, | 4214 | void vlv_set_phy_signal_level(struct intel_encoder *encoder, |
4194 | u32 demph_reg_value, u32 preemph_reg_value, | 4215 | u32 demph_reg_value, u32 preemph_reg_value, |
4195 | u32 uniqtranscale_reg_value, u32 tx3_demph); | 4216 | u32 uniqtranscale_reg_value, u32 tx3_demph); |
4196 | void vlv_phy_pre_pll_enable(struct intel_encoder *encoder); | 4217 | void vlv_phy_pre_pll_enable(struct intel_encoder *encoder, |
4197 | void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder); | 4218 | const struct intel_crtc_state *crtc_state); |
4198 | void vlv_phy_reset_lanes(struct intel_encoder *encoder); | 4219 | void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder, |
4220 | const struct intel_crtc_state *crtc_state); | ||
4221 | void vlv_phy_reset_lanes(struct intel_encoder *encoder, | ||
4222 | const struct intel_crtc_state *old_crtc_state); | ||
4199 | 4223 | ||
4200 | int intel_gpu_freq(struct drm_i915_private *dev_priv, int val); | 4224 | int intel_gpu_freq(struct drm_i915_private *dev_priv, int val); |
4201 | int intel_freq_opcode(struct drm_i915_private *dev_priv, int val); | 4225 | int intel_freq_opcode(struct drm_i915_private *dev_priv, int val); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3a140eedfc83..61ba321e9970 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -538,7 +538,7 @@ i915_gem_object_wait_priority(struct drm_i915_gem_object *obj, | |||
538 | * @obj: i915 gem object | 538 | * @obj: i915 gem object |
539 | * @flags: how to wait (under a lock, for all rendering or just for writes etc) | 539 | * @flags: how to wait (under a lock, for all rendering or just for writes etc) |
540 | * @timeout: how long to wait | 540 | * @timeout: how long to wait |
541 | * @rps: client (user process) to charge for any waitboosting | 541 | * @rps_client: client (user process) to charge for any waitboosting |
542 | */ | 542 | */ |
543 | int | 543 | int |
544 | i915_gem_object_wait(struct drm_i915_gem_object *obj, | 544 | i915_gem_object_wait(struct drm_i915_gem_object *obj, |
@@ -1619,7 +1619,19 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
1619 | if (err) | 1619 | if (err) |
1620 | goto out; | 1620 | goto out; |
1621 | 1621 | ||
1622 | /* Flush and acquire obj->pages so that we are coherent through | 1622 | /* |
1623 | * Proxy objects do not control access to the backing storage, ergo | ||
1624 | * they cannot be used as a means to manipulate the cache domain | ||
1625 | * tracking for that backing storage. The proxy object is always | ||
1626 | * considered to be outside of any cache domain. | ||
1627 | */ | ||
1628 | if (i915_gem_object_is_proxy(obj)) { | ||
1629 | err = -ENXIO; | ||
1630 | goto out; | ||
1631 | } | ||
1632 | |||
1633 | /* | ||
1634 | * Flush and acquire obj->pages so that we are coherent through | ||
1623 | * direct access in memory with previous cached writes through | 1635 | * direct access in memory with previous cached writes through |
1624 | * shmemfs and that our cache domain tracking remains valid. | 1636 | * shmemfs and that our cache domain tracking remains valid. |
1625 | * For example, if the obj->filp was moved to swap without us | 1637 | * For example, if the obj->filp was moved to swap without us |
@@ -1675,6 +1687,11 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, | |||
1675 | if (!obj) | 1687 | if (!obj) |
1676 | return -ENOENT; | 1688 | return -ENOENT; |
1677 | 1689 | ||
1690 | /* | ||
1691 | * Proxy objects are barred from CPU access, so there is no | ||
1692 | * need to ban sw_finish as it is a nop. | ||
1693 | */ | ||
1694 | |||
1678 | /* Pinned buffers may be scanout, so flush the cache */ | 1695 | /* Pinned buffers may be scanout, so flush the cache */ |
1679 | i915_gem_object_flush_if_display(obj); | 1696 | i915_gem_object_flush_if_display(obj); |
1680 | i915_gem_object_put(obj); | 1697 | i915_gem_object_put(obj); |
@@ -1725,7 +1742,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
1725 | */ | 1742 | */ |
1726 | if (!obj->base.filp) { | 1743 | if (!obj->base.filp) { |
1727 | i915_gem_object_put(obj); | 1744 | i915_gem_object_put(obj); |
1728 | return -EINVAL; | 1745 | return -ENXIO; |
1729 | } | 1746 | } |
1730 | 1747 | ||
1731 | addr = vm_mmap(obj->base.filp, 0, args->size, | 1748 | addr = vm_mmap(obj->base.filp, 0, args->size, |
@@ -2669,7 +2686,8 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, | |||
2669 | void *ptr; | 2686 | void *ptr; |
2670 | int ret; | 2687 | int ret; |
2671 | 2688 | ||
2672 | GEM_BUG_ON(!i915_gem_object_has_struct_page(obj)); | 2689 | if (unlikely(!i915_gem_object_has_struct_page(obj))) |
2690 | return ERR_PTR(-ENXIO); | ||
2673 | 2691 | ||
2674 | ret = mutex_lock_interruptible(&obj->mm.lock); | 2692 | ret = mutex_lock_interruptible(&obj->mm.lock); |
2675 | if (ret) | 2693 | if (ret) |
@@ -2915,13 +2933,23 @@ i915_gem_reset_prepare_engine(struct intel_engine_cs *engine) | |||
2915 | * Prevent request submission to the hardware until we have | 2933 | * Prevent request submission to the hardware until we have |
2916 | * completed the reset in i915_gem_reset_finish(). If a request | 2934 | * completed the reset in i915_gem_reset_finish(). If a request |
2917 | * is completed by one engine, it may then queue a request | 2935 | * is completed by one engine, it may then queue a request |
2918 | * to a second via its engine->irq_tasklet *just* as we are | 2936 | * to a second via its execlists->tasklet *just* as we are |
2919 | * calling engine->init_hw() and also writing the ELSP. | 2937 | * calling engine->init_hw() and also writing the ELSP. |
2920 | * Turning off the engine->irq_tasklet until the reset is over | 2938 | * Turning off the execlists->tasklet until the reset is over |
2921 | * prevents the race. | 2939 | * prevents the race. |
2922 | */ | 2940 | */ |
2923 | tasklet_kill(&engine->execlists.irq_tasklet); | 2941 | tasklet_kill(&engine->execlists.tasklet); |
2924 | tasklet_disable(&engine->execlists.irq_tasklet); | 2942 | tasklet_disable(&engine->execlists.tasklet); |
2943 | |||
2944 | /* | ||
2945 | * We're using worker to queue preemption requests from the tasklet in | ||
2946 | * GuC submission mode. | ||
2947 | * Even though tasklet was disabled, we may still have a worker queued. | ||
2948 | * Let's make sure that all workers scheduled before disabling the | ||
2949 | * tasklet are completed before continuing with the reset. | ||
2950 | */ | ||
2951 | if (engine->i915->guc.preempt_wq) | ||
2952 | flush_workqueue(engine->i915->guc.preempt_wq); | ||
2925 | 2953 | ||
2926 | if (engine->irq_seqno_barrier) | 2954 | if (engine->irq_seqno_barrier) |
2927 | engine->irq_seqno_barrier(engine); | 2955 | engine->irq_seqno_barrier(engine); |
@@ -3100,7 +3128,7 @@ void i915_gem_reset(struct drm_i915_private *dev_priv) | |||
3100 | 3128 | ||
3101 | void i915_gem_reset_finish_engine(struct intel_engine_cs *engine) | 3129 | void i915_gem_reset_finish_engine(struct intel_engine_cs *engine) |
3102 | { | 3130 | { |
3103 | tasklet_enable(&engine->execlists.irq_tasklet); | 3131 | tasklet_enable(&engine->execlists.tasklet); |
3104 | kthread_unpark(engine->breadcrumbs.signaler); | 3132 | kthread_unpark(engine->breadcrumbs.signaler); |
3105 | 3133 | ||
3106 | intel_uncore_forcewake_put(engine->i915, FORCEWAKE_ALL); | 3134 | intel_uncore_forcewake_put(engine->i915, FORCEWAKE_ALL); |
@@ -3278,13 +3306,20 @@ i915_gem_retire_work_handler(struct work_struct *work) | |||
3278 | } | 3306 | } |
3279 | } | 3307 | } |
3280 | 3308 | ||
3309 | static inline bool | ||
3310 | new_requests_since_last_retire(const struct drm_i915_private *i915) | ||
3311 | { | ||
3312 | return (READ_ONCE(i915->gt.active_requests) || | ||
3313 | work_pending(&i915->gt.idle_work.work)); | ||
3314 | } | ||
3315 | |||
3281 | static void | 3316 | static void |
3282 | i915_gem_idle_work_handler(struct work_struct *work) | 3317 | i915_gem_idle_work_handler(struct work_struct *work) |
3283 | { | 3318 | { |
3284 | struct drm_i915_private *dev_priv = | 3319 | struct drm_i915_private *dev_priv = |
3285 | container_of(work, typeof(*dev_priv), gt.idle_work.work); | 3320 | container_of(work, typeof(*dev_priv), gt.idle_work.work); |
3286 | struct drm_device *dev = &dev_priv->drm; | ||
3287 | bool rearm_hangcheck; | 3321 | bool rearm_hangcheck; |
3322 | ktime_t end; | ||
3288 | 3323 | ||
3289 | if (!READ_ONCE(dev_priv->gt.awake)) | 3324 | if (!READ_ONCE(dev_priv->gt.awake)) |
3290 | return; | 3325 | return; |
@@ -3293,14 +3328,21 @@ i915_gem_idle_work_handler(struct work_struct *work) | |||
3293 | * Wait for last execlists context complete, but bail out in case a | 3328 | * Wait for last execlists context complete, but bail out in case a |
3294 | * new request is submitted. | 3329 | * new request is submitted. |
3295 | */ | 3330 | */ |
3296 | wait_for(intel_engines_are_idle(dev_priv), 10); | 3331 | end = ktime_add_ms(ktime_get(), 200); |
3297 | if (READ_ONCE(dev_priv->gt.active_requests)) | 3332 | do { |
3298 | return; | 3333 | if (new_requests_since_last_retire(dev_priv)) |
3334 | return; | ||
3335 | |||
3336 | if (intel_engines_are_idle(dev_priv)) | ||
3337 | break; | ||
3338 | |||
3339 | usleep_range(100, 500); | ||
3340 | } while (ktime_before(ktime_get(), end)); | ||
3299 | 3341 | ||
3300 | rearm_hangcheck = | 3342 | rearm_hangcheck = |
3301 | cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); | 3343 | cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); |
3302 | 3344 | ||
3303 | if (!mutex_trylock(&dev->struct_mutex)) { | 3345 | if (!mutex_trylock(&dev_priv->drm.struct_mutex)) { |
3304 | /* Currently busy, come back later */ | 3346 | /* Currently busy, come back later */ |
3305 | mod_delayed_work(dev_priv->wq, | 3347 | mod_delayed_work(dev_priv->wq, |
3306 | &dev_priv->gt.idle_work, | 3348 | &dev_priv->gt.idle_work, |
@@ -3312,16 +3354,23 @@ i915_gem_idle_work_handler(struct work_struct *work) | |||
3312 | * New request retired after this work handler started, extend active | 3354 | * New request retired after this work handler started, extend active |
3313 | * period until next instance of the work. | 3355 | * period until next instance of the work. |
3314 | */ | 3356 | */ |
3315 | if (work_pending(work)) | 3357 | if (new_requests_since_last_retire(dev_priv)) |
3316 | goto out_unlock; | ||
3317 | |||
3318 | if (dev_priv->gt.active_requests) | ||
3319 | goto out_unlock; | 3358 | goto out_unlock; |
3320 | 3359 | ||
3321 | if (wait_for(intel_engines_are_idle(dev_priv), 10)) | 3360 | /* |
3322 | DRM_ERROR("Timeout waiting for engines to idle\n"); | 3361 | * Be paranoid and flush a concurrent interrupt to make sure |
3362 | * we don't reactivate any irq tasklets after parking. | ||
3363 | * | ||
3364 | * FIXME: Note that even though we have waited for execlists to be idle, | ||
3365 | * there may still be an in-flight interrupt even though the CSB | ||
3366 | * is now empty. synchronize_irq() makes sure that a residual interrupt | ||
3367 | * is completed before we continue, but it doesn't prevent the HW from | ||
3368 | * raising a spurious interrupt later. To complete the shield we should | ||
3369 | * coordinate disabling the CS irq with flushing the interrupts. | ||
3370 | */ | ||
3371 | synchronize_irq(dev_priv->drm.irq); | ||
3323 | 3372 | ||
3324 | intel_engines_mark_idle(dev_priv); | 3373 | intel_engines_park(dev_priv); |
3325 | i915_gem_timelines_mark_idle(dev_priv); | 3374 | i915_gem_timelines_mark_idle(dev_priv); |
3326 | 3375 | ||
3327 | GEM_BUG_ON(!dev_priv->gt.awake); | 3376 | GEM_BUG_ON(!dev_priv->gt.awake); |
@@ -3332,7 +3381,7 @@ i915_gem_idle_work_handler(struct work_struct *work) | |||
3332 | gen6_rps_idle(dev_priv); | 3381 | gen6_rps_idle(dev_priv); |
3333 | intel_runtime_pm_put(dev_priv); | 3382 | intel_runtime_pm_put(dev_priv); |
3334 | out_unlock: | 3383 | out_unlock: |
3335 | mutex_unlock(&dev->struct_mutex); | 3384 | mutex_unlock(&dev_priv->drm.struct_mutex); |
3336 | 3385 | ||
3337 | out_rearm: | 3386 | out_rearm: |
3338 | if (rearm_hangcheck) { | 3387 | if (rearm_hangcheck) { |
@@ -3857,6 +3906,15 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data, | |||
3857 | if (!obj) | 3906 | if (!obj) |
3858 | return -ENOENT; | 3907 | return -ENOENT; |
3859 | 3908 | ||
3909 | /* | ||
3910 | * The caching mode of proxy object is handled by its generator, and | ||
3911 | * not allowed to be changed by userspace. | ||
3912 | */ | ||
3913 | if (i915_gem_object_is_proxy(obj)) { | ||
3914 | ret = -ENXIO; | ||
3915 | goto out; | ||
3916 | } | ||
3917 | |||
3860 | if (obj->cache_level == level) | 3918 | if (obj->cache_level == level) |
3861 | goto out; | 3919 | goto out; |
3862 | 3920 | ||
@@ -4662,14 +4720,16 @@ void __i915_gem_object_release_unless_active(struct drm_i915_gem_object *obj) | |||
4662 | i915_gem_object_put(obj); | 4720 | i915_gem_object_put(obj); |
4663 | } | 4721 | } |
4664 | 4722 | ||
4665 | static void assert_kernel_context_is_current(struct drm_i915_private *dev_priv) | 4723 | static void assert_kernel_context_is_current(struct drm_i915_private *i915) |
4666 | { | 4724 | { |
4725 | struct i915_gem_context *kernel_context = i915->kernel_context; | ||
4667 | struct intel_engine_cs *engine; | 4726 | struct intel_engine_cs *engine; |
4668 | enum intel_engine_id id; | 4727 | enum intel_engine_id id; |
4669 | 4728 | ||
4670 | for_each_engine(engine, dev_priv, id) | 4729 | for_each_engine(engine, i915, id) { |
4671 | GEM_BUG_ON(engine->last_retired_context && | 4730 | GEM_BUG_ON(__i915_gem_active_peek(&engine->timeline->last_request)); |
4672 | !i915_gem_context_is_kernel(engine->last_retired_context)); | 4731 | GEM_BUG_ON(engine->last_retired_context != kernel_context); |
4732 | } | ||
4673 | } | 4733 | } |
4674 | 4734 | ||
4675 | void i915_gem_sanitize(struct drm_i915_private *i915) | 4735 | void i915_gem_sanitize(struct drm_i915_private *i915) |
@@ -4773,23 +4833,40 @@ err_unlock: | |||
4773 | return ret; | 4833 | return ret; |
4774 | } | 4834 | } |
4775 | 4835 | ||
4776 | void i915_gem_resume(struct drm_i915_private *dev_priv) | 4836 | void i915_gem_resume(struct drm_i915_private *i915) |
4777 | { | 4837 | { |
4778 | struct drm_device *dev = &dev_priv->drm; | 4838 | WARN_ON(i915->gt.awake); |
4779 | 4839 | ||
4780 | WARN_ON(dev_priv->gt.awake); | 4840 | mutex_lock(&i915->drm.struct_mutex); |
4841 | intel_uncore_forcewake_get(i915, FORCEWAKE_ALL); | ||
4781 | 4842 | ||
4782 | mutex_lock(&dev->struct_mutex); | 4843 | i915_gem_restore_gtt_mappings(i915); |
4783 | i915_gem_restore_gtt_mappings(dev_priv); | 4844 | i915_gem_restore_fences(i915); |
4784 | i915_gem_restore_fences(dev_priv); | ||
4785 | 4845 | ||
4786 | /* As we didn't flush the kernel context before suspend, we cannot | 4846 | /* As we didn't flush the kernel context before suspend, we cannot |
4787 | * guarantee that the context image is complete. So let's just reset | 4847 | * guarantee that the context image is complete. So let's just reset |
4788 | * it and start again. | 4848 | * it and start again. |
4789 | */ | 4849 | */ |
4790 | dev_priv->gt.resume(dev_priv); | 4850 | i915->gt.resume(i915); |
4791 | 4851 | ||
4792 | mutex_unlock(&dev->struct_mutex); | 4852 | if (i915_gem_init_hw(i915)) |
4853 | goto err_wedged; | ||
4854 | |||
4855 | intel_guc_resume(i915); | ||
4856 | |||
4857 | /* Always reload a context for powersaving. */ | ||
4858 | if (i915_gem_switch_to_kernel_context(i915)) | ||
4859 | goto err_wedged; | ||
4860 | |||
4861 | out_unlock: | ||
4862 | intel_uncore_forcewake_put(i915, FORCEWAKE_ALL); | ||
4863 | mutex_unlock(&i915->drm.struct_mutex); | ||
4864 | return; | ||
4865 | |||
4866 | err_wedged: | ||
4867 | DRM_ERROR("failed to re-initialize GPU, declaring wedged!\n"); | ||
4868 | i915_gem_set_wedged(i915); | ||
4869 | goto out_unlock; | ||
4793 | } | 4870 | } |
4794 | 4871 | ||
4795 | void i915_gem_init_swizzling(struct drm_i915_private *dev_priv) | 4872 | void i915_gem_init_swizzling(struct drm_i915_private *dev_priv) |
@@ -4906,18 +4983,15 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv) | |||
4906 | goto out; | 4983 | goto out; |
4907 | } | 4984 | } |
4908 | 4985 | ||
4909 | /* Need to do basic initialisation of all rings first: */ | ||
4910 | ret = __i915_gem_restart_engines(dev_priv); | ||
4911 | if (ret) | ||
4912 | goto out; | ||
4913 | |||
4914 | intel_mocs_init_l3cc_table(dev_priv); | ||
4915 | |||
4916 | /* We can't enable contexts until all firmware is loaded */ | 4986 | /* We can't enable contexts until all firmware is loaded */ |
4917 | ret = intel_uc_init_hw(dev_priv); | 4987 | ret = intel_uc_init_hw(dev_priv); |
4918 | if (ret) | 4988 | if (ret) |
4919 | goto out; | 4989 | goto out; |
4920 | 4990 | ||
4991 | intel_mocs_init_l3cc_table(dev_priv); | ||
4992 | |||
4993 | /* Only when the HW is re-initialised, can we replay the requests */ | ||
4994 | ret = __i915_gem_restart_engines(dev_priv); | ||
4921 | out: | 4995 | out: |
4922 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); | 4996 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
4923 | return ret; | 4997 | return ret; |
@@ -4942,6 +5016,120 @@ bool intel_sanitize_semaphores(struct drm_i915_private *dev_priv, int value) | |||
4942 | return true; | 5016 | return true; |
4943 | } | 5017 | } |
4944 | 5018 | ||
5019 | static int __intel_engines_record_defaults(struct drm_i915_private *i915) | ||
5020 | { | ||
5021 | struct i915_gem_context *ctx; | ||
5022 | struct intel_engine_cs *engine; | ||
5023 | enum intel_engine_id id; | ||
5024 | int err; | ||
5025 | |||
5026 | /* | ||
5027 | * As we reset the gpu during very early sanitisation, the current | ||
5028 | * register state on the GPU should reflect its defaults values. | ||
5029 | * We load a context onto the hw (with restore-inhibit), then switch | ||
5030 | * over to a second context to save that default register state. We | ||
5031 | * can then prime every new context with that state so they all start | ||
5032 | * from the same default HW values. | ||
5033 | */ | ||
5034 | |||
5035 | ctx = i915_gem_context_create_kernel(i915, 0); | ||
5036 | if (IS_ERR(ctx)) | ||
5037 | return PTR_ERR(ctx); | ||
5038 | |||
5039 | for_each_engine(engine, i915, id) { | ||
5040 | struct drm_i915_gem_request *rq; | ||
5041 | |||
5042 | rq = i915_gem_request_alloc(engine, ctx); | ||
5043 | if (IS_ERR(rq)) { | ||
5044 | err = PTR_ERR(rq); | ||
5045 | goto out_ctx; | ||
5046 | } | ||
5047 | |||
5048 | err = i915_switch_context(rq); | ||
5049 | if (engine->init_context) | ||
5050 | err = engine->init_context(rq); | ||
5051 | |||
5052 | __i915_add_request(rq, true); | ||
5053 | if (err) | ||
5054 | goto err_active; | ||
5055 | } | ||
5056 | |||
5057 | err = i915_gem_switch_to_kernel_context(i915); | ||
5058 | if (err) | ||
5059 | goto err_active; | ||
5060 | |||
5061 | err = i915_gem_wait_for_idle(i915, I915_WAIT_LOCKED); | ||
5062 | if (err) | ||
5063 | goto err_active; | ||
5064 | |||
5065 | assert_kernel_context_is_current(i915); | ||
5066 | |||
5067 | for_each_engine(engine, i915, id) { | ||
5068 | struct i915_vma *state; | ||
5069 | |||
5070 | state = ctx->engine[id].state; | ||
5071 | if (!state) | ||
5072 | continue; | ||
5073 | |||
5074 | /* | ||
5075 | * As we will hold a reference to the logical state, it will | ||
5076 | * not be torn down with the context, and importantly the | ||
5077 | * object will hold onto its vma (making it possible for a | ||
5078 | * stray GTT write to corrupt our defaults). Unmap the vma | ||
5079 | * from the GTT to prevent such accidents and reclaim the | ||
5080 | * space. | ||
5081 | */ | ||
5082 | err = i915_vma_unbind(state); | ||
5083 | if (err) | ||
5084 | goto err_active; | ||
5085 | |||
5086 | err = i915_gem_object_set_to_cpu_domain(state->obj, false); | ||
5087 | if (err) | ||
5088 | goto err_active; | ||
5089 | |||
5090 | engine->default_state = i915_gem_object_get(state->obj); | ||
5091 | } | ||
5092 | |||
5093 | if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) { | ||
5094 | unsigned int found = intel_engines_has_context_isolation(i915); | ||
5095 | |||
5096 | /* | ||
5097 | * Make sure that classes with multiple engine instances all | ||
5098 | * share the same basic configuration. | ||
5099 | */ | ||
5100 | for_each_engine(engine, i915, id) { | ||
5101 | unsigned int bit = BIT(engine->uabi_class); | ||
5102 | unsigned int expected = engine->default_state ? bit : 0; | ||
5103 | |||
5104 | if ((found & bit) != expected) { | ||
5105 | DRM_ERROR("mismatching default context state for class %d on engine %s\n", | ||
5106 | engine->uabi_class, engine->name); | ||
5107 | } | ||
5108 | } | ||
5109 | } | ||
5110 | |||
5111 | out_ctx: | ||
5112 | i915_gem_context_set_closed(ctx); | ||
5113 | i915_gem_context_put(ctx); | ||
5114 | return err; | ||
5115 | |||
5116 | err_active: | ||
5117 | /* | ||
5118 | * If we have to abandon now, we expect the engines to be idle | ||
5119 | * and ready to be torn-down. First try to flush any remaining | ||
5120 | * request, ensure we are pointing at the kernel context and | ||
5121 | * then remove it. | ||
5122 | */ | ||
5123 | if (WARN_ON(i915_gem_switch_to_kernel_context(i915))) | ||
5124 | goto out_ctx; | ||
5125 | |||
5126 | if (WARN_ON(i915_gem_wait_for_idle(i915, I915_WAIT_LOCKED))) | ||
5127 | goto out_ctx; | ||
5128 | |||
5129 | i915_gem_contexts_lost(i915); | ||
5130 | goto out_ctx; | ||
5131 | } | ||
5132 | |||
4945 | int i915_gem_init(struct drm_i915_private *dev_priv) | 5133 | int i915_gem_init(struct drm_i915_private *dev_priv) |
4946 | { | 5134 | { |
4947 | int ret; | 5135 | int ret; |
@@ -4991,7 +5179,25 @@ int i915_gem_init(struct drm_i915_private *dev_priv) | |||
4991 | if (ret) | 5179 | if (ret) |
4992 | goto out_unlock; | 5180 | goto out_unlock; |
4993 | 5181 | ||
5182 | intel_init_gt_powersave(dev_priv); | ||
5183 | |||
4994 | ret = i915_gem_init_hw(dev_priv); | 5184 | ret = i915_gem_init_hw(dev_priv); |
5185 | if (ret) | ||
5186 | goto out_unlock; | ||
5187 | |||
5188 | /* | ||
5189 | * Despite its name intel_init_clock_gating applies both display | ||
5190 | * clock gating workarounds; GT mmio workarounds and the occasional | ||
5191 | * GT power context workaround. Worse, sometimes it includes a context | ||
5192 | * register workaround which we need to apply before we record the | ||
5193 | * default HW state for all contexts. | ||
5194 | * | ||
5195 | * FIXME: break up the workarounds and apply them at the right time! | ||
5196 | */ | ||
5197 | intel_init_clock_gating(dev_priv); | ||
5198 | |||
5199 | ret = __intel_engines_record_defaults(dev_priv); | ||
5200 | out_unlock: | ||
4995 | if (ret == -EIO) { | 5201 | if (ret == -EIO) { |
4996 | /* Allow engine initialisation to fail by marking the GPU as | 5202 | /* Allow engine initialisation to fail by marking the GPU as |
4997 | * wedged. But we only want to do this where the GPU is angry, | 5203 | * wedged. But we only want to do this where the GPU is angry, |
@@ -5003,8 +5209,6 @@ int i915_gem_init(struct drm_i915_private *dev_priv) | |||
5003 | } | 5209 | } |
5004 | ret = 0; | 5210 | ret = 0; |
5005 | } | 5211 | } |
5006 | |||
5007 | out_unlock: | ||
5008 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); | 5212 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
5009 | mutex_unlock(&dev_priv->drm.struct_mutex); | 5213 | mutex_unlock(&dev_priv->drm.struct_mutex); |
5010 | 5214 | ||
@@ -5058,6 +5262,22 @@ i915_gem_load_init_fences(struct drm_i915_private *dev_priv) | |||
5058 | i915_gem_detect_bit_6_swizzle(dev_priv); | 5262 | i915_gem_detect_bit_6_swizzle(dev_priv); |
5059 | } | 5263 | } |
5060 | 5264 | ||
5265 | static void i915_gem_init__mm(struct drm_i915_private *i915) | ||
5266 | { | ||
5267 | spin_lock_init(&i915->mm.object_stat_lock); | ||
5268 | spin_lock_init(&i915->mm.obj_lock); | ||
5269 | spin_lock_init(&i915->mm.free_lock); | ||
5270 | |||
5271 | init_llist_head(&i915->mm.free_list); | ||
5272 | |||
5273 | INIT_LIST_HEAD(&i915->mm.unbound_list); | ||
5274 | INIT_LIST_HEAD(&i915->mm.bound_list); | ||
5275 | INIT_LIST_HEAD(&i915->mm.fence_list); | ||
5276 | INIT_LIST_HEAD(&i915->mm.userfault_list); | ||
5277 | |||
5278 | INIT_WORK(&i915->mm.free_work, __i915_gem_free_work); | ||
5279 | } | ||
5280 | |||
5061 | int | 5281 | int |
5062 | i915_gem_load_init(struct drm_i915_private *dev_priv) | 5282 | i915_gem_load_init(struct drm_i915_private *dev_priv) |
5063 | { | 5283 | { |
@@ -5099,15 +5319,7 @@ i915_gem_load_init(struct drm_i915_private *dev_priv) | |||
5099 | if (err) | 5319 | if (err) |
5100 | goto err_priorities; | 5320 | goto err_priorities; |
5101 | 5321 | ||
5102 | INIT_WORK(&dev_priv->mm.free_work, __i915_gem_free_work); | 5322 | i915_gem_init__mm(dev_priv); |
5103 | |||
5104 | spin_lock_init(&dev_priv->mm.obj_lock); | ||
5105 | spin_lock_init(&dev_priv->mm.free_lock); | ||
5106 | init_llist_head(&dev_priv->mm.free_list); | ||
5107 | INIT_LIST_HEAD(&dev_priv->mm.unbound_list); | ||
5108 | INIT_LIST_HEAD(&dev_priv->mm.bound_list); | ||
5109 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); | ||
5110 | INIT_LIST_HEAD(&dev_priv->mm.userfault_list); | ||
5111 | 5323 | ||
5112 | INIT_DELAYED_WORK(&dev_priv->gt.retire_work, | 5324 | INIT_DELAYED_WORK(&dev_priv->gt.retire_work, |
5113 | i915_gem_retire_work_handler); | 5325 | i915_gem_retire_work_handler); |
diff --git a/drivers/gpu/drm/i915/i915_gem.h b/drivers/gpu/drm/i915/i915_gem.h index ee54597465b6..e920dab7f1b8 100644 --- a/drivers/gpu/drm/i915/i915_gem.h +++ b/drivers/gpu/drm/i915/i915_gem.h | |||
@@ -28,7 +28,11 @@ | |||
28 | #include <linux/bug.h> | 28 | #include <linux/bug.h> |
29 | 29 | ||
30 | #ifdef CONFIG_DRM_I915_DEBUG_GEM | 30 | #ifdef CONFIG_DRM_I915_DEBUG_GEM |
31 | #define GEM_BUG_ON(expr) BUG_ON(expr) | 31 | #define GEM_BUG_ON(condition) do { if (unlikely((condition))) { \ |
32 | printk(KERN_ERR "GEM_BUG_ON(%s)\n", __stringify(condition)); \ | ||
33 | BUG(); \ | ||
34 | } \ | ||
35 | } while(0) | ||
32 | #define GEM_WARN_ON(expr) WARN_ON(expr) | 36 | #define GEM_WARN_ON(expr) WARN_ON(expr) |
33 | 37 | ||
34 | #define GEM_DEBUG_DECL(var) var | 38 | #define GEM_DEBUG_DECL(var) var |
@@ -44,6 +48,12 @@ | |||
44 | #define GEM_DEBUG_BUG_ON(expr) | 48 | #define GEM_DEBUG_BUG_ON(expr) |
45 | #endif | 49 | #endif |
46 | 50 | ||
51 | #if IS_ENABLED(CONFIG_DRM_I915_TRACE_GEM) | ||
52 | #define GEM_TRACE(...) trace_printk(__VA_ARGS__) | ||
53 | #else | ||
54 | #define GEM_TRACE(...) do { } while (0) | ||
55 | #endif | ||
56 | |||
47 | #define I915_NUM_ENGINES 5 | 57 | #define I915_NUM_ENGINES 5 |
48 | 58 | ||
49 | #endif /* __I915_GEM_H__ */ | 59 | #endif /* __I915_GEM_H__ */ |
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index f782cf2069c1..2db040695035 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
@@ -418,8 +418,8 @@ out: | |||
418 | return ctx; | 418 | return ctx; |
419 | } | 419 | } |
420 | 420 | ||
421 | static struct i915_gem_context * | 421 | struct i915_gem_context * |
422 | create_kernel_context(struct drm_i915_private *i915, int prio) | 422 | i915_gem_context_create_kernel(struct drm_i915_private *i915, int prio) |
423 | { | 423 | { |
424 | struct i915_gem_context *ctx; | 424 | struct i915_gem_context *ctx; |
425 | 425 | ||
@@ -473,7 +473,7 @@ int i915_gem_contexts_init(struct drm_i915_private *dev_priv) | |||
473 | ida_init(&dev_priv->contexts.hw_ida); | 473 | ida_init(&dev_priv->contexts.hw_ida); |
474 | 474 | ||
475 | /* lowest priority; idle task */ | 475 | /* lowest priority; idle task */ |
476 | ctx = create_kernel_context(dev_priv, I915_PRIORITY_MIN); | 476 | ctx = i915_gem_context_create_kernel(dev_priv, I915_PRIORITY_MIN); |
477 | if (IS_ERR(ctx)) { | 477 | if (IS_ERR(ctx)) { |
478 | DRM_ERROR("Failed to create default global context\n"); | 478 | DRM_ERROR("Failed to create default global context\n"); |
479 | err = PTR_ERR(ctx); | 479 | err = PTR_ERR(ctx); |
@@ -487,7 +487,7 @@ int i915_gem_contexts_init(struct drm_i915_private *dev_priv) | |||
487 | dev_priv->kernel_context = ctx; | 487 | dev_priv->kernel_context = ctx; |
488 | 488 | ||
489 | /* highest priority; preempting task */ | 489 | /* highest priority; preempting task */ |
490 | ctx = create_kernel_context(dev_priv, INT_MAX); | 490 | ctx = i915_gem_context_create_kernel(dev_priv, INT_MAX); |
491 | if (IS_ERR(ctx)) { | 491 | if (IS_ERR(ctx)) { |
492 | DRM_ERROR("Failed to create default preempt context\n"); | 492 | DRM_ERROR("Failed to create default preempt context\n"); |
493 | err = PTR_ERR(ctx); | 493 | err = PTR_ERR(ctx); |
@@ -522,28 +522,6 @@ void i915_gem_contexts_lost(struct drm_i915_private *dev_priv) | |||
522 | engine->context_unpin(engine, engine->last_retired_context); | 522 | engine->context_unpin(engine, engine->last_retired_context); |
523 | engine->last_retired_context = NULL; | 523 | engine->last_retired_context = NULL; |
524 | } | 524 | } |
525 | |||
526 | /* Force the GPU state to be restored on enabling */ | ||
527 | if (!i915_modparams.enable_execlists) { | ||
528 | struct i915_gem_context *ctx; | ||
529 | |||
530 | list_for_each_entry(ctx, &dev_priv->contexts.list, link) { | ||
531 | if (!i915_gem_context_is_default(ctx)) | ||
532 | continue; | ||
533 | |||
534 | for_each_engine(engine, dev_priv, id) | ||
535 | ctx->engine[engine->id].initialised = false; | ||
536 | |||
537 | ctx->remap_slice = ALL_L3_SLICES(dev_priv); | ||
538 | } | ||
539 | |||
540 | for_each_engine(engine, dev_priv, id) { | ||
541 | struct intel_context *kce = | ||
542 | &dev_priv->kernel_context->engine[engine->id]; | ||
543 | |||
544 | kce->initialised = true; | ||
545 | } | ||
546 | } | ||
547 | } | 525 | } |
548 | 526 | ||
549 | void i915_gem_contexts_fini(struct drm_i915_private *i915) | 527 | void i915_gem_contexts_fini(struct drm_i915_private *i915) |
@@ -718,9 +696,6 @@ static inline bool skip_rcs_switch(struct i915_hw_ppgtt *ppgtt, | |||
718 | if (to->remap_slice) | 696 | if (to->remap_slice) |
719 | return false; | 697 | return false; |
720 | 698 | ||
721 | if (!to->engine[RCS].initialised) | ||
722 | return false; | ||
723 | |||
724 | if (ppgtt && (intel_engine_flag(engine) & ppgtt->pd_dirty_rings)) | 699 | if (ppgtt && (intel_engine_flag(engine) & ppgtt->pd_dirty_rings)) |
725 | return false; | 700 | return false; |
726 | 701 | ||
@@ -795,11 +770,14 @@ static int do_rcs_switch(struct drm_i915_gem_request *req) | |||
795 | return ret; | 770 | return ret; |
796 | } | 771 | } |
797 | 772 | ||
798 | if (!to->engine[RCS].initialised || i915_gem_context_is_default(to)) | 773 | if (i915_gem_context_is_kernel(to)) |
799 | /* NB: If we inhibit the restore, the context is not allowed to | 774 | /* |
800 | * die because future work may end up depending on valid address | 775 | * The kernel context(s) is treated as pure scratch and is not |
801 | * space. This means we must enforce that a page table load | 776 | * expected to retain any state (as we sacrifice it during |
802 | * occur when this occurs. */ | 777 | * suspend and on resume it may be corrupted). This is ok, |
778 | * as nothing actually executes using the kernel context; it | ||
779 | * is purely used for flushing user contexts. | ||
780 | */ | ||
803 | hw_flags = MI_RESTORE_INHIBIT; | 781 | hw_flags = MI_RESTORE_INHIBIT; |
804 | else if (ppgtt && intel_engine_flag(engine) & ppgtt->pd_dirty_rings) | 782 | else if (ppgtt && intel_engine_flag(engine) & ppgtt->pd_dirty_rings) |
805 | hw_flags = MI_FORCE_RESTORE; | 783 | hw_flags = MI_FORCE_RESTORE; |
@@ -843,15 +821,6 @@ static int do_rcs_switch(struct drm_i915_gem_request *req) | |||
843 | to->remap_slice &= ~(1<<i); | 821 | to->remap_slice &= ~(1<<i); |
844 | } | 822 | } |
845 | 823 | ||
846 | if (!to->engine[RCS].initialised) { | ||
847 | if (engine->init_context) { | ||
848 | ret = engine->init_context(req); | ||
849 | if (ret) | ||
850 | return ret; | ||
851 | } | ||
852 | to->engine[RCS].initialised = true; | ||
853 | } | ||
854 | |||
855 | return 0; | 824 | return 0; |
856 | } | 825 | } |
857 | 826 | ||
@@ -899,7 +868,7 @@ int i915_switch_context(struct drm_i915_gem_request *req) | |||
899 | return do_rcs_switch(req); | 868 | return do_rcs_switch(req); |
900 | } | 869 | } |
901 | 870 | ||
902 | static bool engine_has_kernel_context(struct intel_engine_cs *engine) | 871 | static bool engine_has_idle_kernel_context(struct intel_engine_cs *engine) |
903 | { | 872 | { |
904 | struct i915_gem_timeline *timeline; | 873 | struct i915_gem_timeline *timeline; |
905 | 874 | ||
@@ -915,8 +884,7 @@ static bool engine_has_kernel_context(struct intel_engine_cs *engine) | |||
915 | return false; | 884 | return false; |
916 | } | 885 | } |
917 | 886 | ||
918 | return (!engine->last_retired_context || | 887 | return intel_engine_has_kernel_context(engine); |
919 | i915_gem_context_is_kernel(engine->last_retired_context)); | ||
920 | } | 888 | } |
921 | 889 | ||
922 | int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv) | 890 | int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv) |
@@ -933,7 +901,7 @@ int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv) | |||
933 | struct drm_i915_gem_request *req; | 901 | struct drm_i915_gem_request *req; |
934 | int ret; | 902 | int ret; |
935 | 903 | ||
936 | if (engine_has_kernel_context(engine)) | 904 | if (engine_has_idle_kernel_context(engine)) |
937 | continue; | 905 | continue; |
938 | 906 | ||
939 | req = i915_gem_request_alloc(engine, dev_priv->kernel_context); | 907 | req = i915_gem_request_alloc(engine, dev_priv->kernel_context); |
diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h index 44688e22a5c2..4bfb72f8e1cb 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.h +++ b/drivers/gpu/drm/i915/i915_gem_context.h | |||
@@ -157,7 +157,6 @@ struct i915_gem_context { | |||
157 | u32 *lrc_reg_state; | 157 | u32 *lrc_reg_state; |
158 | u64 lrc_desc; | 158 | u64 lrc_desc; |
159 | int pin_count; | 159 | int pin_count; |
160 | bool initialised; | ||
161 | } engine[I915_NUM_ENGINES]; | 160 | } engine[I915_NUM_ENGINES]; |
162 | 161 | ||
163 | /** ring_size: size for allocating the per-engine ring buffer */ | 162 | /** ring_size: size for allocating the per-engine ring buffer */ |
@@ -292,6 +291,9 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data, | |||
292 | int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, void *data, | 291 | int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, void *data, |
293 | struct drm_file *file); | 292 | struct drm_file *file); |
294 | 293 | ||
294 | struct i915_gem_context * | ||
295 | i915_gem_context_create_kernel(struct drm_i915_private *i915, int prio); | ||
296 | |||
295 | static inline struct i915_gem_context * | 297 | static inline struct i915_gem_context * |
296 | i915_gem_context_get(struct i915_gem_context *ctx) | 298 | i915_gem_context_get(struct i915_gem_context *ctx) |
297 | { | 299 | { |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 8daa8a78cdc0..60ca4f05ae94 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -46,7 +46,7 @@ static bool ggtt_is_idle(struct drm_i915_private *i915) | |||
46 | return false; | 46 | return false; |
47 | 47 | ||
48 | for_each_engine(engine, i915, id) { | 48 | for_each_engine(engine, i915, id) { |
49 | if (engine->last_retired_context != i915->kernel_context) | 49 | if (!intel_engine_has_kernel_context(engine)) |
50 | return false; | 50 | return false; |
51 | } | 51 | } |
52 | 52 | ||
@@ -73,6 +73,7 @@ static int ggtt_flush(struct drm_i915_private *i915) | |||
73 | if (err) | 73 | if (err) |
74 | return err; | 74 | return err; |
75 | 75 | ||
76 | GEM_BUG_ON(!ggtt_is_idle(i915)); | ||
76 | return 0; | 77 | return 0; |
77 | } | 78 | } |
78 | 79 | ||
@@ -216,6 +217,7 @@ search_again: | |||
216 | if (ret) | 217 | if (ret) |
217 | return ret; | 218 | return ret; |
218 | 219 | ||
220 | cond_resched(); | ||
219 | goto search_again; | 221 | goto search_again; |
220 | } | 222 | } |
221 | 223 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 435ed95df144..53ccb27bfe91 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -2074,23 +2074,27 @@ static struct drm_syncobj ** | |||
2074 | get_fence_array(struct drm_i915_gem_execbuffer2 *args, | 2074 | get_fence_array(struct drm_i915_gem_execbuffer2 *args, |
2075 | struct drm_file *file) | 2075 | struct drm_file *file) |
2076 | { | 2076 | { |
2077 | const unsigned int nfences = args->num_cliprects; | 2077 | const unsigned long nfences = args->num_cliprects; |
2078 | struct drm_i915_gem_exec_fence __user *user; | 2078 | struct drm_i915_gem_exec_fence __user *user; |
2079 | struct drm_syncobj **fences; | 2079 | struct drm_syncobj **fences; |
2080 | unsigned int n; | 2080 | unsigned long n; |
2081 | int err; | 2081 | int err; |
2082 | 2082 | ||
2083 | if (!(args->flags & I915_EXEC_FENCE_ARRAY)) | 2083 | if (!(args->flags & I915_EXEC_FENCE_ARRAY)) |
2084 | return NULL; | 2084 | return NULL; |
2085 | 2085 | ||
2086 | if (nfences > SIZE_MAX / sizeof(*fences)) | 2086 | /* Check multiplication overflow for access_ok() and kvmalloc_array() */ |
2087 | BUILD_BUG_ON(sizeof(size_t) > sizeof(unsigned long)); | ||
2088 | if (nfences > min_t(unsigned long, | ||
2089 | ULONG_MAX / sizeof(*user), | ||
2090 | SIZE_MAX / sizeof(*fences))) | ||
2087 | return ERR_PTR(-EINVAL); | 2091 | return ERR_PTR(-EINVAL); |
2088 | 2092 | ||
2089 | user = u64_to_user_ptr(args->cliprects_ptr); | 2093 | user = u64_to_user_ptr(args->cliprects_ptr); |
2090 | if (!access_ok(VERIFY_READ, user, nfences * 2 * sizeof(u32))) | 2094 | if (!access_ok(VERIFY_READ, user, nfences * sizeof(*user))) |
2091 | return ERR_PTR(-EFAULT); | 2095 | return ERR_PTR(-EFAULT); |
2092 | 2096 | ||
2093 | fences = kvmalloc_array(args->num_cliprects, sizeof(*fences), | 2097 | fences = kvmalloc_array(nfences, sizeof(*fences), |
2094 | __GFP_NOWARN | GFP_KERNEL); | 2098 | __GFP_NOWARN | GFP_KERNEL); |
2095 | if (!fences) | 2099 | if (!fences) |
2096 | return ERR_PTR(-ENOMEM); | 2100 | return ERR_PTR(-ENOMEM); |
@@ -2447,6 +2451,26 @@ err_in_fence: | |||
2447 | return err; | 2451 | return err; |
2448 | } | 2452 | } |
2449 | 2453 | ||
2454 | static size_t eb_element_size(void) | ||
2455 | { | ||
2456 | return (sizeof(struct drm_i915_gem_exec_object2) + | ||
2457 | sizeof(struct i915_vma *) + | ||
2458 | sizeof(unsigned int)); | ||
2459 | } | ||
2460 | |||
2461 | static bool check_buffer_count(size_t count) | ||
2462 | { | ||
2463 | const size_t sz = eb_element_size(); | ||
2464 | |||
2465 | /* | ||
2466 | * When using LUT_HANDLE, we impose a limit of INT_MAX for the lookup | ||
2467 | * array size (see eb_create()). Otherwise, we can accept an array as | ||
2468 | * large as can be addressed (though use large arrays at your peril)! | ||
2469 | */ | ||
2470 | |||
2471 | return !(count < 1 || count > INT_MAX || count > SIZE_MAX / sz - 1); | ||
2472 | } | ||
2473 | |||
2450 | /* | 2474 | /* |
2451 | * Legacy execbuffer just creates an exec2 list from the original exec object | 2475 | * Legacy execbuffer just creates an exec2 list from the original exec object |
2452 | * list array and passes it to the real function. | 2476 | * list array and passes it to the real function. |
@@ -2455,18 +2479,16 @@ int | |||
2455 | i915_gem_execbuffer(struct drm_device *dev, void *data, | 2479 | i915_gem_execbuffer(struct drm_device *dev, void *data, |
2456 | struct drm_file *file) | 2480 | struct drm_file *file) |
2457 | { | 2481 | { |
2458 | const size_t sz = (sizeof(struct drm_i915_gem_exec_object2) + | ||
2459 | sizeof(struct i915_vma *) + | ||
2460 | sizeof(unsigned int)); | ||
2461 | struct drm_i915_gem_execbuffer *args = data; | 2482 | struct drm_i915_gem_execbuffer *args = data; |
2462 | struct drm_i915_gem_execbuffer2 exec2; | 2483 | struct drm_i915_gem_execbuffer2 exec2; |
2463 | struct drm_i915_gem_exec_object *exec_list = NULL; | 2484 | struct drm_i915_gem_exec_object *exec_list = NULL; |
2464 | struct drm_i915_gem_exec_object2 *exec2_list = NULL; | 2485 | struct drm_i915_gem_exec_object2 *exec2_list = NULL; |
2486 | const size_t count = args->buffer_count; | ||
2465 | unsigned int i; | 2487 | unsigned int i; |
2466 | int err; | 2488 | int err; |
2467 | 2489 | ||
2468 | if (args->buffer_count < 1 || args->buffer_count > SIZE_MAX / sz - 1) { | 2490 | if (!check_buffer_count(count)) { |
2469 | DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count); | 2491 | DRM_DEBUG("execbuf2 with %zd buffers\n", count); |
2470 | return -EINVAL; | 2492 | return -EINVAL; |
2471 | } | 2493 | } |
2472 | 2494 | ||
@@ -2485,9 +2507,9 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
2485 | return -EINVAL; | 2507 | return -EINVAL; |
2486 | 2508 | ||
2487 | /* Copy in the exec list from userland */ | 2509 | /* Copy in the exec list from userland */ |
2488 | exec_list = kvmalloc_array(args->buffer_count, sizeof(*exec_list), | 2510 | exec_list = kvmalloc_array(count, sizeof(*exec_list), |
2489 | __GFP_NOWARN | GFP_KERNEL); | 2511 | __GFP_NOWARN | GFP_KERNEL); |
2490 | exec2_list = kvmalloc_array(args->buffer_count + 1, sz, | 2512 | exec2_list = kvmalloc_array(count + 1, eb_element_size(), |
2491 | __GFP_NOWARN | GFP_KERNEL); | 2513 | __GFP_NOWARN | GFP_KERNEL); |
2492 | if (exec_list == NULL || exec2_list == NULL) { | 2514 | if (exec_list == NULL || exec2_list == NULL) { |
2493 | DRM_DEBUG("Failed to allocate exec list for %d buffers\n", | 2515 | DRM_DEBUG("Failed to allocate exec list for %d buffers\n", |
@@ -2498,7 +2520,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
2498 | } | 2520 | } |
2499 | err = copy_from_user(exec_list, | 2521 | err = copy_from_user(exec_list, |
2500 | u64_to_user_ptr(args->buffers_ptr), | 2522 | u64_to_user_ptr(args->buffers_ptr), |
2501 | sizeof(*exec_list) * args->buffer_count); | 2523 | sizeof(*exec_list) * count); |
2502 | if (err) { | 2524 | if (err) { |
2503 | DRM_DEBUG("copy %d exec entries failed %d\n", | 2525 | DRM_DEBUG("copy %d exec entries failed %d\n", |
2504 | args->buffer_count, err); | 2526 | args->buffer_count, err); |
@@ -2548,16 +2570,14 @@ int | |||
2548 | i915_gem_execbuffer2(struct drm_device *dev, void *data, | 2570 | i915_gem_execbuffer2(struct drm_device *dev, void *data, |
2549 | struct drm_file *file) | 2571 | struct drm_file *file) |
2550 | { | 2572 | { |
2551 | const size_t sz = (sizeof(struct drm_i915_gem_exec_object2) + | ||
2552 | sizeof(struct i915_vma *) + | ||
2553 | sizeof(unsigned int)); | ||
2554 | struct drm_i915_gem_execbuffer2 *args = data; | 2573 | struct drm_i915_gem_execbuffer2 *args = data; |
2555 | struct drm_i915_gem_exec_object2 *exec2_list; | 2574 | struct drm_i915_gem_exec_object2 *exec2_list; |
2556 | struct drm_syncobj **fences = NULL; | 2575 | struct drm_syncobj **fences = NULL; |
2576 | const size_t count = args->buffer_count; | ||
2557 | int err; | 2577 | int err; |
2558 | 2578 | ||
2559 | if (args->buffer_count < 1 || args->buffer_count > SIZE_MAX / sz - 1) { | 2579 | if (!check_buffer_count(count)) { |
2560 | DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count); | 2580 | DRM_DEBUG("execbuf2 with %zd buffers\n", count); |
2561 | return -EINVAL; | 2581 | return -EINVAL; |
2562 | } | 2582 | } |
2563 | 2583 | ||
@@ -2565,17 +2585,17 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, | |||
2565 | return -EINVAL; | 2585 | return -EINVAL; |
2566 | 2586 | ||
2567 | /* Allocate an extra slot for use by the command parser */ | 2587 | /* Allocate an extra slot for use by the command parser */ |
2568 | exec2_list = kvmalloc_array(args->buffer_count + 1, sz, | 2588 | exec2_list = kvmalloc_array(count + 1, eb_element_size(), |
2569 | __GFP_NOWARN | GFP_KERNEL); | 2589 | __GFP_NOWARN | GFP_KERNEL); |
2570 | if (exec2_list == NULL) { | 2590 | if (exec2_list == NULL) { |
2571 | DRM_DEBUG("Failed to allocate exec list for %d buffers\n", | 2591 | DRM_DEBUG("Failed to allocate exec list for %zd buffers\n", |
2572 | args->buffer_count); | 2592 | count); |
2573 | return -ENOMEM; | 2593 | return -ENOMEM; |
2574 | } | 2594 | } |
2575 | if (copy_from_user(exec2_list, | 2595 | if (copy_from_user(exec2_list, |
2576 | u64_to_user_ptr(args->buffers_ptr), | 2596 | u64_to_user_ptr(args->buffers_ptr), |
2577 | sizeof(*exec2_list) * args->buffer_count)) { | 2597 | sizeof(*exec2_list) * count)) { |
2578 | DRM_DEBUG("copy %d exec entries failed\n", args->buffer_count); | 2598 | DRM_DEBUG("copy %zd exec entries failed\n", count); |
2579 | kvfree(exec2_list); | 2599 | kvfree(exec2_list); |
2580 | return -EFAULT; | 2600 | return -EFAULT; |
2581 | } | 2601 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 2af65ecf2df8..64e8ae1fd832 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -454,6 +454,14 @@ static void vm_free_pages_release(struct i915_address_space *vm, | |||
454 | 454 | ||
455 | static void vm_free_page(struct i915_address_space *vm, struct page *page) | 455 | static void vm_free_page(struct i915_address_space *vm, struct page *page) |
456 | { | 456 | { |
457 | /* | ||
458 | * On !llc, we need to change the pages back to WB. We only do so | ||
459 | * in bulk, so we rarely need to change the page attributes here, | ||
460 | * but doing so requires a stop_machine() from deep inside arch/x86/mm. | ||
461 | * To make detection of the possible sleep more likely, use an | ||
462 | * unconditional might_sleep() for everybody. | ||
463 | */ | ||
464 | might_sleep(); | ||
457 | if (!pagevec_add(&vm->free_pages, page)) | 465 | if (!pagevec_add(&vm->free_pages, page)) |
458 | vm_free_pages_release(vm, false); | 466 | vm_free_pages_release(vm, false); |
459 | } | 467 | } |
@@ -2248,35 +2256,62 @@ static bool needs_idle_maps(struct drm_i915_private *dev_priv) | |||
2248 | return IS_GEN5(dev_priv) && IS_MOBILE(dev_priv) && intel_vtd_active(); | 2256 | return IS_GEN5(dev_priv) && IS_MOBILE(dev_priv) && intel_vtd_active(); |
2249 | } | 2257 | } |
2250 | 2258 | ||
2251 | void i915_check_and_clear_faults(struct drm_i915_private *dev_priv) | 2259 | static void gen6_check_and_clear_faults(struct drm_i915_private *dev_priv) |
2252 | { | 2260 | { |
2253 | struct intel_engine_cs *engine; | 2261 | struct intel_engine_cs *engine; |
2254 | enum intel_engine_id id; | 2262 | enum intel_engine_id id; |
2255 | 2263 | u32 fault; | |
2256 | if (INTEL_INFO(dev_priv)->gen < 6) | ||
2257 | return; | ||
2258 | 2264 | ||
2259 | for_each_engine(engine, dev_priv, id) { | 2265 | for_each_engine(engine, dev_priv, id) { |
2260 | u32 fault_reg; | 2266 | fault = I915_READ(RING_FAULT_REG(engine)); |
2261 | fault_reg = I915_READ(RING_FAULT_REG(engine)); | 2267 | if (fault & RING_FAULT_VALID) { |
2262 | if (fault_reg & RING_FAULT_VALID) { | ||
2263 | DRM_DEBUG_DRIVER("Unexpected fault\n" | 2268 | DRM_DEBUG_DRIVER("Unexpected fault\n" |
2264 | "\tAddr: 0x%08lx\n" | 2269 | "\tAddr: 0x%08lx\n" |
2265 | "\tAddress space: %s\n" | 2270 | "\tAddress space: %s\n" |
2266 | "\tSource ID: %d\n" | 2271 | "\tSource ID: %d\n" |
2267 | "\tType: %d\n", | 2272 | "\tType: %d\n", |
2268 | fault_reg & PAGE_MASK, | 2273 | fault & PAGE_MASK, |
2269 | fault_reg & RING_FAULT_GTTSEL_MASK ? "GGTT" : "PPGTT", | 2274 | fault & RING_FAULT_GTTSEL_MASK ? "GGTT" : "PPGTT", |
2270 | RING_FAULT_SRCID(fault_reg), | 2275 | RING_FAULT_SRCID(fault), |
2271 | RING_FAULT_FAULT_TYPE(fault_reg)); | 2276 | RING_FAULT_FAULT_TYPE(fault)); |
2272 | I915_WRITE(RING_FAULT_REG(engine), | 2277 | I915_WRITE(RING_FAULT_REG(engine), |
2273 | fault_reg & ~RING_FAULT_VALID); | 2278 | fault & ~RING_FAULT_VALID); |
2274 | } | 2279 | } |
2275 | } | 2280 | } |
2276 | 2281 | ||
2277 | /* Engine specific init may not have been done till this point. */ | 2282 | POSTING_READ(RING_FAULT_REG(dev_priv->engine[RCS])); |
2278 | if (dev_priv->engine[RCS]) | 2283 | } |
2279 | POSTING_READ(RING_FAULT_REG(dev_priv->engine[RCS])); | 2284 | |
2285 | static void gen8_check_and_clear_faults(struct drm_i915_private *dev_priv) | ||
2286 | { | ||
2287 | u32 fault = I915_READ(GEN8_RING_FAULT_REG); | ||
2288 | |||
2289 | if (fault & RING_FAULT_VALID) { | ||
2290 | DRM_DEBUG_DRIVER("Unexpected fault\n" | ||
2291 | "\tAddr: 0x%08lx\n" | ||
2292 | "\tEngine ID: %d\n" | ||
2293 | "\tSource ID: %d\n" | ||
2294 | "\tType: %d\n", | ||
2295 | fault & PAGE_MASK, | ||
2296 | GEN8_RING_FAULT_ENGINE_ID(fault), | ||
2297 | RING_FAULT_SRCID(fault), | ||
2298 | RING_FAULT_FAULT_TYPE(fault)); | ||
2299 | I915_WRITE(GEN8_RING_FAULT_REG, | ||
2300 | fault & ~RING_FAULT_VALID); | ||
2301 | } | ||
2302 | |||
2303 | POSTING_READ(GEN8_RING_FAULT_REG); | ||
2304 | } | ||
2305 | |||
2306 | void i915_check_and_clear_faults(struct drm_i915_private *dev_priv) | ||
2307 | { | ||
2308 | /* From GEN8 onwards we only have one 'All Engine Fault Register' */ | ||
2309 | if (INTEL_GEN(dev_priv) >= 8) | ||
2310 | gen8_check_and_clear_faults(dev_priv); | ||
2311 | else if (INTEL_GEN(dev_priv) >= 6) | ||
2312 | gen6_check_and_clear_faults(dev_priv); | ||
2313 | else | ||
2314 | return; | ||
2280 | } | 2315 | } |
2281 | 2316 | ||
2282 | void i915_gem_suspend_gtt_mappings(struct drm_i915_private *dev_priv) | 2317 | void i915_gem_suspend_gtt_mappings(struct drm_i915_private *dev_priv) |
@@ -3041,7 +3076,7 @@ const struct intel_ppat_entry * | |||
3041 | intel_ppat_get(struct drm_i915_private *i915, u8 value) | 3076 | intel_ppat_get(struct drm_i915_private *i915, u8 value) |
3042 | { | 3077 | { |
3043 | struct intel_ppat *ppat = &i915->ppat; | 3078 | struct intel_ppat *ppat = &i915->ppat; |
3044 | struct intel_ppat_entry *entry; | 3079 | struct intel_ppat_entry *entry = NULL; |
3045 | unsigned int scanned, best_score; | 3080 | unsigned int scanned, best_score; |
3046 | int i; | 3081 | int i; |
3047 | 3082 | ||
@@ -3064,7 +3099,7 @@ intel_ppat_get(struct drm_i915_private *i915, u8 value) | |||
3064 | } | 3099 | } |
3065 | 3100 | ||
3066 | if (scanned == ppat->max_entries) { | 3101 | if (scanned == ppat->max_entries) { |
3067 | if (!best_score) | 3102 | if (!entry) |
3068 | return ERR_PTR(-ENOSPC); | 3103 | return ERR_PTR(-ENOSPC); |
3069 | 3104 | ||
3070 | kref_get(&entry->ref); | 3105 | kref_get(&entry->ref); |
@@ -3171,12 +3206,6 @@ static void cnl_setup_private_ppat(struct intel_ppat *ppat) | |||
3171 | ppat->match = bdw_private_pat_match; | 3206 | ppat->match = bdw_private_pat_match; |
3172 | ppat->clear_value = GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3); | 3207 | ppat->clear_value = GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3); |
3173 | 3208 | ||
3174 | /* XXX: spec is unclear if this is still needed for CNL+ */ | ||
3175 | if (!USES_PPGTT(ppat->i915)) { | ||
3176 | __alloc_ppat_entry(ppat, 0, GEN8_PPAT_UC); | ||
3177 | return; | ||
3178 | } | ||
3179 | |||
3180 | __alloc_ppat_entry(ppat, 0, GEN8_PPAT_WB | GEN8_PPAT_LLC); | 3209 | __alloc_ppat_entry(ppat, 0, GEN8_PPAT_WB | GEN8_PPAT_LLC); |
3181 | __alloc_ppat_entry(ppat, 1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC); | 3210 | __alloc_ppat_entry(ppat, 1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC); |
3182 | __alloc_ppat_entry(ppat, 2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC); | 3211 | __alloc_ppat_entry(ppat, 2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC); |
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h index 63ce38c1cce9..19fb28c177d8 100644 --- a/drivers/gpu/drm/i915/i915_gem_object.h +++ b/drivers/gpu/drm/i915/i915_gem_object.h | |||
@@ -53,8 +53,9 @@ struct i915_lut_handle { | |||
53 | 53 | ||
54 | struct drm_i915_gem_object_ops { | 54 | struct drm_i915_gem_object_ops { |
55 | unsigned int flags; | 55 | unsigned int flags; |
56 | #define I915_GEM_OBJECT_HAS_STRUCT_PAGE BIT(0) | 56 | #define I915_GEM_OBJECT_HAS_STRUCT_PAGE BIT(0) |
57 | #define I915_GEM_OBJECT_IS_SHRINKABLE BIT(1) | 57 | #define I915_GEM_OBJECT_IS_SHRINKABLE BIT(1) |
58 | #define I915_GEM_OBJECT_IS_PROXY BIT(2) | ||
58 | 59 | ||
59 | /* Interface between the GEM object and its backing storage. | 60 | /* Interface between the GEM object and its backing storage. |
60 | * get_pages() is called once prior to the use of the associated set | 61 | * get_pages() is called once prior to the use of the associated set |
@@ -362,6 +363,12 @@ i915_gem_object_is_shrinkable(const struct drm_i915_gem_object *obj) | |||
362 | } | 363 | } |
363 | 364 | ||
364 | static inline bool | 365 | static inline bool |
366 | i915_gem_object_is_proxy(const struct drm_i915_gem_object *obj) | ||
367 | { | ||
368 | return obj->ops->flags & I915_GEM_OBJECT_IS_PROXY; | ||
369 | } | ||
370 | |||
371 | static inline bool | ||
365 | i915_gem_object_is_active(const struct drm_i915_gem_object *obj) | 372 | i915_gem_object_is_active(const struct drm_i915_gem_object *obj) |
366 | { | 373 | { |
367 | return obj->active_count; | 374 | return obj->active_count; |
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c index 3703dc91eeda..c2723a06fbb4 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.c +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c | |||
@@ -26,10 +26,12 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include "i915_drv.h" | 28 | #include "i915_drv.h" |
29 | #include "i915_gem_render_state.h" | ||
29 | #include "intel_renderstate.h" | 30 | #include "intel_renderstate.h" |
30 | 31 | ||
31 | struct intel_render_state { | 32 | struct intel_render_state { |
32 | const struct intel_renderstate_rodata *rodata; | 33 | const struct intel_renderstate_rodata *rodata; |
34 | struct drm_i915_gem_object *obj; | ||
33 | struct i915_vma *vma; | 35 | struct i915_vma *vma; |
34 | u32 batch_offset; | 36 | u32 batch_offset; |
35 | u32 batch_size; | 37 | u32 batch_size; |
@@ -40,6 +42,9 @@ struct intel_render_state { | |||
40 | static const struct intel_renderstate_rodata * | 42 | static const struct intel_renderstate_rodata * |
41 | render_state_get_rodata(const struct intel_engine_cs *engine) | 43 | render_state_get_rodata(const struct intel_engine_cs *engine) |
42 | { | 44 | { |
45 | if (engine->id != RCS) | ||
46 | return NULL; | ||
47 | |||
43 | switch (INTEL_GEN(engine->i915)) { | 48 | switch (INTEL_GEN(engine->i915)) { |
44 | case 6: | 49 | case 6: |
45 | return &gen6_null_state; | 50 | return &gen6_null_state; |
@@ -74,17 +79,16 @@ static int render_state_setup(struct intel_render_state *so, | |||
74 | struct drm_i915_private *i915) | 79 | struct drm_i915_private *i915) |
75 | { | 80 | { |
76 | const struct intel_renderstate_rodata *rodata = so->rodata; | 81 | const struct intel_renderstate_rodata *rodata = so->rodata; |
77 | struct drm_i915_gem_object *obj = so->vma->obj; | ||
78 | unsigned int i = 0, reloc_index = 0; | 82 | unsigned int i = 0, reloc_index = 0; |
79 | unsigned int needs_clflush; | 83 | unsigned int needs_clflush; |
80 | u32 *d; | 84 | u32 *d; |
81 | int ret; | 85 | int ret; |
82 | 86 | ||
83 | ret = i915_gem_obj_prepare_shmem_write(obj, &needs_clflush); | 87 | ret = i915_gem_obj_prepare_shmem_write(so->obj, &needs_clflush); |
84 | if (ret) | 88 | if (ret) |
85 | return ret; | 89 | return ret; |
86 | 90 | ||
87 | d = kmap_atomic(i915_gem_object_get_dirty_page(obj, 0)); | 91 | d = kmap_atomic(i915_gem_object_get_dirty_page(so->obj, 0)); |
88 | 92 | ||
89 | while (i < rodata->batch_items) { | 93 | while (i < rodata->batch_items) { |
90 | u32 s = rodata->batch[i]; | 94 | u32 s = rodata->batch[i]; |
@@ -112,7 +116,7 @@ static int render_state_setup(struct intel_render_state *so, | |||
112 | goto err; | 116 | goto err; |
113 | } | 117 | } |
114 | 118 | ||
115 | so->batch_offset = so->vma->node.start; | 119 | so->batch_offset = i915_ggtt_offset(so->vma); |
116 | so->batch_size = rodata->batch_items * sizeof(u32); | 120 | so->batch_size = rodata->batch_items * sizeof(u32); |
117 | 121 | ||
118 | while (i % CACHELINE_DWORDS) | 122 | while (i % CACHELINE_DWORDS) |
@@ -160,9 +164,9 @@ static int render_state_setup(struct intel_render_state *so, | |||
160 | drm_clflush_virt_range(d, i * sizeof(u32)); | 164 | drm_clflush_virt_range(d, i * sizeof(u32)); |
161 | kunmap_atomic(d); | 165 | kunmap_atomic(d); |
162 | 166 | ||
163 | ret = i915_gem_object_set_to_gtt_domain(obj, false); | 167 | ret = i915_gem_object_set_to_gtt_domain(so->obj, false); |
164 | out: | 168 | out: |
165 | i915_gem_obj_finish_shmem_access(obj); | 169 | i915_gem_obj_finish_shmem_access(so->obj); |
166 | return ret; | 170 | return ret; |
167 | 171 | ||
168 | err: | 172 | err: |
@@ -173,112 +177,61 @@ err: | |||
173 | 177 | ||
174 | #undef OUT_BATCH | 178 | #undef OUT_BATCH |
175 | 179 | ||
176 | int i915_gem_render_state_init(struct intel_engine_cs *engine) | 180 | int i915_gem_render_state_emit(struct drm_i915_gem_request *rq) |
177 | { | 181 | { |
178 | struct intel_render_state *so; | 182 | struct intel_engine_cs *engine = rq->engine; |
179 | const struct intel_renderstate_rodata *rodata; | 183 | struct intel_render_state so = {}; /* keep the compiler happy */ |
180 | struct drm_i915_gem_object *obj; | 184 | int err; |
181 | int ret; | ||
182 | 185 | ||
183 | if (engine->id != RCS) | 186 | so.rodata = render_state_get_rodata(engine); |
187 | if (!so.rodata) | ||
184 | return 0; | 188 | return 0; |
185 | 189 | ||
186 | rodata = render_state_get_rodata(engine); | 190 | if (so.rodata->batch_items * 4 > PAGE_SIZE) |
187 | if (!rodata) | ||
188 | return 0; | ||
189 | |||
190 | if (rodata->batch_items * 4 > PAGE_SIZE) | ||
191 | return -EINVAL; | 191 | return -EINVAL; |
192 | 192 | ||
193 | so = kmalloc(sizeof(*so), GFP_KERNEL); | 193 | so.obj = i915_gem_object_create_internal(engine->i915, PAGE_SIZE); |
194 | if (!so) | 194 | if (IS_ERR(so.obj)) |
195 | return -ENOMEM; | 195 | return PTR_ERR(so.obj); |
196 | |||
197 | obj = i915_gem_object_create_internal(engine->i915, PAGE_SIZE); | ||
198 | if (IS_ERR(obj)) { | ||
199 | ret = PTR_ERR(obj); | ||
200 | goto err_free; | ||
201 | } | ||
202 | 196 | ||
203 | so->vma = i915_vma_instance(obj, &engine->i915->ggtt.base, NULL); | 197 | so.vma = i915_vma_instance(so.obj, &engine->i915->ggtt.base, NULL); |
204 | if (IS_ERR(so->vma)) { | 198 | if (IS_ERR(so.vma)) { |
205 | ret = PTR_ERR(so->vma); | 199 | err = PTR_ERR(so.vma); |
206 | goto err_obj; | 200 | goto err_obj; |
207 | } | 201 | } |
208 | 202 | ||
209 | so->rodata = rodata; | 203 | err = i915_vma_pin(so.vma, 0, 0, PIN_GLOBAL | PIN_HIGH); |
210 | engine->render_state = so; | 204 | if (err) |
211 | return 0; | 205 | goto err_vma; |
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); | ||
226 | |||
227 | so = req->engine->render_state; | ||
228 | if (!so) | ||
229 | return 0; | ||
230 | |||
231 | /* Recreate the page after shrinking */ | ||
232 | if (!i915_gem_object_has_pages(so->vma->obj)) | ||
233 | so->batch_offset = -1; | ||
234 | |||
235 | ret = i915_vma_pin(so->vma, 0, 0, PIN_GLOBAL | PIN_HIGH); | ||
236 | if (ret) | ||
237 | return ret; | ||
238 | 206 | ||
239 | if (so->vma->node.start != so->batch_offset) { | 207 | err = render_state_setup(&so, rq->i915); |
240 | ret = render_state_setup(so, req->i915); | 208 | if (err) |
241 | if (ret) | 209 | goto err_unpin; |
242 | goto err_unpin; | ||
243 | } | ||
244 | 210 | ||
245 | ret = req->engine->emit_flush(req, EMIT_INVALIDATE); | 211 | err = engine->emit_flush(rq, EMIT_INVALIDATE); |
246 | if (ret) | 212 | if (err) |
247 | goto err_unpin; | 213 | goto err_unpin; |
248 | 214 | ||
249 | ret = req->engine->emit_bb_start(req, | 215 | err = engine->emit_bb_start(rq, |
250 | so->batch_offset, so->batch_size, | 216 | so.batch_offset, so.batch_size, |
251 | I915_DISPATCH_SECURE); | 217 | I915_DISPATCH_SECURE); |
252 | if (ret) | 218 | if (err) |
253 | goto err_unpin; | 219 | goto err_unpin; |
254 | 220 | ||
255 | if (so->aux_size > 8) { | 221 | if (so.aux_size > 8) { |
256 | ret = req->engine->emit_bb_start(req, | 222 | err = engine->emit_bb_start(rq, |
257 | so->aux_offset, so->aux_size, | 223 | so.aux_offset, so.aux_size, |
258 | I915_DISPATCH_SECURE); | 224 | I915_DISPATCH_SECURE); |
259 | if (ret) | 225 | if (err) |
260 | goto err_unpin; | 226 | goto err_unpin; |
261 | } | 227 | } |
262 | 228 | ||
263 | i915_vma_move_to_active(so->vma, req, 0); | 229 | i915_vma_move_to_active(so.vma, rq, 0); |
264 | err_unpin: | 230 | err_unpin: |
265 | i915_vma_unpin(so->vma); | 231 | i915_vma_unpin(so.vma); |
266 | return ret; | 232 | err_vma: |
267 | } | 233 | i915_vma_close(so.vma); |
268 | 234 | err_obj: | |
269 | void i915_gem_render_state_fini(struct intel_engine_cs *engine) | 235 | __i915_gem_object_release_unless_active(so.obj); |
270 | { | 236 | return err; |
271 | struct intel_render_state *so; | ||
272 | struct drm_i915_gem_object *obj; | ||
273 | |||
274 | so = fetch_and_zero(&engine->render_state); | ||
275 | if (!so) | ||
276 | return; | ||
277 | |||
278 | obj = so->vma->obj; | ||
279 | |||
280 | i915_vma_close(so->vma); | ||
281 | __i915_gem_object_release_unless_active(obj); | ||
282 | |||
283 | kfree(so); | ||
284 | } | 237 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.h b/drivers/gpu/drm/i915/i915_gem_render_state.h index 87481845799d..86369520482e 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.h +++ b/drivers/gpu/drm/i915/i915_gem_render_state.h | |||
@@ -26,8 +26,6 @@ | |||
26 | 26 | ||
27 | struct drm_i915_gem_request; | 27 | struct drm_i915_gem_request; |
28 | 28 | ||
29 | int i915_gem_render_state_init(struct intel_engine_cs *engine); | 29 | int i915_gem_render_state_emit(struct drm_i915_gem_request *rq); |
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); | ||
32 | 30 | ||
33 | #endif /* _I915_GEM_RENDER_STATE_H_ */ | 31 | #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 d140fcf5c6a3..e0d6221022a8 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c | |||
@@ -259,6 +259,8 @@ static void mark_busy(struct drm_i915_private *i915) | |||
259 | if (INTEL_GEN(i915) >= 6) | 259 | if (INTEL_GEN(i915) >= 6) |
260 | gen6_rps_busy(i915); | 260 | gen6_rps_busy(i915); |
261 | 261 | ||
262 | intel_engines_unpark(i915); | ||
263 | |||
262 | queue_delayed_work(i915->wq, | 264 | queue_delayed_work(i915->wq, |
263 | &i915->gt.retire_work, | 265 | &i915->gt.retire_work, |
264 | round_jiffies_up_relative(HZ)); | 266 | round_jiffies_up_relative(HZ)); |
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 03e7abc7e043..1877ae9a1d9b 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c | |||
@@ -294,6 +294,18 @@ static void g4x_get_stolen_reserved(struct drm_i915_private *dev_priv, | |||
294 | ELK_STOLEN_RESERVED); | 294 | ELK_STOLEN_RESERVED); |
295 | dma_addr_t stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size; | 295 | dma_addr_t stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size; |
296 | 296 | ||
297 | if ((reg_val & G4X_STOLEN_RESERVED_ENABLE) == 0) { | ||
298 | *base = 0; | ||
299 | *size = 0; | ||
300 | return; | ||
301 | } | ||
302 | |||
303 | /* | ||
304 | * Whether ILK really reuses the ELK register for this is unclear. | ||
305 | * Let's see if we catch anyone with this supposedly enabled on ILK. | ||
306 | */ | ||
307 | WARN(IS_GEN5(dev_priv), "ILK stolen reserved found? 0x%08x\n", reg_val); | ||
308 | |||
297 | *base = (reg_val & G4X_STOLEN_RESERVED_ADDR2_MASK) << 16; | 309 | *base = (reg_val & G4X_STOLEN_RESERVED_ADDR2_MASK) << 16; |
298 | 310 | ||
299 | WARN_ON((reg_val & G4X_STOLEN_RESERVED_ADDR1_MASK) < *base); | 311 | WARN_ON((reg_val & G4X_STOLEN_RESERVED_ADDR1_MASK) < *base); |
@@ -313,6 +325,12 @@ static void gen6_get_stolen_reserved(struct drm_i915_private *dev_priv, | |||
313 | { | 325 | { |
314 | uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); | 326 | uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); |
315 | 327 | ||
328 | if ((reg_val & GEN6_STOLEN_RESERVED_ENABLE) == 0) { | ||
329 | *base = 0; | ||
330 | *size = 0; | ||
331 | return; | ||
332 | } | ||
333 | |||
316 | *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK; | 334 | *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK; |
317 | 335 | ||
318 | switch (reg_val & GEN6_STOLEN_RESERVED_SIZE_MASK) { | 336 | switch (reg_val & GEN6_STOLEN_RESERVED_SIZE_MASK) { |
@@ -339,6 +357,12 @@ static void gen7_get_stolen_reserved(struct drm_i915_private *dev_priv, | |||
339 | { | 357 | { |
340 | uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); | 358 | uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); |
341 | 359 | ||
360 | if ((reg_val & GEN6_STOLEN_RESERVED_ENABLE) == 0) { | ||
361 | *base = 0; | ||
362 | *size = 0; | ||
363 | return; | ||
364 | } | ||
365 | |||
342 | *base = reg_val & GEN7_STOLEN_RESERVED_ADDR_MASK; | 366 | *base = reg_val & GEN7_STOLEN_RESERVED_ADDR_MASK; |
343 | 367 | ||
344 | switch (reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK) { | 368 | switch (reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK) { |
@@ -359,6 +383,12 @@ static void chv_get_stolen_reserved(struct drm_i915_private *dev_priv, | |||
359 | { | 383 | { |
360 | uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); | 384 | uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); |
361 | 385 | ||
386 | if ((reg_val & GEN6_STOLEN_RESERVED_ENABLE) == 0) { | ||
387 | *base = 0; | ||
388 | *size = 0; | ||
389 | return; | ||
390 | } | ||
391 | |||
362 | *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK; | 392 | *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK; |
363 | 393 | ||
364 | switch (reg_val & GEN8_STOLEN_RESERVED_SIZE_MASK) { | 394 | switch (reg_val & GEN8_STOLEN_RESERVED_SIZE_MASK) { |
@@ -387,6 +417,12 @@ static void bdw_get_stolen_reserved(struct drm_i915_private *dev_priv, | |||
387 | uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); | 417 | uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); |
388 | dma_addr_t stolen_top; | 418 | dma_addr_t stolen_top; |
389 | 419 | ||
420 | if ((reg_val & GEN6_STOLEN_RESERVED_ENABLE) == 0) { | ||
421 | *base = 0; | ||
422 | *size = 0; | ||
423 | return; | ||
424 | } | ||
425 | |||
390 | stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size; | 426 | stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size; |
391 | 427 | ||
392 | *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK; | 428 | *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK; |
@@ -436,14 +472,12 @@ int i915_gem_init_stolen(struct drm_i915_private *dev_priv) | |||
436 | case 3: | 472 | case 3: |
437 | break; | 473 | break; |
438 | case 4: | 474 | case 4: |
439 | if (IS_G4X(dev_priv)) | 475 | if (!IS_G4X(dev_priv)) |
440 | g4x_get_stolen_reserved(dev_priv, | 476 | break; |
441 | &reserved_base, &reserved_size); | 477 | /* fall through */ |
442 | break; | ||
443 | case 5: | 478 | case 5: |
444 | /* Assume the gen6 maximum for the older platforms. */ | 479 | g4x_get_stolen_reserved(dev_priv, |
445 | reserved_size = 1024 * 1024; | 480 | &reserved_base, &reserved_size); |
446 | reserved_base = stolen_top - reserved_size; | ||
447 | break; | 481 | break; |
448 | case 6: | 482 | case 6: |
449 | gen6_get_stolen_reserved(dev_priv, | 483 | gen6_get_stolen_reserved(dev_priv, |
@@ -473,9 +507,9 @@ int i915_gem_init_stolen(struct drm_i915_private *dev_priv) | |||
473 | if (reserved_base < dev_priv->mm.stolen_base || | 507 | if (reserved_base < dev_priv->mm.stolen_base || |
474 | reserved_base + reserved_size > stolen_top) { | 508 | reserved_base + reserved_size > stolen_top) { |
475 | dma_addr_t reserved_top = reserved_base + reserved_size; | 509 | dma_addr_t reserved_top = reserved_base + reserved_size; |
476 | DRM_DEBUG_KMS("Stolen reserved area [%pad - %pad] outside stolen memory [%pad - %pad]\n", | 510 | DRM_ERROR("Stolen reserved area [%pad - %pad] outside stolen memory [%pad - %pad]\n", |
477 | &reserved_base, &reserved_top, | 511 | &reserved_base, &reserved_top, |
478 | &dev_priv->mm.stolen_base, &stolen_top); | 512 | &dev_priv->mm.stolen_base, &stolen_top); |
479 | return 0; | 513 | return 0; |
480 | } | 514 | } |
481 | 515 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 1294cf695df0..b85d7ebd9bee 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -345,6 +345,15 @@ i915_gem_set_tiling_ioctl(struct drm_device *dev, void *data, | |||
345 | if (!obj) | 345 | if (!obj) |
346 | return -ENOENT; | 346 | return -ENOENT; |
347 | 347 | ||
348 | /* | ||
349 | * The tiling mode of proxy objects is handled by its generator, and | ||
350 | * not allowed to be changed by userspace. | ||
351 | */ | ||
352 | if (i915_gem_object_is_proxy(obj)) { | ||
353 | err = -ENXIO; | ||
354 | goto err; | ||
355 | } | ||
356 | |||
348 | if (!i915_tiling_ok(obj, args->tiling_mode, args->stride)) { | 357 | if (!i915_tiling_ok(obj, args->tiling_mode, args->stride)) { |
349 | err = -EINVAL; | 358 | err = -EINVAL; |
350 | goto err; | 359 | goto err; |
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 653fb69e7ecb..7481c8e1b5a8 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <generated/utsrelease.h> | 30 | #include <generated/utsrelease.h> |
31 | #include <linux/stop_machine.h> | 31 | #include <linux/stop_machine.h> |
32 | #include <linux/zlib.h> | 32 | #include <linux/zlib.h> |
33 | #include <drm/drm_print.h> | ||
34 | |||
33 | #include "i915_drv.h" | 35 | #include "i915_drv.h" |
34 | 36 | ||
35 | static const char *engine_str(int engine) | 37 | static const char *engine_str(int engine) |
@@ -175,6 +177,21 @@ static void i915_error_puts(struct drm_i915_error_state_buf *e, | |||
175 | #define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__) | 177 | #define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__) |
176 | #define err_puts(e, s) i915_error_puts(e, s) | 178 | #define err_puts(e, s) i915_error_puts(e, s) |
177 | 179 | ||
180 | static void __i915_printfn_error(struct drm_printer *p, struct va_format *vaf) | ||
181 | { | ||
182 | i915_error_vprintf(p->arg, vaf->fmt, *vaf->va); | ||
183 | } | ||
184 | |||
185 | static inline struct drm_printer | ||
186 | i915_error_printer(struct drm_i915_error_state_buf *e) | ||
187 | { | ||
188 | struct drm_printer p = { | ||
189 | .printfn = __i915_printfn_error, | ||
190 | .arg = e, | ||
191 | }; | ||
192 | return p; | ||
193 | } | ||
194 | |||
178 | #ifdef CONFIG_DRM_I915_COMPRESS_ERROR | 195 | #ifdef CONFIG_DRM_I915_COMPRESS_ERROR |
179 | 196 | ||
180 | struct compress { | 197 | struct compress { |
@@ -589,6 +606,21 @@ static void err_print_pciid(struct drm_i915_error_state_buf *m, | |||
589 | pdev->subsystem_device); | 606 | pdev->subsystem_device); |
590 | } | 607 | } |
591 | 608 | ||
609 | static void err_print_uc(struct drm_i915_error_state_buf *m, | ||
610 | const struct i915_error_uc *error_uc) | ||
611 | { | ||
612 | struct drm_printer p = i915_error_printer(m); | ||
613 | const struct i915_gpu_state *error = | ||
614 | container_of(error_uc, typeof(*error), uc); | ||
615 | |||
616 | if (!error->device_info.has_guc) | ||
617 | return; | ||
618 | |||
619 | intel_uc_fw_dump(&error_uc->guc_fw, &p); | ||
620 | intel_uc_fw_dump(&error_uc->huc_fw, &p); | ||
621 | print_error_obj(m, NULL, "GuC log buffer", error_uc->guc_log); | ||
622 | } | ||
623 | |||
592 | int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | 624 | int i915_error_state_to_str(struct drm_i915_error_state_buf *m, |
593 | const struct i915_gpu_state *error) | 625 | const struct i915_gpu_state *error) |
594 | { | 626 | { |
@@ -763,8 +795,6 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | |||
763 | 795 | ||
764 | print_error_obj(m, NULL, "Semaphores", error->semaphore); | 796 | print_error_obj(m, NULL, "Semaphores", error->semaphore); |
765 | 797 | ||
766 | print_error_obj(m, NULL, "GuC log buffer", error->guc_log); | ||
767 | |||
768 | if (error->overlay) | 798 | if (error->overlay) |
769 | intel_overlay_print_error_state(m, error->overlay); | 799 | intel_overlay_print_error_state(m, error->overlay); |
770 | 800 | ||
@@ -773,6 +803,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | |||
773 | 803 | ||
774 | err_print_capabilities(m, &error->device_info); | 804 | err_print_capabilities(m, &error->device_info); |
775 | err_print_params(m, &error->params); | 805 | err_print_params(m, &error->params); |
806 | err_print_uc(m, &error->uc); | ||
776 | 807 | ||
777 | if (m->bytes == 0 && m->err) | 808 | if (m->bytes == 0 && m->err) |
778 | return m->err; | 809 | return m->err; |
@@ -831,6 +862,22 @@ static __always_inline void free_param(const char *type, void *x) | |||
831 | kfree(*(void **)x); | 862 | kfree(*(void **)x); |
832 | } | 863 | } |
833 | 864 | ||
865 | static void cleanup_params(struct i915_gpu_state *error) | ||
866 | { | ||
867 | #define FREE(T, x, ...) free_param(#T, &error->params.x); | ||
868 | I915_PARAMS_FOR_EACH(FREE); | ||
869 | #undef FREE | ||
870 | } | ||
871 | |||
872 | static void cleanup_uc_state(struct i915_gpu_state *error) | ||
873 | { | ||
874 | struct i915_error_uc *error_uc = &error->uc; | ||
875 | |||
876 | kfree(error_uc->guc_fw.path); | ||
877 | kfree(error_uc->huc_fw.path); | ||
878 | i915_error_object_free(error_uc->guc_log); | ||
879 | } | ||
880 | |||
834 | void __i915_gpu_state_free(struct kref *error_ref) | 881 | void __i915_gpu_state_free(struct kref *error_ref) |
835 | { | 882 | { |
836 | struct i915_gpu_state *error = | 883 | struct i915_gpu_state *error = |
@@ -857,7 +904,6 @@ void __i915_gpu_state_free(struct kref *error_ref) | |||
857 | } | 904 | } |
858 | 905 | ||
859 | i915_error_object_free(error->semaphore); | 906 | i915_error_object_free(error->semaphore); |
860 | i915_error_object_free(error->guc_log); | ||
861 | 907 | ||
862 | for (i = 0; i < ARRAY_SIZE(error->active_bo); i++) | 908 | for (i = 0; i < ARRAY_SIZE(error->active_bo); i++) |
863 | kfree(error->active_bo[i]); | 909 | kfree(error->active_bo[i]); |
@@ -866,9 +912,8 @@ void __i915_gpu_state_free(struct kref *error_ref) | |||
866 | kfree(error->overlay); | 912 | kfree(error->overlay); |
867 | kfree(error->display); | 913 | kfree(error->display); |
868 | 914 | ||
869 | #define FREE(T, x, ...) free_param(#T, &error->params.x); | 915 | cleanup_params(error); |
870 | I915_PARAMS_FOR_EACH(FREE); | 916 | cleanup_uc_state(error); |
871 | #undef FREE | ||
872 | 917 | ||
873 | kfree(error); | 918 | kfree(error); |
874 | } | 919 | } |
@@ -1172,11 +1217,13 @@ static void error_record_engine_registers(struct i915_gpu_state *error, | |||
1172 | 1217 | ||
1173 | if (INTEL_GEN(dev_priv) >= 6) { | 1218 | if (INTEL_GEN(dev_priv) >= 6) { |
1174 | ee->rc_psmi = I915_READ(RING_PSMI_CTL(engine->mmio_base)); | 1219 | ee->rc_psmi = I915_READ(RING_PSMI_CTL(engine->mmio_base)); |
1175 | ee->fault_reg = I915_READ(RING_FAULT_REG(engine)); | 1220 | if (INTEL_GEN(dev_priv) >= 8) { |
1176 | if (INTEL_GEN(dev_priv) >= 8) | ||
1177 | gen8_record_semaphore_state(error, engine, ee); | 1221 | gen8_record_semaphore_state(error, engine, ee); |
1178 | else | 1222 | ee->fault_reg = I915_READ(GEN8_RING_FAULT_REG); |
1223 | } else { | ||
1179 | gen6_record_semaphore_state(engine, ee); | 1224 | gen6_record_semaphore_state(engine, ee); |
1225 | ee->fault_reg = I915_READ(RING_FAULT_REG(engine)); | ||
1226 | } | ||
1180 | } | 1227 | } |
1181 | 1228 | ||
1182 | if (INTEL_GEN(dev_priv) >= 4) { | 1229 | if (INTEL_GEN(dev_priv) >= 4) { |
@@ -1559,15 +1606,25 @@ static void i915_capture_pinned_buffers(struct drm_i915_private *dev_priv, | |||
1559 | error->pinned_bo = bo; | 1606 | error->pinned_bo = bo; |
1560 | } | 1607 | } |
1561 | 1608 | ||
1562 | static void i915_gem_capture_guc_log_buffer(struct drm_i915_private *dev_priv, | 1609 | static void capture_uc_state(struct i915_gpu_state *error) |
1563 | struct i915_gpu_state *error) | ||
1564 | { | 1610 | { |
1565 | /* Capturing log buf contents won't be useful if logging was disabled */ | 1611 | struct drm_i915_private *i915 = error->i915; |
1566 | if (!dev_priv->guc.log.vma || (i915_modparams.guc_log_level < 0)) | 1612 | struct i915_error_uc *error_uc = &error->uc; |
1613 | |||
1614 | /* Capturing uC state won't be useful if there is no GuC */ | ||
1615 | if (!error->device_info.has_guc) | ||
1567 | return; | 1616 | return; |
1568 | 1617 | ||
1569 | error->guc_log = i915_error_object_create(dev_priv, | 1618 | error_uc->guc_fw = i915->guc.fw; |
1570 | dev_priv->guc.log.vma); | 1619 | error_uc->huc_fw = i915->huc.fw; |
1620 | |||
1621 | /* Non-default firmware paths will be specified by the modparam. | ||
1622 | * As modparams are generally accesible from the userspace make | ||
1623 | * explicit copies of the firmware paths. | ||
1624 | */ | ||
1625 | error_uc->guc_fw.path = kstrdup(i915->guc.fw.path, GFP_ATOMIC); | ||
1626 | error_uc->huc_fw.path = kstrdup(i915->huc.fw.path, GFP_ATOMIC); | ||
1627 | error_uc->guc_log = i915_error_object_create(i915, i915->guc.log.vma); | ||
1571 | } | 1628 | } |
1572 | 1629 | ||
1573 | /* Capture all registers which don't fit into another category. */ | 1630 | /* Capture all registers which don't fit into another category. */ |
@@ -1695,6 +1752,14 @@ static __always_inline void dup_param(const char *type, void *x) | |||
1695 | *(void **)x = kstrdup(*(void **)x, GFP_ATOMIC); | 1752 | *(void **)x = kstrdup(*(void **)x, GFP_ATOMIC); |
1696 | } | 1753 | } |
1697 | 1754 | ||
1755 | static void capture_params(struct i915_gpu_state *error) | ||
1756 | { | ||
1757 | error->params = i915_modparams; | ||
1758 | #define DUP(T, x, ...) dup_param(#T, &error->params.x); | ||
1759 | I915_PARAMS_FOR_EACH(DUP); | ||
1760 | #undef DUP | ||
1761 | } | ||
1762 | |||
1698 | static int capture(void *data) | 1763 | static int capture(void *data) |
1699 | { | 1764 | { |
1700 | struct i915_gpu_state *error = data; | 1765 | struct i915_gpu_state *error = data; |
@@ -1705,10 +1770,8 @@ static int capture(void *data) | |||
1705 | ktime_to_timeval(ktime_sub(ktime_get(), | 1770 | ktime_to_timeval(ktime_sub(ktime_get(), |
1706 | error->i915->gt.last_init_time)); | 1771 | error->i915->gt.last_init_time)); |
1707 | 1772 | ||
1708 | error->params = i915_modparams; | 1773 | capture_params(error); |
1709 | #define DUP(T, x, ...) dup_param(#T, &error->params.x); | 1774 | capture_uc_state(error); |
1710 | I915_PARAMS_FOR_EACH(DUP); | ||
1711 | #undef DUP | ||
1712 | 1775 | ||
1713 | i915_capture_gen_state(error->i915, error); | 1776 | i915_capture_gen_state(error->i915, error); |
1714 | i915_capture_reg_state(error->i915, error); | 1777 | i915_capture_reg_state(error->i915, error); |
@@ -1716,7 +1779,6 @@ static int capture(void *data) | |||
1716 | i915_gem_record_rings(error->i915, error); | 1779 | i915_gem_record_rings(error->i915, error); |
1717 | i915_capture_active_buffers(error->i915, error); | 1780 | i915_capture_active_buffers(error->i915, error); |
1718 | i915_capture_pinned_buffers(error->i915, error); | 1781 | i915_capture_pinned_buffers(error->i915, error); |
1719 | i915_gem_capture_guc_log_buffer(error->i915, error); | ||
1720 | 1782 | ||
1721 | error->overlay = intel_overlay_capture_error_state(error->i915); | 1783 | error->overlay = intel_overlay_capture_error_state(error->i915); |
1722 | error->display = intel_display_capture_error_state(error->i915); | 1784 | error->display = intel_display_capture_error_state(error->i915); |
diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h b/drivers/gpu/drm/i915/i915_guc_reg.h index 35cf9918d09a..bc1ae7d8f424 100644 --- a/drivers/gpu/drm/i915/i915_guc_reg.h +++ b/drivers/gpu/drm/i915/i915_guc_reg.h | |||
@@ -102,13 +102,6 @@ | |||
102 | #define GUC_ENABLE_MIA_CLOCK_GATING (1<<15) | 102 | #define GUC_ENABLE_MIA_CLOCK_GATING (1<<15) |
103 | #define GUC_GEN10_SHIM_WC_ENABLE (1<<21) | 103 | #define GUC_GEN10_SHIM_WC_ENABLE (1<<21) |
104 | 104 | ||
105 | #define GUC_SHIM_CONTROL_VALUE (GUC_DISABLE_SRAM_INIT_TO_ZEROES | \ | ||
106 | GUC_ENABLE_READ_CACHE_LOGIC | \ | ||
107 | GUC_ENABLE_MIA_CACHING | \ | ||
108 | GUC_ENABLE_READ_CACHE_FOR_SRAM_DATA | \ | ||
109 | GUC_ENABLE_READ_CACHE_FOR_WOPCM_DATA | \ | ||
110 | GUC_ENABLE_MIA_CLOCK_GATING) | ||
111 | |||
112 | #define GUC_SEND_INTERRUPT _MMIO(0xc4c8) | 105 | #define GUC_SEND_INTERRUPT _MMIO(0xc4c8) |
113 | #define GUC_SEND_TRIGGER (1<<0) | 106 | #define GUC_SEND_TRIGGER (1<<0) |
114 | 107 | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index f8205841868b..4fb183ae7a07 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -1068,6 +1068,9 @@ static void notify_ring(struct intel_engine_cs *engine) | |||
1068 | struct drm_i915_gem_request *rq = NULL; | 1068 | struct drm_i915_gem_request *rq = NULL; |
1069 | struct intel_wait *wait; | 1069 | struct intel_wait *wait; |
1070 | 1070 | ||
1071 | if (!engine->breadcrumbs.irq_armed) | ||
1072 | return; | ||
1073 | |||
1071 | atomic_inc(&engine->irq_count); | 1074 | atomic_inc(&engine->irq_count); |
1072 | set_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted); | 1075 | set_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted); |
1073 | 1076 | ||
@@ -1101,7 +1104,8 @@ static void notify_ring(struct intel_engine_cs *engine) | |||
1101 | if (wakeup) | 1104 | if (wakeup) |
1102 | wake_up_process(wait->tsk); | 1105 | wake_up_process(wait->tsk); |
1103 | } else { | 1106 | } else { |
1104 | __intel_engine_disarm_breadcrumbs(engine); | 1107 | if (engine->breadcrumbs.irq_armed) |
1108 | __intel_engine_disarm_breadcrumbs(engine); | ||
1105 | } | 1109 | } |
1106 | spin_unlock(&engine->breadcrumbs.irq_lock); | 1110 | spin_unlock(&engine->breadcrumbs.irq_lock); |
1107 | 1111 | ||
@@ -1400,7 +1404,7 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir, int test_shift) | |||
1400 | } | 1404 | } |
1401 | 1405 | ||
1402 | if (tasklet) | 1406 | if (tasklet) |
1403 | tasklet_hi_schedule(&execlists->irq_tasklet); | 1407 | tasklet_hi_schedule(&execlists->tasklet); |
1404 | } | 1408 | } |
1405 | 1409 | ||
1406 | static irqreturn_t gen8_gt_irq_ack(struct drm_i915_private *dev_priv, | 1410 | static irqreturn_t gen8_gt_irq_ack(struct drm_i915_private *dev_priv, |
diff --git a/drivers/gpu/drm/i915/i915_oa_bdw.c b/drivers/gpu/drm/i915/i915_oa_bdw.c index abdf4d0abcce..4abd2e8b5083 100644 --- a/drivers/gpu/drm/i915/i915_oa_bdw.c +++ b/drivers/gpu/drm/i915/i915_oa_bdw.c | |||
@@ -85,9 +85,9 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) | |||
85 | void | 85 | void |
86 | i915_perf_load_test_config_bdw(struct drm_i915_private *dev_priv) | 86 | i915_perf_load_test_config_bdw(struct drm_i915_private *dev_priv) |
87 | { | 87 | { |
88 | strncpy(dev_priv->perf.oa.test_config.uuid, | 88 | strlcpy(dev_priv->perf.oa.test_config.uuid, |
89 | "d6de6f55-e526-4f79-a6a6-d7315c09044e", | 89 | "d6de6f55-e526-4f79-a6a6-d7315c09044e", |
90 | UUID_STRING_LEN); | 90 | sizeof(dev_priv->perf.oa.test_config.uuid)); |
91 | dev_priv->perf.oa.test_config.id = 1; | 91 | dev_priv->perf.oa.test_config.id = 1; |
92 | 92 | ||
93 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; | 93 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; |
diff --git a/drivers/gpu/drm/i915/i915_oa_bxt.c b/drivers/gpu/drm/i915/i915_oa_bxt.c index b69b900de0fe..cb6f304ec16a 100644 --- a/drivers/gpu/drm/i915/i915_oa_bxt.c +++ b/drivers/gpu/drm/i915/i915_oa_bxt.c | |||
@@ -83,9 +83,9 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) | |||
83 | void | 83 | void |
84 | i915_perf_load_test_config_bxt(struct drm_i915_private *dev_priv) | 84 | i915_perf_load_test_config_bxt(struct drm_i915_private *dev_priv) |
85 | { | 85 | { |
86 | strncpy(dev_priv->perf.oa.test_config.uuid, | 86 | strlcpy(dev_priv->perf.oa.test_config.uuid, |
87 | "5ee72f5c-092f-421e-8b70-225f7c3e9612", | 87 | "5ee72f5c-092f-421e-8b70-225f7c3e9612", |
88 | UUID_STRING_LEN); | 88 | sizeof(dev_priv->perf.oa.test_config.uuid)); |
89 | dev_priv->perf.oa.test_config.id = 1; | 89 | dev_priv->perf.oa.test_config.id = 1; |
90 | 90 | ||
91 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; | 91 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; |
diff --git a/drivers/gpu/drm/i915/i915_oa_cflgt2.c b/drivers/gpu/drm/i915/i915_oa_cflgt2.c index 368c87d7ee9a..8641ae30e343 100644 --- a/drivers/gpu/drm/i915/i915_oa_cflgt2.c +++ b/drivers/gpu/drm/i915/i915_oa_cflgt2.c | |||
@@ -84,9 +84,9 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) | |||
84 | void | 84 | void |
85 | i915_perf_load_test_config_cflgt2(struct drm_i915_private *dev_priv) | 85 | i915_perf_load_test_config_cflgt2(struct drm_i915_private *dev_priv) |
86 | { | 86 | { |
87 | strncpy(dev_priv->perf.oa.test_config.uuid, | 87 | strlcpy(dev_priv->perf.oa.test_config.uuid, |
88 | "74fb4902-d3d3-4237-9e90-cbdc68d0a446", | 88 | "74fb4902-d3d3-4237-9e90-cbdc68d0a446", |
89 | UUID_STRING_LEN); | 89 | sizeof(dev_priv->perf.oa.test_config.uuid)); |
90 | dev_priv->perf.oa.test_config.id = 1; | 90 | dev_priv->perf.oa.test_config.id = 1; |
91 | 91 | ||
92 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; | 92 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; |
diff --git a/drivers/gpu/drm/i915/i915_oa_cflgt3.c b/drivers/gpu/drm/i915/i915_oa_cflgt3.c new file mode 100644 index 000000000000..42ff06fe54a3 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_cflgt3.c | |||
@@ -0,0 +1,109 @@ | |||
1 | /* | ||
2 | * Autogenerated file by GPU Top : https://github.com/rib/gputop | ||
3 | * DO NOT EDIT manually! | ||
4 | * | ||
5 | * | ||
6 | * Copyright (c) 2015 Intel Corporation | ||
7 | * | ||
8 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
9 | * copy of this software and associated documentation files (the "Software"), | ||
10 | * to deal in the Software without restriction, including without limitation | ||
11 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
12 | * and/or sell copies of the Software, and to permit persons to whom the | ||
13 | * Software is furnished to do so, subject to the following conditions: | ||
14 | * | ||
15 | * The above copyright notice and this permission notice (including the next | ||
16 | * paragraph) shall be included in all copies or substantial portions of the | ||
17 | * Software. | ||
18 | * | ||
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
22 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
24 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
25 | * IN THE SOFTWARE. | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #include <linux/sysfs.h> | ||
30 | |||
31 | #include "i915_drv.h" | ||
32 | #include "i915_oa_cflgt3.h" | ||
33 | |||
34 | static const struct i915_oa_reg b_counter_config_test_oa[] = { | ||
35 | { _MMIO(0x2740), 0x00000000 }, | ||
36 | { _MMIO(0x2744), 0x00800000 }, | ||
37 | { _MMIO(0x2714), 0xf0800000 }, | ||
38 | { _MMIO(0x2710), 0x00000000 }, | ||
39 | { _MMIO(0x2724), 0xf0800000 }, | ||
40 | { _MMIO(0x2720), 0x00000000 }, | ||
41 | { _MMIO(0x2770), 0x00000004 }, | ||
42 | { _MMIO(0x2774), 0x00000000 }, | ||
43 | { _MMIO(0x2778), 0x00000003 }, | ||
44 | { _MMIO(0x277c), 0x00000000 }, | ||
45 | { _MMIO(0x2780), 0x00000007 }, | ||
46 | { _MMIO(0x2784), 0x00000000 }, | ||
47 | { _MMIO(0x2788), 0x00100002 }, | ||
48 | { _MMIO(0x278c), 0x0000fff7 }, | ||
49 | { _MMIO(0x2790), 0x00100002 }, | ||
50 | { _MMIO(0x2794), 0x0000ffcf }, | ||
51 | { _MMIO(0x2798), 0x00100082 }, | ||
52 | { _MMIO(0x279c), 0x0000ffef }, | ||
53 | { _MMIO(0x27a0), 0x001000c2 }, | ||
54 | { _MMIO(0x27a4), 0x0000ffe7 }, | ||
55 | { _MMIO(0x27a8), 0x00100001 }, | ||
56 | { _MMIO(0x27ac), 0x0000ffe7 }, | ||
57 | }; | ||
58 | |||
59 | static const struct i915_oa_reg flex_eu_config_test_oa[] = { | ||
60 | }; | ||
61 | |||
62 | static const struct i915_oa_reg mux_config_test_oa[] = { | ||
63 | { _MMIO(0x9840), 0x00000080 }, | ||
64 | { _MMIO(0x9888), 0x11810000 }, | ||
65 | { _MMIO(0x9888), 0x07810013 }, | ||
66 | { _MMIO(0x9888), 0x1f810000 }, | ||
67 | { _MMIO(0x9888), 0x1d810000 }, | ||
68 | { _MMIO(0x9888), 0x1b930040 }, | ||
69 | { _MMIO(0x9888), 0x07e54000 }, | ||
70 | { _MMIO(0x9888), 0x1f908000 }, | ||
71 | { _MMIO(0x9888), 0x11900000 }, | ||
72 | { _MMIO(0x9888), 0x37900000 }, | ||
73 | { _MMIO(0x9888), 0x53900000 }, | ||
74 | { _MMIO(0x9888), 0x45900000 }, | ||
75 | { _MMIO(0x9888), 0x33900000 }, | ||
76 | }; | ||
77 | |||
78 | static ssize_t | ||
79 | show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) | ||
80 | { | ||
81 | return sprintf(buf, "1\n"); | ||
82 | } | ||
83 | |||
84 | void | ||
85 | i915_perf_load_test_config_cflgt3(struct drm_i915_private *dev_priv) | ||
86 | { | ||
87 | strncpy(dev_priv->perf.oa.test_config.uuid, | ||
88 | "577e8e2c-3fa0-4875-8743-3538d585e3b0", | ||
89 | UUID_STRING_LEN); | ||
90 | dev_priv->perf.oa.test_config.id = 1; | ||
91 | |||
92 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; | ||
93 | dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa); | ||
94 | |||
95 | dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa; | ||
96 | dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa); | ||
97 | |||
98 | dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa; | ||
99 | dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa); | ||
100 | |||
101 | dev_priv->perf.oa.test_config.sysfs_metric.name = "577e8e2c-3fa0-4875-8743-3538d585e3b0"; | ||
102 | dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs; | ||
103 | |||
104 | dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr; | ||
105 | |||
106 | dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id"; | ||
107 | dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444; | ||
108 | dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id; | ||
109 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_oa_cflgt3.h b/drivers/gpu/drm/i915/i915_oa_cflgt3.h new file mode 100644 index 000000000000..c13b5aac01b9 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_cflgt3.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * Autogenerated file by GPU Top : https://github.com/rib/gputop | ||
3 | * DO NOT EDIT manually! | ||
4 | * | ||
5 | * | ||
6 | * Copyright (c) 2015 Intel Corporation | ||
7 | * | ||
8 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
9 | * copy of this software and associated documentation files (the "Software"), | ||
10 | * to deal in the Software without restriction, including without limitation | ||
11 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
12 | * and/or sell copies of the Software, and to permit persons to whom the | ||
13 | * Software is furnished to do so, subject to the following conditions: | ||
14 | * | ||
15 | * The above copyright notice and this permission notice (including the next | ||
16 | * paragraph) shall be included in all copies or substantial portions of the | ||
17 | * Software. | ||
18 | * | ||
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
22 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
24 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
25 | * IN THE SOFTWARE. | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #ifndef __I915_OA_CFLGT3_H__ | ||
30 | #define __I915_OA_CFLGT3_H__ | ||
31 | |||
32 | extern void i915_perf_load_test_config_cflgt3(struct drm_i915_private *dev_priv); | ||
33 | |||
34 | #endif | ||
diff --git a/drivers/gpu/drm/i915/i915_oa_chv.c b/drivers/gpu/drm/i915/i915_oa_chv.c index 322a3f94cd16..556febb2c3c8 100644 --- a/drivers/gpu/drm/i915/i915_oa_chv.c +++ b/drivers/gpu/drm/i915/i915_oa_chv.c | |||
@@ -84,9 +84,9 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) | |||
84 | void | 84 | void |
85 | i915_perf_load_test_config_chv(struct drm_i915_private *dev_priv) | 85 | i915_perf_load_test_config_chv(struct drm_i915_private *dev_priv) |
86 | { | 86 | { |
87 | strncpy(dev_priv->perf.oa.test_config.uuid, | 87 | strlcpy(dev_priv->perf.oa.test_config.uuid, |
88 | "4a534b07-cba3-414d-8d60-874830e883aa", | 88 | "4a534b07-cba3-414d-8d60-874830e883aa", |
89 | UUID_STRING_LEN); | 89 | sizeof(dev_priv->perf.oa.test_config.uuid)); |
90 | dev_priv->perf.oa.test_config.id = 1; | 90 | dev_priv->perf.oa.test_config.id = 1; |
91 | 91 | ||
92 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; | 92 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; |
diff --git a/drivers/gpu/drm/i915/i915_oa_cnl.c b/drivers/gpu/drm/i915/i915_oa_cnl.c new file mode 100644 index 000000000000..ff0ac3627cc4 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_cnl.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | * Autogenerated file by GPU Top : https://github.com/rib/gputop | ||
3 | * DO NOT EDIT manually! | ||
4 | * | ||
5 | * | ||
6 | * Copyright (c) 2015 Intel Corporation | ||
7 | * | ||
8 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
9 | * copy of this software and associated documentation files (the "Software"), | ||
10 | * to deal in the Software without restriction, including without limitation | ||
11 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
12 | * and/or sell copies of the Software, and to permit persons to whom the | ||
13 | * Software is furnished to do so, subject to the following conditions: | ||
14 | * | ||
15 | * The above copyright notice and this permission notice (including the next | ||
16 | * paragraph) shall be included in all copies or substantial portions of the | ||
17 | * Software. | ||
18 | * | ||
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
22 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
24 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
25 | * IN THE SOFTWARE. | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #include <linux/sysfs.h> | ||
30 | |||
31 | #include "i915_drv.h" | ||
32 | #include "i915_oa_cnl.h" | ||
33 | |||
34 | static const struct i915_oa_reg b_counter_config_test_oa[] = { | ||
35 | { _MMIO(0x2740), 0x00000000 }, | ||
36 | { _MMIO(0x2710), 0x00000000 }, | ||
37 | { _MMIO(0x2714), 0xf0800000 }, | ||
38 | { _MMIO(0x2720), 0x00000000 }, | ||
39 | { _MMIO(0x2724), 0xf0800000 }, | ||
40 | { _MMIO(0x2770), 0x00000004 }, | ||
41 | { _MMIO(0x2774), 0x0000ffff }, | ||
42 | { _MMIO(0x2778), 0x00000003 }, | ||
43 | { _MMIO(0x277c), 0x0000ffff }, | ||
44 | { _MMIO(0x2780), 0x00000007 }, | ||
45 | { _MMIO(0x2784), 0x0000ffff }, | ||
46 | { _MMIO(0x2788), 0x00100002 }, | ||
47 | { _MMIO(0x278c), 0x0000fff7 }, | ||
48 | { _MMIO(0x2790), 0x00100002 }, | ||
49 | { _MMIO(0x2794), 0x0000ffcf }, | ||
50 | { _MMIO(0x2798), 0x00100082 }, | ||
51 | { _MMIO(0x279c), 0x0000ffef }, | ||
52 | { _MMIO(0x27a0), 0x001000c2 }, | ||
53 | { _MMIO(0x27a4), 0x0000ffe7 }, | ||
54 | { _MMIO(0x27a8), 0x00100001 }, | ||
55 | { _MMIO(0x27ac), 0x0000ffe7 }, | ||
56 | }; | ||
57 | |||
58 | static const struct i915_oa_reg flex_eu_config_test_oa[] = { | ||
59 | }; | ||
60 | |||
61 | static const struct i915_oa_reg mux_config_test_oa[] = { | ||
62 | { _MMIO(0xd04), 0x00000200 }, | ||
63 | { _MMIO(0x9884), 0x00000007 }, | ||
64 | { _MMIO(0x9888), 0x17060000 }, | ||
65 | { _MMIO(0x9840), 0x00000000 }, | ||
66 | { _MMIO(0x9884), 0x00000007 }, | ||
67 | { _MMIO(0x9888), 0x13034000 }, | ||
68 | { _MMIO(0x9884), 0x00000007 }, | ||
69 | { _MMIO(0x9888), 0x07060066 }, | ||
70 | { _MMIO(0x9884), 0x00000007 }, | ||
71 | { _MMIO(0x9888), 0x05060000 }, | ||
72 | { _MMIO(0x9884), 0x00000007 }, | ||
73 | { _MMIO(0x9888), 0x0f080040 }, | ||
74 | { _MMIO(0x9884), 0x00000007 }, | ||
75 | { _MMIO(0x9888), 0x07091000 }, | ||
76 | { _MMIO(0x9884), 0x00000007 }, | ||
77 | { _MMIO(0x9888), 0x0f041000 }, | ||
78 | { _MMIO(0x9884), 0x00000007 }, | ||
79 | { _MMIO(0x9888), 0x1d004000 }, | ||
80 | { _MMIO(0x9884), 0x00000007 }, | ||
81 | { _MMIO(0x9888), 0x35000000 }, | ||
82 | { _MMIO(0x9884), 0x00000007 }, | ||
83 | { _MMIO(0x9888), 0x49000000 }, | ||
84 | { _MMIO(0x9884), 0x00000007 }, | ||
85 | { _MMIO(0x9888), 0x3d000000 }, | ||
86 | { _MMIO(0x9884), 0x00000007 }, | ||
87 | { _MMIO(0x9888), 0x31000000 }, | ||
88 | }; | ||
89 | |||
90 | static ssize_t | ||
91 | show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) | ||
92 | { | ||
93 | return sprintf(buf, "1\n"); | ||
94 | } | ||
95 | |||
96 | void | ||
97 | i915_perf_load_test_config_cnl(struct drm_i915_private *dev_priv) | ||
98 | { | ||
99 | strncpy(dev_priv->perf.oa.test_config.uuid, | ||
100 | "db41edd4-d8e7-4730-ad11-b9a2d6833503", | ||
101 | UUID_STRING_LEN); | ||
102 | dev_priv->perf.oa.test_config.id = 1; | ||
103 | |||
104 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; | ||
105 | dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa); | ||
106 | |||
107 | dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa; | ||
108 | dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa); | ||
109 | |||
110 | dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa; | ||
111 | dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa); | ||
112 | |||
113 | dev_priv->perf.oa.test_config.sysfs_metric.name = "db41edd4-d8e7-4730-ad11-b9a2d6833503"; | ||
114 | dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs; | ||
115 | |||
116 | dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr; | ||
117 | |||
118 | dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id"; | ||
119 | dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444; | ||
120 | dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id; | ||
121 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_oa_cnl.h b/drivers/gpu/drm/i915/i915_oa_cnl.h new file mode 100644 index 000000000000..fb918b131105 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_oa_cnl.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * Autogenerated file by GPU Top : https://github.com/rib/gputop | ||
3 | * DO NOT EDIT manually! | ||
4 | * | ||
5 | * | ||
6 | * Copyright (c) 2015 Intel Corporation | ||
7 | * | ||
8 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
9 | * copy of this software and associated documentation files (the "Software"), | ||
10 | * to deal in the Software without restriction, including without limitation | ||
11 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
12 | * and/or sell copies of the Software, and to permit persons to whom the | ||
13 | * Software is furnished to do so, subject to the following conditions: | ||
14 | * | ||
15 | * The above copyright notice and this permission notice (including the next | ||
16 | * paragraph) shall be included in all copies or substantial portions of the | ||
17 | * Software. | ||
18 | * | ||
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
22 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
24 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
25 | * IN THE SOFTWARE. | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #ifndef __I915_OA_CNL_H__ | ||
30 | #define __I915_OA_CNL_H__ | ||
31 | |||
32 | extern void i915_perf_load_test_config_cnl(struct drm_i915_private *dev_priv); | ||
33 | |||
34 | #endif | ||
diff --git a/drivers/gpu/drm/i915/i915_oa_glk.c b/drivers/gpu/drm/i915/i915_oa_glk.c index 4ee527e4c926..971db587957c 100644 --- a/drivers/gpu/drm/i915/i915_oa_glk.c +++ b/drivers/gpu/drm/i915/i915_oa_glk.c | |||
@@ -83,9 +83,9 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) | |||
83 | void | 83 | void |
84 | i915_perf_load_test_config_glk(struct drm_i915_private *dev_priv) | 84 | i915_perf_load_test_config_glk(struct drm_i915_private *dev_priv) |
85 | { | 85 | { |
86 | strncpy(dev_priv->perf.oa.test_config.uuid, | 86 | strlcpy(dev_priv->perf.oa.test_config.uuid, |
87 | "dd3fd789-e783-4204-8cd0-b671bbccb0cf", | 87 | "dd3fd789-e783-4204-8cd0-b671bbccb0cf", |
88 | UUID_STRING_LEN); | 88 | sizeof(dev_priv->perf.oa.test_config.uuid)); |
89 | dev_priv->perf.oa.test_config.id = 1; | 89 | dev_priv->perf.oa.test_config.id = 1; |
90 | 90 | ||
91 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; | 91 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; |
diff --git a/drivers/gpu/drm/i915/i915_oa_hsw.c b/drivers/gpu/drm/i915/i915_oa_hsw.c index 56b03773bb9d..434a9b96d7ab 100644 --- a/drivers/gpu/drm/i915/i915_oa_hsw.c +++ b/drivers/gpu/drm/i915/i915_oa_hsw.c | |||
@@ -113,9 +113,9 @@ show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *b | |||
113 | void | 113 | void |
114 | i915_perf_load_test_config_hsw(struct drm_i915_private *dev_priv) | 114 | i915_perf_load_test_config_hsw(struct drm_i915_private *dev_priv) |
115 | { | 115 | { |
116 | strncpy(dev_priv->perf.oa.test_config.uuid, | 116 | strlcpy(dev_priv->perf.oa.test_config.uuid, |
117 | "403d8832-1a27-4aa6-a64e-f5389ce7b212", | 117 | "403d8832-1a27-4aa6-a64e-f5389ce7b212", |
118 | UUID_STRING_LEN); | 118 | sizeof(dev_priv->perf.oa.test_config.uuid)); |
119 | dev_priv->perf.oa.test_config.id = 1; | 119 | dev_priv->perf.oa.test_config.id = 1; |
120 | 120 | ||
121 | dev_priv->perf.oa.test_config.mux_regs = mux_config_render_basic; | 121 | dev_priv->perf.oa.test_config.mux_regs = mux_config_render_basic; |
diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt2.c b/drivers/gpu/drm/i915/i915_oa_kblgt2.c index b6e7cc774136..2fa98a40bbc8 100644 --- a/drivers/gpu/drm/i915/i915_oa_kblgt2.c +++ b/drivers/gpu/drm/i915/i915_oa_kblgt2.c | |||
@@ -84,9 +84,9 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) | |||
84 | void | 84 | void |
85 | i915_perf_load_test_config_kblgt2(struct drm_i915_private *dev_priv) | 85 | i915_perf_load_test_config_kblgt2(struct drm_i915_private *dev_priv) |
86 | { | 86 | { |
87 | strncpy(dev_priv->perf.oa.test_config.uuid, | 87 | strlcpy(dev_priv->perf.oa.test_config.uuid, |
88 | "baa3c7e4-52b6-4b85-801e-465a94b746dd", | 88 | "baa3c7e4-52b6-4b85-801e-465a94b746dd", |
89 | UUID_STRING_LEN); | 89 | sizeof(dev_priv->perf.oa.test_config.uuid)); |
90 | dev_priv->perf.oa.test_config.id = 1; | 90 | dev_priv->perf.oa.test_config.id = 1; |
91 | 91 | ||
92 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; | 92 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; |
diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt3.c b/drivers/gpu/drm/i915/i915_oa_kblgt3.c index 5576afdd9a7e..f3cb6679a1bc 100644 --- a/drivers/gpu/drm/i915/i915_oa_kblgt3.c +++ b/drivers/gpu/drm/i915/i915_oa_kblgt3.c | |||
@@ -84,9 +84,9 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) | |||
84 | void | 84 | void |
85 | i915_perf_load_test_config_kblgt3(struct drm_i915_private *dev_priv) | 85 | i915_perf_load_test_config_kblgt3(struct drm_i915_private *dev_priv) |
86 | { | 86 | { |
87 | strncpy(dev_priv->perf.oa.test_config.uuid, | 87 | strlcpy(dev_priv->perf.oa.test_config.uuid, |
88 | "f1792f32-6db2-4b50-b4b2-557128f1688d", | 88 | "f1792f32-6db2-4b50-b4b2-557128f1688d", |
89 | UUID_STRING_LEN); | 89 | sizeof(dev_priv->perf.oa.test_config.uuid)); |
90 | dev_priv->perf.oa.test_config.id = 1; | 90 | dev_priv->perf.oa.test_config.id = 1; |
91 | 91 | ||
92 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; | 92 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; |
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt2.c b/drivers/gpu/drm/i915/i915_oa_sklgt2.c index 890d55879946..bf8b8cd8a50d 100644 --- a/drivers/gpu/drm/i915/i915_oa_sklgt2.c +++ b/drivers/gpu/drm/i915/i915_oa_sklgt2.c | |||
@@ -83,9 +83,9 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) | |||
83 | void | 83 | void |
84 | i915_perf_load_test_config_sklgt2(struct drm_i915_private *dev_priv) | 84 | i915_perf_load_test_config_sklgt2(struct drm_i915_private *dev_priv) |
85 | { | 85 | { |
86 | strncpy(dev_priv->perf.oa.test_config.uuid, | 86 | strlcpy(dev_priv->perf.oa.test_config.uuid, |
87 | "1651949f-0ac0-4cb1-a06f-dafd74a407d1", | 87 | "1651949f-0ac0-4cb1-a06f-dafd74a407d1", |
88 | UUID_STRING_LEN); | 88 | sizeof(dev_priv->perf.oa.test_config.uuid)); |
89 | dev_priv->perf.oa.test_config.id = 1; | 89 | dev_priv->perf.oa.test_config.id = 1; |
90 | 90 | ||
91 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; | 91 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; |
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt3.c b/drivers/gpu/drm/i915/i915_oa_sklgt3.c index 85e51addf86a..ae534c7c8135 100644 --- a/drivers/gpu/drm/i915/i915_oa_sklgt3.c +++ b/drivers/gpu/drm/i915/i915_oa_sklgt3.c | |||
@@ -84,9 +84,9 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) | |||
84 | void | 84 | void |
85 | i915_perf_load_test_config_sklgt3(struct drm_i915_private *dev_priv) | 85 | i915_perf_load_test_config_sklgt3(struct drm_i915_private *dev_priv) |
86 | { | 86 | { |
87 | strncpy(dev_priv->perf.oa.test_config.uuid, | 87 | strlcpy(dev_priv->perf.oa.test_config.uuid, |
88 | "2b985803-d3c9-4629-8a4f-634bfecba0e8", | 88 | "2b985803-d3c9-4629-8a4f-634bfecba0e8", |
89 | UUID_STRING_LEN); | 89 | sizeof(dev_priv->perf.oa.test_config.uuid)); |
90 | dev_priv->perf.oa.test_config.id = 1; | 90 | dev_priv->perf.oa.test_config.id = 1; |
91 | 91 | ||
92 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; | 92 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; |
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt4.c b/drivers/gpu/drm/i915/i915_oa_sklgt4.c index bce031ee4445..817fba2d82df 100644 --- a/drivers/gpu/drm/i915/i915_oa_sklgt4.c +++ b/drivers/gpu/drm/i915/i915_oa_sklgt4.c | |||
@@ -84,9 +84,9 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf) | |||
84 | void | 84 | void |
85 | i915_perf_load_test_config_sklgt4(struct drm_i915_private *dev_priv) | 85 | i915_perf_load_test_config_sklgt4(struct drm_i915_private *dev_priv) |
86 | { | 86 | { |
87 | strncpy(dev_priv->perf.oa.test_config.uuid, | 87 | strlcpy(dev_priv->perf.oa.test_config.uuid, |
88 | "882fa433-1f4a-4a67-a962-c741888fe5f5", | 88 | "882fa433-1f4a-4a67-a962-c741888fe5f5", |
89 | UUID_STRING_LEN); | 89 | sizeof(dev_priv->perf.oa.test_config.uuid)); |
90 | dev_priv->perf.oa.test_config.id = 1; | 90 | dev_priv->perf.oa.test_config.id = 1; |
91 | 91 | ||
92 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; | 92 | dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa; |
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index 59ee808f8fd9..00be015e01df 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c | |||
@@ -207,6 +207,8 @@ | |||
207 | #include "i915_oa_kblgt3.h" | 207 | #include "i915_oa_kblgt3.h" |
208 | #include "i915_oa_glk.h" | 208 | #include "i915_oa_glk.h" |
209 | #include "i915_oa_cflgt2.h" | 209 | #include "i915_oa_cflgt2.h" |
210 | #include "i915_oa_cflgt3.h" | ||
211 | #include "i915_oa_cnl.h" | ||
210 | 212 | ||
211 | /* HW requires this to be a power of two, between 128k and 16M, though driver | 213 | /* HW requires this to be a power of two, between 128k and 16M, though driver |
212 | * is currently generally designed assuming the largest 16M size is used such | 214 | * is currently generally designed assuming the largest 16M size is used such |
@@ -1851,7 +1853,7 @@ static int gen8_enable_metric_set(struct drm_i915_private *dev_priv, | |||
1851 | * be read back from automatically triggered reports, as part of the | 1853 | * be read back from automatically triggered reports, as part of the |
1852 | * RPT_ID field. | 1854 | * RPT_ID field. |
1853 | */ | 1855 | */ |
1854 | if (IS_GEN9(dev_priv)) { | 1856 | if (IS_GEN9(dev_priv) || IS_GEN10(dev_priv)) { |
1855 | I915_WRITE(GEN8_OA_DEBUG, | 1857 | I915_WRITE(GEN8_OA_DEBUG, |
1856 | _MASKED_BIT_ENABLE(GEN9_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS | | 1858 | _MASKED_BIT_ENABLE(GEN9_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS | |
1857 | GEN9_OA_DEBUG_INCLUDE_CLK_RATIO)); | 1859 | GEN9_OA_DEBUG_INCLUDE_CLK_RATIO)); |
@@ -1884,6 +1886,16 @@ static void gen8_disable_metric_set(struct drm_i915_private *dev_priv) | |||
1884 | 1886 | ||
1885 | } | 1887 | } |
1886 | 1888 | ||
1889 | static void gen10_disable_metric_set(struct drm_i915_private *dev_priv) | ||
1890 | { | ||
1891 | /* Reset all contexts' slices/subslices configurations. */ | ||
1892 | gen8_configure_all_contexts(dev_priv, NULL, false); | ||
1893 | |||
1894 | /* Make sure we disable noa to save power. */ | ||
1895 | I915_WRITE(RPM_CONFIG1, | ||
1896 | I915_READ(RPM_CONFIG1) & ~GEN10_GT_NOA_ENABLE); | ||
1897 | } | ||
1898 | |||
1887 | static void gen7_oa_enable(struct drm_i915_private *dev_priv) | 1899 | static void gen7_oa_enable(struct drm_i915_private *dev_priv) |
1888 | { | 1900 | { |
1889 | /* | 1901 | /* |
@@ -2934,6 +2946,10 @@ void i915_perf_register(struct drm_i915_private *dev_priv) | |||
2934 | } else if (IS_COFFEELAKE(dev_priv)) { | 2946 | } else if (IS_COFFEELAKE(dev_priv)) { |
2935 | if (IS_CFL_GT2(dev_priv)) | 2947 | if (IS_CFL_GT2(dev_priv)) |
2936 | i915_perf_load_test_config_cflgt2(dev_priv); | 2948 | i915_perf_load_test_config_cflgt2(dev_priv); |
2949 | if (IS_CFL_GT3(dev_priv)) | ||
2950 | i915_perf_load_test_config_cflgt3(dev_priv); | ||
2951 | } else if (IS_CANNONLAKE(dev_priv)) { | ||
2952 | i915_perf_load_test_config_cnl(dev_priv); | ||
2937 | } | 2953 | } |
2938 | 2954 | ||
2939 | if (dev_priv->perf.oa.test_config.id == 0) | 2955 | if (dev_priv->perf.oa.test_config.id == 0) |
@@ -3019,11 +3035,18 @@ static bool gen8_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr) | |||
3019 | (addr >= RPM_CONFIG0.reg && addr <= NOA_CONFIG(8).reg); | 3035 | (addr >= RPM_CONFIG0.reg && addr <= NOA_CONFIG(8).reg); |
3020 | } | 3036 | } |
3021 | 3037 | ||
3038 | static bool gen10_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr) | ||
3039 | { | ||
3040 | return gen8_is_valid_mux_addr(dev_priv, addr) || | ||
3041 | (addr >= OA_PERFCNT3_LO.reg && addr <= OA_PERFCNT4_HI.reg); | ||
3042 | } | ||
3043 | |||
3022 | static bool hsw_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr) | 3044 | static bool hsw_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr) |
3023 | { | 3045 | { |
3024 | return gen7_is_valid_mux_addr(dev_priv, addr) || | 3046 | return gen7_is_valid_mux_addr(dev_priv, addr) || |
3025 | (addr >= 0x25100 && addr <= 0x2FF90) || | 3047 | (addr >= 0x25100 && addr <= 0x2FF90) || |
3026 | addr == 0x9ec0; | 3048 | (addr >= HSW_MBVID2_NOA0.reg && addr <= HSW_MBVID2_NOA9.reg) || |
3049 | addr == HSW_MBVID2_MISR0.reg; | ||
3027 | } | 3050 | } |
3028 | 3051 | ||
3029 | static bool chv_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr) | 3052 | static bool chv_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr) |
@@ -3419,41 +3442,46 @@ void i915_perf_init(struct drm_i915_private *dev_priv) | |||
3419 | * worth the complexity to maintain now that BDW+ enable | 3442 | * worth the complexity to maintain now that BDW+ enable |
3420 | * execlist mode by default. | 3443 | * execlist mode by default. |
3421 | */ | 3444 | */ |
3422 | dev_priv->perf.oa.ops.is_valid_b_counter_reg = | 3445 | dev_priv->perf.oa.oa_formats = gen8_plus_oa_formats; |
3423 | gen7_is_valid_b_counter_addr; | ||
3424 | dev_priv->perf.oa.ops.is_valid_mux_reg = | ||
3425 | gen8_is_valid_mux_addr; | ||
3426 | dev_priv->perf.oa.ops.is_valid_flex_reg = | ||
3427 | gen8_is_valid_flex_addr; | ||
3428 | 3446 | ||
3429 | dev_priv->perf.oa.ops.init_oa_buffer = gen8_init_oa_buffer; | 3447 | dev_priv->perf.oa.ops.init_oa_buffer = gen8_init_oa_buffer; |
3430 | dev_priv->perf.oa.ops.enable_metric_set = gen8_enable_metric_set; | ||
3431 | dev_priv->perf.oa.ops.disable_metric_set = gen8_disable_metric_set; | ||
3432 | dev_priv->perf.oa.ops.oa_enable = gen8_oa_enable; | 3448 | dev_priv->perf.oa.ops.oa_enable = gen8_oa_enable; |
3433 | dev_priv->perf.oa.ops.oa_disable = gen8_oa_disable; | 3449 | dev_priv->perf.oa.ops.oa_disable = gen8_oa_disable; |
3434 | dev_priv->perf.oa.ops.read = gen8_oa_read; | 3450 | dev_priv->perf.oa.ops.read = gen8_oa_read; |
3435 | dev_priv->perf.oa.ops.oa_hw_tail_read = gen8_oa_hw_tail_read; | 3451 | dev_priv->perf.oa.ops.oa_hw_tail_read = gen8_oa_hw_tail_read; |
3436 | 3452 | ||
3437 | dev_priv->perf.oa.oa_formats = gen8_plus_oa_formats; | 3453 | if (IS_GEN8(dev_priv) || IS_GEN9(dev_priv)) { |
3438 | 3454 | dev_priv->perf.oa.ops.is_valid_b_counter_reg = | |
3439 | if (IS_GEN8(dev_priv)) { | 3455 | gen7_is_valid_b_counter_addr; |
3440 | dev_priv->perf.oa.ctx_oactxctrl_offset = 0x120; | 3456 | dev_priv->perf.oa.ops.is_valid_mux_reg = |
3441 | dev_priv->perf.oa.ctx_flexeu0_offset = 0x2ce; | 3457 | gen8_is_valid_mux_addr; |
3442 | 3458 | dev_priv->perf.oa.ops.is_valid_flex_reg = | |
3443 | dev_priv->perf.oa.timestamp_frequency = 12500000; | 3459 | gen8_is_valid_flex_addr; |
3444 | 3460 | ||
3445 | dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<25); | ||
3446 | if (IS_CHERRYVIEW(dev_priv)) { | 3461 | if (IS_CHERRYVIEW(dev_priv)) { |
3447 | dev_priv->perf.oa.ops.is_valid_mux_reg = | 3462 | dev_priv->perf.oa.ops.is_valid_mux_reg = |
3448 | chv_is_valid_mux_addr; | 3463 | chv_is_valid_mux_addr; |
3449 | } | 3464 | } |
3450 | } else if (IS_GEN9(dev_priv)) { | ||
3451 | dev_priv->perf.oa.ctx_oactxctrl_offset = 0x128; | ||
3452 | dev_priv->perf.oa.ctx_flexeu0_offset = 0x3de; | ||
3453 | 3465 | ||
3454 | dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<16); | 3466 | dev_priv->perf.oa.ops.enable_metric_set = gen8_enable_metric_set; |
3467 | dev_priv->perf.oa.ops.disable_metric_set = gen8_disable_metric_set; | ||
3468 | |||
3469 | if (IS_GEN8(dev_priv)) { | ||
3470 | dev_priv->perf.oa.ctx_oactxctrl_offset = 0x120; | ||
3471 | dev_priv->perf.oa.ctx_flexeu0_offset = 0x2ce; | ||
3472 | |||
3473 | dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<25); | ||
3474 | } else { | ||
3475 | dev_priv->perf.oa.ctx_oactxctrl_offset = 0x128; | ||
3476 | dev_priv->perf.oa.ctx_flexeu0_offset = 0x3de; | ||
3477 | |||
3478 | dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<16); | ||
3479 | } | ||
3455 | 3480 | ||
3456 | switch (dev_priv->info.platform) { | 3481 | switch (dev_priv->info.platform) { |
3482 | case INTEL_BROADWELL: | ||
3483 | dev_priv->perf.oa.timestamp_frequency = 12500000; | ||
3484 | break; | ||
3457 | case INTEL_BROXTON: | 3485 | case INTEL_BROXTON: |
3458 | case INTEL_GEMINILAKE: | 3486 | case INTEL_GEMINILAKE: |
3459 | dev_priv->perf.oa.timestamp_frequency = 19200000; | 3487 | dev_priv->perf.oa.timestamp_frequency = 19200000; |
@@ -3464,11 +3492,28 @@ void i915_perf_init(struct drm_i915_private *dev_priv) | |||
3464 | dev_priv->perf.oa.timestamp_frequency = 12000000; | 3492 | dev_priv->perf.oa.timestamp_frequency = 12000000; |
3465 | break; | 3493 | break; |
3466 | default: | 3494 | default: |
3467 | /* Leave timestamp_frequency to 0 so we can | ||
3468 | * detect unsupported platforms. | ||
3469 | */ | ||
3470 | break; | 3495 | break; |
3471 | } | 3496 | } |
3497 | } else if (IS_GEN10(dev_priv)) { | ||
3498 | dev_priv->perf.oa.ops.is_valid_b_counter_reg = | ||
3499 | gen7_is_valid_b_counter_addr; | ||
3500 | dev_priv->perf.oa.ops.is_valid_mux_reg = | ||
3501 | gen10_is_valid_mux_addr; | ||
3502 | dev_priv->perf.oa.ops.is_valid_flex_reg = | ||
3503 | gen8_is_valid_flex_addr; | ||
3504 | |||
3505 | dev_priv->perf.oa.ops.enable_metric_set = gen8_enable_metric_set; | ||
3506 | dev_priv->perf.oa.ops.disable_metric_set = gen10_disable_metric_set; | ||
3507 | |||
3508 | dev_priv->perf.oa.ctx_oactxctrl_offset = 0x128; | ||
3509 | dev_priv->perf.oa.ctx_flexeu0_offset = 0x3de; | ||
3510 | |||
3511 | dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<16); | ||
3512 | |||
3513 | /* Default frequency, although we need to read it from | ||
3514 | * the register as it might vary between parts. | ||
3515 | */ | ||
3516 | dev_priv->perf.oa.timestamp_frequency = 12000000; | ||
3472 | } | 3517 | } |
3473 | } | 3518 | } |
3474 | 3519 | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 68a58cce6ab1..96c80fa0fcac 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -355,9 +355,6 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) | |||
355 | #define ECOCHK_PPGTT_WT_HSW (0x2<<3) | 355 | #define ECOCHK_PPGTT_WT_HSW (0x2<<3) |
356 | #define ECOCHK_PPGTT_WB_HSW (0x3<<3) | 356 | #define ECOCHK_PPGTT_WB_HSW (0x3<<3) |
357 | 357 | ||
358 | #define GEN8_CONFIG0 _MMIO(0xD00) | ||
359 | #define GEN9_DEFAULT_FIXES (1 << 3 | 1 << 2 | 1 << 1) | ||
360 | |||
361 | #define GAC_ECO_BITS _MMIO(0x14090) | 358 | #define GAC_ECO_BITS _MMIO(0x14090) |
362 | #define ECOBITS_SNB_BIT (1<<13) | 359 | #define ECOBITS_SNB_BIT (1<<13) |
363 | #define ECOBITS_PPGTT_CACHE64B (3<<8) | 360 | #define ECOBITS_PPGTT_CACHE64B (3<<8) |
@@ -382,6 +379,7 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) | |||
382 | #define GEN8_STOLEN_RESERVED_2M (1 << 7) | 379 | #define GEN8_STOLEN_RESERVED_2M (1 << 7) |
383 | #define GEN8_STOLEN_RESERVED_4M (2 << 7) | 380 | #define GEN8_STOLEN_RESERVED_4M (2 << 7) |
384 | #define GEN8_STOLEN_RESERVED_8M (3 << 7) | 381 | #define GEN8_STOLEN_RESERVED_8M (3 << 7) |
382 | #define GEN6_STOLEN_RESERVED_ENABLE (1 << 0) | ||
385 | 383 | ||
386 | /* VGA stuff */ | 384 | /* VGA stuff */ |
387 | 385 | ||
@@ -1109,16 +1107,50 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) | |||
1109 | #define OA_PERFCNT1_HI _MMIO(0x91BC) | 1107 | #define OA_PERFCNT1_HI _MMIO(0x91BC) |
1110 | #define OA_PERFCNT2_LO _MMIO(0x91C0) | 1108 | #define OA_PERFCNT2_LO _MMIO(0x91C0) |
1111 | #define OA_PERFCNT2_HI _MMIO(0x91C4) | 1109 | #define OA_PERFCNT2_HI _MMIO(0x91C4) |
1110 | #define OA_PERFCNT3_LO _MMIO(0x91C8) | ||
1111 | #define OA_PERFCNT3_HI _MMIO(0x91CC) | ||
1112 | #define OA_PERFCNT4_LO _MMIO(0x91D8) | ||
1113 | #define OA_PERFCNT4_HI _MMIO(0x91DC) | ||
1112 | 1114 | ||
1113 | #define OA_PERFMATRIX_LO _MMIO(0x91C8) | 1115 | #define OA_PERFMATRIX_LO _MMIO(0x91C8) |
1114 | #define OA_PERFMATRIX_HI _MMIO(0x91CC) | 1116 | #define OA_PERFMATRIX_HI _MMIO(0x91CC) |
1115 | 1117 | ||
1116 | /* RPM unit config (Gen8+) */ | 1118 | /* RPM unit config (Gen8+) */ |
1117 | #define RPM_CONFIG0 _MMIO(0x0D00) | 1119 | #define RPM_CONFIG0 _MMIO(0x0D00) |
1118 | #define RPM_CONFIG1 _MMIO(0x0D04) | 1120 | #define GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT 3 |
1121 | #define GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK (1 << GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT) | ||
1122 | #define GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ 0 | ||
1123 | #define GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ 1 | ||
1124 | #define GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT 1 | ||
1125 | #define GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK (0x3 << GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT) | ||
1119 | 1126 | ||
1120 | /* RPC unit config (Gen8+) */ | 1127 | #define RPM_CONFIG1 _MMIO(0x0D04) |
1121 | #define RPM_CONFIG _MMIO(0x0D08) | 1128 | #define GEN10_GT_NOA_ENABLE (1 << 9) |
1129 | |||
1130 | /* GPM unit config (Gen9+) */ | ||
1131 | #define CTC_MODE _MMIO(0xA26C) | ||
1132 | #define CTC_SOURCE_PARAMETER_MASK 1 | ||
1133 | #define CTC_SOURCE_CRYSTAL_CLOCK 0 | ||
1134 | #define CTC_SOURCE_DIVIDE_LOGIC 1 | ||
1135 | #define CTC_SHIFT_PARAMETER_SHIFT 1 | ||
1136 | #define CTC_SHIFT_PARAMETER_MASK (0x3 << CTC_SHIFT_PARAMETER_SHIFT) | ||
1137 | |||
1138 | /* RCP unit config (Gen8+) */ | ||
1139 | #define RCP_CONFIG _MMIO(0x0D08) | ||
1140 | |||
1141 | /* NOA (HSW) */ | ||
1142 | #define HSW_MBVID2_NOA0 _MMIO(0x9E80) | ||
1143 | #define HSW_MBVID2_NOA1 _MMIO(0x9E84) | ||
1144 | #define HSW_MBVID2_NOA2 _MMIO(0x9E88) | ||
1145 | #define HSW_MBVID2_NOA3 _MMIO(0x9E8C) | ||
1146 | #define HSW_MBVID2_NOA4 _MMIO(0x9E90) | ||
1147 | #define HSW_MBVID2_NOA5 _MMIO(0x9E94) | ||
1148 | #define HSW_MBVID2_NOA6 _MMIO(0x9E98) | ||
1149 | #define HSW_MBVID2_NOA7 _MMIO(0x9E9C) | ||
1150 | #define HSW_MBVID2_NOA8 _MMIO(0x9EA0) | ||
1151 | #define HSW_MBVID2_NOA9 _MMIO(0x9EA4) | ||
1152 | |||
1153 | #define HSW_MBVID2_MISR0 _MMIO(0x9EC0) | ||
1122 | 1154 | ||
1123 | /* NOA (Gen8+) */ | 1155 | /* NOA (Gen8+) */ |
1124 | #define NOA_CONFIG(i) _MMIO(0x0D0C + (i) * 4) | 1156 | #define NOA_CONFIG(i) _MMIO(0x0D0C + (i) * 4) |
@@ -2329,6 +2361,8 @@ enum i915_power_well_id { | |||
2329 | #define ARB_MODE_SWIZZLE_BDW (1<<1) | 2361 | #define ARB_MODE_SWIZZLE_BDW (1<<1) |
2330 | #define RENDER_HWS_PGA_GEN7 _MMIO(0x04080) | 2362 | #define RENDER_HWS_PGA_GEN7 _MMIO(0x04080) |
2331 | #define RING_FAULT_REG(engine) _MMIO(0x4094 + 0x100*(engine)->hw_id) | 2363 | #define RING_FAULT_REG(engine) _MMIO(0x4094 + 0x100*(engine)->hw_id) |
2364 | #define GEN8_RING_FAULT_REG _MMIO(0x4094) | ||
2365 | #define GEN8_RING_FAULT_ENGINE_ID(x) (((x) >> 12) & 0x7) | ||
2332 | #define RING_FAULT_GTTSEL_MASK (1<<11) | 2366 | #define RING_FAULT_GTTSEL_MASK (1<<11) |
2333 | #define RING_FAULT_SRCID(x) (((x) >> 3) & 0xff) | 2367 | #define RING_FAULT_SRCID(x) (((x) >> 3) & 0xff) |
2334 | #define RING_FAULT_FAULT_TYPE(x) (((x) >> 1) & 0x3) | 2368 | #define RING_FAULT_FAULT_TYPE(x) (((x) >> 1) & 0x3) |
@@ -2951,9 +2985,6 @@ enum i915_power_well_id { | |||
2951 | #define ILK_DPFC_CHICKEN _MMIO(0x43224) | 2985 | #define ILK_DPFC_CHICKEN _MMIO(0x43224) |
2952 | #define ILK_DPFC_DISABLE_DUMMY0 (1<<8) | 2986 | #define ILK_DPFC_DISABLE_DUMMY0 (1<<8) |
2953 | #define ILK_DPFC_NUKE_ON_ANY_MODIFICATION (1<<23) | 2987 | #define ILK_DPFC_NUKE_ON_ANY_MODIFICATION (1<<23) |
2954 | #define GLK_SKIP_SEG_EN (1<<12) | ||
2955 | #define GLK_SKIP_SEG_COUNT_MASK (3<<10) | ||
2956 | #define GLK_SKIP_SEG_COUNT(x) ((x)<<10) | ||
2957 | #define ILK_FBC_RT_BASE _MMIO(0x2128) | 2988 | #define ILK_FBC_RT_BASE _MMIO(0x2128) |
2958 | #define ILK_FBC_RT_VALID (1<<0) | 2989 | #define ILK_FBC_RT_VALID (1<<0) |
2959 | #define SNB_FBC_FRONT_BUFFER (1<<1) | 2990 | #define SNB_FBC_FRONT_BUFFER (1<<1) |
@@ -3398,6 +3429,7 @@ enum i915_power_well_id { | |||
3398 | #define ELK_STOLEN_RESERVED _MMIO(MCHBAR_MIRROR_BASE + 0x48) | 3429 | #define ELK_STOLEN_RESERVED _MMIO(MCHBAR_MIRROR_BASE + 0x48) |
3399 | #define G4X_STOLEN_RESERVED_ADDR1_MASK (0xFFFF << 16) | 3430 | #define G4X_STOLEN_RESERVED_ADDR1_MASK (0xFFFF << 16) |
3400 | #define G4X_STOLEN_RESERVED_ADDR2_MASK (0xFFF << 4) | 3431 | #define G4X_STOLEN_RESERVED_ADDR2_MASK (0xFFF << 4) |
3432 | #define G4X_STOLEN_RESERVED_ENABLE (1 << 0) | ||
3401 | 3433 | ||
3402 | /* Memory controller frequency in MCHBAR for Haswell (possible SNB+) */ | 3434 | /* Memory controller frequency in MCHBAR for Haswell (possible SNB+) */ |
3403 | #define DCLK _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5e04) | 3435 | #define DCLK _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5e04) |
@@ -3819,6 +3851,7 @@ enum { | |||
3819 | * GEN9 clock gating regs | 3851 | * GEN9 clock gating regs |
3820 | */ | 3852 | */ |
3821 | #define GEN9_CLKGATE_DIS_0 _MMIO(0x46530) | 3853 | #define GEN9_CLKGATE_DIS_0 _MMIO(0x46530) |
3854 | #define DARBF_GATING_DIS (1 << 27) | ||
3822 | #define PWM2_GATING_DIS (1 << 14) | 3855 | #define PWM2_GATING_DIS (1 << 14) |
3823 | #define PWM1_GATING_DIS (1 << 13) | 3856 | #define PWM1_GATING_DIS (1 << 13) |
3824 | 3857 | ||
@@ -3837,6 +3870,7 @@ enum { | |||
3837 | */ | 3870 | */ |
3838 | #define SLICE_UNIT_LEVEL_CLKGATE _MMIO(0x94d4) | 3871 | #define SLICE_UNIT_LEVEL_CLKGATE _MMIO(0x94d4) |
3839 | #define SARBUNIT_CLKGATE_DIS (1 << 5) | 3872 | #define SARBUNIT_CLKGATE_DIS (1 << 5) |
3873 | #define RCCUNIT_CLKGATE_DIS (1 << 7) | ||
3840 | 3874 | ||
3841 | /* | 3875 | /* |
3842 | * Display engine regs | 3876 | * Display engine regs |
@@ -6263,7 +6297,7 @@ enum { | |||
6263 | #define _PLANE_CTL_2_A 0x70280 | 6297 | #define _PLANE_CTL_2_A 0x70280 |
6264 | #define _PLANE_CTL_3_A 0x70380 | 6298 | #define _PLANE_CTL_3_A 0x70380 |
6265 | #define PLANE_CTL_ENABLE (1 << 31) | 6299 | #define PLANE_CTL_ENABLE (1 << 31) |
6266 | #define PLANE_CTL_PIPE_GAMMA_ENABLE (1 << 30) | 6300 | #define PLANE_CTL_PIPE_GAMMA_ENABLE (1 << 30) /* Pre-GLK */ |
6267 | #define PLANE_CTL_FORMAT_MASK (0xf << 24) | 6301 | #define PLANE_CTL_FORMAT_MASK (0xf << 24) |
6268 | #define PLANE_CTL_FORMAT_YUV422 ( 0 << 24) | 6302 | #define PLANE_CTL_FORMAT_YUV422 ( 0 << 24) |
6269 | #define PLANE_CTL_FORMAT_NV12 ( 1 << 24) | 6303 | #define PLANE_CTL_FORMAT_NV12 ( 1 << 24) |
@@ -6273,7 +6307,7 @@ enum { | |||
6273 | #define PLANE_CTL_FORMAT_AYUV ( 8 << 24) | 6307 | #define PLANE_CTL_FORMAT_AYUV ( 8 << 24) |
6274 | #define PLANE_CTL_FORMAT_INDEXED ( 12 << 24) | 6308 | #define PLANE_CTL_FORMAT_INDEXED ( 12 << 24) |
6275 | #define PLANE_CTL_FORMAT_RGB_565 ( 14 << 24) | 6309 | #define PLANE_CTL_FORMAT_RGB_565 ( 14 << 24) |
6276 | #define PLANE_CTL_PIPE_CSC_ENABLE (1 << 23) | 6310 | #define PLANE_CTL_PIPE_CSC_ENABLE (1 << 23) /* Pre-GLK */ |
6277 | #define PLANE_CTL_KEY_ENABLE_MASK (0x3 << 21) | 6311 | #define PLANE_CTL_KEY_ENABLE_MASK (0x3 << 21) |
6278 | #define PLANE_CTL_KEY_ENABLE_SOURCE ( 1 << 21) | 6312 | #define PLANE_CTL_KEY_ENABLE_SOURCE ( 1 << 21) |
6279 | #define PLANE_CTL_KEY_ENABLE_DESTINATION ( 2 << 21) | 6313 | #define PLANE_CTL_KEY_ENABLE_DESTINATION ( 2 << 21) |
@@ -6286,13 +6320,13 @@ enum { | |||
6286 | #define PLANE_CTL_YUV422_VYUY ( 3 << 16) | 6320 | #define PLANE_CTL_YUV422_VYUY ( 3 << 16) |
6287 | #define PLANE_CTL_DECOMPRESSION_ENABLE (1 << 15) | 6321 | #define PLANE_CTL_DECOMPRESSION_ENABLE (1 << 15) |
6288 | #define PLANE_CTL_TRICKLE_FEED_DISABLE (1 << 14) | 6322 | #define PLANE_CTL_TRICKLE_FEED_DISABLE (1 << 14) |
6289 | #define PLANE_CTL_PLANE_GAMMA_DISABLE (1 << 13) | 6323 | #define PLANE_CTL_PLANE_GAMMA_DISABLE (1 << 13) /* Pre-GLK */ |
6290 | #define PLANE_CTL_TILED_MASK (0x7 << 10) | 6324 | #define PLANE_CTL_TILED_MASK (0x7 << 10) |
6291 | #define PLANE_CTL_TILED_LINEAR ( 0 << 10) | 6325 | #define PLANE_CTL_TILED_LINEAR ( 0 << 10) |
6292 | #define PLANE_CTL_TILED_X ( 1 << 10) | 6326 | #define PLANE_CTL_TILED_X ( 1 << 10) |
6293 | #define PLANE_CTL_TILED_Y ( 4 << 10) | 6327 | #define PLANE_CTL_TILED_Y ( 4 << 10) |
6294 | #define PLANE_CTL_TILED_YF ( 5 << 10) | 6328 | #define PLANE_CTL_TILED_YF ( 5 << 10) |
6295 | #define PLANE_CTL_ALPHA_MASK (0x3 << 4) | 6329 | #define PLANE_CTL_ALPHA_MASK (0x3 << 4) /* Pre-GLK */ |
6296 | #define PLANE_CTL_ALPHA_DISABLE ( 0 << 4) | 6330 | #define PLANE_CTL_ALPHA_DISABLE ( 0 << 4) |
6297 | #define PLANE_CTL_ALPHA_SW_PREMULTIPLY ( 2 << 4) | 6331 | #define PLANE_CTL_ALPHA_SW_PREMULTIPLY ( 2 << 4) |
6298 | #define PLANE_CTL_ALPHA_HW_PREMULTIPLY ( 3 << 4) | 6332 | #define PLANE_CTL_ALPHA_HW_PREMULTIPLY ( 3 << 4) |
@@ -6332,6 +6366,10 @@ enum { | |||
6332 | #define PLANE_COLOR_PIPE_GAMMA_ENABLE (1 << 30) | 6366 | #define PLANE_COLOR_PIPE_GAMMA_ENABLE (1 << 30) |
6333 | #define PLANE_COLOR_PIPE_CSC_ENABLE (1 << 23) | 6367 | #define PLANE_COLOR_PIPE_CSC_ENABLE (1 << 23) |
6334 | #define PLANE_COLOR_PLANE_GAMMA_DISABLE (1 << 13) | 6368 | #define PLANE_COLOR_PLANE_GAMMA_DISABLE (1 << 13) |
6369 | #define PLANE_COLOR_ALPHA_MASK (0x3 << 4) | ||
6370 | #define PLANE_COLOR_ALPHA_DISABLE (0 << 4) | ||
6371 | #define PLANE_COLOR_ALPHA_SW_PREMULTIPLY (2 << 4) | ||
6372 | #define PLANE_COLOR_ALPHA_HW_PREMULTIPLY (3 << 4) | ||
6335 | #define _PLANE_BUF_CFG_1_A 0x7027c | 6373 | #define _PLANE_BUF_CFG_1_A 0x7027c |
6336 | #define _PLANE_BUF_CFG_2_A 0x7037c | 6374 | #define _PLANE_BUF_CFG_2_A 0x7037c |
6337 | #define _PLANE_NV12_BUF_CFG_1_A 0x70278 | 6375 | #define _PLANE_NV12_BUF_CFG_1_A 0x70278 |
@@ -7774,8 +7812,9 @@ enum { | |||
7774 | #define FORCEWAKE_ACK_MEDIA_GEN9 _MMIO(0x0D88) | 7812 | #define FORCEWAKE_ACK_MEDIA_GEN9 _MMIO(0x0D88) |
7775 | #define FORCEWAKE_ACK_RENDER_GEN9 _MMIO(0x0D84) | 7813 | #define FORCEWAKE_ACK_RENDER_GEN9 _MMIO(0x0D84) |
7776 | #define FORCEWAKE_ACK_BLITTER_GEN9 _MMIO(0x130044) | 7814 | #define FORCEWAKE_ACK_BLITTER_GEN9 _MMIO(0x130044) |
7777 | #define FORCEWAKE_KERNEL 0x1 | 7815 | #define FORCEWAKE_KERNEL BIT(0) |
7778 | #define FORCEWAKE_USER 0x2 | 7816 | #define FORCEWAKE_USER BIT(1) |
7817 | #define FORCEWAKE_KERNEL_FALLBACK BIT(15) | ||
7779 | #define FORCEWAKE_MT_ACK _MMIO(0x130040) | 7818 | #define FORCEWAKE_MT_ACK _MMIO(0x130040) |
7780 | #define ECOBUS _MMIO(0xa180) | 7819 | #define ECOBUS _MMIO(0xa180) |
7781 | #define FORCEWAKE_MT_ENABLE (1<<5) | 7820 | #define FORCEWAKE_MT_ENABLE (1<<5) |
@@ -7905,6 +7944,7 @@ enum { | |||
7905 | #define GEN6_RC1_WAKE_RATE_LIMIT _MMIO(0xA098) | 7944 | #define GEN6_RC1_WAKE_RATE_LIMIT _MMIO(0xA098) |
7906 | #define GEN6_RC6_WAKE_RATE_LIMIT _MMIO(0xA09C) | 7945 | #define GEN6_RC6_WAKE_RATE_LIMIT _MMIO(0xA09C) |
7907 | #define GEN6_RC6pp_WAKE_RATE_LIMIT _MMIO(0xA0A0) | 7946 | #define GEN6_RC6pp_WAKE_RATE_LIMIT _MMIO(0xA0A0) |
7947 | #define GEN10_MEDIA_WAKE_RATE_LIMIT _MMIO(0xA0A0) | ||
7908 | #define GEN6_RC_EVALUATION_INTERVAL _MMIO(0xA0A8) | 7948 | #define GEN6_RC_EVALUATION_INTERVAL _MMIO(0xA0A8) |
7909 | #define GEN6_RC_IDLE_HYSTERSIS _MMIO(0xA0AC) | 7949 | #define GEN6_RC_IDLE_HYSTERSIS _MMIO(0xA0AC) |
7910 | #define GEN6_RC_SLEEP _MMIO(0xA0B0) | 7950 | #define GEN6_RC_SLEEP _MMIO(0xA0B0) |
@@ -8036,11 +8076,18 @@ enum { | |||
8036 | #define CHV_EU311_PG_ENABLE (1<<1) | 8076 | #define CHV_EU311_PG_ENABLE (1<<1) |
8037 | 8077 | ||
8038 | #define GEN9_SLICE_PGCTL_ACK(slice) _MMIO(0x804c + (slice)*0x4) | 8078 | #define GEN9_SLICE_PGCTL_ACK(slice) _MMIO(0x804c + (slice)*0x4) |
8079 | #define GEN10_SLICE_PGCTL_ACK(slice) _MMIO(0x804c + ((slice) / 3) * 0x34 + \ | ||
8080 | ((slice) % 3) * 0x4) | ||
8039 | #define GEN9_PGCTL_SLICE_ACK (1 << 0) | 8081 | #define GEN9_PGCTL_SLICE_ACK (1 << 0) |
8040 | #define GEN9_PGCTL_SS_ACK(subslice) (1 << (2 + (subslice)*2)) | 8082 | #define GEN9_PGCTL_SS_ACK(subslice) (1 << (2 + (subslice)*2)) |
8083 | #define GEN10_PGCTL_VALID_SS_MASK(slice) ((slice) == 0 ? 0x7F : 0x1F) | ||
8041 | 8084 | ||
8042 | #define GEN9_SS01_EU_PGCTL_ACK(slice) _MMIO(0x805c + (slice)*0x8) | 8085 | #define GEN9_SS01_EU_PGCTL_ACK(slice) _MMIO(0x805c + (slice)*0x8) |
8086 | #define GEN10_SS01_EU_PGCTL_ACK(slice) _MMIO(0x805c + ((slice) / 3) * 0x30 + \ | ||
8087 | ((slice) % 3) * 0x8) | ||
8043 | #define GEN9_SS23_EU_PGCTL_ACK(slice) _MMIO(0x8060 + (slice)*0x8) | 8088 | #define GEN9_SS23_EU_PGCTL_ACK(slice) _MMIO(0x8060 + (slice)*0x8) |
8089 | #define GEN10_SS23_EU_PGCTL_ACK(slice) _MMIO(0x8060 + ((slice) / 3) * 0x30 + \ | ||
8090 | ((slice) % 3) * 0x8) | ||
8044 | #define GEN9_PGCTL_SSA_EU08_ACK (1 << 0) | 8091 | #define GEN9_PGCTL_SSA_EU08_ACK (1 << 0) |
8045 | #define GEN9_PGCTL_SSA_EU19_ACK (1 << 2) | 8092 | #define GEN9_PGCTL_SSA_EU19_ACK (1 << 2) |
8046 | #define GEN9_PGCTL_SSA_EU210_ACK (1 << 4) | 8093 | #define GEN9_PGCTL_SSA_EU210_ACK (1 << 4) |
@@ -8837,6 +8884,12 @@ enum skl_power_gate { | |||
8837 | #define ILK_TIMESTAMP_HI _MMIO(0x70070) | 8884 | #define ILK_TIMESTAMP_HI _MMIO(0x70070) |
8838 | #define IVB_TIMESTAMP_CTR _MMIO(0x44070) | 8885 | #define IVB_TIMESTAMP_CTR _MMIO(0x44070) |
8839 | 8886 | ||
8887 | #define GEN9_TIMESTAMP_OVERRIDE _MMIO(0x44074) | ||
8888 | #define GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_SHIFT 0 | ||
8889 | #define GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_MASK 0x3ff | ||
8890 | #define GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_SHIFT 12 | ||
8891 | #define GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_MASK (0xf << 12) | ||
8892 | |||
8840 | #define _PIPE_FRMTMSTMP_A 0x70048 | 8893 | #define _PIPE_FRMTMSTMP_A 0x70048 |
8841 | #define PIPE_FRMTMSTMP(pipe) \ | 8894 | #define PIPE_FRMTMSTMP(pipe) \ |
8842 | _MMIO_PIPE2(pipe, _PIPE_FRMTMSTMP_A) | 8895 | _MMIO_PIPE2(pipe, _PIPE_FRMTMSTMP_A) |
diff --git a/drivers/gpu/drm/i915/i915_selftest.h b/drivers/gpu/drm/i915/i915_selftest.h index 78e1a1b168ff..9766e806dce6 100644 --- a/drivers/gpu/drm/i915/i915_selftest.h +++ b/drivers/gpu/drm/i915/i915_selftest.h | |||
@@ -99,6 +99,6 @@ __printf(2, 3) | |||
99 | bool __igt_timeout(unsigned long timeout, const char *fmt, ...); | 99 | bool __igt_timeout(unsigned long timeout, const char *fmt, ...); |
100 | 100 | ||
101 | #define igt_timeout(t, fmt, ...) \ | 101 | #define igt_timeout(t, fmt, ...) \ |
102 | __igt_timeout((t), KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__) | 102 | __igt_timeout((t), KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) |
103 | 103 | ||
104 | #endif /* !__I915_SELFTEST_H__ */ | 104 | #endif /* !__I915_SELFTEST_H__ */ |
diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index af3d7cc53fa1..8d07764887ec 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h | |||
@@ -83,8 +83,11 @@ | |||
83 | (typeof(ptr))(__v & -BIT(n)); \ | 83 | (typeof(ptr))(__v & -BIT(n)); \ |
84 | }) | 84 | }) |
85 | 85 | ||
86 | #define ptr_pack_bits(ptr, bits, n) \ | 86 | #define ptr_pack_bits(ptr, bits, n) ({ \ |
87 | ((typeof(ptr))((unsigned long)(ptr) | (bits))) | 87 | unsigned long __bits = (bits); \ |
88 | GEM_BUG_ON(__bits & -BIT(n)); \ | ||
89 | ((typeof(ptr))((unsigned long)(ptr) | __bits)); \ | ||
90 | }) | ||
88 | 91 | ||
89 | #define page_mask_bits(ptr) ptr_mask_bits(ptr, PAGE_SHIFT) | 92 | #define page_mask_bits(ptr) ptr_mask_bits(ptr, PAGE_SHIFT) |
90 | #define page_unmask_bits(ptr) ptr_unmask_bits(ptr, PAGE_SHIFT) | 93 | #define page_unmask_bits(ptr) ptr_unmask_bits(ptr, PAGE_SHIFT) |
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index fbfab2f33023..bf6d8d1eaabe 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c | |||
@@ -640,15 +640,17 @@ int __i915_vma_do_pin(struct i915_vma *vma, | |||
640 | if (ret) | 640 | if (ret) |
641 | goto err_unpin; | 641 | goto err_unpin; |
642 | } | 642 | } |
643 | GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); | ||
643 | 644 | ||
644 | ret = i915_vma_bind(vma, vma->obj->cache_level, flags); | 645 | ret = i915_vma_bind(vma, vma->obj->cache_level, flags); |
645 | if (ret) | 646 | if (ret) |
646 | goto err_remove; | 647 | goto err_remove; |
647 | 648 | ||
649 | GEM_BUG_ON((vma->flags & I915_VMA_BIND_MASK) == 0); | ||
650 | |||
648 | if ((bound ^ vma->flags) & I915_VMA_GLOBAL_BIND) | 651 | if ((bound ^ vma->flags) & I915_VMA_GLOBAL_BIND) |
649 | __i915_vma_set_map_and_fenceable(vma); | 652 | __i915_vma_set_map_and_fenceable(vma); |
650 | 653 | ||
651 | GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); | ||
652 | GEM_BUG_ON(i915_vma_misplaced(vma, size, alignment, flags)); | 654 | GEM_BUG_ON(i915_vma_misplaced(vma, size, alignment, flags)); |
653 | return 0; | 655 | return 0; |
654 | 656 | ||
@@ -656,6 +658,7 @@ err_remove: | |||
656 | if ((bound & I915_VMA_BIND_MASK) == 0) { | 658 | if ((bound & I915_VMA_BIND_MASK) == 0) { |
657 | i915_vma_remove(vma); | 659 | i915_vma_remove(vma); |
658 | GEM_BUG_ON(vma->pages); | 660 | GEM_BUG_ON(vma->pages); |
661 | GEM_BUG_ON(vma->flags & I915_VMA_BIND_MASK); | ||
659 | } | 662 | } |
660 | err_unpin: | 663 | err_unpin: |
661 | __i915_vma_unpin(vma); | 664 | __i915_vma_unpin(vma); |
@@ -740,6 +743,7 @@ int i915_vma_unbind(struct i915_vma *vma) | |||
740 | /* First wait upon any activity as retiring the request may | 743 | /* First wait upon any activity as retiring the request may |
741 | * have side-effects such as unpinning or even unbinding this vma. | 744 | * have side-effects such as unpinning or even unbinding this vma. |
742 | */ | 745 | */ |
746 | might_sleep(); | ||
743 | active = i915_vma_get_active(vma); | 747 | active = i915_vma_get_active(vma); |
744 | if (active) { | 748 | if (active) { |
745 | int idx; | 749 | int idx; |
diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 0ddba16fde1b..f1502a0188eb 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c | |||
@@ -102,13 +102,13 @@ static const struct dp_aud_n_m dp_aud_n_m[] = { | |||
102 | }; | 102 | }; |
103 | 103 | ||
104 | static const struct dp_aud_n_m * | 104 | static const struct dp_aud_n_m * |
105 | audio_config_dp_get_n_m(struct intel_crtc *intel_crtc, int rate) | 105 | audio_config_dp_get_n_m(const struct intel_crtc_state *crtc_state, int rate) |
106 | { | 106 | { |
107 | int i; | 107 | int i; |
108 | 108 | ||
109 | for (i = 0; i < ARRAY_SIZE(dp_aud_n_m); i++) { | 109 | for (i = 0; i < ARRAY_SIZE(dp_aud_n_m); i++) { |
110 | if (rate == dp_aud_n_m[i].sample_rate && | 110 | if (rate == dp_aud_n_m[i].sample_rate && |
111 | intel_crtc->config->port_clock == dp_aud_n_m[i].clock) | 111 | crtc_state->port_clock == dp_aud_n_m[i].clock) |
112 | return &dp_aud_n_m[i]; | 112 | return &dp_aud_n_m[i]; |
113 | } | 113 | } |
114 | 114 | ||
@@ -157,8 +157,10 @@ static const struct { | |||
157 | }; | 157 | }; |
158 | 158 | ||
159 | /* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */ | 159 | /* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */ |
160 | static u32 audio_config_hdmi_pixel_clock(const struct drm_display_mode *adjusted_mode) | 160 | static u32 audio_config_hdmi_pixel_clock(const struct intel_crtc_state *crtc_state) |
161 | { | 161 | { |
162 | const struct drm_display_mode *adjusted_mode = | ||
163 | &crtc_state->base.adjusted_mode; | ||
162 | int i; | 164 | int i; |
163 | 165 | ||
164 | for (i = 0; i < ARRAY_SIZE(hdmi_audio_clock); i++) { | 166 | for (i = 0; i < ARRAY_SIZE(hdmi_audio_clock); i++) { |
@@ -179,9 +181,11 @@ static u32 audio_config_hdmi_pixel_clock(const struct drm_display_mode *adjusted | |||
179 | return hdmi_audio_clock[i].config; | 181 | return hdmi_audio_clock[i].config; |
180 | } | 182 | } |
181 | 183 | ||
182 | static int audio_config_hdmi_get_n(const struct drm_display_mode *adjusted_mode, | 184 | static int audio_config_hdmi_get_n(const struct intel_crtc_state *crtc_state, |
183 | int rate) | 185 | int rate) |
184 | { | 186 | { |
187 | const struct drm_display_mode *adjusted_mode = | ||
188 | &crtc_state->base.adjusted_mode; | ||
185 | int i; | 189 | int i; |
186 | 190 | ||
187 | for (i = 0; i < ARRAY_SIZE(hdmi_aud_ncts); i++) { | 191 | for (i = 0; i < ARRAY_SIZE(hdmi_aud_ncts); i++) { |
@@ -220,7 +224,9 @@ static bool intel_eld_uptodate(struct drm_connector *connector, | |||
220 | return true; | 224 | return true; |
221 | } | 225 | } |
222 | 226 | ||
223 | static void g4x_audio_codec_disable(struct intel_encoder *encoder) | 227 | static void g4x_audio_codec_disable(struct intel_encoder *encoder, |
228 | const struct intel_crtc_state *old_crtc_state, | ||
229 | const struct drm_connector_state *old_conn_state) | ||
224 | { | 230 | { |
225 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 231 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
226 | uint32_t eldv, tmp; | 232 | uint32_t eldv, tmp; |
@@ -239,11 +245,12 @@ static void g4x_audio_codec_disable(struct intel_encoder *encoder) | |||
239 | I915_WRITE(G4X_AUD_CNTL_ST, tmp); | 245 | I915_WRITE(G4X_AUD_CNTL_ST, tmp); |
240 | } | 246 | } |
241 | 247 | ||
242 | static void g4x_audio_codec_enable(struct drm_connector *connector, | 248 | static void g4x_audio_codec_enable(struct intel_encoder *encoder, |
243 | struct intel_encoder *encoder, | 249 | const struct intel_crtc_state *crtc_state, |
244 | const struct drm_display_mode *adjusted_mode) | 250 | const struct drm_connector_state *conn_state) |
245 | { | 251 | { |
246 | struct drm_i915_private *dev_priv = to_i915(connector->dev); | 252 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
253 | struct drm_connector *connector = conn_state->connector; | ||
247 | uint8_t *eld = connector->eld; | 254 | uint8_t *eld = connector->eld; |
248 | uint32_t eldv; | 255 | uint32_t eldv; |
249 | uint32_t tmp; | 256 | uint32_t tmp; |
@@ -279,16 +286,20 @@ static void g4x_audio_codec_enable(struct drm_connector *connector, | |||
279 | } | 286 | } |
280 | 287 | ||
281 | static void | 288 | static void |
282 | hsw_dp_audio_config_update(struct intel_crtc *intel_crtc, enum port port, | 289 | hsw_dp_audio_config_update(struct intel_encoder *encoder, |
283 | const struct drm_display_mode *adjusted_mode) | 290 | const struct intel_crtc_state *crtc_state) |
284 | { | 291 | { |
285 | struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); | 292 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
286 | struct i915_audio_component *acomp = dev_priv->audio_component; | 293 | struct i915_audio_component *acomp = dev_priv->audio_component; |
287 | int rate = acomp ? acomp->aud_sample_rate[port] : 0; | 294 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
288 | const struct dp_aud_n_m *nm = audio_config_dp_get_n_m(intel_crtc, rate); | 295 | enum port port = encoder->port; |
289 | enum pipe pipe = intel_crtc->pipe; | 296 | enum pipe pipe = crtc->pipe; |
297 | const struct dp_aud_n_m *nm; | ||
298 | int rate; | ||
290 | u32 tmp; | 299 | u32 tmp; |
291 | 300 | ||
301 | rate = acomp ? acomp->aud_sample_rate[port] : 0; | ||
302 | nm = audio_config_dp_get_n_m(crtc_state, rate); | ||
292 | if (nm) | 303 | if (nm) |
293 | DRM_DEBUG_KMS("using Maud %u, Naud %u\n", nm->m, nm->n); | 304 | DRM_DEBUG_KMS("using Maud %u, Naud %u\n", nm->m, nm->n); |
294 | else | 305 | else |
@@ -323,23 +334,26 @@ hsw_dp_audio_config_update(struct intel_crtc *intel_crtc, enum port port, | |||
323 | } | 334 | } |
324 | 335 | ||
325 | static void | 336 | static void |
326 | hsw_hdmi_audio_config_update(struct intel_crtc *intel_crtc, enum port port, | 337 | hsw_hdmi_audio_config_update(struct intel_encoder *encoder, |
327 | const struct drm_display_mode *adjusted_mode) | 338 | const struct intel_crtc_state *crtc_state) |
328 | { | 339 | { |
329 | struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); | 340 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
330 | struct i915_audio_component *acomp = dev_priv->audio_component; | 341 | struct i915_audio_component *acomp = dev_priv->audio_component; |
331 | int rate = acomp ? acomp->aud_sample_rate[port] : 0; | 342 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
332 | enum pipe pipe = intel_crtc->pipe; | 343 | enum port port = encoder->port; |
333 | int n; | 344 | enum pipe pipe = crtc->pipe; |
345 | int n, rate; | ||
334 | u32 tmp; | 346 | u32 tmp; |
335 | 347 | ||
348 | rate = acomp ? acomp->aud_sample_rate[port] : 0; | ||
349 | |||
336 | tmp = I915_READ(HSW_AUD_CFG(pipe)); | 350 | tmp = I915_READ(HSW_AUD_CFG(pipe)); |
337 | tmp &= ~AUD_CONFIG_N_VALUE_INDEX; | 351 | tmp &= ~AUD_CONFIG_N_VALUE_INDEX; |
338 | tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK; | 352 | tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK; |
339 | tmp &= ~AUD_CONFIG_N_PROG_ENABLE; | 353 | tmp &= ~AUD_CONFIG_N_PROG_ENABLE; |
340 | tmp |= audio_config_hdmi_pixel_clock(adjusted_mode); | 354 | tmp |= audio_config_hdmi_pixel_clock(crtc_state); |
341 | 355 | ||
342 | n = audio_config_hdmi_get_n(adjusted_mode, rate); | 356 | n = audio_config_hdmi_get_n(crtc_state, rate); |
343 | if (n != 0) { | 357 | if (n != 0) { |
344 | DRM_DEBUG_KMS("using N %d\n", n); | 358 | DRM_DEBUG_KMS("using N %d\n", n); |
345 | 359 | ||
@@ -363,20 +377,22 @@ hsw_hdmi_audio_config_update(struct intel_crtc *intel_crtc, enum port port, | |||
363 | } | 377 | } |
364 | 378 | ||
365 | static void | 379 | static void |
366 | hsw_audio_config_update(struct intel_crtc *intel_crtc, enum port port, | 380 | hsw_audio_config_update(struct intel_encoder *encoder, |
367 | const struct drm_display_mode *adjusted_mode) | 381 | const struct intel_crtc_state *crtc_state) |
368 | { | 382 | { |
369 | if (intel_crtc_has_dp_encoder(intel_crtc->config)) | 383 | if (intel_crtc_has_dp_encoder(crtc_state)) |
370 | hsw_dp_audio_config_update(intel_crtc, port, adjusted_mode); | 384 | hsw_dp_audio_config_update(encoder, crtc_state); |
371 | else | 385 | else |
372 | hsw_hdmi_audio_config_update(intel_crtc, port, adjusted_mode); | 386 | hsw_hdmi_audio_config_update(encoder, crtc_state); |
373 | } | 387 | } |
374 | 388 | ||
375 | static void hsw_audio_codec_disable(struct intel_encoder *encoder) | 389 | static void hsw_audio_codec_disable(struct intel_encoder *encoder, |
390 | const struct intel_crtc_state *old_crtc_state, | ||
391 | const struct drm_connector_state *old_conn_state) | ||
376 | { | 392 | { |
377 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 393 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
378 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); | 394 | struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); |
379 | enum pipe pipe = intel_crtc->pipe; | 395 | enum pipe pipe = crtc->pipe; |
380 | uint32_t tmp; | 396 | uint32_t tmp; |
381 | 397 | ||
382 | DRM_DEBUG_KMS("Disable audio codec on pipe %c\n", pipe_name(pipe)); | 398 | DRM_DEBUG_KMS("Disable audio codec on pipe %c\n", pipe_name(pipe)); |
@@ -389,7 +405,7 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder) | |||
389 | tmp |= AUD_CONFIG_N_PROG_ENABLE; | 405 | tmp |= AUD_CONFIG_N_PROG_ENABLE; |
390 | tmp &= ~AUD_CONFIG_UPPER_N_MASK; | 406 | tmp &= ~AUD_CONFIG_UPPER_N_MASK; |
391 | tmp &= ~AUD_CONFIG_LOWER_N_MASK; | 407 | tmp &= ~AUD_CONFIG_LOWER_N_MASK; |
392 | if (intel_crtc_has_dp_encoder(intel_crtc->config)) | 408 | if (intel_crtc_has_dp_encoder(old_crtc_state)) |
393 | tmp |= AUD_CONFIG_N_VALUE_INDEX; | 409 | tmp |= AUD_CONFIG_N_VALUE_INDEX; |
394 | I915_WRITE(HSW_AUD_CFG(pipe), tmp); | 410 | I915_WRITE(HSW_AUD_CFG(pipe), tmp); |
395 | 411 | ||
@@ -402,14 +418,14 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder) | |||
402 | mutex_unlock(&dev_priv->av_mutex); | 418 | mutex_unlock(&dev_priv->av_mutex); |
403 | } | 419 | } |
404 | 420 | ||
405 | static void hsw_audio_codec_enable(struct drm_connector *connector, | 421 | static void hsw_audio_codec_enable(struct intel_encoder *encoder, |
406 | struct intel_encoder *intel_encoder, | 422 | const struct intel_crtc_state *crtc_state, |
407 | const struct drm_display_mode *adjusted_mode) | 423 | const struct drm_connector_state *conn_state) |
408 | { | 424 | { |
409 | struct drm_i915_private *dev_priv = to_i915(connector->dev); | 425 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
410 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_encoder->base.crtc); | 426 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
411 | enum pipe pipe = intel_crtc->pipe; | 427 | struct drm_connector *connector = conn_state->connector; |
412 | enum port port = intel_encoder->port; | 428 | enum pipe pipe = crtc->pipe; |
413 | const uint8_t *eld = connector->eld; | 429 | const uint8_t *eld = connector->eld; |
414 | uint32_t tmp; | 430 | uint32_t tmp; |
415 | int len, i; | 431 | int len, i; |
@@ -448,17 +464,19 @@ static void hsw_audio_codec_enable(struct drm_connector *connector, | |||
448 | I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); | 464 | I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); |
449 | 465 | ||
450 | /* Enable timestamps */ | 466 | /* Enable timestamps */ |
451 | hsw_audio_config_update(intel_crtc, port, adjusted_mode); | 467 | hsw_audio_config_update(encoder, crtc_state); |
452 | 468 | ||
453 | mutex_unlock(&dev_priv->av_mutex); | 469 | mutex_unlock(&dev_priv->av_mutex); |
454 | } | 470 | } |
455 | 471 | ||
456 | static void ilk_audio_codec_disable(struct intel_encoder *intel_encoder) | 472 | static void ilk_audio_codec_disable(struct intel_encoder *encoder, |
473 | const struct intel_crtc_state *old_crtc_state, | ||
474 | const struct drm_connector_state *old_conn_state) | ||
457 | { | 475 | { |
458 | struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev); | 476 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
459 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_encoder->base.crtc); | 477 | struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); |
460 | enum pipe pipe = intel_crtc->pipe; | 478 | enum pipe pipe = crtc->pipe; |
461 | enum port port = intel_encoder->port; | 479 | enum port port = encoder->port; |
462 | uint32_t tmp, eldv; | 480 | uint32_t tmp, eldv; |
463 | i915_reg_t aud_config, aud_cntrl_st2; | 481 | i915_reg_t aud_config, aud_cntrl_st2; |
464 | 482 | ||
@@ -485,7 +503,7 @@ static void ilk_audio_codec_disable(struct intel_encoder *intel_encoder) | |||
485 | tmp |= AUD_CONFIG_N_PROG_ENABLE; | 503 | tmp |= AUD_CONFIG_N_PROG_ENABLE; |
486 | tmp &= ~AUD_CONFIG_UPPER_N_MASK; | 504 | tmp &= ~AUD_CONFIG_UPPER_N_MASK; |
487 | tmp &= ~AUD_CONFIG_LOWER_N_MASK; | 505 | tmp &= ~AUD_CONFIG_LOWER_N_MASK; |
488 | if (intel_crtc_has_dp_encoder(intel_crtc->config)) | 506 | if (intel_crtc_has_dp_encoder(old_crtc_state)) |
489 | tmp |= AUD_CONFIG_N_VALUE_INDEX; | 507 | tmp |= AUD_CONFIG_N_VALUE_INDEX; |
490 | I915_WRITE(aud_config, tmp); | 508 | I915_WRITE(aud_config, tmp); |
491 | 509 | ||
@@ -497,14 +515,15 @@ static void ilk_audio_codec_disable(struct intel_encoder *intel_encoder) | |||
497 | I915_WRITE(aud_cntrl_st2, tmp); | 515 | I915_WRITE(aud_cntrl_st2, tmp); |
498 | } | 516 | } |
499 | 517 | ||
500 | static void ilk_audio_codec_enable(struct drm_connector *connector, | 518 | static void ilk_audio_codec_enable(struct intel_encoder *encoder, |
501 | struct intel_encoder *intel_encoder, | 519 | const struct intel_crtc_state *crtc_state, |
502 | const struct drm_display_mode *adjusted_mode) | 520 | const struct drm_connector_state *conn_state) |
503 | { | 521 | { |
504 | struct drm_i915_private *dev_priv = to_i915(connector->dev); | 522 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
505 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_encoder->base.crtc); | 523 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
506 | enum pipe pipe = intel_crtc->pipe; | 524 | struct drm_connector *connector = conn_state->connector; |
507 | enum port port = intel_encoder->port; | 525 | enum pipe pipe = crtc->pipe; |
526 | enum port port = encoder->port; | ||
508 | uint8_t *eld = connector->eld; | 527 | uint8_t *eld = connector->eld; |
509 | uint32_t tmp, eldv; | 528 | uint32_t tmp, eldv; |
510 | int len, i; | 529 | int len, i; |
@@ -568,36 +587,36 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, | |||
568 | tmp &= ~AUD_CONFIG_N_VALUE_INDEX; | 587 | tmp &= ~AUD_CONFIG_N_VALUE_INDEX; |
569 | tmp &= ~AUD_CONFIG_N_PROG_ENABLE; | 588 | tmp &= ~AUD_CONFIG_N_PROG_ENABLE; |
570 | tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK; | 589 | tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK; |
571 | if (intel_crtc_has_dp_encoder(intel_crtc->config)) | 590 | if (intel_crtc_has_dp_encoder(crtc_state)) |
572 | tmp |= AUD_CONFIG_N_VALUE_INDEX; | 591 | tmp |= AUD_CONFIG_N_VALUE_INDEX; |
573 | else | 592 | else |
574 | tmp |= audio_config_hdmi_pixel_clock(adjusted_mode); | 593 | tmp |= audio_config_hdmi_pixel_clock(crtc_state); |
575 | I915_WRITE(aud_config, tmp); | 594 | I915_WRITE(aud_config, tmp); |
576 | } | 595 | } |
577 | 596 | ||
578 | /** | 597 | /** |
579 | * intel_audio_codec_enable - Enable the audio codec for HD audio | 598 | * intel_audio_codec_enable - Enable the audio codec for HD audio |
580 | * @intel_encoder: encoder on which to enable audio | 599 | * @encoder: encoder on which to enable audio |
581 | * @crtc_state: pointer to the current crtc state. | 600 | * @crtc_state: pointer to the current crtc state. |
582 | * @conn_state: pointer to the current connector state. | 601 | * @conn_state: pointer to the current connector state. |
583 | * | 602 | * |
584 | * The enable sequences may only be performed after enabling the transcoder and | 603 | * The enable sequences may only be performed after enabling the transcoder and |
585 | * port, and after completed link training. | 604 | * port, and after completed link training. |
586 | */ | 605 | */ |
587 | void intel_audio_codec_enable(struct intel_encoder *intel_encoder, | 606 | void intel_audio_codec_enable(struct intel_encoder *encoder, |
588 | const struct intel_crtc_state *crtc_state, | 607 | const struct intel_crtc_state *crtc_state, |
589 | const struct drm_connector_state *conn_state) | 608 | const struct drm_connector_state *conn_state) |
590 | { | 609 | { |
591 | struct drm_encoder *encoder = &intel_encoder->base; | 610 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
592 | const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode; | ||
593 | struct drm_connector *connector; | ||
594 | struct drm_i915_private *dev_priv = to_i915(encoder->dev); | ||
595 | struct i915_audio_component *acomp = dev_priv->audio_component; | 611 | struct i915_audio_component *acomp = dev_priv->audio_component; |
596 | enum port port = intel_encoder->port; | 612 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
597 | enum pipe pipe = to_intel_crtc(crtc_state->base.crtc)->pipe; | 613 | struct drm_connector *connector = conn_state->connector; |
614 | const struct drm_display_mode *adjusted_mode = | ||
615 | &crtc_state->base.adjusted_mode; | ||
616 | enum port port = encoder->port; | ||
617 | enum pipe pipe = crtc->pipe; | ||
598 | 618 | ||
599 | connector = conn_state->connector; | 619 | if (!connector->eld[0]) |
600 | if (!connector || !connector->eld[0]) | ||
601 | return; | 620 | return; |
602 | 621 | ||
603 | DRM_DEBUG_DRIVER("ELD on [CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", | 622 | DRM_DEBUG_DRIVER("ELD on [CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", |
@@ -609,19 +628,20 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder, | |||
609 | connector->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2; | 628 | connector->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2; |
610 | 629 | ||
611 | if (dev_priv->display.audio_codec_enable) | 630 | if (dev_priv->display.audio_codec_enable) |
612 | dev_priv->display.audio_codec_enable(connector, intel_encoder, | 631 | dev_priv->display.audio_codec_enable(encoder, |
613 | adjusted_mode); | 632 | crtc_state, |
633 | conn_state); | ||
614 | 634 | ||
615 | mutex_lock(&dev_priv->av_mutex); | 635 | mutex_lock(&dev_priv->av_mutex); |
616 | intel_encoder->audio_connector = connector; | 636 | encoder->audio_connector = connector; |
617 | 637 | ||
618 | /* referred in audio callbacks */ | 638 | /* referred in audio callbacks */ |
619 | dev_priv->av_enc_map[pipe] = intel_encoder; | 639 | dev_priv->av_enc_map[pipe] = encoder; |
620 | mutex_unlock(&dev_priv->av_mutex); | 640 | mutex_unlock(&dev_priv->av_mutex); |
621 | 641 | ||
622 | if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) { | 642 | if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) { |
623 | /* audio drivers expect pipe = -1 to indicate Non-MST cases */ | 643 | /* audio drivers expect pipe = -1 to indicate Non-MST cases */ |
624 | if (intel_encoder->type != INTEL_OUTPUT_DP_MST) | 644 | if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) |
625 | pipe = -1; | 645 | pipe = -1; |
626 | acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, | 646 | acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, |
627 | (int) port, (int) pipe); | 647 | (int) port, (int) pipe); |
@@ -629,36 +649,41 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder, | |||
629 | 649 | ||
630 | intel_lpe_audio_notify(dev_priv, pipe, port, connector->eld, | 650 | intel_lpe_audio_notify(dev_priv, pipe, port, connector->eld, |
631 | crtc_state->port_clock, | 651 | crtc_state->port_clock, |
632 | intel_encoder->type == INTEL_OUTPUT_DP); | 652 | intel_crtc_has_dp_encoder(crtc_state)); |
633 | } | 653 | } |
634 | 654 | ||
635 | /** | 655 | /** |
636 | * intel_audio_codec_disable - Disable the audio codec for HD audio | 656 | * intel_audio_codec_disable - Disable the audio codec for HD audio |
637 | * @intel_encoder: encoder on which to disable audio | 657 | * @encoder: encoder on which to disable audio |
658 | * @old_crtc_state: pointer to the old crtc state. | ||
659 | * @old_conn_state: pointer to the old connector state. | ||
638 | * | 660 | * |
639 | * The disable sequences must be performed before disabling the transcoder or | 661 | * The disable sequences must be performed before disabling the transcoder or |
640 | * port. | 662 | * port. |
641 | */ | 663 | */ |
642 | void intel_audio_codec_disable(struct intel_encoder *intel_encoder) | 664 | void intel_audio_codec_disable(struct intel_encoder *encoder, |
665 | const struct intel_crtc_state *old_crtc_state, | ||
666 | const struct drm_connector_state *old_conn_state) | ||
643 | { | 667 | { |
644 | struct drm_encoder *encoder = &intel_encoder->base; | 668 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
645 | struct drm_i915_private *dev_priv = to_i915(encoder->dev); | ||
646 | struct i915_audio_component *acomp = dev_priv->audio_component; | 669 | struct i915_audio_component *acomp = dev_priv->audio_component; |
647 | enum port port = intel_encoder->port; | 670 | struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); |
648 | struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); | 671 | enum port port = encoder->port; |
649 | enum pipe pipe = crtc->pipe; | 672 | enum pipe pipe = crtc->pipe; |
650 | 673 | ||
651 | if (dev_priv->display.audio_codec_disable) | 674 | if (dev_priv->display.audio_codec_disable) |
652 | dev_priv->display.audio_codec_disable(intel_encoder); | 675 | dev_priv->display.audio_codec_disable(encoder, |
676 | old_crtc_state, | ||
677 | old_conn_state); | ||
653 | 678 | ||
654 | mutex_lock(&dev_priv->av_mutex); | 679 | mutex_lock(&dev_priv->av_mutex); |
655 | intel_encoder->audio_connector = NULL; | 680 | encoder->audio_connector = NULL; |
656 | dev_priv->av_enc_map[pipe] = NULL; | 681 | dev_priv->av_enc_map[pipe] = NULL; |
657 | mutex_unlock(&dev_priv->av_mutex); | 682 | mutex_unlock(&dev_priv->av_mutex); |
658 | 683 | ||
659 | if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) { | 684 | if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify) { |
660 | /* audio drivers expect pipe = -1 to indicate Non-MST cases */ | 685 | /* audio drivers expect pipe = -1 to indicate Non-MST cases */ |
661 | if (intel_encoder->type != INTEL_OUTPUT_DP_MST) | 686 | if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) |
662 | pipe = -1; | 687 | pipe = -1; |
663 | acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, | 688 | acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, |
664 | (int) port, (int) pipe); | 689 | (int) port, (int) pipe); |
@@ -793,10 +818,9 @@ static int i915_audio_component_sync_audio_rate(struct device *kdev, int port, | |||
793 | int pipe, int rate) | 818 | int pipe, int rate) |
794 | { | 819 | { |
795 | struct drm_i915_private *dev_priv = kdev_to_i915(kdev); | 820 | struct drm_i915_private *dev_priv = kdev_to_i915(kdev); |
796 | struct intel_encoder *intel_encoder; | ||
797 | struct intel_crtc *crtc; | ||
798 | struct drm_display_mode *adjusted_mode; | ||
799 | struct i915_audio_component *acomp = dev_priv->audio_component; | 821 | struct i915_audio_component *acomp = dev_priv->audio_component; |
822 | struct intel_encoder *encoder; | ||
823 | struct intel_crtc *crtc; | ||
800 | int err = 0; | 824 | int err = 0; |
801 | 825 | ||
802 | if (!HAS_DDI(dev_priv)) | 826 | if (!HAS_DDI(dev_priv)) |
@@ -806,23 +830,19 @@ static int i915_audio_component_sync_audio_rate(struct device *kdev, int port, | |||
806 | mutex_lock(&dev_priv->av_mutex); | 830 | mutex_lock(&dev_priv->av_mutex); |
807 | 831 | ||
808 | /* 1. get the pipe */ | 832 | /* 1. get the pipe */ |
809 | intel_encoder = get_saved_enc(dev_priv, port, pipe); | 833 | encoder = get_saved_enc(dev_priv, port, pipe); |
810 | if (!intel_encoder || !intel_encoder->base.crtc) { | 834 | if (!encoder || !encoder->base.crtc) { |
811 | DRM_DEBUG_KMS("Not valid for port %c\n", port_name(port)); | 835 | DRM_DEBUG_KMS("Not valid for port %c\n", port_name(port)); |
812 | err = -ENODEV; | 836 | err = -ENODEV; |
813 | goto unlock; | 837 | goto unlock; |
814 | } | 838 | } |
815 | 839 | ||
816 | /* pipe passed from the audio driver will be -1 for Non-MST case */ | 840 | crtc = to_intel_crtc(encoder->base.crtc); |
817 | crtc = to_intel_crtc(intel_encoder->base.crtc); | ||
818 | pipe = crtc->pipe; | ||
819 | |||
820 | adjusted_mode = &crtc->config->base.adjusted_mode; | ||
821 | 841 | ||
822 | /* port must be valid now, otherwise the pipe will be invalid */ | 842 | /* port must be valid now, otherwise the pipe will be invalid */ |
823 | acomp->aud_sample_rate[port] = rate; | 843 | acomp->aud_sample_rate[port] = rate; |
824 | 844 | ||
825 | hsw_audio_config_update(crtc, port, adjusted_mode); | 845 | hsw_audio_config_update(encoder, crtc->config); |
826 | 846 | ||
827 | unlock: | 847 | unlock: |
828 | mutex_unlock(&dev_priv->av_mutex); | 848 | mutex_unlock(&dev_priv->av_mutex); |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index fd23023df7c1..51108ffc28d1 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -1234,6 +1234,30 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, | |||
1234 | info->hdmi_level_shift = hdmi_level_shift; | 1234 | info->hdmi_level_shift = hdmi_level_shift; |
1235 | } | 1235 | } |
1236 | 1236 | ||
1237 | if (bdb_version >= 204) { | ||
1238 | int max_tmds_clock; | ||
1239 | |||
1240 | switch (child->hdmi_max_data_rate) { | ||
1241 | default: | ||
1242 | MISSING_CASE(child->hdmi_max_data_rate); | ||
1243 | /* fall through */ | ||
1244 | case HDMI_MAX_DATA_RATE_PLATFORM: | ||
1245 | max_tmds_clock = 0; | ||
1246 | break; | ||
1247 | case HDMI_MAX_DATA_RATE_297: | ||
1248 | max_tmds_clock = 297000; | ||
1249 | break; | ||
1250 | case HDMI_MAX_DATA_RATE_165: | ||
1251 | max_tmds_clock = 165000; | ||
1252 | break; | ||
1253 | } | ||
1254 | |||
1255 | if (max_tmds_clock) | ||
1256 | DRM_DEBUG_KMS("VBT HDMI max TMDS clock for port %c: %d kHz\n", | ||
1257 | port_name(port), max_tmds_clock); | ||
1258 | info->max_tmds_clock = max_tmds_clock; | ||
1259 | } | ||
1260 | |||
1237 | /* Parse the I_boost config for SKL and above */ | 1261 | /* Parse the I_boost config for SKL and above */ |
1238 | if (bdb_version >= 196 && child->iboost) { | 1262 | if (bdb_version >= 196 && child->iboost) { |
1239 | info->dp_boost_level = translate_iboost(child->dp_iboost_level); | 1263 | info->dp_boost_level = translate_iboost(child->dp_iboost_level); |
diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 5f8b9f1f40f1..5ae2d276f7f3 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c | |||
@@ -123,7 +123,7 @@ static void intel_breadcrumbs_fake_irq(struct timer_list *t) | |||
123 | */ | 123 | */ |
124 | 124 | ||
125 | spin_lock_irq(&b->irq_lock); | 125 | spin_lock_irq(&b->irq_lock); |
126 | if (!__intel_breadcrumbs_wakeup(b)) | 126 | if (b->irq_armed && !__intel_breadcrumbs_wakeup(b)) |
127 | __intel_engine_disarm_breadcrumbs(engine); | 127 | __intel_engine_disarm_breadcrumbs(engine); |
128 | spin_unlock_irq(&b->irq_lock); | 128 | spin_unlock_irq(&b->irq_lock); |
129 | if (!b->irq_armed) | 129 | if (!b->irq_armed) |
@@ -145,6 +145,14 @@ static void intel_breadcrumbs_fake_irq(struct timer_list *t) | |||
145 | 145 | ||
146 | static void irq_enable(struct intel_engine_cs *engine) | 146 | static void irq_enable(struct intel_engine_cs *engine) |
147 | { | 147 | { |
148 | /* | ||
149 | * FIXME: Ideally we want this on the API boundary, but for the | ||
150 | * sake of testing with mock breadcrumbs (no HW so unable to | ||
151 | * enable irqs) we place it deep within the bowels, at the point | ||
152 | * of no return. | ||
153 | */ | ||
154 | GEM_BUG_ON(!intel_irqs_enabled(engine->i915)); | ||
155 | |||
148 | /* Enabling the IRQ may miss the generation of the interrupt, but | 156 | /* Enabling the IRQ may miss the generation of the interrupt, but |
149 | * we still need to force the barrier before reading the seqno, | 157 | * we still need to force the barrier before reading the seqno, |
150 | * just in case. | 158 | * just in case. |
@@ -171,15 +179,37 @@ void __intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine) | |||
171 | 179 | ||
172 | lockdep_assert_held(&b->irq_lock); | 180 | lockdep_assert_held(&b->irq_lock); |
173 | GEM_BUG_ON(b->irq_wait); | 181 | GEM_BUG_ON(b->irq_wait); |
182 | GEM_BUG_ON(!b->irq_armed); | ||
174 | 183 | ||
175 | if (b->irq_enabled) { | 184 | GEM_BUG_ON(!b->irq_enabled); |
185 | if (!--b->irq_enabled) | ||
176 | irq_disable(engine); | 186 | irq_disable(engine); |
177 | b->irq_enabled = false; | ||
178 | } | ||
179 | 187 | ||
180 | b->irq_armed = false; | 188 | b->irq_armed = false; |
181 | } | 189 | } |
182 | 190 | ||
191 | void intel_engine_pin_breadcrumbs_irq(struct intel_engine_cs *engine) | ||
192 | { | ||
193 | struct intel_breadcrumbs *b = &engine->breadcrumbs; | ||
194 | |||
195 | spin_lock_irq(&b->irq_lock); | ||
196 | if (!b->irq_enabled++) | ||
197 | irq_enable(engine); | ||
198 | GEM_BUG_ON(!b->irq_enabled); /* no overflow! */ | ||
199 | spin_unlock_irq(&b->irq_lock); | ||
200 | } | ||
201 | |||
202 | void intel_engine_unpin_breadcrumbs_irq(struct intel_engine_cs *engine) | ||
203 | { | ||
204 | struct intel_breadcrumbs *b = &engine->breadcrumbs; | ||
205 | |||
206 | spin_lock_irq(&b->irq_lock); | ||
207 | GEM_BUG_ON(!b->irq_enabled); /* no underflow! */ | ||
208 | if (!--b->irq_enabled) | ||
209 | irq_disable(engine); | ||
210 | spin_unlock_irq(&b->irq_lock); | ||
211 | } | ||
212 | |||
183 | void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine) | 213 | void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine) |
184 | { | 214 | { |
185 | struct intel_breadcrumbs *b = &engine->breadcrumbs; | 215 | struct intel_breadcrumbs *b = &engine->breadcrumbs; |
@@ -197,7 +227,8 @@ void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine) | |||
197 | 227 | ||
198 | spin_lock(&b->irq_lock); | 228 | spin_lock(&b->irq_lock); |
199 | first = fetch_and_zero(&b->irq_wait); | 229 | first = fetch_and_zero(&b->irq_wait); |
200 | __intel_engine_disarm_breadcrumbs(engine); | 230 | if (b->irq_armed) |
231 | __intel_engine_disarm_breadcrumbs(engine); | ||
201 | spin_unlock(&b->irq_lock); | 232 | spin_unlock(&b->irq_lock); |
202 | 233 | ||
203 | rbtree_postorder_for_each_entry_safe(wait, n, &b->waiters, node) { | 234 | rbtree_postorder_for_each_entry_safe(wait, n, &b->waiters, node) { |
@@ -241,6 +272,7 @@ static bool __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) | |||
241 | struct intel_engine_cs *engine = | 272 | struct intel_engine_cs *engine = |
242 | container_of(b, struct intel_engine_cs, breadcrumbs); | 273 | container_of(b, struct intel_engine_cs, breadcrumbs); |
243 | struct drm_i915_private *i915 = engine->i915; | 274 | struct drm_i915_private *i915 = engine->i915; |
275 | bool enabled; | ||
244 | 276 | ||
245 | lockdep_assert_held(&b->irq_lock); | 277 | lockdep_assert_held(&b->irq_lock); |
246 | if (b->irq_armed) | 278 | if (b->irq_armed) |
@@ -252,7 +284,6 @@ static bool __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) | |||
252 | * the irq. | 284 | * the irq. |
253 | */ | 285 | */ |
254 | b->irq_armed = true; | 286 | b->irq_armed = true; |
255 | GEM_BUG_ON(b->irq_enabled); | ||
256 | 287 | ||
257 | if (I915_SELFTEST_ONLY(b->mock)) { | 288 | if (I915_SELFTEST_ONLY(b->mock)) { |
258 | /* For our mock objects we want to avoid interaction | 289 | /* For our mock objects we want to avoid interaction |
@@ -273,14 +304,15 @@ static bool __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) | |||
273 | */ | 304 | */ |
274 | 305 | ||
275 | /* No interrupts? Kick the waiter every jiffie! */ | 306 | /* No interrupts? Kick the waiter every jiffie! */ |
276 | if (intel_irqs_enabled(i915)) { | 307 | enabled = false; |
277 | if (!test_bit(engine->id, &i915->gpu_error.test_irq_rings)) | 308 | if (!b->irq_enabled++ && |
278 | irq_enable(engine); | 309 | !test_bit(engine->id, &i915->gpu_error.test_irq_rings)) { |
279 | b->irq_enabled = true; | 310 | irq_enable(engine); |
311 | enabled = true; | ||
280 | } | 312 | } |
281 | 313 | ||
282 | enable_fake_irq(b); | 314 | enable_fake_irq(b); |
283 | return true; | 315 | return enabled; |
284 | } | 316 | } |
285 | 317 | ||
286 | static inline struct intel_wait *to_wait(struct rb_node *node) | 318 | static inline struct intel_wait *to_wait(struct rb_node *node) |
diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c index b2a6d62b71c0..e8884c2ade98 100644 --- a/drivers/gpu/drm/i915/intel_cdclk.c +++ b/drivers/gpu/drm/i915/intel_cdclk.c | |||
@@ -437,13 +437,45 @@ static int vlv_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk) | |||
437 | return 200000; | 437 | return 200000; |
438 | } | 438 | } |
439 | 439 | ||
440 | static u8 vlv_calc_voltage_level(struct drm_i915_private *dev_priv, int cdclk) | ||
441 | { | ||
442 | if (IS_VALLEYVIEW(dev_priv)) { | ||
443 | if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */ | ||
444 | return 2; | ||
445 | else if (cdclk >= 266667) | ||
446 | return 1; | ||
447 | else | ||
448 | return 0; | ||
449 | } else { | ||
450 | /* | ||
451 | * Specs are full of misinformation, but testing on actual | ||
452 | * hardware has shown that we just need to write the desired | ||
453 | * CCK divider into the Punit register. | ||
454 | */ | ||
455 | return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1; | ||
456 | } | ||
457 | } | ||
458 | |||
440 | static void vlv_get_cdclk(struct drm_i915_private *dev_priv, | 459 | static void vlv_get_cdclk(struct drm_i915_private *dev_priv, |
441 | struct intel_cdclk_state *cdclk_state) | 460 | struct intel_cdclk_state *cdclk_state) |
442 | { | 461 | { |
462 | u32 val; | ||
463 | |||
443 | cdclk_state->vco = vlv_get_hpll_vco(dev_priv); | 464 | cdclk_state->vco = vlv_get_hpll_vco(dev_priv); |
444 | cdclk_state->cdclk = vlv_get_cck_clock(dev_priv, "cdclk", | 465 | cdclk_state->cdclk = vlv_get_cck_clock(dev_priv, "cdclk", |
445 | CCK_DISPLAY_CLOCK_CONTROL, | 466 | CCK_DISPLAY_CLOCK_CONTROL, |
446 | cdclk_state->vco); | 467 | cdclk_state->vco); |
468 | |||
469 | mutex_lock(&dev_priv->pcu_lock); | ||
470 | val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); | ||
471 | mutex_unlock(&dev_priv->pcu_lock); | ||
472 | |||
473 | if (IS_VALLEYVIEW(dev_priv)) | ||
474 | cdclk_state->voltage_level = (val & DSPFREQGUAR_MASK) >> | ||
475 | DSPFREQGUAR_SHIFT; | ||
476 | else | ||
477 | cdclk_state->voltage_level = (val & DSPFREQGUAR_MASK_CHV) >> | ||
478 | DSPFREQGUAR_SHIFT_CHV; | ||
447 | } | 479 | } |
448 | 480 | ||
449 | static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv) | 481 | static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv) |
@@ -486,7 +518,19 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv, | |||
486 | const struct intel_cdclk_state *cdclk_state) | 518 | const struct intel_cdclk_state *cdclk_state) |
487 | { | 519 | { |
488 | int cdclk = cdclk_state->cdclk; | 520 | int cdclk = cdclk_state->cdclk; |
489 | u32 val, cmd; | 521 | u32 val, cmd = cdclk_state->voltage_level; |
522 | |||
523 | switch (cdclk) { | ||
524 | case 400000: | ||
525 | case 333333: | ||
526 | case 320000: | ||
527 | case 266667: | ||
528 | case 200000: | ||
529 | break; | ||
530 | default: | ||
531 | MISSING_CASE(cdclk); | ||
532 | return; | ||
533 | } | ||
490 | 534 | ||
491 | /* There are cases where we can end up here with power domains | 535 | /* There are cases where we can end up here with power domains |
492 | * off and a CDCLK frequency other than the minimum, like when | 536 | * off and a CDCLK frequency other than the minimum, like when |
@@ -496,13 +540,6 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv, | |||
496 | */ | 540 | */ |
497 | intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A); | 541 | intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A); |
498 | 542 | ||
499 | if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */ | ||
500 | cmd = 2; | ||
501 | else if (cdclk == 266667) | ||
502 | cmd = 1; | ||
503 | else | ||
504 | cmd = 0; | ||
505 | |||
506 | mutex_lock(&dev_priv->pcu_lock); | 543 | mutex_lock(&dev_priv->pcu_lock); |
507 | val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); | 544 | val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); |
508 | val &= ~DSPFREQGUAR_MASK; | 545 | val &= ~DSPFREQGUAR_MASK; |
@@ -562,7 +599,7 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv, | |||
562 | const struct intel_cdclk_state *cdclk_state) | 599 | const struct intel_cdclk_state *cdclk_state) |
563 | { | 600 | { |
564 | int cdclk = cdclk_state->cdclk; | 601 | int cdclk = cdclk_state->cdclk; |
565 | u32 val, cmd; | 602 | u32 val, cmd = cdclk_state->voltage_level; |
566 | 603 | ||
567 | switch (cdclk) { | 604 | switch (cdclk) { |
568 | case 333333: | 605 | case 333333: |
@@ -583,13 +620,6 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv, | |||
583 | */ | 620 | */ |
584 | intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A); | 621 | intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A); |
585 | 622 | ||
586 | /* | ||
587 | * Specs are full of misinformation, but testing on actual | ||
588 | * hardware has shown that we just need to write the desired | ||
589 | * CCK divider into the Punit register. | ||
590 | */ | ||
591 | cmd = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1; | ||
592 | |||
593 | mutex_lock(&dev_priv->pcu_lock); | 623 | mutex_lock(&dev_priv->pcu_lock); |
594 | val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); | 624 | val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); |
595 | val &= ~DSPFREQGUAR_MASK_CHV; | 625 | val &= ~DSPFREQGUAR_MASK_CHV; |
@@ -621,6 +651,21 @@ static int bdw_calc_cdclk(int min_cdclk) | |||
621 | return 337500; | 651 | return 337500; |
622 | } | 652 | } |
623 | 653 | ||
654 | static u8 bdw_calc_voltage_level(int cdclk) | ||
655 | { | ||
656 | switch (cdclk) { | ||
657 | default: | ||
658 | case 337500: | ||
659 | return 2; | ||
660 | case 450000: | ||
661 | return 0; | ||
662 | case 540000: | ||
663 | return 1; | ||
664 | case 675000: | ||
665 | return 3; | ||
666 | } | ||
667 | } | ||
668 | |||
624 | static void bdw_get_cdclk(struct drm_i915_private *dev_priv, | 669 | static void bdw_get_cdclk(struct drm_i915_private *dev_priv, |
625 | struct intel_cdclk_state *cdclk_state) | 670 | struct intel_cdclk_state *cdclk_state) |
626 | { | 671 | { |
@@ -639,13 +684,20 @@ static void bdw_get_cdclk(struct drm_i915_private *dev_priv, | |||
639 | cdclk_state->cdclk = 337500; | 684 | cdclk_state->cdclk = 337500; |
640 | else | 685 | else |
641 | cdclk_state->cdclk = 675000; | 686 | cdclk_state->cdclk = 675000; |
687 | |||
688 | /* | ||
689 | * Can't read this out :( Let's assume it's | ||
690 | * at least what the CDCLK frequency requires. | ||
691 | */ | ||
692 | cdclk_state->voltage_level = | ||
693 | bdw_calc_voltage_level(cdclk_state->cdclk); | ||
642 | } | 694 | } |
643 | 695 | ||
644 | static void bdw_set_cdclk(struct drm_i915_private *dev_priv, | 696 | static void bdw_set_cdclk(struct drm_i915_private *dev_priv, |
645 | const struct intel_cdclk_state *cdclk_state) | 697 | const struct intel_cdclk_state *cdclk_state) |
646 | { | 698 | { |
647 | int cdclk = cdclk_state->cdclk; | 699 | int cdclk = cdclk_state->cdclk; |
648 | uint32_t val, data; | 700 | uint32_t val; |
649 | int ret; | 701 | int ret; |
650 | 702 | ||
651 | if (WARN((I915_READ(LCPLL_CTL) & | 703 | if (WARN((I915_READ(LCPLL_CTL) & |
@@ -681,25 +733,21 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv, | |||
681 | val &= ~LCPLL_CLK_FREQ_MASK; | 733 | val &= ~LCPLL_CLK_FREQ_MASK; |
682 | 734 | ||
683 | switch (cdclk) { | 735 | switch (cdclk) { |
736 | default: | ||
737 | MISSING_CASE(cdclk); | ||
738 | /* fall through */ | ||
739 | case 337500: | ||
740 | val |= LCPLL_CLK_FREQ_337_5_BDW; | ||
741 | break; | ||
684 | case 450000: | 742 | case 450000: |
685 | val |= LCPLL_CLK_FREQ_450; | 743 | val |= LCPLL_CLK_FREQ_450; |
686 | data = 0; | ||
687 | break; | 744 | break; |
688 | case 540000: | 745 | case 540000: |
689 | val |= LCPLL_CLK_FREQ_54O_BDW; | 746 | val |= LCPLL_CLK_FREQ_54O_BDW; |
690 | data = 1; | ||
691 | break; | ||
692 | case 337500: | ||
693 | val |= LCPLL_CLK_FREQ_337_5_BDW; | ||
694 | data = 2; | ||
695 | break; | 747 | break; |
696 | case 675000: | 748 | case 675000: |
697 | val |= LCPLL_CLK_FREQ_675_BDW; | 749 | val |= LCPLL_CLK_FREQ_675_BDW; |
698 | data = 3; | ||
699 | break; | 750 | break; |
700 | default: | ||
701 | WARN(1, "invalid cdclk frequency\n"); | ||
702 | return; | ||
703 | } | 751 | } |
704 | 752 | ||
705 | I915_WRITE(LCPLL_CTL, val); | 753 | I915_WRITE(LCPLL_CTL, val); |
@@ -713,16 +761,13 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv, | |||
713 | DRM_ERROR("Switching back to LCPLL failed\n"); | 761 | DRM_ERROR("Switching back to LCPLL failed\n"); |
714 | 762 | ||
715 | mutex_lock(&dev_priv->pcu_lock); | 763 | mutex_lock(&dev_priv->pcu_lock); |
716 | sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, data); | 764 | sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, |
765 | cdclk_state->voltage_level); | ||
717 | mutex_unlock(&dev_priv->pcu_lock); | 766 | mutex_unlock(&dev_priv->pcu_lock); |
718 | 767 | ||
719 | I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1); | 768 | I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1); |
720 | 769 | ||
721 | intel_update_cdclk(dev_priv); | 770 | intel_update_cdclk(dev_priv); |
722 | |||
723 | WARN(cdclk != dev_priv->cdclk.hw.cdclk, | ||
724 | "cdclk requested %d kHz but got %d kHz\n", | ||
725 | cdclk, dev_priv->cdclk.hw.cdclk); | ||
726 | } | 771 | } |
727 | 772 | ||
728 | static int skl_calc_cdclk(int min_cdclk, int vco) | 773 | static int skl_calc_cdclk(int min_cdclk, int vco) |
@@ -748,6 +793,24 @@ static int skl_calc_cdclk(int min_cdclk, int vco) | |||
748 | } | 793 | } |
749 | } | 794 | } |
750 | 795 | ||
796 | static u8 skl_calc_voltage_level(int cdclk) | ||
797 | { | ||
798 | switch (cdclk) { | ||
799 | default: | ||
800 | case 308571: | ||
801 | case 337500: | ||
802 | return 0; | ||
803 | case 450000: | ||
804 | case 432000: | ||
805 | return 1; | ||
806 | case 540000: | ||
807 | return 2; | ||
808 | case 617143: | ||
809 | case 675000: | ||
810 | return 3; | ||
811 | } | ||
812 | } | ||
813 | |||
751 | static void skl_dpll0_update(struct drm_i915_private *dev_priv, | 814 | static void skl_dpll0_update(struct drm_i915_private *dev_priv, |
752 | struct intel_cdclk_state *cdclk_state) | 815 | struct intel_cdclk_state *cdclk_state) |
753 | { | 816 | { |
@@ -798,7 +861,7 @@ static void skl_get_cdclk(struct drm_i915_private *dev_priv, | |||
798 | cdclk_state->cdclk = cdclk_state->ref; | 861 | cdclk_state->cdclk = cdclk_state->ref; |
799 | 862 | ||
800 | if (cdclk_state->vco == 0) | 863 | if (cdclk_state->vco == 0) |
801 | return; | 864 | goto out; |
802 | 865 | ||
803 | cdctl = I915_READ(CDCLK_CTL); | 866 | cdctl = I915_READ(CDCLK_CTL); |
804 | 867 | ||
@@ -839,6 +902,14 @@ static void skl_get_cdclk(struct drm_i915_private *dev_priv, | |||
839 | break; | 902 | break; |
840 | } | 903 | } |
841 | } | 904 | } |
905 | |||
906 | out: | ||
907 | /* | ||
908 | * Can't read this out :( Let's assume it's | ||
909 | * at least what the CDCLK frequency requires. | ||
910 | */ | ||
911 | cdclk_state->voltage_level = | ||
912 | skl_calc_voltage_level(cdclk_state->cdclk); | ||
842 | } | 913 | } |
843 | 914 | ||
844 | /* convert from kHz to .1 fixpoint MHz with -1MHz offset */ | 915 | /* convert from kHz to .1 fixpoint MHz with -1MHz offset */ |
@@ -923,11 +994,9 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv, | |||
923 | { | 994 | { |
924 | int cdclk = cdclk_state->cdclk; | 995 | int cdclk = cdclk_state->cdclk; |
925 | int vco = cdclk_state->vco; | 996 | int vco = cdclk_state->vco; |
926 | u32 freq_select, pcu_ack; | 997 | u32 freq_select; |
927 | int ret; | 998 | int ret; |
928 | 999 | ||
929 | WARN_ON((cdclk == 24000) != (vco == 0)); | ||
930 | |||
931 | mutex_lock(&dev_priv->pcu_lock); | 1000 | mutex_lock(&dev_priv->pcu_lock); |
932 | ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL, | 1001 | ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL, |
933 | SKL_CDCLK_PREPARE_FOR_CHANGE, | 1002 | SKL_CDCLK_PREPARE_FOR_CHANGE, |
@@ -942,25 +1011,24 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv, | |||
942 | 1011 | ||
943 | /* set CDCLK_CTL */ | 1012 | /* set CDCLK_CTL */ |
944 | switch (cdclk) { | 1013 | switch (cdclk) { |
1014 | default: | ||
1015 | WARN_ON(cdclk != dev_priv->cdclk.hw.ref); | ||
1016 | WARN_ON(vco != 0); | ||
1017 | /* fall through */ | ||
1018 | case 308571: | ||
1019 | case 337500: | ||
1020 | freq_select = CDCLK_FREQ_337_308; | ||
1021 | break; | ||
945 | case 450000: | 1022 | case 450000: |
946 | case 432000: | 1023 | case 432000: |
947 | freq_select = CDCLK_FREQ_450_432; | 1024 | freq_select = CDCLK_FREQ_450_432; |
948 | pcu_ack = 1; | ||
949 | break; | 1025 | break; |
950 | case 540000: | 1026 | case 540000: |
951 | freq_select = CDCLK_FREQ_540; | 1027 | freq_select = CDCLK_FREQ_540; |
952 | pcu_ack = 2; | ||
953 | break; | ||
954 | case 308571: | ||
955 | case 337500: | ||
956 | default: | ||
957 | freq_select = CDCLK_FREQ_337_308; | ||
958 | pcu_ack = 0; | ||
959 | break; | 1028 | break; |
960 | case 617143: | 1029 | case 617143: |
961 | case 675000: | 1030 | case 675000: |
962 | freq_select = CDCLK_FREQ_675_617; | 1031 | freq_select = CDCLK_FREQ_675_617; |
963 | pcu_ack = 3; | ||
964 | break; | 1032 | break; |
965 | } | 1033 | } |
966 | 1034 | ||
@@ -976,7 +1044,8 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv, | |||
976 | 1044 | ||
977 | /* inform PCU of the change */ | 1045 | /* inform PCU of the change */ |
978 | mutex_lock(&dev_priv->pcu_lock); | 1046 | mutex_lock(&dev_priv->pcu_lock); |
979 | sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack); | 1047 | sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, |
1048 | cdclk_state->voltage_level); | ||
980 | mutex_unlock(&dev_priv->pcu_lock); | 1049 | mutex_unlock(&dev_priv->pcu_lock); |
981 | 1050 | ||
982 | intel_update_cdclk(dev_priv); | 1051 | intel_update_cdclk(dev_priv); |
@@ -995,6 +1064,8 @@ static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv) | |||
995 | goto sanitize; | 1064 | goto sanitize; |
996 | 1065 | ||
997 | intel_update_cdclk(dev_priv); | 1066 | intel_update_cdclk(dev_priv); |
1067 | intel_dump_cdclk_state(&dev_priv->cdclk.hw, "Current CDCLK"); | ||
1068 | |||
998 | /* Is PLL enabled and locked ? */ | 1069 | /* Is PLL enabled and locked ? */ |
999 | if (dev_priv->cdclk.hw.vco == 0 || | 1070 | if (dev_priv->cdclk.hw.vco == 0 || |
1000 | dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.ref) | 1071 | dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.ref) |
@@ -1055,6 +1126,7 @@ void skl_init_cdclk(struct drm_i915_private *dev_priv) | |||
1055 | if (cdclk_state.vco == 0) | 1126 | if (cdclk_state.vco == 0) |
1056 | cdclk_state.vco = 8100000; | 1127 | cdclk_state.vco = 8100000; |
1057 | cdclk_state.cdclk = skl_calc_cdclk(0, cdclk_state.vco); | 1128 | cdclk_state.cdclk = skl_calc_cdclk(0, cdclk_state.vco); |
1129 | cdclk_state.voltage_level = skl_calc_voltage_level(cdclk_state.cdclk); | ||
1058 | 1130 | ||
1059 | skl_set_cdclk(dev_priv, &cdclk_state); | 1131 | skl_set_cdclk(dev_priv, &cdclk_state); |
1060 | } | 1132 | } |
@@ -1072,6 +1144,7 @@ void skl_uninit_cdclk(struct drm_i915_private *dev_priv) | |||
1072 | 1144 | ||
1073 | cdclk_state.cdclk = cdclk_state.ref; | 1145 | cdclk_state.cdclk = cdclk_state.ref; |
1074 | cdclk_state.vco = 0; | 1146 | cdclk_state.vco = 0; |
1147 | cdclk_state.voltage_level = skl_calc_voltage_level(cdclk_state.cdclk); | ||
1075 | 1148 | ||
1076 | skl_set_cdclk(dev_priv, &cdclk_state); | 1149 | skl_set_cdclk(dev_priv, &cdclk_state); |
1077 | } | 1150 | } |
@@ -1100,6 +1173,11 @@ static int glk_calc_cdclk(int min_cdclk) | |||
1100 | return 79200; | 1173 | return 79200; |
1101 | } | 1174 | } |
1102 | 1175 | ||
1176 | static u8 bxt_calc_voltage_level(int cdclk) | ||
1177 | { | ||
1178 | return DIV_ROUND_UP(cdclk, 25000); | ||
1179 | } | ||
1180 | |||
1103 | static int bxt_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk) | 1181 | static int bxt_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk) |
1104 | { | 1182 | { |
1105 | int ratio; | 1183 | int ratio; |
@@ -1110,6 +1188,7 @@ static int bxt_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk) | |||
1110 | switch (cdclk) { | 1188 | switch (cdclk) { |
1111 | default: | 1189 | default: |
1112 | MISSING_CASE(cdclk); | 1190 | MISSING_CASE(cdclk); |
1191 | /* fall through */ | ||
1113 | case 144000: | 1192 | case 144000: |
1114 | case 288000: | 1193 | case 288000: |
1115 | case 384000: | 1194 | case 384000: |
@@ -1134,6 +1213,7 @@ static int glk_de_pll_vco(struct drm_i915_private *dev_priv, int cdclk) | |||
1134 | switch (cdclk) { | 1213 | switch (cdclk) { |
1135 | default: | 1214 | default: |
1136 | MISSING_CASE(cdclk); | 1215 | MISSING_CASE(cdclk); |
1216 | /* fall through */ | ||
1137 | case 79200: | 1217 | case 79200: |
1138 | case 158400: | 1218 | case 158400: |
1139 | case 316800: | 1219 | case 316800: |
@@ -1174,7 +1254,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv, | |||
1174 | cdclk_state->cdclk = cdclk_state->ref; | 1254 | cdclk_state->cdclk = cdclk_state->ref; |
1175 | 1255 | ||
1176 | if (cdclk_state->vco == 0) | 1256 | if (cdclk_state->vco == 0) |
1177 | return; | 1257 | goto out; |
1178 | 1258 | ||
1179 | divider = I915_READ(CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK; | 1259 | divider = I915_READ(CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK; |
1180 | 1260 | ||
@@ -1198,6 +1278,14 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv, | |||
1198 | } | 1278 | } |
1199 | 1279 | ||
1200 | cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div); | 1280 | cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div); |
1281 | |||
1282 | out: | ||
1283 | /* | ||
1284 | * Can't read this out :( Let's assume it's | ||
1285 | * at least what the CDCLK frequency requires. | ||
1286 | */ | ||
1287 | cdclk_state->voltage_level = | ||
1288 | bxt_calc_voltage_level(cdclk_state->cdclk); | ||
1201 | } | 1289 | } |
1202 | 1290 | ||
1203 | static void bxt_de_pll_disable(struct drm_i915_private *dev_priv) | 1291 | static void bxt_de_pll_disable(struct drm_i915_private *dev_priv) |
@@ -1246,24 +1334,22 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, | |||
1246 | 1334 | ||
1247 | /* cdclk = vco / 2 / div{1,1.5,2,4} */ | 1335 | /* cdclk = vco / 2 / div{1,1.5,2,4} */ |
1248 | switch (DIV_ROUND_CLOSEST(vco, cdclk)) { | 1336 | switch (DIV_ROUND_CLOSEST(vco, cdclk)) { |
1249 | case 8: | 1337 | default: |
1250 | divider = BXT_CDCLK_CD2X_DIV_SEL_4; | 1338 | WARN_ON(cdclk != dev_priv->cdclk.hw.ref); |
1251 | break; | 1339 | WARN_ON(vco != 0); |
1252 | case 4: | 1340 | /* fall through */ |
1253 | divider = BXT_CDCLK_CD2X_DIV_SEL_2; | 1341 | case 2: |
1342 | divider = BXT_CDCLK_CD2X_DIV_SEL_1; | ||
1254 | break; | 1343 | break; |
1255 | case 3: | 1344 | case 3: |
1256 | WARN(IS_GEMINILAKE(dev_priv), "Unsupported divider\n"); | 1345 | WARN(IS_GEMINILAKE(dev_priv), "Unsupported divider\n"); |
1257 | divider = BXT_CDCLK_CD2X_DIV_SEL_1_5; | 1346 | divider = BXT_CDCLK_CD2X_DIV_SEL_1_5; |
1258 | break; | 1347 | break; |
1259 | case 2: | 1348 | case 4: |
1260 | divider = BXT_CDCLK_CD2X_DIV_SEL_1; | 1349 | divider = BXT_CDCLK_CD2X_DIV_SEL_2; |
1261 | break; | 1350 | break; |
1262 | default: | 1351 | case 8: |
1263 | WARN_ON(cdclk != dev_priv->cdclk.hw.ref); | 1352 | divider = BXT_CDCLK_CD2X_DIV_SEL_4; |
1264 | WARN_ON(vco != 0); | ||
1265 | |||
1266 | divider = BXT_CDCLK_CD2X_DIV_SEL_1; | ||
1267 | break; | 1353 | break; |
1268 | } | 1354 | } |
1269 | 1355 | ||
@@ -1302,7 +1388,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, | |||
1302 | 1388 | ||
1303 | mutex_lock(&dev_priv->pcu_lock); | 1389 | mutex_lock(&dev_priv->pcu_lock); |
1304 | ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, | 1390 | ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, |
1305 | DIV_ROUND_UP(cdclk, 25000)); | 1391 | cdclk_state->voltage_level); |
1306 | mutex_unlock(&dev_priv->pcu_lock); | 1392 | mutex_unlock(&dev_priv->pcu_lock); |
1307 | 1393 | ||
1308 | if (ret) { | 1394 | if (ret) { |
@@ -1319,6 +1405,7 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) | |||
1319 | u32 cdctl, expected; | 1405 | u32 cdctl, expected; |
1320 | 1406 | ||
1321 | intel_update_cdclk(dev_priv); | 1407 | intel_update_cdclk(dev_priv); |
1408 | intel_dump_cdclk_state(&dev_priv->cdclk.hw, "Current CDCLK"); | ||
1322 | 1409 | ||
1323 | if (dev_priv->cdclk.hw.vco == 0 || | 1410 | if (dev_priv->cdclk.hw.vco == 0 || |
1324 | dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.ref) | 1411 | dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.ref) |
@@ -1394,6 +1481,7 @@ void bxt_init_cdclk(struct drm_i915_private *dev_priv) | |||
1394 | cdclk_state.cdclk = bxt_calc_cdclk(0); | 1481 | cdclk_state.cdclk = bxt_calc_cdclk(0); |
1395 | cdclk_state.vco = bxt_de_pll_vco(dev_priv, cdclk_state.cdclk); | 1482 | cdclk_state.vco = bxt_de_pll_vco(dev_priv, cdclk_state.cdclk); |
1396 | } | 1483 | } |
1484 | cdclk_state.voltage_level = bxt_calc_voltage_level(cdclk_state.cdclk); | ||
1397 | 1485 | ||
1398 | bxt_set_cdclk(dev_priv, &cdclk_state); | 1486 | bxt_set_cdclk(dev_priv, &cdclk_state); |
1399 | } | 1487 | } |
@@ -1411,6 +1499,7 @@ void bxt_uninit_cdclk(struct drm_i915_private *dev_priv) | |||
1411 | 1499 | ||
1412 | cdclk_state.cdclk = cdclk_state.ref; | 1500 | cdclk_state.cdclk = cdclk_state.ref; |
1413 | cdclk_state.vco = 0; | 1501 | cdclk_state.vco = 0; |
1502 | cdclk_state.voltage_level = bxt_calc_voltage_level(cdclk_state.cdclk); | ||
1414 | 1503 | ||
1415 | bxt_set_cdclk(dev_priv, &cdclk_state); | 1504 | bxt_set_cdclk(dev_priv, &cdclk_state); |
1416 | } | 1505 | } |
@@ -1425,6 +1514,19 @@ static int cnl_calc_cdclk(int min_cdclk) | |||
1425 | return 168000; | 1514 | return 168000; |
1426 | } | 1515 | } |
1427 | 1516 | ||
1517 | static u8 cnl_calc_voltage_level(int cdclk) | ||
1518 | { | ||
1519 | switch (cdclk) { | ||
1520 | default: | ||
1521 | case 168000: | ||
1522 | return 0; | ||
1523 | case 336000: | ||
1524 | return 1; | ||
1525 | case 528000: | ||
1526 | return 2; | ||
1527 | } | ||
1528 | } | ||
1529 | |||
1428 | static void cnl_cdclk_pll_update(struct drm_i915_private *dev_priv, | 1530 | static void cnl_cdclk_pll_update(struct drm_i915_private *dev_priv, |
1429 | struct intel_cdclk_state *cdclk_state) | 1531 | struct intel_cdclk_state *cdclk_state) |
1430 | { | 1532 | { |
@@ -1458,7 +1560,7 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv, | |||
1458 | cdclk_state->cdclk = cdclk_state->ref; | 1560 | cdclk_state->cdclk = cdclk_state->ref; |
1459 | 1561 | ||
1460 | if (cdclk_state->vco == 0) | 1562 | if (cdclk_state->vco == 0) |
1461 | return; | 1563 | goto out; |
1462 | 1564 | ||
1463 | divider = I915_READ(CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK; | 1565 | divider = I915_READ(CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK; |
1464 | 1566 | ||
@@ -1475,6 +1577,14 @@ static void cnl_get_cdclk(struct drm_i915_private *dev_priv, | |||
1475 | } | 1577 | } |
1476 | 1578 | ||
1477 | cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div); | 1579 | cdclk_state->cdclk = DIV_ROUND_CLOSEST(cdclk_state->vco, div); |
1580 | |||
1581 | out: | ||
1582 | /* | ||
1583 | * Can't read this out :( Let's assume it's | ||
1584 | * at least what the CDCLK frequency requires. | ||
1585 | */ | ||
1586 | cdclk_state->voltage_level = | ||
1587 | cnl_calc_voltage_level(cdclk_state->cdclk); | ||
1478 | } | 1588 | } |
1479 | 1589 | ||
1480 | static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv) | 1590 | static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv) |
@@ -1515,7 +1625,7 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv, | |||
1515 | { | 1625 | { |
1516 | int cdclk = cdclk_state->cdclk; | 1626 | int cdclk = cdclk_state->cdclk; |
1517 | int vco = cdclk_state->vco; | 1627 | int vco = cdclk_state->vco; |
1518 | u32 val, divider, pcu_ack; | 1628 | u32 val, divider; |
1519 | int ret; | 1629 | int ret; |
1520 | 1630 | ||
1521 | mutex_lock(&dev_priv->pcu_lock); | 1631 | mutex_lock(&dev_priv->pcu_lock); |
@@ -1532,30 +1642,15 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv, | |||
1532 | 1642 | ||
1533 | /* cdclk = vco / 2 / div{1,2} */ | 1643 | /* cdclk = vco / 2 / div{1,2} */ |
1534 | switch (DIV_ROUND_CLOSEST(vco, cdclk)) { | 1644 | switch (DIV_ROUND_CLOSEST(vco, cdclk)) { |
1535 | case 4: | ||
1536 | divider = BXT_CDCLK_CD2X_DIV_SEL_2; | ||
1537 | break; | ||
1538 | case 2: | ||
1539 | divider = BXT_CDCLK_CD2X_DIV_SEL_1; | ||
1540 | break; | ||
1541 | default: | 1645 | default: |
1542 | WARN_ON(cdclk != dev_priv->cdclk.hw.ref); | 1646 | WARN_ON(cdclk != dev_priv->cdclk.hw.ref); |
1543 | WARN_ON(vco != 0); | 1647 | WARN_ON(vco != 0); |
1544 | 1648 | /* fall through */ | |
1649 | case 2: | ||
1545 | divider = BXT_CDCLK_CD2X_DIV_SEL_1; | 1650 | divider = BXT_CDCLK_CD2X_DIV_SEL_1; |
1546 | break; | 1651 | break; |
1547 | } | 1652 | case 4: |
1548 | 1653 | divider = BXT_CDCLK_CD2X_DIV_SEL_2; | |
1549 | switch (cdclk) { | ||
1550 | case 528000: | ||
1551 | pcu_ack = 2; | ||
1552 | break; | ||
1553 | case 336000: | ||
1554 | pcu_ack = 1; | ||
1555 | break; | ||
1556 | case 168000: | ||
1557 | default: | ||
1558 | pcu_ack = 0; | ||
1559 | break; | 1654 | break; |
1560 | } | 1655 | } |
1561 | 1656 | ||
@@ -1576,10 +1671,17 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv, | |||
1576 | 1671 | ||
1577 | /* inform PCU of the change */ | 1672 | /* inform PCU of the change */ |
1578 | mutex_lock(&dev_priv->pcu_lock); | 1673 | mutex_lock(&dev_priv->pcu_lock); |
1579 | sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack); | 1674 | sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, |
1675 | cdclk_state->voltage_level); | ||
1580 | mutex_unlock(&dev_priv->pcu_lock); | 1676 | mutex_unlock(&dev_priv->pcu_lock); |
1581 | 1677 | ||
1582 | intel_update_cdclk(dev_priv); | 1678 | intel_update_cdclk(dev_priv); |
1679 | |||
1680 | /* | ||
1681 | * Can't read out the voltage level :( | ||
1682 | * Let's just assume everything is as expected. | ||
1683 | */ | ||
1684 | dev_priv->cdclk.hw.voltage_level = cdclk_state->voltage_level; | ||
1583 | } | 1685 | } |
1584 | 1686 | ||
1585 | static int cnl_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk) | 1687 | static int cnl_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk) |
@@ -1592,6 +1694,7 @@ static int cnl_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk) | |||
1592 | switch (cdclk) { | 1694 | switch (cdclk) { |
1593 | default: | 1695 | default: |
1594 | MISSING_CASE(cdclk); | 1696 | MISSING_CASE(cdclk); |
1697 | /* fall through */ | ||
1595 | case 168000: | 1698 | case 168000: |
1596 | case 336000: | 1699 | case 336000: |
1597 | ratio = dev_priv->cdclk.hw.ref == 19200 ? 35 : 28; | 1700 | ratio = dev_priv->cdclk.hw.ref == 19200 ? 35 : 28; |
@@ -1609,6 +1712,7 @@ static void cnl_sanitize_cdclk(struct drm_i915_private *dev_priv) | |||
1609 | u32 cdctl, expected; | 1712 | u32 cdctl, expected; |
1610 | 1713 | ||
1611 | intel_update_cdclk(dev_priv); | 1714 | intel_update_cdclk(dev_priv); |
1715 | intel_dump_cdclk_state(&dev_priv->cdclk.hw, "Current CDCLK"); | ||
1612 | 1716 | ||
1613 | if (dev_priv->cdclk.hw.vco == 0 || | 1717 | if (dev_priv->cdclk.hw.vco == 0 || |
1614 | dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.ref) | 1718 | dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.ref) |
@@ -1668,6 +1772,7 @@ void cnl_init_cdclk(struct drm_i915_private *dev_priv) | |||
1668 | 1772 | ||
1669 | cdclk_state.cdclk = cnl_calc_cdclk(0); | 1773 | cdclk_state.cdclk = cnl_calc_cdclk(0); |
1670 | cdclk_state.vco = cnl_cdclk_pll_vco(dev_priv, cdclk_state.cdclk); | 1774 | cdclk_state.vco = cnl_cdclk_pll_vco(dev_priv, cdclk_state.cdclk); |
1775 | cdclk_state.voltage_level = cnl_calc_voltage_level(cdclk_state.cdclk); | ||
1671 | 1776 | ||
1672 | cnl_set_cdclk(dev_priv, &cdclk_state); | 1777 | cnl_set_cdclk(dev_priv, &cdclk_state); |
1673 | } | 1778 | } |
@@ -1685,22 +1790,48 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv) | |||
1685 | 1790 | ||
1686 | cdclk_state.cdclk = cdclk_state.ref; | 1791 | cdclk_state.cdclk = cdclk_state.ref; |
1687 | cdclk_state.vco = 0; | 1792 | cdclk_state.vco = 0; |
1793 | cdclk_state.voltage_level = cnl_calc_voltage_level(cdclk_state.cdclk); | ||
1688 | 1794 | ||
1689 | cnl_set_cdclk(dev_priv, &cdclk_state); | 1795 | cnl_set_cdclk(dev_priv, &cdclk_state); |
1690 | } | 1796 | } |
1691 | 1797 | ||
1692 | /** | 1798 | /** |
1693 | * intel_cdclk_state_compare - Determine if two CDCLK states differ | 1799 | * intel_cdclk_needs_modeset - Determine if two CDCLK states require a modeset on all pipes |
1694 | * @a: first CDCLK state | 1800 | * @a: first CDCLK state |
1695 | * @b: second CDCLK state | 1801 | * @b: second CDCLK state |
1696 | * | 1802 | * |
1697 | * Returns: | 1803 | * Returns: |
1698 | * True if the CDCLK states are identical, false if they differ. | 1804 | * True if the CDCLK states require pipes to be off during reprogramming, false if not. |
1699 | */ | 1805 | */ |
1700 | bool intel_cdclk_state_compare(const struct intel_cdclk_state *a, | 1806 | bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a, |
1701 | const struct intel_cdclk_state *b) | 1807 | const struct intel_cdclk_state *b) |
1702 | { | 1808 | { |
1703 | return memcmp(a, b, sizeof(*a)) == 0; | 1809 | return a->cdclk != b->cdclk || |
1810 | a->vco != b->vco || | ||
1811 | a->ref != b->ref; | ||
1812 | } | ||
1813 | |||
1814 | /** | ||
1815 | * intel_cdclk_changed - Determine if two CDCLK states are different | ||
1816 | * @a: first CDCLK state | ||
1817 | * @b: second CDCLK state | ||
1818 | * | ||
1819 | * Returns: | ||
1820 | * True if the CDCLK states don't match, false if they do. | ||
1821 | */ | ||
1822 | bool intel_cdclk_changed(const struct intel_cdclk_state *a, | ||
1823 | const struct intel_cdclk_state *b) | ||
1824 | { | ||
1825 | return intel_cdclk_needs_modeset(a, b) || | ||
1826 | a->voltage_level != b->voltage_level; | ||
1827 | } | ||
1828 | |||
1829 | void intel_dump_cdclk_state(const struct intel_cdclk_state *cdclk_state, | ||
1830 | const char *context) | ||
1831 | { | ||
1832 | DRM_DEBUG_DRIVER("%s %d kHz, VCO %d kHz, ref %d kHz, voltage level %d\n", | ||
1833 | context, cdclk_state->cdclk, cdclk_state->vco, | ||
1834 | cdclk_state->ref, cdclk_state->voltage_level); | ||
1704 | } | 1835 | } |
1705 | 1836 | ||
1706 | /** | 1837 | /** |
@@ -1714,29 +1845,28 @@ bool intel_cdclk_state_compare(const struct intel_cdclk_state *a, | |||
1714 | void intel_set_cdclk(struct drm_i915_private *dev_priv, | 1845 | void intel_set_cdclk(struct drm_i915_private *dev_priv, |
1715 | const struct intel_cdclk_state *cdclk_state) | 1846 | const struct intel_cdclk_state *cdclk_state) |
1716 | { | 1847 | { |
1717 | if (intel_cdclk_state_compare(&dev_priv->cdclk.hw, cdclk_state)) | 1848 | if (!intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_state)) |
1718 | return; | 1849 | return; |
1719 | 1850 | ||
1720 | if (WARN_ON_ONCE(!dev_priv->display.set_cdclk)) | 1851 | if (WARN_ON_ONCE(!dev_priv->display.set_cdclk)) |
1721 | return; | 1852 | return; |
1722 | 1853 | ||
1723 | DRM_DEBUG_DRIVER("Changing CDCLK to %d kHz, VCO %d kHz, ref %d kHz\n", | 1854 | intel_dump_cdclk_state(cdclk_state, "Changing CDCLK to"); |
1724 | cdclk_state->cdclk, cdclk_state->vco, | ||
1725 | cdclk_state->ref); | ||
1726 | 1855 | ||
1727 | dev_priv->display.set_cdclk(dev_priv, cdclk_state); | 1856 | dev_priv->display.set_cdclk(dev_priv, cdclk_state); |
1857 | |||
1858 | if (WARN(intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_state), | ||
1859 | "cdclk state doesn't match!\n")) { | ||
1860 | intel_dump_cdclk_state(&dev_priv->cdclk.hw, "[hw state]"); | ||
1861 | intel_dump_cdclk_state(cdclk_state, "[sw state]"); | ||
1862 | } | ||
1728 | } | 1863 | } |
1729 | 1864 | ||
1730 | static int intel_pixel_rate_to_cdclk(struct drm_i915_private *dev_priv, | 1865 | static int intel_pixel_rate_to_cdclk(struct drm_i915_private *dev_priv, |
1731 | int pixel_rate) | 1866 | int pixel_rate) |
1732 | { | 1867 | { |
1733 | if (INTEL_GEN(dev_priv) >= 10) | 1868 | if (INTEL_GEN(dev_priv) >= 10) |
1734 | /* | 1869 | return DIV_ROUND_UP(pixel_rate, 2); |
1735 | * FIXME: Switch to DIV_ROUND_UP(pixel_rate, 2) | ||
1736 | * once DDI clock voltage requirements are | ||
1737 | * handled correctly. | ||
1738 | */ | ||
1739 | return pixel_rate; | ||
1740 | else if (IS_GEMINILAKE(dev_priv)) | 1870 | else if (IS_GEMINILAKE(dev_priv)) |
1741 | /* | 1871 | /* |
1742 | * FIXME: Avoid using a pixel clock that is more than 99% of the cdclk | 1872 | * FIXME: Avoid using a pixel clock that is more than 99% of the cdclk |
@@ -1829,6 +1959,43 @@ static int intel_compute_min_cdclk(struct drm_atomic_state *state) | |||
1829 | return min_cdclk; | 1959 | return min_cdclk; |
1830 | } | 1960 | } |
1831 | 1961 | ||
1962 | /* | ||
1963 | * Note that this functions assumes that 0 is | ||
1964 | * the lowest voltage value, and higher values | ||
1965 | * correspond to increasingly higher voltages. | ||
1966 | * | ||
1967 | * Should that relationship no longer hold on | ||
1968 | * future platforms this code will need to be | ||
1969 | * adjusted. | ||
1970 | */ | ||
1971 | static u8 cnl_compute_min_voltage_level(struct intel_atomic_state *state) | ||
1972 | { | ||
1973 | struct drm_i915_private *dev_priv = to_i915(state->base.dev); | ||
1974 | struct intel_crtc *crtc; | ||
1975 | struct intel_crtc_state *crtc_state; | ||
1976 | u8 min_voltage_level; | ||
1977 | int i; | ||
1978 | enum pipe pipe; | ||
1979 | |||
1980 | memcpy(state->min_voltage_level, dev_priv->min_voltage_level, | ||
1981 | sizeof(state->min_voltage_level)); | ||
1982 | |||
1983 | for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { | ||
1984 | if (crtc_state->base.enable) | ||
1985 | state->min_voltage_level[i] = | ||
1986 | crtc_state->min_voltage_level; | ||
1987 | else | ||
1988 | state->min_voltage_level[i] = 0; | ||
1989 | } | ||
1990 | |||
1991 | min_voltage_level = 0; | ||
1992 | for_each_pipe(dev_priv, pipe) | ||
1993 | min_voltage_level = max(state->min_voltage_level[pipe], | ||
1994 | min_voltage_level); | ||
1995 | |||
1996 | return min_voltage_level; | ||
1997 | } | ||
1998 | |||
1832 | static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state) | 1999 | static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state) |
1833 | { | 2000 | { |
1834 | struct drm_i915_private *dev_priv = to_i915(state->dev); | 2001 | struct drm_i915_private *dev_priv = to_i915(state->dev); |
@@ -1842,11 +2009,15 @@ static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state) | |||
1842 | cdclk = vlv_calc_cdclk(dev_priv, min_cdclk); | 2009 | cdclk = vlv_calc_cdclk(dev_priv, min_cdclk); |
1843 | 2010 | ||
1844 | intel_state->cdclk.logical.cdclk = cdclk; | 2011 | intel_state->cdclk.logical.cdclk = cdclk; |
2012 | intel_state->cdclk.logical.voltage_level = | ||
2013 | vlv_calc_voltage_level(dev_priv, cdclk); | ||
1845 | 2014 | ||
1846 | if (!intel_state->active_crtcs) { | 2015 | if (!intel_state->active_crtcs) { |
1847 | cdclk = vlv_calc_cdclk(dev_priv, 0); | 2016 | cdclk = vlv_calc_cdclk(dev_priv, 0); |
1848 | 2017 | ||
1849 | intel_state->cdclk.actual.cdclk = cdclk; | 2018 | intel_state->cdclk.actual.cdclk = cdclk; |
2019 | intel_state->cdclk.actual.voltage_level = | ||
2020 | vlv_calc_voltage_level(dev_priv, cdclk); | ||
1850 | } else { | 2021 | } else { |
1851 | intel_state->cdclk.actual = | 2022 | intel_state->cdclk.actual = |
1852 | intel_state->cdclk.logical; | 2023 | intel_state->cdclk.logical; |
@@ -1871,11 +2042,15 @@ static int bdw_modeset_calc_cdclk(struct drm_atomic_state *state) | |||
1871 | cdclk = bdw_calc_cdclk(min_cdclk); | 2042 | cdclk = bdw_calc_cdclk(min_cdclk); |
1872 | 2043 | ||
1873 | intel_state->cdclk.logical.cdclk = cdclk; | 2044 | intel_state->cdclk.logical.cdclk = cdclk; |
2045 | intel_state->cdclk.logical.voltage_level = | ||
2046 | bdw_calc_voltage_level(cdclk); | ||
1874 | 2047 | ||
1875 | if (!intel_state->active_crtcs) { | 2048 | if (!intel_state->active_crtcs) { |
1876 | cdclk = bdw_calc_cdclk(0); | 2049 | cdclk = bdw_calc_cdclk(0); |
1877 | 2050 | ||
1878 | intel_state->cdclk.actual.cdclk = cdclk; | 2051 | intel_state->cdclk.actual.cdclk = cdclk; |
2052 | intel_state->cdclk.actual.voltage_level = | ||
2053 | bdw_calc_voltage_level(cdclk); | ||
1879 | } else { | 2054 | } else { |
1880 | intel_state->cdclk.actual = | 2055 | intel_state->cdclk.actual = |
1881 | intel_state->cdclk.logical; | 2056 | intel_state->cdclk.logical; |
@@ -1906,12 +2081,16 @@ static int skl_modeset_calc_cdclk(struct drm_atomic_state *state) | |||
1906 | 2081 | ||
1907 | intel_state->cdclk.logical.vco = vco; | 2082 | intel_state->cdclk.logical.vco = vco; |
1908 | intel_state->cdclk.logical.cdclk = cdclk; | 2083 | intel_state->cdclk.logical.cdclk = cdclk; |
2084 | intel_state->cdclk.logical.voltage_level = | ||
2085 | skl_calc_voltage_level(cdclk); | ||
1909 | 2086 | ||
1910 | if (!intel_state->active_crtcs) { | 2087 | if (!intel_state->active_crtcs) { |
1911 | cdclk = skl_calc_cdclk(0, vco); | 2088 | cdclk = skl_calc_cdclk(0, vco); |
1912 | 2089 | ||
1913 | intel_state->cdclk.actual.vco = vco; | 2090 | intel_state->cdclk.actual.vco = vco; |
1914 | intel_state->cdclk.actual.cdclk = cdclk; | 2091 | intel_state->cdclk.actual.cdclk = cdclk; |
2092 | intel_state->cdclk.actual.voltage_level = | ||
2093 | skl_calc_voltage_level(cdclk); | ||
1915 | } else { | 2094 | } else { |
1916 | intel_state->cdclk.actual = | 2095 | intel_state->cdclk.actual = |
1917 | intel_state->cdclk.logical; | 2096 | intel_state->cdclk.logical; |
@@ -1940,6 +2119,8 @@ static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state) | |||
1940 | 2119 | ||
1941 | intel_state->cdclk.logical.vco = vco; | 2120 | intel_state->cdclk.logical.vco = vco; |
1942 | intel_state->cdclk.logical.cdclk = cdclk; | 2121 | intel_state->cdclk.logical.cdclk = cdclk; |
2122 | intel_state->cdclk.logical.voltage_level = | ||
2123 | bxt_calc_voltage_level(cdclk); | ||
1943 | 2124 | ||
1944 | if (!intel_state->active_crtcs) { | 2125 | if (!intel_state->active_crtcs) { |
1945 | if (IS_GEMINILAKE(dev_priv)) { | 2126 | if (IS_GEMINILAKE(dev_priv)) { |
@@ -1952,6 +2133,8 @@ static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state) | |||
1952 | 2133 | ||
1953 | intel_state->cdclk.actual.vco = vco; | 2134 | intel_state->cdclk.actual.vco = vco; |
1954 | intel_state->cdclk.actual.cdclk = cdclk; | 2135 | intel_state->cdclk.actual.cdclk = cdclk; |
2136 | intel_state->cdclk.actual.voltage_level = | ||
2137 | bxt_calc_voltage_level(cdclk); | ||
1955 | } else { | 2138 | } else { |
1956 | intel_state->cdclk.actual = | 2139 | intel_state->cdclk.actual = |
1957 | intel_state->cdclk.logical; | 2140 | intel_state->cdclk.logical; |
@@ -1975,6 +2158,9 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state) | |||
1975 | 2158 | ||
1976 | intel_state->cdclk.logical.vco = vco; | 2159 | intel_state->cdclk.logical.vco = vco; |
1977 | intel_state->cdclk.logical.cdclk = cdclk; | 2160 | intel_state->cdclk.logical.cdclk = cdclk; |
2161 | intel_state->cdclk.logical.voltage_level = | ||
2162 | max(cnl_calc_voltage_level(cdclk), | ||
2163 | cnl_compute_min_voltage_level(intel_state)); | ||
1978 | 2164 | ||
1979 | if (!intel_state->active_crtcs) { | 2165 | if (!intel_state->active_crtcs) { |
1980 | cdclk = cnl_calc_cdclk(0); | 2166 | cdclk = cnl_calc_cdclk(0); |
@@ -1982,6 +2168,8 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state) | |||
1982 | 2168 | ||
1983 | intel_state->cdclk.actual.vco = vco; | 2169 | intel_state->cdclk.actual.vco = vco; |
1984 | intel_state->cdclk.actual.cdclk = cdclk; | 2170 | intel_state->cdclk.actual.cdclk = cdclk; |
2171 | intel_state->cdclk.actual.voltage_level = | ||
2172 | cnl_calc_voltage_level(cdclk); | ||
1985 | } else { | 2173 | } else { |
1986 | intel_state->cdclk.actual = | 2174 | intel_state->cdclk.actual = |
1987 | intel_state->cdclk.logical; | 2175 | intel_state->cdclk.logical; |
@@ -1995,12 +2183,7 @@ static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv) | |||
1995 | int max_cdclk_freq = dev_priv->max_cdclk_freq; | 2183 | int max_cdclk_freq = dev_priv->max_cdclk_freq; |
1996 | 2184 | ||
1997 | if (INTEL_GEN(dev_priv) >= 10) | 2185 | if (INTEL_GEN(dev_priv) >= 10) |
1998 | /* | 2186 | return 2 * max_cdclk_freq; |
1999 | * FIXME: Allow '2 * max_cdclk_freq' | ||
2000 | * once DDI clock voltage requirements are | ||
2001 | * handled correctly. | ||
2002 | */ | ||
2003 | return max_cdclk_freq; | ||
2004 | else if (IS_GEMINILAKE(dev_priv)) | 2187 | else if (IS_GEMINILAKE(dev_priv)) |
2005 | /* | 2188 | /* |
2006 | * FIXME: Limiting to 99% as a temporary workaround. See | 2189 | * FIXME: Limiting to 99% as a temporary workaround. See |
@@ -2099,10 +2282,6 @@ void intel_update_cdclk(struct drm_i915_private *dev_priv) | |||
2099 | { | 2282 | { |
2100 | dev_priv->display.get_cdclk(dev_priv, &dev_priv->cdclk.hw); | 2283 | dev_priv->display.get_cdclk(dev_priv, &dev_priv->cdclk.hw); |
2101 | 2284 | ||
2102 | DRM_DEBUG_DRIVER("Current CD clock rate: %d kHz, VCO: %d kHz, ref: %d kHz\n", | ||
2103 | dev_priv->cdclk.hw.cdclk, dev_priv->cdclk.hw.vco, | ||
2104 | dev_priv->cdclk.hw.ref); | ||
2105 | |||
2106 | /* | 2285 | /* |
2107 | * 9:0 CMBUS [sic] CDCLK frequency (cdfreq): | 2286 | * 9:0 CMBUS [sic] CDCLK frequency (cdfreq): |
2108 | * Programmng [sic] note: bit[9:2] should be programmed to the number | 2287 | * Programmng [sic] note: bit[9:2] should be programmed to the number |
diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index b8315bca852b..aa66e952a95d 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c | |||
@@ -370,7 +370,7 @@ static void haswell_load_luts(struct drm_crtc_state *crtc_state) | |||
370 | */ | 370 | */ |
371 | if (IS_HASWELL(dev_priv) && intel_crtc_state->ips_enabled && | 371 | if (IS_HASWELL(dev_priv) && intel_crtc_state->ips_enabled && |
372 | (intel_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)) { | 372 | (intel_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)) { |
373 | hsw_disable_ips(intel_crtc); | 373 | hsw_disable_ips(intel_crtc_state); |
374 | reenable_ips = true; | 374 | reenable_ips = true; |
375 | } | 375 | } |
376 | 376 | ||
@@ -380,7 +380,7 @@ static void haswell_load_luts(struct drm_crtc_state *crtc_state) | |||
380 | i9xx_load_luts(crtc_state); | 380 | i9xx_load_luts(crtc_state); |
381 | 381 | ||
382 | if (reenable_ips) | 382 | if (reenable_ips) |
383 | hsw_enable_ips(intel_crtc); | 383 | hsw_enable_ips(intel_crtc_state); |
384 | } | 384 | } |
385 | 385 | ||
386 | static void bdw_load_degamma_lut(struct drm_crtc_state *state) | 386 | static void bdw_load_degamma_lut(struct drm_crtc_state *state) |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 437339f5d098..9f31aea51dff 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -119,6 +119,8 @@ static unsigned int intel_crt_get_flags(struct intel_encoder *encoder) | |||
119 | static void intel_crt_get_config(struct intel_encoder *encoder, | 119 | static void intel_crt_get_config(struct intel_encoder *encoder, |
120 | struct intel_crtc_state *pipe_config) | 120 | struct intel_crtc_state *pipe_config) |
121 | { | 121 | { |
122 | pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); | ||
123 | |||
122 | pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder); | 124 | pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder); |
123 | 125 | ||
124 | pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; | 126 | pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; |
@@ -217,11 +219,9 @@ static void hsw_disable_crt(struct intel_encoder *encoder, | |||
217 | const struct intel_crtc_state *old_crtc_state, | 219 | const struct intel_crtc_state *old_crtc_state, |
218 | const struct drm_connector_state *old_conn_state) | 220 | const struct drm_connector_state *old_conn_state) |
219 | { | 221 | { |
220 | struct drm_crtc *crtc = old_crtc_state->base.crtc; | 222 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
221 | struct drm_i915_private *dev_priv = to_i915(crtc->dev); | ||
222 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
223 | 223 | ||
224 | WARN_ON(!intel_crtc->config->has_pch_encoder); | 224 | WARN_ON(!old_crtc_state->has_pch_encoder); |
225 | 225 | ||
226 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); | 226 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); |
227 | } | 227 | } |
@@ -245,46 +245,42 @@ static void hsw_post_disable_crt(struct intel_encoder *encoder, | |||
245 | } | 245 | } |
246 | 246 | ||
247 | static void hsw_pre_pll_enable_crt(struct intel_encoder *encoder, | 247 | static void hsw_pre_pll_enable_crt(struct intel_encoder *encoder, |
248 | const struct intel_crtc_state *pipe_config, | 248 | const struct intel_crtc_state *crtc_state, |
249 | const struct drm_connector_state *conn_state) | 249 | const struct drm_connector_state *conn_state) |
250 | { | 250 | { |
251 | struct drm_crtc *crtc = pipe_config->base.crtc; | 251 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
252 | struct drm_i915_private *dev_priv = to_i915(crtc->dev); | ||
253 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
254 | 252 | ||
255 | WARN_ON(!intel_crtc->config->has_pch_encoder); | 253 | WARN_ON(!crtc_state->has_pch_encoder); |
256 | 254 | ||
257 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); | 255 | intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); |
258 | } | 256 | } |
259 | 257 | ||
260 | static void hsw_pre_enable_crt(struct intel_encoder *encoder, | 258 | static void hsw_pre_enable_crt(struct intel_encoder *encoder, |
261 | const struct intel_crtc_state *pipe_config, | 259 | const struct intel_crtc_state *crtc_state, |
262 | const struct drm_connector_state *conn_state) | 260 | const struct drm_connector_state *conn_state) |
263 | { | 261 | { |
264 | struct drm_crtc *crtc = pipe_config->base.crtc; | 262 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
265 | struct drm_i915_private *dev_priv = to_i915(crtc->dev); | 263 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
266 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 264 | enum pipe pipe = crtc->pipe; |
267 | int pipe = intel_crtc->pipe; | ||
268 | 265 | ||
269 | WARN_ON(!intel_crtc->config->has_pch_encoder); | 266 | WARN_ON(!crtc_state->has_pch_encoder); |
270 | 267 | ||
271 | intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); | 268 | intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); |
272 | 269 | ||
273 | dev_priv->display.fdi_link_train(intel_crtc, pipe_config); | 270 | dev_priv->display.fdi_link_train(crtc, crtc_state); |
274 | } | 271 | } |
275 | 272 | ||
276 | static void hsw_enable_crt(struct intel_encoder *encoder, | 273 | static void hsw_enable_crt(struct intel_encoder *encoder, |
277 | const struct intel_crtc_state *pipe_config, | 274 | const struct intel_crtc_state *crtc_state, |
278 | const struct drm_connector_state *conn_state) | 275 | const struct drm_connector_state *conn_state) |
279 | { | 276 | { |
280 | struct drm_crtc *crtc = pipe_config->base.crtc; | 277 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
281 | struct drm_i915_private *dev_priv = to_i915(crtc->dev); | 278 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
282 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 279 | enum pipe pipe = crtc->pipe; |
283 | int pipe = intel_crtc->pipe; | ||
284 | 280 | ||
285 | WARN_ON(!intel_crtc->config->has_pch_encoder); | 281 | WARN_ON(!crtc_state->has_pch_encoder); |
286 | 282 | ||
287 | intel_crt_set_dpms(encoder, pipe_config, DRM_MODE_DPMS_ON); | 283 | intel_crt_set_dpms(encoder, crtc_state, DRM_MODE_DPMS_ON); |
288 | 284 | ||
289 | intel_wait_for_vblank(dev_priv, pipe); | 285 | intel_wait_for_vblank(dev_priv, pipe); |
290 | intel_wait_for_vblank(dev_priv, pipe); | 286 | intel_wait_for_vblank(dev_priv, pipe); |
@@ -293,10 +289,10 @@ static void hsw_enable_crt(struct intel_encoder *encoder, | |||
293 | } | 289 | } |
294 | 290 | ||
295 | static void intel_enable_crt(struct intel_encoder *encoder, | 291 | static void intel_enable_crt(struct intel_encoder *encoder, |
296 | const struct intel_crtc_state *pipe_config, | 292 | const struct intel_crtc_state *crtc_state, |
297 | const struct drm_connector_state *conn_state) | 293 | const struct drm_connector_state *conn_state) |
298 | { | 294 | { |
299 | intel_crt_set_dpms(encoder, pipe_config, DRM_MODE_DPMS_ON); | 295 | intel_crt_set_dpms(encoder, crtc_state, DRM_MODE_DPMS_ON); |
300 | } | 296 | } |
301 | 297 | ||
302 | static enum drm_mode_status | 298 | static enum drm_mode_status |
diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index da9de47562b8..77d8b3d483ca 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c | |||
@@ -37,8 +37,8 @@ | |||
37 | #define I915_CSR_GLK "i915/glk_dmc_ver1_04.bin" | 37 | #define I915_CSR_GLK "i915/glk_dmc_ver1_04.bin" |
38 | #define GLK_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) | 38 | #define GLK_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) |
39 | 39 | ||
40 | #define I915_CSR_CNL "i915/cnl_dmc_ver1_04.bin" | 40 | #define I915_CSR_CNL "i915/cnl_dmc_ver1_06.bin" |
41 | #define CNL_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) | 41 | #define CNL_CSR_VERSION_REQUIRED CSR_VERSION(1, 6) |
42 | 42 | ||
43 | #define I915_CSR_KBL "i915/kbl_dmc_ver1_01.bin" | 43 | #define I915_CSR_KBL "i915/kbl_dmc_ver1_01.bin" |
44 | MODULE_FIRMWARE(I915_CSR_KBL); | 44 | MODULE_FIRMWARE(I915_CSR_KBL); |
@@ -198,6 +198,7 @@ intel_get_stepping_info(struct drm_i915_private *dev_priv) | |||
198 | si = bxt_stepping_info; | 198 | si = bxt_stepping_info; |
199 | } else { | 199 | } else { |
200 | size = 0; | 200 | size = 0; |
201 | si = NULL; | ||
201 | } | 202 | } |
202 | 203 | ||
203 | if (INTEL_REVID(dev_priv) < size) | 204 | if (INTEL_REVID(dev_priv) < size) |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 933c18fd4258..eff3b51872eb 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -492,24 +492,6 @@ static const struct cnl_ddi_buf_trans cnl_ddi_translations_edp_1_05V[] = { | |||
492 | { 0x2, 0x7F, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */ | 492 | { 0x2, 0x7F, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */ |
493 | }; | 493 | }; |
494 | 494 | ||
495 | enum port intel_ddi_get_encoder_port(struct intel_encoder *encoder) | ||
496 | { | ||
497 | switch (encoder->type) { | ||
498 | case INTEL_OUTPUT_DP_MST: | ||
499 | return enc_to_mst(&encoder->base)->primary->port; | ||
500 | case INTEL_OUTPUT_DP: | ||
501 | case INTEL_OUTPUT_EDP: | ||
502 | case INTEL_OUTPUT_HDMI: | ||
503 | case INTEL_OUTPUT_UNKNOWN: | ||
504 | return enc_to_dig_port(&encoder->base)->port; | ||
505 | case INTEL_OUTPUT_ANALOG: | ||
506 | return PORT_E; | ||
507 | default: | ||
508 | MISSING_CASE(encoder->type); | ||
509 | return PORT_A; | ||
510 | } | ||
511 | } | ||
512 | |||
513 | static const struct ddi_buf_trans * | 495 | static const struct ddi_buf_trans * |
514 | bdw_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries) | 496 | bdw_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries) |
515 | { | 497 | { |
@@ -811,31 +793,24 @@ static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port por | |||
811 | * values in advance. This function programs the correct values for | 793 | * values in advance. This function programs the correct values for |
812 | * DP/eDP/FDI use cases. | 794 | * DP/eDP/FDI use cases. |
813 | */ | 795 | */ |
814 | static void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder) | 796 | static void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder, |
797 | const struct intel_crtc_state *crtc_state) | ||
815 | { | 798 | { |
816 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 799 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
817 | u32 iboost_bit = 0; | 800 | u32 iboost_bit = 0; |
818 | int i, n_entries; | 801 | int i, n_entries; |
819 | enum port port = intel_ddi_get_encoder_port(encoder); | 802 | enum port port = encoder->port; |
820 | const struct ddi_buf_trans *ddi_translations; | 803 | const struct ddi_buf_trans *ddi_translations; |
821 | 804 | ||
822 | switch (encoder->type) { | 805 | if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) |
823 | case INTEL_OUTPUT_EDP: | 806 | ddi_translations = intel_ddi_get_buf_trans_fdi(dev_priv, |
807 | &n_entries); | ||
808 | else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) | ||
824 | ddi_translations = intel_ddi_get_buf_trans_edp(dev_priv, port, | 809 | ddi_translations = intel_ddi_get_buf_trans_edp(dev_priv, port, |
825 | &n_entries); | 810 | &n_entries); |
826 | break; | 811 | else |
827 | case INTEL_OUTPUT_DP: | ||
828 | ddi_translations = intel_ddi_get_buf_trans_dp(dev_priv, port, | 812 | ddi_translations = intel_ddi_get_buf_trans_dp(dev_priv, port, |
829 | &n_entries); | 813 | &n_entries); |
830 | break; | ||
831 | case INTEL_OUTPUT_ANALOG: | ||
832 | ddi_translations = intel_ddi_get_buf_trans_fdi(dev_priv, | ||
833 | &n_entries); | ||
834 | break; | ||
835 | default: | ||
836 | MISSING_CASE(encoder->type); | ||
837 | return; | ||
838 | } | ||
839 | 814 | ||
840 | /* If we're boosting the current, set bit 31 of trans1 */ | 815 | /* If we're boosting the current, set bit 31 of trans1 */ |
841 | if (IS_GEN9_BC(dev_priv) && | 816 | if (IS_GEN9_BC(dev_priv) && |
@@ -861,7 +836,7 @@ static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, | |||
861 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 836 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
862 | u32 iboost_bit = 0; | 837 | u32 iboost_bit = 0; |
863 | int n_entries; | 838 | int n_entries; |
864 | enum port port = intel_ddi_get_encoder_port(encoder); | 839 | enum port port = encoder->port; |
865 | const struct ddi_buf_trans *ddi_translations; | 840 | const struct ddi_buf_trans *ddi_translations; |
866 | 841 | ||
867 | ddi_translations = intel_ddi_get_buf_trans_hdmi(dev_priv, &n_entries); | 842 | ddi_translations = intel_ddi_get_buf_trans_hdmi(dev_priv, &n_entries); |
@@ -937,7 +912,7 @@ void hsw_fdi_link_train(struct intel_crtc *crtc, | |||
937 | 912 | ||
938 | for_each_encoder_on_crtc(dev, &crtc->base, encoder) { | 913 | for_each_encoder_on_crtc(dev, &crtc->base, encoder) { |
939 | WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG); | 914 | WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG); |
940 | intel_prepare_dp_ddi_buffers(encoder); | 915 | intel_prepare_dp_ddi_buffers(encoder, crtc_state); |
941 | } | 916 | } |
942 | 917 | ||
943 | /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the | 918 | /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the |
@@ -1448,19 +1423,16 @@ static void hsw_ddi_clock_get(struct intel_encoder *encoder, | |||
1448 | ddi_dotclock_get(pipe_config); | 1423 | ddi_dotclock_get(pipe_config); |
1449 | } | 1424 | } |
1450 | 1425 | ||
1451 | static int bxt_calc_pll_link(struct drm_i915_private *dev_priv, | 1426 | static int bxt_calc_pll_link(struct intel_crtc_state *crtc_state) |
1452 | enum intel_dpll_id pll_id) | ||
1453 | { | 1427 | { |
1454 | struct intel_shared_dpll *pll; | ||
1455 | struct intel_dpll_hw_state *state; | 1428 | struct intel_dpll_hw_state *state; |
1456 | struct dpll clock; | 1429 | struct dpll clock; |
1457 | 1430 | ||
1458 | /* For DDI ports we always use a shared PLL. */ | 1431 | /* For DDI ports we always use a shared PLL. */ |
1459 | if (WARN_ON(pll_id == DPLL_ID_PRIVATE)) | 1432 | if (WARN_ON(!crtc_state->shared_dpll)) |
1460 | return 0; | 1433 | return 0; |
1461 | 1434 | ||
1462 | pll = &dev_priv->shared_dplls[pll_id]; | 1435 | state = &crtc_state->dpll_hw_state; |
1463 | state = &pll->state.hw_state; | ||
1464 | 1436 | ||
1465 | clock.m1 = 2; | 1437 | clock.m1 = 2; |
1466 | clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22; | 1438 | clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22; |
@@ -1474,19 +1446,15 @@ static int bxt_calc_pll_link(struct drm_i915_private *dev_priv, | |||
1474 | } | 1446 | } |
1475 | 1447 | ||
1476 | static void bxt_ddi_clock_get(struct intel_encoder *encoder, | 1448 | static void bxt_ddi_clock_get(struct intel_encoder *encoder, |
1477 | struct intel_crtc_state *pipe_config) | 1449 | struct intel_crtc_state *pipe_config) |
1478 | { | 1450 | { |
1479 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 1451 | pipe_config->port_clock = bxt_calc_pll_link(pipe_config); |
1480 | enum port port = intel_ddi_get_encoder_port(encoder); | ||
1481 | enum intel_dpll_id pll_id = port; | ||
1482 | |||
1483 | pipe_config->port_clock = bxt_calc_pll_link(dev_priv, pll_id); | ||
1484 | 1452 | ||
1485 | ddi_dotclock_get(pipe_config); | 1453 | ddi_dotclock_get(pipe_config); |
1486 | } | 1454 | } |
1487 | 1455 | ||
1488 | void intel_ddi_clock_get(struct intel_encoder *encoder, | 1456 | static void intel_ddi_clock_get(struct intel_encoder *encoder, |
1489 | struct intel_crtc_state *pipe_config) | 1457 | struct intel_crtc_state *pipe_config) |
1490 | { | 1458 | { |
1491 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 1459 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
1492 | 1460 | ||
@@ -1504,33 +1472,34 @@ void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state) | |||
1504 | { | 1472 | { |
1505 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); | 1473 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
1506 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); | 1474 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
1507 | struct intel_encoder *encoder = intel_ddi_get_crtc_encoder(crtc); | ||
1508 | enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; | 1475 | enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; |
1509 | int type = encoder->type; | 1476 | u32 temp; |
1510 | uint32_t temp; | ||
1511 | 1477 | ||
1512 | if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) { | 1478 | if (!intel_crtc_has_dp_encoder(crtc_state)) |
1513 | WARN_ON(transcoder_is_dsi(cpu_transcoder)); | 1479 | return; |
1514 | 1480 | ||
1515 | temp = TRANS_MSA_SYNC_CLK; | 1481 | WARN_ON(transcoder_is_dsi(cpu_transcoder)); |
1516 | switch (crtc_state->pipe_bpp) { | 1482 | |
1517 | case 18: | 1483 | temp = TRANS_MSA_SYNC_CLK; |
1518 | temp |= TRANS_MSA_6_BPC; | 1484 | switch (crtc_state->pipe_bpp) { |
1519 | break; | 1485 | case 18: |
1520 | case 24: | 1486 | temp |= TRANS_MSA_6_BPC; |
1521 | temp |= TRANS_MSA_8_BPC; | 1487 | break; |
1522 | break; | 1488 | case 24: |
1523 | case 30: | 1489 | temp |= TRANS_MSA_8_BPC; |
1524 | temp |= TRANS_MSA_10_BPC; | 1490 | break; |
1525 | break; | 1491 | case 30: |
1526 | case 36: | 1492 | temp |= TRANS_MSA_10_BPC; |
1527 | temp |= TRANS_MSA_12_BPC; | 1493 | break; |
1528 | break; | 1494 | case 36: |
1529 | default: | 1495 | temp |= TRANS_MSA_12_BPC; |
1530 | BUG(); | 1496 | break; |
1531 | } | 1497 | default: |
1532 | I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp); | 1498 | MISSING_CASE(crtc_state->pipe_bpp); |
1499 | break; | ||
1533 | } | 1500 | } |
1501 | |||
1502 | I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp); | ||
1534 | } | 1503 | } |
1535 | 1504 | ||
1536 | void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state, | 1505 | void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state, |
@@ -1540,6 +1509,7 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state, | |||
1540 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); | 1509 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
1541 | enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; | 1510 | enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; |
1542 | uint32_t temp; | 1511 | uint32_t temp; |
1512 | |||
1543 | temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); | 1513 | temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); |
1544 | if (state == true) | 1514 | if (state == true) |
1545 | temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC; | 1515 | temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC; |
@@ -1555,8 +1525,7 @@ void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state) | |||
1555 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); | 1525 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
1556 | enum pipe pipe = crtc->pipe; | 1526 | enum pipe pipe = crtc->pipe; |
1557 | enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; | 1527 | enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; |
1558 | enum port port = intel_ddi_get_encoder_port(encoder); | 1528 | enum port port = encoder->port; |
1559 | int type = encoder->type; | ||
1560 | uint32_t temp; | 1529 | uint32_t temp; |
1561 | 1530 | ||
1562 | /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */ | 1531 | /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */ |
@@ -1611,7 +1580,7 @@ void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state) | |||
1611 | } | 1580 | } |
1612 | } | 1581 | } |
1613 | 1582 | ||
1614 | if (type == INTEL_OUTPUT_HDMI) { | 1583 | if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { |
1615 | if (crtc_state->has_hdmi_sink) | 1584 | if (crtc_state->has_hdmi_sink) |
1616 | temp |= TRANS_DDI_MODE_SELECT_HDMI; | 1585 | temp |= TRANS_DDI_MODE_SELECT_HDMI; |
1617 | else | 1586 | else |
@@ -1621,19 +1590,15 @@ void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state) | |||
1621 | temp |= TRANS_DDI_HDMI_SCRAMBLING_MASK; | 1590 | temp |= TRANS_DDI_HDMI_SCRAMBLING_MASK; |
1622 | if (crtc_state->hdmi_high_tmds_clock_ratio) | 1591 | if (crtc_state->hdmi_high_tmds_clock_ratio) |
1623 | temp |= TRANS_DDI_HIGH_TMDS_CHAR_RATE; | 1592 | temp |= TRANS_DDI_HIGH_TMDS_CHAR_RATE; |
1624 | } else if (type == INTEL_OUTPUT_ANALOG) { | 1593 | } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) { |
1625 | temp |= TRANS_DDI_MODE_SELECT_FDI; | 1594 | temp |= TRANS_DDI_MODE_SELECT_FDI; |
1626 | temp |= (crtc_state->fdi_lanes - 1) << 1; | 1595 | temp |= (crtc_state->fdi_lanes - 1) << 1; |
1627 | } else if (type == INTEL_OUTPUT_DP || | 1596 | } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) { |
1628 | type == INTEL_OUTPUT_EDP) { | ||
1629 | temp |= TRANS_DDI_MODE_SELECT_DP_SST; | ||
1630 | temp |= DDI_PORT_WIDTH(crtc_state->lane_count); | ||
1631 | } else if (type == INTEL_OUTPUT_DP_MST) { | ||
1632 | temp |= TRANS_DDI_MODE_SELECT_DP_MST; | 1597 | temp |= TRANS_DDI_MODE_SELECT_DP_MST; |
1633 | temp |= DDI_PORT_WIDTH(crtc_state->lane_count); | 1598 | temp |= DDI_PORT_WIDTH(crtc_state->lane_count); |
1634 | } else { | 1599 | } else { |
1635 | WARN(1, "Invalid encoder type %d for pipe %c\n", | 1600 | temp |= TRANS_DDI_MODE_SELECT_DP_SST; |
1636 | encoder->type, pipe_name(pipe)); | 1601 | temp |= DDI_PORT_WIDTH(crtc_state->lane_count); |
1637 | } | 1602 | } |
1638 | 1603 | ||
1639 | I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp); | 1604 | I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp); |
@@ -1656,7 +1621,7 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) | |||
1656 | struct drm_i915_private *dev_priv = to_i915(dev); | 1621 | struct drm_i915_private *dev_priv = to_i915(dev); |
1657 | struct intel_encoder *encoder = intel_connector->encoder; | 1622 | struct intel_encoder *encoder = intel_connector->encoder; |
1658 | int type = intel_connector->base.connector_type; | 1623 | int type = intel_connector->base.connector_type; |
1659 | enum port port = intel_ddi_get_encoder_port(encoder); | 1624 | enum port port = encoder->port; |
1660 | enum pipe pipe = 0; | 1625 | enum pipe pipe = 0; |
1661 | enum transcoder cpu_transcoder; | 1626 | enum transcoder cpu_transcoder; |
1662 | uint32_t tmp; | 1627 | uint32_t tmp; |
@@ -1715,9 +1680,9 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder, | |||
1715 | { | 1680 | { |
1716 | struct drm_device *dev = encoder->base.dev; | 1681 | struct drm_device *dev = encoder->base.dev; |
1717 | struct drm_i915_private *dev_priv = to_i915(dev); | 1682 | struct drm_i915_private *dev_priv = to_i915(dev); |
1718 | enum port port = intel_ddi_get_encoder_port(encoder); | 1683 | enum port port = encoder->port; |
1684 | enum pipe p; | ||
1719 | u32 tmp; | 1685 | u32 tmp; |
1720 | int i; | ||
1721 | bool ret; | 1686 | bool ret; |
1722 | 1687 | ||
1723 | if (!intel_display_power_get_if_enabled(dev_priv, | 1688 | if (!intel_display_power_get_if_enabled(dev_priv, |
@@ -1752,15 +1717,17 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder, | |||
1752 | goto out; | 1717 | goto out; |
1753 | } | 1718 | } |
1754 | 1719 | ||
1755 | for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) { | 1720 | for_each_pipe(dev_priv, p) { |
1756 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(i)); | 1721 | enum transcoder cpu_transcoder = (enum transcoder) p; |
1722 | |||
1723 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); | ||
1757 | 1724 | ||
1758 | if ((tmp & TRANS_DDI_PORT_MASK) == TRANS_DDI_SELECT_PORT(port)) { | 1725 | if ((tmp & TRANS_DDI_PORT_MASK) == TRANS_DDI_SELECT_PORT(port)) { |
1759 | if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == | 1726 | if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == |
1760 | TRANS_DDI_MODE_SELECT_DP_MST) | 1727 | TRANS_DDI_MODE_SELECT_DP_MST) |
1761 | goto out; | 1728 | goto out; |
1762 | 1729 | ||
1763 | *pipe = i; | 1730 | *pipe = p; |
1764 | ret = true; | 1731 | ret = true; |
1765 | 1732 | ||
1766 | goto out; | 1733 | goto out; |
@@ -1800,7 +1767,7 @@ void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state) | |||
1800 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); | 1767 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
1801 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); | 1768 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
1802 | struct intel_encoder *encoder = intel_ddi_get_crtc_encoder(crtc); | 1769 | struct intel_encoder *encoder = intel_ddi_get_crtc_encoder(crtc); |
1803 | enum port port = intel_ddi_get_encoder_port(encoder); | 1770 | enum port port = encoder->port; |
1804 | enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; | 1771 | enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; |
1805 | 1772 | ||
1806 | if (cpu_transcoder != TRANSCODER_EDP) | 1773 | if (cpu_transcoder != TRANSCODER_EDP) |
@@ -1836,8 +1803,8 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, | |||
1836 | int level, enum intel_output_type type) | 1803 | int level, enum intel_output_type type) |
1837 | { | 1804 | { |
1838 | struct intel_digital_port *intel_dig_port = enc_to_dig_port(&encoder->base); | 1805 | struct intel_digital_port *intel_dig_port = enc_to_dig_port(&encoder->base); |
1839 | struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev); | 1806 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
1840 | enum port port = intel_dig_port->port; | 1807 | enum port port = encoder->port; |
1841 | uint8_t iboost; | 1808 | uint8_t iboost; |
1842 | 1809 | ||
1843 | if (type == INTEL_OUTPUT_HDMI) | 1810 | if (type == INTEL_OUTPUT_HDMI) |
@@ -1939,8 +1906,8 @@ static void cnl_ddi_vswing_program(struct intel_encoder *encoder, | |||
1939 | int level, enum intel_output_type type) | 1906 | int level, enum intel_output_type type) |
1940 | { | 1907 | { |
1941 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 1908 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
1942 | enum port port = intel_ddi_get_encoder_port(encoder); | ||
1943 | const struct cnl_ddi_buf_trans *ddi_translations; | 1909 | const struct cnl_ddi_buf_trans *ddi_translations; |
1910 | enum port port = encoder->port; | ||
1944 | int n_entries, ln; | 1911 | int n_entries, ln; |
1945 | u32 val; | 1912 | u32 val; |
1946 | 1913 | ||
@@ -2003,7 +1970,7 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, | |||
2003 | int level, enum intel_output_type type) | 1970 | int level, enum intel_output_type type) |
2004 | { | 1971 | { |
2005 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 1972 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
2006 | enum port port = intel_ddi_get_encoder_port(encoder); | 1973 | enum port port = encoder->port; |
2007 | int width, rate, ln; | 1974 | int width, rate, ln; |
2008 | u32 val; | 1975 | u32 val; |
2009 | 1976 | ||
@@ -2122,7 +2089,7 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder, | |||
2122 | const struct intel_shared_dpll *pll) | 2089 | const struct intel_shared_dpll *pll) |
2123 | { | 2090 | { |
2124 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 2091 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
2125 | enum port port = intel_ddi_get_encoder_port(encoder); | 2092 | enum port port = encoder->port; |
2126 | uint32_t val; | 2093 | uint32_t val; |
2127 | 2094 | ||
2128 | if (WARN_ON(!pll)) | 2095 | if (WARN_ON(!pll)) |
@@ -2161,7 +2128,7 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder, | |||
2161 | static void intel_ddi_clk_disable(struct intel_encoder *encoder) | 2128 | static void intel_ddi_clk_disable(struct intel_encoder *encoder) |
2162 | { | 2129 | { |
2163 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 2130 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
2164 | enum port port = intel_ddi_get_encoder_port(encoder); | 2131 | enum port port = encoder->port; |
2165 | 2132 | ||
2166 | if (IS_CANNONLAKE(dev_priv)) | 2133 | if (IS_CANNONLAKE(dev_priv)) |
2167 | I915_WRITE(DPCLKA_CFGCR0, I915_READ(DPCLKA_CFGCR0) | | 2134 | I915_WRITE(DPCLKA_CFGCR0, I915_READ(DPCLKA_CFGCR0) | |
@@ -2179,7 +2146,7 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, | |||
2179 | { | 2146 | { |
2180 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 2147 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
2181 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 2148 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
2182 | enum port port = intel_ddi_get_encoder_port(encoder); | 2149 | enum port port = encoder->port; |
2183 | struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); | 2150 | struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); |
2184 | bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); | 2151 | bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); |
2185 | int level = intel_ddi_dp_level(intel_dp); | 2152 | int level = intel_ddi_dp_level(intel_dp); |
@@ -2200,7 +2167,7 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, | |||
2200 | else if (IS_GEN9_LP(dev_priv)) | 2167 | else if (IS_GEN9_LP(dev_priv)) |
2201 | bxt_ddi_vswing_sequence(encoder, level, encoder->type); | 2168 | bxt_ddi_vswing_sequence(encoder, level, encoder->type); |
2202 | else | 2169 | else |
2203 | intel_prepare_dp_ddi_buffers(encoder); | 2170 | intel_prepare_dp_ddi_buffers(encoder, crtc_state); |
2204 | 2171 | ||
2205 | intel_ddi_init_dp_buf_reg(encoder); | 2172 | intel_ddi_init_dp_buf_reg(encoder); |
2206 | if (!is_mst) | 2173 | if (!is_mst) |
@@ -2217,7 +2184,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder, | |||
2217 | struct intel_digital_port *intel_dig_port = enc_to_dig_port(&encoder->base); | 2184 | struct intel_digital_port *intel_dig_port = enc_to_dig_port(&encoder->base); |
2218 | struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi; | 2185 | struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi; |
2219 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 2186 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
2220 | enum port port = intel_ddi_get_encoder_port(encoder); | 2187 | enum port port = encoder->port; |
2221 | int level = intel_ddi_hdmi_level(dev_priv, port); | 2188 | int level = intel_ddi_hdmi_level(dev_priv, port); |
2222 | struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); | 2189 | struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); |
2223 | 2190 | ||
@@ -2249,6 +2216,19 @@ static void intel_ddi_pre_enable(struct intel_encoder *encoder, | |||
2249 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); | 2216 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
2250 | enum pipe pipe = crtc->pipe; | 2217 | enum pipe pipe = crtc->pipe; |
2251 | 2218 | ||
2219 | /* | ||
2220 | * When called from DP MST code: | ||
2221 | * - conn_state will be NULL | ||
2222 | * - encoder will be the main encoder (ie. mst->primary) | ||
2223 | * - the main connector associated with this port | ||
2224 | * won't be active or linked to a crtc | ||
2225 | * - crtc_state will be the state of the first stream to | ||
2226 | * be activated on this port, and it may not be the same | ||
2227 | * stream that will be deactivated last, but each stream | ||
2228 | * should have a state that is identical when it comes to | ||
2229 | * the DP link parameteres | ||
2230 | */ | ||
2231 | |||
2252 | WARN_ON(crtc_state->has_pch_encoder); | 2232 | WARN_ON(crtc_state->has_pch_encoder); |
2253 | 2233 | ||
2254 | intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); | 2234 | intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); |
@@ -2262,7 +2242,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *encoder, | |||
2262 | static void intel_disable_ddi_buf(struct intel_encoder *encoder) | 2242 | static void intel_disable_ddi_buf(struct intel_encoder *encoder) |
2263 | { | 2243 | { |
2264 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 2244 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
2265 | enum port port = intel_ddi_get_encoder_port(encoder); | 2245 | enum port port = encoder->port; |
2266 | bool wait = false; | 2246 | bool wait = false; |
2267 | u32 val; | 2247 | u32 val; |
2268 | 2248 | ||
@@ -2289,12 +2269,7 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder, | |||
2289 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 2269 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
2290 | struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); | 2270 | struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); |
2291 | struct intel_dp *intel_dp = &dig_port->dp; | 2271 | struct intel_dp *intel_dp = &dig_port->dp; |
2292 | /* | 2272 | bool is_mst = intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST); |
2293 | * old_crtc_state and old_conn_state are NULL when called from | ||
2294 | * DP_MST. The main connector associated with this port is never | ||
2295 | * bound to a crtc for MST. | ||
2296 | */ | ||
2297 | bool is_mst = !old_crtc_state; | ||
2298 | 2273 | ||
2299 | /* | 2274 | /* |
2300 | * Power down sink before disabling the port, otherwise we end | 2275 | * Power down sink before disabling the port, otherwise we end |
@@ -2338,12 +2313,19 @@ static void intel_ddi_post_disable(struct intel_encoder *encoder, | |||
2338 | const struct drm_connector_state *old_conn_state) | 2313 | const struct drm_connector_state *old_conn_state) |
2339 | { | 2314 | { |
2340 | /* | 2315 | /* |
2341 | * old_crtc_state and old_conn_state are NULL when called from | 2316 | * When called from DP MST code: |
2342 | * DP_MST. The main connector associated with this port is never | 2317 | * - old_conn_state will be NULL |
2343 | * bound to a crtc for MST. | 2318 | * - encoder will be the main encoder (ie. mst->primary) |
2319 | * - the main connector associated with this port | ||
2320 | * won't be active or linked to a crtc | ||
2321 | * - old_crtc_state will be the state of the last stream to | ||
2322 | * be deactivated on this port, and it may not be the same | ||
2323 | * stream that was activated last, but each stream | ||
2324 | * should have a state that is identical when it comes to | ||
2325 | * the DP link parameteres | ||
2344 | */ | 2326 | */ |
2345 | if (old_crtc_state && | 2327 | |
2346 | intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI)) | 2328 | if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI)) |
2347 | intel_ddi_post_disable_hdmi(encoder, | 2329 | intel_ddi_post_disable_hdmi(encoder, |
2348 | old_crtc_state, old_conn_state); | 2330 | old_crtc_state, old_conn_state); |
2349 | else | 2331 | else |
@@ -2391,7 +2373,7 @@ static void intel_enable_ddi_dp(struct intel_encoder *encoder, | |||
2391 | { | 2373 | { |
2392 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 2374 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
2393 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 2375 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
2394 | enum port port = intel_ddi_get_encoder_port(encoder); | 2376 | enum port port = encoder->port; |
2395 | 2377 | ||
2396 | if (port == PORT_A && INTEL_GEN(dev_priv) < 9) | 2378 | if (port == PORT_A && INTEL_GEN(dev_priv) < 9) |
2397 | intel_dp_stop_link_train(intel_dp); | 2379 | intel_dp_stop_link_train(intel_dp); |
@@ -2410,7 +2392,7 @@ static void intel_enable_ddi_hdmi(struct intel_encoder *encoder, | |||
2410 | { | 2392 | { |
2411 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 2393 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
2412 | struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); | 2394 | struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); |
2413 | enum port port = intel_ddi_get_encoder_port(encoder); | 2395 | enum port port = encoder->port; |
2414 | 2396 | ||
2415 | intel_hdmi_handle_sink_scrambling(encoder, | 2397 | intel_hdmi_handle_sink_scrambling(encoder, |
2416 | conn_state->connector, | 2398 | conn_state->connector, |
@@ -2445,7 +2427,8 @@ static void intel_disable_ddi_dp(struct intel_encoder *encoder, | |||
2445 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 2427 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
2446 | 2428 | ||
2447 | if (old_crtc_state->has_audio) | 2429 | if (old_crtc_state->has_audio) |
2448 | intel_audio_codec_disable(encoder); | 2430 | intel_audio_codec_disable(encoder, |
2431 | old_crtc_state, old_conn_state); | ||
2449 | 2432 | ||
2450 | intel_edp_drrs_disable(intel_dp, old_crtc_state); | 2433 | intel_edp_drrs_disable(intel_dp, old_crtc_state); |
2451 | intel_psr_disable(intel_dp, old_crtc_state); | 2434 | intel_psr_disable(intel_dp, old_crtc_state); |
@@ -2457,7 +2440,8 @@ static void intel_disable_ddi_hdmi(struct intel_encoder *encoder, | |||
2457 | const struct drm_connector_state *old_conn_state) | 2440 | const struct drm_connector_state *old_conn_state) |
2458 | { | 2441 | { |
2459 | if (old_crtc_state->has_audio) | 2442 | if (old_crtc_state->has_audio) |
2460 | intel_audio_codec_disable(encoder); | 2443 | intel_audio_codec_disable(encoder, |
2444 | old_crtc_state, old_conn_state); | ||
2461 | 2445 | ||
2462 | intel_hdmi_handle_sink_scrambling(encoder, | 2446 | intel_hdmi_handle_sink_scrambling(encoder, |
2463 | old_conn_state->connector, | 2447 | old_conn_state->connector, |
@@ -2488,7 +2472,7 @@ void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp) | |||
2488 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 2472 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
2489 | struct drm_i915_private *dev_priv = | 2473 | struct drm_i915_private *dev_priv = |
2490 | to_i915(intel_dig_port->base.base.dev); | 2474 | to_i915(intel_dig_port->base.base.dev); |
2491 | enum port port = intel_dig_port->port; | 2475 | enum port port = intel_dig_port->base.port; |
2492 | uint32_t val; | 2476 | uint32_t val; |
2493 | bool wait = false; | 2477 | bool wait = false; |
2494 | 2478 | ||
@@ -2542,11 +2526,18 @@ bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv, | |||
2542 | return false; | 2526 | return false; |
2543 | } | 2527 | } |
2544 | 2528 | ||
2529 | void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv, | ||
2530 | struct intel_crtc_state *crtc_state) | ||
2531 | { | ||
2532 | if (IS_CANNONLAKE(dev_priv) && crtc_state->port_clock > 594000) | ||
2533 | crtc_state->min_voltage_level = 2; | ||
2534 | } | ||
2535 | |||
2545 | void intel_ddi_get_config(struct intel_encoder *encoder, | 2536 | void intel_ddi_get_config(struct intel_encoder *encoder, |
2546 | struct intel_crtc_state *pipe_config) | 2537 | struct intel_crtc_state *pipe_config) |
2547 | { | 2538 | { |
2548 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 2539 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
2549 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); | 2540 | struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc); |
2550 | enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; | 2541 | enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; |
2551 | struct intel_digital_port *intel_dig_port; | 2542 | struct intel_digital_port *intel_dig_port; |
2552 | u32 temp, flags = 0; | 2543 | u32 temp, flags = 0; |
@@ -2599,12 +2590,23 @@ void intel_ddi_get_config(struct intel_encoder *encoder, | |||
2599 | pipe_config->hdmi_high_tmds_clock_ratio = true; | 2590 | pipe_config->hdmi_high_tmds_clock_ratio = true; |
2600 | /* fall through */ | 2591 | /* fall through */ |
2601 | case TRANS_DDI_MODE_SELECT_DVI: | 2592 | case TRANS_DDI_MODE_SELECT_DVI: |
2593 | pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); | ||
2602 | pipe_config->lane_count = 4; | 2594 | pipe_config->lane_count = 4; |
2603 | break; | 2595 | break; |
2604 | case TRANS_DDI_MODE_SELECT_FDI: | 2596 | case TRANS_DDI_MODE_SELECT_FDI: |
2597 | pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); | ||
2605 | break; | 2598 | break; |
2606 | case TRANS_DDI_MODE_SELECT_DP_SST: | 2599 | case TRANS_DDI_MODE_SELECT_DP_SST: |
2600 | if (encoder->type == INTEL_OUTPUT_EDP) | ||
2601 | pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); | ||
2602 | else | ||
2603 | pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); | ||
2604 | pipe_config->lane_count = | ||
2605 | ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; | ||
2606 | intel_dp_get_m_n(intel_crtc, pipe_config); | ||
2607 | break; | ||
2607 | case TRANS_DDI_MODE_SELECT_DP_MST: | 2608 | case TRANS_DDI_MODE_SELECT_DP_MST: |
2609 | pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST); | ||
2608 | pipe_config->lane_count = | 2610 | pipe_config->lane_count = |
2609 | ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; | 2611 | ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; |
2610 | intel_dp_get_m_n(intel_crtc, pipe_config); | 2612 | intel_dp_get_m_n(intel_crtc, pipe_config); |
@@ -2641,6 +2643,26 @@ void intel_ddi_get_config(struct intel_encoder *encoder, | |||
2641 | if (IS_GEN9_LP(dev_priv)) | 2643 | if (IS_GEN9_LP(dev_priv)) |
2642 | pipe_config->lane_lat_optim_mask = | 2644 | pipe_config->lane_lat_optim_mask = |
2643 | bxt_ddi_phy_get_lane_lat_optim_mask(encoder); | 2645 | bxt_ddi_phy_get_lane_lat_optim_mask(encoder); |
2646 | |||
2647 | intel_ddi_compute_min_voltage_level(dev_priv, pipe_config); | ||
2648 | } | ||
2649 | |||
2650 | static enum intel_output_type | ||
2651 | intel_ddi_compute_output_type(struct intel_encoder *encoder, | ||
2652 | struct intel_crtc_state *crtc_state, | ||
2653 | struct drm_connector_state *conn_state) | ||
2654 | { | ||
2655 | switch (conn_state->connector->connector_type) { | ||
2656 | case DRM_MODE_CONNECTOR_HDMIA: | ||
2657 | return INTEL_OUTPUT_HDMI; | ||
2658 | case DRM_MODE_CONNECTOR_eDP: | ||
2659 | return INTEL_OUTPUT_EDP; | ||
2660 | case DRM_MODE_CONNECTOR_DisplayPort: | ||
2661 | return INTEL_OUTPUT_DP; | ||
2662 | default: | ||
2663 | MISSING_CASE(conn_state->connector->connector_type); | ||
2664 | return INTEL_OUTPUT_UNUSED; | ||
2665 | } | ||
2644 | } | 2666 | } |
2645 | 2667 | ||
2646 | static bool intel_ddi_compute_config(struct intel_encoder *encoder, | 2668 | static bool intel_ddi_compute_config(struct intel_encoder *encoder, |
@@ -2648,24 +2670,22 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder, | |||
2648 | struct drm_connector_state *conn_state) | 2670 | struct drm_connector_state *conn_state) |
2649 | { | 2671 | { |
2650 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 2672 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
2651 | int type = encoder->type; | 2673 | enum port port = encoder->port; |
2652 | int port = intel_ddi_get_encoder_port(encoder); | ||
2653 | int ret; | 2674 | int ret; |
2654 | 2675 | ||
2655 | WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); | ||
2656 | |||
2657 | if (port == PORT_A) | 2676 | if (port == PORT_A) |
2658 | pipe_config->cpu_transcoder = TRANSCODER_EDP; | 2677 | pipe_config->cpu_transcoder = TRANSCODER_EDP; |
2659 | 2678 | ||
2660 | if (type == INTEL_OUTPUT_HDMI) | 2679 | if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI)) |
2661 | ret = intel_hdmi_compute_config(encoder, pipe_config, conn_state); | 2680 | ret = intel_hdmi_compute_config(encoder, pipe_config, conn_state); |
2662 | else | 2681 | else |
2663 | ret = intel_dp_compute_config(encoder, pipe_config, conn_state); | 2682 | ret = intel_dp_compute_config(encoder, pipe_config, conn_state); |
2664 | 2683 | ||
2665 | if (IS_GEN9_LP(dev_priv) && ret) | 2684 | if (IS_GEN9_LP(dev_priv) && ret) |
2666 | pipe_config->lane_lat_optim_mask = | 2685 | pipe_config->lane_lat_optim_mask = |
2667 | bxt_ddi_phy_calc_lane_lat_optim_mask(encoder, | 2686 | bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); |
2668 | pipe_config->lane_count); | 2687 | |
2688 | intel_ddi_compute_min_voltage_level(dev_priv, pipe_config); | ||
2669 | 2689 | ||
2670 | return ret; | 2690 | return ret; |
2671 | 2691 | ||
@@ -2680,7 +2700,7 @@ static struct intel_connector * | |||
2680 | intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port) | 2700 | intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port) |
2681 | { | 2701 | { |
2682 | struct intel_connector *connector; | 2702 | struct intel_connector *connector; |
2683 | enum port port = intel_dig_port->port; | 2703 | enum port port = intel_dig_port->base.port; |
2684 | 2704 | ||
2685 | connector = intel_connector_alloc(); | 2705 | connector = intel_connector_alloc(); |
2686 | if (!connector) | 2706 | if (!connector) |
@@ -2699,7 +2719,7 @@ static struct intel_connector * | |||
2699 | intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port) | 2719 | intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port) |
2700 | { | 2720 | { |
2701 | struct intel_connector *connector; | 2721 | struct intel_connector *connector; |
2702 | enum port port = intel_dig_port->port; | 2722 | enum port port = intel_dig_port->base.port; |
2703 | 2723 | ||
2704 | connector = intel_connector_alloc(); | 2724 | connector = intel_connector_alloc(); |
2705 | if (!connector) | 2725 | if (!connector) |
@@ -2711,6 +2731,34 @@ intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port) | |||
2711 | return connector; | 2731 | return connector; |
2712 | } | 2732 | } |
2713 | 2733 | ||
2734 | static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dport) | ||
2735 | { | ||
2736 | struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev); | ||
2737 | |||
2738 | if (dport->base.port != PORT_A) | ||
2739 | return false; | ||
2740 | |||
2741 | if (dport->saved_port_bits & DDI_A_4_LANES) | ||
2742 | return false; | ||
2743 | |||
2744 | /* Broxton/Geminilake: Bspec says that DDI_A_4_LANES is the only | ||
2745 | * supported configuration | ||
2746 | */ | ||
2747 | if (IS_GEN9_LP(dev_priv)) | ||
2748 | return true; | ||
2749 | |||
2750 | /* Cannonlake: Most of SKUs don't support DDI_E, and the only | ||
2751 | * one who does also have a full A/E split called | ||
2752 | * DDI_F what makes DDI_E useless. However for this | ||
2753 | * case let's trust VBT info. | ||
2754 | */ | ||
2755 | if (IS_CANNONLAKE(dev_priv) && | ||
2756 | !intel_bios_is_port_present(dev_priv, PORT_E)) | ||
2757 | return true; | ||
2758 | |||
2759 | return false; | ||
2760 | } | ||
2761 | |||
2714 | void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) | 2762 | void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) |
2715 | { | 2763 | { |
2716 | struct intel_digital_port *intel_dig_port; | 2764 | struct intel_digital_port *intel_dig_port; |
@@ -2777,6 +2825,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) | |||
2777 | drm_encoder_init(&dev_priv->drm, encoder, &intel_ddi_funcs, | 2825 | drm_encoder_init(&dev_priv->drm, encoder, &intel_ddi_funcs, |
2778 | DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port)); | 2826 | DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port)); |
2779 | 2827 | ||
2828 | intel_encoder->compute_output_type = intel_ddi_compute_output_type; | ||
2780 | intel_encoder->compute_config = intel_ddi_compute_config; | 2829 | intel_encoder->compute_config = intel_ddi_compute_config; |
2781 | intel_encoder->enable = intel_enable_ddi; | 2830 | intel_encoder->enable = intel_enable_ddi; |
2782 | if (IS_GEN9_LP(dev_priv)) | 2831 | if (IS_GEN9_LP(dev_priv)) |
@@ -2789,7 +2838,6 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) | |||
2789 | intel_encoder->suspend = intel_dp_encoder_suspend; | 2838 | intel_encoder->suspend = intel_dp_encoder_suspend; |
2790 | intel_encoder->get_power_domains = intel_ddi_get_power_domains; | 2839 | intel_encoder->get_power_domains = intel_ddi_get_power_domains; |
2791 | 2840 | ||
2792 | intel_dig_port->port = port; | ||
2793 | intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & | 2841 | intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & |
2794 | (DDI_BUF_PORT_REVERSAL | | 2842 | (DDI_BUF_PORT_REVERSAL | |
2795 | DDI_A_4_LANES); | 2843 | DDI_A_4_LANES); |
@@ -2820,23 +2868,20 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) | |||
2820 | } | 2868 | } |
2821 | 2869 | ||
2822 | /* | 2870 | /* |
2823 | * Bspec says that DDI_A_4_LANES is the only supported configuration | 2871 | * Some BIOS might fail to set this bit on port A if eDP |
2824 | * for Broxton. Yet some BIOS fail to set this bit on port A if eDP | 2872 | * wasn't lit up at boot. Force this bit set when needed |
2825 | * wasn't lit up at boot. Force this bit on in our internal | 2873 | * so we use the proper lane count for our calculations. |
2826 | * configuration so that we use the proper lane count for our | ||
2827 | * calculations. | ||
2828 | */ | 2874 | */ |
2829 | if (IS_GEN9_LP(dev_priv) && port == PORT_A) { | 2875 | if (intel_ddi_a_force_4_lanes(intel_dig_port)) { |
2830 | if (!(intel_dig_port->saved_port_bits & DDI_A_4_LANES)) { | 2876 | DRM_DEBUG_KMS("Forcing DDI_A_4_LANES for port A\n"); |
2831 | DRM_DEBUG_KMS("BXT BIOS forgot to set DDI_A_4_LANES for port A; fixing\n"); | 2877 | intel_dig_port->saved_port_bits |= DDI_A_4_LANES; |
2832 | intel_dig_port->saved_port_bits |= DDI_A_4_LANES; | 2878 | max_lanes = 4; |
2833 | max_lanes = 4; | ||
2834 | } | ||
2835 | } | 2879 | } |
2836 | 2880 | ||
2881 | intel_dig_port->dp.output_reg = INVALID_MMIO_REG; | ||
2837 | intel_dig_port->max_lanes = max_lanes; | 2882 | intel_dig_port->max_lanes = max_lanes; |
2838 | 2883 | ||
2839 | intel_encoder->type = INTEL_OUTPUT_UNKNOWN; | 2884 | intel_encoder->type = INTEL_OUTPUT_DDI; |
2840 | intel_encoder->power_domain = intel_port_to_power_domain(port); | 2885 | intel_encoder->power_domain = intel_port_to_power_domain(port); |
2841 | intel_encoder->port = port; | 2886 | intel_encoder->port = port; |
2842 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); | 2887 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index 875d428ea75f..02f8bf101ccd 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c | |||
@@ -235,16 +235,6 @@ static void gen9_sseu_info_init(struct drm_i915_private *dev_priv) | |||
235 | #define IS_SS_DISABLED(ss) (!(sseu->subslice_mask & BIT(ss))) | 235 | #define IS_SS_DISABLED(ss) (!(sseu->subslice_mask & BIT(ss))) |
236 | info->has_pooled_eu = hweight8(sseu->subslice_mask) == 3; | 236 | info->has_pooled_eu = hweight8(sseu->subslice_mask) == 3; |
237 | 237 | ||
238 | /* | ||
239 | * There is a HW issue in 2x6 fused down parts that requires | ||
240 | * Pooled EU to be enabled as a WA. The pool configuration | ||
241 | * changes depending upon which subslice is fused down. This | ||
242 | * doesn't affect if the device has all 3 subslices enabled. | ||
243 | */ | ||
244 | /* WaEnablePooledEuFor2x6:bxt */ | ||
245 | info->has_pooled_eu |= (hweight8(sseu->subslice_mask) == 2 && | ||
246 | IS_BXT_REVID(dev_priv, 0, BXT_REVID_B_LAST)); | ||
247 | |||
248 | sseu->min_eu_in_pool = 0; | 238 | sseu->min_eu_in_pool = 0; |
249 | if (info->has_pooled_eu) { | 239 | if (info->has_pooled_eu) { |
250 | if (IS_SS_DISABLED(2) || IS_SS_DISABLED(0)) | 240 | if (IS_SS_DISABLED(2) || IS_SS_DISABLED(0)) |
@@ -329,6 +319,107 @@ static void broadwell_sseu_info_init(struct drm_i915_private *dev_priv) | |||
329 | sseu->has_eu_pg = 0; | 319 | sseu->has_eu_pg = 0; |
330 | } | 320 | } |
331 | 321 | ||
322 | static u32 read_reference_ts_freq(struct drm_i915_private *dev_priv) | ||
323 | { | ||
324 | u32 ts_override = I915_READ(GEN9_TIMESTAMP_OVERRIDE); | ||
325 | u32 base_freq, frac_freq; | ||
326 | |||
327 | base_freq = ((ts_override & GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_MASK) >> | ||
328 | GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_SHIFT) + 1; | ||
329 | base_freq *= 1000; | ||
330 | |||
331 | frac_freq = ((ts_override & | ||
332 | GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_MASK) >> | ||
333 | GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_SHIFT); | ||
334 | frac_freq = 1000 / (frac_freq + 1); | ||
335 | |||
336 | return base_freq + frac_freq; | ||
337 | } | ||
338 | |||
339 | static u32 read_timestamp_frequency(struct drm_i915_private *dev_priv) | ||
340 | { | ||
341 | u32 f12_5_mhz = 12500; | ||
342 | u32 f19_2_mhz = 19200; | ||
343 | u32 f24_mhz = 24000; | ||
344 | |||
345 | if (INTEL_GEN(dev_priv) <= 4) { | ||
346 | /* PRMs say: | ||
347 | * | ||
348 | * "The value in this register increments once every 16 | ||
349 | * hclks." (through the “Clocking Configuration” | ||
350 | * (“CLKCFG”) MCHBAR register) | ||
351 | */ | ||
352 | return dev_priv->rawclk_freq / 16; | ||
353 | } else if (INTEL_GEN(dev_priv) <= 8) { | ||
354 | /* PRMs say: | ||
355 | * | ||
356 | * "The PCU TSC counts 10ns increments; this timestamp | ||
357 | * reflects bits 38:3 of the TSC (i.e. 80ns granularity, | ||
358 | * rolling over every 1.5 hours). | ||
359 | */ | ||
360 | return f12_5_mhz; | ||
361 | } else if (INTEL_GEN(dev_priv) <= 9) { | ||
362 | u32 ctc_reg = I915_READ(CTC_MODE); | ||
363 | u32 freq = 0; | ||
364 | |||
365 | if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) { | ||
366 | freq = read_reference_ts_freq(dev_priv); | ||
367 | } else { | ||
368 | freq = IS_GEN9_LP(dev_priv) ? f19_2_mhz : f24_mhz; | ||
369 | |||
370 | /* Now figure out how the command stream's timestamp | ||
371 | * register increments from this frequency (it might | ||
372 | * increment only every few clock cycle). | ||
373 | */ | ||
374 | freq >>= 3 - ((ctc_reg & CTC_SHIFT_PARAMETER_MASK) >> | ||
375 | CTC_SHIFT_PARAMETER_SHIFT); | ||
376 | } | ||
377 | |||
378 | return freq; | ||
379 | } else if (INTEL_GEN(dev_priv) <= 10) { | ||
380 | u32 ctc_reg = I915_READ(CTC_MODE); | ||
381 | u32 freq = 0; | ||
382 | u32 rpm_config_reg = 0; | ||
383 | |||
384 | /* First figure out the reference frequency. There are 2 ways | ||
385 | * we can compute the frequency, either through the | ||
386 | * TIMESTAMP_OVERRIDE register or through RPM_CONFIG. CTC_MODE | ||
387 | * tells us which one we should use. | ||
388 | */ | ||
389 | if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) { | ||
390 | freq = read_reference_ts_freq(dev_priv); | ||
391 | } else { | ||
392 | u32 crystal_clock; | ||
393 | |||
394 | rpm_config_reg = I915_READ(RPM_CONFIG0); | ||
395 | crystal_clock = (rpm_config_reg & | ||
396 | GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK) >> | ||
397 | GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT; | ||
398 | switch (crystal_clock) { | ||
399 | case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ: | ||
400 | freq = f19_2_mhz; | ||
401 | break; | ||
402 | case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ: | ||
403 | freq = f24_mhz; | ||
404 | break; | ||
405 | } | ||
406 | } | ||
407 | |||
408 | /* Now figure out how the command stream's timestamp register | ||
409 | * increments from this frequency (it might increment only | ||
410 | * every few clock cycle). | ||
411 | */ | ||
412 | freq >>= 3 - ((rpm_config_reg & | ||
413 | GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK) >> | ||
414 | GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT); | ||
415 | |||
416 | return freq; | ||
417 | } | ||
418 | |||
419 | DRM_ERROR("Unknown gen, unable to compute command stream timestamp frequency\n"); | ||
420 | return 0; | ||
421 | } | ||
422 | |||
332 | /* | 423 | /* |
333 | * Determine various intel_device_info fields at runtime. | 424 | * Determine various intel_device_info fields at runtime. |
334 | * | 425 | * |
@@ -347,7 +438,10 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) | |||
347 | struct intel_device_info *info = mkwrite_device_info(dev_priv); | 438 | struct intel_device_info *info = mkwrite_device_info(dev_priv); |
348 | enum pipe pipe; | 439 | enum pipe pipe; |
349 | 440 | ||
350 | if (INTEL_GEN(dev_priv) >= 9) { | 441 | if (INTEL_GEN(dev_priv) >= 10) { |
442 | for_each_pipe(dev_priv, pipe) | ||
443 | info->num_scalers[pipe] = 2; | ||
444 | } else if (INTEL_GEN(dev_priv) == 9) { | ||
351 | info->num_scalers[PIPE_A] = 2; | 445 | info->num_scalers[PIPE_A] = 2; |
352 | info->num_scalers[PIPE_B] = 2; | 446 | info->num_scalers[PIPE_B] = 2; |
353 | info->num_scalers[PIPE_C] = 1; | 447 | info->num_scalers[PIPE_C] = 1; |
@@ -447,6 +541,9 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) | |||
447 | else if (INTEL_GEN(dev_priv) >= 10) | 541 | else if (INTEL_GEN(dev_priv) >= 10) |
448 | gen10_sseu_info_init(dev_priv); | 542 | gen10_sseu_info_init(dev_priv); |
449 | 543 | ||
544 | /* Initialize command stream timestamp frequency */ | ||
545 | info->cs_timestamp_frequency_khz = read_timestamp_frequency(dev_priv); | ||
546 | |||
450 | DRM_DEBUG_DRIVER("slice mask: %04x\n", info->sseu.slice_mask); | 547 | DRM_DEBUG_DRIVER("slice mask: %04x\n", info->sseu.slice_mask); |
451 | DRM_DEBUG_DRIVER("slice total: %u\n", hweight8(info->sseu.slice_mask)); | 548 | DRM_DEBUG_DRIVER("slice total: %u\n", hweight8(info->sseu.slice_mask)); |
452 | DRM_DEBUG_DRIVER("subslice total: %u\n", | 549 | DRM_DEBUG_DRIVER("subslice total: %u\n", |
@@ -462,4 +559,6 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) | |||
462 | info->sseu.has_subslice_pg ? "y" : "n"); | 559 | info->sseu.has_subslice_pg ? "y" : "n"); |
463 | DRM_DEBUG_DRIVER("has EU power gating: %s\n", | 560 | DRM_DEBUG_DRIVER("has EU power gating: %s\n", |
464 | info->sseu.has_eu_pg ? "y" : "n"); | 561 | info->sseu.has_eu_pg ? "y" : "n"); |
562 | DRM_DEBUG_DRIVER("CS timestamp frequency: %u kHz\n", | ||
563 | info->cs_timestamp_frequency_khz); | ||
465 | } | 564 | } |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e0fffd883b54..2007c69468b9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -219,10 +219,8 @@ intel_fdi_link_freq(struct drm_i915_private *dev_priv, | |||
219 | { | 219 | { |
220 | if (HAS_DDI(dev_priv)) | 220 | if (HAS_DDI(dev_priv)) |
221 | return pipe_config->port_clock; /* SPLL */ | 221 | return pipe_config->port_clock; /* SPLL */ |
222 | else if (IS_GEN5(dev_priv)) | ||
223 | return ((I915_READ(FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK) + 2) * 10000; | ||
224 | else | 222 | else |
225 | return 270000; | 223 | return dev_priv->fdi_pll_freq; |
226 | } | 224 | } |
227 | 225 | ||
228 | static const struct intel_limit intel_limits_i8xx_dac = { | 226 | static const struct intel_limit intel_limits_i8xx_dac = { |
@@ -1703,7 +1701,7 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv, | |||
1703 | u32 port_mask; | 1701 | u32 port_mask; |
1704 | i915_reg_t dpll_reg; | 1702 | i915_reg_t dpll_reg; |
1705 | 1703 | ||
1706 | switch (dport->port) { | 1704 | switch (dport->base.port) { |
1707 | case PORT_B: | 1705 | case PORT_B: |
1708 | port_mask = DPLL_PORTB_READY_MASK; | 1706 | port_mask = DPLL_PORTB_READY_MASK; |
1709 | dpll_reg = DPLL(0); | 1707 | dpll_reg = DPLL(0); |
@@ -1725,7 +1723,8 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv, | |||
1725 | dpll_reg, port_mask, expected_mask, | 1723 | dpll_reg, port_mask, expected_mask, |
1726 | 1000)) | 1724 | 1000)) |
1727 | WARN(1, "timed out waiting for port %c ready: got 0x%x, expected 0x%x\n", | 1725 | WARN(1, "timed out waiting for port %c ready: got 0x%x, expected 0x%x\n", |
1728 | port_name(dport->port), I915_READ(dpll_reg) & port_mask, expected_mask); | 1726 | port_name(dport->base.port), |
1727 | I915_READ(dpll_reg) & port_mask, expected_mask); | ||
1729 | } | 1728 | } |
1730 | 1729 | ||
1731 | static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, | 1730 | static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, |
@@ -1873,8 +1872,6 @@ enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc) | |||
1873 | { | 1872 | { |
1874 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); | 1873 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
1875 | 1874 | ||
1876 | WARN_ON(!crtc->config->has_pch_encoder); | ||
1877 | |||
1878 | if (HAS_PCH_LPT(dev_priv)) | 1875 | if (HAS_PCH_LPT(dev_priv)) |
1879 | return PIPE_A; | 1876 | return PIPE_A; |
1880 | else | 1877 | else |
@@ -3433,20 +3430,11 @@ static u32 skl_plane_ctl_format(uint32_t pixel_format) | |||
3433 | case DRM_FORMAT_RGB565: | 3430 | case DRM_FORMAT_RGB565: |
3434 | return PLANE_CTL_FORMAT_RGB_565; | 3431 | return PLANE_CTL_FORMAT_RGB_565; |
3435 | case DRM_FORMAT_XBGR8888: | 3432 | case DRM_FORMAT_XBGR8888: |
3433 | case DRM_FORMAT_ABGR8888: | ||
3436 | return PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX; | 3434 | return PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX; |
3437 | case DRM_FORMAT_XRGB8888: | 3435 | case DRM_FORMAT_XRGB8888: |
3438 | return PLANE_CTL_FORMAT_XRGB_8888; | ||
3439 | /* | ||
3440 | * XXX: For ARBG/ABGR formats we default to expecting scanout buffers | ||
3441 | * to be already pre-multiplied. We need to add a knob (or a different | ||
3442 | * DRM_FORMAT) for user-space to configure that. | ||
3443 | */ | ||
3444 | case DRM_FORMAT_ABGR8888: | ||
3445 | return PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX | | ||
3446 | PLANE_CTL_ALPHA_SW_PREMULTIPLY; | ||
3447 | case DRM_FORMAT_ARGB8888: | 3436 | case DRM_FORMAT_ARGB8888: |
3448 | return PLANE_CTL_FORMAT_XRGB_8888 | | 3437 | return PLANE_CTL_FORMAT_XRGB_8888; |
3449 | PLANE_CTL_ALPHA_SW_PREMULTIPLY; | ||
3450 | case DRM_FORMAT_XRGB2101010: | 3438 | case DRM_FORMAT_XRGB2101010: |
3451 | return PLANE_CTL_FORMAT_XRGB_2101010; | 3439 | return PLANE_CTL_FORMAT_XRGB_2101010; |
3452 | case DRM_FORMAT_XBGR2101010: | 3440 | case DRM_FORMAT_XBGR2101010: |
@@ -3466,6 +3454,33 @@ static u32 skl_plane_ctl_format(uint32_t pixel_format) | |||
3466 | return 0; | 3454 | return 0; |
3467 | } | 3455 | } |
3468 | 3456 | ||
3457 | /* | ||
3458 | * XXX: For ARBG/ABGR formats we default to expecting scanout buffers | ||
3459 | * to be already pre-multiplied. We need to add a knob (or a different | ||
3460 | * DRM_FORMAT) for user-space to configure that. | ||
3461 | */ | ||
3462 | static u32 skl_plane_ctl_alpha(uint32_t pixel_format) | ||
3463 | { | ||
3464 | switch (pixel_format) { | ||
3465 | case DRM_FORMAT_ABGR8888: | ||
3466 | case DRM_FORMAT_ARGB8888: | ||
3467 | return PLANE_CTL_ALPHA_SW_PREMULTIPLY; | ||
3468 | default: | ||
3469 | return PLANE_CTL_ALPHA_DISABLE; | ||
3470 | } | ||
3471 | } | ||
3472 | |||
3473 | static u32 glk_plane_color_ctl_alpha(uint32_t pixel_format) | ||
3474 | { | ||
3475 | switch (pixel_format) { | ||
3476 | case DRM_FORMAT_ABGR8888: | ||
3477 | case DRM_FORMAT_ARGB8888: | ||
3478 | return PLANE_COLOR_ALPHA_SW_PREMULTIPLY; | ||
3479 | default: | ||
3480 | return PLANE_COLOR_ALPHA_DISABLE; | ||
3481 | } | ||
3482 | } | ||
3483 | |||
3469 | static u32 skl_plane_ctl_tiling(uint64_t fb_modifier) | 3484 | static u32 skl_plane_ctl_tiling(uint64_t fb_modifier) |
3470 | { | 3485 | { |
3471 | switch (fb_modifier) { | 3486 | switch (fb_modifier) { |
@@ -3522,7 +3537,8 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, | |||
3522 | 3537 | ||
3523 | plane_ctl = PLANE_CTL_ENABLE; | 3538 | plane_ctl = PLANE_CTL_ENABLE; |
3524 | 3539 | ||
3525 | if (!IS_GEMINILAKE(dev_priv) && !IS_CANNONLAKE(dev_priv)) { | 3540 | if (INTEL_GEN(dev_priv) < 10 && !IS_GEMINILAKE(dev_priv)) { |
3541 | plane_ctl |= skl_plane_ctl_alpha(fb->format->format); | ||
3526 | plane_ctl |= | 3542 | plane_ctl |= |
3527 | PLANE_CTL_PIPE_GAMMA_ENABLE | | 3543 | PLANE_CTL_PIPE_GAMMA_ENABLE | |
3528 | PLANE_CTL_PIPE_CSC_ENABLE | | 3544 | PLANE_CTL_PIPE_CSC_ENABLE | |
@@ -3541,6 +3557,20 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, | |||
3541 | return plane_ctl; | 3557 | return plane_ctl; |
3542 | } | 3558 | } |
3543 | 3559 | ||
3560 | u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, | ||
3561 | const struct intel_plane_state *plane_state) | ||
3562 | { | ||
3563 | const struct drm_framebuffer *fb = plane_state->base.fb; | ||
3564 | u32 plane_color_ctl = 0; | ||
3565 | |||
3566 | plane_color_ctl |= PLANE_COLOR_PIPE_GAMMA_ENABLE; | ||
3567 | plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE; | ||
3568 | plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE; | ||
3569 | plane_color_ctl |= glk_plane_color_ctl_alpha(fb->format->format); | ||
3570 | |||
3571 | return plane_color_ctl; | ||
3572 | } | ||
3573 | |||
3544 | static int | 3574 | static int |
3545 | __intel_display_resume(struct drm_device *dev, | 3575 | __intel_display_resume(struct drm_device *dev, |
3546 | struct drm_atomic_state *state, | 3576 | struct drm_atomic_state *state, |
@@ -4483,7 +4513,7 @@ intel_trans_dp_port_sel(struct intel_crtc *crtc) | |||
4483 | for_each_encoder_on_crtc(dev, &crtc->base, encoder) { | 4513 | for_each_encoder_on_crtc(dev, &crtc->base, encoder) { |
4484 | if (encoder->type == INTEL_OUTPUT_DP || | 4514 | if (encoder->type == INTEL_OUTPUT_DP || |
4485 | encoder->type == INTEL_OUTPUT_EDP) | 4515 | encoder->type == INTEL_OUTPUT_EDP) |
4486 | return enc_to_dig_port(&encoder->base)->port; | 4516 | return encoder->port; |
4487 | } | 4517 | } |
4488 | 4518 | ||
4489 | return -1; | 4519 | return -1; |
@@ -4834,8 +4864,9 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc) | |||
4834 | } | 4864 | } |
4835 | } | 4865 | } |
4836 | 4866 | ||
4837 | void hsw_enable_ips(struct intel_crtc *crtc) | 4867 | void hsw_enable_ips(const struct intel_crtc_state *crtc_state) |
4838 | { | 4868 | { |
4869 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); | ||
4839 | struct drm_device *dev = crtc->base.dev; | 4870 | struct drm_device *dev = crtc->base.dev; |
4840 | struct drm_i915_private *dev_priv = to_i915(dev); | 4871 | struct drm_i915_private *dev_priv = to_i915(dev); |
4841 | 4872 | ||
@@ -4873,12 +4904,13 @@ void hsw_enable_ips(struct intel_crtc *crtc) | |||
4873 | } | 4904 | } |
4874 | } | 4905 | } |
4875 | 4906 | ||
4876 | void hsw_disable_ips(struct intel_crtc *crtc) | 4907 | void hsw_disable_ips(const struct intel_crtc_state *crtc_state) |
4877 | { | 4908 | { |
4909 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); | ||
4878 | struct drm_device *dev = crtc->base.dev; | 4910 | struct drm_device *dev = crtc->base.dev; |
4879 | struct drm_i915_private *dev_priv = to_i915(dev); | 4911 | struct drm_i915_private *dev_priv = to_i915(dev); |
4880 | 4912 | ||
4881 | if (!crtc->config->ips_enabled) | 4913 | if (!crtc_state->ips_enabled) |
4882 | return; | 4914 | return; |
4883 | 4915 | ||
4884 | assert_plane_enabled(dev_priv, crtc->plane); | 4916 | assert_plane_enabled(dev_priv, crtc->plane); |
@@ -4926,7 +4958,8 @@ static void intel_crtc_dpms_overlay_disable(struct intel_crtc *intel_crtc) | |||
4926 | * completely hide the primary plane. | 4958 | * completely hide the primary plane. |
4927 | */ | 4959 | */ |
4928 | static void | 4960 | static void |
4929 | intel_post_enable_primary(struct drm_crtc *crtc) | 4961 | intel_post_enable_primary(struct drm_crtc *crtc, |
4962 | const struct intel_crtc_state *new_crtc_state) | ||
4930 | { | 4963 | { |
4931 | struct drm_device *dev = crtc->dev; | 4964 | struct drm_device *dev = crtc->dev; |
4932 | struct drm_i915_private *dev_priv = to_i915(dev); | 4965 | struct drm_i915_private *dev_priv = to_i915(dev); |
@@ -4939,7 +4972,7 @@ intel_post_enable_primary(struct drm_crtc *crtc) | |||
4939 | * when going from primary only to sprite only and vice | 4972 | * when going from primary only to sprite only and vice |
4940 | * versa. | 4973 | * versa. |
4941 | */ | 4974 | */ |
4942 | hsw_enable_ips(intel_crtc); | 4975 | hsw_enable_ips(new_crtc_state); |
4943 | 4976 | ||
4944 | /* | 4977 | /* |
4945 | * Gen2 reports pipe underruns whenever all planes are disabled. | 4978 | * Gen2 reports pipe underruns whenever all planes are disabled. |
@@ -4958,7 +4991,8 @@ intel_post_enable_primary(struct drm_crtc *crtc) | |||
4958 | 4991 | ||
4959 | /* FIXME move all this to pre_plane_update() with proper state tracking */ | 4992 | /* FIXME move all this to pre_plane_update() with proper state tracking */ |
4960 | static void | 4993 | static void |
4961 | intel_pre_disable_primary(struct drm_crtc *crtc) | 4994 | intel_pre_disable_primary(struct drm_crtc *crtc, |
4995 | const struct intel_crtc_state *old_crtc_state) | ||
4962 | { | 4996 | { |
4963 | struct drm_device *dev = crtc->dev; | 4997 | struct drm_device *dev = crtc->dev; |
4964 | struct drm_i915_private *dev_priv = to_i915(dev); | 4998 | struct drm_i915_private *dev_priv = to_i915(dev); |
@@ -4980,7 +5014,7 @@ intel_pre_disable_primary(struct drm_crtc *crtc) | |||
4980 | * when going from primary only to sprite only and vice | 5014 | * when going from primary only to sprite only and vice |
4981 | * versa. | 5015 | * versa. |
4982 | */ | 5016 | */ |
4983 | hsw_disable_ips(intel_crtc); | 5017 | hsw_disable_ips(old_crtc_state); |
4984 | } | 5018 | } |
4985 | 5019 | ||
4986 | /* FIXME get rid of this and use pre_plane_update */ | 5020 | /* FIXME get rid of this and use pre_plane_update */ |
@@ -4992,7 +5026,7 @@ intel_pre_disable_primary_noatomic(struct drm_crtc *crtc) | |||
4992 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 5026 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
4993 | int pipe = intel_crtc->pipe; | 5027 | int pipe = intel_crtc->pipe; |
4994 | 5028 | ||
4995 | intel_pre_disable_primary(crtc); | 5029 | intel_pre_disable_primary(crtc, to_intel_crtc_state(crtc->state)); |
4996 | 5030 | ||
4997 | /* | 5031 | /* |
4998 | * Vblank time updates from the shadow to live plane control register | 5032 | * Vblank time updates from the shadow to live plane control register |
@@ -5036,7 +5070,7 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state) | |||
5036 | if (primary_state->base.visible && | 5070 | if (primary_state->base.visible && |
5037 | (needs_modeset(&pipe_config->base) || | 5071 | (needs_modeset(&pipe_config->base) || |
5038 | !old_primary_state->base.visible)) | 5072 | !old_primary_state->base.visible)) |
5039 | intel_post_enable_primary(&crtc->base); | 5073 | intel_post_enable_primary(&crtc->base, pipe_config); |
5040 | } | 5074 | } |
5041 | } | 5075 | } |
5042 | 5076 | ||
@@ -5065,7 +5099,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state, | |||
5065 | 5099 | ||
5066 | if (old_primary_state->base.visible && | 5100 | if (old_primary_state->base.visible && |
5067 | (modeset || !primary_state->base.visible)) | 5101 | (modeset || !primary_state->base.visible)) |
5068 | intel_pre_disable_primary(&crtc->base); | 5102 | intel_pre_disable_primary(&crtc->base, old_crtc_state); |
5069 | } | 5103 | } |
5070 | 5104 | ||
5071 | /* | 5105 | /* |
@@ -5939,6 +5973,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc, | |||
5939 | 5973 | ||
5940 | dev_priv->active_crtcs &= ~(1 << intel_crtc->pipe); | 5974 | dev_priv->active_crtcs &= ~(1 << intel_crtc->pipe); |
5941 | dev_priv->min_cdclk[intel_crtc->pipe] = 0; | 5975 | dev_priv->min_cdclk[intel_crtc->pipe] = 0; |
5976 | dev_priv->min_voltage_level[intel_crtc->pipe] = 0; | ||
5942 | } | 5977 | } |
5943 | 5978 | ||
5944 | /* | 5979 | /* |
@@ -7633,7 +7668,7 @@ static void ironlake_init_pch_refclk(struct drm_i915_private *dev_priv) | |||
7633 | break; | 7668 | break; |
7634 | case INTEL_OUTPUT_EDP: | 7669 | case INTEL_OUTPUT_EDP: |
7635 | has_panel = true; | 7670 | has_panel = true; |
7636 | if (enc_to_dig_port(&encoder->base)->port == PORT_A) | 7671 | if (encoder->port == PORT_A) |
7637 | has_cpu_edp = true; | 7672 | has_cpu_edp = true; |
7638 | break; | 7673 | break; |
7639 | default: | 7674 | default: |
@@ -8426,7 +8461,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, | |||
8426 | { | 8461 | { |
8427 | struct drm_device *dev = crtc->base.dev; | 8462 | struct drm_device *dev = crtc->base.dev; |
8428 | struct drm_i915_private *dev_priv = to_i915(dev); | 8463 | struct drm_i915_private *dev_priv = to_i915(dev); |
8429 | u32 val, base, offset, stride_mult, tiling; | 8464 | u32 val, base, offset, stride_mult, tiling, alpha; |
8430 | int pipe = crtc->pipe; | 8465 | int pipe = crtc->pipe; |
8431 | int fourcc, pixel_format; | 8466 | int fourcc, pixel_format; |
8432 | unsigned int aligned_height; | 8467 | unsigned int aligned_height; |
@@ -8448,9 +8483,16 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, | |||
8448 | goto error; | 8483 | goto error; |
8449 | 8484 | ||
8450 | pixel_format = val & PLANE_CTL_FORMAT_MASK; | 8485 | pixel_format = val & PLANE_CTL_FORMAT_MASK; |
8486 | |||
8487 | if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { | ||
8488 | alpha = I915_READ(PLANE_COLOR_CTL(pipe, 0)); | ||
8489 | alpha &= PLANE_COLOR_ALPHA_MASK; | ||
8490 | } else { | ||
8491 | alpha = val & PLANE_CTL_ALPHA_MASK; | ||
8492 | } | ||
8493 | |||
8451 | fourcc = skl_format_to_fourcc(pixel_format, | 8494 | fourcc = skl_format_to_fourcc(pixel_format, |
8452 | val & PLANE_CTL_ORDER_RGBX, | 8495 | val & PLANE_CTL_ORDER_RGBX, alpha); |
8453 | val & PLANE_CTL_ALPHA_MASK); | ||
8454 | fb->format = drm_format_info(fourcc); | 8496 | fb->format = drm_format_info(fourcc); |
8455 | 8497 | ||
8456 | tiling = val & PLANE_CTL_TILED_MASK; | 8498 | tiling = val & PLANE_CTL_TILED_MASK; |
@@ -8857,7 +8899,9 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv) | |||
8857 | } | 8899 | } |
8858 | 8900 | ||
8859 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); | 8901 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
8902 | |||
8860 | intel_update_cdclk(dev_priv); | 8903 | intel_update_cdclk(dev_priv); |
8904 | intel_dump_cdclk_state(&dev_priv->cdclk.hw, "Current CDCLK"); | ||
8861 | } | 8905 | } |
8862 | 8906 | ||
8863 | /* | 8907 | /* |
@@ -9231,10 +9275,6 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, | |||
9231 | ironlake_get_pfit_config(crtc, pipe_config); | 9275 | ironlake_get_pfit_config(crtc, pipe_config); |
9232 | } | 9276 | } |
9233 | 9277 | ||
9234 | if (IS_HASWELL(dev_priv)) | ||
9235 | pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) && | ||
9236 | (I915_READ(IPS_CTL) & IPS_ENABLE); | ||
9237 | |||
9238 | if (pipe_config->cpu_transcoder != TRANSCODER_EDP && | 9278 | if (pipe_config->cpu_transcoder != TRANSCODER_EDP && |
9239 | !transcoder_is_dsi(pipe_config->cpu_transcoder)) { | 9279 | !transcoder_is_dsi(pipe_config->cpu_transcoder)) { |
9240 | pipe_config->pixel_multiplier = | 9280 | pipe_config->pixel_multiplier = |
@@ -10578,7 +10618,7 @@ static const char * const output_type_str[] = { | |||
10578 | OUTPUT_TYPE(DP), | 10618 | OUTPUT_TYPE(DP), |
10579 | OUTPUT_TYPE(EDP), | 10619 | OUTPUT_TYPE(EDP), |
10580 | OUTPUT_TYPE(DSI), | 10620 | OUTPUT_TYPE(DSI), |
10581 | OUTPUT_TYPE(UNKNOWN), | 10621 | OUTPUT_TYPE(DDI), |
10582 | OUTPUT_TYPE(DP_MST), | 10622 | OUTPUT_TYPE(DP_MST), |
10583 | }; | 10623 | }; |
10584 | 10624 | ||
@@ -10749,13 +10789,13 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state) | |||
10749 | 10789 | ||
10750 | switch (encoder->type) { | 10790 | switch (encoder->type) { |
10751 | unsigned int port_mask; | 10791 | unsigned int port_mask; |
10752 | case INTEL_OUTPUT_UNKNOWN: | 10792 | case INTEL_OUTPUT_DDI: |
10753 | if (WARN_ON(!HAS_DDI(to_i915(dev)))) | 10793 | if (WARN_ON(!HAS_DDI(to_i915(dev)))) |
10754 | break; | 10794 | break; |
10755 | case INTEL_OUTPUT_DP: | 10795 | case INTEL_OUTPUT_DP: |
10756 | case INTEL_OUTPUT_HDMI: | 10796 | case INTEL_OUTPUT_HDMI: |
10757 | case INTEL_OUTPUT_EDP: | 10797 | case INTEL_OUTPUT_EDP: |
10758 | port_mask = 1 << enc_to_dig_port(&encoder->base)->port; | 10798 | port_mask = 1 << encoder->port; |
10759 | 10799 | ||
10760 | /* the same port mustn't appear more than once */ | 10800 | /* the same port mustn't appear more than once */ |
10761 | if (used_ports & port_mask) | 10801 | if (used_ports & port_mask) |
@@ -10765,7 +10805,7 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state) | |||
10765 | break; | 10805 | break; |
10766 | case INTEL_OUTPUT_DP_MST: | 10806 | case INTEL_OUTPUT_DP_MST: |
10767 | used_mst_ports |= | 10807 | used_mst_ports |= |
10768 | 1 << enc_to_mst(&encoder->base)->primary->port; | 10808 | 1 << encoder->port; |
10769 | break; | 10809 | break; |
10770 | default: | 10810 | default: |
10771 | break; | 10811 | break; |
@@ -10882,7 +10922,12 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, | |||
10882 | * Determine output_types before calling the .compute_config() | 10922 | * Determine output_types before calling the .compute_config() |
10883 | * hooks so that the hooks can use this information safely. | 10923 | * hooks so that the hooks can use this information safely. |
10884 | */ | 10924 | */ |
10885 | pipe_config->output_types |= 1 << encoder->type; | 10925 | if (encoder->compute_output_type) |
10926 | pipe_config->output_types |= | ||
10927 | BIT(encoder->compute_output_type(encoder, pipe_config, | ||
10928 | connector_state)); | ||
10929 | else | ||
10930 | pipe_config->output_types |= BIT(encoder->type); | ||
10886 | } | 10931 | } |
10887 | 10932 | ||
10888 | encoder_retry: | 10933 | encoder_retry: |
@@ -11071,6 +11116,9 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv, | |||
11071 | bool adjust) | 11116 | bool adjust) |
11072 | { | 11117 | { |
11073 | bool ret = true; | 11118 | bool ret = true; |
11119 | bool fixup_inherited = adjust && | ||
11120 | (current_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED) && | ||
11121 | !(pipe_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED); | ||
11074 | 11122 | ||
11075 | #define PIPE_CONF_CHECK_X(name) \ | 11123 | #define PIPE_CONF_CHECK_X(name) \ |
11076 | if (current_config->name != pipe_config->name) { \ | 11124 | if (current_config->name != pipe_config->name) { \ |
@@ -11090,6 +11138,31 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv, | |||
11090 | ret = false; \ | 11138 | ret = false; \ |
11091 | } | 11139 | } |
11092 | 11140 | ||
11141 | #define PIPE_CONF_CHECK_BOOL(name) \ | ||
11142 | if (current_config->name != pipe_config->name) { \ | ||
11143 | pipe_config_err(adjust, __stringify(name), \ | ||
11144 | "(expected %s, found %s)\n", \ | ||
11145 | yesno(current_config->name), \ | ||
11146 | yesno(pipe_config->name)); \ | ||
11147 | ret = false; \ | ||
11148 | } | ||
11149 | |||
11150 | /* | ||
11151 | * Checks state where we only read out the enabling, but not the entire | ||
11152 | * state itself (like full infoframes or ELD for audio). These states | ||
11153 | * require a full modeset on bootup to fix up. | ||
11154 | */ | ||
11155 | #define PIPE_CONF_CHECK_BOOL_INCOMPLETE(name) \ | ||
11156 | if (!fixup_inherited || (!current_config->name && !pipe_config->name)) { \ | ||
11157 | PIPE_CONF_CHECK_BOOL(name); \ | ||
11158 | } else { \ | ||
11159 | pipe_config_err(adjust, __stringify(name), \ | ||
11160 | "unable to verify whether state matches exactly, forcing modeset (expected %s, found %s)\n", \ | ||
11161 | yesno(current_config->name), \ | ||
11162 | yesno(pipe_config->name)); \ | ||
11163 | ret = false; \ | ||
11164 | } | ||
11165 | |||
11093 | #define PIPE_CONF_CHECK_P(name) \ | 11166 | #define PIPE_CONF_CHECK_P(name) \ |
11094 | if (current_config->name != pipe_config->name) { \ | 11167 | if (current_config->name != pipe_config->name) { \ |
11095 | pipe_config_err(adjust, __stringify(name), \ | 11168 | pipe_config_err(adjust, __stringify(name), \ |
@@ -11175,7 +11248,7 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv, | |||
11175 | 11248 | ||
11176 | PIPE_CONF_CHECK_I(cpu_transcoder); | 11249 | PIPE_CONF_CHECK_I(cpu_transcoder); |
11177 | 11250 | ||
11178 | PIPE_CONF_CHECK_I(has_pch_encoder); | 11251 | PIPE_CONF_CHECK_BOOL(has_pch_encoder); |
11179 | PIPE_CONF_CHECK_I(fdi_lanes); | 11252 | PIPE_CONF_CHECK_I(fdi_lanes); |
11180 | PIPE_CONF_CHECK_M_N(fdi_m_n); | 11253 | PIPE_CONF_CHECK_M_N(fdi_m_n); |
11181 | 11254 | ||
@@ -11207,17 +11280,17 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv, | |||
11207 | PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vsync_end); | 11280 | PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vsync_end); |
11208 | 11281 | ||
11209 | PIPE_CONF_CHECK_I(pixel_multiplier); | 11282 | PIPE_CONF_CHECK_I(pixel_multiplier); |
11210 | PIPE_CONF_CHECK_I(has_hdmi_sink); | 11283 | PIPE_CONF_CHECK_BOOL(has_hdmi_sink); |
11211 | if ((INTEL_GEN(dev_priv) < 8 && !IS_HASWELL(dev_priv)) || | 11284 | if ((INTEL_GEN(dev_priv) < 8 && !IS_HASWELL(dev_priv)) || |
11212 | IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) | 11285 | IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) |
11213 | PIPE_CONF_CHECK_I(limited_color_range); | 11286 | PIPE_CONF_CHECK_BOOL(limited_color_range); |
11214 | 11287 | ||
11215 | PIPE_CONF_CHECK_I(hdmi_scrambling); | 11288 | PIPE_CONF_CHECK_BOOL(hdmi_scrambling); |
11216 | PIPE_CONF_CHECK_I(hdmi_high_tmds_clock_ratio); | 11289 | PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio); |
11217 | PIPE_CONF_CHECK_I(has_infoframe); | 11290 | PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_infoframe); |
11218 | PIPE_CONF_CHECK_I(ycbcr420); | 11291 | PIPE_CONF_CHECK_BOOL(ycbcr420); |
11219 | 11292 | ||
11220 | PIPE_CONF_CHECK_I(has_audio); | 11293 | PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio); |
11221 | 11294 | ||
11222 | PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags, | 11295 | PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags, |
11223 | DRM_MODE_FLAG_INTERLACE); | 11296 | DRM_MODE_FLAG_INTERLACE); |
@@ -11243,7 +11316,7 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv, | |||
11243 | PIPE_CONF_CHECK_I(pipe_src_w); | 11316 | PIPE_CONF_CHECK_I(pipe_src_w); |
11244 | PIPE_CONF_CHECK_I(pipe_src_h); | 11317 | PIPE_CONF_CHECK_I(pipe_src_h); |
11245 | 11318 | ||
11246 | PIPE_CONF_CHECK_I(pch_pfit.enabled); | 11319 | PIPE_CONF_CHECK_BOOL(pch_pfit.enabled); |
11247 | if (current_config->pch_pfit.enabled) { | 11320 | if (current_config->pch_pfit.enabled) { |
11248 | PIPE_CONF_CHECK_X(pch_pfit.pos); | 11321 | PIPE_CONF_CHECK_X(pch_pfit.pos); |
11249 | PIPE_CONF_CHECK_X(pch_pfit.size); | 11322 | PIPE_CONF_CHECK_X(pch_pfit.size); |
@@ -11253,11 +11326,7 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv, | |||
11253 | PIPE_CONF_CHECK_CLOCK_FUZZY(pixel_rate); | 11326 | PIPE_CONF_CHECK_CLOCK_FUZZY(pixel_rate); |
11254 | } | 11327 | } |
11255 | 11328 | ||
11256 | /* BDW+ don't expose a synchronous way to read the state */ | 11329 | PIPE_CONF_CHECK_BOOL(double_wide); |
11257 | if (IS_HASWELL(dev_priv)) | ||
11258 | PIPE_CONF_CHECK_I(ips_enabled); | ||
11259 | |||
11260 | PIPE_CONF_CHECK_I(double_wide); | ||
11261 | 11330 | ||
11262 | PIPE_CONF_CHECK_P(shared_dpll); | 11331 | PIPE_CONF_CHECK_P(shared_dpll); |
11263 | PIPE_CONF_CHECK_X(dpll_hw_state.dpll); | 11332 | PIPE_CONF_CHECK_X(dpll_hw_state.dpll); |
@@ -11291,8 +11360,12 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv, | |||
11291 | PIPE_CONF_CHECK_CLOCK_FUZZY(base.adjusted_mode.crtc_clock); | 11360 | PIPE_CONF_CHECK_CLOCK_FUZZY(base.adjusted_mode.crtc_clock); |
11292 | PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock); | 11361 | PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock); |
11293 | 11362 | ||
11363 | PIPE_CONF_CHECK_I(min_voltage_level); | ||
11364 | |||
11294 | #undef PIPE_CONF_CHECK_X | 11365 | #undef PIPE_CONF_CHECK_X |
11295 | #undef PIPE_CONF_CHECK_I | 11366 | #undef PIPE_CONF_CHECK_I |
11367 | #undef PIPE_CONF_CHECK_BOOL | ||
11368 | #undef PIPE_CONF_CHECK_BOOL_INCOMPLETE | ||
11296 | #undef PIPE_CONF_CHECK_P | 11369 | #undef PIPE_CONF_CHECK_P |
11297 | #undef PIPE_CONF_CHECK_FLAGS | 11370 | #undef PIPE_CONF_CHECK_FLAGS |
11298 | #undef PIPE_CONF_CHECK_CLOCK_FUZZY | 11371 | #undef PIPE_CONF_CHECK_CLOCK_FUZZY |
@@ -11559,10 +11632,8 @@ verify_crtc_state(struct drm_crtc *crtc, | |||
11559 | "Encoder connected to wrong pipe %c\n", | 11632 | "Encoder connected to wrong pipe %c\n", |
11560 | pipe_name(pipe)); | 11633 | pipe_name(pipe)); |
11561 | 11634 | ||
11562 | if (active) { | 11635 | if (active) |
11563 | pipe_config->output_types |= 1 << encoder->type; | ||
11564 | encoder->get_config(encoder, pipe_config); | 11636 | encoder->get_config(encoder, pipe_config); |
11565 | } | ||
11566 | } | 11637 | } |
11567 | 11638 | ||
11568 | intel_crtc_compute_pixel_rate(pipe_config); | 11639 | intel_crtc_compute_pixel_rate(pipe_config); |
@@ -11933,16 +12004,16 @@ static int intel_modeset_checks(struct drm_atomic_state *state) | |||
11933 | * holding all the crtc locks, even if we don't end up | 12004 | * holding all the crtc locks, even if we don't end up |
11934 | * touching the hardware | 12005 | * touching the hardware |
11935 | */ | 12006 | */ |
11936 | if (!intel_cdclk_state_compare(&dev_priv->cdclk.logical, | 12007 | if (intel_cdclk_changed(&dev_priv->cdclk.logical, |
11937 | &intel_state->cdclk.logical)) { | 12008 | &intel_state->cdclk.logical)) { |
11938 | ret = intel_lock_all_pipes(state); | 12009 | ret = intel_lock_all_pipes(state); |
11939 | if (ret < 0) | 12010 | if (ret < 0) |
11940 | return ret; | 12011 | return ret; |
11941 | } | 12012 | } |
11942 | 12013 | ||
11943 | /* All pipes must be switched off while we change the cdclk. */ | 12014 | /* All pipes must be switched off while we change the cdclk. */ |
11944 | if (!intel_cdclk_state_compare(&dev_priv->cdclk.actual, | 12015 | if (intel_cdclk_needs_modeset(&dev_priv->cdclk.actual, |
11945 | &intel_state->cdclk.actual)) { | 12016 | &intel_state->cdclk.actual)) { |
11946 | ret = intel_modeset_all_pipes(state); | 12017 | ret = intel_modeset_all_pipes(state); |
11947 | if (ret < 0) | 12018 | if (ret < 0) |
11948 | return ret; | 12019 | return ret; |
@@ -11951,6 +12022,9 @@ static int intel_modeset_checks(struct drm_atomic_state *state) | |||
11951 | DRM_DEBUG_KMS("New cdclk calculated to be logical %u kHz, actual %u kHz\n", | 12022 | DRM_DEBUG_KMS("New cdclk calculated to be logical %u kHz, actual %u kHz\n", |
11952 | intel_state->cdclk.logical.cdclk, | 12023 | intel_state->cdclk.logical.cdclk, |
11953 | intel_state->cdclk.actual.cdclk); | 12024 | intel_state->cdclk.actual.cdclk); |
12025 | DRM_DEBUG_KMS("New voltage level calculated to be logical %u, actual %u\n", | ||
12026 | intel_state->cdclk.logical.voltage_level, | ||
12027 | intel_state->cdclk.actual.voltage_level); | ||
11954 | } else { | 12028 | } else { |
11955 | to_intel_atomic_state(state)->cdclk.logical = dev_priv->cdclk.logical; | 12029 | to_intel_atomic_state(state)->cdclk.logical = dev_priv->cdclk.logical; |
11956 | } | 12030 | } |
@@ -12519,6 +12593,9 @@ static int intel_atomic_commit(struct drm_device *dev, | |||
12519 | if (intel_state->modeset) { | 12593 | if (intel_state->modeset) { |
12520 | memcpy(dev_priv->min_cdclk, intel_state->min_cdclk, | 12594 | memcpy(dev_priv->min_cdclk, intel_state->min_cdclk, |
12521 | sizeof(intel_state->min_cdclk)); | 12595 | sizeof(intel_state->min_cdclk)); |
12596 | memcpy(dev_priv->min_voltage_level, | ||
12597 | intel_state->min_voltage_level, | ||
12598 | sizeof(intel_state->min_voltage_level)); | ||
12522 | dev_priv->active_crtcs = intel_state->active_crtcs; | 12599 | dev_priv->active_crtcs = intel_state->active_crtcs; |
12523 | dev_priv->cdclk.logical = intel_state->cdclk.logical; | 12600 | dev_priv->cdclk.logical = intel_state->cdclk.logical; |
12524 | dev_priv->cdclk.actual = intel_state->cdclk.actual; | 12601 | dev_priv->cdclk.actual = intel_state->cdclk.actual; |
@@ -12756,7 +12833,7 @@ skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state | |||
12756 | crtc_clock = crtc_state->base.adjusted_mode.crtc_clock; | 12833 | crtc_clock = crtc_state->base.adjusted_mode.crtc_clock; |
12757 | max_dotclk = to_intel_atomic_state(crtc_state->base.state)->cdclk.logical.cdclk; | 12834 | max_dotclk = to_intel_atomic_state(crtc_state->base.state)->cdclk.logical.cdclk; |
12758 | 12835 | ||
12759 | if (IS_GEMINILAKE(dev_priv)) | 12836 | if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10) |
12760 | max_dotclk *= 2; | 12837 | max_dotclk *= 2; |
12761 | 12838 | ||
12762 | if (WARN_ON_ONCE(!crtc_clock || max_dotclk < crtc_clock)) | 12839 | if (WARN_ON_ONCE(!crtc_clock || max_dotclk < crtc_clock)) |
@@ -12820,6 +12897,9 @@ intel_check_primary_plane(struct intel_plane *plane, | |||
12820 | state->ctl = i9xx_plane_ctl(crtc_state, state); | 12897 | state->ctl = i9xx_plane_ctl(crtc_state, state); |
12821 | } | 12898 | } |
12822 | 12899 | ||
12900 | if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) | ||
12901 | state->color_ctl = glk_plane_color_ctl(crtc_state, state); | ||
12902 | |||
12823 | return 0; | 12903 | return 0; |
12824 | } | 12904 | } |
12825 | 12905 | ||
@@ -12864,6 +12944,7 @@ out: | |||
12864 | static void intel_finish_crtc_commit(struct drm_crtc *crtc, | 12944 | static void intel_finish_crtc_commit(struct drm_crtc *crtc, |
12865 | struct drm_crtc_state *old_crtc_state) | 12945 | struct drm_crtc_state *old_crtc_state) |
12866 | { | 12946 | { |
12947 | struct drm_i915_private *dev_priv = to_i915(crtc->dev); | ||
12867 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 12948 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
12868 | struct intel_atomic_state *old_intel_state = | 12949 | struct intel_atomic_state *old_intel_state = |
12869 | to_intel_atomic_state(old_crtc_state->state); | 12950 | to_intel_atomic_state(old_crtc_state->state); |
@@ -12871,6 +12952,20 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc, | |||
12871 | intel_atomic_get_new_crtc_state(old_intel_state, intel_crtc); | 12952 | intel_atomic_get_new_crtc_state(old_intel_state, intel_crtc); |
12872 | 12953 | ||
12873 | intel_pipe_update_end(new_crtc_state); | 12954 | intel_pipe_update_end(new_crtc_state); |
12955 | |||
12956 | if (new_crtc_state->update_pipe && | ||
12957 | !needs_modeset(&new_crtc_state->base) && | ||
12958 | old_crtc_state->mode.private_flags & I915_MODE_FLAG_INHERITED) { | ||
12959 | if (!IS_GEN2(dev_priv)) | ||
12960 | intel_set_cpu_fifo_underrun_reporting(dev_priv, intel_crtc->pipe, true); | ||
12961 | |||
12962 | if (new_crtc_state->has_pch_encoder) { | ||
12963 | enum pipe pch_transcoder = | ||
12964 | intel_crtc_pch_transcoder(intel_crtc); | ||
12965 | |||
12966 | intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, true); | ||
12967 | } | ||
12968 | } | ||
12874 | } | 12969 | } |
12875 | 12970 | ||
12876 | /** | 12971 | /** |
@@ -14352,6 +14447,7 @@ void intel_modeset_init_hw(struct drm_device *dev) | |||
14352 | struct drm_i915_private *dev_priv = to_i915(dev); | 14447 | struct drm_i915_private *dev_priv = to_i915(dev); |
14353 | 14448 | ||
14354 | intel_update_cdclk(dev_priv); | 14449 | intel_update_cdclk(dev_priv); |
14450 | intel_dump_cdclk_state(&dev_priv->cdclk.hw, "Current CDCLK"); | ||
14355 | dev_priv->cdclk.logical = dev_priv->cdclk.actual = dev_priv->cdclk.hw; | 14451 | dev_priv->cdclk.logical = dev_priv->cdclk.actual = dev_priv->cdclk.hw; |
14356 | } | 14452 | } |
14357 | 14453 | ||
@@ -14431,6 +14527,8 @@ retry: | |||
14431 | 14527 | ||
14432 | cs->wm.need_postvbl_update = true; | 14528 | cs->wm.need_postvbl_update = true; |
14433 | dev_priv->display.optimize_watermarks(intel_state, cs); | 14529 | dev_priv->display.optimize_watermarks(intel_state, cs); |
14530 | |||
14531 | to_intel_crtc_state(crtc->state)->wm = cs->wm; | ||
14434 | } | 14532 | } |
14435 | 14533 | ||
14436 | put_state: | 14534 | put_state: |
@@ -14440,6 +14538,22 @@ fail: | |||
14440 | drm_modeset_acquire_fini(&ctx); | 14538 | drm_modeset_acquire_fini(&ctx); |
14441 | } | 14539 | } |
14442 | 14540 | ||
14541 | static void intel_update_fdi_pll_freq(struct drm_i915_private *dev_priv) | ||
14542 | { | ||
14543 | if (IS_GEN5(dev_priv)) { | ||
14544 | u32 fdi_pll_clk = | ||
14545 | I915_READ(FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK; | ||
14546 | |||
14547 | dev_priv->fdi_pll_freq = (fdi_pll_clk + 2) * 10000; | ||
14548 | } else if (IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv)) { | ||
14549 | dev_priv->fdi_pll_freq = 270000; | ||
14550 | } else { | ||
14551 | return; | ||
14552 | } | ||
14553 | |||
14554 | DRM_DEBUG_DRIVER("FDI PLL freq=%d\n", dev_priv->fdi_pll_freq); | ||
14555 | } | ||
14556 | |||
14443 | int intel_modeset_init(struct drm_device *dev) | 14557 | int intel_modeset_init(struct drm_device *dev) |
14444 | { | 14558 | { |
14445 | struct drm_i915_private *dev_priv = to_i915(dev); | 14559 | struct drm_i915_private *dev_priv = to_i915(dev); |
@@ -14527,6 +14641,7 @@ int intel_modeset_init(struct drm_device *dev) | |||
14527 | } | 14641 | } |
14528 | 14642 | ||
14529 | intel_shared_dpll_init(dev); | 14643 | intel_shared_dpll_init(dev); |
14644 | intel_update_fdi_pll_freq(dev_priv); | ||
14530 | 14645 | ||
14531 | intel_update_czclk(dev_priv); | 14646 | intel_update_czclk(dev_priv); |
14532 | intel_modeset_init_hw(dev); | 14647 | intel_modeset_init_hw(dev); |
@@ -14716,7 +14831,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc, | |||
14716 | enum transcoder cpu_transcoder = crtc->config->cpu_transcoder; | 14831 | enum transcoder cpu_transcoder = crtc->config->cpu_transcoder; |
14717 | 14832 | ||
14718 | /* Clear any frame start delays used for debugging left by the BIOS */ | 14833 | /* Clear any frame start delays used for debugging left by the BIOS */ |
14719 | if (!transcoder_is_dsi(cpu_transcoder)) { | 14834 | if (crtc->active && !transcoder_is_dsi(cpu_transcoder)) { |
14720 | i915_reg_t reg = PIPECONF(cpu_transcoder); | 14835 | i915_reg_t reg = PIPECONF(cpu_transcoder); |
14721 | 14836 | ||
14722 | I915_WRITE(reg, | 14837 | I915_WRITE(reg, |
@@ -14949,7 +15064,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) | |||
14949 | crtc_state = to_intel_crtc_state(crtc->base.state); | 15064 | crtc_state = to_intel_crtc_state(crtc->base.state); |
14950 | 15065 | ||
14951 | encoder->base.crtc = &crtc->base; | 15066 | encoder->base.crtc = &crtc->base; |
14952 | crtc_state->output_types |= 1 << encoder->type; | ||
14953 | encoder->get_config(encoder, crtc_state); | 15067 | encoder->get_config(encoder, crtc_state); |
14954 | } else { | 15068 | } else { |
14955 | encoder->base.crtc = NULL; | 15069 | encoder->base.crtc = NULL; |
@@ -15028,6 +15142,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) | |||
15028 | } | 15142 | } |
15029 | 15143 | ||
15030 | dev_priv->min_cdclk[crtc->pipe] = min_cdclk; | 15144 | dev_priv->min_cdclk[crtc->pipe] = min_cdclk; |
15145 | dev_priv->min_voltage_level[crtc->pipe] = | ||
15146 | crtc_state->min_voltage_level; | ||
15031 | 15147 | ||
15032 | intel_pipe_config_sanity_check(dev_priv, crtc_state); | 15148 | intel_pipe_config_sanity_check(dev_priv, crtc_state); |
15033 | } | 15149 | } |
@@ -15051,6 +15167,23 @@ get_encoder_power_domains(struct drm_i915_private *dev_priv) | |||
15051 | } | 15167 | } |
15052 | } | 15168 | } |
15053 | 15169 | ||
15170 | static void intel_early_display_was(struct drm_i915_private *dev_priv) | ||
15171 | { | ||
15172 | /* Display WA #1185 WaDisableDARBFClkGating:cnl,glk */ | ||
15173 | if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) | ||
15174 | I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) | | ||
15175 | DARBF_GATING_DIS); | ||
15176 | |||
15177 | if (IS_HASWELL(dev_priv)) { | ||
15178 | /* | ||
15179 | * WaRsPkgCStateDisplayPMReq:hsw | ||
15180 | * System hang if this isn't done before disabling all planes! | ||
15181 | */ | ||
15182 | I915_WRITE(CHICKEN_PAR1_1, | ||
15183 | I915_READ(CHICKEN_PAR1_1) | FORCE_ARB_IDLE_PLANES); | ||
15184 | } | ||
15185 | } | ||
15186 | |||
15054 | /* Scan out the current hw modeset state, | 15187 | /* Scan out the current hw modeset state, |
15055 | * and sanitizes it to the current state | 15188 | * and sanitizes it to the current state |
15056 | */ | 15189 | */ |
@@ -15064,15 +15197,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev, | |||
15064 | struct intel_encoder *encoder; | 15197 | struct intel_encoder *encoder; |
15065 | int i; | 15198 | int i; |
15066 | 15199 | ||
15067 | if (IS_HASWELL(dev_priv)) { | 15200 | intel_early_display_was(dev_priv); |
15068 | /* | ||
15069 | * WaRsPkgCStateDisplayPMReq:hsw | ||
15070 | * System hang if this isn't done before disabling all planes! | ||
15071 | */ | ||
15072 | I915_WRITE(CHICKEN_PAR1_1, | ||
15073 | I915_READ(CHICKEN_PAR1_1) | FORCE_ARB_IDLE_PLANES); | ||
15074 | } | ||
15075 | |||
15076 | intel_modeset_readout_hw_state(dev); | 15201 | intel_modeset_readout_hw_state(dev); |
15077 | 15202 | ||
15078 | /* HW state is read out, now we need to sanitize this mess. */ | 15203 | /* HW state is read out, now we need to sanitize this mess. */ |
@@ -15164,17 +15289,6 @@ void intel_display_resume(struct drm_device *dev) | |||
15164 | drm_atomic_state_put(state); | 15289 | drm_atomic_state_put(state); |
15165 | } | 15290 | } |
15166 | 15291 | ||
15167 | void intel_modeset_gem_init(struct drm_device *dev) | ||
15168 | { | ||
15169 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
15170 | |||
15171 | intel_init_gt_powersave(dev_priv); | ||
15172 | |||
15173 | intel_init_clock_gating(dev_priv); | ||
15174 | |||
15175 | intel_setup_overlay(dev_priv); | ||
15176 | } | ||
15177 | |||
15178 | int intel_connector_register(struct drm_connector *connector) | 15292 | int intel_connector_register(struct drm_connector *connector) |
15179 | { | 15293 | { |
15180 | struct intel_connector *intel_connector = to_intel_connector(connector); | 15294 | struct intel_connector *intel_connector = to_intel_connector(connector); |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 65260fb35d2a..bbf2256ba574 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -129,11 +129,13 @@ static struct intel_dp *intel_attached_dp(struct drm_connector *connector) | |||
129 | return enc_to_intel_dp(&intel_attached_encoder(connector)->base); | 129 | return enc_to_intel_dp(&intel_attached_encoder(connector)->base); |
130 | } | 130 | } |
131 | 131 | ||
132 | static void intel_dp_link_down(struct intel_dp *intel_dp); | 132 | static void intel_dp_link_down(struct intel_encoder *encoder, |
133 | const struct intel_crtc_state *old_crtc_state); | ||
133 | static bool edp_panel_vdd_on(struct intel_dp *intel_dp); | 134 | static bool edp_panel_vdd_on(struct intel_dp *intel_dp); |
134 | static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync); | 135 | static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync); |
135 | static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp); | 136 | static void vlv_init_panel_power_sequencer(struct intel_encoder *encoder, |
136 | static void vlv_steal_power_sequencer(struct drm_device *dev, | 137 | const struct intel_crtc_state *crtc_state); |
138 | static void vlv_steal_power_sequencer(struct drm_i915_private *dev_priv, | ||
137 | enum pipe pipe); | 139 | enum pipe pipe); |
138 | static void intel_dp_unset_edid(struct intel_dp *intel_dp); | 140 | static void intel_dp_unset_edid(struct intel_dp *intel_dp); |
139 | 141 | ||
@@ -221,7 +223,7 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp) | |||
221 | { | 223 | { |
222 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | 224 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
223 | struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); | 225 | struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); |
224 | enum port port = dig_port->port; | 226 | enum port port = dig_port->base.port; |
225 | const int *source_rates; | 227 | const int *source_rates; |
226 | int size; | 228 | int size; |
227 | u32 voltage; | 229 | u32 voltage; |
@@ -427,24 +429,19 @@ static void intel_dp_unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes) | |||
427 | } | 429 | } |
428 | 430 | ||
429 | static void | 431 | static void |
430 | intel_dp_init_panel_power_sequencer(struct drm_device *dev, | 432 | intel_dp_init_panel_power_sequencer(struct intel_dp *intel_dp); |
431 | struct intel_dp *intel_dp); | ||
432 | static void | 433 | static void |
433 | intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, | 434 | intel_dp_init_panel_power_sequencer_registers(struct intel_dp *intel_dp, |
434 | struct intel_dp *intel_dp, | ||
435 | bool force_disable_vdd); | 435 | bool force_disable_vdd); |
436 | static void | 436 | static void |
437 | intel_dp_pps_init(struct drm_device *dev, struct intel_dp *intel_dp); | 437 | intel_dp_pps_init(struct intel_dp *intel_dp); |
438 | 438 | ||
439 | static void pps_lock(struct intel_dp *intel_dp) | 439 | static void pps_lock(struct intel_dp *intel_dp) |
440 | { | 440 | { |
441 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 441 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
442 | struct intel_encoder *encoder = &intel_dig_port->base; | ||
443 | struct drm_device *dev = encoder->base.dev; | ||
444 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
445 | 442 | ||
446 | /* | 443 | /* |
447 | * See vlv_power_sequencer_reset() why we need | 444 | * See intel_power_sequencer_reset() why we need |
448 | * a power domain reference here. | 445 | * a power domain reference here. |
449 | */ | 446 | */ |
450 | intel_display_power_get(dev_priv, intel_dp->aux_power_domain); | 447 | intel_display_power_get(dev_priv, intel_dp->aux_power_domain); |
@@ -454,10 +451,7 @@ static void pps_lock(struct intel_dp *intel_dp) | |||
454 | 451 | ||
455 | static void pps_unlock(struct intel_dp *intel_dp) | 452 | static void pps_unlock(struct intel_dp *intel_dp) |
456 | { | 453 | { |
457 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 454 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
458 | struct intel_encoder *encoder = &intel_dig_port->base; | ||
459 | struct drm_device *dev = encoder->base.dev; | ||
460 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
461 | 455 | ||
462 | mutex_unlock(&dev_priv->pps_mutex); | 456 | mutex_unlock(&dev_priv->pps_mutex); |
463 | 457 | ||
@@ -467,8 +461,8 @@ static void pps_unlock(struct intel_dp *intel_dp) | |||
467 | static void | 461 | static void |
468 | vlv_power_sequencer_kick(struct intel_dp *intel_dp) | 462 | vlv_power_sequencer_kick(struct intel_dp *intel_dp) |
469 | { | 463 | { |
464 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | ||
470 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 465 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
471 | struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev); | ||
472 | enum pipe pipe = intel_dp->pps_pipe; | 466 | enum pipe pipe = intel_dp->pps_pipe; |
473 | bool pll_enabled, release_cl_override = false; | 467 | bool pll_enabled, release_cl_override = false; |
474 | enum dpio_phy phy = DPIO_PHY(pipe); | 468 | enum dpio_phy phy = DPIO_PHY(pipe); |
@@ -477,11 +471,11 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp) | |||
477 | 471 | ||
478 | if (WARN(I915_READ(intel_dp->output_reg) & DP_PORT_EN, | 472 | if (WARN(I915_READ(intel_dp->output_reg) & DP_PORT_EN, |
479 | "skipping pipe %c power seqeuncer kick due to port %c being active\n", | 473 | "skipping pipe %c power seqeuncer kick due to port %c being active\n", |
480 | pipe_name(pipe), port_name(intel_dig_port->port))) | 474 | pipe_name(pipe), port_name(intel_dig_port->base.port))) |
481 | return; | 475 | return; |
482 | 476 | ||
483 | DRM_DEBUG_KMS("kicking pipe %c power sequencer for port %c\n", | 477 | DRM_DEBUG_KMS("kicking pipe %c power sequencer for port %c\n", |
484 | pipe_name(pipe), port_name(intel_dig_port->port)); | 478 | pipe_name(pipe), port_name(intel_dig_port->base.port)); |
485 | 479 | ||
486 | /* Preserve the BIOS-computed detected bit. This is | 480 | /* Preserve the BIOS-computed detected bit. This is |
487 | * supposed to be read-only. | 481 | * supposed to be read-only. |
@@ -578,9 +572,8 @@ static enum pipe vlv_find_free_pps(struct drm_i915_private *dev_priv) | |||
578 | static enum pipe | 572 | static enum pipe |
579 | vlv_power_sequencer_pipe(struct intel_dp *intel_dp) | 573 | vlv_power_sequencer_pipe(struct intel_dp *intel_dp) |
580 | { | 574 | { |
575 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | ||
581 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 576 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
582 | struct drm_device *dev = intel_dig_port->base.base.dev; | ||
583 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
584 | enum pipe pipe; | 577 | enum pipe pipe; |
585 | 578 | ||
586 | lockdep_assert_held(&dev_priv->pps_mutex); | 579 | lockdep_assert_held(&dev_priv->pps_mutex); |
@@ -603,16 +596,16 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp) | |||
603 | if (WARN_ON(pipe == INVALID_PIPE)) | 596 | if (WARN_ON(pipe == INVALID_PIPE)) |
604 | pipe = PIPE_A; | 597 | pipe = PIPE_A; |
605 | 598 | ||
606 | vlv_steal_power_sequencer(dev, pipe); | 599 | vlv_steal_power_sequencer(dev_priv, pipe); |
607 | intel_dp->pps_pipe = pipe; | 600 | intel_dp->pps_pipe = pipe; |
608 | 601 | ||
609 | DRM_DEBUG_KMS("picked pipe %c power sequencer for port %c\n", | 602 | DRM_DEBUG_KMS("picked pipe %c power sequencer for port %c\n", |
610 | pipe_name(intel_dp->pps_pipe), | 603 | pipe_name(intel_dp->pps_pipe), |
611 | port_name(intel_dig_port->port)); | 604 | port_name(intel_dig_port->base.port)); |
612 | 605 | ||
613 | /* init power sequencer on this pipe and port */ | 606 | /* init power sequencer on this pipe and port */ |
614 | intel_dp_init_panel_power_sequencer(dev, intel_dp); | 607 | intel_dp_init_panel_power_sequencer(intel_dp); |
615 | intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, true); | 608 | intel_dp_init_panel_power_sequencer_registers(intel_dp, true); |
616 | 609 | ||
617 | /* | 610 | /* |
618 | * Even vdd force doesn't work until we've made | 611 | * Even vdd force doesn't work until we've made |
@@ -626,9 +619,7 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp) | |||
626 | static int | 619 | static int |
627 | bxt_power_sequencer_idx(struct intel_dp *intel_dp) | 620 | bxt_power_sequencer_idx(struct intel_dp *intel_dp) |
628 | { | 621 | { |
629 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 622 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
630 | struct drm_device *dev = intel_dig_port->base.base.dev; | ||
631 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
632 | 623 | ||
633 | lockdep_assert_held(&dev_priv->pps_mutex); | 624 | lockdep_assert_held(&dev_priv->pps_mutex); |
634 | 625 | ||
@@ -649,7 +640,7 @@ bxt_power_sequencer_idx(struct intel_dp *intel_dp) | |||
649 | * Only the HW needs to be reprogrammed, the SW state is fixed and | 640 | * Only the HW needs to be reprogrammed, the SW state is fixed and |
650 | * has been setup during connector init. | 641 | * has been setup during connector init. |
651 | */ | 642 | */ |
652 | intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, false); | 643 | intel_dp_init_panel_power_sequencer_registers(intel_dp, false); |
653 | 644 | ||
654 | return 0; | 645 | return 0; |
655 | } | 646 | } |
@@ -701,10 +692,9 @@ vlv_initial_pps_pipe(struct drm_i915_private *dev_priv, | |||
701 | static void | 692 | static void |
702 | vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp) | 693 | vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp) |
703 | { | 694 | { |
695 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | ||
704 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 696 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
705 | struct drm_device *dev = intel_dig_port->base.base.dev; | 697 | enum port port = intel_dig_port->base.port; |
706 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
707 | enum port port = intel_dig_port->port; | ||
708 | 698 | ||
709 | lockdep_assert_held(&dev_priv->pps_mutex); | 699 | lockdep_assert_held(&dev_priv->pps_mutex); |
710 | 700 | ||
@@ -731,13 +721,12 @@ vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp) | |||
731 | DRM_DEBUG_KMS("initial power sequencer for port %c: pipe %c\n", | 721 | DRM_DEBUG_KMS("initial power sequencer for port %c: pipe %c\n", |
732 | port_name(port), pipe_name(intel_dp->pps_pipe)); | 722 | port_name(port), pipe_name(intel_dp->pps_pipe)); |
733 | 723 | ||
734 | intel_dp_init_panel_power_sequencer(dev, intel_dp); | 724 | intel_dp_init_panel_power_sequencer(intel_dp); |
735 | intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, false); | 725 | intel_dp_init_panel_power_sequencer_registers(intel_dp, false); |
736 | } | 726 | } |
737 | 727 | ||
738 | void intel_power_sequencer_reset(struct drm_i915_private *dev_priv) | 728 | void intel_power_sequencer_reset(struct drm_i915_private *dev_priv) |
739 | { | 729 | { |
740 | struct drm_device *dev = &dev_priv->drm; | ||
741 | struct intel_encoder *encoder; | 730 | struct intel_encoder *encoder; |
742 | 731 | ||
743 | if (WARN_ON(!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) && | 732 | if (WARN_ON(!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) && |
@@ -754,15 +743,20 @@ void intel_power_sequencer_reset(struct drm_i915_private *dev_priv) | |||
754 | * should use them always. | 743 | * should use them always. |
755 | */ | 744 | */ |
756 | 745 | ||
757 | for_each_intel_encoder(dev, encoder) { | 746 | for_each_intel_encoder(&dev_priv->drm, encoder) { |
758 | struct intel_dp *intel_dp; | 747 | struct intel_dp *intel_dp; |
759 | 748 | ||
760 | if (encoder->type != INTEL_OUTPUT_DP && | 749 | if (encoder->type != INTEL_OUTPUT_DP && |
761 | encoder->type != INTEL_OUTPUT_EDP) | 750 | encoder->type != INTEL_OUTPUT_EDP && |
751 | encoder->type != INTEL_OUTPUT_DDI) | ||
762 | continue; | 752 | continue; |
763 | 753 | ||
764 | intel_dp = enc_to_intel_dp(&encoder->base); | 754 | intel_dp = enc_to_intel_dp(&encoder->base); |
765 | 755 | ||
756 | /* Skip pure DVI/HDMI DDI encoders */ | ||
757 | if (!i915_mmio_reg_valid(intel_dp->output_reg)) | ||
758 | continue; | ||
759 | |||
766 | WARN_ON(intel_dp->active_pipe != INVALID_PIPE); | 760 | WARN_ON(intel_dp->active_pipe != INVALID_PIPE); |
767 | 761 | ||
768 | if (encoder->type != INTEL_OUTPUT_EDP) | 762 | if (encoder->type != INTEL_OUTPUT_EDP) |
@@ -783,10 +777,10 @@ struct pps_registers { | |||
783 | i915_reg_t pp_div; | 777 | i915_reg_t pp_div; |
784 | }; | 778 | }; |
785 | 779 | ||
786 | static void intel_pps_get_registers(struct drm_i915_private *dev_priv, | 780 | static void intel_pps_get_registers(struct intel_dp *intel_dp, |
787 | struct intel_dp *intel_dp, | ||
788 | struct pps_registers *regs) | 781 | struct pps_registers *regs) |
789 | { | 782 | { |
783 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | ||
790 | int pps_idx = 0; | 784 | int pps_idx = 0; |
791 | 785 | ||
792 | memset(regs, 0, sizeof(*regs)); | 786 | memset(regs, 0, sizeof(*regs)); |
@@ -809,8 +803,7 @@ _pp_ctrl_reg(struct intel_dp *intel_dp) | |||
809 | { | 803 | { |
810 | struct pps_registers regs; | 804 | struct pps_registers regs; |
811 | 805 | ||
812 | intel_pps_get_registers(to_i915(intel_dp_to_dev(intel_dp)), intel_dp, | 806 | intel_pps_get_registers(intel_dp, ®s); |
813 | ®s); | ||
814 | 807 | ||
815 | return regs.pp_ctrl; | 808 | return regs.pp_ctrl; |
816 | } | 809 | } |
@@ -820,8 +813,7 @@ _pp_stat_reg(struct intel_dp *intel_dp) | |||
820 | { | 813 | { |
821 | struct pps_registers regs; | 814 | struct pps_registers regs; |
822 | 815 | ||
823 | intel_pps_get_registers(to_i915(intel_dp_to_dev(intel_dp)), intel_dp, | 816 | intel_pps_get_registers(intel_dp, ®s); |
824 | ®s); | ||
825 | 817 | ||
826 | return regs.pp_stat; | 818 | return regs.pp_stat; |
827 | } | 819 | } |
@@ -833,8 +825,7 @@ static int edp_notify_handler(struct notifier_block *this, unsigned long code, | |||
833 | { | 825 | { |
834 | struct intel_dp *intel_dp = container_of(this, typeof(* intel_dp), | 826 | struct intel_dp *intel_dp = container_of(this, typeof(* intel_dp), |
835 | edp_notifier); | 827 | edp_notifier); |
836 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 828 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
837 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
838 | 829 | ||
839 | if (!intel_dp_is_edp(intel_dp) || code != SYS_RESTART) | 830 | if (!intel_dp_is_edp(intel_dp) || code != SYS_RESTART) |
840 | return 0; | 831 | return 0; |
@@ -864,8 +855,7 @@ static int edp_notify_handler(struct notifier_block *this, unsigned long code, | |||
864 | 855 | ||
865 | static bool edp_have_panel_power(struct intel_dp *intel_dp) | 856 | static bool edp_have_panel_power(struct intel_dp *intel_dp) |
866 | { | 857 | { |
867 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 858 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
868 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
869 | 859 | ||
870 | lockdep_assert_held(&dev_priv->pps_mutex); | 860 | lockdep_assert_held(&dev_priv->pps_mutex); |
871 | 861 | ||
@@ -878,8 +868,7 @@ static bool edp_have_panel_power(struct intel_dp *intel_dp) | |||
878 | 868 | ||
879 | static bool edp_have_panel_vdd(struct intel_dp *intel_dp) | 869 | static bool edp_have_panel_vdd(struct intel_dp *intel_dp) |
880 | { | 870 | { |
881 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 871 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
882 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
883 | 872 | ||
884 | lockdep_assert_held(&dev_priv->pps_mutex); | 873 | lockdep_assert_held(&dev_priv->pps_mutex); |
885 | 874 | ||
@@ -893,8 +882,7 @@ static bool edp_have_panel_vdd(struct intel_dp *intel_dp) | |||
893 | static void | 882 | static void |
894 | intel_dp_check_edp(struct intel_dp *intel_dp) | 883 | intel_dp_check_edp(struct intel_dp *intel_dp) |
895 | { | 884 | { |
896 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 885 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
897 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
898 | 886 | ||
899 | if (!intel_dp_is_edp(intel_dp)) | 887 | if (!intel_dp_is_edp(intel_dp)) |
900 | return; | 888 | return; |
@@ -910,9 +898,7 @@ intel_dp_check_edp(struct intel_dp *intel_dp) | |||
910 | static uint32_t | 898 | static uint32_t |
911 | intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq) | 899 | intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq) |
912 | { | 900 | { |
913 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 901 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
914 | struct drm_device *dev = intel_dig_port->base.base.dev; | ||
915 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
916 | i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg; | 902 | i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg; |
917 | uint32_t status; | 903 | uint32_t status; |
918 | bool done; | 904 | bool done; |
@@ -959,7 +945,7 @@ static uint32_t ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index) | |||
959 | * like to run at 2MHz. So, take the cdclk or PCH rawclk value and | 945 | * like to run at 2MHz. So, take the cdclk or PCH rawclk value and |
960 | * divide by 2000 and use that | 946 | * divide by 2000 and use that |
961 | */ | 947 | */ |
962 | if (intel_dig_port->port == PORT_A) | 948 | if (intel_dig_port->base.port == PORT_A) |
963 | return DIV_ROUND_CLOSEST(dev_priv->cdclk.hw.cdclk, 2000); | 949 | return DIV_ROUND_CLOSEST(dev_priv->cdclk.hw.cdclk, 2000); |
964 | else | 950 | else |
965 | return DIV_ROUND_CLOSEST(dev_priv->rawclk_freq, 2000); | 951 | return DIV_ROUND_CLOSEST(dev_priv->rawclk_freq, 2000); |
@@ -970,7 +956,7 @@ static uint32_t hsw_get_aux_clock_divider(struct intel_dp *intel_dp, int index) | |||
970 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 956 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
971 | struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev); | 957 | struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev); |
972 | 958 | ||
973 | if (intel_dig_port->port != PORT_A && HAS_PCH_LPT_H(dev_priv)) { | 959 | if (intel_dig_port->base.port != PORT_A && HAS_PCH_LPT_H(dev_priv)) { |
974 | /* Workaround for non-ULT HSW */ | 960 | /* Workaround for non-ULT HSW */ |
975 | switch (index) { | 961 | switch (index) { |
976 | case 0: return 63; | 962 | case 0: return 63; |
@@ -1440,7 +1426,7 @@ static void intel_aux_reg_init(struct intel_dp *intel_dp) | |||
1440 | { | 1426 | { |
1441 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | 1427 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
1442 | enum port port = intel_aux_port(dev_priv, | 1428 | enum port port = intel_aux_port(dev_priv, |
1443 | dp_to_dig_port(intel_dp)->port); | 1429 | dp_to_dig_port(intel_dp)->base.port); |
1444 | int i; | 1430 | int i; |
1445 | 1431 | ||
1446 | intel_dp->aux_ch_ctl_reg = intel_aux_ctl_reg(dev_priv, port); | 1432 | intel_dp->aux_ch_ctl_reg = intel_aux_ctl_reg(dev_priv, port); |
@@ -1458,7 +1444,7 @@ static void | |||
1458 | intel_dp_aux_init(struct intel_dp *intel_dp) | 1444 | intel_dp_aux_init(struct intel_dp *intel_dp) |
1459 | { | 1445 | { |
1460 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 1446 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
1461 | enum port port = intel_dig_port->port; | 1447 | enum port port = intel_dig_port->base.port; |
1462 | 1448 | ||
1463 | intel_aux_reg_init(intel_dp); | 1449 | intel_aux_reg_init(intel_dp); |
1464 | drm_dp_aux_init(&intel_dp->aux); | 1450 | drm_dp_aux_init(&intel_dp->aux); |
@@ -1479,8 +1465,7 @@ static void | |||
1479 | intel_dp_set_clock(struct intel_encoder *encoder, | 1465 | intel_dp_set_clock(struct intel_encoder *encoder, |
1480 | struct intel_crtc_state *pipe_config) | 1466 | struct intel_crtc_state *pipe_config) |
1481 | { | 1467 | { |
1482 | struct drm_device *dev = encoder->base.dev; | 1468 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
1483 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
1484 | const struct dp_link_dpll *divisor = NULL; | 1469 | const struct dp_link_dpll *divisor = NULL; |
1485 | int i, count = 0; | 1470 | int i, count = 0; |
1486 | 1471 | ||
@@ -1628,7 +1613,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, | |||
1628 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 1613 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
1629 | struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; | 1614 | struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; |
1630 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 1615 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
1631 | enum port port = dp_to_dig_port(intel_dp)->port; | 1616 | enum port port = encoder->port; |
1632 | struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc); | 1617 | struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc); |
1633 | struct intel_connector *intel_connector = intel_dp->attached_connector; | 1618 | struct intel_connector *intel_connector = intel_dp->attached_connector; |
1634 | struct intel_digital_connector_state *intel_conn_state = | 1619 | struct intel_digital_connector_state *intel_conn_state = |
@@ -1849,11 +1834,10 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp, | |||
1849 | static void intel_dp_prepare(struct intel_encoder *encoder, | 1834 | static void intel_dp_prepare(struct intel_encoder *encoder, |
1850 | const struct intel_crtc_state *pipe_config) | 1835 | const struct intel_crtc_state *pipe_config) |
1851 | { | 1836 | { |
1852 | struct drm_device *dev = encoder->base.dev; | 1837 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
1853 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
1854 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 1838 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
1855 | enum port port = dp_to_dig_port(intel_dp)->port; | 1839 | enum port port = encoder->port; |
1856 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); | 1840 | struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc); |
1857 | const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; | 1841 | const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; |
1858 | 1842 | ||
1859 | intel_dp_set_link_params(intel_dp, pipe_config->port_clock, | 1843 | intel_dp_set_link_params(intel_dp, pipe_config->port_clock, |
@@ -1940,20 +1924,18 @@ static void intel_dp_prepare(struct intel_encoder *encoder, | |||
1940 | #define IDLE_CYCLE_MASK (PP_ON | PP_SEQUENCE_MASK | PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK) | 1924 | #define IDLE_CYCLE_MASK (PP_ON | PP_SEQUENCE_MASK | PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK) |
1941 | #define IDLE_CYCLE_VALUE (0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_OFF_IDLE) | 1925 | #define IDLE_CYCLE_VALUE (0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_OFF_IDLE) |
1942 | 1926 | ||
1943 | static void intel_pps_verify_state(struct drm_i915_private *dev_priv, | 1927 | static void intel_pps_verify_state(struct intel_dp *intel_dp); |
1944 | struct intel_dp *intel_dp); | ||
1945 | 1928 | ||
1946 | static void wait_panel_status(struct intel_dp *intel_dp, | 1929 | static void wait_panel_status(struct intel_dp *intel_dp, |
1947 | u32 mask, | 1930 | u32 mask, |
1948 | u32 value) | 1931 | u32 value) |
1949 | { | 1932 | { |
1950 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 1933 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
1951 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
1952 | i915_reg_t pp_stat_reg, pp_ctrl_reg; | 1934 | i915_reg_t pp_stat_reg, pp_ctrl_reg; |
1953 | 1935 | ||
1954 | lockdep_assert_held(&dev_priv->pps_mutex); | 1936 | lockdep_assert_held(&dev_priv->pps_mutex); |
1955 | 1937 | ||
1956 | intel_pps_verify_state(dev_priv, intel_dp); | 1938 | intel_pps_verify_state(intel_dp); |
1957 | 1939 | ||
1958 | pp_stat_reg = _pp_stat_reg(intel_dp); | 1940 | pp_stat_reg = _pp_stat_reg(intel_dp); |
1959 | pp_ctrl_reg = _pp_ctrl_reg(intel_dp); | 1941 | pp_ctrl_reg = _pp_ctrl_reg(intel_dp); |
@@ -2024,8 +2006,7 @@ static void edp_wait_backlight_off(struct intel_dp *intel_dp) | |||
2024 | 2006 | ||
2025 | static u32 ironlake_get_pp_control(struct intel_dp *intel_dp) | 2007 | static u32 ironlake_get_pp_control(struct intel_dp *intel_dp) |
2026 | { | 2008 | { |
2027 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 2009 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
2028 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2029 | u32 control; | 2010 | u32 control; |
2030 | 2011 | ||
2031 | lockdep_assert_held(&dev_priv->pps_mutex); | 2012 | lockdep_assert_held(&dev_priv->pps_mutex); |
@@ -2046,9 +2027,8 @@ static u32 ironlake_get_pp_control(struct intel_dp *intel_dp) | |||
2046 | */ | 2027 | */ |
2047 | static bool edp_panel_vdd_on(struct intel_dp *intel_dp) | 2028 | static bool edp_panel_vdd_on(struct intel_dp *intel_dp) |
2048 | { | 2029 | { |
2049 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 2030 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
2050 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 2031 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
2051 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2052 | u32 pp; | 2032 | u32 pp; |
2053 | i915_reg_t pp_stat_reg, pp_ctrl_reg; | 2033 | i915_reg_t pp_stat_reg, pp_ctrl_reg; |
2054 | bool need_to_disable = !intel_dp->want_panel_vdd; | 2034 | bool need_to_disable = !intel_dp->want_panel_vdd; |
@@ -2067,7 +2047,7 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp) | |||
2067 | intel_display_power_get(dev_priv, intel_dp->aux_power_domain); | 2047 | intel_display_power_get(dev_priv, intel_dp->aux_power_domain); |
2068 | 2048 | ||
2069 | DRM_DEBUG_KMS("Turning eDP port %c VDD on\n", | 2049 | DRM_DEBUG_KMS("Turning eDP port %c VDD on\n", |
2070 | port_name(intel_dig_port->port)); | 2050 | port_name(intel_dig_port->base.port)); |
2071 | 2051 | ||
2072 | if (!edp_have_panel_power(intel_dp)) | 2052 | if (!edp_have_panel_power(intel_dp)) |
2073 | wait_panel_power_cycle(intel_dp); | 2053 | wait_panel_power_cycle(intel_dp); |
@@ -2087,7 +2067,7 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp) | |||
2087 | */ | 2067 | */ |
2088 | if (!edp_have_panel_power(intel_dp)) { | 2068 | if (!edp_have_panel_power(intel_dp)) { |
2089 | DRM_DEBUG_KMS("eDP port %c panel power wasn't enabled\n", | 2069 | DRM_DEBUG_KMS("eDP port %c panel power wasn't enabled\n", |
2090 | port_name(intel_dig_port->port)); | 2070 | port_name(intel_dig_port->base.port)); |
2091 | msleep(intel_dp->panel_power_up_delay); | 2071 | msleep(intel_dp->panel_power_up_delay); |
2092 | } | 2072 | } |
2093 | 2073 | ||
@@ -2113,13 +2093,12 @@ void intel_edp_panel_vdd_on(struct intel_dp *intel_dp) | |||
2113 | pps_unlock(intel_dp); | 2093 | pps_unlock(intel_dp); |
2114 | 2094 | ||
2115 | I915_STATE_WARN(!vdd, "eDP port %c VDD already requested on\n", | 2095 | I915_STATE_WARN(!vdd, "eDP port %c VDD already requested on\n", |
2116 | port_name(dp_to_dig_port(intel_dp)->port)); | 2096 | port_name(dp_to_dig_port(intel_dp)->base.port)); |
2117 | } | 2097 | } |
2118 | 2098 | ||
2119 | static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp) | 2099 | static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp) |
2120 | { | 2100 | { |
2121 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 2101 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
2122 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2123 | struct intel_digital_port *intel_dig_port = | 2102 | struct intel_digital_port *intel_dig_port = |
2124 | dp_to_dig_port(intel_dp); | 2103 | dp_to_dig_port(intel_dp); |
2125 | u32 pp; | 2104 | u32 pp; |
@@ -2133,7 +2112,7 @@ static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp) | |||
2133 | return; | 2112 | return; |
2134 | 2113 | ||
2135 | DRM_DEBUG_KMS("Turning eDP port %c VDD off\n", | 2114 | DRM_DEBUG_KMS("Turning eDP port %c VDD off\n", |
2136 | port_name(intel_dig_port->port)); | 2115 | port_name(intel_dig_port->base.port)); |
2137 | 2116 | ||
2138 | pp = ironlake_get_pp_control(intel_dp); | 2117 | pp = ironlake_get_pp_control(intel_dp); |
2139 | pp &= ~EDP_FORCE_VDD; | 2118 | pp &= ~EDP_FORCE_VDD; |
@@ -2193,7 +2172,7 @@ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) | |||
2193 | return; | 2172 | return; |
2194 | 2173 | ||
2195 | I915_STATE_WARN(!intel_dp->want_panel_vdd, "eDP port %c VDD not forced on", | 2174 | I915_STATE_WARN(!intel_dp->want_panel_vdd, "eDP port %c VDD not forced on", |
2196 | port_name(dp_to_dig_port(intel_dp)->port)); | 2175 | port_name(dp_to_dig_port(intel_dp)->base.port)); |
2197 | 2176 | ||
2198 | intel_dp->want_panel_vdd = false; | 2177 | intel_dp->want_panel_vdd = false; |
2199 | 2178 | ||
@@ -2205,8 +2184,7 @@ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) | |||
2205 | 2184 | ||
2206 | static void edp_panel_on(struct intel_dp *intel_dp) | 2185 | static void edp_panel_on(struct intel_dp *intel_dp) |
2207 | { | 2186 | { |
2208 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 2187 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
2209 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2210 | u32 pp; | 2188 | u32 pp; |
2211 | i915_reg_t pp_ctrl_reg; | 2189 | i915_reg_t pp_ctrl_reg; |
2212 | 2190 | ||
@@ -2216,11 +2194,11 @@ static void edp_panel_on(struct intel_dp *intel_dp) | |||
2216 | return; | 2194 | return; |
2217 | 2195 | ||
2218 | DRM_DEBUG_KMS("Turn eDP port %c panel power on\n", | 2196 | DRM_DEBUG_KMS("Turn eDP port %c panel power on\n", |
2219 | port_name(dp_to_dig_port(intel_dp)->port)); | 2197 | port_name(dp_to_dig_port(intel_dp)->base.port)); |
2220 | 2198 | ||
2221 | if (WARN(edp_have_panel_power(intel_dp), | 2199 | if (WARN(edp_have_panel_power(intel_dp), |
2222 | "eDP port %c panel power already on\n", | 2200 | "eDP port %c panel power already on\n", |
2223 | port_name(dp_to_dig_port(intel_dp)->port))) | 2201 | port_name(dp_to_dig_port(intel_dp)->base.port))) |
2224 | return; | 2202 | return; |
2225 | 2203 | ||
2226 | wait_panel_power_cycle(intel_dp); | 2204 | wait_panel_power_cycle(intel_dp); |
@@ -2264,8 +2242,7 @@ void intel_edp_panel_on(struct intel_dp *intel_dp) | |||
2264 | 2242 | ||
2265 | static void edp_panel_off(struct intel_dp *intel_dp) | 2243 | static void edp_panel_off(struct intel_dp *intel_dp) |
2266 | { | 2244 | { |
2267 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 2245 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
2268 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2269 | u32 pp; | 2246 | u32 pp; |
2270 | i915_reg_t pp_ctrl_reg; | 2247 | i915_reg_t pp_ctrl_reg; |
2271 | 2248 | ||
@@ -2275,10 +2252,10 @@ static void edp_panel_off(struct intel_dp *intel_dp) | |||
2275 | return; | 2252 | return; |
2276 | 2253 | ||
2277 | DRM_DEBUG_KMS("Turn eDP port %c panel power off\n", | 2254 | DRM_DEBUG_KMS("Turn eDP port %c panel power off\n", |
2278 | port_name(dp_to_dig_port(intel_dp)->port)); | 2255 | port_name(dp_to_dig_port(intel_dp)->base.port)); |
2279 | 2256 | ||
2280 | WARN(!intel_dp->want_panel_vdd, "Need eDP port %c VDD to turn off panel\n", | 2257 | WARN(!intel_dp->want_panel_vdd, "Need eDP port %c VDD to turn off panel\n", |
2281 | port_name(dp_to_dig_port(intel_dp)->port)); | 2258 | port_name(dp_to_dig_port(intel_dp)->base.port)); |
2282 | 2259 | ||
2283 | pp = ironlake_get_pp_control(intel_dp); | 2260 | pp = ironlake_get_pp_control(intel_dp); |
2284 | /* We need to switch off panel power _and_ force vdd, for otherwise some | 2261 | /* We need to switch off panel power _and_ force vdd, for otherwise some |
@@ -2313,9 +2290,7 @@ void intel_edp_panel_off(struct intel_dp *intel_dp) | |||
2313 | /* Enable backlight in the panel power control. */ | 2290 | /* Enable backlight in the panel power control. */ |
2314 | static void _intel_edp_backlight_on(struct intel_dp *intel_dp) | 2291 | static void _intel_edp_backlight_on(struct intel_dp *intel_dp) |
2315 | { | 2292 | { |
2316 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 2293 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
2317 | struct drm_device *dev = intel_dig_port->base.base.dev; | ||
2318 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2319 | u32 pp; | 2294 | u32 pp; |
2320 | i915_reg_t pp_ctrl_reg; | 2295 | i915_reg_t pp_ctrl_reg; |
2321 | 2296 | ||
@@ -2358,8 +2333,7 @@ void intel_edp_backlight_on(const struct intel_crtc_state *crtc_state, | |||
2358 | /* Disable backlight in the panel power control. */ | 2333 | /* Disable backlight in the panel power control. */ |
2359 | static void _intel_edp_backlight_off(struct intel_dp *intel_dp) | 2334 | static void _intel_edp_backlight_off(struct intel_dp *intel_dp) |
2360 | { | 2335 | { |
2361 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 2336 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
2362 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2363 | u32 pp; | 2337 | u32 pp; |
2364 | i915_reg_t pp_ctrl_reg; | 2338 | i915_reg_t pp_ctrl_reg; |
2365 | 2339 | ||
@@ -2430,7 +2404,7 @@ static void assert_dp_port(struct intel_dp *intel_dp, bool state) | |||
2430 | 2404 | ||
2431 | I915_STATE_WARN(cur_state != state, | 2405 | I915_STATE_WARN(cur_state != state, |
2432 | "DP port %c state assertion failure (expected %s, current %s)\n", | 2406 | "DP port %c state assertion failure (expected %s, current %s)\n", |
2433 | port_name(dig_port->port), | 2407 | port_name(dig_port->base.port), |
2434 | onoff(state), onoff(cur_state)); | 2408 | onoff(state), onoff(cur_state)); |
2435 | } | 2409 | } |
2436 | #define assert_dp_port_disabled(d) assert_dp_port((d), false) | 2410 | #define assert_dp_port_disabled(d) assert_dp_port((d), false) |
@@ -2486,10 +2460,10 @@ static void ironlake_edp_pll_on(struct intel_dp *intel_dp, | |||
2486 | udelay(200); | 2460 | udelay(200); |
2487 | } | 2461 | } |
2488 | 2462 | ||
2489 | static void ironlake_edp_pll_off(struct intel_dp *intel_dp) | 2463 | static void ironlake_edp_pll_off(struct intel_dp *intel_dp, |
2464 | const struct intel_crtc_state *old_crtc_state) | ||
2490 | { | 2465 | { |
2491 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 2466 | struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); |
2492 | struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc); | ||
2493 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); | 2467 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
2494 | 2468 | ||
2495 | assert_pipe_disabled(dev_priv, crtc->pipe); | 2469 | assert_pipe_disabled(dev_priv, crtc->pipe); |
@@ -2505,6 +2479,21 @@ static void ironlake_edp_pll_off(struct intel_dp *intel_dp) | |||
2505 | udelay(200); | 2479 | udelay(200); |
2506 | } | 2480 | } |
2507 | 2481 | ||
2482 | static bool downstream_hpd_needs_d0(struct intel_dp *intel_dp) | ||
2483 | { | ||
2484 | /* | ||
2485 | * DPCD 1.2+ should support BRANCH_DEVICE_CTRL, and thus | ||
2486 | * be capable of signalling downstream hpd with a long pulse. | ||
2487 | * Whether or not that means D3 is safe to use is not clear, | ||
2488 | * but let's assume so until proven otherwise. | ||
2489 | * | ||
2490 | * FIXME should really check all downstream ports... | ||
2491 | */ | ||
2492 | return intel_dp->dpcd[DP_DPCD_REV] == 0x11 && | ||
2493 | intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT && | ||
2494 | intel_dp->downstream_ports[0] & DP_DS_PORT_HPD; | ||
2495 | } | ||
2496 | |||
2508 | /* If the sink supports it, try to set the power state appropriately */ | 2497 | /* If the sink supports it, try to set the power state appropriately */ |
2509 | void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode) | 2498 | void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode) |
2510 | { | 2499 | { |
@@ -2515,6 +2504,9 @@ void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode) | |||
2515 | return; | 2504 | return; |
2516 | 2505 | ||
2517 | if (mode != DRM_MODE_DPMS_ON) { | 2506 | if (mode != DRM_MODE_DPMS_ON) { |
2507 | if (downstream_hpd_needs_d0(intel_dp)) | ||
2508 | return; | ||
2509 | |||
2518 | ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, | 2510 | ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, |
2519 | DP_SET_POWER_D3); | 2511 | DP_SET_POWER_D3); |
2520 | } else { | 2512 | } else { |
@@ -2544,10 +2536,9 @@ void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode) | |||
2544 | static bool intel_dp_get_hw_state(struct intel_encoder *encoder, | 2536 | static bool intel_dp_get_hw_state(struct intel_encoder *encoder, |
2545 | enum pipe *pipe) | 2537 | enum pipe *pipe) |
2546 | { | 2538 | { |
2539 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | ||
2547 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 2540 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
2548 | enum port port = dp_to_dig_port(intel_dp)->port; | 2541 | enum port port = encoder->port; |
2549 | struct drm_device *dev = encoder->base.dev; | ||
2550 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2551 | u32 tmp; | 2542 | u32 tmp; |
2552 | bool ret; | 2543 | bool ret; |
2553 | 2544 | ||
@@ -2596,12 +2587,16 @@ out: | |||
2596 | static void intel_dp_get_config(struct intel_encoder *encoder, | 2587 | static void intel_dp_get_config(struct intel_encoder *encoder, |
2597 | struct intel_crtc_state *pipe_config) | 2588 | struct intel_crtc_state *pipe_config) |
2598 | { | 2589 | { |
2590 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | ||
2599 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 2591 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
2600 | u32 tmp, flags = 0; | 2592 | u32 tmp, flags = 0; |
2601 | struct drm_device *dev = encoder->base.dev; | 2593 | enum port port = encoder->port; |
2602 | struct drm_i915_private *dev_priv = to_i915(dev); | 2594 | struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc); |
2603 | enum port port = dp_to_dig_port(intel_dp)->port; | 2595 | |
2604 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); | 2596 | if (encoder->type == INTEL_OUTPUT_EDP) |
2597 | pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); | ||
2598 | else | ||
2599 | pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); | ||
2605 | 2600 | ||
2606 | tmp = I915_READ(intel_dp->output_reg); | 2601 | tmp = I915_READ(intel_dp->output_reg); |
2607 | 2602 | ||
@@ -2680,7 +2675,8 @@ static void intel_disable_dp(struct intel_encoder *encoder, | |||
2680 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 2675 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
2681 | 2676 | ||
2682 | if (old_crtc_state->has_audio) | 2677 | if (old_crtc_state->has_audio) |
2683 | intel_audio_codec_disable(encoder); | 2678 | intel_audio_codec_disable(encoder, |
2679 | old_crtc_state, old_conn_state); | ||
2684 | 2680 | ||
2685 | /* Make sure the panel is off before trying to change the mode. But also | 2681 | /* Make sure the panel is off before trying to change the mode. But also |
2686 | * ensure that we have vdd while we switch off the panel. */ | 2682 | * ensure that we have vdd while we switch off the panel. */ |
@@ -2694,12 +2690,10 @@ static void g4x_disable_dp(struct intel_encoder *encoder, | |||
2694 | const struct intel_crtc_state *old_crtc_state, | 2690 | const struct intel_crtc_state *old_crtc_state, |
2695 | const struct drm_connector_state *old_conn_state) | 2691 | const struct drm_connector_state *old_conn_state) |
2696 | { | 2692 | { |
2697 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | ||
2698 | |||
2699 | intel_disable_dp(encoder, old_crtc_state, old_conn_state); | 2693 | intel_disable_dp(encoder, old_crtc_state, old_conn_state); |
2700 | 2694 | ||
2701 | /* disable the port before the pipe on g4x */ | 2695 | /* disable the port before the pipe on g4x */ |
2702 | intel_dp_link_down(intel_dp); | 2696 | intel_dp_link_down(encoder, old_crtc_state); |
2703 | } | 2697 | } |
2704 | 2698 | ||
2705 | static void ilk_disable_dp(struct intel_encoder *encoder, | 2699 | static void ilk_disable_dp(struct intel_encoder *encoder, |
@@ -2725,38 +2719,34 @@ static void ilk_post_disable_dp(struct intel_encoder *encoder, | |||
2725 | const struct drm_connector_state *old_conn_state) | 2719 | const struct drm_connector_state *old_conn_state) |
2726 | { | 2720 | { |
2727 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 2721 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
2728 | enum port port = dp_to_dig_port(intel_dp)->port; | 2722 | enum port port = encoder->port; |
2729 | 2723 | ||
2730 | intel_dp_link_down(intel_dp); | 2724 | intel_dp_link_down(encoder, old_crtc_state); |
2731 | 2725 | ||
2732 | /* Only ilk+ has port A */ | 2726 | /* Only ilk+ has port A */ |
2733 | if (port == PORT_A) | 2727 | if (port == PORT_A) |
2734 | ironlake_edp_pll_off(intel_dp); | 2728 | ironlake_edp_pll_off(intel_dp, old_crtc_state); |
2735 | } | 2729 | } |
2736 | 2730 | ||
2737 | static void vlv_post_disable_dp(struct intel_encoder *encoder, | 2731 | static void vlv_post_disable_dp(struct intel_encoder *encoder, |
2738 | const struct intel_crtc_state *old_crtc_state, | 2732 | const struct intel_crtc_state *old_crtc_state, |
2739 | const struct drm_connector_state *old_conn_state) | 2733 | const struct drm_connector_state *old_conn_state) |
2740 | { | 2734 | { |
2741 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 2735 | intel_dp_link_down(encoder, old_crtc_state); |
2742 | |||
2743 | intel_dp_link_down(intel_dp); | ||
2744 | } | 2736 | } |
2745 | 2737 | ||
2746 | static void chv_post_disable_dp(struct intel_encoder *encoder, | 2738 | static void chv_post_disable_dp(struct intel_encoder *encoder, |
2747 | const struct intel_crtc_state *old_crtc_state, | 2739 | const struct intel_crtc_state *old_crtc_state, |
2748 | const struct drm_connector_state *old_conn_state) | 2740 | const struct drm_connector_state *old_conn_state) |
2749 | { | 2741 | { |
2750 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 2742 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
2751 | struct drm_device *dev = encoder->base.dev; | ||
2752 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2753 | 2743 | ||
2754 | intel_dp_link_down(intel_dp); | 2744 | intel_dp_link_down(encoder, old_crtc_state); |
2755 | 2745 | ||
2756 | mutex_lock(&dev_priv->sb_lock); | 2746 | mutex_lock(&dev_priv->sb_lock); |
2757 | 2747 | ||
2758 | /* Assert data lane reset */ | 2748 | /* Assert data lane reset */ |
2759 | chv_data_lane_soft_reset(encoder, true); | 2749 | chv_data_lane_soft_reset(encoder, old_crtc_state, true); |
2760 | 2750 | ||
2761 | mutex_unlock(&dev_priv->sb_lock); | 2751 | mutex_unlock(&dev_priv->sb_lock); |
2762 | } | 2752 | } |
@@ -2766,10 +2756,9 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp, | |||
2766 | uint32_t *DP, | 2756 | uint32_t *DP, |
2767 | uint8_t dp_train_pat) | 2757 | uint8_t dp_train_pat) |
2768 | { | 2758 | { |
2759 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | ||
2769 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 2760 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
2770 | struct drm_device *dev = intel_dig_port->base.base.dev; | 2761 | enum port port = intel_dig_port->base.port; |
2771 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2772 | enum port port = intel_dig_port->port; | ||
2773 | 2762 | ||
2774 | if (dp_train_pat & DP_TRAINING_PATTERN_MASK) | 2763 | if (dp_train_pat & DP_TRAINING_PATTERN_MASK) |
2775 | DRM_DEBUG_KMS("Using DP training pattern TPS%d\n", | 2764 | DRM_DEBUG_KMS("Using DP training pattern TPS%d\n", |
@@ -2852,8 +2841,7 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp, | |||
2852 | static void intel_dp_enable_port(struct intel_dp *intel_dp, | 2841 | static void intel_dp_enable_port(struct intel_dp *intel_dp, |
2853 | const struct intel_crtc_state *old_crtc_state) | 2842 | const struct intel_crtc_state *old_crtc_state) |
2854 | { | 2843 | { |
2855 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 2844 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
2856 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2857 | 2845 | ||
2858 | /* enable with pattern 1 (as per spec) */ | 2846 | /* enable with pattern 1 (as per spec) */ |
2859 | 2847 | ||
@@ -2877,10 +2865,9 @@ static void intel_enable_dp(struct intel_encoder *encoder, | |||
2877 | const struct intel_crtc_state *pipe_config, | 2865 | const struct intel_crtc_state *pipe_config, |
2878 | const struct drm_connector_state *conn_state) | 2866 | const struct drm_connector_state *conn_state) |
2879 | { | 2867 | { |
2868 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | ||
2880 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 2869 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
2881 | struct drm_device *dev = encoder->base.dev; | 2870 | struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc); |
2882 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2883 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); | ||
2884 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); | 2871 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); |
2885 | enum pipe pipe = crtc->pipe; | 2872 | enum pipe pipe = crtc->pipe; |
2886 | 2873 | ||
@@ -2890,7 +2877,7 @@ static void intel_enable_dp(struct intel_encoder *encoder, | |||
2890 | pps_lock(intel_dp); | 2877 | pps_lock(intel_dp); |
2891 | 2878 | ||
2892 | if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) | 2879 | if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) |
2893 | vlv_init_panel_power_sequencer(intel_dp); | 2880 | vlv_init_panel_power_sequencer(encoder, pipe_config); |
2894 | 2881 | ||
2895 | intel_dp_enable_port(intel_dp, pipe_config); | 2882 | intel_dp_enable_port(intel_dp, pipe_config); |
2896 | 2883 | ||
@@ -2944,7 +2931,7 @@ static void g4x_pre_enable_dp(struct intel_encoder *encoder, | |||
2944 | const struct drm_connector_state *conn_state) | 2931 | const struct drm_connector_state *conn_state) |
2945 | { | 2932 | { |
2946 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 2933 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
2947 | enum port port = dp_to_dig_port(intel_dp)->port; | 2934 | enum port port = encoder->port; |
2948 | 2935 | ||
2949 | intel_dp_prepare(encoder, pipe_config); | 2936 | intel_dp_prepare(encoder, pipe_config); |
2950 | 2937 | ||
@@ -2977,22 +2964,21 @@ static void vlv_detach_power_sequencer(struct intel_dp *intel_dp) | |||
2977 | * from a port. | 2964 | * from a port. |
2978 | */ | 2965 | */ |
2979 | DRM_DEBUG_KMS("detaching pipe %c power sequencer from port %c\n", | 2966 | DRM_DEBUG_KMS("detaching pipe %c power sequencer from port %c\n", |
2980 | pipe_name(pipe), port_name(intel_dig_port->port)); | 2967 | pipe_name(pipe), port_name(intel_dig_port->base.port)); |
2981 | I915_WRITE(pp_on_reg, 0); | 2968 | I915_WRITE(pp_on_reg, 0); |
2982 | POSTING_READ(pp_on_reg); | 2969 | POSTING_READ(pp_on_reg); |
2983 | 2970 | ||
2984 | intel_dp->pps_pipe = INVALID_PIPE; | 2971 | intel_dp->pps_pipe = INVALID_PIPE; |
2985 | } | 2972 | } |
2986 | 2973 | ||
2987 | static void vlv_steal_power_sequencer(struct drm_device *dev, | 2974 | static void vlv_steal_power_sequencer(struct drm_i915_private *dev_priv, |
2988 | enum pipe pipe) | 2975 | enum pipe pipe) |
2989 | { | 2976 | { |
2990 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2991 | struct intel_encoder *encoder; | 2977 | struct intel_encoder *encoder; |
2992 | 2978 | ||
2993 | lockdep_assert_held(&dev_priv->pps_mutex); | 2979 | lockdep_assert_held(&dev_priv->pps_mutex); |
2994 | 2980 | ||
2995 | for_each_intel_encoder(dev, encoder) { | 2981 | for_each_intel_encoder(&dev_priv->drm, encoder) { |
2996 | struct intel_dp *intel_dp; | 2982 | struct intel_dp *intel_dp; |
2997 | enum port port; | 2983 | enum port port; |
2998 | 2984 | ||
@@ -3001,7 +2987,7 @@ static void vlv_steal_power_sequencer(struct drm_device *dev, | |||
3001 | continue; | 2987 | continue; |
3002 | 2988 | ||
3003 | intel_dp = enc_to_intel_dp(&encoder->base); | 2989 | intel_dp = enc_to_intel_dp(&encoder->base); |
3004 | port = dp_to_dig_port(intel_dp)->port; | 2990 | port = dp_to_dig_port(intel_dp)->base.port; |
3005 | 2991 | ||
3006 | WARN(intel_dp->active_pipe == pipe, | 2992 | WARN(intel_dp->active_pipe == pipe, |
3007 | "stealing pipe %c power sequencer from active (e)DP port %c\n", | 2993 | "stealing pipe %c power sequencer from active (e)DP port %c\n", |
@@ -3018,13 +3004,12 @@ static void vlv_steal_power_sequencer(struct drm_device *dev, | |||
3018 | } | 3004 | } |
3019 | } | 3005 | } |
3020 | 3006 | ||
3021 | static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp) | 3007 | static void vlv_init_panel_power_sequencer(struct intel_encoder *encoder, |
3008 | const struct intel_crtc_state *crtc_state) | ||
3022 | { | 3009 | { |
3023 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 3010 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
3024 | struct intel_encoder *encoder = &intel_dig_port->base; | 3011 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
3025 | struct drm_device *dev = encoder->base.dev; | 3012 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
3026 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
3027 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); | ||
3028 | 3013 | ||
3029 | lockdep_assert_held(&dev_priv->pps_mutex); | 3014 | lockdep_assert_held(&dev_priv->pps_mutex); |
3030 | 3015 | ||
@@ -3044,7 +3029,7 @@ static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp) | |||
3044 | * We may be stealing the power | 3029 | * We may be stealing the power |
3045 | * sequencer from another port. | 3030 | * sequencer from another port. |
3046 | */ | 3031 | */ |
3047 | vlv_steal_power_sequencer(dev, crtc->pipe); | 3032 | vlv_steal_power_sequencer(dev_priv, crtc->pipe); |
3048 | 3033 | ||
3049 | intel_dp->active_pipe = crtc->pipe; | 3034 | intel_dp->active_pipe = crtc->pipe; |
3050 | 3035 | ||
@@ -3055,18 +3040,18 @@ static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp) | |||
3055 | intel_dp->pps_pipe = crtc->pipe; | 3040 | intel_dp->pps_pipe = crtc->pipe; |
3056 | 3041 | ||
3057 | DRM_DEBUG_KMS("initializing pipe %c power sequencer for port %c\n", | 3042 | DRM_DEBUG_KMS("initializing pipe %c power sequencer for port %c\n", |
3058 | pipe_name(intel_dp->pps_pipe), port_name(intel_dig_port->port)); | 3043 | pipe_name(intel_dp->pps_pipe), port_name(encoder->port)); |
3059 | 3044 | ||
3060 | /* init power sequencer on this pipe and port */ | 3045 | /* init power sequencer on this pipe and port */ |
3061 | intel_dp_init_panel_power_sequencer(dev, intel_dp); | 3046 | intel_dp_init_panel_power_sequencer(intel_dp); |
3062 | intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, true); | 3047 | intel_dp_init_panel_power_sequencer_registers(intel_dp, true); |
3063 | } | 3048 | } |
3064 | 3049 | ||
3065 | static void vlv_pre_enable_dp(struct intel_encoder *encoder, | 3050 | static void vlv_pre_enable_dp(struct intel_encoder *encoder, |
3066 | const struct intel_crtc_state *pipe_config, | 3051 | const struct intel_crtc_state *pipe_config, |
3067 | const struct drm_connector_state *conn_state) | 3052 | const struct drm_connector_state *conn_state) |
3068 | { | 3053 | { |
3069 | vlv_phy_pre_encoder_enable(encoder); | 3054 | vlv_phy_pre_encoder_enable(encoder, pipe_config); |
3070 | 3055 | ||
3071 | intel_enable_dp(encoder, pipe_config, conn_state); | 3056 | intel_enable_dp(encoder, pipe_config, conn_state); |
3072 | } | 3057 | } |
@@ -3077,14 +3062,14 @@ static void vlv_dp_pre_pll_enable(struct intel_encoder *encoder, | |||
3077 | { | 3062 | { |
3078 | intel_dp_prepare(encoder, pipe_config); | 3063 | intel_dp_prepare(encoder, pipe_config); |
3079 | 3064 | ||
3080 | vlv_phy_pre_pll_enable(encoder); | 3065 | vlv_phy_pre_pll_enable(encoder, pipe_config); |
3081 | } | 3066 | } |
3082 | 3067 | ||
3083 | static void chv_pre_enable_dp(struct intel_encoder *encoder, | 3068 | static void chv_pre_enable_dp(struct intel_encoder *encoder, |
3084 | const struct intel_crtc_state *pipe_config, | 3069 | const struct intel_crtc_state *pipe_config, |
3085 | const struct drm_connector_state *conn_state) | 3070 | const struct drm_connector_state *conn_state) |
3086 | { | 3071 | { |
3087 | chv_phy_pre_encoder_enable(encoder); | 3072 | chv_phy_pre_encoder_enable(encoder, pipe_config); |
3088 | 3073 | ||
3089 | intel_enable_dp(encoder, pipe_config, conn_state); | 3074 | intel_enable_dp(encoder, pipe_config, conn_state); |
3090 | 3075 | ||
@@ -3098,14 +3083,14 @@ static void chv_dp_pre_pll_enable(struct intel_encoder *encoder, | |||
3098 | { | 3083 | { |
3099 | intel_dp_prepare(encoder, pipe_config); | 3084 | intel_dp_prepare(encoder, pipe_config); |
3100 | 3085 | ||
3101 | chv_phy_pre_pll_enable(encoder); | 3086 | chv_phy_pre_pll_enable(encoder, pipe_config); |
3102 | } | 3087 | } |
3103 | 3088 | ||
3104 | static void chv_dp_post_pll_disable(struct intel_encoder *encoder, | 3089 | static void chv_dp_post_pll_disable(struct intel_encoder *encoder, |
3105 | const struct intel_crtc_state *pipe_config, | 3090 | const struct intel_crtc_state *old_crtc_state, |
3106 | const struct drm_connector_state *conn_state) | 3091 | const struct drm_connector_state *old_conn_state) |
3107 | { | 3092 | { |
3108 | chv_phy_post_pll_disable(encoder); | 3093 | chv_phy_post_pll_disable(encoder, old_crtc_state); |
3109 | } | 3094 | } |
3110 | 3095 | ||
3111 | /* | 3096 | /* |
@@ -3153,7 +3138,7 @@ uint8_t | |||
3153 | intel_dp_voltage_max(struct intel_dp *intel_dp) | 3138 | intel_dp_voltage_max(struct intel_dp *intel_dp) |
3154 | { | 3139 | { |
3155 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | 3140 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
3156 | enum port port = dp_to_dig_port(intel_dp)->port; | 3141 | enum port port = dp_to_dig_port(intel_dp)->base.port; |
3157 | 3142 | ||
3158 | if (INTEL_GEN(dev_priv) >= 9) { | 3143 | if (INTEL_GEN(dev_priv) >= 9) { |
3159 | struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; | 3144 | struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; |
@@ -3172,7 +3157,7 @@ uint8_t | |||
3172 | intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing) | 3157 | intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing) |
3173 | { | 3158 | { |
3174 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | 3159 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
3175 | enum port port = dp_to_dig_port(intel_dp)->port; | 3160 | enum port port = dp_to_dig_port(intel_dp)->base.port; |
3176 | 3161 | ||
3177 | if (INTEL_GEN(dev_priv) >= 9) { | 3162 | if (INTEL_GEN(dev_priv) >= 9) { |
3178 | switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { | 3163 | switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { |
@@ -3505,10 +3490,9 @@ gen7_edp_signal_levels(uint8_t train_set) | |||
3505 | void | 3490 | void |
3506 | intel_dp_set_signal_levels(struct intel_dp *intel_dp) | 3491 | intel_dp_set_signal_levels(struct intel_dp *intel_dp) |
3507 | { | 3492 | { |
3493 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | ||
3508 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 3494 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
3509 | enum port port = intel_dig_port->port; | 3495 | enum port port = intel_dig_port->base.port; |
3510 | struct drm_device *dev = intel_dig_port->base.base.dev; | ||
3511 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
3512 | uint32_t signal_levels, mask = 0; | 3496 | uint32_t signal_levels, mask = 0; |
3513 | uint8_t train_set = intel_dp->train_set[0]; | 3497 | uint8_t train_set = intel_dp->train_set[0]; |
3514 | 3498 | ||
@@ -3563,10 +3547,9 @@ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, | |||
3563 | 3547 | ||
3564 | void intel_dp_set_idle_link_train(struct intel_dp *intel_dp) | 3548 | void intel_dp_set_idle_link_train(struct intel_dp *intel_dp) |
3565 | { | 3549 | { |
3550 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | ||
3566 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 3551 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
3567 | struct drm_device *dev = intel_dig_port->base.base.dev; | 3552 | enum port port = intel_dig_port->base.port; |
3568 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
3569 | enum port port = intel_dig_port->port; | ||
3570 | uint32_t val; | 3553 | uint32_t val; |
3571 | 3554 | ||
3572 | if (!HAS_DDI(dev_priv)) | 3555 | if (!HAS_DDI(dev_priv)) |
@@ -3595,13 +3578,13 @@ void intel_dp_set_idle_link_train(struct intel_dp *intel_dp) | |||
3595 | } | 3578 | } |
3596 | 3579 | ||
3597 | static void | 3580 | static void |
3598 | intel_dp_link_down(struct intel_dp *intel_dp) | 3581 | intel_dp_link_down(struct intel_encoder *encoder, |
3582 | const struct intel_crtc_state *old_crtc_state) | ||
3599 | { | 3583 | { |
3600 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 3584 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
3601 | struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc); | 3585 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
3602 | enum port port = intel_dig_port->port; | 3586 | struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); |
3603 | struct drm_device *dev = intel_dig_port->base.base.dev; | 3587 | enum port port = encoder->port; |
3604 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
3605 | uint32_t DP = intel_dp->DP; | 3588 | uint32_t DP = intel_dp->DP; |
3606 | 3589 | ||
3607 | if (WARN_ON(HAS_DDI(dev_priv))) | 3590 | if (WARN_ON(HAS_DDI(dev_priv))) |
@@ -3747,11 +3730,11 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp) | |||
3747 | if (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_DPCD_REV, | 3730 | if (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_DPCD_REV, |
3748 | intel_dp->edp_dpcd, sizeof(intel_dp->edp_dpcd)) == | 3731 | intel_dp->edp_dpcd, sizeof(intel_dp->edp_dpcd)) == |
3749 | sizeof(intel_dp->edp_dpcd)) | 3732 | sizeof(intel_dp->edp_dpcd)) |
3750 | DRM_DEBUG_KMS("EDP DPCD : %*ph\n", (int) sizeof(intel_dp->edp_dpcd), | 3733 | DRM_DEBUG_KMS("eDP DPCD: %*ph\n", (int) sizeof(intel_dp->edp_dpcd), |
3751 | intel_dp->edp_dpcd); | 3734 | intel_dp->edp_dpcd); |
3752 | 3735 | ||
3753 | /* Intermediate frequency support */ | 3736 | /* Read the eDP 1.4+ supported link rates. */ |
3754 | if (intel_dp->edp_dpcd[0] >= 0x03) { /* eDp v1.4 or higher */ | 3737 | if (intel_dp->edp_dpcd[0] >= DP_EDP_14) { |
3755 | __le16 sink_rates[DP_MAX_SUPPORTED_RATES]; | 3738 | __le16 sink_rates[DP_MAX_SUPPORTED_RATES]; |
3756 | int i; | 3739 | int i; |
3757 | 3740 | ||
@@ -3775,6 +3758,10 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp) | |||
3775 | intel_dp->num_sink_rates = i; | 3758 | intel_dp->num_sink_rates = i; |
3776 | } | 3759 | } |
3777 | 3760 | ||
3761 | /* | ||
3762 | * Use DP_LINK_RATE_SET if DP_SUPPORTED_LINK_RATES are available, | ||
3763 | * default to DP_MAX_LINK_RATE and DP_LINK_BW_SET otherwise. | ||
3764 | */ | ||
3778 | if (intel_dp->num_sink_rates) | 3765 | if (intel_dp->num_sink_rates) |
3779 | intel_dp->use_rate_select = true; | 3766 | intel_dp->use_rate_select = true; |
3780 | else | 3767 | else |
@@ -3874,11 +3861,12 @@ intel_dp_configure_mst(struct intel_dp *intel_dp) | |||
3874 | intel_dp->is_mst); | 3861 | intel_dp->is_mst); |
3875 | } | 3862 | } |
3876 | 3863 | ||
3877 | static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp) | 3864 | static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp, |
3865 | struct intel_crtc_state *crtc_state, bool disable_wa) | ||
3878 | { | 3866 | { |
3879 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | 3867 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
3880 | struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); | 3868 | struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); |
3881 | struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc); | 3869 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc); |
3882 | u8 buf; | 3870 | u8 buf; |
3883 | int ret = 0; | 3871 | int ret = 0; |
3884 | int count = 0; | 3872 | int count = 0; |
@@ -3914,15 +3902,17 @@ static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp) | |||
3914 | } | 3902 | } |
3915 | 3903 | ||
3916 | out: | 3904 | out: |
3917 | hsw_enable_ips(intel_crtc); | 3905 | if (disable_wa) |
3906 | hsw_enable_ips(crtc_state); | ||
3918 | return ret; | 3907 | return ret; |
3919 | } | 3908 | } |
3920 | 3909 | ||
3921 | static int intel_dp_sink_crc_start(struct intel_dp *intel_dp) | 3910 | static int intel_dp_sink_crc_start(struct intel_dp *intel_dp, |
3911 | struct intel_crtc_state *crtc_state) | ||
3922 | { | 3912 | { |
3923 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | 3913 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
3924 | struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); | 3914 | struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); |
3925 | struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc); | 3915 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc); |
3926 | u8 buf; | 3916 | u8 buf; |
3927 | int ret; | 3917 | int ret; |
3928 | 3918 | ||
@@ -3936,16 +3926,16 @@ static int intel_dp_sink_crc_start(struct intel_dp *intel_dp) | |||
3936 | return -EIO; | 3926 | return -EIO; |
3937 | 3927 | ||
3938 | if (buf & DP_TEST_SINK_START) { | 3928 | if (buf & DP_TEST_SINK_START) { |
3939 | ret = intel_dp_sink_crc_stop(intel_dp); | 3929 | ret = intel_dp_sink_crc_stop(intel_dp, crtc_state, false); |
3940 | if (ret) | 3930 | if (ret) |
3941 | return ret; | 3931 | return ret; |
3942 | } | 3932 | } |
3943 | 3933 | ||
3944 | hsw_disable_ips(intel_crtc); | 3934 | hsw_disable_ips(crtc_state); |
3945 | 3935 | ||
3946 | if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, | 3936 | if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, |
3947 | buf | DP_TEST_SINK_START) < 0) { | 3937 | buf | DP_TEST_SINK_START) < 0) { |
3948 | hsw_enable_ips(intel_crtc); | 3938 | hsw_enable_ips(crtc_state); |
3949 | return -EIO; | 3939 | return -EIO; |
3950 | } | 3940 | } |
3951 | 3941 | ||
@@ -3953,16 +3943,16 @@ static int intel_dp_sink_crc_start(struct intel_dp *intel_dp) | |||
3953 | return 0; | 3943 | return 0; |
3954 | } | 3944 | } |
3955 | 3945 | ||
3956 | int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) | 3946 | int intel_dp_sink_crc(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, u8 *crc) |
3957 | { | 3947 | { |
3958 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | 3948 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
3959 | struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); | 3949 | struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); |
3960 | struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc); | 3950 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc); |
3961 | u8 buf; | 3951 | u8 buf; |
3962 | int count, ret; | 3952 | int count, ret; |
3963 | int attempts = 6; | 3953 | int attempts = 6; |
3964 | 3954 | ||
3965 | ret = intel_dp_sink_crc_start(intel_dp); | 3955 | ret = intel_dp_sink_crc_start(intel_dp, crtc_state); |
3966 | if (ret) | 3956 | if (ret) |
3967 | return ret; | 3957 | return ret; |
3968 | 3958 | ||
@@ -3990,7 +3980,7 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) | |||
3990 | } | 3980 | } |
3991 | 3981 | ||
3992 | stop: | 3982 | stop: |
3993 | intel_dp_sink_crc_stop(intel_dp); | 3983 | intel_dp_sink_crc_stop(intel_dp, crtc_state, true); |
3994 | return ret; | 3984 | return ret; |
3995 | } | 3985 | } |
3996 | 3986 | ||
@@ -4285,11 +4275,11 @@ intel_dp_retrain_link(struct intel_dp *intel_dp) | |||
4285 | static void | 4275 | static void |
4286 | intel_dp_check_link_status(struct intel_dp *intel_dp) | 4276 | intel_dp_check_link_status(struct intel_dp *intel_dp) |
4287 | { | 4277 | { |
4278 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | ||
4288 | struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; | 4279 | struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; |
4289 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | ||
4290 | u8 link_status[DP_LINK_STATUS_SIZE]; | 4280 | u8 link_status[DP_LINK_STATUS_SIZE]; |
4291 | 4281 | ||
4292 | WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); | 4282 | WARN_ON(!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex)); |
4293 | 4283 | ||
4294 | if (!intel_dp_get_link_status(intel_dp, link_status)) { | 4284 | if (!intel_dp_get_link_status(intel_dp, link_status)) { |
4295 | DRM_ERROR("Failed to get link status\n"); | 4285 | DRM_ERROR("Failed to get link status\n"); |
@@ -4335,8 +4325,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
4335 | static bool | 4325 | static bool |
4336 | intel_dp_short_pulse(struct intel_dp *intel_dp) | 4326 | intel_dp_short_pulse(struct intel_dp *intel_dp) |
4337 | { | 4327 | { |
4338 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 4328 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
4339 | struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; | ||
4340 | u8 sink_irq_vector = 0; | 4329 | u8 sink_irq_vector = 0; |
4341 | u8 old_sink_count = intel_dp->sink_count; | 4330 | u8 old_sink_count = intel_dp->sink_count; |
4342 | bool ret; | 4331 | bool ret; |
@@ -4375,13 +4364,13 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) | |||
4375 | DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); | 4364 | DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); |
4376 | } | 4365 | } |
4377 | 4366 | ||
4378 | drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); | 4367 | drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex, NULL); |
4379 | intel_dp_check_link_status(intel_dp); | 4368 | intel_dp_check_link_status(intel_dp); |
4380 | drm_modeset_unlock(&dev->mode_config.connection_mutex); | 4369 | drm_modeset_unlock(&dev_priv->drm.mode_config.connection_mutex); |
4381 | if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) { | 4370 | if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) { |
4382 | DRM_DEBUG_KMS("Link Training Compliance Test requested\n"); | 4371 | DRM_DEBUG_KMS("Link Training Compliance Test requested\n"); |
4383 | /* Send a Hotplug Uevent to userspace to start modeset */ | 4372 | /* Send a Hotplug Uevent to userspace to start modeset */ |
4384 | drm_kms_helper_hotplug_event(intel_encoder->base.dev); | 4373 | drm_kms_helper_hotplug_event(&dev_priv->drm); |
4385 | } | 4374 | } |
4386 | 4375 | ||
4387 | return true; | 4376 | return true; |
@@ -4445,8 +4434,7 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp) | |||
4445 | static enum drm_connector_status | 4434 | static enum drm_connector_status |
4446 | edp_detect(struct intel_dp *intel_dp) | 4435 | edp_detect(struct intel_dp *intel_dp) |
4447 | { | 4436 | { |
4448 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 4437 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
4449 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
4450 | enum drm_connector_status status; | 4438 | enum drm_connector_status status; |
4451 | 4439 | ||
4452 | status = intel_panel_detect(dev_priv); | 4440 | status = intel_panel_detect(dev_priv); |
@@ -4461,7 +4449,7 @@ static bool ibx_digital_port_connected(struct drm_i915_private *dev_priv, | |||
4461 | { | 4449 | { |
4462 | u32 bit; | 4450 | u32 bit; |
4463 | 4451 | ||
4464 | switch (port->port) { | 4452 | switch (port->base.port) { |
4465 | case PORT_B: | 4453 | case PORT_B: |
4466 | bit = SDE_PORTB_HOTPLUG; | 4454 | bit = SDE_PORTB_HOTPLUG; |
4467 | break; | 4455 | break; |
@@ -4472,7 +4460,7 @@ static bool ibx_digital_port_connected(struct drm_i915_private *dev_priv, | |||
4472 | bit = SDE_PORTD_HOTPLUG; | 4460 | bit = SDE_PORTD_HOTPLUG; |
4473 | break; | 4461 | break; |
4474 | default: | 4462 | default: |
4475 | MISSING_CASE(port->port); | 4463 | MISSING_CASE(port->base.port); |
4476 | return false; | 4464 | return false; |
4477 | } | 4465 | } |
4478 | 4466 | ||
@@ -4484,7 +4472,7 @@ static bool cpt_digital_port_connected(struct drm_i915_private *dev_priv, | |||
4484 | { | 4472 | { |
4485 | u32 bit; | 4473 | u32 bit; |
4486 | 4474 | ||
4487 | switch (port->port) { | 4475 | switch (port->base.port) { |
4488 | case PORT_B: | 4476 | case PORT_B: |
4489 | bit = SDE_PORTB_HOTPLUG_CPT; | 4477 | bit = SDE_PORTB_HOTPLUG_CPT; |
4490 | break; | 4478 | break; |
@@ -4495,7 +4483,7 @@ static bool cpt_digital_port_connected(struct drm_i915_private *dev_priv, | |||
4495 | bit = SDE_PORTD_HOTPLUG_CPT; | 4483 | bit = SDE_PORTD_HOTPLUG_CPT; |
4496 | break; | 4484 | break; |
4497 | default: | 4485 | default: |
4498 | MISSING_CASE(port->port); | 4486 | MISSING_CASE(port->base.port); |
4499 | return false; | 4487 | return false; |
4500 | } | 4488 | } |
4501 | 4489 | ||
@@ -4507,7 +4495,7 @@ static bool spt_digital_port_connected(struct drm_i915_private *dev_priv, | |||
4507 | { | 4495 | { |
4508 | u32 bit; | 4496 | u32 bit; |
4509 | 4497 | ||
4510 | switch (port->port) { | 4498 | switch (port->base.port) { |
4511 | case PORT_A: | 4499 | case PORT_A: |
4512 | bit = SDE_PORTA_HOTPLUG_SPT; | 4500 | bit = SDE_PORTA_HOTPLUG_SPT; |
4513 | break; | 4501 | break; |
@@ -4526,7 +4514,7 @@ static bool g4x_digital_port_connected(struct drm_i915_private *dev_priv, | |||
4526 | { | 4514 | { |
4527 | u32 bit; | 4515 | u32 bit; |
4528 | 4516 | ||
4529 | switch (port->port) { | 4517 | switch (port->base.port) { |
4530 | case PORT_B: | 4518 | case PORT_B: |
4531 | bit = PORTB_HOTPLUG_LIVE_STATUS_G4X; | 4519 | bit = PORTB_HOTPLUG_LIVE_STATUS_G4X; |
4532 | break; | 4520 | break; |
@@ -4537,7 +4525,7 @@ static bool g4x_digital_port_connected(struct drm_i915_private *dev_priv, | |||
4537 | bit = PORTD_HOTPLUG_LIVE_STATUS_G4X; | 4525 | bit = PORTD_HOTPLUG_LIVE_STATUS_G4X; |
4538 | break; | 4526 | break; |
4539 | default: | 4527 | default: |
4540 | MISSING_CASE(port->port); | 4528 | MISSING_CASE(port->base.port); |
4541 | return false; | 4529 | return false; |
4542 | } | 4530 | } |
4543 | 4531 | ||
@@ -4549,7 +4537,7 @@ static bool gm45_digital_port_connected(struct drm_i915_private *dev_priv, | |||
4549 | { | 4537 | { |
4550 | u32 bit; | 4538 | u32 bit; |
4551 | 4539 | ||
4552 | switch (port->port) { | 4540 | switch (port->base.port) { |
4553 | case PORT_B: | 4541 | case PORT_B: |
4554 | bit = PORTB_HOTPLUG_LIVE_STATUS_GM45; | 4542 | bit = PORTB_HOTPLUG_LIVE_STATUS_GM45; |
4555 | break; | 4543 | break; |
@@ -4560,7 +4548,7 @@ static bool gm45_digital_port_connected(struct drm_i915_private *dev_priv, | |||
4560 | bit = PORTD_HOTPLUG_LIVE_STATUS_GM45; | 4548 | bit = PORTD_HOTPLUG_LIVE_STATUS_GM45; |
4561 | break; | 4549 | break; |
4562 | default: | 4550 | default: |
4563 | MISSING_CASE(port->port); | 4551 | MISSING_CASE(port->base.port); |
4564 | return false; | 4552 | return false; |
4565 | } | 4553 | } |
4566 | 4554 | ||
@@ -4570,7 +4558,7 @@ static bool gm45_digital_port_connected(struct drm_i915_private *dev_priv, | |||
4570 | static bool ilk_digital_port_connected(struct drm_i915_private *dev_priv, | 4558 | static bool ilk_digital_port_connected(struct drm_i915_private *dev_priv, |
4571 | struct intel_digital_port *port) | 4559 | struct intel_digital_port *port) |
4572 | { | 4560 | { |
4573 | if (port->port == PORT_A) | 4561 | if (port->base.port == PORT_A) |
4574 | return I915_READ(DEISR) & DE_DP_A_HOTPLUG; | 4562 | return I915_READ(DEISR) & DE_DP_A_HOTPLUG; |
4575 | else | 4563 | else |
4576 | return ibx_digital_port_connected(dev_priv, port); | 4564 | return ibx_digital_port_connected(dev_priv, port); |
@@ -4579,7 +4567,7 @@ static bool ilk_digital_port_connected(struct drm_i915_private *dev_priv, | |||
4579 | static bool snb_digital_port_connected(struct drm_i915_private *dev_priv, | 4567 | static bool snb_digital_port_connected(struct drm_i915_private *dev_priv, |
4580 | struct intel_digital_port *port) | 4568 | struct intel_digital_port *port) |
4581 | { | 4569 | { |
4582 | if (port->port == PORT_A) | 4570 | if (port->base.port == PORT_A) |
4583 | return I915_READ(DEISR) & DE_DP_A_HOTPLUG; | 4571 | return I915_READ(DEISR) & DE_DP_A_HOTPLUG; |
4584 | else | 4572 | else |
4585 | return cpt_digital_port_connected(dev_priv, port); | 4573 | return cpt_digital_port_connected(dev_priv, port); |
@@ -4588,7 +4576,7 @@ static bool snb_digital_port_connected(struct drm_i915_private *dev_priv, | |||
4588 | static bool ivb_digital_port_connected(struct drm_i915_private *dev_priv, | 4576 | static bool ivb_digital_port_connected(struct drm_i915_private *dev_priv, |
4589 | struct intel_digital_port *port) | 4577 | struct intel_digital_port *port) |
4590 | { | 4578 | { |
4591 | if (port->port == PORT_A) | 4579 | if (port->base.port == PORT_A) |
4592 | return I915_READ(DEISR) & DE_DP_A_HOTPLUG_IVB; | 4580 | return I915_READ(DEISR) & DE_DP_A_HOTPLUG_IVB; |
4593 | else | 4581 | else |
4594 | return cpt_digital_port_connected(dev_priv, port); | 4582 | return cpt_digital_port_connected(dev_priv, port); |
@@ -4597,7 +4585,7 @@ static bool ivb_digital_port_connected(struct drm_i915_private *dev_priv, | |||
4597 | static bool bdw_digital_port_connected(struct drm_i915_private *dev_priv, | 4585 | static bool bdw_digital_port_connected(struct drm_i915_private *dev_priv, |
4598 | struct intel_digital_port *port) | 4586 | struct intel_digital_port *port) |
4599 | { | 4587 | { |
4600 | if (port->port == PORT_A) | 4588 | if (port->base.port == PORT_A) |
4601 | return I915_READ(GEN8_DE_PORT_ISR) & GEN8_PORT_DP_A_HOTPLUG; | 4589 | return I915_READ(GEN8_DE_PORT_ISR) & GEN8_PORT_DP_A_HOTPLUG; |
4602 | else | 4590 | else |
4603 | return cpt_digital_port_connected(dev_priv, port); | 4591 | return cpt_digital_port_connected(dev_priv, port); |
@@ -4702,24 +4690,21 @@ intel_dp_unset_edid(struct intel_dp *intel_dp) | |||
4702 | } | 4690 | } |
4703 | 4691 | ||
4704 | static int | 4692 | static int |
4705 | intel_dp_long_pulse(struct intel_connector *intel_connector) | 4693 | intel_dp_long_pulse(struct intel_connector *connector) |
4706 | { | 4694 | { |
4707 | struct drm_connector *connector = &intel_connector->base; | 4695 | struct drm_i915_private *dev_priv = to_i915(connector->base.dev); |
4708 | struct intel_dp *intel_dp = intel_attached_dp(connector); | 4696 | struct intel_dp *intel_dp = intel_attached_dp(&connector->base); |
4709 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | ||
4710 | struct intel_encoder *intel_encoder = &intel_dig_port->base; | ||
4711 | struct drm_device *dev = connector->dev; | ||
4712 | enum drm_connector_status status; | 4697 | enum drm_connector_status status; |
4713 | u8 sink_irq_vector = 0; | 4698 | u8 sink_irq_vector = 0; |
4714 | 4699 | ||
4715 | WARN_ON(!drm_modeset_is_locked(&connector->dev->mode_config.connection_mutex)); | 4700 | WARN_ON(!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex)); |
4716 | 4701 | ||
4717 | intel_display_power_get(to_i915(dev), intel_dp->aux_power_domain); | 4702 | intel_display_power_get(dev_priv, intel_dp->aux_power_domain); |
4718 | 4703 | ||
4719 | /* Can't disconnect eDP, but you can close the lid... */ | 4704 | /* Can't disconnect eDP, but you can close the lid... */ |
4720 | if (intel_dp_is_edp(intel_dp)) | 4705 | if (intel_dp_is_edp(intel_dp)) |
4721 | status = edp_detect(intel_dp); | 4706 | status = edp_detect(intel_dp); |
4722 | else if (intel_digital_port_connected(to_i915(dev), | 4707 | else if (intel_digital_port_connected(dev_priv, |
4723 | dp_to_dig_port(intel_dp))) | 4708 | dp_to_dig_port(intel_dp))) |
4724 | status = intel_dp_detect_dpcd(intel_dp); | 4709 | status = intel_dp_detect_dpcd(intel_dp); |
4725 | else | 4710 | else |
@@ -4740,9 +4725,6 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) | |||
4740 | goto out; | 4725 | goto out; |
4741 | } | 4726 | } |
4742 | 4727 | ||
4743 | if (intel_encoder->type != INTEL_OUTPUT_EDP) | ||
4744 | intel_encoder->type = INTEL_OUTPUT_DP; | ||
4745 | |||
4746 | if (intel_dp->reset_link_params) { | 4728 | if (intel_dp->reset_link_params) { |
4747 | /* Initial max link lane count */ | 4729 | /* Initial max link lane count */ |
4748 | intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp); | 4730 | intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp); |
@@ -4793,7 +4775,7 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) | |||
4793 | intel_dp->aux.i2c_defer_count = 0; | 4775 | intel_dp->aux.i2c_defer_count = 0; |
4794 | 4776 | ||
4795 | intel_dp_set_edid(intel_dp); | 4777 | intel_dp_set_edid(intel_dp); |
4796 | if (intel_dp_is_edp(intel_dp) || intel_connector->detect_edid) | 4778 | if (intel_dp_is_edp(intel_dp) || connector->detect_edid) |
4797 | status = connector_status_connected; | 4779 | status = connector_status_connected; |
4798 | intel_dp->detect_done = true; | 4780 | intel_dp->detect_done = true; |
4799 | 4781 | ||
@@ -4816,7 +4798,7 @@ out: | |||
4816 | if (status != connector_status_connected && !intel_dp->is_mst) | 4798 | if (status != connector_status_connected && !intel_dp->is_mst) |
4817 | intel_dp_unset_edid(intel_dp); | 4799 | intel_dp_unset_edid(intel_dp); |
4818 | 4800 | ||
4819 | intel_display_power_put(to_i915(dev), intel_dp->aux_power_domain); | 4801 | intel_display_power_put(dev_priv, intel_dp->aux_power_domain); |
4820 | return status; | 4802 | return status; |
4821 | } | 4803 | } |
4822 | 4804 | ||
@@ -4859,9 +4841,6 @@ intel_dp_force(struct drm_connector *connector) | |||
4859 | intel_dp_set_edid(intel_dp); | 4841 | intel_dp_set_edid(intel_dp); |
4860 | 4842 | ||
4861 | intel_display_power_put(dev_priv, intel_dp->aux_power_domain); | 4843 | intel_display_power_put(dev_priv, intel_dp->aux_power_domain); |
4862 | |||
4863 | if (intel_encoder->type != INTEL_OUTPUT_EDP) | ||
4864 | intel_encoder->type = INTEL_OUTPUT_DP; | ||
4865 | } | 4844 | } |
4866 | 4845 | ||
4867 | static int intel_dp_get_modes(struct drm_connector *connector) | 4846 | static int intel_dp_get_modes(struct drm_connector *connector) |
@@ -4986,9 +4965,7 @@ void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder) | |||
4986 | 4965 | ||
4987 | static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp) | 4966 | static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp) |
4988 | { | 4967 | { |
4989 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 4968 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
4990 | struct drm_device *dev = intel_dig_port->base.base.dev; | ||
4991 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
4992 | 4969 | ||
4993 | lockdep_assert_held(&dev_priv->pps_mutex); | 4970 | lockdep_assert_held(&dev_priv->pps_mutex); |
4994 | 4971 | ||
@@ -5041,7 +5018,7 @@ void intel_dp_encoder_reset(struct drm_encoder *encoder) | |||
5041 | 5018 | ||
5042 | if (intel_dp_is_edp(intel_dp)) { | 5019 | if (intel_dp_is_edp(intel_dp)) { |
5043 | /* Reinit the power sequencer, in case BIOS did something with it. */ | 5020 | /* Reinit the power sequencer, in case BIOS did something with it. */ |
5044 | intel_dp_pps_init(encoder->dev, intel_dp); | 5021 | intel_dp_pps_init(intel_dp); |
5045 | intel_edp_panel_vdd_sanitize(intel_dp); | 5022 | intel_edp_panel_vdd_sanitize(intel_dp); |
5046 | } | 5023 | } |
5047 | 5024 | ||
@@ -5076,14 +5053,9 @@ enum irqreturn | |||
5076 | intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) | 5053 | intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) |
5077 | { | 5054 | { |
5078 | struct intel_dp *intel_dp = &intel_dig_port->dp; | 5055 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
5079 | struct drm_device *dev = intel_dig_port->base.base.dev; | 5056 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
5080 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
5081 | enum irqreturn ret = IRQ_NONE; | 5057 | enum irqreturn ret = IRQ_NONE; |
5082 | 5058 | ||
5083 | if (intel_dig_port->base.type != INTEL_OUTPUT_EDP && | ||
5084 | intel_dig_port->base.type != INTEL_OUTPUT_HDMI) | ||
5085 | intel_dig_port->base.type = INTEL_OUTPUT_DP; | ||
5086 | |||
5087 | if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) { | 5059 | if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) { |
5088 | /* | 5060 | /* |
5089 | * vdd off can generate a long pulse on eDP which | 5061 | * vdd off can generate a long pulse on eDP which |
@@ -5092,12 +5064,12 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) | |||
5092 | * "vdd off -> long hpd -> vdd on -> detect -> vdd off -> ..." | 5064 | * "vdd off -> long hpd -> vdd on -> detect -> vdd off -> ..." |
5093 | */ | 5065 | */ |
5094 | DRM_DEBUG_KMS("ignoring long hpd on eDP port %c\n", | 5066 | DRM_DEBUG_KMS("ignoring long hpd on eDP port %c\n", |
5095 | port_name(intel_dig_port->port)); | 5067 | port_name(intel_dig_port->base.port)); |
5096 | return IRQ_HANDLED; | 5068 | return IRQ_HANDLED; |
5097 | } | 5069 | } |
5098 | 5070 | ||
5099 | DRM_DEBUG_KMS("got hpd irq on port %c - %s\n", | 5071 | DRM_DEBUG_KMS("got hpd irq on port %c - %s\n", |
5100 | port_name(intel_dig_port->port), | 5072 | port_name(intel_dig_port->base.port), |
5101 | long_hpd ? "long" : "short"); | 5073 | long_hpd ? "long" : "short"); |
5102 | 5074 | ||
5103 | if (long_hpd) { | 5075 | if (long_hpd) { |
@@ -5185,13 +5157,13 @@ static void intel_dp_init_panel_power_timestamps(struct intel_dp *intel_dp) | |||
5185 | } | 5157 | } |
5186 | 5158 | ||
5187 | static void | 5159 | static void |
5188 | intel_pps_readout_hw_state(struct drm_i915_private *dev_priv, | 5160 | intel_pps_readout_hw_state(struct intel_dp *intel_dp, struct edp_power_seq *seq) |
5189 | struct intel_dp *intel_dp, struct edp_power_seq *seq) | ||
5190 | { | 5161 | { |
5162 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | ||
5191 | u32 pp_on, pp_off, pp_div = 0, pp_ctl = 0; | 5163 | u32 pp_on, pp_off, pp_div = 0, pp_ctl = 0; |
5192 | struct pps_registers regs; | 5164 | struct pps_registers regs; |
5193 | 5165 | ||
5194 | intel_pps_get_registers(dev_priv, intel_dp, ®s); | 5166 | intel_pps_get_registers(intel_dp, ®s); |
5195 | 5167 | ||
5196 | /* Workaround: Need to write PP_CONTROL with the unlock key as | 5168 | /* Workaround: Need to write PP_CONTROL with the unlock key as |
5197 | * the very first thing. */ | 5169 | * the very first thing. */ |
@@ -5235,13 +5207,12 @@ intel_pps_dump_state(const char *state_name, const struct edp_power_seq *seq) | |||
5235 | } | 5207 | } |
5236 | 5208 | ||
5237 | static void | 5209 | static void |
5238 | intel_pps_verify_state(struct drm_i915_private *dev_priv, | 5210 | intel_pps_verify_state(struct intel_dp *intel_dp) |
5239 | struct intel_dp *intel_dp) | ||
5240 | { | 5211 | { |
5241 | struct edp_power_seq hw; | 5212 | struct edp_power_seq hw; |
5242 | struct edp_power_seq *sw = &intel_dp->pps_delays; | 5213 | struct edp_power_seq *sw = &intel_dp->pps_delays; |
5243 | 5214 | ||
5244 | intel_pps_readout_hw_state(dev_priv, intel_dp, &hw); | 5215 | intel_pps_readout_hw_state(intel_dp, &hw); |
5245 | 5216 | ||
5246 | if (hw.t1_t3 != sw->t1_t3 || hw.t8 != sw->t8 || hw.t9 != sw->t9 || | 5217 | if (hw.t1_t3 != sw->t1_t3 || hw.t8 != sw->t8 || hw.t9 != sw->t9 || |
5247 | hw.t10 != sw->t10 || hw.t11_t12 != sw->t11_t12) { | 5218 | hw.t10 != sw->t10 || hw.t11_t12 != sw->t11_t12) { |
@@ -5252,10 +5223,9 @@ intel_pps_verify_state(struct drm_i915_private *dev_priv, | |||
5252 | } | 5223 | } |
5253 | 5224 | ||
5254 | static void | 5225 | static void |
5255 | intel_dp_init_panel_power_sequencer(struct drm_device *dev, | 5226 | intel_dp_init_panel_power_sequencer(struct intel_dp *intel_dp) |
5256 | struct intel_dp *intel_dp) | ||
5257 | { | 5227 | { |
5258 | struct drm_i915_private *dev_priv = to_i915(dev); | 5228 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
5259 | struct edp_power_seq cur, vbt, spec, | 5229 | struct edp_power_seq cur, vbt, spec, |
5260 | *final = &intel_dp->pps_delays; | 5230 | *final = &intel_dp->pps_delays; |
5261 | 5231 | ||
@@ -5265,7 +5235,7 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, | |||
5265 | if (final->t11_t12 != 0) | 5235 | if (final->t11_t12 != 0) |
5266 | return; | 5236 | return; |
5267 | 5237 | ||
5268 | intel_pps_readout_hw_state(dev_priv, intel_dp, &cur); | 5238 | intel_pps_readout_hw_state(intel_dp, &cur); |
5269 | 5239 | ||
5270 | intel_pps_dump_state("cur", &cur); | 5240 | intel_pps_dump_state("cur", &cur); |
5271 | 5241 | ||
@@ -5339,20 +5309,19 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, | |||
5339 | } | 5309 | } |
5340 | 5310 | ||
5341 | static void | 5311 | static void |
5342 | intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, | 5312 | intel_dp_init_panel_power_sequencer_registers(struct intel_dp *intel_dp, |
5343 | struct intel_dp *intel_dp, | ||
5344 | bool force_disable_vdd) | 5313 | bool force_disable_vdd) |
5345 | { | 5314 | { |
5346 | struct drm_i915_private *dev_priv = to_i915(dev); | 5315 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
5347 | u32 pp_on, pp_off, pp_div, port_sel = 0; | 5316 | u32 pp_on, pp_off, pp_div, port_sel = 0; |
5348 | int div = dev_priv->rawclk_freq / 1000; | 5317 | int div = dev_priv->rawclk_freq / 1000; |
5349 | struct pps_registers regs; | 5318 | struct pps_registers regs; |
5350 | enum port port = dp_to_dig_port(intel_dp)->port; | 5319 | enum port port = dp_to_dig_port(intel_dp)->base.port; |
5351 | const struct edp_power_seq *seq = &intel_dp->pps_delays; | 5320 | const struct edp_power_seq *seq = &intel_dp->pps_delays; |
5352 | 5321 | ||
5353 | lockdep_assert_held(&dev_priv->pps_mutex); | 5322 | lockdep_assert_held(&dev_priv->pps_mutex); |
5354 | 5323 | ||
5355 | intel_pps_get_registers(dev_priv, intel_dp, ®s); | 5324 | intel_pps_get_registers(intel_dp, ®s); |
5356 | 5325 | ||
5357 | /* | 5326 | /* |
5358 | * On some VLV machines the BIOS can leave the VDD | 5327 | * On some VLV machines the BIOS can leave the VDD |
@@ -5424,16 +5393,15 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, | |||
5424 | I915_READ(regs.pp_div)); | 5393 | I915_READ(regs.pp_div)); |
5425 | } | 5394 | } |
5426 | 5395 | ||
5427 | static void intel_dp_pps_init(struct drm_device *dev, | 5396 | static void intel_dp_pps_init(struct intel_dp *intel_dp) |
5428 | struct intel_dp *intel_dp) | ||
5429 | { | 5397 | { |
5430 | struct drm_i915_private *dev_priv = to_i915(dev); | 5398 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
5431 | 5399 | ||
5432 | if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { | 5400 | if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { |
5433 | vlv_initial_power_sequencer_setup(intel_dp); | 5401 | vlv_initial_power_sequencer_setup(intel_dp); |
5434 | } else { | 5402 | } else { |
5435 | intel_dp_init_panel_power_sequencer(dev, intel_dp); | 5403 | intel_dp_init_panel_power_sequencer(intel_dp); |
5436 | intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, false); | 5404 | intel_dp_init_panel_power_sequencer_registers(intel_dp, false); |
5437 | } | 5405 | } |
5438 | } | 5406 | } |
5439 | 5407 | ||
@@ -5472,7 +5440,6 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv, | |||
5472 | 5440 | ||
5473 | dig_port = dp_to_dig_port(intel_dp); | 5441 | dig_port = dp_to_dig_port(intel_dp); |
5474 | encoder = &dig_port->base; | 5442 | encoder = &dig_port->base; |
5475 | intel_crtc = to_intel_crtc(encoder->base.crtc); | ||
5476 | 5443 | ||
5477 | if (!intel_crtc) { | 5444 | if (!intel_crtc) { |
5478 | DRM_DEBUG_KMS("DRRS: intel_crtc not initialized\n"); | 5445 | DRM_DEBUG_KMS("DRRS: intel_crtc not initialized\n"); |
@@ -5545,8 +5512,7 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv, | |||
5545 | void intel_edp_drrs_enable(struct intel_dp *intel_dp, | 5512 | void intel_edp_drrs_enable(struct intel_dp *intel_dp, |
5546 | const struct intel_crtc_state *crtc_state) | 5513 | const struct intel_crtc_state *crtc_state) |
5547 | { | 5514 | { |
5548 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 5515 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
5549 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
5550 | 5516 | ||
5551 | if (!crtc_state->has_drrs) { | 5517 | if (!crtc_state->has_drrs) { |
5552 | DRM_DEBUG_KMS("Panel doesn't support DRRS\n"); | 5518 | DRM_DEBUG_KMS("Panel doesn't support DRRS\n"); |
@@ -5581,8 +5547,7 @@ unlock: | |||
5581 | void intel_edp_drrs_disable(struct intel_dp *intel_dp, | 5547 | void intel_edp_drrs_disable(struct intel_dp *intel_dp, |
5582 | const struct intel_crtc_state *old_crtc_state) | 5548 | const struct intel_crtc_state *old_crtc_state) |
5583 | { | 5549 | { |
5584 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 5550 | struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); |
5585 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
5586 | 5551 | ||
5587 | if (!old_crtc_state->has_drrs) | 5552 | if (!old_crtc_state->has_drrs) |
5588 | return; | 5553 | return; |
@@ -5765,7 +5730,7 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, | |||
5765 | 5730 | ||
5766 | /** | 5731 | /** |
5767 | * intel_dp_drrs_init - Init basic DRRS work and mutex. | 5732 | * intel_dp_drrs_init - Init basic DRRS work and mutex. |
5768 | * @intel_connector: eDP connector | 5733 | * @connector: eDP connector |
5769 | * @fixed_mode: preferred mode of panel | 5734 | * @fixed_mode: preferred mode of panel |
5770 | * | 5735 | * |
5771 | * This function is called only once at driver load to initialize basic | 5736 | * This function is called only once at driver load to initialize basic |
@@ -5777,12 +5742,10 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, | |||
5777 | * from VBT setting). | 5742 | * from VBT setting). |
5778 | */ | 5743 | */ |
5779 | static struct drm_display_mode * | 5744 | static struct drm_display_mode * |
5780 | intel_dp_drrs_init(struct intel_connector *intel_connector, | 5745 | intel_dp_drrs_init(struct intel_connector *connector, |
5781 | struct drm_display_mode *fixed_mode) | 5746 | struct drm_display_mode *fixed_mode) |
5782 | { | 5747 | { |
5783 | struct drm_connector *connector = &intel_connector->base; | 5748 | struct drm_i915_private *dev_priv = to_i915(connector->base.dev); |
5784 | struct drm_device *dev = connector->dev; | ||
5785 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
5786 | struct drm_display_mode *downclock_mode = NULL; | 5749 | struct drm_display_mode *downclock_mode = NULL; |
5787 | 5750 | ||
5788 | INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work); | 5751 | INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work); |
@@ -5798,8 +5761,8 @@ intel_dp_drrs_init(struct intel_connector *intel_connector, | |||
5798 | return NULL; | 5761 | return NULL; |
5799 | } | 5762 | } |
5800 | 5763 | ||
5801 | downclock_mode = intel_find_panel_downclock | 5764 | downclock_mode = intel_find_panel_downclock(dev_priv, fixed_mode, |
5802 | (dev_priv, fixed_mode, connector); | 5765 | &connector->base); |
5803 | 5766 | ||
5804 | if (!downclock_mode) { | 5767 | if (!downclock_mode) { |
5805 | DRM_DEBUG_KMS("Downclock mode is not found. DRRS not supported\n"); | 5768 | DRM_DEBUG_KMS("Downclock mode is not found. DRRS not supported\n"); |
@@ -5816,11 +5779,9 @@ intel_dp_drrs_init(struct intel_connector *intel_connector, | |||
5816 | static bool intel_edp_init_connector(struct intel_dp *intel_dp, | 5779 | static bool intel_edp_init_connector(struct intel_dp *intel_dp, |
5817 | struct intel_connector *intel_connector) | 5780 | struct intel_connector *intel_connector) |
5818 | { | 5781 | { |
5819 | struct drm_connector *connector = &intel_connector->base; | 5782 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
5820 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | ||
5821 | struct intel_encoder *intel_encoder = &intel_dig_port->base; | ||
5822 | struct drm_device *dev = intel_encoder->base.dev; | ||
5823 | struct drm_i915_private *dev_priv = to_i915(dev); | 5783 | struct drm_i915_private *dev_priv = to_i915(dev); |
5784 | struct drm_connector *connector = &intel_connector->base; | ||
5824 | struct drm_display_mode *fixed_mode = NULL; | 5785 | struct drm_display_mode *fixed_mode = NULL; |
5825 | struct drm_display_mode *alt_fixed_mode = NULL; | 5786 | struct drm_display_mode *alt_fixed_mode = NULL; |
5826 | struct drm_display_mode *downclock_mode = NULL; | 5787 | struct drm_display_mode *downclock_mode = NULL; |
@@ -5838,7 +5799,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, | |||
5838 | * eDP and LVDS bail out early in this case to prevent interfering | 5799 | * eDP and LVDS bail out early in this case to prevent interfering |
5839 | * with an already powered-on LVDS power sequencer. | 5800 | * with an already powered-on LVDS power sequencer. |
5840 | */ | 5801 | */ |
5841 | if (intel_get_lvds_encoder(dev)) { | 5802 | if (intel_get_lvds_encoder(&dev_priv->drm)) { |
5842 | WARN_ON(!(HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv))); | 5803 | WARN_ON(!(HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv))); |
5843 | DRM_INFO("LVDS was detected, not registering eDP\n"); | 5804 | DRM_INFO("LVDS was detected, not registering eDP\n"); |
5844 | 5805 | ||
@@ -5848,7 +5809,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, | |||
5848 | pps_lock(intel_dp); | 5809 | pps_lock(intel_dp); |
5849 | 5810 | ||
5850 | intel_dp_init_panel_power_timestamps(intel_dp); | 5811 | intel_dp_init_panel_power_timestamps(intel_dp); |
5851 | intel_dp_pps_init(dev, intel_dp); | 5812 | intel_dp_pps_init(intel_dp); |
5852 | intel_edp_panel_vdd_sanitize(intel_dp); | 5813 | intel_edp_panel_vdd_sanitize(intel_dp); |
5853 | 5814 | ||
5854 | pps_unlock(intel_dp); | 5815 | pps_unlock(intel_dp); |
@@ -5948,9 +5909,9 @@ intel_dp_init_connector_port_info(struct intel_digital_port *intel_dig_port) | |||
5948 | struct intel_encoder *encoder = &intel_dig_port->base; | 5909 | struct intel_encoder *encoder = &intel_dig_port->base; |
5949 | struct intel_dp *intel_dp = &intel_dig_port->dp; | 5910 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
5950 | 5911 | ||
5951 | encoder->hpd_pin = intel_hpd_pin(intel_dig_port->port); | 5912 | encoder->hpd_pin = intel_hpd_pin(encoder->port); |
5952 | 5913 | ||
5953 | switch (intel_dig_port->port) { | 5914 | switch (encoder->port) { |
5954 | case PORT_A: | 5915 | case PORT_A: |
5955 | intel_dp->aux_power_domain = POWER_DOMAIN_AUX_A; | 5916 | intel_dp->aux_power_domain = POWER_DOMAIN_AUX_A; |
5956 | break; | 5917 | break; |
@@ -5968,7 +5929,7 @@ intel_dp_init_connector_port_info(struct intel_digital_port *intel_dig_port) | |||
5968 | intel_dp->aux_power_domain = POWER_DOMAIN_AUX_D; | 5929 | intel_dp->aux_power_domain = POWER_DOMAIN_AUX_D; |
5969 | break; | 5930 | break; |
5970 | default: | 5931 | default: |
5971 | MISSING_CASE(intel_dig_port->port); | 5932 | MISSING_CASE(encoder->port); |
5972 | } | 5933 | } |
5973 | } | 5934 | } |
5974 | 5935 | ||
@@ -6004,7 +5965,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, | |||
6004 | struct intel_encoder *intel_encoder = &intel_dig_port->base; | 5965 | struct intel_encoder *intel_encoder = &intel_dig_port->base; |
6005 | struct drm_device *dev = intel_encoder->base.dev; | 5966 | struct drm_device *dev = intel_encoder->base.dev; |
6006 | struct drm_i915_private *dev_priv = to_i915(dev); | 5967 | struct drm_i915_private *dev_priv = to_i915(dev); |
6007 | enum port port = intel_dig_port->port; | 5968 | enum port port = intel_encoder->port; |
6008 | int type; | 5969 | int type; |
6009 | 5970 | ||
6010 | /* Initialize the work for modeset in case of link train failure */ | 5971 | /* Initialize the work for modeset in case of link train failure */ |
@@ -6174,7 +6135,6 @@ bool intel_dp_init(struct drm_i915_private *dev_priv, | |||
6174 | intel_encoder->disable = g4x_disable_dp; | 6135 | intel_encoder->disable = g4x_disable_dp; |
6175 | } | 6136 | } |
6176 | 6137 | ||
6177 | intel_dig_port->port = port; | ||
6178 | intel_dig_port->dp.output_reg = output_reg; | 6138 | intel_dig_port->dp.output_reg = output_reg; |
6179 | intel_dig_port->max_lanes = 4; | 6139 | intel_dig_port->max_lanes = 4; |
6180 | 6140 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 772521440a9f..c3de0918ee13 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c | |||
@@ -34,6 +34,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, | |||
34 | struct intel_crtc_state *pipe_config, | 34 | struct intel_crtc_state *pipe_config, |
35 | struct drm_connector_state *conn_state) | 35 | struct drm_connector_state *conn_state) |
36 | { | 36 | { |
37 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | ||
37 | struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); | 38 | struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); |
38 | struct intel_digital_port *intel_dig_port = intel_mst->primary; | 39 | struct intel_digital_port *intel_dig_port = intel_mst->primary; |
39 | struct intel_dp *intel_dp = &intel_dig_port->dp; | 40 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
@@ -87,6 +88,12 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, | |||
87 | 88 | ||
88 | pipe_config->dp_m_n.tu = slots; | 89 | pipe_config->dp_m_n.tu = slots; |
89 | 90 | ||
91 | if (IS_GEN9_LP(dev_priv)) | ||
92 | pipe_config->lane_lat_optim_mask = | ||
93 | bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); | ||
94 | |||
95 | intel_ddi_compute_min_voltage_level(dev_priv, pipe_config); | ||
96 | |||
90 | return true; | 97 | return true; |
91 | } | 98 | } |
92 | 99 | ||
@@ -142,7 +149,8 @@ static void intel_mst_disable_dp(struct intel_encoder *encoder, | |||
142 | DRM_ERROR("failed to update payload %d\n", ret); | 149 | DRM_ERROR("failed to update payload %d\n", ret); |
143 | } | 150 | } |
144 | if (old_crtc_state->has_audio) | 151 | if (old_crtc_state->has_audio) |
145 | intel_audio_codec_disable(encoder); | 152 | intel_audio_codec_disable(encoder, |
153 | old_crtc_state, old_conn_state); | ||
146 | } | 154 | } |
147 | 155 | ||
148 | static void intel_mst_post_disable_dp(struct intel_encoder *encoder, | 156 | static void intel_mst_post_disable_dp(struct intel_encoder *encoder, |
@@ -172,13 +180,27 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder, | |||
172 | intel_dp->active_mst_links--; | 180 | intel_dp->active_mst_links--; |
173 | 181 | ||
174 | intel_mst->connector = NULL; | 182 | intel_mst->connector = NULL; |
175 | if (intel_dp->active_mst_links == 0) { | 183 | if (intel_dp->active_mst_links == 0) |
176 | intel_dig_port->base.post_disable(&intel_dig_port->base, | 184 | intel_dig_port->base.post_disable(&intel_dig_port->base, |
177 | NULL, NULL); | 185 | old_crtc_state, NULL); |
178 | } | 186 | |
179 | DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); | 187 | DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); |
180 | } | 188 | } |
181 | 189 | ||
190 | static void intel_mst_pre_pll_enable_dp(struct intel_encoder *encoder, | ||
191 | const struct intel_crtc_state *pipe_config, | ||
192 | const struct drm_connector_state *conn_state) | ||
193 | { | ||
194 | struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); | ||
195 | struct intel_digital_port *intel_dig_port = intel_mst->primary; | ||
196 | struct intel_dp *intel_dp = &intel_dig_port->dp; | ||
197 | |||
198 | if (intel_dp->active_mst_links == 0 && | ||
199 | intel_dig_port->base.pre_pll_enable) | ||
200 | intel_dig_port->base.pre_pll_enable(&intel_dig_port->base, | ||
201 | pipe_config, NULL); | ||
202 | } | ||
203 | |||
182 | static void intel_mst_pre_enable_dp(struct intel_encoder *encoder, | 204 | static void intel_mst_pre_enable_dp(struct intel_encoder *encoder, |
183 | const struct intel_crtc_state *pipe_config, | 205 | const struct intel_crtc_state *pipe_config, |
184 | const struct drm_connector_state *conn_state) | 206 | const struct drm_connector_state *conn_state) |
@@ -187,7 +209,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder, | |||
187 | struct intel_digital_port *intel_dig_port = intel_mst->primary; | 209 | struct intel_digital_port *intel_dig_port = intel_mst->primary; |
188 | struct intel_dp *intel_dp = &intel_dig_port->dp; | 210 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
189 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 211 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
190 | enum port port = intel_dig_port->port; | 212 | enum port port = intel_dig_port->base.port; |
191 | struct intel_connector *connector = | 213 | struct intel_connector *connector = |
192 | to_intel_connector(conn_state->connector); | 214 | to_intel_connector(conn_state->connector); |
193 | int ret; | 215 | int ret; |
@@ -231,7 +253,7 @@ static void intel_mst_enable_dp(struct intel_encoder *encoder, | |||
231 | struct intel_digital_port *intel_dig_port = intel_mst->primary; | 253 | struct intel_digital_port *intel_dig_port = intel_mst->primary; |
232 | struct intel_dp *intel_dp = &intel_dig_port->dp; | 254 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
233 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 255 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
234 | enum port port = intel_dig_port->port; | 256 | enum port port = intel_dig_port->base.port; |
235 | int ret; | 257 | int ret; |
236 | 258 | ||
237 | DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); | 259 | DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); |
@@ -265,48 +287,8 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder, | |||
265 | { | 287 | { |
266 | struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); | 288 | struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); |
267 | struct intel_digital_port *intel_dig_port = intel_mst->primary; | 289 | struct intel_digital_port *intel_dig_port = intel_mst->primary; |
268 | struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc); | ||
269 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | ||
270 | enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; | ||
271 | u32 temp, flags = 0; | ||
272 | |||
273 | pipe_config->has_audio = | ||
274 | intel_ddi_is_audio_enabled(dev_priv, crtc); | ||
275 | |||
276 | temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); | ||
277 | if (temp & TRANS_DDI_PHSYNC) | ||
278 | flags |= DRM_MODE_FLAG_PHSYNC; | ||
279 | else | ||
280 | flags |= DRM_MODE_FLAG_NHSYNC; | ||
281 | if (temp & TRANS_DDI_PVSYNC) | ||
282 | flags |= DRM_MODE_FLAG_PVSYNC; | ||
283 | else | ||
284 | flags |= DRM_MODE_FLAG_NVSYNC; | ||
285 | |||
286 | switch (temp & TRANS_DDI_BPC_MASK) { | ||
287 | case TRANS_DDI_BPC_6: | ||
288 | pipe_config->pipe_bpp = 18; | ||
289 | break; | ||
290 | case TRANS_DDI_BPC_8: | ||
291 | pipe_config->pipe_bpp = 24; | ||
292 | break; | ||
293 | case TRANS_DDI_BPC_10: | ||
294 | pipe_config->pipe_bpp = 30; | ||
295 | break; | ||
296 | case TRANS_DDI_BPC_12: | ||
297 | pipe_config->pipe_bpp = 36; | ||
298 | break; | ||
299 | default: | ||
300 | break; | ||
301 | } | ||
302 | pipe_config->base.adjusted_mode.flags |= flags; | ||
303 | |||
304 | pipe_config->lane_count = | ||
305 | ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; | ||
306 | |||
307 | intel_dp_get_m_n(crtc, pipe_config); | ||
308 | 290 | ||
309 | intel_ddi_clock_get(&intel_dig_port->base, pipe_config); | 291 | intel_ddi_get_config(&intel_dig_port->base, pipe_config); |
310 | } | 292 | } |
311 | 293 | ||
312 | static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector) | 294 | static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector) |
@@ -570,13 +552,14 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *intel_dig_port, enum | |||
570 | 552 | ||
571 | intel_encoder->type = INTEL_OUTPUT_DP_MST; | 553 | intel_encoder->type = INTEL_OUTPUT_DP_MST; |
572 | intel_encoder->power_domain = intel_dig_port->base.power_domain; | 554 | intel_encoder->power_domain = intel_dig_port->base.power_domain; |
573 | intel_encoder->port = intel_dig_port->port; | 555 | intel_encoder->port = intel_dig_port->base.port; |
574 | intel_encoder->crtc_mask = 0x7; | 556 | intel_encoder->crtc_mask = 0x7; |
575 | intel_encoder->cloneable = 0; | 557 | intel_encoder->cloneable = 0; |
576 | 558 | ||
577 | intel_encoder->compute_config = intel_dp_mst_compute_config; | 559 | intel_encoder->compute_config = intel_dp_mst_compute_config; |
578 | intel_encoder->disable = intel_mst_disable_dp; | 560 | intel_encoder->disable = intel_mst_disable_dp; |
579 | intel_encoder->post_disable = intel_mst_post_disable_dp; | 561 | intel_encoder->post_disable = intel_mst_post_disable_dp; |
562 | intel_encoder->pre_pll_enable = intel_mst_pre_pll_enable_dp; | ||
580 | intel_encoder->pre_enable = intel_mst_pre_enable_dp; | 563 | intel_encoder->pre_enable = intel_mst_pre_enable_dp; |
581 | intel_encoder->enable = intel_mst_enable_dp; | 564 | intel_encoder->enable = intel_mst_enable_dp; |
582 | intel_encoder->get_hw_state = intel_dp_mst_enc_get_hw_state; | 565 | intel_encoder->get_hw_state = intel_dp_mst_enc_get_hw_state; |
diff --git a/drivers/gpu/drm/i915/intel_dpio_phy.c b/drivers/gpu/drm/i915/intel_dpio_phy.c index de38d014ed39..76473e9836c6 100644 --- a/drivers/gpu/drm/i915/intel_dpio_phy.c +++ b/drivers/gpu/drm/i915/intel_dpio_phy.c | |||
@@ -466,21 +466,21 @@ void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy) | |||
466 | 466 | ||
467 | lockdep_assert_held(&dev_priv->power_domains.lock); | 467 | lockdep_assert_held(&dev_priv->power_domains.lock); |
468 | 468 | ||
469 | if (rcomp_phy != -1) { | 469 | was_enabled = true; |
470 | if (rcomp_phy != -1) | ||
470 | was_enabled = bxt_ddi_phy_is_enabled(dev_priv, rcomp_phy); | 471 | was_enabled = bxt_ddi_phy_is_enabled(dev_priv, rcomp_phy); |
471 | 472 | ||
472 | /* | 473 | /* |
473 | * We need to copy the GRC calibration value from rcomp_phy, | 474 | * We need to copy the GRC calibration value from rcomp_phy, |
474 | * so make sure it's powered up. | 475 | * so make sure it's powered up. |
475 | */ | 476 | */ |
476 | if (!was_enabled) | 477 | if (!was_enabled) |
477 | _bxt_ddi_phy_init(dev_priv, rcomp_phy); | 478 | _bxt_ddi_phy_init(dev_priv, rcomp_phy); |
478 | } | ||
479 | 479 | ||
480 | _bxt_ddi_phy_init(dev_priv, phy); | 480 | _bxt_ddi_phy_init(dev_priv, phy); |
481 | 481 | ||
482 | if (rcomp_phy != -1 && !was_enabled) | 482 | if (!was_enabled) |
483 | bxt_ddi_phy_uninit(dev_priv, phy_info->rcomp_phy); | 483 | bxt_ddi_phy_uninit(dev_priv, rcomp_phy); |
484 | } | 484 | } |
485 | 485 | ||
486 | static bool __printf(6, 7) | 486 | static bool __printf(6, 7) |
@@ -567,8 +567,7 @@ bool bxt_ddi_phy_verify_state(struct drm_i915_private *dev_priv, | |||
567 | } | 567 | } |
568 | 568 | ||
569 | uint8_t | 569 | uint8_t |
570 | bxt_ddi_phy_calc_lane_lat_optim_mask(struct intel_encoder *encoder, | 570 | bxt_ddi_phy_calc_lane_lat_optim_mask(uint8_t lane_count) |
571 | uint8_t lane_count) | ||
572 | { | 571 | { |
573 | switch (lane_count) { | 572 | switch (lane_count) { |
574 | case 1: | 573 | case 1: |
@@ -587,9 +586,8 @@ bxt_ddi_phy_calc_lane_lat_optim_mask(struct intel_encoder *encoder, | |||
587 | void bxt_ddi_phy_set_lane_optim_mask(struct intel_encoder *encoder, | 586 | void bxt_ddi_phy_set_lane_optim_mask(struct intel_encoder *encoder, |
588 | uint8_t lane_lat_optim_mask) | 587 | uint8_t lane_lat_optim_mask) |
589 | { | 588 | { |
590 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); | 589 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
591 | struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev); | 590 | enum port port = encoder->port; |
592 | enum port port = dport->port; | ||
593 | enum dpio_phy phy; | 591 | enum dpio_phy phy; |
594 | enum dpio_channel ch; | 592 | enum dpio_channel ch; |
595 | int lane; | 593 | int lane; |
@@ -614,9 +612,8 @@ void bxt_ddi_phy_set_lane_optim_mask(struct intel_encoder *encoder, | |||
614 | uint8_t | 612 | uint8_t |
615 | bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder) | 613 | bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder) |
616 | { | 614 | { |
617 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); | 615 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
618 | struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev); | 616 | enum port port = encoder->port; |
619 | enum port port = dport->port; | ||
620 | enum dpio_phy phy; | 617 | enum dpio_phy phy; |
621 | enum dpio_channel ch; | 618 | enum dpio_channel ch; |
622 | int lane; | 619 | int lane; |
@@ -642,7 +639,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, | |||
642 | { | 639 | { |
643 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 640 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
644 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); | 641 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); |
645 | struct intel_crtc *intel_crtc = to_intel_crtc(dport->base.base.crtc); | 642 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
646 | enum dpio_channel ch = vlv_dport_to_channel(dport); | 643 | enum dpio_channel ch = vlv_dport_to_channel(dport); |
647 | enum pipe pipe = intel_crtc->pipe; | 644 | enum pipe pipe = intel_crtc->pipe; |
648 | u32 val; | 645 | u32 val; |
@@ -734,11 +731,12 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, | |||
734 | } | 731 | } |
735 | 732 | ||
736 | void chv_data_lane_soft_reset(struct intel_encoder *encoder, | 733 | void chv_data_lane_soft_reset(struct intel_encoder *encoder, |
734 | const struct intel_crtc_state *crtc_state, | ||
737 | bool reset) | 735 | bool reset) |
738 | { | 736 | { |
739 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 737 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
740 | enum dpio_channel ch = vlv_dport_to_channel(enc_to_dig_port(&encoder->base)); | 738 | enum dpio_channel ch = vlv_dport_to_channel(enc_to_dig_port(&encoder->base)); |
741 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); | 739 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
742 | enum pipe pipe = crtc->pipe; | 740 | enum pipe pipe = crtc->pipe; |
743 | uint32_t val; | 741 | uint32_t val; |
744 | 742 | ||
@@ -777,17 +775,16 @@ void chv_data_lane_soft_reset(struct intel_encoder *encoder, | |||
777 | } | 775 | } |
778 | } | 776 | } |
779 | 777 | ||
780 | void chv_phy_pre_pll_enable(struct intel_encoder *encoder) | 778 | void chv_phy_pre_pll_enable(struct intel_encoder *encoder, |
779 | const struct intel_crtc_state *crtc_state) | ||
781 | { | 780 | { |
782 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); | 781 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); |
783 | struct drm_device *dev = encoder->base.dev; | 782 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
784 | struct drm_i915_private *dev_priv = to_i915(dev); | 783 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
785 | struct intel_crtc *intel_crtc = | ||
786 | to_intel_crtc(encoder->base.crtc); | ||
787 | enum dpio_channel ch = vlv_dport_to_channel(dport); | 784 | enum dpio_channel ch = vlv_dport_to_channel(dport); |
788 | enum pipe pipe = intel_crtc->pipe; | 785 | enum pipe pipe = crtc->pipe; |
789 | unsigned int lane_mask = | 786 | unsigned int lane_mask = |
790 | intel_dp_unused_lane_mask(intel_crtc->config->lane_count); | 787 | intel_dp_unused_lane_mask(crtc_state->lane_count); |
791 | u32 val; | 788 | u32 val; |
792 | 789 | ||
793 | /* | 790 | /* |
@@ -803,7 +800,7 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder) | |||
803 | mutex_lock(&dev_priv->sb_lock); | 800 | mutex_lock(&dev_priv->sb_lock); |
804 | 801 | ||
805 | /* Assert data lane reset */ | 802 | /* Assert data lane reset */ |
806 | chv_data_lane_soft_reset(encoder, true); | 803 | chv_data_lane_soft_reset(encoder, crtc_state, true); |
807 | 804 | ||
808 | /* program left/right clock distribution */ | 805 | /* program left/right clock distribution */ |
809 | if (pipe != PIPE_B) { | 806 | if (pipe != PIPE_B) { |
@@ -833,7 +830,7 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder) | |||
833 | val |= CHV_PCS_USEDCLKCHANNEL; | 830 | val |= CHV_PCS_USEDCLKCHANNEL; |
834 | vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW8(ch), val); | 831 | vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW8(ch), val); |
835 | 832 | ||
836 | if (intel_crtc->config->lane_count > 2) { | 833 | if (crtc_state->lane_count > 2) { |
837 | val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW8(ch)); | 834 | val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW8(ch)); |
838 | val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE; | 835 | val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE; |
839 | if (pipe != PIPE_B) | 836 | if (pipe != PIPE_B) |
@@ -858,16 +855,15 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder) | |||
858 | mutex_unlock(&dev_priv->sb_lock); | 855 | mutex_unlock(&dev_priv->sb_lock); |
859 | } | 856 | } |
860 | 857 | ||
861 | void chv_phy_pre_encoder_enable(struct intel_encoder *encoder) | 858 | void chv_phy_pre_encoder_enable(struct intel_encoder *encoder, |
859 | const struct intel_crtc_state *crtc_state) | ||
862 | { | 860 | { |
863 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 861 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
864 | struct intel_digital_port *dport = dp_to_dig_port(intel_dp); | 862 | struct intel_digital_port *dport = dp_to_dig_port(intel_dp); |
865 | struct drm_device *dev = encoder->base.dev; | 863 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
866 | struct drm_i915_private *dev_priv = to_i915(dev); | 864 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
867 | struct intel_crtc *intel_crtc = | ||
868 | to_intel_crtc(encoder->base.crtc); | ||
869 | enum dpio_channel ch = vlv_dport_to_channel(dport); | 865 | enum dpio_channel ch = vlv_dport_to_channel(dport); |
870 | int pipe = intel_crtc->pipe; | 866 | enum pipe pipe = crtc->pipe; |
871 | int data, i, stagger; | 867 | int data, i, stagger; |
872 | u32 val; | 868 | u32 val; |
873 | 869 | ||
@@ -878,16 +874,16 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder) | |||
878 | val &= ~DPIO_LANEDESKEW_STRAP_OVRD; | 874 | val &= ~DPIO_LANEDESKEW_STRAP_OVRD; |
879 | vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val); | 875 | vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val); |
880 | 876 | ||
881 | if (intel_crtc->config->lane_count > 2) { | 877 | if (crtc_state->lane_count > 2) { |
882 | val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch)); | 878 | val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch)); |
883 | val &= ~DPIO_LANEDESKEW_STRAP_OVRD; | 879 | val &= ~DPIO_LANEDESKEW_STRAP_OVRD; |
884 | vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val); | 880 | vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val); |
885 | } | 881 | } |
886 | 882 | ||
887 | /* Program Tx lane latency optimal setting*/ | 883 | /* Program Tx lane latency optimal setting*/ |
888 | for (i = 0; i < intel_crtc->config->lane_count; i++) { | 884 | for (i = 0; i < crtc_state->lane_count; i++) { |
889 | /* Set the upar bit */ | 885 | /* Set the upar bit */ |
890 | if (intel_crtc->config->lane_count == 1) | 886 | if (crtc_state->lane_count == 1) |
891 | data = 0x0; | 887 | data = 0x0; |
892 | else | 888 | else |
893 | data = (i == 1) ? 0x0 : 0x1; | 889 | data = (i == 1) ? 0x0 : 0x1; |
@@ -896,13 +892,13 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder) | |||
896 | } | 892 | } |
897 | 893 | ||
898 | /* Data lane stagger programming */ | 894 | /* Data lane stagger programming */ |
899 | if (intel_crtc->config->port_clock > 270000) | 895 | if (crtc_state->port_clock > 270000) |
900 | stagger = 0x18; | 896 | stagger = 0x18; |
901 | else if (intel_crtc->config->port_clock > 135000) | 897 | else if (crtc_state->port_clock > 135000) |
902 | stagger = 0xd; | 898 | stagger = 0xd; |
903 | else if (intel_crtc->config->port_clock > 67500) | 899 | else if (crtc_state->port_clock > 67500) |
904 | stagger = 0x7; | 900 | stagger = 0x7; |
905 | else if (intel_crtc->config->port_clock > 33750) | 901 | else if (crtc_state->port_clock > 33750) |
906 | stagger = 0x4; | 902 | stagger = 0x4; |
907 | else | 903 | else |
908 | stagger = 0x2; | 904 | stagger = 0x2; |
@@ -911,7 +907,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder) | |||
911 | val |= DPIO_TX2_STAGGER_MASK(0x1f); | 907 | val |= DPIO_TX2_STAGGER_MASK(0x1f); |
912 | vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val); | 908 | vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val); |
913 | 909 | ||
914 | if (intel_crtc->config->lane_count > 2) { | 910 | if (crtc_state->lane_count > 2) { |
915 | val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch)); | 911 | val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch)); |
916 | val |= DPIO_TX2_STAGGER_MASK(0x1f); | 912 | val |= DPIO_TX2_STAGGER_MASK(0x1f); |
917 | vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val); | 913 | vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val); |
@@ -924,7 +920,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder) | |||
924 | DPIO_TX1_STAGGER_MULT(6) | | 920 | DPIO_TX1_STAGGER_MULT(6) | |
925 | DPIO_TX2_STAGGER_MULT(0)); | 921 | DPIO_TX2_STAGGER_MULT(0)); |
926 | 922 | ||
927 | if (intel_crtc->config->lane_count > 2) { | 923 | if (crtc_state->lane_count > 2) { |
928 | vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW12(ch), | 924 | vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW12(ch), |
929 | DPIO_LANESTAGGER_STRAP(stagger) | | 925 | DPIO_LANESTAGGER_STRAP(stagger) | |
930 | DPIO_LANESTAGGER_STRAP_OVRD | | 926 | DPIO_LANESTAGGER_STRAP_OVRD | |
@@ -934,7 +930,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder) | |||
934 | } | 930 | } |
935 | 931 | ||
936 | /* Deassert data lane reset */ | 932 | /* Deassert data lane reset */ |
937 | chv_data_lane_soft_reset(encoder, false); | 933 | chv_data_lane_soft_reset(encoder, crtc_state, false); |
938 | 934 | ||
939 | mutex_unlock(&dev_priv->sb_lock); | 935 | mutex_unlock(&dev_priv->sb_lock); |
940 | } | 936 | } |
@@ -950,10 +946,11 @@ void chv_phy_release_cl2_override(struct intel_encoder *encoder) | |||
950 | } | 946 | } |
951 | } | 947 | } |
952 | 948 | ||
953 | void chv_phy_post_pll_disable(struct intel_encoder *encoder) | 949 | void chv_phy_post_pll_disable(struct intel_encoder *encoder, |
950 | const struct intel_crtc_state *old_crtc_state) | ||
954 | { | 951 | { |
955 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 952 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
956 | enum pipe pipe = to_intel_crtc(encoder->base.crtc)->pipe; | 953 | enum pipe pipe = to_intel_crtc(old_crtc_state->base.crtc)->pipe; |
957 | u32 val; | 954 | u32 val; |
958 | 955 | ||
959 | mutex_lock(&dev_priv->sb_lock); | 956 | mutex_lock(&dev_priv->sb_lock); |
@@ -991,7 +988,7 @@ void vlv_set_phy_signal_level(struct intel_encoder *encoder, | |||
991 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); | 988 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
992 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); | 989 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); |
993 | enum dpio_channel port = vlv_dport_to_channel(dport); | 990 | enum dpio_channel port = vlv_dport_to_channel(dport); |
994 | int pipe = intel_crtc->pipe; | 991 | enum pipe pipe = intel_crtc->pipe; |
995 | 992 | ||
996 | mutex_lock(&dev_priv->sb_lock); | 993 | mutex_lock(&dev_priv->sb_lock); |
997 | vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x00000000); | 994 | vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x00000000); |
@@ -1009,15 +1006,14 @@ void vlv_set_phy_signal_level(struct intel_encoder *encoder, | |||
1009 | mutex_unlock(&dev_priv->sb_lock); | 1006 | mutex_unlock(&dev_priv->sb_lock); |
1010 | } | 1007 | } |
1011 | 1008 | ||
1012 | void vlv_phy_pre_pll_enable(struct intel_encoder *encoder) | 1009 | void vlv_phy_pre_pll_enable(struct intel_encoder *encoder, |
1010 | const struct intel_crtc_state *crtc_state) | ||
1013 | { | 1011 | { |
1014 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); | 1012 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); |
1015 | struct drm_device *dev = encoder->base.dev; | 1013 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
1016 | struct drm_i915_private *dev_priv = to_i915(dev); | 1014 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
1017 | struct intel_crtc *intel_crtc = | ||
1018 | to_intel_crtc(encoder->base.crtc); | ||
1019 | enum dpio_channel port = vlv_dport_to_channel(dport); | 1015 | enum dpio_channel port = vlv_dport_to_channel(dport); |
1020 | int pipe = intel_crtc->pipe; | 1016 | enum pipe pipe = crtc->pipe; |
1021 | 1017 | ||
1022 | /* Program Tx lane resets to default */ | 1018 | /* Program Tx lane resets to default */ |
1023 | mutex_lock(&dev_priv->sb_lock); | 1019 | mutex_lock(&dev_priv->sb_lock); |
@@ -1037,15 +1033,15 @@ void vlv_phy_pre_pll_enable(struct intel_encoder *encoder) | |||
1037 | mutex_unlock(&dev_priv->sb_lock); | 1033 | mutex_unlock(&dev_priv->sb_lock); |
1038 | } | 1034 | } |
1039 | 1035 | ||
1040 | void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder) | 1036 | void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder, |
1037 | const struct intel_crtc_state *crtc_state) | ||
1041 | { | 1038 | { |
1042 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 1039 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
1043 | struct intel_digital_port *dport = dp_to_dig_port(intel_dp); | 1040 | struct intel_digital_port *dport = dp_to_dig_port(intel_dp); |
1044 | struct drm_device *dev = encoder->base.dev; | 1041 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
1045 | struct drm_i915_private *dev_priv = to_i915(dev); | 1042 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
1046 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); | ||
1047 | enum dpio_channel port = vlv_dport_to_channel(dport); | 1043 | enum dpio_channel port = vlv_dport_to_channel(dport); |
1048 | int pipe = intel_crtc->pipe; | 1044 | enum pipe pipe = crtc->pipe; |
1049 | u32 val; | 1045 | u32 val; |
1050 | 1046 | ||
1051 | mutex_lock(&dev_priv->sb_lock); | 1047 | mutex_lock(&dev_priv->sb_lock); |
@@ -1067,14 +1063,14 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder) | |||
1067 | mutex_unlock(&dev_priv->sb_lock); | 1063 | mutex_unlock(&dev_priv->sb_lock); |
1068 | } | 1064 | } |
1069 | 1065 | ||
1070 | void vlv_phy_reset_lanes(struct intel_encoder *encoder) | 1066 | void vlv_phy_reset_lanes(struct intel_encoder *encoder, |
1067 | const struct intel_crtc_state *old_crtc_state) | ||
1071 | { | 1068 | { |
1072 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); | 1069 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); |
1073 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 1070 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
1074 | struct intel_crtc *intel_crtc = | 1071 | struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); |
1075 | to_intel_crtc(encoder->base.crtc); | ||
1076 | enum dpio_channel port = vlv_dport_to_channel(dport); | 1072 | enum dpio_channel port = vlv_dport_to_channel(dport); |
1077 | int pipe = intel_crtc->pipe; | 1073 | enum pipe pipe = crtc->pipe; |
1078 | 1074 | ||
1079 | mutex_lock(&dev_priv->sb_lock); | 1075 | mutex_lock(&dev_priv->sb_lock); |
1080 | vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port), 0x00000000); | 1076 | vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port), 0x00000000); |
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index df808a94c511..51c5ae4e9116 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c | |||
@@ -813,15 +813,11 @@ hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, | |||
813 | memset(&crtc_state->dpll_hw_state, 0, | 813 | memset(&crtc_state->dpll_hw_state, 0, |
814 | sizeof(crtc_state->dpll_hw_state)); | 814 | sizeof(crtc_state->dpll_hw_state)); |
815 | 815 | ||
816 | if (encoder->type == INTEL_OUTPUT_HDMI) { | 816 | if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { |
817 | pll = hsw_ddi_hdmi_get_dpll(clock, crtc, crtc_state); | 817 | pll = hsw_ddi_hdmi_get_dpll(clock, crtc, crtc_state); |
818 | 818 | } else if (intel_crtc_has_dp_encoder(crtc_state)) { | |
819 | } else if (encoder->type == INTEL_OUTPUT_DP || | ||
820 | encoder->type == INTEL_OUTPUT_DP_MST || | ||
821 | encoder->type == INTEL_OUTPUT_EDP) { | ||
822 | pll = hsw_ddi_dp_get_dpll(encoder, clock); | 819 | pll = hsw_ddi_dp_get_dpll(encoder, clock); |
823 | 820 | } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) { | |
824 | } else if (encoder->type == INTEL_OUTPUT_ANALOG) { | ||
825 | if (WARN_ON(crtc_state->port_clock / 2 != 135000)) | 821 | if (WARN_ON(crtc_state->port_clock / 2 != 135000)) |
826 | return NULL; | 822 | return NULL; |
827 | 823 | ||
@@ -1369,15 +1365,13 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, | |||
1369 | 1365 | ||
1370 | memset(&dpll_hw_state, 0, sizeof(dpll_hw_state)); | 1366 | memset(&dpll_hw_state, 0, sizeof(dpll_hw_state)); |
1371 | 1367 | ||
1372 | if (encoder->type == INTEL_OUTPUT_HDMI) { | 1368 | if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { |
1373 | bret = skl_ddi_hdmi_pll_dividers(crtc, crtc_state, clock); | 1369 | bret = skl_ddi_hdmi_pll_dividers(crtc, crtc_state, clock); |
1374 | if (!bret) { | 1370 | if (!bret) { |
1375 | DRM_DEBUG_KMS("Could not get HDMI pll dividers.\n"); | 1371 | DRM_DEBUG_KMS("Could not get HDMI pll dividers.\n"); |
1376 | return NULL; | 1372 | return NULL; |
1377 | } | 1373 | } |
1378 | } else if (encoder->type == INTEL_OUTPUT_DP || | 1374 | } else if (intel_crtc_has_dp_encoder(crtc_state)) { |
1379 | encoder->type == INTEL_OUTPUT_DP_MST || | ||
1380 | encoder->type == INTEL_OUTPUT_EDP) { | ||
1381 | bret = skl_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state); | 1375 | bret = skl_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state); |
1382 | if (!bret) { | 1376 | if (!bret) { |
1383 | DRM_DEBUG_KMS("Could not set DP dpll HW state.\n"); | 1377 | DRM_DEBUG_KMS("Could not set DP dpll HW state.\n"); |
@@ -1388,7 +1382,7 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, | |||
1388 | return NULL; | 1382 | return NULL; |
1389 | } | 1383 | } |
1390 | 1384 | ||
1391 | if (encoder->type == INTEL_OUTPUT_EDP) | 1385 | if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) |
1392 | pll = intel_find_shared_dpll(crtc, crtc_state, | 1386 | pll = intel_find_shared_dpll(crtc, crtc_state, |
1393 | DPLL_ID_SKL_DPLL0, | 1387 | DPLL_ID_SKL_DPLL0, |
1394 | DPLL_ID_SKL_DPLL0); | 1388 | DPLL_ID_SKL_DPLL0); |
@@ -1808,18 +1802,15 @@ bxt_get_dpll(struct intel_crtc *crtc, | |||
1808 | { | 1802 | { |
1809 | struct intel_dpll_hw_state dpll_hw_state = { }; | 1803 | struct intel_dpll_hw_state dpll_hw_state = { }; |
1810 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); | 1804 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
1811 | struct intel_digital_port *intel_dig_port; | ||
1812 | struct intel_shared_dpll *pll; | 1805 | struct intel_shared_dpll *pll; |
1813 | int i, clock = crtc_state->port_clock; | 1806 | int i, clock = crtc_state->port_clock; |
1814 | 1807 | ||
1815 | if (encoder->type == INTEL_OUTPUT_HDMI && | 1808 | if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) && |
1816 | !bxt_ddi_hdmi_set_dpll_hw_state(crtc, crtc_state, clock, | 1809 | !bxt_ddi_hdmi_set_dpll_hw_state(crtc, crtc_state, clock, |
1817 | &dpll_hw_state)) | 1810 | &dpll_hw_state)) |
1818 | return NULL; | 1811 | return NULL; |
1819 | 1812 | ||
1820 | if ((encoder->type == INTEL_OUTPUT_DP || | 1813 | if (intel_crtc_has_dp_encoder(crtc_state) && |
1821 | encoder->type == INTEL_OUTPUT_EDP || | ||
1822 | encoder->type == INTEL_OUTPUT_DP_MST) && | ||
1823 | !bxt_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state)) | 1814 | !bxt_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state)) |
1824 | return NULL; | 1815 | return NULL; |
1825 | 1816 | ||
@@ -1828,15 +1819,8 @@ bxt_get_dpll(struct intel_crtc *crtc, | |||
1828 | 1819 | ||
1829 | crtc_state->dpll_hw_state = dpll_hw_state; | 1820 | crtc_state->dpll_hw_state = dpll_hw_state; |
1830 | 1821 | ||
1831 | if (encoder->type == INTEL_OUTPUT_DP_MST) { | ||
1832 | struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); | ||
1833 | |||
1834 | intel_dig_port = intel_mst->primary; | ||
1835 | } else | ||
1836 | intel_dig_port = enc_to_dig_port(&encoder->base); | ||
1837 | |||
1838 | /* 1:1 mapping between ports and PLLs */ | 1822 | /* 1:1 mapping between ports and PLLs */ |
1839 | i = (enum intel_dpll_id) intel_dig_port->port; | 1823 | i = (enum intel_dpll_id) encoder->port; |
1840 | pll = intel_get_shared_dpll_by_id(dev_priv, i); | 1824 | pll = intel_get_shared_dpll_by_id(dev_priv, i); |
1841 | 1825 | ||
1842 | DRM_DEBUG_KMS("[CRTC:%d:%s] using pre-allocated %s\n", | 1826 | DRM_DEBUG_KMS("[CRTC:%d:%s] using pre-allocated %s\n", |
@@ -2008,8 +1992,8 @@ static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv, | |||
2008 | * requirement, follow the Display Voltage Frequency Switching | 1992 | * requirement, follow the Display Voltage Frequency Switching |
2009 | * Sequence Before Frequency Change | 1993 | * Sequence Before Frequency Change |
2010 | * | 1994 | * |
2011 | * FIXME: (DVFS) is used to adjust the display voltage to match the | 1995 | * Note: DVFS is actually handled via the cdclk code paths, |
2012 | * display clock frequencies | 1996 | * hence we do nothing here. |
2013 | */ | 1997 | */ |
2014 | 1998 | ||
2015 | /* 6. Enable DPLL in DPLL_ENABLE. */ | 1999 | /* 6. Enable DPLL in DPLL_ENABLE. */ |
@@ -2030,8 +2014,8 @@ static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv, | |||
2030 | * requirement, follow the Display Voltage Frequency Switching | 2014 | * requirement, follow the Display Voltage Frequency Switching |
2031 | * Sequence After Frequency Change | 2015 | * Sequence After Frequency Change |
2032 | * | 2016 | * |
2033 | * FIXME: (DVFS) is used to adjust the display voltage to match the | 2017 | * Note: DVFS is actually handled via the cdclk code paths, |
2034 | * display clock frequencies | 2018 | * hence we do nothing here. |
2035 | */ | 2019 | */ |
2036 | 2020 | ||
2037 | /* | 2021 | /* |
@@ -2055,8 +2039,8 @@ static void cnl_ddi_pll_disable(struct drm_i915_private *dev_priv, | |||
2055 | * requirement, follow the Display Voltage Frequency Switching | 2039 | * requirement, follow the Display Voltage Frequency Switching |
2056 | * Sequence Before Frequency Change | 2040 | * Sequence Before Frequency Change |
2057 | * | 2041 | * |
2058 | * FIXME: (DVFS) is used to adjust the display voltage to match the | 2042 | * Note: DVFS is actually handled via the cdclk code paths, |
2059 | * display clock frequencies | 2043 | * hence we do nothing here. |
2060 | */ | 2044 | */ |
2061 | 2045 | ||
2062 | /* 3. Disable DPLL through DPLL_ENABLE. */ | 2046 | /* 3. Disable DPLL through DPLL_ENABLE. */ |
@@ -2077,8 +2061,8 @@ static void cnl_ddi_pll_disable(struct drm_i915_private *dev_priv, | |||
2077 | * requirement, follow the Display Voltage Frequency Switching | 2061 | * requirement, follow the Display Voltage Frequency Switching |
2078 | * Sequence After Frequency Change | 2062 | * Sequence After Frequency Change |
2079 | * | 2063 | * |
2080 | * FIXME: (DVFS) is used to adjust the display voltage to match the | 2064 | * Note: DVFS is actually handled via the cdclk code paths, |
2081 | * display clock frequencies | 2065 | * hence we do nothing here. |
2082 | */ | 2066 | */ |
2083 | 2067 | ||
2084 | /* 6. Disable DPLL power in DPLL_ENABLE. */ | 2068 | /* 6. Disable DPLL power in DPLL_ENABLE. */ |
@@ -2126,10 +2110,8 @@ out: | |||
2126 | return ret; | 2110 | return ret; |
2127 | } | 2111 | } |
2128 | 2112 | ||
2129 | static void cnl_wrpll_get_multipliers(unsigned int bestdiv, | 2113 | static void cnl_wrpll_get_multipliers(int bestdiv, int *pdiv, |
2130 | unsigned int *pdiv, | 2114 | int *qdiv, int *kdiv) |
2131 | unsigned int *qdiv, | ||
2132 | unsigned int *kdiv) | ||
2133 | { | 2115 | { |
2134 | /* even dividers */ | 2116 | /* even dividers */ |
2135 | if (bestdiv % 2 == 0) { | 2117 | if (bestdiv % 2 == 0) { |
@@ -2167,10 +2149,12 @@ static void cnl_wrpll_get_multipliers(unsigned int bestdiv, | |||
2167 | } | 2149 | } |
2168 | } | 2150 | } |
2169 | 2151 | ||
2170 | static void cnl_wrpll_params_populate(struct skl_wrpll_params *params, uint32_t dco_freq, | 2152 | static void cnl_wrpll_params_populate(struct skl_wrpll_params *params, |
2171 | uint32_t ref_freq, uint32_t pdiv, uint32_t qdiv, | 2153 | u32 dco_freq, u32 ref_freq, |
2172 | uint32_t kdiv) | 2154 | int pdiv, int qdiv, int kdiv) |
2173 | { | 2155 | { |
2156 | u32 dco; | ||
2157 | |||
2174 | switch (kdiv) { | 2158 | switch (kdiv) { |
2175 | case 1: | 2159 | case 1: |
2176 | params->kdiv = 1; | 2160 | params->kdiv = 1; |
@@ -2202,39 +2186,35 @@ static void cnl_wrpll_params_populate(struct skl_wrpll_params *params, uint32_t | |||
2202 | WARN(1, "Incorrect PDiv\n"); | 2186 | WARN(1, "Incorrect PDiv\n"); |
2203 | } | 2187 | } |
2204 | 2188 | ||
2205 | if (kdiv != 2) | 2189 | WARN_ON(kdiv != 2 && qdiv != 1); |
2206 | qdiv = 1; | ||
2207 | 2190 | ||
2208 | params->qdiv_ratio = qdiv; | 2191 | params->qdiv_ratio = qdiv; |
2209 | params->qdiv_mode = (qdiv == 1) ? 0 : 1; | 2192 | params->qdiv_mode = (qdiv == 1) ? 0 : 1; |
2210 | 2193 | ||
2211 | params->dco_integer = div_u64(dco_freq, ref_freq); | 2194 | dco = div_u64((u64)dco_freq << 15, ref_freq); |
2212 | params->dco_fraction = div_u64((div_u64((uint64_t)dco_freq<<15, (uint64_t)ref_freq) - | 2195 | |
2213 | ((uint64_t)params->dco_integer<<15)) * 0x8000, 0x8000); | 2196 | params->dco_integer = dco >> 15; |
2197 | params->dco_fraction = dco & 0x7fff; | ||
2214 | } | 2198 | } |
2215 | 2199 | ||
2216 | static bool | 2200 | static bool |
2217 | cnl_ddi_calculate_wrpll(int clock /* in Hz */, | 2201 | cnl_ddi_calculate_wrpll(int clock, |
2218 | struct drm_i915_private *dev_priv, | 2202 | struct drm_i915_private *dev_priv, |
2219 | struct skl_wrpll_params *wrpll_params) | 2203 | struct skl_wrpll_params *wrpll_params) |
2220 | { | 2204 | { |
2221 | uint64_t afe_clock = clock * 5 / KHz(1); /* clocks in kHz */ | 2205 | u32 afe_clock = clock * 5; |
2222 | unsigned int dco_min = 7998 * KHz(1); | 2206 | u32 dco_min = 7998000; |
2223 | unsigned int dco_max = 10000 * KHz(1); | 2207 | u32 dco_max = 10000000; |
2224 | unsigned int dco_mid = (dco_min + dco_max) / 2; | 2208 | u32 dco_mid = (dco_min + dco_max) / 2; |
2225 | |||
2226 | static const int dividers[] = { 2, 4, 6, 8, 10, 12, 14, 16, | 2209 | static const int dividers[] = { 2, 4, 6, 8, 10, 12, 14, 16, |
2227 | 18, 20, 24, 28, 30, 32, 36, 40, | 2210 | 18, 20, 24, 28, 30, 32, 36, 40, |
2228 | 42, 44, 48, 50, 52, 54, 56, 60, | 2211 | 42, 44, 48, 50, 52, 54, 56, 60, |
2229 | 64, 66, 68, 70, 72, 76, 78, 80, | 2212 | 64, 66, 68, 70, 72, 76, 78, 80, |
2230 | 84, 88, 90, 92, 96, 98, 100, 102, | 2213 | 84, 88, 90, 92, 96, 98, 100, 102, |
2231 | 3, 5, 7, 9, 15, 21 }; | 2214 | 3, 5, 7, 9, 15, 21 }; |
2232 | unsigned int d, dco; | 2215 | u32 dco, best_dco = 0, dco_centrality = 0; |
2233 | unsigned int dco_centrality = 0; | 2216 | u32 best_dco_centrality = U32_MAX; /* Spec meaning of 999999 MHz */ |
2234 | unsigned int best_dco_centrality = 999999; | 2217 | int d, best_div = 0, pdiv = 0, qdiv = 0, kdiv = 0; |
2235 | unsigned int best_div = 0; | ||
2236 | unsigned int best_dco = 0; | ||
2237 | unsigned int pdiv = 0, qdiv = 0, kdiv = 0; | ||
2238 | 2218 | ||
2239 | for (d = 0; d < ARRAY_SIZE(dividers); d++) { | 2219 | for (d = 0; d < ARRAY_SIZE(dividers); d++) { |
2240 | dco = afe_clock * dividers[d]; | 2220 | dco = afe_clock * dividers[d]; |
@@ -2271,7 +2251,7 @@ static bool cnl_ddi_hdmi_pll_dividers(struct intel_crtc *crtc, | |||
2271 | 2251 | ||
2272 | cfgcr0 = DPLL_CFGCR0_HDMI_MODE; | 2252 | cfgcr0 = DPLL_CFGCR0_HDMI_MODE; |
2273 | 2253 | ||
2274 | if (!cnl_ddi_calculate_wrpll(clock * 1000, dev_priv, &wrpll_params)) | 2254 | if (!cnl_ddi_calculate_wrpll(clock, dev_priv, &wrpll_params)) |
2275 | return false; | 2255 | return false; |
2276 | 2256 | ||
2277 | cfgcr0 |= DPLL_CFGCR0_DCO_FRACTION(wrpll_params.dco_fraction) | | 2257 | cfgcr0 |= DPLL_CFGCR0_DCO_FRACTION(wrpll_params.dco_fraction) | |
@@ -2281,7 +2261,6 @@ static bool cnl_ddi_hdmi_pll_dividers(struct intel_crtc *crtc, | |||
2281 | DPLL_CFGCR1_QDIV_MODE(wrpll_params.qdiv_mode) | | 2261 | DPLL_CFGCR1_QDIV_MODE(wrpll_params.qdiv_mode) | |
2282 | DPLL_CFGCR1_KDIV(wrpll_params.kdiv) | | 2262 | DPLL_CFGCR1_KDIV(wrpll_params.kdiv) | |
2283 | DPLL_CFGCR1_PDIV(wrpll_params.pdiv) | | 2263 | DPLL_CFGCR1_PDIV(wrpll_params.pdiv) | |
2284 | wrpll_params.central_freq | | ||
2285 | DPLL_CFGCR1_CENTRAL_FREQ; | 2264 | DPLL_CFGCR1_CENTRAL_FREQ; |
2286 | 2265 | ||
2287 | memset(&crtc_state->dpll_hw_state, 0, | 2266 | memset(&crtc_state->dpll_hw_state, 0, |
@@ -2345,15 +2324,13 @@ cnl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, | |||
2345 | 2324 | ||
2346 | memset(&dpll_hw_state, 0, sizeof(dpll_hw_state)); | 2325 | memset(&dpll_hw_state, 0, sizeof(dpll_hw_state)); |
2347 | 2326 | ||
2348 | if (encoder->type == INTEL_OUTPUT_HDMI) { | 2327 | if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { |
2349 | bret = cnl_ddi_hdmi_pll_dividers(crtc, crtc_state, clock); | 2328 | bret = cnl_ddi_hdmi_pll_dividers(crtc, crtc_state, clock); |
2350 | if (!bret) { | 2329 | if (!bret) { |
2351 | DRM_DEBUG_KMS("Could not get HDMI pll dividers.\n"); | 2330 | DRM_DEBUG_KMS("Could not get HDMI pll dividers.\n"); |
2352 | return NULL; | 2331 | return NULL; |
2353 | } | 2332 | } |
2354 | } else if (encoder->type == INTEL_OUTPUT_DP || | 2333 | } else if (intel_crtc_has_dp_encoder(crtc_state)) { |
2355 | encoder->type == INTEL_OUTPUT_DP_MST || | ||
2356 | encoder->type == INTEL_OUTPUT_EDP) { | ||
2357 | bret = cnl_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state); | 2334 | bret = cnl_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state); |
2358 | if (!bret) { | 2335 | if (!bret) { |
2359 | DRM_DEBUG_KMS("Could not set DP dpll HW state.\n"); | 2336 | DRM_DEBUG_KMS("Could not set DP dpll HW state.\n"); |
@@ -2361,8 +2338,8 @@ cnl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, | |||
2361 | } | 2338 | } |
2362 | crtc_state->dpll_hw_state = dpll_hw_state; | 2339 | crtc_state->dpll_hw_state = dpll_hw_state; |
2363 | } else { | 2340 | } else { |
2364 | DRM_DEBUG_KMS("Skip DPLL setup for encoder %d\n", | 2341 | DRM_DEBUG_KMS("Skip DPLL setup for output_types 0x%x\n", |
2365 | encoder->type); | 2342 | crtc_state->output_types); |
2366 | return NULL; | 2343 | return NULL; |
2367 | } | 2344 | } |
2368 | 2345 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 6c7f8bca574e..bf8b057f72a6 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -47,14 +47,11 @@ | |||
47 | * contexts. Note that it's important that we check the condition again after | 47 | * contexts. Note that it's important that we check the condition again after |
48 | * having timed out, since the timeout could be due to preemption or similar and | 48 | * having timed out, since the timeout could be due to preemption or similar and |
49 | * we've never had a chance to check the condition before the timeout. | 49 | * we've never had a chance to check the condition before the timeout. |
50 | * | ||
51 | * TODO: When modesetting has fully transitioned to atomic, the below | ||
52 | * drm_can_sleep() can be removed and in_atomic()/!in_atomic() asserts | ||
53 | * added. | ||
54 | */ | 50 | */ |
55 | #define _wait_for(COND, US, W) ({ \ | 51 | #define _wait_for(COND, US, W) ({ \ |
56 | unsigned long timeout__ = jiffies + usecs_to_jiffies(US) + 1; \ | 52 | unsigned long timeout__ = jiffies + usecs_to_jiffies(US) + 1; \ |
57 | int ret__; \ | 53 | int ret__; \ |
54 | might_sleep(); \ | ||
58 | for (;;) { \ | 55 | for (;;) { \ |
59 | bool expired__ = time_after(jiffies, timeout__); \ | 56 | bool expired__ = time_after(jiffies, timeout__); \ |
60 | if (COND) { \ | 57 | if (COND) { \ |
@@ -65,11 +62,7 @@ | |||
65 | ret__ = -ETIMEDOUT; \ | 62 | ret__ = -ETIMEDOUT; \ |
66 | break; \ | 63 | break; \ |
67 | } \ | 64 | } \ |
68 | if ((W) && drm_can_sleep()) { \ | 65 | usleep_range((W), (W) * 2); \ |
69 | usleep_range((W), (W)*2); \ | ||
70 | } else { \ | ||
71 | cpu_relax(); \ | ||
72 | } \ | ||
73 | } \ | 66 | } \ |
74 | ret__; \ | 67 | ret__; \ |
75 | }) | 68 | }) |
@@ -173,7 +166,7 @@ enum intel_output_type { | |||
173 | INTEL_OUTPUT_DP = 7, | 166 | INTEL_OUTPUT_DP = 7, |
174 | INTEL_OUTPUT_EDP = 8, | 167 | INTEL_OUTPUT_EDP = 8, |
175 | INTEL_OUTPUT_DSI = 9, | 168 | INTEL_OUTPUT_DSI = 9, |
176 | INTEL_OUTPUT_UNKNOWN = 10, | 169 | INTEL_OUTPUT_DDI = 10, |
177 | INTEL_OUTPUT_DP_MST = 11, | 170 | INTEL_OUTPUT_DP_MST = 11, |
178 | }; | 171 | }; |
179 | 172 | ||
@@ -216,6 +209,9 @@ struct intel_encoder { | |||
216 | enum port port; | 209 | enum port port; |
217 | unsigned int cloneable; | 210 | unsigned int cloneable; |
218 | void (*hot_plug)(struct intel_encoder *); | 211 | void (*hot_plug)(struct intel_encoder *); |
212 | enum intel_output_type (*compute_output_type)(struct intel_encoder *, | ||
213 | struct intel_crtc_state *, | ||
214 | struct drm_connector_state *); | ||
219 | bool (*compute_config)(struct intel_encoder *, | 215 | bool (*compute_config)(struct intel_encoder *, |
220 | struct intel_crtc_state *, | 216 | struct intel_crtc_state *, |
221 | struct drm_connector_state *); | 217 | struct drm_connector_state *); |
@@ -386,6 +382,8 @@ struct intel_atomic_state { | |||
386 | unsigned int active_crtcs; | 382 | unsigned int active_crtcs; |
387 | /* minimum acceptable cdclk for each pipe */ | 383 | /* minimum acceptable cdclk for each pipe */ |
388 | int min_cdclk[I915_MAX_PIPES]; | 384 | int min_cdclk[I915_MAX_PIPES]; |
385 | /* minimum acceptable voltage level for each pipe */ | ||
386 | u8 min_voltage_level[I915_MAX_PIPES]; | ||
389 | 387 | ||
390 | struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS]; | 388 | struct intel_shared_dpll_state shared_dpll[I915_NUM_PLLS]; |
391 | 389 | ||
@@ -420,6 +418,9 @@ struct intel_plane_state { | |||
420 | /* plane control register */ | 418 | /* plane control register */ |
421 | u32 ctl; | 419 | u32 ctl; |
422 | 420 | ||
421 | /* plane color control register */ | ||
422 | u32 color_ctl; | ||
423 | |||
423 | /* | 424 | /* |
424 | * scaler_id | 425 | * scaler_id |
425 | * = -1 : not using a scaler | 426 | * = -1 : not using a scaler |
@@ -738,6 +739,9 @@ struct intel_crtc_state { | |||
738 | */ | 739 | */ |
739 | uint8_t lane_lat_optim_mask; | 740 | uint8_t lane_lat_optim_mask; |
740 | 741 | ||
742 | /* minimum acceptable voltage level */ | ||
743 | u8 min_voltage_level; | ||
744 | |||
741 | /* Panel fitter controls for gen2-gen4 + VLV */ | 745 | /* Panel fitter controls for gen2-gen4 + VLV */ |
742 | struct { | 746 | struct { |
743 | u32 control; | 747 | u32 control; |
@@ -1048,7 +1052,6 @@ struct intel_lspcon { | |||
1048 | 1052 | ||
1049 | struct intel_digital_port { | 1053 | struct intel_digital_port { |
1050 | struct intel_encoder base; | 1054 | struct intel_encoder base; |
1051 | enum port port; | ||
1052 | u32 saved_port_bits; | 1055 | u32 saved_port_bits; |
1053 | struct intel_dp dp; | 1056 | struct intel_dp dp; |
1054 | struct intel_hdmi hdmi; | 1057 | struct intel_hdmi hdmi; |
@@ -1080,7 +1083,7 @@ struct intel_dp_mst_encoder { | |||
1080 | static inline enum dpio_channel | 1083 | static inline enum dpio_channel |
1081 | vlv_dport_to_channel(struct intel_digital_port *dport) | 1084 | vlv_dport_to_channel(struct intel_digital_port *dport) |
1082 | { | 1085 | { |
1083 | switch (dport->port) { | 1086 | switch (dport->base.port) { |
1084 | case PORT_B: | 1087 | case PORT_B: |
1085 | case PORT_D: | 1088 | case PORT_D: |
1086 | return DPIO_CH0; | 1089 | return DPIO_CH0; |
@@ -1094,7 +1097,7 @@ vlv_dport_to_channel(struct intel_digital_port *dport) | |||
1094 | static inline enum dpio_phy | 1097 | static inline enum dpio_phy |
1095 | vlv_dport_to_phy(struct intel_digital_port *dport) | 1098 | vlv_dport_to_phy(struct intel_digital_port *dport) |
1096 | { | 1099 | { |
1097 | switch (dport->port) { | 1100 | switch (dport->base.port) { |
1098 | case PORT_B: | 1101 | case PORT_B: |
1099 | case PORT_C: | 1102 | case PORT_C: |
1100 | return DPIO_PHY0; | 1103 | return DPIO_PHY0; |
@@ -1147,7 +1150,7 @@ enc_to_dig_port(struct drm_encoder *encoder) | |||
1147 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); | 1150 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); |
1148 | 1151 | ||
1149 | switch (intel_encoder->type) { | 1152 | switch (intel_encoder->type) { |
1150 | case INTEL_OUTPUT_UNKNOWN: | 1153 | case INTEL_OUTPUT_DDI: |
1151 | WARN_ON(!HAS_DDI(to_i915(encoder->dev))); | 1154 | WARN_ON(!HAS_DDI(to_i915(encoder->dev))); |
1152 | case INTEL_OUTPUT_DP: | 1155 | case INTEL_OUTPUT_DP: |
1153 | case INTEL_OUTPUT_EDP: | 1156 | case INTEL_OUTPUT_EDP: |
@@ -1271,7 +1274,6 @@ void intel_ddi_fdi_post_disable(struct intel_encoder *intel_encoder, | |||
1271 | void hsw_fdi_link_train(struct intel_crtc *crtc, | 1274 | void hsw_fdi_link_train(struct intel_crtc *crtc, |
1272 | const struct intel_crtc_state *crtc_state); | 1275 | const struct intel_crtc_state *crtc_state); |
1273 | void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port); | 1276 | void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port); |
1274 | enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder); | ||
1275 | bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe); | 1277 | bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe); |
1276 | void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state); | 1278 | void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state); |
1277 | void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv, | 1279 | void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv, |
@@ -1288,10 +1290,10 @@ bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv, | |||
1288 | void intel_ddi_get_config(struct intel_encoder *encoder, | 1290 | void intel_ddi_get_config(struct intel_encoder *encoder, |
1289 | struct intel_crtc_state *pipe_config); | 1291 | struct intel_crtc_state *pipe_config); |
1290 | 1292 | ||
1291 | void intel_ddi_clock_get(struct intel_encoder *encoder, | ||
1292 | struct intel_crtc_state *pipe_config); | ||
1293 | void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state, | 1293 | void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state, |
1294 | bool state); | 1294 | bool state); |
1295 | void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv, | ||
1296 | struct intel_crtc_state *crtc_state); | ||
1295 | u32 bxt_signal_levels(struct intel_dp *intel_dp); | 1297 | u32 bxt_signal_levels(struct intel_dp *intel_dp); |
1296 | uint32_t ddi_signal_levels(struct intel_dp *intel_dp); | 1298 | uint32_t ddi_signal_levels(struct intel_dp *intel_dp); |
1297 | u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder); | 1299 | u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder); |
@@ -1304,7 +1306,9 @@ void intel_init_audio_hooks(struct drm_i915_private *dev_priv); | |||
1304 | void intel_audio_codec_enable(struct intel_encoder *encoder, | 1306 | void intel_audio_codec_enable(struct intel_encoder *encoder, |
1305 | const struct intel_crtc_state *crtc_state, | 1307 | const struct intel_crtc_state *crtc_state, |
1306 | const struct drm_connector_state *conn_state); | 1308 | const struct drm_connector_state *conn_state); |
1307 | void intel_audio_codec_disable(struct intel_encoder *encoder); | 1309 | void intel_audio_codec_disable(struct intel_encoder *encoder, |
1310 | const struct intel_crtc_state *old_crtc_state, | ||
1311 | const struct drm_connector_state *old_conn_state); | ||
1308 | void i915_audio_component_init(struct drm_i915_private *dev_priv); | 1312 | void i915_audio_component_init(struct drm_i915_private *dev_priv); |
1309 | void i915_audio_component_cleanup(struct drm_i915_private *dev_priv); | 1313 | void i915_audio_component_cleanup(struct drm_i915_private *dev_priv); |
1310 | void intel_audio_init(struct drm_i915_private *dev_priv); | 1314 | void intel_audio_init(struct drm_i915_private *dev_priv); |
@@ -1322,10 +1326,14 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv); | |||
1322 | void intel_update_max_cdclk(struct drm_i915_private *dev_priv); | 1326 | void intel_update_max_cdclk(struct drm_i915_private *dev_priv); |
1323 | void intel_update_cdclk(struct drm_i915_private *dev_priv); | 1327 | void intel_update_cdclk(struct drm_i915_private *dev_priv); |
1324 | void intel_update_rawclk(struct drm_i915_private *dev_priv); | 1328 | void intel_update_rawclk(struct drm_i915_private *dev_priv); |
1325 | bool intel_cdclk_state_compare(const struct intel_cdclk_state *a, | 1329 | bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a, |
1326 | const struct intel_cdclk_state *b); | 1330 | const struct intel_cdclk_state *b); |
1331 | bool intel_cdclk_changed(const struct intel_cdclk_state *a, | ||
1332 | const struct intel_cdclk_state *b); | ||
1327 | void intel_set_cdclk(struct drm_i915_private *dev_priv, | 1333 | void intel_set_cdclk(struct drm_i915_private *dev_priv, |
1328 | const struct intel_cdclk_state *cdclk_state); | 1334 | const struct intel_cdclk_state *cdclk_state); |
1335 | void intel_dump_cdclk_state(const struct intel_cdclk_state *cdclk_state, | ||
1336 | const char *context); | ||
1329 | 1337 | ||
1330 | /* intel_display.c */ | 1338 | /* intel_display.c */ |
1331 | void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe); | 1339 | void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe); |
@@ -1477,8 +1485,8 @@ bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock, | |||
1477 | int chv_calc_dpll_params(int refclk, struct dpll *pll_clock); | 1485 | int chv_calc_dpll_params(int refclk, struct dpll *pll_clock); |
1478 | 1486 | ||
1479 | bool intel_crtc_active(struct intel_crtc *crtc); | 1487 | bool intel_crtc_active(struct intel_crtc *crtc); |
1480 | void hsw_enable_ips(struct intel_crtc *crtc); | 1488 | void hsw_enable_ips(const struct intel_crtc_state *crtc_state); |
1481 | void hsw_disable_ips(struct intel_crtc *crtc); | 1489 | void hsw_disable_ips(const struct intel_crtc_state *crtc_state); |
1482 | enum intel_display_power_domain intel_port_to_power_domain(enum port port); | 1490 | enum intel_display_power_domain intel_port_to_power_domain(enum port port); |
1483 | void intel_mode_from_pipe_config(struct drm_display_mode *mode, | 1491 | void intel_mode_from_pipe_config(struct drm_display_mode *mode, |
1484 | struct intel_crtc_state *pipe_config); | 1492 | struct intel_crtc_state *pipe_config); |
@@ -1491,6 +1499,8 @@ static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state) | |||
1491 | return i915_ggtt_offset(state->vma); | 1499 | return i915_ggtt_offset(state->vma); |
1492 | } | 1500 | } |
1493 | 1501 | ||
1502 | u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, | ||
1503 | const struct intel_plane_state *plane_state); | ||
1494 | u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, | 1504 | u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, |
1495 | const struct intel_plane_state *plane_state); | 1505 | const struct intel_plane_state *plane_state); |
1496 | u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane, | 1506 | u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane, |
@@ -1521,7 +1531,8 @@ void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode); | |||
1521 | void intel_dp_encoder_reset(struct drm_encoder *encoder); | 1531 | void intel_dp_encoder_reset(struct drm_encoder *encoder); |
1522 | void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder); | 1532 | void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder); |
1523 | void intel_dp_encoder_destroy(struct drm_encoder *encoder); | 1533 | void intel_dp_encoder_destroy(struct drm_encoder *encoder); |
1524 | int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc); | 1534 | int intel_dp_sink_crc(struct intel_dp *intel_dp, |
1535 | struct intel_crtc_state *crtc_state, u8 *crc); | ||
1525 | bool intel_dp_compute_config(struct intel_encoder *encoder, | 1536 | bool intel_dp_compute_config(struct intel_encoder *encoder, |
1526 | struct intel_crtc_state *pipe_config, | 1537 | struct intel_crtc_state *pipe_config, |
1527 | struct drm_connector_state *conn_state); | 1538 | struct drm_connector_state *conn_state); |
@@ -1868,7 +1879,6 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv); | |||
1868 | void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv); | 1879 | void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv); |
1869 | void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv); | 1880 | void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv); |
1870 | void intel_enable_gt_powersave(struct drm_i915_private *dev_priv); | 1881 | void intel_enable_gt_powersave(struct drm_i915_private *dev_priv); |
1871 | void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv); | ||
1872 | void intel_disable_gt_powersave(struct drm_i915_private *dev_priv); | 1882 | void intel_disable_gt_powersave(struct drm_i915_private *dev_priv); |
1873 | void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv); | 1883 | void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv); |
1874 | void gen6_rps_busy(struct drm_i915_private *dev_priv); | 1884 | void gen6_rps_busy(struct drm_i915_private *dev_priv); |
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 83f15848098a..f09474b0c4d3 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c | |||
@@ -662,11 +662,11 @@ static void vlv_dsi_clear_device_ready(struct intel_encoder *encoder) | |||
662 | } | 662 | } |
663 | } | 663 | } |
664 | 664 | ||
665 | static void intel_dsi_port_enable(struct intel_encoder *encoder) | 665 | static void intel_dsi_port_enable(struct intel_encoder *encoder, |
666 | const struct intel_crtc_state *crtc_state) | ||
666 | { | 667 | { |
667 | struct drm_device *dev = encoder->base.dev; | 668 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
668 | struct drm_i915_private *dev_priv = to_i915(dev); | 669 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
669 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); | ||
670 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); | 670 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); |
671 | enum port port; | 671 | enum port port; |
672 | 672 | ||
@@ -705,7 +705,7 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder) | |||
705 | if (IS_BROXTON(dev_priv)) | 705 | if (IS_BROXTON(dev_priv)) |
706 | temp |= LANE_CONFIGURATION_DUAL_LINK_A; | 706 | temp |= LANE_CONFIGURATION_DUAL_LINK_A; |
707 | else | 707 | else |
708 | temp |= intel_crtc->pipe ? | 708 | temp |= crtc->pipe ? |
709 | LANE_CONFIGURATION_DUAL_LINK_B : | 709 | LANE_CONFIGURATION_DUAL_LINK_B : |
710 | LANE_CONFIGURATION_DUAL_LINK_A; | 710 | LANE_CONFIGURATION_DUAL_LINK_A; |
711 | } | 711 | } |
@@ -875,7 +875,7 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder, | |||
875 | 875 | ||
876 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON); | 876 | intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON); |
877 | 877 | ||
878 | intel_dsi_port_enable(encoder); | 878 | intel_dsi_port_enable(encoder, pipe_config); |
879 | } | 879 | } |
880 | 880 | ||
881 | intel_panel_enable_backlight(pipe_config, conn_state); | 881 | intel_panel_enable_backlight(pipe_config, conn_state); |
@@ -1082,7 +1082,7 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder, | |||
1082 | struct drm_display_mode *adjusted_mode = | 1082 | struct drm_display_mode *adjusted_mode = |
1083 | &pipe_config->base.adjusted_mode; | 1083 | &pipe_config->base.adjusted_mode; |
1084 | struct drm_display_mode *adjusted_mode_sw; | 1084 | struct drm_display_mode *adjusted_mode_sw; |
1085 | struct intel_crtc *intel_crtc; | 1085 | struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc); |
1086 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); | 1086 | struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); |
1087 | unsigned int lane_count = intel_dsi->lane_count; | 1087 | unsigned int lane_count = intel_dsi->lane_count; |
1088 | unsigned int bpp, fmt; | 1088 | unsigned int bpp, fmt; |
@@ -1093,8 +1093,7 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder, | |||
1093 | crtc_hblank_start_sw, crtc_hblank_end_sw; | 1093 | crtc_hblank_start_sw, crtc_hblank_end_sw; |
1094 | 1094 | ||
1095 | /* FIXME: hw readout should not depend on SW state */ | 1095 | /* FIXME: hw readout should not depend on SW state */ |
1096 | intel_crtc = to_intel_crtc(encoder->base.crtc); | 1096 | adjusted_mode_sw = &crtc->config->base.adjusted_mode; |
1097 | adjusted_mode_sw = &intel_crtc->config->base.adjusted_mode; | ||
1098 | 1097 | ||
1099 | /* | 1098 | /* |
1100 | * Atleast one port is active as encoder->get_config called only if | 1099 | * Atleast one port is active as encoder->get_config called only if |
@@ -1243,6 +1242,8 @@ static void intel_dsi_get_config(struct intel_encoder *encoder, | |||
1243 | u32 pclk; | 1242 | u32 pclk; |
1244 | DRM_DEBUG_KMS("\n"); | 1243 | DRM_DEBUG_KMS("\n"); |
1245 | 1244 | ||
1245 | pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI); | ||
1246 | |||
1246 | if (IS_GEN9_LP(dev_priv)) | 1247 | if (IS_GEN9_LP(dev_priv)) |
1247 | bxt_dsi_get_pipe_config(encoder, pipe_config); | 1248 | bxt_dsi_get_pipe_config(encoder, pipe_config); |
1248 | 1249 | ||
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 53c9b763f4ce..754baa00bea9 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -159,6 +159,8 @@ static void intel_dvo_get_config(struct intel_encoder *encoder, | |||
159 | struct intel_dvo *intel_dvo = enc_to_dvo(encoder); | 159 | struct intel_dvo *intel_dvo = enc_to_dvo(encoder); |
160 | u32 tmp, flags = 0; | 160 | u32 tmp, flags = 0; |
161 | 161 | ||
162 | pipe_config->output_types |= BIT(INTEL_OUTPUT_DVO); | ||
163 | |||
162 | tmp = I915_READ(intel_dvo->dev.dvo_reg); | 164 | tmp = I915_READ(intel_dvo->dev.dvo_reg); |
163 | if (tmp & DVO_HSYNC_ACTIVE_HIGH) | 165 | if (tmp & DVO_HSYNC_ACTIVE_HIGH) |
164 | flags |= DRM_MODE_FLAG_PHSYNC; | 166 | flags |= DRM_MODE_FLAG_PHSYNC; |
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index ab5bf4e2e28e..9897c7f78c51 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c | |||
@@ -50,6 +50,8 @@ struct engine_class_info { | |||
50 | const char *name; | 50 | const char *name; |
51 | int (*init_legacy)(struct intel_engine_cs *engine); | 51 | int (*init_legacy)(struct intel_engine_cs *engine); |
52 | int (*init_execlists)(struct intel_engine_cs *engine); | 52 | int (*init_execlists)(struct intel_engine_cs *engine); |
53 | |||
54 | u8 uabi_class; | ||
53 | }; | 55 | }; |
54 | 56 | ||
55 | static const struct engine_class_info intel_engine_classes[] = { | 57 | static const struct engine_class_info intel_engine_classes[] = { |
@@ -57,21 +59,25 @@ static const struct engine_class_info intel_engine_classes[] = { | |||
57 | .name = "rcs", | 59 | .name = "rcs", |
58 | .init_execlists = logical_render_ring_init, | 60 | .init_execlists = logical_render_ring_init, |
59 | .init_legacy = intel_init_render_ring_buffer, | 61 | .init_legacy = intel_init_render_ring_buffer, |
62 | .uabi_class = I915_ENGINE_CLASS_RENDER, | ||
60 | }, | 63 | }, |
61 | [COPY_ENGINE_CLASS] = { | 64 | [COPY_ENGINE_CLASS] = { |
62 | .name = "bcs", | 65 | .name = "bcs", |
63 | .init_execlists = logical_xcs_ring_init, | 66 | .init_execlists = logical_xcs_ring_init, |
64 | .init_legacy = intel_init_blt_ring_buffer, | 67 | .init_legacy = intel_init_blt_ring_buffer, |
68 | .uabi_class = I915_ENGINE_CLASS_COPY, | ||
65 | }, | 69 | }, |
66 | [VIDEO_DECODE_CLASS] = { | 70 | [VIDEO_DECODE_CLASS] = { |
67 | .name = "vcs", | 71 | .name = "vcs", |
68 | .init_execlists = logical_xcs_ring_init, | 72 | .init_execlists = logical_xcs_ring_init, |
69 | .init_legacy = intel_init_bsd_ring_buffer, | 73 | .init_legacy = intel_init_bsd_ring_buffer, |
74 | .uabi_class = I915_ENGINE_CLASS_VIDEO, | ||
70 | }, | 75 | }, |
71 | [VIDEO_ENHANCEMENT_CLASS] = { | 76 | [VIDEO_ENHANCEMENT_CLASS] = { |
72 | .name = "vecs", | 77 | .name = "vecs", |
73 | .init_execlists = logical_xcs_ring_init, | 78 | .init_execlists = logical_xcs_ring_init, |
74 | .init_legacy = intel_init_vebox_ring_buffer, | 79 | .init_legacy = intel_init_vebox_ring_buffer, |
80 | .uabi_class = I915_ENGINE_CLASS_VIDEO_ENHANCE, | ||
75 | }, | 81 | }, |
76 | }; | 82 | }; |
77 | 83 | ||
@@ -213,13 +219,15 @@ intel_engine_setup(struct drm_i915_private *dev_priv, | |||
213 | WARN_ON(snprintf(engine->name, sizeof(engine->name), "%s%u", | 219 | WARN_ON(snprintf(engine->name, sizeof(engine->name), "%s%u", |
214 | class_info->name, info->instance) >= | 220 | class_info->name, info->instance) >= |
215 | sizeof(engine->name)); | 221 | sizeof(engine->name)); |
216 | engine->uabi_id = info->uabi_id; | ||
217 | engine->hw_id = engine->guc_id = info->hw_id; | 222 | engine->hw_id = engine->guc_id = info->hw_id; |
218 | engine->mmio_base = info->mmio_base; | 223 | engine->mmio_base = info->mmio_base; |
219 | engine->irq_shift = info->irq_shift; | 224 | engine->irq_shift = info->irq_shift; |
220 | engine->class = info->class; | 225 | engine->class = info->class; |
221 | engine->instance = info->instance; | 226 | engine->instance = info->instance; |
222 | 227 | ||
228 | engine->uabi_id = info->uabi_id; | ||
229 | engine->uabi_class = class_info->uabi_class; | ||
230 | |||
223 | engine->context_size = __intel_engine_context_size(dev_priv, | 231 | engine->context_size = __intel_engine_context_size(dev_priv, |
224 | engine->class); | 232 | engine->class); |
225 | if (WARN_ON(engine->context_size > BIT(20))) | 233 | if (WARN_ON(engine->context_size > BIT(20))) |
@@ -281,6 +289,8 @@ int intel_engines_init_mmio(struct drm_i915_private *dev_priv) | |||
281 | 289 | ||
282 | device_info->num_rings = hweight32(mask); | 290 | device_info->num_rings = hweight32(mask); |
283 | 291 | ||
292 | i915_check_and_clear_faults(dev_priv); | ||
293 | |||
284 | return 0; | 294 | return 0; |
285 | 295 | ||
286 | cleanup: | 296 | cleanup: |
@@ -620,7 +630,7 @@ int intel_engine_init_common(struct intel_engine_cs *engine) | |||
620 | * Similarly the preempt context must always be available so that | 630 | * Similarly the preempt context must always be available so that |
621 | * we can interrupt the engine at any time. | 631 | * we can interrupt the engine at any time. |
622 | */ | 632 | */ |
623 | if (INTEL_INFO(engine->i915)->has_logical_ring_preemption) { | 633 | if (HAS_LOGICAL_RING_PREEMPTION(engine->i915)) { |
624 | ring = engine->context_pin(engine, | 634 | ring = engine->context_pin(engine, |
625 | engine->i915->preempt_context); | 635 | engine->i915->preempt_context); |
626 | if (IS_ERR(ring)) { | 636 | if (IS_ERR(ring)) { |
@@ -633,25 +643,19 @@ int intel_engine_init_common(struct intel_engine_cs *engine) | |||
633 | if (ret) | 643 | if (ret) |
634 | goto err_unpin_preempt; | 644 | goto err_unpin_preempt; |
635 | 645 | ||
636 | ret = i915_gem_render_state_init(engine); | ||
637 | if (ret) | ||
638 | goto err_breadcrumbs; | ||
639 | |||
640 | if (HWS_NEEDS_PHYSICAL(engine->i915)) | 646 | if (HWS_NEEDS_PHYSICAL(engine->i915)) |
641 | ret = init_phys_status_page(engine); | 647 | ret = init_phys_status_page(engine); |
642 | else | 648 | else |
643 | ret = init_status_page(engine); | 649 | ret = init_status_page(engine); |
644 | if (ret) | 650 | if (ret) |
645 | goto err_rs_fini; | 651 | goto err_breadcrumbs; |
646 | 652 | ||
647 | return 0; | 653 | return 0; |
648 | 654 | ||
649 | err_rs_fini: | ||
650 | i915_gem_render_state_fini(engine); | ||
651 | err_breadcrumbs: | 655 | err_breadcrumbs: |
652 | intel_engine_fini_breadcrumbs(engine); | 656 | intel_engine_fini_breadcrumbs(engine); |
653 | err_unpin_preempt: | 657 | err_unpin_preempt: |
654 | if (INTEL_INFO(engine->i915)->has_logical_ring_preemption) | 658 | if (HAS_LOGICAL_RING_PREEMPTION(engine->i915)) |
655 | engine->context_unpin(engine, engine->i915->preempt_context); | 659 | engine->context_unpin(engine, engine->i915->preempt_context); |
656 | err_unpin_kernel: | 660 | err_unpin_kernel: |
657 | engine->context_unpin(engine, engine->i915->kernel_context); | 661 | engine->context_unpin(engine, engine->i915->kernel_context); |
@@ -674,12 +678,14 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine) | |||
674 | else | 678 | else |
675 | cleanup_status_page(engine); | 679 | cleanup_status_page(engine); |
676 | 680 | ||
677 | i915_gem_render_state_fini(engine); | ||
678 | intel_engine_fini_breadcrumbs(engine); | 681 | intel_engine_fini_breadcrumbs(engine); |
679 | intel_engine_cleanup_cmd_parser(engine); | 682 | intel_engine_cleanup_cmd_parser(engine); |
680 | i915_gem_batch_pool_fini(&engine->batch_pool); | 683 | i915_gem_batch_pool_fini(&engine->batch_pool); |
681 | 684 | ||
682 | if (INTEL_INFO(engine->i915)->has_logical_ring_preemption) | 685 | if (engine->default_state) |
686 | i915_gem_object_put(engine->default_state); | ||
687 | |||
688 | if (HAS_LOGICAL_RING_PREEMPTION(engine->i915)) | ||
683 | engine->context_unpin(engine, engine->i915->preempt_context); | 689 | engine->context_unpin(engine, engine->i915->preempt_context); |
684 | engine->context_unpin(engine, engine->i915->kernel_context); | 690 | engine->context_unpin(engine, engine->i915->kernel_context); |
685 | } | 691 | } |
@@ -1014,22 +1020,6 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine) | |||
1014 | WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, | 1020 | WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, |
1015 | GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC); | 1021 | GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC); |
1016 | 1022 | ||
1017 | /* WaDisableDgMirrorFixInHalfSliceChicken5:bxt */ | ||
1018 | if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) | ||
1019 | WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, | ||
1020 | GEN9_DG_MIRROR_FIX_ENABLE); | ||
1021 | |||
1022 | /* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:bxt */ | ||
1023 | if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) { | ||
1024 | WA_SET_BIT_MASKED(GEN7_COMMON_SLICE_CHICKEN1, | ||
1025 | GEN9_RHWO_OPTIMIZATION_DISABLE); | ||
1026 | /* | ||
1027 | * WA also requires GEN9_SLICE_COMMON_ECO_CHICKEN0[14:14] to be set | ||
1028 | * but we do that in per ctx batchbuffer as there is an issue | ||
1029 | * with this register not getting restored on ctx restore | ||
1030 | */ | ||
1031 | } | ||
1032 | |||
1033 | /* WaEnableYV12BugFixInHalfSliceChicken7:skl,bxt,kbl,glk,cfl */ | 1023 | /* WaEnableYV12BugFixInHalfSliceChicken7:skl,bxt,kbl,glk,cfl */ |
1034 | /* WaEnableSamplerGPGPUPreemptionSupport:skl,bxt,kbl,cfl */ | 1024 | /* WaEnableSamplerGPGPUPreemptionSupport:skl,bxt,kbl,cfl */ |
1035 | WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7, | 1025 | WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7, |
@@ -1045,11 +1035,6 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine) | |||
1045 | WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, | 1035 | WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, |
1046 | GEN9_CCS_TLB_PREFETCH_ENABLE); | 1036 | GEN9_CCS_TLB_PREFETCH_ENABLE); |
1047 | 1037 | ||
1048 | /* WaDisableMaskBasedCammingInRCC:bxt */ | ||
1049 | if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) | ||
1050 | WA_SET_BIT_MASKED(SLICE_ECO_CHICKEN0, | ||
1051 | PIXEL_MASK_CAMMING_DISABLE); | ||
1052 | |||
1053 | /* WaForceContextSaveRestoreNonCoherent:skl,bxt,kbl,cfl */ | 1038 | /* WaForceContextSaveRestoreNonCoherent:skl,bxt,kbl,cfl */ |
1054 | WA_SET_BIT_MASKED(HDC_CHICKEN0, | 1039 | WA_SET_BIT_MASKED(HDC_CHICKEN0, |
1055 | HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT | | 1040 | HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT | |
@@ -1079,8 +1064,7 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine) | |||
1079 | /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl,cfl */ | 1064 | /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl,cfl */ |
1080 | if (IS_SKYLAKE(dev_priv) || | 1065 | if (IS_SKYLAKE(dev_priv) || |
1081 | IS_KABYLAKE(dev_priv) || | 1066 | IS_KABYLAKE(dev_priv) || |
1082 | IS_COFFEELAKE(dev_priv) || | 1067 | IS_COFFEELAKE(dev_priv)) |
1083 | IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0)) | ||
1084 | WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, | 1068 | WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, |
1085 | GEN8_SAMPLER_POWER_BYPASS_DIS); | 1069 | GEN8_SAMPLER_POWER_BYPASS_DIS); |
1086 | 1070 | ||
@@ -1204,72 +1188,35 @@ static int skl_init_workarounds(struct intel_engine_cs *engine) | |||
1204 | static int bxt_init_workarounds(struct intel_engine_cs *engine) | 1188 | static int bxt_init_workarounds(struct intel_engine_cs *engine) |
1205 | { | 1189 | { |
1206 | struct drm_i915_private *dev_priv = engine->i915; | 1190 | struct drm_i915_private *dev_priv = engine->i915; |
1191 | u32 val; | ||
1207 | int ret; | 1192 | int ret; |
1208 | 1193 | ||
1209 | ret = gen9_init_workarounds(engine); | 1194 | ret = gen9_init_workarounds(engine); |
1210 | if (ret) | 1195 | if (ret) |
1211 | return ret; | 1196 | return ret; |
1212 | 1197 | ||
1213 | /* WaStoreMultiplePTEenable:bxt */ | ||
1214 | /* This is a requirement according to Hardware specification */ | ||
1215 | if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) | ||
1216 | I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF); | ||
1217 | |||
1218 | /* WaSetClckGatingDisableMedia:bxt */ | ||
1219 | if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) { | ||
1220 | I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) & | ||
1221 | ~GEN8_DOP_CLOCK_GATE_MEDIA_ENABLE)); | ||
1222 | } | ||
1223 | |||
1224 | /* WaDisableThreadStallDopClockGating:bxt */ | 1198 | /* WaDisableThreadStallDopClockGating:bxt */ |
1225 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, | 1199 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, |
1226 | STALL_DOP_GATING_DISABLE); | 1200 | STALL_DOP_GATING_DISABLE); |
1227 | 1201 | ||
1228 | /* WaDisablePooledEuLoadBalancingFix:bxt */ | 1202 | /* WaDisablePooledEuLoadBalancingFix:bxt */ |
1229 | if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER)) { | 1203 | I915_WRITE(FF_SLICE_CS_CHICKEN2, |
1230 | I915_WRITE(FF_SLICE_CS_CHICKEN2, | 1204 | _MASKED_BIT_ENABLE(GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE)); |
1231 | _MASKED_BIT_ENABLE(GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE)); | ||
1232 | } | ||
1233 | |||
1234 | /* WaDisableSbeCacheDispatchPortSharing:bxt */ | ||
1235 | if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0)) { | ||
1236 | WA_SET_BIT_MASKED( | ||
1237 | GEN7_HALF_SLICE_CHICKEN1, | ||
1238 | GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); | ||
1239 | } | ||
1240 | |||
1241 | /* WaDisableObjectLevelPreemptionForTrifanOrPolygon:bxt */ | ||
1242 | /* WaDisableObjectLevelPreemptionForInstancedDraw:bxt */ | ||
1243 | /* WaDisableObjectLevelPreemtionForInstanceId:bxt */ | ||
1244 | /* WaDisableLSQCROPERFforOCL:bxt */ | ||
1245 | if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) { | ||
1246 | ret = wa_ring_whitelist_reg(engine, GEN9_CS_DEBUG_MODE1); | ||
1247 | if (ret) | ||
1248 | return ret; | ||
1249 | |||
1250 | ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4); | ||
1251 | if (ret) | ||
1252 | return ret; | ||
1253 | } | ||
1254 | 1205 | ||
1255 | /* WaProgramL3SqcReg1DefaultForPerf:bxt */ | 1206 | /* WaProgramL3SqcReg1DefaultForPerf:bxt */ |
1256 | if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER)) { | 1207 | val = I915_READ(GEN8_L3SQCREG1); |
1257 | u32 val = I915_READ(GEN8_L3SQCREG1); | 1208 | val &= ~L3_PRIO_CREDITS_MASK; |
1258 | val &= ~L3_PRIO_CREDITS_MASK; | 1209 | val |= L3_GENERAL_PRIO_CREDITS(62) | L3_HIGH_PRIO_CREDITS(2); |
1259 | val |= L3_GENERAL_PRIO_CREDITS(62) | L3_HIGH_PRIO_CREDITS(2); | 1210 | I915_WRITE(GEN8_L3SQCREG1, val); |
1260 | I915_WRITE(GEN8_L3SQCREG1, val); | ||
1261 | } | ||
1262 | 1211 | ||
1263 | /* WaToEnableHwFixForPushConstHWBug:bxt */ | 1212 | /* WaToEnableHwFixForPushConstHWBug:bxt */ |
1264 | if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER)) | 1213 | WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, |
1265 | WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, | 1214 | GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); |
1266 | GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); | ||
1267 | 1215 | ||
1268 | /* WaInPlaceDecompressionHang:bxt */ | 1216 | /* WaInPlaceDecompressionHang:bxt */ |
1269 | if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER)) | 1217 | I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, |
1270 | I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, | 1218 | (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | |
1271 | (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | | 1219 | GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS)); |
1272 | GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS)); | ||
1273 | 1220 | ||
1274 | return 0; | 1221 | return 0; |
1275 | } | 1222 | } |
@@ -1585,6 +1532,34 @@ bool intel_engines_are_idle(struct drm_i915_private *dev_priv) | |||
1585 | return true; | 1532 | return true; |
1586 | } | 1533 | } |
1587 | 1534 | ||
1535 | /** | ||
1536 | * intel_engine_has_kernel_context: | ||
1537 | * @engine: the engine | ||
1538 | * | ||
1539 | * Returns true if the last context to be executed on this engine, or has been | ||
1540 | * executed if the engine is already idle, is the kernel context | ||
1541 | * (#i915.kernel_context). | ||
1542 | */ | ||
1543 | bool intel_engine_has_kernel_context(const struct intel_engine_cs *engine) | ||
1544 | { | ||
1545 | const struct i915_gem_context * const kernel_context = | ||
1546 | engine->i915->kernel_context; | ||
1547 | struct drm_i915_gem_request *rq; | ||
1548 | |||
1549 | lockdep_assert_held(&engine->i915->drm.struct_mutex); | ||
1550 | |||
1551 | /* | ||
1552 | * Check the last context seen by the engine. If active, it will be | ||
1553 | * the last request that remains in the timeline. When idle, it is | ||
1554 | * the last executed context as tracked by retirement. | ||
1555 | */ | ||
1556 | rq = __i915_gem_active_peek(&engine->timeline->last_request); | ||
1557 | if (rq) | ||
1558 | return rq->ctx == kernel_context; | ||
1559 | else | ||
1560 | return engine->last_retired_context == kernel_context; | ||
1561 | } | ||
1562 | |||
1588 | void intel_engines_reset_default_submission(struct drm_i915_private *i915) | 1563 | void intel_engines_reset_default_submission(struct drm_i915_private *i915) |
1589 | { | 1564 | { |
1590 | struct intel_engine_cs *engine; | 1565 | struct intel_engine_cs *engine; |
@@ -1594,19 +1569,63 @@ void intel_engines_reset_default_submission(struct drm_i915_private *i915) | |||
1594 | engine->set_default_submission(engine); | 1569 | engine->set_default_submission(engine); |
1595 | } | 1570 | } |
1596 | 1571 | ||
1597 | void intel_engines_mark_idle(struct drm_i915_private *i915) | 1572 | /** |
1573 | * intel_engines_park: called when the GT is transitioning from busy->idle | ||
1574 | * @i915: the i915 device | ||
1575 | * | ||
1576 | * The GT is now idle and about to go to sleep (maybe never to wake again?). | ||
1577 | * Time for us to tidy and put away our toys (release resources back to the | ||
1578 | * system). | ||
1579 | */ | ||
1580 | void intel_engines_park(struct drm_i915_private *i915) | ||
1598 | { | 1581 | { |
1599 | struct intel_engine_cs *engine; | 1582 | struct intel_engine_cs *engine; |
1600 | enum intel_engine_id id; | 1583 | enum intel_engine_id id; |
1601 | 1584 | ||
1602 | for_each_engine(engine, i915, id) { | 1585 | for_each_engine(engine, i915, id) { |
1586 | /* Flush the residual irq tasklets first. */ | ||
1603 | intel_engine_disarm_breadcrumbs(engine); | 1587 | intel_engine_disarm_breadcrumbs(engine); |
1588 | tasklet_kill(&engine->execlists.tasklet); | ||
1589 | |||
1590 | /* | ||
1591 | * We are committed now to parking the engines, make sure there | ||
1592 | * will be no more interrupts arriving later and the engines | ||
1593 | * are truly idle. | ||
1594 | */ | ||
1595 | if (wait_for(intel_engine_is_idle(engine), 10)) { | ||
1596 | struct drm_printer p = drm_debug_printer(__func__); | ||
1597 | |||
1598 | dev_err(i915->drm.dev, | ||
1599 | "%s is not idle before parking\n", | ||
1600 | engine->name); | ||
1601 | intel_engine_dump(engine, &p); | ||
1602 | } | ||
1603 | |||
1604 | if (engine->park) | ||
1605 | engine->park(engine); | ||
1606 | |||
1604 | i915_gem_batch_pool_fini(&engine->batch_pool); | 1607 | i915_gem_batch_pool_fini(&engine->batch_pool); |
1605 | tasklet_kill(&engine->execlists.irq_tasklet); | ||
1606 | engine->execlists.no_priolist = false; | 1608 | engine->execlists.no_priolist = false; |
1607 | } | 1609 | } |
1608 | } | 1610 | } |
1609 | 1611 | ||
1612 | /** | ||
1613 | * intel_engines_unpark: called when the GT is transitioning from idle->busy | ||
1614 | * @i915: the i915 device | ||
1615 | * | ||
1616 | * The GT was idle and now about to fire up with some new user requests. | ||
1617 | */ | ||
1618 | void intel_engines_unpark(struct drm_i915_private *i915) | ||
1619 | { | ||
1620 | struct intel_engine_cs *engine; | ||
1621 | enum intel_engine_id id; | ||
1622 | |||
1623 | for_each_engine(engine, i915, id) { | ||
1624 | if (engine->unpark) | ||
1625 | engine->unpark(engine); | ||
1626 | } | ||
1627 | } | ||
1628 | |||
1610 | bool intel_engine_can_store_dword(struct intel_engine_cs *engine) | 1629 | bool intel_engine_can_store_dword(struct intel_engine_cs *engine) |
1611 | { | 1630 | { |
1612 | switch (INTEL_GEN(engine->i915)) { | 1631 | switch (INTEL_GEN(engine->i915)) { |
@@ -1622,6 +1641,20 @@ bool intel_engine_can_store_dword(struct intel_engine_cs *engine) | |||
1622 | } | 1641 | } |
1623 | } | 1642 | } |
1624 | 1643 | ||
1644 | unsigned int intel_engines_has_context_isolation(struct drm_i915_private *i915) | ||
1645 | { | ||
1646 | struct intel_engine_cs *engine; | ||
1647 | enum intel_engine_id id; | ||
1648 | unsigned int which; | ||
1649 | |||
1650 | which = 0; | ||
1651 | for_each_engine(engine, i915, id) | ||
1652 | if (engine->default_state) | ||
1653 | which |= BIT(engine->uabi_class); | ||
1654 | |||
1655 | return which; | ||
1656 | } | ||
1657 | |||
1625 | static void print_request(struct drm_printer *m, | 1658 | static void print_request(struct drm_printer *m, |
1626 | struct drm_i915_gem_request *rq, | 1659 | struct drm_i915_gem_request *rq, |
1627 | const char *prefix) | 1660 | const char *prefix) |
@@ -1688,9 +1721,14 @@ void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *m) | |||
1688 | drm_printf(m, "\tRING_TAIL: 0x%08x [0x%08x]\n", | 1721 | drm_printf(m, "\tRING_TAIL: 0x%08x [0x%08x]\n", |
1689 | I915_READ(RING_TAIL(engine->mmio_base)) & TAIL_ADDR, | 1722 | I915_READ(RING_TAIL(engine->mmio_base)) & TAIL_ADDR, |
1690 | rq ? rq->ring->tail : 0); | 1723 | rq ? rq->ring->tail : 0); |
1691 | drm_printf(m, "\tRING_CTL: 0x%08x [%s]\n", | 1724 | drm_printf(m, "\tRING_CTL: 0x%08x%s\n", |
1692 | I915_READ(RING_CTL(engine->mmio_base)), | 1725 | I915_READ(RING_CTL(engine->mmio_base)), |
1693 | I915_READ(RING_CTL(engine->mmio_base)) & (RING_WAIT | RING_WAIT_SEMAPHORE) ? "waiting" : ""); | 1726 | I915_READ(RING_CTL(engine->mmio_base)) & (RING_WAIT | RING_WAIT_SEMAPHORE) ? " [waiting]" : ""); |
1727 | if (INTEL_GEN(engine->i915) > 2) { | ||
1728 | drm_printf(m, "\tRING_MODE: 0x%08x%s\n", | ||
1729 | I915_READ(RING_MI_MODE(engine->mmio_base)), | ||
1730 | I915_READ(RING_MI_MODE(engine->mmio_base)) & (MODE_IDLE) ? " [idle]" : ""); | ||
1731 | } | ||
1694 | 1732 | ||
1695 | rcu_read_unlock(); | 1733 | rcu_read_unlock(); |
1696 | 1734 | ||
@@ -1781,6 +1819,7 @@ void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *m) | |||
1781 | } | 1819 | } |
1782 | spin_unlock_irq(&b->rb_lock); | 1820 | spin_unlock_irq(&b->rb_lock); |
1783 | 1821 | ||
1822 | drm_printf(m, "Idle? %s\n", yesno(intel_engine_is_idle(engine))); | ||
1784 | drm_printf(m, "\n"); | 1823 | drm_printf(m, "\n"); |
1785 | } | 1824 | } |
1786 | 1825 | ||
diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c index 10037c0fdf95..823d0c2e9ad2 100644 --- a/drivers/gpu/drm/i915/intel_guc.c +++ b/drivers/gpu/drm/i915/intel_guc.c | |||
@@ -23,6 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "intel_guc.h" | 25 | #include "intel_guc.h" |
26 | #include "intel_guc_submission.h" | ||
26 | #include "i915_drv.h" | 27 | #include "i915_drv.h" |
27 | 28 | ||
28 | static void gen8_guc_raise_irq(struct intel_guc *guc) | 29 | static void gen8_guc_raise_irq(struct intel_guc *guc) |
@@ -268,7 +269,6 @@ int intel_guc_auth_huc(struct intel_guc *guc, u32 rsa_offset) | |||
268 | int intel_guc_suspend(struct drm_i915_private *dev_priv) | 269 | int intel_guc_suspend(struct drm_i915_private *dev_priv) |
269 | { | 270 | { |
270 | struct intel_guc *guc = &dev_priv->guc; | 271 | struct intel_guc *guc = &dev_priv->guc; |
271 | struct i915_gem_context *ctx; | ||
272 | u32 data[3]; | 272 | u32 data[3]; |
273 | 273 | ||
274 | if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) | 274 | if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) |
@@ -276,14 +276,33 @@ int intel_guc_suspend(struct drm_i915_private *dev_priv) | |||
276 | 276 | ||
277 | gen9_disable_guc_interrupts(dev_priv); | 277 | gen9_disable_guc_interrupts(dev_priv); |
278 | 278 | ||
279 | ctx = dev_priv->kernel_context; | ||
280 | |||
281 | data[0] = INTEL_GUC_ACTION_ENTER_S_STATE; | 279 | data[0] = INTEL_GUC_ACTION_ENTER_S_STATE; |
282 | /* any value greater than GUC_POWER_D0 */ | 280 | /* any value greater than GUC_POWER_D0 */ |
283 | data[1] = GUC_POWER_D1; | 281 | data[1] = GUC_POWER_D1; |
284 | /* first page is shared data with GuC */ | 282 | data[2] = guc_ggtt_offset(guc->shared_data); |
285 | data[2] = guc_ggtt_offset(ctx->engine[RCS].state) + | 283 | |
286 | LRC_GUCSHR_PN * PAGE_SIZE; | 284 | return intel_guc_send(guc, data, ARRAY_SIZE(data)); |
285 | } | ||
286 | |||
287 | /** | ||
288 | * intel_guc_reset_engine() - ask GuC to reset an engine | ||
289 | * @guc: intel_guc structure | ||
290 | * @engine: engine to be reset | ||
291 | */ | ||
292 | int intel_guc_reset_engine(struct intel_guc *guc, | ||
293 | struct intel_engine_cs *engine) | ||
294 | { | ||
295 | u32 data[7]; | ||
296 | |||
297 | GEM_BUG_ON(!guc->execbuf_client); | ||
298 | |||
299 | data[0] = INTEL_GUC_ACTION_REQUEST_ENGINE_RESET; | ||
300 | data[1] = engine->guc_id; | ||
301 | data[2] = 0; | ||
302 | data[3] = 0; | ||
303 | data[4] = 0; | ||
304 | data[5] = guc->execbuf_client->stage_id; | ||
305 | data[6] = guc_ggtt_offset(guc->shared_data); | ||
287 | 306 | ||
288 | return intel_guc_send(guc, data, ARRAY_SIZE(data)); | 307 | return intel_guc_send(guc, data, ARRAY_SIZE(data)); |
289 | } | 308 | } |
@@ -295,7 +314,6 @@ int intel_guc_suspend(struct drm_i915_private *dev_priv) | |||
295 | int intel_guc_resume(struct drm_i915_private *dev_priv) | 314 | int intel_guc_resume(struct drm_i915_private *dev_priv) |
296 | { | 315 | { |
297 | struct intel_guc *guc = &dev_priv->guc; | 316 | struct intel_guc *guc = &dev_priv->guc; |
298 | struct i915_gem_context *ctx; | ||
299 | u32 data[3]; | 317 | u32 data[3]; |
300 | 318 | ||
301 | if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) | 319 | if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) |
@@ -304,13 +322,9 @@ int intel_guc_resume(struct drm_i915_private *dev_priv) | |||
304 | if (i915_modparams.guc_log_level >= 0) | 322 | if (i915_modparams.guc_log_level >= 0) |
305 | gen9_enable_guc_interrupts(dev_priv); | 323 | gen9_enable_guc_interrupts(dev_priv); |
306 | 324 | ||
307 | ctx = dev_priv->kernel_context; | ||
308 | |||
309 | data[0] = INTEL_GUC_ACTION_EXIT_S_STATE; | 325 | data[0] = INTEL_GUC_ACTION_EXIT_S_STATE; |
310 | data[1] = GUC_POWER_D0; | 326 | data[1] = GUC_POWER_D0; |
311 | /* first page is shared data with GuC */ | 327 | data[2] = guc_ggtt_offset(guc->shared_data); |
312 | data[2] = guc_ggtt_offset(ctx->engine[RCS].state) + | ||
313 | LRC_GUCSHR_PN * PAGE_SIZE; | ||
314 | 328 | ||
315 | return intel_guc_send(guc, data, ARRAY_SIZE(data)); | 329 | return intel_guc_send(guc, data, ARRAY_SIZE(data)); |
316 | } | 330 | } |
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index 418450b1ae27..75c4cfefdaff 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h | |||
@@ -34,9 +34,14 @@ | |||
34 | #include "i915_guc_reg.h" | 34 | #include "i915_guc_reg.h" |
35 | #include "i915_vma.h" | 35 | #include "i915_vma.h" |
36 | 36 | ||
37 | struct guc_preempt_work { | ||
38 | struct work_struct work; | ||
39 | struct intel_engine_cs *engine; | ||
40 | }; | ||
41 | |||
37 | /* | 42 | /* |
38 | * Top level structure of GuC. It handles firmware loading and manages client | 43 | * Top level structure of GuC. It handles firmware loading and manages client |
39 | * pool and doorbells. intel_guc owns a i915_guc_client to replace the legacy | 44 | * pool and doorbells. intel_guc owns a intel_guc_client to replace the legacy |
40 | * ExecList submission. | 45 | * ExecList submission. |
41 | */ | 46 | */ |
42 | struct intel_guc { | 47 | struct intel_guc { |
@@ -54,8 +59,14 @@ struct intel_guc { | |||
54 | struct i915_vma *stage_desc_pool; | 59 | struct i915_vma *stage_desc_pool; |
55 | void *stage_desc_pool_vaddr; | 60 | void *stage_desc_pool_vaddr; |
56 | struct ida stage_ids; | 61 | struct ida stage_ids; |
62 | struct i915_vma *shared_data; | ||
63 | void *shared_data_vaddr; | ||
64 | |||
65 | struct intel_guc_client *execbuf_client; | ||
66 | struct intel_guc_client *preempt_client; | ||
57 | 67 | ||
58 | struct i915_guc_client *execbuf_client; | 68 | struct guc_preempt_work preempt_work[I915_NUM_ENGINES]; |
69 | struct workqueue_struct *preempt_wq; | ||
59 | 70 | ||
60 | DECLARE_BITMAP(doorbell_bitmap, GUC_NUM_DOORBELLS); | 71 | DECLARE_BITMAP(doorbell_bitmap, GUC_NUM_DOORBELLS); |
61 | /* Cyclic counter mod pagesize */ | 72 | /* Cyclic counter mod pagesize */ |
diff --git a/drivers/gpu/drm/i915/intel_guc_ct.c b/drivers/gpu/drm/i915/intel_guc_ct.c index c4cbec140101..24ad55752396 100644 --- a/drivers/gpu/drm/i915/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/intel_guc_ct.c | |||
@@ -198,6 +198,7 @@ static int ctch_open(struct intel_guc *guc, | |||
198 | err = ctch_init(guc, ctch); | 198 | err = ctch_init(guc, ctch); |
199 | if (unlikely(err)) | 199 | if (unlikely(err)) |
200 | goto err_out; | 200 | goto err_out; |
201 | GEM_BUG_ON(!ctch->vma); | ||
201 | } | 202 | } |
202 | 203 | ||
203 | /* vma should be already allocated and map'ed */ | 204 | /* vma should be already allocated and map'ed */ |
diff --git a/drivers/gpu/drm/i915/intel_guc_fw.c b/drivers/gpu/drm/i915/intel_guc_fw.c index ef67a36354c5..69ba01599575 100644 --- a/drivers/gpu/drm/i915/intel_guc_fw.c +++ b/drivers/gpu/drm/i915/intel_guc_fw.c | |||
@@ -97,23 +97,50 @@ int intel_guc_fw_select(struct intel_guc *guc) | |||
97 | return 0; | 97 | return 0; |
98 | } | 98 | } |
99 | 99 | ||
100 | /* | 100 | static void guc_prepare_xfer(struct intel_guc *guc) |
101 | * Read the GuC status register (GUC_STATUS) and store it in the | ||
102 | * specified location; then return a boolean indicating whether | ||
103 | * the value matches either of two values representing completion | ||
104 | * of the GuC boot process. | ||
105 | * | ||
106 | * This is used for polling the GuC status in a wait_for() | ||
107 | * loop below. | ||
108 | */ | ||
109 | static inline bool guc_ucode_response(struct drm_i915_private *dev_priv, | ||
110 | u32 *status) | ||
111 | { | 101 | { |
112 | u32 val = I915_READ(GUC_STATUS); | 102 | struct drm_i915_private *dev_priv = guc_to_i915(guc); |
113 | u32 uk_val = val & GS_UKERNEL_MASK; | 103 | |
114 | *status = val; | 104 | /* Must program this register before loading the ucode with DMA */ |
115 | return (uk_val == GS_UKERNEL_READY || | 105 | I915_WRITE(GUC_SHIM_CONTROL, GUC_DISABLE_SRAM_INIT_TO_ZEROES | |
116 | ((val & GS_MIA_CORE_STATE) && uk_val == GS_UKERNEL_LAPIC_DONE)); | 106 | GUC_ENABLE_READ_CACHE_LOGIC | |
107 | GUC_ENABLE_MIA_CACHING | | ||
108 | GUC_ENABLE_READ_CACHE_FOR_SRAM_DATA | | ||
109 | GUC_ENABLE_READ_CACHE_FOR_WOPCM_DATA | | ||
110 | GUC_ENABLE_MIA_CLOCK_GATING); | ||
111 | |||
112 | if (IS_GEN9_LP(dev_priv)) | ||
113 | I915_WRITE(GEN9LP_GT_PM_CONFIG, GT_DOORBELL_ENABLE); | ||
114 | else | ||
115 | I915_WRITE(GEN9_GT_PM_CONFIG, GT_DOORBELL_ENABLE); | ||
116 | |||
117 | if (IS_GEN9(dev_priv)) { | ||
118 | /* DOP Clock Gating Enable for GuC clocks */ | ||
119 | I915_WRITE(GEN7_MISCCPCTL, (GEN8_DOP_CLOCK_GATE_GUC_ENABLE | | ||
120 | I915_READ(GEN7_MISCCPCTL))); | ||
121 | |||
122 | /* allows for 5us (in 10ns units) before GT can go to RC6 */ | ||
123 | I915_WRITE(GUC_ARAT_C6DIS, 0x1FF); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | /* Copy RSA signature from the fw image to HW for verification */ | ||
128 | static int guc_xfer_rsa(struct intel_guc *guc, struct i915_vma *vma) | ||
129 | { | ||
130 | struct drm_i915_private *dev_priv = guc_to_i915(guc); | ||
131 | struct intel_uc_fw *guc_fw = &guc->fw; | ||
132 | struct sg_table *sg = vma->pages; | ||
133 | u32 rsa[UOS_RSA_SCRATCH_MAX_COUNT]; | ||
134 | int i; | ||
135 | |||
136 | if (sg_pcopy_to_buffer(sg->sgl, sg->nents, rsa, sizeof(rsa), | ||
137 | guc_fw->rsa_offset) != sizeof(rsa)) | ||
138 | return -EINVAL; | ||
139 | |||
140 | for (i = 0; i < UOS_RSA_SCRATCH_MAX_COUNT; i++) | ||
141 | I915_WRITE(UOS_RSA_SCRATCH(i), rsa[i]); | ||
142 | |||
143 | return 0; | ||
117 | } | 144 | } |
118 | 145 | ||
119 | /* | 146 | /* |
@@ -122,29 +149,19 @@ static inline bool guc_ucode_response(struct drm_i915_private *dev_priv, | |||
122 | * Architecturally, the DMA engine is bidirectional, and can potentially even | 149 | * Architecturally, the DMA engine is bidirectional, and can potentially even |
123 | * transfer between GTT locations. This functionality is left out of the API | 150 | * transfer between GTT locations. This functionality is left out of the API |
124 | * for now as there is no need for it. | 151 | * for now as there is no need for it. |
125 | * | ||
126 | * Note that GuC needs the CSS header plus uKernel code to be copied by the | ||
127 | * DMA engine in one operation, whereas the RSA signature is loaded via MMIO. | ||
128 | */ | 152 | */ |
129 | static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv, | 153 | static int guc_xfer_ucode(struct intel_guc *guc, struct i915_vma *vma) |
130 | struct i915_vma *vma) | ||
131 | { | 154 | { |
132 | struct intel_uc_fw *guc_fw = &dev_priv->guc.fw; | 155 | struct drm_i915_private *dev_priv = guc_to_i915(guc); |
156 | struct intel_uc_fw *guc_fw = &guc->fw; | ||
133 | unsigned long offset; | 157 | unsigned long offset; |
134 | struct sg_table *sg = vma->pages; | 158 | u32 status; |
135 | u32 status, rsa[UOS_RSA_SCRATCH_MAX_COUNT]; | 159 | int ret; |
136 | int i, ret = 0; | ||
137 | |||
138 | /* where RSA signature starts */ | ||
139 | offset = guc_fw->rsa_offset; | ||
140 | |||
141 | /* Copy RSA signature from the fw image to HW for verification */ | ||
142 | sg_pcopy_to_buffer(sg->sgl, sg->nents, rsa, sizeof(rsa), offset); | ||
143 | for (i = 0; i < UOS_RSA_SCRATCH_MAX_COUNT; i++) | ||
144 | I915_WRITE(UOS_RSA_SCRATCH(i), rsa[i]); | ||
145 | 160 | ||
146 | /* The header plus uCode will be copied to WOPCM via DMA, excluding any | 161 | /* |
147 | * other components */ | 162 | * The header plus uCode will be copied to WOPCM via DMA, excluding any |
163 | * other components | ||
164 | */ | ||
148 | I915_WRITE(DMA_COPY_SIZE, guc_fw->header_size + guc_fw->ucode_size); | 165 | I915_WRITE(DMA_COPY_SIZE, guc_fw->header_size + guc_fw->ucode_size); |
149 | 166 | ||
150 | /* Set the source address for the new blob */ | 167 | /* Set the source address for the new blob */ |
@@ -162,33 +179,62 @@ static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv, | |||
162 | /* Finally start the DMA */ | 179 | /* Finally start the DMA */ |
163 | I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE | START_DMA)); | 180 | I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE | START_DMA)); |
164 | 181 | ||
182 | /* Wait for DMA to finish */ | ||
183 | ret = __intel_wait_for_register_fw(dev_priv, DMA_CTRL, START_DMA, 0, | ||
184 | 2, 100, &status); | ||
185 | DRM_DEBUG_DRIVER("GuC DMA status %#x\n", status); | ||
186 | |||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | /* | ||
191 | * Read the GuC status register (GUC_STATUS) and store it in the | ||
192 | * specified location; then return a boolean indicating whether | ||
193 | * the value matches either of two values representing completion | ||
194 | * of the GuC boot process. | ||
195 | * | ||
196 | * This is used for polling the GuC status in a wait_for() | ||
197 | * loop below. | ||
198 | */ | ||
199 | static inline bool guc_ready(struct intel_guc *guc, u32 *status) | ||
200 | { | ||
201 | struct drm_i915_private *dev_priv = guc_to_i915(guc); | ||
202 | u32 val = I915_READ(GUC_STATUS); | ||
203 | u32 uk_val = val & GS_UKERNEL_MASK; | ||
204 | |||
205 | *status = val; | ||
206 | return (uk_val == GS_UKERNEL_READY) || | ||
207 | ((val & GS_MIA_CORE_STATE) && (uk_val == GS_UKERNEL_LAPIC_DONE)); | ||
208 | } | ||
209 | |||
210 | static int guc_wait_ucode(struct intel_guc *guc) | ||
211 | { | ||
212 | u32 status; | ||
213 | int ret; | ||
214 | |||
165 | /* | 215 | /* |
166 | * Wait for the DMA to complete & the GuC to start up. | 216 | * Wait for the GuC to start up. |
167 | * NB: Docs recommend not using the interrupt for completion. | 217 | * NB: Docs recommend not using the interrupt for completion. |
168 | * Measurements indicate this should take no more than 20ms, so a | 218 | * Measurements indicate this should take no more than 20ms, so a |
169 | * timeout here indicates that the GuC has failed and is unusable. | 219 | * timeout here indicates that the GuC has failed and is unusable. |
170 | * (Higher levels of the driver will attempt to fall back to | 220 | * (Higher levels of the driver will attempt to fall back to |
171 | * execlist mode if this happens.) | 221 | * execlist mode if this happens.) |
172 | */ | 222 | */ |
173 | ret = wait_for(guc_ucode_response(dev_priv, &status), 100); | 223 | ret = wait_for(guc_ready(guc, &status), 100); |
174 | 224 | DRM_DEBUG_DRIVER("GuC status %#x\n", status); | |
175 | DRM_DEBUG_DRIVER("DMA status 0x%x, GuC status 0x%x\n", | ||
176 | I915_READ(DMA_CTRL), status); | ||
177 | 225 | ||
178 | if ((status & GS_BOOTROM_MASK) == GS_BOOTROM_RSA_FAILED) { | 226 | if ((status & GS_BOOTROM_MASK) == GS_BOOTROM_RSA_FAILED) { |
179 | DRM_ERROR("GuC firmware signature verification failed\n"); | 227 | DRM_ERROR("GuC firmware signature verification failed\n"); |
180 | ret = -ENOEXEC; | 228 | ret = -ENOEXEC; |
181 | } | 229 | } |
182 | 230 | ||
183 | DRM_DEBUG_DRIVER("returning %d\n", ret); | ||
184 | |||
185 | return ret; | 231 | return ret; |
186 | } | 232 | } |
187 | 233 | ||
188 | /* | 234 | /* |
189 | * Load the GuC firmware blob into the MinuteIA. | 235 | * Load the GuC firmware blob into the MinuteIA. |
190 | */ | 236 | */ |
191 | static int guc_ucode_xfer(struct intel_uc_fw *guc_fw, struct i915_vma *vma) | 237 | static int guc_fw_xfer(struct intel_uc_fw *guc_fw, struct i915_vma *vma) |
192 | { | 238 | { |
193 | struct intel_guc *guc = container_of(guc_fw, struct intel_guc, fw); | 239 | struct intel_guc *guc = container_of(guc_fw, struct intel_guc, fw); |
194 | struct drm_i915_private *dev_priv = guc_to_i915(guc); | 240 | struct drm_i915_private *dev_priv = guc_to_i915(guc); |
@@ -198,34 +244,24 @@ static int guc_ucode_xfer(struct intel_uc_fw *guc_fw, struct i915_vma *vma) | |||
198 | 244 | ||
199 | intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); | 245 | intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
200 | 246 | ||
201 | /* Enable MIA caching. GuC clock gating is disabled. */ | 247 | guc_prepare_xfer(guc); |
202 | I915_WRITE(GUC_SHIM_CONTROL, GUC_SHIM_CONTROL_VALUE); | ||
203 | 248 | ||
204 | /* WaDisableMinuteIaClockGating:bxt */ | 249 | /* |
205 | if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) { | 250 | * Note that GuC needs the CSS header plus uKernel code to be copied |
206 | I915_WRITE(GUC_SHIM_CONTROL, (I915_READ(GUC_SHIM_CONTROL) & | 251 | * by the DMA engine in one operation, whereas the RSA signature is |
207 | ~GUC_ENABLE_MIA_CLOCK_GATING)); | 252 | * loaded via MMIO. |
208 | } | 253 | */ |
209 | 254 | ret = guc_xfer_rsa(guc, vma); | |
210 | /* WaC6DisallowByGfxPause:bxt */ | 255 | if (ret) |
211 | if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0)) | 256 | DRM_WARN("GuC firmware signature xfer error %d\n", ret); |
212 | I915_WRITE(GEN6_GFXPAUSE, 0x30FFF); | ||
213 | |||
214 | if (IS_GEN9_LP(dev_priv)) | ||
215 | I915_WRITE(GEN9LP_GT_PM_CONFIG, GT_DOORBELL_ENABLE); | ||
216 | else | ||
217 | I915_WRITE(GEN9_GT_PM_CONFIG, GT_DOORBELL_ENABLE); | ||
218 | |||
219 | if (IS_GEN9(dev_priv)) { | ||
220 | /* DOP Clock Gating Enable for GuC clocks */ | ||
221 | I915_WRITE(GEN7_MISCCPCTL, (GEN8_DOP_CLOCK_GATE_GUC_ENABLE | | ||
222 | I915_READ(GEN7_MISCCPCTL))); | ||
223 | 257 | ||
224 | /* allows for 5us (in 10ns units) before GT can go to RC6 */ | 258 | ret = guc_xfer_ucode(guc, vma); |
225 | I915_WRITE(GUC_ARAT_C6DIS, 0x1FF); | 259 | if (ret) |
226 | } | 260 | DRM_WARN("GuC firmware code xfer error %d\n", ret); |
227 | 261 | ||
228 | ret = guc_ucode_xfer_dma(dev_priv, vma); | 262 | ret = guc_wait_ucode(guc); |
263 | if (ret) | ||
264 | DRM_ERROR("GuC firmware xfer error %d\n", ret); | ||
229 | 265 | ||
230 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); | 266 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
231 | 267 | ||
@@ -247,5 +283,5 @@ static int guc_ucode_xfer(struct intel_uc_fw *guc_fw, struct i915_vma *vma) | |||
247 | */ | 283 | */ |
248 | int intel_guc_fw_upload(struct intel_guc *guc) | 284 | int intel_guc_fw_upload(struct intel_guc *guc) |
249 | { | 285 | { |
250 | return intel_uc_fw_upload(&guc->fw, guc_ucode_xfer); | 286 | return intel_uc_fw_upload(&guc->fw, guc_fw_xfer); |
251 | } | 287 | } |
diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h index 80c507435458..6a10aa6f04d3 100644 --- a/drivers/gpu/drm/i915/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h | |||
@@ -544,9 +544,37 @@ union guc_log_control { | |||
544 | u32 value; | 544 | u32 value; |
545 | } __packed; | 545 | } __packed; |
546 | 546 | ||
547 | struct guc_ctx_report { | ||
548 | u32 report_return_status; | ||
549 | u32 reserved1[64]; | ||
550 | u32 affected_count; | ||
551 | u32 reserved2[2]; | ||
552 | } __packed; | ||
553 | |||
554 | /* GuC Shared Context Data Struct */ | ||
555 | struct guc_shared_ctx_data { | ||
556 | u32 addr_of_last_preempted_data_low; | ||
557 | u32 addr_of_last_preempted_data_high; | ||
558 | u32 addr_of_last_preempted_data_high_tmp; | ||
559 | u32 padding; | ||
560 | u32 is_mapped_to_proxy; | ||
561 | u32 proxy_ctx_id; | ||
562 | u32 engine_reset_ctx_id; | ||
563 | u32 media_reset_count; | ||
564 | u32 reserved1[8]; | ||
565 | u32 uk_last_ctx_switch_reason; | ||
566 | u32 was_reset; | ||
567 | u32 lrca_gpu_addr; | ||
568 | u64 execlist_ctx; | ||
569 | u32 reserved2[66]; | ||
570 | struct guc_ctx_report preempt_ctx_report[GUC_MAX_ENGINES_NUM]; | ||
571 | } __packed; | ||
572 | |||
547 | /* This Action will be programmed in C180 - SOFT_SCRATCH_O_REG */ | 573 | /* This Action will be programmed in C180 - SOFT_SCRATCH_O_REG */ |
548 | enum intel_guc_action { | 574 | enum intel_guc_action { |
549 | INTEL_GUC_ACTION_DEFAULT = 0x0, | 575 | INTEL_GUC_ACTION_DEFAULT = 0x0, |
576 | INTEL_GUC_ACTION_REQUEST_PREEMPTION = 0x2, | ||
577 | INTEL_GUC_ACTION_REQUEST_ENGINE_RESET = 0x3, | ||
550 | INTEL_GUC_ACTION_SAMPLE_FORCEWAKE = 0x6, | 578 | INTEL_GUC_ACTION_SAMPLE_FORCEWAKE = 0x6, |
551 | INTEL_GUC_ACTION_ALLOCATE_DOORBELL = 0x10, | 579 | INTEL_GUC_ACTION_ALLOCATE_DOORBELL = 0x10, |
552 | INTEL_GUC_ACTION_DEALLOCATE_DOORBELL = 0x20, | 580 | INTEL_GUC_ACTION_DEALLOCATE_DOORBELL = 0x20, |
@@ -562,6 +590,18 @@ enum intel_guc_action { | |||
562 | INTEL_GUC_ACTION_LIMIT | 590 | INTEL_GUC_ACTION_LIMIT |
563 | }; | 591 | }; |
564 | 592 | ||
593 | enum intel_guc_preempt_options { | ||
594 | INTEL_GUC_PREEMPT_OPTION_DROP_WORK_Q = 0x4, | ||
595 | INTEL_GUC_PREEMPT_OPTION_DROP_SUBMIT_Q = 0x8, | ||
596 | }; | ||
597 | |||
598 | enum intel_guc_report_status { | ||
599 | INTEL_GUC_REPORT_STATUS_UNKNOWN = 0x0, | ||
600 | INTEL_GUC_REPORT_STATUS_ACKED = 0x1, | ||
601 | INTEL_GUC_REPORT_STATUS_ERROR = 0x2, | ||
602 | INTEL_GUC_REPORT_STATUS_COMPLETE = 0x4, | ||
603 | }; | ||
604 | |||
565 | /* | 605 | /* |
566 | * The GuC sends its response to a command by overwriting the | 606 | * The GuC sends its response to a command by overwriting the |
567 | * command in SS0. The response is distinguishable from a command | 607 | * command in SS0. The response is distinguishable from a command |
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c index f84c267728fd..cbf5a96f5806 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/intel_guc_submission.c | |||
@@ -25,23 +25,24 @@ | |||
25 | #include <linux/circ_buf.h> | 25 | #include <linux/circ_buf.h> |
26 | #include <trace/events/dma_fence.h> | 26 | #include <trace/events/dma_fence.h> |
27 | 27 | ||
28 | #include "i915_guc_submission.h" | 28 | #include "intel_guc_submission.h" |
29 | #include "i915_drv.h" | 29 | #include "i915_drv.h" |
30 | 30 | ||
31 | /** | 31 | /** |
32 | * DOC: GuC-based command submission | 32 | * DOC: GuC-based command submission |
33 | * | 33 | * |
34 | * GuC client: | 34 | * GuC client: |
35 | * A i915_guc_client refers to a submission path through GuC. Currently, there | 35 | * A intel_guc_client refers to a submission path through GuC. Currently, there |
36 | * is only one of these (the execbuf_client) and this one is charged with all | 36 | * are two clients. One of them (the execbuf_client) is charged with all |
37 | * submissions to the GuC. This struct is the owner of a doorbell, a process | 37 | * submissions to the GuC, the other one (preempt_client) is responsible for |
38 | * descriptor and a workqueue (all of them inside a single gem object that | 38 | * preempting the execbuf_client. This struct is the owner of a doorbell, a |
39 | * contains all required pages for these elements). | 39 | * process descriptor and a workqueue (all of them inside a single gem object |
40 | * that contains all required pages for these elements). | ||
40 | * | 41 | * |
41 | * GuC stage descriptor: | 42 | * GuC stage descriptor: |
42 | * During initialization, the driver allocates a static pool of 1024 such | 43 | * During initialization, the driver allocates a static pool of 1024 such |
43 | * descriptors, and shares them with the GuC. | 44 | * descriptors, and shares them with the GuC. |
44 | * Currently, there exists a 1:1 mapping between a i915_guc_client and a | 45 | * Currently, there exists a 1:1 mapping between a intel_guc_client and a |
45 | * guc_stage_desc (via the client's stage_id), so effectively only one | 46 | * guc_stage_desc (via the client's stage_id), so effectively only one |
46 | * gets used. This stage descriptor lets the GuC know about the doorbell, | 47 | * gets used. This stage descriptor lets the GuC know about the doorbell, |
47 | * workqueue and process descriptor. Theoretically, it also lets the GuC | 48 | * workqueue and process descriptor. Theoretically, it also lets the GuC |
@@ -70,7 +71,7 @@ | |||
70 | * WQ_TYPE_INORDER is needed to support legacy submission via GuC, which | 71 | * WQ_TYPE_INORDER is needed to support legacy submission via GuC, which |
71 | * represents in-order queue. The kernel driver packs ring tail pointer and an | 72 | * represents in-order queue. The kernel driver packs ring tail pointer and an |
72 | * ELSP context descriptor dword into Work Item. | 73 | * ELSP context descriptor dword into Work Item. |
73 | * See guc_wq_item_append() | 74 | * See guc_add_request() |
74 | * | 75 | * |
75 | * ADS: | 76 | * ADS: |
76 | * The Additional Data Struct (ADS) has pointers for different buffers used by | 77 | * The Additional Data Struct (ADS) has pointers for different buffers used by |
@@ -81,12 +82,13 @@ | |||
81 | * | 82 | * |
82 | */ | 83 | */ |
83 | 84 | ||
84 | static inline bool is_high_priority(struct i915_guc_client* client) | 85 | static inline bool is_high_priority(struct intel_guc_client *client) |
85 | { | 86 | { |
86 | return client->priority <= GUC_CLIENT_PRIORITY_HIGH; | 87 | return (client->priority == GUC_CLIENT_PRIORITY_KMD_HIGH || |
88 | client->priority == GUC_CLIENT_PRIORITY_HIGH); | ||
87 | } | 89 | } |
88 | 90 | ||
89 | static int __reserve_doorbell(struct i915_guc_client *client) | 91 | static int __reserve_doorbell(struct intel_guc_client *client) |
90 | { | 92 | { |
91 | unsigned long offset; | 93 | unsigned long offset; |
92 | unsigned long end; | 94 | unsigned long end; |
@@ -100,7 +102,7 @@ static int __reserve_doorbell(struct i915_guc_client *client) | |||
100 | * priority contexts, the second half for high-priority ones. | 102 | * priority contexts, the second half for high-priority ones. |
101 | */ | 103 | */ |
102 | offset = 0; | 104 | offset = 0; |
103 | end = GUC_NUM_DOORBELLS/2; | 105 | end = GUC_NUM_DOORBELLS / 2; |
104 | if (is_high_priority(client)) { | 106 | if (is_high_priority(client)) { |
105 | offset = end; | 107 | offset = end; |
106 | end += offset; | 108 | end += offset; |
@@ -118,7 +120,7 @@ static int __reserve_doorbell(struct i915_guc_client *client) | |||
118 | return 0; | 120 | return 0; |
119 | } | 121 | } |
120 | 122 | ||
121 | static void __unreserve_doorbell(struct i915_guc_client *client) | 123 | static void __unreserve_doorbell(struct intel_guc_client *client) |
122 | { | 124 | { |
123 | GEM_BUG_ON(client->doorbell_id == GUC_DOORBELL_INVALID); | 125 | GEM_BUG_ON(client->doorbell_id == GUC_DOORBELL_INVALID); |
124 | 126 | ||
@@ -150,7 +152,7 @@ static int __guc_deallocate_doorbell(struct intel_guc *guc, u32 stage_id) | |||
150 | return intel_guc_send(guc, action, ARRAY_SIZE(action)); | 152 | return intel_guc_send(guc, action, ARRAY_SIZE(action)); |
151 | } | 153 | } |
152 | 154 | ||
153 | static struct guc_stage_desc *__get_stage_desc(struct i915_guc_client *client) | 155 | static struct guc_stage_desc *__get_stage_desc(struct intel_guc_client *client) |
154 | { | 156 | { |
155 | struct guc_stage_desc *base = client->guc->stage_desc_pool_vaddr; | 157 | struct guc_stage_desc *base = client->guc->stage_desc_pool_vaddr; |
156 | 158 | ||
@@ -164,7 +166,7 @@ static struct guc_stage_desc *__get_stage_desc(struct i915_guc_client *client) | |||
164 | * client object which contains the page being used for the doorbell | 166 | * client object which contains the page being used for the doorbell |
165 | */ | 167 | */ |
166 | 168 | ||
167 | static void __update_doorbell_desc(struct i915_guc_client *client, u16 new_id) | 169 | static void __update_doorbell_desc(struct intel_guc_client *client, u16 new_id) |
168 | { | 170 | { |
169 | struct guc_stage_desc *desc; | 171 | struct guc_stage_desc *desc; |
170 | 172 | ||
@@ -173,12 +175,12 @@ static void __update_doorbell_desc(struct i915_guc_client *client, u16 new_id) | |||
173 | desc->db_id = new_id; | 175 | desc->db_id = new_id; |
174 | } | 176 | } |
175 | 177 | ||
176 | static struct guc_doorbell_info *__get_doorbell(struct i915_guc_client *client) | 178 | static struct guc_doorbell_info *__get_doorbell(struct intel_guc_client *client) |
177 | { | 179 | { |
178 | return client->vaddr + client->doorbell_offset; | 180 | return client->vaddr + client->doorbell_offset; |
179 | } | 181 | } |
180 | 182 | ||
181 | static bool has_doorbell(struct i915_guc_client *client) | 183 | static bool has_doorbell(struct intel_guc_client *client) |
182 | { | 184 | { |
183 | if (client->doorbell_id == GUC_DOORBELL_INVALID) | 185 | if (client->doorbell_id == GUC_DOORBELL_INVALID) |
184 | return false; | 186 | return false; |
@@ -186,7 +188,7 @@ static bool has_doorbell(struct i915_guc_client *client) | |||
186 | return test_bit(client->doorbell_id, client->guc->doorbell_bitmap); | 188 | return test_bit(client->doorbell_id, client->guc->doorbell_bitmap); |
187 | } | 189 | } |
188 | 190 | ||
189 | static int __create_doorbell(struct i915_guc_client *client) | 191 | static int __create_doorbell(struct intel_guc_client *client) |
190 | { | 192 | { |
191 | struct guc_doorbell_info *doorbell; | 193 | struct guc_doorbell_info *doorbell; |
192 | int err; | 194 | int err; |
@@ -196,13 +198,16 @@ static int __create_doorbell(struct i915_guc_client *client) | |||
196 | doorbell->cookie = 0; | 198 | doorbell->cookie = 0; |
197 | 199 | ||
198 | err = __guc_allocate_doorbell(client->guc, client->stage_id); | 200 | err = __guc_allocate_doorbell(client->guc, client->stage_id); |
199 | if (err) | 201 | if (err) { |
200 | doorbell->db_status = GUC_DOORBELL_DISABLED; | 202 | doorbell->db_status = GUC_DOORBELL_DISABLED; |
203 | DRM_ERROR("Couldn't create client %u doorbell: %d\n", | ||
204 | client->stage_id, err); | ||
205 | } | ||
201 | 206 | ||
202 | return err; | 207 | return err; |
203 | } | 208 | } |
204 | 209 | ||
205 | static int __destroy_doorbell(struct i915_guc_client *client) | 210 | static int __destroy_doorbell(struct intel_guc_client *client) |
206 | { | 211 | { |
207 | struct drm_i915_private *dev_priv = guc_to_i915(client->guc); | 212 | struct drm_i915_private *dev_priv = guc_to_i915(client->guc); |
208 | struct guc_doorbell_info *doorbell; | 213 | struct guc_doorbell_info *doorbell; |
@@ -216,14 +221,15 @@ static int __destroy_doorbell(struct i915_guc_client *client) | |||
216 | 221 | ||
217 | /* Doorbell release flow requires that we wait for GEN8_DRB_VALID bit | 222 | /* Doorbell release flow requires that we wait for GEN8_DRB_VALID bit |
218 | * to go to zero after updating db_status before we call the GuC to | 223 | * to go to zero after updating db_status before we call the GuC to |
219 | * release the doorbell */ | 224 | * release the doorbell |
225 | */ | ||
220 | if (wait_for_us(!(I915_READ(GEN8_DRBREGL(db_id)) & GEN8_DRB_VALID), 10)) | 226 | if (wait_for_us(!(I915_READ(GEN8_DRBREGL(db_id)) & GEN8_DRB_VALID), 10)) |
221 | WARN_ONCE(true, "Doorbell never became invalid after disable\n"); | 227 | WARN_ONCE(true, "Doorbell never became invalid after disable\n"); |
222 | 228 | ||
223 | return __guc_deallocate_doorbell(client->guc, client->stage_id); | 229 | return __guc_deallocate_doorbell(client->guc, client->stage_id); |
224 | } | 230 | } |
225 | 231 | ||
226 | static int create_doorbell(struct i915_guc_client *client) | 232 | static int create_doorbell(struct intel_guc_client *client) |
227 | { | 233 | { |
228 | int ret; | 234 | int ret; |
229 | 235 | ||
@@ -245,7 +251,7 @@ err: | |||
245 | return ret; | 251 | return ret; |
246 | } | 252 | } |
247 | 253 | ||
248 | static int destroy_doorbell(struct i915_guc_client *client) | 254 | static int destroy_doorbell(struct intel_guc_client *client) |
249 | { | 255 | { |
250 | int err; | 256 | int err; |
251 | 257 | ||
@@ -265,7 +271,7 @@ static int destroy_doorbell(struct i915_guc_client *client) | |||
265 | return 0; | 271 | return 0; |
266 | } | 272 | } |
267 | 273 | ||
268 | static unsigned long __select_cacheline(struct intel_guc* guc) | 274 | static unsigned long __select_cacheline(struct intel_guc *guc) |
269 | { | 275 | { |
270 | unsigned long offset; | 276 | unsigned long offset; |
271 | 277 | ||
@@ -276,12 +282,12 @@ static unsigned long __select_cacheline(struct intel_guc* guc) | |||
276 | guc->db_cacheline += cache_line_size(); | 282 | guc->db_cacheline += cache_line_size(); |
277 | 283 | ||
278 | DRM_DEBUG_DRIVER("reserved cacheline 0x%lx, next 0x%x, linesize %u\n", | 284 | DRM_DEBUG_DRIVER("reserved cacheline 0x%lx, next 0x%x, linesize %u\n", |
279 | offset, guc->db_cacheline, cache_line_size()); | 285 | offset, guc->db_cacheline, cache_line_size()); |
280 | return offset; | 286 | return offset; |
281 | } | 287 | } |
282 | 288 | ||
283 | static inline struct guc_process_desc * | 289 | static inline struct guc_process_desc * |
284 | __get_process_desc(struct i915_guc_client *client) | 290 | __get_process_desc(struct intel_guc_client *client) |
285 | { | 291 | { |
286 | return client->vaddr + client->proc_desc_offset; | 292 | return client->vaddr + client->proc_desc_offset; |
287 | } | 293 | } |
@@ -290,7 +296,7 @@ __get_process_desc(struct i915_guc_client *client) | |||
290 | * Initialise the process descriptor shared with the GuC firmware. | 296 | * Initialise the process descriptor shared with the GuC firmware. |
291 | */ | 297 | */ |
292 | static void guc_proc_desc_init(struct intel_guc *guc, | 298 | static void guc_proc_desc_init(struct intel_guc *guc, |
293 | struct i915_guc_client *client) | 299 | struct intel_guc_client *client) |
294 | { | 300 | { |
295 | struct guc_process_desc *desc; | 301 | struct guc_process_desc *desc; |
296 | 302 | ||
@@ -311,6 +317,37 @@ static void guc_proc_desc_init(struct intel_guc *guc, | |||
311 | desc->priority = client->priority; | 317 | desc->priority = client->priority; |
312 | } | 318 | } |
313 | 319 | ||
320 | static int guc_stage_desc_pool_create(struct intel_guc *guc) | ||
321 | { | ||
322 | struct i915_vma *vma; | ||
323 | void *vaddr; | ||
324 | |||
325 | vma = intel_guc_allocate_vma(guc, | ||
326 | PAGE_ALIGN(sizeof(struct guc_stage_desc) * | ||
327 | GUC_MAX_STAGE_DESCRIPTORS)); | ||
328 | if (IS_ERR(vma)) | ||
329 | return PTR_ERR(vma); | ||
330 | |||
331 | vaddr = i915_gem_object_pin_map(vma->obj, I915_MAP_WB); | ||
332 | if (IS_ERR(vaddr)) { | ||
333 | i915_vma_unpin_and_release(&vma); | ||
334 | return PTR_ERR(vaddr); | ||
335 | } | ||
336 | |||
337 | guc->stage_desc_pool = vma; | ||
338 | guc->stage_desc_pool_vaddr = vaddr; | ||
339 | ida_init(&guc->stage_ids); | ||
340 | |||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | static void guc_stage_desc_pool_destroy(struct intel_guc *guc) | ||
345 | { | ||
346 | ida_destroy(&guc->stage_ids); | ||
347 | i915_gem_object_unpin_map(guc->stage_desc_pool->obj); | ||
348 | i915_vma_unpin_and_release(&guc->stage_desc_pool); | ||
349 | } | ||
350 | |||
314 | /* | 351 | /* |
315 | * Initialise/clear the stage descriptor shared with the GuC firmware. | 352 | * Initialise/clear the stage descriptor shared with the GuC firmware. |
316 | * | 353 | * |
@@ -319,7 +356,7 @@ static void guc_proc_desc_init(struct intel_guc *guc, | |||
319 | * write queue, etc). | 356 | * write queue, etc). |
320 | */ | 357 | */ |
321 | static void guc_stage_desc_init(struct intel_guc *guc, | 358 | static void guc_stage_desc_init(struct intel_guc *guc, |
322 | struct i915_guc_client *client) | 359 | struct intel_guc_client *client) |
323 | { | 360 | { |
324 | struct drm_i915_private *dev_priv = guc_to_i915(guc); | 361 | struct drm_i915_private *dev_priv = guc_to_i915(guc); |
325 | struct intel_engine_cs *engine; | 362 | struct intel_engine_cs *engine; |
@@ -331,7 +368,10 @@ static void guc_stage_desc_init(struct intel_guc *guc, | |||
331 | desc = __get_stage_desc(client); | 368 | desc = __get_stage_desc(client); |
332 | memset(desc, 0, sizeof(*desc)); | 369 | memset(desc, 0, sizeof(*desc)); |
333 | 370 | ||
334 | desc->attribute = GUC_STAGE_DESC_ATTR_ACTIVE | GUC_STAGE_DESC_ATTR_KERNEL; | 371 | desc->attribute = GUC_STAGE_DESC_ATTR_ACTIVE | |
372 | GUC_STAGE_DESC_ATTR_KERNEL; | ||
373 | if (is_high_priority(client)) | ||
374 | desc->attribute |= GUC_STAGE_DESC_ATTR_PREEMPT; | ||
335 | desc->stage_id = client->stage_id; | 375 | desc->stage_id = client->stage_id; |
336 | desc->priority = client->priority; | 376 | desc->priority = client->priority; |
337 | desc->db_id = client->doorbell_id; | 377 | desc->db_id = client->doorbell_id; |
@@ -356,7 +396,7 @@ static void guc_stage_desc_init(struct intel_guc *guc, | |||
356 | * submission or, in other words, not using a direct submission | 396 | * submission or, in other words, not using a direct submission |
357 | * model) the KMD's LRCA is not used for any work submission. | 397 | * model) the KMD's LRCA is not used for any work submission. |
358 | * Instead, the GuC uses the LRCA of the user mode context (see | 398 | * Instead, the GuC uses the LRCA of the user mode context (see |
359 | * guc_wq_item_append below). | 399 | * guc_add_request below). |
360 | */ | 400 | */ |
361 | lrc->context_desc = lower_32_bits(ce->lrc_desc); | 401 | lrc->context_desc = lower_32_bits(ce->lrc_desc); |
362 | 402 | ||
@@ -365,7 +405,8 @@ static void guc_stage_desc_init(struct intel_guc *guc, | |||
365 | guc_ggtt_offset(ce->state) + LRC_STATE_PN * PAGE_SIZE; | 405 | guc_ggtt_offset(ce->state) + LRC_STATE_PN * PAGE_SIZE; |
366 | 406 | ||
367 | /* XXX: In direct submission, the GuC wants the HW context id | 407 | /* XXX: In direct submission, the GuC wants the HW context id |
368 | * here. In proxy submission, it wants the stage id */ | 408 | * here. In proxy submission, it wants the stage id |
409 | */ | ||
369 | lrc->context_id = (client->stage_id << GUC_ELC_CTXID_OFFSET) | | 410 | lrc->context_id = (client->stage_id << GUC_ELC_CTXID_OFFSET) | |
370 | (guc_engine_id << GUC_ELC_ENGINE_OFFSET); | 411 | (guc_engine_id << GUC_ELC_ENGINE_OFFSET); |
371 | 412 | ||
@@ -378,7 +419,7 @@ static void guc_stage_desc_init(struct intel_guc *guc, | |||
378 | } | 419 | } |
379 | 420 | ||
380 | DRM_DEBUG_DRIVER("Host engines 0x%x => GuC engines used 0x%x\n", | 421 | DRM_DEBUG_DRIVER("Host engines 0x%x => GuC engines used 0x%x\n", |
381 | client->engines, desc->engines_used); | 422 | client->engines, desc->engines_used); |
382 | WARN_ON(desc->engines_used == 0); | 423 | WARN_ON(desc->engines_used == 0); |
383 | 424 | ||
384 | /* | 425 | /* |
@@ -398,7 +439,7 @@ static void guc_stage_desc_init(struct intel_guc *guc, | |||
398 | } | 439 | } |
399 | 440 | ||
400 | static void guc_stage_desc_fini(struct intel_guc *guc, | 441 | static void guc_stage_desc_fini(struct intel_guc *guc, |
401 | struct i915_guc_client *client) | 442 | struct intel_guc_client *client) |
402 | { | 443 | { |
403 | struct guc_stage_desc *desc; | 444 | struct guc_stage_desc *desc; |
404 | 445 | ||
@@ -406,24 +447,47 @@ static void guc_stage_desc_fini(struct intel_guc *guc, | |||
406 | memset(desc, 0, sizeof(*desc)); | 447 | memset(desc, 0, sizeof(*desc)); |
407 | } | 448 | } |
408 | 449 | ||
450 | static int guc_shared_data_create(struct intel_guc *guc) | ||
451 | { | ||
452 | struct i915_vma *vma; | ||
453 | void *vaddr; | ||
454 | |||
455 | vma = intel_guc_allocate_vma(guc, PAGE_SIZE); | ||
456 | if (IS_ERR(vma)) | ||
457 | return PTR_ERR(vma); | ||
458 | |||
459 | vaddr = i915_gem_object_pin_map(vma->obj, I915_MAP_WB); | ||
460 | if (IS_ERR(vaddr)) { | ||
461 | i915_vma_unpin_and_release(&vma); | ||
462 | return PTR_ERR(vaddr); | ||
463 | } | ||
464 | |||
465 | guc->shared_data = vma; | ||
466 | guc->shared_data_vaddr = vaddr; | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | static void guc_shared_data_destroy(struct intel_guc *guc) | ||
472 | { | ||
473 | i915_gem_object_unpin_map(guc->shared_data->obj); | ||
474 | i915_vma_unpin_and_release(&guc->shared_data); | ||
475 | } | ||
476 | |||
409 | /* Construct a Work Item and append it to the GuC's Work Queue */ | 477 | /* Construct a Work Item and append it to the GuC's Work Queue */ |
410 | static void guc_wq_item_append(struct i915_guc_client *client, | 478 | static void guc_wq_item_append(struct intel_guc_client *client, |
411 | struct drm_i915_gem_request *rq) | 479 | u32 target_engine, u32 context_desc, |
480 | u32 ring_tail, u32 fence_id) | ||
412 | { | 481 | { |
413 | /* wqi_len is in DWords, and does not include the one-word header */ | 482 | /* wqi_len is in DWords, and does not include the one-word header */ |
414 | const size_t wqi_size = sizeof(struct guc_wq_item); | 483 | const size_t wqi_size = sizeof(struct guc_wq_item); |
415 | const u32 wqi_len = wqi_size / sizeof(u32) - 1; | 484 | const u32 wqi_len = wqi_size / sizeof(u32) - 1; |
416 | struct intel_engine_cs *engine = rq->engine; | ||
417 | struct i915_gem_context *ctx = rq->ctx; | ||
418 | struct guc_process_desc *desc = __get_process_desc(client); | 485 | struct guc_process_desc *desc = __get_process_desc(client); |
419 | struct guc_wq_item *wqi; | 486 | struct guc_wq_item *wqi; |
420 | u32 ring_tail, wq_off; | 487 | u32 wq_off; |
421 | 488 | ||
422 | lockdep_assert_held(&client->wq_lock); | 489 | lockdep_assert_held(&client->wq_lock); |
423 | 490 | ||
424 | ring_tail = intel_ring_set_tail(rq->ring, rq->tail) / sizeof(u64); | ||
425 | GEM_BUG_ON(ring_tail > WQ_RING_TAIL_MAX); | ||
426 | |||
427 | /* For now workqueue item is 4 DWs; workqueue buffer is 2 pages. So we | 491 | /* For now workqueue item is 4 DWs; workqueue buffer is 2 pages. So we |
428 | * should not have the case where structure wqi is across page, neither | 492 | * should not have the case where structure wqi is across page, neither |
429 | * wrapped to the beginning. This simplifies the implementation below. | 493 | * wrapped to the beginning. This simplifies the implementation below. |
@@ -445,19 +509,18 @@ static void guc_wq_item_append(struct i915_guc_client *client, | |||
445 | /* Now fill in the 4-word work queue item */ | 509 | /* Now fill in the 4-word work queue item */ |
446 | wqi->header = WQ_TYPE_INORDER | | 510 | wqi->header = WQ_TYPE_INORDER | |
447 | (wqi_len << WQ_LEN_SHIFT) | | 511 | (wqi_len << WQ_LEN_SHIFT) | |
448 | (engine->guc_id << WQ_TARGET_SHIFT) | | 512 | (target_engine << WQ_TARGET_SHIFT) | |
449 | WQ_NO_WCFLUSH_WAIT; | 513 | WQ_NO_WCFLUSH_WAIT; |
450 | 514 | wqi->context_desc = context_desc; | |
451 | wqi->context_desc = lower_32_bits(intel_lr_context_descriptor(ctx, engine)); | ||
452 | |||
453 | wqi->submit_element_info = ring_tail << WQ_RING_TAIL_SHIFT; | 515 | wqi->submit_element_info = ring_tail << WQ_RING_TAIL_SHIFT; |
454 | wqi->fence_id = rq->global_seqno; | 516 | GEM_BUG_ON(ring_tail > WQ_RING_TAIL_MAX); |
517 | wqi->fence_id = fence_id; | ||
455 | 518 | ||
456 | /* Postincrement WQ tail for next time. */ | 519 | /* Make the update visible to GuC */ |
457 | WRITE_ONCE(desc->tail, (wq_off + wqi_size) & (GUC_WQ_SIZE - 1)); | 520 | WRITE_ONCE(desc->tail, (wq_off + wqi_size) & (GUC_WQ_SIZE - 1)); |
458 | } | 521 | } |
459 | 522 | ||
460 | static void guc_reset_wq(struct i915_guc_client *client) | 523 | static void guc_reset_wq(struct intel_guc_client *client) |
461 | { | 524 | { |
462 | struct guc_process_desc *desc = __get_process_desc(client); | 525 | struct guc_process_desc *desc = __get_process_desc(client); |
463 | 526 | ||
@@ -465,7 +528,7 @@ static void guc_reset_wq(struct i915_guc_client *client) | |||
465 | desc->tail = 0; | 528 | desc->tail = 0; |
466 | } | 529 | } |
467 | 530 | ||
468 | static void guc_ring_doorbell(struct i915_guc_client *client) | 531 | static void guc_ring_doorbell(struct intel_guc_client *client) |
469 | { | 532 | { |
470 | struct guc_doorbell_info *db; | 533 | struct guc_doorbell_info *db; |
471 | u32 cookie; | 534 | u32 cookie; |
@@ -475,29 +538,166 @@ static void guc_ring_doorbell(struct i915_guc_client *client) | |||
475 | /* pointer of current doorbell cacheline */ | 538 | /* pointer of current doorbell cacheline */ |
476 | db = __get_doorbell(client); | 539 | db = __get_doorbell(client); |
477 | 540 | ||
478 | /* we're not expecting the doorbell cookie to change behind our back */ | 541 | /* |
542 | * We're not expecting the doorbell cookie to change behind our back, | ||
543 | * we also need to treat 0 as a reserved value. | ||
544 | */ | ||
479 | cookie = READ_ONCE(db->cookie); | 545 | cookie = READ_ONCE(db->cookie); |
480 | WARN_ON_ONCE(xchg(&db->cookie, cookie + 1) != cookie); | 546 | WARN_ON_ONCE(xchg(&db->cookie, cookie + 1 ?: cookie + 2) != cookie); |
481 | 547 | ||
482 | /* XXX: doorbell was lost and need to acquire it again */ | 548 | /* XXX: doorbell was lost and need to acquire it again */ |
483 | GEM_BUG_ON(db->db_status != GUC_DOORBELL_ENABLED); | 549 | GEM_BUG_ON(db->db_status != GUC_DOORBELL_ENABLED); |
484 | } | 550 | } |
485 | 551 | ||
552 | static void guc_add_request(struct intel_guc *guc, | ||
553 | struct drm_i915_gem_request *rq) | ||
554 | { | ||
555 | struct intel_guc_client *client = guc->execbuf_client; | ||
556 | struct intel_engine_cs *engine = rq->engine; | ||
557 | u32 ctx_desc = lower_32_bits(intel_lr_context_descriptor(rq->ctx, | ||
558 | engine)); | ||
559 | u32 ring_tail = intel_ring_set_tail(rq->ring, rq->tail) / sizeof(u64); | ||
560 | |||
561 | spin_lock(&client->wq_lock); | ||
562 | |||
563 | guc_wq_item_append(client, engine->guc_id, ctx_desc, | ||
564 | ring_tail, rq->global_seqno); | ||
565 | guc_ring_doorbell(client); | ||
566 | |||
567 | client->submissions[engine->id] += 1; | ||
568 | |||
569 | spin_unlock(&client->wq_lock); | ||
570 | } | ||
571 | |||
572 | /* | ||
573 | * When we're doing submissions using regular execlists backend, writing to | ||
574 | * ELSP from CPU side is enough to make sure that writes to ringbuffer pages | ||
575 | * pinned in mappable aperture portion of GGTT are visible to command streamer. | ||
576 | * Writes done by GuC on our behalf are not guaranteeing such ordering, | ||
577 | * therefore, to ensure the flush, we're issuing a POSTING READ. | ||
578 | */ | ||
579 | static void flush_ggtt_writes(struct i915_vma *vma) | ||
580 | { | ||
581 | struct drm_i915_private *dev_priv = to_i915(vma->obj->base.dev); | ||
582 | |||
583 | if (i915_vma_is_map_and_fenceable(vma)) | ||
584 | POSTING_READ_FW(GUC_STATUS); | ||
585 | } | ||
586 | |||
587 | #define GUC_PREEMPT_FINISHED 0x1 | ||
588 | #define GUC_PREEMPT_BREADCRUMB_DWORDS 0x8 | ||
589 | static void inject_preempt_context(struct work_struct *work) | ||
590 | { | ||
591 | struct guc_preempt_work *preempt_work = | ||
592 | container_of(work, typeof(*preempt_work), work); | ||
593 | struct intel_engine_cs *engine = preempt_work->engine; | ||
594 | struct intel_guc *guc = container_of(preempt_work, typeof(*guc), | ||
595 | preempt_work[engine->id]); | ||
596 | struct intel_guc_client *client = guc->preempt_client; | ||
597 | struct guc_stage_desc *stage_desc = __get_stage_desc(client); | ||
598 | struct intel_ring *ring = client->owner->engine[engine->id].ring; | ||
599 | u32 ctx_desc = lower_32_bits(intel_lr_context_descriptor(client->owner, | ||
600 | engine)); | ||
601 | u32 *cs = ring->vaddr + ring->tail; | ||
602 | u32 data[7]; | ||
603 | |||
604 | if (engine->id == RCS) { | ||
605 | cs = gen8_emit_ggtt_write_rcs(cs, GUC_PREEMPT_FINISHED, | ||
606 | intel_hws_preempt_done_address(engine)); | ||
607 | } else { | ||
608 | cs = gen8_emit_ggtt_write(cs, GUC_PREEMPT_FINISHED, | ||
609 | intel_hws_preempt_done_address(engine)); | ||
610 | *cs++ = MI_NOOP; | ||
611 | *cs++ = MI_NOOP; | ||
612 | } | ||
613 | *cs++ = MI_USER_INTERRUPT; | ||
614 | *cs++ = MI_NOOP; | ||
615 | |||
616 | GEM_BUG_ON(!IS_ALIGNED(ring->size, | ||
617 | GUC_PREEMPT_BREADCRUMB_DWORDS * sizeof(u32))); | ||
618 | GEM_BUG_ON((void *)cs - (ring->vaddr + ring->tail) != | ||
619 | GUC_PREEMPT_BREADCRUMB_DWORDS * sizeof(u32)); | ||
620 | |||
621 | ring->tail += GUC_PREEMPT_BREADCRUMB_DWORDS * sizeof(u32); | ||
622 | ring->tail &= (ring->size - 1); | ||
623 | |||
624 | flush_ggtt_writes(ring->vma); | ||
625 | |||
626 | spin_lock_irq(&client->wq_lock); | ||
627 | guc_wq_item_append(client, engine->guc_id, ctx_desc, | ||
628 | ring->tail / sizeof(u64), 0); | ||
629 | spin_unlock_irq(&client->wq_lock); | ||
630 | |||
631 | /* | ||
632 | * If GuC firmware performs an engine reset while that engine had | ||
633 | * a preemption pending, it will set the terminated attribute bit | ||
634 | * on our preemption stage descriptor. GuC firmware retains all | ||
635 | * pending work items for a high-priority GuC client, unlike the | ||
636 | * normal-priority GuC client where work items are dropped. It | ||
637 | * wants to make sure the preempt-to-idle work doesn't run when | ||
638 | * scheduling resumes, and uses this bit to inform its scheduler | ||
639 | * and presumably us as well. Our job is to clear it for the next | ||
640 | * preemption after reset, otherwise that and future preemptions | ||
641 | * will never complete. We'll just clear it every time. | ||
642 | */ | ||
643 | stage_desc->attribute &= ~GUC_STAGE_DESC_ATTR_TERMINATED; | ||
644 | |||
645 | data[0] = INTEL_GUC_ACTION_REQUEST_PREEMPTION; | ||
646 | data[1] = client->stage_id; | ||
647 | data[2] = INTEL_GUC_PREEMPT_OPTION_DROP_WORK_Q | | ||
648 | INTEL_GUC_PREEMPT_OPTION_DROP_SUBMIT_Q; | ||
649 | data[3] = engine->guc_id; | ||
650 | data[4] = guc->execbuf_client->priority; | ||
651 | data[5] = guc->execbuf_client->stage_id; | ||
652 | data[6] = guc_ggtt_offset(guc->shared_data); | ||
653 | |||
654 | if (WARN_ON(intel_guc_send(guc, data, ARRAY_SIZE(data)))) { | ||
655 | execlists_clear_active(&engine->execlists, | ||
656 | EXECLISTS_ACTIVE_PREEMPT); | ||
657 | tasklet_schedule(&engine->execlists.tasklet); | ||
658 | } | ||
659 | } | ||
660 | |||
661 | /* | ||
662 | * We're using user interrupt and HWSP value to mark that preemption has | ||
663 | * finished and GPU is idle. Normally, we could unwind and continue similar to | ||
664 | * execlists submission path. Unfortunately, with GuC we also need to wait for | ||
665 | * it to finish its own postprocessing, before attempting to submit. Otherwise | ||
666 | * GuC may silently ignore our submissions, and thus we risk losing request at | ||
667 | * best, executing out-of-order and causing kernel panic at worst. | ||
668 | */ | ||
669 | #define GUC_PREEMPT_POSTPROCESS_DELAY_MS 10 | ||
670 | static void wait_for_guc_preempt_report(struct intel_engine_cs *engine) | ||
671 | { | ||
672 | struct intel_guc *guc = &engine->i915->guc; | ||
673 | struct guc_shared_ctx_data *data = guc->shared_data_vaddr; | ||
674 | struct guc_ctx_report *report = | ||
675 | &data->preempt_ctx_report[engine->guc_id]; | ||
676 | |||
677 | WARN_ON(wait_for_atomic(report->report_return_status == | ||
678 | INTEL_GUC_REPORT_STATUS_COMPLETE, | ||
679 | GUC_PREEMPT_POSTPROCESS_DELAY_MS)); | ||
680 | /* | ||
681 | * GuC is expecting that we're also going to clear the affected context | ||
682 | * counter, let's also reset the return status to not depend on GuC | ||
683 | * resetting it after recieving another preempt action | ||
684 | */ | ||
685 | report->affected_count = 0; | ||
686 | report->report_return_status = INTEL_GUC_REPORT_STATUS_UNKNOWN; | ||
687 | } | ||
688 | |||
486 | /** | 689 | /** |
487 | * i915_guc_submit() - Submit commands through GuC | 690 | * guc_submit() - Submit commands through GuC |
488 | * @engine: engine associated with the commands | 691 | * @engine: engine associated with the commands |
489 | * | 692 | * |
490 | * The only error here arises if the doorbell hardware isn't functioning | 693 | * The only error here arises if the doorbell hardware isn't functioning |
491 | * as expected, which really shouln't happen. | 694 | * as expected, which really shouln't happen. |
492 | */ | 695 | */ |
493 | static void i915_guc_submit(struct intel_engine_cs *engine) | 696 | static void guc_submit(struct intel_engine_cs *engine) |
494 | { | 697 | { |
495 | struct drm_i915_private *dev_priv = engine->i915; | 698 | struct intel_guc *guc = &engine->i915->guc; |
496 | struct intel_guc *guc = &dev_priv->guc; | ||
497 | struct i915_guc_client *client = guc->execbuf_client; | ||
498 | struct intel_engine_execlists * const execlists = &engine->execlists; | 699 | struct intel_engine_execlists * const execlists = &engine->execlists; |
499 | struct execlist_port *port = execlists->port; | 700 | struct execlist_port *port = execlists->port; |
500 | const unsigned int engine_id = engine->id; | ||
501 | unsigned int n; | 701 | unsigned int n; |
502 | 702 | ||
503 | for (n = 0; n < execlists_num_ports(execlists); n++) { | 703 | for (n = 0; n < execlists_num_ports(execlists); n++) { |
@@ -508,44 +708,13 @@ static void i915_guc_submit(struct intel_engine_cs *engine) | |||
508 | if (rq && count == 0) { | 708 | if (rq && count == 0) { |
509 | port_set(&port[n], port_pack(rq, ++count)); | 709 | port_set(&port[n], port_pack(rq, ++count)); |
510 | 710 | ||
511 | if (i915_vma_is_map_and_fenceable(rq->ring->vma)) | 711 | flush_ggtt_writes(rq->ring->vma); |
512 | POSTING_READ_FW(GUC_STATUS); | ||
513 | |||
514 | spin_lock(&client->wq_lock); | ||
515 | |||
516 | guc_wq_item_append(client, rq); | ||
517 | guc_ring_doorbell(client); | ||
518 | 712 | ||
519 | client->submissions[engine_id] += 1; | 713 | guc_add_request(guc, rq); |
520 | |||
521 | spin_unlock(&client->wq_lock); | ||
522 | } | 714 | } |
523 | } | 715 | } |
524 | } | 716 | } |
525 | 717 | ||
526 | static void nested_enable_signaling(struct drm_i915_gem_request *rq) | ||
527 | { | ||
528 | /* If we use dma_fence_enable_sw_signaling() directly, lockdep | ||
529 | * detects an ordering issue between the fence lockclass and the | ||
530 | * global_timeline. This circular dependency can only occur via 2 | ||
531 | * different fences (but same fence lockclass), so we use the nesting | ||
532 | * annotation here to prevent the warn, equivalent to the nesting | ||
533 | * inside i915_gem_request_submit() for when we also enable the | ||
534 | * signaler. | ||
535 | */ | ||
536 | |||
537 | if (test_and_set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, | ||
538 | &rq->fence.flags)) | ||
539 | return; | ||
540 | |||
541 | GEM_BUG_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &rq->fence.flags)); | ||
542 | trace_dma_fence_enable_signal(&rq->fence); | ||
543 | |||
544 | spin_lock_nested(&rq->lock, SINGLE_DEPTH_NESTING); | ||
545 | intel_engine_enable_signaling(rq, true); | ||
546 | spin_unlock(&rq->lock); | ||
547 | } | ||
548 | |||
549 | static void port_assign(struct execlist_port *port, | 718 | static void port_assign(struct execlist_port *port, |
550 | struct drm_i915_gem_request *rq) | 719 | struct drm_i915_gem_request *rq) |
551 | { | 720 | { |
@@ -555,10 +724,9 @@ static void port_assign(struct execlist_port *port, | |||
555 | i915_gem_request_put(port_request(port)); | 724 | i915_gem_request_put(port_request(port)); |
556 | 725 | ||
557 | port_set(port, port_pack(i915_gem_request_get(rq), port_count(port))); | 726 | port_set(port, port_pack(i915_gem_request_get(rq), port_count(port))); |
558 | nested_enable_signaling(rq); | ||
559 | } | 727 | } |
560 | 728 | ||
561 | static void i915_guc_dequeue(struct intel_engine_cs *engine) | 729 | static void guc_dequeue(struct intel_engine_cs *engine) |
562 | { | 730 | { |
563 | struct intel_engine_execlists * const execlists = &engine->execlists; | 731 | struct intel_engine_execlists * const execlists = &engine->execlists; |
564 | struct execlist_port *port = execlists->port; | 732 | struct execlist_port *port = execlists->port; |
@@ -568,13 +736,32 @@ static void i915_guc_dequeue(struct intel_engine_cs *engine) | |||
568 | bool submit = false; | 736 | bool submit = false; |
569 | struct rb_node *rb; | 737 | struct rb_node *rb; |
570 | 738 | ||
571 | if (port_isset(port)) | ||
572 | port++; | ||
573 | |||
574 | spin_lock_irq(&engine->timeline->lock); | 739 | spin_lock_irq(&engine->timeline->lock); |
575 | rb = execlists->first; | 740 | rb = execlists->first; |
576 | GEM_BUG_ON(rb_first(&execlists->queue) != rb); | 741 | GEM_BUG_ON(rb_first(&execlists->queue) != rb); |
577 | while (rb) { | 742 | |
743 | if (!rb) | ||
744 | goto unlock; | ||
745 | |||
746 | if (HAS_LOGICAL_RING_PREEMPTION(engine->i915) && port_isset(port)) { | ||
747 | struct guc_preempt_work *preempt_work = | ||
748 | &engine->i915->guc.preempt_work[engine->id]; | ||
749 | |||
750 | if (rb_entry(rb, struct i915_priolist, node)->priority > | ||
751 | max(port_request(port)->priotree.priority, 0)) { | ||
752 | execlists_set_active(execlists, | ||
753 | EXECLISTS_ACTIVE_PREEMPT); | ||
754 | queue_work(engine->i915->guc.preempt_wq, | ||
755 | &preempt_work->work); | ||
756 | goto unlock; | ||
757 | } else if (port_isset(last_port)) { | ||
758 | goto unlock; | ||
759 | } | ||
760 | |||
761 | port++; | ||
762 | } | ||
763 | |||
764 | do { | ||
578 | struct i915_priolist *p = rb_entry(rb, typeof(*p), node); | 765 | struct i915_priolist *p = rb_entry(rb, typeof(*p), node); |
579 | struct drm_i915_gem_request *rq, *rn; | 766 | struct drm_i915_gem_request *rq, *rn; |
580 | 767 | ||
@@ -592,10 +779,10 @@ static void i915_guc_dequeue(struct intel_engine_cs *engine) | |||
592 | } | 779 | } |
593 | 780 | ||
594 | INIT_LIST_HEAD(&rq->priotree.link); | 781 | INIT_LIST_HEAD(&rq->priotree.link); |
595 | rq->priotree.priority = INT_MAX; | ||
596 | 782 | ||
597 | __i915_gem_request_submit(rq); | 783 | __i915_gem_request_submit(rq); |
598 | trace_i915_gem_request_in(rq, port_index(port, execlists)); | 784 | trace_i915_gem_request_in(rq, |
785 | port_index(port, execlists)); | ||
599 | last = rq; | 786 | last = rq; |
600 | submit = true; | 787 | submit = true; |
601 | } | 788 | } |
@@ -605,24 +792,23 @@ static void i915_guc_dequeue(struct intel_engine_cs *engine) | |||
605 | INIT_LIST_HEAD(&p->requests); | 792 | INIT_LIST_HEAD(&p->requests); |
606 | if (p->priority != I915_PRIORITY_NORMAL) | 793 | if (p->priority != I915_PRIORITY_NORMAL) |
607 | kmem_cache_free(engine->i915->priorities, p); | 794 | kmem_cache_free(engine->i915->priorities, p); |
608 | } | 795 | } while (rb); |
609 | done: | 796 | done: |
610 | execlists->first = rb; | 797 | execlists->first = rb; |
611 | if (submit) { | 798 | if (submit) { |
612 | port_assign(port, last); | 799 | port_assign(port, last); |
613 | execlists_set_active(execlists, EXECLISTS_ACTIVE_USER); | 800 | execlists_set_active(execlists, EXECLISTS_ACTIVE_USER); |
614 | i915_guc_submit(engine); | 801 | guc_submit(engine); |
615 | } | 802 | } |
803 | unlock: | ||
616 | spin_unlock_irq(&engine->timeline->lock); | 804 | spin_unlock_irq(&engine->timeline->lock); |
617 | } | 805 | } |
618 | 806 | ||
619 | static void i915_guc_irq_handler(unsigned long data) | 807 | static void guc_submission_tasklet(unsigned long data) |
620 | { | 808 | { |
621 | struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; | 809 | struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; |
622 | struct intel_engine_execlists * const execlists = &engine->execlists; | 810 | struct intel_engine_execlists * const execlists = &engine->execlists; |
623 | struct execlist_port *port = execlists->port; | 811 | struct execlist_port *port = execlists->port; |
624 | const struct execlist_port * const last_port = | ||
625 | &execlists->port[execlists->port_mask]; | ||
626 | struct drm_i915_gem_request *rq; | 812 | struct drm_i915_gem_request *rq; |
627 | 813 | ||
628 | rq = port_request(&port[0]); | 814 | rq = port_request(&port[0]); |
@@ -637,14 +823,26 @@ static void i915_guc_irq_handler(unsigned long data) | |||
637 | if (!rq) | 823 | if (!rq) |
638 | execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER); | 824 | execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER); |
639 | 825 | ||
640 | if (!port_isset(last_port)) | 826 | if (execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT) && |
641 | i915_guc_dequeue(engine); | 827 | intel_read_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX) == |
828 | GUC_PREEMPT_FINISHED) { | ||
829 | execlists_cancel_port_requests(&engine->execlists); | ||
830 | execlists_unwind_incomplete_requests(execlists); | ||
831 | |||
832 | wait_for_guc_preempt_report(engine); | ||
833 | |||
834 | execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT); | ||
835 | intel_write_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX, 0); | ||
836 | } | ||
837 | |||
838 | if (!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT)) | ||
839 | guc_dequeue(engine); | ||
642 | } | 840 | } |
643 | 841 | ||
644 | /* | 842 | /* |
645 | * Everything below here is concerned with setup & teardown, and is | 843 | * Everything below here is concerned with setup & teardown, and is |
646 | * therefore not part of the somewhat time-critical batch-submission | 844 | * therefore not part of the somewhat time-critical batch-submission |
647 | * path of i915_guc_submit() above. | 845 | * path of guc_submit() above. |
648 | */ | 846 | */ |
649 | 847 | ||
650 | /* Check that a doorbell register is in the expected state */ | 848 | /* Check that a doorbell register is in the expected state */ |
@@ -673,7 +871,7 @@ static bool doorbell_ok(struct intel_guc *guc, u16 db_id) | |||
673 | * reloaded the GuC FW) we can use this function to tell the GuC to reassign the | 871 | * reloaded the GuC FW) we can use this function to tell the GuC to reassign the |
674 | * doorbell to the rightful owner. | 872 | * doorbell to the rightful owner. |
675 | */ | 873 | */ |
676 | static int __reset_doorbell(struct i915_guc_client* client, u16 db_id) | 874 | static int __reset_doorbell(struct intel_guc_client *client, u16 db_id) |
677 | { | 875 | { |
678 | int err; | 876 | int err; |
679 | 877 | ||
@@ -694,7 +892,7 @@ static int __reset_doorbell(struct i915_guc_client* client, u16 db_id) | |||
694 | */ | 892 | */ |
695 | static int guc_init_doorbell_hw(struct intel_guc *guc) | 893 | static int guc_init_doorbell_hw(struct intel_guc *guc) |
696 | { | 894 | { |
697 | struct i915_guc_client *client = guc->execbuf_client; | 895 | struct intel_guc_client *client = guc->execbuf_client; |
698 | bool recreate_first_client = false; | 896 | bool recreate_first_client = false; |
699 | u16 db_id; | 897 | u16 db_id; |
700 | int ret; | 898 | int ret; |
@@ -717,7 +915,8 @@ static int guc_init_doorbell_hw(struct intel_guc *guc) | |||
717 | if (recreate_first_client) { | 915 | if (recreate_first_client) { |
718 | ret = __reserve_doorbell(client); | 916 | ret = __reserve_doorbell(client); |
719 | if (unlikely(ret)) { | 917 | if (unlikely(ret)) { |
720 | DRM_ERROR("Couldn't re-reserve first client db: %d\n", ret); | 918 | DRM_ERROR("Couldn't re-reserve first client db: %d\n", |
919 | ret); | ||
721 | return ret; | 920 | return ret; |
722 | } | 921 | } |
723 | 922 | ||
@@ -725,15 +924,16 @@ static int guc_init_doorbell_hw(struct intel_guc *guc) | |||
725 | } | 924 | } |
726 | 925 | ||
727 | /* Now for every client (and not only execbuf_client) make sure their | 926 | /* Now for every client (and not only execbuf_client) make sure their |
728 | * doorbells are known by the GuC */ | 927 | * doorbells are known by the GuC |
729 | //for (client = client_list; client != NULL; client = client->next) | 928 | */ |
730 | { | 929 | ret = __create_doorbell(guc->execbuf_client); |
731 | ret = __create_doorbell(client); | 930 | if (ret) |
732 | if (ret) { | 931 | return ret; |
733 | DRM_ERROR("Couldn't recreate client %u doorbell: %d\n", | 932 | |
734 | client->stage_id, ret); | 933 | ret = __create_doorbell(guc->preempt_client); |
735 | return ret; | 934 | if (ret) { |
736 | } | 935 | __destroy_doorbell(guc->execbuf_client); |
936 | return ret; | ||
737 | } | 937 | } |
738 | 938 | ||
739 | /* Read back & verify all (used & unused) doorbell registers */ | 939 | /* Read back & verify all (used & unused) doorbell registers */ |
@@ -744,25 +944,25 @@ static int guc_init_doorbell_hw(struct intel_guc *guc) | |||
744 | } | 944 | } |
745 | 945 | ||
746 | /** | 946 | /** |
747 | * guc_client_alloc() - Allocate an i915_guc_client | 947 | * guc_client_alloc() - Allocate an intel_guc_client |
748 | * @dev_priv: driver private data structure | 948 | * @dev_priv: driver private data structure |
749 | * @engines: The set of engines to enable for this client | 949 | * @engines: The set of engines to enable for this client |
750 | * @priority: four levels priority _CRITICAL, _HIGH, _NORMAL and _LOW | 950 | * @priority: four levels priority _CRITICAL, _HIGH, _NORMAL and _LOW |
751 | * The kernel client to replace ExecList submission is created with | 951 | * The kernel client to replace ExecList submission is created with |
752 | * NORMAL priority. Priority of a client for scheduler can be HIGH, | 952 | * NORMAL priority. Priority of a client for scheduler can be HIGH, |
753 | * while a preemption context can use CRITICAL. | 953 | * while a preemption context can use CRITICAL. |
754 | * @ctx: the context that owns the client (we use the default render | 954 | * @ctx: the context that owns the client (we use the default render |
755 | * context) | 955 | * context) |
756 | * | 956 | * |
757 | * Return: An i915_guc_client object if success, else NULL. | 957 | * Return: An intel_guc_client object if success, else NULL. |
758 | */ | 958 | */ |
759 | static struct i915_guc_client * | 959 | static struct intel_guc_client * |
760 | guc_client_alloc(struct drm_i915_private *dev_priv, | 960 | guc_client_alloc(struct drm_i915_private *dev_priv, |
761 | u32 engines, | 961 | u32 engines, |
762 | u32 priority, | 962 | u32 priority, |
763 | struct i915_gem_context *ctx) | 963 | struct i915_gem_context *ctx) |
764 | { | 964 | { |
765 | struct i915_guc_client *client; | 965 | struct intel_guc_client *client; |
766 | struct intel_guc *guc = &dev_priv->guc; | 966 | struct intel_guc *guc = &dev_priv->guc; |
767 | struct i915_vma *vma; | 967 | struct i915_vma *vma; |
768 | void *vaddr; | 968 | void *vaddr; |
@@ -780,7 +980,7 @@ guc_client_alloc(struct drm_i915_private *dev_priv, | |||
780 | spin_lock_init(&client->wq_lock); | 980 | spin_lock_init(&client->wq_lock); |
781 | 981 | ||
782 | ret = ida_simple_get(&guc->stage_ids, 0, GUC_MAX_STAGE_DESCRIPTORS, | 982 | ret = ida_simple_get(&guc->stage_ids, 0, GUC_MAX_STAGE_DESCRIPTORS, |
783 | GFP_KERNEL); | 983 | GFP_KERNEL); |
784 | if (ret < 0) | 984 | if (ret < 0) |
785 | goto err_client; | 985 | goto err_client; |
786 | 986 | ||
@@ -840,7 +1040,7 @@ err_client: | |||
840 | return ERR_PTR(ret); | 1040 | return ERR_PTR(ret); |
841 | } | 1041 | } |
842 | 1042 | ||
843 | static void guc_client_free(struct i915_guc_client *client) | 1043 | static void guc_client_free(struct intel_guc_client *client) |
844 | { | 1044 | { |
845 | /* | 1045 | /* |
846 | * XXX: wait for any outstanding submissions before freeing memory. | 1046 | * XXX: wait for any outstanding submissions before freeing memory. |
@@ -849,7 +1049,8 @@ static void guc_client_free(struct i915_guc_client *client) | |||
849 | 1049 | ||
850 | /* FIXME: in many cases, by the time we get here the GuC has been | 1050 | /* FIXME: in many cases, by the time we get here the GuC has been |
851 | * reset, so we cannot destroy the doorbell properly. Ignore the | 1051 | * reset, so we cannot destroy the doorbell properly. Ignore the |
852 | * error message for now */ | 1052 | * error message for now |
1053 | */ | ||
853 | destroy_doorbell(client); | 1054 | destroy_doorbell(client); |
854 | guc_stage_desc_fini(client->guc, client); | 1055 | guc_stage_desc_fini(client->guc, client); |
855 | i915_gem_object_unpin_map(client->vma->obj); | 1056 | i915_gem_object_unpin_map(client->vma->obj); |
@@ -858,6 +1059,50 @@ static void guc_client_free(struct i915_guc_client *client) | |||
858 | kfree(client); | 1059 | kfree(client); |
859 | } | 1060 | } |
860 | 1061 | ||
1062 | static int guc_clients_create(struct intel_guc *guc) | ||
1063 | { | ||
1064 | struct drm_i915_private *dev_priv = guc_to_i915(guc); | ||
1065 | struct intel_guc_client *client; | ||
1066 | |||
1067 | GEM_BUG_ON(guc->execbuf_client); | ||
1068 | GEM_BUG_ON(guc->preempt_client); | ||
1069 | |||
1070 | client = guc_client_alloc(dev_priv, | ||
1071 | INTEL_INFO(dev_priv)->ring_mask, | ||
1072 | GUC_CLIENT_PRIORITY_KMD_NORMAL, | ||
1073 | dev_priv->kernel_context); | ||
1074 | if (IS_ERR(client)) { | ||
1075 | DRM_ERROR("Failed to create GuC client for submission!\n"); | ||
1076 | return PTR_ERR(client); | ||
1077 | } | ||
1078 | guc->execbuf_client = client; | ||
1079 | |||
1080 | client = guc_client_alloc(dev_priv, | ||
1081 | INTEL_INFO(dev_priv)->ring_mask, | ||
1082 | GUC_CLIENT_PRIORITY_KMD_HIGH, | ||
1083 | dev_priv->preempt_context); | ||
1084 | if (IS_ERR(client)) { | ||
1085 | DRM_ERROR("Failed to create GuC client for preemption!\n"); | ||
1086 | guc_client_free(guc->execbuf_client); | ||
1087 | guc->execbuf_client = NULL; | ||
1088 | return PTR_ERR(client); | ||
1089 | } | ||
1090 | guc->preempt_client = client; | ||
1091 | |||
1092 | return 0; | ||
1093 | } | ||
1094 | |||
1095 | static void guc_clients_destroy(struct intel_guc *guc) | ||
1096 | { | ||
1097 | struct intel_guc_client *client; | ||
1098 | |||
1099 | client = fetch_and_zero(&guc->execbuf_client); | ||
1100 | guc_client_free(client); | ||
1101 | |||
1102 | client = fetch_and_zero(&guc->preempt_client); | ||
1103 | guc_client_free(client); | ||
1104 | } | ||
1105 | |||
861 | static void guc_policy_init(struct guc_policy *policy) | 1106 | static void guc_policy_init(struct guc_policy *policy) |
862 | { | 1107 | { |
863 | policy->execution_quantum = POLICY_DEFAULT_EXECUTION_QUANTUM_US; | 1108 | policy->execution_quantum = POLICY_DEFAULT_EXECUTION_QUANTUM_US; |
@@ -941,7 +1186,8 @@ static int guc_ads_create(struct intel_guc *guc) | |||
941 | * because our GuC shared data is there. | 1186 | * because our GuC shared data is there. |
942 | */ | 1187 | */ |
943 | blob->ads.golden_context_lrca = | 1188 | blob->ads.golden_context_lrca = |
944 | guc_ggtt_offset(dev_priv->kernel_context->engine[RCS].state) + skipped_offset; | 1189 | guc_ggtt_offset(dev_priv->kernel_context->engine[RCS].state) + |
1190 | skipped_offset; | ||
945 | 1191 | ||
946 | /* | 1192 | /* |
947 | * The GuC expects us to exclude the portion of the context image that | 1193 | * The GuC expects us to exclude the portion of the context image that |
@@ -950,7 +1196,8 @@ static int guc_ads_create(struct intel_guc *guc) | |||
950 | * dwords). Weird guc is weird. | 1196 | * dwords). Weird guc is weird. |
951 | */ | 1197 | */ |
952 | for_each_engine(engine, dev_priv, id) | 1198 | for_each_engine(engine, dev_priv, id) |
953 | blob->ads.eng_state_size[engine->guc_id] = engine->context_size - skipped_size; | 1199 | blob->ads.eng_state_size[engine->guc_id] = |
1200 | engine->context_size - skipped_size; | ||
954 | 1201 | ||
955 | base = guc_ggtt_offset(vma); | 1202 | base = guc_ggtt_offset(vma); |
956 | blob->ads.scheduler_policies = base + ptr_offset(blob, policies); | 1203 | blob->ads.scheduler_policies = base + ptr_offset(blob, policies); |
@@ -967,66 +1214,110 @@ static void guc_ads_destroy(struct intel_guc *guc) | |||
967 | i915_vma_unpin_and_release(&guc->ads_vma); | 1214 | i915_vma_unpin_and_release(&guc->ads_vma); |
968 | } | 1215 | } |
969 | 1216 | ||
1217 | static int guc_preempt_work_create(struct intel_guc *guc) | ||
1218 | { | ||
1219 | struct drm_i915_private *dev_priv = guc_to_i915(guc); | ||
1220 | struct intel_engine_cs *engine; | ||
1221 | enum intel_engine_id id; | ||
1222 | |||
1223 | /* | ||
1224 | * Even though both sending GuC action, and adding a new workitem to | ||
1225 | * GuC workqueue are serialized (each with its own locking), since | ||
1226 | * we're using mutliple engines, it's possible that we're going to | ||
1227 | * issue a preempt request with two (or more - each for different | ||
1228 | * engine) workitems in GuC queue. In this situation, GuC may submit | ||
1229 | * all of them, which will make us very confused. | ||
1230 | * Our preemption contexts may even already be complete - before we | ||
1231 | * even had the chance to sent the preempt action to GuC!. Rather | ||
1232 | * than introducing yet another lock, we can just use ordered workqueue | ||
1233 | * to make sure we're always sending a single preemption request with a | ||
1234 | * single workitem. | ||
1235 | */ | ||
1236 | guc->preempt_wq = alloc_ordered_workqueue("i915-guc_preempt", | ||
1237 | WQ_HIGHPRI); | ||
1238 | if (!guc->preempt_wq) | ||
1239 | return -ENOMEM; | ||
1240 | |||
1241 | for_each_engine(engine, dev_priv, id) { | ||
1242 | guc->preempt_work[id].engine = engine; | ||
1243 | INIT_WORK(&guc->preempt_work[id].work, inject_preempt_context); | ||
1244 | } | ||
1245 | |||
1246 | return 0; | ||
1247 | } | ||
1248 | |||
1249 | static void guc_preempt_work_destroy(struct intel_guc *guc) | ||
1250 | { | ||
1251 | struct drm_i915_private *dev_priv = guc_to_i915(guc); | ||
1252 | struct intel_engine_cs *engine; | ||
1253 | enum intel_engine_id id; | ||
1254 | |||
1255 | for_each_engine(engine, dev_priv, id) | ||
1256 | cancel_work_sync(&guc->preempt_work[id].work); | ||
1257 | |||
1258 | destroy_workqueue(guc->preempt_wq); | ||
1259 | guc->preempt_wq = NULL; | ||
1260 | } | ||
1261 | |||
970 | /* | 1262 | /* |
971 | * Set up the memory resources to be shared with the GuC (via the GGTT) | 1263 | * Set up the memory resources to be shared with the GuC (via the GGTT) |
972 | * at firmware loading time. | 1264 | * at firmware loading time. |
973 | */ | 1265 | */ |
974 | int i915_guc_submission_init(struct drm_i915_private *dev_priv) | 1266 | int intel_guc_submission_init(struct intel_guc *guc) |
975 | { | 1267 | { |
976 | struct intel_guc *guc = &dev_priv->guc; | ||
977 | struct i915_vma *vma; | ||
978 | void *vaddr; | ||
979 | int ret; | 1268 | int ret; |
980 | 1269 | ||
981 | if (guc->stage_desc_pool) | 1270 | if (guc->stage_desc_pool) |
982 | return 0; | 1271 | return 0; |
983 | 1272 | ||
984 | vma = intel_guc_allocate_vma(guc, | 1273 | ret = guc_stage_desc_pool_create(guc); |
985 | PAGE_ALIGN(sizeof(struct guc_stage_desc) * | 1274 | if (ret) |
986 | GUC_MAX_STAGE_DESCRIPTORS)); | 1275 | return ret; |
987 | if (IS_ERR(vma)) | 1276 | /* |
988 | return PTR_ERR(vma); | 1277 | * Keep static analysers happy, let them know that we allocated the |
989 | 1278 | * vma after testing that it didn't exist earlier. | |
990 | guc->stage_desc_pool = vma; | 1279 | */ |
991 | 1280 | GEM_BUG_ON(!guc->stage_desc_pool); | |
992 | vaddr = i915_gem_object_pin_map(guc->stage_desc_pool->obj, I915_MAP_WB); | ||
993 | if (IS_ERR(vaddr)) { | ||
994 | ret = PTR_ERR(vaddr); | ||
995 | goto err_vma; | ||
996 | } | ||
997 | 1281 | ||
998 | guc->stage_desc_pool_vaddr = vaddr; | 1282 | ret = guc_shared_data_create(guc); |
1283 | if (ret) | ||
1284 | goto err_stage_desc_pool; | ||
1285 | GEM_BUG_ON(!guc->shared_data); | ||
999 | 1286 | ||
1000 | ret = intel_guc_log_create(guc); | 1287 | ret = intel_guc_log_create(guc); |
1001 | if (ret < 0) | 1288 | if (ret < 0) |
1002 | goto err_vaddr; | 1289 | goto err_shared_data; |
1003 | 1290 | ||
1004 | ret = guc_ads_create(guc); | 1291 | ret = guc_preempt_work_create(guc); |
1005 | if (ret < 0) | 1292 | if (ret) |
1006 | goto err_log; | 1293 | goto err_log; |
1294 | GEM_BUG_ON(!guc->preempt_wq); | ||
1007 | 1295 | ||
1008 | ida_init(&guc->stage_ids); | 1296 | ret = guc_ads_create(guc); |
1297 | if (ret < 0) | ||
1298 | goto err_wq; | ||
1299 | GEM_BUG_ON(!guc->ads_vma); | ||
1009 | 1300 | ||
1010 | return 0; | 1301 | return 0; |
1011 | 1302 | ||
1303 | err_wq: | ||
1304 | guc_preempt_work_destroy(guc); | ||
1012 | err_log: | 1305 | err_log: |
1013 | intel_guc_log_destroy(guc); | 1306 | intel_guc_log_destroy(guc); |
1014 | err_vaddr: | 1307 | err_shared_data: |
1015 | i915_gem_object_unpin_map(guc->stage_desc_pool->obj); | 1308 | guc_shared_data_destroy(guc); |
1016 | err_vma: | 1309 | err_stage_desc_pool: |
1017 | i915_vma_unpin_and_release(&guc->stage_desc_pool); | 1310 | guc_stage_desc_pool_destroy(guc); |
1018 | return ret; | 1311 | return ret; |
1019 | } | 1312 | } |
1020 | 1313 | ||
1021 | void i915_guc_submission_fini(struct drm_i915_private *dev_priv) | 1314 | void intel_guc_submission_fini(struct intel_guc *guc) |
1022 | { | 1315 | { |
1023 | struct intel_guc *guc = &dev_priv->guc; | ||
1024 | |||
1025 | ida_destroy(&guc->stage_ids); | ||
1026 | guc_ads_destroy(guc); | 1316 | guc_ads_destroy(guc); |
1317 | guc_preempt_work_destroy(guc); | ||
1027 | intel_guc_log_destroy(guc); | 1318 | intel_guc_log_destroy(guc); |
1028 | i915_gem_object_unpin_map(guc->stage_desc_pool->obj); | 1319 | guc_shared_data_destroy(guc); |
1029 | i915_vma_unpin_and_release(&guc->stage_desc_pool); | 1320 | guc_stage_desc_pool_destroy(guc); |
1030 | } | 1321 | } |
1031 | 1322 | ||
1032 | static void guc_interrupts_capture(struct drm_i915_private *dev_priv) | 1323 | static void guc_interrupts_capture(struct drm_i915_private *dev_priv) |
@@ -1036,7 +1327,9 @@ static void guc_interrupts_capture(struct drm_i915_private *dev_priv) | |||
1036 | enum intel_engine_id id; | 1327 | enum intel_engine_id id; |
1037 | int irqs; | 1328 | int irqs; |
1038 | 1329 | ||
1039 | /* tell all command streamers to forward interrupts (but not vblank) to GuC */ | 1330 | /* tell all command streamers to forward interrupts (but not vblank) |
1331 | * to GuC | ||
1332 | */ | ||
1040 | irqs = _MASKED_BIT_ENABLE(GFX_INTERRUPT_STEERING); | 1333 | irqs = _MASKED_BIT_ENABLE(GFX_INTERRUPT_STEERING); |
1041 | for_each_engine(engine, dev_priv, id) | 1334 | for_each_engine(engine, dev_priv, id) |
1042 | I915_WRITE(RING_MODE_GEN7(engine), irqs); | 1335 | I915_WRITE(RING_MODE_GEN7(engine), irqs); |
@@ -1097,10 +1390,19 @@ static void guc_interrupts_release(struct drm_i915_private *dev_priv) | |||
1097 | rps->pm_intrmsk_mbz &= ~ARAT_EXPIRED_INTRMSK; | 1390 | rps->pm_intrmsk_mbz &= ~ARAT_EXPIRED_INTRMSK; |
1098 | } | 1391 | } |
1099 | 1392 | ||
1100 | int i915_guc_submission_enable(struct drm_i915_private *dev_priv) | 1393 | static void guc_submission_park(struct intel_engine_cs *engine) |
1101 | { | 1394 | { |
1102 | struct intel_guc *guc = &dev_priv->guc; | 1395 | intel_engine_unpin_breadcrumbs_irq(engine); |
1103 | struct i915_guc_client *client = guc->execbuf_client; | 1396 | } |
1397 | |||
1398 | static void guc_submission_unpark(struct intel_engine_cs *engine) | ||
1399 | { | ||
1400 | intel_engine_pin_breadcrumbs_irq(engine); | ||
1401 | } | ||
1402 | |||
1403 | int intel_guc_submission_enable(struct intel_guc *guc) | ||
1404 | { | ||
1405 | struct drm_i915_private *dev_priv = guc_to_i915(guc); | ||
1104 | struct intel_engine_cs *engine; | 1406 | struct intel_engine_cs *engine; |
1105 | enum intel_engine_id id; | 1407 | enum intel_engine_id id; |
1106 | int err; | 1408 | int err; |
@@ -1118,61 +1420,62 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv) | |||
1118 | sizeof(struct guc_wq_item) * | 1420 | sizeof(struct guc_wq_item) * |
1119 | I915_NUM_ENGINES > GUC_WQ_SIZE); | 1421 | I915_NUM_ENGINES > GUC_WQ_SIZE); |
1120 | 1422 | ||
1121 | if (!client) { | 1423 | /* |
1122 | client = guc_client_alloc(dev_priv, | 1424 | * We're being called on both module initialization and on reset, |
1123 | INTEL_INFO(dev_priv)->ring_mask, | 1425 | * until this flow is changed, we're using regular client presence to |
1124 | GUC_CLIENT_PRIORITY_KMD_NORMAL, | 1426 | * determine which case are we in, and whether we should allocate new |
1125 | dev_priv->kernel_context); | 1427 | * clients or just reset their workqueues. |
1126 | if (IS_ERR(client)) { | 1428 | */ |
1127 | DRM_ERROR("Failed to create GuC client for execbuf!\n"); | 1429 | if (!guc->execbuf_client) { |
1128 | return PTR_ERR(client); | 1430 | err = guc_clients_create(guc); |
1129 | } | 1431 | if (err) |
1130 | 1432 | return err; | |
1131 | guc->execbuf_client = client; | 1433 | } else { |
1434 | guc_reset_wq(guc->execbuf_client); | ||
1435 | guc_reset_wq(guc->preempt_client); | ||
1132 | } | 1436 | } |
1133 | 1437 | ||
1134 | err = intel_guc_sample_forcewake(guc); | 1438 | err = intel_guc_sample_forcewake(guc); |
1135 | if (err) | 1439 | if (err) |
1136 | goto err_execbuf_client; | 1440 | goto err_free_clients; |
1137 | |||
1138 | guc_reset_wq(client); | ||
1139 | 1441 | ||
1140 | err = guc_init_doorbell_hw(guc); | 1442 | err = guc_init_doorbell_hw(guc); |
1141 | if (err) | 1443 | if (err) |
1142 | goto err_execbuf_client; | 1444 | goto err_free_clients; |
1143 | 1445 | ||
1144 | /* Take over from manual control of ELSP (execlists) */ | 1446 | /* Take over from manual control of ELSP (execlists) */ |
1145 | guc_interrupts_capture(dev_priv); | 1447 | guc_interrupts_capture(dev_priv); |
1146 | 1448 | ||
1147 | for_each_engine(engine, dev_priv, id) { | 1449 | for_each_engine(engine, dev_priv, id) { |
1148 | struct intel_engine_execlists * const execlists = &engine->execlists; | 1450 | struct intel_engine_execlists * const execlists = |
1149 | /* The tasklet was initialised by execlists, and may be in | 1451 | &engine->execlists; |
1150 | * a state of flux (across a reset) and so we just want to | 1452 | |
1151 | * take over the callback without changing any other state | 1453 | execlists->tasklet.func = guc_submission_tasklet; |
1152 | * in the tasklet. | 1454 | engine->park = guc_submission_park; |
1153 | */ | 1455 | engine->unpark = guc_submission_unpark; |
1154 | execlists->irq_tasklet.func = i915_guc_irq_handler; | ||
1155 | clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); | ||
1156 | tasklet_schedule(&execlists->irq_tasklet); | ||
1157 | } | 1456 | } |
1158 | 1457 | ||
1159 | return 0; | 1458 | return 0; |
1160 | 1459 | ||
1161 | err_execbuf_client: | 1460 | err_free_clients: |
1162 | guc_client_free(guc->execbuf_client); | 1461 | guc_clients_destroy(guc); |
1163 | guc->execbuf_client = NULL; | ||
1164 | return err; | 1462 | return err; |
1165 | } | 1463 | } |
1166 | 1464 | ||
1167 | void i915_guc_submission_disable(struct drm_i915_private *dev_priv) | 1465 | void intel_guc_submission_disable(struct intel_guc *guc) |
1168 | { | 1466 | { |
1169 | struct intel_guc *guc = &dev_priv->guc; | 1467 | struct drm_i915_private *dev_priv = guc_to_i915(guc); |
1468 | |||
1469 | GEM_BUG_ON(dev_priv->gt.awake); /* GT should be parked first */ | ||
1170 | 1470 | ||
1171 | guc_interrupts_release(dev_priv); | 1471 | guc_interrupts_release(dev_priv); |
1172 | 1472 | ||
1173 | /* Revert back to manual ELSP submission */ | 1473 | /* Revert back to manual ELSP submission */ |
1174 | intel_engines_reset_default_submission(dev_priv); | 1474 | intel_engines_reset_default_submission(dev_priv); |
1175 | 1475 | ||
1176 | guc_client_free(guc->execbuf_client); | 1476 | guc_clients_destroy(guc); |
1177 | guc->execbuf_client = NULL; | ||
1178 | } | 1477 | } |
1478 | |||
1479 | #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) | ||
1480 | #include "selftests/intel_guc.c" | ||
1481 | #endif | ||
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.h b/drivers/gpu/drm/i915/intel_guc_submission.h index cb4353b59059..e901192ee469 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.h +++ b/drivers/gpu/drm/i915/intel_guc_submission.h | |||
@@ -52,7 +52,7 @@ struct drm_i915_private; | |||
52 | * queue (a circular array of work items), again described in the process | 52 | * queue (a circular array of work items), again described in the process |
53 | * descriptor. Work queue pages are mapped momentarily as required. | 53 | * descriptor. Work queue pages are mapped momentarily as required. |
54 | */ | 54 | */ |
55 | struct i915_guc_client { | 55 | struct intel_guc_client { |
56 | struct i915_vma *vma; | 56 | struct i915_vma *vma; |
57 | void *vaddr; | 57 | void *vaddr; |
58 | struct i915_gem_context *owner; | 58 | struct i915_gem_context *owner; |
@@ -67,14 +67,15 @@ struct i915_guc_client { | |||
67 | u16 doorbell_id; | 67 | u16 doorbell_id; |
68 | unsigned long doorbell_offset; | 68 | unsigned long doorbell_offset; |
69 | 69 | ||
70 | /* Protects GuC client's WQ access */ | ||
70 | spinlock_t wq_lock; | 71 | spinlock_t wq_lock; |
71 | /* Per-engine counts of GuC submissions */ | 72 | /* Per-engine counts of GuC submissions */ |
72 | u64 submissions[I915_NUM_ENGINES]; | 73 | u64 submissions[I915_NUM_ENGINES]; |
73 | }; | 74 | }; |
74 | 75 | ||
75 | int i915_guc_submission_init(struct drm_i915_private *dev_priv); | 76 | int intel_guc_submission_init(struct intel_guc *guc); |
76 | int i915_guc_submission_enable(struct drm_i915_private *dev_priv); | 77 | int intel_guc_submission_enable(struct intel_guc *guc); |
77 | void i915_guc_submission_disable(struct drm_i915_private *dev_priv); | 78 | void intel_guc_submission_disable(struct intel_guc *guc); |
78 | void i915_guc_submission_fini(struct drm_i915_private *dev_priv); | 79 | void intel_guc_submission_fini(struct intel_guc *guc); |
79 | 80 | ||
80 | #endif | 81 | #endif |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index e039702c1907..a40f35af225c 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -186,7 +186,7 @@ static bool g4x_infoframe_enabled(struct drm_encoder *encoder, | |||
186 | if ((val & VIDEO_DIP_ENABLE) == 0) | 186 | if ((val & VIDEO_DIP_ENABLE) == 0) |
187 | return false; | 187 | return false; |
188 | 188 | ||
189 | if ((val & VIDEO_DIP_PORT_MASK) != VIDEO_DIP_PORT(intel_dig_port->port)) | 189 | if ((val & VIDEO_DIP_PORT_MASK) != VIDEO_DIP_PORT(intel_dig_port->base.port)) |
190 | return false; | 190 | return false; |
191 | 191 | ||
192 | return val & (VIDEO_DIP_ENABLE_AVI | | 192 | return val & (VIDEO_DIP_ENABLE_AVI | |
@@ -245,7 +245,7 @@ static bool ibx_infoframe_enabled(struct drm_encoder *encoder, | |||
245 | if ((val & VIDEO_DIP_ENABLE) == 0) | 245 | if ((val & VIDEO_DIP_ENABLE) == 0) |
246 | return false; | 246 | return false; |
247 | 247 | ||
248 | if ((val & VIDEO_DIP_PORT_MASK) != VIDEO_DIP_PORT(intel_dig_port->port)) | 248 | if ((val & VIDEO_DIP_PORT_MASK) != VIDEO_DIP_PORT(intel_dig_port->base.port)) |
249 | return false; | 249 | return false; |
250 | 250 | ||
251 | return val & (VIDEO_DIP_ENABLE_AVI | | 251 | return val & (VIDEO_DIP_ENABLE_AVI | |
@@ -362,7 +362,7 @@ static bool vlv_infoframe_enabled(struct drm_encoder *encoder, | |||
362 | if ((val & VIDEO_DIP_ENABLE) == 0) | 362 | if ((val & VIDEO_DIP_ENABLE) == 0) |
363 | return false; | 363 | return false; |
364 | 364 | ||
365 | if ((val & VIDEO_DIP_PORT_MASK) != VIDEO_DIP_PORT(intel_dig_port->port)) | 365 | if ((val & VIDEO_DIP_PORT_MASK) != VIDEO_DIP_PORT(intel_dig_port->base.port)) |
366 | return false; | 366 | return false; |
367 | 367 | ||
368 | return val & (VIDEO_DIP_ENABLE_AVI | | 368 | return val & (VIDEO_DIP_ENABLE_AVI | |
@@ -538,7 +538,7 @@ static void g4x_set_infoframes(struct drm_encoder *encoder, | |||
538 | struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi; | 538 | struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi; |
539 | i915_reg_t reg = VIDEO_DIP_CTL; | 539 | i915_reg_t reg = VIDEO_DIP_CTL; |
540 | u32 val = I915_READ(reg); | 540 | u32 val = I915_READ(reg); |
541 | u32 port = VIDEO_DIP_PORT(intel_dig_port->port); | 541 | u32 port = VIDEO_DIP_PORT(intel_dig_port->base.port); |
542 | 542 | ||
543 | assert_hdmi_port_disabled(intel_hdmi); | 543 | assert_hdmi_port_disabled(intel_hdmi); |
544 | 544 | ||
@@ -689,7 +689,7 @@ static void ibx_set_infoframes(struct drm_encoder *encoder, | |||
689 | struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi; | 689 | struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi; |
690 | i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe); | 690 | i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe); |
691 | u32 val = I915_READ(reg); | 691 | u32 val = I915_READ(reg); |
692 | u32 port = VIDEO_DIP_PORT(intel_dig_port->port); | 692 | u32 port = VIDEO_DIP_PORT(intel_dig_port->base.port); |
693 | 693 | ||
694 | assert_hdmi_port_disabled(intel_hdmi); | 694 | assert_hdmi_port_disabled(intel_hdmi); |
695 | 695 | ||
@@ -785,7 +785,7 @@ static void vlv_set_infoframes(struct drm_encoder *encoder, | |||
785 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | 785 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
786 | i915_reg_t reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe); | 786 | i915_reg_t reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe); |
787 | u32 val = I915_READ(reg); | 787 | u32 val = I915_READ(reg); |
788 | u32 port = VIDEO_DIP_PORT(intel_dig_port->port); | 788 | u32 port = VIDEO_DIP_PORT(intel_dig_port->base.port); |
789 | 789 | ||
790 | assert_hdmi_port_disabled(intel_hdmi); | 790 | assert_hdmi_port_disabled(intel_hdmi); |
791 | 791 | ||
@@ -960,6 +960,8 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder, | |||
960 | u32 tmp, flags = 0; | 960 | u32 tmp, flags = 0; |
961 | int dotclock; | 961 | int dotclock; |
962 | 962 | ||
963 | pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); | ||
964 | |||
963 | tmp = I915_READ(intel_hdmi->hdmi_reg); | 965 | tmp = I915_READ(intel_hdmi->hdmi_reg); |
964 | 966 | ||
965 | if (tmp & SDVO_HSYNC_ACTIVE_HIGH) | 967 | if (tmp & SDVO_HSYNC_ACTIVE_HIGH) |
@@ -1207,7 +1209,8 @@ static void g4x_disable_hdmi(struct intel_encoder *encoder, | |||
1207 | const struct drm_connector_state *old_conn_state) | 1209 | const struct drm_connector_state *old_conn_state) |
1208 | { | 1210 | { |
1209 | if (old_crtc_state->has_audio) | 1211 | if (old_crtc_state->has_audio) |
1210 | intel_audio_codec_disable(encoder); | 1212 | intel_audio_codec_disable(encoder, |
1213 | old_crtc_state, old_conn_state); | ||
1211 | 1214 | ||
1212 | intel_disable_hdmi(encoder, old_crtc_state, old_conn_state); | 1215 | intel_disable_hdmi(encoder, old_crtc_state, old_conn_state); |
1213 | } | 1216 | } |
@@ -1217,7 +1220,8 @@ static void pch_disable_hdmi(struct intel_encoder *encoder, | |||
1217 | const struct drm_connector_state *old_conn_state) | 1220 | const struct drm_connector_state *old_conn_state) |
1218 | { | 1221 | { |
1219 | if (old_crtc_state->has_audio) | 1222 | if (old_crtc_state->has_audio) |
1220 | intel_audio_codec_disable(encoder); | 1223 | intel_audio_codec_disable(encoder, |
1224 | old_crtc_state, old_conn_state); | ||
1221 | } | 1225 | } |
1222 | 1226 | ||
1223 | static void pch_post_disable_hdmi(struct intel_encoder *encoder, | 1227 | static void pch_post_disable_hdmi(struct intel_encoder *encoder, |
@@ -1227,24 +1231,34 @@ static void pch_post_disable_hdmi(struct intel_encoder *encoder, | |||
1227 | intel_disable_hdmi(encoder, old_crtc_state, old_conn_state); | 1231 | intel_disable_hdmi(encoder, old_crtc_state, old_conn_state); |
1228 | } | 1232 | } |
1229 | 1233 | ||
1230 | static int intel_hdmi_source_max_tmds_clock(struct drm_i915_private *dev_priv) | 1234 | static int intel_hdmi_source_max_tmds_clock(struct intel_encoder *encoder) |
1231 | { | 1235 | { |
1232 | if (IS_G4X(dev_priv)) | 1236 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
1233 | return 165000; | 1237 | const struct ddi_vbt_port_info *info = |
1234 | else if (IS_GEMINILAKE(dev_priv)) | 1238 | &dev_priv->vbt.ddi_port_info[encoder->port]; |
1235 | return 594000; | 1239 | int max_tmds_clock; |
1236 | else if (IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8) | 1240 | |
1237 | return 300000; | 1241 | if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) |
1242 | max_tmds_clock = 594000; | ||
1243 | else if (INTEL_GEN(dev_priv) >= 8 || IS_HASWELL(dev_priv)) | ||
1244 | max_tmds_clock = 300000; | ||
1245 | else if (INTEL_GEN(dev_priv) >= 5) | ||
1246 | max_tmds_clock = 225000; | ||
1238 | else | 1247 | else |
1239 | return 225000; | 1248 | max_tmds_clock = 165000; |
1249 | |||
1250 | if (info->max_tmds_clock) | ||
1251 | max_tmds_clock = min(max_tmds_clock, info->max_tmds_clock); | ||
1252 | |||
1253 | return max_tmds_clock; | ||
1240 | } | 1254 | } |
1241 | 1255 | ||
1242 | static int hdmi_port_clock_limit(struct intel_hdmi *hdmi, | 1256 | static int hdmi_port_clock_limit(struct intel_hdmi *hdmi, |
1243 | bool respect_downstream_limits, | 1257 | bool respect_downstream_limits, |
1244 | bool force_dvi) | 1258 | bool force_dvi) |
1245 | { | 1259 | { |
1246 | struct drm_device *dev = intel_hdmi_to_dev(hdmi); | 1260 | struct intel_encoder *encoder = &hdmi_to_dig_port(hdmi)->base; |
1247 | int max_tmds_clock = intel_hdmi_source_max_tmds_clock(to_i915(dev)); | 1261 | int max_tmds_clock = intel_hdmi_source_max_tmds_clock(encoder); |
1248 | 1262 | ||
1249 | if (respect_downstream_limits) { | 1263 | if (respect_downstream_limits) { |
1250 | struct intel_connector *connector = hdmi->attached_connector; | 1264 | struct intel_connector *connector = hdmi->attached_connector; |
@@ -1339,6 +1353,12 @@ static bool hdmi_12bpc_possible(const struct intel_crtc_state *crtc_state) | |||
1339 | if (HAS_GMCH_DISPLAY(dev_priv)) | 1353 | if (HAS_GMCH_DISPLAY(dev_priv)) |
1340 | return false; | 1354 | return false; |
1341 | 1355 | ||
1356 | if (crtc_state->pipe_bpp <= 8*3) | ||
1357 | return false; | ||
1358 | |||
1359 | if (!crtc_state->has_hdmi_sink) | ||
1360 | return false; | ||
1361 | |||
1342 | /* | 1362 | /* |
1343 | * HDMI 12bpc affects the clocks, so it's only possible | 1363 | * HDMI 12bpc affects the clocks, so it's only possible |
1344 | * when not cloning with other encoder types. | 1364 | * when not cloning with other encoder types. |
@@ -1464,9 +1484,8 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, | |||
1464 | * outputs. We also need to check that the higher clock still fits | 1484 | * outputs. We also need to check that the higher clock still fits |
1465 | * within limits. | 1485 | * within limits. |
1466 | */ | 1486 | */ |
1467 | if (pipe_config->pipe_bpp > 8*3 && pipe_config->has_hdmi_sink && !force_dvi && | 1487 | if (hdmi_12bpc_possible(pipe_config) && |
1468 | hdmi_port_clock_valid(intel_hdmi, clock_12bpc, true, force_dvi) == MODE_OK && | 1488 | hdmi_port_clock_valid(intel_hdmi, clock_12bpc, true, force_dvi) == MODE_OK) { |
1469 | hdmi_12bpc_possible(pipe_config)) { | ||
1470 | DRM_DEBUG_KMS("picking bpc to 12 for HDMI output\n"); | 1489 | DRM_DEBUG_KMS("picking bpc to 12 for HDMI output\n"); |
1471 | desired_bpp = 12*3; | 1490 | desired_bpp = 12*3; |
1472 | 1491 | ||
@@ -1495,7 +1514,8 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, | |||
1495 | 1514 | ||
1496 | pipe_config->lane_count = 4; | 1515 | pipe_config->lane_count = 4; |
1497 | 1516 | ||
1498 | if (scdc->scrambling.supported && IS_GEMINILAKE(dev_priv)) { | 1517 | if (scdc->scrambling.supported && (INTEL_GEN(dev_priv) >= 10 || |
1518 | IS_GEMINILAKE(dev_priv))) { | ||
1499 | if (scdc->scrambling.low_rates) | 1519 | if (scdc->scrambling.low_rates) |
1500 | pipe_config->hdmi_scrambling = true; | 1520 | pipe_config->hdmi_scrambling = true; |
1501 | 1521 | ||
@@ -1529,7 +1549,7 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid) | |||
1529 | { | 1549 | { |
1530 | struct drm_i915_private *dev_priv = to_i915(connector->dev); | 1550 | struct drm_i915_private *dev_priv = to_i915(connector->dev); |
1531 | struct intel_hdmi *hdmi = intel_attached_hdmi(connector); | 1551 | struct intel_hdmi *hdmi = intel_attached_hdmi(connector); |
1532 | enum port port = hdmi_to_dig_port(hdmi)->port; | 1552 | enum port port = hdmi_to_dig_port(hdmi)->base.port; |
1533 | struct i2c_adapter *adapter = | 1553 | struct i2c_adapter *adapter = |
1534 | intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus); | 1554 | intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus); |
1535 | enum drm_dp_dual_mode_type type = drm_dp_dual_mode_detect(adapter); | 1555 | enum drm_dp_dual_mode_type type = drm_dp_dual_mode_detect(adapter); |
@@ -1613,12 +1633,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) | |||
1613 | 1633 | ||
1614 | intel_hdmi_unset_edid(connector); | 1634 | intel_hdmi_unset_edid(connector); |
1615 | 1635 | ||
1616 | if (intel_hdmi_set_edid(connector)) { | 1636 | if (intel_hdmi_set_edid(connector)) |
1617 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); | ||
1618 | |||
1619 | hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; | ||
1620 | status = connector_status_connected; | 1637 | status = connector_status_connected; |
1621 | } else | 1638 | else |
1622 | status = connector_status_disconnected; | 1639 | status = connector_status_disconnected; |
1623 | 1640 | ||
1624 | intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); | 1641 | intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); |
@@ -1629,8 +1646,6 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) | |||
1629 | static void | 1646 | static void |
1630 | intel_hdmi_force(struct drm_connector *connector) | 1647 | intel_hdmi_force(struct drm_connector *connector) |
1631 | { | 1648 | { |
1632 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); | ||
1633 | |||
1634 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", | 1649 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", |
1635 | connector->base.id, connector->name); | 1650 | connector->base.id, connector->name); |
1636 | 1651 | ||
@@ -1640,7 +1655,6 @@ intel_hdmi_force(struct drm_connector *connector) | |||
1640 | return; | 1655 | return; |
1641 | 1656 | ||
1642 | intel_hdmi_set_edid(connector); | 1657 | intel_hdmi_set_edid(connector); |
1643 | hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; | ||
1644 | } | 1658 | } |
1645 | 1659 | ||
1646 | static int intel_hdmi_get_modes(struct drm_connector *connector) | 1660 | static int intel_hdmi_get_modes(struct drm_connector *connector) |
@@ -1673,10 +1687,9 @@ static void vlv_hdmi_pre_enable(struct intel_encoder *encoder, | |||
1673 | const struct drm_connector_state *conn_state) | 1687 | const struct drm_connector_state *conn_state) |
1674 | { | 1688 | { |
1675 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); | 1689 | struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); |
1676 | struct drm_device *dev = encoder->base.dev; | 1690 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
1677 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
1678 | 1691 | ||
1679 | vlv_phy_pre_encoder_enable(encoder); | 1692 | vlv_phy_pre_encoder_enable(encoder, pipe_config); |
1680 | 1693 | ||
1681 | /* HDMI 1.0V-2dB */ | 1694 | /* HDMI 1.0V-2dB */ |
1682 | vlv_set_phy_signal_level(encoder, 0x2b245f5f, 0x00002000, 0x5578b83a, | 1695 | vlv_set_phy_signal_level(encoder, 0x2b245f5f, 0x00002000, 0x5578b83a, |
@@ -1697,7 +1710,7 @@ static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder, | |||
1697 | { | 1710 | { |
1698 | intel_hdmi_prepare(encoder, pipe_config); | 1711 | intel_hdmi_prepare(encoder, pipe_config); |
1699 | 1712 | ||
1700 | vlv_phy_pre_pll_enable(encoder); | 1713 | vlv_phy_pre_pll_enable(encoder, pipe_config); |
1701 | } | 1714 | } |
1702 | 1715 | ||
1703 | static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder, | 1716 | static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder, |
@@ -1706,14 +1719,14 @@ static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder, | |||
1706 | { | 1719 | { |
1707 | intel_hdmi_prepare(encoder, pipe_config); | 1720 | intel_hdmi_prepare(encoder, pipe_config); |
1708 | 1721 | ||
1709 | chv_phy_pre_pll_enable(encoder); | 1722 | chv_phy_pre_pll_enable(encoder, pipe_config); |
1710 | } | 1723 | } |
1711 | 1724 | ||
1712 | static void chv_hdmi_post_pll_disable(struct intel_encoder *encoder, | 1725 | static void chv_hdmi_post_pll_disable(struct intel_encoder *encoder, |
1713 | const struct intel_crtc_state *old_crtc_state, | 1726 | const struct intel_crtc_state *old_crtc_state, |
1714 | const struct drm_connector_state *old_conn_state) | 1727 | const struct drm_connector_state *old_conn_state) |
1715 | { | 1728 | { |
1716 | chv_phy_post_pll_disable(encoder); | 1729 | chv_phy_post_pll_disable(encoder, old_crtc_state); |
1717 | } | 1730 | } |
1718 | 1731 | ||
1719 | static void vlv_hdmi_post_disable(struct intel_encoder *encoder, | 1732 | static void vlv_hdmi_post_disable(struct intel_encoder *encoder, |
@@ -1721,7 +1734,7 @@ static void vlv_hdmi_post_disable(struct intel_encoder *encoder, | |||
1721 | const struct drm_connector_state *old_conn_state) | 1734 | const struct drm_connector_state *old_conn_state) |
1722 | { | 1735 | { |
1723 | /* Reset lanes to avoid HDMI flicker (VLV w/a) */ | 1736 | /* Reset lanes to avoid HDMI flicker (VLV w/a) */ |
1724 | vlv_phy_reset_lanes(encoder); | 1737 | vlv_phy_reset_lanes(encoder, old_crtc_state); |
1725 | } | 1738 | } |
1726 | 1739 | ||
1727 | static void chv_hdmi_post_disable(struct intel_encoder *encoder, | 1740 | static void chv_hdmi_post_disable(struct intel_encoder *encoder, |
@@ -1734,7 +1747,7 @@ static void chv_hdmi_post_disable(struct intel_encoder *encoder, | |||
1734 | mutex_lock(&dev_priv->sb_lock); | 1747 | mutex_lock(&dev_priv->sb_lock); |
1735 | 1748 | ||
1736 | /* Assert data lane reset */ | 1749 | /* Assert data lane reset */ |
1737 | chv_data_lane_soft_reset(encoder, true); | 1750 | chv_data_lane_soft_reset(encoder, old_crtc_state, true); |
1738 | 1751 | ||
1739 | mutex_unlock(&dev_priv->sb_lock); | 1752 | mutex_unlock(&dev_priv->sb_lock); |
1740 | } | 1753 | } |
@@ -1747,7 +1760,7 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder, | |||
1747 | struct drm_device *dev = encoder->base.dev; | 1760 | struct drm_device *dev = encoder->base.dev; |
1748 | struct drm_i915_private *dev_priv = to_i915(dev); | 1761 | struct drm_i915_private *dev_priv = to_i915(dev); |
1749 | 1762 | ||
1750 | chv_phy_pre_encoder_enable(encoder); | 1763 | chv_phy_pre_encoder_enable(encoder, pipe_config); |
1751 | 1764 | ||
1752 | /* FIXME: Program the support xxx V-dB */ | 1765 | /* FIXME: Program the support xxx V-dB */ |
1753 | /* Use 800mV-0dB */ | 1766 | /* Use 800mV-0dB */ |
@@ -2006,7 +2019,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, | |||
2006 | struct intel_encoder *intel_encoder = &intel_dig_port->base; | 2019 | struct intel_encoder *intel_encoder = &intel_dig_port->base; |
2007 | struct drm_device *dev = intel_encoder->base.dev; | 2020 | struct drm_device *dev = intel_encoder->base.dev; |
2008 | struct drm_i915_private *dev_priv = to_i915(dev); | 2021 | struct drm_i915_private *dev_priv = to_i915(dev); |
2009 | enum port port = intel_dig_port->port; | 2022 | enum port port = intel_encoder->port; |
2010 | 2023 | ||
2011 | DRM_DEBUG_KMS("Adding HDMI connector on port %c\n", | 2024 | DRM_DEBUG_KMS("Adding HDMI connector on port %c\n", |
2012 | port_name(port)); | 2025 | port_name(port)); |
@@ -2024,7 +2037,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, | |||
2024 | connector->doublescan_allowed = 0; | 2037 | connector->doublescan_allowed = 0; |
2025 | connector->stereo_allowed = 1; | 2038 | connector->stereo_allowed = 1; |
2026 | 2039 | ||
2027 | if (IS_GEMINILAKE(dev_priv)) | 2040 | if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) |
2028 | connector->ycbcr_420_allowed = true; | 2041 | connector->ycbcr_420_allowed = true; |
2029 | 2042 | ||
2030 | intel_hdmi->ddc_bus = intel_hdmi_ddc_pin(dev_priv, port); | 2043 | intel_hdmi->ddc_bus = intel_hdmi_ddc_pin(dev_priv, port); |
@@ -2126,7 +2139,6 @@ void intel_hdmi_init(struct drm_i915_private *dev_priv, | |||
2126 | if (IS_G4X(dev_priv)) | 2139 | if (IS_G4X(dev_priv)) |
2127 | intel_encoder->cloneable |= 1 << INTEL_OUTPUT_HDMI; | 2140 | intel_encoder->cloneable |= 1 << INTEL_OUTPUT_HDMI; |
2128 | 2141 | ||
2129 | intel_dig_port->port = port; | ||
2130 | intel_dig_port->hdmi.hdmi_reg = hdmi_reg; | 2142 | intel_dig_port->hdmi.hdmi_reg = hdmi_reg; |
2131 | intel_dig_port->dp.output_reg = INVALID_MMIO_REG; | 2143 | intel_dig_port->dp.output_reg = INVALID_MMIO_REG; |
2132 | intel_dig_port->max_lanes = 4; | 2144 | intel_dig_port->max_lanes = 4; |
diff --git a/drivers/gpu/drm/i915/intel_huc.c b/drivers/gpu/drm/i915/intel_huc.c index c8a48cbc2b7d..98d17254593c 100644 --- a/drivers/gpu/drm/i915/intel_huc.c +++ b/drivers/gpu/drm/i915/intel_huc.c | |||
@@ -151,7 +151,7 @@ static int huc_ucode_xfer(struct intel_uc_fw *huc_fw, struct i915_vma *vma) | |||
151 | I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(HUC_UKERNEL | START_DMA)); | 151 | I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(HUC_UKERNEL | START_DMA)); |
152 | 152 | ||
153 | /* Wait for DMA to finish */ | 153 | /* Wait for DMA to finish */ |
154 | ret = wait_for((I915_READ(DMA_CTRL) & START_DMA) == 0, 100); | 154 | ret = intel_wait_for_register_fw(dev_priv, DMA_CTRL, START_DMA, 0, 100); |
155 | 155 | ||
156 | DRM_DEBUG_DRIVER("HuC DMA transfer wait over with ret %d\n", ret); | 156 | DRM_DEBUG_DRIVER("HuC DMA transfer wait over with ret %d\n", ret); |
157 | 157 | ||
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index d36e25607435..be6c39adebdf 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c | |||
@@ -136,6 +136,7 @@ | |||
136 | #include <drm/drmP.h> | 136 | #include <drm/drmP.h> |
137 | #include <drm/i915_drm.h> | 137 | #include <drm/i915_drm.h> |
138 | #include "i915_drv.h" | 138 | #include "i915_drv.h" |
139 | #include "i915_gem_render_state.h" | ||
139 | #include "intel_mocs.h" | 140 | #include "intel_mocs.h" |
140 | 141 | ||
141 | #define RING_EXECLIST_QFULL (1 << 0x2) | 142 | #define RING_EXECLIST_QFULL (1 << 0x2) |
@@ -354,7 +355,7 @@ static void unwind_wa_tail(struct drm_i915_gem_request *rq) | |||
354 | assert_ring_tail_valid(rq->ring, rq->tail); | 355 | assert_ring_tail_valid(rq->ring, rq->tail); |
355 | } | 356 | } |
356 | 357 | ||
357 | static void unwind_incomplete_requests(struct intel_engine_cs *engine) | 358 | static void __unwind_incomplete_requests(struct intel_engine_cs *engine) |
358 | { | 359 | { |
359 | struct drm_i915_gem_request *rq, *rn; | 360 | struct drm_i915_gem_request *rq, *rn; |
360 | struct i915_priolist *uninitialized_var(p); | 361 | struct i915_priolist *uninitialized_var(p); |
@@ -385,6 +386,17 @@ static void unwind_incomplete_requests(struct intel_engine_cs *engine) | |||
385 | } | 386 | } |
386 | } | 387 | } |
387 | 388 | ||
389 | void | ||
390 | execlists_unwind_incomplete_requests(struct intel_engine_execlists *execlists) | ||
391 | { | ||
392 | struct intel_engine_cs *engine = | ||
393 | container_of(execlists, typeof(*engine), execlists); | ||
394 | |||
395 | spin_lock_irq(&engine->timeline->lock); | ||
396 | __unwind_incomplete_requests(engine); | ||
397 | spin_unlock_irq(&engine->timeline->lock); | ||
398 | } | ||
399 | |||
388 | static inline void | 400 | static inline void |
389 | execlists_context_status_change(struct drm_i915_gem_request *rq, | 401 | execlists_context_status_change(struct drm_i915_gem_request *rq, |
390 | unsigned long status) | 402 | unsigned long status) |
@@ -455,6 +467,11 @@ static void execlists_submit_ports(struct intel_engine_cs *engine) | |||
455 | port_set(&port[n], port_pack(rq, count)); | 467 | port_set(&port[n], port_pack(rq, count)); |
456 | desc = execlists_update_context(rq); | 468 | desc = execlists_update_context(rq); |
457 | GEM_DEBUG_EXEC(port[n].context_id = upper_32_bits(desc)); | 469 | GEM_DEBUG_EXEC(port[n].context_id = upper_32_bits(desc)); |
470 | |||
471 | GEM_TRACE("%s in[%d]: ctx=%d.%d, seqno=%x\n", | ||
472 | engine->name, n, | ||
473 | rq->ctx->hw_id, count, | ||
474 | rq->global_seqno); | ||
458 | } else { | 475 | } else { |
459 | GEM_BUG_ON(!n); | 476 | GEM_BUG_ON(!n); |
460 | desc = 0; | 477 | desc = 0; |
@@ -509,17 +526,13 @@ static void inject_preempt_context(struct intel_engine_cs *engine) | |||
509 | ce->ring->tail &= (ce->ring->size - 1); | 526 | ce->ring->tail &= (ce->ring->size - 1); |
510 | ce->lrc_reg_state[CTX_RING_TAIL+1] = ce->ring->tail; | 527 | ce->lrc_reg_state[CTX_RING_TAIL+1] = ce->ring->tail; |
511 | 528 | ||
529 | GEM_TRACE("\n"); | ||
512 | for (n = execlists_num_ports(&engine->execlists); --n; ) | 530 | for (n = execlists_num_ports(&engine->execlists); --n; ) |
513 | elsp_write(0, elsp); | 531 | elsp_write(0, elsp); |
514 | 532 | ||
515 | elsp_write(ce->lrc_desc, elsp); | 533 | elsp_write(ce->lrc_desc, elsp); |
516 | } | 534 | } |
517 | 535 | ||
518 | static bool can_preempt(struct intel_engine_cs *engine) | ||
519 | { | ||
520 | return INTEL_INFO(engine->i915)->has_logical_ring_preemption; | ||
521 | } | ||
522 | |||
523 | static void execlists_dequeue(struct intel_engine_cs *engine) | 536 | static void execlists_dequeue(struct intel_engine_cs *engine) |
524 | { | 537 | { |
525 | struct intel_engine_execlists * const execlists = &engine->execlists; | 538 | struct intel_engine_execlists * const execlists = &engine->execlists; |
@@ -567,7 +580,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) | |||
567 | if (port_count(&port[0]) > 1) | 580 | if (port_count(&port[0]) > 1) |
568 | goto unlock; | 581 | goto unlock; |
569 | 582 | ||
570 | if (can_preempt(engine) && | 583 | if (HAS_LOGICAL_RING_PREEMPTION(engine->i915) && |
571 | rb_entry(rb, struct i915_priolist, node)->priority > | 584 | rb_entry(rb, struct i915_priolist, node)->priority > |
572 | max(last->priotree.priority, 0)) { | 585 | max(last->priotree.priority, 0)) { |
573 | /* | 586 | /* |
@@ -690,8 +703,8 @@ unlock: | |||
690 | } | 703 | } |
691 | } | 704 | } |
692 | 705 | ||
693 | static void | 706 | void |
694 | execlist_cancel_port_requests(struct intel_engine_execlists *execlists) | 707 | execlists_cancel_port_requests(struct intel_engine_execlists * const execlists) |
695 | { | 708 | { |
696 | struct execlist_port *port = execlists->port; | 709 | struct execlist_port *port = execlists->port; |
697 | unsigned int num_ports = execlists_num_ports(execlists); | 710 | unsigned int num_ports = execlists_num_ports(execlists); |
@@ -718,7 +731,7 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) | |||
718 | spin_lock_irqsave(&engine->timeline->lock, flags); | 731 | spin_lock_irqsave(&engine->timeline->lock, flags); |
719 | 732 | ||
720 | /* Cancel the requests on the HW and clear the ELSP tracker. */ | 733 | /* Cancel the requests on the HW and clear the ELSP tracker. */ |
721 | execlist_cancel_port_requests(execlists); | 734 | execlists_cancel_port_requests(execlists); |
722 | 735 | ||
723 | /* Mark all executing requests as skipped. */ | 736 | /* Mark all executing requests as skipped. */ |
724 | list_for_each_entry(rq, &engine->timeline->requests, link) { | 737 | list_for_each_entry(rq, &engine->timeline->requests, link) { |
@@ -768,7 +781,7 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) | |||
768 | * Check the unread Context Status Buffers and manage the submission of new | 781 | * Check the unread Context Status Buffers and manage the submission of new |
769 | * contexts to the ELSP accordingly. | 782 | * contexts to the ELSP accordingly. |
770 | */ | 783 | */ |
771 | static void intel_lrc_irq_handler(unsigned long data) | 784 | static void execlists_submission_tasklet(unsigned long data) |
772 | { | 785 | { |
773 | struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; | 786 | struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; |
774 | struct intel_engine_execlists * const execlists = &engine->execlists; | 787 | struct intel_engine_execlists * const execlists = &engine->execlists; |
@@ -826,6 +839,10 @@ static void intel_lrc_irq_handler(unsigned long data) | |||
826 | head = execlists->csb_head; | 839 | head = execlists->csb_head; |
827 | tail = READ_ONCE(buf[write_idx]); | 840 | tail = READ_ONCE(buf[write_idx]); |
828 | } | 841 | } |
842 | GEM_TRACE("%s cs-irq head=%d [%d], tail=%d [%d]\n", | ||
843 | engine->name, | ||
844 | head, GEN8_CSB_READ_PTR(readl(dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine)))), | ||
845 | tail, GEN8_CSB_WRITE_PTR(readl(dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))))); | ||
829 | 846 | ||
830 | while (head != tail) { | 847 | while (head != tail) { |
831 | struct drm_i915_gem_request *rq; | 848 | struct drm_i915_gem_request *rq; |
@@ -853,16 +870,16 @@ static void intel_lrc_irq_handler(unsigned long data) | |||
853 | */ | 870 | */ |
854 | 871 | ||
855 | status = READ_ONCE(buf[2 * head]); /* maybe mmio! */ | 872 | status = READ_ONCE(buf[2 * head]); /* maybe mmio! */ |
873 | GEM_TRACE("%s csb[%dd]: status=0x%08x:0x%08x\n", | ||
874 | engine->name, head, | ||
875 | status, buf[2*head + 1]); | ||
856 | if (!(status & GEN8_CTX_STATUS_COMPLETED_MASK)) | 876 | if (!(status & GEN8_CTX_STATUS_COMPLETED_MASK)) |
857 | continue; | 877 | continue; |
858 | 878 | ||
859 | if (status & GEN8_CTX_STATUS_ACTIVE_IDLE && | 879 | if (status & GEN8_CTX_STATUS_ACTIVE_IDLE && |
860 | buf[2*head + 1] == PREEMPT_ID) { | 880 | buf[2*head + 1] == PREEMPT_ID) { |
861 | execlist_cancel_port_requests(execlists); | 881 | execlists_cancel_port_requests(execlists); |
862 | 882 | execlists_unwind_incomplete_requests(execlists); | |
863 | spin_lock_irq(&engine->timeline->lock); | ||
864 | unwind_incomplete_requests(engine); | ||
865 | spin_unlock_irq(&engine->timeline->lock); | ||
866 | 883 | ||
867 | GEM_BUG_ON(!execlists_is_active(execlists, | 884 | GEM_BUG_ON(!execlists_is_active(execlists, |
868 | EXECLISTS_ACTIVE_PREEMPT)); | 885 | EXECLISTS_ACTIVE_PREEMPT)); |
@@ -883,6 +900,10 @@ static void intel_lrc_irq_handler(unsigned long data) | |||
883 | GEM_DEBUG_BUG_ON(buf[2 * head + 1] != port->context_id); | 900 | GEM_DEBUG_BUG_ON(buf[2 * head + 1] != port->context_id); |
884 | 901 | ||
885 | rq = port_unpack(port, &count); | 902 | rq = port_unpack(port, &count); |
903 | GEM_TRACE("%s out[0]: ctx=%d.%d, seqno=%x\n", | ||
904 | engine->name, | ||
905 | rq->ctx->hw_id, count, | ||
906 | rq->global_seqno); | ||
886 | GEM_BUG_ON(count == 0); | 907 | GEM_BUG_ON(count == 0); |
887 | if (--count == 0) { | 908 | if (--count == 0) { |
888 | GEM_BUG_ON(status & GEN8_CTX_STATUS_PREEMPTED); | 909 | GEM_BUG_ON(status & GEN8_CTX_STATUS_PREEMPTED); |
@@ -926,7 +947,7 @@ static void insert_request(struct intel_engine_cs *engine, | |||
926 | 947 | ||
927 | list_add_tail(&pt->link, &ptr_mask_bits(p, 1)->requests); | 948 | list_add_tail(&pt->link, &ptr_mask_bits(p, 1)->requests); |
928 | if (ptr_unmask_bits(p, 1)) | 949 | if (ptr_unmask_bits(p, 1)) |
929 | tasklet_hi_schedule(&engine->execlists.irq_tasklet); | 950 | tasklet_hi_schedule(&engine->execlists.tasklet); |
930 | } | 951 | } |
931 | 952 | ||
932 | static void execlists_submit_request(struct drm_i915_gem_request *request) | 953 | static void execlists_submit_request(struct drm_i915_gem_request *request) |
@@ -1057,12 +1078,34 @@ static void execlists_schedule(struct drm_i915_gem_request *request, int prio) | |||
1057 | spin_unlock_irq(&engine->timeline->lock); | 1078 | spin_unlock_irq(&engine->timeline->lock); |
1058 | } | 1079 | } |
1059 | 1080 | ||
1081 | static int __context_pin(struct i915_gem_context *ctx, struct i915_vma *vma) | ||
1082 | { | ||
1083 | unsigned int flags; | ||
1084 | int err; | ||
1085 | |||
1086 | /* | ||
1087 | * Clear this page out of any CPU caches for coherent swap-in/out. | ||
1088 | * We only want to do this on the first bind so that we do not stall | ||
1089 | * on an active context (which by nature is already on the GPU). | ||
1090 | */ | ||
1091 | if (!(vma->flags & I915_VMA_GLOBAL_BIND)) { | ||
1092 | err = i915_gem_object_set_to_gtt_domain(vma->obj, true); | ||
1093 | if (err) | ||
1094 | return err; | ||
1095 | } | ||
1096 | |||
1097 | flags = PIN_GLOBAL | PIN_HIGH; | ||
1098 | if (ctx->ggtt_offset_bias) | ||
1099 | flags |= PIN_OFFSET_BIAS | ctx->ggtt_offset_bias; | ||
1100 | |||
1101 | return i915_vma_pin(vma, 0, GEN8_LR_CONTEXT_ALIGN, flags); | ||
1102 | } | ||
1103 | |||
1060 | static struct intel_ring * | 1104 | static struct intel_ring * |
1061 | execlists_context_pin(struct intel_engine_cs *engine, | 1105 | execlists_context_pin(struct intel_engine_cs *engine, |
1062 | struct i915_gem_context *ctx) | 1106 | struct i915_gem_context *ctx) |
1063 | { | 1107 | { |
1064 | struct intel_context *ce = &ctx->engine[engine->id]; | 1108 | struct intel_context *ce = &ctx->engine[engine->id]; |
1065 | unsigned int flags; | ||
1066 | void *vaddr; | 1109 | void *vaddr; |
1067 | int ret; | 1110 | int ret; |
1068 | 1111 | ||
@@ -1079,11 +1122,7 @@ execlists_context_pin(struct intel_engine_cs *engine, | |||
1079 | } | 1122 | } |
1080 | GEM_BUG_ON(!ce->state); | 1123 | GEM_BUG_ON(!ce->state); |
1081 | 1124 | ||
1082 | flags = PIN_GLOBAL | PIN_HIGH; | 1125 | ret = __context_pin(ctx, ce->state); |
1083 | if (ctx->ggtt_offset_bias) | ||
1084 | flags |= PIN_OFFSET_BIAS | ctx->ggtt_offset_bias; | ||
1085 | |||
1086 | ret = i915_vma_pin(ce->state, 0, GEN8_LR_CONTEXT_ALIGN, flags); | ||
1087 | if (ret) | 1126 | if (ret) |
1088 | goto err; | 1127 | goto err; |
1089 | 1128 | ||
@@ -1103,9 +1142,7 @@ execlists_context_pin(struct intel_engine_cs *engine, | |||
1103 | ce->lrc_reg_state[CTX_RING_BUFFER_START+1] = | 1142 | ce->lrc_reg_state[CTX_RING_BUFFER_START+1] = |
1104 | i915_ggtt_offset(ce->ring->vma); | 1143 | i915_ggtt_offset(ce->ring->vma); |
1105 | 1144 | ||
1106 | ce->state->obj->mm.dirty = true; | ||
1107 | ce->state->obj->pin_global++; | 1145 | ce->state->obj->pin_global++; |
1108 | |||
1109 | i915_gem_context_get(ctx); | 1146 | i915_gem_context_get(ctx); |
1110 | out: | 1147 | out: |
1111 | return ce->ring; | 1148 | return ce->ring; |
@@ -1143,7 +1180,6 @@ static int execlists_request_alloc(struct drm_i915_gem_request *request) | |||
1143 | { | 1180 | { |
1144 | struct intel_engine_cs *engine = request->engine; | 1181 | struct intel_engine_cs *engine = request->engine; |
1145 | struct intel_context *ce = &request->ctx->engine[engine->id]; | 1182 | struct intel_context *ce = &request->ctx->engine[engine->id]; |
1146 | u32 *cs; | ||
1147 | int ret; | 1183 | int ret; |
1148 | 1184 | ||
1149 | GEM_BUG_ON(!ce->pin_count); | 1185 | GEM_BUG_ON(!ce->pin_count); |
@@ -1154,17 +1190,9 @@ static int execlists_request_alloc(struct drm_i915_gem_request *request) | |||
1154 | */ | 1190 | */ |
1155 | request->reserved_space += EXECLISTS_REQUEST_SIZE; | 1191 | request->reserved_space += EXECLISTS_REQUEST_SIZE; |
1156 | 1192 | ||
1157 | cs = intel_ring_begin(request, 0); | 1193 | ret = intel_ring_wait_for_space(request->ring, request->reserved_space); |
1158 | if (IS_ERR(cs)) | 1194 | if (ret) |
1159 | return PTR_ERR(cs); | 1195 | return ret; |
1160 | |||
1161 | if (!ce->initialised) { | ||
1162 | ret = engine->init_context(request); | ||
1163 | if (ret) | ||
1164 | return ret; | ||
1165 | |||
1166 | ce->initialised = true; | ||
1167 | } | ||
1168 | 1196 | ||
1169 | /* Note that after this point, we have committed to using | 1197 | /* Note that after this point, we have committed to using |
1170 | * this request as it is being used to both track the | 1198 | * this request as it is being used to both track the |
@@ -1474,8 +1502,8 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine) | |||
1474 | execlists->active = 0; | 1502 | execlists->active = 0; |
1475 | 1503 | ||
1476 | /* After a GPU reset, we may have requests to replay */ | 1504 | /* After a GPU reset, we may have requests to replay */ |
1477 | if (!i915_modparams.enable_guc_submission && execlists->first) | 1505 | if (execlists->first) |
1478 | tasklet_schedule(&execlists->irq_tasklet); | 1506 | tasklet_schedule(&execlists->tasklet); |
1479 | 1507 | ||
1480 | return 0; | 1508 | return 0; |
1481 | } | 1509 | } |
@@ -1531,10 +1559,10 @@ static void reset_common_ring(struct intel_engine_cs *engine, | |||
1531 | * guessing the missed context-switch events by looking at what | 1559 | * guessing the missed context-switch events by looking at what |
1532 | * requests were completed. | 1560 | * requests were completed. |
1533 | */ | 1561 | */ |
1534 | execlist_cancel_port_requests(execlists); | 1562 | execlists_cancel_port_requests(execlists); |
1535 | 1563 | ||
1536 | /* Push back any incomplete requests for replay after the reset. */ | 1564 | /* Push back any incomplete requests for replay after the reset. */ |
1537 | unwind_incomplete_requests(engine); | 1565 | __unwind_incomplete_requests(engine); |
1538 | 1566 | ||
1539 | spin_unlock_irqrestore(&engine->timeline->lock, flags); | 1567 | spin_unlock_irqrestore(&engine->timeline->lock, flags); |
1540 | 1568 | ||
@@ -1794,10 +1822,8 @@ static void gen8_emit_breadcrumb(struct drm_i915_gem_request *request, u32 *cs) | |||
1794 | /* w/a: bit 5 needs to be zero for MI_FLUSH_DW address. */ | 1822 | /* w/a: bit 5 needs to be zero for MI_FLUSH_DW address. */ |
1795 | BUILD_BUG_ON(I915_GEM_HWS_INDEX_ADDR & (1 << 5)); | 1823 | BUILD_BUG_ON(I915_GEM_HWS_INDEX_ADDR & (1 << 5)); |
1796 | 1824 | ||
1797 | *cs++ = (MI_FLUSH_DW + 1) | MI_FLUSH_DW_OP_STOREDW; | 1825 | cs = gen8_emit_ggtt_write(cs, request->global_seqno, |
1798 | *cs++ = intel_hws_seqno_address(request->engine) | MI_FLUSH_DW_USE_GTT; | 1826 | intel_hws_seqno_address(request->engine)); |
1799 | *cs++ = 0; | ||
1800 | *cs++ = request->global_seqno; | ||
1801 | *cs++ = MI_USER_INTERRUPT; | 1827 | *cs++ = MI_USER_INTERRUPT; |
1802 | *cs++ = MI_NOOP; | 1828 | *cs++ = MI_NOOP; |
1803 | request->tail = intel_ring_offset(request, cs); | 1829 | request->tail = intel_ring_offset(request, cs); |
@@ -1807,24 +1833,14 @@ static void gen8_emit_breadcrumb(struct drm_i915_gem_request *request, u32 *cs) | |||
1807 | } | 1833 | } |
1808 | static const int gen8_emit_breadcrumb_sz = 6 + WA_TAIL_DWORDS; | 1834 | static const int gen8_emit_breadcrumb_sz = 6 + WA_TAIL_DWORDS; |
1809 | 1835 | ||
1810 | static void gen8_emit_breadcrumb_render(struct drm_i915_gem_request *request, | 1836 | static void gen8_emit_breadcrumb_rcs(struct drm_i915_gem_request *request, |
1811 | u32 *cs) | 1837 | u32 *cs) |
1812 | { | 1838 | { |
1813 | /* We're using qword write, seqno should be aligned to 8 bytes. */ | 1839 | /* We're using qword write, seqno should be aligned to 8 bytes. */ |
1814 | BUILD_BUG_ON(I915_GEM_HWS_INDEX & 1); | 1840 | BUILD_BUG_ON(I915_GEM_HWS_INDEX & 1); |
1815 | 1841 | ||
1816 | /* w/a for post sync ops following a GPGPU operation we | 1842 | cs = gen8_emit_ggtt_write_rcs(cs, request->global_seqno, |
1817 | * need a prior CS_STALL, which is emitted by the flush | 1843 | intel_hws_seqno_address(request->engine)); |
1818 | * following the batch. | ||
1819 | */ | ||
1820 | *cs++ = GFX_OP_PIPE_CONTROL(6); | ||
1821 | *cs++ = PIPE_CONTROL_GLOBAL_GTT_IVB | PIPE_CONTROL_CS_STALL | | ||
1822 | PIPE_CONTROL_QW_WRITE; | ||
1823 | *cs++ = intel_hws_seqno_address(request->engine); | ||
1824 | *cs++ = 0; | ||
1825 | *cs++ = request->global_seqno; | ||
1826 | /* We're thrashing one dword of HWS. */ | ||
1827 | *cs++ = 0; | ||
1828 | *cs++ = MI_USER_INTERRUPT; | 1844 | *cs++ = MI_USER_INTERRUPT; |
1829 | *cs++ = MI_NOOP; | 1845 | *cs++ = MI_NOOP; |
1830 | request->tail = intel_ring_offset(request, cs); | 1846 | request->tail = intel_ring_offset(request, cs); |
@@ -1832,7 +1848,7 @@ static void gen8_emit_breadcrumb_render(struct drm_i915_gem_request *request, | |||
1832 | 1848 | ||
1833 | gen8_emit_wa_tail(request, cs); | 1849 | gen8_emit_wa_tail(request, cs); |
1834 | } | 1850 | } |
1835 | static const int gen8_emit_breadcrumb_render_sz = 8 + WA_TAIL_DWORDS; | 1851 | static const int gen8_emit_breadcrumb_rcs_sz = 8 + WA_TAIL_DWORDS; |
1836 | 1852 | ||
1837 | static int gen8_init_rcs_context(struct drm_i915_gem_request *req) | 1853 | static int gen8_init_rcs_context(struct drm_i915_gem_request *req) |
1838 | { | 1854 | { |
@@ -1865,8 +1881,9 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *engine) | |||
1865 | * Tasklet cannot be active at this point due intel_mark_active/idle | 1881 | * Tasklet cannot be active at this point due intel_mark_active/idle |
1866 | * so this is just for documentation. | 1882 | * so this is just for documentation. |
1867 | */ | 1883 | */ |
1868 | if (WARN_ON(test_bit(TASKLET_STATE_SCHED, &engine->execlists.irq_tasklet.state))) | 1884 | if (WARN_ON(test_bit(TASKLET_STATE_SCHED, |
1869 | tasklet_kill(&engine->execlists.irq_tasklet); | 1885 | &engine->execlists.tasklet.state))) |
1886 | tasklet_kill(&engine->execlists.tasklet); | ||
1870 | 1887 | ||
1871 | dev_priv = engine->i915; | 1888 | dev_priv = engine->i915; |
1872 | 1889 | ||
@@ -1890,7 +1907,10 @@ static void execlists_set_default_submission(struct intel_engine_cs *engine) | |||
1890 | engine->submit_request = execlists_submit_request; | 1907 | engine->submit_request = execlists_submit_request; |
1891 | engine->cancel_requests = execlists_cancel_requests; | 1908 | engine->cancel_requests = execlists_cancel_requests; |
1892 | engine->schedule = execlists_schedule; | 1909 | engine->schedule = execlists_schedule; |
1893 | engine->execlists.irq_tasklet.func = intel_lrc_irq_handler; | 1910 | engine->execlists.tasklet.func = execlists_submission_tasklet; |
1911 | |||
1912 | engine->park = NULL; | ||
1913 | engine->unpark = NULL; | ||
1894 | } | 1914 | } |
1895 | 1915 | ||
1896 | static void | 1916 | static void |
@@ -1949,8 +1969,8 @@ logical_ring_setup(struct intel_engine_cs *engine) | |||
1949 | 1969 | ||
1950 | engine->execlists.fw_domains = fw_domains; | 1970 | engine->execlists.fw_domains = fw_domains; |
1951 | 1971 | ||
1952 | tasklet_init(&engine->execlists.irq_tasklet, | 1972 | tasklet_init(&engine->execlists.tasklet, |
1953 | intel_lrc_irq_handler, (unsigned long)engine); | 1973 | execlists_submission_tasklet, (unsigned long)engine); |
1954 | 1974 | ||
1955 | logical_ring_default_vfuncs(engine); | 1975 | logical_ring_default_vfuncs(engine); |
1956 | logical_ring_default_irqs(engine); | 1976 | logical_ring_default_irqs(engine); |
@@ -1988,8 +2008,8 @@ int logical_render_ring_init(struct intel_engine_cs *engine) | |||
1988 | engine->init_hw = gen8_init_render_ring; | 2008 | engine->init_hw = gen8_init_render_ring; |
1989 | engine->init_context = gen8_init_rcs_context; | 2009 | engine->init_context = gen8_init_rcs_context; |
1990 | engine->emit_flush = gen8_emit_flush_render; | 2010 | engine->emit_flush = gen8_emit_flush_render; |
1991 | engine->emit_breadcrumb = gen8_emit_breadcrumb_render; | 2011 | engine->emit_breadcrumb = gen8_emit_breadcrumb_rcs; |
1992 | engine->emit_breadcrumb_sz = gen8_emit_breadcrumb_render_sz; | 2012 | engine->emit_breadcrumb_sz = gen8_emit_breadcrumb_rcs_sz; |
1993 | 2013 | ||
1994 | ret = intel_engine_create_scratch(engine, PAGE_SIZE); | 2014 | ret = intel_engine_create_scratch(engine, PAGE_SIZE); |
1995 | if (ret) | 2015 | if (ret) |
@@ -2106,7 +2126,6 @@ static void execlists_init_reg_state(u32 *regs, | |||
2106 | 2126 | ||
2107 | CTX_REG(regs, CTX_CONTEXT_CONTROL, RING_CONTEXT_CONTROL(engine), | 2127 | CTX_REG(regs, CTX_CONTEXT_CONTROL, RING_CONTEXT_CONTROL(engine), |
2108 | _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH | | 2128 | _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH | |
2109 | CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT | | ||
2110 | (HAS_RESOURCE_STREAMER(dev_priv) ? | 2129 | (HAS_RESOURCE_STREAMER(dev_priv) ? |
2111 | CTX_CTRL_RS_CTX_ENABLE : 0))); | 2130 | CTX_CTRL_RS_CTX_ENABLE : 0))); |
2112 | CTX_REG(regs, CTX_RING_HEAD, RING_HEAD(base), 0); | 2131 | CTX_REG(regs, CTX_RING_HEAD, RING_HEAD(base), 0); |
@@ -2183,6 +2202,7 @@ populate_lr_context(struct i915_gem_context *ctx, | |||
2183 | struct intel_ring *ring) | 2202 | struct intel_ring *ring) |
2184 | { | 2203 | { |
2185 | void *vaddr; | 2204 | void *vaddr; |
2205 | u32 *regs; | ||
2186 | int ret; | 2206 | int ret; |
2187 | 2207 | ||
2188 | ret = i915_gem_object_set_to_cpu_domain(ctx_obj, true); | 2208 | ret = i915_gem_object_set_to_cpu_domain(ctx_obj, true); |
@@ -2199,11 +2219,31 @@ populate_lr_context(struct i915_gem_context *ctx, | |||
2199 | } | 2219 | } |
2200 | ctx_obj->mm.dirty = true; | 2220 | ctx_obj->mm.dirty = true; |
2201 | 2221 | ||
2222 | if (engine->default_state) { | ||
2223 | /* | ||
2224 | * We only want to copy over the template context state; | ||
2225 | * skipping over the headers reserved for GuC communication, | ||
2226 | * leaving those as zero. | ||
2227 | */ | ||
2228 | const unsigned long start = LRC_HEADER_PAGES * PAGE_SIZE; | ||
2229 | void *defaults; | ||
2230 | |||
2231 | defaults = i915_gem_object_pin_map(engine->default_state, | ||
2232 | I915_MAP_WB); | ||
2233 | if (IS_ERR(defaults)) | ||
2234 | return PTR_ERR(defaults); | ||
2235 | |||
2236 | memcpy(vaddr + start, defaults + start, engine->context_size); | ||
2237 | i915_gem_object_unpin_map(engine->default_state); | ||
2238 | } | ||
2239 | |||
2202 | /* The second page of the context object contains some fields which must | 2240 | /* The second page of the context object contains some fields which must |
2203 | * be set up prior to the first execution. */ | 2241 | * be set up prior to the first execution. */ |
2204 | 2242 | regs = vaddr + LRC_STATE_PN * PAGE_SIZE; | |
2205 | execlists_init_reg_state(vaddr + LRC_STATE_PN * PAGE_SIZE, | 2243 | execlists_init_reg_state(regs, ctx, engine, ring); |
2206 | ctx, engine, ring); | 2244 | if (!engine->default_state) |
2245 | regs[CTX_CONTEXT_CONTROL + 1] |= | ||
2246 | _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT); | ||
2207 | 2247 | ||
2208 | i915_gem_object_unpin_map(ctx_obj); | 2248 | i915_gem_object_unpin_map(ctx_obj); |
2209 | 2249 | ||
@@ -2256,7 +2296,6 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx, | |||
2256 | 2296 | ||
2257 | ce->ring = ring; | 2297 | ce->ring = ring; |
2258 | ce->state = vma; | 2298 | ce->state = vma; |
2259 | ce->initialised |= engine->init_context == NULL; | ||
2260 | 2299 | ||
2261 | return 0; | 2300 | return 0; |
2262 | 2301 | ||
diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 689fde1a63a9..17182ce29674 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h | |||
@@ -107,7 +107,6 @@ intel_lr_context_descriptor(struct i915_gem_context *ctx, | |||
107 | return ctx->engine[engine->id].lrc_desc; | 107 | return ctx->engine[engine->id].lrc_desc; |
108 | } | 108 | } |
109 | 109 | ||
110 | |||
111 | /* Execlists */ | 110 | /* Execlists */ |
112 | int intel_sanitize_enable_execlists(struct drm_i915_private *dev_priv, | 111 | int intel_sanitize_enable_execlists(struct drm_i915_private *dev_priv, |
113 | int enable_execlists); | 112 | int enable_execlists); |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 38572d65e46e..ef80499113ee 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -125,6 +125,8 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, | |||
125 | struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); | 125 | struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); |
126 | u32 tmp, flags = 0; | 126 | u32 tmp, flags = 0; |
127 | 127 | ||
128 | pipe_config->output_types |= BIT(INTEL_OUTPUT_LVDS); | ||
129 | |||
128 | tmp = I915_READ(lvds_encoder->reg); | 130 | tmp = I915_READ(lvds_encoder->reg); |
129 | if (tmp & LVDS_HSYNC_POLARITY) | 131 | if (tmp & LVDS_HSYNC_POLARITY) |
130 | flags |= DRM_MODE_FLAG_NHSYNC; | 132 | flags |= DRM_MODE_FLAG_NHSYNC; |
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 1d946240e55f..fc65f5e451dd 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c | |||
@@ -367,7 +367,7 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, | |||
367 | if (intel_encoder->type == INTEL_OUTPUT_DSI) | 367 | if (intel_encoder->type == INTEL_OUTPUT_DSI) |
368 | port = 0; | 368 | port = 0; |
369 | else | 369 | else |
370 | port = intel_ddi_get_encoder_port(intel_encoder); | 370 | port = intel_encoder->port; |
371 | 371 | ||
372 | if (port == PORT_E) { | 372 | if (port == PORT_E) { |
373 | port = 0; | 373 | port = 0; |
@@ -383,7 +383,7 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, | |||
383 | case INTEL_OUTPUT_ANALOG: | 383 | case INTEL_OUTPUT_ANALOG: |
384 | type = DISPLAY_TYPE_CRT; | 384 | type = DISPLAY_TYPE_CRT; |
385 | break; | 385 | break; |
386 | case INTEL_OUTPUT_UNKNOWN: | 386 | case INTEL_OUTPUT_DDI: |
387 | case INTEL_OUTPUT_DP: | 387 | case INTEL_OUTPUT_DP: |
388 | case INTEL_OUTPUT_HDMI: | 388 | case INTEL_OUTPUT_HDMI: |
389 | case INTEL_OUTPUT_DP_MST: | 389 | case INTEL_OUTPUT_DP_MST: |
diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c b/drivers/gpu/drm/i915/intel_pipe_crc.c index 899839f2f7c6..61641d479b93 100644 --- a/drivers/gpu/drm/i915/intel_pipe_crc.c +++ b/drivers/gpu/drm/i915/intel_pipe_crc.c | |||
@@ -269,7 +269,7 @@ static int i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv, | |||
269 | case INTEL_OUTPUT_DP: | 269 | case INTEL_OUTPUT_DP: |
270 | case INTEL_OUTPUT_EDP: | 270 | case INTEL_OUTPUT_EDP: |
271 | dig_port = enc_to_dig_port(&encoder->base); | 271 | dig_port = enc_to_dig_port(&encoder->base); |
272 | switch (dig_port->port) { | 272 | switch (dig_port->base.port) { |
273 | case PORT_B: | 273 | case PORT_B: |
274 | *source = INTEL_PIPE_CRC_SOURCE_DP_B; | 274 | *source = INTEL_PIPE_CRC_SOURCE_DP_B; |
275 | break; | 275 | break; |
@@ -281,7 +281,7 @@ static int i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv, | |||
281 | break; | 281 | break; |
282 | default: | 282 | default: |
283 | WARN(1, "nonexisting DP port %c\n", | 283 | WARN(1, "nonexisting DP port %c\n", |
284 | port_name(dig_port->port)); | 284 | port_name(dig_port->base.port)); |
285 | break; | 285 | break; |
286 | } | 286 | } |
287 | break; | 287 | break; |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index f4a4e9496893..4d2cd432f739 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -75,9 +75,6 @@ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv) | |||
75 | I915_WRITE(CHICKEN_PAR1_1, | 75 | I915_WRITE(CHICKEN_PAR1_1, |
76 | I915_READ(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP); | 76 | I915_READ(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP); |
77 | 77 | ||
78 | I915_WRITE(GEN8_CONFIG0, | ||
79 | I915_READ(GEN8_CONFIG0) | GEN9_DEFAULT_FIXES); | ||
80 | |||
81 | /* WaEnableChickenDCPR:skl,bxt,kbl,glk,cfl */ | 78 | /* WaEnableChickenDCPR:skl,bxt,kbl,glk,cfl */ |
82 | I915_WRITE(GEN8_CHICKEN_DCPR_1, | 79 | I915_WRITE(GEN8_CHICKEN_DCPR_1, |
83 | I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM); | 80 | I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM); |
@@ -124,7 +121,6 @@ static void bxt_init_clock_gating(struct drm_i915_private *dev_priv) | |||
124 | 121 | ||
125 | static void glk_init_clock_gating(struct drm_i915_private *dev_priv) | 122 | static void glk_init_clock_gating(struct drm_i915_private *dev_priv) |
126 | { | 123 | { |
127 | u32 val; | ||
128 | gen9_init_clock_gating(dev_priv); | 124 | gen9_init_clock_gating(dev_priv); |
129 | 125 | ||
130 | /* | 126 | /* |
@@ -144,11 +140,6 @@ static void glk_init_clock_gating(struct drm_i915_private *dev_priv) | |||
144 | I915_WRITE(CHICKEN_MISC_2, val); | 140 | I915_WRITE(CHICKEN_MISC_2, val); |
145 | } | 141 | } |
146 | 142 | ||
147 | /* Display WA #1133: WaFbcSkipSegments:glk */ | ||
148 | val = I915_READ(ILK_DPFC_CHICKEN); | ||
149 | val &= ~GLK_SKIP_SEG_COUNT_MASK; | ||
150 | val |= GLK_SKIP_SEG_EN | GLK_SKIP_SEG_COUNT(1); | ||
151 | I915_WRITE(ILK_DPFC_CHICKEN, val); | ||
152 | } | 143 | } |
153 | 144 | ||
154 | static void i915_pineview_get_mem_freq(struct drm_i915_private *dev_priv) | 145 | static void i915_pineview_get_mem_freq(struct drm_i915_private *dev_priv) |
@@ -928,7 +919,7 @@ static void pineview_update_wm(struct intel_crtc *unused_crtc) | |||
928 | * and the size of 8 whole lines. This adjustment is always performed | 919 | * and the size of 8 whole lines. This adjustment is always performed |
929 | * in the actual pixel depth regardless of whether FBC is enabled or not." | 920 | * in the actual pixel depth regardless of whether FBC is enabled or not." |
930 | */ | 921 | */ |
931 | static int g4x_tlb_miss_wa(int fifo_size, int width, int cpp) | 922 | static unsigned int g4x_tlb_miss_wa(int fifo_size, int width, int cpp) |
932 | { | 923 | { |
933 | int tlb_miss = fifo_size * 64 - width * cpp * 8; | 924 | int tlb_miss = fifo_size * 64 - width * cpp * 8; |
934 | 925 | ||
@@ -1105,8 +1096,8 @@ static uint16_t g4x_compute_wm(const struct intel_crtc_state *crtc_state, | |||
1105 | struct drm_i915_private *dev_priv = to_i915(plane->base.dev); | 1096 | struct drm_i915_private *dev_priv = to_i915(plane->base.dev); |
1106 | const struct drm_display_mode *adjusted_mode = | 1097 | const struct drm_display_mode *adjusted_mode = |
1107 | &crtc_state->base.adjusted_mode; | 1098 | &crtc_state->base.adjusted_mode; |
1108 | int clock, htotal, cpp, width, wm; | 1099 | unsigned int latency = dev_priv->wm.pri_latency[level] * 10; |
1109 | int latency = dev_priv->wm.pri_latency[level] * 10; | 1100 | unsigned int clock, htotal, cpp, width, wm; |
1110 | 1101 | ||
1111 | if (latency == 0) | 1102 | if (latency == 0) |
1112 | return USHRT_MAX; | 1103 | return USHRT_MAX; |
@@ -1145,7 +1136,7 @@ static uint16_t g4x_compute_wm(const struct intel_crtc_state *crtc_state, | |||
1145 | level == G4X_WM_LEVEL_NORMAL) { | 1136 | level == G4X_WM_LEVEL_NORMAL) { |
1146 | wm = intel_wm_method1(clock, cpp, latency); | 1137 | wm = intel_wm_method1(clock, cpp, latency); |
1147 | } else { | 1138 | } else { |
1148 | int small, large; | 1139 | unsigned int small, large; |
1149 | 1140 | ||
1150 | small = intel_wm_method1(clock, cpp, latency); | 1141 | small = intel_wm_method1(clock, cpp, latency); |
1151 | large = intel_wm_method2(clock, htotal, width, cpp, latency); | 1142 | large = intel_wm_method2(clock, htotal, width, cpp, latency); |
@@ -1158,7 +1149,7 @@ static uint16_t g4x_compute_wm(const struct intel_crtc_state *crtc_state, | |||
1158 | 1149 | ||
1159 | wm = DIV_ROUND_UP(wm, 64) + 2; | 1150 | wm = DIV_ROUND_UP(wm, 64) + 2; |
1160 | 1151 | ||
1161 | return min_t(int, wm, USHRT_MAX); | 1152 | return min_t(unsigned int, wm, USHRT_MAX); |
1162 | } | 1153 | } |
1163 | 1154 | ||
1164 | static bool g4x_raw_plane_wm_set(struct intel_crtc_state *crtc_state, | 1155 | static bool g4x_raw_plane_wm_set(struct intel_crtc_state *crtc_state, |
@@ -1409,17 +1400,29 @@ static int g4x_compute_pipe_wm(struct intel_crtc_state *crtc_state) | |||
1409 | 1400 | ||
1410 | static int g4x_compute_intermediate_wm(struct drm_device *dev, | 1401 | static int g4x_compute_intermediate_wm(struct drm_device *dev, |
1411 | struct intel_crtc *crtc, | 1402 | struct intel_crtc *crtc, |
1412 | struct intel_crtc_state *crtc_state) | 1403 | struct intel_crtc_state *new_crtc_state) |
1413 | { | 1404 | { |
1414 | struct g4x_wm_state *intermediate = &crtc_state->wm.g4x.intermediate; | 1405 | struct g4x_wm_state *intermediate = &new_crtc_state->wm.g4x.intermediate; |
1415 | const struct g4x_wm_state *optimal = &crtc_state->wm.g4x.optimal; | 1406 | const struct g4x_wm_state *optimal = &new_crtc_state->wm.g4x.optimal; |
1416 | const struct g4x_wm_state *active = &crtc->wm.active.g4x; | 1407 | struct intel_atomic_state *intel_state = |
1408 | to_intel_atomic_state(new_crtc_state->base.state); | ||
1409 | const struct intel_crtc_state *old_crtc_state = | ||
1410 | intel_atomic_get_old_crtc_state(intel_state, crtc); | ||
1411 | const struct g4x_wm_state *active = &old_crtc_state->wm.g4x.optimal; | ||
1417 | enum plane_id plane_id; | 1412 | enum plane_id plane_id; |
1418 | 1413 | ||
1414 | if (!new_crtc_state->base.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->base)) { | ||
1415 | *intermediate = *optimal; | ||
1416 | |||
1417 | intermediate->cxsr = false; | ||
1418 | intermediate->hpll_en = false; | ||
1419 | goto out; | ||
1420 | } | ||
1421 | |||
1419 | intermediate->cxsr = optimal->cxsr && active->cxsr && | 1422 | intermediate->cxsr = optimal->cxsr && active->cxsr && |
1420 | !crtc_state->disable_cxsr; | 1423 | !new_crtc_state->disable_cxsr; |
1421 | intermediate->hpll_en = optimal->hpll_en && active->hpll_en && | 1424 | intermediate->hpll_en = optimal->hpll_en && active->hpll_en && |
1422 | !crtc_state->disable_cxsr; | 1425 | !new_crtc_state->disable_cxsr; |
1423 | intermediate->fbc_en = optimal->fbc_en && active->fbc_en; | 1426 | intermediate->fbc_en = optimal->fbc_en && active->fbc_en; |
1424 | 1427 | ||
1425 | for_each_plane_id_on_crtc(crtc, plane_id) { | 1428 | for_each_plane_id_on_crtc(crtc, plane_id) { |
@@ -1461,12 +1464,13 @@ static int g4x_compute_intermediate_wm(struct drm_device *dev, | |||
1461 | WARN_ON(intermediate->hpll.fbc > g4x_fbc_fifo_size(2) && | 1464 | WARN_ON(intermediate->hpll.fbc > g4x_fbc_fifo_size(2) && |
1462 | intermediate->fbc_en && intermediate->hpll_en); | 1465 | intermediate->fbc_en && intermediate->hpll_en); |
1463 | 1466 | ||
1467 | out: | ||
1464 | /* | 1468 | /* |
1465 | * If our intermediate WM are identical to the final WM, then we can | 1469 | * If our intermediate WM are identical to the final WM, then we can |
1466 | * omit the post-vblank programming; only update if it's different. | 1470 | * omit the post-vblank programming; only update if it's different. |
1467 | */ | 1471 | */ |
1468 | if (memcmp(intermediate, optimal, sizeof(*intermediate)) != 0) | 1472 | if (memcmp(intermediate, optimal, sizeof(*intermediate)) != 0) |
1469 | crtc_state->wm.need_postvbl_update = true; | 1473 | new_crtc_state->wm.need_postvbl_update = true; |
1470 | 1474 | ||
1471 | return 0; | 1475 | return 0; |
1472 | } | 1476 | } |
@@ -1602,7 +1606,7 @@ static uint16_t vlv_compute_wm_level(const struct intel_crtc_state *crtc_state, | |||
1602 | struct drm_i915_private *dev_priv = to_i915(plane->base.dev); | 1606 | struct drm_i915_private *dev_priv = to_i915(plane->base.dev); |
1603 | const struct drm_display_mode *adjusted_mode = | 1607 | const struct drm_display_mode *adjusted_mode = |
1604 | &crtc_state->base.adjusted_mode; | 1608 | &crtc_state->base.adjusted_mode; |
1605 | int clock, htotal, cpp, width, wm; | 1609 | unsigned int clock, htotal, cpp, width, wm; |
1606 | 1610 | ||
1607 | if (dev_priv->wm.pri_latency[level] == 0) | 1611 | if (dev_priv->wm.pri_latency[level] == 0) |
1608 | return USHRT_MAX; | 1612 | return USHRT_MAX; |
@@ -1628,7 +1632,7 @@ static uint16_t vlv_compute_wm_level(const struct intel_crtc_state *crtc_state, | |||
1628 | dev_priv->wm.pri_latency[level] * 10); | 1632 | dev_priv->wm.pri_latency[level] * 10); |
1629 | } | 1633 | } |
1630 | 1634 | ||
1631 | return min_t(int, wm, USHRT_MAX); | 1635 | return min_t(unsigned int, wm, USHRT_MAX); |
1632 | } | 1636 | } |
1633 | 1637 | ||
1634 | static bool vlv_need_sprite0_fifo_workaround(unsigned int active_planes) | 1638 | static bool vlv_need_sprite0_fifo_workaround(unsigned int active_planes) |
@@ -2029,16 +2033,27 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state, | |||
2029 | 2033 | ||
2030 | static int vlv_compute_intermediate_wm(struct drm_device *dev, | 2034 | static int vlv_compute_intermediate_wm(struct drm_device *dev, |
2031 | struct intel_crtc *crtc, | 2035 | struct intel_crtc *crtc, |
2032 | struct intel_crtc_state *crtc_state) | 2036 | struct intel_crtc_state *new_crtc_state) |
2033 | { | 2037 | { |
2034 | struct vlv_wm_state *intermediate = &crtc_state->wm.vlv.intermediate; | 2038 | struct vlv_wm_state *intermediate = &new_crtc_state->wm.vlv.intermediate; |
2035 | const struct vlv_wm_state *optimal = &crtc_state->wm.vlv.optimal; | 2039 | const struct vlv_wm_state *optimal = &new_crtc_state->wm.vlv.optimal; |
2036 | const struct vlv_wm_state *active = &crtc->wm.active.vlv; | 2040 | struct intel_atomic_state *intel_state = |
2041 | to_intel_atomic_state(new_crtc_state->base.state); | ||
2042 | const struct intel_crtc_state *old_crtc_state = | ||
2043 | intel_atomic_get_old_crtc_state(intel_state, crtc); | ||
2044 | const struct vlv_wm_state *active = &old_crtc_state->wm.vlv.optimal; | ||
2037 | int level; | 2045 | int level; |
2038 | 2046 | ||
2047 | if (!new_crtc_state->base.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->base)) { | ||
2048 | *intermediate = *optimal; | ||
2049 | |||
2050 | intermediate->cxsr = false; | ||
2051 | goto out; | ||
2052 | } | ||
2053 | |||
2039 | intermediate->num_levels = min(optimal->num_levels, active->num_levels); | 2054 | intermediate->num_levels = min(optimal->num_levels, active->num_levels); |
2040 | intermediate->cxsr = optimal->cxsr && active->cxsr && | 2055 | intermediate->cxsr = optimal->cxsr && active->cxsr && |
2041 | !crtc_state->disable_cxsr; | 2056 | !new_crtc_state->disable_cxsr; |
2042 | 2057 | ||
2043 | for (level = 0; level < intermediate->num_levels; level++) { | 2058 | for (level = 0; level < intermediate->num_levels; level++) { |
2044 | enum plane_id plane_id; | 2059 | enum plane_id plane_id; |
@@ -2057,12 +2072,13 @@ static int vlv_compute_intermediate_wm(struct drm_device *dev, | |||
2057 | 2072 | ||
2058 | vlv_invalidate_wms(crtc, intermediate, level); | 2073 | vlv_invalidate_wms(crtc, intermediate, level); |
2059 | 2074 | ||
2075 | out: | ||
2060 | /* | 2076 | /* |
2061 | * If our intermediate WM are identical to the final WM, then we can | 2077 | * If our intermediate WM are identical to the final WM, then we can |
2062 | * omit the post-vblank programming; only update if it's different. | 2078 | * omit the post-vblank programming; only update if it's different. |
2063 | */ | 2079 | */ |
2064 | if (memcmp(intermediate, optimal, sizeof(*intermediate)) != 0) | 2080 | if (memcmp(intermediate, optimal, sizeof(*intermediate)) != 0) |
2065 | crtc_state->wm.need_postvbl_update = true; | 2081 | new_crtc_state->wm.need_postvbl_update = true; |
2066 | 2082 | ||
2067 | return 0; | 2083 | return 0; |
2068 | } | 2084 | } |
@@ -3930,6 +3946,7 @@ skl_pipe_downscale_amount(const struct intel_crtc_state *crtc_state) | |||
3930 | int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc, | 3946 | int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc, |
3931 | struct intel_crtc_state *cstate) | 3947 | struct intel_crtc_state *cstate) |
3932 | { | 3948 | { |
3949 | struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); | ||
3933 | struct drm_crtc_state *crtc_state = &cstate->base; | 3950 | struct drm_crtc_state *crtc_state = &cstate->base; |
3934 | struct drm_atomic_state *state = crtc_state->state; | 3951 | struct drm_atomic_state *state = crtc_state->state; |
3935 | struct drm_plane *plane; | 3952 | struct drm_plane *plane; |
@@ -3972,7 +3989,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc, | |||
3972 | crtc_clock = crtc_state->adjusted_mode.crtc_clock; | 3989 | crtc_clock = crtc_state->adjusted_mode.crtc_clock; |
3973 | dotclk = to_intel_atomic_state(state)->cdclk.logical.cdclk; | 3990 | dotclk = to_intel_atomic_state(state)->cdclk.logical.cdclk; |
3974 | 3991 | ||
3975 | if (IS_GEMINILAKE(to_i915(intel_crtc->base.dev))) | 3992 | if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10) |
3976 | dotclk *= 2; | 3993 | dotclk *= 2; |
3977 | 3994 | ||
3978 | pipe_max_pixel_rate = div_round_up_u32_fixed16(dotclk, pipe_downscale); | 3995 | pipe_max_pixel_rate = div_round_up_u32_fixed16(dotclk, pipe_downscale); |
@@ -6620,12 +6637,19 @@ static void gen9_enable_rc6(struct drm_i915_private *dev_priv) | |||
6620 | I915_WRITE(GEN6_RC_CONTROL, 0); | 6637 | I915_WRITE(GEN6_RC_CONTROL, 0); |
6621 | 6638 | ||
6622 | /* 2b: Program RC6 thresholds.*/ | 6639 | /* 2b: Program RC6 thresholds.*/ |
6623 | 6640 | if (INTEL_GEN(dev_priv) >= 10) { | |
6624 | /* WaRsDoubleRc6WrlWithCoarsePowerGating: Doubling WRL only when CPG is enabled */ | 6641 | I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16 | 85); |
6625 | if (IS_SKYLAKE(dev_priv)) | 6642 | I915_WRITE(GEN10_MEDIA_WAKE_RATE_LIMIT, 150); |
6643 | } else if (IS_SKYLAKE(dev_priv)) { | ||
6644 | /* | ||
6645 | * WaRsDoubleRc6WrlWithCoarsePowerGating:skl Doubling WRL only | ||
6646 | * when CPG is enabled | ||
6647 | */ | ||
6626 | I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 108 << 16); | 6648 | I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 108 << 16); |
6627 | else | 6649 | } else { |
6628 | I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16); | 6650 | I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16); |
6651 | } | ||
6652 | |||
6629 | I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ | 6653 | I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ |
6630 | I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ | 6654 | I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ |
6631 | for_each_engine(engine, dev_priv, id) | 6655 | for_each_engine(engine, dev_priv, id) |
@@ -7910,7 +7934,6 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv) | |||
7910 | intel_runtime_pm_get(dev_priv); | 7934 | intel_runtime_pm_get(dev_priv); |
7911 | } | 7935 | } |
7912 | 7936 | ||
7913 | mutex_lock(&dev_priv->drm.struct_mutex); | ||
7914 | mutex_lock(&dev_priv->pcu_lock); | 7937 | mutex_lock(&dev_priv->pcu_lock); |
7915 | 7938 | ||
7916 | /* Initialize RPS limits (for userspace) */ | 7939 | /* Initialize RPS limits (for userspace) */ |
@@ -7952,9 +7975,6 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv) | |||
7952 | rps->boost_freq = rps->max_freq; | 7975 | rps->boost_freq = rps->max_freq; |
7953 | 7976 | ||
7954 | mutex_unlock(&dev_priv->pcu_lock); | 7977 | mutex_unlock(&dev_priv->pcu_lock); |
7955 | mutex_unlock(&dev_priv->drm.struct_mutex); | ||
7956 | |||
7957 | intel_autoenable_gt_powersave(dev_priv); | ||
7958 | } | 7978 | } |
7959 | 7979 | ||
7960 | void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv) | 7980 | void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv) |
@@ -7979,9 +7999,6 @@ void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv) | |||
7979 | if (INTEL_GEN(dev_priv) < 6) | 7999 | if (INTEL_GEN(dev_priv) < 6) |
7980 | return; | 8000 | return; |
7981 | 8001 | ||
7982 | if (cancel_delayed_work_sync(&dev_priv->gt_pm.autoenable_work)) | ||
7983 | intel_runtime_pm_put(dev_priv); | ||
7984 | |||
7985 | /* gen6_rps_idle() will be called later to disable interrupts */ | 8002 | /* gen6_rps_idle() will be called later to disable interrupts */ |
7986 | } | 8003 | } |
7987 | 8004 | ||
@@ -8140,65 +8157,6 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) | |||
8140 | mutex_unlock(&dev_priv->pcu_lock); | 8157 | mutex_unlock(&dev_priv->pcu_lock); |
8141 | } | 8158 | } |
8142 | 8159 | ||
8143 | static void __intel_autoenable_gt_powersave(struct work_struct *work) | ||
8144 | { | ||
8145 | struct drm_i915_private *dev_priv = | ||
8146 | container_of(work, | ||
8147 | typeof(*dev_priv), | ||
8148 | gt_pm.autoenable_work.work); | ||
8149 | struct intel_engine_cs *rcs; | ||
8150 | struct drm_i915_gem_request *req; | ||
8151 | |||
8152 | rcs = dev_priv->engine[RCS]; | ||
8153 | if (rcs->last_retired_context) | ||
8154 | goto out; | ||
8155 | |||
8156 | if (!rcs->init_context) | ||
8157 | goto out; | ||
8158 | |||
8159 | mutex_lock(&dev_priv->drm.struct_mutex); | ||
8160 | |||
8161 | req = i915_gem_request_alloc(rcs, dev_priv->kernel_context); | ||
8162 | if (IS_ERR(req)) | ||
8163 | goto unlock; | ||
8164 | |||
8165 | if (!i915_modparams.enable_execlists && i915_switch_context(req) == 0) | ||
8166 | rcs->init_context(req); | ||
8167 | |||
8168 | /* Mark the device busy, calling intel_enable_gt_powersave() */ | ||
8169 | i915_add_request(req); | ||
8170 | |||
8171 | unlock: | ||
8172 | mutex_unlock(&dev_priv->drm.struct_mutex); | ||
8173 | out: | ||
8174 | intel_runtime_pm_put(dev_priv); | ||
8175 | } | ||
8176 | |||
8177 | void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv) | ||
8178 | { | ||
8179 | if (IS_IRONLAKE_M(dev_priv)) { | ||
8180 | ironlake_enable_drps(dev_priv); | ||
8181 | intel_init_emon(dev_priv); | ||
8182 | } else if (INTEL_INFO(dev_priv)->gen >= 6) { | ||
8183 | /* | ||
8184 | * PCU communication is slow and this doesn't need to be | ||
8185 | * done at any specific time, so do this out of our fast path | ||
8186 | * to make resume and init faster. | ||
8187 | * | ||
8188 | * We depend on the HW RC6 power context save/restore | ||
8189 | * mechanism when entering D3 through runtime PM suspend. So | ||
8190 | * disable RPM until RPS/RC6 is properly setup. We can only | ||
8191 | * get here via the driver load/system resume/runtime resume | ||
8192 | * paths, so the _noresume version is enough (and in case of | ||
8193 | * runtime resume it's necessary). | ||
8194 | */ | ||
8195 | if (queue_delayed_work(dev_priv->wq, | ||
8196 | &dev_priv->gt_pm.autoenable_work, | ||
8197 | round_jiffies_up_relative(HZ))) | ||
8198 | intel_runtime_pm_get_noresume(dev_priv); | ||
8199 | } | ||
8200 | } | ||
8201 | |||
8202 | static void ibx_init_clock_gating(struct drm_i915_private *dev_priv) | 8160 | static void ibx_init_clock_gating(struct drm_i915_private *dev_priv) |
8203 | { | 8161 | { |
8204 | /* | 8162 | /* |
@@ -8532,17 +8490,13 @@ static void cnl_init_clock_gating(struct drm_i915_private *dev_priv) | |||
8532 | I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | | 8490 | I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | |
8533 | DISP_FBC_MEMORY_WAKE); | 8491 | DISP_FBC_MEMORY_WAKE); |
8534 | 8492 | ||
8493 | val = I915_READ(SLICE_UNIT_LEVEL_CLKGATE); | ||
8494 | /* ReadHitWriteOnlyDisable:cnl */ | ||
8495 | val |= RCCUNIT_CLKGATE_DIS; | ||
8535 | /* WaSarbUnitClockGatingDisable:cnl (pre-prod) */ | 8496 | /* WaSarbUnitClockGatingDisable:cnl (pre-prod) */ |
8536 | if (IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0)) | 8497 | if (IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0)) |
8537 | I915_WRITE(SLICE_UNIT_LEVEL_CLKGATE, | 8498 | val |= SARBUNIT_CLKGATE_DIS; |
8538 | I915_READ(SLICE_UNIT_LEVEL_CLKGATE) | | 8499 | I915_WRITE(SLICE_UNIT_LEVEL_CLKGATE, val); |
8539 | SARBUNIT_CLKGATE_DIS); | ||
8540 | |||
8541 | /* Display WA #1133: WaFbcSkipSegments:cnl */ | ||
8542 | val = I915_READ(ILK_DPFC_CHICKEN); | ||
8543 | val &= ~GLK_SKIP_SEG_COUNT_MASK; | ||
8544 | val |= GLK_SKIP_SEG_EN | GLK_SKIP_SEG_COUNT(1); | ||
8545 | I915_WRITE(ILK_DPFC_CHICKEN, val); | ||
8546 | } | 8500 | } |
8547 | 8501 | ||
8548 | static void cfl_init_clock_gating(struct drm_i915_private *dev_priv) | 8502 | static void cfl_init_clock_gating(struct drm_i915_private *dev_priv) |
@@ -9429,8 +9383,6 @@ void intel_pm_setup(struct drm_i915_private *dev_priv) | |||
9429 | { | 9383 | { |
9430 | mutex_init(&dev_priv->pcu_lock); | 9384 | mutex_init(&dev_priv->pcu_lock); |
9431 | 9385 | ||
9432 | INIT_DELAYED_WORK(&dev_priv->gt_pm.autoenable_work, | ||
9433 | __intel_autoenable_gt_powersave); | ||
9434 | atomic_set(&dev_priv->gt_pm.rps.num_waiters, 0); | 9386 | atomic_set(&dev_priv->gt_pm.rps.num_waiters, 0); |
9435 | 9387 | ||
9436 | dev_priv->runtime_pm.suspended = false; | 9388 | dev_priv->runtime_pm.suspended = false; |
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 6e3b430fccdc..a1ad85fa5c1a 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c | |||
@@ -163,7 +163,7 @@ static void hsw_psr_enable_sink(struct intel_dp *intel_dp) | |||
163 | [3] = 1 - 1, | 163 | [3] = 1 - 1, |
164 | [4] = DP_SET_POWER_D0, | 164 | [4] = DP_SET_POWER_D0, |
165 | }; | 165 | }; |
166 | enum port port = dig_port->port; | 166 | enum port port = dig_port->base.port; |
167 | u32 aux_ctl; | 167 | u32 aux_ctl; |
168 | int i; | 168 | int i; |
169 | 169 | ||
@@ -376,7 +376,7 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, | |||
376 | * ones. Since by Display design transcoder EDP is tied to port A | 376 | * ones. Since by Display design transcoder EDP is tied to port A |
377 | * we can safely escape based on the port A. | 377 | * we can safely escape based on the port A. |
378 | */ | 378 | */ |
379 | if (HAS_DDI(dev_priv) && dig_port->port != PORT_A) { | 379 | if (HAS_DDI(dev_priv) && dig_port->base.port != PORT_A) { |
380 | DRM_DEBUG_KMS("PSR condition failed: Port not supported\n"); | 380 | DRM_DEBUG_KMS("PSR condition failed: Port not supported\n"); |
381 | return; | 381 | return; |
382 | } | 382 | } |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 8da1bde442dd..12e734b29463 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -28,9 +28,12 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/log2.h> | 30 | #include <linux/log2.h> |
31 | |||
31 | #include <drm/drmP.h> | 32 | #include <drm/drmP.h> |
32 | #include "i915_drv.h" | ||
33 | #include <drm/i915_drm.h> | 33 | #include <drm/i915_drm.h> |
34 | |||
35 | #include "i915_drv.h" | ||
36 | #include "i915_gem_render_state.h" | ||
34 | #include "i915_trace.h" | 37 | #include "i915_trace.h" |
35 | #include "intel_drv.h" | 38 | #include "intel_drv.h" |
36 | 39 | ||
@@ -480,10 +483,14 @@ static bool stop_ring(struct intel_engine_cs *engine) | |||
480 | } | 483 | } |
481 | } | 484 | } |
482 | 485 | ||
483 | I915_WRITE_CTL(engine, 0); | 486 | I915_WRITE_HEAD(engine, I915_READ_TAIL(engine)); |
487 | |||
484 | I915_WRITE_HEAD(engine, 0); | 488 | I915_WRITE_HEAD(engine, 0); |
485 | I915_WRITE_TAIL(engine, 0); | 489 | I915_WRITE_TAIL(engine, 0); |
486 | 490 | ||
491 | /* The ring must be empty before it is disabled */ | ||
492 | I915_WRITE_CTL(engine, 0); | ||
493 | |||
487 | return (I915_READ_HEAD(engine) & HEAD_ADDR) == 0; | 494 | return (I915_READ_HEAD(engine) & HEAD_ADDR) == 0; |
488 | } | 495 | } |
489 | 496 | ||
@@ -1359,12 +1366,13 @@ static int context_pin(struct i915_gem_context *ctx) | |||
1359 | struct i915_vma *vma = ctx->engine[RCS].state; | 1366 | struct i915_vma *vma = ctx->engine[RCS].state; |
1360 | int ret; | 1367 | int ret; |
1361 | 1368 | ||
1362 | /* Clear this page out of any CPU caches for coherent swap-in/out. | 1369 | /* |
1370 | * Clear this page out of any CPU caches for coherent swap-in/out. | ||
1363 | * We only want to do this on the first bind so that we do not stall | 1371 | * We only want to do this on the first bind so that we do not stall |
1364 | * on an active context (which by nature is already on the GPU). | 1372 | * on an active context (which by nature is already on the GPU). |
1365 | */ | 1373 | */ |
1366 | if (!(vma->flags & I915_VMA_GLOBAL_BIND)) { | 1374 | if (!(vma->flags & I915_VMA_GLOBAL_BIND)) { |
1367 | ret = i915_gem_object_set_to_gtt_domain(vma->obj, false); | 1375 | ret = i915_gem_object_set_to_gtt_domain(vma->obj, true); |
1368 | if (ret) | 1376 | if (ret) |
1369 | return ret; | 1377 | return ret; |
1370 | } | 1378 | } |
@@ -1379,11 +1387,34 @@ alloc_context_vma(struct intel_engine_cs *engine) | |||
1379 | struct drm_i915_private *i915 = engine->i915; | 1387 | struct drm_i915_private *i915 = engine->i915; |
1380 | struct drm_i915_gem_object *obj; | 1388 | struct drm_i915_gem_object *obj; |
1381 | struct i915_vma *vma; | 1389 | struct i915_vma *vma; |
1390 | int err; | ||
1382 | 1391 | ||
1383 | obj = i915_gem_object_create(i915, engine->context_size); | 1392 | obj = i915_gem_object_create(i915, engine->context_size); |
1384 | if (IS_ERR(obj)) | 1393 | if (IS_ERR(obj)) |
1385 | return ERR_CAST(obj); | 1394 | return ERR_CAST(obj); |
1386 | 1395 | ||
1396 | if (engine->default_state) { | ||
1397 | void *defaults, *vaddr; | ||
1398 | |||
1399 | vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); | ||
1400 | if (IS_ERR(vaddr)) { | ||
1401 | err = PTR_ERR(vaddr); | ||
1402 | goto err_obj; | ||
1403 | } | ||
1404 | |||
1405 | defaults = i915_gem_object_pin_map(engine->default_state, | ||
1406 | I915_MAP_WB); | ||
1407 | if (IS_ERR(defaults)) { | ||
1408 | err = PTR_ERR(defaults); | ||
1409 | goto err_map; | ||
1410 | } | ||
1411 | |||
1412 | memcpy(vaddr, defaults, engine->context_size); | ||
1413 | |||
1414 | i915_gem_object_unpin_map(engine->default_state); | ||
1415 | i915_gem_object_unpin_map(obj); | ||
1416 | } | ||
1417 | |||
1387 | /* | 1418 | /* |
1388 | * Try to make the context utilize L3 as well as LLC. | 1419 | * Try to make the context utilize L3 as well as LLC. |
1389 | * | 1420 | * |
@@ -1405,10 +1436,18 @@ alloc_context_vma(struct intel_engine_cs *engine) | |||
1405 | } | 1436 | } |
1406 | 1437 | ||
1407 | vma = i915_vma_instance(obj, &i915->ggtt.base, NULL); | 1438 | vma = i915_vma_instance(obj, &i915->ggtt.base, NULL); |
1408 | if (IS_ERR(vma)) | 1439 | if (IS_ERR(vma)) { |
1409 | i915_gem_object_put(obj); | 1440 | err = PTR_ERR(vma); |
1441 | goto err_obj; | ||
1442 | } | ||
1410 | 1443 | ||
1411 | return vma; | 1444 | return vma; |
1445 | |||
1446 | err_map: | ||
1447 | i915_gem_object_unpin_map(obj); | ||
1448 | err_obj: | ||
1449 | i915_gem_object_put(obj); | ||
1450 | return ERR_PTR(err); | ||
1412 | } | 1451 | } |
1413 | 1452 | ||
1414 | static struct intel_ring * | 1453 | static struct intel_ring * |
@@ -1441,20 +1480,9 @@ intel_ring_context_pin(struct intel_engine_cs *engine, | |||
1441 | if (ret) | 1480 | if (ret) |
1442 | goto err; | 1481 | goto err; |
1443 | 1482 | ||
1444 | ce->state->obj->mm.dirty = true; | ||
1445 | ce->state->obj->pin_global++; | 1483 | ce->state->obj->pin_global++; |
1446 | } | 1484 | } |
1447 | 1485 | ||
1448 | /* The kernel context is only used as a placeholder for flushing the | ||
1449 | * active context. It is never used for submitting user rendering and | ||
1450 | * as such never requires the golden render context, and so we can skip | ||
1451 | * emitting it when we switch to the kernel context. This is required | ||
1452 | * as during eviction we cannot allocate and pin the renderstate in | ||
1453 | * order to initialise the context. | ||
1454 | */ | ||
1455 | if (i915_gem_context_is_kernel(ctx)) | ||
1456 | ce->initialised = true; | ||
1457 | |||
1458 | i915_gem_context_get(ctx); | 1486 | i915_gem_context_get(ctx); |
1459 | 1487 | ||
1460 | out: | 1488 | out: |
@@ -1550,7 +1578,7 @@ void intel_legacy_submission_resume(struct drm_i915_private *dev_priv) | |||
1550 | 1578 | ||
1551 | static int ring_request_alloc(struct drm_i915_gem_request *request) | 1579 | static int ring_request_alloc(struct drm_i915_gem_request *request) |
1552 | { | 1580 | { |
1553 | u32 *cs; | 1581 | int ret; |
1554 | 1582 | ||
1555 | GEM_BUG_ON(!request->ctx->engine[request->engine->id].pin_count); | 1583 | GEM_BUG_ON(!request->ctx->engine[request->engine->id].pin_count); |
1556 | 1584 | ||
@@ -1560,37 +1588,24 @@ static int ring_request_alloc(struct drm_i915_gem_request *request) | |||
1560 | */ | 1588 | */ |
1561 | request->reserved_space += LEGACY_REQUEST_SIZE; | 1589 | request->reserved_space += LEGACY_REQUEST_SIZE; |
1562 | 1590 | ||
1563 | cs = intel_ring_begin(request, 0); | 1591 | ret = intel_ring_wait_for_space(request->ring, request->reserved_space); |
1564 | if (IS_ERR(cs)) | 1592 | if (ret) |
1565 | return PTR_ERR(cs); | 1593 | return ret; |
1566 | 1594 | ||
1567 | request->reserved_space -= LEGACY_REQUEST_SIZE; | 1595 | request->reserved_space -= LEGACY_REQUEST_SIZE; |
1568 | return 0; | 1596 | return 0; |
1569 | } | 1597 | } |
1570 | 1598 | ||
1571 | static noinline int wait_for_space(struct drm_i915_gem_request *req, | 1599 | static noinline int wait_for_space(struct intel_ring *ring, unsigned int bytes) |
1572 | unsigned int bytes) | ||
1573 | { | 1600 | { |
1574 | struct intel_ring *ring = req->ring; | ||
1575 | struct drm_i915_gem_request *target; | 1601 | struct drm_i915_gem_request *target; |
1576 | long timeout; | 1602 | long timeout; |
1577 | 1603 | ||
1578 | lockdep_assert_held(&req->i915->drm.struct_mutex); | 1604 | lockdep_assert_held(&ring->vma->vm->i915->drm.struct_mutex); |
1579 | 1605 | ||
1580 | if (intel_ring_update_space(ring) >= bytes) | 1606 | if (intel_ring_update_space(ring) >= bytes) |
1581 | return 0; | 1607 | return 0; |
1582 | 1608 | ||
1583 | /* | ||
1584 | * Space is reserved in the ringbuffer for finalising the request, | ||
1585 | * as that cannot be allowed to fail. During request finalisation, | ||
1586 | * reserved_space is set to 0 to stop the overallocation and the | ||
1587 | * assumption is that then we never need to wait (which has the | ||
1588 | * risk of failing with EINTR). | ||
1589 | * | ||
1590 | * See also i915_gem_request_alloc() and i915_add_request(). | ||
1591 | */ | ||
1592 | GEM_BUG_ON(!req->reserved_space); | ||
1593 | |||
1594 | list_for_each_entry(target, &ring->request_list, ring_link) { | 1609 | list_for_each_entry(target, &ring->request_list, ring_link) { |
1595 | /* Would completion of this request free enough space? */ | 1610 | /* Would completion of this request free enough space? */ |
1596 | if (bytes <= __intel_ring_space(target->postfix, | 1611 | if (bytes <= __intel_ring_space(target->postfix, |
@@ -1614,6 +1629,22 @@ static noinline int wait_for_space(struct drm_i915_gem_request *req, | |||
1614 | return 0; | 1629 | return 0; |
1615 | } | 1630 | } |
1616 | 1631 | ||
1632 | int intel_ring_wait_for_space(struct intel_ring *ring, unsigned int bytes) | ||
1633 | { | ||
1634 | GEM_BUG_ON(bytes > ring->effective_size); | ||
1635 | if (unlikely(bytes > ring->effective_size - ring->emit)) | ||
1636 | bytes += ring->size - ring->emit; | ||
1637 | |||
1638 | if (unlikely(bytes > ring->space)) { | ||
1639 | int ret = wait_for_space(ring, bytes); | ||
1640 | if (unlikely(ret)) | ||
1641 | return ret; | ||
1642 | } | ||
1643 | |||
1644 | GEM_BUG_ON(ring->space < bytes); | ||
1645 | return 0; | ||
1646 | } | ||
1647 | |||
1617 | u32 *intel_ring_begin(struct drm_i915_gem_request *req, | 1648 | u32 *intel_ring_begin(struct drm_i915_gem_request *req, |
1618 | unsigned int num_dwords) | 1649 | unsigned int num_dwords) |
1619 | { | 1650 | { |
@@ -1653,7 +1684,20 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req, | |||
1653 | } | 1684 | } |
1654 | 1685 | ||
1655 | if (unlikely(total_bytes > ring->space)) { | 1686 | if (unlikely(total_bytes > ring->space)) { |
1656 | int ret = wait_for_space(req, total_bytes); | 1687 | int ret; |
1688 | |||
1689 | /* | ||
1690 | * Space is reserved in the ringbuffer for finalising the | ||
1691 | * request, as that cannot be allowed to fail. During request | ||
1692 | * finalisation, reserved_space is set to 0 to stop the | ||
1693 | * overallocation and the assumption is that then we never need | ||
1694 | * to wait (which has the risk of failing with EINTR). | ||
1695 | * | ||
1696 | * See also i915_gem_request_alloc() and i915_add_request(). | ||
1697 | */ | ||
1698 | GEM_BUG_ON(!req->reserved_space); | ||
1699 | |||
1700 | ret = wait_for_space(ring, total_bytes); | ||
1657 | if (unlikely(ret)) | 1701 | if (unlikely(ret)) |
1658 | return ERR_PTR(ret); | 1702 | return ERR_PTR(ret); |
1659 | } | 1703 | } |
@@ -2028,12 +2072,15 @@ static void i9xx_set_default_submission(struct intel_engine_cs *engine) | |||
2028 | { | 2072 | { |
2029 | engine->submit_request = i9xx_submit_request; | 2073 | engine->submit_request = i9xx_submit_request; |
2030 | engine->cancel_requests = cancel_requests; | 2074 | engine->cancel_requests = cancel_requests; |
2075 | |||
2076 | engine->park = NULL; | ||
2077 | engine->unpark = NULL; | ||
2031 | } | 2078 | } |
2032 | 2079 | ||
2033 | static void gen6_bsd_set_default_submission(struct intel_engine_cs *engine) | 2080 | static void gen6_bsd_set_default_submission(struct intel_engine_cs *engine) |
2034 | { | 2081 | { |
2082 | i9xx_set_default_submission(engine); | ||
2035 | engine->submit_request = gen6_bsd_submit_request; | 2083 | engine->submit_request = gen6_bsd_submit_request; |
2036 | engine->cancel_requests = cancel_requests; | ||
2037 | } | 2084 | } |
2038 | 2085 | ||
2039 | static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, | 2086 | static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 2863d5a65187..f867aa6c31fc 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -166,7 +166,6 @@ struct i915_ctx_workarounds { | |||
166 | }; | 166 | }; |
167 | 167 | ||
168 | struct drm_i915_gem_request; | 168 | struct drm_i915_gem_request; |
169 | struct intel_render_state; | ||
170 | 169 | ||
171 | /* | 170 | /* |
172 | * Engine IDs definitions. | 171 | * Engine IDs definitions. |
@@ -195,9 +194,9 @@ struct i915_priolist { | |||
195 | */ | 194 | */ |
196 | struct intel_engine_execlists { | 195 | struct intel_engine_execlists { |
197 | /** | 196 | /** |
198 | * @irq_tasklet: softirq tasklet for bottom handler | 197 | * @tasklet: softirq tasklet for bottom handler |
199 | */ | 198 | */ |
200 | struct tasklet_struct irq_tasklet; | 199 | struct tasklet_struct tasklet; |
201 | 200 | ||
202 | /** | 201 | /** |
203 | * @default_priolist: priority list for I915_PRIORITY_NORMAL | 202 | * @default_priolist: priority list for I915_PRIORITY_NORMAL |
@@ -290,11 +289,14 @@ struct intel_engine_execlists { | |||
290 | struct intel_engine_cs { | 289 | struct intel_engine_cs { |
291 | struct drm_i915_private *i915; | 290 | struct drm_i915_private *i915; |
292 | char name[INTEL_ENGINE_CS_MAX_NAME]; | 291 | char name[INTEL_ENGINE_CS_MAX_NAME]; |
292 | |||
293 | enum intel_engine_id id; | 293 | enum intel_engine_id id; |
294 | unsigned int uabi_id; | ||
295 | unsigned int hw_id; | 294 | unsigned int hw_id; |
296 | unsigned int guc_id; | 295 | unsigned int guc_id; |
297 | 296 | ||
297 | u8 uabi_id; | ||
298 | u8 uabi_class; | ||
299 | |||
298 | u8 class; | 300 | u8 class; |
299 | u8 instance; | 301 | u8 instance; |
300 | u32 context_size; | 302 | u32 context_size; |
@@ -304,7 +306,7 @@ struct intel_engine_cs { | |||
304 | struct intel_ring *buffer; | 306 | struct intel_ring *buffer; |
305 | struct intel_timeline *timeline; | 307 | struct intel_timeline *timeline; |
306 | 308 | ||
307 | struct intel_render_state *render_state; | 309 | struct drm_i915_gem_object *default_state; |
308 | 310 | ||
309 | atomic_t irq_count; | 311 | atomic_t irq_count; |
310 | unsigned long irq_posted; | 312 | unsigned long irq_posted; |
@@ -340,9 +342,9 @@ struct intel_engine_cs { | |||
340 | struct timer_list hangcheck; /* detect missed interrupts */ | 342 | struct timer_list hangcheck; /* detect missed interrupts */ |
341 | 343 | ||
342 | unsigned int hangcheck_interrupts; | 344 | unsigned int hangcheck_interrupts; |
345 | unsigned int irq_enabled; | ||
343 | 346 | ||
344 | bool irq_armed : 1; | 347 | bool irq_armed : 1; |
345 | bool irq_enabled : 1; | ||
346 | I915_SELFTEST_DECLARE(bool mock : 1); | 348 | I915_SELFTEST_DECLARE(bool mock : 1); |
347 | } breadcrumbs; | 349 | } breadcrumbs; |
348 | 350 | ||
@@ -366,6 +368,9 @@ struct intel_engine_cs { | |||
366 | void (*reset_hw)(struct intel_engine_cs *engine, | 368 | void (*reset_hw)(struct intel_engine_cs *engine, |
367 | struct drm_i915_gem_request *req); | 369 | struct drm_i915_gem_request *req); |
368 | 370 | ||
371 | void (*park)(struct intel_engine_cs *engine); | ||
372 | void (*unpark)(struct intel_engine_cs *engine); | ||
373 | |||
369 | void (*set_default_submission)(struct intel_engine_cs *engine); | 374 | void (*set_default_submission)(struct intel_engine_cs *engine); |
370 | 375 | ||
371 | struct intel_ring *(*context_pin)(struct intel_engine_cs *engine, | 376 | struct intel_ring *(*context_pin)(struct intel_engine_cs *engine, |
@@ -555,6 +560,12 @@ execlists_is_active(const struct intel_engine_execlists *execlists, | |||
555 | return test_bit(bit, (unsigned long *)&execlists->active); | 560 | return test_bit(bit, (unsigned long *)&execlists->active); |
556 | } | 561 | } |
557 | 562 | ||
563 | void | ||
564 | execlists_cancel_port_requests(struct intel_engine_execlists * const execlists); | ||
565 | |||
566 | void | ||
567 | execlists_unwind_incomplete_requests(struct intel_engine_execlists *execlists); | ||
568 | |||
558 | static inline unsigned int | 569 | static inline unsigned int |
559 | execlists_num_ports(const struct intel_engine_execlists * const execlists) | 570 | execlists_num_ports(const struct intel_engine_execlists * const execlists) |
560 | { | 571 | { |
@@ -624,6 +635,8 @@ intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value) | |||
624 | */ | 635 | */ |
625 | #define I915_GEM_HWS_INDEX 0x30 | 636 | #define I915_GEM_HWS_INDEX 0x30 |
626 | #define I915_GEM_HWS_INDEX_ADDR (I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT) | 637 | #define I915_GEM_HWS_INDEX_ADDR (I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT) |
638 | #define I915_GEM_HWS_PREEMPT_INDEX 0x32 | ||
639 | #define I915_GEM_HWS_PREEMPT_ADDR (I915_GEM_HWS_PREEMPT_INDEX << MI_STORE_DWORD_INDEX_SHIFT) | ||
627 | #define I915_GEM_HWS_SCRATCH_INDEX 0x40 | 640 | #define I915_GEM_HWS_SCRATCH_INDEX 0x40 |
628 | #define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT) | 641 | #define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT) |
629 | 642 | ||
@@ -648,6 +661,7 @@ void intel_legacy_submission_resume(struct drm_i915_private *dev_priv); | |||
648 | 661 | ||
649 | int __must_check intel_ring_cacheline_align(struct drm_i915_gem_request *req); | 662 | int __must_check intel_ring_cacheline_align(struct drm_i915_gem_request *req); |
650 | 663 | ||
664 | int intel_ring_wait_for_space(struct intel_ring *ring, unsigned int bytes); | ||
651 | u32 __must_check *intel_ring_begin(struct drm_i915_gem_request *req, | 665 | u32 __must_check *intel_ring_begin(struct drm_i915_gem_request *req, |
652 | unsigned int n); | 666 | unsigned int n); |
653 | 667 | ||
@@ -776,6 +790,11 @@ static inline u32 intel_hws_seqno_address(struct intel_engine_cs *engine) | |||
776 | return engine->status_page.ggtt_offset + I915_GEM_HWS_INDEX_ADDR; | 790 | return engine->status_page.ggtt_offset + I915_GEM_HWS_INDEX_ADDR; |
777 | } | 791 | } |
778 | 792 | ||
793 | static inline u32 intel_hws_preempt_done_address(struct intel_engine_cs *engine) | ||
794 | { | ||
795 | return engine->status_page.ggtt_offset + I915_GEM_HWS_PREEMPT_ADDR; | ||
796 | } | ||
797 | |||
779 | /* intel_breadcrumbs.c -- user interrupt bottom-half for waiters */ | 798 | /* intel_breadcrumbs.c -- user interrupt bottom-half for waiters */ |
780 | int intel_engine_init_breadcrumbs(struct intel_engine_cs *engine); | 799 | int intel_engine_init_breadcrumbs(struct intel_engine_cs *engine); |
781 | 800 | ||
@@ -846,6 +865,9 @@ unsigned int intel_engine_wakeup(struct intel_engine_cs *engine); | |||
846 | #define ENGINE_WAKEUP_WAITER BIT(0) | 865 | #define ENGINE_WAKEUP_WAITER BIT(0) |
847 | #define ENGINE_WAKEUP_ASLEEP BIT(1) | 866 | #define ENGINE_WAKEUP_ASLEEP BIT(1) |
848 | 867 | ||
868 | void intel_engine_pin_breadcrumbs_irq(struct intel_engine_cs *engine); | ||
869 | void intel_engine_unpin_breadcrumbs_irq(struct intel_engine_cs *engine); | ||
870 | |||
849 | void __intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine); | 871 | void __intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine); |
850 | void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine); | 872 | void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine); |
851 | 873 | ||
@@ -864,11 +886,54 @@ static inline u32 *gen8_emit_pipe_control(u32 *batch, u32 flags, u32 offset) | |||
864 | return batch + 6; | 886 | return batch + 6; |
865 | } | 887 | } |
866 | 888 | ||
889 | static inline u32 * | ||
890 | gen8_emit_ggtt_write_rcs(u32 *cs, u32 value, u32 gtt_offset) | ||
891 | { | ||
892 | /* We're using qword write, offset should be aligned to 8 bytes. */ | ||
893 | GEM_BUG_ON(!IS_ALIGNED(gtt_offset, 8)); | ||
894 | |||
895 | /* w/a for post sync ops following a GPGPU operation we | ||
896 | * need a prior CS_STALL, which is emitted by the flush | ||
897 | * following the batch. | ||
898 | */ | ||
899 | *cs++ = GFX_OP_PIPE_CONTROL(6); | ||
900 | *cs++ = PIPE_CONTROL_GLOBAL_GTT_IVB | PIPE_CONTROL_CS_STALL | | ||
901 | PIPE_CONTROL_QW_WRITE; | ||
902 | *cs++ = gtt_offset; | ||
903 | *cs++ = 0; | ||
904 | *cs++ = value; | ||
905 | /* We're thrashing one dword of HWS. */ | ||
906 | *cs++ = 0; | ||
907 | |||
908 | return cs; | ||
909 | } | ||
910 | |||
911 | static inline u32 * | ||
912 | gen8_emit_ggtt_write(u32 *cs, u32 value, u32 gtt_offset) | ||
913 | { | ||
914 | /* w/a: bit 5 needs to be zero for MI_FLUSH_DW address. */ | ||
915 | GEM_BUG_ON(gtt_offset & (1 << 5)); | ||
916 | /* Offset should be aligned to 8 bytes for both (QW/DW) write types */ | ||
917 | GEM_BUG_ON(!IS_ALIGNED(gtt_offset, 8)); | ||
918 | |||
919 | *cs++ = (MI_FLUSH_DW + 1) | MI_FLUSH_DW_OP_STOREDW; | ||
920 | *cs++ = gtt_offset | MI_FLUSH_DW_USE_GTT; | ||
921 | *cs++ = 0; | ||
922 | *cs++ = value; | ||
923 | |||
924 | return cs; | ||
925 | } | ||
926 | |||
867 | bool intel_engine_is_idle(struct intel_engine_cs *engine); | 927 | bool intel_engine_is_idle(struct intel_engine_cs *engine); |
868 | bool intel_engines_are_idle(struct drm_i915_private *dev_priv); | 928 | bool intel_engines_are_idle(struct drm_i915_private *dev_priv); |
869 | 929 | ||
870 | void intel_engines_mark_idle(struct drm_i915_private *i915); | 930 | bool intel_engine_has_kernel_context(const struct intel_engine_cs *engine); |
931 | |||
932 | void intel_engines_park(struct drm_i915_private *i915); | ||
933 | void intel_engines_unpark(struct drm_i915_private *i915); | ||
934 | |||
871 | void intel_engines_reset_default_submission(struct drm_i915_private *i915); | 935 | void intel_engines_reset_default_submission(struct drm_i915_private *i915); |
936 | unsigned int intel_engines_has_context_isolation(struct drm_i915_private *i915); | ||
872 | 937 | ||
873 | bool intel_engine_can_store_dword(struct intel_engine_cs *engine); | 938 | bool intel_engine_can_store_dword(struct intel_engine_cs *engine); |
874 | 939 | ||
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 8af286c63d3b..8315499452dc 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c | |||
@@ -705,7 +705,8 @@ static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv, | |||
705 | gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); | 705 | gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); |
706 | 706 | ||
707 | dev_priv->display.get_cdclk(dev_priv, &cdclk_state); | 707 | dev_priv->display.get_cdclk(dev_priv, &cdclk_state); |
708 | WARN_ON(!intel_cdclk_state_compare(&dev_priv->cdclk.hw, &cdclk_state)); | 708 | /* Can't read out voltage_level so can't use intel_cdclk_changed() */ |
709 | WARN_ON(intel_cdclk_needs_modeset(&dev_priv->cdclk.hw, &cdclk_state)); | ||
709 | 710 | ||
710 | gen9_assert_dbuf_enabled(dev_priv); | 711 | gen9_assert_dbuf_enabled(dev_priv); |
711 | 712 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 7437944b388f..2b8764897d68 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1429,6 +1429,8 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, | |||
1429 | u8 val; | 1429 | u8 val; |
1430 | bool ret; | 1430 | bool ret; |
1431 | 1431 | ||
1432 | pipe_config->output_types |= BIT(INTEL_OUTPUT_SDVO); | ||
1433 | |||
1432 | sdvox = I915_READ(intel_sdvo->sdvo_reg); | 1434 | sdvox = I915_READ(intel_sdvo->sdvo_reg); |
1433 | 1435 | ||
1434 | ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); | 1436 | ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); |
@@ -1510,7 +1512,7 @@ static void intel_disable_sdvo(struct intel_encoder *encoder, | |||
1510 | { | 1512 | { |
1511 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 1513 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
1512 | struct intel_sdvo *intel_sdvo = to_sdvo(encoder); | 1514 | struct intel_sdvo *intel_sdvo = to_sdvo(encoder); |
1513 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); | 1515 | struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); |
1514 | u32 temp; | 1516 | u32 temp; |
1515 | 1517 | ||
1516 | intel_sdvo_set_active_outputs(intel_sdvo, 0); | 1518 | intel_sdvo_set_active_outputs(intel_sdvo, 0); |
@@ -1569,7 +1571,7 @@ static void intel_enable_sdvo(struct intel_encoder *encoder, | |||
1569 | struct drm_device *dev = encoder->base.dev; | 1571 | struct drm_device *dev = encoder->base.dev; |
1570 | struct drm_i915_private *dev_priv = to_i915(dev); | 1572 | struct drm_i915_private *dev_priv = to_i915(dev); |
1571 | struct intel_sdvo *intel_sdvo = to_sdvo(encoder); | 1573 | struct intel_sdvo *intel_sdvo = to_sdvo(encoder); |
1572 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); | 1574 | struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc); |
1573 | u32 temp; | 1575 | u32 temp; |
1574 | bool input1, input2; | 1576 | bool input1, input2; |
1575 | int i; | 1577 | int i; |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 4fcf80ca91dd..ce615704982a 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
@@ -263,13 +263,9 @@ skl_update_plane(struct intel_plane *plane, | |||
263 | 263 | ||
264 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); | 264 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); |
265 | 265 | ||
266 | if (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) { | 266 | if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) |
267 | I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), | 267 | I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), |
268 | PLANE_COLOR_PIPE_GAMMA_ENABLE | | 268 | plane_state->color_ctl); |
269 | PLANE_COLOR_PIPE_CSC_ENABLE | | ||
270 | PLANE_COLOR_PLANE_GAMMA_DISABLE); | ||
271 | } | ||
272 | |||
273 | if (key->flags) { | 269 | if (key->flags) { |
274 | I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value); | 270 | I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value); |
275 | I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), key->max_value); | 271 | I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), key->max_value); |
@@ -978,6 +974,9 @@ intel_check_sprite_plane(struct intel_plane *plane, | |||
978 | state->ctl = g4x_sprite_ctl(crtc_state, state); | 974 | state->ctl = g4x_sprite_ctl(crtc_state, state); |
979 | } | 975 | } |
980 | 976 | ||
977 | if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) | ||
978 | state->color_ctl = glk_plane_color_ctl(crtc_state, state); | ||
979 | |||
981 | return 0; | 980 | return 0; |
982 | } | 981 | } |
983 | 982 | ||
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index a79a7591b2cf..b3dabc219e6a 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -822,7 +822,7 @@ intel_enable_tv(struct intel_encoder *encoder, | |||
822 | 822 | ||
823 | /* Prevents vblank waits from timing out in intel_tv_detect_type() */ | 823 | /* Prevents vblank waits from timing out in intel_tv_detect_type() */ |
824 | intel_wait_for_vblank(dev_priv, | 824 | intel_wait_for_vblank(dev_priv, |
825 | to_intel_crtc(encoder->base.crtc)->pipe); | 825 | to_intel_crtc(pipe_config->base.crtc)->pipe); |
826 | 826 | ||
827 | I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE); | 827 | I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE); |
828 | } | 828 | } |
@@ -868,6 +868,8 @@ static void | |||
868 | intel_tv_get_config(struct intel_encoder *encoder, | 868 | intel_tv_get_config(struct intel_encoder *encoder, |
869 | struct intel_crtc_state *pipe_config) | 869 | struct intel_crtc_state *pipe_config) |
870 | { | 870 | { |
871 | pipe_config->output_types |= BIT(INTEL_OUTPUT_TVOUT); | ||
872 | |||
871 | pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; | 873 | pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; |
872 | } | 874 | } |
873 | 875 | ||
@@ -980,7 +982,7 @@ static void intel_tv_pre_enable(struct intel_encoder *encoder, | |||
980 | const struct drm_connector_state *conn_state) | 982 | const struct drm_connector_state *conn_state) |
981 | { | 983 | { |
982 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 984 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
983 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); | 985 | struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc); |
984 | struct intel_tv *intel_tv = enc_to_tv(encoder); | 986 | struct intel_tv *intel_tv = enc_to_tv(encoder); |
985 | const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state); | 987 | const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state); |
986 | u32 tv_ctl; | 988 | u32 tv_ctl; |
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 25bd162f38d2..1e2a30a40ede 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c | |||
@@ -23,8 +23,8 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "intel_uc.h" | 25 | #include "intel_uc.h" |
26 | #include "intel_guc_submission.h" | ||
26 | #include "i915_drv.h" | 27 | #include "i915_drv.h" |
27 | #include "i915_guc_submission.h" | ||
28 | 28 | ||
29 | /* Reset GuC providing us with fresh state for both GuC and HuC. | 29 | /* Reset GuC providing us with fresh state for both GuC and HuC. |
30 | */ | 30 | */ |
@@ -33,9 +33,9 @@ static int __intel_uc_reset_hw(struct drm_i915_private *dev_priv) | |||
33 | int ret; | 33 | int ret; |
34 | u32 guc_status; | 34 | u32 guc_status; |
35 | 35 | ||
36 | ret = intel_guc_reset(dev_priv); | 36 | ret = intel_reset_guc(dev_priv); |
37 | if (ret) { | 37 | if (ret) { |
38 | DRM_ERROR("GuC reset failed, ret = %d\n", ret); | 38 | DRM_ERROR("Failed to reset GuC, ret = %d\n", ret); |
39 | return ret; | 39 | return ret; |
40 | } | 40 | } |
41 | 41 | ||
@@ -168,7 +168,7 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) | |||
168 | * This is stuff we need to have available at fw load time | 168 | * This is stuff we need to have available at fw load time |
169 | * if we are planning to enable submission later | 169 | * if we are planning to enable submission later |
170 | */ | 170 | */ |
171 | ret = i915_guc_submission_init(dev_priv); | 171 | ret = intel_guc_submission_init(guc); |
172 | if (ret) | 172 | if (ret) |
173 | goto err_guc; | 173 | goto err_guc; |
174 | } | 174 | } |
@@ -217,7 +217,7 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) | |||
217 | if (i915_modparams.guc_log_level >= 0) | 217 | if (i915_modparams.guc_log_level >= 0) |
218 | gen9_enable_guc_interrupts(dev_priv); | 218 | gen9_enable_guc_interrupts(dev_priv); |
219 | 219 | ||
220 | ret = i915_guc_submission_enable(dev_priv); | 220 | ret = intel_guc_submission_enable(guc); |
221 | if (ret) | 221 | if (ret) |
222 | goto err_interrupts; | 222 | goto err_interrupts; |
223 | } | 223 | } |
@@ -246,7 +246,7 @@ err_log_capture: | |||
246 | guc_capture_load_err_log(guc); | 246 | guc_capture_load_err_log(guc); |
247 | err_submission: | 247 | err_submission: |
248 | if (i915_modparams.enable_guc_submission) | 248 | if (i915_modparams.enable_guc_submission) |
249 | i915_guc_submission_fini(dev_priv); | 249 | intel_guc_submission_fini(guc); |
250 | err_guc: | 250 | err_guc: |
251 | i915_ggtt_disable_guc(dev_priv); | 251 | i915_ggtt_disable_guc(dev_priv); |
252 | 252 | ||
@@ -271,19 +271,21 @@ err_guc: | |||
271 | 271 | ||
272 | void intel_uc_fini_hw(struct drm_i915_private *dev_priv) | 272 | void intel_uc_fini_hw(struct drm_i915_private *dev_priv) |
273 | { | 273 | { |
274 | guc_free_load_err_log(&dev_priv->guc); | 274 | struct intel_guc *guc = &dev_priv->guc; |
275 | |||
276 | guc_free_load_err_log(guc); | ||
275 | 277 | ||
276 | if (!i915_modparams.enable_guc_loading) | 278 | if (!i915_modparams.enable_guc_loading) |
277 | return; | 279 | return; |
278 | 280 | ||
279 | if (i915_modparams.enable_guc_submission) | 281 | if (i915_modparams.enable_guc_submission) |
280 | i915_guc_submission_disable(dev_priv); | 282 | intel_guc_submission_disable(guc); |
281 | 283 | ||
282 | guc_disable_communication(&dev_priv->guc); | 284 | guc_disable_communication(guc); |
283 | 285 | ||
284 | if (i915_modparams.enable_guc_submission) { | 286 | if (i915_modparams.enable_guc_submission) { |
285 | gen9_disable_guc_interrupts(dev_priv); | 287 | gen9_disable_guc_interrupts(dev_priv); |
286 | i915_guc_submission_fini(dev_priv); | 288 | intel_guc_submission_fini(guc); |
287 | } | 289 | } |
288 | 290 | ||
289 | i915_ggtt_disable_guc(dev_priv); | 291 | i915_ggtt_disable_guc(dev_priv); |
diff --git a/drivers/gpu/drm/i915/intel_uc_fw.c b/drivers/gpu/drm/i915/intel_uc_fw.c index 973888e94cba..4bc82d3005ff 100644 --- a/drivers/gpu/drm/i915/intel_uc_fw.c +++ b/drivers/gpu/drm/i915/intel_uc_fw.c | |||
@@ -299,7 +299,7 @@ void intel_uc_fw_fini(struct intel_uc_fw *uc_fw) | |||
299 | * | 299 | * |
300 | * Pretty printer for uC firmware. | 300 | * Pretty printer for uC firmware. |
301 | */ | 301 | */ |
302 | void intel_uc_fw_dump(struct intel_uc_fw *uc_fw, struct drm_printer *p) | 302 | void intel_uc_fw_dump(const struct intel_uc_fw *uc_fw, struct drm_printer *p) |
303 | { | 303 | { |
304 | drm_printf(p, "%s firmware: %s\n", | 304 | drm_printf(p, "%s firmware: %s\n", |
305 | intel_uc_fw_type_repr(uc_fw->type), uc_fw->path); | 305 | intel_uc_fw_type_repr(uc_fw->type), uc_fw->path); |
diff --git a/drivers/gpu/drm/i915/intel_uc_fw.h b/drivers/gpu/drm/i915/intel_uc_fw.h index 132903669391..5394d9d1e683 100644 --- a/drivers/gpu/drm/i915/intel_uc_fw.h +++ b/drivers/gpu/drm/i915/intel_uc_fw.h | |||
@@ -116,6 +116,6 @@ int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, | |||
116 | int (*xfer)(struct intel_uc_fw *uc_fw, | 116 | int (*xfer)(struct intel_uc_fw *uc_fw, |
117 | struct i915_vma *vma)); | 117 | struct i915_vma *vma)); |
118 | void intel_uc_fw_fini(struct intel_uc_fw *uc_fw); | 118 | void intel_uc_fw_fini(struct intel_uc_fw *uc_fw); |
119 | void intel_uc_fw_dump(struct intel_uc_fw *uc_fw, struct drm_printer *p); | 119 | void intel_uc_fw_dump(const struct intel_uc_fw *uc_fw, struct drm_printer *p); |
120 | 120 | ||
121 | #endif | 121 | #endif |
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 8c2ce81f01c2..b4621271e7a2 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c | |||
@@ -69,17 +69,104 @@ fw_domain_arm_timer(struct intel_uncore_forcewake_domain *d) | |||
69 | HRTIMER_MODE_REL); | 69 | HRTIMER_MODE_REL); |
70 | } | 70 | } |
71 | 71 | ||
72 | static inline int | ||
73 | __wait_for_ack(const struct drm_i915_private *i915, | ||
74 | const struct intel_uncore_forcewake_domain *d, | ||
75 | const u32 ack, | ||
76 | const u32 value) | ||
77 | { | ||
78 | return wait_for_atomic((__raw_i915_read32(i915, d->reg_ack) & ack) == value, | ||
79 | FORCEWAKE_ACK_TIMEOUT_MS); | ||
80 | } | ||
81 | |||
82 | static inline int | ||
83 | wait_ack_clear(const struct drm_i915_private *i915, | ||
84 | const struct intel_uncore_forcewake_domain *d, | ||
85 | const u32 ack) | ||
86 | { | ||
87 | return __wait_for_ack(i915, d, ack, 0); | ||
88 | } | ||
89 | |||
90 | static inline int | ||
91 | wait_ack_set(const struct drm_i915_private *i915, | ||
92 | const struct intel_uncore_forcewake_domain *d, | ||
93 | const u32 ack) | ||
94 | { | ||
95 | return __wait_for_ack(i915, d, ack, ack); | ||
96 | } | ||
97 | |||
72 | static inline void | 98 | static inline void |
73 | fw_domain_wait_ack_clear(const struct drm_i915_private *i915, | 99 | fw_domain_wait_ack_clear(const struct drm_i915_private *i915, |
74 | const struct intel_uncore_forcewake_domain *d) | 100 | const struct intel_uncore_forcewake_domain *d) |
75 | { | 101 | { |
76 | if (wait_for_atomic((__raw_i915_read32(i915, d->reg_ack) & | 102 | if (wait_ack_clear(i915, d, FORCEWAKE_KERNEL)) |
77 | FORCEWAKE_KERNEL) == 0, | ||
78 | FORCEWAKE_ACK_TIMEOUT_MS)) | ||
79 | DRM_ERROR("%s: timed out waiting for forcewake ack to clear.\n", | 103 | DRM_ERROR("%s: timed out waiting for forcewake ack to clear.\n", |
80 | intel_uncore_forcewake_domain_to_str(d->id)); | 104 | intel_uncore_forcewake_domain_to_str(d->id)); |
81 | } | 105 | } |
82 | 106 | ||
107 | enum ack_type { | ||
108 | ACK_CLEAR = 0, | ||
109 | ACK_SET | ||
110 | }; | ||
111 | |||
112 | static int | ||
113 | fw_domain_wait_ack_with_fallback(const struct drm_i915_private *i915, | ||
114 | const struct intel_uncore_forcewake_domain *d, | ||
115 | const enum ack_type type) | ||
116 | { | ||
117 | const u32 ack_bit = FORCEWAKE_KERNEL; | ||
118 | const u32 value = type == ACK_SET ? ack_bit : 0; | ||
119 | unsigned int pass; | ||
120 | bool ack_detected; | ||
121 | |||
122 | /* | ||
123 | * There is a possibility of driver's wake request colliding | ||
124 | * with hardware's own wake requests and that can cause | ||
125 | * hardware to not deliver the driver's ack message. | ||
126 | * | ||
127 | * Use a fallback bit toggle to kick the gpu state machine | ||
128 | * in the hope that the original ack will be delivered along with | ||
129 | * the fallback ack. | ||
130 | * | ||
131 | * This workaround is described in HSDES #1604254524 | ||
132 | */ | ||
133 | |||
134 | pass = 1; | ||
135 | do { | ||
136 | wait_ack_clear(i915, d, FORCEWAKE_KERNEL_FALLBACK); | ||
137 | |||
138 | __raw_i915_write32(i915, d->reg_set, | ||
139 | _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL_FALLBACK)); | ||
140 | /* Give gt some time to relax before the polling frenzy */ | ||
141 | udelay(10 * pass); | ||
142 | wait_ack_set(i915, d, FORCEWAKE_KERNEL_FALLBACK); | ||
143 | |||
144 | ack_detected = (__raw_i915_read32(i915, d->reg_ack) & ack_bit) == value; | ||
145 | |||
146 | __raw_i915_write32(i915, d->reg_set, | ||
147 | _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL_FALLBACK)); | ||
148 | } while (!ack_detected && pass++ < 10); | ||
149 | |||
150 | DRM_DEBUG_DRIVER("%s had to use fallback to %s ack, 0x%x (passes %u)\n", | ||
151 | intel_uncore_forcewake_domain_to_str(d->id), | ||
152 | type == ACK_SET ? "set" : "clear", | ||
153 | __raw_i915_read32(i915, d->reg_ack), | ||
154 | pass); | ||
155 | |||
156 | return ack_detected ? 0 : -ETIMEDOUT; | ||
157 | } | ||
158 | |||
159 | static inline void | ||
160 | fw_domain_wait_ack_clear_fallback(const struct drm_i915_private *i915, | ||
161 | const struct intel_uncore_forcewake_domain *d) | ||
162 | { | ||
163 | if (likely(!wait_ack_clear(i915, d, FORCEWAKE_KERNEL))) | ||
164 | return; | ||
165 | |||
166 | if (fw_domain_wait_ack_with_fallback(i915, d, ACK_CLEAR)) | ||
167 | fw_domain_wait_ack_clear(i915, d); | ||
168 | } | ||
169 | |||
83 | static inline void | 170 | static inline void |
84 | fw_domain_get(struct drm_i915_private *i915, | 171 | fw_domain_get(struct drm_i915_private *i915, |
85 | const struct intel_uncore_forcewake_domain *d) | 172 | const struct intel_uncore_forcewake_domain *d) |
@@ -88,17 +175,26 @@ fw_domain_get(struct drm_i915_private *i915, | |||
88 | } | 175 | } |
89 | 176 | ||
90 | static inline void | 177 | static inline void |
91 | fw_domain_wait_ack(const struct drm_i915_private *i915, | 178 | fw_domain_wait_ack_set(const struct drm_i915_private *i915, |
92 | const struct intel_uncore_forcewake_domain *d) | 179 | const struct intel_uncore_forcewake_domain *d) |
93 | { | 180 | { |
94 | if (wait_for_atomic((__raw_i915_read32(i915, d->reg_ack) & | 181 | if (wait_ack_set(i915, d, FORCEWAKE_KERNEL)) |
95 | FORCEWAKE_KERNEL), | ||
96 | FORCEWAKE_ACK_TIMEOUT_MS)) | ||
97 | DRM_ERROR("%s: timed out waiting for forcewake ack request.\n", | 182 | DRM_ERROR("%s: timed out waiting for forcewake ack request.\n", |
98 | intel_uncore_forcewake_domain_to_str(d->id)); | 183 | intel_uncore_forcewake_domain_to_str(d->id)); |
99 | } | 184 | } |
100 | 185 | ||
101 | static inline void | 186 | static inline void |
187 | fw_domain_wait_ack_set_fallback(const struct drm_i915_private *i915, | ||
188 | const struct intel_uncore_forcewake_domain *d) | ||
189 | { | ||
190 | if (likely(!wait_ack_set(i915, d, FORCEWAKE_KERNEL))) | ||
191 | return; | ||
192 | |||
193 | if (fw_domain_wait_ack_with_fallback(i915, d, ACK_SET)) | ||
194 | fw_domain_wait_ack_set(i915, d); | ||
195 | } | ||
196 | |||
197 | static inline void | ||
102 | fw_domain_put(const struct drm_i915_private *i915, | 198 | fw_domain_put(const struct drm_i915_private *i915, |
103 | const struct intel_uncore_forcewake_domain *d) | 199 | const struct intel_uncore_forcewake_domain *d) |
104 | { | 200 | { |
@@ -119,7 +215,27 @@ fw_domains_get(struct drm_i915_private *i915, enum forcewake_domains fw_domains) | |||
119 | } | 215 | } |
120 | 216 | ||
121 | for_each_fw_domain_masked(d, fw_domains, i915, tmp) | 217 | for_each_fw_domain_masked(d, fw_domains, i915, tmp) |
122 | fw_domain_wait_ack(i915, d); | 218 | fw_domain_wait_ack_set(i915, d); |
219 | |||
220 | i915->uncore.fw_domains_active |= fw_domains; | ||
221 | } | ||
222 | |||
223 | static void | ||
224 | fw_domains_get_with_fallback(struct drm_i915_private *i915, | ||
225 | enum forcewake_domains fw_domains) | ||
226 | { | ||
227 | struct intel_uncore_forcewake_domain *d; | ||
228 | unsigned int tmp; | ||
229 | |||
230 | GEM_BUG_ON(fw_domains & ~i915->uncore.fw_domains); | ||
231 | |||
232 | for_each_fw_domain_masked(d, fw_domains, i915, tmp) { | ||
233 | fw_domain_wait_ack_clear_fallback(i915, d); | ||
234 | fw_domain_get(i915, d); | ||
235 | } | ||
236 | |||
237 | for_each_fw_domain_masked(d, fw_domains, i915, tmp) | ||
238 | fw_domain_wait_ack_set_fallback(i915, d); | ||
123 | 239 | ||
124 | i915->uncore.fw_domains_active |= fw_domains; | 240 | i915->uncore.fw_domains_active |= fw_domains; |
125 | } | 241 | } |
@@ -229,6 +345,7 @@ intel_uncore_fw_release_timer(struct hrtimer *timer) | |||
229 | return HRTIMER_NORESTART; | 345 | return HRTIMER_NORESTART; |
230 | } | 346 | } |
231 | 347 | ||
348 | /* Note callers must have acquired the PUNIT->PMIC bus, before calling this. */ | ||
232 | static void intel_uncore_forcewake_reset(struct drm_i915_private *dev_priv, | 349 | static void intel_uncore_forcewake_reset(struct drm_i915_private *dev_priv, |
233 | bool restore) | 350 | bool restore) |
234 | { | 351 | { |
@@ -237,6 +354,8 @@ static void intel_uncore_forcewake_reset(struct drm_i915_private *dev_priv, | |||
237 | int retry_count = 100; | 354 | int retry_count = 100; |
238 | enum forcewake_domains fw, active_domains; | 355 | enum forcewake_domains fw, active_domains; |
239 | 356 | ||
357 | iosf_mbi_assert_punit_acquired(); | ||
358 | |||
240 | /* Hold uncore.lock across reset to prevent any register access | 359 | /* Hold uncore.lock across reset to prevent any register access |
241 | * with forcewake not set correctly. Wait until all pending | 360 | * with forcewake not set correctly. Wait until all pending |
242 | * timers are run before holding. | 361 | * timers are run before holding. |
@@ -416,14 +535,18 @@ static void __intel_uncore_early_sanitize(struct drm_i915_private *dev_priv, | |||
416 | GT_FIFO_CTL_RC6_POLICY_STALL); | 535 | GT_FIFO_CTL_RC6_POLICY_STALL); |
417 | } | 536 | } |
418 | 537 | ||
538 | iosf_mbi_punit_acquire(); | ||
419 | intel_uncore_forcewake_reset(dev_priv, restore_forcewake); | 539 | intel_uncore_forcewake_reset(dev_priv, restore_forcewake); |
540 | iosf_mbi_punit_release(); | ||
420 | } | 541 | } |
421 | 542 | ||
422 | void intel_uncore_suspend(struct drm_i915_private *dev_priv) | 543 | void intel_uncore_suspend(struct drm_i915_private *dev_priv) |
423 | { | 544 | { |
424 | iosf_mbi_unregister_pmic_bus_access_notifier( | 545 | iosf_mbi_punit_acquire(); |
546 | iosf_mbi_unregister_pmic_bus_access_notifier_unlocked( | ||
425 | &dev_priv->uncore.pmic_bus_access_nb); | 547 | &dev_priv->uncore.pmic_bus_access_nb); |
426 | intel_uncore_forcewake_reset(dev_priv, false); | 548 | intel_uncore_forcewake_reset(dev_priv, false); |
549 | iosf_mbi_punit_release(); | ||
427 | } | 550 | } |
428 | 551 | ||
429 | void intel_uncore_resume_early(struct drm_i915_private *dev_priv) | 552 | void intel_uncore_resume_early(struct drm_i915_private *dev_priv) |
@@ -1148,7 +1271,8 @@ static void intel_uncore_fw_domains_init(struct drm_i915_private *dev_priv) | |||
1148 | } | 1271 | } |
1149 | 1272 | ||
1150 | if (INTEL_GEN(dev_priv) >= 9) { | 1273 | if (INTEL_GEN(dev_priv) >= 9) { |
1151 | dev_priv->uncore.funcs.force_wake_get = fw_domains_get; | 1274 | dev_priv->uncore.funcs.force_wake_get = |
1275 | fw_domains_get_with_fallback; | ||
1152 | dev_priv->uncore.funcs.force_wake_put = fw_domains_put; | 1276 | dev_priv->uncore.funcs.force_wake_put = fw_domains_put; |
1153 | fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER, | 1277 | fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER, |
1154 | FORCEWAKE_RENDER_GEN9, | 1278 | FORCEWAKE_RENDER_GEN9, |
@@ -1309,18 +1433,18 @@ void intel_uncore_init(struct drm_i915_private *dev_priv) | |||
1309 | 1433 | ||
1310 | iosf_mbi_register_pmic_bus_access_notifier( | 1434 | iosf_mbi_register_pmic_bus_access_notifier( |
1311 | &dev_priv->uncore.pmic_bus_access_nb); | 1435 | &dev_priv->uncore.pmic_bus_access_nb); |
1312 | |||
1313 | i915_check_and_clear_faults(dev_priv); | ||
1314 | } | 1436 | } |
1315 | 1437 | ||
1316 | void intel_uncore_fini(struct drm_i915_private *dev_priv) | 1438 | void intel_uncore_fini(struct drm_i915_private *dev_priv) |
1317 | { | 1439 | { |
1318 | iosf_mbi_unregister_pmic_bus_access_notifier( | ||
1319 | &dev_priv->uncore.pmic_bus_access_nb); | ||
1320 | |||
1321 | /* Paranoia: make sure we have disabled everything before we exit. */ | 1440 | /* Paranoia: make sure we have disabled everything before we exit. */ |
1322 | intel_uncore_sanitize(dev_priv); | 1441 | intel_uncore_sanitize(dev_priv); |
1442 | |||
1443 | iosf_mbi_punit_acquire(); | ||
1444 | iosf_mbi_unregister_pmic_bus_access_notifier_unlocked( | ||
1445 | &dev_priv->uncore.pmic_bus_access_nb); | ||
1323 | intel_uncore_forcewake_reset(dev_priv, false); | 1446 | intel_uncore_forcewake_reset(dev_priv, false); |
1447 | iosf_mbi_punit_release(); | ||
1324 | } | 1448 | } |
1325 | 1449 | ||
1326 | static const struct reg_whitelist { | 1450 | static const struct reg_whitelist { |
@@ -1400,10 +1524,14 @@ static void gen3_stop_engine(struct intel_engine_cs *engine) | |||
1400 | DRM_DEBUG_DRIVER("%s: timed out on STOP_RING\n", | 1524 | DRM_DEBUG_DRIVER("%s: timed out on STOP_RING\n", |
1401 | engine->name); | 1525 | engine->name); |
1402 | 1526 | ||
1403 | I915_WRITE_FW(RING_CTL(base), 0); | 1527 | I915_WRITE_FW(RING_HEAD(base), I915_READ_FW(RING_TAIL(base))); |
1528 | |||
1404 | I915_WRITE_FW(RING_HEAD(base), 0); | 1529 | I915_WRITE_FW(RING_HEAD(base), 0); |
1405 | I915_WRITE_FW(RING_TAIL(base), 0); | 1530 | I915_WRITE_FW(RING_TAIL(base), 0); |
1406 | 1531 | ||
1532 | /* The ring must be empty before it is disabled */ | ||
1533 | I915_WRITE_FW(RING_CTL(base), 0); | ||
1534 | |||
1407 | /* Check acts as a post */ | 1535 | /* Check acts as a post */ |
1408 | if (I915_READ_FW(RING_HEAD(base)) != 0) | 1536 | if (I915_READ_FW(RING_HEAD(base)) != 0) |
1409 | DRM_DEBUG_DRIVER("%s: ring head not parked\n", | 1537 | DRM_DEBUG_DRIVER("%s: ring head not parked\n", |
@@ -1801,18 +1929,13 @@ bool intel_has_gpu_reset(struct drm_i915_private *dev_priv) | |||
1801 | return intel_get_gpu_reset(dev_priv) != NULL; | 1929 | return intel_get_gpu_reset(dev_priv) != NULL; |
1802 | } | 1930 | } |
1803 | 1931 | ||
1804 | /* | ||
1805 | * When GuC submission is enabled, GuC manages ELSP and can initiate the | ||
1806 | * engine reset too. For now, fall back to full GPU reset if it is enabled. | ||
1807 | */ | ||
1808 | bool intel_has_reset_engine(struct drm_i915_private *dev_priv) | 1932 | bool intel_has_reset_engine(struct drm_i915_private *dev_priv) |
1809 | { | 1933 | { |
1810 | return (dev_priv->info.has_reset_engine && | 1934 | return (dev_priv->info.has_reset_engine && |
1811 | !dev_priv->guc.execbuf_client && | ||
1812 | i915_modparams.reset >= 2); | 1935 | i915_modparams.reset >= 2); |
1813 | } | 1936 | } |
1814 | 1937 | ||
1815 | int intel_guc_reset(struct drm_i915_private *dev_priv) | 1938 | int intel_reset_guc(struct drm_i915_private *dev_priv) |
1816 | { | 1939 | { |
1817 | int ret; | 1940 | int ret; |
1818 | 1941 | ||
diff --git a/drivers/gpu/drm/i915/intel_vbt_defs.h b/drivers/gpu/drm/i915/intel_vbt_defs.h index f225c288a121..e3d7745a9151 100644 --- a/drivers/gpu/drm/i915/intel_vbt_defs.h +++ b/drivers/gpu/drm/i915/intel_vbt_defs.h | |||
@@ -304,6 +304,10 @@ struct bdb_general_features { | |||
304 | #define DVO_PORT_MIPIC 23 /* 171 */ | 304 | #define DVO_PORT_MIPIC 23 /* 171 */ |
305 | #define DVO_PORT_MIPID 24 /* 171 */ | 305 | #define DVO_PORT_MIPID 24 /* 171 */ |
306 | 306 | ||
307 | #define HDMI_MAX_DATA_RATE_PLATFORM 0 /* 204 */ | ||
308 | #define HDMI_MAX_DATA_RATE_297 1 /* 204 */ | ||
309 | #define HDMI_MAX_DATA_RATE_165 2 /* 204 */ | ||
310 | |||
307 | #define LEGACY_CHILD_DEVICE_CONFIG_SIZE 33 | 311 | #define LEGACY_CHILD_DEVICE_CONFIG_SIZE 33 |
308 | 312 | ||
309 | /* DDC Bus DDI Type 155+ */ | 313 | /* DDC Bus DDI Type 155+ */ |
@@ -342,8 +346,8 @@ struct child_device_config { | |||
342 | u8 i2c_speed; | 346 | u8 i2c_speed; |
343 | u8 dp_onboard_redriver; /* 158 */ | 347 | u8 dp_onboard_redriver; /* 158 */ |
344 | u8 dp_ondock_redriver; /* 158 */ | 348 | u8 dp_ondock_redriver; /* 158 */ |
345 | u8 hdmi_level_shifter_value:4; /* 169 */ | 349 | u8 hdmi_level_shifter_value:5; /* 169 */ |
346 | u8 hdmi_max_data_rate:4; /* 204 */ | 350 | u8 hdmi_max_data_rate:3; /* 204 */ |
347 | u16 dtd_buf_ptr; /* 161 */ | 351 | u16 dtd_buf_ptr; /* 161 */ |
348 | u8 edidless_efp:1; /* 161 */ | 352 | u8 edidless_efp:1; /* 161 */ |
349 | u8 compression_enable:1; /* 198 */ | 353 | u8 compression_enable:1; /* 198 */ |
diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c index 5cc8101bb2b1..01af540b6ef9 100644 --- a/drivers/gpu/drm/i915/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/selftests/huge_pages.c | |||
@@ -1159,6 +1159,9 @@ static int igt_ppgtt_exhaust_huge(void *arg) | |||
1159 | int n, i; | 1159 | int n, i; |
1160 | int err = -ENODEV; | 1160 | int err = -ENODEV; |
1161 | 1161 | ||
1162 | if (supported == I915_GTT_PAGE_SIZE_4K) | ||
1163 | return 0; | ||
1164 | |||
1162 | /* | 1165 | /* |
1163 | * Sanity check creating objects with a varying mix of page sizes -- | 1166 | * Sanity check creating objects with a varying mix of page sizes -- |
1164 | * ensuring that our writes lands in the right place. | 1167 | * ensuring that our writes lands in the right place. |
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c b/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c index 35d778d70626..7a0d1e17c1ad 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c | |||
@@ -33,7 +33,7 @@ static int cpu_set(struct drm_i915_gem_object *obj, | |||
33 | { | 33 | { |
34 | unsigned int needs_clflush; | 34 | unsigned int needs_clflush; |
35 | struct page *page; | 35 | struct page *page; |
36 | typeof(v) *map; | 36 | u32 *map; |
37 | int err; | 37 | int err; |
38 | 38 | ||
39 | err = i915_gem_obj_prepare_shmem_write(obj, &needs_clflush); | 39 | err = i915_gem_obj_prepare_shmem_write(obj, &needs_clflush); |
@@ -59,7 +59,7 @@ static int cpu_get(struct drm_i915_gem_object *obj, | |||
59 | { | 59 | { |
60 | unsigned int needs_clflush; | 60 | unsigned int needs_clflush; |
61 | struct page *page; | 61 | struct page *page; |
62 | typeof(v) map; | 62 | u32 *map; |
63 | int err; | 63 | int err; |
64 | 64 | ||
65 | err = i915_gem_obj_prepare_shmem_read(obj, &needs_clflush); | 65 | err = i915_gem_obj_prepare_shmem_read(obj, &needs_clflush); |
@@ -82,7 +82,7 @@ static int gtt_set(struct drm_i915_gem_object *obj, | |||
82 | u32 v) | 82 | u32 v) |
83 | { | 83 | { |
84 | struct i915_vma *vma; | 84 | struct i915_vma *vma; |
85 | typeof(v) *map; | 85 | u32 __iomem *map; |
86 | int err; | 86 | int err; |
87 | 87 | ||
88 | err = i915_gem_object_set_to_gtt_domain(obj, true); | 88 | err = i915_gem_object_set_to_gtt_domain(obj, true); |
@@ -98,7 +98,7 @@ static int gtt_set(struct drm_i915_gem_object *obj, | |||
98 | if (IS_ERR(map)) | 98 | if (IS_ERR(map)) |
99 | return PTR_ERR(map); | 99 | return PTR_ERR(map); |
100 | 100 | ||
101 | map[offset / sizeof(*map)] = v; | 101 | iowrite32(v, &map[offset / sizeof(*map)]); |
102 | i915_vma_unpin_iomap(vma); | 102 | i915_vma_unpin_iomap(vma); |
103 | 103 | ||
104 | return 0; | 104 | return 0; |
@@ -109,7 +109,7 @@ static int gtt_get(struct drm_i915_gem_object *obj, | |||
109 | u32 *v) | 109 | u32 *v) |
110 | { | 110 | { |
111 | struct i915_vma *vma; | 111 | struct i915_vma *vma; |
112 | typeof(v) map; | 112 | u32 __iomem *map; |
113 | int err; | 113 | int err; |
114 | 114 | ||
115 | err = i915_gem_object_set_to_gtt_domain(obj, false); | 115 | err = i915_gem_object_set_to_gtt_domain(obj, false); |
@@ -125,7 +125,7 @@ static int gtt_get(struct drm_i915_gem_object *obj, | |||
125 | if (IS_ERR(map)) | 125 | if (IS_ERR(map)) |
126 | return PTR_ERR(map); | 126 | return PTR_ERR(map); |
127 | 127 | ||
128 | *v = map[offset / sizeof(*map)]; | 128 | *v = ioread32(&map[offset / sizeof(*map)]); |
129 | i915_vma_unpin_iomap(vma); | 129 | i915_vma_unpin_iomap(vma); |
130 | 130 | ||
131 | return 0; | 131 | return 0; |
@@ -135,7 +135,7 @@ static int wc_set(struct drm_i915_gem_object *obj, | |||
135 | unsigned long offset, | 135 | unsigned long offset, |
136 | u32 v) | 136 | u32 v) |
137 | { | 137 | { |
138 | typeof(v) *map; | 138 | u32 *map; |
139 | int err; | 139 | int err; |
140 | 140 | ||
141 | err = i915_gem_object_set_to_wc_domain(obj, true); | 141 | err = i915_gem_object_set_to_wc_domain(obj, true); |
@@ -156,7 +156,7 @@ static int wc_get(struct drm_i915_gem_object *obj, | |||
156 | unsigned long offset, | 156 | unsigned long offset, |
157 | u32 *v) | 157 | u32 *v) |
158 | { | 158 | { |
159 | typeof(v) map; | 159 | u32 *map; |
160 | int err; | 160 | int err; |
161 | 161 | ||
162 | err = i915_gem_object_set_to_wc_domain(obj, false); | 162 | err = i915_gem_object_set_to_wc_domain(obj, false); |
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/selftests/i915_gem_context.c index def5052862ae..c82780a9d455 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_context.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_context.c | |||
@@ -325,7 +325,7 @@ static int igt_ctx_exec(void *arg) | |||
325 | LIST_HEAD(objects); | 325 | LIST_HEAD(objects); |
326 | unsigned long ncontexts, ndwords, dw; | 326 | unsigned long ncontexts, ndwords, dw; |
327 | bool first_shared_gtt = true; | 327 | bool first_shared_gtt = true; |
328 | int err; | 328 | int err = -ENODEV; |
329 | 329 | ||
330 | /* Create a few different contexts (with different mm) and write | 330 | /* Create a few different contexts (with different mm) and write |
331 | * through each ctx/mm using the GPU making sure those writes end | 331 | * through each ctx/mm using the GPU making sure those writes end |
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c index 9da0c9f99916..6491cf0a4f46 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | |||
@@ -216,13 +216,21 @@ static int lowlevel_hole(struct drm_i915_private *i915, | |||
216 | hole_size = (hole_end - hole_start) >> size; | 216 | hole_size = (hole_end - hole_start) >> size; |
217 | if (hole_size > KMALLOC_MAX_SIZE / sizeof(u32)) | 217 | if (hole_size > KMALLOC_MAX_SIZE / sizeof(u32)) |
218 | hole_size = KMALLOC_MAX_SIZE / sizeof(u32); | 218 | hole_size = KMALLOC_MAX_SIZE / sizeof(u32); |
219 | count = hole_size; | 219 | count = hole_size >> 1; |
220 | if (!count) { | ||
221 | pr_debug("%s: hole is too small [%llx - %llx] >> %d: %lld\n", | ||
222 | __func__, hole_start, hole_end, size, hole_size); | ||
223 | break; | ||
224 | } | ||
225 | |||
220 | do { | 226 | do { |
221 | count >>= 1; | ||
222 | order = i915_random_order(count, &prng); | 227 | order = i915_random_order(count, &prng); |
223 | } while (!order && count); | 228 | if (order) |
224 | if (!order) | 229 | break; |
225 | break; | 230 | } while (count >>= 1); |
231 | if (!count) | ||
232 | return -ENOMEM; | ||
233 | GEM_BUG_ON(!order); | ||
226 | 234 | ||
227 | GEM_BUG_ON(count * BIT_ULL(size) > vm->total); | 235 | GEM_BUG_ON(count * BIT_ULL(size) > vm->total); |
228 | GEM_BUG_ON(hole_start + count * BIT_ULL(size) > hole_end); | 236 | GEM_BUG_ON(hole_start + count * BIT_ULL(size) > hole_end); |
@@ -267,7 +275,9 @@ static int lowlevel_hole(struct drm_i915_private *i915, | |||
267 | mock_vma.node.size = BIT_ULL(size); | 275 | mock_vma.node.size = BIT_ULL(size); |
268 | mock_vma.node.start = addr; | 276 | mock_vma.node.start = addr; |
269 | 277 | ||
278 | intel_runtime_pm_get(i915); | ||
270 | vm->insert_entries(vm, &mock_vma, I915_CACHE_NONE, 0); | 279 | vm->insert_entries(vm, &mock_vma, I915_CACHE_NONE, 0); |
280 | intel_runtime_pm_put(i915); | ||
271 | } | 281 | } |
272 | count = n; | 282 | count = n; |
273 | 283 | ||
@@ -697,18 +707,26 @@ static int drunk_hole(struct drm_i915_private *i915, | |||
697 | unsigned int *order, count, n; | 707 | unsigned int *order, count, n; |
698 | struct i915_vma *vma; | 708 | struct i915_vma *vma; |
699 | u64 hole_size; | 709 | u64 hole_size; |
700 | int err; | 710 | int err = -ENODEV; |
701 | 711 | ||
702 | hole_size = (hole_end - hole_start) >> size; | 712 | hole_size = (hole_end - hole_start) >> size; |
703 | if (hole_size > KMALLOC_MAX_SIZE / sizeof(u32)) | 713 | if (hole_size > KMALLOC_MAX_SIZE / sizeof(u32)) |
704 | hole_size = KMALLOC_MAX_SIZE / sizeof(u32); | 714 | hole_size = KMALLOC_MAX_SIZE / sizeof(u32); |
705 | count = hole_size; | 715 | count = hole_size >> 1; |
716 | if (!count) { | ||
717 | pr_debug("%s: hole is too small [%llx - %llx] >> %d: %lld\n", | ||
718 | __func__, hole_start, hole_end, size, hole_size); | ||
719 | break; | ||
720 | } | ||
721 | |||
706 | do { | 722 | do { |
707 | count >>= 1; | ||
708 | order = i915_random_order(count, &prng); | 723 | order = i915_random_order(count, &prng); |
709 | } while (!order && count); | 724 | if (order) |
710 | if (!order) | 725 | break; |
711 | break; | 726 | } while (count >>= 1); |
727 | if (!count) | ||
728 | return -ENOMEM; | ||
729 | GEM_BUG_ON(!order); | ||
712 | 730 | ||
713 | /* Ignore allocation failures (i.e. don't report them as | 731 | /* Ignore allocation failures (i.e. don't report them as |
714 | * a test failure) as we are purposefully allocating very | 732 | * a test failure) as we are purposefully allocating very |
@@ -956,7 +974,7 @@ static int exercise_ggtt(struct drm_i915_private *i915, | |||
956 | u64 hole_start, hole_end, last = 0; | 974 | u64 hole_start, hole_end, last = 0; |
957 | struct drm_mm_node *node; | 975 | struct drm_mm_node *node; |
958 | IGT_TIMEOUT(end_time); | 976 | IGT_TIMEOUT(end_time); |
959 | int err; | 977 | int err = 0; |
960 | 978 | ||
961 | mutex_lock(&i915->drm.struct_mutex); | 979 | mutex_lock(&i915->drm.struct_mutex); |
962 | restart: | 980 | restart: |
@@ -1047,6 +1065,7 @@ static int igt_ggtt_page(void *arg) | |||
1047 | goto out_remove; | 1065 | goto out_remove; |
1048 | } | 1066 | } |
1049 | 1067 | ||
1068 | intel_runtime_pm_get(i915); | ||
1050 | for (n = 0; n < count; n++) { | 1069 | for (n = 0; n < count; n++) { |
1051 | u64 offset = tmp.start + order[n] * PAGE_SIZE; | 1070 | u64 offset = tmp.start + order[n] * PAGE_SIZE; |
1052 | u32 __iomem *vaddr; | 1071 | u32 __iomem *vaddr; |
@@ -1086,6 +1105,7 @@ static int igt_ggtt_page(void *arg) | |||
1086 | break; | 1105 | break; |
1087 | } | 1106 | } |
1088 | } | 1107 | } |
1108 | intel_runtime_pm_put(i915); | ||
1089 | 1109 | ||
1090 | kfree(order); | 1110 | kfree(order); |
1091 | out_remove: | 1111 | out_remove: |
@@ -1160,7 +1180,7 @@ static int igt_gtt_reserve(void *arg) | |||
1160 | struct drm_i915_gem_object *obj, *on; | 1180 | struct drm_i915_gem_object *obj, *on; |
1161 | LIST_HEAD(objects); | 1181 | LIST_HEAD(objects); |
1162 | u64 total; | 1182 | u64 total; |
1163 | int err; | 1183 | int err = -ENODEV; |
1164 | 1184 | ||
1165 | /* i915_gem_gtt_reserve() tries to reserve the precise range | 1185 | /* i915_gem_gtt_reserve() tries to reserve the precise range |
1166 | * for the node, and evicts if it has to. So our test checks that | 1186 | * for the node, and evicts if it has to. So our test checks that |
@@ -1351,7 +1371,7 @@ static int igt_gtt_insert(void *arg) | |||
1351 | }, *ii; | 1371 | }, *ii; |
1352 | LIST_HEAD(objects); | 1372 | LIST_HEAD(objects); |
1353 | u64 total; | 1373 | u64 total; |
1354 | int err; | 1374 | int err = -ENODEV; |
1355 | 1375 | ||
1356 | /* i915_gem_gtt_insert() tries to allocate some free space in the GTT | 1376 | /* i915_gem_gtt_insert() tries to allocate some free space in the GTT |
1357 | * to the node, evicting if required. | 1377 | * to the node, evicting if required. |
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_object.c b/drivers/gpu/drm/i915/selftests/i915_gem_object.c index 1b8774a42e48..f32aa6bb79e2 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_object.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_object.c | |||
@@ -317,6 +317,7 @@ static int igt_partial_tiling(void *arg) | |||
317 | } | 317 | } |
318 | 318 | ||
319 | mutex_lock(&i915->drm.struct_mutex); | 319 | mutex_lock(&i915->drm.struct_mutex); |
320 | intel_runtime_pm_get(i915); | ||
320 | 321 | ||
321 | if (1) { | 322 | if (1) { |
322 | IGT_TIMEOUT(end); | 323 | IGT_TIMEOUT(end); |
@@ -418,6 +419,7 @@ next_tiling: ; | |||
418 | } | 419 | } |
419 | 420 | ||
420 | out_unlock: | 421 | out_unlock: |
422 | intel_runtime_pm_put(i915); | ||
421 | mutex_unlock(&i915->drm.struct_mutex); | 423 | mutex_unlock(&i915->drm.struct_mutex); |
422 | i915_gem_object_unpin_pages(obj); | 424 | i915_gem_object_unpin_pages(obj); |
423 | out: | 425 | out: |
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_request.c b/drivers/gpu/drm/i915/selftests/i915_gem_request.c index a999161e8db1..6bce99050e94 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_request.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_request.c | |||
@@ -332,7 +332,7 @@ static int live_nop_request(void *arg) | |||
332 | struct intel_engine_cs *engine; | 332 | struct intel_engine_cs *engine; |
333 | struct live_test t; | 333 | struct live_test t; |
334 | unsigned int id; | 334 | unsigned int id; |
335 | int err; | 335 | int err = -ENODEV; |
336 | 336 | ||
337 | /* Submit various sized batches of empty requests, to each engine | 337 | /* Submit various sized batches of empty requests, to each engine |
338 | * (individually), and wait for the batch to complete. We can check | 338 | * (individually), and wait for the batch to complete. We can check |
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c index 4795877abe56..3000e6a7d82d 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c | |||
@@ -79,7 +79,7 @@ static int igt_sync(void *arg) | |||
79 | }, *p; | 79 | }, *p; |
80 | struct intel_timeline *tl; | 80 | struct intel_timeline *tl; |
81 | int order, offset; | 81 | int order, offset; |
82 | int ret; | 82 | int ret = -ENODEV; |
83 | 83 | ||
84 | tl = mock_timeline(0); | 84 | tl = mock_timeline(0); |
85 | if (!tl) | 85 | if (!tl) |
diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h index d7dd98a6acad..088f45bc6199 100644 --- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h +++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h | |||
@@ -20,3 +20,4 @@ selftest(evict, i915_gem_evict_live_selftests) | |||
20 | selftest(hugepages, i915_gem_huge_page_live_selftests) | 20 | selftest(hugepages, i915_gem_huge_page_live_selftests) |
21 | selftest(contexts, i915_gem_context_live_selftests) | 21 | selftest(contexts, i915_gem_context_live_selftests) |
22 | selftest(hangcheck, intel_hangcheck_live_selftests) | 22 | selftest(hangcheck, intel_hangcheck_live_selftests) |
23 | selftest(guc, intel_guc_live_selftest) | ||
diff --git a/drivers/gpu/drm/i915/selftests/i915_syncmap.c b/drivers/gpu/drm/i915/selftests/i915_syncmap.c index bcab3d00a785..47f4ae18a1ef 100644 --- a/drivers/gpu/drm/i915/selftests/i915_syncmap.c +++ b/drivers/gpu/drm/i915/selftests/i915_syncmap.c | |||
@@ -333,7 +333,7 @@ static int igt_syncmap_join_below(void *arg) | |||
333 | { | 333 | { |
334 | struct i915_syncmap *sync; | 334 | struct i915_syncmap *sync; |
335 | unsigned int step, order, idx; | 335 | unsigned int step, order, idx; |
336 | int err; | 336 | int err = -ENODEV; |
337 | 337 | ||
338 | i915_syncmap_init(&sync); | 338 | i915_syncmap_init(&sync); |
339 | 339 | ||
@@ -402,7 +402,7 @@ static int igt_syncmap_neighbours(void *arg) | |||
402 | I915_RND_STATE(prng); | 402 | I915_RND_STATE(prng); |
403 | IGT_TIMEOUT(end_time); | 403 | IGT_TIMEOUT(end_time); |
404 | struct i915_syncmap *sync; | 404 | struct i915_syncmap *sync; |
405 | int err; | 405 | int err = -ENODEV; |
406 | 406 | ||
407 | /* | 407 | /* |
408 | * Each leaf holds KSYNCMAP seqno. Check that when we create KSYNCMAP | 408 | * Each leaf holds KSYNCMAP seqno. Check that when we create KSYNCMAP |
@@ -447,7 +447,7 @@ static int igt_syncmap_compact(void *arg) | |||
447 | { | 447 | { |
448 | struct i915_syncmap *sync; | 448 | struct i915_syncmap *sync; |
449 | unsigned int idx, order; | 449 | unsigned int idx, order; |
450 | int err; | 450 | int err = -ENODEV; |
451 | 451 | ||
452 | i915_syncmap_init(&sync); | 452 | i915_syncmap_init(&sync); |
453 | 453 | ||
diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c index 2e86ec136b35..eb89e301b602 100644 --- a/drivers/gpu/drm/i915/selftests/i915_vma.c +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c | |||
@@ -150,7 +150,7 @@ static int igt_vma_create(void *arg) | |||
150 | IGT_TIMEOUT(end_time); | 150 | IGT_TIMEOUT(end_time); |
151 | LIST_HEAD(contexts); | 151 | LIST_HEAD(contexts); |
152 | LIST_HEAD(objects); | 152 | LIST_HEAD(objects); |
153 | int err; | 153 | int err = -ENOMEM; |
154 | 154 | ||
155 | /* Exercise creating many vma amonst many objections, checking the | 155 | /* Exercise creating many vma amonst many objections, checking the |
156 | * vma creation and lookup routines. | 156 | * vma creation and lookup routines. |
diff --git a/drivers/gpu/drm/i915/selftests/intel_guc.c b/drivers/gpu/drm/i915/selftests/intel_guc.c new file mode 100644 index 000000000000..f10029e18820 --- /dev/null +++ b/drivers/gpu/drm/i915/selftests/intel_guc.c | |||
@@ -0,0 +1,367 @@ | |||
1 | /* | ||
2 | * Copyright © 2017 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_selftest.h" | ||
26 | |||
27 | /* max doorbell number + negative test for each client type */ | ||
28 | #define ATTEMPTS (GUC_NUM_DOORBELLS + GUC_CLIENT_PRIORITY_NUM) | ||
29 | |||
30 | struct intel_guc_client *clients[ATTEMPTS]; | ||
31 | |||
32 | static bool available_dbs(struct intel_guc *guc, u32 priority) | ||
33 | { | ||
34 | unsigned long offset; | ||
35 | unsigned long end; | ||
36 | u16 id; | ||
37 | |||
38 | /* first half is used for normal priority, second half for high */ | ||
39 | offset = 0; | ||
40 | end = GUC_NUM_DOORBELLS / 2; | ||
41 | if (priority <= GUC_CLIENT_PRIORITY_HIGH) { | ||
42 | offset = end; | ||
43 | end += offset; | ||
44 | } | ||
45 | |||
46 | id = find_next_zero_bit(guc->doorbell_bitmap, end, offset); | ||
47 | if (id < end) | ||
48 | return true; | ||
49 | |||
50 | return false; | ||
51 | } | ||
52 | |||
53 | static int check_all_doorbells(struct intel_guc *guc) | ||
54 | { | ||
55 | u16 db_id; | ||
56 | |||
57 | pr_info_once("Max number of doorbells: %d", GUC_NUM_DOORBELLS); | ||
58 | for (db_id = 0; db_id < GUC_NUM_DOORBELLS; ++db_id) { | ||
59 | if (!doorbell_ok(guc, db_id)) { | ||
60 | pr_err("doorbell %d, not ok\n", db_id); | ||
61 | return -EIO; | ||
62 | } | ||
63 | } | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | /* | ||
69 | * Basic client sanity check, handy to validate create_clients. | ||
70 | */ | ||
71 | static int validate_client(struct intel_guc_client *client, | ||
72 | int client_priority, | ||
73 | bool is_preempt_client) | ||
74 | { | ||
75 | struct drm_i915_private *dev_priv = guc_to_i915(client->guc); | ||
76 | struct i915_gem_context *ctx_owner = is_preempt_client ? | ||
77 | dev_priv->preempt_context : dev_priv->kernel_context; | ||
78 | |||
79 | if (client->owner != ctx_owner || | ||
80 | client->engines != INTEL_INFO(dev_priv)->ring_mask || | ||
81 | client->priority != client_priority || | ||
82 | client->doorbell_id == GUC_DOORBELL_INVALID) | ||
83 | return -EINVAL; | ||
84 | else | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | /* | ||
89 | * Check that guc_init_doorbell_hw is doing what it should. | ||
90 | * | ||
91 | * During GuC submission enable, we create GuC clients and their doorbells, | ||
92 | * but after resetting the microcontroller (resume & gpu reset), these | ||
93 | * GuC clients are still around, but the status of their doorbells may be | ||
94 | * incorrect. This is the reason behind validating that the doorbells status | ||
95 | * expected by the driver matches what the GuC/HW have. | ||
96 | */ | ||
97 | static int igt_guc_init_doorbell_hw(void *args) | ||
98 | { | ||
99 | struct drm_i915_private *dev_priv = args; | ||
100 | struct intel_guc *guc; | ||
101 | DECLARE_BITMAP(db_bitmap_bk, GUC_NUM_DOORBELLS); | ||
102 | int i, err = 0; | ||
103 | |||
104 | GEM_BUG_ON(!HAS_GUC(dev_priv)); | ||
105 | mutex_lock(&dev_priv->drm.struct_mutex); | ||
106 | |||
107 | guc = &dev_priv->guc; | ||
108 | if (!guc) { | ||
109 | pr_err("No guc object!\n"); | ||
110 | err = -EINVAL; | ||
111 | goto unlock; | ||
112 | } | ||
113 | |||
114 | err = check_all_doorbells(guc); | ||
115 | if (err) | ||
116 | goto unlock; | ||
117 | |||
118 | /* | ||
119 | * Get rid of clients created during driver load because the test will | ||
120 | * recreate them. | ||
121 | */ | ||
122 | guc_clients_destroy(guc); | ||
123 | if (guc->execbuf_client || guc->preempt_client) { | ||
124 | pr_err("guc_clients_destroy lied!\n"); | ||
125 | err = -EINVAL; | ||
126 | goto unlock; | ||
127 | } | ||
128 | |||
129 | err = guc_clients_create(guc); | ||
130 | if (err) { | ||
131 | pr_err("Failed to create clients\n"); | ||
132 | goto unlock; | ||
133 | } | ||
134 | |||
135 | err = validate_client(guc->execbuf_client, | ||
136 | GUC_CLIENT_PRIORITY_KMD_NORMAL, false); | ||
137 | if (err) { | ||
138 | pr_err("execbug client validation failed\n"); | ||
139 | goto out; | ||
140 | } | ||
141 | |||
142 | err = validate_client(guc->preempt_client, | ||
143 | GUC_CLIENT_PRIORITY_KMD_HIGH, true); | ||
144 | if (err) { | ||
145 | pr_err("preempt client validation failed\n"); | ||
146 | goto out; | ||
147 | } | ||
148 | |||
149 | /* each client should have received a doorbell during alloc */ | ||
150 | if (!has_doorbell(guc->execbuf_client) || | ||
151 | !has_doorbell(guc->preempt_client)) { | ||
152 | pr_err("guc_clients_create didn't create doorbells\n"); | ||
153 | err = -EINVAL; | ||
154 | goto out; | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * Basic test - an attempt to reallocate a valid doorbell to the | ||
159 | * client it is currently assigned should not cause a failure. | ||
160 | */ | ||
161 | err = guc_init_doorbell_hw(guc); | ||
162 | if (err) | ||
163 | goto out; | ||
164 | |||
165 | /* | ||
166 | * Negative test - a client with no doorbell (invalid db id). | ||
167 | * Each client gets a doorbell when it is created, after destroying | ||
168 | * the doorbell, the db id is changed to GUC_DOORBELL_INVALID and the | ||
169 | * firmware will reject any attempt to allocate a doorbell with an | ||
170 | * invalid id (db has to be reserved before allocation). | ||
171 | */ | ||
172 | destroy_doorbell(guc->execbuf_client); | ||
173 | if (has_doorbell(guc->execbuf_client)) { | ||
174 | pr_err("destroy db did not work\n"); | ||
175 | err = -EINVAL; | ||
176 | goto out; | ||
177 | } | ||
178 | |||
179 | err = guc_init_doorbell_hw(guc); | ||
180 | if (err != -EIO) { | ||
181 | pr_err("unexpected (err = %d)", err); | ||
182 | goto out; | ||
183 | } | ||
184 | |||
185 | if (!available_dbs(guc, guc->execbuf_client->priority)) { | ||
186 | pr_err("doorbell not available when it should\n"); | ||
187 | err = -EIO; | ||
188 | goto out; | ||
189 | } | ||
190 | |||
191 | /* clean after test */ | ||
192 | err = create_doorbell(guc->execbuf_client); | ||
193 | if (err) { | ||
194 | pr_err("recreate doorbell failed\n"); | ||
195 | goto out; | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * Negative test - doorbell_bitmap out of sync, will trigger a few of | ||
200 | * WARN_ON(!doorbell_ok(guc, db_id)) but that's ok as long as the | ||
201 | * doorbells from our clients don't fail. | ||
202 | */ | ||
203 | bitmap_copy(db_bitmap_bk, guc->doorbell_bitmap, GUC_NUM_DOORBELLS); | ||
204 | for (i = 0; i < GUC_NUM_DOORBELLS; i++) | ||
205 | if (i % 2) | ||
206 | test_and_change_bit(i, guc->doorbell_bitmap); | ||
207 | |||
208 | err = guc_init_doorbell_hw(guc); | ||
209 | if (err) { | ||
210 | pr_err("out of sync doorbell caused an error\n"); | ||
211 | goto out; | ||
212 | } | ||
213 | |||
214 | /* restore 'correct' db bitmap */ | ||
215 | bitmap_copy(guc->doorbell_bitmap, db_bitmap_bk, GUC_NUM_DOORBELLS); | ||
216 | err = guc_init_doorbell_hw(guc); | ||
217 | if (err) { | ||
218 | pr_err("restored doorbell caused an error\n"); | ||
219 | goto out; | ||
220 | } | ||
221 | |||
222 | out: | ||
223 | /* | ||
224 | * Leave clean state for other test, plus the driver always destroy the | ||
225 | * clients during unload. | ||
226 | */ | ||
227 | guc_clients_destroy(guc); | ||
228 | guc_clients_create(guc); | ||
229 | unlock: | ||
230 | mutex_unlock(&dev_priv->drm.struct_mutex); | ||
231 | return err; | ||
232 | } | ||
233 | |||
234 | /* | ||
235 | * Create as many clients as number of doorbells. Note that there's already | ||
236 | * client(s)/doorbell(s) created during driver load, but this test creates | ||
237 | * its own and do not interact with the existing ones. | ||
238 | */ | ||
239 | static int igt_guc_doorbells(void *arg) | ||
240 | { | ||
241 | struct drm_i915_private *dev_priv = arg; | ||
242 | struct intel_guc *guc; | ||
243 | int i, err = 0; | ||
244 | u16 db_id; | ||
245 | |||
246 | GEM_BUG_ON(!HAS_GUC(dev_priv)); | ||
247 | mutex_lock(&dev_priv->drm.struct_mutex); | ||
248 | |||
249 | guc = &dev_priv->guc; | ||
250 | if (!guc) { | ||
251 | pr_err("No guc object!\n"); | ||
252 | err = -EINVAL; | ||
253 | goto unlock; | ||
254 | } | ||
255 | |||
256 | err = check_all_doorbells(guc); | ||
257 | if (err) | ||
258 | goto unlock; | ||
259 | |||
260 | for (i = 0; i < ATTEMPTS; i++) { | ||
261 | clients[i] = guc_client_alloc(dev_priv, | ||
262 | INTEL_INFO(dev_priv)->ring_mask, | ||
263 | i % GUC_CLIENT_PRIORITY_NUM, | ||
264 | dev_priv->kernel_context); | ||
265 | |||
266 | if (!clients[i]) { | ||
267 | pr_err("[%d] No guc client\n", i); | ||
268 | err = -EINVAL; | ||
269 | goto out; | ||
270 | } | ||
271 | |||
272 | if (IS_ERR(clients[i])) { | ||
273 | if (PTR_ERR(clients[i]) != -ENOSPC) { | ||
274 | pr_err("[%d] unexpected error\n", i); | ||
275 | err = PTR_ERR(clients[i]); | ||
276 | goto out; | ||
277 | } | ||
278 | |||
279 | if (available_dbs(guc, i % GUC_CLIENT_PRIORITY_NUM)) { | ||
280 | pr_err("[%d] non-db related alloc fail\n", i); | ||
281 | err = -EINVAL; | ||
282 | goto out; | ||
283 | } | ||
284 | |||
285 | /* expected, ran out of dbs for this client type */ | ||
286 | continue; | ||
287 | } | ||
288 | |||
289 | /* | ||
290 | * The check below is only valid because we keep a doorbell | ||
291 | * assigned during the whole life of the client. | ||
292 | */ | ||
293 | if (clients[i]->stage_id >= GUC_NUM_DOORBELLS) { | ||
294 | pr_err("[%d] more clients than doorbells (%d >= %d)\n", | ||
295 | i, clients[i]->stage_id, GUC_NUM_DOORBELLS); | ||
296 | err = -EINVAL; | ||
297 | goto out; | ||
298 | } | ||
299 | |||
300 | err = validate_client(clients[i], | ||
301 | i % GUC_CLIENT_PRIORITY_NUM, false); | ||
302 | if (err) { | ||
303 | pr_err("[%d] client_alloc sanity check failed!\n", i); | ||
304 | err = -EINVAL; | ||
305 | goto out; | ||
306 | } | ||
307 | |||
308 | db_id = clients[i]->doorbell_id; | ||
309 | |||
310 | /* | ||
311 | * Client alloc gives us a doorbell, but we want to exercise | ||
312 | * this ourselves (this resembles guc_init_doorbell_hw) | ||
313 | */ | ||
314 | destroy_doorbell(clients[i]); | ||
315 | if (clients[i]->doorbell_id != GUC_DOORBELL_INVALID) { | ||
316 | pr_err("[%d] destroy db did not work!\n", i); | ||
317 | err = -EINVAL; | ||
318 | goto out; | ||
319 | } | ||
320 | |||
321 | err = __reserve_doorbell(clients[i]); | ||
322 | if (err) { | ||
323 | pr_err("[%d] Failed to reserve a doorbell\n", i); | ||
324 | goto out; | ||
325 | } | ||
326 | |||
327 | __update_doorbell_desc(clients[i], clients[i]->doorbell_id); | ||
328 | err = __create_doorbell(clients[i]); | ||
329 | if (err) { | ||
330 | pr_err("[%d] Failed to create a doorbell\n", i); | ||
331 | goto out; | ||
332 | } | ||
333 | |||
334 | /* doorbell id shouldn't change, we are holding the mutex */ | ||
335 | if (db_id != clients[i]->doorbell_id) { | ||
336 | pr_err("[%d] doorbell id changed (%d != %d)\n", | ||
337 | i, db_id, clients[i]->doorbell_id); | ||
338 | err = -EINVAL; | ||
339 | goto out; | ||
340 | } | ||
341 | |||
342 | err = check_all_doorbells(guc); | ||
343 | if (err) | ||
344 | goto out; | ||
345 | } | ||
346 | |||
347 | out: | ||
348 | for (i = 0; i < ATTEMPTS; i++) | ||
349 | if (!IS_ERR_OR_NULL(clients[i])) | ||
350 | guc_client_free(clients[i]); | ||
351 | unlock: | ||
352 | mutex_unlock(&dev_priv->drm.struct_mutex); | ||
353 | return err; | ||
354 | } | ||
355 | |||
356 | int intel_guc_live_selftest(struct drm_i915_private *dev_priv) | ||
357 | { | ||
358 | static const struct i915_subtest tests[] = { | ||
359 | SUBTEST(igt_guc_init_doorbell_hw), | ||
360 | SUBTEST(igt_guc_doorbells), | ||
361 | }; | ||
362 | |||
363 | if (!i915_modparams.enable_guc_submission) | ||
364 | return 0; | ||
365 | |||
366 | return i915_subtests(tests, dev_priv); | ||
367 | } | ||
diff --git a/drivers/gpu/drm/i915/selftests/intel_uncore.c b/drivers/gpu/drm/i915/selftests/intel_uncore.c index 3cac22eb47ce..2f6367643171 100644 --- a/drivers/gpu/drm/i915/selftests/intel_uncore.c +++ b/drivers/gpu/drm/i915/selftests/intel_uncore.c | |||
@@ -120,10 +120,10 @@ static int intel_uncore_check_forcewake_domains(struct drm_i915_private *dev_pri | |||
120 | !IS_CHERRYVIEW(dev_priv)) | 120 | !IS_CHERRYVIEW(dev_priv)) |
121 | return 0; | 121 | return 0; |
122 | 122 | ||
123 | if (IS_VALLEYVIEW(dev_priv)) /* XXX system lockup! */ | 123 | /* |
124 | return 0; | 124 | * This test may lockup the machine or cause GPU hangs afterwards. |
125 | 125 | */ | |
126 | if (IS_BROADWELL(dev_priv)) /* XXX random GPU hang afterwards! */ | 126 | if (!IS_ENABLED(CONFIG_DRM_I915_SELFTEST_BROKEN)) |
127 | return 0; | 127 | return 0; |
128 | 128 | ||
129 | valid = kzalloc(BITS_TO_LONGS(FW_RANGE) * sizeof(*valid), | 129 | valid = kzalloc(BITS_TO_LONGS(FW_RANGE) * sizeof(*valid), |
@@ -148,7 +148,10 @@ static int intel_uncore_check_forcewake_domains(struct drm_i915_private *dev_pri | |||
148 | for_each_set_bit(offset, valid, FW_RANGE) { | 148 | for_each_set_bit(offset, valid, FW_RANGE) { |
149 | i915_reg_t reg = { offset }; | 149 | i915_reg_t reg = { offset }; |
150 | 150 | ||
151 | iosf_mbi_punit_acquire(); | ||
151 | intel_uncore_forcewake_reset(dev_priv, false); | 152 | intel_uncore_forcewake_reset(dev_priv, false); |
153 | iosf_mbi_punit_release(); | ||
154 | |||
152 | check_for_unclaimed_mmio(dev_priv); | 155 | check_for_unclaimed_mmio(dev_priv); |
153 | 156 | ||
154 | (void)I915_READ(reg); | 157 | (void)I915_READ(reg); |
diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.c b/drivers/gpu/drm/i915/selftests/mock_engine.c index 331c2b09869e..55c0e2c15782 100644 --- a/drivers/gpu/drm/i915/selftests/mock_engine.c +++ b/drivers/gpu/drm/i915/selftests/mock_engine.c | |||
@@ -32,6 +32,13 @@ static struct mock_request *first_request(struct mock_engine *engine) | |||
32 | link); | 32 | link); |
33 | } | 33 | } |
34 | 34 | ||
35 | static void advance(struct mock_engine *engine, | ||
36 | struct mock_request *request) | ||
37 | { | ||
38 | list_del_init(&request->link); | ||
39 | mock_seqno_advance(&engine->base, request->base.global_seqno); | ||
40 | } | ||
41 | |||
35 | static void hw_delay_complete(struct timer_list *t) | 42 | static void hw_delay_complete(struct timer_list *t) |
36 | { | 43 | { |
37 | struct mock_engine *engine = from_timer(engine, t, hw_delay); | 44 | struct mock_engine *engine = from_timer(engine, t, hw_delay); |
@@ -39,15 +46,23 @@ static void hw_delay_complete(struct timer_list *t) | |||
39 | 46 | ||
40 | spin_lock(&engine->hw_lock); | 47 | spin_lock(&engine->hw_lock); |
41 | 48 | ||
42 | request = first_request(engine); | 49 | /* Timer fired, first request is complete */ |
43 | if (request) { | ||
44 | list_del_init(&request->link); | ||
45 | mock_seqno_advance(&engine->base, request->base.global_seqno); | ||
46 | } | ||
47 | |||
48 | request = first_request(engine); | 50 | request = first_request(engine); |
49 | if (request) | 51 | if (request) |
50 | mod_timer(&engine->hw_delay, jiffies + request->delay); | 52 | advance(engine, request); |
53 | |||
54 | /* | ||
55 | * Also immediately signal any subsequent 0-delay requests, but | ||
56 | * requeue the timer for the next delayed request. | ||
57 | */ | ||
58 | while ((request = first_request(engine))) { | ||
59 | if (request->delay) { | ||
60 | mod_timer(&engine->hw_delay, jiffies + request->delay); | ||
61 | break; | ||
62 | } | ||
63 | |||
64 | advance(engine, request); | ||
65 | } | ||
51 | 66 | ||
52 | spin_unlock(&engine->hw_lock); | 67 | spin_unlock(&engine->hw_lock); |
53 | } | 68 | } |
@@ -98,16 +113,22 @@ static void mock_submit_request(struct drm_i915_gem_request *request) | |||
98 | 113 | ||
99 | spin_lock_irq(&engine->hw_lock); | 114 | spin_lock_irq(&engine->hw_lock); |
100 | list_add_tail(&mock->link, &engine->hw_queue); | 115 | list_add_tail(&mock->link, &engine->hw_queue); |
101 | if (mock->link.prev == &engine->hw_queue) | 116 | if (mock->link.prev == &engine->hw_queue) { |
102 | mod_timer(&engine->hw_delay, jiffies + mock->delay); | 117 | if (mock->delay) |
118 | mod_timer(&engine->hw_delay, jiffies + mock->delay); | ||
119 | else | ||
120 | advance(engine, mock); | ||
121 | } | ||
103 | spin_unlock_irq(&engine->hw_lock); | 122 | spin_unlock_irq(&engine->hw_lock); |
104 | } | 123 | } |
105 | 124 | ||
106 | static struct intel_ring *mock_ring(struct intel_engine_cs *engine) | 125 | static struct intel_ring *mock_ring(struct intel_engine_cs *engine) |
107 | { | 126 | { |
108 | const unsigned long sz = roundup_pow_of_two(sizeof(struct intel_ring)); | 127 | const unsigned long sz = PAGE_SIZE / 2; |
109 | struct intel_ring *ring; | 128 | struct intel_ring *ring; |
110 | 129 | ||
130 | BUILD_BUG_ON(MIN_SPACE_FOR_ADD_REQUEST > sz); | ||
131 | |||
111 | ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL); | 132 | ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL); |
112 | if (!ring) | 133 | if (!ring) |
113 | return NULL; | 134 | return NULL; |
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index 04eb9362f4f8..80f152aaedf9 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c | |||
@@ -179,8 +179,8 @@ struct drm_i915_private *mock_gem_device(void) | |||
179 | I915_GTT_PAGE_SIZE_64K | | 179 | I915_GTT_PAGE_SIZE_64K | |
180 | I915_GTT_PAGE_SIZE_2M; | 180 | I915_GTT_PAGE_SIZE_2M; |
181 | 181 | ||
182 | spin_lock_init(&i915->mm.object_stat_lock); | ||
183 | mock_uncore_init(i915); | 182 | mock_uncore_init(i915); |
183 | i915_gem_init__mm(i915); | ||
184 | 184 | ||
185 | init_waitqueue_head(&i915->gpu_error.wait_queue); | 185 | init_waitqueue_head(&i915->gpu_error.wait_queue); |
186 | init_waitqueue_head(&i915->gpu_error.reset_queue); | 186 | init_waitqueue_head(&i915->gpu_error.reset_queue); |
@@ -189,11 +189,6 @@ struct drm_i915_private *mock_gem_device(void) | |||
189 | if (!i915->wq) | 189 | if (!i915->wq) |
190 | goto put_device; | 190 | goto put_device; |
191 | 191 | ||
192 | INIT_WORK(&i915->mm.free_work, __i915_gem_free_work); | ||
193 | init_llist_head(&i915->mm.free_list); | ||
194 | INIT_LIST_HEAD(&i915->mm.unbound_list); | ||
195 | INIT_LIST_HEAD(&i915->mm.bound_list); | ||
196 | |||
197 | mock_init_contexts(i915); | 192 | mock_init_contexts(i915); |
198 | 193 | ||
199 | INIT_DELAYED_WORK(&i915->gt.retire_work, mock_retire_work_handler); | 194 | INIT_DELAYED_WORK(&i915->gt.retire_work, mock_retire_work_handler); |
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index ac3c6503ca27..b57985929553 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h | |||
@@ -86,6 +86,22 @@ enum i915_mocs_table_index { | |||
86 | I915_MOCS_CACHED, | 86 | I915_MOCS_CACHED, |
87 | }; | 87 | }; |
88 | 88 | ||
89 | /* | ||
90 | * Different engines serve different roles, and there may be more than one | ||
91 | * engine serving each role. enum drm_i915_gem_engine_class provides a | ||
92 | * classification of the role of the engine, which may be used when requesting | ||
93 | * operations to be performed on a certain subset of engines, or for providing | ||
94 | * information about that group. | ||
95 | */ | ||
96 | enum drm_i915_gem_engine_class { | ||
97 | I915_ENGINE_CLASS_RENDER = 0, | ||
98 | I915_ENGINE_CLASS_COPY = 1, | ||
99 | I915_ENGINE_CLASS_VIDEO = 2, | ||
100 | I915_ENGINE_CLASS_VIDEO_ENHANCE = 3, | ||
101 | |||
102 | I915_ENGINE_CLASS_INVALID = -1 | ||
103 | }; | ||
104 | |||
89 | /* Each region is a minimum of 16k, and there are at most 255 of them. | 105 | /* Each region is a minimum of 16k, and there are at most 255 of them. |
90 | */ | 106 | */ |
91 | #define I915_NR_TEX_REGIONS 255 /* table size 2k - maximum due to use | 107 | #define I915_NR_TEX_REGIONS 255 /* table size 2k - maximum due to use |
@@ -450,6 +466,27 @@ typedef struct drm_i915_irq_wait { | |||
450 | */ | 466 | */ |
451 | #define I915_PARAM_HAS_EXEC_FENCE_ARRAY 49 | 467 | #define I915_PARAM_HAS_EXEC_FENCE_ARRAY 49 |
452 | 468 | ||
469 | /* | ||
470 | * Query whether every context (both per-file default and user created) is | ||
471 | * isolated (insofar as HW supports). If this parameter is not true, then | ||
472 | * freshly created contexts may inherit values from an existing context, | ||
473 | * rather than default HW values. If true, it also ensures (insofar as HW | ||
474 | * supports) that all state set by this context will not leak to any other | ||
475 | * context. | ||
476 | * | ||
477 | * As not every engine across every gen support contexts, the returned | ||
478 | * value reports the support of context isolation for individual engines by | ||
479 | * returning a bitmask of each engine class set to true if that class supports | ||
480 | * isolation. | ||
481 | */ | ||
482 | #define I915_PARAM_HAS_CONTEXT_ISOLATION 50 | ||
483 | |||
484 | /* Frequency of the command streamer timestamps given by the *_TIMESTAMP | ||
485 | * registers. This used to be fixed per platform but from CNL onwards, this | ||
486 | * might vary depending on the parts. | ||
487 | */ | ||
488 | #define I915_PARAM_CS_TIMESTAMP_FREQUENCY 51 | ||
489 | |||
453 | typedef struct drm_i915_getparam { | 490 | typedef struct drm_i915_getparam { |
454 | __s32 param; | 491 | __s32 param; |
455 | /* | 492 | /* |