Commit 885ac04a authored by Dave Airlie's avatar Dave Airlie

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

drm-intel-next-2014-04-16:
- vlv infoframe fixes from Jesse
- dsi/mipi fixes from Shobhit
- gen8 pageflip fixes for LRI/SRM from Damien
- cmd parser fixes from Brad Volkin
- some prep patches for CHV, DRRS, ...
- and tons of little things all over
drm-intel-next-2014-04-04:
- cmd parser for gen7 but only in enforcing and not yet granting mode - the
  batch copying stuff is still missing. Also performance is a bit ... rough
  (Brad Volkin + OACONTROL fix from Ken).
- deprecate UMS harder (i.e. CONFIG_BROKEN)
- interrupt rework from Paulo Zanoni
- runtime PM support for bdw and snb, again from Paulo
- a pile of refactorings from various people all over the place to prep for new
  stuff (irq reworks, power domain polish, ...)

drm-intel-next-2014-04-04:
- cmd parser for gen7 but only in enforcing and not yet granting mode - the
  batch copying stuff is still missing. Also performance is a bit ... rough
  (Brad Volkin + OACONTROL fix from Ken).
- deprecate UMS harder (i.e. CONFIG_BROKEN)
- interrupt rework from Paulo Zanoni
- runtime PM support for bdw and snb, again from Paulo
- a pile of refactorings from various people all over the place to prep for new
  stuff (irq reworks, power domain polish, ...)

Conflicts:
	drivers/gpu/drm/i915/i915_gem_context.c
parents 8aa9e85a c7905792
...@@ -131,11 +131,11 @@ drm_clflush_sg(struct sg_table *st) ...@@ -131,11 +131,11 @@ drm_clflush_sg(struct sg_table *st)
EXPORT_SYMBOL(drm_clflush_sg); EXPORT_SYMBOL(drm_clflush_sg);
void void
drm_clflush_virt_range(char *addr, unsigned long length) drm_clflush_virt_range(void *addr, unsigned long length)
{ {
#if defined(CONFIG_X86) #if defined(CONFIG_X86)
if (cpu_has_clflush) { if (cpu_has_clflush) {
char *end = addr + length; void *end = addr + length;
mb(); mb();
for (; addr < end; addr += boot_cpu_data.x86_clflush_size) for (; addr < end; addr += boot_cpu_data.x86_clflush_size)
clflush(addr); clflush(addr);
......
...@@ -71,7 +71,7 @@ config DRM_I915_PRELIMINARY_HW_SUPPORT ...@@ -71,7 +71,7 @@ config DRM_I915_PRELIMINARY_HW_SUPPORT
config DRM_I915_UMS config DRM_I915_UMS
bool "Enable userspace modesetting on Intel hardware (DEPRECATED)" bool "Enable userspace modesetting on Intel hardware (DEPRECATED)"
depends on DRM_I915 depends on DRM_I915 && BROKEN
default n default n
help help
Choose this option if you still need userspace modesetting. Choose this option if you still need userspace modesetting.
......
...@@ -160,7 +160,7 @@ static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) ...@@ -160,7 +160,7 @@ static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
if (i2c_transfer(adapter, msgs, 2) == 2) { if (i2c_transfer(adapter, msgs, 2) == 2) {
*ch = in_buf[0]; *ch = in_buf[0];
return true; return true;
}; }
if (!ch7xxx->quiet) { if (!ch7xxx->quiet) {
DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n", DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
......
...@@ -195,7 +195,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) ...@@ -195,7 +195,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data)
if (i2c_transfer(adapter, msgs, 3) == 3) { if (i2c_transfer(adapter, msgs, 3) == 3) {
*data = (in_buf[1] << 8) | in_buf[0]; *data = (in_buf[1] << 8) | in_buf[0];
return true; return true;
}; }
if (!priv->quiet) { if (!priv->quiet) {
DRM_DEBUG_KMS("Unable to read register 0x%02x from " DRM_DEBUG_KMS("Unable to read register 0x%02x from "
......
...@@ -121,7 +121,7 @@ static bool ns2501_readb(struct intel_dvo_device *dvo, int addr, uint8_t * ch) ...@@ -121,7 +121,7 @@ static bool ns2501_readb(struct intel_dvo_device *dvo, int addr, uint8_t * ch)
if (i2c_transfer(adapter, msgs, 2) == 2) { if (i2c_transfer(adapter, msgs, 2) == 2) {
*ch = in_buf[0]; *ch = in_buf[0];
return true; return true;
}; }
if (!ns->quiet) { if (!ns->quiet) {
DRM_DEBUG_KMS DRM_DEBUG_KMS
...@@ -233,9 +233,8 @@ static enum drm_mode_status ns2501_mode_valid(struct intel_dvo_device *dvo, ...@@ -233,9 +233,8 @@ static enum drm_mode_status ns2501_mode_valid(struct intel_dvo_device *dvo,
struct drm_display_mode *mode) struct drm_display_mode *mode)
{ {
DRM_DEBUG_KMS DRM_DEBUG_KMS
("%s: is mode valid (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d)\n", ("is mode valid (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d)\n",
__FUNCTION__, mode->hdisplay, mode->htotal, mode->vdisplay, mode->hdisplay, mode->htotal, mode->vdisplay, mode->vtotal);
mode->vtotal);
/* /*
* Currently, these are all the modes I have data from. * Currently, these are all the modes I have data from.
...@@ -261,9 +260,8 @@ static void ns2501_mode_set(struct intel_dvo_device *dvo, ...@@ -261,9 +260,8 @@ static void ns2501_mode_set(struct intel_dvo_device *dvo,
struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv); struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
DRM_DEBUG_KMS DRM_DEBUG_KMS
("%s: set mode (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d).\n", ("set mode (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d).\n",
__FUNCTION__, mode->hdisplay, mode->htotal, mode->vdisplay, mode->hdisplay, mode->htotal, mode->vdisplay, mode->vtotal);
mode->vtotal);
/* /*
* Where do I find the native resolution for which scaling is not required??? * Where do I find the native resolution for which scaling is not required???
...@@ -277,8 +275,7 @@ static void ns2501_mode_set(struct intel_dvo_device *dvo, ...@@ -277,8 +275,7 @@ static void ns2501_mode_set(struct intel_dvo_device *dvo,
if (mode->hdisplay == 800 && mode->vdisplay == 600) { if (mode->hdisplay == 800 && mode->vdisplay == 600) {
/* mode 277 */ /* mode 277 */
ns->reg_8_shadow &= ~NS2501_8_BPAS; ns->reg_8_shadow &= ~NS2501_8_BPAS;
DRM_DEBUG_KMS("%s: switching to 800x600\n", DRM_DEBUG_KMS("switching to 800x600\n");
__FUNCTION__);
/* /*
* No, I do not know where this data comes from. * No, I do not know where this data comes from.
...@@ -341,8 +338,7 @@ static void ns2501_mode_set(struct intel_dvo_device *dvo, ...@@ -341,8 +338,7 @@ static void ns2501_mode_set(struct intel_dvo_device *dvo,
} else if (mode->hdisplay == 640 && mode->vdisplay == 480) { } else if (mode->hdisplay == 640 && mode->vdisplay == 480) {
/* mode 274 */ /* mode 274 */
DRM_DEBUG_KMS("%s: switching to 640x480\n", DRM_DEBUG_KMS("switching to 640x480\n");
__FUNCTION__);
/* /*
* No, I do not know where this data comes from. * No, I do not know where this data comes from.
* It is just what the video bios left in the DVO, so * It is just what the video bios left in the DVO, so
...@@ -406,8 +402,7 @@ static void ns2501_mode_set(struct intel_dvo_device *dvo, ...@@ -406,8 +402,7 @@ static void ns2501_mode_set(struct intel_dvo_device *dvo,
} else if (mode->hdisplay == 1024 && mode->vdisplay == 768) { } else if (mode->hdisplay == 1024 && mode->vdisplay == 768) {
/* mode 280 */ /* mode 280 */
DRM_DEBUG_KMS("%s: switching to 1024x768\n", DRM_DEBUG_KMS("switching to 1024x768\n");
__FUNCTION__);
/* /*
* This might or might not work, actually. I'm silently * This might or might not work, actually. I'm silently
* assuming here that the native panel resolution is * assuming here that the native panel resolution is
...@@ -458,8 +453,7 @@ static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable) ...@@ -458,8 +453,7 @@ static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable)
struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv); struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
unsigned char ch; unsigned char ch;
DRM_DEBUG_KMS("%s: Trying set the dpms of the DVO to %i\n", DRM_DEBUG_KMS("Trying set the dpms of the DVO to %i\n", enable);
__FUNCTION__, enable);
ch = ns->reg_8_shadow; ch = ns->reg_8_shadow;
......
...@@ -93,7 +93,7 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) ...@@ -93,7 +93,7 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
if (i2c_transfer(adapter, msgs, 2) == 2) { if (i2c_transfer(adapter, msgs, 2) == 2) {
*ch = in_buf[0]; *ch = in_buf[0];
return true; return true;
}; }
if (!sil->quiet) { if (!sil->quiet) {
DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n", DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
......
...@@ -118,7 +118,7 @@ static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) ...@@ -118,7 +118,7 @@ static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
if (i2c_transfer(adapter, msgs, 2) == 2) { if (i2c_transfer(adapter, msgs, 2) == 2) {
*ch = in_buf[0]; *ch = in_buf[0];
return true; return true;
}; }
if (!tfp->quiet) { if (!tfp->quiet) {
DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n", DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
......
This diff is collapsed.
...@@ -966,7 +966,7 @@ static int i915_rstdby_delays(struct seq_file *m, void *unused) ...@@ -966,7 +966,7 @@ static int i915_rstdby_delays(struct seq_file *m, void *unused)
return 0; return 0;
} }
static int i915_cur_delayinfo(struct seq_file *m, void *unused) static int i915_frequency_info(struct seq_file *m, void *unused)
{ {
struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev; struct drm_device *dev = node->minor->dev;
...@@ -991,6 +991,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) ...@@ -991,6 +991,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
u32 rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS); u32 rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS);
u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
u32 rpmodectl, rpinclimit, rpdeclimit;
u32 rpstat, cagf, reqf; u32 rpstat, cagf, reqf;
u32 rpupei, rpcurup, rpprevup; u32 rpupei, rpcurup, rpprevup;
u32 rpdownei, rpcurdown, rpprevdown; u32 rpdownei, rpcurdown, rpprevdown;
...@@ -1011,6 +1012,10 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) ...@@ -1011,6 +1012,10 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
reqf >>= 25; reqf >>= 25;
reqf *= GT_FREQUENCY_MULTIPLIER; reqf *= GT_FREQUENCY_MULTIPLIER;
rpmodectl = I915_READ(GEN6_RP_CONTROL);
rpinclimit = I915_READ(GEN6_RP_UP_THRESHOLD);
rpdeclimit = I915_READ(GEN6_RP_DOWN_THRESHOLD);
rpstat = I915_READ(GEN6_RPSTAT1); rpstat = I915_READ(GEN6_RPSTAT1);
rpupei = I915_READ(GEN6_RP_CUR_UP_EI); rpupei = I915_READ(GEN6_RP_CUR_UP_EI);
rpcurup = I915_READ(GEN6_RP_CUR_UP); rpcurup = I915_READ(GEN6_RP_CUR_UP);
...@@ -1027,14 +1032,23 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) ...@@ -1027,14 +1032,23 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
seq_printf(m, "PM IER=0x%08x IMR=0x%08x ISR=0x%08x IIR=0x%08x, MASK=0x%08x\n",
I915_READ(GEN6_PMIER),
I915_READ(GEN6_PMIMR),
I915_READ(GEN6_PMISR),
I915_READ(GEN6_PMIIR),
I915_READ(GEN6_PMINTRMSK));
seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status); seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status);
seq_printf(m, "RPSTAT1: 0x%08x\n", rpstat);
seq_printf(m, "Render p-state ratio: %d\n", seq_printf(m, "Render p-state ratio: %d\n",
(gt_perf_status & 0xff00) >> 8); (gt_perf_status & 0xff00) >> 8);
seq_printf(m, "Render p-state VID: %d\n", seq_printf(m, "Render p-state VID: %d\n",
gt_perf_status & 0xff); gt_perf_status & 0xff);
seq_printf(m, "Render p-state limit: %d\n", seq_printf(m, "Render p-state limit: %d\n",
rp_state_limits & 0xff); rp_state_limits & 0xff);
seq_printf(m, "RPSTAT1: 0x%08x\n", rpstat);
seq_printf(m, "RPMODECTL: 0x%08x\n", rpmodectl);
seq_printf(m, "RPINCLIMIT: 0x%08x\n", rpinclimit);
seq_printf(m, "RPDECLIMIT: 0x%08x\n", rpdeclimit);
seq_printf(m, "RPNSWREQ: %dMHz\n", reqf); seq_printf(m, "RPNSWREQ: %dMHz\n", reqf);
seq_printf(m, "CAGF: %dMHz\n", cagf); seq_printf(m, "CAGF: %dMHz\n", cagf);
seq_printf(m, "RP CUR UP EI: %dus\n", rpupei & seq_printf(m, "RP CUR UP EI: %dus\n", rpupei &
...@@ -1816,8 +1830,7 @@ static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev) ...@@ -1816,8 +1830,7 @@ static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev)
u64 pdp = I915_READ(ring->mmio_base + offset + 4); u64 pdp = I915_READ(ring->mmio_base + offset + 4);
pdp <<= 32; pdp <<= 32;
pdp |= I915_READ(ring->mmio_base + offset); pdp |= I915_READ(ring->mmio_base + offset);
for (i = 0; i < 4; i++) seq_printf(m, "\tPDP%d 0x%016llx\n", i, pdp);
seq_printf(m, "\tPDP%d 0x%016llx\n", i, pdp);
} }
} }
} }
...@@ -2044,7 +2057,7 @@ static int i915_pc8_status(struct seq_file *m, void *unused) ...@@ -2044,7 +2057,7 @@ static int i915_pc8_status(struct seq_file *m, void *unused)
struct drm_device *dev = node->minor->dev; struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
if (!IS_HASWELL(dev)) { if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
seq_puts(m, "not supported\n"); seq_puts(m, "not supported\n");
return 0; return 0;
} }
...@@ -3774,7 +3787,7 @@ static const struct drm_info_list i915_debugfs_list[] = { ...@@ -3774,7 +3787,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_gem_hws_bsd", i915_hws_info, 0, (void *)VCS}, {"i915_gem_hws_bsd", i915_hws_info, 0, (void *)VCS},
{"i915_gem_hws_vebox", i915_hws_info, 0, (void *)VECS}, {"i915_gem_hws_vebox", i915_hws_info, 0, (void *)VECS},
{"i915_rstdby_delays", i915_rstdby_delays, 0}, {"i915_rstdby_delays", i915_rstdby_delays, 0},
{"i915_cur_delayinfo", i915_cur_delayinfo, 0}, {"i915_frequency_info", i915_frequency_info, 0},
{"i915_delayfreq_table", i915_delayfreq_table, 0}, {"i915_delayfreq_table", i915_delayfreq_table, 0},
{"i915_inttoext_table", i915_inttoext_table, 0}, {"i915_inttoext_table", i915_inttoext_table, 0},
{"i915_drpc_info", i915_drpc_info, 0}, {"i915_drpc_info", i915_drpc_info, 0},
......
...@@ -1017,6 +1017,9 @@ static int i915_getparam(struct drm_device *dev, void *data, ...@@ -1017,6 +1017,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_HAS_EXEC_HANDLE_LUT: case I915_PARAM_HAS_EXEC_HANDLE_LUT:
value = 1; value = 1;
break; break;
case I915_PARAM_CMD_PARSER_VERSION:
value = i915_cmd_parser_get_version();
break;
default: default:
DRM_DEBUG("Unknown parameter %d\n", param->param); DRM_DEBUG("Unknown parameter %d\n", param->param);
return -EINVAL; return -EINVAL;
......
...@@ -891,7 +891,36 @@ static int i915_pm_poweroff(struct device *dev) ...@@ -891,7 +891,36 @@ static int i915_pm_poweroff(struct device *dev)
return i915_drm_freeze(drm_dev); return i915_drm_freeze(drm_dev);
} }
static int i915_runtime_suspend(struct device *device) static void snb_runtime_suspend(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = dev_priv->dev;
intel_runtime_pm_disable_interrupts(dev);
}
static void hsw_runtime_suspend(struct drm_i915_private *dev_priv)
{
hsw_enable_pc8(dev_priv);
}
static void snb_runtime_resume(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = dev_priv->dev;
intel_runtime_pm_restore_interrupts(dev);
intel_init_pch_refclk(dev);
i915_gem_init_swizzling(dev);
mutex_lock(&dev_priv->rps.hw_lock);
gen6_update_ring_freq(dev);
mutex_unlock(&dev_priv->rps.hw_lock);
}
static void hsw_runtime_resume(struct drm_i915_private *dev_priv)
{
hsw_disable_pc8(dev_priv);
}
static int intel_runtime_suspend(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);
...@@ -902,8 +931,12 @@ static int i915_runtime_suspend(struct device *device) ...@@ -902,8 +931,12 @@ static int i915_runtime_suspend(struct device *device)
DRM_DEBUG_KMS("Suspending device\n"); DRM_DEBUG_KMS("Suspending device\n");
if (HAS_PC8(dev)) if (IS_GEN6(dev))
hsw_enable_pc8(dev_priv); snb_runtime_suspend(dev_priv);
else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
hsw_runtime_suspend(dev_priv);
else
WARN_ON(1);
i915_gem_release_all_mmaps(dev_priv); i915_gem_release_all_mmaps(dev_priv);
...@@ -923,7 +956,7 @@ static int i915_runtime_suspend(struct device *device) ...@@ -923,7 +956,7 @@ static int i915_runtime_suspend(struct device *device)
return 0; return 0;
} }
static int i915_runtime_resume(struct device *device) 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);
...@@ -936,8 +969,12 @@ static int i915_runtime_resume(struct device *device) ...@@ -936,8 +969,12 @@ static int i915_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;
if (HAS_PC8(dev)) if (IS_GEN6(dev))
hsw_disable_pc8(dev_priv); snb_runtime_resume(dev_priv);
else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
hsw_runtime_resume(dev_priv);
else
WARN_ON(1);
DRM_DEBUG_KMS("Device resumed\n"); DRM_DEBUG_KMS("Device resumed\n");
return 0; return 0;
...@@ -954,8 +991,8 @@ static const struct dev_pm_ops i915_pm_ops = { ...@@ -954,8 +991,8 @@ static const struct dev_pm_ops i915_pm_ops = {
.poweroff = i915_pm_poweroff, .poweroff = i915_pm_poweroff,
.restore_early = i915_pm_resume_early, .restore_early = i915_pm_resume_early,
.restore = i915_pm_resume, .restore = i915_pm_resume,
.runtime_suspend = i915_runtime_suspend, .runtime_suspend = intel_runtime_suspend,
.runtime_resume = i915_runtime_resume, .runtime_resume = intel_runtime_resume,
}; };
static const struct vm_operations_struct i915_gem_vm_ops = { static const struct vm_operations_struct i915_gem_vm_ops = {
......
This diff is collapsed.
...@@ -2277,8 +2277,9 @@ static bool i915_context_is_banned(struct drm_i915_private *dev_priv, ...@@ -2277,8 +2277,9 @@ static bool i915_context_is_banned(struct drm_i915_private *dev_priv,
if (!i915_gem_context_is_default(ctx)) { if (!i915_gem_context_is_default(ctx)) {
DRM_DEBUG("context hanging too fast, banning!\n"); DRM_DEBUG("context hanging too fast, banning!\n");
return true; return true;
} else if (dev_priv->gpu_error.stop_rings == 0) { } else if (i915_stop_ring_allow_ban(dev_priv)) {
DRM_ERROR("gpu hanging too fast, banning!\n"); if (i915_stop_ring_allow_warn(dev_priv))
DRM_ERROR("gpu hanging too fast, banning!\n");
return true; return true;
} }
} }
......
...@@ -240,7 +240,15 @@ __create_hw_context(struct drm_device *dev, ...@@ -240,7 +240,15 @@ __create_hw_context(struct drm_device *dev,
goto err_out; goto err_out;
} }
if (INTEL_INFO(dev)->gen >= 7) { /*
* Try to make the context utilize L3 as well as LLC.
*
* On VLV we don't have L3 controls in the PTEs so we
* shouldn't touch the cache level, especially as that
* would make the object snooped which might have a
* negative performance impact.
*/
if (INTEL_INFO(dev)->gen >= 7 && !IS_VALLEYVIEW(dev)) {
ret = i915_gem_object_set_cache_level(ctx->obj, ret = i915_gem_object_set_cache_level(ctx->obj,
I915_CACHE_L3_LLC); I915_CACHE_L3_LLC);
/* Failure shouldn't ever happen this early */ /* Failure shouldn't ever happen this early */
...@@ -549,7 +557,7 @@ mi_set_context(struct intel_ring_buffer *ring, ...@@ -549,7 +557,7 @@ mi_set_context(struct intel_ring_buffer *ring,
* explicitly, so we rely on the value at ring init, stored in * explicitly, so we rely on the value at ring init, stored in
* itlb_before_ctx_switch. * itlb_before_ctx_switch.
*/ */
if (IS_GEN6(ring->dev) && ring->itlb_before_ctx_switch) { if (IS_GEN6(ring->dev)) {
ret = ring->flush(ring, I915_GEM_GPU_DOMAINS, 0); ret = ring->flush(ring, I915_GEM_GPU_DOMAINS, 0);
if (ret) if (ret)
return ret; return ret;
...@@ -559,8 +567,8 @@ mi_set_context(struct intel_ring_buffer *ring, ...@@ -559,8 +567,8 @@ mi_set_context(struct intel_ring_buffer *ring,
if (ret) if (ret)
return ret; return ret;
/* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw */ /* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw,bdw */
if (IS_GEN7(ring->dev)) if (INTEL_INFO(ring->dev)->gen >= 7)
intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_DISABLE); intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_DISABLE);
else else
intel_ring_emit(ring, MI_NOOP); intel_ring_emit(ring, MI_NOOP);
...@@ -578,7 +586,7 @@ mi_set_context(struct intel_ring_buffer *ring, ...@@ -578,7 +586,7 @@ mi_set_context(struct intel_ring_buffer *ring,
*/ */
intel_ring_emit(ring, MI_NOOP); intel_ring_emit(ring, MI_NOOP);
if (IS_GEN7(ring->dev)) if (INTEL_INFO(ring->dev)->gen >= 7)
intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_ENABLE); intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_ENABLE);
else else
intel_ring_emit(ring, MI_NOOP); intel_ring_emit(ring, MI_NOOP);
......
...@@ -161,12 +161,8 @@ static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr) ...@@ -161,12 +161,8 @@ static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
{ {
struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
struct drm_device *dev = obj->base.dev; struct drm_device *dev = obj->base.dev;
int ret;
ret = i915_mutex_lock_interruptible(dev);
if (ret)
return;
mutex_lock(&dev->struct_mutex);
if (--obj->vmapping_count == 0) { if (--obj->vmapping_count == 0) {
vunmap(obj->dma_buf_vmapping); vunmap(obj->dma_buf_vmapping);
obj->dma_buf_vmapping = NULL; obj->dma_buf_vmapping = NULL;
......
...@@ -1132,7 +1132,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, ...@@ -1132,7 +1132,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
ret = PTR_ERR(ctx); ret = PTR_ERR(ctx);
goto pre_mutex_err; goto pre_mutex_err;
} }
i915_gem_context_reference(ctx); i915_gem_context_reference(ctx);
...@@ -1142,6 +1142,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, ...@@ -1142,6 +1142,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
eb = eb_create(args); eb = eb_create(args);
if (eb == NULL) { if (eb == NULL) {
i915_gem_context_unreference(ctx);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
ret = -ENOMEM; ret = -ENOMEM;
goto pre_mutex_err; goto pre_mutex_err;
......
...@@ -55,59 +55,6 @@ bool intel_enable_ppgtt(struct drm_device *dev, bool full) ...@@ -55,59 +55,6 @@ bool intel_enable_ppgtt(struct drm_device *dev, bool full)
return HAS_ALIASING_PPGTT(dev); return HAS_ALIASING_PPGTT(dev);
} }
#define GEN6_PPGTT_PD_ENTRIES 512
#define I915_PPGTT_PT_ENTRIES (PAGE_SIZE / sizeof(gen6_gtt_pte_t))
typedef uint64_t gen8_gtt_pte_t;
typedef gen8_gtt_pte_t gen8_ppgtt_pde_t;
/* PPGTT stuff */
#define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0))
#define HSW_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0x7f0))
#define GEN6_PDE_VALID (1 << 0)
/* gen6+ has bit 11-4 for physical addr bit 39-32 */
#define GEN6_PDE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr)
#define GEN6_PTE_VALID (1 << 0)
#define GEN6_PTE_UNCACHED (1 << 1)
#define HSW_PTE_UNCACHED (0)
#define GEN6_PTE_CACHE_LLC (2 << 1)
#define GEN7_PTE_CACHE_L3_LLC (3 << 1)
#define GEN6_PTE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr)
#define HSW_PTE_ADDR_ENCODE(addr) HSW_GTT_ADDR_ENCODE(addr)
/* Cacheability Control is a 4-bit value. The low three bits are stored in *
* bits 3:1 of the PTE, while the fourth bit is stored in bit 11 of the PTE.
*/
#define HSW_CACHEABILITY_CONTROL(bits) ((((bits) & 0x7) << 1) | \
(((bits) & 0x8) << (11 - 3)))
#define HSW_WB_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x2)
#define HSW_WB_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x3)
#define HSW_WB_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0xb)
#define HSW_WB_ELLC_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x8)
#define HSW_WT_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x6)
#define HSW_WT_ELLC_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x7)
#define GEN8_PTES_PER_PAGE (PAGE_SIZE / sizeof(gen8_gtt_pte_t))
#define GEN8_PDES_PER_PAGE (PAGE_SIZE / sizeof(gen8_ppgtt_pde_t))
/* GEN8 legacy style addressis defined as a 3 level page table:
* 31:30 | 29:21 | 20:12 | 11:0
* PDPE | PDE | PTE | offset
* The difference as compared to normal x86 3 level page table is the PDPEs are
* programmed via register.
*/
#define GEN8_PDPE_SHIFT 30
#define GEN8_PDPE_MASK 0x3
#define GEN8_PDE_SHIFT 21
#define GEN8_PDE_MASK 0x1ff
#define GEN8_PTE_SHIFT 12
#define GEN8_PTE_MASK 0x1ff
#define PPAT_UNCACHED_INDEX (_PAGE_PWT | _PAGE_PCD)
#define PPAT_CACHED_PDE_INDEX 0 /* WB LLC */
#define PPAT_CACHED_INDEX _PAGE_PAT /* WB LLCeLLC */
#define PPAT_DISPLAY_ELLC_INDEX _PAGE_PCD /* WT eLLC */
static void ppgtt_bind_vma(struct i915_vma *vma, static void ppgtt_bind_vma(struct i915_vma *vma,
enum i915_cache_level cache_level, enum i915_cache_level cache_level,
...@@ -187,9 +134,6 @@ static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr, ...@@ -187,9 +134,6 @@ static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr,
return pte; return pte;
} }
#define BYT_PTE_WRITEABLE (1 << 1)
#define BYT_PTE_SNOOPED_BY_CPU_CACHES (1 << 2)
static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr, static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr,
enum i915_cache_level level, enum i915_cache_level level,
bool valid) bool valid)
...@@ -1057,8 +1001,6 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm) ...@@ -1057,8 +1001,6 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
static int gen6_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt) static int gen6_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt)
{ {
#define GEN6_PD_ALIGN (PAGE_SIZE * 16)
#define GEN6_PD_SIZE (GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE)
struct drm_device *dev = ppgtt->base.dev; struct drm_device *dev = ppgtt->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
bool retried = false; bool retried = false;
...@@ -1848,17 +1790,6 @@ static int ggtt_probe_common(struct drm_device *dev, ...@@ -1848,17 +1790,6 @@ static int ggtt_probe_common(struct drm_device *dev,
* writing this data shouldn't be harmful even in those cases. */ * writing this data shouldn't be harmful even in those cases. */
static void gen8_setup_private_ppat(struct drm_i915_private *dev_priv) static void gen8_setup_private_ppat(struct drm_i915_private *dev_priv)
{ {
#define GEN8_PPAT_UC (0<<0)
#define GEN8_PPAT_WC (1<<0)
#define GEN8_PPAT_WT (2<<0)
#define GEN8_PPAT_WB (3<<0)
#define GEN8_PPAT_ELLC_OVERRIDE (0<<2)
/* FIXME(BDW): Bspec is completely confused about cache control bits. */
#define GEN8_PPAT_LLC (1<<2)
#define GEN8_PPAT_LLCELLC (2<<2)
#define GEN8_PPAT_LLCeLLC (3<<2)
#define GEN8_PPAT_AGE(x) (x<<4)
#define GEN8_PPAT(i, x) ((uint64_t) (x) << ((i) * 8))
uint64_t pat; uint64_t pat;
pat = GEN8_PPAT(0, GEN8_PPAT_WB | GEN8_PPAT_LLC) | /* for normal objects, no eLLC */ pat = GEN8_PPAT(0, GEN8_PPAT_WB | GEN8_PPAT_LLC) | /* for normal objects, no eLLC */
...@@ -2031,6 +1962,10 @@ int i915_gem_gtt_init(struct drm_device *dev) ...@@ -2031,6 +1962,10 @@ int i915_gem_gtt_init(struct drm_device *dev)
gtt->base.total >> 20); gtt->base.total >> 20);
DRM_DEBUG_DRIVER("GMADR size = %ldM\n", gtt->mappable_end >> 20); DRM_DEBUG_DRIVER("GMADR size = %ldM\n", gtt->mappable_end >> 20);
DRM_DEBUG_DRIVER("GTT stolen size = %zdM\n", gtt->stolen_size >> 20); DRM_DEBUG_DRIVER("GTT stolen size = %zdM\n", gtt->stolen_size >> 20);
#ifdef CONFIG_INTEL_IOMMU
if (intel_iommu_gfx_mapped)
DRM_INFO("VT-d active for gfx access\n");
#endif
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -257,7 +257,8 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m, ...@@ -257,7 +257,8 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
err_printf(m, " INSTPS: 0x%08x\n", ring->instps); err_printf(m, " INSTPS: 0x%08x\n", ring->instps);
} }
err_printf(m, " INSTPM: 0x%08x\n", ring->instpm); err_printf(m, " INSTPM: 0x%08x\n", ring->instpm);
err_printf(m, " FADDR: 0x%08x\n", ring->faddr); err_printf(m, " FADDR: 0x%08x %08x\n", upper_32_bits(ring->faddr),
lower_32_bits(ring->faddr));
if (INTEL_INFO(dev)->gen >= 6) { if (INTEL_INFO(dev)->gen >= 6) {
err_printf(m, " RC PSMI: 0x%08x\n", ring->rc_psmi); err_printf(m, " RC PSMI: 0x%08x\n", ring->rc_psmi);
err_printf(m, " FAULT_REG: 0x%08x\n", ring->fault_reg); err_printf(m, " FAULT_REG: 0x%08x\n", ring->fault_reg);
...@@ -452,16 +453,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, ...@@ -452,16 +453,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
err_printf(m, "%s --- HW Context = 0x%08x\n", err_printf(m, "%s --- HW Context = 0x%08x\n",
dev_priv->ring[i].name, dev_priv->ring[i].name,
obj->gtt_offset); obj->gtt_offset);
offset = 0; print_error_obj(m, obj);
for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
err_printf(m, "[%04x] %08x %08x %08x %08x\n",
offset,
obj->pages[0][elt],
obj->pages[0][elt+1],
obj->pages[0][elt+2],
obj->pages[0][elt+3]);
offset += 16;
}
} }
} }
...@@ -781,8 +773,10 @@ static void i915_record_ring_state(struct drm_device *dev, ...@@ -781,8 +773,10 @@ static void i915_record_ring_state(struct drm_device *dev,
ering->instdone = I915_READ(RING_INSTDONE(ring->mmio_base)); ering->instdone = I915_READ(RING_INSTDONE(ring->mmio_base));
ering->instps = I915_READ(RING_INSTPS(ring->mmio_base)); ering->instps = I915_READ(RING_INSTPS(ring->mmio_base));
ering->bbaddr = I915_READ(RING_BBADDR(ring->mmio_base)); ering->bbaddr = I915_READ(RING_BBADDR(ring->mmio_base));
if (INTEL_INFO(dev)->gen >= 8) if (INTEL_INFO(dev)->gen >= 8) {
ering->faddr |= (u64) I915_READ(RING_DMA_FADD_UDW(ring->mmio_base)) << 32;
ering->bbaddr |= (u64) I915_READ(RING_BBADDR_UDW(ring->mmio_base)) << 32; ering->bbaddr |= (u64) I915_READ(RING_BBADDR_UDW(ring->mmio_base)) << 32;
}
ering->bbstate = I915_READ(RING_BBSTATE(ring->mmio_base)); ering->bbstate = I915_READ(RING_BBSTATE(ring->mmio_base));
} else { } else {
ering->faddr = I915_READ(DMA_FADD_I8XX); ering->faddr = I915_READ(DMA_FADD_I8XX);
...@@ -875,10 +869,7 @@ static void i915_gem_record_active_context(struct intel_ring_buffer *ring, ...@@ -875,10 +869,7 @@ static void i915_gem_record_active_context(struct intel_ring_buffer *ring,
list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
if ((error->ccid & PAGE_MASK) == i915_gem_obj_ggtt_offset(obj)) { if ((error->ccid & PAGE_MASK) == i915_gem_obj_ggtt_offset(obj)) {
ering->ctx = i915_error_object_create_sized(dev_priv, ering->ctx = i915_error_ggtt_object_create(dev_priv, obj);
obj,
&dev_priv->gtt.base,
1);
break; break;
} }
} }
......
This diff is collapsed.
...@@ -46,7 +46,8 @@ struct i915_params i915 __read_mostly = { ...@@ -46,7 +46,8 @@ struct i915_params i915 __read_mostly = {
.reset = true, .reset = true,
.invert_brightness = 0, .invert_brightness = 0,
.disable_display = 0, .disable_display = 0,
.enable_cmd_parser = 0, .enable_cmd_parser = 1,
.disable_vtd_wa = 0,
}; };
module_param_named(modeset, i915.modeset, int, 0400); module_param_named(modeset, i915.modeset, int, 0400);
...@@ -149,6 +150,9 @@ MODULE_PARM_DESC(invert_brightness, ...@@ -149,6 +150,9 @@ MODULE_PARM_DESC(invert_brightness,
module_param_named(disable_display, i915.disable_display, bool, 0600); module_param_named(disable_display, i915.disable_display, bool, 0600);
MODULE_PARM_DESC(disable_display, "Disable display (default: false)"); MODULE_PARM_DESC(disable_display, "Disable display (default: false)");
module_param_named(disable_vtd_wa, i915.disable_vtd_wa, bool, 0600);
MODULE_PARM_DESC(disable_vtd_wa, "Disable all VT-d workarounds (default: false)");
module_param_named(enable_cmd_parser, i915.enable_cmd_parser, int, 0600); module_param_named(enable_cmd_parser, i915.enable_cmd_parser, int, 0600);
MODULE_PARM_DESC(enable_cmd_parser, MODULE_PARM_DESC(enable_cmd_parser,
"Enable command parsing (1=enabled, 0=disabled [default])"); "Enable command parsing (1=enabled [default], 0=disabled)");
...@@ -190,6 +190,8 @@ ...@@ -190,6 +190,8 @@
* Memory interface instructions used by the kernel * Memory interface instructions used by the kernel
*/ */
#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags)) #define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
/* Many MI commands use bit 22 of the header dword for GGTT vs PPGTT */
#define MI_GLOBAL_GTT (1<<22)
#define MI_NOOP MI_INSTR(0, 0) #define MI_NOOP MI_INSTR(0, 0)
#define MI_USER_INTERRUPT MI_INSTR(0x02, 0) #define MI_USER_INTERRUPT MI_INSTR(0x02, 0)
...@@ -244,7 +246,8 @@ ...@@ -244,7 +246,8 @@
#define MI_SEMAPHORE_SYNC_BVE (0<<16) /* VECS wait for BCS (VEBSYNC) */ #define MI_SEMAPHORE_SYNC_BVE (0<<16) /* VECS wait for BCS (VEBSYNC) */
#define MI_SEMAPHORE_SYNC_VVE (1<<16) /* VECS wait for VCS (VEVSYNC) */ #define MI_SEMAPHORE_SYNC_VVE (1<<16) /* VECS wait for VCS (VEVSYNC) */
#define MI_SEMAPHORE_SYNC_RVE (2<<16) /* VECS wait for RCS (VERSYNC) */ #define MI_SEMAPHORE_SYNC_RVE (2<<16) /* VECS wait for RCS (VERSYNC) */
#define MI_SEMAPHORE_SYNC_INVALID (3<<16) #define MI_SEMAPHORE_SYNC_INVALID (3<<16)
#define MI_SEMAPHORE_SYNC_MASK (3<<16)
#define MI_SET_CONTEXT MI_INSTR(0x18, 0) #define MI_SET_CONTEXT MI_INSTR(0x18, 0)
#define MI_MM_SPACE_GTT (1<<8) #define MI_MM_SPACE_GTT (1<<8)
#define MI_MM_SPACE_PHYSICAL (0<<8) #define MI_MM_SPACE_PHYSICAL (0<<8)
...@@ -262,13 +265,16 @@ ...@@ -262,13 +265,16 @@
* - One can actually load arbitrary many arbitrary registers: Simply issue x * - One can actually load arbitrary many arbitrary registers: Simply issue x
* address/value pairs. Don't overdue it, though, x <= 2^4 must hold! * address/value pairs. Don't overdue it, though, x <= 2^4 must hold!
*/ */
#define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*x-1) #define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*(x)-1)
#define MI_STORE_REGISTER_MEM(x) MI_INSTR(0x24, 2*x-1) #define MI_STORE_REGISTER_MEM(x) MI_INSTR(0x24, 2*(x)-1)
#define MI_STORE_REGISTER_MEM_GEN8(x) MI_INSTR(0x24, 3*(x)-1)
#define MI_SRM_LRM_GLOBAL_GTT (1<<22) #define MI_SRM_LRM_GLOBAL_GTT (1<<22)
#define MI_FLUSH_DW MI_INSTR(0x26, 1) /* for GEN6 */ #define MI_FLUSH_DW MI_INSTR(0x26, 1) /* for GEN6 */
#define MI_FLUSH_DW_STORE_INDEX (1<<21) #define MI_FLUSH_DW_STORE_INDEX (1<<21)
#define MI_INVALIDATE_TLB (1<<18) #define MI_INVALIDATE_TLB (1<<18)
#define MI_FLUSH_DW_OP_STOREDW (1<<14) #define MI_FLUSH_DW_OP_STOREDW (1<<14)
#define MI_FLUSH_DW_OP_MASK (3<<14)
#define MI_FLUSH_DW_NOTIFY (1<<8)
#define MI_INVALIDATE_BSD (1<<7) #define MI_INVALIDATE_BSD (1<<7)
#define MI_FLUSH_DW_USE_GTT (1<<2) #define MI_FLUSH_DW_USE_GTT (1<<2)
#define MI_FLUSH_DW_USE_PPGTT (0<<2) #define MI_FLUSH_DW_USE_PPGTT (0<<2)
...@@ -330,9 +336,12 @@ ...@@ -330,9 +336,12 @@
#define DISPLAY_PLANE_B (1<<20) #define DISPLAY_PLANE_B (1<<20)
#define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2)) #define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2))
#define PIPE_CONTROL_GLOBAL_GTT_IVB (1<<24) /* gen7+ */ #define PIPE_CONTROL_GLOBAL_GTT_IVB (1<<24) /* gen7+ */
#define PIPE_CONTROL_MMIO_WRITE (1<<23)
#define PIPE_CONTROL_STORE_DATA_INDEX (1<<21)
#define PIPE_CONTROL_CS_STALL (1<<20) #define PIPE_CONTROL_CS_STALL (1<<20)
#define PIPE_CONTROL_TLB_INVALIDATE (1<<18) #define PIPE_CONTROL_TLB_INVALIDATE (1<<18)
#define PIPE_CONTROL_QW_WRITE (1<<14) #define PIPE_CONTROL_QW_WRITE (1<<14)
#define PIPE_CONTROL_POST_SYNC_OP_MASK (3<<14)
#define PIPE_CONTROL_DEPTH_STALL (1<<13) #define PIPE_CONTROL_DEPTH_STALL (1<<13)
#define PIPE_CONTROL_WRITE_FLUSH (1<<12) #define PIPE_CONTROL_WRITE_FLUSH (1<<12)
#define PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH (1<<12) /* gen6+ */ #define PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH (1<<12) /* gen6+ */
...@@ -347,6 +356,94 @@ ...@@ -347,6 +356,94 @@
#define PIPE_CONTROL_DEPTH_CACHE_FLUSH (1<<0) #define PIPE_CONTROL_DEPTH_CACHE_FLUSH (1<<0)
#define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */ #define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */
/*
* Commands used only by the command parser
*/
#define MI_SET_PREDICATE MI_INSTR(0x01, 0)
#define MI_ARB_CHECK MI_INSTR(0x05, 0)
#define MI_RS_CONTROL MI_INSTR(0x06, 0)
#define MI_URB_ATOMIC_ALLOC MI_INSTR(0x09, 0)
#define MI_PREDICATE MI_INSTR(0x0C, 0)
#define MI_RS_CONTEXT MI_INSTR(0x0F, 0)
#define MI_TOPOLOGY_FILTER MI_INSTR(0x0D, 0)
#define MI_LOAD_SCAN_LINES_EXCL MI_INSTR(0x13, 0)
#define MI_URB_CLEAR MI_INSTR(0x19, 0)
#define MI_UPDATE_GTT MI_INSTR(0x23, 0)
#define MI_CLFLUSH MI_INSTR(0x27, 0)
#define MI_REPORT_PERF_COUNT MI_INSTR(0x28, 0)
#define MI_REPORT_PERF_COUNT_GGTT (1<<0)
#define MI_LOAD_REGISTER_MEM MI_INSTR(0x29, 0)
#define MI_LOAD_REGISTER_REG MI_INSTR(0x2A, 0)
#define MI_RS_STORE_DATA_IMM MI_INSTR(0x2B, 0)
#define MI_LOAD_URB_MEM MI_INSTR(0x2C, 0)
#define MI_STORE_URB_MEM MI_INSTR(0x2D, 0)
#define MI_CONDITIONAL_BATCH_BUFFER_END MI_INSTR(0x36, 0)
#define PIPELINE_SELECT ((0x3<<29)|(0x1<<27)|(0x1<<24)|(0x4<<16))
#define GFX_OP_3DSTATE_VF_STATISTICS ((0x3<<29)|(0x1<<27)|(0x0<<24)|(0xB<<16))
#define MEDIA_VFE_STATE ((0x3<<29)|(0x2<<27)|(0x0<<24)|(0x0<<16))
#define MEDIA_VFE_STATE_MMIO_ACCESS_MASK (0x18)
#define GPGPU_OBJECT ((0x3<<29)|(0x2<<27)|(0x1<<24)|(0x4<<16))
#define GPGPU_WALKER ((0x3<<29)|(0x2<<27)|(0x1<<24)|(0x5<<16))
#define GFX_OP_3DSTATE_DX9_CONSTANTF_VS \
((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x39<<16))
#define GFX_OP_3DSTATE_DX9_CONSTANTF_PS \
((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x3A<<16))
#define GFX_OP_3DSTATE_SO_DECL_LIST \
((0x3<<29)|(0x3<<27)|(0x1<<24)|(0x17<<16))
#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_VS \
((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x43<<16))
#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_GS \
((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x44<<16))
#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_HS \
((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x45<<16))
#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_DS \
((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x46<<16))
#define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_PS \
((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x47<<16))
#define MFX_WAIT ((0x3<<29)|(0x1<<27)|(0x0<<16))
#define COLOR_BLT ((0x2<<29)|(0x40<<22))
#define SRC_COPY_BLT ((0x2<<29)|(0x43<<22))
/*
* Registers used only by the command parser
*/
#define BCS_SWCTRL 0x22200
#define HS_INVOCATION_COUNT 0x2300
#define DS_INVOCATION_COUNT 0x2308
#define IA_VERTICES_COUNT 0x2310
#define IA_PRIMITIVES_COUNT 0x2318
#define VS_INVOCATION_COUNT 0x2320
#define GS_INVOCATION_COUNT 0x2328
#define GS_PRIMITIVES_COUNT 0x2330
#define CL_INVOCATION_COUNT 0x2338
#define CL_PRIMITIVES_COUNT 0x2340
#define PS_INVOCATION_COUNT 0x2348
#define PS_DEPTH_COUNT 0x2350
/* There are the 4 64-bit counter registers, one for each stream output */
#define GEN7_SO_NUM_PRIMS_WRITTEN(n) (0x5200 + (n) * 8)
#define GEN7_SO_PRIM_STORAGE_NEEDED(n) (0x5240 + (n) * 8)
#define GEN7_3DPRIM_END_OFFSET 0x2420
#define GEN7_3DPRIM_START_VERTEX 0x2430
#define GEN7_3DPRIM_VERTEX_COUNT 0x2434
#define GEN7_3DPRIM_INSTANCE_COUNT 0x2438
#define GEN7_3DPRIM_START_INSTANCE 0x243C
#define GEN7_3DPRIM_BASE_VERTEX 0x2440
#define OACONTROL 0x2360
#define _GEN7_PIPEA_DE_LOAD_SL 0x70068
#define _GEN7_PIPEB_DE_LOAD_SL 0x71068
#define GEN7_PIPE_DE_LOAD_SL(pipe) _PIPE(pipe, \
_GEN7_PIPEA_DE_LOAD_SL, \
_GEN7_PIPEB_DE_LOAD_SL)
/* /*
* Reset registers * Reset registers
...@@ -748,6 +845,7 @@ enum punit_power_well { ...@@ -748,6 +845,7 @@ enum punit_power_well {
#define RING_INSTDONE(base) ((base)+0x6c) #define RING_INSTDONE(base) ((base)+0x6c)
#define RING_INSTPS(base) ((base)+0x70) #define RING_INSTPS(base) ((base)+0x70)
#define RING_DMA_FADD(base) ((base)+0x78) #define RING_DMA_FADD(base) ((base)+0x78)
#define RING_DMA_FADD_UDW(base) ((base)+0x60) /* gen8+ */
#define RING_INSTPM(base) ((base)+0xc0) #define RING_INSTPM(base) ((base)+0xc0)
#define RING_MI_MODE(base) ((base)+0x9c) #define RING_MI_MODE(base) ((base)+0x9c)
#define INSTPS 0x02070 /* 965+ only */ #define INSTPS 0x02070 /* 965+ only */
...@@ -842,7 +940,7 @@ enum punit_power_well { ...@@ -842,7 +940,7 @@ enum punit_power_well {
#define GFX_MODE_GEN7 0x0229c #define GFX_MODE_GEN7 0x0229c
#define RING_MODE_GEN7(ring) ((ring)->mmio_base+0x29c) #define RING_MODE_GEN7(ring) ((ring)->mmio_base+0x29c)
#define GFX_RUN_LIST_ENABLE (1<<15) #define GFX_RUN_LIST_ENABLE (1<<15)
#define GFX_TLB_INVALIDATE_ALWAYS (1<<13) #define GFX_TLB_INVALIDATE_EXPLICIT (1<<13)
#define GFX_SURFACE_FAULT_ENABLE (1<<12) #define GFX_SURFACE_FAULT_ENABLE (1<<12)
#define GFX_REPLAY_MODE (1<<11) #define GFX_REPLAY_MODE (1<<11)
#define GFX_PSMI_GRANULARITY (1<<10) #define GFX_PSMI_GRANULARITY (1<<10)
...@@ -973,6 +1071,7 @@ enum punit_power_well { ...@@ -973,6 +1071,7 @@ enum punit_power_well {
#define ECO_FLIP_DONE (1<<0) #define ECO_FLIP_DONE (1<<0)
#define CACHE_MODE_0_GEN7 0x7000 /* IVB+ */ #define CACHE_MODE_0_GEN7 0x7000 /* IVB+ */
#define RC_OP_FLUSH_ENABLE (1<<0)
#define HIZ_RAW_STALL_OPT_DISABLE (1<<2) #define HIZ_RAW_STALL_OPT_DISABLE (1<<2)
#define CACHE_MODE_1 0x7004 /* IVB+ */ #define CACHE_MODE_1 0x7004 /* IVB+ */
#define PIXEL_SUBSPAN_COLLECT_OPT_DISABLE (1<<6) #define PIXEL_SUBSPAN_COLLECT_OPT_DISABLE (1<<6)
...@@ -3258,6 +3357,7 @@ enum punit_power_well { ...@@ -3258,6 +3357,7 @@ enum punit_power_well {
#define PIPECONF_INTERLACED_DBL_ILK (4 << 21) /* ilk/snb only */ #define PIPECONF_INTERLACED_DBL_ILK (4 << 21) /* ilk/snb only */
#define PIPECONF_PFIT_PF_INTERLACED_DBL_ILK (5 << 21) /* ilk/snb only */ #define PIPECONF_PFIT_PF_INTERLACED_DBL_ILK (5 << 21) /* ilk/snb only */
#define PIPECONF_INTERLACE_MODE_MASK (7 << 21) #define PIPECONF_INTERLACE_MODE_MASK (7 << 21)
#define PIPECONF_EDP_RR_MODE_SWITCH (1 << 20)
#define PIPECONF_CXSR_DOWNCLOCK (1<<16) #define PIPECONF_CXSR_DOWNCLOCK (1<<16)
#define PIPECONF_COLOR_RANGE_SELECT (1 << 13) #define PIPECONF_COLOR_RANGE_SELECT (1 << 13)
#define PIPECONF_BPC_MASK (0x7 << 5) #define PIPECONF_BPC_MASK (0x7 << 5)
...@@ -3535,9 +3635,9 @@ enum punit_power_well { ...@@ -3535,9 +3635,9 @@ enum punit_power_well {
#define PIPE_PIXEL_MASK 0x00ffffff #define PIPE_PIXEL_MASK 0x00ffffff
#define PIPE_PIXEL_SHIFT 0 #define PIPE_PIXEL_SHIFT 0
/* GM45+ just has to be different */ /* GM45+ just has to be different */
#define _PIPEA_FRMCOUNT_GM45 (dev_priv->info.display_mmio_offset + 0x70040) #define _PIPEA_FRMCOUNT_GM45 0x70040
#define _PIPEA_FLIPCOUNT_GM45 (dev_priv->info.display_mmio_offset + 0x70044) #define _PIPEA_FLIPCOUNT_GM45 0x70044
#define PIPE_FRMCOUNT_GM45(pipe) _PIPE(pipe, _PIPEA_FRMCOUNT_GM45, _PIPEB_FRMCOUNT_GM45) #define PIPE_FRMCOUNT_GM45(pipe) _PIPE2(pipe, _PIPEA_FRMCOUNT_GM45)
/* Cursor A & B regs */ /* Cursor A & B regs */
#define _CURACNTR (dev_priv->info.display_mmio_offset + 0x70080) #define _CURACNTR (dev_priv->info.display_mmio_offset + 0x70080)
...@@ -4120,7 +4220,7 @@ enum punit_power_well { ...@@ -4120,7 +4220,7 @@ enum punit_power_well {
#define GEN8_PIPE_SPRITE_FAULT (1 << 9) #define GEN8_PIPE_SPRITE_FAULT (1 << 9)
#define GEN8_PIPE_PRIMARY_FAULT (1 << 8) #define GEN8_PIPE_PRIMARY_FAULT (1 << 8)
#define GEN8_PIPE_SPRITE_FLIP_DONE (1 << 5) #define GEN8_PIPE_SPRITE_FLIP_DONE (1 << 5)
#define GEN8_PIPE_FLIP_DONE (1 << 4) #define GEN8_PIPE_PRIMARY_FLIP_DONE (1 << 4)
#define GEN8_PIPE_SCAN_LINE_EVENT (1 << 2) #define GEN8_PIPE_SCAN_LINE_EVENT (1 << 2)
#define GEN8_PIPE_VSYNC (1 << 1) #define GEN8_PIPE_VSYNC (1 << 1)
#define GEN8_PIPE_VBLANK (1 << 0) #define GEN8_PIPE_VBLANK (1 << 0)
......
...@@ -206,7 +206,7 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, ...@@ -206,7 +206,7 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
const struct lvds_dvo_timing *panel_dvo_timing; const struct lvds_dvo_timing *panel_dvo_timing;
const struct lvds_fp_timing *fp_timing; const struct lvds_fp_timing *fp_timing;
struct drm_display_mode *panel_fixed_mode; struct drm_display_mode *panel_fixed_mode;
int i, downclock; int i, downclock, drrs_mode;
lvds_options = find_section(bdb, BDB_LVDS_OPTIONS); lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
if (!lvds_options) if (!lvds_options)
...@@ -218,6 +218,28 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, ...@@ -218,6 +218,28 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
panel_type = lvds_options->panel_type; panel_type = lvds_options->panel_type;
drrs_mode = (lvds_options->dps_panel_type_bits
>> (panel_type * 2)) & MODE_MASK;
/*
* VBT has static DRRS = 0 and seamless DRRS = 2.
* The below piece of code is required to adjust vbt.drrs_type
* to match the enum drrs_support_type.
*/
switch (drrs_mode) {
case 0:
dev_priv->vbt.drrs_type = STATIC_DRRS_SUPPORT;
DRM_DEBUG_KMS("DRRS supported mode is static\n");
break;
case 2:
dev_priv->vbt.drrs_type = SEAMLESS_DRRS_SUPPORT;
DRM_DEBUG_KMS("DRRS supported mode is seamless\n");
break;
default:
dev_priv->vbt.drrs_type = DRRS_NOT_SUPPORTED;
DRM_DEBUG_KMS("DRRS not supported (VBT input)\n");
break;
}
lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA); lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
if (!lvds_lfp_data) if (!lvds_lfp_data)
return; return;
...@@ -526,6 +548,16 @@ parse_driver_features(struct drm_i915_private *dev_priv, ...@@ -526,6 +548,16 @@ parse_driver_features(struct drm_i915_private *dev_priv,
if (driver->dual_frequency) if (driver->dual_frequency)
dev_priv->render_reclock_avail = true; dev_priv->render_reclock_avail = true;
DRM_DEBUG_KMS("DRRS State Enabled:%d\n", driver->drrs_enabled);
/*
* If DRRS is not supported, drrs_type has to be set to 0.
* This is because, VBT is configured in such a way that
* static DRRS is 0 and DRRS not supported is represented by
* driver->drrs_enabled=false
*/
if (!driver->drrs_enabled)
dev_priv->vbt.drrs_type = DRRS_NOT_SUPPORTED;
} }
static void static void
...@@ -604,19 +636,217 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb) ...@@ -604,19 +636,217 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
} }
} }
static u8 *goto_next_sequence(u8 *data, int *size)
{
u16 len;
int tmp = *size;
if (--tmp < 0)
return NULL;
/* goto first element */
data++;
while (1) {
switch (*data) {
case MIPI_SEQ_ELEM_SEND_PKT:
/*
* skip by this element payload size
* skip elem id, command flag and data type
*/
tmp -= 5;
if (tmp < 0)
return NULL;
data += 3;
len = *((u16 *)data);
tmp -= len;
if (tmp < 0)
return NULL;
/* skip by len */
data = data + 2 + len;
break;
case MIPI_SEQ_ELEM_DELAY:
/* skip by elem id, and delay is 4 bytes */
tmp -= 5;
if (tmp < 0)
return NULL;
data += 5;
break;
case MIPI_SEQ_ELEM_GPIO:
tmp -= 3;
if (tmp < 0)
return NULL;
data += 3;
break;
default:
DRM_ERROR("Unknown element\n");
return NULL;
}
/* end of sequence ? */
if (*data == 0)
break;
}
/* goto next sequence or end of block byte */
if (--tmp < 0)
return NULL;
data++;
/* update amount of data left for the sequence block to be parsed */
*size = tmp;
return data;
}
static void static void
parse_mipi(struct drm_i915_private *dev_priv, struct bdb_header *bdb) parse_mipi(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
{ {
struct bdb_mipi *mipi; struct bdb_mipi_config *start;
struct bdb_mipi_sequence *sequence;
struct mipi_config *config;
struct mipi_pps_data *pps;
u8 *data, *seq_data;
int i, panel_id, seq_size;
u16 block_size;
/* Initialize this to undefined indicating no generic MIPI support */
dev_priv->vbt.dsi.panel_id = MIPI_DSI_UNDEFINED_PANEL_ID;
/* Block #40 is already parsed and panel_fixed_mode is
* stored in dev_priv->lfp_lvds_vbt_mode
* resuse this when needed
*/
mipi = find_section(bdb, BDB_MIPI_CONFIG); /* Parse #52 for panel index used from panel_type already
if (!mipi) { * parsed
DRM_DEBUG_KMS("No MIPI BDB found"); */
start = find_section(bdb, BDB_MIPI_CONFIG);
if (!start) {
DRM_DEBUG_KMS("No MIPI config BDB found");
return; return;
} }
/* XXX: add more info */ DRM_DEBUG_DRIVER("Found MIPI Config block, panel index = %d\n",
panel_type);
/*
* get hold of the correct configuration block and pps data as per
* the panel_type as index
*/
config = &start->config[panel_type];
pps = &start->pps[panel_type];
/* store as of now full data. Trim when we realise all is not needed */
dev_priv->vbt.dsi.config = kmemdup(config, sizeof(struct mipi_config), GFP_KERNEL);
if (!dev_priv->vbt.dsi.config)
return;
dev_priv->vbt.dsi.pps = kmemdup(pps, sizeof(struct mipi_pps_data), GFP_KERNEL);
if (!dev_priv->vbt.dsi.pps) {
kfree(dev_priv->vbt.dsi.config);
return;
}
/* We have mandatory mipi config blocks. Initialize as generic panel */
dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID; dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID;
/* Check if we have sequence block as well */
sequence = find_section(bdb, BDB_MIPI_SEQUENCE);
if (!sequence) {
DRM_DEBUG_KMS("No MIPI Sequence found, parsing complete\n");
return;
}
DRM_DEBUG_DRIVER("Found MIPI sequence block\n");
block_size = get_blocksize(sequence);
/*
* parse the sequence block for individual sequences
*/
dev_priv->vbt.dsi.seq_version = sequence->version;
seq_data = &sequence->data[0];
/*
* sequence block is variable length and hence we need to parse and
* get the sequence data for specific panel id
*/
for (i = 0; i < MAX_MIPI_CONFIGURATIONS; i++) {
panel_id = *seq_data;
seq_size = *((u16 *) (seq_data + 1));
if (panel_id == panel_type)
break;
/* skip the sequence including seq header of 3 bytes */
seq_data = seq_data + 3 + seq_size;
if ((seq_data - &sequence->data[0]) > block_size) {
DRM_ERROR("Sequence start is beyond sequence block size, corrupted sequence block\n");
return;
}
}
if (i == MAX_MIPI_CONFIGURATIONS) {
DRM_ERROR("Sequence block detected but no valid configuration\n");
return;
}
/* check if found sequence is completely within the sequence block
* just being paranoid */
if (seq_size > block_size) {
DRM_ERROR("Corrupted sequence/size, bailing out\n");
return;
}
/* skip the panel id(1 byte) and seq size(2 bytes) */
dev_priv->vbt.dsi.data = kmemdup(seq_data + 3, seq_size, GFP_KERNEL);
if (!dev_priv->vbt.dsi.data)
return;
/*
* loop into the sequence data and split into multiple sequneces
* There are only 5 types of sequences as of now
*/
data = dev_priv->vbt.dsi.data;
dev_priv->vbt.dsi.size = seq_size;
/* two consecutive 0x00 indicate end of all sequences */
while (1) {
int seq_id = *data;
if (MIPI_SEQ_MAX > seq_id && seq_id > MIPI_SEQ_UNDEFINED) {
dev_priv->vbt.dsi.sequence[seq_id] = data;
DRM_DEBUG_DRIVER("Found mipi sequence - %d\n", seq_id);
} else {
DRM_ERROR("undefined sequence\n");
goto err;
}
/* partial parsing to skip elements */
data = goto_next_sequence(data, &seq_size);
if (data == NULL) {
DRM_ERROR("Sequence elements going beyond block itself. Sequence block parsing failed\n");
goto err;
}
if (*data == 0)
break; /* end of sequence reached */
}
DRM_DEBUG_DRIVER("MIPI related vbt parsing complete\n");
return;
err:
kfree(dev_priv->vbt.dsi.data);
dev_priv->vbt.dsi.data = NULL;
/* error during parsing so set all pointers to null
* because of partial parsing */
memset(dev_priv->vbt.dsi.sequence, 0, MIPI_SEQ_MAX);
} }
static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
......
...@@ -282,6 +282,9 @@ struct bdb_general_definitions { ...@@ -282,6 +282,9 @@ struct bdb_general_definitions {
union child_device_config devices[0]; union child_device_config devices[0];
} __packed; } __packed;
/* Mask for DRRS / Panel Channel / SSC / BLT control bits extraction */
#define MODE_MASK 0x3
struct bdb_lvds_options { struct bdb_lvds_options {
u8 panel_type; u8 panel_type;
u8 rsvd1; u8 rsvd1;
...@@ -294,6 +297,18 @@ struct bdb_lvds_options { ...@@ -294,6 +297,18 @@ struct bdb_lvds_options {
u8 lvds_edid:1; u8 lvds_edid:1;
u8 rsvd2:1; u8 rsvd2:1;
u8 rsvd4; u8 rsvd4;
/* LVDS Panel channel bits stored here */
u32 lvds_panel_channel_bits;
/* LVDS SSC (Spread Spectrum Clock) bits stored here. */
u16 ssc_bits;
u16 ssc_freq;
u16 ssc_ddt;
/* Panel color depth defined here */
u16 panel_color_depth;
/* LVDS panel type bits stored here */
u32 dps_panel_type_bits;
/* LVDS backlight control type bits stored here */
u32 blt_control_type_bits;
} __packed; } __packed;
/* LFP pointer table contains entries to the struct below */ /* LFP pointer table contains entries to the struct below */
...@@ -482,6 +497,20 @@ struct bdb_driver_features { ...@@ -482,6 +497,20 @@ struct bdb_driver_features {
u8 hdmi_termination; u8 hdmi_termination;
u8 custom_vbt_version; u8 custom_vbt_version;
/* Driver features data block */
u16 rmpm_enabled:1;
u16 s2ddt_enabled:1;
u16 dpst_enabled:1;
u16 bltclt_enabled:1;
u16 adb_enabled:1;
u16 drrs_enabled:1;
u16 grs_enabled:1;
u16 gpmt_enabled:1;
u16 tbt_enabled:1;
u16 psr_enabled:1;
u16 ips_enabled:1;
u16 reserved3:4;
u16 pc_feature_valid:1;
} __packed; } __packed;
#define EDP_18BPP 0 #define EDP_18BPP 0
...@@ -870,4 +899,35 @@ struct bdb_mipi_sequence { ...@@ -870,4 +899,35 @@ struct bdb_mipi_sequence {
u8 data[0]; u8 data[0];
}; };
/* MIPI Sequnece Block definitions */
enum mipi_seq {
MIPI_SEQ_UNDEFINED = 0,
MIPI_SEQ_ASSERT_RESET,
MIPI_SEQ_INIT_OTP,
MIPI_SEQ_DISPLAY_ON,
MIPI_SEQ_DISPLAY_OFF,
MIPI_SEQ_DEASSERT_RESET,
MIPI_SEQ_MAX
};
enum mipi_seq_element {
MIPI_SEQ_ELEM_UNDEFINED = 0,
MIPI_SEQ_ELEM_SEND_PKT,
MIPI_SEQ_ELEM_DELAY,
MIPI_SEQ_ELEM_GPIO,
MIPI_SEQ_ELEM_STATUS,
MIPI_SEQ_ELEM_MAX
};
enum mipi_gpio_pin_index {
MIPI_GPIO_UNDEFINED = 0,
MIPI_GPIO_PANEL_ENABLE,
MIPI_GPIO_BL_ENABLE,
MIPI_GPIO_PWM_ENABLE,
MIPI_GPIO_RESET_N,
MIPI_GPIO_PWR_DOWN_R,
MIPI_GPIO_STDBY_RST_N,
MIPI_GPIO_MAX
};
#endif /* _I830_BIOS_H_ */ #endif /* _I830_BIOS_H_ */
This diff is collapsed.
This diff is collapsed.
...@@ -81,8 +81,8 @@ ...@@ -81,8 +81,8 @@
/* Maximum cursor sizes */ /* Maximum cursor sizes */
#define GEN2_CURSOR_WIDTH 64 #define GEN2_CURSOR_WIDTH 64
#define GEN2_CURSOR_HEIGHT 64 #define GEN2_CURSOR_HEIGHT 64
#define CURSOR_WIDTH 256 #define MAX_CURSOR_WIDTH 256
#define CURSOR_HEIGHT 256 #define MAX_CURSOR_HEIGHT 256
#define INTEL_I2C_BUS_DVO 1 #define INTEL_I2C_BUS_DVO 1
#define INTEL_I2C_BUS_SDVO 2 #define INTEL_I2C_BUS_SDVO 2
...@@ -306,6 +306,9 @@ struct intel_crtc_config { ...@@ -306,6 +306,9 @@ struct intel_crtc_config {
int pipe_bpp; int pipe_bpp;
struct intel_link_m_n dp_m_n; struct intel_link_m_n dp_m_n;
/* m2_n2 for eDP downclock */
struct intel_link_m_n dp_m2_n2;
/* /*
* Frequence the dpll for the port should run at. Differs from the * Frequence the dpll for the port should run at. Differs from the
* adjusted dotclock e.g. for DP or 12bpc hdmi mode. This is also * adjusted dotclock e.g. for DP or 12bpc hdmi mode. This is also
...@@ -343,6 +346,9 @@ struct intel_pipe_wm { ...@@ -343,6 +346,9 @@ struct intel_pipe_wm {
struct intel_wm_level wm[5]; struct intel_wm_level wm[5];
uint32_t linetime; uint32_t linetime;
bool fbc_wm_enabled; bool fbc_wm_enabled;
bool pipe_enabled;
bool sprites_enabled;
bool sprites_scaled;
}; };
struct intel_crtc { struct intel_crtc {
...@@ -374,7 +380,6 @@ struct intel_crtc { ...@@ -374,7 +380,6 @@ struct intel_crtc {
uint32_t cursor_addr; uint32_t cursor_addr;
int16_t cursor_x, cursor_y; int16_t cursor_x, cursor_y;
int16_t cursor_width, cursor_height; int16_t cursor_width, cursor_height;
int16_t max_cursor_width, max_cursor_height;
bool cursor_visible; bool cursor_visible;
struct intel_plane_config plane_config; struct intel_plane_config plane_config;
...@@ -484,6 +489,17 @@ struct intel_hdmi { ...@@ -484,6 +489,17 @@ struct intel_hdmi {
#define DP_MAX_DOWNSTREAM_PORTS 0x10 #define DP_MAX_DOWNSTREAM_PORTS 0x10
/**
* HIGH_RR is the highest eDP panel refresh rate read from EDID
* LOW_RR is the lowest eDP panel refresh rate found from EDID
* parsing for same resolution.
*/
enum edp_drrs_refresh_rate_type {
DRRS_HIGH_RR,
DRRS_LOW_RR,
DRRS_MAX_RR, /* RR count */
};
struct intel_dp { struct intel_dp {
uint32_t output_reg; uint32_t output_reg;
uint32_t aux_ch_ctl_reg; uint32_t aux_ch_ctl_reg;
...@@ -522,6 +538,12 @@ struct intel_dp { ...@@ -522,6 +538,12 @@ struct intel_dp {
bool has_aux_irq, bool has_aux_irq,
int send_bytes, int send_bytes,
uint32_t aux_clock_divider); uint32_t aux_clock_divider);
struct {
enum drrs_support_type type;
enum edp_drrs_refresh_rate_type refresh_rate_type;
struct mutex mutex;
} drrs_state;
}; };
struct intel_digital_port { struct intel_digital_port {
...@@ -629,8 +651,8 @@ void ilk_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); ...@@ -629,8 +651,8 @@ void ilk_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
void ilk_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask); void ilk_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
void snb_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); void snb_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
void snb_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); void snb_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
void hsw_runtime_pm_disable_interrupts(struct drm_device *dev); void intel_runtime_pm_disable_interrupts(struct drm_device *dev);
void hsw_runtime_pm_restore_interrupts(struct drm_device *dev); void intel_runtime_pm_restore_interrupts(struct drm_device *dev);
/* intel_crt.c */ /* intel_crt.c */
...@@ -666,6 +688,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder, ...@@ -666,6 +688,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
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);
int intel_pch_rawclk(struct drm_device *dev); int intel_pch_rawclk(struct drm_device *dev);
int valleyview_cur_cdclk(struct drm_i915_private *dev_priv);
void intel_mark_busy(struct drm_device *dev); void intel_mark_busy(struct drm_device *dev);
void intel_mark_fb_busy(struct drm_i915_gem_object *obj, void intel_mark_fb_busy(struct drm_i915_gem_object *obj,
struct intel_ring_buffer *ring); struct intel_ring_buffer *ring);
...@@ -774,7 +797,7 @@ void intel_edp_panel_off(struct intel_dp *intel_dp); ...@@ -774,7 +797,7 @@ 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);
void intel_edp_psr_disable(struct intel_dp *intel_dp); void intel_edp_psr_disable(struct intel_dp *intel_dp);
void intel_edp_psr_update(struct drm_device *dev); void intel_edp_psr_update(struct drm_device *dev);
void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate);
/* intel_dsi.c */ /* intel_dsi.c */
bool intel_dsi_init(struct drm_device *dev); bool intel_dsi_init(struct drm_device *dev);
......
...@@ -110,6 +110,15 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder) ...@@ -110,6 +110,15 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder)
DRM_DEBUG_KMS("\n"); DRM_DEBUG_KMS("\n");
mutex_lock(&dev_priv->dpio_lock);
/* program rcomp for compliance, reduce from 50 ohms to 45 ohms
* needed everytime after power gate */
vlv_flisdsi_write(dev_priv, 0x04, 0x0004);
mutex_unlock(&dev_priv->dpio_lock);
/* bandgap reset is needed after everytime we do power gate */
band_gap_reset(dev_priv);
val = I915_READ(MIPI_PORT_CTRL(pipe)); val = I915_READ(MIPI_PORT_CTRL(pipe));
I915_WRITE(MIPI_PORT_CTRL(pipe), val | LP_OUTPUT_HOLD); I915_WRITE(MIPI_PORT_CTRL(pipe), val | LP_OUTPUT_HOLD);
usleep_range(1000, 1500); usleep_range(1000, 1500);
...@@ -122,21 +131,6 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder) ...@@ -122,21 +131,6 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder)
I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY); I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY);
usleep_range(2000, 2500); usleep_range(2000, 2500);
} }
static void intel_dsi_pre_enable(struct intel_encoder *encoder)
{
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
DRM_DEBUG_KMS("\n");
if (intel_dsi->dev.dev_ops->panel_reset)
intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev);
/* put device in ready state */
intel_dsi_device_ready(encoder);
if (intel_dsi->dev.dev_ops->send_otp_cmds)
intel_dsi->dev.dev_ops->send_otp_cmds(&intel_dsi->dev);
}
static void intel_dsi_enable(struct intel_encoder *encoder) static void intel_dsi_enable(struct intel_encoder *encoder)
{ {
...@@ -153,18 +147,63 @@ static void intel_dsi_enable(struct intel_encoder *encoder) ...@@ -153,18 +147,63 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(pipe), 8 * 4); I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(pipe), 8 * 4);
else { else {
msleep(20); /* XXX */ msleep(20); /* XXX */
dpi_send_cmd(intel_dsi, TURN_ON); dpi_send_cmd(intel_dsi, TURN_ON, DPI_LP_MODE_EN);
msleep(100); msleep(100);
if (intel_dsi->dev.dev_ops->enable)
intel_dsi->dev.dev_ops->enable(&intel_dsi->dev);
/* assert ip_tg_enable signal */ /* assert ip_tg_enable signal */
temp = I915_READ(MIPI_PORT_CTRL(pipe)) & ~LANE_CONFIGURATION_MASK; temp = I915_READ(MIPI_PORT_CTRL(pipe)) & ~LANE_CONFIGURATION_MASK;
temp = temp | intel_dsi->port_bits; temp = temp | intel_dsi->port_bits;
I915_WRITE(MIPI_PORT_CTRL(pipe), temp | DPI_ENABLE); I915_WRITE(MIPI_PORT_CTRL(pipe), temp | DPI_ENABLE);
POSTING_READ(MIPI_PORT_CTRL(pipe)); POSTING_READ(MIPI_PORT_CTRL(pipe));
} }
}
static void intel_dsi_pre_enable(struct intel_encoder *encoder)
{
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
enum pipe pipe = intel_crtc->pipe;
u32 tmp;
DRM_DEBUG_KMS("\n");
if (intel_dsi->dev.dev_ops->enable) /* Disable DPOunit clock gating, can stall pipe
intel_dsi->dev.dev_ops->enable(&intel_dsi->dev); * and we need DPLL REFA always enabled */
tmp = I915_READ(DPLL(pipe));
tmp |= DPLL_REFA_CLK_ENABLE_VLV;
I915_WRITE(DPLL(pipe), tmp);
tmp = I915_READ(DSPCLK_GATE_D);
tmp |= DPOUNIT_CLOCK_GATE_DISABLE;
I915_WRITE(DSPCLK_GATE_D, tmp);
/* put device in ready state */
intel_dsi_device_ready(encoder);
if (intel_dsi->dev.dev_ops->panel_reset)
intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev);
if (intel_dsi->dev.dev_ops->send_otp_cmds)
intel_dsi->dev.dev_ops->send_otp_cmds(&intel_dsi->dev);
/* Enable port in pre-enable phase itself because as per hw team
* recommendation, port should be enabled befor plane & pipe */
intel_dsi_enable(encoder);
}
static void intel_dsi_enable_nop(struct intel_encoder *encoder)
{
DRM_DEBUG_KMS("\n");
/* for DSI port enable has to be done before pipe
* and plane enable, so port enable is done in
* pre_enable phase itself unlike other encoders
*/
} }
static void intel_dsi_disable(struct intel_encoder *encoder) static void intel_dsi_disable(struct intel_encoder *encoder)
...@@ -179,7 +218,8 @@ static void intel_dsi_disable(struct intel_encoder *encoder) ...@@ -179,7 +218,8 @@ static void intel_dsi_disable(struct intel_encoder *encoder)
DRM_DEBUG_KMS("\n"); DRM_DEBUG_KMS("\n");
if (is_vid_mode(intel_dsi)) { if (is_vid_mode(intel_dsi)) {
dpi_send_cmd(intel_dsi, SHUTDOWN); /* Send Shutdown command to the panel in LP mode */
dpi_send_cmd(intel_dsi, SHUTDOWN, DPI_LP_MODE_EN);
msleep(10); msleep(10);
/* de-assert ip_tg_enable signal */ /* de-assert ip_tg_enable signal */
...@@ -190,6 +230,23 @@ static void intel_dsi_disable(struct intel_encoder *encoder) ...@@ -190,6 +230,23 @@ static void intel_dsi_disable(struct intel_encoder *encoder)
msleep(2); msleep(2);
} }
/* Panel commands can be sent when clock is in LP11 */
I915_WRITE(MIPI_DEVICE_READY(pipe), 0x0);
temp = I915_READ(MIPI_CTRL(pipe));
temp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
I915_WRITE(MIPI_CTRL(pipe), temp |
intel_dsi->escape_clk_div <<
ESCAPE_CLOCK_DIVIDER_SHIFT);
I915_WRITE(MIPI_EOT_DISABLE(pipe), CLOCKSTOP);
temp = I915_READ(MIPI_DSI_FUNC_PRG(pipe));
temp &= ~VID_MODE_FORMAT_MASK;
I915_WRITE(MIPI_DSI_FUNC_PRG(pipe), temp);
I915_WRITE(MIPI_DEVICE_READY(pipe), 0x1);
/* if disable packets are sent before sending shutdown packet then in /* if disable packets are sent before sending shutdown packet then in
* some next enable sequence send turn on packet error is observed */ * some next enable sequence send turn on packet error is observed */
if (intel_dsi->dev.dev_ops->disable) if (intel_dsi->dev.dev_ops->disable)
...@@ -227,14 +284,21 @@ static void intel_dsi_clear_device_ready(struct intel_encoder *encoder) ...@@ -227,14 +284,21 @@ static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
vlv_disable_dsi_pll(encoder); vlv_disable_dsi_pll(encoder);
} }
static void intel_dsi_post_disable(struct intel_encoder *encoder) static void intel_dsi_post_disable(struct intel_encoder *encoder)
{ {
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
u32 val;
DRM_DEBUG_KMS("\n"); DRM_DEBUG_KMS("\n");
intel_dsi_clear_device_ready(encoder); intel_dsi_clear_device_ready(encoder);
val = I915_READ(DSPCLK_GATE_D);
val &= ~DPOUNIT_CLOCK_GATE_DISABLE;
I915_WRITE(DSPCLK_GATE_D, val);
if (intel_dsi->dev.dev_ops->disable_panel_power) if (intel_dsi->dev.dev_ops->disable_panel_power)
intel_dsi->dev.dev_ops->disable_panel_power(&intel_dsi->dev); intel_dsi->dev.dev_ops->disable_panel_power(&intel_dsi->dev);
} }
...@@ -379,9 +443,6 @@ static void intel_dsi_mode_set(struct intel_encoder *intel_encoder) ...@@ -379,9 +443,6 @@ static void intel_dsi_mode_set(struct intel_encoder *intel_encoder)
DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe)); DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
/* XXX: Location of the call */
band_gap_reset(dev_priv);
/* escape clock divider, 20MHz, shared for A and C. device ready must be /* escape clock divider, 20MHz, shared for A and C. device ready must be
* off when doing this! txclkesc? */ * off when doing this! txclkesc? */
tmp = I915_READ(MIPI_CTRL(0)); tmp = I915_READ(MIPI_CTRL(0));
...@@ -452,10 +513,17 @@ static void intel_dsi_mode_set(struct intel_encoder *intel_encoder) ...@@ -452,10 +513,17 @@ static void intel_dsi_mode_set(struct intel_encoder *intel_encoder)
/* dphy stuff */ /* dphy stuff */
/* in terms of low power clock */ /* in terms of low power clock */
I915_WRITE(MIPI_INIT_COUNT(pipe), txclkesc(ESCAPE_CLOCK_DIVIDER_1, 100)); I915_WRITE(MIPI_INIT_COUNT(pipe), txclkesc(intel_dsi->escape_clk_div, 100));
val = 0;
if (intel_dsi->eotp_pkt == 0)
val |= EOT_DISABLE;
if (intel_dsi->clock_stop)
val |= CLOCKSTOP;
/* recovery disables */ /* recovery disables */
I915_WRITE(MIPI_EOT_DISABLE(pipe), intel_dsi->eot_disable); I915_WRITE(MIPI_EOT_DISABLE(pipe), val);
/* in terms of txbyteclkhs. actual high to low switch + /* in terms of txbyteclkhs. actual high to low switch +
* MIPI_STOP_STATE_STALL * MIPI_LP_BYTECLK. * MIPI_STOP_STATE_STALL * MIPI_LP_BYTECLK.
...@@ -484,9 +552,14 @@ static void intel_dsi_mode_set(struct intel_encoder *intel_encoder) ...@@ -484,9 +552,14 @@ static void intel_dsi_mode_set(struct intel_encoder *intel_encoder)
intel_dsi->clk_hs_to_lp_count << HS_LP_PWR_SW_CNT_SHIFT); intel_dsi->clk_hs_to_lp_count << HS_LP_PWR_SW_CNT_SHIFT);
if (is_vid_mode(intel_dsi)) if (is_vid_mode(intel_dsi))
/* Some panels might have resolution which is not a multiple of
* 64 like 1366 x 768. Enable RANDOM resolution support for such
* panels by default */
I915_WRITE(MIPI_VIDEO_MODE_FORMAT(pipe), I915_WRITE(MIPI_VIDEO_MODE_FORMAT(pipe),
intel_dsi->video_frmt_cfg_bits | intel_dsi->video_frmt_cfg_bits |
intel_dsi->video_mode_format); intel_dsi->video_mode_format |
IP_TG_CONFIG |
RANDOM_DPI_DISPLAY_RESOLUTION);
} }
static enum drm_connector_status static enum drm_connector_status
...@@ -594,7 +667,7 @@ bool intel_dsi_init(struct drm_device *dev) ...@@ -594,7 +667,7 @@ bool intel_dsi_init(struct drm_device *dev)
intel_encoder->compute_config = intel_dsi_compute_config; intel_encoder->compute_config = intel_dsi_compute_config;
intel_encoder->pre_pll_enable = intel_dsi_pre_pll_enable; intel_encoder->pre_pll_enable = intel_dsi_pre_pll_enable;
intel_encoder->pre_enable = intel_dsi_pre_enable; intel_encoder->pre_enable = intel_dsi_pre_enable;
intel_encoder->enable = intel_dsi_enable; intel_encoder->enable = intel_dsi_enable_nop;
intel_encoder->mode_set = intel_dsi_mode_set; intel_encoder->mode_set = intel_dsi_mode_set;
intel_encoder->disable = intel_dsi_disable; intel_encoder->disable = intel_dsi_disable;
intel_encoder->post_disable = intel_dsi_post_disable; intel_encoder->post_disable = intel_dsi_post_disable;
......
...@@ -95,8 +95,10 @@ struct intel_dsi { ...@@ -95,8 +95,10 @@ struct intel_dsi {
u32 video_mode_format; u32 video_mode_format;
/* eot for MIPI_EOT_DISABLE register */ /* eot for MIPI_EOT_DISABLE register */
u32 eot_disable; u8 eotp_pkt;
u8 clock_stop;
u8 escape_clk_div;
u32 port_bits; u32 port_bits;
u32 bw_timer; u32 bw_timer;
u32 dphy_reg; u32 dphy_reg;
......
...@@ -389,7 +389,7 @@ int dsi_vc_generic_read(struct intel_dsi *intel_dsi, int channel, ...@@ -389,7 +389,7 @@ int dsi_vc_generic_read(struct intel_dsi *intel_dsi, int channel,
* *
* XXX: commands with data in MIPI_DPI_DATA? * XXX: commands with data in MIPI_DPI_DATA?
*/ */
int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd) int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs)
{ {
struct drm_encoder *encoder = &intel_dsi->base.base; struct drm_encoder *encoder = &intel_dsi->base.base;
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
...@@ -399,7 +399,7 @@ int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd) ...@@ -399,7 +399,7 @@ int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd)
u32 mask; u32 mask;
/* XXX: pipe, hs */ /* XXX: pipe, hs */
if (intel_dsi->hs) if (hs)
cmd &= ~DPI_LP_MODE; cmd &= ~DPI_LP_MODE;
else else
cmd |= DPI_LP_MODE; cmd |= DPI_LP_MODE;
......
...@@ -33,6 +33,9 @@ ...@@ -33,6 +33,9 @@
#include "intel_drv.h" #include "intel_drv.h"
#include "intel_dsi.h" #include "intel_dsi.h"
#define DPI_LP_MODE_EN false
#define DPI_HS_MODE_EN true
void dsi_hs_mode_enable(struct intel_dsi *intel_dsi, bool enable); void dsi_hs_mode_enable(struct intel_dsi *intel_dsi, bool enable);
int dsi_vc_dcs_write(struct intel_dsi *intel_dsi, int channel, int dsi_vc_dcs_write(struct intel_dsi *intel_dsi, int channel,
...@@ -47,7 +50,7 @@ int dsi_vc_dcs_read(struct intel_dsi *intel_dsi, int channel, u8 dcs_cmd, ...@@ -47,7 +50,7 @@ int dsi_vc_dcs_read(struct intel_dsi *intel_dsi, int channel, u8 dcs_cmd,
int dsi_vc_generic_read(struct intel_dsi *intel_dsi, int channel, int dsi_vc_generic_read(struct intel_dsi *intel_dsi, int channel,
u8 *reqdata, int reqlen, u8 *buf, int buflen); u8 *reqdata, int reqlen, u8 *buf, int buflen);
int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd); int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs);
/* XXX: questionable write helpers */ /* XXX: questionable write helpers */
static inline int dsi_vc_dcs_write_0(struct intel_dsi *intel_dsi, static inline int dsi_vc_dcs_write_0(struct intel_dsi *intel_dsi,
......
...@@ -557,10 +557,12 @@ static void vlv_set_infoframes(struct drm_encoder *encoder, ...@@ -557,10 +557,12 @@ static void vlv_set_infoframes(struct drm_encoder *encoder,
struct drm_display_mode *adjusted_mode) struct drm_display_mode *adjusted_mode)
{ {
struct drm_i915_private *dev_priv = encoder->dev->dev_private; struct drm_i915_private *dev_priv = encoder->dev->dev_private;
struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
u32 reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe); u32 reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
u32 val = I915_READ(reg); u32 val = I915_READ(reg);
u32 port = VIDEO_DIP_PORT(intel_dig_port->port);
assert_hdmi_port_disabled(intel_hdmi); assert_hdmi_port_disabled(intel_hdmi);
...@@ -576,9 +578,19 @@ static void vlv_set_infoframes(struct drm_encoder *encoder, ...@@ -576,9 +578,19 @@ static void vlv_set_infoframes(struct drm_encoder *encoder,
return; return;
} }
if (port != (val & VIDEO_DIP_PORT_MASK)) {
if (val & VIDEO_DIP_ENABLE) {
val &= ~VIDEO_DIP_ENABLE;
I915_WRITE(reg, val);
POSTING_READ(reg);
}
val &= ~VIDEO_DIP_PORT_MASK;
val |= port;
}
val |= VIDEO_DIP_ENABLE; val |= VIDEO_DIP_ENABLE;
val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT | val &= ~(VIDEO_DIP_ENABLE_AVI | VIDEO_DIP_ENABLE_VENDOR |
VIDEO_DIP_ENABLE_GCP); VIDEO_DIP_ENABLE_GAMUT | VIDEO_DIP_ENABLE_GCP);
I915_WRITE(reg, val); I915_WRITE(reg, val);
POSTING_READ(reg); POSTING_READ(reg);
...@@ -638,8 +650,8 @@ static void intel_hdmi_mode_set(struct intel_encoder *encoder) ...@@ -638,8 +650,8 @@ static void intel_hdmi_mode_set(struct intel_encoder *encoder)
else else
hdmi_val |= SDVO_COLOR_FORMAT_8bpc; hdmi_val |= SDVO_COLOR_FORMAT_8bpc;
/* Required on CPT */ if (intel_hdmi->has_hdmi_sink &&
if (intel_hdmi->has_hdmi_sink && HAS_PCH_CPT(dev)) (HAS_PCH_CPT(dev) || IS_VALLEYVIEW(dev)))
hdmi_val |= HDMI_MODE_SELECT_HDMI; hdmi_val |= HDMI_MODE_SELECT_HDMI;
if (intel_hdmi->has_audio) { if (intel_hdmi->has_audio) {
...@@ -657,8 +669,6 @@ static void intel_hdmi_mode_set(struct intel_encoder *encoder) ...@@ -657,8 +669,6 @@ static void intel_hdmi_mode_set(struct intel_encoder *encoder)
I915_WRITE(intel_hdmi->hdmi_reg, hdmi_val); I915_WRITE(intel_hdmi->hdmi_reg, hdmi_val);
POSTING_READ(intel_hdmi->hdmi_reg); POSTING_READ(intel_hdmi->hdmi_reg);
intel_hdmi->set_infoframes(&encoder->base, adjusted_mode);
} }
static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
...@@ -1104,13 +1114,26 @@ intel_hdmi_set_property(struct drm_connector *connector, ...@@ -1104,13 +1114,26 @@ intel_hdmi_set_property(struct drm_connector *connector,
return 0; return 0;
} }
static void intel_hdmi_pre_enable(struct intel_encoder *encoder)
{
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
struct drm_display_mode *adjusted_mode =
&intel_crtc->config.adjusted_mode;
intel_hdmi->set_infoframes(&encoder->base, adjusted_mode);
}
static void vlv_hdmi_pre_enable(struct intel_encoder *encoder) static void vlv_hdmi_pre_enable(struct intel_encoder *encoder)
{ {
struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
struct intel_hdmi *intel_hdmi = &dport->hdmi;
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_crtc *intel_crtc = struct intel_crtc *intel_crtc =
to_intel_crtc(encoder->base.crtc); to_intel_crtc(encoder->base.crtc);
struct drm_display_mode *adjusted_mode =
&intel_crtc->config.adjusted_mode;
enum dpio_channel port = vlv_dport_to_channel(dport); enum dpio_channel port = vlv_dport_to_channel(dport);
int pipe = intel_crtc->pipe; int pipe = intel_crtc->pipe;
u32 val; u32 val;
...@@ -1144,6 +1167,8 @@ static void vlv_hdmi_pre_enable(struct intel_encoder *encoder) ...@@ -1144,6 +1167,8 @@ static void vlv_hdmi_pre_enable(struct intel_encoder *encoder)
vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW23(port), 0x00400888); vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW23(port), 0x00400888);
mutex_unlock(&dev_priv->dpio_lock); mutex_unlock(&dev_priv->dpio_lock);
intel_hdmi->set_infoframes(&encoder->base, adjusted_mode);
intel_enable_hdmi(encoder); intel_enable_hdmi(encoder);
vlv_wait_port_ready(dev_priv, dport); vlv_wait_port_ready(dev_priv, dport);
...@@ -1339,6 +1364,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port) ...@@ -1339,6 +1364,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port)
intel_encoder->enable = vlv_enable_hdmi; intel_encoder->enable = vlv_enable_hdmi;
intel_encoder->post_disable = vlv_hdmi_post_disable; intel_encoder->post_disable = vlv_hdmi_post_disable;
} else { } else {
intel_encoder->pre_enable = intel_hdmi_pre_enable;
intel_encoder->enable = intel_enable_hdmi; intel_encoder->enable = intel_enable_hdmi;
} }
......
...@@ -111,13 +111,6 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, ...@@ -111,13 +111,6 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
pipe_config->adjusted_mode.flags |= flags; pipe_config->adjusted_mode.flags |= flags;
/* gen2/3 store dither state in pfit control, needs to match */
if (INTEL_INFO(dev)->gen < 4) {
tmp = I915_READ(PFIT_CONTROL);
pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE;
}
dotclock = pipe_config->port_clock; dotclock = pipe_config->port_clock;
if (HAS_PCH_SPLIT(dev_priv->dev)) if (HAS_PCH_SPLIT(dev_priv->dev))
......
...@@ -308,16 +308,16 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, ...@@ -308,16 +308,16 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) |
PFIT_FILTER_FUZZY); PFIT_FILTER_FUZZY);
/* Make sure pre-965 set dither correctly for 18bpp panels. */
if (INTEL_INFO(dev)->gen < 4 && pipe_config->pipe_bpp == 18)
pfit_control |= PANEL_8TO6_DITHER_ENABLE;
out: out:
if ((pfit_control & PFIT_ENABLE) == 0) { if ((pfit_control & PFIT_ENABLE) == 0) {
pfit_control = 0; pfit_control = 0;
pfit_pgm_ratios = 0; pfit_pgm_ratios = 0;
} }
/* Make sure pre-965 set dither correctly for 18bpp panels. */
if (INTEL_INFO(dev)->gen < 4 && pipe_config->pipe_bpp == 18)
pfit_control |= PANEL_8TO6_DITHER_ENABLE;
pipe_config->gmch_pfit.control = pfit_control; pipe_config->gmch_pfit.control = pfit_control;
pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios; pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios;
pipe_config->gmch_pfit.lvds_border_bits = border; pipe_config->gmch_pfit.lvds_border_bits = border;
......
This diff is collapsed.
...@@ -41,12 +41,16 @@ static inline int ring_space(struct intel_ring_buffer *ring) ...@@ -41,12 +41,16 @@ static inline int ring_space(struct intel_ring_buffer *ring)
return space; return space;
} }
void __intel_ring_advance(struct intel_ring_buffer *ring) static bool intel_ring_stopped(struct intel_ring_buffer *ring)
{ {
struct drm_i915_private *dev_priv = ring->dev->dev_private; struct drm_i915_private *dev_priv = ring->dev->dev_private;
return dev_priv->gpu_error.stop_rings & intel_ring_flag(ring);
}
void __intel_ring_advance(struct intel_ring_buffer *ring)
{
ring->tail &= ring->size - 1; ring->tail &= ring->size - 1;
if (dev_priv->gpu_error.stop_rings & intel_ring_flag(ring)) if (intel_ring_stopped(ring))
return; return;
ring->write_tail(ring, ring->tail); ring->write_tail(ring, ring->tail);
} }
...@@ -601,13 +605,15 @@ static int init_render_ring(struct intel_ring_buffer *ring) ...@@ -601,13 +605,15 @@ static int init_render_ring(struct intel_ring_buffer *ring)
I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE)); I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE));
/* Required for the hardware to program scanline values for waiting */ /* Required for the hardware to program scanline values for waiting */
/* WaEnableFlushTlbInvalidationMode:snb */
if (INTEL_INFO(dev)->gen == 6) if (INTEL_INFO(dev)->gen == 6)
I915_WRITE(GFX_MODE, I915_WRITE(GFX_MODE,
_MASKED_BIT_ENABLE(GFX_TLB_INVALIDATE_ALWAYS)); _MASKED_BIT_ENABLE(GFX_TLB_INVALIDATE_EXPLICIT));
/* WaBCSVCSTlbInvalidationMode:ivb,vlv,hsw */
if (IS_GEN7(dev)) if (IS_GEN7(dev))
I915_WRITE(GFX_MODE_GEN7, I915_WRITE(GFX_MODE_GEN7,
_MASKED_BIT_DISABLE(GFX_TLB_INVALIDATE_ALWAYS) | _MASKED_BIT_ENABLE(GFX_TLB_INVALIDATE_EXPLICIT) |
_MASKED_BIT_ENABLE(GFX_REPLAY_MODE)); _MASKED_BIT_ENABLE(GFX_REPLAY_MODE));
if (INTEL_INFO(dev)->gen >= 5) { if (INTEL_INFO(dev)->gen >= 5) {
...@@ -624,13 +630,6 @@ static int init_render_ring(struct intel_ring_buffer *ring) ...@@ -624,13 +630,6 @@ static int init_render_ring(struct intel_ring_buffer *ring)
*/ */
I915_WRITE(CACHE_MODE_0, I915_WRITE(CACHE_MODE_0,
_MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB)); _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB));
/* This is not explicitly set for GEN6, so read the register.
* see intel_ring_mi_set_context() for why we care.
* TODO: consider explicitly setting the bit for GEN5
*/
ring->itlb_before_ctx_switch =
!!(I915_READ(GFX_MODE) & GFX_TLB_INVALIDATE_ALWAYS);
} }
if (INTEL_INFO(dev)->gen >= 6) if (INTEL_INFO(dev)->gen >= 6)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -1310,7 +1310,7 @@ extern int drm_remove_magic(struct drm_master *master, drm_magic_t magic); ...@@ -1310,7 +1310,7 @@ extern int drm_remove_magic(struct drm_master *master, drm_magic_t magic);
/* Cache management (drm_cache.c) */ /* Cache management (drm_cache.c) */
void drm_clflush_pages(struct page *pages[], unsigned long num_pages); void drm_clflush_pages(struct page *pages[], unsigned long num_pages);
void drm_clflush_sg(struct sg_table *st); void drm_clflush_sg(struct sg_table *st);
void drm_clflush_virt_range(char *addr, unsigned long length); void drm_clflush_virt_range(void *addr, unsigned long length);
/* Locking IOCTL support (drm_lock.h) */ /* Locking IOCTL support (drm_lock.h) */
extern int drm_lock(struct drm_device *dev, void *data, extern int drm_lock(struct drm_device *dev, void *data,
......
This diff is collapsed.
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