#include <drm/drm_rect.h>
#include <linux/dma_remapping.h>
-/* Primary plane formats supported by all gen */
-#define COMMON_PRIMARY_FORMATS \
- DRM_FORMAT_C8, \
- DRM_FORMAT_RGB565, \
- DRM_FORMAT_XRGB8888, \
- DRM_FORMAT_ARGB8888
-
/* Primary plane formats for gen <= 3 */
-static const uint32_t intel_primary_formats_gen2[] = {
- COMMON_PRIMARY_FORMATS,
+static const uint32_t i8xx_primary_formats[] = {
+ DRM_FORMAT_C8,
+ DRM_FORMAT_RGB565,
DRM_FORMAT_XRGB1555,
- DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_XRGB8888,
};
/* Primary plane formats for gen >= 4 */
-static const uint32_t intel_primary_formats_gen4[] = {
- COMMON_PRIMARY_FORMATS, \
+static const uint32_t i965_primary_formats[] = {
+ DRM_FORMAT_C8,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_XRGB2101010,
+ DRM_FORMAT_XBGR2101010,
+};
+
+static const uint32_t skl_primary_formats[] = {
+ DRM_FORMAT_C8,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_XRGB8888,
DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_ARGB8888,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_XRGB2101010,
- DRM_FORMAT_ARGB2101010,
DRM_FORMAT_XBGR2101010,
- DRM_FORMAT_ABGR2101010,
};
/* Cursor formats */
u32 val;
bool cur_state;
- mutex_lock(&dev_priv->dpio_lock);
+ mutex_lock(&dev_priv->sb_lock);
val = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
- mutex_unlock(&dev_priv->dpio_lock);
+ mutex_unlock(&dev_priv->sb_lock);
cur_state = val & DSI_PLL_VCO_EN;
I915_STATE_WARN(cur_state != state,
BUG_ON(!IS_CHERRYVIEW(dev_priv->dev));
- mutex_lock(&dev_priv->dpio_lock);
+ mutex_lock(&dev_priv->sb_lock);
/* Enable back the 10bit clock to display controller */
tmp = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
tmp |= DPIO_DCLKP_EN;
vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), tmp);
+ mutex_unlock(&dev_priv->sb_lock);
+
/*
* Need to wait > 100ns between dclkp clock enable bit and PLL enable.
*/
/* not sure when this should be written */
I915_WRITE(DPLL_MD(pipe), pipe_config->dpll_hw_state.dpll_md);
POSTING_READ(DPLL_MD(pipe));
-
- mutex_unlock(&dev_priv->dpio_lock);
}
static int intel_num_dvo_pipes(struct drm_device *dev)
I915_WRITE(DPLL(pipe), val);
POSTING_READ(DPLL(pipe));
- mutex_lock(&dev_priv->dpio_lock);
+ mutex_lock(&dev_priv->sb_lock);
/* Disable 10bit clock to display controller */
val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
}
- mutex_unlock(&dev_priv->dpio_lock);
+ mutex_unlock(&dev_priv->sb_lock);
}
void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
intel_wait_for_pipe_off(crtc);
}
-/*
- * Plane regs are double buffered, going from enabled->disabled needs a
- * trigger in order to latch. The display address reg provides this.
- */
-void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
- enum plane plane)
-{
- struct drm_device *dev = dev_priv->dev;
- u32 reg = INTEL_INFO(dev)->gen >= 4 ? DSPSURF(plane) : DSPADDR(plane);
-
- I915_WRITE(reg, I915_READ(reg));
- POSTING_READ(reg);
-}
-
/**
* intel_enable_primary_hw_plane - enable the primary plane on a given pipe
* @plane: plane to be enabled
dspcntr |= DISPPLANE_8BPP;
break;
case DRM_FORMAT_XRGB1555:
- case DRM_FORMAT_ARGB1555:
dspcntr |= DISPPLANE_BGRX555;
break;
case DRM_FORMAT_RGB565:
dspcntr |= DISPPLANE_BGRX565;
break;
case DRM_FORMAT_XRGB8888:
- case DRM_FORMAT_ARGB8888:
dspcntr |= DISPPLANE_BGRX888;
break;
case DRM_FORMAT_XBGR8888:
- case DRM_FORMAT_ABGR8888:
dspcntr |= DISPPLANE_RGBX888;
break;
case DRM_FORMAT_XRGB2101010:
- case DRM_FORMAT_ARGB2101010:
dspcntr |= DISPPLANE_BGRX101010;
break;
case DRM_FORMAT_XBGR2101010:
- case DRM_FORMAT_ABGR2101010:
dspcntr |= DISPPLANE_RGBX101010;
break;
default:
dspcntr |= DISPPLANE_BGRX565;
break;
case DRM_FORMAT_XRGB8888:
- case DRM_FORMAT_ARGB8888:
dspcntr |= DISPPLANE_BGRX888;
break;
case DRM_FORMAT_XBGR8888:
- case DRM_FORMAT_ABGR8888:
dspcntr |= DISPPLANE_RGBX888;
break;
case DRM_FORMAT_XRGB2101010:
- case DRM_FORMAT_ARGB2101010:
dspcntr |= DISPPLANE_BGRX101010;
break;
case DRM_FORMAT_XBGR2101010:
- case DRM_FORMAT_ABGR2101010:
dspcntr |= DISPPLANE_RGBX101010;
break;
default:
u32 skl_plane_ctl_format(uint32_t pixel_format)
{
- u32 plane_ctl_format = 0;
switch (pixel_format) {
+ case DRM_FORMAT_C8:
+ return PLANE_CTL_FORMAT_INDEXED;
case DRM_FORMAT_RGB565:
- plane_ctl_format = PLANE_CTL_FORMAT_RGB_565;
- break;
+ return PLANE_CTL_FORMAT_RGB_565;
case DRM_FORMAT_XBGR8888:
- plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
- break;
+ return PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
case DRM_FORMAT_XRGB8888:
- plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888;
- break;
+ return PLANE_CTL_FORMAT_XRGB_8888;
/*
* XXX: For ARBG/ABGR formats we default to expecting scanout buffers
* to be already pre-multiplied. We need to add a knob (or a different
* DRM_FORMAT) for user-space to configure that.
*/
case DRM_FORMAT_ABGR8888:
- plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX |
+ return PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX |
PLANE_CTL_ALPHA_SW_PREMULTIPLY;
- break;
case DRM_FORMAT_ARGB8888:
- plane_ctl_format = PLANE_CTL_FORMAT_XRGB_8888 |
+ return PLANE_CTL_FORMAT_XRGB_8888 |
PLANE_CTL_ALPHA_SW_PREMULTIPLY;
- break;
case DRM_FORMAT_XRGB2101010:
- plane_ctl_format = PLANE_CTL_FORMAT_XRGB_2101010;
- break;
+ return PLANE_CTL_FORMAT_XRGB_2101010;
case DRM_FORMAT_XBGR2101010:
- plane_ctl_format = PLANE_CTL_ORDER_RGBX | PLANE_CTL_FORMAT_XRGB_2101010;
- break;
+ return PLANE_CTL_ORDER_RGBX | PLANE_CTL_FORMAT_XRGB_2101010;
case DRM_FORMAT_YUYV:
- plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
- break;
+ return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
case DRM_FORMAT_YVYU:
- plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
- break;
+ return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
case DRM_FORMAT_UYVY:
- plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
- break;
+ return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
case DRM_FORMAT_VYUY:
- plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
- break;
+ return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
default:
- BUG();
+ MISSING_CASE(pixel_format);
}
- return plane_ctl_format;
+
+ return 0;
}
u32 skl_plane_ctl_tiling(uint64_t fb_modifier)
{
- u32 plane_ctl_tiling = 0;
switch (fb_modifier) {
case DRM_FORMAT_MOD_NONE:
break;
case I915_FORMAT_MOD_X_TILED:
- plane_ctl_tiling = PLANE_CTL_TILED_X;
- break;
+ return PLANE_CTL_TILED_X;
case I915_FORMAT_MOD_Y_TILED:
- plane_ctl_tiling = PLANE_CTL_TILED_Y;
- break;
+ return PLANE_CTL_TILED_Y;
case I915_FORMAT_MOD_Yf_TILED:
- plane_ctl_tiling = PLANE_CTL_TILED_YF;
- break;
+ return PLANE_CTL_TILED_YF;
default:
MISSING_CASE(fb_modifier);
}
- return plane_ctl_tiling;
+
+ return 0;
}
u32 skl_plane_ctl_rotation(unsigned int rotation)
{
- u32 plane_ctl_rotation = 0;
switch (rotation) {
case BIT(DRM_ROTATE_0):
break;
+ /*
+ * DRM_ROTATE_ is counter clockwise to stay compatible with Xrandr
+ * while i915 HW rotation is clockwise, thats why this swapping.
+ */
case BIT(DRM_ROTATE_90):
- plane_ctl_rotation = PLANE_CTL_ROTATE_90;
- break;
+ return PLANE_CTL_ROTATE_270;
case BIT(DRM_ROTATE_180):
- plane_ctl_rotation = PLANE_CTL_ROTATE_180;
- break;
+ return PLANE_CTL_ROTATE_180;
case BIT(DRM_ROTATE_270):
- plane_ctl_rotation = PLANE_CTL_ROTATE_270;
- break;
+ return PLANE_CTL_ROTATE_90;
default:
MISSING_CASE(rotation);
}
- return plane_ctl_rotation;
+ return 0;
}
static void skylake_update_primary_plane(struct drm_crtc *crtc,
u32 divsel, phaseinc, auxdiv, phasedir = 0;
u32 temp;
- mutex_lock(&dev_priv->dpio_lock);
+ mutex_lock(&dev_priv->sb_lock);
/* It is necessary to ungate the pixclk gate prior to programming
* the divisors, and gate it back when it is done.
I915_WRITE(PIXCLK_GATE, PIXCLK_GATE_UNGATE);
- mutex_unlock(&dev_priv->dpio_lock);
+ mutex_unlock(&dev_priv->sb_lock);
}
static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc,
temp &= ~(TRANS_DP_PORT_SEL_MASK |
TRANS_DP_SYNC_MASK |
TRANS_DP_BPC_MASK);
- temp |= (TRANS_DP_OUTPUT_ENABLE |
- TRANS_DP_ENH_FRAMING);
+ temp |= TRANS_DP_OUTPUT_ENABLE;
temp |= bpc << 9; /* same format but at 11:9 */
if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC)
}
/* check colorkey */
- if (intel_plane && intel_plane->ckey.flags != I915_SET_COLORKEY_NONE) {
- DRM_DEBUG_KMS("PLANE:%d scaling with color key not allowed",
- intel_plane->base.base.id);
+ if (WARN_ON(intel_plane &&
+ intel_plane->ckey.flags != I915_SET_COLORKEY_NONE)) {
+ DRM_DEBUG_KMS("PLANE:%d scaling %ux%u->%ux%u not allowed with colorkey",
+ intel_plane->base.base.id, src_w, src_h, dst_w, dst_h);
return -EINVAL;
}
case DRM_FORMAT_ABGR8888:
case DRM_FORMAT_ARGB8888:
case DRM_FORMAT_XRGB2101010:
- case DRM_FORMAT_ARGB2101010:
case DRM_FORMAT_XBGR2101010:
- case DRM_FORMAT_ABGR2101010:
case DRM_FORMAT_YUYV:
case DRM_FORMAT_YVYU:
case DRM_FORMAT_UYVY:
ironlake_pfit_disable(intel_crtc);
+ if (intel_crtc->config->has_pch_encoder)
+ ironlake_fdi_disable(crtc);
+
for_each_encoder_on_crtc(dev, crtc, encoder)
if (encoder->post_disable)
encoder->post_disable(encoder);
if (intel_crtc->config->has_pch_encoder) {
- ironlake_fdi_disable(crtc);
-
ironlake_disable_pch_transcoder(dev_priv, pipe);
if (HAS_PCH_CPT(dev)) {
intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
}
+static const struct skl_cdclk_entry {
+ unsigned int freq;
+ unsigned int vco;
+} skl_cdclk_frequencies[] = {
+ { .freq = 308570, .vco = 8640 },
+ { .freq = 337500, .vco = 8100 },
+ { .freq = 432000, .vco = 8640 },
+ { .freq = 450000, .vco = 8100 },
+ { .freq = 540000, .vco = 8100 },
+ { .freq = 617140, .vco = 8640 },
+ { .freq = 675000, .vco = 8100 },
+};
+
+static unsigned int skl_cdclk_decimal(unsigned int freq)
+{
+ return (freq - 1000) / 500;
+}
+
+static unsigned int skl_cdclk_get_vco(unsigned int freq)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(skl_cdclk_frequencies); i++) {
+ const struct skl_cdclk_entry *e = &skl_cdclk_frequencies[i];
+
+ if (e->freq == freq)
+ return e->vco;
+ }
+
+ return 8100;
+}
+
+static void
+skl_dpll0_enable(struct drm_i915_private *dev_priv, unsigned int required_vco)
+{
+ unsigned int min_freq;
+ u32 val;
+
+ /* select the minimum CDCLK before enabling DPLL 0 */
+ val = I915_READ(CDCLK_CTL);
+ val &= ~CDCLK_FREQ_SEL_MASK | ~CDCLK_FREQ_DECIMAL_MASK;
+ val |= CDCLK_FREQ_337_308;
+
+ if (required_vco == 8640)
+ min_freq = 308570;
+ else
+ min_freq = 337500;
+
+ val = CDCLK_FREQ_337_308 | skl_cdclk_decimal(min_freq);
+
+ I915_WRITE(CDCLK_CTL, val);
+ POSTING_READ(CDCLK_CTL);
+
+ /*
+ * We always enable DPLL0 with the lowest link rate possible, but still
+ * taking into account the VCO required to operate the eDP panel at the
+ * desired frequency. The usual DP link rates operate with a VCO of
+ * 8100 while the eDP 1.4 alternate link rates need a VCO of 8640.
+ * The modeset code is responsible for the selection of the exact link
+ * rate later on, with the constraint of choosing a frequency that
+ * works with required_vco.
+ */
+ val = I915_READ(DPLL_CTRL1);
+
+ val &= ~(DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) | DPLL_CTRL1_SSC(SKL_DPLL0) |
+ DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0));
+ val |= DPLL_CTRL1_OVERRIDE(SKL_DPLL0);
+ if (required_vco == 8640)
+ val |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080,
+ SKL_DPLL0);
+ else
+ val |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810,
+ SKL_DPLL0);
+
+ I915_WRITE(DPLL_CTRL1, val);
+ POSTING_READ(DPLL_CTRL1);
+
+ I915_WRITE(LCPLL1_CTL, I915_READ(LCPLL1_CTL) | LCPLL_PLL_ENABLE);
+
+ if (wait_for(I915_READ(LCPLL1_CTL) & LCPLL_PLL_LOCK, 5))
+ DRM_ERROR("DPLL0 not locked\n");
+}
+
+static bool skl_cdclk_pcu_ready(struct drm_i915_private *dev_priv)
+{
+ int ret;
+ u32 val;
+
+ /* inform PCU we want to change CDCLK */
+ val = SKL_CDCLK_PREPARE_FOR_CHANGE;
+ mutex_lock(&dev_priv->rps.hw_lock);
+ ret = sandybridge_pcode_read(dev_priv, SKL_PCODE_CDCLK_CONTROL, &val);
+ mutex_unlock(&dev_priv->rps.hw_lock);
+
+ return ret == 0 && (val & SKL_CDCLK_READY_FOR_CHANGE);
+}
+
+static bool skl_cdclk_wait_for_pcu_ready(struct drm_i915_private *dev_priv)
+{
+ unsigned int i;
+
+ for (i = 0; i < 15; i++) {
+ if (skl_cdclk_pcu_ready(dev_priv))
+ return true;
+ udelay(10);
+ }
+
+ return false;
+}
+
+static void skl_set_cdclk(struct drm_i915_private *dev_priv, unsigned int freq)
+{
+ u32 freq_select, pcu_ack;
+
+ DRM_DEBUG_DRIVER("Changing CDCLK to %dKHz\n", freq);
+
+ if (!skl_cdclk_wait_for_pcu_ready(dev_priv)) {
+ DRM_ERROR("failed to inform PCU about cdclk change\n");
+ return;
+ }
+
+ /* set CDCLK_CTL */
+ switch(freq) {
+ case 450000:
+ case 432000:
+ freq_select = CDCLK_FREQ_450_432;
+ pcu_ack = 1;
+ break;
+ case 540000:
+ freq_select = CDCLK_FREQ_540;
+ pcu_ack = 2;
+ break;
+ case 308570:
+ case 337500:
+ default:
+ freq_select = CDCLK_FREQ_337_308;
+ pcu_ack = 0;
+ break;
+ case 617140:
+ case 675000:
+ freq_select = CDCLK_FREQ_675_617;
+ pcu_ack = 3;
+ break;
+ }
+
+ I915_WRITE(CDCLK_CTL, freq_select | skl_cdclk_decimal(freq));
+ POSTING_READ(CDCLK_CTL);
+
+ /* inform PCU of the change */
+ mutex_lock(&dev_priv->rps.hw_lock);
+ sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, pcu_ack);
+ mutex_unlock(&dev_priv->rps.hw_lock);
+}
+
+void skl_uninit_cdclk(struct drm_i915_private *dev_priv)
+{
+ /* disable DBUF power */
+ I915_WRITE(DBUF_CTL, I915_READ(DBUF_CTL) & ~DBUF_POWER_REQUEST);
+ POSTING_READ(DBUF_CTL);
+
+ udelay(10);
+
+ if (I915_READ(DBUF_CTL) & DBUF_POWER_STATE)
+ DRM_ERROR("DBuf power disable timeout\n");
+
+ /* disable DPLL0 */
+ I915_WRITE(LCPLL1_CTL, I915_READ(LCPLL1_CTL) & ~LCPLL_PLL_ENABLE);
+ if (wait_for(!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_LOCK), 1))
+ DRM_ERROR("Couldn't disable DPLL0\n");
+
+ intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+}
+
+void skl_init_cdclk(struct drm_i915_private *dev_priv)
+{
+ u32 val;
+ unsigned int required_vco;
+
+ /* enable PCH reset handshake */
+ val = I915_READ(HSW_NDE_RSTWRN_OPT);
+ I915_WRITE(HSW_NDE_RSTWRN_OPT, val | RESET_PCH_HANDSHAKE_ENABLE);
+
+ /* enable PG1 and Misc I/O */
+ intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
+
+ /* DPLL0 already enabed !? */
+ if (I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE) {
+ DRM_DEBUG_DRIVER("DPLL0 already running\n");
+ return;
+ }
+
+ /* enable DPLL0 */
+ required_vco = skl_cdclk_get_vco(dev_priv->skl_boot_cdclk);
+ skl_dpll0_enable(dev_priv, required_vco);
+
+ /* set CDCLK to the frequency the BIOS chose */
+ skl_set_cdclk(dev_priv, dev_priv->skl_boot_cdclk);
+
+ /* enable DBUF power */
+ I915_WRITE(DBUF_CTL, I915_READ(DBUF_CTL) | DBUF_POWER_REQUEST);
+ POSTING_READ(DBUF_CTL);
+
+ udelay(10);
+
+ if (!(I915_READ(DBUF_CTL) & DBUF_POWER_STATE))
+ DRM_ERROR("DBuf power enable timeout\n");
+}
+
/* returns HPLL frequency in kHz */
static int valleyview_get_vco(struct drm_i915_private *dev_priv)
{
int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
/* Obtain SKU information */
- mutex_lock(&dev_priv->dpio_lock);
+ mutex_lock(&dev_priv->sb_lock);
hpll_freq = vlv_cck_read(dev_priv, CCK_FUSE_REG) &
CCK_FUSE_HPLL_FREQ_MASK;
- mutex_unlock(&dev_priv->dpio_lock);
+ mutex_unlock(&dev_priv->sb_lock);
return vco_freq[hpll_freq] * 1000;
}
}
mutex_unlock(&dev_priv->rps.hw_lock);
+ mutex_lock(&dev_priv->sb_lock);
+
if (cdclk == 400000) {
u32 divider;
divider = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
- mutex_lock(&dev_priv->dpio_lock);
/* adjust cdclk divider */
val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);
val &= ~DISPLAY_FREQUENCY_VALUES;
DISPLAY_FREQUENCY_STATUS) == (divider << DISPLAY_FREQUENCY_STATUS_SHIFT),
50))
DRM_ERROR("timed out waiting for CDclk change\n");
- mutex_unlock(&dev_priv->dpio_lock);
}
- mutex_lock(&dev_priv->dpio_lock);
/* adjust self-refresh exit latency value */
val = vlv_bunit_read(dev_priv, BUNIT_REG_BISOC);
val &= ~0x7f;
else
val |= 3000 / 250; /* 3.0 usec */
vlv_bunit_write(dev_priv, BUNIT_REG_BISOC, val);
- mutex_unlock(&dev_priv->dpio_lock);
+
+ mutex_unlock(&dev_priv->sb_lock);
vlv_update_cdclk(dev);
}
if (dev_priv->hpll_freq == 0)
dev_priv->hpll_freq = valleyview_get_vco(dev_priv);
- mutex_lock(&dev_priv->dpio_lock);
+ mutex_lock(&dev_priv->sb_lock);
val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);
- mutex_unlock(&dev_priv->dpio_lock);
+ mutex_unlock(&dev_priv->sb_lock);
divider = val & DISPLAY_FREQUENCY_VALUES;
u32 bestn, bestm1, bestm2, bestp1, bestp2;
u32 coreclk, reg_val;
- mutex_lock(&dev_priv->dpio_lock);
+ mutex_lock(&dev_priv->sb_lock);
bestn = pipe_config->dpll.n;
bestm1 = pipe_config->dpll.m1;
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW7(pipe), coreclk);
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW11(pipe), 0x87871000);
- mutex_unlock(&dev_priv->dpio_lock);
+ mutex_unlock(&dev_priv->sb_lock);
}
static void chv_update_pll(struct intel_crtc *crtc,
I915_WRITE(dpll_reg,
pipe_config->dpll_hw_state.dpll & ~DPLL_VCO_ENABLE);
- mutex_lock(&dev_priv->dpio_lock);
+ mutex_lock(&dev_priv->sb_lock);
/* p1 and p2 divider */
vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW13(port),
vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port)) |
DPIO_AFC_RECAL);
- mutex_unlock(&dev_priv->dpio_lock);
+ mutex_unlock(&dev_priv->sb_lock);
}
/**
struct drm_connector_state *connector_state;
int i;
+ memset(&crtc_state->dpll_hw_state, 0,
+ sizeof(crtc_state->dpll_hw_state));
+
for_each_connector_in_state(state, connector, connector_state, i) {
if (connector_state->crtc != &crtc->base)
continue;
if (!(pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE))
return;
- mutex_lock(&dev_priv->dpio_lock);
+ mutex_lock(&dev_priv->sb_lock);
mdiv = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW3(pipe));
- mutex_unlock(&dev_priv->dpio_lock);
+ mutex_unlock(&dev_priv->sb_lock);
clock.m1 = (mdiv >> DPIO_M1DIV_SHIFT) & 7;
clock.m2 = mdiv & DPIO_M2DIV_MASK;
u32 cmn_dw13, pll_dw0, pll_dw1, pll_dw2;
int refclk = 100000;
- mutex_lock(&dev_priv->dpio_lock);
+ mutex_lock(&dev_priv->sb_lock);
cmn_dw13 = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW13(port));
pll_dw0 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW0(port));
pll_dw1 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW1(port));
pll_dw2 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW2(port));
- mutex_unlock(&dev_priv->dpio_lock);
+ mutex_unlock(&dev_priv->sb_lock);
clock.m1 = (pll_dw1 & 0x7) == DPIO_CHV_M1_DIV_BY_2 ? 2 : 0;
clock.m2 = ((pll_dw0 & 0xff) << 22) | (pll_dw2 & 0x3fffff);
with_fdi, "LP PCH doesn't have FDI\n"))
with_fdi = false;
- mutex_lock(&dev_priv->dpio_lock);
+ mutex_lock(&dev_priv->sb_lock);
tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK);
tmp &= ~SBI_SSCCTL_DISABLE;
tmp |= SBI_GEN0_CFG_BUFFENABLE_DISABLE;
intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK);
- mutex_unlock(&dev_priv->dpio_lock);
+ mutex_unlock(&dev_priv->sb_lock);
}
/* Sequence to disable CLKOUT_DP */
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t reg, tmp;
- mutex_lock(&dev_priv->dpio_lock);
+ mutex_lock(&dev_priv->sb_lock);
reg = (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) ?
SBI_GEN0 : SBI_DBUFF0;
intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK);
}
- mutex_unlock(&dev_priv->dpio_lock);
+ mutex_unlock(&dev_priv->sb_lock);
}
static void lpt_init_pch_refclk(struct drm_device *dev)
bool is_lvds = false;
struct intel_shared_dpll *pll;
+ memset(&crtc_state->dpll_hw_state, 0,
+ sizeof(crtc_state->dpll_hw_state));
+
is_lvds = intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS);
WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)),
else if (i915.enable_execlists)
return true;
else
- return ring != i915_gem_request_get_ring(obj->last_read_req);
+ return ring != i915_gem_request_get_ring(obj->last_write_req);
}
static void skl_do_mmio_flip(struct intel_crtc *intel_crtc)
struct intel_mmio_flip *mmio_flip =
container_of(work, struct intel_mmio_flip, work);
- if (mmio_flip->rq)
- WARN_ON(__i915_wait_request(mmio_flip->rq,
+ if (mmio_flip->req)
+ WARN_ON(__i915_wait_request(mmio_flip->req,
mmio_flip->crtc->reset_counter,
- false, NULL, NULL));
+ false, NULL,
+ &mmio_flip->i915->rps.mmioflips));
intel_do_mmio_flip(mmio_flip->crtc);
- i915_gem_request_unreference__unlocked(mmio_flip->rq);
+ i915_gem_request_unreference__unlocked(mmio_flip->req);
kfree(mmio_flip);
}
if (mmio_flip == NULL)
return -ENOMEM;
- mmio_flip->rq = i915_gem_request_reference(obj->last_write_req);
+ mmio_flip->i915 = to_i915(dev);
+ mmio_flip->req = i915_gem_request_reference(obj->last_write_req);
mmio_flip->crtc = to_intel_crtc(crtc);
INIT_WORK(&mmio_flip->work, intel_mmio_flip_work_func);
} else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) {
ring = &dev_priv->ring[BCS];
} else if (INTEL_INFO(dev)->gen >= 7) {
- ring = i915_gem_request_get_ring(obj->last_read_req);
+ ring = i915_gem_request_get_ring(obj->last_write_req);
if (ring == NULL || ring->id != RCS)
ring = &dev_priv->ring[BCS];
} else {
*/
ret = intel_pin_and_fence_fb_obj(crtc->primary, fb,
crtc->primary->state,
- mmio_flip ? i915_gem_request_get_ring(obj->last_read_req) : ring);
+ mmio_flip ? i915_gem_request_get_ring(obj->last_write_req) : ring);
if (ret)
goto cleanup_pending;
DRM_DEBUG_KMS("port clock: %d\n", pipe_config->port_clock);
DRM_DEBUG_KMS("pipe src size: %dx%d\n",
pipe_config->pipe_src_w, pipe_config->pipe_src_h);
- DRM_DEBUG_KMS("num_scalers: %d\n", crtc->num_scalers);
- DRM_DEBUG_KMS("scaler_users: 0x%x\n", pipe_config->scaler_state.scaler_users);
- DRM_DEBUG_KMS("scaler id: %d\n", pipe_config->scaler_state.scaler_id);
+ DRM_DEBUG_KMS("num_scalers: %d, scaler_users: 0x%x, scaler_id: %d\n",
+ crtc->num_scalers,
+ pipe_config->scaler_state.scaler_users,
+ pipe_config->scaler_state.scaler_id);
DRM_DEBUG_KMS("gmch pfit: control: 0x%08x, ratios: 0x%08x, lvds border: 0x%08x\n",
pipe_config->gmch_pfit.control,
pipe_config->gmch_pfit.pgm_ratios,
DRM_DEBUG_KMS("ips: %i\n", pipe_config->ips_enabled);
DRM_DEBUG_KMS("double wide: %i\n", pipe_config->double_wide);
+ if (IS_BROXTON(dev)) {
+ DRM_DEBUG_KMS("ddi_pll_sel: %u; dpll_hw_state: ebb0: 0x%x, "
+ "pll0: 0x%x, pll1: 0x%x, pll2: 0x%x, pll3: 0x%x, "
+ "pll6: 0x%x, pll8: 0x%x, pcsdw12: 0x%x\n",
+ pipe_config->ddi_pll_sel,
+ pipe_config->dpll_hw_state.ebb0,
+ pipe_config->dpll_hw_state.pll0,
+ pipe_config->dpll_hw_state.pll1,
+ pipe_config->dpll_hw_state.pll2,
+ pipe_config->dpll_hw_state.pll3,
+ pipe_config->dpll_hw_state.pll6,
+ pipe_config->dpll_hw_state.pll8,
+ pipe_config->dpll_hw_state.pcsdw12);
+ } else if (IS_SKYLAKE(dev)) {
+ DRM_DEBUG_KMS("ddi_pll_sel: %u; dpll_hw_state: "
+ "ctrl1: 0x%x, cfgcr1: 0x%x, cfgcr2: 0x%x\n",
+ pipe_config->ddi_pll_sel,
+ pipe_config->dpll_hw_state.ctrl1,
+ pipe_config->dpll_hw_state.cfgcr1,
+ pipe_config->dpll_hw_state.cfgcr2);
+ } else if (HAS_DDI(dev)) {
+ DRM_DEBUG_KMS("ddi_pll_sel: %u; dpll_hw_state: wrpll: 0x%x\n",
+ pipe_config->ddi_pll_sel,
+ pipe_config->dpll_hw_state.wrpll);
+ } else {
+ DRM_DEBUG_KMS("dpll_hw_state: dpll: 0x%x, dpll_md: 0x%x, "
+ "fp0: 0x%x, fp1: 0x%x\n",
+ pipe_config->dpll_hw_state.dpll,
+ pipe_config->dpll_hw_state.dpll_md,
+ pipe_config->dpll_hw_state.fp0,
+ pipe_config->dpll_hw_state.fp1);
+ }
+
DRM_DEBUG_KMS("planes on this crtc\n");
list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
intel_plane = to_intel_plane(plane);
struct intel_crtc_scaler_state scaler_state;
struct intel_dpll_hw_state dpll_hw_state;
enum intel_dpll_id shared_dpll;
+ uint32_t ddi_pll_sel;
+
+ /* FIXME: before the switch to atomic started, a new pipe_config was
+ * kzalloc'd. Code that depends on any field being zero should be
+ * fixed, so that the crtc_state can be safely duplicated. For now,
+ * only fields that are know to not cause problems are preserved. */
- /* Clear only the intel specific part of the crtc state excluding scalers */
tmp_state = crtc_state->base;
scaler_state = crtc_state->scaler_state;
shared_dpll = crtc_state->shared_dpll;
dpll_hw_state = crtc_state->dpll_hw_state;
+ ddi_pll_sel = crtc_state->ddi_pll_sel;
memset(crtc_state, 0, sizeof *crtc_state);
crtc_state->scaler_state = scaler_state;
crtc_state->shared_dpll = shared_dpll;
crtc_state->dpll_hw_state = dpll_hw_state;
+ crtc_state->ddi_pll_sel = ddi_pll_sel;
}
static int
if (needs_modeset(crtc_state)) {
clear_pipes |= 1 << intel_crtc->pipe;
intel_crtc_state->shared_dpll = DPLL_ID_PRIVATE;
- memset(&intel_crtc_state->dpll_hw_state, 0,
- sizeof(intel_crtc_state->dpll_hw_state));
}
}
intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
if (INTEL_INFO(dev)->gen >= 9) {
- min_scale = 1;
- max_scale = skl_max_scale(intel_crtc, crtc_state);
+ /* use scaler when colorkey is not required */
+ if (to_intel_plane(plane)->ckey.flags == I915_SET_COLORKEY_NONE) {
+ min_scale = 1;
+ max_scale = skl_max_scale(intel_crtc, crtc_state);
+ }
can_position = true;
}
if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4)
primary->plane = !pipe;
- if (INTEL_INFO(dev)->gen <= 3) {
- intel_primary_formats = intel_primary_formats_gen2;
- num_formats = ARRAY_SIZE(intel_primary_formats_gen2);
+ if (INTEL_INFO(dev)->gen >= 9) {
+ intel_primary_formats = skl_primary_formats;
+ num_formats = ARRAY_SIZE(skl_primary_formats);
+ } else if (INTEL_INFO(dev)->gen >= 4) {
+ intel_primary_formats = i965_primary_formats;
+ num_formats = ARRAY_SIZE(i965_primary_formats);
} else {
- intel_primary_formats = intel_primary_formats_gen4;
- num_formats = ARRAY_SIZE(intel_primary_formats_gen4);
+ intel_primary_formats = i8xx_primary_formats;
+ num_formats = ARRAY_SIZE(i8xx_primary_formats);
}
drm_universal_plane_init(dev, &primary->base, 0,
case DRM_FORMAT_ARGB8888:
break;
case DRM_FORMAT_XRGB1555:
- case DRM_FORMAT_ARGB1555:
if (INTEL_INFO(dev)->gen > 3) {
DRM_DEBUG("unsupported pixel format: %s\n",
drm_get_format_name(mode_cmd->pixel_format));
return -EINVAL;
}
break;
- case DRM_FORMAT_XBGR8888:
case DRM_FORMAT_ABGR8888:
+ if (!IS_VALLEYVIEW(dev) && INTEL_INFO(dev)->gen < 9) {
+ DRM_DEBUG("unsupported pixel format: %s\n",
+ drm_get_format_name(mode_cmd->pixel_format));
+ return -EINVAL;
+ }
+ break;
+ case DRM_FORMAT_XBGR8888:
case DRM_FORMAT_XRGB2101010:
- case DRM_FORMAT_ARGB2101010:
case DRM_FORMAT_XBGR2101010:
- case DRM_FORMAT_ABGR2101010:
if (INTEL_INFO(dev)->gen < 4) {
DRM_DEBUG("unsupported pixel format: %s\n",
drm_get_format_name(mode_cmd->pixel_format));
return -EINVAL;
}
break;
+ case DRM_FORMAT_ABGR2101010:
+ if (!IS_VALLEYVIEW(dev)) {
+ DRM_DEBUG("unsupported pixel format: %s\n",
+ drm_get_format_name(mode_cmd->pixel_format));
+ return -EINVAL;
+ }
+ break;
case DRM_FORMAT_YUYV:
case DRM_FORMAT_UYVY:
case DRM_FORMAT_YVYU: