mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
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
This commit is contained in:
@@ -232,6 +232,18 @@ MIPI DSI Helper Functions Reference
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_mipi_dsi.c
|
||||
:export:
|
||||
|
||||
Display Stream Compression Helper Functions Reference
|
||||
=====================================================
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_dsc.c
|
||||
:doc: dsc helpers
|
||||
|
||||
.. kernel-doc:: include/drm/drm_dsc.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_dsc.c
|
||||
:export:
|
||||
|
||||
Output Probing Helper Functions Reference
|
||||
=========================================
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ drm-$(CONFIG_AGP) += drm_agpsupport.o
|
||||
drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o
|
||||
drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
|
||||
|
||||
drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
|
||||
drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_dsc.o drm_probe_helper.o \
|
||||
drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
|
||||
drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
|
||||
drm_simple_kms_helper.o drm_modeset_helper.o \
|
||||
|
||||
@@ -1428,17 +1428,19 @@ u8 drm_dp_dsc_sink_line_buf_depth(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
|
||||
}
|
||||
EXPORT_SYMBOL(drm_dp_dsc_sink_line_buf_depth);
|
||||
|
||||
u8 drm_dp_dsc_sink_max_color_depth(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
|
||||
int drm_dp_dsc_sink_supported_input_bpcs(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE],
|
||||
u8 dsc_bpc[3])
|
||||
{
|
||||
int num_bpc = 0;
|
||||
u8 color_depth = dsc_dpcd[DP_DSC_DEC_COLOR_DEPTH_CAP - DP_DSC_SUPPORT];
|
||||
|
||||
if (color_depth & DP_DSC_12_BPC)
|
||||
return 12;
|
||||
dsc_bpc[num_bpc++] = 12;
|
||||
if (color_depth & DP_DSC_10_BPC)
|
||||
return 10;
|
||||
dsc_bpc[num_bpc++] = 10;
|
||||
if (color_depth & DP_DSC_8_BPC)
|
||||
return 8;
|
||||
dsc_bpc[num_bpc++] = 8;
|
||||
|
||||
return 0;
|
||||
return num_bpc;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_dp_dsc_sink_max_color_depth);
|
||||
EXPORT_SYMBOL(drm_dp_dsc_sink_supported_input_bpcs);
|
||||
|
||||
228
drivers/gpu/drm/drm_dsc.c
Normal file
228
drivers/gpu/drm/drm_dsc.c
Normal file
@@ -0,0 +1,228 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright © 2018 Intel Corp
|
||||
*
|
||||
* Author:
|
||||
* Manasi Navare <manasi.d.navare@intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <drm/drm_dp_helper.h>
|
||||
#include <drm/drm_dsc.h>
|
||||
|
||||
/**
|
||||
* DOC: dsc helpers
|
||||
*
|
||||
* These functions contain some common logic and helpers to deal with VESA
|
||||
* Display Stream Compression standard required for DSC on Display Port/eDP or
|
||||
* MIPI display interfaces.
|
||||
*/
|
||||
|
||||
/**
|
||||
* drm_dsc_dp_pps_header_init() - Initializes the PPS Header
|
||||
* for DisplayPort as per the DP 1.4 spec.
|
||||
* @pps_sdp: Secondary data packet for DSC Picture Parameter Set
|
||||
*/
|
||||
void drm_dsc_dp_pps_header_init(struct drm_dsc_pps_infoframe *pps_sdp)
|
||||
{
|
||||
memset(&pps_sdp->pps_header, 0, sizeof(pps_sdp->pps_header));
|
||||
|
||||
pps_sdp->pps_header.HB1 = DP_SDP_PPS;
|
||||
pps_sdp->pps_header.HB2 = DP_SDP_PPS_HEADER_PAYLOAD_BYTES_MINUS_1;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_dsc_dp_pps_header_init);
|
||||
|
||||
/**
|
||||
* drm_dsc_pps_infoframe_pack() - Populates the DSC PPS infoframe
|
||||
* using the DSC configuration parameters in the order expected
|
||||
* by the DSC Display Sink device. For the DSC, the sink device
|
||||
* expects the PPS payload in the big endian format for the fields
|
||||
* that span more than 1 byte.
|
||||
*
|
||||
* @pps_sdp:
|
||||
* Secondary data packet for DSC Picture Parameter Set
|
||||
* @dsc_cfg:
|
||||
* DSC Configuration data filled by driver
|
||||
*/
|
||||
void drm_dsc_pps_infoframe_pack(struct drm_dsc_pps_infoframe *pps_sdp,
|
||||
const struct drm_dsc_config *dsc_cfg)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Protect against someone accidently changing struct size */
|
||||
BUILD_BUG_ON(sizeof(pps_sdp->pps_payload) !=
|
||||
DP_SDP_PPS_HEADER_PAYLOAD_BYTES_MINUS_1 + 1);
|
||||
|
||||
memset(&pps_sdp->pps_payload, 0, sizeof(pps_sdp->pps_payload));
|
||||
|
||||
/* PPS 0 */
|
||||
pps_sdp->pps_payload.dsc_version =
|
||||
dsc_cfg->dsc_version_minor |
|
||||
dsc_cfg->dsc_version_major << DSC_PPS_VERSION_MAJOR_SHIFT;
|
||||
|
||||
/* PPS 1, 2 is 0 */
|
||||
|
||||
/* PPS 3 */
|
||||
pps_sdp->pps_payload.pps_3 =
|
||||
dsc_cfg->line_buf_depth |
|
||||
dsc_cfg->bits_per_component << DSC_PPS_BPC_SHIFT;
|
||||
|
||||
/* PPS 4 */
|
||||
pps_sdp->pps_payload.pps_4 =
|
||||
((dsc_cfg->bits_per_pixel & DSC_PPS_BPP_HIGH_MASK) >>
|
||||
DSC_PPS_MSB_SHIFT) |
|
||||
dsc_cfg->vbr_enable << DSC_PPS_VBR_EN_SHIFT |
|
||||
dsc_cfg->enable422 << DSC_PPS_SIMPLE422_SHIFT |
|
||||
dsc_cfg->convert_rgb << DSC_PPS_CONVERT_RGB_SHIFT |
|
||||
dsc_cfg->block_pred_enable << DSC_PPS_BLOCK_PRED_EN_SHIFT;
|
||||
|
||||
/* PPS 5 */
|
||||
pps_sdp->pps_payload.bits_per_pixel_low =
|
||||
(dsc_cfg->bits_per_pixel & DSC_PPS_LSB_MASK);
|
||||
|
||||
/*
|
||||
* The DSC panel expects the PPS packet to have big endian format
|
||||
* for data spanning 2 bytes. Use a macro cpu_to_be16() to convert
|
||||
* to big endian format. If format is little endian, it will swap
|
||||
* bytes to convert to Big endian else keep it unchanged.
|
||||
*/
|
||||
|
||||
/* PPS 6, 7 */
|
||||
pps_sdp->pps_payload.pic_height = cpu_to_be16(dsc_cfg->pic_height);
|
||||
|
||||
/* PPS 8, 9 */
|
||||
pps_sdp->pps_payload.pic_width = cpu_to_be16(dsc_cfg->pic_width);
|
||||
|
||||
/* PPS 10, 11 */
|
||||
pps_sdp->pps_payload.slice_height = cpu_to_be16(dsc_cfg->slice_height);
|
||||
|
||||
/* PPS 12, 13 */
|
||||
pps_sdp->pps_payload.slice_width = cpu_to_be16(dsc_cfg->slice_width);
|
||||
|
||||
/* PPS 14, 15 */
|
||||
pps_sdp->pps_payload.chunk_size = cpu_to_be16(dsc_cfg->slice_chunk_size);
|
||||
|
||||
/* PPS 16 */
|
||||
pps_sdp->pps_payload.initial_xmit_delay_high =
|
||||
((dsc_cfg->initial_xmit_delay &
|
||||
DSC_PPS_INIT_XMIT_DELAY_HIGH_MASK) >>
|
||||
DSC_PPS_MSB_SHIFT);
|
||||
|
||||
/* PPS 17 */
|
||||
pps_sdp->pps_payload.initial_xmit_delay_low =
|
||||
(dsc_cfg->initial_xmit_delay & DSC_PPS_LSB_MASK);
|
||||
|
||||
/* PPS 18, 19 */
|
||||
pps_sdp->pps_payload.initial_dec_delay =
|
||||
cpu_to_be16(dsc_cfg->initial_dec_delay);
|
||||
|
||||
/* PPS 20 is 0 */
|
||||
|
||||
/* PPS 21 */
|
||||
pps_sdp->pps_payload.initial_scale_value =
|
||||
dsc_cfg->initial_scale_value;
|
||||
|
||||
/* PPS 22, 23 */
|
||||
pps_sdp->pps_payload.scale_increment_interval =
|
||||
cpu_to_be16(dsc_cfg->scale_increment_interval);
|
||||
|
||||
/* PPS 24 */
|
||||
pps_sdp->pps_payload.scale_decrement_interval_high =
|
||||
((dsc_cfg->scale_decrement_interval &
|
||||
DSC_PPS_SCALE_DEC_INT_HIGH_MASK) >>
|
||||
DSC_PPS_MSB_SHIFT);
|
||||
|
||||
/* PPS 25 */
|
||||
pps_sdp->pps_payload.scale_decrement_interval_low =
|
||||
(dsc_cfg->scale_decrement_interval & DSC_PPS_LSB_MASK);
|
||||
|
||||
/* PPS 26[7:0], PPS 27[7:5] RESERVED */
|
||||
|
||||
/* PPS 27 */
|
||||
pps_sdp->pps_payload.first_line_bpg_offset =
|
||||
dsc_cfg->first_line_bpg_offset;
|
||||
|
||||
/* PPS 28, 29 */
|
||||
pps_sdp->pps_payload.nfl_bpg_offset =
|
||||
cpu_to_be16(dsc_cfg->nfl_bpg_offset);
|
||||
|
||||
/* PPS 30, 31 */
|
||||
pps_sdp->pps_payload.slice_bpg_offset =
|
||||
cpu_to_be16(dsc_cfg->slice_bpg_offset);
|
||||
|
||||
/* PPS 32, 33 */
|
||||
pps_sdp->pps_payload.initial_offset =
|
||||
cpu_to_be16(dsc_cfg->initial_offset);
|
||||
|
||||
/* PPS 34, 35 */
|
||||
pps_sdp->pps_payload.final_offset = cpu_to_be16(dsc_cfg->final_offset);
|
||||
|
||||
/* PPS 36 */
|
||||
pps_sdp->pps_payload.flatness_min_qp = dsc_cfg->flatness_min_qp;
|
||||
|
||||
/* PPS 37 */
|
||||
pps_sdp->pps_payload.flatness_max_qp = dsc_cfg->flatness_max_qp;
|
||||
|
||||
/* PPS 38, 39 */
|
||||
pps_sdp->pps_payload.rc_model_size =
|
||||
cpu_to_be16(DSC_RC_MODEL_SIZE_CONST);
|
||||
|
||||
/* PPS 40 */
|
||||
pps_sdp->pps_payload.rc_edge_factor = DSC_RC_EDGE_FACTOR_CONST;
|
||||
|
||||
/* PPS 41 */
|
||||
pps_sdp->pps_payload.rc_quant_incr_limit0 =
|
||||
dsc_cfg->rc_quant_incr_limit0;
|
||||
|
||||
/* PPS 42 */
|
||||
pps_sdp->pps_payload.rc_quant_incr_limit1 =
|
||||
dsc_cfg->rc_quant_incr_limit1;
|
||||
|
||||
/* PPS 43 */
|
||||
pps_sdp->pps_payload.rc_tgt_offset = DSC_RC_TGT_OFFSET_LO_CONST |
|
||||
DSC_RC_TGT_OFFSET_HI_CONST << DSC_PPS_RC_TGT_OFFSET_HI_SHIFT;
|
||||
|
||||
/* PPS 44 - 57 */
|
||||
for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++)
|
||||
pps_sdp->pps_payload.rc_buf_thresh[i] =
|
||||
dsc_cfg->rc_buf_thresh[i];
|
||||
|
||||
/* PPS 58 - 87 */
|
||||
/*
|
||||
* For DSC sink programming the RC Range parameter fields
|
||||
* are as follows: Min_qp[15:11], max_qp[10:6], offset[5:0]
|
||||
*/
|
||||
for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
|
||||
pps_sdp->pps_payload.rc_range_parameters[i] =
|
||||
((dsc_cfg->rc_range_params[i].range_min_qp <<
|
||||
DSC_PPS_RC_RANGE_MINQP_SHIFT) |
|
||||
(dsc_cfg->rc_range_params[i].range_max_qp <<
|
||||
DSC_PPS_RC_RANGE_MAXQP_SHIFT) |
|
||||
(dsc_cfg->rc_range_params[i].range_bpg_offset));
|
||||
pps_sdp->pps_payload.rc_range_parameters[i] =
|
||||
cpu_to_be16(pps_sdp->pps_payload.rc_range_parameters[i]);
|
||||
}
|
||||
|
||||
/* PPS 88 */
|
||||
pps_sdp->pps_payload.native_422_420 = dsc_cfg->native_422 |
|
||||
dsc_cfg->native_420 << DSC_PPS_NATIVE_420_SHIFT;
|
||||
|
||||
/* PPS 89 */
|
||||
pps_sdp->pps_payload.second_line_bpg_offset =
|
||||
dsc_cfg->second_line_bpg_offset;
|
||||
|
||||
/* PPS 90, 91 */
|
||||
pps_sdp->pps_payload.nsl_bpg_offset =
|
||||
cpu_to_be16(dsc_cfg->nsl_bpg_offset);
|
||||
|
||||
/* PPS 92, 93 */
|
||||
pps_sdp->pps_payload.second_line_offset_adj =
|
||||
cpu_to_be16(dsc_cfg->second_line_offset_adj);
|
||||
|
||||
/* PPS 94 - 127 are O */
|
||||
}
|
||||
EXPORT_SYMBOL(drm_dsc_pps_infoframe_pack);
|
||||
@@ -157,14 +157,17 @@ i915-y += dvo_ch7017.o \
|
||||
intel_sdvo.o \
|
||||
intel_tv.o \
|
||||
vlv_dsi.o \
|
||||
vlv_dsi_pll.o
|
||||
vlv_dsi_pll.o \
|
||||
intel_vdsc.o
|
||||
|
||||
# Post-mortem debug and GPU hang state capture
|
||||
i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o
|
||||
i915-$(CONFIG_DRM_I915_SELFTEST) += \
|
||||
selftests/i915_random.o \
|
||||
selftests/i915_selftest.o \
|
||||
selftests/igt_flush_test.o
|
||||
selftests/igt_flush_test.o \
|
||||
selftests/igt_reset.o \
|
||||
selftests/igt_spinner.o
|
||||
|
||||
# virtual gpu code
|
||||
i915-y += i915_vgpu.o
|
||||
|
||||
@@ -943,30 +943,30 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data)
|
||||
static ssize_t gpu_state_read(struct file *file, char __user *ubuf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
struct i915_gpu_state *error = file->private_data;
|
||||
struct drm_i915_error_state_buf str;
|
||||
struct i915_gpu_state *error;
|
||||
ssize_t ret;
|
||||
loff_t tmp;
|
||||
void *buf;
|
||||
|
||||
error = file->private_data;
|
||||
if (!error)
|
||||
return 0;
|
||||
|
||||
ret = i915_error_state_buf_init(&str, error->i915, count, *pos);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* Bounce buffer required because of kernfs __user API convenience. */
|
||||
buf = kmalloc(count, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = i915_error_state_to_str(&str, error);
|
||||
if (ret)
|
||||
ret = i915_gpu_state_copy_to_buffer(error, buf, *pos, count);
|
||||
if (ret <= 0)
|
||||
goto out;
|
||||
|
||||
tmp = 0;
|
||||
ret = simple_read_from_buffer(ubuf, count, &tmp, str.buf, str.bytes);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
if (!copy_to_user(ubuf, buf, ret))
|
||||
*pos += ret;
|
||||
else
|
||||
ret = -EFAULT;
|
||||
|
||||
*pos = str.start + ret;
|
||||
out:
|
||||
i915_error_state_buf_release(&str);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3375,13 +3375,15 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
|
||||
|
||||
static int i915_wa_registers(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct i915_workarounds *wa = &node_to_i915(m->private)->workarounds;
|
||||
int i;
|
||||
struct drm_i915_private *i915 = node_to_i915(m->private);
|
||||
const struct i915_wa_list *wal = &i915->engine[RCS]->ctx_wa_list;
|
||||
struct i915_wa *wa;
|
||||
unsigned int i;
|
||||
|
||||
seq_printf(m, "Workarounds applied: %d\n", wa->count);
|
||||
for (i = 0; i < wa->count; ++i)
|
||||
seq_printf(m, "Workarounds applied: %u\n", wal->count);
|
||||
for (i = 0, wa = wal->list; i < wal->count; i++, wa++)
|
||||
seq_printf(m, "0x%X: 0x%08X, mask: 0x%08X\n",
|
||||
wa->reg[i].addr, wa->reg[i].value, wa->reg[i].mask);
|
||||
i915_mmio_reg_offset(wa->reg), wa->val, wa->mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3441,31 +3443,32 @@ static int i915_ddb_info(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct skl_ddb_allocation *ddb;
|
||||
struct skl_ddb_entry *entry;
|
||||
enum pipe pipe;
|
||||
int plane;
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
if (INTEL_GEN(dev_priv) < 9)
|
||||
return -ENODEV;
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
|
||||
ddb = &dev_priv->wm.skl_hw.ddb;
|
||||
|
||||
seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
|
||||
|
||||
for_each_pipe(dev_priv, pipe) {
|
||||
for_each_intel_crtc(&dev_priv->drm, crtc) {
|
||||
struct intel_crtc_state *crtc_state =
|
||||
to_intel_crtc_state(crtc->base.state);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
enum plane_id plane_id;
|
||||
|
||||
seq_printf(m, "Pipe %c\n", pipe_name(pipe));
|
||||
|
||||
for_each_universal_plane(dev_priv, pipe, plane) {
|
||||
entry = &ddb->plane[pipe][plane];
|
||||
seq_printf(m, " Plane%-8d%8u%8u%8u\n", plane + 1,
|
||||
for_each_plane_id_on_crtc(crtc, plane_id) {
|
||||
entry = &crtc_state->wm.skl.plane_ddb_y[plane_id];
|
||||
seq_printf(m, " Plane%-8d%8u%8u%8u\n", plane_id + 1,
|
||||
entry->start, entry->end,
|
||||
skl_ddb_entry_size(entry));
|
||||
}
|
||||
|
||||
entry = &ddb->plane[pipe][PLANE_CURSOR];
|
||||
entry = &crtc_state->wm.skl.plane_ddb_y[PLANE_CURSOR];
|
||||
seq_printf(m, " %-13s%8u%8u%8u\n", "Cursor", entry->start,
|
||||
entry->end, skl_ddb_entry_size(entry));
|
||||
}
|
||||
@@ -4592,6 +4595,13 @@ static int i915_hpd_storm_ctl_show(struct seq_file *m, void *data)
|
||||
struct drm_i915_private *dev_priv = m->private;
|
||||
struct i915_hotplug *hotplug = &dev_priv->hotplug;
|
||||
|
||||
/* Synchronize with everything first in case there's been an HPD
|
||||
* storm, but we haven't finished handling it in the kernel yet
|
||||
*/
|
||||
synchronize_irq(dev_priv->drm.irq);
|
||||
flush_work(&dev_priv->hotplug.dig_port_work);
|
||||
flush_work(&dev_priv->hotplug.hotplug_work);
|
||||
|
||||
seq_printf(m, "Threshold: %d\n", hotplug->hpd_storm_threshold);
|
||||
seq_printf(m, "Detected: %s\n",
|
||||
yesno(delayed_work_pending(&hotplug->reenable_work)));
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "i915_vgpu.h"
|
||||
#include "intel_drv.h"
|
||||
#include "intel_uc.h"
|
||||
#include "intel_workarounds.h"
|
||||
|
||||
static struct drm_driver driver;
|
||||
|
||||
@@ -287,7 +288,7 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv)
|
||||
* Use PCH_NOP (PCH but no South Display) for PCH platforms without
|
||||
* display.
|
||||
*/
|
||||
if (pch && INTEL_INFO(dev_priv)->num_pipes == 0) {
|
||||
if (pch && !HAS_DISPLAY(dev_priv)) {
|
||||
DRM_DEBUG_KMS("Display disabled, reverting to NOP PCH\n");
|
||||
dev_priv->pch_type = PCH_NOP;
|
||||
dev_priv->pch_id = 0;
|
||||
@@ -645,7 +646,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
|
||||
if (i915_inject_load_failure())
|
||||
return -ENODEV;
|
||||
|
||||
if (INTEL_INFO(dev_priv)->num_pipes) {
|
||||
if (HAS_DISPLAY(dev_priv)) {
|
||||
ret = drm_vblank_init(&dev_priv->drm,
|
||||
INTEL_INFO(dev_priv)->num_pipes);
|
||||
if (ret)
|
||||
@@ -696,7 +697,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
|
||||
|
||||
intel_overlay_setup(dev_priv);
|
||||
|
||||
if (INTEL_INFO(dev_priv)->num_pipes == 0)
|
||||
if (!HAS_DISPLAY(dev_priv))
|
||||
return 0;
|
||||
|
||||
ret = intel_fbdev_init(dev);
|
||||
@@ -868,6 +869,7 @@ static void intel_detect_preproduction_hw(struct drm_i915_private *dev_priv)
|
||||
pre |= IS_HSW_EARLY_SDV(dev_priv);
|
||||
pre |= IS_SKL_REVID(dev_priv, 0, SKL_REVID_F0);
|
||||
pre |= IS_BXT_REVID(dev_priv, 0, BXT_REVID_B_LAST);
|
||||
pre |= IS_KBL_REVID(dev_priv, 0, KBL_REVID_A0);
|
||||
|
||||
if (pre) {
|
||||
DRM_ERROR("This is a pre-production stepping. "
|
||||
@@ -1383,6 +1385,20 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
|
||||
}
|
||||
}
|
||||
|
||||
if (HAS_EXECLISTS(dev_priv)) {
|
||||
/*
|
||||
* Older GVT emulation depends upon intercepting CSB mmio,
|
||||
* which we no longer use, preferring to use the HWSP cache
|
||||
* instead.
|
||||
*/
|
||||
if (intel_vgpu_active(dev_priv) &&
|
||||
!intel_vgpu_has_hwsp_emulation(dev_priv)) {
|
||||
i915_report_error(dev_priv,
|
||||
"old vGPU host found, support for HWSP emulation required\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
|
||||
intel_sanitize_options(dev_priv);
|
||||
|
||||
i915_perf_init(dev_priv);
|
||||
@@ -1452,6 +1468,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
|
||||
|
||||
intel_uncore_sanitize(dev_priv);
|
||||
|
||||
intel_gt_init_workarounds(dev_priv);
|
||||
i915_gem_load_init_fences(dev_priv);
|
||||
|
||||
/* On the 945G/GM, the chipset reports the MSI capability on the
|
||||
@@ -1551,7 +1568,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
|
||||
} else
|
||||
DRM_ERROR("Failed to register driver for userspace access!\n");
|
||||
|
||||
if (INTEL_INFO(dev_priv)->num_pipes) {
|
||||
if (HAS_DISPLAY(dev_priv)) {
|
||||
/* Must be done after probing outputs */
|
||||
intel_opregion_register(dev_priv);
|
||||
acpi_video_register();
|
||||
@@ -1575,7 +1592,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
|
||||
* We need to coordinate the hotplugs with the asynchronous fbdev
|
||||
* configuration, for which we use the fbdev->async_cookie.
|
||||
*/
|
||||
if (INTEL_INFO(dev_priv)->num_pipes)
|
||||
if (HAS_DISPLAY(dev_priv))
|
||||
drm_kms_helper_poll_init(dev);
|
||||
|
||||
intel_power_domains_enable(dev_priv);
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include <drm/drm_auth.h>
|
||||
#include <drm/drm_cache.h>
|
||||
#include <drm/drm_util.h>
|
||||
#include <drm/drm_dsc.h>
|
||||
|
||||
#include "i915_fixed.h"
|
||||
#include "i915_params.h"
|
||||
@@ -68,6 +69,7 @@
|
||||
#include "intel_ringbuffer.h"
|
||||
#include "intel_uncore.h"
|
||||
#include "intel_wopcm.h"
|
||||
#include "intel_workarounds.h"
|
||||
#include "intel_uc.h"
|
||||
|
||||
#include "i915_gem.h"
|
||||
@@ -88,8 +90,8 @@
|
||||
|
||||
#define DRIVER_NAME "i915"
|
||||
#define DRIVER_DESC "Intel Graphics"
|
||||
#define DRIVER_DATE "20181122"
|
||||
#define DRIVER_TIMESTAMP 1542898187
|
||||
#define DRIVER_DATE "20181204"
|
||||
#define DRIVER_TIMESTAMP 1543944377
|
||||
|
||||
/* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and
|
||||
* WARN_ON()) for hw state sanity checks to check for unexpected conditions
|
||||
@@ -494,6 +496,7 @@ struct i915_psr {
|
||||
bool sink_support;
|
||||
bool prepared, enabled;
|
||||
struct intel_dp *dp;
|
||||
enum pipe pipe;
|
||||
bool active;
|
||||
struct work_struct work;
|
||||
unsigned busy_frontbuffer_bits;
|
||||
@@ -504,6 +507,8 @@ struct i915_psr {
|
||||
u8 sink_sync_latency;
|
||||
ktime_t last_entry_attempt;
|
||||
ktime_t last_exit;
|
||||
bool sink_not_reliable;
|
||||
bool irq_aux_error;
|
||||
};
|
||||
|
||||
enum intel_pch {
|
||||
@@ -1093,9 +1098,6 @@ static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
|
||||
}
|
||||
|
||||
struct skl_ddb_allocation {
|
||||
/* packed/y */
|
||||
struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
|
||||
struct skl_ddb_entry uv_plane[I915_MAX_PIPES][I915_MAX_PLANES];
|
||||
u8 enabled_slices; /* GEN11 has configurable 2 slices */
|
||||
};
|
||||
|
||||
@@ -1188,20 +1190,6 @@ struct i915_frontbuffer_tracking {
|
||||
unsigned flip_bits;
|
||||
};
|
||||
|
||||
struct i915_wa_reg {
|
||||
u32 addr;
|
||||
u32 value;
|
||||
/* bitmask representing WA bits */
|
||||
u32 mask;
|
||||
};
|
||||
|
||||
#define I915_MAX_WA_REGS 16
|
||||
|
||||
struct i915_workarounds {
|
||||
struct i915_wa_reg reg[I915_MAX_WA_REGS];
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct i915_virtual_gpu {
|
||||
bool active;
|
||||
u32 caps;
|
||||
@@ -1651,7 +1639,7 @@ struct drm_i915_private {
|
||||
|
||||
int dpio_phy_iosf_port[I915_NUM_PHYS_VLV];
|
||||
|
||||
struct i915_workarounds workarounds;
|
||||
struct i915_wa_list gt_wa_list;
|
||||
|
||||
struct i915_frontbuffer_tracking fb_tracking;
|
||||
|
||||
@@ -1995,6 +1983,8 @@ struct drm_i915_private {
|
||||
struct delayed_work idle_work;
|
||||
|
||||
ktime_t last_init_time;
|
||||
|
||||
struct i915_vma *scratch;
|
||||
} gt;
|
||||
|
||||
/* perform PHY state sanity checks? */
|
||||
@@ -2448,9 +2438,9 @@ intel_info(const struct drm_i915_private *dev_priv)
|
||||
((sizes) & ~(dev_priv)->info.page_sizes) == 0; \
|
||||
})
|
||||
|
||||
#define HAS_OVERLAY(dev_priv) ((dev_priv)->info.has_overlay)
|
||||
#define HAS_OVERLAY(dev_priv) ((dev_priv)->info.display.has_overlay)
|
||||
#define OVERLAY_NEEDS_PHYSICAL(dev_priv) \
|
||||
((dev_priv)->info.overlay_needs_physical)
|
||||
((dev_priv)->info.display.overlay_needs_physical)
|
||||
|
||||
/* Early gen2 have a totally busted CS tlb and require pinned batches. */
|
||||
#define HAS_BROKEN_CS_TLB(dev_priv) (IS_I830(dev_priv) || IS_I845G(dev_priv))
|
||||
@@ -2471,31 +2461,31 @@ intel_info(const struct drm_i915_private *dev_priv)
|
||||
#define HAS_128_BYTE_Y_TILING(dev_priv) (!IS_GEN2(dev_priv) && \
|
||||
!(IS_I915G(dev_priv) || \
|
||||
IS_I915GM(dev_priv)))
|
||||
#define SUPPORTS_TV(dev_priv) ((dev_priv)->info.supports_tv)
|
||||
#define I915_HAS_HOTPLUG(dev_priv) ((dev_priv)->info.has_hotplug)
|
||||
#define SUPPORTS_TV(dev_priv) ((dev_priv)->info.display.supports_tv)
|
||||
#define I915_HAS_HOTPLUG(dev_priv) ((dev_priv)->info.display.has_hotplug)
|
||||
|
||||
#define HAS_FW_BLC(dev_priv) (INTEL_GEN(dev_priv) > 2)
|
||||
#define HAS_FBC(dev_priv) ((dev_priv)->info.has_fbc)
|
||||
#define HAS_FBC(dev_priv) ((dev_priv)->info.display.has_fbc)
|
||||
#define HAS_CUR_FBC(dev_priv) (!HAS_GMCH_DISPLAY(dev_priv) && INTEL_GEN(dev_priv) >= 7)
|
||||
|
||||
#define HAS_IPS(dev_priv) (IS_HSW_ULT(dev_priv) || IS_BROADWELL(dev_priv))
|
||||
|
||||
#define HAS_DP_MST(dev_priv) ((dev_priv)->info.has_dp_mst)
|
||||
#define HAS_DP_MST(dev_priv) ((dev_priv)->info.display.has_dp_mst)
|
||||
|
||||
#define HAS_DDI(dev_priv) ((dev_priv)->info.has_ddi)
|
||||
#define HAS_DDI(dev_priv) ((dev_priv)->info.display.has_ddi)
|
||||
#define HAS_FPGA_DBG_UNCLAIMED(dev_priv) ((dev_priv)->info.has_fpga_dbg)
|
||||
#define HAS_PSR(dev_priv) ((dev_priv)->info.has_psr)
|
||||
#define HAS_PSR(dev_priv) ((dev_priv)->info.display.has_psr)
|
||||
|
||||
#define HAS_RC6(dev_priv) ((dev_priv)->info.has_rc6)
|
||||
#define HAS_RC6p(dev_priv) ((dev_priv)->info.has_rc6p)
|
||||
#define HAS_RC6pp(dev_priv) (false) /* HW was never validated */
|
||||
|
||||
#define HAS_CSR(dev_priv) ((dev_priv)->info.has_csr)
|
||||
#define HAS_CSR(dev_priv) ((dev_priv)->info.display.has_csr)
|
||||
|
||||
#define HAS_RUNTIME_PM(dev_priv) ((dev_priv)->info.has_runtime_pm)
|
||||
#define HAS_64BIT_RELOC(dev_priv) ((dev_priv)->info.has_64bit_reloc)
|
||||
|
||||
#define HAS_IPC(dev_priv) ((dev_priv)->info.has_ipc)
|
||||
#define HAS_IPC(dev_priv) ((dev_priv)->info.display.has_ipc)
|
||||
|
||||
/*
|
||||
* For now, anything with a GuC requires uCode loading, and then supports
|
||||
@@ -2556,7 +2546,7 @@ intel_info(const struct drm_i915_private *dev_priv)
|
||||
#define HAS_PCH_NOP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_NOP)
|
||||
#define HAS_PCH_SPLIT(dev_priv) (INTEL_PCH_TYPE(dev_priv) != PCH_NONE)
|
||||
|
||||
#define HAS_GMCH_DISPLAY(dev_priv) ((dev_priv)->info.has_gmch_display)
|
||||
#define HAS_GMCH_DISPLAY(dev_priv) ((dev_priv)->info.display.has_gmch_display)
|
||||
|
||||
#define HAS_LSPCON(dev_priv) (INTEL_GEN(dev_priv) >= 9)
|
||||
|
||||
@@ -2568,6 +2558,8 @@ intel_info(const struct drm_i915_private *dev_priv)
|
||||
#define GT_FREQUENCY_MULTIPLIER 50
|
||||
#define GEN9_FREQ_SCALER 3
|
||||
|
||||
#define HAS_DISPLAY(dev_priv) (INTEL_INFO(dev_priv)->num_pipes > 0)
|
||||
|
||||
#include "i915_trace.h"
|
||||
|
||||
static inline bool intel_vtd_active(void)
|
||||
@@ -3340,6 +3332,9 @@ extern void intel_rps_mark_interactive(struct drm_i915_private *i915,
|
||||
bool interactive);
|
||||
extern bool intel_set_memory_cxsr(struct drm_i915_private *dev_priv,
|
||||
bool enable);
|
||||
void intel_dsc_enable(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void intel_dsc_disable(const struct intel_crtc_state *crtc_state);
|
||||
|
||||
int i915_reg_read_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file);
|
||||
@@ -3720,4 +3715,9 @@ static inline int intel_hws_csb_write_index(struct drm_i915_private *i915)
|
||||
return I915_HWS_CSB_WRITE_INDEX;
|
||||
}
|
||||
|
||||
static inline u32 i915_scratch_offset(const struct drm_i915_private *i915)
|
||||
{
|
||||
return i915_ggtt_offset(i915->gt.scratch);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3308,16 +3308,6 @@ void i915_gem_reset_finish(struct drm_i915_private *dev_priv)
|
||||
}
|
||||
|
||||
static void nop_submit_request(struct i915_request *request)
|
||||
{
|
||||
GEM_TRACE("%s fence %llx:%d -> -EIO\n",
|
||||
request->engine->name,
|
||||
request->fence.context, request->fence.seqno);
|
||||
dma_fence_set_error(&request->fence, -EIO);
|
||||
|
||||
i915_request_submit(request);
|
||||
}
|
||||
|
||||
static void nop_complete_submit_request(struct i915_request *request)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
@@ -3354,57 +3344,33 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
|
||||
* rolling the global seqno forward (since this would complete requests
|
||||
* for which we haven't set the fence error to EIO yet).
|
||||
*/
|
||||
for_each_engine(engine, i915, id) {
|
||||
for_each_engine(engine, i915, id)
|
||||
i915_gem_reset_prepare_engine(engine);
|
||||
|
||||
engine->submit_request = nop_submit_request;
|
||||
engine->schedule = NULL;
|
||||
}
|
||||
i915->caps.scheduler = 0;
|
||||
|
||||
/* Even if the GPU reset fails, it should still stop the engines */
|
||||
if (INTEL_GEN(i915) >= 5)
|
||||
intel_gpu_reset(i915, ALL_ENGINES);
|
||||
|
||||
/*
|
||||
* Make sure no one is running the old callback before we proceed with
|
||||
* cancelling requests and resetting the completion tracking. Otherwise
|
||||
* we might submit a request to the hardware which never completes.
|
||||
*/
|
||||
synchronize_rcu();
|
||||
|
||||
for_each_engine(engine, i915, id) {
|
||||
/* Mark all executing requests as skipped */
|
||||
engine->cancel_requests(engine);
|
||||
|
||||
/*
|
||||
* Only once we've force-cancelled all in-flight requests can we
|
||||
* start to complete all requests.
|
||||
*/
|
||||
engine->submit_request = nop_complete_submit_request;
|
||||
engine->submit_request = nop_submit_request;
|
||||
engine->schedule = NULL;
|
||||
}
|
||||
i915->caps.scheduler = 0;
|
||||
|
||||
/*
|
||||
* Make sure no request can slip through without getting completed by
|
||||
* either this call here to intel_engine_init_global_seqno, or the one
|
||||
* in nop_complete_submit_request.
|
||||
* in nop_submit_request.
|
||||
*/
|
||||
synchronize_rcu();
|
||||
|
||||
/* Mark all executing requests as skipped */
|
||||
for_each_engine(engine, i915, id)
|
||||
engine->cancel_requests(engine);
|
||||
|
||||
for_each_engine(engine, i915, id) {
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* Mark all pending requests as complete so that any concurrent
|
||||
* (lockless) lookup doesn't try and wait upon the request as we
|
||||
* reset it.
|
||||
*/
|
||||
spin_lock_irqsave(&engine->timeline.lock, flags);
|
||||
intel_engine_init_global_seqno(engine,
|
||||
intel_engine_last_submit(engine));
|
||||
spin_unlock_irqrestore(&engine->timeline.lock, flags);
|
||||
|
||||
i915_gem_reset_finish_engine(engine);
|
||||
intel_engine_wakeup(engine);
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -5334,7 +5300,10 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv)
|
||||
I915_WRITE(MI_PREDICATE_RESULT_2, IS_HSW_GT3(dev_priv) ?
|
||||
LOWER_SLICE_ENABLED : LOWER_SLICE_DISABLED);
|
||||
|
||||
intel_gt_workarounds_apply(dev_priv);
|
||||
/* Apply the GT workarounds... */
|
||||
intel_gt_apply_workarounds(dev_priv);
|
||||
/* ...and determine whether they are sticking. */
|
||||
intel_gt_verify_workarounds(dev_priv, "init");
|
||||
|
||||
i915_gem_init_swizzling(dev_priv);
|
||||
|
||||
@@ -5529,6 +5498,44 @@ err_active:
|
||||
goto out_ctx;
|
||||
}
|
||||
|
||||
static int
|
||||
i915_gem_init_scratch(struct drm_i915_private *i915, unsigned int size)
|
||||
{
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct i915_vma *vma;
|
||||
int ret;
|
||||
|
||||
obj = i915_gem_object_create_stolen(i915, size);
|
||||
if (!obj)
|
||||
obj = i915_gem_object_create_internal(i915, size);
|
||||
if (IS_ERR(obj)) {
|
||||
DRM_ERROR("Failed to allocate scratch page\n");
|
||||
return PTR_ERR(obj);
|
||||
}
|
||||
|
||||
vma = i915_vma_instance(obj, &i915->ggtt.vm, NULL);
|
||||
if (IS_ERR(vma)) {
|
||||
ret = PTR_ERR(vma);
|
||||
goto err_unref;
|
||||
}
|
||||
|
||||
ret = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH);
|
||||
if (ret)
|
||||
goto err_unref;
|
||||
|
||||
i915->gt.scratch = vma;
|
||||
return 0;
|
||||
|
||||
err_unref:
|
||||
i915_gem_object_put(obj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void i915_gem_fini_scratch(struct drm_i915_private *i915)
|
||||
{
|
||||
i915_vma_unpin_and_release(&i915->gt.scratch, 0);
|
||||
}
|
||||
|
||||
int i915_gem_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
int ret;
|
||||
@@ -5575,12 +5582,19 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
ret = i915_gem_contexts_init(dev_priv);
|
||||
ret = i915_gem_init_scratch(dev_priv,
|
||||
IS_GEN2(dev_priv) ? SZ_256K : PAGE_SIZE);
|
||||
if (ret) {
|
||||
GEM_BUG_ON(ret == -EIO);
|
||||
goto err_ggtt;
|
||||
}
|
||||
|
||||
ret = i915_gem_contexts_init(dev_priv);
|
||||
if (ret) {
|
||||
GEM_BUG_ON(ret == -EIO);
|
||||
goto err_scratch;
|
||||
}
|
||||
|
||||
ret = intel_engines_init(dev_priv);
|
||||
if (ret) {
|
||||
GEM_BUG_ON(ret == -EIO);
|
||||
@@ -5653,6 +5667,8 @@ err_pm:
|
||||
err_context:
|
||||
if (ret != -EIO)
|
||||
i915_gem_contexts_fini(dev_priv);
|
||||
err_scratch:
|
||||
i915_gem_fini_scratch(dev_priv);
|
||||
err_ggtt:
|
||||
err_unlock:
|
||||
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
|
||||
@@ -5704,8 +5720,11 @@ void i915_gem_fini(struct drm_i915_private *dev_priv)
|
||||
intel_uc_fini(dev_priv);
|
||||
i915_gem_cleanup_engines(dev_priv);
|
||||
i915_gem_contexts_fini(dev_priv);
|
||||
i915_gem_fini_scratch(dev_priv);
|
||||
mutex_unlock(&dev_priv->drm.struct_mutex);
|
||||
|
||||
intel_wa_list_free(&dev_priv->gt_wa_list);
|
||||
|
||||
intel_cleanup_gt_powersave(dev_priv);
|
||||
|
||||
intel_uc_fini_misc(dev_priv);
|
||||
|
||||
@@ -535,16 +535,12 @@ static bool needs_preempt_context(struct drm_i915_private *i915)
|
||||
int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct i915_gem_context *ctx;
|
||||
int ret;
|
||||
|
||||
/* Reassure ourselves we are only called once */
|
||||
GEM_BUG_ON(dev_priv->kernel_context);
|
||||
GEM_BUG_ON(dev_priv->preempt_context);
|
||||
|
||||
ret = intel_ctx_workarounds_init(dev_priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
intel_engine_init_ctx_wa(dev_priv->engine[RCS]);
|
||||
init_contexts(dev_priv);
|
||||
|
||||
/* lowest priority; idle task */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -192,6 +192,8 @@ struct i915_gpu_state {
|
||||
} *active_bo[I915_NUM_ENGINES], *pinned_bo;
|
||||
u32 active_bo_count[I915_NUM_ENGINES], pinned_bo_count;
|
||||
struct i915_address_space *active_vm[I915_NUM_ENGINES];
|
||||
|
||||
struct scatterlist *sgl, *fit;
|
||||
};
|
||||
|
||||
struct i915_gpu_error {
|
||||
@@ -298,29 +300,20 @@ struct i915_gpu_error {
|
||||
|
||||
struct drm_i915_error_state_buf {
|
||||
struct drm_i915_private *i915;
|
||||
unsigned int bytes;
|
||||
unsigned int size;
|
||||
struct scatterlist *sgl, *cur, *end;
|
||||
|
||||
char *buf;
|
||||
size_t bytes;
|
||||
size_t size;
|
||||
loff_t iter;
|
||||
|
||||
int err;
|
||||
u8 *buf;
|
||||
loff_t start;
|
||||
loff_t pos;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
|
||||
|
||||
__printf(2, 3)
|
||||
void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...);
|
||||
int i915_error_state_to_str(struct drm_i915_error_state_buf *estr,
|
||||
const struct i915_gpu_state *gpu);
|
||||
int i915_error_state_buf_init(struct drm_i915_error_state_buf *eb,
|
||||
struct drm_i915_private *i915,
|
||||
size_t count, loff_t pos);
|
||||
|
||||
static inline void
|
||||
i915_error_state_buf_release(struct drm_i915_error_state_buf *eb)
|
||||
{
|
||||
kfree(eb->buf);
|
||||
}
|
||||
|
||||
struct i915_gpu_state *i915_capture_gpu_state(struct drm_i915_private *i915);
|
||||
void i915_capture_error_state(struct drm_i915_private *dev_priv,
|
||||
@@ -334,6 +327,9 @@ i915_gpu_state_get(struct i915_gpu_state *gpu)
|
||||
return gpu;
|
||||
}
|
||||
|
||||
ssize_t i915_gpu_state_copy_to_buffer(struct i915_gpu_state *error,
|
||||
char *buf, loff_t offset, size_t count);
|
||||
|
||||
void __i915_gpu_state_free(struct kref *kref);
|
||||
static inline void i915_gpu_state_put(struct i915_gpu_state *gpu)
|
||||
{
|
||||
|
||||
@@ -79,8 +79,9 @@
|
||||
#define GEN2_FEATURES \
|
||||
GEN(2), \
|
||||
.num_pipes = 1, \
|
||||
.has_overlay = 1, .overlay_needs_physical = 1, \
|
||||
.has_gmch_display = 1, \
|
||||
.display.has_overlay = 1, \
|
||||
.display.overlay_needs_physical = 1, \
|
||||
.display.has_gmch_display = 1, \
|
||||
.hws_needs_physical = 1, \
|
||||
.unfenced_needs_alignment = 1, \
|
||||
.ring_mask = RENDER_RING, \
|
||||
@@ -93,7 +94,8 @@
|
||||
static const struct intel_device_info intel_i830_info = {
|
||||
GEN2_FEATURES,
|
||||
PLATFORM(INTEL_I830),
|
||||
.is_mobile = 1, .cursor_needs_physical = 1,
|
||||
.is_mobile = 1,
|
||||
.display.cursor_needs_physical = 1,
|
||||
.num_pipes = 2, /* legal, last one wins */
|
||||
};
|
||||
|
||||
@@ -107,8 +109,8 @@ static const struct intel_device_info intel_i85x_info = {
|
||||
PLATFORM(INTEL_I85X),
|
||||
.is_mobile = 1,
|
||||
.num_pipes = 2, /* legal, last one wins */
|
||||
.cursor_needs_physical = 1,
|
||||
.has_fbc = 1,
|
||||
.display.cursor_needs_physical = 1,
|
||||
.display.has_fbc = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_i865g_info = {
|
||||
@@ -119,7 +121,7 @@ static const struct intel_device_info intel_i865g_info = {
|
||||
#define GEN3_FEATURES \
|
||||
GEN(3), \
|
||||
.num_pipes = 2, \
|
||||
.has_gmch_display = 1, \
|
||||
.display.has_gmch_display = 1, \
|
||||
.ring_mask = RENDER_RING, \
|
||||
.has_snoop = true, \
|
||||
.has_coherent_ggtt = true, \
|
||||
@@ -131,8 +133,9 @@ static const struct intel_device_info intel_i915g_info = {
|
||||
GEN3_FEATURES,
|
||||
PLATFORM(INTEL_I915G),
|
||||
.has_coherent_ggtt = false,
|
||||
.cursor_needs_physical = 1,
|
||||
.has_overlay = 1, .overlay_needs_physical = 1,
|
||||
.display.cursor_needs_physical = 1,
|
||||
.display.has_overlay = 1,
|
||||
.display.overlay_needs_physical = 1,
|
||||
.hws_needs_physical = 1,
|
||||
.unfenced_needs_alignment = 1,
|
||||
};
|
||||
@@ -141,10 +144,11 @@ static const struct intel_device_info intel_i915gm_info = {
|
||||
GEN3_FEATURES,
|
||||
PLATFORM(INTEL_I915GM),
|
||||
.is_mobile = 1,
|
||||
.cursor_needs_physical = 1,
|
||||
.has_overlay = 1, .overlay_needs_physical = 1,
|
||||
.supports_tv = 1,
|
||||
.has_fbc = 1,
|
||||
.display.cursor_needs_physical = 1,
|
||||
.display.has_overlay = 1,
|
||||
.display.overlay_needs_physical = 1,
|
||||
.display.supports_tv = 1,
|
||||
.display.has_fbc = 1,
|
||||
.hws_needs_physical = 1,
|
||||
.unfenced_needs_alignment = 1,
|
||||
};
|
||||
@@ -152,8 +156,10 @@ static const struct intel_device_info intel_i915gm_info = {
|
||||
static const struct intel_device_info intel_i945g_info = {
|
||||
GEN3_FEATURES,
|
||||
PLATFORM(INTEL_I945G),
|
||||
.has_hotplug = 1, .cursor_needs_physical = 1,
|
||||
.has_overlay = 1, .overlay_needs_physical = 1,
|
||||
.display.has_hotplug = 1,
|
||||
.display.cursor_needs_physical = 1,
|
||||
.display.has_overlay = 1,
|
||||
.display.overlay_needs_physical = 1,
|
||||
.hws_needs_physical = 1,
|
||||
.unfenced_needs_alignment = 1,
|
||||
};
|
||||
@@ -162,10 +168,12 @@ static const struct intel_device_info intel_i945gm_info = {
|
||||
GEN3_FEATURES,
|
||||
PLATFORM(INTEL_I945GM),
|
||||
.is_mobile = 1,
|
||||
.has_hotplug = 1, .cursor_needs_physical = 1,
|
||||
.has_overlay = 1, .overlay_needs_physical = 1,
|
||||
.supports_tv = 1,
|
||||
.has_fbc = 1,
|
||||
.display.has_hotplug = 1,
|
||||
.display.cursor_needs_physical = 1,
|
||||
.display.has_overlay = 1,
|
||||
.display.overlay_needs_physical = 1,
|
||||
.display.supports_tv = 1,
|
||||
.display.has_fbc = 1,
|
||||
.hws_needs_physical = 1,
|
||||
.unfenced_needs_alignment = 1,
|
||||
};
|
||||
@@ -173,23 +181,23 @@ static const struct intel_device_info intel_i945gm_info = {
|
||||
static const struct intel_device_info intel_g33_info = {
|
||||
GEN3_FEATURES,
|
||||
PLATFORM(INTEL_G33),
|
||||
.has_hotplug = 1,
|
||||
.has_overlay = 1,
|
||||
.display.has_hotplug = 1,
|
||||
.display.has_overlay = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_pineview_info = {
|
||||
GEN3_FEATURES,
|
||||
PLATFORM(INTEL_PINEVIEW),
|
||||
.is_mobile = 1,
|
||||
.has_hotplug = 1,
|
||||
.has_overlay = 1,
|
||||
.display.has_hotplug = 1,
|
||||
.display.has_overlay = 1,
|
||||
};
|
||||
|
||||
#define GEN4_FEATURES \
|
||||
GEN(4), \
|
||||
.num_pipes = 2, \
|
||||
.has_hotplug = 1, \
|
||||
.has_gmch_display = 1, \
|
||||
.display.has_hotplug = 1, \
|
||||
.display.has_gmch_display = 1, \
|
||||
.ring_mask = RENDER_RING, \
|
||||
.has_snoop = true, \
|
||||
.has_coherent_ggtt = true, \
|
||||
@@ -200,7 +208,7 @@ static const struct intel_device_info intel_pineview_info = {
|
||||
static const struct intel_device_info intel_i965g_info = {
|
||||
GEN4_FEATURES,
|
||||
PLATFORM(INTEL_I965G),
|
||||
.has_overlay = 1,
|
||||
.display.has_overlay = 1,
|
||||
.hws_needs_physical = 1,
|
||||
.has_snoop = false,
|
||||
};
|
||||
@@ -208,9 +216,10 @@ static const struct intel_device_info intel_i965g_info = {
|
||||
static const struct intel_device_info intel_i965gm_info = {
|
||||
GEN4_FEATURES,
|
||||
PLATFORM(INTEL_I965GM),
|
||||
.is_mobile = 1, .has_fbc = 1,
|
||||
.has_overlay = 1,
|
||||
.supports_tv = 1,
|
||||
.is_mobile = 1,
|
||||
.display.has_fbc = 1,
|
||||
.display.has_overlay = 1,
|
||||
.display.supports_tv = 1,
|
||||
.hws_needs_physical = 1,
|
||||
.has_snoop = false,
|
||||
};
|
||||
@@ -224,15 +233,16 @@ static const struct intel_device_info intel_g45_info = {
|
||||
static const struct intel_device_info intel_gm45_info = {
|
||||
GEN4_FEATURES,
|
||||
PLATFORM(INTEL_GM45),
|
||||
.is_mobile = 1, .has_fbc = 1,
|
||||
.supports_tv = 1,
|
||||
.is_mobile = 1,
|
||||
.display.has_fbc = 1,
|
||||
.display.supports_tv = 1,
|
||||
.ring_mask = RENDER_RING | BSD_RING,
|
||||
};
|
||||
|
||||
#define GEN5_FEATURES \
|
||||
GEN(5), \
|
||||
.num_pipes = 2, \
|
||||
.has_hotplug = 1, \
|
||||
.display.has_hotplug = 1, \
|
||||
.ring_mask = RENDER_RING | BSD_RING, \
|
||||
.has_snoop = true, \
|
||||
.has_coherent_ggtt = true, \
|
||||
@@ -250,14 +260,15 @@ static const struct intel_device_info intel_ironlake_d_info = {
|
||||
static const struct intel_device_info intel_ironlake_m_info = {
|
||||
GEN5_FEATURES,
|
||||
PLATFORM(INTEL_IRONLAKE),
|
||||
.is_mobile = 1, .has_fbc = 1,
|
||||
.is_mobile = 1,
|
||||
.display.has_fbc = 1,
|
||||
};
|
||||
|
||||
#define GEN6_FEATURES \
|
||||
GEN(6), \
|
||||
.num_pipes = 2, \
|
||||
.has_hotplug = 1, \
|
||||
.has_fbc = 1, \
|
||||
.display.has_hotplug = 1, \
|
||||
.display.has_fbc = 1, \
|
||||
.ring_mask = RENDER_RING | BSD_RING | BLT_RING, \
|
||||
.has_coherent_ggtt = true, \
|
||||
.has_llc = 1, \
|
||||
@@ -301,8 +312,8 @@ static const struct intel_device_info intel_sandybridge_m_gt2_info = {
|
||||
#define GEN7_FEATURES \
|
||||
GEN(7), \
|
||||
.num_pipes = 3, \
|
||||
.has_hotplug = 1, \
|
||||
.has_fbc = 1, \
|
||||
.display.has_hotplug = 1, \
|
||||
.display.has_fbc = 1, \
|
||||
.ring_mask = RENDER_RING | BSD_RING | BLT_RING, \
|
||||
.has_coherent_ggtt = true, \
|
||||
.has_llc = 1, \
|
||||
@@ -359,8 +370,8 @@ static const struct intel_device_info intel_valleyview_info = {
|
||||
.num_pipes = 2,
|
||||
.has_runtime_pm = 1,
|
||||
.has_rc6 = 1,
|
||||
.has_gmch_display = 1,
|
||||
.has_hotplug = 1,
|
||||
.display.has_gmch_display = 1,
|
||||
.display.has_hotplug = 1,
|
||||
.ppgtt = INTEL_PPGTT_FULL,
|
||||
.has_snoop = true,
|
||||
.has_coherent_ggtt = false,
|
||||
@@ -374,10 +385,10 @@ static const struct intel_device_info intel_valleyview_info = {
|
||||
#define G75_FEATURES \
|
||||
GEN7_FEATURES, \
|
||||
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, \
|
||||
.has_ddi = 1, \
|
||||
.display.has_ddi = 1, \
|
||||
.has_fpga_dbg = 1, \
|
||||
.has_psr = 1, \
|
||||
.has_dp_mst = 1, \
|
||||
.display.has_psr = 1, \
|
||||
.display.has_dp_mst = 1, \
|
||||
.has_rc6p = 0 /* RC6p removed-by HSW */, \
|
||||
.has_runtime_pm = 1
|
||||
|
||||
@@ -444,14 +455,14 @@ static const struct intel_device_info intel_cherryview_info = {
|
||||
PLATFORM(INTEL_CHERRYVIEW),
|
||||
GEN(8),
|
||||
.num_pipes = 3,
|
||||
.has_hotplug = 1,
|
||||
.display.has_hotplug = 1,
|
||||
.is_lp = 1,
|
||||
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
|
||||
.has_64bit_reloc = 1,
|
||||
.has_runtime_pm = 1,
|
||||
.has_rc6 = 1,
|
||||
.has_logical_ring_contexts = 1,
|
||||
.has_gmch_display = 1,
|
||||
.display.has_gmch_display = 1,
|
||||
.ppgtt = INTEL_PPGTT_FULL,
|
||||
.has_reset_engine = 1,
|
||||
.has_snoop = true,
|
||||
@@ -473,15 +484,15 @@ static const struct intel_device_info intel_cherryview_info = {
|
||||
GEN(9), \
|
||||
GEN9_DEFAULT_PAGE_SIZES, \
|
||||
.has_logical_ring_preemption = 1, \
|
||||
.has_csr = 1, \
|
||||
.display.has_csr = 1, \
|
||||
.has_guc = 1, \
|
||||
.has_ipc = 1, \
|
||||
.display.has_ipc = 1, \
|
||||
.ddb_size = 896
|
||||
|
||||
#define SKL_PLATFORM \
|
||||
GEN9_FEATURES, \
|
||||
/* Display WA #0477 WaDisableIPC: skl */ \
|
||||
.has_ipc = 0, \
|
||||
.display.has_ipc = 0, \
|
||||
PLATFORM(INTEL_SKYLAKE)
|
||||
|
||||
static const struct intel_device_info intel_skylake_gt1_info = {
|
||||
@@ -512,19 +523,19 @@ static const struct intel_device_info intel_skylake_gt4_info = {
|
||||
#define GEN9_LP_FEATURES \
|
||||
GEN(9), \
|
||||
.is_lp = 1, \
|
||||
.has_hotplug = 1, \
|
||||
.display.has_hotplug = 1, \
|
||||
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, \
|
||||
.num_pipes = 3, \
|
||||
.has_64bit_reloc = 1, \
|
||||
.has_ddi = 1, \
|
||||
.display.has_ddi = 1, \
|
||||
.has_fpga_dbg = 1, \
|
||||
.has_fbc = 1, \
|
||||
.has_psr = 1, \
|
||||
.display.has_fbc = 1, \
|
||||
.display.has_psr = 1, \
|
||||
.has_runtime_pm = 1, \
|
||||
.has_pooled_eu = 0, \
|
||||
.has_csr = 1, \
|
||||
.display.has_csr = 1, \
|
||||
.has_rc6 = 1, \
|
||||
.has_dp_mst = 1, \
|
||||
.display.has_dp_mst = 1, \
|
||||
.has_logical_ring_contexts = 1, \
|
||||
.has_logical_ring_preemption = 1, \
|
||||
.has_guc = 1, \
|
||||
@@ -532,7 +543,7 @@ static const struct intel_device_info intel_skylake_gt4_info = {
|
||||
.has_reset_engine = 1, \
|
||||
.has_snoop = true, \
|
||||
.has_coherent_ggtt = false, \
|
||||
.has_ipc = 1, \
|
||||
.display.has_ipc = 1, \
|
||||
GEN9_DEFAULT_PAGE_SIZES, \
|
||||
GEN_DEFAULT_PIPEOFFSETS, \
|
||||
IVB_CURSOR_OFFSETS, \
|
||||
|
||||
@@ -4570,6 +4570,7 @@ enum {
|
||||
* of the infoframe structure specified by CEA-861. */
|
||||
#define VIDEO_DIP_DATA_SIZE 32
|
||||
#define VIDEO_DIP_VSC_DATA_SIZE 36
|
||||
#define VIDEO_DIP_PPS_DATA_SIZE 132
|
||||
#define VIDEO_DIP_CTL _MMIO(0x61170)
|
||||
/* Pre HSW: */
|
||||
#define VIDEO_DIP_ENABLE (1 << 31)
|
||||
@@ -4617,6 +4618,17 @@ enum {
|
||||
#define _PP_STATUS 0x61200
|
||||
#define PP_STATUS(pps_idx) _MMIO_PPS(pps_idx, _PP_STATUS)
|
||||
#define PP_ON (1 << 31)
|
||||
|
||||
#define _PP_CONTROL_1 0xc7204
|
||||
#define _PP_CONTROL_2 0xc7304
|
||||
#define ICP_PP_CONTROL(x) _MMIO(((x) == 1) ? _PP_CONTROL_1 : \
|
||||
_PP_CONTROL_2)
|
||||
#define POWER_CYCLE_DELAY_MASK (0x1f << 4)
|
||||
#define POWER_CYCLE_DELAY_SHIFT 4
|
||||
#define VDD_OVERRIDE_FORCE (1 << 3)
|
||||
#define BACKLIGHT_ENABLE (1 << 2)
|
||||
#define PWR_DOWN_ON_RESET (1 << 1)
|
||||
#define PWR_STATE_TARGET (1 << 0)
|
||||
/*
|
||||
* Indicates that all dependencies of the panel are on:
|
||||
*
|
||||
@@ -7750,6 +7762,7 @@ enum {
|
||||
#define ICP_DDIB_HPD_LONG_DETECT (2 << 4)
|
||||
#define ICP_DDIB_HPD_SHORT_LONG_DETECT (3 << 4)
|
||||
#define ICP_DDIA_HPD_ENABLE (1 << 3)
|
||||
#define ICP_DDIA_HPD_OP_DRIVE_1 (1 << 2)
|
||||
#define ICP_DDIA_HPD_STATUS_MASK (3 << 0)
|
||||
#define ICP_DDIA_HPD_NO_DETECT (0 << 0)
|
||||
#define ICP_DDIA_HPD_SHORT_DETECT (1 << 0)
|
||||
@@ -9197,6 +9210,7 @@ enum skl_power_gate {
|
||||
#define _DP_TP_CTL_B 0x64140
|
||||
#define DP_TP_CTL(port) _MMIO_PORT(port, _DP_TP_CTL_A, _DP_TP_CTL_B)
|
||||
#define DP_TP_CTL_ENABLE (1 << 31)
|
||||
#define DP_TP_CTL_FEC_ENABLE (1 << 30)
|
||||
#define DP_TP_CTL_MODE_SST (0 << 27)
|
||||
#define DP_TP_CTL_MODE_MST (1 << 27)
|
||||
#define DP_TP_CTL_FORCE_ACT (1 << 25)
|
||||
@@ -9215,6 +9229,7 @@ enum skl_power_gate {
|
||||
#define _DP_TP_STATUS_A 0x64044
|
||||
#define _DP_TP_STATUS_B 0x64144
|
||||
#define DP_TP_STATUS(port) _MMIO_PORT(port, _DP_TP_STATUS_A, _DP_TP_STATUS_B)
|
||||
#define DP_TP_STATUS_FEC_ENABLE_LIVE (1 << 28)
|
||||
#define DP_TP_STATUS_IDLE_DONE (1 << 25)
|
||||
#define DP_TP_STATUS_ACT_SENT (1 << 24)
|
||||
#define DP_TP_STATUS_MODE_STATUS_MST (1 << 23)
|
||||
|
||||
@@ -136,6 +136,9 @@ static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno)
|
||||
intel_engine_get_seqno(engine),
|
||||
seqno);
|
||||
|
||||
if (seqno == engine->timeline.seqno)
|
||||
continue;
|
||||
|
||||
kthread_park(engine->breadcrumbs.signaler);
|
||||
|
||||
if (!i915_seqno_passed(seqno, engine->timeline.seqno)) {
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
/*
|
||||
* (C) Copyright 2016 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; version 2
|
||||
* of the License.
|
||||
* (C) Copyright 2016 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* i915_sw_fence.h - library routines for N:M synchronisation points
|
||||
*
|
||||
* Copyright (C) 2016 Intel Corporation
|
||||
*
|
||||
* This file is released under the GPLv2.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _I915_SW_FENCE_H_
|
||||
|
||||
@@ -483,7 +483,7 @@ static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", val);
|
||||
}
|
||||
|
||||
static const struct attribute *gen6_attrs[] = {
|
||||
static const struct attribute * const gen6_attrs[] = {
|
||||
&dev_attr_gt_act_freq_mhz.attr,
|
||||
&dev_attr_gt_cur_freq_mhz.attr,
|
||||
&dev_attr_gt_boost_freq_mhz.attr,
|
||||
@@ -495,7 +495,7 @@ static const struct attribute *gen6_attrs[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct attribute *vlv_attrs[] = {
|
||||
static const struct attribute * const vlv_attrs[] = {
|
||||
&dev_attr_gt_act_freq_mhz.attr,
|
||||
&dev_attr_gt_cur_freq_mhz.attr,
|
||||
&dev_attr_gt_boost_freq_mhz.attr,
|
||||
@@ -516,26 +516,21 @@ static ssize_t error_state_read(struct file *filp, struct kobject *kobj,
|
||||
{
|
||||
|
||||
struct device *kdev = kobj_to_dev(kobj);
|
||||
struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
|
||||
struct drm_i915_error_state_buf error_str;
|
||||
struct drm_i915_private *i915 = kdev_minor_to_i915(kdev);
|
||||
struct i915_gpu_state *gpu;
|
||||
ssize_t ret;
|
||||
|
||||
ret = i915_error_state_buf_init(&error_str, dev_priv, count, off);
|
||||
if (ret)
|
||||
return ret;
|
||||
gpu = i915_first_error_state(i915);
|
||||
if (gpu) {
|
||||
ret = i915_gpu_state_copy_to_buffer(gpu, buf, off, count);
|
||||
i915_gpu_state_put(gpu);
|
||||
} else {
|
||||
const char *str = "No error state collected\n";
|
||||
size_t len = strlen(str);
|
||||
|
||||
gpu = i915_first_error_state(dev_priv);
|
||||
ret = i915_error_state_to_str(&error_str, gpu);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = count < error_str.bytes ? count : error_str.bytes;
|
||||
memcpy(buf, error_str.buf, ret);
|
||||
|
||||
out:
|
||||
i915_gpu_state_put(gpu);
|
||||
i915_error_state_buf_release(&error_str);
|
||||
ret = min_t(size_t, count, len - off);
|
||||
memcpy(buf, str + off, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -44,16 +44,19 @@
|
||||
__stringify(x), (long)(x))
|
||||
|
||||
#if defined(GCC_VERSION) && GCC_VERSION >= 70000
|
||||
#define add_overflows(A, B) \
|
||||
__builtin_add_overflow_p((A), (B), (typeof((A) + (B)))0)
|
||||
#define add_overflows_t(T, A, B) \
|
||||
__builtin_add_overflow_p((A), (B), (T)0)
|
||||
#else
|
||||
#define add_overflows(A, B) ({ \
|
||||
#define add_overflows_t(T, A, B) ({ \
|
||||
typeof(A) a = (A); \
|
||||
typeof(B) b = (B); \
|
||||
a + b < a; \
|
||||
(T)(a + b) < a; \
|
||||
})
|
||||
#endif
|
||||
|
||||
#define add_overflows(A, B) \
|
||||
add_overflows_t(typeof((A) + (B)), (A), (B))
|
||||
|
||||
#define range_overflows(start, size, max) ({ \
|
||||
typeof(start) start__ = (start); \
|
||||
typeof(size) size__ = (size); \
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user