|
@@ -51,7 +51,10 @@ static void ironlake_pch_clock_get(struct intel_crtc *crtc,
|
|
|
|
|
|
static int intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
|
|
static int intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
|
|
int x, int y, struct drm_framebuffer *old_fb);
|
|
int x, int y, struct drm_framebuffer *old_fb);
|
|
-
|
|
|
|
|
|
+static int intel_framebuffer_init(struct drm_device *dev,
|
|
|
|
+ struct intel_framebuffer *ifb,
|
|
|
|
+ struct drm_mode_fb_cmd2 *mode_cmd,
|
|
|
|
+ struct drm_i915_gem_object *obj);
|
|
|
|
|
|
typedef struct {
|
|
typedef struct {
|
|
int min, max;
|
|
int min, max;
|
|
@@ -1030,7 +1033,7 @@ static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv,
|
|
u32 val;
|
|
u32 val;
|
|
|
|
|
|
/* ILK FDI PLL is always enabled */
|
|
/* ILK FDI PLL is always enabled */
|
|
- if (dev_priv->info->gen == 5)
|
|
|
|
|
|
+ if (INTEL_INFO(dev_priv->dev)->gen == 5)
|
|
return;
|
|
return;
|
|
|
|
|
|
/* On Haswell, DDI ports are responsible for the FDI PLL setup */
|
|
/* On Haswell, DDI ports are responsible for the FDI PLL setup */
|
|
@@ -1189,7 +1192,7 @@ static void assert_sprites_disabled(struct drm_i915_private *dev_priv,
|
|
u32 val;
|
|
u32 val;
|
|
|
|
|
|
if (IS_VALLEYVIEW(dev)) {
|
|
if (IS_VALLEYVIEW(dev)) {
|
|
- for (i = 0; i < dev_priv->num_plane; i++) {
|
|
|
|
|
|
+ for (i = 0; i < INTEL_INFO(dev)->num_sprites; i++) {
|
|
reg = SPCNTR(pipe, i);
|
|
reg = SPCNTR(pipe, i);
|
|
val = I915_READ(reg);
|
|
val = I915_READ(reg);
|
|
WARN((val & SP_ENABLE),
|
|
WARN((val & SP_ENABLE),
|
|
@@ -1443,7 +1446,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc)
|
|
assert_pipe_disabled(dev_priv, crtc->pipe);
|
|
assert_pipe_disabled(dev_priv, crtc->pipe);
|
|
|
|
|
|
/* No really, not for ILK+ */
|
|
/* No really, not for ILK+ */
|
|
- BUG_ON(dev_priv->info->gen >= 5);
|
|
|
|
|
|
+ BUG_ON(INTEL_INFO(dev)->gen >= 5);
|
|
|
|
|
|
/* PLL is protected by panel, make sure we can write it */
|
|
/* PLL is protected by panel, make sure we can write it */
|
|
if (IS_MOBILE(dev) && !IS_I830(dev))
|
|
if (IS_MOBILE(dev) && !IS_I830(dev))
|
|
@@ -1549,11 +1552,12 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
|
|
*/
|
|
*/
|
|
static void ironlake_enable_shared_dpll(struct intel_crtc *crtc)
|
|
static void ironlake_enable_shared_dpll(struct intel_crtc *crtc)
|
|
{
|
|
{
|
|
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
|
|
|
|
|
|
+ struct drm_device *dev = crtc->base.dev;
|
|
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
|
|
struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
|
|
|
|
|
|
/* PCH PLLs only available on ILK, SNB and IVB */
|
|
/* PCH PLLs only available on ILK, SNB and IVB */
|
|
- BUG_ON(dev_priv->info->gen < 5);
|
|
|
|
|
|
+ BUG_ON(INTEL_INFO(dev)->gen < 5);
|
|
if (WARN_ON(pll == NULL))
|
|
if (WARN_ON(pll == NULL))
|
|
return;
|
|
return;
|
|
|
|
|
|
@@ -1578,11 +1582,12 @@ static void ironlake_enable_shared_dpll(struct intel_crtc *crtc)
|
|
|
|
|
|
static void intel_disable_shared_dpll(struct intel_crtc *crtc)
|
|
static void intel_disable_shared_dpll(struct intel_crtc *crtc)
|
|
{
|
|
{
|
|
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
|
|
|
|
|
|
+ struct drm_device *dev = crtc->base.dev;
|
|
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
|
|
struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
|
|
|
|
|
|
/* PCH only available on ILK+ */
|
|
/* PCH only available on ILK+ */
|
|
- BUG_ON(dev_priv->info->gen < 5);
|
|
|
|
|
|
+ BUG_ON(INTEL_INFO(dev)->gen < 5);
|
|
if (WARN_ON(pll == NULL))
|
|
if (WARN_ON(pll == NULL))
|
|
return;
|
|
return;
|
|
|
|
|
|
@@ -1617,7 +1622,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
|
|
uint32_t reg, val, pipeconf_val;
|
|
uint32_t reg, val, pipeconf_val;
|
|
|
|
|
|
/* PCH only available on ILK+ */
|
|
/* PCH only available on ILK+ */
|
|
- BUG_ON(dev_priv->info->gen < 5);
|
|
|
|
|
|
+ BUG_ON(INTEL_INFO(dev)->gen < 5);
|
|
|
|
|
|
/* Make sure PCH DPLL is enabled */
|
|
/* Make sure PCH DPLL is enabled */
|
|
assert_shared_dpll_enabled(dev_priv,
|
|
assert_shared_dpll_enabled(dev_priv,
|
|
@@ -1670,7 +1675,7 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
|
|
u32 val, pipeconf_val;
|
|
u32 val, pipeconf_val;
|
|
|
|
|
|
/* PCH only available on ILK+ */
|
|
/* PCH only available on ILK+ */
|
|
- BUG_ON(dev_priv->info->gen < 5);
|
|
|
|
|
|
+ BUG_ON(INTEL_INFO(dev_priv->dev)->gen < 5);
|
|
|
|
|
|
/* FDI must be feeding us bits for PCH ports */
|
|
/* FDI must be feeding us bits for PCH ports */
|
|
assert_fdi_tx_enabled(dev_priv, (enum pipe) cpu_transcoder);
|
|
assert_fdi_tx_enabled(dev_priv, (enum pipe) cpu_transcoder);
|
|
@@ -1744,21 +1749,16 @@ static void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv)
|
|
|
|
|
|
/**
|
|
/**
|
|
* intel_enable_pipe - enable a pipe, asserting requirements
|
|
* intel_enable_pipe - enable a pipe, asserting requirements
|
|
- * @dev_priv: i915 private structure
|
|
|
|
- * @pipe: pipe to enable
|
|
|
|
- * @pch_port: on ILK+, is this pipe driving a PCH port or not
|
|
|
|
|
|
+ * @crtc: crtc responsible for the pipe
|
|
*
|
|
*
|
|
- * Enable @pipe, making sure that various hardware specific requirements
|
|
|
|
|
|
+ * Enable @crtc's pipe, making sure that various hardware specific requirements
|
|
* are met, if applicable, e.g. PLL enabled, LVDS pairs enabled, etc.
|
|
* are met, if applicable, e.g. PLL enabled, LVDS pairs enabled, etc.
|
|
- *
|
|
|
|
- * @pipe should be %PIPE_A or %PIPE_B.
|
|
|
|
- *
|
|
|
|
- * Will wait until the pipe is actually running (i.e. first vblank) before
|
|
|
|
- * returning.
|
|
|
|
*/
|
|
*/
|
|
-static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
|
|
|
|
- bool pch_port, bool dsi)
|
|
|
|
|
|
+static void intel_enable_pipe(struct intel_crtc *crtc)
|
|
{
|
|
{
|
|
|
|
+ struct drm_device *dev = crtc->base.dev;
|
|
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
+ enum pipe pipe = crtc->pipe;
|
|
enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
|
|
enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
|
|
pipe);
|
|
pipe);
|
|
enum pipe pch_transcoder;
|
|
enum pipe pch_transcoder;
|
|
@@ -1780,12 +1780,12 @@ static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
|
|
* need the check.
|
|
* need the check.
|
|
*/
|
|
*/
|
|
if (!HAS_PCH_SPLIT(dev_priv->dev))
|
|
if (!HAS_PCH_SPLIT(dev_priv->dev))
|
|
- if (dsi)
|
|
|
|
|
|
+ if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DSI))
|
|
assert_dsi_pll_enabled(dev_priv);
|
|
assert_dsi_pll_enabled(dev_priv);
|
|
else
|
|
else
|
|
assert_pll_enabled(dev_priv, pipe);
|
|
assert_pll_enabled(dev_priv, pipe);
|
|
else {
|
|
else {
|
|
- if (pch_port) {
|
|
|
|
|
|
+ if (crtc->config.has_pch_encoder) {
|
|
/* if driving the PCH, we need FDI enabled */
|
|
/* if driving the PCH, we need FDI enabled */
|
|
assert_fdi_rx_pll_enabled(dev_priv, pch_transcoder);
|
|
assert_fdi_rx_pll_enabled(dev_priv, pch_transcoder);
|
|
assert_fdi_tx_pll_enabled(dev_priv,
|
|
assert_fdi_tx_pll_enabled(dev_priv,
|
|
@@ -1796,11 +1796,24 @@ static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
|
|
|
|
|
|
reg = PIPECONF(cpu_transcoder);
|
|
reg = PIPECONF(cpu_transcoder);
|
|
val = I915_READ(reg);
|
|
val = I915_READ(reg);
|
|
- if (val & PIPECONF_ENABLE)
|
|
|
|
|
|
+ if (val & PIPECONF_ENABLE) {
|
|
|
|
+ WARN_ON(!(pipe == PIPE_A &&
|
|
|
|
+ dev_priv->quirks & QUIRK_PIPEA_FORCE));
|
|
return;
|
|
return;
|
|
|
|
+ }
|
|
|
|
|
|
I915_WRITE(reg, val | PIPECONF_ENABLE);
|
|
I915_WRITE(reg, val | PIPECONF_ENABLE);
|
|
- intel_wait_for_vblank(dev_priv->dev, pipe);
|
|
|
|
|
|
+ POSTING_READ(reg);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * There's no guarantee the pipe will really start running now. It
|
|
|
|
+ * depends on the Gen, the output type and the relative order between
|
|
|
|
+ * pipe and plane enabling. Avoid waiting on HSW+ since it's not
|
|
|
|
+ * necessary.
|
|
|
|
+ * TODO: audit the previous gens.
|
|
|
|
+ */
|
|
|
|
+ if (INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev))
|
|
|
|
+ intel_wait_for_vblank(dev_priv->dev, pipe);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -1851,7 +1864,8 @@ static void intel_disable_pipe(struct drm_i915_private *dev_priv,
|
|
void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
|
|
void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
|
|
enum plane plane)
|
|
enum plane plane)
|
|
{
|
|
{
|
|
- u32 reg = dev_priv->info->gen >= 4 ? DSPSURF(plane) : DSPADDR(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));
|
|
I915_WRITE(reg, I915_READ(reg));
|
|
POSTING_READ(reg);
|
|
POSTING_READ(reg);
|
|
@@ -1929,6 +1943,14 @@ static bool need_vtd_wa(struct drm_device *dev)
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int intel_align_height(struct drm_device *dev, int height, bool tiled)
|
|
|
|
+{
|
|
|
|
+ int tile_height;
|
|
|
|
+
|
|
|
|
+ tile_height = tiled ? (IS_GEN2(dev) ? 16 : 8) : 1;
|
|
|
|
+ return ALIGN(height, tile_height);
|
|
|
|
+}
|
|
|
|
+
|
|
int
|
|
int
|
|
intel_pin_and_fence_fb_obj(struct drm_device *dev,
|
|
intel_pin_and_fence_fb_obj(struct drm_device *dev,
|
|
struct drm_i915_gem_object *obj,
|
|
struct drm_i915_gem_object *obj,
|
|
@@ -2299,33 +2321,6 @@ intel_finish_fb(struct drm_framebuffer *old_fb)
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
-static void intel_crtc_update_sarea_pos(struct drm_crtc *crtc, int x, int y)
|
|
|
|
-{
|
|
|
|
- struct drm_device *dev = crtc->dev;
|
|
|
|
- struct drm_i915_master_private *master_priv;
|
|
|
|
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
-
|
|
|
|
- if (!dev->primary->master)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- master_priv = dev->primary->master->driver_priv;
|
|
|
|
- if (!master_priv->sarea_priv)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- switch (intel_crtc->pipe) {
|
|
|
|
- case 0:
|
|
|
|
- master_priv->sarea_priv->pipeA_x = x;
|
|
|
|
- master_priv->sarea_priv->pipeA_y = y;
|
|
|
|
- break;
|
|
|
|
- case 1:
|
|
|
|
- master_priv->sarea_priv->pipeB_x = x;
|
|
|
|
- master_priv->sarea_priv->pipeB_y = y;
|
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static int
|
|
static int
|
|
intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
|
intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
|
struct drm_framebuffer *fb)
|
|
struct drm_framebuffer *fb)
|
|
@@ -2413,8 +2408,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
|
intel_edp_psr_update(dev);
|
|
intel_edp_psr_update(dev);
|
|
mutex_unlock(&dev->struct_mutex);
|
|
mutex_unlock(&dev->struct_mutex);
|
|
|
|
|
|
- intel_crtc_update_sarea_pos(crtc, x, y);
|
|
|
|
-
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3587,8 +3580,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
|
|
intel_crtc_load_lut(crtc);
|
|
intel_crtc_load_lut(crtc);
|
|
|
|
|
|
intel_update_watermarks(crtc);
|
|
intel_update_watermarks(crtc);
|
|
- intel_enable_pipe(dev_priv, pipe,
|
|
|
|
- intel_crtc->config.has_pch_encoder, false);
|
|
|
|
|
|
+ intel_enable_pipe(intel_crtc);
|
|
intel_enable_primary_plane(dev_priv, plane, pipe);
|
|
intel_enable_primary_plane(dev_priv, plane, pipe);
|
|
intel_enable_planes(crtc);
|
|
intel_enable_planes(crtc);
|
|
intel_crtc_update_cursor(crtc, true);
|
|
intel_crtc_update_cursor(crtc, true);
|
|
@@ -3733,8 +3725,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
|
|
intel_ddi_enable_transcoder_func(crtc);
|
|
intel_ddi_enable_transcoder_func(crtc);
|
|
|
|
|
|
intel_update_watermarks(crtc);
|
|
intel_update_watermarks(crtc);
|
|
- intel_enable_pipe(dev_priv, pipe,
|
|
|
|
- intel_crtc->config.has_pch_encoder, false);
|
|
|
|
|
|
+ intel_enable_pipe(intel_crtc);
|
|
|
|
|
|
if (intel_crtc->config.has_pch_encoder)
|
|
if (intel_crtc->config.has_pch_encoder)
|
|
lpt_pch_enable(crtc);
|
|
lpt_pch_enable(crtc);
|
|
@@ -3748,16 +3739,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
|
|
* to change the workaround. */
|
|
* to change the workaround. */
|
|
haswell_mode_set_planes_workaround(intel_crtc);
|
|
haswell_mode_set_planes_workaround(intel_crtc);
|
|
haswell_crtc_enable_planes(crtc);
|
|
haswell_crtc_enable_planes(crtc);
|
|
-
|
|
|
|
- /*
|
|
|
|
- * There seems to be a race in PCH platform hw (at least on some
|
|
|
|
- * outputs) where an enabled pipe still completes any pageflip right
|
|
|
|
- * away (as if the pipe is off) instead of waiting for vblank. As soon
|
|
|
|
- * as the first vblank happend, everything works as expected. Hence just
|
|
|
|
- * wait for one vblank before returning to avoid strange things
|
|
|
|
- * happening.
|
|
|
|
- */
|
|
|
|
- intel_wait_for_vblank(dev, intel_crtc->pipe);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static void ironlake_pfit_disable(struct intel_crtc *crtc)
|
|
static void ironlake_pfit_disable(struct intel_crtc *crtc)
|
|
@@ -4169,7 +4150,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
|
|
intel_crtc_load_lut(crtc);
|
|
intel_crtc_load_lut(crtc);
|
|
|
|
|
|
intel_update_watermarks(crtc);
|
|
intel_update_watermarks(crtc);
|
|
- intel_enable_pipe(dev_priv, pipe, false, is_dsi);
|
|
|
|
|
|
+ intel_enable_pipe(intel_crtc);
|
|
intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
|
|
intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
|
|
intel_enable_primary_plane(dev_priv, plane, pipe);
|
|
intel_enable_primary_plane(dev_priv, plane, pipe);
|
|
intel_enable_planes(crtc);
|
|
intel_enable_planes(crtc);
|
|
@@ -4208,7 +4189,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
|
|
intel_crtc_load_lut(crtc);
|
|
intel_crtc_load_lut(crtc);
|
|
|
|
|
|
intel_update_watermarks(crtc);
|
|
intel_update_watermarks(crtc);
|
|
- intel_enable_pipe(dev_priv, pipe, false, false);
|
|
|
|
|
|
+ intel_enable_pipe(intel_crtc);
|
|
intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
|
|
intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
|
|
intel_enable_primary_plane(dev_priv, plane, pipe);
|
|
intel_enable_primary_plane(dev_priv, plane, pipe);
|
|
intel_enable_planes(crtc);
|
|
intel_enable_planes(crtc);
|
|
@@ -5256,25 +5237,23 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc,
|
|
pipe_config->requested_mode.hdisplay = pipe_config->pipe_src_w;
|
|
pipe_config->requested_mode.hdisplay = pipe_config->pipe_src_w;
|
|
}
|
|
}
|
|
|
|
|
|
-static void intel_crtc_mode_from_pipe_config(struct intel_crtc *intel_crtc,
|
|
|
|
- struct intel_crtc_config *pipe_config)
|
|
|
|
|
|
+void intel_mode_from_pipe_config(struct drm_display_mode *mode,
|
|
|
|
+ struct intel_crtc_config *pipe_config)
|
|
{
|
|
{
|
|
- struct drm_crtc *crtc = &intel_crtc->base;
|
|
|
|
|
|
+ mode->hdisplay = pipe_config->adjusted_mode.crtc_hdisplay;
|
|
|
|
+ mode->htotal = pipe_config->adjusted_mode.crtc_htotal;
|
|
|
|
+ mode->hsync_start = pipe_config->adjusted_mode.crtc_hsync_start;
|
|
|
|
+ mode->hsync_end = pipe_config->adjusted_mode.crtc_hsync_end;
|
|
|
|
|
|
- crtc->mode.hdisplay = pipe_config->adjusted_mode.crtc_hdisplay;
|
|
|
|
- crtc->mode.htotal = pipe_config->adjusted_mode.crtc_htotal;
|
|
|
|
- crtc->mode.hsync_start = pipe_config->adjusted_mode.crtc_hsync_start;
|
|
|
|
- crtc->mode.hsync_end = pipe_config->adjusted_mode.crtc_hsync_end;
|
|
|
|
|
|
+ mode->vdisplay = pipe_config->adjusted_mode.crtc_vdisplay;
|
|
|
|
+ mode->vtotal = pipe_config->adjusted_mode.crtc_vtotal;
|
|
|
|
+ mode->vsync_start = pipe_config->adjusted_mode.crtc_vsync_start;
|
|
|
|
+ mode->vsync_end = pipe_config->adjusted_mode.crtc_vsync_end;
|
|
|
|
|
|
- crtc->mode.vdisplay = pipe_config->adjusted_mode.crtc_vdisplay;
|
|
|
|
- crtc->mode.vtotal = pipe_config->adjusted_mode.crtc_vtotal;
|
|
|
|
- crtc->mode.vsync_start = pipe_config->adjusted_mode.crtc_vsync_start;
|
|
|
|
- crtc->mode.vsync_end = pipe_config->adjusted_mode.crtc_vsync_end;
|
|
|
|
|
|
+ mode->flags = pipe_config->adjusted_mode.flags;
|
|
|
|
|
|
- crtc->mode.flags = pipe_config->adjusted_mode.flags;
|
|
|
|
-
|
|
|
|
- crtc->mode.clock = pipe_config->adjusted_mode.crtc_clock;
|
|
|
|
- crtc->mode.flags |= pipe_config->adjusted_mode.flags;
|
|
|
|
|
|
+ mode->clock = pipe_config->adjusted_mode.crtc_clock;
|
|
|
|
+ mode->flags |= pipe_config->adjusted_mode.flags;
|
|
}
|
|
}
|
|
|
|
|
|
static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
|
|
static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
|
|
@@ -7577,7 +7556,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
|
|
|
|
|
|
/* we only need to pin inside GTT if cursor is non-phy */
|
|
/* we only need to pin inside GTT if cursor is non-phy */
|
|
mutex_lock(&dev->struct_mutex);
|
|
mutex_lock(&dev->struct_mutex);
|
|
- if (!dev_priv->info->cursor_needs_physical) {
|
|
|
|
|
|
+ if (!INTEL_INFO(dev)->cursor_needs_physical) {
|
|
unsigned alignment;
|
|
unsigned alignment;
|
|
|
|
|
|
if (obj->tiling_mode) {
|
|
if (obj->tiling_mode) {
|
|
@@ -7625,7 +7604,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
|
|
|
|
|
|
finish:
|
|
finish:
|
|
if (intel_crtc->cursor_bo) {
|
|
if (intel_crtc->cursor_bo) {
|
|
- if (dev_priv->info->cursor_needs_physical) {
|
|
|
|
|
|
+ if (INTEL_INFO(dev)->cursor_needs_physical) {
|
|
if (intel_crtc->cursor_bo != obj)
|
|
if (intel_crtc->cursor_bo != obj)
|
|
i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo);
|
|
i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo);
|
|
} else
|
|
} else
|
|
@@ -7687,10 +7666,10 @@ static struct drm_display_mode load_detect_mode = {
|
|
704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
|
|
704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
|
|
};
|
|
};
|
|
|
|
|
|
-static struct drm_framebuffer *
|
|
|
|
-intel_framebuffer_create(struct drm_device *dev,
|
|
|
|
- struct drm_mode_fb_cmd2 *mode_cmd,
|
|
|
|
- struct drm_i915_gem_object *obj)
|
|
|
|
|
|
+struct drm_framebuffer *
|
|
|
|
+__intel_framebuffer_create(struct drm_device *dev,
|
|
|
|
+ struct drm_mode_fb_cmd2 *mode_cmd,
|
|
|
|
+ struct drm_i915_gem_object *obj)
|
|
{
|
|
{
|
|
struct intel_framebuffer *intel_fb;
|
|
struct intel_framebuffer *intel_fb;
|
|
int ret;
|
|
int ret;
|
|
@@ -7701,12 +7680,7 @@ intel_framebuffer_create(struct drm_device *dev,
|
|
return ERR_PTR(-ENOMEM);
|
|
return ERR_PTR(-ENOMEM);
|
|
}
|
|
}
|
|
|
|
|
|
- ret = i915_mutex_lock_interruptible(dev);
|
|
|
|
- if (ret)
|
|
|
|
- goto err;
|
|
|
|
-
|
|
|
|
ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj);
|
|
ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj);
|
|
- mutex_unlock(&dev->struct_mutex);
|
|
|
|
if (ret)
|
|
if (ret)
|
|
goto err;
|
|
goto err;
|
|
|
|
|
|
@@ -7718,6 +7692,23 @@ err:
|
|
return ERR_PTR(ret);
|
|
return ERR_PTR(ret);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+struct drm_framebuffer *
|
|
|
|
+intel_framebuffer_create(struct drm_device *dev,
|
|
|
|
+ struct drm_mode_fb_cmd2 *mode_cmd,
|
|
|
|
+ struct drm_i915_gem_object *obj)
|
|
|
|
+{
|
|
|
|
+ struct drm_framebuffer *fb;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ ret = i915_mutex_lock_interruptible(dev);
|
|
|
|
+ if (ret)
|
|
|
|
+ return ERR_PTR(ret);
|
|
|
|
+ fb = __intel_framebuffer_create(dev, mode_cmd, obj);
|
|
|
|
+ mutex_unlock(&dev->struct_mutex);
|
|
|
|
+
|
|
|
|
+ return fb;
|
|
|
|
+}
|
|
|
|
+
|
|
static u32
|
|
static u32
|
|
intel_framebuffer_pitch_for_width(int width, int bpp)
|
|
intel_framebuffer_pitch_for_width(int width, int bpp)
|
|
{
|
|
{
|
|
@@ -7763,14 +7754,16 @@ mode_fits_in_fbdev(struct drm_device *dev,
|
|
struct drm_i915_gem_object *obj;
|
|
struct drm_i915_gem_object *obj;
|
|
struct drm_framebuffer *fb;
|
|
struct drm_framebuffer *fb;
|
|
|
|
|
|
- if (dev_priv->fbdev == NULL)
|
|
|
|
|
|
+ if (!dev_priv->fbdev)
|
|
return NULL;
|
|
return NULL;
|
|
|
|
|
|
- obj = dev_priv->fbdev->ifb.obj;
|
|
|
|
- if (obj == NULL)
|
|
|
|
|
|
+ if (!dev_priv->fbdev->fb)
|
|
return NULL;
|
|
return NULL;
|
|
|
|
|
|
- fb = &dev_priv->fbdev->ifb.base;
|
|
|
|
|
|
+ obj = dev_priv->fbdev->fb->obj;
|
|
|
|
+ BUG_ON(!obj);
|
|
|
|
+
|
|
|
|
+ fb = &dev_priv->fbdev->fb->base;
|
|
if (fb->pitches[0] < intel_framebuffer_pitch_for_width(mode->hdisplay,
|
|
if (fb->pitches[0] < intel_framebuffer_pitch_for_width(mode->hdisplay,
|
|
fb->bits_per_pixel))
|
|
fb->bits_per_pixel))
|
|
return NULL;
|
|
return NULL;
|
|
@@ -8220,7 +8213,7 @@ void intel_mark_idle(struct drm_device *dev)
|
|
intel_decrease_pllclock(crtc);
|
|
intel_decrease_pllclock(crtc);
|
|
}
|
|
}
|
|
|
|
|
|
- if (dev_priv->info->gen >= 6)
|
|
|
|
|
|
+ if (INTEL_INFO(dev)->gen >= 6)
|
|
gen6_rps_idle(dev->dev_private);
|
|
gen6_rps_idle(dev->dev_private);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -10384,8 +10377,7 @@ static bool has_edp_a(struct drm_device *dev)
|
|
if ((I915_READ(DP_A) & DP_DETECTED) == 0)
|
|
if ((I915_READ(DP_A) & DP_DETECTED) == 0)
|
|
return false;
|
|
return false;
|
|
|
|
|
|
- if (IS_GEN5(dev) &&
|
|
|
|
- (I915_READ(ILK_DISPLAY_CHICKEN_FUSES) & ILK_eDP_A_DISABLE))
|
|
|
|
|
|
+ if (IS_GEN5(dev) && (I915_READ(FUSE_STRAP) & ILK_eDP_A_DISABLE))
|
|
return false;
|
|
return false;
|
|
|
|
|
|
return true;
|
|
return true;
|
|
@@ -10538,18 +10530,13 @@ static void intel_setup_outputs(struct drm_device *dev)
|
|
drm_helper_move_panel_connectors_to_head(dev);
|
|
drm_helper_move_panel_connectors_to_head(dev);
|
|
}
|
|
}
|
|
|
|
|
|
-void intel_framebuffer_fini(struct intel_framebuffer *fb)
|
|
|
|
-{
|
|
|
|
- drm_framebuffer_cleanup(&fb->base);
|
|
|
|
- WARN_ON(!fb->obj->framebuffer_references--);
|
|
|
|
- drm_gem_object_unreference_unlocked(&fb->obj->base);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
|
|
static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
|
|
{
|
|
{
|
|
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
|
|
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
|
|
|
|
|
|
- intel_framebuffer_fini(intel_fb);
|
|
|
|
|
|
+ drm_framebuffer_cleanup(fb);
|
|
|
|
+ WARN_ON(!intel_fb->obj->framebuffer_references--);
|
|
|
|
+ drm_gem_object_unreference_unlocked(&intel_fb->obj->base);
|
|
kfree(intel_fb);
|
|
kfree(intel_fb);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -10573,7 +10560,7 @@ int intel_framebuffer_init(struct drm_device *dev,
|
|
struct drm_mode_fb_cmd2 *mode_cmd,
|
|
struct drm_mode_fb_cmd2 *mode_cmd,
|
|
struct drm_i915_gem_object *obj)
|
|
struct drm_i915_gem_object *obj)
|
|
{
|
|
{
|
|
- int aligned_height, tile_height;
|
|
|
|
|
|
+ int aligned_height;
|
|
int pitch_limit;
|
|
int pitch_limit;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
@@ -10667,9 +10654,8 @@ int intel_framebuffer_init(struct drm_device *dev,
|
|
if (mode_cmd->offsets[0] != 0)
|
|
if (mode_cmd->offsets[0] != 0)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
- tile_height = IS_GEN2(dev) ? 16 : 8;
|
|
|
|
- aligned_height = ALIGN(mode_cmd->height,
|
|
|
|
- obj->tiling_mode ? tile_height : 1);
|
|
|
|
|
|
+ aligned_height = intel_align_height(dev, mode_cmd->height,
|
|
|
|
+ obj->tiling_mode);
|
|
/* FIXME drm helper for size checks (especially planar formats)? */
|
|
/* FIXME drm helper for size checks (especially planar formats)? */
|
|
if (obj->base.size < aligned_height * mode_cmd->pitches[0])
|
|
if (obj->base.size < aligned_height * mode_cmd->pitches[0])
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
@@ -11049,7 +11035,7 @@ void intel_modeset_init(struct drm_device *dev)
|
|
|
|
|
|
for_each_pipe(i) {
|
|
for_each_pipe(i) {
|
|
intel_crtc_init(dev, i);
|
|
intel_crtc_init(dev, i);
|
|
- for (j = 0; j < dev_priv->num_plane; j++) {
|
|
|
|
|
|
+ for (j = 0; j < INTEL_INFO(dev)->num_sprites; j++) {
|
|
ret = intel_plane_init(dev, i, j);
|
|
ret = intel_plane_init(dev, i, j);
|
|
if (ret)
|
|
if (ret)
|
|
DRM_DEBUG_KMS("pipe %c sprite %c init failed: %d\n",
|
|
DRM_DEBUG_KMS("pipe %c sprite %c init failed: %d\n",
|
|
@@ -11069,6 +11055,8 @@ void intel_modeset_init(struct drm_device *dev)
|
|
|
|
|
|
/* Just in case the BIOS is doing something questionable. */
|
|
/* Just in case the BIOS is doing something questionable. */
|
|
intel_disable_fbc(dev);
|
|
intel_disable_fbc(dev);
|
|
|
|
+
|
|
|
|
+ intel_modeset_setup_hw_state(dev, false);
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
static void
|
|
@@ -11375,8 +11363,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
|
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list,
|
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list,
|
|
base.head) {
|
|
base.head) {
|
|
if (crtc->active && i915.fastboot) {
|
|
if (crtc->active && i915.fastboot) {
|
|
- intel_crtc_mode_from_pipe_config(crtc, &crtc->config);
|
|
|
|
-
|
|
|
|
|
|
+ intel_mode_from_pipe_config(&crtc->base.mode, &crtc->config);
|
|
DRM_DEBUG_KMS("[CRTC:%d] found active mode: ",
|
|
DRM_DEBUG_KMS("[CRTC:%d] found active mode: ",
|
|
crtc->base.base.id);
|
|
crtc->base.base.id);
|
|
drm_mode_debug_printmodeline(&crtc->base.mode);
|
|
drm_mode_debug_printmodeline(&crtc->base.mode);
|
|
@@ -11436,10 +11423,14 @@ void intel_modeset_gem_init(struct drm_device *dev)
|
|
intel_modeset_init_hw(dev);
|
|
intel_modeset_init_hw(dev);
|
|
|
|
|
|
intel_setup_overlay(dev);
|
|
intel_setup_overlay(dev);
|
|
|
|
+}
|
|
|
|
|
|
- mutex_lock(&dev->mode_config.mutex);
|
|
|
|
- intel_modeset_setup_hw_state(dev, false);
|
|
|
|
- mutex_unlock(&dev->mode_config.mutex);
|
|
|
|
|
|
+void intel_connector_unregister(struct intel_connector *intel_connector)
|
|
|
|
+{
|
|
|
|
+ struct drm_connector *connector = &intel_connector->base;
|
|
|
|
+
|
|
|
|
+ intel_panel_destroy_backlight(connector);
|
|
|
|
+ drm_sysfs_connector_remove(connector);
|
|
}
|
|
}
|
|
|
|
|
|
void intel_modeset_cleanup(struct drm_device *dev)
|
|
void intel_modeset_cleanup(struct drm_device *dev)
|
|
@@ -11486,8 +11477,10 @@ void intel_modeset_cleanup(struct drm_device *dev)
|
|
|
|
|
|
/* destroy the backlight and sysfs files before encoders/connectors */
|
|
/* destroy the backlight and sysfs files before encoders/connectors */
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
|
- intel_panel_destroy_backlight(connector);
|
|
|
|
- drm_sysfs_connector_remove(connector);
|
|
|
|
|
|
+ struct intel_connector *intel_connector;
|
|
|
|
+
|
|
|
|
+ intel_connector = to_intel_connector(connector);
|
|
|
|
+ intel_connector->unregister(intel_connector);
|
|
}
|
|
}
|
|
|
|
|
|
drm_mode_config_cleanup(dev);
|
|
drm_mode_config_cleanup(dev);
|
|
@@ -11520,12 +11513,24 @@ int intel_modeset_vga_set_state(struct drm_device *dev, bool state)
|
|
unsigned reg = INTEL_INFO(dev)->gen >= 6 ? SNB_GMCH_CTRL : INTEL_GMCH_CTRL;
|
|
unsigned reg = INTEL_INFO(dev)->gen >= 6 ? SNB_GMCH_CTRL : INTEL_GMCH_CTRL;
|
|
u16 gmch_ctrl;
|
|
u16 gmch_ctrl;
|
|
|
|
|
|
- pci_read_config_word(dev_priv->bridge_dev, reg, &gmch_ctrl);
|
|
|
|
|
|
+ if (pci_read_config_word(dev_priv->bridge_dev, reg, &gmch_ctrl)) {
|
|
|
|
+ DRM_ERROR("failed to read control word\n");
|
|
|
|
+ return -EIO;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!!(gmch_ctrl & INTEL_GMCH_VGA_DISABLE) == !state)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
if (state)
|
|
if (state)
|
|
gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE;
|
|
gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE;
|
|
else
|
|
else
|
|
gmch_ctrl |= INTEL_GMCH_VGA_DISABLE;
|
|
gmch_ctrl |= INTEL_GMCH_VGA_DISABLE;
|
|
- pci_write_config_word(dev_priv->bridge_dev, reg, gmch_ctrl);
|
|
|
|
|
|
+
|
|
|
|
+ if (pci_write_config_word(dev_priv->bridge_dev, reg, gmch_ctrl)) {
|
|
|
|
+ DRM_ERROR("failed to write control word\n");
|
|
|
|
+ return -EIO;
|
|
|
|
+ }
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|