Commit fd172d0c authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-next-2014-11-07-fixups' of...

Merge tag 'drm-intel-next-2014-11-07-fixups' of git://anongit.freedesktop.org/drm-intel into drm-next

- skl watermarks code (Damien, Vandana, Pradeep)
- reworked audio codec /eld handling code (Jani)
- rework the mmio_flip code to use the vblank evade logic and wait for rendering
  using the standard wait_seqno interface (Ander)
- skl forcewake support (Zhe Wang)
- refactor the chv interrupt code to use functions shared with vlv (Ville)
- prep work for different global gtt views (Tvrtko Ursulin)
- precompute the display PLL config before touching hw state (Ander)
- completely reworked panel power sequencer code for chv/vlv (Ville)
- pre work to split the plane update code into a prepare and commit phase
  (Gustavo Padovan)
- golden context for skl (Armin Reese)
- as usual tons of fixes and improvements all over

* tag 'drm-intel-next-2014-11-07-fixups' of git://anongit.freedesktop.org/drm-intel: (135 commits)
  drm/i915: Use correct pipe config to update pll dividers. V2
  drm/i915: Plug memory leak in intel_shared_dpll_start_config()
  drm/i915: Update DRIVER_DATE to 20141107
  drm/i915: Add gen to the gpu hang ecode
  drm/i915: Cache HPLL frequency on VLV/CHV
  Revert "drm/i915/vlv: Remove check for Old Ack during forcewake"
  drm/i915: Make mmio flip wait for seqno in the work function
  drm/i915: Make __wait_seqno non-static and rename to __i915_wait_seqno
  drm/i915: Move the .global_resources() hook call into modeset_update_crtc_power_domains()
  drm/i915/audio: add DOC comment describing HDA over HDMI/DP
  drm/i915: make pipe/port based audio valid accessors easier to use
  drm/i915/audio: add audio codec enable debug log for g4x
  drm/i915/audio: add audio codec disable on g4x
  drm/i915: enable audio codec after port
  drm/i915/audio: add vlv/chv/gen5-7 audio codec disable sequence
  drm/i915/audio: rewrite vlv/chv and gen 5-7 audio codec enable sequence
  drm/i915/skl: Enable Gen9 RC6
  drm/i915/skl: Gen9 Forcewake
  drm/i915/skl: Log the order in which we flush the pipes in the WM code
  drm/i915/skl: Flush the WM configuration
  ...
parents b853fdb3 e1f234bd
...@@ -3887,6 +3887,11 @@ int num_ioctls;</synopsis> ...@@ -3887,6 +3887,11 @@ int num_ioctls;</synopsis>
probing, so those sections fully apply. probing, so those sections fully apply.
</para> </para>
</sect2> </sect2>
<sect2>
<title>High Definition Audio</title>
!Pdrivers/gpu/drm/i915/intel_audio.c High Definition Audio over HDMI and Display Port
!Idrivers/gpu/drm/i915/intel_audio.c
</sect2>
<sect2> <sect2>
<title>DPIO</title> <title>DPIO</title>
!Pdrivers/gpu/drm/i915/i915_reg.h DPIO !Pdrivers/gpu/drm/i915/i915_reg.h DPIO
......
...@@ -155,6 +155,11 @@ int drm_plane_helper_check_update(struct drm_plane *plane, ...@@ -155,6 +155,11 @@ int drm_plane_helper_check_update(struct drm_plane *plane,
return -ERANGE; return -ERANGE;
} }
if (!fb) {
*visible = false;
return 0;
}
*visible = drm_rect_clip_scaled(src, dest, clip, hscale, vscale); *visible = drm_rect_clip_scaled(src, dest, clip, hscale, vscale);
if (!*visible) if (!*visible)
/* /*
......
...@@ -40,10 +40,12 @@ i915-y += i915_cmd_parser.o \ ...@@ -40,10 +40,12 @@ i915-y += i915_cmd_parser.o \
# autogenerated null render state # autogenerated null render state
i915-y += intel_renderstate_gen6.o \ i915-y += intel_renderstate_gen6.o \
intel_renderstate_gen7.o \ intel_renderstate_gen7.o \
intel_renderstate_gen8.o intel_renderstate_gen8.o \
intel_renderstate_gen9.o
# modesetting core code # modesetting core code
i915-y += intel_bios.o \ i915-y += intel_audio.o \
intel_bios.o \
intel_display.o \ intel_display.o \
intel_fifo_underrun.o \ intel_fifo_underrun.o \
intel_frontbuffer.o \ intel_frontbuffer.o \
......
...@@ -138,6 +138,11 @@ static const struct drm_i915_cmd_descriptor common_cmds[] = { ...@@ -138,6 +138,11 @@ static const struct drm_i915_cmd_descriptor common_cmds[] = {
.mask = MI_GLOBAL_GTT, .mask = MI_GLOBAL_GTT,
.expected = 0, .expected = 0,
}}, ), }}, ),
/*
* MI_BATCH_BUFFER_START requires some special handling. It's not
* really a 'skip' action but it doesn't seem like it's worth adding
* a new action. See i915_parse_cmds().
*/
CMD( MI_BATCH_BUFFER_START, SMI, !F, 0xFF, S ), CMD( MI_BATCH_BUFFER_START, SMI, !F, 0xFF, S ),
}; };
...@@ -955,7 +960,8 @@ static bool check_cmd(const struct intel_engine_cs *ring, ...@@ -955,7 +960,8 @@ static bool check_cmd(const struct intel_engine_cs *ring,
* Parses the specified batch buffer looking for privilege violations as * Parses the specified batch buffer looking for privilege violations as
* described in the overview. * described in the overview.
* *
* Return: non-zero if the parser finds violations or otherwise fails * Return: non-zero if the parser finds violations or otherwise fails; -EACCES
* if the batch appears legal but should use hardware parsing
*/ */
int i915_parse_cmds(struct intel_engine_cs *ring, int i915_parse_cmds(struct intel_engine_cs *ring,
struct drm_i915_gem_object *batch_obj, struct drm_i915_gem_object *batch_obj,
...@@ -1002,6 +1008,16 @@ int i915_parse_cmds(struct intel_engine_cs *ring, ...@@ -1002,6 +1008,16 @@ int i915_parse_cmds(struct intel_engine_cs *ring,
break; break;
} }
/*
* If the batch buffer contains a chained batch, return an
* error that tells the caller to abort and dispatch the
* workload as a non-secure batch.
*/
if (desc->cmd.value == MI_BATCH_BUFFER_START) {
ret = -EACCES;
break;
}
if (desc->flags & CMD_DESC_FIXED) if (desc->flags & CMD_DESC_FIXED)
length = desc->length.fixed; length = desc->length.fixed;
else else
......
...@@ -116,7 +116,7 @@ static const char *get_tiling_flag(struct drm_i915_gem_object *obj) ...@@ -116,7 +116,7 @@ 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 inline const char *get_global_flag(struct drm_i915_gem_object *obj)
{ {
return obj->has_global_gtt_mapping ? "g" : " "; return i915_gem_obj_to_ggtt(obj) ? "g" : " ";
} }
static void static void
...@@ -2630,14 +2630,15 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused) ...@@ -2630,14 +2630,15 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
seq_printf(m, "DPLL%i: %s, id: %i\n", i, pll->name, pll->id); seq_printf(m, "DPLL%i: %s, id: %i\n", i, pll->name, pll->id);
seq_printf(m, " refcount: %i, active: %i, on: %s\n", pll->refcount, seq_printf(m, " crtc_mask: 0x%08x, active: %d, on: %s\n",
pll->active, yesno(pll->on)); pll->config.crtc_mask, pll->active, yesno(pll->on));
seq_printf(m, " tracked hardware state:\n"); seq_printf(m, " tracked hardware state:\n");
seq_printf(m, " dpll: 0x%08x\n", pll->hw_state.dpll); seq_printf(m, " dpll: 0x%08x\n", pll->config.hw_state.dpll);
seq_printf(m, " dpll_md: 0x%08x\n", pll->hw_state.dpll_md); seq_printf(m, " dpll_md: 0x%08x\n",
seq_printf(m, " fp0: 0x%08x\n", pll->hw_state.fp0); pll->config.hw_state.dpll_md);
seq_printf(m, " fp1: 0x%08x\n", pll->hw_state.fp1); seq_printf(m, " fp0: 0x%08x\n", pll->config.hw_state.fp0);
seq_printf(m, " wrpll: 0x%08x\n", pll->hw_state.wrpll); seq_printf(m, " fp1: 0x%08x\n", pll->config.hw_state.fp1);
seq_printf(m, " wrpll: 0x%08x\n", pll->config.hw_state.wrpll);
} }
drm_modeset_unlock_all(dev); drm_modeset_unlock_all(dev);
...@@ -2678,6 +2679,42 @@ static int i915_wa_registers(struct seq_file *m, void *unused) ...@@ -2678,6 +2679,42 @@ static int i915_wa_registers(struct seq_file *m, void *unused)
return 0; return 0;
} }
static int i915_ddb_info(struct seq_file *m, void *unused)
{
struct drm_info_node *node = m->private;
struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct skl_ddb_allocation *ddb;
struct skl_ddb_entry *entry;
enum pipe pipe;
int plane;
drm_modeset_lock_all(dev);
ddb = &dev_priv->wm.skl_hw.ddb;
seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
for_each_pipe(dev_priv, pipe) {
seq_printf(m, "Pipe %c\n", pipe_name(pipe));
for_each_plane(pipe, plane) {
entry = &ddb->plane[pipe][plane];
seq_printf(m, " Plane%-8d%8u%8u%8u\n", plane + 1,
entry->start, entry->end,
skl_ddb_entry_size(entry));
}
entry = &ddb->cursor[pipe];
seq_printf(m, " %-13s%8u%8u%8u\n", "Cursor", entry->start,
entry->end, skl_ddb_entry_size(entry));
}
drm_modeset_unlock_all(dev);
return 0;
}
struct pipe_crc_info { struct pipe_crc_info {
const char *name; const char *name;
struct drm_device *dev; struct drm_device *dev;
...@@ -2971,6 +3008,8 @@ static int i9xx_pipe_crc_auto_source(struct drm_device *dev, enum pipe pipe, ...@@ -2971,6 +3008,8 @@ static int i9xx_pipe_crc_auto_source(struct drm_device *dev, enum pipe pipe,
break; break;
} }
break; break;
default:
break;
} }
} }
drm_modeset_unlock_all(dev); drm_modeset_unlock_all(dev);
...@@ -3520,7 +3559,7 @@ static const struct file_operations i915_display_crc_ctl_fops = { ...@@ -3520,7 +3559,7 @@ static const struct file_operations i915_display_crc_ctl_fops = {
.write = display_crc_ctl_write .write = display_crc_ctl_write
}; };
static void wm_latency_show(struct seq_file *m, const uint16_t wm[5]) static void wm_latency_show(struct seq_file *m, const uint16_t wm[8])
{ {
struct drm_device *dev = m->private; struct drm_device *dev = m->private;
int num_levels = ilk_wm_max_level(dev) + 1; int num_levels = ilk_wm_max_level(dev) + 1;
...@@ -3531,13 +3570,17 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[5]) ...@@ -3531,13 +3570,17 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[5])
for (level = 0; level < num_levels; level++) { for (level = 0; level < num_levels; level++) {
unsigned int latency = wm[level]; unsigned int latency = wm[level];
/* WM1+ latency values in 0.5us units */ /*
if (level > 0) * - WM1+ latency values in 0.5us units
* - latencies are in us on gen9
*/
if (INTEL_INFO(dev)->gen >= 9)
latency *= 10;
else if (level > 0)
latency *= 5; latency *= 5;
seq_printf(m, "WM%d %u (%u.%u usec)\n", seq_printf(m, "WM%d %u (%u.%u usec)\n",
level, wm[level], level, wm[level], latency / 10, latency % 10);
latency / 10, latency % 10);
} }
drm_modeset_unlock_all(dev); drm_modeset_unlock_all(dev);
...@@ -3546,8 +3589,15 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[5]) ...@@ -3546,8 +3589,15 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[5])
static int pri_wm_latency_show(struct seq_file *m, void *data) static int pri_wm_latency_show(struct seq_file *m, void *data)
{ {
struct drm_device *dev = m->private; struct drm_device *dev = m->private;
struct drm_i915_private *dev_priv = dev->dev_private;
const uint16_t *latencies;
if (INTEL_INFO(dev)->gen >= 9)
latencies = dev_priv->wm.skl_latency;
else
latencies = to_i915(dev)->wm.pri_latency;
wm_latency_show(m, to_i915(dev)->wm.pri_latency); wm_latency_show(m, latencies);
return 0; return 0;
} }
...@@ -3555,8 +3605,15 @@ static int pri_wm_latency_show(struct seq_file *m, void *data) ...@@ -3555,8 +3605,15 @@ static int pri_wm_latency_show(struct seq_file *m, void *data)
static int spr_wm_latency_show(struct seq_file *m, void *data) static int spr_wm_latency_show(struct seq_file *m, void *data)
{ {
struct drm_device *dev = m->private; struct drm_device *dev = m->private;
struct drm_i915_private *dev_priv = dev->dev_private;
const uint16_t *latencies;
if (INTEL_INFO(dev)->gen >= 9)
latencies = dev_priv->wm.skl_latency;
else
latencies = to_i915(dev)->wm.spr_latency;
wm_latency_show(m, to_i915(dev)->wm.spr_latency); wm_latency_show(m, latencies);
return 0; return 0;
} }
...@@ -3564,8 +3621,15 @@ static int spr_wm_latency_show(struct seq_file *m, void *data) ...@@ -3564,8 +3621,15 @@ static int spr_wm_latency_show(struct seq_file *m, void *data)
static int cur_wm_latency_show(struct seq_file *m, void *data) static int cur_wm_latency_show(struct seq_file *m, void *data)
{ {
struct drm_device *dev = m->private; struct drm_device *dev = m->private;
struct drm_i915_private *dev_priv = dev->dev_private;
const uint16_t *latencies;
wm_latency_show(m, to_i915(dev)->wm.cur_latency); if (INTEL_INFO(dev)->gen >= 9)
latencies = dev_priv->wm.skl_latency;
else
latencies = to_i915(dev)->wm.cur_latency;
wm_latency_show(m, latencies);
return 0; return 0;
} }
...@@ -3601,11 +3665,11 @@ static int cur_wm_latency_open(struct inode *inode, struct file *file) ...@@ -3601,11 +3665,11 @@ static int cur_wm_latency_open(struct inode *inode, struct file *file)
} }
static ssize_t wm_latency_write(struct file *file, const char __user *ubuf, static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
size_t len, loff_t *offp, uint16_t wm[5]) size_t len, loff_t *offp, uint16_t wm[8])
{ {
struct seq_file *m = file->private_data; struct seq_file *m = file->private_data;
struct drm_device *dev = m->private; struct drm_device *dev = m->private;
uint16_t new[5] = { 0 }; uint16_t new[8] = { 0 };
int num_levels = ilk_wm_max_level(dev) + 1; int num_levels = ilk_wm_max_level(dev) + 1;
int level; int level;
int ret; int ret;
...@@ -3619,7 +3683,9 @@ static ssize_t wm_latency_write(struct file *file, const char __user *ubuf, ...@@ -3619,7 +3683,9 @@ static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
tmp[len] = '\0'; tmp[len] = '\0';
ret = sscanf(tmp, "%hu %hu %hu %hu %hu", &new[0], &new[1], &new[2], &new[3], &new[4]); ret = sscanf(tmp, "%hu %hu %hu %hu %hu %hu %hu %hu",
&new[0], &new[1], &new[2], &new[3],
&new[4], &new[5], &new[6], &new[7]);
if (ret != num_levels) if (ret != num_levels)
return -EINVAL; return -EINVAL;
...@@ -3639,8 +3705,15 @@ static ssize_t pri_wm_latency_write(struct file *file, const char __user *ubuf, ...@@ -3639,8 +3705,15 @@ static ssize_t pri_wm_latency_write(struct file *file, const char __user *ubuf,
{ {
struct seq_file *m = file->private_data; struct seq_file *m = file->private_data;
struct drm_device *dev = m->private; struct drm_device *dev = m->private;
struct drm_i915_private *dev_priv = dev->dev_private;
uint16_t *latencies;
return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.pri_latency); if (INTEL_INFO(dev)->gen >= 9)
latencies = dev_priv->wm.skl_latency;
else
latencies = to_i915(dev)->wm.pri_latency;
return wm_latency_write(file, ubuf, len, offp, latencies);
} }
static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf, static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf,
...@@ -3648,8 +3721,15 @@ static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf, ...@@ -3648,8 +3721,15 @@ static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf,
{ {
struct seq_file *m = file->private_data; struct seq_file *m = file->private_data;
struct drm_device *dev = m->private; struct drm_device *dev = m->private;
struct drm_i915_private *dev_priv = dev->dev_private;
uint16_t *latencies;
return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.spr_latency); if (INTEL_INFO(dev)->gen >= 9)
latencies = dev_priv->wm.skl_latency;
else
latencies = to_i915(dev)->wm.spr_latency;
return wm_latency_write(file, ubuf, len, offp, latencies);
} }
static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf, static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
...@@ -3657,8 +3737,15 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf, ...@@ -3657,8 +3737,15 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
{ {
struct seq_file *m = file->private_data; struct seq_file *m = file->private_data;
struct drm_device *dev = m->private; struct drm_device *dev = m->private;
struct drm_i915_private *dev_priv = dev->dev_private;
uint16_t *latencies;
if (INTEL_INFO(dev)->gen >= 9)
latencies = dev_priv->wm.skl_latency;
else
latencies = to_i915(dev)->wm.cur_latency;
return wm_latency_write(file, ubuf, len, offp, to_i915(dev)->wm.cur_latency); return wm_latency_write(file, ubuf, len, offp, latencies);
} }
static const struct file_operations i915_pri_wm_latency_fops = { static const struct file_operations i915_pri_wm_latency_fops = {
...@@ -4201,6 +4288,7 @@ static const struct drm_info_list i915_debugfs_list[] = { ...@@ -4201,6 +4288,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_shared_dplls_info", i915_shared_dplls_info, 0}, {"i915_shared_dplls_info", i915_shared_dplls_info, 0},
{"i915_dp_mst_info", i915_dp_mst_info, 0}, {"i915_dp_mst_info", i915_dp_mst_info, 0},
{"i915_wa_registers", i915_wa_registers, 0}, {"i915_wa_registers", i915_wa_registers, 0},
{"i915_ddb_info", i915_ddb_info, 0},
}; };
#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
......
...@@ -551,8 +551,8 @@ static void intel_suspend_encoders(struct drm_i915_private *dev_priv) ...@@ -551,8 +551,8 @@ static void intel_suspend_encoders(struct drm_i915_private *dev_priv)
} }
static int intel_suspend_complete(struct drm_i915_private *dev_priv); static int intel_suspend_complete(struct drm_i915_private *dev_priv);
static int intel_resume_prepare(struct drm_i915_private *dev_priv, static int vlv_resume_prepare(struct drm_i915_private *dev_priv,
bool rpm_resume); bool rpm_resume);
static int i915_drm_suspend(struct drm_device *dev) static int i915_drm_suspend(struct drm_device *dev)
{ {
...@@ -744,7 +744,7 @@ static int i915_drm_resume(struct drm_device *dev) ...@@ -744,7 +744,7 @@ static int i915_drm_resume(struct drm_device *dev)
static int i915_drm_resume_early(struct drm_device *dev) static int i915_drm_resume_early(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
int ret; int ret = 0;
/* /*
* We have a resume ordering issue with the snd-hda driver also * We have a resume ordering issue with the snd-hda driver also
...@@ -760,11 +760,16 @@ static int i915_drm_resume_early(struct drm_device *dev) ...@@ -760,11 +760,16 @@ static int i915_drm_resume_early(struct drm_device *dev)
pci_set_master(dev->pdev); pci_set_master(dev->pdev);
ret = intel_resume_prepare(dev_priv, false); if (IS_VALLEYVIEW(dev_priv))
ret = vlv_resume_prepare(dev_priv, false);
if (ret) if (ret)
DRM_ERROR("Resume prepare failed: %d,Continuing resume\n", ret); DRM_ERROR("Resume prepare failed: %d,Continuing resume\n", ret);
intel_uncore_early_sanitize(dev, true); intel_uncore_early_sanitize(dev, true);
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
hsw_disable_pc8(dev_priv);
intel_uncore_sanitize(dev); intel_uncore_sanitize(dev);
intel_power_domains_init_hw(dev_priv); intel_power_domains_init_hw(dev_priv);
...@@ -986,25 +991,6 @@ static int hsw_suspend_complete(struct drm_i915_private *dev_priv) ...@@ -986,25 +991,6 @@ static int hsw_suspend_complete(struct drm_i915_private *dev_priv)
return 0; return 0;
} }
static int snb_resume_prepare(struct drm_i915_private *dev_priv,
bool rpm_resume)
{
struct drm_device *dev = dev_priv->dev;
if (rpm_resume)
intel_init_pch_refclk(dev);
return 0;
}
static int hsw_resume_prepare(struct drm_i915_private *dev_priv,
bool rpm_resume)
{
hsw_disable_pc8(dev_priv);
return 0;
}
/* /*
* Save all Gunit registers that may be lost after a D3 and a subsequent * 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 * S0i[R123] transition. The list of registers needing a save/restore is
...@@ -1409,13 +1395,9 @@ static int intel_runtime_suspend(struct device *device) ...@@ -1409,13 +1395,9 @@ static int intel_runtime_suspend(struct device *device)
i915_gem_release_all_mmaps(dev_priv); i915_gem_release_all_mmaps(dev_priv);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
/* flush_delayed_work(&dev_priv->rps.delayed_resume_work);
* rps.work can't be rearmed here, since we get here only after making
* sure the GPU is idle and the RPS freq is set to the minimum. See
* intel_mark_idle().
*/
cancel_work_sync(&dev_priv->rps.work);
intel_runtime_pm_disable_interrupts(dev_priv); intel_runtime_pm_disable_interrupts(dev_priv);
intel_suspend_gt_powersave(dev);
ret = intel_suspend_complete(dev_priv); ret = intel_suspend_complete(dev_priv);
if (ret) { if (ret) {
...@@ -1462,7 +1444,7 @@ static int intel_runtime_resume(struct device *device) ...@@ -1462,7 +1444,7 @@ static int intel_runtime_resume(struct device *device)
struct pci_dev *pdev = to_pci_dev(device); struct pci_dev *pdev = to_pci_dev(device);
struct drm_device *dev = pci_get_drvdata(pdev); struct drm_device *dev = pci_get_drvdata(pdev);
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
int ret; int ret = 0;
if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev))) if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev)))
return -ENODEV; return -ENODEV;
...@@ -1472,7 +1454,13 @@ static int intel_runtime_resume(struct device *device) ...@@ -1472,7 +1454,13 @@ static int intel_runtime_resume(struct device *device)
intel_opregion_notify_adapter(dev, PCI_D0); intel_opregion_notify_adapter(dev, PCI_D0);
dev_priv->pm.suspended = false; dev_priv->pm.suspended = false;
ret = intel_resume_prepare(dev_priv, true); if (IS_GEN6(dev_priv))
intel_init_pch_refclk(dev);
else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
hsw_disable_pc8(dev_priv);
else if (IS_VALLEYVIEW(dev_priv))
ret = vlv_resume_prepare(dev_priv, true);
/* /*
* No point of rolling back things in case of an error, as the best * No point of rolling back things in case of an error, as the best
* we can do is to hope that things will still work (and disable RPM). * we can do is to hope that things will still work (and disable RPM).
...@@ -1481,7 +1469,7 @@ static int intel_runtime_resume(struct device *device) ...@@ -1481,7 +1469,7 @@ static int intel_runtime_resume(struct device *device)
gen6_update_ring_freq(dev); gen6_update_ring_freq(dev);
intel_runtime_pm_enable_interrupts(dev_priv); intel_runtime_pm_enable_interrupts(dev_priv);
intel_reset_gt_powersave(dev); intel_enable_gt_powersave(dev);
if (ret) if (ret)
DRM_ERROR("Runtime resume failed, disabling it (%d)\n", ret); DRM_ERROR("Runtime resume failed, disabling it (%d)\n", ret);
...@@ -1510,29 +1498,6 @@ static int intel_suspend_complete(struct drm_i915_private *dev_priv) ...@@ -1510,29 +1498,6 @@ static int intel_suspend_complete(struct drm_i915_private *dev_priv)
return ret; return ret;
} }
/*
* This function implements common functionality of runtime and system
* resume sequence. Variable rpm_resume used for implementing different
* code paths.
*/
static int intel_resume_prepare(struct drm_i915_private *dev_priv,
bool rpm_resume)
{
struct drm_device *dev = dev_priv->dev;
int ret;
if (IS_GEN6(dev))
ret = snb_resume_prepare(dev_priv, rpm_resume);
else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
ret = hsw_resume_prepare(dev_priv, rpm_resume);
else if (IS_VALLEYVIEW(dev))
ret = vlv_resume_prepare(dev_priv, rpm_resume);
else
ret = 0;
return ret;
}
static const struct dev_pm_ops i915_pm_ops = { static const struct dev_pm_ops i915_pm_ops = {
/* /*
* S0ix (via system suspend) and S3 event handlers [PMSG_SUSPEND, * S0ix (via system suspend) and S3 event handlers [PMSG_SUSPEND,
......
...@@ -55,7 +55,10 @@ ...@@ -55,7 +55,10 @@
#define DRIVER_NAME "i915" #define DRIVER_NAME "i915"
#define DRIVER_DESC "Intel Graphics" #define DRIVER_DESC "Intel Graphics"
#define DRIVER_DATE "20141024" #define DRIVER_DATE "20141107"
#undef WARN_ON
#define WARN_ON(x) WARN(x, "WARN_ON(" #x ")")
enum pipe { enum pipe {
INVALID_PIPE = -1, INVALID_PIPE = -1,
...@@ -226,14 +229,20 @@ struct intel_dpll_hw_state { ...@@ -226,14 +229,20 @@ struct intel_dpll_hw_state {
uint32_t wrpll; uint32_t wrpll;
}; };
struct intel_shared_dpll_config {
unsigned crtc_mask; /* mask of CRTCs sharing this PLL */
struct intel_dpll_hw_state hw_state;
};
struct intel_shared_dpll { struct intel_shared_dpll {
int refcount; /* count of number of CRTCs sharing this PLL */ struct intel_shared_dpll_config config;
struct intel_shared_dpll_config *new_config;
int active; /* count of number of active CRTCs (i.e. DPMS on) */ int active; /* count of number of active CRTCs (i.e. DPMS on) */
bool on; /* is the PLL actually active? Disabled during modeset */ bool on; /* is the PLL actually active? Disabled during modeset */
const char *name; const char *name;
/* should match the index in the dev_priv->shared_dplls array */ /* should match the index in the dev_priv->shared_dplls array */
enum intel_dpll_id id; enum intel_dpll_id id;
struct intel_dpll_hw_state hw_state;
/* The mode_set hook is optional and should be used together with the /* The mode_set hook is optional and should be used together with the
* intel_prepare_shared_dpll function. */ * intel_prepare_shared_dpll function. */
void (*mode_set)(struct drm_i915_private *dev_priv, void (*mode_set)(struct drm_i915_private *dev_priv,
...@@ -275,7 +284,6 @@ void intel_link_compute_m_n(int bpp, int nlanes, ...@@ -275,7 +284,6 @@ void intel_link_compute_m_n(int bpp, int nlanes,
#define DRIVER_PATCHLEVEL 0 #define DRIVER_PATCHLEVEL 0
#define WATCH_LISTS 0 #define WATCH_LISTS 0
#define WATCH_GTT 0
struct opregion_header; struct opregion_header;
struct opregion_acpi; struct opregion_acpi;
...@@ -434,6 +442,7 @@ struct drm_i915_error_state { ...@@ -434,6 +442,7 @@ struct drm_i915_error_state {
}; };
struct intel_connector; struct intel_connector;
struct intel_encoder;
struct intel_crtc_config; struct intel_crtc_config;
struct intel_plane_config; struct intel_plane_config;
struct intel_crtc; struct intel_crtc;
...@@ -476,15 +485,14 @@ struct drm_i915_display_funcs { ...@@ -476,15 +485,14 @@ struct drm_i915_display_funcs {
struct intel_crtc_config *); struct intel_crtc_config *);
void (*get_plane_config)(struct intel_crtc *, void (*get_plane_config)(struct intel_crtc *,
struct intel_plane_config *); struct intel_plane_config *);
int (*crtc_mode_set)(struct intel_crtc *crtc, int (*crtc_compute_clock)(struct intel_crtc *crtc);
int x, int y,
struct drm_framebuffer *old_fb);
void (*crtc_enable)(struct drm_crtc *crtc); void (*crtc_enable)(struct drm_crtc *crtc);
void (*crtc_disable)(struct drm_crtc *crtc); void (*crtc_disable)(struct drm_crtc *crtc);
void (*off)(struct drm_crtc *crtc); void (*off)(struct drm_crtc *crtc);
void (*write_eld)(struct drm_connector *connector, void (*audio_codec_enable)(struct drm_connector *connector,
struct drm_crtc *crtc, struct intel_encoder *encoder,
struct drm_display_mode *mode); struct drm_display_mode *mode);
void (*audio_codec_disable)(struct intel_encoder *encoder);
void (*fdi_link_train)(struct drm_crtc *crtc); void (*fdi_link_train)(struct drm_crtc *crtc);
void (*init_clock_gating)(struct drm_device *dev); void (*init_clock_gating)(struct drm_device *dev);
int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc, int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc,
...@@ -541,6 +549,7 @@ struct intel_uncore { ...@@ -541,6 +549,7 @@ struct intel_uncore {
unsigned fw_rendercount; unsigned fw_rendercount;
unsigned fw_mediacount; unsigned fw_mediacount;
unsigned fw_blittercount;
struct timer_list force_wake_timer; struct timer_list force_wake_timer;
}; };
...@@ -1379,6 +1388,49 @@ struct ilk_wm_values { ...@@ -1379,6 +1388,49 @@ struct ilk_wm_values {
enum intel_ddb_partitioning partitioning; enum intel_ddb_partitioning partitioning;
}; };
struct skl_ddb_entry {
uint16_t start, end; /* in number of blocks, 'end' is exclusive */
};
static inline uint16_t skl_ddb_entry_size(const struct skl_ddb_entry *entry)
{
return entry->end - entry->start;
}
static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
const struct skl_ddb_entry *e2)
{
if (e1->start == e2->start && e1->end == e2->end)
return true;
return false;
}
struct skl_ddb_allocation {
struct skl_ddb_entry pipe[I915_MAX_PIPES];
struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
struct skl_ddb_entry cursor[I915_MAX_PIPES];
};
struct skl_wm_values {
bool dirty[I915_MAX_PIPES];
struct skl_ddb_allocation ddb;
uint32_t wm_linetime[I915_MAX_PIPES];
uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
uint32_t cursor[I915_MAX_PIPES][8];
uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
uint32_t cursor_trans[I915_MAX_PIPES];
};
struct skl_wm_level {
bool plane_en[I915_MAX_PLANES];
bool cursor_en;
uint16_t plane_res_b[I915_MAX_PLANES];
uint8_t plane_res_l[I915_MAX_PLANES];
uint16_t cursor_res_b;
uint8_t cursor_res_l;
};
/* /*
* This struct helps tracking the state needed for runtime PM, which puts the * This struct helps tracking the state needed for runtime PM, which puts the
* device in PCI D3 state. Notice that when this happens, nothing on the * device in PCI D3 state. Notice that when this happens, nothing on the
...@@ -1561,6 +1613,7 @@ struct drm_i915_private { ...@@ -1561,6 +1613,7 @@ struct drm_i915_private {
unsigned int fsb_freq, mem_freq, is_ddr3; unsigned int fsb_freq, mem_freq, is_ddr3;
unsigned int vlv_cdclk_freq; unsigned int vlv_cdclk_freq;
unsigned int hpll_freq;
/** /**
* wq - Driver workqueue for GEM. * wq - Driver workqueue for GEM.
...@@ -1670,9 +1723,25 @@ struct drm_i915_private { ...@@ -1670,9 +1723,25 @@ struct drm_i915_private {
uint16_t spr_latency[5]; uint16_t spr_latency[5];
/* cursor */ /* cursor */
uint16_t cur_latency[5]; uint16_t cur_latency[5];
/*
* Raw watermark memory latency values
* for SKL for all 8 levels
* in 1us units.
*/
uint16_t skl_latency[8];
/*
* The skl_wm_values structure is a bit too big for stack
* allocation, so we keep the staging struct where we store
* intermediate results here instead.
*/
struct skl_wm_values skl_results;
/* current hardware state */ /* current hardware state */
struct ilk_wm_values hw; union {
struct ilk_wm_values hw;
struct skl_wm_values skl_hw;
};
} wm; } wm;
struct i915_runtime_pm pm; struct i915_runtime_pm pm;
...@@ -1856,8 +1925,6 @@ struct drm_i915_gem_object { ...@@ -1856,8 +1925,6 @@ struct drm_i915_gem_object {
unsigned long gt_ro:1; unsigned long gt_ro:1;
unsigned int cache_level:3; unsigned int cache_level:3;
unsigned int has_aliasing_ppgtt_mapping:1;
unsigned int has_global_gtt_mapping:1;
unsigned int has_dma_mapping:1; unsigned int has_dma_mapping:1;
unsigned int frontbuffer_bits:INTEL_FRONTBUFFER_BITS; unsigned int frontbuffer_bits:INTEL_FRONTBUFFER_BITS;
...@@ -2292,8 +2359,6 @@ __printf(3, 4) ...@@ -2292,8 +2359,6 @@ __printf(3, 4)
void i915_handle_error(struct drm_device *dev, bool wedged, void i915_handle_error(struct drm_device *dev, bool wedged,
const char *fmt, ...); const char *fmt, ...);
void gen6_set_pm_mask(struct drm_i915_private *dev_priv, u32 pm_iir,
int new_delay);
extern void intel_irq_init(struct drm_i915_private *dev_priv); extern void intel_irq_init(struct drm_i915_private *dev_priv);
extern void intel_hpd_init(struct drm_i915_private *dev_priv); extern void intel_hpd_init(struct drm_i915_private *dev_priv);
int intel_irq_install(struct drm_i915_private *dev_priv); int intel_irq_install(struct drm_i915_private *dev_priv);
...@@ -2531,6 +2596,11 @@ int __i915_add_request(struct intel_engine_cs *ring, ...@@ -2531,6 +2596,11 @@ int __i915_add_request(struct intel_engine_cs *ring,
u32 *seqno); u32 *seqno);
#define i915_add_request(ring, seqno) \ #define i915_add_request(ring, seqno) \
__i915_add_request(ring, NULL, NULL, seqno) __i915_add_request(ring, NULL, NULL, seqno)
int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
unsigned reset_counter,
bool interruptible,
s64 *timeout,
struct drm_i915_file_private *file_priv);
int __must_check i915_wait_seqno(struct intel_engine_cs *ring, int __must_check i915_wait_seqno(struct intel_engine_cs *ring,
uint32_t seqno); uint32_t seqno);
int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
...@@ -2800,7 +2870,6 @@ static inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter) ...@@ -2800,7 +2870,6 @@ static inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter)
extern void intel_i2c_reset(struct drm_device *dev); extern void intel_i2c_reset(struct drm_device *dev);
/* intel_opregion.c */ /* intel_opregion.c */
struct intel_encoder;
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
extern int intel_opregion_setup(struct drm_device *dev); extern int intel_opregion_setup(struct drm_device *dev);
extern void intel_opregion_init(struct drm_device *dev); extern void intel_opregion_init(struct drm_device *dev);
...@@ -2917,7 +2986,9 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val); ...@@ -2917,7 +2986,9 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val);
#define FORCEWAKE_RENDER (1 << 0) #define FORCEWAKE_RENDER (1 << 0)
#define FORCEWAKE_MEDIA (1 << 1) #define FORCEWAKE_MEDIA (1 << 1)
#define FORCEWAKE_ALL (FORCEWAKE_RENDER | FORCEWAKE_MEDIA) #define FORCEWAKE_BLITTER (1 << 2)
#define FORCEWAKE_ALL (FORCEWAKE_RENDER | FORCEWAKE_MEDIA | \
FORCEWAKE_BLITTER)
#define I915_READ8(reg) dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true) #define I915_READ8(reg) dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true)
......
...@@ -1134,7 +1134,7 @@ static bool can_wait_boost(struct drm_i915_file_private *file_priv) ...@@ -1134,7 +1134,7 @@ static bool can_wait_boost(struct drm_i915_file_private *file_priv)
} }
/** /**
* __wait_seqno - wait until execution of seqno has finished * __i915_wait_seqno - wait until execution of seqno has finished
* @ring: the ring expected to report seqno * @ring: the ring expected to report seqno
* @seqno: duh! * @seqno: duh!
* @reset_counter: reset sequence associated with the given seqno * @reset_counter: reset sequence associated with the given seqno
...@@ -1151,7 +1151,7 @@ static bool can_wait_boost(struct drm_i915_file_private *file_priv) ...@@ -1151,7 +1151,7 @@ static bool can_wait_boost(struct drm_i915_file_private *file_priv)
* Returns 0 if the seqno was found within the alloted time. Else returns the * Returns 0 if the seqno was found within the alloted time. Else returns the
* errno with remaining time filled in timeout argument. * errno with remaining time filled in timeout argument.
*/ */
static int __wait_seqno(struct intel_engine_cs *ring, u32 seqno, int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
unsigned reset_counter, unsigned reset_counter,
bool interruptible, bool interruptible,
s64 *timeout, s64 *timeout,
...@@ -1262,6 +1262,7 @@ i915_wait_seqno(struct intel_engine_cs *ring, uint32_t seqno) ...@@ -1262,6 +1262,7 @@ i915_wait_seqno(struct intel_engine_cs *ring, uint32_t seqno)
struct drm_device *dev = ring->dev; struct drm_device *dev = ring->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
bool interruptible = dev_priv->mm.interruptible; bool interruptible = dev_priv->mm.interruptible;
unsigned reset_counter;
int ret; int ret;
BUG_ON(!mutex_is_locked(&dev->struct_mutex)); BUG_ON(!mutex_is_locked(&dev->struct_mutex));
...@@ -1275,14 +1276,13 @@ i915_wait_seqno(struct intel_engine_cs *ring, uint32_t seqno) ...@@ -1275,14 +1276,13 @@ i915_wait_seqno(struct intel_engine_cs *ring, uint32_t seqno)
if (ret) if (ret)
return ret; return ret;
return __wait_seqno(ring, seqno, reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
atomic_read(&dev_priv->gpu_error.reset_counter), return __i915_wait_seqno(ring, seqno, reset_counter, interruptible,
interruptible, NULL, NULL); NULL, NULL);
} }
static int static int
i915_gem_object_wait_rendering__tail(struct drm_i915_gem_object *obj, i915_gem_object_wait_rendering__tail(struct drm_i915_gem_object *obj)
struct intel_engine_cs *ring)
{ {
if (!obj->active) if (!obj->active)
return 0; return 0;
...@@ -1319,7 +1319,7 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, ...@@ -1319,7 +1319,7 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
if (ret) if (ret)
return ret; return ret;
return i915_gem_object_wait_rendering__tail(obj, ring); return i915_gem_object_wait_rendering__tail(obj);
} }
/* A nonblocking variant of the above wait. This is a highly dangerous routine /* A nonblocking variant of the above wait. This is a highly dangerous routine
...@@ -1354,12 +1354,13 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj, ...@@ -1354,12 +1354,13 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
ret = __wait_seqno(ring, seqno, reset_counter, true, NULL, file_priv); ret = __i915_wait_seqno(ring, seqno, reset_counter, true, NULL,
file_priv);
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
if (ret) if (ret)
return ret; return ret;
return i915_gem_object_wait_rendering__tail(obj, ring); return i915_gem_object_wait_rendering__tail(obj);
} }
/** /**
...@@ -2848,8 +2849,8 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) ...@@ -2848,8 +2849,8 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
return __wait_seqno(ring, seqno, reset_counter, true, &args->timeout_ns, return __i915_wait_seqno(ring, seqno, reset_counter, true,
file->driver_priv); &args->timeout_ns, file->driver_priv);
out: out:
drm_gem_object_unreference(&obj->base); drm_gem_object_unreference(&obj->base);
...@@ -3477,23 +3478,9 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, ...@@ -3477,23 +3478,9 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
list_move_tail(&obj->global_list, &dev_priv->mm.bound_list); list_move_tail(&obj->global_list, &dev_priv->mm.bound_list);
list_add_tail(&vma->mm_list, &vm->inactive_list); list_add_tail(&vma->mm_list, &vm->inactive_list);
if (i915_is_ggtt(vm)) {
bool mappable, fenceable;
fenceable = (vma->node.size == fence_size &&
(vma->node.start & (fence_alignment - 1)) == 0);
mappable = (vma->node.start + obj->base.size <=
dev_priv->gtt.mappable_end);
obj->map_and_fenceable = mappable && fenceable;
}
WARN_ON(flags & PIN_MAPPABLE && !obj->map_and_fenceable);
trace_i915_vma_bind(vma, flags); trace_i915_vma_bind(vma, flags);
vma->bind_vma(vma, obj->cache_level, vma->bind_vma(vma, obj->cache_level,
flags & (PIN_MAPPABLE | PIN_GLOBAL) ? GLOBAL_BIND : 0); flags & PIN_GLOBAL ? GLOBAL_BIND : 0);
return vma; return vma;
...@@ -3701,7 +3688,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, ...@@ -3701,7 +3688,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
list_for_each_entry(vma, &obj->vma_list, vma_link) list_for_each_entry(vma, &obj->vma_list, vma_link)
if (drm_mm_node_allocated(&vma->node)) if (drm_mm_node_allocated(&vma->node))
vma->bind_vma(vma, cache_level, vma->bind_vma(vma, cache_level,
obj->has_global_gtt_mapping ? GLOBAL_BIND : 0); vma->bound & GLOBAL_BIND);
} }
list_for_each_entry(vma, &obj->vma_list, vma_link) list_for_each_entry(vma, &obj->vma_list, vma_link)
...@@ -4028,7 +4015,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) ...@@ -4028,7 +4015,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
if (seqno == 0) if (seqno == 0)
return 0; return 0;
ret = __wait_seqno(ring, seqno, reset_counter, true, NULL, NULL); ret = __i915_wait_seqno(ring, seqno, reset_counter, true, NULL, NULL);
if (ret == 0) if (ret == 0)
queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0); queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0);
...@@ -4062,6 +4049,7 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, ...@@ -4062,6 +4049,7 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
{ {
struct drm_i915_private *dev_priv = obj->base.dev->dev_private; struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
struct i915_vma *vma; struct i915_vma *vma;
unsigned bound;
int ret; int ret;
if (WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base)) if (WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base))
...@@ -4070,6 +4058,9 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, ...@@ -4070,6 +4058,9 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
if (WARN_ON(flags & (PIN_GLOBAL | PIN_MAPPABLE) && !i915_is_ggtt(vm))) if (WARN_ON(flags & (PIN_GLOBAL | PIN_MAPPABLE) && !i915_is_ggtt(vm)))
return -EINVAL; return -EINVAL;
if (WARN_ON((flags & (PIN_MAPPABLE | PIN_GLOBAL)) == PIN_MAPPABLE))
return -EINVAL;
vma = i915_gem_obj_to_vma(obj, vm); vma = i915_gem_obj_to_vma(obj, vm);
if (vma) { if (vma) {
if (WARN_ON(vma->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT)) if (WARN_ON(vma->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
...@@ -4091,15 +4082,39 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, ...@@ -4091,15 +4082,39 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
} }
} }
bound = vma ? vma->bound : 0;
if (vma == NULL || !drm_mm_node_allocated(&vma->node)) { if (vma == NULL || !drm_mm_node_allocated(&vma->node)) {
vma = i915_gem_object_bind_to_vm(obj, vm, alignment, flags); vma = i915_gem_object_bind_to_vm(obj, vm, alignment, flags);
if (IS_ERR(vma)) if (IS_ERR(vma))
return PTR_ERR(vma); return PTR_ERR(vma);
} }
if (flags & PIN_GLOBAL && !obj->has_global_gtt_mapping) if (flags & PIN_GLOBAL && !(vma->bound & GLOBAL_BIND))
vma->bind_vma(vma, obj->cache_level, GLOBAL_BIND); vma->bind_vma(vma, obj->cache_level, GLOBAL_BIND);
if ((bound ^ vma->bound) & GLOBAL_BIND) {
bool mappable, fenceable;
u32 fence_size, fence_alignment;
fence_size = i915_gem_get_gtt_size(obj->base.dev,
obj->base.size,
obj->tiling_mode);
fence_alignment = i915_gem_get_gtt_alignment(obj->base.dev,
obj->base.size,
obj->tiling_mode,
true);
fenceable = (vma->node.size == fence_size &&
(vma->node.start & (fence_alignment - 1)) == 0);
mappable = (vma->node.start + obj->base.size <=
dev_priv->gtt.mappable_end);
obj->map_and_fenceable = mappable && fenceable;
}
WARN_ON(flags & PIN_MAPPABLE && !obj->map_and_fenceable);
vma->pin_count++; vma->pin_count++;
if (flags & PIN_MAPPABLE) if (flags & PIN_MAPPABLE)
obj->pin_mappable |= true; obj->pin_mappable |= true;
......
...@@ -522,6 +522,7 @@ static int do_switch(struct intel_engine_cs *ring, ...@@ -522,6 +522,7 @@ static int do_switch(struct intel_engine_cs *ring,
struct intel_context *from = ring->last_context; struct intel_context *from = ring->last_context;
u32 hw_flags = 0; u32 hw_flags = 0;
bool uninitialized = false; bool uninitialized = false;
struct i915_vma *vma;
int ret, i; int ret, i;
if (from != NULL && ring == &dev_priv->ring[RCS]) { if (from != NULL && ring == &dev_priv->ring[RCS]) {
...@@ -571,11 +572,10 @@ static int do_switch(struct intel_engine_cs *ring, ...@@ -571,11 +572,10 @@ static int do_switch(struct intel_engine_cs *ring,
if (ret) if (ret)
goto unpin_out; goto unpin_out;
if (!to->legacy_hw_ctx.rcs_state->has_global_gtt_mapping) { vma = i915_gem_obj_to_ggtt(to->legacy_hw_ctx.rcs_state);
struct i915_vma *vma = i915_gem_obj_to_vma(to->legacy_hw_ctx.rcs_state, if (!(vma->bound & GLOBAL_BIND))
&dev_priv->gtt.base); vma->bind_vma(vma, to->legacy_hw_ctx.rcs_state->cache_level,
vma->bind_vma(vma, to->legacy_hw_ctx.rcs_state->cache_level, GLOBAL_BIND); GLOBAL_BIND);
}
if (!to->legacy_hw_ctx.initialized || i915_gem_context_is_default(to)) if (!to->legacy_hw_ctx.initialized || i915_gem_context_is_default(to))
hw_flags |= MI_RESTORE_INHIBIT; hw_flags |= MI_RESTORE_INHIBIT;
......
...@@ -357,12 +357,9 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, ...@@ -357,12 +357,9 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
* through the ppgtt for non_secure batchbuffers. */ * through the ppgtt for non_secure batchbuffers. */
if (unlikely(IS_GEN6(dev) && if (unlikely(IS_GEN6(dev) &&
reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION && reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION &&
!target_i915_obj->has_global_gtt_mapping)) { !(target_vma->bound & GLOBAL_BIND)))
struct i915_vma *vma = target_vma->bind_vma(target_vma, target_i915_obj->cache_level,
list_first_entry(&target_i915_obj->vma_list, GLOBAL_BIND);
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 */ /* Validate that the target is in a valid r/w GPU domain */
if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) { if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) {
...@@ -531,7 +528,7 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, ...@@ -531,7 +528,7 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma,
flags = 0; flags = 0;
if (entry->flags & __EXEC_OBJECT_NEEDS_MAP) if (entry->flags & __EXEC_OBJECT_NEEDS_MAP)
flags |= PIN_MAPPABLE; flags |= PIN_GLOBAL | PIN_MAPPABLE;
if (entry->flags & EXEC_OBJECT_NEEDS_GTT) if (entry->flags & EXEC_OBJECT_NEEDS_GTT)
flags |= PIN_GLOBAL; flags |= PIN_GLOBAL;
if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS)
...@@ -1368,17 +1365,19 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, ...@@ -1368,17 +1365,19 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
batch_obj, batch_obj,
args->batch_start_offset, args->batch_start_offset,
file->is_master); file->is_master);
if (ret) if (ret) {
goto err; if (ret != -EACCES)
goto err;
/* } else {
* XXX: Actually do this when enabling batch copy... /*
* * XXX: Actually do this when enabling batch copy...
* Set the DISPATCH_SECURE bit to remove the NON_SECURE bit *
* from MI_BATCH_BUFFER_START commands issued in the * Set the DISPATCH_SECURE bit to remove the NON_SECURE bit
* dispatch_execbuffer implementations. We specifically don't * from MI_BATCH_BUFFER_START commands issued in the
* want that set when the command parser is enabled. * dispatch_execbuffer implementations. We specifically don't
*/ * want that set when the command parser is enabled.
*/
}
} }
/* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure
......
...@@ -1266,7 +1266,7 @@ void i915_check_and_clear_faults(struct drm_device *dev) ...@@ -1266,7 +1266,7 @@ void i915_check_and_clear_faults(struct drm_device *dev)
fault_reg = I915_READ(RING_FAULT_REG(ring)); fault_reg = I915_READ(RING_FAULT_REG(ring));
if (fault_reg & RING_FAULT_VALID) { if (fault_reg & RING_FAULT_VALID) {
DRM_DEBUG_DRIVER("Unexpected fault\n" DRM_DEBUG_DRIVER("Unexpected fault\n"
"\tAddr: 0x%08lx\\n" "\tAddr: 0x%08lx\n"
"\tAddress space: %s\n" "\tAddress space: %s\n"
"\tSource ID: %d\n" "\tSource ID: %d\n"
"\tType: %d\n", "\tType: %d\n",
...@@ -1336,7 +1336,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) ...@@ -1336,7 +1336,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
* Unfortunately above, we've just wiped out the mappings * Unfortunately above, we've just wiped out the mappings
* without telling our object about it. So we need to fake it. * without telling our object about it. So we need to fake it.
*/ */
obj->has_global_gtt_mapping = 0; vma->bound &= ~GLOBAL_BIND;
vma->bind_vma(vma, obj->cache_level, GLOBAL_BIND); vma->bind_vma(vma, obj->cache_level, GLOBAL_BIND);
} }
...@@ -1533,7 +1533,7 @@ static void i915_ggtt_bind_vma(struct i915_vma *vma, ...@@ -1533,7 +1533,7 @@ static void i915_ggtt_bind_vma(struct i915_vma *vma,
BUG_ON(!i915_is_ggtt(vma->vm)); BUG_ON(!i915_is_ggtt(vma->vm));
intel_gtt_insert_sg_entries(vma->obj->pages, entry, flags); intel_gtt_insert_sg_entries(vma->obj->pages, entry, flags);
vma->obj->has_global_gtt_mapping = 1; vma->bound = GLOBAL_BIND;
} }
static void i915_ggtt_clear_range(struct i915_address_space *vm, static void i915_ggtt_clear_range(struct i915_address_space *vm,
...@@ -1552,7 +1552,7 @@ static void i915_ggtt_unbind_vma(struct i915_vma *vma) ...@@ -1552,7 +1552,7 @@ static void i915_ggtt_unbind_vma(struct i915_vma *vma)
const unsigned int size = vma->obj->base.size >> PAGE_SHIFT; const unsigned int size = vma->obj->base.size >> PAGE_SHIFT;
BUG_ON(!i915_is_ggtt(vma->vm)); BUG_ON(!i915_is_ggtt(vma->vm));
vma->obj->has_global_gtt_mapping = 0; vma->bound = 0;
intel_gtt_clear_range(first, size); intel_gtt_clear_range(first, size);
} }
...@@ -1580,24 +1580,24 @@ static void ggtt_bind_vma(struct i915_vma *vma, ...@@ -1580,24 +1580,24 @@ static void ggtt_bind_vma(struct i915_vma *vma,
* flags. At all other times, the GPU will use the aliasing PPGTT. * flags. At all other times, the GPU will use the aliasing PPGTT.
*/ */
if (!dev_priv->mm.aliasing_ppgtt || flags & GLOBAL_BIND) { if (!dev_priv->mm.aliasing_ppgtt || flags & GLOBAL_BIND) {
if (!obj->has_global_gtt_mapping || if (!(vma->bound & GLOBAL_BIND) ||
(cache_level != obj->cache_level)) { (cache_level != obj->cache_level)) {
vma->vm->insert_entries(vma->vm, obj->pages, vma->vm->insert_entries(vma->vm, obj->pages,
vma->node.start, vma->node.start,
cache_level, flags); cache_level, flags);
obj->has_global_gtt_mapping = 1; vma->bound |= GLOBAL_BIND;
} }
} }
if (dev_priv->mm.aliasing_ppgtt && if (dev_priv->mm.aliasing_ppgtt &&
(!obj->has_aliasing_ppgtt_mapping || (!(vma->bound & LOCAL_BIND) ||
(cache_level != obj->cache_level))) { (cache_level != obj->cache_level))) {
struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt; struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt;
appgtt->base.insert_entries(&appgtt->base, appgtt->base.insert_entries(&appgtt->base,
vma->obj->pages, vma->obj->pages,
vma->node.start, vma->node.start,
cache_level, flags); cache_level, flags);
vma->obj->has_aliasing_ppgtt_mapping = 1; vma->bound |= LOCAL_BIND;
} }
} }
...@@ -1607,21 +1607,21 @@ static void ggtt_unbind_vma(struct i915_vma *vma) ...@@ -1607,21 +1607,21 @@ static void ggtt_unbind_vma(struct i915_vma *vma)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj = vma->obj; struct drm_i915_gem_object *obj = vma->obj;
if (obj->has_global_gtt_mapping) { if (vma->bound & GLOBAL_BIND) {
vma->vm->clear_range(vma->vm, vma->vm->clear_range(vma->vm,
vma->node.start, vma->node.start,
obj->base.size, obj->base.size,
true); true);
obj->has_global_gtt_mapping = 0; vma->bound &= ~GLOBAL_BIND;
} }
if (obj->has_aliasing_ppgtt_mapping) { if (vma->bound & LOCAL_BIND) {
struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt; struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt;
appgtt->base.clear_range(&appgtt->base, appgtt->base.clear_range(&appgtt->base,
vma->node.start, vma->node.start,
obj->base.size, obj->base.size,
true); true);
obj->has_aliasing_ppgtt_mapping = 0; vma->bound &= ~LOCAL_BIND;
} }
} }
...@@ -1699,7 +1699,7 @@ int i915_gem_setup_global_gtt(struct drm_device *dev, ...@@ -1699,7 +1699,7 @@ int i915_gem_setup_global_gtt(struct drm_device *dev,
DRM_DEBUG_KMS("Reservation failed: %i\n", ret); DRM_DEBUG_KMS("Reservation failed: %i\n", ret);
return ret; return ret;
} }
obj->has_global_gtt_mapping = 1; vma->bound |= GLOBAL_BIND;
} }
dev_priv->gtt.base.start = start; dev_priv->gtt.base.start = start;
......
...@@ -123,6 +123,12 @@ struct i915_vma { ...@@ -123,6 +123,12 @@ struct i915_vma {
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
struct i915_address_space *vm; struct i915_address_space *vm;
/** Flags and address space this VMA is bound to */
#define GLOBAL_BIND (1<<0)
#define LOCAL_BIND (1<<1)
#define PTE_READ_ONLY (1<<2)
unsigned int bound : 4;
/** This object's place on the active/inactive lists */ /** This object's place on the active/inactive lists */
struct list_head mm_list; struct list_head mm_list;
...@@ -155,8 +161,6 @@ struct i915_vma { ...@@ -155,8 +161,6 @@ struct i915_vma {
* setting the valid PTE entries to a reserved scratch page. */ * setting the valid PTE entries to a reserved scratch page. */
void (*unbind_vma)(struct i915_vma *vma); void (*unbind_vma)(struct i915_vma *vma);
/* Map an object into an address space with the given cache flags. */ /* Map an object into an address space with the given cache flags. */
#define GLOBAL_BIND (1<<0)
#define PTE_READ_ONLY (1<<1)
void (*bind_vma)(struct i915_vma *vma, void (*bind_vma)(struct i915_vma *vma,
enum i915_cache_level cache_level, enum i915_cache_level cache_level,
u32 flags); u32 flags);
......
...@@ -38,6 +38,8 @@ render_state_get_rodata(struct drm_device *dev, const int gen) ...@@ -38,6 +38,8 @@ render_state_get_rodata(struct drm_device *dev, const int gen)
return &gen7_null_state; return &gen7_null_state;
case 8: case 8:
return &gen8_null_state; return &gen8_null_state;
case 9:
return &gen9_null_state;
} }
return NULL; return NULL;
......
...@@ -533,7 +533,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, ...@@ -533,7 +533,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
} }
} }
obj->has_global_gtt_mapping = 1; vma->bound |= GLOBAL_BIND;
list_add_tail(&obj->global_list, &dev_priv->mm.bound_list); list_add_tail(&obj->global_list, &dev_priv->mm.bound_list);
list_add_tail(&vma->mm_list, &ggtt->inactive_list); list_add_tail(&vma->mm_list, &ggtt->inactive_list);
......
...@@ -458,6 +458,7 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, ...@@ -458,6 +458,7 @@ i915_gem_get_tiling(struct drm_device *dev, void *data,
} }
/* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */ /* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */
args->phys_swizzle_mode = args->swizzle_mode;
if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17) if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
args->swizzle_mode = I915_BIT_6_SWIZZLE_9; args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17) if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
......
...@@ -565,6 +565,7 @@ i915_error_object_create(struct drm_i915_private *dev_priv, ...@@ -565,6 +565,7 @@ i915_error_object_create(struct drm_i915_private *dev_priv,
struct i915_address_space *vm) struct i915_address_space *vm)
{ {
struct drm_i915_error_object *dst; struct drm_i915_error_object *dst;
struct i915_vma *vma = NULL;
int num_pages; int num_pages;
bool use_ggtt; bool use_ggtt;
int i = 0; int i = 0;
...@@ -585,16 +586,17 @@ i915_error_object_create(struct drm_i915_private *dev_priv, ...@@ -585,16 +586,17 @@ i915_error_object_create(struct drm_i915_private *dev_priv,
dst->gtt_offset = -1; dst->gtt_offset = -1;
reloc_offset = dst->gtt_offset; reloc_offset = dst->gtt_offset;
if (i915_is_ggtt(vm))
vma = i915_gem_obj_to_ggtt(src);
use_ggtt = (src->cache_level == I915_CACHE_NONE && use_ggtt = (src->cache_level == I915_CACHE_NONE &&
i915_is_ggtt(vm) && vma && (vma->bound & GLOBAL_BIND) &&
src->has_global_gtt_mapping && reloc_offset + num_pages * PAGE_SIZE <= dev_priv->gtt.mappable_end);
reloc_offset + num_pages * PAGE_SIZE <= dev_priv->gtt.mappable_end);
/* Cannot access stolen address directly, try to use the aperture */ /* Cannot access stolen address directly, try to use the aperture */
if (src->stolen) { if (src->stolen) {
use_ggtt = true; use_ggtt = true;
if (!src->has_global_gtt_mapping) if (!(vma && vma->bound & GLOBAL_BIND))
goto unwind; goto unwind;
reloc_offset = i915_gem_obj_ggtt_offset(src); reloc_offset = i915_gem_obj_ggtt_offset(src);
...@@ -1240,7 +1242,8 @@ static void i915_error_capture_msg(struct drm_device *dev, ...@@ -1240,7 +1242,8 @@ static void i915_error_capture_msg(struct drm_device *dev,
ecode = i915_error_generate_code(dev_priv, error, &ring_id); ecode = i915_error_generate_code(dev_priv, error, &ring_id);
len = scnprintf(error->error_msg, sizeof(error->error_msg), len = scnprintf(error->error_msg, sizeof(error->error_msg),
"GPU HANG: ecode %d:0x%08x", ring_id, ecode); "GPU HANG: ecode %d:%d:0x%08x",
INTEL_INFO(dev)->gen, ring_id, ecode);
if (ring_id != -1 && error->ring[ring_id].pid != -1) if (ring_id != -1 && error->ring[ring_id].pid != -1)
len += scnprintf(error->error_msg + len, len += scnprintf(error->error_msg + len,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -459,6 +459,27 @@ intel_ddi_get_crtc_encoder(struct drm_crtc *crtc) ...@@ -459,6 +459,27 @@ intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
return ret; return ret;
} }
static struct intel_encoder *
intel_ddi_get_crtc_new_encoder(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct intel_encoder *intel_encoder, *ret = NULL;
int num_encoders = 0;
for_each_intel_encoder(dev, intel_encoder) {
if (intel_encoder->new_crtc == crtc) {
ret = intel_encoder;
num_encoders++;
}
}
WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
pipe_name(crtc->pipe));
BUG_ON(ret == NULL);
return ret;
}
#define LC_FREQ 2700 #define LC_FREQ 2700
#define LC_FREQ_2K U64_C(LC_FREQ * 2000) #define LC_FREQ_2K U64_C(LC_FREQ * 2000)
...@@ -792,7 +813,7 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc, ...@@ -792,7 +813,7 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
WRPLL_DIVIDER_POST(p); WRPLL_DIVIDER_POST(p);
intel_crtc->config.dpll_hw_state.wrpll = val; intel_crtc->new_config->dpll_hw_state.wrpll = val;
pll = intel_get_shared_dpll(intel_crtc); pll = intel_get_shared_dpll(intel_crtc);
if (pll == NULL) { if (pll == NULL) {
...@@ -801,7 +822,7 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc, ...@@ -801,7 +822,7 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
return false; return false;
} }
intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id); intel_crtc->new_config->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
} }
return true; return true;
...@@ -817,11 +838,9 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc, ...@@ -817,11 +838,9 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
*/ */
bool intel_ddi_pll_select(struct intel_crtc *intel_crtc) bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
{ {
struct drm_crtc *crtc = &intel_crtc->base; struct intel_encoder *intel_encoder =
struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); intel_ddi_get_crtc_new_encoder(intel_crtc);
int clock = intel_crtc->config.port_clock; int clock = intel_crtc->new_config->port_clock;
intel_put_shared_dpll(intel_crtc);
return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock); return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock);
} }
...@@ -1120,15 +1139,6 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) ...@@ -1120,15 +1139,6 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
enum port port = intel_ddi_get_encoder_port(intel_encoder); enum port port = intel_ddi_get_encoder_port(intel_encoder);
int type = intel_encoder->type; int type = intel_encoder->type;
if (crtc->config.has_audio) {
DRM_DEBUG_DRIVER("Audio on pipe %c on DDI\n",
pipe_name(crtc->pipe));
/* write eld */
DRM_DEBUG_DRIVER("DDI audio: write eld information\n");
intel_write_eld(encoder, &crtc->config.adjusted_mode);
}
if (type == INTEL_OUTPUT_EDP) { if (type == INTEL_OUTPUT_EDP) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
intel_edp_panel_on(intel_dp); intel_edp_panel_on(intel_dp);
...@@ -1195,12 +1205,10 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder) ...@@ -1195,12 +1205,10 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
struct drm_encoder *encoder = &intel_encoder->base; struct drm_encoder *encoder = &intel_encoder->base;
struct drm_crtc *crtc = encoder->crtc; struct drm_crtc *crtc = encoder->crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_crtc->pipe;
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
enum port port = intel_ddi_get_encoder_port(intel_encoder); enum port port = intel_ddi_get_encoder_port(intel_encoder);
int type = intel_encoder->type; int type = intel_encoder->type;
uint32_t tmp;
if (type == INTEL_OUTPUT_HDMI) { if (type == INTEL_OUTPUT_HDMI) {
struct intel_digital_port *intel_dig_port = struct intel_digital_port *intel_dig_port =
...@@ -1225,9 +1233,7 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder) ...@@ -1225,9 +1233,7 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
if (intel_crtc->config.has_audio) { if (intel_crtc->config.has_audio) {
intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO); intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); intel_audio_codec_enable(intel_encoder);
tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4));
I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
} }
} }
...@@ -1236,19 +1242,12 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder) ...@@ -1236,19 +1242,12 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
struct drm_encoder *encoder = &intel_encoder->base; struct drm_encoder *encoder = &intel_encoder->base;
struct drm_crtc *crtc = encoder->crtc; struct drm_crtc *crtc = encoder->crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_crtc->pipe;
int type = intel_encoder->type; int type = intel_encoder->type;
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t tmp;
/* We can't touch HSW_AUD_PIN_ELD_CP_VLD uncionditionally because this
* register is part of the power well on Haswell. */
if (intel_crtc->config.has_audio) { if (intel_crtc->config.has_audio) {
tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); intel_audio_codec_disable(intel_encoder);
tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) <<
(pipe * 4));
I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO); intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
} }
...@@ -1311,7 +1310,7 @@ int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) ...@@ -1311,7 +1310,7 @@ int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv, static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
struct intel_shared_dpll *pll) struct intel_shared_dpll *pll)
{ {
I915_WRITE(WRPLL_CTL(pll->id), pll->hw_state.wrpll); I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
POSTING_READ(WRPLL_CTL(pll->id)); POSTING_READ(WRPLL_CTL(pll->id));
udelay(20); udelay(20);
} }
...@@ -1524,7 +1523,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder, ...@@ -1524,7 +1523,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) { if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
if (temp & (AUDIO_OUTPUT_ENABLE_A << (intel_crtc->pipe * 4))) if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
pipe_config->has_audio = true; pipe_config->has_audio = true;
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -94,18 +94,20 @@ ...@@ -94,18 +94,20 @@
/* these are outputs from the chip - integrated only /* these are outputs from the chip - integrated only
external chips are via DVO or SDVO output */ external chips are via DVO or SDVO output */
#define INTEL_OUTPUT_UNUSED 0 enum intel_output_type {
#define INTEL_OUTPUT_ANALOG 1 INTEL_OUTPUT_UNUSED = 0,
#define INTEL_OUTPUT_DVO 2 INTEL_OUTPUT_ANALOG = 1,
#define INTEL_OUTPUT_SDVO 3 INTEL_OUTPUT_DVO = 2,
#define INTEL_OUTPUT_LVDS 4 INTEL_OUTPUT_SDVO = 3,
#define INTEL_OUTPUT_TVOUT 5 INTEL_OUTPUT_LVDS = 4,
#define INTEL_OUTPUT_HDMI 6 INTEL_OUTPUT_TVOUT = 5,
#define INTEL_OUTPUT_DISPLAYPORT 7 INTEL_OUTPUT_HDMI = 6,
#define INTEL_OUTPUT_EDP 8 INTEL_OUTPUT_DISPLAYPORT = 7,
#define INTEL_OUTPUT_DSI 9 INTEL_OUTPUT_EDP = 8,
#define INTEL_OUTPUT_UNKNOWN 10 INTEL_OUTPUT_DSI = 9,
#define INTEL_OUTPUT_DP_MST 11 INTEL_OUTPUT_UNKNOWN = 10,
INTEL_OUTPUT_DP_MST = 11,
};
#define INTEL_DVO_CHIP_NONE 0 #define INTEL_DVO_CHIP_NONE 0
#define INTEL_DVO_CHIP_LVDS 1 #define INTEL_DVO_CHIP_LVDS 1
...@@ -136,7 +138,7 @@ struct intel_encoder { ...@@ -136,7 +138,7 @@ struct intel_encoder {
*/ */
struct intel_crtc *new_crtc; struct intel_crtc *new_crtc;
int type; enum intel_output_type type;
unsigned int cloneable; unsigned int cloneable;
bool connectors_active; bool connectors_active;
void (*hot_plug)(struct intel_encoder *); void (*hot_plug)(struct intel_encoder *);
...@@ -399,7 +401,14 @@ struct intel_pipe_wm { ...@@ -399,7 +401,14 @@ struct intel_pipe_wm {
struct intel_mmio_flip { struct intel_mmio_flip {
u32 seqno; u32 seqno;
u32 ring_id; struct intel_engine_cs *ring;
struct work_struct work;
};
struct skl_pipe_wm {
struct skl_wm_level wm[8];
struct skl_wm_level trans_wm;
uint32_t linetime;
}; };
struct intel_crtc { struct intel_crtc {
...@@ -449,6 +458,8 @@ struct intel_crtc { ...@@ -449,6 +458,8 @@ struct intel_crtc {
struct { struct {
/* watermarks currently being used */ /* watermarks currently being used */
struct intel_pipe_wm active; struct intel_pipe_wm active;
/* SKL wm values currently in use */
struct skl_pipe_wm skl_active;
} wm; } wm;
int scanline_offset; int scanline_offset;
...@@ -590,6 +601,7 @@ struct intel_dp { ...@@ -590,6 +601,7 @@ struct intel_dp {
* this port. Only relevant on VLV/CHV. * this port. Only relevant on VLV/CHV.
*/ */
enum pipe pps_pipe; enum pipe pps_pipe;
struct edp_power_seq pps_delays;
bool use_tps3; bool use_tps3;
bool can_mst; /* this port supports mst */ bool can_mst; /* this port supports mst */
...@@ -848,6 +860,11 @@ void intel_frontbuffer_flip(struct drm_device *dev, ...@@ -848,6 +860,11 @@ void intel_frontbuffer_flip(struct drm_device *dev,
void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire); void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire);
/* intel_audio.c */
void intel_init_audio(struct drm_device *dev);
void intel_audio_codec_enable(struct intel_encoder *encoder);
void intel_audio_codec_disable(struct intel_encoder *encoder);
/* intel_display.c */ /* intel_display.c */
const char *intel_output_name(int output); const char *intel_output_name(int output);
bool intel_has_pending_fb_unpin(struct drm_device *dev); bool intel_has_pending_fb_unpin(struct drm_device *dev);
...@@ -873,6 +890,7 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, ...@@ -873,6 +890,7 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv, enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
enum pipe pipe); enum pipe pipe);
bool intel_pipe_has_type(struct intel_crtc *crtc, enum intel_output_type type);
static inline void static inline void
intel_wait_for_vblank(struct drm_device *dev, int pipe) intel_wait_for_vblank(struct drm_device *dev, int pipe)
{ {
...@@ -887,8 +905,8 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, ...@@ -887,8 +905,8 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
struct drm_modeset_acquire_ctx *ctx); struct drm_modeset_acquire_ctx *ctx);
void intel_release_load_detect_pipe(struct drm_connector *connector, void intel_release_load_detect_pipe(struct drm_connector *connector,
struct intel_load_detect_pipe *old); struct intel_load_detect_pipe *old);
int intel_pin_and_fence_fb_obj(struct drm_device *dev, int intel_pin_and_fence_fb_obj(struct drm_plane *plane,
struct drm_i915_gem_object *obj, struct drm_framebuffer *fb,
struct intel_engine_cs *pipelined); struct intel_engine_cs *pipelined);
void intel_unpin_fb_obj(struct drm_i915_gem_object *obj); void intel_unpin_fb_obj(struct drm_i915_gem_object *obj);
struct drm_framebuffer * struct drm_framebuffer *
...@@ -910,6 +928,10 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv, ...@@ -910,6 +928,10 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc); struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc);
void intel_put_shared_dpll(struct intel_crtc *crtc); void intel_put_shared_dpll(struct intel_crtc *crtc);
void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
const struct dpll *dpll);
void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe);
/* modesetting asserts */ /* modesetting asserts */
void assert_panel_unlocked(struct drm_i915_private *dev_priv, void assert_panel_unlocked(struct drm_i915_private *dev_priv,
enum pipe pipe); enum pipe pipe);
...@@ -924,8 +946,6 @@ void assert_fdi_rx_pll(struct drm_i915_private *dev_priv, ...@@ -924,8 +946,6 @@ void assert_fdi_rx_pll(struct drm_i915_private *dev_priv,
void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, bool state); void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, bool state);
#define assert_pipe_enabled(d, p) assert_pipe(d, p, true) #define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
#define assert_pipe_disabled(d, p) assert_pipe(d, p, false) #define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
void intel_write_eld(struct drm_encoder *encoder,
struct drm_display_mode *mode);
unsigned long intel_gen4_compute_page_offset(int *x, int *y, unsigned long intel_gen4_compute_page_offset(int *x, int *y,
unsigned int tiling_mode, unsigned int tiling_mode,
unsigned int bpp, unsigned int bpp,
...@@ -970,7 +990,6 @@ bool intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, ...@@ -970,7 +990,6 @@ bool intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port,
void intel_edp_backlight_on(struct intel_dp *intel_dp); void intel_edp_backlight_on(struct intel_dp *intel_dp);
void intel_edp_backlight_off(struct intel_dp *intel_dp); void intel_edp_backlight_off(struct intel_dp *intel_dp);
void intel_edp_panel_vdd_on(struct intel_dp *intel_dp); void intel_edp_panel_vdd_on(struct intel_dp *intel_dp);
void intel_edp_panel_vdd_sanitize(struct intel_encoder *intel_encoder);
void intel_edp_panel_on(struct intel_dp *intel_dp); void intel_edp_panel_on(struct intel_dp *intel_dp);
void intel_edp_panel_off(struct intel_dp *intel_dp); void intel_edp_panel_off(struct intel_dp *intel_dp);
void intel_edp_psr_enable(struct intel_dp *intel_dp); void intel_edp_psr_enable(struct intel_dp *intel_dp);
...@@ -982,7 +1001,6 @@ void intel_edp_psr_flush(struct drm_device *dev, ...@@ -982,7 +1001,6 @@ void intel_edp_psr_flush(struct drm_device *dev,
unsigned frontbuffer_bits); unsigned frontbuffer_bits);
void intel_edp_psr_init(struct drm_device *dev); void intel_edp_psr_init(struct drm_device *dev);
int intel_dp_handle_hpd_irq(struct intel_digital_port *digport, bool long_hpd);
void intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector); void intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector);
void intel_dp_mst_suspend(struct drm_device *dev); void intel_dp_mst_suspend(struct drm_device *dev);
void intel_dp_mst_resume(struct drm_device *dev); void intel_dp_mst_resume(struct drm_device *dev);
...@@ -1139,6 +1157,9 @@ void gen6_update_ring_freq(struct drm_device *dev); ...@@ -1139,6 +1157,9 @@ void gen6_update_ring_freq(struct drm_device *dev);
void gen6_rps_idle(struct drm_i915_private *dev_priv); void gen6_rps_idle(struct drm_i915_private *dev_priv);
void gen6_rps_boost(struct drm_i915_private *dev_priv); void gen6_rps_boost(struct drm_i915_private *dev_priv);
void ilk_wm_get_hw_state(struct drm_device *dev); void ilk_wm_get_hw_state(struct drm_device *dev);
void skl_wm_get_hw_state(struct drm_device *dev);
void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
struct skl_ddb_allocation *ddb /* out */);
/* intel_sdvo.c */ /* intel_sdvo.c */
...@@ -1158,7 +1179,9 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data, ...@@ -1158,7 +1179,9 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
int intel_sprite_get_colorkey(struct drm_device *dev, void *data, int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
bool intel_pipe_update_start(struct intel_crtc *crtc,
uint32_t *start_vbl_count);
void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count);
/* intel_tv.c */ /* intel_tv.c */
void intel_tv_init(struct drm_device *dev); void intel_tv_init(struct drm_device *dev);
......
...@@ -119,25 +119,25 @@ static int intelfb_alloc(struct drm_fb_helper *helper, ...@@ -119,25 +119,25 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
goto out; goto out;
} }
/* Flush everything out, we'll be doing GTT only from now on */
ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
if (ret) {
DRM_ERROR("failed to pin obj: %d\n", ret);
goto out_unref;
}
fb = __intel_framebuffer_create(dev, &mode_cmd, obj); fb = __intel_framebuffer_create(dev, &mode_cmd, obj);
if (IS_ERR(fb)) { if (IS_ERR(fb)) {
ret = PTR_ERR(fb); ret = PTR_ERR(fb);
goto out_unpin; goto out_unref;
}
/* Flush everything out, we'll be doing GTT only from now on */
ret = intel_pin_and_fence_fb_obj(NULL, fb, NULL);
if (ret) {
DRM_ERROR("failed to pin obj: %d\n", ret);
goto out_fb;
} }
ifbdev->fb = to_intel_framebuffer(fb); ifbdev->fb = to_intel_framebuffer(fb);
return 0; return 0;
out_unpin: out_fb:
i915_gem_object_ggtt_unpin(obj); drm_framebuffer_remove(fb);
out_unref: out_unref:
drm_gem_object_unreference(&obj->base); drm_gem_object_unreference(&obj->base);
out: out:
......
...@@ -661,14 +661,6 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder) ...@@ -661,14 +661,6 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder)
if (crtc->config.has_hdmi_sink) if (crtc->config.has_hdmi_sink)
hdmi_val |= HDMI_MODE_SELECT_HDMI; hdmi_val |= HDMI_MODE_SELECT_HDMI;
if (crtc->config.has_audio) {
WARN_ON(!crtc->config.has_hdmi_sink);
DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n",
pipe_name(crtc->pipe));
hdmi_val |= SDVO_AUDIO_ENABLE;
intel_write_eld(&encoder->base, adjusted_mode);
}
if (HAS_PCH_CPT(dev)) if (HAS_PCH_CPT(dev))
hdmi_val |= SDVO_PIPE_SEL_CPT(crtc->pipe); hdmi_val |= SDVO_PIPE_SEL_CPT(crtc->pipe);
else if (IS_CHERRYVIEW(dev)) else if (IS_CHERRYVIEW(dev))
...@@ -791,6 +783,13 @@ static void intel_enable_hdmi(struct intel_encoder *encoder) ...@@ -791,6 +783,13 @@ static void intel_enable_hdmi(struct intel_encoder *encoder)
I915_WRITE(intel_hdmi->hdmi_reg, temp); I915_WRITE(intel_hdmi->hdmi_reg, temp);
POSTING_READ(intel_hdmi->hdmi_reg); POSTING_READ(intel_hdmi->hdmi_reg);
} }
if (intel_crtc->config.has_audio) {
WARN_ON(!intel_crtc->config.has_hdmi_sink);
DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n",
pipe_name(intel_crtc->pipe));
intel_audio_codec_enable(encoder);
}
} }
static void vlv_enable_hdmi(struct intel_encoder *encoder) static void vlv_enable_hdmi(struct intel_encoder *encoder)
...@@ -802,9 +801,13 @@ static void intel_disable_hdmi(struct intel_encoder *encoder) ...@@ -802,9 +801,13 @@ static void intel_disable_hdmi(struct intel_encoder *encoder)
struct drm_device *dev = encoder->base.dev; struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
u32 temp; u32 temp;
u32 enable_bits = SDVO_ENABLE | SDVO_AUDIO_ENABLE; u32 enable_bits = SDVO_ENABLE | SDVO_AUDIO_ENABLE;
if (crtc->config.has_audio)
intel_audio_codec_disable(encoder);
temp = I915_READ(intel_hdmi->hdmi_reg); temp = I915_READ(intel_hdmi->hdmi_reg);
/* HW workaround for IBX, we need to move the port to transcoder A /* HW workaround for IBX, we need to move the port to transcoder A
......
...@@ -356,9 +356,9 @@ static int execlists_ctx_write_tail(struct drm_i915_gem_object *ctx_obj, u32 tai ...@@ -356,9 +356,9 @@ static int execlists_ctx_write_tail(struct drm_i915_gem_object *ctx_obj, u32 tai
return 0; return 0;
} }
static int execlists_submit_context(struct intel_engine_cs *ring, static void execlists_submit_contexts(struct intel_engine_cs *ring,
struct intel_context *to0, u32 tail0, struct intel_context *to0, u32 tail0,
struct intel_context *to1, u32 tail1) struct intel_context *to1, u32 tail1)
{ {
struct drm_i915_gem_object *ctx_obj0; struct drm_i915_gem_object *ctx_obj0;
struct drm_i915_gem_object *ctx_obj1 = NULL; struct drm_i915_gem_object *ctx_obj1 = NULL;
...@@ -378,8 +378,6 @@ static int execlists_submit_context(struct intel_engine_cs *ring, ...@@ -378,8 +378,6 @@ static int execlists_submit_context(struct intel_engine_cs *ring,
} }
execlists_elsp_write(ring, ctx_obj0, ctx_obj1); execlists_elsp_write(ring, ctx_obj0, ctx_obj1);
return 0;
} }
static void execlists_context_unqueue(struct intel_engine_cs *ring) static void execlists_context_unqueue(struct intel_engine_cs *ring)
...@@ -413,9 +411,9 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) ...@@ -413,9 +411,9 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
WARN_ON(req1 && req1->elsp_submitted); WARN_ON(req1 && req1->elsp_submitted);
WARN_ON(execlists_submit_context(ring, req0->ctx, req0->tail, execlists_submit_contexts(ring, req0->ctx, req0->tail,
req1 ? req1->ctx : NULL, req1 ? req1->ctx : NULL,
req1 ? req1->tail : 0)); req1 ? req1->tail : 0);
req0->elsp_submitted++; req0->elsp_submitted++;
if (req1) if (req1)
...@@ -1214,11 +1212,13 @@ static int gen8_emit_request(struct intel_ringbuffer *ringbuf) ...@@ -1214,11 +1212,13 @@ static int gen8_emit_request(struct intel_ringbuffer *ringbuf)
*/ */
void intel_logical_ring_cleanup(struct intel_engine_cs *ring) void intel_logical_ring_cleanup(struct intel_engine_cs *ring)
{ {
struct drm_i915_private *dev_priv = ring->dev->dev_private; struct drm_i915_private *dev_priv;
if (!intel_ring_initialized(ring)) if (!intel_ring_initialized(ring))
return; return;
dev_priv = ring->dev->dev_private;
intel_logical_ring_stop(ring); intel_logical_ring_stop(ring);
WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0); WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0);
ring->preallocated_lazy_request = NULL; ring->preallocated_lazy_request = NULL;
...@@ -1649,6 +1649,27 @@ static uint32_t get_lr_context_size(struct intel_engine_cs *ring) ...@@ -1649,6 +1649,27 @@ static uint32_t get_lr_context_size(struct intel_engine_cs *ring)
return ret; return ret;
} }
static int lrc_setup_hardware_status_page(struct intel_engine_cs *ring,
struct drm_i915_gem_object *default_ctx_obj)
{
struct drm_i915_private *dev_priv = ring->dev->dev_private;
/* The status page is offset 0 from the default context object
* in LRC mode. */
ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(default_ctx_obj);
ring->status_page.page_addr =
kmap(sg_page(default_ctx_obj->pages->sgl));
if (ring->status_page.page_addr == NULL)
return -ENOMEM;
ring->status_page.obj = default_ctx_obj;
I915_WRITE(RING_HWS_PGA(ring->mmio_base),
(u32)ring->status_page.gfx_addr);
POSTING_READ(RING_HWS_PGA(ring->mmio_base));
return 0;
}
/** /**
* intel_lr_context_deferred_create() - create the LRC specific bits of a context * intel_lr_context_deferred_create() - create the LRC specific bits of a context
* @ctx: LR context to create. * @ctx: LR context to create.
...@@ -1734,14 +1755,11 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, ...@@ -1734,14 +1755,11 @@ int intel_lr_context_deferred_create(struct intel_context *ctx,
ctx->engine[ring->id].state = ctx_obj; ctx->engine[ring->id].state = ctx_obj;
if (ctx == ring->default_context) { if (ctx == ring->default_context) {
/* The status page is offset 0 from the default context object ret = lrc_setup_hardware_status_page(ring, ctx_obj);
* in LRC mode. */ if (ret) {
ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(ctx_obj); DRM_ERROR("Failed to setup hardware status page\n");
ring->status_page.page_addr = goto error;
kmap(sg_page(ctx_obj->pages->sgl)); }
if (ring->status_page.page_addr == NULL)
return -ENOMEM;
ring->status_page.obj = ctx_obj;
} }
if (ring->id == RCS && !ctx->rcs_initialized) { if (ring->id == RCS && !ctx->rcs_initialized) {
......
This diff is collapsed.
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
extern const struct intel_renderstate_rodata gen6_null_state; extern const struct intel_renderstate_rodata gen6_null_state;
extern const struct intel_renderstate_rodata gen7_null_state; extern const struct intel_renderstate_rodata gen7_null_state;
extern const struct intel_renderstate_rodata gen8_null_state; extern const struct intel_renderstate_rodata gen8_null_state;
extern const struct intel_renderstate_rodata gen9_null_state;
#define RO_RENDERSTATE(_g) \ #define RO_RENDERSTATE(_g) \
const struct intel_renderstate_rodata gen ## _g ## _null_state = { \ const struct intel_renderstate_rodata gen ## _g ## _null_state = { \
......
This diff is collapsed.
...@@ -1845,12 +1845,15 @@ static int intel_init_ring_buffer(struct drm_device *dev, ...@@ -1845,12 +1845,15 @@ static int intel_init_ring_buffer(struct drm_device *dev,
void intel_cleanup_ring_buffer(struct intel_engine_cs *ring) void intel_cleanup_ring_buffer(struct intel_engine_cs *ring)
{ {
struct drm_i915_private *dev_priv = to_i915(ring->dev); struct drm_i915_private *dev_priv;
struct intel_ringbuffer *ringbuf = ring->buffer; struct intel_ringbuffer *ringbuf;
if (!intel_ring_initialized(ring)) if (!intel_ring_initialized(ring))
return; return;
dev_priv = to_i915(ring->dev);
ringbuf = ring->buffer;
intel_stop_ring_buffer(ring); intel_stop_ring_buffer(ring);
WARN_ON(!IS_GEN2(ring->dev) && (I915_READ_MODE(ring) & MODE_IDLE) == 0); WARN_ON(!IS_GEN2(ring->dev) && (I915_READ_MODE(ring) & MODE_IDLE) == 0);
......
...@@ -587,6 +587,9 @@ static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv, ...@@ -587,6 +587,9 @@ static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv,
power_well->data != PIPE_C); power_well->data != PIPE_C);
chv_set_pipe_power_well(dev_priv, power_well, false); chv_set_pipe_power_well(dev_priv, power_well, false);
if (power_well->data == PIPE_A)
vlv_power_sequencer_reset(dev_priv);
} }
static void check_power_well_state(struct drm_i915_private *dev_priv, static void check_power_well_state(struct drm_i915_private *dev_priv,
...@@ -938,12 +941,20 @@ static struct i915_power_well chv_power_wells[] = { ...@@ -938,12 +941,20 @@ static struct i915_power_well chv_power_wells[] = {
.data = PUNIT_POWER_WELL_DISP2D, .data = PUNIT_POWER_WELL_DISP2D,
.ops = &vlv_display_power_well_ops, .ops = &vlv_display_power_well_ops,
}, },
#endif
{ {
.name = "pipe-a", .name = "pipe-a",
.domains = CHV_PIPE_A_POWER_DOMAINS, /*
* FIXME: pipe A power well seems to be the new disp2d well.
* At least all registers seem to be housed there. Figure
* out if this a a temporary situation in pre-production
* hardware or a permanent state of affairs.
*/
.domains = CHV_PIPE_A_POWER_DOMAINS | VLV_DISPLAY_POWER_DOMAINS,
.data = PIPE_A, .data = PIPE_A,
.ops = &chv_pipe_power_well_ops, .ops = &chv_pipe_power_well_ops,
}, },
#if 0
{ {
.name = "pipe-b", .name = "pipe-b",
.domains = CHV_PIPE_B_POWER_DOMAINS, .domains = CHV_PIPE_B_POWER_DOMAINS,
...@@ -1137,12 +1148,9 @@ static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv) ...@@ -1137,12 +1148,9 @@ static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv)
struct i915_power_well *disp2d = struct i915_power_well *disp2d =
lookup_power_well(dev_priv, PUNIT_POWER_WELL_DISP2D); lookup_power_well(dev_priv, PUNIT_POWER_WELL_DISP2D);
/* nothing to do if common lane is already off */
if (!cmn->ops->is_enabled(dev_priv, cmn))
return;
/* If the display might be already active skip this */ /* If the display might be already active skip this */
if (disp2d->ops->is_enabled(dev_priv, disp2d) && if (cmn->ops->is_enabled(dev_priv, cmn) &&
disp2d->ops->is_enabled(dev_priv, disp2d) &&
I915_READ(DPIO_CTL) & DPIO_CMNRST) I915_READ(DPIO_CTL) & DPIO_CMNRST)
return; return;
......
This diff is collapsed.
This diff is collapsed.
...@@ -876,6 +876,12 @@ struct drm_i915_gem_get_tiling { ...@@ -876,6 +876,12 @@ struct drm_i915_gem_get_tiling {
* mmap mapping. * mmap mapping.
*/ */
__u32 swizzle_mode; __u32 swizzle_mode;
/**
* Returned address bit 6 swizzling required for CPU access through
* mmap mapping whilst bound.
*/
__u32 phys_swizzle_mode;
}; };
struct drm_i915_gem_get_aperture { struct drm_i915_gem_get_aperture {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment