Commit ecb889e6 authored by Dave Airlie's avatar Dave Airlie

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

> Bunch of stuff for 3.16 still:
> - Mipi dsi panel support for byt. Finally! From Shobhit&others. I've
>   squeezed this in since it's a regression compared to vbios and we've
>   been ridiculed about it a bit too often ...
> - connection_mutex deadlock fix in get_connector (only affects i915).
> - Core patches from Matt's primary plane from Matt Roper, I've pushed the
>   i915 stuff to 3.17.
> - vlv power well sequencing fixes from Jesse.
> - Fix for cursor size changes from Chris.
> - agpbusy fixes from Ville.
> - A few smaller things.
>

* tag 'drm-intel-fixes-2014-06-06' of git://anongit.freedesktop.org/drm-intel: (32 commits)
  drm/i915: BDW: Adding missing cursor offsets.
  drm: Fix getconnector connection_mutex locking
  drm/i915/bdw: Only use 2g GGTT for 32b platforms
  drm/i915: Nuke pipe A quirk on i830M
  drm/i915: fix display power sw state reporting
  drm/i915: Always apply cursor width changes
  drm/i915: tell the user if both KMS and UMS are disabled
  drm/plane-helper: Add drm_plane_helper_check_update() (v3)
  drm: Check CRTC compatibility in setplane
  drm/i915: use VBT to determine whether to enumerate the VGA port
  drm/i915: Don't WARN about ring idle bit on gen2
  drm/i915: Silence the WARN if the user tries to GTT mmap an incoherent object
  drm/i915: Move the C3 LP write bit setup to gen3_init_clock_gating() for KMS
  drm/i915: Enable interrupt-based AGPBUSY# enable on 85x
  drm/i915: Flip the sense of AGPBUSY_DIS bit
  drm/i915: Set AGPBUSY# bit in init_clock_gating
  drm/i915/vlv: add pll assertion when disabling DPIO common well
  drm/i915/vlv: move DPIO common reset de-assert into __vlv_set_power_well
  drm/i915/vlv: re-order power wells so DPIO common comes after TX
  drm/i915/vlv: move CRI refclk enable into __vlv_set_power_well
  ...
parents c7560f12 15d24aa5
...@@ -2178,6 +2178,13 @@ int drm_mode_setplane(struct drm_device *dev, void *data, ...@@ -2178,6 +2178,13 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
goto out; goto out;
} }
/* Check whether this plane is usable on this CRTC */
if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) {
DRM_DEBUG_KMS("Invalid crtc for plane\n");
ret = -EINVAL;
goto out;
}
fb = drm_framebuffer_lookup(dev, plane_req->fb_id); fb = drm_framebuffer_lookup(dev, plane_req->fb_id);
if (!fb) { if (!fb) {
DRM_DEBUG_KMS("Unknown framebuffer ID %d\n", DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_rect.h> #include <drm/drm_rect.h>
#include <drm/drm_plane_helper.h> #include <drm/drm_plane_helper.h>
...@@ -73,6 +74,79 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc, ...@@ -73,6 +74,79 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
return count; return count;
} }
/**
* drm_plane_helper_check_update() - Check plane update for validity
* @plane: plane object to update
* @crtc: owning CRTC of owning plane
* @fb: framebuffer to flip onto plane
* @src: source coordinates in 16.16 fixed point
* @dest: integer destination coordinates
* @clip: integer clipping coordinates
* @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point
* @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point
* @can_position: is it legal to position the plane such that it
* doesn't cover the entire crtc? This will generally
* only be false for primary planes.
* @can_update_disabled: can the plane be updated while the crtc
* is disabled?
* @visible: output parameter indicating whether plane is still visible after
* clipping
*
* Checks that a desired plane update is valid. Drivers that provide
* their own plane handling rather than helper-provided implementations may
* still wish to call this function to avoid duplication of error checking
* code.
*
* RETURNS:
* Zero if update appears valid, error code on failure
*/
int drm_plane_helper_check_update(struct drm_plane *plane,
struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_rect *src,
struct drm_rect *dest,
const struct drm_rect *clip,
int min_scale,
int max_scale,
bool can_position,
bool can_update_disabled,
bool *visible)
{
int hscale, vscale;
if (!crtc->enabled && !can_update_disabled) {
DRM_DEBUG_KMS("Cannot update plane of a disabled CRTC.\n");
return -EINVAL;
}
/* Check scaling */
hscale = drm_rect_calc_hscale(src, dest, min_scale, max_scale);
vscale = drm_rect_calc_vscale(src, dest, min_scale, max_scale);
if (hscale < 0 || vscale < 0) {
DRM_DEBUG_KMS("Invalid scaling of plane\n");
return -ERANGE;
}
*visible = drm_rect_clip_scaled(src, dest, clip, hscale, vscale);
if (!*visible)
/*
* Plane isn't visible; some drivers can handle this
* so we just return success here. Drivers that can't
* (including those that use the primary plane helper's
* update function) will return an error from their
* update_plane handler.
*/
return 0;
if (!can_position && !drm_rect_equals(dest, clip)) {
DRM_DEBUG_KMS("Plane must cover entire CRTC\n");
return -EINVAL;
}
return 0;
}
EXPORT_SYMBOL(drm_plane_helper_check_update);
/** /**
* drm_primary_helper_update() - Helper for primary plane update * drm_primary_helper_update() - Helper for primary plane update
* @plane: plane object to update * @plane: plane object to update
...@@ -121,57 +195,42 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, ...@@ -121,57 +195,42 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
.x = src_x >> 16, .x = src_x >> 16,
.y = src_y >> 16, .y = src_y >> 16,
}; };
struct drm_rect src = {
.x1 = src_x,
.y1 = src_y,
.x2 = src_x + src_w,
.y2 = src_y + src_h,
};
struct drm_rect dest = { struct drm_rect dest = {
.x1 = crtc_x, .x1 = crtc_x,
.y1 = crtc_y, .y1 = crtc_y,
.x2 = crtc_x + crtc_w, .x2 = crtc_x + crtc_w,
.y2 = crtc_y + crtc_h, .y2 = crtc_y + crtc_h,
}; };
struct drm_rect clip = { const struct drm_rect clip = {
.x2 = crtc->mode.hdisplay, .x2 = crtc->mode.hdisplay,
.y2 = crtc->mode.vdisplay, .y2 = crtc->mode.vdisplay,
}; };
struct drm_connector **connector_list; struct drm_connector **connector_list;
int num_connectors, ret; int num_connectors, ret;
bool visible;
if (!crtc->enabled) { ret = drm_plane_helper_check_update(plane, crtc, fb,
DRM_DEBUG_KMS("Cannot update primary plane of a disabled CRTC.\n"); &src, &dest, &clip,
return -EINVAL; DRM_PLANE_HELPER_NO_SCALING,
} DRM_PLANE_HELPER_NO_SCALING,
false, false, &visible);
/* Disallow subpixel positioning */
if ((src_x | src_y | src_w | src_h) & SUBPIXEL_MASK) {
DRM_DEBUG_KMS("Primary plane does not support subpixel positioning\n");
return -EINVAL;
}
/* Primary planes are locked to their owning CRTC */
if (plane->possible_crtcs != drm_crtc_mask(crtc)) {
DRM_DEBUG_KMS("Cannot change primary plane CRTC\n");
return -EINVAL;
}
/* Disallow scaling */
src_w >>= 16;
src_h >>= 16;
if (crtc_w != src_w || crtc_h != src_h) {
DRM_DEBUG_KMS("Can't scale primary plane\n");
return -EINVAL;
}
/* Make sure primary plane covers entire CRTC */
drm_rect_intersect(&dest, &clip);
if (dest.x1 != 0 || dest.y1 != 0 ||
dest.x2 != crtc->mode.hdisplay || dest.y2 != crtc->mode.vdisplay) {
DRM_DEBUG_KMS("Primary plane must cover entire CRTC\n");
return -EINVAL;
}
/* Framebuffer must be big enough to cover entire plane */
ret = drm_crtc_check_viewport(crtc, crtc_x, crtc_y, &crtc->mode, fb);
if (ret) if (ret)
return ret; return ret;
if (!visible)
/*
* Primary plane isn't visible. Note that unless a driver
* provides their own disable function, this will just
* wind up returning -EINVAL to userspace.
*/
return plane->funcs->disable_plane(plane);
/* Find current connectors for CRTC */ /* Find current connectors for CRTC */
num_connectors = get_connectors_for_crtc(crtc, NULL, 0); num_connectors = get_connectors_for_crtc(crtc, NULL, 0);
BUG_ON(num_connectors == 0); BUG_ON(num_connectors == 0);
......
...@@ -62,6 +62,7 @@ i915-y += dvo_ch7017.o \ ...@@ -62,6 +62,7 @@ i915-y += dvo_ch7017.o \
intel_dsi_cmd.o \ intel_dsi_cmd.o \
intel_dsi.o \ intel_dsi.o \
intel_dsi_pll.o \ intel_dsi_pll.o \
intel_dsi_panel_vbt.o \
intel_dvo.o \ intel_dvo.o \
intel_hdmi.o \ intel_hdmi.o \
intel_i2c.o \ intel_i2c.o \
......
...@@ -2353,10 +2353,14 @@ static int i915_display_info(struct seq_file *m, void *unused) ...@@ -2353,10 +2353,14 @@ static int i915_display_info(struct seq_file *m, void *unused)
active = cursor_position(dev, crtc->pipe, &x, &y); active = cursor_position(dev, crtc->pipe, &x, &y);
seq_printf(m, "\tcursor visible? %s, position (%d, %d), addr 0x%08x, active? %s\n", seq_printf(m, "\tcursor visible? %s, position (%d, %d), addr 0x%08x, active? %s\n",
yesno(crtc->cursor_visible), yesno(crtc->cursor_base),
x, y, crtc->cursor_addr, x, y, crtc->cursor_addr,
yesno(active)); yesno(active));
} }
seq_printf(m, "\tunderrun reporting: cpu=%s pch=%s \n",
yesno(!crtc->cpu_fifo_underrun_disabled),
yesno(!crtc->pch_fifo_underrun_disabled));
} }
seq_printf(m, "\n"); seq_printf(m, "\n");
......
...@@ -321,6 +321,7 @@ static const struct intel_device_info intel_broadwell_m_info = { ...@@ -321,6 +321,7 @@ static const struct intel_device_info intel_broadwell_m_info = {
.has_ddi = 1, .has_ddi = 1,
.has_fbc = 1, .has_fbc = 1,
GEN_DEFAULT_PIPEOFFSETS, GEN_DEFAULT_PIPEOFFSETS,
IVB_CURSOR_OFFSETS,
}; };
static const struct intel_device_info intel_broadwell_gt3d_info = { static const struct intel_device_info intel_broadwell_gt3d_info = {
...@@ -331,6 +332,7 @@ static const struct intel_device_info intel_broadwell_gt3d_info = { ...@@ -331,6 +332,7 @@ static const struct intel_device_info intel_broadwell_gt3d_info = {
.has_ddi = 1, .has_ddi = 1,
.has_fbc = 1, .has_fbc = 1,
GEN_DEFAULT_PIPEOFFSETS, GEN_DEFAULT_PIPEOFFSETS,
IVB_CURSOR_OFFSETS,
}; };
static const struct intel_device_info intel_broadwell_gt3m_info = { static const struct intel_device_info intel_broadwell_gt3m_info = {
...@@ -811,17 +813,17 @@ int i915_reset(struct drm_device *dev) ...@@ -811,17 +813,17 @@ int i915_reset(struct drm_device *dev)
} }
/* /*
* FIXME: This is horribly race against concurrent pageflip and * FIXME: This races pretty badly against concurrent holders of
* vblank wait ioctls since they can observe dev->irqs_disabled * ring interrupts. This is possible since we've started to drop
* being false when they shouldn't be able to. * dev->struct_mutex in select places when waiting for the gpu.
*/ */
drm_irq_uninstall(dev);
drm_irq_install(dev, dev->pdev->irq);
/* rps/rc6 re-init is necessary to restore state lost after the /*
* reset and the re-install of drm irq. Skip for ironlake per * rps/rc6 re-init is necessary to restore state lost after the
* reset and the re-install of gt irqs. Skip for ironlake per
* previous concerns that it doesn't respond well to some forms * previous concerns that it doesn't respond well to some forms
* of re-init after reset. */ * of re-init after reset.
*/
if (INTEL_INFO(dev)->gen > 5) if (INTEL_INFO(dev)->gen > 5)
intel_reset_gt_powersave(dev); intel_reset_gt_powersave(dev);
...@@ -1583,6 +1585,7 @@ static int __init i915_init(void) ...@@ -1583,6 +1585,7 @@ static int __init i915_init(void)
driver.get_vblank_timestamp = NULL; driver.get_vblank_timestamp = NULL;
#ifndef CONFIG_DRM_I915_UMS #ifndef CONFIG_DRM_I915_UMS
/* Silently fail loading to not upset userspace. */ /* Silently fail loading to not upset userspace. */
DRM_DEBUG_DRIVER("KMS and UMS disabled.\n");
return 0; return 0;
#endif #endif
} }
......
...@@ -1207,6 +1207,7 @@ struct intel_vbt_data { ...@@ -1207,6 +1207,7 @@ struct intel_vbt_data {
unsigned int lvds_use_ssc:1; unsigned int lvds_use_ssc:1;
unsigned int display_clock_mode:1; unsigned int display_clock_mode:1;
unsigned int fdi_rx_polarity_inverted:1; unsigned int fdi_rx_polarity_inverted:1;
unsigned int has_mipi:1;
int lvds_ssc_freq; int lvds_ssc_freq;
unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */ unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
...@@ -1230,6 +1231,7 @@ struct intel_vbt_data { ...@@ -1230,6 +1231,7 @@ struct intel_vbt_data {
/* MIPI DSI */ /* MIPI DSI */
struct { struct {
u16 port;
u16 panel_id; u16 panel_id;
struct mipi_config *config; struct mipi_config *config;
struct mipi_pps_data *pps; struct mipi_pps_data *pps;
......
...@@ -1544,7 +1544,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ...@@ -1544,7 +1544,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
/* Access to snoopable pages through the GTT is incoherent. */ /* Access to snoopable pages through the GTT is incoherent. */
if (obj->cache_level != I915_CACHE_NONE && !HAS_LLC(dev)) { if (obj->cache_level != I915_CACHE_NONE && !HAS_LLC(dev)) {
ret = -EINVAL; ret = -EFAULT;
goto unlock; goto unlock;
} }
...@@ -4894,7 +4894,7 @@ i915_gem_load(struct drm_device *dev) ...@@ -4894,7 +4894,7 @@ i915_gem_load(struct drm_device *dev)
init_waitqueue_head(&dev_priv->gpu_error.reset_queue); init_waitqueue_head(&dev_priv->gpu_error.reset_queue);
/* On GEN3 we really need to make sure the ARB C3 LP bit is set */ /* On GEN3 we really need to make sure the ARB C3 LP bit is set */
if (IS_GEN3(dev)) { if (!drm_core_check_feature(dev, DRIVER_MODESET) && IS_GEN3(dev)) {
I915_WRITE(MI_ARB_STATE, I915_WRITE(MI_ARB_STATE,
_MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE)); _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE));
} }
......
...@@ -1775,6 +1775,13 @@ static inline unsigned int gen8_get_total_gtt_size(u16 bdw_gmch_ctl) ...@@ -1775,6 +1775,13 @@ static inline unsigned int gen8_get_total_gtt_size(u16 bdw_gmch_ctl)
bdw_gmch_ctl &= BDW_GMCH_GGMS_MASK; bdw_gmch_ctl &= BDW_GMCH_GGMS_MASK;
if (bdw_gmch_ctl) if (bdw_gmch_ctl)
bdw_gmch_ctl = 1 << bdw_gmch_ctl; bdw_gmch_ctl = 1 << bdw_gmch_ctl;
#ifdef CONFIG_X86_32
/* Limit 32b platforms to a 2GB GGTT: 4 << 20 / pte size * PAGE_SIZE */
if (bdw_gmch_ctl > 4)
bdw_gmch_ctl = 4;
#endif
return bdw_gmch_ctl << 20; return bdw_gmch_ctl << 20;
} }
......
...@@ -335,7 +335,8 @@ void i9xx_check_fifo_underruns(struct drm_device *dev) ...@@ -335,7 +335,8 @@ void i9xx_check_fifo_underruns(struct drm_device *dev)
} }
static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev, static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev,
enum pipe pipe, bool enable) enum pipe pipe,
bool enable, bool old)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 reg = PIPESTAT(pipe); u32 reg = PIPESTAT(pipe);
...@@ -347,7 +348,7 @@ static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev, ...@@ -347,7 +348,7 @@ static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev,
I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS); I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS);
POSTING_READ(reg); POSTING_READ(reg);
} else { } else {
if (pipestat & PIPE_FIFO_UNDERRUN_STATUS) if (old && pipestat & PIPE_FIFO_UNDERRUN_STATUS)
DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); DRM_ERROR("pipe %c underrun\n", pipe_name(pipe));
} }
} }
...@@ -366,7 +367,8 @@ static void ironlake_set_fifo_underrun_reporting(struct drm_device *dev, ...@@ -366,7 +367,8 @@ static void ironlake_set_fifo_underrun_reporting(struct drm_device *dev,
} }
static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev, static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev,
enum pipe pipe, bool enable) enum pipe pipe,
bool enable, bool old)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
if (enable) { if (enable) {
...@@ -379,7 +381,8 @@ static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev, ...@@ -379,7 +381,8 @@ static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev,
} else { } else {
ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB); ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB);
if (I915_READ(GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe)) { if (old &&
I915_READ(GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe)) {
DRM_ERROR("uncleared fifo underrun on pipe %c\n", DRM_ERROR("uncleared fifo underrun on pipe %c\n",
pipe_name(pipe)); pipe_name(pipe));
} }
...@@ -444,7 +447,7 @@ static void ibx_set_fifo_underrun_reporting(struct drm_device *dev, ...@@ -444,7 +447,7 @@ static void ibx_set_fifo_underrun_reporting(struct drm_device *dev,
static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, static void cpt_set_fifo_underrun_reporting(struct drm_device *dev,
enum transcoder pch_transcoder, enum transcoder pch_transcoder,
bool enable) bool enable, bool old)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
...@@ -459,7 +462,8 @@ static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, ...@@ -459,7 +462,8 @@ static void cpt_set_fifo_underrun_reporting(struct drm_device *dev,
} else { } else {
ibx_disable_display_interrupt(dev_priv, SDE_ERROR_CPT); ibx_disable_display_interrupt(dev_priv, SDE_ERROR_CPT);
if (I915_READ(SERR_INT) & SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) { if (old && I915_READ(SERR_INT) &
SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) {
DRM_ERROR("uncleared pch fifo underrun on pch transcoder %c\n", DRM_ERROR("uncleared pch fifo underrun on pch transcoder %c\n",
transcoder_name(pch_transcoder)); transcoder_name(pch_transcoder));
} }
...@@ -486,28 +490,23 @@ static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, ...@@ -486,28 +490,23 @@ static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
bool ret; bool old;
assert_spin_locked(&dev_priv->irq_lock); assert_spin_locked(&dev_priv->irq_lock);
ret = !intel_crtc->cpu_fifo_underrun_disabled; old = !intel_crtc->cpu_fifo_underrun_disabled;
if (enable == ret)
goto done;
intel_crtc->cpu_fifo_underrun_disabled = !enable; intel_crtc->cpu_fifo_underrun_disabled = !enable;
if (INTEL_INFO(dev)->gen < 5 || IS_VALLEYVIEW(dev)) if (INTEL_INFO(dev)->gen < 5 || IS_VALLEYVIEW(dev))
i9xx_set_fifo_underrun_reporting(dev, pipe, enable); i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old);
else if (IS_GEN5(dev) || IS_GEN6(dev)) else if (IS_GEN5(dev) || IS_GEN6(dev))
ironlake_set_fifo_underrun_reporting(dev, pipe, enable); ironlake_set_fifo_underrun_reporting(dev, pipe, enable);
else if (IS_GEN7(dev)) else if (IS_GEN7(dev))
ivybridge_set_fifo_underrun_reporting(dev, pipe, enable); ivybridge_set_fifo_underrun_reporting(dev, pipe, enable, old);
else if (IS_GEN8(dev)) else if (IS_GEN8(dev))
broadwell_set_fifo_underrun_reporting(dev, pipe, enable); broadwell_set_fifo_underrun_reporting(dev, pipe, enable);
done: return old;
return ret;
} }
bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
...@@ -556,7 +555,7 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, ...@@ -556,7 +555,7 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev,
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pch_transcoder]; struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pch_transcoder];
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
unsigned long flags; unsigned long flags;
bool ret; bool old;
/* /*
* NOTE: Pre-LPT has a fixed cpu pipe -> pch transcoder mapping, but LPT * NOTE: Pre-LPT has a fixed cpu pipe -> pch transcoder mapping, but LPT
...@@ -569,21 +568,16 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev, ...@@ -569,21 +568,16 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev,
spin_lock_irqsave(&dev_priv->irq_lock, flags); spin_lock_irqsave(&dev_priv->irq_lock, flags);
ret = !intel_crtc->pch_fifo_underrun_disabled; old = !intel_crtc->pch_fifo_underrun_disabled;
if (enable == ret)
goto done;
intel_crtc->pch_fifo_underrun_disabled = !enable; intel_crtc->pch_fifo_underrun_disabled = !enable;
if (HAS_PCH_IBX(dev)) if (HAS_PCH_IBX(dev))
ibx_set_fifo_underrun_reporting(dev, pch_transcoder, enable); ibx_set_fifo_underrun_reporting(dev, pch_transcoder, enable);
else else
cpt_set_fifo_underrun_reporting(dev, pch_transcoder, enable); cpt_set_fifo_underrun_reporting(dev, pch_transcoder, enable, old);
done:
spin_unlock_irqrestore(&dev_priv->irq_lock, flags); spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
return ret; return old;
} }
...@@ -2634,10 +2628,6 @@ static int i915_enable_vblank(struct drm_device *dev, int pipe) ...@@ -2634,10 +2628,6 @@ static int i915_enable_vblank(struct drm_device *dev, int pipe)
else else
i915_enable_pipestat(dev_priv, pipe, i915_enable_pipestat(dev_priv, pipe,
PIPE_VBLANK_INTERRUPT_STATUS); PIPE_VBLANK_INTERRUPT_STATUS);
/* maintain vblank delivery even in deep C-states */
if (INTEL_INFO(dev)->gen == 3)
I915_WRITE(INSTPM, _MASKED_BIT_DISABLE(INSTPM_AGPBUSY_DIS));
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
return 0; return 0;
...@@ -2701,9 +2691,6 @@ static void i915_disable_vblank(struct drm_device *dev, int pipe) ...@@ -2701,9 +2691,6 @@ static void i915_disable_vblank(struct drm_device *dev, int pipe)
unsigned long irqflags; unsigned long irqflags;
spin_lock_irqsave(&dev_priv->irq_lock, irqflags); spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
if (INTEL_INFO(dev)->gen == 3)
I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_AGPBUSY_DIS));
i915_disable_pipestat(dev_priv, pipe, i915_disable_pipestat(dev_priv, pipe,
PIPE_VBLANK_INTERRUPT_STATUS | PIPE_VBLANK_INTERRUPT_STATUS |
PIPE_START_VBLANK_INTERRUPT_STATUS); PIPE_START_VBLANK_INTERRUPT_STATUS);
...@@ -3117,11 +3104,6 @@ static void ironlake_irq_reset(struct drm_device *dev) ...@@ -3117,11 +3104,6 @@ static void ironlake_irq_reset(struct drm_device *dev)
ibx_irq_reset(dev); ibx_irq_reset(dev);
} }
static void ironlake_irq_preinstall(struct drm_device *dev)
{
ironlake_irq_reset(dev);
}
static void valleyview_irq_preinstall(struct drm_device *dev) static void valleyview_irq_preinstall(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
...@@ -3151,6 +3133,14 @@ static void valleyview_irq_preinstall(struct drm_device *dev) ...@@ -3151,6 +3133,14 @@ static void valleyview_irq_preinstall(struct drm_device *dev)
POSTING_READ(VLV_IER); POSTING_READ(VLV_IER);
} }
static void gen8_gt_irq_reset(struct drm_i915_private *dev_priv)
{
GEN8_IRQ_RESET_NDX(GT, 0);
GEN8_IRQ_RESET_NDX(GT, 1);
GEN8_IRQ_RESET_NDX(GT, 2);
GEN8_IRQ_RESET_NDX(GT, 3);
}
static void gen8_irq_reset(struct drm_device *dev) static void gen8_irq_reset(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
...@@ -3159,10 +3149,7 @@ static void gen8_irq_reset(struct drm_device *dev) ...@@ -3159,10 +3149,7 @@ static void gen8_irq_reset(struct drm_device *dev)
I915_WRITE(GEN8_MASTER_IRQ, 0); I915_WRITE(GEN8_MASTER_IRQ, 0);
POSTING_READ(GEN8_MASTER_IRQ); POSTING_READ(GEN8_MASTER_IRQ);
GEN8_IRQ_RESET_NDX(GT, 0); gen8_gt_irq_reset(dev_priv);
GEN8_IRQ_RESET_NDX(GT, 1);
GEN8_IRQ_RESET_NDX(GT, 2);
GEN8_IRQ_RESET_NDX(GT, 3);
for_each_pipe(pipe) for_each_pipe(pipe)
GEN8_IRQ_RESET_NDX(DE_PIPE, pipe); GEN8_IRQ_RESET_NDX(DE_PIPE, pipe);
...@@ -3174,11 +3161,6 @@ static void gen8_irq_reset(struct drm_device *dev) ...@@ -3174,11 +3161,6 @@ static void gen8_irq_reset(struct drm_device *dev)
ibx_irq_reset(dev); ibx_irq_reset(dev);
} }
static void gen8_irq_preinstall(struct drm_device *dev)
{
gen8_irq_reset(dev);
}
static void cherryview_irq_preinstall(struct drm_device *dev) static void cherryview_irq_preinstall(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
...@@ -3187,10 +3169,7 @@ static void cherryview_irq_preinstall(struct drm_device *dev) ...@@ -3187,10 +3169,7 @@ static void cherryview_irq_preinstall(struct drm_device *dev)
I915_WRITE(GEN8_MASTER_IRQ, 0); I915_WRITE(GEN8_MASTER_IRQ, 0);
POSTING_READ(GEN8_MASTER_IRQ); POSTING_READ(GEN8_MASTER_IRQ);
GEN8_IRQ_RESET_NDX(GT, 0); gen8_gt_irq_reset(dev_priv);
GEN8_IRQ_RESET_NDX(GT, 1);
GEN8_IRQ_RESET_NDX(GT, 2);
GEN8_IRQ_RESET_NDX(GT, 3);
GEN5_IRQ_RESET(GEN8_PCU_); GEN5_IRQ_RESET(GEN8_PCU_);
...@@ -4387,7 +4366,7 @@ void intel_irq_init(struct drm_device *dev) ...@@ -4387,7 +4366,7 @@ void intel_irq_init(struct drm_device *dev)
dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
} else if (IS_GEN8(dev)) { } else if (IS_GEN8(dev)) {
dev->driver->irq_handler = gen8_irq_handler; dev->driver->irq_handler = gen8_irq_handler;
dev->driver->irq_preinstall = gen8_irq_preinstall; dev->driver->irq_preinstall = gen8_irq_reset;
dev->driver->irq_postinstall = gen8_irq_postinstall; dev->driver->irq_postinstall = gen8_irq_postinstall;
dev->driver->irq_uninstall = gen8_irq_uninstall; dev->driver->irq_uninstall = gen8_irq_uninstall;
dev->driver->enable_vblank = gen8_enable_vblank; dev->driver->enable_vblank = gen8_enable_vblank;
...@@ -4395,7 +4374,7 @@ void intel_irq_init(struct drm_device *dev) ...@@ -4395,7 +4374,7 @@ void intel_irq_init(struct drm_device *dev)
dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup; dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup;
} else if (HAS_PCH_SPLIT(dev)) { } else if (HAS_PCH_SPLIT(dev)) {
dev->driver->irq_handler = ironlake_irq_handler; dev->driver->irq_handler = ironlake_irq_handler;
dev->driver->irq_preinstall = ironlake_irq_preinstall; dev->driver->irq_preinstall = ironlake_irq_reset;
dev->driver->irq_postinstall = ironlake_irq_postinstall; dev->driver->irq_postinstall = ironlake_irq_postinstall;
dev->driver->irq_uninstall = ironlake_irq_uninstall; dev->driver->irq_uninstall = ironlake_irq_uninstall;
dev->driver->enable_vblank = ironlake_enable_vblank; dev->driver->enable_vblank = ironlake_enable_vblank;
......
...@@ -1179,7 +1179,7 @@ enum punit_power_well { ...@@ -1179,7 +1179,7 @@ enum punit_power_well {
#define I915_ERROR_INSTRUCTION (1<<0) #define I915_ERROR_INSTRUCTION (1<<0)
#define INSTPM 0x020c0 #define INSTPM 0x020c0
#define INSTPM_SELF_EN (1<<12) /* 915GM only */ #define INSTPM_SELF_EN (1<<12) /* 915GM only */
#define INSTPM_AGPBUSY_DIS (1<<11) /* gen3: when disabled, pending interrupts #define INSTPM_AGPBUSY_INT_EN (1<<11) /* gen3: when disabled, pending interrupts
will not assert AGPBUSY# and will only will not assert AGPBUSY# and will only
be delivered when out of C3. */ be delivered when out of C3. */
#define INSTPM_FORCE_ORDERING (1<<7) /* GEN6+ */ #define INSTPM_FORCE_ORDERING (1<<7) /* GEN6+ */
...@@ -1260,6 +1260,10 @@ enum punit_power_well { ...@@ -1260,6 +1260,10 @@ enum punit_power_well {
#define MI_ARB_DISPLAY_PRIORITY_A_B (0 << 0) /* display A > display B */ #define MI_ARB_DISPLAY_PRIORITY_A_B (0 << 0) /* display A > display B */
#define MI_ARB_DISPLAY_PRIORITY_B_A (1 << 0) /* display B > display A */ #define MI_ARB_DISPLAY_PRIORITY_B_A (1 << 0) /* display B > display A */
#define MI_STATE 0x020e4 /* gen2 only */
#define MI_AGPBUSY_INT_EN (1 << 1) /* 85x only */
#define MI_AGPBUSY_830_MODE (1 << 0) /* 85x only */
#define CACHE_MODE_0 0x02120 /* 915+ only */ #define CACHE_MODE_0 0x02120 /* 915+ only */
#define CM0_PIPELINED_RENDER_FLUSH_DISABLE (1<<8) #define CM0_PIPELINED_RENDER_FLUSH_DISABLE (1<<8)
#define CM0_IZ_OPT_DISABLE (1<<6) #define CM0_IZ_OPT_DISABLE (1<<6)
......
...@@ -744,6 +744,10 @@ parse_mipi(struct drm_i915_private *dev_priv, struct bdb_header *bdb) ...@@ -744,6 +744,10 @@ parse_mipi(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
int i, panel_id, seq_size; int i, panel_id, seq_size;
u16 block_size; u16 block_size;
/* parse MIPI blocks only if LFP type is MIPI */
if (!dev_priv->vbt.has_mipi)
return;
/* Initialize this to undefined indicating no generic MIPI support */ /* Initialize this to undefined indicating no generic MIPI support */
dev_priv->vbt.dsi.panel_id = MIPI_DSI_UNDEFINED_PANEL_ID; dev_priv->vbt.dsi.panel_id = MIPI_DSI_UNDEFINED_PANEL_ID;
...@@ -1059,6 +1063,15 @@ parse_device_mapping(struct drm_i915_private *dev_priv, ...@@ -1059,6 +1063,15 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
/* skip the device block if device type is invalid */ /* skip the device block if device type is invalid */
continue; continue;
} }
if (p_child->common.dvo_port >= DVO_PORT_MIPIA
&& p_child->common.dvo_port <= DVO_PORT_MIPID
&&p_child->common.device_type & DEVICE_TYPE_MIPI_OUTPUT) {
DRM_DEBUG_KMS("Found MIPI as LFP\n");
dev_priv->vbt.has_mipi = 1;
dev_priv->vbt.dsi.port = p_child->common.dvo_port;
}
child_dev_ptr = dev_priv->vbt.child_dev + count; child_dev_ptr = dev_priv->vbt.child_dev + count;
count++; count++;
memcpy((void *)child_dev_ptr, (void *)p_child, memcpy((void *)child_dev_ptr, (void *)p_child,
......
...@@ -743,6 +743,10 @@ int intel_parse_bios(struct drm_device *dev); ...@@ -743,6 +743,10 @@ int intel_parse_bios(struct drm_device *dev);
#define DVO_PORT_DPC 8 #define DVO_PORT_DPC 8
#define DVO_PORT_DPD 9 #define DVO_PORT_DPD 9
#define DVO_PORT_DPA 10 #define DVO_PORT_DPA 10
#define DVO_PORT_MIPIA 21
#define DVO_PORT_MIPIB 22
#define DVO_PORT_MIPIC 23
#define DVO_PORT_MIPID 24
/* Block 52 contains MIPI Panel info /* Block 52 contains MIPI Panel info
* 6 such enteries will there. Index into correct * 6 such enteries will there. Index into correct
......
...@@ -1484,14 +1484,6 @@ static void intel_reset_dpio(struct drm_device *dev) ...@@ -1484,14 +1484,6 @@ static void intel_reset_dpio(struct drm_device *dev)
if (!IS_VALLEYVIEW(dev)) if (!IS_VALLEYVIEW(dev))
return; return;
/*
* Enable the CRI clock source so we can get at the display and the
* reference clock for VGA hotplug / manual detection.
*/
I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) |
DPLL_REFA_CLK_ENABLE_VLV |
DPLL_INTEGRATED_CRI_CLK_VLV);
if (IS_CHERRYVIEW(dev)) { if (IS_CHERRYVIEW(dev)) {
enum dpio_phy phy; enum dpio_phy phy;
u32 val; u32 val;
...@@ -1516,17 +1508,23 @@ static void intel_reset_dpio(struct drm_device *dev) ...@@ -1516,17 +1508,23 @@ static void intel_reset_dpio(struct drm_device *dev)
} else { } else {
/* /*
* From VLV2A0_DP_eDP_DPIO_driver_vbios_notes_10.docx - * If DPIO has already been reset, e.g. by BIOS, just skip all
* 6. De-assert cmn_reset/side_reset. Same as VLV X0. * this.
* a. GUnit 0x2110 bit[0] set to 1 (def 0)
* b. The other bits such as sfr settings / modesel may all
* be set to 0.
*
* This should only be done on init and resume from S3 with
* both PLLs disabled, or we risk losing DPIO and PLL
* synchronization.
*/ */
I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) | DPIO_CMNRST); if (I915_READ(DPIO_CTL) & DPIO_CMNRST)
return;
/*
* From VLV2A0_DP_eDP_HDMI_DPIO_driver_vbios_notes_11.docx:
* Need to assert and de-assert PHY SB reset by gating the
* common lane power, then un-gating it.
* Simply ungating isn't enough to reset the PHY enough to get
* ports and lanes running.
*/
__vlv_set_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC,
false);
__vlv_set_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC,
true);
} }
} }
...@@ -7868,29 +7866,33 @@ static void i845_update_cursor(struct drm_crtc *crtc, u32 base) ...@@ -7868,29 +7866,33 @@ static void i845_update_cursor(struct drm_crtc *crtc, u32 base)
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
bool visible = base != 0; uint32_t cntl;
u32 cntl;
if (intel_crtc->cursor_visible == visible) if (base != intel_crtc->cursor_base) {
return;
cntl = I915_READ(_CURACNTR);
if (visible) {
/* On these chipsets we can only modify the base whilst /* On these chipsets we can only modify the base whilst
* the cursor is disabled. * the cursor is disabled.
*/ */
if (intel_crtc->cursor_cntl) {
I915_WRITE(_CURACNTR, 0);
POSTING_READ(_CURACNTR);
intel_crtc->cursor_cntl = 0;
}
I915_WRITE(_CURABASE, base); I915_WRITE(_CURABASE, base);
POSTING_READ(_CURABASE);
}
cntl &= ~(CURSOR_FORMAT_MASK); /* XXX width must be 64, stride 256 => 0x00 << 28 */
/* XXX width must be 64, stride 256 => 0x00 << 28 */ cntl = 0;
cntl |= CURSOR_ENABLE | if (base)
cntl = (CURSOR_ENABLE |
CURSOR_GAMMA_ENABLE | CURSOR_GAMMA_ENABLE |
CURSOR_FORMAT_ARGB; CURSOR_FORMAT_ARGB);
} else if (intel_crtc->cursor_cntl != cntl) {
cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); I915_WRITE(_CURACNTR, cntl);
I915_WRITE(_CURACNTR, cntl); POSTING_READ(_CURACNTR);
intel_crtc->cursor_cntl = cntl;
intel_crtc->cursor_visible = visible; }
} }
static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
...@@ -7899,16 +7901,12 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) ...@@ -7899,16 +7901,12 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_crtc->pipe; int pipe = intel_crtc->pipe;
bool visible = base != 0; uint32_t cntl;
if (intel_crtc->cursor_visible != visible) {
int16_t width = intel_crtc->cursor_width;
uint32_t cntl = I915_READ(CURCNTR(pipe));
if (base) {
cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
cntl |= MCURSOR_GAMMA_ENABLE;
switch (width) { cntl = 0;
if (base) {
cntl = MCURSOR_GAMMA_ENABLE;
switch (intel_crtc->cursor_width) {
case 64: case 64:
cntl |= CURSOR_MODE_64_ARGB_AX; cntl |= CURSOR_MODE_64_ARGB_AX;
break; break;
...@@ -7921,18 +7919,16 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) ...@@ -7921,18 +7919,16 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
default: default:
WARN_ON(1); WARN_ON(1);
return; return;
}
cntl |= pipe << 28; /* Connect to correct pipe */
} else {
cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
cntl |= CURSOR_MODE_DISABLE;
} }
cntl |= pipe << 28; /* Connect to correct pipe */
}
if (intel_crtc->cursor_cntl != cntl) {
I915_WRITE(CURCNTR(pipe), cntl); I915_WRITE(CURCNTR(pipe), cntl);
POSTING_READ(CURCNTR(pipe));
intel_crtc->cursor_visible = visible; intel_crtc->cursor_cntl = cntl;
} }
/* and commit changes on next vblank */ /* and commit changes on next vblank */
POSTING_READ(CURCNTR(pipe));
I915_WRITE(CURBASE(pipe), base); I915_WRITE(CURBASE(pipe), base);
POSTING_READ(CURBASE(pipe)); POSTING_READ(CURBASE(pipe));
} }
...@@ -7943,15 +7939,12 @@ static void ivb_update_cursor(struct drm_crtc *crtc, u32 base) ...@@ -7943,15 +7939,12 @@ static void ivb_update_cursor(struct drm_crtc *crtc, u32 base)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_crtc->pipe; int pipe = intel_crtc->pipe;
bool visible = base != 0; uint32_t cntl;
if (intel_crtc->cursor_visible != visible) { cntl = 0;
int16_t width = intel_crtc->cursor_width; if (base) {
uint32_t cntl = I915_READ(CURCNTR(pipe)); cntl = MCURSOR_GAMMA_ENABLE;
if (base) { switch (intel_crtc->cursor_width) {
cntl &= ~CURSOR_MODE;
cntl |= MCURSOR_GAMMA_ENABLE;
switch (width) {
case 64: case 64:
cntl |= CURSOR_MODE_64_ARGB_AX; cntl |= CURSOR_MODE_64_ARGB_AX;
break; break;
...@@ -7964,21 +7957,18 @@ static void ivb_update_cursor(struct drm_crtc *crtc, u32 base) ...@@ -7964,21 +7957,18 @@ static void ivb_update_cursor(struct drm_crtc *crtc, u32 base)
default: default:
WARN_ON(1); WARN_ON(1);
return; return;
}
} else {
cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
cntl |= CURSOR_MODE_DISABLE;
} }
if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { }
cntl |= CURSOR_PIPE_CSC_ENABLE; if (IS_HASWELL(dev) || IS_BROADWELL(dev))
cntl &= ~CURSOR_TRICKLE_FEED_DISABLE; cntl |= CURSOR_PIPE_CSC_ENABLE;
}
I915_WRITE(CURCNTR(pipe), cntl);
intel_crtc->cursor_visible = visible; if (intel_crtc->cursor_cntl != cntl) {
I915_WRITE(CURCNTR(pipe), cntl);
POSTING_READ(CURCNTR(pipe));
intel_crtc->cursor_cntl = cntl;
} }
/* and commit changes on next vblank */ /* and commit changes on next vblank */
POSTING_READ(CURCNTR(pipe));
I915_WRITE(CURBASE(pipe), base); I915_WRITE(CURBASE(pipe), base);
POSTING_READ(CURBASE(pipe)); POSTING_READ(CURBASE(pipe));
} }
...@@ -7994,7 +7984,6 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc, ...@@ -7994,7 +7984,6 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
int x = intel_crtc->cursor_x; int x = intel_crtc->cursor_x;
int y = intel_crtc->cursor_y; int y = intel_crtc->cursor_y;
u32 base = 0, pos = 0; u32 base = 0, pos = 0;
bool visible;
if (on) if (on)
base = intel_crtc->cursor_addr; base = intel_crtc->cursor_addr;
...@@ -8023,8 +8012,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc, ...@@ -8023,8 +8012,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
} }
pos |= y << CURSOR_Y_SHIFT; pos |= y << CURSOR_Y_SHIFT;
visible = base != 0; if (base == 0 && intel_crtc->cursor_base == 0)
if (!visible && !intel_crtc->cursor_visible)
return; return;
I915_WRITE(CURPOS(pipe), pos); I915_WRITE(CURPOS(pipe), pos);
...@@ -8035,6 +8023,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc, ...@@ -8035,6 +8023,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
i845_update_cursor(crtc, base); i845_update_cursor(crtc, base);
else else
i9xx_update_cursor(crtc, base); i9xx_update_cursor(crtc, base);
intel_crtc->cursor_base = base;
} }
static int intel_crtc_cursor_set(struct drm_crtc *crtc, static int intel_crtc_cursor_set(struct drm_crtc *crtc,
...@@ -10990,6 +10979,9 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) ...@@ -10990,6 +10979,9 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
intel_crtc->plane = !pipe; intel_crtc->plane = !pipe;
} }
intel_crtc->cursor_base = ~0;
intel_crtc->cursor_cntl = ~0;
init_waitqueue_head(&intel_crtc->vbl_wait); init_waitqueue_head(&intel_crtc->vbl_wait);
BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) || BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
...@@ -11103,7 +11095,7 @@ static void intel_setup_outputs(struct drm_device *dev) ...@@ -11103,7 +11095,7 @@ static void intel_setup_outputs(struct drm_device *dev)
intel_lvds_init(dev); intel_lvds_init(dev);
if (!IS_ULT(dev) && !IS_CHERRYVIEW(dev)) if (!IS_ULT(dev) && !IS_CHERRYVIEW(dev) && dev_priv->vbt.int_crt_support)
intel_crt_init(dev); intel_crt_init(dev);
if (HAS_DDI(dev)) { if (HAS_DDI(dev)) {
...@@ -11618,9 +11610,6 @@ static struct intel_quirk intel_quirks[] = { ...@@ -11618,9 +11610,6 @@ static struct intel_quirk intel_quirks[] = {
/* ThinkPad T60 needs pipe A force quirk (bug #16494) */ /* ThinkPad T60 needs pipe A force quirk (bug #16494) */
{ 0x2782, 0x17aa, 0x201a, quirk_pipea_force }, { 0x2782, 0x17aa, 0x201a, quirk_pipea_force },
/* 830 needs to leave pipe A & dpll A up */
{ 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
/* Lenovo U160 cannot use SSC on LVDS */ /* Lenovo U160 cannot use SSC on LVDS */
{ 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable }, { 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable },
......
...@@ -386,7 +386,8 @@ struct intel_crtc { ...@@ -386,7 +386,8 @@ struct intel_crtc {
uint32_t cursor_addr; uint32_t cursor_addr;
int16_t cursor_x, cursor_y; int16_t cursor_x, cursor_y;
int16_t cursor_width, cursor_height; int16_t cursor_width, cursor_height;
bool cursor_visible; uint32_t cursor_cntl;
uint32_t cursor_base;
struct intel_plane_config plane_config; struct intel_plane_config plane_config;
struct intel_crtc_config config; struct intel_crtc_config config;
...@@ -973,7 +974,8 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv); ...@@ -973,7 +974,8 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv);
void intel_init_runtime_pm(struct drm_i915_private *dev_priv); void intel_init_runtime_pm(struct drm_i915_private *dev_priv);
void intel_fini_runtime_pm(struct drm_i915_private *dev_priv); void intel_fini_runtime_pm(struct drm_i915_private *dev_priv);
void ilk_wm_get_hw_state(struct drm_device *dev); void ilk_wm_get_hw_state(struct drm_device *dev);
void __vlv_set_power_well(struct drm_i915_private *dev_priv,
enum punit_power_well power_well_id, bool enable);
/* intel_sdvo.c */ /* intel_sdvo.c */
bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob); bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
......
...@@ -35,6 +35,11 @@ ...@@ -35,6 +35,11 @@
/* the sub-encoders aka panel drivers */ /* the sub-encoders aka panel drivers */
static const struct intel_dsi_device intel_dsi_devices[] = { static const struct intel_dsi_device intel_dsi_devices[] = {
{
.panel_id = MIPI_DSI_GENERIC_PANEL_ID,
.name = "vbt-generic-dsi-vid-mode-display",
.dev_ops = &vbt_generic_dsi_display_ops,
},
}; };
static void band_gap_reset(struct drm_i915_private *dev_priv) static void band_gap_reset(struct drm_i915_private *dev_priv)
...@@ -201,6 +206,19 @@ static void intel_dsi_enable_nop(struct intel_encoder *encoder) ...@@ -201,6 +206,19 @@ static void intel_dsi_enable_nop(struct intel_encoder *encoder)
*/ */
} }
static void intel_dsi_pre_disable(struct intel_encoder *encoder)
{
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
DRM_DEBUG_KMS("\n");
if (is_vid_mode(intel_dsi)) {
/* Send Shutdown command to the panel in LP mode */
dpi_send_cmd(intel_dsi, SHUTDOWN, DPI_LP_MODE_EN);
msleep(10);
}
}
static void intel_dsi_disable(struct intel_encoder *encoder) static void intel_dsi_disable(struct intel_encoder *encoder)
{ {
struct drm_device *dev = encoder->base.dev; struct drm_device *dev = encoder->base.dev;
...@@ -213,10 +231,6 @@ static void intel_dsi_disable(struct intel_encoder *encoder) ...@@ -213,10 +231,6 @@ static void intel_dsi_disable(struct intel_encoder *encoder)
DRM_DEBUG_KMS("\n"); DRM_DEBUG_KMS("\n");
if (is_vid_mode(intel_dsi)) { if (is_vid_mode(intel_dsi)) {
/* Send Shutdown command to the panel in LP mode */
dpi_send_cmd(intel_dsi, SHUTDOWN, DPI_LP_MODE_EN);
msleep(10);
/* de-assert ip_tg_enable signal */ /* de-assert ip_tg_enable signal */
temp = I915_READ(MIPI_PORT_CTRL(pipe)); temp = I915_READ(MIPI_PORT_CTRL(pipe));
I915_WRITE(MIPI_PORT_CTRL(pipe), temp & ~DPI_ENABLE); I915_WRITE(MIPI_PORT_CTRL(pipe), temp & ~DPI_ENABLE);
...@@ -288,6 +302,8 @@ static void intel_dsi_post_disable(struct intel_encoder *encoder) ...@@ -288,6 +302,8 @@ static void intel_dsi_post_disable(struct intel_encoder *encoder)
DRM_DEBUG_KMS("\n"); DRM_DEBUG_KMS("\n");
intel_dsi_disable(encoder);
intel_dsi_clear_device_ready(encoder); intel_dsi_clear_device_ready(encoder);
val = I915_READ(DSPCLK_GATE_D); val = I915_READ(DSPCLK_GATE_D);
...@@ -655,6 +671,10 @@ bool intel_dsi_init(struct drm_device *dev) ...@@ -655,6 +671,10 @@ bool intel_dsi_init(struct drm_device *dev)
DRM_DEBUG_KMS("\n"); DRM_DEBUG_KMS("\n");
/* There is no detection method for MIPI so rely on VBT */
if (!dev_priv->vbt.has_mipi)
return false;
intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL); intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL);
if (!intel_dsi) if (!intel_dsi)
return false; return false;
...@@ -686,7 +706,7 @@ bool intel_dsi_init(struct drm_device *dev) ...@@ -686,7 +706,7 @@ bool intel_dsi_init(struct drm_device *dev)
intel_encoder->pre_pll_enable = intel_dsi_pre_pll_enable; intel_encoder->pre_pll_enable = intel_dsi_pre_pll_enable;
intel_encoder->pre_enable = intel_dsi_pre_enable; intel_encoder->pre_enable = intel_dsi_pre_enable;
intel_encoder->enable = intel_dsi_enable_nop; intel_encoder->enable = intel_dsi_enable_nop;
intel_encoder->disable = intel_dsi_disable; intel_encoder->disable = intel_dsi_pre_disable;
intel_encoder->post_disable = intel_dsi_post_disable; intel_encoder->post_disable = intel_dsi_post_disable;
intel_encoder->get_hw_state = intel_dsi_get_hw_state; intel_encoder->get_hw_state = intel_dsi_get_hw_state;
intel_encoder->get_config = intel_dsi_get_config; intel_encoder->get_config = intel_dsi_get_config;
......
...@@ -133,4 +133,6 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder) ...@@ -133,4 +133,6 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder)
extern void vlv_enable_dsi_pll(struct intel_encoder *encoder); extern void vlv_enable_dsi_pll(struct intel_encoder *encoder);
extern void vlv_disable_dsi_pll(struct intel_encoder *encoder); extern void vlv_disable_dsi_pll(struct intel_encoder *encoder);
extern struct intel_dsi_dev_ops vbt_generic_dsi_display_ops;
#endif /* _INTEL_DSI_H */ #endif /* _INTEL_DSI_H */
This diff is collapsed.
...@@ -5388,8 +5388,11 @@ static void valleyview_init_clock_gating(struct drm_device *dev) ...@@ -5388,8 +5388,11 @@ static void valleyview_init_clock_gating(struct drm_device *dev)
I915_WRITE(GEN6_UCGCTL2, I915_WRITE(GEN6_UCGCTL2,
GEN6_RCZUNIT_CLOCK_GATE_DISABLE); GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
/* WaDisableL3Bank2xClockGate:vlv */ /* WaDisableL3Bank2xClockGate:vlv
I915_WRITE(GEN7_UCGCTL4, GEN7_L3BANK2X_CLOCK_GATE_DISABLE); * Disabling L3 clock gating- MMIO 940c[25] = 1
* Set bit 25, to disable L3_BANK_2x_CLK_GATING */
I915_WRITE(GEN7_UCGCTL4,
I915_READ(GEN7_UCGCTL4) | GEN7_L3BANK2X_CLOCK_GATE_DISABLE);
I915_WRITE(MI_ARB_VLV, MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE); I915_WRITE(MI_ARB_VLV, MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE);
...@@ -5541,6 +5544,12 @@ static void gen3_init_clock_gating(struct drm_device *dev) ...@@ -5541,6 +5544,12 @@ static void gen3_init_clock_gating(struct drm_device *dev)
/* IIR "flip pending" means done if this bit is set */ /* IIR "flip pending" means done if this bit is set */
I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE));
/* interrupts should cause a wake up from C3 */
I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_AGPBUSY_INT_EN));
/* On GEN3 we really need to make sure the ARB C3 LP bit is set */
I915_WRITE(MI_ARB_STATE, _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE));
} }
static void i85x_init_clock_gating(struct drm_device *dev) static void i85x_init_clock_gating(struct drm_device *dev)
...@@ -5548,6 +5557,10 @@ static void i85x_init_clock_gating(struct drm_device *dev) ...@@ -5548,6 +5557,10 @@ static void i85x_init_clock_gating(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
/* interrupts should cause a wake up from C3 */
I915_WRITE(MI_STATE, _MASKED_BIT_ENABLE(MI_AGPBUSY_INT_EN) |
_MASKED_BIT_DISABLE(MI_AGPBUSY_830_MODE));
} }
static void i830_init_clock_gating(struct drm_device *dev) static void i830_init_clock_gating(struct drm_device *dev)
...@@ -5599,10 +5612,25 @@ bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, ...@@ -5599,10 +5612,25 @@ bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain) enum intel_display_power_domain domain)
{ {
struct i915_power_domains *power_domains; struct i915_power_domains *power_domains;
struct i915_power_well *power_well;
bool is_enabled;
int i;
if (dev_priv->pm.suspended)
return false;
power_domains = &dev_priv->power_domains; power_domains = &dev_priv->power_domains;
is_enabled = true;
for_each_power_well_rev(i, power_well, BIT(domain), power_domains) {
if (power_well->always_on)
continue;
return power_domains->domain_use_count[domain]; if (!power_well->count) {
is_enabled = false;
break;
}
}
return is_enabled;
} }
bool intel_display_power_enabled(struct drm_i915_private *dev_priv, bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
...@@ -5745,13 +5773,34 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv, ...@@ -5745,13 +5773,34 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv,
return true; return true;
} }
static void vlv_set_power_well(struct drm_i915_private *dev_priv, void __vlv_set_power_well(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well, bool enable) enum punit_power_well power_well_id, bool enable)
{ {
enum punit_power_well power_well_id = power_well->data; struct drm_device *dev = dev_priv->dev;
u32 mask; u32 mask;
u32 state; u32 state;
u32 ctrl; u32 ctrl;
enum pipe pipe;
if (power_well_id == PUNIT_POWER_WELL_DPIO_CMN_BC) {
if (enable) {
/*
* Enable the CRI clock source so we can get at the
* display and the reference clock for VGA
* hotplug / manual detection.
*/
I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) |
DPLL_REFA_CLK_ENABLE_VLV |
DPLL_INTEGRATED_CRI_CLK_VLV);
udelay(1); /* >10ns for cmnreset, >0ns for sidereset */
} else {
for_each_pipe(pipe)
assert_pll_disabled(dev_priv, pipe);
/* Assert common reset */
I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) &
~DPIO_CMNRST);
}
}
mask = PUNIT_PWRGT_MASK(power_well_id); mask = PUNIT_PWRGT_MASK(power_well_id);
state = enable ? PUNIT_PWRGT_PWR_ON(power_well_id) : state = enable ? PUNIT_PWRGT_PWR_ON(power_well_id) :
...@@ -5779,6 +5828,28 @@ static void vlv_set_power_well(struct drm_i915_private *dev_priv, ...@@ -5779,6 +5828,28 @@ static void vlv_set_power_well(struct drm_i915_private *dev_priv,
out: out:
mutex_unlock(&dev_priv->rps.hw_lock); mutex_unlock(&dev_priv->rps.hw_lock);
/*
* From VLV2A0_DP_eDP_DPIO_driver_vbios_notes_10.docx -
* 6. De-assert cmn_reset/side_reset. Same as VLV X0.
* a. GUnit 0x2110 bit[0] set to 1 (def 0)
* b. The other bits such as sfr settings / modesel may all
* be set to 0.
*
* This should only be done on init and resume from S3 with
* both PLLs disabled, or we risk losing DPIO and PLL
* synchronization.
*/
if (power_well_id == PUNIT_POWER_WELL_DPIO_CMN_BC && enable)
I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) | DPIO_CMNRST);
}
static void vlv_set_power_well(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well, bool enable)
{
enum punit_power_well power_well_id = power_well->data;
__vlv_set_power_well(dev_priv, power_well_id, enable);
} }
static void vlv_power_well_sync_hw(struct drm_i915_private *dev_priv, static void vlv_power_well_sync_hw(struct drm_i915_private *dev_priv,
...@@ -6113,12 +6184,6 @@ static struct i915_power_well vlv_power_wells[] = { ...@@ -6113,12 +6184,6 @@ static struct i915_power_well vlv_power_wells[] = {
.data = PUNIT_POWER_WELL_DISP2D, .data = PUNIT_POWER_WELL_DISP2D,
.ops = &vlv_display_power_well_ops, .ops = &vlv_display_power_well_ops,
}, },
{
.name = "dpio-common",
.domains = VLV_DPIO_CMN_BC_POWER_DOMAINS,
.data = PUNIT_POWER_WELL_DPIO_CMN_BC,
.ops = &vlv_dpio_power_well_ops,
},
{ {
.name = "dpio-tx-b-01", .name = "dpio-tx-b-01",
.domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
...@@ -6155,6 +6220,12 @@ static struct i915_power_well vlv_power_wells[] = { ...@@ -6155,6 +6220,12 @@ static struct i915_power_well vlv_power_wells[] = {
.ops = &vlv_dpio_power_well_ops, .ops = &vlv_dpio_power_well_ops,
.data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23, .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23,
}, },
{
.name = "dpio-common",
.domains = VLV_DPIO_CMN_BC_POWER_DOMAINS,
.data = PUNIT_POWER_WELL_DPIO_CMN_BC,
.ops = &vlv_dpio_power_well_ops,
},
}; };
#define set_power_wells(power_domains, __power_wells) ({ \ #define set_power_wells(power_domains, __power_wells) ({ \
......
...@@ -1494,7 +1494,7 @@ void intel_cleanup_ring_buffer(struct intel_engine_cs *ring) ...@@ -1494,7 +1494,7 @@ void intel_cleanup_ring_buffer(struct intel_engine_cs *ring)
return; return;
intel_stop_ring_buffer(ring); intel_stop_ring_buffer(ring);
WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0); WARN_ON(!IS_GEN2(ring->dev) && (I915_READ_MODE(ring) & MODE_IDLE) == 0);
iounmap(ringbuf->virtual_start); iounmap(ringbuf->virtual_start);
......
...@@ -393,26 +393,8 @@ void intel_uncore_early_sanitize(struct drm_device *dev) ...@@ -393,26 +393,8 @@ void intel_uncore_early_sanitize(struct drm_device *dev)
void intel_uncore_sanitize(struct drm_device *dev) void intel_uncore_sanitize(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private;
u32 reg_val;
/* BIOS often leaves RC6 enabled, but disable it for hw init */ /* BIOS often leaves RC6 enabled, but disable it for hw init */
intel_disable_gt_powersave(dev); intel_disable_gt_powersave(dev);
/* Turn off power gate, require especially for the BIOS less system */
if (IS_VALLEYVIEW(dev)) {
mutex_lock(&dev_priv->rps.hw_lock);
reg_val = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS);
if (reg_val & (PUNIT_PWRGT_PWR_GATE(PUNIT_POWER_WELL_RENDER) |
PUNIT_PWRGT_PWR_GATE(PUNIT_POWER_WELL_MEDIA) |
PUNIT_PWRGT_PWR_GATE(PUNIT_POWER_WELL_DISP2D)))
vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, 0x0);
mutex_unlock(&dev_priv->rps.hw_lock);
}
} }
/* /*
...@@ -967,6 +949,9 @@ static int i965_do_reset(struct drm_device *dev) ...@@ -967,6 +949,9 @@ static int i965_do_reset(struct drm_device *dev)
{ {
int ret; int ret;
/* FIXME: i965g/gm need a display save/restore for gpu reset. */
return -ENODEV;
/* /*
* Set the domains we want to reset (GRDOM/bits 2 and 3) as * Set the domains we want to reset (GRDOM/bits 2 and 3) as
* well as the reset bit (GR/bit 0). Setting the GR bit * well as the reset bit (GR/bit 0). Setting the GR bit
......
...@@ -24,6 +24,17 @@ ...@@ -24,6 +24,17 @@
#ifndef DRM_PLANE_HELPER_H #ifndef DRM_PLANE_HELPER_H
#define DRM_PLANE_HELPER_H #define DRM_PLANE_HELPER_H
#include <drm/drm_rect.h>
/*
* Drivers that don't allow primary plane scaling may pass this macro in place
* of the min/max scale parameters of the update checker function.
*
* Due to src being in 16.16 fixed point and dest being in integer pixels,
* 1<<16 represents no scaling.
*/
#define DRM_PLANE_HELPER_NO_SCALING (1<<16)
/** /**
* DOC: plane helpers * DOC: plane helpers
* *
...@@ -31,6 +42,17 @@ ...@@ -31,6 +42,17 @@
* planes. * planes.
*/ */
extern int drm_plane_helper_check_update(struct drm_plane *plane,
struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_rect *src,
struct drm_rect *dest,
const struct drm_rect *clip,
int min_scale,
int max_scale,
bool can_position,
bool can_update_disabled,
bool *visible);
extern int drm_primary_helper_update(struct drm_plane *plane, extern int drm_primary_helper_update(struct drm_plane *plane,
struct drm_crtc *crtc, struct drm_crtc *crtc,
struct drm_framebuffer *fb, struct drm_framebuffer *fb,
......
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