Merge tag 'gvt-next-2018-09-04' drm-intel-next-2018-09-06-1: UAPI Changes: - GGTT coherency GETPARAM: GGTT has turned out to be non-coherent for some platforms, which we've failed to communicate to userspace so far. SNA was modified to do extra flushing on non-coherent GGTT access, while Mesa will mitigate by always requiring WC mapping (which is non-coherent anyway). - Neuter Resource Streamer uAPI: There never really were users for the feature, so neuter it while keeping the interface bits for compatibility. This is a long due item from past. Cross-subsystem Changes: - Backmerge of branch drm-next-4.19 for DP_DPCD_REV_14 changes Core Changes: - None Driver Changes: - A load of Icelake (ICL) enabling patches (Paulo, Manasi) - Enabled full PPGTT for IVB,VLV and HSW (Chris) - Bugzilla #107113: Distribute DDB based on display resolutions (Mahesh) - Bugzillas #100023,#107476,#94921: Support limited range DP displays (Jani) - Bugzilla #107503: Increase LSPCON timeout (Fredrik) - Avoid boosting GPU due to an occasional stall in interactive workloads (Chris) - Apply GGTT coherency W/A only for affected systems instead of all (Chris) - Fix for infinite link training loop for faulty USB-C MST hubs (Nathan) - Keep KMS functional on Gen4 and earlier when GPU is wedged (Chris) - Stop holding ppGTT reference from closed VMAs (Chris) - Clear error registers after error capture (Lionel) - Various Icelake fixes (Anusha, Jyoti, Ville, Tvrtko) - Add missing Coffeelake (CFL) PCI IDs (Rodrigo) - Flush execlists tasklet directly from reset-finish (Chris) - Fix LPE audio runtime PM (Chris) - Fix detection of out of range surface positions (GLK/CNL) (Ville) - Remove wait-for-idle for PSR2 (Dhinakaran) - Power down existing display hardware resources when display is disabled (Chris) - Don't allow runtime power management if RC6 doesn't exist (Chris) - Add debugging checks for runtime power management paths (Imre) - Increase symmetry in display power init/fini paths (Imre) - Isolate GVT specific macros from i915_reg.h (Lucas) - Increase symmetry in power management enable/disable paths (Chris) - Increase IP disable timeout to 100 ms to avoid DRM_ERROR (Imre) - Fix memory leak from HDMI HDCP write function (Brian, Rodrigo) - Reject Y/Yf tiling on interlaced modes (Ville) - Use a cached mapping for the physical HWS on older gens (Chris) - Force slow path of writing relocations to buffer if unable to write to userspace (Chris) - Do a full device reset after being wedged (Chris) - Keep forcewake counts over reset (in case of debugfs user) (Imre, Chris) - Avoid false-positive errors from power wells during init (Imre) - Reset engines forcibly in exchange of declaring whole device wedged (Mika) - Reduce context HW ID lifetime in preparation for Icelake (Chris) - Attempt to recover from module load failures (Chris) - Keep select interrupts over a reset to avoid missing/losing them (Chris) - GuC submission backend improvements (Jakub) - Terminate context images with BB_END (Chris, Lionel) - Make GCC evaluate GGTT view struct size assertions again (Ville) - Add selftest to exercise suspend/hibernate code-paths for GEM (Chris) - Use a full emulation of a user ppgtt context in selftests (Chris) - Exercise resetting in the middle of a wait-on-fence in selftests (Chris) - Fix coherency issues on selftests for Baytrail (Chris) - Various other GEM fixes / self-test updates (Chris, Matt) - GuC doorbell self-tests (Daniele) - PSR mode control through debugfs for IGTs (Maarten) - Degrade expected WM latency errors to DRM_DEBUG_KMS (Chris) - Cope with errors better in MST link training (Dhinakaran) - Fix WARN on KBL external displays (Azhar) - Power well code cleanups (Imre) - Fixes to PSR debugging (Dhinakaran) - Make forcewake errors louder for easier catching in CI (WARNs) (Chris) - Fortify tiling code against programmer errors (Chris) - Bunch of fixes for CI exposed corner cases (multiple authors, mostly Chris) Signed-off-by: Dave Airlie <airlied@redhat.com>
Unified · Split
| @@ -30,6 +30,7 @@ config DRM_I915_DEBUG · 29 unmodified lines | ||
| 30 | 30 | select SW_SYNC # signaling validation framework (igt/syncobj*) |
| 31 | 31 | select DRM_I915_SW_FENCE_DEBUG_OBJECTS |
| 32 | 32 | select DRM_I915_SELFTEST |
| 33 | + select DRM_I915_DEBUG_RUNTIME_PM | |
| 33 | 34 | default n |
| 34 | 35 | help |
| 35 | 36 | Choose this option to turn on extra driver debugging that may affect |
| @@ -167,3 +168,14 @@ config DRM_I915_DEBUG_VBLANK_EVADE · 131 unmodified lines | ||
| 167 | 168 | the vblank. |
| 168 | 169 | |
| 169 | 170 | If in doubt, say "N". |
| 171 | + | |
| 172 | +config DRM_I915_DEBUG_RUNTIME_PM | |
| 173 | + bool "Enable extra state checking for runtime PM" | |
| 174 | + depends on DRM_I915 | |
| 175 | + default n | |
| 176 | + help | |
| 177 | + Choose this option to turn on extra state checking for the | |
| 178 | + runtime PM functionality. This may introduce overhead during | |
| 179 | + driver loading, suspend and resume operations. | |
| 180 | + | |
| 181 | + If in doubt, say "N" | |
| @@ -56,6 +56,10 @@ static const u8 pci_cfg_space_rw_bmp[PCI_INTERRUPT_LINE + 4] = { · 55 unmodified lines | ||
| 56 | 56 | |
| 57 | 57 | /** |
| 58 | 58 | * vgpu_pci_cfg_mem_write - write virtual cfg space memory |
| 59 | + * @vgpu: target vgpu | |
| 60 | + * @off: offset | |
| 61 | + * @src: src ptr to write | |
| 62 | + * @bytes: number of bytes | |
| 59 | 63 | * |
| 60 | 64 | * Use this function to write virtual cfg space memory. |
| 61 | 65 | * For standard cfg space, only RW bits can be changed, |
| @@ -91,6 +95,10 @@ static void vgpu_pci_cfg_mem_write(struct intel_vgpu *vgpu, unsigned int off, · 29 unmodified lines | ||
| 91 | 95 | |
| 92 | 96 | /** |
| 93 | 97 | * intel_vgpu_emulate_cfg_read - emulate vGPU configuration space read |
| 98 | + * @vgpu: target vgpu | |
| 99 | + * @offset: offset | |
| 100 | + * @p_data: return data ptr | |
| 101 | + * @bytes: number of bytes to read | |
| 94 | 102 | * |
| 95 | 103 | * Returns: |
| 96 | 104 | * Zero on success, negative error code if failed. |
| @@ -278,6 +286,10 @@ static int emulate_pci_bar_write(struct intel_vgpu *vgpu, unsigned int offset, · 181 unmodified lines | ||
| 278 | 286 | |
| 279 | 287 | /** |
| 280 | 288 | * intel_vgpu_emulate_cfg_read - emulate vGPU configuration space write |
| 289 | + * @vgpu: target vgpu | |
| 290 | + * @offset: offset | |
| 291 | + * @p_data: write data ptr | |
| 292 | + * @bytes: number of bytes to write | |
| 281 | 293 | * |
| 282 | 294 | * Returns: |
| 283 | 295 | * Zero on success, negative error code if failed. |
| @@ -1840,6 +1840,8 @@ static int cmd_handler_mi_batch_buffer_start(struct parser_exec_state *s) · 1839 unmodified lines | ||
| 1840 | 1840 | return ret; |
| 1841 | 1841 | } |
| 1842 | 1842 | |
| 1843 | +static int mi_noop_index; | |
| 1844 | + | |
| 1843 | 1845 | static struct cmd_info cmd_info[] = { |
| 1844 | 1846 | {"MI_NOOP", OP_MI_NOOP, F_LEN_CONST, R_ALL, D_ALL, 0, 1, NULL}, |
| 1845 | 1847 | |
| @@ -2525,7 +2527,12 @@ static int cmd_parser_exec(struct parser_exec_state *s) · 679 unmodified lines | ||
| 2525 | 2527 | |
| 2526 | 2528 | cmd = cmd_val(s, 0); |
| 2527 | 2529 | |
| 2528 | − info = get_cmd_info(s->vgpu->gvt, cmd, s->ring_id); | |
| 2530 | + /* fastpath for MI_NOOP */ | |
| 2531 | + if (cmd == MI_NOOP) | |
| 2532 | + info = &cmd_info[mi_noop_index]; | |
| 2533 | + else | |
| 2534 | + info = get_cmd_info(s->vgpu->gvt, cmd, s->ring_id); | |
| 2535 | + | |
| 2529 | 2536 | if (info == NULL) { |
| 2530 | 2537 | gvt_vgpu_err("unknown cmd 0x%x, opcode=0x%x, addr_type=%s, ring %d, workload=%p\n", |
| 2531 | 2538 | cmd, get_opcode(cmd, s->ring_id), |
| @@ -2928,6 +2935,8 @@ static int init_cmd_table(struct intel_gvt *gvt) · 396 unmodified lines | ||
| 2928 | 2935 | kfree(e); |
| 2929 | 2936 | return -EEXIST; |
| 2930 | 2937 | } |
| 2938 | + if (cmd_info[i].opcode == OP_MI_NOOP) | |
| 2939 | + mi_noop_index = i; | |
| 2931 | 2940 | |
| 2932 | 2941 | INIT_HLIST_NODE(&e->hlist); |
| 2933 | 2942 | add_cmd_entry(gvt, e); |
| @@ -462,6 +462,7 @@ void intel_vgpu_clean_display(struct intel_vgpu *vgpu) · 461 unmodified lines | ||
| 462 | 462 | /** |
| 463 | 463 | * intel_vgpu_init_display- initialize vGPU virtual display emulation |
| 464 | 464 | * @vgpu: a vGPU |
| 465 | + * @resolution: resolution index for intel_vgpu_edid | |
| 465 | 466 | * |
| 466 | 467 | * This function is used to initialize vGPU virtual display emulation stuffs |
| 467 | 468 | * |
| @@ -340,6 +340,9 @@ static int gmbus2_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, · 339 unmodified lines | ||
| 340 | 340 | /** |
| 341 | 341 | * intel_gvt_i2c_handle_gmbus_read - emulate gmbus register mmio read |
| 342 | 342 | * @vgpu: a vGPU |
| 343 | + * @offset: reg offset | |
| 344 | + * @p_data: data return buffer | |
| 345 | + * @bytes: access data length | |
| 343 | 346 | * |
| 344 | 347 | * This function is used to emulate gmbus register mmio read |
| 345 | 348 | * |
| @@ -365,6 +368,9 @@ int intel_gvt_i2c_handle_gmbus_read(struct intel_vgpu *vgpu, · 19 unmodified lines | ||
| 365 | 368 | /** |
| 366 | 369 | * intel_gvt_i2c_handle_gmbus_write - emulate gmbus register mmio write |
| 367 | 370 | * @vgpu: a vGPU |
| 371 | + * @offset: reg offset | |
| 372 | + * @p_data: data return buffer | |
| 373 | + * @bytes: access data length | |
| 368 | 374 | * |
| 369 | 375 | * This function is used to emulate gmbus register mmio write |
| 370 | 376 | * |
| @@ -437,6 +443,9 @@ static inline int get_aux_ch_reg(unsigned int offset) · 66 unmodified lines | ||
| 437 | 443 | /** |
| 438 | 444 | * intel_gvt_i2c_handle_aux_ch_write - emulate AUX channel register write |
| 439 | 445 | * @vgpu: a vGPU |
| 446 | + * @port_idx: port index | |
| 447 | + * @offset: reg offset | |
| 448 | + * @p_data: write ptr | |
| 440 | 449 | * |
| 441 | 450 | * This function is used to emulate AUX channel register write |
| 442 | 451 | * |
| @@ -1113,6 +1113,10 @@ static inline void ppgtt_generate_shadow_entry(struct intel_gvt_gtt_entry *se, · 1112 unmodified lines | ||
| 1113 | 1113 | } |
| 1114 | 1114 | |
| 1115 | 1115 | /** |
| 1116 | + * Check if can do 2M page | |
| 1117 | + * @vgpu: target vgpu | |
| 1118 | + * @entry: target pfn's gtt entry | |
| 1119 | + * | |
| 1116 | 1120 | * Return 1 if 2MB huge gtt shadowing is possilbe, 0 if miscondition, |
| 1117 | 1121 | * negtive if found err. |
| 1118 | 1122 | */ |
| @@ -1945,7 +1949,7 @@ void intel_vgpu_unpin_mm(struct intel_vgpu_mm *mm) · 826 unmodified lines | ||
| 1945 | 1949 | |
| 1946 | 1950 | /** |
| 1947 | 1951 | * intel_vgpu_pin_mm - increase the pin count of a vGPU mm object |
| 1948 | − * @vgpu: a vGPU | |
| 1952 | + * @mm: target vgpu mm | |
| 1949 | 1953 | * |
| 1950 | 1954 | * This function is called when user wants to use a vGPU mm object. If this |
| 1951 | 1955 | * mm object hasn't been shadowed yet, the shadow will be populated at this |
| @@ -2521,8 +2525,7 @@ fail: · 569 unmodified lines | ||
| 2521 | 2525 | /** |
| 2522 | 2526 | * intel_vgpu_find_ppgtt_mm - find a PPGTT mm object |
| 2523 | 2527 | * @vgpu: a vGPU |
| 2524 | − * @page_table_level: PPGTT page table level | |
| 2525 | − * @root_entry: PPGTT page table root pointers | |
| 2528 | + * @pdps: pdp root array | |
| 2526 | 2529 | * |
| 2527 | 2530 | * This function is used to find a PPGTT mm object from mm object pool |
| 2528 | 2531 | * |
| @@ -189,7 +189,6 @@ static const struct intel_gvt_ops intel_gvt_ops = { · 188 unmodified lines | ||
| 189 | 189 | |
| 190 | 190 | /** |
| 191 | 191 | * intel_gvt_init_host - Load MPT modules and detect if we're running in host |
| 192 | − * @gvt: intel gvt device | |
| 193 | 192 | * |
| 194 | 193 | * This function is called at the driver loading stage. If failed to find a |
| 195 | 194 | * loadable MPT module or detect currently we're running in a VM, then GVT-g |
| @@ -303,7 +302,7 @@ static int init_service_thread(struct intel_gvt *gvt) · 107 unmodified lines | ||
| 303 | 302 | |
| 304 | 303 | /** |
| 305 | 304 | * intel_gvt_clean_device - clean a GVT device |
| 306 | − * @gvt: intel gvt device | |
| 305 | + * @dev_priv: i915 private | |
| 307 | 306 | * |
| 308 | 307 | * This function is called at the driver unloading stage, to free the |
| 309 | 308 | * resources owned by a GVT device. |
| @@ -1287,12 +1287,13 @@ static int power_well_ctl_mmio_write(struct intel_vgpu *vgpu, · 1286 unmodified lines | ||
| 1287 | 1287 | { |
| 1288 | 1288 | write_vreg(vgpu, offset, p_data, bytes); |
| 1289 | 1289 | |
| 1290 | − if (vgpu_vreg(vgpu, offset) & HSW_PWR_WELL_CTL_REQ(HSW_DISP_PW_GLOBAL)) | |
| 1290 | + if (vgpu_vreg(vgpu, offset) & | |
| 1291 | + HSW_PWR_WELL_CTL_REQ(HSW_PW_CTL_IDX_GLOBAL)) | |
| 1291 | 1292 | vgpu_vreg(vgpu, offset) |= |
| 1292 | − HSW_PWR_WELL_CTL_STATE(HSW_DISP_PW_GLOBAL); | |
| 1293 | + HSW_PWR_WELL_CTL_STATE(HSW_PW_CTL_IDX_GLOBAL); | |
| 1293 | 1294 | else |
| 1294 | 1295 | vgpu_vreg(vgpu, offset) &= |
| 1295 | − ~HSW_PWR_WELL_CTL_STATE(HSW_DISP_PW_GLOBAL); | |
| 1296 | + ~HSW_PWR_WELL_CTL_STATE(HSW_PW_CTL_IDX_GLOBAL); | |
| 1296 | 1297 | return 0; |
| 1297 | 1298 | } |
| 1298 | 1299 | |
| @@ -2118,7 +2119,7 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) · 819 unmodified lines | ||
| 2118 | 2119 | |
| 2119 | 2120 | MMIO_F(PCH_GMBUS0, 4 * 4, 0, 0, 0, D_ALL, gmbus_mmio_read, |
| 2120 | 2121 | gmbus_mmio_write); |
| 2121 | − MMIO_F(PCH_GPIOA, 6 * 4, F_UNALIGN, 0, 0, D_ALL, NULL, NULL); | |
| 2122 | + MMIO_F(PCH_GPIO_BASE, 6 * 4, F_UNALIGN, 0, 0, D_ALL, NULL, NULL); | |
| 2122 | 2123 | MMIO_F(_MMIO(0xe4f00), 0x28, 0, 0, 0, D_ALL, NULL, NULL); |
| 2123 | 2124 | |
| 2124 | 2125 | MMIO_F(_MMIO(_PCH_DPB_AUX_CH_CTL), 6 * 4, 0, 0, 0, D_PRE_SKL, NULL, |
| @@ -2443,17 +2444,10 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) · 318 unmodified lines | ||
| 2443 | 2444 | MMIO_D(GEN6_RC6p_THRESHOLD, D_ALL); |
| 2444 | 2445 | MMIO_D(GEN6_RC6pp_THRESHOLD, D_ALL); |
| 2445 | 2446 | MMIO_D(GEN6_PMINTRMSK, D_ALL); |
| 2446 | − /* | |
| 2447 | − * Use an arbitrary power well controlled by the PWR_WELL_CTL | |
| 2448 | − * register. | |
| 2449 | − */ | |
| 2450 | − MMIO_DH(HSW_PWR_WELL_CTL_BIOS(HSW_DISP_PW_GLOBAL), D_BDW, NULL, | |
| 2451 | − power_well_ctl_mmio_write); | |
| 2452 | − MMIO_DH(HSW_PWR_WELL_CTL_DRIVER(HSW_DISP_PW_GLOBAL), D_BDW, NULL, | |
| 2453 | − power_well_ctl_mmio_write); | |
| 2454 | − MMIO_DH(HSW_PWR_WELL_CTL_KVMR, D_BDW, NULL, power_well_ctl_mmio_write); | |
| 2455 | − MMIO_DH(HSW_PWR_WELL_CTL_DEBUG(HSW_DISP_PW_GLOBAL), D_BDW, NULL, | |
| 2456 | − power_well_ctl_mmio_write); | |
| 2447 | + MMIO_DH(HSW_PWR_WELL_CTL1, D_BDW, NULL, power_well_ctl_mmio_write); | |
| 2448 | + MMIO_DH(HSW_PWR_WELL_CTL2, D_BDW, NULL, power_well_ctl_mmio_write); | |
| 2449 | + MMIO_DH(HSW_PWR_WELL_CTL3, D_BDW, NULL, power_well_ctl_mmio_write); | |
| 2450 | + MMIO_DH(HSW_PWR_WELL_CTL4, D_BDW, NULL, power_well_ctl_mmio_write); | |
| 2457 | 2451 | MMIO_DH(HSW_PWR_WELL_CTL5, D_BDW, NULL, power_well_ctl_mmio_write); |
| 2458 | 2452 | MMIO_DH(HSW_PWR_WELL_CTL6, D_BDW, NULL, power_well_ctl_mmio_write); |
| 2459 | 2453 | |
| @@ -2804,13 +2798,8 @@ static int init_skl_mmio_info(struct intel_gvt *gvt) · 344 unmodified lines | ||
| 2804 | 2798 | MMIO_F(_MMIO(_DPD_AUX_CH_CTL), 6 * 4, 0, 0, 0, D_SKL_PLUS, NULL, |
| 2805 | 2799 | dp_aux_ch_ctl_mmio_write); |
| 2806 | 2800 | |
| 2807 | − /* | |
| 2808 | − * Use an arbitrary power well controlled by the PWR_WELL_CTL | |
| 2809 | − * register. | |
| 2810 | − */ | |
| 2811 | − MMIO_D(HSW_PWR_WELL_CTL_BIOS(SKL_DISP_PW_MISC_IO), D_SKL_PLUS); | |
| 2812 | − MMIO_DH(HSW_PWR_WELL_CTL_DRIVER(SKL_DISP_PW_MISC_IO), D_SKL_PLUS, NULL, | |
| 2813 | − skl_power_well_ctl_write); | |
| 2801 | + MMIO_D(HSW_PWR_WELL_CTL1, D_SKL_PLUS); | |
| 2802 | + MMIO_DH(HSW_PWR_WELL_CTL2, D_SKL_PLUS, NULL, skl_power_well_ctl_write); | |
| 2814 | 2803 | |
| 2815 | 2804 | MMIO_D(_MMIO(0xa210), D_SKL_PLUS); |
| 2816 | 2805 | MMIO_D(GEN9_MEDIA_PG_IDLE_HYSTERESIS, D_SKL_PLUS); |
| @@ -3434,6 +3423,7 @@ bool intel_gvt_in_force_nonpriv_whitelist(struct intel_gvt *gvt, · 617 unmodified lines | ||
| 3434 | 3423 | * @offset: register offset |
| 3435 | 3424 | * @pdata: data buffer |
| 3436 | 3425 | * @bytes: data length |
| 3426 | + * @is_read: read or write | |
| 3437 | 3427 | * |
| 3438 | 3428 | * Returns: |
| 3439 | 3429 | * Zero on success, negative error code if failed. |
| @@ -1712,7 +1712,7 @@ static unsigned long kvmgt_gfn_to_pfn(unsigned long handle, unsigned long gfn) · 1711 unmodified lines | ||
| 1712 | 1712 | return pfn; |
| 1713 | 1713 | } |
| 1714 | 1714 | |
| 1715 | −int kvmgt_dma_map_guest_page(unsigned long handle, unsigned long gfn, | |
| 1715 | +static int kvmgt_dma_map_guest_page(unsigned long handle, unsigned long gfn, | |
| 1716 | 1716 | unsigned long size, dma_addr_t *dma_addr) |
| 1717 | 1717 | { |
| 1718 | 1718 | struct kvmgt_guest_info *info; |
| @@ -1761,7 +1761,7 @@ static void __gvt_dma_release(struct kref *ref) · 42 unmodified lines | ||
| 1761 | 1761 | __gvt_cache_remove_entry(entry->vgpu, entry); |
| 1762 | 1762 | } |
| 1763 | 1763 | |
| 1764 | −void kvmgt_dma_unmap_guest_page(unsigned long handle, dma_addr_t dma_addr) | |
| 1764 | +static void kvmgt_dma_unmap_guest_page(unsigned long handle, dma_addr_t dma_addr) | |
| 1765 | 1765 | { |
| 1766 | 1766 | struct kvmgt_guest_info *info; |
| 1767 | 1767 | struct gvt_dma *entry; |
| @@ -39,6 +39,7 @@ · 38 unmodified lines | ||
| 39 | 39 | /** |
| 40 | 40 | * intel_vgpu_gpa_to_mmio_offset - translate a GPA to MMIO offset |
| 41 | 41 | * @vgpu: a vGPU |
| 42 | + * @gpa: guest physical address | |
| 42 | 43 | * |
| 43 | 44 | * Returns: |
| 44 | 45 | * Zero on success, negative error code if failed |
| @@ -228,7 +229,7 @@ out: · 183 unmodified lines | ||
| 228 | 229 | /** |
| 229 | 230 | * intel_vgpu_reset_mmio - reset virtual MMIO space |
| 230 | 231 | * @vgpu: a vGPU |
| 231 | − * | |
| 232 | + * @dmlr: whether this is device model level reset | |
| 232 | 233 | */ |
| 233 | 234 | void intel_vgpu_reset_mmio(struct intel_vgpu *vgpu, bool dmlr) |
| 234 | 235 | { |
| @@ -37,19 +37,6 @@ · 36 unmodified lines | ||
| 37 | 37 | #include "gvt.h" |
| 38 | 38 | #include "trace.h" |
| 39 | 39 | |
| 40 | −/** | |
| 41 | − * Defined in Intel Open Source PRM. | |
| 42 | − * Ref: https://01.org/linuxgraphics/documentation/hardware-specification-prms | |
| 43 | − */ | |
| 44 | −#define TRVATTL3PTRDW(i) _MMIO(0x4de0 + (i)*4) | |
| 45 | −#define TRNULLDETCT _MMIO(0x4de8) | |
| 46 | −#define TRINVTILEDETCT _MMIO(0x4dec) | |
| 47 | −#define TRVADR _MMIO(0x4df0) | |
| 48 | −#define TRTTE _MMIO(0x4df4) | |
| 49 | −#define RING_EXCC(base) _MMIO((base) + 0x28) | |
| 50 | −#define RING_GFX_MODE(base) _MMIO((base) + 0x29c) | |
| 51 | −#define VF_GUARDBAND _MMIO(0x83a4) | |
| 52 | − | |
| 53 | 40 | #define GEN9_MOCS_SIZE 64 |
| 54 | 41 | |
| 55 | 42 | /* Raw offset is appened to each line for convenience. */ |
| @@ -53,5 +53,8 @@ bool is_inhibit_context(struct intel_context *ce); · 52 unmodified lines | ||
| 53 | 53 | |
| 54 | 54 | int intel_vgpu_restore_inhibit_context(struct intel_vgpu *vgpu, |
| 55 | 55 | struct i915_request *req); |
| 56 | +#define IS_RESTORE_INHIBIT(a) \ | |
| 57 | + (_MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT) == \ | |
| 58 | + ((a) & _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT))) | |
| 56 | 59 | |
| 57 | 60 | #endif |
| @@ -216,7 +216,6 @@ static void virt_vbt_generation(struct vbt *v) · 215 unmodified lines | ||
| 216 | 216 | /** |
| 217 | 217 | * intel_vgpu_init_opregion - initialize the stuff used to emulate opregion |
| 218 | 218 | * @vgpu: a vGPU |
| 219 | − * @gpa: guest physical address of opregion | |
| 220 | 219 | * |
| 221 | 220 | * Returns: |
| 222 | 221 | * Zero on success, negative error code if failed. |
| @@ -41,6 +41,8 @@ struct intel_vgpu_page_track *intel_vgpu_find_page_track( · 40 unmodified lines | ||
| 41 | 41 | * intel_vgpu_register_page_track - register a guest page to be tacked |
| 42 | 42 | * @vgpu: a vGPU |
| 43 | 43 | * @gfn: the gfn of guest page |
| 44 | + * @handler: page track handler | |
| 45 | + * @priv: tracker private | |
| 44 | 46 | * |
| 45 | 47 | * Returns: |
| 46 | 48 | * zero on success, negative error code if failed. |
| @@ -77,4 +77,22 @@ · 76 unmodified lines | ||
| 77 | 77 | #define _RING_CTL_BUF_SIZE(ctl) (((ctl) & RB_TAIL_SIZE_MASK) + \ |
| 78 | 78 | I915_GTT_PAGE_SIZE) |
| 79 | 79 | |
| 80 | +#define PCH_GPIO_BASE _MMIO(0xc5010) | |
| 81 | + | |
| 82 | +#define PCH_GMBUS0 _MMIO(0xc5100) | |
| 83 | +#define PCH_GMBUS1 _MMIO(0xc5104) | |
| 84 | +#define PCH_GMBUS2 _MMIO(0xc5108) | |
| 85 | +#define PCH_GMBUS3 _MMIO(0xc510c) | |
| 86 | +#define PCH_GMBUS4 _MMIO(0xc5110) | |
| 87 | +#define PCH_GMBUS5 _MMIO(0xc5120) | |
| 88 | + | |
| 89 | +#define TRVATTL3PTRDW(i) _MMIO(0x4de0 + (i) * 4) | |
| 90 | +#define TRNULLDETCT _MMIO(0x4de8) | |
| 91 | +#define TRINVTILEDETCT _MMIO(0x4dec) | |
| 92 | +#define TRVADR _MMIO(0x4df0) | |
| 93 | +#define TRTTE _MMIO(0x4df4) | |
| 94 | +#define RING_EXCC(base) _MMIO((base) + 0x28) | |
| 95 | +#define RING_GFX_MODE(base) _MMIO((base) + 0x29c) | |
| 96 | +#define VF_GUARDBAND _MMIO(0x83a4) | |
| 97 | + | |
| 80 | 98 | #endif |
| @@ -132,35 +132,6 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload) · 131 unmodified lines | ||
| 132 | 132 | unsigned long context_gpa, context_page_num; |
| 133 | 133 | int i; |
| 134 | 134 | |
| 135 | − gvt_dbg_sched("ring id %d workload lrca %x", ring_id, | |
| 136 | − workload->ctx_desc.lrca); | |
| 137 | − | |
| 138 | − context_page_num = gvt->dev_priv->engine[ring_id]->context_size; | |
| 139 | − | |
| 140 | − context_page_num = context_page_num >> PAGE_SHIFT; | |
| 141 | − | |
| 142 | − if (IS_BROADWELL(gvt->dev_priv) && ring_id == RCS) | |
| 143 | − context_page_num = 19; | |
| 144 | − | |
| 145 | − i = 2; | |
| 146 | − | |
| 147 | − while (i < context_page_num) { | |
| 148 | − context_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, | |
| 149 | − (u32)((workload->ctx_desc.lrca + i) << | |
| 150 | − I915_GTT_PAGE_SHIFT)); | |
| 151 | − if (context_gpa == INTEL_GVT_INVALID_ADDR) { | |
| 152 | − gvt_vgpu_err("Invalid guest context descriptor\n"); | |
| 153 | − return -EFAULT; | |
| 154 | − } | |
| 155 | − | |
| 156 | − page = i915_gem_object_get_page(ctx_obj, LRC_HEADER_PAGES + i); | |
| 157 | − dst = kmap(page); | |
| 158 | − intel_gvt_hypervisor_read_gpa(vgpu, context_gpa, dst, | |
| 159 | − I915_GTT_PAGE_SIZE); | |
| 160 | − kunmap(page); | |
| 161 | − i++; | |
| 162 | − } | |
| 163 | − | |
| 164 | 135 | page = i915_gem_object_get_page(ctx_obj, LRC_STATE_PN); |
| 165 | 136 | shadow_ring_context = kmap(page); |
| 166 | 137 | |
| @@ -195,6 +166,37 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload) · 28 unmodified lines | ||
| 195 | 166 | |
| 196 | 167 | sr_oa_regs(workload, (u32 *)shadow_ring_context, false); |
| 197 | 168 | kunmap(page); |
| 169 | + | |
| 170 | + if (IS_RESTORE_INHIBIT(shadow_ring_context->ctx_ctrl.val)) | |
| 171 | + return 0; | |
| 172 | + | |
| 173 | + gvt_dbg_sched("ring id %d workload lrca %x", ring_id, | |
| 174 | + workload->ctx_desc.lrca); | |
| 175 | + | |
| 176 | + context_page_num = gvt->dev_priv->engine[ring_id]->context_size; | |
| 177 | + | |
| 178 | + context_page_num = context_page_num >> PAGE_SHIFT; | |
| 179 | + | |
| 180 | + if (IS_BROADWELL(gvt->dev_priv) && ring_id == RCS) | |
| 181 | + context_page_num = 19; | |
| 182 | + | |
| 183 | + i = 2; | |
| 184 | + while (i < context_page_num) { | |
| 185 | + context_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, | |
| 186 | + (u32)((workload->ctx_desc.lrca + i) << | |
| 187 | + I915_GTT_PAGE_SHIFT)); | |
| 188 | + if (context_gpa == INTEL_GVT_INVALID_ADDR) { | |
| 189 | + gvt_vgpu_err("Invalid guest context descriptor\n"); | |
| 190 | + return -EFAULT; | |
| 191 | + } | |
| 192 | + | |
| 193 | + page = i915_gem_object_get_page(ctx_obj, LRC_HEADER_PAGES + i); | |
| 194 | + dst = kmap(page); | |
| 195 | + intel_gvt_hypervisor_read_gpa(vgpu, context_gpa, dst, | |
| 196 | + I915_GTT_PAGE_SIZE); | |
| 197 | + kunmap(page); | |
| 198 | + i++; | |
| 199 | + } | |
| 198 | 200 | return 0; |
| 199 | 201 | } |
| 200 | 202 | |
| @@ -1138,6 +1140,7 @@ out_shadow_ctx: · 937 unmodified lines | ||
| 1138 | 1140 | /** |
| 1139 | 1141 | * intel_vgpu_select_submission_ops - select virtual submission interface |
| 1140 | 1142 | * @vgpu: a vGPU |
| 1143 | + * @engine_mask: either ALL_ENGINES or target engine mask | |
| 1141 | 1144 | * @interface: expected vGPU virtual submission interface |
| 1142 | 1145 | * |
| 1143 | 1146 | * This function is called when guest configures submission interface. |
| @@ -1190,7 +1193,7 @@ int intel_vgpu_select_submission_ops(struct intel_vgpu *vgpu, · 46 unmodified lines | ||
| 1190 | 1193 | |
| 1191 | 1194 | /** |
| 1192 | 1195 | * intel_vgpu_destroy_workload - destroy a vGPU workload |
| 1193 | − * @vgpu: a vGPU | |
| 1196 | + * @workload: workload to destroy | |
| 1194 | 1197 | * |
| 1195 | 1198 | * This function is called when destroy a vGPU workload. |
| 1196 | 1199 | * |
| @@ -1282,6 +1285,7 @@ static int prepare_mm(struct intel_vgpu_workload *workload) · 85 unmodified lines | ||
| 1282 | 1285 | /** |
| 1283 | 1286 | * intel_vgpu_create_workload - create a vGPU workload |
| 1284 | 1287 | * @vgpu: a vGPU |
| 1288 | + * @ring_id: ring index | |
| 1285 | 1289 | * @desc: a guest context descriptor |
| 1286 | 1290 | * |
| 1287 | 1291 | * This function is called when creating a vGPU workload. |
| @@ -1953,7 +1953,10 @@ static int i915_context_status(struct seq_file *m, void *unused) · 1952 unmodified lines | ||
| 1953 | 1953 | return ret; |
| 1954 | 1954 | |
| 1955 | 1955 | list_for_each_entry(ctx, &dev_priv->contexts.list, link) { |
| 1956 | − seq_printf(m, "HW context %u ", ctx->hw_id); | |
| 1956 | + seq_puts(m, "HW context "); | |
| 1957 | + if (!list_empty(&ctx->hw_id_link)) | |
| 1958 | + seq_printf(m, "%x [pin %u]", ctx->hw_id, | |
| 1959 | + atomic_read(&ctx->hw_id_pin_count)); | |
| 1957 | 1960 | if (ctx->pid) { |
| 1958 | 1961 | struct task_struct *task; |
| 1959 | 1962 | |
| @@ -2708,7 +2711,9 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) · 748 unmodified lines | ||
| 2708 | 2711 | intel_runtime_pm_get(dev_priv); |
| 2709 | 2712 | |
| 2710 | 2713 | mutex_lock(&dev_priv->psr.lock); |
| 2711 | − seq_printf(m, "Enabled: %s\n", yesno((bool)dev_priv->psr.enabled)); | |
| 2714 | + seq_printf(m, "PSR mode: %s\n", | |
| 2715 | + dev_priv->psr.psr2_enabled ? "PSR2" : "PSR1"); | |
| 2716 | + seq_printf(m, "Enabled: %s\n", yesno(dev_priv->psr.enabled)); | |
| 2712 | 2717 | seq_printf(m, "Busy frontbuffer bits: 0x%03x\n", |
| 2713 | 2718 | dev_priv->psr.busy_frontbuffer_bits); |
| 2714 | 2719 | |
| @@ -2735,7 +2740,7 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) · 20 unmodified lines | ||
| 2735 | 2740 | psr_source_status(dev_priv, m); |
| 2736 | 2741 | mutex_unlock(&dev_priv->psr.lock); |
| 2737 | 2742 | |
| 2738 | − if (READ_ONCE(dev_priv->psr.debug)) { | |
| 2743 | + if (READ_ONCE(dev_priv->psr.debug) & I915_PSR_DEBUG_IRQ) { | |
| 2739 | 2744 | seq_printf(m, "Last attempted entry at: %lld\n", |
| 2740 | 2745 | dev_priv->psr.last_entry_attempt); |
| 2741 | 2746 | seq_printf(m, "Last exit at: %lld\n", |
| @@ -2750,17 +2755,32 @@ static int · 8 unmodified lines | ||
| 2750 | 2755 | i915_edp_psr_debug_set(void *data, u64 val) |
| 2751 | 2756 | { |
| 2752 | 2757 | struct drm_i915_private *dev_priv = data; |
| 2758 | + struct drm_modeset_acquire_ctx ctx; | |
| 2759 | + int ret; | |
| 2753 | 2760 | |
| 2754 | 2761 | if (!CAN_PSR(dev_priv)) |
| 2755 | 2762 | return -ENODEV; |
| 2756 | 2763 | |
| 2757 | − DRM_DEBUG_KMS("PSR debug %s\n", enableddisabled(val)); | |
| 2764 | + DRM_DEBUG_KMS("Setting PSR debug to %llx\n", val); | |
| 2758 | 2765 | |
| 2759 | 2766 | intel_runtime_pm_get(dev_priv); |
| 2760 | − intel_psr_irq_control(dev_priv, !!val); | |
| 2767 | + | |
| 2768 | + drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); | |
| 2769 | + | |
| 2770 | +retry: | |
| 2771 | + ret = intel_psr_set_debugfs_mode(dev_priv, &ctx, val); | |
| 2772 | + if (ret == -EDEADLK) { | |
| 2773 | + ret = drm_modeset_backoff(&ctx); | |
| 2774 | + if (!ret) | |
| 2775 | + goto retry; | |
| 2776 | + } | |
| 2777 | + | |
| 2778 | + drm_modeset_drop_locks(&ctx); | |
| 2779 | + drm_modeset_acquire_fini(&ctx); | |
| 2780 | + | |
| 2761 | 2781 | intel_runtime_pm_put(dev_priv); |
| 2762 | 2782 | |
| 2763 | − return 0; | |
| 2783 | + return ret; | |
| 2764 | 2784 | } |
| 2765 | 2785 | |
| 2766 | 2786 | static int |
| @@ -2845,10 +2865,10 @@ static int i915_power_domain_info(struct seq_file *m, void *unused) · 78 unmodified lines | ||
| 2845 | 2865 | enum intel_display_power_domain power_domain; |
| 2846 | 2866 | |
| 2847 | 2867 | power_well = &power_domains->power_wells[i]; |
| 2848 | − seq_printf(m, "%-25s %d\n", power_well->name, | |
| 2868 | + seq_printf(m, "%-25s %d\n", power_well->desc->name, | |
| 2849 | 2869 | power_well->count); |
| 2850 | 2870 | |
| 2851 | − for_each_power_domain(power_domain, power_well->domains) | |
| 2871 | + for_each_power_domain(power_domain, power_well->desc->domains) | |
| 2852 | 2872 | seq_printf(m, " %-23s %d\n", |
| 2853 | 2873 | intel_display_power_domain_str(power_domain), |
| 2854 | 2874 | power_domains->domain_use_count[power_domain]); |
| @@ -4114,13 +4134,17 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_ring_test_irq_fops, · 1259 unmodified lines | ||
| 4114 | 4134 | #define DROP_FREED BIT(4) |
| 4115 | 4135 | #define DROP_SHRINK_ALL BIT(5) |
| 4116 | 4136 | #define DROP_IDLE BIT(6) |
| 4137 | +#define DROP_RESET_ACTIVE BIT(7) | |
| 4138 | +#define DROP_RESET_SEQNO BIT(8) | |
| 4117 | 4139 | #define DROP_ALL (DROP_UNBOUND | \ |
| 4118 | 4140 | DROP_BOUND | \ |
| 4119 | 4141 | DROP_RETIRE | \ |
| 4120 | 4142 | DROP_ACTIVE | \ |
| 4121 | 4143 | DROP_FREED | \ |
| 4122 | 4144 | DROP_SHRINK_ALL |\ |
| 4123 | − DROP_IDLE) | |
| 4145 | + DROP_IDLE | \ | |
| 4146 | + DROP_RESET_ACTIVE | \ | |
| 4147 | + DROP_RESET_SEQNO) | |
| 4124 | 4148 | static int |
| 4125 | 4149 | i915_drop_caches_get(void *data, u64 *val) |
| 4126 | 4150 | { |
| @@ -4132,53 +4156,69 @@ i915_drop_caches_get(void *data, u64 *val) · 5 unmodified lines | ||
| 4132 | 4156 | static int |
| 4133 | 4157 | i915_drop_caches_set(void *data, u64 val) |
| 4134 | 4158 | { |
| 4135 | − struct drm_i915_private *dev_priv = data; | |
| 4136 | − struct drm_device *dev = &dev_priv->drm; | |
| 4159 | + struct drm_i915_private *i915 = data; | |
| 4137 | 4160 | int ret = 0; |
| 4138 | 4161 | |
| 4139 | 4162 | DRM_DEBUG("Dropping caches: 0x%08llx [0x%08llx]\n", |
| 4140 | 4163 | val, val & DROP_ALL); |
| 4141 | 4164 | |
| 4165 | + if (val & DROP_RESET_ACTIVE && !intel_engines_are_idle(i915)) | |
| 4166 | + i915_gem_set_wedged(i915); | |
| 4167 | + | |
| 4142 | 4168 | /* No need to check and wait for gpu resets, only libdrm auto-restarts |
| 4143 | 4169 | * on ioctls on -EAGAIN. */ |
| 4144 | − if (val & (DROP_ACTIVE | DROP_RETIRE)) { | |
| 4145 | − ret = mutex_lock_interruptible(&dev->struct_mutex); | |
| 4170 | + if (val & (DROP_ACTIVE | DROP_RETIRE | DROP_RESET_SEQNO)) { | |
| 4171 | + ret = mutex_lock_interruptible(&i915->drm.struct_mutex); | |
| 4146 | 4172 | if (ret) |
| 4147 | 4173 | return ret; |
| 4148 | 4174 | |
| 4149 | 4175 | if (val & DROP_ACTIVE) |
| 4150 | − ret = i915_gem_wait_for_idle(dev_priv, | |
| 4176 | + ret = i915_gem_wait_for_idle(i915, | |
| 4151 | 4177 | I915_WAIT_INTERRUPTIBLE | |
| 4152 | 4178 | I915_WAIT_LOCKED, |
| 4153 | 4179 | MAX_SCHEDULE_TIMEOUT); |
| 4154 | 4180 | |
| 4181 | + if (val & DROP_RESET_SEQNO) { | |
| 4182 | + intel_runtime_pm_get(i915); | |
| 4183 | + ret = i915_gem_set_global_seqno(&i915->drm, 1); | |
| 4184 | + intel_runtime_pm_put(i915); | |
| 4185 | + } | |
| 4186 | + | |
| 4155 | 4187 | if (val & DROP_RETIRE) |
| 4156 | − i915_retire_requests(dev_priv); | |
| 4188 | + i915_retire_requests(i915); | |
| 4157 | 4189 | |
| 4158 | − mutex_unlock(&dev->struct_mutex); | |
| 4190 | + mutex_unlock(&i915->drm.struct_mutex); | |
| 4191 | + } | |
| 4192 | + | |
| 4193 | + if (val & DROP_RESET_ACTIVE && | |
| 4194 | + i915_terminally_wedged(&i915->gpu_error)) { | |
| 4195 | + i915_handle_error(i915, ALL_ENGINES, 0, NULL); | |
| 4196 | + wait_on_bit(&i915->gpu_error.flags, | |
| 4197 | + I915_RESET_HANDOFF, | |
| 4198 | + TASK_UNINTERRUPTIBLE); | |
| 4159 | 4199 | } |
| 4160 | 4200 | |
| 4161 | 4201 | fs_reclaim_acquire(GFP_KERNEL); |
| 4162 | 4202 | if (val & DROP_BOUND) |
| 4163 | − i915_gem_shrink(dev_priv, LONG_MAX, NULL, I915_SHRINK_BOUND); | |
| 4203 | + i915_gem_shrink(i915, LONG_MAX, NULL, I915_SHRINK_BOUND); | |
| 4164 | 4204 | |
| 4165 | 4205 | if (val & DROP_UNBOUND) |
| 4166 | − i915_gem_shrink(dev_priv, LONG_MAX, NULL, I915_SHRINK_UNBOUND); | |
| 4206 | + i915_gem_shrink(i915, LONG_MAX, NULL, I915_SHRINK_UNBOUND); | |
| 4167 | 4207 | |
| 4168 | 4208 | if (val & DROP_SHRINK_ALL) |
| 4169 | − i915_gem_shrink_all(dev_priv); | |
| 4209 | + i915_gem_shrink_all(i915); | |
| 4170 | 4210 | fs_reclaim_release(GFP_KERNEL); |
| 4171 | 4211 | |
| 4172 | 4212 | if (val & DROP_IDLE) { |
| 4173 | 4213 | do { |
| 4174 | − if (READ_ONCE(dev_priv->gt.active_requests)) | |
| 4175 | − flush_delayed_work(&dev_priv->gt.retire_work); | |
| 4176 | − drain_delayed_work(&dev_priv->gt.idle_work); | |
| 4177 | − } while (READ_ONCE(dev_priv->gt.awake)); | |
| 4214 | + if (READ_ONCE(i915->gt.active_requests)) | |
| 4215 | + flush_delayed_work(&i915->gt.retire_work); | |
| 4216 | + drain_delayed_work(&i915->gt.idle_work); | |
| 4217 | + } while (READ_ONCE(i915->gt.awake)); | |
| 4178 | 4218 | } |
| 4179 | 4219 | |
| 4180 | 4220 | if (val & DROP_FREED) |
| 4181 | − i915_gem_drain_freed_objects(dev_priv); | |
| 4221 | + i915_gem_drain_freed_objects(i915); | |
| 4182 | 4222 | |
| 4183 | 4223 | return ret; |
| 4184 | 4224 | } |
| @@ -373,7 +373,7 @@ static int i915_getparam_ioctl(struct drm_device *dev, void *data, · 372 unmodified lines | ||
| 373 | 373 | value = 2; |
| 374 | 374 | break; |
| 375 | 375 | case I915_PARAM_HAS_RESOURCE_STREAMER: |
| 376 | − value = HAS_RESOURCE_STREAMER(dev_priv); | |
| 376 | + value = 0; | |
| 377 | 377 | break; |
| 378 | 378 | case I915_PARAM_HAS_POOLED_EU: |
| 379 | 379 | value = HAS_POOLED_EU(dev_priv); |
| @@ -441,6 +441,9 @@ static int i915_getparam_ioctl(struct drm_device *dev, void *data, · 61 unmodified lines | ||
| 441 | 441 | case I915_PARAM_CS_TIMESTAMP_FREQUENCY: |
| 442 | 442 | value = 1000 * INTEL_INFO(dev_priv)->cs_timestamp_frequency_khz; |
| 443 | 443 | break; |
| 444 | + case I915_PARAM_MMAP_GTT_COHERENT: | |
| 445 | + value = INTEL_INFO(dev_priv)->has_coherent_ggtt; | |
| 446 | + break; | |
| 444 | 447 | default: |
| 445 | 448 | DRM_DEBUG("Unknown parameter %d\n", param->param); |
| 446 | 449 | return -EINVAL; |
| @@ -709,7 +712,7 @@ cleanup_irq: · 262 unmodified lines | ||
| 709 | 712 | intel_teardown_gmbus(dev_priv); |
| 710 | 713 | cleanup_csr: |
| 711 | 714 | intel_csr_ucode_fini(dev_priv); |
| 712 | − intel_power_domains_fini(dev_priv); | |
| 715 | + intel_power_domains_fini_hw(dev_priv); | |
| 713 | 716 | vga_switcheroo_unregister_client(pdev); |
| 714 | 717 | cleanup_vga_client: |
| 715 | 718 | vga_client_register(pdev, NULL, NULL, NULL); |
| @@ -867,7 +870,6 @@ static void intel_detect_preproduction_hw(struct drm_i915_private *dev_priv) · 151 unmodified lines | ||
| 867 | 870 | /** |
| 868 | 871 | * i915_driver_init_early - setup state not requiring device access |
| 869 | 872 | * @dev_priv: device private |
| 870 | − * @ent: the matching pci_device_id | |
| 871 | 873 | * |
| 872 | 874 | * Initialize everything that is a "SW-only" state, that is state not |
| 873 | 875 | * requiring accessing the device or exposing the driver via kernel internal |
| @@ -875,25 +877,13 @@ static void intel_detect_preproduction_hw(struct drm_i915_private *dev_priv) · 1 unmodified line | ||
| 875 | 877 | * system memory allocation, setting up device specific attributes and |
| 876 | 878 | * function hooks not requiring accessing the device. |
| 877 | 879 | */ |
| 878 | −static int i915_driver_init_early(struct drm_i915_private *dev_priv, | |
| 879 | − const struct pci_device_id *ent) | |
| 880 | +static int i915_driver_init_early(struct drm_i915_private *dev_priv) | |
| 880 | 881 | { |
| 881 | − const struct intel_device_info *match_info = | |
| 882 | − (struct intel_device_info *)ent->driver_data; | |
| 883 | − struct intel_device_info *device_info; | |
| 884 | 882 | int ret = 0; |
| 885 | 883 | |
| 886 | 884 | if (i915_inject_load_failure()) |
| 887 | 885 | return -ENODEV; |
| 888 | 886 | |
| 889 | − /* Setup the write-once "constant" device info */ | |
| 890 | − device_info = mkwrite_device_info(dev_priv); | |
| 891 | − memcpy(device_info, match_info, sizeof(*device_info)); | |
| 892 | − device_info->device_id = dev_priv->drm.pdev->device; | |
| 893 | − | |
| 894 | − BUILD_BUG_ON(INTEL_MAX_PLATFORMS > | |
| 895 | − sizeof(device_info->platform_mask) * BITS_PER_BYTE); | |
| 896 | − BUG_ON(device_info->gen > sizeof(device_info->gen_mask) * BITS_PER_BYTE); | |
| 897 | 887 | spin_lock_init(&dev_priv->irq_lock); |
| 898 | 888 | spin_lock_init(&dev_priv->gpu_error.lock); |
| 899 | 889 | mutex_init(&dev_priv->backlight_lock); |
| @@ -921,7 +911,9 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, · 21 unmodified lines | ||
| 921 | 911 | intel_uc_init_early(dev_priv); |
| 922 | 912 | intel_pm_setup(dev_priv); |
| 923 | 913 | intel_init_dpio(dev_priv); |
| 924 | − intel_power_domains_init(dev_priv); | |
| 914 | + ret = intel_power_domains_init(dev_priv); | |
| 915 | + if (ret < 0) | |
| 916 | + goto err_uc; | |
| 925 | 917 | intel_irq_init(dev_priv); |
| 926 | 918 | intel_hangcheck_init(dev_priv); |
| 927 | 919 | intel_init_display_hooks(dev_priv); |
| @@ -933,6 +925,9 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, · 5 unmodified lines | ||
| 933 | 925 | |
| 934 | 926 | return 0; |
| 935 | 927 | |
| 928 | +err_uc: | |
| 929 | + intel_uc_cleanup_early(dev_priv); | |
| 930 | + i915_gem_cleanup_early(dev_priv); | |
| 936 | 931 | err_workqueues: |
| 937 | 932 | i915_workqueues_cleanup(dev_priv); |
| 938 | 933 | err_engines: |
| @@ -947,6 +942,7 @@ err_engines: · 8 unmodified lines | ||
| 947 | 942 | static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv) |
| 948 | 943 | { |
| 949 | 944 | intel_irq_fini(dev_priv); |
| 945 | + intel_power_domains_cleanup(dev_priv); | |
| 950 | 946 | intel_uc_cleanup_early(dev_priv); |
| 951 | 947 | i915_gem_cleanup_early(dev_priv); |
| 952 | 948 | i915_workqueues_cleanup(dev_priv); |
| @@ -1272,6 +1268,9 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) · 319 unmodified lines | ||
| 1272 | 1268 | */ |
| 1273 | 1269 | if (INTEL_INFO(dev_priv)->num_pipes) |
| 1274 | 1270 | drm_kms_helper_poll_init(dev); |
| 1271 | + | |
| 1272 | + intel_power_domains_enable(dev_priv); | |
| 1273 | + intel_runtime_pm_enable(dev_priv); | |
| 1275 | 1274 | } |
| 1276 | 1275 | |
| 1277 | 1276 | /** |
| @@ -1280,6 +1279,9 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) · 2 unmodified lines | ||
| 1280 | 1279 | */ |
| 1281 | 1280 | static void i915_driver_unregister(struct drm_i915_private *dev_priv) |
| 1282 | 1281 | { |
| 1282 | + intel_runtime_pm_disable(dev_priv); | |
| 1283 | + intel_power_domains_disable(dev_priv); | |
| 1284 | + | |
| 1283 | 1285 | intel_fbdev_unregister(dev_priv); |
| 1284 | 1286 | intel_audio_deinit(dev_priv); |
| 1285 | 1287 | |
| @@ -1316,6 +1318,52 @@ static void i915_welcome_messages(struct drm_i915_private *dev_priv) · 30 unmodified lines | ||
| 1316 | 1318 | DRM_INFO("DRM_I915_DEBUG enabled\n"); |
| 1317 | 1319 | if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) |
| 1318 | 1320 | DRM_INFO("DRM_I915_DEBUG_GEM enabled\n"); |
| 1321 | + if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)) | |
| 1322 | + DRM_INFO("DRM_I915_DEBUG_RUNTIME_PM enabled\n"); | |
| 1323 | +} | |
| 1324 | + | |
| 1325 | +static struct drm_i915_private * | |
| 1326 | +i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent) | |
| 1327 | +{ | |
| 1328 | + const struct intel_device_info *match_info = | |
| 1329 | + (struct intel_device_info *)ent->driver_data; | |
| 1330 | + struct intel_device_info *device_info; | |
| 1331 | + struct drm_i915_private *i915; | |
| 1332 | + | |
| 1333 | + i915 = kzalloc(sizeof(*i915), GFP_KERNEL); | |
| 1334 | + if (!i915) | |
| 1335 | + return NULL; | |
| 1336 | + | |
| 1337 | + if (drm_dev_init(&i915->drm, &driver, &pdev->dev)) { | |
| 1338 | + kfree(i915); | |
| 1339 | + return NULL; | |
| 1340 | + } | |
| 1341 | + | |
| 1342 | + i915->drm.pdev = pdev; | |
| 1343 | + i915->drm.dev_private = i915; | |
| 1344 | + pci_set_drvdata(pdev, &i915->drm); | |
| 1345 | + | |
| 1346 | + /* Setup the write-once "constant" device info */ | |
| 1347 | + device_info = mkwrite_device_info(i915); | |
| 1348 | + memcpy(device_info, match_info, sizeof(*device_info)); | |
| 1349 | + device_info->device_id = pdev->device; | |
| 1350 | + | |
| 1351 | + BUILD_BUG_ON(INTEL_MAX_PLATFORMS > | |
| 1352 | + sizeof(device_info->platform_mask) * BITS_PER_BYTE); | |
| 1353 | + BUG_ON(device_info->gen > sizeof(device_info->gen_mask) * BITS_PER_BYTE); | |
| 1354 | + | |
| 1355 | + return i915; | |
| 1356 | +} | |
| 1357 | + | |
| 1358 | +static void i915_driver_destroy(struct drm_i915_private *i915) | |
| 1359 | +{ | |
| 1360 | + struct pci_dev *pdev = i915->drm.pdev; | |
| 1361 | + | |
| 1362 | + drm_dev_fini(&i915->drm); | |
| 1363 | + kfree(i915); | |
| 1364 | + | |
| 1365 | + /* And make sure we never chase our dangling pointer from pci_dev */ | |
| 1366 | + pci_set_drvdata(pdev, NULL); | |
| 1319 | 1367 | } |
| 1320 | 1368 | |
| 1321 | 1369 | /** |
| @@ -1340,38 +1388,19 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) · 18 unmodified lines | ||
| 1340 | 1388 | if (!i915_modparams.nuclear_pageflip && match_info->gen < 5) |
| 1341 | 1389 | driver.driver_features &= ~DRIVER_ATOMIC; |
| 1342 | 1390 | |
| 1343 | − ret = -ENOMEM; | |
| 1344 | − dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); | |
| 1345 | − if (dev_priv) | |
| 1346 | − ret = drm_dev_init(&dev_priv->drm, &driver, &pdev->dev); | |
| 1347 | − if (ret) { | |
| 1348 | − DRM_DEV_ERROR(&pdev->dev, "allocation failed\n"); | |
| 1349 | − goto out_free; | |
| 1350 | − } | |
| 1351 | − | |
| 1352 | − dev_priv->drm.pdev = pdev; | |
| 1353 | − dev_priv->drm.dev_private = dev_priv; | |
| 1391 | + dev_priv = i915_driver_create(pdev, ent); | |
| 1392 | + if (!dev_priv) | |
| 1393 | + return -ENOMEM; | |
| 1354 | 1394 | |
| 1355 | 1395 | ret = pci_enable_device(pdev); |
| 1356 | 1396 | if (ret) |
| 1357 | 1397 | goto out_fini; |
| 1358 | 1398 | |
| 1359 | − pci_set_drvdata(pdev, &dev_priv->drm); | |
| 1360 | − /* | |
| 1361 | − * Disable the system suspend direct complete optimization, which can | |
| 1362 | − * leave the device suspended skipping the driver's suspend handlers | |
| 1363 | − * if the device was already runtime suspended. This is needed due to | |
| 1364 | − * the difference in our runtime and system suspend sequence and | |
| 1365 | − * becaue the HDA driver may require us to enable the audio power | |
| 1366 | − * domain during system suspend. | |
| 1367 | − */ | |
| 1368 | − dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NEVER_SKIP); | |
| 1369 | − | |
| 1370 | − ret = i915_driver_init_early(dev_priv, ent); | |
| 1399 | + ret = i915_driver_init_early(dev_priv); | |
| 1371 | 1400 | if (ret < 0) |
| 1372 | 1401 | goto out_pci_disable; |
| 1373 | 1402 | |
| 1374 | − intel_runtime_pm_get(dev_priv); | |
| 1403 | + disable_rpm_wakeref_asserts(dev_priv); | |
| 1375 | 1404 | |
| 1376 | 1405 | ret = i915_driver_init_mmio(dev_priv); |
| 1377 | 1406 | if (ret < 0) |
| @@ -1399,11 +1428,9 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) · 21 unmodified lines | ||
| 1399 | 1428 | |
| 1400 | 1429 | i915_driver_register(dev_priv); |
| 1401 | 1430 | |
| 1402 | − intel_runtime_pm_enable(dev_priv); | |
| 1403 | − | |
| 1404 | 1431 | intel_init_ipc(dev_priv); |
| 1405 | 1432 | |
| 1406 | − intel_runtime_pm_put(dev_priv); | |
| 1433 | + enable_rpm_wakeref_asserts(dev_priv); | |
| 1407 | 1434 | |
| 1408 | 1435 | i915_welcome_messages(dev_priv); |
| 1409 | 1436 | |
| @@ -1414,16 +1441,13 @@ out_cleanup_hw: · 4 unmodified lines | ||
| 1414 | 1441 | out_cleanup_mmio: |
| 1415 | 1442 | i915_driver_cleanup_mmio(dev_priv); |
| 1416 | 1443 | out_runtime_pm_put: |
| 1417 | − intel_runtime_pm_put(dev_priv); | |
| 1444 | + enable_rpm_wakeref_asserts(dev_priv); | |
| 1418 | 1445 | i915_driver_cleanup_early(dev_priv); |
| 1419 | 1446 | out_pci_disable: |
| 1420 | 1447 | pci_disable_device(pdev); |
| 1421 | 1448 | out_fini: |
| 1422 | 1449 | i915_load_error(dev_priv, "Device initialization failed (%d)\n", ret); |
| 1423 | − drm_dev_fini(&dev_priv->drm); | |
| 1424 | −out_free: | |
| 1425 | − kfree(dev_priv); | |
| 1426 | − pci_set_drvdata(pdev, NULL); | |
| 1450 | + i915_driver_destroy(dev_priv); | |
| 1427 | 1451 | return ret; |
| 1428 | 1452 | } |
| 1429 | 1453 | |
| @@ -1432,13 +1456,13 @@ void i915_driver_unload(struct drm_device *dev) · 2 unmodified lines | ||
| 1432 | 1456 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 1433 | 1457 | struct pci_dev *pdev = dev_priv->drm.pdev; |
| 1434 | 1458 | |
| 1459 | + disable_rpm_wakeref_asserts(dev_priv); | |
| 1460 | + | |
| 1435 | 1461 | i915_driver_unregister(dev_priv); |
| 1436 | 1462 | |
| 1437 | 1463 | if (i915_gem_suspend(dev_priv)) |
| 1438 | 1464 | DRM_ERROR("failed to idle hardware; continuing to unload!\n"); |
| 1439 | 1465 | |
| 1440 | − intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); | |
| 1441 | − | |
| 1442 | 1466 | drm_atomic_helper_shutdown(dev); |
| 1443 | 1467 | |
| 1444 | 1468 | intel_gvt_cleanup(dev_priv); |
| @@ -1459,12 +1483,14 @@ void i915_driver_unload(struct drm_device *dev) · 14 unmodified lines | ||
| 1459 | 1483 | i915_gem_fini(dev_priv); |
| 1460 | 1484 | intel_fbc_cleanup_cfb(dev_priv); |
| 1461 | 1485 | |
| 1462 | − intel_power_domains_fini(dev_priv); | |
| 1486 | + intel_power_domains_fini_hw(dev_priv); | |
| 1463 | 1487 | |
| 1464 | 1488 | i915_driver_cleanup_hw(dev_priv); |
| 1465 | 1489 | i915_driver_cleanup_mmio(dev_priv); |
| 1466 | 1490 | |
| 1467 | − intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); | |
| 1491 | + enable_rpm_wakeref_asserts(dev_priv); | |
| 1492 | + | |
| 1493 | + WARN_ON(atomic_read(&dev_priv->runtime_pm.wakeref_count)); | |
| 1468 | 1494 | } |
| 1469 | 1495 | |
| 1470 | 1496 | static void i915_driver_release(struct drm_device *dev) |
| @@ -1472,9 +1498,7 @@ static void i915_driver_release(struct drm_device *dev) · 1 unmodified line | ||
| 1472 | 1498 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 1473 | 1499 | |
| 1474 | 1500 | i915_driver_cleanup_early(dev_priv); |
| 1475 | − drm_dev_fini(&dev_priv->drm); | |
| 1476 | − | |
| 1477 | − kfree(dev_priv); | |
| 1501 | + i915_driver_destroy(dev_priv); | |
| 1478 | 1502 | } |
| 1479 | 1503 | |
| 1480 | 1504 | static int i915_driver_open(struct drm_device *dev, struct drm_file *file) |
| @@ -1573,7 +1597,7 @@ static int i915_drm_suspend(struct drm_device *dev) · 92 unmodified lines | ||
| 1573 | 1597 | |
| 1574 | 1598 | /* We do a lot of poking in a lot of registers, make sure they work |
| 1575 | 1599 | * properly. */ |
| 1576 | − intel_display_set_init_power(dev_priv, true); | |
| 1600 | + intel_power_domains_disable(dev_priv); | |
| 1577 | 1601 | |
| 1578 | 1602 | drm_kms_helper_poll_disable(dev); |
| 1579 | 1603 | |
| @@ -1610,6 +1634,18 @@ static int i915_drm_suspend(struct drm_device *dev) · 30 unmodified lines | ||
| 1610 | 1634 | return 0; |
| 1611 | 1635 | } |
| 1612 | 1636 | |
| 1637 | +static enum i915_drm_suspend_mode | |
| 1638 | +get_suspend_mode(struct drm_i915_private *dev_priv, bool hibernate) | |
| 1639 | +{ | |
| 1640 | + if (hibernate) | |
| 1641 | + return I915_DRM_SUSPEND_HIBERNATE; | |
| 1642 | + | |
| 1643 | + if (suspend_to_idle(dev_priv)) | |
| 1644 | + return I915_DRM_SUSPEND_IDLE; | |
| 1645 | + | |
| 1646 | + return I915_DRM_SUSPEND_MEM; | |
| 1647 | +} | |
| 1648 | + | |
| 1613 | 1649 | static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation) |
| 1614 | 1650 | { |
| 1615 | 1651 | struct drm_i915_private *dev_priv = to_i915(dev); |
| @@ -1620,21 +1656,10 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation) · 4 unmodified lines | ||
| 1620 | 1656 | |
| 1621 | 1657 | i915_gem_suspend_late(dev_priv); |
| 1622 | 1658 | |
| 1623 | − intel_display_set_init_power(dev_priv, false); | |
| 1624 | 1659 | intel_uncore_suspend(dev_priv); |
| 1625 | 1660 | |
| 1626 | − /* | |
| 1627 | − * In case of firmware assisted context save/restore don't manually | |
| 1628 | − * deinit the power domains. This also means the CSR/DMC firmware will | |
| 1629 | − * stay active, it will power down any HW resources as required and | |
| 1630 | − * also enable deeper system power states that would be blocked if the | |
| 1631 | − * firmware was inactive. | |
| 1632 | − */ | |
| 1633 | − if (IS_GEN9_LP(dev_priv) || hibernation || !suspend_to_idle(dev_priv) || | |
| 1634 | − dev_priv->csr.dmc_payload == NULL) { | |
| 1635 | − intel_power_domains_suspend(dev_priv); | |
| 1636 | − dev_priv->power_domains_suspended = true; | |
| 1637 | − } | |
| 1661 | + intel_power_domains_suspend(dev_priv, | |
| 1662 | + get_suspend_mode(dev_priv, hibernation)); | |
| 1638 | 1663 | |
| 1639 | 1664 | ret = 0; |
| 1640 | 1665 | if (IS_GEN9_LP(dev_priv)) |
| @@ -1646,10 +1671,7 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation) · 5 unmodified lines | ||
| 1646 | 1671 | |
| 1647 | 1672 | if (ret) { |
| 1648 | 1673 | DRM_ERROR("Suspend complete failed: %d\n", ret); |
| 1649 | − if (dev_priv->power_domains_suspended) { | |
| 1650 | − intel_power_domains_init_hw(dev_priv, true); | |
| 1651 | − dev_priv->power_domains_suspended = false; | |
| 1652 | − } | |
| 1674 | + intel_power_domains_resume(dev_priv); | |
| 1653 | 1675 | |
| 1654 | 1676 | goto out; |
| 1655 | 1677 | } |
| @@ -1755,7 +1777,7 @@ static int i915_drm_resume(struct drm_device *dev) · 99 unmodified lines | ||
| 1755 | 1777 | /* |
| 1756 | 1778 | * ... but also need to make sure that hotplug processing |
| 1757 | 1779 | * doesn't cause havoc. Like in the driver load code we don't |
| 1758 | − * bother with the tiny race here where we might loose hotplug | |
| 1780 | + * bother with the tiny race here where we might lose hotplug | |
| 1759 | 1781 | * notifications. |
| 1760 | 1782 | * */ |
| 1761 | 1783 | intel_hpd_init(dev_priv); |
| @@ -1766,6 +1788,8 @@ static int i915_drm_resume(struct drm_device *dev) · 4 unmodified lines | ||
| 1766 | 1788 | |
| 1767 | 1789 | intel_opregion_notify_adapter(dev_priv, PCI_D0); |
| 1768 | 1790 | |
| 1791 | + intel_power_domains_enable(dev_priv); | |
| 1792 | + | |
| 1769 | 1793 | enable_rpm_wakeref_asserts(dev_priv); |
| 1770 | 1794 | |
| 1771 | 1795 | return 0; |
| @@ -1800,7 +1824,7 @@ static int i915_drm_resume_early(struct drm_device *dev) · 28 unmodified lines | ||
| 1800 | 1824 | ret = pci_set_power_state(pdev, PCI_D0); |
| 1801 | 1825 | if (ret) { |
| 1802 | 1826 | DRM_ERROR("failed to set PCI D0 power state (%d)\n", ret); |
| 1803 | − goto out; | |
| 1827 | + return ret; | |
| 1804 | 1828 | } |
| 1805 | 1829 | |
| 1806 | 1830 | /* |
| @@ -1816,10 +1840,8 @@ static int i915_drm_resume_early(struct drm_device *dev) · 9 unmodified lines | ||
| 1816 | 1840 | * depend on the device enable refcount we can't anyway depend on them |
| 1817 | 1841 | * disabling/enabling the device. |
| 1818 | 1842 | */ |
| 1819 | − if (pci_enable_device(pdev)) { | |
| 1820 | − ret = -EIO; | |
| 1821 | − goto out; | |
| 1822 | − } | |
| 1843 | + if (pci_enable_device(pdev)) | |
| 1844 | + return -EIO; | |
| 1823 | 1845 | |
| 1824 | 1846 | pci_set_master(pdev); |
| 1825 | 1847 | |
| @@ -1842,18 +1864,12 @@ static int i915_drm_resume_early(struct drm_device *dev) · 16 unmodified lines | ||
| 1842 | 1864 | |
| 1843 | 1865 | intel_uncore_sanitize(dev_priv); |
| 1844 | 1866 | |
| 1845 | − if (dev_priv->power_domains_suspended) | |
| 1846 | − intel_power_domains_init_hw(dev_priv, true); | |
| 1847 | − else | |
| 1848 | − intel_display_set_init_power(dev_priv, true); | |
| 1867 | + intel_power_domains_resume(dev_priv); | |
| 1849 | 1868 | |
| 1850 | 1869 | intel_engines_sanitize(dev_priv); |
| 1851 | 1870 | |
| 1852 | 1871 | enable_rpm_wakeref_asserts(dev_priv); |
| 1853 | 1872 | |
| 1854 | −out: | |
| 1855 | − dev_priv->power_domains_suspended = false; | |
| 1856 | − | |
| 1857 | 1873 | return ret; |
| 1858 | 1874 | } |
| 1859 | 1875 | |
| @@ -1915,7 +1931,6 @@ void i915_reset(struct drm_i915_private *i915, · 55 unmodified lines | ||
| 1915 | 1931 | dev_notice(i915->drm.dev, "Resetting chip for %s\n", reason); |
| 1916 | 1932 | error->reset_count++; |
| 1917 | 1933 | |
| 1918 | − disable_irq(i915->drm.irq); | |
| 1919 | 1934 | ret = i915_gem_reset_prepare(i915); |
| 1920 | 1935 | if (ret) { |
| 1921 | 1936 | dev_err(i915->drm.dev, "GPU recovery failed\n"); |
| @@ -1977,8 +1992,6 @@ void i915_reset(struct drm_i915_private *i915, · 55 unmodified lines | ||
| 1977 | 1992 | |
| 1978 | 1993 | finish: |
| 1979 | 1994 | i915_gem_reset_finish(i915); |
| 1980 | − enable_irq(i915->drm.irq); | |
| 1981 | − | |
| 1982 | 1995 | wakeup: |
| 1983 | 1996 | clear_bit(I915_RESET_HANDOFF, &error->flags); |
| 1984 | 1997 | wake_up_bit(&error->flags, I915_RESET_HANDOFF); |
| @@ -2073,6 +2086,7 @@ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg) · 88 unmodified lines | ||
| 2073 | 2086 | goto out; |
| 2074 | 2087 | |
| 2075 | 2088 | out: |
| 2089 | + intel_engine_cancel_stop_cs(engine); | |
| 2076 | 2090 | i915_gem_reset_finish_engine(engine); |
| 2077 | 2091 | return ret; |
| 2078 | 2092 | } |
| @@ -86,8 +86,8 @@ · 85 unmodified lines | ||
| 86 | 86 | |
| 87 | 87 | #define DRIVER_NAME "i915" |
| 88 | 88 | #define DRIVER_DESC "Intel Graphics" |
| 89 | −#define DRIVER_DATE "20180719" | |
| 90 | −#define DRIVER_TIMESTAMP 1532015279 | |
| 89 | +#define DRIVER_DATE "20180906" | |
| 90 | +#define DRIVER_TIMESTAMP 1536242083 | |
| 91 | 91 | |
| 92 | 92 | /* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and |
| 93 | 93 | * WARN_ON()) for hw state sanity checks to check for unexpected conditions |
| @@ -611,8 +611,18 @@ struct i915_drrs { · 517 unmodified lines | ||
| 611 | 611 | |
| 612 | 612 | struct i915_psr { |
| 613 | 613 | struct mutex lock; |
| 614 | + | |
| 615 | +#define I915_PSR_DEBUG_MODE_MASK 0x0f | |
| 616 | +#define I915_PSR_DEBUG_DEFAULT 0x00 | |
| 617 | +#define I915_PSR_DEBUG_DISABLE 0x01 | |
| 618 | +#define I915_PSR_DEBUG_ENABLE 0x02 | |
| 619 | +#define I915_PSR_DEBUG_FORCE_PSR1 0x03 | |
| 620 | +#define I915_PSR_DEBUG_IRQ 0x10 | |
| 621 | + | |
| 622 | + u32 debug; | |
| 614 | 623 | bool sink_support; |
| 615 | − struct intel_dp *enabled; | |
| 624 | + bool prepared, enabled; | |
| 625 | + struct intel_dp *dp; | |
| 616 | 626 | bool active; |
| 617 | 627 | struct work_struct work; |
| 618 | 628 | unsigned busy_frontbuffer_bits; |
| @@ -622,7 +632,6 @@ struct i915_psr { · 3 unmodified lines | ||
| 622 | 632 | bool alpm; |
| 623 | 633 | bool psr2_enabled; |
| 624 | 634 | u8 sink_sync_latency; |
| 625 | − bool debug; | |
| 626 | 635 | ktime_t last_entry_attempt; |
| 627 | 636 | ktime_t last_exit; |
| 628 | 637 | }; |
| @@ -867,14 +876,17 @@ struct i915_power_well_ops { · 238 unmodified lines | ||
| 867 | 876 | struct i915_power_well *power_well); |
| 868 | 877 | }; |
| 869 | 878 | |
| 879 | +struct i915_power_well_regs { | |
| 880 | + i915_reg_t bios; | |
| 881 | + i915_reg_t driver; | |
| 882 | + i915_reg_t kvmr; | |
| 883 | + i915_reg_t debug; | |
| 884 | +}; | |
| 885 | + | |
| 870 | 886 | /* Power well structure for haswell */ |
| 871 | −struct i915_power_well { | |
| 887 | +struct i915_power_well_desc { | |
| 872 | 888 | const char *name; |
| 873 | 889 | bool always_on; |
| 874 | − /* power well enable/disable usage count */ | |
| 875 | − int count; | |
| 876 | − /* cached hw enabled state */ | |
| 877 | − bool hw_enabled; | |
| 878 | 890 | u64 domains; |
| 879 | 891 | /* unique identifier for this power well */ |
| 880 | 892 | enum i915_power_well_id id; |
| @@ -883,10 +895,23 @@ struct i915_power_well { · 2 unmodified lines | ||
| 883 | 895 | * well specific. |
| 884 | 896 | */ |
| 885 | 897 | union { |
| 898 | + struct { | |
| 899 | + /* | |
| 900 | + * request/status flag index in the PUNIT power well | |
| 901 | + * control/status registers. | |
| 902 | + */ | |
| 903 | + u8 idx; | |
| 904 | + } vlv; | |
| 886 | 905 | struct { |
| 887 | 906 | enum dpio_phy phy; |
| 888 | 907 | } bxt; |
| 889 | 908 | struct { |
| 909 | + const struct i915_power_well_regs *regs; | |
| 910 | + /* | |
| 911 | + * request/status flag index in the power well | |
| 912 | + * constrol/status registers. | |
| 913 | + */ | |
| 914 | + u8 idx; | |
| 890 | 915 | /* Mask of pipes whose IRQ logic is backed by the pw */ |
| 891 | 916 | u8 irq_pipe_mask; |
| 892 | 917 | /* The pw is backing the VGA functionality */ |
| @@ -897,13 +922,21 @@ struct i915_power_well { · 4 unmodified lines | ||
| 897 | 922 | const struct i915_power_well_ops *ops; |
| 898 | 923 | }; |
| 899 | 924 | |
| 925 | +struct i915_power_well { | |
| 926 | + const struct i915_power_well_desc *desc; | |
| 927 | + /* power well enable/disable usage count */ | |
| 928 | + int count; | |
| 929 | + /* cached hw enabled state */ | |
| 930 | + bool hw_enabled; | |
| 931 | +}; | |
| 932 | + | |
| 900 | 933 | struct i915_power_domains { |
| 901 | 934 | /* |
| 902 | 935 | * Power wells needed for initialization at driver init and suspend |
| 903 | 936 | * time are on. They are kept on until after the first modeset. |
| 904 | 937 | */ |
| 905 | − bool init_power_on; | |
| 906 | 938 | bool initializing; |
| 939 | + bool display_core_suspended; | |
| 907 | 940 | int power_well_count; |
| 908 | 941 | |
| 909 | 942 | struct mutex lock; |
| @@ -1610,7 +1643,8 @@ struct drm_i915_private { · 700 unmodified lines | ||
| 1610 | 1643 | struct mutex gmbus_mutex; |
| 1611 | 1644 | |
| 1612 | 1645 | /** |
| 1613 | − * Base address of the gmbus and gpio block. | |
| 1646 | + * Base address of where the gmbus and gpio blocks are located (either | |
| 1647 | + * on PCH or on SoC for platforms without PCH). | |
| 1614 | 1648 | */ |
| 1615 | 1649 | uint32_t gpio_mmio_base; |
| 1616 | 1650 | |
| @@ -1632,7 +1666,6 @@ struct drm_i915_private { · 15 unmodified lines | ||
| 1632 | 1666 | struct intel_engine_cs *engine_class[MAX_ENGINE_CLASS + 1] |
| 1633 | 1667 | [MAX_ENGINE_INSTANCE + 1]; |
| 1634 | 1668 | |
| 1635 | − struct drm_dma_handle *status_page_dmah; | |
| 1636 | 1669 | struct resource mch_res; |
| 1637 | 1670 | |
| 1638 | 1671 | /* protects the irq masks */ |
| @@ -1828,6 +1861,7 @@ struct drm_i915_private { · 189 unmodified lines | ||
| 1828 | 1861 | struct mutex av_mutex; |
| 1829 | 1862 | |
| 1830 | 1863 | struct { |
| 1864 | + struct mutex mutex; | |
| 1831 | 1865 | struct list_head list; |
| 1832 | 1866 | struct llist_head free_list; |
| 1833 | 1867 | struct work_struct free_work; |
| @@ -1840,6 +1874,7 @@ struct drm_i915_private { · 6 unmodified lines | ||
| 1840 | 1874 | #define MAX_CONTEXT_HW_ID (1<<21) /* exclusive */ |
| 1841 | 1875 | #define MAX_GUC_CONTEXT_HW_ID (1 << 20) /* exclusive */ |
| 1842 | 1876 | #define GEN11_MAX_CONTEXT_HW_ID (1<<11) /* exclusive */ |
| 1877 | + struct list_head hw_id_list; | |
| 1843 | 1878 | } contexts; |
| 1844 | 1879 | |
| 1845 | 1880 | u32 fdi_rx_config; |
| @@ -2610,8 +2645,6 @@ intel_info(const struct drm_i915_private *dev_priv) · 764 unmodified lines | ||
| 2610 | 2645 | #define USES_GUC_SUBMISSION(dev_priv) intel_uc_is_using_guc_submission() |
| 2611 | 2646 | #define USES_HUC(dev_priv) intel_uc_is_using_huc() |
| 2612 | 2647 | |
| 2613 | −#define HAS_RESOURCE_STREAMER(dev_priv) ((dev_priv)->info.has_resource_streamer) | |
| 2614 | − | |
| 2615 | 2648 | #define HAS_POOLED_EU(dev_priv) ((dev_priv)->info.has_pooled_eu) |
| 2616 | 2649 | |
| 2617 | 2650 | #define INTEL_PCH_DEVICE_ID_MASK 0xff80 |
| @@ -2775,6 +2808,8 @@ extern void intel_irq_fini(struct drm_i915_private *dev_priv); · 157 unmodified lines | ||
| 2775 | 2808 | int intel_irq_install(struct drm_i915_private *dev_priv); |
| 2776 | 2809 | void intel_irq_uninstall(struct drm_i915_private *dev_priv); |
| 2777 | 2810 | |
| 2811 | +void i915_clear_error_registers(struct drm_i915_private *dev_priv); | |
| 2812 | + | |
| 2778 | 2813 | static inline bool intel_gvt_active(struct drm_i915_private *dev_priv) |
| 2779 | 2814 | { |
| 2780 | 2815 | return dev_priv->gvt; |
| @@ -802,6 +802,11 @@ void i915_gem_flush_ggtt_writes(struct drm_i915_private *dev_priv) · 801 unmodified lines | ||
| 802 | 802 | * that was!). |
| 803 | 803 | */ |
| 804 | 804 | |
| 805 | + wmb(); | |
| 806 | + | |
| 807 | + if (INTEL_INFO(dev_priv)->has_coherent_ggtt) | |
| 808 | + return; | |
| 809 | + | |
| 805 | 810 | i915_gem_chipset_flush(dev_priv); |
| 806 | 811 | |
| 807 | 812 | intel_runtime_pm_get(dev_priv); |
| @@ -1906,7 +1911,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, · 1098 unmodified lines | ||
| 1906 | 1911 | return 0; |
| 1907 | 1912 | } |
| 1908 | 1913 | |
| 1909 | −static unsigned int tile_row_pages(struct drm_i915_gem_object *obj) | |
| 1914 | +static unsigned int tile_row_pages(const struct drm_i915_gem_object *obj) | |
| 1910 | 1915 | { |
| 1911 | 1916 | return i915_gem_object_get_tile_row_size(obj) >> PAGE_SHIFT; |
| 1912 | 1917 | } |
| @@ -1965,7 +1970,7 @@ int i915_gem_mmap_gtt_version(void) · 52 unmodified lines | ||
| 1965 | 1970 | } |
| 1966 | 1971 | |
| 1967 | 1972 | static inline struct i915_ggtt_view |
| 1968 | −compute_partial_view(struct drm_i915_gem_object *obj, | |
| 1973 | +compute_partial_view(const struct drm_i915_gem_object *obj, | |
| 1969 | 1974 | pgoff_t page_offset, |
| 1970 | 1975 | unsigned int chunk) |
| 1971 | 1976 | { |
| @@ -2013,7 +2018,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf) · 41 unmodified lines | ||
| 2013 | 2018 | struct drm_device *dev = obj->base.dev; |
| 2014 | 2019 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 2015 | 2020 | struct i915_ggtt *ggtt = &dev_priv->ggtt; |
| 2016 | − bool write = !!(vmf->flags & FAULT_FLAG_WRITE); | |
| 2021 | + bool write = area->vm_flags & VM_WRITE; | |
| 2017 | 2022 | struct i915_vma *vma; |
| 2018 | 2023 | pgoff_t page_offset; |
| 2019 | 2024 | int ret; |
| @@ -2528,13 +2533,21 @@ static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) · 508 unmodified lines | ||
| 2528 | 2533 | gfp_t noreclaim; |
| 2529 | 2534 | int ret; |
| 2530 | 2535 | |
| 2531 | − /* Assert that the object is not currently in any GPU domain. As it | |
| 2536 | + /* | |
| 2537 | + * Assert that the object is not currently in any GPU domain. As it | |
| 2532 | 2538 | * wasn't in the GTT, there shouldn't be any way it could have been in |
| 2533 | 2539 | * a GPU cache |
| 2534 | 2540 | */ |
| 2535 | 2541 | GEM_BUG_ON(obj->read_domains & I915_GEM_GPU_DOMAINS); |
| 2536 | 2542 | GEM_BUG_ON(obj->write_domain & I915_GEM_GPU_DOMAINS); |
| 2537 | 2543 | |
| 2544 | + /* | |
| 2545 | + * If there's no chance of allocating enough pages for the whole | |
| 2546 | + * object, bail early. | |
| 2547 | + */ | |
| 2548 | + if (page_count > totalram_pages) | |
| 2549 | + return -ENOMEM; | |
| 2550 | + | |
| 2538 | 2551 | st = kmalloc(sizeof(*st), GFP_KERNEL); |
| 2539 | 2552 | if (st == NULL) |
| 2540 | 2553 | return -ENOMEM; |
| @@ -2545,7 +2558,8 @@ rebuild_st: · 4 unmodified lines | ||
| 2545 | 2558 | return -ENOMEM; |
| 2546 | 2559 | } |
| 2547 | 2560 | |
| 2548 | − /* Get the list of pages out of our struct file. They'll be pinned | |
| 2561 | + /* | |
| 2562 | + * Get the list of pages out of our struct file. They'll be pinned | |
| 2549 | 2563 | * at this point until we release them. |
| 2550 | 2564 | * |
| 2551 | 2565 | * Fail silently without starting the shrinker |
| @@ -2577,7 +2591,8 @@ rebuild_st: · 25 unmodified lines | ||
| 2577 | 2591 | i915_gem_shrink(dev_priv, 2 * page_count, NULL, *s++); |
| 2578 | 2592 | cond_resched(); |
| 2579 | 2593 | |
| 2580 | − /* We've tried hard to allocate the memory by reaping | |
| 2594 | + /* | |
| 2595 | + * We've tried hard to allocate the memory by reaping | |
| 2581 | 2596 | * our own buffer, now let the real VM do its job and |
| 2582 | 2597 | * go down in flames if truly OOM. |
| 2583 | 2598 | * |
| @@ -2589,7 +2604,8 @@ rebuild_st: · 5 unmodified lines | ||
| 2589 | 2604 | /* reclaim and warn, but no oom */ |
| 2590 | 2605 | gfp = mapping_gfp_mask(mapping); |
| 2591 | 2606 | |
| 2592 | − /* Our bo are always dirty and so we require | |
| 2607 | + /* | |
| 2608 | + * Our bo are always dirty and so we require | |
| 2593 | 2609 | * kswapd to reclaim our pages (direct reclaim |
| 2594 | 2610 | * does not effectively begin pageout of our |
| 2595 | 2611 | * buffers on its own). However, direct reclaim |
| @@ -2633,7 +2649,8 @@ rebuild_st: · 37 unmodified lines | ||
| 2633 | 2649 | |
| 2634 | 2650 | ret = i915_gem_gtt_prepare_pages(obj, st); |
| 2635 | 2651 | if (ret) { |
| 2636 | − /* DMA remapping failed? One possible cause is that | |
| 2652 | + /* | |
| 2653 | + * DMA remapping failed? One possible cause is that | |
| 2637 | 2654 | * it could not reserve enough large entries, asking |
| 2638 | 2655 | * for PAGE_SIZE chunks instead may be helpful. |
| 2639 | 2656 | */ |
| @@ -2667,7 +2684,8 @@ err_pages: · 27 unmodified lines | ||
| 2667 | 2684 | sg_free_table(st); |
| 2668 | 2685 | kfree(st); |
| 2669 | 2686 | |
| 2670 | − /* shmemfs first checks if there is enough memory to allocate the page | |
| 2687 | + /* | |
| 2688 | + * shmemfs first checks if there is enough memory to allocate the page | |
| 2671 | 2689 | * and reports ENOSPC should there be insufficient, along with the usual |
| 2672 | 2690 | * ENOMEM for a genuine allocation failure. |
| 2673 | 2691 | * |
| @@ -3307,8 +3325,8 @@ void i915_gem_set_wedged(struct drm_i915_private *i915) · 633 unmodified lines | ||
| 3307 | 3325 | intel_engine_dump(engine, &p, "%s\n", engine->name); |
| 3308 | 3326 | } |
| 3309 | 3327 | |
| 3310 | − set_bit(I915_WEDGED, &i915->gpu_error.flags); | |
| 3311 | − smp_mb__after_atomic(); | |
| 3328 | + if (test_and_set_bit(I915_WEDGED, &i915->gpu_error.flags)) | |
| 3329 | + goto out; | |
| 3312 | 3330 | |
| 3313 | 3331 | /* |
| 3314 | 3332 | * First, stop submission to hw, but do not yet complete requests by |
| @@ -3324,7 +3342,8 @@ void i915_gem_set_wedged(struct drm_i915_private *i915) · 9 unmodified lines | ||
| 3324 | 3342 | i915->caps.scheduler = 0; |
| 3325 | 3343 | |
| 3326 | 3344 | /* Even if the GPU reset fails, it should still stop the engines */ |
| 3327 | − intel_gpu_reset(i915, ALL_ENGINES); | |
| 3345 | + if (INTEL_GEN(i915) >= 5) | |
| 3346 | + intel_gpu_reset(i915, ALL_ENGINES); | |
| 3328 | 3347 | |
| 3329 | 3348 | /* |
| 3330 | 3349 | * Make sure no one is running the old callback before we proceed with |
| @@ -3367,6 +3386,7 @@ void i915_gem_set_wedged(struct drm_i915_private *i915) · 36 unmodified lines | ||
| 3367 | 3386 | i915_gem_reset_finish_engine(engine); |
| 3368 | 3387 | } |
| 3369 | 3388 | |
| 3389 | +out: | |
| 3370 | 3390 | GEM_TRACE("end\n"); |
| 3371 | 3391 | |
| 3372 | 3392 | wake_up_all(&i915->gpu_error.reset_queue); |
| @@ -3816,6 +3836,12 @@ int i915_gem_wait_for_idle(struct drm_i915_private *i915, · 443 unmodified lines | ||
| 3816 | 3836 | if (timeout < 0) |
| 3817 | 3837 | return timeout; |
| 3818 | 3838 | } |
| 3839 | + if (GEM_SHOW_DEBUG() && !timeout) { | |
| 3840 | + /* Presume that timeout was non-zero to begin with! */ | |
| 3841 | + dev_warn(&i915->drm.pdev->dev, | |
| 3842 | + "Missed idle-completion interrupt!\n"); | |
| 3843 | + GEM_TRACE_DUMP(); | |
| 3844 | + } | |
| 3819 | 3845 | |
| 3820 | 3846 | err = wait_for_engines(i915); |
| 3821 | 3847 | if (err) |
| @@ -5592,6 +5618,8 @@ err_uc_misc: · 1770 unmodified lines | ||
| 5592 | 5618 | i915_gem_cleanup_userptr(dev_priv); |
| 5593 | 5619 | |
| 5594 | 5620 | if (ret == -EIO) { |
| 5621 | + mutex_lock(&dev_priv->drm.struct_mutex); | |
| 5622 | + | |
| 5595 | 5623 | /* |
| 5596 | 5624 | * Allow engine initialisation to fail by marking the GPU as |
| 5597 | 5625 | * wedged. But we only want to do this where the GPU is angry, |
| @@ -5602,7 +5630,14 @@ err_uc_misc: · 4 unmodified lines | ||
| 5602 | 5630 | "Failed to initialize GPU, declaring it wedged!\n"); |
| 5603 | 5631 | i915_gem_set_wedged(dev_priv); |
| 5604 | 5632 | } |
| 5605 | − ret = 0; | |
| 5633 | + | |
| 5634 | + /* Minimal basic recovery for KMS */ | |
| 5635 | + ret = i915_ggtt_enable_hw(dev_priv); | |
| 5636 | + i915_gem_restore_gtt_mappings(dev_priv); | |
| 5637 | + i915_gem_restore_fences(dev_priv); | |
| 5638 | + intel_init_clock_gating(dev_priv); | |
| 5639 | + | |
| 5640 | + mutex_unlock(&dev_priv->drm.struct_mutex); | |
| 5606 | 5641 | } |
| 5607 | 5642 | |
| 5608 | 5643 | i915_gem_drain_freed_objects(dev_priv); |
| @@ -5612,6 +5647,7 @@ err_uc_misc: · 3 unmodified lines | ||
| 5612 | 5647 | void i915_gem_fini(struct drm_i915_private *dev_priv) |
| 5613 | 5648 | { |
| 5614 | 5649 | i915_gem_suspend_late(dev_priv); |
| 5650 | + intel_disable_gt_powersave(dev_priv); | |
| 5615 | 5651 | |
| 5616 | 5652 | /* Flush any outstanding unpin_work. */ |
| 5617 | 5653 | i915_gem_drain_workqueue(dev_priv); |
| @@ -5623,6 +5659,8 @@ void i915_gem_fini(struct drm_i915_private *dev_priv) · 5 unmodified lines | ||
| 5623 | 5659 | i915_gem_contexts_fini(dev_priv); |
| 5624 | 5660 | mutex_unlock(&dev_priv->drm.struct_mutex); |
| 5625 | 5661 | |
| 5662 | + intel_cleanup_gt_powersave(dev_priv); | |
| 5663 | + | |
| 5626 | 5664 | intel_uc_fini_misc(dev_priv); |
| 5627 | 5665 | i915_gem_cleanup_userptr(dev_priv); |
| 5628 | 5666 | |
| @@ -6182,4 +6220,5 @@ err_unlock: · 553 unmodified lines | ||
| 6182 | 6220 | #include "selftests/huge_pages.c" |
| 6183 | 6221 | #include "selftests/i915_gem_object.c" |
| 6184 | 6222 | #include "selftests/i915_gem_coherency.c" |
| 6223 | +#include "selftests/i915_gem.c" | |
| 6185 | 6224 | #endif |
| @@ -82,12 +82,6 @@ static inline void __tasklet_disable_sync_once(struct tasklet_struct *t) · 81 unmodified lines | ||
| 82 | 82 | tasklet_unlock_wait(t); |
| 83 | 83 | } |
| 84 | 84 | |
| 85 | −static inline void __tasklet_enable_sync_once(struct tasklet_struct *t) | |
| 86 | −{ | |
| 87 | − if (atomic_dec_return(&t->count) == 0) | |
| 88 | − tasklet_kill(t); | |
| 89 | −} | |
| 90 | − | |
| 91 | 85 | static inline bool __tasklet_is_enabled(const struct tasklet_struct *t) |
| 92 | 86 | { |
| 93 | 87 | return !atomic_read(&t->count); |
| @@ -115,6 +115,95 @@ static void lut_close(struct i915_gem_context *ctx) · 114 unmodified lines | ||
| 115 | 115 | rcu_read_unlock(); |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | +static inline int new_hw_id(struct drm_i915_private *i915, gfp_t gfp) | |
| 119 | +{ | |
| 120 | + unsigned int max; | |
| 121 | + | |
| 122 | + lockdep_assert_held(&i915->contexts.mutex); | |
| 123 | + | |
| 124 | + if (INTEL_GEN(i915) >= 11) | |
| 125 | + max = GEN11_MAX_CONTEXT_HW_ID; | |
| 126 | + else if (USES_GUC_SUBMISSION(i915)) | |
| 127 | + /* | |
| 128 | + * When using GuC in proxy submission, GuC consumes the | |
| 129 | + * highest bit in the context id to indicate proxy submission. | |
| 130 | + */ | |
| 131 | + max = MAX_GUC_CONTEXT_HW_ID; | |
| 132 | + else | |
| 133 | + max = MAX_CONTEXT_HW_ID; | |
| 134 | + | |
| 135 | + return ida_simple_get(&i915->contexts.hw_ida, 0, max, gfp); | |
| 136 | +} | |
| 137 | + | |
| 138 | +static int steal_hw_id(struct drm_i915_private *i915) | |
| 139 | +{ | |
| 140 | + struct i915_gem_context *ctx, *cn; | |
| 141 | + LIST_HEAD(pinned); | |
| 142 | + int id = -ENOSPC; | |
| 143 | + | |
| 144 | + lockdep_assert_held(&i915->contexts.mutex); | |
| 145 | + | |
| 146 | + list_for_each_entry_safe(ctx, cn, | |
| 147 | + &i915->contexts.hw_id_list, hw_id_link) { | |
| 148 | + if (atomic_read(&ctx->hw_id_pin_count)) { | |
| 149 | + list_move_tail(&ctx->hw_id_link, &pinned); | |
| 150 | + continue; | |
| 151 | + } | |
| 152 | + | |
| 153 | + GEM_BUG_ON(!ctx->hw_id); /* perma-pinned kernel context */ | |
| 154 | + list_del_init(&ctx->hw_id_link); | |
| 155 | + id = ctx->hw_id; | |
| 156 | + break; | |
| 157 | + } | |
| 158 | + | |
| 159 | + /* | |
| 160 | + * Remember how far we got up on the last repossesion scan, so the | |
| 161 | + * list is kept in a "least recently scanned" order. | |
| 162 | + */ | |
| 163 | + list_splice_tail(&pinned, &i915->contexts.hw_id_list); | |
| 164 | + return id; | |
| 165 | +} | |
| 166 | + | |
| 167 | +static int assign_hw_id(struct drm_i915_private *i915, unsigned int *out) | |
| 168 | +{ | |
| 169 | + int ret; | |
| 170 | + | |
| 171 | + lockdep_assert_held(&i915->contexts.mutex); | |
| 172 | + | |
| 173 | + /* | |
| 174 | + * We prefer to steal/stall ourselves and our users over that of the | |
| 175 | + * entire system. That may be a little unfair to our users, and | |
| 176 | + * even hurt high priority clients. The choice is whether to oomkill | |
| 177 | + * something else, or steal a context id. | |
| 178 | + */ | |
| 179 | + ret = new_hw_id(i915, GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN); | |
| 180 | + if (unlikely(ret < 0)) { | |
| 181 | + ret = steal_hw_id(i915); | |
| 182 | + if (ret < 0) /* once again for the correct errno code */ | |
| 183 | + ret = new_hw_id(i915, GFP_KERNEL); | |
| 184 | + if (ret < 0) | |
| 185 | + return ret; | |
| 186 | + } | |
| 187 | + | |
| 188 | + *out = ret; | |
| 189 | + return 0; | |
| 190 | +} | |
| 191 | + | |
| 192 | +static void release_hw_id(struct i915_gem_context *ctx) | |
| 193 | +{ | |
| 194 | + struct drm_i915_private *i915 = ctx->i915; | |
| 195 | + | |
| 196 | + if (list_empty(&ctx->hw_id_link)) | |
| 197 | + return; | |
| 198 | + | |
| 199 | + mutex_lock(&i915->contexts.mutex); | |
| 200 | + if (!list_empty(&ctx->hw_id_link)) { | |
| 201 | + ida_simple_remove(&i915->contexts.hw_ida, ctx->hw_id); | |
| 202 | + list_del_init(&ctx->hw_id_link); | |
| 203 | + } | |
| 204 | + mutex_unlock(&i915->contexts.mutex); | |
| 205 | +} | |
| 206 | + | |
| 118 | 207 | static void i915_gem_context_free(struct i915_gem_context *ctx) |
| 119 | 208 | { |
| 120 | 209 | unsigned int n; |
| @@ -122,6 +211,7 @@ static void i915_gem_context_free(struct i915_gem_context *ctx) · 1 unmodified line | ||
| 122 | 211 | lockdep_assert_held(&ctx->i915->drm.struct_mutex); |
| 123 | 212 | GEM_BUG_ON(!i915_gem_context_is_closed(ctx)); |
| 124 | 213 | |
| 214 | + release_hw_id(ctx); | |
| 125 | 215 | i915_ppgtt_put(ctx->ppgtt); |
| 126 | 216 | |
| 127 | 217 | for (n = 0; n < ARRAY_SIZE(ctx->__engine); n++) { |
| @@ -136,7 +226,6 @@ static void i915_gem_context_free(struct i915_gem_context *ctx) · 8 unmodified lines | ||
| 136 | 226 | |
| 137 | 227 | list_del(&ctx->link); |
| 138 | 228 | |
| 139 | − ida_simple_remove(&ctx->i915->contexts.hw_ida, ctx->hw_id); | |
| 140 | 229 | kfree_rcu(ctx, rcu); |
| 141 | 230 | } |
| 142 | 231 | |
| @@ -190,6 +279,12 @@ static void context_close(struct i915_gem_context *ctx) · 47 unmodified lines | ||
| 190 | 279 | { |
| 191 | 280 | i915_gem_context_set_closed(ctx); |
| 192 | 281 | |
| 282 | + /* | |
| 283 | + * This context will never again be assinged to HW, so we can | |
| 284 | + * reuse its ID for the next context. | |
| 285 | + */ | |
| 286 | + release_hw_id(ctx); | |
| 287 | + | |
| 193 | 288 | /* |
| 194 | 289 | * The LUT uses the VMA as a backpointer to unref the object, |
| 195 | 290 | * so we need to clear the LUT before we close all the VMA (inside |
| @@ -203,43 +298,6 @@ static void context_close(struct i915_gem_context *ctx) · 7 unmodified lines | ||
| 203 | 298 | i915_gem_context_put(ctx); |
| 204 | 299 | } |
| 205 | 300 | |
| 206 | −static int assign_hw_id(struct drm_i915_private *dev_priv, unsigned *out) | |
| 207 | −{ | |
| 208 | − int ret; | |
| 209 | − unsigned int max; | |
| 210 | − | |
| 211 | − if (INTEL_GEN(dev_priv) >= 11) { | |
| 212 | − max = GEN11_MAX_CONTEXT_HW_ID; | |
| 213 | − } else { | |
| 214 | − /* | |
| 215 | − * When using GuC in proxy submission, GuC consumes the | |
| 216 | − * highest bit in the context id to indicate proxy submission. | |
| 217 | − */ | |
| 218 | − if (USES_GUC_SUBMISSION(dev_priv)) | |
| 219 | − max = MAX_GUC_CONTEXT_HW_ID; | |
| 220 | − else | |
| 221 | − max = MAX_CONTEXT_HW_ID; | |
| 222 | − } | |
| 223 | − | |
| 224 | − | |
| 225 | − ret = ida_simple_get(&dev_priv->contexts.hw_ida, | |
| 226 | − 0, max, GFP_KERNEL); | |
| 227 | − if (ret < 0) { | |
| 228 | − /* Contexts are only released when no longer active. | |
| 229 | − * Flush any pending retires to hopefully release some | |
| 230 | − * stale contexts and try again. | |
| 231 | − */ | |
| 232 | − i915_retire_requests(dev_priv); | |
| 233 | − ret = ida_simple_get(&dev_priv->contexts.hw_ida, | |
| 234 | − 0, max, GFP_KERNEL); | |
| 235 | − if (ret < 0) | |
| 236 | − return ret; | |
| 237 | − } | |
| 238 | − | |
| 239 | − *out = ret; | |
| 240 | − return 0; | |
| 241 | −} | |
| 242 | − | |
| 243 | 301 | static u32 default_desc_template(const struct drm_i915_private *i915, |
| 244 | 302 | const struct i915_hw_ppgtt *ppgtt) |
| 245 | 303 | { |
| @@ -276,12 +334,6 @@ __create_hw_context(struct drm_i915_private *dev_priv, · 30 unmodified lines | ||
| 276 | 334 | if (ctx == NULL) |
| 277 | 335 | return ERR_PTR(-ENOMEM); |
| 278 | 336 | |
| 279 | − ret = assign_hw_id(dev_priv, &ctx->hw_id); | |
| 280 | − if (ret) { | |
| 281 | − kfree(ctx); | |
| 282 | − return ERR_PTR(ret); | |
| 283 | − } | |
| 284 | − | |
| 285 | 337 | kref_init(&ctx->ref); |
| 286 | 338 | list_add_tail(&ctx->link, &dev_priv->contexts.list); |
| 287 | 339 | ctx->i915 = dev_priv; |
| @@ -295,6 +347,7 @@ __create_hw_context(struct drm_i915_private *dev_priv, · 7 unmodified lines | ||
| 295 | 347 | |
| 296 | 348 | INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL); |
| 297 | 349 | INIT_LIST_HEAD(&ctx->handles_list); |
| 350 | + INIT_LIST_HEAD(&ctx->hw_id_link); | |
| 298 | 351 | |
| 299 | 352 | /* Default context will never have a file_priv */ |
| 300 | 353 | ret = DEFAULT_CONTEXT_HANDLE; |
| @@ -329,16 +382,6 @@ __create_hw_context(struct drm_i915_private *dev_priv, · 28 unmodified lines | ||
| 329 | 382 | ctx->desc_template = |
| 330 | 383 | default_desc_template(dev_priv, dev_priv->mm.aliasing_ppgtt); |
| 331 | 384 | |
| 332 | − /* | |
| 333 | − * GuC requires the ring to be placed in Non-WOPCM memory. If GuC is not | |
| 334 | − * present or not in use we still need a small bias as ring wraparound | |
| 335 | − * at offset 0 sometimes hangs. No idea why. | |
| 336 | − */ | |
| 337 | − if (USES_GUC(dev_priv)) | |
| 338 | − ctx->ggtt_offset_bias = dev_priv->guc.ggtt_pin_bias; | |
| 339 | − else | |
| 340 | − ctx->ggtt_offset_bias = I915_GTT_PAGE_SIZE; | |
| 341 | − | |
| 342 | 385 | return ctx; |
| 343 | 386 | |
| 344 | 387 | err_pid: |
| @@ -431,15 +474,35 @@ out: · 86 unmodified lines | ||
| 431 | 474 | return ctx; |
| 432 | 475 | } |
| 433 | 476 | |
| 477 | +static void | |
| 478 | +destroy_kernel_context(struct i915_gem_context **ctxp) | |
| 479 | +{ | |
| 480 | + struct i915_gem_context *ctx; | |
| 481 | + | |
| 482 | + /* Keep the context ref so that we can free it immediately ourselves */ | |
| 483 | + ctx = i915_gem_context_get(fetch_and_zero(ctxp)); | |
| 484 | + GEM_BUG_ON(!i915_gem_context_is_kernel(ctx)); | |
| 485 | + | |
| 486 | + context_close(ctx); | |
| 487 | + i915_gem_context_free(ctx); | |
| 488 | +} | |
| 489 | + | |
| 434 | 490 | struct i915_gem_context * |
| 435 | 491 | i915_gem_context_create_kernel(struct drm_i915_private *i915, int prio) |
| 436 | 492 | { |
| 437 | 493 | struct i915_gem_context *ctx; |
| 494 | + int err; | |
| 438 | 495 | |
| 439 | 496 | ctx = i915_gem_create_context(i915, NULL); |
| 440 | 497 | if (IS_ERR(ctx)) |
| 441 | 498 | return ctx; |
| 442 | 499 | |
| 500 | + err = i915_gem_context_pin_hw_id(ctx); | |
| 501 | + if (err) { | |
| 502 | + destroy_kernel_context(&ctx); | |
| 503 | + return ERR_PTR(err); | |
| 504 | + } | |
| 505 | + | |
| 443 | 506 | i915_gem_context_clear_bannable(ctx); |
| 444 | 507 | ctx->sched.priority = prio; |
| 445 | 508 | ctx->ring_size = PAGE_SIZE; |
| @@ -449,17 +512,19 @@ i915_gem_context_create_kernel(struct drm_i915_private *i915, int prio) · 3 unmodified lines | ||
| 449 | 512 | return ctx; |
| 450 | 513 | } |
| 451 | 514 | |
| 452 | −static void | |
| 453 | −destroy_kernel_context(struct i915_gem_context **ctxp) | |
| 515 | +static void init_contexts(struct drm_i915_private *i915) | |
| 454 | 516 | { |
| 455 | − struct i915_gem_context *ctx; | |
| 517 | + mutex_init(&i915->contexts.mutex); | |
| 518 | + INIT_LIST_HEAD(&i915->contexts.list); | |
| 456 | 519 | |
| 457 | − /* Keep the context ref so that we can free it immediately ourselves */ | |
| 458 | − ctx = i915_gem_context_get(fetch_and_zero(ctxp)); | |
| 459 | − GEM_BUG_ON(!i915_gem_context_is_kernel(ctx)); | |
| 520 | + /* Using the simple ida interface, the max is limited by sizeof(int) */ | |
| 521 | + BUILD_BUG_ON(MAX_CONTEXT_HW_ID > INT_MAX); | |
| 522 | + BUILD_BUG_ON(GEN11_MAX_CONTEXT_HW_ID > INT_MAX); | |
| 523 | + ida_init(&i915->contexts.hw_ida); | |
| 524 | + INIT_LIST_HEAD(&i915->contexts.hw_id_list); | |
| 460 | 525 | |
| 461 | − context_close(ctx); | |
| 462 | − i915_gem_context_free(ctx); | |
| 526 | + INIT_WORK(&i915->contexts.free_work, contexts_free_worker); | |
| 527 | + init_llist_head(&i915->contexts.free_list); | |
| 463 | 528 | } |
| 464 | 529 | |
| 465 | 530 | static bool needs_preempt_context(struct drm_i915_private *i915) |
| @@ -480,14 +545,7 @@ int i915_gem_contexts_init(struct drm_i915_private *dev_priv) · 14 unmodified lines | ||
| 480 | 545 | if (ret) |
| 481 | 546 | return ret; |
| 482 | 547 | |
| 483 | − INIT_LIST_HEAD(&dev_priv->contexts.list); | |
| 484 | − INIT_WORK(&dev_priv->contexts.free_work, contexts_free_worker); | |
| 485 | − init_llist_head(&dev_priv->contexts.free_list); | |
| 486 | − | |
| 487 | − /* Using the simple ida interface, the max is limited by sizeof(int) */ | |
| 488 | − BUILD_BUG_ON(MAX_CONTEXT_HW_ID > INT_MAX); | |
| 489 | − BUILD_BUG_ON(GEN11_MAX_CONTEXT_HW_ID > INT_MAX); | |
| 490 | − ida_init(&dev_priv->contexts.hw_ida); | |
| 548 | + init_contexts(dev_priv); | |
| 491 | 549 | |
| 492 | 550 | /* lowest priority; idle task */ |
| 493 | 551 | ctx = i915_gem_context_create_kernel(dev_priv, I915_PRIORITY_MIN); |
| @@ -497,9 +555,13 @@ int i915_gem_contexts_init(struct drm_i915_private *dev_priv) · 3 unmodified lines | ||
| 497 | 555 | } |
| 498 | 556 | /* |
| 499 | 557 | * For easy recognisablity, we want the kernel context to be 0 and then |
| 500 | − * all user contexts will have non-zero hw_id. | |
| 558 | + * all user contexts will have non-zero hw_id. Kernel contexts are | |
| 559 | + * permanently pinned, so that we never suffer a stall and can | |
| 560 | + * use them from any allocation context (e.g. for evicting other | |
| 561 | + * contexts and from inside the shrinker). | |
| 501 | 562 | */ |
| 502 | 563 | GEM_BUG_ON(ctx->hw_id); |
| 564 | + GEM_BUG_ON(!atomic_read(&ctx->hw_id_pin_count)); | |
| 503 | 565 | dev_priv->kernel_context = ctx; |
| 504 | 566 | |
| 505 | 567 | /* highest priority; preempting task */ |
| @@ -537,6 +599,7 @@ void i915_gem_contexts_fini(struct drm_i915_private *i915) · 31 unmodified lines | ||
| 537 | 599 | destroy_kernel_context(&i915->kernel_context); |
| 538 | 600 | |
| 539 | 601 | /* Must free all deferred contexts (via flush_workqueue) first */ |
| 602 | + GEM_BUG_ON(!list_empty(&i915->contexts.hw_id_list)); | |
| 540 | 603 | ida_destroy(&i915->contexts.hw_ida); |
| 541 | 604 | } |
| 542 | 605 | |
| @@ -942,6 +1005,33 @@ out: · 399 unmodified lines | ||
| 942 | 1005 | return ret; |
| 943 | 1006 | } |
| 944 | 1007 | |
| 1008 | +int __i915_gem_context_pin_hw_id(struct i915_gem_context *ctx) | |
| 1009 | +{ | |
| 1010 | + struct drm_i915_private *i915 = ctx->i915; | |
| 1011 | + int err = 0; | |
| 1012 | + | |
| 1013 | + mutex_lock(&i915->contexts.mutex); | |
| 1014 | + | |
| 1015 | + GEM_BUG_ON(i915_gem_context_is_closed(ctx)); | |
| 1016 | + | |
| 1017 | + if (list_empty(&ctx->hw_id_link)) { | |
| 1018 | + GEM_BUG_ON(atomic_read(&ctx->hw_id_pin_count)); | |
| 1019 | + | |
| 1020 | + err = assign_hw_id(i915, &ctx->hw_id); | |
| 1021 | + if (err) | |
| 1022 | + goto out_unlock; | |
| 1023 | + | |
| 1024 | + list_add_tail(&ctx->hw_id_link, &i915->contexts.hw_id_list); | |
| 1025 | + } | |
| 1026 | + | |
| 1027 | + GEM_BUG_ON(atomic_read(&ctx->hw_id_pin_count) == ~0u); | |
| 1028 | + atomic_inc(&ctx->hw_id_pin_count); | |
| 1029 | + | |
| 1030 | +out_unlock: | |
| 1031 | + mutex_unlock(&i915->contexts.mutex); | |
| 1032 | + return err; | |
| 1033 | +} | |
| 1034 | + | |
| 945 | 1035 | #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) |
| 946 | 1036 | #include "selftests/mock_context.c" |
| 947 | 1037 | #include "selftests/i915_gem_context.c" |
| @@ -134,8 +134,16 @@ struct i915_gem_context { · 133 unmodified lines | ||
| 134 | 134 | * functions like fault reporting, PASID, scheduling. The |
| 135 | 135 | * &drm_i915_private.context_hw_ida is used to assign a unqiue |
| 136 | 136 | * id for the lifetime of the context. |
| 137 | + * | |
| 138 | + * @hw_id_pin_count: - number of times this context had been pinned | |
| 139 | + * for use (should be, at most, once per engine). | |
| 140 | + * | |
| 141 | + * @hw_id_link: - all contexts with an assigned id are tracked | |
| 142 | + * for possible repossession. | |
| 137 | 143 | */ |
| 138 | 144 | unsigned int hw_id; |
| 145 | + atomic_t hw_id_pin_count; | |
| 146 | + struct list_head hw_id_link; | |
| 139 | 147 | |
| 140 | 148 | /** |
| 141 | 149 | * @user_handle: userspace identifier |
| @@ -147,9 +155,6 @@ struct i915_gem_context { · 5 unmodified lines | ||
| 147 | 155 | |
| 148 | 156 | struct i915_sched_attr sched; |
| 149 | 157 | |
| 150 | − /** ggtt_offset_bias: placement restriction for context objects */ | |
| 151 | − u32 ggtt_offset_bias; | |
| 152 | − | |
| 153 | 158 | /** engine: per-engine logical HW state */ |
| 154 | 159 | struct intel_context { |
| 155 | 160 | struct i915_gem_context *gem_context; |
| @@ -257,6 +262,21 @@ static inline void i915_gem_context_set_force_single_submission(struct i915_gem_ · 101 unmodified lines | ||
| 257 | 262 | __set_bit(CONTEXT_FORCE_SINGLE_SUBMISSION, &ctx->flags); |
| 258 | 263 | } |
| 259 | 264 | |
| 265 | +int __i915_gem_context_pin_hw_id(struct i915_gem_context *ctx); | |
| 266 | +static inline int i915_gem_context_pin_hw_id(struct i915_gem_context *ctx) | |
| 267 | +{ | |
| 268 | + if (atomic_inc_not_zero(&ctx->hw_id_pin_count)) | |
| 269 | + return 0; | |
| 270 | + | |
| 271 | + return __i915_gem_context_pin_hw_id(ctx); | |
| 272 | +} | |
| 273 | + | |
| 274 | +static inline void i915_gem_context_unpin_hw_id(struct i915_gem_context *ctx) | |
| 275 | +{ | |
| 276 | + GEM_BUG_ON(atomic_read(&ctx->hw_id_pin_count) == 0u); | |
| 277 | + atomic_dec(&ctx->hw_id_pin_count); | |
| 278 | +} | |
| 279 | + | |
| 260 | 280 | static inline bool i915_gem_context_is_default(const struct i915_gem_context *c) |
| 261 | 281 | { |
| 262 | 282 | return c->user_handle == DEFAULT_CONTEXT_HANDLE; |
| @@ -64,7 +64,9 @@ enum { · 63 unmodified lines | ||
| 64 | 64 | #define BATCH_OFFSET_BIAS (256*1024) |
| 65 | 65 | |
| 66 | 66 | #define __I915_EXEC_ILLEGAL_FLAGS \ |
| 67 | − (__I915_EXEC_UNKNOWN_FLAGS | I915_EXEC_CONSTANTS_MASK) | |
| 67 | + (__I915_EXEC_UNKNOWN_FLAGS | \ | |
| 68 | + I915_EXEC_CONSTANTS_MASK | \ | |
| 69 | + I915_EXEC_RESOURCE_STREAMER) | |
| 68 | 70 | |
| 69 | 71 | /* Catch emission of unexpected errors for CI! */ |
| 70 | 72 | #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) |
| @@ -733,7 +735,12 @@ static int eb_select_context(struct i915_execbuffer *eb) · 662 unmodified lines | ||
| 733 | 735 | return -ENOENT; |
| 734 | 736 | |
| 735 | 737 | eb->ctx = ctx; |
| 736 | − eb->vm = ctx->ppgtt ? &ctx->ppgtt->vm : &eb->i915->ggtt.vm; | |
| 738 | + if (ctx->ppgtt) { | |
| 739 | + eb->vm = &ctx->ppgtt->vm; | |
| 740 | + eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT; | |
| 741 | + } else { | |
| 742 | + eb->vm = &eb->i915->ggtt.vm; | |
| 743 | + } | |
| 737 | 744 | |
| 738 | 745 | eb->context_flags = 0; |
| 739 | 746 | if (ctx->flags & CONTEXT_NO_ZEROMAP) |
| @@ -1120,6 +1127,13 @@ static int __reloc_gpu_alloc(struct i915_execbuffer *eb, · 380 unmodified lines | ||
| 1120 | 1127 | u32 *cmd; |
| 1121 | 1128 | int err; |
| 1122 | 1129 | |
| 1130 | + if (DBG_FORCE_RELOC == FORCE_GPU_RELOC) { | |
| 1131 | + obj = vma->obj; | |
| 1132 | + if (obj->cache_dirty & ~obj->cache_coherent) | |
| 1133 | + i915_gem_clflush_object(obj, 0); | |
| 1134 | + obj->write_domain = 0; | |
| 1135 | + } | |
| 1136 | + | |
| 1123 | 1137 | GEM_BUG_ON(vma->obj->write_domain & I915_GEM_DOMAIN_CPU); |
| 1124 | 1138 | |
| 1125 | 1139 | obj = i915_gem_batch_pool_get(&eb->engine->batch_pool, PAGE_SIZE); |
| @@ -1484,8 +1498,10 @@ static int eb_relocate_vma(struct i915_execbuffer *eb, struct i915_vma *vma) · 358 unmodified lines | ||
| 1484 | 1498 | * can read from this userspace address. |
| 1485 | 1499 | */ |
| 1486 | 1500 | offset = gen8_canonical_addr(offset & ~UPDATE); |
| 1487 | − __put_user(offset, | |
| 1488 | − &urelocs[r-stack].presumed_offset); | |
| 1501 | + if (unlikely(__put_user(offset, &urelocs[r-stack].presumed_offset))) { | |
| 1502 | + remain = -EFAULT; | |
| 1503 | + goto out; | |
| 1504 | + } | |
| 1489 | 1505 | } |
| 1490 | 1506 | } while (r++, --count); |
| 1491 | 1507 | urelocs += ARRAY_SIZE(stack); |
| @@ -1570,7 +1586,6 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb) · 78 unmodified lines | ||
| 1570 | 1586 | |
| 1571 | 1587 | relocs = kvmalloc_array(size, 1, GFP_KERNEL); |
| 1572 | 1588 | if (!relocs) { |
| 1573 | − kvfree(relocs); | |
| 1574 | 1589 | err = -ENOMEM; |
| 1575 | 1590 | goto err; |
| 1576 | 1591 | } |
| @@ -1584,6 +1599,7 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb) · 7 unmodified lines | ||
| 1584 | 1599 | if (__copy_from_user((char *)relocs + copied, |
| 1585 | 1600 | (char __user *)urelocs + copied, |
| 1586 | 1601 | len)) { |
| 1602 | +end_user: | |
| 1587 | 1603 | kvfree(relocs); |
| 1588 | 1604 | err = -EFAULT; |
| 1589 | 1605 | goto err; |
| @@ -1607,7 +1623,6 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb) · 17 unmodified lines | ||
| 1607 | 1623 | unsafe_put_user(-1, |
| 1608 | 1624 | &urelocs[copied].presumed_offset, |
| 1609 | 1625 | end_user); |
| 1610 | −end_user: | |
| 1611 | 1626 | user_access_end(); |
| 1612 | 1627 | |
| 1613 | 1628 | eb->exec[i].relocs_ptr = (uintptr_t)relocs; |
| @@ -2199,8 +2214,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, · 585 unmodified lines | ||
| 2199 | 2214 | eb.flags = (unsigned int *)(eb.vma + args->buffer_count + 1); |
| 2200 | 2215 | |
| 2201 | 2216 | eb.invalid_flags = __EXEC_OBJECT_UNKNOWN_FLAGS; |
| 2202 | − if (USES_FULL_PPGTT(eb.i915)) | |
| 2203 | − eb.invalid_flags |= EXEC_OBJECT_NEEDS_GTT; | |
| 2204 | 2217 | reloc_cache_init(&eb.reloc_cache, eb.i915); |
| 2205 | 2218 | |
| 2206 | 2219 | eb.buffer_count = args->buffer_count; |
| @@ -2221,20 +2234,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, · 14 unmodified lines | ||
| 2221 | 2234 | if (!eb.engine) |
| 2222 | 2235 | return -EINVAL; |
| 2223 | 2236 | |
| 2224 | − if (args->flags & I915_EXEC_RESOURCE_STREAMER) { | |
| 2225 | − if (!HAS_RESOURCE_STREAMER(eb.i915)) { | |
| 2226 | − DRM_DEBUG("RS is only allowed for Haswell, Gen8 and above\n"); | |
| 2227 | − return -EINVAL; | |
| 2228 | − } | |
| 2229 | − if (eb.engine->id != RCS) { | |
| 2230 | − DRM_DEBUG("RS is not available on %s\n", | |
| 2231 | − eb.engine->name); | |
| 2232 | − return -EINVAL; | |
| 2233 | − } | |
| 2234 | − | |
| 2235 | − eb.batch_flags |= I915_DISPATCH_RS; | |
| 2236 | − } | |
| 2237 | − | |
| 2238 | 2237 | if (args->flags & I915_EXEC_FENCE_IN) { |
| 2239 | 2238 | in_fence = sync_file_get_fence(lower_32_bits(args->rsvd2)); |
| 2240 | 2239 | if (!in_fence) |
| @@ -173,19 +173,11 @@ int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv, · 172 unmodified lines | ||
| 173 | 173 | return 0; |
| 174 | 174 | } |
| 175 | 175 | |
| 176 | − /* Early VLV doesn't have this */ | |
| 177 | − if (IS_VALLEYVIEW(dev_priv) && dev_priv->drm.pdev->revision < 0xb) { | |
| 178 | − DRM_DEBUG_DRIVER("disabling PPGTT on pre-B3 step VLV\n"); | |
| 179 | − return 0; | |
| 180 | − } | |
| 181 | − | |
| 182 | − if (HAS_LOGICAL_RING_CONTEXTS(dev_priv)) { | |
| 183 | − if (has_full_48bit_ppgtt) | |
| 184 | − return 3; | |
| 176 | + if (has_full_48bit_ppgtt) | |
| 177 | + return 3; | |
| 185 | 178 | |
| 186 | − if (has_full_ppgtt) | |
| 187 | − return 2; | |
| 188 | − } | |
| 179 | + if (has_full_ppgtt) | |
| 180 | + return 2; | |
| 189 | 181 | |
| 190 | 182 | return 1; |
| 191 | 183 | } |
| @@ -1259,9 +1251,6 @@ static void gen8_free_page_tables(struct i915_address_space *vm, · 1067 unmodified lines | ||
| 1259 | 1251 | { |
| 1260 | 1252 | int i; |
| 1261 | 1253 | |
| 1262 | − if (!px_page(pd)) | |
| 1263 | − return; | |
| 1264 | − | |
| 1265 | 1254 | for (i = 0; i < I915_PDES; i++) { |
| 1266 | 1255 | if (pd->page_table[i] != vm->scratch_pt) |
| 1267 | 1256 | free_pt(vm, pd->page_table[i]); |
| @@ -2348,7 +2337,7 @@ static bool needs_idle_maps(struct drm_i915_private *dev_priv) · 1080 unmodified lines | ||
| 2348 | 2337 | return IS_GEN5(dev_priv) && IS_MOBILE(dev_priv) && intel_vtd_active(); |
| 2349 | 2338 | } |
| 2350 | 2339 | |
| 2351 | −static void gen6_check_and_clear_faults(struct drm_i915_private *dev_priv) | |
| 2340 | +static void gen6_check_faults(struct drm_i915_private *dev_priv) | |
| 2352 | 2341 | { |
| 2353 | 2342 | struct intel_engine_cs *engine; |
| 2354 | 2343 | enum intel_engine_id id; |
| @@ -2366,15 +2355,11 @@ static void gen6_check_and_clear_faults(struct drm_i915_private *dev_priv) · 11 unmodified lines | ||
| 2366 | 2355 | fault & RING_FAULT_GTTSEL_MASK ? "GGTT" : "PPGTT", |
| 2367 | 2356 | RING_FAULT_SRCID(fault), |
| 2368 | 2357 | RING_FAULT_FAULT_TYPE(fault)); |
| 2369 | − I915_WRITE(RING_FAULT_REG(engine), | |
| 2370 | − fault & ~RING_FAULT_VALID); | |
| 2371 | 2358 | } |
| 2372 | 2359 | } |
| 2373 | − | |
| 2374 | − POSTING_READ(RING_FAULT_REG(dev_priv->engine[RCS])); | |
| 2375 | 2360 | } |
| 2376 | 2361 | |
| 2377 | −static void gen8_check_and_clear_faults(struct drm_i915_private *dev_priv) | |
| 2362 | +static void gen8_check_faults(struct drm_i915_private *dev_priv) | |
| 2378 | 2363 | { |
| 2379 | 2364 | u32 fault = I915_READ(GEN8_RING_FAULT_REG); |
| 2380 | 2365 | |
| @@ -2399,22 +2384,20 @@ static void gen8_check_and_clear_faults(struct drm_i915_private *dev_priv) · 18 unmodified lines | ||
| 2399 | 2384 | GEN8_RING_FAULT_ENGINE_ID(fault), |
| 2400 | 2385 | RING_FAULT_SRCID(fault), |
| 2401 | 2386 | RING_FAULT_FAULT_TYPE(fault)); |
| 2402 | − I915_WRITE(GEN8_RING_FAULT_REG, | |
| 2403 | − fault & ~RING_FAULT_VALID); | |
| 2404 | 2387 | } |
| 2405 | − | |
| 2406 | − POSTING_READ(GEN8_RING_FAULT_REG); | |
| 2407 | 2388 | } |
| 2408 | 2389 | |
| 2409 | 2390 | void i915_check_and_clear_faults(struct drm_i915_private *dev_priv) |
| 2410 | 2391 | { |
| 2411 | 2392 | /* From GEN8 onwards we only have one 'All Engine Fault Register' */ |
| 2412 | 2393 | if (INTEL_GEN(dev_priv) >= 8) |
| 2413 | − gen8_check_and_clear_faults(dev_priv); | |
| 2394 | + gen8_check_faults(dev_priv); | |
| 2414 | 2395 | else if (INTEL_GEN(dev_priv) >= 6) |
| 2415 | − gen6_check_and_clear_faults(dev_priv); | |
| 2396 | + gen6_check_faults(dev_priv); | |
| 2416 | 2397 | else |
| 2417 | 2398 | return; |
| 2399 | + | |
| 2400 | + i915_clear_error_registers(dev_priv); | |
| 2418 | 2401 | } |
| 2419 | 2402 | |
| 2420 | 2403 | void i915_gem_suspend_gtt_mappings(struct drm_i915_private *dev_priv) |
| @@ -2937,6 +2920,15 @@ int i915_gem_init_ggtt(struct drm_i915_private *dev_priv) · 516 unmodified lines | ||
| 2937 | 2920 | struct drm_mm_node *entry; |
| 2938 | 2921 | int ret; |
| 2939 | 2922 | |
| 2923 | + /* | |
| 2924 | + * GuC requires all resources that we're sharing with it to be placed in | |
| 2925 | + * non-WOPCM memory. If GuC is not present or not in use we still need a | |
| 2926 | + * small bias as ring wraparound at offset 0 sometimes hangs. No idea | |
| 2927 | + * why. | |
| 2928 | + */ | |
| 2929 | + ggtt->pin_bias = max_t(u32, I915_GTT_PAGE_SIZE, | |
| 2930 | + intel_guc_reserved_gtt_size(&dev_priv->guc)); | |
| 2931 | + | |
| 2940 | 2932 | ret = intel_vgt_balloon(dev_priv); |
| 2941 | 2933 | if (ret) |
| 2942 | 2934 | return ret; |
| @@ -3612,6 +3604,8 @@ int i915_ggtt_init_hw(struct drm_i915_private *dev_priv) · 669 unmodified lines | ||
| 3612 | 3604 | mutex_lock(&dev_priv->drm.struct_mutex); |
| 3613 | 3605 | i915_address_space_init(&ggtt->vm, dev_priv); |
| 3614 | 3606 | |
| 3607 | + ggtt->vm.is_ggtt = true; | |
| 3608 | + | |
| 3615 | 3609 | /* Only VLV supports read-only GGTT mappings */ |
| 3616 | 3610 | ggtt->vm.has_read_only = IS_VALLEYVIEW(dev_priv); |
| 3617 | 3611 | |
| @@ -3662,6 +3656,10 @@ void i915_ggtt_enable_guc(struct drm_i915_private *i915) · 44 unmodified lines | ||
| 3662 | 3656 | |
| 3663 | 3657 | void i915_ggtt_disable_guc(struct drm_i915_private *i915) |
| 3664 | 3658 | { |
| 3659 | + /* XXX Temporary pardon for error unload */ | |
| 3660 | + if (i915->ggtt.invalidate == gen6_ggtt_invalidate) | |
| 3661 | + return; | |
| 3662 | + | |
| 3665 | 3663 | /* We should only be called after i915_ggtt_enable_guc() */ |
| 3666 | 3664 | GEM_BUG_ON(i915->ggtt.invalidate != guc_ggtt_invalidate); |
| 3667 | 3665 | |
| @@ -167,29 +167,22 @@ struct intel_rotation_info { · 166 unmodified lines | ||
| 167 | 167 | } plane[2]; |
| 168 | 168 | } __packed; |
| 169 | 169 | |
| 170 | −static inline void assert_intel_rotation_info_is_packed(void) | |
| 171 | −{ | |
| 172 | − BUILD_BUG_ON(sizeof(struct intel_rotation_info) != 8*sizeof(unsigned int)); | |
| 173 | −} | |
| 174 | − | |
| 175 | 170 | struct intel_partial_info { |
| 176 | 171 | u64 offset; |
| 177 | 172 | unsigned int size; |
| 178 | 173 | } __packed; |
| 179 | 174 | |
| 180 | −static inline void assert_intel_partial_info_is_packed(void) | |
| 181 | −{ | |
| 182 | − BUILD_BUG_ON(sizeof(struct intel_partial_info) != sizeof(u64) + sizeof(unsigned int)); | |
| 183 | −} | |
| 184 | − | |
| 185 | 175 | enum i915_ggtt_view_type { |
| 186 | 176 | I915_GGTT_VIEW_NORMAL = 0, |
| 187 | 177 | I915_GGTT_VIEW_ROTATED = sizeof(struct intel_rotation_info), |
| 188 | 178 | I915_GGTT_VIEW_PARTIAL = sizeof(struct intel_partial_info), |
| 189 | 179 | }; |
| 190 | 180 | |
| 191 | −static inline void assert_i915_ggtt_view_type_is_unique(void) | |
| 181 | +static inline void assert_i915_gem_gtt_types(void) | |
| 192 | 182 | { |
| 183 | + BUILD_BUG_ON(sizeof(struct intel_rotation_info) != 8*sizeof(unsigned int)); | |
| 184 | + BUILD_BUG_ON(sizeof(struct intel_partial_info) != sizeof(u64) + sizeof(unsigned int)); | |
| 185 | + | |
| 193 | 186 | /* As we encode the size of each branch inside the union into its type, |
| 194 | 187 | * we have to be careful that each branch has a unique size. |
| 195 | 188 | */ |
| @@ -229,7 +222,6 @@ struct i915_page_dma { · 33 unmodified lines | ||
| 229 | 222 | }; |
| 230 | 223 | |
| 231 | 224 | #define px_base(px) (&(px)->base) |
| 232 | −#define px_page(px) (px_base(px)->page) | |
| 233 | 225 | #define px_dma(px) (px_base(px)->daddr) |
| 234 | 226 | |
| 235 | 227 | struct i915_page_table { |
| @@ -332,6 +324,9 @@ struct i915_address_space { · 96 unmodified lines | ||
| 332 | 324 | |
| 333 | 325 | struct pagestash free_pages; |
| 334 | 326 | |
| 327 | + /* Global GTT */ | |
| 328 | + bool is_ggtt:1; | |
| 329 | + | |
| 335 | 330 | /* Some systems require uncached updates of the page directories */ |
| 336 | 331 | bool pt_kmap_wc:1; |
| 337 | 332 | |
| @@ -365,7 +360,7 @@ struct i915_address_space { · 27 unmodified lines | ||
| 365 | 360 | I915_SELFTEST_DECLARE(bool scrub_64K); |
| 366 | 361 | }; |
| 367 | 362 | |
| 368 | −#define i915_is_ggtt(V) (!(V)->file) | |
| 363 | +#define i915_is_ggtt(vm) ((vm)->is_ggtt) | |
| 369 | 364 | |
| 370 | 365 | static inline bool |
| 371 | 366 | i915_vm_is_48bit(const struct i915_address_space *vm) |
| @@ -401,6 +396,8 @@ struct i915_ggtt { · 29 unmodified lines | ||
| 401 | 396 | |
| 402 | 397 | int mtrr; |
| 403 | 398 | |
| 399 | + u32 pin_bias; | |
| 400 | + | |
| 404 | 401 | struct drm_mm_node error_capture; |
| 405 | 402 | }; |
| 406 | 403 | |
| @@ -421,19 +421,19 @@ i915_gem_object_is_framebuffer(const struct drm_i915_gem_object *obj) · 420 unmodified lines | ||
| 421 | 421 | } |
| 422 | 422 | |
| 423 | 423 | static inline unsigned int |
| 424 | −i915_gem_object_get_tiling(struct drm_i915_gem_object *obj) | |
| 424 | +i915_gem_object_get_tiling(const struct drm_i915_gem_object *obj) | |
| 425 | 425 | { |
| 426 | 426 | return obj->tiling_and_stride & TILING_MASK; |
| 427 | 427 | } |
| 428 | 428 | |
| 429 | 429 | static inline bool |
| 430 | −i915_gem_object_is_tiled(struct drm_i915_gem_object *obj) | |
| 430 | +i915_gem_object_is_tiled(const struct drm_i915_gem_object *obj) | |
| 431 | 431 | { |
| 432 | 432 | return i915_gem_object_get_tiling(obj) != I915_TILING_NONE; |
| 433 | 433 | } |
| 434 | 434 | |
| 435 | 435 | static inline unsigned int |
| 436 | −i915_gem_object_get_stride(struct drm_i915_gem_object *obj) | |
| 436 | +i915_gem_object_get_stride(const struct drm_i915_gem_object *obj) | |
| 437 | 437 | { |
| 438 | 438 | return obj->tiling_and_stride & STRIDE_MASK; |
| 439 | 439 | } |
| @@ -446,13 +446,13 @@ i915_gem_tile_height(unsigned int tiling) · 6 unmodified lines | ||
| 446 | 446 | } |
| 447 | 447 | |
| 448 | 448 | static inline unsigned int |
| 449 | −i915_gem_object_get_tile_height(struct drm_i915_gem_object *obj) | |
| 449 | +i915_gem_object_get_tile_height(const struct drm_i915_gem_object *obj) | |
| 450 | 450 | { |
| 451 | 451 | return i915_gem_tile_height(i915_gem_object_get_tiling(obj)); |
| 452 | 452 | } |
| 453 | 453 | |
| 454 | 454 | static inline unsigned int |
| 455 | −i915_gem_object_get_tile_row_size(struct drm_i915_gem_object *obj) | |
| 455 | +i915_gem_object_get_tile_row_size(const struct drm_i915_gem_object *obj) | |
| 456 | 456 | { |
| 457 | 457 | return (i915_gem_object_get_stride(obj) * |
| 458 | 458 | i915_gem_object_get_tile_height(obj)); |
| @@ -478,7 +478,7 @@ void gen11_reset_rps_interrupts(struct drm_i915_private *dev_priv) · 477 unmodified lines | ||
| 478 | 478 | void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv) |
| 479 | 479 | { |
| 480 | 480 | spin_lock_irq(&dev_priv->irq_lock); |
| 481 | − gen6_reset_pm_iir(dev_priv, dev_priv->pm_rps_events); | |
| 481 | + gen6_reset_pm_iir(dev_priv, GEN6_PM_RPS_EVENTS); | |
| 482 | 482 | dev_priv->gt_pm.rps.pm_iir = 0; |
| 483 | 483 | spin_unlock_irq(&dev_priv->irq_lock); |
| 484 | 484 | } |
| @@ -516,7 +516,7 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv) · 31 unmodified lines | ||
| 516 | 516 | |
| 517 | 517 | I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0u)); |
| 518 | 518 | |
| 519 | − gen6_disable_pm_irq(dev_priv, dev_priv->pm_rps_events); | |
| 519 | + gen6_disable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS); | |
| 520 | 520 | |
| 521 | 521 | spin_unlock_irq(&dev_priv->irq_lock); |
| 522 | 522 | synchronize_irq(dev_priv->drm.irq); |
| @@ -1534,11 +1534,8 @@ static void gen8_gt_irq_ack(struct drm_i915_private *i915, · 1011 unmodified lines | ||
| 1534 | 1534 | |
| 1535 | 1535 | if (master_ctl & (GEN8_GT_PM_IRQ | GEN8_GT_GUC_IRQ)) { |
| 1536 | 1536 | gt_iir[2] = raw_reg_read(regs, GEN8_GT_IIR(2)); |
| 1537 | − if (likely(gt_iir[2] & (i915->pm_rps_events | | |
| 1538 | − i915->pm_guc_events))) | |
| 1539 | − raw_reg_write(regs, GEN8_GT_IIR(2), | |
| 1540 | − gt_iir[2] & (i915->pm_rps_events | | |
| 1541 | − i915->pm_guc_events)); | |
| 1537 | + if (likely(gt_iir[2])) | |
| 1538 | + raw_reg_write(regs, GEN8_GT_IIR(2), gt_iir[2]); | |
| 1542 | 1539 | } |
| 1543 | 1540 | |
| 1544 | 1541 | if (master_ctl & GEN8_GT_VECS_IRQ) { |
| @@ -3218,7 +3215,7 @@ static void i915_reset_device(struct drm_i915_private *dev_priv, · 1673 unmodified lines | ||
| 3218 | 3215 | kobject_uevent_env(kobj, KOBJ_CHANGE, reset_done_event); |
| 3219 | 3216 | } |
| 3220 | 3217 | |
| 3221 | −static void i915_clear_error_registers(struct drm_i915_private *dev_priv) | |
| 3218 | +void i915_clear_error_registers(struct drm_i915_private *dev_priv) | |
| 3222 | 3219 | { |
| 3223 | 3220 | u32 eir; |
| 3224 | 3221 | |
| @@ -3241,6 +3238,22 @@ static void i915_clear_error_registers(struct drm_i915_private *dev_priv) · 16 unmodified lines | ||
| 3241 | 3238 | I915_WRITE(EMR, I915_READ(EMR) | eir); |
| 3242 | 3239 | I915_WRITE(IIR, I915_MASTER_ERROR_INTERRUPT); |
| 3243 | 3240 | } |
| 3241 | + | |
| 3242 | + if (INTEL_GEN(dev_priv) >= 8) { | |
| 3243 | + I915_WRITE(GEN8_RING_FAULT_REG, | |
| 3244 | + I915_READ(GEN8_RING_FAULT_REG) & ~RING_FAULT_VALID); | |
| 3245 | + POSTING_READ(GEN8_RING_FAULT_REG); | |
| 3246 | + } else if (INTEL_GEN(dev_priv) >= 6) { | |
| 3247 | + struct intel_engine_cs *engine; | |
| 3248 | + enum intel_engine_id id; | |
| 3249 | + | |
| 3250 | + for_each_engine(engine, dev_priv, id) { | |
| 3251 | + I915_WRITE(RING_FAULT_REG(engine), | |
| 3252 | + I915_READ(RING_FAULT_REG(engine)) & | |
| 3253 | + ~RING_FAULT_VALID); | |
| 3254 | + } | |
| 3255 | + POSTING_READ(RING_FAULT_REG(dev_priv->engine[RCS])); | |
| 3256 | + } | |
| 3244 | 3257 | } |
| 3245 | 3258 | |
| 3246 | 3259 | /** |
| @@ -3296,7 +3309,8 @@ void i915_handle_error(struct drm_i915_private *dev_priv, · 49 unmodified lines | ||
| 3296 | 3309 | * Try engine reset when available. We fall back to full reset if |
| 3297 | 3310 | * single reset fails. |
| 3298 | 3311 | */ |
| 3299 | − if (intel_has_reset_engine(dev_priv)) { | |
| 3312 | + if (intel_has_reset_engine(dev_priv) && | |
| 3313 | + !i915_terminally_wedged(&dev_priv->gpu_error)) { | |
| 3300 | 3314 | for_each_engine_masked(engine, dev_priv, engine_mask, tmp) { |
| 3301 | 3315 | BUILD_BUG_ON(I915_RESET_MODESET >= I915_RESET_ENGINE); |
| 3302 | 3316 | if (test_and_set_bit(I915_RESET_ENGINE + engine->id, |
| @@ -4781,7 +4795,9 @@ void intel_irq_init(struct drm_i915_private *dev_priv) · 1478 unmodified lines | ||
| 4781 | 4795 | /* WaGsvRC0ResidencyMethod:vlv */ |
| 4782 | 4796 | dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED; |
| 4783 | 4797 | else |
| 4784 | − dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; | |
| 4798 | + dev_priv->pm_rps_events = (GEN6_PM_RP_UP_THRESHOLD | | |
| 4799 | + GEN6_PM_RP_DOWN_THRESHOLD | | |
| 4800 | + GEN6_PM_RP_DOWN_TIMEOUT); | |
| 4785 | 4801 | |
| 4786 | 4802 | rps->pm_intrmsk_mbz = 0; |
| 4787 | 4803 | |
| @@ -74,6 +74,7 @@ · 73 unmodified lines | ||
| 74 | 74 | .unfenced_needs_alignment = 1, \ |
| 75 | 75 | .ring_mask = RENDER_RING, \ |
| 76 | 76 | .has_snoop = true, \ |
| 77 | + .has_coherent_ggtt = false, \ | |
| 77 | 78 | GEN_DEFAULT_PIPEOFFSETS, \ |
| 78 | 79 | GEN_DEFAULT_PAGE_SIZES, \ |
| 79 | 80 | CURSOR_OFFSETS |
| @@ -110,6 +111,7 @@ static const struct intel_device_info intel_i865g_info = { · 30 unmodified lines | ||
| 110 | 111 | .has_gmch_display = 1, \ |
| 111 | 112 | .ring_mask = RENDER_RING, \ |
| 112 | 113 | .has_snoop = true, \ |
| 114 | + .has_coherent_ggtt = true, \ | |
| 113 | 115 | GEN_DEFAULT_PIPEOFFSETS, \ |
| 114 | 116 | GEN_DEFAULT_PAGE_SIZES, \ |
| 115 | 117 | CURSOR_OFFSETS |
| @@ -117,6 +119,7 @@ static const struct intel_device_info intel_i865g_info = { · 1 unmodified line | ||
| 117 | 119 | static const struct intel_device_info intel_i915g_info = { |
| 118 | 120 | GEN3_FEATURES, |
| 119 | 121 | PLATFORM(INTEL_I915G), |
| 122 | + .has_coherent_ggtt = false, | |
| 120 | 123 | .cursor_needs_physical = 1, |
| 121 | 124 | .has_overlay = 1, .overlay_needs_physical = 1, |
| 122 | 125 | .hws_needs_physical = 1, |
| @@ -178,6 +181,7 @@ static const struct intel_device_info intel_pineview_info = { · 55 unmodified lines | ||
| 178 | 181 | .has_gmch_display = 1, \ |
| 179 | 182 | .ring_mask = RENDER_RING, \ |
| 180 | 183 | .has_snoop = true, \ |
| 184 | + .has_coherent_ggtt = true, \ | |
| 181 | 185 | GEN_DEFAULT_PIPEOFFSETS, \ |
| 182 | 186 | GEN_DEFAULT_PAGE_SIZES, \ |
| 183 | 187 | CURSOR_OFFSETS |
| @@ -220,6 +224,7 @@ static const struct intel_device_info intel_gm45_info = { · 36 unmodified lines | ||
| 220 | 224 | .has_hotplug = 1, \ |
| 221 | 225 | .ring_mask = RENDER_RING | BSD_RING, \ |
| 222 | 226 | .has_snoop = true, \ |
| 227 | + .has_coherent_ggtt = true, \ | |
| 223 | 228 | /* ilk does support rc6, but we do not implement [power] contexts */ \ |
| 224 | 229 | .has_rc6 = 0, \ |
| 225 | 230 | GEN_DEFAULT_PIPEOFFSETS, \ |
| @@ -243,6 +248,7 @@ static const struct intel_device_info intel_ironlake_m_info = { · 17 unmodified lines | ||
| 243 | 248 | .has_hotplug = 1, \ |
| 244 | 249 | .has_fbc = 1, \ |
| 245 | 250 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING, \ |
| 251 | + .has_coherent_ggtt = true, \ | |
| 246 | 252 | .has_llc = 1, \ |
| 247 | 253 | .has_rc6 = 1, \ |
| 248 | 254 | .has_rc6p = 1, \ |
| @@ -287,6 +293,7 @@ static const struct intel_device_info intel_sandybridge_m_gt2_info = { · 38 unmodified lines | ||
| 287 | 293 | .has_hotplug = 1, \ |
| 288 | 294 | .has_fbc = 1, \ |
| 289 | 295 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING, \ |
| 296 | + .has_coherent_ggtt = true, \ | |
| 290 | 297 | .has_llc = 1, \ |
| 291 | 298 | .has_rc6 = 1, \ |
| 292 | 299 | .has_rc6p = 1, \ |
| @@ -347,6 +354,7 @@ static const struct intel_device_info intel_valleyview_info = { · 54 unmodified lines | ||
| 347 | 354 | .has_aliasing_ppgtt = 1, |
| 348 | 355 | .has_full_ppgtt = 1, |
| 349 | 356 | .has_snoop = true, |
| 357 | + .has_coherent_ggtt = false, | |
| 350 | 358 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING, |
| 351 | 359 | .display_mmio_offset = VLV_DISPLAY_BASE, |
| 352 | 360 | GEN_DEFAULT_PAGE_SIZES, |
| @@ -360,7 +368,6 @@ static const struct intel_device_info intel_valleyview_info = { · 7 unmodified lines | ||
| 360 | 368 | .has_ddi = 1, \ |
| 361 | 369 | .has_fpga_dbg = 1, \ |
| 362 | 370 | .has_psr = 1, \ |
| 363 | − .has_resource_streamer = 1, \ | |
| 364 | 371 | .has_dp_mst = 1, \ |
| 365 | 372 | .has_rc6p = 0 /* RC6p removed-by HSW */, \ |
| 366 | 373 | .has_runtime_pm = 1 |
| @@ -433,7 +440,6 @@ static const struct intel_device_info intel_cherryview_info = { · 66 unmodified lines | ||
| 433 | 440 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, |
| 434 | 441 | .has_64bit_reloc = 1, |
| 435 | 442 | .has_runtime_pm = 1, |
| 436 | − .has_resource_streamer = 1, | |
| 437 | 443 | .has_rc6 = 1, |
| 438 | 444 | .has_logical_ring_contexts = 1, |
| 439 | 445 | .has_gmch_display = 1, |
| @@ -441,6 +447,7 @@ static const struct intel_device_info intel_cherryview_info = { · 1 unmodified line | ||
| 441 | 447 | .has_full_ppgtt = 1, |
| 442 | 448 | .has_reset_engine = 1, |
| 443 | 449 | .has_snoop = true, |
| 450 | + .has_coherent_ggtt = false, | |
| 444 | 451 | .display_mmio_offset = VLV_DISPLAY_BASE, |
| 445 | 452 | GEN_DEFAULT_PAGE_SIZES, |
| 446 | 453 | GEN_CHV_PIPEOFFSETS, |
| @@ -506,7 +513,6 @@ static const struct intel_device_info intel_skylake_gt4_info = { · 59 unmodified lines | ||
| 506 | 513 | .has_runtime_pm = 1, \ |
| 507 | 514 | .has_pooled_eu = 0, \ |
| 508 | 515 | .has_csr = 1, \ |
| 509 | − .has_resource_streamer = 1, \ | |
| 510 | 516 | .has_rc6 = 1, \ |
| 511 | 517 | .has_dp_mst = 1, \ |
| 512 | 518 | .has_logical_ring_contexts = 1, \ |
| @@ -517,6 +523,7 @@ static const struct intel_device_info intel_skylake_gt4_info = { · 4 unmodified lines | ||
| 517 | 523 | .has_full_48bit_ppgtt = 1, \ |
| 518 | 524 | .has_reset_engine = 1, \ |
| 519 | 525 | .has_snoop = true, \ |
| 526 | + .has_coherent_ggtt = false, \ | |
| 520 | 527 | .has_ipc = 1, \ |
| 521 | 528 | GEN9_DEFAULT_PAGE_SIZES, \ |
| 522 | 529 | GEN_DEFAULT_PIPEOFFSETS, \ |
| @@ -580,6 +587,7 @@ static const struct intel_device_info intel_coffeelake_gt3_info = { · 57 unmodified lines | ||
| 580 | 587 | GEN9_FEATURES, \ |
| 581 | 588 | GEN(10), \ |
| 582 | 589 | .ddb_size = 1024, \ |
| 590 | + .has_coherent_ggtt = false, \ | |
| 583 | 591 | GLK_COLORS |
| 584 | 592 | |
| 585 | 593 | static const struct intel_device_info intel_cannonlake_info = { |
| @@ -592,14 +600,12 @@ static const struct intel_device_info intel_cannonlake_info = { · 6 unmodified lines | ||
| 592 | 600 | GEN10_FEATURES, \ |
| 593 | 601 | GEN(11), \ |
| 594 | 602 | .ddb_size = 2048, \ |
| 595 | − .has_csr = 0, \ | |
| 596 | 603 | .has_logical_ring_elsq = 1 |
| 597 | 604 | |
| 598 | 605 | static const struct intel_device_info intel_icelake_11_info = { |
| 599 | 606 | GEN11_FEATURES, |
| 600 | 607 | PLATFORM(INTEL_ICELAKE), |
| 601 | 608 | .is_alpha_support = 1, |
| 602 | − .has_resource_streamer = 0, | |
| 603 | 609 | .ring_mask = RENDER_RING | BLT_RING | VEBOX_RING | BSD_RING | BSD3_RING, |
| 604 | 610 | }; |
| 605 | 611 | |
| @@ -210,6 +210,7 @@ · 209 unmodified lines | ||
| 210 | 210 | #include "i915_oa_cflgt3.h" |
| 211 | 211 | #include "i915_oa_cnl.h" |
| 212 | 212 | #include "i915_oa_icl.h" |
| 213 | +#include "intel_lrc_reg.h" | |
| 213 | 214 | |
| 214 | 215 | /* HW requires this to be a power of two, between 128k and 16M, though driver |
| 215 | 216 | * is currently generally designed assuming the largest 16M size is used such |
| @@ -1338,14 +1339,12 @@ free_oa_buffer(struct drm_i915_private *i915) · 1122 unmodified lines | ||
| 1338 | 1339 | { |
| 1339 | 1340 | mutex_lock(&i915->drm.struct_mutex); |
| 1340 | 1341 | |
| 1341 | − i915_gem_object_unpin_map(i915->perf.oa.oa_buffer.vma->obj); | |
| 1342 | − i915_vma_unpin(i915->perf.oa.oa_buffer.vma); | |
| 1343 | − i915_gem_object_put(i915->perf.oa.oa_buffer.vma->obj); | |
| 1344 | − | |
| 1345 | − i915->perf.oa.oa_buffer.vma = NULL; | |
| 1346 | − i915->perf.oa.oa_buffer.vaddr = NULL; | |
| 1342 | + i915_vma_unpin_and_release(&i915->perf.oa.oa_buffer.vma, | |
| 1343 | + I915_VMA_RELEASE_MAP); | |
| 1347 | 1344 | |
| 1348 | 1345 | mutex_unlock(&i915->drm.struct_mutex); |
| 1346 | + | |
| 1347 | + i915->perf.oa.oa_buffer.vaddr = NULL; | |
| 1349 | 1348 | } |
| 1350 | 1349 | |
| 1351 | 1350 | static void i915_oa_stream_destroy(struct i915_perf_stream *stream) |
| @@ -1638,27 +1637,25 @@ static void gen8_update_reg_state_unlocked(struct i915_gem_context *ctx, · 286 unmodified lines | ||
| 1638 | 1637 | u32 ctx_oactxctrl = dev_priv->perf.oa.ctx_oactxctrl_offset; |
| 1639 | 1638 | u32 ctx_flexeu0 = dev_priv->perf.oa.ctx_flexeu0_offset; |
| 1640 | 1639 | /* The MMIO offsets for Flex EU registers aren't contiguous */ |
| 1641 | − u32 flex_mmio[] = { | |
| 1642 | − i915_mmio_reg_offset(EU_PERF_CNTL0), | |
| 1643 | − i915_mmio_reg_offset(EU_PERF_CNTL1), | |
| 1644 | − i915_mmio_reg_offset(EU_PERF_CNTL2), | |
| 1645 | − i915_mmio_reg_offset(EU_PERF_CNTL3), | |
| 1646 | − i915_mmio_reg_offset(EU_PERF_CNTL4), | |
| 1647 | − i915_mmio_reg_offset(EU_PERF_CNTL5), | |
| 1648 | − i915_mmio_reg_offset(EU_PERF_CNTL6), | |
| 1640 | + i915_reg_t flex_regs[] = { | |
| 1641 | + EU_PERF_CNTL0, | |
| 1642 | + EU_PERF_CNTL1, | |
| 1643 | + EU_PERF_CNTL2, | |
| 1644 | + EU_PERF_CNTL3, | |
| 1645 | + EU_PERF_CNTL4, | |
| 1646 | + EU_PERF_CNTL5, | |
| 1647 | + EU_PERF_CNTL6, | |
| 1649 | 1648 | }; |
| 1650 | 1649 | int i; |
| 1651 | 1650 | |
| 1652 | − reg_state[ctx_oactxctrl] = i915_mmio_reg_offset(GEN8_OACTXCONTROL); | |
| 1653 | − reg_state[ctx_oactxctrl+1] = (dev_priv->perf.oa.period_exponent << | |
| 1654 | − GEN8_OA_TIMER_PERIOD_SHIFT) | | |
| 1655 | − (dev_priv->perf.oa.periodic ? | |
| 1656 | − GEN8_OA_TIMER_ENABLE : 0) | | |
| 1657 | − GEN8_OA_COUNTER_RESUME; | |
| 1651 | + CTX_REG(reg_state, ctx_oactxctrl, GEN8_OACTXCONTROL, | |
| 1652 | + (dev_priv->perf.oa.period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) | | |
| 1653 | + (dev_priv->perf.oa.periodic ? GEN8_OA_TIMER_ENABLE : 0) | | |
| 1654 | + GEN8_OA_COUNTER_RESUME); | |
| 1658 | 1655 | |
| 1659 | − for (i = 0; i < ARRAY_SIZE(flex_mmio); i++) { | |
| 1656 | + for (i = 0; i < ARRAY_SIZE(flex_regs); i++) { | |
| 1660 | 1657 | u32 state_offset = ctx_flexeu0 + i * 2; |
| 1661 | − u32 mmio = flex_mmio[i]; | |
| 1658 | + u32 mmio = i915_mmio_reg_offset(flex_regs[i]); | |
| 1662 | 1659 | |
| 1663 | 1660 | /* |
| 1664 | 1661 | * This arbitrary default will select the 'EU FPU0 Pipeline |
| @@ -1678,8 +1675,7 @@ static void gen8_update_reg_state_unlocked(struct i915_gem_context *ctx, · 13 unmodified lines | ||
| 1678 | 1675 | } |
| 1679 | 1676 | } |
| 1680 | 1677 | |
| 1681 | − reg_state[state_offset] = mmio; | |
| 1682 | − reg_state[state_offset+1] = value; | |
| 1678 | + CTX_REG(reg_state, state_offset, flex_regs[i], value); | |
| 1683 | 1679 | } |
| 1684 | 1680 | } |
| 1685 | 1681 | |
| @@ -1821,7 +1817,7 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv, · 135 unmodified lines | ||
| 1821 | 1817 | /* Switch away from any user context. */ |
| 1822 | 1818 | ret = gen8_switch_to_updated_kernel_context(dev_priv, oa_config); |
| 1823 | 1819 | if (ret) |
| 1824 | − goto out; | |
| 1820 | + return ret; | |
| 1825 | 1821 | |
| 1826 | 1822 | /* |
| 1827 | 1823 | * The OA register config is setup through the context image. This image |
| @@ -1840,7 +1836,7 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv, · 12 unmodified lines | ||
| 1840 | 1836 | wait_flags, |
| 1841 | 1837 | MAX_SCHEDULE_TIMEOUT); |
| 1842 | 1838 | if (ret) |
| 1843 | − goto out; | |
| 1839 | + return ret; | |
| 1844 | 1840 | |
| 1845 | 1841 | /* Update all contexts now that we've stalled the submission. */ |
| 1846 | 1842 | list_for_each_entry(ctx, &dev_priv->contexts.list, link) { |
| @@ -1852,10 +1848,8 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv, · 5 unmodified lines | ||
| 1852 | 1848 | continue; |
| 1853 | 1849 | |
| 1854 | 1850 | regs = i915_gem_object_pin_map(ce->state->obj, I915_MAP_WB); |
| 1855 | − if (IS_ERR(regs)) { | |
| 1856 | − ret = PTR_ERR(regs); | |
| 1857 | − goto out; | |
| 1858 | − } | |
| 1851 | + if (IS_ERR(regs)) | |
| 1852 | + return PTR_ERR(regs); | |
| 1859 | 1853 | |
| 1860 | 1854 | ce->state->obj->mm.dirty = true; |
| 1861 | 1855 | regs += LRC_STATE_PN * PAGE_SIZE / sizeof(*regs); |
| @@ -1865,7 +1859,6 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv, · 3 unmodified lines | ||
| 1865 | 1859 | i915_gem_object_unpin_map(ce->state->obj); |
| 1866 | 1860 | } |
| 1867 | 1861 | |
| 1868 | − out: | |
| 1869 | 1862 | return ret; |
| 1870 | 1863 | } |
| 1871 | 1864 | |
| @@ -344,6 +344,8 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) · 343 unmodified lines | ||
| 344 | 344 | #define GEN8_RPCS_S_CNT_ENABLE (1 << 18) |
| 345 | 345 | #define GEN8_RPCS_S_CNT_SHIFT 15 |
| 346 | 346 | #define GEN8_RPCS_S_CNT_MASK (0x7 << GEN8_RPCS_S_CNT_SHIFT) |
| 347 | +#define GEN11_RPCS_S_CNT_SHIFT 12 | |
| 348 | +#define GEN11_RPCS_S_CNT_MASK (0x3f << GEN11_RPCS_S_CNT_SHIFT) | |
| 347 | 349 | #define GEN8_RPCS_SS_CNT_ENABLE (1 << 11) |
| 348 | 350 | #define GEN8_RPCS_SS_CNT_SHIFT 8 |
| 349 | 351 | #define GEN8_RPCS_SS_CNT_MASK (0x7 << GEN8_RPCS_SS_CNT_SHIFT) |
| @@ -1029,126 +1031,43 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) · 679 unmodified lines | ||
| 1029 | 1031 | /* |
| 1030 | 1032 | * i915_power_well_id: |
| 1031 | 1033 | * |
| 1032 | − * Platform specific IDs used to look up power wells and - except for custom | |
| 1033 | − * power wells - to define request/status register flag bit positions. As such | |
| 1034 | − * the set of IDs on a given platform must be unique and except for custom | |
| 1035 | − * power wells their value must stay fixed. | |
| 1034 | + * IDs used to look up power wells. Power wells accessed directly bypassing | |
| 1035 | + * the power domains framework must be assigned a unique ID. The rest of power | |
| 1036 | + * wells must be assigned DISP_PW_ID_NONE. | |
| 1036 | 1037 | */ |
| 1037 | 1038 | enum i915_power_well_id { |
| 1038 | − /* | |
| 1039 | − * I830 | |
| 1040 | − * - custom power well | |
| 1041 | − */ | |
| 1042 | − I830_DISP_PW_PIPES = 0, | |
| 1043 | − | |
| 1044 | − /* | |
| 1045 | − * VLV/CHV | |
| 1046 | − * - PUNIT_REG_PWRGT_CTRL (bit: id*2), | |
| 1047 | − * PUNIT_REG_PWRGT_STATUS (bit: id*2) (PUNIT HAS v0.8) | |
| 1048 | − */ | |
| 1049 | − PUNIT_POWER_WELL_RENDER = 0, | |
| 1050 | − PUNIT_POWER_WELL_MEDIA = 1, | |
| 1051 | − PUNIT_POWER_WELL_DISP2D = 3, | |
| 1052 | − PUNIT_POWER_WELL_DPIO_CMN_BC = 5, | |
| 1053 | − PUNIT_POWER_WELL_DPIO_TX_B_LANES_01 = 6, | |
| 1054 | − PUNIT_POWER_WELL_DPIO_TX_B_LANES_23 = 7, | |
| 1055 | − PUNIT_POWER_WELL_DPIO_TX_C_LANES_01 = 8, | |
| 1056 | − PUNIT_POWER_WELL_DPIO_TX_C_LANES_23 = 9, | |
| 1057 | − PUNIT_POWER_WELL_DPIO_RX0 = 10, | |
| 1058 | − PUNIT_POWER_WELL_DPIO_RX1 = 11, | |
| 1059 | − PUNIT_POWER_WELL_DPIO_CMN_D = 12, | |
| 1060 | − /* - custom power well */ | |
| 1061 | − CHV_DISP_PW_PIPE_A, /* 13 */ | |
| 1062 | − | |
| 1063 | − /* | |
| 1064 | − * HSW/BDW | |
| 1065 | − * - _HSW_PWR_WELL_CTL1-4 (status bit: id*2, req bit: id*2+1) | |
| 1066 | − */ | |
| 1067 | − HSW_DISP_PW_GLOBAL = 15, | |
| 1068 | − | |
| 1069 | − /* | |
| 1070 | − * GEN9+ | |
| 1071 | − * - _HSW_PWR_WELL_CTL1-4 (status bit: id*2, req bit: id*2+1) | |
| 1072 | − */ | |
| 1073 | − SKL_DISP_PW_MISC_IO = 0, | |
| 1074 | − SKL_DISP_PW_DDI_A_E, | |
| 1075 | − GLK_DISP_PW_DDI_A = SKL_DISP_PW_DDI_A_E, | |
| 1076 | − CNL_DISP_PW_DDI_A = SKL_DISP_PW_DDI_A_E, | |
| 1077 | − SKL_DISP_PW_DDI_B, | |
| 1078 | − SKL_DISP_PW_DDI_C, | |
| 1079 | − SKL_DISP_PW_DDI_D, | |
| 1080 | − CNL_DISP_PW_DDI_F = 6, | |
| 1081 | − | |
| 1082 | − GLK_DISP_PW_AUX_A = 8, | |
| 1083 | − GLK_DISP_PW_AUX_B, | |
| 1084 | − GLK_DISP_PW_AUX_C, | |
| 1085 | − CNL_DISP_PW_AUX_A = GLK_DISP_PW_AUX_A, | |
| 1086 | − CNL_DISP_PW_AUX_B = GLK_DISP_PW_AUX_B, | |
| 1087 | − CNL_DISP_PW_AUX_C = GLK_DISP_PW_AUX_C, | |
| 1088 | − CNL_DISP_PW_AUX_D, | |
| 1089 | − CNL_DISP_PW_AUX_F, | |
| 1090 | − | |
| 1091 | − SKL_DISP_PW_1 = 14, | |
| 1039 | + DISP_PW_ID_NONE, | |
| 1040 | + | |
| 1041 | + VLV_DISP_PW_DISP2D, | |
| 1042 | + BXT_DISP_PW_DPIO_CMN_A, | |
| 1043 | + VLV_DISP_PW_DPIO_CMN_BC, | |
| 1044 | + GLK_DISP_PW_DPIO_CMN_C, | |
| 1045 | + CHV_DISP_PW_DPIO_CMN_D, | |
| 1046 | + HSW_DISP_PW_GLOBAL, | |
| 1047 | + SKL_DISP_PW_MISC_IO, | |
| 1048 | + SKL_DISP_PW_1, | |
| 1092 | 1049 | SKL_DISP_PW_2, |
| 1093 | − | |
| 1094 | − /* - custom power wells */ | |
| 1095 | − BXT_DPIO_CMN_A, | |
| 1096 | − BXT_DPIO_CMN_BC, | |
| 1097 | − GLK_DPIO_CMN_C, /* 18 */ | |
| 1098 | − | |
| 1099 | − /* | |
| 1100 | − * GEN11+ | |
| 1101 | − * - _HSW_PWR_WELL_CTL1-4 | |
| 1102 | − * (status bit: (id&15)*2, req bit:(id&15)*2+1) | |
| 1103 | − */ | |
| 1104 | − ICL_DISP_PW_1 = 0, | |
| 1105 | − ICL_DISP_PW_2, | |
| 1106 | − ICL_DISP_PW_3, | |
| 1107 | − ICL_DISP_PW_4, | |
| 1108 | − | |
| 1109 | − /* | |
| 1110 | − * - _HSW_PWR_WELL_CTL_AUX1/2/4 | |
| 1111 | − * (status bit: (id&15)*2, req bit:(id&15)*2+1) | |
| 1112 | − */ | |
| 1113 | − ICL_DISP_PW_AUX_A = 16, | |
| 1114 | − ICL_DISP_PW_AUX_B, | |
| 1115 | − ICL_DISP_PW_AUX_C, | |
| 1116 | − ICL_DISP_PW_AUX_D, | |
| 1117 | − ICL_DISP_PW_AUX_E, | |
| 1118 | − ICL_DISP_PW_AUX_F, | |
| 1119 | − | |
| 1120 | − ICL_DISP_PW_AUX_TBT1 = 24, | |
| 1121 | − ICL_DISP_PW_AUX_TBT2, | |
| 1122 | − ICL_DISP_PW_AUX_TBT3, | |
| 1123 | − ICL_DISP_PW_AUX_TBT4, | |
| 1124 | − | |
| 1125 | − /* | |
| 1126 | − * - _HSW_PWR_WELL_CTL_DDI1/2/4 | |
| 1127 | − * (status bit: (id&15)*2, req bit:(id&15)*2+1) | |
| 1128 | − */ | |
| 1129 | − ICL_DISP_PW_DDI_A = 32, | |
| 1130 | − ICL_DISP_PW_DDI_B, | |
| 1131 | − ICL_DISP_PW_DDI_C, | |
| 1132 | − ICL_DISP_PW_DDI_D, | |
| 1133 | − ICL_DISP_PW_DDI_E, | |
| 1134 | − ICL_DISP_PW_DDI_F, /* 37 */ | |
| 1135 | − | |
| 1136 | − /* | |
| 1137 | − * Multiple platforms. | |
| 1138 | − * Must start following the highest ID of any platform. | |
| 1139 | − * - custom power wells | |
| 1140 | − */ | |
| 1141 | − SKL_DISP_PW_DC_OFF = 38, | |
| 1142 | − I915_DISP_PW_ALWAYS_ON, | |
| 1143 | 1050 | }; |
| 1144 | 1051 | |
| 1145 | 1052 | #define PUNIT_REG_PWRGT_CTRL 0x60 |
| 1146 | 1053 | #define PUNIT_REG_PWRGT_STATUS 0x61 |
| 1147 | −#define PUNIT_PWRGT_MASK(power_well) (3 << ((power_well) * 2)) | |
| 1148 | −#define PUNIT_PWRGT_PWR_ON(power_well) (0 << ((power_well) * 2)) | |
| 1149 | −#define PUNIT_PWRGT_CLK_GATE(power_well) (1 << ((power_well) * 2)) | |
| 1150 | −#define PUNIT_PWRGT_RESET(power_well) (2 << ((power_well) * 2)) | |
| 1151 | −#define PUNIT_PWRGT_PWR_GATE(power_well) (3 << ((power_well) * 2)) | |
| 1054 | +#define PUNIT_PWRGT_MASK(pw_idx) (3 << ((pw_idx) * 2)) | |
| 1055 | +#define PUNIT_PWRGT_PWR_ON(pw_idx) (0 << ((pw_idx) * 2)) | |
| 1056 | +#define PUNIT_PWRGT_CLK_GATE(pw_idx) (1 << ((pw_idx) * 2)) | |
| 1057 | +#define PUNIT_PWRGT_RESET(pw_idx) (2 << ((pw_idx) * 2)) | |
| 1058 | +#define PUNIT_PWRGT_PWR_GATE(pw_idx) (3 << ((pw_idx) * 2)) | |
| 1059 | + | |
| 1060 | +#define PUNIT_PWGT_IDX_RENDER 0 | |
| 1061 | +#define PUNIT_PWGT_IDX_MEDIA 1 | |
| 1062 | +#define PUNIT_PWGT_IDX_DISP2D 3 | |
| 1063 | +#define PUNIT_PWGT_IDX_DPIO_CMN_BC 5 | |
| 1064 | +#define PUNIT_PWGT_IDX_DPIO_TX_B_LANES_01 6 | |
| 1065 | +#define PUNIT_PWGT_IDX_DPIO_TX_B_LANES_23 7 | |
| 1066 | +#define PUNIT_PWGT_IDX_DPIO_TX_C_LANES_01 8 | |
| 1067 | +#define PUNIT_PWGT_IDX_DPIO_TX_C_LANES_23 9 | |
| 1068 | +#define PUNIT_PWGT_IDX_DPIO_RX0 10 | |
| 1069 | +#define PUNIT_PWGT_IDX_DPIO_RX1 11 | |
| 1070 | +#define PUNIT_PWGT_IDX_DPIO_CMN_D 12 | |
| 1152 | 1071 | |
| 1153 | 1072 | #define PUNIT_REG_GPU_LFM 0xd3 |
| 1154 | 1073 | #define PUNIT_REG_GPU_FREQ_REQ 0xd4 |
| @@ -1932,121 +1851,200 @@ enum i915_power_well_id { · 777 unmodified lines | ||
| 1932 | 1851 | #define N_SCALAR(x) ((x) << 24) |
| 1933 | 1852 | #define N_SCALAR_MASK (0x7F << 24) |
| 1934 | 1853 | |
| 1935 | −#define _ICL_MG_PHY_PORT_LN(port, ln, ln0p1, ln0p2, ln1p1) \ | |
| 1854 | +#define MG_PHY_PORT_LN(port, ln, ln0p1, ln0p2, ln1p1) \ | |
| 1936 | 1855 | _MMIO(_PORT((port) - PORT_C, ln0p1, ln0p2) + (ln) * ((ln1p1) - (ln0p1))) |
| 1937 | 1856 | |
| 1938 | −#define _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT1 0x16812C | |
| 1939 | −#define _ICL_MG_TX_LINK_PARAMS_TX1LN1_PORT1 0x16852C | |
| 1940 | −#define _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT2 0x16912C | |
| 1941 | −#define _ICL_MG_TX_LINK_PARAMS_TX1LN1_PORT2 0x16952C | |
| 1942 | −#define _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT3 0x16A12C | |
| 1943 | −#define _ICL_MG_TX_LINK_PARAMS_TX1LN1_PORT3 0x16A52C | |
| 1944 | −#define _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT4 0x16B12C | |
| 1945 | −#define _ICL_MG_TX_LINK_PARAMS_TX1LN1_PORT4 0x16B52C | |
| 1946 | −#define ICL_PORT_MG_TX1_LINK_PARAMS(port, ln) \ | |
| 1947 | − _ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT1, \ | |
| 1948 | − _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT2, \ | |
| 1949 | − _ICL_MG_TX_LINK_PARAMS_TX1LN1_PORT1) | |
| 1950 | − | |
| 1951 | −#define _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT1 0x1680AC | |
| 1952 | −#define _ICL_MG_TX_LINK_PARAMS_TX2LN1_PORT1 0x1684AC | |
| 1953 | −#define _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT2 0x1690AC | |
| 1954 | −#define _ICL_MG_TX_LINK_PARAMS_TX2LN1_PORT2 0x1694AC | |
| 1955 | −#define _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT3 0x16A0AC | |
| 1956 | −#define _ICL_MG_TX_LINK_PARAMS_TX2LN1_PORT3 0x16A4AC | |
| 1957 | −#define _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT4 0x16B0AC | |
| 1958 | −#define _ICL_MG_TX_LINK_PARAMS_TX2LN1_PORT4 0x16B4AC | |
| 1959 | −#define ICL_PORT_MG_TX2_LINK_PARAMS(port, ln) \ | |
| 1960 | − _ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT1, \ | |
| 1961 | − _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT2, \ | |
| 1962 | − _ICL_MG_TX_LINK_PARAMS_TX2LN1_PORT1) | |
| 1963 | −#define CRI_USE_FS32 (1 << 5) | |
| 1964 | − | |
| 1965 | −#define _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT1 0x16814C | |
| 1966 | −#define _ICL_MG_TX_PISO_READLOAD_TX1LN1_PORT1 0x16854C | |
| 1967 | −#define _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT2 0x16914C | |
| 1968 | −#define _ICL_MG_TX_PISO_READLOAD_TX1LN1_PORT2 0x16954C | |
| 1969 | −#define _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT3 0x16A14C | |
| 1970 | −#define _ICL_MG_TX_PISO_READLOAD_TX1LN1_PORT3 0x16A54C | |
| 1971 | −#define _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT4 0x16B14C | |
| 1972 | −#define _ICL_MG_TX_PISO_READLOAD_TX1LN1_PORT4 0x16B54C | |
| 1973 | −#define ICL_PORT_MG_TX1_PISO_READLOAD(port, ln) \ | |
| 1974 | − _ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT1, \ | |
| 1975 | − _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT2, \ | |
| 1976 | − _ICL_MG_TX_PISO_READLOAD_TX1LN1_PORT1) | |
| 1977 | − | |
| 1978 | −#define _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT1 0x1680CC | |
| 1979 | −#define _ICL_MG_TX_PISO_READLOAD_TX2LN1_PORT1 0x1684CC | |
| 1980 | −#define _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT2 0x1690CC | |
| 1981 | −#define _ICL_MG_TX_PISO_READLOAD_TX2LN1_PORT2 0x1694CC | |
| 1982 | −#define _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT3 0x16A0CC | |
| 1983 | −#define _ICL_MG_TX_PISO_READLOAD_TX2LN1_PORT3 0x16A4CC | |
| 1984 | −#define _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT4 0x16B0CC | |
| 1985 | −#define _ICL_MG_TX_PISO_READLOAD_TX2LN1_PORT4 0x16B4CC | |
| 1986 | −#define ICL_PORT_MG_TX2_PISO_READLOAD(port, ln) \ | |
| 1987 | − _ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT1, \ | |
| 1988 | − _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT2, \ | |
| 1989 | − _ICL_MG_TX_PISO_READLOAD_TX2LN1_PORT1) | |
| 1990 | −#define CRI_CALCINIT (1 << 1) | |
| 1991 | − | |
| 1992 | −#define _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT1 0x168148 | |
| 1993 | −#define _ICL_MG_TX_SWINGCTRL_TX1LN1_PORT1 0x168548 | |
| 1994 | −#define _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT2 0x169148 | |
| 1995 | −#define _ICL_MG_TX_SWINGCTRL_TX1LN1_PORT2 0x169548 | |
| 1996 | −#define _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT3 0x16A148 | |
| 1997 | −#define _ICL_MG_TX_SWINGCTRL_TX1LN1_PORT3 0x16A548 | |
| 1998 | −#define _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT4 0x16B148 | |
| 1999 | −#define _ICL_MG_TX_SWINGCTRL_TX1LN1_PORT4 0x16B548 | |
| 2000 | −#define ICL_PORT_MG_TX1_SWINGCTRL(port, ln) \ | |
| 2001 | − _ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT1, \ | |
| 2002 | − _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT2, \ | |
| 2003 | − _ICL_MG_TX_SWINGCTRL_TX1LN1_PORT1) | |
| 2004 | − | |
| 2005 | −#define _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT1 0x1680C8 | |
| 2006 | −#define _ICL_MG_TX_SWINGCTRL_TX2LN1_PORT1 0x1684C8 | |
| 2007 | −#define _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT2 0x1690C8 | |
| 2008 | −#define _ICL_MG_TX_SWINGCTRL_TX2LN1_PORT2 0x1694C8 | |
| 2009 | −#define _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT3 0x16A0C8 | |
| 2010 | −#define _ICL_MG_TX_SWINGCTRL_TX2LN1_PORT3 0x16A4C8 | |
| 2011 | −#define _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT4 0x16B0C8 | |
| 2012 | −#define _ICL_MG_TX_SWINGCTRL_TX2LN1_PORT4 0x16B4C8 | |
| 2013 | −#define ICL_PORT_MG_TX2_SWINGCTRL(port, ln) \ | |
| 2014 | − _ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT1, \ | |
| 2015 | − _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT2, \ | |
| 2016 | − _ICL_MG_TX_SWINGCTRL_TX2LN1_PORT1) | |
| 2017 | −#define CRI_TXDEEMPH_OVERRIDE_17_12(x) ((x) << 0) | |
| 2018 | −#define CRI_TXDEEMPH_OVERRIDE_17_12_MASK (0x3F << 0) | |
| 2019 | − | |
| 2020 | −#define _ICL_MG_TX_DRVCTRL_TX1LN0_PORT1 0x168144 | |
| 2021 | −#define _ICL_MG_TX_DRVCTRL_TX1LN1_PORT1 0x168544 | |
| 2022 | −#define _ICL_MG_TX_DRVCTRL_TX1LN0_PORT2 0x169144 | |
| 2023 | −#define _ICL_MG_TX_DRVCTRL_TX1LN1_PORT2 0x169544 | |
| 2024 | −#define _ICL_MG_TX_DRVCTRL_TX1LN0_PORT3 0x16A144 | |
| 2025 | −#define _ICL_MG_TX_DRVCTRL_TX1LN1_PORT3 0x16A544 | |
| 2026 | −#define _ICL_MG_TX_DRVCTRL_TX1LN0_PORT4 0x16B144 | |
| 2027 | −#define _ICL_MG_TX_DRVCTRL_TX1LN1_PORT4 0x16B544 | |
| 2028 | −#define ICL_PORT_MG_TX1_DRVCTRL(port, ln) \ | |
| 2029 | − _ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_DRVCTRL_TX1LN0_PORT1, \ | |
| 2030 | − _ICL_MG_TX_DRVCTRL_TX1LN0_PORT2, \ | |
| 2031 | − _ICL_MG_TX_DRVCTRL_TX1LN1_PORT1) | |
| 2032 | − | |
| 2033 | −#define _ICL_MG_TX_DRVCTRL_TX2LN0_PORT1 0x1680C4 | |
| 2034 | −#define _ICL_MG_TX_DRVCTRL_TX2LN1_PORT1 0x1684C4 | |
| 2035 | −#define _ICL_MG_TX_DRVCTRL_TX2LN0_PORT2 0x1690C4 | |
| 2036 | −#define _ICL_MG_TX_DRVCTRL_TX2LN1_PORT2 0x1694C4 | |
| 2037 | −#define _ICL_MG_TX_DRVCTRL_TX2LN0_PORT3 0x16A0C4 | |
| 2038 | −#define _ICL_MG_TX_DRVCTRL_TX2LN1_PORT3 0x16A4C4 | |
| 2039 | −#define _ICL_MG_TX_DRVCTRL_TX2LN0_PORT4 0x16B0C4 | |
| 2040 | −#define _ICL_MG_TX_DRVCTRL_TX2LN1_PORT4 0x16B4C4 | |
| 2041 | −#define ICL_PORT_MG_TX2_DRVCTRL(port, ln) \ | |
| 2042 | − _ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_DRVCTRL_TX2LN0_PORT1, \ | |
| 2043 | − _ICL_MG_TX_DRVCTRL_TX2LN0_PORT2, \ | |
| 2044 | − _ICL_MG_TX_DRVCTRL_TX2LN1_PORT1) | |
| 2045 | −#define CRI_TXDEEMPH_OVERRIDE_11_6(x) ((x) << 24) | |
| 2046 | −#define CRI_TXDEEMPH_OVERRIDE_11_6_MASK (0x3F << 24) | |
| 2047 | −#define CRI_TXDEEMPH_OVERRIDE_EN (1 << 22) | |
| 2048 | −#define CRI_TXDEEMPH_OVERRIDE_5_0(x) ((x) << 16) | |
| 2049 | −#define CRI_TXDEEMPH_OVERRIDE_5_0_MASK (0x3F << 16) | |
| 1857 | +#define MG_TX_LINK_PARAMS_TX1LN0_PORT1 0x16812C | |
| 1858 | +#define MG_TX_LINK_PARAMS_TX1LN1_PORT1 0x16852C | |
| 1859 | +#define MG_TX_LINK_PARAMS_TX1LN0_PORT2 0x16912C | |
| 1860 | +#define MG_TX_LINK_PARAMS_TX1LN1_PORT2 0x16952C | |
| 1861 | +#define MG_TX_LINK_PARAMS_TX1LN0_PORT3 0x16A12C | |
| 1862 | +#define MG_TX_LINK_PARAMS_TX1LN1_PORT3 0x16A52C | |
| 1863 | +#define MG_TX_LINK_PARAMS_TX1LN0_PORT4 0x16B12C | |
| 1864 | +#define MG_TX_LINK_PARAMS_TX1LN1_PORT4 0x16B52C | |
| 1865 | +#define MG_TX1_LINK_PARAMS(port, ln) \ | |
| 1866 | + MG_PHY_PORT_LN(port, ln, MG_TX_LINK_PARAMS_TX1LN0_PORT1, \ | |
| 1867 | + MG_TX_LINK_PARAMS_TX1LN0_PORT2, \ | |
| 1868 | + MG_TX_LINK_PARAMS_TX1LN1_PORT1) | |
| 1869 | + | |
| 1870 | +#define MG_TX_LINK_PARAMS_TX2LN0_PORT1 0x1680AC | |
| 1871 | +#define MG_TX_LINK_PARAMS_TX2LN1_PORT1 0x1684AC | |
| 1872 | +#define MG_TX_LINK_PARAMS_TX2LN0_PORT2 0x1690AC | |
| 1873 | +#define MG_TX_LINK_PARAMS_TX2LN1_PORT2 0x1694AC | |
| 1874 | +#define MG_TX_LINK_PARAMS_TX2LN0_PORT3 0x16A0AC | |
| 1875 | +#define MG_TX_LINK_PARAMS_TX2LN1_PORT3 0x16A4AC | |
| 1876 | +#define MG_TX_LINK_PARAMS_TX2LN0_PORT4 0x16B0AC | |
| 1877 | +#define MG_TX_LINK_PARAMS_TX2LN1_PORT4 0x16B4AC | |
| 1878 | +#define MG_TX2_LINK_PARAMS(port, ln) \ | |
| 1879 | + MG_PHY_PORT_LN(port, ln, MG_TX_LINK_PARAMS_TX2LN0_PORT1, \ | |
| 1880 | + MG_TX_LINK_PARAMS_TX2LN0_PORT2, \ | |
| 1881 | + MG_TX_LINK_PARAMS_TX2LN1_PORT1) | |
| 1882 | +#define CRI_USE_FS32 (1 << 5) | |
| 1883 | + | |
| 1884 | +#define MG_TX_PISO_READLOAD_TX1LN0_PORT1 0x16814C | |
| 1885 | +#define MG_TX_PISO_READLOAD_TX1LN1_PORT1 0x16854C | |
| 1886 | +#define MG_TX_PISO_READLOAD_TX1LN0_PORT2 0x16914C | |
| 1887 | +#define MG_TX_PISO_READLOAD_TX1LN1_PORT2 0x16954C | |
| 1888 | +#define MG_TX_PISO_READLOAD_TX1LN0_PORT3 0x16A14C | |
| 1889 | +#define MG_TX_PISO_READLOAD_TX1LN1_PORT3 0x16A54C | |
| 1890 | +#define MG_TX_PISO_READLOAD_TX1LN0_PORT4 0x16B14C | |
| 1891 | +#define MG_TX_PISO_READLOAD_TX1LN1_PORT4 0x16B54C | |
| 1892 | +#define MG_TX1_PISO_READLOAD(port, ln) \ | |
| 1893 | + MG_PHY_PORT_LN(port, ln, MG_TX_PISO_READLOAD_TX1LN0_PORT1, \ | |
| 1894 | + MG_TX_PISO_READLOAD_TX1LN0_PORT2, \ | |
| 1895 | + MG_TX_PISO_READLOAD_TX1LN1_PORT1) | |
| 1896 | + | |
| 1897 | +#define MG_TX_PISO_READLOAD_TX2LN0_PORT1 0x1680CC | |
| 1898 | +#define MG_TX_PISO_READLOAD_TX2LN1_PORT1 0x1684CC | |
| 1899 | +#define MG_TX_PISO_READLOAD_TX2LN0_PORT2 0x1690CC | |
| 1900 | +#define MG_TX_PISO_READLOAD_TX2LN1_PORT2 0x1694CC | |
| 1901 | +#define MG_TX_PISO_READLOAD_TX2LN0_PORT3 0x16A0CC | |
| 1902 | +#define MG_TX_PISO_READLOAD_TX2LN1_PORT3 0x16A4CC | |
| 1903 | +#define MG_TX_PISO_READLOAD_TX2LN0_PORT4 0x16B0CC | |
| 1904 | +#define MG_TX_PISO_READLOAD_TX2LN1_PORT4 0x16B4CC | |
| 1905 | +#define MG_TX2_PISO_READLOAD(port, ln) \ | |
| 1906 | + MG_PHY_PORT_LN(port, ln, MG_TX_PISO_READLOAD_TX2LN0_PORT1, \ | |
| 1907 | + MG_TX_PISO_READLOAD_TX2LN0_PORT2, \ | |
| 1908 | + MG_TX_PISO_READLOAD_TX2LN1_PORT1) | |
| 1909 | +#define CRI_CALCINIT (1 << 1) | |
| 1910 | + | |
| 1911 | +#define MG_TX_SWINGCTRL_TX1LN0_PORT1 0x168148 | |
| 1912 | +#define MG_TX_SWINGCTRL_TX1LN1_PORT1 0x168548 | |
| 1913 | +#define MG_TX_SWINGCTRL_TX1LN0_PORT2 0x169148 | |
| 1914 | +#define MG_TX_SWINGCTRL_TX1LN1_PORT2 0x169548 | |
| 1915 | +#define MG_TX_SWINGCTRL_TX1LN0_PORT3 0x16A148 | |
| 1916 | +#define MG_TX_SWINGCTRL_TX1LN1_PORT3 0x16A548 | |
| 1917 | +#define MG_TX_SWINGCTRL_TX1LN0_PORT4 0x16B148 | |
| 1918 | +#define MG_TX_SWINGCTRL_TX1LN1_PORT4 0x16B548 | |
| 1919 | +#define MG_TX1_SWINGCTRL(port, ln) \ | |
| 1920 | + MG_PHY_PORT_LN(port, ln, MG_TX_SWINGCTRL_TX1LN0_PORT1, \ | |
| 1921 | + MG_TX_SWINGCTRL_TX1LN0_PORT2, \ | |
| 1922 | + MG_TX_SWINGCTRL_TX1LN1_PORT1) | |
| 1923 | + | |
| 1924 | +#define MG_TX_SWINGCTRL_TX2LN0_PORT1 0x1680C8 | |
| 1925 | +#define MG_TX_SWINGCTRL_TX2LN1_PORT1 0x1684C8 | |
| 1926 | +#define MG_TX_SWINGCTRL_TX2LN0_PORT2 0x1690C8 | |
| 1927 | +#define MG_TX_SWINGCTRL_TX2LN1_PORT2 0x1694C8 | |
| 1928 | +#define MG_TX_SWINGCTRL_TX2LN0_PORT3 0x16A0C8 | |
| 1929 | +#define MG_TX_SWINGCTRL_TX2LN1_PORT3 0x16A4C8 | |
| 1930 | +#define MG_TX_SWINGCTRL_TX2LN0_PORT4 0x16B0C8 | |
| 1931 | +#define MG_TX_SWINGCTRL_TX2LN1_PORT4 0x16B4C8 | |
| 1932 | +#define MG_TX2_SWINGCTRL(port, ln) \ | |
| 1933 | + MG_PHY_PORT_LN(port, ln, MG_TX_SWINGCTRL_TX2LN0_PORT1, \ | |
| 1934 | + MG_TX_SWINGCTRL_TX2LN0_PORT2, \ | |
| 1935 | + MG_TX_SWINGCTRL_TX2LN1_PORT1) | |
| 1936 | +#define CRI_TXDEEMPH_OVERRIDE_17_12(x) ((x) << 0) | |
| 1937 | +#define CRI_TXDEEMPH_OVERRIDE_17_12_MASK (0x3F << 0) | |
| 1938 | + | |
| 1939 | +#define MG_TX_DRVCTRL_TX1LN0_TXPORT1 0x168144 | |
| 1940 | +#define MG_TX_DRVCTRL_TX1LN1_TXPORT1 0x168544 | |
| 1941 | +#define MG_TX_DRVCTRL_TX1LN0_TXPORT2 0x169144 | |
| 1942 | +#define MG_TX_DRVCTRL_TX1LN1_TXPORT2 0x169544 | |
| 1943 | +#define MG_TX_DRVCTRL_TX1LN0_TXPORT3 0x16A144 | |
| 1944 | +#define MG_TX_DRVCTRL_TX1LN1_TXPORT3 0x16A544 | |
| 1945 | +#define MG_TX_DRVCTRL_TX1LN0_TXPORT4 0x16B144 | |
| 1946 | +#define MG_TX_DRVCTRL_TX1LN1_TXPORT4 0x16B544 | |
| 1947 | +#define MG_TX1_DRVCTRL(port, ln) \ | |
| 1948 | + MG_PHY_PORT_LN(port, ln, MG_TX_DRVCTRL_TX1LN0_TXPORT1, \ | |
| 1949 | + MG_TX_DRVCTRL_TX1LN0_TXPORT2, \ | |
| 1950 | + MG_TX_DRVCTRL_TX1LN1_TXPORT1) | |
| 1951 | + | |
| 1952 | +#define MG_TX_DRVCTRL_TX2LN0_PORT1 0x1680C4 | |
| 1953 | +#define MG_TX_DRVCTRL_TX2LN1_PORT1 0x1684C4 | |
| 1954 | +#define MG_TX_DRVCTRL_TX2LN0_PORT2 0x1690C4 | |
| 1955 | +#define MG_TX_DRVCTRL_TX2LN1_PORT2 0x1694C4 | |
| 1956 | +#define MG_TX_DRVCTRL_TX2LN0_PORT3 0x16A0C4 | |
| 1957 | +#define MG_TX_DRVCTRL_TX2LN1_PORT3 0x16A4C4 | |
| 1958 | +#define MG_TX_DRVCTRL_TX2LN0_PORT4 0x16B0C4 | |
| 1959 | +#define MG_TX_DRVCTRL_TX2LN1_PORT4 0x16B4C4 | |
| 1960 | +#define MG_TX2_DRVCTRL(port, ln) \ | |
| 1961 | + MG_PHY_PORT_LN(port, ln, MG_TX_DRVCTRL_TX2LN0_PORT1, \ | |
| 1962 | + MG_TX_DRVCTRL_TX2LN0_PORT2, \ | |
| 1963 | + MG_TX_DRVCTRL_TX2LN1_PORT1) | |
| 1964 | +#define CRI_TXDEEMPH_OVERRIDE_11_6(x) ((x) << 24) | |
| 1965 | +#define CRI_TXDEEMPH_OVERRIDE_11_6_MASK (0x3F << 24) | |
| 1966 | +#define CRI_TXDEEMPH_OVERRIDE_EN (1 << 22) | |
| 1967 | +#define CRI_TXDEEMPH_OVERRIDE_5_0(x) ((x) << 16) | |
| 1968 | +#define CRI_TXDEEMPH_OVERRIDE_5_0_MASK (0x3F << 16) | |
| 1969 | +#define CRI_LOADGEN_SEL(x) ((x) << 12) | |
| 1970 | +#define CRI_LOADGEN_SEL_MASK (0x3 << 12) | |
| 1971 | + | |
| 1972 | +#define MG_CLKHUB_LN0_PORT1 0x16839C | |
| 1973 | +#define MG_CLKHUB_LN1_PORT1 0x16879C | |
| 1974 | +#define MG_CLKHUB_LN0_PORT2 0x16939C | |
| 1975 | +#define MG_CLKHUB_LN1_PORT2 0x16979C | |
| 1976 | +#define MG_CLKHUB_LN0_PORT3 0x16A39C | |
| 1977 | +#define MG_CLKHUB_LN1_PORT3 0x16A79C | |
| 1978 | +#define MG_CLKHUB_LN0_PORT4 0x16B39C | |
| 1979 | +#define MG_CLKHUB_LN1_PORT4 0x16B79C | |
| 1980 | +#define MG_CLKHUB(port, ln) \ | |
| 1981 | + MG_PHY_PORT_LN(port, ln, MG_CLKHUB_LN0_PORT1, \ | |
| 1982 | + MG_CLKHUB_LN0_PORT2, \ | |
| 1983 | + MG_CLKHUB_LN1_PORT1) | |
| 1984 | +#define CFG_LOW_RATE_LKREN_EN (1 << 11) | |
| 1985 | + | |
| 1986 | +#define MG_TX_DCC_TX1LN0_PORT1 0x168110 | |
| 1987 | +#define MG_TX_DCC_TX1LN1_PORT1 0x168510 | |
| 1988 | +#define MG_TX_DCC_TX1LN0_PORT2 0x169110 | |
| 1989 | +#define MG_TX_DCC_TX1LN1_PORT2 0x169510 | |
| 1990 | +#define MG_TX_DCC_TX1LN0_PORT3 0x16A110 | |
| 1991 | +#define MG_TX_DCC_TX1LN1_PORT3 0x16A510 | |
| 1992 | +#define MG_TX_DCC_TX1LN0_PORT4 0x16B110 | |
| 1993 | +#define MG_TX_DCC_TX1LN1_PORT4 0x16B510 | |
| 1994 | +#define MG_TX1_DCC(port, ln) \ | |
| 1995 | + MG_PHY_PORT_LN(port, ln, MG_TX_DCC_TX1LN0_PORT1, \ | |
| 1996 | + MG_TX_DCC_TX1LN0_PORT2, \ | |
| 1997 | + MG_TX_DCC_TX1LN1_PORT1) | |
| 1998 | +#define MG_TX_DCC_TX2LN0_PORT1 0x168090 | |
| 1999 | +#define MG_TX_DCC_TX2LN1_PORT1 0x168490 | |
| 2000 | +#define MG_TX_DCC_TX2LN0_PORT2 0x169090 | |
| 2001 | +#define MG_TX_DCC_TX2LN1_PORT2 0x169490 | |
| 2002 | +#define MG_TX_DCC_TX2LN0_PORT3 0x16A090 | |
| 2003 | +#define MG_TX_DCC_TX2LN1_PORT3 0x16A490 | |
| 2004 | +#define MG_TX_DCC_TX2LN0_PORT4 0x16B090 | |
| 2005 | +#define MG_TX_DCC_TX2LN1_PORT4 0x16B490 | |
| 2006 | +#define MG_TX2_DCC(port, ln) \ | |
| 2007 | + MG_PHY_PORT_LN(port, ln, MG_TX_DCC_TX2LN0_PORT1, \ | |
| 2008 | + MG_TX_DCC_TX2LN0_PORT2, \ | |
| 2009 | + MG_TX_DCC_TX2LN1_PORT1) | |
| 2010 | +#define CFG_AMI_CK_DIV_OVERRIDE_VAL(x) ((x) << 25) | |
| 2011 | +#define CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK (0x3 << 25) | |
| 2012 | +#define CFG_AMI_CK_DIV_OVERRIDE_EN (1 << 24) | |
| 2013 | + | |
| 2014 | +#define MG_DP_MODE_LN0_ACU_PORT1 0x1683A0 | |
| 2015 | +#define MG_DP_MODE_LN1_ACU_PORT1 0x1687A0 | |
| 2016 | +#define MG_DP_MODE_LN0_ACU_PORT2 0x1693A0 | |
| 2017 | +#define MG_DP_MODE_LN1_ACU_PORT2 0x1697A0 | |
| 2018 | +#define MG_DP_MODE_LN0_ACU_PORT3 0x16A3A0 | |
| 2019 | +#define MG_DP_MODE_LN1_ACU_PORT3 0x16A7A0 | |
| 2020 | +#define MG_DP_MODE_LN0_ACU_PORT4 0x16B3A0 | |
| 2021 | +#define MG_DP_MODE_LN1_ACU_PORT4 0x16B7A0 | |
| 2022 | +#define MG_DP_MODE(port, ln) \ | |
| 2023 | + MG_PHY_PORT_LN(port, ln, MG_DP_MODE_LN0_ACU_PORT1, \ | |
| 2024 | + MG_DP_MODE_LN0_ACU_PORT2, \ | |
| 2025 | + MG_DP_MODE_LN1_ACU_PORT1) | |
| 2026 | +#define MG_DP_MODE_CFG_DP_X2_MODE (1 << 7) | |
| 2027 | +#define MG_DP_MODE_CFG_DP_X1_MODE (1 << 6) | |
| 2028 | +#define MG_DP_MODE_CFG_TR2PWR_GATING (1 << 5) | |
| 2029 | +#define MG_DP_MODE_CFG_TRPWR_GATING (1 << 4) | |
| 2030 | +#define MG_DP_MODE_CFG_CLNPWR_GATING (1 << 3) | |
| 2031 | +#define MG_DP_MODE_CFG_DIGPWR_GATING (1 << 2) | |
| 2032 | +#define MG_DP_MODE_CFG_GAONPWR_GATING (1 << 1) | |
| 2033 | + | |
| 2034 | +#define MG_MISC_SUS0_PORT1 0x168814 | |
| 2035 | +#define MG_MISC_SUS0_PORT2 0x169814 | |
| 2036 | +#define MG_MISC_SUS0_PORT3 0x16A814 | |
| 2037 | +#define MG_MISC_SUS0_PORT4 0x16B814 | |
| 2038 | +#define MG_MISC_SUS0(tc_port) \ | |
| 2039 | + _MMIO(_PORT(tc_port, MG_MISC_SUS0_PORT1, MG_MISC_SUS0_PORT2)) | |
| 2040 | +#define MG_MISC_SUS0_SUSCLK_DYNCLKGATE_MODE_MASK (3 << 14) | |
| 2041 | +#define MG_MISC_SUS0_SUSCLK_DYNCLKGATE_MODE(x) ((x) << 14) | |
| 2042 | +#define MG_MISC_SUS0_CFG_TR2PWR_GATING (1 << 12) | |
| 2043 | +#define MG_MISC_SUS0_CFG_CL2PWR_GATING (1 << 11) | |
| 2044 | +#define MG_MISC_SUS0_CFG_GAONPWR_GATING (1 << 10) | |
| 2045 | +#define MG_MISC_SUS0_CFG_TRPWR_GATING (1 << 7) | |
| 2046 | +#define MG_MISC_SUS0_CFG_CL1PWR_GATING (1 << 6) | |
| 2047 | +#define MG_MISC_SUS0_CFG_DGPWR_GATING (1 << 5) | |
| 2050 | 2048 | |
| 2051 | 2049 | /* The spec defines this only for BXT PHY0, but lets assume that this |
| 2052 | 2050 | * would exist for PHY1 too if it had a second channel. |
| @@ -3086,18 +3084,9 @@ enum i915_power_well_id { · 1033 unmodified lines | ||
| 3086 | 3084 | /* |
| 3087 | 3085 | * GPIO regs |
| 3088 | 3086 | */ |
| 3089 | −#define GPIOA _MMIO(0x5010) | |
| 3090 | −#define GPIOB _MMIO(0x5014) | |
| 3091 | −#define GPIOC _MMIO(0x5018) | |
| 3092 | −#define GPIOD _MMIO(0x501c) | |
| 3093 | −#define GPIOE _MMIO(0x5020) | |
| 3094 | −#define GPIOF _MMIO(0x5024) | |
| 3095 | −#define GPIOG _MMIO(0x5028) | |
| 3096 | −#define GPIOH _MMIO(0x502c) | |
| 3097 | −#define GPIOJ _MMIO(0x5034) | |
| 3098 | −#define GPIOK _MMIO(0x5038) | |
| 3099 | −#define GPIOL _MMIO(0x503C) | |
| 3100 | −#define GPIOM _MMIO(0x5040) | |
| 3087 | +#define GPIO(gpio) _MMIO(dev_priv->gpio_mmio_base + 0x5010 + \ | |
| 3088 | + 4 * (gpio)) | |
| 3089 | + | |
| 3101 | 3090 | # define GPIO_CLOCK_DIR_MASK (1 << 0) |
| 3102 | 3091 | # define GPIO_CLOCK_DIR_IN (0 << 1) |
| 3103 | 3092 | # define GPIO_CLOCK_DIR_OUT (1 << 1) |
| @@ -5476,6 +5465,7 @@ enum { · 2372 unmodified lines | ||
| 5476 | 5465 | #define DP_AUX_CH_CTL_PSR_DATA_AUX_REG_SKL (1 << 14) |
| 5477 | 5466 | #define DP_AUX_CH_CTL_FS_DATA_AUX_REG_SKL (1 << 13) |
| 5478 | 5467 | #define DP_AUX_CH_CTL_GTC_DATA_AUX_REG_SKL (1 << 12) |
| 5468 | +#define DP_AUX_CH_CTL_TBT_IO (1 << 11) | |
| 5479 | 5469 | #define DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL_MASK (0x1f << 5) |
| 5480 | 5470 | #define DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(c) (((c) - 1) << 5) |
| 5481 | 5471 | #define DP_AUX_CH_CTL_SYNC_PULSE_SKL(c) ((c) - 1) |
| @@ -6527,7 +6517,7 @@ enum { · 1045 unmodified lines | ||
| 6527 | 6517 | #define PLANE_CTL_YUV422_UYVY (1 << 16) |
| 6528 | 6518 | #define PLANE_CTL_YUV422_YVYU (2 << 16) |
| 6529 | 6519 | #define PLANE_CTL_YUV422_VYUY (3 << 16) |
| 6530 | −#define PLANE_CTL_DECOMPRESSION_ENABLE (1 << 15) | |
| 6520 | +#define PLANE_CTL_RENDER_DECOMPRESSION_ENABLE (1 << 15) | |
| 6531 | 6521 | #define PLANE_CTL_TRICKLE_FEED_DISABLE (1 << 14) |
| 6532 | 6522 | #define PLANE_CTL_PLANE_GAMMA_DISABLE (1 << 13) /* Pre-GLK */ |
| 6533 | 6523 | #define PLANE_CTL_TILED_MASK (0x7 << 10) |
| @@ -7207,6 +7197,7 @@ enum { · 673 unmodified lines | ||
| 7207 | 7197 | #define GEN11_TC3_HOTPLUG (1 << 18) |
| 7208 | 7198 | #define GEN11_TC2_HOTPLUG (1 << 17) |
| 7209 | 7199 | #define GEN11_TC1_HOTPLUG (1 << 16) |
| 7200 | +#define GEN11_TC_HOTPLUG(tc_port) (1 << ((tc_port) + 16)) | |
| 7210 | 7201 | #define GEN11_DE_TC_HOTPLUG_MASK (GEN11_TC4_HOTPLUG | \ |
| 7211 | 7202 | GEN11_TC3_HOTPLUG | \ |
| 7212 | 7203 | GEN11_TC2_HOTPLUG | \ |
| @@ -7215,6 +7206,7 @@ enum { · 2 unmodified lines | ||
| 7215 | 7206 | #define GEN11_TBT3_HOTPLUG (1 << 2) |
| 7216 | 7207 | #define GEN11_TBT2_HOTPLUG (1 << 1) |
| 7217 | 7208 | #define GEN11_TBT1_HOTPLUG (1 << 0) |
| 7209 | +#define GEN11_TBT_HOTPLUG(tc_port) (1 << (tc_port)) | |
| 7218 | 7210 | #define GEN11_DE_TBT_HOTPLUG_MASK (GEN11_TBT4_HOTPLUG | \ |
| 7219 | 7211 | GEN11_TBT3_HOTPLUG | \ |
| 7220 | 7212 | GEN11_TBT2_HOTPLUG | \ |
| @@ -7490,6 +7482,8 @@ enum { · 269 unmodified lines | ||
| 7490 | 7482 | |
| 7491 | 7483 | /* PCH */ |
| 7492 | 7484 | |
| 7485 | +#define PCH_DISPLAY_BASE 0xc0000u | |
| 7486 | + | |
| 7493 | 7487 | /* south display engine interrupt: IBX */ |
| 7494 | 7488 | #define SDE_AUDIO_POWER_D (1 << 27) |
| 7495 | 7489 | #define SDE_AUDIO_POWER_C (1 << 26) |
| @@ -7587,6 +7581,8 @@ enum { · 91 unmodified lines | ||
| 7587 | 7581 | #define SDE_GMBUS_ICP (1 << 23) |
| 7588 | 7582 | #define SDE_DDIB_HOTPLUG_ICP (1 << 17) |
| 7589 | 7583 | #define SDE_DDIA_HOTPLUG_ICP (1 << 16) |
| 7584 | +#define SDE_TC_HOTPLUG_ICP(tc_port) (1 << ((tc_port) + 24)) | |
| 7585 | +#define SDE_DDI_HOTPLUG_ICP(port) (1 << ((port) + 16)) | |
| 7590 | 7586 | #define SDE_DDI_MASK_ICP (SDE_DDIB_HOTPLUG_ICP | \ |
| 7591 | 7587 | SDE_DDIA_HOTPLUG_ICP) |
| 7592 | 7588 | #define SDE_TC_MASK_ICP (SDE_TC4_HOTPLUG_ICP | \ |
| @@ -7782,20 +7778,6 @@ enum { · 189 unmodified lines | ||
| 7782 | 7778 | #define ICP_TC_HPD_LONG_DETECT(tc_port) (2 << (tc_port) * 4) |
| 7783 | 7779 | #define ICP_TC_HPD_SHORT_DETECT(tc_port) (1 << (tc_port) * 4) |
| 7784 | 7780 | |
| 7785 | −#define PCH_GPIOA _MMIO(0xc5010) | |
| 7786 | −#define PCH_GPIOB _MMIO(0xc5014) | |
| 7787 | −#define PCH_GPIOC _MMIO(0xc5018) | |
| 7788 | −#define PCH_GPIOD _MMIO(0xc501c) | |
| 7789 | −#define PCH_GPIOE _MMIO(0xc5020) | |
| 7790 | −#define PCH_GPIOF _MMIO(0xc5024) | |
| 7791 | − | |
| 7792 | −#define PCH_GMBUS0 _MMIO(0xc5100) | |
| 7793 | −#define PCH_GMBUS1 _MMIO(0xc5104) | |
| 7794 | −#define PCH_GMBUS2 _MMIO(0xc5108) | |
| 7795 | −#define PCH_GMBUS3 _MMIO(0xc510c) | |
| 7796 | −#define PCH_GMBUS4 _MMIO(0xc5110) | |
| 7797 | −#define PCH_GMBUS5 _MMIO(0xc5120) | |
| 7798 | − | |
| 7799 | 7781 | #define _PCH_DPLL_A 0xc6014 |
| 7800 | 7782 | #define _PCH_DPLL_B 0xc6018 |
| 7801 | 7783 | #define PCH_DPLL(pll) _MMIO((pll) == 0 ? _PCH_DPLL_A : _PCH_DPLL_B) |
| @@ -8498,8 +8480,10 @@ enum { · 696 unmodified lines | ||
| 8498 | 8480 | #define GEN6_PM_RP_DOWN_THRESHOLD (1 << 4) |
| 8499 | 8481 | #define GEN6_PM_RP_UP_EI_EXPIRED (1 << 2) |
| 8500 | 8482 | #define GEN6_PM_RP_DOWN_EI_EXPIRED (1 << 1) |
| 8501 | −#define GEN6_PM_RPS_EVENTS (GEN6_PM_RP_UP_THRESHOLD | \ | |
| 8502 | − GEN6_PM_RP_DOWN_THRESHOLD | \ | |
| 8483 | +#define GEN6_PM_RPS_EVENTS (GEN6_PM_RP_UP_EI_EXPIRED | \ | |
| 8484 | + GEN6_PM_RP_UP_THRESHOLD | \ | |
| 8485 | + GEN6_PM_RP_DOWN_EI_EXPIRED | \ | |
| 8486 | + GEN6_PM_RP_DOWN_THRESHOLD | \ | |
| 8503 | 8487 | GEN6_PM_RP_DOWN_TIMEOUT) |
| 8504 | 8488 | |
| 8505 | 8489 | #define GEN7_GT_SCRATCH(i) _MMIO(0x4F100 + (i) * 4) |
| @@ -8827,46 +8811,78 @@ enum { · 321 unmodified lines | ||
| 8827 | 8811 | #define HSW_AUD_CHICKENBIT _MMIO(0x65f10) |
| 8828 | 8812 | #define SKL_AUD_CODEC_WAKE_SIGNAL (1 << 15) |
| 8829 | 8813 | |
| 8830 | −/* HSW Power Wells */ | |
| 8831 | −#define _HSW_PWR_WELL_CTL1 0x45400 | |
| 8832 | −#define _HSW_PWR_WELL_CTL2 0x45404 | |
| 8833 | −#define _HSW_PWR_WELL_CTL3 0x45408 | |
| 8834 | −#define _HSW_PWR_WELL_CTL4 0x4540C | |
| 8835 | − | |
| 8836 | −#define _ICL_PWR_WELL_CTL_AUX1 0x45440 | |
| 8837 | −#define _ICL_PWR_WELL_CTL_AUX2 0x45444 | |
| 8838 | −#define _ICL_PWR_WELL_CTL_AUX4 0x4544C | |
| 8839 | − | |
| 8840 | −#define _ICL_PWR_WELL_CTL_DDI1 0x45450 | |
| 8841 | −#define _ICL_PWR_WELL_CTL_DDI2 0x45454 | |
| 8842 | −#define _ICL_PWR_WELL_CTL_DDI4 0x4545C | |
| 8843 | − | |
| 8844 | 8814 | /* |
| 8845 | − * Each power well control register contains up to 16 (request, status) HW | |
| 8846 | − * flag tuples. The register index and HW flag shift is determined by the | |
| 8847 | − * power well ID (see i915_power_well_id). There are 4 possible sources of | |
| 8848 | − * power well requests each source having its own set of control registers: | |
| 8849 | − * BIOS, DRIVER, KVMR, DEBUG. | |
| 8815 | + * HSW - ICL power wells | |
| 8816 | + * | |
| 8817 | + * Platforms have up to 3 power well control register sets, each set | |
| 8818 | + * controlling up to 16 power wells via a request/status HW flag tuple: | |
| 8819 | + * - main (HSW_PWR_WELL_CTL[1-4]) | |
| 8820 | + * - AUX (ICL_PWR_WELL_CTL_AUX[1-4]) | |
| 8821 | + * - DDI (ICL_PWR_WELL_CTL_DDI[1-4]) | |
| 8822 | + * Each control register set consists of up to 4 registers used by different | |
| 8823 | + * sources that can request a power well to be enabled: | |
| 8824 | + * - BIOS (HSW_PWR_WELL_CTL1/ICL_PWR_WELL_CTL_AUX1/ICL_PWR_WELL_CTL_DDI1) | |
| 8825 | + * - DRIVER (HSW_PWR_WELL_CTL2/ICL_PWR_WELL_CTL_AUX2/ICL_PWR_WELL_CTL_DDI2) | |
| 8826 | + * - KVMR (HSW_PWR_WELL_CTL3) (only in the main register set) | |
| 8827 | + * - DEBUG (HSW_PWR_WELL_CTL4/ICL_PWR_WELL_CTL_AUX4/ICL_PWR_WELL_CTL_DDI4) | |
| 8850 | 8828 | */ |
| 8851 | −#define _HSW_PW_REG_IDX(pw) ((pw) >> 4) | |
| 8852 | −#define _HSW_PW_SHIFT(pw) (((pw) & 0xf) * 2) | |
| 8853 | −#define HSW_PWR_WELL_CTL_BIOS(pw) _MMIO(_PICK(_HSW_PW_REG_IDX(pw), \ | |
| 8854 | − _HSW_PWR_WELL_CTL1, \ | |
| 8855 | − _ICL_PWR_WELL_CTL_AUX1, \ | |
| 8856 | − _ICL_PWR_WELL_CTL_DDI1)) | |
| 8857 | −#define HSW_PWR_WELL_CTL_DRIVER(pw) _MMIO(_PICK(_HSW_PW_REG_IDX(pw), \ | |
| 8858 | − _HSW_PWR_WELL_CTL2, \ | |
| 8859 | − _ICL_PWR_WELL_CTL_AUX2, \ | |
| 8860 | − _ICL_PWR_WELL_CTL_DDI2)) | |
| 8861 | −/* KVMR doesn't have a reg for AUX or DDI power well control */ | |
| 8862 | −#define HSW_PWR_WELL_CTL_KVMR _MMIO(_HSW_PWR_WELL_CTL3) | |
| 8863 | −#define HSW_PWR_WELL_CTL_DEBUG(pw) _MMIO(_PICK(_HSW_PW_REG_IDX(pw), \ | |
| 8864 | − _HSW_PWR_WELL_CTL4, \ | |
| 8865 | − _ICL_PWR_WELL_CTL_AUX4, \ | |
| 8866 | − _ICL_PWR_WELL_CTL_DDI4)) | |
| 8867 | − | |
| 8868 | −#define HSW_PWR_WELL_CTL_REQ(pw) (1 << (_HSW_PW_SHIFT(pw) + 1)) | |
| 8869 | −#define HSW_PWR_WELL_CTL_STATE(pw) (1 << _HSW_PW_SHIFT(pw)) | |
| 8829 | +#define HSW_PWR_WELL_CTL1 _MMIO(0x45400) | |
| 8830 | +#define HSW_PWR_WELL_CTL2 _MMIO(0x45404) | |
| 8831 | +#define HSW_PWR_WELL_CTL3 _MMIO(0x45408) | |
| 8832 | +#define HSW_PWR_WELL_CTL4 _MMIO(0x4540C) | |
| 8833 | +#define HSW_PWR_WELL_CTL_REQ(pw_idx) (0x2 << ((pw_idx) * 2)) | |
| 8834 | +#define HSW_PWR_WELL_CTL_STATE(pw_idx) (0x1 << ((pw_idx) * 2)) | |
| 8835 | + | |
| 8836 | +/* HSW/BDW power well */ | |
| 8837 | +#define HSW_PW_CTL_IDX_GLOBAL 15 | |
| 8838 | + | |
| 8839 | +/* SKL/BXT/GLK/CNL power wells */ | |
| 8840 | +#define SKL_PW_CTL_IDX_PW_2 15 | |
| 8841 | +#define SKL_PW_CTL_IDX_PW_1 14 | |
| 8842 | +#define CNL_PW_CTL_IDX_AUX_F 12 | |
| 8843 | +#define CNL_PW_CTL_IDX_AUX_D 11 | |
| 8844 | +#define GLK_PW_CTL_IDX_AUX_C 10 | |
| 8845 | +#define GLK_PW_CTL_IDX_AUX_B 9 | |
| 8846 | +#define GLK_PW_CTL_IDX_AUX_A 8 | |
| 8847 | +#define CNL_PW_CTL_IDX_DDI_F 6 | |
| 8848 | +#define SKL_PW_CTL_IDX_DDI_D 4 | |
| 8849 | +#define SKL_PW_CTL_IDX_DDI_C 3 | |
| 8850 | +#define SKL_PW_CTL_IDX_DDI_B 2 | |
| 8851 | +#define SKL_PW_CTL_IDX_DDI_A_E 1 | |
| 8852 | +#define GLK_PW_CTL_IDX_DDI_A 1 | |
| 8853 | +#define SKL_PW_CTL_IDX_MISC_IO 0 | |
| 8854 | + | |
| 8855 | +/* ICL - power wells */ | |
| 8856 | +#define ICL_PW_CTL_IDX_PW_4 3 | |
| 8857 | +#define ICL_PW_CTL_IDX_PW_3 2 | |
| 8858 | +#define ICL_PW_CTL_IDX_PW_2 1 | |
| 8859 | +#define ICL_PW_CTL_IDX_PW_1 0 | |
| 8860 | + | |
| 8861 | +#define ICL_PWR_WELL_CTL_AUX1 _MMIO(0x45440) | |
| 8862 | +#define ICL_PWR_WELL_CTL_AUX2 _MMIO(0x45444) | |
| 8863 | +#define ICL_PWR_WELL_CTL_AUX4 _MMIO(0x4544C) | |
| 8864 | +#define ICL_PW_CTL_IDX_AUX_TBT4 11 | |
| 8865 | +#define ICL_PW_CTL_IDX_AUX_TBT3 10 | |
| 8866 | +#define ICL_PW_CTL_IDX_AUX_TBT2 9 | |
| 8867 | +#define ICL_PW_CTL_IDX_AUX_TBT1 8 | |
| 8868 | +#define ICL_PW_CTL_IDX_AUX_F 5 | |
| 8869 | +#define ICL_PW_CTL_IDX_AUX_E 4 | |
| 8870 | +#define ICL_PW_CTL_IDX_AUX_D 3 | |
| 8871 | +#define ICL_PW_CTL_IDX_AUX_C 2 | |
| 8872 | +#define ICL_PW_CTL_IDX_AUX_B 1 | |
| 8873 | +#define ICL_PW_CTL_IDX_AUX_A 0 | |
| 8874 | + | |
| 8875 | +#define ICL_PWR_WELL_CTL_DDI1 _MMIO(0x45450) | |
| 8876 | +#define ICL_PWR_WELL_CTL_DDI2 _MMIO(0x45454) | |
| 8877 | +#define ICL_PWR_WELL_CTL_DDI4 _MMIO(0x4545C) | |
| 8878 | +#define ICL_PW_CTL_IDX_DDI_F 5 | |
| 8879 | +#define ICL_PW_CTL_IDX_DDI_E 4 | |
| 8880 | +#define ICL_PW_CTL_IDX_DDI_D 3 | |
| 8881 | +#define ICL_PW_CTL_IDX_DDI_C 2 | |
| 8882 | +#define ICL_PW_CTL_IDX_DDI_B 1 | |
| 8883 | +#define ICL_PW_CTL_IDX_DDI_A 0 | |
| 8884 | + | |
| 8885 | +/* HSW - power well misc debug registers */ | |
| 8870 | 8886 | #define HSW_PWR_WELL_CTL5 _MMIO(0x45410) |
| 8871 | 8887 | #define HSW_PWR_WELL_ENABLE_SINGLE_STEP (1 << 31) |
| 8872 | 8888 | #define HSW_PWR_WELL_PWR_GATE_OVERRIDE (1 << 20) |
| @@ -8878,22 +8894,32 @@ enum skl_power_gate { · 5 unmodified lines | ||
| 8878 | 8894 | SKL_PG0, |
| 8879 | 8895 | SKL_PG1, |
| 8880 | 8896 | SKL_PG2, |
| 8897 | + ICL_PG3, | |
| 8898 | + ICL_PG4, | |
| 8881 | 8899 | }; |
| 8882 | 8900 | |
| 8883 | 8901 | #define SKL_FUSE_STATUS _MMIO(0x42000) |
| 8884 | 8902 | #define SKL_FUSE_DOWNLOAD_STATUS (1 << 31) |
| 8885 | −/* PG0 (HW control->no power well ID), PG1..PG2 (SKL_DISP_PW1..SKL_DISP_PW2) */ | |
| 8886 | −#define SKL_PW_TO_PG(pw) ((pw) - SKL_DISP_PW_1 + SKL_PG1) | |
| 8887 | −/* PG0 (HW control->no power well ID), PG1..PG4 (ICL_DISP_PW1..ICL_DISP_PW4) */ | |
| 8888 | −#define ICL_PW_TO_PG(pw) ((pw) - ICL_DISP_PW_1 + SKL_PG1) | |
| 8903 | +/* | |
| 8904 | + * PG0 is HW controlled, so doesn't have a corresponding power well control knob | |
| 8905 | + * SKL_DISP_PW1_IDX..SKL_DISP_PW2_IDX -> PG1..PG2 | |
| 8906 | + */ | |
| 8907 | +#define SKL_PW_CTL_IDX_TO_PG(pw_idx) \ | |
| 8908 | + ((pw_idx) - SKL_PW_CTL_IDX_PW_1 + SKL_PG1) | |
| 8909 | +/* | |
| 8910 | + * PG0 is HW controlled, so doesn't have a corresponding power well control knob | |
| 8911 | + * ICL_DISP_PW1_IDX..ICL_DISP_PW4_IDX -> PG1..PG4 | |
| 8912 | + */ | |
| 8913 | +#define ICL_PW_CTL_IDX_TO_PG(pw_idx) \ | |
| 8914 | + ((pw_idx) - ICL_PW_CTL_IDX_PW_1 + SKL_PG1) | |
| 8889 | 8915 | #define SKL_FUSE_PG_DIST_STATUS(pg) (1 << (27 - (pg))) |
| 8890 | 8916 | |
| 8891 | −#define _CNL_AUX_REG_IDX(pw) ((pw) - 9) | |
| 8917 | +#define _CNL_AUX_REG_IDX(pw_idx) ((pw_idx) - GLK_PW_CTL_IDX_AUX_B) | |
| 8892 | 8918 | #define _CNL_AUX_ANAOVRD1_B 0x162250 |
| 8893 | 8919 | #define _CNL_AUX_ANAOVRD1_C 0x162210 |
| 8894 | 8920 | #define _CNL_AUX_ANAOVRD1_D 0x1622D0 |
| 8895 | 8921 | #define _CNL_AUX_ANAOVRD1_F 0x162A90 |
| 8896 | −#define CNL_AUX_ANAOVRD1(pw) _MMIO(_PICK(_CNL_AUX_REG_IDX(pw), \ | |
| 8922 | +#define CNL_AUX_ANAOVRD1(pw_idx) _MMIO(_PICK(_CNL_AUX_REG_IDX(pw_idx), \ | |
| 8897 | 8923 | _CNL_AUX_ANAOVRD1_B, \ |
| 8898 | 8924 | _CNL_AUX_ANAOVRD1_C, \ |
| 8899 | 8925 | _CNL_AUX_ANAOVRD1_D, \ |
| @@ -9367,9 +9393,13 @@ enum skl_power_gate { · 467 unmodified lines | ||
| 9367 | 9393 | #define MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK (0x1 << 16) |
| 9368 | 9394 | #define MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(x) ((x) << 14) |
| 9369 | 9395 | #define MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK (0x3 << 14) |
| 9370 | −#define MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO(x) ((x) << 12) | |
| 9371 | 9396 | #define MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK (0x3 << 12) |
| 9397 | +#define MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_2 (0 << 12) | |
| 9398 | +#define MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_3 (1 << 12) | |
| 9399 | +#define MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_5 (2 << 12) | |
| 9400 | +#define MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_7 (3 << 12) | |
| 9372 | 9401 | #define MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO(x) ((x) << 8) |
| 9402 | +#define MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_SHIFT 8 | |
| 9373 | 9403 | #define MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK (0xf << 8) |
| 9374 | 9404 | #define MG_CLKTOP2_HSCLKCTL(port) _MMIO_PORT((port) - PORT_C, \ |
| 9375 | 9405 | _MG_CLKTOP2_HSCLKCTL_PORT1, \ |
| @@ -9380,7 +9410,10 @@ enum skl_power_gate { · 4 unmodified lines | ||
| 9380 | 9410 | #define _MG_PLL_DIV0_PORT3 0x16AA00 |
| 9381 | 9411 | #define _MG_PLL_DIV0_PORT4 0x16BA00 |
| 9382 | 9412 | #define MG_PLL_DIV0_FRACNEN_H (1 << 30) |
| 9413 | +#define MG_PLL_DIV0_FBDIV_FRAC_MASK (0x3fffff << 8) | |
| 9414 | +#define MG_PLL_DIV0_FBDIV_FRAC_SHIFT 8 | |
| 9383 | 9415 | #define MG_PLL_DIV0_FBDIV_FRAC(x) ((x) << 8) |
| 9416 | +#define MG_PLL_DIV0_FBDIV_INT_MASK (0xff << 0) | |
| 9384 | 9417 | #define MG_PLL_DIV0_FBDIV_INT(x) ((x) << 0) |
| 9385 | 9418 | #define MG_PLL_DIV0(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_DIV0_PORT1, \ |
| 9386 | 9419 | _MG_PLL_DIV0_PORT2) |
| @@ -9395,6 +9428,7 @@ enum skl_power_gate { · 8 unmodified lines | ||
| 9395 | 9428 | #define MG_PLL_DIV1_DITHER_DIV_4 (2 << 12) |
| 9396 | 9429 | #define MG_PLL_DIV1_DITHER_DIV_8 (3 << 12) |
| 9397 | 9430 | #define MG_PLL_DIV1_NDIVRATIO(x) ((x) << 4) |
| 9431 | +#define MG_PLL_DIV1_FBPREDIV_MASK (0xf << 0) | |
| 9398 | 9432 | #define MG_PLL_DIV1_FBPREDIV(x) ((x) << 0) |
| 9399 | 9433 | #define MG_PLL_DIV1(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_DIV1_PORT1, \ |
| 9400 | 9434 | _MG_PLL_DIV1_PORT2) |
| @@ -10347,8 +10381,8 @@ enum skl_power_gate { · 946 unmodified lines | ||
| 10347 | 10381 | #define ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN (1 << 23) |
| 10348 | 10382 | |
| 10349 | 10383 | /* Icelake Display Stream Compression Registers */ |
| 10350 | −#define DSCA_PICTURE_PARAMETER_SET_0 0x6B200 | |
| 10351 | −#define DSCC_PICTURE_PARAMETER_SET_0 0x6BA00 | |
| 10384 | +#define DSCA_PICTURE_PARAMETER_SET_0 _MMIO(0x6B200) | |
| 10385 | +#define DSCC_PICTURE_PARAMETER_SET_0 _MMIO(0x6BA00) | |
| 10352 | 10386 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_0_PB 0x78270 |
| 10353 | 10387 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_0_PB 0x78370 |
| 10354 | 10388 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_0_PC 0x78470 |
| @@ -10368,8 +10402,8 @@ enum skl_power_gate { · 13 unmodified lines | ||
| 10368 | 10402 | #define DSC_VER_MIN_SHIFT 4 |
| 10369 | 10403 | #define DSC_VER_MAJ (0x1 << 0) |
| 10370 | 10404 | |
| 10371 | −#define DSCA_PICTURE_PARAMETER_SET_1 0x6B204 | |
| 10372 | −#define DSCC_PICTURE_PARAMETER_SET_1 0x6BA04 | |
| 10405 | +#define DSCA_PICTURE_PARAMETER_SET_1 _MMIO(0x6B204) | |
| 10406 | +#define DSCC_PICTURE_PARAMETER_SET_1 _MMIO(0x6BA04) | |
| 10373 | 10407 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_1_PB 0x78274 |
| 10374 | 10408 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_1_PB 0x78374 |
| 10375 | 10409 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_1_PC 0x78474 |
| @@ -10382,8 +10416,8 @@ enum skl_power_gate { · 6 unmodified lines | ||
| 10382 | 10416 | _ICL_DSC1_PICTURE_PARAMETER_SET_1_PC) |
| 10383 | 10417 | #define DSC_BPP(bpp) ((bpp) << 0) |
| 10384 | 10418 | |
| 10385 | −#define DSCA_PICTURE_PARAMETER_SET_2 0x6B208 | |
| 10386 | −#define DSCC_PICTURE_PARAMETER_SET_2 0x6BA08 | |
| 10419 | +#define DSCA_PICTURE_PARAMETER_SET_2 _MMIO(0x6B208) | |
| 10420 | +#define DSCC_PICTURE_PARAMETER_SET_2 _MMIO(0x6BA08) | |
| 10387 | 10421 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_2_PB 0x78278 |
| 10388 | 10422 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_2_PB 0x78378 |
| 10389 | 10423 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_2_PC 0x78478 |
| @@ -10397,8 +10431,8 @@ enum skl_power_gate { · 7 unmodified lines | ||
| 10397 | 10431 | #define DSC_PIC_WIDTH(pic_width) ((pic_width) << 16) |
| 10398 | 10432 | #define DSC_PIC_HEIGHT(pic_height) ((pic_height) << 0) |
| 10399 | 10433 | |
| 10400 | −#define DSCA_PICTURE_PARAMETER_SET_3 0x6B20C | |
| 10401 | −#define DSCC_PICTURE_PARAMETER_SET_3 0x6BA0C | |
| 10434 | +#define DSCA_PICTURE_PARAMETER_SET_3 _MMIO(0x6B20C) | |
| 10435 | +#define DSCC_PICTURE_PARAMETER_SET_3 _MMIO(0x6BA0C) | |
| 10402 | 10436 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_3_PB 0x7827C |
| 10403 | 10437 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_3_PB 0x7837C |
| 10404 | 10438 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_3_PC 0x7847C |
| @@ -10412,8 +10446,8 @@ enum skl_power_gate { · 7 unmodified lines | ||
| 10412 | 10446 | #define DSC_SLICE_WIDTH(slice_width) ((slice_width) << 16) |
| 10413 | 10447 | #define DSC_SLICE_HEIGHT(slice_height) ((slice_height) << 0) |
| 10414 | 10448 | |
| 10415 | −#define DSCA_PICTURE_PARAMETER_SET_4 0x6B210 | |
| 10416 | −#define DSCC_PICTURE_PARAMETER_SET_4 0x6BA10 | |
| 10449 | +#define DSCA_PICTURE_PARAMETER_SET_4 _MMIO(0x6B210) | |
| 10450 | +#define DSCC_PICTURE_PARAMETER_SET_4 _MMIO(0x6BA10) | |
| 10417 | 10451 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_4_PB 0x78280 |
| 10418 | 10452 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_4_PB 0x78380 |
| 10419 | 10453 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_4_PC 0x78480 |
| @@ -10422,13 +10456,13 @@ enum skl_power_gate { · 2 unmodified lines | ||
| 10422 | 10456 | _ICL_DSC0_PICTURE_PARAMETER_SET_4_PB, \ |
| 10423 | 10457 | _ICL_DSC0_PICTURE_PARAMETER_SET_4_PC) |
| 10424 | 10458 | #define ICL_DSC1_PICTURE_PARAMETER_SET_4(pipe) _MMIO_PIPE((pipe) - PIPE_B, \ |
| 10425 | − _ICL_DSC0_PICTURE_PARAMETER_SET_4_PB, \ | |
| 10459 | + _ICL_DSC1_PICTURE_PARAMETER_SET_4_PB, \ | |
| 10426 | 10460 | _ICL_DSC1_PICTURE_PARAMETER_SET_4_PC) |
| 10427 | 10461 | #define DSC_INITIAL_DEC_DELAY(dec_delay) ((dec_delay) << 16) |
| 10428 | 10462 | #define DSC_INITIAL_XMIT_DELAY(xmit_delay) ((xmit_delay) << 0) |
| 10429 | 10463 | |
| 10430 | −#define DSCA_PICTURE_PARAMETER_SET_5 0x6B214 | |
| 10431 | −#define DSCC_PICTURE_PARAMETER_SET_5 0x6BA14 | |
| 10464 | +#define DSCA_PICTURE_PARAMETER_SET_5 _MMIO(0x6B214) | |
| 10465 | +#define DSCC_PICTURE_PARAMETER_SET_5 _MMIO(0x6BA14) | |
| 10432 | 10466 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_5_PB 0x78284 |
| 10433 | 10467 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_5_PB 0x78384 |
| 10434 | 10468 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_5_PC 0x78484 |
| @@ -10437,13 +10471,13 @@ enum skl_power_gate { · 2 unmodified lines | ||
| 10437 | 10471 | _ICL_DSC0_PICTURE_PARAMETER_SET_5_PB, \ |
| 10438 | 10472 | _ICL_DSC0_PICTURE_PARAMETER_SET_5_PC) |
| 10439 | 10473 | #define ICL_DSC1_PICTURE_PARAMETER_SET_5(pipe) _MMIO_PIPE((pipe) - PIPE_B, \ |
| 10440 | − _ICL_DSC1_PICTURE_PARAMETER_SET_5_PC, \ | |
| 10474 | + _ICL_DSC1_PICTURE_PARAMETER_SET_5_PB, \ | |
| 10441 | 10475 | _ICL_DSC1_PICTURE_PARAMETER_SET_5_PC) |
| 10442 | −#define DSC_SCALE_DEC_INTINT(scale_dec) ((scale_dec) << 16) | |
| 10476 | +#define DSC_SCALE_DEC_INT(scale_dec) ((scale_dec) << 16) | |
| 10443 | 10477 | #define DSC_SCALE_INC_INT(scale_inc) ((scale_inc) << 0) |
| 10444 | 10478 | |
| 10445 | −#define DSCA_PICTURE_PARAMETER_SET_6 0x6B218 | |
| 10446 | −#define DSCC_PICTURE_PARAMETER_SET_6 0x6BA18 | |
| 10479 | +#define DSCA_PICTURE_PARAMETER_SET_6 _MMIO(0x6B218) | |
| 10480 | +#define DSCC_PICTURE_PARAMETER_SET_6 _MMIO(0x6BA18) | |
| 10447 | 10481 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_6_PB 0x78288 |
| 10448 | 10482 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_6_PB 0x78388 |
| 10449 | 10483 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_6_PC 0x78488 |
| @@ -10454,13 +10488,13 @@ enum skl_power_gate { · 4 unmodified lines | ||
| 10454 | 10488 | #define ICL_DSC1_PICTURE_PARAMETER_SET_6(pipe) _MMIO_PIPE((pipe) - PIPE_B, \ |
| 10455 | 10489 | _ICL_DSC1_PICTURE_PARAMETER_SET_6_PB, \ |
| 10456 | 10490 | _ICL_DSC1_PICTURE_PARAMETER_SET_6_PC) |
| 10457 | −#define DSC_FLATNESS_MAX_QP(max_qp) (qp << 24) | |
| 10458 | −#define DSC_FLATNESS_MIN_QP(min_qp) (qp << 16) | |
| 10491 | +#define DSC_FLATNESS_MAX_QP(max_qp) ((max_qp) << 24) | |
| 10492 | +#define DSC_FLATNESS_MIN_QP(min_qp) ((min_qp) << 16) | |
| 10459 | 10493 | #define DSC_FIRST_LINE_BPG_OFFSET(offset) ((offset) << 8) |
| 10460 | 10494 | #define DSC_INITIAL_SCALE_VALUE(value) ((value) << 0) |
| 10461 | 10495 | |
| 10462 | −#define DSCA_PICTURE_PARAMETER_SET_7 0x6B21C | |
| 10463 | −#define DSCC_PICTURE_PARAMETER_SET_7 0x6BA1C | |
| 10496 | +#define DSCA_PICTURE_PARAMETER_SET_7 _MMIO(0x6B21C) | |
| 10497 | +#define DSCC_PICTURE_PARAMETER_SET_7 _MMIO(0x6BA1C) | |
| 10464 | 10498 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_7_PB 0x7828C |
| 10465 | 10499 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_7_PB 0x7838C |
| 10466 | 10500 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_7_PC 0x7848C |
| @@ -10474,8 +10508,8 @@ enum skl_power_gate { · 7 unmodified lines | ||
| 10474 | 10508 | #define DSC_NFL_BPG_OFFSET(bpg_offset) ((bpg_offset) << 16) |
| 10475 | 10509 | #define DSC_SLICE_BPG_OFFSET(bpg_offset) ((bpg_offset) << 0) |
| 10476 | 10510 | |
| 10477 | −#define DSCA_PICTURE_PARAMETER_SET_8 0x6B220 | |
| 10478 | −#define DSCC_PICTURE_PARAMETER_SET_8 0x6BA20 | |
| 10511 | +#define DSCA_PICTURE_PARAMETER_SET_8 _MMIO(0x6B220) | |
| 10512 | +#define DSCC_PICTURE_PARAMETER_SET_8 _MMIO(0x6BA20) | |
| 10479 | 10513 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_8_PB 0x78290 |
| 10480 | 10514 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_8_PB 0x78390 |
| 10481 | 10515 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_8_PC 0x78490 |
| @@ -10489,8 +10523,8 @@ enum skl_power_gate { · 7 unmodified lines | ||
| 10489 | 10523 | #define DSC_INITIAL_OFFSET(initial_offset) ((initial_offset) << 16) |
| 10490 | 10524 | #define DSC_FINAL_OFFSET(final_offset) ((final_offset) << 0) |
| 10491 | 10525 | |
| 10492 | −#define DSCA_PICTURE_PARAMETER_SET_9 0x6B224 | |
| 10493 | −#define DSCC_PICTURE_PARAMETER_SET_9 0x6BA24 | |
| 10526 | +#define DSCA_PICTURE_PARAMETER_SET_9 _MMIO(0x6B224) | |
| 10527 | +#define DSCC_PICTURE_PARAMETER_SET_9 _MMIO(0x6BA24) | |
| 10494 | 10528 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_9_PB 0x78294 |
| 10495 | 10529 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_9_PB 0x78394 |
| 10496 | 10530 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_9_PC 0x78494 |
| @@ -10504,8 +10538,8 @@ enum skl_power_gate { · 7 unmodified lines | ||
| 10504 | 10538 | #define DSC_RC_EDGE_FACTOR(rc_edge_fact) ((rc_edge_fact) << 16) |
| 10505 | 10539 | #define DSC_RC_MODEL_SIZE(rc_model_size) ((rc_model_size) << 0) |
| 10506 | 10540 | |
| 10507 | −#define DSCA_PICTURE_PARAMETER_SET_10 0x6B228 | |
| 10508 | −#define DSCC_PICTURE_PARAMETER_SET_10 0x6BA28 | |
| 10541 | +#define DSCA_PICTURE_PARAMETER_SET_10 _MMIO(0x6B228) | |
| 10542 | +#define DSCC_PICTURE_PARAMETER_SET_10 _MMIO(0x6BA28) | |
| 10509 | 10543 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_10_PB 0x78298 |
| 10510 | 10544 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_10_PB 0x78398 |
| 10511 | 10545 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_10_PC 0x78498 |
| @@ -10521,8 +10555,8 @@ enum skl_power_gate { · 9 unmodified lines | ||
| 10521 | 10555 | #define DSC_RC_QUANT_INC_LIMIT1(lim) ((lim) << 8) |
| 10522 | 10556 | #define DSC_RC_QUANT_INC_LIMIT0(lim) ((lim) << 0) |
| 10523 | 10557 | |
| 10524 | −#define DSCA_PICTURE_PARAMETER_SET_11 0x6B22C | |
| 10525 | −#define DSCC_PICTURE_PARAMETER_SET_11 0x6BA2C | |
| 10558 | +#define DSCA_PICTURE_PARAMETER_SET_11 _MMIO(0x6B22C) | |
| 10559 | +#define DSCC_PICTURE_PARAMETER_SET_11 _MMIO(0x6BA2C) | |
| 10526 | 10560 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_11_PB 0x7829C |
| 10527 | 10561 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_11_PB 0x7839C |
| 10528 | 10562 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_11_PC 0x7849C |
| @@ -10534,8 +10568,8 @@ enum skl_power_gate { · 5 unmodified lines | ||
| 10534 | 10568 | _ICL_DSC1_PICTURE_PARAMETER_SET_11_PB, \ |
| 10535 | 10569 | _ICL_DSC1_PICTURE_PARAMETER_SET_11_PC) |
| 10536 | 10570 | |
| 10537 | −#define DSCA_PICTURE_PARAMETER_SET_12 0x6B260 | |
| 10538 | −#define DSCC_PICTURE_PARAMETER_SET_12 0x6BA60 | |
| 10571 | +#define DSCA_PICTURE_PARAMETER_SET_12 _MMIO(0x6B260) | |
| 10572 | +#define DSCC_PICTURE_PARAMETER_SET_12 _MMIO(0x6BA60) | |
| 10539 | 10573 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_12_PB 0x782A0 |
| 10540 | 10574 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_12_PB 0x783A0 |
| 10541 | 10575 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_12_PC 0x784A0 |
| @@ -10547,8 +10581,8 @@ enum skl_power_gate { · 5 unmodified lines | ||
| 10547 | 10581 | _ICL_DSC1_PICTURE_PARAMETER_SET_12_PB, \ |
| 10548 | 10582 | _ICL_DSC1_PICTURE_PARAMETER_SET_12_PC) |
| 10549 | 10583 | |
| 10550 | −#define DSCA_PICTURE_PARAMETER_SET_13 0x6B264 | |
| 10551 | −#define DSCC_PICTURE_PARAMETER_SET_13 0x6BA64 | |
| 10584 | +#define DSCA_PICTURE_PARAMETER_SET_13 _MMIO(0x6B264) | |
| 10585 | +#define DSCC_PICTURE_PARAMETER_SET_13 _MMIO(0x6BA64) | |
| 10552 | 10586 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_13_PB 0x782A4 |
| 10553 | 10587 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_13_PB 0x783A4 |
| 10554 | 10588 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_13_PC 0x784A4 |
| @@ -10560,8 +10594,8 @@ enum skl_power_gate { · 5 unmodified lines | ||
| 10560 | 10594 | _ICL_DSC1_PICTURE_PARAMETER_SET_13_PB, \ |
| 10561 | 10595 | _ICL_DSC1_PICTURE_PARAMETER_SET_13_PC) |
| 10562 | 10596 | |
| 10563 | −#define DSCA_PICTURE_PARAMETER_SET_14 0x6B268 | |
| 10564 | −#define DSCC_PICTURE_PARAMETER_SET_14 0x6BA68 | |
| 10597 | +#define DSCA_PICTURE_PARAMETER_SET_14 _MMIO(0x6B268) | |
| 10598 | +#define DSCC_PICTURE_PARAMETER_SET_14 _MMIO(0x6BA68) | |
| 10565 | 10599 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_14_PB 0x782A8 |
| 10566 | 10600 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_14_PB 0x783A8 |
| 10567 | 10601 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_14_PC 0x784A8 |
| @@ -10573,8 +10607,8 @@ enum skl_power_gate { · 5 unmodified lines | ||
| 10573 | 10607 | _ICL_DSC1_PICTURE_PARAMETER_SET_14_PB, \ |
| 10574 | 10608 | _ICL_DSC1_PICTURE_PARAMETER_SET_14_PC) |
| 10575 | 10609 | |
| 10576 | −#define DSCA_PICTURE_PARAMETER_SET_15 0x6B26C | |
| 10577 | −#define DSCC_PICTURE_PARAMETER_SET_15 0x6BA6C | |
| 10610 | +#define DSCA_PICTURE_PARAMETER_SET_15 _MMIO(0x6B26C) | |
| 10611 | +#define DSCC_PICTURE_PARAMETER_SET_15 _MMIO(0x6BA6C) | |
| 10578 | 10612 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_15_PB 0x782AC |
| 10579 | 10613 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_15_PB 0x783AC |
| 10580 | 10614 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_15_PC 0x784AC |
| @@ -10586,8 +10620,8 @@ enum skl_power_gate { · 5 unmodified lines | ||
| 10586 | 10620 | _ICL_DSC1_PICTURE_PARAMETER_SET_15_PB, \ |
| 10587 | 10621 | _ICL_DSC1_PICTURE_PARAMETER_SET_15_PC) |
| 10588 | 10622 | |
| 10589 | −#define DSCA_PICTURE_PARAMETER_SET_16 0x6B270 | |
| 10590 | −#define DSCC_PICTURE_PARAMETER_SET_16 0x6BA70 | |
| 10623 | +#define DSCA_PICTURE_PARAMETER_SET_16 _MMIO(0x6B270) | |
| 10624 | +#define DSCC_PICTURE_PARAMETER_SET_16 _MMIO(0x6BA70) | |
| 10591 | 10625 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_16_PB 0x782B0 |
| 10592 | 10626 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_16_PB 0x783B0 |
| 10593 | 10627 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_16_PC 0x784B0 |
| @@ -10599,7 +10633,7 @@ enum skl_power_gate { · 5 unmodified lines | ||
| 10599 | 10633 | _ICL_DSC1_PICTURE_PARAMETER_SET_16_PB, \ |
| 10600 | 10634 | _ICL_DSC1_PICTURE_PARAMETER_SET_16_PC) |
| 10601 | 10635 | #define DSC_SLICE_PER_LINE(slice_per_line) ((slice_per_line) << 16) |
| 10602 | −#define DSC_SLICE_CHUNK_SIZE(slice_chunk_aize) (slice_chunk_size << 0) | |
| 10636 | +#define DSC_SLICE_CHUNK_SIZE(slice_chunk_size) ((slice_chunk_size) << 0) | |
| 10603 | 10637 | |
| 10604 | 10638 | /* Icelake Rate Control Buffer Threshold Registers */ |
| 10605 | 10639 | #define DSCA_RC_BUF_THRESH_0 _MMIO(0x6B230) |
| @@ -10652,4 +10686,17 @@ enum skl_power_gate { · 46 unmodified lines | ||
| 10652 | 10686 | _ICL_DSC1_RC_BUF_THRESH_1_UDW_PB, \ |
| 10653 | 10687 | _ICL_DSC1_RC_BUF_THRESH_1_UDW_PC) |
| 10654 | 10688 | |
| 10689 | +#define PORT_TX_DFLEXDPSP _MMIO(0x1638A0) | |
| 10690 | +#define TC_LIVE_STATE_TBT(tc_port) (1 << ((tc_port) * 8 + 6)) | |
| 10691 | +#define TC_LIVE_STATE_TC(tc_port) (1 << ((tc_port) * 8 + 5)) | |
| 10692 | +#define DP_LANE_ASSIGNMENT_SHIFT(tc_port) ((tc_port) * 8) | |
| 10693 | +#define DP_LANE_ASSIGNMENT_MASK(tc_port) (0xf << ((tc_port) * 8)) | |
| 10694 | +#define DP_LANE_ASSIGNMENT(tc_port, x) ((x) << ((tc_port) * 8)) | |
| 10695 | + | |
| 10696 | +#define PORT_TX_DFLEXDPPMS _MMIO(0x163890) | |
| 10697 | +#define DP_PHY_MODE_STATUS_COMPLETED(tc_port) (1 << (tc_port)) | |
| 10698 | + | |
| 10699 | +#define PORT_TX_DFLEXDPCSSS _MMIO(0x163894) | |
| 10700 | +#define DP_PHY_MODE_STATUS_NOT_SAFE(tc_port) (1 << (tc_port)) | |
| 10701 | + | |
| 10655 | 10702 | #endif /* _I915_REG_H_ */ |
| @@ -527,7 +527,7 @@ void __i915_request_submit(struct i915_request *request) · 526 unmodified lines | ||
| 527 | 527 | |
| 528 | 528 | seqno = timeline_get_seqno(&engine->timeline); |
| 529 | 529 | GEM_BUG_ON(!seqno); |
| 530 | − GEM_BUG_ON(i915_seqno_passed(intel_engine_get_seqno(engine), seqno)); | |
| 530 | + GEM_BUG_ON(intel_engine_signaled(engine, seqno)); | |
| 531 | 531 | |
| 532 | 532 | /* We may be recursing from the signal callback of another i915 fence */ |
| 533 | 533 | spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING); |
| @@ -579,8 +579,7 @@ void __i915_request_unsubmit(struct i915_request *request) · 45 unmodified lines | ||
| 579 | 579 | */ |
| 580 | 580 | GEM_BUG_ON(!request->global_seqno); |
| 581 | 581 | GEM_BUG_ON(request->global_seqno != engine->timeline.seqno); |
| 582 | − GEM_BUG_ON(i915_seqno_passed(intel_engine_get_seqno(engine), | |
| 583 | − request->global_seqno)); | |
| 582 | + GEM_BUG_ON(intel_engine_has_completed(engine, request->global_seqno)); | |
| 584 | 583 | engine->timeline.seqno--; |
| 585 | 584 | |
| 586 | 585 | /* We may be recursing from the signal callback of another i915 fence */ |
| @@ -1205,7 +1204,7 @@ static bool __i915_spin_request(const struct i915_request *rq, · 618 unmodified lines | ||
| 1205 | 1204 | * it is a fair assumption that it will not complete within our |
| 1206 | 1205 | * relatively short timeout. |
| 1207 | 1206 | */ |
| 1208 | − if (!i915_seqno_passed(intel_engine_get_seqno(engine), seqno - 1)) | |
| 1207 | + if (!intel_engine_has_started(engine, seqno)) | |
| 1209 | 1208 | return false; |
| 1210 | 1209 | |
| 1211 | 1210 | /* |
| @@ -1222,7 +1221,7 @@ static bool __i915_spin_request(const struct i915_request *rq, · 10 unmodified lines | ||
| 1222 | 1221 | irq = READ_ONCE(engine->breadcrumbs.irq_count); |
| 1223 | 1222 | timeout_us += local_clock_us(&cpu); |
| 1224 | 1223 | do { |
| 1225 | − if (i915_seqno_passed(intel_engine_get_seqno(engine), seqno)) | |
| 1224 | + if (intel_engine_has_completed(engine, seqno)) | |
| 1226 | 1225 | return seqno == i915_request_global_seqno(rq); |
| 1227 | 1226 | |
| 1228 | 1227 | /* |
| @@ -272,7 +272,10 @@ long i915_request_wait(struct i915_request *rq, · 271 unmodified lines | ||
| 272 | 272 | #define I915_WAIT_ALL BIT(2) /* used by i915_gem_object_wait() */ |
| 273 | 273 | #define I915_WAIT_FOR_IDLE_BOOST BIT(3) |
| 274 | 274 | |
| 275 | −static inline u32 intel_engine_get_seqno(struct intel_engine_cs *engine); | |
| 275 | +static inline bool intel_engine_has_started(struct intel_engine_cs *engine, | |
| 276 | + u32 seqno); | |
| 277 | +static inline bool intel_engine_has_completed(struct intel_engine_cs *engine, | |
| 278 | + u32 seqno); | |
| 276 | 279 | |
| 277 | 280 | /** |
| 278 | 281 | * Returns true if seq1 is later than seq2. |
| @@ -282,11 +285,31 @@ static inline bool i915_seqno_passed(u32 seq1, u32 seq2) · 3 unmodified lines | ||
| 282 | 285 | return (s32)(seq1 - seq2) >= 0; |
| 283 | 286 | } |
| 284 | 287 | |
| 288 | +/** | |
| 289 | + * i915_request_started - check if the request has begun being executed | |
| 290 | + * @rq: the request | |
| 291 | + * | |
| 292 | + * Returns true if the request has been submitted to hardware, and the hardware | |
| 293 | + * has advanced passed the end of the previous request and so should be either | |
| 294 | + * currently processing the request (though it may be preempted and so | |
| 295 | + * not necessarily the next request to complete) or have completed the request. | |
| 296 | + */ | |
| 297 | +static inline bool i915_request_started(const struct i915_request *rq) | |
| 298 | +{ | |
| 299 | + u32 seqno; | |
| 300 | + | |
| 301 | + seqno = i915_request_global_seqno(rq); | |
| 302 | + if (!seqno) /* not yet submitted to HW */ | |
| 303 | + return false; | |
| 304 | + | |
| 305 | + return intel_engine_has_started(rq->engine, seqno); | |
| 306 | +} | |
| 307 | + | |
| 285 | 308 | static inline bool |
| 286 | 309 | __i915_request_completed(const struct i915_request *rq, u32 seqno) |
| 287 | 310 | { |
| 288 | 311 | GEM_BUG_ON(!seqno); |
| 289 | − return i915_seqno_passed(intel_engine_get_seqno(rq->engine), seqno) && | |
| 312 | + return intel_engine_has_completed(rq->engine, seqno) && | |
| 290 | 313 | seqno == i915_request_global_seqno(rq); |
| 291 | 314 | } |
| 292 | 315 | |
| @@ -301,18 +324,6 @@ static inline bool i915_request_completed(const struct i915_request *rq) · 8 unmodified lines | ||
| 301 | 324 | return __i915_request_completed(rq, seqno); |
| 302 | 325 | } |
| 303 | 326 | |
| 304 | −static inline bool i915_request_started(const struct i915_request *rq) | |
| 305 | −{ | |
| 306 | − u32 seqno; | |
| 307 | − | |
| 308 | − seqno = i915_request_global_seqno(rq); | |
| 309 | − if (!seqno) | |
| 310 | − return false; | |
| 311 | − | |
| 312 | − return i915_seqno_passed(intel_engine_get_seqno(rq->engine), | |
| 313 | − seqno - 1); | |
| 314 | −} | |
| 315 | − | |
| 316 | 327 | static inline bool i915_sched_node_signaled(const struct i915_sched_node *node) |
| 317 | 328 | { |
| 318 | 329 | const struct i915_request *rq = |
| @@ -405,7 +405,7 @@ void i915_vma_unpin_iomap(struct i915_vma *vma) · 404 unmodified lines | ||
| 405 | 405 | i915_vma_unpin(vma); |
| 406 | 406 | } |
| 407 | 407 | |
| 408 | −void i915_vma_unpin_and_release(struct i915_vma **p_vma) | |
| 408 | +void i915_vma_unpin_and_release(struct i915_vma **p_vma, unsigned int flags) | |
| 409 | 409 | { |
| 410 | 410 | struct i915_vma *vma; |
| 411 | 411 | struct drm_i915_gem_object *obj; |
| @@ -420,6 +420,9 @@ void i915_vma_unpin_and_release(struct i915_vma **p_vma) · 8 unmodified lines | ||
| 420 | 420 | i915_vma_unpin(vma); |
| 421 | 421 | i915_vma_close(vma); |
| 422 | 422 | |
| 423 | + if (flags & I915_VMA_RELEASE_MAP) | |
| 424 | + i915_gem_object_unpin_map(obj); | |
| 425 | + | |
| 423 | 426 | __i915_gem_object_release_unless_active(obj); |
| 424 | 427 | } |
| 425 | 428 | |
| @@ -138,7 +138,8 @@ i915_vma_instance(struct drm_i915_gem_object *obj, · 137 unmodified lines | ||
| 138 | 138 | struct i915_address_space *vm, |
| 139 | 139 | const struct i915_ggtt_view *view); |
| 140 | 140 | |
| 141 | −void i915_vma_unpin_and_release(struct i915_vma **p_vma); | |
| 141 | +void i915_vma_unpin_and_release(struct i915_vma **p_vma, unsigned int flags); | |
| 142 | +#define I915_VMA_RELEASE_MAP BIT(0) | |
| 142 | 143 | |
| 143 | 144 | static inline bool i915_vma_is_active(struct i915_vma *vma) |
| 144 | 145 | { |
| @@ -207,6 +208,11 @@ static inline u32 i915_ggtt_offset(const struct i915_vma *vma) · 62 unmodified lines | ||
| 207 | 208 | return lower_32_bits(vma->node.start); |
| 208 | 209 | } |
| 209 | 210 | |
| 211 | +static inline u32 i915_ggtt_pin_bias(struct i915_vma *vma) | |
| 212 | +{ | |
| 213 | + return i915_vm_to_ggtt(vma->vm)->pin_bias; | |
| 214 | +} | |
| 215 | + | |
| 210 | 216 | static inline struct i915_vma *i915_vma_get(struct i915_vma *vma) |
| 211 | 217 | { |
| 212 | 218 | i915_gem_object_get(vma->obj); |
| @@ -245,6 +251,8 @@ i915_vma_compare(struct i915_vma *vma, · 32 unmodified lines | ||
| 245 | 251 | if (cmp) |
| 246 | 252 | return cmp; |
| 247 | 253 | |
| 254 | + assert_i915_gem_gtt_types(); | |
| 255 | + | |
| 248 | 256 | /* ggtt_view.type also encodes its size so that we both distinguish |
| 249 | 257 | * different views using it as a "type" and also use a compact (no |
| 250 | 258 | * accessing of uninitialised padding bytes) memcmp without storing |
| @@ -159,7 +159,7 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_ · 158 unmodified lines | ||
| 159 | 159 | } |
| 160 | 160 | |
| 161 | 161 | intel_state->base.visible = false; |
| 162 | − ret = intel_plane->check_plane(intel_plane, crtc_state, intel_state); | |
| 162 | + ret = intel_plane->check_plane(crtc_state, intel_state); | |
| 163 | 163 | if (ret) |
| 164 | 164 | return ret; |
| 165 | 165 | |
| @@ -170,7 +170,9 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_ · 4 unmodified lines | ||
| 170 | 170 | if (state->fb && INTEL_GEN(dev_priv) >= 9 && crtc_state->base.enable && |
| 171 | 171 | adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { |
| 172 | 172 | if (state->fb->modifier == I915_FORMAT_MOD_Y_TILED || |
| 173 | − state->fb->modifier == I915_FORMAT_MOD_Yf_TILED) { | |
| 173 | + state->fb->modifier == I915_FORMAT_MOD_Yf_TILED || | |
| 174 | + state->fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || | |
| 175 | + state->fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) { | |
| 174 | 176 | DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n"); |
| 175 | 177 | return -EINVAL; |
| 176 | 178 | } |
| @@ -256,8 +256,7 @@ void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine) · 255 unmodified lines | ||
| 256 | 256 | spin_unlock(&b->irq_lock); |
| 257 | 257 | |
| 258 | 258 | rbtree_postorder_for_each_entry_safe(wait, n, &b->waiters, node) { |
| 259 | − GEM_BUG_ON(!i915_seqno_passed(intel_engine_get_seqno(engine), | |
| 260 | − wait->seqno)); | |
| 259 | + GEM_BUG_ON(!intel_engine_signaled(engine, wait->seqno)); | |
| 261 | 260 | RB_CLEAR_NODE(&wait->node); |
| 262 | 261 | wake_up_process(wait->tsk); |
| 263 | 262 | } |
| @@ -508,8 +507,7 @@ bool intel_engine_add_wait(struct intel_engine_cs *engine, · 244 unmodified lines | ||
| 508 | 507 | return armed; |
| 509 | 508 | |
| 510 | 509 | /* Make the caller recheck if its request has already started. */ |
| 511 | − return i915_seqno_passed(intel_engine_get_seqno(engine), | |
| 512 | − wait->seqno - 1); | |
| 510 | + return intel_engine_has_started(engine, wait->seqno); | |
| 513 | 511 | } |
| 514 | 512 | |
| 515 | 513 | static inline bool chain_wakeup(struct rb_node *rb, int priority) |
| @@ -55,7 +55,9 @@ MODULE_FIRMWARE(I915_CSR_BXT); · 54 unmodified lines | ||
| 55 | 55 | #define BXT_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) |
| 56 | 56 | |
| 57 | 57 | |
| 58 | −#define CSR_MAX_FW_SIZE 0x2FFF | |
| 58 | +#define BXT_CSR_MAX_FW_SIZE 0x3000 | |
| 59 | +#define GLK_CSR_MAX_FW_SIZE 0x4000 | |
| 60 | +#define ICL_CSR_MAX_FW_SIZE 0x6000 | |
| 59 | 61 | #define CSR_DEFAULT_FW_OFFSET 0xFFFFFFFF |
| 60 | 62 | |
| 61 | 63 | struct intel_css_header { |
| @@ -279,6 +281,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, · 217 unmodified lines | ||
| 279 | 281 | struct intel_csr *csr = &dev_priv->csr; |
| 280 | 282 | const struct stepping_info *si = intel_get_stepping_info(dev_priv); |
| 281 | 283 | uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes; |
| 284 | + uint32_t max_fw_size = 0; | |
| 282 | 285 | uint32_t i; |
| 283 | 286 | uint32_t *dmc_payload; |
| 284 | 287 | uint32_t required_version; |
| @@ -359,6 +362,8 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, · 74 unmodified lines | ||
| 359 | 362 | si->stepping); |
| 360 | 363 | return NULL; |
| 361 | 364 | } |
| 365 | + /* Convert dmc_offset into number of bytes. By default it is in dwords*/ | |
| 366 | + dmc_offset *= 4; | |
| 362 | 367 | readcount += dmc_offset; |
| 363 | 368 | |
| 364 | 369 | /* Extract dmc_header information. */ |
| @@ -391,8 +396,16 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, · 26 unmodified lines | ||
| 391 | 396 | |
| 392 | 397 | /* fw_size is in dwords, so multiplied by 4 to convert into bytes. */ |
| 393 | 398 | nbytes = dmc_header->fw_size * 4; |
| 394 | − if (nbytes > CSR_MAX_FW_SIZE) { | |
| 395 | − DRM_ERROR("DMC firmware too big (%u bytes)\n", nbytes); | |
| 399 | + if (INTEL_GEN(dev_priv) >= 11) | |
| 400 | + max_fw_size = ICL_CSR_MAX_FW_SIZE; | |
| 401 | + else if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) | |
| 402 | + max_fw_size = GLK_CSR_MAX_FW_SIZE; | |
| 403 | + else if (IS_GEN9(dev_priv)) | |
| 404 | + max_fw_size = BXT_CSR_MAX_FW_SIZE; | |
| 405 | + else | |
| 406 | + MISSING_CASE(INTEL_REVID(dev_priv)); | |
| 407 | + if (nbytes > max_fw_size) { | |
| 408 | + DRM_ERROR("DMC FW too big (%u bytes)\n", nbytes); | |
| 396 | 409 | return NULL; |
| 397 | 410 | } |
| 398 | 411 | csr->dmc_fw_size = dmc_header->fw_size; |
| @@ -468,12 +481,6 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv) · 69 unmodified lines | ||
| 468 | 481 | csr->fw_path = I915_CSR_SKL; |
| 469 | 482 | else if (IS_BROXTON(dev_priv)) |
| 470 | 483 | csr->fw_path = I915_CSR_BXT; |
| 471 | − else { | |
| 472 | − DRM_ERROR("Unexpected: no known CSR firmware for platform\n"); | |
| 473 | − return; | |
| 474 | − } | |
| 475 | − | |
| 476 | − DRM_DEBUG_KMS("Loading %s\n", csr->fw_path); | |
| 477 | 484 | |
| 478 | 485 | /* |
| 479 | 486 | * Obtain a runtime pm reference, until CSR is loaded, |
| @@ -481,6 +488,14 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv) · 1 unmodified line | ||
| 481 | 488 | */ |
| 482 | 489 | intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); |
| 483 | 490 | |
| 491 | + if (csr->fw_path == NULL) { | |
| 492 | + DRM_DEBUG_KMS("No known CSR firmware for platform, disabling runtime PM\n"); | |
| 493 | + WARN_ON(!IS_ALPHA_SUPPORT(INTEL_INFO(dev_priv))); | |
| 494 | + | |
| 495 | + return; | |
| 496 | + } | |
| 497 | + | |
| 498 | + DRM_DEBUG_KMS("Loading %s\n", csr->fw_path); | |
| 484 | 499 | schedule_work(&dev_priv->csr.work); |
| 485 | 500 | } |
| 486 | 501 | |
| @@ -1414,7 +1414,7 @@ static int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv, · 1413 unmodified lines | ||
| 1414 | 1414 | break; |
| 1415 | 1415 | } |
| 1416 | 1416 | |
| 1417 | − ref_clock = dev_priv->cdclk.hw.ref; | |
| 1417 | + ref_clock = cnl_hdmi_pll_ref_clock(dev_priv); | |
| 1418 | 1418 | |
| 1419 | 1419 | dco_freq = (cfgcr0 & DPLL_CFGCR0_DCO_INTEGER_MASK) * ref_clock; |
| 1420 | 1420 | |
| @@ -1427,6 +1427,81 @@ static int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv, · 6 unmodified lines | ||
| 1427 | 1427 | return dco_freq / (p0 * p1 * p2 * 5); |
| 1428 | 1428 | } |
| 1429 | 1429 | |
| 1430 | +static int icl_calc_tbt_pll_link(struct drm_i915_private *dev_priv, | |
| 1431 | + enum port port) | |
| 1432 | +{ | |
| 1433 | + u32 val = I915_READ(DDI_CLK_SEL(port)) & DDI_CLK_SEL_MASK; | |
| 1434 | + | |
| 1435 | + switch (val) { | |
| 1436 | + case DDI_CLK_SEL_NONE: | |
| 1437 | + return 0; | |
| 1438 | + case DDI_CLK_SEL_TBT_162: | |
| 1439 | + return 162000; | |
| 1440 | + case DDI_CLK_SEL_TBT_270: | |
| 1441 | + return 270000; | |
| 1442 | + case DDI_CLK_SEL_TBT_540: | |
| 1443 | + return 540000; | |
| 1444 | + case DDI_CLK_SEL_TBT_810: | |
| 1445 | + return 810000; | |
| 1446 | + default: | |
| 1447 | + MISSING_CASE(val); | |
| 1448 | + return 0; | |
| 1449 | + } | |
| 1450 | +} | |
| 1451 | + | |
| 1452 | +static int icl_calc_mg_pll_link(struct drm_i915_private *dev_priv, | |
| 1453 | + enum port port) | |
| 1454 | +{ | |
| 1455 | + u32 mg_pll_div0, mg_clktop_hsclkctl; | |
| 1456 | + u32 m1, m2_int, m2_frac, div1, div2, refclk; | |
| 1457 | + u64 tmp; | |
| 1458 | + | |
| 1459 | + refclk = dev_priv->cdclk.hw.ref; | |
| 1460 | + | |
| 1461 | + mg_pll_div0 = I915_READ(MG_PLL_DIV0(port)); | |
| 1462 | + mg_clktop_hsclkctl = I915_READ(MG_CLKTOP2_HSCLKCTL(port)); | |
| 1463 | + | |
| 1464 | + m1 = I915_READ(MG_PLL_DIV1(port)) & MG_PLL_DIV1_FBPREDIV_MASK; | |
| 1465 | + m2_int = mg_pll_div0 & MG_PLL_DIV0_FBDIV_INT_MASK; | |
| 1466 | + m2_frac = (mg_pll_div0 & MG_PLL_DIV0_FRACNEN_H) ? | |
| 1467 | + (mg_pll_div0 & MG_PLL_DIV0_FBDIV_FRAC_MASK) >> | |
| 1468 | + MG_PLL_DIV0_FBDIV_FRAC_SHIFT : 0; | |
| 1469 | + | |
| 1470 | + switch (mg_clktop_hsclkctl & MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK) { | |
| 1471 | + case MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_2: | |
| 1472 | + div1 = 2; | |
| 1473 | + break; | |
| 1474 | + case MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_3: | |
| 1475 | + div1 = 3; | |
| 1476 | + break; | |
| 1477 | + case MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_5: | |
| 1478 | + div1 = 5; | |
| 1479 | + break; | |
| 1480 | + case MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_7: | |
| 1481 | + div1 = 7; | |
| 1482 | + break; | |
| 1483 | + default: | |
| 1484 | + MISSING_CASE(mg_clktop_hsclkctl); | |
| 1485 | + return 0; | |
| 1486 | + } | |
| 1487 | + | |
| 1488 | + div2 = (mg_clktop_hsclkctl & MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK) >> | |
| 1489 | + MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_SHIFT; | |
| 1490 | + /* div2 value of 0 is same as 1 means no div */ | |
| 1491 | + if (div2 == 0) | |
| 1492 | + div2 = 1; | |
| 1493 | + | |
| 1494 | + /* | |
| 1495 | + * Adjust the original formula to delay the division by 2^22 in order to | |
| 1496 | + * minimize possible rounding errors. | |
| 1497 | + */ | |
| 1498 | + tmp = (u64)m1 * m2_int * refclk + | |
| 1499 | + (((u64)m1 * m2_frac * refclk) >> 22); | |
| 1500 | + tmp = div_u64(tmp, 5 * div1 * div2); | |
| 1501 | + | |
| 1502 | + return tmp; | |
| 1503 | +} | |
| 1504 | + | |
| 1430 | 1505 | static void ddi_dotclock_get(struct intel_crtc_state *pipe_config) |
| 1431 | 1506 | { |
| 1432 | 1507 | int dotclock; |
| @@ -1467,8 +1542,10 @@ static void icl_ddi_clock_get(struct intel_encoder *encoder, · 34 unmodified lines | ||
| 1467 | 1542 | link_clock = icl_calc_dp_combo_pll_link(dev_priv, |
| 1468 | 1543 | pll_id); |
| 1469 | 1544 | } else { |
| 1470 | − /* FIXME - Add for MG PLL */ | |
| 1471 | − WARN(1, "MG PLL clock_get code not implemented yet\n"); | |
| 1545 | + if (pll_id == DPLL_ID_ICL_TBTPLL) | |
| 1546 | + link_clock = icl_calc_tbt_pll_link(dev_priv, port); | |
| 1547 | + else | |
| 1548 | + link_clock = icl_calc_mg_pll_link(dev_priv, port); | |
| 1472 | 1549 | } |
| 1473 | 1550 | |
| 1474 | 1551 | pipe_config->port_clock = link_clock; |
| @@ -2468,7 +2545,128 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, · 993 unmodified lines | ||
| 2468 | 2545 | I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val); |
| 2469 | 2546 | } |
| 2470 | 2547 | |
| 2471 | −static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level, | |
| 2548 | +static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, | |
| 2549 | + int link_clock, | |
| 2550 | + u32 level) | |
| 2551 | +{ | |
| 2552 | + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | |
| 2553 | + enum port port = encoder->port; | |
| 2554 | + const struct icl_mg_phy_ddi_buf_trans *ddi_translations; | |
| 2555 | + u32 n_entries, val; | |
| 2556 | + int ln; | |
| 2557 | + | |
| 2558 | + n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations); | |
| 2559 | + ddi_translations = icl_mg_phy_ddi_translations; | |
| 2560 | + /* The table does not have values for level 3 and level 9. */ | |
| 2561 | + if (level >= n_entries || level == 3 || level == 9) { | |
| 2562 | + DRM_DEBUG_KMS("DDI translation not found for level %d. Using %d instead.", | |
| 2563 | + level, n_entries - 2); | |
| 2564 | + level = n_entries - 2; | |
| 2565 | + } | |
| 2566 | + | |
| 2567 | + /* Set MG_TX_LINK_PARAMS cri_use_fs32 to 0. */ | |
| 2568 | + for (ln = 0; ln < 2; ln++) { | |
| 2569 | + val = I915_READ(MG_TX1_LINK_PARAMS(port, ln)); | |
| 2570 | + val &= ~CRI_USE_FS32; | |
| 2571 | + I915_WRITE(MG_TX1_LINK_PARAMS(port, ln), val); | |
| 2572 | + | |
| 2573 | + val = I915_READ(MG_TX2_LINK_PARAMS(port, ln)); | |
| 2574 | + val &= ~CRI_USE_FS32; | |
| 2575 | + I915_WRITE(MG_TX2_LINK_PARAMS(port, ln), val); | |
| 2576 | + } | |
| 2577 | + | |
| 2578 | + /* Program MG_TX_SWINGCTRL with values from vswing table */ | |
| 2579 | + for (ln = 0; ln < 2; ln++) { | |
| 2580 | + val = I915_READ(MG_TX1_SWINGCTRL(port, ln)); | |
| 2581 | + val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK; | |
| 2582 | + val |= CRI_TXDEEMPH_OVERRIDE_17_12( | |
| 2583 | + ddi_translations[level].cri_txdeemph_override_17_12); | |
| 2584 | + I915_WRITE(MG_TX1_SWINGCTRL(port, ln), val); | |
| 2585 | + | |
| 2586 | + val = I915_READ(MG_TX2_SWINGCTRL(port, ln)); | |
| 2587 | + val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK; | |
| 2588 | + val |= CRI_TXDEEMPH_OVERRIDE_17_12( | |
| 2589 | + ddi_translations[level].cri_txdeemph_override_17_12); | |
| 2590 | + I915_WRITE(MG_TX2_SWINGCTRL(port, ln), val); | |
| 2591 | + } | |
| 2592 | + | |
| 2593 | + /* Program MG_TX_DRVCTRL with values from vswing table */ | |
| 2594 | + for (ln = 0; ln < 2; ln++) { | |
| 2595 | + val = I915_READ(MG_TX1_DRVCTRL(port, ln)); | |
| 2596 | + val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK | | |
| 2597 | + CRI_TXDEEMPH_OVERRIDE_5_0_MASK); | |
| 2598 | + val |= CRI_TXDEEMPH_OVERRIDE_5_0( | |
| 2599 | + ddi_translations[level].cri_txdeemph_override_5_0) | | |
| 2600 | + CRI_TXDEEMPH_OVERRIDE_11_6( | |
| 2601 | + ddi_translations[level].cri_txdeemph_override_11_6) | | |
| 2602 | + CRI_TXDEEMPH_OVERRIDE_EN; | |
| 2603 | + I915_WRITE(MG_TX1_DRVCTRL(port, ln), val); | |
| 2604 | + | |
| 2605 | + val = I915_READ(MG_TX2_DRVCTRL(port, ln)); | |
| 2606 | + val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK | | |
| 2607 | + CRI_TXDEEMPH_OVERRIDE_5_0_MASK); | |
| 2608 | + val |= CRI_TXDEEMPH_OVERRIDE_5_0( | |
| 2609 | + ddi_translations[level].cri_txdeemph_override_5_0) | | |
| 2610 | + CRI_TXDEEMPH_OVERRIDE_11_6( | |
| 2611 | + ddi_translations[level].cri_txdeemph_override_11_6) | | |
| 2612 | + CRI_TXDEEMPH_OVERRIDE_EN; | |
| 2613 | + I915_WRITE(MG_TX2_DRVCTRL(port, ln), val); | |
| 2614 | + | |
| 2615 | + /* FIXME: Program CRI_LOADGEN_SEL after the spec is updated */ | |
| 2616 | + } | |
| 2617 | + | |
| 2618 | + /* | |
| 2619 | + * Program MG_CLKHUB<LN, port being used> with value from frequency table | |
| 2620 | + * In case of Legacy mode on MG PHY, both TX1 and TX2 enabled so use the | |
| 2621 | + * values from table for which TX1 and TX2 enabled. | |
| 2622 | + */ | |
| 2623 | + for (ln = 0; ln < 2; ln++) { | |
| 2624 | + val = I915_READ(MG_CLKHUB(port, ln)); | |
| 2625 | + if (link_clock < 300000) | |
| 2626 | + val |= CFG_LOW_RATE_LKREN_EN; | |
| 2627 | + else | |
| 2628 | + val &= ~CFG_LOW_RATE_LKREN_EN; | |
| 2629 | + I915_WRITE(MG_CLKHUB(port, ln), val); | |
| 2630 | + } | |
| 2631 | + | |
| 2632 | + /* Program the MG_TX_DCC<LN, port being used> based on the link frequency */ | |
| 2633 | + for (ln = 0; ln < 2; ln++) { | |
| 2634 | + val = I915_READ(MG_TX1_DCC(port, ln)); | |
| 2635 | + val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK; | |
| 2636 | + if (link_clock <= 500000) { | |
| 2637 | + val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN; | |
| 2638 | + } else { | |
| 2639 | + val |= CFG_AMI_CK_DIV_OVERRIDE_EN | | |
| 2640 | + CFG_AMI_CK_DIV_OVERRIDE_VAL(1); | |
| 2641 | + } | |
| 2642 | + I915_WRITE(MG_TX1_DCC(port, ln), val); | |
| 2643 | + | |
| 2644 | + val = I915_READ(MG_TX2_DCC(port, ln)); | |
| 2645 | + val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK; | |
| 2646 | + if (link_clock <= 500000) { | |
| 2647 | + val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN; | |
| 2648 | + } else { | |
| 2649 | + val |= CFG_AMI_CK_DIV_OVERRIDE_EN | | |
| 2650 | + CFG_AMI_CK_DIV_OVERRIDE_VAL(1); | |
| 2651 | + } | |
| 2652 | + I915_WRITE(MG_TX2_DCC(port, ln), val); | |
| 2653 | + } | |
| 2654 | + | |
| 2655 | + /* Program MG_TX_PISO_READLOAD with values from vswing table */ | |
| 2656 | + for (ln = 0; ln < 2; ln++) { | |
| 2657 | + val = I915_READ(MG_TX1_PISO_READLOAD(port, ln)); | |
| 2658 | + val |= CRI_CALCINIT; | |
| 2659 | + I915_WRITE(MG_TX1_PISO_READLOAD(port, ln), val); | |
| 2660 | + | |
| 2661 | + val = I915_READ(MG_TX2_PISO_READLOAD(port, ln)); | |
| 2662 | + val |= CRI_CALCINIT; | |
| 2663 | + I915_WRITE(MG_TX2_PISO_READLOAD(port, ln), val); | |
| 2664 | + } | |
| 2665 | +} | |
| 2666 | + | |
| 2667 | +static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, | |
| 2668 | + int link_clock, | |
| 2669 | + u32 level, | |
| 2472 | 2670 | enum intel_output_type type) |
| 2473 | 2671 | { |
| 2474 | 2672 | enum port port = encoder->port; |
| @@ -2476,8 +2674,7 @@ static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level, · 1 unmodified line | ||
| 2476 | 2674 | if (port == PORT_A || port == PORT_B) |
| 2477 | 2675 | icl_combo_phy_ddi_vswing_sequence(encoder, level, type); |
| 2478 | 2676 | else |
| 2479 | − /* Not Implemented Yet */ | |
| 2480 | − WARN_ON(1); | |
| 2677 | + icl_mg_phy_ddi_vswing_sequence(encoder, link_clock, level); | |
| 2481 | 2678 | } |
| 2482 | 2679 | |
| 2483 | 2680 | static uint32_t translate_signal_level(int signal_levels) |
| @@ -2512,7 +2709,8 @@ u32 bxt_signal_levels(struct intel_dp *intel_dp) · 28 unmodified lines | ||
| 2512 | 2709 | int level = intel_ddi_dp_level(intel_dp); |
| 2513 | 2710 | |
| 2514 | 2711 | if (IS_ICELAKE(dev_priv)) |
| 2515 | − icl_ddi_vswing_sequence(encoder, level, encoder->type); | |
| 2712 | + icl_ddi_vswing_sequence(encoder, intel_dp->link_rate, | |
| 2713 | + level, encoder->type); | |
| 2516 | 2714 | else if (IS_CANNONLAKE(dev_priv)) |
| 2517 | 2715 | cnl_ddi_vswing_sequence(encoder, level, encoder->type); |
| 2518 | 2716 | else |
| @@ -2692,8 +2890,12 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, · 173 unmodified lines | ||
| 2692 | 2890 | |
| 2693 | 2891 | intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); |
| 2694 | 2892 | |
| 2893 | + icl_program_mg_dp_mode(intel_dp); | |
| 2894 | + icl_disable_phy_clock_gating(dig_port); | |
| 2895 | + | |
| 2695 | 2896 | if (IS_ICELAKE(dev_priv)) |
| 2696 | − icl_ddi_vswing_sequence(encoder, level, encoder->type); | |
| 2897 | + icl_ddi_vswing_sequence(encoder, crtc_state->port_clock, | |
| 2898 | + level, encoder->type); | |
| 2697 | 2899 | else if (IS_CANNONLAKE(dev_priv)) |
| 2698 | 2900 | cnl_ddi_vswing_sequence(encoder, level, encoder->type); |
| 2699 | 2901 | else if (IS_GEN9_LP(dev_priv)) |
| @@ -2708,7 +2910,10 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, · 8 unmodified lines | ||
| 2708 | 2910 | if (port != PORT_A || INTEL_GEN(dev_priv) >= 9) |
| 2709 | 2911 | intel_dp_stop_link_train(intel_dp); |
| 2710 | 2912 | |
| 2711 | − intel_ddi_enable_pipe_clock(crtc_state); | |
| 2913 | + icl_enable_phy_clock_gating(dig_port); | |
| 2914 | + | |
| 2915 | + if (!is_mst) | |
| 2916 | + intel_ddi_enable_pipe_clock(crtc_state); | |
| 2712 | 2917 | } |
| 2713 | 2918 | |
| 2714 | 2919 | static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder, |
| @@ -2728,7 +2933,8 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder, · 13 unmodified lines | ||
| 2728 | 2933 | intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); |
| 2729 | 2934 | |
| 2730 | 2935 | if (IS_ICELAKE(dev_priv)) |
| 2731 | − icl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI); | |
| 2936 | + icl_ddi_vswing_sequence(encoder, crtc_state->port_clock, | |
| 2937 | + level, INTEL_OUTPUT_HDMI); | |
| 2732 | 2938 | else if (IS_CANNONLAKE(dev_priv)) |
| 2733 | 2939 | cnl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI); |
| 2734 | 2940 | else if (IS_GEN9_LP(dev_priv)) |
| @@ -2810,14 +3016,14 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder, · 75 unmodified lines | ||
| 2810 | 3016 | bool is_mst = intel_crtc_has_type(old_crtc_state, |
| 2811 | 3017 | INTEL_OUTPUT_DP_MST); |
| 2812 | 3018 | |
| 2813 | − intel_ddi_disable_pipe_clock(old_crtc_state); | |
| 2814 | − | |
| 2815 | − /* | |
| 2816 | − * Power down sink before disabling the port, otherwise we end | |
| 2817 | − * up getting interrupts from the sink on detecting link loss. | |
| 2818 | − */ | |
| 2819 | − if (!is_mst) | |
| 3019 | + if (!is_mst) { | |
| 3020 | + intel_ddi_disable_pipe_clock(old_crtc_state); | |
| 3021 | + /* | |
| 3022 | + * Power down sink before disabling the port, otherwise we end | |
| 3023 | + * up getting interrupts from the sink on detecting link loss. | |
| 3024 | + */ | |
| 2820 | 3025 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); |
| 3026 | + } | |
| 2821 | 3027 | |
| 2822 | 3028 | intel_disable_ddi_buf(encoder); |
| 2823 | 3029 | |
| @@ -103,9 +103,9 @@ enum intel_platform { · 102 unmodified lines | ||
| 103 | 103 | func(has_psr); \ |
| 104 | 104 | func(has_rc6); \ |
| 105 | 105 | func(has_rc6p); \ |
| 106 | − func(has_resource_streamer); \ | |
| 107 | 106 | func(has_runtime_pm); \ |
| 108 | 107 | func(has_snoop); \ |
| 108 | + func(has_coherent_ggtt); \ | |
| 109 | 109 | func(unfenced_needs_alignment); \ |
| 110 | 110 | func(cursor_needs_physical); \ |
| 111 | 111 | func(hws_needs_physical); \ |
| @@ -2474,6 +2474,12 @@ intel_get_format_info(const struct drm_mode_fb_cmd2 *cmd) · 2473 unmodified lines | ||
| 2474 | 2474 | } |
| 2475 | 2475 | } |
| 2476 | 2476 | |
| 2477 | +bool is_ccs_modifier(u64 modifier) | |
| 2478 | +{ | |
| 2479 | + return modifier == I915_FORMAT_MOD_Y_TILED_CCS || | |
| 2480 | + modifier == I915_FORMAT_MOD_Yf_TILED_CCS; | |
| 2481 | +} | |
| 2482 | + | |
| 2477 | 2483 | static int |
| 2478 | 2484 | intel_fill_fb_info(struct drm_i915_private *dev_priv, |
| 2479 | 2485 | struct drm_framebuffer *fb) |
| @@ -2504,8 +2510,7 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv, · 24 unmodified lines | ||
| 2504 | 2510 | return ret; |
| 2505 | 2511 | } |
| 2506 | 2512 | |
| 2507 | − if ((fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || | |
| 2508 | − fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) && i == 1) { | |
| 2513 | + if (is_ccs_modifier(fb->modifier) && i == 1) { | |
| 2509 | 2514 | int hsub = fb->format->hsub; |
| 2510 | 2515 | int vsub = fb->format->vsub; |
| 2511 | 2516 | int tile_width, tile_height; |
| @@ -3055,8 +3060,7 @@ static int skl_check_main_surface(const struct intel_crtc_state *crtc_state, · 543 unmodified lines | ||
| 3055 | 3060 | * CCS AUX surface doesn't have its own x/y offsets, we must make sure |
| 3056 | 3061 | * they match with the main surface x/y offsets. |
| 3057 | 3062 | */ |
| 3058 | − if (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || | |
| 3059 | − fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) { | |
| 3063 | + if (is_ccs_modifier(fb->modifier)) { | |
| 3060 | 3064 | while (!skl_check_main_ccs_coordinates(plane_state, x, y, offset)) { |
| 3061 | 3065 | if (offset == 0) |
| 3062 | 3066 | break; |
| @@ -3190,8 +3194,7 @@ int skl_check_plane_surface(const struct intel_crtc_state *crtc_state, · 127 unmodified lines | ||
| 3190 | 3194 | ret = skl_check_nv12_aux_surface(plane_state); |
| 3191 | 3195 | if (ret) |
| 3192 | 3196 | return ret; |
| 3193 | − } else if (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || | |
| 3194 | − fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) { | |
| 3197 | + } else if (is_ccs_modifier(fb->modifier)) { | |
| 3195 | 3198 | ret = skl_check_ccs_aux_surface(plane_state); |
| 3196 | 3199 | if (ret) |
| 3197 | 3200 | return ret; |
| @@ -3552,11 +3555,11 @@ static u32 skl_plane_ctl_tiling(uint64_t fb_modifier) · 354 unmodified lines | ||
| 3552 | 3555 | case I915_FORMAT_MOD_Y_TILED: |
| 3553 | 3556 | return PLANE_CTL_TILED_Y; |
| 3554 | 3557 | case I915_FORMAT_MOD_Y_TILED_CCS: |
| 3555 | − return PLANE_CTL_TILED_Y | PLANE_CTL_DECOMPRESSION_ENABLE; | |
| 3558 | + return PLANE_CTL_TILED_Y | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE; | |
| 3556 | 3559 | case I915_FORMAT_MOD_Yf_TILED: |
| 3557 | 3560 | return PLANE_CTL_TILED_YF; |
| 3558 | 3561 | case I915_FORMAT_MOD_Yf_TILED_CCS: |
| 3559 | − return PLANE_CTL_TILED_YF | PLANE_CTL_DECOMPRESSION_ENABLE; | |
| 3562 | + return PLANE_CTL_TILED_YF | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE; | |
| 3560 | 3563 | default: |
| 3561 | 3564 | MISSING_CASE(fb_modifier); |
| 3562 | 3565 | } |
| @@ -5079,10 +5082,14 @@ void hsw_disable_ips(const struct intel_crtc_state *crtc_state) · 1516 unmodified lines | ||
| 5079 | 5082 | mutex_lock(&dev_priv->pcu_lock); |
| 5080 | 5083 | WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0)); |
| 5081 | 5084 | mutex_unlock(&dev_priv->pcu_lock); |
| 5082 | − /* wait for pcode to finish disabling IPS, which may take up to 42ms */ | |
| 5085 | + /* | |
| 5086 | + * Wait for PCODE to finish disabling IPS. The BSpec specified | |
| 5087 | + * 42ms timeout value leads to occasional timeouts so use 100ms | |
| 5088 | + * instead. | |
| 5089 | + */ | |
| 5083 | 5090 | if (intel_wait_for_register(dev_priv, |
| 5084 | 5091 | IPS_CTL, IPS_ENABLE, 0, |
| 5085 | − 42)) | |
| 5092 | + 100)) | |
| 5086 | 5093 | DRM_ERROR("Timed out waiting for IPS disable\n"); |
| 5087 | 5094 | } else { |
| 5088 | 5095 | I915_WRITE(IPS_CTL, 0); |
| @@ -8799,13 +8806,13 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, · 3710 unmodified lines | ||
| 8799 | 8806 | fb->modifier = I915_FORMAT_MOD_X_TILED; |
| 8800 | 8807 | break; |
| 8801 | 8808 | case PLANE_CTL_TILED_Y: |
| 8802 | − if (val & PLANE_CTL_DECOMPRESSION_ENABLE) | |
| 8809 | + if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE) | |
| 8803 | 8810 | fb->modifier = I915_FORMAT_MOD_Y_TILED_CCS; |
| 8804 | 8811 | else |
| 8805 | 8812 | fb->modifier = I915_FORMAT_MOD_Y_TILED; |
| 8806 | 8813 | break; |
| 8807 | 8814 | case PLANE_CTL_TILED_YF: |
| 8808 | − if (val & PLANE_CTL_DECOMPRESSION_ENABLE) | |
| 8815 | + if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE) | |
| 8809 | 8816 | fb->modifier = I915_FORMAT_MOD_Yf_TILED_CCS; |
| 8810 | 8817 | else |
| 8811 | 8818 | fb->modifier = I915_FORMAT_MOD_Yf_TILED; |
| @@ -8974,7 +8981,7 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv) · 162 unmodified lines | ||
| 8974 | 8981 | I915_STATE_WARN(crtc->active, "CRTC for pipe %c enabled\n", |
| 8975 | 8982 | pipe_name(crtc->pipe)); |
| 8976 | 8983 | |
| 8977 | − I915_STATE_WARN(I915_READ(HSW_PWR_WELL_CTL_DRIVER(HSW_DISP_PW_GLOBAL)), | |
| 8984 | + I915_STATE_WARN(I915_READ(HSW_PWR_WELL_CTL2), | |
| 8978 | 8985 | "Display power well on\n"); |
| 8979 | 8986 | I915_STATE_WARN(I915_READ(SPLL_CTL) & SPLL_PLL_ENABLE, "SPLL enabled\n"); |
| 8980 | 8987 | I915_STATE_WARN(I915_READ(WRPLL_CTL(0)) & WRPLL_PLL_ENABLE, "WRPLL1 enabled\n"); |
| @@ -9691,8 +9698,7 @@ static bool i845_cursor_size_ok(const struct intel_plane_state *plane_state) · 710 unmodified lines | ||
| 9691 | 9698 | return intel_cursor_size_ok(plane_state) && IS_ALIGNED(width, 64); |
| 9692 | 9699 | } |
| 9693 | 9700 | |
| 9694 | −static int i845_check_cursor(struct intel_plane *plane, | |
| 9695 | − struct intel_crtc_state *crtc_state, | |
| 9701 | +static int i845_check_cursor(struct intel_crtc_state *crtc_state, | |
| 9696 | 9702 | struct intel_plane_state *plane_state) |
| 9697 | 9703 | { |
| 9698 | 9704 | const struct drm_framebuffer *fb = plane_state->base.fb; |
| @@ -9882,10 +9888,10 @@ static bool i9xx_cursor_size_ok(const struct intel_plane_state *plane_state) · 183 unmodified lines | ||
| 9882 | 9888 | return true; |
| 9883 | 9889 | } |
| 9884 | 9890 | |
| 9885 | −static int i9xx_check_cursor(struct intel_plane *plane, | |
| 9886 | − struct intel_crtc_state *crtc_state, | |
| 9891 | +static int i9xx_check_cursor(struct intel_crtc_state *crtc_state, | |
| 9887 | 9892 | struct intel_plane_state *plane_state) |
| 9888 | 9893 | { |
| 9894 | + struct intel_plane *plane = to_intel_plane(plane_state->base.plane); | |
| 9889 | 9895 | struct drm_i915_private *dev_priv = to_i915(plane->base.dev); |
| 9890 | 9896 | const struct drm_framebuffer *fb = plane_state->base.fb; |
| 9891 | 9897 | enum pipe pipe = plane->pipe; |
| @@ -12739,7 +12745,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) · 2847 unmodified lines | ||
| 12739 | 12745 | * down. |
| 12740 | 12746 | */ |
| 12741 | 12747 | INIT_WORK(&state->commit_work, intel_atomic_cleanup_work); |
| 12742 | − schedule_work(&state->commit_work); | |
| 12748 | + queue_work(system_highpri_wq, &state->commit_work); | |
| 12743 | 12749 | } |
| 12744 | 12750 | |
| 12745 | 12751 | static void intel_atomic_commit_work(struct work_struct *work) |
| @@ -12969,8 +12975,11 @@ static int intel_plane_pin_fb(struct intel_plane_state *plane_state) · 223 unmodified lines | ||
| 12969 | 12975 | INTEL_INFO(dev_priv)->cursor_needs_physical) { |
| 12970 | 12976 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); |
| 12971 | 12977 | const int align = intel_cursor_alignment(dev_priv); |
| 12978 | + int err; | |
| 12972 | 12979 | |
| 12973 | − return i915_gem_object_attach_phys(obj, align); | |
| 12980 | + err = i915_gem_object_attach_phys(obj, align); | |
| 12981 | + if (err) | |
| 12982 | + return err; | |
| 12974 | 12983 | } |
| 12975 | 12984 | |
| 12976 | 12985 | vma = intel_pin_and_fence_fb_obj(fb, |
| @@ -13189,10 +13198,10 @@ skl_max_scale(struct intel_crtc *intel_crtc, · 212 unmodified lines | ||
| 13189 | 13198 | } |
| 13190 | 13199 | |
| 13191 | 13200 | static int |
| 13192 | −intel_check_primary_plane(struct intel_plane *plane, | |
| 13193 | − struct intel_crtc_state *crtc_state, | |
| 13201 | +intel_check_primary_plane(struct intel_crtc_state *crtc_state, | |
| 13194 | 13202 | struct intel_plane_state *state) |
| 13195 | 13203 | { |
| 13204 | + struct intel_plane *plane = to_intel_plane(state->base.plane); | |
| 13196 | 13205 | struct drm_i915_private *dev_priv = to_i915(plane->base.dev); |
| 13197 | 13206 | struct drm_crtc *crtc = state->base.crtc; |
| 13198 | 13207 | int min_scale = DRM_PLANE_HELPER_NO_SCALING; |
| @@ -13400,8 +13409,7 @@ static bool skl_plane_format_mod_supported(struct drm_plane *_plane, · 201 unmodified lines | ||
| 13400 | 13409 | case DRM_FORMAT_XBGR8888: |
| 13401 | 13410 | case DRM_FORMAT_ARGB8888: |
| 13402 | 13411 | case DRM_FORMAT_ABGR8888: |
| 13403 | − if (modifier == I915_FORMAT_MOD_Yf_TILED_CCS || | |
| 13404 | − modifier == I915_FORMAT_MOD_Y_TILED_CCS) | |
| 13412 | + if (is_ccs_modifier(modifier)) | |
| 13405 | 13413 | return true; |
| 13406 | 13414 | /* fall through */ |
| 13407 | 13415 | case DRM_FORMAT_RGB565: |
| @@ -13620,24 +13628,22 @@ static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv, · 212 unmodified lines | ||
| 13620 | 13628 | bool skl_plane_has_planar(struct drm_i915_private *dev_priv, |
| 13621 | 13629 | enum pipe pipe, enum plane_id plane_id) |
| 13622 | 13630 | { |
| 13623 | − if (plane_id == PLANE_PRIMARY) { | |
| 13624 | − if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv)) | |
| 13625 | − return false; | |
| 13626 | − else if ((INTEL_GEN(dev_priv) == 9 && pipe == PIPE_C) && | |
| 13627 | − !IS_GEMINILAKE(dev_priv)) | |
| 13628 | − return false; | |
| 13629 | − } else if (plane_id >= PLANE_SPRITE0) { | |
| 13630 | − if (plane_id == PLANE_CURSOR) | |
| 13631 | − return false; | |
| 13632 | − if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) == 10) { | |
| 13633 | − if (plane_id != PLANE_SPRITE0) | |
| 13634 | − return false; | |
| 13635 | − } else { | |
| 13636 | − if (plane_id != PLANE_SPRITE0 || pipe == PIPE_C || | |
| 13637 | − IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv)) | |
| 13638 | − return false; | |
| 13639 | − } | |
| 13640 | − } | |
| 13631 | + /* | |
| 13632 | + * FIXME: ICL requires two hardware planes for scanning out NV12 | |
| 13633 | + * framebuffers. Do not advertize support until this is implemented. | |
| 13634 | + */ | |
| 13635 | + if (INTEL_GEN(dev_priv) >= 11) | |
| 13636 | + return false; | |
| 13637 | + | |
| 13638 | + if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv)) | |
| 13639 | + return false; | |
| 13640 | + | |
| 13641 | + if (INTEL_GEN(dev_priv) == 9 && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C) | |
| 13642 | + return false; | |
| 13643 | + | |
| 13644 | + if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0) | |
| 13645 | + return false; | |
| 13646 | + | |
| 13641 | 13647 | return true; |
| 13642 | 13648 | } |
| 13643 | 13649 | |
| @@ -14131,6 +14137,9 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv) · 487 unmodified lines | ||
| 14131 | 14137 | |
| 14132 | 14138 | intel_pps_init(dev_priv); |
| 14133 | 14139 | |
| 14140 | + if (INTEL_INFO(dev_priv)->num_pipes == 0) | |
| 14141 | + return; | |
| 14142 | + | |
| 14134 | 14143 | /* |
| 14135 | 14144 | * intel_edp_init_connector() depends on this completing first, to |
| 14136 | 14145 | * prevent the registeration of both eDP and LVDS and the incorrect |
| @@ -14547,7 +14556,7 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb, · 410 unmodified lines | ||
| 14547 | 14556 | break; |
| 14548 | 14557 | case DRM_FORMAT_NV12: |
| 14549 | 14558 | if (INTEL_GEN(dev_priv) < 9 || IS_SKYLAKE(dev_priv) || |
| 14550 | − IS_BROXTON(dev_priv)) { | |
| 14559 | + IS_BROXTON(dev_priv) || INTEL_GEN(dev_priv) >= 11) { | |
| 14551 | 14560 | DRM_DEBUG_KMS("unsupported pixel format: %s\n", |
| 14552 | 14561 | drm_get_format_name(mode_cmd->pixel_format, |
| 14553 | 14562 | &format_name)); |
| @@ -14594,8 +14603,7 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb, · 40 unmodified lines | ||
| 14594 | 14603 | * potential runtime errors at plane configuration time. |
| 14595 | 14604 | */ |
| 14596 | 14605 | if (IS_GEN9(dev_priv) && i == 0 && fb->width > 3840 && |
| 14597 | − (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || | |
| 14598 | − fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)) | |
| 14606 | + is_ccs_modifier(fb->modifier)) | |
| 14599 | 14607 | stride_alignment *= 4; |
| 14600 | 14608 | |
| 14601 | 14609 | if (fb->pitches[i] & (stride_alignment - 1)) { |
| @@ -15131,12 +15139,61 @@ static void intel_update_fdi_pll_freq(struct drm_i915_private *dev_priv) · 529 unmodified lines | ||
| 15131 | 15139 | DRM_DEBUG_DRIVER("FDI PLL freq=%d\n", dev_priv->fdi_pll_freq); |
| 15132 | 15140 | } |
| 15133 | 15141 | |
| 15142 | +static int intel_initial_commit(struct drm_device *dev) | |
| 15143 | +{ | |
| 15144 | + struct drm_atomic_state *state = NULL; | |
| 15145 | + struct drm_modeset_acquire_ctx ctx; | |
| 15146 | + struct drm_crtc *crtc; | |
| 15147 | + struct drm_crtc_state *crtc_state; | |
| 15148 | + int ret = 0; | |
| 15149 | + | |
| 15150 | + state = drm_atomic_state_alloc(dev); | |
| 15151 | + if (!state) | |
| 15152 | + return -ENOMEM; | |
| 15153 | + | |
| 15154 | + drm_modeset_acquire_init(&ctx, 0); | |
| 15155 | + | |
| 15156 | +retry: | |
| 15157 | + state->acquire_ctx = &ctx; | |
| 15158 | + | |
| 15159 | + drm_for_each_crtc(crtc, dev) { | |
| 15160 | + crtc_state = drm_atomic_get_crtc_state(state, crtc); | |
| 15161 | + if (IS_ERR(crtc_state)) { | |
| 15162 | + ret = PTR_ERR(crtc_state); | |
| 15163 | + goto out; | |
| 15164 | + } | |
| 15165 | + | |
| 15166 | + if (crtc_state->active) { | |
| 15167 | + ret = drm_atomic_add_affected_planes(state, crtc); | |
| 15168 | + if (ret) | |
| 15169 | + goto out; | |
| 15170 | + } | |
| 15171 | + } | |
| 15172 | + | |
| 15173 | + ret = drm_atomic_commit(state); | |
| 15174 | + | |
| 15175 | +out: | |
| 15176 | + if (ret == -EDEADLK) { | |
| 15177 | + drm_atomic_state_clear(state); | |
| 15178 | + drm_modeset_backoff(&ctx); | |
| 15179 | + goto retry; | |
| 15180 | + } | |
| 15181 | + | |
| 15182 | + drm_atomic_state_put(state); | |
| 15183 | + | |
| 15184 | + drm_modeset_drop_locks(&ctx); | |
| 15185 | + drm_modeset_acquire_fini(&ctx); | |
| 15186 | + | |
| 15187 | + return ret; | |
| 15188 | +} | |
| 15189 | + | |
| 15134 | 15190 | int intel_modeset_init(struct drm_device *dev) |
| 15135 | 15191 | { |
| 15136 | 15192 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 15137 | 15193 | struct i915_ggtt *ggtt = &dev_priv->ggtt; |
| 15138 | 15194 | enum pipe pipe; |
| 15139 | 15195 | struct intel_crtc *crtc; |
| 15196 | + int ret; | |
| 15140 | 15197 | |
| 15141 | 15198 | dev_priv->modeset_wq = alloc_ordered_workqueue("i915_modeset", 0); |
| 15142 | 15199 | |
| @@ -15160,9 +15217,6 @@ int intel_modeset_init(struct drm_device *dev) · 17 unmodified lines | ||
| 15160 | 15217 | |
| 15161 | 15218 | intel_init_pm(dev_priv); |
| 15162 | 15219 | |
| 15163 | − if (INTEL_INFO(dev_priv)->num_pipes == 0) | |
| 15164 | − return 0; | |
| 15165 | − | |
| 15166 | 15220 | /* |
| 15167 | 15221 | * There may be no VBT; and if the BIOS enabled SSC we can |
| 15168 | 15222 | * just keep using it to avoid unnecessary flicker. Whereas if the |
| @@ -15211,8 +15265,6 @@ int intel_modeset_init(struct drm_device *dev) · 42 unmodified lines | ||
| 15211 | 15265 | INTEL_INFO(dev_priv)->num_pipes > 1 ? "s" : ""); |
| 15212 | 15266 | |
| 15213 | 15267 | for_each_pipe(dev_priv, pipe) { |
| 15214 | − int ret; | |
| 15215 | − | |
| 15216 | 15268 | ret = intel_crtc_init(dev_priv, pipe); |
| 15217 | 15269 | if (ret) { |
| 15218 | 15270 | drm_mode_config_cleanup(dev); |
| @@ -15268,6 +15320,16 @@ int intel_modeset_init(struct drm_device *dev) · 49 unmodified lines | ||
| 15268 | 15320 | if (!HAS_GMCH_DISPLAY(dev_priv)) |
| 15269 | 15321 | sanitize_watermarks(dev); |
| 15270 | 15322 | |
| 15323 | + /* | |
| 15324 | + * Force all active planes to recompute their states. So that on | |
| 15325 | + * mode_setcrtc after probe, all the intel_plane_state variables | |
| 15326 | + * are already calculated and there is no assert_plane warnings | |
| 15327 | + * during bootup. | |
| 15328 | + */ | |
| 15329 | + ret = intel_initial_commit(dev); | |
| 15330 | + if (ret) | |
| 15331 | + DRM_DEBUG_KMS("Initial commit in probe failed.\n"); | |
| 15332 | + | |
| 15271 | 15333 | return 0; |
| 15272 | 15334 | } |
| 15273 | 15335 | |
| @@ -15792,6 +15854,8 @@ intel_modeset_setup_hw_state(struct drm_device *dev, · 518 unmodified lines | ||
| 15792 | 15854 | struct intel_encoder *encoder; |
| 15793 | 15855 | int i; |
| 15794 | 15856 | |
| 15857 | + intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); | |
| 15858 | + | |
| 15795 | 15859 | intel_early_display_was(dev_priv); |
| 15796 | 15860 | intel_modeset_readout_hw_state(dev); |
| 15797 | 15861 | |
| @@ -15846,9 +15910,8 @@ intel_modeset_setup_hw_state(struct drm_device *dev, · 48 unmodified lines | ||
| 15846 | 15910 | if (WARN_ON(put_domains)) |
| 15847 | 15911 | modeset_put_power_domains(dev_priv, put_domains); |
| 15848 | 15912 | } |
| 15849 | − intel_display_set_init_power(dev_priv, false); | |
| 15850 | 15913 | |
| 15851 | − intel_power_domains_verify_state(dev_priv); | |
| 15914 | + intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); | |
| 15852 | 15915 | |
| 15853 | 15916 | intel_fbc_init_pipe_state(dev_priv); |
| 15854 | 15917 | } |
| @@ -15937,8 +16000,6 @@ void intel_modeset_cleanup(struct drm_device *dev) · 82 unmodified lines | ||
| 15937 | 16000 | flush_work(&dev_priv->atomic_helper.free_work); |
| 15938 | 16001 | WARN_ON(!llist_empty(&dev_priv->atomic_helper.free_list)); |
| 15939 | 16002 | |
| 15940 | − intel_disable_gt_powersave(dev_priv); | |
| 15941 | − | |
| 15942 | 16003 | /* |
| 15943 | 16004 | * Interrupts and polling as the first thing to avoid creating havoc. |
| 15944 | 16005 | * Too much stuff here (turning of connectors, ...) would |
| @@ -15966,8 +16027,6 @@ void intel_modeset_cleanup(struct drm_device *dev) · 21 unmodified lines | ||
| 15966 | 16027 | |
| 15967 | 16028 | intel_cleanup_overlay(dev_priv); |
| 15968 | 16029 | |
| 15969 | − intel_cleanup_gt_powersave(dev_priv); | |
| 15970 | − | |
| 15971 | 16030 | intel_teardown_gmbus(dev_priv); |
| 15972 | 16031 | |
| 15973 | 16032 | destroy_workqueue(dev_priv->modeset_wq); |
| @@ -16075,8 +16134,7 @@ intel_display_capture_error_state(struct drm_i915_private *dev_priv) · 101 unmodified lines | ||
| 16075 | 16134 | return NULL; |
| 16076 | 16135 | |
| 16077 | 16136 | if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) |
| 16078 | − error->power_well_driver = | |
| 16079 | − I915_READ(HSW_PWR_WELL_CTL_DRIVER(HSW_DISP_PW_GLOBAL)); | |
| 16137 | + error->power_well_driver = I915_READ(HSW_PWR_WELL_CTL2); | |
| 16080 | 16138 | |
| 16081 | 16139 | for_each_pipe(dev_priv, i) { |
| 16082 | 16140 | error->pipe[i].power_domain_on = |
| @@ -25,6 +25,22 @@ · 24 unmodified lines | ||
| 25 | 25 | #ifndef _INTEL_DISPLAY_H_ |
| 26 | 26 | #define _INTEL_DISPLAY_H_ |
| 27 | 27 | |
| 28 | +enum i915_gpio { | |
| 29 | + GPIOA, | |
| 30 | + GPIOB, | |
| 31 | + GPIOC, | |
| 32 | + GPIOD, | |
| 33 | + GPIOE, | |
| 34 | + GPIOF, | |
| 35 | + GPIOG, | |
| 36 | + GPIOH, | |
| 37 | + __GPIOI_UNUSED, | |
| 38 | + GPIOJ, | |
| 39 | + GPIOK, | |
| 40 | + GPIOL, | |
| 41 | + GPIOM, | |
| 42 | +}; | |
| 43 | + | |
| 28 | 44 | enum pipe { |
| 29 | 45 | INVALID_PIPE = -1, |
| 30 | 46 | |
| @@ -161,6 +177,13 @@ enum tc_port { · 130 unmodified lines | ||
| 161 | 177 | I915_MAX_TC_PORTS |
| 162 | 178 | }; |
| 163 | 179 | |
| 180 | +enum tc_port_type { | |
| 181 | + TC_PORT_UNKNOWN = 0, | |
| 182 | + TC_PORT_TYPEC, | |
| 183 | + TC_PORT_TBT, | |
| 184 | + TC_PORT_LEGACY, | |
| 185 | +}; | |
| 186 | + | |
| 164 | 187 | enum dpio_channel { |
| 165 | 188 | DPIO_CH0, |
| 166 | 189 | DPIO_CH1 |
| @@ -346,11 +369,11 @@ struct intel_link_m_n { · 179 unmodified lines | ||
| 346 | 369 | |
| 347 | 370 | #define for_each_power_domain_well(__dev_priv, __power_well, __domain_mask) \ |
| 348 | 371 | for_each_power_well(__dev_priv, __power_well) \ |
| 349 | − for_each_if((__power_well)->domains & (__domain_mask)) | |
| 372 | + for_each_if((__power_well)->desc->domains & (__domain_mask)) | |
| 350 | 373 | |
| 351 | 374 | #define for_each_power_domain_well_rev(__dev_priv, __power_well, __domain_mask) \ |
| 352 | 375 | for_each_power_well_rev(__dev_priv, __power_well) \ |
| 353 | − for_each_if((__power_well)->domains & (__domain_mask)) | |
| 376 | + for_each_if((__power_well)->desc->domains & (__domain_mask)) | |
| 354 | 377 | |
| 355 | 378 | #define for_each_new_intel_plane_in_state(__state, plane, new_plane_state, __i) \ |
| 356 | 379 | for ((__i) = 0; \ |
| @@ -382,4 +405,5 @@ void intel_link_compute_m_n(int bpp, int nlanes, · 25 unmodified lines | ||
| 382 | 405 | struct intel_link_m_n *m_n, |
| 383 | 406 | bool reduce_m_n); |
| 384 | 407 | |
| 408 | +bool is_ccs_modifier(u64 modifier); | |
| 385 | 409 | #endif |
| @@ -107,13 +107,6 @@ bool intel_dp_is_edp(struct intel_dp *intel_dp) · 106 unmodified lines | ||
| 107 | 107 | return intel_dig_port->base.type == INTEL_OUTPUT_EDP; |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | −static struct drm_device *intel_dp_to_dev(struct intel_dp *intel_dp) | |
| 111 | −{ | |
| 112 | − struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | |
| 113 | − | |
| 114 | − return intel_dig_port->base.base.dev; | |
| 115 | −} | |
| 116 | − | |
| 117 | 110 | static struct intel_dp *intel_attached_dp(struct drm_connector *connector) |
| 118 | 111 | { |
| 119 | 112 | return enc_to_intel_dp(&intel_attached_encoder(connector)->base); |
| @@ -176,14 +169,45 @@ static int intel_dp_max_common_rate(struct intel_dp *intel_dp) · 56 unmodified lines | ||
| 176 | 169 | return intel_dp->common_rates[intel_dp->num_common_rates - 1]; |
| 177 | 170 | } |
| 178 | 171 | |
| 172 | +static int intel_dp_get_fia_supported_lane_count(struct intel_dp *intel_dp) | |
| 173 | +{ | |
| 174 | + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | |
| 175 | + struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); | |
| 176 | + enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port); | |
| 177 | + u32 lane_info; | |
| 178 | + | |
| 179 | + if (tc_port == PORT_TC_NONE || dig_port->tc_type != TC_PORT_TYPEC) | |
| 180 | + return 4; | |
| 181 | + | |
| 182 | + lane_info = (I915_READ(PORT_TX_DFLEXDPSP) & | |
| 183 | + DP_LANE_ASSIGNMENT_MASK(tc_port)) >> | |
| 184 | + DP_LANE_ASSIGNMENT_SHIFT(tc_port); | |
| 185 | + | |
| 186 | + switch (lane_info) { | |
| 187 | + default: | |
| 188 | + MISSING_CASE(lane_info); | |
| 189 | + case 1: | |
| 190 | + case 2: | |
| 191 | + case 4: | |
| 192 | + case 8: | |
| 193 | + return 1; | |
| 194 | + case 3: | |
| 195 | + case 12: | |
| 196 | + return 2; | |
| 197 | + case 15: | |
| 198 | + return 4; | |
| 199 | + } | |
| 200 | +} | |
| 201 | + | |
| 179 | 202 | /* Theoretical max between source and sink */ |
| 180 | 203 | static int intel_dp_max_common_lane_count(struct intel_dp *intel_dp) |
| 181 | 204 | { |
| 182 | 205 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
| 183 | 206 | int source_max = intel_dig_port->max_lanes; |
| 184 | 207 | int sink_max = drm_dp_max_lane_count(intel_dp->dpcd); |
| 208 | + int fia_max = intel_dp_get_fia_supported_lane_count(intel_dp); | |
| 185 | 209 | |
| 186 | − return min(source_max, sink_max); | |
| 210 | + return min3(source_max, sink_max, fia_max); | |
| 187 | 211 | } |
| 188 | 212 | |
| 189 | 213 | int intel_dp_max_lane_count(struct intel_dp *intel_dp) |
| @@ -198,6 +222,138 @@ intel_dp_link_required(int pixel_clock, int bpp) · 8 unmodified lines | ||
| 198 | 222 | return DIV_ROUND_UP(pixel_clock * bpp, 8); |
| 199 | 223 | } |
| 200 | 224 | |
| 225 | +void icl_program_mg_dp_mode(struct intel_dp *intel_dp) | |
| 226 | +{ | |
| 227 | + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | |
| 228 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 229 | + enum port port = intel_dig_port->base.port; | |
| 230 | + enum tc_port tc_port = intel_port_to_tc(dev_priv, port); | |
| 231 | + u32 ln0, ln1, lane_info; | |
| 232 | + | |
| 233 | + if (tc_port == PORT_TC_NONE || intel_dig_port->tc_type == TC_PORT_TBT) | |
| 234 | + return; | |
| 235 | + | |
| 236 | + ln0 = I915_READ(MG_DP_MODE(port, 0)); | |
| 237 | + ln1 = I915_READ(MG_DP_MODE(port, 1)); | |
| 238 | + | |
| 239 | + switch (intel_dig_port->tc_type) { | |
| 240 | + case TC_PORT_TYPEC: | |
| 241 | + ln0 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE); | |
| 242 | + ln1 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE); | |
| 243 | + | |
| 244 | + lane_info = (I915_READ(PORT_TX_DFLEXDPSP) & | |
| 245 | + DP_LANE_ASSIGNMENT_MASK(tc_port)) >> | |
| 246 | + DP_LANE_ASSIGNMENT_SHIFT(tc_port); | |
| 247 | + | |
| 248 | + switch (lane_info) { | |
| 249 | + case 0x1: | |
| 250 | + case 0x4: | |
| 251 | + break; | |
| 252 | + case 0x2: | |
| 253 | + ln0 |= MG_DP_MODE_CFG_DP_X1_MODE; | |
| 254 | + break; | |
| 255 | + case 0x3: | |
| 256 | + ln0 |= MG_DP_MODE_CFG_DP_X1_MODE | | |
| 257 | + MG_DP_MODE_CFG_DP_X2_MODE; | |
| 258 | + break; | |
| 259 | + case 0x8: | |
| 260 | + ln1 |= MG_DP_MODE_CFG_DP_X1_MODE; | |
| 261 | + break; | |
| 262 | + case 0xC: | |
| 263 | + ln1 |= MG_DP_MODE_CFG_DP_X1_MODE | | |
| 264 | + MG_DP_MODE_CFG_DP_X2_MODE; | |
| 265 | + break; | |
| 266 | + case 0xF: | |
| 267 | + ln0 |= MG_DP_MODE_CFG_DP_X1_MODE | | |
| 268 | + MG_DP_MODE_CFG_DP_X2_MODE; | |
| 269 | + ln1 |= MG_DP_MODE_CFG_DP_X1_MODE | | |
| 270 | + MG_DP_MODE_CFG_DP_X2_MODE; | |
| 271 | + break; | |
| 272 | + default: | |
| 273 | + MISSING_CASE(lane_info); | |
| 274 | + } | |
| 275 | + break; | |
| 276 | + | |
| 277 | + case TC_PORT_LEGACY: | |
| 278 | + ln0 |= MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE; | |
| 279 | + ln1 |= MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE; | |
| 280 | + break; | |
| 281 | + | |
| 282 | + default: | |
| 283 | + MISSING_CASE(intel_dig_port->tc_type); | |
| 284 | + return; | |
| 285 | + } | |
| 286 | + | |
| 287 | + I915_WRITE(MG_DP_MODE(port, 0), ln0); | |
| 288 | + I915_WRITE(MG_DP_MODE(port, 1), ln1); | |
| 289 | +} | |
| 290 | + | |
| 291 | +void icl_enable_phy_clock_gating(struct intel_digital_port *dig_port) | |
| 292 | +{ | |
| 293 | + struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); | |
| 294 | + enum port port = dig_port->base.port; | |
| 295 | + enum tc_port tc_port = intel_port_to_tc(dev_priv, port); | |
| 296 | + i915_reg_t mg_regs[2] = { MG_DP_MODE(port, 0), MG_DP_MODE(port, 1) }; | |
| 297 | + u32 val; | |
| 298 | + int i; | |
| 299 | + | |
| 300 | + if (tc_port == PORT_TC_NONE) | |
| 301 | + return; | |
| 302 | + | |
| 303 | + for (i = 0; i < ARRAY_SIZE(mg_regs); i++) { | |
| 304 | + val = I915_READ(mg_regs[i]); | |
| 305 | + val |= MG_DP_MODE_CFG_TR2PWR_GATING | | |
| 306 | + MG_DP_MODE_CFG_TRPWR_GATING | | |
| 307 | + MG_DP_MODE_CFG_CLNPWR_GATING | | |
| 308 | + MG_DP_MODE_CFG_DIGPWR_GATING | | |
| 309 | + MG_DP_MODE_CFG_GAONPWR_GATING; | |
| 310 | + I915_WRITE(mg_regs[i], val); | |
| 311 | + } | |
| 312 | + | |
| 313 | + val = I915_READ(MG_MISC_SUS0(tc_port)); | |
| 314 | + val |= MG_MISC_SUS0_SUSCLK_DYNCLKGATE_MODE(3) | | |
| 315 | + MG_MISC_SUS0_CFG_TR2PWR_GATING | | |
| 316 | + MG_MISC_SUS0_CFG_CL2PWR_GATING | | |
| 317 | + MG_MISC_SUS0_CFG_GAONPWR_GATING | | |
| 318 | + MG_MISC_SUS0_CFG_TRPWR_GATING | | |
| 319 | + MG_MISC_SUS0_CFG_CL1PWR_GATING | | |
| 320 | + MG_MISC_SUS0_CFG_DGPWR_GATING; | |
| 321 | + I915_WRITE(MG_MISC_SUS0(tc_port), val); | |
| 322 | +} | |
| 323 | + | |
| 324 | +void icl_disable_phy_clock_gating(struct intel_digital_port *dig_port) | |
| 325 | +{ | |
| 326 | + struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); | |
| 327 | + enum port port = dig_port->base.port; | |
| 328 | + enum tc_port tc_port = intel_port_to_tc(dev_priv, port); | |
| 329 | + i915_reg_t mg_regs[2] = { MG_DP_MODE(port, 0), MG_DP_MODE(port, 1) }; | |
| 330 | + u32 val; | |
| 331 | + int i; | |
| 332 | + | |
| 333 | + if (tc_port == PORT_TC_NONE) | |
| 334 | + return; | |
| 335 | + | |
| 336 | + for (i = 0; i < ARRAY_SIZE(mg_regs); i++) { | |
| 337 | + val = I915_READ(mg_regs[i]); | |
| 338 | + val &= ~(MG_DP_MODE_CFG_TR2PWR_GATING | | |
| 339 | + MG_DP_MODE_CFG_TRPWR_GATING | | |
| 340 | + MG_DP_MODE_CFG_CLNPWR_GATING | | |
| 341 | + MG_DP_MODE_CFG_DIGPWR_GATING | | |
| 342 | + MG_DP_MODE_CFG_GAONPWR_GATING); | |
| 343 | + I915_WRITE(mg_regs[i], val); | |
| 344 | + } | |
| 345 | + | |
| 346 | + val = I915_READ(MG_MISC_SUS0(tc_port)); | |
| 347 | + val &= ~(MG_MISC_SUS0_SUSCLK_DYNCLKGATE_MODE_MASK | | |
| 348 | + MG_MISC_SUS0_CFG_TR2PWR_GATING | | |
| 349 | + MG_MISC_SUS0_CFG_CL2PWR_GATING | | |
| 350 | + MG_MISC_SUS0_CFG_GAONPWR_GATING | | |
| 351 | + MG_MISC_SUS0_CFG_TRPWR_GATING | | |
| 352 | + MG_MISC_SUS0_CFG_CL1PWR_GATING | | |
| 353 | + MG_MISC_SUS0_CFG_DGPWR_GATING); | |
| 354 | + I915_WRITE(MG_MISC_SUS0(tc_port), val); | |
| 355 | +} | |
| 356 | + | |
| 201 | 357 | int |
| 202 | 358 | intel_dp_max_data_rate(int max_link_clock, int max_lanes) |
| 203 | 359 | { |
| @@ -498,7 +654,7 @@ intel_dp_pps_init(struct intel_dp *intel_dp); · 294 unmodified lines | ||
| 498 | 654 | |
| 499 | 655 | static void pps_lock(struct intel_dp *intel_dp) |
| 500 | 656 | { |
| 501 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 657 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 502 | 658 | |
| 503 | 659 | /* |
| 504 | 660 | * See intel_power_sequencer_reset() why we need |
| @@ -511,7 +667,7 @@ static void pps_lock(struct intel_dp *intel_dp) · 6 unmodified lines | ||
| 511 | 667 | |
| 512 | 668 | static void pps_unlock(struct intel_dp *intel_dp) |
| 513 | 669 | { |
| 514 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 670 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 515 | 671 | |
| 516 | 672 | mutex_unlock(&dev_priv->pps_mutex); |
| 517 | 673 | |
| @@ -521,7 +677,7 @@ static void pps_unlock(struct intel_dp *intel_dp) · 3 unmodified lines | ||
| 521 | 677 | static void |
| 522 | 678 | vlv_power_sequencer_kick(struct intel_dp *intel_dp) |
| 523 | 679 | { |
| 524 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 680 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 525 | 681 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
| 526 | 682 | enum pipe pipe = intel_dp->pps_pipe; |
| 527 | 683 | bool pll_enabled, release_cl_override = false; |
| @@ -626,7 +782,7 @@ static enum pipe vlv_find_free_pps(struct drm_i915_private *dev_priv) · 98 unmodified lines | ||
| 626 | 782 | static enum pipe |
| 627 | 783 | vlv_power_sequencer_pipe(struct intel_dp *intel_dp) |
| 628 | 784 | { |
| 629 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 785 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 630 | 786 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
| 631 | 787 | enum pipe pipe; |
| 632 | 788 | |
| @@ -673,7 +829,7 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp) · 40 unmodified lines | ||
| 673 | 829 | static int |
| 674 | 830 | bxt_power_sequencer_idx(struct intel_dp *intel_dp) |
| 675 | 831 | { |
| 676 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 832 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 677 | 833 | int backlight_controller = dev_priv->vbt.backlight.controller; |
| 678 | 834 | |
| 679 | 835 | lockdep_assert_held(&dev_priv->pps_mutex); |
| @@ -742,7 +898,7 @@ vlv_initial_pps_pipe(struct drm_i915_private *dev_priv, · 62 unmodified lines | ||
| 742 | 898 | static void |
| 743 | 899 | vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp) |
| 744 | 900 | { |
| 745 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 901 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 746 | 902 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
| 747 | 903 | enum port port = intel_dig_port->base.port; |
| 748 | 904 | |
| @@ -819,7 +975,7 @@ struct pps_registers { · 70 unmodified lines | ||
| 819 | 975 | static void intel_pps_get_registers(struct intel_dp *intel_dp, |
| 820 | 976 | struct pps_registers *regs) |
| 821 | 977 | { |
| 822 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 978 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 823 | 979 | int pps_idx = 0; |
| 824 | 980 | |
| 825 | 981 | memset(regs, 0, sizeof(*regs)); |
| @@ -865,7 +1021,7 @@ static int edp_notify_handler(struct notifier_block *this, unsigned long code, · 39 unmodified lines | ||
| 865 | 1021 | { |
| 866 | 1022 | struct intel_dp *intel_dp = container_of(this, typeof(* intel_dp), |
| 867 | 1023 | edp_notifier); |
| 868 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 1024 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 869 | 1025 | |
| 870 | 1026 | if (!intel_dp_is_edp(intel_dp) || code != SYS_RESTART) |
| 871 | 1027 | return 0; |
| @@ -895,7 +1051,7 @@ static int edp_notify_handler(struct notifier_block *this, unsigned long code, · 23 unmodified lines | ||
| 895 | 1051 | |
| 896 | 1052 | static bool edp_have_panel_power(struct intel_dp *intel_dp) |
| 897 | 1053 | { |
| 898 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 1054 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 899 | 1055 | |
| 900 | 1056 | lockdep_assert_held(&dev_priv->pps_mutex); |
| 901 | 1057 | |
| @@ -908,7 +1064,7 @@ static bool edp_have_panel_power(struct intel_dp *intel_dp) · 6 unmodified lines | ||
| 908 | 1064 | |
| 909 | 1065 | static bool edp_have_panel_vdd(struct intel_dp *intel_dp) |
| 910 | 1066 | { |
| 911 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 1067 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 912 | 1068 | |
| 913 | 1069 | lockdep_assert_held(&dev_priv->pps_mutex); |
| 914 | 1070 | |
| @@ -922,7 +1078,7 @@ static bool edp_have_panel_vdd(struct intel_dp *intel_dp) · 7 unmodified lines | ||
| 922 | 1078 | static void |
| 923 | 1079 | intel_dp_check_edp(struct intel_dp *intel_dp) |
| 924 | 1080 | { |
| 925 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 1081 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 926 | 1082 | |
| 927 | 1083 | if (!intel_dp_is_edp(intel_dp)) |
| 928 | 1084 | return; |
| @@ -938,7 +1094,7 @@ intel_dp_check_edp(struct intel_dp *intel_dp) · 9 unmodified lines | ||
| 938 | 1094 | static uint32_t |
| 939 | 1095 | intel_dp_aux_wait_done(struct intel_dp *intel_dp) |
| 940 | 1096 | { |
| 941 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 1097 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 942 | 1098 | i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg(intel_dp); |
| 943 | 1099 | uint32_t status; |
| 944 | 1100 | bool done; |
| @@ -955,7 +1111,7 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp) · 10 unmodified lines | ||
| 955 | 1111 | |
| 956 | 1112 | static uint32_t g4x_get_aux_clock_divider(struct intel_dp *intel_dp, int index) |
| 957 | 1113 | { |
| 958 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 1114 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 959 | 1115 | |
| 960 | 1116 | if (index) |
| 961 | 1117 | return 0; |
| @@ -969,7 +1125,7 @@ static uint32_t g4x_get_aux_clock_divider(struct intel_dp *intel_dp, int index) · 7 unmodified lines | ||
| 969 | 1125 | |
| 970 | 1126 | static uint32_t ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index) |
| 971 | 1127 | { |
| 972 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 1128 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 973 | 1129 | |
| 974 | 1130 | if (index) |
| 975 | 1131 | return 0; |
| @@ -987,7 +1143,7 @@ static uint32_t ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index) · 11 unmodified lines | ||
| 987 | 1143 | |
| 988 | 1144 | static uint32_t hsw_get_aux_clock_divider(struct intel_dp *intel_dp, int index) |
| 989 | 1145 | { |
| 990 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 1146 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 991 | 1147 | |
| 992 | 1148 | if (intel_dp->aux_ch != AUX_CH_A && HAS_PCH_LPT_H(dev_priv)) { |
| 993 | 1149 | /* Workaround for non-ULT HSW */ |
| @@ -1045,15 +1201,23 @@ static uint32_t skl_get_aux_send_ctl(struct intel_dp *intel_dp, · 51 unmodified lines | ||
| 1045 | 1201 | int send_bytes, |
| 1046 | 1202 | uint32_t unused) |
| 1047 | 1203 | { |
| 1048 | − return DP_AUX_CH_CTL_SEND_BUSY | | |
| 1049 | − DP_AUX_CH_CTL_DONE | | |
| 1050 | − DP_AUX_CH_CTL_INTERRUPT | | |
| 1051 | − DP_AUX_CH_CTL_TIME_OUT_ERROR | | |
| 1052 | − DP_AUX_CH_CTL_TIME_OUT_MAX | | |
| 1053 | − DP_AUX_CH_CTL_RECEIVE_ERROR | | |
| 1054 | − (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | | |
| 1055 | − DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(32) | | |
| 1056 | − DP_AUX_CH_CTL_SYNC_PULSE_SKL(32); | |
| 1204 | + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | |
| 1205 | + uint32_t ret; | |
| 1206 | + | |
| 1207 | + ret = DP_AUX_CH_CTL_SEND_BUSY | | |
| 1208 | + DP_AUX_CH_CTL_DONE | | |
| 1209 | + DP_AUX_CH_CTL_INTERRUPT | | |
| 1210 | + DP_AUX_CH_CTL_TIME_OUT_ERROR | | |
| 1211 | + DP_AUX_CH_CTL_TIME_OUT_MAX | | |
| 1212 | + DP_AUX_CH_CTL_RECEIVE_ERROR | | |
| 1213 | + (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | | |
| 1214 | + DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(32) | | |
| 1215 | + DP_AUX_CH_CTL_SYNC_PULSE_SKL(32); | |
| 1216 | + | |
| 1217 | + if (intel_dig_port->tc_type == TC_PORT_TBT) | |
| 1218 | + ret |= DP_AUX_CH_CTL_TBT_IO; | |
| 1219 | + | |
| 1220 | + return ret; | |
| 1057 | 1221 | } |
| 1058 | 1222 | |
| 1059 | 1223 | static int |
| @@ -1381,7 +1545,7 @@ intel_aux_power_domain(struct intel_dp *intel_dp) · 321 unmodified lines | ||
| 1381 | 1545 | |
| 1382 | 1546 | static i915_reg_t g4x_aux_ctl_reg(struct intel_dp *intel_dp) |
| 1383 | 1547 | { |
| 1384 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 1548 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 1385 | 1549 | enum aux_ch aux_ch = intel_dp->aux_ch; |
| 1386 | 1550 | |
| 1387 | 1551 | switch (aux_ch) { |
| @@ -1397,7 +1561,7 @@ static i915_reg_t g4x_aux_ctl_reg(struct intel_dp *intel_dp) · 9 unmodified lines | ||
| 1397 | 1561 | |
| 1398 | 1562 | static i915_reg_t g4x_aux_data_reg(struct intel_dp *intel_dp, int index) |
| 1399 | 1563 | { |
| 1400 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 1564 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 1401 | 1565 | enum aux_ch aux_ch = intel_dp->aux_ch; |
| 1402 | 1566 | |
| 1403 | 1567 | switch (aux_ch) { |
| @@ -1413,7 +1577,7 @@ static i915_reg_t g4x_aux_data_reg(struct intel_dp *intel_dp, int index) · 9 unmodified lines | ||
| 1413 | 1577 | |
| 1414 | 1578 | static i915_reg_t ilk_aux_ctl_reg(struct intel_dp *intel_dp) |
| 1415 | 1579 | { |
| 1416 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 1580 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 1417 | 1581 | enum aux_ch aux_ch = intel_dp->aux_ch; |
| 1418 | 1582 | |
| 1419 | 1583 | switch (aux_ch) { |
| @@ -1431,7 +1595,7 @@ static i915_reg_t ilk_aux_ctl_reg(struct intel_dp *intel_dp) · 11 unmodified lines | ||
| 1431 | 1595 | |
| 1432 | 1596 | static i915_reg_t ilk_aux_data_reg(struct intel_dp *intel_dp, int index) |
| 1433 | 1597 | { |
| 1434 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 1598 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 1435 | 1599 | enum aux_ch aux_ch = intel_dp->aux_ch; |
| 1436 | 1600 | |
| 1437 | 1601 | switch (aux_ch) { |
| @@ -1449,7 +1613,7 @@ static i915_reg_t ilk_aux_data_reg(struct intel_dp *intel_dp, int index) · 11 unmodified lines | ||
| 1449 | 1613 | |
| 1450 | 1614 | static i915_reg_t skl_aux_ctl_reg(struct intel_dp *intel_dp) |
| 1451 | 1615 | { |
| 1452 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 1616 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 1453 | 1617 | enum aux_ch aux_ch = intel_dp->aux_ch; |
| 1454 | 1618 | |
| 1455 | 1619 | switch (aux_ch) { |
| @@ -1468,7 +1632,7 @@ static i915_reg_t skl_aux_ctl_reg(struct intel_dp *intel_dp) · 12 unmodified lines | ||
| 1468 | 1632 | |
| 1469 | 1633 | static i915_reg_t skl_aux_data_reg(struct intel_dp *intel_dp, int index) |
| 1470 | 1634 | { |
| 1471 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 1635 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 1472 | 1636 | enum aux_ch aux_ch = intel_dp->aux_ch; |
| 1473 | 1637 | |
| 1474 | 1638 | switch (aux_ch) { |
| @@ -1494,7 +1658,7 @@ intel_dp_aux_fini(struct intel_dp *intel_dp) · 19 unmodified lines | ||
| 1494 | 1658 | static void |
| 1495 | 1659 | intel_dp_aux_init(struct intel_dp *intel_dp) |
| 1496 | 1660 | { |
| 1497 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 1661 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 1498 | 1662 | struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; |
| 1499 | 1663 | |
| 1500 | 1664 | intel_dp->aux_ch = intel_aux_ch(intel_dp); |
| @@ -1662,7 +1826,7 @@ struct link_config_limits { · 161 unmodified lines | ||
| 1662 | 1826 | static int intel_dp_compute_bpp(struct intel_dp *intel_dp, |
| 1663 | 1827 | struct intel_crtc_state *pipe_config) |
| 1664 | 1828 | { |
| 1665 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 1829 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 1666 | 1830 | struct intel_connector *intel_connector = intel_dp->attached_connector; |
| 1667 | 1831 | int bpp, bpc; |
| 1668 | 1832 | |
| @@ -2030,7 +2194,7 @@ static void wait_panel_status(struct intel_dp *intel_dp, · 361 unmodified lines | ||
| 2030 | 2194 | u32 mask, |
| 2031 | 2195 | u32 value) |
| 2032 | 2196 | { |
| 2033 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 2197 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 2034 | 2198 | i915_reg_t pp_stat_reg, pp_ctrl_reg; |
| 2035 | 2199 | |
| 2036 | 2200 | lockdep_assert_held(&dev_priv->pps_mutex); |
| @@ -2106,7 +2270,7 @@ static void edp_wait_backlight_off(struct intel_dp *intel_dp) · 69 unmodified lines | ||
| 2106 | 2270 | |
| 2107 | 2271 | static u32 ironlake_get_pp_control(struct intel_dp *intel_dp) |
| 2108 | 2272 | { |
| 2109 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 2273 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 2110 | 2274 | u32 control; |
| 2111 | 2275 | |
| 2112 | 2276 | lockdep_assert_held(&dev_priv->pps_mutex); |
| @@ -2127,7 +2291,7 @@ static u32 ironlake_get_pp_control(struct intel_dp *intel_dp) · 14 unmodified lines | ||
| 2127 | 2291 | */ |
| 2128 | 2292 | static bool edp_panel_vdd_on(struct intel_dp *intel_dp) |
| 2129 | 2293 | { |
| 2130 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 2294 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 2131 | 2295 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
| 2132 | 2296 | u32 pp; |
| 2133 | 2297 | i915_reg_t pp_stat_reg, pp_ctrl_reg; |
| @@ -2198,7 +2362,7 @@ void intel_edp_panel_vdd_on(struct intel_dp *intel_dp) · 64 unmodified lines | ||
| 2198 | 2362 | |
| 2199 | 2363 | static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp) |
| 2200 | 2364 | { |
| 2201 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 2365 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 2202 | 2366 | struct intel_digital_port *intel_dig_port = |
| 2203 | 2367 | dp_to_dig_port(intel_dp); |
| 2204 | 2368 | u32 pp; |
| @@ -2264,7 +2428,7 @@ static void edp_panel_vdd_schedule_off(struct intel_dp *intel_dp) · 59 unmodified lines | ||
| 2264 | 2428 | */ |
| 2265 | 2429 | static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) |
| 2266 | 2430 | { |
| 2267 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 2431 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 2268 | 2432 | |
| 2269 | 2433 | lockdep_assert_held(&dev_priv->pps_mutex); |
| 2270 | 2434 | |
| @@ -2284,7 +2448,7 @@ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) · 13 unmodified lines | ||
| 2284 | 2448 | |
| 2285 | 2449 | static void edp_panel_on(struct intel_dp *intel_dp) |
| 2286 | 2450 | { |
| 2287 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 2451 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 2288 | 2452 | u32 pp; |
| 2289 | 2453 | i915_reg_t pp_ctrl_reg; |
| 2290 | 2454 | |
| @@ -2342,7 +2506,7 @@ void intel_edp_panel_on(struct intel_dp *intel_dp) · 51 unmodified lines | ||
| 2342 | 2506 | |
| 2343 | 2507 | static void edp_panel_off(struct intel_dp *intel_dp) |
| 2344 | 2508 | { |
| 2345 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 2509 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 2346 | 2510 | u32 pp; |
| 2347 | 2511 | i915_reg_t pp_ctrl_reg; |
| 2348 | 2512 | |
| @@ -2390,7 +2554,7 @@ void intel_edp_panel_off(struct intel_dp *intel_dp) · 41 unmodified lines | ||
| 2390 | 2554 | /* Enable backlight in the panel power control. */ |
| 2391 | 2555 | static void _intel_edp_backlight_on(struct intel_dp *intel_dp) |
| 2392 | 2556 | { |
| 2393 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 2557 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 2394 | 2558 | u32 pp; |
| 2395 | 2559 | i915_reg_t pp_ctrl_reg; |
| 2396 | 2560 | |
| @@ -2433,7 +2597,7 @@ void intel_edp_backlight_on(const struct intel_crtc_state *crtc_state, · 36 unmodified lines | ||
| 2433 | 2597 | /* Disable backlight in the panel power control. */ |
| 2434 | 2598 | static void _intel_edp_backlight_off(struct intel_dp *intel_dp) |
| 2435 | 2599 | { |
| 2436 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 2600 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 2437 | 2601 | u32 pp; |
| 2438 | 2602 | i915_reg_t pp_ctrl_reg; |
| 2439 | 2603 | |
| @@ -2864,7 +3028,7 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp, · 424 unmodified lines | ||
| 2864 | 3028 | uint32_t *DP, |
| 2865 | 3029 | uint8_t dp_train_pat) |
| 2866 | 3030 | { |
| 2867 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 3031 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 2868 | 3032 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
| 2869 | 3033 | enum port port = intel_dig_port->base.port; |
| 2870 | 3034 | uint8_t train_pat_mask = drm_dp_training_pattern_mask(intel_dp->dpcd); |
| @@ -2946,7 +3110,7 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp, · 75 unmodified lines | ||
| 2946 | 3110 | static void intel_dp_enable_port(struct intel_dp *intel_dp, |
| 2947 | 3111 | const struct intel_crtc_state *old_crtc_state) |
| 2948 | 3112 | { |
| 2949 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 3113 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 2950 | 3114 | |
| 2951 | 3115 | /* enable with pattern 1 (as per spec) */ |
| 2952 | 3116 | |
| @@ -3203,7 +3367,7 @@ intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_ · 250 unmodified lines | ||
| 3203 | 3367 | uint8_t |
| 3204 | 3368 | intel_dp_voltage_max(struct intel_dp *intel_dp) |
| 3205 | 3369 | { |
| 3206 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 3370 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 3207 | 3371 | struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; |
| 3208 | 3372 | enum port port = encoder->port; |
| 3209 | 3373 | |
| @@ -3222,7 +3386,7 @@ intel_dp_voltage_max(struct intel_dp *intel_dp) · 12 unmodified lines | ||
| 3222 | 3386 | uint8_t |
| 3223 | 3387 | intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing) |
| 3224 | 3388 | { |
| 3225 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 3389 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 3226 | 3390 | struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; |
| 3227 | 3391 | enum port port = encoder->port; |
| 3228 | 3392 | |
| @@ -3534,7 +3698,7 @@ ivb_cpu_edp_signal_levels(uint8_t train_set) · 305 unmodified lines | ||
| 3534 | 3698 | void |
| 3535 | 3699 | intel_dp_set_signal_levels(struct intel_dp *intel_dp) |
| 3536 | 3700 | { |
| 3537 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 3701 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 3538 | 3702 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
| 3539 | 3703 | enum port port = intel_dig_port->base.port; |
| 3540 | 3704 | uint32_t signal_levels, mask = 0; |
| @@ -3591,7 +3755,7 @@ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, · 50 unmodified lines | ||
| 3591 | 3755 | |
| 3592 | 3756 | void intel_dp_set_idle_link_train(struct intel_dp *intel_dp) |
| 3593 | 3757 | { |
| 3594 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 3758 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 3595 | 3759 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
| 3596 | 3760 | enum port port = intel_dig_port->base.port; |
| 3597 | 3761 | uint32_t val; |
| @@ -4090,12 +4254,14 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) · 492 unmodified lines | ||
| 4090 | 4254 | int ret = 0; |
| 4091 | 4255 | int retry; |
| 4092 | 4256 | bool handled; |
| 4257 | + | |
| 4258 | + WARN_ON_ONCE(intel_dp->active_mst_links < 0); | |
| 4093 | 4259 | bret = intel_dp_get_sink_irq_esi(intel_dp, esi); |
| 4094 | 4260 | go_again: |
| 4095 | 4261 | if (bret == true) { |
| 4096 | 4262 | |
| 4097 | 4263 | /* check link status - esi[10] = 0x200c */ |
| 4098 | − if (intel_dp->active_mst_links && | |
| 4264 | + if (intel_dp->active_mst_links > 0 && | |
| 4099 | 4265 | !drm_dp_channel_eq_ok(&esi[10], intel_dp->lane_count)) { |
| 4100 | 4266 | DRM_DEBUG_KMS("channel EQ not ok, retraining\n"); |
| 4101 | 4267 | intel_dp_start_link_train(intel_dp); |
| @@ -4160,18 +4326,6 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp) · 58 unmodified lines | ||
| 4160 | 4326 | return !drm_dp_channel_eq_ok(link_status, intel_dp->lane_count); |
| 4161 | 4327 | } |
| 4162 | 4328 | |
| 4163 | −/* | |
| 4164 | − * If display is now connected check links status, | |
| 4165 | − * there has been known issues of link loss triggering | |
| 4166 | − * long pulse. | |
| 4167 | − * | |
| 4168 | − * Some sinks (eg. ASUS PB287Q) seem to perform some | |
| 4169 | − * weird HPD ping pong during modesets. So we can apparently | |
| 4170 | − * end up with HPD going low during a modeset, and then | |
| 4171 | − * going back up soon after. And once that happens we must | |
| 4172 | − * retrain the link to get a picture. That's in case no | |
| 4173 | − * userspace component reacted to intermittent HPD dip. | |
| 4174 | − */ | |
| 4175 | 4329 | int intel_dp_retrain_link(struct intel_encoder *encoder, |
| 4176 | 4330 | struct drm_modeset_acquire_ctx *ctx) |
| 4177 | 4331 | { |
| @@ -4294,7 +4448,7 @@ static bool intel_dp_hotplug(struct intel_encoder *encoder, · 116 unmodified lines | ||
| 4294 | 4448 | static bool |
| 4295 | 4449 | intel_dp_short_pulse(struct intel_dp *intel_dp) |
| 4296 | 4450 | { |
| 4297 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 4451 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 4298 | 4452 | u8 sink_irq_vector = 0; |
| 4299 | 4453 | u8 old_sink_count = intel_dp->sink_count; |
| 4300 | 4454 | bool ret; |
| @@ -4586,10 +4740,205 @@ static bool bxt_digital_port_connected(struct intel_encoder *encoder) · 285 unmodified lines | ||
| 4586 | 4740 | return I915_READ(GEN8_DE_PORT_ISR) & bit; |
| 4587 | 4741 | } |
| 4588 | 4742 | |
| 4743 | +static bool icl_combo_port_connected(struct drm_i915_private *dev_priv, | |
| 4744 | + struct intel_digital_port *intel_dig_port) | |
| 4745 | +{ | |
| 4746 | + enum port port = intel_dig_port->base.port; | |
| 4747 | + | |
| 4748 | + return I915_READ(SDEISR) & SDE_DDI_HOTPLUG_ICP(port); | |
| 4749 | +} | |
| 4750 | + | |
| 4751 | +static void icl_update_tc_port_type(struct drm_i915_private *dev_priv, | |
| 4752 | + struct intel_digital_port *intel_dig_port, | |
| 4753 | + bool is_legacy, bool is_typec, bool is_tbt) | |
| 4754 | +{ | |
| 4755 | + enum port port = intel_dig_port->base.port; | |
| 4756 | + enum tc_port_type old_type = intel_dig_port->tc_type; | |
| 4757 | + const char *type_str; | |
| 4758 | + | |
| 4759 | + WARN_ON(is_legacy + is_typec + is_tbt != 1); | |
| 4760 | + | |
| 4761 | + if (is_legacy) { | |
| 4762 | + intel_dig_port->tc_type = TC_PORT_LEGACY; | |
| 4763 | + type_str = "legacy"; | |
| 4764 | + } else if (is_typec) { | |
| 4765 | + intel_dig_port->tc_type = TC_PORT_TYPEC; | |
| 4766 | + type_str = "typec"; | |
| 4767 | + } else if (is_tbt) { | |
| 4768 | + intel_dig_port->tc_type = TC_PORT_TBT; | |
| 4769 | + type_str = "tbt"; | |
| 4770 | + } else { | |
| 4771 | + return; | |
| 4772 | + } | |
| 4773 | + | |
| 4774 | + /* Types are not supposed to be changed at runtime. */ | |
| 4775 | + WARN_ON(old_type != TC_PORT_UNKNOWN && | |
| 4776 | + old_type != intel_dig_port->tc_type); | |
| 4777 | + | |
| 4778 | + if (old_type != intel_dig_port->tc_type) | |
| 4779 | + DRM_DEBUG_KMS("Port %c has TC type %s\n", port_name(port), | |
| 4780 | + type_str); | |
| 4781 | +} | |
| 4782 | + | |
| 4783 | +/* | |
| 4784 | + * This function implements the first part of the Connect Flow described by our | |
| 4785 | + * specification, Gen11 TypeC Programming chapter. The rest of the flow (reading | |
| 4786 | + * lanes, EDID, etc) is done as needed in the typical places. | |
| 4787 | + * | |
| 4788 | + * Unlike the other ports, type-C ports are not available to use as soon as we | |
| 4789 | + * get a hotplug. The type-C PHYs can be shared between multiple controllers: | |
| 4790 | + * display, USB, etc. As a result, handshaking through FIA is required around | |
| 4791 | + * connect and disconnect to cleanly transfer ownership with the controller and | |
| 4792 | + * set the type-C power state. | |
| 4793 | + * | |
| 4794 | + * We could opt to only do the connect flow when we actually try to use the AUX | |
| 4795 | + * channels or do a modeset, then immediately run the disconnect flow after | |
| 4796 | + * usage, but there are some implications on this for a dynamic environment: | |
| 4797 | + * things may go away or change behind our backs. So for now our driver is | |
| 4798 | + * always trying to acquire ownership of the controller as soon as it gets an | |
| 4799 | + * interrupt (or polls state and sees a port is connected) and only gives it | |
| 4800 | + * back when it sees a disconnect. Implementation of a more fine-grained model | |
| 4801 | + * will require a lot of coordination with user space and thorough testing for | |
| 4802 | + * the extra possible cases. | |
| 4803 | + */ | |
| 4804 | +static bool icl_tc_phy_connect(struct drm_i915_private *dev_priv, | |
| 4805 | + struct intel_digital_port *dig_port) | |
| 4806 | +{ | |
| 4807 | + enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port); | |
| 4808 | + u32 val; | |
| 4809 | + | |
| 4810 | + if (dig_port->tc_type != TC_PORT_LEGACY && | |
| 4811 | + dig_port->tc_type != TC_PORT_TYPEC) | |
| 4812 | + return true; | |
| 4813 | + | |
| 4814 | + val = I915_READ(PORT_TX_DFLEXDPPMS); | |
| 4815 | + if (!(val & DP_PHY_MODE_STATUS_COMPLETED(tc_port))) { | |
| 4816 | + DRM_DEBUG_KMS("DP PHY for TC port %d not ready\n", tc_port); | |
| 4817 | + return false; | |
| 4818 | + } | |
| 4819 | + | |
| 4820 | + /* | |
| 4821 | + * This function may be called many times in a row without an HPD event | |
| 4822 | + * in between, so try to avoid the write when we can. | |
| 4823 | + */ | |
| 4824 | + val = I915_READ(PORT_TX_DFLEXDPCSSS); | |
| 4825 | + if (!(val & DP_PHY_MODE_STATUS_NOT_SAFE(tc_port))) { | |
| 4826 | + val |= DP_PHY_MODE_STATUS_NOT_SAFE(tc_port); | |
| 4827 | + I915_WRITE(PORT_TX_DFLEXDPCSSS, val); | |
| 4828 | + } | |
| 4829 | + | |
| 4830 | + /* | |
| 4831 | + * Now we have to re-check the live state, in case the port recently | |
| 4832 | + * became disconnected. Not necessary for legacy mode. | |
| 4833 | + */ | |
| 4834 | + if (dig_port->tc_type == TC_PORT_TYPEC && | |
| 4835 | + !(I915_READ(PORT_TX_DFLEXDPSP) & TC_LIVE_STATE_TC(tc_port))) { | |
| 4836 | + DRM_DEBUG_KMS("TC PHY %d sudden disconnect.\n", tc_port); | |
| 4837 | + val = I915_READ(PORT_TX_DFLEXDPCSSS); | |
| 4838 | + val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(tc_port); | |
| 4839 | + I915_WRITE(PORT_TX_DFLEXDPCSSS, val); | |
| 4840 | + return false; | |
| 4841 | + } | |
| 4842 | + | |
| 4843 | + return true; | |
| 4844 | +} | |
| 4845 | + | |
| 4846 | +/* | |
| 4847 | + * See the comment at the connect function. This implements the Disconnect | |
| 4848 | + * Flow. | |
| 4849 | + */ | |
| 4850 | +static void icl_tc_phy_disconnect(struct drm_i915_private *dev_priv, | |
| 4851 | + struct intel_digital_port *dig_port) | |
| 4852 | +{ | |
| 4853 | + enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port); | |
| 4854 | + u32 val; | |
| 4855 | + | |
| 4856 | + if (dig_port->tc_type != TC_PORT_LEGACY && | |
| 4857 | + dig_port->tc_type != TC_PORT_TYPEC) | |
| 4858 | + return; | |
| 4859 | + | |
| 4860 | + /* | |
| 4861 | + * This function may be called many times in a row without an HPD event | |
| 4862 | + * in between, so try to avoid the write when we can. | |
| 4863 | + */ | |
| 4864 | + val = I915_READ(PORT_TX_DFLEXDPCSSS); | |
| 4865 | + if (val & DP_PHY_MODE_STATUS_NOT_SAFE(tc_port)) { | |
| 4866 | + val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(tc_port); | |
| 4867 | + I915_WRITE(PORT_TX_DFLEXDPCSSS, val); | |
| 4868 | + } | |
| 4869 | +} | |
| 4870 | + | |
| 4871 | +/* | |
| 4872 | + * The type-C ports are different because even when they are connected, they may | |
| 4873 | + * not be available/usable by the graphics driver: see the comment on | |
| 4874 | + * icl_tc_phy_connect(). So in our driver instead of adding the additional | |
| 4875 | + * concept of "usable" and make everything check for "connected and usable" we | |
| 4876 | + * define a port as "connected" when it is not only connected, but also when it | |
| 4877 | + * is usable by the rest of the driver. That maintains the old assumption that | |
| 4878 | + * connected ports are usable, and avoids exposing to the users objects they | |
| 4879 | + * can't really use. | |
| 4880 | + */ | |
| 4881 | +static bool icl_tc_port_connected(struct drm_i915_private *dev_priv, | |
| 4882 | + struct intel_digital_port *intel_dig_port) | |
| 4883 | +{ | |
| 4884 | + enum port port = intel_dig_port->base.port; | |
| 4885 | + enum tc_port tc_port = intel_port_to_tc(dev_priv, port); | |
| 4886 | + bool is_legacy, is_typec, is_tbt; | |
| 4887 | + u32 dpsp; | |
| 4888 | + | |
| 4889 | + is_legacy = I915_READ(SDEISR) & SDE_TC_HOTPLUG_ICP(tc_port); | |
| 4890 | + | |
| 4891 | + /* | |
| 4892 | + * The spec says we shouldn't be using the ISR bits for detecting | |
| 4893 | + * between TC and TBT. We should use DFLEXDPSP. | |
| 4894 | + */ | |
| 4895 | + dpsp = I915_READ(PORT_TX_DFLEXDPSP); | |
| 4896 | + is_typec = dpsp & TC_LIVE_STATE_TC(tc_port); | |
| 4897 | + is_tbt = dpsp & TC_LIVE_STATE_TBT(tc_port); | |
| 4898 | + | |
| 4899 | + if (!is_legacy && !is_typec && !is_tbt) { | |
| 4900 | + icl_tc_phy_disconnect(dev_priv, intel_dig_port); | |
| 4901 | + return false; | |
| 4902 | + } | |
| 4903 | + | |
| 4904 | + icl_update_tc_port_type(dev_priv, intel_dig_port, is_legacy, is_typec, | |
| 4905 | + is_tbt); | |
| 4906 | + | |
| 4907 | + if (!icl_tc_phy_connect(dev_priv, intel_dig_port)) | |
| 4908 | + return false; | |
| 4909 | + | |
| 4910 | + return true; | |
| 4911 | +} | |
| 4912 | + | |
| 4913 | +static bool icl_digital_port_connected(struct intel_encoder *encoder) | |
| 4914 | +{ | |
| 4915 | + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | |
| 4916 | + struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); | |
| 4917 | + | |
| 4918 | + switch (encoder->hpd_pin) { | |
| 4919 | + case HPD_PORT_A: | |
| 4920 | + case HPD_PORT_B: | |
| 4921 | + return icl_combo_port_connected(dev_priv, dig_port); | |
| 4922 | + case HPD_PORT_C: | |
| 4923 | + case HPD_PORT_D: | |
| 4924 | + case HPD_PORT_E: | |
| 4925 | + case HPD_PORT_F: | |
| 4926 | + return icl_tc_port_connected(dev_priv, dig_port); | |
| 4927 | + default: | |
| 4928 | + MISSING_CASE(encoder->hpd_pin); | |
| 4929 | + return false; | |
| 4930 | + } | |
| 4931 | +} | |
| 4932 | + | |
| 4589 | 4933 | /* |
| 4590 | 4934 | * intel_digital_port_connected - is the specified port connected? |
| 4591 | 4935 | * @encoder: intel_encoder |
| 4592 | 4936 | * |
| 4937 | + * In cases where there's a connector physically connected but it can't be used | |
| 4938 | + * by our hardware we also return false, since the rest of the driver should | |
| 4939 | + * pretty much treat the port as disconnected. This is relevant for type-C | |
| 4940 | + * (starting on ICL) where there's ownership involved. | |
| 4941 | + * | |
| 4593 | 4942 | * Return %true if port is connected, %false otherwise. |
| 4594 | 4943 | */ |
| 4595 | 4944 | bool intel_digital_port_connected(struct intel_encoder *encoder) |
| @@ -4613,8 +4962,10 @@ bool intel_digital_port_connected(struct intel_encoder *encoder) · 17 unmodified lines | ||
| 4613 | 4962 | return bdw_digital_port_connected(encoder); |
| 4614 | 4963 | else if (IS_GEN9_LP(dev_priv)) |
| 4615 | 4964 | return bxt_digital_port_connected(encoder); |
| 4616 | − else | |
| 4965 | + else if (IS_GEN9_BC(dev_priv) || IS_GEN10(dev_priv)) | |
| 4617 | 4966 | return spt_digital_port_connected(encoder); |
| 4967 | + else | |
| 4968 | + return icl_digital_port_connected(encoder); | |
| 4618 | 4969 | } |
| 4619 | 4970 | |
| 4620 | 4971 | static struct edid * |
| @@ -4661,7 +5012,8 @@ intel_dp_unset_edid(struct intel_dp *intel_dp) · 40 unmodified lines | ||
| 4661 | 5012 | } |
| 4662 | 5013 | |
| 4663 | 5014 | static int |
| 4664 | −intel_dp_long_pulse(struct intel_connector *connector) | |
| 5015 | +intel_dp_long_pulse(struct intel_connector *connector, | |
| 5016 | + struct drm_modeset_acquire_ctx *ctx) | |
| 4665 | 5017 | { |
| 4666 | 5018 | struct drm_i915_private *dev_priv = to_i915(connector->base.dev); |
| 4667 | 5019 | struct intel_dp *intel_dp = intel_attached_dp(&connector->base); |
| @@ -4720,6 +5072,22 @@ intel_dp_long_pulse(struct intel_connector *connector) · 52 unmodified lines | ||
| 4720 | 5072 | */ |
| 4721 | 5073 | status = connector_status_disconnected; |
| 4722 | 5074 | goto out; |
| 5075 | + } else { | |
| 5076 | + /* | |
| 5077 | + * If display is now connected check links status, | |
| 5078 | + * there has been known issues of link loss triggering | |
| 5079 | + * long pulse. | |
| 5080 | + * | |
| 5081 | + * Some sinks (eg. ASUS PB287Q) seem to perform some | |
| 5082 | + * weird HPD ping pong during modesets. So we can apparently | |
| 5083 | + * end up with HPD going low during a modeset, and then | |
| 5084 | + * going back up soon after. And once that happens we must | |
| 5085 | + * retrain the link to get a picture. That's in case no | |
| 5086 | + * userspace component reacted to intermittent HPD dip. | |
| 5087 | + */ | |
| 5088 | + struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; | |
| 5089 | + | |
| 5090 | + intel_dp_retrain_link(encoder, ctx); | |
| 4723 | 5091 | } |
| 4724 | 5092 | |
| 4725 | 5093 | /* |
| @@ -4781,7 +5149,7 @@ intel_dp_detect(struct drm_connector *connector, · 55 unmodified lines | ||
| 4781 | 5149 | return ret; |
| 4782 | 5150 | } |
| 4783 | 5151 | |
| 4784 | − status = intel_dp_long_pulse(intel_dp->attached_connector); | |
| 5152 | + status = intel_dp_long_pulse(intel_dp->attached_connector, ctx); | |
| 4785 | 5153 | } |
| 4786 | 5154 | |
| 4787 | 5155 | intel_dp->detect_done = false; |
| @@ -5172,7 +5540,7 @@ static const struct intel_hdcp_shim intel_dp_hdcp_shim = { · 384 unmodified lines | ||
| 5172 | 5540 | |
| 5173 | 5541 | static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp) |
| 5174 | 5542 | { |
| 5175 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 5543 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 5176 | 5544 | |
| 5177 | 5545 | lockdep_assert_held(&dev_priv->pps_mutex); |
| 5178 | 5546 | |
| @@ -5193,7 +5561,7 @@ static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp) · 14 unmodified lines | ||
| 5193 | 5561 | |
| 5194 | 5562 | static enum pipe vlv_active_pipe(struct intel_dp *intel_dp) |
| 5195 | 5563 | { |
| 5196 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 5564 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 5197 | 5565 | struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; |
| 5198 | 5566 | enum pipe pipe; |
| 5199 | 5567 | |
| @@ -5260,7 +5628,7 @@ enum irqreturn · 60 unmodified lines | ||
| 5260 | 5628 | intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) |
| 5261 | 5629 | { |
| 5262 | 5630 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
| 5263 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 5631 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 5264 | 5632 | enum irqreturn ret = IRQ_NONE; |
| 5265 | 5633 | |
| 5266 | 5634 | if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) { |
| @@ -5376,7 +5744,7 @@ static void intel_dp_init_panel_power_timestamps(struct intel_dp *intel_dp) · 109 unmodified lines | ||
| 5376 | 5744 | static void |
| 5377 | 5745 | intel_pps_readout_hw_state(struct intel_dp *intel_dp, struct edp_power_seq *seq) |
| 5378 | 5746 | { |
| 5379 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 5747 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 5380 | 5748 | u32 pp_on, pp_off, pp_div = 0, pp_ctl = 0; |
| 5381 | 5749 | struct pps_registers regs; |
| 5382 | 5750 | |
| @@ -5444,7 +5812,7 @@ intel_pps_verify_state(struct intel_dp *intel_dp) · 61 unmodified lines | ||
| 5444 | 5812 | static void |
| 5445 | 5813 | intel_dp_init_panel_power_sequencer(struct intel_dp *intel_dp) |
| 5446 | 5814 | { |
| 5447 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 5815 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 5448 | 5816 | struct edp_power_seq cur, vbt, spec, |
| 5449 | 5817 | *final = &intel_dp->pps_delays; |
| 5450 | 5818 | |
| @@ -5537,7 +5905,7 @@ static void · 86 unmodified lines | ||
| 5537 | 5905 | intel_dp_init_panel_power_sequencer_registers(struct intel_dp *intel_dp, |
| 5538 | 5906 | bool force_disable_vdd) |
| 5539 | 5907 | { |
| 5540 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 5908 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 5541 | 5909 | u32 pp_on, pp_off, pp_div, port_sel = 0; |
| 5542 | 5910 | int div = dev_priv->rawclk_freq / 1000; |
| 5543 | 5911 | struct pps_registers regs; |
| @@ -5633,7 +6001,7 @@ intel_dp_init_panel_power_sequencer_registers(struct intel_dp *intel_dp, · 89 unmodified lines | ||
| 5633 | 6001 | |
| 5634 | 6002 | static void intel_dp_pps_init(struct intel_dp *intel_dp) |
| 5635 | 6003 | { |
| 5636 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 6004 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 5637 | 6005 | |
| 5638 | 6006 | if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { |
| 5639 | 6007 | vlv_initial_power_sequencer_setup(intel_dp); |
| @@ -5750,7 +6118,7 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv, · 110 unmodified lines | ||
| 5750 | 6118 | void intel_edp_drrs_enable(struct intel_dp *intel_dp, |
| 5751 | 6119 | const struct intel_crtc_state *crtc_state) |
| 5752 | 6120 | { |
| 5753 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 6121 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 5754 | 6122 | |
| 5755 | 6123 | if (!crtc_state->has_drrs) { |
| 5756 | 6124 | DRM_DEBUG_KMS("Panel doesn't support DRRS\n"); |
| @@ -5785,7 +6153,7 @@ unlock: · 28 unmodified lines | ||
| 5785 | 6153 | void intel_edp_drrs_disable(struct intel_dp *intel_dp, |
| 5786 | 6154 | const struct intel_crtc_state *old_crtc_state) |
| 5787 | 6155 | { |
| 5788 | − struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); | |
| 6156 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 5789 | 6157 | |
| 5790 | 6158 | if (!old_crtc_state->has_drrs) |
| 5791 | 6159 | return; |
| @@ -6017,8 +6385,8 @@ intel_dp_drrs_init(struct intel_connector *connector, · 225 unmodified lines | ||
| 6017 | 6385 | static bool intel_edp_init_connector(struct intel_dp *intel_dp, |
| 6018 | 6386 | struct intel_connector *intel_connector) |
| 6019 | 6387 | { |
| 6020 | − struct drm_device *dev = intel_dp_to_dev(intel_dp); | |
| 6021 | − struct drm_i915_private *dev_priv = to_i915(dev); | |
| 6388 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 6389 | + struct drm_device *dev = &dev_priv->drm; | |
| 6022 | 6390 | struct drm_connector *connector = &intel_connector->base; |
| 6023 | 6391 | struct drm_display_mode *fixed_mode = NULL; |
| 6024 | 6392 | struct drm_display_mode *downclock_mode = NULL; |
| @@ -129,7 +129,8 @@ static bool · 128 unmodified lines | ||
| 129 | 129 | intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) |
| 130 | 130 | { |
| 131 | 131 | uint8_t voltage; |
| 132 | − int voltage_tries, max_vswing_tries; | |
| 132 | + int voltage_tries, cr_tries, max_cr_tries; | |
| 133 | + bool max_vswing_reached = false; | |
| 133 | 134 | uint8_t link_config[2]; |
| 134 | 135 | uint8_t link_bw, rate_select; |
| 135 | 136 | |
| @@ -170,9 +171,21 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) · 34 unmodified lines | ||
| 170 | 171 | return false; |
| 171 | 172 | } |
| 172 | 173 | |
| 174 | + /* | |
| 175 | + * The DP 1.4 spec defines the max clock recovery retries value | |
| 176 | + * as 10 but for pre-DP 1.4 devices we set a very tolerant | |
| 177 | + * retry limit of 80 (4 voltage levels x 4 preemphasis levels x | |
| 178 | + * x 5 identical voltage retries). Since the previous specs didn't | |
| 179 | + * define a limit and created the possibility of an infinite loop | |
| 180 | + * we want to prevent any sync from triggering that corner case. | |
| 181 | + */ | |
| 182 | + if (intel_dp->dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14) | |
| 183 | + max_cr_tries = 10; | |
| 184 | + else | |
| 185 | + max_cr_tries = 80; | |
| 186 | + | |
| 173 | 187 | voltage_tries = 1; |
| 174 | − max_vswing_tries = 0; | |
| 175 | − for (;;) { | |
| 188 | + for (cr_tries = 0; cr_tries < max_cr_tries; ++cr_tries) { | |
| 176 | 189 | uint8_t link_status[DP_LINK_STATUS_SIZE]; |
| 177 | 190 | |
| 178 | 191 | drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd); |
| @@ -192,7 +205,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) · 13 unmodified lines | ||
| 192 | 205 | return false; |
| 193 | 206 | } |
| 194 | 207 | |
| 195 | − if (max_vswing_tries == 1) { | |
| 208 | + if (max_vswing_reached) { | |
| 196 | 209 | DRM_DEBUG_KMS("Max Voltage Swing reached\n"); |
| 197 | 210 | return false; |
| 198 | 211 | } |
| @@ -213,9 +226,11 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) · 14 unmodified lines | ||
| 213 | 226 | voltage_tries = 1; |
| 214 | 227 | |
| 215 | 228 | if (intel_dp_link_max_vswing_reached(intel_dp)) |
| 216 | − ++max_vswing_tries; | |
| 229 | + max_vswing_reached = true; | |
| 217 | 230 | |
| 218 | 231 | } |
| 232 | + DRM_ERROR("Failed clock recovery %d times, giving up!\n", max_cr_tries); | |
| 233 | + return false; | |
| 219 | 234 | } |
| 220 | 235 | |
| 221 | 236 | /* |
| @@ -166,6 +166,8 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder, · 165 unmodified lines | ||
| 166 | 166 | struct intel_connector *connector = |
| 167 | 167 | to_intel_connector(old_conn_state->connector); |
| 168 | 168 | |
| 169 | + intel_ddi_disable_pipe_clock(old_crtc_state); | |
| 170 | + | |
| 169 | 171 | /* this can fail */ |
| 170 | 172 | drm_dp_check_act_status(&intel_dp->mst_mgr); |
| 171 | 173 | /* and this can also fail */ |
| @@ -241,17 +243,16 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder, · 69 unmodified lines | ||
| 241 | 243 | connector->port, |
| 242 | 244 | pipe_config->pbn, |
| 243 | 245 | pipe_config->dp_m_n.tu); |
| 244 | − if (ret == false) { | |
| 246 | + if (!ret) | |
| 245 | 247 | DRM_ERROR("failed to allocate vcpi\n"); |
| 246 | − return; | |
| 247 | − } | |
| 248 | − | |
| 249 | 248 | |
| 250 | 249 | intel_dp->active_mst_links++; |
| 251 | 250 | temp = I915_READ(DP_TP_STATUS(port)); |
| 252 | 251 | I915_WRITE(DP_TP_STATUS(port), temp); |
| 253 | 252 | |
| 254 | 253 | ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr); |
| 254 | + | |
| 255 | + intel_ddi_enable_pipe_clock(pipe_config); | |
| 255 | 256 | } |
| 256 | 257 | |
| 257 | 258 | static void intel_mst_enable_dp(struct intel_encoder *encoder, |
| @@ -263,7 +264,6 @@ static void intel_mst_enable_dp(struct intel_encoder *encoder, · 5 unmodified lines | ||
| 263 | 264 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
| 264 | 265 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
| 265 | 266 | enum port port = intel_dig_port->base.port; |
| 266 | − int ret; | |
| 267 | 267 | |
| 268 | 268 | DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); |
| 269 | 269 | |
| @@ -274,9 +274,9 @@ static void intel_mst_enable_dp(struct intel_encoder *encoder, · 4 unmodified lines | ||
| 274 | 274 | 1)) |
| 275 | 275 | DRM_ERROR("Timed out waiting for ACT sent\n"); |
| 276 | 276 | |
| 277 | − ret = drm_dp_check_act_status(&intel_dp->mst_mgr); | |
| 277 | + drm_dp_check_act_status(&intel_dp->mst_mgr); | |
| 278 | 278 | |
| 279 | − ret = drm_dp_update_payload_part2(&intel_dp->mst_mgr); | |
| 279 | + drm_dp_update_payload_part2(&intel_dp->mst_mgr); | |
| 280 | 280 | if (pipe_config->has_audio) |
| 281 | 281 | intel_audio_codec_enable(encoder, pipe_config, conn_state); |
| 282 | 282 | } |
| @@ -2212,6 +2212,20 @@ static void cnl_wrpll_params_populate(struct skl_wrpll_params *params, · 2211 unmodified lines | ||
| 2212 | 2212 | params->dco_fraction = dco & 0x7fff; |
| 2213 | 2213 | } |
| 2214 | 2214 | |
| 2215 | +int cnl_hdmi_pll_ref_clock(struct drm_i915_private *dev_priv) | |
| 2216 | +{ | |
| 2217 | + int ref_clock = dev_priv->cdclk.hw.ref; | |
| 2218 | + | |
| 2219 | + /* | |
| 2220 | + * For ICL+, the spec states: if reference frequency is 38.4, | |
| 2221 | + * use 19.2 because the DPLL automatically divides that by 2. | |
| 2222 | + */ | |
| 2223 | + if (INTEL_GEN(dev_priv) >= 11 && ref_clock == 38400) | |
| 2224 | + ref_clock = 19200; | |
| 2225 | + | |
| 2226 | + return ref_clock; | |
| 2227 | +} | |
| 2228 | + | |
| 2215 | 2229 | static bool |
| 2216 | 2230 | cnl_ddi_calculate_wrpll(int clock, |
| 2217 | 2231 | struct drm_i915_private *dev_priv, |
| @@ -2251,14 +2265,7 @@ cnl_ddi_calculate_wrpll(int clock, · 33 unmodified lines | ||
| 2251 | 2265 | |
| 2252 | 2266 | cnl_wrpll_get_multipliers(best_div, &pdiv, &qdiv, &kdiv); |
| 2253 | 2267 | |
| 2254 | − ref_clock = dev_priv->cdclk.hw.ref; | |
| 2255 | − | |
| 2256 | − /* | |
| 2257 | − * For ICL, the spec states: if reference frequency is 38.4, use 19.2 | |
| 2258 | − * because the DPLL automatically divides that by 2. | |
| 2259 | − */ | |
| 2260 | − if (IS_ICELAKE(dev_priv) && ref_clock == 38400) | |
| 2261 | − ref_clock = 19200; | |
| 2268 | + ref_clock = cnl_hdmi_pll_ref_clock(dev_priv); | |
| 2262 | 2269 | |
| 2263 | 2270 | cnl_wrpll_params_populate(wrpll_params, best_dco, ref_clock, pdiv, qdiv, |
| 2264 | 2271 | kdiv); |
| @@ -2452,6 +2459,16 @@ static const struct skl_wrpll_params icl_dp_combo_pll_19_2MHz_values[] = { · 187 unmodified lines | ||
| 2452 | 2459 | .pdiv = 0x1 /* 2 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0}, |
| 2453 | 2460 | }; |
| 2454 | 2461 | |
| 2462 | +static const struct skl_wrpll_params icl_tbt_pll_24MHz_values = { | |
| 2463 | + .dco_integer = 0x151, .dco_fraction = 0x4000, | |
| 2464 | + .pdiv = 0x4 /* 5 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, | |
| 2465 | +}; | |
| 2466 | + | |
| 2467 | +static const struct skl_wrpll_params icl_tbt_pll_19_2MHz_values = { | |
| 2468 | + .dco_integer = 0x1A5, .dco_fraction = 0x7000, | |
| 2469 | + .pdiv = 0x4 /* 5 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0, | |
| 2470 | +}; | |
| 2471 | + | |
| 2455 | 2472 | static bool icl_calc_dp_combo_pll(struct drm_i915_private *dev_priv, int clock, |
| 2456 | 2473 | struct skl_wrpll_params *pll_params) |
| 2457 | 2474 | { |
| @@ -2494,6 +2511,14 @@ static bool icl_calc_dp_combo_pll(struct drm_i915_private *dev_priv, int clock, · 36 unmodified lines | ||
| 2494 | 2511 | return true; |
| 2495 | 2512 | } |
| 2496 | 2513 | |
| 2514 | +static bool icl_calc_tbt_pll(struct drm_i915_private *dev_priv, int clock, | |
| 2515 | + struct skl_wrpll_params *pll_params) | |
| 2516 | +{ | |
| 2517 | + *pll_params = dev_priv->cdclk.hw.ref == 24000 ? | |
| 2518 | + icl_tbt_pll_24MHz_values : icl_tbt_pll_19_2MHz_values; | |
| 2519 | + return true; | |
| 2520 | +} | |
| 2521 | + | |
| 2497 | 2522 | static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state, |
| 2498 | 2523 | struct intel_encoder *encoder, int clock, |
| 2499 | 2524 | struct intel_dpll_hw_state *pll_state) |
| @@ -2503,7 +2528,9 @@ static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state, · 3 unmodified lines | ||
| 2503 | 2528 | struct skl_wrpll_params pll_params = { 0 }; |
| 2504 | 2529 | bool ret; |
| 2505 | 2530 | |
| 2506 | − if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) | |
| 2531 | + if (intel_port_is_tc(dev_priv, encoder->port)) | |
| 2532 | + ret = icl_calc_tbt_pll(dev_priv, clock, &pll_params); | |
| 2533 | + else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) | |
| 2507 | 2534 | ret = cnl_ddi_calculate_wrpll(clock, dev_priv, &pll_params); |
| 2508 | 2535 | else |
| 2509 | 2536 | ret = icl_calc_dp_combo_pll(dev_priv, clock, &pll_params); |
| @@ -2623,7 +2650,8 @@ static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc, · 113 unmodified lines | ||
| 2623 | 2650 | |
| 2624 | 2651 | for (div2 = 10; div2 > 0; div2--) { |
| 2625 | 2652 | int dco = div1 * div2 * clock_khz * 5; |
| 2626 | − int a_divratio, tlinedrv, inputsel, hsdiv; | |
| 2653 | + int a_divratio, tlinedrv, inputsel; | |
| 2654 | + u32 hsdiv; | |
| 2627 | 2655 | |
| 2628 | 2656 | if (dco < dco_min_freq || dco > dco_max_freq) |
| 2629 | 2657 | continue; |
| @@ -2642,16 +2670,16 @@ static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc, · 12 unmodified lines | ||
| 2642 | 2670 | MISSING_CASE(div1); |
| 2643 | 2671 | /* fall through */ |
| 2644 | 2672 | case 2: |
| 2645 | − hsdiv = 0; | |
| 2673 | + hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_2; | |
| 2646 | 2674 | break; |
| 2647 | 2675 | case 3: |
| 2648 | − hsdiv = 1; | |
| 2676 | + hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_3; | |
| 2649 | 2677 | break; |
| 2650 | 2678 | case 5: |
| 2651 | − hsdiv = 2; | |
| 2679 | + hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_5; | |
| 2652 | 2680 | break; |
| 2653 | 2681 | case 7: |
| 2654 | − hsdiv = 3; | |
| 2682 | + hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_7; | |
| 2655 | 2683 | break; |
| 2656 | 2684 | } |
| 2657 | 2685 | |
| @@ -2665,7 +2693,7 @@ static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc, · 7 unmodified lines | ||
| 2665 | 2693 | state->mg_clktop2_hsclkctl = |
| 2666 | 2694 | MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(tlinedrv) | |
| 2667 | 2695 | MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL(inputsel) | |
| 2668 | − MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO(hsdiv) | | |
| 2696 | + hsdiv | | |
| 2669 | 2697 | MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO(div2); |
| 2670 | 2698 | |
| 2671 | 2699 | return true; |
| @@ -2846,6 +2874,8 @@ static struct intel_shared_dpll * · 174 unmodified lines | ||
| 2846 | 2874 | icl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, |
| 2847 | 2875 | struct intel_encoder *encoder) |
| 2848 | 2876 | { |
| 2877 | + struct intel_digital_port *intel_dig_port = | |
| 2878 | + enc_to_dig_port(&encoder->base); | |
| 2849 | 2879 | struct intel_shared_dpll *pll; |
| 2850 | 2880 | struct intel_dpll_hw_state pll_state = {}; |
| 2851 | 2881 | enum port port = encoder->port; |
| @@ -2865,7 +2895,7 @@ icl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, · 13 unmodified lines | ||
| 2865 | 2895 | case PORT_D: |
| 2866 | 2896 | case PORT_E: |
| 2867 | 2897 | case PORT_F: |
| 2868 | − if (0 /* TODO: TBT PLLs */) { | |
| 2898 | + if (intel_dig_port->tc_type == TC_PORT_TBT) { | |
| 2869 | 2899 | min = DPLL_ID_ICL_TBTPLL; |
| 2870 | 2900 | max = min; |
| 2871 | 2901 | ret = icl_calc_dpll_state(crtc_state, encoder, clock, |
| @@ -344,5 +344,6 @@ void intel_dpll_dump_hw_state(struct drm_i915_private *dev_priv, · 343 unmodified lines | ||
| 344 | 344 | struct intel_dpll_hw_state *hw_state); |
| 345 | 345 | int icl_calc_dp_combo_pll_link(struct drm_i915_private *dev_priv, |
| 346 | 346 | uint32_t pll_id); |
| 347 | +int cnl_hdmi_pll_ref_clock(struct drm_i915_private *dev_priv); | |
| 347 | 348 | |
| 348 | 349 | #endif /* _INTEL_DPLL_MGR_H_ */ |
| @@ -972,9 +972,8 @@ struct intel_plane { · 971 unmodified lines | ||
| 972 | 972 | void (*disable_plane)(struct intel_plane *plane, |
| 973 | 973 | struct intel_crtc *crtc); |
| 974 | 974 | bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe); |
| 975 | − int (*check_plane)(struct intel_plane *plane, | |
| 976 | − struct intel_crtc_state *crtc_state, | |
| 977 | − struct intel_plane_state *state); | |
| 975 | + int (*check_plane)(struct intel_crtc_state *crtc_state, | |
| 976 | + struct intel_plane_state *plane_state); | |
| 978 | 977 | }; |
| 979 | 978 | |
| 980 | 979 | struct intel_watermark_params { |
| @@ -1168,6 +1167,7 @@ struct intel_digital_port { · 187 unmodified lines | ||
| 1168 | 1167 | bool release_cl2_override; |
| 1169 | 1168 | uint8_t max_lanes; |
| 1170 | 1169 | enum intel_display_power_domain ddi_io_power_domain; |
| 1170 | + enum tc_port_type tc_type; | |
| 1171 | 1171 | |
| 1172 | 1172 | void (*write_infoframe)(struct drm_encoder *encoder, |
| 1173 | 1173 | const struct intel_crtc_state *crtc_state, |
| @@ -1314,6 +1314,12 @@ dp_to_lspcon(struct intel_dp *intel_dp) · 140 unmodified lines | ||
| 1314 | 1314 | return &dp_to_dig_port(intel_dp)->lspcon; |
| 1315 | 1315 | } |
| 1316 | 1316 | |
| 1317 | +static inline struct drm_i915_private * | |
| 1318 | +dp_to_i915(struct intel_dp *intel_dp) | |
| 1319 | +{ | |
| 1320 | + return to_i915(dp_to_dig_port(intel_dp)->base.base.dev); | |
| 1321 | +} | |
| 1322 | + | |
| 1317 | 1323 | static inline struct intel_digital_port * |
| 1318 | 1324 | hdmi_to_dig_port(struct intel_hdmi *intel_hdmi) |
| 1319 | 1325 | { |
| @@ -1717,6 +1723,9 @@ void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv, · 397 unmodified lines | ||
| 1717 | 1723 | unsigned int frontbuffer_bits); |
| 1718 | 1724 | void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, |
| 1719 | 1725 | unsigned int frontbuffer_bits); |
| 1726 | +void icl_program_mg_dp_mode(struct intel_dp *intel_dp); | |
| 1727 | +void icl_enable_phy_clock_gating(struct intel_digital_port *dig_port); | |
| 1728 | +void icl_disable_phy_clock_gating(struct intel_digital_port *dig_port); | |
| 1720 | 1729 | |
| 1721 | 1730 | void |
| 1722 | 1731 | intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, |
| @@ -1930,6 +1939,9 @@ void intel_psr_enable(struct intel_dp *intel_dp, · 207 unmodified lines | ||
| 1930 | 1939 | const struct intel_crtc_state *crtc_state); |
| 1931 | 1940 | void intel_psr_disable(struct intel_dp *intel_dp, |
| 1932 | 1941 | const struct intel_crtc_state *old_crtc_state); |
| 1942 | +int intel_psr_set_debugfs_mode(struct drm_i915_private *dev_priv, | |
| 1943 | + struct drm_modeset_acquire_ctx *ctx, | |
| 1944 | + u64 value); | |
| 1933 | 1945 | void intel_psr_invalidate(struct drm_i915_private *dev_priv, |
| 1934 | 1946 | unsigned frontbuffer_bits, |
| 1935 | 1947 | enum fb_op_origin origin); |
| @@ -1939,20 +1951,33 @@ void intel_psr_flush(struct drm_i915_private *dev_priv, · 3 unmodified lines | ||
| 1939 | 1951 | void intel_psr_init(struct drm_i915_private *dev_priv); |
| 1940 | 1952 | void intel_psr_compute_config(struct intel_dp *intel_dp, |
| 1941 | 1953 | struct intel_crtc_state *crtc_state); |
| 1942 | −void intel_psr_irq_control(struct drm_i915_private *dev_priv, bool debug); | |
| 1954 | +void intel_psr_irq_control(struct drm_i915_private *dev_priv, u32 debug); | |
| 1943 | 1955 | void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir); |
| 1944 | 1956 | void intel_psr_short_pulse(struct intel_dp *intel_dp); |
| 1945 | −int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state); | |
| 1957 | +int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state, | |
| 1958 | + u32 *out_value); | |
| 1946 | 1959 | |
| 1947 | 1960 | /* intel_runtime_pm.c */ |
| 1948 | 1961 | int intel_power_domains_init(struct drm_i915_private *); |
| 1949 | −void intel_power_domains_fini(struct drm_i915_private *); | |
| 1962 | +void intel_power_domains_cleanup(struct drm_i915_private *dev_priv); | |
| 1950 | 1963 | void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume); |
| 1951 | −void intel_power_domains_suspend(struct drm_i915_private *dev_priv); | |
| 1952 | −void intel_power_domains_verify_state(struct drm_i915_private *dev_priv); | |
| 1964 | +void intel_power_domains_fini_hw(struct drm_i915_private *dev_priv); | |
| 1965 | +void intel_power_domains_enable(struct drm_i915_private *dev_priv); | |
| 1966 | +void intel_power_domains_disable(struct drm_i915_private *dev_priv); | |
| 1967 | + | |
| 1968 | +enum i915_drm_suspend_mode { | |
| 1969 | + I915_DRM_SUSPEND_IDLE, | |
| 1970 | + I915_DRM_SUSPEND_MEM, | |
| 1971 | + I915_DRM_SUSPEND_HIBERNATE, | |
| 1972 | +}; | |
| 1973 | + | |
| 1974 | +void intel_power_domains_suspend(struct drm_i915_private *dev_priv, | |
| 1975 | + enum i915_drm_suspend_mode); | |
| 1976 | +void intel_power_domains_resume(struct drm_i915_private *dev_priv); | |
| 1953 | 1977 | void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume); |
| 1954 | 1978 | void bxt_display_core_uninit(struct drm_i915_private *dev_priv); |
| 1955 | 1979 | void intel_runtime_pm_enable(struct drm_i915_private *dev_priv); |
| 1980 | +void intel_runtime_pm_disable(struct drm_i915_private *dev_priv); | |
| 1956 | 1981 | const char * |
| 1957 | 1982 | intel_display_power_domain_str(enum intel_display_power_domain domain); |
| 1958 | 1983 | |
| @@ -2030,8 +2055,6 @@ bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *dev_priv); · 71 unmodified lines | ||
| 2030 | 2055 | void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv); |
| 2031 | 2056 | void intel_runtime_pm_put(struct drm_i915_private *dev_priv); |
| 2032 | 2057 | |
| 2033 | −void intel_display_set_init_power(struct drm_i915_private *dev, bool enable); | |
| 2034 | − | |
| 2035 | 2058 | void chv_phy_powergate_lanes(struct intel_encoder *encoder, |
| 2036 | 2059 | bool override, unsigned int mask); |
| 2037 | 2060 | bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy, |
| @@ -513,7 +513,7 @@ int intel_engine_create_scratch(struct intel_engine_cs *engine, · 512 unmodified lines | ||
| 513 | 513 | goto err_unref; |
| 514 | 514 | } |
| 515 | 515 | |
| 516 | − ret = i915_vma_pin(vma, 0, 4096, PIN_GLOBAL | PIN_HIGH); | |
| 516 | + ret = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH); | |
| 517 | 517 | if (ret) |
| 518 | 518 | goto err_unref; |
| 519 | 519 | |
| @@ -527,36 +527,19 @@ err_unref: · 7 unmodified lines | ||
| 527 | 527 | |
| 528 | 528 | void intel_engine_cleanup_scratch(struct intel_engine_cs *engine) |
| 529 | 529 | { |
| 530 | − i915_vma_unpin_and_release(&engine->scratch); | |
| 531 | −} | |
| 532 | − | |
| 533 | −static void cleanup_phys_status_page(struct intel_engine_cs *engine) | |
| 534 | −{ | |
| 535 | − struct drm_i915_private *dev_priv = engine->i915; | |
| 536 | − | |
| 537 | − if (!dev_priv->status_page_dmah) | |
| 538 | − return; | |
| 539 | − | |
| 540 | − drm_pci_free(&dev_priv->drm, dev_priv->status_page_dmah); | |
| 541 | − engine->status_page.page_addr = NULL; | |
| 530 | + i915_vma_unpin_and_release(&engine->scratch, 0); | |
| 542 | 531 | } |
| 543 | 532 | |
| 544 | 533 | static void cleanup_status_page(struct intel_engine_cs *engine) |
| 545 | 534 | { |
| 546 | − struct i915_vma *vma; | |
| 547 | − struct drm_i915_gem_object *obj; | |
| 548 | − | |
| 549 | − vma = fetch_and_zero(&engine->status_page.vma); | |
| 550 | − if (!vma) | |
| 551 | − return; | |
| 552 | − | |
| 553 | − obj = vma->obj; | |
| 535 | + if (HWS_NEEDS_PHYSICAL(engine->i915)) { | |
| 536 | + void *addr = fetch_and_zero(&engine->status_page.page_addr); | |
| 554 | 537 | |
| 555 | − i915_vma_unpin(vma); | |
| 556 | − i915_vma_close(vma); | |
| 538 | + __free_page(virt_to_page(addr)); | |
| 539 | + } | |
| 557 | 540 | |
| 558 | − i915_gem_object_unpin_map(obj); | |
| 559 | − __i915_gem_object_release_unless_active(obj); | |
| 541 | + i915_vma_unpin_and_release(&engine->status_page.vma, | |
| 542 | + I915_VMA_RELEASE_MAP); | |
| 560 | 543 | } |
| 561 | 544 | |
| 562 | 545 | static int init_status_page(struct intel_engine_cs *engine) |
| @@ -598,7 +581,7 @@ static int init_status_page(struct intel_engine_cs *engine) · 35 unmodified lines | ||
| 598 | 581 | flags |= PIN_MAPPABLE; |
| 599 | 582 | else |
| 600 | 583 | flags |= PIN_HIGH; |
| 601 | − ret = i915_vma_pin(vma, 0, 4096, flags); | |
| 584 | + ret = i915_vma_pin(vma, 0, 0, flags); | |
| 602 | 585 | if (ret) |
| 603 | 586 | goto err; |
| 604 | 587 | |
| @@ -622,17 +605,18 @@ err: · 17 unmodified lines | ||
| 622 | 605 | |
| 623 | 606 | static int init_phys_status_page(struct intel_engine_cs *engine) |
| 624 | 607 | { |
| 625 | − struct drm_i915_private *dev_priv = engine->i915; | |
| 608 | + struct page *page; | |
| 626 | 609 | |
| 627 | − GEM_BUG_ON(engine->id != RCS); | |
| 628 | − | |
| 629 | − dev_priv->status_page_dmah = | |
| 630 | − drm_pci_alloc(&dev_priv->drm, PAGE_SIZE, PAGE_SIZE); | |
| 631 | − if (!dev_priv->status_page_dmah) | |
| 610 | + /* | |
| 611 | + * Though the HWS register does support 36bit addresses, historically | |
| 612 | + * we have had hangs and corruption reported due to wild writes if | |
| 613 | + * the HWS is placed above 4G. | |
| 614 | + */ | |
| 615 | + page = alloc_page(GFP_KERNEL | __GFP_DMA32 | __GFP_ZERO); | |
| 616 | + if (!page) | |
| 632 | 617 | return -ENOMEM; |
| 633 | 618 | |
| 634 | − engine->status_page.page_addr = dev_priv->status_page_dmah->vaddr; | |
| 635 | − memset(engine->status_page.page_addr, 0, PAGE_SIZE); | |
| 619 | + engine->status_page.page_addr = page_address(page); | |
| 636 | 620 | |
| 637 | 621 | return 0; |
| 638 | 622 | } |
| @@ -722,10 +706,7 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine) · 83 unmodified lines | ||
| 722 | 706 | |
| 723 | 707 | intel_engine_cleanup_scratch(engine); |
| 724 | 708 | |
| 725 | − if (HWS_NEEDS_PHYSICAL(engine->i915)) | |
| 726 | − cleanup_phys_status_page(engine); | |
| 727 | − else | |
| 728 | − cleanup_status_page(engine); | |
| 709 | + cleanup_status_page(engine); | |
| 729 | 710 | |
| 730 | 711 | intel_engine_fini_breadcrumbs(engine); |
| 731 | 712 | intel_engine_cleanup_cmd_parser(engine); |
| @@ -800,6 +781,16 @@ int intel_engine_stop_cs(struct intel_engine_cs *engine) · 68 unmodified lines | ||
| 800 | 781 | return err; |
| 801 | 782 | } |
| 802 | 783 | |
| 784 | +void intel_engine_cancel_stop_cs(struct intel_engine_cs *engine) | |
| 785 | +{ | |
| 786 | + struct drm_i915_private *dev_priv = engine->i915; | |
| 787 | + | |
| 788 | + GEM_TRACE("%s\n", engine->name); | |
| 789 | + | |
| 790 | + I915_WRITE_FW(RING_MI_MODE(engine->mmio_base), | |
| 791 | + _MASKED_BIT_DISABLE(STOP_RING)); | |
| 792 | +} | |
| 793 | + | |
| 803 | 794 | const char *i915_cache_level_str(struct drm_i915_private *i915, int type) |
| 804 | 795 | { |
| 805 | 796 | switch (type) { |
| @@ -980,8 +971,7 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine) · 174 unmodified lines | ||
| 980 | 971 | return true; |
| 981 | 972 | |
| 982 | 973 | /* Any inflight/incomplete requests? */ |
| 983 | − if (!i915_seqno_passed(intel_engine_get_seqno(engine), | |
| 984 | − intel_engine_last_submit(engine))) | |
| 974 | + if (!intel_engine_signaled(engine, intel_engine_last_submit(engine))) | |
| 985 | 975 | return false; |
| 986 | 976 | |
| 987 | 977 | if (I915_SELFTEST_ONLY(engine->breadcrumbs.mock)) |
| @@ -1348,20 +1338,19 @@ static void intel_engine_print_registers(const struct intel_engine_cs *engine, · 360 unmodified lines | ||
| 1348 | 1338 | |
| 1349 | 1339 | if (HAS_EXECLISTS(dev_priv)) { |
| 1350 | 1340 | const u32 *hws = &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; |
| 1351 | − u32 ptr, read, write; | |
| 1352 | 1341 | unsigned int idx; |
| 1342 | + u8 read, write; | |
| 1353 | 1343 | |
| 1354 | 1344 | drm_printf(m, "\tExeclist status: 0x%08x %08x\n", |
| 1355 | 1345 | I915_READ(RING_EXECLIST_STATUS_LO(engine)), |
| 1356 | 1346 | I915_READ(RING_EXECLIST_STATUS_HI(engine))); |
| 1357 | 1347 | |
| 1358 | − ptr = I915_READ(RING_CONTEXT_STATUS_PTR(engine)); | |
| 1359 | − read = GEN8_CSB_READ_PTR(ptr); | |
| 1360 | − write = GEN8_CSB_WRITE_PTR(ptr); | |
| 1361 | − drm_printf(m, "\tExeclist CSB read %d [%d cached], write %d [%d from hws], tasklet queued? %s (%s)\n", | |
| 1362 | − read, execlists->csb_head, | |
| 1363 | − write, | |
| 1364 | − intel_read_status_page(engine, intel_hws_csb_write_index(engine->i915)), | |
| 1348 | + read = execlists->csb_head; | |
| 1349 | + write = READ_ONCE(*execlists->csb_write); | |
| 1350 | + | |
| 1351 | + drm_printf(m, "\tExeclist CSB read %d, write %d [mmio:%d], tasklet queued? %s (%s)\n", | |
| 1352 | + read, write, | |
| 1353 | + GEN8_CSB_WRITE_PTR(I915_READ(RING_CONTEXT_STATUS_PTR(engine))), | |
| 1365 | 1354 | yesno(test_bit(TASKLET_STATE_SCHED, |
| 1366 | 1355 | &engine->execlists.tasklet.state)), |
| 1367 | 1356 | enableddisabled(!atomic_read(&engine->execlists.tasklet.count))); |
| @@ -1373,12 +1362,12 @@ static void intel_engine_print_registers(const struct intel_engine_cs *engine, · 5 unmodified lines | ||
| 1373 | 1362 | write += GEN8_CSB_ENTRIES; |
| 1374 | 1363 | while (read < write) { |
| 1375 | 1364 | idx = ++read % GEN8_CSB_ENTRIES; |
| 1376 | − drm_printf(m, "\tExeclist CSB[%d]: 0x%08x [0x%08x in hwsp], context: %d [%d in hwsp]\n", | |
| 1365 | + drm_printf(m, "\tExeclist CSB[%d]: 0x%08x [mmio:0x%08x], context: %d [mmio:%d]\n", | |
| 1377 | 1366 | idx, |
| 1378 | − I915_READ(RING_CONTEXT_STATUS_BUF_LO(engine, idx)), | |
| 1379 | 1367 | hws[idx * 2], |
| 1380 | − I915_READ(RING_CONTEXT_STATUS_BUF_HI(engine, idx)), | |
| 1381 | − hws[idx * 2 + 1]); | |
| 1368 | + I915_READ(RING_CONTEXT_STATUS_BUF_LO(engine, idx)), | |
| 1369 | + hws[idx * 2 + 1], | |
| 1370 | + I915_READ(RING_CONTEXT_STATUS_BUF_HI(engine, idx))); | |
| 1382 | 1371 | } |
| 1383 | 1372 | |
| 1384 | 1373 | rcu_read_lock(); |
| @@ -27,8 +27,6 @@ · 26 unmodified lines | ||
| 27 | 27 | #include "intel_guc_submission.h" |
| 28 | 28 | #include "i915_drv.h" |
| 29 | 29 | |
| 30 | −static void guc_init_ggtt_pin_bias(struct intel_guc *guc); | |
| 31 | − | |
| 32 | 30 | static void gen8_guc_raise_irq(struct intel_guc *guc) |
| 33 | 31 | { |
| 34 | 32 | struct drm_i915_private *dev_priv = guc_to_i915(guc); |
| @@ -128,13 +126,15 @@ static int guc_init_wq(struct intel_guc *guc) · 93 unmodified lines | ||
| 128 | 126 | |
| 129 | 127 | static void guc_fini_wq(struct intel_guc *guc) |
| 130 | 128 | { |
| 131 | − struct drm_i915_private *dev_priv = guc_to_i915(guc); | |
| 129 | + struct workqueue_struct *wq; | |
| 132 | 130 | |
| 133 | − if (HAS_LOGICAL_RING_PREEMPTION(dev_priv) && | |
| 134 | − USES_GUC_SUBMISSION(dev_priv)) | |
| 135 | − destroy_workqueue(guc->preempt_wq); | |
| 131 | + wq = fetch_and_zero(&guc->preempt_wq); | |
| 132 | + if (wq) | |
| 133 | + destroy_workqueue(wq); | |
| 136 | 134 | |
| 137 | − destroy_workqueue(guc->log.relay.flush_wq); | |
| 135 | + wq = fetch_and_zero(&guc->log.relay.flush_wq); | |
| 136 | + if (wq) | |
| 137 | + destroy_workqueue(wq); | |
| 138 | 138 | } |
| 139 | 139 | |
| 140 | 140 | int intel_guc_init_misc(struct intel_guc *guc) |
| @@ -142,8 +142,6 @@ int intel_guc_init_misc(struct intel_guc *guc) · 1 unmodified line | ||
| 142 | 142 | struct drm_i915_private *i915 = guc_to_i915(guc); |
| 143 | 143 | int ret; |
| 144 | 144 | |
| 145 | − guc_init_ggtt_pin_bias(guc); | |
| 146 | − | |
| 147 | 145 | ret = guc_init_wq(guc); |
| 148 | 146 | if (ret) |
| 149 | 147 | return ret; |
| @@ -170,7 +168,7 @@ static int guc_shared_data_create(struct intel_guc *guc) · 20 unmodified lines | ||
| 170 | 168 | |
| 171 | 169 | vaddr = i915_gem_object_pin_map(vma->obj, I915_MAP_WB); |
| 172 | 170 | if (IS_ERR(vaddr)) { |
| 173 | − i915_vma_unpin_and_release(&vma); | |
| 171 | + i915_vma_unpin_and_release(&vma, 0); | |
| 174 | 172 | return PTR_ERR(vaddr); |
| 175 | 173 | } |
| 176 | 174 | |
| @@ -182,8 +180,7 @@ static int guc_shared_data_create(struct intel_guc *guc) · 5 unmodified lines | ||
| 182 | 180 | |
| 183 | 181 | static void guc_shared_data_destroy(struct intel_guc *guc) |
| 184 | 182 | { |
| 185 | − i915_gem_object_unpin_map(guc->shared_data->obj); | |
| 186 | − i915_vma_unpin_and_release(&guc->shared_data); | |
| 183 | + i915_vma_unpin_and_release(&guc->shared_data, I915_VMA_RELEASE_MAP); | |
| 187 | 184 | } |
| 188 | 185 | |
| 189 | 186 | int intel_guc_init(struct intel_guc *guc) |
| @@ -584,52 +581,27 @@ int intel_guc_resume(struct intel_guc *guc) · 394 unmodified lines | ||
| 584 | 581 | * |
| 585 | 582 | * :: |
| 586 | 583 | * |
| 587 | − * +==============> +====================+ <== GUC_GGTT_TOP | |
| 588 | − * ^ | | | |
| 589 | − * | | | | |
| 590 | − * | | DRAM | | |
| 591 | − * | | Memory | | |
| 592 | − * | | | | |
| 593 | − * GuC | | | |
| 594 | − * Address +========> +====================+ <== WOPCM Top | |
| 595 | − * Space ^ | HW contexts RSVD | | |
| 596 | − * | | | WOPCM | | |
| 597 | − * | | +==> +--------------------+ <== GuC WOPCM Top | |
| 598 | − * | GuC ^ | | | |
| 599 | − * | GGTT | | | | |
| 600 | − * | Pin GuC | GuC | | |
| 601 | − * | Bias WOPCM | WOPCM | | |
| 602 | − * | | Size | | | |
| 603 | − * | | | | | | |
| 604 | − * v v v | | | |
| 605 | − * +=====+=====+==> +====================+ <== GuC WOPCM Base | |
| 606 | − * | Non-GuC WOPCM | | |
| 607 | − * | (HuC/Reserved) | | |
| 608 | − * +====================+ <== WOPCM Base | |
| 584 | + * +===========> +====================+ <== FFFF_FFFF | |
| 585 | + * ^ | Reserved | | |
| 586 | + * | +====================+ <== GUC_GGTT_TOP | |
| 587 | + * | | | | |
| 588 | + * | | DRAM | | |
| 589 | + * GuC | | | |
| 590 | + * Address +===> +====================+ <== GuC ggtt_pin_bias | |
| 591 | + * Space ^ | | | |
| 592 | + * | | | | | |
| 593 | + * | GuC | GuC | | |
| 594 | + * | WOPCM | WOPCM | | |
| 595 | + * | Size | | | |
| 596 | + * | | | | | |
| 597 | + * v v | | | |
| 598 | + * +=======+===> +====================+ <== 0000_0000 | |
| 609 | 599 | * |
| 610 | − * The lower part of GuC Address Space [0, ggtt_pin_bias) is mapped to WOPCM | |
| 600 | + * The lower part of GuC Address Space [0, ggtt_pin_bias) is mapped to GuC WOPCM | |
| 611 | 601 | * while upper part of GuC Address Space [ggtt_pin_bias, GUC_GGTT_TOP) is mapped |
| 612 | − * to DRAM. The value of the GuC ggtt_pin_bias is determined by WOPCM size and | |
| 613 | − * actual GuC WOPCM size. | |
| 602 | + * to DRAM. The value of the GuC ggtt_pin_bias is the GuC WOPCM size. | |
| 614 | 603 | */ |
| 615 | 604 | |
| 616 | −/** | |
| 617 | − * guc_init_ggtt_pin_bias() - Initialize the GuC ggtt_pin_bias value. | |
| 618 | − * @guc: intel_guc structure. | |
| 619 | − * | |
| 620 | − * This function will calculate and initialize the ggtt_pin_bias value based on | |
| 621 | − * overall WOPCM size and GuC WOPCM size. | |
| 622 | − */ | |
| 623 | −static void guc_init_ggtt_pin_bias(struct intel_guc *guc) | |
| 624 | −{ | |
| 625 | − struct drm_i915_private *i915 = guc_to_i915(guc); | |
| 626 | − | |
| 627 | − GEM_BUG_ON(!i915->wopcm.size); | |
| 628 | − GEM_BUG_ON(i915->wopcm.size < i915->wopcm.guc.base); | |
| 629 | − | |
| 630 | − guc->ggtt_pin_bias = i915->wopcm.size - i915->wopcm.guc.base; | |
| 631 | −} | |
| 632 | − | |
| 633 | 605 | /** |
| 634 | 606 | * intel_guc_allocate_vma() - Allocate a GGTT VMA for GuC usage |
| 635 | 607 | * @guc: the guc |
| @@ -648,6 +620,7 @@ struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size) · 12 unmodified lines | ||
| 648 | 620 | struct drm_i915_private *dev_priv = guc_to_i915(guc); |
| 649 | 621 | struct drm_i915_gem_object *obj; |
| 650 | 622 | struct i915_vma *vma; |
| 623 | + u64 flags; | |
| 651 | 624 | int ret; |
| 652 | 625 | |
| 653 | 626 | obj = i915_gem_object_create(dev_priv, size); |
| @@ -658,8 +631,8 @@ struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size) · 4 unmodified lines | ||
| 658 | 631 | if (IS_ERR(vma)) |
| 659 | 632 | goto err; |
| 660 | 633 | |
| 661 | − ret = i915_vma_pin(vma, 0, PAGE_SIZE, | |
| 662 | − PIN_GLOBAL | PIN_OFFSET_BIAS | guc->ggtt_pin_bias); | |
| 634 | + flags = PIN_GLOBAL | PIN_OFFSET_BIAS | i915_ggtt_pin_bias(vma); | |
| 635 | + ret = i915_vma_pin(vma, 0, 0, flags); | |
| 663 | 636 | if (ret) { |
| 664 | 637 | vma = ERR_PTR(ret); |
| 665 | 638 | goto err; |
| @@ -671,3 +644,20 @@ err: · 5 unmodified lines | ||
| 671 | 644 | i915_gem_object_put(obj); |
| 672 | 645 | return vma; |
| 673 | 646 | } |
| 647 | + | |
| 648 | +/** | |
| 649 | + * intel_guc_reserved_gtt_size() | |
| 650 | + * @guc: intel_guc structure | |
| 651 | + * | |
| 652 | + * The GuC WOPCM mapping shadows the lower part of the GGTT, so if we are using | |
| 653 | + * GuC we can't have any objects pinned in that region. This function returns | |
| 654 | + * the size of the shadowed region. | |
| 655 | + * | |
| 656 | + * Returns: | |
| 657 | + * 0 if GuC is not present or not in use. | |
| 658 | + * Otherwise, the GuC WOPCM size. | |
| 659 | + */ | |
| 660 | +u32 intel_guc_reserved_gtt_size(struct intel_guc *guc) | |
| 661 | +{ | |
| 662 | + return guc_to_i915(guc)->wopcm.guc.size; | |
| 663 | +} | |
| @@ -49,9 +49,6 @@ struct intel_guc { · 48 unmodified lines | ||
| 49 | 49 | struct intel_guc_log log; |
| 50 | 50 | struct intel_guc_ct ct; |
| 51 | 51 | |
| 52 | − /* Offset where Non-WOPCM memory starts. */ | |
| 53 | − u32 ggtt_pin_bias; | |
| 54 | − | |
| 55 | 52 | /* Log snapshot if GuC errors during load */ |
| 56 | 53 | struct drm_i915_gem_object *load_err_log; |
| 57 | 54 | |
| @@ -130,10 +127,10 @@ static inline void intel_guc_to_host_event_handler(struct intel_guc *guc) · 72 unmodified lines | ||
| 130 | 127 | * @vma: i915 graphics virtual memory area. |
| 131 | 128 | * |
| 132 | 129 | * GuC does not allow any gfx GGTT address that falls into range |
| 133 | − * [0, GuC ggtt_pin_bias), which is reserved for Boot ROM, SRAM and WOPCM. | |
| 134 | − * Currently, in order to exclude [0, GuC ggtt_pin_bias) address space from | |
| 130 | + * [0, ggtt.pin_bias), which is reserved for Boot ROM, SRAM and WOPCM. | |
| 131 | + * Currently, in order to exclude [0, ggtt.pin_bias) address space from | |
| 135 | 132 | * GGTT, all gfx objects used by GuC are allocated with intel_guc_allocate_vma() |
| 136 | − * and pinned with PIN_OFFSET_BIAS along with the value of GuC ggtt_pin_bias. | |
| 133 | + * and pinned with PIN_OFFSET_BIAS along with the value of ggtt.pin_bias. | |
| 137 | 134 | * |
| 138 | 135 | * Return: GGTT offset of the @vma. |
| 139 | 136 | */ |
| @@ -142,7 +139,7 @@ static inline u32 intel_guc_ggtt_offset(struct intel_guc *guc, · 2 unmodified lines | ||
| 142 | 139 | { |
| 143 | 140 | u32 offset = i915_ggtt_offset(vma); |
| 144 | 141 | |
| 145 | − GEM_BUG_ON(offset < guc->ggtt_pin_bias); | |
| 142 | + GEM_BUG_ON(offset < i915_ggtt_pin_bias(vma)); | |
| 146 | 143 | GEM_BUG_ON(range_overflows_t(u64, offset, vma->size, GUC_GGTT_TOP)); |
| 147 | 144 | |
| 148 | 145 | return offset; |
| @@ -168,6 +165,7 @@ int intel_guc_auth_huc(struct intel_guc *guc, u32 rsa_offset); · 19 unmodified lines | ||
| 168 | 165 | int intel_guc_suspend(struct intel_guc *guc); |
| 169 | 166 | int intel_guc_resume(struct intel_guc *guc); |
| 170 | 167 | struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size); |
| 168 | +u32 intel_guc_reserved_gtt_size(struct intel_guc *guc); | |
| 171 | 169 | |
| 172 | 170 | static inline int intel_guc_sanitize(struct intel_guc *guc) |
| 173 | 171 | { |
| @@ -148,5 +148,5 @@ int intel_guc_ads_create(struct intel_guc *guc) · 147 unmodified lines | ||
| 148 | 148 | |
| 149 | 149 | void intel_guc_ads_destroy(struct intel_guc *guc) |
| 150 | 150 | { |
| 151 | − i915_vma_unpin_and_release(&guc->ads_vma); | |
| 151 | + i915_vma_unpin_and_release(&guc->ads_vma, 0); | |
| 152 | 152 | } |
| @@ -204,7 +204,7 @@ static int ctch_init(struct intel_guc *guc, · 203 unmodified lines | ||
| 204 | 204 | return 0; |
| 205 | 205 | |
| 206 | 206 | err_vma: |
| 207 | − i915_vma_unpin_and_release(&ctch->vma); | |
| 207 | + i915_vma_unpin_and_release(&ctch->vma, 0); | |
| 208 | 208 | err_out: |
| 209 | 209 | CT_DEBUG_DRIVER("CT: channel %d initialization failed; err=%d\n", |
| 210 | 210 | ctch->owner, err); |
| @@ -214,10 +214,7 @@ err_out: · 3 unmodified lines | ||
| 214 | 214 | static void ctch_fini(struct intel_guc *guc, |
| 215 | 215 | struct intel_guc_ct_channel *ctch) |
| 216 | 216 | { |
| 217 | − GEM_BUG_ON(!ctch->vma); | |
| 218 | − | |
| 219 | − i915_gem_object_unpin_map(ctch->vma->obj); | |
| 220 | − i915_vma_unpin_and_release(&ctch->vma); | |
| 217 | + i915_vma_unpin_and_release(&ctch->vma, I915_VMA_RELEASE_MAP); | |
| 221 | 218 | } |
| 222 | 219 | |
| 223 | 220 | static int ctch_open(struct intel_guc *guc, |
| @@ -49,6 +49,7 @@ · 48 unmodified lines | ||
| 49 | 49 | #define WQ_TYPE_BATCH_BUF (0x1 << WQ_TYPE_SHIFT) |
| 50 | 50 | #define WQ_TYPE_PSEUDO (0x2 << WQ_TYPE_SHIFT) |
| 51 | 51 | #define WQ_TYPE_INORDER (0x3 << WQ_TYPE_SHIFT) |
| 52 | +#define WQ_TYPE_NOOP (0x4 << WQ_TYPE_SHIFT) | |
| 52 | 53 | #define WQ_TARGET_SHIFT 10 |
| 53 | 54 | #define WQ_LEN_SHIFT 16 |
| 54 | 55 | #define WQ_NO_WCFLUSH_WAIT (1 << 27) |
| @@ -498,7 +498,7 @@ err: · 497 unmodified lines | ||
| 498 | 498 | |
| 499 | 499 | void intel_guc_log_destroy(struct intel_guc_log *log) |
| 500 | 500 | { |
| 501 | − i915_vma_unpin_and_release(&log->vma); | |
| 501 | + i915_vma_unpin_and_release(&log->vma, 0); | |
| 502 | 502 | } |
| 503 | 503 | |
| 504 | 504 | int intel_guc_log_set_level(struct intel_guc_log *log, u32 level) |
| @@ -317,7 +317,7 @@ static int guc_stage_desc_pool_create(struct intel_guc *guc) · 316 unmodified lines | ||
| 317 | 317 | |
| 318 | 318 | vaddr = i915_gem_object_pin_map(vma->obj, I915_MAP_WB); |
| 319 | 319 | if (IS_ERR(vaddr)) { |
| 320 | − i915_vma_unpin_and_release(&vma); | |
| 320 | + i915_vma_unpin_and_release(&vma, 0); | |
| 321 | 321 | return PTR_ERR(vaddr); |
| 322 | 322 | } |
| 323 | 323 | |
| @@ -331,8 +331,7 @@ static int guc_stage_desc_pool_create(struct intel_guc *guc) · 7 unmodified lines | ||
| 331 | 331 | static void guc_stage_desc_pool_destroy(struct intel_guc *guc) |
| 332 | 332 | { |
| 333 | 333 | ida_destroy(&guc->stage_ids); |
| 334 | − i915_gem_object_unpin_map(guc->stage_desc_pool->obj); | |
| 335 | − i915_vma_unpin_and_release(&guc->stage_desc_pool); | |
| 334 | + i915_vma_unpin_and_release(&guc->stage_desc_pool, I915_VMA_RELEASE_MAP); | |
| 336 | 335 | } |
| 337 | 336 | |
| 338 | 337 | /* |
| @@ -457,6 +456,9 @@ static void guc_wq_item_append(struct intel_guc_client *client, · 118 unmodified lines | ||
| 457 | 456 | */ |
| 458 | 457 | BUILD_BUG_ON(wqi_size != 16); |
| 459 | 458 | |
| 459 | + /* We expect the WQ to be active if we're appending items to it */ | |
| 460 | + GEM_BUG_ON(desc->wq_status != WQ_STATUS_ACTIVE); | |
| 461 | + | |
| 460 | 462 | /* Free space is guaranteed. */ |
| 461 | 463 | wq_off = READ_ONCE(desc->tail); |
| 462 | 464 | GEM_BUG_ON(CIRC_SPACE(wq_off, READ_ONCE(desc->head), |
| @@ -466,15 +468,19 @@ static void guc_wq_item_append(struct intel_guc_client *client, · 3 unmodified lines | ||
| 466 | 468 | /* WQ starts from the page after doorbell / process_desc */ |
| 467 | 469 | wqi = client->vaddr + wq_off + GUC_DB_SIZE; |
| 468 | 470 | |
| 469 | − /* Now fill in the 4-word work queue item */ | |
| 470 | − wqi->header = WQ_TYPE_INORDER | | |
| 471 | − (wqi_len << WQ_LEN_SHIFT) | | |
| 472 | − (target_engine << WQ_TARGET_SHIFT) | | |
| 473 | − WQ_NO_WCFLUSH_WAIT; | |
| 474 | − wqi->context_desc = context_desc; | |
| 475 | − wqi->submit_element_info = ring_tail << WQ_RING_TAIL_SHIFT; | |
| 476 | − GEM_BUG_ON(ring_tail > WQ_RING_TAIL_MAX); | |
| 477 | − wqi->fence_id = fence_id; | |
| 471 | + if (I915_SELFTEST_ONLY(client->use_nop_wqi)) { | |
| 472 | + wqi->header = WQ_TYPE_NOOP | (wqi_len << WQ_LEN_SHIFT); | |
| 473 | + } else { | |
| 474 | + /* Now fill in the 4-word work queue item */ | |
| 475 | + wqi->header = WQ_TYPE_INORDER | | |
| 476 | + (wqi_len << WQ_LEN_SHIFT) | | |
| 477 | + (target_engine << WQ_TARGET_SHIFT) | | |
| 478 | + WQ_NO_WCFLUSH_WAIT; | |
| 479 | + wqi->context_desc = context_desc; | |
| 480 | + wqi->submit_element_info = ring_tail << WQ_RING_TAIL_SHIFT; | |
| 481 | + GEM_BUG_ON(ring_tail > WQ_RING_TAIL_MAX); | |
| 482 | + wqi->fence_id = fence_id; | |
| 483 | + } | |
| 478 | 484 | |
| 479 | 485 | /* Make the update visible to GuC */ |
| 480 | 486 | WRITE_ONCE(desc->tail, (wq_off + wqi_size) & (GUC_WQ_SIZE - 1)); |
| @@ -1008,7 +1014,7 @@ guc_client_alloc(struct drm_i915_private *dev_priv, · 527 unmodified lines | ||
| 1008 | 1014 | err_vaddr: |
| 1009 | 1015 | i915_gem_object_unpin_map(client->vma->obj); |
| 1010 | 1016 | err_vma: |
| 1011 | − i915_vma_unpin_and_release(&client->vma); | |
| 1017 | + i915_vma_unpin_and_release(&client->vma, 0); | |
| 1012 | 1018 | err_id: |
| 1013 | 1019 | ida_simple_remove(&guc->stage_ids, client->stage_id); |
| 1014 | 1020 | err_client: |
| @@ -1020,8 +1026,7 @@ static void guc_client_free(struct intel_guc_client *client) · 5 unmodified lines | ||
| 1020 | 1026 | { |
| 1021 | 1027 | unreserve_doorbell(client); |
| 1022 | 1028 | guc_stage_desc_fini(client->guc, client); |
| 1023 | − i915_gem_object_unpin_map(client->vma->obj); | |
| 1024 | − i915_vma_unpin_and_release(&client->vma); | |
| 1029 | + i915_vma_unpin_and_release(&client->vma, I915_VMA_RELEASE_MAP); | |
| 1025 | 1030 | ida_simple_remove(&client->guc->stage_ids, client->stage_id); |
| 1026 | 1031 | kfree(client); |
| 1027 | 1032 | } |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/spinlock.h> |
| 29 | 29 | |
| 30 | 30 | #include "i915_gem.h" |
| 31 | +#include "i915_selftest.h" | |
| 31 | 32 | |
| 32 | 33 | struct drm_i915_private; |
| 33 | 34 | |
| @@ -71,6 +72,9 @@ struct intel_guc_client { · 37 unmodified lines | ||
| 71 | 72 | spinlock_t wq_lock; |
| 72 | 73 | /* Per-engine counts of GuC submissions */ |
| 73 | 74 | u64 submissions[I915_NUM_ENGINES]; |
| 75 | + | |
| 76 | + /* For testing purposes, use nop WQ items instead of real ones */ | |
| 77 | + I915_SELFTEST_DECLARE(bool use_nop_wqi); | |
| 74 | 78 | }; |
| 75 | 79 | |
| 76 | 80 | int intel_guc_submission_init(struct intel_guc *guc); |
| @@ -142,7 +142,7 @@ static int semaphore_passed(struct intel_engine_cs *engine) · 141 unmodified lines | ||
| 142 | 142 | if (signaller->hangcheck.deadlock >= I915_NUM_ENGINES) |
| 143 | 143 | return -1; |
| 144 | 144 | |
| 145 | − if (i915_seqno_passed(intel_engine_get_seqno(signaller), seqno)) | |
| 145 | + if (intel_engine_signaled(signaller, seqno)) | |
| 146 | 146 | return 1; |
| 147 | 147 | |
| 148 | 148 | /* cursory check for an unkickable deadlock */ |
| @@ -57,9 +57,9 @@ static bool hdcp_key_loadable(struct drm_i915_private *dev_priv) · 56 unmodified lines | ||
| 57 | 57 | |
| 58 | 58 | /* PG1 (power well #1) needs to be enabled */ |
| 59 | 59 | for_each_power_well(dev_priv, power_well) { |
| 60 | − if (power_well->id == id) { | |
| 61 | − enabled = power_well->ops->is_enabled(dev_priv, | |
| 62 | − power_well); | |
| 60 | + if (power_well->desc->id == id) { | |
| 61 | + enabled = power_well->desc->ops->is_enabled(dev_priv, | |
| 62 | + power_well); | |
| 63 | 63 | break; |
| 64 | 64 | } |
| 65 | 65 | } |
| @@ -1911,22 +1911,26 @@ intel_hdmi_set_edid(struct drm_connector *connector) · 1910 unmodified lines | ||
| 1911 | 1911 | static enum drm_connector_status |
| 1912 | 1912 | intel_hdmi_detect(struct drm_connector *connector, bool force) |
| 1913 | 1913 | { |
| 1914 | − enum drm_connector_status status; | |
| 1914 | + enum drm_connector_status status = connector_status_disconnected; | |
| 1915 | 1915 | struct drm_i915_private *dev_priv = to_i915(connector->dev); |
| 1916 | 1916 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); |
| 1917 | + struct intel_encoder *encoder = &hdmi_to_dig_port(intel_hdmi)->base; | |
| 1917 | 1918 | |
| 1918 | 1919 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", |
| 1919 | 1920 | connector->base.id, connector->name); |
| 1920 | 1921 | |
| 1921 | 1922 | intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); |
| 1922 | 1923 | |
| 1924 | + if (IS_ICELAKE(dev_priv) && | |
| 1925 | + !intel_digital_port_connected(encoder)) | |
| 1926 | + goto out; | |
| 1927 | + | |
| 1923 | 1928 | intel_hdmi_unset_edid(connector); |
| 1924 | 1929 | |
| 1925 | 1930 | if (intel_hdmi_set_edid(connector)) |
| 1926 | 1931 | status = connector_status_connected; |
| 1927 | − else | |
| 1928 | − status = connector_status_disconnected; | |
| 1929 | 1932 | |
| 1933 | +out: | |
| 1930 | 1934 | intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); |
| 1931 | 1935 | |
| 1932 | 1936 | if (status != connector_status_connected) |
| @@ -63,7 +63,7 @@ int intel_huc_auth(struct intel_huc *huc) · 62 unmodified lines | ||
| 63 | 63 | return -ENOEXEC; |
| 64 | 64 | |
| 65 | 65 | vma = i915_gem_object_ggtt_pin(huc->fw.obj, NULL, 0, 0, |
| 66 | − PIN_OFFSET_BIAS | guc->ggtt_pin_bias); | |
| 66 | + PIN_OFFSET_BIAS | i915->ggtt.pin_bias); | |
| 67 | 67 | if (IS_ERR(vma)) { |
| 68 | 68 | ret = PTR_ERR(vma); |
| 69 | 69 | DRM_ERROR("HuC: Failed to pin huc fw object %d\n", ret); |
| @@ -37,7 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | |
| 38 | 38 | struct gmbus_pin { |
| 39 | 39 | const char *name; |
| 40 | − i915_reg_t reg; | |
| 40 | + enum i915_gpio gpio; | |
| 41 | 41 | }; |
| 42 | 42 | |
| 43 | 43 | /* Map gmbus pin pairs to names and registers. */ |
| @@ -121,8 +121,7 @@ bool intel_gmbus_is_valid_pin(struct drm_i915_private *dev_priv, · 77 unmodified lines | ||
| 121 | 121 | else |
| 122 | 122 | size = ARRAY_SIZE(gmbus_pins); |
| 123 | 123 | |
| 124 | − return pin < size && | |
| 125 | − i915_mmio_reg_valid(get_gmbus_pin(dev_priv, pin)->reg); | |
| 124 | + return pin < size && get_gmbus_pin(dev_priv, pin)->name; | |
| 126 | 125 | } |
| 127 | 126 | |
| 128 | 127 | /* Intel GPIO access functions */ |
| @@ -292,8 +291,7 @@ intel_gpio_setup(struct intel_gmbus *bus, unsigned int pin) · 163 unmodified lines | ||
| 292 | 291 | |
| 293 | 292 | algo = &bus->bit_algo; |
| 294 | 293 | |
| 295 | − bus->gpio_reg = _MMIO(dev_priv->gpio_mmio_base + | |
| 296 | − i915_mmio_reg_offset(get_gmbus_pin(dev_priv, pin)->reg)); | |
| 294 | + bus->gpio_reg = GPIO(get_gmbus_pin(dev_priv, pin)->gpio); | |
| 297 | 295 | bus->adapter.algo_data = algo; |
| 298 | 296 | algo->setsda = set_data; |
| 299 | 297 | algo->setscl = set_clock; |
| @@ -825,9 +823,11 @@ int intel_setup_gmbus(struct drm_i915_private *dev_priv) · 525 unmodified lines | ||
| 825 | 823 | if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) |
| 826 | 824 | dev_priv->gpio_mmio_base = VLV_DISPLAY_BASE; |
| 827 | 825 | else if (!HAS_GMCH_DISPLAY(dev_priv)) |
| 828 | − dev_priv->gpio_mmio_base = | |
| 829 | − i915_mmio_reg_offset(PCH_GPIOA) - | |
| 830 | − i915_mmio_reg_offset(GPIOA); | |
| 826 | + /* | |
| 827 | + * Broxton uses the same PCH offsets for South Display Engine, | |
| 828 | + * even though it doesn't have a PCH. | |
| 829 | + */ | |
| 830 | + dev_priv->gpio_mmio_base = PCH_DISPLAY_BASE; | |
| 831 | 831 | |
| 832 | 832 | mutex_init(&dev_priv->gmbus_mutex); |
| 833 | 833 | init_waitqueue_head(&dev_priv->gmbus_wait_queue); |
| @@ -541,11 +541,6 @@ static void inject_preempt_context(struct intel_engine_cs *engine) · 540 unmodified lines | ||
| 541 | 541 | |
| 542 | 542 | GEM_BUG_ON(execlists->preempt_complete_status != |
| 543 | 543 | upper_32_bits(ce->lrc_desc)); |
| 544 | − GEM_BUG_ON((ce->lrc_reg_state[CTX_CONTEXT_CONTROL + 1] & | |
| 545 | − _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT | | |
| 546 | − CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT)) != | |
| 547 | − _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT | | |
| 548 | − CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT)); | |
| 549 | 544 | |
| 550 | 545 | /* |
| 551 | 546 | * Switch to our empty preempt context so |
| @@ -1277,6 +1272,8 @@ static void execlists_context_destroy(struct intel_context *ce) · 725 unmodified lines | ||
| 1277 | 1272 | |
| 1278 | 1273 | static void execlists_context_unpin(struct intel_context *ce) |
| 1279 | 1274 | { |
| 1275 | + i915_gem_context_unpin_hw_id(ce->gem_context); | |
| 1276 | + | |
| 1280 | 1277 | intel_ring_unpin(ce->ring); |
| 1281 | 1278 | |
| 1282 | 1279 | ce->state->obj->pin_global--; |
| @@ -1303,10 +1300,9 @@ static int __context_pin(struct i915_gem_context *ctx, struct i915_vma *vma) · 20 unmodified lines | ||
| 1303 | 1300 | } |
| 1304 | 1301 | |
| 1305 | 1302 | flags = PIN_GLOBAL | PIN_HIGH; |
| 1306 | − if (ctx->ggtt_offset_bias) | |
| 1307 | − flags |= PIN_OFFSET_BIAS | ctx->ggtt_offset_bias; | |
| 1303 | + flags |= PIN_OFFSET_BIAS | i915_ggtt_pin_bias(vma); | |
| 1308 | 1304 | |
| 1309 | − return i915_vma_pin(vma, 0, GEN8_LR_CONTEXT_ALIGN, flags); | |
| 1305 | + return i915_vma_pin(vma, 0, 0, flags); | |
| 1310 | 1306 | } |
| 1311 | 1307 | |
| 1312 | 1308 | static struct intel_context * |
| @@ -1332,10 +1328,14 @@ __execlists_context_pin(struct intel_engine_cs *engine, · 19 unmodified lines | ||
| 1332 | 1328 | goto unpin_vma; |
| 1333 | 1329 | } |
| 1334 | 1330 | |
| 1335 | − ret = intel_ring_pin(ce->ring, ctx->i915, ctx->ggtt_offset_bias); | |
| 1331 | + ret = intel_ring_pin(ce->ring); | |
| 1336 | 1332 | if (ret) |
| 1337 | 1333 | goto unpin_map; |
| 1338 | 1334 | |
| 1335 | + ret = i915_gem_context_pin_hw_id(ctx); | |
| 1336 | + if (ret) | |
| 1337 | + goto unpin_ring; | |
| 1338 | + | |
| 1339 | 1339 | intel_lr_context_descriptor_update(ctx, engine, ce); |
| 1340 | 1340 | |
| 1341 | 1341 | ce->lrc_reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE; |
| @@ -1348,6 +1348,8 @@ __execlists_context_pin(struct intel_engine_cs *engine, · 6 unmodified lines | ||
| 1348 | 1348 | i915_gem_context_get(ctx); |
| 1349 | 1349 | return ce; |
| 1350 | 1350 | |
| 1351 | +unpin_ring: | |
| 1352 | + intel_ring_unpin(ce->ring); | |
| 1351 | 1353 | unpin_map: |
| 1352 | 1354 | i915_gem_object_unpin_map(ce->state->obj); |
| 1353 | 1355 | unpin_vma: |
| @@ -1643,7 +1645,7 @@ static int lrc_setup_wa_ctx(struct intel_engine_cs *engine) · 289 unmodified lines | ||
| 1643 | 1645 | goto err; |
| 1644 | 1646 | } |
| 1645 | 1647 | |
| 1646 | − err = i915_vma_pin(vma, 0, PAGE_SIZE, PIN_GLOBAL | PIN_HIGH); | |
| 1648 | + err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH); | |
| 1647 | 1649 | if (err) |
| 1648 | 1650 | goto err; |
| 1649 | 1651 | |
| @@ -1657,7 +1659,7 @@ err: · 7 unmodified lines | ||
| 1657 | 1659 | |
| 1658 | 1660 | static void lrc_destroy_wa_ctx(struct intel_engine_cs *engine) |
| 1659 | 1661 | { |
| 1660 | − i915_vma_unpin_and_release(&engine->wa_ctx.vma); | |
| 1662 | + i915_vma_unpin_and_release(&engine->wa_ctx.vma, 0); | |
| 1661 | 1663 | } |
| 1662 | 1664 | |
| 1663 | 1665 | typedef u32 *(*wa_bb_func_t)(struct intel_engine_cs *engine, u32 *batch); |
| @@ -1775,11 +1777,7 @@ static bool unexpected_starting_state(struct intel_engine_cs *engine) · 111 unmodified lines | ||
| 1775 | 1777 | |
| 1776 | 1778 | static int gen8_init_common_ring(struct intel_engine_cs *engine) |
| 1777 | 1779 | { |
| 1778 | − int ret; | |
| 1779 | − | |
| 1780 | − ret = intel_mocs_init_engine(engine); | |
| 1781 | − if (ret) | |
| 1782 | − return ret; | |
| 1780 | + intel_mocs_init_engine(engine); | |
| 1783 | 1781 | |
| 1784 | 1782 | intel_engine_reset_breadcrumbs(engine); |
| 1785 | 1783 | |
| @@ -1838,7 +1836,8 @@ execlists_reset_prepare(struct intel_engine_cs *engine) · 52 unmodified lines | ||
| 1838 | 1836 | struct i915_request *request, *active; |
| 1839 | 1837 | unsigned long flags; |
| 1840 | 1838 | |
| 1841 | − GEM_TRACE("%s\n", engine->name); | |
| 1839 | + GEM_TRACE("%s: depth<-%d\n", engine->name, | |
| 1840 | + atomic_read(&execlists->tasklet.count)); | |
| 1842 | 1841 | |
| 1843 | 1842 | /* |
| 1844 | 1843 | * Prevent request submission to the hardware until we have |
| @@ -1971,22 +1970,18 @@ static void execlists_reset_finish(struct intel_engine_cs *engine) · 126 unmodified lines | ||
| 1971 | 1970 | { |
| 1972 | 1971 | struct intel_engine_execlists * const execlists = &engine->execlists; |
| 1973 | 1972 | |
| 1974 | − /* After a GPU reset, we may have requests to replay */ | |
| 1975 | − if (!RB_EMPTY_ROOT(&execlists->queue.rb_root)) | |
| 1976 | − tasklet_schedule(&execlists->tasklet); | |
| 1977 | − | |
| 1978 | 1973 | /* |
| 1979 | − * Flush the tasklet while we still have the forcewake to be sure | |
| 1980 | − * that it is not allowed to sleep before we restart and reload a | |
| 1981 | − * context. | |
| 1974 | + * After a GPU reset, we may have requests to replay. Do so now while | |
| 1975 | + * we still have the forcewake to be sure that the GPU is not allowed | |
| 1976 | + * to sleep before we restart and reload a context. | |
| 1982 | 1977 | * |
| 1983 | − * As before (with execlists_reset_prepare) we rely on the caller | |
| 1984 | − * serialising multiple attempts to reset so that we know that we | |
| 1985 | − * are the only one manipulating tasklet state. | |
| 1986 | 1978 | */ |
| 1987 | − __tasklet_enable_sync_once(&execlists->tasklet); | |
| 1979 | + if (!RB_EMPTY_ROOT(&execlists->queue.rb_root)) | |
| 1980 | + execlists->tasklet.func(execlists->tasklet.data); | |
| 1988 | 1981 | |
| 1989 | − GEM_TRACE("%s\n", engine->name); | |
| 1982 | + tasklet_enable(&execlists->tasklet); | |
| 1983 | + GEM_TRACE("%s: depth->%d\n", engine->name, | |
| 1984 | + atomic_read(&execlists->tasklet.count)); | |
| 1990 | 1985 | } |
| 1991 | 1986 | |
| 1992 | 1987 | static int intel_logical_ring_emit_pdps(struct i915_request *rq) |
| @@ -2066,8 +2061,7 @@ static int gen8_emit_bb_start(struct i915_request *rq, · 73 unmodified lines | ||
| 2066 | 2061 | |
| 2067 | 2062 | /* FIXME(BDW): Address space and security selectors. */ |
| 2068 | 2063 | *cs++ = MI_BATCH_BUFFER_START_GEN8 | |
| 2069 | − (flags & I915_DISPATCH_SECURE ? 0 : BIT(8)) | | |
| 2070 | − (flags & I915_DISPATCH_RS ? MI_BATCH_RESOURCE_STREAMER : 0); | |
| 2064 | + (flags & I915_DISPATCH_SECURE ? 0 : BIT(8)); | |
| 2071 | 2065 | *cs++ = lower_32_bits(offset); |
| 2072 | 2066 | *cs++ = upper_32_bits(offset); |
| 2073 | 2067 | |
| @@ -2494,6 +2488,9 @@ int logical_xcs_ring_init(struct intel_engine_cs *engine) · 420 unmodified lines | ||
| 2494 | 2488 | static u32 |
| 2495 | 2489 | make_rpcs(struct drm_i915_private *dev_priv) |
| 2496 | 2490 | { |
| 2491 | + bool subslice_pg = INTEL_INFO(dev_priv)->sseu.has_subslice_pg; | |
| 2492 | + u8 slices = hweight8(INTEL_INFO(dev_priv)->sseu.slice_mask); | |
| 2493 | + u8 subslices = hweight8(INTEL_INFO(dev_priv)->sseu.subslice_mask[0]); | |
| 2497 | 2494 | u32 rpcs = 0; |
| 2498 | 2495 | |
| 2499 | 2496 | /* |
| @@ -2503,6 +2500,38 @@ make_rpcs(struct drm_i915_private *dev_priv) · 3 unmodified lines | ||
| 2503 | 2500 | if (INTEL_GEN(dev_priv) < 9) |
| 2504 | 2501 | return 0; |
| 2505 | 2502 | |
| 2503 | + /* | |
| 2504 | + * Since the SScount bitfield in GEN8_R_PWR_CLK_STATE is only three bits | |
| 2505 | + * wide and Icelake has up to eight subslices, specfial programming is | |
| 2506 | + * needed in order to correctly enable all subslices. | |
| 2507 | + * | |
| 2508 | + * According to documentation software must consider the configuration | |
| 2509 | + * as 2x4x8 and hardware will translate this to 1x8x8. | |
| 2510 | + * | |
| 2511 | + * Furthemore, even though SScount is three bits, maximum documented | |
| 2512 | + * value for it is four. From this some rules/restrictions follow: | |
| 2513 | + * | |
| 2514 | + * 1. | |
| 2515 | + * If enabled subslice count is greater than four, two whole slices must | |
| 2516 | + * be enabled instead. | |
| 2517 | + * | |
| 2518 | + * 2. | |
| 2519 | + * When more than one slice is enabled, hardware ignores the subslice | |
| 2520 | + * count altogether. | |
| 2521 | + * | |
| 2522 | + * From these restrictions it follows that it is not possible to enable | |
| 2523 | + * a count of subslices between the SScount maximum of four restriction, | |
| 2524 | + * and the maximum available number on a particular SKU. Either all | |
| 2525 | + * subslices are enabled, or a count between one and four on the first | |
| 2526 | + * slice. | |
| 2527 | + */ | |
| 2528 | + if (IS_GEN11(dev_priv) && slices == 1 && subslices >= 4) { | |
| 2529 | + GEM_BUG_ON(subslices & 1); | |
| 2530 | + | |
| 2531 | + subslice_pg = false; | |
| 2532 | + slices *= 2; | |
| 2533 | + } | |
| 2534 | + | |
| 2506 | 2535 | /* |
| 2507 | 2536 | * Starting in Gen9, render power gating can leave |
| 2508 | 2537 | * slice/subslice/EU in a partially enabled state. We |
| @@ -2510,24 +2539,50 @@ make_rpcs(struct drm_i915_private *dev_priv) · 1 unmodified line | ||
| 2510 | 2539 | * enablement. |
| 2511 | 2540 | */ |
| 2512 | 2541 | if (INTEL_INFO(dev_priv)->sseu.has_slice_pg) { |
| 2513 | − rpcs |= GEN8_RPCS_S_CNT_ENABLE; | |
| 2514 | − rpcs |= hweight8(INTEL_INFO(dev_priv)->sseu.slice_mask) << | |
| 2515 | − GEN8_RPCS_S_CNT_SHIFT; | |
| 2516 | − rpcs |= GEN8_RPCS_ENABLE; | |
| 2542 | + u32 mask, val = slices; | |
| 2543 | + | |
| 2544 | + if (INTEL_GEN(dev_priv) >= 11) { | |
| 2545 | + mask = GEN11_RPCS_S_CNT_MASK; | |
| 2546 | + val <<= GEN11_RPCS_S_CNT_SHIFT; | |
| 2547 | + } else { | |
| 2548 | + mask = GEN8_RPCS_S_CNT_MASK; | |
| 2549 | + val <<= GEN8_RPCS_S_CNT_SHIFT; | |
| 2550 | + } | |
| 2551 | + | |
| 2552 | + GEM_BUG_ON(val & ~mask); | |
| 2553 | + val &= mask; | |
| 2554 | + | |
| 2555 | + rpcs |= GEN8_RPCS_ENABLE | GEN8_RPCS_S_CNT_ENABLE | val; | |
| 2517 | 2556 | } |
| 2518 | 2557 | |
| 2519 | − if (INTEL_INFO(dev_priv)->sseu.has_subslice_pg) { | |
| 2520 | − rpcs |= GEN8_RPCS_SS_CNT_ENABLE; | |
| 2521 | − rpcs |= hweight8(INTEL_INFO(dev_priv)->sseu.subslice_mask[0]) << | |
| 2522 | − GEN8_RPCS_SS_CNT_SHIFT; | |
| 2523 | − rpcs |= GEN8_RPCS_ENABLE; | |
| 2558 | + if (subslice_pg) { | |
| 2559 | + u32 val = subslices; | |
| 2560 | + | |
| 2561 | + val <<= GEN8_RPCS_SS_CNT_SHIFT; | |
| 2562 | + | |
| 2563 | + GEM_BUG_ON(val & ~GEN8_RPCS_SS_CNT_MASK); | |
| 2564 | + val &= GEN8_RPCS_SS_CNT_MASK; | |
| 2565 | + | |
| 2566 | + rpcs |= GEN8_RPCS_ENABLE | GEN8_RPCS_SS_CNT_ENABLE | val; | |
| 2524 | 2567 | } |
| 2525 | 2568 | |
| 2526 | 2569 | if (INTEL_INFO(dev_priv)->sseu.has_eu_pg) { |
| 2527 | − rpcs |= INTEL_INFO(dev_priv)->sseu.eu_per_subslice << | |
| 2528 | − GEN8_RPCS_EU_MIN_SHIFT; | |
| 2529 | − rpcs |= INTEL_INFO(dev_priv)->sseu.eu_per_subslice << | |
| 2530 | − GEN8_RPCS_EU_MAX_SHIFT; | |
| 2570 | + u32 val; | |
| 2571 | + | |
| 2572 | + val = INTEL_INFO(dev_priv)->sseu.eu_per_subslice << | |
| 2573 | + GEN8_RPCS_EU_MIN_SHIFT; | |
| 2574 | + GEM_BUG_ON(val & ~GEN8_RPCS_EU_MIN_MASK); | |
| 2575 | + val &= GEN8_RPCS_EU_MIN_MASK; | |
| 2576 | + | |
| 2577 | + rpcs |= val; | |
| 2578 | + | |
| 2579 | + val = INTEL_INFO(dev_priv)->sseu.eu_per_subslice << | |
| 2580 | + GEN8_RPCS_EU_MAX_SHIFT; | |
| 2581 | + GEM_BUG_ON(val & ~GEN8_RPCS_EU_MAX_MASK); | |
| 2582 | + val &= GEN8_RPCS_EU_MAX_MASK; | |
| 2583 | + | |
| 2584 | + rpcs |= val; | |
| 2585 | + | |
| 2531 | 2586 | rpcs |= GEN8_RPCS_ENABLE; |
| 2532 | 2587 | } |
| 2533 | 2588 | |
| @@ -2584,11 +2639,13 @@ static void execlists_init_reg_state(u32 *regs, · 50 unmodified lines | ||
| 2584 | 2639 | MI_LRI_FORCE_POSTED; |
| 2585 | 2640 | |
| 2586 | 2641 | CTX_REG(regs, CTX_CONTEXT_CONTROL, RING_CONTEXT_CONTROL(engine), |
| 2587 | − _MASKED_BIT_DISABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT | | |
| 2588 | − CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT) | | |
| 2589 | − _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH | | |
| 2590 | − (HAS_RESOURCE_STREAMER(dev_priv) ? | |
| 2591 | − CTX_CTRL_RS_CTX_ENABLE : 0))); | |
| 2642 | + _MASKED_BIT_DISABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT) | | |
| 2643 | + _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH)); | |
| 2644 | + if (INTEL_GEN(dev_priv) < 11) { | |
| 2645 | + regs[CTX_CONTEXT_CONTROL + 1] |= | |
| 2646 | + _MASKED_BIT_DISABLE(CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT | | |
| 2647 | + CTX_CTRL_RS_CTX_ENABLE); | |
| 2648 | + } | |
| 2592 | 2649 | CTX_REG(regs, CTX_RING_HEAD, RING_HEAD(base), 0); |
| 2593 | 2650 | CTX_REG(regs, CTX_RING_TAIL, RING_TAIL(base), 0); |
| 2594 | 2651 | CTX_REG(regs, CTX_RING_BUFFER_START, RING_START(base), 0); |
| @@ -2654,6 +2711,10 @@ static void execlists_init_reg_state(u32 *regs, · 59 unmodified lines | ||
| 2654 | 2711 | |
| 2655 | 2712 | i915_oa_init_reg_state(engine, ctx, regs); |
| 2656 | 2713 | } |
| 2714 | + | |
| 2715 | + regs[CTX_END] = MI_BATCH_BUFFER_END; | |
| 2716 | + if (INTEL_GEN(dev_priv) >= 10) | |
| 2717 | + regs[CTX_END] |= BIT(0); | |
| 2657 | 2718 | } |
| 2658 | 2719 | |
| 2659 | 2720 | static int |
| @@ -27,8 +27,6 @@ · 26 unmodified lines | ||
| 27 | 27 | #include "intel_ringbuffer.h" |
| 28 | 28 | #include "i915_gem_context.h" |
| 29 | 29 | |
| 30 | −#define GEN8_LR_CONTEXT_ALIGN I915_GTT_MIN_ALIGNMENT | |
| 31 | − | |
| 32 | 30 | /* Execlists regs */ |
| 33 | 31 | #define RING_ELSP(engine) _MMIO((engine)->mmio_base + 0x230) |
| 34 | 32 | #define RING_EXECLIST_STATUS_LO(engine) _MMIO((engine)->mmio_base + 0x234) |
| @@ -37,7 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | #define CTX_PDP0_LDW 0x32 |
| 38 | 38 | #define CTX_LRI_HEADER_2 0x41 |
| 39 | 39 | #define CTX_R_PWR_CLK_STATE 0x42 |
| 40 | −#define CTX_GPGPU_CSR_BASE_ADDRESS 0x44 | |
| 40 | +#define CTX_END 0x44 | |
| 41 | 41 | |
| 42 | 42 | #define CTX_REG(reg_state, pos, reg, val) do { \ |
| 43 | 43 | u32 *reg_state__ = (reg_state); \ |
| @@ -232,20 +232,17 @@ static i915_reg_t mocs_register(enum intel_engine_id engine_id, int index) · 231 unmodified lines | ||
| 232 | 232 | * |
| 233 | 233 | * This function simply emits a MI_LOAD_REGISTER_IMM command for the |
| 234 | 234 | * given table starting at the given address. |
| 235 | − * | |
| 236 | − * Return: 0 on success, otherwise the error status. | |
| 237 | 235 | */ |
| 238 | −int intel_mocs_init_engine(struct intel_engine_cs *engine) | |
| 236 | +void intel_mocs_init_engine(struct intel_engine_cs *engine) | |
| 239 | 237 | { |
| 240 | 238 | struct drm_i915_private *dev_priv = engine->i915; |
| 241 | 239 | struct drm_i915_mocs_table table; |
| 242 | 240 | unsigned int index; |
| 243 | 241 | |
| 244 | 242 | if (!get_mocs_settings(dev_priv, &table)) |
| 245 | − return 0; | |
| 243 | + return; | |
| 246 | 244 | |
| 247 | − if (WARN_ON(table.size > GEN9_NUM_MOCS_ENTRIES)) | |
| 248 | − return -ENODEV; | |
| 245 | + GEM_BUG_ON(table.size > GEN9_NUM_MOCS_ENTRIES); | |
| 249 | 246 | |
| 250 | 247 | for (index = 0; index < table.size; index++) |
| 251 | 248 | I915_WRITE(mocs_register(engine->id, index), |
| @@ -262,8 +259,6 @@ int intel_mocs_init_engine(struct intel_engine_cs *engine) · 10 unmodified lines | ||
| 262 | 259 | for (; index < GEN9_NUM_MOCS_ENTRIES; index++) |
| 263 | 260 | I915_WRITE(mocs_register(engine->id, index), |
| 264 | 261 | table.table[0].control_value); |
| 265 | − | |
| 266 | − return 0; | |
| 267 | 262 | } |
| 268 | 263 | |
| 269 | 264 | /** |
| @@ -54,6 +54,6 @@ · 53 unmodified lines | ||
| 54 | 54 | |
| 55 | 55 | int intel_rcs_context_init_mocs(struct i915_request *rq); |
| 56 | 56 | void intel_mocs_init_l3cc_table(struct drm_i915_private *dev_priv); |
| 57 | −int intel_mocs_init_engine(struct intel_engine_cs *engine); | |
| 57 | +void intel_mocs_init_engine(struct intel_engine_cs *engine); | |
| 58 | 58 | |
| 59 | 59 | #endif |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | */ |
| 27 | 27 | |
| 28 | 28 | #include <linux/cpufreq.h> |
| 29 | +#include <linux/pm_runtime.h> | |
| 29 | 30 | #include <drm/drm_plane_helper.h> |
| 30 | 31 | #include "i915_drv.h" |
| 31 | 32 | #include "intel_drv.h" |
| @@ -2942,8 +2943,8 @@ static void intel_print_wm_latency(struct drm_i915_private *dev_priv, · 2910 unmodified lines | ||
| 2942 | 2943 | unsigned int latency = wm[level]; |
| 2943 | 2944 | |
| 2944 | 2945 | if (latency == 0) { |
| 2945 | − DRM_ERROR("%s WM%d latency not provided\n", | |
| 2946 | − name, level); | |
| 2946 | + DRM_DEBUG_KMS("%s WM%d latency not provided\n", | |
| 2947 | + name, level); | |
| 2947 | 2948 | continue; |
| 2948 | 2949 | } |
| 2949 | 2950 | |
| @@ -3771,11 +3772,11 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state) · 821 unmodified lines | ||
| 3771 | 3772 | return true; |
| 3772 | 3773 | } |
| 3773 | 3774 | |
| 3774 | −static unsigned int intel_get_ddb_size(struct drm_i915_private *dev_priv, | |
| 3775 | − const struct intel_crtc_state *cstate, | |
| 3776 | − const unsigned int total_data_rate, | |
| 3777 | − const int num_active, | |
| 3778 | − struct skl_ddb_allocation *ddb) | |
| 3775 | +static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv, | |
| 3776 | + const struct intel_crtc_state *cstate, | |
| 3777 | + const unsigned int total_data_rate, | |
| 3778 | + const int num_active, | |
| 3779 | + struct skl_ddb_allocation *ddb) | |
| 3779 | 3780 | { |
| 3780 | 3781 | const struct drm_display_mode *adjusted_mode; |
| 3781 | 3782 | u64 total_data_bw; |
| @@ -3814,8 +3815,12 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, · 32 unmodified lines | ||
| 3814 | 3815 | struct intel_atomic_state *intel_state = to_intel_atomic_state(state); |
| 3815 | 3816 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 3816 | 3817 | struct drm_crtc *for_crtc = cstate->base.crtc; |
| 3817 | − unsigned int pipe_size, ddb_size; | |
| 3818 | − int nth_active_pipe; | |
| 3818 | + const struct drm_crtc_state *crtc_state; | |
| 3819 | + const struct drm_crtc *crtc; | |
| 3820 | + u32 pipe_width = 0, total_width = 0, width_before_pipe = 0; | |
| 3821 | + enum pipe for_pipe = to_intel_crtc(for_crtc)->pipe; | |
| 3822 | + u16 ddb_size; | |
| 3823 | + u32 i; | |
| 3819 | 3824 | |
| 3820 | 3825 | if (WARN_ON(!state) || !cstate->base.active) { |
| 3821 | 3826 | alloc->start = 0; |
| @@ -3833,14 +3838,14 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, · 11 unmodified lines | ||
| 3833 | 3838 | *num_active, ddb); |
| 3834 | 3839 | |
| 3835 | 3840 | /* |
| 3836 | − * If the state doesn't change the active CRTC's, then there's | |
| 3837 | − * no need to recalculate; the existing pipe allocation limits | |
| 3838 | − * should remain unchanged. Note that we're safe from racing | |
| 3839 | − * commits since any racing commit that changes the active CRTC | |
| 3840 | − * list would need to grab _all_ crtc locks, including the one | |
| 3841 | − * we currently hold. | |
| 3841 | + * If the state doesn't change the active CRTC's or there is no | |
| 3842 | + * modeset request, then there's no need to recalculate; | |
| 3843 | + * the existing pipe allocation limits should remain unchanged. | |
| 3844 | + * Note that we're safe from racing commits since any racing commit | |
| 3845 | + * that changes the active CRTC list or do modeset would need to | |
| 3846 | + * grab _all_ crtc locks, including the one we currently hold. | |
| 3842 | 3847 | */ |
| 3843 | − if (!intel_state->active_pipe_changes) { | |
| 3848 | + if (!intel_state->active_pipe_changes && !intel_state->modeset) { | |
| 3844 | 3849 | /* |
| 3845 | 3850 | * alloc may be cleared by clear_intel_crtc_state, |
| 3846 | 3851 | * copy from old state to be sure |
| @@ -3849,11 +3854,32 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, · 2 unmodified lines | ||
| 3849 | 3854 | return; |
| 3850 | 3855 | } |
| 3851 | 3856 | |
| 3852 | − nth_active_pipe = hweight32(intel_state->active_crtcs & | |
| 3853 | − (drm_crtc_mask(for_crtc) - 1)); | |
| 3854 | − pipe_size = ddb_size / hweight32(intel_state->active_crtcs); | |
| 3855 | − alloc->start = nth_active_pipe * ddb_size / *num_active; | |
| 3856 | − alloc->end = alloc->start + pipe_size; | |
| 3857 | + /* | |
| 3858 | + * Watermark/ddb requirement highly depends upon width of the | |
| 3859 | + * framebuffer, So instead of allocating DDB equally among pipes | |
| 3860 | + * distribute DDB based on resolution/width of the display. | |
| 3861 | + */ | |
| 3862 | + for_each_new_crtc_in_state(state, crtc, crtc_state, i) { | |
| 3863 | + const struct drm_display_mode *adjusted_mode; | |
| 3864 | + int hdisplay, vdisplay; | |
| 3865 | + enum pipe pipe; | |
| 3866 | + | |
| 3867 | + if (!crtc_state->enable) | |
| 3868 | + continue; | |
| 3869 | + | |
| 3870 | + pipe = to_intel_crtc(crtc)->pipe; | |
| 3871 | + adjusted_mode = &crtc_state->adjusted_mode; | |
| 3872 | + drm_mode_get_hv_timing(adjusted_mode, &hdisplay, &vdisplay); | |
| 3873 | + total_width += hdisplay; | |
| 3874 | + | |
| 3875 | + if (pipe < for_pipe) | |
| 3876 | + width_before_pipe += hdisplay; | |
| 3877 | + else if (pipe == for_pipe) | |
| 3878 | + pipe_width = hdisplay; | |
| 3879 | + } | |
| 3880 | + | |
| 3881 | + alloc->start = ddb_size * width_before_pipe / total_width; | |
| 3882 | + alloc->end = ddb_size * (width_before_pipe + pipe_width) / total_width; | |
| 3857 | 3883 | } |
| 3858 | 3884 | |
| 3859 | 3885 | static unsigned int skl_cursor_allocation(int num_active) |
| @@ -3909,7 +3935,12 @@ skl_ddb_get_hw_plane_state(struct drm_i915_private *dev_priv, · 49 unmodified lines | ||
| 3909 | 3935 | val & PLANE_CTL_ALPHA_MASK); |
| 3910 | 3936 | |
| 3911 | 3937 | val = I915_READ(PLANE_BUF_CFG(pipe, plane_id)); |
| 3912 | − val2 = I915_READ(PLANE_NV12_BUF_CFG(pipe, plane_id)); | |
| 3938 | + /* | |
| 3939 | + * FIXME: add proper NV12 support for ICL. Avoid reading unclaimed | |
| 3940 | + * registers for now. | |
| 3941 | + */ | |
| 3942 | + if (INTEL_GEN(dev_priv) < 11) | |
| 3943 | + val2 = I915_READ(PLANE_NV12_BUF_CFG(pipe, plane_id)); | |
| 3913 | 3944 | |
| 3914 | 3945 | if (fourcc == DRM_FORMAT_NV12) { |
| 3915 | 3946 | skl_ddb_entry_init_from_hw(dev_priv, |
| @@ -4977,6 +5008,7 @@ static void skl_write_plane_wm(struct intel_crtc *intel_crtc, · 1061 unmodified lines | ||
| 4977 | 5008 | |
| 4978 | 5009 | skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id), |
| 4979 | 5010 | &ddb->plane[pipe][plane_id]); |
| 5011 | + /* FIXME: add proper NV12 support for ICL. */ | |
| 4980 | 5012 | if (INTEL_GEN(dev_priv) >= 11) |
| 4981 | 5013 | return skl_ddb_entry_write(dev_priv, |
| 4982 | 5014 | PLANE_BUF_CFG(pipe, plane_id), |
| @@ -5141,17 +5173,6 @@ skl_compute_ddb(struct drm_atomic_state *state) · 158 unmodified lines | ||
| 5141 | 5173 | return 0; |
| 5142 | 5174 | } |
| 5143 | 5175 | |
| 5144 | −static void | |
| 5145 | −skl_copy_ddb_for_pipe(struct skl_ddb_values *dst, | |
| 5146 | − struct skl_ddb_values *src, | |
| 5147 | − enum pipe pipe) | |
| 5148 | −{ | |
| 5149 | − memcpy(dst->ddb.uv_plane[pipe], src->ddb.uv_plane[pipe], | |
| 5150 | − sizeof(dst->ddb.uv_plane[pipe])); | |
| 5151 | − memcpy(dst->ddb.plane[pipe], src->ddb.plane[pipe], | |
| 5152 | − sizeof(dst->ddb.plane[pipe])); | |
| 5153 | −} | |
| 5154 | − | |
| 5155 | 5176 | static void |
| 5156 | 5177 | skl_print_wm_changes(const struct drm_atomic_state *state) |
| 5157 | 5178 | { |
| @@ -5259,7 +5280,7 @@ skl_ddb_add_affected_pipes(struct drm_atomic_state *state, bool *changed) · 101 unmodified lines | ||
| 5259 | 5280 | * any other display updates race with this transaction, so we need |
| 5260 | 5281 | * to grab the lock on *all* CRTC's. |
| 5261 | 5282 | */ |
| 5262 | − if (intel_state->active_pipe_changes) { | |
| 5283 | + if (intel_state->active_pipe_changes || intel_state->modeset) { | |
| 5263 | 5284 | realloc_pipes = ~0; |
| 5264 | 5285 | intel_state->wm_results.dirty_pipes = ~0; |
| 5265 | 5286 | } |
| @@ -5381,7 +5402,10 @@ static void skl_initial_wm(struct intel_atomic_state *state, · 115 unmodified lines | ||
| 5381 | 5402 | if (cstate->base.active_changed) |
| 5382 | 5403 | skl_atomic_update_crtc_wm(state, cstate); |
| 5383 | 5404 | |
| 5384 | − skl_copy_ddb_for_pipe(hw_vals, results, pipe); | |
| 5405 | + memcpy(hw_vals->ddb.uv_plane[pipe], results->ddb.uv_plane[pipe], | |
| 5406 | + sizeof(hw_vals->ddb.uv_plane[pipe])); | |
| 5407 | + memcpy(hw_vals->ddb.plane[pipe], results->ddb.plane[pipe], | |
| 5408 | + sizeof(hw_vals->ddb.plane[pipe])); | |
| 5385 | 5409 | |
| 5386 | 5410 | mutex_unlock(&dev_priv->wm.wm_mutex); |
| 5387 | 5411 | } |
| @@ -6379,7 +6403,6 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) · 991 unmodified lines | ||
| 6379 | 6403 | new_power = HIGH_POWER; |
| 6380 | 6404 | rps_set_power(dev_priv, new_power); |
| 6381 | 6405 | mutex_unlock(&rps->power.mutex); |
| 6382 | − rps->last_adj = 0; | |
| 6383 | 6406 | } |
| 6384 | 6407 | |
| 6385 | 6408 | void intel_rps_mark_interactive(struct drm_i915_private *i915, bool interactive) |
| @@ -8159,7 +8182,7 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv) · 1773 unmodified lines | ||
| 8159 | 8182 | */ |
| 8160 | 8183 | if (!sanitize_rc6(dev_priv)) { |
| 8161 | 8184 | DRM_INFO("RC6 disabled, disabling runtime PM support\n"); |
| 8162 | − intel_runtime_pm_get(dev_priv); | |
| 8185 | + pm_runtime_get(&dev_priv->drm.pdev->dev); | |
| 8163 | 8186 | } |
| 8164 | 8187 | |
| 8165 | 8188 | mutex_lock(&dev_priv->pcu_lock); |
| @@ -8211,7 +8234,7 @@ void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv) · 45 unmodified lines | ||
| 8211 | 8234 | valleyview_cleanup_gt_powersave(dev_priv); |
| 8212 | 8235 | |
| 8213 | 8236 | if (!HAS_RC6(dev_priv)) |
| 8214 | − intel_runtime_pm_put(dev_priv); | |
| 8237 | + pm_runtime_put(&dev_priv->drm.pdev->dev); | |
| 8215 | 8238 | } |
| 8216 | 8239 | |
| 8217 | 8240 | /** |
| @@ -8238,7 +8261,7 @@ void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv) · 20 unmodified lines | ||
| 8238 | 8261 | |
| 8239 | 8262 | if (INTEL_GEN(dev_priv) >= 11) |
| 8240 | 8263 | gen11_reset_rps_interrupts(dev_priv); |
| 8241 | − else | |
| 8264 | + else if (INTEL_GEN(dev_priv) >= 6) | |
| 8242 | 8265 | gen6_reset_rps_interrupts(dev_priv); |
| 8243 | 8266 | } |
| 8244 | 8267 | |
| @@ -56,7 +56,30 @@ · 55 unmodified lines | ||
| 56 | 56 | #include "intel_drv.h" |
| 57 | 57 | #include "i915_drv.h" |
| 58 | 58 | |
| 59 | −void intel_psr_irq_control(struct drm_i915_private *dev_priv, bool debug) | |
| 59 | +static bool psr_global_enabled(u32 debug) | |
| 60 | +{ | |
| 61 | + switch (debug & I915_PSR_DEBUG_MODE_MASK) { | |
| 62 | + case I915_PSR_DEBUG_DEFAULT: | |
| 63 | + return i915_modparams.enable_psr; | |
| 64 | + case I915_PSR_DEBUG_DISABLE: | |
| 65 | + return false; | |
| 66 | + default: | |
| 67 | + return true; | |
| 68 | + } | |
| 69 | +} | |
| 70 | + | |
| 71 | +static bool intel_psr2_enabled(struct drm_i915_private *dev_priv, | |
| 72 | + const struct intel_crtc_state *crtc_state) | |
| 73 | +{ | |
| 74 | + switch (dev_priv->psr.debug & I915_PSR_DEBUG_MODE_MASK) { | |
| 75 | + case I915_PSR_DEBUG_FORCE_PSR1: | |
| 76 | + return false; | |
| 77 | + default: | |
| 78 | + return crtc_state->has_psr2; | |
| 79 | + } | |
| 80 | +} | |
| 81 | + | |
| 82 | +void intel_psr_irq_control(struct drm_i915_private *dev_priv, u32 debug) | |
| 60 | 83 | { |
| 61 | 84 | u32 debug_mask, mask; |
| 62 | 85 | |
| @@ -77,10 +100,9 @@ void intel_psr_irq_control(struct drm_i915_private *dev_priv, bool debug) · 14 unmodified lines | ||
| 77 | 100 | EDP_PSR_PRE_ENTRY(TRANSCODER_C); |
| 78 | 101 | } |
| 79 | 102 | |
| 80 | − if (debug) | |
| 103 | + if (debug & I915_PSR_DEBUG_IRQ) | |
| 81 | 104 | mask |= debug_mask; |
| 82 | 105 | |
| 83 | − WRITE_ONCE(dev_priv->psr.debug, debug); | |
| 84 | 106 | I915_WRITE(EDP_PSR_IMR, ~mask); |
| 85 | 107 | } |
| 86 | 108 | |
| @@ -213,6 +235,9 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp) · 126 unmodified lines | ||
| 213 | 235 | dev_priv->psr.sink_sync_latency = |
| 214 | 236 | intel_dp_get_sink_sync_latency(intel_dp); |
| 215 | 237 | |
| 238 | + WARN_ON(dev_priv->psr.dp); | |
| 239 | + dev_priv->psr.dp = intel_dp; | |
| 240 | + | |
| 216 | 241 | if (INTEL_GEN(dev_priv) >= 9 && |
| 217 | 242 | (intel_dp->psr_dpcd[0] == DP_PSR2_WITH_Y_COORD_IS_SUPPORTED)) { |
| 218 | 243 | bool y_req = intel_dp->psr_dpcd[1] & |
| @@ -245,7 +270,7 @@ static void intel_psr_setup_vsc(struct intel_dp *intel_dp, · 26 unmodified lines | ||
| 245 | 270 | const struct intel_crtc_state *crtc_state) |
| 246 | 271 | { |
| 247 | 272 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
| 248 | − struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev); | |
| 273 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 249 | 274 | struct edp_vsc_psr psr_vsc; |
| 250 | 275 | |
| 251 | 276 | if (dev_priv->psr.psr2_enabled) { |
| @@ -275,8 +300,7 @@ static void intel_psr_setup_vsc(struct intel_dp *intel_dp, · 23 unmodified lines | ||
| 275 | 300 | |
| 276 | 301 | static void hsw_psr_setup_aux(struct intel_dp *intel_dp) |
| 277 | 302 | { |
| 278 | − struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | |
| 279 | − struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); | |
| 303 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 280 | 304 | u32 aux_clock_divider, aux_ctl; |
| 281 | 305 | int i; |
| 282 | 306 | static const uint8_t aux_msg[] = { |
| @@ -309,9 +333,7 @@ static void hsw_psr_setup_aux(struct intel_dp *intel_dp) · 26 unmodified lines | ||
| 309 | 333 | |
| 310 | 334 | static void intel_psr_enable_sink(struct intel_dp *intel_dp) |
| 311 | 335 | { |
| 312 | − struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | |
| 313 | − struct drm_device *dev = dig_port->base.base.dev; | |
| 314 | − struct drm_i915_private *dev_priv = to_i915(dev); | |
| 336 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 315 | 337 | u8 dpcd_val = DP_PSR_ENABLE; |
| 316 | 338 | |
| 317 | 339 | /* Enable ALPM at sink for psr2 */ |
| @@ -332,9 +354,7 @@ static void intel_psr_enable_sink(struct intel_dp *intel_dp) · 14 unmodified lines | ||
| 332 | 354 | |
| 333 | 355 | static void hsw_activate_psr1(struct intel_dp *intel_dp) |
| 334 | 356 | { |
| 335 | − struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | |
| 336 | − struct drm_device *dev = dig_port->base.base.dev; | |
| 337 | − struct drm_i915_private *dev_priv = to_i915(dev); | |
| 357 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 338 | 358 | u32 max_sleep_time = 0x1f; |
| 339 | 359 | u32 val = EDP_PSR_ENABLE; |
| 340 | 360 | |
| @@ -389,9 +409,7 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp) · 48 unmodified lines | ||
| 389 | 409 | |
| 390 | 410 | static void hsw_activate_psr2(struct intel_dp *intel_dp) |
| 391 | 411 | { |
| 392 | − struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | |
| 393 | − struct drm_device *dev = dig_port->base.base.dev; | |
| 394 | − struct drm_i915_private *dev_priv = to_i915(dev); | |
| 412 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 395 | 413 | u32 val; |
| 396 | 414 | |
| 397 | 415 | /* Let's use 6 as the minimum to cover all known cases including the |
| @@ -427,8 +445,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) · 29 unmodified lines | ||
| 427 | 445 | static bool intel_psr2_config_valid(struct intel_dp *intel_dp, |
| 428 | 446 | struct intel_crtc_state *crtc_state) |
| 429 | 447 | { |
| 430 | − struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | |
| 431 | − struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); | |
| 448 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 432 | 449 | int crtc_hdisplay = crtc_state->base.adjusted_mode.crtc_hdisplay; |
| 433 | 450 | int crtc_vdisplay = crtc_state->base.adjusted_mode.crtc_vdisplay; |
| 434 | 451 | int psr_max_h = 0, psr_max_v = 0; |
| @@ -463,7 +480,7 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, · 28 unmodified lines | ||
| 463 | 480 | struct intel_crtc_state *crtc_state) |
| 464 | 481 | { |
| 465 | 482 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
| 466 | − struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); | |
| 483 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 467 | 484 | const struct drm_display_mode *adjusted_mode = |
| 468 | 485 | &crtc_state->base.adjusted_mode; |
| 469 | 486 | int psr_setup_time; |
| @@ -471,10 +488,8 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, · 1 unmodified line | ||
| 471 | 488 | if (!CAN_PSR(dev_priv)) |
| 472 | 489 | return; |
| 473 | 490 | |
| 474 | − if (!i915_modparams.enable_psr) { | |
| 475 | − DRM_DEBUG_KMS("PSR disable by flag\n"); | |
| 491 | + if (intel_dp != dev_priv->psr.dp) | |
| 476 | 492 | return; |
| 477 | − } | |
| 478 | 493 | |
| 479 | 494 | /* |
| 480 | 495 | * HSW spec explicitly says PSR is tied to port A. |
| @@ -517,14 +532,11 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, · 36 unmodified lines | ||
| 517 | 532 | |
| 518 | 533 | crtc_state->has_psr = true; |
| 519 | 534 | crtc_state->has_psr2 = intel_psr2_config_valid(intel_dp, crtc_state); |
| 520 | − DRM_DEBUG_KMS("Enabling PSR%s\n", crtc_state->has_psr2 ? "2" : ""); | |
| 521 | 535 | } |
| 522 | 536 | |
| 523 | 537 | static void intel_psr_activate(struct intel_dp *intel_dp) |
| 524 | 538 | { |
| 525 | − struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | |
| 526 | − struct drm_device *dev = intel_dig_port->base.base.dev; | |
| 527 | − struct drm_i915_private *dev_priv = to_i915(dev); | |
| 539 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 528 | 540 | |
| 529 | 541 | if (INTEL_GEN(dev_priv) >= 9) |
| 530 | 542 | WARN_ON(I915_READ(EDP_PSR2_CTL) & EDP_PSR2_ENABLE); |
| @@ -544,9 +556,7 @@ static void intel_psr_activate(struct intel_dp *intel_dp) · 13 unmodified lines | ||
| 544 | 556 | static void intel_psr_enable_source(struct intel_dp *intel_dp, |
| 545 | 557 | const struct intel_crtc_state *crtc_state) |
| 546 | 558 | { |
| 547 | − struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | |
| 548 | − struct drm_device *dev = dig_port->base.base.dev; | |
| 549 | − struct drm_i915_private *dev_priv = to_i915(dev); | |
| 559 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 550 | 560 | enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; |
| 551 | 561 | |
| 552 | 562 | /* Only HSW and BDW have PSR AUX registers that need to be setup. SKL+ |
| @@ -589,6 +599,24 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, · 36 unmodified lines | ||
| 589 | 599 | } |
| 590 | 600 | } |
| 591 | 601 | |
| 602 | +static void intel_psr_enable_locked(struct drm_i915_private *dev_priv, | |
| 603 | + const struct intel_crtc_state *crtc_state) | |
| 604 | +{ | |
| 605 | + struct intel_dp *intel_dp = dev_priv->psr.dp; | |
| 606 | + | |
| 607 | + if (dev_priv->psr.enabled) | |
| 608 | + return; | |
| 609 | + | |
| 610 | + DRM_DEBUG_KMS("Enabling PSR%s\n", | |
| 611 | + dev_priv->psr.psr2_enabled ? "2" : "1"); | |
| 612 | + intel_psr_setup_vsc(intel_dp, crtc_state); | |
| 613 | + intel_psr_enable_sink(intel_dp); | |
| 614 | + intel_psr_enable_source(intel_dp, crtc_state); | |
| 615 | + dev_priv->psr.enabled = true; | |
| 616 | + | |
| 617 | + intel_psr_activate(intel_dp); | |
| 618 | +} | |
| 619 | + | |
| 592 | 620 | /** |
| 593 | 621 | * intel_psr_enable - Enable PSR |
| 594 | 622 | * @intel_dp: Intel DP |
| @@ -599,9 +627,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, · 4 unmodified lines | ||
| 599 | 627 | void intel_psr_enable(struct intel_dp *intel_dp, |
| 600 | 628 | const struct intel_crtc_state *crtc_state) |
| 601 | 629 | { |
| 602 | − struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | |
| 603 | − struct drm_device *dev = intel_dig_port->base.base.dev; | |
| 604 | − struct drm_i915_private *dev_priv = to_i915(dev); | |
| 630 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 605 | 631 | |
| 606 | 632 | if (!crtc_state->has_psr) |
| 607 | 633 | return; |
| @@ -610,21 +636,21 @@ void intel_psr_enable(struct intel_dp *intel_dp, · 2 unmodified lines | ||
| 610 | 636 | return; |
| 611 | 637 | |
| 612 | 638 | WARN_ON(dev_priv->drrs.dp); |
| 639 | + | |
| 613 | 640 | mutex_lock(&dev_priv->psr.lock); |
| 614 | − if (dev_priv->psr.enabled) { | |
| 641 | + if (dev_priv->psr.prepared) { | |
| 615 | 642 | DRM_DEBUG_KMS("PSR already in use\n"); |
| 616 | 643 | goto unlock; |
| 617 | 644 | } |
| 618 | 645 | |
| 619 | − dev_priv->psr.psr2_enabled = crtc_state->has_psr2; | |
| 646 | + dev_priv->psr.psr2_enabled = intel_psr2_enabled(dev_priv, crtc_state); | |
| 620 | 647 | dev_priv->psr.busy_frontbuffer_bits = 0; |
| 648 | + dev_priv->psr.prepared = true; | |
| 621 | 649 | |
| 622 | − intel_psr_setup_vsc(intel_dp, crtc_state); | |
| 623 | − intel_psr_enable_sink(intel_dp); | |
| 624 | − intel_psr_enable_source(intel_dp, crtc_state); | |
| 625 | − dev_priv->psr.enabled = intel_dp; | |
| 626 | − | |
| 627 | − intel_psr_activate(intel_dp); | |
| 650 | + if (psr_global_enabled(dev_priv->psr.debug)) | |
| 651 | + intel_psr_enable_locked(dev_priv, crtc_state); | |
| 652 | + else | |
| 653 | + DRM_DEBUG_KMS("PSR disabled by flag\n"); | |
| 628 | 654 | |
| 629 | 655 | unlock: |
| 630 | 656 | mutex_unlock(&dev_priv->psr.lock); |
| @@ -633,9 +659,7 @@ unlock: · 2 unmodified lines | ||
| 633 | 659 | static void |
| 634 | 660 | intel_psr_disable_source(struct intel_dp *intel_dp) |
| 635 | 661 | { |
| 636 | − struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | |
| 637 | − struct drm_device *dev = intel_dig_port->base.base.dev; | |
| 638 | − struct drm_i915_private *dev_priv = to_i915(dev); | |
| 662 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 639 | 663 | |
| 640 | 664 | if (dev_priv->psr.active) { |
| 641 | 665 | i915_reg_t psr_status; |
| @@ -674,21 +698,21 @@ intel_psr_disable_source(struct intel_dp *intel_dp) · 32 unmodified lines | ||
| 674 | 698 | |
| 675 | 699 | static void intel_psr_disable_locked(struct intel_dp *intel_dp) |
| 676 | 700 | { |
| 677 | − struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | |
| 678 | − struct drm_device *dev = intel_dig_port->base.base.dev; | |
| 679 | − struct drm_i915_private *dev_priv = to_i915(dev); | |
| 701 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 680 | 702 | |
| 681 | 703 | lockdep_assert_held(&dev_priv->psr.lock); |
| 682 | 704 | |
| 683 | 705 | if (!dev_priv->psr.enabled) |
| 684 | 706 | return; |
| 685 | 707 | |
| 708 | + DRM_DEBUG_KMS("Disabling PSR%s\n", | |
| 709 | + dev_priv->psr.psr2_enabled ? "2" : "1"); | |
| 686 | 710 | intel_psr_disable_source(intel_dp); |
| 687 | 711 | |
| 688 | 712 | /* Disable PSR on Sink */ |
| 689 | 713 | drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0); |
| 690 | 714 | |
| 691 | − dev_priv->psr.enabled = NULL; | |
| 715 | + dev_priv->psr.enabled = false; | |
| 692 | 716 | } |
| 693 | 717 | |
| 694 | 718 | /** |
| @@ -701,9 +725,7 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) · 6 unmodified lines | ||
| 701 | 725 | void intel_psr_disable(struct intel_dp *intel_dp, |
| 702 | 726 | const struct intel_crtc_state *old_crtc_state) |
| 703 | 727 | { |
| 704 | − struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | |
| 705 | − struct drm_device *dev = intel_dig_port->base.base.dev; | |
| 706 | − struct drm_i915_private *dev_priv = to_i915(dev); | |
| 728 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 707 | 729 | |
| 708 | 730 | if (!old_crtc_state->has_psr) |
| 709 | 731 | return; |
| @@ -712,57 +734,61 @@ void intel_psr_disable(struct intel_dp *intel_dp, · 2 unmodified lines | ||
| 712 | 734 | return; |
| 713 | 735 | |
| 714 | 736 | mutex_lock(&dev_priv->psr.lock); |
| 737 | + if (!dev_priv->psr.prepared) { | |
| 738 | + mutex_unlock(&dev_priv->psr.lock); | |
| 739 | + return; | |
| 740 | + } | |
| 741 | + | |
| 715 | 742 | intel_psr_disable_locked(intel_dp); |
| 743 | + | |
| 744 | + dev_priv->psr.prepared = false; | |
| 716 | 745 | mutex_unlock(&dev_priv->psr.lock); |
| 717 | 746 | cancel_work_sync(&dev_priv->psr.work); |
| 718 | 747 | } |
| 719 | 748 | |
| 720 | −int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state) | |
| 749 | +/** | |
| 750 | + * intel_psr_wait_for_idle - wait for PSR1 to idle | |
| 751 | + * @new_crtc_state: new CRTC state | |
| 752 | + * @out_value: PSR status in case of failure | |
| 753 | + * | |
| 754 | + * This function is expected to be called from pipe_update_start() where it is | |
| 755 | + * not expected to race with PSR enable or disable. | |
| 756 | + * | |
| 757 | + * Returns: 0 on success or -ETIMEOUT if PSR status does not idle. | |
| 758 | + */ | |
| 759 | +int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state, | |
| 760 | + u32 *out_value) | |
| 721 | 761 | { |
| 722 | 762 | struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc); |
| 723 | 763 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
| 724 | − i915_reg_t reg; | |
| 725 | − u32 mask; | |
| 726 | 764 | |
| 727 | − if (!new_crtc_state->has_psr) | |
| 765 | + if (!dev_priv->psr.enabled || !new_crtc_state->has_psr) | |
| 728 | 766 | return 0; |
| 729 | 767 | |
| 730 | − /* | |
| 731 | − * The sole user right now is intel_pipe_update_start(), | |
| 732 | − * which won't race with psr_enable/disable, which is | |
| 733 | − * where psr2_enabled is written to. So, we don't need | |
| 734 | − * to acquire the psr.lock. More importantly, we want the | |
| 735 | − * latency inside intel_pipe_update_start() to be as low | |
| 736 | − * as possible, so no need to acquire psr.lock when it is | |
| 737 | − * not needed and will induce latencies in the atomic | |
| 738 | − * update path. | |
| 739 | − */ | |
| 740 | − if (dev_priv->psr.psr2_enabled) { | |
| 741 | − reg = EDP_PSR2_STATUS; | |
| 742 | − mask = EDP_PSR2_STATUS_STATE_MASK; | |
| 743 | − } else { | |
| 744 | − reg = EDP_PSR_STATUS; | |
| 745 | − mask = EDP_PSR_STATUS_STATE_MASK; | |
| 746 | − } | |
| 768 | + /* FIXME: Update this for PSR2 if we need to wait for idle */ | |
| 769 | + if (READ_ONCE(dev_priv->psr.psr2_enabled)) | |
| 770 | + return 0; | |
| 747 | 771 | |
| 748 | 772 | /* |
| 749 | − * Max time for PSR to idle = Inverse of the refresh rate + | |
| 750 | − * 6 ms of exit training time + 1.5 ms of aux channel | |
| 751 | − * handshake. 50 msec is defesive enough to cover everything. | |
| 773 | + * From bspec: Panel Self Refresh (BDW+) | |
| 774 | + * Max. time for PSR to idle = Inverse of the refresh rate + 6 ms of | |
| 775 | + * exit training time + 1.5 ms of aux channel handshake. 50 ms is | |
| 776 | + * defensive enough to cover everything. | |
| 752 | 777 | */ |
| 753 | − return intel_wait_for_register(dev_priv, reg, mask, | |
| 754 | − EDP_PSR_STATUS_STATE_IDLE, 50); | |
| 778 | + | |
| 779 | + return __intel_wait_for_register(dev_priv, EDP_PSR_STATUS, | |
| 780 | + EDP_PSR_STATUS_STATE_MASK, | |
| 781 | + EDP_PSR_STATUS_STATE_IDLE, 2, 50, | |
| 782 | + out_value); | |
| 755 | 783 | } |
| 756 | 784 | |
| 757 | 785 | static bool __psr_wait_for_idle_locked(struct drm_i915_private *dev_priv) |
| 758 | 786 | { |
| 759 | − struct intel_dp *intel_dp; | |
| 760 | 787 | i915_reg_t reg; |
| 761 | 788 | u32 mask; |
| 762 | 789 | int err; |
| 763 | 790 | |
| 764 | − intel_dp = dev_priv->psr.enabled; | |
| 765 | − if (!intel_dp) | |
| 791 | + if (!dev_priv->psr.enabled) | |
| 766 | 792 | return false; |
| 767 | 793 | |
| 768 | 794 | if (dev_priv->psr.psr2_enabled) { |
| @@ -784,6 +810,89 @@ static bool __psr_wait_for_idle_locked(struct drm_i915_private *dev_priv) · 15 unmodified lines | ||
| 784 | 810 | return err == 0 && dev_priv->psr.enabled; |
| 785 | 811 | } |
| 786 | 812 | |
| 813 | +static bool switching_psr(struct drm_i915_private *dev_priv, | |
| 814 | + struct intel_crtc_state *crtc_state, | |
| 815 | + u32 mode) | |
| 816 | +{ | |
| 817 | + /* Can't switch psr state anyway if PSR2 is not supported. */ | |
| 818 | + if (!crtc_state || !crtc_state->has_psr2) | |
| 819 | + return false; | |
| 820 | + | |
| 821 | + if (dev_priv->psr.psr2_enabled && mode == I915_PSR_DEBUG_FORCE_PSR1) | |
| 822 | + return true; | |
| 823 | + | |
| 824 | + if (!dev_priv->psr.psr2_enabled && mode != I915_PSR_DEBUG_FORCE_PSR1) | |
| 825 | + return true; | |
| 826 | + | |
| 827 | + return false; | |
| 828 | +} | |
| 829 | + | |
| 830 | +int intel_psr_set_debugfs_mode(struct drm_i915_private *dev_priv, | |
| 831 | + struct drm_modeset_acquire_ctx *ctx, | |
| 832 | + u64 val) | |
| 833 | +{ | |
| 834 | + struct drm_device *dev = &dev_priv->drm; | |
| 835 | + struct drm_connector_state *conn_state; | |
| 836 | + struct intel_crtc_state *crtc_state = NULL; | |
| 837 | + struct drm_crtc_commit *commit; | |
| 838 | + struct drm_crtc *crtc; | |
| 839 | + struct intel_dp *dp; | |
| 840 | + int ret; | |
| 841 | + bool enable; | |
| 842 | + u32 mode = val & I915_PSR_DEBUG_MODE_MASK; | |
| 843 | + | |
| 844 | + if (val & ~(I915_PSR_DEBUG_IRQ | I915_PSR_DEBUG_MODE_MASK) || | |
| 845 | + mode > I915_PSR_DEBUG_FORCE_PSR1) { | |
| 846 | + DRM_DEBUG_KMS("Invalid debug mask %llx\n", val); | |
| 847 | + return -EINVAL; | |
| 848 | + } | |
| 849 | + | |
| 850 | + ret = drm_modeset_lock(&dev->mode_config.connection_mutex, ctx); | |
| 851 | + if (ret) | |
| 852 | + return ret; | |
| 853 | + | |
| 854 | + /* dev_priv->psr.dp should be set once and then never touched again. */ | |
| 855 | + dp = READ_ONCE(dev_priv->psr.dp); | |
| 856 | + conn_state = dp->attached_connector->base.state; | |
| 857 | + crtc = conn_state->crtc; | |
| 858 | + if (crtc) { | |
| 859 | + ret = drm_modeset_lock(&crtc->mutex, ctx); | |
| 860 | + if (ret) | |
| 861 | + return ret; | |
| 862 | + | |
| 863 | + crtc_state = to_intel_crtc_state(crtc->state); | |
| 864 | + commit = crtc_state->base.commit; | |
| 865 | + } else { | |
| 866 | + commit = conn_state->commit; | |
| 867 | + } | |
| 868 | + if (commit) { | |
| 869 | + ret = wait_for_completion_interruptible(&commit->hw_done); | |
| 870 | + if (ret) | |
| 871 | + return ret; | |
| 872 | + } | |
| 873 | + | |
| 874 | + ret = mutex_lock_interruptible(&dev_priv->psr.lock); | |
| 875 | + if (ret) | |
| 876 | + return ret; | |
| 877 | + | |
| 878 | + enable = psr_global_enabled(val); | |
| 879 | + | |
| 880 | + if (!enable || switching_psr(dev_priv, crtc_state, mode)) | |
| 881 | + intel_psr_disable_locked(dev_priv->psr.dp); | |
| 882 | + | |
| 883 | + dev_priv->psr.debug = val; | |
| 884 | + if (crtc) | |
| 885 | + dev_priv->psr.psr2_enabled = intel_psr2_enabled(dev_priv, crtc_state); | |
| 886 | + | |
| 887 | + intel_psr_irq_control(dev_priv, dev_priv->psr.debug); | |
| 888 | + | |
| 889 | + if (dev_priv->psr.prepared && enable) | |
| 890 | + intel_psr_enable_locked(dev_priv, crtc_state); | |
| 891 | + | |
| 892 | + mutex_unlock(&dev_priv->psr.lock); | |
| 893 | + return ret; | |
| 894 | +} | |
| 895 | + | |
| 787 | 896 | static void intel_psr_work(struct work_struct *work) |
| 788 | 897 | { |
| 789 | 898 | struct drm_i915_private *dev_priv = |
| @@ -811,7 +920,7 @@ static void intel_psr_work(struct work_struct *work) · 21 unmodified lines | ||
| 811 | 920 | if (dev_priv->psr.busy_frontbuffer_bits || dev_priv->psr.active) |
| 812 | 921 | goto unlock; |
| 813 | 922 | |
| 814 | − intel_psr_activate(dev_priv->psr.enabled); | |
| 923 | + intel_psr_activate(dev_priv->psr.dp); | |
| 815 | 924 | unlock: |
| 816 | 925 | mutex_unlock(&dev_priv->psr.lock); |
| 817 | 926 | } |
| @@ -866,7 +975,7 @@ void intel_psr_invalidate(struct drm_i915_private *dev_priv, · 48 unmodified lines | ||
| 866 | 975 | return; |
| 867 | 976 | } |
| 868 | 977 | |
| 869 | − crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc; | |
| 978 | + crtc = dp_to_dig_port(dev_priv->psr.dp)->base.base.crtc; | |
| 870 | 979 | pipe = to_intel_crtc(crtc)->pipe; |
| 871 | 980 | |
| 872 | 981 | frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe); |
| @@ -909,7 +1018,7 @@ void intel_psr_flush(struct drm_i915_private *dev_priv, · 36 unmodified lines | ||
| 909 | 1018 | return; |
| 910 | 1019 | } |
| 911 | 1020 | |
| 912 | − crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc; | |
| 1021 | + crtc = dp_to_dig_port(dev_priv->psr.dp)->base.base.crtc; | |
| 913 | 1022 | pipe = to_intel_crtc(crtc)->pipe; |
| 914 | 1023 | |
| 915 | 1024 | frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe); |
| @@ -977,9 +1086,7 @@ void intel_psr_init(struct drm_i915_private *dev_priv) · 61 unmodified lines | ||
| 977 | 1086 | |
| 978 | 1087 | void intel_psr_short_pulse(struct intel_dp *intel_dp) |
| 979 | 1088 | { |
| 980 | − struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | |
| 981 | − struct drm_device *dev = intel_dig_port->base.base.dev; | |
| 982 | − struct drm_i915_private *dev_priv = to_i915(dev); | |
| 1089 | + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); | |
| 983 | 1090 | struct i915_psr *psr = &dev_priv->psr; |
| 984 | 1091 | u8 val; |
| 985 | 1092 | const u8 errors = DP_PSR_RFB_STORAGE_ERROR | |
| @@ -991,7 +1098,7 @@ void intel_psr_short_pulse(struct intel_dp *intel_dp) · 5 unmodified lines | ||
| 991 | 1098 | |
| 992 | 1099 | mutex_lock(&psr->lock); |
| 993 | 1100 | |
| 994 | − if (psr->enabled != intel_dp) | |
| 1101 | + if (!psr->enabled || psr->dp != intel_dp) | |
| 995 | 1102 | goto exit; |
| 996 | 1103 | |
| 997 | 1104 | if (drm_dp_dpcd_readb(&intel_dp->aux, DP_PSR_STATUS, &val) != 1) { |
| @@ -344,11 +344,14 @@ gen7_render_ring_flush(struct i915_request *rq, u32 mode) · 343 unmodified lines | ||
| 344 | 344 | static void ring_setup_phys_status_page(struct intel_engine_cs *engine) |
| 345 | 345 | { |
| 346 | 346 | struct drm_i915_private *dev_priv = engine->i915; |
| 347 | + struct page *page = virt_to_page(engine->status_page.page_addr); | |
| 348 | + phys_addr_t phys = PFN_PHYS(page_to_pfn(page)); | |
| 347 | 349 | u32 addr; |
| 348 | 350 | |
| 349 | − addr = dev_priv->status_page_dmah->busaddr; | |
| 351 | + addr = lower_32_bits(phys); | |
| 350 | 352 | if (INTEL_GEN(dev_priv) >= 4) |
| 351 | − addr |= (dev_priv->status_page_dmah->busaddr >> 28) & 0xf0; | |
| 353 | + addr |= (phys >> 28) & 0xf0; | |
| 354 | + | |
| 352 | 355 | I915_WRITE(HWS_PGA, addr); |
| 353 | 356 | } |
| 354 | 357 | |
| @@ -537,6 +540,8 @@ static int init_ring_common(struct intel_engine_cs *engine) · 182 unmodified lines | ||
| 537 | 540 | if (INTEL_GEN(dev_priv) > 2) |
| 538 | 541 | I915_WRITE_MODE(engine, _MASKED_BIT_DISABLE(STOP_RING)); |
| 539 | 542 | |
| 543 | + /* Papering over lost _interrupts_ immediately following the restart */ | |
| 544 | + intel_engine_wakeup(engine); | |
| 540 | 545 | out: |
| 541 | 546 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
| 542 | 547 | |
| @@ -1013,24 +1018,22 @@ i915_emit_bb_start(struct i915_request *rq, · 470 unmodified lines | ||
| 1013 | 1018 | return 0; |
| 1014 | 1019 | } |
| 1015 | 1020 | |
| 1016 | − | |
| 1017 | − | |
| 1018 | −int intel_ring_pin(struct intel_ring *ring, | |
| 1019 | − struct drm_i915_private *i915, | |
| 1020 | − unsigned int offset_bias) | |
| 1021 | +int intel_ring_pin(struct intel_ring *ring) | |
| 1021 | 1022 | { |
| 1022 | − enum i915_map_type map = HAS_LLC(i915) ? I915_MAP_WB : I915_MAP_WC; | |
| 1023 | 1023 | struct i915_vma *vma = ring->vma; |
| 1024 | + enum i915_map_type map = | |
| 1025 | + HAS_LLC(vma->vm->i915) ? I915_MAP_WB : I915_MAP_WC; | |
| 1024 | 1026 | unsigned int flags; |
| 1025 | 1027 | void *addr; |
| 1026 | 1028 | int ret; |
| 1027 | 1029 | |
| 1028 | 1030 | GEM_BUG_ON(ring->vaddr); |
| 1029 | 1031 | |
| 1030 | − | |
| 1031 | 1032 | flags = PIN_GLOBAL; |
| 1032 | − if (offset_bias) | |
| 1033 | − flags |= PIN_OFFSET_BIAS | offset_bias; | |
| 1033 | + | |
| 1034 | + /* Ring wraparound at offset 0 sometimes hangs. No idea why. */ | |
| 1035 | + flags |= PIN_OFFSET_BIAS | i915_ggtt_pin_bias(vma); | |
| 1036 | + | |
| 1034 | 1037 | if (vma->obj->stolen) |
| 1035 | 1038 | flags |= PIN_MAPPABLE; |
| 1036 | 1039 | else |
| @@ -1045,7 +1048,7 @@ int intel_ring_pin(struct intel_ring *ring, · 8 unmodified lines | ||
| 1045 | 1048 | return ret; |
| 1046 | 1049 | } |
| 1047 | 1050 | |
| 1048 | − ret = i915_vma_pin(vma, 0, PAGE_SIZE, flags); | |
| 1051 | + ret = i915_vma_pin(vma, 0, 0, flags); | |
| 1049 | 1052 | if (unlikely(ret)) |
| 1050 | 1053 | return ret; |
| 1051 | 1054 | |
| @@ -1230,8 +1233,7 @@ static int __context_pin(struct intel_context *ce) · 178 unmodified lines | ||
| 1230 | 1233 | return err; |
| 1231 | 1234 | } |
| 1232 | 1235 | |
| 1233 | − err = i915_vma_pin(vma, 0, I915_GTT_MIN_ALIGNMENT, | |
| 1234 | − PIN_GLOBAL | PIN_HIGH); | |
| 1236 | + err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH); | |
| 1235 | 1237 | if (err) |
| 1236 | 1238 | return err; |
| 1237 | 1239 | |
| @@ -1419,8 +1421,7 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine) · 181 unmodified lines | ||
| 1419 | 1421 | goto err; |
| 1420 | 1422 | } |
| 1421 | 1423 | |
| 1422 | − /* Ring wraparound at offset 0 sometimes hangs. No idea why. */ | |
| 1423 | − err = intel_ring_pin(ring, engine->i915, I915_GTT_PAGE_SIZE); | |
| 1424 | + err = intel_ring_pin(ring); | |
| 1424 | 1425 | if (err) |
| 1425 | 1426 | goto err_ring; |
| 1426 | 1427 | |
| @@ -1706,9 +1707,29 @@ static int switch_context(struct i915_request *rq) · 279 unmodified lines | ||
| 1706 | 1707 | } |
| 1707 | 1708 | |
| 1708 | 1709 | if (ppgtt) { |
| 1710 | + ret = engine->emit_flush(rq, EMIT_INVALIDATE); | |
| 1711 | + if (ret) | |
| 1712 | + goto err_mm; | |
| 1713 | + | |
| 1709 | 1714 | ret = flush_pd_dir(rq); |
| 1710 | 1715 | if (ret) |
| 1711 | 1716 | goto err_mm; |
| 1717 | + | |
| 1718 | + /* | |
| 1719 | + * Not only do we need a full barrier (post-sync write) after | |
| 1720 | + * invalidating the TLBs, but we need to wait a little bit | |
| 1721 | + * longer. Whether this is merely delaying us, or the | |
| 1722 | + * subsequent flush is a key part of serialising with the | |
| 1723 | + * post-sync op, this extra pass appears vital before a | |
| 1724 | + * mm switch! | |
| 1725 | + */ | |
| 1726 | + ret = engine->emit_flush(rq, EMIT_INVALIDATE); | |
| 1727 | + if (ret) | |
| 1728 | + goto err_mm; | |
| 1729 | + | |
| 1730 | + ret = engine->emit_flush(rq, EMIT_FLUSH); | |
| 1731 | + if (ret) | |
| 1732 | + goto err_mm; | |
| 1712 | 1733 | } |
| 1713 | 1734 | |
| 1714 | 1735 | if (ctx->remap_slice) { |
| @@ -1946,7 +1967,7 @@ static void gen6_bsd_submit_request(struct i915_request *request) · 231 unmodified lines | ||
| 1946 | 1967 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
| 1947 | 1968 | } |
| 1948 | 1969 | |
| 1949 | −static int gen6_bsd_ring_flush(struct i915_request *rq, u32 mode) | |
| 1970 | +static int mi_flush_dw(struct i915_request *rq, u32 flags) | |
| 1950 | 1971 | { |
| 1951 | 1972 | u32 cmd, *cs; |
| 1952 | 1973 | |
| @@ -1956,7 +1977,8 @@ static int gen6_bsd_ring_flush(struct i915_request *rq, u32 mode) · 3 unmodified lines | ||
| 1956 | 1977 | |
| 1957 | 1978 | cmd = MI_FLUSH_DW; |
| 1958 | 1979 | |
| 1959 | − /* We always require a command barrier so that subsequent | |
| 1980 | + /* | |
| 1981 | + * We always require a command barrier so that subsequent | |
| 1960 | 1982 | * commands, such as breadcrumb interrupts, are strictly ordered |
| 1961 | 1983 | * wrt the contents of the write cache being flushed to memory |
| 1962 | 1984 | * (and thus being coherent from the CPU). |
| @@ -1964,22 +1986,33 @@ static int gen6_bsd_ring_flush(struct i915_request *rq, u32 mode) · 1 unmodified line | ||
| 1964 | 1986 | cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW; |
| 1965 | 1987 | |
| 1966 | 1988 | /* |
| 1967 | − * Bspec vol 1c.5 - video engine command streamer: | |
| 1989 | + * Bspec vol 1c.3 - blitter engine command streamer: | |
| 1968 | 1990 | * "If ENABLED, all TLBs will be invalidated once the flush |
| 1969 | 1991 | * operation is complete. This bit is only valid when the |
| 1970 | 1992 | * Post-Sync Operation field is a value of 1h or 3h." |
| 1971 | 1993 | */ |
| 1972 | − if (mode & EMIT_INVALIDATE) | |
| 1973 | − cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD; | |
| 1994 | + cmd |= flags; | |
| 1974 | 1995 | |
| 1975 | 1996 | *cs++ = cmd; |
| 1976 | 1997 | *cs++ = I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT; |
| 1977 | 1998 | *cs++ = 0; |
| 1978 | 1999 | *cs++ = MI_NOOP; |
| 2000 | + | |
| 1979 | 2001 | intel_ring_advance(rq, cs); |
| 2002 | + | |
| 1980 | 2003 | return 0; |
| 1981 | 2004 | } |
| 1982 | 2005 | |
| 2006 | +static int gen6_flush_dw(struct i915_request *rq, u32 mode, u32 invflags) | |
| 2007 | +{ | |
| 2008 | + return mi_flush_dw(rq, mode & EMIT_INVALIDATE ? invflags : 0); | |
| 2009 | +} | |
| 2010 | + | |
| 2011 | +static int gen6_bsd_ring_flush(struct i915_request *rq, u32 mode) | |
| 2012 | +{ | |
| 2013 | + return gen6_flush_dw(rq, mode, MI_INVALIDATE_TLB | MI_INVALIDATE_BSD); | |
| 2014 | +} | |
| 2015 | + | |
| 1983 | 2016 | static int |
| 1984 | 2017 | hsw_emit_bb_start(struct i915_request *rq, |
| 1985 | 2018 | u64 offset, u32 len, |
| @@ -1992,9 +2025,7 @@ hsw_emit_bb_start(struct i915_request *rq, · 6 unmodified lines | ||
| 1992 | 2025 | return PTR_ERR(cs); |
| 1993 | 2026 | |
| 1994 | 2027 | *cs++ = MI_BATCH_BUFFER_START | (dispatch_flags & I915_DISPATCH_SECURE ? |
| 1995 | − 0 : MI_BATCH_PPGTT_HSW | MI_BATCH_NON_SECURE_HSW) | | |
| 1996 | − (dispatch_flags & I915_DISPATCH_RS ? | |
| 1997 | − MI_BATCH_RESOURCE_STREAMER : 0); | |
| 2028 | + 0 : MI_BATCH_PPGTT_HSW | MI_BATCH_NON_SECURE_HSW); | |
| 1998 | 2029 | /* bit0-7 is the length on GEN6+ */ |
| 1999 | 2030 | *cs++ = offset; |
| 2000 | 2031 | intel_ring_advance(rq, cs); |
| @@ -2026,36 +2057,7 @@ gen6_emit_bb_start(struct i915_request *rq, · 25 unmodified lines | ||
| 2026 | 2057 | |
| 2027 | 2058 | static int gen6_ring_flush(struct i915_request *rq, u32 mode) |
| 2028 | 2059 | { |
| 2029 | − u32 cmd, *cs; | |
| 2030 | − | |
| 2031 | − cs = intel_ring_begin(rq, 4); | |
| 2032 | − if (IS_ERR(cs)) | |
| 2033 | − return PTR_ERR(cs); | |
| 2034 | − | |
| 2035 | − cmd = MI_FLUSH_DW; | |
| 2036 | − | |
| 2037 | − /* We always require a command barrier so that subsequent | |
| 2038 | − * commands, such as breadcrumb interrupts, are strictly ordered | |
| 2039 | − * wrt the contents of the write cache being flushed to memory | |
| 2040 | − * (and thus being coherent from the CPU). | |
| 2041 | − */ | |
| 2042 | − cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW; | |
| 2043 | − | |
| 2044 | − /* | |
| 2045 | − * Bspec vol 1c.3 - blitter engine command streamer: | |
| 2046 | − * "If ENABLED, all TLBs will be invalidated once the flush | |
| 2047 | − * operation is complete. This bit is only valid when the | |
| 2048 | − * Post-Sync Operation field is a value of 1h or 3h." | |
| 2049 | − */ | |
| 2050 | − if (mode & EMIT_INVALIDATE) | |
| 2051 | − cmd |= MI_INVALIDATE_TLB; | |
| 2052 | − *cs++ = cmd; | |
| 2053 | − *cs++ = I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT; | |
| 2054 | − *cs++ = 0; | |
| 2055 | − *cs++ = MI_NOOP; | |
| 2056 | − intel_ring_advance(rq, cs); | |
| 2057 | − | |
| 2058 | − return 0; | |
| 2060 | + return gen6_flush_dw(rq, mode, MI_INVALIDATE_TLB); | |
| 2059 | 2061 | } |
| 2060 | 2062 | |
| 2061 | 2063 | static void intel_ring_init_semaphores(struct drm_i915_private *dev_priv, |
| @@ -474,7 +474,6 @@ struct intel_engine_cs { · 473 unmodified lines | ||
| 474 | 474 | unsigned int dispatch_flags); |
| 475 | 475 | #define I915_DISPATCH_SECURE BIT(0) |
| 476 | 476 | #define I915_DISPATCH_PINNED BIT(1) |
| 477 | −#define I915_DISPATCH_RS BIT(2) | |
| 478 | 477 | void (*emit_breadcrumb)(struct i915_request *rq, u32 *cs); |
| 479 | 478 | int emit_breadcrumb_sz; |
| 480 | 479 | |
| @@ -797,9 +796,7 @@ struct intel_ring * · 316 unmodified lines | ||
| 797 | 796 | intel_engine_create_ring(struct intel_engine_cs *engine, |
| 798 | 797 | struct i915_timeline *timeline, |
| 799 | 798 | int size); |
| 800 | −int intel_ring_pin(struct intel_ring *ring, | |
| 801 | − struct drm_i915_private *i915, | |
| 802 | − unsigned int offset_bias); | |
| 799 | +int intel_ring_pin(struct intel_ring *ring); | |
| 803 | 800 | void intel_ring_reset(struct intel_ring *ring, u32 tail); |
| 804 | 801 | unsigned int intel_ring_update_space(struct intel_ring *ring); |
| 805 | 802 | void intel_ring_unpin(struct intel_ring *ring); |
| @@ -909,18 +906,15 @@ int intel_init_blt_ring_buffer(struct intel_engine_cs *engine); · 103 unmodified lines | ||
| 909 | 906 | int intel_init_vebox_ring_buffer(struct intel_engine_cs *engine); |
| 910 | 907 | |
| 911 | 908 | int intel_engine_stop_cs(struct intel_engine_cs *engine); |
| 909 | +void intel_engine_cancel_stop_cs(struct intel_engine_cs *engine); | |
| 912 | 910 | |
| 913 | 911 | u64 intel_engine_get_active_head(const struct intel_engine_cs *engine); |
| 914 | 912 | u64 intel_engine_get_last_batch_head(const struct intel_engine_cs *engine); |
| 915 | 913 | |
| 916 | −static inline u32 intel_engine_get_seqno(struct intel_engine_cs *engine) | |
| 917 | −{ | |
| 918 | − return intel_read_status_page(engine, I915_GEM_HWS_INDEX); | |
| 919 | −} | |
| 920 | − | |
| 921 | 914 | static inline u32 intel_engine_last_submit(struct intel_engine_cs *engine) |
| 922 | 915 | { |
| 923 | − /* We are only peeking at the tail of the submit queue (and not the | |
| 916 | + /* | |
| 917 | + * We are only peeking at the tail of the submit queue (and not the | |
| 924 | 918 | * queue itself) in order to gain a hint as to the current active |
| 925 | 919 | * state of the engine. Callers are not expected to be taking |
| 926 | 920 | * engine->timeline->lock, nor are they expected to be concerned |
| @@ -930,6 +924,31 @@ static inline u32 intel_engine_last_submit(struct intel_engine_cs *engine) · 3 unmodified lines | ||
| 930 | 924 | return READ_ONCE(engine->timeline.seqno); |
| 931 | 925 | } |
| 932 | 926 | |
| 927 | +static inline u32 intel_engine_get_seqno(struct intel_engine_cs *engine) | |
| 928 | +{ | |
| 929 | + return intel_read_status_page(engine, I915_GEM_HWS_INDEX); | |
| 930 | +} | |
| 931 | + | |
| 932 | +static inline bool intel_engine_signaled(struct intel_engine_cs *engine, | |
| 933 | + u32 seqno) | |
| 934 | +{ | |
| 935 | + return i915_seqno_passed(intel_engine_get_seqno(engine), seqno); | |
| 936 | +} | |
| 937 | + | |
| 938 | +static inline bool intel_engine_has_completed(struct intel_engine_cs *engine, | |
| 939 | + u32 seqno) | |
| 940 | +{ | |
| 941 | + GEM_BUG_ON(!seqno); | |
| 942 | + return intel_engine_signaled(engine, seqno); | |
| 943 | +} | |
| 944 | + | |
| 945 | +static inline bool intel_engine_has_started(struct intel_engine_cs *engine, | |
| 946 | + u32 seqno) | |
| 947 | +{ | |
| 948 | + GEM_BUG_ON(!seqno); | |
| 949 | + return intel_engine_signaled(engine, seqno - 1); | |
| 950 | +} | |
| 951 | + | |
| 933 | 952 | void intel_engine_get_instdone(struct intel_engine_cs *engine, |
| 934 | 953 | struct intel_instdone *instdone); |
| 935 | 954 | |
| @@ -52,10 +52,6 @@ · 51 unmodified lines | ||
| 52 | 52 | bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv, |
| 53 | 53 | enum i915_power_well_id power_well_id); |
| 54 | 54 | |
| 55 | −static struct i915_power_well * | |
| 56 | −lookup_power_well(struct drm_i915_private *dev_priv, | |
| 57 | − enum i915_power_well_id power_well_id); | |
| 58 | − | |
| 59 | 55 | const char * |
| 60 | 56 | intel_display_power_domain_str(enum intel_display_power_domain domain) |
| 61 | 57 | { |
| @@ -159,17 +155,17 @@ intel_display_power_domain_str(enum intel_display_power_domain domain) · 97 unmodified lines | ||
| 159 | 155 | static void intel_power_well_enable(struct drm_i915_private *dev_priv, |
| 160 | 156 | struct i915_power_well *power_well) |
| 161 | 157 | { |
| 162 | − DRM_DEBUG_KMS("enabling %s\n", power_well->name); | |
| 163 | − power_well->ops->enable(dev_priv, power_well); | |
| 158 | + DRM_DEBUG_KMS("enabling %s\n", power_well->desc->name); | |
| 159 | + power_well->desc->ops->enable(dev_priv, power_well); | |
| 164 | 160 | power_well->hw_enabled = true; |
| 165 | 161 | } |
| 166 | 162 | |
| 167 | 163 | static void intel_power_well_disable(struct drm_i915_private *dev_priv, |
| 168 | 164 | struct i915_power_well *power_well) |
| 169 | 165 | { |
| 170 | − DRM_DEBUG_KMS("disabling %s\n", power_well->name); | |
| 166 | + DRM_DEBUG_KMS("disabling %s\n", power_well->desc->name); | |
| 171 | 167 | power_well->hw_enabled = false; |
| 172 | − power_well->ops->disable(dev_priv, power_well); | |
| 168 | + power_well->desc->ops->disable(dev_priv, power_well); | |
| 173 | 169 | } |
| 174 | 170 | |
| 175 | 171 | static void intel_power_well_get(struct drm_i915_private *dev_priv, |
| @@ -183,7 +179,7 @@ static void intel_power_well_put(struct drm_i915_private *dev_priv, · 7 unmodified lines | ||
| 183 | 179 | struct i915_power_well *power_well) |
| 184 | 180 | { |
| 185 | 181 | WARN(!power_well->count, "Use count on power well %s is already zero", |
| 186 | − power_well->name); | |
| 182 | + power_well->desc->name); | |
| 187 | 183 | |
| 188 | 184 | if (!--power_well->count) |
| 189 | 185 | intel_power_well_disable(dev_priv, power_well); |
| @@ -213,7 +209,7 @@ bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv, · 23 unmodified lines | ||
| 213 | 209 | is_enabled = true; |
| 214 | 210 | |
| 215 | 211 | for_each_power_domain_well_rev(dev_priv, power_well, BIT_ULL(domain)) { |
| 216 | − if (power_well->always_on) | |
| 212 | + if (power_well->desc->always_on) | |
| 217 | 213 | continue; |
| 218 | 214 | |
| 219 | 215 | if (!power_well->hw_enabled) { |
| @@ -257,30 +253,6 @@ bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv, · 37 unmodified lines | ||
| 257 | 253 | return ret; |
| 258 | 254 | } |
| 259 | 255 | |
| 260 | −/** | |
| 261 | − * intel_display_set_init_power - set the initial power domain state | |
| 262 | − * @dev_priv: i915 device instance | |
| 263 | − * @enable: whether to enable or disable the initial power domain state | |
| 264 | − * | |
| 265 | − * For simplicity our driver load/unload and system suspend/resume code assumes | |
| 266 | − * that all power domains are always enabled. This functions controls the state | |
| 267 | − * of this little hack. While the initial power domain state is enabled runtime | |
| 268 | − * pm is effectively disabled. | |
| 269 | − */ | |
| 270 | −void intel_display_set_init_power(struct drm_i915_private *dev_priv, | |
| 271 | − bool enable) | |
| 272 | −{ | |
| 273 | − if (dev_priv->power_domains.init_power_on == enable) | |
| 274 | − return; | |
| 275 | − | |
| 276 | − if (enable) | |
| 277 | − intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); | |
| 278 | − else | |
| 279 | − intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); | |
| 280 | − | |
| 281 | − dev_priv->power_domains.init_power_on = enable; | |
| 282 | −} | |
| 283 | − | |
| 284 | 256 | /* |
| 285 | 257 | * Starting with Haswell, we have a "Power Down Well" that can be turned off |
| 286 | 258 | * when not needed anymore. We have 4 registers that can request the power well |
| @@ -323,26 +295,29 @@ static void hsw_power_well_pre_disable(struct drm_i915_private *dev_priv, · 36 unmodified lines | ||
| 323 | 295 | static void hsw_wait_for_power_well_enable(struct drm_i915_private *dev_priv, |
| 324 | 296 | struct i915_power_well *power_well) |
| 325 | 297 | { |
| 326 | − enum i915_power_well_id id = power_well->id; | |
| 298 | + const struct i915_power_well_regs *regs = power_well->desc->hsw.regs; | |
| 299 | + int pw_idx = power_well->desc->hsw.idx; | |
| 327 | 300 | |
| 328 | 301 | /* Timeout for PW1:10 us, AUX:not specified, other PWs:20 us. */ |
| 329 | 302 | WARN_ON(intel_wait_for_register(dev_priv, |
| 330 | − HSW_PWR_WELL_CTL_DRIVER(id), | |
| 331 | − HSW_PWR_WELL_CTL_STATE(id), | |
| 332 | − HSW_PWR_WELL_CTL_STATE(id), | |
| 303 | + regs->driver, | |
| 304 | + HSW_PWR_WELL_CTL_STATE(pw_idx), | |
| 305 | + HSW_PWR_WELL_CTL_STATE(pw_idx), | |
| 333 | 306 | 1)); |
| 334 | 307 | } |
| 335 | 308 | |
| 336 | 309 | static u32 hsw_power_well_requesters(struct drm_i915_private *dev_priv, |
| 337 | − enum i915_power_well_id id) | |
| 310 | + const struct i915_power_well_regs *regs, | |
| 311 | + int pw_idx) | |
| 338 | 312 | { |
| 339 | − u32 req_mask = HSW_PWR_WELL_CTL_REQ(id); | |
| 313 | + u32 req_mask = HSW_PWR_WELL_CTL_REQ(pw_idx); | |
| 340 | 314 | u32 ret; |
| 341 | 315 | |
| 342 | − ret = I915_READ(HSW_PWR_WELL_CTL_BIOS(id)) & req_mask ? 1 : 0; | |
| 343 | − ret |= I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) & req_mask ? 2 : 0; | |
| 344 | − ret |= I915_READ(HSW_PWR_WELL_CTL_KVMR) & req_mask ? 4 : 0; | |
| 345 | − ret |= I915_READ(HSW_PWR_WELL_CTL_DEBUG(id)) & req_mask ? 8 : 0; | |
| 316 | + ret = I915_READ(regs->bios) & req_mask ? 1 : 0; | |
| 317 | + ret |= I915_READ(regs->driver) & req_mask ? 2 : 0; | |
| 318 | + if (regs->kvmr.reg) | |
| 319 | + ret |= I915_READ(regs->kvmr) & req_mask ? 4 : 0; | |
| 320 | + ret |= I915_READ(regs->debug) & req_mask ? 8 : 0; | |
| 346 | 321 | |
| 347 | 322 | return ret; |
| 348 | 323 | } |
| @@ -350,7 +325,8 @@ static u32 hsw_power_well_requesters(struct drm_i915_private *dev_priv, · 1 unmodified line | ||
| 350 | 325 | static void hsw_wait_for_power_well_disable(struct drm_i915_private *dev_priv, |
| 351 | 326 | struct i915_power_well *power_well) |
| 352 | 327 | { |
| 353 | − enum i915_power_well_id id = power_well->id; | |
| 328 | + const struct i915_power_well_regs *regs = power_well->desc->hsw.regs; | |
| 329 | + int pw_idx = power_well->desc->hsw.idx; | |
| 354 | 330 | bool disabled; |
| 355 | 331 | u32 reqs; |
| 356 | 332 | |
| @@ -363,14 +339,14 @@ static void hsw_wait_for_power_well_disable(struct drm_i915_private *dev_priv, · 6 unmodified lines | ||
| 363 | 339 | * Skip the wait in case any of the request bits are set and print a |
| 364 | 340 | * diagnostic message. |
| 365 | 341 | */ |
| 366 | − wait_for((disabled = !(I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) & | |
| 367 | − HSW_PWR_WELL_CTL_STATE(id))) || | |
| 368 | − (reqs = hsw_power_well_requesters(dev_priv, id)), 1); | |
| 342 | + wait_for((disabled = !(I915_READ(regs->driver) & | |
| 343 | + HSW_PWR_WELL_CTL_STATE(pw_idx))) || | |
| 344 | + (reqs = hsw_power_well_requesters(dev_priv, regs, pw_idx)), 1); | |
| 369 | 345 | if (disabled) |
| 370 | 346 | return; |
| 371 | 347 | |
| 372 | 348 | DRM_DEBUG_KMS("%s forced on (bios:%d driver:%d kvmr:%d debug:%d)\n", |
| 373 | − power_well->name, | |
| 349 | + power_well->desc->name, | |
| 374 | 350 | !!(reqs & 1), !!(reqs & 2), !!(reqs & 4), !!(reqs & 8)); |
| 375 | 351 | } |
| 376 | 352 | |
| @@ -386,14 +362,15 @@ static void gen9_wait_for_power_well_fuses(struct drm_i915_private *dev_priv, · 9 unmodified lines | ||
| 386 | 362 | static void hsw_power_well_enable(struct drm_i915_private *dev_priv, |
| 387 | 363 | struct i915_power_well *power_well) |
| 388 | 364 | { |
| 389 | − enum i915_power_well_id id = power_well->id; | |
| 390 | − bool wait_fuses = power_well->hsw.has_fuses; | |
| 365 | + const struct i915_power_well_regs *regs = power_well->desc->hsw.regs; | |
| 366 | + int pw_idx = power_well->desc->hsw.idx; | |
| 367 | + bool wait_fuses = power_well->desc->hsw.has_fuses; | |
| 391 | 368 | enum skl_power_gate uninitialized_var(pg); |
| 392 | 369 | u32 val; |
| 393 | 370 | |
| 394 | 371 | if (wait_fuses) { |
| 395 | − pg = INTEL_GEN(dev_priv) >= 11 ? ICL_PW_TO_PG(id) : | |
| 396 | − SKL_PW_TO_PG(id); | |
| 372 | + pg = INTEL_GEN(dev_priv) >= 11 ? ICL_PW_CTL_IDX_TO_PG(pw_idx) : | |
| 373 | + SKL_PW_CTL_IDX_TO_PG(pw_idx); | |
| 397 | 374 | /* |
| 398 | 375 | * For PW1 we have to wait both for the PW0/PG0 fuse state |
| 399 | 376 | * before enabling the power well and PW1/PG1's own fuse |
| @@ -405,52 +382,55 @@ static void hsw_power_well_enable(struct drm_i915_private *dev_priv, · 5 unmodified lines | ||
| 405 | 382 | gen9_wait_for_power_well_fuses(dev_priv, SKL_PG0); |
| 406 | 383 | } |
| 407 | 384 | |
| 408 | − val = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)); | |
| 409 | − I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id), val | HSW_PWR_WELL_CTL_REQ(id)); | |
| 385 | + val = I915_READ(regs->driver); | |
| 386 | + I915_WRITE(regs->driver, val | HSW_PWR_WELL_CTL_REQ(pw_idx)); | |
| 410 | 387 | hsw_wait_for_power_well_enable(dev_priv, power_well); |
| 411 | 388 | |
| 412 | 389 | /* Display WA #1178: cnl */ |
| 413 | 390 | if (IS_CANNONLAKE(dev_priv) && |
| 414 | − (id == CNL_DISP_PW_AUX_B || id == CNL_DISP_PW_AUX_C || | |
| 415 | − id == CNL_DISP_PW_AUX_D || id == CNL_DISP_PW_AUX_F)) { | |
| 416 | − val = I915_READ(CNL_AUX_ANAOVRD1(id)); | |
| 391 | + pw_idx >= GLK_PW_CTL_IDX_AUX_B && | |
| 392 | + pw_idx <= CNL_PW_CTL_IDX_AUX_F) { | |
| 393 | + val = I915_READ(CNL_AUX_ANAOVRD1(pw_idx)); | |
| 417 | 394 | val |= CNL_AUX_ANAOVRD1_ENABLE | CNL_AUX_ANAOVRD1_LDO_BYPASS; |
| 418 | − I915_WRITE(CNL_AUX_ANAOVRD1(id), val); | |
| 395 | + I915_WRITE(CNL_AUX_ANAOVRD1(pw_idx), val); | |
| 419 | 396 | } |
| 420 | 397 | |
| 421 | 398 | if (wait_fuses) |
| 422 | 399 | gen9_wait_for_power_well_fuses(dev_priv, pg); |
| 423 | 400 | |
| 424 | − hsw_power_well_post_enable(dev_priv, power_well->hsw.irq_pipe_mask, | |
| 425 | − power_well->hsw.has_vga); | |
| 401 | + hsw_power_well_post_enable(dev_priv, | |
| 402 | + power_well->desc->hsw.irq_pipe_mask, | |
| 403 | + power_well->desc->hsw.has_vga); | |
| 426 | 404 | } |
| 427 | 405 | |
| 428 | 406 | static void hsw_power_well_disable(struct drm_i915_private *dev_priv, |
| 429 | 407 | struct i915_power_well *power_well) |
| 430 | 408 | { |
| 431 | − enum i915_power_well_id id = power_well->id; | |
| 409 | + const struct i915_power_well_regs *regs = power_well->desc->hsw.regs; | |
| 410 | + int pw_idx = power_well->desc->hsw.idx; | |
| 432 | 411 | u32 val; |
| 433 | 412 | |
| 434 | − hsw_power_well_pre_disable(dev_priv, power_well->hsw.irq_pipe_mask); | |
| 413 | + hsw_power_well_pre_disable(dev_priv, | |
| 414 | + power_well->desc->hsw.irq_pipe_mask); | |
| 435 | 415 | |
| 436 | − val = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)); | |
| 437 | − I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id), | |
| 438 | − val & ~HSW_PWR_WELL_CTL_REQ(id)); | |
| 416 | + val = I915_READ(regs->driver); | |
| 417 | + I915_WRITE(regs->driver, val & ~HSW_PWR_WELL_CTL_REQ(pw_idx)); | |
| 439 | 418 | hsw_wait_for_power_well_disable(dev_priv, power_well); |
| 440 | 419 | } |
| 441 | 420 | |
| 442 | −#define ICL_AUX_PW_TO_PORT(pw) ((pw) - ICL_DISP_PW_AUX_A) | |
| 421 | +#define ICL_AUX_PW_TO_PORT(pw_idx) ((pw_idx) - ICL_PW_CTL_IDX_AUX_A) | |
| 443 | 422 | |
| 444 | 423 | static void |
| 445 | 424 | icl_combo_phy_aux_power_well_enable(struct drm_i915_private *dev_priv, |
| 446 | 425 | struct i915_power_well *power_well) |
| 447 | 426 | { |
| 448 | − enum i915_power_well_id id = power_well->id; | |
| 449 | − enum port port = ICL_AUX_PW_TO_PORT(id); | |
| 427 | + const struct i915_power_well_regs *regs = power_well->desc->hsw.regs; | |
| 428 | + int pw_idx = power_well->desc->hsw.idx; | |
| 429 | + enum port port = ICL_AUX_PW_TO_PORT(pw_idx); | |
| 450 | 430 | u32 val; |
| 451 | 431 | |
| 452 | − val = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)); | |
| 453 | − I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id), val | HSW_PWR_WELL_CTL_REQ(id)); | |
| 432 | + val = I915_READ(regs->driver); | |
| 433 | + I915_WRITE(regs->driver, val | HSW_PWR_WELL_CTL_REQ(pw_idx)); | |
| 454 | 434 | |
| 455 | 435 | val = I915_READ(ICL_PORT_CL_DW12(port)); |
| 456 | 436 | I915_WRITE(ICL_PORT_CL_DW12(port), val | ICL_LANE_ENABLE_AUX); |
| @@ -462,16 +442,16 @@ static void · 5 unmodified lines | ||
| 462 | 442 | icl_combo_phy_aux_power_well_disable(struct drm_i915_private *dev_priv, |
| 463 | 443 | struct i915_power_well *power_well) |
| 464 | 444 | { |
| 465 | − enum i915_power_well_id id = power_well->id; | |
| 466 | − enum port port = ICL_AUX_PW_TO_PORT(id); | |
| 445 | + const struct i915_power_well_regs *regs = power_well->desc->hsw.regs; | |
| 446 | + int pw_idx = power_well->desc->hsw.idx; | |
| 447 | + enum port port = ICL_AUX_PW_TO_PORT(pw_idx); | |
| 467 | 448 | u32 val; |
| 468 | 449 | |
| 469 | 450 | val = I915_READ(ICL_PORT_CL_DW12(port)); |
| 470 | 451 | I915_WRITE(ICL_PORT_CL_DW12(port), val & ~ICL_LANE_ENABLE_AUX); |
| 471 | 452 | |
| 472 | − val = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)); | |
| 473 | − I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id), | |
| 474 | − val & ~HSW_PWR_WELL_CTL_REQ(id)); | |
| 453 | + val = I915_READ(regs->driver); | |
| 454 | + I915_WRITE(regs->driver, val & ~HSW_PWR_WELL_CTL_REQ(pw_idx)); | |
| 475 | 455 | |
| 476 | 456 | hsw_wait_for_power_well_disable(dev_priv, power_well); |
| 477 | 457 | } |
| @@ -484,22 +464,22 @@ icl_combo_phy_aux_power_well_disable(struct drm_i915_private *dev_priv, · 6 unmodified lines | ||
| 484 | 464 | static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv, |
| 485 | 465 | struct i915_power_well *power_well) |
| 486 | 466 | { |
| 487 | − enum i915_power_well_id id = power_well->id; | |
| 488 | − u32 mask = HSW_PWR_WELL_CTL_REQ(id) | HSW_PWR_WELL_CTL_STATE(id); | |
| 467 | + const struct i915_power_well_regs *regs = power_well->desc->hsw.regs; | |
| 468 | + int pw_idx = power_well->desc->hsw.idx; | |
| 469 | + u32 mask = HSW_PWR_WELL_CTL_REQ(pw_idx) | | |
| 470 | + HSW_PWR_WELL_CTL_STATE(pw_idx); | |
| 489 | 471 | |
| 490 | − return (I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) & mask) == mask; | |
| 472 | + return (I915_READ(regs->driver) & mask) == mask; | |
| 491 | 473 | } |
| 492 | 474 | |
| 493 | 475 | static void assert_can_enable_dc9(struct drm_i915_private *dev_priv) |
| 494 | 476 | { |
| 495 | − enum i915_power_well_id id = SKL_DISP_PW_2; | |
| 496 | − | |
| 497 | 477 | WARN_ONCE((I915_READ(DC_STATE_EN) & DC_STATE_EN_DC9), |
| 498 | 478 | "DC9 already programmed to be enabled.\n"); |
| 499 | 479 | WARN_ONCE(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5, |
| 500 | 480 | "DC5 still not disabled to enable DC9.\n"); |
| 501 | − WARN_ONCE(I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) & | |
| 502 | − HSW_PWR_WELL_CTL_REQ(id), | |
| 481 | + WARN_ONCE(I915_READ(HSW_PWR_WELL_CTL2) & | |
| 482 | + HSW_PWR_WELL_CTL_REQ(SKL_PW_CTL_IDX_PW_2), | |
| 503 | 483 | "Power well 2 on.\n"); |
| 504 | 484 | WARN_ONCE(intel_irqs_enabled(dev_priv), |
| 505 | 485 | "Interrupts not disabled yet.\n"); |
| @@ -668,6 +648,27 @@ static void assert_csr_loaded(struct drm_i915_private *dev_priv) · 162 unmodified lines | ||
| 668 | 648 | WARN_ONCE(!I915_READ(CSR_HTP_SKL), "CSR HTP Not fine\n"); |
| 669 | 649 | } |
| 670 | 650 | |
| 651 | +static struct i915_power_well * | |
| 652 | +lookup_power_well(struct drm_i915_private *dev_priv, | |
| 653 | + enum i915_power_well_id power_well_id) | |
| 654 | +{ | |
| 655 | + struct i915_power_well *power_well; | |
| 656 | + | |
| 657 | + for_each_power_well(dev_priv, power_well) | |
| 658 | + if (power_well->desc->id == power_well_id) | |
| 659 | + return power_well; | |
| 660 | + | |
| 661 | + /* | |
| 662 | + * It's not feasible to add error checking code to the callers since | |
| 663 | + * this condition really shouldn't happen and it doesn't even make sense | |
| 664 | + * to abort things like display initialization sequences. Just return | |
| 665 | + * the first power well and hope the WARN gets reported so we can fix | |
| 666 | + * our driver. | |
| 667 | + */ | |
| 668 | + WARN(1, "Power well %d not defined for this platform\n", power_well_id); | |
| 669 | + return &dev_priv->power_domains.power_wells[0]; | |
| 670 | +} | |
| 671 | + | |
| 671 | 672 | static void assert_can_enable_dc5(struct drm_i915_private *dev_priv) |
| 672 | 673 | { |
| 673 | 674 | bool pg2_enabled = intel_display_power_well_is_enabled(dev_priv, |
| @@ -723,54 +724,57 @@ static void skl_enable_dc6(struct drm_i915_private *dev_priv) · 49 unmodified lines | ||
| 723 | 724 | static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv, |
| 724 | 725 | struct i915_power_well *power_well) |
| 725 | 726 | { |
| 726 | − enum i915_power_well_id id = power_well->id; | |
| 727 | − u32 mask = HSW_PWR_WELL_CTL_REQ(id); | |
| 728 | − u32 bios_req = I915_READ(HSW_PWR_WELL_CTL_BIOS(id)); | |
| 727 | + const struct i915_power_well_regs *regs = power_well->desc->hsw.regs; | |
| 728 | + int pw_idx = power_well->desc->hsw.idx; | |
| 729 | + u32 mask = HSW_PWR_WELL_CTL_REQ(pw_idx); | |
| 730 | + u32 bios_req = I915_READ(regs->bios); | |
| 729 | 731 | |
| 730 | 732 | /* Take over the request bit if set by BIOS. */ |
| 731 | 733 | if (bios_req & mask) { |
| 732 | − u32 drv_req = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)); | |
| 734 | + u32 drv_req = I915_READ(regs->driver); | |
| 733 | 735 | |
| 734 | 736 | if (!(drv_req & mask)) |
| 735 | − I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id), drv_req | mask); | |
| 736 | − I915_WRITE(HSW_PWR_WELL_CTL_BIOS(id), bios_req & ~mask); | |
| 737 | + I915_WRITE(regs->driver, drv_req | mask); | |
| 738 | + I915_WRITE(regs->bios, bios_req & ~mask); | |
| 737 | 739 | } |
| 738 | 740 | } |
| 739 | 741 | |
| 740 | 742 | static void bxt_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, |
| 741 | 743 | struct i915_power_well *power_well) |
| 742 | 744 | { |
| 743 | − bxt_ddi_phy_init(dev_priv, power_well->bxt.phy); | |
| 745 | + bxt_ddi_phy_init(dev_priv, power_well->desc->bxt.phy); | |
| 744 | 746 | } |
| 745 | 747 | |
| 746 | 748 | static void bxt_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, |
| 747 | 749 | struct i915_power_well *power_well) |
| 748 | 750 | { |
| 749 | − bxt_ddi_phy_uninit(dev_priv, power_well->bxt.phy); | |
| 751 | + bxt_ddi_phy_uninit(dev_priv, power_well->desc->bxt.phy); | |
| 750 | 752 | } |
| 751 | 753 | |
| 752 | 754 | static bool bxt_dpio_cmn_power_well_enabled(struct drm_i915_private *dev_priv, |
| 753 | 755 | struct i915_power_well *power_well) |
| 754 | 756 | { |
| 755 | − return bxt_ddi_phy_is_enabled(dev_priv, power_well->bxt.phy); | |
| 757 | + return bxt_ddi_phy_is_enabled(dev_priv, power_well->desc->bxt.phy); | |
| 756 | 758 | } |
| 757 | 759 | |
| 758 | 760 | static void bxt_verify_ddi_phy_power_wells(struct drm_i915_private *dev_priv) |
| 759 | 761 | { |
| 760 | 762 | struct i915_power_well *power_well; |
| 761 | 763 | |
| 762 | − power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_A); | |
| 764 | + power_well = lookup_power_well(dev_priv, BXT_DISP_PW_DPIO_CMN_A); | |
| 763 | 765 | if (power_well->count > 0) |
| 764 | − bxt_ddi_phy_verify_state(dev_priv, power_well->bxt.phy); | |
| 766 | + bxt_ddi_phy_verify_state(dev_priv, power_well->desc->bxt.phy); | |
| 765 | 767 | |
| 766 | − power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_BC); | |
| 768 | + power_well = lookup_power_well(dev_priv, VLV_DISP_PW_DPIO_CMN_BC); | |
| 767 | 769 | if (power_well->count > 0) |
| 768 | − bxt_ddi_phy_verify_state(dev_priv, power_well->bxt.phy); | |
| 770 | + bxt_ddi_phy_verify_state(dev_priv, power_well->desc->bxt.phy); | |
| 769 | 771 | |
| 770 | 772 | if (IS_GEMINILAKE(dev_priv)) { |
| 771 | − power_well = lookup_power_well(dev_priv, GLK_DPIO_CMN_C); | |
| 773 | + power_well = lookup_power_well(dev_priv, | |
| 774 | + GLK_DISP_PW_DPIO_CMN_C); | |
| 772 | 775 | if (power_well->count > 0) |
| 773 | − bxt_ddi_phy_verify_state(dev_priv, power_well->bxt.phy); | |
| 776 | + bxt_ddi_phy_verify_state(dev_priv, | |
| 777 | + power_well->desc->bxt.phy); | |
| 774 | 778 | } |
| 775 | 779 | } |
| 776 | 780 | |
| @@ -869,14 +873,14 @@ static void i830_pipes_power_well_sync_hw(struct drm_i915_private *dev_priv, · 92 unmodified lines | ||
| 869 | 873 | static void vlv_set_power_well(struct drm_i915_private *dev_priv, |
| 870 | 874 | struct i915_power_well *power_well, bool enable) |
| 871 | 875 | { |
| 872 | − enum i915_power_well_id power_well_id = power_well->id; | |
| 876 | + int pw_idx = power_well->desc->vlv.idx; | |
| 873 | 877 | u32 mask; |
| 874 | 878 | u32 state; |
| 875 | 879 | u32 ctrl; |
| 876 | 880 | |
| 877 | − mask = PUNIT_PWRGT_MASK(power_well_id); | |
| 878 | − state = enable ? PUNIT_PWRGT_PWR_ON(power_well_id) : | |
| 879 | − PUNIT_PWRGT_PWR_GATE(power_well_id); | |
| 881 | + mask = PUNIT_PWRGT_MASK(pw_idx); | |
| 882 | + state = enable ? PUNIT_PWRGT_PWR_ON(pw_idx) : | |
| 883 | + PUNIT_PWRGT_PWR_GATE(pw_idx); | |
| 880 | 884 | |
| 881 | 885 | mutex_lock(&dev_priv->pcu_lock); |
| 882 | 886 | |
| @@ -917,14 +921,14 @@ static void vlv_power_well_disable(struct drm_i915_private *dev_priv, · 34 unmodified lines | ||
| 917 | 921 | static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv, |
| 918 | 922 | struct i915_power_well *power_well) |
| 919 | 923 | { |
| 920 | − enum i915_power_well_id power_well_id = power_well->id; | |
| 924 | + int pw_idx = power_well->desc->vlv.idx; | |
| 921 | 925 | bool enabled = false; |
| 922 | 926 | u32 mask; |
| 923 | 927 | u32 state; |
| 924 | 928 | u32 ctrl; |
| 925 | 929 | |
| 926 | − mask = PUNIT_PWRGT_MASK(power_well_id); | |
| 927 | − ctrl = PUNIT_PWRGT_PWR_ON(power_well_id); | |
| 930 | + mask = PUNIT_PWRGT_MASK(pw_idx); | |
| 931 | + ctrl = PUNIT_PWRGT_PWR_ON(pw_idx); | |
| 928 | 932 | |
| 929 | 933 | mutex_lock(&dev_priv->pcu_lock); |
| 930 | 934 | |
| @@ -933,8 +937,8 @@ static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv, · 2 unmodified lines | ||
| 933 | 937 | * We only ever set the power-on and power-gate states, anything |
| 934 | 938 | * else is unexpected. |
| 935 | 939 | */ |
| 936 | − WARN_ON(state != PUNIT_PWRGT_PWR_ON(power_well_id) && | |
| 937 | − state != PUNIT_PWRGT_PWR_GATE(power_well_id)); | |
| 940 | + WARN_ON(state != PUNIT_PWRGT_PWR_ON(pw_idx) && | |
| 941 | + state != PUNIT_PWRGT_PWR_GATE(pw_idx)); | |
| 938 | 942 | if (state == ctrl) |
| 939 | 943 | enabled = true; |
| 940 | 944 | |
| @@ -1045,8 +1049,6 @@ static void vlv_display_power_well_deinit(struct drm_i915_private *dev_priv) · 104 unmodified lines | ||
| 1045 | 1049 | static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv, |
| 1046 | 1050 | struct i915_power_well *power_well) |
| 1047 | 1051 | { |
| 1048 | − WARN_ON_ONCE(power_well->id != PUNIT_POWER_WELL_DISP2D); | |
| 1049 | − | |
| 1050 | 1052 | vlv_set_power_well(dev_priv, power_well, true); |
| 1051 | 1053 | |
| 1052 | 1054 | vlv_display_power_well_init(dev_priv); |
| @@ -1055,8 +1057,6 @@ static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv, · 2 unmodified lines | ||
| 1055 | 1057 | static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv, |
| 1056 | 1058 | struct i915_power_well *power_well) |
| 1057 | 1059 | { |
| 1058 | − WARN_ON_ONCE(power_well->id != PUNIT_POWER_WELL_DISP2D); | |
| 1059 | − | |
| 1060 | 1060 | vlv_display_power_well_deinit(dev_priv); |
| 1061 | 1061 | |
| 1062 | 1062 | vlv_set_power_well(dev_priv, power_well, false); |
| @@ -1065,8 +1065,6 @@ static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv, · 2 unmodified lines | ||
| 1065 | 1065 | static void vlv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, |
| 1066 | 1066 | struct i915_power_well *power_well) |
| 1067 | 1067 | { |
| 1068 | − WARN_ON_ONCE(power_well->id != PUNIT_POWER_WELL_DPIO_CMN_BC); | |
| 1069 | − | |
| 1070 | 1068 | /* since ref/cri clock was enabled */ |
| 1071 | 1069 | udelay(1); /* >10ns for cmnreset, >0ns for sidereset */ |
| 1072 | 1070 | |
| @@ -1091,8 +1089,6 @@ static void vlv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, · 18 unmodified lines | ||
| 1091 | 1089 | { |
| 1092 | 1090 | enum pipe pipe; |
| 1093 | 1091 | |
| 1094 | − WARN_ON_ONCE(power_well->id != PUNIT_POWER_WELL_DPIO_CMN_BC); | |
| 1095 | − | |
| 1096 | 1092 | for_each_pipe(dev_priv, pipe) |
| 1097 | 1093 | assert_pll_disabled(dev_priv, pipe); |
| 1098 | 1094 | |
| @@ -1104,32 +1100,14 @@ static void vlv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, · 5 unmodified lines | ||
| 1104 | 1100 | |
| 1105 | 1101 | #define POWER_DOMAIN_MASK (GENMASK_ULL(POWER_DOMAIN_NUM - 1, 0)) |
| 1106 | 1102 | |
| 1107 | −static struct i915_power_well * | |
| 1108 | −lookup_power_well(struct drm_i915_private *dev_priv, | |
| 1109 | − enum i915_power_well_id power_well_id) | |
| 1110 | −{ | |
| 1111 | − struct i915_power_domains *power_domains = &dev_priv->power_domains; | |
| 1112 | − int i; | |
| 1113 | − | |
| 1114 | − for (i = 0; i < power_domains->power_well_count; i++) { | |
| 1115 | − struct i915_power_well *power_well; | |
| 1116 | − | |
| 1117 | − power_well = &power_domains->power_wells[i]; | |
| 1118 | − if (power_well->id == power_well_id) | |
| 1119 | − return power_well; | |
| 1120 | − } | |
| 1121 | − | |
| 1122 | − return NULL; | |
| 1123 | −} | |
| 1124 | − | |
| 1125 | 1103 | #define BITS_SET(val, bits) (((val) & (bits)) == (bits)) |
| 1126 | 1104 | |
| 1127 | 1105 | static void assert_chv_phy_status(struct drm_i915_private *dev_priv) |
| 1128 | 1106 | { |
| 1129 | 1107 | struct i915_power_well *cmn_bc = |
| 1130 | − lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC); | |
| 1108 | + lookup_power_well(dev_priv, VLV_DISP_PW_DPIO_CMN_BC); | |
| 1131 | 1109 | struct i915_power_well *cmn_d = |
| 1132 | − lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_D); | |
| 1110 | + lookup_power_well(dev_priv, CHV_DISP_PW_DPIO_CMN_D); | |
| 1133 | 1111 | u32 phy_control = dev_priv->chv_phy_control; |
| 1134 | 1112 | u32 phy_status = 0; |
| 1135 | 1113 | u32 phy_status_mask = 0xffffffff; |
| @@ -1154,7 +1132,7 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv) · 18 unmodified lines | ||
| 1154 | 1132 | PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 0) | |
| 1155 | 1133 | PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 1)); |
| 1156 | 1134 | |
| 1157 | − if (cmn_bc->ops->is_enabled(dev_priv, cmn_bc)) { | |
| 1135 | + if (cmn_bc->desc->ops->is_enabled(dev_priv, cmn_bc)) { | |
| 1158 | 1136 | phy_status |= PHY_POWERGOOD(DPIO_PHY0); |
| 1159 | 1137 | |
| 1160 | 1138 | /* this assumes override is only used to enable lanes */ |
| @@ -1195,7 +1173,7 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv) · 34 unmodified lines | ||
| 1195 | 1173 | phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH1, 1); |
| 1196 | 1174 | } |
| 1197 | 1175 | |
| 1198 | − if (cmn_d->ops->is_enabled(dev_priv, cmn_d)) { | |
| 1176 | + if (cmn_d->desc->ops->is_enabled(dev_priv, cmn_d)) { | |
| 1199 | 1177 | phy_status |= PHY_POWERGOOD(DPIO_PHY1); |
| 1200 | 1178 | |
| 1201 | 1179 | /* this assumes override is only used to enable lanes */ |
| @@ -1239,10 +1217,10 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, · 37 unmodified lines | ||
| 1239 | 1217 | enum pipe pipe; |
| 1240 | 1218 | uint32_t tmp; |
| 1241 | 1219 | |
| 1242 | − WARN_ON_ONCE(power_well->id != PUNIT_POWER_WELL_DPIO_CMN_BC && | |
| 1243 | − power_well->id != PUNIT_POWER_WELL_DPIO_CMN_D); | |
| 1220 | + WARN_ON_ONCE(power_well->desc->id != VLV_DISP_PW_DPIO_CMN_BC && | |
| 1221 | + power_well->desc->id != CHV_DISP_PW_DPIO_CMN_D); | |
| 1244 | 1222 | |
| 1245 | − if (power_well->id == PUNIT_POWER_WELL_DPIO_CMN_BC) { | |
| 1223 | + if (power_well->desc->id == VLV_DISP_PW_DPIO_CMN_BC) { | |
| 1246 | 1224 | pipe = PIPE_A; |
| 1247 | 1225 | phy = DPIO_PHY0; |
| 1248 | 1226 | } else { |
| @@ -1270,7 +1248,7 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, · 21 unmodified lines | ||
| 1270 | 1248 | DPIO_SUS_CLK_CONFIG_GATE_CLKREQ; |
| 1271 | 1249 | vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW28, tmp); |
| 1272 | 1250 | |
| 1273 | − if (power_well->id == PUNIT_POWER_WELL_DPIO_CMN_BC) { | |
| 1251 | + if (power_well->desc->id == VLV_DISP_PW_DPIO_CMN_BC) { | |
| 1274 | 1252 | tmp = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW6_CH1); |
| 1275 | 1253 | tmp |= DPIO_DYNPWRDOWNEN_CH1; |
| 1276 | 1254 | vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW6_CH1, tmp); |
| @@ -1301,10 +1279,10 @@ static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, · 24 unmodified lines | ||
| 1301 | 1279 | { |
| 1302 | 1280 | enum dpio_phy phy; |
| 1303 | 1281 | |
| 1304 | − WARN_ON_ONCE(power_well->id != PUNIT_POWER_WELL_DPIO_CMN_BC && | |
| 1305 | − power_well->id != PUNIT_POWER_WELL_DPIO_CMN_D); | |
| 1282 | + WARN_ON_ONCE(power_well->desc->id != VLV_DISP_PW_DPIO_CMN_BC && | |
| 1283 | + power_well->desc->id != CHV_DISP_PW_DPIO_CMN_D); | |
| 1306 | 1284 | |
| 1307 | − if (power_well->id == PUNIT_POWER_WELL_DPIO_CMN_BC) { | |
| 1285 | + if (power_well->desc->id == VLV_DISP_PW_DPIO_CMN_BC) { | |
| 1308 | 1286 | phy = DPIO_PHY0; |
| 1309 | 1287 | assert_pll_disabled(dev_priv, PIPE_A); |
| 1310 | 1288 | assert_pll_disabled(dev_priv, PIPE_B); |
| @@ -1516,8 +1494,6 @@ out: · 205 unmodified lines | ||
| 1516 | 1494 | static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv, |
| 1517 | 1495 | struct i915_power_well *power_well) |
| 1518 | 1496 | { |
| 1519 | − WARN_ON_ONCE(power_well->id != CHV_DISP_PW_PIPE_A); | |
| 1520 | − | |
| 1521 | 1497 | chv_set_pipe_power_well(dev_priv, power_well, true); |
| 1522 | 1498 | |
| 1523 | 1499 | vlv_display_power_well_init(dev_priv); |
| @@ -1526,8 +1502,6 @@ static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv, · 2 unmodified lines | ||
| 1526 | 1502 | static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv, |
| 1527 | 1503 | struct i915_power_well *power_well) |
| 1528 | 1504 | { |
| 1529 | − WARN_ON_ONCE(power_well->id != CHV_DISP_PW_PIPE_A); | |
| 1530 | − | |
| 1531 | 1505 | vlv_display_power_well_deinit(dev_priv); |
| 1532 | 1506 | |
| 1533 | 1507 | chv_set_pipe_power_well(dev_priv, power_well, false); |
| @@ -2063,13 +2037,13 @@ static const struct i915_power_well_ops chv_dpio_cmn_power_well_ops = { · 529 unmodified lines | ||
| 2063 | 2037 | .is_enabled = vlv_power_well_enabled, |
| 2064 | 2038 | }; |
| 2065 | 2039 | |
| 2066 | −static struct i915_power_well i9xx_always_on_power_well[] = { | |
| 2040 | +static const struct i915_power_well_desc i9xx_always_on_power_well[] = { | |
| 2067 | 2041 | { |
| 2068 | 2042 | .name = "always-on", |
| 2069 | 2043 | .always_on = 1, |
| 2070 | 2044 | .domains = POWER_DOMAIN_MASK, |
| 2071 | 2045 | .ops = &i9xx_always_on_power_well_ops, |
| 2072 | − .id = I915_DISP_PW_ALWAYS_ON, | |
| 2046 | + .id = DISP_PW_ID_NONE, | |
| 2073 | 2047 | }, |
| 2074 | 2048 | }; |
| 2075 | 2049 | |
| @@ -2080,19 +2054,19 @@ static const struct i915_power_well_ops i830_pipes_power_well_ops = { · 4 unmodified lines | ||
| 2080 | 2054 | .is_enabled = i830_pipes_power_well_enabled, |
| 2081 | 2055 | }; |
| 2082 | 2056 | |
| 2083 | −static struct i915_power_well i830_power_wells[] = { | |
| 2057 | +static const struct i915_power_well_desc i830_power_wells[] = { | |
| 2084 | 2058 | { |
| 2085 | 2059 | .name = "always-on", |
| 2086 | 2060 | .always_on = 1, |
| 2087 | 2061 | .domains = POWER_DOMAIN_MASK, |
| 2088 | 2062 | .ops = &i9xx_always_on_power_well_ops, |
| 2089 | − .id = I915_DISP_PW_ALWAYS_ON, | |
| 2063 | + .id = DISP_PW_ID_NONE, | |
| 2090 | 2064 | }, |
| 2091 | 2065 | { |
| 2092 | 2066 | .name = "pipes", |
| 2093 | 2067 | .domains = I830_PIPES_POWER_DOMAINS, |
| 2094 | 2068 | .ops = &i830_pipes_power_well_ops, |
| 2095 | − .id = I830_DISP_PW_PIPES, | |
| 2069 | + .id = DISP_PW_ID_NONE, | |
| 2096 | 2070 | }, |
| 2097 | 2071 | }; |
| 2098 | 2072 | |
| @@ -2117,13 +2091,20 @@ static const struct i915_power_well_ops bxt_dpio_cmn_power_well_ops = { · 18 unmodified lines | ||
| 2117 | 2091 | .is_enabled = bxt_dpio_cmn_power_well_enabled, |
| 2118 | 2092 | }; |
| 2119 | 2093 | |
| 2120 | −static struct i915_power_well hsw_power_wells[] = { | |
| 2094 | +static const struct i915_power_well_regs hsw_power_well_regs = { | |
| 2095 | + .bios = HSW_PWR_WELL_CTL1, | |
| 2096 | + .driver = HSW_PWR_WELL_CTL2, | |
| 2097 | + .kvmr = HSW_PWR_WELL_CTL3, | |
| 2098 | + .debug = HSW_PWR_WELL_CTL4, | |
| 2099 | +}; | |
| 2100 | + | |
| 2101 | +static const struct i915_power_well_desc hsw_power_wells[] = { | |
| 2121 | 2102 | { |
| 2122 | 2103 | .name = "always-on", |
| 2123 | 2104 | .always_on = 1, |
| 2124 | 2105 | .domains = POWER_DOMAIN_MASK, |
| 2125 | 2106 | .ops = &i9xx_always_on_power_well_ops, |
| 2126 | − .id = I915_DISP_PW_ALWAYS_ON, | |
| 2107 | + .id = DISP_PW_ID_NONE, | |
| 2127 | 2108 | }, |
| 2128 | 2109 | { |
| 2129 | 2110 | .name = "display", |
| @@ -2131,18 +2112,20 @@ static struct i915_power_well hsw_power_wells[] = { · 1 unmodified line | ||
| 2131 | 2112 | .ops = &hsw_power_well_ops, |
| 2132 | 2113 | .id = HSW_DISP_PW_GLOBAL, |
| 2133 | 2114 | { |
| 2115 | + .hsw.regs = &hsw_power_well_regs, | |
| 2116 | + .hsw.idx = HSW_PW_CTL_IDX_GLOBAL, | |
| 2134 | 2117 | .hsw.has_vga = true, |
| 2135 | 2118 | }, |
| 2136 | 2119 | }, |
| 2137 | 2120 | }; |
| 2138 | 2121 | |
| 2139 | −static struct i915_power_well bdw_power_wells[] = { | |
| 2122 | +static const struct i915_power_well_desc bdw_power_wells[] = { | |
| 2140 | 2123 | { |
| 2141 | 2124 | .name = "always-on", |
| 2142 | 2125 | .always_on = 1, |
| 2143 | 2126 | .domains = POWER_DOMAIN_MASK, |
| 2144 | 2127 | .ops = &i9xx_always_on_power_well_ops, |
| 2145 | − .id = I915_DISP_PW_ALWAYS_ON, | |
| 2128 | + .id = DISP_PW_ID_NONE, | |
| 2146 | 2129 | }, |
| 2147 | 2130 | { |
| 2148 | 2131 | .name = "display", |
| @@ -2150,6 +2133,8 @@ static struct i915_power_well bdw_power_wells[] = { · 1 unmodified line | ||
| 2150 | 2133 | .ops = &hsw_power_well_ops, |
| 2151 | 2134 | .id = HSW_DISP_PW_GLOBAL, |
| 2152 | 2135 | { |
| 2136 | + .hsw.regs = &hsw_power_well_regs, | |
| 2137 | + .hsw.idx = HSW_PW_CTL_IDX_GLOBAL, | |
| 2153 | 2138 | .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C), |
| 2154 | 2139 | .hsw.has_vga = true, |
| 2155 | 2140 | }, |
| @@ -2177,19 +2162,22 @@ static const struct i915_power_well_ops vlv_dpio_power_well_ops = { · 21 unmodified lines | ||
| 2177 | 2162 | .is_enabled = vlv_power_well_enabled, |
| 2178 | 2163 | }; |
| 2179 | 2164 | |
| 2180 | −static struct i915_power_well vlv_power_wells[] = { | |
| 2165 | +static const struct i915_power_well_desc vlv_power_wells[] = { | |
| 2181 | 2166 | { |
| 2182 | 2167 | .name = "always-on", |
| 2183 | 2168 | .always_on = 1, |
| 2184 | 2169 | .domains = POWER_DOMAIN_MASK, |
| 2185 | 2170 | .ops = &i9xx_always_on_power_well_ops, |
| 2186 | − .id = I915_DISP_PW_ALWAYS_ON, | |
| 2171 | + .id = DISP_PW_ID_NONE, | |
| 2187 | 2172 | }, |
| 2188 | 2173 | { |
| 2189 | 2174 | .name = "display", |
| 2190 | 2175 | .domains = VLV_DISPLAY_POWER_DOMAINS, |
| 2191 | − .id = PUNIT_POWER_WELL_DISP2D, | |
| 2192 | 2176 | .ops = &vlv_display_power_well_ops, |
| 2177 | + .id = VLV_DISP_PW_DISP2D, | |
| 2178 | + { | |
| 2179 | + .vlv.idx = PUNIT_PWGT_IDX_DISP2D, | |
| 2180 | + }, | |
| 2193 | 2181 | }, |
| 2194 | 2182 | { |
| 2195 | 2183 | .name = "dpio-tx-b-01", |
| @@ -2198,7 +2186,10 @@ static struct i915_power_well vlv_power_wells[] = { · 2 unmodified lines | ||
| 2198 | 2186 | VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | |
| 2199 | 2187 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, |
| 2200 | 2188 | .ops = &vlv_dpio_power_well_ops, |
| 2201 | − .id = PUNIT_POWER_WELL_DPIO_TX_B_LANES_01, | |
| 2189 | + .id = DISP_PW_ID_NONE, | |
| 2190 | + { | |
| 2191 | + .vlv.idx = PUNIT_PWGT_IDX_DPIO_TX_B_LANES_01, | |
| 2192 | + }, | |
| 2202 | 2193 | }, |
| 2203 | 2194 | { |
| 2204 | 2195 | .name = "dpio-tx-b-23", |
| @@ -2207,7 +2198,10 @@ static struct i915_power_well vlv_power_wells[] = { · 2 unmodified lines | ||
| 2207 | 2198 | VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | |
| 2208 | 2199 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, |
| 2209 | 2200 | .ops = &vlv_dpio_power_well_ops, |
| 2210 | − .id = PUNIT_POWER_WELL_DPIO_TX_B_LANES_23, | |
| 2201 | + .id = DISP_PW_ID_NONE, | |
| 2202 | + { | |
| 2203 | + .vlv.idx = PUNIT_PWGT_IDX_DPIO_TX_B_LANES_23, | |
| 2204 | + }, | |
| 2211 | 2205 | }, |
| 2212 | 2206 | { |
| 2213 | 2207 | .name = "dpio-tx-c-01", |
| @@ -2216,7 +2210,10 @@ static struct i915_power_well vlv_power_wells[] = { · 2 unmodified lines | ||
| 2216 | 2210 | VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | |
| 2217 | 2211 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, |
| 2218 | 2212 | .ops = &vlv_dpio_power_well_ops, |
| 2219 | − .id = PUNIT_POWER_WELL_DPIO_TX_C_LANES_01, | |
| 2213 | + .id = DISP_PW_ID_NONE, | |
| 2214 | + { | |
| 2215 | + .vlv.idx = PUNIT_PWGT_IDX_DPIO_TX_C_LANES_01, | |
| 2216 | + }, | |
| 2220 | 2217 | }, |
| 2221 | 2218 | { |
| 2222 | 2219 | .name = "dpio-tx-c-23", |
| @@ -2225,23 +2222,29 @@ static struct i915_power_well vlv_power_wells[] = { · 2 unmodified lines | ||
| 2225 | 2222 | VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | |
| 2226 | 2223 | VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, |
| 2227 | 2224 | .ops = &vlv_dpio_power_well_ops, |
| 2228 | − .id = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23, | |
| 2225 | + .id = DISP_PW_ID_NONE, | |
| 2226 | + { | |
| 2227 | + .vlv.idx = PUNIT_PWGT_IDX_DPIO_TX_C_LANES_23, | |
| 2228 | + }, | |
| 2229 | 2229 | }, |
| 2230 | 2230 | { |
| 2231 | 2231 | .name = "dpio-common", |
| 2232 | 2232 | .domains = VLV_DPIO_CMN_BC_POWER_DOMAINS, |
| 2233 | − .id = PUNIT_POWER_WELL_DPIO_CMN_BC, | |
| 2234 | 2233 | .ops = &vlv_dpio_cmn_power_well_ops, |
| 2234 | + .id = VLV_DISP_PW_DPIO_CMN_BC, | |
| 2235 | + { | |
| 2236 | + .vlv.idx = PUNIT_PWGT_IDX_DPIO_CMN_BC, | |
| 2237 | + }, | |
| 2235 | 2238 | }, |
| 2236 | 2239 | }; |
| 2237 | 2240 | |
| 2238 | −static struct i915_power_well chv_power_wells[] = { | |
| 2241 | +static const struct i915_power_well_desc chv_power_wells[] = { | |
| 2239 | 2242 | { |
| 2240 | 2243 | .name = "always-on", |
| 2241 | 2244 | .always_on = 1, |
| 2242 | 2245 | .domains = POWER_DOMAIN_MASK, |
| 2243 | 2246 | .ops = &i9xx_always_on_power_well_ops, |
| 2244 | − .id = I915_DISP_PW_ALWAYS_ON, | |
| 2247 | + .id = DISP_PW_ID_NONE, | |
| 2245 | 2248 | }, |
| 2246 | 2249 | { |
| 2247 | 2250 | .name = "display", |
| @@ -2251,20 +2254,26 @@ static struct i915_power_well chv_power_wells[] = { · 3 unmodified lines | ||
| 2251 | 2254 | * required for any pipe to work. |
| 2252 | 2255 | */ |
| 2253 | 2256 | .domains = CHV_DISPLAY_POWER_DOMAINS, |
| 2254 | − .id = CHV_DISP_PW_PIPE_A, | |
| 2255 | 2257 | .ops = &chv_pipe_power_well_ops, |
| 2258 | + .id = DISP_PW_ID_NONE, | |
| 2256 | 2259 | }, |
| 2257 | 2260 | { |
| 2258 | 2261 | .name = "dpio-common-bc", |
| 2259 | 2262 | .domains = CHV_DPIO_CMN_BC_POWER_DOMAINS, |
| 2260 | − .id = PUNIT_POWER_WELL_DPIO_CMN_BC, | |
| 2261 | 2263 | .ops = &chv_dpio_cmn_power_well_ops, |
| 2264 | + .id = VLV_DISP_PW_DPIO_CMN_BC, | |
| 2265 | + { | |
| 2266 | + .vlv.idx = PUNIT_PWGT_IDX_DPIO_CMN_BC, | |
| 2267 | + }, | |
| 2262 | 2268 | }, |
| 2263 | 2269 | { |
| 2264 | 2270 | .name = "dpio-common-d", |
| 2265 | 2271 | .domains = CHV_DPIO_CMN_D_POWER_DOMAINS, |
| 2266 | − .id = PUNIT_POWER_WELL_DPIO_CMN_D, | |
| 2267 | 2272 | .ops = &chv_dpio_cmn_power_well_ops, |
| 2273 | + .id = CHV_DISP_PW_DPIO_CMN_D, | |
| 2274 | + { | |
| 2275 | + .vlv.idx = PUNIT_PWGT_IDX_DPIO_CMN_D, | |
| 2276 | + }, | |
| 2268 | 2277 | }, |
| 2269 | 2278 | }; |
| 2270 | 2279 | |
| @@ -2275,18 +2284,18 @@ bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv, · 4 unmodified lines | ||
| 2275 | 2284 | bool ret; |
| 2276 | 2285 | |
| 2277 | 2286 | power_well = lookup_power_well(dev_priv, power_well_id); |
| 2278 | − ret = power_well->ops->is_enabled(dev_priv, power_well); | |
| 2287 | + ret = power_well->desc->ops->is_enabled(dev_priv, power_well); | |
| 2279 | 2288 | |
| 2280 | 2289 | return ret; |
| 2281 | 2290 | } |
| 2282 | 2291 | |
| 2283 | −static struct i915_power_well skl_power_wells[] = { | |
| 2292 | +static const struct i915_power_well_desc skl_power_wells[] = { | |
| 2284 | 2293 | { |
| 2285 | 2294 | .name = "always-on", |
| 2286 | 2295 | .always_on = 1, |
| 2287 | 2296 | .domains = POWER_DOMAIN_MASK, |
| 2288 | 2297 | .ops = &i9xx_always_on_power_well_ops, |
| 2289 | − .id = I915_DISP_PW_ALWAYS_ON, | |
| 2298 | + .id = DISP_PW_ID_NONE, | |
| 2290 | 2299 | }, |
| 2291 | 2300 | { |
| 2292 | 2301 | .name = "power well 1", |
| @@ -2295,6 +2304,8 @@ static struct i915_power_well skl_power_wells[] = { · 2 unmodified lines | ||
| 2295 | 2304 | .ops = &hsw_power_well_ops, |
| 2296 | 2305 | .id = SKL_DISP_PW_1, |
| 2297 | 2306 | { |
| 2307 | + .hsw.regs = &hsw_power_well_regs, | |
| 2308 | + .hsw.idx = SKL_PW_CTL_IDX_PW_1, | |
| 2298 | 2309 | .hsw.has_fuses = true, |
| 2299 | 2310 | }, |
| 2300 | 2311 | }, |
| @@ -2304,12 +2315,16 @@ static struct i915_power_well skl_power_wells[] = { · 3 unmodified lines | ||
| 2304 | 2315 | .domains = 0, |
| 2305 | 2316 | .ops = &hsw_power_well_ops, |
| 2306 | 2317 | .id = SKL_DISP_PW_MISC_IO, |
| 2318 | + { | |
| 2319 | + .hsw.regs = &hsw_power_well_regs, | |
| 2320 | + .hsw.idx = SKL_PW_CTL_IDX_MISC_IO, | |
| 2321 | + }, | |
| 2307 | 2322 | }, |
| 2308 | 2323 | { |
| 2309 | 2324 | .name = "DC off", |
| 2310 | 2325 | .domains = SKL_DISPLAY_DC_OFF_POWER_DOMAINS, |
| 2311 | 2326 | .ops = &gen9_dc_off_power_well_ops, |
| 2312 | − .id = SKL_DISP_PW_DC_OFF, | |
| 2327 | + .id = DISP_PW_ID_NONE, | |
| 2313 | 2328 | }, |
| 2314 | 2329 | { |
| 2315 | 2330 | .name = "power well 2", |
| @@ -2317,6 +2332,8 @@ static struct i915_power_well skl_power_wells[] = { · 1 unmodified line | ||
| 2317 | 2332 | .ops = &hsw_power_well_ops, |
| 2318 | 2333 | .id = SKL_DISP_PW_2, |
| 2319 | 2334 | { |
| 2335 | + .hsw.regs = &hsw_power_well_regs, | |
| 2336 | + .hsw.idx = SKL_PW_CTL_IDX_PW_2, | |
| 2320 | 2337 | .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C), |
| 2321 | 2338 | .hsw.has_vga = true, |
| 2322 | 2339 | .hsw.has_fuses = true, |
| @@ -2326,35 +2343,51 @@ static struct i915_power_well skl_power_wells[] = { · 3 unmodified lines | ||
| 2326 | 2343 | .name = "DDI A/E IO power well", |
| 2327 | 2344 | .domains = SKL_DISPLAY_DDI_IO_A_E_POWER_DOMAINS, |
| 2328 | 2345 | .ops = &hsw_power_well_ops, |
| 2329 | − .id = SKL_DISP_PW_DDI_A_E, | |
| 2346 | + .id = DISP_PW_ID_NONE, | |
| 2347 | + { | |
| 2348 | + .hsw.regs = &hsw_power_well_regs, | |
| 2349 | + .hsw.idx = SKL_PW_CTL_IDX_DDI_A_E, | |
| 2350 | + }, | |
| 2330 | 2351 | }, |
| 2331 | 2352 | { |
| 2332 | 2353 | .name = "DDI B IO power well", |
| 2333 | 2354 | .domains = SKL_DISPLAY_DDI_IO_B_POWER_DOMAINS, |
| 2334 | 2355 | .ops = &hsw_power_well_ops, |
| 2335 | − .id = SKL_DISP_PW_DDI_B, | |
| 2356 | + .id = DISP_PW_ID_NONE, | |
| 2357 | + { | |
| 2358 | + .hsw.regs = &hsw_power_well_regs, | |
| 2359 | + .hsw.idx = SKL_PW_CTL_IDX_DDI_B, | |
| 2360 | + }, | |
| 2336 | 2361 | }, |
| 2337 | 2362 | { |
| 2338 | 2363 | .name = "DDI C IO power well", |
| 2339 | 2364 | .domains = SKL_DISPLAY_DDI_IO_C_POWER_DOMAINS, |
| 2340 | 2365 | .ops = &hsw_power_well_ops, |
| 2341 | − .id = SKL_DISP_PW_DDI_C, | |
| 2366 | + .id = DISP_PW_ID_NONE, | |
| 2367 | + { | |
| 2368 | + .hsw.regs = &hsw_power_well_regs, | |
| 2369 | + .hsw.idx = SKL_PW_CTL_IDX_DDI_C, | |
| 2370 | + }, | |
| 2342 | 2371 | }, |
| 2343 | 2372 | { |
| 2344 | 2373 | .name = "DDI D IO power well", |
| 2345 | 2374 | .domains = SKL_DISPLAY_DDI_IO_D_POWER_DOMAINS, |
| 2346 | 2375 | .ops = &hsw_power_well_ops, |
| 2347 | − .id = SKL_DISP_PW_DDI_D, | |
| 2376 | + .id = DISP_PW_ID_NONE, | |
| 2377 | + { | |
| 2378 | + .hsw.regs = &hsw_power_well_regs, | |
| 2379 | + .hsw.idx = SKL_PW_CTL_IDX_DDI_D, | |
| 2380 | + }, | |
| 2348 | 2381 | }, |
| 2349 | 2382 | }; |
| 2350 | 2383 | |
| 2351 | −static struct i915_power_well bxt_power_wells[] = { | |
| 2384 | +static const struct i915_power_well_desc bxt_power_wells[] = { | |
| 2352 | 2385 | { |
| 2353 | 2386 | .name = "always-on", |
| 2354 | 2387 | .always_on = 1, |
| 2355 | 2388 | .domains = POWER_DOMAIN_MASK, |
| 2356 | 2389 | .ops = &i9xx_always_on_power_well_ops, |
| 2357 | − .id = I915_DISP_PW_ALWAYS_ON, | |
| 2390 | + .id = DISP_PW_ID_NONE, | |
| 2358 | 2391 | }, |
| 2359 | 2392 | { |
| 2360 | 2393 | .name = "power well 1", |
| @@ -2362,6 +2395,8 @@ static struct i915_power_well bxt_power_wells[] = { · 1 unmodified line | ||
| 2362 | 2395 | .ops = &hsw_power_well_ops, |
| 2363 | 2396 | .id = SKL_DISP_PW_1, |
| 2364 | 2397 | { |
| 2398 | + .hsw.regs = &hsw_power_well_regs, | |
| 2399 | + .hsw.idx = SKL_PW_CTL_IDX_PW_1, | |
| 2365 | 2400 | .hsw.has_fuses = true, |
| 2366 | 2401 | }, |
| 2367 | 2402 | }, |
| @@ -2369,7 +2404,7 @@ static struct i915_power_well bxt_power_wells[] = { · 1 unmodified line | ||
| 2369 | 2404 | .name = "DC off", |
| 2370 | 2405 | .domains = BXT_DISPLAY_DC_OFF_POWER_DOMAINS, |
| 2371 | 2406 | .ops = &gen9_dc_off_power_well_ops, |
| 2372 | − .id = SKL_DISP_PW_DC_OFF, | |
| 2407 | + .id = DISP_PW_ID_NONE, | |
| 2373 | 2408 | }, |
| 2374 | 2409 | { |
| 2375 | 2410 | .name = "power well 2", |
| @@ -2377,6 +2412,8 @@ static struct i915_power_well bxt_power_wells[] = { · 1 unmodified line | ||
| 2377 | 2412 | .ops = &hsw_power_well_ops, |
| 2378 | 2413 | .id = SKL_DISP_PW_2, |
| 2379 | 2414 | { |
| 2415 | + .hsw.regs = &hsw_power_well_regs, | |
| 2416 | + .hsw.idx = SKL_PW_CTL_IDX_PW_2, | |
| 2380 | 2417 | .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C), |
| 2381 | 2418 | .hsw.has_vga = true, |
| 2382 | 2419 | .hsw.has_fuses = true, |
| @@ -2386,7 +2423,7 @@ static struct i915_power_well bxt_power_wells[] = { · 3 unmodified lines | ||
| 2386 | 2423 | .name = "dpio-common-a", |
| 2387 | 2424 | .domains = BXT_DPIO_CMN_A_POWER_DOMAINS, |
| 2388 | 2425 | .ops = &bxt_dpio_cmn_power_well_ops, |
| 2389 | − .id = BXT_DPIO_CMN_A, | |
| 2426 | + .id = BXT_DISP_PW_DPIO_CMN_A, | |
| 2390 | 2427 | { |
| 2391 | 2428 | .bxt.phy = DPIO_PHY1, |
| 2392 | 2429 | }, |
| @@ -2395,20 +2432,20 @@ static struct i915_power_well bxt_power_wells[] = { · 2 unmodified lines | ||
| 2395 | 2432 | .name = "dpio-common-bc", |
| 2396 | 2433 | .domains = BXT_DPIO_CMN_BC_POWER_DOMAINS, |
| 2397 | 2434 | .ops = &bxt_dpio_cmn_power_well_ops, |
| 2398 | − .id = BXT_DPIO_CMN_BC, | |
| 2435 | + .id = VLV_DISP_PW_DPIO_CMN_BC, | |
| 2399 | 2436 | { |
| 2400 | 2437 | .bxt.phy = DPIO_PHY0, |
| 2401 | 2438 | }, |
| 2402 | 2439 | }, |
| 2403 | 2440 | }; |
| 2404 | 2441 | |
| 2405 | −static struct i915_power_well glk_power_wells[] = { | |
| 2442 | +static const struct i915_power_well_desc glk_power_wells[] = { | |
| 2406 | 2443 | { |
| 2407 | 2444 | .name = "always-on", |
| 2408 | 2445 | .always_on = 1, |
| 2409 | 2446 | .domains = POWER_DOMAIN_MASK, |
| 2410 | 2447 | .ops = &i9xx_always_on_power_well_ops, |
| 2411 | − .id = I915_DISP_PW_ALWAYS_ON, | |
| 2448 | + .id = DISP_PW_ID_NONE, | |
| 2412 | 2449 | }, |
| 2413 | 2450 | { |
| 2414 | 2451 | .name = "power well 1", |
| @@ -2417,6 +2454,8 @@ static struct i915_power_well glk_power_wells[] = { · 2 unmodified lines | ||
| 2417 | 2454 | .ops = &hsw_power_well_ops, |
| 2418 | 2455 | .id = SKL_DISP_PW_1, |
| 2419 | 2456 | { |
| 2457 | + .hsw.regs = &hsw_power_well_regs, | |
| 2458 | + .hsw.idx = SKL_PW_CTL_IDX_PW_1, | |
| 2420 | 2459 | .hsw.has_fuses = true, |
| 2421 | 2460 | }, |
| 2422 | 2461 | }, |
| @@ -2424,7 +2463,7 @@ static struct i915_power_well glk_power_wells[] = { · 1 unmodified line | ||
| 2424 | 2463 | .name = "DC off", |
| 2425 | 2464 | .domains = GLK_DISPLAY_DC_OFF_POWER_DOMAINS, |
| 2426 | 2465 | .ops = &gen9_dc_off_power_well_ops, |
| 2427 | − .id = SKL_DISP_PW_DC_OFF, | |
| 2466 | + .id = DISP_PW_ID_NONE, | |
| 2428 | 2467 | }, |
| 2429 | 2468 | { |
| 2430 | 2469 | .name = "power well 2", |
| @@ -2432,6 +2471,8 @@ static struct i915_power_well glk_power_wells[] = { · 1 unmodified line | ||
| 2432 | 2471 | .ops = &hsw_power_well_ops, |
| 2433 | 2472 | .id = SKL_DISP_PW_2, |
| 2434 | 2473 | { |
| 2474 | + .hsw.regs = &hsw_power_well_regs, | |
| 2475 | + .hsw.idx = SKL_PW_CTL_IDX_PW_2, | |
| 2435 | 2476 | .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C), |
| 2436 | 2477 | .hsw.has_vga = true, |
| 2437 | 2478 | .hsw.has_fuses = true, |
| @@ -2441,7 +2482,7 @@ static struct i915_power_well glk_power_wells[] = { · 3 unmodified lines | ||
| 2441 | 2482 | .name = "dpio-common-a", |
| 2442 | 2483 | .domains = GLK_DPIO_CMN_A_POWER_DOMAINS, |
| 2443 | 2484 | .ops = &bxt_dpio_cmn_power_well_ops, |
| 2444 | − .id = BXT_DPIO_CMN_A, | |
| 2485 | + .id = BXT_DISP_PW_DPIO_CMN_A, | |
| 2445 | 2486 | { |
| 2446 | 2487 | .bxt.phy = DPIO_PHY1, |
| 2447 | 2488 | }, |
| @@ -2450,7 +2491,7 @@ static struct i915_power_well glk_power_wells[] = { · 2 unmodified lines | ||
| 2450 | 2491 | .name = "dpio-common-b", |
| 2451 | 2492 | .domains = GLK_DPIO_CMN_B_POWER_DOMAINS, |
| 2452 | 2493 | .ops = &bxt_dpio_cmn_power_well_ops, |
| 2453 | − .id = BXT_DPIO_CMN_BC, | |
| 2494 | + .id = VLV_DISP_PW_DPIO_CMN_BC, | |
| 2454 | 2495 | { |
| 2455 | 2496 | .bxt.phy = DPIO_PHY0, |
| 2456 | 2497 | }, |
| @@ -2459,7 +2500,7 @@ static struct i915_power_well glk_power_wells[] = { · 2 unmodified lines | ||
| 2459 | 2500 | .name = "dpio-common-c", |
| 2460 | 2501 | .domains = GLK_DPIO_CMN_C_POWER_DOMAINS, |
| 2461 | 2502 | .ops = &bxt_dpio_cmn_power_well_ops, |
| 2462 | − .id = GLK_DPIO_CMN_C, | |
| 2503 | + .id = GLK_DISP_PW_DPIO_CMN_C, | |
| 2463 | 2504 | { |
| 2464 | 2505 | .bxt.phy = DPIO_PHY2, |
| 2465 | 2506 | }, |
| @@ -2468,47 +2509,71 @@ static struct i915_power_well glk_power_wells[] = { · 2 unmodified lines | ||
| 2468 | 2509 | .name = "AUX A", |
| 2469 | 2510 | .domains = GLK_DISPLAY_AUX_A_POWER_DOMAINS, |
| 2470 | 2511 | .ops = &hsw_power_well_ops, |
| 2471 | − .id = GLK_DISP_PW_AUX_A, | |
| 2512 | + .id = DISP_PW_ID_NONE, | |
| 2513 | + { | |
| 2514 | + .hsw.regs = &hsw_power_well_regs, | |
| 2515 | + .hsw.idx = GLK_PW_CTL_IDX_AUX_A, | |
| 2516 | + }, | |
| 2472 | 2517 | }, |
| 2473 | 2518 | { |
| 2474 | 2519 | .name = "AUX B", |
| 2475 | 2520 | .domains = GLK_DISPLAY_AUX_B_POWER_DOMAINS, |
| 2476 | 2521 | .ops = &hsw_power_well_ops, |
| 2477 | − .id = GLK_DISP_PW_AUX_B, | |
| 2522 | + .id = DISP_PW_ID_NONE, | |
| 2523 | + { | |
| 2524 | + .hsw.regs = &hsw_power_well_regs, | |
| 2525 | + .hsw.idx = GLK_PW_CTL_IDX_AUX_B, | |
| 2526 | + }, | |
| 2478 | 2527 | }, |
| 2479 | 2528 | { |
| 2480 | 2529 | .name = "AUX C", |
| 2481 | 2530 | .domains = GLK_DISPLAY_AUX_C_POWER_DOMAINS, |
| 2482 | 2531 | .ops = &hsw_power_well_ops, |
| 2483 | − .id = GLK_DISP_PW_AUX_C, | |
| 2532 | + .id = DISP_PW_ID_NONE, | |
| 2533 | + { | |
| 2534 | + .hsw.regs = &hsw_power_well_regs, | |
| 2535 | + .hsw.idx = GLK_PW_CTL_IDX_AUX_C, | |
| 2536 | + }, | |
| 2484 | 2537 | }, |
| 2485 | 2538 | { |
| 2486 | 2539 | .name = "DDI A IO power well", |
| 2487 | 2540 | .domains = GLK_DISPLAY_DDI_IO_A_POWER_DOMAINS, |
| 2488 | 2541 | .ops = &hsw_power_well_ops, |
| 2489 | − .id = GLK_DISP_PW_DDI_A, | |
| 2542 | + .id = DISP_PW_ID_NONE, | |
| 2543 | + { | |
| 2544 | + .hsw.regs = &hsw_power_well_regs, | |
| 2545 | + .hsw.idx = GLK_PW_CTL_IDX_DDI_A, | |
| 2546 | + }, | |
| 2490 | 2547 | }, |
| 2491 | 2548 | { |
| 2492 | 2549 | .name = "DDI B IO power well", |
| 2493 | 2550 | .domains = GLK_DISPLAY_DDI_IO_B_POWER_DOMAINS, |
| 2494 | 2551 | .ops = &hsw_power_well_ops, |
| 2495 | − .id = SKL_DISP_PW_DDI_B, | |
| 2552 | + .id = DISP_PW_ID_NONE, | |
| 2553 | + { | |
| 2554 | + .hsw.regs = &hsw_power_well_regs, | |
| 2555 | + .hsw.idx = SKL_PW_CTL_IDX_DDI_B, | |
| 2556 | + }, | |
| 2496 | 2557 | }, |
| 2497 | 2558 | { |
| 2498 | 2559 | .name = "DDI C IO power well", |
| 2499 | 2560 | .domains = GLK_DISPLAY_DDI_IO_C_POWER_DOMAINS, |
| 2500 | 2561 | .ops = &hsw_power_well_ops, |
| 2501 | − .id = SKL_DISP_PW_DDI_C, | |
| 2562 | + .id = DISP_PW_ID_NONE, | |
| 2563 | + { | |
| 2564 | + .hsw.regs = &hsw_power_well_regs, | |
| 2565 | + .hsw.idx = SKL_PW_CTL_IDX_DDI_C, | |
| 2566 | + }, | |
| 2502 | 2567 | }, |
| 2503 | 2568 | }; |
| 2504 | 2569 | |
| 2505 | −static struct i915_power_well cnl_power_wells[] = { | |
| 2570 | +static const struct i915_power_well_desc cnl_power_wells[] = { | |
| 2506 | 2571 | { |
| 2507 | 2572 | .name = "always-on", |
| 2508 | 2573 | .always_on = 1, |
| 2509 | 2574 | .domains = POWER_DOMAIN_MASK, |
| 2510 | 2575 | .ops = &i9xx_always_on_power_well_ops, |
| 2511 | − .id = I915_DISP_PW_ALWAYS_ON, | |
| 2576 | + .id = DISP_PW_ID_NONE, | |
| 2512 | 2577 | }, |
| 2513 | 2578 | { |
| 2514 | 2579 | .name = "power well 1", |
| @@ -2517,6 +2582,8 @@ static struct i915_power_well cnl_power_wells[] = { · 2 unmodified lines | ||
| 2517 | 2582 | .ops = &hsw_power_well_ops, |
| 2518 | 2583 | .id = SKL_DISP_PW_1, |
| 2519 | 2584 | { |
| 2585 | + .hsw.regs = &hsw_power_well_regs, | |
| 2586 | + .hsw.idx = SKL_PW_CTL_IDX_PW_1, | |
| 2520 | 2587 | .hsw.has_fuses = true, |
| 2521 | 2588 | }, |
| 2522 | 2589 | }, |
| @@ -2524,31 +2591,47 @@ static struct i915_power_well cnl_power_wells[] = { · 1 unmodified line | ||
| 2524 | 2591 | .name = "AUX A", |
| 2525 | 2592 | .domains = CNL_DISPLAY_AUX_A_POWER_DOMAINS, |
| 2526 | 2593 | .ops = &hsw_power_well_ops, |
| 2527 | − .id = CNL_DISP_PW_AUX_A, | |
| 2594 | + .id = DISP_PW_ID_NONE, | |
| 2595 | + { | |
| 2596 | + .hsw.regs = &hsw_power_well_regs, | |
| 2597 | + .hsw.idx = GLK_PW_CTL_IDX_AUX_A, | |
| 2598 | + }, | |
| 2528 | 2599 | }, |
| 2529 | 2600 | { |
| 2530 | 2601 | .name = "AUX B", |
| 2531 | 2602 | .domains = CNL_DISPLAY_AUX_B_POWER_DOMAINS, |
| 2532 | 2603 | .ops = &hsw_power_well_ops, |
| 2533 | − .id = CNL_DISP_PW_AUX_B, | |
| 2604 | + .id = DISP_PW_ID_NONE, | |
| 2605 | + { | |
| 2606 | + .hsw.regs = &hsw_power_well_regs, | |
| 2607 | + .hsw.idx = GLK_PW_CTL_IDX_AUX_B, | |
| 2608 | + }, | |
| 2534 | 2609 | }, |
| 2535 | 2610 | { |
| 2536 | 2611 | .name = "AUX C", |
| 2537 | 2612 | .domains = CNL_DISPLAY_AUX_C_POWER_DOMAINS, |
| 2538 | 2613 | .ops = &hsw_power_well_ops, |
| 2539 | − .id = CNL_DISP_PW_AUX_C, | |
| 2614 | + .id = DISP_PW_ID_NONE, | |
| 2615 | + { | |
| 2616 | + .hsw.regs = &hsw_power_well_regs, | |
| 2617 | + .hsw.idx = GLK_PW_CTL_IDX_AUX_C, | |
| 2618 | + }, | |
| 2540 | 2619 | }, |
| 2541 | 2620 | { |
| 2542 | 2621 | .name = "AUX D", |
| 2543 | 2622 | .domains = CNL_DISPLAY_AUX_D_POWER_DOMAINS, |
| 2544 | 2623 | .ops = &hsw_power_well_ops, |
| 2545 | − .id = CNL_DISP_PW_AUX_D, | |
| 2624 | + .id = DISP_PW_ID_NONE, | |
| 2625 | + { | |
| 2626 | + .hsw.regs = &hsw_power_well_regs, | |
| 2627 | + .hsw.idx = CNL_PW_CTL_IDX_AUX_D, | |
| 2628 | + }, | |
| 2546 | 2629 | }, |
| 2547 | 2630 | { |
| 2548 | 2631 | .name = "DC off", |
| 2549 | 2632 | .domains = CNL_DISPLAY_DC_OFF_POWER_DOMAINS, |
| 2550 | 2633 | .ops = &gen9_dc_off_power_well_ops, |
| 2551 | − .id = SKL_DISP_PW_DC_OFF, | |
| 2634 | + .id = DISP_PW_ID_NONE, | |
| 2552 | 2635 | }, |
| 2553 | 2636 | { |
| 2554 | 2637 | .name = "power well 2", |
| @@ -2556,6 +2639,8 @@ static struct i915_power_well cnl_power_wells[] = { · 1 unmodified line | ||
| 2556 | 2639 | .ops = &hsw_power_well_ops, |
| 2557 | 2640 | .id = SKL_DISP_PW_2, |
| 2558 | 2641 | { |
| 2642 | + .hsw.regs = &hsw_power_well_regs, | |
| 2643 | + .hsw.idx = SKL_PW_CTL_IDX_PW_2, | |
| 2559 | 2644 | .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C), |
| 2560 | 2645 | .hsw.has_vga = true, |
| 2561 | 2646 | .hsw.has_fuses = true, |
| @@ -2565,37 +2650,61 @@ static struct i915_power_well cnl_power_wells[] = { · 3 unmodified lines | ||
| 2565 | 2650 | .name = "DDI A IO power well", |
| 2566 | 2651 | .domains = CNL_DISPLAY_DDI_A_IO_POWER_DOMAINS, |
| 2567 | 2652 | .ops = &hsw_power_well_ops, |
| 2568 | − .id = CNL_DISP_PW_DDI_A, | |
| 2653 | + .id = DISP_PW_ID_NONE, | |
| 2654 | + { | |
| 2655 | + .hsw.regs = &hsw_power_well_regs, | |
| 2656 | + .hsw.idx = GLK_PW_CTL_IDX_DDI_A, | |
| 2657 | + }, | |
| 2569 | 2658 | }, |
| 2570 | 2659 | { |
| 2571 | 2660 | .name = "DDI B IO power well", |
| 2572 | 2661 | .domains = CNL_DISPLAY_DDI_B_IO_POWER_DOMAINS, |
| 2573 | 2662 | .ops = &hsw_power_well_ops, |
| 2574 | − .id = SKL_DISP_PW_DDI_B, | |
| 2663 | + .id = DISP_PW_ID_NONE, | |
| 2664 | + { | |
| 2665 | + .hsw.regs = &hsw_power_well_regs, | |
| 2666 | + .hsw.idx = SKL_PW_CTL_IDX_DDI_B, | |
| 2667 | + }, | |
| 2575 | 2668 | }, |
| 2576 | 2669 | { |
| 2577 | 2670 | .name = "DDI C IO power well", |
| 2578 | 2671 | .domains = CNL_DISPLAY_DDI_C_IO_POWER_DOMAINS, |
| 2579 | 2672 | .ops = &hsw_power_well_ops, |
| 2580 | − .id = SKL_DISP_PW_DDI_C, | |
| 2673 | + .id = DISP_PW_ID_NONE, | |
| 2674 | + { | |
| 2675 | + .hsw.regs = &hsw_power_well_regs, | |
| 2676 | + .hsw.idx = SKL_PW_CTL_IDX_DDI_C, | |
| 2677 | + }, | |
| 2581 | 2678 | }, |
| 2582 | 2679 | { |
| 2583 | 2680 | .name = "DDI D IO power well", |
| 2584 | 2681 | .domains = CNL_DISPLAY_DDI_D_IO_POWER_DOMAINS, |
| 2585 | 2682 | .ops = &hsw_power_well_ops, |
| 2586 | − .id = SKL_DISP_PW_DDI_D, | |
| 2683 | + .id = DISP_PW_ID_NONE, | |
| 2684 | + { | |
| 2685 | + .hsw.regs = &hsw_power_well_regs, | |
| 2686 | + .hsw.idx = SKL_PW_CTL_IDX_DDI_D, | |
| 2687 | + }, | |
| 2587 | 2688 | }, |
| 2588 | 2689 | { |
| 2589 | 2690 | .name = "DDI F IO power well", |
| 2590 | 2691 | .domains = CNL_DISPLAY_DDI_F_IO_POWER_DOMAINS, |
| 2591 | 2692 | .ops = &hsw_power_well_ops, |
| 2592 | − .id = CNL_DISP_PW_DDI_F, | |
| 2693 | + .id = DISP_PW_ID_NONE, | |
| 2694 | + { | |
| 2695 | + .hsw.regs = &hsw_power_well_regs, | |
| 2696 | + .hsw.idx = CNL_PW_CTL_IDX_DDI_F, | |
| 2697 | + }, | |
| 2593 | 2698 | }, |
| 2594 | 2699 | { |
| 2595 | 2700 | .name = "AUX F", |
| 2596 | 2701 | .domains = CNL_DISPLAY_AUX_F_POWER_DOMAINS, |
| 2597 | 2702 | .ops = &hsw_power_well_ops, |
| 2598 | − .id = CNL_DISP_PW_AUX_F, | |
| 2703 | + .id = DISP_PW_ID_NONE, | |
| 2704 | + { | |
| 2705 | + .hsw.regs = &hsw_power_well_regs, | |
| 2706 | + .hsw.idx = CNL_PW_CTL_IDX_AUX_F, | |
| 2707 | + }, | |
| 2599 | 2708 | }, |
| 2600 | 2709 | }; |
| 2601 | 2710 | |
| @@ -2606,147 +2715,239 @@ static const struct i915_power_well_ops icl_combo_phy_aux_power_well_ops = { · 4 unmodified lines | ||
| 2606 | 2715 | .is_enabled = hsw_power_well_enabled, |
| 2607 | 2716 | }; |
| 2608 | 2717 | |
| 2609 | −static struct i915_power_well icl_power_wells[] = { | |
| 2718 | +static const struct i915_power_well_regs icl_aux_power_well_regs = { | |
| 2719 | + .bios = ICL_PWR_WELL_CTL_AUX1, | |
| 2720 | + .driver = ICL_PWR_WELL_CTL_AUX2, | |
| 2721 | + .debug = ICL_PWR_WELL_CTL_AUX4, | |
| 2722 | +}; | |
| 2723 | + | |
| 2724 | +static const struct i915_power_well_regs icl_ddi_power_well_regs = { | |
| 2725 | + .bios = ICL_PWR_WELL_CTL_DDI1, | |
| 2726 | + .driver = ICL_PWR_WELL_CTL_DDI2, | |
| 2727 | + .debug = ICL_PWR_WELL_CTL_DDI4, | |
| 2728 | +}; | |
| 2729 | + | |
| 2730 | +static const struct i915_power_well_desc icl_power_wells[] = { | |
| 2610 | 2731 | { |
| 2611 | 2732 | .name = "always-on", |
| 2612 | 2733 | .always_on = 1, |
| 2613 | 2734 | .domains = POWER_DOMAIN_MASK, |
| 2614 | 2735 | .ops = &i9xx_always_on_power_well_ops, |
| 2615 | − .id = I915_DISP_PW_ALWAYS_ON, | |
| 2736 | + .id = DISP_PW_ID_NONE, | |
| 2616 | 2737 | }, |
| 2617 | 2738 | { |
| 2618 | 2739 | .name = "power well 1", |
| 2619 | 2740 | /* Handled by the DMC firmware */ |
| 2620 | 2741 | .domains = 0, |
| 2621 | 2742 | .ops = &hsw_power_well_ops, |
| 2622 | − .id = ICL_DISP_PW_1, | |
| 2623 | − .hsw.has_fuses = true, | |
| 2743 | + .id = SKL_DISP_PW_1, | |
| 2744 | + { | |
| 2745 | + .hsw.regs = &hsw_power_well_regs, | |
| 2746 | + .hsw.idx = ICL_PW_CTL_IDX_PW_1, | |
| 2747 | + .hsw.has_fuses = true, | |
| 2748 | + }, | |
| 2624 | 2749 | }, |
| 2625 | 2750 | { |
| 2626 | 2751 | .name = "power well 2", |
| 2627 | 2752 | .domains = ICL_PW_2_POWER_DOMAINS, |
| 2628 | 2753 | .ops = &hsw_power_well_ops, |
| 2629 | − .id = ICL_DISP_PW_2, | |
| 2630 | − .hsw.has_fuses = true, | |
| 2754 | + .id = SKL_DISP_PW_2, | |
| 2755 | + { | |
| 2756 | + .hsw.regs = &hsw_power_well_regs, | |
| 2757 | + .hsw.idx = ICL_PW_CTL_IDX_PW_2, | |
| 2758 | + .hsw.has_fuses = true, | |
| 2759 | + }, | |
| 2631 | 2760 | }, |
| 2632 | 2761 | { |
| 2633 | 2762 | .name = "DC off", |
| 2634 | 2763 | .domains = ICL_DISPLAY_DC_OFF_POWER_DOMAINS, |
| 2635 | 2764 | .ops = &gen9_dc_off_power_well_ops, |
| 2636 | − .id = SKL_DISP_PW_DC_OFF, | |
| 2765 | + .id = DISP_PW_ID_NONE, | |
| 2637 | 2766 | }, |
| 2638 | 2767 | { |
| 2639 | 2768 | .name = "power well 3", |
| 2640 | 2769 | .domains = ICL_PW_3_POWER_DOMAINS, |
| 2641 | 2770 | .ops = &hsw_power_well_ops, |
| 2642 | − .id = ICL_DISP_PW_3, | |
| 2643 | − .hsw.irq_pipe_mask = BIT(PIPE_B), | |
| 2644 | − .hsw.has_vga = true, | |
| 2645 | − .hsw.has_fuses = true, | |
| 2771 | + .id = DISP_PW_ID_NONE, | |
| 2772 | + { | |
| 2773 | + .hsw.regs = &hsw_power_well_regs, | |
| 2774 | + .hsw.idx = ICL_PW_CTL_IDX_PW_3, | |
| 2775 | + .hsw.irq_pipe_mask = BIT(PIPE_B), | |
| 2776 | + .hsw.has_vga = true, | |
| 2777 | + .hsw.has_fuses = true, | |
| 2778 | + }, | |
| 2646 | 2779 | }, |
| 2647 | 2780 | { |
| 2648 | 2781 | .name = "DDI A IO", |
| 2649 | 2782 | .domains = ICL_DDI_IO_A_POWER_DOMAINS, |
| 2650 | 2783 | .ops = &hsw_power_well_ops, |
| 2651 | − .id = ICL_DISP_PW_DDI_A, | |
| 2784 | + .id = DISP_PW_ID_NONE, | |
| 2785 | + { | |
| 2786 | + .hsw.regs = &icl_ddi_power_well_regs, | |
| 2787 | + .hsw.idx = ICL_PW_CTL_IDX_DDI_A, | |
| 2788 | + }, | |
| 2652 | 2789 | }, |
| 2653 | 2790 | { |
| 2654 | 2791 | .name = "DDI B IO", |
| 2655 | 2792 | .domains = ICL_DDI_IO_B_POWER_DOMAINS, |
| 2656 | 2793 | .ops = &hsw_power_well_ops, |
| 2657 | − .id = ICL_DISP_PW_DDI_B, | |
| 2794 | + .id = DISP_PW_ID_NONE, | |
| 2795 | + { | |
| 2796 | + .hsw.regs = &icl_ddi_power_well_regs, | |
| 2797 | + .hsw.idx = ICL_PW_CTL_IDX_DDI_B, | |
| 2798 | + }, | |
| 2658 | 2799 | }, |
| 2659 | 2800 | { |
| 2660 | 2801 | .name = "DDI C IO", |
| 2661 | 2802 | .domains = ICL_DDI_IO_C_POWER_DOMAINS, |
| 2662 | 2803 | .ops = &hsw_power_well_ops, |
| 2663 | − .id = ICL_DISP_PW_DDI_C, | |
| 2804 | + .id = DISP_PW_ID_NONE, | |
| 2805 | + { | |
| 2806 | + .hsw.regs = &icl_ddi_power_well_regs, | |
| 2807 | + .hsw.idx = ICL_PW_CTL_IDX_DDI_C, | |
| 2808 | + }, | |
| 2664 | 2809 | }, |
| 2665 | 2810 | { |
| 2666 | 2811 | .name = "DDI D IO", |
| 2667 | 2812 | .domains = ICL_DDI_IO_D_POWER_DOMAINS, |
| 2668 | 2813 | .ops = &hsw_power_well_ops, |
| 2669 | − .id = ICL_DISP_PW_DDI_D, | |
| 2814 | + .id = DISP_PW_ID_NONE, | |
| 2815 | + { | |
| 2816 | + .hsw.regs = &icl_ddi_power_well_regs, | |
| 2817 | + .hsw.idx = ICL_PW_CTL_IDX_DDI_D, | |
| 2818 | + }, | |
| 2670 | 2819 | }, |
| 2671 | 2820 | { |
| 2672 | 2821 | .name = "DDI E IO", |
| 2673 | 2822 | .domains = ICL_DDI_IO_E_POWER_DOMAINS, |
| 2674 | 2823 | .ops = &hsw_power_well_ops, |
| 2675 | − .id = ICL_DISP_PW_DDI_E, | |
| 2824 | + .id = DISP_PW_ID_NONE, | |
| 2825 | + { | |
| 2826 | + .hsw.regs = &icl_ddi_power_well_regs, | |
| 2827 | + .hsw.idx = ICL_PW_CTL_IDX_DDI_E, | |
| 2828 | + }, | |
| 2676 | 2829 | }, |
| 2677 | 2830 | { |
| 2678 | 2831 | .name = "DDI F IO", |
| 2679 | 2832 | .domains = ICL_DDI_IO_F_POWER_DOMAINS, |
| 2680 | 2833 | .ops = &hsw_power_well_ops, |
| 2681 | − .id = ICL_DISP_PW_DDI_F, | |
| 2834 | + .id = DISP_PW_ID_NONE, | |
| 2835 | + { | |
| 2836 | + .hsw.regs = &icl_ddi_power_well_regs, | |
| 2837 | + .hsw.idx = ICL_PW_CTL_IDX_DDI_F, | |
| 2838 | + }, | |
| 2682 | 2839 | }, |
| 2683 | 2840 | { |
| 2684 | 2841 | .name = "AUX A", |
| 2685 | 2842 | .domains = ICL_AUX_A_IO_POWER_DOMAINS, |
| 2686 | 2843 | .ops = &icl_combo_phy_aux_power_well_ops, |
| 2687 | − .id = ICL_DISP_PW_AUX_A, | |
| 2844 | + .id = DISP_PW_ID_NONE, | |
| 2845 | + { | |
| 2846 | + .hsw.regs = &icl_aux_power_well_regs, | |
| 2847 | + .hsw.idx = ICL_PW_CTL_IDX_AUX_A, | |
| 2848 | + }, | |
| 2688 | 2849 | }, |
| 2689 | 2850 | { |
| 2690 | 2851 | .name = "AUX B", |
| 2691 | 2852 | .domains = ICL_AUX_B_IO_POWER_DOMAINS, |
| 2692 | 2853 | .ops = &icl_combo_phy_aux_power_well_ops, |
| 2693 | − .id = ICL_DISP_PW_AUX_B, | |
| 2854 | + .id = DISP_PW_ID_NONE, | |
| 2855 | + { | |
| 2856 | + .hsw.regs = &icl_aux_power_well_regs, | |
| 2857 | + .hsw.idx = ICL_PW_CTL_IDX_AUX_B, | |
| 2858 | + }, | |
| 2694 | 2859 | }, |
| 2695 | 2860 | { |
| 2696 | 2861 | .name = "AUX C", |
| 2697 | 2862 | .domains = ICL_AUX_C_IO_POWER_DOMAINS, |
| 2698 | 2863 | .ops = &hsw_power_well_ops, |
| 2699 | − .id = ICL_DISP_PW_AUX_C, | |
| 2864 | + .id = DISP_PW_ID_NONE, | |
| 2865 | + { | |
| 2866 | + .hsw.regs = &icl_aux_power_well_regs, | |
| 2867 | + .hsw.idx = ICL_PW_CTL_IDX_AUX_C, | |
| 2868 | + }, | |
| 2700 | 2869 | }, |
| 2701 | 2870 | { |
| 2702 | 2871 | .name = "AUX D", |
| 2703 | 2872 | .domains = ICL_AUX_D_IO_POWER_DOMAINS, |
| 2704 | 2873 | .ops = &hsw_power_well_ops, |
| 2705 | − .id = ICL_DISP_PW_AUX_D, | |
| 2874 | + .id = DISP_PW_ID_NONE, | |
| 2875 | + { | |
| 2876 | + .hsw.regs = &icl_aux_power_well_regs, | |
| 2877 | + .hsw.idx = ICL_PW_CTL_IDX_AUX_D, | |
| 2878 | + }, | |
| 2706 | 2879 | }, |
| 2707 | 2880 | { |
| 2708 | 2881 | .name = "AUX E", |
| 2709 | 2882 | .domains = ICL_AUX_E_IO_POWER_DOMAINS, |
| 2710 | 2883 | .ops = &hsw_power_well_ops, |
| 2711 | − .id = ICL_DISP_PW_AUX_E, | |
| 2884 | + .id = DISP_PW_ID_NONE, | |
| 2885 | + { | |
| 2886 | + .hsw.regs = &icl_aux_power_well_regs, | |
| 2887 | + .hsw.idx = ICL_PW_CTL_IDX_AUX_E, | |
| 2888 | + }, | |
| 2712 | 2889 | }, |
| 2713 | 2890 | { |
| 2714 | 2891 | .name = "AUX F", |
| 2715 | 2892 | .domains = ICL_AUX_F_IO_POWER_DOMAINS, |
| 2716 | 2893 | .ops = &hsw_power_well_ops, |
| 2717 | − .id = ICL_DISP_PW_AUX_F, | |
| 2894 | + .id = DISP_PW_ID_NONE, | |
| 2895 | + { | |
| 2896 | + .hsw.regs = &icl_aux_power_well_regs, | |
| 2897 | + .hsw.idx = ICL_PW_CTL_IDX_AUX_F, | |
| 2898 | + }, | |
| 2718 | 2899 | }, |
| 2719 | 2900 | { |
| 2720 | 2901 | .name = "AUX TBT1", |
| 2721 | 2902 | .domains = ICL_AUX_TBT1_IO_POWER_DOMAINS, |
| 2722 | 2903 | .ops = &hsw_power_well_ops, |
| 2723 | − .id = ICL_DISP_PW_AUX_TBT1, | |
| 2904 | + .id = DISP_PW_ID_NONE, | |
| 2905 | + { | |
| 2906 | + .hsw.regs = &icl_aux_power_well_regs, | |
| 2907 | + .hsw.idx = ICL_PW_CTL_IDX_AUX_TBT1, | |
| 2908 | + }, | |
| 2724 | 2909 | }, |
| 2725 | 2910 | { |
| 2726 | 2911 | .name = "AUX TBT2", |
| 2727 | 2912 | .domains = ICL_AUX_TBT2_IO_POWER_DOMAINS, |
| 2728 | 2913 | .ops = &hsw_power_well_ops, |
| 2729 | − .id = ICL_DISP_PW_AUX_TBT2, | |
| 2914 | + .id = DISP_PW_ID_NONE, | |
| 2915 | + { | |
| 2916 | + .hsw.regs = &icl_aux_power_well_regs, | |
| 2917 | + .hsw.idx = ICL_PW_CTL_IDX_AUX_TBT2, | |
| 2918 | + }, | |
| 2730 | 2919 | }, |
| 2731 | 2920 | { |
| 2732 | 2921 | .name = "AUX TBT3", |
| 2733 | 2922 | .domains = ICL_AUX_TBT3_IO_POWER_DOMAINS, |
| 2734 | 2923 | .ops = &hsw_power_well_ops, |
| 2735 | − .id = ICL_DISP_PW_AUX_TBT3, | |
| 2924 | + .id = DISP_PW_ID_NONE, | |
| 2925 | + { | |
| 2926 | + .hsw.regs = &icl_aux_power_well_regs, | |
| 2927 | + .hsw.idx = ICL_PW_CTL_IDX_AUX_TBT3, | |
| 2928 | + }, | |
| 2736 | 2929 | }, |
| 2737 | 2930 | { |
| 2738 | 2931 | .name = "AUX TBT4", |
| 2739 | 2932 | .domains = ICL_AUX_TBT4_IO_POWER_DOMAINS, |
| 2740 | 2933 | .ops = &hsw_power_well_ops, |
| 2741 | − .id = ICL_DISP_PW_AUX_TBT4, | |
| 2934 | + .id = DISP_PW_ID_NONE, | |
| 2935 | + { | |
| 2936 | + .hsw.regs = &icl_aux_power_well_regs, | |
| 2937 | + .hsw.idx = ICL_PW_CTL_IDX_AUX_TBT4, | |
| 2938 | + }, | |
| 2742 | 2939 | }, |
| 2743 | 2940 | { |
| 2744 | 2941 | .name = "power well 4", |
| 2745 | 2942 | .domains = ICL_PW_4_POWER_DOMAINS, |
| 2746 | 2943 | .ops = &hsw_power_well_ops, |
| 2747 | − .id = ICL_DISP_PW_4, | |
| 2748 | − .hsw.has_fuses = true, | |
| 2749 | − .hsw.irq_pipe_mask = BIT(PIPE_C), | |
| 2944 | + .id = DISP_PW_ID_NONE, | |
| 2945 | + { | |
| 2946 | + .hsw.regs = &hsw_power_well_regs, | |
| 2947 | + .hsw.idx = ICL_PW_CTL_IDX_PW_4, | |
| 2948 | + .hsw.has_fuses = true, | |
| 2949 | + .hsw.irq_pipe_mask = BIT(PIPE_C), | |
| 2950 | + }, | |
| 2750 | 2951 | }, |
| 2751 | 2952 | }; |
| 2752 | 2953 | |
| @@ -2809,26 +3010,41 @@ static uint32_t get_allowed_dc_mask(const struct drm_i915_private *dev_priv, · 56 unmodified lines | ||
| 2809 | 3010 | return mask; |
| 2810 | 3011 | } |
| 2811 | 3012 | |
| 2812 | −static void assert_power_well_ids_unique(struct drm_i915_private *dev_priv) | |
| 3013 | +static int | |
| 3014 | +__set_power_wells(struct i915_power_domains *power_domains, | |
| 3015 | + const struct i915_power_well_desc *power_well_descs, | |
| 3016 | + int power_well_count) | |
| 2813 | 3017 | { |
| 2814 | − struct i915_power_domains *power_domains = &dev_priv->power_domains; | |
| 2815 | − u64 power_well_ids; | |
| 3018 | + u64 power_well_ids = 0; | |
| 2816 | 3019 | int i; |
| 2817 | 3020 | |
| 2818 | − power_well_ids = 0; | |
| 2819 | − for (i = 0; i < power_domains->power_well_count; i++) { | |
| 2820 | − enum i915_power_well_id id = power_domains->power_wells[i].id; | |
| 3021 | + power_domains->power_well_count = power_well_count; | |
| 3022 | + power_domains->power_wells = | |
| 3023 | + kcalloc(power_well_count, | |
| 3024 | + sizeof(*power_domains->power_wells), | |
| 3025 | + GFP_KERNEL); | |
| 3026 | + if (!power_domains->power_wells) | |
| 3027 | + return -ENOMEM; | |
| 3028 | + | |
| 3029 | + for (i = 0; i < power_well_count; i++) { | |
| 3030 | + enum i915_power_well_id id = power_well_descs[i].id; | |
| 3031 | + | |
| 3032 | + power_domains->power_wells[i].desc = &power_well_descs[i]; | |
| 3033 | + | |
| 3034 | + if (id == DISP_PW_ID_NONE) | |
| 3035 | + continue; | |
| 2821 | 3036 | |
| 2822 | 3037 | WARN_ON(id >= sizeof(power_well_ids) * 8); |
| 2823 | 3038 | WARN_ON(power_well_ids & BIT_ULL(id)); |
| 2824 | 3039 | power_well_ids |= BIT_ULL(id); |
| 2825 | 3040 | } |
| 3041 | + | |
| 3042 | + return 0; | |
| 2826 | 3043 | } |
| 2827 | 3044 | |
| 2828 | −#define set_power_wells(power_domains, __power_wells) ({ \ | |
| 2829 | − (power_domains)->power_wells = (__power_wells); \ | |
| 2830 | − (power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \ | |
| 2831 | −}) | |
| 3045 | +#define set_power_wells(power_domains, __power_well_descs) \ | |
| 3046 | + __set_power_wells(power_domains, __power_well_descs, \ | |
| 3047 | + ARRAY_SIZE(__power_well_descs)) | |
| 2832 | 3048 | |
| 2833 | 3049 | /** |
| 2834 | 3050 | * intel_power_domains_init - initializes the power domain structures |
| @@ -2840,6 +3056,7 @@ static void assert_power_well_ids_unique(struct drm_i915_private *dev_priv) · 5 unmodified lines | ||
| 2840 | 3056 | int intel_power_domains_init(struct drm_i915_private *dev_priv) |
| 2841 | 3057 | { |
| 2842 | 3058 | struct i915_power_domains *power_domains = &dev_priv->power_domains; |
| 3059 | + int err; | |
| 2843 | 3060 | |
| 2844 | 3061 | i915_modparams.disable_power_well = |
| 2845 | 3062 | sanitize_disable_power_well_option(dev_priv, |
| @@ -2856,15 +3073,15 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) · 10 unmodified lines | ||
| 2856 | 3073 | * the disabling order is reversed. |
| 2857 | 3074 | */ |
| 2858 | 3075 | if (IS_ICELAKE(dev_priv)) { |
| 2859 | − set_power_wells(power_domains, icl_power_wells); | |
| 3076 | + err = set_power_wells(power_domains, icl_power_wells); | |
| 2860 | 3077 | } else if (IS_HASWELL(dev_priv)) { |
| 2861 | − set_power_wells(power_domains, hsw_power_wells); | |
| 3078 | + err = set_power_wells(power_domains, hsw_power_wells); | |
| 2862 | 3079 | } else if (IS_BROADWELL(dev_priv)) { |
| 2863 | − set_power_wells(power_domains, bdw_power_wells); | |
| 3080 | + err = set_power_wells(power_domains, bdw_power_wells); | |
| 2864 | 3081 | } else if (IS_GEN9_BC(dev_priv)) { |
| 2865 | − set_power_wells(power_domains, skl_power_wells); | |
| 3082 | + err = set_power_wells(power_domains, skl_power_wells); | |
| 2866 | 3083 | } else if (IS_CANNONLAKE(dev_priv)) { |
| 2867 | − set_power_wells(power_domains, cnl_power_wells); | |
| 3084 | + err = set_power_wells(power_domains, cnl_power_wells); | |
| 2868 | 3085 | |
| 2869 | 3086 | /* |
| 2870 | 3087 | * DDI and Aux IO are getting enabled for all ports |
| @@ -2876,57 +3093,31 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) · 5 unmodified lines | ||
| 2876 | 3093 | power_domains->power_well_count -= 2; |
| 2877 | 3094 | |
| 2878 | 3095 | } else if (IS_BROXTON(dev_priv)) { |
| 2879 | − set_power_wells(power_domains, bxt_power_wells); | |
| 3096 | + err = set_power_wells(power_domains, bxt_power_wells); | |
| 2880 | 3097 | } else if (IS_GEMINILAKE(dev_priv)) { |
| 2881 | − set_power_wells(power_domains, glk_power_wells); | |
| 3098 | + err = set_power_wells(power_domains, glk_power_wells); | |
| 2882 | 3099 | } else if (IS_CHERRYVIEW(dev_priv)) { |
| 2883 | − set_power_wells(power_domains, chv_power_wells); | |
| 3100 | + err = set_power_wells(power_domains, chv_power_wells); | |
| 2884 | 3101 | } else if (IS_VALLEYVIEW(dev_priv)) { |
| 2885 | − set_power_wells(power_domains, vlv_power_wells); | |
| 3102 | + err = set_power_wells(power_domains, vlv_power_wells); | |
| 2886 | 3103 | } else if (IS_I830(dev_priv)) { |
| 2887 | − set_power_wells(power_domains, i830_power_wells); | |
| 3104 | + err = set_power_wells(power_domains, i830_power_wells); | |
| 2888 | 3105 | } else { |
| 2889 | − set_power_wells(power_domains, i9xx_always_on_power_well); | |
| 3106 | + err = set_power_wells(power_domains, i9xx_always_on_power_well); | |
| 2890 | 3107 | } |
| 2891 | 3108 | |
| 2892 | − assert_power_well_ids_unique(dev_priv); | |
| 2893 | − | |
| 2894 | − return 0; | |
| 3109 | + return err; | |
| 2895 | 3110 | } |
| 2896 | 3111 | |
| 2897 | 3112 | /** |
| 2898 | − * intel_power_domains_fini - finalizes the power domain structures | |
| 3113 | + * intel_power_domains_cleanup - clean up power domains resources | |
| 2899 | 3114 | * @dev_priv: i915 device instance |
| 2900 | 3115 | * |
| 2901 | − * Finalizes the power domain structures for @dev_priv depending upon the | |
| 2902 | − * supported platform. This function also disables runtime pm and ensures that | |
| 2903 | − * the device stays powered up so that the driver can be reloaded. | |
| 3116 | + * Release any resources acquired by intel_power_domains_init() | |
| 2904 | 3117 | */ |
| 2905 | −void intel_power_domains_fini(struct drm_i915_private *dev_priv) | |
| 3118 | +void intel_power_domains_cleanup(struct drm_i915_private *dev_priv) | |
| 2906 | 3119 | { |
| 2907 | − struct device *kdev = &dev_priv->drm.pdev->dev; | |
| 2908 | − | |
| 2909 | − /* | |
| 2910 | − * The i915.ko module is still not prepared to be loaded when | |
| 2911 | − * the power well is not enabled, so just enable it in case | |
| 2912 | − * we're going to unload/reload. | |
| 2913 | − * The following also reacquires the RPM reference the core passed | |
| 2914 | − * to the driver during loading, which is dropped in | |
| 2915 | − * intel_runtime_pm_enable(). We have to hand back the control of the | |
| 2916 | − * device to the core with this reference held. | |
| 2917 | − */ | |
| 2918 | − intel_display_set_init_power(dev_priv, true); | |
| 2919 | − | |
| 2920 | − /* Remove the refcount we took to keep power well support disabled. */ | |
| 2921 | − if (!i915_modparams.disable_power_well) | |
| 2922 | − intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); | |
| 2923 | − | |
| 2924 | − /* | |
| 2925 | − * Remove the refcount we took in intel_runtime_pm_enable() in case | |
| 2926 | − * the platform doesn't support runtime PM. | |
| 2927 | − */ | |
| 2928 | − if (!HAS_RUNTIME_PM(dev_priv)) | |
| 2929 | − pm_runtime_put(kdev); | |
| 3120 | + kfree(dev_priv->power_domains.power_wells); | |
| 2930 | 3121 | } |
| 2931 | 3122 | |
| 2932 | 3123 | static void intel_power_domains_sync_hw(struct drm_i915_private *dev_priv) |
| @@ -2936,9 +3127,9 @@ static void intel_power_domains_sync_hw(struct drm_i915_private *dev_priv) · 3 unmodified lines | ||
| 2936 | 3127 | |
| 2937 | 3128 | mutex_lock(&power_domains->lock); |
| 2938 | 3129 | for_each_power_well(dev_priv, power_well) { |
| 2939 | − power_well->ops->sync_hw(dev_priv, power_well); | |
| 2940 | − power_well->hw_enabled = power_well->ops->is_enabled(dev_priv, | |
| 2941 | − power_well); | |
| 3130 | + power_well->desc->ops->sync_hw(dev_priv, power_well); | |
| 3131 | + power_well->hw_enabled = | |
| 3132 | + power_well->desc->ops->is_enabled(dev_priv, power_well); | |
| 2942 | 3133 | } |
| 2943 | 3134 | mutex_unlock(&power_domains->lock); |
| 2944 | 3135 | } |
| @@ -3360,7 +3551,7 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv, · 415 unmodified lines | ||
| 3360 | 3551 | * The AUX IO power wells will be enabled on demand. |
| 3361 | 3552 | */ |
| 3362 | 3553 | mutex_lock(&power_domains->lock); |
| 3363 | − well = lookup_power_well(dev_priv, ICL_DISP_PW_1); | |
| 3554 | + well = lookup_power_well(dev_priv, SKL_DISP_PW_1); | |
| 3364 | 3555 | intel_power_well_enable(dev_priv, well); |
| 3365 | 3556 | mutex_unlock(&power_domains->lock); |
| 3366 | 3557 | |
| @@ -3372,10 +3563,6 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv, · 5 unmodified lines | ||
| 3372 | 3563 | |
| 3373 | 3564 | /* 7. Setup MBUS. */ |
| 3374 | 3565 | icl_mbus_init(dev_priv); |
| 3375 | − | |
| 3376 | − /* 8. CHICKEN_DCPR_1 */ | |
| 3377 | − I915_WRITE(GEN8_CHICKEN_DCPR_1, I915_READ(GEN8_CHICKEN_DCPR_1) | | |
| 3378 | − CNL_DDI_CLOCK_REG_ACCESS_ON); | |
| 3379 | 3566 | } |
| 3380 | 3567 | |
| 3381 | 3568 | static void icl_display_core_uninit(struct drm_i915_private *dev_priv) |
| @@ -3401,7 +3588,7 @@ static void icl_display_core_uninit(struct drm_i915_private *dev_priv) · 19 unmodified lines | ||
| 3401 | 3588 | * disabled at this point. |
| 3402 | 3589 | */ |
| 3403 | 3590 | mutex_lock(&power_domains->lock); |
| 3404 | − well = lookup_power_well(dev_priv, ICL_DISP_PW_1); | |
| 3591 | + well = lookup_power_well(dev_priv, SKL_DISP_PW_1); | |
| 3405 | 3592 | intel_power_well_disable(dev_priv, well); |
| 3406 | 3593 | mutex_unlock(&power_domains->lock); |
| 3407 | 3594 | |
| @@ -3416,9 +3603,9 @@ static void icl_display_core_uninit(struct drm_i915_private *dev_priv) · 8 unmodified lines | ||
| 3416 | 3603 | static void chv_phy_control_init(struct drm_i915_private *dev_priv) |
| 3417 | 3604 | { |
| 3418 | 3605 | struct i915_power_well *cmn_bc = |
| 3419 | − lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC); | |
| 3606 | + lookup_power_well(dev_priv, VLV_DISP_PW_DPIO_CMN_BC); | |
| 3420 | 3607 | struct i915_power_well *cmn_d = |
| 3421 | − lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_D); | |
| 3608 | + lookup_power_well(dev_priv, CHV_DISP_PW_DPIO_CMN_D); | |
| 3422 | 3609 | |
| 3423 | 3610 | /* |
| 3424 | 3611 | * DISPLAY_PHY_CONTROL can get corrupted if read. As a |
| @@ -3441,7 +3628,7 @@ static void chv_phy_control_init(struct drm_i915_private *dev_priv) · 16 unmodified lines | ||
| 3441 | 3628 | * override and set the lane powerdown bits accding to the |
| 3442 | 3629 | * current lane status. |
| 3443 | 3630 | */ |
| 3444 | − if (cmn_bc->ops->is_enabled(dev_priv, cmn_bc)) { | |
| 3631 | + if (cmn_bc->desc->ops->is_enabled(dev_priv, cmn_bc)) { | |
| 3445 | 3632 | uint32_t status = I915_READ(DPLL(PIPE_A)); |
| 3446 | 3633 | unsigned int mask; |
| 3447 | 3634 | |
| @@ -3472,7 +3659,7 @@ static void chv_phy_control_init(struct drm_i915_private *dev_priv) · 24 unmodified lines | ||
| 3472 | 3659 | dev_priv->chv_phy_assert[DPIO_PHY0] = true; |
| 3473 | 3660 | } |
| 3474 | 3661 | |
| 3475 | − if (cmn_d->ops->is_enabled(dev_priv, cmn_d)) { | |
| 3662 | + if (cmn_d->desc->ops->is_enabled(dev_priv, cmn_d)) { | |
| 3476 | 3663 | uint32_t status = I915_READ(DPIO_PHY_STATUS); |
| 3477 | 3664 | unsigned int mask; |
| 3478 | 3665 | |
| @@ -3503,20 +3690,20 @@ static void chv_phy_control_init(struct drm_i915_private *dev_priv) · 24 unmodified lines | ||
| 3503 | 3690 | static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv) |
| 3504 | 3691 | { |
| 3505 | 3692 | struct i915_power_well *cmn = |
| 3506 | − lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC); | |
| 3693 | + lookup_power_well(dev_priv, VLV_DISP_PW_DPIO_CMN_BC); | |
| 3507 | 3694 | struct i915_power_well *disp2d = |
| 3508 | − lookup_power_well(dev_priv, PUNIT_POWER_WELL_DISP2D); | |
| 3695 | + lookup_power_well(dev_priv, VLV_DISP_PW_DISP2D); | |
| 3509 | 3696 | |
| 3510 | 3697 | /* If the display might be already active skip this */ |
| 3511 | − if (cmn->ops->is_enabled(dev_priv, cmn) && | |
| 3512 | − disp2d->ops->is_enabled(dev_priv, disp2d) && | |
| 3698 | + if (cmn->desc->ops->is_enabled(dev_priv, cmn) && | |
| 3699 | + disp2d->desc->ops->is_enabled(dev_priv, disp2d) && | |
| 3513 | 3700 | I915_READ(DPIO_CTL) & DPIO_CMNRST) |
| 3514 | 3701 | return; |
| 3515 | 3702 | |
| 3516 | 3703 | DRM_DEBUG_KMS("toggling display PHY side reset\n"); |
| 3517 | 3704 | |
| 3518 | 3705 | /* cmnlane needs DPLL registers */ |
| 3519 | − disp2d->ops->enable(dev_priv, disp2d); | |
| 3706 | + disp2d->desc->ops->enable(dev_priv, disp2d); | |
| 3520 | 3707 | |
| 3521 | 3708 | /* |
| 3522 | 3709 | * From VLV2A0_DP_eDP_HDMI_DPIO_driver_vbios_notes_11.docx: |
| @@ -3525,9 +3712,11 @@ static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv) · 2 unmodified lines | ||
| 3525 | 3712 | * Simply ungating isn't enough to reset the PHY enough to get |
| 3526 | 3713 | * ports and lanes running. |
| 3527 | 3714 | */ |
| 3528 | − cmn->ops->disable(dev_priv, cmn); | |
| 3715 | + cmn->desc->ops->disable(dev_priv, cmn); | |
| 3529 | 3716 | } |
| 3530 | 3717 | |
| 3718 | +static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv); | |
| 3719 | + | |
| 3531 | 3720 | /** |
| 3532 | 3721 | * intel_power_domains_init_hw - initialize hardware power domain state |
| 3533 | 3722 | * @dev_priv: i915 device instance |
| @@ -3535,9 +3724,14 @@ static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv) · 1 unmodified line | ||
| 3535 | 3724 | * |
| 3536 | 3725 | * This function initializes the hardware power domain state and enables all |
| 3537 | 3726 | * power wells belonging to the INIT power domain. Power wells in other |
| 3538 | − * domains (and not in the INIT domain) are referenced or disabled during the | |
| 3539 | − * modeset state HW readout. After that the reference count of each power well | |
| 3540 | − * must match its HW enabled state, see intel_power_domains_verify_state(). | |
| 3727 | + * domains (and not in the INIT domain) are referenced or disabled by | |
| 3728 | + * intel_modeset_readout_hw_state(). After that the reference count of each | |
| 3729 | + * power well must match its HW enabled state, see | |
| 3730 | + * intel_power_domains_verify_state(). | |
| 3731 | + * | |
| 3732 | + * It will return with power domains disabled (to be enabled later by | |
| 3733 | + * intel_power_domains_enable()) and must be paired with | |
| 3734 | + * intel_power_domains_fini_hw(). | |
| 3541 | 3735 | */ |
| 3542 | 3736 | void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume) |
| 3543 | 3737 | { |
| @@ -3563,30 +3757,117 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume) · 19 unmodified lines | ||
| 3563 | 3757 | mutex_unlock(&power_domains->lock); |
| 3564 | 3758 | } |
| 3565 | 3759 | |
| 3566 | − /* For now, we need the power well to be always enabled. */ | |
| 3567 | − intel_display_set_init_power(dev_priv, true); | |
| 3760 | + /* | |
| 3761 | + * Keep all power wells enabled for any dependent HW access during | |
| 3762 | + * initialization and to make sure we keep BIOS enabled display HW | |
| 3763 | + * resources powered until display HW readout is complete. We drop | |
| 3764 | + * this reference in intel_power_domains_enable(). | |
| 3765 | + */ | |
| 3766 | + intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); | |
| 3568 | 3767 | /* Disable power support if the user asked so. */ |
| 3569 | 3768 | if (!i915_modparams.disable_power_well) |
| 3570 | 3769 | intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); |
| 3571 | 3770 | intel_power_domains_sync_hw(dev_priv); |
| 3771 | + | |
| 3572 | 3772 | power_domains->initializing = false; |
| 3573 | 3773 | } |
| 3574 | 3774 | |
| 3775 | +/** | |
| 3776 | + * intel_power_domains_fini_hw - deinitialize hw power domain state | |
| 3777 | + * @dev_priv: i915 device instance | |
| 3778 | + * | |
| 3779 | + * De-initializes the display power domain HW state. It also ensures that the | |
| 3780 | + * device stays powered up so that the driver can be reloaded. | |
| 3781 | + * | |
| 3782 | + * It must be called with power domains already disabled (after a call to | |
| 3783 | + * intel_power_domains_disable()) and must be paired with | |
| 3784 | + * intel_power_domains_init_hw(). | |
| 3785 | + */ | |
| 3786 | +void intel_power_domains_fini_hw(struct drm_i915_private *dev_priv) | |
| 3787 | +{ | |
| 3788 | + /* Keep the power well enabled, but cancel its rpm wakeref. */ | |
| 3789 | + intel_runtime_pm_put(dev_priv); | |
| 3790 | + | |
| 3791 | + /* Remove the refcount we took to keep power well support disabled. */ | |
| 3792 | + if (!i915_modparams.disable_power_well) | |
| 3793 | + intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); | |
| 3794 | + | |
| 3795 | + intel_power_domains_verify_state(dev_priv); | |
| 3796 | +} | |
| 3797 | + | |
| 3798 | +/** | |
| 3799 | + * intel_power_domains_enable - enable toggling of display power wells | |
| 3800 | + * @dev_priv: i915 device instance | |
| 3801 | + * | |
| 3802 | + * Enable the ondemand enabling/disabling of the display power wells. Note that | |
| 3803 | + * power wells not belonging to POWER_DOMAIN_INIT are allowed to be toggled | |
| 3804 | + * only at specific points of the display modeset sequence, thus they are not | |
| 3805 | + * affected by the intel_power_domains_enable()/disable() calls. The purpose | |
| 3806 | + * of these function is to keep the rest of power wells enabled until the end | |
| 3807 | + * of display HW readout (which will acquire the power references reflecting | |
| 3808 | + * the current HW state). | |
| 3809 | + */ | |
| 3810 | +void intel_power_domains_enable(struct drm_i915_private *dev_priv) | |
| 3811 | +{ | |
| 3812 | + intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); | |
| 3813 | + | |
| 3814 | + intel_power_domains_verify_state(dev_priv); | |
| 3815 | +} | |
| 3816 | + | |
| 3817 | +/** | |
| 3818 | + * intel_power_domains_disable - disable toggling of display power wells | |
| 3819 | + * @dev_priv: i915 device instance | |
| 3820 | + * | |
| 3821 | + * Disable the ondemand enabling/disabling of the display power wells. See | |
| 3822 | + * intel_power_domains_enable() for which power wells this call controls. | |
| 3823 | + */ | |
| 3824 | +void intel_power_domains_disable(struct drm_i915_private *dev_priv) | |
| 3825 | +{ | |
| 3826 | + intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); | |
| 3827 | + | |
| 3828 | + intel_power_domains_verify_state(dev_priv); | |
| 3829 | +} | |
| 3830 | + | |
| 3575 | 3831 | /** |
| 3576 | 3832 | * intel_power_domains_suspend - suspend power domain state |
| 3577 | 3833 | * @dev_priv: i915 device instance |
| 3834 | + * @suspend_mode: specifies the target suspend state (idle, mem, hibernation) | |
| 3578 | 3835 | * |
| 3579 | 3836 | * This function prepares the hardware power domain state before entering |
| 3580 | − * system suspend. It must be paired with intel_power_domains_init_hw(). | |
| 3837 | + * system suspend. | |
| 3838 | + * | |
| 3839 | + * It must be called with power domains already disabled (after a call to | |
| 3840 | + * intel_power_domains_disable()) and paired with intel_power_domains_resume(). | |
| 3581 | 3841 | */ |
| 3582 | −void intel_power_domains_suspend(struct drm_i915_private *dev_priv) | |
| 3842 | +void intel_power_domains_suspend(struct drm_i915_private *dev_priv, | |
| 3843 | + enum i915_drm_suspend_mode suspend_mode) | |
| 3583 | 3844 | { |
| 3845 | + struct i915_power_domains *power_domains = &dev_priv->power_domains; | |
| 3846 | + | |
| 3847 | + intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); | |
| 3848 | + | |
| 3849 | + /* | |
| 3850 | + * In case of suspend-to-idle (aka S0ix) on a DMC platform without DC9 | |
| 3851 | + * support don't manually deinit the power domains. This also means the | |
| 3852 | + * CSR/DMC firmware will stay active, it will power down any HW | |
| 3853 | + * resources as required and also enable deeper system power states | |
| 3854 | + * that would be blocked if the firmware was inactive. | |
| 3855 | + */ | |
| 3856 | + if (!(dev_priv->csr.allowed_dc_mask & DC_STATE_EN_DC9) && | |
| 3857 | + suspend_mode == I915_DRM_SUSPEND_IDLE && | |
| 3858 | + dev_priv->csr.dmc_payload != NULL) { | |
| 3859 | + intel_power_domains_verify_state(dev_priv); | |
| 3860 | + return; | |
| 3861 | + } | |
| 3862 | + | |
| 3584 | 3863 | /* |
| 3585 | 3864 | * Even if power well support was disabled we still want to disable |
| 3586 | − * power wells while we are system suspended. | |
| 3865 | + * power wells if power domains must be deinitialized for suspend. | |
| 3587 | 3866 | */ |
| 3588 | − if (!i915_modparams.disable_power_well) | |
| 3867 | + if (!i915_modparams.disable_power_well) { | |
| 3589 | 3868 | intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); |
| 3869 | + intel_power_domains_verify_state(dev_priv); | |
| 3870 | + } | |
| 3590 | 3871 | |
| 3591 | 3872 | if (IS_ICELAKE(dev_priv)) |
| 3592 | 3873 | icl_display_core_uninit(dev_priv); |
| @@ -3596,8 +3877,36 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv) · 3 unmodified lines | ||
| 3596 | 3877 | skl_display_core_uninit(dev_priv); |
| 3597 | 3878 | else if (IS_GEN9_LP(dev_priv)) |
| 3598 | 3879 | bxt_display_core_uninit(dev_priv); |
| 3880 | + | |
| 3881 | + power_domains->display_core_suspended = true; | |
| 3599 | 3882 | } |
| 3600 | 3883 | |
| 3884 | +/** | |
| 3885 | + * intel_power_domains_resume - resume power domain state | |
| 3886 | + * @dev_priv: i915 device instance | |
| 3887 | + * | |
| 3888 | + * This function resume the hardware power domain state during system resume. | |
| 3889 | + * | |
| 3890 | + * It will return with power domain support disabled (to be enabled later by | |
| 3891 | + * intel_power_domains_enable()) and must be paired with | |
| 3892 | + * intel_power_domains_suspend(). | |
| 3893 | + */ | |
| 3894 | +void intel_power_domains_resume(struct drm_i915_private *dev_priv) | |
| 3895 | +{ | |
| 3896 | + struct i915_power_domains *power_domains = &dev_priv->power_domains; | |
| 3897 | + | |
| 3898 | + if (power_domains->display_core_suspended) { | |
| 3899 | + intel_power_domains_init_hw(dev_priv, true); | |
| 3900 | + power_domains->display_core_suspended = false; | |
| 3901 | + } else { | |
| 3902 | + intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); | |
| 3903 | + } | |
| 3904 | + | |
| 3905 | + intel_power_domains_verify_state(dev_priv); | |
| 3906 | +} | |
| 3907 | + | |
| 3908 | +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) | |
| 3909 | + | |
| 3601 | 3910 | static void intel_power_domains_dump_info(struct drm_i915_private *dev_priv) |
| 3602 | 3911 | { |
| 3603 | 3912 | struct i915_power_domains *power_domains = &dev_priv->power_domains; |
| @@ -3607,9 +3916,9 @@ static void intel_power_domains_dump_info(struct drm_i915_private *dev_priv) · 3 unmodified lines | ||
| 3607 | 3916 | enum intel_display_power_domain domain; |
| 3608 | 3917 | |
| 3609 | 3918 | DRM_DEBUG_DRIVER("%-25s %d\n", |
| 3610 | − power_well->name, power_well->count); | |
| 3919 | + power_well->desc->name, power_well->count); | |
| 3611 | 3920 | |
| 3612 | − for_each_power_domain(domain, power_well->domains) | |
| 3921 | + for_each_power_domain(domain, power_well->desc->domains) | |
| 3613 | 3922 | DRM_DEBUG_DRIVER(" %-23s %d\n", |
| 3614 | 3923 | intel_display_power_domain_str(domain), |
| 3615 | 3924 | power_domains->domain_use_count[domain]); |
| @@ -3626,7 +3935,7 @@ static void intel_power_domains_dump_info(struct drm_i915_private *dev_priv) · 10 unmodified lines | ||
| 3626 | 3935 | * acquiring reference counts for any power wells in use and disabling the |
| 3627 | 3936 | * ones left on by BIOS but not required by any active output. |
| 3628 | 3937 | */ |
| 3629 | −void intel_power_domains_verify_state(struct drm_i915_private *dev_priv) | |
| 3938 | +static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv) | |
| 3630 | 3939 | { |
| 3631 | 3940 | struct i915_power_domains *power_domains = &dev_priv->power_domains; |
| 3632 | 3941 | struct i915_power_well *power_well; |
| @@ -3645,22 +3954,25 @@ void intel_power_domains_verify_state(struct drm_i915_private *dev_priv) · 12 unmodified lines | ||
| 3645 | 3954 | * and PW1 power wells) are under FW control, so ignore them, |
| 3646 | 3955 | * since their state can change asynchronously. |
| 3647 | 3956 | */ |
| 3648 | − if (!power_well->domains) | |
| 3957 | + if (!power_well->desc->domains) | |
| 3649 | 3958 | continue; |
| 3650 | 3959 | |
| 3651 | − enabled = power_well->ops->is_enabled(dev_priv, power_well); | |
| 3652 | − if ((power_well->count || power_well->always_on) != enabled) | |
| 3960 | + enabled = power_well->desc->ops->is_enabled(dev_priv, | |
| 3961 | + power_well); | |
| 3962 | + if ((power_well->count || power_well->desc->always_on) != | |
| 3963 | + enabled) | |
| 3653 | 3964 | DRM_ERROR("power well %s state mismatch (refcount %d/enabled %d)", |
| 3654 | − power_well->name, power_well->count, enabled); | |
| 3965 | + power_well->desc->name, | |
| 3966 | + power_well->count, enabled); | |
| 3655 | 3967 | |
| 3656 | 3968 | domains_count = 0; |
| 3657 | − for_each_power_domain(domain, power_well->domains) | |
| 3969 | + for_each_power_domain(domain, power_well->desc->domains) | |
| 3658 | 3970 | domains_count += power_domains->domain_use_count[domain]; |
| 3659 | 3971 | |
| 3660 | 3972 | if (power_well->count != domains_count) { |
| 3661 | 3973 | DRM_ERROR("power well %s refcount/domain refcount mismatch " |
| 3662 | 3974 | "(refcount %d/domains refcount %d)\n", |
| 3663 | − power_well->name, power_well->count, | |
| 3975 | + power_well->desc->name, power_well->count, | |
| 3664 | 3976 | domains_count); |
| 3665 | 3977 | dump_domain_info = true; |
| 3666 | 3978 | } |
| @@ -3678,6 +3990,14 @@ void intel_power_domains_verify_state(struct drm_i915_private *dev_priv) · 11 unmodified lines | ||
| 3678 | 3990 | mutex_unlock(&power_domains->lock); |
| 3679 | 3991 | } |
| 3680 | 3992 | |
| 3993 | +#else | |
| 3994 | + | |
| 3995 | +static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv) | |
| 3996 | +{ | |
| 3997 | +} | |
| 3998 | + | |
| 3999 | +#endif | |
| 4000 | + | |
| 3681 | 4001 | /** |
| 3682 | 4002 | * intel_runtime_pm_get - grab a runtime pm reference |
| 3683 | 4003 | * @dev_priv: i915 device instance |
| @@ -3791,14 +4111,24 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv) · 107 unmodified lines | ||
| 3791 | 4111 | * This function enables runtime pm at the end of the driver load sequence. |
| 3792 | 4112 | * |
| 3793 | 4113 | * Note that this function does currently not enable runtime pm for the |
| 3794 | − * subordinate display power domains. That is only done on the first modeset | |
| 3795 | − * using intel_display_set_init_power(). | |
| 4114 | + * subordinate display power domains. That is done by | |
| 4115 | + * intel_power_domains_enable(). | |
| 3796 | 4116 | */ |
| 3797 | 4117 | void intel_runtime_pm_enable(struct drm_i915_private *dev_priv) |
| 3798 | 4118 | { |
| 3799 | 4119 | struct pci_dev *pdev = dev_priv->drm.pdev; |
| 3800 | 4120 | struct device *kdev = &pdev->dev; |
| 3801 | 4121 | |
| 4122 | + /* | |
| 4123 | + * Disable the system suspend direct complete optimization, which can | |
| 4124 | + * leave the device suspended skipping the driver's suspend handlers | |
| 4125 | + * if the device was already runtime suspended. This is needed due to | |
| 4126 | + * the difference in our runtime and system suspend sequence and | |
| 4127 | + * becaue the HDA driver may require us to enable the audio power | |
| 4128 | + * domain during system suspend. | |
| 4129 | + */ | |
| 4130 | + dev_pm_set_driver_flags(kdev, DPM_FLAG_NEVER_SKIP); | |
| 4131 | + | |
| 3802 | 4132 | pm_runtime_set_autosuspend_delay(kdev, 10000); /* 10s */ |
| 3803 | 4133 | pm_runtime_mark_last_busy(kdev); |
| 3804 | 4134 | |
| @@ -3825,3 +4155,18 @@ void intel_runtime_pm_enable(struct drm_i915_private *dev_priv) · 20 unmodified lines | ||
| 3825 | 4155 | */ |
| 3826 | 4156 | pm_runtime_put_autosuspend(kdev); |
| 3827 | 4157 | } |
| 4158 | + | |
| 4159 | +void intel_runtime_pm_disable(struct drm_i915_private *dev_priv) | |
| 4160 | +{ | |
| 4161 | + struct pci_dev *pdev = dev_priv->drm.pdev; | |
| 4162 | + struct device *kdev = &pdev->dev; | |
| 4163 | + | |
| 4164 | + /* Transfer rpm ownership back to core */ | |
| 4165 | + WARN(pm_runtime_get_sync(&dev_priv->drm.pdev->dev) < 0, | |
| 4166 | + "Failed to pass rpm ownership back to core\n"); | |
| 4167 | + | |
| 4168 | + pm_runtime_dont_use_autosuspend(kdev); | |
| 4169 | + | |
| 4170 | + if (!HAS_RUNTIME_PM(dev_priv)) | |
| 4171 | + pm_runtime_put(kdev); | |
| 4172 | +} | |
| @@ -83,6 +83,7 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state) · 82 unmodified lines | ||
| 83 | 83 | bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && |
| 84 | 84 | intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI); |
| 85 | 85 | DEFINE_WAIT(wait); |
| 86 | + u32 psr_status; | |
| 86 | 87 | |
| 87 | 88 | vblank_start = adjusted_mode->crtc_vblank_start; |
| 88 | 89 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) |
| @@ -104,8 +105,9 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state) · 15 unmodified lines | ||
| 104 | 105 | * VBL interrupts will start the PSR exit and prevent a PSR |
| 105 | 106 | * re-entry as well. |
| 106 | 107 | */ |
| 107 | − if (intel_psr_wait_for_idle(new_crtc_state)) | |
| 108 | − DRM_ERROR("PSR idle timed out, atomic update may fail\n"); | |
| 108 | + if (intel_psr_wait_for_idle(new_crtc_state, &psr_status)) | |
| 109 | + DRM_ERROR("PSR idle timed out 0x%x, atomic update may fail\n", | |
| 110 | + psr_status); | |
| 109 | 111 | |
| 110 | 112 | local_irq_disable(); |
| 111 | 113 | |
| @@ -957,10 +959,10 @@ g4x_plane_get_hw_state(struct intel_plane *plane, · 845 unmodified lines | ||
| 957 | 959 | } |
| 958 | 960 | |
| 959 | 961 | static int |
| 960 | −intel_check_sprite_plane(struct intel_plane *plane, | |
| 961 | − struct intel_crtc_state *crtc_state, | |
| 962 | +intel_check_sprite_plane(struct intel_crtc_state *crtc_state, | |
| 962 | 963 | struct intel_plane_state *state) |
| 963 | 964 | { |
| 965 | + struct intel_plane *plane = to_intel_plane(state->base.plane); | |
| 964 | 966 | struct drm_i915_private *dev_priv = to_i915(plane->base.dev); |
| 965 | 967 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
| 966 | 968 | struct drm_framebuffer *fb = state->base.fb; |
| @@ -1407,8 +1409,7 @@ static bool skl_plane_format_mod_supported(struct drm_plane *_plane, · 440 unmodified lines | ||
| 1407 | 1409 | case DRM_FORMAT_XBGR8888: |
| 1408 | 1410 | case DRM_FORMAT_ARGB8888: |
| 1409 | 1411 | case DRM_FORMAT_ABGR8888: |
| 1410 | − if (modifier == I915_FORMAT_MOD_Yf_TILED_CCS || | |
| 1411 | − modifier == I915_FORMAT_MOD_Y_TILED_CCS) | |
| 1412 | + if (is_ccs_modifier(modifier)) | |
| 1412 | 1413 | return true; |
| 1413 | 1414 | /* fall through */ |
| 1414 | 1415 | case DRM_FORMAT_RGB565: |
| @@ -222,7 +222,7 @@ int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, · 221 unmodified lines | ||
| 222 | 222 | goto fail; |
| 223 | 223 | } |
| 224 | 224 | |
| 225 | − ggtt_pin_bias = to_i915(uc_fw->obj->base.dev)->guc.ggtt_pin_bias; | |
| 225 | + ggtt_pin_bias = to_i915(uc_fw->obj->base.dev)->ggtt.pin_bias; | |
| 226 | 226 | vma = i915_gem_object_ggtt_pin(uc_fw->obj, NULL, 0, 0, |
| 227 | 227 | PIN_OFFSET_BIAS | ggtt_pin_bias); |
| 228 | 228 | if (IS_ERR(vma)) { |
| @@ -283,14 +283,24 @@ fw_domains_reset(struct drm_i915_private *i915, · 282 unmodified lines | ||
| 283 | 283 | fw_domain_reset(i915, d); |
| 284 | 284 | } |
| 285 | 285 | |
| 286 | +static inline u32 gt_thread_status(struct drm_i915_private *dev_priv) | |
| 287 | +{ | |
| 288 | + u32 val; | |
| 289 | + | |
| 290 | + val = __raw_i915_read32(dev_priv, GEN6_GT_THREAD_STATUS_REG); | |
| 291 | + val &= GEN6_GT_THREAD_STATUS_CORE_MASK; | |
| 292 | + | |
| 293 | + return val; | |
| 294 | +} | |
| 295 | + | |
| 286 | 296 | static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) |
| 287 | 297 | { |
| 288 | − /* w/a for a sporadic read returning 0 by waiting for the GT | |
| 298 | + /* | |
| 299 | + * w/a for a sporadic read returning 0 by waiting for the GT | |
| 289 | 300 | * thread to wake up. |
| 290 | 301 | */ |
| 291 | − if (wait_for_atomic_us((__raw_i915_read32(dev_priv, GEN6_GT_THREAD_STATUS_REG) & | |
| 292 | − GEN6_GT_THREAD_STATUS_CORE_MASK) == 0, 500)) | |
| 293 | − DRM_ERROR("GT thread status wait timed out\n"); | |
| 302 | + WARN_ONCE(wait_for_atomic_us(gt_thread_status(dev_priv) == 0, 5000), | |
| 303 | + "GT thread status wait timed out\n"); | |
| 294 | 304 | } |
| 295 | 305 | |
| 296 | 306 | static void fw_domains_get_with_thread_status(struct drm_i915_private *dev_priv, |
| @@ -1729,7 +1739,7 @@ static void gen3_stop_engine(struct intel_engine_cs *engine) · 1432 unmodified lines | ||
| 1729 | 1739 | } |
| 1730 | 1740 | |
| 1731 | 1741 | static void i915_stop_engines(struct drm_i915_private *dev_priv, |
| 1732 | − unsigned engine_mask) | |
| 1742 | + unsigned int engine_mask) | |
| 1733 | 1743 | { |
| 1734 | 1744 | struct intel_engine_cs *engine; |
| 1735 | 1745 | enum intel_engine_id id; |
| @@ -1749,7 +1759,9 @@ static bool i915_in_reset(struct pci_dev *pdev) · 13 unmodified lines | ||
| 1749 | 1759 | return gdrst & GRDOM_RESET_STATUS; |
| 1750 | 1760 | } |
| 1751 | 1761 | |
| 1752 | −static int i915_do_reset(struct drm_i915_private *dev_priv, unsigned engine_mask) | |
| 1762 | +static int i915_do_reset(struct drm_i915_private *dev_priv, | |
| 1763 | + unsigned int engine_mask, | |
| 1764 | + unsigned int retry) | |
| 1753 | 1765 | { |
| 1754 | 1766 | struct pci_dev *pdev = dev_priv->drm.pdev; |
| 1755 | 1767 | int err; |
| @@ -1776,7 +1788,9 @@ static bool g4x_reset_complete(struct pci_dev *pdev) · 20 unmodified lines | ||
| 1776 | 1788 | return (gdrst & GRDOM_RESET_ENABLE) == 0; |
| 1777 | 1789 | } |
| 1778 | 1790 | |
| 1779 | −static int g33_do_reset(struct drm_i915_private *dev_priv, unsigned engine_mask) | |
| 1791 | +static int g33_do_reset(struct drm_i915_private *dev_priv, | |
| 1792 | + unsigned int engine_mask, | |
| 1793 | + unsigned int retry) | |
| 1780 | 1794 | { |
| 1781 | 1795 | struct pci_dev *pdev = dev_priv->drm.pdev; |
| 1782 | 1796 | |
| @@ -1784,7 +1798,9 @@ static int g33_do_reset(struct drm_i915_private *dev_priv, unsigned engine_mask) · 1 unmodified line | ||
| 1784 | 1798 | return wait_for(g4x_reset_complete(pdev), 500); |
| 1785 | 1799 | } |
| 1786 | 1800 | |
| 1787 | −static int g4x_do_reset(struct drm_i915_private *dev_priv, unsigned engine_mask) | |
| 1801 | +static int g4x_do_reset(struct drm_i915_private *dev_priv, | |
| 1802 | + unsigned int engine_mask, | |
| 1803 | + unsigned int retry) | |
| 1788 | 1804 | { |
| 1789 | 1805 | struct pci_dev *pdev = dev_priv->drm.pdev; |
| 1790 | 1806 | int ret; |
| @@ -1821,7 +1837,8 @@ out: · 30 unmodified lines | ||
| 1821 | 1837 | } |
| 1822 | 1838 | |
| 1823 | 1839 | static int ironlake_do_reset(struct drm_i915_private *dev_priv, |
| 1824 | − unsigned engine_mask) | |
| 1840 | + unsigned int engine_mask, | |
| 1841 | + unsigned int retry) | |
| 1825 | 1842 | { |
| 1826 | 1843 | int ret; |
| 1827 | 1844 | |
| @@ -1877,6 +1894,7 @@ static int gen6_hw_domain_reset(struct drm_i915_private *dev_priv, · 49 unmodified lines | ||
| 1877 | 1894 | * gen6_reset_engines - reset individual engines |
| 1878 | 1895 | * @dev_priv: i915 device |
| 1879 | 1896 | * @engine_mask: mask of intel_ring_flag() engines or ALL_ENGINES for full reset |
| 1897 | + * @retry: the count of of previous attempts to reset. | |
| 1880 | 1898 | * |
| 1881 | 1899 | * This function will reset the individual engines that are set in engine_mask. |
| 1882 | 1900 | * If you provide ALL_ENGINES as mask, full global domain reset will be issued. |
| @@ -1887,7 +1905,8 @@ static int gen6_hw_domain_reset(struct drm_i915_private *dev_priv, · 4 unmodified lines | ||
| 1887 | 1905 | * Returns 0 on success, nonzero on error. |
| 1888 | 1906 | */ |
| 1889 | 1907 | static int gen6_reset_engines(struct drm_i915_private *dev_priv, |
| 1890 | − unsigned engine_mask) | |
| 1908 | + unsigned int engine_mask, | |
| 1909 | + unsigned int retry) | |
| 1891 | 1910 | { |
| 1892 | 1911 | struct intel_engine_cs *engine; |
| 1893 | 1912 | const u32 hw_engine_mask[I915_NUM_ENGINES] = { |
| @@ -1926,7 +1945,7 @@ static int gen6_reset_engines(struct drm_i915_private *dev_priv, · 32 unmodified lines | ||
| 1926 | 1945 | * Returns 0 on success, nonzero on error. |
| 1927 | 1946 | */ |
| 1928 | 1947 | static int gen11_reset_engines(struct drm_i915_private *dev_priv, |
| 1929 | − unsigned engine_mask) | |
| 1948 | + unsigned int engine_mask) | |
| 1930 | 1949 | { |
| 1931 | 1950 | struct intel_engine_cs *engine; |
| 1932 | 1951 | const u32 hw_engine_mask[I915_NUM_ENGINES] = { |
| @@ -2066,7 +2085,7 @@ int __intel_wait_for_register(struct drm_i915_private *dev_priv, · 133 unmodified lines | ||
| 2066 | 2085 | return ret; |
| 2067 | 2086 | } |
| 2068 | 2087 | |
| 2069 | −static int gen8_reset_engine_start(struct intel_engine_cs *engine) | |
| 2088 | +static int gen8_engine_reset_prepare(struct intel_engine_cs *engine) | |
| 2070 | 2089 | { |
| 2071 | 2090 | struct drm_i915_private *dev_priv = engine->i915; |
| 2072 | 2091 | int ret; |
| @@ -2086,7 +2105,7 @@ static int gen8_reset_engine_start(struct intel_engine_cs *engine) · 13 unmodified lines | ||
| 2086 | 2105 | return ret; |
| 2087 | 2106 | } |
| 2088 | 2107 | |
| 2089 | −static void gen8_reset_engine_cancel(struct intel_engine_cs *engine) | |
| 2108 | +static void gen8_engine_reset_cancel(struct intel_engine_cs *engine) | |
| 2090 | 2109 | { |
| 2091 | 2110 | struct drm_i915_private *dev_priv = engine->i915; |
| 2092 | 2111 | |
| @@ -2094,33 +2113,56 @@ static void gen8_reset_engine_cancel(struct intel_engine_cs *engine) · 1 unmodified line | ||
| 2094 | 2113 | _MASKED_BIT_DISABLE(RESET_CTL_REQUEST_RESET)); |
| 2095 | 2114 | } |
| 2096 | 2115 | |
| 2116 | +static int reset_engines(struct drm_i915_private *i915, | |
| 2117 | + unsigned int engine_mask, | |
| 2118 | + unsigned int retry) | |
| 2119 | +{ | |
| 2120 | + if (INTEL_GEN(i915) >= 11) | |
| 2121 | + return gen11_reset_engines(i915, engine_mask); | |
| 2122 | + else | |
| 2123 | + return gen6_reset_engines(i915, engine_mask, retry); | |
| 2124 | +} | |
| 2125 | + | |
| 2097 | 2126 | static int gen8_reset_engines(struct drm_i915_private *dev_priv, |
| 2098 | − unsigned engine_mask) | |
| 2127 | + unsigned int engine_mask, | |
| 2128 | + unsigned int retry) | |
| 2099 | 2129 | { |
| 2100 | 2130 | struct intel_engine_cs *engine; |
| 2131 | + const bool reset_non_ready = retry >= 1; | |
| 2101 | 2132 | unsigned int tmp; |
| 2102 | 2133 | int ret; |
| 2103 | 2134 | |
| 2104 | 2135 | for_each_engine_masked(engine, dev_priv, engine_mask, tmp) { |
| 2105 | − if (gen8_reset_engine_start(engine)) { | |
| 2106 | − ret = -EIO; | |
| 2107 | − goto not_ready; | |
| 2108 | − } | |
| 2136 | + ret = gen8_engine_reset_prepare(engine); | |
| 2137 | + if (ret && !reset_non_ready) | |
| 2138 | + goto skip_reset; | |
| 2139 | + | |
| 2140 | + /* | |
| 2141 | + * If this is not the first failed attempt to prepare, | |
| 2142 | + * we decide to proceed anyway. | |
| 2143 | + * | |
| 2144 | + * By doing so we risk context corruption and with | |
| 2145 | + * some gens (kbl), possible system hang if reset | |
| 2146 | + * happens during active bb execution. | |
| 2147 | + * | |
| 2148 | + * We rather take context corruption instead of | |
| 2149 | + * failed reset with a wedged driver/gpu. And | |
| 2150 | + * active bb execution case should be covered by | |
| 2151 | + * i915_stop_engines we have before the reset. | |
| 2152 | + */ | |
| 2109 | 2153 | } |
| 2110 | 2154 | |
| 2111 | − if (INTEL_GEN(dev_priv) >= 11) | |
| 2112 | − ret = gen11_reset_engines(dev_priv, engine_mask); | |
| 2113 | − else | |
| 2114 | − ret = gen6_reset_engines(dev_priv, engine_mask); | |
| 2155 | + ret = reset_engines(dev_priv, engine_mask, retry); | |
| 2115 | 2156 | |
| 2116 | −not_ready: | |
| 2157 | +skip_reset: | |
| 2117 | 2158 | for_each_engine_masked(engine, dev_priv, engine_mask, tmp) |
| 2118 | − gen8_reset_engine_cancel(engine); | |
| 2159 | + gen8_engine_reset_cancel(engine); | |
| 2119 | 2160 | |
| 2120 | 2161 | return ret; |
| 2121 | 2162 | } |
| 2122 | 2163 | |
| 2123 | −typedef int (*reset_func)(struct drm_i915_private *, unsigned engine_mask); | |
| 2164 | +typedef int (*reset_func)(struct drm_i915_private *, | |
| 2165 | + unsigned int engine_mask, unsigned int retry); | |
| 2124 | 2166 | |
| 2125 | 2167 | static reset_func intel_get_gpu_reset(struct drm_i915_private *dev_priv) |
| 2126 | 2168 | { |
| @@ -2143,12 +2185,15 @@ static reset_func intel_get_gpu_reset(struct drm_i915_private *dev_priv) · 16 unmodified lines | ||
| 2143 | 2185 | return NULL; |
| 2144 | 2186 | } |
| 2145 | 2187 | |
| 2146 | −int intel_gpu_reset(struct drm_i915_private *dev_priv, unsigned engine_mask) | |
| 2188 | +int intel_gpu_reset(struct drm_i915_private *dev_priv, | |
| 2189 | + const unsigned int engine_mask) | |
| 2147 | 2190 | { |
| 2148 | 2191 | reset_func reset = intel_get_gpu_reset(dev_priv); |
| 2149 | − int retry; | |
| 2192 | + unsigned int retry; | |
| 2150 | 2193 | int ret; |
| 2151 | 2194 | |
| 2195 | + GEM_BUG_ON(!engine_mask); | |
| 2196 | + | |
| 2152 | 2197 | /* |
| 2153 | 2198 | * We want to perform per-engine reset from atomic context (e.g. |
| 2154 | 2199 | * softirq), which imposes the constraint that we cannot sleep. |
| @@ -2190,8 +2235,9 @@ int intel_gpu_reset(struct drm_i915_private *dev_priv, unsigned engine_mask) · 35 unmodified lines | ||
| 2190 | 2235 | |
| 2191 | 2236 | ret = -ENODEV; |
| 2192 | 2237 | if (reset) { |
| 2193 | − GEM_TRACE("engine_mask=%x\n", engine_mask); | |
| 2194 | − ret = reset(dev_priv, engine_mask); | |
| 2238 | + ret = reset(dev_priv, engine_mask, retry); | |
| 2239 | + GEM_TRACE("engine_mask=%x, ret=%d, retry=%d\n", | |
| 2240 | + engine_mask, ret, retry); | |
| 2195 | 2241 | } |
| 2196 | 2242 | if (ret != -ETIMEDOUT || engine_mask != ALL_ENGINES) |
| 2197 | 2243 | break; |
| @@ -2237,20 +2283,28 @@ bool intel_uncore_unclaimed_mmio(struct drm_i915_private *dev_priv) · 39 unmodified lines | ||
| 2237 | 2283 | bool |
| 2238 | 2284 | intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv) |
| 2239 | 2285 | { |
| 2240 | − if (unlikely(i915_modparams.mmio_debug || | |
| 2241 | − dev_priv->uncore.unclaimed_mmio_check <= 0)) | |
| 2242 | − return false; | |
| 2286 | + bool ret = false; | |
| 2287 | + | |
| 2288 | + spin_lock_irq(&dev_priv->uncore.lock); | |
| 2289 | + | |
| 2290 | + if (unlikely(dev_priv->uncore.unclaimed_mmio_check <= 0)) | |
| 2291 | + goto out; | |
| 2243 | 2292 | |
| 2244 | 2293 | if (unlikely(intel_uncore_unclaimed_mmio(dev_priv))) { |
| 2245 | − DRM_DEBUG("Unclaimed register detected, " | |
| 2246 | − "enabling oneshot unclaimed register reporting. " | |
| 2247 | − "Please use i915.mmio_debug=N for more information.\n"); | |
| 2248 | − i915_modparams.mmio_debug++; | |
| 2294 | + if (!i915_modparams.mmio_debug) { | |
| 2295 | + DRM_DEBUG("Unclaimed register detected, " | |
| 2296 | + "enabling oneshot unclaimed register reporting. " | |
| 2297 | + "Please use i915.mmio_debug=N for more information.\n"); | |
| 2298 | + i915_modparams.mmio_debug++; | |
| 2299 | + } | |
| 2249 | 2300 | dev_priv->uncore.unclaimed_mmio_check--; |
| 2250 | − return true; | |
| 2301 | + ret = true; | |
| 2251 | 2302 | } |
| 2252 | 2303 | |
| 2253 | − return false; | |
| 2304 | +out: | |
| 2305 | + spin_unlock_irq(&dev_priv->uncore.lock); | |
| 2306 | + | |
| 2307 | + return ret; | |
| 2254 | 2308 | } |
| 2255 | 2309 | |
| 2256 | 2310 | static enum forcewake_domains |
| @@ -163,8 +163,14 @@ int intel_wopcm_init(struct intel_wopcm *wopcm) · 162 unmodified lines | ||
| 163 | 163 | u32 guc_wopcm_rsvd; |
| 164 | 164 | int err; |
| 165 | 165 | |
| 166 | + if (!USES_GUC(dev_priv)) | |
| 167 | + return 0; | |
| 168 | + | |
| 166 | 169 | GEM_BUG_ON(!wopcm->size); |
| 167 | 170 | |
| 171 | + if (i915_inject_load_failure()) | |
| 172 | + return -E2BIG; | |
| 173 | + | |
| 168 | 174 | if (guc_fw_size >= wopcm->size) { |
| 169 | 175 | DRM_ERROR("GuC FW (%uKiB) is too big to fit in WOPCM.", |
| 170 | 176 | guc_fw_size / 1024); |
| @@ -906,7 +906,11 @@ gpu_write_dw(struct i915_vma *vma, u64 offset, u32 val) · 905 unmodified lines | ||
| 906 | 906 | if (IS_ERR(obj)) |
| 907 | 907 | return ERR_CAST(obj); |
| 908 | 908 | |
| 909 | − cmd = i915_gem_object_pin_map(obj, I915_MAP_WB); | |
| 909 | + err = i915_gem_object_set_to_wc_domain(obj, true); | |
| 910 | + if (err) | |
| 911 | + goto err; | |
| 912 | + | |
| 913 | + cmd = i915_gem_object_pin_map(obj, I915_MAP_WC); | |
| 910 | 914 | if (IS_ERR(cmd)) { |
| 911 | 915 | err = PTR_ERR(cmd); |
| 912 | 916 | goto err; |
| @@ -936,13 +940,10 @@ gpu_write_dw(struct i915_vma *vma, u64 offset, u32 val) · 23 unmodified lines | ||
| 936 | 940 | } |
| 937 | 941 | |
| 938 | 942 | *cmd = MI_BATCH_BUFFER_END; |
| 943 | + i915_gem_chipset_flush(i915); | |
| 939 | 944 | |
| 940 | 945 | i915_gem_object_unpin_map(obj); |
| 941 | 946 | |
| 942 | − err = i915_gem_object_set_to_gtt_domain(obj, false); | |
| 943 | − if (err) | |
| 944 | − goto err; | |
| 945 | − | |
| 946 | 947 | batch = i915_vma_instance(obj, vma->vm, NULL); |
| 947 | 948 | if (IS_ERR(batch)) { |
| 948 | 949 | err = PTR_ERR(batch); |
| @@ -0,0 +1,221 @@ | ||
| 1 | +/* | |
| 2 | + * SPDX-License-Identifier: MIT | |
| 3 | + * | |
| 4 | + * Copyright © 2018 Intel Corporation | |
| 5 | + */ | |
| 6 | + | |
| 7 | +#include <linux/random.h> | |
| 8 | + | |
| 9 | +#include "../i915_selftest.h" | |
| 10 | + | |
| 11 | +#include "mock_context.h" | |
| 12 | +#include "igt_flush_test.h" | |
| 13 | + | |
| 14 | +static int switch_to_context(struct drm_i915_private *i915, | |
| 15 | + struct i915_gem_context *ctx) | |
| 16 | +{ | |
| 17 | + struct intel_engine_cs *engine; | |
| 18 | + enum intel_engine_id id; | |
| 19 | + int err = 0; | |
| 20 | + | |
| 21 | + intel_runtime_pm_get(i915); | |
| 22 | + | |
| 23 | + for_each_engine(engine, i915, id) { | |
| 24 | + struct i915_request *rq; | |
| 25 | + | |
| 26 | + rq = i915_request_alloc(engine, ctx); | |
| 27 | + if (IS_ERR(rq)) { | |
| 28 | + err = PTR_ERR(rq); | |
| 29 | + break; | |
| 30 | + } | |
| 31 | + | |
| 32 | + i915_request_add(rq); | |
| 33 | + } | |
| 34 | + | |
| 35 | + intel_runtime_pm_put(i915); | |
| 36 | + | |
| 37 | + return err; | |
| 38 | +} | |
| 39 | + | |
| 40 | +static void trash_stolen(struct drm_i915_private *i915) | |
| 41 | +{ | |
| 42 | + struct i915_ggtt *ggtt = &i915->ggtt; | |
| 43 | + const u64 slot = ggtt->error_capture.start; | |
| 44 | + const resource_size_t size = resource_size(&i915->dsm); | |
| 45 | + unsigned long page; | |
| 46 | + u32 prng = 0x12345678; | |
| 47 | + | |
| 48 | + for (page = 0; page < size; page += PAGE_SIZE) { | |
| 49 | + const dma_addr_t dma = i915->dsm.start + page; | |
| 50 | + u32 __iomem *s; | |
| 51 | + int x; | |
| 52 | + | |
| 53 | + ggtt->vm.insert_page(&ggtt->vm, dma, slot, I915_CACHE_NONE, 0); | |
| 54 | + | |
| 55 | + s = io_mapping_map_atomic_wc(&ggtt->iomap, slot); | |
| 56 | + for (x = 0; x < PAGE_SIZE / sizeof(u32); x++) { | |
| 57 | + prng = next_pseudo_random32(prng); | |
| 58 | + iowrite32(prng, &s[x]); | |
| 59 | + } | |
| 60 | + io_mapping_unmap_atomic(s); | |
| 61 | + } | |
| 62 | + | |
| 63 | + ggtt->vm.clear_range(&ggtt->vm, slot, PAGE_SIZE); | |
| 64 | +} | |
| 65 | + | |
| 66 | +static void simulate_hibernate(struct drm_i915_private *i915) | |
| 67 | +{ | |
| 68 | + intel_runtime_pm_get(i915); | |
| 69 | + | |
| 70 | + /* | |
| 71 | + * As a final sting in the tail, invalidate stolen. Under a real S4, | |
| 72 | + * stolen is lost and needs to be refilled on resume. However, under | |
| 73 | + * CI we merely do S4-device testing (as full S4 is too unreliable | |
| 74 | + * for automated testing across a cluster), so to simulate the effect | |
| 75 | + * of stolen being trashed across S4, we trash it ourselves. | |
| 76 | + */ | |
| 77 | + trash_stolen(i915); | |
| 78 | + | |
| 79 | + intel_runtime_pm_put(i915); | |
| 80 | +} | |
| 81 | + | |
| 82 | +static int pm_prepare(struct drm_i915_private *i915) | |
| 83 | +{ | |
| 84 | + int err = 0; | |
| 85 | + | |
| 86 | + if (i915_gem_suspend(i915)) { | |
| 87 | + pr_err("i915_gem_suspend failed\n"); | |
| 88 | + err = -EINVAL; | |
| 89 | + } | |
| 90 | + | |
| 91 | + return err; | |
| 92 | +} | |
| 93 | + | |
| 94 | +static void pm_suspend(struct drm_i915_private *i915) | |
| 95 | +{ | |
| 96 | + intel_runtime_pm_get(i915); | |
| 97 | + | |
| 98 | + i915_gem_suspend_gtt_mappings(i915); | |
| 99 | + i915_gem_suspend_late(i915); | |
| 100 | + | |
| 101 | + intel_runtime_pm_put(i915); | |
| 102 | +} | |
| 103 | + | |
| 104 | +static void pm_hibernate(struct drm_i915_private *i915) | |
| 105 | +{ | |
| 106 | + intel_runtime_pm_get(i915); | |
| 107 | + | |
| 108 | + i915_gem_suspend_gtt_mappings(i915); | |
| 109 | + | |
| 110 | + i915_gem_freeze(i915); | |
| 111 | + i915_gem_freeze_late(i915); | |
| 112 | + | |
| 113 | + intel_runtime_pm_put(i915); | |
| 114 | +} | |
| 115 | + | |
| 116 | +static void pm_resume(struct drm_i915_private *i915) | |
| 117 | +{ | |
| 118 | + /* | |
| 119 | + * Both suspend and hibernate follow the same wakeup path and assume | |
| 120 | + * that runtime-pm just works. | |
| 121 | + */ | |
| 122 | + intel_runtime_pm_get(i915); | |
| 123 | + | |
| 124 | + intel_engines_sanitize(i915); | |
| 125 | + i915_gem_sanitize(i915); | |
| 126 | + i915_gem_resume(i915); | |
| 127 | + | |
| 128 | + intel_runtime_pm_put(i915); | |
| 129 | +} | |
| 130 | + | |
| 131 | +static int igt_gem_suspend(void *arg) | |
| 132 | +{ | |
| 133 | + struct drm_i915_private *i915 = arg; | |
| 134 | + struct i915_gem_context *ctx; | |
| 135 | + struct drm_file *file; | |
| 136 | + int err; | |
| 137 | + | |
| 138 | + file = mock_file(i915); | |
| 139 | + if (IS_ERR(file)) | |
| 140 | + return PTR_ERR(file); | |
| 141 | + | |
| 142 | + err = -ENOMEM; | |
| 143 | + mutex_lock(&i915->drm.struct_mutex); | |
| 144 | + ctx = live_context(i915, file); | |
| 145 | + if (!IS_ERR(ctx)) | |
| 146 | + err = switch_to_context(i915, ctx); | |
| 147 | + mutex_unlock(&i915->drm.struct_mutex); | |
| 148 | + if (err) | |
| 149 | + goto out; | |
| 150 | + | |
| 151 | + err = pm_prepare(i915); | |
| 152 | + if (err) | |
| 153 | + goto out; | |
| 154 | + | |
| 155 | + pm_suspend(i915); | |
| 156 | + | |
| 157 | + /* Here be dragons! Note that with S3RST any S3 may become S4! */ | |
| 158 | + simulate_hibernate(i915); | |
| 159 | + | |
| 160 | + pm_resume(i915); | |
| 161 | + | |
| 162 | + mutex_lock(&i915->drm.struct_mutex); | |
| 163 | + err = switch_to_context(i915, ctx); | |
| 164 | + if (igt_flush_test(i915, I915_WAIT_LOCKED)) | |
| 165 | + err = -EIO; | |
| 166 | + mutex_unlock(&i915->drm.struct_mutex); | |
| 167 | +out: | |
| 168 | + mock_file_free(i915, file); | |
| 169 | + return err; | |
| 170 | +} | |
| 171 | + | |
| 172 | +static int igt_gem_hibernate(void *arg) | |
| 173 | +{ | |
| 174 | + struct drm_i915_private *i915 = arg; | |
| 175 | + struct i915_gem_context *ctx; | |
| 176 | + struct drm_file *file; | |
| 177 | + int err; | |
| 178 | + | |
| 179 | + file = mock_file(i915); | |
| 180 | + if (IS_ERR(file)) | |
| 181 | + return PTR_ERR(file); | |
| 182 | + | |
| 183 | + err = -ENOMEM; | |
| 184 | + mutex_lock(&i915->drm.struct_mutex); | |
| 185 | + ctx = live_context(i915, file); | |
| 186 | + if (!IS_ERR(ctx)) | |
| 187 | + err = switch_to_context(i915, ctx); | |
| 188 | + mutex_unlock(&i915->drm.struct_mutex); | |
| 189 | + if (err) | |
| 190 | + goto out; | |
| 191 | + | |
| 192 | + err = pm_prepare(i915); | |
| 193 | + if (err) | |
| 194 | + goto out; | |
| 195 | + | |
| 196 | + pm_hibernate(i915); | |
| 197 | + | |
| 198 | + /* Here be dragons! */ | |
| 199 | + simulate_hibernate(i915); | |
| 200 | + | |
| 201 | + pm_resume(i915); | |
| 202 | + | |
| 203 | + mutex_lock(&i915->drm.struct_mutex); | |
| 204 | + err = switch_to_context(i915, ctx); | |
| 205 | + if (igt_flush_test(i915, I915_WAIT_LOCKED)) | |
| 206 | + err = -EIO; | |
| 207 | + mutex_unlock(&i915->drm.struct_mutex); | |
| 208 | +out: | |
| 209 | + mock_file_free(i915, file); | |
| 210 | + return err; | |
| 211 | +} | |
| 212 | + | |
| 213 | +int i915_gem_live_selftests(struct drm_i915_private *i915) | |
| 214 | +{ | |
| 215 | + static const struct i915_subtest tests[] = { | |
| 216 | + SUBTEST(igt_gem_suspend), | |
| 217 | + SUBTEST(igt_gem_hibernate), | |
| 218 | + }; | |
| 219 | + | |
| 220 | + return i915_subtests(tests, i915); | |
| 221 | +} | |
| @@ -33,7 +33,8 @@ static int cpu_set(struct drm_i915_gem_object *obj, · 32 unmodified lines | ||
| 33 | 33 | { |
| 34 | 34 | unsigned int needs_clflush; |
| 35 | 35 | struct page *page; |
| 36 | − u32 *map; | |
| 36 | + void *map; | |
| 37 | + u32 *cpu; | |
| 37 | 38 | int err; |
| 38 | 39 | |
| 39 | 40 | err = i915_gem_obj_prepare_shmem_write(obj, &needs_clflush); |
| @@ -42,24 +43,19 @@ static int cpu_set(struct drm_i915_gem_object *obj, · 2 unmodified lines | ||
| 42 | 43 | |
| 43 | 44 | page = i915_gem_object_get_page(obj, offset >> PAGE_SHIFT); |
| 44 | 45 | map = kmap_atomic(page); |
| 46 | + cpu = map + offset_in_page(offset); | |
| 45 | 47 | |
| 46 | − if (needs_clflush & CLFLUSH_BEFORE) { | |
| 47 | − mb(); | |
| 48 | − clflush(map+offset_in_page(offset) / sizeof(*map)); | |
| 49 | − mb(); | |
| 50 | − } | |
| 48 | + if (needs_clflush & CLFLUSH_BEFORE) | |
| 49 | + drm_clflush_virt_range(cpu, sizeof(*cpu)); | |
| 51 | 50 | |
| 52 | − map[offset_in_page(offset) / sizeof(*map)] = v; | |
| 51 | + *cpu = v; | |
| 53 | 52 | |
| 54 | − if (needs_clflush & CLFLUSH_AFTER) { | |
| 55 | − mb(); | |
| 56 | − clflush(map+offset_in_page(offset) / sizeof(*map)); | |
| 57 | − mb(); | |
| 58 | − } | |
| 53 | + if (needs_clflush & CLFLUSH_AFTER) | |
| 54 | + drm_clflush_virt_range(cpu, sizeof(*cpu)); | |
| 59 | 55 | |
| 60 | 56 | kunmap_atomic(map); |
| 61 | − | |
| 62 | 57 | i915_gem_obj_finish_shmem_access(obj); |
| 58 | + | |
| 63 | 59 | return 0; |
| 64 | 60 | } |
| 65 | 61 | |
| @@ -69,7 +65,8 @@ static int cpu_get(struct drm_i915_gem_object *obj, · 3 unmodified lines | ||
| 69 | 65 | { |
| 70 | 66 | unsigned int needs_clflush; |
| 71 | 67 | struct page *page; |
| 72 | − u32 *map; | |
| 68 | + void *map; | |
| 69 | + u32 *cpu; | |
| 73 | 70 | int err; |
| 74 | 71 | |
| 75 | 72 | err = i915_gem_obj_prepare_shmem_read(obj, &needs_clflush); |
| @@ -78,17 +75,16 @@ static int cpu_get(struct drm_i915_gem_object *obj, · 2 unmodified lines | ||
| 78 | 75 | |
| 79 | 76 | page = i915_gem_object_get_page(obj, offset >> PAGE_SHIFT); |
| 80 | 77 | map = kmap_atomic(page); |
| 78 | + cpu = map + offset_in_page(offset); | |
| 81 | 79 | |
| 82 | − if (needs_clflush & CLFLUSH_BEFORE) { | |
| 83 | − mb(); | |
| 84 | − clflush(map+offset_in_page(offset) / sizeof(*map)); | |
| 85 | − mb(); | |
| 86 | − } | |
| 80 | + if (needs_clflush & CLFLUSH_BEFORE) | |
| 81 | + drm_clflush_virt_range(cpu, sizeof(*cpu)); | |
| 87 | 82 | |
| 88 | − *v = map[offset_in_page(offset) / sizeof(*map)]; | |
| 89 | − kunmap_atomic(map); | |
| 83 | + *v = *cpu; | |
| 90 | 84 | |
| 85 | + kunmap_atomic(map); | |
| 91 | 86 | i915_gem_obj_finish_shmem_access(obj); |
| 87 | + | |
| 92 | 88 | return 0; |
| 93 | 89 | } |
| 94 | 90 | |
| @@ -282,7 +282,7 @@ static int check_partial_mapping(struct drm_i915_gem_object *obj, · 281 unmodified lines | ||
| 282 | 282 | view.partial.offset, |
| 283 | 283 | view.partial.size, |
| 284 | 284 | vma->size >> PAGE_SHIFT, |
| 285 | − tile_row_pages(obj), | |
| 285 | + tile->tiling ? tile_row_pages(obj) : 0, | |
| 286 | 286 | vma->fence ? vma->fence->id : -1, tile->tiling, tile->stride, |
| 287 | 287 | offset >> PAGE_SHIFT, |
| 288 | 288 | (unsigned int)offset_in_page(offset), |
| @@ -17,6 +17,7 @@ selftest(objects, i915_gem_object_live_selftests) · 16 unmodified lines | ||
| 17 | 17 | selftest(dmabuf, i915_gem_dmabuf_live_selftests) |
| 18 | 18 | selftest(coherency, i915_gem_coherency_live_selftests) |
| 19 | 19 | selftest(gtt, i915_gem_gtt_live_selftests) |
| 20 | +selftest(gem, i915_gem_live_selftests) | |
| 20 | 21 | selftest(evict, i915_gem_evict_live_selftests) |
| 21 | 22 | selftest(hugepages, i915_gem_huge_page_live_selftests) |
| 22 | 23 | selftest(contexts, i915_gem_context_live_selftests) |
| @@ -65,6 +65,40 @@ static int check_all_doorbells(struct intel_guc *guc) · 64 unmodified lines | ||
| 65 | 65 | return 0; |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | +static int ring_doorbell_nop(struct intel_guc_client *client) | |
| 69 | +{ | |
| 70 | + struct guc_process_desc *desc = __get_process_desc(client); | |
| 71 | + int err; | |
| 72 | + | |
| 73 | + client->use_nop_wqi = true; | |
| 74 | + | |
| 75 | + spin_lock_irq(&client->wq_lock); | |
| 76 | + | |
| 77 | + guc_wq_item_append(client, 0, 0, 0, 0); | |
| 78 | + guc_ring_doorbell(client); | |
| 79 | + | |
| 80 | + spin_unlock_irq(&client->wq_lock); | |
| 81 | + | |
| 82 | + client->use_nop_wqi = false; | |
| 83 | + | |
| 84 | + /* if there are no issues GuC will update the WQ head and keep the | |
| 85 | + * WQ in active status | |
| 86 | + */ | |
| 87 | + err = wait_for(READ_ONCE(desc->head) == READ_ONCE(desc->tail), 10); | |
| 88 | + if (err) { | |
| 89 | + pr_err("doorbell %u ring failed!\n", client->doorbell_id); | |
| 90 | + return -EIO; | |
| 91 | + } | |
| 92 | + | |
| 93 | + if (desc->wq_status != WQ_STATUS_ACTIVE) { | |
| 94 | + pr_err("doorbell %u ring put WQ in bad state (%u)!\n", | |
| 95 | + client->doorbell_id, desc->wq_status); | |
| 96 | + return -EIO; | |
| 97 | + } | |
| 98 | + | |
| 99 | + return 0; | |
| 100 | +} | |
| 101 | + | |
| 68 | 102 | /* |
| 69 | 103 | * Basic client sanity check, handy to validate create_clients. |
| 70 | 104 | */ |
| @@ -332,6 +366,10 @@ static int igt_guc_doorbells(void *arg) · 261 unmodified lines | ||
| 332 | 366 | err = check_all_doorbells(guc); |
| 333 | 367 | if (err) |
| 334 | 368 | goto out; |
| 369 | + | |
| 370 | + err = ring_doorbell_nop(clients[i]); | |
| 371 | + if (err) | |
| 372 | + goto out; | |
| 335 | 373 | } |
| 336 | 374 | |
| 337 | 375 | out: |
| @@ -1018,8 +1018,41 @@ static int evict_vma(void *data) · 1017 unmodified lines | ||
| 1018 | 1018 | return err; |
| 1019 | 1019 | } |
| 1020 | 1020 | |
| 1021 | +static int evict_fence(void *data) | |
| 1022 | +{ | |
| 1023 | + struct evict_vma *arg = data; | |
| 1024 | + struct drm_i915_private *i915 = arg->vma->vm->i915; | |
| 1025 | + int err; | |
| 1026 | + | |
| 1027 | + complete(&arg->completion); | |
| 1028 | + | |
| 1029 | + mutex_lock(&i915->drm.struct_mutex); | |
| 1030 | + | |
| 1031 | + /* Mark the fence register as dirty to force the mmio update. */ | |
| 1032 | + err = i915_gem_object_set_tiling(arg->vma->obj, I915_TILING_Y, 512); | |
| 1033 | + if (err) { | |
| 1034 | + pr_err("Invalid Y-tiling settings; err:%d\n", err); | |
| 1035 | + goto out_unlock; | |
| 1036 | + } | |
| 1037 | + | |
| 1038 | + err = i915_vma_pin_fence(arg->vma); | |
| 1039 | + if (err) { | |
| 1040 | + pr_err("Unable to pin Y-tiled fence; err:%d\n", err); | |
| 1041 | + goto out_unlock; | |
| 1042 | + } | |
| 1043 | + | |
| 1044 | + i915_vma_unpin_fence(arg->vma); | |
| 1045 | + | |
| 1046 | +out_unlock: | |
| 1047 | + mutex_unlock(&i915->drm.struct_mutex); | |
| 1048 | + | |
| 1049 | + return err; | |
| 1050 | +} | |
| 1051 | + | |
| 1021 | 1052 | static int __igt_reset_evict_vma(struct drm_i915_private *i915, |
| 1022 | − struct i915_address_space *vm) | |
| 1053 | + struct i915_address_space *vm, | |
| 1054 | + int (*fn)(void *), | |
| 1055 | + unsigned int flags) | |
| 1023 | 1056 | { |
| 1024 | 1057 | struct drm_i915_gem_object *obj; |
| 1025 | 1058 | struct task_struct *tsk = NULL; |
| @@ -1040,12 +1073,20 @@ static int __igt_reset_evict_vma(struct drm_i915_private *i915, · 14 unmodified lines | ||
| 1040 | 1073 | if (err) |
| 1041 | 1074 | goto unlock; |
| 1042 | 1075 | |
| 1043 | − obj = i915_gem_object_create_internal(i915, PAGE_SIZE); | |
| 1076 | + obj = i915_gem_object_create_internal(i915, SZ_1M); | |
| 1044 | 1077 | if (IS_ERR(obj)) { |
| 1045 | 1078 | err = PTR_ERR(obj); |
| 1046 | 1079 | goto fini; |
| 1047 | 1080 | } |
| 1048 | 1081 | |
| 1082 | + if (flags & EXEC_OBJECT_NEEDS_FENCE) { | |
| 1083 | + err = i915_gem_object_set_tiling(obj, I915_TILING_X, 512); | |
| 1084 | + if (err) { | |
| 1085 | + pr_err("Invalid X-tiling settings; err:%d\n", err); | |
| 1086 | + goto out_obj; | |
| 1087 | + } | |
| 1088 | + } | |
| 1089 | + | |
| 1049 | 1090 | arg.vma = i915_vma_instance(obj, vm, NULL); |
| 1050 | 1091 | if (IS_ERR(arg.vma)) { |
| 1051 | 1092 | err = PTR_ERR(arg.vma); |
| @@ -1059,11 +1100,28 @@ static int __igt_reset_evict_vma(struct drm_i915_private *i915, · 7 unmodified lines | ||
| 1059 | 1100 | } |
| 1060 | 1101 | |
| 1061 | 1102 | err = i915_vma_pin(arg.vma, 0, 0, |
| 1062 | − i915_vma_is_ggtt(arg.vma) ? PIN_GLOBAL : PIN_USER); | |
| 1063 | − if (err) | |
| 1103 | + i915_vma_is_ggtt(arg.vma) ? | |
| 1104 | + PIN_GLOBAL | PIN_MAPPABLE : | |
| 1105 | + PIN_USER); | |
| 1106 | + if (err) { | |
| 1107 | + i915_request_add(rq); | |
| 1064 | 1108 | goto out_obj; |
| 1109 | + } | |
| 1110 | + | |
| 1111 | + if (flags & EXEC_OBJECT_NEEDS_FENCE) { | |
| 1112 | + err = i915_vma_pin_fence(arg.vma); | |
| 1113 | + if (err) { | |
| 1114 | + pr_err("Unable to pin X-tiled fence; err:%d\n", err); | |
| 1115 | + i915_vma_unpin(arg.vma); | |
| 1116 | + i915_request_add(rq); | |
| 1117 | + goto out_obj; | |
| 1118 | + } | |
| 1119 | + } | |
| 1120 | + | |
| 1121 | + err = i915_vma_move_to_active(arg.vma, rq, flags); | |
| 1065 | 1122 | |
| 1066 | − err = i915_vma_move_to_active(arg.vma, rq, EXEC_OBJECT_WRITE); | |
| 1123 | + if (flags & EXEC_OBJECT_NEEDS_FENCE) | |
| 1124 | + i915_vma_unpin_fence(arg.vma); | |
| 1067 | 1125 | i915_vma_unpin(arg.vma); |
| 1068 | 1126 | |
| 1069 | 1127 | i915_request_get(rq); |
| @@ -1086,7 +1144,7 @@ static int __igt_reset_evict_vma(struct drm_i915_private *i915, · 16 unmodified lines | ||
| 1086 | 1144 | |
| 1087 | 1145 | init_completion(&arg.completion); |
| 1088 | 1146 | |
| 1089 | − tsk = kthread_run(evict_vma, &arg, "igt/evict_vma"); | |
| 1147 | + tsk = kthread_run(fn, &arg, "igt/evict_vma"); | |
| 1090 | 1148 | if (IS_ERR(tsk)) { |
| 1091 | 1149 | err = PTR_ERR(tsk); |
| 1092 | 1150 | tsk = NULL; |
| @@ -1137,29 +1195,47 @@ static int igt_reset_evict_ggtt(void *arg) · 44 unmodified lines | ||
| 1137 | 1195 | { |
| 1138 | 1196 | struct drm_i915_private *i915 = arg; |
| 1139 | 1197 | |
| 1140 | − return __igt_reset_evict_vma(i915, &i915->ggtt.vm); | |
| 1198 | + return __igt_reset_evict_vma(i915, &i915->ggtt.vm, | |
| 1199 | + evict_vma, EXEC_OBJECT_WRITE); | |
| 1141 | 1200 | } |
| 1142 | 1201 | |
| 1143 | 1202 | static int igt_reset_evict_ppgtt(void *arg) |
| 1144 | 1203 | { |
| 1145 | 1204 | struct drm_i915_private *i915 = arg; |
| 1146 | 1205 | struct i915_gem_context *ctx; |
| 1206 | + struct drm_file *file; | |
| 1147 | 1207 | int err; |
| 1148 | 1208 | |
| 1209 | + file = mock_file(i915); | |
| 1210 | + if (IS_ERR(file)) | |
| 1211 | + return PTR_ERR(file); | |
| 1212 | + | |
| 1149 | 1213 | mutex_lock(&i915->drm.struct_mutex); |
| 1150 | − ctx = kernel_context(i915); | |
| 1214 | + ctx = live_context(i915, file); | |
| 1151 | 1215 | mutex_unlock(&i915->drm.struct_mutex); |
| 1152 | − if (IS_ERR(ctx)) | |
| 1153 | − return PTR_ERR(ctx); | |
| 1216 | + if (IS_ERR(ctx)) { | |
| 1217 | + err = PTR_ERR(ctx); | |
| 1218 | + goto out; | |
| 1219 | + } | |
| 1154 | 1220 | |
| 1155 | 1221 | err = 0; |
| 1156 | 1222 | if (ctx->ppgtt) /* aliasing == global gtt locking, covered above */ |
| 1157 | − err = __igt_reset_evict_vma(i915, &ctx->ppgtt->vm); | |
| 1223 | + err = __igt_reset_evict_vma(i915, &ctx->ppgtt->vm, | |
| 1224 | + evict_vma, EXEC_OBJECT_WRITE); | |
| 1158 | 1225 | |
| 1159 | − kernel_context_close(ctx); | |
| 1226 | +out: | |
| 1227 | + mock_file_free(i915, file); | |
| 1160 | 1228 | return err; |
| 1161 | 1229 | } |
| 1162 | 1230 | |
| 1231 | +static int igt_reset_evict_fence(void *arg) | |
| 1232 | +{ | |
| 1233 | + struct drm_i915_private *i915 = arg; | |
| 1234 | + | |
| 1235 | + return __igt_reset_evict_vma(i915, &i915->ggtt.vm, | |
| 1236 | + evict_fence, EXEC_OBJECT_NEEDS_FENCE); | |
| 1237 | +} | |
| 1238 | + | |
| 1163 | 1239 | static int wait_for_others(struct drm_i915_private *i915, |
| 1164 | 1240 | struct intel_engine_cs *exclude) |
| 1165 | 1241 | { |
| @@ -1409,6 +1485,7 @@ int intel_hangcheck_live_selftests(struct drm_i915_private *i915) · 243 unmodified lines | ||
| 1409 | 1485 | SUBTEST(igt_reset_wait), |
| 1410 | 1486 | SUBTEST(igt_reset_evict_ggtt), |
| 1411 | 1487 | SUBTEST(igt_reset_evict_ppgtt), |
| 1488 | + SUBTEST(igt_reset_evict_fence), | |
| 1412 | 1489 | SUBTEST(igt_handle_error), |
| 1413 | 1490 | }; |
| 1414 | 1491 | bool saved_hangcheck; |
| @@ -43,6 +43,7 @@ mock_context(struct drm_i915_private *i915, · 42 unmodified lines | ||
| 43 | 43 | |
| 44 | 44 | INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL); |
| 45 | 45 | INIT_LIST_HEAD(&ctx->handles_list); |
| 46 | + INIT_LIST_HEAD(&ctx->hw_id_link); | |
| 46 | 47 | |
| 47 | 48 | for (n = 0; n < ARRAY_SIZE(ctx->__engine); n++) { |
| 48 | 49 | struct intel_context *ce = &ctx->__engine[n]; |
| @@ -50,11 +51,9 @@ mock_context(struct drm_i915_private *i915, · 1 unmodified line | ||
| 50 | 51 | ce->gem_context = ctx; |
| 51 | 52 | } |
| 52 | 53 | |
| 53 | − ret = ida_simple_get(&i915->contexts.hw_ida, | |
| 54 | − 0, MAX_CONTEXT_HW_ID, GFP_KERNEL); | |
| 54 | + ret = i915_gem_context_pin_hw_id(ctx); | |
| 55 | 55 | if (ret < 0) |
| 56 | 56 | goto err_handles; |
| 57 | − ctx->hw_id = ret; | |
| 58 | 57 | |
| 59 | 58 | if (name) { |
| 60 | 59 | ctx->name = kstrdup(name, GFP_KERNEL); |
| @@ -85,11 +84,7 @@ void mock_context_close(struct i915_gem_context *ctx) · 24 unmodified lines | ||
| 85 | 84 | |
| 86 | 85 | void mock_init_contexts(struct drm_i915_private *i915) |
| 87 | 86 | { |
| 88 | − INIT_LIST_HEAD(&i915->contexts.list); | |
| 89 | − ida_init(&i915->contexts.hw_ida); | |
| 90 | − | |
| 91 | − INIT_WORK(&i915->contexts.free_work, contexts_free_worker); | |
| 92 | − init_llist_head(&i915->contexts.free_list); | |
| 87 | + init_contexts(i915); | |
| 93 | 88 | } |
| 94 | 89 | |
| 95 | 90 | struct i915_gem_context * |
| @@ -118,6 +118,8 @@ void mock_init_ggtt(struct drm_i915_private *i915) · 117 unmodified lines | ||
| 118 | 118 | ggtt->vm.vma_ops.clear_pages = clear_pages; |
| 119 | 119 | |
| 120 | 120 | i915_address_space_init(&ggtt->vm, i915); |
| 121 | + | |
| 122 | + ggtt->vm.is_ggtt = true; | |
| 121 | 123 | } |
| 122 | 124 | |
| 123 | 125 | void mock_fini_ggtt(struct drm_i915_private *i915) |
| @@ -386,6 +386,7 @@ · 385 unmodified lines | ||
| 386 | 386 | INTEL_VGA_DEVICE(0x3E91, info), /* SRV GT2 */ \ |
| 387 | 387 | INTEL_VGA_DEVICE(0x3E92, info), /* SRV GT2 */ \ |
| 388 | 388 | INTEL_VGA_DEVICE(0x3E96, info), /* SRV GT2 */ \ |
| 389 | + INTEL_VGA_DEVICE(0x3E98, info), /* SRV GT2 */ \ | |
| 389 | 390 | INTEL_VGA_DEVICE(0x3E9A, info) /* SRV GT2 */ |
| 390 | 391 | |
| 391 | 392 | /* CFL H */ |
| @@ -529,6 +529,28 @@ typedef struct drm_i915_irq_wait { · 528 unmodified lines | ||
| 529 | 529 | */ |
| 530 | 530 | #define I915_PARAM_CS_TIMESTAMP_FREQUENCY 51 |
| 531 | 531 | |
| 532 | +/* | |
| 533 | + * Once upon a time we supposed that writes through the GGTT would be | |
| 534 | + * immediately in physical memory (once flushed out of the CPU path). However, | |
| 535 | + * on a few different processors and chipsets, this is not necessarily the case | |
| 536 | + * as the writes appear to be buffered internally. Thus a read of the backing | |
| 537 | + * storage (physical memory) via a different path (with different physical tags | |
| 538 | + * to the indirect write via the GGTT) will see stale values from before | |
| 539 | + * the GGTT write. Inside the kernel, we can for the most part keep track of | |
| 540 | + * the different read/write domains in use (e.g. set-domain), but the assumption | |
| 541 | + * of coherency is baked into the ABI, hence reporting its true state in this | |
| 542 | + * parameter. | |
| 543 | + * | |
| 544 | + * Reports true when writes via mmap_gtt are immediately visible following an | |
| 545 | + * lfence to flush the WCB. | |
| 546 | + * | |
| 547 | + * Reports false when writes via mmap_gtt are indeterminately delayed in an in | |
| 548 | + * internal buffer and are _not_ immediately visible to third parties accessing | |
| 549 | + * directly via mmap_cpu/mmap_wc. Use of mmap_gtt as part of an IPC | |
| 550 | + * communications channel when reporting false is strongly disadvised. | |
| 551 | + */ | |
| 552 | +#define I915_PARAM_MMAP_GTT_COHERENT 52 | |
| 553 | + | |
| 532 | 554 | typedef struct drm_i915_getparam { |
| 533 | 555 | __s32 param; |
| 534 | 556 | /* |