Browse Source

Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux

DRM fixes from Dave Airlie:
  intel: fixes for output regression on 965GM, an oops and a machine
  hang

  radeon: uninitialised var (that gcc didn't warn about for some reason)
  + a couple of correctness fixes.

  exynos: fixes for various things, drop some chunks of unused code.

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm/radeon/kms/vm: fix possible bug in radeon_vm_bo_rmv()
  drm/radeon: fix uninitialized variable
  drm/radeon/kms: fix radeon_dp_get_modes for LVDS bridges (v2)
  drm/i915: Remove use of the autoreported ringbuffer HEAD position
  drm/i915: Prevent a machine hang by checking crtc->active before loading lut
  drm/i915: fix operator precedence when enabling RC6p
  drm/i915: fix a sprite watermark computation to avoid divide by zero if xpos<0
  drm/i915: fix mode set on load pipe. (v2)
  drm/exynos: exynos_drm.h header file fixes
  drm/exynos: added panel physical size.
  drm/exynos: added postclose to release resource.
  drm/exynos: removed exynos_drm_fbdev_recreate function.
  drm/exynos: fixed page flip issue.
  drm/exynos: added possible_clones setup function.
  drm/exynos: removed pageflip_event_list init code when closed.
  drm/exynos: changed priority of mixer layers.
  drm/exynos: Fix typo in exynos_mixer.c
Linus Torvalds 13 years ago
parent
commit
cfa5555cab

+ 11 - 5
drivers/gpu/drm/exynos/exynos_drm_connector.c

@@ -28,6 +28,7 @@
 #include "drmP.h"
 #include "drmP.h"
 #include "drm_crtc_helper.h"
 #include "drm_crtc_helper.h"
 
 
+#include <drm/exynos_drm.h>
 #include "exynos_drm_drv.h"
 #include "exynos_drm_drv.h"
 #include "exynos_drm_encoder.h"
 #include "exynos_drm_encoder.h"
 
 
@@ -44,8 +45,9 @@ struct exynos_drm_connector {
 /* convert exynos_video_timings to drm_display_mode */
 /* convert exynos_video_timings to drm_display_mode */
 static inline void
 static inline void
 convert_to_display_mode(struct drm_display_mode *mode,
 convert_to_display_mode(struct drm_display_mode *mode,
-			struct fb_videomode *timing)
+			struct exynos_drm_panel_info *panel)
 {
 {
+	struct fb_videomode *timing = &panel->timing;
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
 
 	mode->clock = timing->pixclock / 1000;
 	mode->clock = timing->pixclock / 1000;
@@ -60,6 +62,8 @@ convert_to_display_mode(struct drm_display_mode *mode,
 	mode->vsync_start = mode->vdisplay + timing->upper_margin;
 	mode->vsync_start = mode->vdisplay + timing->upper_margin;
 	mode->vsync_end = mode->vsync_start + timing->vsync_len;
 	mode->vsync_end = mode->vsync_start + timing->vsync_len;
 	mode->vtotal = mode->vsync_end + timing->lower_margin;
 	mode->vtotal = mode->vsync_end + timing->lower_margin;
+	mode->width_mm = panel->width_mm;
+	mode->height_mm = panel->height_mm;
 
 
 	if (timing->vmode & FB_VMODE_INTERLACED)
 	if (timing->vmode & FB_VMODE_INTERLACED)
 		mode->flags |= DRM_MODE_FLAG_INTERLACE;
 		mode->flags |= DRM_MODE_FLAG_INTERLACE;
@@ -148,16 +152,18 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
 		connector->display_info.raw_edid = edid;
 		connector->display_info.raw_edid = edid;
 	} else {
 	} else {
 		struct drm_display_mode *mode = drm_mode_create(connector->dev);
 		struct drm_display_mode *mode = drm_mode_create(connector->dev);
-		struct fb_videomode *timing;
+		struct exynos_drm_panel_info *panel;
 
 
-		if (display_ops->get_timing)
-			timing = display_ops->get_timing(manager->dev);
+		if (display_ops->get_panel)
+			panel = display_ops->get_panel(manager->dev);
 		else {
 		else {
 			drm_mode_destroy(connector->dev, mode);
 			drm_mode_destroy(connector->dev, mode);
 			return 0;
 			return 0;
 		}
 		}
 
 
-		convert_to_display_mode(mode, timing);
+		convert_to_display_mode(mode, panel);
+		connector->display_info.width_mm = mode->width_mm;
+		connector->display_info.height_mm = mode->height_mm;
 
 
 		mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
 		mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
 		drm_mode_set_name(mode);
 		drm_mode_set_name(mode);

+ 2 - 2
drivers/gpu/drm/exynos/exynos_drm_drv.h

@@ -136,7 +136,7 @@ struct exynos_drm_overlay {
  * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI.
  * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI.
  * @is_connected: check for that display is connected or not.
  * @is_connected: check for that display is connected or not.
  * @get_edid: get edid modes from display driver.
  * @get_edid: get edid modes from display driver.
- * @get_timing: get timing object from display driver.
+ * @get_panel: get panel object from display driver.
  * @check_timing: check if timing is valid or not.
  * @check_timing: check if timing is valid or not.
  * @power_on: display device on or off.
  * @power_on: display device on or off.
  */
  */
@@ -145,7 +145,7 @@ struct exynos_drm_display_ops {
 	bool (*is_connected)(struct device *dev);
 	bool (*is_connected)(struct device *dev);
 	int (*get_edid)(struct device *dev, struct drm_connector *connector,
 	int (*get_edid)(struct device *dev, struct drm_connector *connector,
 				u8 *edid, int len);
 				u8 *edid, int len);
-	void *(*get_timing)(struct device *dev);
+	void *(*get_panel)(struct device *dev);
 	int (*check_timing)(struct device *dev, void *timing);
 	int (*check_timing)(struct device *dev, void *timing);
 	int (*power_on)(struct device *dev, int mode);
 	int (*power_on)(struct device *dev, int mode);
 };
 };

+ 14 - 13
drivers/gpu/drm/exynos/exynos_drm_fimd.c

@@ -89,7 +89,7 @@ struct fimd_context {
 	bool				suspended;
 	bool				suspended;
 	struct mutex			lock;
 	struct mutex			lock;
 
 
-	struct fb_videomode		*timing;
+	struct exynos_drm_panel_info *panel;
 };
 };
 
 
 static bool fimd_display_is_connected(struct device *dev)
 static bool fimd_display_is_connected(struct device *dev)
@@ -101,13 +101,13 @@ static bool fimd_display_is_connected(struct device *dev)
 	return true;
 	return true;
 }
 }
 
 
-static void *fimd_get_timing(struct device *dev)
+static void *fimd_get_panel(struct device *dev)
 {
 {
 	struct fimd_context *ctx = get_fimd_context(dev);
 	struct fimd_context *ctx = get_fimd_context(dev);
 
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
 
-	return ctx->timing;
+	return ctx->panel;
 }
 }
 
 
 static int fimd_check_timing(struct device *dev, void *timing)
 static int fimd_check_timing(struct device *dev, void *timing)
@@ -131,7 +131,7 @@ static int fimd_display_power_on(struct device *dev, int mode)
 static struct exynos_drm_display_ops fimd_display_ops = {
 static struct exynos_drm_display_ops fimd_display_ops = {
 	.type = EXYNOS_DISPLAY_TYPE_LCD,
 	.type = EXYNOS_DISPLAY_TYPE_LCD,
 	.is_connected = fimd_display_is_connected,
 	.is_connected = fimd_display_is_connected,
-	.get_timing = fimd_get_timing,
+	.get_panel = fimd_get_panel,
 	.check_timing = fimd_check_timing,
 	.check_timing = fimd_check_timing,
 	.power_on = fimd_display_power_on,
 	.power_on = fimd_display_power_on,
 };
 };
@@ -193,7 +193,8 @@ static void fimd_apply(struct device *subdrv_dev)
 static void fimd_commit(struct device *dev)
 static void fimd_commit(struct device *dev)
 {
 {
 	struct fimd_context *ctx = get_fimd_context(dev);
 	struct fimd_context *ctx = get_fimd_context(dev);
-	struct fb_videomode *timing = ctx->timing;
+	struct exynos_drm_panel_info *panel = ctx->panel;
+	struct fb_videomode *timing = &panel->timing;
 	u32 val;
 	u32 val;
 
 
 	if (ctx->suspended)
 	if (ctx->suspended)
@@ -786,7 +787,7 @@ static int __devinit fimd_probe(struct platform_device *pdev)
 	struct fimd_context *ctx;
 	struct fimd_context *ctx;
 	struct exynos_drm_subdrv *subdrv;
 	struct exynos_drm_subdrv *subdrv;
 	struct exynos_drm_fimd_pdata *pdata;
 	struct exynos_drm_fimd_pdata *pdata;
-	struct fb_videomode *timing;
+	struct exynos_drm_panel_info *panel;
 	struct resource *res;
 	struct resource *res;
 	int win;
 	int win;
 	int ret = -EINVAL;
 	int ret = -EINVAL;
@@ -799,9 +800,9 @@ static int __devinit fimd_probe(struct platform_device *pdev)
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	timing = &pdata->timing;
-	if (!timing) {
-		dev_err(dev, "timing is null.\n");
+	panel = &pdata->panel;
+	if (!panel) {
+		dev_err(dev, "panel is null.\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -863,16 +864,16 @@ static int __devinit fimd_probe(struct platform_device *pdev)
 		goto err_req_irq;
 		goto err_req_irq;
 	}
 	}
 
 
-	ctx->clkdiv = fimd_calc_clkdiv(ctx, timing);
+	ctx->clkdiv = fimd_calc_clkdiv(ctx, &panel->timing);
 	ctx->vidcon0 = pdata->vidcon0;
 	ctx->vidcon0 = pdata->vidcon0;
 	ctx->vidcon1 = pdata->vidcon1;
 	ctx->vidcon1 = pdata->vidcon1;
 	ctx->default_win = pdata->default_win;
 	ctx->default_win = pdata->default_win;
-	ctx->timing = timing;
+	ctx->panel = panel;
 
 
-	timing->pixclock = clk_get_rate(ctx->lcd_clk) / ctx->clkdiv;
+	panel->timing.pixclock = clk_get_rate(ctx->lcd_clk) / ctx->clkdiv;
 
 
 	DRM_DEBUG_KMS("pixel clock = %d, clkdiv = %d\n",
 	DRM_DEBUG_KMS("pixel clock = %d, clkdiv = %d\n",
-			timing->pixclock, ctx->clkdiv);
+			panel->timing.pixclock, ctx->clkdiv);
 
 
 	subdrv = &ctx->subdrv;
 	subdrv = &ctx->subdrv;
 
 

+ 12 - 3
drivers/gpu/drm/i915/intel_display.c

@@ -4680,8 +4680,17 @@ sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane,
 
 
 	crtc = intel_get_crtc_for_plane(dev, plane);
 	crtc = intel_get_crtc_for_plane(dev, plane);
 	clock = crtc->mode.clock;
 	clock = crtc->mode.clock;
+	if (!clock) {
+		*sprite_wm = 0;
+		return false;
+	}
 
 
 	line_time_us = (sprite_width * 1000) / clock;
 	line_time_us = (sprite_width * 1000) / clock;
+	if (!line_time_us) {
+		*sprite_wm = 0;
+		return false;
+	}
+
 	line_count = (latency_ns / line_time_us + 1000) / 1000;
 	line_count = (latency_ns / line_time_us + 1000) / 1000;
 	line_size = sprite_width * pixel_size;
 	line_size = sprite_width * pixel_size;
 
 
@@ -6175,7 +6184,7 @@ void intel_crtc_load_lut(struct drm_crtc *crtc)
 	int i;
 	int i;
 
 
 	/* The clocks have to be on to load the palette. */
 	/* The clocks have to be on to load the palette. */
-	if (!crtc->enabled)
+	if (!crtc->enabled || !intel_crtc->active)
 		return;
 		return;
 
 
 	/* use legacy palette for Ironlake */
 	/* use legacy palette for Ironlake */
@@ -6561,7 +6570,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev,
 	mode_cmd.height = mode->vdisplay;
 	mode_cmd.height = mode->vdisplay;
 	mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width,
 	mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width,
 								bpp);
 								bpp);
-	mode_cmd.pixel_format = 0;
+	mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth);
 
 
 	return intel_framebuffer_create(dev, &mode_cmd, obj);
 	return intel_framebuffer_create(dev, &mode_cmd, obj);
 }
 }
@@ -8185,7 +8194,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
 
 
 	if (intel_enable_rc6(dev_priv->dev))
 	if (intel_enable_rc6(dev_priv->dev))
 		rc6_mask = GEN6_RC_CTL_RC6_ENABLE |
 		rc6_mask = GEN6_RC_CTL_RC6_ENABLE |
-			(IS_GEN7(dev_priv->dev)) ? GEN6_RC_CTL_RC6p_ENABLE : 0;
+			((IS_GEN7(dev_priv->dev)) ? GEN6_RC_CTL_RC6p_ENABLE : 0);
 
 
 	I915_WRITE(GEN6_RC_CONTROL,
 	I915_WRITE(GEN6_RC_CONTROL,
 		   rc6_mask |
 		   rc6_mask |

+ 1 - 13
drivers/gpu/drm/i915/intel_ringbuffer.c

@@ -301,7 +301,7 @@ static int init_ring_common(struct intel_ring_buffer *ring)
 
 
 	I915_WRITE_CTL(ring,
 	I915_WRITE_CTL(ring,
 			((ring->size - PAGE_SIZE) & RING_NR_PAGES)
 			((ring->size - PAGE_SIZE) & RING_NR_PAGES)
-			| RING_REPORT_64K | RING_VALID);
+			| RING_VALID);
 
 
 	/* If the head is still not zero, the ring is dead */
 	/* If the head is still not zero, the ring is dead */
 	if ((I915_READ_CTL(ring) & RING_VALID) == 0 ||
 	if ((I915_READ_CTL(ring) & RING_VALID) == 0 ||
@@ -1132,18 +1132,6 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n)
 	struct drm_device *dev = ring->dev;
 	struct drm_device *dev = ring->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	unsigned long end;
 	unsigned long end;
-	u32 head;
-
-	/* If the reported head position has wrapped or hasn't advanced,
-	 * fallback to the slow and accurate path.
-	 */
-	head = intel_read_status_page(ring, 4);
-	if (head > ring->head) {
-		ring->head = head;
-		ring->space = ring_space(ring);
-		if (ring->space >= n)
-			return 0;
-	}
 
 
 	trace_i915_ring_wait_begin(ring);
 	trace_i915_ring_wait_begin(ring);
 	if (drm_core_check_feature(dev, DRIVER_GEM))
 	if (drm_core_check_feature(dev, DRIVER_GEM))

+ 1 - 0
drivers/gpu/drm/radeon/r600_cs.c

@@ -1304,6 +1304,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
 	h0 = G_038004_TEX_HEIGHT(word1) + 1;
 	h0 = G_038004_TEX_HEIGHT(word1) + 1;
 	d0 = G_038004_TEX_DEPTH(word1);
 	d0 = G_038004_TEX_DEPTH(word1);
 	nfaces = 1;
 	nfaces = 1;
+	array = 0;
 	switch (G_038000_DIM(word0)) {
 	switch (G_038000_DIM(word0)) {
 	case V_038000_SQ_TEX_DIM_1D:
 	case V_038000_SQ_TEX_DIM_1D:
 	case V_038000_SQ_TEX_DIM_2D:
 	case V_038000_SQ_TEX_DIM_2D:

+ 17 - 8
drivers/gpu/drm/radeon/radeon_connectors.c

@@ -1117,13 +1117,23 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
 	    (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
 	    (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
 		struct drm_display_mode *mode;
 		struct drm_display_mode *mode;
 
 
-		if (!radeon_dig_connector->edp_on)
-			atombios_set_edp_panel_power(connector,
-						     ATOM_TRANSMITTER_ACTION_POWER_ON);
-		ret = radeon_ddc_get_modes(radeon_connector);
-		if (!radeon_dig_connector->edp_on)
-			atombios_set_edp_panel_power(connector,
-						     ATOM_TRANSMITTER_ACTION_POWER_OFF);
+		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+			if (!radeon_dig_connector->edp_on)
+				atombios_set_edp_panel_power(connector,
+							     ATOM_TRANSMITTER_ACTION_POWER_ON);
+			ret = radeon_ddc_get_modes(radeon_connector);
+			if (!radeon_dig_connector->edp_on)
+				atombios_set_edp_panel_power(connector,
+							     ATOM_TRANSMITTER_ACTION_POWER_OFF);
+		} else {
+			/* need to setup ddc on the bridge */
+			if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) !=
+			    ENCODER_OBJECT_ID_NONE) {
+				if (encoder)
+					radeon_atom_ext_encoder_setup_ddc(encoder);
+			}
+			ret = radeon_ddc_get_modes(radeon_connector);
+		}
 
 
 		if (ret > 0) {
 		if (ret > 0) {
 			if (encoder) {
 			if (encoder) {
@@ -1134,7 +1144,6 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
 			return ret;
 			return ret;
 		}
 		}
 
 
-		encoder = radeon_best_single_encoder(connector);
 		if (!encoder)
 		if (!encoder)
 			return 0;
 			return 0;
 
 

+ 1 - 1
drivers/gpu/drm/radeon/radeon_gart.c

@@ -597,13 +597,13 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev,
 	if (bo_va == NULL)
 	if (bo_va == NULL)
 		return 0;
 		return 0;
 
 
-	list_del(&bo_va->bo_list);
 	mutex_lock(&vm->mutex);
 	mutex_lock(&vm->mutex);
 	radeon_mutex_lock(&rdev->cs_mutex);
 	radeon_mutex_lock(&rdev->cs_mutex);
 	radeon_vm_bo_update_pte(rdev, vm, bo, NULL);
 	radeon_vm_bo_update_pte(rdev, vm, bo, NULL);
 	radeon_mutex_unlock(&rdev->cs_mutex);
 	radeon_mutex_unlock(&rdev->cs_mutex);
 	list_del(&bo_va->vm_list);
 	list_del(&bo_va->vm_list);
 	mutex_unlock(&vm->mutex);
 	mutex_unlock(&vm->mutex);
+	list_del(&bo_va->bo_list);
 
 
 	kfree(bo_va);
 	kfree(bo_va);
 	return 0;
 	return 0;

+ 1 - 0
include/drm/Kbuild

@@ -2,6 +2,7 @@ header-y += drm.h
 header-y += drm_fourcc.h
 header-y += drm_fourcc.h
 header-y += drm_mode.h
 header-y += drm_mode.h
 header-y += drm_sarea.h
 header-y += drm_sarea.h
+header-y += exynos_drm.h
 header-y += i810_drm.h
 header-y += i810_drm.h
 header-y += i915_drm.h
 header-y += i915_drm.h
 header-y += mga_drm.h
 header-y += mga_drm.h

+ 19 - 3
include/drm/exynos_drm.h

@@ -97,15 +97,30 @@ struct drm_exynos_plane_set_zpos {
 #define DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS	DRM_IOWR(DRM_COMMAND_BASE + \
 #define DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS	DRM_IOWR(DRM_COMMAND_BASE + \
 		DRM_EXYNOS_PLANE_SET_ZPOS, struct drm_exynos_plane_set_zpos)
 		DRM_EXYNOS_PLANE_SET_ZPOS, struct drm_exynos_plane_set_zpos)
 
 
+#ifdef __KERNEL__
+
 /**
 /**
- * Platform Specific Structure for DRM based FIMD.
+ * A structure for lcd panel information.
  *
  *
  * @timing: default video mode for initializing
  * @timing: default video mode for initializing
+ * @width_mm: physical size of lcd width.
+ * @height_mm: physical size of lcd height.
+ */
+struct exynos_drm_panel_info {
+	struct fb_videomode timing;
+	u32 width_mm;
+	u32 height_mm;
+};
+
+/**
+ * Platform Specific Structure for DRM based FIMD.
+ *
+ * @panel: default panel info for initializing
  * @default_win: default window layer number to be used for UI.
  * @default_win: default window layer number to be used for UI.
  * @bpp: default bit per pixel.
  * @bpp: default bit per pixel.
  */
  */
 struct exynos_drm_fimd_pdata {
 struct exynos_drm_fimd_pdata {
-	struct fb_videomode		timing;
+	struct exynos_drm_panel_info panel;
 	u32				vidcon0;
 	u32				vidcon0;
 	u32				vidcon1;
 	u32				vidcon1;
 	unsigned int			default_win;
 	unsigned int			default_win;
@@ -139,4 +154,5 @@ struct exynos_drm_hdmi_pdata {
 	unsigned int			bpp;
 	unsigned int			bpp;
 };
 };
 
 
-#endif
+#endif	/* __KERNEL__ */
+#endif	/* _EXYNOS_DRM_H_ */