瀏覽代碼

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

Pull radeon drm stuff from Dave Airlie:
 "Just some radeon fixes, one is for an oops where we run out of ioremap
  space on some big hardware systems in 32-bit mode, stuff doesn't work
  properly but at least the machine will boot.

  One regression fix, and two bugs, one hw, one blit code."

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm/radeon/kms: fix hdmi duallink checks
  drm/radeon/kms: set SX_MISC in the r6xx blit code (v2)
  drm/radeon: deal with errors from framebuffer init path.
  drm/radeon: fix a semaphore deadlock on pre cayman asics
Linus Torvalds 13 年之前
父節點
當前提交
45b8da90f2

+ 3 - 0
drivers/gpu/drm/radeon/r600.c

@@ -2362,6 +2362,9 @@ void r600_semaphore_ring_emit(struct radeon_device *rdev,
 	uint64_t addr = semaphore->gpu_addr;
 	uint64_t addr = semaphore->gpu_addr;
 	unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL;
 	unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL;
 
 
+	if (rdev->family < CHIP_CAYMAN)
+		sel |= PACKET3_SEM_WAIT_ON_SIGNAL;
+
 	radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1));
 	radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1));
 	radeon_ring_write(ring, addr & 0xffffffff);
 	radeon_ring_write(ring, addr & 0xffffffff);
 	radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | sel);
 	radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | sel);

+ 8 - 0
drivers/gpu/drm/radeon/r600_blit_shaders.c

@@ -313,6 +313,10 @@ const u32 r6xx_default_state[] =
 	0x00000000, /* VGT_REUSE_OFF */
 	0x00000000, /* VGT_REUSE_OFF */
 	0x00000000, /* VGT_VTX_CNT_EN */
 	0x00000000, /* VGT_VTX_CNT_EN */
 
 
+	0xc0016900,
+	0x000000d4,
+	0x00000000, /* SX_MISC */
+
 	0xc0016900,
 	0xc0016900,
 	0x000002c8,
 	0x000002c8,
 	0x00000000, /* VGT_STRMOUT_BUFFER_EN */
 	0x00000000, /* VGT_STRMOUT_BUFFER_EN */
@@ -625,6 +629,10 @@ const u32 r7xx_default_state[] =
 	0x00000000, /* VGT_REUSE_OFF */
 	0x00000000, /* VGT_REUSE_OFF */
 	0x00000000, /* VGT_VTX_CNT_EN */
 	0x00000000, /* VGT_VTX_CNT_EN */
 
 
+	0xc0016900,
+	0x000000d4,
+	0x00000000, /* SX_MISC */
+
 	0xc0016900,
 	0xc0016900,
 	0x000002c8,
 	0x000002c8,
 	0x00000000, /* VGT_STRMOUT_BUFFER_EN */
 	0x00000000, /* VGT_STRMOUT_BUFFER_EN */

+ 1 - 0
drivers/gpu/drm/radeon/r600d.h

@@ -831,6 +831,7 @@
 #define	PACKET3_STRMOUT_BUFFER_UPDATE			0x34
 #define	PACKET3_STRMOUT_BUFFER_UPDATE			0x34
 #define	PACKET3_INDIRECT_BUFFER_MP			0x38
 #define	PACKET3_INDIRECT_BUFFER_MP			0x38
 #define	PACKET3_MEM_SEMAPHORE				0x39
 #define	PACKET3_MEM_SEMAPHORE				0x39
+#              define PACKET3_SEM_WAIT_ON_SIGNAL    (0x1 << 12)
 #              define PACKET3_SEM_SEL_SIGNAL	    (0x6 << 29)
 #              define PACKET3_SEM_SEL_SIGNAL	    (0x6 << 29)
 #              define PACKET3_SEM_SEL_WAIT	    (0x7 << 29)
 #              define PACKET3_SEM_SEL_WAIT	    (0x7 << 29)
 #define	PACKET3_MPEG_INDEX				0x3A
 #define	PACKET3_MPEG_INDEX				0x3A

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

@@ -1057,7 +1057,7 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector,
 		    (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B))
 		    (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B))
 			return MODE_OK;
 			return MODE_OK;
 		else if (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_A) {
 		else if (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_A) {
-			if (ASIC_IS_DCE3(rdev)) {
+			if (0) {
 				/* HDMI 1.3+ supports max clock of 340 Mhz */
 				/* HDMI 1.3+ supports max clock of 340 Mhz */
 				if (mode->clock > 340000)
 				if (mode->clock > 340000)
 					return MODE_CLOCK_HIGH;
 					return MODE_CLOCK_HIGH;

+ 15 - 3
drivers/gpu/drm/radeon/radeon_display.c

@@ -1078,15 +1078,21 @@ static const struct drm_framebuffer_funcs radeon_fb_funcs = {
 	.create_handle = radeon_user_framebuffer_create_handle,
 	.create_handle = radeon_user_framebuffer_create_handle,
 };
 };
 
 
-void
+int
 radeon_framebuffer_init(struct drm_device *dev,
 radeon_framebuffer_init(struct drm_device *dev,
 			struct radeon_framebuffer *rfb,
 			struct radeon_framebuffer *rfb,
 			struct drm_mode_fb_cmd2 *mode_cmd,
 			struct drm_mode_fb_cmd2 *mode_cmd,
 			struct drm_gem_object *obj)
 			struct drm_gem_object *obj)
 {
 {
+	int ret;
 	rfb->obj = obj;
 	rfb->obj = obj;
-	drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs);
+	ret = drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs);
+	if (ret) {
+		rfb->obj = NULL;
+		return ret;
+	}
 	drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd);
 	drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd);
+	return 0;
 }
 }
 
 
 static struct drm_framebuffer *
 static struct drm_framebuffer *
@@ -1096,6 +1102,7 @@ radeon_user_framebuffer_create(struct drm_device *dev,
 {
 {
 	struct drm_gem_object *obj;
 	struct drm_gem_object *obj;
 	struct radeon_framebuffer *radeon_fb;
 	struct radeon_framebuffer *radeon_fb;
+	int ret;
 
 
 	obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
 	obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
 	if (obj ==  NULL) {
 	if (obj ==  NULL) {
@@ -1108,7 +1115,12 @@ radeon_user_framebuffer_create(struct drm_device *dev,
 	if (radeon_fb == NULL)
 	if (radeon_fb == NULL)
 		return ERR_PTR(-ENOMEM);
 		return ERR_PTR(-ENOMEM);
 
 
-	radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj);
+	ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj);
+	if (ret) {
+		kfree(radeon_fb);
+		drm_gem_object_unreference_unlocked(obj);
+		return NULL;
+	}
 
 
 	return &radeon_fb->base;
 	return &radeon_fb->base;
 }
 }

+ 2 - 4
drivers/gpu/drm/radeon/radeon_encoders.c

@@ -307,8 +307,6 @@ void radeon_panel_mode_fixup(struct drm_encoder *encoder,
 bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
 bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
 				    u32 pixel_clock)
 				    u32 pixel_clock)
 {
 {
-	struct drm_device *dev = encoder->dev;
-	struct radeon_device *rdev = dev->dev_private;
 	struct drm_connector *connector;
 	struct drm_connector *connector;
 	struct radeon_connector *radeon_connector;
 	struct radeon_connector *radeon_connector;
 	struct radeon_connector_atom_dig *dig_connector;
 	struct radeon_connector_atom_dig *dig_connector;
@@ -326,7 +324,7 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
 	case DRM_MODE_CONNECTOR_HDMIB:
 	case DRM_MODE_CONNECTOR_HDMIB:
 		if (radeon_connector->use_digital) {
 		if (radeon_connector->use_digital) {
 			/* HDMI 1.3 supports up to 340 Mhz over single link */
 			/* HDMI 1.3 supports up to 340 Mhz over single link */
-			if (ASIC_IS_DCE3(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
+			if (0 && drm_detect_hdmi_monitor(radeon_connector->edid)) {
 				if (pixel_clock > 340000)
 				if (pixel_clock > 340000)
 					return true;
 					return true;
 				else
 				else
@@ -348,7 +346,7 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
 			return false;
 			return false;
 		else {
 		else {
 			/* HDMI 1.3 supports up to 340 Mhz over single link */
 			/* HDMI 1.3 supports up to 340 Mhz over single link */
-			if (ASIC_IS_DCE3(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
+			if (0 && drm_detect_hdmi_monitor(radeon_connector->edid)) {
 				if (pixel_clock > 340000)
 				if (pixel_clock > 340000)
 					return true;
 					return true;
 				else
 				else

+ 10 - 1
drivers/gpu/drm/radeon/radeon_fb.c

@@ -209,6 +209,11 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
 							  sizes->surface_depth);
 							  sizes->surface_depth);
 
 
 	ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj);
 	ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj);
+	if (ret) {
+		DRM_ERROR("failed to create fbcon object %d\n", ret);
+		return ret;
+	}
+
 	rbo = gem_to_radeon_bo(gobj);
 	rbo = gem_to_radeon_bo(gobj);
 
 
 	/* okay we have an object now allocate the framebuffer */
 	/* okay we have an object now allocate the framebuffer */
@@ -220,7 +225,11 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
 
 
 	info->par = rfbdev;
 	info->par = rfbdev;
 
 
-	radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj);
+	ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj);
+	if (ret) {
+		DRM_ERROR("failed to initalise framebuffer %d\n", ret);
+		goto out_unref;
+	}
 
 
 	fb = &rfbdev->rfb.base;
 	fb = &rfbdev->rfb.base;
 
 

+ 1 - 1
drivers/gpu/drm/radeon/radeon_mode.h

@@ -649,7 +649,7 @@ extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
 				     u16 blue, int regno);
 				     u16 blue, int regno);
 extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
 extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
 				     u16 *blue, int regno);
 				     u16 *blue, int regno);
-void radeon_framebuffer_init(struct drm_device *dev,
+int radeon_framebuffer_init(struct drm_device *dev,
 			     struct radeon_framebuffer *rfb,
 			     struct radeon_framebuffer *rfb,
 			     struct drm_mode_fb_cmd2 *mode_cmd,
 			     struct drm_mode_fb_cmd2 *mode_cmd,
 			     struct drm_gem_object *obj);
 			     struct drm_gem_object *obj);