Re: radeon modeset crashes on A4-3400 HD6410D

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jan 29, 2013 at 1:09 PM, Mikko Tiihonen <mikko.tiihonen@xxxxxx> wrote:
> Hi,
>
> I have a A4-3400 CPU that I bought half a year ago. I've tried once month,
> but  Fedora has never succeeded in booting in graphical mode.
>
> Some time ago a finally built some custom kernels to figure out why. I
> created a bug to Fedora bug, but it has not progressed.
>
> Analysis:
> The radeon module startup fails with division by zero in
> r6xx_remap_render_backend because the first RB is not enabled and the code
> assuming that enabled RBs must be all the first ones of the valid range.
>
>
> Longer version:
>
> In r600.c:r6xx_remap_render_backend
>
> The function contains only one divide:
>
> u32 r6xx_remap_render_backend(struct radeon_device *rdev,
>                               u32 tiling_pipe_num,
>                               u32 max_rb_num,
>                               u32 total_max_rb_num,
>                               u32 disabled_rb_mask)
> {
>         u32 rendering_pipe_num, rb_num_width, req_rb_num;
> ...
>         /* mask out the RBs that don't exist on that asic */
>         disabled_rb_mask |= (0xff << max_rb_num) & 0xff;
>
>         rendering_pipe_num = 1 << tiling_pipe_num;
>         req_rb_num = total_max_rb_num -
> r600_count_pipe_bits(disabled_rb_mask);
>         BUG_ON(rendering_pipe_num < req_rb_num);
>
>         pipe_rb_ratio = rendering_pipe_num / req_rb_num;
>
> I added a printk to see what actual parameters are passed in:
>
> tiling_pipe_num=2, max_rb_num=1, total_max_rb_num=8, disabled_rb_mask=253
>
> Using those to calculate the divide by zero comes from:
>
> disabled_rb_mask |= 254; -> 255
> req_rb_num = 8 - 8;
>
>
> Quick fix for stable kernel series:
>
> The attached fix activates only in the division by zero case and instead of
> failing uses the given disabled_rb_mask. This is guaranteed to be regression
> free and actually allows me to load the radeon driver successfully. It does
> help with cards that currently work, but for which some usable RBs are
> disabled due to the eager masking.
>
>
> Proper fix would propably be to find out think why the disabled_rb_mask is
> masked the way it is, were there bugs in other places for which it is a
> workaround. I can see two possible modifictions:
> 1) only mask bits exceeding total_max_rb_num instead of the max_rb_num since
> the one enabled RB on A4-3400 can propably be any one of the 8 possible
> values.
> 2) or activate the current code only if there are more than max_rb_num zero
> bits in the given disabled_rb_mask

Looks good.  I've gone ahead and applied your patch for safety sake
and I also added a patch to set up the RBs correctly on your board.
Please test the attached patches.

Thanks!

Alex
From f689e3acbd2e48cc4101e0af454193f81af4baaf Mon Sep 17 00:00:00 2001
From: Mikko Tiihonen <mikko.tiihonen@xxxxxx>
Date: Wed, 30 Jan 2013 14:10:04 -0500
Subject: [PATCH 2/2] drm/radeon: protect against div by 0 in backend setup

Make sure at least one RB is enabled in
r6xx_remap_render_backend() to avoid an division by
zero in some corner cases.

See:
https://bugzilla.redhat.com/show_bug.cgi?id=892233

Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
---
 drivers/gpu/drm/radeon/r600.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index bc2540b..becb03e 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -1462,12 +1462,15 @@ u32 r6xx_remap_render_backend(struct radeon_device *rdev,
 			      u32 disabled_rb_mask)
 {
 	u32 rendering_pipe_num, rb_num_width, req_rb_num;
-	u32 pipe_rb_ratio, pipe_rb_remain;
+	u32 pipe_rb_ratio, pipe_rb_remain, tmp;
 	u32 data = 0, mask = 1 << (max_rb_num - 1);
 	unsigned i, j;
 
 	/* mask out the RBs that don't exist on that asic */
-	disabled_rb_mask |= (0xff << max_rb_num) & 0xff;
+	tmp = disabled_rb_mask | ((0xff << max_rb_num) & 0xff);
+	/* make sure at least one RB is available */
+	if ((tmp & 0xff) != 0xff)
+		disabled_rb_mask = tmp;
 
 	rendering_pipe_num = 1 << tiling_pipe_num;
 	req_rb_num = total_max_rb_num - r600_count_pipe_bits(disabled_rb_mask);
-- 
1.7.7.5

From f7eb97300832f4fe5fe916c5d84cd2e25169330e Mon Sep 17 00:00:00 2001
From: Alex Deucher <alexander.deucher@xxxxxxx>
Date: Wed, 30 Jan 2013 13:57:40 -0500
Subject: [PATCH 1/2] drm/radeon: fix backend map setup on 1 RB sumo boards

Need to adjust the backend map depending on which
RB is enabled.

Fixes:
https://bugzilla.redhat.com/show_bug.cgi?id=892233

Reported-by: Mikko Tiihonen <mikko.tiihonen@xxxxxx>
Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
---
 drivers/gpu/drm/radeon/evergreen.c |   17 ++++++++++++++---
 1 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 112da9b..2270867 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2044,9 +2044,20 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
 	WREG32(HDP_ADDR_CONFIG, gb_addr_config);
 	WREG32(DMA_TILING_CONFIG, gb_addr_config);
 
-	tmp = gb_addr_config & NUM_PIPES_MASK;
-	tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.evergreen.max_backends,
-					EVERGREEN_MAX_BACKENDS, disabled_rb_mask);
+	if ((rdev->config.evergreen.max_backends == 1) &&
+	    (rdev->flags & RADEON_IS_IGP)) {
+		if ((disabled_rb_mask & 3) == 1) {
+			/* RB0 disabled, RB1 enabled */
+			tmp = 0x11111111;
+		} else {
+			/* RB1 disabled, RB0 enabled */
+			tmp = 0x00000000;
+		}
+	} else {
+		tmp = gb_addr_config & NUM_PIPES_MASK;
+		tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.evergreen.max_backends,
+						EVERGREEN_MAX_BACKENDS, disabled_rb_mask);
+	}
 	WREG32(GB_BACKEND_MAP, tmp);
 
 	WREG32(CGTS_SYS_TCC_DISABLE, 0);
-- 
1.7.7.5

_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/dri-devel

[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux