You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'drm-intel-next-2014-02-07' of ssh://git.freedesktop.org/git/drm-intel into drm-next
- Yet more steps towards atomic modeset from Ville. - DP panel power sequencing improvements from Paulo. - irq code cleanups from Ville. - 5.4 GHz dp lane clock support for bdw/hsw from Todd. - Clock readout support for hsw/bdw (aka fastboot) from Jesse. - Make pipe underruns report at ERROR level (Ville). This is to check our improved watermarks code. - Full ppgtt support from Ben for gen7. - More fbc fixes and improvements from Ville all over the place, unfortunately not yet enabled by default on more platforms. - w/a cleanups from Ville. - HiZ stall optimization settings (Chia-I Wu). - Display register mmio offset refactor patch from Antti. - RPS improvements for corner-cases from Jeff McGee. * tag 'drm-intel-next-2014-02-07' of ssh://git.freedesktop.org/git/drm-intel: (166 commits) drm/i915: Update rps interrupt limits drm/i915: Restore rps/rc6 on reset drm/i915: Prevent recursion by retiring requests when the ring is full drm/i915: Generate a hang error code drm/i915: unify FLIP_DONE macro names drm/i915: vlv: s/spin_lock_irqsave/spin_lock/ in irq handler drm/i915: factor out valleyview_pipestat_irq_handler drm/i915: vlv: don't unmask IIR[DISPLAY_PIPE_A/B_VBLANK] interrupt drm/i915: Reorganize display pipe register accesses drm/i915: Treat using a purged buffer as a source of EFAULT drm/i915: Convert EFAULT into a silent SIGBUS drm/i915: release mutex in i915_gem_init()'s error path drm/i915: check for oom when allocating private_default_ctx drm/i915/vlv: WA to fix Voltage not getting dropped to Vmin when Gfx is power gated. drm/i915: Get rid of acthd based guilty batch search drm/i915: Use hangcheck score to find guilty context drm/i915: Drop WaDisablePSDDualDispatchEnable:ivb for IVB GT2 drm/i915: Fix IVB GT2 WaDisableDopClockGating and WaDisablePSDDualDispatchEnable drm/i915: Don't access snooped pages through the GTT (even for error capture) drm/i915: Only print information for filing bug reports once ... Conflicts: drivers/gpu/drm/i915/intel_dp.c
This commit is contained in:
@@ -14,6 +14,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
|
||||
i915_gem_gtt.o \
|
||||
i915_gem_stolen.o \
|
||||
i915_gem_tiling.o \
|
||||
i915_params.o \
|
||||
i915_sysfs.o \
|
||||
i915_trace_points.o \
|
||||
i915_ums.o \
|
||||
|
||||
@@ -98,7 +98,7 @@ static const char *get_pin_flag(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
if (obj->user_pin_count > 0)
|
||||
return "P";
|
||||
else if (obj->pin_count > 0)
|
||||
else if (i915_gem_obj_is_pinned(obj))
|
||||
return "p";
|
||||
else
|
||||
return " ";
|
||||
@@ -123,6 +123,8 @@ static void
|
||||
describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
|
||||
{
|
||||
struct i915_vma *vma;
|
||||
int pin_count = 0;
|
||||
|
||||
seq_printf(m, "%pK: %s%s%s %8zdKiB %02x %02x %u %u %u%s%s%s",
|
||||
&obj->base,
|
||||
get_pin_flag(obj),
|
||||
@@ -139,8 +141,10 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
|
||||
obj->madv == I915_MADV_DONTNEED ? " purgeable" : "");
|
||||
if (obj->base.name)
|
||||
seq_printf(m, " (name: %d)", obj->base.name);
|
||||
if (obj->pin_count)
|
||||
seq_printf(m, " (pinned x %d)", obj->pin_count);
|
||||
list_for_each_entry(vma, &obj->vma_list, vma_link)
|
||||
if (vma->pin_count > 0)
|
||||
pin_count++;
|
||||
seq_printf(m, " (pinned x %d)", pin_count);
|
||||
if (obj->pin_display)
|
||||
seq_printf(m, " (display)");
|
||||
if (obj->fence_reg != I915_FENCE_REG_NONE)
|
||||
@@ -447,7 +451,7 @@ static int i915_gem_gtt_info(struct seq_file *m, void *data)
|
||||
|
||||
total_obj_size = total_gtt_size = count = 0;
|
||||
list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
|
||||
if (list == PINNED_LIST && obj->pin_count == 0)
|
||||
if (list == PINNED_LIST && !i915_gem_obj_is_pinned(obj))
|
||||
continue;
|
||||
|
||||
seq_puts(m, " ");
|
||||
@@ -712,8 +716,6 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
|
||||
seq_printf(m, "Graphics Interrupt mask: %08x\n",
|
||||
I915_READ(GTIMR));
|
||||
}
|
||||
seq_printf(m, "Interrupts received: %d\n",
|
||||
atomic_read(&dev_priv->irq_received));
|
||||
for_each_ring(ring, dev_priv, i) {
|
||||
if (INTEL_INFO(dev)->gen >= 6) {
|
||||
seq_printf(m,
|
||||
@@ -1733,6 +1735,17 @@ static int i915_swizzle_info(struct seq_file *m, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int per_file_ctx(int id, void *ptr, void *data)
|
||||
{
|
||||
struct i915_hw_context *ctx = ptr;
|
||||
struct seq_file *m = data;
|
||||
struct i915_hw_ppgtt *ppgtt = ctx_to_ppgtt(ctx);
|
||||
|
||||
ppgtt->debug_dump(ppgtt, m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
@@ -1762,6 +1775,7 @@ static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_ring_buffer *ring;
|
||||
struct drm_file *file;
|
||||
int i;
|
||||
|
||||
if (INTEL_INFO(dev)->gen == 6)
|
||||
@@ -1780,6 +1794,20 @@ static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev)
|
||||
|
||||
seq_puts(m, "aliasing PPGTT:\n");
|
||||
seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset);
|
||||
|
||||
ppgtt->debug_dump(ppgtt, m);
|
||||
} else
|
||||
return;
|
||||
|
||||
list_for_each_entry_reverse(file, &dev->filelist, lhead) {
|
||||
struct drm_i915_file_private *file_priv = file->driver_priv;
|
||||
struct i915_hw_ppgtt *pvt_ppgtt;
|
||||
|
||||
pvt_ppgtt = ctx_to_ppgtt(file_priv->private_default_ctx);
|
||||
seq_printf(m, "proc: %s\n",
|
||||
get_pid_task(file->pid, PIDTYPE_PID)->comm);
|
||||
seq_puts(m, " default context:\n");
|
||||
idr_for_each(&file_priv->context_idr, per_file_ctx, m);
|
||||
}
|
||||
seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK));
|
||||
}
|
||||
@@ -1892,6 +1920,44 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i915_sink_crc(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_info_node *node = m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct intel_encoder *encoder;
|
||||
struct intel_connector *connector;
|
||||
struct intel_dp *intel_dp = NULL;
|
||||
int ret;
|
||||
u8 crc[6];
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list,
|
||||
base.head) {
|
||||
|
||||
if (connector->base.dpms != DRM_MODE_DPMS_ON)
|
||||
continue;
|
||||
|
||||
encoder = to_intel_encoder(connector->base.encoder);
|
||||
if (encoder->type != INTEL_OUTPUT_EDP)
|
||||
continue;
|
||||
|
||||
intel_dp = enc_to_intel_dp(&encoder->base);
|
||||
|
||||
ret = intel_dp_sink_crc(intel_dp, crc);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
seq_printf(m, "%02x%02x%02x%02x%02x%02x\n",
|
||||
crc[0], crc[1], crc[2],
|
||||
crc[3], crc[4], crc[5]);
|
||||
goto out;
|
||||
}
|
||||
ret = -ENODEV;
|
||||
out:
|
||||
drm_modeset_unlock_all(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int i915_energy_uJ(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_info_node *node = m->private;
|
||||
@@ -2756,6 +2822,174 @@ static const struct file_operations i915_display_crc_ctl_fops = {
|
||||
.write = display_crc_ctl_write
|
||||
};
|
||||
|
||||
static void wm_latency_show(struct seq_file *m, const uint16_t wm[5])
|
||||
{
|
||||
struct drm_device *dev = m->private;
|
||||
int num_levels = IS_HASWELL(dev) || IS_BROADWELL(dev) ? 5 : 4;
|
||||
int level;
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
|
||||
for (level = 0; level < num_levels; level++) {
|
||||
unsigned int latency = wm[level];
|
||||
|
||||
/* WM1+ latency values in 0.5us units */
|
||||
if (level > 0)
|
||||
latency *= 5;
|
||||
|
||||
seq_printf(m, "WM%d %u (%u.%u usec)\n",
|
||||
level, wm[level],
|
||||
latency / 10, latency % 10);
|
||||
}
|
||||
|
||||
drm_modeset_unlock_all(dev);
|
||||
}
|
||||
|
||||
static int pri_wm_latency_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_device *dev = m->private;
|
||||
|
||||
wm_latency_show(m, to_i915(dev)->wm.pri_latency);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spr_wm_latency_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_device *dev = m->private;
|
||||
|
||||
wm_latency_show(m, to_i915(dev)->wm.spr_latency);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cur_wm_latency_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_device *dev = m->private;
|
||||
|
||||
wm_latency_show(m, to_i915(dev)->wm.cur_latency);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pri_wm_latency_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct drm_device *dev = inode->i_private;
|
||||
|
||||
if (!HAS_PCH_SPLIT(dev))
|
||||
return -ENODEV;
|
||||
|
||||
return single_open(file, pri_wm_latency_show, dev);
|
||||
}
|
||||
|
||||
static int spr_wm_latency_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct drm_device *dev = inode->i_private;
|
||||
|
||||
if (!HAS_PCH_SPLIT(dev))
|
||||
return -ENODEV;
|
||||
|
||||
return single_open(file, spr_wm_latency_show, dev);
|
||||
}
|
||||
|
||||
static int cur_wm_latency_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct drm_device *dev = inode->i_private;
|
||||
|
||||
if (!HAS_PCH_SPLIT(dev))
|
||||
return -ENODEV;
|
||||
|
||||
return single_open(file, cur_wm_latency_show, dev);
|
||||
}
|
||||
|
||||
static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
|
||||
size_t len, loff_t *offp, uint16_t wm[5])
|
||||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct drm_device *dev = m->private;
|
||||
uint16_t new[5] = { 0 };
|
||||
int num_levels = IS_HASWELL(dev) || IS_BROADWELL(dev) ? 5 : 4;
|
||||
int level;
|
||||
int ret;
|
||||
char tmp[32];
|
||||
|
||||
if (len >= sizeof(tmp))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(tmp, ubuf, len))
|
||||
return -EFAULT;
|
||||
|
||||
tmp[len] = '\0';
|
||||
|
||||
ret = sscanf(tmp, "%hu %hu %hu %hu %hu", &new[0], &new[1], &new[2], &new[3], &new[4]);
|
||||
if (ret != num_levels)
|
||||
return -EINVAL;
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
|
||||
for (level = 0; level < num_levels; level++)
|
||||
wm[level] = new[level];
|
||||
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t pri_wm_latency_write(struct file *file, const char __user *ubuf,
|
||||
size_t len, loff_t *offp)
|
||||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct drm_device *dev = m->private;
|
||||
|
||||
return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.pri_latency);
|
||||
}
|
||||
|
||||
static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf,
|
||||
size_t len, loff_t *offp)
|
||||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct drm_device *dev = m->private;
|
||||
|
||||
return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.spr_latency);
|
||||
}
|
||||
|
||||
static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
|
||||
size_t len, loff_t *offp)
|
||||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct drm_device *dev = m->private;
|
||||
|
||||
return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.cur_latency);
|
||||
}
|
||||
|
||||
static const struct file_operations i915_pri_wm_latency_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = pri_wm_latency_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = pri_wm_latency_write
|
||||
};
|
||||
|
||||
static const struct file_operations i915_spr_wm_latency_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = spr_wm_latency_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = spr_wm_latency_write
|
||||
};
|
||||
|
||||
static const struct file_operations i915_cur_wm_latency_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = cur_wm_latency_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = cur_wm_latency_write
|
||||
};
|
||||
|
||||
static int
|
||||
i915_wedged_get(void *data, u64 *val)
|
||||
{
|
||||
@@ -2929,7 +3163,7 @@ i915_drop_caches_set(void *data, u64 val)
|
||||
list_for_each_entry(vm, &dev_priv->vm_list, global_link) {
|
||||
list_for_each_entry_safe(vma, x, &vm->inactive_list,
|
||||
mm_list) {
|
||||
if (vma->obj->pin_count)
|
||||
if (vma->pin_count)
|
||||
continue;
|
||||
|
||||
ret = i915_vma_unbind(vma);
|
||||
@@ -2989,6 +3223,7 @@ i915_max_freq_set(void *data, u64 val)
|
||||
{
|
||||
struct drm_device *dev = data;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 rp_state_cap, hw_max, hw_min;
|
||||
int ret;
|
||||
|
||||
if (!(IS_GEN6(dev) || IS_GEN7(dev)))
|
||||
@@ -3007,14 +3242,29 @@ i915_max_freq_set(void *data, u64 val)
|
||||
*/
|
||||
if (IS_VALLEYVIEW(dev)) {
|
||||
val = vlv_freq_opcode(dev_priv, val);
|
||||
dev_priv->rps.max_delay = val;
|
||||
valleyview_set_rps(dev, val);
|
||||
|
||||
hw_max = valleyview_rps_max_freq(dev_priv);
|
||||
hw_min = valleyview_rps_min_freq(dev_priv);
|
||||
} else {
|
||||
do_div(val, GT_FREQUENCY_MULTIPLIER);
|
||||
dev_priv->rps.max_delay = val;
|
||||
gen6_set_rps(dev, val);
|
||||
|
||||
rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
|
||||
hw_max = dev_priv->rps.hw_max;
|
||||
hw_min = (rp_state_cap >> 16) & 0xff;
|
||||
}
|
||||
|
||||
if (val < hw_min || val > hw_max || val < dev_priv->rps.min_delay) {
|
||||
mutex_unlock(&dev_priv->rps.hw_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_priv->rps.max_delay = val;
|
||||
|
||||
if (IS_VALLEYVIEW(dev))
|
||||
valleyview_set_rps(dev, val);
|
||||
else
|
||||
gen6_set_rps(dev, val);
|
||||
|
||||
mutex_unlock(&dev_priv->rps.hw_lock);
|
||||
|
||||
return 0;
|
||||
@@ -3054,6 +3304,7 @@ i915_min_freq_set(void *data, u64 val)
|
||||
{
|
||||
struct drm_device *dev = data;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 rp_state_cap, hw_max, hw_min;
|
||||
int ret;
|
||||
|
||||
if (!(IS_GEN6(dev) || IS_GEN7(dev)))
|
||||
@@ -3072,13 +3323,29 @@ i915_min_freq_set(void *data, u64 val)
|
||||
*/
|
||||
if (IS_VALLEYVIEW(dev)) {
|
||||
val = vlv_freq_opcode(dev_priv, val);
|
||||
dev_priv->rps.min_delay = val;
|
||||
valleyview_set_rps(dev, val);
|
||||
|
||||
hw_max = valleyview_rps_max_freq(dev_priv);
|
||||
hw_min = valleyview_rps_min_freq(dev_priv);
|
||||
} else {
|
||||
do_div(val, GT_FREQUENCY_MULTIPLIER);
|
||||
dev_priv->rps.min_delay = val;
|
||||
gen6_set_rps(dev, val);
|
||||
|
||||
rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
|
||||
hw_max = dev_priv->rps.hw_max;
|
||||
hw_min = (rp_state_cap >> 16) & 0xff;
|
||||
}
|
||||
|
||||
if (val < hw_min || val > hw_max || val > dev_priv->rps.max_delay) {
|
||||
mutex_unlock(&dev_priv->rps.hw_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_priv->rps.min_delay = val;
|
||||
|
||||
if (IS_VALLEYVIEW(dev))
|
||||
valleyview_set_rps(dev, val);
|
||||
else
|
||||
gen6_set_rps(dev, val);
|
||||
|
||||
mutex_unlock(&dev_priv->rps.hw_lock);
|
||||
|
||||
return 0;
|
||||
@@ -3248,6 +3515,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
|
||||
{"i915_dpio", i915_dpio_info, 0},
|
||||
{"i915_llc", i915_llc, 0},
|
||||
{"i915_edp_psr_status", i915_edp_psr_status, 0},
|
||||
{"i915_sink_crc_eDP1", i915_sink_crc, 0},
|
||||
{"i915_energy_uJ", i915_energy_uJ, 0},
|
||||
{"i915_pc8_status", i915_pc8_status, 0},
|
||||
{"i915_power_domain_info", i915_power_domain_info, 0},
|
||||
@@ -3269,6 +3537,9 @@ static const struct i915_debugfs_files {
|
||||
{"i915_error_state", &i915_error_state_fops},
|
||||
{"i915_next_seqno", &i915_next_seqno_fops},
|
||||
{"i915_display_crc_ctl", &i915_display_crc_ctl_fops},
|
||||
{"i915_pri_wm_latency", &i915_pri_wm_latency_fops},
|
||||
{"i915_spr_wm_latency", &i915_spr_wm_latency_fops},
|
||||
{"i915_cur_wm_latency", &i915_cur_wm_latency_fops},
|
||||
};
|
||||
|
||||
void intel_display_crc_init(struct drm_device *dev)
|
||||
|
||||
@@ -990,7 +990,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
|
||||
value = HAS_WT(dev);
|
||||
break;
|
||||
case I915_PARAM_HAS_ALIASING_PPGTT:
|
||||
value = dev_priv->mm.aliasing_ppgtt ? 1 : 0;
|
||||
value = dev_priv->mm.aliasing_ppgtt || USES_FULL_PPGTT(dev);
|
||||
break;
|
||||
case I915_PARAM_HAS_WAIT_TIMEOUT:
|
||||
value = 1;
|
||||
@@ -1374,7 +1374,7 @@ cleanup_gem:
|
||||
i915_gem_cleanup_ringbuffer(dev);
|
||||
i915_gem_context_fini(dev);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
i915_gem_cleanup_aliasing_ppgtt(dev);
|
||||
WARN_ON(dev_priv->mm.aliasing_ppgtt);
|
||||
drm_mm_takedown(&dev_priv->gtt.base.mm);
|
||||
cleanup_power:
|
||||
intel_display_power_put(dev, POWER_DOMAIN_VGA);
|
||||
@@ -1776,8 +1776,8 @@ int i915_driver_unload(struct drm_device *dev)
|
||||
i915_gem_free_all_phys_object(dev);
|
||||
i915_gem_cleanup_ringbuffer(dev);
|
||||
i915_gem_context_fini(dev);
|
||||
WARN_ON(dev_priv->mm.aliasing_ppgtt);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
i915_gem_cleanup_aliasing_ppgtt(dev);
|
||||
i915_gem_cleanup_stolen(dev);
|
||||
|
||||
if (!I915_NEED_GFX_HWS(dev))
|
||||
|
||||
+57
-125
@@ -38,134 +38,30 @@
|
||||
#include <linux/module.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
|
||||
static int i915_modeset __read_mostly = -1;
|
||||
module_param_named(modeset, i915_modeset, int, 0400);
|
||||
MODULE_PARM_DESC(modeset,
|
||||
"Use kernel modesetting [KMS] (0=DRM_I915_KMS from .config, "
|
||||
"1=on, -1=force vga console preference [default])");
|
||||
|
||||
unsigned int i915_fbpercrtc __always_unused = 0;
|
||||
module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
|
||||
|
||||
int i915_panel_ignore_lid __read_mostly = 1;
|
||||
module_param_named(panel_ignore_lid, i915_panel_ignore_lid, int, 0600);
|
||||
MODULE_PARM_DESC(panel_ignore_lid,
|
||||
"Override lid status (0=autodetect, 1=autodetect disabled [default], "
|
||||
"-1=force lid closed, -2=force lid open)");
|
||||
|
||||
unsigned int i915_powersave __read_mostly = 1;
|
||||
module_param_named(powersave, i915_powersave, int, 0600);
|
||||
MODULE_PARM_DESC(powersave,
|
||||
"Enable powersavings, fbc, downclocking, etc. (default: true)");
|
||||
|
||||
int i915_semaphores __read_mostly = -1;
|
||||
module_param_named(semaphores, i915_semaphores, int, 0400);
|
||||
MODULE_PARM_DESC(semaphores,
|
||||
"Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))");
|
||||
|
||||
int i915_enable_rc6 __read_mostly = -1;
|
||||
module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0400);
|
||||
MODULE_PARM_DESC(i915_enable_rc6,
|
||||
"Enable power-saving render C-state 6. "
|
||||
"Different stages can be selected via bitmask values "
|
||||
"(0 = disable; 1 = enable rc6; 2 = enable deep rc6; 4 = enable deepest rc6). "
|
||||
"For example, 3 would enable rc6 and deep rc6, and 7 would enable everything. "
|
||||
"default: -1 (use per-chip default)");
|
||||
|
||||
int i915_enable_fbc __read_mostly = -1;
|
||||
module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600);
|
||||
MODULE_PARM_DESC(i915_enable_fbc,
|
||||
"Enable frame buffer compression for power savings "
|
||||
"(default: -1 (use per-chip default))");
|
||||
|
||||
unsigned int i915_lvds_downclock __read_mostly = 0;
|
||||
module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400);
|
||||
MODULE_PARM_DESC(lvds_downclock,
|
||||
"Use panel (LVDS/eDP) downclocking for power savings "
|
||||
"(default: false)");
|
||||
|
||||
int i915_lvds_channel_mode __read_mostly;
|
||||
module_param_named(lvds_channel_mode, i915_lvds_channel_mode, int, 0600);
|
||||
MODULE_PARM_DESC(lvds_channel_mode,
|
||||
"Specify LVDS channel mode "
|
||||
"(0=probe BIOS [default], 1=single-channel, 2=dual-channel)");
|
||||
|
||||
int i915_panel_use_ssc __read_mostly = -1;
|
||||
module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600);
|
||||
MODULE_PARM_DESC(lvds_use_ssc,
|
||||
"Use Spread Spectrum Clock with panels [LVDS/eDP] "
|
||||
"(default: auto from VBT)");
|
||||
|
||||
int i915_vbt_sdvo_panel_type __read_mostly = -1;
|
||||
module_param_named(vbt_sdvo_panel_type, i915_vbt_sdvo_panel_type, int, 0600);
|
||||
MODULE_PARM_DESC(vbt_sdvo_panel_type,
|
||||
"Override/Ignore selection of SDVO panel mode in the VBT "
|
||||
"(-2=ignore, -1=auto [default], index in VBT BIOS table)");
|
||||
|
||||
static bool i915_try_reset __read_mostly = true;
|
||||
module_param_named(reset, i915_try_reset, bool, 0600);
|
||||
MODULE_PARM_DESC(reset, "Attempt GPU resets (default: true)");
|
||||
|
||||
bool i915_enable_hangcheck __read_mostly = true;
|
||||
module_param_named(enable_hangcheck, i915_enable_hangcheck, bool, 0644);
|
||||
MODULE_PARM_DESC(enable_hangcheck,
|
||||
"Periodically check GPU activity for detecting hangs. "
|
||||
"WARNING: Disabling this can cause system wide hangs. "
|
||||
"(default: true)");
|
||||
|
||||
int i915_enable_ppgtt __read_mostly = -1;
|
||||
module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, int, 0400);
|
||||
MODULE_PARM_DESC(i915_enable_ppgtt,
|
||||
"Enable PPGTT (default: true)");
|
||||
|
||||
int i915_enable_psr __read_mostly = 0;
|
||||
module_param_named(enable_psr, i915_enable_psr, int, 0600);
|
||||
MODULE_PARM_DESC(enable_psr, "Enable PSR (default: false)");
|
||||
|
||||
unsigned int i915_preliminary_hw_support __read_mostly = IS_ENABLED(CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT);
|
||||
module_param_named(preliminary_hw_support, i915_preliminary_hw_support, int, 0600);
|
||||
MODULE_PARM_DESC(preliminary_hw_support,
|
||||
"Enable preliminary hardware support.");
|
||||
|
||||
int i915_disable_power_well __read_mostly = 1;
|
||||
module_param_named(disable_power_well, i915_disable_power_well, int, 0600);
|
||||
MODULE_PARM_DESC(disable_power_well,
|
||||
"Disable the power well when possible (default: true)");
|
||||
|
||||
int i915_enable_ips __read_mostly = 1;
|
||||
module_param_named(enable_ips, i915_enable_ips, int, 0600);
|
||||
MODULE_PARM_DESC(enable_ips, "Enable IPS (default: true)");
|
||||
|
||||
bool i915_fastboot __read_mostly = 0;
|
||||
module_param_named(fastboot, i915_fastboot, bool, 0600);
|
||||
MODULE_PARM_DESC(fastboot, "Try to skip unnecessary mode sets at boot time "
|
||||
"(default: false)");
|
||||
|
||||
int i915_enable_pc8 __read_mostly = 1;
|
||||
module_param_named(enable_pc8, i915_enable_pc8, int, 0600);
|
||||
MODULE_PARM_DESC(enable_pc8, "Enable support for low power package C states (PC8+) (default: true)");
|
||||
|
||||
int i915_pc8_timeout __read_mostly = 5000;
|
||||
module_param_named(pc8_timeout, i915_pc8_timeout, int, 0600);
|
||||
MODULE_PARM_DESC(pc8_timeout, "Number of msecs of idleness required to enter PC8+ (default: 5000)");
|
||||
|
||||
bool i915_prefault_disable __read_mostly;
|
||||
module_param_named(prefault_disable, i915_prefault_disable, bool, 0600);
|
||||
MODULE_PARM_DESC(prefault_disable,
|
||||
"Disable page prefaulting for pread/pwrite/reloc (default:false). For developers only.");
|
||||
|
||||
static struct drm_driver driver;
|
||||
|
||||
#define GEN_DEFAULT_PIPEOFFSETS \
|
||||
.pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \
|
||||
PIPE_C_OFFSET, PIPE_EDP_OFFSET }, \
|
||||
.trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \
|
||||
TRANSCODER_C_OFFSET, TRANSCODER_EDP_OFFSET }, \
|
||||
.dpll_offsets = { DPLL_A_OFFSET, DPLL_B_OFFSET }, \
|
||||
.dpll_md_offsets = { DPLL_A_MD_OFFSET, DPLL_B_MD_OFFSET }, \
|
||||
.palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET }
|
||||
|
||||
|
||||
static const struct intel_device_info intel_i830_info = {
|
||||
.gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, .num_pipes = 2,
|
||||
.has_overlay = 1, .overlay_needs_physical = 1,
|
||||
.ring_mask = RENDER_RING,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_845g_info = {
|
||||
.gen = 2, .num_pipes = 1,
|
||||
.has_overlay = 1, .overlay_needs_physical = 1,
|
||||
.ring_mask = RENDER_RING,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_i85x_info = {
|
||||
@@ -174,18 +70,21 @@ static const struct intel_device_info intel_i85x_info = {
|
||||
.has_overlay = 1, .overlay_needs_physical = 1,
|
||||
.has_fbc = 1,
|
||||
.ring_mask = RENDER_RING,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_i865g_info = {
|
||||
.gen = 2, .num_pipes = 1,
|
||||
.has_overlay = 1, .overlay_needs_physical = 1,
|
||||
.ring_mask = RENDER_RING,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_i915g_info = {
|
||||
.gen = 3, .is_i915g = 1, .cursor_needs_physical = 1, .num_pipes = 2,
|
||||
.has_overlay = 1, .overlay_needs_physical = 1,
|
||||
.ring_mask = RENDER_RING,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
static const struct intel_device_info intel_i915gm_info = {
|
||||
.gen = 3, .is_mobile = 1, .num_pipes = 2,
|
||||
@@ -194,11 +93,13 @@ static const struct intel_device_info intel_i915gm_info = {
|
||||
.supports_tv = 1,
|
||||
.has_fbc = 1,
|
||||
.ring_mask = RENDER_RING,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
static const struct intel_device_info intel_i945g_info = {
|
||||
.gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1, .num_pipes = 2,
|
||||
.has_overlay = 1, .overlay_needs_physical = 1,
|
||||
.ring_mask = RENDER_RING,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
static const struct intel_device_info intel_i945gm_info = {
|
||||
.gen = 3, .is_i945gm = 1, .is_mobile = 1, .num_pipes = 2,
|
||||
@@ -207,6 +108,7 @@ static const struct intel_device_info intel_i945gm_info = {
|
||||
.supports_tv = 1,
|
||||
.has_fbc = 1,
|
||||
.ring_mask = RENDER_RING,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_i965g_info = {
|
||||
@@ -214,6 +116,7 @@ static const struct intel_device_info intel_i965g_info = {
|
||||
.has_hotplug = 1,
|
||||
.has_overlay = 1,
|
||||
.ring_mask = RENDER_RING,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_i965gm_info = {
|
||||
@@ -222,6 +125,7 @@ static const struct intel_device_info intel_i965gm_info = {
|
||||
.has_overlay = 1,
|
||||
.supports_tv = 1,
|
||||
.ring_mask = RENDER_RING,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_g33_info = {
|
||||
@@ -229,12 +133,14 @@ static const struct intel_device_info intel_g33_info = {
|
||||
.need_gfx_hws = 1, .has_hotplug = 1,
|
||||
.has_overlay = 1,
|
||||
.ring_mask = RENDER_RING,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_g45_info = {
|
||||
.gen = 4, .is_g4x = 1, .need_gfx_hws = 1, .num_pipes = 2,
|
||||
.has_pipe_cxsr = 1, .has_hotplug = 1,
|
||||
.ring_mask = RENDER_RING | BSD_RING,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_gm45_info = {
|
||||
@@ -243,18 +149,21 @@ static const struct intel_device_info intel_gm45_info = {
|
||||
.has_pipe_cxsr = 1, .has_hotplug = 1,
|
||||
.supports_tv = 1,
|
||||
.ring_mask = RENDER_RING | BSD_RING,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_pineview_info = {
|
||||
.gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .num_pipes = 2,
|
||||
.need_gfx_hws = 1, .has_hotplug = 1,
|
||||
.has_overlay = 1,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_ironlake_d_info = {
|
||||
.gen = 5, .num_pipes = 2,
|
||||
.need_gfx_hws = 1, .has_hotplug = 1,
|
||||
.ring_mask = RENDER_RING | BSD_RING,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_ironlake_m_info = {
|
||||
@@ -262,6 +171,7 @@ static const struct intel_device_info intel_ironlake_m_info = {
|
||||
.need_gfx_hws = 1, .has_hotplug = 1,
|
||||
.has_fbc = 1,
|
||||
.ring_mask = RENDER_RING | BSD_RING,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_sandybridge_d_info = {
|
||||
@@ -270,6 +180,7 @@ static const struct intel_device_info intel_sandybridge_d_info = {
|
||||
.has_fbc = 1,
|
||||
.ring_mask = RENDER_RING | BSD_RING | BLT_RING,
|
||||
.has_llc = 1,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_sandybridge_m_info = {
|
||||
@@ -278,6 +189,7 @@ static const struct intel_device_info intel_sandybridge_m_info = {
|
||||
.has_fbc = 1,
|
||||
.ring_mask = RENDER_RING | BSD_RING | BLT_RING,
|
||||
.has_llc = 1,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
#define GEN7_FEATURES \
|
||||
@@ -290,18 +202,21 @@ static const struct intel_device_info intel_sandybridge_m_info = {
|
||||
static const struct intel_device_info intel_ivybridge_d_info = {
|
||||
GEN7_FEATURES,
|
||||
.is_ivybridge = 1,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_ivybridge_m_info = {
|
||||
GEN7_FEATURES,
|
||||
.is_ivybridge = 1,
|
||||
.is_mobile = 1,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_ivybridge_q_info = {
|
||||
GEN7_FEATURES,
|
||||
.is_ivybridge = 1,
|
||||
.num_pipes = 0, /* legal, last one wins */
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_valleyview_m_info = {
|
||||
@@ -312,6 +227,7 @@ static const struct intel_device_info intel_valleyview_m_info = {
|
||||
.display_mmio_offset = VLV_DISPLAY_BASE,
|
||||
.has_fbc = 0, /* legal, last one wins */
|
||||
.has_llc = 0, /* legal, last one wins */
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_valleyview_d_info = {
|
||||
@@ -321,6 +237,7 @@ static const struct intel_device_info intel_valleyview_d_info = {
|
||||
.display_mmio_offset = VLV_DISPLAY_BASE,
|
||||
.has_fbc = 0, /* legal, last one wins */
|
||||
.has_llc = 0, /* legal, last one wins */
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_haswell_d_info = {
|
||||
@@ -329,6 +246,7 @@ static const struct intel_device_info intel_haswell_d_info = {
|
||||
.has_ddi = 1,
|
||||
.has_fpga_dbg = 1,
|
||||
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_haswell_m_info = {
|
||||
@@ -338,6 +256,7 @@ static const struct intel_device_info intel_haswell_m_info = {
|
||||
.has_ddi = 1,
|
||||
.has_fpga_dbg = 1,
|
||||
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_broadwell_d_info = {
|
||||
@@ -346,6 +265,7 @@ static const struct intel_device_info intel_broadwell_d_info = {
|
||||
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
|
||||
.has_llc = 1,
|
||||
.has_ddi = 1,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_broadwell_m_info = {
|
||||
@@ -354,6 +274,7 @@ static const struct intel_device_info intel_broadwell_m_info = {
|
||||
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
|
||||
.has_llc = 1,
|
||||
.has_ddi = 1,
|
||||
GEN_DEFAULT_PIPEOFFSETS,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -482,12 +403,12 @@ bool i915_semaphore_is_enabled(struct drm_device *dev)
|
||||
|
||||
/* Until we get further testing... */
|
||||
if (IS_GEN8(dev)) {
|
||||
WARN_ON(!i915_preliminary_hw_support);
|
||||
WARN_ON(!i915.preliminary_hw_support);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (i915_semaphores >= 0)
|
||||
return i915_semaphores;
|
||||
if (i915.semaphores >= 0)
|
||||
return i915.semaphores;
|
||||
|
||||
#ifdef CONFIG_INTEL_IOMMU
|
||||
/* Enable semaphores on SNB when IO remapping is off */
|
||||
@@ -643,6 +564,7 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings)
|
||||
/* KMS EnterVT equivalent */
|
||||
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
||||
intel_init_pch_refclk(dev);
|
||||
drm_mode_config_reset(dev);
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
@@ -655,7 +577,6 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings)
|
||||
intel_modeset_init_hw(dev);
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
drm_mode_config_reset(dev);
|
||||
intel_modeset_setup_hw_state(dev, true);
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
@@ -752,7 +673,7 @@ int i915_reset(struct drm_device *dev)
|
||||
bool simulated;
|
||||
int ret;
|
||||
|
||||
if (!i915_try_reset)
|
||||
if (!i915.reset)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
@@ -807,6 +728,17 @@ int i915_reset(struct drm_device *dev)
|
||||
|
||||
drm_irq_uninstall(dev);
|
||||
drm_irq_install(dev);
|
||||
|
||||
/* rps/rc6 re-init is necessary to restore state lost after the
|
||||
* reset and the re-install of drm irq. Skip for ironlake per
|
||||
* previous concerns that it doesn't respond well to some forms
|
||||
* of re-init after reset. */
|
||||
if (INTEL_INFO(dev)->gen > 5) {
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
intel_enable_gt_powersave(dev);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
}
|
||||
|
||||
intel_hpd_init(dev);
|
||||
} else {
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
@@ -820,7 +752,7 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
struct intel_device_info *intel_info =
|
||||
(struct intel_device_info *) ent->driver_data;
|
||||
|
||||
if (IS_PRELIMINARY_HW(intel_info) && !i915_preliminary_hw_support) {
|
||||
if (IS_PRELIMINARY_HW(intel_info) && !i915.preliminary_hw_support) {
|
||||
DRM_INFO("This hardware requires preliminary hardware support.\n"
|
||||
"See CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT, and/or modparam preliminary_hw_support\n");
|
||||
return -ENODEV;
|
||||
@@ -1051,14 +983,14 @@ static int __init i915_init(void)
|
||||
* the default behavior.
|
||||
*/
|
||||
#if defined(CONFIG_DRM_I915_KMS)
|
||||
if (i915_modeset != 0)
|
||||
if (i915.modeset != 0)
|
||||
driver.driver_features |= DRIVER_MODESET;
|
||||
#endif
|
||||
if (i915_modeset == 1)
|
||||
if (i915.modeset == 1)
|
||||
driver.driver_features |= DRIVER_MODESET;
|
||||
|
||||
#ifdef CONFIG_VGA_CONSOLE
|
||||
if (vgacon_text_force() && i915_modeset == -1)
|
||||
if (vgacon_text_force() && i915.modeset == -1)
|
||||
driver.driver_features &= ~DRIVER_MODESET;
|
||||
#endif
|
||||
|
||||
|
||||
+289
-140
File diff suppressed because it is too large
Load Diff
+167
-245
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -36,7 +36,7 @@
|
||||
static bool
|
||||
mark_free(struct i915_vma *vma, struct list_head *unwind)
|
||||
{
|
||||
if (vma->obj->pin_count)
|
||||
if (vma->pin_count)
|
||||
return false;
|
||||
|
||||
if (WARN_ON(!list_empty(&vma->exec_list)))
|
||||
@@ -46,6 +46,25 @@ mark_free(struct i915_vma *vma, struct list_head *unwind)
|
||||
return drm_mm_scan_add_block(&vma->node);
|
||||
}
|
||||
|
||||
/**
|
||||
* i915_gem_evict_something - Evict vmas to make room for binding a new one
|
||||
* @dev: drm_device
|
||||
* @vm: address space to evict from
|
||||
* @size: size of the desired free space
|
||||
* @alignment: alignment constraint of the desired free space
|
||||
* @cache_level: cache_level for the desired space
|
||||
* @mappable: whether the free space must be mappable
|
||||
* @nonblocking: whether evicting active objects is allowed or not
|
||||
*
|
||||
* This function will try to evict vmas until a free space satisfying the
|
||||
* requirements is found. Callers must check first whether any such hole exists
|
||||
* already before calling this function.
|
||||
*
|
||||
* This function is used by the object/vma binding code.
|
||||
*
|
||||
* To clarify: This is for freeing up virtual address space, not for freeing
|
||||
* memory in e.g. the shrinker.
|
||||
*/
|
||||
int
|
||||
i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm,
|
||||
int min_size, unsigned alignment, unsigned cache_level,
|
||||
@@ -177,19 +196,19 @@ found:
|
||||
}
|
||||
|
||||
/**
|
||||
* i915_gem_evict_vm - Try to free up VM space
|
||||
* i915_gem_evict_vm - Evict all idle vmas from a vm
|
||||
*
|
||||
* @vm: Address space to evict from
|
||||
* @vm: Address space to cleanse
|
||||
* @do_idle: Boolean directing whether to idle first.
|
||||
*
|
||||
* VM eviction is about freeing up virtual address space. If one wants fine
|
||||
* grained eviction, they should see evict something for more details. In terms
|
||||
* of freeing up actual system memory, this function may not accomplish the
|
||||
* desired result. An object may be shared in multiple address space, and this
|
||||
* function will not assert those objects be freed.
|
||||
* This function evicts all idles vmas from a vm. If all unpinned vmas should be
|
||||
* evicted the @do_idle needs to be set to true.
|
||||
*
|
||||
* Using do_idle will result in a more complete eviction because it retires, and
|
||||
* inactivates current BOs.
|
||||
* This is used by the execbuf code as a last-ditch effort to defragment the
|
||||
* address space.
|
||||
*
|
||||
* To clarify: This is for freeing up virtual address space, not for freeing
|
||||
* memory in e.g. the shrinker.
|
||||
*/
|
||||
int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle)
|
||||
{
|
||||
@@ -207,12 +226,20 @@ int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle)
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(vma, next, &vm->inactive_list, mm_list)
|
||||
if (vma->obj->pin_count == 0)
|
||||
if (vma->pin_count == 0)
|
||||
WARN_ON(i915_vma_unbind(vma));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* i915_gem_evict_everything - Try to evict all objects
|
||||
* @dev: Device to evict objects for
|
||||
*
|
||||
* This functions tries to evict all gem objects from all address spaces. Used
|
||||
* by the shrinker as a last-ditch effort and for suspend, before releasing the
|
||||
* backing storage of all unbound objects.
|
||||
*/
|
||||
int
|
||||
i915_gem_evict_everything(struct drm_device *dev)
|
||||
{
|
||||
|
||||
@@ -91,6 +91,7 @@ eb_lookup_vmas(struct eb_vmas *eb,
|
||||
struct i915_address_space *vm,
|
||||
struct drm_file *file)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = vm->dev->dev_private;
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct list_head objects;
|
||||
int i, ret;
|
||||
@@ -125,6 +126,20 @@ eb_lookup_vmas(struct eb_vmas *eb,
|
||||
i = 0;
|
||||
while (!list_empty(&objects)) {
|
||||
struct i915_vma *vma;
|
||||
struct i915_address_space *bind_vm = vm;
|
||||
|
||||
if (exec[i].flags & EXEC_OBJECT_NEEDS_GTT &&
|
||||
USES_FULL_PPGTT(vm->dev)) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* If we have secure dispatch, or the userspace assures us that
|
||||
* they know what they're doing, use the GGTT VM.
|
||||
*/
|
||||
if (((args->flags & I915_EXEC_SECURE) &&
|
||||
(i == (args->buffer_count - 1))))
|
||||
bind_vm = &dev_priv->gtt.base;
|
||||
|
||||
obj = list_first_entry(&objects,
|
||||
struct drm_i915_gem_object,
|
||||
@@ -138,7 +153,7 @@ eb_lookup_vmas(struct eb_vmas *eb,
|
||||
* from the (obj, vm) we don't run the risk of creating
|
||||
* duplicated vmas for the same vm.
|
||||
*/
|
||||
vma = i915_gem_obj_lookup_or_create_vma(obj, vm);
|
||||
vma = i915_gem_obj_lookup_or_create_vma(obj, bind_vm);
|
||||
if (IS_ERR(vma)) {
|
||||
DRM_DEBUG("Failed to lookup VMA\n");
|
||||
ret = PTR_ERR(vma);
|
||||
@@ -217,7 +232,7 @@ i915_gem_execbuffer_unreserve_vma(struct i915_vma *vma)
|
||||
i915_gem_object_unpin_fence(obj);
|
||||
|
||||
if (entry->flags & __EXEC_OBJECT_HAS_PIN)
|
||||
i915_gem_object_unpin(obj);
|
||||
vma->pin_count--;
|
||||
|
||||
entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
|
||||
}
|
||||
@@ -327,8 +342,7 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj,
|
||||
static int
|
||||
i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
|
||||
struct eb_vmas *eb,
|
||||
struct drm_i915_gem_relocation_entry *reloc,
|
||||
struct i915_address_space *vm)
|
||||
struct drm_i915_gem_relocation_entry *reloc)
|
||||
{
|
||||
struct drm_device *dev = obj->base.dev;
|
||||
struct drm_gem_object *target_obj;
|
||||
@@ -352,8 +366,10 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
|
||||
if (unlikely(IS_GEN6(dev) &&
|
||||
reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION &&
|
||||
!target_i915_obj->has_global_gtt_mapping)) {
|
||||
i915_gem_gtt_bind_object(target_i915_obj,
|
||||
target_i915_obj->cache_level);
|
||||
struct i915_vma *vma =
|
||||
list_first_entry(&target_i915_obj->vma_list,
|
||||
typeof(*vma), vma_link);
|
||||
vma->bind_vma(vma, target_i915_obj->cache_level, GLOBAL_BIND);
|
||||
}
|
||||
|
||||
/* Validate that the target is in a valid r/w GPU domain */
|
||||
@@ -451,8 +467,7 @@ i915_gem_execbuffer_relocate_vma(struct i915_vma *vma,
|
||||
do {
|
||||
u64 offset = r->presumed_offset;
|
||||
|
||||
ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, r,
|
||||
vma->vm);
|
||||
ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, r);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -481,8 +496,7 @@ i915_gem_execbuffer_relocate_vma_slow(struct i915_vma *vma,
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < entry->relocation_count; i++) {
|
||||
ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, &relocs[i],
|
||||
vma->vm);
|
||||
ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, &relocs[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -527,11 +541,12 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma,
|
||||
struct intel_ring_buffer *ring,
|
||||
bool *need_reloc)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = ring->dev->dev_private;
|
||||
struct drm_i915_gem_object *obj = vma->obj;
|
||||
struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
|
||||
bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
|
||||
bool need_fence, need_mappable;
|
||||
struct drm_i915_gem_object *obj = vma->obj;
|
||||
u32 flags = (entry->flags & EXEC_OBJECT_NEEDS_GTT) &&
|
||||
!vma->obj->has_global_gtt_mapping ? GLOBAL_BIND : 0;
|
||||
int ret;
|
||||
|
||||
need_fence =
|
||||
@@ -560,14 +575,6 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma,
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure ppgtt mapping exists if needed */
|
||||
if (dev_priv->mm.aliasing_ppgtt && !obj->has_aliasing_ppgtt_mapping) {
|
||||
i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt,
|
||||
obj, obj->cache_level);
|
||||
|
||||
obj->has_aliasing_ppgtt_mapping = 1;
|
||||
}
|
||||
|
||||
if (entry->offset != vma->node.start) {
|
||||
entry->offset = vma->node.start;
|
||||
*need_reloc = true;
|
||||
@@ -578,9 +585,7 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma,
|
||||
obj->base.pending_write_domain = I915_GEM_DOMAIN_RENDER;
|
||||
}
|
||||
|
||||
if (entry->flags & EXEC_OBJECT_NEEDS_GTT &&
|
||||
!obj->has_global_gtt_mapping)
|
||||
i915_gem_gtt_bind_object(obj, obj->cache_level);
|
||||
vma->bind_vma(vma, obj->cache_level, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -891,7 +896,7 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
|
||||
if (!access_ok(VERIFY_WRITE, ptr, length))
|
||||
return -EFAULT;
|
||||
|
||||
if (likely(!i915_prefault_disable)) {
|
||||
if (likely(!i915.prefault_disable)) {
|
||||
if (fault_in_multipages_readable(ptr, length))
|
||||
return -EFAULT;
|
||||
}
|
||||
@@ -900,22 +905,27 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct i915_hw_context *
|
||||
i915_gem_validate_context(struct drm_device *dev, struct drm_file *file,
|
||||
const u32 ctx_id)
|
||||
struct intel_ring_buffer *ring, const u32 ctx_id)
|
||||
{
|
||||
struct i915_hw_context *ctx = NULL;
|
||||
struct i915_ctx_hang_stats *hs;
|
||||
|
||||
hs = i915_gem_context_get_hang_stats(dev, file, ctx_id);
|
||||
if (IS_ERR(hs))
|
||||
return PTR_ERR(hs);
|
||||
if (ring->id != RCS && ctx_id != DEFAULT_CONTEXT_ID)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
ctx = i915_gem_context_get(file->driver_priv, ctx_id);
|
||||
if (IS_ERR(ctx))
|
||||
return ctx;
|
||||
|
||||
hs = &ctx->hang_stats;
|
||||
if (hs->banned) {
|
||||
DRM_DEBUG("Context %u tried to submit while banned\n", ctx_id);
|
||||
return -EIO;
|
||||
return ERR_PTR(-EIO);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -939,7 +949,9 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas,
|
||||
if (obj->base.write_domain) {
|
||||
obj->dirty = 1;
|
||||
obj->last_write_seqno = intel_ring_get_seqno(ring);
|
||||
if (obj->pin_count) /* check for potential scanout */
|
||||
/* check for potential scanout */
|
||||
if (i915_gem_obj_ggtt_bound(obj) &&
|
||||
i915_gem_obj_to_ggtt(obj)->pin_count)
|
||||
intel_mark_fb_busy(obj, ring);
|
||||
}
|
||||
|
||||
@@ -989,16 +1001,17 @@ static int
|
||||
i915_gem_do_execbuffer(struct drm_device *dev, void *data,
|
||||
struct drm_file *file,
|
||||
struct drm_i915_gem_execbuffer2 *args,
|
||||
struct drm_i915_gem_exec_object2 *exec,
|
||||
struct i915_address_space *vm)
|
||||
struct drm_i915_gem_exec_object2 *exec)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct eb_vmas *eb;
|
||||
struct drm_i915_gem_object *batch_obj;
|
||||
struct drm_clip_rect *cliprects = NULL;
|
||||
struct intel_ring_buffer *ring;
|
||||
struct i915_hw_context *ctx;
|
||||
struct i915_address_space *vm;
|
||||
const u32 ctx_id = i915_execbuffer2_get_context_id(*args);
|
||||
u32 exec_start, exec_len;
|
||||
u32 exec_start = args->batch_start_offset, exec_len;
|
||||
u32 mask, flags;
|
||||
int ret, mode, i;
|
||||
bool need_relocs;
|
||||
@@ -1020,41 +1033,17 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
|
||||
if (args->flags & I915_EXEC_IS_PINNED)
|
||||
flags |= I915_DISPATCH_PINNED;
|
||||
|
||||
switch (args->flags & I915_EXEC_RING_MASK) {
|
||||
case I915_EXEC_DEFAULT:
|
||||
case I915_EXEC_RENDER:
|
||||
ring = &dev_priv->ring[RCS];
|
||||
break;
|
||||
case I915_EXEC_BSD:
|
||||
ring = &dev_priv->ring[VCS];
|
||||
if (ctx_id != DEFAULT_CONTEXT_ID) {
|
||||
DRM_DEBUG("Ring %s doesn't support contexts\n",
|
||||
ring->name);
|
||||
return -EPERM;
|
||||
}
|
||||
break;
|
||||
case I915_EXEC_BLT:
|
||||
ring = &dev_priv->ring[BCS];
|
||||
if (ctx_id != DEFAULT_CONTEXT_ID) {
|
||||
DRM_DEBUG("Ring %s doesn't support contexts\n",
|
||||
ring->name);
|
||||
return -EPERM;
|
||||
}
|
||||
break;
|
||||
case I915_EXEC_VEBOX:
|
||||
ring = &dev_priv->ring[VECS];
|
||||
if (ctx_id != DEFAULT_CONTEXT_ID) {
|
||||
DRM_DEBUG("Ring %s doesn't support contexts\n",
|
||||
ring->name);
|
||||
return -EPERM;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if ((args->flags & I915_EXEC_RING_MASK) > I915_NUM_RINGS) {
|
||||
DRM_DEBUG("execbuf with unknown ring: %d\n",
|
||||
(int)(args->flags & I915_EXEC_RING_MASK));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((args->flags & I915_EXEC_RING_MASK) == I915_EXEC_DEFAULT)
|
||||
ring = &dev_priv->ring[RCS];
|
||||
else
|
||||
ring = &dev_priv->ring[(args->flags & I915_EXEC_RING_MASK) - 1];
|
||||
|
||||
if (!intel_ring_initialized(ring)) {
|
||||
DRM_DEBUG("execbuf with invalid ring: %d\n",
|
||||
(int)(args->flags & I915_EXEC_RING_MASK));
|
||||
@@ -1136,11 +1125,18 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
|
||||
goto pre_mutex_err;
|
||||
}
|
||||
|
||||
ret = i915_gem_validate_context(dev, file, ctx_id);
|
||||
if (ret) {
|
||||
ctx = i915_gem_validate_context(dev, file, ring, ctx_id);
|
||||
if (IS_ERR(ctx)) {
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
ret = PTR_ERR(ctx);
|
||||
goto pre_mutex_err;
|
||||
}
|
||||
}
|
||||
|
||||
i915_gem_context_reference(ctx);
|
||||
|
||||
vm = ctx->vm;
|
||||
if (!USES_FULL_PPGTT(dev))
|
||||
vm = &dev_priv->gtt.base;
|
||||
|
||||
eb = eb_create(args);
|
||||
if (eb == NULL) {
|
||||
@@ -1187,14 +1183,25 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
|
||||
/* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure
|
||||
* batch" bit. Hence we need to pin secure batches into the global gtt.
|
||||
* hsw should have this fixed, but bdw mucks it up again. */
|
||||
if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping)
|
||||
i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level);
|
||||
if (flags & I915_DISPATCH_SECURE &&
|
||||
!batch_obj->has_global_gtt_mapping) {
|
||||
/* When we have multiple VMs, we'll need to make sure that we
|
||||
* allocate space first */
|
||||
struct i915_vma *vma = i915_gem_obj_to_ggtt(batch_obj);
|
||||
BUG_ON(!vma);
|
||||
vma->bind_vma(vma, batch_obj->cache_level, GLOBAL_BIND);
|
||||
}
|
||||
|
||||
if (flags & I915_DISPATCH_SECURE)
|
||||
exec_start += i915_gem_obj_ggtt_offset(batch_obj);
|
||||
else
|
||||
exec_start += i915_gem_obj_offset(batch_obj, vm);
|
||||
|
||||
ret = i915_gem_execbuffer_move_to_gpu(ring, &eb->vmas);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = i915_switch_context(ring, file, ctx_id);
|
||||
ret = i915_switch_context(ring, file, ctx);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
@@ -1219,8 +1226,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
|
||||
goto err;
|
||||
}
|
||||
|
||||
exec_start = i915_gem_obj_offset(batch_obj, vm) +
|
||||
args->batch_start_offset;
|
||||
|
||||
exec_len = args->batch_len;
|
||||
if (cliprects) {
|
||||
for (i = 0; i < args->num_cliprects; i++) {
|
||||
@@ -1249,6 +1255,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
|
||||
i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj);
|
||||
|
||||
err:
|
||||
/* the request owns the ref now */
|
||||
i915_gem_context_unreference(ctx);
|
||||
eb_destroy(eb);
|
||||
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
@@ -1270,7 +1278,6 @@ int
|
||||
i915_gem_execbuffer(struct drm_device *dev, void *data,
|
||||
struct drm_file *file)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct drm_i915_gem_execbuffer *args = data;
|
||||
struct drm_i915_gem_execbuffer2 exec2;
|
||||
struct drm_i915_gem_exec_object *exec_list = NULL;
|
||||
@@ -1326,8 +1333,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
|
||||
exec2.flags = I915_EXEC_RENDER;
|
||||
i915_execbuffer2_set_context_id(exec2, 0);
|
||||
|
||||
ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list,
|
||||
&dev_priv->gtt.base);
|
||||
ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list);
|
||||
if (!ret) {
|
||||
/* Copy the new buffer offsets back to the user's exec list. */
|
||||
for (i = 0; i < args->buffer_count; i++)
|
||||
@@ -1353,7 +1359,6 @@ int
|
||||
i915_gem_execbuffer2(struct drm_device *dev, void *data,
|
||||
struct drm_file *file)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct drm_i915_gem_execbuffer2 *args = data;
|
||||
struct drm_i915_gem_exec_object2 *exec2_list = NULL;
|
||||
int ret;
|
||||
@@ -1384,8 +1389,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list,
|
||||
&dev_priv->gtt.base);
|
||||
ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list);
|
||||
if (!ret) {
|
||||
/* Copy the new buffer offsets back to the user's exec list. */
|
||||
ret = copy_to_user(to_user_ptr(args->buffers_ptr),
|
||||
|
||||
+519
-172
File diff suppressed because it is too large
Load Diff
@@ -308,7 +308,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (obj->pin_count || obj->framebuffer_references) {
|
||||
if (i915_gem_obj_is_pinned(obj) || obj->framebuffer_references) {
|
||||
drm_gem_object_unreference_unlocked(&obj->base);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+138
-121
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright © 2014 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "i915_drv.h"
|
||||
|
||||
struct i915_params i915 __read_mostly = {
|
||||
.modeset = -1,
|
||||
.panel_ignore_lid = 1,
|
||||
.powersave = 1,
|
||||
.semaphores = -1,
|
||||
.lvds_downclock = 0,
|
||||
.lvds_channel_mode = 0,
|
||||
.panel_use_ssc = -1,
|
||||
.vbt_sdvo_panel_type = -1,
|
||||
.enable_rc6 = -1,
|
||||
.enable_fbc = -1,
|
||||
.enable_hangcheck = true,
|
||||
.enable_ppgtt = -1,
|
||||
.enable_psr = 0,
|
||||
.preliminary_hw_support = IS_ENABLED(CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT),
|
||||
.disable_power_well = 1,
|
||||
.enable_ips = 1,
|
||||
.fastboot = 0,
|
||||
.enable_pc8 = 1,
|
||||
.pc8_timeout = 5000,
|
||||
.prefault_disable = 0,
|
||||
.reset = true,
|
||||
.invert_brightness = 0,
|
||||
};
|
||||
|
||||
module_param_named(modeset, i915.modeset, int, 0400);
|
||||
MODULE_PARM_DESC(modeset,
|
||||
"Use kernel modesetting [KMS] (0=DRM_I915_KMS from .config, "
|
||||
"1=on, -1=force vga console preference [default])");
|
||||
|
||||
module_param_named(panel_ignore_lid, i915.panel_ignore_lid, int, 0600);
|
||||
MODULE_PARM_DESC(panel_ignore_lid,
|
||||
"Override lid status (0=autodetect, 1=autodetect disabled [default], "
|
||||
"-1=force lid closed, -2=force lid open)");
|
||||
|
||||
module_param_named(powersave, i915.powersave, int, 0600);
|
||||
MODULE_PARM_DESC(powersave,
|
||||
"Enable powersavings, fbc, downclocking, etc. (default: true)");
|
||||
|
||||
module_param_named(semaphores, i915.semaphores, int, 0400);
|
||||
MODULE_PARM_DESC(semaphores,
|
||||
"Use semaphores for inter-ring sync "
|
||||
"(default: -1 (use per-chip defaults))");
|
||||
|
||||
module_param_named(enable_rc6, i915.enable_rc6, int, 0400);
|
||||
MODULE_PARM_DESC(enable_rc6,
|
||||
"Enable power-saving render C-state 6. "
|
||||
"Different stages can be selected via bitmask values "
|
||||
"(0 = disable; 1 = enable rc6; 2 = enable deep rc6; 4 = enable deepest rc6). "
|
||||
"For example, 3 would enable rc6 and deep rc6, and 7 would enable everything. "
|
||||
"default: -1 (use per-chip default)");
|
||||
|
||||
module_param_named(enable_fbc, i915.enable_fbc, int, 0600);
|
||||
MODULE_PARM_DESC(enable_fbc,
|
||||
"Enable frame buffer compression for power savings "
|
||||
"(default: -1 (use per-chip default))");
|
||||
|
||||
module_param_named(lvds_downclock, i915.lvds_downclock, int, 0400);
|
||||
MODULE_PARM_DESC(lvds_downclock,
|
||||
"Use panel (LVDS/eDP) downclocking for power savings "
|
||||
"(default: false)");
|
||||
|
||||
module_param_named(lvds_channel_mode, i915.lvds_channel_mode, int, 0600);
|
||||
MODULE_PARM_DESC(lvds_channel_mode,
|
||||
"Specify LVDS channel mode "
|
||||
"(0=probe BIOS [default], 1=single-channel, 2=dual-channel)");
|
||||
|
||||
module_param_named(lvds_use_ssc, i915.panel_use_ssc, int, 0600);
|
||||
MODULE_PARM_DESC(lvds_use_ssc,
|
||||
"Use Spread Spectrum Clock with panels [LVDS/eDP] "
|
||||
"(default: auto from VBT)");
|
||||
|
||||
module_param_named(vbt_sdvo_panel_type, i915.vbt_sdvo_panel_type, int, 0600);
|
||||
MODULE_PARM_DESC(vbt_sdvo_panel_type,
|
||||
"Override/Ignore selection of SDVO panel mode in the VBT "
|
||||
"(-2=ignore, -1=auto [default], index in VBT BIOS table)");
|
||||
|
||||
module_param_named(reset, i915.reset, bool, 0600);
|
||||
MODULE_PARM_DESC(reset, "Attempt GPU resets (default: true)");
|
||||
|
||||
module_param_named(enable_hangcheck, i915.enable_hangcheck, bool, 0644);
|
||||
MODULE_PARM_DESC(enable_hangcheck,
|
||||
"Periodically check GPU activity for detecting hangs. "
|
||||
"WARNING: Disabling this can cause system wide hangs. "
|
||||
"(default: true)");
|
||||
|
||||
module_param_named(enable_ppgtt, i915.enable_ppgtt, int, 0400);
|
||||
MODULE_PARM_DESC(enable_ppgtt,
|
||||
"Override PPGTT usage. "
|
||||
"(-1=auto [default], 0=disabled, 1=aliasing, 2=full)");
|
||||
|
||||
module_param_named(enable_psr, i915.enable_psr, int, 0600);
|
||||
MODULE_PARM_DESC(enable_psr, "Enable PSR (default: false)");
|
||||
|
||||
module_param_named(preliminary_hw_support, i915.preliminary_hw_support, int, 0600);
|
||||
MODULE_PARM_DESC(preliminary_hw_support,
|
||||
"Enable preliminary hardware support.");
|
||||
|
||||
module_param_named(disable_power_well, i915.disable_power_well, int, 0600);
|
||||
MODULE_PARM_DESC(disable_power_well,
|
||||
"Disable the power well when possible (default: true)");
|
||||
|
||||
module_param_named(enable_ips, i915.enable_ips, int, 0600);
|
||||
MODULE_PARM_DESC(enable_ips, "Enable IPS (default: true)");
|
||||
|
||||
module_param_named(fastboot, i915.fastboot, bool, 0600);
|
||||
MODULE_PARM_DESC(fastboot,
|
||||
"Try to skip unnecessary mode sets at boot time (default: false)");
|
||||
|
||||
module_param_named(enable_pc8, i915.enable_pc8, int, 0600);
|
||||
MODULE_PARM_DESC(enable_pc8,
|
||||
"Enable support for low power package C states (PC8+) (default: true)");
|
||||
|
||||
module_param_named(pc8_timeout, i915.pc8_timeout, int, 0600);
|
||||
MODULE_PARM_DESC(pc8_timeout,
|
||||
"Number of msecs of idleness required to enter PC8+ (default: 5000)");
|
||||
|
||||
module_param_named(prefault_disable, i915.prefault_disable, bool, 0600);
|
||||
MODULE_PARM_DESC(prefault_disable,
|
||||
"Disable page prefaulting for pread/pwrite/reloc (default:false). "
|
||||
"For developers only.");
|
||||
|
||||
module_param_named(invert_brightness, i915.invert_brightness, int, 0600);
|
||||
MODULE_PARM_DESC(invert_brightness,
|
||||
"Invert backlight brightness "
|
||||
"(-1 force normal, 0 machine defaults, 1 force inversion), please "
|
||||
"report PCI device ID, subsystem vendor and subsystem device ID "
|
||||
"to dri-devel@lists.freedesktop.org, if your machine needs it. "
|
||||
"It will then be included in an upcoming module version.");
|
||||
+192
-138
File diff suppressed because it is too large
Load Diff
@@ -236,19 +236,9 @@ static void i915_save_display(struct drm_device *dev)
|
||||
dev_priv->regfile.savePP_DIVISOR = I915_READ(PP_DIVISOR);
|
||||
}
|
||||
|
||||
/* Only regfile.save FBC state on the platform that supports FBC */
|
||||
if (HAS_FBC(dev)) {
|
||||
if (HAS_PCH_SPLIT(dev)) {
|
||||
dev_priv->regfile.saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE);
|
||||
} else if (IS_GM45(dev)) {
|
||||
dev_priv->regfile.saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE);
|
||||
} else {
|
||||
dev_priv->regfile.saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
|
||||
dev_priv->regfile.saveFBC_LL_BASE = I915_READ(FBC_LL_BASE);
|
||||
dev_priv->regfile.saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
|
||||
dev_priv->regfile.saveFBC_CONTROL = I915_READ(FBC_CONTROL);
|
||||
}
|
||||
}
|
||||
/* save FBC interval */
|
||||
if (HAS_FBC(dev) && INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev))
|
||||
dev_priv->regfile.saveFBC_CONTROL = I915_READ(FBC_CONTROL);
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_MODESET))
|
||||
i915_save_vga(dev);
|
||||
@@ -300,18 +290,10 @@ static void i915_restore_display(struct drm_device *dev)
|
||||
|
||||
/* only restore FBC info on the platform that supports FBC*/
|
||||
intel_disable_fbc(dev);
|
||||
if (HAS_FBC(dev)) {
|
||||
if (HAS_PCH_SPLIT(dev)) {
|
||||
I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->regfile.saveDPFC_CB_BASE);
|
||||
} else if (IS_GM45(dev)) {
|
||||
I915_WRITE(DPFC_CB_BASE, dev_priv->regfile.saveDPFC_CB_BASE);
|
||||
} else {
|
||||
I915_WRITE(FBC_CFB_BASE, dev_priv->regfile.saveFBC_CFB_BASE);
|
||||
I915_WRITE(FBC_LL_BASE, dev_priv->regfile.saveFBC_LL_BASE);
|
||||
I915_WRITE(FBC_CONTROL2, dev_priv->regfile.saveFBC_CONTROL2);
|
||||
I915_WRITE(FBC_CONTROL, dev_priv->regfile.saveFBC_CONTROL);
|
||||
}
|
||||
}
|
||||
|
||||
/* restore FBC interval */
|
||||
if (HAS_FBC(dev) && INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev))
|
||||
I915_WRITE(FBC_CONTROL, dev_priv->regfile.saveFBC_CONTROL);
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_MODESET))
|
||||
i915_restore_vga(dev);
|
||||
@@ -324,10 +306,6 @@ int i915_save_state(struct drm_device *dev)
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
|
||||
if (INTEL_INFO(dev)->gen <= 4)
|
||||
pci_read_config_byte(dev->pdev, LBB,
|
||||
&dev_priv->regfile.saveLBB);
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
i915_save_display(dev);
|
||||
@@ -377,10 +355,6 @@ int i915_restore_state(struct drm_device *dev)
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
|
||||
if (INTEL_INFO(dev)->gen <= 4)
|
||||
pci_write_config_byte(dev->pdev, LBB,
|
||||
dev_priv->regfile.saveLBB);
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
i915_gem_restore_fences(dev);
|
||||
|
||||
@@ -357,6 +357,11 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
|
||||
else
|
||||
gen6_set_rps(dev, val);
|
||||
}
|
||||
else if (!IS_VALLEYVIEW(dev))
|
||||
/* We still need gen6_set_rps to process the new max_delay
|
||||
and update the interrupt limits even though frequency
|
||||
request is unchanged. */
|
||||
gen6_set_rps(dev, dev_priv->rps.cur_delay);
|
||||
|
||||
mutex_unlock(&dev_priv->rps.hw_lock);
|
||||
|
||||
@@ -426,6 +431,11 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
|
||||
else
|
||||
gen6_set_rps(dev, val);
|
||||
}
|
||||
else if (!IS_VALLEYVIEW(dev))
|
||||
/* We still need gen6_set_rps to process the new min_delay
|
||||
and update the interrupt limits even though frequency
|
||||
request is unchanged. */
|
||||
gen6_set_rps(dev, dev_priv->rps.cur_delay);
|
||||
|
||||
mutex_unlock(&dev_priv->rps.hw_lock);
|
||||
|
||||
|
||||
@@ -271,6 +271,10 @@ void i915_save_display_reg(struct drm_device *dev)
|
||||
/* FIXME: regfile.save TV & SDVO state */
|
||||
|
||||
/* Backlight */
|
||||
if (INTEL_INFO(dev)->gen <= 4)
|
||||
pci_read_config_byte(dev->pdev, PCI_LBPC,
|
||||
&dev_priv->regfile.saveLBB);
|
||||
|
||||
if (HAS_PCH_SPLIT(dev)) {
|
||||
dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
|
||||
dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
|
||||
@@ -293,6 +297,10 @@ void i915_restore_display_reg(struct drm_device *dev)
|
||||
int i;
|
||||
|
||||
/* Backlight */
|
||||
if (INTEL_INFO(dev)->gen <= 4)
|
||||
pci_write_config_byte(dev->pdev, PCI_LBPC,
|
||||
dev_priv->regfile.saveLBB);
|
||||
|
||||
if (HAS_PCH_SPLIT(dev)) {
|
||||
I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->regfile.saveBLC_PWM_CTL);
|
||||
I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
|
||||
|
||||
@@ -259,7 +259,7 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
|
||||
downclock = dvo_timing->clock;
|
||||
}
|
||||
|
||||
if (downclock < panel_dvo_timing->clock && i915_lvds_downclock) {
|
||||
if (downclock < panel_dvo_timing->clock && i915.lvds_downclock) {
|
||||
dev_priv->lvds_downclock_avail = 1;
|
||||
dev_priv->lvds_downclock = downclock * 10;
|
||||
DRM_DEBUG_KMS("LVDS downclock is found in VBT. "
|
||||
@@ -318,7 +318,7 @@ parse_sdvo_panel_data(struct drm_i915_private *dev_priv,
|
||||
struct drm_display_mode *panel_fixed_mode;
|
||||
int index;
|
||||
|
||||
index = i915_vbt_sdvo_panel_type;
|
||||
index = i915.vbt_sdvo_panel_type;
|
||||
if (index == -2) {
|
||||
DRM_DEBUG_KMS("Ignore SDVO panel mode from BIOS VBT tables.\n");
|
||||
return;
|
||||
|
||||
@@ -857,4 +857,6 @@ void intel_crt_init(struct drm_device *dev)
|
||||
|
||||
dev_priv->fdi_rx_config = I915_READ(_FDI_RXA_CTL) & fdi_config;
|
||||
}
|
||||
|
||||
intel_crt_reset(connector);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user