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>
!Idrivers/gpu/drm/i915/i915_gem_shrinker.c
</sect2>
</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>
<title> Tracing </title>
<para>
......
......@@ -40,6 +40,10 @@ i915-y += i915_cmd_parser.o \
intel_ringbuffer.o \
intel_uncore.o
# general-purpose microcontroller (GuC) support
i915-y += intel_guc_loader.o \
i915_guc_submission.o
# autogenerated null render state
i915-y += intel_renderstate_gen6.o \
intel_renderstate_gen7.o \
......
......@@ -94,7 +94,7 @@
#define CMD(op, opm, f, lm, fl, ...) \
{ \
.flags = (fl) | ((f) ? CMD_DESC_FIXED : 0), \
.cmd = { (op), (opm) }, \
.cmd = { (op), (opm) }, \
.length = { (lm) }, \
__VA_ARGS__ \
}
......@@ -124,14 +124,14 @@ static const struct drm_i915_cmd_descriptor common_cmds[] = {
CMD( MI_STORE_DWORD_INDEX, SMI, !F, 0xFF, R ),
CMD( MI_LOAD_REGISTER_IMM(1), SMI, !F, 0xFF, W,
.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 },
.bits = {{
.offset = 0,
.mask = MI_GLOBAL_GTT,
.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 },
.bits = {{
.offset = 0,
......@@ -1021,7 +1021,7 @@ static bool check_cmd(const struct intel_engine_cs *ring,
* only MI_LOAD_REGISTER_IMM commands.
*/
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");
return false;
}
......@@ -1035,7 +1035,7 @@ static bool check_cmd(const struct intel_engine_cs *ring,
* allowed mask/value pair given in the whitelist entry.
*/
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",
reg_addr);
return false;
......@@ -1213,6 +1213,7 @@ int i915_cmd_parser_get_version(void)
* 2. Allow access to the MI_PREDICATE_SRC0 and
* MI_PREDICATE_SRC1 registers.
* 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_
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
/* i915 resume handler doesn't set to 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;
} else {
pr_err("switched off\n");
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;
}
}
......@@ -435,6 +435,11 @@ static int i915_load_modeset_init(struct drm_device *dev)
* working irqs for e.g. gmbus and dp aux transfers. */
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);
if (ret)
goto cleanup_irq;
......@@ -476,6 +481,9 @@ static int i915_load_modeset_init(struct drm_device *dev)
i915_gem_context_fini(dev);
mutex_unlock(&dev->struct_mutex);
cleanup_irq:
mutex_lock(&dev->struct_mutex);
intel_guc_ucode_fini(dev);
mutex_unlock(&dev->struct_mutex);
drm_irq_uninstall(dev);
cleanup_gem_stolen:
i915_gem_cleanup_stolen(dev);
......@@ -791,6 +799,24 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
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
* @dev: DRM device
......@@ -971,8 +997,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
intel_setup_gmbus(dev);
intel_opregion_setup(dev);
intel_setup_bios(dev);
i915_gem_load(dev);
/* 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)
intel_device_info_runtime_init(dev);
intel_init_dpio(dev_priv);
if (INTEL_INFO(dev)->num_pipes) {
ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes);
if (ret)
......@@ -1128,6 +1154,7 @@ int i915_driver_unload(struct drm_device *dev)
flush_workqueue(dev_priv->wq);
mutex_lock(&dev->struct_mutex);
intel_guc_ucode_fini(dev);
i915_gem_cleanup_ringbuffer(dev);
i915_gem_context_fini(dev);
mutex_unlock(&dev->struct_mutex);
......
......@@ -362,6 +362,7 @@ static const struct intel_device_info intel_skylake_info = {
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
.has_llc = 1,
.has_ddi = 1,
.has_fpga_dbg = 1,
.has_fbc = 1,
GEN_DEFAULT_PIPEOFFSETS,
IVB_CURSOR_OFFSETS,
......@@ -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,
.has_llc = 1,
.has_ddi = 1,
.has_fpga_dbg = 1,
.has_fbc = 1,
GEN_DEFAULT_PIPEOFFSETS,
IVB_CURSOR_OFFSETS,
......@@ -386,6 +388,7 @@ static const struct intel_device_info intel_broxton_info = {
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
.num_pipes = 3,
.has_ddi = 1,
.has_fpga_dbg = 1,
.has_fbc = 1,
GEN_DEFAULT_PIPEOFFSETS,
IVB_CURSOR_OFFSETS,
......@@ -679,7 +682,7 @@ static int i915_drm_suspend_late(struct drm_device *drm_dev, bool hibernation)
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;
......@@ -812,7 +815,7 @@ static int i915_drm_resume_early(struct drm_device *dev)
return ret;
}
int i915_resume_legacy(struct drm_device *dev)
int i915_resume_switcheroo(struct drm_device *dev)
{
int ret;
......@@ -1552,6 +1555,15 @@ static int intel_runtime_resume(struct device *device)
gen6_update_ring_freq(dev);
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);
if (ret)
......@@ -1649,7 +1661,7 @@ static struct drm_driver driver = {
*/
.driver_features =
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME |
DRIVER_RENDER,
DRIVER_RENDER | DRIVER_MODESET,
.load = i915_driver_load,
.unload = i915_driver_unload,
.open = i915_driver_open,
......@@ -1658,10 +1670,6 @@ static struct drm_driver driver = {
.postclose = i915_driver_postclose,
.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)
.debugfs_init = i915_debugfs_init,
.debugfs_cleanup = i915_debugfs_cleanup,
......@@ -1704,7 +1712,6 @@ static int __init i915_init(void)
* either the i915.modeset prarameter or by the
* vga_text_mode_force boot option.
*/
driver.driver_features |= DRIVER_MODESET;
if (i915.modeset == 0)
driver.driver_features &= ~DRIVER_MODESET;
......@@ -1715,18 +1722,12 @@ static int __init i915_init(void)
#endif
if (!(driver.driver_features & DRIVER_MODESET)) {
driver.get_vblank_timestamp = NULL;
/* Silently fail loading to not upset userspace. */
DRM_DEBUG_DRIVER("KMS and UMS disabled.\n");
return 0;
}
/*
* 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)
if (i915.nuclear_pageflip)
driver.driver_features |= DRIVER_ATOMIC;
return drm_pci_init(&driver, &i915_pci_driver);
......
......@@ -50,13 +50,14 @@
#include <linux/intel-iommu.h>
#include <linux/kref.h>
#include <linux/pm_qos.h>
#include "intel_guc.h"
/* General customization:
*/
#define DRIVER_NAME "i915"
#define DRIVER_DESC "Intel Graphics"
#define DRIVER_DATE "20150731"
#define DRIVER_DATE "20150911"
#undef WARN_ON
/* Many gcc seem to no see through this and fall over :( */
......@@ -67,11 +68,11 @@
BUILD_BUG_ON(__i915_warn_cond); \
WARN(__i915_warn_cond, "WARN_ON(" #x ")"); })
#else
#define WARN_ON(x) WARN((x), "WARN_ON(" #x ")")
#define WARN_ON(x) WARN((x), "WARN_ON(%s)", #x )
#endif
#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", \
(long) (x), __func__);
......@@ -105,6 +106,11 @@
unlikely(__ret_warn_on); \
})
static inline const char *yesno(bool v)
{
return v ? "yes" : "no";
}
enum pipe {
INVALID_PIPE = -1,
PIPE_A = 0,
......@@ -549,7 +555,7 @@ struct drm_i915_error_state {
struct drm_i915_error_object {
int page_count;
u32 gtt_offset;
u64 gtt_offset;
u32 *pages[0];
} *ringbuffer, *batchbuffer, *wa_batchbuffer, *ctx, *hws_page;
......@@ -575,7 +581,7 @@ struct drm_i915_error_state {
u32 size;
u32 name;
u32 rseqno[I915_NUM_RINGS], wseqno;
u32 gtt_offset;
u64 gtt_offset;
u32 read_domains;
u32 write_domain;
s32 fence_reg:I915_MAX_NUM_FENCE_BITS;
......@@ -665,6 +671,8 @@ struct drm_i915_display_funcs {
uint32_t level);
void (*disable_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 {
......@@ -1693,7 +1701,7 @@ struct i915_execbuffer_params {
struct drm_file *file;
uint32_t dispatch_flags;
uint32_t args_batch_start_offset;
uint32_t batch_obj_vm_offset;
uint64_t batch_obj_vm_offset;
struct intel_engine_cs *ring;
struct drm_i915_gem_object *batch_obj;
struct intel_context *ctx;
......@@ -1716,6 +1724,8 @@ struct drm_i915_private {
struct i915_virtual_gpu vgpu;
struct intel_guc guc;
struct intel_csr csr;
/* Display CSR-related protection */
......@@ -1796,6 +1806,7 @@ struct drm_i915_private {
unsigned int fsb_freq, mem_freq, is_ddr3;
unsigned int skl_boot_cdclk;
unsigned int cdclk_freq, max_cdclk_freq;
unsigned int max_dotclk_freq;
unsigned int hpll_freq;
/**
......@@ -1963,6 +1974,11 @@ static inline struct drm_i915_private *dev_to_i915(struct device *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 */
#define for_each_ring(ring__, dev_priv__, i__) \
for ((i__) = 0; (i__) < I915_NUM_RINGS; (i__)++) \
......@@ -2520,7 +2536,8 @@ struct drm_i915_cmd_table {
#define HAS_HW_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 6)
#define HAS_LOGICAL_RING_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 8)
#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 OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical)
......@@ -2566,6 +2583,9 @@ struct drm_i915_cmd_table {
#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) || \
INTEL_INFO(dev)->gen >= 8)
......@@ -2584,6 +2604,7 @@ struct drm_i915_cmd_table {
#define INTEL_PCH_TYPE(dev) (__I915__(dev)->pch_type)
#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_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_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX)
#define HAS_PCH_NOP(dev) (INTEL_PCH_TYPE(dev) == PCH_NOP)
......@@ -2603,8 +2624,8 @@ struct drm_i915_cmd_table {
extern const struct drm_ioctl_desc i915_ioctls[];
extern int i915_max_ioctl;
extern int i915_suspend_legacy(struct drm_device *dev, pm_message_t state);
extern int i915_resume_legacy(struct drm_device *dev);
extern int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state);
extern int i915_resume_switcheroo(struct drm_device *dev);
/* i915_params.c */
struct i915_params {
......@@ -2637,6 +2658,7 @@ struct i915_params {
int use_mmio_flip;
int mmio_debug;
bool verbose_state_checks;
bool nuclear_pageflip;
int edp_vswing;
};
extern struct i915_params i915 __read_mostly;
......@@ -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 drm_gem_object *gem_obj, int flags);
unsigned long
i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
const struct i915_ggtt_view *view);
unsigned long
i915_gem_obj_offset(struct drm_i915_gem_object *o,
struct i915_address_space *vm);
static inline unsigned long
u64 i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
const struct i915_ggtt_view *view);
u64 i915_gem_obj_offset(struct drm_i915_gem_object *o,
struct i915_address_space *vm);
static inline u64
i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *o)
{
return i915_gem_obj_ggtt_offset_view(o, &i915_ggtt_view_normal);
......
......@@ -1005,12 +1005,14 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
if (!needs_clflush_after &&
obj->base.write_domain != I915_GEM_DOMAIN_CPU) {
if (i915_gem_clflush_object(obj, obj->pin_display))
i915_gem_chipset_flush(dev);
needs_clflush_after = true;
}
}
if (needs_clflush_after)
i915_gem_chipset_flush(dev);
else
obj->cache_dirty = true;
intel_fb_obj_flush(obj, false, ORIGIN_CPU);
return ret;
......@@ -3228,10 +3230,6 @@ int i915_vma_unbind(struct i915_vma *vma)
ret = i915_gem_object_wait_rendering(obj, false);
if (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) &&
vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
......@@ -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_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 =
flags & PIN_OFFSET_BIAS ? flags & PIN_OFFSET_MASK : 0;
u64 end =
......@@ -3414,7 +3413,7 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
* attempt to find space.
*/
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,
size,
flags & PIN_MAPPABLE ? "mappable" : "total",
......@@ -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 i915_vma *vma, *next;
int ret;
int ret = 0;
if (obj->cache_level == cache_level)
return 0;
goto out;
if (i915_gem_obj_is_pinned(obj)) {
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,
vma->node.color = cache_level;
obj->cache_level = cache_level;
out:
if (obj->cache_dirty &&
obj->base.write_domain != I915_GEM_DOMAIN_CPU &&
cpu_write_needs_clflush(obj)) {
......@@ -3738,6 +3738,15 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
level = I915_CACHE_NONE;
break;
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;
break;
case I915_CACHING_DISPLAY:
......@@ -4011,15 +4020,13 @@ i915_gem_object_do_pin(struct drm_i915_gem_object *obj,
return -EBUSY;
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,
"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",
ggtt_view ? "ggtt" : "ppgtt",
offset,
upper_32_bits(vma->node.start),
lower_32_bits(vma->node.start),
alignment,
!!(flags & PIN_MAPPABLE),
obj->map_and_fenceable);
......@@ -4679,6 +4686,22 @@ i915_gem_init_hw(struct drm_device *dev)
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: */
for_each_ring(ring, dev_priv, i) {
struct drm_i915_gem_request *req;
......@@ -4974,9 +4997,8 @@ void i915_gem_track_fb(struct drm_i915_gem_object *old,
}
/* All the new VM stuff */
unsigned long
i915_gem_obj_offset(struct drm_i915_gem_object *o,
struct i915_address_space *vm)
u64 i915_gem_obj_offset(struct drm_i915_gem_object *o,
struct i915_address_space *vm)
{
struct drm_i915_private *dev_priv = o->base.dev->dev_private;
struct i915_vma *vma;
......@@ -4996,9 +5018,8 @@ i915_gem_obj_offset(struct drm_i915_gem_object *o,
return -1;
}
unsigned long
i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
const struct i915_ggtt_view *view)
u64 i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
const struct i915_ggtt_view *view)
{
struct i915_address_space *ggtt = i915_obj_to_ggtt(o);
struct i915_vma *vma;
......
......@@ -332,6 +332,13 @@ int i915_gem_context_init(struct drm_device *dev)
if (WARN_ON(dev_priv->ring[RCS].default_context))
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) {
/* NB: intentionally left blank. We will allocate our own
* 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,
WARN((i915_gem_obj_ggtt_offset(obj) & ~I915_FENCE_START_MASK) ||
(size & -size) != size ||
(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);
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,
WARN((i915_gem_obj_ggtt_offset(obj) & ~I830_FENCE_START_MASK) ||
(size & -size) != size ||
(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);
pitch_val = obj->stride / 128;
......
This diff is collapsed.
......@@ -39,6 +39,8 @@ struct drm_i915_file_private;
typedef uint32_t gen6_pte_t;
typedef uint64_t gen8_pte_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)
......@@ -88,9 +90,18 @@ typedef uint64_t gen8_pde_t;
* PDPE | PDE | PTE | offset
* The difference as compared to normal x86 3 level page table is the PDPEs are
* 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_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_MASK 0x1ff
#define GEN8_PTE_SHIFT 12
......@@ -98,6 +109,9 @@ typedef uint64_t gen8_pde_t;
#define GEN8_LEGACY_PDPES 4
#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_CACHED_PDE_INDEX 0 /* WB LLC */
#define PPAT_CACHED_INDEX _PAGE_PAT /* WB LLCeLLC */
......@@ -135,7 +149,7 @@ struct i915_ggtt_view {
union {
struct {
unsigned long offset;
u64 offset;
unsigned int size;
} partial;
} params;
......@@ -241,9 +255,17 @@ struct i915_page_directory {
};
struct i915_page_directory_pointer {
/* struct page *page; */
DECLARE_BITMAP(used_pdpes, GEN8_LEGACY_PDPES);
struct i915_page_directory *page_directory[GEN8_LEGACY_PDPES];
struct i915_page_dma base;
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 {
......@@ -256,6 +278,7 @@ struct i915_address_space {
struct i915_page_scratch *scratch_page;
struct i915_page_table *scratch_pt;
struct i915_page_directory *scratch_pd;
struct i915_page_directory_pointer *scratch_pdp; /* GEN8+ & 48b PPGTT */
/**
* List of objects currently involved in rendering.
......@@ -341,8 +364,9 @@ struct i915_hw_ppgtt {
struct drm_mm_node node;
unsigned long pd_dirty_rings;
union {
struct i915_page_directory_pointer pdp;
struct i915_page_directory pd;
struct i915_pml4 pml4; /* GEN8+ & 48b PPGTT */
struct i915_page_directory_pointer pdp; /* GEN8+ */
struct i915_page_directory pd; /* GEN6-7 */
};
struct drm_i915_file_private *file_priv;
......@@ -436,24 +460,23 @@ static inline uint32_t gen6_pde_index(uint32_t addr)
temp = min(temp, length), \
start += temp, length -= temp)
#define gen8_for_each_pdpe(pd, pdp, start, length, temp, iter) \
for (iter = gen8_pdpe_index(start); \
pd = (pdp)->page_directory[iter], length > 0 && iter < GEN8_LEGACY_PDPES; \
#define gen8_for_each_pdpe(pd, pdp, start, length, temp, iter) \
for (iter = gen8_pdpe_index(start); \
pd = (pdp)->page_directory[iter], \
length > 0 && (iter < I915_PDPES_PER_PDP(dev)); \
iter++, \
temp = ALIGN(start+1, 1 << GEN8_PDPE_SHIFT) - start, \
temp = min(temp, length), \
start += temp, length -= temp)
/* Clamp length to the next page_directory boundary */
static inline uint64_t gen8_clamp_pd(uint64_t start, uint64_t length)
{
uint64_t next_pd = ALIGN(start + 1, 1 << GEN8_PDPE_SHIFT);
if (next_pd > (start + length))
return length;
return next_pd - start;
}
#define gen8_for_each_pml4e(pdp, pml4, start, length, temp, iter) \
for (iter = gen8_pml4e_index(start); \
pdp = (pml4)->pdps[iter], \
length > 0 && iter < GEN8_PML4ES_PER_PML4; \
iter++, \
temp = ALIGN(start+1, 1ULL << GEN8_PML4E_SHIFT) - start, \
temp = min(temp, length), \
start += temp, length -= temp)
static inline uint32_t gen8_pte_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)
{
WARN_ON(1); /* For 64B */
return 0;
return (address >> GEN8_PML4E_SHIFT) & GEN8_PML4E_MASK;
}
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 = {
int
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_object *obj;
int ret;
......@@ -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))
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,
(char __user *)(unsigned long)args->user_ptr, args->user_size))
return -EFAULT;
......
......@@ -30,11 +30,6 @@
#include <generated/utsrelease.h>
#include "i915_drv.h"
static const char *yesno(int v)
{
return v ? "yes" : "no";
}
static const char *ring_str(int ring)
{
switch (ring) {
......@@ -197,8 +192,9 @@ static void print_error_buffers(struct drm_i915_error_state_buf *m,
err_printf(m, " %s [%d]:\n", name, count);
while (count--) {
err_printf(m, " %08x %8u %02x %02x [ ",
err->gtt_offset,
err_printf(m, " %08x_%08x %8u %02x %02x [ ",
upper_32_bits(err->gtt_offset),
lower_32_bits(err->gtt_offset),
err->size,
err->read_domains,
err->write_domain);
......@@ -427,15 +423,17 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
err_printf(m, " (submitted by %s [%d])",
error->ring[i].comm,
error->ring[i].pid);
err_printf(m, " --- gtt_offset = 0x%08x\n",
obj->gtt_offset);
err_printf(m, " --- gtt_offset = 0x%08x %08x\n",
upper_32_bits(obj->gtt_offset),
lower_32_bits(obj->gtt_offset));
print_error_obj(m, obj);
}
obj = error->ring[i].wa_batchbuffer;
if (obj) {
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);
}
......@@ -454,22 +452,22 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
if ((obj = error->ring[i].ringbuffer)) {
err_printf(m, "%s --- ringbuffer = 0x%08x\n",
dev_priv->ring[i].name,
obj->gtt_offset);
lower_32_bits(obj->gtt_offset));
print_error_obj(m, obj);
}
if ((obj = error->ring[i].hws_page)) {
err_printf(m, "%s --- HW Status = 0x%08x\n",
dev_priv->ring[i].name,
obj->gtt_offset);
err_printf(m, "%s --- HW Status = 0x%08llx\n",
dev_priv->ring[i].name,
obj->gtt_offset + LRC_PPHWSP_PN * PAGE_SIZE);
offset = 0;
for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
err_printf(m, "[%04x] %08x %08x %08x %08x\n",
offset,
obj->pages[0][elt],
obj->pages[0][elt+1],
obj->pages[0][elt+2],
obj->pages[0][elt+3]);
obj->pages[LRC_PPHWSP_PN][elt],
obj->pages[LRC_PPHWSP_PN][elt+1],
obj->pages[LRC_PPHWSP_PN][elt+2],
obj->pages[LRC_PPHWSP_PN][elt+3]);
offset += 16;
}
}
......@@ -477,13 +475,14 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
if ((obj = error->ring[i].ctx)) {
err_printf(m, "%s --- HW Context = 0x%08x\n",
dev_priv->ring[i].name,
obj->gtt_offset);
lower_32_bits(obj->gtt_offset));
print_error_obj(m, 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) {
err_printf(m, "[%04x] %08x %08x %08x %08x\n",
elt * 4,
......@@ -591,7 +590,7 @@ i915_error_object_create(struct drm_i915_private *dev_priv,
int num_pages;
bool use_ggtt;
int i = 0;
u32 reloc_offset;
u64 reloc_offset;
if (src == NULL || src->pages == NULL)
return NULL;
......
......@@ -38,10 +38,6 @@
#define GS_MIA_SHIFT 16
#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 UOS_RSA_SCRATCH_0 0xc200
......@@ -56,10 +52,18 @@
#define UOS_MOVE (1<<4)
#define START_DMA (1<<0)
#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 GEN9LP_GT_PM_CONFIG 0x138140
#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_INVALIDATE (1<<0)
......@@ -80,7 +84,8 @@
GUC_ENABLE_READ_CACHE_LOGIC | \
GUC_ENABLE_MIA_CACHING | \
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_TRIGGER (1<<0)
......
This diff is collapsed.
This diff is collapsed.
......@@ -51,6 +51,7 @@ struct i915_params i915 __read_mostly = {
.use_mmio_flip = 0,
.mmio_debug = 0,
.verbose_state_checks = 1,
.nuclear_pageflip = 0,
.edp_vswing = 0,
.enable_guc_submission = false,
.guc_log_level = -1,
......@@ -177,6 +178,10 @@ module_param_named(verbose_state_checks, i915.verbose_state_checks, bool, 0600);
MODULE_PARM_DESC(verbose_state_checks,
"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 */
module_param_named_unsafe(edp_vswing, i915.edp_vswing, int, 0400);
MODULE_PARM_DESC(edp_vswing,
......
This diff is collapsed.
......@@ -186,33 +186,49 @@ DEFINE_EVENT(i915_va, i915_va_alloc,
TP_ARGS(vm, start, length, name)
);
DECLARE_EVENT_CLASS(i915_page_table_entry,
TP_PROTO(struct i915_address_space *vm, u32 pde, u64 start, u64 pde_shift),
TP_ARGS(vm, pde, start, pde_shift),
DECLARE_EVENT_CLASS(i915_px_entry,
TP_PROTO(struct i915_address_space *vm, u32 px, u64 start, u64 px_shift),
TP_ARGS(vm, px, start, px_shift),
TP_STRUCT__entry(
__field(struct i915_address_space *, vm)
__field(u32, pde)
__field(u32, px)
__field(u64, start)
__field(u64, end)
),
TP_fast_assign(
__entry->vm = vm;
__entry->pde = pde;
__entry->px = px;
__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)",
__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_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
* bitmap_scnprintf. Each 32 bits is 8 HEX digits followed by comma */
#define TRACE_PT_SIZE(bits) \
......
......@@ -40,6 +40,19 @@
#define INTEL_VGT_IF_VERSION \
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 {
uint64_t magic; /* VGT_MAGIC */
uint16_t version_major;
......@@ -70,11 +83,28 @@ struct vgt_if {
uint32_t rsv3[0x200 - 24]; /* pad to half page */
/*
* The bottom half page is for response from Gfx driver to hypervisor.
* Set to reserved fields temporarily by now.
*/
uint32_t rsv4;
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;
#define vgtif_reg(x) \
......
......@@ -85,22 +85,14 @@ intel_connector_atomic_get_property(struct drm_connector *connector,
struct drm_crtc_state *
intel_crtc_duplicate_state(struct drm_crtc *crtc)
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_crtc_state *crtc_state;
if (WARN_ON(!intel_crtc->config))
crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
else
crtc_state = kmemdup(intel_crtc->config,
sizeof(*intel_crtc->config), GFP_KERNEL);
crtc_state = kmemdup(crtc->state, sizeof(*crtc_state), GFP_KERNEL);
if (!crtc_state)
return NULL;
__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base);
crtc_state->base.crtc = crtc;
return &crtc_state->base;
}
......@@ -149,9 +141,6 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
int i, j;
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:
......
......@@ -76,11 +76,7 @@ intel_plane_duplicate_state(struct drm_plane *plane)
struct drm_plane_state *state;
struct intel_plane_state *intel_state;
if (WARN_ON(!plane->state))
intel_state = intel_create_plane_state(plane);
else
intel_state = kmemdup(plane->state, sizeof(*intel_state),
GFP_KERNEL);
intel_state = kmemdup(plane->state, sizeof(*intel_state), GFP_KERNEL);
if (!intel_state)
return NULL;
......
......@@ -1350,21 +1350,3 @@ intel_parse_bios(struct drm_device *dev)
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 {
struct psr_table psr_table[16];
} __packed;
void intel_setup_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)
intel_dp->DP = intel_dig_port->saved_port_bits |
DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
}
static struct intel_encoder *
......@@ -1242,9 +1241,10 @@ hsw_ddi_calculate_wrpll(int clock /* in Hz */,
static bool
hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
struct intel_crtc_state *crtc_state,
struct intel_encoder *intel_encoder,
int clock)
struct intel_encoder *intel_encoder)
{
int clock = crtc_state->port_clock;
if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
struct intel_shared_dpll *pll;
uint32_t val;
......@@ -1523,11 +1523,11 @@ skl_ddi_calculate_wrpll(int clock /* in Hz */,
static bool
skl_ddi_pll_select(struct intel_crtc *intel_crtc,
struct intel_crtc_state *crtc_state,
struct intel_encoder *intel_encoder,
int clock)
struct intel_encoder *intel_encoder)
{
struct intel_shared_dpll *pll;
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
......@@ -1615,14 +1615,14 @@ static const struct bxt_clk_div bxt_dp_clk_val[] = {
static bool
bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
struct intel_crtc_state *crtc_state,
struct intel_encoder *intel_encoder,
int clock)
struct intel_encoder *intel_encoder)
{
struct intel_shared_dpll *pll;
struct bxt_clk_div clk_div = {0};
int vco = 0;
uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
uint32_t lanestagger;
int clock = crtc_state->port_clock;
if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
intel_clock_t best_clock;
......@@ -1750,17 +1750,16 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
struct drm_device *dev = intel_crtc->base.dev;
struct intel_encoder *intel_encoder =
intel_ddi_get_crtc_new_encoder(crtc_state);
int clock = crtc_state->port_clock;
if (IS_SKYLAKE(dev))
return skl_ddi_pll_select(intel_crtc, crtc_state,
intel_encoder, clock);
intel_encoder);
else if (IS_BROXTON(dev))
return bxt_ddi_pll_select(intel_crtc, crtc_state,
intel_encoder, clock);
intel_encoder);
else
return hsw_ddi_pll_select(intel_crtc, crtc_state,
intel_encoder, clock);
intel_encoder);
}
void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
......@@ -1893,7 +1892,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
} else
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) {
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)
} else
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 {
WARN(1, "Invalid encoder type %d for pipe %c\n",
intel_encoder->type, pipe_name(pipe));
......@@ -2289,6 +2288,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
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_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
......@@ -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_MST:
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);
break;
default:
......@@ -3215,7 +3218,15 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
goto err;
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
......
This diff is collapsed.
This diff is collapsed.
......@@ -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 drm_atomic_state *state;
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_connector *drm_connector;
struct intel_connector *connector, *found = NULL;
......@@ -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);
rate = intel_dp_max_link_rate(intel_dp);
if (intel_dp->num_sink_rates) {
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->lane_count = lane_count;
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;
......@@ -184,6 +175,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
if (intel_dp->active_mst_links == 0) {
enum port port = intel_ddi_get_encoder_port(encoder);
intel_dp_set_link_params(intel_dp, intel_crtc->config);
/* FIXME: add support for SKL */
if (INTEL_INFO(dev)->gen < 9)
I915_WRITE(PORT_CLK_SEL(port),
......@@ -286,6 +279,10 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
break;
}
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_ddi_clock_get(&intel_dig_port->base, pipe_config);
......
......@@ -142,6 +142,7 @@ struct intel_encoder {
void (*mode_set)(struct intel_encoder *intel_encoder);
void (*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
* the encoder is active. If the encoder is enabled it also set the pipe
* it is connected to in the pipe parameter. */
......@@ -423,6 +424,8 @@ struct intel_crtc_state {
/* Used by SDVO (and if we ever fix it, HDMI). */
unsigned pixel_multiplier;
uint8_t lane_count;
/* Panel fitter controls for gen2-gen4 + VLV */
struct {
u32 control;
......@@ -561,6 +564,8 @@ struct intel_crtc {
int scanline_offset;
unsigned start_vbl_count;
ktime_t start_vbl_time;
struct intel_crtc_atomic_commit atomic;
/* scalers available on this crtc */
......@@ -657,13 +662,14 @@ struct cxsr_latency {
struct intel_hdmi {
u32 hdmi_reg;
int ddc_bus;
uint32_t color_range;
bool limited_color_range;
bool color_range_auto;
bool has_hdmi_sink;
bool has_audio;
enum hdmi_force_audio force_audio;
bool rgb_quant_range_selectable;
enum hdmi_picture_aspect aspect_ratio;
struct intel_connector *attached_connector;
void (*write_infoframe)(struct drm_encoder *encoder,
enum hdmi_infoframe_type type,
const void *frame, ssize_t len);
......@@ -696,23 +702,29 @@ enum link_m_n_set {
M2_N2
};
struct sink_crc {
bool started;
u8 last_crc[6];
int last_count;
};
struct intel_dp {
uint32_t output_reg;
uint32_t aux_ch_ctl_reg;
uint32_t DP;
int link_rate;
uint8_t lane_count;
bool has_audio;
enum hdmi_force_audio force_audio;
uint32_t color_range;
bool limited_color_range;
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 psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE];
uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
/* sink rates as reported by DP_SUPPORTED_LINK_RATES */
uint8_t num_sink_rates;
int sink_rates[DP_MAX_SUPPORTED_RATES];
struct sink_crc sink_crc;
struct drm_dp_aux aux;
uint8_t train_set[4];
int panel_power_up_delay;
......@@ -735,7 +747,6 @@ struct intel_dp {
enum pipe pps_pipe;
struct edp_power_seq pps_delays;
bool use_tps3;
bool can_mst; /* this port supports mst */
bool is_mst;
int active_mst_links;
......@@ -770,6 +781,7 @@ struct intel_digital_port {
struct intel_dp dp;
struct intel_hdmi hdmi;
enum irqreturn (*hpd_pulse)(struct intel_digital_port *, bool);
bool release_cl2_override;
};
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 */
};
static inline int
static inline enum dpio_channel
vlv_dport_to_channel(struct intel_digital_port *dport)
{
switch (dport->port) {
......@@ -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)
{
switch (pipe) {
......@@ -987,6 +1013,7 @@ void i915_audio_component_cleanup(struct drm_i915_private *dev_priv);
extern const struct drm_plane_funcs intel_plane_funcs;
bool intel_has_pending_fb_unpin(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_idle(struct drm_device *dev);
void intel_crtc_restore_mode(struct drm_crtc *crtc);
......@@ -995,8 +1022,6 @@ void intel_encoder_destroy(struct drm_encoder *encoder);
int intel_connector_init(struct intel_connector *);
struct intel_connector *intel_connector_alloc(void);
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,
struct intel_encoder *encoder);
struct drm_encoder *intel_best_encoder(struct drm_connector *connector);
......@@ -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);
bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
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_complete_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);
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 */
void intel_init_clock_gating(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);
int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv);
void intel_pipe_update_start(struct intel_crtc *crtc,
uint32_t *start_vbl_count);
void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count);
void intel_pipe_update_start(struct intel_crtc *crtc);
void intel_pipe_update_end(struct intel_crtc *crtc);
/* intel_tv.c */
void intel_tv_init(struct drm_device *dev);
......
......@@ -654,6 +654,7 @@ intel_dsi_mode_valid(struct drm_connector *connector,
{
struct intel_connector *intel_connector = to_intel_connector(connector);
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");
......@@ -667,6 +668,8 @@ intel_dsi_mode_valid(struct drm_connector *connector,
return MODE_PANEL;
if (mode->vdisplay > fixed_mode->vdisplay)
return MODE_PANEL;
if (fixed_mode->clock > max_dotclk)
return MODE_CLOCK_HIGH;
}
return MODE_OK;
......
......@@ -201,6 +201,8 @@ intel_dvo_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
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)
return MODE_NO_DBLESCAN;
......@@ -212,8 +214,13 @@ intel_dvo_mode_valid(struct drm_connector *connector,
return MODE_PANEL;
if (mode->vdisplay > intel_dvo->panel_fixed_mode->vdisplay)
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);
}
......
......@@ -263,7 +263,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
/* 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,
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 @@
* 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_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_NORMAL 2
#define GUC_CTX_PRIORITY_LOW 3
#define GUC_CTX_PRIORITY_KMD_NORMAL 2
#define GUC_CTX_PRIORITY_NORMAL 3
#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 */
#define WQ_STATUS_ACTIVE 1
......@@ -76,6 +75,7 @@
#define GUC_CTX_DESC_ATTR_RESET (1 << 4)
#define GUC_CTX_DESC_ATTR_WQLOCKED (1 << 5)
#define GUC_CTX_DESC_ATTR_PCH (1 << 6)
#define GUC_CTX_DESC_ATTR_TERMINATED (1 << 7)
/* The guc control data is 10 DWORDs */
#define GUC_CTL_CTXINFO 0
......@@ -108,6 +108,7 @@
#define GUC_CTL_DISABLE_SCHEDULER (1 << 4)
#define GUC_CTL_PREEMPTION_LOG (1 << 5)
#define GUC_CTL_ENABLE_SLPC (1 << 7)
#define GUC_CTL_RESET_ON_PREMPT_FAILURE (1 << 8)
#define GUC_CTL_DEBUG 8
#define GUC_LOG_VERBOSITY_SHIFT 0
#define GUC_LOG_VERBOSITY_LOW (0 << GUC_LOG_VERBOSITY_SHIFT)
......@@ -117,8 +118,9 @@
/* Verbosity range-check limits, without the shift */
#define GUC_LOG_VERBOSITY_MIN 0
#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 {
u32 db_status;
......@@ -208,7 +210,9 @@ struct guc_context_desc {
u32 engine_presence;
u32 reserved0[1];
u8 engine_suspended;
u8 reserved0[3];
u64 reserved1[1];
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,
}
/* 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);
int intel_lr_context_deferred_create(struct intel_context *ctx,
struct intel_engine_cs *ring);
void intel_lr_context_unpin(struct drm_i915_gem_request *req);
void intel_lr_context_reset(struct drm_device *dev,
struct intel_context *ctx);
uint64_t intel_lr_context_descriptor(struct intel_context *ctx,
struct intel_engine_cs *ring);
/* 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,
{
struct intel_connector *intel_connector = to_intel_connector(connector);
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)
return MODE_PANEL;
if (mode->vdisplay > fixed_mode->vdisplay)
return MODE_PANEL;
if (fixed_mode->clock > max_pixclk)
return MODE_CLOCK_HIGH;
return MODE_OK;
}
......@@ -952,7 +955,7 @@ void intel_lvds_init(struct drm_device *dev)
if (HAS_PCH_SPLIT(dev)) {
I915_WRITE(PCH_PP_CONTROL,
I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS);
} else {
} else if (INTEL_INFO(dev_priv)->gen < 5) {
I915_WRITE(PP_CONTROL,
I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS);
}
......@@ -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");
}
/* 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);
if (!lvds_encoder)
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,
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
intel_read_status_page(struct intel_engine_cs *ring,
int reg)
......@@ -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_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,
struct intel_ringbuffer *ringbuf);
void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf);
int intel_alloc_ringbuffer_obj(struct drm_device *dev,
struct intel_ringbuffer *ringbuf);
void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf);
void intel_ringbuffer_free(struct intel_ringbuffer *ring);
void intel_stop_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)
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;
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