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 branch 'drm-intel-next' of git://anongit.freedesktop.org/drm-intel into drm-next
drm-intel-next-2016-05-22: - cmd-parser support for direct reg->reg loads (Ken Graunke) - better handle DP++ smart dongles (Ville) - bxt guc fw loading support (Nick Hoathe) - remove a bunch of struct typedefs from dpll code (Ander) - tons of small work all over to avoid casting between drm_device and the i915 dev struct (Tvrtko&Chris) - untangle request retiring from other operations, also fixes reset stat corner cases (Chris) - skl atomic watermark support from Matt Roper, yay! - various wm handling bugfixes from Ville - big pile of cdclck rework for bxt/skl (Ville) - CABC (Content Adaptive Brigthness Control) for dsi panels (Jani&Deepak M) - nonblocking atomic commits for plane-only updates (Maarten Lankhorst) - bunch of PSR fixes&improvements - untangle our map/pin/sg_iter code a bit (Dave Gordon) drm-intel-next-2016-05-08: - refactor stolen quirks to share code between early quirks and i915 (Joonas) - refactor gem BO/vma funcstion (Tvrtko&Dave) - backlight over DPCD support (Yetunde Abedisi) - more dsi panel sequence support (Jani) - lots of refactoring around handling iomaps, vma, ring access and related topics culmulating in removing the duplicated request tracking in the execlist code (Chris & Tvrtko) includes a small patch for core iomapping code - hw state readout for bxt dsi (Ramalingam C) - cdclk cleanups (Ville) - dedupe chv pll code a bit (Ander) - enable semaphores on gen8+ for legacy submission, to be able to have a direct comparison against execlist on the same platform (Chris) Not meant to be used for anything else but performance tuning - lvds border bit hw state checker fix (Jani) - rpm vs. shrinker/oom-notifier fixes (Praveen Paneri) - l3 tuning (Imre) - revert mst dp audio, it's totally non-functional and crash-y (Lyude) - first official dmc for kbl (Rodrigo) - and tons of small things all over as usual * 'drm-intel-next' of git://anongit.freedesktop.org/drm-intel: (194 commits) drm/i915: Revert async unpin and nonblocking atomic commit drm/i915: Update DRIVER_DATE to 20160522 drm/i915: Inline sg_next() for the optimised SGL iterator drm/i915: Introduce & use new lightweight SGL iterators drm/i915: optimise i915_gem_object_map() for small objects drm/i915: refactor i915_gem_object_pin_map() drm/i915/psr: Implement PSR2 w/a for gen9 drm/i915/psr: Use ->get_aux_send_ctl functions drm/i915/psr: Order DP aux transactions correctly drm/i915/psr: Make idle_frames sensible again drm/i915/psr: Try to program link training times correctly drm/i915/userptr: Convert to drm_i915_private drm/i915: Allow nonblocking update of pageflips. drm/i915: Check for unpin correctness. Reapply "drm/i915: Avoid stalling on pending flips for legacy cursor updates" drm/i915: Make unpin async. drm/i915: Prepare connectors for nonblocking checks. drm/i915: Pass atomic states to fbc update functions. drm/i915: Remove reset_counter from intel_crtc. drm/i915: Remove queue_flip pointer. ...
This commit is contained in:
+192
-208
File diff suppressed because it is too large
Load Diff
@@ -242,6 +242,37 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
|
||||
store_vblank(dev, pipe, diff, &t_vblank, cur_vblank);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_accurate_vblank_count - retrieve the master vblank counter
|
||||
* @crtc: which counter to retrieve
|
||||
*
|
||||
* This function is similar to @drm_crtc_vblank_count but this
|
||||
* function interpolates to handle a race with vblank irq's.
|
||||
*
|
||||
* This is mostly useful for hardware that can obtain the scanout
|
||||
* position, but doesn't have a frame counter.
|
||||
*/
|
||||
u32 drm_accurate_vblank_count(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
unsigned int pipe = drm_crtc_index(crtc);
|
||||
u32 vblank;
|
||||
unsigned long flags;
|
||||
|
||||
WARN(!dev->driver->get_vblank_timestamp,
|
||||
"This function requires support for accurate vblank timestamps.");
|
||||
|
||||
spin_lock_irqsave(&dev->vblank_time_lock, flags);
|
||||
|
||||
drm_update_vblank_count(dev, pipe, 0);
|
||||
vblank = drm_vblank_count(dev, pipe);
|
||||
|
||||
spin_unlock_irqrestore(&dev->vblank_time_lock, flags);
|
||||
|
||||
return vblank;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_accurate_vblank_count);
|
||||
|
||||
/*
|
||||
* Disable vblank irq's on crtc, make sure that last vblank count
|
||||
* of hardware and corresponding consistent software vblank counter
|
||||
|
||||
@@ -59,6 +59,7 @@ i915-y += intel_audio.o \
|
||||
intel_bios.o \
|
||||
intel_color.o \
|
||||
intel_display.o \
|
||||
intel_dpio_phy.o \
|
||||
intel_dpll_mgr.o \
|
||||
intel_fbc.o \
|
||||
intel_fifo_underrun.o \
|
||||
@@ -81,10 +82,12 @@ i915-y += dvo_ch7017.o \
|
||||
dvo_tfp410.o \
|
||||
intel_crt.o \
|
||||
intel_ddi.o \
|
||||
intel_dp_aux_backlight.o \
|
||||
intel_dp_link_training.o \
|
||||
intel_dp_mst.o \
|
||||
intel_dp.o \
|
||||
intel_dsi.o \
|
||||
intel_dsi_dcs_backlight.o \
|
||||
intel_dsi_panel_vbt.o \
|
||||
intel_dsi_pll.o \
|
||||
intel_dvo.o \
|
||||
|
||||
@@ -215,7 +215,8 @@ static const struct drm_i915_cmd_descriptor hsw_render_cmds[] = {
|
||||
CMD( MI_RS_CONTEXT, SMI, F, 1, S ),
|
||||
CMD( MI_LOAD_SCAN_LINES_INCL, SMI, !F, 0x3F, M ),
|
||||
CMD( MI_LOAD_SCAN_LINES_EXCL, SMI, !F, 0x3F, R ),
|
||||
CMD( MI_LOAD_REGISTER_REG, SMI, !F, 0xFF, R ),
|
||||
CMD( MI_LOAD_REGISTER_REG, SMI, !F, 0xFF, W,
|
||||
.reg = { .offset = 1, .mask = 0x007FFFFC, .step = 1 } ),
|
||||
CMD( MI_RS_STORE_DATA_IMM, SMI, !F, 0xFF, S ),
|
||||
CMD( MI_LOAD_URB_MEM, SMI, !F, 0xFF, S ),
|
||||
CMD( MI_STORE_URB_MEM, SMI, !F, 0xFF, S ),
|
||||
@@ -750,12 +751,12 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *engine)
|
||||
int cmd_table_count;
|
||||
int ret;
|
||||
|
||||
if (!IS_GEN7(engine->dev))
|
||||
if (!IS_GEN7(engine->i915))
|
||||
return 0;
|
||||
|
||||
switch (engine->id) {
|
||||
case RCS:
|
||||
if (IS_HASWELL(engine->dev)) {
|
||||
if (IS_HASWELL(engine->i915)) {
|
||||
cmd_tables = hsw_render_ring_cmds;
|
||||
cmd_table_count =
|
||||
ARRAY_SIZE(hsw_render_ring_cmds);
|
||||
@@ -764,7 +765,7 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *engine)
|
||||
cmd_table_count = ARRAY_SIZE(gen7_render_cmds);
|
||||
}
|
||||
|
||||
if (IS_HASWELL(engine->dev)) {
|
||||
if (IS_HASWELL(engine->i915)) {
|
||||
engine->reg_tables = hsw_render_reg_tables;
|
||||
engine->reg_table_count = ARRAY_SIZE(hsw_render_reg_tables);
|
||||
} else {
|
||||
@@ -780,7 +781,7 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *engine)
|
||||
engine->get_cmd_length_mask = gen7_bsd_get_cmd_length_mask;
|
||||
break;
|
||||
case BCS:
|
||||
if (IS_HASWELL(engine->dev)) {
|
||||
if (IS_HASWELL(engine->i915)) {
|
||||
cmd_tables = hsw_blt_ring_cmds;
|
||||
cmd_table_count = ARRAY_SIZE(hsw_blt_ring_cmds);
|
||||
} else {
|
||||
@@ -788,7 +789,7 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *engine)
|
||||
cmd_table_count = ARRAY_SIZE(gen7_blt_cmds);
|
||||
}
|
||||
|
||||
if (IS_HASWELL(engine->dev)) {
|
||||
if (IS_HASWELL(engine->i915)) {
|
||||
engine->reg_tables = hsw_blt_reg_tables;
|
||||
engine->reg_table_count = ARRAY_SIZE(hsw_blt_reg_tables);
|
||||
} else {
|
||||
@@ -1035,7 +1036,7 @@ bool i915_needs_cmd_parser(struct intel_engine_cs *engine)
|
||||
if (!engine->needs_cmd_parser)
|
||||
return false;
|
||||
|
||||
if (!USES_PPGTT(engine->dev))
|
||||
if (!USES_PPGTT(engine->i915))
|
||||
return false;
|
||||
|
||||
return (i915.enable_cmd_parser == 1);
|
||||
@@ -1098,6 +1099,11 @@ static bool check_cmd(const struct intel_engine_cs *engine,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (desc->cmd.value == MI_LOAD_REGISTER_REG) {
|
||||
DRM_DEBUG_DRIVER("CMD: Rejected LRR to OACONTROL\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (desc->cmd.value == MI_LOAD_REGISTER_IMM(1))
|
||||
*oacontrol_set = (cmd[offset + 1] != 0);
|
||||
}
|
||||
@@ -1113,6 +1119,12 @@ static bool check_cmd(const struct intel_engine_cs *engine,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (desc->cmd.value == MI_LOAD_REGISTER_REG) {
|
||||
DRM_DEBUG_DRIVER("CMD: Rejected LRR to masked register 0x%08X\n",
|
||||
reg_addr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (desc->cmd.value == MI_LOAD_REGISTER_IMM(1) &&
|
||||
(offset + 2 > length ||
|
||||
(cmd[offset + 1] & reg->mask) != reg->value)) {
|
||||
@@ -1275,8 +1287,21 @@ int i915_parse_cmds(struct intel_engine_cs *engine,
|
||||
*
|
||||
* Return: the current version number of the cmd parser
|
||||
*/
|
||||
int i915_cmd_parser_get_version(void)
|
||||
int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_engine_cs *engine;
|
||||
bool active = false;
|
||||
|
||||
/* If the command parser is not enabled, report 0 - unsupported */
|
||||
for_each_engine(engine, dev_priv) {
|
||||
if (i915_needs_cmd_parser(engine)) {
|
||||
active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!active)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Command parser version history
|
||||
*
|
||||
@@ -1288,6 +1313,7 @@ int i915_cmd_parser_get_version(void)
|
||||
* 4. L3 atomic chicken bits of HSW_SCRATCH1 and HSW_ROW_CHICKEN3.
|
||||
* 5. GPGPU dispatch compute indirect registers.
|
||||
* 6. TIMESTAMP register and Haswell CS GPR registers
|
||||
* 7. Allow MI_LOAD_REGISTER_REG between whitelisted registers.
|
||||
*/
|
||||
return 6;
|
||||
return 7;
|
||||
}
|
||||
|
||||
@@ -89,17 +89,17 @@ static int i915_capabilities(struct seq_file *m, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char get_active_flag(struct drm_i915_gem_object *obj)
|
||||
static char get_active_flag(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
return obj->active ? '*' : ' ';
|
||||
}
|
||||
|
||||
static const char get_pin_flag(struct drm_i915_gem_object *obj)
|
||||
static char get_pin_flag(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
return obj->pin_display ? 'p' : ' ';
|
||||
}
|
||||
|
||||
static const char get_tiling_flag(struct drm_i915_gem_object *obj)
|
||||
static char get_tiling_flag(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
switch (obj->tiling_mode) {
|
||||
default:
|
||||
@@ -109,12 +109,12 @@ static const char get_tiling_flag(struct drm_i915_gem_object *obj)
|
||||
}
|
||||
}
|
||||
|
||||
static inline const char get_global_flag(struct drm_i915_gem_object *obj)
|
||||
static char get_global_flag(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
return i915_gem_obj_to_ggtt(obj) ? 'g' : ' ';
|
||||
}
|
||||
|
||||
static inline const char get_pin_mapped_flag(struct drm_i915_gem_object *obj)
|
||||
static char get_pin_mapped_flag(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
return obj->mapping ? 'M' : ' ';
|
||||
}
|
||||
@@ -607,18 +607,20 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data)
|
||||
for_each_intel_crtc(dev, crtc) {
|
||||
const char pipe = pipe_name(crtc->pipe);
|
||||
const char plane = plane_name(crtc->plane);
|
||||
struct intel_unpin_work *work;
|
||||
struct intel_flip_work *work;
|
||||
|
||||
spin_lock_irq(&dev->event_lock);
|
||||
work = crtc->unpin_work;
|
||||
work = crtc->flip_work;
|
||||
if (work == NULL) {
|
||||
seq_printf(m, "No flip due on pipe %c (plane %c)\n",
|
||||
pipe, plane);
|
||||
} else {
|
||||
u32 pending;
|
||||
u32 addr;
|
||||
|
||||
if (atomic_read(&work->pending) < INTEL_FLIP_COMPLETE) {
|
||||
seq_printf(m, "Flip queued on pipe %c (plane %c)\n",
|
||||
pending = atomic_read(&work->pending);
|
||||
if (pending) {
|
||||
seq_printf(m, "Flip ioctl preparing on pipe %c (plane %c)\n",
|
||||
pipe, plane);
|
||||
} else {
|
||||
seq_printf(m, "Flip pending (waiting for vsync) on pipe %c (plane %c)\n",
|
||||
@@ -638,11 +640,7 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data)
|
||||
seq_printf(m, "Flip queued on frame %d, (was ready on frame %d), now %d\n",
|
||||
work->flip_queued_vblank,
|
||||
work->flip_ready_vblank,
|
||||
drm_crtc_vblank_count(&crtc->base));
|
||||
if (work->enable_stall_check)
|
||||
seq_puts(m, "Stall check enabled, ");
|
||||
else
|
||||
seq_puts(m, "Stall check waiting for page flip ioctl, ");
|
||||
intel_crtc_get_vblank_counter(crtc));
|
||||
seq_printf(m, "%d prepares\n", atomic_read(&work->pending));
|
||||
|
||||
if (INTEL_INFO(dev)->gen >= 4)
|
||||
@@ -1383,7 +1381,7 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused)
|
||||
seqno[id] = engine->get_seqno(engine);
|
||||
}
|
||||
|
||||
i915_get_extra_instdone(dev, instdone);
|
||||
i915_get_extra_instdone(dev_priv, instdone);
|
||||
|
||||
intel_runtime_pm_put(dev_priv);
|
||||
|
||||
@@ -2004,7 +2002,7 @@ static int i915_context_status(struct seq_file *m, void *unused)
|
||||
ctx->legacy_hw_ctx.rcs_state == NULL)
|
||||
continue;
|
||||
|
||||
seq_puts(m, "HW context ");
|
||||
seq_printf(m, "HW context %u ", ctx->hw_id);
|
||||
describe_ctx(m, ctx);
|
||||
if (ctx == dev_priv->kernel_context)
|
||||
seq_printf(m, "(kernel context) ");
|
||||
@@ -2046,15 +2044,13 @@ static void i915_dump_lrc_obj(struct seq_file *m,
|
||||
struct drm_i915_gem_object *ctx_obj = ctx->engine[engine->id].state;
|
||||
unsigned long ggtt_offset = 0;
|
||||
|
||||
seq_printf(m, "CONTEXT: %s %u\n", engine->name, ctx->hw_id);
|
||||
|
||||
if (ctx_obj == NULL) {
|
||||
seq_printf(m, "Context on %s with no gem object\n",
|
||||
engine->name);
|
||||
seq_puts(m, "\tNot allocated\n");
|
||||
return;
|
||||
}
|
||||
|
||||
seq_printf(m, "CONTEXT: %s %u\n", engine->name,
|
||||
intel_execlists_ctx_id(ctx, engine));
|
||||
|
||||
if (!i915_gem_obj_ggtt_bound(ctx_obj))
|
||||
seq_puts(m, "\tNot bound in GGTT\n");
|
||||
else
|
||||
@@ -2100,9 +2096,8 @@ static int i915_dump_lrc(struct seq_file *m, void *unused)
|
||||
return ret;
|
||||
|
||||
list_for_each_entry(ctx, &dev_priv->context_list, link)
|
||||
if (ctx != dev_priv->kernel_context)
|
||||
for_each_engine(engine, dev_priv)
|
||||
i915_dump_lrc_obj(m, ctx, engine);
|
||||
for_each_engine(engine, dev_priv)
|
||||
i915_dump_lrc_obj(m, ctx, engine);
|
||||
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
@@ -2173,8 +2168,8 @@ static int i915_execlists(struct seq_file *m, void *data)
|
||||
|
||||
seq_printf(m, "\t%d requests in queue\n", count);
|
||||
if (head_req) {
|
||||
seq_printf(m, "\tHead request id: %u\n",
|
||||
intel_execlists_ctx_id(head_req->ctx, engine));
|
||||
seq_printf(m, "\tHead request context: %u\n",
|
||||
head_req->ctx->hw_id);
|
||||
seq_printf(m, "\tHead request tail: %u\n",
|
||||
head_req->tail);
|
||||
}
|
||||
@@ -2313,12 +2308,12 @@ static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev)
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_engine_cs *engine;
|
||||
|
||||
if (INTEL_INFO(dev)->gen == 6)
|
||||
if (IS_GEN6(dev_priv))
|
||||
seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE));
|
||||
|
||||
for_each_engine(engine, dev_priv) {
|
||||
seq_printf(m, "%s\n", engine->name);
|
||||
if (INTEL_INFO(dev)->gen == 7)
|
||||
if (IS_GEN7(dev_priv))
|
||||
seq_printf(m, "GFX_MODE: 0x%08x\n",
|
||||
I915_READ(RING_MODE_GEN7(engine)));
|
||||
seq_printf(m, "PP_DIR_BASE: 0x%08x\n",
|
||||
@@ -3168,7 +3163,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused)
|
||||
enum intel_engine_id id;
|
||||
int j, ret;
|
||||
|
||||
if (!i915_semaphore_is_enabled(dev)) {
|
||||
if (!i915_semaphore_is_enabled(dev_priv)) {
|
||||
seq_puts(m, "Semaphores are disabled\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -4769,7 +4764,7 @@ i915_wedged_set(void *data, u64 val)
|
||||
|
||||
intel_runtime_pm_get(dev_priv);
|
||||
|
||||
i915_handle_error(dev, val,
|
||||
i915_handle_error(dev_priv, val,
|
||||
"Manually setting wedged to %llu", val);
|
||||
|
||||
intel_runtime_pm_put(dev_priv);
|
||||
@@ -4919,7 +4914,7 @@ i915_drop_caches_set(void *data, u64 val)
|
||||
}
|
||||
|
||||
if (val & (DROP_RETIRE | DROP_ACTIVE))
|
||||
i915_gem_retire_requests(dev);
|
||||
i915_gem_retire_requests(dev_priv);
|
||||
|
||||
if (val & DROP_BOUND)
|
||||
i915_gem_shrink(dev_priv, LONG_MAX, I915_SHRINK_BOUND);
|
||||
@@ -4993,7 +4988,7 @@ i915_max_freq_set(void *data, u64 val)
|
||||
|
||||
dev_priv->rps.max_freq_softlimit = val;
|
||||
|
||||
intel_set_rps(dev, val);
|
||||
intel_set_rps(dev_priv, val);
|
||||
|
||||
mutex_unlock(&dev_priv->rps.hw_lock);
|
||||
|
||||
@@ -5060,7 +5055,7 @@ i915_min_freq_set(void *data, u64 val)
|
||||
|
||||
dev_priv->rps.min_freq_softlimit = val;
|
||||
|
||||
intel_set_rps(dev, val);
|
||||
intel_set_rps(dev_priv, val);
|
||||
|
||||
mutex_unlock(&dev_priv->rps.hw_lock);
|
||||
|
||||
|
||||
@@ -186,7 +186,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
|
||||
value = 1;
|
||||
break;
|
||||
case I915_PARAM_HAS_SEMAPHORES:
|
||||
value = i915_semaphore_is_enabled(dev);
|
||||
value = i915_semaphore_is_enabled(dev_priv);
|
||||
break;
|
||||
case I915_PARAM_HAS_PRIME_VMAP_FLUSH:
|
||||
value = 1;
|
||||
@@ -204,7 +204,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
|
||||
value = 1;
|
||||
break;
|
||||
case I915_PARAM_CMD_PARSER_VERSION:
|
||||
value = i915_cmd_parser_get_version();
|
||||
value = i915_cmd_parser_get_version(dev_priv);
|
||||
break;
|
||||
case I915_PARAM_HAS_COHERENT_PHYS_GTT:
|
||||
value = 1;
|
||||
@@ -223,8 +223,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
|
||||
return -ENODEV;
|
||||
break;
|
||||
case I915_PARAM_HAS_GPU_RESET:
|
||||
value = i915.enable_hangcheck &&
|
||||
intel_has_gpu_reset(dev);
|
||||
value = i915.enable_hangcheck && intel_has_gpu_reset(dev_priv);
|
||||
break;
|
||||
case I915_PARAM_HAS_RESOURCE_STREAMER:
|
||||
value = HAS_RESOURCE_STREAMER(dev);
|
||||
@@ -425,6 +424,43 @@ static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
|
||||
.can_switch = i915_switcheroo_can_switch,
|
||||
};
|
||||
|
||||
static void i915_gem_fini(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
|
||||
/*
|
||||
* Neither the BIOS, ourselves or any other kernel
|
||||
* expects the system to be in execlists mode on startup,
|
||||
* so we need to reset the GPU back to legacy mode. And the only
|
||||
* known way to disable logical contexts is through a GPU reset.
|
||||
*
|
||||
* So in order to leave the system in a known default configuration,
|
||||
* always reset the GPU upon unload. Afterwards we then clean up the
|
||||
* GEM state tracking, flushing off the requests and leaving the
|
||||
* system in a known idle state.
|
||||
*
|
||||
* Note that is of the upmost importance that the GPU is idle and
|
||||
* all stray writes are flushed *before* we dismantle the backing
|
||||
* storage for the pinned objects.
|
||||
*
|
||||
* However, since we are uncertain that reseting the GPU on older
|
||||
* machines is a good idea, we don't - just in case it leaves the
|
||||
* machine in an unusable condition.
|
||||
*/
|
||||
if (HAS_HW_CONTEXTS(dev)) {
|
||||
int reset = intel_gpu_reset(dev_priv, ALL_ENGINES);
|
||||
WARN_ON(reset && reset != -ENODEV);
|
||||
}
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
i915_gem_reset(dev);
|
||||
i915_gem_cleanup_engines(dev);
|
||||
i915_gem_context_fini(dev);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
WARN_ON(!list_empty(&to_i915(dev)->context_list));
|
||||
}
|
||||
|
||||
static int i915_load_modeset_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
@@ -454,6 +490,9 @@ static int i915_load_modeset_init(struct drm_device *dev)
|
||||
if (ret)
|
||||
goto cleanup_vga_client;
|
||||
|
||||
/* must happen before intel_power_domains_init_hw() on VLV/CHV */
|
||||
intel_update_rawclk(dev_priv);
|
||||
|
||||
intel_power_domains_init_hw(dev_priv, false);
|
||||
|
||||
intel_csr_ucode_init(dev_priv);
|
||||
@@ -503,10 +542,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
|
||||
return 0;
|
||||
|
||||
cleanup_gem:
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
i915_gem_cleanup_engines(dev);
|
||||
i915_gem_context_fini(dev);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
i915_gem_fini(dev);
|
||||
cleanup_irq:
|
||||
intel_guc_ucode_fini(dev);
|
||||
drm_irq_uninstall(dev);
|
||||
@@ -850,7 +886,7 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
|
||||
DRM_INFO("Display disabled (module parameter)\n");
|
||||
info->num_pipes = 0;
|
||||
} else if (info->num_pipes > 0 &&
|
||||
(INTEL_INFO(dev)->gen == 7 || INTEL_INFO(dev)->gen == 8) &&
|
||||
(IS_GEN7(dev_priv) || IS_GEN8(dev_priv)) &&
|
||||
HAS_PCH_SPLIT(dev)) {
|
||||
u32 fuse_strap = I915_READ(FUSE_STRAP);
|
||||
u32 sfuse_strap = I915_READ(SFUSE_STRAP);
|
||||
@@ -874,7 +910,7 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
|
||||
DRM_INFO("PipeC fused off\n");
|
||||
info->num_pipes -= 1;
|
||||
}
|
||||
} else if (info->num_pipes > 0 && INTEL_INFO(dev)->gen == 9) {
|
||||
} else if (info->num_pipes > 0 && IS_GEN9(dev_priv)) {
|
||||
u32 dfsm = I915_READ(SKL_DFSM);
|
||||
u8 disabled_mask = 0;
|
||||
bool invalid;
|
||||
@@ -915,9 +951,11 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
|
||||
else if (INTEL_INFO(dev)->gen >= 9)
|
||||
gen9_sseu_info_init(dev);
|
||||
|
||||
/* Snooping is broken on BXT A stepping. */
|
||||
info->has_snoop = !info->has_llc;
|
||||
info->has_snoop &= !IS_BXT_REVID(dev, 0, BXT_REVID_A1);
|
||||
|
||||
/* Snooping is broken on BXT A stepping. */
|
||||
if (IS_BXT_REVID(dev, 0, BXT_REVID_A1))
|
||||
info->has_snoop = false;
|
||||
|
||||
DRM_DEBUG_DRIVER("slice total: %u\n", info->slice_total);
|
||||
DRM_DEBUG_DRIVER("subslice total: %u\n", info->subslice_total);
|
||||
@@ -930,6 +968,20 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
|
||||
info->has_subslice_pg ? "y" : "n");
|
||||
DRM_DEBUG_DRIVER("has EU power gating: %s\n",
|
||||
info->has_eu_pg ? "y" : "n");
|
||||
|
||||
i915.enable_execlists =
|
||||
intel_sanitize_enable_execlists(dev_priv,
|
||||
i915.enable_execlists);
|
||||
|
||||
/*
|
||||
* i915.enable_ppgtt is read-only, so do an early pass to validate the
|
||||
* user's requested state against the hardware/driver capabilities. We
|
||||
* do this now so that we can print out any log messages once rather
|
||||
* than every time we check intel_enable_ppgtt().
|
||||
*/
|
||||
i915.enable_ppgtt =
|
||||
intel_sanitize_enable_ppgtt(dev_priv, i915.enable_ppgtt);
|
||||
DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915.enable_ppgtt);
|
||||
}
|
||||
|
||||
static void intel_init_dpio(struct drm_i915_private *dev_priv)
|
||||
@@ -1020,6 +1072,9 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,
|
||||
memcpy(device_info, info, sizeof(dev_priv->info));
|
||||
device_info->device_id = dev->pdev->device;
|
||||
|
||||
BUG_ON(device_info->gen > sizeof(device_info->gen_mask) * BITS_PER_BYTE);
|
||||
device_info->gen_mask = BIT(device_info->gen - 1);
|
||||
|
||||
spin_lock_init(&dev_priv->irq_lock);
|
||||
spin_lock_init(&dev_priv->gpu_error.lock);
|
||||
mutex_init(&dev_priv->backlight_lock);
|
||||
@@ -1137,7 +1192,7 @@ static int i915_driver_init_mmio(struct drm_i915_private *dev_priv)
|
||||
if (ret < 0)
|
||||
goto put_bridge;
|
||||
|
||||
intel_uncore_init(dev);
|
||||
intel_uncore_init(dev_priv);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1155,7 +1210,7 @@ static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = dev_priv->dev;
|
||||
|
||||
intel_uncore_fini(dev);
|
||||
intel_uncore_fini(dev_priv);
|
||||
i915_mmio_cleanup(dev);
|
||||
pci_dev_put(dev_priv->bridge_dev);
|
||||
}
|
||||
@@ -1206,8 +1261,15 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
|
||||
pci_set_master(dev->pdev);
|
||||
|
||||
/* overlay on gen2 is broken and can't address above 1G */
|
||||
if (IS_GEN2(dev))
|
||||
dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30));
|
||||
if (IS_GEN2(dev)) {
|
||||
ret = dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30));
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to set DMA mask\n");
|
||||
|
||||
goto out_ggtt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 965GM sometimes incorrectly writes to hardware status page (HWS)
|
||||
* using 32bit addressing, overwriting memory if HWS is located
|
||||
@@ -1217,8 +1279,15 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
|
||||
* behaviour if any general state is accessed within a page above 4GB,
|
||||
* which also needs to be handled carefully.
|
||||
*/
|
||||
if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
|
||||
dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32));
|
||||
if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) {
|
||||
ret = dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32));
|
||||
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to set DMA mask\n");
|
||||
|
||||
goto out_ggtt;
|
||||
}
|
||||
}
|
||||
|
||||
aperture_size = ggtt->mappable_end;
|
||||
|
||||
@@ -1236,7 +1305,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
|
||||
pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY,
|
||||
PM_QOS_DEFAULT_VALUE);
|
||||
|
||||
intel_uncore_sanitize(dev);
|
||||
intel_uncore_sanitize(dev_priv);
|
||||
|
||||
intel_opregion_setup(dev);
|
||||
|
||||
@@ -1300,7 +1369,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
|
||||
* Notify a valid surface after modesetting,
|
||||
* when running inside a VM.
|
||||
*/
|
||||
if (intel_vgpu_active(dev))
|
||||
if (intel_vgpu_active(dev_priv))
|
||||
I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY);
|
||||
|
||||
i915_setup_sysfs(dev);
|
||||
@@ -1459,10 +1528,7 @@ int i915_driver_unload(struct drm_device *dev)
|
||||
flush_workqueue(dev_priv->wq);
|
||||
|
||||
intel_guc_ucode_fini(dev);
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
i915_gem_cleanup_engines(dev);
|
||||
i915_gem_context_fini(dev);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
i915_gem_fini(dev);
|
||||
intel_fbc_cleanup_cfb(dev_priv);
|
||||
|
||||
intel_power_domains_fini(dev_priv);
|
||||
@@ -1570,15 +1636,15 @@ const struct drm_ioctl_desc i915_ioctls[] = {
|
||||
DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0),
|
||||
DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, i915_gem_context_create_ioctl, DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(I915_GET_RESET_STATS, i915_get_reset_stats_ioctl, DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(I915_GET_RESET_STATS, i915_gem_context_reset_stats_ioctl, DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_RENDER_ALLOW),
|
||||
|
||||
@@ -298,22 +298,26 @@ static const struct intel_device_info intel_haswell_m_info = {
|
||||
static const struct intel_device_info intel_broadwell_d_info = {
|
||||
BDW_FEATURES,
|
||||
.gen = 8,
|
||||
.is_broadwell = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_broadwell_m_info = {
|
||||
BDW_FEATURES,
|
||||
.gen = 8, .is_mobile = 1,
|
||||
.is_broadwell = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_broadwell_gt3d_info = {
|
||||
BDW_FEATURES,
|
||||
.gen = 8,
|
||||
.is_broadwell = 1,
|
||||
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_broadwell_gt3m_info = {
|
||||
BDW_FEATURES,
|
||||
.gen = 8, .is_mobile = 1,
|
||||
.is_broadwell = 1,
|
||||
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
|
||||
};
|
||||
|
||||
@@ -528,9 +532,9 @@ void intel_detect_pch(struct drm_device *dev)
|
||||
pci_dev_put(pch);
|
||||
}
|
||||
|
||||
bool i915_semaphore_is_enabled(struct drm_device *dev)
|
||||
bool i915_semaphore_is_enabled(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
if (INTEL_INFO(dev)->gen < 6)
|
||||
if (INTEL_GEN(dev_priv) < 6)
|
||||
return false;
|
||||
|
||||
if (i915.semaphores >= 0)
|
||||
@@ -540,13 +544,9 @@ bool i915_semaphore_is_enabled(struct drm_device *dev)
|
||||
if (i915.enable_execlists)
|
||||
return false;
|
||||
|
||||
/* Until we get further testing... */
|
||||
if (IS_GEN8(dev))
|
||||
return false;
|
||||
|
||||
#ifdef CONFIG_INTEL_IOMMU
|
||||
/* Enable semaphores on SNB when IO remapping is off */
|
||||
if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped)
|
||||
if (IS_GEN6(dev_priv) && intel_iommu_gfx_mapped)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
@@ -608,7 +608,7 @@ static int i915_drm_suspend(struct drm_device *dev)
|
||||
|
||||
intel_guc_suspend(dev);
|
||||
|
||||
intel_suspend_gt_powersave(dev);
|
||||
intel_suspend_gt_powersave(dev_priv);
|
||||
|
||||
intel_display_suspend(dev);
|
||||
|
||||
@@ -628,7 +628,7 @@ static int i915_drm_suspend(struct drm_device *dev)
|
||||
opregion_target_state = suspend_to_idle(dev_priv) ? PCI_D1 : PCI_D3cold;
|
||||
intel_opregion_notify_adapter(dev, opregion_target_state);
|
||||
|
||||
intel_uncore_forcewake_reset(dev, false);
|
||||
intel_uncore_forcewake_reset(dev_priv, false);
|
||||
intel_opregion_fini(dev);
|
||||
|
||||
intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED, true);
|
||||
@@ -775,7 +775,7 @@ static int i915_drm_resume(struct drm_device *dev)
|
||||
|
||||
spin_lock_irq(&dev_priv->irq_lock);
|
||||
if (dev_priv->display.hpd_irq_setup)
|
||||
dev_priv->display.hpd_irq_setup(dev);
|
||||
dev_priv->display.hpd_irq_setup(dev_priv);
|
||||
spin_unlock_irq(&dev_priv->irq_lock);
|
||||
|
||||
intel_dp_mst_resume(dev);
|
||||
@@ -868,9 +868,9 @@ static int i915_drm_resume_early(struct drm_device *dev)
|
||||
DRM_ERROR("Resume prepare failed: %d, continuing anyway\n",
|
||||
ret);
|
||||
|
||||
intel_uncore_early_sanitize(dev, true);
|
||||
intel_uncore_early_sanitize(dev_priv, true);
|
||||
|
||||
if (IS_BROXTON(dev)) {
|
||||
if (IS_BROXTON(dev_priv)) {
|
||||
if (!dev_priv->suspended_to_idle)
|
||||
gen9_sanitize_dc_state(dev_priv);
|
||||
bxt_disable_dc9(dev_priv);
|
||||
@@ -878,7 +878,7 @@ static int i915_drm_resume_early(struct drm_device *dev)
|
||||
hsw_disable_pc8(dev_priv);
|
||||
}
|
||||
|
||||
intel_uncore_sanitize(dev);
|
||||
intel_uncore_sanitize(dev_priv);
|
||||
|
||||
if (IS_BROXTON(dev_priv) ||
|
||||
!(dev_priv->suspended_to_idle && dev_priv->csr.dmc_payload))
|
||||
@@ -921,14 +921,14 @@ int i915_resume_switcheroo(struct drm_device *dev)
|
||||
* - re-init interrupt state
|
||||
* - re-init display
|
||||
*/
|
||||
int i915_reset(struct drm_device *dev)
|
||||
int i915_reset(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct drm_device *dev = dev_priv->dev;
|
||||
struct i915_gpu_error *error = &dev_priv->gpu_error;
|
||||
unsigned reset_counter;
|
||||
int ret;
|
||||
|
||||
intel_reset_gt_powersave(dev);
|
||||
intel_reset_gt_powersave(dev_priv);
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
@@ -944,7 +944,7 @@ int i915_reset(struct drm_device *dev)
|
||||
|
||||
i915_gem_reset(dev);
|
||||
|
||||
ret = intel_gpu_reset(dev, ALL_ENGINES);
|
||||
ret = intel_gpu_reset(dev_priv, ALL_ENGINES);
|
||||
|
||||
/* Also reset the gpu hangman. */
|
||||
if (error->stop_rings != 0) {
|
||||
@@ -999,7 +999,7 @@ int i915_reset(struct drm_device *dev)
|
||||
* of re-init after reset.
|
||||
*/
|
||||
if (INTEL_INFO(dev)->gen > 5)
|
||||
intel_enable_gt_powersave(dev);
|
||||
intel_enable_gt_powersave(dev_priv);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1107,6 +1107,49 @@ static int i915_pm_resume(struct device *dev)
|
||||
return i915_drm_resume(drm_dev);
|
||||
}
|
||||
|
||||
/* freeze: before creating the hibernation_image */
|
||||
static int i915_pm_freeze(struct device *dev)
|
||||
{
|
||||
return i915_pm_suspend(dev);
|
||||
}
|
||||
|
||||
static int i915_pm_freeze_late(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = i915_pm_suspend_late(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = i915_gem_freeze_late(dev_to_i915(dev));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* thaw: called after creating the hibernation image, but before turning off. */
|
||||
static int i915_pm_thaw_early(struct device *dev)
|
||||
{
|
||||
return i915_pm_resume_early(dev);
|
||||
}
|
||||
|
||||
static int i915_pm_thaw(struct device *dev)
|
||||
{
|
||||
return i915_pm_resume(dev);
|
||||
}
|
||||
|
||||
/* restore: called after loading the hibernation image. */
|
||||
static int i915_pm_restore_early(struct device *dev)
|
||||
{
|
||||
return i915_pm_resume_early(dev);
|
||||
}
|
||||
|
||||
static int i915_pm_restore(struct device *dev)
|
||||
{
|
||||
return i915_pm_resume(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Save all Gunit registers that may be lost after a D3 and a subsequent
|
||||
* S0i[R123] transition. The list of registers needing a save/restore is
|
||||
@@ -1470,7 +1513,7 @@ static int intel_runtime_suspend(struct device *device)
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int ret;
|
||||
|
||||
if (WARN_ON_ONCE(!(dev_priv->rps.enabled && intel_enable_rc6(dev))))
|
||||
if (WARN_ON_ONCE(!(dev_priv->rps.enabled && intel_enable_rc6())))
|
||||
return -ENODEV;
|
||||
|
||||
if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev)))
|
||||
@@ -1509,7 +1552,7 @@ static int intel_runtime_suspend(struct device *device)
|
||||
|
||||
intel_guc_suspend(dev);
|
||||
|
||||
intel_suspend_gt_powersave(dev);
|
||||
intel_suspend_gt_powersave(dev_priv);
|
||||
intel_runtime_pm_disable_interrupts(dev_priv);
|
||||
|
||||
ret = 0;
|
||||
@@ -1531,7 +1574,7 @@ static int intel_runtime_suspend(struct device *device)
|
||||
return ret;
|
||||
}
|
||||
|
||||
intel_uncore_forcewake_reset(dev, false);
|
||||
intel_uncore_forcewake_reset(dev_priv, false);
|
||||
|
||||
enable_rpm_wakeref_asserts(dev_priv);
|
||||
WARN_ON_ONCE(atomic_read(&dev_priv->pm.wakeref_count));
|
||||
@@ -1612,7 +1655,7 @@ static int intel_runtime_resume(struct device *device)
|
||||
* we can do is to hope that things will still work (and disable RPM).
|
||||
*/
|
||||
i915_gem_init_swizzling(dev);
|
||||
gen6_update_ring_freq(dev);
|
||||
gen6_update_ring_freq(dev_priv);
|
||||
|
||||
intel_runtime_pm_enable_interrupts(dev_priv);
|
||||
|
||||
@@ -1624,7 +1667,7 @@ static int intel_runtime_resume(struct device *device)
|
||||
if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv))
|
||||
intel_hpd_init(dev_priv);
|
||||
|
||||
intel_enable_gt_powersave(dev);
|
||||
intel_enable_gt_powersave(dev_priv);
|
||||
|
||||
enable_rpm_wakeref_asserts(dev_priv);
|
||||
|
||||
@@ -1661,14 +1704,14 @@ static const struct dev_pm_ops i915_pm_ops = {
|
||||
* @restore, @restore_early : called after rebooting and restoring the
|
||||
* hibernation image [PMSG_RESTORE]
|
||||
*/
|
||||
.freeze = i915_pm_suspend,
|
||||
.freeze_late = i915_pm_suspend_late,
|
||||
.thaw_early = i915_pm_resume_early,
|
||||
.thaw = i915_pm_resume,
|
||||
.freeze = i915_pm_freeze,
|
||||
.freeze_late = i915_pm_freeze_late,
|
||||
.thaw_early = i915_pm_thaw_early,
|
||||
.thaw = i915_pm_thaw,
|
||||
.poweroff = i915_pm_suspend,
|
||||
.poweroff_late = i915_pm_poweroff_late,
|
||||
.restore_early = i915_pm_resume_early,
|
||||
.restore = i915_pm_resume,
|
||||
.restore_early = i915_pm_restore_early,
|
||||
.restore = i915_pm_restore,
|
||||
|
||||
/* S0ix (via runtime suspend) event handlers */
|
||||
.runtime_suspend = intel_runtime_suspend,
|
||||
|
||||
+222
-85
File diff suppressed because it is too large
Load Diff
+169
-231
File diff suppressed because it is too large
Load Diff
@@ -134,9 +134,9 @@ i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool,
|
||||
if (obj == NULL) {
|
||||
int ret;
|
||||
|
||||
obj = i915_gem_alloc_object(pool->dev, size);
|
||||
if (obj == NULL)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
obj = i915_gem_object_create(pool->dev, size);
|
||||
if (IS_ERR(obj))
|
||||
return obj;
|
||||
|
||||
ret = i915_gem_object_get_pages(obj);
|
||||
if (ret)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -154,7 +154,7 @@ none:
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
i915_gem_retire_requests(dev);
|
||||
i915_gem_retire_requests(to_i915(dev));
|
||||
goto search_again;
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
i915_gem_retire_requests(vm->dev);
|
||||
i915_gem_retire_requests(to_i915(vm->dev));
|
||||
|
||||
WARN_ON(!list_empty(&vm->active_list));
|
||||
}
|
||||
|
||||
@@ -722,7 +722,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *engine,
|
||||
struct i915_address_space *vm;
|
||||
struct list_head ordered_vmas;
|
||||
struct list_head pinned_vmas;
|
||||
bool has_fenced_gpu_access = INTEL_INFO(engine->dev)->gen < 4;
|
||||
bool has_fenced_gpu_access = INTEL_GEN(engine->i915) < 4;
|
||||
int retry;
|
||||
|
||||
i915_gem_retire_requests_ring(engine);
|
||||
@@ -963,7 +963,7 @@ i915_gem_execbuffer_move_to_gpu(struct drm_i915_gem_request *req,
|
||||
}
|
||||
|
||||
if (flush_chipset)
|
||||
i915_gem_chipset_flush(req->engine->dev);
|
||||
i915_gem_chipset_flush(req->engine->i915);
|
||||
|
||||
if (flush_domains & I915_GEM_DOMAIN_GTT)
|
||||
wmb();
|
||||
@@ -1083,14 +1083,6 @@ i915_gem_validate_context(struct drm_device *dev, struct drm_file *file,
|
||||
return ERR_PTR(-EIO);
|
||||
}
|
||||
|
||||
if (i915.enable_execlists && !ctx->engine[engine->id].state) {
|
||||
int ret = intel_lr_context_deferred_alloc(ctx, engine);
|
||||
if (ret) {
|
||||
DRM_DEBUG("Could not create LRC %u: %d\n", ctx_id, ret);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@@ -1125,7 +1117,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas,
|
||||
if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) {
|
||||
i915_gem_request_assign(&obj->last_fenced_req, req);
|
||||
if (entry->flags & __EXEC_OBJECT_HAS_FENCE) {
|
||||
struct drm_i915_private *dev_priv = to_i915(engine->dev);
|
||||
struct drm_i915_private *dev_priv = engine->i915;
|
||||
list_move_tail(&dev_priv->fence_regs[obj->fence_reg].lru_list,
|
||||
&dev_priv->mm.fence_list);
|
||||
}
|
||||
|
||||
@@ -745,15 +745,15 @@ i915_gem_swizzle_page(struct page *page)
|
||||
void
|
||||
i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
struct sg_page_iter sg_iter;
|
||||
struct sgt_iter sgt_iter;
|
||||
struct page *page;
|
||||
int i;
|
||||
|
||||
if (obj->bit_17 == NULL)
|
||||
return;
|
||||
|
||||
i = 0;
|
||||
for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) {
|
||||
struct page *page = sg_page_iter_page(&sg_iter);
|
||||
for_each_sgt_page(page, sgt_iter, obj->pages) {
|
||||
char new_bit_17 = page_to_phys(page) >> 17;
|
||||
if ((new_bit_17 & 0x1) !=
|
||||
(test_bit(i, obj->bit_17) != 0)) {
|
||||
@@ -775,7 +775,8 @@ i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj)
|
||||
void
|
||||
i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
struct sg_page_iter sg_iter;
|
||||
struct sgt_iter sgt_iter;
|
||||
struct page *page;
|
||||
int page_count = obj->base.size >> PAGE_SHIFT;
|
||||
int i;
|
||||
|
||||
@@ -790,8 +791,9 @@ i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj)
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) {
|
||||
if (page_to_phys(sg_page_iter_page(&sg_iter)) & (1 << 17))
|
||||
|
||||
for_each_sgt_page(page, sgt_iter, obj->pages) {
|
||||
if (page_to_phys(page) & (1 << 17))
|
||||
__set_bit(i, obj->bit_17);
|
||||
else
|
||||
__clear_bit(i, obj->bit_17);
|
||||
|
||||
+131
-108
@@ -93,6 +93,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
static inline struct i915_ggtt *
|
||||
i915_vm_to_ggtt(struct i915_address_space *vm)
|
||||
{
|
||||
GEM_BUG_ON(!i915_is_ggtt(vm));
|
||||
return container_of(vm, struct i915_ggtt, base);
|
||||
}
|
||||
|
||||
static int
|
||||
i915_get_ggtt_vma_pages(struct i915_vma *vma);
|
||||
|
||||
@@ -103,25 +110,29 @@ const struct i915_ggtt_view i915_ggtt_view_rotated = {
|
||||
.type = I915_GGTT_VIEW_ROTATED,
|
||||
};
|
||||
|
||||
static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt)
|
||||
int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv,
|
||||
int enable_ppgtt)
|
||||
{
|
||||
bool has_aliasing_ppgtt;
|
||||
bool has_full_ppgtt;
|
||||
bool has_full_48bit_ppgtt;
|
||||
|
||||
has_aliasing_ppgtt = INTEL_INFO(dev)->gen >= 6;
|
||||
has_full_ppgtt = INTEL_INFO(dev)->gen >= 7;
|
||||
has_full_48bit_ppgtt = IS_BROADWELL(dev) || INTEL_INFO(dev)->gen >= 9;
|
||||
has_aliasing_ppgtt = INTEL_GEN(dev_priv) >= 6;
|
||||
has_full_ppgtt = INTEL_GEN(dev_priv) >= 7;
|
||||
has_full_48bit_ppgtt =
|
||||
IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9;
|
||||
|
||||
if (intel_vgpu_active(dev))
|
||||
if (intel_vgpu_active(dev_priv))
|
||||
has_full_ppgtt = false; /* emulation is too hard */
|
||||
|
||||
if (!has_aliasing_ppgtt)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We don't allow disabling PPGTT for gen9+ as it's a requirement for
|
||||
* execlists, the sole mechanism available to submit work.
|
||||
*/
|
||||
if (INTEL_INFO(dev)->gen < 9 &&
|
||||
(enable_ppgtt == 0 || !has_aliasing_ppgtt))
|
||||
if (enable_ppgtt == 0 && INTEL_GEN(dev_priv) < 9)
|
||||
return 0;
|
||||
|
||||
if (enable_ppgtt == 1)
|
||||
@@ -135,19 +146,19 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt)
|
||||
|
||||
#ifdef CONFIG_INTEL_IOMMU
|
||||
/* Disable ppgtt on SNB if VT-d is on. */
|
||||
if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) {
|
||||
if (IS_GEN6(dev_priv) && intel_iommu_gfx_mapped) {
|
||||
DRM_INFO("Disabling PPGTT because VT-d is on\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Early VLV doesn't have this */
|
||||
if (IS_VALLEYVIEW(dev) && dev->pdev->revision < 0xb) {
|
||||
if (IS_VALLEYVIEW(dev_priv) && dev_priv->dev->pdev->revision < 0xb) {
|
||||
DRM_DEBUG_DRIVER("disabling PPGTT on pre-B3 step VLV\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (INTEL_INFO(dev)->gen >= 8 && i915.enable_execlists)
|
||||
if (INTEL_GEN(dev_priv) >= 8 && i915.enable_execlists)
|
||||
return has_full_48bit_ppgtt ? 3 : 2;
|
||||
else
|
||||
return has_aliasing_ppgtt ? 1 : 0;
|
||||
@@ -866,6 +877,7 @@ static void gen8_free_page_tables(struct drm_device *dev,
|
||||
static int gen8_init_scratch(struct i915_address_space *vm)
|
||||
{
|
||||
struct drm_device *dev = vm->dev;
|
||||
int ret;
|
||||
|
||||
vm->scratch_page = alloc_scratch_page(dev);
|
||||
if (IS_ERR(vm->scratch_page))
|
||||
@@ -873,24 +885,21 @@ static int gen8_init_scratch(struct i915_address_space *vm)
|
||||
|
||||
vm->scratch_pt = alloc_pt(dev);
|
||||
if (IS_ERR(vm->scratch_pt)) {
|
||||
free_scratch_page(dev, vm->scratch_page);
|
||||
return PTR_ERR(vm->scratch_pt);
|
||||
ret = PTR_ERR(vm->scratch_pt);
|
||||
goto free_scratch_page;
|
||||
}
|
||||
|
||||
vm->scratch_pd = alloc_pd(dev);
|
||||
if (IS_ERR(vm->scratch_pd)) {
|
||||
free_pt(dev, vm->scratch_pt);
|
||||
free_scratch_page(dev, vm->scratch_page);
|
||||
return PTR_ERR(vm->scratch_pd);
|
||||
ret = PTR_ERR(vm->scratch_pd);
|
||||
goto free_pt;
|
||||
}
|
||||
|
||||
if (USES_FULL_48BIT_PPGTT(dev)) {
|
||||
vm->scratch_pdp = alloc_pdp(dev);
|
||||
if (IS_ERR(vm->scratch_pdp)) {
|
||||
free_pd(dev, vm->scratch_pd);
|
||||
free_pt(dev, vm->scratch_pt);
|
||||
free_scratch_page(dev, vm->scratch_page);
|
||||
return PTR_ERR(vm->scratch_pdp);
|
||||
ret = PTR_ERR(vm->scratch_pdp);
|
||||
goto free_pd;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -900,6 +909,15 @@ static int gen8_init_scratch(struct i915_address_space *vm)
|
||||
gen8_initialize_pdp(vm, vm->scratch_pdp);
|
||||
|
||||
return 0;
|
||||
|
||||
free_pd:
|
||||
free_pd(dev, vm->scratch_pd);
|
||||
free_pt:
|
||||
free_pt(dev, vm->scratch_pt);
|
||||
free_scratch_page:
|
||||
free_scratch_page(dev, vm->scratch_page);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int gen8_ppgtt_notify_vgt(struct i915_hw_ppgtt *ppgtt, bool create)
|
||||
@@ -978,7 +996,7 @@ static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
|
||||
{
|
||||
struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
|
||||
|
||||
if (intel_vgpu_active(vm->dev))
|
||||
if (intel_vgpu_active(to_i915(vm->dev)))
|
||||
gen8_ppgtt_notify_vgt(ppgtt, false);
|
||||
|
||||
if (!USES_FULL_48BIT_PPGTT(ppgtt->base.dev))
|
||||
@@ -1529,14 +1547,14 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
|
||||
0, 0,
|
||||
GEN8_PML4E_SHIFT);
|
||||
|
||||
if (intel_vgpu_active(ppgtt->base.dev)) {
|
||||
if (intel_vgpu_active(to_i915(ppgtt->base.dev))) {
|
||||
ret = gen8_preallocate_top_level_pdps(ppgtt);
|
||||
if (ret)
|
||||
goto free_scratch;
|
||||
}
|
||||
}
|
||||
|
||||
if (intel_vgpu_active(ppgtt->base.dev))
|
||||
if (intel_vgpu_active(to_i915(ppgtt->base.dev)))
|
||||
gen8_ppgtt_notify_vgt(ppgtt, true);
|
||||
|
||||
return 0;
|
||||
@@ -1821,20 +1839,19 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
|
||||
enum i915_cache_level cache_level, u32 flags)
|
||||
{
|
||||
struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
|
||||
gen6_pte_t *pt_vaddr;
|
||||
unsigned first_entry = start >> PAGE_SHIFT;
|
||||
unsigned act_pt = first_entry / GEN6_PTES;
|
||||
unsigned act_pte = first_entry % GEN6_PTES;
|
||||
struct sg_page_iter sg_iter;
|
||||
gen6_pte_t *pt_vaddr = NULL;
|
||||
struct sgt_iter sgt_iter;
|
||||
dma_addr_t addr;
|
||||
|
||||
pt_vaddr = NULL;
|
||||
for_each_sg_page(pages->sgl, &sg_iter, pages->nents, 0) {
|
||||
for_each_sgt_dma(addr, sgt_iter, pages) {
|
||||
if (pt_vaddr == NULL)
|
||||
pt_vaddr = kmap_px(ppgtt->pd.page_table[act_pt]);
|
||||
|
||||
pt_vaddr[act_pte] =
|
||||
vm->pte_encode(sg_page_iter_dma_address(&sg_iter),
|
||||
cache_level, true, flags);
|
||||
vm->pte_encode(addr, cache_level, true, flags);
|
||||
|
||||
if (++act_pte == GEN6_PTES) {
|
||||
kunmap_px(ppgtt, pt_vaddr);
|
||||
@@ -1843,6 +1860,7 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
|
||||
act_pte = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (pt_vaddr)
|
||||
kunmap_px(ppgtt, pt_vaddr);
|
||||
}
|
||||
@@ -2064,7 +2082,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
|
||||
} else
|
||||
BUG();
|
||||
|
||||
if (intel_vgpu_active(dev))
|
||||
if (intel_vgpu_active(dev_priv))
|
||||
ppgtt->switch_mm = vgpu_mm_switch;
|
||||
|
||||
ret = gen6_ppgtt_alloc(ppgtt);
|
||||
@@ -2140,7 +2158,7 @@ static void gtt_write_workarounds(struct drm_device *dev)
|
||||
I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_BXT);
|
||||
}
|
||||
|
||||
int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
|
||||
static int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int ret = 0;
|
||||
@@ -2179,20 +2197,6 @@ int i915_ppgtt_init_hw(struct drm_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i915_ppgtt_init_ring(struct drm_i915_gem_request *req)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = req->i915;
|
||||
struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
|
||||
|
||||
if (i915.enable_execlists)
|
||||
return 0;
|
||||
|
||||
if (!ppgtt)
|
||||
return 0;
|
||||
|
||||
return ppgtt->switch_mm(ppgtt, req);
|
||||
}
|
||||
|
||||
struct i915_hw_ppgtt *
|
||||
i915_ppgtt_create(struct drm_device *dev, struct drm_i915_file_private *fpriv)
|
||||
{
|
||||
@@ -2275,12 +2279,11 @@ static void undo_idling(struct drm_i915_private *dev_priv, bool interruptible)
|
||||
dev_priv->mm.interruptible = interruptible;
|
||||
}
|
||||
|
||||
void i915_check_and_clear_faults(struct drm_device *dev)
|
||||
void i915_check_and_clear_faults(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_engine_cs *engine;
|
||||
|
||||
if (INTEL_INFO(dev)->gen < 6)
|
||||
if (INTEL_INFO(dev_priv)->gen < 6)
|
||||
return;
|
||||
|
||||
for_each_engine(engine, dev_priv) {
|
||||
@@ -2324,7 +2327,7 @@ void i915_gem_suspend_gtt_mappings(struct drm_device *dev)
|
||||
if (INTEL_INFO(dev)->gen < 6)
|
||||
return;
|
||||
|
||||
i915_check_and_clear_faults(dev);
|
||||
i915_check_and_clear_faults(dev_priv);
|
||||
|
||||
ggtt->base.clear_range(&ggtt->base, ggtt->base.start, ggtt->base.total,
|
||||
true);
|
||||
@@ -2358,23 +2361,21 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
|
||||
enum i915_cache_level level, u32 unused)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(vm->dev);
|
||||
struct i915_ggtt *ggtt = &dev_priv->ggtt;
|
||||
unsigned first_entry = start >> PAGE_SHIFT;
|
||||
gen8_pte_t __iomem *gtt_entries =
|
||||
(gen8_pte_t __iomem *)ggtt->gsm + first_entry;
|
||||
int i = 0;
|
||||
struct sg_page_iter sg_iter;
|
||||
dma_addr_t addr = 0; /* shut up gcc */
|
||||
struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
|
||||
struct sgt_iter sgt_iter;
|
||||
gen8_pte_t __iomem *gtt_entries;
|
||||
gen8_pte_t gtt_entry;
|
||||
dma_addr_t addr;
|
||||
int rpm_atomic_seq;
|
||||
int i = 0;
|
||||
|
||||
rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv);
|
||||
|
||||
for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
|
||||
addr = sg_dma_address(sg_iter.sg) +
|
||||
(sg_iter.sg_pgoffset << PAGE_SHIFT);
|
||||
gen8_set_pte(>t_entries[i],
|
||||
gen8_pte_encode(addr, level, true));
|
||||
i++;
|
||||
gtt_entries = (gen8_pte_t __iomem *)ggtt->gsm + (start >> PAGE_SHIFT);
|
||||
|
||||
for_each_sgt_dma(addr, sgt_iter, st) {
|
||||
gtt_entry = gen8_pte_encode(addr, level, true);
|
||||
gen8_set_pte(>t_entries[i++], gtt_entry);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2385,8 +2386,7 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
|
||||
* hardware should work, we must keep this posting read for paranoia.
|
||||
*/
|
||||
if (i != 0)
|
||||
WARN_ON(readq(>t_entries[i-1])
|
||||
!= gen8_pte_encode(addr, level, true));
|
||||
WARN_ON(readq(>t_entries[i-1]) != gtt_entry);
|
||||
|
||||
/* This next bit makes the above posting read even more important. We
|
||||
* want to flush the TLBs only after we're certain all the PTE updates
|
||||
@@ -2436,21 +2436,21 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
|
||||
enum i915_cache_level level, u32 flags)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(vm->dev);
|
||||
struct i915_ggtt *ggtt = &dev_priv->ggtt;
|
||||
unsigned first_entry = start >> PAGE_SHIFT;
|
||||
gen6_pte_t __iomem *gtt_entries =
|
||||
(gen6_pte_t __iomem *)ggtt->gsm + first_entry;
|
||||
int i = 0;
|
||||
struct sg_page_iter sg_iter;
|
||||
dma_addr_t addr = 0;
|
||||
struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
|
||||
struct sgt_iter sgt_iter;
|
||||
gen6_pte_t __iomem *gtt_entries;
|
||||
gen6_pte_t gtt_entry;
|
||||
dma_addr_t addr;
|
||||
int rpm_atomic_seq;
|
||||
int i = 0;
|
||||
|
||||
rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv);
|
||||
|
||||
for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
|
||||
addr = sg_page_iter_dma_address(&sg_iter);
|
||||
iowrite32(vm->pte_encode(addr, level, true, flags), >t_entries[i]);
|
||||
i++;
|
||||
gtt_entries = (gen6_pte_t __iomem *)ggtt->gsm + (start >> PAGE_SHIFT);
|
||||
|
||||
for_each_sgt_dma(addr, sgt_iter, st) {
|
||||
gtt_entry = vm->pte_encode(addr, level, true, flags);
|
||||
iowrite32(gtt_entry, >t_entries[i++]);
|
||||
}
|
||||
|
||||
/* XXX: This serves as a posting read to make sure that the PTE has
|
||||
@@ -2459,10 +2459,8 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
|
||||
* of NUMA access patterns. Therefore, even with the way we assume
|
||||
* hardware should work, we must keep this posting read for paranoia.
|
||||
*/
|
||||
if (i != 0) {
|
||||
unsigned long gtt = readl(>t_entries[i-1]);
|
||||
WARN_ON(gtt != vm->pte_encode(addr, level, true, flags));
|
||||
}
|
||||
if (i != 0)
|
||||
WARN_ON(readl(>t_entries[i-1]) != gtt_entry);
|
||||
|
||||
/* This next bit makes the above posting read even more important. We
|
||||
* want to flush the TLBs only after we're certain all the PTE updates
|
||||
@@ -2474,13 +2472,20 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
|
||||
assert_rpm_atomic_end(dev_priv, rpm_atomic_seq);
|
||||
}
|
||||
|
||||
static void nop_clear_range(struct i915_address_space *vm,
|
||||
uint64_t start,
|
||||
uint64_t length,
|
||||
bool use_scratch)
|
||||
{
|
||||
}
|
||||
|
||||
static void gen8_ggtt_clear_range(struct i915_address_space *vm,
|
||||
uint64_t start,
|
||||
uint64_t length,
|
||||
bool use_scratch)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(vm->dev);
|
||||
struct i915_ggtt *ggtt = &dev_priv->ggtt;
|
||||
struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
|
||||
unsigned first_entry = start >> PAGE_SHIFT;
|
||||
unsigned num_entries = length >> PAGE_SHIFT;
|
||||
gen8_pte_t scratch_pte, __iomem *gtt_base =
|
||||
@@ -2512,7 +2517,7 @@ static void gen6_ggtt_clear_range(struct i915_address_space *vm,
|
||||
bool use_scratch)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(vm->dev);
|
||||
struct i915_ggtt *ggtt = &dev_priv->ggtt;
|
||||
struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
|
||||
unsigned first_entry = start >> PAGE_SHIFT;
|
||||
unsigned num_entries = length >> PAGE_SHIFT;
|
||||
gen6_pte_t scratch_pte, __iomem *gtt_base =
|
||||
@@ -2727,7 +2732,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
|
||||
i915_address_space_init(&ggtt->base, dev_priv);
|
||||
ggtt->base.total += PAGE_SIZE;
|
||||
|
||||
if (intel_vgpu_active(dev)) {
|
||||
if (intel_vgpu_active(dev_priv)) {
|
||||
ret = intel_vgt_balloon(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -2831,7 +2836,7 @@ void i915_ggtt_cleanup_hw(struct drm_device *dev)
|
||||
i915_gem_cleanup_stolen(dev);
|
||||
|
||||
if (drm_mm_initialized(&ggtt->base.mm)) {
|
||||
if (intel_vgpu_active(dev))
|
||||
if (intel_vgpu_active(dev_priv))
|
||||
intel_vgt_deballoon();
|
||||
|
||||
drm_mm_takedown(&ggtt->base.mm);
|
||||
@@ -3069,14 +3074,17 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
|
||||
|
||||
ret = ggtt_probe_common(dev, ggtt->size);
|
||||
|
||||
ggtt->base.clear_range = gen8_ggtt_clear_range;
|
||||
if (IS_CHERRYVIEW(dev_priv))
|
||||
ggtt->base.insert_entries = gen8_ggtt_insert_entries__BKL;
|
||||
else
|
||||
ggtt->base.insert_entries = gen8_ggtt_insert_entries;
|
||||
ggtt->base.bind_vma = ggtt_bind_vma;
|
||||
ggtt->base.unbind_vma = ggtt_unbind_vma;
|
||||
|
||||
ggtt->base.clear_range = nop_clear_range;
|
||||
if (!USES_FULL_PPGTT(dev_priv))
|
||||
ggtt->base.clear_range = gen8_ggtt_clear_range;
|
||||
|
||||
ggtt->base.insert_entries = gen8_ggtt_insert_entries;
|
||||
if (IS_CHERRYVIEW(dev_priv))
|
||||
ggtt->base.insert_entries = gen8_ggtt_insert_entries__BKL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3219,14 +3227,6 @@ int i915_ggtt_init_hw(struct drm_device *dev)
|
||||
if (intel_iommu_gfx_mapped)
|
||||
DRM_INFO("VT-d active for gfx access\n");
|
||||
#endif
|
||||
/*
|
||||
* i915.enable_ppgtt is read-only, so do an early pass to validate the
|
||||
* user's requested state against the hardware/driver capabilities. We
|
||||
* do this now so that we can print out any log messages once rather
|
||||
* than every time we check intel_enable_ppgtt().
|
||||
*/
|
||||
i915.enable_ppgtt = sanitize_enable_ppgtt(dev, i915.enable_ppgtt);
|
||||
DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915.enable_ppgtt);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -3250,9 +3250,8 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
|
||||
struct i915_ggtt *ggtt = &dev_priv->ggtt;
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct i915_vma *vma;
|
||||
bool flush;
|
||||
|
||||
i915_check_and_clear_faults(dev);
|
||||
i915_check_and_clear_faults(dev_priv);
|
||||
|
||||
/* First fill our portion of the GTT with scratch pages */
|
||||
ggtt->base.clear_range(&ggtt->base, ggtt->base.start, ggtt->base.total,
|
||||
@@ -3260,19 +3259,16 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
|
||||
|
||||
/* Cache flush objects bound into GGTT and rebind them. */
|
||||
list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
|
||||
flush = false;
|
||||
list_for_each_entry(vma, &obj->vma_list, obj_link) {
|
||||
if (vma->vm != &ggtt->base)
|
||||
continue;
|
||||
|
||||
WARN_ON(i915_vma_bind(vma, obj->cache_level,
|
||||
PIN_UPDATE));
|
||||
|
||||
flush = true;
|
||||
}
|
||||
|
||||
if (flush)
|
||||
i915_gem_clflush_object(obj, obj->pin_display);
|
||||
if (obj->pin_display)
|
||||
WARN_ON(i915_gem_object_set_to_gtt_domain(obj, false));
|
||||
}
|
||||
|
||||
if (INTEL_INFO(dev)->gen >= 8) {
|
||||
@@ -3398,9 +3394,11 @@ static struct sg_table *
|
||||
intel_rotate_fb_obj_pages(struct intel_rotation_info *rot_info,
|
||||
struct drm_i915_gem_object *obj)
|
||||
{
|
||||
const size_t n_pages = obj->base.size / PAGE_SIZE;
|
||||
unsigned int size_pages = rot_info->plane[0].width * rot_info->plane[0].height;
|
||||
unsigned int size_pages_uv;
|
||||
struct sg_page_iter sg_iter;
|
||||
struct sgt_iter sgt_iter;
|
||||
dma_addr_t dma_addr;
|
||||
unsigned long i;
|
||||
dma_addr_t *page_addr_list;
|
||||
struct sg_table *st;
|
||||
@@ -3409,7 +3407,7 @@ intel_rotate_fb_obj_pages(struct intel_rotation_info *rot_info,
|
||||
int ret = -ENOMEM;
|
||||
|
||||
/* Allocate a temporary list of source pages for random access. */
|
||||
page_addr_list = drm_malloc_gfp(obj->base.size / PAGE_SIZE,
|
||||
page_addr_list = drm_malloc_gfp(n_pages,
|
||||
sizeof(dma_addr_t),
|
||||
GFP_TEMPORARY);
|
||||
if (!page_addr_list)
|
||||
@@ -3432,11 +3430,10 @@ intel_rotate_fb_obj_pages(struct intel_rotation_info *rot_info,
|
||||
|
||||
/* Populate source page list from the object. */
|
||||
i = 0;
|
||||
for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) {
|
||||
page_addr_list[i] = sg_page_iter_dma_address(&sg_iter);
|
||||
i++;
|
||||
}
|
||||
for_each_sgt_dma(dma_addr, sgt_iter, obj->pages)
|
||||
page_addr_list[i++] = dma_addr;
|
||||
|
||||
GEM_BUG_ON(i != n_pages);
|
||||
st->nents = 0;
|
||||
sg = st->sgl;
|
||||
|
||||
@@ -3634,3 +3631,29 @@ i915_ggtt_view_size(struct drm_i915_gem_object *obj,
|
||||
return obj->base.size;
|
||||
}
|
||||
}
|
||||
|
||||
void __iomem *i915_vma_pin_iomap(struct i915_vma *vma)
|
||||
{
|
||||
void __iomem *ptr;
|
||||
|
||||
lockdep_assert_held(&vma->vm->dev->struct_mutex);
|
||||
if (WARN_ON(!vma->obj->map_and_fenceable))
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
GEM_BUG_ON(!vma->is_ggtt);
|
||||
GEM_BUG_ON((vma->bound & GLOBAL_BIND) == 0);
|
||||
|
||||
ptr = vma->iomap;
|
||||
if (ptr == NULL) {
|
||||
ptr = io_mapping_map_wc(i915_vm_to_ggtt(vma->vm)->mappable,
|
||||
vma->node.start,
|
||||
vma->node.size);
|
||||
if (ptr == NULL)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
vma->iomap = ptr;
|
||||
}
|
||||
|
||||
vma->pin_count++;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#ifndef __I915_GEM_GTT_H__
|
||||
#define __I915_GEM_GTT_H__
|
||||
|
||||
#include <linux/io-mapping.h>
|
||||
|
||||
struct drm_i915_file_private;
|
||||
|
||||
typedef uint32_t gen6_pte_t;
|
||||
@@ -175,6 +177,7 @@ struct i915_vma {
|
||||
struct drm_mm_node node;
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct i915_address_space *vm;
|
||||
void __iomem *iomap;
|
||||
|
||||
/** Flags and address space this VMA is bound to */
|
||||
#define GLOBAL_BIND (1<<0)
|
||||
@@ -518,9 +521,7 @@ int i915_ggtt_enable_hw(struct drm_device *dev);
|
||||
void i915_gem_init_ggtt(struct drm_device *dev);
|
||||
void i915_ggtt_cleanup_hw(struct drm_device *dev);
|
||||
|
||||
int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt);
|
||||
int i915_ppgtt_init_hw(struct drm_device *dev);
|
||||
int i915_ppgtt_init_ring(struct drm_i915_gem_request *req);
|
||||
void i915_ppgtt_release(struct kref *kref);
|
||||
struct i915_hw_ppgtt *i915_ppgtt_create(struct drm_device *dev,
|
||||
struct drm_i915_file_private *fpriv);
|
||||
@@ -535,7 +536,7 @@ static inline void i915_ppgtt_put(struct i915_hw_ppgtt *ppgtt)
|
||||
kref_put(&ppgtt->ref, i915_ppgtt_release);
|
||||
}
|
||||
|
||||
void i915_check_and_clear_faults(struct drm_device *dev);
|
||||
void i915_check_and_clear_faults(struct drm_i915_private *dev_priv);
|
||||
void i915_gem_suspend_gtt_mappings(struct drm_device *dev);
|
||||
void i915_gem_restore_gtt_mappings(struct drm_device *dev);
|
||||
|
||||
@@ -560,4 +561,36 @@ size_t
|
||||
i915_ggtt_view_size(struct drm_i915_gem_object *obj,
|
||||
const struct i915_ggtt_view *view);
|
||||
|
||||
/**
|
||||
* i915_vma_pin_iomap - calls ioremap_wc to map the GGTT VMA via the aperture
|
||||
* @vma: VMA to iomap
|
||||
*
|
||||
* The passed in VMA has to be pinned in the global GTT mappable region.
|
||||
* An extra pinning of the VMA is acquired for the return iomapping,
|
||||
* the caller must call i915_vma_unpin_iomap to relinquish the pinning
|
||||
* after the iomapping is no longer required.
|
||||
*
|
||||
* Callers must hold the struct_mutex.
|
||||
*
|
||||
* Returns a valid iomapped pointer or ERR_PTR.
|
||||
*/
|
||||
void __iomem *i915_vma_pin_iomap(struct i915_vma *vma);
|
||||
|
||||
/**
|
||||
* i915_vma_unpin_iomap - unpins the mapping returned from i915_vma_iomap
|
||||
* @vma: VMA to unpin
|
||||
*
|
||||
* Unpins the previously iomapped VMA from i915_vma_pin_iomap().
|
||||
*
|
||||
* Callers must hold the struct_mutex. This function is only valid to be
|
||||
* called on a VMA previously iomapped by the caller with i915_vma_pin_iomap().
|
||||
*/
|
||||
static inline void i915_vma_unpin_iomap(struct i915_vma *vma)
|
||||
{
|
||||
lockdep_assert_held(&vma->vm->dev->struct_mutex);
|
||||
GEM_BUG_ON(vma->pin_count == 0);
|
||||
GEM_BUG_ON(vma->iomap == NULL);
|
||||
vma->pin_count--;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "intel_renderstate.h"
|
||||
|
||||
static const struct intel_renderstate_rodata *
|
||||
render_state_get_rodata(struct drm_device *dev, const int gen)
|
||||
render_state_get_rodata(const int gen)
|
||||
{
|
||||
switch (gen) {
|
||||
case 6:
|
||||
@@ -45,21 +45,22 @@ render_state_get_rodata(struct drm_device *dev, const int gen)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int render_state_init(struct render_state *so, struct drm_device *dev)
|
||||
static int render_state_init(struct render_state *so,
|
||||
struct drm_i915_private *dev_priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
so->gen = INTEL_INFO(dev)->gen;
|
||||
so->rodata = render_state_get_rodata(dev, so->gen);
|
||||
so->gen = INTEL_GEN(dev_priv);
|
||||
so->rodata = render_state_get_rodata(so->gen);
|
||||
if (so->rodata == NULL)
|
||||
return 0;
|
||||
|
||||
if (so->rodata->batch_items * 4 > 4096)
|
||||
return -EINVAL;
|
||||
|
||||
so->obj = i915_gem_alloc_object(dev, 4096);
|
||||
if (so->obj == NULL)
|
||||
return -ENOMEM;
|
||||
so->obj = i915_gem_object_create(dev_priv->dev, 4096);
|
||||
if (IS_ERR(so->obj))
|
||||
return PTR_ERR(so->obj);
|
||||
|
||||
ret = i915_gem_obj_ggtt_pin(so->obj, 4096, 0);
|
||||
if (ret)
|
||||
@@ -177,7 +178,7 @@ int i915_gem_render_state_prepare(struct intel_engine_cs *engine,
|
||||
if (WARN_ON(engine->id != RCS))
|
||||
return -ENOENT;
|
||||
|
||||
ret = render_state_init(so, engine->dev);
|
||||
ret = render_state_init(so, engine->i915);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -131,7 +131,16 @@ i915_gem_shrink(struct drm_i915_private *dev_priv,
|
||||
unsigned long count = 0;
|
||||
|
||||
trace_i915_gem_shrink(dev_priv, target, flags);
|
||||
i915_gem_retire_requests(dev_priv->dev);
|
||||
i915_gem_retire_requests(dev_priv);
|
||||
|
||||
/*
|
||||
* Unbinding of objects will require HW access; Let us not wake the
|
||||
* device just to recover a little memory. If absolutely necessary,
|
||||
* we will force the wake during oom-notifier.
|
||||
*/
|
||||
if ((flags & I915_SHRINK_BOUND) &&
|
||||
!intel_runtime_pm_get_if_in_use(dev_priv))
|
||||
flags &= ~I915_SHRINK_BOUND;
|
||||
|
||||
/*
|
||||
* As we may completely rewrite the (un)bound list whilst unbinding
|
||||
@@ -197,7 +206,10 @@ i915_gem_shrink(struct drm_i915_private *dev_priv,
|
||||
list_splice(&still_in_list, phase->list);
|
||||
}
|
||||
|
||||
i915_gem_retire_requests(dev_priv->dev);
|
||||
if (flags & I915_SHRINK_BOUND)
|
||||
intel_runtime_pm_put(dev_priv);
|
||||
|
||||
i915_gem_retire_requests(dev_priv);
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -345,7 +357,9 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr)
|
||||
if (!i915_gem_shrinker_lock_uninterruptible(dev_priv, &slu, 5000))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
intel_runtime_pm_get(dev_priv);
|
||||
freed_pages = i915_gem_shrink_all(dev_priv);
|
||||
intel_runtime_pm_put(dev_priv);
|
||||
|
||||
/* Because we may be allocating inside our own driver, we cannot
|
||||
* assert that there are no objects with pinned pages that are not
|
||||
@@ -386,17 +400,35 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr
|
||||
struct drm_i915_private *dev_priv =
|
||||
container_of(nb, struct drm_i915_private, mm.vmap_notifier);
|
||||
struct shrinker_lock_uninterruptible slu;
|
||||
unsigned long freed_pages;
|
||||
struct i915_vma *vma, *next;
|
||||
unsigned long freed_pages = 0;
|
||||
int ret;
|
||||
|
||||
if (!i915_gem_shrinker_lock_uninterruptible(dev_priv, &slu, 5000))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
freed_pages = i915_gem_shrink(dev_priv, -1UL,
|
||||
I915_SHRINK_BOUND |
|
||||
I915_SHRINK_UNBOUND |
|
||||
I915_SHRINK_ACTIVE |
|
||||
I915_SHRINK_VMAPS);
|
||||
/* Force everything onto the inactive lists */
|
||||
ret = i915_gpu_idle(dev_priv->dev);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
intel_runtime_pm_get(dev_priv);
|
||||
freed_pages += i915_gem_shrink(dev_priv, -1UL,
|
||||
I915_SHRINK_BOUND |
|
||||
I915_SHRINK_UNBOUND |
|
||||
I915_SHRINK_ACTIVE |
|
||||
I915_SHRINK_VMAPS);
|
||||
intel_runtime_pm_put(dev_priv);
|
||||
|
||||
/* We also want to clear any cached iomaps as they wrap vmap */
|
||||
list_for_each_entry_safe(vma, next,
|
||||
&dev_priv->ggtt.base.inactive_list, vm_link) {
|
||||
unsigned long count = vma->node.size >> PAGE_SHIFT;
|
||||
if (vma->iomap && i915_vma_unbind(vma) == 0)
|
||||
freed_pages += count;
|
||||
}
|
||||
|
||||
out:
|
||||
i915_gem_shrinker_unlock_uninterruptible(dev_priv, &slu);
|
||||
|
||||
*(unsigned long *)ptr += freed_pages;
|
||||
|
||||
@@ -56,7 +56,7 @@ int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *dev_priv,
|
||||
|
||||
/* See the comment at the drm_mm_init() call for more about this check.
|
||||
* WaSkipStolenMemoryFirstPage:bdw,chv (incomplete) */
|
||||
if (INTEL_INFO(dev_priv)->gen == 8 && start < 4096)
|
||||
if (IS_GEN8(dev_priv) && start < 4096)
|
||||
start = 4096;
|
||||
|
||||
mutex_lock(&dev_priv->mm.stolen_lock);
|
||||
@@ -109,9 +109,9 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev)
|
||||
if (INTEL_INFO(dev)->gen >= 3) {
|
||||
u32 bsm;
|
||||
|
||||
pci_read_config_dword(dev->pdev, BSM, &bsm);
|
||||
pci_read_config_dword(dev->pdev, INTEL_BSM, &bsm);
|
||||
|
||||
base = bsm & BSM_MASK;
|
||||
base = bsm & INTEL_BSM_MASK;
|
||||
} else if (IS_I865G(dev)) {
|
||||
u16 toud = 0;
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode)
|
||||
if (INTEL_INFO(obj->base.dev)->gen >= 4)
|
||||
return true;
|
||||
|
||||
if (INTEL_INFO(obj->base.dev)->gen == 3) {
|
||||
if (IS_GEN3(obj->base.dev)) {
|
||||
if (i915_gem_obj_ggtt_offset(obj) & ~I915_FENCE_START_MASK)
|
||||
return false;
|
||||
} else {
|
||||
@@ -229,7 +229,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
|
||||
*/
|
||||
if (obj->map_and_fenceable &&
|
||||
!i915_gem_object_fence_ok(obj, args->tiling_mode))
|
||||
ret = i915_gem_object_ggtt_unbind(obj);
|
||||
ret = i915_vma_unbind(i915_gem_obj_to_ggtt(obj));
|
||||
|
||||
if (ret == 0) {
|
||||
if (obj->pages &&
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user