Commit d4070ff7 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-next-2015-09-11' of git://anongit.freedesktop.org/drm-intel into drm-next

- initialize backlight from VBT as fallback (Jani)
- hpd A support from Ville
- various atomic polish all over (mostly from Maarten)
- first parts of virtualize gpu guest support on bdw from
  Zhiyuan Lv
- GuC fixes from Alex
- polish for the chv clocks code (Ville)
- various things all over, as usual

* tag 'drm-intel-next-2015-09-11' of git://anongit.freedesktop.org/drm-intel: (145 commits)
  drm/i915: Update DRIVER_DATE to 20150911
  drm/i915: Remove one very outdated comment
  drm/i915: Use crtc->state for duplication.
  drm/i915: Do not handle a null plane state.
  drm/i915: Remove legacy plane updates for cursor and sprite planes.
  drm/i915: Use atomic state when changing cursor visibility.
  drm/i915: Use the atomic state in intel_update_primary_planes.
  drm/i915: Use the plane state in intel_crtc_info.
  drm/i915: Use atomic plane state in the primary plane update.
  drm/i915: add attached connector to hdmi container
  drm/i915: don't hard code vlv backlight frequency if unset
  drm/i915: initialize backlight max from VBT
  drm/i915: use pch backlight override on hsw too
  drm/i915/bxt: Clean up bxt_init_clock_gating
  drm/i915: Fix cmdparser STORE/LOAD command descriptors
  drm/i915: Dump pfit state as hex
  drm/i915: access the PP_ON_DELAYS/PP_OFF_DELAYS regs only pre GEN5
  drm/i915: access the PP_CONTROL reg only pre GEN5
  drm/i915: Refactor common ringbuffer allocation code
  drm/i915: use the yesno helper for logging
  ...
parents 2d4df13c fd1ee4cc
...@@ -4237,6 +4237,20 @@ int num_ioctls;</synopsis> ...@@ -4237,6 +4237,20 @@ int num_ioctls;</synopsis>
!Idrivers/gpu/drm/i915/i915_gem_shrinker.c !Idrivers/gpu/drm/i915/i915_gem_shrinker.c
</sect2> </sect2>
</sect1> </sect1>
<sect1>
<title>GuC-based Command Submission</title>
<sect2>
<title>GuC</title>
!Pdrivers/gpu/drm/i915/intel_guc_loader.c GuC-specific firmware loader
!Idrivers/gpu/drm/i915/intel_guc_loader.c
</sect2>
<sect2>
<title>GuC Client</title>
!Pdrivers/gpu/drm/i915/i915_guc_submission.c GuC-based command submissison
!Idrivers/gpu/drm/i915/i915_guc_submission.c
</sect2>
</sect1>
<sect1> <sect1>
<title> Tracing </title> <title> Tracing </title>
<para> <para>
......
...@@ -40,6 +40,10 @@ i915-y += i915_cmd_parser.o \ ...@@ -40,6 +40,10 @@ i915-y += i915_cmd_parser.o \
intel_ringbuffer.o \ intel_ringbuffer.o \
intel_uncore.o intel_uncore.o
# general-purpose microcontroller (GuC) support
i915-y += intel_guc_loader.o \
i915_guc_submission.o
# autogenerated null render state # autogenerated null render state
i915-y += intel_renderstate_gen6.o \ i915-y += intel_renderstate_gen6.o \
intel_renderstate_gen7.o \ intel_renderstate_gen7.o \
......
...@@ -94,7 +94,7 @@ ...@@ -94,7 +94,7 @@
#define CMD(op, opm, f, lm, fl, ...) \ #define CMD(op, opm, f, lm, fl, ...) \
{ \ { \
.flags = (fl) | ((f) ? CMD_DESC_FIXED : 0), \ .flags = (fl) | ((f) ? CMD_DESC_FIXED : 0), \
.cmd = { (op), (opm) }, \ .cmd = { (op), (opm) }, \
.length = { (lm) }, \ .length = { (lm) }, \
__VA_ARGS__ \ __VA_ARGS__ \
} }
...@@ -124,14 +124,14 @@ static const struct drm_i915_cmd_descriptor common_cmds[] = { ...@@ -124,14 +124,14 @@ static const struct drm_i915_cmd_descriptor common_cmds[] = {
CMD( MI_STORE_DWORD_INDEX, SMI, !F, 0xFF, R ), CMD( MI_STORE_DWORD_INDEX, SMI, !F, 0xFF, R ),
CMD( MI_LOAD_REGISTER_IMM(1), SMI, !F, 0xFF, W, CMD( MI_LOAD_REGISTER_IMM(1), SMI, !F, 0xFF, W,
.reg = { .offset = 1, .mask = 0x007FFFFC, .step = 2 } ), .reg = { .offset = 1, .mask = 0x007FFFFC, .step = 2 } ),
CMD( MI_STORE_REGISTER_MEM(1), SMI, !F, 0xFF, W | B, CMD( MI_STORE_REGISTER_MEM, SMI, F, 3, W | B,
.reg = { .offset = 1, .mask = 0x007FFFFC }, .reg = { .offset = 1, .mask = 0x007FFFFC },
.bits = {{ .bits = {{
.offset = 0, .offset = 0,
.mask = MI_GLOBAL_GTT, .mask = MI_GLOBAL_GTT,
.expected = 0, .expected = 0,
}}, ), }}, ),
CMD( MI_LOAD_REGISTER_MEM(1), SMI, !F, 0xFF, W | B, CMD( MI_LOAD_REGISTER_MEM, SMI, F, 3, W | B,
.reg = { .offset = 1, .mask = 0x007FFFFC }, .reg = { .offset = 1, .mask = 0x007FFFFC },
.bits = {{ .bits = {{
.offset = 0, .offset = 0,
...@@ -1021,7 +1021,7 @@ static bool check_cmd(const struct intel_engine_cs *ring, ...@@ -1021,7 +1021,7 @@ static bool check_cmd(const struct intel_engine_cs *ring,
* only MI_LOAD_REGISTER_IMM commands. * only MI_LOAD_REGISTER_IMM commands.
*/ */
if (reg_addr == OACONTROL) { if (reg_addr == OACONTROL) {
if (desc->cmd.value == MI_LOAD_REGISTER_MEM(1)) { if (desc->cmd.value == MI_LOAD_REGISTER_MEM) {
DRM_DEBUG_DRIVER("CMD: Rejected LRM to OACONTROL\n"); DRM_DEBUG_DRIVER("CMD: Rejected LRM to OACONTROL\n");
return false; return false;
} }
...@@ -1035,7 +1035,7 @@ static bool check_cmd(const struct intel_engine_cs *ring, ...@@ -1035,7 +1035,7 @@ static bool check_cmd(const struct intel_engine_cs *ring,
* allowed mask/value pair given in the whitelist entry. * allowed mask/value pair given in the whitelist entry.
*/ */
if (reg->mask) { if (reg->mask) {
if (desc->cmd.value == MI_LOAD_REGISTER_MEM(1)) { if (desc->cmd.value == MI_LOAD_REGISTER_MEM) {
DRM_DEBUG_DRIVER("CMD: Rejected LRM to masked register 0x%08X\n", DRM_DEBUG_DRIVER("CMD: Rejected LRM to masked register 0x%08X\n",
reg_addr); reg_addr);
return false; return false;
...@@ -1213,6 +1213,7 @@ int i915_cmd_parser_get_version(void) ...@@ -1213,6 +1213,7 @@ int i915_cmd_parser_get_version(void)
* 2. Allow access to the MI_PREDICATE_SRC0 and * 2. Allow access to the MI_PREDICATE_SRC0 and
* MI_PREDICATE_SRC1 registers. * MI_PREDICATE_SRC1 registers.
* 3. Allow access to the GPGPU_THREADS_DISPATCHED register. * 3. Allow access to the GPGPU_THREADS_DISPATCHED register.
* 4. L3 atomic chicken bits of HSW_SCRATCH1 and HSW_ROW_CHICKEN3.
*/ */
return 3; return 4;
} }
This diff is collapsed.
...@@ -364,12 +364,12 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_ ...@@ -364,12 +364,12 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
/* i915 resume handler doesn't set to D0 */ /* i915 resume handler doesn't set to D0 */
pci_set_power_state(dev->pdev, PCI_D0); pci_set_power_state(dev->pdev, PCI_D0);
i915_resume_legacy(dev); i915_resume_switcheroo(dev);
dev->switch_power_state = DRM_SWITCH_POWER_ON; dev->switch_power_state = DRM_SWITCH_POWER_ON;
} else { } else {
pr_err("switched off\n"); pr_err("switched off\n");
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
i915_suspend_legacy(dev, pmm); i915_suspend_switcheroo(dev, pmm);
dev->switch_power_state = DRM_SWITCH_POWER_OFF; dev->switch_power_state = DRM_SWITCH_POWER_OFF;
} }
} }
...@@ -435,6 +435,11 @@ static int i915_load_modeset_init(struct drm_device *dev) ...@@ -435,6 +435,11 @@ static int i915_load_modeset_init(struct drm_device *dev)
* 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);
/* intel_guc_ucode_init() needs the mutex to allocate GEM objects */
mutex_lock(&dev->struct_mutex);
intel_guc_ucode_init(dev);
mutex_unlock(&dev->struct_mutex);
ret = i915_gem_init(dev); ret = i915_gem_init(dev);
if (ret) if (ret)
goto cleanup_irq; goto cleanup_irq;
...@@ -476,6 +481,9 @@ static int i915_load_modeset_init(struct drm_device *dev) ...@@ -476,6 +481,9 @@ static int i915_load_modeset_init(struct drm_device *dev)
i915_gem_context_fini(dev); i915_gem_context_fini(dev);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
cleanup_irq: cleanup_irq:
mutex_lock(&dev->struct_mutex);
intel_guc_ucode_fini(dev);
mutex_unlock(&dev->struct_mutex);
drm_irq_uninstall(dev); drm_irq_uninstall(dev);
cleanup_gem_stolen: cleanup_gem_stolen:
i915_gem_cleanup_stolen(dev); i915_gem_cleanup_stolen(dev);
...@@ -791,6 +799,24 @@ static void intel_device_info_runtime_init(struct drm_device *dev) ...@@ -791,6 +799,24 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
info->has_eu_pg ? "y" : "n"); info->has_eu_pg ? "y" : "n");
} }
static void intel_init_dpio(struct drm_i915_private *dev_priv)
{
if (!IS_VALLEYVIEW(dev_priv))
return;
/*
* IOSF_PORT_DPIO is used for VLV x2 PHY (DP/HDMI B and C),
* CHV x1 PHY (DP/HDMI D)
* IOSF_PORT_DPIO_2 is used for CHV x2 PHY (DP/HDMI B and C)
*/
if (IS_CHERRYVIEW(dev_priv)) {
DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO_2;
DPIO_PHY_IOSF_PORT(DPIO_PHY1) = IOSF_PORT_DPIO;
} else {
DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO;
}
}
/** /**
* i915_driver_load - setup chip and create an initial config * i915_driver_load - setup chip and create an initial config
* @dev: DRM device * @dev: DRM device
...@@ -971,8 +997,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ...@@ -971,8 +997,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
intel_setup_gmbus(dev); intel_setup_gmbus(dev);
intel_opregion_setup(dev); intel_opregion_setup(dev);
intel_setup_bios(dev);
i915_gem_load(dev); i915_gem_load(dev);
/* On the 945G/GM, the chipset reports the MSI capability on the /* On the 945G/GM, the chipset reports the MSI capability on the
...@@ -991,6 +1015,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ...@@ -991,6 +1015,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
intel_device_info_runtime_init(dev); intel_device_info_runtime_init(dev);
intel_init_dpio(dev_priv);
if (INTEL_INFO(dev)->num_pipes) { if (INTEL_INFO(dev)->num_pipes) {
ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes); ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes);
if (ret) if (ret)
...@@ -1128,6 +1154,7 @@ int i915_driver_unload(struct drm_device *dev) ...@@ -1128,6 +1154,7 @@ int i915_driver_unload(struct drm_device *dev)
flush_workqueue(dev_priv->wq); flush_workqueue(dev_priv->wq);
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
intel_guc_ucode_fini(dev);
i915_gem_cleanup_ringbuffer(dev); i915_gem_cleanup_ringbuffer(dev);
i915_gem_context_fini(dev); i915_gem_context_fini(dev);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
......
...@@ -362,6 +362,7 @@ static const struct intel_device_info intel_skylake_info = { ...@@ -362,6 +362,7 @@ static const struct intel_device_info intel_skylake_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_fpga_dbg = 1,
.has_fbc = 1, .has_fbc = 1,
GEN_DEFAULT_PIPEOFFSETS, GEN_DEFAULT_PIPEOFFSETS,
IVB_CURSOR_OFFSETS, IVB_CURSOR_OFFSETS,
...@@ -374,6 +375,7 @@ static const struct intel_device_info intel_skylake_gt3_info = { ...@@ -374,6 +375,7 @@ static const struct intel_device_info intel_skylake_gt3_info = {
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
.has_llc = 1, .has_llc = 1,
.has_ddi = 1, .has_ddi = 1,
.has_fpga_dbg = 1,
.has_fbc = 1, .has_fbc = 1,
GEN_DEFAULT_PIPEOFFSETS, GEN_DEFAULT_PIPEOFFSETS,
IVB_CURSOR_OFFSETS, IVB_CURSOR_OFFSETS,
...@@ -386,6 +388,7 @@ static const struct intel_device_info intel_broxton_info = { ...@@ -386,6 +388,7 @@ static const struct intel_device_info intel_broxton_info = {
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
.num_pipes = 3, .num_pipes = 3,
.has_ddi = 1, .has_ddi = 1,
.has_fpga_dbg = 1,
.has_fbc = 1, .has_fbc = 1,
GEN_DEFAULT_PIPEOFFSETS, GEN_DEFAULT_PIPEOFFSETS,
IVB_CURSOR_OFFSETS, IVB_CURSOR_OFFSETS,
...@@ -679,7 +682,7 @@ static int i915_drm_suspend_late(struct drm_device *drm_dev, bool hibernation) ...@@ -679,7 +682,7 @@ static int i915_drm_suspend_late(struct drm_device *drm_dev, bool hibernation)
return 0; return 0;
} }
int i915_suspend_legacy(struct drm_device *dev, pm_message_t state) int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state)
{ {
int error; int error;
...@@ -812,7 +815,7 @@ static int i915_drm_resume_early(struct drm_device *dev) ...@@ -812,7 +815,7 @@ static int i915_drm_resume_early(struct drm_device *dev)
return ret; return ret;
} }
int i915_resume_legacy(struct drm_device *dev) int i915_resume_switcheroo(struct drm_device *dev)
{ {
int ret; int ret;
...@@ -1552,6 +1555,15 @@ static int intel_runtime_resume(struct device *device) ...@@ -1552,6 +1555,15 @@ static int intel_runtime_resume(struct device *device)
gen6_update_ring_freq(dev); gen6_update_ring_freq(dev);
intel_runtime_pm_enable_interrupts(dev_priv); intel_runtime_pm_enable_interrupts(dev_priv);
/*
* On VLV/CHV display interrupts are part of the display
* power well, so hpd is reinitialized from there. For
* everyone else do it here.
*/
if (!IS_VALLEYVIEW(dev_priv))
intel_hpd_init(dev_priv);
intel_enable_gt_powersave(dev); intel_enable_gt_powersave(dev);
if (ret) if (ret)
...@@ -1649,7 +1661,7 @@ static struct drm_driver driver = { ...@@ -1649,7 +1661,7 @@ static struct drm_driver driver = {
*/ */
.driver_features = .driver_features =
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME |
DRIVER_RENDER, DRIVER_RENDER | DRIVER_MODESET,
.load = i915_driver_load, .load = i915_driver_load,
.unload = i915_driver_unload, .unload = i915_driver_unload,
.open = i915_driver_open, .open = i915_driver_open,
...@@ -1658,10 +1670,6 @@ static struct drm_driver driver = { ...@@ -1658,10 +1670,6 @@ static struct drm_driver driver = {
.postclose = i915_driver_postclose, .postclose = i915_driver_postclose,
.set_busid = drm_pci_set_busid, .set_busid = drm_pci_set_busid,
/* Used in place of i915_pm_ops for non-DRIVER_MODESET */
.suspend = i915_suspend_legacy,
.resume = i915_resume_legacy,
#if defined(CONFIG_DEBUG_FS) #if defined(CONFIG_DEBUG_FS)
.debugfs_init = i915_debugfs_init, .debugfs_init = i915_debugfs_init,
.debugfs_cleanup = i915_debugfs_cleanup, .debugfs_cleanup = i915_debugfs_cleanup,
...@@ -1704,7 +1712,6 @@ static int __init i915_init(void) ...@@ -1704,7 +1712,6 @@ static int __init i915_init(void)
* either the i915.modeset prarameter or by the * either the i915.modeset prarameter or by the
* vga_text_mode_force boot option. * vga_text_mode_force boot option.
*/ */
driver.driver_features |= DRIVER_MODESET;
if (i915.modeset == 0) if (i915.modeset == 0)
driver.driver_features &= ~DRIVER_MODESET; driver.driver_features &= ~DRIVER_MODESET;
...@@ -1715,18 +1722,12 @@ static int __init i915_init(void) ...@@ -1715,18 +1722,12 @@ static int __init i915_init(void)
#endif #endif
if (!(driver.driver_features & DRIVER_MODESET)) { if (!(driver.driver_features & DRIVER_MODESET)) {
driver.get_vblank_timestamp = NULL;
/* Silently fail loading to not upset userspace. */ /* Silently fail loading to not upset userspace. */
DRM_DEBUG_DRIVER("KMS and UMS disabled.\n"); DRM_DEBUG_DRIVER("KMS and UMS disabled.\n");
return 0; return 0;
} }
/* if (i915.nuclear_pageflip)
* FIXME: Note that we're lying to the DRM core here so that we can get access
* to the atomic ioctl and the atomic properties. Only plane operations on
* a single CRTC will actually work.
*/
if (driver.driver_features & DRIVER_MODESET)
driver.driver_features |= DRIVER_ATOMIC; driver.driver_features |= DRIVER_ATOMIC;
return drm_pci_init(&driver, &i915_pci_driver); return drm_pci_init(&driver, &i915_pci_driver);
......
...@@ -50,13 +50,14 @@ ...@@ -50,13 +50,14 @@
#include <linux/intel-iommu.h> #include <linux/intel-iommu.h>
#include <linux/kref.h> #include <linux/kref.h>
#include <linux/pm_qos.h> #include <linux/pm_qos.h>
#include "intel_guc.h"
/* General customization: /* General customization:
*/ */
#define DRIVER_NAME "i915" #define DRIVER_NAME "i915"
#define DRIVER_DESC "Intel Graphics" #define DRIVER_DESC "Intel Graphics"
#define DRIVER_DATE "20150731" #define DRIVER_DATE "20150911"
#undef WARN_ON #undef WARN_ON
/* Many gcc seem to no see through this and fall over :( */ /* Many gcc seem to no see through this and fall over :( */
...@@ -67,11 +68,11 @@ ...@@ -67,11 +68,11 @@
BUILD_BUG_ON(__i915_warn_cond); \ BUILD_BUG_ON(__i915_warn_cond); \
WARN(__i915_warn_cond, "WARN_ON(" #x ")"); }) WARN(__i915_warn_cond, "WARN_ON(" #x ")"); })
#else #else
#define WARN_ON(x) WARN((x), "WARN_ON(" #x ")") #define WARN_ON(x) WARN((x), "WARN_ON(%s)", #x )
#endif #endif
#undef WARN_ON_ONCE #undef WARN_ON_ONCE
#define WARN_ON_ONCE(x) WARN_ONCE((x), "WARN_ON_ONCE(" #x ")") #define WARN_ON_ONCE(x) WARN_ONCE((x), "WARN_ON_ONCE(%s)", #x )
#define MISSING_CASE(x) WARN(1, "Missing switch case (%lu) in %s\n", \ #define MISSING_CASE(x) WARN(1, "Missing switch case (%lu) in %s\n", \
(long) (x), __func__); (long) (x), __func__);
...@@ -105,6 +106,11 @@ ...@@ -105,6 +106,11 @@
unlikely(__ret_warn_on); \ unlikely(__ret_warn_on); \
}) })
static inline const char *yesno(bool v)
{
return v ? "yes" : "no";
}
enum pipe { enum pipe {
INVALID_PIPE = -1, INVALID_PIPE = -1,
PIPE_A = 0, PIPE_A = 0,
...@@ -549,7 +555,7 @@ struct drm_i915_error_state { ...@@ -549,7 +555,7 @@ struct drm_i915_error_state {
struct drm_i915_error_object { struct drm_i915_error_object {
int page_count; int page_count;
u32 gtt_offset; u64 gtt_offset;
u32 *pages[0]; u32 *pages[0];
} *ringbuffer, *batchbuffer, *wa_batchbuffer, *ctx, *hws_page; } *ringbuffer, *batchbuffer, *wa_batchbuffer, *ctx, *hws_page;
...@@ -575,7 +581,7 @@ struct drm_i915_error_state { ...@@ -575,7 +581,7 @@ struct drm_i915_error_state {
u32 size; u32 size;
u32 name; u32 name;
u32 rseqno[I915_NUM_RINGS], wseqno; u32 rseqno[I915_NUM_RINGS], wseqno;
u32 gtt_offset; u64 gtt_offset;
u32 read_domains; u32 read_domains;
u32 write_domain; u32 write_domain;
s32 fence_reg:I915_MAX_NUM_FENCE_BITS; s32 fence_reg:I915_MAX_NUM_FENCE_BITS;
...@@ -665,6 +671,8 @@ struct drm_i915_display_funcs { ...@@ -665,6 +671,8 @@ struct drm_i915_display_funcs {
uint32_t level); uint32_t level);
void (*disable_backlight)(struct intel_connector *connector); void (*disable_backlight)(struct intel_connector *connector);
void (*enable_backlight)(struct intel_connector *connector); void (*enable_backlight)(struct intel_connector *connector);
uint32_t (*backlight_hz_to_pwm)(struct intel_connector *connector,
uint32_t hz);
}; };
enum forcewake_domain_id { enum forcewake_domain_id {
...@@ -1693,7 +1701,7 @@ struct i915_execbuffer_params { ...@@ -1693,7 +1701,7 @@ struct i915_execbuffer_params {
struct drm_file *file; struct drm_file *file;
uint32_t dispatch_flags; uint32_t dispatch_flags;
uint32_t args_batch_start_offset; uint32_t args_batch_start_offset;
uint32_t batch_obj_vm_offset; uint64_t batch_obj_vm_offset;
struct intel_engine_cs *ring; struct intel_engine_cs *ring;
struct drm_i915_gem_object *batch_obj; struct drm_i915_gem_object *batch_obj;
struct intel_context *ctx; struct intel_context *ctx;
...@@ -1716,6 +1724,8 @@ struct drm_i915_private { ...@@ -1716,6 +1724,8 @@ struct drm_i915_private {
struct i915_virtual_gpu vgpu; struct i915_virtual_gpu vgpu;
struct intel_guc guc;
struct intel_csr csr; struct intel_csr csr;
/* Display CSR-related protection */ /* Display CSR-related protection */
...@@ -1796,6 +1806,7 @@ struct drm_i915_private { ...@@ -1796,6 +1806,7 @@ struct drm_i915_private {
unsigned int fsb_freq, mem_freq, is_ddr3; unsigned int fsb_freq, mem_freq, is_ddr3;
unsigned int skl_boot_cdclk; unsigned int skl_boot_cdclk;
unsigned int cdclk_freq, max_cdclk_freq; unsigned int cdclk_freq, max_cdclk_freq;
unsigned int max_dotclk_freq;
unsigned int hpll_freq; unsigned int hpll_freq;
/** /**
...@@ -1963,6 +1974,11 @@ static inline struct drm_i915_private *dev_to_i915(struct device *dev) ...@@ -1963,6 +1974,11 @@ static inline struct drm_i915_private *dev_to_i915(struct device *dev)
return to_i915(dev_get_drvdata(dev)); return to_i915(dev_get_drvdata(dev));
} }
static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc)
{
return container_of(guc, struct drm_i915_private, guc);
}
/* Iterate over initialised rings */ /* Iterate over initialised rings */
#define for_each_ring(ring__, dev_priv__, i__) \ #define for_each_ring(ring__, dev_priv__, i__) \
for ((i__) = 0; (i__) < I915_NUM_RINGS; (i__)++) \ for ((i__) = 0; (i__) < I915_NUM_RINGS; (i__)++) \
...@@ -2520,7 +2536,8 @@ struct drm_i915_cmd_table { ...@@ -2520,7 +2536,8 @@ struct drm_i915_cmd_table {
#define HAS_HW_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 6) #define HAS_HW_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 6)
#define HAS_LOGICAL_RING_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 8) #define HAS_LOGICAL_RING_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 8)
#define USES_PPGTT(dev) (i915.enable_ppgtt) #define USES_PPGTT(dev) (i915.enable_ppgtt)
#define USES_FULL_PPGTT(dev) (i915.enable_ppgtt == 2) #define USES_FULL_PPGTT(dev) (i915.enable_ppgtt >= 2)
#define USES_FULL_48BIT_PPGTT(dev) (i915.enable_ppgtt == 3)
#define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay)
#define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) #define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical)
...@@ -2566,6 +2583,9 @@ struct drm_i915_cmd_table { ...@@ -2566,6 +2583,9 @@ struct drm_i915_cmd_table {
#define HAS_CSR(dev) (IS_SKYLAKE(dev)) #define HAS_CSR(dev) (IS_SKYLAKE(dev))
#define HAS_GUC_UCODE(dev) (IS_GEN9(dev))
#define HAS_GUC_SCHED(dev) (IS_GEN9(dev))
#define HAS_RESOURCE_STREAMER(dev) (IS_HASWELL(dev) || \ #define HAS_RESOURCE_STREAMER(dev) (IS_HASWELL(dev) || \
INTEL_INFO(dev)->gen >= 8) INTEL_INFO(dev)->gen >= 8)
...@@ -2584,6 +2604,7 @@ struct drm_i915_cmd_table { ...@@ -2584,6 +2604,7 @@ struct drm_i915_cmd_table {
#define INTEL_PCH_TYPE(dev) (__I915__(dev)->pch_type) #define INTEL_PCH_TYPE(dev) (__I915__(dev)->pch_type)
#define HAS_PCH_SPT(dev) (INTEL_PCH_TYPE(dev) == PCH_SPT) #define HAS_PCH_SPT(dev) (INTEL_PCH_TYPE(dev) == PCH_SPT)
#define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT) #define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT)
#define HAS_PCH_LPT_LP(dev) (__I915__(dev)->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE)
#define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
#define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX)
#define HAS_PCH_NOP(dev) (INTEL_PCH_TYPE(dev) == PCH_NOP) #define HAS_PCH_NOP(dev) (INTEL_PCH_TYPE(dev) == PCH_NOP)
...@@ -2603,8 +2624,8 @@ struct drm_i915_cmd_table { ...@@ -2603,8 +2624,8 @@ struct drm_i915_cmd_table {
extern const struct drm_ioctl_desc i915_ioctls[]; extern const struct drm_ioctl_desc i915_ioctls[];
extern int i915_max_ioctl; extern int i915_max_ioctl;
extern int i915_suspend_legacy(struct drm_device *dev, pm_message_t state); extern int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state);
extern int i915_resume_legacy(struct drm_device *dev); extern int i915_resume_switcheroo(struct drm_device *dev);
/* i915_params.c */ /* i915_params.c */
struct i915_params { struct i915_params {
...@@ -2637,6 +2658,7 @@ struct i915_params { ...@@ -2637,6 +2658,7 @@ struct i915_params {
int use_mmio_flip; int use_mmio_flip;
int mmio_debug; int mmio_debug;
bool verbose_state_checks; bool verbose_state_checks;
bool nuclear_pageflip;
int edp_vswing; int edp_vswing;
}; };
extern struct i915_params i915 __read_mostly; extern struct i915_params i915 __read_mostly;
...@@ -2986,13 +3008,11 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev, ...@@ -2986,13 +3008,11 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
struct dma_buf *i915_gem_prime_export(struct drm_device *dev, struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *gem_obj, int flags); struct drm_gem_object *gem_obj, int flags);
unsigned long u64 i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o, const struct i915_ggtt_view *view);
const struct i915_ggtt_view *view); u64 i915_gem_obj_offset(struct drm_i915_gem_object *o,
unsigned long struct i915_address_space *vm);
i915_gem_obj_offset(struct drm_i915_gem_object *o, static inline u64
struct i915_address_space *vm);
static inline unsigned long
i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *o) i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *o)
{ {
return i915_gem_obj_ggtt_offset_view(o, &i915_ggtt_view_normal); return i915_gem_obj_ggtt_offset_view(o, &i915_ggtt_view_normal);
......
...@@ -1005,12 +1005,14 @@ i915_gem_shmem_pwrite(struct drm_device *dev, ...@@ -1005,12 +1005,14 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
if (!needs_clflush_after && if (!needs_clflush_after &&
obj->base.write_domain != I915_GEM_DOMAIN_CPU) { obj->base.write_domain != I915_GEM_DOMAIN_CPU) {
if (i915_gem_clflush_object(obj, obj->pin_display)) if (i915_gem_clflush_object(obj, obj->pin_display))
i915_gem_chipset_flush(dev); needs_clflush_after = true;
} }
} }
if (needs_clflush_after) if (needs_clflush_after)
i915_gem_chipset_flush(dev); i915_gem_chipset_flush(dev);
else
obj->cache_dirty = true;
intel_fb_obj_flush(obj, false, ORIGIN_CPU); intel_fb_obj_flush(obj, false, ORIGIN_CPU);
return ret; return ret;
...@@ -3228,10 +3230,6 @@ int i915_vma_unbind(struct i915_vma *vma) ...@@ -3228,10 +3230,6 @@ int i915_vma_unbind(struct i915_vma *vma)
ret = i915_gem_object_wait_rendering(obj, false); ret = i915_gem_object_wait_rendering(obj, false);
if (ret) if (ret)
return ret; return ret;
/* Continue on if we fail due to EIO, the GPU is hung so we
* should be safe and we need to cleanup or else we might
* cause memory corruption through use-after-free.
*/
if (i915_is_ggtt(vma->vm) && if (i915_is_ggtt(vma->vm) &&
vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) { vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
...@@ -3355,7 +3353,8 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, ...@@ -3355,7 +3353,8 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
{ {
struct drm_device *dev = obj->base.dev; struct drm_device *dev = obj->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 size, fence_size, fence_alignment, unfenced_alignment; u32 fence_alignment, unfenced_alignment;
u64 size, fence_size;
u64 start = u64 start =
flags & PIN_OFFSET_BIAS ? flags & PIN_OFFSET_MASK : 0; flags & PIN_OFFSET_BIAS ? flags & PIN_OFFSET_MASK : 0;
u64 end = u64 end =
...@@ -3414,7 +3413,7 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, ...@@ -3414,7 +3413,7 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
* attempt to find space. * attempt to find space.
*/ */
if (size > end) { if (size > end) {
DRM_DEBUG("Attempting to bind an object (view type=%u) larger than the aperture: size=%u > %s aperture=%llu\n", DRM_DEBUG("Attempting to bind an object (view type=%u) larger than the aperture: size=%llu > %s aperture=%llu\n",
ggtt_view ? ggtt_view->type : 0, ggtt_view ? ggtt_view->type : 0,
size, size,
flags & PIN_MAPPABLE ? "mappable" : "total", flags & PIN_MAPPABLE ? "mappable" : "total",
...@@ -3638,10 +3637,10 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, ...@@ -3638,10 +3637,10 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
{ {
struct drm_device *dev = obj->base.dev; struct drm_device *dev = obj->base.dev;
struct i915_vma *vma, *next; struct i915_vma *vma, *next;
int ret; int ret = 0;
if (obj->cache_level == cache_level) if (obj->cache_level == cache_level)
return 0; goto out;
if (i915_gem_obj_is_pinned(obj)) { if (i915_gem_obj_is_pinned(obj)) {
DRM_DEBUG("can not change the cache level of pinned objects\n"); DRM_DEBUG("can not change the cache level of pinned objects\n");
...@@ -3686,6 +3685,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, ...@@ -3686,6 +3685,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
vma->node.color = cache_level; vma->node.color = cache_level;
obj->cache_level = cache_level; obj->cache_level = cache_level;
out:
if (obj->cache_dirty && if (obj->cache_dirty &&
obj->base.write_domain != I915_GEM_DOMAIN_CPU && obj->base.write_domain != I915_GEM_DOMAIN_CPU &&
cpu_write_needs_clflush(obj)) { cpu_write_needs_clflush(obj)) {
...@@ -3738,6 +3738,15 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data, ...@@ -3738,6 +3738,15 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
level = I915_CACHE_NONE; level = I915_CACHE_NONE;
break; break;
case I915_CACHING_CACHED: case I915_CACHING_CACHED:
/*
* Due to a HW issue on BXT A stepping, GPU stores via a
* snooped mapping may leave stale data in a corresponding CPU
* cacheline, whereas normally such cachelines would get
* invalidated.
*/
if (IS_BROXTON(dev) && INTEL_REVID(dev) < BXT_REVID_B0)
return -ENODEV;
level = I915_CACHE_LLC; level = I915_CACHE_LLC;
break; break;
case I915_CACHING_DISPLAY: case I915_CACHING_DISPLAY:
...@@ -4011,15 +4020,13 @@ i915_gem_object_do_pin(struct drm_i915_gem_object *obj, ...@@ -4011,15 +4020,13 @@ i915_gem_object_do_pin(struct drm_i915_gem_object *obj,
return -EBUSY; return -EBUSY;
if (i915_vma_misplaced(vma, alignment, flags)) { if (i915_vma_misplaced(vma, alignment, flags)) {
unsigned long offset;
offset = ggtt_view ? i915_gem_obj_ggtt_offset_view(obj, ggtt_view) :
i915_gem_obj_offset(obj, vm);
WARN(vma->pin_count, WARN(vma->pin_count,
"bo is already pinned in %s with incorrect alignment:" "bo is already pinned in %s with incorrect alignment:"
" offset=%lx, req.alignment=%x, req.map_and_fenceable=%d," " offset=%08x %08x, req.alignment=%x, req.map_and_fenceable=%d,"
" obj->map_and_fenceable=%d\n", " obj->map_and_fenceable=%d\n",
ggtt_view ? "ggtt" : "ppgtt", ggtt_view ? "ggtt" : "ppgtt",
offset, upper_32_bits(vma->node.start),
lower_32_bits(vma->node.start),
alignment, alignment,
!!(flags & PIN_MAPPABLE), !!(flags & PIN_MAPPABLE),
obj->map_and_fenceable); obj->map_and_fenceable);
...@@ -4679,6 +4686,22 @@ i915_gem_init_hw(struct drm_device *dev) ...@@ -4679,6 +4686,22 @@ i915_gem_init_hw(struct drm_device *dev)
goto out; goto out;
} }
/* We can't enable contexts until all firmware is loaded */
ret = intel_guc_ucode_load(dev);
if (ret) {
/*
* If we got an error and GuC submission is enabled, map
* the error to -EIO so the GPU will be declared wedged.
* OTOH, if we didn't intend to use the GuC anyway, just
* discard the error and carry on.
*/
DRM_ERROR("Failed to initialize GuC, error %d%s\n", ret,
i915.enable_guc_submission ? "" : " (ignored)");
ret = i915.enable_guc_submission ? -EIO : 0;
if (ret)
goto out;
}
/* Now it is safe to go back round and do everything else: */ /* Now it is safe to go back round and do everything else: */
for_each_ring(ring, dev_priv, i) { for_each_ring(ring, dev_priv, i) {
struct drm_i915_gem_request *req; struct drm_i915_gem_request *req;
...@@ -4974,9 +4997,8 @@ void i915_gem_track_fb(struct drm_i915_gem_object *old, ...@@ -4974,9 +4997,8 @@ void i915_gem_track_fb(struct drm_i915_gem_object *old,
} }
/* All the new VM stuff */ /* All the new VM stuff */
unsigned long u64 i915_gem_obj_offset(struct drm_i915_gem_object *o,
i915_gem_obj_offset(struct drm_i915_gem_object *o, struct i915_address_space *vm)
struct i915_address_space *vm)
{ {
struct drm_i915_private *dev_priv = o->base.dev->dev_private; struct drm_i915_private *dev_priv = o->base.dev->dev_private;
struct i915_vma *vma; struct i915_vma *vma;
...@@ -4996,9 +5018,8 @@ i915_gem_obj_offset(struct drm_i915_gem_object *o, ...@@ -4996,9 +5018,8 @@ i915_gem_obj_offset(struct drm_i915_gem_object *o,
return -1; return -1;
} }
unsigned long u64 i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o, const struct i915_ggtt_view *view)
const struct i915_ggtt_view *view)
{ {
struct i915_address_space *ggtt = i915_obj_to_ggtt(o); struct i915_address_space *ggtt = i915_obj_to_ggtt(o);
struct i915_vma *vma; struct i915_vma *vma;
......
...@@ -332,6 +332,13 @@ int i915_gem_context_init(struct drm_device *dev) ...@@ -332,6 +332,13 @@ int i915_gem_context_init(struct drm_device *dev)
if (WARN_ON(dev_priv->ring[RCS].default_context)) if (WARN_ON(dev_priv->ring[RCS].default_context))
return 0; return 0;
if (intel_vgpu_active(dev) && HAS_LOGICAL_RING_CONTEXTS(dev)) {
if (!i915.enable_execlists) {
DRM_INFO("Only EXECLIST mode is supported in vgpu.\n");
return -EINVAL;
}
}
if (i915.enable_execlists) { if (i915.enable_execlists) {
/* NB: intentionally left blank. We will allocate our own /* NB: intentionally left blank. We will allocate our own
* backing objects as we need them, thank you very much */ * backing objects as we need them, thank you very much */
......
...@@ -128,7 +128,7 @@ static void i915_write_fence_reg(struct drm_device *dev, int reg, ...@@ -128,7 +128,7 @@ static void i915_write_fence_reg(struct drm_device *dev, int reg,
WARN((i915_gem_obj_ggtt_offset(obj) & ~I915_FENCE_START_MASK) || WARN((i915_gem_obj_ggtt_offset(obj) & ~I915_FENCE_START_MASK) ||
(size & -size) != size || (size & -size) != size ||
(i915_gem_obj_ggtt_offset(obj) & (size - 1)), (i915_gem_obj_ggtt_offset(obj) & (size - 1)),
"object 0x%08lx [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n", "object 0x%08llx [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n",
i915_gem_obj_ggtt_offset(obj), obj->map_and_fenceable, size); i915_gem_obj_ggtt_offset(obj), obj->map_and_fenceable, size);
if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))
...@@ -171,7 +171,7 @@ static void i830_write_fence_reg(struct drm_device *dev, int reg, ...@@ -171,7 +171,7 @@ static void i830_write_fence_reg(struct drm_device *dev, int reg,
WARN((i915_gem_obj_ggtt_offset(obj) & ~I830_FENCE_START_MASK) || WARN((i915_gem_obj_ggtt_offset(obj) & ~I830_FENCE_START_MASK) ||
(size & -size) != size || (size & -size) != size ||
(i915_gem_obj_ggtt_offset(obj) & (size - 1)), (i915_gem_obj_ggtt_offset(obj) & (size - 1)),
"object 0x%08lx not 512K or pot-size 0x%08x aligned\n", "object 0x%08llx not 512K or pot-size 0x%08x aligned\n",
i915_gem_obj_ggtt_offset(obj), size); i915_gem_obj_ggtt_offset(obj), size);
pitch_val = obj->stride / 128; pitch_val = obj->stride / 128;
......
This diff is collapsed.
...@@ -39,6 +39,8 @@ struct drm_i915_file_private; ...@@ -39,6 +39,8 @@ struct drm_i915_file_private;
typedef uint32_t gen6_pte_t; typedef uint32_t gen6_pte_t;
typedef uint64_t gen8_pte_t; typedef uint64_t gen8_pte_t;
typedef uint64_t gen8_pde_t; typedef uint64_t gen8_pde_t;
typedef uint64_t gen8_ppgtt_pdpe_t;
typedef uint64_t gen8_ppgtt_pml4e_t;
#define gtt_total_entries(gtt) ((gtt).base.total >> PAGE_SHIFT) #define gtt_total_entries(gtt) ((gtt).base.total >> PAGE_SHIFT)
...@@ -88,9 +90,18 @@ typedef uint64_t gen8_pde_t; ...@@ -88,9 +90,18 @@ typedef uint64_t gen8_pde_t;
* PDPE | PDE | PTE | offset * PDPE | PDE | PTE | offset
* The difference as compared to normal x86 3 level page table is the PDPEs are * The difference as compared to normal x86 3 level page table is the PDPEs are
* programmed via register. * programmed via register.
*
* GEN8 48b legacy style address is defined as a 4 level page table:
* 47:39 | 38:30 | 29:21 | 20:12 | 11:0
* PML4E | PDPE | PDE | PTE | offset
*/ */
#define GEN8_PML4ES_PER_PML4 512
#define GEN8_PML4E_SHIFT 39
#define GEN8_PML4E_MASK (GEN8_PML4ES_PER_PML4 - 1)
#define GEN8_PDPE_SHIFT 30 #define GEN8_PDPE_SHIFT 30
#define GEN8_PDPE_MASK 0x3 /* NB: GEN8_PDPE_MASK is untrue for 32b platforms, but it has no impact on 32b page
* tables */
#define GEN8_PDPE_MASK 0x1ff
#define GEN8_PDE_SHIFT 21 #define GEN8_PDE_SHIFT 21
#define GEN8_PDE_MASK 0x1ff #define GEN8_PDE_MASK 0x1ff
#define GEN8_PTE_SHIFT 12 #define GEN8_PTE_SHIFT 12
...@@ -98,6 +109,9 @@ typedef uint64_t gen8_pde_t; ...@@ -98,6 +109,9 @@ typedef uint64_t gen8_pde_t;
#define GEN8_LEGACY_PDPES 4 #define GEN8_LEGACY_PDPES 4
#define GEN8_PTES I915_PTES(sizeof(gen8_pte_t)) #define GEN8_PTES I915_PTES(sizeof(gen8_pte_t))
#define I915_PDPES_PER_PDP(dev) (USES_FULL_48BIT_PPGTT(dev) ?\
GEN8_PML4ES_PER_PML4 : GEN8_LEGACY_PDPES)
#define PPAT_UNCACHED_INDEX (_PAGE_PWT | _PAGE_PCD) #define PPAT_UNCACHED_INDEX (_PAGE_PWT | _PAGE_PCD)
#define PPAT_CACHED_PDE_INDEX 0 /* WB LLC */ #define PPAT_CACHED_PDE_INDEX 0 /* WB LLC */
#define PPAT_CACHED_INDEX _PAGE_PAT /* WB LLCeLLC */ #define PPAT_CACHED_INDEX _PAGE_PAT /* WB LLCeLLC */
...@@ -135,7 +149,7 @@ struct i915_ggtt_view { ...@@ -135,7 +149,7 @@ struct i915_ggtt_view {
union { union {
struct { struct {
unsigned long offset; u64 offset;
unsigned int size; unsigned int size;
} partial; } partial;
} params; } params;
...@@ -241,9 +255,17 @@ struct i915_page_directory { ...@@ -241,9 +255,17 @@ struct i915_page_directory {
}; };
struct i915_page_directory_pointer { struct i915_page_directory_pointer {
/* struct page *page; */ struct i915_page_dma base;
DECLARE_BITMAP(used_pdpes, GEN8_LEGACY_PDPES);
struct i915_page_directory *page_directory[GEN8_LEGACY_PDPES]; unsigned long *used_pdpes;
struct i915_page_directory **page_directory;
};
struct i915_pml4 {
struct i915_page_dma base;
DECLARE_BITMAP(used_pml4es, GEN8_PML4ES_PER_PML4);
struct i915_page_directory_pointer *pdps[GEN8_PML4ES_PER_PML4];
}; };
struct i915_address_space { struct i915_address_space {
...@@ -256,6 +278,7 @@ struct i915_address_space { ...@@ -256,6 +278,7 @@ struct i915_address_space {
struct i915_page_scratch *scratch_page; struct i915_page_scratch *scratch_page;
struct i915_page_table *scratch_pt; struct i915_page_table *scratch_pt;
struct i915_page_directory *scratch_pd; struct i915_page_directory *scratch_pd;
struct i915_page_directory_pointer *scratch_pdp; /* GEN8+ & 48b PPGTT */
/** /**
* List of objects currently involved in rendering. * List of objects currently involved in rendering.
...@@ -341,8 +364,9 @@ struct i915_hw_ppgtt { ...@@ -341,8 +364,9 @@ struct i915_hw_ppgtt {
struct drm_mm_node node; struct drm_mm_node node;
unsigned long pd_dirty_rings; unsigned long pd_dirty_rings;
union { union {
struct i915_page_directory_pointer pdp; struct i915_pml4 pml4; /* GEN8+ & 48b PPGTT */
struct i915_page_directory pd; struct i915_page_directory_pointer pdp; /* GEN8+ */
struct i915_page_directory pd; /* GEN6-7 */
}; };
struct drm_i915_file_private *file_priv; struct drm_i915_file_private *file_priv;
...@@ -436,24 +460,23 @@ static inline uint32_t gen6_pde_index(uint32_t addr) ...@@ -436,24 +460,23 @@ static inline uint32_t gen6_pde_index(uint32_t addr)
temp = min(temp, length), \ temp = min(temp, length), \
start += temp, length -= temp) start += temp, length -= temp)
#define gen8_for_each_pdpe(pd, pdp, start, length, temp, iter) \ #define gen8_for_each_pdpe(pd, pdp, start, length, temp, iter) \
for (iter = gen8_pdpe_index(start); \ for (iter = gen8_pdpe_index(start); \
pd = (pdp)->page_directory[iter], length > 0 && iter < GEN8_LEGACY_PDPES; \ pd = (pdp)->page_directory[iter], \
length > 0 && (iter < I915_PDPES_PER_PDP(dev)); \
iter++, \ iter++, \
temp = ALIGN(start+1, 1 << GEN8_PDPE_SHIFT) - start, \ temp = ALIGN(start+1, 1 << GEN8_PDPE_SHIFT) - start, \
temp = min(temp, length), \ temp = min(temp, length), \
start += temp, length -= temp) start += temp, length -= temp)
/* Clamp length to the next page_directory boundary */ #define gen8_for_each_pml4e(pdp, pml4, start, length, temp, iter) \
static inline uint64_t gen8_clamp_pd(uint64_t start, uint64_t length) for (iter = gen8_pml4e_index(start); \
{ pdp = (pml4)->pdps[iter], \
uint64_t next_pd = ALIGN(start + 1, 1 << GEN8_PDPE_SHIFT); length > 0 && iter < GEN8_PML4ES_PER_PML4; \
iter++, \
if (next_pd > (start + length)) temp = ALIGN(start+1, 1ULL << GEN8_PML4E_SHIFT) - start, \
return length; temp = min(temp, length), \
start += temp, length -= temp)
return next_pd - start;
}
static inline uint32_t gen8_pte_index(uint64_t address) static inline uint32_t gen8_pte_index(uint64_t address)
{ {
...@@ -472,8 +495,7 @@ static inline uint32_t gen8_pdpe_index(uint64_t address) ...@@ -472,8 +495,7 @@ static inline uint32_t gen8_pdpe_index(uint64_t address)
static inline uint32_t gen8_pml4e_index(uint64_t address) static inline uint32_t gen8_pml4e_index(uint64_t address)
{ {
WARN_ON(1); /* For 64B */ return (address >> GEN8_PML4E_SHIFT) & GEN8_PML4E_MASK;
return 0;
} }
static inline size_t gen8_pte_count(uint64_t address, uint64_t length) static inline size_t gen8_pte_count(uint64_t address, uint64_t length)
......
...@@ -813,7 +813,6 @@ static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = { ...@@ -813,7 +813,6 @@ static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = {
int int
i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file) i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
{ {
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_userptr *args = data; struct drm_i915_gem_userptr *args = data;
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
int ret; int ret;
...@@ -826,9 +825,6 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file ...@@ -826,9 +825,6 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file
if (offset_in_page(args->user_ptr | args->user_size)) if (offset_in_page(args->user_ptr | args->user_size))
return -EINVAL; return -EINVAL;
if (args->user_size > dev_priv->gtt.base.total)
return -E2BIG;
if (!access_ok(args->flags & I915_USERPTR_READ_ONLY ? VERIFY_READ : VERIFY_WRITE, if (!access_ok(args->flags & I915_USERPTR_READ_ONLY ? VERIFY_READ : VERIFY_WRITE,
(char __user *)(unsigned long)args->user_ptr, args->user_size)) (char __user *)(unsigned long)args->user_ptr, args->user_size))
return -EFAULT; return -EFAULT;
......
...@@ -30,11 +30,6 @@ ...@@ -30,11 +30,6 @@
#include <generated/utsrelease.h> #include <generated/utsrelease.h>
#include "i915_drv.h" #include "i915_drv.h"
static const char *yesno(int v)
{
return v ? "yes" : "no";
}
static const char *ring_str(int ring) static const char *ring_str(int ring)
{ {
switch (ring) { switch (ring) {
...@@ -197,8 +192,9 @@ static void print_error_buffers(struct drm_i915_error_state_buf *m, ...@@ -197,8 +192,9 @@ static void print_error_buffers(struct drm_i915_error_state_buf *m,
err_printf(m, " %s [%d]:\n", name, count); err_printf(m, " %s [%d]:\n", name, count);
while (count--) { while (count--) {
err_printf(m, " %08x %8u %02x %02x [ ", err_printf(m, " %08x_%08x %8u %02x %02x [ ",
err->gtt_offset, upper_32_bits(err->gtt_offset),
lower_32_bits(err->gtt_offset),
err->size, err->size,
err->read_domains, err->read_domains,
err->write_domain); err->write_domain);
...@@ -427,15 +423,17 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, ...@@ -427,15 +423,17 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
err_printf(m, " (submitted by %s [%d])", err_printf(m, " (submitted by %s [%d])",
error->ring[i].comm, error->ring[i].comm,
error->ring[i].pid); error->ring[i].pid);
err_printf(m, " --- gtt_offset = 0x%08x\n", err_printf(m, " --- gtt_offset = 0x%08x %08x\n",
obj->gtt_offset); upper_32_bits(obj->gtt_offset),
lower_32_bits(obj->gtt_offset));
print_error_obj(m, obj); print_error_obj(m, obj);
} }
obj = error->ring[i].wa_batchbuffer; obj = error->ring[i].wa_batchbuffer;
if (obj) { if (obj) {
err_printf(m, "%s (w/a) --- gtt_offset = 0x%08x\n", err_printf(m, "%s (w/a) --- gtt_offset = 0x%08x\n",
dev_priv->ring[i].name, obj->gtt_offset); dev_priv->ring[i].name,
lower_32_bits(obj->gtt_offset));
print_error_obj(m, obj); print_error_obj(m, obj);
} }
...@@ -454,22 +452,22 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, ...@@ -454,22 +452,22 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
if ((obj = error->ring[i].ringbuffer)) { if ((obj = error->ring[i].ringbuffer)) {
err_printf(m, "%s --- ringbuffer = 0x%08x\n", err_printf(m, "%s --- ringbuffer = 0x%08x\n",
dev_priv->ring[i].name, dev_priv->ring[i].name,
obj->gtt_offset); lower_32_bits(obj->gtt_offset));
print_error_obj(m, obj); print_error_obj(m, obj);
} }
if ((obj = error->ring[i].hws_page)) { if ((obj = error->ring[i].hws_page)) {
err_printf(m, "%s --- HW Status = 0x%08x\n", err_printf(m, "%s --- HW Status = 0x%08llx\n",
dev_priv->ring[i].name, dev_priv->ring[i].name,
obj->gtt_offset); obj->gtt_offset + LRC_PPHWSP_PN * PAGE_SIZE);
offset = 0; offset = 0;
for (elt = 0; elt < PAGE_SIZE/16; elt += 4) { for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
err_printf(m, "[%04x] %08x %08x %08x %08x\n", err_printf(m, "[%04x] %08x %08x %08x %08x\n",
offset, offset,
obj->pages[0][elt], obj->pages[LRC_PPHWSP_PN][elt],
obj->pages[0][elt+1], obj->pages[LRC_PPHWSP_PN][elt+1],
obj->pages[0][elt+2], obj->pages[LRC_PPHWSP_PN][elt+2],
obj->pages[0][elt+3]); obj->pages[LRC_PPHWSP_PN][elt+3]);
offset += 16; offset += 16;
} }
} }
...@@ -477,13 +475,14 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, ...@@ -477,13 +475,14 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
if ((obj = error->ring[i].ctx)) { if ((obj = error->ring[i].ctx)) {
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); lower_32_bits(obj->gtt_offset));
print_error_obj(m, obj); print_error_obj(m, obj);
} }
} }
if ((obj = error->semaphore_obj)) { if ((obj = error->semaphore_obj)) {
err_printf(m, "Semaphore page = 0x%08x\n", obj->gtt_offset); err_printf(m, "Semaphore page = 0x%08x\n",
lower_32_bits(obj->gtt_offset));
for (elt = 0; elt < PAGE_SIZE/16; elt += 4) { for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
err_printf(m, "[%04x] %08x %08x %08x %08x\n", err_printf(m, "[%04x] %08x %08x %08x %08x\n",
elt * 4, elt * 4,
...@@ -591,7 +590,7 @@ i915_error_object_create(struct drm_i915_private *dev_priv, ...@@ -591,7 +590,7 @@ i915_error_object_create(struct drm_i915_private *dev_priv,
int num_pages; int num_pages;
bool use_ggtt; bool use_ggtt;
int i = 0; int i = 0;
u32 reloc_offset; u64 reloc_offset;
if (src == NULL || src->pages == NULL) if (src == NULL || src->pages == NULL)
return NULL; return NULL;
......
...@@ -38,10 +38,6 @@ ...@@ -38,10 +38,6 @@
#define GS_MIA_SHIFT 16 #define GS_MIA_SHIFT 16
#define GS_MIA_MASK (0x07 << GS_MIA_SHIFT) #define GS_MIA_MASK (0x07 << GS_MIA_SHIFT)
#define GUC_WOPCM_SIZE 0xc050
#define GUC_WOPCM_SIZE_VALUE (0x80 << 12) /* 512KB */
#define GUC_WOPCM_OFFSET 0x80000 /* 512KB */
#define SOFT_SCRATCH(n) (0xc180 + ((n) * 4)) #define SOFT_SCRATCH(n) (0xc180 + ((n) * 4))
#define UOS_RSA_SCRATCH_0 0xc200 #define UOS_RSA_SCRATCH_0 0xc200
...@@ -56,10 +52,18 @@ ...@@ -56,10 +52,18 @@
#define UOS_MOVE (1<<4) #define UOS_MOVE (1<<4)
#define START_DMA (1<<0) #define START_DMA (1<<0)
#define DMA_GUC_WOPCM_OFFSET 0xc340 #define DMA_GUC_WOPCM_OFFSET 0xc340
#define GUC_WOPCM_OFFSET_VALUE 0x80000 /* 512KB */
#define GUC_WOPCM_SIZE 0xc050
#define GUC_WOPCM_SIZE_VALUE (0x80 << 12) /* 512KB */
/* GuC addresses below GUC_WOPCM_TOP don't map through the GTT */
#define GUC_WOPCM_TOP (GUC_WOPCM_SIZE_VALUE)
#define GEN8_GT_PM_CONFIG 0x138140 #define GEN8_GT_PM_CONFIG 0x138140
#define GEN9LP_GT_PM_CONFIG 0x138140
#define GEN9_GT_PM_CONFIG 0x13816c #define GEN9_GT_PM_CONFIG 0x13816c
#define GEN8_GT_DOORBELL_ENABLE (1<<0) #define GT_DOORBELL_ENABLE (1<<0)
#define GEN8_GTCR 0x4274 #define GEN8_GTCR 0x4274
#define GEN8_GTCR_INVALIDATE (1<<0) #define GEN8_GTCR_INVALIDATE (1<<0)
...@@ -80,7 +84,8 @@ ...@@ -80,7 +84,8 @@
GUC_ENABLE_READ_CACHE_LOGIC | \ GUC_ENABLE_READ_CACHE_LOGIC | \
GUC_ENABLE_MIA_CACHING | \ GUC_ENABLE_MIA_CACHING | \
GUC_ENABLE_READ_CACHE_FOR_SRAM_DATA | \ GUC_ENABLE_READ_CACHE_FOR_SRAM_DATA | \
GUC_ENABLE_READ_CACHE_FOR_WOPCM_DATA) GUC_ENABLE_READ_CACHE_FOR_WOPCM_DATA | \
GUC_ENABLE_MIA_CLOCK_GATING)
#define HOST2GUC_INTERRUPT 0xc4c8 #define HOST2GUC_INTERRUPT 0xc4c8
#define HOST2GUC_TRIGGER (1<<0) #define HOST2GUC_TRIGGER (1<<0)
......
This diff is collapsed.
This diff is collapsed.
...@@ -51,6 +51,7 @@ struct i915_params i915 __read_mostly = { ...@@ -51,6 +51,7 @@ struct i915_params i915 __read_mostly = {
.use_mmio_flip = 0, .use_mmio_flip = 0,
.mmio_debug = 0, .mmio_debug = 0,
.verbose_state_checks = 1, .verbose_state_checks = 1,
.nuclear_pageflip = 0,
.edp_vswing = 0, .edp_vswing = 0,
.enable_guc_submission = false, .enable_guc_submission = false,
.guc_log_level = -1, .guc_log_level = -1,
...@@ -177,6 +178,10 @@ module_param_named(verbose_state_checks, i915.verbose_state_checks, bool, 0600); ...@@ -177,6 +178,10 @@ module_param_named(verbose_state_checks, i915.verbose_state_checks, bool, 0600);
MODULE_PARM_DESC(verbose_state_checks, MODULE_PARM_DESC(verbose_state_checks,
"Enable verbose logs (ie. WARN_ON()) in case of unexpected hw state conditions."); "Enable verbose logs (ie. WARN_ON()) in case of unexpected hw state conditions.");
module_param_named_unsafe(nuclear_pageflip, i915.nuclear_pageflip, bool, 0600);
MODULE_PARM_DESC(nuclear_pageflip,
"Force atomic modeset functionality; asynchronous mode is not yet supported. (default: false).");
/* WA to get away with the default setting in VBT for early platforms.Will be removed */ /* WA to get away with the default setting in VBT for early platforms.Will be removed */
module_param_named_unsafe(edp_vswing, i915.edp_vswing, int, 0400); module_param_named_unsafe(edp_vswing, i915.edp_vswing, int, 0400);
MODULE_PARM_DESC(edp_vswing, MODULE_PARM_DESC(edp_vswing,
......
This diff is collapsed.
...@@ -186,33 +186,49 @@ DEFINE_EVENT(i915_va, i915_va_alloc, ...@@ -186,33 +186,49 @@ DEFINE_EVENT(i915_va, i915_va_alloc,
TP_ARGS(vm, start, length, name) TP_ARGS(vm, start, length, name)
); );
DECLARE_EVENT_CLASS(i915_page_table_entry, DECLARE_EVENT_CLASS(i915_px_entry,
TP_PROTO(struct i915_address_space *vm, u32 pde, u64 start, u64 pde_shift), TP_PROTO(struct i915_address_space *vm, u32 px, u64 start, u64 px_shift),
TP_ARGS(vm, pde, start, pde_shift), TP_ARGS(vm, px, start, px_shift),
TP_STRUCT__entry( TP_STRUCT__entry(
__field(struct i915_address_space *, vm) __field(struct i915_address_space *, vm)
__field(u32, pde) __field(u32, px)
__field(u64, start) __field(u64, start)
__field(u64, end) __field(u64, end)
), ),
TP_fast_assign( TP_fast_assign(
__entry->vm = vm; __entry->vm = vm;
__entry->pde = pde; __entry->px = px;
__entry->start = start; __entry->start = start;
__entry->end = ((start + (1ULL << pde_shift)) & ~((1ULL << pde_shift)-1)) - 1; __entry->end = ((start + (1ULL << px_shift)) & ~((1ULL << px_shift)-1)) - 1;
), ),
TP_printk("vm=%p, pde=%d (0x%llx-0x%llx)", TP_printk("vm=%p, pde=%d (0x%llx-0x%llx)",
__entry->vm, __entry->pde, __entry->start, __entry->end) __entry->vm, __entry->px, __entry->start, __entry->end)
); );
DEFINE_EVENT(i915_page_table_entry, i915_page_table_entry_alloc, DEFINE_EVENT(i915_px_entry, i915_page_table_entry_alloc,
TP_PROTO(struct i915_address_space *vm, u32 pde, u64 start, u64 pde_shift), TP_PROTO(struct i915_address_space *vm, u32 pde, u64 start, u64 pde_shift),
TP_ARGS(vm, pde, start, pde_shift) TP_ARGS(vm, pde, start, pde_shift)
); );
DEFINE_EVENT_PRINT(i915_px_entry, i915_page_directory_entry_alloc,
TP_PROTO(struct i915_address_space *vm, u32 pdpe, u64 start, u64 pdpe_shift),
TP_ARGS(vm, pdpe, start, pdpe_shift),
TP_printk("vm=%p, pdpe=%d (0x%llx-0x%llx)",
__entry->vm, __entry->px, __entry->start, __entry->end)
);
DEFINE_EVENT_PRINT(i915_px_entry, i915_page_directory_pointer_entry_alloc,
TP_PROTO(struct i915_address_space *vm, u32 pml4e, u64 start, u64 pml4e_shift),
TP_ARGS(vm, pml4e, start, pml4e_shift),
TP_printk("vm=%p, pml4e=%d (0x%llx-0x%llx)",
__entry->vm, __entry->px, __entry->start, __entry->end)
);
/* Avoid extra math because we only support two sizes. The format is defined by /* Avoid extra math because we only support two sizes. The format is defined by
* bitmap_scnprintf. Each 32 bits is 8 HEX digits followed by comma */ * bitmap_scnprintf. Each 32 bits is 8 HEX digits followed by comma */
#define TRACE_PT_SIZE(bits) \ #define TRACE_PT_SIZE(bits) \
......
...@@ -40,6 +40,19 @@ ...@@ -40,6 +40,19 @@
#define INTEL_VGT_IF_VERSION \ #define INTEL_VGT_IF_VERSION \
INTEL_VGT_IF_VERSION_ENCODE(VGT_VERSION_MAJOR, VGT_VERSION_MINOR) INTEL_VGT_IF_VERSION_ENCODE(VGT_VERSION_MAJOR, VGT_VERSION_MINOR)
/*
* notifications from guest to vgpu device model
*/
enum vgt_g2v_type {
VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE = 2,
VGT_G2V_PPGTT_L3_PAGE_TABLE_DESTROY,
VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE,
VGT_G2V_PPGTT_L4_PAGE_TABLE_DESTROY,
VGT_G2V_EXECLIST_CONTEXT_CREATE,
VGT_G2V_EXECLIST_CONTEXT_DESTROY,
VGT_G2V_MAX,
};
struct vgt_if { struct vgt_if {
uint64_t magic; /* VGT_MAGIC */ uint64_t magic; /* VGT_MAGIC */
uint16_t version_major; uint16_t version_major;
...@@ -70,11 +83,28 @@ struct vgt_if { ...@@ -70,11 +83,28 @@ struct vgt_if {
uint32_t rsv3[0x200 - 24]; /* pad to half page */ uint32_t rsv3[0x200 - 24]; /* pad to half page */
/* /*
* The bottom half page is for response from Gfx driver to hypervisor. * The bottom half page is for response from Gfx driver to hypervisor.
* Set to reserved fields temporarily by now.
*/ */
uint32_t rsv4; uint32_t rsv4;
uint32_t display_ready; /* ready for display owner switch */ uint32_t display_ready; /* ready for display owner switch */
uint32_t rsv5[0x200 - 2]; /* pad to one page */
uint32_t rsv5[4];
uint32_t g2v_notify;
uint32_t rsv6[7];
uint32_t pdp0_lo;
uint32_t pdp0_hi;
uint32_t pdp1_lo;
uint32_t pdp1_hi;
uint32_t pdp2_lo;
uint32_t pdp2_hi;
uint32_t pdp3_lo;
uint32_t pdp3_hi;
uint32_t execlist_context_descriptor_lo;
uint32_t execlist_context_descriptor_hi;
uint32_t rsv7[0x200 - 24]; /* pad to one page */
} __packed; } __packed;
#define vgtif_reg(x) \ #define vgtif_reg(x) \
......
...@@ -85,22 +85,14 @@ intel_connector_atomic_get_property(struct drm_connector *connector, ...@@ -85,22 +85,14 @@ intel_connector_atomic_get_property(struct drm_connector *connector,
struct drm_crtc_state * struct drm_crtc_state *
intel_crtc_duplicate_state(struct drm_crtc *crtc) intel_crtc_duplicate_state(struct drm_crtc *crtc)
{ {
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_crtc_state *crtc_state; struct intel_crtc_state *crtc_state;
if (WARN_ON(!intel_crtc->config)) crtc_state = kmemdup(crtc->state, sizeof(*crtc_state), GFP_KERNEL);
crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
else
crtc_state = kmemdup(intel_crtc->config,
sizeof(*intel_crtc->config), GFP_KERNEL);
if (!crtc_state) if (!crtc_state)
return NULL; return NULL;
__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base); __drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base);
crtc_state->base.crtc = crtc;
return &crtc_state->base; return &crtc_state->base;
} }
...@@ -149,9 +141,6 @@ int intel_atomic_setup_scalers(struct drm_device *dev, ...@@ -149,9 +141,6 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
int i, j; int i, j;
num_scalers_need = hweight32(scaler_state->scaler_users); num_scalers_need = hweight32(scaler_state->scaler_users);
DRM_DEBUG_KMS("crtc_state = %p need = %d avail = %d scaler_users = 0x%x\n",
crtc_state, num_scalers_need, intel_crtc->num_scalers,
scaler_state->scaler_users);
/* /*
* High level flow: * High level flow:
......
...@@ -76,11 +76,7 @@ intel_plane_duplicate_state(struct drm_plane *plane) ...@@ -76,11 +76,7 @@ intel_plane_duplicate_state(struct drm_plane *plane)
struct drm_plane_state *state; struct drm_plane_state *state;
struct intel_plane_state *intel_state; struct intel_plane_state *intel_state;
if (WARN_ON(!plane->state)) intel_state = kmemdup(plane->state, sizeof(*intel_state), GFP_KERNEL);
intel_state = intel_create_plane_state(plane);
else
intel_state = kmemdup(plane->state, sizeof(*intel_state),
GFP_KERNEL);
if (!intel_state) if (!intel_state)
return NULL; return NULL;
......
...@@ -1350,21 +1350,3 @@ intel_parse_bios(struct drm_device *dev) ...@@ -1350,21 +1350,3 @@ intel_parse_bios(struct drm_device *dev)
return 0; return 0;
} }
/* Ensure that vital registers have been initialised, even if the BIOS
* is absent or just failing to do its job.
*/
void intel_setup_bios(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
/* Set the Panel Power On/Off timings if uninitialized. */
if (!HAS_PCH_SPLIT(dev) &&
I915_READ(PP_ON_DELAYS) == 0 && I915_READ(PP_OFF_DELAYS) == 0) {
/* Set T2 to 40ms and T5 to 200ms */
I915_WRITE(PP_ON_DELAYS, 0x019007d0);
/* Set T3 to 35ms and Tx to 200ms */
I915_WRITE(PP_OFF_DELAYS, 0x015e07d0);
}
}
...@@ -588,7 +588,6 @@ struct bdb_psr { ...@@ -588,7 +588,6 @@ struct bdb_psr {
struct psr_table psr_table[16]; struct psr_table psr_table[16];
} __packed; } __packed;
void intel_setup_bios(struct drm_device *dev);
int intel_parse_bios(struct drm_device *dev); int intel_parse_bios(struct drm_device *dev);
/* /*
......
...@@ -707,7 +707,6 @@ void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder) ...@@ -707,7 +707,6 @@ void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
intel_dp->DP = intel_dig_port->saved_port_bits | intel_dp->DP = intel_dig_port->saved_port_bits |
DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0); DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count); intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
} }
static struct intel_encoder * static struct intel_encoder *
...@@ -1242,9 +1241,10 @@ hsw_ddi_calculate_wrpll(int clock /* in Hz */, ...@@ -1242,9 +1241,10 @@ hsw_ddi_calculate_wrpll(int clock /* in Hz */,
static bool static bool
hsw_ddi_pll_select(struct intel_crtc *intel_crtc, hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
struct intel_crtc_state *crtc_state, struct intel_crtc_state *crtc_state,
struct intel_encoder *intel_encoder, struct intel_encoder *intel_encoder)
int clock)
{ {
int clock = crtc_state->port_clock;
if (intel_encoder->type == INTEL_OUTPUT_HDMI) { if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
struct intel_shared_dpll *pll; struct intel_shared_dpll *pll;
uint32_t val; uint32_t val;
...@@ -1523,11 +1523,11 @@ skl_ddi_calculate_wrpll(int clock /* in Hz */, ...@@ -1523,11 +1523,11 @@ skl_ddi_calculate_wrpll(int clock /* in Hz */,
static bool static bool
skl_ddi_pll_select(struct intel_crtc *intel_crtc, skl_ddi_pll_select(struct intel_crtc *intel_crtc,
struct intel_crtc_state *crtc_state, struct intel_crtc_state *crtc_state,
struct intel_encoder *intel_encoder, struct intel_encoder *intel_encoder)
int clock)
{ {
struct intel_shared_dpll *pll; struct intel_shared_dpll *pll;
uint32_t ctrl1, cfgcr1, cfgcr2; uint32_t ctrl1, cfgcr1, cfgcr2;
int clock = crtc_state->port_clock;
/* /*
* See comment in intel_dpll_hw_state to understand why we always use 0 * See comment in intel_dpll_hw_state to understand why we always use 0
...@@ -1615,14 +1615,14 @@ static const struct bxt_clk_div bxt_dp_clk_val[] = { ...@@ -1615,14 +1615,14 @@ static const struct bxt_clk_div bxt_dp_clk_val[] = {
static bool static bool
bxt_ddi_pll_select(struct intel_crtc *intel_crtc, bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
struct intel_crtc_state *crtc_state, struct intel_crtc_state *crtc_state,
struct intel_encoder *intel_encoder, struct intel_encoder *intel_encoder)
int clock)
{ {
struct intel_shared_dpll *pll; struct intel_shared_dpll *pll;
struct bxt_clk_div clk_div = {0}; struct bxt_clk_div clk_div = {0};
int vco = 0; int vco = 0;
uint32_t prop_coef, int_coef, gain_ctl, targ_cnt; uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
uint32_t lanestagger; uint32_t lanestagger;
int clock = crtc_state->port_clock;
if (intel_encoder->type == INTEL_OUTPUT_HDMI) { if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
intel_clock_t best_clock; intel_clock_t best_clock;
...@@ -1750,17 +1750,16 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc, ...@@ -1750,17 +1750,16 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
struct drm_device *dev = intel_crtc->base.dev; struct drm_device *dev = intel_crtc->base.dev;
struct intel_encoder *intel_encoder = struct intel_encoder *intel_encoder =
intel_ddi_get_crtc_new_encoder(crtc_state); intel_ddi_get_crtc_new_encoder(crtc_state);
int clock = crtc_state->port_clock;
if (IS_SKYLAKE(dev)) if (IS_SKYLAKE(dev))
return skl_ddi_pll_select(intel_crtc, crtc_state, return skl_ddi_pll_select(intel_crtc, crtc_state,
intel_encoder, clock); intel_encoder);
else if (IS_BROXTON(dev)) else if (IS_BROXTON(dev))
return bxt_ddi_pll_select(intel_crtc, crtc_state, return bxt_ddi_pll_select(intel_crtc, crtc_state,
intel_encoder, clock); intel_encoder);
else else
return hsw_ddi_pll_select(intel_crtc, crtc_state, return hsw_ddi_pll_select(intel_crtc, crtc_state,
intel_encoder, clock); intel_encoder);
} }
void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
...@@ -1893,7 +1892,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) ...@@ -1893,7 +1892,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
} else } else
temp |= TRANS_DDI_MODE_SELECT_DP_SST; temp |= TRANS_DDI_MODE_SELECT_DP_SST;
temp |= DDI_PORT_WIDTH(intel_dp->lane_count); temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
} else if (type == INTEL_OUTPUT_DP_MST) { } else if (type == INTEL_OUTPUT_DP_MST) {
struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp; struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
...@@ -1902,7 +1901,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) ...@@ -1902,7 +1901,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
} else } else
temp |= TRANS_DDI_MODE_SELECT_DP_SST; temp |= TRANS_DDI_MODE_SELECT_DP_SST;
temp |= DDI_PORT_WIDTH(intel_dp->lane_count); temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
} else { } else {
WARN(1, "Invalid encoder type %d for pipe %c\n", WARN(1, "Invalid encoder type %d for pipe %c\n",
intel_encoder->type, pipe_name(pipe)); intel_encoder->type, pipe_name(pipe));
...@@ -2289,6 +2288,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) ...@@ -2289,6 +2288,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
intel_dp_set_link_params(intel_dp, crtc->config);
intel_ddi_init_dp_buf_reg(intel_encoder); intel_ddi_init_dp_buf_reg(intel_encoder);
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
...@@ -3069,6 +3070,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder, ...@@ -3069,6 +3070,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
case TRANS_DDI_MODE_SELECT_DP_SST: case TRANS_DDI_MODE_SELECT_DP_SST:
case TRANS_DDI_MODE_SELECT_DP_MST: case TRANS_DDI_MODE_SELECT_DP_MST:
pipe_config->has_dp_encoder = true; pipe_config->has_dp_encoder = true;
pipe_config->lane_count =
((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
intel_dp_get_m_n(intel_crtc, pipe_config); intel_dp_get_m_n(intel_crtc, pipe_config);
break; break;
default: default:
...@@ -3215,7 +3218,15 @@ void intel_ddi_init(struct drm_device *dev, enum port port) ...@@ -3215,7 +3218,15 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
goto err; goto err;
intel_dig_port->hpd_pulse = intel_dp_hpd_pulse; intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
dev_priv->hotplug.irq_port[port] = intel_dig_port; /*
* On BXT A0/A1, sw needs to activate DDIA HPD logic and
* interrupts to check the external panel connection.
*/
if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)
&& port == PORT_B)
dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
else
dev_priv->hotplug.irq_port[port] = intel_dig_port;
} }
/* In theory we don't need the encoder->type check, but leave it just in /* In theory we don't need the encoder->type check, but leave it just in
......
This diff is collapsed.
This diff is collapsed.
...@@ -39,7 +39,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, ...@@ -39,7 +39,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
struct intel_dp *intel_dp = &intel_dig_port->dp; struct intel_dp *intel_dp = &intel_dig_port->dp;
struct drm_atomic_state *state; struct drm_atomic_state *state;
int bpp, i; int bpp, i;
int lane_count, slots, rate; int lane_count, slots;
struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
struct drm_connector *drm_connector; struct drm_connector *drm_connector;
struct intel_connector *connector, *found = NULL; struct intel_connector *connector, *found = NULL;
...@@ -56,20 +56,11 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, ...@@ -56,20 +56,11 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
*/ */
lane_count = drm_dp_max_lane_count(intel_dp->dpcd); lane_count = drm_dp_max_lane_count(intel_dp->dpcd);
rate = intel_dp_max_link_rate(intel_dp);
if (intel_dp->num_sink_rates) { pipe_config->lane_count = lane_count;
intel_dp->link_bw = 0;
intel_dp->rate_select = intel_dp_rate_select(intel_dp, rate);
} else {
intel_dp->link_bw = drm_dp_link_rate_to_bw_code(rate);
intel_dp->rate_select = 0;
}
intel_dp->lane_count = lane_count;
pipe_config->pipe_bpp = 24; pipe_config->pipe_bpp = 24;
pipe_config->port_clock = rate; pipe_config->port_clock = intel_dp_max_link_rate(intel_dp);
state = pipe_config->base.state; state = pipe_config->base.state;
...@@ -184,6 +175,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder) ...@@ -184,6 +175,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
if (intel_dp->active_mst_links == 0) { if (intel_dp->active_mst_links == 0) {
enum port port = intel_ddi_get_encoder_port(encoder); enum port port = intel_ddi_get_encoder_port(encoder);
intel_dp_set_link_params(intel_dp, intel_crtc->config);
/* FIXME: add support for SKL */ /* FIXME: add support for SKL */
if (INTEL_INFO(dev)->gen < 9) if (INTEL_INFO(dev)->gen < 9)
I915_WRITE(PORT_CLK_SEL(port), I915_WRITE(PORT_CLK_SEL(port),
...@@ -286,6 +279,10 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder, ...@@ -286,6 +279,10 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
break; break;
} }
pipe_config->base.adjusted_mode.flags |= flags; pipe_config->base.adjusted_mode.flags |= flags;
pipe_config->lane_count =
((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
intel_dp_get_m_n(crtc, pipe_config); intel_dp_get_m_n(crtc, pipe_config);
intel_ddi_clock_get(&intel_dig_port->base, pipe_config); intel_ddi_clock_get(&intel_dig_port->base, pipe_config);
......
...@@ -142,6 +142,7 @@ struct intel_encoder { ...@@ -142,6 +142,7 @@ struct intel_encoder {
void (*mode_set)(struct intel_encoder *intel_encoder); void (*mode_set)(struct intel_encoder *intel_encoder);
void (*disable)(struct intel_encoder *); void (*disable)(struct intel_encoder *);
void (*post_disable)(struct intel_encoder *); void (*post_disable)(struct intel_encoder *);
void (*post_pll_disable)(struct intel_encoder *);
/* Read out the current hw state of this connector, returning true if /* Read out the current hw state of this connector, returning true if
* the encoder is active. If the encoder is enabled it also set the pipe * the encoder is active. If the encoder is enabled it also set the pipe
* it is connected to in the pipe parameter. */ * it is connected to in the pipe parameter. */
...@@ -423,6 +424,8 @@ struct intel_crtc_state { ...@@ -423,6 +424,8 @@ struct intel_crtc_state {
/* Used by SDVO (and if we ever fix it, HDMI). */ /* Used by SDVO (and if we ever fix it, HDMI). */
unsigned pixel_multiplier; unsigned pixel_multiplier;
uint8_t lane_count;
/* Panel fitter controls for gen2-gen4 + VLV */ /* Panel fitter controls for gen2-gen4 + VLV */
struct { struct {
u32 control; u32 control;
...@@ -561,6 +564,8 @@ struct intel_crtc { ...@@ -561,6 +564,8 @@ struct intel_crtc {
int scanline_offset; int scanline_offset;
unsigned start_vbl_count; unsigned start_vbl_count;
ktime_t start_vbl_time;
struct intel_crtc_atomic_commit atomic; struct intel_crtc_atomic_commit atomic;
/* scalers available on this crtc */ /* scalers available on this crtc */
...@@ -657,13 +662,14 @@ struct cxsr_latency { ...@@ -657,13 +662,14 @@ struct cxsr_latency {
struct intel_hdmi { struct intel_hdmi {
u32 hdmi_reg; u32 hdmi_reg;
int ddc_bus; int ddc_bus;
uint32_t color_range; bool limited_color_range;
bool color_range_auto; bool color_range_auto;
bool has_hdmi_sink; bool has_hdmi_sink;
bool has_audio; bool has_audio;
enum hdmi_force_audio force_audio; enum hdmi_force_audio force_audio;
bool rgb_quant_range_selectable; bool rgb_quant_range_selectable;
enum hdmi_picture_aspect aspect_ratio; enum hdmi_picture_aspect aspect_ratio;
struct intel_connector *attached_connector;
void (*write_infoframe)(struct drm_encoder *encoder, void (*write_infoframe)(struct drm_encoder *encoder,
enum hdmi_infoframe_type type, enum hdmi_infoframe_type type,
const void *frame, ssize_t len); const void *frame, ssize_t len);
...@@ -696,23 +702,29 @@ enum link_m_n_set { ...@@ -696,23 +702,29 @@ enum link_m_n_set {
M2_N2 M2_N2
}; };
struct sink_crc {
bool started;
u8 last_crc[6];
int last_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;
uint32_t DP; uint32_t DP;
int link_rate;
uint8_t lane_count;
bool has_audio; bool has_audio;
enum hdmi_force_audio force_audio; enum hdmi_force_audio force_audio;
uint32_t color_range; bool limited_color_range;
bool color_range_auto; bool color_range_auto;
uint8_t link_bw;
uint8_t rate_select;
uint8_t lane_count;
uint8_t dpcd[DP_RECEIVER_CAP_SIZE]; uint8_t dpcd[DP_RECEIVER_CAP_SIZE];
uint8_t psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE]; uint8_t psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE];
uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS]; uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
/* sink rates as reported by DP_SUPPORTED_LINK_RATES */ /* sink rates as reported by DP_SUPPORTED_LINK_RATES */
uint8_t num_sink_rates; uint8_t num_sink_rates;
int sink_rates[DP_MAX_SUPPORTED_RATES]; int sink_rates[DP_MAX_SUPPORTED_RATES];
struct sink_crc sink_crc;
struct drm_dp_aux aux; struct drm_dp_aux aux;
uint8_t train_set[4]; uint8_t train_set[4];
int panel_power_up_delay; int panel_power_up_delay;
...@@ -735,7 +747,6 @@ struct intel_dp { ...@@ -735,7 +747,6 @@ struct intel_dp {
enum pipe pps_pipe; enum pipe pps_pipe;
struct edp_power_seq pps_delays; struct edp_power_seq pps_delays;
bool use_tps3;
bool can_mst; /* this port supports mst */ bool can_mst; /* this port supports mst */
bool is_mst; bool is_mst;
int active_mst_links; int active_mst_links;
...@@ -770,6 +781,7 @@ struct intel_digital_port { ...@@ -770,6 +781,7 @@ struct intel_digital_port {
struct intel_dp dp; struct intel_dp dp;
struct intel_hdmi hdmi; struct intel_hdmi hdmi;
enum irqreturn (*hpd_pulse)(struct intel_digital_port *, bool); enum irqreturn (*hpd_pulse)(struct intel_digital_port *, bool);
bool release_cl2_override;
}; };
struct intel_dp_mst_encoder { struct intel_dp_mst_encoder {
...@@ -779,7 +791,7 @@ struct intel_dp_mst_encoder { ...@@ -779,7 +791,7 @@ struct intel_dp_mst_encoder {
void *port; /* store this opaque as its illegal to dereference it */ void *port; /* store this opaque as its illegal to dereference it */
}; };
static inline int static inline enum dpio_channel
vlv_dport_to_channel(struct intel_digital_port *dport) vlv_dport_to_channel(struct intel_digital_port *dport)
{ {
switch (dport->port) { switch (dport->port) {
...@@ -793,7 +805,21 @@ vlv_dport_to_channel(struct intel_digital_port *dport) ...@@ -793,7 +805,21 @@ vlv_dport_to_channel(struct intel_digital_port *dport)
} }
} }
static inline int static inline enum dpio_phy
vlv_dport_to_phy(struct intel_digital_port *dport)
{
switch (dport->port) {
case PORT_B:
case PORT_C:
return DPIO_PHY0;
case PORT_D:
return DPIO_PHY1;
default:
BUG();
}
}
static inline enum dpio_channel
vlv_pipe_to_channel(enum pipe pipe) vlv_pipe_to_channel(enum pipe pipe)
{ {
switch (pipe) { switch (pipe) {
...@@ -987,6 +1013,7 @@ void i915_audio_component_cleanup(struct drm_i915_private *dev_priv); ...@@ -987,6 +1013,7 @@ void i915_audio_component_cleanup(struct drm_i915_private *dev_priv);
extern const struct drm_plane_funcs intel_plane_funcs; extern const struct drm_plane_funcs intel_plane_funcs;
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 intel_hrawclk(struct drm_device *dev);
void intel_mark_busy(struct drm_device *dev); void intel_mark_busy(struct drm_device *dev);
void intel_mark_idle(struct drm_device *dev); void intel_mark_idle(struct drm_device *dev);
void intel_crtc_restore_mode(struct drm_crtc *crtc); void intel_crtc_restore_mode(struct drm_crtc *crtc);
...@@ -995,8 +1022,6 @@ void intel_encoder_destroy(struct drm_encoder *encoder); ...@@ -995,8 +1022,6 @@ void intel_encoder_destroy(struct drm_encoder *encoder);
int intel_connector_init(struct intel_connector *); int intel_connector_init(struct intel_connector *);
struct intel_connector *intel_connector_alloc(void); struct intel_connector *intel_connector_alloc(void);
bool intel_connector_get_hw_state(struct intel_connector *connector); bool intel_connector_get_hw_state(struct intel_connector *connector);
bool ibx_digital_port_connected(struct drm_i915_private *dev_priv,
struct intel_digital_port *port);
void intel_connector_attach_encoder(struct intel_connector *connector, void intel_connector_attach_encoder(struct intel_connector *connector,
struct intel_encoder *encoder); struct intel_encoder *encoder);
struct drm_encoder *intel_best_encoder(struct drm_connector *connector); struct drm_encoder *intel_best_encoder(struct drm_connector *connector);
...@@ -1153,6 +1178,8 @@ void assert_csr_loaded(struct drm_i915_private *dev_priv); ...@@ -1153,6 +1178,8 @@ void assert_csr_loaded(struct drm_i915_private *dev_priv);
void intel_dp_init(struct drm_device *dev, int output_reg, enum port port); void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port, bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
struct intel_connector *intel_connector); struct intel_connector *intel_connector);
void intel_dp_set_link_params(struct intel_dp *intel_dp,
const struct intel_crtc_state *pipe_config);
void intel_dp_start_link_train(struct intel_dp *intel_dp); void intel_dp_start_link_train(struct intel_dp *intel_dp);
void intel_dp_complete_link_train(struct intel_dp *intel_dp); void intel_dp_complete_link_train(struct intel_dp *intel_dp);
void intel_dp_stop_link_train(struct intel_dp *intel_dp); void intel_dp_stop_link_train(struct intel_dp *intel_dp);
...@@ -1337,6 +1364,12 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv); ...@@ -1337,6 +1364,12 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv);
void intel_display_set_init_power(struct drm_i915_private *dev, bool enable); void intel_display_set_init_power(struct drm_i915_private *dev, bool enable);
void chv_phy_powergate_lanes(struct intel_encoder *encoder,
bool override, unsigned int mask);
bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
enum dpio_channel ch, bool override);
/* intel_pm.c */ /* intel_pm.c */
void intel_init_clock_gating(struct drm_device *dev); void intel_init_clock_gating(struct drm_device *dev);
void intel_suspend_hw(struct drm_device *dev); void intel_suspend_hw(struct drm_device *dev);
...@@ -1382,9 +1415,8 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob); ...@@ -1382,9 +1415,8 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane); int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
int intel_sprite_set_colorkey(struct drm_device *dev, void *data, int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
void intel_pipe_update_start(struct intel_crtc *crtc, void intel_pipe_update_start(struct intel_crtc *crtc);
uint32_t *start_vbl_count); void intel_pipe_update_end(struct intel_crtc *crtc);
void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count);
/* intel_tv.c */ /* intel_tv.c */
void intel_tv_init(struct drm_device *dev); void intel_tv_init(struct drm_device *dev);
......
...@@ -654,6 +654,7 @@ intel_dsi_mode_valid(struct drm_connector *connector, ...@@ -654,6 +654,7 @@ intel_dsi_mode_valid(struct drm_connector *connector,
{ {
struct intel_connector *intel_connector = to_intel_connector(connector); struct intel_connector *intel_connector = to_intel_connector(connector);
struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode; struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
DRM_DEBUG_KMS("\n"); DRM_DEBUG_KMS("\n");
...@@ -667,6 +668,8 @@ intel_dsi_mode_valid(struct drm_connector *connector, ...@@ -667,6 +668,8 @@ intel_dsi_mode_valid(struct drm_connector *connector,
return MODE_PANEL; return MODE_PANEL;
if (mode->vdisplay > fixed_mode->vdisplay) if (mode->vdisplay > fixed_mode->vdisplay)
return MODE_PANEL; return MODE_PANEL;
if (fixed_mode->clock > max_dotclk)
return MODE_CLOCK_HIGH;
} }
return MODE_OK; return MODE_OK;
......
...@@ -201,6 +201,8 @@ intel_dvo_mode_valid(struct drm_connector *connector, ...@@ -201,6 +201,8 @@ intel_dvo_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode) struct drm_display_mode *mode)
{ {
struct intel_dvo *intel_dvo = intel_attached_dvo(connector); struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
int target_clock = mode->clock;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN) if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN; return MODE_NO_DBLESCAN;
...@@ -212,8 +214,13 @@ intel_dvo_mode_valid(struct drm_connector *connector, ...@@ -212,8 +214,13 @@ intel_dvo_mode_valid(struct drm_connector *connector,
return MODE_PANEL; return MODE_PANEL;
if (mode->vdisplay > intel_dvo->panel_fixed_mode->vdisplay) if (mode->vdisplay > intel_dvo->panel_fixed_mode->vdisplay)
return MODE_PANEL; return MODE_PANEL;
target_clock = intel_dvo->panel_fixed_mode->clock;
} }
if (target_clock > max_dotclk)
return MODE_CLOCK_HIGH;
return intel_dvo->dev.dev_ops->mode_valid(&intel_dvo->dev, mode); return intel_dvo->dev.dev_ops->mode_valid(&intel_dvo->dev, mode);
} }
......
...@@ -263,7 +263,7 @@ static int intelfb_create(struct drm_fb_helper *helper, ...@@ -263,7 +263,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08lx, bo %p\n", DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08llx, bo %p\n",
fb->width, fb->height, fb->width, fb->height,
i915_gem_obj_ggtt_offset(obj), obj); i915_gem_obj_ggtt_offset(obj), obj);
......
/*
* Copyright © 2014 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*/
#ifndef _INTEL_GUC_H_
#define _INTEL_GUC_H_
#include "intel_guc_fwif.h"
#include "i915_guc_reg.h"
struct i915_guc_client {
struct drm_i915_gem_object *client_obj;
struct intel_context *owner;
struct intel_guc *guc;
uint32_t priority;
uint32_t ctx_index;
uint32_t proc_desc_offset;
uint32_t doorbell_offset;
uint32_t cookie;
uint16_t doorbell_id;
uint16_t padding; /* Maintain alignment */
uint32_t wq_offset;
uint32_t wq_size;
spinlock_t wq_lock; /* Protects all data below */
uint32_t wq_tail;
/* GuC submission statistics & status */
uint64_t submissions[I915_NUM_RINGS];
uint32_t q_fail;
uint32_t b_fail;
int retcode;
};
enum intel_guc_fw_status {
GUC_FIRMWARE_FAIL = -1,
GUC_FIRMWARE_NONE = 0,
GUC_FIRMWARE_PENDING,
GUC_FIRMWARE_SUCCESS
};
/*
* This structure encapsulates all the data needed during the process
* of fetching, caching, and loading the firmware image into the GuC.
*/
struct intel_guc_fw {
struct drm_device * guc_dev;
const char * guc_fw_path;
size_t guc_fw_size;
struct drm_i915_gem_object * guc_fw_obj;
enum intel_guc_fw_status guc_fw_fetch_status;
enum intel_guc_fw_status guc_fw_load_status;
uint16_t guc_fw_major_wanted;
uint16_t guc_fw_minor_wanted;
uint16_t guc_fw_major_found;
uint16_t guc_fw_minor_found;
};
struct intel_guc {
struct intel_guc_fw guc_fw;
uint32_t log_flags;
struct drm_i915_gem_object *log_obj;
struct drm_i915_gem_object *ctx_pool_obj;
struct ida ctx_ids;
struct i915_guc_client *execbuf_client;
spinlock_t host2guc_lock; /* Protects all data below */
DECLARE_BITMAP(doorbell_bitmap, GUC_MAX_DOORBELLS);
uint32_t db_cacheline; /* Cyclic counter mod pagesize */
/* Action status & statistics */
uint64_t action_count; /* Total commands issued */
uint32_t action_cmd; /* Last command word */
uint32_t action_status; /* Last return status */
uint32_t action_fail; /* Total number of failures */
int32_t action_err; /* Last error code */
uint64_t submissions[I915_NUM_RINGS];
uint32_t last_seqno[I915_NUM_RINGS];
};
/* intel_guc_loader.c */
extern void intel_guc_ucode_init(struct drm_device *dev);
extern int intel_guc_ucode_load(struct drm_device *dev);
extern void intel_guc_ucode_fini(struct drm_device *dev);
extern const char *intel_guc_fw_status_repr(enum intel_guc_fw_status status);
/* i915_guc_submission.c */
int i915_guc_submission_init(struct drm_device *dev);
int i915_guc_submission_enable(struct drm_device *dev);
int i915_guc_submit(struct i915_guc_client *client,
struct drm_i915_gem_request *rq);
void i915_guc_submission_disable(struct drm_device *dev);
void i915_guc_submission_fini(struct drm_device *dev);
#endif
...@@ -32,17 +32,16 @@ ...@@ -32,17 +32,16 @@
* EDITING THIS FILE IS THEREFORE NOT RECOMMENDED - YOUR CHANGES MAY BE LOST. * EDITING THIS FILE IS THEREFORE NOT RECOMMENDED - YOUR CHANGES MAY BE LOST.
*/ */
#define GFXCORE_FAMILY_GEN8 11
#define GFXCORE_FAMILY_GEN9 12 #define GFXCORE_FAMILY_GEN9 12
#define GFXCORE_FAMILY_FORCE_ULONG 0x7fffffff #define GFXCORE_FAMILY_UNKNOWN 0x7fffffff
#define GUC_CTX_PRIORITY_CRITICAL 0 #define GUC_CTX_PRIORITY_KMD_HIGH 0
#define GUC_CTX_PRIORITY_HIGH 1 #define GUC_CTX_PRIORITY_HIGH 1
#define GUC_CTX_PRIORITY_NORMAL 2 #define GUC_CTX_PRIORITY_KMD_NORMAL 2
#define GUC_CTX_PRIORITY_LOW 3 #define GUC_CTX_PRIORITY_NORMAL 3
#define GUC_MAX_GPU_CONTEXTS 1024 #define GUC_MAX_GPU_CONTEXTS 1024
#define GUC_INVALID_CTX_ID (GUC_MAX_GPU_CONTEXTS + 1) #define GUC_INVALID_CTX_ID GUC_MAX_GPU_CONTEXTS
/* Work queue item header definitions */ /* Work queue item header definitions */
#define WQ_STATUS_ACTIVE 1 #define WQ_STATUS_ACTIVE 1
...@@ -76,6 +75,7 @@ ...@@ -76,6 +75,7 @@
#define GUC_CTX_DESC_ATTR_RESET (1 << 4) #define GUC_CTX_DESC_ATTR_RESET (1 << 4)
#define GUC_CTX_DESC_ATTR_WQLOCKED (1 << 5) #define GUC_CTX_DESC_ATTR_WQLOCKED (1 << 5)
#define GUC_CTX_DESC_ATTR_PCH (1 << 6) #define GUC_CTX_DESC_ATTR_PCH (1 << 6)
#define GUC_CTX_DESC_ATTR_TERMINATED (1 << 7)
/* The guc control data is 10 DWORDs */ /* The guc control data is 10 DWORDs */
#define GUC_CTL_CTXINFO 0 #define GUC_CTL_CTXINFO 0
...@@ -108,6 +108,7 @@ ...@@ -108,6 +108,7 @@
#define GUC_CTL_DISABLE_SCHEDULER (1 << 4) #define GUC_CTL_DISABLE_SCHEDULER (1 << 4)
#define GUC_CTL_PREEMPTION_LOG (1 << 5) #define GUC_CTL_PREEMPTION_LOG (1 << 5)
#define GUC_CTL_ENABLE_SLPC (1 << 7) #define GUC_CTL_ENABLE_SLPC (1 << 7)
#define GUC_CTL_RESET_ON_PREMPT_FAILURE (1 << 8)
#define GUC_CTL_DEBUG 8 #define GUC_CTL_DEBUG 8
#define GUC_LOG_VERBOSITY_SHIFT 0 #define GUC_LOG_VERBOSITY_SHIFT 0
#define GUC_LOG_VERBOSITY_LOW (0 << GUC_LOG_VERBOSITY_SHIFT) #define GUC_LOG_VERBOSITY_LOW (0 << GUC_LOG_VERBOSITY_SHIFT)
...@@ -117,8 +118,9 @@ ...@@ -117,8 +118,9 @@
/* Verbosity range-check limits, without the shift */ /* Verbosity range-check limits, without the shift */
#define GUC_LOG_VERBOSITY_MIN 0 #define GUC_LOG_VERBOSITY_MIN 0
#define GUC_LOG_VERBOSITY_MAX 3 #define GUC_LOG_VERBOSITY_MAX 3
#define GUC_CTL_RSRVD 9
#define GUC_CTL_MAX_DWORDS (GUC_CTL_DEBUG + 1) #define GUC_CTL_MAX_DWORDS (GUC_CTL_RSRVD + 1)
struct guc_doorbell_info { struct guc_doorbell_info {
u32 db_status; u32 db_status;
...@@ -208,7 +210,9 @@ struct guc_context_desc { ...@@ -208,7 +210,9 @@ struct guc_context_desc {
u32 engine_presence; u32 engine_presence;
u32 reserved0[1]; u8 engine_suspended;
u8 reserved0[3];
u64 reserved1[1]; u64 reserved1[1];
u64 desc_private; u64 desc_private;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -68,12 +68,20 @@ static inline void intel_logical_ring_emit(struct intel_ringbuffer *ringbuf, ...@@ -68,12 +68,20 @@ static inline void intel_logical_ring_emit(struct intel_ringbuffer *ringbuf,
} }
/* Logical Ring Contexts */ /* Logical Ring Contexts */
/* One extra page is added before LRC for GuC as shared data */
#define LRC_GUCSHR_PN (0)
#define LRC_PPHWSP_PN (LRC_GUCSHR_PN + 1)
#define LRC_STATE_PN (LRC_PPHWSP_PN + 1)
void intel_lr_context_free(struct intel_context *ctx); void intel_lr_context_free(struct intel_context *ctx);
int intel_lr_context_deferred_create(struct intel_context *ctx, int intel_lr_context_deferred_create(struct intel_context *ctx,
struct intel_engine_cs *ring); struct intel_engine_cs *ring);
void intel_lr_context_unpin(struct drm_i915_gem_request *req); void intel_lr_context_unpin(struct drm_i915_gem_request *req);
void intel_lr_context_reset(struct drm_device *dev, void intel_lr_context_reset(struct drm_device *dev,
struct intel_context *ctx); struct intel_context *ctx);
uint64_t intel_lr_context_descriptor(struct intel_context *ctx,
struct intel_engine_cs *ring);
/* Execlists */ /* Execlists */
int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists); int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists);
......
...@@ -289,11 +289,14 @@ intel_lvds_mode_valid(struct drm_connector *connector, ...@@ -289,11 +289,14 @@ intel_lvds_mode_valid(struct drm_connector *connector,
{ {
struct intel_connector *intel_connector = to_intel_connector(connector); struct intel_connector *intel_connector = to_intel_connector(connector);
struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode; struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
int max_pixclk = to_i915(connector->dev)->max_dotclk_freq;
if (mode->hdisplay > fixed_mode->hdisplay) if (mode->hdisplay > fixed_mode->hdisplay)
return MODE_PANEL; return MODE_PANEL;
if (mode->vdisplay > fixed_mode->vdisplay) if (mode->vdisplay > fixed_mode->vdisplay)
return MODE_PANEL; return MODE_PANEL;
if (fixed_mode->clock > max_pixclk)
return MODE_CLOCK_HIGH;
return MODE_OK; return MODE_OK;
} }
...@@ -952,7 +955,7 @@ void intel_lvds_init(struct drm_device *dev) ...@@ -952,7 +955,7 @@ void intel_lvds_init(struct drm_device *dev)
if (HAS_PCH_SPLIT(dev)) { if (HAS_PCH_SPLIT(dev)) {
I915_WRITE(PCH_PP_CONTROL, I915_WRITE(PCH_PP_CONTROL,
I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS); I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS);
} else { } else if (INTEL_INFO(dev_priv)->gen < 5) {
I915_WRITE(PP_CONTROL, I915_WRITE(PP_CONTROL,
I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS);
} }
...@@ -982,6 +985,18 @@ void intel_lvds_init(struct drm_device *dev) ...@@ -982,6 +985,18 @@ void intel_lvds_init(struct drm_device *dev)
DRM_DEBUG_KMS("LVDS is not present in VBT, but enabled anyway\n"); DRM_DEBUG_KMS("LVDS is not present in VBT, but enabled anyway\n");
} }
/* Set the Panel Power On/Off timings if uninitialized. */
if (INTEL_INFO(dev_priv)->gen < 5 &&
I915_READ(PP_ON_DELAYS) == 0 && I915_READ(PP_OFF_DELAYS) == 0) {
/* Set T2 to 40ms and T5 to 200ms */
I915_WRITE(PP_ON_DELAYS, 0x019007d0);
/* Set T3 to 35ms and Tx to 200ms */
I915_WRITE(PP_OFF_DELAYS, 0x015e07d0);
DRM_DEBUG_KMS("Panel power timings uninitialized, setting defaults\n");
}
lvds_encoder = kzalloc(sizeof(*lvds_encoder), GFP_KERNEL); lvds_encoder = kzalloc(sizeof(*lvds_encoder), GFP_KERNEL);
if (!lvds_encoder) if (!lvds_encoder)
return; return;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -377,6 +377,13 @@ intel_ring_sync_index(struct intel_engine_cs *ring, ...@@ -377,6 +377,13 @@ intel_ring_sync_index(struct intel_engine_cs *ring,
return idx; return idx;
} }
static inline void
intel_flush_status_page(struct intel_engine_cs *ring, int reg)
{
drm_clflush_virt_range(&ring->status_page.page_addr[reg],
sizeof(uint32_t));
}
static inline u32 static inline u32
intel_read_status_page(struct intel_engine_cs *ring, intel_read_status_page(struct intel_engine_cs *ring,
int reg) int reg)
...@@ -413,12 +420,12 @@ intel_write_status_page(struct intel_engine_cs *ring, ...@@ -413,12 +420,12 @@ intel_write_status_page(struct intel_engine_cs *ring,
#define I915_GEM_HWS_SCRATCH_INDEX 0x40 #define I915_GEM_HWS_SCRATCH_INDEX 0x40
#define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT) #define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT)
void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf); struct intel_ringbuffer *
intel_engine_create_ringbuffer(struct intel_engine_cs *engine, int size);
int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev,
struct intel_ringbuffer *ringbuf); struct intel_ringbuffer *ringbuf);
void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf); void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf);
int intel_alloc_ringbuffer_obj(struct drm_device *dev, void intel_ringbuffer_free(struct intel_ringbuffer *ring);
struct intel_ringbuffer *ringbuf);
void intel_stop_ring_buffer(struct intel_engine_cs *ring); void intel_stop_ring_buffer(struct intel_engine_cs *ring);
void intel_cleanup_ring_buffer(struct intel_engine_cs *ring); void intel_cleanup_ring_buffer(struct intel_engine_cs *ring);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -1291,7 +1291,7 @@ static void intel_tv_find_better_format(struct drm_connector *connector) ...@@ -1291,7 +1291,7 @@ static void intel_tv_find_better_format(struct drm_connector *connector)
return; return;
for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) { for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
tv_mode = tv_modes + i; tv_mode = tv_modes + i;
if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) == if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
......
This diff is collapsed.
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