Commit 8ad2bc97 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-intel-next' of git://git.freedesktop.org/git/drm-intel into drm-next

- fine-grained display power domains for byt (Imre)
- runtime pm prep patches for !hsw from Paulo
- WiZ hashing flag updates from Ville
- ppgtt setup cleanup and enabling of full 4G range on bdw (Ben)
- fixes from Jesse for the inherited intial config code
- gpu reset code improvements from Mika
- per-pipe num_planes refactoring from Damien
- stability fixes around bdw forcewake handling and other bdw w/a from Mika
  Ken
- and as usual a pile of smaller fixes all over

* 'drm-intel-next' of git://git.freedesktop.org/git/drm-intel: (107 commits)
  drm/i915: Go OCD on the Makefile
  drm/i915: Implement command buffer parsing logic
  drm/i915: Refactor shmem pread setup
  drm/i915: Avoid div by zero when pixel clock is large
  drm/i915: power domains: add vlv power wells
  drm/i915: factor out intel_set_cpu_fifo_underrun_reporting_nolock
  drm/i915: vlv: factor out valleyview_display_irq_install
  drm/i915: sanity check power well sw state against hw state
  drm/i915: factor out reset_vblank_counter
  drm/i915: sanitize PUNIT register macro definitions
  drm/i915: vlv: keep first level vblank IRQs masked
  drm/i915: check pipe power domain when reading its hw state
  drm/i915: check port power domain when reading the encoder hw state
  drm/i915: get port power domain in connector detect handlers
  drm/i915: add port power domains
  drm/i915: add noop power well handlers instead of NULL checking them
  drm/i915: split power well 'set' handler to separate enable/disable/sync_hw
  drm/i915: add init power domain to always-on power wells
  drm/i915: move power domain macros to intel_pm.c
  drm/i915: Disable full ppgtt by default
  ...
parents e40d6410 e19b9137
...@@ -3,58 +3,69 @@ ...@@ -3,58 +3,69 @@
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
ccflags-y := -Iinclude/drm ccflags-y := -Iinclude/drm
i915-y := i915_drv.o i915_dma.o i915_irq.o \
i915_gpu_error.o \ # Please keep these build lists sorted!
# core driver code
i915-y := i915_drv.o \
i915_params.o \
i915_suspend.o \ i915_suspend.o \
i915_gem.o \ i915_sysfs.o \
intel_pm.o
i915-$(CONFIG_COMPAT) += i915_ioc32.o
i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o
# GEM code
i915-y += i915_cmd_parser.o \
i915_gem_context.o \ i915_gem_context.o \
i915_gem_debug.o \ i915_gem_debug.o \
i915_gem_dmabuf.o \
i915_gem_evict.o \ i915_gem_evict.o \
i915_gem_execbuffer.o \ i915_gem_execbuffer.o \
i915_gem_gtt.o \ i915_gem_gtt.o \
i915_gem.o \
i915_gem_stolen.o \ i915_gem_stolen.o \
i915_gem_tiling.o \ i915_gem_tiling.o \
i915_params.o \ i915_gpu_error.o \
i915_sysfs.o \ i915_irq.o \
i915_trace_points.o \ i915_trace_points.o \
i915_ums.o \ intel_ringbuffer.o \
intel_uncore.o
# modesetting core code
i915-y += intel_bios.o \
intel_display.o \ intel_display.o \
intel_crt.o \
intel_lvds.o \
intel_dsi.o \
intel_dsi_cmd.o \
intel_dsi_pll.o \
intel_bios.o \
intel_ddi.o \
intel_dp.o \
intel_hdmi.o \
intel_sdvo.o \
intel_modes.o \ intel_modes.o \
intel_panel.o \
intel_pm.o \
intel_i2c.o \
intel_tv.o \
intel_dvo.o \
intel_ringbuffer.o \
intel_overlay.o \ intel_overlay.o \
intel_sprite.o \
intel_sideband.o \ intel_sideband.o \
intel_uncore.o \ intel_sprite.o
i915-$(CONFIG_ACPI) += intel_acpi.o intel_opregion.o
i915-$(CONFIG_DRM_I915_FBDEV) += intel_fbdev.o
# modesetting output/encoder code
i915-y += dvo_ch7017.o \
dvo_ch7xxx.o \ dvo_ch7xxx.o \
dvo_ch7017.o \
dvo_ivch.o \ dvo_ivch.o \
dvo_tfp410.o \
dvo_sil164.o \
dvo_ns2501.o \ dvo_ns2501.o \
i915_gem_dmabuf.o dvo_sil164.o \
dvo_tfp410.o \
i915-$(CONFIG_COMPAT) += i915_ioc32.o intel_crt.o \
intel_ddi.o \
i915-$(CONFIG_ACPI) += intel_acpi.o intel_opregion.o intel_dp.o \
intel_dsi_cmd.o \
i915-$(CONFIG_DRM_I915_FBDEV) += intel_fbdev.o intel_dsi.o \
intel_dsi_pll.o \
intel_dvo.o \
intel_hdmi.o \
intel_i2c.o \
intel_lvds.o \
intel_panel.o \
intel_sdvo.o \
intel_tv.o
i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o # legacy horrors
i915-y += i915_dma.o \
i915_ums.o
obj-$(CONFIG_DRM_I915) += i915.o obj-$(CONFIG_DRM_I915) += i915.o
......
This diff is collapsed.
...@@ -602,7 +602,6 @@ static int i915_interrupt_info(struct seq_file *m, void *data) ...@@ -602,7 +602,6 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
intel_runtime_pm_get(dev_priv); intel_runtime_pm_get(dev_priv);
if (INTEL_INFO(dev)->gen >= 8) { if (INTEL_INFO(dev)->gen >= 8) {
int i;
seq_printf(m, "Master Interrupt Control:\t%08x\n", seq_printf(m, "Master Interrupt Control:\t%08x\n",
I915_READ(GEN8_MASTER_IRQ)); I915_READ(GEN8_MASTER_IRQ));
...@@ -615,16 +614,16 @@ static int i915_interrupt_info(struct seq_file *m, void *data) ...@@ -615,16 +614,16 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
i, I915_READ(GEN8_GT_IER(i))); i, I915_READ(GEN8_GT_IER(i)));
} }
for_each_pipe(i) { for_each_pipe(pipe) {
seq_printf(m, "Pipe %c IMR:\t%08x\n", seq_printf(m, "Pipe %c IMR:\t%08x\n",
pipe_name(i), pipe_name(pipe),
I915_READ(GEN8_DE_PIPE_IMR(i))); I915_READ(GEN8_DE_PIPE_IMR(pipe)));
seq_printf(m, "Pipe %c IIR:\t%08x\n", seq_printf(m, "Pipe %c IIR:\t%08x\n",
pipe_name(i), pipe_name(pipe),
I915_READ(GEN8_DE_PIPE_IIR(i))); I915_READ(GEN8_DE_PIPE_IIR(pipe)));
seq_printf(m, "Pipe %c IER:\t%08x\n", seq_printf(m, "Pipe %c IER:\t%08x\n",
pipe_name(i), pipe_name(pipe),
I915_READ(GEN8_DE_PIPE_IER(i))); I915_READ(GEN8_DE_PIPE_IER(pipe)));
} }
seq_printf(m, "Display Engine port interrupt mask:\t%08x\n", seq_printf(m, "Display Engine port interrupt mask:\t%08x\n",
...@@ -1348,6 +1347,8 @@ static int i915_fbc_status(struct seq_file *m, void *unused) ...@@ -1348,6 +1347,8 @@ static int i915_fbc_status(struct seq_file *m, void *unused)
return 0; return 0;
} }
intel_runtime_pm_get(dev_priv);
if (intel_fbc_enabled(dev)) { if (intel_fbc_enabled(dev)) {
seq_puts(m, "FBC enabled\n"); seq_puts(m, "FBC enabled\n");
} else { } else {
...@@ -1391,6 +1392,9 @@ static int i915_fbc_status(struct seq_file *m, void *unused) ...@@ -1391,6 +1392,9 @@ static int i915_fbc_status(struct seq_file *m, void *unused)
} }
seq_putc(m, '\n'); seq_putc(m, '\n');
} }
intel_runtime_pm_put(dev_priv);
return 0; return 0;
} }
...@@ -1405,11 +1409,15 @@ static int i915_ips_status(struct seq_file *m, void *unused) ...@@ -1405,11 +1409,15 @@ static int i915_ips_status(struct seq_file *m, void *unused)
return 0; return 0;
} }
intel_runtime_pm_get(dev_priv);
if (IS_BROADWELL(dev) || I915_READ(IPS_CTL) & IPS_ENABLE) if (IS_BROADWELL(dev) || I915_READ(IPS_CTL) & IPS_ENABLE)
seq_puts(m, "enabled\n"); seq_puts(m, "enabled\n");
else else
seq_puts(m, "disabled\n"); seq_puts(m, "disabled\n");
intel_runtime_pm_put(dev_priv);
return 0; return 0;
} }
...@@ -1420,6 +1428,8 @@ static int i915_sr_status(struct seq_file *m, void *unused) ...@@ -1420,6 +1428,8 @@ static int i915_sr_status(struct seq_file *m, void *unused)
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
bool sr_enabled = false; bool sr_enabled = false;
intel_runtime_pm_get(dev_priv);
if (HAS_PCH_SPLIT(dev)) if (HAS_PCH_SPLIT(dev))
sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN; sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN;
else if (IS_CRESTLINE(dev) || IS_I945G(dev) || IS_I945GM(dev)) else if (IS_CRESTLINE(dev) || IS_I945G(dev) || IS_I945GM(dev))
...@@ -1429,6 +1439,8 @@ static int i915_sr_status(struct seq_file *m, void *unused) ...@@ -1429,6 +1439,8 @@ static int i915_sr_status(struct seq_file *m, void *unused)
else if (IS_PINEVIEW(dev)) else if (IS_PINEVIEW(dev))
sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN; sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN;
intel_runtime_pm_put(dev_priv);
seq_printf(m, "self-refresh: %s\n", seq_printf(m, "self-refresh: %s\n",
sr_enabled ? "enabled" : "disabled"); sr_enabled ? "enabled" : "disabled");
...@@ -1468,7 +1480,7 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) ...@@ -1468,7 +1480,7 @@ static int i915_ring_freq_table(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;
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
int ret; int ret = 0;
int gpu_freq, ia_freq; int gpu_freq, ia_freq;
if (!(IS_GEN6(dev) || IS_GEN7(dev))) { if (!(IS_GEN6(dev) || IS_GEN7(dev))) {
...@@ -1476,12 +1488,13 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) ...@@ -1476,12 +1488,13 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
return 0; return 0;
} }
intel_runtime_pm_get(dev_priv);
flush_delayed_work(&dev_priv->rps.delayed_resume_work); flush_delayed_work(&dev_priv->rps.delayed_resume_work);
ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
if (ret) if (ret)
return ret; goto out;
intel_runtime_pm_get(dev_priv);
seq_puts(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\tEffective Ring freq (MHz)\n"); seq_puts(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\tEffective Ring freq (MHz)\n");
...@@ -1498,10 +1511,11 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) ...@@ -1498,10 +1511,11 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
((ia_freq >> 8) & 0xff) * 100); ((ia_freq >> 8) & 0xff) * 100);
} }
intel_runtime_pm_put(dev_priv);
mutex_unlock(&dev_priv->rps.hw_lock); mutex_unlock(&dev_priv->rps.hw_lock);
return 0; out:
intel_runtime_pm_put(dev_priv);
return ret;
} }
static int i915_gfxec(struct seq_file *m, void *unused) static int i915_gfxec(struct seq_file *m, void *unused)
...@@ -1757,7 +1771,7 @@ static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev) ...@@ -1757,7 +1771,7 @@ static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev)
return; return;
seq_printf(m, "Page directories: %d\n", ppgtt->num_pd_pages); seq_printf(m, "Page directories: %d\n", ppgtt->num_pd_pages);
seq_printf(m, "Page tables: %d\n", ppgtt->num_pt_pages); seq_printf(m, "Page tables: %d\n", ppgtt->num_pd_entries);
for_each_ring(ring, dev_priv, unused) { for_each_ring(ring, dev_priv, unused) {
seq_printf(m, "%s\n", ring->name); seq_printf(m, "%s\n", ring->name);
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
...@@ -1972,12 +1986,16 @@ static int i915_energy_uJ(struct seq_file *m, void *data) ...@@ -1972,12 +1986,16 @@ static int i915_energy_uJ(struct seq_file *m, void *data)
if (INTEL_INFO(dev)->gen < 6) if (INTEL_INFO(dev)->gen < 6)
return -ENODEV; return -ENODEV;
intel_runtime_pm_get(dev_priv);
rdmsrl(MSR_RAPL_POWER_UNIT, power); rdmsrl(MSR_RAPL_POWER_UNIT, power);
power = (power & 0x1f00) >> 8; power = (power & 0x1f00) >> 8;
units = 1000000 / (1 << power); /* convert to uJ */ units = 1000000 / (1 << power); /* convert to uJ */
power = I915_READ(MCH_SECP_NRG_STTS); power = I915_READ(MCH_SECP_NRG_STTS);
power *= units; power *= units;
intel_runtime_pm_put(dev_priv);
seq_printf(m, "%llu", (long long unsigned)power); seq_printf(m, "%llu", (long long unsigned)power);
return 0; return 0;
...@@ -1997,7 +2015,7 @@ static int i915_pc8_status(struct seq_file *m, void *unused) ...@@ -1997,7 +2015,7 @@ static int i915_pc8_status(struct seq_file *m, void *unused)
mutex_lock(&dev_priv->pc8.lock); mutex_lock(&dev_priv->pc8.lock);
seq_printf(m, "Requirements met: %s\n", seq_printf(m, "Requirements met: %s\n",
yesno(dev_priv->pc8.requirements_met)); yesno(dev_priv->pc8.requirements_met));
seq_printf(m, "GPU idle: %s\n", yesno(dev_priv->pc8.gpu_idle)); seq_printf(m, "GPU idle: %s\n", yesno(!dev_priv->mm.busy));
seq_printf(m, "Disable count: %d\n", dev_priv->pc8.disable_count); seq_printf(m, "Disable count: %d\n", dev_priv->pc8.disable_count);
seq_printf(m, "IRQs disabled: %s\n", seq_printf(m, "IRQs disabled: %s\n",
yesno(dev_priv->pc8.irqs_disabled)); yesno(dev_priv->pc8.irqs_disabled));
...@@ -2030,6 +2048,28 @@ static const char *power_domain_str(enum intel_display_power_domain domain) ...@@ -2030,6 +2048,28 @@ static const char *power_domain_str(enum intel_display_power_domain domain)
return "TRANSCODER_C"; return "TRANSCODER_C";
case POWER_DOMAIN_TRANSCODER_EDP: case POWER_DOMAIN_TRANSCODER_EDP:
return "TRANSCODER_EDP"; return "TRANSCODER_EDP";
case POWER_DOMAIN_PORT_DDI_A_2_LANES:
return "PORT_DDI_A_2_LANES";
case POWER_DOMAIN_PORT_DDI_A_4_LANES:
return "PORT_DDI_A_4_LANES";
case POWER_DOMAIN_PORT_DDI_B_2_LANES:
return "PORT_DDI_B_2_LANES";
case POWER_DOMAIN_PORT_DDI_B_4_LANES:
return "PORT_DDI_B_4_LANES";
case POWER_DOMAIN_PORT_DDI_C_2_LANES:
return "PORT_DDI_C_2_LANES";
case POWER_DOMAIN_PORT_DDI_C_4_LANES:
return "PORT_DDI_C_4_LANES";
case POWER_DOMAIN_PORT_DDI_D_2_LANES:
return "PORT_DDI_D_2_LANES";
case POWER_DOMAIN_PORT_DDI_D_4_LANES:
return "PORT_DDI_D_4_LANES";
case POWER_DOMAIN_PORT_DSI:
return "PORT_DSI";
case POWER_DOMAIN_PORT_CRT:
return "PORT_CRT";
case POWER_DOMAIN_PORT_OTHER:
return "PORT_OTHER";
case POWER_DOMAIN_VGA: case POWER_DOMAIN_VGA:
return "VGA"; return "VGA";
case POWER_DOMAIN_AUDIO: case POWER_DOMAIN_AUDIO:
...@@ -2180,6 +2220,7 @@ static void intel_connector_info(struct seq_file *m, ...@@ -2180,6 +2220,7 @@ static void intel_connector_info(struct seq_file *m,
{ {
struct intel_connector *intel_connector = to_intel_connector(connector); struct intel_connector *intel_connector = to_intel_connector(connector);
struct intel_encoder *intel_encoder = intel_connector->encoder; struct intel_encoder *intel_encoder = intel_connector->encoder;
struct drm_display_mode *mode;
seq_printf(m, "connector %d: type %s, status: %s\n", seq_printf(m, "connector %d: type %s, status: %s\n",
connector->base.id, drm_get_connector_name(connector), connector->base.id, drm_get_connector_name(connector),
...@@ -2202,6 +2243,9 @@ static void intel_connector_info(struct seq_file *m, ...@@ -2202,6 +2243,9 @@ static void intel_connector_info(struct seq_file *m,
else if (intel_encoder->type == INTEL_OUTPUT_LVDS) else if (intel_encoder->type == INTEL_OUTPUT_LVDS)
intel_lvds_info(m, intel_connector); intel_lvds_info(m, intel_connector);
seq_printf(m, "\tmodes:\n");
list_for_each_entry(mode, &connector->modes, head)
intel_seq_print_mode(m, 2, mode);
} }
static int i915_display_info(struct seq_file *m, void *unused) static int i915_display_info(struct seq_file *m, void *unused)
...@@ -3167,9 +3211,8 @@ i915_wedged_set(void *data, u64 val) ...@@ -3167,9 +3211,8 @@ i915_wedged_set(void *data, u64 val)
{ {
struct drm_device *dev = data; struct drm_device *dev = data;
DRM_INFO("Manually setting wedged to %llu\n", val); i915_handle_error(dev, val,
i915_handle_error(dev, val); "Manually setting wedged to %llu", val);
return 0; return 0;
} }
......
...@@ -1321,12 +1321,12 @@ static int i915_load_modeset_init(struct drm_device *dev) ...@@ -1321,12 +1321,12 @@ static int i915_load_modeset_init(struct drm_device *dev)
if (ret) if (ret)
goto cleanup_vga_switcheroo; goto cleanup_vga_switcheroo;
intel_power_domains_init_hw(dev_priv);
ret = drm_irq_install(dev); ret = drm_irq_install(dev);
if (ret) if (ret)
goto cleanup_gem_stolen; goto cleanup_gem_stolen;
intel_power_domains_init_hw(dev);
/* Important: The output setup functions called by modeset_init need /* Important: The output setup functions called by modeset_init need
* working irqs for e.g. gmbus and dp aux transfers. */ * working irqs for e.g. gmbus and dp aux transfers. */
intel_modeset_init(dev); intel_modeset_init(dev);
...@@ -1343,7 +1343,7 @@ static int i915_load_modeset_init(struct drm_device *dev) ...@@ -1343,7 +1343,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
/* FIXME: do pre/post-mode set stuff in core KMS code */ /* FIXME: do pre/post-mode set stuff in core KMS code */
dev->vblank_disable_allowed = true; dev->vblank_disable_allowed = true;
if (INTEL_INFO(dev)->num_pipes == 0) { if (INTEL_INFO(dev)->num_pipes == 0) {
intel_display_power_put(dev, POWER_DOMAIN_VGA); intel_display_power_put(dev_priv, POWER_DOMAIN_VGA);
return 0; return 0;
} }
...@@ -1381,7 +1381,7 @@ static int i915_load_modeset_init(struct drm_device *dev) ...@@ -1381,7 +1381,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
WARN_ON(dev_priv->mm.aliasing_ppgtt); WARN_ON(dev_priv->mm.aliasing_ppgtt);
drm_mm_takedown(&dev_priv->gtt.base.mm); drm_mm_takedown(&dev_priv->gtt.base.mm);
cleanup_power: cleanup_power:
intel_display_power_put(dev, POWER_DOMAIN_VGA); intel_display_power_put(dev_priv, POWER_DOMAIN_VGA);
drm_irq_uninstall(dev); drm_irq_uninstall(dev);
cleanup_gem_stolen: cleanup_gem_stolen:
i915_gem_cleanup_stolen(dev); i915_gem_cleanup_stolen(dev);
...@@ -1480,12 +1480,16 @@ static void intel_device_info_runtime_init(struct drm_device *dev) ...@@ -1480,12 +1480,16 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_device_info *info; struct intel_device_info *info;
enum pipe pipe;
info = (struct intel_device_info *)&dev_priv->info; info = (struct intel_device_info *)&dev_priv->info;
info->num_sprites = 1;
if (IS_VALLEYVIEW(dev)) if (IS_VALLEYVIEW(dev))
info->num_sprites = 2; for_each_pipe(pipe)
info->num_sprites[pipe] = 2;
else
for_each_pipe(pipe)
info->num_sprites[pipe] = 1;
if (i915.disable_display) { if (i915.disable_display) {
DRM_INFO("Display disabled (module parameter)\n"); DRM_INFO("Display disabled (module parameter)\n");
...@@ -1702,7 +1706,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ...@@ -1702,7 +1706,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto out_gem_unload; goto out_gem_unload;
} }
intel_power_domains_init(dev); intel_power_domains_init(dev_priv);
if (drm_core_check_feature(dev, DRIVER_MODESET)) { if (drm_core_check_feature(dev, DRIVER_MODESET)) {
ret = i915_load_modeset_init(dev); ret = i915_load_modeset_init(dev);
...@@ -1731,7 +1735,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ...@@ -1731,7 +1735,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
return 0; return 0;
out_power_well: out_power_well:
intel_power_domains_remove(dev); intel_power_domains_remove(dev_priv);
drm_vblank_cleanup(dev); drm_vblank_cleanup(dev);
out_gem_unload: out_gem_unload:
if (dev_priv->mm.inactive_shrinker.scan_objects) if (dev_priv->mm.inactive_shrinker.scan_objects)
...@@ -1781,8 +1785,8 @@ int i915_driver_unload(struct drm_device *dev) ...@@ -1781,8 +1785,8 @@ int i915_driver_unload(struct drm_device *dev)
/* The i915.ko module is still not prepared to be loaded when /* The i915.ko module is still not prepared to be loaded when
* the power well is not enabled, so just enable it in case * the power well is not enabled, so just enable it in case
* we're going to unload/reload. */ * we're going to unload/reload. */
intel_display_set_init_power(dev, true); intel_display_set_init_power(dev_priv, true);
intel_power_domains_remove(dev); intel_power_domains_remove(dev_priv);
i915_teardown_sysfs(dev); i915_teardown_sysfs(dev);
......
...@@ -265,6 +265,7 @@ static const struct intel_device_info intel_broadwell_d_info = { ...@@ -265,6 +265,7 @@ static const struct intel_device_info intel_broadwell_d_info = {
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
.has_llc = 1, .has_llc = 1,
.has_ddi = 1, .has_ddi = 1,
.has_fbc = 1,
GEN_DEFAULT_PIPEOFFSETS, GEN_DEFAULT_PIPEOFFSETS,
}; };
...@@ -274,6 +275,7 @@ static const struct intel_device_info intel_broadwell_m_info = { ...@@ -274,6 +275,7 @@ static const struct intel_device_info intel_broadwell_m_info = {
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
.has_llc = 1, .has_llc = 1,
.has_ddi = 1, .has_ddi = 1,
.has_fbc = 1,
GEN_DEFAULT_PIPEOFFSETS, GEN_DEFAULT_PIPEOFFSETS,
}; };
...@@ -401,15 +403,13 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) ...@@ -401,15 +403,13 @@ bool i915_semaphore_is_enabled(struct drm_device *dev)
if (INTEL_INFO(dev)->gen < 6) if (INTEL_INFO(dev)->gen < 6)
return false; return false;
/* Until we get further testing... */
if (IS_GEN8(dev)) {
WARN_ON(!i915.preliminary_hw_support);
return false;
}
if (i915.semaphores >= 0) if (i915.semaphores >= 0)
return i915.semaphores; return i915.semaphores;
/* Until we get further testing... */
if (IS_GEN8(dev))
return false;
#ifdef CONFIG_INTEL_IOMMU #ifdef CONFIG_INTEL_IOMMU
/* Enable semaphores on SNB when IO remapping is off */ /* Enable semaphores on SNB when IO remapping is off */
if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped)
...@@ -434,7 +434,7 @@ static int i915_drm_freeze(struct drm_device *dev) ...@@ -434,7 +434,7 @@ static int i915_drm_freeze(struct drm_device *dev)
/* We do a lot of poking in a lot of registers, make sure they work /* We do a lot of poking in a lot of registers, make sure they work
* properly. */ * properly. */
hsw_disable_package_c8(dev_priv); hsw_disable_package_c8(dev_priv);
intel_display_set_init_power(dev, true); intel_display_set_init_power(dev_priv, true);
drm_kms_helper_poll_disable(dev); drm_kms_helper_poll_disable(dev);
...@@ -477,6 +477,8 @@ static int i915_drm_freeze(struct drm_device *dev) ...@@ -477,6 +477,8 @@ static int i915_drm_freeze(struct drm_device *dev)
intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED); intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED);
console_unlock(); console_unlock();
dev_priv->suspend_count++;
return 0; return 0;
} }
...@@ -556,7 +558,7 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings) ...@@ -556,7 +558,7 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings)
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
} }
intel_power_domains_init_hw(dev); intel_power_domains_init_hw(dev_priv);
i915_restore_state(dev); i915_restore_state(dev);
intel_opregion_setup(dev); intel_opregion_setup(dev);
...@@ -847,6 +849,7 @@ static int i915_runtime_suspend(struct device *device) ...@@ -847,6 +849,7 @@ static int i915_runtime_suspend(struct device *device)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
WARN_ON(!HAS_RUNTIME_PM(dev)); WARN_ON(!HAS_RUNTIME_PM(dev));
assert_force_wake_inactive(dev_priv);
DRM_DEBUG_KMS("Suspending device\n"); DRM_DEBUG_KMS("Suspending device\n");
......
This diff is collapsed.
...@@ -61,6 +61,7 @@ static unsigned long i915_gem_inactive_scan(struct shrinker *shrinker, ...@@ -61,6 +61,7 @@ static unsigned long i915_gem_inactive_scan(struct shrinker *shrinker,
static unsigned long i915_gem_purge(struct drm_i915_private *dev_priv, long target); static unsigned long i915_gem_purge(struct drm_i915_private *dev_priv, long target);
static unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv); static unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv);
static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); static void i915_gem_object_truncate(struct drm_i915_gem_object *obj);
static void i915_gem_retire_requests_ring(struct intel_ring_buffer *ring);
static bool cpu_cache_is_coherent(struct drm_device *dev, static bool cpu_cache_is_coherent(struct drm_device *dev,
enum i915_cache_level level) enum i915_cache_level level)
...@@ -326,6 +327,42 @@ __copy_from_user_swizzled(char *gpu_vaddr, int gpu_offset, ...@@ -326,6 +327,42 @@ __copy_from_user_swizzled(char *gpu_vaddr, int gpu_offset,
return 0; return 0;
} }
/*
* Pins the specified object's pages and synchronizes the object with
* GPU accesses. Sets needs_clflush to non-zero if the caller should
* flush the object from the CPU cache.
*/
int i915_gem_obj_prepare_shmem_read(struct drm_i915_gem_object *obj,
int *needs_clflush)
{
int ret;
*needs_clflush = 0;
if (!obj->base.filp)
return -EINVAL;
if (!(obj->base.read_domains & I915_GEM_DOMAIN_CPU)) {
/* If we're not in the cpu read domain, set ourself into the gtt
* read domain and manually flush cachelines (if required). This
* optimizes for the case when the gpu will dirty the data
* anyway again before the next pread happens. */
*needs_clflush = !cpu_cache_is_coherent(obj->base.dev,
obj->cache_level);
ret = i915_gem_object_wait_rendering(obj, true);
if (ret)
return ret;
}
ret = i915_gem_object_get_pages(obj);
if (ret)
return ret;
i915_gem_object_pin_pages(obj);
return ret;
}
/* Per-page copy function for the shmem pread fastpath. /* Per-page copy function for the shmem pread fastpath.
* Flushes invalid cachelines before reading the target if * Flushes invalid cachelines before reading the target if
* needs_clflush is set. */ * needs_clflush is set. */
...@@ -423,23 +460,10 @@ i915_gem_shmem_pread(struct drm_device *dev, ...@@ -423,23 +460,10 @@ i915_gem_shmem_pread(struct drm_device *dev,
obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
if (!(obj->base.read_domains & I915_GEM_DOMAIN_CPU)) { ret = i915_gem_obj_prepare_shmem_read(obj, &needs_clflush);
/* If we're not in the cpu read domain, set ourself into the gtt
* read domain and manually flush cachelines (if required). This
* optimizes for the case when the gpu will dirty the data
* anyway again before the next pread happens. */
needs_clflush = !cpu_cache_is_coherent(dev, obj->cache_level);
ret = i915_gem_object_wait_rendering(obj, true);
if (ret)
return ret;
}
ret = i915_gem_object_get_pages(obj);
if (ret) if (ret)
return ret; return ret;
i915_gem_object_pin_pages(obj);
offset = args->offset; offset = args->offset;
for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents,
...@@ -2148,7 +2172,6 @@ int __i915_add_request(struct intel_ring_buffer *ring, ...@@ -2148,7 +2172,6 @@ int __i915_add_request(struct intel_ring_buffer *ring,
drm_i915_private_t *dev_priv = ring->dev->dev_private; drm_i915_private_t *dev_priv = ring->dev->dev_private;
struct drm_i915_gem_request *request; struct drm_i915_gem_request *request;
u32 request_ring_position, request_start; u32 request_ring_position, request_start;
int was_empty;
int ret; int ret;
request_start = intel_ring_get_tail(ring); request_start = intel_ring_get_tail(ring);
...@@ -2199,7 +2222,6 @@ int __i915_add_request(struct intel_ring_buffer *ring, ...@@ -2199,7 +2222,6 @@ int __i915_add_request(struct intel_ring_buffer *ring,
i915_gem_context_reference(request->ctx); i915_gem_context_reference(request->ctx);
request->emitted_jiffies = jiffies; request->emitted_jiffies = jiffies;
was_empty = list_empty(&ring->request_list);
list_add_tail(&request->list, &ring->request_list); list_add_tail(&request->list, &ring->request_list);
request->file_priv = NULL; request->file_priv = NULL;
...@@ -2220,13 +2242,11 @@ int __i915_add_request(struct intel_ring_buffer *ring, ...@@ -2220,13 +2242,11 @@ int __i915_add_request(struct intel_ring_buffer *ring,
if (!dev_priv->ums.mm_suspended) { if (!dev_priv->ums.mm_suspended) {
i915_queue_hangcheck(ring->dev); i915_queue_hangcheck(ring->dev);
if (was_empty) { cancel_delayed_work_sync(&dev_priv->mm.idle_work);
cancel_delayed_work_sync(&dev_priv->mm.idle_work); queue_delayed_work(dev_priv->wq,
queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work,
&dev_priv->mm.retire_work, round_jiffies_up_relative(HZ));
round_jiffies_up_relative(HZ)); intel_mark_busy(dev_priv->dev);
intel_mark_busy(dev_priv->dev);
}
} }
if (out_seqno) if (out_seqno)
...@@ -2259,14 +2279,13 @@ static bool i915_context_is_banned(struct drm_i915_private *dev_priv, ...@@ -2259,14 +2279,13 @@ static bool i915_context_is_banned(struct drm_i915_private *dev_priv,
return true; return true;
if (elapsed <= DRM_I915_CTX_BAN_PERIOD) { if (elapsed <= DRM_I915_CTX_BAN_PERIOD) {
if (dev_priv->gpu_error.stop_rings == 0 && if (!i915_gem_context_is_default(ctx)) {
i915_gem_context_is_default(ctx)) {
DRM_ERROR("gpu hanging too fast, banning!\n");
} else {
DRM_DEBUG("context hanging too fast, banning!\n"); DRM_DEBUG("context hanging too fast, banning!\n");
return true;
} else if (dev_priv->gpu_error.stop_rings == 0) {
DRM_ERROR("gpu hanging too fast, banning!\n");
return true;
} }
return true;
} }
return false; return false;
...@@ -2303,11 +2322,13 @@ static void i915_gem_free_request(struct drm_i915_gem_request *request) ...@@ -2303,11 +2322,13 @@ static void i915_gem_free_request(struct drm_i915_gem_request *request)
kfree(request); kfree(request);
} }
static struct drm_i915_gem_request * struct drm_i915_gem_request *
i915_gem_find_first_non_complete(struct intel_ring_buffer *ring) i915_gem_find_active_request(struct intel_ring_buffer *ring)
{ {
struct drm_i915_gem_request *request; struct drm_i915_gem_request *request;
const u32 completed_seqno = ring->get_seqno(ring, false); u32 completed_seqno;
completed_seqno = ring->get_seqno(ring, false);
list_for_each_entry(request, &ring->request_list, list) { list_for_each_entry(request, &ring->request_list, list) {
if (i915_seqno_passed(completed_seqno, request->seqno)) if (i915_seqno_passed(completed_seqno, request->seqno))
...@@ -2325,7 +2346,7 @@ static void i915_gem_reset_ring_status(struct drm_i915_private *dev_priv, ...@@ -2325,7 +2346,7 @@ static void i915_gem_reset_ring_status(struct drm_i915_private *dev_priv,
struct drm_i915_gem_request *request; struct drm_i915_gem_request *request;
bool ring_hung; bool ring_hung;
request = i915_gem_find_first_non_complete(ring); request = i915_gem_find_active_request(ring);
if (request == NULL) if (request == NULL)
return; return;
...@@ -2417,7 +2438,7 @@ void i915_gem_reset(struct drm_device *dev) ...@@ -2417,7 +2438,7 @@ void i915_gem_reset(struct drm_device *dev)
/** /**
* This function clears the request list as sequence numbers are passed. * This function clears the request list as sequence numbers are passed.
*/ */
void static void
i915_gem_retire_requests_ring(struct intel_ring_buffer *ring) i915_gem_retire_requests_ring(struct intel_ring_buffer *ring)
{ {
uint32_t seqno; uint32_t seqno;
...@@ -2744,7 +2765,7 @@ int i915_vma_unbind(struct i915_vma *vma) ...@@ -2744,7 +2765,7 @@ int i915_vma_unbind(struct i915_vma *vma)
i915_gem_gtt_finish_object(obj); i915_gem_gtt_finish_object(obj);
list_del(&vma->mm_list); list_del_init(&vma->mm_list);
/* Avoid an unnecessary call to unbind on rebind. */ /* Avoid an unnecessary call to unbind on rebind. */
if (i915_is_ggtt(vma->vm)) if (i915_is_ggtt(vma->vm))
obj->map_and_fenceable = true; obj->map_and_fenceable = true;
...@@ -4860,6 +4881,7 @@ int i915_gem_open(struct drm_device *dev, struct drm_file *file) ...@@ -4860,6 +4881,7 @@ int i915_gem_open(struct drm_device *dev, struct drm_file *file)
file->driver_priv = file_priv; file->driver_priv = file_priv;
file_priv->dev_priv = dev->dev_private; file_priv->dev_priv = dev->dev_private;
file_priv->file = file;
spin_lock_init(&file_priv->mm.lock); spin_lock_init(&file_priv->mm.lock);
INIT_LIST_HEAD(&file_priv->mm.request_list); INIT_LIST_HEAD(&file_priv->mm.request_list);
......
...@@ -99,6 +99,50 @@ ...@@ -99,6 +99,50 @@
static int do_switch(struct intel_ring_buffer *ring, static int do_switch(struct intel_ring_buffer *ring,
struct i915_hw_context *to); struct i915_hw_context *to);
static void do_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt)
{
struct drm_device *dev = ppgtt->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct i915_address_space *vm = &ppgtt->base;
if (ppgtt == dev_priv->mm.aliasing_ppgtt ||
(list_empty(&vm->active_list) && list_empty(&vm->inactive_list))) {
ppgtt->base.cleanup(&ppgtt->base);
return;
}
/*
* Make sure vmas are unbound before we take down the drm_mm
*
* FIXME: Proper refcounting should take care of this, this shouldn't be
* needed at all.
*/
if (!list_empty(&vm->active_list)) {
struct i915_vma *vma;
list_for_each_entry(vma, &vm->active_list, mm_list)
if (WARN_ON(list_empty(&vma->vma_link) ||
list_is_singular(&vma->vma_link)))
break;
i915_gem_evict_vm(&ppgtt->base, true);
} else {
i915_gem_retire_requests(dev);
i915_gem_evict_vm(&ppgtt->base, false);
}
ppgtt->base.cleanup(&ppgtt->base);
}
static void ppgtt_release(struct kref *kref)
{
struct i915_hw_ppgtt *ppgtt =
container_of(kref, struct i915_hw_ppgtt, ref);
do_ppgtt_cleanup(ppgtt);
kfree(ppgtt);
}
static size_t get_context_alignment(struct drm_device *dev) static size_t get_context_alignment(struct drm_device *dev)
{ {
if (IS_GEN6(dev)) if (IS_GEN6(dev))
...@@ -714,7 +758,7 @@ static int do_switch(struct intel_ring_buffer *ring, ...@@ -714,7 +758,7 @@ static int do_switch(struct intel_ring_buffer *ring,
* i915_switch_context() - perform a GPU context switch. * i915_switch_context() - perform a GPU context switch.
* @ring: ring for which we'll execute the context switch * @ring: ring for which we'll execute the context switch
* @file_priv: file_priv associated with the context, may be NULL * @file_priv: file_priv associated with the context, may be NULL
* @id: context id number * @to: the context to switch to
* *
* The context life cycle is simple. The context refcount is incremented and * The context life cycle is simple. The context refcount is incremented and
* decremented by 1 and create and destroy. If the context is in use by the GPU, * decremented by 1 and create and destroy. If the context is in use by the GPU,
...@@ -746,9 +790,6 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, ...@@ -746,9 +790,6 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
struct i915_hw_context *ctx; struct i915_hw_context *ctx;
int ret; int ret;
if (!(dev->driver->driver_features & DRIVER_GEM))
return -ENODEV;
if (!HAS_HW_CONTEXTS(dev)) if (!HAS_HW_CONTEXTS(dev))
return -ENODEV; return -ENODEV;
...@@ -775,9 +816,6 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, ...@@ -775,9 +816,6 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
struct i915_hw_context *ctx; struct i915_hw_context *ctx;
int ret; int ret;
if (!(dev->driver->driver_features & DRIVER_GEM))
return -ENODEV;
if (args->ctx_id == DEFAULT_CONTEXT_ID) if (args->ctx_id == DEFAULT_CONTEXT_ID)
return -ENOENT; return -ENOENT;
......
...@@ -1182,6 +1182,24 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, ...@@ -1182,6 +1182,24 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
} }
batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND; batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND;
if (i915_needs_cmd_parser(ring)) {
ret = i915_parse_cmds(ring,
batch_obj,
args->batch_start_offset,
file->is_master);
if (ret)
goto err;
/*
* 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
* 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
* batch" bit. Hence we need to pin secure batches into the global gtt. * batch" bit. Hence we need to pin secure batches into the global gtt.
* hsw should have this fixed, but bdw mucks it up again. */ * hsw should have this fixed, but bdw mucks it up again. */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -48,6 +48,7 @@ struct i915_params i915 __read_mostly = { ...@@ -48,6 +48,7 @@ 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,
}; };
module_param_named(modeset, i915.modeset, int, 0400); module_param_named(modeset, i915.modeset, int, 0400);
...@@ -157,3 +158,7 @@ MODULE_PARM_DESC(invert_brightness, ...@@ -157,3 +158,7 @@ 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(enable_cmd_parser, i915.enable_cmd_parser, int, 0600);
MODULE_PARM_DESC(enable_cmd_parser,
"Enable command parsing (1=enabled, 0=disabled [default])");
...@@ -174,6 +174,18 @@ ...@@ -174,6 +174,18 @@
#define VGA_CR_INDEX_CGA 0x3d4 #define VGA_CR_INDEX_CGA 0x3d4
#define VGA_CR_DATA_CGA 0x3d5 #define VGA_CR_DATA_CGA 0x3d5
/*
* Instruction field definitions used by the command parser
*/
#define INSTR_CLIENT_SHIFT 29
#define INSTR_CLIENT_MASK 0xE0000000
#define INSTR_MI_CLIENT 0x0
#define INSTR_BC_CLIENT 0x2
#define INSTR_RC_CLIENT 0x3
#define INSTR_SUBCLIENT_SHIFT 27
#define INSTR_SUBCLIENT_MASK 0x18000000
#define INSTR_MEDIA_SUBCLIENT 0x2
/* /*
* Memory interface instructions used by the kernel * Memory interface instructions used by the kernel
*/ */
...@@ -377,14 +389,30 @@ ...@@ -377,14 +389,30 @@
#define DSPFREQSTAT_MASK (0x3 << DSPFREQSTAT_SHIFT) #define DSPFREQSTAT_MASK (0x3 << DSPFREQSTAT_SHIFT)
#define DSPFREQGUAR_SHIFT 14 #define DSPFREQGUAR_SHIFT 14
#define DSPFREQGUAR_MASK (0x3 << DSPFREQGUAR_SHIFT) #define DSPFREQGUAR_MASK (0x3 << DSPFREQGUAR_SHIFT)
/* See the PUNIT HAS v0.8 for the below bits */
enum punit_power_well {
PUNIT_POWER_WELL_RENDER = 0,
PUNIT_POWER_WELL_MEDIA = 1,
PUNIT_POWER_WELL_DISP2D = 3,
PUNIT_POWER_WELL_DPIO_CMN_BC = 5,
PUNIT_POWER_WELL_DPIO_TX_B_LANES_01 = 6,
PUNIT_POWER_WELL_DPIO_TX_B_LANES_23 = 7,
PUNIT_POWER_WELL_DPIO_TX_C_LANES_01 = 8,
PUNIT_POWER_WELL_DPIO_TX_C_LANES_23 = 9,
PUNIT_POWER_WELL_DPIO_RX0 = 10,
PUNIT_POWER_WELL_DPIO_RX1 = 11,
PUNIT_POWER_WELL_NUM,
};
#define PUNIT_REG_PWRGT_CTRL 0x60 #define PUNIT_REG_PWRGT_CTRL 0x60
#define PUNIT_REG_PWRGT_STATUS 0x61 #define PUNIT_REG_PWRGT_STATUS 0x61
#define PUNIT_CLK_GATE 1 #define PUNIT_PWRGT_MASK(power_well) (3 << ((power_well) * 2))
#define PUNIT_PWR_RESET 2 #define PUNIT_PWRGT_PWR_ON(power_well) (0 << ((power_well) * 2))
#define PUNIT_PWR_GATE 3 #define PUNIT_PWRGT_CLK_GATE(power_well) (1 << ((power_well) * 2))
#define RENDER_PWRGT (PUNIT_PWR_GATE << 0) #define PUNIT_PWRGT_RESET(power_well) (2 << ((power_well) * 2))
#define MEDIA_PWRGT (PUNIT_PWR_GATE << 2) #define PUNIT_PWRGT_PWR_GATE(power_well) (3 << ((power_well) * 2))
#define DISP2D_PWRGT (PUNIT_PWR_GATE << 6)
#define PUNIT_REG_GPU_LFM 0xd3 #define PUNIT_REG_GPU_LFM 0xd3
#define PUNIT_REG_GPU_FREQ_REQ 0xd4 #define PUNIT_REG_GPU_FREQ_REQ 0xd4
...@@ -798,7 +826,12 @@ ...@@ -798,7 +826,12 @@
# define ASYNC_FLIP_PERF_DISABLE (1 << 14) # define ASYNC_FLIP_PERF_DISABLE (1 << 14)
#define GEN6_GT_MODE 0x20d0 #define GEN6_GT_MODE 0x20d0
#define GEN6_GT_MODE_HI (1 << 9) #define GEN7_GT_MODE 0x7008
#define GEN6_WIZ_HASHING(hi, lo) (((hi) << 9) | ((lo) << 7))
#define GEN6_WIZ_HASHING_8x8 GEN6_WIZ_HASHING(0, 0)
#define GEN6_WIZ_HASHING_8x4 GEN6_WIZ_HASHING(0, 1)
#define GEN6_WIZ_HASHING_16x4 GEN6_WIZ_HASHING(1, 0)
#define GEN6_WIZ_HASHING_MASK (GEN6_WIZ_HASHING(1, 1) << 16)
#define GEN6_TD_FOUR_ROW_DISPATCH_DISABLE (1 << 5) #define GEN6_TD_FOUR_ROW_DISPATCH_DISABLE (1 << 5)
#define GFX_MODE 0x02520 #define GFX_MODE 0x02520
...@@ -944,6 +977,9 @@ ...@@ -944,6 +977,9 @@
#define GEN6_BLITTER_LOCK_SHIFT 16 #define GEN6_BLITTER_LOCK_SHIFT 16
#define GEN6_BLITTER_FBC_NOTIFY (1<<3) #define GEN6_BLITTER_FBC_NOTIFY (1<<3)
#define GEN6_RC_SLEEP_PSMI_CONTROL 0x2050
#define GEN8_RC_SEMA_IDLE_MSG_DISABLE (1 << 12)
#define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050 #define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050
#define GEN6_BSD_SLEEP_MSG_DISABLE (1 << 0) #define GEN6_BSD_SLEEP_MSG_DISABLE (1 << 0)
#define GEN6_BSD_SLEEP_FLUSH_DISABLE (1 << 2) #define GEN6_BSD_SLEEP_FLUSH_DISABLE (1 << 2)
...@@ -1121,13 +1157,6 @@ ...@@ -1121,13 +1157,6 @@
#define FBC_REND_NUKE (1<<2) #define FBC_REND_NUKE (1<<2)
#define FBC_REND_CACHE_CLEAN (1<<1) #define FBC_REND_CACHE_CLEAN (1<<1)
#define _HSW_PIPE_SLICE_CHICKEN_1_A 0x420B0
#define _HSW_PIPE_SLICE_CHICKEN_1_B 0x420B4
#define HSW_BYPASS_FBC_QUEUE (1<<22)
#define HSW_PIPE_SLICE_CHICKEN_1(pipe) _PIPE(pipe, + \
_HSW_PIPE_SLICE_CHICKEN_1_A, + \
_HSW_PIPE_SLICE_CHICKEN_1_B)
/* /*
* GPIO regs * GPIO regs
*/ */
...@@ -4140,7 +4169,8 @@ ...@@ -4140,7 +4169,8 @@
#define _CHICKEN_PIPESL_1_A 0x420b0 #define _CHICKEN_PIPESL_1_A 0x420b0
#define _CHICKEN_PIPESL_1_B 0x420b4 #define _CHICKEN_PIPESL_1_B 0x420b4
#define DPRS_MASK_VBLANK_SRD (1 << 0) #define HSW_FBCQ_DIS (1 << 22)
#define BDW_DPRS_MASK_VBLANK_SRD (1 << 0)
#define CHICKEN_PIPESL_1(pipe) _PIPE(pipe, _CHICKEN_PIPESL_1_A, _CHICKEN_PIPESL_1_B) #define CHICKEN_PIPESL_1(pipe) _PIPE(pipe, _CHICKEN_PIPESL_1_A, _CHICKEN_PIPESL_1_B)
#define DISP_ARB_CTL 0x45000 #define DISP_ARB_CTL 0x45000
...@@ -4164,7 +4194,7 @@ ...@@ -4164,7 +4194,7 @@
#define VLV_B0_WA_L3SQCREG1_VALUE 0x00D30000 #define VLV_B0_WA_L3SQCREG1_VALUE 0x00D30000
#define GEN7_L3CNTLREG1 0xB01C #define GEN7_L3CNTLREG1 0xB01C
#define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C4FFF8C #define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C47FF8C
#define GEN7_L3AGDIS (1<<19) #define GEN7_L3AGDIS (1<<19)
#define GEN7_L3_CHICKEN_MODE_REGISTER 0xB030 #define GEN7_L3_CHICKEN_MODE_REGISTER 0xB030
...@@ -4898,6 +4928,9 @@ ...@@ -4898,6 +4928,9 @@
#define GEN7_UCGCTL4 0x940c #define GEN7_UCGCTL4 0x940c
#define GEN7_L3BANK2X_CLOCK_GATE_DISABLE (1<<25) #define GEN7_L3BANK2X_CLOCK_GATE_DISABLE (1<<25)
#define GEN8_UCGCTL6 0x9430
#define GEN8_SDEUNIT_CLOCK_GATE_DISABLE (1<<14)
#define GEN6_RPNSWREQ 0xA008 #define GEN6_RPNSWREQ 0xA008
#define GEN6_TURBO_DISABLE (1<<31) #define GEN6_TURBO_DISABLE (1<<31)
#define GEN6_FREQUENCY(x) ((x)<<25) #define GEN6_FREQUENCY(x) ((x)<<25)
...@@ -5043,6 +5076,10 @@ ...@@ -5043,6 +5076,10 @@
#define GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE (1<<10) #define GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE (1<<10)
#define GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE (1<<3) #define GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE (1<<3)
#define GEN8_ROW_CHICKEN 0xe4f0
#define PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE (1<<8)
#define STALL_DOP_GATING_DISABLE (1<<5)
#define GEN7_ROW_CHICKEN2 0xe4f4 #define GEN7_ROW_CHICKEN2 0xe4f4
#define GEN7_ROW_CHICKEN2_GT2 0xf4f4 #define GEN7_ROW_CHICKEN2_GT2 0xf4f4
#define DOP_CLOCK_GATING_DISABLE (1<<0) #define DOP_CLOCK_GATING_DISABLE (1<<0)
......
...@@ -599,14 +599,14 @@ parse_mipi(struct drm_i915_private *dev_priv, struct bdb_header *bdb) ...@@ -599,14 +599,14 @@ parse_mipi(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
{ {
struct bdb_mipi *mipi; struct bdb_mipi *mipi;
mipi = find_section(bdb, BDB_MIPI); mipi = find_section(bdb, BDB_MIPI_CONFIG);
if (!mipi) { if (!mipi) {
DRM_DEBUG_KMS("No MIPI BDB found"); DRM_DEBUG_KMS("No MIPI BDB found");
return; return;
} }
/* XXX: add more info */ /* XXX: add more info */
dev_priv->vbt.dsi.panel_id = mipi->panel_id; dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID;
} }
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,
......
...@@ -104,7 +104,8 @@ struct vbios_data { ...@@ -104,7 +104,8 @@ struct vbios_data {
#define BDB_LVDS_LFP_DATA 42 #define BDB_LVDS_LFP_DATA 42
#define BDB_LVDS_BACKLIGHT 43 #define BDB_LVDS_BACKLIGHT 43
#define BDB_LVDS_POWER 44 #define BDB_LVDS_POWER 44
#define BDB_MIPI 50 #define BDB_MIPI_CONFIG 52
#define BDB_MIPI_SEQUENCE 53
#define BDB_SKIP 254 /* VBIOS private block, ignore */ #define BDB_SKIP 254 /* VBIOS private block, ignore */
struct bdb_general_features { struct bdb_general_features {
...@@ -711,44 +712,159 @@ int intel_parse_bios(struct drm_device *dev); ...@@ -711,44 +712,159 @@ int intel_parse_bios(struct drm_device *dev);
#define DVO_PORT_DPD 9 #define DVO_PORT_DPD 9
#define DVO_PORT_DPA 10 #define DVO_PORT_DPA 10
/* MIPI DSI panel info */ /* Block 52 contains MIPI Panel info
struct bdb_mipi { * 6 such enteries will there. Index into correct
u16 panel_id; * entery is based on the panel_index in #40 LFP
u16 bridge_revision; */
#define MAX_MIPI_CONFIGURATIONS 6
/* General params */
u32 dithering:1;
u32 bpp_pixel_format:1;
u32 rsvd1:1;
u32 dphy_valid:1;
u32 resvd2:28;
u16 port_info; #define MIPI_DSI_UNDEFINED_PANEL_ID 0
u16 rsvd3:2; #define MIPI_DSI_GENERIC_PANEL_ID 1
u16 num_lanes:2;
u16 rsvd4:12;
/* DSI config */ struct mipi_config {
u16 virt_ch_num:2; u16 panel_id;
u16 vtm:2;
u16 rsvd5:12;
u32 dsi_clock; /* General Params */
u32 enable_dithering:1;
u32 rsvd1:1;
u32 is_bridge:1;
u32 panel_arch_type:2;
u32 is_cmd_mode:1;
#define NON_BURST_SYNC_PULSE 0x1
#define NON_BURST_SYNC_EVENTS 0x2
#define BURST_MODE 0x3
u32 video_transfer_mode:2;
u32 cabc_supported:1;
u32 pwm_blc:1;
/* Bit 13:10 */
#define PIXEL_FORMAT_RGB565 0x1
#define PIXEL_FORMAT_RGB666 0x2
#define PIXEL_FORMAT_RGB666_LOOSELY_PACKED 0x3
#define PIXEL_FORMAT_RGB888 0x4
u32 videomode_color_format:4;
/* Bit 15:14 */
#define ENABLE_ROTATION_0 0x0
#define ENABLE_ROTATION_90 0x1
#define ENABLE_ROTATION_180 0x2
#define ENABLE_ROTATION_270 0x3
u32 rotation:2;
u32 bta_enabled:1;
u32 rsvd2:15;
/* 2 byte Port Description */
#define DUAL_LINK_NOT_SUPPORTED 0
#define DUAL_LINK_FRONT_BACK 1
#define DUAL_LINK_PIXEL_ALT 2
u16 dual_link:2;
u16 lane_cnt:2;
u16 rsvd3:12;
u16 rsvd4;
u8 rsvd5[5];
u32 dsi_ddr_clk;
u32 bridge_ref_clk; u32 bridge_ref_clk;
u16 rsvd_pwr;
/* Dphy Params */ #define BYTE_CLK_SEL_20MHZ 0
u32 prepare_cnt:5; #define BYTE_CLK_SEL_10MHZ 1
u32 rsvd6:3; #define BYTE_CLK_SEL_5MHZ 2
u8 byte_clk_sel:2;
u8 rsvd6:6;
/* DPHY Flags */
u16 dphy_param_valid:1;
u16 eot_pkt_disabled:1;
u16 enable_clk_stop:1;
u16 rsvd7:13;
u32 hs_tx_timeout;
u32 lp_rx_timeout;
u32 turn_around_timeout;
u32 device_reset_timer;
u32 master_init_timer;
u32 dbi_bw_timer;
u32 lp_byte_clk_val;
/* 4 byte Dphy Params */
u32 prepare_cnt:6;
u32 rsvd8:2;
u32 clk_zero_cnt:8; u32 clk_zero_cnt:8;
u32 trail_cnt:5; u32 trail_cnt:5;
u32 rsvd7:3; u32 rsvd9:3;
u32 exit_zero_cnt:6; u32 exit_zero_cnt:6;
u32 rsvd8:2; u32 rsvd10:2;
u32 hl_switch_cnt;
u32 lp_byte_clk;
u32 clk_lane_switch_cnt; u32 clk_lane_switch_cnt;
u32 hl_switch_cnt;
u32 rsvd11[6];
/* timings based on dphy spec */
u8 tclk_miss;
u8 tclk_post;
u8 rsvd12;
u8 tclk_pre;
u8 tclk_prepare;
u8 tclk_settle;
u8 tclk_term_enable;
u8 tclk_trail;
u16 tclk_prepare_clkzero;
u8 rsvd13;
u8 td_term_enable;
u8 teot;
u8 ths_exit;
u8 ths_prepare;
u16 ths_prepare_hszero;
u8 rsvd14;
u8 ths_settle;
u8 ths_skip;
u8 ths_trail;
u8 tinit;
u8 tlpx;
u8 rsvd15[3];
/* GPIOs */
u8 panel_enable;
u8 bl_enable;
u8 pwm_enable;
u8 reset_r_n;
u8 pwr_down_r;
u8 stdby_r_n;
} __packed; } __packed;
/* Block 52 contains MIPI configuration block
* 6 * bdb_mipi_config, followed by 6 pps data
* block below
*
* all delays has a unit of 100us
*/
struct mipi_pps_data {
u16 panel_on_delay;
u16 bl_enable_delay;
u16 bl_disable_delay;
u16 panel_off_delay;
u16 panel_power_cycle_delay;
};
struct bdb_mipi_config {
struct mipi_config config[MAX_MIPI_CONFIGURATIONS];
struct mipi_pps_data pps[MAX_MIPI_CONFIGURATIONS];
};
/* Block 53 contains MIPI sequences as needed by the panel
* for enabling it. This block can be variable in size and
* can be maximum of 6 blocks
*/
struct bdb_mipi_sequence {
u8 version;
u8 data[0];
};
#endif /* _I830_BIOS_H_ */ #endif /* _I830_BIOS_H_ */
...@@ -68,8 +68,13 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder, ...@@ -68,8 +68,13 @@ static bool intel_crt_get_hw_state(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_crt *crt = intel_encoder_to_crt(encoder); struct intel_crt *crt = intel_encoder_to_crt(encoder);
enum intel_display_power_domain power_domain;
u32 tmp; u32 tmp;
power_domain = intel_display_port_power_domain(encoder);
if (!intel_display_power_enabled(dev_priv, power_domain))
return false;
tmp = I915_READ(crt->adpa_reg); tmp = I915_READ(crt->adpa_reg);
if (!(tmp & ADPA_DAC_ENABLE)) if (!(tmp & ADPA_DAC_ENABLE))
...@@ -262,6 +267,10 @@ static bool intel_crt_compute_config(struct intel_encoder *encoder, ...@@ -262,6 +267,10 @@ static bool intel_crt_compute_config(struct intel_encoder *encoder,
if (HAS_PCH_LPT(dev)) if (HAS_PCH_LPT(dev))
pipe_config->pipe_bpp = 24; pipe_config->pipe_bpp = 24;
/* FDI must always be 2.7 GHz */
if (HAS_DDI(dev))
pipe_config->port_clock = 135000 * 2;
return true; return true;
} }
...@@ -630,14 +639,22 @@ static enum drm_connector_status ...@@ -630,14 +639,22 @@ static enum drm_connector_status
intel_crt_detect(struct drm_connector *connector, bool force) intel_crt_detect(struct drm_connector *connector, bool force)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crt *crt = intel_attached_crt(connector); struct intel_crt *crt = intel_attached_crt(connector);
struct intel_encoder *intel_encoder = &crt->base;
enum intel_display_power_domain power_domain;
enum drm_connector_status status; enum drm_connector_status status;
struct intel_load_detect_pipe tmp; struct intel_load_detect_pipe tmp;
intel_runtime_pm_get(dev_priv);
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n", DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n",
connector->base.id, drm_get_connector_name(connector), connector->base.id, drm_get_connector_name(connector),
force); force);
power_domain = intel_display_port_power_domain(intel_encoder);
intel_display_power_get(dev_priv, power_domain);
if (I915_HAS_HOTPLUG(dev)) { if (I915_HAS_HOTPLUG(dev)) {
/* We can not rely on the HPD pin always being correctly wired /* We can not rely on the HPD pin always being correctly wired
* up, for example many KVM do not pass it through, and so * up, for example many KVM do not pass it through, and so
...@@ -645,23 +662,30 @@ intel_crt_detect(struct drm_connector *connector, bool force) ...@@ -645,23 +662,30 @@ intel_crt_detect(struct drm_connector *connector, bool force)
*/ */
if (intel_crt_detect_hotplug(connector)) { if (intel_crt_detect_hotplug(connector)) {
DRM_DEBUG_KMS("CRT detected via hotplug\n"); DRM_DEBUG_KMS("CRT detected via hotplug\n");
return connector_status_connected; status = connector_status_connected;
goto out;
} else } else
DRM_DEBUG_KMS("CRT not detected via hotplug\n"); DRM_DEBUG_KMS("CRT not detected via hotplug\n");
} }
if (intel_crt_detect_ddc(connector)) if (intel_crt_detect_ddc(connector)) {
return connector_status_connected; status = connector_status_connected;
goto out;
}
/* Load detection is broken on HPD capable machines. Whoever wants a /* Load detection is broken on HPD capable machines. Whoever wants a
* broken monitor (without edid) to work behind a broken kvm (that fails * broken monitor (without edid) to work behind a broken kvm (that fails
* to have the right resistors for HP detection) needs to fix this up. * to have the right resistors for HP detection) needs to fix this up.
* For now just bail out. */ * For now just bail out. */
if (I915_HAS_HOTPLUG(dev)) if (I915_HAS_HOTPLUG(dev)) {
return connector_status_disconnected; status = connector_status_disconnected;
goto out;
}
if (!force) if (!force) {
return connector->status; status = connector->status;
goto out;
}
/* for pre-945g platforms use load detect */ /* for pre-945g platforms use load detect */
if (intel_get_load_detect_pipe(connector, NULL, &tmp)) { if (intel_get_load_detect_pipe(connector, NULL, &tmp)) {
...@@ -673,6 +697,10 @@ intel_crt_detect(struct drm_connector *connector, bool force) ...@@ -673,6 +697,10 @@ intel_crt_detect(struct drm_connector *connector, bool force)
} else } else
status = connector_status_unknown; status = connector_status_unknown;
out:
intel_display_power_put(dev_priv, power_domain);
intel_runtime_pm_put(dev_priv);
return status; return status;
} }
...@@ -686,17 +714,28 @@ static int intel_crt_get_modes(struct drm_connector *connector) ...@@ -686,17 +714,28 @@ static int intel_crt_get_modes(struct drm_connector *connector)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crt *crt = intel_attached_crt(connector);
struct intel_encoder *intel_encoder = &crt->base;
enum intel_display_power_domain power_domain;
int ret; int ret;
struct i2c_adapter *i2c; struct i2c_adapter *i2c;
power_domain = intel_display_port_power_domain(intel_encoder);
intel_display_power_get(dev_priv, power_domain);
i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin); i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin);
ret = intel_crt_ddc_get_modes(connector, i2c); ret = intel_crt_ddc_get_modes(connector, i2c);
if (ret || !IS_G4X(dev)) if (ret || !IS_G4X(dev))
return ret; goto out;
/* Try to probe digital port for output in DVI-I -> VGA mode. */ /* Try to probe digital port for output in DVI-I -> VGA mode. */
i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB); i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB);
return intel_crt_ddc_get_modes(connector, i2c); ret = intel_crt_ddc_get_modes(connector, i2c);
out:
intel_display_power_put(dev_priv, power_domain);
return ret;
} }
static int intel_crt_set_property(struct drm_connector *connector, static int intel_crt_set_property(struct drm_connector *connector,
......
...@@ -1145,9 +1145,14 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder, ...@@ -1145,9 +1145,14 @@ bool intel_ddi_get_hw_state(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;
enum port port = intel_ddi_get_encoder_port(encoder); enum port port = intel_ddi_get_encoder_port(encoder);
enum intel_display_power_domain power_domain;
u32 tmp; u32 tmp;
int i; int i;
power_domain = intel_display_port_power_domain(encoder);
if (!intel_display_power_enabled(dev_priv, power_domain))
return false;
tmp = I915_READ(DDI_BUF_CTL(port)); tmp = I915_READ(DDI_BUF_CTL(port));
if (!(tmp & DDI_BUF_CTL_ENABLE)) if (!(tmp & DDI_BUF_CTL_ENABLE))
......
This diff is collapsed.
...@@ -916,8 +916,8 @@ intel_dp_compute_config(struct intel_encoder *encoder, ...@@ -916,8 +916,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
bpp); bpp);
for (clock = 0; clock <= max_clock; clock++) { for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { for (clock = 0; clock <= max_clock; clock++) {
link_clock = drm_dp_bw_code_to_link_rate(bws[clock]); link_clock = drm_dp_bw_code_to_link_rate(bws[clock]);
link_avail = intel_dp_max_data_rate(link_clock, link_avail = intel_dp_max_data_rate(link_clock,
lane_count); lane_count);
...@@ -1333,7 +1333,8 @@ void intel_edp_panel_off(struct intel_dp *intel_dp) ...@@ -1333,7 +1333,8 @@ void intel_edp_panel_off(struct intel_dp *intel_dp)
pp = ironlake_get_pp_control(intel_dp); pp = ironlake_get_pp_control(intel_dp);
/* We need to switch off panel power _and_ force vdd, for otherwise some /* We need to switch off panel power _and_ force vdd, for otherwise some
* panels get very unhappy and cease to work. */ * panels get very unhappy and cease to work. */
pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE); pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_FORCE_VDD |
EDP_BLC_ENABLE);
pp_ctrl_reg = _pp_ctrl_reg(intel_dp); pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
...@@ -1485,7 +1486,14 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder, ...@@ -1485,7 +1486,14 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
enum port port = dp_to_dig_port(intel_dp)->port; enum port port = dp_to_dig_port(intel_dp)->port;
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;
u32 tmp = I915_READ(intel_dp->output_reg); enum intel_display_power_domain power_domain;
u32 tmp;
power_domain = intel_display_port_power_domain(encoder);
if (!intel_display_power_enabled(dev_priv, power_domain))
return false;
tmp = I915_READ(intel_dp->output_reg);
if (!(tmp & DP_PORT_EN)) if (!(tmp & DP_PORT_EN))
return false; return false;
...@@ -1868,9 +1876,11 @@ static void intel_disable_dp(struct intel_encoder *encoder) ...@@ -1868,9 +1876,11 @@ static void intel_disable_dp(struct intel_encoder *encoder)
/* Make sure the panel is off before trying to change the mode. But also /* Make sure the panel is off before trying to change the mode. But also
* ensure that we have vdd while we switch off the panel. */ * ensure that we have vdd while we switch off the panel. */
edp_panel_vdd_on(intel_dp);
intel_edp_backlight_off(intel_dp); intel_edp_backlight_off(intel_dp);
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
intel_edp_panel_off(intel_dp); intel_edp_panel_off(intel_dp);
edp_panel_vdd_off(intel_dp, true);
/* cpu edp my only be disable _after_ the cpu pipe/plane is disabled. */ /* cpu edp my only be disable _after_ the cpu pipe/plane is disabled. */
if (!(port == PORT_A || IS_VALLEYVIEW(dev))) if (!(port == PORT_A || IS_VALLEYVIEW(dev)))
...@@ -3224,10 +3234,14 @@ intel_dp_detect(struct drm_connector *connector, bool force) ...@@ -3224,10 +3234,14 @@ intel_dp_detect(struct drm_connector *connector, bool force)
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
enum drm_connector_status status; enum drm_connector_status status;
enum intel_display_power_domain power_domain;
struct edid *edid = NULL; struct edid *edid = NULL;
intel_runtime_pm_get(dev_priv); intel_runtime_pm_get(dev_priv);
power_domain = intel_display_port_power_domain(intel_encoder);
intel_display_power_get(dev_priv, power_domain);
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
connector->base.id, drm_get_connector_name(connector)); connector->base.id, drm_get_connector_name(connector));
...@@ -3258,21 +3272,32 @@ intel_dp_detect(struct drm_connector *connector, bool force) ...@@ -3258,21 +3272,32 @@ intel_dp_detect(struct drm_connector *connector, bool force)
status = connector_status_connected; status = connector_status_connected;
out: out:
intel_display_power_put(dev_priv, power_domain);
intel_runtime_pm_put(dev_priv); intel_runtime_pm_put(dev_priv);
return status; return status;
} }
static int intel_dp_get_modes(struct drm_connector *connector) static int intel_dp_get_modes(struct drm_connector *connector)
{ {
struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_dp *intel_dp = intel_attached_dp(connector);
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct intel_encoder *intel_encoder = &intel_dig_port->base;
struct intel_connector *intel_connector = to_intel_connector(connector); struct intel_connector *intel_connector = to_intel_connector(connector);
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum intel_display_power_domain power_domain;
int ret; int ret;
/* We should parse the EDID data and find out if it has an audio sink /* We should parse the EDID data and find out if it has an audio sink
*/ */
power_domain = intel_display_port_power_domain(intel_encoder);
intel_display_power_get(dev_priv, power_domain);
ret = intel_dp_get_edid_modes(connector, &intel_dp->adapter); ret = intel_dp_get_edid_modes(connector, &intel_dp->adapter);
intel_display_power_put(dev_priv, power_domain);
if (ret) if (ret)
return ret; return ret;
...@@ -3293,15 +3318,25 @@ static bool ...@@ -3293,15 +3318,25 @@ static bool
intel_dp_detect_audio(struct drm_connector *connector) intel_dp_detect_audio(struct drm_connector *connector)
{ {
struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_dp *intel_dp = intel_attached_dp(connector);
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct intel_encoder *intel_encoder = &intel_dig_port->base;
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum intel_display_power_domain power_domain;
struct edid *edid; struct edid *edid;
bool has_audio = false; bool has_audio = false;
power_domain = intel_display_port_power_domain(intel_encoder);
intel_display_power_get(dev_priv, power_domain);
edid = intel_dp_get_edid(connector, &intel_dp->adapter); edid = intel_dp_get_edid(connector, &intel_dp->adapter);
if (edid) { if (edid) {
has_audio = drm_detect_monitor_audio(edid); has_audio = drm_detect_monitor_audio(edid);
kfree(edid); kfree(edid);
} }
intel_display_power_put(dev_priv, power_domain);
return has_audio; return has_audio;
} }
......
...@@ -609,6 +609,8 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi) ...@@ -609,6 +609,8 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
/* i915_irq.c */ /* i915_irq.c */
bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
enum pipe pipe, bool enable); enum pipe pipe, bool enable);
bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
enum pipe pipe, bool enable);
bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev,
enum transcoder pch_transcoder, enum transcoder pch_transcoder,
bool enable); bool enable);
...@@ -732,7 +734,9 @@ ironlake_check_encoder_dotclock(const struct intel_crtc_config *pipe_config, ...@@ -732,7 +734,9 @@ ironlake_check_encoder_dotclock(const struct intel_crtc_config *pipe_config,
bool intel_crtc_active(struct drm_crtc *crtc); bool intel_crtc_active(struct drm_crtc *crtc);
void hsw_enable_ips(struct intel_crtc *crtc); void hsw_enable_ips(struct intel_crtc *crtc);
void hsw_disable_ips(struct intel_crtc *crtc); void hsw_disable_ips(struct intel_crtc *crtc);
void intel_display_set_init_power(struct drm_device *dev, bool enable); void intel_display_set_init_power(struct drm_i915_private *dev, bool enable);
enum intel_display_power_domain
intel_display_port_power_domain(struct intel_encoder *intel_encoder);
int valleyview_get_vco(struct drm_i915_private *dev_priv); int valleyview_get_vco(struct drm_i915_private *dev_priv);
void intel_mode_from_pipe_config(struct drm_display_mode *mode, void intel_mode_from_pipe_config(struct drm_display_mode *mode,
struct intel_crtc_config *pipe_config); struct intel_crtc_config *pipe_config);
...@@ -871,18 +875,17 @@ bool intel_fbc_enabled(struct drm_device *dev); ...@@ -871,18 +875,17 @@ bool intel_fbc_enabled(struct drm_device *dev);
void intel_update_fbc(struct drm_device *dev); void intel_update_fbc(struct drm_device *dev);
void intel_gpu_ips_init(struct drm_i915_private *dev_priv); void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
void intel_gpu_ips_teardown(void); void intel_gpu_ips_teardown(void);
int intel_power_domains_init(struct drm_device *dev); int intel_power_domains_init(struct drm_i915_private *);
void intel_power_domains_remove(struct drm_device *dev); void intel_power_domains_remove(struct drm_i915_private *);
bool intel_display_power_enabled(struct drm_device *dev, bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain); enum intel_display_power_domain domain);
bool intel_display_power_enabled_sw(struct drm_device *dev, bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain); enum intel_display_power_domain domain);
void intel_display_power_get(struct drm_device *dev, void intel_display_power_get(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain); enum intel_display_power_domain domain);
void intel_display_power_put(struct drm_device *dev, void intel_display_power_put(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain); enum intel_display_power_domain domain);
void intel_power_domains_init_hw(struct drm_device *dev); void intel_power_domains_init_hw(struct drm_i915_private *dev_priv);
void intel_set_power_well(struct drm_device *dev, bool enable);
void intel_enable_gt_powersave(struct drm_device *dev); void intel_enable_gt_powersave(struct drm_device *dev);
void intel_disable_gt_powersave(struct drm_device *dev); void intel_disable_gt_powersave(struct drm_device *dev);
void ironlake_teardown_rc6(struct drm_device *dev); void ironlake_teardown_rc6(struct drm_device *dev);
......
...@@ -243,11 +243,16 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, ...@@ -243,11 +243,16 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
enum pipe *pipe) enum pipe *pipe)
{ {
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
enum intel_display_power_domain power_domain;
u32 port, func; u32 port, func;
enum pipe p; enum pipe p;
DRM_DEBUG_KMS("\n"); DRM_DEBUG_KMS("\n");
power_domain = intel_display_port_power_domain(encoder);
if (!intel_display_power_enabled(dev_priv, power_domain))
return false;
/* XXX: this only works for one DSI output */ /* XXX: this only works for one DSI output */
for (p = PIPE_A; p <= PIPE_B; p++) { for (p = PIPE_A; p <= PIPE_B; p++) {
port = I915_READ(MIPI_PORT_CTRL(p)); port = I915_READ(MIPI_PORT_CTRL(p));
...@@ -488,8 +493,19 @@ static enum drm_connector_status ...@@ -488,8 +493,19 @@ static enum drm_connector_status
intel_dsi_detect(struct drm_connector *connector, bool force) intel_dsi_detect(struct drm_connector *connector, bool force)
{ {
struct intel_dsi *intel_dsi = intel_attached_dsi(connector); struct intel_dsi *intel_dsi = intel_attached_dsi(connector);
struct intel_encoder *intel_encoder = &intel_dsi->base;
enum intel_display_power_domain power_domain;
enum drm_connector_status connector_status;
struct drm_i915_private *dev_priv = intel_encoder->base.dev->dev_private;
DRM_DEBUG_KMS("\n"); DRM_DEBUG_KMS("\n");
return intel_dsi->dev.dev_ops->detect(&intel_dsi->dev); power_domain = intel_display_port_power_domain(intel_encoder);
intel_display_power_get(dev_priv, power_domain);
connector_status = intel_dsi->dev.dev_ops->detect(&intel_dsi->dev);
intel_display_power_put(dev_priv, power_domain);
return connector_status;
} }
static int intel_dsi_get_modes(struct drm_connector *connector) static int intel_dsi_get_modes(struct drm_connector *connector)
......
...@@ -289,7 +289,27 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, ...@@ -289,7 +289,27 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
struct drm_device *dev = fb_helper->dev; struct drm_device *dev = fb_helper->dev;
int i, j; int i, j;
bool *save_enabled; bool *save_enabled;
bool any_enabled = false; bool fallback = true;
int num_connectors_enabled = 0;
int num_connectors_detected = 0;
/*
* If the user specified any force options, just bail here
* and use that config.
*/
for (i = 0; i < fb_helper->connector_count; i++) {
struct drm_fb_helper_connector *fb_conn;
struct drm_connector *connector;
fb_conn = fb_helper->connector_info[i];
connector = fb_conn->connector;
if (!enabled[i])
continue;
if (connector->force != DRM_FORCE_UNSPECIFIED)
return false;
}
save_enabled = kcalloc(dev->mode_config.num_connector, sizeof(bool), save_enabled = kcalloc(dev->mode_config.num_connector, sizeof(bool),
GFP_KERNEL); GFP_KERNEL);
...@@ -306,6 +326,10 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, ...@@ -306,6 +326,10 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
fb_conn = fb_helper->connector_info[i]; fb_conn = fb_helper->connector_info[i];
connector = fb_conn->connector; connector = fb_conn->connector;
if (connector->status == connector_status_connected)
num_connectors_detected++;
if (!enabled[i]) { if (!enabled[i]) {
DRM_DEBUG_KMS("connector %d not enabled, skipping\n", DRM_DEBUG_KMS("connector %d not enabled, skipping\n",
connector->base.id); connector->base.id);
...@@ -320,6 +344,8 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, ...@@ -320,6 +344,8 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
continue; continue;
} }
num_connectors_enabled++;
new_crtc = intel_fb_helper_crtc(fb_helper, encoder->crtc); new_crtc = intel_fb_helper_crtc(fb_helper, encoder->crtc);
/* /*
...@@ -329,7 +355,8 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, ...@@ -329,7 +355,8 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
*/ */
for (j = 0; j < fb_helper->connector_count; j++) { for (j = 0; j < fb_helper->connector_count; j++) {
if (crtcs[j] == new_crtc) { if (crtcs[j] == new_crtc) {
any_enabled = false; DRM_DEBUG_KMS("fallback: cloned configuration\n");
fallback = true;
goto out; goto out;
} }
} }
...@@ -372,11 +399,25 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, ...@@ -372,11 +399,25 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
encoder->crtc->base.id, encoder->crtc->base.id,
modes[i]->name); modes[i]->name);
any_enabled = true; fallback = false;
}
/*
* If the BIOS didn't enable everything it could, fall back to have the
* same user experiencing of lighting up as much as possible like the
* fbdev helper library.
*/
if (num_connectors_enabled != num_connectors_detected &&
num_connectors_enabled < INTEL_INFO(dev)->num_pipes) {
DRM_DEBUG_KMS("fallback: Not all outputs enabled\n");
DRM_DEBUG_KMS("Enabled: %i, detected: %i\n", num_connectors_enabled,
num_connectors_detected);
fallback = true;
} }
out: out:
if (!any_enabled) { if (fallback) {
DRM_DEBUG_KMS("Not using firmware configuration\n");
memcpy(enabled, save_enabled, dev->mode_config.num_connector); memcpy(enabled, save_enabled, dev->mode_config.num_connector);
kfree(save_enabled); kfree(save_enabled);
return false; return false;
......
...@@ -667,8 +667,13 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, ...@@ -667,8 +667,13 @@ static bool intel_hdmi_get_hw_state(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);
enum intel_display_power_domain power_domain;
u32 tmp; u32 tmp;
power_domain = intel_display_port_power_domain(encoder);
if (!intel_display_power_enabled(dev_priv, power_domain))
return false;
tmp = I915_READ(intel_hdmi->hdmi_reg); tmp = I915_READ(intel_hdmi->hdmi_reg);
if (!(tmp & SDVO_ENABLE)) if (!(tmp & SDVO_ENABLE))
...@@ -909,11 +914,15 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) ...@@ -909,11 +914,15 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
struct intel_encoder *intel_encoder = &intel_dig_port->base; struct intel_encoder *intel_encoder = &intel_dig_port->base;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct edid *edid; struct edid *edid;
enum intel_display_power_domain power_domain;
enum drm_connector_status status = connector_status_disconnected; enum drm_connector_status status = connector_status_disconnected;
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
connector->base.id, drm_get_connector_name(connector)); connector->base.id, drm_get_connector_name(connector));
power_domain = intel_display_port_power_domain(intel_encoder);
intel_display_power_get(dev_priv, power_domain);
intel_hdmi->has_hdmi_sink = false; intel_hdmi->has_hdmi_sink = false;
intel_hdmi->has_audio = false; intel_hdmi->has_audio = false;
intel_hdmi->rgb_quant_range_selectable = false; intel_hdmi->rgb_quant_range_selectable = false;
...@@ -941,31 +950,48 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) ...@@ -941,31 +950,48 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
intel_encoder->type = INTEL_OUTPUT_HDMI; intel_encoder->type = INTEL_OUTPUT_HDMI;
} }
intel_display_power_put(dev_priv, power_domain);
return status; return status;
} }
static int intel_hdmi_get_modes(struct drm_connector *connector) static int intel_hdmi_get_modes(struct drm_connector *connector)
{ {
struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); struct intel_encoder *intel_encoder = intel_attached_encoder(connector);
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base);
struct drm_i915_private *dev_priv = connector->dev->dev_private; struct drm_i915_private *dev_priv = connector->dev->dev_private;
enum intel_display_power_domain power_domain;
int ret;
/* We should parse the EDID data and find out if it's an HDMI sink so /* We should parse the EDID data and find out if it's an HDMI sink so
* we can send audio to it. * we can send audio to it.
*/ */
return intel_ddc_get_modes(connector, power_domain = intel_display_port_power_domain(intel_encoder);
intel_display_power_get(dev_priv, power_domain);
ret = intel_ddc_get_modes(connector,
intel_gmbus_get_adapter(dev_priv, intel_gmbus_get_adapter(dev_priv,
intel_hdmi->ddc_bus)); intel_hdmi->ddc_bus));
intel_display_power_put(dev_priv, power_domain);
return ret;
} }
static bool static bool
intel_hdmi_detect_audio(struct drm_connector *connector) intel_hdmi_detect_audio(struct drm_connector *connector)
{ {
struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); struct intel_encoder *intel_encoder = intel_attached_encoder(connector);
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base);
struct drm_i915_private *dev_priv = connector->dev->dev_private; struct drm_i915_private *dev_priv = connector->dev->dev_private;
enum intel_display_power_domain power_domain;
struct edid *edid; struct edid *edid;
bool has_audio = false; bool has_audio = false;
power_domain = intel_display_port_power_domain(intel_encoder);
intel_display_power_get(dev_priv, power_domain);
edid = drm_get_edid(connector, edid = drm_get_edid(connector,
intel_gmbus_get_adapter(dev_priv, intel_gmbus_get_adapter(dev_priv,
intel_hdmi->ddc_bus)); intel_hdmi->ddc_bus));
...@@ -975,6 +1001,8 @@ intel_hdmi_detect_audio(struct drm_connector *connector) ...@@ -975,6 +1001,8 @@ intel_hdmi_detect_audio(struct drm_connector *connector)
kfree(edid); kfree(edid);
} }
intel_display_power_put(dev_priv, power_domain);
return has_audio; return has_audio;
} }
......
...@@ -1076,7 +1076,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, ...@@ -1076,7 +1076,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
if (new_bo->tiling_mode) { if (new_bo->tiling_mode) {
DRM_ERROR("buffer used for overlay image can not be tiled\n"); DRM_DEBUG_KMS("buffer used for overlay image can not be tiled\n");
ret = -EINVAL; ret = -EINVAL;
goto out_unlock; goto out_unlock;
} }
......
This diff is collapsed.
...@@ -571,7 +571,7 @@ static int init_render_ring(struct intel_ring_buffer *ring) ...@@ -571,7 +571,7 @@ static int init_render_ring(struct intel_ring_buffer *ring)
* to use MI_WAIT_FOR_EVENT within the CS. It should already be * to use MI_WAIT_FOR_EVENT within the CS. It should already be
* programmed to '1' on all products. * programmed to '1' on all products.
* *
* WaDisableAsyncFlipPerfMode:snb,ivb,hsw,vlv * WaDisableAsyncFlipPerfMode:snb,ivb,hsw,vlv,bdw
*/ */
if (INTEL_INFO(dev)->gen >= 6) if (INTEL_INFO(dev)->gen >= 6)
I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE)); I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE));
...@@ -1388,6 +1388,8 @@ static int intel_init_ring_buffer(struct drm_device *dev, ...@@ -1388,6 +1388,8 @@ static int intel_init_ring_buffer(struct drm_device *dev,
if (IS_I830(ring->dev) || IS_845G(ring->dev)) if (IS_I830(ring->dev) || IS_845G(ring->dev))
ring->effective_size -= 128; ring->effective_size -= 128;
i915_cmd_parser_init_ring(ring);
return 0; return 0;
err_unmap: err_unmap:
......
...@@ -164,6 +164,38 @@ struct intel_ring_buffer { ...@@ -164,6 +164,38 @@ struct intel_ring_buffer {
u32 gtt_offset; u32 gtt_offset;
volatile u32 *cpu_page; volatile u32 *cpu_page;
} scratch; } scratch;
/*
* Tables of commands the command parser needs to know about
* for this ring.
*/
const struct drm_i915_cmd_table *cmd_tables;
int cmd_table_count;
/*
* Table of registers allowed in commands that read/write registers.
*/
const u32 *reg_table;
int reg_count;
/*
* Table of registers allowed in commands that read/write registers, but
* only from the DRM master.
*/
const u32 *master_reg_table;
int master_reg_count;
/*
* Returns the bitmask for the length field of the specified command.
* Return 0 for an unrecognized/invalid command.
*
* If the command parser finds an entry for a command in the ring's
* cmd_tables, it gets the command's length based on the table entry.
* If not, it calls this function to determine the per-ring length field
* encoding for the command (i.e. certain opcode ranges use certain bits
* to encode the command length in the header).
*/
u32 (*get_cmd_length_mask)(u32 cmd_header);
}; };
static inline bool static inline bool
......
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