Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'drm-intel-next-2018-12-04' of git://anongit.freedesktop.org/drm/drm-intel into drm-next

Final drm/i915 changes for v4.21:
- ICL DSI video mode enabling (Madhav, Vandita, Jani, Imre)
- eDP sink count fix (José)
- PSR fixes (José)
- DRM DP helper and i915 DSC enabling (Manasi, Gaurav, Anusha)
- DP FEC enabling (Anusha)
- SKL+ watermark/ddb programming improvements (Ville)
- Pixel format fixes (Ville)
- Selftest updates (Chris, Tvrtko)
- GT and engine workaround improvements (Tvrtko)

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/87va496uoe.fsf@intel.com

+5375 -1983
+12
Documentation/gpu/drm-kms-helpers.rst
··· 232 232 .. kernel-doc:: drivers/gpu/drm/drm_mipi_dsi.c 233 233 :export: 234 234 235 + Display Stream Compression Helper Functions Reference 236 + ===================================================== 237 + 238 + .. kernel-doc:: drivers/gpu/drm/drm_dsc.c 239 + :doc: dsc helpers 240 + 241 + .. kernel-doc:: include/drm/drm_dsc.h 242 + :internal: 243 + 244 + .. kernel-doc:: drivers/gpu/drm/drm_dsc.c 245 + :export: 246 + 235 247 Output Probing Helper Functions Reference 236 248 ========================================= 237 249
+1 -1
drivers/gpu/drm/Makefile
··· 32 32 drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o 33 33 drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o 34 34 35 - drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ 35 + drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_dsc.o drm_probe_helper.o \ 36 36 drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \ 37 37 drm_kms_helper_common.o drm_dp_dual_mode_helper.o \ 38 38 drm_simple_kms_helper.o drm_modeset_helper.o \
+8 -6
drivers/gpu/drm/drm_dp_helper.c
··· 1428 1428 } 1429 1429 EXPORT_SYMBOL(drm_dp_dsc_sink_line_buf_depth); 1430 1430 1431 - u8 drm_dp_dsc_sink_max_color_depth(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]) 1431 + int drm_dp_dsc_sink_supported_input_bpcs(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE], 1432 + u8 dsc_bpc[3]) 1432 1433 { 1434 + int num_bpc = 0; 1433 1435 u8 color_depth = dsc_dpcd[DP_DSC_DEC_COLOR_DEPTH_CAP - DP_DSC_SUPPORT]; 1434 1436 1435 1437 if (color_depth & DP_DSC_12_BPC) 1436 - return 12; 1438 + dsc_bpc[num_bpc++] = 12; 1437 1439 if (color_depth & DP_DSC_10_BPC) 1438 - return 10; 1440 + dsc_bpc[num_bpc++] = 10; 1439 1441 if (color_depth & DP_DSC_8_BPC) 1440 - return 8; 1442 + dsc_bpc[num_bpc++] = 8; 1441 1443 1442 - return 0; 1444 + return num_bpc; 1443 1445 } 1444 - EXPORT_SYMBOL(drm_dp_dsc_sink_max_color_depth); 1446 + EXPORT_SYMBOL(drm_dp_dsc_sink_supported_input_bpcs);
+228
drivers/gpu/drm/drm_dsc.c
··· 1 + // SPDX-License-Identifier: MIT 2 + /* 3 + * Copyright © 2018 Intel Corp 4 + * 5 + * Author: 6 + * Manasi Navare <manasi.d.navare@intel.com> 7 + */ 8 + 9 + #include <linux/kernel.h> 10 + #include <linux/module.h> 11 + #include <linux/init.h> 12 + #include <linux/errno.h> 13 + #include <linux/byteorder/generic.h> 14 + #include <drm/drm_dp_helper.h> 15 + #include <drm/drm_dsc.h> 16 + 17 + /** 18 + * DOC: dsc helpers 19 + * 20 + * These functions contain some common logic and helpers to deal with VESA 21 + * Display Stream Compression standard required for DSC on Display Port/eDP or 22 + * MIPI display interfaces. 23 + */ 24 + 25 + /** 26 + * drm_dsc_dp_pps_header_init() - Initializes the PPS Header 27 + * for DisplayPort as per the DP 1.4 spec. 28 + * @pps_sdp: Secondary data packet for DSC Picture Parameter Set 29 + */ 30 + void drm_dsc_dp_pps_header_init(struct drm_dsc_pps_infoframe *pps_sdp) 31 + { 32 + memset(&pps_sdp->pps_header, 0, sizeof(pps_sdp->pps_header)); 33 + 34 + pps_sdp->pps_header.HB1 = DP_SDP_PPS; 35 + pps_sdp->pps_header.HB2 = DP_SDP_PPS_HEADER_PAYLOAD_BYTES_MINUS_1; 36 + } 37 + EXPORT_SYMBOL(drm_dsc_dp_pps_header_init); 38 + 39 + /** 40 + * drm_dsc_pps_infoframe_pack() - Populates the DSC PPS infoframe 41 + * using the DSC configuration parameters in the order expected 42 + * by the DSC Display Sink device. For the DSC, the sink device 43 + * expects the PPS payload in the big endian format for the fields 44 + * that span more than 1 byte. 45 + * 46 + * @pps_sdp: 47 + * Secondary data packet for DSC Picture Parameter Set 48 + * @dsc_cfg: 49 + * DSC Configuration data filled by driver 50 + */ 51 + void drm_dsc_pps_infoframe_pack(struct drm_dsc_pps_infoframe *pps_sdp, 52 + const struct drm_dsc_config *dsc_cfg) 53 + { 54 + int i; 55 + 56 + /* Protect against someone accidently changing struct size */ 57 + BUILD_BUG_ON(sizeof(pps_sdp->pps_payload) != 58 + DP_SDP_PPS_HEADER_PAYLOAD_BYTES_MINUS_1 + 1); 59 + 60 + memset(&pps_sdp->pps_payload, 0, sizeof(pps_sdp->pps_payload)); 61 + 62 + /* PPS 0 */ 63 + pps_sdp->pps_payload.dsc_version = 64 + dsc_cfg->dsc_version_minor | 65 + dsc_cfg->dsc_version_major << DSC_PPS_VERSION_MAJOR_SHIFT; 66 + 67 + /* PPS 1, 2 is 0 */ 68 + 69 + /* PPS 3 */ 70 + pps_sdp->pps_payload.pps_3 = 71 + dsc_cfg->line_buf_depth | 72 + dsc_cfg->bits_per_component << DSC_PPS_BPC_SHIFT; 73 + 74 + /* PPS 4 */ 75 + pps_sdp->pps_payload.pps_4 = 76 + ((dsc_cfg->bits_per_pixel & DSC_PPS_BPP_HIGH_MASK) >> 77 + DSC_PPS_MSB_SHIFT) | 78 + dsc_cfg->vbr_enable << DSC_PPS_VBR_EN_SHIFT | 79 + dsc_cfg->enable422 << DSC_PPS_SIMPLE422_SHIFT | 80 + dsc_cfg->convert_rgb << DSC_PPS_CONVERT_RGB_SHIFT | 81 + dsc_cfg->block_pred_enable << DSC_PPS_BLOCK_PRED_EN_SHIFT; 82 + 83 + /* PPS 5 */ 84 + pps_sdp->pps_payload.bits_per_pixel_low = 85 + (dsc_cfg->bits_per_pixel & DSC_PPS_LSB_MASK); 86 + 87 + /* 88 + * The DSC panel expects the PPS packet to have big endian format 89 + * for data spanning 2 bytes. Use a macro cpu_to_be16() to convert 90 + * to big endian format. If format is little endian, it will swap 91 + * bytes to convert to Big endian else keep it unchanged. 92 + */ 93 + 94 + /* PPS 6, 7 */ 95 + pps_sdp->pps_payload.pic_height = cpu_to_be16(dsc_cfg->pic_height); 96 + 97 + /* PPS 8, 9 */ 98 + pps_sdp->pps_payload.pic_width = cpu_to_be16(dsc_cfg->pic_width); 99 + 100 + /* PPS 10, 11 */ 101 + pps_sdp->pps_payload.slice_height = cpu_to_be16(dsc_cfg->slice_height); 102 + 103 + /* PPS 12, 13 */ 104 + pps_sdp->pps_payload.slice_width = cpu_to_be16(dsc_cfg->slice_width); 105 + 106 + /* PPS 14, 15 */ 107 + pps_sdp->pps_payload.chunk_size = cpu_to_be16(dsc_cfg->slice_chunk_size); 108 + 109 + /* PPS 16 */ 110 + pps_sdp->pps_payload.initial_xmit_delay_high = 111 + ((dsc_cfg->initial_xmit_delay & 112 + DSC_PPS_INIT_XMIT_DELAY_HIGH_MASK) >> 113 + DSC_PPS_MSB_SHIFT); 114 + 115 + /* PPS 17 */ 116 + pps_sdp->pps_payload.initial_xmit_delay_low = 117 + (dsc_cfg->initial_xmit_delay & DSC_PPS_LSB_MASK); 118 + 119 + /* PPS 18, 19 */ 120 + pps_sdp->pps_payload.initial_dec_delay = 121 + cpu_to_be16(dsc_cfg->initial_dec_delay); 122 + 123 + /* PPS 20 is 0 */ 124 + 125 + /* PPS 21 */ 126 + pps_sdp->pps_payload.initial_scale_value = 127 + dsc_cfg->initial_scale_value; 128 + 129 + /* PPS 22, 23 */ 130 + pps_sdp->pps_payload.scale_increment_interval = 131 + cpu_to_be16(dsc_cfg->scale_increment_interval); 132 + 133 + /* PPS 24 */ 134 + pps_sdp->pps_payload.scale_decrement_interval_high = 135 + ((dsc_cfg->scale_decrement_interval & 136 + DSC_PPS_SCALE_DEC_INT_HIGH_MASK) >> 137 + DSC_PPS_MSB_SHIFT); 138 + 139 + /* PPS 25 */ 140 + pps_sdp->pps_payload.scale_decrement_interval_low = 141 + (dsc_cfg->scale_decrement_interval & DSC_PPS_LSB_MASK); 142 + 143 + /* PPS 26[7:0], PPS 27[7:5] RESERVED */ 144 + 145 + /* PPS 27 */ 146 + pps_sdp->pps_payload.first_line_bpg_offset = 147 + dsc_cfg->first_line_bpg_offset; 148 + 149 + /* PPS 28, 29 */ 150 + pps_sdp->pps_payload.nfl_bpg_offset = 151 + cpu_to_be16(dsc_cfg->nfl_bpg_offset); 152 + 153 + /* PPS 30, 31 */ 154 + pps_sdp->pps_payload.slice_bpg_offset = 155 + cpu_to_be16(dsc_cfg->slice_bpg_offset); 156 + 157 + /* PPS 32, 33 */ 158 + pps_sdp->pps_payload.initial_offset = 159 + cpu_to_be16(dsc_cfg->initial_offset); 160 + 161 + /* PPS 34, 35 */ 162 + pps_sdp->pps_payload.final_offset = cpu_to_be16(dsc_cfg->final_offset); 163 + 164 + /* PPS 36 */ 165 + pps_sdp->pps_payload.flatness_min_qp = dsc_cfg->flatness_min_qp; 166 + 167 + /* PPS 37 */ 168 + pps_sdp->pps_payload.flatness_max_qp = dsc_cfg->flatness_max_qp; 169 + 170 + /* PPS 38, 39 */ 171 + pps_sdp->pps_payload.rc_model_size = 172 + cpu_to_be16(DSC_RC_MODEL_SIZE_CONST); 173 + 174 + /* PPS 40 */ 175 + pps_sdp->pps_payload.rc_edge_factor = DSC_RC_EDGE_FACTOR_CONST; 176 + 177 + /* PPS 41 */ 178 + pps_sdp->pps_payload.rc_quant_incr_limit0 = 179 + dsc_cfg->rc_quant_incr_limit0; 180 + 181 + /* PPS 42 */ 182 + pps_sdp->pps_payload.rc_quant_incr_limit1 = 183 + dsc_cfg->rc_quant_incr_limit1; 184 + 185 + /* PPS 43 */ 186 + pps_sdp->pps_payload.rc_tgt_offset = DSC_RC_TGT_OFFSET_LO_CONST | 187 + DSC_RC_TGT_OFFSET_HI_CONST << DSC_PPS_RC_TGT_OFFSET_HI_SHIFT; 188 + 189 + /* PPS 44 - 57 */ 190 + for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) 191 + pps_sdp->pps_payload.rc_buf_thresh[i] = 192 + dsc_cfg->rc_buf_thresh[i]; 193 + 194 + /* PPS 58 - 87 */ 195 + /* 196 + * For DSC sink programming the RC Range parameter fields 197 + * are as follows: Min_qp[15:11], max_qp[10:6], offset[5:0] 198 + */ 199 + for (i = 0; i < DSC_NUM_BUF_RANGES; i++) { 200 + pps_sdp->pps_payload.rc_range_parameters[i] = 201 + ((dsc_cfg->rc_range_params[i].range_min_qp << 202 + DSC_PPS_RC_RANGE_MINQP_SHIFT) | 203 + (dsc_cfg->rc_range_params[i].range_max_qp << 204 + DSC_PPS_RC_RANGE_MAXQP_SHIFT) | 205 + (dsc_cfg->rc_range_params[i].range_bpg_offset)); 206 + pps_sdp->pps_payload.rc_range_parameters[i] = 207 + cpu_to_be16(pps_sdp->pps_payload.rc_range_parameters[i]); 208 + } 209 + 210 + /* PPS 88 */ 211 + pps_sdp->pps_payload.native_422_420 = dsc_cfg->native_422 | 212 + dsc_cfg->native_420 << DSC_PPS_NATIVE_420_SHIFT; 213 + 214 + /* PPS 89 */ 215 + pps_sdp->pps_payload.second_line_bpg_offset = 216 + dsc_cfg->second_line_bpg_offset; 217 + 218 + /* PPS 90, 91 */ 219 + pps_sdp->pps_payload.nsl_bpg_offset = 220 + cpu_to_be16(dsc_cfg->nsl_bpg_offset); 221 + 222 + /* PPS 92, 93 */ 223 + pps_sdp->pps_payload.second_line_offset_adj = 224 + cpu_to_be16(dsc_cfg->second_line_offset_adj); 225 + 226 + /* PPS 94 - 127 are O */ 227 + } 228 + EXPORT_SYMBOL(drm_dsc_pps_infoframe_pack);
+5 -2
drivers/gpu/drm/i915/Makefile
··· 157 157 intel_sdvo.o \ 158 158 intel_tv.o \ 159 159 vlv_dsi.o \ 160 - vlv_dsi_pll.o 160 + vlv_dsi_pll.o \ 161 + intel_vdsc.o 161 162 162 163 # Post-mortem debug and GPU hang state capture 163 164 i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o 164 165 i915-$(CONFIG_DRM_I915_SELFTEST) += \ 165 166 selftests/i915_random.o \ 166 167 selftests/i915_selftest.o \ 167 - selftests/igt_flush_test.o 168 + selftests/igt_flush_test.o \ 169 + selftests/igt_reset.o \ 170 + selftests/igt_spinner.o 168 171 169 172 # virtual gpu code 170 173 i915-y += i915_vgpu.o
+39 -29
drivers/gpu/drm/i915/i915_debugfs.c
··· 943 943 static ssize_t gpu_state_read(struct file *file, char __user *ubuf, 944 944 size_t count, loff_t *pos) 945 945 { 946 - struct i915_gpu_state *error = file->private_data; 947 - struct drm_i915_error_state_buf str; 946 + struct i915_gpu_state *error; 948 947 ssize_t ret; 949 - loff_t tmp; 948 + void *buf; 950 949 950 + error = file->private_data; 951 951 if (!error) 952 952 return 0; 953 953 954 - ret = i915_error_state_buf_init(&str, error->i915, count, *pos); 955 - if (ret) 956 - return ret; 954 + /* Bounce buffer required because of kernfs __user API convenience. */ 955 + buf = kmalloc(count, GFP_KERNEL); 956 + if (!buf) 957 + return -ENOMEM; 957 958 958 - ret = i915_error_state_to_str(&str, error); 959 - if (ret) 959 + ret = i915_gpu_state_copy_to_buffer(error, buf, *pos, count); 960 + if (ret <= 0) 960 961 goto out; 961 962 962 - tmp = 0; 963 - ret = simple_read_from_buffer(ubuf, count, &tmp, str.buf, str.bytes); 964 - if (ret < 0) 965 - goto out; 963 + if (!copy_to_user(ubuf, buf, ret)) 964 + *pos += ret; 965 + else 966 + ret = -EFAULT; 966 967 967 - *pos = str.start + ret; 968 968 out: 969 - i915_error_state_buf_release(&str); 969 + kfree(buf); 970 970 return ret; 971 971 } 972 972 ··· 3375 3375 3376 3376 static int i915_wa_registers(struct seq_file *m, void *unused) 3377 3377 { 3378 - struct i915_workarounds *wa = &node_to_i915(m->private)->workarounds; 3379 - int i; 3378 + struct drm_i915_private *i915 = node_to_i915(m->private); 3379 + const struct i915_wa_list *wal = &i915->engine[RCS]->ctx_wa_list; 3380 + struct i915_wa *wa; 3381 + unsigned int i; 3380 3382 3381 - seq_printf(m, "Workarounds applied: %d\n", wa->count); 3382 - for (i = 0; i < wa->count; ++i) 3383 + seq_printf(m, "Workarounds applied: %u\n", wal->count); 3384 + for (i = 0, wa = wal->list; i < wal->count; i++, wa++) 3383 3385 seq_printf(m, "0x%X: 0x%08X, mask: 0x%08X\n", 3384 - wa->reg[i].addr, wa->reg[i].value, wa->reg[i].mask); 3386 + i915_mmio_reg_offset(wa->reg), wa->val, wa->mask); 3385 3387 3386 3388 return 0; 3387 3389 } ··· 3443 3441 { 3444 3442 struct drm_i915_private *dev_priv = node_to_i915(m->private); 3445 3443 struct drm_device *dev = &dev_priv->drm; 3446 - struct skl_ddb_allocation *ddb; 3447 3444 struct skl_ddb_entry *entry; 3448 - enum pipe pipe; 3449 - int plane; 3445 + struct intel_crtc *crtc; 3450 3446 3451 3447 if (INTEL_GEN(dev_priv) < 9) 3452 3448 return -ENODEV; 3453 3449 3454 3450 drm_modeset_lock_all(dev); 3455 3451 3456 - ddb = &dev_priv->wm.skl_hw.ddb; 3457 - 3458 3452 seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size"); 3459 3453 3460 - for_each_pipe(dev_priv, pipe) { 3454 + for_each_intel_crtc(&dev_priv->drm, crtc) { 3455 + struct intel_crtc_state *crtc_state = 3456 + to_intel_crtc_state(crtc->base.state); 3457 + enum pipe pipe = crtc->pipe; 3458 + enum plane_id plane_id; 3459 + 3461 3460 seq_printf(m, "Pipe %c\n", pipe_name(pipe)); 3462 3461 3463 - for_each_universal_plane(dev_priv, pipe, plane) { 3464 - entry = &ddb->plane[pipe][plane]; 3465 - seq_printf(m, " Plane%-8d%8u%8u%8u\n", plane + 1, 3462 + for_each_plane_id_on_crtc(crtc, plane_id) { 3463 + entry = &crtc_state->wm.skl.plane_ddb_y[plane_id]; 3464 + seq_printf(m, " Plane%-8d%8u%8u%8u\n", plane_id + 1, 3466 3465 entry->start, entry->end, 3467 3466 skl_ddb_entry_size(entry)); 3468 3467 } 3469 3468 3470 - entry = &ddb->plane[pipe][PLANE_CURSOR]; 3469 + entry = &crtc_state->wm.skl.plane_ddb_y[PLANE_CURSOR]; 3471 3470 seq_printf(m, " %-13s%8u%8u%8u\n", "Cursor", entry->start, 3472 3471 entry->end, skl_ddb_entry_size(entry)); 3473 3472 } ··· 4594 4591 { 4595 4592 struct drm_i915_private *dev_priv = m->private; 4596 4593 struct i915_hotplug *hotplug = &dev_priv->hotplug; 4594 + 4595 + /* Synchronize with everything first in case there's been an HPD 4596 + * storm, but we haven't finished handling it in the kernel yet 4597 + */ 4598 + synchronize_irq(dev_priv->drm.irq); 4599 + flush_work(&dev_priv->hotplug.dig_port_work); 4600 + flush_work(&dev_priv->hotplug.hotplug_work); 4597 4601 4598 4602 seq_printf(m, "Threshold: %d\n", hotplug->hpd_storm_threshold); 4599 4603 seq_printf(m, "Detected: %s\n",
+22 -5
drivers/gpu/drm/i915/i915_drv.c
··· 53 53 #include "i915_vgpu.h" 54 54 #include "intel_drv.h" 55 55 #include "intel_uc.h" 56 + #include "intel_workarounds.h" 56 57 57 58 static struct drm_driver driver; 58 59 ··· 288 287 * Use PCH_NOP (PCH but no South Display) for PCH platforms without 289 288 * display. 290 289 */ 291 - if (pch && INTEL_INFO(dev_priv)->num_pipes == 0) { 290 + if (pch && !HAS_DISPLAY(dev_priv)) { 292 291 DRM_DEBUG_KMS("Display disabled, reverting to NOP PCH\n"); 293 292 dev_priv->pch_type = PCH_NOP; 294 293 dev_priv->pch_id = 0; ··· 646 645 if (i915_inject_load_failure()) 647 646 return -ENODEV; 648 647 649 - if (INTEL_INFO(dev_priv)->num_pipes) { 648 + if (HAS_DISPLAY(dev_priv)) { 650 649 ret = drm_vblank_init(&dev_priv->drm, 651 650 INTEL_INFO(dev_priv)->num_pipes); 652 651 if (ret) ··· 697 696 698 697 intel_overlay_setup(dev_priv); 699 698 700 - if (INTEL_INFO(dev_priv)->num_pipes == 0) 699 + if (!HAS_DISPLAY(dev_priv)) 701 700 return 0; 702 701 703 702 ret = intel_fbdev_init(dev); ··· 869 868 pre |= IS_HSW_EARLY_SDV(dev_priv); 870 869 pre |= IS_SKL_REVID(dev_priv, 0, SKL_REVID_F0); 871 870 pre |= IS_BXT_REVID(dev_priv, 0, BXT_REVID_B_LAST); 871 + pre |= IS_KBL_REVID(dev_priv, 0, KBL_REVID_A0); 872 872 873 873 if (pre) { 874 874 DRM_ERROR("This is a pre-production stepping. " ··· 1385 1383 } 1386 1384 } 1387 1385 1386 + if (HAS_EXECLISTS(dev_priv)) { 1387 + /* 1388 + * Older GVT emulation depends upon intercepting CSB mmio, 1389 + * which we no longer use, preferring to use the HWSP cache 1390 + * instead. 1391 + */ 1392 + if (intel_vgpu_active(dev_priv) && 1393 + !intel_vgpu_has_hwsp_emulation(dev_priv)) { 1394 + i915_report_error(dev_priv, 1395 + "old vGPU host found, support for HWSP emulation required\n"); 1396 + return -ENXIO; 1397 + } 1398 + } 1399 + 1388 1400 intel_sanitize_options(dev_priv); 1389 1401 1390 1402 i915_perf_init(dev_priv); ··· 1468 1452 1469 1453 intel_uncore_sanitize(dev_priv); 1470 1454 1455 + intel_gt_init_workarounds(dev_priv); 1471 1456 i915_gem_load_init_fences(dev_priv); 1472 1457 1473 1458 /* On the 945G/GM, the chipset reports the MSI capability on the ··· 1568 1551 } else 1569 1552 DRM_ERROR("Failed to register driver for userspace access!\n"); 1570 1553 1571 - if (INTEL_INFO(dev_priv)->num_pipes) { 1554 + if (HAS_DISPLAY(dev_priv)) { 1572 1555 /* Must be done after probing outputs */ 1573 1556 intel_opregion_register(dev_priv); 1574 1557 acpi_video_register(); ··· 1592 1575 * We need to coordinate the hotplugs with the asynchronous fbdev 1593 1576 * configuration, for which we use the fbdev->async_cookie. 1594 1577 */ 1595 - if (INTEL_INFO(dev_priv)->num_pipes) 1578 + if (HAS_DISPLAY(dev_priv)) 1596 1579 drm_kms_helper_poll_init(dev); 1597 1580 1598 1581 intel_power_domains_enable(dev_priv);
+31 -31
drivers/gpu/drm/i915/i915_drv.h
··· 53 53 #include <drm/drm_auth.h> 54 54 #include <drm/drm_cache.h> 55 55 #include <drm/drm_util.h> 56 + #include <drm/drm_dsc.h> 56 57 57 58 #include "i915_fixed.h" 58 59 #include "i915_params.h" ··· 69 68 #include "intel_ringbuffer.h" 70 69 #include "intel_uncore.h" 71 70 #include "intel_wopcm.h" 71 + #include "intel_workarounds.h" 72 72 #include "intel_uc.h" 73 73 74 74 #include "i915_gem.h" ··· 90 88 91 89 #define DRIVER_NAME "i915" 92 90 #define DRIVER_DESC "Intel Graphics" 93 - #define DRIVER_DATE "20181122" 94 - #define DRIVER_TIMESTAMP 1542898187 91 + #define DRIVER_DATE "20181204" 92 + #define DRIVER_TIMESTAMP 1543944377 95 93 96 94 /* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and 97 95 * WARN_ON()) for hw state sanity checks to check for unexpected conditions ··· 496 494 bool sink_support; 497 495 bool prepared, enabled; 498 496 struct intel_dp *dp; 497 + enum pipe pipe; 499 498 bool active; 500 499 struct work_struct work; 501 500 unsigned busy_frontbuffer_bits; ··· 507 504 u8 sink_sync_latency; 508 505 ktime_t last_entry_attempt; 509 506 ktime_t last_exit; 507 + bool sink_not_reliable; 508 + bool irq_aux_error; 510 509 }; 511 510 512 511 enum intel_pch { ··· 1098 1093 } 1099 1094 1100 1095 struct skl_ddb_allocation { 1101 - /* packed/y */ 1102 - struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES]; 1103 - struct skl_ddb_entry uv_plane[I915_MAX_PIPES][I915_MAX_PLANES]; 1104 1096 u8 enabled_slices; /* GEN11 has configurable 2 slices */ 1105 1097 }; 1106 1098 ··· 1188 1186 */ 1189 1187 unsigned busy_bits; 1190 1188 unsigned flip_bits; 1191 - }; 1192 - 1193 - struct i915_wa_reg { 1194 - u32 addr; 1195 - u32 value; 1196 - /* bitmask representing WA bits */ 1197 - u32 mask; 1198 - }; 1199 - 1200 - #define I915_MAX_WA_REGS 16 1201 - 1202 - struct i915_workarounds { 1203 - struct i915_wa_reg reg[I915_MAX_WA_REGS]; 1204 - u32 count; 1205 1189 }; 1206 1190 1207 1191 struct i915_virtual_gpu { ··· 1639 1651 1640 1652 int dpio_phy_iosf_port[I915_NUM_PHYS_VLV]; 1641 1653 1642 - struct i915_workarounds workarounds; 1654 + struct i915_wa_list gt_wa_list; 1643 1655 1644 1656 struct i915_frontbuffer_tracking fb_tracking; 1645 1657 ··· 1983 1995 struct delayed_work idle_work; 1984 1996 1985 1997 ktime_t last_init_time; 1998 + 1999 + struct i915_vma *scratch; 1986 2000 } gt; 1987 2001 1988 2002 /* perform PHY state sanity checks? */ ··· 2438 2448 ((sizes) & ~(dev_priv)->info.page_sizes) == 0; \ 2439 2449 }) 2440 2450 2441 - #define HAS_OVERLAY(dev_priv) ((dev_priv)->info.has_overlay) 2451 + #define HAS_OVERLAY(dev_priv) ((dev_priv)->info.display.has_overlay) 2442 2452 #define OVERLAY_NEEDS_PHYSICAL(dev_priv) \ 2443 - ((dev_priv)->info.overlay_needs_physical) 2453 + ((dev_priv)->info.display.overlay_needs_physical) 2444 2454 2445 2455 /* Early gen2 have a totally busted CS tlb and require pinned batches. */ 2446 2456 #define HAS_BROKEN_CS_TLB(dev_priv) (IS_I830(dev_priv) || IS_I845G(dev_priv)) ··· 2461 2471 #define HAS_128_BYTE_Y_TILING(dev_priv) (!IS_GEN2(dev_priv) && \ 2462 2472 !(IS_I915G(dev_priv) || \ 2463 2473 IS_I915GM(dev_priv))) 2464 - #define SUPPORTS_TV(dev_priv) ((dev_priv)->info.supports_tv) 2465 - #define I915_HAS_HOTPLUG(dev_priv) ((dev_priv)->info.has_hotplug) 2474 + #define SUPPORTS_TV(dev_priv) ((dev_priv)->info.display.supports_tv) 2475 + #define I915_HAS_HOTPLUG(dev_priv) ((dev_priv)->info.display.has_hotplug) 2466 2476 2467 2477 #define HAS_FW_BLC(dev_priv) (INTEL_GEN(dev_priv) > 2) 2468 - #define HAS_FBC(dev_priv) ((dev_priv)->info.has_fbc) 2478 + #define HAS_FBC(dev_priv) ((dev_priv)->info.display.has_fbc) 2469 2479 #define HAS_CUR_FBC(dev_priv) (!HAS_GMCH_DISPLAY(dev_priv) && INTEL_GEN(dev_priv) >= 7) 2470 2480 2471 2481 #define HAS_IPS(dev_priv) (IS_HSW_ULT(dev_priv) || IS_BROADWELL(dev_priv)) 2472 2482 2473 - #define HAS_DP_MST(dev_priv) ((dev_priv)->info.has_dp_mst) 2483 + #define HAS_DP_MST(dev_priv) ((dev_priv)->info.display.has_dp_mst) 2474 2484 2475 - #define HAS_DDI(dev_priv) ((dev_priv)->info.has_ddi) 2485 + #define HAS_DDI(dev_priv) ((dev_priv)->info.display.has_ddi) 2476 2486 #define HAS_FPGA_DBG_UNCLAIMED(dev_priv) ((dev_priv)->info.has_fpga_dbg) 2477 - #define HAS_PSR(dev_priv) ((dev_priv)->info.has_psr) 2487 + #define HAS_PSR(dev_priv) ((dev_priv)->info.display.has_psr) 2478 2488 2479 2489 #define HAS_RC6(dev_priv) ((dev_priv)->info.has_rc6) 2480 2490 #define HAS_RC6p(dev_priv) ((dev_priv)->info.has_rc6p) 2481 2491 #define HAS_RC6pp(dev_priv) (false) /* HW was never validated */ 2482 2492 2483 - #define HAS_CSR(dev_priv) ((dev_priv)->info.has_csr) 2493 + #define HAS_CSR(dev_priv) ((dev_priv)->info.display.has_csr) 2484 2494 2485 2495 #define HAS_RUNTIME_PM(dev_priv) ((dev_priv)->info.has_runtime_pm) 2486 2496 #define HAS_64BIT_RELOC(dev_priv) ((dev_priv)->info.has_64bit_reloc) 2487 2497 2488 - #define HAS_IPC(dev_priv) ((dev_priv)->info.has_ipc) 2498 + #define HAS_IPC(dev_priv) ((dev_priv)->info.display.has_ipc) 2489 2499 2490 2500 /* 2491 2501 * For now, anything with a GuC requires uCode loading, and then supports ··· 2546 2556 #define HAS_PCH_NOP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_NOP) 2547 2557 #define HAS_PCH_SPLIT(dev_priv) (INTEL_PCH_TYPE(dev_priv) != PCH_NONE) 2548 2558 2549 - #define HAS_GMCH_DISPLAY(dev_priv) ((dev_priv)->info.has_gmch_display) 2559 + #define HAS_GMCH_DISPLAY(dev_priv) ((dev_priv)->info.display.has_gmch_display) 2550 2560 2551 2561 #define HAS_LSPCON(dev_priv) (INTEL_GEN(dev_priv) >= 9) 2552 2562 ··· 2557 2567 2558 2568 #define GT_FREQUENCY_MULTIPLIER 50 2559 2569 #define GEN9_FREQ_SCALER 3 2570 + 2571 + #define HAS_DISPLAY(dev_priv) (INTEL_INFO(dev_priv)->num_pipes > 0) 2560 2572 2561 2573 #include "i915_trace.h" 2562 2574 ··· 3332 3340 bool interactive); 3333 3341 extern bool intel_set_memory_cxsr(struct drm_i915_private *dev_priv, 3334 3342 bool enable); 3343 + void intel_dsc_enable(struct intel_encoder *encoder, 3344 + const struct intel_crtc_state *crtc_state); 3345 + void intel_dsc_disable(const struct intel_crtc_state *crtc_state); 3335 3346 3336 3347 int i915_reg_read_ioctl(struct drm_device *dev, void *data, 3337 3348 struct drm_file *file); ··· 3713 3718 return CNL_HWS_CSB_WRITE_INDEX; 3714 3719 else 3715 3720 return I915_HWS_CSB_WRITE_INDEX; 3721 + } 3722 + 3723 + static inline u32 i915_scratch_offset(const struct drm_i915_private *i915) 3724 + { 3725 + return i915_ggtt_offset(i915->gt.scratch); 3716 3726 } 3717 3727 3718 3728 #endif
+65 -46
drivers/gpu/drm/i915/i915_gem.c
··· 3309 3309 3310 3310 static void nop_submit_request(struct i915_request *request) 3311 3311 { 3312 - GEM_TRACE("%s fence %llx:%d -> -EIO\n", 3313 - request->engine->name, 3314 - request->fence.context, request->fence.seqno); 3315 - dma_fence_set_error(&request->fence, -EIO); 3316 - 3317 - i915_request_submit(request); 3318 - } 3319 - 3320 - static void nop_complete_submit_request(struct i915_request *request) 3321 - { 3322 3312 unsigned long flags; 3323 3313 3324 3314 GEM_TRACE("%s fence %llx:%d -> -EIO\n", ··· 3344 3354 * rolling the global seqno forward (since this would complete requests 3345 3355 * for which we haven't set the fence error to EIO yet). 3346 3356 */ 3347 - for_each_engine(engine, i915, id) { 3357 + for_each_engine(engine, i915, id) 3348 3358 i915_gem_reset_prepare_engine(engine); 3349 - 3350 - engine->submit_request = nop_submit_request; 3351 - engine->schedule = NULL; 3352 - } 3353 - i915->caps.scheduler = 0; 3354 3359 3355 3360 /* Even if the GPU reset fails, it should still stop the engines */ 3356 3361 if (INTEL_GEN(i915) >= 5) 3357 3362 intel_gpu_reset(i915, ALL_ENGINES); 3358 3363 3359 - /* 3360 - * Make sure no one is running the old callback before we proceed with 3361 - * cancelling requests and resetting the completion tracking. Otherwise 3362 - * we might submit a request to the hardware which never completes. 3363 - */ 3364 - synchronize_rcu(); 3365 - 3366 3364 for_each_engine(engine, i915, id) { 3367 - /* Mark all executing requests as skipped */ 3368 - engine->cancel_requests(engine); 3369 - 3370 - /* 3371 - * Only once we've force-cancelled all in-flight requests can we 3372 - * start to complete all requests. 3373 - */ 3374 - engine->submit_request = nop_complete_submit_request; 3365 + engine->submit_request = nop_submit_request; 3366 + engine->schedule = NULL; 3375 3367 } 3368 + i915->caps.scheduler = 0; 3376 3369 3377 3370 /* 3378 3371 * Make sure no request can slip through without getting completed by 3379 3372 * either this call here to intel_engine_init_global_seqno, or the one 3380 - * in nop_complete_submit_request. 3373 + * in nop_submit_request. 3381 3374 */ 3382 3375 synchronize_rcu(); 3383 3376 3377 + /* Mark all executing requests as skipped */ 3378 + for_each_engine(engine, i915, id) 3379 + engine->cancel_requests(engine); 3380 + 3384 3381 for_each_engine(engine, i915, id) { 3385 - unsigned long flags; 3386 - 3387 - /* 3388 - * Mark all pending requests as complete so that any concurrent 3389 - * (lockless) lookup doesn't try and wait upon the request as we 3390 - * reset it. 3391 - */ 3392 - spin_lock_irqsave(&engine->timeline.lock, flags); 3393 - intel_engine_init_global_seqno(engine, 3394 - intel_engine_last_submit(engine)); 3395 - spin_unlock_irqrestore(&engine->timeline.lock, flags); 3396 - 3397 3382 i915_gem_reset_finish_engine(engine); 3383 + intel_engine_wakeup(engine); 3398 3384 } 3399 3385 3400 3386 out: ··· 5300 5334 I915_WRITE(MI_PREDICATE_RESULT_2, IS_HSW_GT3(dev_priv) ? 5301 5335 LOWER_SLICE_ENABLED : LOWER_SLICE_DISABLED); 5302 5336 5303 - intel_gt_workarounds_apply(dev_priv); 5337 + /* Apply the GT workarounds... */ 5338 + intel_gt_apply_workarounds(dev_priv); 5339 + /* ...and determine whether they are sticking. */ 5340 + intel_gt_verify_workarounds(dev_priv, "init"); 5304 5341 5305 5342 i915_gem_init_swizzling(dev_priv); 5306 5343 ··· 5498 5529 goto out_ctx; 5499 5530 } 5500 5531 5532 + static int 5533 + i915_gem_init_scratch(struct drm_i915_private *i915, unsigned int size) 5534 + { 5535 + struct drm_i915_gem_object *obj; 5536 + struct i915_vma *vma; 5537 + int ret; 5538 + 5539 + obj = i915_gem_object_create_stolen(i915, size); 5540 + if (!obj) 5541 + obj = i915_gem_object_create_internal(i915, size); 5542 + if (IS_ERR(obj)) { 5543 + DRM_ERROR("Failed to allocate scratch page\n"); 5544 + return PTR_ERR(obj); 5545 + } 5546 + 5547 + vma = i915_vma_instance(obj, &i915->ggtt.vm, NULL); 5548 + if (IS_ERR(vma)) { 5549 + ret = PTR_ERR(vma); 5550 + goto err_unref; 5551 + } 5552 + 5553 + ret = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH); 5554 + if (ret) 5555 + goto err_unref; 5556 + 5557 + i915->gt.scratch = vma; 5558 + return 0; 5559 + 5560 + err_unref: 5561 + i915_gem_object_put(obj); 5562 + return ret; 5563 + } 5564 + 5565 + static void i915_gem_fini_scratch(struct drm_i915_private *i915) 5566 + { 5567 + i915_vma_unpin_and_release(&i915->gt.scratch, 0); 5568 + } 5569 + 5501 5570 int i915_gem_init(struct drm_i915_private *dev_priv) 5502 5571 { 5503 5572 int ret; ··· 5582 5575 goto err_unlock; 5583 5576 } 5584 5577 5585 - ret = i915_gem_contexts_init(dev_priv); 5578 + ret = i915_gem_init_scratch(dev_priv, 5579 + IS_GEN2(dev_priv) ? SZ_256K : PAGE_SIZE); 5586 5580 if (ret) { 5587 5581 GEM_BUG_ON(ret == -EIO); 5588 5582 goto err_ggtt; 5583 + } 5584 + 5585 + ret = i915_gem_contexts_init(dev_priv); 5586 + if (ret) { 5587 + GEM_BUG_ON(ret == -EIO); 5588 + goto err_scratch; 5589 5589 } 5590 5590 5591 5591 ret = intel_engines_init(dev_priv); ··· 5667 5653 err_context: 5668 5654 if (ret != -EIO) 5669 5655 i915_gem_contexts_fini(dev_priv); 5656 + err_scratch: 5657 + i915_gem_fini_scratch(dev_priv); 5670 5658 err_ggtt: 5671 5659 err_unlock: 5672 5660 intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); ··· 5720 5704 intel_uc_fini(dev_priv); 5721 5705 i915_gem_cleanup_engines(dev_priv); 5722 5706 i915_gem_contexts_fini(dev_priv); 5707 + i915_gem_fini_scratch(dev_priv); 5723 5708 mutex_unlock(&dev_priv->drm.struct_mutex); 5709 + 5710 + intel_wa_list_free(&dev_priv->gt_wa_list); 5724 5711 5725 5712 intel_cleanup_gt_powersave(dev_priv); 5726 5713
+1 -5
drivers/gpu/drm/i915/i915_gem_context.c
··· 535 535 int i915_gem_contexts_init(struct drm_i915_private *dev_priv) 536 536 { 537 537 struct i915_gem_context *ctx; 538 - int ret; 539 538 540 539 /* Reassure ourselves we are only called once */ 541 540 GEM_BUG_ON(dev_priv->kernel_context); 542 541 GEM_BUG_ON(dev_priv->preempt_context); 543 542 544 - ret = intel_ctx_workarounds_init(dev_priv); 545 - if (ret) 546 - return ret; 547 - 543 + intel_engine_init_ctx_wa(dev_priv->engine[RCS]); 548 544 init_contexts(dev_priv); 549 545 550 546 /* lowest priority; idle task */
+211 -134
drivers/gpu/drm/i915/i915_gpu_error.c
··· 27 27 * 28 28 */ 29 29 30 - #include <linux/utsname.h> 31 - #include <linux/stop_machine.h> 32 - #include <linux/zlib.h> 33 - #include <drm/drm_print.h> 34 30 #include <linux/ascii85.h> 31 + #include <linux/nmi.h> 32 + #include <linux/scatterlist.h> 33 + #include <linux/stop_machine.h> 34 + #include <linux/utsname.h> 35 + #include <linux/zlib.h> 36 + 37 + #include <drm/drm_print.h> 35 38 36 39 #include "i915_gpu_error.h" 37 40 #include "i915_drv.h" ··· 80 77 return purgeable ? " purgeable" : ""; 81 78 } 82 79 83 - static bool __i915_error_ok(struct drm_i915_error_state_buf *e) 80 + static void __sg_set_buf(struct scatterlist *sg, 81 + void *addr, unsigned int len, loff_t it) 84 82 { 85 - 86 - if (!e->err && WARN(e->bytes > (e->size - 1), "overflow")) { 87 - e->err = -ENOSPC; 88 - return false; 89 - } 90 - 91 - if (e->bytes == e->size - 1 || e->err) 92 - return false; 93 - 94 - return true; 83 + sg->page_link = (unsigned long)virt_to_page(addr); 84 + sg->offset = offset_in_page(addr); 85 + sg->length = len; 86 + sg->dma_address = it; 95 87 } 96 88 97 - static bool __i915_error_seek(struct drm_i915_error_state_buf *e, 98 - unsigned len) 89 + static bool __i915_error_grow(struct drm_i915_error_state_buf *e, size_t len) 99 90 { 100 - if (e->pos + len <= e->start) { 101 - e->pos += len; 91 + if (!len) 102 92 return false; 93 + 94 + if (e->bytes + len + 1 <= e->size) 95 + return true; 96 + 97 + if (e->bytes) { 98 + __sg_set_buf(e->cur++, e->buf, e->bytes, e->iter); 99 + e->iter += e->bytes; 100 + e->buf = NULL; 101 + e->bytes = 0; 103 102 } 104 103 105 - /* First vsnprintf needs to fit in its entirety for memmove */ 106 - if (len >= e->size) { 107 - e->err = -EIO; 108 - return false; 109 - } 104 + if (e->cur == e->end) { 105 + struct scatterlist *sgl; 110 106 111 - return true; 112 - } 113 - 114 - static void __i915_error_advance(struct drm_i915_error_state_buf *e, 115 - unsigned len) 116 - { 117 - /* If this is first printf in this window, adjust it so that 118 - * start position matches start of the buffer 119 - */ 120 - 121 - if (e->pos < e->start) { 122 - const size_t off = e->start - e->pos; 123 - 124 - /* Should not happen but be paranoid */ 125 - if (off > len || e->bytes) { 126 - e->err = -EIO; 127 - return; 107 + sgl = (typeof(sgl))__get_free_page(GFP_KERNEL); 108 + if (!sgl) { 109 + e->err = -ENOMEM; 110 + return false; 128 111 } 129 112 130 - memmove(e->buf, e->buf + off, len - off); 131 - e->bytes = len - off; 132 - e->pos = e->start; 133 - return; 113 + if (e->cur) { 114 + e->cur->offset = 0; 115 + e->cur->length = 0; 116 + e->cur->page_link = 117 + (unsigned long)sgl | SG_CHAIN; 118 + } else { 119 + e->sgl = sgl; 120 + } 121 + 122 + e->cur = sgl; 123 + e->end = sgl + SG_MAX_SINGLE_ALLOC - 1; 134 124 } 135 125 136 - e->bytes += len; 137 - e->pos += len; 126 + e->size = ALIGN(len + 1, SZ_64K); 127 + e->buf = kmalloc(e->size, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); 128 + if (!e->buf) { 129 + e->size = PAGE_ALIGN(len + 1); 130 + e->buf = kmalloc(e->size, GFP_KERNEL); 131 + } 132 + if (!e->buf) { 133 + e->err = -ENOMEM; 134 + return false; 135 + } 136 + 137 + return true; 138 138 } 139 139 140 140 __printf(2, 0) 141 141 static void i915_error_vprintf(struct drm_i915_error_state_buf *e, 142 - const char *f, va_list args) 142 + const char *fmt, va_list args) 143 143 { 144 - unsigned len; 144 + va_list ap; 145 + int len; 145 146 146 - if (!__i915_error_ok(e)) 147 + if (e->err) 147 148 return; 148 149 149 - /* Seek the first printf which is hits start position */ 150 - if (e->pos < e->start) { 151 - va_list tmp; 152 - 153 - va_copy(tmp, args); 154 - len = vsnprintf(NULL, 0, f, tmp); 155 - va_end(tmp); 156 - 157 - if (!__i915_error_seek(e, len)) 158 - return; 150 + va_copy(ap, args); 151 + len = vsnprintf(NULL, 0, fmt, ap); 152 + va_end(ap); 153 + if (len <= 0) { 154 + e->err = len; 155 + return; 159 156 } 160 157 161 - len = vsnprintf(e->buf + e->bytes, e->size - e->bytes, f, args); 162 - if (len >= e->size - e->bytes) 163 - len = e->size - e->bytes - 1; 158 + if (!__i915_error_grow(e, len)) 159 + return; 164 160 165 - __i915_error_advance(e, len); 161 + GEM_BUG_ON(e->bytes >= e->size); 162 + len = vscnprintf(e->buf + e->bytes, e->size - e->bytes, fmt, args); 163 + if (len < 0) { 164 + e->err = len; 165 + return; 166 + } 167 + e->bytes += len; 166 168 } 167 169 168 - static void i915_error_puts(struct drm_i915_error_state_buf *e, 169 - const char *str) 170 + static void i915_error_puts(struct drm_i915_error_state_buf *e, const char *str) 170 171 { 171 172 unsigned len; 172 173 173 - if (!__i915_error_ok(e)) 174 + if (e->err || !str) 174 175 return; 175 176 176 177 len = strlen(str); 178 + if (!__i915_error_grow(e, len)) 179 + return; 177 180 178 - /* Seek the first printf which is hits start position */ 179 - if (e->pos < e->start) { 180 - if (!__i915_error_seek(e, len)) 181 - return; 182 - } 183 - 184 - if (len >= e->size - e->bytes) 185 - len = e->size - e->bytes - 1; 181 + GEM_BUG_ON(e->bytes + len > e->size); 186 182 memcpy(e->buf + e->bytes, str, len); 187 - 188 - __i915_error_advance(e, len); 183 + e->bytes += len; 189 184 } 190 185 191 186 #define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__) ··· 269 268 270 269 if (zlib_deflate(zstream, Z_NO_FLUSH) != Z_OK) 271 270 return -EIO; 271 + 272 + touch_nmi_watchdog(); 272 273 } while (zstream->avail_in); 273 274 274 275 /* Fallback to uncompressed if we increase size? */ ··· 638 635 print_error_obj(m, NULL, "GuC log buffer", error_uc->guc_log); 639 636 } 640 637 641 - int i915_error_state_to_str(struct drm_i915_error_state_buf *m, 642 - const struct i915_gpu_state *error) 638 + static void err_free_sgl(struct scatterlist *sgl) 643 639 { 644 - struct drm_i915_private *dev_priv = m->i915; 640 + while (sgl) { 641 + struct scatterlist *sg; 642 + 643 + for (sg = sgl; !sg_is_chain(sg); sg++) { 644 + kfree(sg_virt(sg)); 645 + if (sg_is_last(sg)) 646 + break; 647 + } 648 + 649 + sg = sg_is_last(sg) ? NULL : sg_chain_ptr(sg); 650 + free_page((unsigned long)sgl); 651 + sgl = sg; 652 + } 653 + } 654 + 655 + static void __err_print_to_sgl(struct drm_i915_error_state_buf *m, 656 + struct i915_gpu_state *error) 657 + { 645 658 struct drm_i915_error_object *obj; 646 659 struct timespec64 ts; 647 660 int i, j; 648 - 649 - if (!error) { 650 - err_printf(m, "No error state collected\n"); 651 - return 0; 652 - } 653 - 654 - if (IS_ERR(error)) 655 - return PTR_ERR(error); 656 661 657 662 if (*error->error_msg) 658 663 err_printf(m, "%s\n", error->error_msg); ··· 694 683 err_printf(m, "Reset count: %u\n", error->reset_count); 695 684 err_printf(m, "Suspend count: %u\n", error->suspend_count); 696 685 err_printf(m, "Platform: %s\n", intel_platform_name(error->device_info.platform)); 697 - err_print_pciid(m, error->i915); 686 + err_print_pciid(m, m->i915); 698 687 699 688 err_printf(m, "IOMMU enabled?: %d\n", error->iommu); 700 689 701 - if (HAS_CSR(dev_priv)) { 702 - struct intel_csr *csr = &dev_priv->csr; 690 + if (HAS_CSR(m->i915)) { 691 + struct intel_csr *csr = &m->i915->csr; 703 692 704 693 err_printf(m, "DMC loaded: %s\n", 705 694 yesno(csr->dmc_payload != NULL)); ··· 719 708 err_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake); 720 709 err_printf(m, "DERRMR: 0x%08x\n", error->derrmr); 721 710 err_printf(m, "CCID: 0x%08x\n", error->ccid); 722 - err_printf(m, "Missed interrupts: 0x%08lx\n", dev_priv->gpu_error.missed_irq_rings); 711 + err_printf(m, "Missed interrupts: 0x%08lx\n", 712 + m->i915->gpu_error.missed_irq_rings); 723 713 724 714 for (i = 0; i < error->nfence; i++) 725 715 err_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); 726 716 727 - if (INTEL_GEN(dev_priv) >= 6) { 717 + if (INTEL_GEN(m->i915) >= 6) { 728 718 err_printf(m, "ERROR: 0x%08x\n", error->error); 729 719 730 - if (INTEL_GEN(dev_priv) >= 8) 720 + if (INTEL_GEN(m->i915) >= 8) 731 721 err_printf(m, "FAULT_TLB_DATA: 0x%08x 0x%08x\n", 732 722 error->fault_data1, error->fault_data0); 733 723 734 724 err_printf(m, "DONE_REG: 0x%08x\n", error->done_reg); 735 725 } 736 726 737 - if (IS_GEN7(dev_priv)) 727 + if (IS_GEN7(m->i915)) 738 728 err_printf(m, "ERR_INT: 0x%08x\n", error->err_int); 739 729 740 730 for (i = 0; i < ARRAY_SIZE(error->engine); i++) { ··· 757 745 758 746 len += scnprintf(buf + len, sizeof(buf), "%s%s", 759 747 first ? "" : ", ", 760 - dev_priv->engine[j]->name); 748 + m->i915->engine[j]->name); 761 749 first = 0; 762 750 } 763 751 scnprintf(buf + len, sizeof(buf), ")"); ··· 775 763 776 764 obj = ee->batchbuffer; 777 765 if (obj) { 778 - err_puts(m, dev_priv->engine[i]->name); 766 + err_puts(m, m->i915->engine[i]->name); 779 767 if (ee->context.pid) 780 768 err_printf(m, " (submitted by %s [%d], ctx %d [%d], score %d%s)", 781 769 ee->context.comm, ··· 787 775 err_printf(m, " --- gtt_offset = 0x%08x %08x\n", 788 776 upper_32_bits(obj->gtt_offset), 789 777 lower_32_bits(obj->gtt_offset)); 790 - print_error_obj(m, dev_priv->engine[i], NULL, obj); 778 + print_error_obj(m, m->i915->engine[i], NULL, obj); 791 779 } 792 780 793 781 for (j = 0; j < ee->user_bo_count; j++) 794 - print_error_obj(m, dev_priv->engine[i], 782 + print_error_obj(m, m->i915->engine[i], 795 783 "user", ee->user_bo[j]); 796 784 797 785 if (ee->num_requests) { 798 786 err_printf(m, "%s --- %d requests\n", 799 - dev_priv->engine[i]->name, 787 + m->i915->engine[i]->name, 800 788 ee->num_requests); 801 789 for (j = 0; j < ee->num_requests; j++) 802 790 error_print_request(m, " ", ··· 806 794 807 795 if (IS_ERR(ee->waiters)) { 808 796 err_printf(m, "%s --- ? waiters [unable to acquire spinlock]\n", 809 - dev_priv->engine[i]->name); 797 + m->i915->engine[i]->name); 810 798 } else if (ee->num_waiters) { 811 799 err_printf(m, "%s --- %d waiters\n", 812 - dev_priv->engine[i]->name, 800 + m->i915->engine[i]->name, 813 801 ee->num_waiters); 814 802 for (j = 0; j < ee->num_waiters; j++) { 815 803 err_printf(m, " seqno 0x%08x for %s [%d]\n", ··· 819 807 } 820 808 } 821 809 822 - print_error_obj(m, dev_priv->engine[i], 810 + print_error_obj(m, m->i915->engine[i], 823 811 "ringbuffer", ee->ringbuffer); 824 812 825 - print_error_obj(m, dev_priv->engine[i], 813 + print_error_obj(m, m->i915->engine[i], 826 814 "HW Status", ee->hws_page); 827 815 828 - print_error_obj(m, dev_priv->engine[i], 816 + print_error_obj(m, m->i915->engine[i], 829 817 "HW context", ee->ctx); 830 818 831 - print_error_obj(m, dev_priv->engine[i], 819 + print_error_obj(m, m->i915->engine[i], 832 820 "WA context", ee->wa_ctx); 833 821 834 - print_error_obj(m, dev_priv->engine[i], 822 + print_error_obj(m, m->i915->engine[i], 835 823 "WA batchbuffer", ee->wa_batchbuffer); 836 824 837 - print_error_obj(m, dev_priv->engine[i], 825 + print_error_obj(m, m->i915->engine[i], 838 826 "NULL context", ee->default_state); 839 827 } 840 828 ··· 847 835 err_print_capabilities(m, &error->device_info, &error->driver_caps); 848 836 err_print_params(m, &error->params); 849 837 err_print_uc(m, &error->uc); 838 + } 850 839 851 - if (m->bytes == 0 && m->err) 852 - return m->err; 840 + static int err_print_to_sgl(struct i915_gpu_state *error) 841 + { 842 + struct drm_i915_error_state_buf m; 843 + 844 + if (IS_ERR(error)) 845 + return PTR_ERR(error); 846 + 847 + if (READ_ONCE(error->sgl)) 848 + return 0; 849 + 850 + memset(&m, 0, sizeof(m)); 851 + m.i915 = error->i915; 852 + 853 + __err_print_to_sgl(&m, error); 854 + 855 + if (m.buf) { 856 + __sg_set_buf(m.cur++, m.buf, m.bytes, m.iter); 857 + m.bytes = 0; 858 + m.buf = NULL; 859 + } 860 + if (m.cur) { 861 + GEM_BUG_ON(m.end < m.cur); 862 + sg_mark_end(m.cur - 1); 863 + } 864 + GEM_BUG_ON(m.sgl && !m.cur); 865 + 866 + if (m.err) { 867 + err_free_sgl(m.sgl); 868 + return m.err; 869 + } 870 + 871 + if (cmpxchg(&error->sgl, NULL, m.sgl)) 872 + err_free_sgl(m.sgl); 853 873 854 874 return 0; 855 875 } 856 876 857 - int i915_error_state_buf_init(struct drm_i915_error_state_buf *ebuf, 858 - struct drm_i915_private *i915, 859 - size_t count, loff_t pos) 877 + ssize_t i915_gpu_state_copy_to_buffer(struct i915_gpu_state *error, 878 + char *buf, loff_t off, size_t rem) 860 879 { 861 - memset(ebuf, 0, sizeof(*ebuf)); 862 - ebuf->i915 = i915; 880 + struct scatterlist *sg; 881 + size_t count; 882 + loff_t pos; 883 + int err; 863 884 864 - /* We need to have enough room to store any i915_error_state printf 865 - * so that we can move it to start position. 866 - */ 867 - ebuf->size = count + 1 > PAGE_SIZE ? count + 1 : PAGE_SIZE; 868 - ebuf->buf = kmalloc(ebuf->size, 869 - GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN); 885 + if (!error || !rem) 886 + return 0; 870 887 871 - if (ebuf->buf == NULL) { 872 - ebuf->size = PAGE_SIZE; 873 - ebuf->buf = kmalloc(ebuf->size, GFP_KERNEL); 874 - } 888 + err = err_print_to_sgl(error); 889 + if (err) 890 + return err; 875 891 876 - if (ebuf->buf == NULL) { 877 - ebuf->size = 128; 878 - ebuf->buf = kmalloc(ebuf->size, GFP_KERNEL); 879 - } 892 + sg = READ_ONCE(error->fit); 893 + if (!sg || off < sg->dma_address) 894 + sg = error->sgl; 895 + if (!sg) 896 + return 0; 880 897 881 - if (ebuf->buf == NULL) 882 - return -ENOMEM; 898 + pos = sg->dma_address; 899 + count = 0; 900 + do { 901 + size_t len, start; 883 902 884 - ebuf->start = pos; 903 + if (sg_is_chain(sg)) { 904 + sg = sg_chain_ptr(sg); 905 + GEM_BUG_ON(sg_is_chain(sg)); 906 + } 885 907 886 - return 0; 908 + len = sg->length; 909 + if (pos + len <= off) { 910 + pos += len; 911 + continue; 912 + } 913 + 914 + start = sg->offset; 915 + if (pos < off) { 916 + GEM_BUG_ON(off - pos > len); 917 + len -= off - pos; 918 + start += off - pos; 919 + pos = off; 920 + } 921 + 922 + len = min(len, rem); 923 + GEM_BUG_ON(!len || len > sg->length); 924 + 925 + memcpy(buf, page_address(sg_page(sg)) + start, len); 926 + 927 + count += len; 928 + pos += len; 929 + 930 + buf += len; 931 + rem -= len; 932 + if (!rem) { 933 + WRITE_ONCE(error->fit, sg); 934 + break; 935 + } 936 + } while (!sg_is_last(sg++)); 937 + 938 + return count; 887 939 } 888 940 889 941 static void i915_error_object_free(struct drm_i915_error_object *obj) ··· 1020 944 cleanup_params(error); 1021 945 cleanup_uc_state(error); 1022 946 947 + err_free_sgl(error->sgl); 1023 948 kfree(error); 1024 949 } 1025 950 ··· 1571 1494 if (HAS_BROKEN_CS_TLB(i915)) 1572 1495 ee->wa_batchbuffer = 1573 1496 i915_error_object_create(i915, 1574 - engine->scratch); 1497 + i915->gt.scratch); 1575 1498 request_record_user_bo(request, ee); 1576 1499 1577 1500 ee->ctx =
+12 -16
drivers/gpu/drm/i915/i915_gpu_error.h
··· 192 192 } *active_bo[I915_NUM_ENGINES], *pinned_bo; 193 193 u32 active_bo_count[I915_NUM_ENGINES], pinned_bo_count; 194 194 struct i915_address_space *active_vm[I915_NUM_ENGINES]; 195 + 196 + struct scatterlist *sgl, *fit; 195 197 }; 196 198 197 199 struct i915_gpu_error { ··· 300 298 301 299 struct drm_i915_error_state_buf { 302 300 struct drm_i915_private *i915; 303 - unsigned int bytes; 304 - unsigned int size; 301 + struct scatterlist *sgl, *cur, *end; 302 + 303 + char *buf; 304 + size_t bytes; 305 + size_t size; 306 + loff_t iter; 307 + 305 308 int err; 306 - u8 *buf; 307 - loff_t start; 308 - loff_t pos; 309 309 }; 310 310 311 311 #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) 312 312 313 313 __printf(2, 3) 314 314 void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...); 315 - int i915_error_state_to_str(struct drm_i915_error_state_buf *estr, 316 - const struct i915_gpu_state *gpu); 317 - int i915_error_state_buf_init(struct drm_i915_error_state_buf *eb, 318 - struct drm_i915_private *i915, 319 - size_t count, loff_t pos); 320 - 321 - static inline void 322 - i915_error_state_buf_release(struct drm_i915_error_state_buf *eb) 323 - { 324 - kfree(eb->buf); 325 - } 326 315 327 316 struct i915_gpu_state *i915_capture_gpu_state(struct drm_i915_private *i915); 328 317 void i915_capture_error_state(struct drm_i915_private *dev_priv, ··· 326 333 kref_get(&gpu->ref); 327 334 return gpu; 328 335 } 336 + 337 + ssize_t i915_gpu_state_copy_to_buffer(struct i915_gpu_state *error, 338 + char *buf, loff_t offset, size_t count); 329 339 330 340 void __i915_gpu_state_free(struct kref *kref); 331 341 static inline void i915_gpu_state_put(struct i915_gpu_state *gpu)
+64 -53
drivers/gpu/drm/i915/i915_pci.c
··· 79 79 #define GEN2_FEATURES \ 80 80 GEN(2), \ 81 81 .num_pipes = 1, \ 82 - .has_overlay = 1, .overlay_needs_physical = 1, \ 83 - .has_gmch_display = 1, \ 82 + .display.has_overlay = 1, \ 83 + .display.overlay_needs_physical = 1, \ 84 + .display.has_gmch_display = 1, \ 84 85 .hws_needs_physical = 1, \ 85 86 .unfenced_needs_alignment = 1, \ 86 87 .ring_mask = RENDER_RING, \ ··· 94 93 static const struct intel_device_info intel_i830_info = { 95 94 GEN2_FEATURES, 96 95 PLATFORM(INTEL_I830), 97 - .is_mobile = 1, .cursor_needs_physical = 1, 96 + .is_mobile = 1, 97 + .display.cursor_needs_physical = 1, 98 98 .num_pipes = 2, /* legal, last one wins */ 99 99 }; 100 100 ··· 109 107 PLATFORM(INTEL_I85X), 110 108 .is_mobile = 1, 111 109 .num_pipes = 2, /* legal, last one wins */ 112 - .cursor_needs_physical = 1, 113 - .has_fbc = 1, 110 + .display.cursor_needs_physical = 1, 111 + .display.has_fbc = 1, 114 112 }; 115 113 116 114 static const struct intel_device_info intel_i865g_info = { ··· 121 119 #define GEN3_FEATURES \ 122 120 GEN(3), \ 123 121 .num_pipes = 2, \ 124 - .has_gmch_display = 1, \ 122 + .display.has_gmch_display = 1, \ 125 123 .ring_mask = RENDER_RING, \ 126 124 .has_snoop = true, \ 127 125 .has_coherent_ggtt = true, \ ··· 133 131 GEN3_FEATURES, 134 132 PLATFORM(INTEL_I915G), 135 133 .has_coherent_ggtt = false, 136 - .cursor_needs_physical = 1, 137 - .has_overlay = 1, .overlay_needs_physical = 1, 134 + .display.cursor_needs_physical = 1, 135 + .display.has_overlay = 1, 136 + .display.overlay_needs_physical = 1, 138 137 .hws_needs_physical = 1, 139 138 .unfenced_needs_alignment = 1, 140 139 }; ··· 144 141 GEN3_FEATURES, 145 142 PLATFORM(INTEL_I915GM), 146 143 .is_mobile = 1, 147 - .cursor_needs_physical = 1, 148 - .has_overlay = 1, .overlay_needs_physical = 1, 149 - .supports_tv = 1, 150 - .has_fbc = 1, 144 + .display.cursor_needs_physical = 1, 145 + .display.has_overlay = 1, 146 + .display.overlay_needs_physical = 1, 147 + .display.supports_tv = 1, 148 + .display.has_fbc = 1, 151 149 .hws_needs_physical = 1, 152 150 .unfenced_needs_alignment = 1, 153 151 }; ··· 156 152 static const struct intel_device_info intel_i945g_info = { 157 153 GEN3_FEATURES, 158 154 PLATFORM(INTEL_I945G), 159 - .has_hotplug = 1, .cursor_needs_physical = 1, 160 - .has_overlay = 1, .overlay_needs_physical = 1, 155 + .display.has_hotplug = 1, 156 + .display.cursor_needs_physical = 1, 157 + .display.has_overlay = 1, 158 + .display.overlay_needs_physical = 1, 161 159 .hws_needs_physical = 1, 162 160 .unfenced_needs_alignment = 1, 163 161 }; ··· 168 162 GEN3_FEATURES, 169 163 PLATFORM(INTEL_I945GM), 170 164 .is_mobile = 1, 171 - .has_hotplug = 1, .cursor_needs_physical = 1, 172 - .has_overlay = 1, .overlay_needs_physical = 1, 173 - .supports_tv = 1, 174 - .has_fbc = 1, 165 + .display.has_hotplug = 1, 166 + .display.cursor_needs_physical = 1, 167 + .display.has_overlay = 1, 168 + .display.overlay_needs_physical = 1, 169 + .display.supports_tv = 1, 170 + .display.has_fbc = 1, 175 171 .hws_needs_physical = 1, 176 172 .unfenced_needs_alignment = 1, 177 173 }; ··· 181 173 static const struct intel_device_info intel_g33_info = { 182 174 GEN3_FEATURES, 183 175 PLATFORM(INTEL_G33), 184 - .has_hotplug = 1, 185 - .has_overlay = 1, 176 + .display.has_hotplug = 1, 177 + .display.has_overlay = 1, 186 178 }; 187 179 188 180 static const struct intel_device_info intel_pineview_info = { 189 181 GEN3_FEATURES, 190 182 PLATFORM(INTEL_PINEVIEW), 191 183 .is_mobile = 1, 192 - .has_hotplug = 1, 193 - .has_overlay = 1, 184 + .display.has_hotplug = 1, 185 + .display.has_overlay = 1, 194 186 }; 195 187 196 188 #define GEN4_FEATURES \ 197 189 GEN(4), \ 198 190 .num_pipes = 2, \ 199 - .has_hotplug = 1, \ 200 - .has_gmch_display = 1, \ 191 + .display.has_hotplug = 1, \ 192 + .display.has_gmch_display = 1, \ 201 193 .ring_mask = RENDER_RING, \ 202 194 .has_snoop = true, \ 203 195 .has_coherent_ggtt = true, \ ··· 208 200 static const struct intel_device_info intel_i965g_info = { 209 201 GEN4_FEATURES, 210 202 PLATFORM(INTEL_I965G), 211 - .has_overlay = 1, 203 + .display.has_overlay = 1, 212 204 .hws_needs_physical = 1, 213 205 .has_snoop = false, 214 206 }; ··· 216 208 static const struct intel_device_info intel_i965gm_info = { 217 209 GEN4_FEATURES, 218 210 PLATFORM(INTEL_I965GM), 219 - .is_mobile = 1, .has_fbc = 1, 220 - .has_overlay = 1, 221 - .supports_tv = 1, 211 + .is_mobile = 1, 212 + .display.has_fbc = 1, 213 + .display.has_overlay = 1, 214 + .display.supports_tv = 1, 222 215 .hws_needs_physical = 1, 223 216 .has_snoop = false, 224 217 }; ··· 233 224 static const struct intel_device_info intel_gm45_info = { 234 225 GEN4_FEATURES, 235 226 PLATFORM(INTEL_GM45), 236 - .is_mobile = 1, .has_fbc = 1, 237 - .supports_tv = 1, 227 + .is_mobile = 1, 228 + .display.has_fbc = 1, 229 + .display.supports_tv = 1, 238 230 .ring_mask = RENDER_RING | BSD_RING, 239 231 }; 240 232 241 233 #define GEN5_FEATURES \ 242 234 GEN(5), \ 243 235 .num_pipes = 2, \ 244 - .has_hotplug = 1, \ 236 + .display.has_hotplug = 1, \ 245 237 .ring_mask = RENDER_RING | BSD_RING, \ 246 238 .has_snoop = true, \ 247 239 .has_coherent_ggtt = true, \ ··· 260 250 static const struct intel_device_info intel_ironlake_m_info = { 261 251 GEN5_FEATURES, 262 252 PLATFORM(INTEL_IRONLAKE), 263 - .is_mobile = 1, .has_fbc = 1, 253 + .is_mobile = 1, 254 + .display.has_fbc = 1, 264 255 }; 265 256 266 257 #define GEN6_FEATURES \ 267 258 GEN(6), \ 268 259 .num_pipes = 2, \ 269 - .has_hotplug = 1, \ 270 - .has_fbc = 1, \ 260 + .display.has_hotplug = 1, \ 261 + .display.has_fbc = 1, \ 271 262 .ring_mask = RENDER_RING | BSD_RING | BLT_RING, \ 272 263 .has_coherent_ggtt = true, \ 273 264 .has_llc = 1, \ ··· 312 301 #define GEN7_FEATURES \ 313 302 GEN(7), \ 314 303 .num_pipes = 3, \ 315 - .has_hotplug = 1, \ 316 - .has_fbc = 1, \ 304 + .display.has_hotplug = 1, \ 305 + .display.has_fbc = 1, \ 317 306 .ring_mask = RENDER_RING | BSD_RING | BLT_RING, \ 318 307 .has_coherent_ggtt = true, \ 319 308 .has_llc = 1, \ ··· 370 359 .num_pipes = 2, 371 360 .has_runtime_pm = 1, 372 361 .has_rc6 = 1, 373 - .has_gmch_display = 1, 374 - .has_hotplug = 1, 362 + .display.has_gmch_display = 1, 363 + .display.has_hotplug = 1, 375 364 .ppgtt = INTEL_PPGTT_FULL, 376 365 .has_snoop = true, 377 366 .has_coherent_ggtt = false, ··· 385 374 #define G75_FEATURES \ 386 375 GEN7_FEATURES, \ 387 376 .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, \ 388 - .has_ddi = 1, \ 377 + .display.has_ddi = 1, \ 389 378 .has_fpga_dbg = 1, \ 390 - .has_psr = 1, \ 391 - .has_dp_mst = 1, \ 379 + .display.has_psr = 1, \ 380 + .display.has_dp_mst = 1, \ 392 381 .has_rc6p = 0 /* RC6p removed-by HSW */, \ 393 382 .has_runtime_pm = 1 394 383 ··· 455 444 PLATFORM(INTEL_CHERRYVIEW), 456 445 GEN(8), 457 446 .num_pipes = 3, 458 - .has_hotplug = 1, 447 + .display.has_hotplug = 1, 459 448 .is_lp = 1, 460 449 .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, 461 450 .has_64bit_reloc = 1, 462 451 .has_runtime_pm = 1, 463 452 .has_rc6 = 1, 464 453 .has_logical_ring_contexts = 1, 465 - .has_gmch_display = 1, 454 + .display.has_gmch_display = 1, 466 455 .ppgtt = INTEL_PPGTT_FULL, 467 456 .has_reset_engine = 1, 468 457 .has_snoop = true, ··· 484 473 GEN(9), \ 485 474 GEN9_DEFAULT_PAGE_SIZES, \ 486 475 .has_logical_ring_preemption = 1, \ 487 - .has_csr = 1, \ 476 + .display.has_csr = 1, \ 488 477 .has_guc = 1, \ 489 - .has_ipc = 1, \ 478 + .display.has_ipc = 1, \ 490 479 .ddb_size = 896 491 480 492 481 #define SKL_PLATFORM \ 493 482 GEN9_FEATURES, \ 494 483 /* Display WA #0477 WaDisableIPC: skl */ \ 495 - .has_ipc = 0, \ 484 + .display.has_ipc = 0, \ 496 485 PLATFORM(INTEL_SKYLAKE) 497 486 498 487 static const struct intel_device_info intel_skylake_gt1_info = { ··· 523 512 #define GEN9_LP_FEATURES \ 524 513 GEN(9), \ 525 514 .is_lp = 1, \ 526 - .has_hotplug = 1, \ 515 + .display.has_hotplug = 1, \ 527 516 .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, \ 528 517 .num_pipes = 3, \ 529 518 .has_64bit_reloc = 1, \ 530 - .has_ddi = 1, \ 519 + .display.has_ddi = 1, \ 531 520 .has_fpga_dbg = 1, \ 532 - .has_fbc = 1, \ 533 - .has_psr = 1, \ 521 + .display.has_fbc = 1, \ 522 + .display.has_psr = 1, \ 534 523 .has_runtime_pm = 1, \ 535 524 .has_pooled_eu = 0, \ 536 - .has_csr = 1, \ 525 + .display.has_csr = 1, \ 537 526 .has_rc6 = 1, \ 538 - .has_dp_mst = 1, \ 527 + .display.has_dp_mst = 1, \ 539 528 .has_logical_ring_contexts = 1, \ 540 529 .has_logical_ring_preemption = 1, \ 541 530 .has_guc = 1, \ ··· 543 532 .has_reset_engine = 1, \ 544 533 .has_snoop = true, \ 545 534 .has_coherent_ggtt = false, \ 546 - .has_ipc = 1, \ 535 + .display.has_ipc = 1, \ 547 536 GEN9_DEFAULT_PAGE_SIZES, \ 548 537 GEN_DEFAULT_PIPEOFFSETS, \ 549 538 IVB_CURSOR_OFFSETS, \
+15
drivers/gpu/drm/i915/i915_reg.h
··· 4570 4570 * of the infoframe structure specified by CEA-861. */ 4571 4571 #define VIDEO_DIP_DATA_SIZE 32 4572 4572 #define VIDEO_DIP_VSC_DATA_SIZE 36 4573 + #define VIDEO_DIP_PPS_DATA_SIZE 132 4573 4574 #define VIDEO_DIP_CTL _MMIO(0x61170) 4574 4575 /* Pre HSW: */ 4575 4576 #define VIDEO_DIP_ENABLE (1 << 31) ··· 4618 4617 #define _PP_STATUS 0x61200 4619 4618 #define PP_STATUS(pps_idx) _MMIO_PPS(pps_idx, _PP_STATUS) 4620 4619 #define PP_ON (1 << 31) 4620 + 4621 + #define _PP_CONTROL_1 0xc7204 4622 + #define _PP_CONTROL_2 0xc7304 4623 + #define ICP_PP_CONTROL(x) _MMIO(((x) == 1) ? _PP_CONTROL_1 : \ 4624 + _PP_CONTROL_2) 4625 + #define POWER_CYCLE_DELAY_MASK (0x1f << 4) 4626 + #define POWER_CYCLE_DELAY_SHIFT 4 4627 + #define VDD_OVERRIDE_FORCE (1 << 3) 4628 + #define BACKLIGHT_ENABLE (1 << 2) 4629 + #define PWR_DOWN_ON_RESET (1 << 1) 4630 + #define PWR_STATE_TARGET (1 << 0) 4621 4631 /* 4622 4632 * Indicates that all dependencies of the panel are on: 4623 4633 * ··· 7762 7750 #define ICP_DDIB_HPD_LONG_DETECT (2 << 4) 7763 7751 #define ICP_DDIB_HPD_SHORT_LONG_DETECT (3 << 4) 7764 7752 #define ICP_DDIA_HPD_ENABLE (1 << 3) 7753 + #define ICP_DDIA_HPD_OP_DRIVE_1 (1 << 2) 7765 7754 #define ICP_DDIA_HPD_STATUS_MASK (3 << 0) 7766 7755 #define ICP_DDIA_HPD_NO_DETECT (0 << 0) 7767 7756 #define ICP_DDIA_HPD_SHORT_DETECT (1 << 0) ··· 9210 9197 #define _DP_TP_CTL_B 0x64140 9211 9198 #define DP_TP_CTL(port) _MMIO_PORT(port, _DP_TP_CTL_A, _DP_TP_CTL_B) 9212 9199 #define DP_TP_CTL_ENABLE (1 << 31) 9200 + #define DP_TP_CTL_FEC_ENABLE (1 << 30) 9213 9201 #define DP_TP_CTL_MODE_SST (0 << 27) 9214 9202 #define DP_TP_CTL_MODE_MST (1 << 27) 9215 9203 #define DP_TP_CTL_FORCE_ACT (1 << 25) ··· 9229 9215 #define _DP_TP_STATUS_A 0x64044 9230 9216 #define _DP_TP_STATUS_B 0x64144 9231 9217 #define DP_TP_STATUS(port) _MMIO_PORT(port, _DP_TP_STATUS_A, _DP_TP_STATUS_B) 9218 + #define DP_TP_STATUS_FEC_ENABLE_LIVE (1 << 28) 9232 9219 #define DP_TP_STATUS_IDLE_DONE (1 << 25) 9233 9220 #define DP_TP_STATUS_ACT_SENT (1 << 24) 9234 9221 #define DP_TP_STATUS_MODE_STATUS_MST (1 << 23)
+3
drivers/gpu/drm/i915/i915_request.c
··· 136 136 intel_engine_get_seqno(engine), 137 137 seqno); 138 138 139 + if (seqno == engine->timeline.seqno) 140 + continue; 141 + 139 142 kthread_park(engine->breadcrumbs.signaler); 140 143 141 144 if (!i915_seqno_passed(seqno, engine->timeline.seqno)) {
+2 -5
drivers/gpu/drm/i915/i915_sw_fence.c
··· 1 1 /* 2 - * (C) Copyright 2016 Intel Corporation 2 + * SPDX-License-Identifier: MIT 3 3 * 4 - * This program is free software; you can redistribute it and/or 5 - * modify it under the terms of the GNU General Public License 6 - * as published by the Free Software Foundation; version 2 7 - * of the License. 4 + * (C) Copyright 2016 Intel Corporation 8 5 */ 9 6 10 7 #include <linux/slab.h>
+2 -3
drivers/gpu/drm/i915/i915_sw_fence.h
··· 1 1 /* 2 + * SPDX-License-Identifier: MIT 3 + * 2 4 * i915_sw_fence.h - library routines for N:M synchronisation points 3 5 * 4 6 * Copyright (C) 2016 Intel Corporation 5 - * 6 - * This file is released under the GPLv2. 7 - * 8 7 */ 9 8 10 9 #ifndef _I915_SW_FENCE_H_
+13 -18
drivers/gpu/drm/i915/i915_sysfs.c
··· 483 483 return snprintf(buf, PAGE_SIZE, "%d\n", val); 484 484 } 485 485 486 - static const struct attribute *gen6_attrs[] = { 486 + static const struct attribute * const gen6_attrs[] = { 487 487 &dev_attr_gt_act_freq_mhz.attr, 488 488 &dev_attr_gt_cur_freq_mhz.attr, 489 489 &dev_attr_gt_boost_freq_mhz.attr, ··· 495 495 NULL, 496 496 }; 497 497 498 - static const struct attribute *vlv_attrs[] = { 498 + static const struct attribute * const vlv_attrs[] = { 499 499 &dev_attr_gt_act_freq_mhz.attr, 500 500 &dev_attr_gt_cur_freq_mhz.attr, 501 501 &dev_attr_gt_boost_freq_mhz.attr, ··· 516 516 { 517 517 518 518 struct device *kdev = kobj_to_dev(kobj); 519 - struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); 520 - struct drm_i915_error_state_buf error_str; 519 + struct drm_i915_private *i915 = kdev_minor_to_i915(kdev); 521 520 struct i915_gpu_state *gpu; 522 521 ssize_t ret; 523 522 524 - ret = i915_error_state_buf_init(&error_str, dev_priv, count, off); 525 - if (ret) 526 - return ret; 523 + gpu = i915_first_error_state(i915); 524 + if (gpu) { 525 + ret = i915_gpu_state_copy_to_buffer(gpu, buf, off, count); 526 + i915_gpu_state_put(gpu); 527 + } else { 528 + const char *str = "No error state collected\n"; 529 + size_t len = strlen(str); 527 530 528 - gpu = i915_first_error_state(dev_priv); 529 - ret = i915_error_state_to_str(&error_str, gpu); 530 - if (ret) 531 - goto out; 532 - 533 - ret = count < error_str.bytes ? count : error_str.bytes; 534 - memcpy(buf, error_str.buf, ret); 535 - 536 - out: 537 - i915_gpu_state_put(gpu); 538 - i915_error_state_buf_release(&error_str); 531 + ret = min_t(size_t, count, len - off); 532 + memcpy(buf, str + off, ret); 533 + } 539 534 540 535 return ret; 541 536 }
+7 -4
drivers/gpu/drm/i915/i915_utils.h
··· 44 44 __stringify(x), (long)(x)) 45 45 46 46 #if defined(GCC_VERSION) && GCC_VERSION >= 70000 47 - #define add_overflows(A, B) \ 48 - __builtin_add_overflow_p((A), (B), (typeof((A) + (B)))0) 47 + #define add_overflows_t(T, A, B) \ 48 + __builtin_add_overflow_p((A), (B), (T)0) 49 49 #else 50 - #define add_overflows(A, B) ({ \ 50 + #define add_overflows_t(T, A, B) ({ \ 51 51 typeof(A) a = (A); \ 52 52 typeof(B) b = (B); \ 53 - a + b < a; \ 53 + (T)(a + b) < a; \ 54 54 }) 55 55 #endif 56 + 57 + #define add_overflows(A, B) \ 58 + add_overflows_t(typeof((A) + (B)), (A), (B)) 56 59 57 60 #define range_overflows(start, size, max) ({ \ 58 61 typeof(start) start__ = (start); \
+482 -11
drivers/gpu/drm/i915/icl_dsi.c
··· 26 26 */ 27 27 28 28 #include <drm/drm_mipi_dsi.h> 29 + #include <drm/drm_atomic_helper.h> 29 30 #include "intel_dsi.h" 30 31 31 32 static inline int header_credits_available(struct drm_i915_private *dev_priv, ··· 108 107 } 109 108 } 110 109 110 + static bool add_payld_to_queue(struct intel_dsi_host *host, const u8 *data, 111 + u32 len) 112 + { 113 + struct intel_dsi *intel_dsi = host->intel_dsi; 114 + struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); 115 + enum transcoder dsi_trans = dsi_port_to_transcoder(host->port); 116 + int free_credits; 117 + int i, j; 118 + 119 + for (i = 0; i < len; i += 4) { 120 + u32 tmp = 0; 121 + 122 + free_credits = payload_credits_available(dev_priv, dsi_trans); 123 + if (free_credits < 1) { 124 + DRM_ERROR("Payload credit not available\n"); 125 + return false; 126 + } 127 + 128 + for (j = 0; j < min_t(u32, len - i, 4); j++) 129 + tmp |= *data++ << 8 * j; 130 + 131 + I915_WRITE(DSI_CMD_TXPYLD(dsi_trans), tmp); 132 + } 133 + 134 + return true; 135 + } 136 + 137 + static int dsi_send_pkt_hdr(struct intel_dsi_host *host, 138 + struct mipi_dsi_packet pkt, bool enable_lpdt) 139 + { 140 + struct intel_dsi *intel_dsi = host->intel_dsi; 141 + struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); 142 + enum transcoder dsi_trans = dsi_port_to_transcoder(host->port); 143 + u32 tmp; 144 + int free_credits; 145 + 146 + /* check if header credit available */ 147 + free_credits = header_credits_available(dev_priv, dsi_trans); 148 + if (free_credits < 1) { 149 + DRM_ERROR("send pkt header failed, not enough hdr credits\n"); 150 + return -1; 151 + } 152 + 153 + tmp = I915_READ(DSI_CMD_TXHDR(dsi_trans)); 154 + 155 + if (pkt.payload) 156 + tmp |= PAYLOAD_PRESENT; 157 + else 158 + tmp &= ~PAYLOAD_PRESENT; 159 + 160 + tmp &= ~VBLANK_FENCE; 161 + 162 + if (enable_lpdt) 163 + tmp |= LP_DATA_TRANSFER; 164 + 165 + tmp &= ~(PARAM_WC_MASK | VC_MASK | DT_MASK); 166 + tmp |= ((pkt.header[0] & VC_MASK) << VC_SHIFT); 167 + tmp |= ((pkt.header[0] & DT_MASK) << DT_SHIFT); 168 + tmp |= (pkt.header[1] << PARAM_WC_LOWER_SHIFT); 169 + tmp |= (pkt.header[2] << PARAM_WC_UPPER_SHIFT); 170 + I915_WRITE(DSI_CMD_TXHDR(dsi_trans), tmp); 171 + 172 + return 0; 173 + } 174 + 175 + static int dsi_send_pkt_payld(struct intel_dsi_host *host, 176 + struct mipi_dsi_packet pkt) 177 + { 178 + /* payload queue can accept *256 bytes*, check limit */ 179 + if (pkt.payload_length > MAX_PLOAD_CREDIT * 4) { 180 + DRM_ERROR("payload size exceeds max queue limit\n"); 181 + return -1; 182 + } 183 + 184 + /* load data into command payload queue */ 185 + if (!add_payld_to_queue(host, pkt.payload, 186 + pkt.payload_length)) { 187 + DRM_ERROR("adding payload to queue failed\n"); 188 + return -1; 189 + } 190 + 191 + return 0; 192 + } 193 + 111 194 static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder) 112 195 { 113 196 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); ··· 255 170 I915_WRITE(ICL_PORT_TX_DW4_LN(port, lane), tmp); 256 171 } 257 172 } 173 + } 174 + 175 + static void configure_dual_link_mode(struct intel_encoder *encoder, 176 + const struct intel_crtc_state *pipe_config) 177 + { 178 + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 179 + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); 180 + u32 dss_ctl1; 181 + 182 + dss_ctl1 = I915_READ(DSS_CTL1); 183 + dss_ctl1 |= SPLITTER_ENABLE; 184 + dss_ctl1 &= ~OVERLAP_PIXELS_MASK; 185 + dss_ctl1 |= OVERLAP_PIXELS(intel_dsi->pixel_overlap); 186 + 187 + if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) { 188 + const struct drm_display_mode *adjusted_mode = 189 + &pipe_config->base.adjusted_mode; 190 + u32 dss_ctl2; 191 + u16 hactive = adjusted_mode->crtc_hdisplay; 192 + u16 dl_buffer_depth; 193 + 194 + dss_ctl1 &= ~DUAL_LINK_MODE_INTERLEAVE; 195 + dl_buffer_depth = hactive / 2 + intel_dsi->pixel_overlap; 196 + 197 + if (dl_buffer_depth > MAX_DL_BUFFER_TARGET_DEPTH) 198 + DRM_ERROR("DL buffer depth exceed max value\n"); 199 + 200 + dss_ctl1 &= ~LEFT_DL_BUF_TARGET_DEPTH_MASK; 201 + dss_ctl1 |= LEFT_DL_BUF_TARGET_DEPTH(dl_buffer_depth); 202 + dss_ctl2 = I915_READ(DSS_CTL2); 203 + dss_ctl2 &= ~RIGHT_DL_BUF_TARGET_DEPTH_MASK; 204 + dss_ctl2 |= RIGHT_DL_BUF_TARGET_DEPTH(dl_buffer_depth); 205 + I915_WRITE(DSS_CTL2, dss_ctl2); 206 + } else { 207 + /* Interleave */ 208 + dss_ctl1 |= DUAL_LINK_MODE_INTERLEAVE; 209 + } 210 + 211 + I915_WRITE(DSS_CTL1, dss_ctl1); 258 212 } 259 213 260 214 static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder) ··· 536 412 } 537 413 } 538 414 415 + static void gen11_dsi_gate_clocks(struct intel_encoder *encoder) 416 + { 417 + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 418 + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); 419 + u32 tmp; 420 + enum port port; 421 + 422 + mutex_lock(&dev_priv->dpll_lock); 423 + tmp = I915_READ(DPCLKA_CFGCR0_ICL); 424 + for_each_dsi_port(port, intel_dsi->ports) { 425 + tmp |= DPCLKA_CFGCR0_DDI_CLK_OFF(port); 426 + } 427 + 428 + I915_WRITE(DPCLKA_CFGCR0_ICL, tmp); 429 + mutex_unlock(&dev_priv->dpll_lock); 430 + } 431 + 432 + static void gen11_dsi_ungate_clocks(struct intel_encoder *encoder) 433 + { 434 + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 435 + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); 436 + u32 tmp; 437 + enum port port; 438 + 439 + mutex_lock(&dev_priv->dpll_lock); 440 + tmp = I915_READ(DPCLKA_CFGCR0_ICL); 441 + for_each_dsi_port(port, intel_dsi->ports) { 442 + tmp &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port); 443 + } 444 + 445 + I915_WRITE(DPCLKA_CFGCR0_ICL, tmp); 446 + mutex_unlock(&dev_priv->dpll_lock); 447 + } 448 + 449 + static void gen11_dsi_map_pll(struct intel_encoder *encoder, 450 + const struct intel_crtc_state *crtc_state) 451 + { 452 + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 453 + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); 454 + struct intel_shared_dpll *pll = crtc_state->shared_dpll; 455 + enum port port; 456 + u32 val; 457 + 458 + mutex_lock(&dev_priv->dpll_lock); 459 + 460 + val = I915_READ(DPCLKA_CFGCR0_ICL); 461 + for_each_dsi_port(port, intel_dsi->ports) { 462 + val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port); 463 + val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port); 464 + } 465 + I915_WRITE(DPCLKA_CFGCR0_ICL, val); 466 + POSTING_READ(DPCLKA_CFGCR0_ICL); 467 + 468 + mutex_unlock(&dev_priv->dpll_lock); 469 + } 470 + 539 471 static void 540 472 gen11_dsi_configure_transcoder(struct intel_encoder *encoder, 541 473 const struct intel_crtc_state *pipe_config) ··· 686 506 I915_WRITE(TRANS_DDI_FUNC_CTL2(dsi_trans), tmp); 687 507 } 688 508 689 - //TODO: configure DSS_CTL1 509 + /* configure stream splitting */ 510 + configure_dual_link_mode(encoder, pipe_config); 690 511 } 691 512 692 513 for_each_dsi_port(port, intel_dsi->ports) { ··· 939 758 940 759 /* Step (4h, 4i, 4j, 4k): Configure transcoder */ 941 760 gen11_dsi_configure_transcoder(encoder, pipe_config); 761 + 762 + /* Step 4l: Gate DDI clocks */ 763 + gen11_dsi_gate_clocks(encoder); 942 764 } 943 765 944 766 static void gen11_dsi_powerup_panel(struct intel_encoder *encoder) ··· 983 799 wait_for_cmds_dispatched_to_panel(encoder); 984 800 } 985 801 986 - static void __attribute__((unused)) 987 - gen11_dsi_pre_enable(struct intel_encoder *encoder, 988 - const struct intel_crtc_state *pipe_config, 989 - const struct drm_connector_state *conn_state) 802 + static void gen11_dsi_pre_pll_enable(struct intel_encoder *encoder, 803 + const struct intel_crtc_state *pipe_config, 804 + const struct drm_connector_state *conn_state) 990 805 { 991 - struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); 992 - 993 806 /* step2: enable IO power */ 994 807 gen11_dsi_enable_io_power(encoder); 995 808 996 809 /* step3: enable DSI PLL */ 997 810 gen11_dsi_program_esc_clk_div(encoder); 811 + } 812 + 813 + static void gen11_dsi_pre_enable(struct intel_encoder *encoder, 814 + const struct intel_crtc_state *pipe_config, 815 + const struct drm_connector_state *conn_state) 816 + { 817 + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); 818 + 819 + /* step3b */ 820 + gen11_dsi_map_pll(encoder, pipe_config); 998 821 999 822 /* step4: enable DSI port and DPHY */ 1000 823 gen11_dsi_enable_port_and_phy(encoder, pipe_config); ··· 1103 912 u32 tmp; 1104 913 enum port port; 1105 914 915 + gen11_dsi_ungate_clocks(encoder); 1106 916 for_each_dsi_port(port, intel_dsi->ports) { 1107 917 tmp = I915_READ(DDI_BUF_CTL(port)); 1108 918 tmp &= ~DDI_BUF_CTL_ENABLE; ··· 1115 923 DRM_ERROR("DDI port:%c buffer not idle\n", 1116 924 port_name(port)); 1117 925 } 926 + gen11_dsi_ungate_clocks(encoder); 1118 927 } 1119 928 1120 929 static void gen11_dsi_disable_io_power(struct intel_encoder *encoder) ··· 1138 945 } 1139 946 } 1140 947 1141 - static void __attribute__((unused)) gen11_dsi_disable( 1142 - struct intel_encoder *encoder, 1143 - const struct intel_crtc_state *old_crtc_state, 1144 - const struct drm_connector_state *old_conn_state) 948 + static void gen11_dsi_disable(struct intel_encoder *encoder, 949 + const struct intel_crtc_state *old_crtc_state, 950 + const struct drm_connector_state *old_conn_state) 1145 951 { 1146 952 struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); 1147 953 ··· 1164 972 gen11_dsi_disable_io_power(encoder); 1165 973 } 1166 974 975 + static void gen11_dsi_get_config(struct intel_encoder *encoder, 976 + struct intel_crtc_state *pipe_config) 977 + { 978 + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 979 + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); 980 + u32 pll_id; 981 + 982 + /* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */ 983 + pll_id = intel_get_shared_dpll_id(dev_priv, pipe_config->shared_dpll); 984 + pipe_config->port_clock = cnl_calc_wrpll_link(dev_priv, pll_id); 985 + pipe_config->base.adjusted_mode.crtc_clock = intel_dsi->pclk; 986 + pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI); 987 + } 988 + 989 + static bool gen11_dsi_compute_config(struct intel_encoder *encoder, 990 + struct intel_crtc_state *pipe_config, 991 + struct drm_connector_state *conn_state) 992 + { 993 + struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi, 994 + base); 995 + struct intel_connector *intel_connector = intel_dsi->attached_connector; 996 + struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc); 997 + const struct drm_display_mode *fixed_mode = 998 + intel_connector->panel.fixed_mode; 999 + struct drm_display_mode *adjusted_mode = 1000 + &pipe_config->base.adjusted_mode; 1001 + 1002 + intel_fixed_panel_mode(fixed_mode, adjusted_mode); 1003 + intel_pch_panel_fitting(crtc, pipe_config, conn_state->scaling_mode); 1004 + 1005 + adjusted_mode->flags = 0; 1006 + 1007 + /* Dual link goes to trancoder DSI'0' */ 1008 + if (intel_dsi->ports == BIT(PORT_B)) 1009 + pipe_config->cpu_transcoder = TRANSCODER_DSI_1; 1010 + else 1011 + pipe_config->cpu_transcoder = TRANSCODER_DSI_0; 1012 + 1013 + pipe_config->clock_set = true; 1014 + pipe_config->port_clock = intel_dsi_bitrate(intel_dsi) / 5; 1015 + 1016 + return true; 1017 + } 1018 + 1019 + static u64 gen11_dsi_get_power_domains(struct intel_encoder *encoder, 1020 + struct intel_crtc_state *crtc_state) 1021 + { 1022 + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); 1023 + u64 domains = 0; 1024 + enum port port; 1025 + 1026 + for_each_dsi_port(port, intel_dsi->ports) 1027 + if (port == PORT_A) 1028 + domains |= BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO); 1029 + else 1030 + domains |= BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO); 1031 + 1032 + return domains; 1033 + } 1034 + 1035 + static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, 1036 + enum pipe *pipe) 1037 + { 1038 + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1039 + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); 1040 + u32 tmp; 1041 + enum port port; 1042 + enum transcoder dsi_trans; 1043 + bool ret = false; 1044 + 1045 + if (!intel_display_power_get_if_enabled(dev_priv, 1046 + encoder->power_domain)) 1047 + return false; 1048 + 1049 + for_each_dsi_port(port, intel_dsi->ports) { 1050 + dsi_trans = dsi_port_to_transcoder(port); 1051 + tmp = I915_READ(TRANS_DDI_FUNC_CTL(dsi_trans)); 1052 + switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { 1053 + case TRANS_DDI_EDP_INPUT_A_ON: 1054 + *pipe = PIPE_A; 1055 + break; 1056 + case TRANS_DDI_EDP_INPUT_B_ONOFF: 1057 + *pipe = PIPE_B; 1058 + break; 1059 + case TRANS_DDI_EDP_INPUT_C_ONOFF: 1060 + *pipe = PIPE_C; 1061 + break; 1062 + default: 1063 + DRM_ERROR("Invalid PIPE input\n"); 1064 + goto out; 1065 + } 1066 + 1067 + tmp = I915_READ(PIPECONF(dsi_trans)); 1068 + ret = tmp & PIPECONF_ENABLE; 1069 + } 1070 + out: 1071 + intel_display_power_put(dev_priv, encoder->power_domain); 1072 + return ret; 1073 + } 1074 + 1075 + static void gen11_dsi_encoder_destroy(struct drm_encoder *encoder) 1076 + { 1077 + intel_encoder_destroy(encoder); 1078 + } 1079 + 1080 + static const struct drm_encoder_funcs gen11_dsi_encoder_funcs = { 1081 + .destroy = gen11_dsi_encoder_destroy, 1082 + }; 1083 + 1084 + static const struct drm_connector_funcs gen11_dsi_connector_funcs = { 1085 + .late_register = intel_connector_register, 1086 + .early_unregister = intel_connector_unregister, 1087 + .destroy = intel_connector_destroy, 1088 + .fill_modes = drm_helper_probe_single_connector_modes, 1089 + .atomic_get_property = intel_digital_connector_atomic_get_property, 1090 + .atomic_set_property = intel_digital_connector_atomic_set_property, 1091 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1092 + .atomic_duplicate_state = intel_digital_connector_duplicate_state, 1093 + }; 1094 + 1095 + static const struct drm_connector_helper_funcs gen11_dsi_connector_helper_funcs = { 1096 + .get_modes = intel_dsi_get_modes, 1097 + .mode_valid = intel_dsi_mode_valid, 1098 + .atomic_check = intel_digital_connector_atomic_check, 1099 + }; 1100 + 1101 + static int gen11_dsi_host_attach(struct mipi_dsi_host *host, 1102 + struct mipi_dsi_device *dsi) 1103 + { 1104 + return 0; 1105 + } 1106 + 1107 + static int gen11_dsi_host_detach(struct mipi_dsi_host *host, 1108 + struct mipi_dsi_device *dsi) 1109 + { 1110 + return 0; 1111 + } 1112 + 1113 + static ssize_t gen11_dsi_host_transfer(struct mipi_dsi_host *host, 1114 + const struct mipi_dsi_msg *msg) 1115 + { 1116 + struct intel_dsi_host *intel_dsi_host = to_intel_dsi_host(host); 1117 + struct mipi_dsi_packet dsi_pkt; 1118 + ssize_t ret; 1119 + bool enable_lpdt = false; 1120 + 1121 + ret = mipi_dsi_create_packet(&dsi_pkt, msg); 1122 + if (ret < 0) 1123 + return ret; 1124 + 1125 + if (msg->flags & MIPI_DSI_MSG_USE_LPM) 1126 + enable_lpdt = true; 1127 + 1128 + /* send packet header */ 1129 + ret = dsi_send_pkt_hdr(intel_dsi_host, dsi_pkt, enable_lpdt); 1130 + if (ret < 0) 1131 + return ret; 1132 + 1133 + /* only long packet contains payload */ 1134 + if (mipi_dsi_packet_format_is_long(msg->type)) { 1135 + ret = dsi_send_pkt_payld(intel_dsi_host, dsi_pkt); 1136 + if (ret < 0) 1137 + return ret; 1138 + } 1139 + 1140 + //TODO: add payload receive code if needed 1141 + 1142 + ret = sizeof(dsi_pkt.header) + dsi_pkt.payload_length; 1143 + 1144 + return ret; 1145 + } 1146 + 1147 + static const struct mipi_dsi_host_ops gen11_dsi_host_ops = { 1148 + .attach = gen11_dsi_host_attach, 1149 + .detach = gen11_dsi_host_detach, 1150 + .transfer = gen11_dsi_host_transfer, 1151 + }; 1152 + 1167 1153 void icl_dsi_init(struct drm_i915_private *dev_priv) 1168 1154 { 1155 + struct drm_device *dev = &dev_priv->drm; 1156 + struct intel_dsi *intel_dsi; 1157 + struct intel_encoder *encoder; 1158 + struct intel_connector *intel_connector; 1159 + struct drm_connector *connector; 1160 + struct drm_display_mode *scan, *fixed_mode = NULL; 1169 1161 enum port port; 1170 1162 1171 1163 if (!intel_bios_is_dsi_present(dev_priv, &port)) 1172 1164 return; 1165 + 1166 + intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL); 1167 + if (!intel_dsi) 1168 + return; 1169 + 1170 + intel_connector = intel_connector_alloc(); 1171 + if (!intel_connector) { 1172 + kfree(intel_dsi); 1173 + return; 1174 + } 1175 + 1176 + encoder = &intel_dsi->base; 1177 + intel_dsi->attached_connector = intel_connector; 1178 + connector = &intel_connector->base; 1179 + 1180 + /* register DSI encoder with DRM subsystem */ 1181 + drm_encoder_init(dev, &encoder->base, &gen11_dsi_encoder_funcs, 1182 + DRM_MODE_ENCODER_DSI, "DSI %c", port_name(port)); 1183 + 1184 + encoder->pre_pll_enable = gen11_dsi_pre_pll_enable; 1185 + encoder->pre_enable = gen11_dsi_pre_enable; 1186 + encoder->disable = gen11_dsi_disable; 1187 + encoder->port = port; 1188 + encoder->get_config = gen11_dsi_get_config; 1189 + encoder->compute_config = gen11_dsi_compute_config; 1190 + encoder->get_hw_state = gen11_dsi_get_hw_state; 1191 + encoder->type = INTEL_OUTPUT_DSI; 1192 + encoder->cloneable = 0; 1193 + encoder->crtc_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C); 1194 + encoder->power_domain = POWER_DOMAIN_PORT_DSI; 1195 + encoder->get_power_domains = gen11_dsi_get_power_domains; 1196 + 1197 + /* register DSI connector with DRM subsystem */ 1198 + drm_connector_init(dev, connector, &gen11_dsi_connector_funcs, 1199 + DRM_MODE_CONNECTOR_DSI); 1200 + drm_connector_helper_add(connector, &gen11_dsi_connector_helper_funcs); 1201 + connector->display_info.subpixel_order = SubPixelHorizontalRGB; 1202 + connector->interlace_allowed = false; 1203 + connector->doublescan_allowed = false; 1204 + intel_connector->get_hw_state = intel_connector_get_hw_state; 1205 + 1206 + /* attach connector to encoder */ 1207 + intel_connector_attach_encoder(intel_connector, encoder); 1208 + 1209 + /* fill mode info from VBT */ 1210 + mutex_lock(&dev->mode_config.mutex); 1211 + intel_dsi_vbt_get_modes(intel_dsi); 1212 + list_for_each_entry(scan, &connector->probed_modes, head) { 1213 + if (scan->type & DRM_MODE_TYPE_PREFERRED) { 1214 + fixed_mode = drm_mode_duplicate(dev, scan); 1215 + break; 1216 + } 1217 + } 1218 + mutex_unlock(&dev->mode_config.mutex); 1219 + 1220 + if (!fixed_mode) { 1221 + DRM_ERROR("DSI fixed mode info missing\n"); 1222 + goto err; 1223 + } 1224 + 1225 + connector->display_info.width_mm = fixed_mode->width_mm; 1226 + connector->display_info.height_mm = fixed_mode->height_mm; 1227 + intel_panel_init(&intel_connector->panel, fixed_mode, NULL); 1228 + intel_panel_setup_backlight(connector, INVALID_PIPE); 1229 + 1230 + 1231 + if (dev_priv->vbt.dsi.config->dual_link) 1232 + intel_dsi->ports = BIT(PORT_A) | BIT(PORT_B); 1233 + else 1234 + intel_dsi->ports = BIT(port); 1235 + 1236 + intel_dsi->dcs_backlight_ports = dev_priv->vbt.dsi.bl_ports; 1237 + intel_dsi->dcs_cabc_ports = dev_priv->vbt.dsi.cabc_ports; 1238 + 1239 + for_each_dsi_port(port, intel_dsi->ports) { 1240 + struct intel_dsi_host *host; 1241 + 1242 + host = intel_dsi_host_init(intel_dsi, &gen11_dsi_host_ops, port); 1243 + if (!host) 1244 + goto err; 1245 + 1246 + intel_dsi->dsi_hosts[port] = host; 1247 + } 1248 + 1249 + if (!intel_dsi_vbt_init(intel_dsi, MIPI_DSI_GENERIC_PANEL_ID)) { 1250 + DRM_DEBUG_KMS("no device found\n"); 1251 + goto err; 1252 + } 1253 + 1254 + return; 1255 + 1256 + err: 1257 + drm_encoder_cleanup(&encoder->base); 1258 + kfree(intel_dsi); 1259 + kfree(intel_connector); 1173 1260 }
+1
drivers/gpu/drm/i915/intel_atomic.c
··· 184 184 crtc_state->fifo_changed = false; 185 185 crtc_state->wm.need_postvbl_update = false; 186 186 crtc_state->fb_bits = 0; 187 + crtc_state->update_planes = 0; 187 188 188 189 return &crtc_state->base; 189 190 }
+88 -14
drivers/gpu/drm/i915/intel_atomic_plane.c
··· 139 139 if (state->visible && state->fb->format->format == DRM_FORMAT_NV12) 140 140 crtc_state->nv12_planes |= BIT(intel_plane->id); 141 141 142 + if (state->visible || old_plane_state->base.visible) 143 + crtc_state->update_planes |= BIT(intel_plane->id); 144 + 142 145 return intel_plane_atomic_calc_changes(old_crtc_state, 143 146 &crtc_state->base, 144 147 old_plane_state, ··· 171 168 to_intel_plane_state(new_plane_state)); 172 169 } 173 170 174 - void intel_update_planes_on_crtc(struct intel_atomic_state *old_state, 175 - struct intel_crtc *crtc, 176 - struct intel_crtc_state *old_crtc_state, 177 - struct intel_crtc_state *new_crtc_state) 171 + static struct intel_plane * 172 + skl_next_plane_to_commit(struct intel_atomic_state *state, 173 + struct intel_crtc *crtc, 174 + struct skl_ddb_entry entries_y[I915_MAX_PLANES], 175 + struct skl_ddb_entry entries_uv[I915_MAX_PLANES], 176 + unsigned int *update_mask) 178 177 { 179 - struct intel_plane_state *new_plane_state; 178 + struct intel_crtc_state *crtc_state = 179 + intel_atomic_get_new_crtc_state(state, crtc); 180 + struct intel_plane_state *plane_state; 180 181 struct intel_plane *plane; 181 - u32 update_mask; 182 182 int i; 183 183 184 - update_mask = old_crtc_state->active_planes; 185 - update_mask |= new_crtc_state->active_planes; 184 + if (*update_mask == 0) 185 + return NULL; 186 186 187 - for_each_new_intel_plane_in_state(old_state, plane, new_plane_state, i) { 187 + for_each_new_intel_plane_in_state(state, plane, plane_state, i) { 188 + enum plane_id plane_id = plane->id; 189 + 188 190 if (crtc->pipe != plane->pipe || 189 - !(update_mask & BIT(plane->id))) 191 + !(*update_mask & BIT(plane_id))) 190 192 continue; 193 + 194 + if (skl_ddb_allocation_overlaps(&crtc_state->wm.skl.plane_ddb_y[plane_id], 195 + entries_y, 196 + I915_MAX_PLANES, plane_id) || 197 + skl_ddb_allocation_overlaps(&crtc_state->wm.skl.plane_ddb_uv[plane_id], 198 + entries_uv, 199 + I915_MAX_PLANES, plane_id)) 200 + continue; 201 + 202 + *update_mask &= ~BIT(plane_id); 203 + entries_y[plane_id] = crtc_state->wm.skl.plane_ddb_y[plane_id]; 204 + entries_uv[plane_id] = crtc_state->wm.skl.plane_ddb_uv[plane_id]; 205 + 206 + return plane; 207 + } 208 + 209 + /* should never happen */ 210 + WARN_ON(1); 211 + 212 + return NULL; 213 + } 214 + 215 + void skl_update_planes_on_crtc(struct intel_atomic_state *state, 216 + struct intel_crtc *crtc) 217 + { 218 + struct intel_crtc_state *old_crtc_state = 219 + intel_atomic_get_old_crtc_state(state, crtc); 220 + struct intel_crtc_state *new_crtc_state = 221 + intel_atomic_get_new_crtc_state(state, crtc); 222 + struct skl_ddb_entry entries_y[I915_MAX_PLANES]; 223 + struct skl_ddb_entry entries_uv[I915_MAX_PLANES]; 224 + u32 update_mask = new_crtc_state->update_planes; 225 + struct intel_plane *plane; 226 + 227 + memcpy(entries_y, old_crtc_state->wm.skl.plane_ddb_y, 228 + sizeof(old_crtc_state->wm.skl.plane_ddb_y)); 229 + memcpy(entries_uv, old_crtc_state->wm.skl.plane_ddb_uv, 230 + sizeof(old_crtc_state->wm.skl.plane_ddb_uv)); 231 + 232 + while ((plane = skl_next_plane_to_commit(state, crtc, 233 + entries_y, entries_uv, 234 + &update_mask))) { 235 + struct intel_plane_state *new_plane_state = 236 + intel_atomic_get_new_plane_state(state, plane); 191 237 192 238 if (new_plane_state->base.visible) { 193 239 trace_intel_update_plane(&plane->base, crtc); 194 - 195 240 plane->update_plane(plane, new_crtc_state, new_plane_state); 196 241 } else if (new_plane_state->slave) { 197 242 struct intel_plane *master = ··· 255 204 * plane_state. 256 205 */ 257 206 new_plane_state = 258 - intel_atomic_get_new_plane_state(old_state, master); 207 + intel_atomic_get_new_plane_state(state, master); 259 208 260 209 trace_intel_update_plane(&plane->base, crtc); 261 - 262 210 plane->update_slave(plane, new_crtc_state, new_plane_state); 263 211 } else { 264 212 trace_intel_disable_plane(&plane->base, crtc); 213 + plane->disable_plane(plane, new_crtc_state); 214 + } 215 + } 216 + } 265 217 266 - plane->disable_plane(plane, crtc); 218 + void i9xx_update_planes_on_crtc(struct intel_atomic_state *state, 219 + struct intel_crtc *crtc) 220 + { 221 + struct intel_crtc_state *new_crtc_state = 222 + intel_atomic_get_new_crtc_state(state, crtc); 223 + u32 update_mask = new_crtc_state->update_planes; 224 + struct intel_plane_state *new_plane_state; 225 + struct intel_plane *plane; 226 + int i; 227 + 228 + for_each_new_intel_plane_in_state(state, plane, new_plane_state, i) { 229 + if (crtc->pipe != plane->pipe || 230 + !(update_mask & BIT(plane->id))) 231 + continue; 232 + 233 + if (new_plane_state->base.visible) { 234 + trace_intel_update_plane(&plane->base, crtc); 235 + plane->update_plane(plane, new_crtc_state, new_plane_state); 236 + } else { 237 + trace_intel_disable_plane(&plane->base, crtc); 238 + plane->disable_plane(plane, new_crtc_state); 267 239 } 268 240 } 269 241 }
+1 -1
drivers/gpu/drm/i915/intel_bios.c
··· 1752 1752 const struct bdb_header *bdb; 1753 1753 u8 __iomem *bios = NULL; 1754 1754 1755 - if (INTEL_INFO(dev_priv)->num_pipes == 0) { 1755 + if (!HAS_DISPLAY(dev_priv)) { 1756 1756 DRM_DEBUG_KMS("Skipping VBT init due to disabled display.\n"); 1757 1757 return; 1758 1758 }
+1 -5
drivers/gpu/drm/i915/intel_breadcrumbs.c
··· 27 27 28 28 #include "i915_drv.h" 29 29 30 - #ifdef CONFIG_SMP 31 - #define task_asleep(tsk) ((tsk)->state & TASK_NORMAL && !(tsk)->on_cpu) 32 - #else 33 - #define task_asleep(tsk) ((tsk)->state & TASK_NORMAL) 34 - #endif 30 + #define task_asleep(tsk) ((tsk)->state & TASK_NORMAL && !(tsk)->on_rq) 35 31 36 32 static unsigned int __intel_breadcrumbs_wakeup(struct intel_breadcrumbs *b) 37 33 {
+155 -73
drivers/gpu/drm/i915/intel_ddi.c
··· 28 28 #include <drm/drm_scdc_helper.h> 29 29 #include "i915_drv.h" 30 30 #include "intel_drv.h" 31 + #include "intel_dsi.h" 31 32 32 33 struct ddi_buf_trans { 33 34 u32 trans1; /* balance leg enable, de-emph level */ ··· 1364 1363 return dco_freq / (p0 * p1 * p2 * 5); 1365 1364 } 1366 1365 1367 - static int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv, 1368 - enum intel_dpll_id pll_id) 1366 + int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv, 1367 + enum intel_dpll_id pll_id) 1369 1368 { 1370 1369 uint32_t cfgcr0, cfgcr1; 1371 1370 uint32_t p0, p1, p2, dco_freq, ref_clock; ··· 2155 2154 intel_port_is_tc(dev_priv, encoder->port)) 2156 2155 domains |= BIT_ULL(intel_ddi_main_link_aux_domain(dig_port)); 2157 2156 2157 + /* 2158 + * VDSC power is needed when DSC is enabled 2159 + */ 2160 + if (crtc_state->dsc_params.compression_enable) 2161 + domains |= BIT_ULL(intel_dsc_power_domain(crtc_state)); 2162 + 2158 2163 return domains; 2159 2164 } 2160 2165 ··· 2792 2785 return 0; 2793 2786 } 2794 2787 2795 - void icl_map_plls_to_ports(struct drm_crtc *crtc, 2796 - struct intel_crtc_state *crtc_state, 2797 - struct drm_atomic_state *old_state) 2788 + static void icl_map_plls_to_ports(struct intel_encoder *encoder, 2789 + const struct intel_crtc_state *crtc_state) 2798 2790 { 2791 + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2799 2792 struct intel_shared_dpll *pll = crtc_state->shared_dpll; 2800 - struct drm_i915_private *dev_priv = to_i915(crtc->dev); 2801 - struct drm_connector_state *conn_state; 2802 - struct drm_connector *conn; 2803 - int i; 2793 + enum port port = encoder->port; 2794 + u32 val; 2804 2795 2805 - for_each_new_connector_in_state(old_state, conn, conn_state, i) { 2806 - struct intel_encoder *encoder = 2807 - to_intel_encoder(conn_state->best_encoder); 2808 - enum port port; 2809 - uint32_t val; 2796 + mutex_lock(&dev_priv->dpll_lock); 2810 2797 2811 - if (conn_state->crtc != crtc) 2812 - continue; 2798 + val = I915_READ(DPCLKA_CFGCR0_ICL); 2799 + WARN_ON((val & icl_dpclka_cfgcr0_clk_off(dev_priv, port)) == 0); 2813 2800 2814 - port = encoder->port; 2815 - mutex_lock(&dev_priv->dpll_lock); 2816 - 2817 - val = I915_READ(DPCLKA_CFGCR0_ICL); 2818 - WARN_ON((val & icl_dpclka_cfgcr0_clk_off(dev_priv, port)) == 0); 2819 - 2820 - if (intel_port_is_combophy(dev_priv, port)) { 2821 - val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port); 2822 - val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port); 2823 - I915_WRITE(DPCLKA_CFGCR0_ICL, val); 2824 - POSTING_READ(DPCLKA_CFGCR0_ICL); 2825 - } 2826 - 2827 - val &= ~icl_dpclka_cfgcr0_clk_off(dev_priv, port); 2801 + if (intel_port_is_combophy(dev_priv, port)) { 2802 + val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port); 2803 + val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port); 2828 2804 I915_WRITE(DPCLKA_CFGCR0_ICL, val); 2829 - 2830 - mutex_unlock(&dev_priv->dpll_lock); 2805 + POSTING_READ(DPCLKA_CFGCR0_ICL); 2831 2806 } 2807 + 2808 + val &= ~icl_dpclka_cfgcr0_clk_off(dev_priv, port); 2809 + I915_WRITE(DPCLKA_CFGCR0_ICL, val); 2810 + 2811 + mutex_unlock(&dev_priv->dpll_lock); 2832 2812 } 2833 2813 2834 - void icl_unmap_plls_to_ports(struct drm_crtc *crtc, 2835 - struct intel_crtc_state *crtc_state, 2836 - struct drm_atomic_state *old_state) 2814 + static void icl_unmap_plls_to_ports(struct intel_encoder *encoder) 2837 2815 { 2838 - struct drm_i915_private *dev_priv = to_i915(crtc->dev); 2839 - struct drm_connector_state *old_conn_state; 2840 - struct drm_connector *conn; 2841 - int i; 2816 + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2817 + enum port port = encoder->port; 2818 + u32 val; 2842 2819 2843 - for_each_old_connector_in_state(old_state, conn, old_conn_state, i) { 2844 - struct intel_encoder *encoder = 2845 - to_intel_encoder(old_conn_state->best_encoder); 2846 - enum port port; 2820 + mutex_lock(&dev_priv->dpll_lock); 2847 2821 2848 - if (old_conn_state->crtc != crtc) 2849 - continue; 2822 + val = I915_READ(DPCLKA_CFGCR0_ICL); 2823 + val |= icl_dpclka_cfgcr0_clk_off(dev_priv, port); 2824 + I915_WRITE(DPCLKA_CFGCR0_ICL, val); 2850 2825 2851 - port = encoder->port; 2852 - mutex_lock(&dev_priv->dpll_lock); 2853 - I915_WRITE(DPCLKA_CFGCR0_ICL, 2854 - I915_READ(DPCLKA_CFGCR0_ICL) | 2855 - icl_dpclka_cfgcr0_clk_off(dev_priv, port)); 2856 - mutex_unlock(&dev_priv->dpll_lock); 2857 - } 2826 + mutex_unlock(&dev_priv->dpll_lock); 2858 2827 } 2859 2828 2860 2829 void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) 2861 2830 { 2862 2831 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 2863 2832 u32 val; 2864 - enum port port = encoder->port; 2865 - bool clk_enabled; 2833 + enum port port; 2834 + u32 port_mask; 2835 + bool ddi_clk_needed; 2866 2836 2867 2837 /* 2868 2838 * In case of DP MST, we sanitize the primary encoder only, not the ··· 2847 2863 */ 2848 2864 if (encoder->type == INTEL_OUTPUT_DP_MST) 2849 2865 return; 2850 - 2851 - val = I915_READ(DPCLKA_CFGCR0_ICL); 2852 - clk_enabled = !(val & icl_dpclka_cfgcr0_clk_off(dev_priv, port)); 2853 2866 2854 2867 if (!encoder->base.crtc && intel_encoder_is_dp(encoder)) { 2855 2868 u8 pipe_mask; ··· 2861 2880 return; 2862 2881 } 2863 2882 2864 - if (clk_enabled == !!encoder->base.crtc) 2865 - return; 2883 + port_mask = BIT(encoder->port); 2884 + ddi_clk_needed = encoder->base.crtc; 2866 2885 2867 - /* 2868 - * Punt on the case now where clock is disabled, but the encoder is 2869 - * enabled, something else is really broken then. 2870 - */ 2871 - if (WARN_ON(!clk_enabled)) 2872 - return; 2886 + if (encoder->type == INTEL_OUTPUT_DSI) { 2887 + struct intel_encoder *other_encoder; 2873 2888 2874 - DRM_NOTE("Port %c is disabled but it has a mapped PLL, unmap it\n", 2875 - port_name(port)); 2876 - val |= icl_dpclka_cfgcr0_clk_off(dev_priv, port); 2877 - I915_WRITE(DPCLKA_CFGCR0_ICL, val); 2889 + port_mask = intel_dsi_encoder_ports(encoder); 2890 + /* 2891 + * Sanity check that we haven't incorrectly registered another 2892 + * encoder using any of the ports of this DSI encoder. 2893 + */ 2894 + for_each_intel_encoder(&dev_priv->drm, other_encoder) { 2895 + if (other_encoder == encoder) 2896 + continue; 2897 + 2898 + if (WARN_ON(port_mask & BIT(other_encoder->port))) 2899 + return; 2900 + } 2901 + /* 2902 + * DSI ports should have their DDI clock ungated when disabled 2903 + * and gated when enabled. 2904 + */ 2905 + ddi_clk_needed = !encoder->base.crtc; 2906 + } 2907 + 2908 + val = I915_READ(DPCLKA_CFGCR0_ICL); 2909 + for_each_port_masked(port, port_mask) { 2910 + bool ddi_clk_ungated = !(val & 2911 + icl_dpclka_cfgcr0_clk_off(dev_priv, 2912 + port)); 2913 + 2914 + if (ddi_clk_needed == ddi_clk_ungated) 2915 + continue; 2916 + 2917 + /* 2918 + * Punt on the case now where clock is gated, but it would 2919 + * be needed by the port. Something else is really broken then. 2920 + */ 2921 + if (WARN_ON(ddi_clk_needed)) 2922 + continue; 2923 + 2924 + DRM_NOTE("Port %c is disabled/in DSI mode with an ungated DDI clock, gate it\n", 2925 + port_name(port)); 2926 + val |= icl_dpclka_cfgcr0_clk_off(dev_priv, port); 2927 + I915_WRITE(DPCLKA_CFGCR0_ICL, val); 2928 + } 2878 2929 } 2879 2930 2880 2931 static void intel_ddi_clk_select(struct intel_encoder *encoder, ··· 3109 3096 I915_WRITE(MG_DP_MODE(port, 1), ln1); 3110 3097 } 3111 3098 3099 + static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp, 3100 + const struct intel_crtc_state *crtc_state) 3101 + { 3102 + if (!crtc_state->fec_enable) 3103 + return; 3104 + 3105 + if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_FEC_CONFIGURATION, DP_FEC_READY) <= 0) 3106 + DRM_DEBUG_KMS("Failed to set FEC_READY in the sink\n"); 3107 + } 3108 + 3109 + static void intel_ddi_enable_fec(struct intel_encoder *encoder, 3110 + const struct intel_crtc_state *crtc_state) 3111 + { 3112 + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 3113 + enum port port = encoder->port; 3114 + u32 val; 3115 + 3116 + if (!crtc_state->fec_enable) 3117 + return; 3118 + 3119 + val = I915_READ(DP_TP_CTL(port)); 3120 + val |= DP_TP_CTL_FEC_ENABLE; 3121 + I915_WRITE(DP_TP_CTL(port), val); 3122 + 3123 + if (intel_wait_for_register(dev_priv, DP_TP_STATUS(port), 3124 + DP_TP_STATUS_FEC_ENABLE_LIVE, 3125 + DP_TP_STATUS_FEC_ENABLE_LIVE, 3126 + 1)) 3127 + DRM_ERROR("Timed out waiting for FEC Enable Status\n"); 3128 + } 3129 + 3130 + static void intel_ddi_disable_fec_state(struct intel_encoder *encoder, 3131 + const struct intel_crtc_state *crtc_state) 3132 + { 3133 + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 3134 + enum port port = encoder->port; 3135 + u32 val; 3136 + 3137 + if (!crtc_state->fec_enable) 3138 + return; 3139 + 3140 + val = I915_READ(DP_TP_CTL(port)); 3141 + val &= ~DP_TP_CTL_FEC_ENABLE; 3142 + I915_WRITE(DP_TP_CTL(port), val); 3143 + POSTING_READ(DP_TP_CTL(port)); 3144 + } 3145 + 3112 3146 static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, 3113 3147 const struct intel_crtc_state *crtc_state, 3114 3148 const struct drm_connector_state *conn_state) ··· 3194 3134 intel_ddi_init_dp_buf_reg(encoder); 3195 3135 if (!is_mst) 3196 3136 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); 3137 + intel_dp_sink_set_decompression_state(intel_dp, crtc_state, 3138 + true); 3139 + intel_dp_sink_set_fec_ready(intel_dp, crtc_state); 3197 3140 intel_dp_start_link_train(intel_dp); 3198 3141 if (port != PORT_A || INTEL_GEN(dev_priv) >= 9) 3199 3142 intel_dp_stop_link_train(intel_dp); 3143 + 3144 + intel_ddi_enable_fec(encoder, crtc_state); 3200 3145 3201 3146 icl_enable_phy_clock_gating(dig_port); 3202 3147 3203 3148 if (!is_mst) 3204 3149 intel_ddi_enable_pipe_clock(crtc_state); 3150 + 3151 + intel_dsc_enable(encoder, crtc_state); 3205 3152 } 3206 3153 3207 3154 static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder, ··· 3275 3208 3276 3209 WARN_ON(crtc_state->has_pch_encoder); 3277 3210 3211 + if (INTEL_GEN(dev_priv) >= 11) 3212 + icl_map_plls_to_ports(encoder, crtc_state); 3213 + 3278 3214 intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); 3279 3215 3280 3216 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { ··· 3298 3228 } 3299 3229 } 3300 3230 3301 - static void intel_disable_ddi_buf(struct intel_encoder *encoder) 3231 + static void intel_disable_ddi_buf(struct intel_encoder *encoder, 3232 + const struct intel_crtc_state *crtc_state) 3302 3233 { 3303 3234 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 3304 3235 enum port port = encoder->port; ··· 3317 3246 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); 3318 3247 val |= DP_TP_CTL_LINK_TRAIN_PAT1; 3319 3248 I915_WRITE(DP_TP_CTL(port), val); 3249 + 3250 + /* Disable FEC in DP Sink */ 3251 + intel_ddi_disable_fec_state(encoder, crtc_state); 3320 3252 3321 3253 if (wait) 3322 3254 intel_wait_ddi_buf_idle(dev_priv, port); ··· 3344 3270 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); 3345 3271 } 3346 3272 3347 - intel_disable_ddi_buf(encoder); 3273 + intel_disable_ddi_buf(encoder, old_crtc_state); 3348 3274 3349 3275 intel_edp_panel_vdd_on(intel_dp); 3350 3276 intel_edp_panel_off(intel_dp); ··· 3367 3293 3368 3294 intel_ddi_disable_pipe_clock(old_crtc_state); 3369 3295 3370 - intel_disable_ddi_buf(encoder); 3296 + intel_disable_ddi_buf(encoder, old_crtc_state); 3371 3297 3372 3298 intel_display_power_put(dev_priv, dig_port->ddi_io_power_domain); 3373 3299 ··· 3380 3306 const struct intel_crtc_state *old_crtc_state, 3381 3307 const struct drm_connector_state *old_conn_state) 3382 3308 { 3309 + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 3310 + 3383 3311 /* 3384 3312 * When called from DP MST code: 3385 3313 * - old_conn_state will be NULL ··· 3401 3325 else 3402 3326 intel_ddi_post_disable_dp(encoder, 3403 3327 old_crtc_state, old_conn_state); 3328 + 3329 + if (INTEL_GEN(dev_priv) >= 11) 3330 + icl_unmap_plls_to_ports(encoder); 3404 3331 } 3405 3332 3406 3333 void intel_ddi_fdi_post_disable(struct intel_encoder *encoder, ··· 3423 3344 val &= ~FDI_RX_ENABLE; 3424 3345 I915_WRITE(FDI_RX_CTL(PIPE_A), val); 3425 3346 3426 - intel_disable_ddi_buf(encoder); 3347 + intel_disable_ddi_buf(encoder, old_crtc_state); 3427 3348 intel_ddi_clk_disable(encoder); 3428 3349 3429 3350 val = I915_READ(FDI_RX_MISC(PIPE_A)); ··· 3570 3491 intel_edp_drrs_disable(intel_dp, old_crtc_state); 3571 3492 intel_psr_disable(intel_dp, old_crtc_state); 3572 3493 intel_edp_backlight_off(old_conn_state); 3494 + /* Disable the decompression in DP Sink */ 3495 + intel_dp_sink_set_decompression_state(intel_dp, old_crtc_state, 3496 + false); 3573 3497 } 3574 3498 3575 3499 static void intel_disable_ddi_hdmi(struct intel_encoder *encoder,
+6 -2
drivers/gpu/drm/i915/intel_device_info.c
··· 77 77 #define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, yesno(info->name)); 78 78 DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG); 79 79 #undef PRINT_FLAG 80 + 81 + #define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, yesno(info->display.name)); 82 + DEV_INFO_DISPLAY_FOR_EACH_FLAG(PRINT_FLAG); 83 + #undef PRINT_FLAG 80 84 } 81 85 82 86 static void sseu_dump(const struct sseu_dev_info *sseu, struct drm_printer *p) ··· 786 782 if (i915_modparams.disable_display) { 787 783 DRM_INFO("Display disabled (module parameter)\n"); 788 784 info->num_pipes = 0; 789 - } else if (info->num_pipes > 0 && 785 + } else if (HAS_DISPLAY(dev_priv) && 790 786 (IS_GEN7(dev_priv) || IS_GEN8(dev_priv)) && 791 787 HAS_PCH_SPLIT(dev_priv)) { 792 788 u32 fuse_strap = I915_READ(FUSE_STRAP); ··· 811 807 DRM_INFO("PipeC fused off\n"); 812 808 info->num_pipes -= 1; 813 809 } 814 - } else if (info->num_pipes > 0 && IS_GEN9(dev_priv)) { 810 + } else if (HAS_DISPLAY(dev_priv) && IS_GEN9(dev_priv)) { 815 811 u32 dfsm = I915_READ(SKL_DFSM); 816 812 u8 disabled_mask = 0; 817 813 bool invalid;
+21 -11
drivers/gpu/drm/i915/intel_device_info.h
··· 89 89 func(is_alpha_support); \ 90 90 /* Keep has_* in alphabetical order */ \ 91 91 func(has_64bit_reloc); \ 92 - func(has_csr); \ 93 - func(has_ddi); \ 94 - func(has_dp_mst); \ 95 92 func(has_reset_engine); \ 96 - func(has_fbc); \ 97 93 func(has_fpga_dbg); \ 98 - func(has_gmch_display); \ 99 94 func(has_guc); \ 100 95 func(has_guc_ct); \ 101 - func(has_hotplug); \ 102 96 func(has_l3_dpf); \ 103 97 func(has_llc); \ 104 98 func(has_logical_ring_contexts); \ 105 99 func(has_logical_ring_elsq); \ 106 100 func(has_logical_ring_preemption); \ 107 - func(has_overlay); \ 108 101 func(has_pooled_eu); \ 109 - func(has_psr); \ 110 102 func(has_rc6); \ 111 103 func(has_rc6p); \ 112 104 func(has_runtime_pm); \ 113 105 func(has_snoop); \ 114 106 func(has_coherent_ggtt); \ 115 107 func(unfenced_needs_alignment); \ 108 + func(hws_needs_physical); 109 + 110 + #define DEV_INFO_DISPLAY_FOR_EACH_FLAG(func) \ 111 + /* Keep in alphabetical order */ \ 116 112 func(cursor_needs_physical); \ 117 - func(hws_needs_physical); \ 113 + func(has_csr); \ 114 + func(has_ddi); \ 115 + func(has_dp_mst); \ 116 + func(has_fbc); \ 117 + func(has_gmch_display); \ 118 + func(has_hotplug); \ 119 + func(has_ipc); \ 120 + func(has_overlay); \ 121 + func(has_psr); \ 118 122 func(overlay_needs_physical); \ 119 - func(supports_tv); \ 120 - func(has_ipc); 123 + func(supports_tv); 121 124 122 125 #define GEN_MAX_SLICES (6) /* CNL upper bound */ 123 126 #define GEN_MAX_SUBSLICES (8) /* ICL upper bound */ ··· 175 172 #define DEFINE_FLAG(name) u8 name:1 176 173 DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG); 177 174 #undef DEFINE_FLAG 175 + 176 + struct { 177 + #define DEFINE_FLAG(name) u8 name:1 178 + DEV_INFO_DISPLAY_FOR_EACH_FLAG(DEFINE_FLAG); 179 + #undef DEFINE_FLAG 180 + } display; 181 + 178 182 u16 ddb_size; /* in blocks */ 179 183 180 184 /* Register offsets for the various display pipes and transcoders */
+157 -173
drivers/gpu/drm/i915/intel_display.c
··· 2341 2341 int color_plane) 2342 2342 { 2343 2343 struct drm_i915_private *dev_priv = to_i915(fb->dev); 2344 + unsigned int height; 2344 2345 2345 2346 if (fb->modifier != DRM_FORMAT_MOD_LINEAR && 2346 - fb->offsets[color_plane] % intel_tile_size(dev_priv)) 2347 + fb->offsets[color_plane] % intel_tile_size(dev_priv)) { 2348 + DRM_DEBUG_KMS("Misaligned offset 0x%08x for color plane %d\n", 2349 + fb->offsets[color_plane], color_plane); 2347 2350 return -EINVAL; 2351 + } 2352 + 2353 + height = drm_framebuffer_plane_height(fb->height, fb, color_plane); 2354 + height = ALIGN(height, intel_tile_height(fb, color_plane)); 2355 + 2356 + /* Catch potential overflows early */ 2357 + if (add_overflows_t(u32, mul_u32_u32(height, fb->pitches[color_plane]), 2358 + fb->offsets[color_plane])) { 2359 + DRM_DEBUG_KMS("Bad offset 0x%08x or pitch %d for color plane %d\n", 2360 + fb->offsets[color_plane], fb->pitches[color_plane], 2361 + color_plane); 2362 + return -ERANGE; 2363 + } 2348 2364 2349 2365 *x = 0; 2350 2366 *y = 0; ··· 2783 2767 intel_pre_disable_primary_noatomic(&crtc->base); 2784 2768 2785 2769 trace_intel_disable_plane(&plane->base, crtc); 2786 - plane->disable_plane(plane, crtc); 2770 + plane->disable_plane(plane, crtc_state); 2787 2771 } 2788 2772 2789 2773 static void ··· 3331 3315 enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; 3332 3316 u32 linear_offset; 3333 3317 u32 dspcntr = plane_state->ctl; 3334 - i915_reg_t reg = DSPCNTR(i9xx_plane); 3335 3318 int x = plane_state->color_plane[0].x; 3336 3319 int y = plane_state->color_plane[0].y; 3337 3320 unsigned long irqflags; ··· 3345 3330 3346 3331 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 3347 3332 3333 + I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride); 3334 + 3348 3335 if (INTEL_GEN(dev_priv) < 4) { 3349 3336 /* pipesrc and dspsize control the size that is scaled from, 3350 3337 * which should always be the user's requested size. 3351 3338 */ 3339 + I915_WRITE_FW(DSPPOS(i9xx_plane), 0); 3352 3340 I915_WRITE_FW(DSPSIZE(i9xx_plane), 3353 3341 ((crtc_state->pipe_src_h - 1) << 16) | 3354 3342 (crtc_state->pipe_src_w - 1)); 3355 - I915_WRITE_FW(DSPPOS(i9xx_plane), 0); 3356 3343 } else if (IS_CHERRYVIEW(dev_priv) && i9xx_plane == PLANE_B) { 3344 + I915_WRITE_FW(PRIMPOS(i9xx_plane), 0); 3357 3345 I915_WRITE_FW(PRIMSIZE(i9xx_plane), 3358 3346 ((crtc_state->pipe_src_h - 1) << 16) | 3359 3347 (crtc_state->pipe_src_w - 1)); 3360 - I915_WRITE_FW(PRIMPOS(i9xx_plane), 0); 3361 3348 I915_WRITE_FW(PRIMCNSTALPHA(i9xx_plane), 0); 3362 3349 } 3363 3350 3364 - I915_WRITE_FW(reg, dspcntr); 3365 - 3366 - I915_WRITE_FW(DSPSTRIDE(i9xx_plane), plane_state->color_plane[0].stride); 3367 3351 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { 3368 - I915_WRITE_FW(DSPSURF(i9xx_plane), 3369 - intel_plane_ggtt_offset(plane_state) + 3370 - dspaddr_offset); 3371 3352 I915_WRITE_FW(DSPOFFSET(i9xx_plane), (y << 16) | x); 3372 3353 } else if (INTEL_GEN(dev_priv) >= 4) { 3354 + I915_WRITE_FW(DSPLINOFF(i9xx_plane), linear_offset); 3355 + I915_WRITE_FW(DSPTILEOFF(i9xx_plane), (y << 16) | x); 3356 + } 3357 + 3358 + /* 3359 + * The control register self-arms if the plane was previously 3360 + * disabled. Try to make the plane enable atomic by writing 3361 + * the control register just before the surface register. 3362 + */ 3363 + I915_WRITE_FW(DSPCNTR(i9xx_plane), dspcntr); 3364 + if (INTEL_GEN(dev_priv) >= 4) 3373 3365 I915_WRITE_FW(DSPSURF(i9xx_plane), 3374 3366 intel_plane_ggtt_offset(plane_state) + 3375 3367 dspaddr_offset); 3376 - I915_WRITE_FW(DSPTILEOFF(i9xx_plane), (y << 16) | x); 3377 - I915_WRITE_FW(DSPLINOFF(i9xx_plane), linear_offset); 3378 - } else { 3368 + else 3379 3369 I915_WRITE_FW(DSPADDR(i9xx_plane), 3380 3370 intel_plane_ggtt_offset(plane_state) + 3381 3371 dspaddr_offset); 3382 - } 3383 3372 3384 3373 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 3385 3374 } 3386 3375 3387 3376 static void i9xx_disable_plane(struct intel_plane *plane, 3388 - struct intel_crtc *crtc) 3377 + const struct intel_crtc_state *crtc_state) 3389 3378 { 3390 3379 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 3391 3380 enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; ··· 3475 3456 } 3476 3457 } 3477 3458 3459 + static unsigned int skl_plane_stride_mult(const struct drm_framebuffer *fb, 3460 + int color_plane, unsigned int rotation) 3461 + { 3462 + /* 3463 + * The stride is either expressed as a multiple of 64 bytes chunks for 3464 + * linear buffers or in number of tiles for tiled buffers. 3465 + */ 3466 + if (fb->modifier == DRM_FORMAT_MOD_LINEAR) 3467 + return 64; 3468 + else if (drm_rotation_90_or_270(rotation)) 3469 + return intel_tile_height(fb, color_plane); 3470 + else 3471 + return intel_tile_width_bytes(fb, color_plane); 3472 + } 3473 + 3478 3474 u32 skl_plane_stride(const struct intel_plane_state *plane_state, 3479 3475 int color_plane) 3480 3476 { ··· 3500 3466 if (color_plane >= fb->format->num_planes) 3501 3467 return 0; 3502 3468 3503 - /* 3504 - * The stride is either expressed as a multiple of 64 bytes chunks for 3505 - * linear buffers or in number of tiles for tiled buffers. 3506 - */ 3507 - if (drm_rotation_90_or_270(rotation)) 3508 - stride /= intel_tile_height(fb, color_plane); 3509 - else 3510 - stride /= intel_fb_stride_alignment(fb, color_plane); 3511 - 3512 - return stride; 3469 + return stride / skl_plane_stride_mult(fb, color_plane, rotation); 3513 3470 } 3514 3471 3515 3472 static u32 skl_plane_ctl_format(uint32_t pixel_format) ··· 5428 5403 intel_update_watermarks(crtc); 5429 5404 } 5430 5405 5431 - static void intel_crtc_disable_planes(struct intel_crtc *crtc, unsigned plane_mask) 5406 + static void intel_crtc_disable_planes(struct intel_atomic_state *state, 5407 + struct intel_crtc *crtc) 5432 5408 { 5433 - struct drm_device *dev = crtc->base.dev; 5409 + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 5410 + const struct intel_crtc_state *new_crtc_state = 5411 + intel_atomic_get_new_crtc_state(state, crtc); 5412 + unsigned int update_mask = new_crtc_state->update_planes; 5413 + const struct intel_plane_state *old_plane_state; 5434 5414 struct intel_plane *plane; 5435 5415 unsigned fb_bits = 0; 5416 + int i; 5436 5417 5437 5418 intel_crtc_dpms_overlay_disable(crtc); 5438 5419 5439 - for_each_intel_plane_on_crtc(dev, crtc, plane) { 5440 - if (plane_mask & BIT(plane->id)) { 5441 - plane->disable_plane(plane, crtc); 5420 + for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) { 5421 + if (crtc->pipe != plane->pipe || 5422 + !(update_mask & BIT(plane->id))) 5423 + continue; 5442 5424 5425 + plane->disable_plane(plane, new_crtc_state); 5426 + 5427 + if (old_plane_state->base.visible) 5443 5428 fb_bits |= plane->frontbuffer_bit; 5444 - } 5445 5429 } 5446 5430 5447 - intel_frontbuffer_flip(to_i915(dev), fb_bits); 5431 + intel_frontbuffer_flip(dev_priv, fb_bits); 5448 5432 } 5449 5433 5450 5434 static void intel_encoders_pre_pll_enable(struct drm_crtc *crtc, ··· 5726 5692 if (pipe_config->shared_dpll) 5727 5693 intel_enable_shared_dpll(pipe_config); 5728 5694 5729 - if (INTEL_GEN(dev_priv) >= 11) 5730 - icl_map_plls_to_ports(crtc, pipe_config, old_state); 5731 - 5732 5695 intel_encoders_pre_enable(crtc, pipe_config, old_state); 5733 5696 5734 5697 if (intel_crtc_has_dp_encoder(pipe_config)) ··· 5920 5889 if (!transcoder_is_dsi(cpu_transcoder)) 5921 5890 intel_ddi_disable_transcoder_func(old_crtc_state); 5922 5891 5892 + intel_dsc_disable(old_crtc_state); 5893 + 5923 5894 if (INTEL_GEN(dev_priv) >= 9) 5924 5895 skylake_scaler_disable(intel_crtc); 5925 5896 else 5926 5897 ironlake_pfit_disable(old_crtc_state); 5927 5898 5928 5899 intel_encoders_post_disable(crtc, old_crtc_state, old_state); 5929 - 5930 - if (INTEL_GEN(dev_priv) >= 11) 5931 - icl_unmap_plls_to_ports(crtc, old_crtc_state, old_state); 5932 5900 5933 5901 intel_encoders_post_pll_disable(crtc, old_crtc_state, old_state); 5934 5902 } ··· 6754 6724 } 6755 6725 6756 6726 void 6757 - intel_link_compute_m_n(int bits_per_pixel, int nlanes, 6727 + intel_link_compute_m_n(u16 bits_per_pixel, int nlanes, 6758 6728 int pixel_clock, int link_clock, 6759 6729 struct intel_link_m_n *m_n, 6760 6730 bool constant_n) ··· 8969 8939 fb->width = ((val >> 0) & 0x1fff) + 1; 8970 8940 8971 8941 val = I915_READ(PLANE_STRIDE(pipe, plane_id)); 8972 - stride_mult = intel_fb_stride_alignment(fb, 0); 8942 + stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0); 8973 8943 fb->pitches[0] = (val & 0x3ff) * stride_mult; 8974 8944 8975 8945 aligned_height = intel_fb_align_height(fb, 0, fb->height); ··· 9333 9303 static int haswell_crtc_compute_clock(struct intel_crtc *crtc, 9334 9304 struct intel_crtc_state *crtc_state) 9335 9305 { 9306 + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 9336 9307 struct intel_atomic_state *state = 9337 9308 to_intel_atomic_state(crtc_state->base.state); 9338 9309 9339 - if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI)) { 9310 + if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) || 9311 + IS_ICELAKE(dev_priv)) { 9340 9312 struct intel_encoder *encoder = 9341 9313 intel_get_crtc_new_encoder(state, crtc_state); 9342 9314 ··· 9476 9444 struct drm_device *dev = crtc->base.dev; 9477 9445 struct drm_i915_private *dev_priv = to_i915(dev); 9478 9446 enum intel_display_power_domain power_domain; 9447 + unsigned long panel_transcoder_mask = BIT(TRANSCODER_EDP); 9448 + unsigned long enabled_panel_transcoders = 0; 9449 + enum transcoder panel_transcoder; 9479 9450 u32 tmp; 9451 + 9452 + if (IS_ICELAKE(dev_priv)) 9453 + panel_transcoder_mask |= 9454 + BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1); 9480 9455 9481 9456 /* 9482 9457 * The pipe->transcoder mapping is fixed with the exception of the eDP 9483 - * transcoder handled below. 9458 + * and DSI transcoders handled below. 9484 9459 */ 9485 9460 pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; 9486 9461 ··· 9495 9456 * XXX: Do intel_display_power_get_if_enabled before reading this (for 9496 9457 * consistency and less surprising code; it's in always on power). 9497 9458 */ 9498 - tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); 9499 - if (tmp & TRANS_DDI_FUNC_ENABLE) { 9500 - enum pipe trans_edp_pipe; 9459 + for_each_set_bit(panel_transcoder, &panel_transcoder_mask, 32) { 9460 + enum pipe trans_pipe; 9461 + 9462 + tmp = I915_READ(TRANS_DDI_FUNC_CTL(panel_transcoder)); 9463 + if (!(tmp & TRANS_DDI_FUNC_ENABLE)) 9464 + continue; 9465 + 9466 + /* 9467 + * Log all enabled ones, only use the first one. 9468 + * 9469 + * FIXME: This won't work for two separate DSI displays. 9470 + */ 9471 + enabled_panel_transcoders |= BIT(panel_transcoder); 9472 + if (enabled_panel_transcoders != BIT(panel_transcoder)) 9473 + continue; 9474 + 9501 9475 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { 9502 9476 default: 9503 - WARN(1, "unknown pipe linked to edp transcoder\n"); 9477 + WARN(1, "unknown pipe linked to transcoder %s\n", 9478 + transcoder_name(panel_transcoder)); 9504 9479 /* fall through */ 9505 9480 case TRANS_DDI_EDP_INPUT_A_ONOFF: 9506 9481 case TRANS_DDI_EDP_INPUT_A_ON: 9507 - trans_edp_pipe = PIPE_A; 9482 + trans_pipe = PIPE_A; 9508 9483 break; 9509 9484 case TRANS_DDI_EDP_INPUT_B_ONOFF: 9510 - trans_edp_pipe = PIPE_B; 9485 + trans_pipe = PIPE_B; 9511 9486 break; 9512 9487 case TRANS_DDI_EDP_INPUT_C_ONOFF: 9513 - trans_edp_pipe = PIPE_C; 9488 + trans_pipe = PIPE_C; 9514 9489 break; 9515 9490 } 9516 9491 9517 - if (trans_edp_pipe == crtc->pipe) 9518 - pipe_config->cpu_transcoder = TRANSCODER_EDP; 9492 + if (trans_pipe == crtc->pipe) 9493 + pipe_config->cpu_transcoder = panel_transcoder; 9519 9494 } 9495 + 9496 + /* 9497 + * Valid combos: none, eDP, DSI0, DSI1, DSI0+DSI1 9498 + */ 9499 + WARN_ON((enabled_panel_transcoders & BIT(TRANSCODER_EDP)) && 9500 + enabled_panel_transcoders != BIT(TRANSCODER_EDP)); 9520 9501 9521 9502 power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder); 9522 9503 if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) ··· 9670 9611 if (!active) 9671 9612 goto out; 9672 9613 9673 - if (!transcoder_is_dsi(pipe_config->cpu_transcoder)) { 9614 + if (!transcoder_is_dsi(pipe_config->cpu_transcoder) || 9615 + IS_ICELAKE(dev_priv)) { 9674 9616 haswell_get_ddi_port_state(crtc, pipe_config); 9675 9617 intel_get_pipe_timings(crtc, pipe_config); 9676 9618 } ··· 9727 9667 const struct drm_i915_gem_object *obj = intel_fb_obj(fb); 9728 9668 u32 base; 9729 9669 9730 - if (INTEL_INFO(dev_priv)->cursor_needs_physical) 9670 + if (INTEL_INFO(dev_priv)->display.cursor_needs_physical) 9731 9671 base = obj->phys_handle->busaddr; 9732 9672 else 9733 9673 base = intel_plane_ggtt_offset(plane_state); ··· 9954 9894 } 9955 9895 9956 9896 static void i845_disable_cursor(struct intel_plane *plane, 9957 - struct intel_crtc *crtc) 9897 + const struct intel_crtc_state *crtc_state) 9958 9898 { 9959 - i845_update_cursor(plane, NULL, NULL); 9899 + i845_update_cursor(plane, crtc_state, NULL); 9960 9900 } 9961 9901 9962 9902 static bool i845_cursor_get_hw_state(struct intel_plane *plane, ··· 10147 10087 * On some platforms writing CURCNTR first will also 10148 10088 * cause CURPOS to be armed by the CURBASE write. 10149 10089 * Without the CURCNTR write the CURPOS write would 10150 - * arm itself. Thus we always start the full update 10151 - * with a CURCNTR write. 10090 + * arm itself. Thus we always update CURCNTR before 10091 + * CURPOS. 10152 10092 * 10153 10093 * On other platforms CURPOS always requires the 10154 10094 * CURBASE write to arm the update. Additonally ··· 10158 10098 * cursor that doesn't appear to move, or even change 10159 10099 * shape. Thus we always write CURBASE. 10160 10100 * 10161 - * CURCNTR and CUR_FBC_CTL are always 10162 - * armed by the CURBASE write only. 10101 + * The other registers are armed by by the CURBASE write 10102 + * except when the plane is getting enabled at which time 10103 + * the CURCNTR write arms the update. 10163 10104 */ 10105 + 10106 + if (INTEL_GEN(dev_priv) >= 9) 10107 + skl_write_cursor_wm(plane, crtc_state); 10108 + 10164 10109 if (plane->cursor.base != base || 10165 10110 plane->cursor.size != fbc_ctl || 10166 10111 plane->cursor.cntl != cntl) { 10167 - I915_WRITE_FW(CURCNTR(pipe), cntl); 10168 10112 if (HAS_CUR_FBC(dev_priv)) 10169 10113 I915_WRITE_FW(CUR_FBC_CTL(pipe), fbc_ctl); 10114 + I915_WRITE_FW(CURCNTR(pipe), cntl); 10170 10115 I915_WRITE_FW(CURPOS(pipe), pos); 10171 10116 I915_WRITE_FW(CURBASE(pipe), base); 10172 10117 ··· 10187 10122 } 10188 10123 10189 10124 static void i9xx_disable_cursor(struct intel_plane *plane, 10190 - struct intel_crtc *crtc) 10125 + const struct intel_crtc_state *crtc_state) 10191 10126 { 10192 - i9xx_update_cursor(plane, NULL, NULL); 10127 + i9xx_update_cursor(plane, crtc_state, NULL); 10193 10128 } 10194 10129 10195 10130 static bool i9xx_cursor_get_hw_state(struct intel_plane *plane, ··· 10900 10835 continue; 10901 10836 10902 10837 plane_state->linked_plane = NULL; 10903 - if (plane_state->slave && !plane_state->base.visible) 10838 + if (plane_state->slave && !plane_state->base.visible) { 10904 10839 crtc_state->active_planes &= ~BIT(plane->id); 10840 + crtc_state->update_planes |= BIT(plane->id); 10841 + } 10905 10842 10906 10843 plane_state->slave = false; 10907 10844 } ··· 10944 10877 linked_state->slave = true; 10945 10878 linked_state->linked_plane = plane; 10946 10879 crtc_state->active_planes |= BIT(linked->id); 10880 + crtc_state->update_planes |= BIT(linked->id); 10947 10881 DRM_DEBUG_KMS("Using %s as Y plane for %s\n", linked->base.name, plane->base.name); 10948 10882 } 10949 10883 ··· 11955 11887 struct skl_pipe_wm hw_wm, *sw_wm; 11956 11888 struct skl_plane_wm *hw_plane_wm, *sw_plane_wm; 11957 11889 struct skl_ddb_entry *hw_ddb_entry, *sw_ddb_entry; 11890 + struct skl_ddb_entry hw_ddb_y[I915_MAX_PLANES]; 11891 + struct skl_ddb_entry hw_ddb_uv[I915_MAX_PLANES]; 11958 11892 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 11959 11893 const enum pipe pipe = intel_crtc->pipe; 11960 11894 int plane, level, max_level = ilk_wm_max_level(dev_priv); ··· 11966 11896 11967 11897 skl_pipe_wm_get_hw_state(crtc, &hw_wm); 11968 11898 sw_wm = &to_intel_crtc_state(new_state)->wm.skl.optimal; 11899 + 11900 + skl_pipe_ddb_get_hw_state(intel_crtc, hw_ddb_y, hw_ddb_uv); 11969 11901 11970 11902 skl_ddb_get_hw_state(dev_priv, &hw_ddb); 11971 11903 sw_ddb = &dev_priv->wm.skl_hw.ddb; ··· 12011 11939 } 12012 11940 12013 11941 /* DDB */ 12014 - hw_ddb_entry = &hw_ddb.plane[pipe][plane]; 12015 - sw_ddb_entry = &sw_ddb->plane[pipe][plane]; 11942 + hw_ddb_entry = &hw_ddb_y[plane]; 11943 + sw_ddb_entry = &to_intel_crtc_state(new_state)->wm.skl.plane_ddb_y[plane]; 12016 11944 12017 11945 if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) { 12018 11946 DRM_ERROR("mismatch in DDB state pipe %c plane %d (expected (%u,%u), found (%u,%u))\n", ··· 12061 11989 } 12062 11990 12063 11991 /* DDB */ 12064 - hw_ddb_entry = &hw_ddb.plane[pipe][PLANE_CURSOR]; 12065 - sw_ddb_entry = &sw_ddb->plane[pipe][PLANE_CURSOR]; 11992 + hw_ddb_entry = &hw_ddb_y[PLANE_CURSOR]; 11993 + sw_ddb_entry = &to_intel_crtc_state(new_state)->wm.skl.plane_ddb_y[PLANE_CURSOR]; 12066 11994 12067 11995 if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) { 12068 11996 DRM_ERROR("mismatch in DDB state pipe %c cursor (expected (%u,%u), found (%u,%u))\n", ··· 12740 12668 struct drm_device *dev = crtc->dev; 12741 12669 struct drm_i915_private *dev_priv = to_i915(dev); 12742 12670 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 12743 - struct intel_crtc_state *old_intel_cstate = to_intel_crtc_state(old_crtc_state); 12744 12671 struct intel_crtc_state *pipe_config = to_intel_crtc_state(new_crtc_state); 12745 12672 bool modeset = needs_modeset(new_crtc_state); 12746 12673 struct intel_plane_state *new_plane_state = ··· 12762 12691 12763 12692 intel_begin_crtc_commit(crtc, old_crtc_state); 12764 12693 12765 - intel_update_planes_on_crtc(to_intel_atomic_state(state), intel_crtc, 12766 - old_intel_cstate, pipe_config); 12694 + if (INTEL_GEN(dev_priv) >= 9) 12695 + skl_update_planes_on_crtc(to_intel_atomic_state(state), intel_crtc); 12696 + else 12697 + i9xx_update_planes_on_crtc(to_intel_atomic_state(state), intel_crtc); 12767 12698 12768 12699 intel_finish_crtc_commit(crtc, old_crtc_state); 12769 12700 } ··· 12958 12885 intel_pre_plane_update(old_intel_crtc_state, new_intel_crtc_state); 12959 12886 12960 12887 if (old_crtc_state->active) { 12961 - intel_crtc_disable_planes(intel_crtc, old_intel_crtc_state->active_planes); 12888 + intel_crtc_disable_planes(intel_state, intel_crtc); 12962 12889 12963 12890 /* 12964 12891 * We need to disable pipe CRC before disabling the pipe, ··· 13313 13240 struct i915_vma *vma; 13314 13241 13315 13242 if (plane->id == PLANE_CURSOR && 13316 - INTEL_INFO(dev_priv)->cursor_needs_physical) { 13243 + INTEL_INFO(dev_priv)->display.cursor_needs_physical) { 13317 13244 struct drm_i915_gem_object *obj = intel_fb_obj(fb); 13318 13245 const int align = intel_cursor_alignment(dev_priv); 13319 13246 int err; ··· 13808 13735 to_intel_plane_state(plane->state)); 13809 13736 } else { 13810 13737 trace_intel_disable_plane(plane, to_intel_crtc(crtc)); 13811 - intel_plane->disable_plane(intel_plane, to_intel_crtc(crtc)); 13738 + intel_plane->disable_plane(intel_plane, crtc_state); 13812 13739 } 13813 13740 13814 13741 intel_plane_unpin_fb(to_intel_plane_state(old_plane_state)); ··· 14259 14186 14260 14187 intel_pps_init(dev_priv); 14261 14188 14262 - if (INTEL_INFO(dev_priv)->num_pipes == 0) 14189 + if (!HAS_DISPLAY(dev_priv)) 14263 14190 return; 14264 14191 14265 14192 /* ··· 14524 14451 { 14525 14452 struct drm_i915_private *dev_priv = to_i915(obj->base.dev); 14526 14453 struct drm_framebuffer *fb = &intel_fb->base; 14527 - struct drm_format_name_buf format_name; 14528 14454 u32 pitch_limit; 14529 14455 unsigned int tiling, stride; 14530 14456 int ret = -EINVAL; ··· 14554 14482 } 14555 14483 } 14556 14484 14557 - /* Passed in modifier sanity checking. */ 14558 - switch (mode_cmd->modifier[0]) { 14559 - case I915_FORMAT_MOD_Y_TILED_CCS: 14560 - case I915_FORMAT_MOD_Yf_TILED_CCS: 14561 - switch (mode_cmd->pixel_format) { 14562 - case DRM_FORMAT_XBGR8888: 14563 - case DRM_FORMAT_ABGR8888: 14564 - case DRM_FORMAT_XRGB8888: 14565 - case DRM_FORMAT_ARGB8888: 14566 - break; 14567 - default: 14568 - DRM_DEBUG_KMS("RC supported only with RGB8888 formats\n"); 14569 - goto err; 14570 - } 14571 - /* fall through */ 14572 - case I915_FORMAT_MOD_Yf_TILED: 14573 - if (mode_cmd->pixel_format == DRM_FORMAT_C8) { 14574 - DRM_DEBUG_KMS("Indexed format does not support Yf tiling\n"); 14575 - goto err; 14576 - } 14577 - /* fall through */ 14578 - case I915_FORMAT_MOD_Y_TILED: 14579 - if (INTEL_GEN(dev_priv) < 9) { 14580 - DRM_DEBUG_KMS("Unsupported tiling 0x%llx!\n", 14581 - mode_cmd->modifier[0]); 14582 - goto err; 14583 - } 14584 - break; 14585 - case DRM_FORMAT_MOD_LINEAR: 14586 - case I915_FORMAT_MOD_X_TILED: 14587 - break; 14588 - default: 14589 - DRM_DEBUG_KMS("Unsupported fb modifier 0x%llx!\n", 14485 + if (!drm_any_plane_has_format(&dev_priv->drm, 14486 + mode_cmd->pixel_format, 14487 + mode_cmd->modifier[0])) { 14488 + struct drm_format_name_buf format_name; 14489 + 14490 + DRM_DEBUG_KMS("unsupported pixel format %s / modifier 0x%llx\n", 14491 + drm_get_format_name(mode_cmd->pixel_format, 14492 + &format_name), 14590 14493 mode_cmd->modifier[0]); 14591 14494 goto err; 14592 14495 } ··· 14593 14546 if (tiling != I915_TILING_NONE && mode_cmd->pitches[0] != stride) { 14594 14547 DRM_DEBUG_KMS("pitch (%d) must match tiling stride (%d)\n", 14595 14548 mode_cmd->pitches[0], stride); 14596 - goto err; 14597 - } 14598 - 14599 - /* Reject formats not supported by any plane early. */ 14600 - switch (mode_cmd->pixel_format) { 14601 - case DRM_FORMAT_C8: 14602 - case DRM_FORMAT_RGB565: 14603 - case DRM_FORMAT_XRGB8888: 14604 - case DRM_FORMAT_ARGB8888: 14605 - break; 14606 - case DRM_FORMAT_XRGB1555: 14607 - if (INTEL_GEN(dev_priv) > 3) { 14608 - DRM_DEBUG_KMS("unsupported pixel format: %s\n", 14609 - drm_get_format_name(mode_cmd->pixel_format, &format_name)); 14610 - goto err; 14611 - } 14612 - break; 14613 - case DRM_FORMAT_ABGR8888: 14614 - if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) && 14615 - INTEL_GEN(dev_priv) < 9) { 14616 - DRM_DEBUG_KMS("unsupported pixel format: %s\n", 14617 - drm_get_format_name(mode_cmd->pixel_format, &format_name)); 14618 - goto err; 14619 - } 14620 - break; 14621 - case DRM_FORMAT_XBGR8888: 14622 - case DRM_FORMAT_XRGB2101010: 14623 - case DRM_FORMAT_XBGR2101010: 14624 - if (INTEL_GEN(dev_priv) < 4) { 14625 - DRM_DEBUG_KMS("unsupported pixel format: %s\n", 14626 - drm_get_format_name(mode_cmd->pixel_format, &format_name)); 14627 - goto err; 14628 - } 14629 - break; 14630 - case DRM_FORMAT_ABGR2101010: 14631 - if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) { 14632 - DRM_DEBUG_KMS("unsupported pixel format: %s\n", 14633 - drm_get_format_name(mode_cmd->pixel_format, &format_name)); 14634 - goto err; 14635 - } 14636 - break; 14637 - case DRM_FORMAT_YUYV: 14638 - case DRM_FORMAT_UYVY: 14639 - case DRM_FORMAT_YVYU: 14640 - case DRM_FORMAT_VYUY: 14641 - if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv)) { 14642 - DRM_DEBUG_KMS("unsupported pixel format: %s\n", 14643 - drm_get_format_name(mode_cmd->pixel_format, &format_name)); 14644 - goto err; 14645 - } 14646 - break; 14647 - case DRM_FORMAT_NV12: 14648 - if (INTEL_GEN(dev_priv) < 9 || IS_SKYLAKE(dev_priv) || 14649 - IS_BROXTON(dev_priv)) { 14650 - DRM_DEBUG_KMS("unsupported pixel format: %s\n", 14651 - drm_get_format_name(mode_cmd->pixel_format, 14652 - &format_name)); 14653 - goto err; 14654 - } 14655 - break; 14656 - default: 14657 - DRM_DEBUG_KMS("unsupported pixel format: %s\n", 14658 - drm_get_format_name(mode_cmd->pixel_format, &format_name)); 14659 14549 goto err; 14660 14550 } 14661 14551 ··· 16050 16066 }; 16051 16067 int i; 16052 16068 16053 - if (INTEL_INFO(dev_priv)->num_pipes == 0) 16069 + if (!HAS_DISPLAY(dev_priv)) 16054 16070 return NULL; 16055 16071 16056 16072 error = kzalloc(sizeof(*error), GFP_ATOMIC);
+19 -2
drivers/gpu/drm/i915/intel_display.h
··· 242 242 POWER_DOMAIN_TRANSCODER_B, 243 243 POWER_DOMAIN_TRANSCODER_C, 244 244 POWER_DOMAIN_TRANSCODER_EDP, 245 + POWER_DOMAIN_TRANSCODER_EDP_VDSC, 245 246 POWER_DOMAIN_TRANSCODER_DSI_A, 246 247 POWER_DOMAIN_TRANSCODER_DSI_C, 247 248 POWER_DOMAIN_PORT_DDI_A_LANES, ··· 399 398 for_each_power_well_reverse(__dev_priv, __power_well) \ 400 399 for_each_if((__power_well)->desc->domains & (__domain_mask)) 401 400 401 + #define for_each_old_intel_plane_in_state(__state, plane, old_plane_state, __i) \ 402 + for ((__i) = 0; \ 403 + (__i) < (__state)->base.dev->mode_config.num_total_plane && \ 404 + ((plane) = to_intel_plane((__state)->base.planes[__i].ptr), \ 405 + (old_plane_state) = to_intel_plane_state((__state)->base.planes[__i].old_state), 1); \ 406 + (__i)++) \ 407 + for_each_if(plane) 408 + 402 409 #define for_each_new_intel_plane_in_state(__state, plane, new_plane_state, __i) \ 403 410 for ((__i) = 0; \ 404 411 (__i) < (__state)->base.dev->mode_config.num_total_plane && \ ··· 432 423 (__i)++) \ 433 424 for_each_if(plane) 434 425 435 - void intel_link_compute_m_n(int bpp, int nlanes, 426 + #define for_each_oldnew_intel_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state, __i) \ 427 + for ((__i) = 0; \ 428 + (__i) < (__state)->base.dev->mode_config.num_crtc && \ 429 + ((crtc) = to_intel_crtc((__state)->base.crtcs[__i].ptr), \ 430 + (old_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].old_state), \ 431 + (new_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].new_state), 1); \ 432 + (__i)++) \ 433 + for_each_if(crtc) 434 + 435 + void intel_link_compute_m_n(u16 bpp, int nlanes, 436 436 int pixel_clock, int link_clock, 437 437 struct intel_link_m_n *m_n, 438 438 bool constant_n); 439 - 440 439 bool is_ccs_modifier(u64 modifier); 441 440 #endif
+256 -49
drivers/gpu/drm/i915/intel_dp.c
··· 47 47 48 48 /* DP DSC small joiner has 2 FIFOs each of 640 x 6 bytes */ 49 49 #define DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER 61440 50 + #define DP_DSC_MIN_SUPPORTED_BPC 8 51 + #define DP_DSC_MAX_SUPPORTED_BPC 10 50 52 51 53 /* DP DSC throughput values used for slice count calculations KPixels/s */ 52 54 #define DP_DSC_PEAK_PIXEL_RATE 2720000 ··· 545 543 dsc_slice_count = 546 544 drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, 547 545 true); 548 - } else { 546 + } else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) { 549 547 dsc_max_output_bpp = 550 548 intel_dp_dsc_get_output_bpp(max_link_clock, 551 549 max_lanes, ··· 1710 1708 int min_bpp, max_bpp; 1711 1709 }; 1712 1710 1711 + static bool intel_dp_source_supports_fec(struct intel_dp *intel_dp, 1712 + const struct intel_crtc_state *pipe_config) 1713 + { 1714 + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); 1715 + 1716 + return INTEL_GEN(dev_priv) >= 11 && 1717 + pipe_config->cpu_transcoder != TRANSCODER_A; 1718 + } 1719 + 1720 + static bool intel_dp_supports_fec(struct intel_dp *intel_dp, 1721 + const struct intel_crtc_state *pipe_config) 1722 + { 1723 + return intel_dp_source_supports_fec(intel_dp, pipe_config) && 1724 + drm_dp_sink_supports_fec(intel_dp->fec_capable); 1725 + } 1726 + 1727 + static bool intel_dp_source_supports_dsc(struct intel_dp *intel_dp, 1728 + const struct intel_crtc_state *pipe_config) 1729 + { 1730 + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); 1731 + 1732 + return INTEL_GEN(dev_priv) >= 10 && 1733 + pipe_config->cpu_transcoder != TRANSCODER_A; 1734 + } 1735 + 1736 + static bool intel_dp_supports_dsc(struct intel_dp *intel_dp, 1737 + const struct intel_crtc_state *pipe_config) 1738 + { 1739 + if (!intel_dp_is_edp(intel_dp) && !pipe_config->fec_enable) 1740 + return false; 1741 + 1742 + return intel_dp_source_supports_dsc(intel_dp, pipe_config) && 1743 + drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd); 1744 + } 1745 + 1713 1746 static int intel_dp_compute_bpp(struct intel_dp *intel_dp, 1714 1747 struct intel_crtc_state *pipe_config) 1715 1748 { ··· 1879 1842 return false; 1880 1843 } 1881 1844 1845 + static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc) 1846 + { 1847 + int i, num_bpc; 1848 + u8 dsc_bpc[3] = {0}; 1849 + 1850 + num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd, 1851 + dsc_bpc); 1852 + for (i = 0; i < num_bpc; i++) { 1853 + if (dsc_max_bpc >= dsc_bpc[i]) 1854 + return dsc_bpc[i] * 3; 1855 + } 1856 + 1857 + return 0; 1858 + } 1859 + 1860 + static bool intel_dp_dsc_compute_config(struct intel_dp *intel_dp, 1861 + struct intel_crtc_state *pipe_config, 1862 + struct drm_connector_state *conn_state, 1863 + struct link_config_limits *limits) 1864 + { 1865 + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); 1866 + struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); 1867 + struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; 1868 + u8 dsc_max_bpc; 1869 + int pipe_bpp; 1870 + 1871 + if (!intel_dp_supports_dsc(intel_dp, pipe_config)) 1872 + return false; 1873 + 1874 + dsc_max_bpc = min_t(u8, DP_DSC_MAX_SUPPORTED_BPC, 1875 + conn_state->max_requested_bpc); 1876 + 1877 + pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, dsc_max_bpc); 1878 + if (pipe_bpp < DP_DSC_MIN_SUPPORTED_BPC * 3) { 1879 + DRM_DEBUG_KMS("No DSC support for less than 8bpc\n"); 1880 + return false; 1881 + } 1882 + 1883 + /* 1884 + * For now enable DSC for max bpp, max link rate, max lane count. 1885 + * Optimize this later for the minimum possible link rate/lane count 1886 + * with DSC enabled for the requested mode. 1887 + */ 1888 + pipe_config->pipe_bpp = pipe_bpp; 1889 + pipe_config->port_clock = intel_dp->common_rates[limits->max_clock]; 1890 + pipe_config->lane_count = limits->max_lane_count; 1891 + 1892 + if (intel_dp_is_edp(intel_dp)) { 1893 + pipe_config->dsc_params.compressed_bpp = 1894 + min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4, 1895 + pipe_config->pipe_bpp); 1896 + pipe_config->dsc_params.slice_count = 1897 + drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, 1898 + true); 1899 + } else { 1900 + u16 dsc_max_output_bpp; 1901 + u8 dsc_dp_slice_count; 1902 + 1903 + dsc_max_output_bpp = 1904 + intel_dp_dsc_get_output_bpp(pipe_config->port_clock, 1905 + pipe_config->lane_count, 1906 + adjusted_mode->crtc_clock, 1907 + adjusted_mode->crtc_hdisplay); 1908 + dsc_dp_slice_count = 1909 + intel_dp_dsc_get_slice_count(intel_dp, 1910 + adjusted_mode->crtc_clock, 1911 + adjusted_mode->crtc_hdisplay); 1912 + if (!dsc_max_output_bpp || !dsc_dp_slice_count) { 1913 + DRM_DEBUG_KMS("Compressed BPP/Slice Count not supported\n"); 1914 + return false; 1915 + } 1916 + pipe_config->dsc_params.compressed_bpp = min_t(u16, 1917 + dsc_max_output_bpp >> 4, 1918 + pipe_config->pipe_bpp); 1919 + pipe_config->dsc_params.slice_count = dsc_dp_slice_count; 1920 + } 1921 + /* 1922 + * VDSC engine operates at 1 Pixel per clock, so if peak pixel rate 1923 + * is greater than the maximum Cdclock and if slice count is even 1924 + * then we need to use 2 VDSC instances. 1925 + */ 1926 + if (adjusted_mode->crtc_clock > dev_priv->max_cdclk_freq) { 1927 + if (pipe_config->dsc_params.slice_count > 1) { 1928 + pipe_config->dsc_params.dsc_split = true; 1929 + } else { 1930 + DRM_DEBUG_KMS("Cannot split stream to use 2 VDSC instances\n"); 1931 + return false; 1932 + } 1933 + } 1934 + if (intel_dp_compute_dsc_params(intel_dp, pipe_config) < 0) { 1935 + DRM_DEBUG_KMS("Cannot compute valid DSC parameters for Input Bpp = %d " 1936 + "Compressed BPP = %d\n", 1937 + pipe_config->pipe_bpp, 1938 + pipe_config->dsc_params.compressed_bpp); 1939 + return false; 1940 + } 1941 + pipe_config->dsc_params.compression_enable = true; 1942 + DRM_DEBUG_KMS("DP DSC computed with Input Bpp = %d " 1943 + "Compressed Bpp = %d Slice Count = %d\n", 1944 + pipe_config->pipe_bpp, 1945 + pipe_config->dsc_params.compressed_bpp, 1946 + pipe_config->dsc_params.slice_count); 1947 + 1948 + return true; 1949 + } 1950 + 1882 1951 static bool 1883 1952 intel_dp_compute_link_config(struct intel_encoder *encoder, 1884 - struct intel_crtc_state *pipe_config) 1953 + struct intel_crtc_state *pipe_config, 1954 + struct drm_connector_state *conn_state) 1885 1955 { 1886 1956 struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; 1887 1957 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); 1888 1958 struct link_config_limits limits; 1889 1959 int common_len; 1960 + bool ret; 1890 1961 1891 1962 common_len = intel_dp_common_len_rate_limit(intel_dp, 1892 1963 intel_dp->max_link_rate); ··· 2033 1888 intel_dp->common_rates[limits.max_clock], 2034 1889 limits.max_bpp, adjusted_mode->crtc_clock); 2035 1890 2036 - if (intel_dp_is_edp(intel_dp)) { 1891 + if (intel_dp_is_edp(intel_dp)) 2037 1892 /* 2038 1893 * Optimize for fast and narrow. eDP 1.3 section 3.3 and eDP 1.4 2039 1894 * section A.1: "It is recommended that the minimum number of ··· 2043 1898 * Note that we use the max clock and lane count for eDP 1.3 and 2044 1899 * earlier, and fast vs. wide is irrelevant. 2045 1900 */ 2046 - if (!intel_dp_compute_link_config_fast(intel_dp, pipe_config, 2047 - &limits)) 2048 - return false; 2049 - } else { 1901 + ret = intel_dp_compute_link_config_fast(intel_dp, pipe_config, 1902 + &limits); 1903 + else 2050 1904 /* Optimize for slow and wide. */ 2051 - if (!intel_dp_compute_link_config_wide(intel_dp, pipe_config, 2052 - &limits)) 1905 + ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, 1906 + &limits); 1907 + 1908 + /* enable compression if the mode doesn't fit available BW */ 1909 + if (!ret) { 1910 + if (!intel_dp_dsc_compute_config(intel_dp, pipe_config, 1911 + conn_state, &limits)) 2053 1912 return false; 2054 1913 } 2055 1914 2056 - DRM_DEBUG_KMS("DP lane count %d clock %d bpp %d\n", 2057 - pipe_config->lane_count, pipe_config->port_clock, 2058 - pipe_config->pipe_bpp); 1915 + if (pipe_config->dsc_params.compression_enable) { 1916 + DRM_DEBUG_KMS("DP lane count %d clock %d Input bpp %d Compressed bpp %d\n", 1917 + pipe_config->lane_count, pipe_config->port_clock, 1918 + pipe_config->pipe_bpp, 1919 + pipe_config->dsc_params.compressed_bpp); 2059 1920 2060 - DRM_DEBUG_KMS("DP link rate required %i available %i\n", 2061 - intel_dp_link_required(adjusted_mode->crtc_clock, 2062 - pipe_config->pipe_bpp), 2063 - intel_dp_max_data_rate(pipe_config->port_clock, 2064 - pipe_config->lane_count)); 1921 + DRM_DEBUG_KMS("DP link rate required %i available %i\n", 1922 + intel_dp_link_required(adjusted_mode->crtc_clock, 1923 + pipe_config->dsc_params.compressed_bpp), 1924 + intel_dp_max_data_rate(pipe_config->port_clock, 1925 + pipe_config->lane_count)); 1926 + } else { 1927 + DRM_DEBUG_KMS("DP lane count %d clock %d bpp %d\n", 1928 + pipe_config->lane_count, pipe_config->port_clock, 1929 + pipe_config->pipe_bpp); 2065 1930 1931 + DRM_DEBUG_KMS("DP link rate required %i available %i\n", 1932 + intel_dp_link_required(adjusted_mode->crtc_clock, 1933 + pipe_config->pipe_bpp), 1934 + intel_dp_max_data_rate(pipe_config->port_clock, 1935 + pipe_config->lane_count)); 1936 + } 2066 1937 return true; 2067 1938 } 2068 1939 ··· 2144 1983 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) 2145 1984 return false; 2146 1985 2147 - if (!intel_dp_compute_link_config(encoder, pipe_config)) 1986 + pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) && 1987 + intel_dp_supports_fec(intel_dp, pipe_config); 1988 + 1989 + if (!intel_dp_compute_link_config(encoder, pipe_config, conn_state)) 2148 1990 return false; 2149 1991 2150 1992 if (intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_AUTO) { ··· 2165 2001 intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_LIMITED; 2166 2002 } 2167 2003 2168 - intel_link_compute_m_n(pipe_config->pipe_bpp, pipe_config->lane_count, 2169 - adjusted_mode->crtc_clock, 2170 - pipe_config->port_clock, 2171 - &pipe_config->dp_m_n, 2172 - constant_n); 2004 + if (!pipe_config->dsc_params.compression_enable) 2005 + intel_link_compute_m_n(pipe_config->pipe_bpp, 2006 + pipe_config->lane_count, 2007 + adjusted_mode->crtc_clock, 2008 + pipe_config->port_clock, 2009 + &pipe_config->dp_m_n, 2010 + constant_n); 2011 + else 2012 + intel_link_compute_m_n(pipe_config->dsc_params.compressed_bpp, 2013 + pipe_config->lane_count, 2014 + adjusted_mode->crtc_clock, 2015 + pipe_config->port_clock, 2016 + &pipe_config->dp_m_n, 2017 + constant_n); 2173 2018 2174 2019 if (intel_connector->panel.downclock_mode != NULL && 2175 2020 dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) { ··· 2873 2700 return intel_dp->dpcd[DP_DPCD_REV] == 0x11 && 2874 2701 intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT && 2875 2702 intel_dp->downstream_ports[0] & DP_DS_PORT_HPD; 2703 + } 2704 + 2705 + void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp, 2706 + const struct intel_crtc_state *crtc_state, 2707 + bool enable) 2708 + { 2709 + int ret; 2710 + 2711 + if (!crtc_state->dsc_params.compression_enable) 2712 + return; 2713 + 2714 + ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_DSC_ENABLE, 2715 + enable ? DP_DECOMPRESSION_EN : 0); 2716 + if (ret < 0) 2717 + DRM_DEBUG_KMS("Failed to %s sink decompression state\n", 2718 + enable ? "enable" : "disable"); 2876 2719 } 2877 2720 2878 2721 /* If the sink supports it, try to set the power state appropriately */ ··· 4026 3837 DRM_DEBUG_KMS("DSC DPCD: %*ph\n", 4027 3838 (int)sizeof(intel_dp->dsc_dpcd), 4028 3839 intel_dp->dsc_dpcd); 4029 - /* FEC is supported only on DP 1.4 */ 4030 - if (!intel_dp_is_edp(intel_dp)) { 4031 - if (drm_dp_dpcd_readb(&intel_dp->aux, DP_FEC_CAPABILITY, 4032 - &intel_dp->fec_capable) < 0) 4033 - DRM_ERROR("Failed to read FEC DPCD register\n"); 4034 3840 4035 - DRM_DEBUG_KMS("FEC CAPABILITY: %x\n", 4036 - intel_dp->fec_capable); 4037 - } 3841 + /* FEC is supported only on DP 1.4 */ 3842 + if (!intel_dp_is_edp(intel_dp) && 3843 + drm_dp_dpcd_readb(&intel_dp->aux, DP_FEC_CAPABILITY, 3844 + &intel_dp->fec_capable) < 0) 3845 + DRM_ERROR("Failed to read FEC DPCD register\n"); 3846 + 3847 + DRM_DEBUG_KMS("FEC CAPABILITY: %x\n", intel_dp->fec_capable); 4038 3848 } 4039 3849 } 4040 3850 ··· 4124 3936 static bool 4125 3937 intel_dp_get_dpcd(struct intel_dp *intel_dp) 4126 3938 { 4127 - u8 sink_count; 4128 - 4129 3939 if (!intel_dp_read_dpcd(intel_dp)) 4130 3940 return false; 4131 3941 ··· 4133 3947 intel_dp_set_common_rates(intel_dp); 4134 3948 } 4135 3949 4136 - if (drm_dp_dpcd_readb(&intel_dp->aux, DP_SINK_COUNT, &sink_count) <= 0) 4137 - return false; 4138 - 4139 3950 /* 4140 - * Sink count can change between short pulse hpd hence 4141 - * a member variable in intel_dp will track any changes 4142 - * between short pulse interrupts. 3951 + * Some eDP panels do not set a valid value for sink count, that is why 3952 + * it don't care about read it here and in intel_edp_init_dpcd(). 4143 3953 */ 4144 - intel_dp->sink_count = DP_GET_SINK_COUNT(sink_count); 3954 + if (!intel_dp_is_edp(intel_dp)) { 3955 + u8 count; 3956 + ssize_t r; 4145 3957 4146 - /* 4147 - * SINK_COUNT == 0 and DOWNSTREAM_PORT_PRESENT == 1 implies that 4148 - * a dongle is present but no display. Unless we require to know 4149 - * if a dongle is present or not, we don't need to update 4150 - * downstream port information. So, an early return here saves 4151 - * time from performing other operations which are not required. 4152 - */ 4153 - if (!intel_dp_is_edp(intel_dp) && !intel_dp->sink_count) 4154 - return false; 3958 + r = drm_dp_dpcd_readb(&intel_dp->aux, DP_SINK_COUNT, &count); 3959 + if (r < 1) 3960 + return false; 3961 + 3962 + /* 3963 + * Sink count can change between short pulse hpd hence 3964 + * a member variable in intel_dp will track any changes 3965 + * between short pulse interrupts. 3966 + */ 3967 + intel_dp->sink_count = DP_GET_SINK_COUNT(count); 3968 + 3969 + /* 3970 + * SINK_COUNT == 0 and DOWNSTREAM_PORT_PRESENT == 1 implies that 3971 + * a dongle is present but no display. Unless we require to know 3972 + * if a dongle is present or not, we don't need to update 3973 + * downstream port information. So, an early return here saves 3974 + * time from performing other operations which are not required. 3975 + */ 3976 + if (!intel_dp->sink_count) 3977 + return false; 3978 + } 4155 3979 4156 3980 if (!drm_dp_is_branch(intel_dp->dpcd)) 4157 3981 return true; /* native DP sink */ ··· 4569 4373 u8 link_status[DP_LINK_STATUS_SIZE]; 4570 4374 4571 4375 if (!intel_dp->link_trained) 4376 + return false; 4377 + 4378 + /* 4379 + * While PSR source HW is enabled, it will control main-link sending 4380 + * frames, enabling and disabling it so trying to do a retrain will fail 4381 + * as the link would or not be on or it could mix training patterns 4382 + * and frame data at the same time causing retrain to fail. 4383 + * Also when exiting PSR, HW will retrain the link anyways fixing 4384 + * any link status error. 4385 + */ 4386 + if (intel_psr_enabled(intel_dp)) 4572 4387 return false; 4573 4388 4574 4389 if (!intel_dp_get_link_status(intel_dp, link_status))
+2 -1
drivers/gpu/drm/i915/intel_dpll_mgr.c
··· 2523 2523 2524 2524 if (intel_port_is_tc(dev_priv, encoder->port)) 2525 2525 ret = icl_calc_tbt_pll(dev_priv, clock, &pll_params); 2526 - else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) 2526 + else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) || 2527 + intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI)) 2527 2528 ret = cnl_ddi_calculate_wrpll(clock, dev_priv, &pll_params); 2528 2529 else 2529 2530 ret = icl_calc_dp_combo_pll(dev_priv, clock, &pll_params);
+41 -11
drivers/gpu/drm/i915/intel_drv.h
··· 706 706 /* gen9+ only needs 1-step wm programming */ 707 707 struct skl_pipe_wm optimal; 708 708 struct skl_ddb_entry ddb; 709 + struct skl_ddb_entry plane_ddb_y[I915_MAX_PLANES]; 710 + struct skl_ddb_entry plane_ddb_uv[I915_MAX_PLANES]; 709 711 } skl; 710 712 711 713 struct { ··· 928 926 u8 active_planes; 929 927 u8 nv12_planes; 930 928 929 + /* bitmask of planes that will be updated during the commit */ 930 + u8 update_planes; 931 + 931 932 /* HDMI scrambling status */ 932 933 bool hdmi_scrambling; 933 934 ··· 942 937 943 938 /* Output down scaling is done in LSPCON device */ 944 939 bool lspcon_downsampling; 940 + 941 + /* Display Stream compression state */ 942 + struct { 943 + bool compression_enable; 944 + bool dsc_split; 945 + u16 compressed_bpp; 946 + u8 slice_count; 947 + } dsc_params; 948 + struct drm_dsc_config dp_dsc_cfg; 949 + 950 + /* Forward Error correction State */ 951 + bool fec_enable; 945 952 }; 946 953 947 954 struct intel_crtc { ··· 1030 1013 const struct intel_crtc_state *crtc_state, 1031 1014 const struct intel_plane_state *plane_state); 1032 1015 void (*disable_plane)(struct intel_plane *plane, 1033 - struct intel_crtc *crtc); 1016 + const struct intel_crtc_state *crtc_state); 1034 1017 bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe); 1035 1018 int (*check_plane)(struct intel_crtc_state *crtc_state, 1036 1019 struct intel_plane_state *plane_state); ··· 1534 1517 u8 voltage_swing); 1535 1518 int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, 1536 1519 bool enable); 1537 - void icl_map_plls_to_ports(struct drm_crtc *crtc, 1538 - struct intel_crtc_state *crtc_state, 1539 - struct drm_atomic_state *old_state); 1540 - void icl_unmap_plls_to_ports(struct drm_crtc *crtc, 1541 - struct intel_crtc_state *crtc_state, 1542 - struct drm_atomic_state *old_state); 1543 1520 void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder); 1521 + int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv, 1522 + enum intel_dpll_id pll_id); 1544 1523 1545 1524 unsigned int intel_fb_align_height(const struct drm_framebuffer *fb, 1546 1525 int color_plane, unsigned int height); ··· 1801 1788 int intel_dp_retrain_link(struct intel_encoder *encoder, 1802 1789 struct drm_modeset_acquire_ctx *ctx); 1803 1790 void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode); 1791 + void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp, 1792 + const struct intel_crtc_state *crtc_state, 1793 + bool enable); 1804 1794 void intel_dp_encoder_reset(struct drm_encoder *encoder); 1805 1795 void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder); 1806 1796 void intel_dp_encoder_destroy(struct drm_encoder *encoder); ··· 1858 1842 int mode_clock, int mode_hdisplay); 1859 1843 uint8_t intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock, 1860 1844 int mode_hdisplay); 1845 + 1846 + /* intel_vdsc.c */ 1847 + int intel_dp_compute_dsc_params(struct intel_dp *intel_dp, 1848 + struct intel_crtc_state *pipe_config); 1849 + enum intel_display_power_domain 1850 + intel_dsc_power_domain(const struct intel_crtc_state *crtc_state); 1861 1851 1862 1852 static inline unsigned int intel_dp_unused_lane_mask(int lane_count) 1863 1853 { ··· 2069 2047 void intel_psr_short_pulse(struct intel_dp *intel_dp); 2070 2048 int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state, 2071 2049 u32 *out_value); 2050 + bool intel_psr_enabled(struct intel_dp *intel_dp); 2072 2051 2073 2052 /* intel_quirks.c */ 2074 2053 void intel_init_quirks(struct drm_i915_private *dev_priv); ··· 2204 2181 void vlv_wm_get_hw_state(struct drm_device *dev); 2205 2182 void ilk_wm_get_hw_state(struct drm_device *dev); 2206 2183 void skl_wm_get_hw_state(struct drm_device *dev); 2184 + void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc, 2185 + struct skl_ddb_entry *ddb_y, 2186 + struct skl_ddb_entry *ddb_uv); 2207 2187 void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, 2208 2188 struct skl_ddb_allocation *ddb /* out */); 2209 2189 void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc, ··· 2221 2195 bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb, 2222 2196 const struct skl_ddb_entry entries[], 2223 2197 int num_entries, int ignore_idx); 2198 + void skl_write_plane_wm(struct intel_plane *plane, 2199 + const struct intel_crtc_state *crtc_state); 2200 + void skl_write_cursor_wm(struct intel_plane *plane, 2201 + const struct intel_crtc_state *crtc_state); 2224 2202 bool ilk_disable_lp_wm(struct drm_device *dev); 2225 2203 int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc, 2226 2204 struct intel_crtc_state *cstate); ··· 2317 2287 void intel_plane_destroy_state(struct drm_plane *plane, 2318 2288 struct drm_plane_state *state); 2319 2289 extern const struct drm_plane_helper_funcs intel_plane_helper_funcs; 2320 - void intel_update_planes_on_crtc(struct intel_atomic_state *old_state, 2321 - struct intel_crtc *crtc, 2322 - struct intel_crtc_state *old_crtc_state, 2323 - struct intel_crtc_state *new_crtc_state); 2290 + void skl_update_planes_on_crtc(struct intel_atomic_state *state, 2291 + struct intel_crtc *crtc); 2292 + void i9xx_update_planes_on_crtc(struct intel_atomic_state *state, 2293 + struct intel_crtc *crtc); 2324 2294 int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_state, 2325 2295 struct intel_crtc_state *crtc_state, 2326 2296 const struct intel_plane_state *old_plane_state,
+5
drivers/gpu/drm/i915/intel_dsi.h
··· 146 146 return intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE; 147 147 } 148 148 149 + static inline u16 intel_dsi_encoder_ports(struct intel_encoder *encoder) 150 + { 151 + return enc_to_intel_dsi(&encoder->base)->ports; 152 + } 153 + 149 154 /* intel_dsi.c */ 150 155 int intel_dsi_bitrate(const struct intel_dsi *intel_dsi); 151 156 int intel_dsi_tlpx_ns(const struct intel_dsi *intel_dsi);
+21 -1
drivers/gpu/drm/i915/intel_dsi_vbt.c
··· 103 103 #define CHV_GPIO_PAD_CFG1(f, i) (0x4400 + (f) * 0x400 + (i) * 8 + 4) 104 104 #define CHV_GPIO_CFGLOCK (1 << 31) 105 105 106 + /* ICL DSI Display GPIO Pins */ 107 + #define ICL_GPIO_DDSP_HPD_A 0 108 + #define ICL_GPIO_L_VDDEN_1 1 109 + #define ICL_GPIO_L_BKLTEN_1 2 110 + #define ICL_GPIO_DDPA_CTRLCLK_1 3 111 + #define ICL_GPIO_DDPA_CTRLDATA_1 4 112 + #define ICL_GPIO_DDSP_HPD_B 5 113 + #define ICL_GPIO_L_VDDEN_2 6 114 + #define ICL_GPIO_L_BKLTEN_2 7 115 + #define ICL_GPIO_DDPA_CTRLCLK_2 8 116 + #define ICL_GPIO_DDPA_CTRLDATA_2 9 117 + 106 118 static inline enum port intel_dsi_seq_port_to_port(u8 port) 107 119 { 108 120 return port ? PORT_C : PORT_A; ··· 336 324 gpiod_set_value(gpio_desc, value); 337 325 } 338 326 327 + static void icl_exec_gpio(struct drm_i915_private *dev_priv, 328 + u8 gpio_source, u8 gpio_index, bool value) 329 + { 330 + DRM_DEBUG_KMS("Skipping ICL GPIO element execution\n"); 331 + } 332 + 339 333 static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) 340 334 { 341 335 struct drm_device *dev = intel_dsi->base.base.dev; ··· 365 347 /* pull up/down */ 366 348 value = *data++ & 1; 367 349 368 - if (IS_VALLEYVIEW(dev_priv)) 350 + if (IS_ICELAKE(dev_priv)) 351 + icl_exec_gpio(dev_priv, gpio_source, gpio_index, value); 352 + else if (IS_VALLEYVIEW(dev_priv)) 369 353 vlv_exec_gpio(dev_priv, gpio_source, gpio_number, value); 370 354 else if (IS_CHERRYVIEW(dev_priv)) 371 355 chv_exec_gpio(dev_priv, gpio_source, gpio_number, value);
+4 -42
drivers/gpu/drm/i915/intel_engine_cs.c
··· 493 493 intel_engine_init_cmd_parser(engine); 494 494 } 495 495 496 - int intel_engine_create_scratch(struct intel_engine_cs *engine, 497 - unsigned int size) 498 - { 499 - struct drm_i915_gem_object *obj; 500 - struct i915_vma *vma; 501 - int ret; 502 - 503 - WARN_ON(engine->scratch); 504 - 505 - obj = i915_gem_object_create_stolen(engine->i915, size); 506 - if (!obj) 507 - obj = i915_gem_object_create_internal(engine->i915, size); 508 - if (IS_ERR(obj)) { 509 - DRM_ERROR("Failed to allocate scratch page\n"); 510 - return PTR_ERR(obj); 511 - } 512 - 513 - vma = i915_vma_instance(obj, &engine->i915->ggtt.vm, NULL); 514 - if (IS_ERR(vma)) { 515 - ret = PTR_ERR(vma); 516 - goto err_unref; 517 - } 518 - 519 - ret = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH); 520 - if (ret) 521 - goto err_unref; 522 - 523 - engine->scratch = vma; 524 - return 0; 525 - 526 - err_unref: 527 - i915_gem_object_put(obj); 528 - return ret; 529 - } 530 - 531 - void intel_engine_cleanup_scratch(struct intel_engine_cs *engine) 532 - { 533 - i915_vma_unpin_and_release(&engine->scratch, 0); 534 - } 535 - 536 496 static void cleanup_status_page(struct intel_engine_cs *engine) 537 497 { 538 498 if (HWS_NEEDS_PHYSICAL(engine->i915)) { ··· 667 707 { 668 708 struct drm_i915_private *i915 = engine->i915; 669 709 670 - intel_engine_cleanup_scratch(engine); 671 - 672 710 cleanup_status_page(engine); 673 711 674 712 intel_engine_fini_breadcrumbs(engine); ··· 681 723 __intel_context_unpin(i915->kernel_context, engine); 682 724 683 725 i915_timeline_fini(&engine->timeline); 726 + 727 + intel_wa_list_free(&engine->ctx_wa_list); 728 + intel_wa_list_free(&engine->wa_list); 729 + intel_wa_list_free(&engine->whitelist); 684 730 } 685 731 686 732 u64 intel_engine_get_active_head(const struct intel_engine_cs *engine)
+1 -1
drivers/gpu/drm/i915/intel_fbc.c
··· 1309 1309 fbc->active = false; 1310 1310 1311 1311 if (need_fbc_vtd_wa(dev_priv)) 1312 - mkwrite_device_info(dev_priv)->has_fbc = false; 1312 + mkwrite_device_info(dev_priv)->display.has_fbc = false; 1313 1313 1314 1314 i915_modparams.enable_fbc = intel_sanitize_fbc_option(dev_priv); 1315 1315 DRM_DEBUG_KMS("Sanitized enable_fbc value: %d\n",
+1 -1
drivers/gpu/drm/i915/intel_fbdev.c
··· 672 672 struct intel_fbdev *ifbdev; 673 673 int ret; 674 674 675 - if (WARN_ON(INTEL_INFO(dev_priv)->num_pipes == 0)) 675 + if (WARN_ON(!HAS_DISPLAY(dev_priv))) 676 676 return -ENODEV; 677 677 678 678 ifbdev = kzalloc(sizeof(struct intel_fbdev), GFP_KERNEL);
+19 -2
drivers/gpu/drm/i915/intel_hdmi.c
··· 115 115 switch (type) { 116 116 case DP_SDP_VSC: 117 117 return VIDEO_DIP_ENABLE_VSC_HSW; 118 + case DP_SDP_PPS: 119 + return VDIP_ENABLE_PPS; 118 120 case HDMI_INFOFRAME_TYPE_AVI: 119 121 return VIDEO_DIP_ENABLE_AVI_HSW; 120 122 case HDMI_INFOFRAME_TYPE_SPD: ··· 138 136 switch (type) { 139 137 case DP_SDP_VSC: 140 138 return HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder, i); 139 + case DP_SDP_PPS: 140 + return ICL_VIDEO_DIP_PPS_DATA(cpu_transcoder, i); 141 141 case HDMI_INFOFRAME_TYPE_AVI: 142 142 return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder, i); 143 143 case HDMI_INFOFRAME_TYPE_SPD: ··· 149 145 default: 150 146 MISSING_CASE(type); 151 147 return INVALID_MMIO_REG; 148 + } 149 + } 150 + 151 + static int hsw_dip_data_size(unsigned int type) 152 + { 153 + switch (type) { 154 + case DP_SDP_VSC: 155 + return VIDEO_DIP_VSC_DATA_SIZE; 156 + case DP_SDP_PPS: 157 + return VIDEO_DIP_PPS_DATA_SIZE; 158 + default: 159 + return VIDEO_DIP_DATA_SIZE; 152 160 } 153 161 } 154 162 ··· 398 382 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 399 383 enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 400 384 i915_reg_t ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder); 401 - int data_size = type == DP_SDP_VSC ? 402 - VIDEO_DIP_VSC_DATA_SIZE : VIDEO_DIP_DATA_SIZE; 385 + int data_size; 403 386 int i; 404 387 u32 val = I915_READ(ctl_reg); 388 + 389 + data_size = hsw_dip_data_size(type); 405 390 406 391 val &= ~hsw_infoframe_enable(type); 407 392 I915_WRITE(ctl_reg, val);
+1 -1
drivers/gpu/drm/i915/intel_i2c.c
··· 817 817 unsigned int pin; 818 818 int ret; 819 819 820 - if (INTEL_INFO(dev_priv)->num_pipes == 0) 820 + if (!HAS_DISPLAY(dev_priv)) 821 821 return 0; 822 822 823 823 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+30 -53
drivers/gpu/drm/i915/intel_lrc.c
··· 767 767 768 768 static void reset_csb_pointers(struct intel_engine_execlists *execlists) 769 769 { 770 + const unsigned int reset_value = GEN8_CSB_ENTRIES - 1; 771 + 770 772 /* 771 773 * After a reset, the HW starts writing into CSB entry [0]. We 772 774 * therefore have to set our HEAD pointer back one entry so that ··· 778 776 * inline comparison of our cached head position against the last HW 779 777 * write works even before the first interrupt. 780 778 */ 781 - execlists->csb_head = execlists->csb_write_reset; 782 - WRITE_ONCE(*execlists->csb_write, execlists->csb_write_reset); 779 + execlists->csb_head = reset_value; 780 + WRITE_ONCE(*execlists->csb_write, reset_value); 783 781 } 784 782 785 783 static void nop_submission_tasklet(unsigned long data) ··· 820 818 /* Mark all executing requests as skipped. */ 821 819 list_for_each_entry(rq, &engine->timeline.requests, link) { 822 820 GEM_BUG_ON(!rq->global_seqno); 823 - if (!i915_request_completed(rq)) 824 - dma_fence_set_error(&rq->fence, -EIO); 821 + 822 + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &rq->fence.flags)) 823 + continue; 824 + 825 + dma_fence_set_error(&rq->fence, -EIO); 825 826 } 826 827 827 828 /* Flush the queued requests to the timeline list (for retiring). */ ··· 843 838 if (p->priority != I915_PRIORITY_NORMAL) 844 839 kmem_cache_free(engine->i915->priorities, p); 845 840 } 841 + 842 + intel_write_status_page(engine, 843 + I915_GEM_HWS_INDEX, 844 + intel_engine_last_submit(engine)); 846 845 847 846 /* Remaining _unready_ requests will be nop'ed when submitted */ 848 847 ··· 1288 1279 static u32 * 1289 1280 gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine, u32 *batch) 1290 1281 { 1282 + /* NB no one else is allowed to scribble over scratch + 256! */ 1291 1283 *batch++ = MI_STORE_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT; 1292 1284 *batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4); 1293 - *batch++ = i915_ggtt_offset(engine->scratch) + 256; 1285 + *batch++ = i915_scratch_offset(engine->i915) + 256; 1294 1286 *batch++ = 0; 1295 1287 1296 1288 *batch++ = MI_LOAD_REGISTER_IMM(1); ··· 1305 1295 1306 1296 *batch++ = MI_LOAD_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT; 1307 1297 *batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4); 1308 - *batch++ = i915_ggtt_offset(engine->scratch) + 256; 1298 + *batch++ = i915_scratch_offset(engine->i915) + 256; 1309 1299 *batch++ = 0; 1310 1300 1311 1301 return batch; ··· 1342 1332 PIPE_CONTROL_GLOBAL_GTT_IVB | 1343 1333 PIPE_CONTROL_CS_STALL | 1344 1334 PIPE_CONTROL_QW_WRITE, 1345 - i915_ggtt_offset(engine->scratch) + 1335 + i915_scratch_offset(engine->i915) + 1346 1336 2 * CACHELINE_BYTES); 1347 1337 1348 1338 *batch++ = MI_ARB_ON_OFF | MI_ARB_ENABLE; ··· 1410 1400 batch = gen8_emit_flush_coherentl3_wa(engine, batch); 1411 1401 1412 1402 batch = emit_lri(batch, lri, ARRAY_SIZE(lri)); 1413 - 1414 - /* WaClearSlmSpaceAtContextSwitch:kbl */ 1415 - /* Actual scratch location is at 128 bytes offset */ 1416 - if (IS_KBL_REVID(engine->i915, 0, KBL_REVID_A0)) { 1417 - batch = gen8_emit_pipe_control(batch, 1418 - PIPE_CONTROL_FLUSH_L3 | 1419 - PIPE_CONTROL_GLOBAL_GTT_IVB | 1420 - PIPE_CONTROL_CS_STALL | 1421 - PIPE_CONTROL_QW_WRITE, 1422 - i915_ggtt_offset(engine->scratch) 1423 - + 2 * CACHELINE_BYTES); 1424 - } 1425 1403 1426 1404 /* WaMediaPoolStateCmdInWABB:bxt,glk */ 1427 1405 if (HAS_POOLED_EU(engine->i915)) { ··· 1627 1629 1628 1630 static int gen8_init_common_ring(struct intel_engine_cs *engine) 1629 1631 { 1632 + intel_engine_apply_workarounds(engine); 1633 + 1630 1634 intel_mocs_init_engine(engine); 1631 1635 1632 1636 intel_engine_reset_breadcrumbs(engine); ··· 1653 1653 if (ret) 1654 1654 return ret; 1655 1655 1656 - intel_whitelist_workarounds_apply(engine); 1656 + intel_engine_apply_whitelist(engine); 1657 1657 1658 1658 /* We need to disable the AsyncFlip performance optimisations in order 1659 1659 * to use MI_WAIT_FOR_EVENT within the CS. It should already be ··· 1676 1676 if (ret) 1677 1677 return ret; 1678 1678 1679 - intel_whitelist_workarounds_apply(engine); 1679 + intel_engine_apply_whitelist(engine); 1680 1680 1681 1681 return 0; 1682 1682 } ··· 1974 1974 { 1975 1975 struct intel_engine_cs *engine = request->engine; 1976 1976 u32 scratch_addr = 1977 - i915_ggtt_offset(engine->scratch) + 2 * CACHELINE_BYTES; 1977 + i915_scratch_offset(engine->i915) + 2 * CACHELINE_BYTES; 1978 1978 bool vf_flush_wa = false, dc_flush_wa = false; 1979 1979 u32 *cs, flags = 0; 1980 1980 int len; ··· 2088 2088 { 2089 2089 int ret; 2090 2090 2091 - ret = intel_ctx_workarounds_emit(rq); 2091 + ret = intel_engine_emit_ctx_wa(rq); 2092 2092 if (ret) 2093 2093 return ret; 2094 2094 ··· 2229 2229 logical_ring_default_irqs(engine); 2230 2230 } 2231 2231 2232 - static bool csb_force_mmio(struct drm_i915_private *i915) 2233 - { 2234 - /* Older GVT emulation depends upon intercepting CSB mmio */ 2235 - return intel_vgpu_active(i915) && !intel_vgpu_has_hwsp_emulation(i915); 2236 - } 2237 - 2238 2232 static int logical_ring_init(struct intel_engine_cs *engine) 2239 2233 { 2240 2234 struct drm_i915_private *i915 = engine->i915; ··· 2258 2264 upper_32_bits(ce->lrc_desc); 2259 2265 } 2260 2266 2261 - execlists->csb_read = 2262 - i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine)); 2263 - if (csb_force_mmio(i915)) { 2264 - execlists->csb_status = (u32 __force *) 2265 - (i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); 2267 + execlists->csb_status = 2268 + &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; 2266 2269 2267 - execlists->csb_write = (u32 __force *)execlists->csb_read; 2268 - execlists->csb_write_reset = 2269 - _MASKED_FIELD(GEN8_CSB_WRITE_PTR_MASK, 2270 - GEN8_CSB_ENTRIES - 1); 2271 - } else { 2272 - execlists->csb_status = 2273 - &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; 2270 + execlists->csb_write = 2271 + &engine->status_page.page_addr[intel_hws_csb_write_index(i915)]; 2274 2272 2275 - execlists->csb_write = 2276 - &engine->status_page.page_addr[intel_hws_csb_write_index(i915)]; 2277 - execlists->csb_write_reset = GEN8_CSB_ENTRIES - 1; 2278 - } 2279 2273 reset_csb_pointers(execlists); 2280 2274 2281 2275 return 0; ··· 2293 2311 if (ret) 2294 2312 return ret; 2295 2313 2296 - ret = intel_engine_create_scratch(engine, PAGE_SIZE); 2297 - if (ret) 2298 - goto err_cleanup_common; 2299 - 2300 2314 ret = intel_init_workaround_bb(engine); 2301 2315 if (ret) { 2302 2316 /* ··· 2304 2326 ret); 2305 2327 } 2306 2328 2307 - return 0; 2329 + intel_engine_init_whitelist(engine); 2330 + intel_engine_init_workarounds(engine); 2308 2331 2309 - err_cleanup_common: 2310 - intel_engine_cleanup_common(engine); 2311 - return ret; 2332 + return 0; 2312 2333 } 2313 2334 2314 2335 int logical_xcs_ring_init(struct intel_engine_cs *engine)
+3 -3
drivers/gpu/drm/i915/intel_opregion.h
··· 87 87 { 88 88 } 89 89 90 - void intel_opregion_resume(struct drm_i915_private *dev_priv) 90 + static inline void intel_opregion_resume(struct drm_i915_private *dev_priv) 91 91 { 92 92 } 93 93 94 - void intel_opregion_suspend(struct drm_i915_private *dev_priv, 95 - pci_power_t state) 94 + static inline void intel_opregion_suspend(struct drm_i915_private *dev_priv, 95 + pci_power_t state) 96 96 { 97 97 } 98 98
+312 -281
drivers/gpu/drm/i915/intel_pm.c
··· 3951 3951 skl_ddb_get_hw_plane_state(struct drm_i915_private *dev_priv, 3952 3952 const enum pipe pipe, 3953 3953 const enum plane_id plane_id, 3954 - struct skl_ddb_allocation *ddb /* out */) 3954 + struct skl_ddb_entry *ddb_y, 3955 + struct skl_ddb_entry *ddb_uv) 3955 3956 { 3956 - u32 val, val2 = 0; 3957 - int fourcc, pixel_format; 3957 + u32 val, val2; 3958 + u32 fourcc = 0; 3958 3959 3959 3960 /* Cursor doesn't support NV12/planar, so no extra calculation needed */ 3960 3961 if (plane_id == PLANE_CURSOR) { 3961 3962 val = I915_READ(CUR_BUF_CFG(pipe)); 3962 - skl_ddb_entry_init_from_hw(dev_priv, 3963 - &ddb->plane[pipe][plane_id], val); 3963 + skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val); 3964 3964 return; 3965 3965 } 3966 3966 3967 3967 val = I915_READ(PLANE_CTL(pipe, plane_id)); 3968 3968 3969 3969 /* No DDB allocated for disabled planes */ 3970 - if (!(val & PLANE_CTL_ENABLE)) 3971 - return; 3970 + if (val & PLANE_CTL_ENABLE) 3971 + fourcc = skl_format_to_fourcc(val & PLANE_CTL_FORMAT_MASK, 3972 + val & PLANE_CTL_ORDER_RGBX, 3973 + val & PLANE_CTL_ALPHA_MASK); 3972 3974 3973 - pixel_format = val & PLANE_CTL_FORMAT_MASK; 3974 - fourcc = skl_format_to_fourcc(pixel_format, 3975 - val & PLANE_CTL_ORDER_RGBX, 3976 - val & PLANE_CTL_ALPHA_MASK); 3977 - 3978 - val = I915_READ(PLANE_BUF_CFG(pipe, plane_id)); 3979 - if (fourcc == DRM_FORMAT_NV12 && INTEL_GEN(dev_priv) < 11) { 3975 + if (INTEL_GEN(dev_priv) >= 11) { 3976 + val = I915_READ(PLANE_BUF_CFG(pipe, plane_id)); 3977 + skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val); 3978 + } else { 3979 + val = I915_READ(PLANE_BUF_CFG(pipe, plane_id)); 3980 3980 val2 = I915_READ(PLANE_NV12_BUF_CFG(pipe, plane_id)); 3981 3981 3982 - skl_ddb_entry_init_from_hw(dev_priv, 3983 - &ddb->plane[pipe][plane_id], val2); 3984 - skl_ddb_entry_init_from_hw(dev_priv, 3985 - &ddb->uv_plane[pipe][plane_id], val); 3986 - } else { 3987 - skl_ddb_entry_init_from_hw(dev_priv, 3988 - &ddb->plane[pipe][plane_id], val); 3982 + if (fourcc == DRM_FORMAT_NV12) 3983 + swap(val, val2); 3984 + 3985 + skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val); 3986 + skl_ddb_entry_init_from_hw(dev_priv, ddb_uv, val2); 3989 3987 } 3988 + } 3989 + 3990 + void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc, 3991 + struct skl_ddb_entry *ddb_y, 3992 + struct skl_ddb_entry *ddb_uv) 3993 + { 3994 + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 3995 + enum intel_display_power_domain power_domain; 3996 + enum pipe pipe = crtc->pipe; 3997 + enum plane_id plane_id; 3998 + 3999 + power_domain = POWER_DOMAIN_PIPE(pipe); 4000 + if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) 4001 + return; 4002 + 4003 + for_each_plane_id_on_crtc(crtc, plane_id) 4004 + skl_ddb_get_hw_plane_state(dev_priv, pipe, 4005 + plane_id, 4006 + &ddb_y[plane_id], 4007 + &ddb_uv[plane_id]); 4008 + 4009 + intel_display_power_put(dev_priv, power_domain); 3990 4010 } 3991 4011 3992 4012 void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, 3993 4013 struct skl_ddb_allocation *ddb /* out */) 3994 4014 { 3995 - struct intel_crtc *crtc; 3996 - 3997 - memset(ddb, 0, sizeof(*ddb)); 3998 - 3999 4015 ddb->enabled_slices = intel_enabled_dbuf_slices_num(dev_priv); 4000 - 4001 - for_each_intel_crtc(&dev_priv->drm, crtc) { 4002 - enum intel_display_power_domain power_domain; 4003 - enum plane_id plane_id; 4004 - enum pipe pipe = crtc->pipe; 4005 - 4006 - power_domain = POWER_DOMAIN_PIPE(pipe); 4007 - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) 4008 - continue; 4009 - 4010 - for_each_plane_id_on_crtc(crtc, plane_id) 4011 - skl_ddb_get_hw_plane_state(dev_priv, pipe, 4012 - plane_id, ddb); 4013 - 4014 - intel_display_power_put(dev_priv, power_domain); 4015 - } 4016 4016 } 4017 4017 4018 4018 /* ··· 4410 4410 struct drm_crtc *crtc = cstate->base.crtc; 4411 4411 struct drm_i915_private *dev_priv = to_i915(crtc->dev); 4412 4412 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 4413 - enum pipe pipe = intel_crtc->pipe; 4414 4413 struct skl_ddb_entry *alloc = &cstate->wm.skl.ddb; 4415 4414 uint16_t alloc_size, start; 4416 4415 uint16_t minimum[I915_MAX_PLANES] = {}; ··· 4422 4423 uint16_t total_min_blocks = 0; 4423 4424 4424 4425 /* Clear the partitioning for disabled planes. */ 4425 - memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); 4426 - memset(ddb->uv_plane[pipe], 0, sizeof(ddb->uv_plane[pipe])); 4426 + memset(cstate->wm.skl.plane_ddb_y, 0, sizeof(cstate->wm.skl.plane_ddb_y)); 4427 + memset(cstate->wm.skl.plane_ddb_uv, 0, sizeof(cstate->wm.skl.plane_ddb_uv)); 4427 4428 4428 4429 if (WARN_ON(!state)) 4429 4430 return 0; ··· 4470 4471 } 4471 4472 4472 4473 alloc_size -= total_min_blocks; 4473 - ddb->plane[pipe][PLANE_CURSOR].start = alloc->end - minimum[PLANE_CURSOR]; 4474 - ddb->plane[pipe][PLANE_CURSOR].end = alloc->end; 4474 + cstate->wm.skl.plane_ddb_y[PLANE_CURSOR].start = alloc->end - minimum[PLANE_CURSOR]; 4475 + cstate->wm.skl.plane_ddb_y[PLANE_CURSOR].end = alloc->end; 4475 4476 4476 4477 /* 4477 4478 * 2. Distribute the remaining space in proportion to the amount of ··· 4502 4503 4503 4504 /* Leave disabled planes at (0,0) */ 4504 4505 if (data_rate) { 4505 - ddb->plane[pipe][plane_id].start = start; 4506 - ddb->plane[pipe][plane_id].end = start + plane_blocks; 4506 + cstate->wm.skl.plane_ddb_y[plane_id].start = start; 4507 + cstate->wm.skl.plane_ddb_y[plane_id].end = start + plane_blocks; 4507 4508 } 4508 4509 4509 4510 start += plane_blocks; ··· 4518 4519 WARN_ON(INTEL_GEN(dev_priv) >= 11 && uv_plane_blocks); 4519 4520 4520 4521 if (uv_data_rate) { 4521 - ddb->uv_plane[pipe][plane_id].start = start; 4522 - ddb->uv_plane[pipe][plane_id].end = 4522 + cstate->wm.skl.plane_ddb_uv[plane_id].start = start; 4523 + cstate->wm.skl.plane_ddb_uv[plane_id].end = 4523 4524 start + uv_plane_blocks; 4524 4525 } 4525 4526 ··· 4616 4617 } 4617 4618 4618 4619 static int 4619 - skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv, 4620 - const struct intel_crtc_state *cstate, 4620 + skl_compute_plane_wm_params(const struct intel_crtc_state *cstate, 4621 4621 const struct intel_plane_state *intel_pstate, 4622 - struct skl_wm_params *wp, int plane_id) 4622 + struct skl_wm_params *wp, int color_plane) 4623 4623 { 4624 4624 struct intel_plane *plane = to_intel_plane(intel_pstate->base.plane); 4625 + struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 4625 4626 const struct drm_plane_state *pstate = &intel_pstate->base; 4626 4627 const struct drm_framebuffer *fb = pstate->fb; 4627 4628 uint32_t interm_pbpl; ··· 4629 4630 to_intel_atomic_state(cstate->base.state); 4630 4631 bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state); 4631 4632 4632 - if (!intel_wm_plane_visible(cstate, intel_pstate)) 4633 - return 0; 4634 - 4635 4633 /* only NV12 format has two planes */ 4636 - if (plane_id == 1 && fb->format->format != DRM_FORMAT_NV12) { 4634 + if (color_plane == 1 && fb->format->format != DRM_FORMAT_NV12) { 4637 4635 DRM_DEBUG_KMS("Non NV12 format have single plane\n"); 4638 4636 return -EINVAL; 4639 4637 } ··· 4655 4659 wp->width = drm_rect_width(&intel_pstate->base.src) >> 16; 4656 4660 } 4657 4661 4658 - if (plane_id == 1 && wp->is_planar) 4662 + if (color_plane == 1 && wp->is_planar) 4659 4663 wp->width /= 2; 4660 4664 4661 - wp->cpp = fb->format->cpp[plane_id]; 4665 + wp->cpp = fb->format->cpp[color_plane]; 4662 4666 wp->plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, 4663 4667 intel_pstate); 4664 4668 ··· 4720 4724 return 0; 4721 4725 } 4722 4726 4723 - static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv, 4724 - const struct intel_crtc_state *cstate, 4727 + static int skl_compute_plane_wm(const struct intel_crtc_state *cstate, 4725 4728 const struct intel_plane_state *intel_pstate, 4726 4729 uint16_t ddb_allocation, 4727 4730 int level, ··· 4728 4733 const struct skl_wm_level *result_prev, 4729 4734 struct skl_wm_level *result /* out */) 4730 4735 { 4736 + struct drm_i915_private *dev_priv = 4737 + to_i915(intel_pstate->base.plane->dev); 4731 4738 const struct drm_plane_state *pstate = &intel_pstate->base; 4732 4739 uint32_t latency = dev_priv->wm.skl_latency[level]; 4733 4740 uint_fixed_16_16_t method1, method2; ··· 4740 4743 bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state); 4741 4744 uint32_t min_disp_buf_needed; 4742 4745 4743 - if (latency == 0 || 4744 - !intel_wm_plane_visible(cstate, intel_pstate)) { 4745 - result->plane_en = false; 4746 - return 0; 4747 - } 4746 + if (latency == 0) 4747 + return level == 0 ? -EINVAL : 0; 4748 4748 4749 4749 /* Display WA #1141: kbl,cfl */ 4750 4750 if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv) || ··· 4838 4844 if ((level > 0 && res_lines > 31) || 4839 4845 res_blocks >= ddb_allocation || 4840 4846 min_disp_buf_needed >= ddb_allocation) { 4841 - result->plane_en = false; 4842 - 4843 4847 /* 4844 4848 * If there are no valid level 0 watermarks, then we can't 4845 4849 * support this display configuration. ··· 4864 4872 } 4865 4873 4866 4874 static int 4867 - skl_compute_wm_levels(const struct drm_i915_private *dev_priv, 4868 - struct skl_ddb_allocation *ddb, 4869 - const struct intel_crtc_state *cstate, 4875 + skl_compute_wm_levels(const struct intel_crtc_state *cstate, 4870 4876 const struct intel_plane_state *intel_pstate, 4871 4877 uint16_t ddb_blocks, 4872 4878 const struct skl_wm_params *wm_params, 4873 - struct skl_plane_wm *wm, 4874 4879 struct skl_wm_level *levels) 4875 4880 { 4881 + struct drm_i915_private *dev_priv = 4882 + to_i915(intel_pstate->base.plane->dev); 4876 4883 int level, max_level = ilk_wm_max_level(dev_priv); 4877 4884 struct skl_wm_level *result_prev = &levels[0]; 4878 4885 int ret; 4879 4886 4880 - if (WARN_ON(!intel_pstate->base.fb)) 4881 - return -EINVAL; 4882 - 4883 4887 for (level = 0; level <= max_level; level++) { 4884 4888 struct skl_wm_level *result = &levels[level]; 4885 4889 4886 - ret = skl_compute_plane_wm(dev_priv, 4887 - cstate, 4890 + ret = skl_compute_plane_wm(cstate, 4888 4891 intel_pstate, 4889 4892 ddb_blocks, 4890 4893 level, ··· 4891 4904 4892 4905 result_prev = result; 4893 4906 } 4894 - 4895 - if (intel_pstate->base.fb->format->format == DRM_FORMAT_NV12) 4896 - wm->is_planar = true; 4897 4907 4898 4908 return 0; 4899 4909 } ··· 4919 4935 } 4920 4936 4921 4937 static void skl_compute_transition_wm(const struct intel_crtc_state *cstate, 4922 - struct skl_wm_params *wp, 4923 - struct skl_wm_level *wm_l0, 4924 - uint16_t ddb_allocation, 4925 - struct skl_wm_level *trans_wm /* out */) 4938 + const struct skl_wm_params *wp, 4939 + struct skl_plane_wm *wm, 4940 + uint16_t ddb_allocation) 4926 4941 { 4927 4942 struct drm_device *dev = cstate->base.crtc->dev; 4928 4943 const struct drm_i915_private *dev_priv = to_i915(dev); ··· 4929 4946 const uint16_t trans_amount = 10; /* This is configurable amount */ 4930 4947 uint16_t wm0_sel_res_b, trans_offset_b, res_blocks; 4931 4948 4932 - if (!cstate->base.active) 4933 - goto exit; 4934 - 4935 4949 /* Transition WM are not recommended by HW team for GEN9 */ 4936 4950 if (INTEL_GEN(dev_priv) <= 9) 4937 - goto exit; 4951 + return; 4938 4952 4939 4953 /* Transition WM don't make any sense if ipc is disabled */ 4940 4954 if (!dev_priv->ipc_enabled) 4941 - goto exit; 4955 + return; 4942 4956 4943 4957 trans_min = 14; 4944 4958 if (INTEL_GEN(dev_priv) >= 11) ··· 4953 4973 * Result Blocks is Result Blocks minus 1 and it should work for the 4954 4974 * current platforms. 4955 4975 */ 4956 - wm0_sel_res_b = wm_l0->plane_res_b - 1; 4976 + wm0_sel_res_b = wm->wm[0].plane_res_b - 1; 4957 4977 4958 4978 if (wp->y_tiled) { 4959 4979 trans_y_tile_min = (uint16_t) mul_round_up_u32_fixed16(2, ··· 4972 4992 res_blocks += 1; 4973 4993 4974 4994 if (res_blocks < ddb_allocation) { 4975 - trans_wm->plane_res_b = res_blocks; 4976 - trans_wm->plane_en = true; 4977 - return; 4995 + wm->trans_wm.plane_res_b = res_blocks; 4996 + wm->trans_wm.plane_en = true; 4978 4997 } 4979 - 4980 - exit: 4981 - trans_wm->plane_en = false; 4982 4998 } 4983 4999 4984 - static int __skl_build_plane_wm_single(struct skl_ddb_allocation *ddb, 4985 - struct skl_pipe_wm *pipe_wm, 4986 - enum plane_id plane_id, 4987 - const struct intel_crtc_state *cstate, 4988 - const struct intel_plane_state *pstate, 4989 - int color_plane) 5000 + static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state, 5001 + const struct intel_plane_state *plane_state, 5002 + enum plane_id plane_id, int color_plane) 4990 5003 { 4991 - struct drm_i915_private *dev_priv = to_i915(pstate->base.plane->dev); 4992 - struct skl_plane_wm *wm = &pipe_wm->planes[plane_id]; 4993 - enum pipe pipe = to_intel_plane(pstate->base.plane)->pipe; 5004 + struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id]; 5005 + u16 ddb_blocks = skl_ddb_entry_size(&crtc_state->wm.skl.plane_ddb_y[plane_id]); 4994 5006 struct skl_wm_params wm_params; 4995 - uint16_t ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]); 4996 5007 int ret; 4997 5008 4998 - ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate, 5009 + ret = skl_compute_plane_wm_params(crtc_state, plane_state, 4999 5010 &wm_params, color_plane); 5000 5011 if (ret) 5001 5012 return ret; 5002 5013 5003 - ret = skl_compute_wm_levels(dev_priv, ddb, cstate, pstate, 5004 - ddb_blocks, &wm_params, wm, wm->wm); 5005 - 5014 + ret = skl_compute_wm_levels(crtc_state, plane_state, 5015 + ddb_blocks, &wm_params, wm->wm); 5006 5016 if (ret) 5007 5017 return ret; 5008 5018 5009 - skl_compute_transition_wm(cstate, &wm_params, &wm->wm[0], 5010 - ddb_blocks, &wm->trans_wm); 5019 + skl_compute_transition_wm(crtc_state, &wm_params, wm, ddb_blocks); 5011 5020 5012 5021 return 0; 5013 5022 } 5014 5023 5015 - static int skl_build_plane_wm_single(struct skl_ddb_allocation *ddb, 5016 - struct skl_pipe_wm *pipe_wm, 5017 - const struct intel_crtc_state *cstate, 5018 - const struct intel_plane_state *pstate) 5024 + static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state, 5025 + const struct intel_plane_state *plane_state, 5026 + enum plane_id plane_id) 5019 5027 { 5020 - enum plane_id plane_id = to_intel_plane(pstate->base.plane)->id; 5021 - 5022 - return __skl_build_plane_wm_single(ddb, pipe_wm, plane_id, cstate, pstate, 0); 5023 - } 5024 - 5025 - static int skl_build_plane_wm_planar(struct skl_ddb_allocation *ddb, 5026 - struct skl_pipe_wm *pipe_wm, 5027 - const struct intel_crtc_state *cstate, 5028 - const struct intel_plane_state *pstate) 5029 - { 5030 - struct intel_plane *plane = to_intel_plane(pstate->base.plane); 5031 - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 5032 - enum plane_id plane_id = plane->id; 5033 - struct skl_plane_wm *wm = &pipe_wm->planes[plane_id]; 5028 + struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id]; 5029 + u16 ddb_blocks = skl_ddb_entry_size(&crtc_state->wm.skl.plane_ddb_uv[plane_id]); 5034 5030 struct skl_wm_params wm_params; 5035 - enum pipe pipe = plane->pipe; 5036 - uint16_t ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]); 5037 5031 int ret; 5038 5032 5039 - ret = __skl_build_plane_wm_single(ddb, pipe_wm, plane_id, cstate, pstate, 0); 5040 - if (ret) 5041 - return ret; 5033 + wm->is_planar = true; 5042 5034 5043 5035 /* uv plane watermarks must also be validated for NV12/Planar */ 5044 - ddb_blocks = skl_ddb_entry_size(&ddb->uv_plane[pipe][plane_id]); 5045 - 5046 - ret = skl_compute_plane_wm_params(dev_priv, cstate, pstate, &wm_params, 1); 5036 + ret = skl_compute_plane_wm_params(crtc_state, plane_state, 5037 + &wm_params, 1); 5047 5038 if (ret) 5048 5039 return ret; 5049 5040 5050 - return skl_compute_wm_levels(dev_priv, ddb, cstate, pstate, 5051 - ddb_blocks, &wm_params, wm, wm->uv_wm); 5041 + ret = skl_compute_wm_levels(crtc_state, plane_state, 5042 + ddb_blocks, &wm_params, wm->uv_wm); 5043 + if (ret) 5044 + return ret; 5045 + 5046 + return 0; 5052 5047 } 5053 5048 5054 - static int icl_build_plane_wm_planar(struct skl_ddb_allocation *ddb, 5055 - struct skl_pipe_wm *pipe_wm, 5056 - const struct intel_crtc_state *cstate, 5057 - const struct intel_plane_state *pstate) 5049 + static int skl_build_plane_wm(struct skl_pipe_wm *pipe_wm, 5050 + struct intel_crtc_state *crtc_state, 5051 + const struct intel_plane_state *plane_state) 5058 5052 { 5053 + struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 5054 + const struct drm_framebuffer *fb = plane_state->base.fb; 5055 + enum plane_id plane_id = plane->id; 5059 5056 int ret; 5060 - enum plane_id y_plane_id = pstate->linked_plane->id; 5061 - enum plane_id uv_plane_id = to_intel_plane(pstate->base.plane)->id; 5062 5057 5063 - ret = __skl_build_plane_wm_single(ddb, pipe_wm, y_plane_id, 5064 - cstate, pstate, 0); 5058 + if (!intel_wm_plane_visible(crtc_state, plane_state)) 5059 + return 0; 5060 + 5061 + ret = skl_build_plane_wm_single(crtc_state, plane_state, 5062 + plane_id, 0); 5065 5063 if (ret) 5066 5064 return ret; 5067 5065 5068 - return __skl_build_plane_wm_single(ddb, pipe_wm, uv_plane_id, 5069 - cstate, pstate, 1); 5066 + if (fb->format->is_yuv && fb->format->num_planes > 1) { 5067 + ret = skl_build_plane_wm_uv(crtc_state, plane_state, 5068 + plane_id); 5069 + if (ret) 5070 + return ret; 5071 + } 5072 + 5073 + return 0; 5074 + } 5075 + 5076 + static int icl_build_plane_wm(struct skl_pipe_wm *pipe_wm, 5077 + struct intel_crtc_state *crtc_state, 5078 + const struct intel_plane_state *plane_state) 5079 + { 5080 + enum plane_id plane_id = to_intel_plane(plane_state->base.plane)->id; 5081 + int ret; 5082 + 5083 + /* Watermarks calculated in master */ 5084 + if (plane_state->slave) 5085 + return 0; 5086 + 5087 + if (plane_state->linked_plane) { 5088 + const struct drm_framebuffer *fb = plane_state->base.fb; 5089 + enum plane_id y_plane_id = plane_state->linked_plane->id; 5090 + 5091 + WARN_ON(!intel_wm_plane_visible(crtc_state, plane_state)); 5092 + WARN_ON(!fb->format->is_yuv || 5093 + fb->format->num_planes == 1); 5094 + 5095 + ret = skl_build_plane_wm_single(crtc_state, plane_state, 5096 + y_plane_id, 0); 5097 + if (ret) 5098 + return ret; 5099 + 5100 + ret = skl_build_plane_wm_single(crtc_state, plane_state, 5101 + plane_id, 1); 5102 + if (ret) 5103 + return ret; 5104 + } else if (intel_wm_plane_visible(crtc_state, plane_state)) { 5105 + ret = skl_build_plane_wm_single(crtc_state, plane_state, 5106 + plane_id, 0); 5107 + if (ret) 5108 + return ret; 5109 + } 5110 + 5111 + return 0; 5070 5112 } 5071 5113 5072 5114 static int skl_build_pipe_wm(struct intel_crtc_state *cstate, 5073 - struct skl_ddb_allocation *ddb, 5074 5115 struct skl_pipe_wm *pipe_wm) 5075 5116 { 5117 + struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev); 5076 5118 struct drm_crtc_state *crtc_state = &cstate->base; 5077 5119 struct drm_plane *plane; 5078 5120 const struct drm_plane_state *pstate; ··· 5110 5108 const struct intel_plane_state *intel_pstate = 5111 5109 to_intel_plane_state(pstate); 5112 5110 5113 - /* Watermarks calculated in master */ 5114 - if (intel_pstate->slave) 5115 - continue; 5116 - 5117 - if (intel_pstate->linked_plane) 5118 - ret = icl_build_plane_wm_planar(ddb, pipe_wm, cstate, intel_pstate); 5119 - else if (intel_pstate->base.fb && 5120 - intel_pstate->base.fb->format->format == DRM_FORMAT_NV12) 5121 - ret = skl_build_plane_wm_planar(ddb, pipe_wm, cstate, intel_pstate); 5111 + if (INTEL_GEN(dev_priv) >= 11) 5112 + ret = icl_build_plane_wm(pipe_wm, 5113 + cstate, intel_pstate); 5122 5114 else 5123 - ret = skl_build_plane_wm_single(ddb, pipe_wm, cstate, intel_pstate); 5124 - 5115 + ret = skl_build_plane_wm(pipe_wm, 5116 + cstate, intel_pstate); 5125 5117 if (ret) 5126 5118 return ret; 5127 5119 } ··· 5130 5134 const struct skl_ddb_entry *entry) 5131 5135 { 5132 5136 if (entry->end) 5133 - I915_WRITE(reg, (entry->end - 1) << 16 | entry->start); 5137 + I915_WRITE_FW(reg, (entry->end - 1) << 16 | entry->start); 5134 5138 else 5135 - I915_WRITE(reg, 0); 5139 + I915_WRITE_FW(reg, 0); 5136 5140 } 5137 5141 5138 5142 static void skl_write_wm_level(struct drm_i915_private *dev_priv, ··· 5147 5151 val |= level->plane_res_l << PLANE_WM_LINES_SHIFT; 5148 5152 } 5149 5153 5150 - I915_WRITE(reg, val); 5154 + I915_WRITE_FW(reg, val); 5151 5155 } 5152 5156 5153 - static void skl_write_plane_wm(struct intel_crtc *intel_crtc, 5154 - const struct skl_plane_wm *wm, 5155 - const struct skl_ddb_allocation *ddb, 5156 - enum plane_id plane_id) 5157 + void skl_write_plane_wm(struct intel_plane *plane, 5158 + const struct intel_crtc_state *crtc_state) 5157 5159 { 5158 - struct drm_crtc *crtc = &intel_crtc->base; 5159 - struct drm_device *dev = crtc->dev; 5160 - struct drm_i915_private *dev_priv = to_i915(dev); 5160 + struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 5161 5161 int level, max_level = ilk_wm_max_level(dev_priv); 5162 - enum pipe pipe = intel_crtc->pipe; 5162 + enum plane_id plane_id = plane->id; 5163 + enum pipe pipe = plane->pipe; 5164 + const struct skl_plane_wm *wm = 5165 + &crtc_state->wm.skl.optimal.planes[plane_id]; 5166 + const struct skl_ddb_entry *ddb_y = 5167 + &crtc_state->wm.skl.plane_ddb_y[plane_id]; 5168 + const struct skl_ddb_entry *ddb_uv = 5169 + &crtc_state->wm.skl.plane_ddb_uv[plane_id]; 5163 5170 5164 5171 for (level = 0; level <= max_level; level++) { 5165 5172 skl_write_wm_level(dev_priv, PLANE_WM(pipe, plane_id, level), ··· 5171 5172 skl_write_wm_level(dev_priv, PLANE_WM_TRANS(pipe, plane_id), 5172 5173 &wm->trans_wm); 5173 5174 5174 - if (wm->is_planar && INTEL_GEN(dev_priv) < 11) { 5175 - skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id), 5176 - &ddb->uv_plane[pipe][plane_id]); 5175 + if (INTEL_GEN(dev_priv) >= 11) { 5177 5176 skl_ddb_entry_write(dev_priv, 5178 - PLANE_NV12_BUF_CFG(pipe, plane_id), 5179 - &ddb->plane[pipe][plane_id]); 5180 - } else { 5181 - skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id), 5182 - &ddb->plane[pipe][plane_id]); 5183 - if (INTEL_GEN(dev_priv) < 11) 5184 - I915_WRITE(PLANE_NV12_BUF_CFG(pipe, plane_id), 0x0); 5177 + PLANE_BUF_CFG(pipe, plane_id), ddb_y); 5178 + return; 5185 5179 } 5180 + 5181 + if (wm->is_planar) 5182 + swap(ddb_y, ddb_uv); 5183 + 5184 + skl_ddb_entry_write(dev_priv, 5185 + PLANE_BUF_CFG(pipe, plane_id), ddb_y); 5186 + skl_ddb_entry_write(dev_priv, 5187 + PLANE_NV12_BUF_CFG(pipe, plane_id), ddb_uv); 5186 5188 } 5187 5189 5188 - static void skl_write_cursor_wm(struct intel_crtc *intel_crtc, 5189 - const struct skl_plane_wm *wm, 5190 - const struct skl_ddb_allocation *ddb) 5190 + void skl_write_cursor_wm(struct intel_plane *plane, 5191 + const struct intel_crtc_state *crtc_state) 5191 5192 { 5192 - struct drm_crtc *crtc = &intel_crtc->base; 5193 - struct drm_device *dev = crtc->dev; 5194 - struct drm_i915_private *dev_priv = to_i915(dev); 5193 + struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 5195 5194 int level, max_level = ilk_wm_max_level(dev_priv); 5196 - enum pipe pipe = intel_crtc->pipe; 5195 + enum plane_id plane_id = plane->id; 5196 + enum pipe pipe = plane->pipe; 5197 + const struct skl_plane_wm *wm = 5198 + &crtc_state->wm.skl.optimal.planes[plane_id]; 5199 + const struct skl_ddb_entry *ddb = 5200 + &crtc_state->wm.skl.plane_ddb_y[plane_id]; 5197 5201 5198 5202 for (level = 0; level <= max_level; level++) { 5199 5203 skl_write_wm_level(dev_priv, CUR_WM(pipe, level), ··· 5204 5202 } 5205 5203 skl_write_wm_level(dev_priv, CUR_WM_TRANS(pipe), &wm->trans_wm); 5206 5204 5207 - skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), 5208 - &ddb->plane[pipe][PLANE_CURSOR]); 5205 + skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), ddb); 5209 5206 } 5210 5207 5211 5208 bool skl_wm_level_equals(const struct skl_wm_level *l1, 5212 5209 const struct skl_wm_level *l2) 5213 5210 { 5214 - if (l1->plane_en != l2->plane_en) 5215 - return false; 5211 + return l1->plane_en == l2->plane_en && 5212 + l1->plane_res_l == l2->plane_res_l && 5213 + l1->plane_res_b == l2->plane_res_b; 5214 + } 5216 5215 5217 - /* If both planes aren't enabled, the rest shouldn't matter */ 5218 - if (!l1->plane_en) 5219 - return true; 5216 + static bool skl_plane_wm_equals(struct drm_i915_private *dev_priv, 5217 + const struct skl_plane_wm *wm1, 5218 + const struct skl_plane_wm *wm2) 5219 + { 5220 + int level, max_level = ilk_wm_max_level(dev_priv); 5220 5221 5221 - return (l1->plane_res_l == l2->plane_res_l && 5222 - l1->plane_res_b == l2->plane_res_b); 5222 + for (level = 0; level <= max_level; level++) { 5223 + if (!skl_wm_level_equals(&wm1->wm[level], &wm2->wm[level]) || 5224 + !skl_wm_level_equals(&wm1->uv_wm[level], &wm2->uv_wm[level])) 5225 + return false; 5226 + } 5227 + 5228 + return skl_wm_level_equals(&wm1->trans_wm, &wm2->trans_wm); 5223 5229 } 5224 5230 5225 5231 static inline bool skl_ddb_entries_overlap(const struct skl_ddb_entry *a, ··· 5254 5244 static int skl_update_pipe_wm(struct drm_crtc_state *cstate, 5255 5245 const struct skl_pipe_wm *old_pipe_wm, 5256 5246 struct skl_pipe_wm *pipe_wm, /* out */ 5257 - struct skl_ddb_allocation *ddb, /* out */ 5258 5247 bool *changed /* out */) 5259 5248 { 5260 5249 struct intel_crtc_state *intel_cstate = to_intel_crtc_state(cstate); 5261 5250 int ret; 5262 5251 5263 - ret = skl_build_pipe_wm(intel_cstate, ddb, pipe_wm); 5252 + ret = skl_build_pipe_wm(intel_cstate, pipe_wm); 5264 5253 if (ret) 5265 5254 return ret; 5266 5255 ··· 5285 5276 } 5286 5277 5287 5278 static int 5288 - skl_ddb_add_affected_planes(struct intel_crtc_state *cstate) 5279 + skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state, 5280 + struct intel_crtc_state *new_crtc_state) 5289 5281 { 5290 - struct drm_atomic_state *state = cstate->base.state; 5291 - struct drm_device *dev = state->dev; 5292 - struct drm_crtc *crtc = cstate->base.crtc; 5293 - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 5294 - struct drm_i915_private *dev_priv = to_i915(dev); 5295 - struct intel_atomic_state *intel_state = to_intel_atomic_state(state); 5296 - struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb; 5297 - struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb; 5298 - struct drm_plane *plane; 5299 - enum pipe pipe = intel_crtc->pipe; 5282 + struct intel_atomic_state *state = to_intel_atomic_state(new_crtc_state->base.state); 5283 + struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc); 5284 + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 5285 + struct intel_plane *plane; 5300 5286 5301 - drm_for_each_plane_mask(plane, dev, cstate->base.plane_mask) { 5302 - struct drm_plane_state *plane_state; 5303 - struct intel_plane *linked; 5304 - enum plane_id plane_id = to_intel_plane(plane)->id; 5287 + for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) { 5288 + struct intel_plane_state *plane_state; 5289 + enum plane_id plane_id = plane->id; 5305 5290 5306 - if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][plane_id], 5307 - &new_ddb->plane[pipe][plane_id]) && 5308 - skl_ddb_entry_equal(&cur_ddb->uv_plane[pipe][plane_id], 5309 - &new_ddb->uv_plane[pipe][plane_id])) 5291 + if (skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb_y[plane_id], 5292 + &new_crtc_state->wm.skl.plane_ddb_y[plane_id]) && 5293 + skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb_uv[plane_id], 5294 + &new_crtc_state->wm.skl.plane_ddb_uv[plane_id])) 5310 5295 continue; 5311 5296 5312 - plane_state = drm_atomic_get_plane_state(state, plane); 5297 + plane_state = intel_atomic_get_plane_state(state, plane); 5313 5298 if (IS_ERR(plane_state)) 5314 5299 return PTR_ERR(plane_state); 5315 5300 5316 - /* Make sure linked plane is updated too */ 5317 - linked = to_intel_plane_state(plane_state)->linked_plane; 5318 - if (!linked) 5319 - continue; 5320 - 5321 - plane_state = drm_atomic_get_plane_state(state, &linked->base); 5322 - if (IS_ERR(plane_state)) 5323 - return PTR_ERR(plane_state); 5301 + new_crtc_state->update_planes |= BIT(plane_id); 5324 5302 } 5325 5303 5326 5304 return 0; ··· 5319 5323 const struct drm_i915_private *dev_priv = to_i915(state->dev); 5320 5324 struct intel_atomic_state *intel_state = to_intel_atomic_state(state); 5321 5325 struct skl_ddb_allocation *ddb = &intel_state->wm_results.ddb; 5326 + struct intel_crtc_state *old_crtc_state; 5327 + struct intel_crtc_state *new_crtc_state; 5322 5328 struct intel_crtc *crtc; 5323 - struct intel_crtc_state *cstate; 5324 5329 int ret, i; 5325 5330 5326 5331 memcpy(ddb, &dev_priv->wm.skl_hw.ddb, sizeof(*ddb)); 5327 5332 5328 - for_each_new_intel_crtc_in_state(intel_state, crtc, cstate, i) { 5329 - ret = skl_allocate_pipe_ddb(cstate, ddb); 5333 + for_each_oldnew_intel_crtc_in_state(intel_state, crtc, old_crtc_state, 5334 + new_crtc_state, i) { 5335 + ret = skl_allocate_pipe_ddb(new_crtc_state, ddb); 5330 5336 if (ret) 5331 5337 return ret; 5332 5338 5333 - ret = skl_ddb_add_affected_planes(cstate); 5339 + ret = skl_ddb_add_affected_planes(old_crtc_state, 5340 + new_crtc_state); 5334 5341 if (ret) 5335 5342 return ret; 5336 5343 } ··· 5342 5343 } 5343 5344 5344 5345 static void 5345 - skl_print_wm_changes(const struct drm_atomic_state *state) 5346 + skl_print_wm_changes(struct intel_atomic_state *state) 5346 5347 { 5347 - const struct drm_device *dev = state->dev; 5348 - const struct drm_i915_private *dev_priv = to_i915(dev); 5349 - const struct intel_atomic_state *intel_state = 5350 - to_intel_atomic_state(state); 5351 - const struct drm_crtc *crtc; 5352 - const struct drm_crtc_state *cstate; 5353 - const struct intel_plane *intel_plane; 5354 - const struct skl_ddb_allocation *old_ddb = &dev_priv->wm.skl_hw.ddb; 5355 - const struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb; 5348 + struct drm_i915_private *dev_priv = to_i915(state->base.dev); 5349 + const struct intel_crtc_state *old_crtc_state; 5350 + const struct intel_crtc_state *new_crtc_state; 5351 + struct intel_plane *plane; 5352 + struct intel_crtc *crtc; 5356 5353 int i; 5357 5354 5358 - for_each_new_crtc_in_state(state, crtc, cstate, i) { 5359 - const struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 5360 - enum pipe pipe = intel_crtc->pipe; 5361 - 5362 - for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { 5363 - enum plane_id plane_id = intel_plane->id; 5355 + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, 5356 + new_crtc_state, i) { 5357 + for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) { 5358 + enum plane_id plane_id = plane->id; 5364 5359 const struct skl_ddb_entry *old, *new; 5365 5360 5366 - old = &old_ddb->plane[pipe][plane_id]; 5367 - new = &new_ddb->plane[pipe][plane_id]; 5361 + old = &old_crtc_state->wm.skl.plane_ddb_y[plane_id]; 5362 + new = &new_crtc_state->wm.skl.plane_ddb_y[plane_id]; 5368 5363 5369 5364 if (skl_ddb_entry_equal(old, new)) 5370 5365 continue; 5371 5366 5372 5367 DRM_DEBUG_KMS("[PLANE:%d:%s] ddb (%d - %d) -> (%d - %d)\n", 5373 - intel_plane->base.base.id, 5374 - intel_plane->base.name, 5368 + plane->base.base.id, plane->base.name, 5375 5369 old->start, old->end, 5376 5370 new->start, new->end); 5377 5371 } ··· 5461 5469 return 0; 5462 5470 } 5463 5471 5472 + /* 5473 + * To make sure the cursor watermark registers are always consistent 5474 + * with our computed state the following scenario needs special 5475 + * treatment: 5476 + * 5477 + * 1. enable cursor 5478 + * 2. move cursor entirely offscreen 5479 + * 3. disable cursor 5480 + * 5481 + * Step 2. does call .disable_plane() but does not zero the watermarks 5482 + * (since we consider an offscreen cursor still active for the purposes 5483 + * of watermarks). Step 3. would not normally call .disable_plane() 5484 + * because the actual plane visibility isn't changing, and we don't 5485 + * deallocate the cursor ddb until the pipe gets disabled. So we must 5486 + * force step 3. to call .disable_plane() to update the watermark 5487 + * registers properly. 5488 + * 5489 + * Other planes do not suffer from this issues as their watermarks are 5490 + * calculated based on the actual plane visibility. The only time this 5491 + * can trigger for the other planes is during the initial readout as the 5492 + * default value of the watermarks registers is not zero. 5493 + */ 5494 + static int skl_wm_add_affected_planes(struct intel_atomic_state *state, 5495 + struct intel_crtc *crtc) 5496 + { 5497 + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 5498 + const struct intel_crtc_state *old_crtc_state = 5499 + intel_atomic_get_old_crtc_state(state, crtc); 5500 + struct intel_crtc_state *new_crtc_state = 5501 + intel_atomic_get_new_crtc_state(state, crtc); 5502 + struct intel_plane *plane; 5503 + 5504 + for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) { 5505 + struct intel_plane_state *plane_state; 5506 + enum plane_id plane_id = plane->id; 5507 + 5508 + /* 5509 + * Force a full wm update for every plane on modeset. 5510 + * Required because the reset value of the wm registers 5511 + * is non-zero, whereas we want all disabled planes to 5512 + * have zero watermarks. So if we turn off the relevant 5513 + * power well the hardware state will go out of sync 5514 + * with the software state. 5515 + */ 5516 + if (!drm_atomic_crtc_needs_modeset(&new_crtc_state->base) && 5517 + skl_plane_wm_equals(dev_priv, 5518 + &old_crtc_state->wm.skl.optimal.planes[plane_id], 5519 + &new_crtc_state->wm.skl.optimal.planes[plane_id])) 5520 + continue; 5521 + 5522 + plane_state = intel_atomic_get_plane_state(state, plane); 5523 + if (IS_ERR(plane_state)) 5524 + return PTR_ERR(plane_state); 5525 + 5526 + new_crtc_state->update_planes |= BIT(plane_id); 5527 + } 5528 + 5529 + return 0; 5530 + } 5531 + 5464 5532 static int 5465 5533 skl_compute_wm(struct drm_atomic_state *state) 5466 5534 { ··· 5560 5508 &to_intel_crtc_state(crtc->state)->wm.skl.optimal; 5561 5509 5562 5510 pipe_wm = &intel_cstate->wm.skl.optimal; 5563 - ret = skl_update_pipe_wm(cstate, old_pipe_wm, pipe_wm, 5564 - &results->ddb, &changed); 5511 + ret = skl_update_pipe_wm(cstate, old_pipe_wm, pipe_wm, &changed); 5512 + if (ret) 5513 + return ret; 5514 + 5515 + ret = skl_wm_add_affected_planes(intel_state, 5516 + to_intel_crtc(crtc)); 5565 5517 if (ret) 5566 5518 return ret; 5567 5519 ··· 5579 5523 intel_cstate->update_wm_pre = true; 5580 5524 } 5581 5525 5582 - skl_print_wm_changes(state); 5526 + skl_print_wm_changes(intel_state); 5583 5527 5584 5528 return 0; 5585 5529 } ··· 5590 5534 struct intel_crtc *crtc = to_intel_crtc(cstate->base.crtc); 5591 5535 struct drm_i915_private *dev_priv = to_i915(state->base.dev); 5592 5536 struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal; 5593 - const struct skl_ddb_allocation *ddb = &state->wm_results.ddb; 5594 5537 enum pipe pipe = crtc->pipe; 5595 - enum plane_id plane_id; 5596 5538 5597 5539 if (!(state->wm_results.dirty_pipes & drm_crtc_mask(&crtc->base))) 5598 5540 return; 5599 5541 5600 5542 I915_WRITE(PIPE_WM_LINETIME(pipe), pipe_wm->linetime); 5601 - 5602 - for_each_plane_id_on_crtc(crtc, plane_id) { 5603 - if (plane_id != PLANE_CURSOR) 5604 - skl_write_plane_wm(crtc, &pipe_wm->planes[plane_id], 5605 - ddb, plane_id); 5606 - else 5607 - skl_write_cursor_wm(crtc, &pipe_wm->planes[plane_id], 5608 - ddb); 5609 - } 5610 5543 } 5611 5544 5612 5545 static void skl_initial_wm(struct intel_atomic_state *state, ··· 5605 5560 struct drm_device *dev = intel_crtc->base.dev; 5606 5561 struct drm_i915_private *dev_priv = to_i915(dev); 5607 5562 struct skl_ddb_values *results = &state->wm_results; 5608 - struct skl_ddb_values *hw_vals = &dev_priv->wm.skl_hw; 5609 - enum pipe pipe = intel_crtc->pipe; 5610 5563 5611 5564 if ((results->dirty_pipes & drm_crtc_mask(&intel_crtc->base)) == 0) 5612 5565 return; ··· 5613 5570 5614 5571 if (cstate->base.active_changed) 5615 5572 skl_atomic_update_crtc_wm(state, cstate); 5616 - 5617 - memcpy(hw_vals->ddb.uv_plane[pipe], results->ddb.uv_plane[pipe], 5618 - sizeof(hw_vals->ddb.uv_plane[pipe])); 5619 - memcpy(hw_vals->ddb.plane[pipe], results->ddb.plane[pipe], 5620 - sizeof(hw_vals->ddb.plane[pipe])); 5621 5573 5622 5574 mutex_unlock(&dev_priv->wm.wm_mutex); 5623 5575 } ··· 5764 5726 if (dev_priv->active_crtcs) { 5765 5727 /* Fully recompute DDB on first atomic commit */ 5766 5728 dev_priv->wm.distrust_bios_wm = true; 5767 - } else { 5768 - /* 5769 - * Easy/common case; just sanitize DDB now if everything off 5770 - * Keep dbuf slice info intact 5771 - */ 5772 - memset(ddb->plane, 0, sizeof(ddb->plane)); 5773 - memset(ddb->uv_plane, 0, sizeof(ddb->uv_plane)); 5774 5729 } 5775 5730 } 5776 5731
+94 -24
drivers/gpu/drm/i915/intel_psr.c
··· 75 75 if (i915_modparams.enable_psr == -1) 76 76 return false; 77 77 78 + /* Cannot enable DSC and PSR2 simultaneously */ 79 + WARN_ON(crtc_state->dsc_params.compression_enable && 80 + crtc_state->has_psr2); 81 + 78 82 switch (dev_priv->psr.debug & I915_PSR_DEBUG_MODE_MASK) { 79 83 case I915_PSR_DEBUG_FORCE_PSR1: 80 84 return false; ··· 173 169 u32 transcoders = BIT(TRANSCODER_EDP); 174 170 enum transcoder cpu_transcoder; 175 171 ktime_t time_ns = ktime_get(); 172 + u32 mask = 0; 176 173 177 174 if (INTEL_GEN(dev_priv) >= 8) 178 175 transcoders |= BIT(TRANSCODER_A) | ··· 183 178 for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, transcoders) { 184 179 int shift = edp_psr_shift(cpu_transcoder); 185 180 186 - /* FIXME: Exit PSR and link train manually when this happens. */ 187 - if (psr_iir & EDP_PSR_ERROR(shift)) 188 - DRM_DEBUG_KMS("[transcoder %s] PSR aux error\n", 189 - transcoder_name(cpu_transcoder)); 181 + if (psr_iir & EDP_PSR_ERROR(shift)) { 182 + DRM_WARN("[transcoder %s] PSR aux error\n", 183 + transcoder_name(cpu_transcoder)); 184 + 185 + dev_priv->psr.irq_aux_error = true; 186 + 187 + /* 188 + * If this interruption is not masked it will keep 189 + * interrupting so fast that it prevents the scheduled 190 + * work to run. 191 + * Also after a PSR error, we don't want to arm PSR 192 + * again so we don't care about unmask the interruption 193 + * or unset irq_aux_error. 194 + */ 195 + mask |= EDP_PSR_ERROR(shift); 196 + } 190 197 191 198 if (psr_iir & EDP_PSR_PRE_ENTRY(shift)) { 192 199 dev_priv->psr.last_entry_attempt = time_ns; ··· 219 202 psr_event_print(val, psr2_enabled); 220 203 } 221 204 } 205 + } 206 + 207 + if (mask) { 208 + mask |= I915_READ(EDP_PSR_IMR); 209 + I915_WRITE(EDP_PSR_IMR, mask); 210 + 211 + schedule_work(&dev_priv->psr.work); 222 212 } 223 213 } 224 214 ··· 506 482 if (!dev_priv->psr.sink_psr2_support) 507 483 return false; 508 484 485 + /* 486 + * DSC and PSR2 cannot be enabled simultaneously. If a requested 487 + * resolution requires DSC to be enabled, priority is given to DSC 488 + * over PSR2. 489 + */ 490 + if (crtc_state->dsc_params.compression_enable) { 491 + DRM_DEBUG_KMS("PSR2 cannot be enabled since DSC is enabled\n"); 492 + return false; 493 + } 494 + 509 495 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { 510 496 psr_max_h = 4096; 511 497 psr_max_v = 2304; ··· 561 527 return; 562 528 } 563 529 564 - if (IS_HASWELL(dev_priv) && 565 - I915_READ(HSW_STEREO_3D_CTL(crtc_state->cpu_transcoder)) & 566 - S3D_ENABLE) { 567 - DRM_DEBUG_KMS("PSR condition failed: Stereo 3D is Enabled\n"); 530 + if (dev_priv->psr.sink_not_reliable) { 531 + DRM_DEBUG_KMS("PSR sink implementation is not reliable\n"); 568 532 return; 569 533 } 570 534 ··· 719 687 dev_priv->psr.psr2_enabled = intel_psr2_enabled(dev_priv, crtc_state); 720 688 dev_priv->psr.busy_frontbuffer_bits = 0; 721 689 dev_priv->psr.prepared = true; 690 + dev_priv->psr.pipe = to_intel_crtc(crtc_state->base.crtc)->pipe; 722 691 723 692 if (psr_global_enabled(dev_priv->psr.debug)) 724 693 intel_psr_enable_locked(dev_priv, crtc_state); ··· 966 933 return ret; 967 934 } 968 935 936 + static void intel_psr_handle_irq(struct drm_i915_private *dev_priv) 937 + { 938 + struct i915_psr *psr = &dev_priv->psr; 939 + 940 + intel_psr_disable_locked(psr->dp); 941 + psr->sink_not_reliable = true; 942 + /* let's make sure that sink is awaken */ 943 + drm_dp_dpcd_writeb(&psr->dp->aux, DP_SET_POWER, DP_SET_POWER_D0); 944 + } 945 + 969 946 static void intel_psr_work(struct work_struct *work) 970 947 { 971 948 struct drm_i915_private *dev_priv = ··· 985 942 986 943 if (!dev_priv->psr.enabled) 987 944 goto unlock; 945 + 946 + if (READ_ONCE(dev_priv->psr.irq_aux_error)) 947 + intel_psr_handle_irq(dev_priv); 988 948 989 949 /* 990 950 * We have to make sure PSR is ready for re-enable ··· 1027 981 void intel_psr_invalidate(struct drm_i915_private *dev_priv, 1028 982 unsigned frontbuffer_bits, enum fb_op_origin origin) 1029 983 { 1030 - struct drm_crtc *crtc; 1031 - enum pipe pipe; 1032 - 1033 984 if (!CAN_PSR(dev_priv)) 1034 985 return; 1035 986 ··· 1039 996 return; 1040 997 } 1041 998 1042 - crtc = dp_to_dig_port(dev_priv->psr.dp)->base.base.crtc; 1043 - pipe = to_intel_crtc(crtc)->pipe; 1044 - 1045 - frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe); 999 + frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(dev_priv->psr.pipe); 1046 1000 dev_priv->psr.busy_frontbuffer_bits |= frontbuffer_bits; 1047 1001 1048 1002 if (frontbuffer_bits) ··· 1064 1024 void intel_psr_flush(struct drm_i915_private *dev_priv, 1065 1025 unsigned frontbuffer_bits, enum fb_op_origin origin) 1066 1026 { 1067 - struct drm_crtc *crtc; 1068 - enum pipe pipe; 1069 - 1070 1027 if (!CAN_PSR(dev_priv)) 1071 1028 return; 1072 1029 ··· 1076 1039 return; 1077 1040 } 1078 1041 1079 - crtc = dp_to_dig_port(dev_priv->psr.dp)->base.base.crtc; 1080 - pipe = to_intel_crtc(crtc)->pipe; 1081 - 1082 - frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe); 1042 + frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(dev_priv->psr.pipe); 1083 1043 dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits; 1084 1044 1085 1045 /* By definition flush = invalidate + flush */ ··· 1090 1056 * but it makes more sense write to the current active 1091 1057 * pipe. 1092 1058 */ 1093 - I915_WRITE(CURSURFLIVE(pipe), 0); 1059 + I915_WRITE(CURSURFLIVE(dev_priv->psr.pipe), 0); 1094 1060 } 1095 1061 1096 1062 if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits) ··· 1107 1073 */ 1108 1074 void intel_psr_init(struct drm_i915_private *dev_priv) 1109 1075 { 1076 + u32 val; 1077 + 1110 1078 if (!HAS_PSR(dev_priv)) 1111 1079 return; 1112 1080 ··· 1121 1085 if (i915_modparams.enable_psr == -1) 1122 1086 if (INTEL_GEN(dev_priv) < 9 || !dev_priv->vbt.psr.enable) 1123 1087 i915_modparams.enable_psr = 0; 1088 + 1089 + /* 1090 + * If a PSR error happened and the driver is reloaded, the EDP_PSR_IIR 1091 + * will still keep the error set even after the reset done in the 1092 + * irq_preinstall and irq_uninstall hooks. 1093 + * And enabling in this situation cause the screen to freeze in the 1094 + * first time that PSR HW tries to activate so lets keep PSR disabled 1095 + * to avoid any rendering problems. 1096 + */ 1097 + val = I915_READ(EDP_PSR_IIR); 1098 + val &= EDP_PSR_ERROR(edp_psr_shift(TRANSCODER_EDP)); 1099 + if (val) { 1100 + DRM_DEBUG_KMS("PSR interruption error set\n"); 1101 + dev_priv->psr.sink_not_reliable = true; 1102 + return; 1103 + } 1124 1104 1125 1105 /* Set link_standby x link_off defaults */ 1126 1106 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) ··· 1175 1123 if ((val & DP_PSR_SINK_STATE_MASK) == DP_PSR_SINK_INTERNAL_ERROR) { 1176 1124 DRM_DEBUG_KMS("PSR sink internal error, disabling PSR\n"); 1177 1125 intel_psr_disable_locked(intel_dp); 1126 + psr->sink_not_reliable = true; 1178 1127 } 1179 1128 1180 1129 if (drm_dp_dpcd_readb(&intel_dp->aux, DP_PSR_ERROR_STATUS, &val) != 1) { ··· 1193 1140 if (val & ~errors) 1194 1141 DRM_ERROR("PSR_ERROR_STATUS unhandled errors %x\n", 1195 1142 val & ~errors); 1196 - if (val & errors) 1143 + if (val & errors) { 1197 1144 intel_psr_disable_locked(intel_dp); 1145 + psr->sink_not_reliable = true; 1146 + } 1198 1147 /* clear status register */ 1199 1148 drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_ERROR_STATUS, val); 1200 1149 exit: 1201 1150 mutex_unlock(&psr->lock); 1151 + } 1152 + 1153 + bool intel_psr_enabled(struct intel_dp *intel_dp) 1154 + { 1155 + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); 1156 + bool ret; 1157 + 1158 + if (!CAN_PSR(dev_priv) || !intel_dp_is_edp(intel_dp)) 1159 + return false; 1160 + 1161 + mutex_lock(&dev_priv->psr.lock); 1162 + ret = (dev_priv->psr.dp == intel_dp && dev_priv->psr.enabled); 1163 + mutex_unlock(&dev_priv->psr.lock); 1164 + 1165 + return ret; 1202 1166 }
+40 -32
drivers/gpu/drm/i915/intel_ringbuffer.c
··· 150 150 */ 151 151 if (mode & EMIT_INVALIDATE) { 152 152 *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE; 153 - *cs++ = i915_ggtt_offset(rq->engine->scratch) | 154 - PIPE_CONTROL_GLOBAL_GTT; 153 + *cs++ = i915_scratch_offset(rq->i915) | PIPE_CONTROL_GLOBAL_GTT; 155 154 *cs++ = 0; 156 155 *cs++ = 0; 157 156 ··· 158 159 *cs++ = MI_FLUSH; 159 160 160 161 *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE; 161 - *cs++ = i915_ggtt_offset(rq->engine->scratch) | 162 - PIPE_CONTROL_GLOBAL_GTT; 162 + *cs++ = i915_scratch_offset(rq->i915) | PIPE_CONTROL_GLOBAL_GTT; 163 163 *cs++ = 0; 164 164 *cs++ = 0; 165 165 } ··· 210 212 static int 211 213 intel_emit_post_sync_nonzero_flush(struct i915_request *rq) 212 214 { 213 - u32 scratch_addr = 214 - i915_ggtt_offset(rq->engine->scratch) + 2 * CACHELINE_BYTES; 215 + u32 scratch_addr = i915_scratch_offset(rq->i915) + 2 * CACHELINE_BYTES; 215 216 u32 *cs; 216 217 217 218 cs = intel_ring_begin(rq, 6); ··· 243 246 static int 244 247 gen6_render_ring_flush(struct i915_request *rq, u32 mode) 245 248 { 246 - u32 scratch_addr = 247 - i915_ggtt_offset(rq->engine->scratch) + 2 * CACHELINE_BYTES; 249 + u32 scratch_addr = i915_scratch_offset(rq->i915) + 2 * CACHELINE_BYTES; 248 250 u32 *cs, flags = 0; 249 251 int ret; 250 252 ··· 312 316 static int 313 317 gen7_render_ring_flush(struct i915_request *rq, u32 mode) 314 318 { 315 - u32 scratch_addr = 316 - i915_ggtt_offset(rq->engine->scratch) + 2 * CACHELINE_BYTES; 319 + u32 scratch_addr = i915_scratch_offset(rq->i915) + 2 * CACHELINE_BYTES; 317 320 u32 *cs, flags = 0; 318 321 319 322 /* ··· 524 529 525 530 intel_engine_reset_breadcrumbs(engine); 526 531 532 + if (HAS_LEGACY_SEMAPHORES(engine->i915)) { 533 + I915_WRITE(RING_SYNC_0(engine->mmio_base), 0); 534 + I915_WRITE(RING_SYNC_1(engine->mmio_base), 0); 535 + if (HAS_VEBOX(dev_priv)) 536 + I915_WRITE(RING_SYNC_2(engine->mmio_base), 0); 537 + } 538 + 527 539 /* Enforce ordering by reading HEAD register back */ 528 540 I915_READ_HEAD(engine); 529 541 ··· 548 546 /* Check that the ring offsets point within the ring! */ 549 547 GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->head)); 550 548 GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->tail)); 551 - 552 549 intel_ring_update_space(ring); 550 + 551 + /* First wake the ring up to an empty/idle ring */ 553 552 I915_WRITE_HEAD(engine, ring->head); 554 - I915_WRITE_TAIL(engine, ring->tail); 553 + I915_WRITE_TAIL(engine, ring->head); 555 554 (void)I915_READ_TAIL(engine); 556 555 557 556 I915_WRITE_CTL(engine, RING_CTL_SIZE(ring->size) | RING_VALID); ··· 576 573 577 574 if (INTEL_GEN(dev_priv) > 2) 578 575 I915_WRITE_MODE(engine, _MASKED_BIT_DISABLE(STOP_RING)); 576 + 577 + /* Now awake, let it get started */ 578 + if (ring->tail != ring->head) { 579 + I915_WRITE_TAIL(engine, ring->tail); 580 + (void)I915_READ_TAIL(engine); 581 + } 579 582 580 583 /* Papering over lost _interrupts_ immediately following the restart */ 581 584 intel_engine_wakeup(engine); ··· 651 642 { 652 643 int ret; 653 644 654 - ret = intel_ctx_workarounds_emit(rq); 645 + ret = intel_engine_emit_ctx_wa(rq); 655 646 if (ret != 0) 656 647 return ret; 657 648 ··· 668 659 int ret = init_ring_common(engine); 669 660 if (ret) 670 661 return ret; 671 - 672 - intel_whitelist_workarounds_apply(engine); 673 662 674 663 /* WaTimedSingleVertexDispatch:cl,bw,ctg,elk,ilk,snb */ 675 664 if (IS_GEN(dev_priv, 4, 6)) ··· 750 743 /* Mark all submitted requests as skipped. */ 751 744 list_for_each_entry(request, &engine->timeline.requests, link) { 752 745 GEM_BUG_ON(!request->global_seqno); 753 - if (!i915_request_completed(request)) 754 - dma_fence_set_error(&request->fence, -EIO); 746 + 747 + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, 748 + &request->fence.flags)) 749 + continue; 750 + 751 + dma_fence_set_error(&request->fence, -EIO); 755 752 } 753 + 754 + intel_write_status_page(engine, 755 + I915_GEM_HWS_INDEX, 756 + intel_engine_last_submit(engine)); 757 + 756 758 /* Remaining _unready_ requests will be nop'ed when submitted */ 757 759 758 760 spin_unlock_irqrestore(&engine->timeline.lock, flags); ··· 989 973 } 990 974 991 975 /* Just userspace ABI convention to limit the wa batch bo to a resonable size */ 992 - #define I830_BATCH_LIMIT (256*1024) 976 + #define I830_BATCH_LIMIT SZ_256K 993 977 #define I830_TLB_ENTRIES (2) 994 978 #define I830_WA_SIZE max(I830_TLB_ENTRIES*4096, I830_BATCH_LIMIT) 995 979 static int ··· 997 981 u64 offset, u32 len, 998 982 unsigned int dispatch_flags) 999 983 { 1000 - u32 *cs, cs_offset = i915_ggtt_offset(rq->engine->scratch); 984 + u32 *cs, cs_offset = i915_scratch_offset(rq->i915); 985 + 986 + GEM_BUG_ON(rq->i915->gt.scratch->size < I830_WA_SIZE); 1001 987 1002 988 cs = intel_ring_begin(rq, 6); 1003 989 if (IS_ERR(cs)) ··· 1456 1438 { 1457 1439 struct i915_timeline *timeline; 1458 1440 struct intel_ring *ring; 1459 - unsigned int size; 1460 1441 int err; 1461 1442 1462 1443 intel_engine_setup_common(engine); ··· 1480 1463 GEM_BUG_ON(engine->buffer); 1481 1464 engine->buffer = ring; 1482 1465 1483 - size = PAGE_SIZE; 1484 - if (HAS_BROKEN_CS_TLB(engine->i915)) 1485 - size = I830_WA_SIZE; 1486 - err = intel_engine_create_scratch(engine, size); 1466 + err = intel_engine_init_common(engine); 1487 1467 if (err) 1488 1468 goto err_unpin; 1489 1469 1490 - err = intel_engine_init_common(engine); 1491 - if (err) 1492 - goto err_scratch; 1493 - 1494 1470 return 0; 1495 1471 1496 - err_scratch: 1497 - intel_engine_cleanup_scratch(engine); 1498 1472 err_unpin: 1499 1473 intel_ring_unpin(ring); 1500 1474 err_ring: ··· 1559 1551 /* Stall until the page table load is complete */ 1560 1552 *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT; 1561 1553 *cs++ = i915_mmio_reg_offset(RING_PP_DIR_BASE(engine)); 1562 - *cs++ = i915_ggtt_offset(engine->scratch); 1554 + *cs++ = i915_scratch_offset(rq->i915); 1563 1555 *cs++ = MI_NOOP; 1564 1556 1565 1557 intel_ring_advance(rq, cs); ··· 1668 1660 /* Insert a delay before the next switch! */ 1669 1661 *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT; 1670 1662 *cs++ = i915_mmio_reg_offset(last_reg); 1671 - *cs++ = i915_ggtt_offset(engine->scratch); 1663 + *cs++ = i915_scratch_offset(rq->i915); 1672 1664 *cs++ = MI_NOOP; 1673 1665 } 1674 1666 *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
+4 -21
drivers/gpu/drm/i915/intel_ringbuffer.h
··· 15 15 #include "i915_selftest.h" 16 16 #include "i915_timeline.h" 17 17 #include "intel_gpu_commands.h" 18 + #include "intel_workarounds.h" 18 19 19 20 struct drm_printer; 20 21 struct i915_sched_attr; ··· 314 313 struct rb_root_cached queue; 315 314 316 315 /** 317 - * @csb_read: control register for Context Switch buffer 318 - * 319 - * Note this register is always in mmio. 320 - */ 321 - u32 __iomem *csb_read; 322 - 323 - /** 324 316 * @csb_write: control register for Context Switch buffer 325 317 * 326 318 * Note this register may be either mmio or HWSP shadow. ··· 331 337 * @preempt_complete_status: expected CSB upon completing preemption 332 338 */ 333 339 u32 preempt_complete_status; 334 - 335 - /** 336 - * @csb_write_reset: reset value for CSB write pointer 337 - * 338 - * As the CSB write pointer maybe either in HWSP or as a field 339 - * inside an mmio register, we want to reprogram it slightly 340 - * differently to avoid later confusion. 341 - */ 342 - u32 csb_write_reset; 343 340 344 341 /** 345 342 * @csb_head: context status buffer head ··· 436 451 437 452 struct intel_hw_status_page status_page; 438 453 struct i915_ctx_workarounds wa_ctx; 439 - struct i915_vma *scratch; 454 + struct i915_wa_list ctx_wa_list; 455 + struct i915_wa_list wa_list; 456 + struct i915_wa_list whitelist; 440 457 441 458 u32 irq_keep_mask; /* always keep these interrupts */ 442 459 u32 irq_enable_mask; /* bitmask to enable ring interrupt */ ··· 894 907 void intel_engine_setup_common(struct intel_engine_cs *engine); 895 908 int intel_engine_init_common(struct intel_engine_cs *engine); 896 909 void intel_engine_cleanup_common(struct intel_engine_cs *engine); 897 - 898 - int intel_engine_create_scratch(struct intel_engine_cs *engine, 899 - unsigned int size); 900 - void intel_engine_cleanup_scratch(struct intel_engine_cs *engine); 901 910 902 911 int intel_init_render_ring_buffer(struct intel_engine_cs *engine); 903 912 int intel_init_bsd_ring_buffer(struct intel_engine_cs *engine);
+3 -1
drivers/gpu/drm/i915/intel_runtime_pm.c
··· 76 76 return "TRANSCODER_C"; 77 77 case POWER_DOMAIN_TRANSCODER_EDP: 78 78 return "TRANSCODER_EDP"; 79 + case POWER_DOMAIN_TRANSCODER_EDP_VDSC: 80 + return "TRANSCODER_EDP_VDSC"; 79 81 case POWER_DOMAIN_TRANSCODER_DSI_A: 80 82 return "TRANSCODER_DSI_A"; 81 83 case POWER_DOMAIN_TRANSCODER_DSI_C: ··· 2030 2028 */ 2031 2029 #define ICL_PW_2_POWER_DOMAINS ( \ 2032 2030 ICL_PW_3_POWER_DOMAINS | \ 2031 + BIT_ULL(POWER_DOMAIN_TRANSCODER_EDP_VDSC) | \ 2033 2032 BIT_ULL(POWER_DOMAIN_INIT)) 2034 2033 /* 2035 - * - eDP/DSI VDSC 2036 2034 * - KVMR (HW control) 2037 2035 */ 2038 2036 #define ICL_DISPLAY_DC_OFF_POWER_DOMAINS ( \
+87 -61
drivers/gpu/drm/i915/intel_sprite.c
··· 373 373 #define BOFF(x) (((x) & 0xffff) << 16) 374 374 375 375 static void 376 - icl_program_input_csc_coeff(const struct intel_crtc_state *crtc_state, 377 - const struct intel_plane_state *plane_state) 376 + icl_program_input_csc(struct intel_plane *plane, 377 + const struct intel_crtc_state *crtc_state, 378 + const struct intel_plane_state *plane_state) 378 379 { 379 - struct drm_i915_private *dev_priv = 380 - to_i915(plane_state->base.plane->dev); 381 - struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); 382 - enum pipe pipe = crtc->pipe; 383 - struct intel_plane *plane = to_intel_plane(plane_state->base.plane); 380 + struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 381 + enum pipe pipe = plane->pipe; 384 382 enum plane_id plane_id = plane->id; 385 383 386 384 static const u16 input_csc_matrix[][9] = { ··· 506 508 507 509 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 508 510 509 - if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 510 - I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), 511 - plane_state->color_ctl); 512 - 513 - if (fb->format->is_yuv && icl_is_hdr_plane(plane)) 514 - icl_program_input_csc_coeff(crtc_state, plane_state); 515 - 516 - I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value); 517 - I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax); 518 - I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk); 519 - 520 - I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x); 521 511 I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride); 512 + I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x); 522 513 I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w); 523 514 I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id), 524 515 (plane_state->color_plane[1].offset - surf_addr) | aux_stride); 525 - 526 - if (INTEL_GEN(dev_priv) < 11) 527 - I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id), 528 - (plane_state->color_plane[1].y << 16) | 529 - plane_state->color_plane[1].x); 530 516 531 517 if (icl_is_hdr_plane(plane)) { 532 518 u32 cus_ctl = 0; ··· 533 551 I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl); 534 552 } 535 553 536 - if (!slave && plane_state->scaler_id >= 0) 537 - skl_program_scaler(plane, crtc_state, plane_state); 554 + if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 555 + I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), 556 + plane_state->color_ctl); 538 557 539 - I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x); 558 + if (fb->format->is_yuv && icl_is_hdr_plane(plane)) 559 + icl_program_input_csc(plane, crtc_state, plane_state); 540 560 561 + skl_write_plane_wm(plane, crtc_state); 562 + 563 + I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value); 564 + I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk); 565 + I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax); 566 + 567 + I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x); 568 + 569 + if (INTEL_GEN(dev_priv) < 11) 570 + I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id), 571 + (plane_state->color_plane[1].y << 16) | 572 + plane_state->color_plane[1].x); 573 + 574 + /* 575 + * The control register self-arms if the plane was previously 576 + * disabled. Try to make the plane enable atomic by writing 577 + * the control register just before the surface register. 578 + */ 541 579 I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl); 542 580 I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 543 581 intel_plane_ggtt_offset(plane_state) + surf_addr); 582 + 583 + if (!slave && plane_state->scaler_id >= 0) 584 + skl_program_scaler(plane, crtc_state, plane_state); 544 585 545 586 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 546 587 } ··· 594 589 } 595 590 596 591 static void 597 - skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc) 592 + skl_disable_plane(struct intel_plane *plane, 593 + const struct intel_crtc_state *crtc_state) 598 594 { 599 595 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 600 596 enum plane_id plane_id = plane->id; ··· 603 597 unsigned long irqflags; 604 598 605 599 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 600 + 601 + skl_write_plane_wm(plane, crtc_state); 606 602 607 603 I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0); 608 604 I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0); ··· 827 819 828 820 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 829 821 830 - vlv_update_clrc(plane_state); 822 + I915_WRITE_FW(SPSTRIDE(pipe, plane_id), 823 + plane_state->color_plane[0].stride); 824 + I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x); 825 + I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w); 826 + I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0); 831 827 832 828 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) 833 829 chv_update_csc(plane_state); 834 830 835 831 if (key->flags) { 836 832 I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value); 837 - I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value); 838 833 I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask); 834 + I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value); 839 835 } 840 - I915_WRITE_FW(SPSTRIDE(pipe, plane_id), 841 - plane_state->color_plane[0].stride); 842 - I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x); 843 836 844 - I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x); 845 837 I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset); 838 + I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x); 846 839 847 - I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0); 848 - 849 - I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w); 840 + /* 841 + * The control register self-arms if the plane was previously 842 + * disabled. Try to make the plane enable atomic by writing 843 + * the control register just before the surface register. 844 + */ 850 845 I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl); 851 846 I915_WRITE_FW(SPSURF(pipe, plane_id), 852 847 intel_plane_ggtt_offset(plane_state) + sprsurf_offset); 848 + 849 + vlv_update_clrc(plane_state); 853 850 854 851 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); 855 852 } 856 853 857 854 static void 858 - vlv_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc) 855 + vlv_disable_plane(struct intel_plane *plane, 856 + const struct intel_crtc_state *crtc_state) 859 857 { 860 858 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 861 859 enum pipe pipe = plane->pipe; ··· 994 980 995 981 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 996 982 997 - if (key->flags) { 998 - I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value); 999 - I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value); 1000 - I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask); 1001 - } 1002 - 1003 983 I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride); 1004 984 I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x); 985 + I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); 986 + if (IS_IVYBRIDGE(dev_priv)) 987 + I915_WRITE_FW(SPRSCALE(pipe), sprscale); 988 + 989 + if (key->flags) { 990 + I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value); 991 + I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask); 992 + I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value); 993 + } 1005 994 1006 995 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET 1007 996 * register */ 1008 997 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { 1009 998 I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x); 1010 999 } else { 1011 - I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x); 1012 1000 I915_WRITE_FW(SPRLINOFF(pipe), linear_offset); 1001 + I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x); 1013 1002 } 1014 1003 1015 - I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); 1016 - if (IS_IVYBRIDGE(dev_priv)) 1017 - I915_WRITE_FW(SPRSCALE(pipe), sprscale); 1004 + /* 1005 + * The control register self-arms if the plane was previously 1006 + * disabled. Try to make the plane enable atomic by writing 1007 + * the control register just before the surface register. 1008 + */ 1018 1009 I915_WRITE_FW(SPRCTL(pipe), sprctl); 1019 1010 I915_WRITE_FW(SPRSURF(pipe), 1020 1011 intel_plane_ggtt_offset(plane_state) + sprsurf_offset); ··· 1028 1009 } 1029 1010 1030 1011 static void 1031 - ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc) 1012 + ivb_disable_plane(struct intel_plane *plane, 1013 + const struct intel_crtc_state *crtc_state) 1032 1014 { 1033 1015 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1034 1016 enum pipe pipe = plane->pipe; ··· 1038 1018 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1039 1019 1040 1020 I915_WRITE_FW(SPRCTL(pipe), 0); 1041 - /* Can't leave the scaler enabled... */ 1021 + /* Disable the scaler */ 1042 1022 if (IS_IVYBRIDGE(dev_priv)) 1043 1023 I915_WRITE_FW(SPRSCALE(pipe), 0); 1044 1024 I915_WRITE_FW(SPRSURF(pipe), 0); ··· 1168 1148 1169 1149 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 1170 1150 1171 - if (key->flags) { 1172 - I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value); 1173 - I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value); 1174 - I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask); 1175 - } 1176 - 1177 1151 I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride); 1178 1152 I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x); 1179 - 1180 - I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x); 1181 - I915_WRITE_FW(DVSLINOFF(pipe), linear_offset); 1182 - 1183 1153 I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); 1184 1154 I915_WRITE_FW(DVSSCALE(pipe), dvsscale); 1155 + 1156 + if (key->flags) { 1157 + I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value); 1158 + I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask); 1159 + I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value); 1160 + } 1161 + 1162 + I915_WRITE_FW(DVSLINOFF(pipe), linear_offset); 1163 + I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x); 1164 + 1165 + /* 1166 + * The control register self-arms if the plane was previously 1167 + * disabled. Try to make the plane enable atomic by writing 1168 + * the control register just before the surface register. 1169 + */ 1185 1170 I915_WRITE_FW(DVSCNTR(pipe), dvscntr); 1186 1171 I915_WRITE_FW(DVSSURF(pipe), 1187 1172 intel_plane_ggtt_offset(plane_state) + dvssurf_offset); ··· 1195 1170 } 1196 1171 1197 1172 static void 1198 - g4x_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc) 1173 + g4x_disable_plane(struct intel_plane *plane, 1174 + const struct intel_crtc_state *crtc_state) 1199 1175 { 1200 1176 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1201 1177 enum pipe pipe = plane->pipe;
+1088
drivers/gpu/drm/i915/intel_vdsc.c
··· 1 + // SPDX-License-Identifier: MIT 2 + /* 3 + * Copyright © 2018 Intel Corporation 4 + * 5 + * Author: Gaurav K Singh <gaurav.k.singh@intel.com> 6 + * Manasi Navare <manasi.d.navare@intel.com> 7 + */ 8 + 9 + #include <drm/drmP.h> 10 + #include <drm/i915_drm.h> 11 + #include "i915_drv.h" 12 + #include "intel_drv.h" 13 + 14 + enum ROW_INDEX_BPP { 15 + ROW_INDEX_6BPP = 0, 16 + ROW_INDEX_8BPP, 17 + ROW_INDEX_10BPP, 18 + ROW_INDEX_12BPP, 19 + ROW_INDEX_15BPP, 20 + MAX_ROW_INDEX 21 + }; 22 + 23 + enum COLUMN_INDEX_BPC { 24 + COLUMN_INDEX_8BPC = 0, 25 + COLUMN_INDEX_10BPC, 26 + COLUMN_INDEX_12BPC, 27 + COLUMN_INDEX_14BPC, 28 + COLUMN_INDEX_16BPC, 29 + MAX_COLUMN_INDEX 30 + }; 31 + 32 + #define DSC_SUPPORTED_VERSION_MIN 1 33 + 34 + /* From DSC_v1.11 spec, rc_parameter_Set syntax element typically constant */ 35 + static u16 rc_buf_thresh[] = { 36 + 896, 1792, 2688, 3584, 4480, 5376, 6272, 6720, 7168, 7616, 37 + 7744, 7872, 8000, 8064 38 + }; 39 + 40 + struct rc_parameters { 41 + u16 initial_xmit_delay; 42 + u8 first_line_bpg_offset; 43 + u16 initial_offset; 44 + u8 flatness_min_qp; 45 + u8 flatness_max_qp; 46 + u8 rc_quant_incr_limit0; 47 + u8 rc_quant_incr_limit1; 48 + struct drm_dsc_rc_range_parameters rc_range_params[DSC_NUM_BUF_RANGES]; 49 + }; 50 + 51 + /* 52 + * Selected Rate Control Related Parameter Recommended Values 53 + * from DSC_v1.11 spec & C Model release: DSC_model_20161212 54 + */ 55 + static struct rc_parameters rc_params[][MAX_COLUMN_INDEX] = { 56 + { 57 + /* 6BPP/8BPC */ 58 + { 768, 15, 6144, 3, 13, 11, 11, { 59 + { 0, 4, 0 }, { 1, 6, -2 }, { 3, 8, -2 }, { 4, 8, -4 }, 60 + { 5, 9, -6 }, { 5, 9, -6 }, { 6, 9, -6 }, { 6, 10, -8 }, 61 + { 7, 11, -8 }, { 8, 12, -10 }, { 9, 12, -10 }, { 10, 12, -12 }, 62 + { 10, 12, -12 }, { 11, 12, -12 }, { 13, 14, -12 } 63 + } 64 + }, 65 + /* 6BPP/10BPC */ 66 + { 768, 15, 6144, 7, 17, 15, 15, { 67 + { 0, 8, 0 }, { 3, 10, -2 }, { 7, 12, -2 }, { 8, 12, -4 }, 68 + { 9, 13, -6 }, { 9, 13, -6 }, { 10, 13, -6 }, { 10, 14, -8 }, 69 + { 11, 15, -8 }, { 12, 16, -10 }, { 13, 16, -10 }, 70 + { 14, 16, -12 }, { 14, 16, -12 }, { 15, 16, -12 }, 71 + { 17, 18, -12 } 72 + } 73 + }, 74 + /* 6BPP/12BPC */ 75 + { 768, 15, 6144, 11, 21, 19, 19, { 76 + { 0, 12, 0 }, { 5, 14, -2 }, { 11, 16, -2 }, { 12, 16, -4 }, 77 + { 13, 17, -6 }, { 13, 17, -6 }, { 14, 17, -6 }, { 14, 18, -8 }, 78 + { 15, 19, -8 }, { 16, 20, -10 }, { 17, 20, -10 }, 79 + { 18, 20, -12 }, { 18, 20, -12 }, { 19, 20, -12 }, 80 + { 21, 22, -12 } 81 + } 82 + }, 83 + /* 6BPP/14BPC */ 84 + { 768, 15, 6144, 15, 25, 23, 27, { 85 + { 0, 16, 0 }, { 7, 18, -2 }, { 15, 20, -2 }, { 16, 20, -4 }, 86 + { 17, 21, -6 }, { 17, 21, -6 }, { 18, 21, -6 }, { 18, 22, -8 }, 87 + { 19, 23, -8 }, { 20, 24, -10 }, { 21, 24, -10 }, 88 + { 22, 24, -12 }, { 22, 24, -12 }, { 23, 24, -12 }, 89 + { 25, 26, -12 } 90 + } 91 + }, 92 + /* 6BPP/16BPC */ 93 + { 768, 15, 6144, 19, 29, 27, 27, { 94 + { 0, 20, 0 }, { 9, 22, -2 }, { 19, 24, -2 }, { 20, 24, -4 }, 95 + { 21, 25, -6 }, { 21, 25, -6 }, { 22, 25, -6 }, { 22, 26, -8 }, 96 + { 23, 27, -8 }, { 24, 28, -10 }, { 25, 28, -10 }, 97 + { 26, 28, -12 }, { 26, 28, -12 }, { 27, 28, -12 }, 98 + { 29, 30, -12 } 99 + } 100 + }, 101 + }, 102 + { 103 + /* 8BPP/8BPC */ 104 + { 512, 12, 6144, 3, 12, 11, 11, { 105 + { 0, 4, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 1, 6, -2 }, 106 + { 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 }, 107 + { 3, 9, -8 }, { 3, 10, -10 }, { 5, 11, -10 }, { 5, 12, -12 }, 108 + { 5, 13, -12 }, { 7, 13, -12 }, { 13, 15, -12 } 109 + } 110 + }, 111 + /* 8BPP/10BPC */ 112 + { 512, 12, 6144, 7, 16, 15, 15, { 113 + { 0, 4, 2 }, { 4, 8, 0 }, { 5, 9, 0 }, { 5, 10, -2 }, 114 + { 7, 11, -4 }, { 7, 11, -6 }, { 7, 11, -8 }, { 7, 12, -8 }, 115 + { 7, 13, -8 }, { 7, 14, -10 }, { 9, 15, -10 }, { 9, 16, -12 }, 116 + { 9, 17, -12 }, { 11, 17, -12 }, { 17, 19, -12 } 117 + } 118 + }, 119 + /* 8BPP/12BPC */ 120 + { 512, 12, 6144, 11, 20, 19, 19, { 121 + { 0, 12, 2 }, { 4, 12, 0 }, { 9, 13, 0 }, { 9, 14, -2 }, 122 + { 11, 15, -4 }, { 11, 15, -6 }, { 11, 15, -8 }, { 11, 16, -8 }, 123 + { 11, 17, -8 }, { 11, 18, -10 }, { 13, 19, -10 }, 124 + { 13, 20, -12 }, { 13, 21, -12 }, { 15, 21, -12 }, 125 + { 21, 23, -12 } 126 + } 127 + }, 128 + /* 8BPP/14BPC */ 129 + { 512, 12, 6144, 15, 24, 23, 23, { 130 + { 0, 12, 0 }, { 5, 13, 0 }, { 11, 15, 0 }, { 12, 17, -2 }, 131 + { 15, 19, -4 }, { 15, 19, -6 }, { 15, 19, -8 }, { 15, 20, -8 }, 132 + { 15, 21, -8 }, { 15, 22, -10 }, { 17, 22, -10 }, 133 + { 17, 23, -12 }, { 17, 23, -12 }, { 21, 24, -12 }, 134 + { 24, 25, -12 } 135 + } 136 + }, 137 + /* 8BPP/16BPC */ 138 + { 512, 12, 6144, 19, 28, 27, 27, { 139 + { 0, 12, 2 }, { 6, 14, 0 }, { 13, 17, 0 }, { 15, 20, -2 }, 140 + { 19, 23, -4 }, { 19, 23, -6 }, { 19, 23, -8 }, { 19, 24, -8 }, 141 + { 19, 25, -8 }, { 19, 26, -10 }, { 21, 26, -10 }, 142 + { 21, 27, -12 }, { 21, 27, -12 }, { 25, 28, -12 }, 143 + { 28, 29, -12 } 144 + } 145 + }, 146 + }, 147 + { 148 + /* 10BPP/8BPC */ 149 + { 410, 15, 5632, 3, 12, 11, 11, { 150 + { 0, 3, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 2, 6, -2 }, 151 + { 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 }, 152 + { 3, 9, -8 }, { 3, 9, -10 }, { 5, 10, -10 }, { 5, 10, -10 }, 153 + { 5, 11, -12 }, { 7, 11, -12 }, { 11, 12, -12 } 154 + } 155 + }, 156 + /* 10BPP/10BPC */ 157 + { 410, 15, 5632, 7, 16, 15, 15, { 158 + { 0, 7, 2 }, { 4, 8, 0 }, { 5, 9, 0 }, { 6, 10, -2 }, 159 + { 7, 11, -4 }, { 7, 11, -6 }, { 7, 11, -8 }, { 7, 12, -8 }, 160 + { 7, 13, -8 }, { 7, 13, -10 }, { 9, 14, -10 }, { 9, 14, -10 }, 161 + { 9, 15, -12 }, { 11, 15, -12 }, { 15, 16, -12 } 162 + } 163 + }, 164 + /* 10BPP/12BPC */ 165 + { 410, 15, 5632, 11, 20, 19, 19, { 166 + { 0, 11, 2 }, { 4, 12, 0 }, { 9, 13, 0 }, { 10, 14, -2 }, 167 + { 11, 15, -4 }, { 11, 15, -6 }, { 11, 15, -8 }, { 11, 16, -8 }, 168 + { 11, 17, -8 }, { 11, 17, -10 }, { 13, 18, -10 }, 169 + { 13, 18, -10 }, { 13, 19, -12 }, { 15, 19, -12 }, 170 + { 19, 20, -12 } 171 + } 172 + }, 173 + /* 10BPP/14BPC */ 174 + { 410, 15, 5632, 15, 24, 23, 23, { 175 + { 0, 11, 2 }, { 5, 13, 0 }, { 11, 15, 0 }, { 13, 18, -2 }, 176 + { 15, 19, -4 }, { 15, 19, -6 }, { 15, 19, -8 }, { 15, 20, -8 }, 177 + { 15, 21, -8 }, { 15, 21, -10 }, { 17, 22, -10 }, 178 + { 17, 22, -10 }, { 17, 23, -12 }, { 19, 23, -12 }, 179 + { 23, 24, -12 } 180 + } 181 + }, 182 + /* 10BPP/16BPC */ 183 + { 410, 15, 5632, 19, 28, 27, 27, { 184 + { 0, 11, 2 }, { 6, 14, 0 }, { 13, 17, 0 }, { 16, 20, -2 }, 185 + { 19, 23, -4 }, { 19, 23, -6 }, { 19, 23, -8 }, { 19, 24, -8 }, 186 + { 19, 25, -8 }, { 19, 25, -10 }, { 21, 26, -10 }, 187 + { 21, 26, -10 }, { 21, 27, -12 }, { 23, 27, -12 }, 188 + { 27, 28, -12 } 189 + } 190 + }, 191 + }, 192 + { 193 + /* 12BPP/8BPC */ 194 + { 341, 15, 2048, 3, 12, 11, 11, { 195 + { 0, 2, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 1, 6, -2 }, 196 + { 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 }, 197 + { 3, 9, -8 }, { 3, 10, -10 }, { 5, 11, -10 }, 198 + { 5, 12, -12 }, { 5, 13, -12 }, { 7, 13, -12 }, { 13, 15, -12 } 199 + } 200 + }, 201 + /* 12BPP/10BPC */ 202 + { 341, 15, 2048, 7, 16, 15, 15, { 203 + { 0, 2, 2 }, { 2, 5, 0 }, { 3, 7, 0 }, { 4, 8, -2 }, 204 + { 6, 9, -4 }, { 7, 10, -6 }, { 7, 11, -8 }, { 7, 12, -8 }, 205 + { 7, 13, -8 }, { 7, 14, -10 }, { 9, 15, -10 }, { 9, 16, -12 }, 206 + { 9, 17, -12 }, { 11, 17, -12 }, { 17, 19, -12 } 207 + } 208 + }, 209 + /* 12BPP/12BPC */ 210 + { 341, 15, 2048, 11, 20, 19, 19, { 211 + { 0, 6, 2 }, { 4, 9, 0 }, { 7, 11, 0 }, { 8, 12, -2 }, 212 + { 10, 13, -4 }, { 11, 14, -6 }, { 11, 15, -8 }, { 11, 16, -8 }, 213 + { 11, 17, -8 }, { 11, 18, -10 }, { 13, 19, -10 }, 214 + { 13, 20, -12 }, { 13, 21, -12 }, { 15, 21, -12 }, 215 + { 21, 23, -12 } 216 + } 217 + }, 218 + /* 12BPP/14BPC */ 219 + { 341, 15, 2048, 15, 24, 23, 23, { 220 + { 0, 6, 2 }, { 7, 10, 0 }, { 9, 13, 0 }, { 11, 16, -2 }, 221 + { 14, 17, -4 }, { 15, 18, -6 }, { 15, 19, -8 }, { 15, 20, -8 }, 222 + { 15, 20, -8 }, { 15, 21, -10 }, { 17, 21, -10 }, 223 + { 17, 21, -12 }, { 17, 21, -12 }, { 19, 22, -12 }, 224 + { 22, 23, -12 } 225 + } 226 + }, 227 + /* 12BPP/16BPC */ 228 + { 341, 15, 2048, 19, 28, 27, 27, { 229 + { 0, 6, 2 }, { 6, 11, 0 }, { 11, 15, 0 }, { 14, 18, -2 }, 230 + { 18, 21, -4 }, { 19, 22, -6 }, { 19, 23, -8 }, { 19, 24, -8 }, 231 + { 19, 24, -8 }, { 19, 25, -10 }, { 21, 25, -10 }, 232 + { 21, 25, -12 }, { 21, 25, -12 }, { 23, 26, -12 }, 233 + { 26, 27, -12 } 234 + } 235 + }, 236 + }, 237 + { 238 + /* 15BPP/8BPC */ 239 + { 273, 15, 2048, 3, 12, 11, 11, { 240 + { 0, 0, 10 }, { 0, 1, 8 }, { 0, 1, 6 }, { 0, 2, 4 }, 241 + { 1, 2, 2 }, { 1, 3, 0 }, { 1, 3, -2 }, { 2, 4, -4 }, 242 + { 2, 5, -6 }, { 3, 5, -8 }, { 4, 6, -10 }, { 4, 7, -10 }, 243 + { 5, 7, -12 }, { 7, 8, -12 }, { 8, 9, -12 } 244 + } 245 + }, 246 + /* 15BPP/10BPC */ 247 + { 273, 15, 2048, 7, 16, 15, 15, { 248 + { 0, 2, 10 }, { 2, 5, 8 }, { 3, 5, 6 }, { 4, 6, 4 }, 249 + { 5, 6, 2 }, { 5, 7, 0 }, { 5, 7, -2 }, { 6, 8, -4 }, 250 + { 6, 9, -6 }, { 7, 9, -8 }, { 8, 10, -10 }, { 8, 11, -10 }, 251 + { 9, 11, -12 }, { 11, 12, -12 }, { 12, 13, -12 } 252 + } 253 + }, 254 + /* 15BPP/12BPC */ 255 + { 273, 15, 2048, 11, 20, 19, 19, { 256 + { 0, 4, 10 }, { 2, 7, 8 }, { 4, 9, 6 }, { 6, 11, 4 }, 257 + { 9, 11, 2 }, { 9, 11, 0 }, { 9, 12, -2 }, { 10, 12, -4 }, 258 + { 11, 13, -6 }, { 11, 13, -8 }, { 12, 14, -10 }, 259 + { 13, 15, -10 }, { 13, 15, -12 }, { 15, 16, -12 }, 260 + { 16, 17, -12 } 261 + } 262 + }, 263 + /* 15BPP/14BPC */ 264 + { 273, 15, 2048, 15, 24, 23, 23, { 265 + { 0, 4, 10 }, { 3, 8, 8 }, { 6, 11, 6 }, { 9, 14, 4 }, 266 + { 13, 15, 2 }, { 13, 15, 0 }, { 13, 16, -2 }, { 14, 16, -4 }, 267 + { 15, 17, -6 }, { 15, 17, -8 }, { 16, 18, -10 }, 268 + { 17, 19, -10 }, { 17, 19, -12 }, { 19, 20, -12 }, 269 + { 20, 21, -12 } 270 + } 271 + }, 272 + /* 15BPP/16BPC */ 273 + { 273, 15, 2048, 19, 28, 27, 27, { 274 + { 0, 4, 10 }, { 4, 9, 8 }, { 8, 13, 6 }, { 12, 17, 4 }, 275 + { 17, 19, 2 }, { 17, 20, 0 }, { 17, 20, -2 }, { 18, 20, -4 }, 276 + { 19, 21, -6 }, { 19, 21, -8 }, { 20, 22, -10 }, 277 + { 21, 23, -10 }, { 21, 23, -12 }, { 23, 24, -12 }, 278 + { 24, 25, -12 } 279 + } 280 + } 281 + } 282 + 283 + }; 284 + 285 + static int get_row_index_for_rc_params(u16 compressed_bpp) 286 + { 287 + switch (compressed_bpp) { 288 + case 6: 289 + return ROW_INDEX_6BPP; 290 + case 8: 291 + return ROW_INDEX_8BPP; 292 + case 10: 293 + return ROW_INDEX_10BPP; 294 + case 12: 295 + return ROW_INDEX_12BPP; 296 + case 15: 297 + return ROW_INDEX_15BPP; 298 + default: 299 + return -EINVAL; 300 + } 301 + } 302 + 303 + static int get_column_index_for_rc_params(u8 bits_per_component) 304 + { 305 + switch (bits_per_component) { 306 + case 8: 307 + return COLUMN_INDEX_8BPC; 308 + case 10: 309 + return COLUMN_INDEX_10BPC; 310 + case 12: 311 + return COLUMN_INDEX_12BPC; 312 + case 14: 313 + return COLUMN_INDEX_14BPC; 314 + case 16: 315 + return COLUMN_INDEX_16BPC; 316 + default: 317 + return -EINVAL; 318 + } 319 + } 320 + 321 + static int intel_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg) 322 + { 323 + unsigned long groups_per_line = 0; 324 + unsigned long groups_total = 0; 325 + unsigned long num_extra_mux_bits = 0; 326 + unsigned long slice_bits = 0; 327 + unsigned long hrd_delay = 0; 328 + unsigned long final_scale = 0; 329 + unsigned long rbs_min = 0; 330 + 331 + /* Number of groups used to code each line of a slice */ 332 + groups_per_line = DIV_ROUND_UP(vdsc_cfg->slice_width, 333 + DSC_RC_PIXELS_PER_GROUP); 334 + 335 + /* chunksize in Bytes */ 336 + vdsc_cfg->slice_chunk_size = DIV_ROUND_UP(vdsc_cfg->slice_width * 337 + vdsc_cfg->bits_per_pixel, 338 + (8 * 16)); 339 + 340 + if (vdsc_cfg->convert_rgb) 341 + num_extra_mux_bits = 3 * (vdsc_cfg->mux_word_size + 342 + (4 * vdsc_cfg->bits_per_component + 4) 343 + - 2); 344 + else 345 + num_extra_mux_bits = 3 * vdsc_cfg->mux_word_size + 346 + (4 * vdsc_cfg->bits_per_component + 4) + 347 + 2 * (4 * vdsc_cfg->bits_per_component) - 2; 348 + /* Number of bits in one Slice */ 349 + slice_bits = 8 * vdsc_cfg->slice_chunk_size * vdsc_cfg->slice_height; 350 + 351 + while ((num_extra_mux_bits > 0) && 352 + ((slice_bits - num_extra_mux_bits) % vdsc_cfg->mux_word_size)) 353 + num_extra_mux_bits--; 354 + 355 + if (groups_per_line < vdsc_cfg->initial_scale_value - 8) 356 + vdsc_cfg->initial_scale_value = groups_per_line + 8; 357 + 358 + /* scale_decrement_interval calculation according to DSC spec 1.11 */ 359 + if (vdsc_cfg->initial_scale_value > 8) 360 + vdsc_cfg->scale_decrement_interval = groups_per_line / 361 + (vdsc_cfg->initial_scale_value - 8); 362 + else 363 + vdsc_cfg->scale_decrement_interval = DSC_SCALE_DECREMENT_INTERVAL_MAX; 364 + 365 + vdsc_cfg->final_offset = vdsc_cfg->rc_model_size - 366 + (vdsc_cfg->initial_xmit_delay * 367 + vdsc_cfg->bits_per_pixel + 8) / 16 + num_extra_mux_bits; 368 + 369 + if (vdsc_cfg->final_offset >= vdsc_cfg->rc_model_size) { 370 + DRM_DEBUG_KMS("FinalOfs < RcModelSze for this InitialXmitDelay\n"); 371 + return -ERANGE; 372 + } 373 + 374 + final_scale = (vdsc_cfg->rc_model_size * 8) / 375 + (vdsc_cfg->rc_model_size - vdsc_cfg->final_offset); 376 + if (vdsc_cfg->slice_height > 1) 377 + /* 378 + * NflBpgOffset is 16 bit value with 11 fractional bits 379 + * hence we multiply by 2^11 for preserving the 380 + * fractional part 381 + */ 382 + vdsc_cfg->nfl_bpg_offset = DIV_ROUND_UP((vdsc_cfg->first_line_bpg_offset << 11), 383 + (vdsc_cfg->slice_height - 1)); 384 + else 385 + vdsc_cfg->nfl_bpg_offset = 0; 386 + 387 + /* 2^16 - 1 */ 388 + if (vdsc_cfg->nfl_bpg_offset > 65535) { 389 + DRM_DEBUG_KMS("NflBpgOffset is too large for this slice height\n"); 390 + return -ERANGE; 391 + } 392 + 393 + /* Number of groups used to code the entire slice */ 394 + groups_total = groups_per_line * vdsc_cfg->slice_height; 395 + 396 + /* slice_bpg_offset is 16 bit value with 11 fractional bits */ 397 + vdsc_cfg->slice_bpg_offset = DIV_ROUND_UP(((vdsc_cfg->rc_model_size - 398 + vdsc_cfg->initial_offset + 399 + num_extra_mux_bits) << 11), 400 + groups_total); 401 + 402 + if (final_scale > 9) { 403 + /* 404 + * ScaleIncrementInterval = 405 + * finaloffset/((NflBpgOffset + SliceBpgOffset)*8(finalscale - 1.125)) 406 + * as (NflBpgOffset + SliceBpgOffset) has 11 bit fractional value, 407 + * we need divide by 2^11 from pstDscCfg values 408 + */ 409 + vdsc_cfg->scale_increment_interval = 410 + (vdsc_cfg->final_offset * (1 << 11)) / 411 + ((vdsc_cfg->nfl_bpg_offset + 412 + vdsc_cfg->slice_bpg_offset) * 413 + (final_scale - 9)); 414 + } else { 415 + /* 416 + * If finalScaleValue is less than or equal to 9, a value of 0 should 417 + * be used to disable the scale increment at the end of the slice 418 + */ 419 + vdsc_cfg->scale_increment_interval = 0; 420 + } 421 + 422 + if (vdsc_cfg->scale_increment_interval > 65535) { 423 + DRM_DEBUG_KMS("ScaleIncrementInterval is large for slice height\n"); 424 + return -ERANGE; 425 + } 426 + 427 + /* 428 + * DSC spec mentions that bits_per_pixel specifies the target 429 + * bits/pixel (bpp) rate that is used by the encoder, 430 + * in steps of 1/16 of a bit per pixel 431 + */ 432 + rbs_min = vdsc_cfg->rc_model_size - vdsc_cfg->initial_offset + 433 + DIV_ROUND_UP(vdsc_cfg->initial_xmit_delay * 434 + vdsc_cfg->bits_per_pixel, 16) + 435 + groups_per_line * vdsc_cfg->first_line_bpg_offset; 436 + 437 + hrd_delay = DIV_ROUND_UP((rbs_min * 16), vdsc_cfg->bits_per_pixel); 438 + vdsc_cfg->rc_bits = (hrd_delay * vdsc_cfg->bits_per_pixel) / 16; 439 + vdsc_cfg->initial_dec_delay = hrd_delay - vdsc_cfg->initial_xmit_delay; 440 + 441 + return 0; 442 + } 443 + 444 + int intel_dp_compute_dsc_params(struct intel_dp *intel_dp, 445 + struct intel_crtc_state *pipe_config) 446 + { 447 + struct drm_dsc_config *vdsc_cfg = &pipe_config->dp_dsc_cfg; 448 + u16 compressed_bpp = pipe_config->dsc_params.compressed_bpp; 449 + u8 i = 0; 450 + int row_index = 0; 451 + int column_index = 0; 452 + u8 line_buf_depth = 0; 453 + 454 + vdsc_cfg->pic_width = pipe_config->base.adjusted_mode.crtc_hdisplay; 455 + vdsc_cfg->pic_height = pipe_config->base.adjusted_mode.crtc_vdisplay; 456 + vdsc_cfg->slice_width = DIV_ROUND_UP(vdsc_cfg->pic_width, 457 + pipe_config->dsc_params.slice_count); 458 + /* 459 + * Slice Height of 8 works for all currently available panels. So start 460 + * with that if pic_height is an integral multiple of 8. 461 + * Eventually add logic to try multiple slice heights. 462 + */ 463 + if (vdsc_cfg->pic_height % 8 == 0) 464 + vdsc_cfg->slice_height = 8; 465 + else if (vdsc_cfg->pic_height % 4 == 0) 466 + vdsc_cfg->slice_height = 4; 467 + else 468 + vdsc_cfg->slice_height = 2; 469 + 470 + /* Values filled from DSC Sink DPCD */ 471 + vdsc_cfg->dsc_version_major = 472 + (intel_dp->dsc_dpcd[DP_DSC_REV - DP_DSC_SUPPORT] & 473 + DP_DSC_MAJOR_MASK) >> DP_DSC_MAJOR_SHIFT; 474 + vdsc_cfg->dsc_version_minor = 475 + min(DSC_SUPPORTED_VERSION_MIN, 476 + (intel_dp->dsc_dpcd[DP_DSC_REV - DP_DSC_SUPPORT] & 477 + DP_DSC_MINOR_MASK) >> DP_DSC_MINOR_SHIFT); 478 + 479 + vdsc_cfg->convert_rgb = intel_dp->dsc_dpcd[DP_DSC_DEC_COLOR_FORMAT_CAP - DP_DSC_SUPPORT] & 480 + DP_DSC_RGB; 481 + 482 + line_buf_depth = drm_dp_dsc_sink_line_buf_depth(intel_dp->dsc_dpcd); 483 + if (!line_buf_depth) { 484 + DRM_DEBUG_KMS("DSC Sink Line Buffer Depth invalid\n"); 485 + return -EINVAL; 486 + } 487 + if (vdsc_cfg->dsc_version_minor == 2) 488 + vdsc_cfg->line_buf_depth = (line_buf_depth == DSC_1_2_MAX_LINEBUF_DEPTH_BITS) ? 489 + DSC_1_2_MAX_LINEBUF_DEPTH_VAL : line_buf_depth; 490 + else 491 + vdsc_cfg->line_buf_depth = (line_buf_depth > DSC_1_1_MAX_LINEBUF_DEPTH_BITS) ? 492 + DSC_1_1_MAX_LINEBUF_DEPTH_BITS : line_buf_depth; 493 + 494 + /* Gen 11 does not support YCbCr */ 495 + vdsc_cfg->enable422 = false; 496 + /* Gen 11 does not support VBR */ 497 + vdsc_cfg->vbr_enable = false; 498 + vdsc_cfg->block_pred_enable = 499 + intel_dp->dsc_dpcd[DP_DSC_BLK_PREDICTION_SUPPORT - DP_DSC_SUPPORT] & 500 + DP_DSC_BLK_PREDICTION_IS_SUPPORTED; 501 + 502 + /* Gen 11 only supports integral values of bpp */ 503 + vdsc_cfg->bits_per_pixel = compressed_bpp << 4; 504 + vdsc_cfg->bits_per_component = pipe_config->pipe_bpp / 3; 505 + 506 + for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) { 507 + /* 508 + * six 0s are appended to the lsb of each threshold value 509 + * internally in h/w. 510 + * Only 8 bits are allowed for programming RcBufThreshold 511 + */ 512 + vdsc_cfg->rc_buf_thresh[i] = rc_buf_thresh[i] >> 6; 513 + } 514 + 515 + /* 516 + * For 6bpp, RC Buffer threshold 12 and 13 need a different value 517 + * as per C Model 518 + */ 519 + if (compressed_bpp == 6) { 520 + vdsc_cfg->rc_buf_thresh[12] = 0x7C; 521 + vdsc_cfg->rc_buf_thresh[13] = 0x7D; 522 + } 523 + 524 + row_index = get_row_index_for_rc_params(compressed_bpp); 525 + column_index = 526 + get_column_index_for_rc_params(vdsc_cfg->bits_per_component); 527 + 528 + if (row_index < 0 || column_index < 0) 529 + return -EINVAL; 530 + 531 + vdsc_cfg->first_line_bpg_offset = 532 + rc_params[row_index][column_index].first_line_bpg_offset; 533 + vdsc_cfg->initial_xmit_delay = 534 + rc_params[row_index][column_index].initial_xmit_delay; 535 + vdsc_cfg->initial_offset = 536 + rc_params[row_index][column_index].initial_offset; 537 + vdsc_cfg->flatness_min_qp = 538 + rc_params[row_index][column_index].flatness_min_qp; 539 + vdsc_cfg->flatness_max_qp = 540 + rc_params[row_index][column_index].flatness_max_qp; 541 + vdsc_cfg->rc_quant_incr_limit0 = 542 + rc_params[row_index][column_index].rc_quant_incr_limit0; 543 + vdsc_cfg->rc_quant_incr_limit1 = 544 + rc_params[row_index][column_index].rc_quant_incr_limit1; 545 + 546 + for (i = 0; i < DSC_NUM_BUF_RANGES; i++) { 547 + vdsc_cfg->rc_range_params[i].range_min_qp = 548 + rc_params[row_index][column_index].rc_range_params[i].range_min_qp; 549 + vdsc_cfg->rc_range_params[i].range_max_qp = 550 + rc_params[row_index][column_index].rc_range_params[i].range_max_qp; 551 + /* 552 + * Range BPG Offset uses 2's complement and is only a 6 bits. So 553 + * mask it to get only 6 bits. 554 + */ 555 + vdsc_cfg->rc_range_params[i].range_bpg_offset = 556 + rc_params[row_index][column_index].rc_range_params[i].range_bpg_offset & 557 + DSC_RANGE_BPG_OFFSET_MASK; 558 + } 559 + 560 + /* 561 + * BitsPerComponent value determines mux_word_size: 562 + * When BitsPerComponent is 12bpc, muxWordSize will be equal to 64 bits 563 + * When BitsPerComponent is 8 or 10bpc, muxWordSize will be equal to 564 + * 48 bits 565 + */ 566 + if (vdsc_cfg->bits_per_component == 8 || 567 + vdsc_cfg->bits_per_component == 10) 568 + vdsc_cfg->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC; 569 + else if (vdsc_cfg->bits_per_component == 12) 570 + vdsc_cfg->mux_word_size = DSC_MUX_WORD_SIZE_12_BPC; 571 + 572 + /* RC_MODEL_SIZE is a constant across all configurations */ 573 + vdsc_cfg->rc_model_size = DSC_RC_MODEL_SIZE_CONST; 574 + /* InitialScaleValue is a 6 bit value with 3 fractional bits (U3.3) */ 575 + vdsc_cfg->initial_scale_value = (vdsc_cfg->rc_model_size << 3) / 576 + (vdsc_cfg->rc_model_size - vdsc_cfg->initial_offset); 577 + 578 + return intel_compute_rc_parameters(vdsc_cfg); 579 + } 580 + 581 + enum intel_display_power_domain 582 + intel_dsc_power_domain(const struct intel_crtc_state *crtc_state) 583 + { 584 + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 585 + 586 + /* 587 + * On ICL VDSC/joining for eDP transcoder uses a separate power well PW2 588 + * This requires POWER_DOMAIN_TRANSCODER_EDP_VDSC power domain. 589 + * For any other transcoder, VDSC/joining uses the power well associated 590 + * with the pipe/transcoder in use. Hence another reference on the 591 + * transcoder power domain will suffice. 592 + */ 593 + if (cpu_transcoder == TRANSCODER_EDP) 594 + return POWER_DOMAIN_TRANSCODER_EDP_VDSC; 595 + else 596 + return POWER_DOMAIN_TRANSCODER(cpu_transcoder); 597 + } 598 + 599 + static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder, 600 + const struct intel_crtc_state *crtc_state) 601 + { 602 + struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); 603 + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 604 + const struct drm_dsc_config *vdsc_cfg = &crtc_state->dp_dsc_cfg; 605 + enum pipe pipe = crtc->pipe; 606 + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 607 + u32 pps_val = 0; 608 + u32 rc_buf_thresh_dword[4]; 609 + u32 rc_range_params_dword[8]; 610 + u8 num_vdsc_instances = (crtc_state->dsc_params.dsc_split) ? 2 : 1; 611 + int i = 0; 612 + 613 + /* Populate PICTURE_PARAMETER_SET_0 registers */ 614 + pps_val = DSC_VER_MAJ | vdsc_cfg->dsc_version_minor << 615 + DSC_VER_MIN_SHIFT | 616 + vdsc_cfg->bits_per_component << DSC_BPC_SHIFT | 617 + vdsc_cfg->line_buf_depth << DSC_LINE_BUF_DEPTH_SHIFT; 618 + if (vdsc_cfg->block_pred_enable) 619 + pps_val |= DSC_BLOCK_PREDICTION; 620 + if (vdsc_cfg->convert_rgb) 621 + pps_val |= DSC_COLOR_SPACE_CONVERSION; 622 + if (vdsc_cfg->enable422) 623 + pps_val |= DSC_422_ENABLE; 624 + if (vdsc_cfg->vbr_enable) 625 + pps_val |= DSC_VBR_ENABLE; 626 + DRM_INFO("PPS0 = 0x%08x\n", pps_val); 627 + if (cpu_transcoder == TRANSCODER_EDP) { 628 + I915_WRITE(DSCA_PICTURE_PARAMETER_SET_0, pps_val); 629 + /* 630 + * If 2 VDSC instances are needed, configure PPS for second 631 + * VDSC 632 + */ 633 + if (crtc_state->dsc_params.dsc_split) 634 + I915_WRITE(DSCC_PICTURE_PARAMETER_SET_0, pps_val); 635 + } else { 636 + I915_WRITE(ICL_DSC0_PICTURE_PARAMETER_SET_0(pipe), pps_val); 637 + if (crtc_state->dsc_params.dsc_split) 638 + I915_WRITE(ICL_DSC1_PICTURE_PARAMETER_SET_0(pipe), 639 + pps_val); 640 + } 641 + 642 + /* Populate PICTURE_PARAMETER_SET_1 registers */ 643 + pps_val = 0; 644 + pps_val |= DSC_BPP(vdsc_cfg->bits_per_pixel); 645 + DRM_INFO("PPS1 = 0x%08x\n", pps_val); 646 + if (cpu_transcoder == TRANSCODER_EDP) { 647 + I915_WRITE(DSCA_PICTURE_PARAMETER_SET_1, pps_val); 648 + /* 649 + * If 2 VDSC instances are needed, configure PPS for second 650 + * VDSC 651 + */ 652 + if (crtc_state->dsc_params.dsc_split) 653 + I915_WRITE(DSCC_PICTURE_PARAMETER_SET_1, pps_val); 654 + } else { 655 + I915_WRITE(ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe), pps_val); 656 + if (crtc_state->dsc_params.dsc_split) 657 + I915_WRITE(ICL_DSC1_PICTURE_PARAMETER_SET_1(pipe), 658 + pps_val); 659 + } 660 + 661 + /* Populate PICTURE_PARAMETER_SET_2 registers */ 662 + pps_val = 0; 663 + pps_val |= DSC_PIC_HEIGHT(vdsc_cfg->pic_height) | 664 + DSC_PIC_WIDTH(vdsc_cfg->pic_width / num_vdsc_instances); 665 + DRM_INFO("PPS2 = 0x%08x\n", pps_val); 666 + if (encoder->type == INTEL_OUTPUT_EDP) { 667 + I915_WRITE(DSCA_PICTURE_PARAMETER_SET_2, pps_val); 668 + /* 669 + * If 2 VDSC instances are needed, configure PPS for second 670 + * VDSC 671 + */ 672 + if (crtc_state->dsc_params.dsc_split) 673 + I915_WRITE(DSCC_PICTURE_PARAMETER_SET_2, pps_val); 674 + } else { 675 + I915_WRITE(ICL_DSC0_PICTURE_PARAMETER_SET_2(pipe), pps_val); 676 + if (crtc_state->dsc_params.dsc_split) 677 + I915_WRITE(ICL_DSC1_PICTURE_PARAMETER_SET_2(pipe), 678 + pps_val); 679 + } 680 + 681 + /* Populate PICTURE_PARAMETER_SET_3 registers */ 682 + pps_val = 0; 683 + pps_val |= DSC_SLICE_HEIGHT(vdsc_cfg->slice_height) | 684 + DSC_SLICE_WIDTH(vdsc_cfg->slice_width); 685 + DRM_INFO("PPS3 = 0x%08x\n", pps_val); 686 + if (cpu_transcoder == TRANSCODER_EDP) { 687 + I915_WRITE(DSCA_PICTURE_PARAMETER_SET_3, pps_val); 688 + /* 689 + * If 2 VDSC instances are needed, configure PPS for second 690 + * VDSC 691 + */ 692 + if (crtc_state->dsc_params.dsc_split) 693 + I915_WRITE(DSCC_PICTURE_PARAMETER_SET_3, pps_val); 694 + } else { 695 + I915_WRITE(ICL_DSC0_PICTURE_PARAMETER_SET_3(pipe), pps_val); 696 + if (crtc_state->dsc_params.dsc_split) 697 + I915_WRITE(ICL_DSC1_PICTURE_PARAMETER_SET_3(pipe), 698 + pps_val); 699 + } 700 + 701 + /* Populate PICTURE_PARAMETER_SET_4 registers */ 702 + pps_val = 0; 703 + pps_val |= DSC_INITIAL_XMIT_DELAY(vdsc_cfg->initial_xmit_delay) | 704 + DSC_INITIAL_DEC_DELAY(vdsc_cfg->initial_dec_delay); 705 + DRM_INFO("PPS4 = 0x%08x\n", pps_val); 706 + if (cpu_transcoder == TRANSCODER_EDP) { 707 + I915_WRITE(DSCA_PICTURE_PARAMETER_SET_4, pps_val); 708 + /* 709 + * If 2 VDSC instances are needed, configure PPS for second 710 + * VDSC 711 + */ 712 + if (crtc_state->dsc_params.dsc_split) 713 + I915_WRITE(DSCC_PICTURE_PARAMETER_SET_4, pps_val); 714 + } else { 715 + I915_WRITE(ICL_DSC0_PICTURE_PARAMETER_SET_4(pipe), pps_val); 716 + if (crtc_state->dsc_params.dsc_split) 717 + I915_WRITE(ICL_DSC1_PICTURE_PARAMETER_SET_4(pipe), 718 + pps_val); 719 + } 720 + 721 + /* Populate PICTURE_PARAMETER_SET_5 registers */ 722 + pps_val = 0; 723 + pps_val |= DSC_SCALE_INC_INT(vdsc_cfg->scale_increment_interval) | 724 + DSC_SCALE_DEC_INT(vdsc_cfg->scale_decrement_interval); 725 + DRM_INFO("PPS5 = 0x%08x\n", pps_val); 726 + if (cpu_transcoder == TRANSCODER_EDP) { 727 + I915_WRITE(DSCA_PICTURE_PARAMETER_SET_5, pps_val); 728 + /* 729 + * If 2 VDSC instances are needed, configure PPS for second 730 + * VDSC 731 + */ 732 + if (crtc_state->dsc_params.dsc_split) 733 + I915_WRITE(DSCC_PICTURE_PARAMETER_SET_5, pps_val); 734 + } else { 735 + I915_WRITE(ICL_DSC0_PICTURE_PARAMETER_SET_5(pipe), pps_val); 736 + if (crtc_state->dsc_params.dsc_split) 737 + I915_WRITE(ICL_DSC1_PICTURE_PARAMETER_SET_5(pipe), 738 + pps_val); 739 + } 740 + 741 + /* Populate PICTURE_PARAMETER_SET_6 registers */ 742 + pps_val = 0; 743 + pps_val |= DSC_INITIAL_SCALE_VALUE(vdsc_cfg->initial_scale_value) | 744 + DSC_FIRST_LINE_BPG_OFFSET(vdsc_cfg->first_line_bpg_offset) | 745 + DSC_FLATNESS_MIN_QP(vdsc_cfg->flatness_min_qp) | 746 + DSC_FLATNESS_MAX_QP(vdsc_cfg->flatness_max_qp); 747 + DRM_INFO("PPS6 = 0x%08x\n", pps_val); 748 + if (cpu_transcoder == TRANSCODER_EDP) { 749 + I915_WRITE(DSCA_PICTURE_PARAMETER_SET_6, pps_val); 750 + /* 751 + * If 2 VDSC instances are needed, configure PPS for second 752 + * VDSC 753 + */ 754 + if (crtc_state->dsc_params.dsc_split) 755 + I915_WRITE(DSCC_PICTURE_PARAMETER_SET_6, pps_val); 756 + } else { 757 + I915_WRITE(ICL_DSC0_PICTURE_PARAMETER_SET_6(pipe), pps_val); 758 + if (crtc_state->dsc_params.dsc_split) 759 + I915_WRITE(ICL_DSC1_PICTURE_PARAMETER_SET_6(pipe), 760 + pps_val); 761 + } 762 + 763 + /* Populate PICTURE_PARAMETER_SET_7 registers */ 764 + pps_val = 0; 765 + pps_val |= DSC_SLICE_BPG_OFFSET(vdsc_cfg->slice_bpg_offset) | 766 + DSC_NFL_BPG_OFFSET(vdsc_cfg->nfl_bpg_offset); 767 + DRM_INFO("PPS7 = 0x%08x\n", pps_val); 768 + if (cpu_transcoder == TRANSCODER_EDP) { 769 + I915_WRITE(DSCA_PICTURE_PARAMETER_SET_7, pps_val); 770 + /* 771 + * If 2 VDSC instances are needed, configure PPS for second 772 + * VDSC 773 + */ 774 + if (crtc_state->dsc_params.dsc_split) 775 + I915_WRITE(DSCC_PICTURE_PARAMETER_SET_7, pps_val); 776 + } else { 777 + I915_WRITE(ICL_DSC0_PICTURE_PARAMETER_SET_7(pipe), pps_val); 778 + if (crtc_state->dsc_params.dsc_split) 779 + I915_WRITE(ICL_DSC1_PICTURE_PARAMETER_SET_7(pipe), 780 + pps_val); 781 + } 782 + 783 + /* Populate PICTURE_PARAMETER_SET_8 registers */ 784 + pps_val = 0; 785 + pps_val |= DSC_FINAL_OFFSET(vdsc_cfg->final_offset) | 786 + DSC_INITIAL_OFFSET(vdsc_cfg->initial_offset); 787 + DRM_INFO("PPS8 = 0x%08x\n", pps_val); 788 + if (cpu_transcoder == TRANSCODER_EDP) { 789 + I915_WRITE(DSCA_PICTURE_PARAMETER_SET_8, pps_val); 790 + /* 791 + * If 2 VDSC instances are needed, configure PPS for second 792 + * VDSC 793 + */ 794 + if (crtc_state->dsc_params.dsc_split) 795 + I915_WRITE(DSCC_PICTURE_PARAMETER_SET_8, pps_val); 796 + } else { 797 + I915_WRITE(ICL_DSC0_PICTURE_PARAMETER_SET_8(pipe), pps_val); 798 + if (crtc_state->dsc_params.dsc_split) 799 + I915_WRITE(ICL_DSC1_PICTURE_PARAMETER_SET_8(pipe), 800 + pps_val); 801 + } 802 + 803 + /* Populate PICTURE_PARAMETER_SET_9 registers */ 804 + pps_val = 0; 805 + pps_val |= DSC_RC_MODEL_SIZE(DSC_RC_MODEL_SIZE_CONST) | 806 + DSC_RC_EDGE_FACTOR(DSC_RC_EDGE_FACTOR_CONST); 807 + DRM_INFO("PPS9 = 0x%08x\n", pps_val); 808 + if (cpu_transcoder == TRANSCODER_EDP) { 809 + I915_WRITE(DSCA_PICTURE_PARAMETER_SET_9, pps_val); 810 + /* 811 + * If 2 VDSC instances are needed, configure PPS for second 812 + * VDSC 813 + */ 814 + if (crtc_state->dsc_params.dsc_split) 815 + I915_WRITE(DSCC_PICTURE_PARAMETER_SET_9, pps_val); 816 + } else { 817 + I915_WRITE(ICL_DSC0_PICTURE_PARAMETER_SET_9(pipe), pps_val); 818 + if (crtc_state->dsc_params.dsc_split) 819 + I915_WRITE(ICL_DSC1_PICTURE_PARAMETER_SET_9(pipe), 820 + pps_val); 821 + } 822 + 823 + /* Populate PICTURE_PARAMETER_SET_10 registers */ 824 + pps_val = 0; 825 + pps_val |= DSC_RC_QUANT_INC_LIMIT0(vdsc_cfg->rc_quant_incr_limit0) | 826 + DSC_RC_QUANT_INC_LIMIT1(vdsc_cfg->rc_quant_incr_limit1) | 827 + DSC_RC_TARGET_OFF_HIGH(DSC_RC_TGT_OFFSET_HI_CONST) | 828 + DSC_RC_TARGET_OFF_LOW(DSC_RC_TGT_OFFSET_LO_CONST); 829 + DRM_INFO("PPS10 = 0x%08x\n", pps_val); 830 + if (cpu_transcoder == TRANSCODER_EDP) { 831 + I915_WRITE(DSCA_PICTURE_PARAMETER_SET_10, pps_val); 832 + /* 833 + * If 2 VDSC instances are needed, configure PPS for second 834 + * VDSC 835 + */ 836 + if (crtc_state->dsc_params.dsc_split) 837 + I915_WRITE(DSCC_PICTURE_PARAMETER_SET_10, pps_val); 838 + } else { 839 + I915_WRITE(ICL_DSC0_PICTURE_PARAMETER_SET_10(pipe), pps_val); 840 + if (crtc_state->dsc_params.dsc_split) 841 + I915_WRITE(ICL_DSC1_PICTURE_PARAMETER_SET_10(pipe), 842 + pps_val); 843 + } 844 + 845 + /* Populate Picture parameter set 16 */ 846 + pps_val = 0; 847 + pps_val |= DSC_SLICE_CHUNK_SIZE(vdsc_cfg->slice_chunk_size) | 848 + DSC_SLICE_PER_LINE((vdsc_cfg->pic_width / num_vdsc_instances) / 849 + vdsc_cfg->slice_width) | 850 + DSC_SLICE_ROW_PER_FRAME(vdsc_cfg->pic_height / 851 + vdsc_cfg->slice_height); 852 + DRM_INFO("PPS16 = 0x%08x\n", pps_val); 853 + if (cpu_transcoder == TRANSCODER_EDP) { 854 + I915_WRITE(DSCA_PICTURE_PARAMETER_SET_16, pps_val); 855 + /* 856 + * If 2 VDSC instances are needed, configure PPS for second 857 + * VDSC 858 + */ 859 + if (crtc_state->dsc_params.dsc_split) 860 + I915_WRITE(DSCC_PICTURE_PARAMETER_SET_16, pps_val); 861 + } else { 862 + I915_WRITE(ICL_DSC0_PICTURE_PARAMETER_SET_16(pipe), pps_val); 863 + if (crtc_state->dsc_params.dsc_split) 864 + I915_WRITE(ICL_DSC1_PICTURE_PARAMETER_SET_16(pipe), 865 + pps_val); 866 + } 867 + 868 + /* Populate the RC_BUF_THRESH registers */ 869 + memset(rc_buf_thresh_dword, 0, sizeof(rc_buf_thresh_dword)); 870 + for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) { 871 + rc_buf_thresh_dword[i / 4] |= 872 + (u32)(vdsc_cfg->rc_buf_thresh[i] << 873 + BITS_PER_BYTE * (i % 4)); 874 + DRM_INFO(" RC_BUF_THRESH%d = 0x%08x\n", i, 875 + rc_buf_thresh_dword[i / 4]); 876 + } 877 + if (cpu_transcoder == TRANSCODER_EDP) { 878 + I915_WRITE(DSCA_RC_BUF_THRESH_0, rc_buf_thresh_dword[0]); 879 + I915_WRITE(DSCA_RC_BUF_THRESH_0_UDW, rc_buf_thresh_dword[1]); 880 + I915_WRITE(DSCA_RC_BUF_THRESH_1, rc_buf_thresh_dword[2]); 881 + I915_WRITE(DSCA_RC_BUF_THRESH_1_UDW, rc_buf_thresh_dword[3]); 882 + if (crtc_state->dsc_params.dsc_split) { 883 + I915_WRITE(DSCC_RC_BUF_THRESH_0, 884 + rc_buf_thresh_dword[0]); 885 + I915_WRITE(DSCC_RC_BUF_THRESH_0_UDW, 886 + rc_buf_thresh_dword[1]); 887 + I915_WRITE(DSCC_RC_BUF_THRESH_1, 888 + rc_buf_thresh_dword[2]); 889 + I915_WRITE(DSCC_RC_BUF_THRESH_1_UDW, 890 + rc_buf_thresh_dword[3]); 891 + } 892 + } else { 893 + I915_WRITE(ICL_DSC0_RC_BUF_THRESH_0(pipe), 894 + rc_buf_thresh_dword[0]); 895 + I915_WRITE(ICL_DSC0_RC_BUF_THRESH_0_UDW(pipe), 896 + rc_buf_thresh_dword[1]); 897 + I915_WRITE(ICL_DSC0_RC_BUF_THRESH_1(pipe), 898 + rc_buf_thresh_dword[2]); 899 + I915_WRITE(ICL_DSC0_RC_BUF_THRESH_1_UDW(pipe), 900 + rc_buf_thresh_dword[3]); 901 + if (crtc_state->dsc_params.dsc_split) { 902 + I915_WRITE(ICL_DSC1_RC_BUF_THRESH_0(pipe), 903 + rc_buf_thresh_dword[0]); 904 + I915_WRITE(ICL_DSC1_RC_BUF_THRESH_0_UDW(pipe), 905 + rc_buf_thresh_dword[1]); 906 + I915_WRITE(ICL_DSC1_RC_BUF_THRESH_1(pipe), 907 + rc_buf_thresh_dword[2]); 908 + I915_WRITE(ICL_DSC1_RC_BUF_THRESH_1_UDW(pipe), 909 + rc_buf_thresh_dword[3]); 910 + } 911 + } 912 + 913 + /* Populate the RC_RANGE_PARAMETERS registers */ 914 + memset(rc_range_params_dword, 0, sizeof(rc_range_params_dword)); 915 + for (i = 0; i < DSC_NUM_BUF_RANGES; i++) { 916 + rc_range_params_dword[i / 2] |= 917 + (u32)(((vdsc_cfg->rc_range_params[i].range_bpg_offset << 918 + RC_BPG_OFFSET_SHIFT) | 919 + (vdsc_cfg->rc_range_params[i].range_max_qp << 920 + RC_MAX_QP_SHIFT) | 921 + (vdsc_cfg->rc_range_params[i].range_min_qp << 922 + RC_MIN_QP_SHIFT)) << 16 * (i % 2)); 923 + DRM_INFO(" RC_RANGE_PARAM_%d = 0x%08x\n", i, 924 + rc_range_params_dword[i / 2]); 925 + } 926 + if (cpu_transcoder == TRANSCODER_EDP) { 927 + I915_WRITE(DSCA_RC_RANGE_PARAMETERS_0, 928 + rc_range_params_dword[0]); 929 + I915_WRITE(DSCA_RC_RANGE_PARAMETERS_0_UDW, 930 + rc_range_params_dword[1]); 931 + I915_WRITE(DSCA_RC_RANGE_PARAMETERS_1, 932 + rc_range_params_dword[2]); 933 + I915_WRITE(DSCA_RC_RANGE_PARAMETERS_1_UDW, 934 + rc_range_params_dword[3]); 935 + I915_WRITE(DSCA_RC_RANGE_PARAMETERS_2, 936 + rc_range_params_dword[4]); 937 + I915_WRITE(DSCA_RC_RANGE_PARAMETERS_2_UDW, 938 + rc_range_params_dword[5]); 939 + I915_WRITE(DSCA_RC_RANGE_PARAMETERS_3, 940 + rc_range_params_dword[6]); 941 + I915_WRITE(DSCA_RC_RANGE_PARAMETERS_3_UDW, 942 + rc_range_params_dword[7]); 943 + if (crtc_state->dsc_params.dsc_split) { 944 + I915_WRITE(DSCC_RC_RANGE_PARAMETERS_0, 945 + rc_range_params_dword[0]); 946 + I915_WRITE(DSCC_RC_RANGE_PARAMETERS_0_UDW, 947 + rc_range_params_dword[1]); 948 + I915_WRITE(DSCC_RC_RANGE_PARAMETERS_1, 949 + rc_range_params_dword[2]); 950 + I915_WRITE(DSCC_RC_RANGE_PARAMETERS_1_UDW, 951 + rc_range_params_dword[3]); 952 + I915_WRITE(DSCC_RC_RANGE_PARAMETERS_2, 953 + rc_range_params_dword[4]); 954 + I915_WRITE(DSCC_RC_RANGE_PARAMETERS_2_UDW, 955 + rc_range_params_dword[5]); 956 + I915_WRITE(DSCC_RC_RANGE_PARAMETERS_3, 957 + rc_range_params_dword[6]); 958 + I915_WRITE(DSCC_RC_RANGE_PARAMETERS_3_UDW, 959 + rc_range_params_dword[7]); 960 + } 961 + } else { 962 + I915_WRITE(ICL_DSC0_RC_RANGE_PARAMETERS_0(pipe), 963 + rc_range_params_dword[0]); 964 + I915_WRITE(ICL_DSC0_RC_RANGE_PARAMETERS_0_UDW(pipe), 965 + rc_range_params_dword[1]); 966 + I915_WRITE(ICL_DSC0_RC_RANGE_PARAMETERS_1(pipe), 967 + rc_range_params_dword[2]); 968 + I915_WRITE(ICL_DSC0_RC_RANGE_PARAMETERS_1_UDW(pipe), 969 + rc_range_params_dword[3]); 970 + I915_WRITE(ICL_DSC0_RC_RANGE_PARAMETERS_2(pipe), 971 + rc_range_params_dword[4]); 972 + I915_WRITE(ICL_DSC0_RC_RANGE_PARAMETERS_2_UDW(pipe), 973 + rc_range_params_dword[5]); 974 + I915_WRITE(ICL_DSC0_RC_RANGE_PARAMETERS_3(pipe), 975 + rc_range_params_dword[6]); 976 + I915_WRITE(ICL_DSC0_RC_RANGE_PARAMETERS_3_UDW(pipe), 977 + rc_range_params_dword[7]); 978 + if (crtc_state->dsc_params.dsc_split) { 979 + I915_WRITE(ICL_DSC1_RC_RANGE_PARAMETERS_0(pipe), 980 + rc_range_params_dword[0]); 981 + I915_WRITE(ICL_DSC1_RC_RANGE_PARAMETERS_0_UDW(pipe), 982 + rc_range_params_dword[1]); 983 + I915_WRITE(ICL_DSC1_RC_RANGE_PARAMETERS_1(pipe), 984 + rc_range_params_dword[2]); 985 + I915_WRITE(ICL_DSC1_RC_RANGE_PARAMETERS_1_UDW(pipe), 986 + rc_range_params_dword[3]); 987 + I915_WRITE(ICL_DSC1_RC_RANGE_PARAMETERS_2(pipe), 988 + rc_range_params_dword[4]); 989 + I915_WRITE(ICL_DSC1_RC_RANGE_PARAMETERS_2_UDW(pipe), 990 + rc_range_params_dword[5]); 991 + I915_WRITE(ICL_DSC1_RC_RANGE_PARAMETERS_3(pipe), 992 + rc_range_params_dword[6]); 993 + I915_WRITE(ICL_DSC1_RC_RANGE_PARAMETERS_3_UDW(pipe), 994 + rc_range_params_dword[7]); 995 + } 996 + } 997 + } 998 + 999 + static void intel_dp_write_dsc_pps_sdp(struct intel_encoder *encoder, 1000 + const struct intel_crtc_state *crtc_state) 1001 + { 1002 + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); 1003 + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); 1004 + const struct drm_dsc_config *vdsc_cfg = &crtc_state->dp_dsc_cfg; 1005 + struct drm_dsc_pps_infoframe dp_dsc_pps_sdp; 1006 + 1007 + /* Prepare DP SDP PPS header as per DP 1.4 spec, Table 2-123 */ 1008 + drm_dsc_dp_pps_header_init(&dp_dsc_pps_sdp); 1009 + 1010 + /* Fill the PPS payload bytes as per DSC spec 1.2 Table 4-1 */ 1011 + drm_dsc_pps_infoframe_pack(&dp_dsc_pps_sdp, vdsc_cfg); 1012 + 1013 + intel_dig_port->write_infoframe(encoder, crtc_state, 1014 + DP_SDP_PPS, &dp_dsc_pps_sdp, 1015 + sizeof(dp_dsc_pps_sdp)); 1016 + } 1017 + 1018 + void intel_dsc_enable(struct intel_encoder *encoder, 1019 + const struct intel_crtc_state *crtc_state) 1020 + { 1021 + struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); 1022 + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1023 + enum pipe pipe = crtc->pipe; 1024 + i915_reg_t dss_ctl1_reg, dss_ctl2_reg; 1025 + u32 dss_ctl1_val = 0; 1026 + u32 dss_ctl2_val = 0; 1027 + 1028 + if (!crtc_state->dsc_params.compression_enable) 1029 + return; 1030 + 1031 + /* Enable Power wells for VDSC/joining */ 1032 + intel_display_power_get(dev_priv, 1033 + intel_dsc_power_domain(crtc_state)); 1034 + 1035 + intel_configure_pps_for_dsc_encoder(encoder, crtc_state); 1036 + 1037 + intel_dp_write_dsc_pps_sdp(encoder, crtc_state); 1038 + 1039 + if (crtc_state->cpu_transcoder == TRANSCODER_EDP) { 1040 + dss_ctl1_reg = DSS_CTL1; 1041 + dss_ctl2_reg = DSS_CTL2; 1042 + } else { 1043 + dss_ctl1_reg = ICL_PIPE_DSS_CTL1(pipe); 1044 + dss_ctl2_reg = ICL_PIPE_DSS_CTL2(pipe); 1045 + } 1046 + dss_ctl2_val |= LEFT_BRANCH_VDSC_ENABLE; 1047 + if (crtc_state->dsc_params.dsc_split) { 1048 + dss_ctl2_val |= RIGHT_BRANCH_VDSC_ENABLE; 1049 + dss_ctl1_val |= JOINER_ENABLE; 1050 + } 1051 + I915_WRITE(dss_ctl1_reg, dss_ctl1_val); 1052 + I915_WRITE(dss_ctl2_reg, dss_ctl2_val); 1053 + } 1054 + 1055 + void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state) 1056 + { 1057 + struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); 1058 + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 1059 + enum pipe pipe = crtc->pipe; 1060 + i915_reg_t dss_ctl1_reg, dss_ctl2_reg; 1061 + u32 dss_ctl1_val = 0, dss_ctl2_val = 0; 1062 + 1063 + if (!old_crtc_state->dsc_params.compression_enable) 1064 + return; 1065 + 1066 + if (old_crtc_state->cpu_transcoder == TRANSCODER_EDP) { 1067 + dss_ctl1_reg = DSS_CTL1; 1068 + dss_ctl2_reg = DSS_CTL2; 1069 + } else { 1070 + dss_ctl1_reg = ICL_PIPE_DSS_CTL1(pipe); 1071 + dss_ctl2_reg = ICL_PIPE_DSS_CTL2(pipe); 1072 + } 1073 + dss_ctl1_val = I915_READ(dss_ctl1_reg); 1074 + if (dss_ctl1_val & JOINER_ENABLE) 1075 + dss_ctl1_val &= ~JOINER_ENABLE; 1076 + I915_WRITE(dss_ctl1_reg, dss_ctl1_val); 1077 + 1078 + dss_ctl2_val = I915_READ(dss_ctl2_reg); 1079 + if (dss_ctl2_val & LEFT_BRANCH_VDSC_ENABLE || 1080 + dss_ctl2_val & RIGHT_BRANCH_VDSC_ENABLE) 1081 + dss_ctl2_val &= ~(LEFT_BRANCH_VDSC_ENABLE | 1082 + RIGHT_BRANCH_VDSC_ENABLE); 1083 + I915_WRITE(dss_ctl2_reg, dss_ctl2_val); 1084 + 1085 + /* Disable Power wells for VDSC/joining */ 1086 + intel_display_power_put(dev_priv, 1087 + intel_dsc_power_domain(old_crtc_state)); 1088 + }
+590 -407
drivers/gpu/drm/i915/intel_workarounds.c
··· 48 48 * - Public functions to init or apply the given workaround type. 49 49 */ 50 50 51 - static void wa_add(struct drm_i915_private *i915, 52 - i915_reg_t reg, const u32 mask, const u32 val) 51 + static void wa_init_start(struct i915_wa_list *wal, const char *name) 53 52 { 54 - struct i915_workarounds *wa = &i915->workarounds; 55 - unsigned int start = 0, end = wa->count; 56 - unsigned int addr = i915_mmio_reg_offset(reg); 57 - struct i915_wa_reg *r; 53 + wal->name = name; 54 + } 55 + 56 + #define WA_LIST_CHUNK (1 << 4) 57 + 58 + static void wa_init_finish(struct i915_wa_list *wal) 59 + { 60 + /* Trim unused entries. */ 61 + if (!IS_ALIGNED(wal->count, WA_LIST_CHUNK)) { 62 + struct i915_wa *list = kmemdup(wal->list, 63 + wal->count * sizeof(*list), 64 + GFP_KERNEL); 65 + 66 + if (list) { 67 + kfree(wal->list); 68 + wal->list = list; 69 + } 70 + } 71 + 72 + if (!wal->count) 73 + return; 74 + 75 + DRM_DEBUG_DRIVER("Initialized %u %s workarounds\n", 76 + wal->wa_count, wal->name); 77 + } 78 + 79 + static void _wa_add(struct i915_wa_list *wal, const struct i915_wa *wa) 80 + { 81 + unsigned int addr = i915_mmio_reg_offset(wa->reg); 82 + unsigned int start = 0, end = wal->count; 83 + const unsigned int grow = WA_LIST_CHUNK; 84 + struct i915_wa *wa_; 85 + 86 + GEM_BUG_ON(!is_power_of_2(grow)); 87 + 88 + if (IS_ALIGNED(wal->count, grow)) { /* Either uninitialized or full. */ 89 + struct i915_wa *list; 90 + 91 + list = kmalloc_array(ALIGN(wal->count + 1, grow), sizeof(*wa), 92 + GFP_KERNEL); 93 + if (!list) { 94 + DRM_ERROR("No space for workaround init!\n"); 95 + return; 96 + } 97 + 98 + if (wal->list) 99 + memcpy(list, wal->list, sizeof(*wa) * wal->count); 100 + 101 + wal->list = list; 102 + } 58 103 59 104 while (start < end) { 60 105 unsigned int mid = start + (end - start) / 2; 61 106 62 - if (wa->reg[mid].addr < addr) { 107 + if (i915_mmio_reg_offset(wal->list[mid].reg) < addr) { 63 108 start = mid + 1; 64 - } else if (wa->reg[mid].addr > addr) { 109 + } else if (i915_mmio_reg_offset(wal->list[mid].reg) > addr) { 65 110 end = mid; 66 111 } else { 67 - r = &wa->reg[mid]; 112 + wa_ = &wal->list[mid]; 68 113 69 - if ((mask & ~r->mask) == 0) { 114 + if ((wa->mask & ~wa_->mask) == 0) { 70 115 DRM_ERROR("Discarding overwritten w/a for reg %04x (mask: %08x, value: %08x)\n", 71 - addr, r->mask, r->value); 116 + i915_mmio_reg_offset(wa_->reg), 117 + wa_->mask, wa_->val); 72 118 73 - r->value &= ~mask; 119 + wa_->val &= ~wa->mask; 74 120 } 75 121 76 - r->value |= val; 77 - r->mask |= mask; 122 + wal->wa_count++; 123 + wa_->val |= wa->val; 124 + wa_->mask |= wa->mask; 78 125 return; 79 126 } 80 127 } 81 128 82 - if (WARN_ON_ONCE(wa->count >= I915_MAX_WA_REGS)) { 83 - DRM_ERROR("Dropping w/a for reg %04x (mask: %08x, value: %08x)\n", 84 - addr, mask, val); 85 - return; 86 - } 129 + wal->wa_count++; 130 + wa_ = &wal->list[wal->count++]; 131 + *wa_ = *wa; 87 132 88 - r = &wa->reg[wa->count++]; 89 - r->addr = addr; 90 - r->value = val; 91 - r->mask = mask; 92 - 93 - while (r-- > wa->reg) { 94 - GEM_BUG_ON(r[0].addr == r[1].addr); 95 - if (r[1].addr > r[0].addr) 133 + while (wa_-- > wal->list) { 134 + GEM_BUG_ON(i915_mmio_reg_offset(wa_[0].reg) == 135 + i915_mmio_reg_offset(wa_[1].reg)); 136 + if (i915_mmio_reg_offset(wa_[1].reg) > 137 + i915_mmio_reg_offset(wa_[0].reg)) 96 138 break; 97 139 98 - swap(r[1], r[0]); 140 + swap(wa_[1], wa_[0]); 99 141 } 100 142 } 101 143 102 - #define WA_REG(addr, mask, val) wa_add(dev_priv, (addr), (mask), (val)) 144 + static void 145 + __wa_add(struct i915_wa_list *wal, i915_reg_t reg, u32 mask, u32 val) 146 + { 147 + struct i915_wa wa = { 148 + .reg = reg, 149 + .mask = mask, 150 + .val = val 151 + }; 152 + 153 + _wa_add(wal, &wa); 154 + } 155 + 156 + #define WA_REG(addr, mask, val) __wa_add(wal, (addr), (mask), (val)) 103 157 104 158 #define WA_SET_BIT_MASKED(addr, mask) \ 105 159 WA_REG(addr, (mask), _MASKED_BIT_ENABLE(mask)) ··· 164 110 #define WA_SET_FIELD_MASKED(addr, mask, value) \ 165 111 WA_REG(addr, (mask), _MASKED_FIELD(mask, value)) 166 112 167 - static int gen8_ctx_workarounds_init(struct drm_i915_private *dev_priv) 113 + static void gen8_ctx_workarounds_init(struct intel_engine_cs *engine) 168 114 { 115 + struct i915_wa_list *wal = &engine->ctx_wa_list; 116 + 169 117 WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING); 170 118 171 119 /* WaDisableAsyncFlipPerfMode:bdw,chv */ ··· 211 155 WA_SET_FIELD_MASKED(GEN7_GT_MODE, 212 156 GEN6_WIZ_HASHING_MASK, 213 157 GEN6_WIZ_HASHING_16x4); 214 - 215 - return 0; 216 158 } 217 159 218 - static int bdw_ctx_workarounds_init(struct drm_i915_private *dev_priv) 160 + static void bdw_ctx_workarounds_init(struct intel_engine_cs *engine) 219 161 { 220 - int ret; 162 + struct drm_i915_private *i915 = engine->i915; 163 + struct i915_wa_list *wal = &engine->ctx_wa_list; 221 164 222 - ret = gen8_ctx_workarounds_init(dev_priv); 223 - if (ret) 224 - return ret; 165 + gen8_ctx_workarounds_init(engine); 225 166 226 167 /* WaDisableThreadStallDopClockGating:bdw (pre-production) */ 227 168 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE); ··· 238 185 /* WaForceContextSaveRestoreNonCoherent:bdw */ 239 186 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT | 240 187 /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */ 241 - (IS_BDW_GT3(dev_priv) ? HDC_FENCE_DEST_SLM_DISABLE : 0)); 242 - 243 - return 0; 188 + (IS_BDW_GT3(i915) ? HDC_FENCE_DEST_SLM_DISABLE : 0)); 244 189 } 245 190 246 - static int chv_ctx_workarounds_init(struct drm_i915_private *dev_priv) 191 + static void chv_ctx_workarounds_init(struct intel_engine_cs *engine) 247 192 { 248 - int ret; 193 + struct i915_wa_list *wal = &engine->ctx_wa_list; 249 194 250 - ret = gen8_ctx_workarounds_init(dev_priv); 251 - if (ret) 252 - return ret; 195 + gen8_ctx_workarounds_init(engine); 253 196 254 197 /* WaDisableThreadStallDopClockGating:chv */ 255 198 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE); 256 199 257 200 /* Improve HiZ throughput on CHV. */ 258 201 WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X); 259 - 260 - return 0; 261 202 } 262 203 263 - static int gen9_ctx_workarounds_init(struct drm_i915_private *dev_priv) 204 + static void gen9_ctx_workarounds_init(struct intel_engine_cs *engine) 264 205 { 265 - if (HAS_LLC(dev_priv)) { 206 + struct drm_i915_private *i915 = engine->i915; 207 + struct i915_wa_list *wal = &engine->ctx_wa_list; 208 + 209 + if (HAS_LLC(i915)) { 266 210 /* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl 267 211 * 268 212 * Must match Display Engine. See ··· 278 228 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); 279 229 280 230 /* Syncing dependencies between camera and graphics:skl,bxt,kbl */ 281 - if (!IS_COFFEELAKE(dev_priv)) 231 + if (!IS_COFFEELAKE(i915)) 282 232 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, 283 233 GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC); 284 234 ··· 321 271 HDC_FORCE_NON_COHERENT); 322 272 323 273 /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl,cfl */ 324 - if (IS_SKYLAKE(dev_priv) || 325 - IS_KABYLAKE(dev_priv) || 326 - IS_COFFEELAKE(dev_priv)) 274 + if (IS_SKYLAKE(i915) || IS_KABYLAKE(i915) || IS_COFFEELAKE(i915)) 327 275 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, 328 276 GEN8_SAMPLER_POWER_BYPASS_DIS); 329 277 ··· 348 300 GEN9_PREEMPT_GPGPU_COMMAND_LEVEL); 349 301 350 302 /* WaClearHIZ_WM_CHICKEN3:bxt,glk */ 351 - if (IS_GEN9_LP(dev_priv)) 303 + if (IS_GEN9_LP(i915)) 352 304 WA_SET_BIT_MASKED(GEN9_WM_CHICKEN3, GEN9_FACTOR_IN_CLR_VAL_HIZ); 353 - 354 - return 0; 355 305 } 356 306 357 - static int skl_tune_iz_hashing(struct drm_i915_private *dev_priv) 307 + static void skl_tune_iz_hashing(struct intel_engine_cs *engine) 358 308 { 309 + struct drm_i915_private *i915 = engine->i915; 310 + struct i915_wa_list *wal = &engine->ctx_wa_list; 359 311 u8 vals[3] = { 0, 0, 0 }; 360 312 unsigned int i; 361 313 ··· 366 318 * Only consider slices where one, and only one, subslice has 7 367 319 * EUs 368 320 */ 369 - if (!is_power_of_2(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i])) 321 + if (!is_power_of_2(INTEL_INFO(i915)->sseu.subslice_7eu[i])) 370 322 continue; 371 323 372 324 /* ··· 375 327 * 376 328 * -> 0 <= ss <= 3; 377 329 */ 378 - ss = ffs(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]) - 1; 330 + ss = ffs(INTEL_INFO(i915)->sseu.subslice_7eu[i]) - 1; 379 331 vals[i] = 3 - ss; 380 332 } 381 333 382 334 if (vals[0] == 0 && vals[1] == 0 && vals[2] == 0) 383 - return 0; 335 + return; 384 336 385 337 /* Tune IZ hashing. See intel_device_info_runtime_init() */ 386 338 WA_SET_FIELD_MASKED(GEN7_GT_MODE, ··· 390 342 GEN9_IZ_HASHING(2, vals[2]) | 391 343 GEN9_IZ_HASHING(1, vals[1]) | 392 344 GEN9_IZ_HASHING(0, vals[0])); 393 - 394 - return 0; 395 345 } 396 346 397 - static int skl_ctx_workarounds_init(struct drm_i915_private *dev_priv) 347 + static void skl_ctx_workarounds_init(struct intel_engine_cs *engine) 398 348 { 399 - int ret; 400 - 401 - ret = gen9_ctx_workarounds_init(dev_priv); 402 - if (ret) 403 - return ret; 404 - 405 - return skl_tune_iz_hashing(dev_priv); 349 + gen9_ctx_workarounds_init(engine); 350 + skl_tune_iz_hashing(engine); 406 351 } 407 352 408 - static int bxt_ctx_workarounds_init(struct drm_i915_private *dev_priv) 353 + static void bxt_ctx_workarounds_init(struct intel_engine_cs *engine) 409 354 { 410 - int ret; 355 + struct i915_wa_list *wal = &engine->ctx_wa_list; 411 356 412 - ret = gen9_ctx_workarounds_init(dev_priv); 413 - if (ret) 414 - return ret; 357 + gen9_ctx_workarounds_init(engine); 415 358 416 359 /* WaDisableThreadStallDopClockGating:bxt */ 417 360 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, ··· 411 372 /* WaToEnableHwFixForPushConstHWBug:bxt */ 412 373 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, 413 374 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); 414 - 415 - return 0; 416 375 } 417 376 418 - static int kbl_ctx_workarounds_init(struct drm_i915_private *dev_priv) 377 + static void kbl_ctx_workarounds_init(struct intel_engine_cs *engine) 419 378 { 420 - int ret; 379 + struct drm_i915_private *i915 = engine->i915; 380 + struct i915_wa_list *wal = &engine->ctx_wa_list; 421 381 422 - ret = gen9_ctx_workarounds_init(dev_priv); 423 - if (ret) 424 - return ret; 425 - 426 - /* WaDisableFenceDestinationToSLM:kbl (pre-prod) */ 427 - if (IS_KBL_REVID(dev_priv, KBL_REVID_A0, KBL_REVID_A0)) 428 - WA_SET_BIT_MASKED(HDC_CHICKEN0, 429 - HDC_FENCE_DEST_SLM_DISABLE); 382 + gen9_ctx_workarounds_init(engine); 430 383 431 384 /* WaToEnableHwFixForPushConstHWBug:kbl */ 432 - if (IS_KBL_REVID(dev_priv, KBL_REVID_C0, REVID_FOREVER)) 385 + if (IS_KBL_REVID(i915, KBL_REVID_C0, REVID_FOREVER)) 433 386 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, 434 387 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); 435 388 436 389 /* WaDisableSbeCacheDispatchPortSharing:kbl */ 437 390 WA_SET_BIT_MASKED(GEN7_HALF_SLICE_CHICKEN1, 438 391 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); 439 - 440 - return 0; 441 392 } 442 393 443 - static int glk_ctx_workarounds_init(struct drm_i915_private *dev_priv) 394 + static void glk_ctx_workarounds_init(struct intel_engine_cs *engine) 444 395 { 445 - int ret; 396 + struct i915_wa_list *wal = &engine->ctx_wa_list; 446 397 447 - ret = gen9_ctx_workarounds_init(dev_priv); 448 - if (ret) 449 - return ret; 398 + gen9_ctx_workarounds_init(engine); 450 399 451 400 /* WaToEnableHwFixForPushConstHWBug:glk */ 452 401 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, 453 402 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); 454 - 455 - return 0; 456 403 } 457 404 458 - static int cfl_ctx_workarounds_init(struct drm_i915_private *dev_priv) 405 + static void cfl_ctx_workarounds_init(struct intel_engine_cs *engine) 459 406 { 460 - int ret; 407 + struct i915_wa_list *wal = &engine->ctx_wa_list; 461 408 462 - ret = gen9_ctx_workarounds_init(dev_priv); 463 - if (ret) 464 - return ret; 409 + gen9_ctx_workarounds_init(engine); 465 410 466 411 /* WaToEnableHwFixForPushConstHWBug:cfl */ 467 412 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, ··· 454 431 /* WaDisableSbeCacheDispatchPortSharing:cfl */ 455 432 WA_SET_BIT_MASKED(GEN7_HALF_SLICE_CHICKEN1, 456 433 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); 457 - 458 - return 0; 459 434 } 460 435 461 - static int cnl_ctx_workarounds_init(struct drm_i915_private *dev_priv) 436 + static void cnl_ctx_workarounds_init(struct intel_engine_cs *engine) 462 437 { 438 + struct drm_i915_private *i915 = engine->i915; 439 + struct i915_wa_list *wal = &engine->ctx_wa_list; 440 + 463 441 /* WaForceContextSaveRestoreNonCoherent:cnl */ 464 442 WA_SET_BIT_MASKED(CNL_HDC_CHICKEN0, 465 443 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT); 466 444 467 445 /* WaThrottleEUPerfToAvoidTDBackPressure:cnl(pre-prod) */ 468 - if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0)) 446 + if (IS_CNL_REVID(i915, CNL_REVID_B0, CNL_REVID_B0)) 469 447 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, THROTTLE_12_5); 470 448 471 449 /* WaDisableReplayBufferBankArbitrationOptimization:cnl */ ··· 474 450 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); 475 451 476 452 /* WaDisableEnhancedSBEVertexCaching:cnl (pre-prod) */ 477 - if (IS_CNL_REVID(dev_priv, 0, CNL_REVID_B0)) 453 + if (IS_CNL_REVID(i915, 0, CNL_REVID_B0)) 478 454 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, 479 455 GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE); 480 456 ··· 494 470 495 471 /* WaDisableEarlyEOT:cnl */ 496 472 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, DISABLE_EARLY_EOT); 497 - 498 - return 0; 499 473 } 500 474 501 - static int icl_ctx_workarounds_init(struct drm_i915_private *dev_priv) 475 + static void icl_ctx_workarounds_init(struct intel_engine_cs *engine) 502 476 { 477 + struct drm_i915_private *i915 = engine->i915; 478 + struct i915_wa_list *wal = &engine->ctx_wa_list; 479 + 503 480 /* Wa_1604370585:icl (pre-prod) 504 481 * Formerly known as WaPushConstantDereferenceHoldDisable 505 482 */ 506 - if (IS_ICL_REVID(dev_priv, ICL_REVID_A0, ICL_REVID_B0)) 483 + if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_B0)) 507 484 WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, 508 485 PUSH_CONSTANT_DEREF_DISABLE); 509 486 ··· 520 495 /* Wa_2006611047:icl (pre-prod) 521 496 * Formerly known as WaDisableImprovedTdlClkGating 522 497 */ 523 - if (IS_ICL_REVID(dev_priv, ICL_REVID_A0, ICL_REVID_A0)) 498 + if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_A0)) 524 499 WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, 525 500 GEN11_TDL_CLOCK_GATING_FIX_DISABLE); 526 501 ··· 529 504 GEN11_STATE_CACHE_REDIRECT_TO_CS); 530 505 531 506 /* Wa_2006665173:icl (pre-prod) */ 532 - if (IS_ICL_REVID(dev_priv, ICL_REVID_A0, ICL_REVID_A0)) 507 + if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_A0)) 533 508 WA_SET_BIT_MASKED(GEN11_COMMON_SLICE_CHICKEN3, 534 509 GEN11_BLEND_EMB_FIX_DISABLE_IN_RCC); 535 - 536 - return 0; 537 510 } 538 511 539 - int intel_ctx_workarounds_init(struct drm_i915_private *dev_priv) 512 + void intel_engine_init_ctx_wa(struct intel_engine_cs *engine) 540 513 { 541 - int err = 0; 514 + struct drm_i915_private *i915 = engine->i915; 515 + struct i915_wa_list *wal = &engine->ctx_wa_list; 542 516 543 - dev_priv->workarounds.count = 0; 517 + wa_init_start(wal, "context"); 544 518 545 - if (INTEL_GEN(dev_priv) < 8) 546 - err = 0; 547 - else if (IS_BROADWELL(dev_priv)) 548 - err = bdw_ctx_workarounds_init(dev_priv); 549 - else if (IS_CHERRYVIEW(dev_priv)) 550 - err = chv_ctx_workarounds_init(dev_priv); 551 - else if (IS_SKYLAKE(dev_priv)) 552 - err = skl_ctx_workarounds_init(dev_priv); 553 - else if (IS_BROXTON(dev_priv)) 554 - err = bxt_ctx_workarounds_init(dev_priv); 555 - else if (IS_KABYLAKE(dev_priv)) 556 - err = kbl_ctx_workarounds_init(dev_priv); 557 - else if (IS_GEMINILAKE(dev_priv)) 558 - err = glk_ctx_workarounds_init(dev_priv); 559 - else if (IS_COFFEELAKE(dev_priv)) 560 - err = cfl_ctx_workarounds_init(dev_priv); 561 - else if (IS_CANNONLAKE(dev_priv)) 562 - err = cnl_ctx_workarounds_init(dev_priv); 563 - else if (IS_ICELAKE(dev_priv)) 564 - err = icl_ctx_workarounds_init(dev_priv); 519 + if (INTEL_GEN(i915) < 8) 520 + return; 521 + else if (IS_BROADWELL(i915)) 522 + bdw_ctx_workarounds_init(engine); 523 + else if (IS_CHERRYVIEW(i915)) 524 + chv_ctx_workarounds_init(engine); 525 + else if (IS_SKYLAKE(i915)) 526 + skl_ctx_workarounds_init(engine); 527 + else if (IS_BROXTON(i915)) 528 + bxt_ctx_workarounds_init(engine); 529 + else if (IS_KABYLAKE(i915)) 530 + kbl_ctx_workarounds_init(engine); 531 + else if (IS_GEMINILAKE(i915)) 532 + glk_ctx_workarounds_init(engine); 533 + else if (IS_COFFEELAKE(i915)) 534 + cfl_ctx_workarounds_init(engine); 535 + else if (IS_CANNONLAKE(i915)) 536 + cnl_ctx_workarounds_init(engine); 537 + else if (IS_ICELAKE(i915)) 538 + icl_ctx_workarounds_init(engine); 565 539 else 566 - MISSING_CASE(INTEL_GEN(dev_priv)); 567 - if (err) 568 - return err; 540 + MISSING_CASE(INTEL_GEN(i915)); 569 541 570 - DRM_DEBUG_DRIVER("Number of context specific w/a: %d\n", 571 - dev_priv->workarounds.count); 572 - return 0; 542 + wa_init_finish(wal); 573 543 } 574 544 575 - int intel_ctx_workarounds_emit(struct i915_request *rq) 545 + int intel_engine_emit_ctx_wa(struct i915_request *rq) 576 546 { 577 - struct i915_workarounds *w = &rq->i915->workarounds; 547 + struct i915_wa_list *wal = &rq->engine->ctx_wa_list; 548 + struct i915_wa *wa; 549 + unsigned int i; 578 550 u32 *cs; 579 - int ret, i; 551 + int ret; 580 552 581 - if (w->count == 0) 553 + if (wal->count == 0) 582 554 return 0; 583 555 584 556 ret = rq->engine->emit_flush(rq, EMIT_BARRIER); 585 557 if (ret) 586 558 return ret; 587 559 588 - cs = intel_ring_begin(rq, (w->count * 2 + 2)); 560 + cs = intel_ring_begin(rq, (wal->count * 2 + 2)); 589 561 if (IS_ERR(cs)) 590 562 return PTR_ERR(cs); 591 563 592 - *cs++ = MI_LOAD_REGISTER_IMM(w->count); 593 - for (i = 0; i < w->count; i++) { 594 - *cs++ = w->reg[i].addr; 595 - *cs++ = w->reg[i].value; 564 + *cs++ = MI_LOAD_REGISTER_IMM(wal->count); 565 + for (i = 0, wa = wal->list; i < wal->count; i++, wa++) { 566 + *cs++ = i915_mmio_reg_offset(wa->reg); 567 + *cs++ = wa->val; 596 568 } 597 569 *cs++ = MI_NOOP; 598 570 ··· 602 580 return 0; 603 581 } 604 582 605 - static void bdw_gt_workarounds_apply(struct drm_i915_private *dev_priv) 583 + static void 584 + wa_masked_en(struct i915_wa_list *wal, i915_reg_t reg, u32 val) 606 585 { 586 + struct i915_wa wa = { 587 + .reg = reg, 588 + .mask = val, 589 + .val = _MASKED_BIT_ENABLE(val) 590 + }; 591 + 592 + _wa_add(wal, &wa); 607 593 } 608 594 609 - static void chv_gt_workarounds_apply(struct drm_i915_private *dev_priv) 595 + static void 596 + wa_write_masked_or(struct i915_wa_list *wal, i915_reg_t reg, u32 mask, 597 + u32 val) 610 598 { 599 + struct i915_wa wa = { 600 + .reg = reg, 601 + .mask = mask, 602 + .val = val 603 + }; 604 + 605 + _wa_add(wal, &wa); 611 606 } 612 607 613 - static void gen9_gt_workarounds_apply(struct drm_i915_private *dev_priv) 608 + static void 609 + wa_write(struct i915_wa_list *wal, i915_reg_t reg, u32 val) 614 610 { 615 - /* WaContextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */ 616 - I915_WRITE(GEN9_CSFE_CHICKEN1_RCS, 617 - _MASKED_BIT_ENABLE(GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE)); 611 + wa_write_masked_or(wal, reg, ~0, val); 612 + } 618 613 619 - /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk,cfl */ 620 - I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) | 621 - GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE); 614 + static void 615 + wa_write_or(struct i915_wa_list *wal, i915_reg_t reg, u32 val) 616 + { 617 + wa_write_masked_or(wal, reg, val, val); 618 + } 619 + 620 + static void gen9_gt_workarounds_init(struct drm_i915_private *i915) 621 + { 622 + struct i915_wa_list *wal = &i915->gt_wa_list; 622 623 623 624 /* WaDisableKillLogic:bxt,skl,kbl */ 624 - if (!IS_COFFEELAKE(dev_priv)) 625 - I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | 626 - ECOCHK_DIS_TLB); 625 + if (!IS_COFFEELAKE(i915)) 626 + wa_write_or(wal, 627 + GAM_ECOCHK, 628 + ECOCHK_DIS_TLB); 627 629 628 - if (HAS_LLC(dev_priv)) { 630 + if (HAS_LLC(i915)) { 629 631 /* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl 630 632 * 631 633 * Must match Display Engine. See 632 634 * WaCompressedResourceDisplayNewHashMode. 633 635 */ 634 - I915_WRITE(MMCD_MISC_CTRL, 635 - I915_READ(MMCD_MISC_CTRL) | 636 - MMCD_PCLA | 637 - MMCD_HOTSPOT_EN); 636 + wa_write_or(wal, 637 + MMCD_MISC_CTRL, 638 + MMCD_PCLA | MMCD_HOTSPOT_EN); 638 639 } 639 640 640 641 /* WaDisableHDCInvalidation:skl,bxt,kbl,cfl */ 641 - I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | 642 - BDW_DISABLE_HDC_INVALIDATION); 643 - 644 - /* WaProgramL3SqcReg1DefaultForPerf:bxt,glk */ 645 - if (IS_GEN9_LP(dev_priv)) { 646 - u32 val = I915_READ(GEN8_L3SQCREG1); 647 - 648 - val &= ~L3_PRIO_CREDITS_MASK; 649 - val |= L3_GENERAL_PRIO_CREDITS(62) | L3_HIGH_PRIO_CREDITS(2); 650 - I915_WRITE(GEN8_L3SQCREG1, val); 651 - } 652 - 653 - /* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */ 654 - I915_WRITE(GEN8_L3SQCREG4, 655 - I915_READ(GEN8_L3SQCREG4) | GEN8_LQSC_FLUSH_COHERENT_LINES); 656 - 657 - /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,[cnl] */ 658 - I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1, 659 - _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL)); 642 + wa_write_or(wal, 643 + GAM_ECOCHK, 644 + BDW_DISABLE_HDC_INVALIDATION); 660 645 } 661 646 662 - static void skl_gt_workarounds_apply(struct drm_i915_private *dev_priv) 647 + static void skl_gt_workarounds_init(struct drm_i915_private *i915) 663 648 { 664 - gen9_gt_workarounds_apply(dev_priv); 649 + struct i915_wa_list *wal = &i915->gt_wa_list; 665 650 666 - /* WaEnableGapsTsvCreditFix:skl */ 667 - I915_WRITE(GEN8_GARBCNTL, 668 - I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE); 651 + gen9_gt_workarounds_init(i915); 669 652 670 653 /* WaDisableGafsUnitClkGating:skl */ 671 - I915_WRITE(GEN7_UCGCTL4, 672 - I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); 654 + wa_write_or(wal, 655 + GEN7_UCGCTL4, 656 + GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); 673 657 674 658 /* WaInPlaceDecompressionHang:skl */ 675 - if (IS_SKL_REVID(dev_priv, SKL_REVID_H0, REVID_FOREVER)) 676 - I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 677 - I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 678 - GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 659 + if (IS_SKL_REVID(i915, SKL_REVID_H0, REVID_FOREVER)) 660 + wa_write_or(wal, 661 + GEN9_GAMT_ECO_REG_RW_IA, 662 + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 679 663 } 680 664 681 - static void bxt_gt_workarounds_apply(struct drm_i915_private *dev_priv) 665 + static void bxt_gt_workarounds_init(struct drm_i915_private *i915) 682 666 { 683 - gen9_gt_workarounds_apply(dev_priv); 667 + struct i915_wa_list *wal = &i915->gt_wa_list; 684 668 685 - /* WaDisablePooledEuLoadBalancingFix:bxt */ 686 - I915_WRITE(FF_SLICE_CS_CHICKEN2, 687 - _MASKED_BIT_ENABLE(GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE)); 669 + gen9_gt_workarounds_init(i915); 688 670 689 671 /* WaInPlaceDecompressionHang:bxt */ 690 - I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 691 - I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 692 - GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 672 + wa_write_or(wal, 673 + GEN9_GAMT_ECO_REG_RW_IA, 674 + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 693 675 } 694 676 695 - static void kbl_gt_workarounds_apply(struct drm_i915_private *dev_priv) 677 + static void kbl_gt_workarounds_init(struct drm_i915_private *i915) 696 678 { 697 - gen9_gt_workarounds_apply(dev_priv); 679 + struct i915_wa_list *wal = &i915->gt_wa_list; 698 680 699 - /* WaEnableGapsTsvCreditFix:kbl */ 700 - I915_WRITE(GEN8_GARBCNTL, 701 - I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE); 681 + gen9_gt_workarounds_init(i915); 702 682 703 683 /* WaDisableDynamicCreditSharing:kbl */ 704 - if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0)) 705 - I915_WRITE(GAMT_CHKN_BIT_REG, 706 - I915_READ(GAMT_CHKN_BIT_REG) | 707 - GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING); 684 + if (IS_KBL_REVID(i915, 0, KBL_REVID_B0)) 685 + wa_write_or(wal, 686 + GAMT_CHKN_BIT_REG, 687 + GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING); 708 688 709 689 /* WaDisableGafsUnitClkGating:kbl */ 710 - I915_WRITE(GEN7_UCGCTL4, 711 - I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); 690 + wa_write_or(wal, 691 + GEN7_UCGCTL4, 692 + GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); 712 693 713 694 /* WaInPlaceDecompressionHang:kbl */ 714 - I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 715 - I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 716 - GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 717 - 718 - /* WaKBLVECSSemaphoreWaitPoll:kbl */ 719 - if (IS_KBL_REVID(dev_priv, KBL_REVID_A0, KBL_REVID_E0)) { 720 - struct intel_engine_cs *engine; 721 - unsigned int tmp; 722 - 723 - for_each_engine(engine, dev_priv, tmp) { 724 - if (engine->id == RCS) 725 - continue; 726 - 727 - I915_WRITE(RING_SEMA_WAIT_POLL(engine->mmio_base), 1); 728 - } 729 - } 695 + wa_write_or(wal, 696 + GEN9_GAMT_ECO_REG_RW_IA, 697 + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 730 698 } 731 699 732 - static void glk_gt_workarounds_apply(struct drm_i915_private *dev_priv) 700 + static void glk_gt_workarounds_init(struct drm_i915_private *i915) 733 701 { 734 - gen9_gt_workarounds_apply(dev_priv); 702 + gen9_gt_workarounds_init(i915); 735 703 } 736 704 737 - static void cfl_gt_workarounds_apply(struct drm_i915_private *dev_priv) 705 + static void cfl_gt_workarounds_init(struct drm_i915_private *i915) 738 706 { 739 - gen9_gt_workarounds_apply(dev_priv); 707 + struct i915_wa_list *wal = &i915->gt_wa_list; 740 708 741 - /* WaEnableGapsTsvCreditFix:cfl */ 742 - I915_WRITE(GEN8_GARBCNTL, 743 - I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE); 709 + gen9_gt_workarounds_init(i915); 744 710 745 711 /* WaDisableGafsUnitClkGating:cfl */ 746 - I915_WRITE(GEN7_UCGCTL4, 747 - I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); 712 + wa_write_or(wal, 713 + GEN7_UCGCTL4, 714 + GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); 748 715 749 716 /* WaInPlaceDecompressionHang:cfl */ 750 - I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 751 - I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 752 - GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 717 + wa_write_or(wal, 718 + GEN9_GAMT_ECO_REG_RW_IA, 719 + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 753 720 } 754 721 755 722 static void wa_init_mcr(struct drm_i915_private *dev_priv) 756 723 { 757 724 const struct sseu_dev_info *sseu = &(INTEL_INFO(dev_priv)->sseu); 758 - u32 mcr; 725 + struct i915_wa_list *wal = &dev_priv->gt_wa_list; 759 726 u32 mcr_slice_subslice_mask; 760 727 761 728 /* ··· 781 770 WARN_ON((enabled_mask & disabled_mask) != enabled_mask); 782 771 } 783 772 784 - mcr = I915_READ(GEN8_MCR_SELECTOR); 785 - 786 773 if (INTEL_GEN(dev_priv) >= 11) 787 774 mcr_slice_subslice_mask = GEN11_MCR_SLICE_MASK | 788 775 GEN11_MCR_SUBSLICE_MASK; ··· 798 789 * occasions, such as INSTDONE, where this value is dependent 799 790 * on s/ss combo, the read should be done with read_subslice_reg. 800 791 */ 801 - mcr &= ~mcr_slice_subslice_mask; 802 - mcr |= intel_calculate_mcr_s_ss_select(dev_priv); 803 - I915_WRITE(GEN8_MCR_SELECTOR, mcr); 792 + wa_write_masked_or(wal, 793 + GEN8_MCR_SELECTOR, 794 + mcr_slice_subslice_mask, 795 + intel_calculate_mcr_s_ss_select(dev_priv)); 804 796 } 805 797 806 - static void cnl_gt_workarounds_apply(struct drm_i915_private *dev_priv) 798 + static void cnl_gt_workarounds_init(struct drm_i915_private *i915) 807 799 { 808 - wa_init_mcr(dev_priv); 800 + struct i915_wa_list *wal = &i915->gt_wa_list; 801 + 802 + wa_init_mcr(i915); 809 803 810 804 /* WaDisableI2mCycleOnWRPort:cnl (pre-prod) */ 811 - if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0)) 812 - I915_WRITE(GAMT_CHKN_BIT_REG, 813 - I915_READ(GAMT_CHKN_BIT_REG) | 814 - GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT); 805 + if (IS_CNL_REVID(i915, CNL_REVID_B0, CNL_REVID_B0)) 806 + wa_write_or(wal, 807 + GAMT_CHKN_BIT_REG, 808 + GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT); 815 809 816 810 /* WaInPlaceDecompressionHang:cnl */ 817 - I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 818 - I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 819 - GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 820 - 821 - /* WaEnablePreemptionGranularityControlByUMD:cnl */ 822 - I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1, 823 - _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL)); 811 + wa_write_or(wal, 812 + GEN9_GAMT_ECO_REG_RW_IA, 813 + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 824 814 } 825 815 826 - static void icl_gt_workarounds_apply(struct drm_i915_private *dev_priv) 816 + static void icl_gt_workarounds_init(struct drm_i915_private *i915) 827 817 { 828 - wa_init_mcr(dev_priv); 818 + struct i915_wa_list *wal = &i915->gt_wa_list; 829 819 830 - /* This is not an Wa. Enable for better image quality */ 831 - I915_WRITE(_3D_CHICKEN3, 832 - _MASKED_BIT_ENABLE(_3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE)); 820 + wa_init_mcr(i915); 833 821 834 822 /* WaInPlaceDecompressionHang:icl */ 835 - I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 836 - I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 837 - GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 838 - 839 - /* WaPipelineFlushCoherentLines:icl */ 840 - I915_WRITE(GEN8_L3SQCREG4, 841 - I915_READ(GEN8_L3SQCREG4) | 842 - GEN8_LQSC_FLUSH_COHERENT_LINES); 843 - 844 - /* Wa_1405543622:icl 845 - * Formerly known as WaGAPZPriorityScheme 846 - */ 847 - I915_WRITE(GEN8_GARBCNTL, 848 - I915_READ(GEN8_GARBCNTL) | 849 - GEN11_ARBITRATION_PRIO_ORDER_MASK); 850 - 851 - /* Wa_1604223664:icl 852 - * Formerly known as WaL3BankAddressHashing 853 - */ 854 - I915_WRITE(GEN8_GARBCNTL, 855 - (I915_READ(GEN8_GARBCNTL) & ~GEN11_HASH_CTRL_EXCL_MASK) | 856 - GEN11_HASH_CTRL_EXCL_BIT0); 857 - I915_WRITE(GEN11_GLBLINVL, 858 - (I915_READ(GEN11_GLBLINVL) & ~GEN11_BANK_HASH_ADDR_EXCL_MASK) | 859 - GEN11_BANK_HASH_ADDR_EXCL_BIT0); 823 + wa_write_or(wal, 824 + GEN9_GAMT_ECO_REG_RW_IA, 825 + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 860 826 861 827 /* WaModifyGamTlbPartitioning:icl */ 862 - I915_WRITE(GEN11_GACB_PERF_CTRL, 863 - (I915_READ(GEN11_GACB_PERF_CTRL) & ~GEN11_HASH_CTRL_MASK) | 864 - GEN11_HASH_CTRL_BIT0 | GEN11_HASH_CTRL_BIT4); 865 - 866 - /* Wa_1405733216:icl 867 - * Formerly known as WaDisableCleanEvicts 868 - */ 869 - I915_WRITE(GEN8_L3SQCREG4, 870 - I915_READ(GEN8_L3SQCREG4) | 871 - GEN11_LQSC_CLEAN_EVICT_DISABLE); 828 + wa_write_masked_or(wal, 829 + GEN11_GACB_PERF_CTRL, 830 + GEN11_HASH_CTRL_MASK, 831 + GEN11_HASH_CTRL_BIT0 | GEN11_HASH_CTRL_BIT4); 872 832 873 833 /* Wa_1405766107:icl 874 834 * Formerly known as WaCL2SFHalfMaxAlloc 875 835 */ 876 - I915_WRITE(GEN11_LSN_UNSLCVC, 877 - I915_READ(GEN11_LSN_UNSLCVC) | 878 - GEN11_LSN_UNSLCVC_GAFS_HALF_SF_MAXALLOC | 879 - GEN11_LSN_UNSLCVC_GAFS_HALF_CL2_MAXALLOC); 836 + wa_write_or(wal, 837 + GEN11_LSN_UNSLCVC, 838 + GEN11_LSN_UNSLCVC_GAFS_HALF_SF_MAXALLOC | 839 + GEN11_LSN_UNSLCVC_GAFS_HALF_CL2_MAXALLOC); 880 840 881 841 /* Wa_220166154:icl 882 842 * Formerly known as WaDisCtxReload 883 843 */ 884 - I915_WRITE(GEN8_GAMW_ECO_DEV_RW_IA, 885 - I915_READ(GEN8_GAMW_ECO_DEV_RW_IA) | 886 - GAMW_ECO_DEV_CTX_RELOAD_DISABLE); 844 + wa_write_or(wal, 845 + GEN8_GAMW_ECO_DEV_RW_IA, 846 + GAMW_ECO_DEV_CTX_RELOAD_DISABLE); 887 847 888 848 /* Wa_1405779004:icl (pre-prod) */ 889 - if (IS_ICL_REVID(dev_priv, ICL_REVID_A0, ICL_REVID_A0)) 890 - I915_WRITE(SLICE_UNIT_LEVEL_CLKGATE, 891 - I915_READ(SLICE_UNIT_LEVEL_CLKGATE) | 892 - MSCUNIT_CLKGATE_DIS); 849 + if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_A0)) 850 + wa_write_or(wal, 851 + SLICE_UNIT_LEVEL_CLKGATE, 852 + MSCUNIT_CLKGATE_DIS); 893 853 894 854 /* Wa_1406680159:icl */ 895 - I915_WRITE(SUBSLICE_UNIT_LEVEL_CLKGATE, 896 - I915_READ(SUBSLICE_UNIT_LEVEL_CLKGATE) | 897 - GWUNIT_CLKGATE_DIS); 898 - 899 - /* Wa_1604302699:icl */ 900 - I915_WRITE(GEN10_L3_CHICKEN_MODE_REGISTER, 901 - I915_READ(GEN10_L3_CHICKEN_MODE_REGISTER) | 902 - GEN11_I2M_WRITE_DISABLE); 855 + wa_write_or(wal, 856 + SUBSLICE_UNIT_LEVEL_CLKGATE, 857 + GWUNIT_CLKGATE_DIS); 903 858 904 859 /* Wa_1406838659:icl (pre-prod) */ 905 - if (IS_ICL_REVID(dev_priv, ICL_REVID_A0, ICL_REVID_B0)) 906 - I915_WRITE(INF_UNIT_LEVEL_CLKGATE, 907 - I915_READ(INF_UNIT_LEVEL_CLKGATE) | 908 - CGPSF_CLKGATE_DIS); 909 - 910 - /* WaForwardProgressSoftReset:icl */ 911 - I915_WRITE(GEN10_SCRATCH_LNCF2, 912 - I915_READ(GEN10_SCRATCH_LNCF2) | 913 - PMFLUSHDONE_LNICRSDROP | 914 - PMFLUSH_GAPL3UNBLOCK | 915 - PMFLUSHDONE_LNEBLK); 860 + if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_B0)) 861 + wa_write_or(wal, 862 + INF_UNIT_LEVEL_CLKGATE, 863 + CGPSF_CLKGATE_DIS); 916 864 917 865 /* Wa_1406463099:icl 918 866 * Formerly known as WaGamTlbPendError 919 867 */ 920 - I915_WRITE(GAMT_CHKN_BIT_REG, 921 - I915_READ(GAMT_CHKN_BIT_REG) | 922 - GAMT_CHKN_DISABLE_L3_COH_PIPE); 923 - 924 - /* Wa_1406609255:icl (pre-prod) */ 925 - if (IS_ICL_REVID(dev_priv, ICL_REVID_A0, ICL_REVID_B0)) 926 - I915_WRITE(GEN7_SARCHKMD, 927 - I915_READ(GEN7_SARCHKMD) | 928 - GEN7_DISABLE_DEMAND_PREFETCH | 929 - GEN7_DISABLE_SAMPLER_PREFETCH); 868 + wa_write_or(wal, 869 + GAMT_CHKN_BIT_REG, 870 + GAMT_CHKN_DISABLE_L3_COH_PIPE); 930 871 } 931 872 932 - void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv) 873 + void intel_gt_init_workarounds(struct drm_i915_private *i915) 933 874 { 934 - if (INTEL_GEN(dev_priv) < 8) 875 + struct i915_wa_list *wal = &i915->gt_wa_list; 876 + 877 + wa_init_start(wal, "GT"); 878 + 879 + if (INTEL_GEN(i915) < 8) 935 880 return; 936 - else if (IS_BROADWELL(dev_priv)) 937 - bdw_gt_workarounds_apply(dev_priv); 938 - else if (IS_CHERRYVIEW(dev_priv)) 939 - chv_gt_workarounds_apply(dev_priv); 940 - else if (IS_SKYLAKE(dev_priv)) 941 - skl_gt_workarounds_apply(dev_priv); 942 - else if (IS_BROXTON(dev_priv)) 943 - bxt_gt_workarounds_apply(dev_priv); 944 - else if (IS_KABYLAKE(dev_priv)) 945 - kbl_gt_workarounds_apply(dev_priv); 946 - else if (IS_GEMINILAKE(dev_priv)) 947 - glk_gt_workarounds_apply(dev_priv); 948 - else if (IS_COFFEELAKE(dev_priv)) 949 - cfl_gt_workarounds_apply(dev_priv); 950 - else if (IS_CANNONLAKE(dev_priv)) 951 - cnl_gt_workarounds_apply(dev_priv); 952 - else if (IS_ICELAKE(dev_priv)) 953 - icl_gt_workarounds_apply(dev_priv); 881 + else if (IS_BROADWELL(i915)) 882 + return; 883 + else if (IS_CHERRYVIEW(i915)) 884 + return; 885 + else if (IS_SKYLAKE(i915)) 886 + skl_gt_workarounds_init(i915); 887 + else if (IS_BROXTON(i915)) 888 + bxt_gt_workarounds_init(i915); 889 + else if (IS_KABYLAKE(i915)) 890 + kbl_gt_workarounds_init(i915); 891 + else if (IS_GEMINILAKE(i915)) 892 + glk_gt_workarounds_init(i915); 893 + else if (IS_COFFEELAKE(i915)) 894 + cfl_gt_workarounds_init(i915); 895 + else if (IS_CANNONLAKE(i915)) 896 + cnl_gt_workarounds_init(i915); 897 + else if (IS_ICELAKE(i915)) 898 + icl_gt_workarounds_init(i915); 954 899 else 955 - MISSING_CASE(INTEL_GEN(dev_priv)); 900 + MISSING_CASE(INTEL_GEN(i915)); 901 + 902 + wa_init_finish(wal); 956 903 } 957 904 958 - struct whitelist { 959 - i915_reg_t reg[RING_MAX_NONPRIV_SLOTS]; 960 - unsigned int count; 961 - u32 nopid; 962 - }; 963 - 964 - static void whitelist_reg(struct whitelist *w, i915_reg_t reg) 905 + static enum forcewake_domains 906 + wal_get_fw_for_rmw(struct drm_i915_private *dev_priv, 907 + const struct i915_wa_list *wal) 965 908 { 966 - if (GEM_DEBUG_WARN_ON(w->count >= RING_MAX_NONPRIV_SLOTS)) 909 + enum forcewake_domains fw = 0; 910 + struct i915_wa *wa; 911 + unsigned int i; 912 + 913 + for (i = 0, wa = wal->list; i < wal->count; i++, wa++) 914 + fw |= intel_uncore_forcewake_for_reg(dev_priv, 915 + wa->reg, 916 + FW_REG_READ | 917 + FW_REG_WRITE); 918 + 919 + return fw; 920 + } 921 + 922 + static void 923 + wa_list_apply(struct drm_i915_private *dev_priv, const struct i915_wa_list *wal) 924 + { 925 + enum forcewake_domains fw; 926 + unsigned long flags; 927 + struct i915_wa *wa; 928 + unsigned int i; 929 + 930 + if (!wal->count) 967 931 return; 968 932 969 - w->reg[w->count++] = reg; 933 + fw = wal_get_fw_for_rmw(dev_priv, wal); 934 + 935 + spin_lock_irqsave(&dev_priv->uncore.lock, flags); 936 + intel_uncore_forcewake_get__locked(dev_priv, fw); 937 + 938 + for (i = 0, wa = wal->list; i < wal->count; i++, wa++) { 939 + u32 val = I915_READ_FW(wa->reg); 940 + 941 + val &= ~wa->mask; 942 + val |= wa->val; 943 + 944 + I915_WRITE_FW(wa->reg, val); 945 + } 946 + 947 + intel_uncore_forcewake_put__locked(dev_priv, fw); 948 + spin_unlock_irqrestore(&dev_priv->uncore.lock, flags); 949 + 950 + DRM_DEBUG_DRIVER("Applied %u %s workarounds\n", wal->count, wal->name); 970 951 } 971 952 972 - static void bdw_whitelist_build(struct whitelist *w) 953 + void intel_gt_apply_workarounds(struct drm_i915_private *dev_priv) 973 954 { 955 + wa_list_apply(dev_priv, &dev_priv->gt_wa_list); 974 956 } 975 957 976 - static void chv_whitelist_build(struct whitelist *w) 958 + static bool 959 + wa_verify(const struct i915_wa *wa, u32 cur, const char *name, const char *from) 977 960 { 961 + if ((cur ^ wa->val) & wa->mask) { 962 + DRM_ERROR("%s workaround lost on %s! (%x=%x/%x, expected %x, mask=%x)\n", 963 + name, from, i915_mmio_reg_offset(wa->reg), cur, 964 + cur & wa->mask, wa->val, wa->mask); 965 + 966 + return false; 967 + } 968 + 969 + return true; 978 970 } 979 971 980 - static void gen9_whitelist_build(struct whitelist *w) 972 + static bool wa_list_verify(struct drm_i915_private *dev_priv, 973 + const struct i915_wa_list *wal, 974 + const char *from) 975 + { 976 + struct i915_wa *wa; 977 + unsigned int i; 978 + bool ok = true; 979 + 980 + for (i = 0, wa = wal->list; i < wal->count; i++, wa++) 981 + ok &= wa_verify(wa, I915_READ(wa->reg), wal->name, from); 982 + 983 + return ok; 984 + } 985 + 986 + bool intel_gt_verify_workarounds(struct drm_i915_private *dev_priv, 987 + const char *from) 988 + { 989 + return wa_list_verify(dev_priv, &dev_priv->gt_wa_list, from); 990 + } 991 + 992 + static void 993 + whitelist_reg(struct i915_wa_list *wal, i915_reg_t reg) 994 + { 995 + struct i915_wa wa = { 996 + .reg = reg 997 + }; 998 + 999 + if (GEM_DEBUG_WARN_ON(wal->count >= RING_MAX_NONPRIV_SLOTS)) 1000 + return; 1001 + 1002 + _wa_add(wal, &wa); 1003 + } 1004 + 1005 + static void gen9_whitelist_build(struct i915_wa_list *w) 981 1006 { 982 1007 /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */ 983 1008 whitelist_reg(w, GEN9_CTX_PREEMPT_REG); ··· 1023 980 whitelist_reg(w, GEN8_HDC_CHICKEN1); 1024 981 } 1025 982 1026 - static void skl_whitelist_build(struct whitelist *w) 983 + static void skl_whitelist_build(struct i915_wa_list *w) 1027 984 { 1028 985 gen9_whitelist_build(w); 1029 986 ··· 1031 988 whitelist_reg(w, GEN8_L3SQCREG4); 1032 989 } 1033 990 1034 - static void bxt_whitelist_build(struct whitelist *w) 991 + static void bxt_whitelist_build(struct i915_wa_list *w) 1035 992 { 1036 993 gen9_whitelist_build(w); 1037 994 } 1038 995 1039 - static void kbl_whitelist_build(struct whitelist *w) 996 + static void kbl_whitelist_build(struct i915_wa_list *w) 1040 997 { 1041 998 gen9_whitelist_build(w); 1042 999 ··· 1044 1001 whitelist_reg(w, GEN8_L3SQCREG4); 1045 1002 } 1046 1003 1047 - static void glk_whitelist_build(struct whitelist *w) 1004 + static void glk_whitelist_build(struct i915_wa_list *w) 1048 1005 { 1049 1006 gen9_whitelist_build(w); 1050 1007 ··· 1052 1009 whitelist_reg(w, GEN9_SLICE_COMMON_ECO_CHICKEN1); 1053 1010 } 1054 1011 1055 - static void cfl_whitelist_build(struct whitelist *w) 1012 + static void cfl_whitelist_build(struct i915_wa_list *w) 1056 1013 { 1057 1014 gen9_whitelist_build(w); 1058 1015 } 1059 1016 1060 - static void cnl_whitelist_build(struct whitelist *w) 1017 + static void cnl_whitelist_build(struct i915_wa_list *w) 1061 1018 { 1062 1019 /* WaEnablePreemptionGranularityControlByUMD:cnl */ 1063 1020 whitelist_reg(w, GEN8_CS_CHICKEN1); 1064 1021 } 1065 1022 1066 - static void icl_whitelist_build(struct whitelist *w) 1023 + static void icl_whitelist_build(struct i915_wa_list *w) 1067 1024 { 1068 1025 /* WaAllowUMDToModifyHalfSliceChicken7:icl */ 1069 1026 whitelist_reg(w, GEN9_HALF_SLICE_CHICKEN7); ··· 1072 1029 whitelist_reg(w, GEN10_SAMPLER_MODE); 1073 1030 } 1074 1031 1075 - static struct whitelist *whitelist_build(struct intel_engine_cs *engine, 1076 - struct whitelist *w) 1032 + void intel_engine_init_whitelist(struct intel_engine_cs *engine) 1077 1033 { 1078 1034 struct drm_i915_private *i915 = engine->i915; 1035 + struct i915_wa_list *w = &engine->whitelist; 1079 1036 1080 1037 GEM_BUG_ON(engine->id != RCS); 1081 1038 1082 - w->count = 0; 1083 - w->nopid = i915_mmio_reg_offset(RING_NOPID(engine->mmio_base)); 1039 + wa_init_start(w, "whitelist"); 1084 1040 1085 1041 if (INTEL_GEN(i915) < 8) 1086 - return NULL; 1042 + return; 1087 1043 else if (IS_BROADWELL(i915)) 1088 - bdw_whitelist_build(w); 1044 + return; 1089 1045 else if (IS_CHERRYVIEW(i915)) 1090 - chv_whitelist_build(w); 1046 + return; 1091 1047 else if (IS_SKYLAKE(i915)) 1092 1048 skl_whitelist_build(w); 1093 1049 else if (IS_BROXTON(i915)) ··· 1104 1062 else 1105 1063 MISSING_CASE(INTEL_GEN(i915)); 1106 1064 1107 - return w; 1065 + wa_init_finish(w); 1108 1066 } 1109 1067 1110 - static void whitelist_apply(struct intel_engine_cs *engine, 1111 - const struct whitelist *w) 1068 + void intel_engine_apply_whitelist(struct intel_engine_cs *engine) 1112 1069 { 1113 1070 struct drm_i915_private *dev_priv = engine->i915; 1071 + const struct i915_wa_list *wal = &engine->whitelist; 1114 1072 const u32 base = engine->mmio_base; 1073 + struct i915_wa *wa; 1115 1074 unsigned int i; 1116 1075 1117 - if (!w) 1076 + if (!wal->count) 1118 1077 return; 1119 1078 1120 - intel_uncore_forcewake_get(engine->i915, FORCEWAKE_ALL); 1121 - 1122 - for (i = 0; i < w->count; i++) 1123 - I915_WRITE_FW(RING_FORCE_TO_NONPRIV(base, i), 1124 - i915_mmio_reg_offset(w->reg[i])); 1079 + for (i = 0, wa = wal->list; i < wal->count; i++, wa++) 1080 + I915_WRITE(RING_FORCE_TO_NONPRIV(base, i), 1081 + i915_mmio_reg_offset(wa->reg)); 1125 1082 1126 1083 /* And clear the rest just in case of garbage */ 1127 1084 for (; i < RING_MAX_NONPRIV_SLOTS; i++) 1128 - I915_WRITE_FW(RING_FORCE_TO_NONPRIV(base, i), w->nopid); 1085 + I915_WRITE(RING_FORCE_TO_NONPRIV(base, i), 1086 + i915_mmio_reg_offset(RING_NOPID(base))); 1129 1087 1130 - intel_uncore_forcewake_put(engine->i915, FORCEWAKE_ALL); 1088 + DRM_DEBUG_DRIVER("Applied %u %s workarounds\n", wal->count, wal->name); 1131 1089 } 1132 1090 1133 - void intel_whitelist_workarounds_apply(struct intel_engine_cs *engine) 1091 + static void rcs_engine_wa_init(struct intel_engine_cs *engine) 1134 1092 { 1135 - struct whitelist w; 1093 + struct drm_i915_private *i915 = engine->i915; 1094 + struct i915_wa_list *wal = &engine->wa_list; 1136 1095 1137 - whitelist_apply(engine, whitelist_build(engine, &w)); 1096 + if (IS_ICELAKE(i915)) { 1097 + /* This is not an Wa. Enable for better image quality */ 1098 + wa_masked_en(wal, 1099 + _3D_CHICKEN3, 1100 + _3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE); 1101 + 1102 + /* WaPipelineFlushCoherentLines:icl */ 1103 + wa_write_or(wal, 1104 + GEN8_L3SQCREG4, 1105 + GEN8_LQSC_FLUSH_COHERENT_LINES); 1106 + 1107 + /* 1108 + * Wa_1405543622:icl 1109 + * Formerly known as WaGAPZPriorityScheme 1110 + */ 1111 + wa_write_or(wal, 1112 + GEN8_GARBCNTL, 1113 + GEN11_ARBITRATION_PRIO_ORDER_MASK); 1114 + 1115 + /* 1116 + * Wa_1604223664:icl 1117 + * Formerly known as WaL3BankAddressHashing 1118 + */ 1119 + wa_write_masked_or(wal, 1120 + GEN8_GARBCNTL, 1121 + GEN11_HASH_CTRL_EXCL_MASK, 1122 + GEN11_HASH_CTRL_EXCL_BIT0); 1123 + wa_write_masked_or(wal, 1124 + GEN11_GLBLINVL, 1125 + GEN11_BANK_HASH_ADDR_EXCL_MASK, 1126 + GEN11_BANK_HASH_ADDR_EXCL_BIT0); 1127 + 1128 + /* 1129 + * Wa_1405733216:icl 1130 + * Formerly known as WaDisableCleanEvicts 1131 + */ 1132 + wa_write_or(wal, 1133 + GEN8_L3SQCREG4, 1134 + GEN11_LQSC_CLEAN_EVICT_DISABLE); 1135 + 1136 + /* WaForwardProgressSoftReset:icl */ 1137 + wa_write_or(wal, 1138 + GEN10_SCRATCH_LNCF2, 1139 + PMFLUSHDONE_LNICRSDROP | 1140 + PMFLUSH_GAPL3UNBLOCK | 1141 + PMFLUSHDONE_LNEBLK); 1142 + 1143 + /* Wa_1406609255:icl (pre-prod) */ 1144 + if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_B0)) 1145 + wa_write_or(wal, 1146 + GEN7_SARCHKMD, 1147 + GEN7_DISABLE_DEMAND_PREFETCH | 1148 + GEN7_DISABLE_SAMPLER_PREFETCH); 1149 + } 1150 + 1151 + if (IS_GEN9(i915) || IS_CANNONLAKE(i915)) { 1152 + /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,cnl */ 1153 + wa_masked_en(wal, 1154 + GEN7_FF_SLICE_CS_CHICKEN1, 1155 + GEN9_FFSC_PERCTX_PREEMPT_CTRL); 1156 + } 1157 + 1158 + if (IS_SKYLAKE(i915) || IS_KABYLAKE(i915) || IS_COFFEELAKE(i915)) { 1159 + /* WaEnableGapsTsvCreditFix:skl,kbl,cfl */ 1160 + wa_write_or(wal, 1161 + GEN8_GARBCNTL, 1162 + GEN9_GAPS_TSV_CREDIT_DISABLE); 1163 + } 1164 + 1165 + if (IS_BROXTON(i915)) { 1166 + /* WaDisablePooledEuLoadBalancingFix:bxt */ 1167 + wa_masked_en(wal, 1168 + FF_SLICE_CS_CHICKEN2, 1169 + GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE); 1170 + } 1171 + 1172 + if (IS_GEN9(i915)) { 1173 + /* WaContextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */ 1174 + wa_masked_en(wal, 1175 + GEN9_CSFE_CHICKEN1_RCS, 1176 + GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE); 1177 + 1178 + /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk,cfl */ 1179 + wa_write_or(wal, 1180 + BDW_SCRATCH1, 1181 + GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE); 1182 + 1183 + /* WaProgramL3SqcReg1DefaultForPerf:bxt,glk */ 1184 + if (IS_GEN9_LP(i915)) 1185 + wa_write_masked_or(wal, 1186 + GEN8_L3SQCREG1, 1187 + L3_PRIO_CREDITS_MASK, 1188 + L3_GENERAL_PRIO_CREDITS(62) | 1189 + L3_HIGH_PRIO_CREDITS(2)); 1190 + 1191 + /* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */ 1192 + wa_write_or(wal, 1193 + GEN8_L3SQCREG4, 1194 + GEN8_LQSC_FLUSH_COHERENT_LINES); 1195 + } 1196 + } 1197 + 1198 + static void xcs_engine_wa_init(struct intel_engine_cs *engine) 1199 + { 1200 + struct drm_i915_private *i915 = engine->i915; 1201 + struct i915_wa_list *wal = &engine->wa_list; 1202 + 1203 + /* WaKBLVECSSemaphoreWaitPoll:kbl */ 1204 + if (IS_KBL_REVID(i915, KBL_REVID_A0, KBL_REVID_E0)) { 1205 + wa_write(wal, 1206 + RING_SEMA_WAIT_POLL(engine->mmio_base), 1207 + 1); 1208 + } 1209 + } 1210 + 1211 + void intel_engine_init_workarounds(struct intel_engine_cs *engine) 1212 + { 1213 + struct i915_wa_list *wal = &engine->wa_list; 1214 + 1215 + if (GEM_WARN_ON(INTEL_GEN(engine->i915) < 8)) 1216 + return; 1217 + 1218 + wa_init_start(wal, engine->name); 1219 + 1220 + if (engine->id == RCS) 1221 + rcs_engine_wa_init(engine); 1222 + else 1223 + xcs_engine_wa_init(engine); 1224 + 1225 + wa_init_finish(wal); 1226 + } 1227 + 1228 + void intel_engine_apply_workarounds(struct intel_engine_cs *engine) 1229 + { 1230 + wa_list_apply(engine->i915, &engine->wa_list); 1138 1231 } 1139 1232 1140 1233 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) 1234 + static bool intel_engine_verify_workarounds(struct intel_engine_cs *engine, 1235 + const char *from) 1236 + { 1237 + return wa_list_verify(engine->i915, &engine->wa_list, from); 1238 + } 1239 + 1141 1240 #include "selftests/intel_workarounds.c" 1142 1241 #endif
+32 -4
drivers/gpu/drm/i915/intel_workarounds.h
··· 7 7 #ifndef _I915_WORKAROUNDS_H_ 8 8 #define _I915_WORKAROUNDS_H_ 9 9 10 - int intel_ctx_workarounds_init(struct drm_i915_private *dev_priv); 11 - int intel_ctx_workarounds_emit(struct i915_request *rq); 10 + #include <linux/slab.h> 12 11 13 - void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv); 12 + struct i915_wa { 13 + i915_reg_t reg; 14 + u32 mask; 15 + u32 val; 16 + }; 14 17 15 - void intel_whitelist_workarounds_apply(struct intel_engine_cs *engine); 18 + struct i915_wa_list { 19 + const char *name; 20 + struct i915_wa *list; 21 + unsigned int count; 22 + unsigned int wa_count; 23 + }; 24 + 25 + static inline void intel_wa_list_free(struct i915_wa_list *wal) 26 + { 27 + kfree(wal->list); 28 + memset(wal, 0, sizeof(*wal)); 29 + } 30 + 31 + void intel_engine_init_ctx_wa(struct intel_engine_cs *engine); 32 + int intel_engine_emit_ctx_wa(struct i915_request *rq); 33 + 34 + void intel_gt_init_workarounds(struct drm_i915_private *dev_priv); 35 + void intel_gt_apply_workarounds(struct drm_i915_private *dev_priv); 36 + bool intel_gt_verify_workarounds(struct drm_i915_private *dev_priv, 37 + const char *from); 38 + 39 + void intel_engine_init_whitelist(struct intel_engine_cs *engine); 40 + void intel_engine_apply_whitelist(struct intel_engine_cs *engine); 41 + 42 + void intel_engine_init_workarounds(struct intel_engine_cs *engine); 43 + void intel_engine_apply_workarounds(struct intel_engine_cs *engine); 16 44 17 45 #endif
+44
drivers/gpu/drm/i915/selftests/igt_reset.c
··· 1 + /* 2 + * SPDX-License-Identifier: MIT 3 + * 4 + * Copyright © 2018 Intel Corporation 5 + */ 6 + 7 + #include "igt_reset.h" 8 + 9 + #include "../i915_drv.h" 10 + #include "../intel_ringbuffer.h" 11 + 12 + void igt_global_reset_lock(struct drm_i915_private *i915) 13 + { 14 + struct intel_engine_cs *engine; 15 + enum intel_engine_id id; 16 + 17 + pr_debug("%s: current gpu_error=%08lx\n", 18 + __func__, i915->gpu_error.flags); 19 + 20 + while (test_and_set_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags)) 21 + wait_event(i915->gpu_error.reset_queue, 22 + !test_bit(I915_RESET_BACKOFF, 23 + &i915->gpu_error.flags)); 24 + 25 + for_each_engine(engine, i915, id) { 26 + while (test_and_set_bit(I915_RESET_ENGINE + id, 27 + &i915->gpu_error.flags)) 28 + wait_on_bit(&i915->gpu_error.flags, 29 + I915_RESET_ENGINE + id, 30 + TASK_UNINTERRUPTIBLE); 31 + } 32 + } 33 + 34 + void igt_global_reset_unlock(struct drm_i915_private *i915) 35 + { 36 + struct intel_engine_cs *engine; 37 + enum intel_engine_id id; 38 + 39 + for_each_engine(engine, i915, id) 40 + clear_bit(I915_RESET_ENGINE + id, &i915->gpu_error.flags); 41 + 42 + clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags); 43 + wake_up_all(&i915->gpu_error.reset_queue); 44 + }
+15
drivers/gpu/drm/i915/selftests/igt_reset.h
··· 1 + /* 2 + * SPDX-License-Identifier: MIT 3 + * 4 + * Copyright © 2018 Intel Corporation 5 + */ 6 + 7 + #ifndef __I915_SELFTESTS_IGT_RESET_H__ 8 + #define __I915_SELFTESTS_IGT_RESET_H__ 9 + 10 + #include "../i915_drv.h" 11 + 12 + void igt_global_reset_lock(struct drm_i915_private *i915); 13 + void igt_global_reset_unlock(struct drm_i915_private *i915); 14 + 15 + #endif
+199
drivers/gpu/drm/i915/selftests/igt_spinner.c
··· 1 + /* 2 + * SPDX-License-Identifier: MIT 3 + * 4 + * Copyright © 2018 Intel Corporation 5 + */ 6 + 7 + #include "igt_spinner.h" 8 + 9 + int igt_spinner_init(struct igt_spinner *spin, struct drm_i915_private *i915) 10 + { 11 + unsigned int mode; 12 + void *vaddr; 13 + int err; 14 + 15 + GEM_BUG_ON(INTEL_GEN(i915) < 8); 16 + 17 + memset(spin, 0, sizeof(*spin)); 18 + spin->i915 = i915; 19 + 20 + spin->hws = i915_gem_object_create_internal(i915, PAGE_SIZE); 21 + if (IS_ERR(spin->hws)) { 22 + err = PTR_ERR(spin->hws); 23 + goto err; 24 + } 25 + 26 + spin->obj = i915_gem_object_create_internal(i915, PAGE_SIZE); 27 + if (IS_ERR(spin->obj)) { 28 + err = PTR_ERR(spin->obj); 29 + goto err_hws; 30 + } 31 + 32 + i915_gem_object_set_cache_level(spin->hws, I915_CACHE_LLC); 33 + vaddr = i915_gem_object_pin_map(spin->hws, I915_MAP_WB); 34 + if (IS_ERR(vaddr)) { 35 + err = PTR_ERR(vaddr); 36 + goto err_obj; 37 + } 38 + spin->seqno = memset(vaddr, 0xff, PAGE_SIZE); 39 + 40 + mode = i915_coherent_map_type(i915); 41 + vaddr = i915_gem_object_pin_map(spin->obj, mode); 42 + if (IS_ERR(vaddr)) { 43 + err = PTR_ERR(vaddr); 44 + goto err_unpin_hws; 45 + } 46 + spin->batch = vaddr; 47 + 48 + return 0; 49 + 50 + err_unpin_hws: 51 + i915_gem_object_unpin_map(spin->hws); 52 + err_obj: 53 + i915_gem_object_put(spin->obj); 54 + err_hws: 55 + i915_gem_object_put(spin->hws); 56 + err: 57 + return err; 58 + } 59 + 60 + static unsigned int seqno_offset(u64 fence) 61 + { 62 + return offset_in_page(sizeof(u32) * fence); 63 + } 64 + 65 + static u64 hws_address(const struct i915_vma *hws, 66 + const struct i915_request *rq) 67 + { 68 + return hws->node.start + seqno_offset(rq->fence.context); 69 + } 70 + 71 + static int emit_recurse_batch(struct igt_spinner *spin, 72 + struct i915_request *rq, 73 + u32 arbitration_command) 74 + { 75 + struct i915_address_space *vm = &rq->gem_context->ppgtt->vm; 76 + struct i915_vma *hws, *vma; 77 + u32 *batch; 78 + int err; 79 + 80 + vma = i915_vma_instance(spin->obj, vm, NULL); 81 + if (IS_ERR(vma)) 82 + return PTR_ERR(vma); 83 + 84 + hws = i915_vma_instance(spin->hws, vm, NULL); 85 + if (IS_ERR(hws)) 86 + return PTR_ERR(hws); 87 + 88 + err = i915_vma_pin(vma, 0, 0, PIN_USER); 89 + if (err) 90 + return err; 91 + 92 + err = i915_vma_pin(hws, 0, 0, PIN_USER); 93 + if (err) 94 + goto unpin_vma; 95 + 96 + err = i915_vma_move_to_active(vma, rq, 0); 97 + if (err) 98 + goto unpin_hws; 99 + 100 + if (!i915_gem_object_has_active_reference(vma->obj)) { 101 + i915_gem_object_get(vma->obj); 102 + i915_gem_object_set_active_reference(vma->obj); 103 + } 104 + 105 + err = i915_vma_move_to_active(hws, rq, 0); 106 + if (err) 107 + goto unpin_hws; 108 + 109 + if (!i915_gem_object_has_active_reference(hws->obj)) { 110 + i915_gem_object_get(hws->obj); 111 + i915_gem_object_set_active_reference(hws->obj); 112 + } 113 + 114 + batch = spin->batch; 115 + 116 + *batch++ = MI_STORE_DWORD_IMM_GEN4; 117 + *batch++ = lower_32_bits(hws_address(hws, rq)); 118 + *batch++ = upper_32_bits(hws_address(hws, rq)); 119 + *batch++ = rq->fence.seqno; 120 + 121 + *batch++ = arbitration_command; 122 + 123 + *batch++ = MI_BATCH_BUFFER_START | 1 << 8 | 1; 124 + *batch++ = lower_32_bits(vma->node.start); 125 + *batch++ = upper_32_bits(vma->node.start); 126 + *batch++ = MI_BATCH_BUFFER_END; /* not reached */ 127 + 128 + i915_gem_chipset_flush(spin->i915); 129 + 130 + err = rq->engine->emit_bb_start(rq, vma->node.start, PAGE_SIZE, 0); 131 + 132 + unpin_hws: 133 + i915_vma_unpin(hws); 134 + unpin_vma: 135 + i915_vma_unpin(vma); 136 + return err; 137 + } 138 + 139 + struct i915_request * 140 + igt_spinner_create_request(struct igt_spinner *spin, 141 + struct i915_gem_context *ctx, 142 + struct intel_engine_cs *engine, 143 + u32 arbitration_command) 144 + { 145 + struct i915_request *rq; 146 + int err; 147 + 148 + rq = i915_request_alloc(engine, ctx); 149 + if (IS_ERR(rq)) 150 + return rq; 151 + 152 + err = emit_recurse_batch(spin, rq, arbitration_command); 153 + if (err) { 154 + i915_request_add(rq); 155 + return ERR_PTR(err); 156 + } 157 + 158 + return rq; 159 + } 160 + 161 + static u32 162 + hws_seqno(const struct igt_spinner *spin, const struct i915_request *rq) 163 + { 164 + u32 *seqno = spin->seqno + seqno_offset(rq->fence.context); 165 + 166 + return READ_ONCE(*seqno); 167 + } 168 + 169 + void igt_spinner_end(struct igt_spinner *spin) 170 + { 171 + *spin->batch = MI_BATCH_BUFFER_END; 172 + i915_gem_chipset_flush(spin->i915); 173 + } 174 + 175 + void igt_spinner_fini(struct igt_spinner *spin) 176 + { 177 + igt_spinner_end(spin); 178 + 179 + i915_gem_object_unpin_map(spin->obj); 180 + i915_gem_object_put(spin->obj); 181 + 182 + i915_gem_object_unpin_map(spin->hws); 183 + i915_gem_object_put(spin->hws); 184 + } 185 + 186 + bool igt_wait_for_spinner(struct igt_spinner *spin, struct i915_request *rq) 187 + { 188 + if (!wait_event_timeout(rq->execute, 189 + READ_ONCE(rq->global_seqno), 190 + msecs_to_jiffies(10))) 191 + return false; 192 + 193 + return !(wait_for_us(i915_seqno_passed(hws_seqno(spin, rq), 194 + rq->fence.seqno), 195 + 10) && 196 + wait_for(i915_seqno_passed(hws_seqno(spin, rq), 197 + rq->fence.seqno), 198 + 1000)); 199 + }
+37
drivers/gpu/drm/i915/selftests/igt_spinner.h
··· 1 + /* 2 + * SPDX-License-Identifier: MIT 3 + * 4 + * Copyright © 2018 Intel Corporation 5 + */ 6 + 7 + #ifndef __I915_SELFTESTS_IGT_SPINNER_H__ 8 + #define __I915_SELFTESTS_IGT_SPINNER_H__ 9 + 10 + #include "../i915_selftest.h" 11 + 12 + #include "../i915_drv.h" 13 + #include "../i915_request.h" 14 + #include "../intel_ringbuffer.h" 15 + #include "../i915_gem_context.h" 16 + 17 + struct igt_spinner { 18 + struct drm_i915_private *i915; 19 + struct drm_i915_gem_object *hws; 20 + struct drm_i915_gem_object *obj; 21 + u32 *batch; 22 + void *seqno; 23 + }; 24 + 25 + int igt_spinner_init(struct igt_spinner *spin, struct drm_i915_private *i915); 26 + void igt_spinner_fini(struct igt_spinner *spin); 27 + 28 + struct i915_request * 29 + igt_spinner_create_request(struct igt_spinner *spin, 30 + struct i915_gem_context *ctx, 31 + struct intel_engine_cs *engine, 32 + u32 arbitration_command); 33 + void igt_spinner_end(struct igt_spinner *spin); 34 + 35 + bool igt_wait_for_spinner(struct igt_spinner *spin, struct i915_request *rq); 36 + 37 + #endif
+18 -45
drivers/gpu/drm/i915/selftests/intel_hangcheck.c
··· 27 27 #include "../i915_selftest.h" 28 28 #include "i915_random.h" 29 29 #include "igt_flush_test.h" 30 + #include "igt_reset.h" 30 31 #include "igt_wedge_me.h" 31 32 32 33 #include "mock_context.h" ··· 309 308 goto unlock; 310 309 311 310 for_each_engine(engine, i915, id) { 311 + struct igt_wedge_me w; 312 312 long timeout; 313 313 314 314 if (!intel_engine_can_store_dword(engine)) ··· 330 328 331 329 i915_request_add(rq); 332 330 333 - timeout = i915_request_wait(rq, 334 - I915_WAIT_LOCKED, 335 - MAX_SCHEDULE_TIMEOUT); 331 + timeout = 0; 332 + igt_wedge_on_timeout(&w, i915, HZ / 10 /* 100ms timeout*/) 333 + timeout = i915_request_wait(rq, 334 + I915_WAIT_LOCKED, 335 + MAX_SCHEDULE_TIMEOUT); 336 + if (i915_terminally_wedged(&i915->gpu_error)) 337 + timeout = -EIO; 338 + 336 339 i915_request_put(rq); 337 340 338 341 if (timeout < 0) { ··· 355 348 return err; 356 349 } 357 350 358 - static void global_reset_lock(struct drm_i915_private *i915) 359 - { 360 - struct intel_engine_cs *engine; 361 - enum intel_engine_id id; 362 - 363 - pr_debug("%s: current gpu_error=%08lx\n", 364 - __func__, i915->gpu_error.flags); 365 - 366 - while (test_and_set_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags)) 367 - wait_event(i915->gpu_error.reset_queue, 368 - !test_bit(I915_RESET_BACKOFF, 369 - &i915->gpu_error.flags)); 370 - 371 - for_each_engine(engine, i915, id) { 372 - while (test_and_set_bit(I915_RESET_ENGINE + id, 373 - &i915->gpu_error.flags)) 374 - wait_on_bit(&i915->gpu_error.flags, 375 - I915_RESET_ENGINE + id, 376 - TASK_UNINTERRUPTIBLE); 377 - } 378 - } 379 - 380 - static void global_reset_unlock(struct drm_i915_private *i915) 381 - { 382 - struct intel_engine_cs *engine; 383 - enum intel_engine_id id; 384 - 385 - for_each_engine(engine, i915, id) 386 - clear_bit(I915_RESET_ENGINE + id, &i915->gpu_error.flags); 387 - 388 - clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags); 389 - wake_up_all(&i915->gpu_error.reset_queue); 390 - } 391 - 392 351 static int igt_global_reset(void *arg) 393 352 { 394 353 struct drm_i915_private *i915 = arg; ··· 363 390 364 391 /* Check that we can issue a global GPU reset */ 365 392 366 - global_reset_lock(i915); 393 + igt_global_reset_lock(i915); 367 394 set_bit(I915_RESET_HANDOFF, &i915->gpu_error.flags); 368 395 369 396 mutex_lock(&i915->drm.struct_mutex); ··· 378 405 mutex_unlock(&i915->drm.struct_mutex); 379 406 380 407 GEM_BUG_ON(test_bit(I915_RESET_HANDOFF, &i915->gpu_error.flags)); 381 - global_reset_unlock(i915); 408 + igt_global_reset_unlock(i915); 382 409 383 410 if (i915_terminally_wedged(&i915->gpu_error)) 384 411 err = -EIO; ··· 909 936 910 937 /* Check that we detect a stuck waiter and issue a reset */ 911 938 912 - global_reset_lock(i915); 939 + igt_global_reset_lock(i915); 913 940 914 941 mutex_lock(&i915->drm.struct_mutex); 915 942 err = hang_init(&h, i915); ··· 961 988 hang_fini(&h); 962 989 unlock: 963 990 mutex_unlock(&i915->drm.struct_mutex); 964 - global_reset_unlock(i915); 991 + igt_global_reset_unlock(i915); 965 992 966 993 if (i915_terminally_wedged(&i915->gpu_error)) 967 994 return -EIO; ··· 1039 1066 1040 1067 /* Check that we can recover an unbind stuck on a hanging request */ 1041 1068 1042 - global_reset_lock(i915); 1069 + igt_global_reset_lock(i915); 1043 1070 1044 1071 mutex_lock(&i915->drm.struct_mutex); 1045 1072 err = hang_init(&h, i915); ··· 1159 1186 hang_fini(&h); 1160 1187 unlock: 1161 1188 mutex_unlock(&i915->drm.struct_mutex); 1162 - global_reset_unlock(i915); 1189 + igt_global_reset_unlock(i915); 1163 1190 1164 1191 if (i915_terminally_wedged(&i915->gpu_error)) 1165 1192 return -EIO; ··· 1239 1266 1240 1267 /* Check that we replay pending requests following a hang */ 1241 1268 1242 - global_reset_lock(i915); 1269 + igt_global_reset_lock(i915); 1243 1270 1244 1271 mutex_lock(&i915->drm.struct_mutex); 1245 1272 err = hang_init(&h, i915); ··· 1370 1397 hang_fini(&h); 1371 1398 unlock: 1372 1399 mutex_unlock(&i915->drm.struct_mutex); 1373 - global_reset_unlock(i915); 1400 + igt_global_reset_unlock(i915); 1374 1401 1375 1402 if (i915_terminally_wedged(&i915->gpu_error)) 1376 1403 return -EIO;
+52 -249
drivers/gpu/drm/i915/selftests/intel_lrc.c
··· 6 6 7 7 #include "../i915_selftest.h" 8 8 #include "igt_flush_test.h" 9 + #include "igt_spinner.h" 9 10 #include "i915_random.h" 10 11 11 12 #include "mock_context.h" 12 - 13 - struct spinner { 14 - struct drm_i915_private *i915; 15 - struct drm_i915_gem_object *hws; 16 - struct drm_i915_gem_object *obj; 17 - u32 *batch; 18 - void *seqno; 19 - }; 20 - 21 - static int spinner_init(struct spinner *spin, struct drm_i915_private *i915) 22 - { 23 - unsigned int mode; 24 - void *vaddr; 25 - int err; 26 - 27 - GEM_BUG_ON(INTEL_GEN(i915) < 8); 28 - 29 - memset(spin, 0, sizeof(*spin)); 30 - spin->i915 = i915; 31 - 32 - spin->hws = i915_gem_object_create_internal(i915, PAGE_SIZE); 33 - if (IS_ERR(spin->hws)) { 34 - err = PTR_ERR(spin->hws); 35 - goto err; 36 - } 37 - 38 - spin->obj = i915_gem_object_create_internal(i915, PAGE_SIZE); 39 - if (IS_ERR(spin->obj)) { 40 - err = PTR_ERR(spin->obj); 41 - goto err_hws; 42 - } 43 - 44 - i915_gem_object_set_cache_level(spin->hws, I915_CACHE_LLC); 45 - vaddr = i915_gem_object_pin_map(spin->hws, I915_MAP_WB); 46 - if (IS_ERR(vaddr)) { 47 - err = PTR_ERR(vaddr); 48 - goto err_obj; 49 - } 50 - spin->seqno = memset(vaddr, 0xff, PAGE_SIZE); 51 - 52 - mode = i915_coherent_map_type(i915); 53 - vaddr = i915_gem_object_pin_map(spin->obj, mode); 54 - if (IS_ERR(vaddr)) { 55 - err = PTR_ERR(vaddr); 56 - goto err_unpin_hws; 57 - } 58 - spin->batch = vaddr; 59 - 60 - return 0; 61 - 62 - err_unpin_hws: 63 - i915_gem_object_unpin_map(spin->hws); 64 - err_obj: 65 - i915_gem_object_put(spin->obj); 66 - err_hws: 67 - i915_gem_object_put(spin->hws); 68 - err: 69 - return err; 70 - } 71 - 72 - static unsigned int seqno_offset(u64 fence) 73 - { 74 - return offset_in_page(sizeof(u32) * fence); 75 - } 76 - 77 - static u64 hws_address(const struct i915_vma *hws, 78 - const struct i915_request *rq) 79 - { 80 - return hws->node.start + seqno_offset(rq->fence.context); 81 - } 82 - 83 - static int emit_recurse_batch(struct spinner *spin, 84 - struct i915_request *rq, 85 - u32 arbitration_command) 86 - { 87 - struct i915_address_space *vm = &rq->gem_context->ppgtt->vm; 88 - struct i915_vma *hws, *vma; 89 - u32 *batch; 90 - int err; 91 - 92 - vma = i915_vma_instance(spin->obj, vm, NULL); 93 - if (IS_ERR(vma)) 94 - return PTR_ERR(vma); 95 - 96 - hws = i915_vma_instance(spin->hws, vm, NULL); 97 - if (IS_ERR(hws)) 98 - return PTR_ERR(hws); 99 - 100 - err = i915_vma_pin(vma, 0, 0, PIN_USER); 101 - if (err) 102 - return err; 103 - 104 - err = i915_vma_pin(hws, 0, 0, PIN_USER); 105 - if (err) 106 - goto unpin_vma; 107 - 108 - err = i915_vma_move_to_active(vma, rq, 0); 109 - if (err) 110 - goto unpin_hws; 111 - 112 - if (!i915_gem_object_has_active_reference(vma->obj)) { 113 - i915_gem_object_get(vma->obj); 114 - i915_gem_object_set_active_reference(vma->obj); 115 - } 116 - 117 - err = i915_vma_move_to_active(hws, rq, 0); 118 - if (err) 119 - goto unpin_hws; 120 - 121 - if (!i915_gem_object_has_active_reference(hws->obj)) { 122 - i915_gem_object_get(hws->obj); 123 - i915_gem_object_set_active_reference(hws->obj); 124 - } 125 - 126 - batch = spin->batch; 127 - 128 - *batch++ = MI_STORE_DWORD_IMM_GEN4; 129 - *batch++ = lower_32_bits(hws_address(hws, rq)); 130 - *batch++ = upper_32_bits(hws_address(hws, rq)); 131 - *batch++ = rq->fence.seqno; 132 - 133 - *batch++ = arbitration_command; 134 - 135 - *batch++ = MI_BATCH_BUFFER_START | 1 << 8 | 1; 136 - *batch++ = lower_32_bits(vma->node.start); 137 - *batch++ = upper_32_bits(vma->node.start); 138 - *batch++ = MI_BATCH_BUFFER_END; /* not reached */ 139 - 140 - i915_gem_chipset_flush(spin->i915); 141 - 142 - err = rq->engine->emit_bb_start(rq, vma->node.start, PAGE_SIZE, 0); 143 - 144 - unpin_hws: 145 - i915_vma_unpin(hws); 146 - unpin_vma: 147 - i915_vma_unpin(vma); 148 - return err; 149 - } 150 - 151 - static struct i915_request * 152 - spinner_create_request(struct spinner *spin, 153 - struct i915_gem_context *ctx, 154 - struct intel_engine_cs *engine, 155 - u32 arbitration_command) 156 - { 157 - struct i915_request *rq; 158 - int err; 159 - 160 - rq = i915_request_alloc(engine, ctx); 161 - if (IS_ERR(rq)) 162 - return rq; 163 - 164 - err = emit_recurse_batch(spin, rq, arbitration_command); 165 - if (err) { 166 - i915_request_add(rq); 167 - return ERR_PTR(err); 168 - } 169 - 170 - return rq; 171 - } 172 - 173 - static u32 hws_seqno(const struct spinner *spin, const struct i915_request *rq) 174 - { 175 - u32 *seqno = spin->seqno + seqno_offset(rq->fence.context); 176 - 177 - return READ_ONCE(*seqno); 178 - } 179 - 180 - static void spinner_end(struct spinner *spin) 181 - { 182 - *spin->batch = MI_BATCH_BUFFER_END; 183 - i915_gem_chipset_flush(spin->i915); 184 - } 185 - 186 - static void spinner_fini(struct spinner *spin) 187 - { 188 - spinner_end(spin); 189 - 190 - i915_gem_object_unpin_map(spin->obj); 191 - i915_gem_object_put(spin->obj); 192 - 193 - i915_gem_object_unpin_map(spin->hws); 194 - i915_gem_object_put(spin->hws); 195 - } 196 - 197 - static bool wait_for_spinner(struct spinner *spin, struct i915_request *rq) 198 - { 199 - if (!wait_event_timeout(rq->execute, 200 - READ_ONCE(rq->global_seqno), 201 - msecs_to_jiffies(10))) 202 - return false; 203 - 204 - return !(wait_for_us(i915_seqno_passed(hws_seqno(spin, rq), 205 - rq->fence.seqno), 206 - 10) && 207 - wait_for(i915_seqno_passed(hws_seqno(spin, rq), 208 - rq->fence.seqno), 209 - 1000)); 210 - } 211 13 212 14 static int live_sanitycheck(void *arg) 213 15 { ··· 17 215 struct intel_engine_cs *engine; 18 216 struct i915_gem_context *ctx; 19 217 enum intel_engine_id id; 20 - struct spinner spin; 218 + struct igt_spinner spin; 21 219 int err = -ENOMEM; 22 220 23 221 if (!HAS_LOGICAL_RING_CONTEXTS(i915)) ··· 26 224 mutex_lock(&i915->drm.struct_mutex); 27 225 intel_runtime_pm_get(i915); 28 226 29 - if (spinner_init(&spin, i915)) 227 + if (igt_spinner_init(&spin, i915)) 30 228 goto err_unlock; 31 229 32 230 ctx = kernel_context(i915); ··· 36 234 for_each_engine(engine, i915, id) { 37 235 struct i915_request *rq; 38 236 39 - rq = spinner_create_request(&spin, ctx, engine, MI_NOOP); 237 + rq = igt_spinner_create_request(&spin, ctx, engine, MI_NOOP); 40 238 if (IS_ERR(rq)) { 41 239 err = PTR_ERR(rq); 42 240 goto err_ctx; 43 241 } 44 242 45 243 i915_request_add(rq); 46 - if (!wait_for_spinner(&spin, rq)) { 244 + if (!igt_wait_for_spinner(&spin, rq)) { 47 245 GEM_TRACE("spinner failed to start\n"); 48 246 GEM_TRACE_DUMP(); 49 247 i915_gem_set_wedged(i915); ··· 51 249 goto err_ctx; 52 250 } 53 251 54 - spinner_end(&spin); 252 + igt_spinner_end(&spin); 55 253 if (igt_flush_test(i915, I915_WAIT_LOCKED)) { 56 254 err = -EIO; 57 255 goto err_ctx; ··· 62 260 err_ctx: 63 261 kernel_context_close(ctx); 64 262 err_spin: 65 - spinner_fini(&spin); 263 + igt_spinner_fini(&spin); 66 264 err_unlock: 67 265 igt_flush_test(i915, I915_WAIT_LOCKED); 68 266 intel_runtime_pm_put(i915); ··· 74 272 { 75 273 struct drm_i915_private *i915 = arg; 76 274 struct i915_gem_context *ctx_hi, *ctx_lo; 77 - struct spinner spin_hi, spin_lo; 275 + struct igt_spinner spin_hi, spin_lo; 78 276 struct intel_engine_cs *engine; 79 277 enum intel_engine_id id; 80 278 int err = -ENOMEM; ··· 85 283 mutex_lock(&i915->drm.struct_mutex); 86 284 intel_runtime_pm_get(i915); 87 285 88 - if (spinner_init(&spin_hi, i915)) 286 + if (igt_spinner_init(&spin_hi, i915)) 89 287 goto err_unlock; 90 288 91 - if (spinner_init(&spin_lo, i915)) 289 + if (igt_spinner_init(&spin_lo, i915)) 92 290 goto err_spin_hi; 93 291 94 292 ctx_hi = kernel_context(i915); ··· 106 304 for_each_engine(engine, i915, id) { 107 305 struct i915_request *rq; 108 306 109 - rq = spinner_create_request(&spin_lo, ctx_lo, engine, 110 - MI_ARB_CHECK); 307 + rq = igt_spinner_create_request(&spin_lo, ctx_lo, engine, 308 + MI_ARB_CHECK); 111 309 if (IS_ERR(rq)) { 112 310 err = PTR_ERR(rq); 113 311 goto err_ctx_lo; 114 312 } 115 313 116 314 i915_request_add(rq); 117 - if (!wait_for_spinner(&spin_lo, rq)) { 315 + if (!igt_wait_for_spinner(&spin_lo, rq)) { 118 316 GEM_TRACE("lo spinner failed to start\n"); 119 317 GEM_TRACE_DUMP(); 120 318 i915_gem_set_wedged(i915); ··· 122 320 goto err_ctx_lo; 123 321 } 124 322 125 - rq = spinner_create_request(&spin_hi, ctx_hi, engine, 126 - MI_ARB_CHECK); 323 + rq = igt_spinner_create_request(&spin_hi, ctx_hi, engine, 324 + MI_ARB_CHECK); 127 325 if (IS_ERR(rq)) { 128 - spinner_end(&spin_lo); 326 + igt_spinner_end(&spin_lo); 129 327 err = PTR_ERR(rq); 130 328 goto err_ctx_lo; 131 329 } 132 330 133 331 i915_request_add(rq); 134 - if (!wait_for_spinner(&spin_hi, rq)) { 332 + if (!igt_wait_for_spinner(&spin_hi, rq)) { 135 333 GEM_TRACE("hi spinner failed to start\n"); 136 334 GEM_TRACE_DUMP(); 137 335 i915_gem_set_wedged(i915); ··· 139 337 goto err_ctx_lo; 140 338 } 141 339 142 - spinner_end(&spin_hi); 143 - spinner_end(&spin_lo); 340 + igt_spinner_end(&spin_hi); 341 + igt_spinner_end(&spin_lo); 144 342 if (igt_flush_test(i915, I915_WAIT_LOCKED)) { 145 343 err = -EIO; 146 344 goto err_ctx_lo; ··· 153 351 err_ctx_hi: 154 352 kernel_context_close(ctx_hi); 155 353 err_spin_lo: 156 - spinner_fini(&spin_lo); 354 + igt_spinner_fini(&spin_lo); 157 355 err_spin_hi: 158 - spinner_fini(&spin_hi); 356 + igt_spinner_fini(&spin_hi); 159 357 err_unlock: 160 358 igt_flush_test(i915, I915_WAIT_LOCKED); 161 359 intel_runtime_pm_put(i915); ··· 167 365 { 168 366 struct drm_i915_private *i915 = arg; 169 367 struct i915_gem_context *ctx_hi, *ctx_lo; 170 - struct spinner spin_hi, spin_lo; 368 + struct igt_spinner spin_hi, spin_lo; 171 369 struct intel_engine_cs *engine; 172 370 struct i915_sched_attr attr = {}; 173 371 enum intel_engine_id id; ··· 179 377 mutex_lock(&i915->drm.struct_mutex); 180 378 intel_runtime_pm_get(i915); 181 379 182 - if (spinner_init(&spin_hi, i915)) 380 + if (igt_spinner_init(&spin_hi, i915)) 183 381 goto err_unlock; 184 382 185 - if (spinner_init(&spin_lo, i915)) 383 + if (igt_spinner_init(&spin_lo, i915)) 186 384 goto err_spin_hi; 187 385 188 386 ctx_hi = kernel_context(i915); ··· 196 394 for_each_engine(engine, i915, id) { 197 395 struct i915_request *rq; 198 396 199 - rq = spinner_create_request(&spin_lo, ctx_lo, engine, 200 - MI_ARB_CHECK); 397 + rq = igt_spinner_create_request(&spin_lo, ctx_lo, engine, 398 + MI_ARB_CHECK); 201 399 if (IS_ERR(rq)) { 202 400 err = PTR_ERR(rq); 203 401 goto err_ctx_lo; 204 402 } 205 403 206 404 i915_request_add(rq); 207 - if (!wait_for_spinner(&spin_lo, rq)) { 405 + if (!igt_wait_for_spinner(&spin_lo, rq)) { 208 406 pr_err("First context failed to start\n"); 209 407 goto err_wedged; 210 408 } 211 409 212 - rq = spinner_create_request(&spin_hi, ctx_hi, engine, MI_NOOP); 410 + rq = igt_spinner_create_request(&spin_hi, ctx_hi, engine, 411 + MI_NOOP); 213 412 if (IS_ERR(rq)) { 214 - spinner_end(&spin_lo); 413 + igt_spinner_end(&spin_lo); 215 414 err = PTR_ERR(rq); 216 415 goto err_ctx_lo; 217 416 } 218 417 219 418 i915_request_add(rq); 220 - if (wait_for_spinner(&spin_hi, rq)) { 419 + if (igt_wait_for_spinner(&spin_hi, rq)) { 221 420 pr_err("Second context overtook first?\n"); 222 421 goto err_wedged; 223 422 } ··· 226 423 attr.priority = I915_USER_PRIORITY(I915_PRIORITY_MAX); 227 424 engine->schedule(rq, &attr); 228 425 229 - if (!wait_for_spinner(&spin_hi, rq)) { 426 + if (!igt_wait_for_spinner(&spin_hi, rq)) { 230 427 pr_err("High priority context failed to preempt the low priority context\n"); 231 428 GEM_TRACE_DUMP(); 232 429 goto err_wedged; 233 430 } 234 431 235 - spinner_end(&spin_hi); 236 - spinner_end(&spin_lo); 432 + igt_spinner_end(&spin_hi); 433 + igt_spinner_end(&spin_lo); 237 434 if (igt_flush_test(i915, I915_WAIT_LOCKED)) { 238 435 err = -EIO; 239 436 goto err_ctx_lo; ··· 246 443 err_ctx_hi: 247 444 kernel_context_close(ctx_hi); 248 445 err_spin_lo: 249 - spinner_fini(&spin_lo); 446 + igt_spinner_fini(&spin_lo); 250 447 err_spin_hi: 251 - spinner_fini(&spin_hi); 448 + igt_spinner_fini(&spin_hi); 252 449 err_unlock: 253 450 igt_flush_test(i915, I915_WAIT_LOCKED); 254 451 intel_runtime_pm_put(i915); ··· 256 453 return err; 257 454 258 455 err_wedged: 259 - spinner_end(&spin_hi); 260 - spinner_end(&spin_lo); 456 + igt_spinner_end(&spin_hi); 457 + igt_spinner_end(&spin_lo); 261 458 i915_gem_set_wedged(i915); 262 459 err = -EIO; 263 460 goto err_ctx_lo; ··· 267 464 { 268 465 struct drm_i915_private *i915 = arg; 269 466 struct i915_gem_context *ctx_hi, *ctx_lo; 270 - struct spinner spin_hi, spin_lo; 467 + struct igt_spinner spin_hi, spin_lo; 271 468 struct intel_engine_cs *engine; 272 469 enum intel_engine_id id; 273 470 int err = -ENOMEM; ··· 281 478 mutex_lock(&i915->drm.struct_mutex); 282 479 intel_runtime_pm_get(i915); 283 480 284 - if (spinner_init(&spin_hi, i915)) 481 + if (igt_spinner_init(&spin_hi, i915)) 285 482 goto err_unlock; 286 483 287 - if (spinner_init(&spin_lo, i915)) 484 + if (igt_spinner_init(&spin_lo, i915)) 288 485 goto err_spin_hi; 289 486 290 487 ctx_hi = kernel_context(i915); ··· 303 500 if (!intel_engine_has_preemption(engine)) 304 501 continue; 305 502 306 - rq = spinner_create_request(&spin_lo, ctx_lo, engine, 307 - MI_ARB_CHECK); 503 + rq = igt_spinner_create_request(&spin_lo, ctx_lo, engine, 504 + MI_ARB_CHECK); 308 505 if (IS_ERR(rq)) { 309 506 err = PTR_ERR(rq); 310 507 goto err_ctx_lo; 311 508 } 312 509 313 510 i915_request_add(rq); 314 - if (!wait_for_spinner(&spin_lo, rq)) { 511 + if (!igt_wait_for_spinner(&spin_lo, rq)) { 315 512 GEM_TRACE("lo spinner failed to start\n"); 316 513 GEM_TRACE_DUMP(); 317 514 i915_gem_set_wedged(i915); ··· 319 516 goto err_ctx_lo; 320 517 } 321 518 322 - rq = spinner_create_request(&spin_hi, ctx_hi, engine, 323 - MI_ARB_CHECK); 519 + rq = igt_spinner_create_request(&spin_hi, ctx_hi, engine, 520 + MI_ARB_CHECK); 324 521 if (IS_ERR(rq)) { 325 - spinner_end(&spin_lo); 522 + igt_spinner_end(&spin_lo); 326 523 err = PTR_ERR(rq); 327 524 goto err_ctx_lo; 328 525 } ··· 347 544 348 545 engine->execlists.preempt_hang.inject_hang = false; 349 546 350 - if (!wait_for_spinner(&spin_hi, rq)) { 547 + if (!igt_wait_for_spinner(&spin_hi, rq)) { 351 548 GEM_TRACE("hi spinner failed to start\n"); 352 549 GEM_TRACE_DUMP(); 353 550 i915_gem_set_wedged(i915); ··· 355 552 goto err_ctx_lo; 356 553 } 357 554 358 - spinner_end(&spin_hi); 359 - spinner_end(&spin_lo); 555 + igt_spinner_end(&spin_hi); 556 + igt_spinner_end(&spin_lo); 360 557 if (igt_flush_test(i915, I915_WAIT_LOCKED)) { 361 558 err = -EIO; 362 559 goto err_ctx_lo; ··· 369 566 err_ctx_hi: 370 567 kernel_context_close(ctx_hi); 371 568 err_spin_lo: 372 - spinner_fini(&spin_lo); 569 + igt_spinner_fini(&spin_lo); 373 570 err_spin_hi: 374 - spinner_fini(&spin_hi); 571 + igt_spinner_fini(&spin_hi); 375 572 err_unlock: 376 573 igt_flush_test(i915, I915_WAIT_LOCKED); 377 574 intel_runtime_pm_put(i915);
+211 -36
drivers/gpu/drm/i915/selftests/intel_workarounds.c
··· 6 6 7 7 #include "../i915_selftest.h" 8 8 9 + #include "igt_flush_test.h" 10 + #include "igt_reset.h" 11 + #include "igt_spinner.h" 9 12 #include "igt_wedge_me.h" 10 13 #include "mock_context.h" 11 14 ··· 94 91 return ERR_PTR(err); 95 92 } 96 93 97 - static u32 get_whitelist_reg(const struct whitelist *w, unsigned int i) 94 + static u32 95 + get_whitelist_reg(const struct intel_engine_cs *engine, unsigned int i) 98 96 { 99 - return i < w->count ? i915_mmio_reg_offset(w->reg[i]) : w->nopid; 97 + i915_reg_t reg = i < engine->whitelist.count ? 98 + engine->whitelist.list[i].reg : 99 + RING_NOPID(engine->mmio_base); 100 + 101 + return i915_mmio_reg_offset(reg); 100 102 } 101 103 102 - static void print_results(const struct whitelist *w, const u32 *results) 104 + static void 105 + print_results(const struct intel_engine_cs *engine, const u32 *results) 103 106 { 104 107 unsigned int i; 105 108 106 109 for (i = 0; i < RING_MAX_NONPRIV_SLOTS; i++) { 107 - u32 expected = get_whitelist_reg(w, i); 110 + u32 expected = get_whitelist_reg(engine, i); 108 111 u32 actual = results[i]; 109 112 110 113 pr_info("RING_NONPRIV[%d]: expected 0x%08x, found 0x%08x\n", ··· 118 109 } 119 110 } 120 111 121 - static int check_whitelist(const struct whitelist *w, 122 - struct i915_gem_context *ctx, 112 + static int check_whitelist(struct i915_gem_context *ctx, 123 113 struct intel_engine_cs *engine) 124 114 { 125 115 struct drm_i915_gem_object *results; ··· 146 138 } 147 139 148 140 for (i = 0; i < RING_MAX_NONPRIV_SLOTS; i++) { 149 - u32 expected = get_whitelist_reg(w, i); 141 + u32 expected = get_whitelist_reg(engine, i); 150 142 u32 actual = vaddr[i]; 151 143 152 144 if (expected != actual) { 153 - print_results(w, vaddr); 145 + print_results(engine, vaddr); 154 146 pr_err("Invalid RING_NONPRIV[%d], expected 0x%08x, found 0x%08x\n", 155 147 i, expected, actual); 156 148 ··· 167 159 168 160 static int do_device_reset(struct intel_engine_cs *engine) 169 161 { 170 - i915_reset(engine->i915, ENGINE_MASK(engine->id), NULL); 162 + set_bit(I915_RESET_HANDOFF, &engine->i915->gpu_error.flags); 163 + i915_reset(engine->i915, ENGINE_MASK(engine->id), "live_workarounds"); 171 164 return 0; 172 165 } 173 166 174 167 static int do_engine_reset(struct intel_engine_cs *engine) 175 168 { 176 - return i915_reset_engine(engine, NULL); 169 + return i915_reset_engine(engine, "live_workarounds"); 177 170 } 178 171 179 - static int switch_to_scratch_context(struct intel_engine_cs *engine) 172 + static int 173 + switch_to_scratch_context(struct intel_engine_cs *engine, 174 + struct igt_spinner *spin) 180 175 { 181 176 struct i915_gem_context *ctx; 182 177 struct i915_request *rq; 178 + int err = 0; 183 179 184 180 ctx = kernel_context(engine->i915); 185 181 if (IS_ERR(ctx)) 186 182 return PTR_ERR(ctx); 187 183 188 184 intel_runtime_pm_get(engine->i915); 189 - rq = i915_request_alloc(engine, ctx); 185 + 186 + if (spin) 187 + rq = igt_spinner_create_request(spin, ctx, engine, MI_NOOP); 188 + else 189 + rq = i915_request_alloc(engine, ctx); 190 + 190 191 intel_runtime_pm_put(engine->i915); 191 192 192 193 kernel_context_close(ctx); 193 - if (IS_ERR(rq)) 194 - return PTR_ERR(rq); 194 + 195 + if (IS_ERR(rq)) { 196 + spin = NULL; 197 + err = PTR_ERR(rq); 198 + goto err; 199 + } 195 200 196 201 i915_request_add(rq); 197 202 198 - return 0; 203 + if (spin && !igt_wait_for_spinner(spin, rq)) { 204 + pr_err("Spinner failed to start\n"); 205 + err = -ETIMEDOUT; 206 + } 207 + 208 + err: 209 + if (err && spin) 210 + igt_spinner_end(spin); 211 + 212 + return err; 199 213 } 200 214 201 215 static int check_whitelist_across_reset(struct intel_engine_cs *engine, 202 216 int (*reset)(struct intel_engine_cs *), 203 - const struct whitelist *w, 204 217 const char *name) 205 218 { 219 + struct drm_i915_private *i915 = engine->i915; 220 + bool want_spin = reset == do_engine_reset; 206 221 struct i915_gem_context *ctx; 222 + struct igt_spinner spin; 207 223 int err; 208 224 209 - ctx = kernel_context(engine->i915); 225 + pr_info("Checking %d whitelisted registers (RING_NONPRIV) [%s]\n", 226 + engine->whitelist.count, name); 227 + 228 + if (want_spin) { 229 + err = igt_spinner_init(&spin, i915); 230 + if (err) 231 + return err; 232 + } 233 + 234 + ctx = kernel_context(i915); 210 235 if (IS_ERR(ctx)) 211 236 return PTR_ERR(ctx); 212 237 213 - err = check_whitelist(w, ctx, engine); 238 + err = check_whitelist(ctx, engine); 214 239 if (err) { 215 240 pr_err("Invalid whitelist *before* %s reset!\n", name); 216 241 goto out; 217 242 } 218 243 219 - err = switch_to_scratch_context(engine); 244 + err = switch_to_scratch_context(engine, want_spin ? &spin : NULL); 220 245 if (err) 221 246 goto out; 222 247 248 + intel_runtime_pm_get(i915); 223 249 err = reset(engine); 250 + intel_runtime_pm_put(i915); 251 + 252 + if (want_spin) { 253 + igt_spinner_end(&spin); 254 + igt_spinner_fini(&spin); 255 + } 256 + 224 257 if (err) { 225 258 pr_err("%s reset failed\n", name); 226 259 goto out; 227 260 } 228 261 229 - err = check_whitelist(w, ctx, engine); 262 + err = check_whitelist(ctx, engine); 230 263 if (err) { 231 264 pr_err("Whitelist not preserved in context across %s reset!\n", 232 265 name); ··· 276 227 277 228 kernel_context_close(ctx); 278 229 279 - ctx = kernel_context(engine->i915); 230 + ctx = kernel_context(i915); 280 231 if (IS_ERR(ctx)) 281 232 return PTR_ERR(ctx); 282 233 283 - err = check_whitelist(w, ctx, engine); 234 + err = check_whitelist(ctx, engine); 284 235 if (err) { 285 236 pr_err("Invalid whitelist *after* %s reset in fresh context!\n", 286 237 name); ··· 296 247 { 297 248 struct drm_i915_private *i915 = arg; 298 249 struct intel_engine_cs *engine = i915->engine[RCS]; 299 - struct i915_gpu_error *error = &i915->gpu_error; 300 - struct whitelist w; 301 250 int err = 0; 302 251 303 252 /* If we reset the gpu, we should not lose the RING_NONPRIV */ 304 253 305 - if (!engine) 254 + if (!engine || engine->whitelist.count == 0) 306 255 return 0; 307 256 308 - if (!whitelist_build(engine, &w)) 309 - return 0; 310 - 311 - pr_info("Checking %d whitelisted registers (RING_NONPRIV)\n", w.count); 312 - 313 - set_bit(I915_RESET_BACKOFF, &error->flags); 314 - set_bit(I915_RESET_ENGINE + engine->id, &error->flags); 257 + igt_global_reset_lock(i915); 315 258 316 259 if (intel_has_reset_engine(i915)) { 317 260 err = check_whitelist_across_reset(engine, 318 - do_engine_reset, &w, 261 + do_engine_reset, 319 262 "engine"); 320 263 if (err) 321 264 goto out; ··· 315 274 316 275 if (intel_has_gpu_reset(i915)) { 317 276 err = check_whitelist_across_reset(engine, 318 - do_device_reset, &w, 277 + do_device_reset, 319 278 "device"); 320 279 if (err) 321 280 goto out; 322 281 } 323 282 324 283 out: 325 - clear_bit(I915_RESET_ENGINE + engine->id, &error->flags); 326 - clear_bit(I915_RESET_BACKOFF, &error->flags); 284 + igt_global_reset_unlock(i915); 327 285 return err; 286 + } 287 + 288 + static bool verify_gt_engine_wa(struct drm_i915_private *i915, const char *str) 289 + { 290 + struct intel_engine_cs *engine; 291 + enum intel_engine_id id; 292 + bool ok = true; 293 + 294 + ok &= intel_gt_verify_workarounds(i915, str); 295 + 296 + for_each_engine(engine, i915, id) 297 + ok &= intel_engine_verify_workarounds(engine, str); 298 + 299 + return ok; 300 + } 301 + 302 + static int 303 + live_gpu_reset_gt_engine_workarounds(void *arg) 304 + { 305 + struct drm_i915_private *i915 = arg; 306 + struct i915_gpu_error *error = &i915->gpu_error; 307 + bool ok; 308 + 309 + if (!intel_has_gpu_reset(i915)) 310 + return 0; 311 + 312 + pr_info("Verifying after GPU reset...\n"); 313 + 314 + igt_global_reset_lock(i915); 315 + 316 + ok = verify_gt_engine_wa(i915, "before reset"); 317 + if (!ok) 318 + goto out; 319 + 320 + intel_runtime_pm_get(i915); 321 + set_bit(I915_RESET_HANDOFF, &error->flags); 322 + i915_reset(i915, ALL_ENGINES, "live_workarounds"); 323 + intel_runtime_pm_put(i915); 324 + 325 + ok = verify_gt_engine_wa(i915, "after reset"); 326 + 327 + out: 328 + igt_global_reset_unlock(i915); 329 + 330 + return ok ? 0 : -ESRCH; 331 + } 332 + 333 + static int 334 + live_engine_reset_gt_engine_workarounds(void *arg) 335 + { 336 + struct drm_i915_private *i915 = arg; 337 + struct intel_engine_cs *engine; 338 + struct i915_gem_context *ctx; 339 + struct igt_spinner spin; 340 + enum intel_engine_id id; 341 + struct i915_request *rq; 342 + int ret = 0; 343 + 344 + if (!intel_has_reset_engine(i915)) 345 + return 0; 346 + 347 + ctx = kernel_context(i915); 348 + if (IS_ERR(ctx)) 349 + return PTR_ERR(ctx); 350 + 351 + igt_global_reset_lock(i915); 352 + 353 + for_each_engine(engine, i915, id) { 354 + bool ok; 355 + 356 + pr_info("Verifying after %s reset...\n", engine->name); 357 + 358 + ok = verify_gt_engine_wa(i915, "before reset"); 359 + if (!ok) { 360 + ret = -ESRCH; 361 + goto err; 362 + } 363 + 364 + intel_runtime_pm_get(i915); 365 + i915_reset_engine(engine, "live_workarounds"); 366 + intel_runtime_pm_put(i915); 367 + 368 + ok = verify_gt_engine_wa(i915, "after idle reset"); 369 + if (!ok) { 370 + ret = -ESRCH; 371 + goto err; 372 + } 373 + 374 + ret = igt_spinner_init(&spin, i915); 375 + if (ret) 376 + goto err; 377 + 378 + intel_runtime_pm_get(i915); 379 + 380 + rq = igt_spinner_create_request(&spin, ctx, engine, MI_NOOP); 381 + if (IS_ERR(rq)) { 382 + ret = PTR_ERR(rq); 383 + igt_spinner_fini(&spin); 384 + intel_runtime_pm_put(i915); 385 + goto err; 386 + } 387 + 388 + i915_request_add(rq); 389 + 390 + if (!igt_wait_for_spinner(&spin, rq)) { 391 + pr_err("Spinner failed to start\n"); 392 + igt_spinner_fini(&spin); 393 + intel_runtime_pm_put(i915); 394 + ret = -ETIMEDOUT; 395 + goto err; 396 + } 397 + 398 + i915_reset_engine(engine, "live_workarounds"); 399 + 400 + intel_runtime_pm_put(i915); 401 + 402 + igt_spinner_end(&spin); 403 + igt_spinner_fini(&spin); 404 + 405 + ok = verify_gt_engine_wa(i915, "after busy reset"); 406 + if (!ok) { 407 + ret = -ESRCH; 408 + goto err; 409 + } 410 + } 411 + 412 + err: 413 + igt_global_reset_unlock(i915); 414 + kernel_context_close(ctx); 415 + 416 + igt_flush_test(i915, I915_WAIT_LOCKED); 417 + 418 + return ret; 328 419 } 329 420 330 421 int intel_workarounds_live_selftests(struct drm_i915_private *i915) 331 422 { 332 423 static const struct i915_subtest tests[] = { 333 424 SUBTEST(live_reset_whitelist), 425 + SUBTEST(live_gpu_reset_gt_engine_workarounds), 426 + SUBTEST(live_engine_reset_gt_engine_workarounds), 334 427 }; 335 428 int err; 336 429
+2 -2
fs/sysfs/file.c
··· 334 334 } 335 335 EXPORT_SYMBOL_GPL(sysfs_create_file_ns); 336 336 337 - int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr) 337 + int sysfs_create_files(struct kobject *kobj, const struct attribute * const *ptr) 338 338 { 339 339 int err = 0; 340 340 int i; ··· 493 493 return ret; 494 494 } 495 495 496 - void sysfs_remove_files(struct kobject *kobj, const struct attribute **ptr) 496 + void sysfs_remove_files(struct kobject *kobj, const struct attribute * const *ptr) 497 497 { 498 498 int i; 499 499 for (i = 0; ptr[i]; i++)
+2 -1
include/drm/drm_dp_helper.h
··· 1123 1123 u8 drm_dp_dsc_sink_max_slice_count(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE], 1124 1124 bool is_edp); 1125 1125 u8 drm_dp_dsc_sink_line_buf_depth(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]); 1126 - u8 drm_dp_dsc_sink_max_color_depth(const u8 dsc_dpc[DP_DSC_RECEIVER_CAP_SIZE]); 1126 + int drm_dp_dsc_sink_supported_input_bpcs(const u8 dsc_dpc[DP_DSC_RECEIVER_CAP_SIZE], 1127 + u8 dsc_bpc[3]); 1127 1128 1128 1129 static inline bool 1129 1130 drm_dp_sink_supports_dsc(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
+485
include/drm/drm_dsc.h
··· 1 + /* SPDX-License-Identifier: MIT 2 + * Copyright (C) 2018 Intel Corp. 3 + * 4 + * Authors: 5 + * Manasi Navare <manasi.d.navare@intel.com> 6 + */ 7 + 8 + #ifndef DRM_DSC_H_ 9 + #define DRM_DSC_H_ 10 + 11 + #include <drm/drm_dp_helper.h> 12 + 13 + /* VESA Display Stream Compression DSC 1.2 constants */ 14 + #define DSC_NUM_BUF_RANGES 15 15 + #define DSC_MUX_WORD_SIZE_8_10_BPC 48 16 + #define DSC_MUX_WORD_SIZE_12_BPC 64 17 + #define DSC_RC_PIXELS_PER_GROUP 3 18 + #define DSC_SCALE_DECREMENT_INTERVAL_MAX 4095 19 + #define DSC_RANGE_BPG_OFFSET_MASK 0x3f 20 + 21 + /* DSC Rate Control Constants */ 22 + #define DSC_RC_MODEL_SIZE_CONST 8192 23 + #define DSC_RC_EDGE_FACTOR_CONST 6 24 + #define DSC_RC_TGT_OFFSET_HI_CONST 3 25 + #define DSC_RC_TGT_OFFSET_LO_CONST 3 26 + 27 + /* DSC PPS constants and macros */ 28 + #define DSC_PPS_VERSION_MAJOR_SHIFT 4 29 + #define DSC_PPS_BPC_SHIFT 4 30 + #define DSC_PPS_MSB_SHIFT 8 31 + #define DSC_PPS_LSB_MASK (0xFF << 0) 32 + #define DSC_PPS_BPP_HIGH_MASK (0x3 << 8) 33 + #define DSC_PPS_VBR_EN_SHIFT 2 34 + #define DSC_PPS_SIMPLE422_SHIFT 3 35 + #define DSC_PPS_CONVERT_RGB_SHIFT 4 36 + #define DSC_PPS_BLOCK_PRED_EN_SHIFT 5 37 + #define DSC_PPS_INIT_XMIT_DELAY_HIGH_MASK (0x3 << 8) 38 + #define DSC_PPS_SCALE_DEC_INT_HIGH_MASK (0xF << 8) 39 + #define DSC_PPS_RC_TGT_OFFSET_HI_SHIFT 4 40 + #define DSC_PPS_RC_RANGE_MINQP_SHIFT 11 41 + #define DSC_PPS_RC_RANGE_MAXQP_SHIFT 6 42 + #define DSC_PPS_NATIVE_420_SHIFT 1 43 + #define DSC_1_2_MAX_LINEBUF_DEPTH_BITS 16 44 + #define DSC_1_2_MAX_LINEBUF_DEPTH_VAL 0 45 + #define DSC_1_1_MAX_LINEBUF_DEPTH_BITS 13 46 + 47 + /* Configuration for a single Rate Control model range */ 48 + struct drm_dsc_rc_range_parameters { 49 + /* Min Quantization Parameters allowed for this range */ 50 + u8 range_min_qp; 51 + /* Max Quantization Parameters allowed for this range */ 52 + u8 range_max_qp; 53 + /* Bits/group offset to apply to target for this group */ 54 + u8 range_bpg_offset; 55 + }; 56 + 57 + struct drm_dsc_config { 58 + /* Bits / component for previous reconstructed line buffer */ 59 + u8 line_buf_depth; 60 + /* Bits per component to code (must be 8, 10, or 12) */ 61 + u8 bits_per_component; 62 + /* 63 + * Flag indicating to do RGB - YCoCg conversion 64 + * and back (should be 1 for RGB input) 65 + */ 66 + bool convert_rgb; 67 + u8 slice_count; 68 + /* Slice Width */ 69 + u16 slice_width; 70 + /* Slice Height */ 71 + u16 slice_height; 72 + /* 73 + * 4:2:2 enable mode (from PPS, 4:2:2 conversion happens 74 + * outside of DSC encode/decode algorithm) 75 + */ 76 + bool enable422; 77 + /* Picture Width */ 78 + u16 pic_width; 79 + /* Picture Height */ 80 + u16 pic_height; 81 + /* Offset to bits/group used by RC to determine QP adjustment */ 82 + u8 rc_tgt_offset_high; 83 + /* Offset to bits/group used by RC to determine QP adjustment */ 84 + u8 rc_tgt_offset_low; 85 + /* Bits/pixel target << 4 (ie., 4 fractional bits) */ 86 + u16 bits_per_pixel; 87 + /* 88 + * Factor to determine if an edge is present based 89 + * on the bits produced 90 + */ 91 + u8 rc_edge_factor; 92 + /* Slow down incrementing once the range reaches this value */ 93 + u8 rc_quant_incr_limit1; 94 + /* Slow down incrementing once the range reaches this value */ 95 + u8 rc_quant_incr_limit0; 96 + /* Number of pixels to delay the initial transmission */ 97 + u16 initial_xmit_delay; 98 + /* Number of pixels to delay the VLD on the decoder,not including SSM */ 99 + u16 initial_dec_delay; 100 + /* Block prediction enable */ 101 + bool block_pred_enable; 102 + /* Bits/group offset to use for first line of the slice */ 103 + u8 first_line_bpg_offset; 104 + /* Value to use for RC model offset at slice start */ 105 + u16 initial_offset; 106 + /* Thresholds defining each of the buffer ranges */ 107 + u16 rc_buf_thresh[DSC_NUM_BUF_RANGES - 1]; 108 + /* Parameters for each of the RC ranges */ 109 + struct drm_dsc_rc_range_parameters rc_range_params[DSC_NUM_BUF_RANGES]; 110 + /* Total size of RC model */ 111 + u16 rc_model_size; 112 + /* Minimum QP where flatness information is sent */ 113 + u8 flatness_min_qp; 114 + /* Maximum QP where flatness information is sent */ 115 + u8 flatness_max_qp; 116 + /* Initial value for scale factor */ 117 + u8 initial_scale_value; 118 + /* Decrement scale factor every scale_decrement_interval groups */ 119 + u16 scale_decrement_interval; 120 + /* Increment scale factor every scale_increment_interval groups */ 121 + u16 scale_increment_interval; 122 + /* Non-first line BPG offset to use */ 123 + u16 nfl_bpg_offset; 124 + /* BPG offset used to enforce slice bit */ 125 + u16 slice_bpg_offset; 126 + /* Final RC linear transformation offset value */ 127 + u16 final_offset; 128 + /* Enable on-off VBR (ie., disable stuffing bits) */ 129 + bool vbr_enable; 130 + /* Mux word size (in bits) for SSM mode */ 131 + u8 mux_word_size; 132 + /* 133 + * The (max) size in bytes of the "chunks" that are 134 + * used in slice multiplexing 135 + */ 136 + u16 slice_chunk_size; 137 + /* Rate Control buffer siz in bits */ 138 + u16 rc_bits; 139 + /* DSC Minor Version */ 140 + u8 dsc_version_minor; 141 + /* DSC Major version */ 142 + u8 dsc_version_major; 143 + /* Native 4:2:2 support */ 144 + bool native_422; 145 + /* Native 4:2:0 support */ 146 + bool native_420; 147 + /* Additional bits/grp for seconnd line of slice for native 4:2:0 */ 148 + u8 second_line_bpg_offset; 149 + /* Num of bits deallocated for each grp that is not in second line of slice */ 150 + u16 nsl_bpg_offset; 151 + /* Offset adj fr second line in Native 4:2:0 mode */ 152 + u16 second_line_offset_adj; 153 + }; 154 + 155 + /** 156 + * struct picture_parameter_set - Represents 128 bytes of Picture Parameter Set 157 + * 158 + * The VESA DSC standard defines picture parameter set (PPS) which display 159 + * stream compression encoders must communicate to decoders. 160 + * The PPS is encapsulated in 128 bytes (PPS 0 through PPS 127). The fields in 161 + * this structure are as per Table 4.1 in Vesa DSC specification v1.1/v1.2. 162 + * The PPS fields that span over more than a byte should be stored in Big Endian 163 + * format. 164 + */ 165 + struct drm_dsc_picture_parameter_set { 166 + /** 167 + * @dsc_version: 168 + * PPS0[3:0] - dsc_version_minor: Contains Minor version of DSC 169 + * PPS0[7:4] - dsc_version_major: Contains major version of DSC 170 + */ 171 + u8 dsc_version; 172 + /** 173 + * @pps_identifier: 174 + * PPS1[7:0] - Application specific identifier that can be 175 + * used to differentiate between different PPS tables. 176 + */ 177 + u8 pps_identifier; 178 + /** 179 + * @pps_reserved: 180 + * PPS2[7:0]- RESERVED Byte 181 + */ 182 + u8 pps_reserved; 183 + /** 184 + * @pps_3: 185 + * PPS3[3:0] - linebuf_depth: Contains linebuffer bit depth used to 186 + * generate the bitstream. (0x0 - 16 bits for DSC 1.2, 0x8 - 8 bits, 187 + * 0xA - 10 bits, 0xB - 11 bits, 0xC - 12 bits, 0xD - 13 bits, 188 + * 0xE - 14 bits for DSC1.2, 0xF - 14 bits for DSC 1.2. 189 + * PPS3[7:4] - bits_per_component: Bits per component for the original 190 + * pixels of the encoded picture. 191 + * 0x0 = 16bpc (allowed only when dsc_version_minor = 0x2) 192 + * 0x8 = 8bpc, 0xA = 10bpc, 0xC = 12bpc, 0xE = 14bpc (also 193 + * allowed only when dsc_minor_version = 0x2) 194 + */ 195 + u8 pps_3; 196 + /** 197 + * @pps_4: 198 + * PPS4[1:0] -These are the most significant 2 bits of 199 + * compressed BPP bits_per_pixel[9:0] syntax element. 200 + * PPS4[2] - vbr_enable: 0 = VBR disabled, 1 = VBR enabled 201 + * PPS4[3] - simple_422: Indicates if decoder drops samples to 202 + * reconstruct the 4:2:2 picture. 203 + * PPS4[4] - Convert_rgb: Indicates if DSC color space conversion is 204 + * active. 205 + * PPS4[5] - blobk_pred_enable: Indicates if BP is used to code any 206 + * groups in picture 207 + * PPS4[7:6] - Reseved bits 208 + */ 209 + u8 pps_4; 210 + /** 211 + * @bits_per_pixel_low: 212 + * PPS5[7:0] - This indicates the lower significant 8 bits of 213 + * the compressed BPP bits_per_pixel[9:0] element. 214 + */ 215 + u8 bits_per_pixel_low; 216 + /** 217 + * @pic_height: 218 + * PPS6[7:0], PPS7[7:0] -pic_height: Specifies the number of pixel rows 219 + * within the raster. 220 + */ 221 + __be16 pic_height; 222 + /** 223 + * @pic_width: 224 + * PPS8[7:0], PPS9[7:0] - pic_width: Number of pixel columns within 225 + * the raster. 226 + */ 227 + __be16 pic_width; 228 + /** 229 + * @slice_height: 230 + * PPS10[7:0], PPS11[7:0] - Slice height in units of pixels. 231 + */ 232 + __be16 slice_height; 233 + /** 234 + * @slice_width: 235 + * PPS12[7:0], PPS13[7:0] - Slice width in terms of pixels. 236 + */ 237 + __be16 slice_width; 238 + /** 239 + * @chunk_size: 240 + * PPS14[7:0], PPS15[7:0] - Size in units of bytes of the chunks 241 + * that are used for slice multiplexing. 242 + */ 243 + __be16 chunk_size; 244 + /** 245 + * @initial_xmit_delay_high: 246 + * PPS16[1:0] - Most Significant two bits of initial transmission delay. 247 + * It specifies the number of pixel times that the encoder waits before 248 + * transmitting data from its rate buffer. 249 + * PPS16[7:2] - Reserved 250 + */ 251 + u8 initial_xmit_delay_high; 252 + /** 253 + * @initial_xmit_delay_low: 254 + * PPS17[7:0] - Least significant 8 bits of initial transmission delay. 255 + */ 256 + u8 initial_xmit_delay_low; 257 + /** 258 + * @initial_dec_delay: 259 + * 260 + * PPS18[7:0], PPS19[7:0] - Initial decoding delay which is the number 261 + * of pixel times that the decoder accumulates data in its rate buffer 262 + * before starting to decode and output pixels. 263 + */ 264 + __be16 initial_dec_delay; 265 + /** 266 + * @pps20_reserved: 267 + * 268 + * PPS20[7:0] - Reserved 269 + */ 270 + u8 pps20_reserved; 271 + /** 272 + * @initial_scale_value: 273 + * PPS21[5:0] - Initial rcXformScale factor used at beginning 274 + * of a slice. 275 + * PPS21[7:6] - Reserved 276 + */ 277 + u8 initial_scale_value; 278 + /** 279 + * @scale_increment_interval: 280 + * PPS22[7:0], PPS23[7:0] - Number of group times between incrementing 281 + * the rcXformScale factor at end of a slice. 282 + */ 283 + __be16 scale_increment_interval; 284 + /** 285 + * @scale_decrement_interval_high: 286 + * PPS24[3:0] - Higher 4 bits indicating number of group times between 287 + * decrementing the rcXformScale factor at beginning of a slice. 288 + * PPS24[7:4] - Reserved 289 + */ 290 + u8 scale_decrement_interval_high; 291 + /** 292 + * @scale_decrement_interval_low: 293 + * PPS25[7:0] - Lower 8 bits of scale decrement interval 294 + */ 295 + u8 scale_decrement_interval_low; 296 + /** 297 + * @pps26_reserved: 298 + * PPS26[7:0] 299 + */ 300 + u8 pps26_reserved; 301 + /** 302 + * @first_line_bpg_offset: 303 + * PPS27[4:0] - Number of additional bits that are allocated 304 + * for each group on first line of a slice. 305 + * PPS27[7:5] - Reserved 306 + */ 307 + u8 first_line_bpg_offset; 308 + /** 309 + * @nfl_bpg_offset: 310 + * PPS28[7:0], PPS29[7:0] - Number of bits including frac bits 311 + * deallocated for each group for groups after the first line of slice. 312 + */ 313 + __be16 nfl_bpg_offset; 314 + /** 315 + * @slice_bpg_offset: 316 + * PPS30, PPS31[7:0] - Number of bits that are deallocated for each 317 + * group to enforce the slice constraint. 318 + */ 319 + __be16 slice_bpg_offset; 320 + /** 321 + * @initial_offset: 322 + * PPS32,33[7:0] - Initial value for rcXformOffset 323 + */ 324 + __be16 initial_offset; 325 + /** 326 + * @final_offset: 327 + * PPS34,35[7:0] - Maximum end-of-slice value for rcXformOffset 328 + */ 329 + __be16 final_offset; 330 + /** 331 + * @flatness_min_qp: 332 + * PPS36[4:0] - Minimum QP at which flatness is signaled and 333 + * flatness QP adjustment is made. 334 + * PPS36[7:5] - Reserved 335 + */ 336 + u8 flatness_min_qp; 337 + /** 338 + * @flatness_max_qp: 339 + * PPS37[4:0] - Max QP at which flatness is signalled and 340 + * the flatness adjustment is made. 341 + * PPS37[7:5] - Reserved 342 + */ 343 + u8 flatness_max_qp; 344 + /** 345 + * @rc_model_size: 346 + * PPS38,39[7:0] - Number of bits within RC Model. 347 + */ 348 + __be16 rc_model_size; 349 + /** 350 + * @rc_edge_factor: 351 + * PPS40[3:0] - Ratio of current activity vs, previous 352 + * activity to determine presence of edge. 353 + * PPS40[7:4] - Reserved 354 + */ 355 + u8 rc_edge_factor; 356 + /** 357 + * @rc_quant_incr_limit0: 358 + * PPS41[4:0] - QP threshold used in short term RC 359 + * PPS41[7:5] - Reserved 360 + */ 361 + u8 rc_quant_incr_limit0; 362 + /** 363 + * @rc_quant_incr_limit1: 364 + * PPS42[4:0] - QP threshold used in short term RC 365 + * PPS42[7:5] - Reserved 366 + */ 367 + u8 rc_quant_incr_limit1; 368 + /** 369 + * @rc_tgt_offset: 370 + * PPS43[3:0] - Lower end of the variability range around the target 371 + * bits per group that is allowed by short term RC. 372 + * PPS43[7:4]- Upper end of the variability range around the target 373 + * bits per group that i allowed by short term rc. 374 + */ 375 + u8 rc_tgt_offset; 376 + /** 377 + * @rc_buf_thresh: 378 + * PPS44[7:0] - PPS57[7:0] - Specifies the thresholds in RC model for 379 + * the 15 ranges defined by 14 thresholds. 380 + */ 381 + u8 rc_buf_thresh[DSC_NUM_BUF_RANGES - 1]; 382 + /** 383 + * @rc_range_parameters: 384 + * PPS58[7:0] - PPS87[7:0] 385 + * Parameters that correspond to each of the 15 ranges. 386 + */ 387 + __be16 rc_range_parameters[DSC_NUM_BUF_RANGES]; 388 + /** 389 + * @native_422_420: 390 + * PPS88[0] - 0 = Native 4:2:2 not used 391 + * 1 = Native 4:2:2 used 392 + * PPS88[1] - 0 = Native 4:2:0 not use 393 + * 1 = Native 4:2:0 used 394 + * PPS88[7:2] - Reserved 6 bits 395 + */ 396 + u8 native_422_420; 397 + /** 398 + * @second_line_bpg_offset: 399 + * PPS89[4:0] - Additional bits/group budget for the 400 + * second line of a slice in Native 4:2:0 mode. 401 + * Set to 0 if DSC minor version is 1 or native420 is 0. 402 + * PPS89[7:5] - Reserved 403 + */ 404 + u8 second_line_bpg_offset; 405 + /** 406 + * @nsl_bpg_offset: 407 + * PPS90[7:0], PPS91[7:0] - Number of bits that are deallocated 408 + * for each group that is not in the second line of a slice. 409 + */ 410 + __be16 nsl_bpg_offset; 411 + /** 412 + * @second_line_offset_adj: 413 + * PPS92[7:0], PPS93[7:0] - Used as offset adjustment for the second 414 + * line in Native 4:2:0 mode. 415 + */ 416 + __be16 second_line_offset_adj; 417 + /** 418 + * @pps_long_94_reserved: 419 + * PPS 94, 95, 96, 97 - Reserved 420 + */ 421 + u32 pps_long_94_reserved; 422 + /** 423 + * @pps_long_98_reserved: 424 + * PPS 98, 99, 100, 101 - Reserved 425 + */ 426 + u32 pps_long_98_reserved; 427 + /** 428 + * @pps_long_102_reserved: 429 + * PPS 102, 103, 104, 105 - Reserved 430 + */ 431 + u32 pps_long_102_reserved; 432 + /** 433 + * @pps_long_106_reserved: 434 + * PPS 106, 107, 108, 109 - reserved 435 + */ 436 + u32 pps_long_106_reserved; 437 + /** 438 + * @pps_long_110_reserved: 439 + * PPS 110, 111, 112, 113 - reserved 440 + */ 441 + u32 pps_long_110_reserved; 442 + /** 443 + * @pps_long_114_reserved: 444 + * PPS 114 - 117 - reserved 445 + */ 446 + u32 pps_long_114_reserved; 447 + /** 448 + * @pps_long_118_reserved: 449 + * PPS 118 - 121 - reserved 450 + */ 451 + u32 pps_long_118_reserved; 452 + /** 453 + * @pps_long_122_reserved: 454 + * PPS 122- 125 - reserved 455 + */ 456 + u32 pps_long_122_reserved; 457 + /** 458 + * @pps_short_126_reserved: 459 + * PPS 126, 127 - reserved 460 + */ 461 + __be16 pps_short_126_reserved; 462 + } __packed; 463 + 464 + /** 465 + * struct drm_dsc_pps_infoframe - DSC infoframe carrying the Picture Parameter 466 + * Set Metadata 467 + * 468 + * This structure represents the DSC PPS infoframe required to send the Picture 469 + * Parameter Set metadata required before enabling VESA Display Stream 470 + * Compression. This is based on the DP Secondary Data Packet structure and 471 + * comprises of SDP Header as defined in drm_dp_helper.h and PPS payload. 472 + * 473 + * @pps_header: Header for PPS as per DP SDP header format 474 + * @pps_payload: PPS payload fields as per DSC specification Table 4-1 475 + */ 476 + struct drm_dsc_pps_infoframe { 477 + struct dp_sdp_header pps_header; 478 + struct drm_dsc_picture_parameter_set pps_payload; 479 + } __packed; 480 + 481 + void drm_dsc_dp_pps_header_init(struct drm_dsc_pps_infoframe *pps_sdp); 482 + void drm_dsc_pps_infoframe_pack(struct drm_dsc_pps_infoframe *pps_sdp, 483 + const struct drm_dsc_config *dsc_cfg); 484 + 485 + #endif /* _DRM_DSC_H_ */
+4 -4
include/linux/sysfs.h
··· 234 234 const struct attribute *attr, 235 235 const void *ns); 236 236 int __must_check sysfs_create_files(struct kobject *kobj, 237 - const struct attribute **attr); 237 + const struct attribute * const *attr); 238 238 int __must_check sysfs_chmod_file(struct kobject *kobj, 239 239 const struct attribute *attr, umode_t mode); 240 240 struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj, ··· 243 243 void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr, 244 244 const void *ns); 245 245 bool sysfs_remove_file_self(struct kobject *kobj, const struct attribute *attr); 246 - void sysfs_remove_files(struct kobject *kobj, const struct attribute **attr); 246 + void sysfs_remove_files(struct kobject *kobj, const struct attribute * const *attr); 247 247 248 248 int __must_check sysfs_create_bin_file(struct kobject *kobj, 249 249 const struct bin_attribute *attr); ··· 342 342 } 343 343 344 344 static inline int sysfs_create_files(struct kobject *kobj, 345 - const struct attribute **attr) 345 + const struct attribute * const *attr) 346 346 { 347 347 return 0; 348 348 } ··· 377 377 } 378 378 379 379 static inline void sysfs_remove_files(struct kobject *kobj, 380 - const struct attribute **attr) 380 + const struct attribute * const *attr) 381 381 { 382 382 } 383 383