Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e06b14ee authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie
Browse files

drm/radeon/kms: handle the case of no active displays properly in the bandwidth code

Logic was:
if (mode0 && mode1)
else if (mode0)
else

Should be:
if (mode0 && mode1)
else if (mode0)
else if (mode1)

Otherwise we may end up calculating the priority regs with
unitialized values.

Fixes:
https://bugzilla.kernel.org/show_bug.cgi?id=16492



Signed-off-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Cc: stable@kernel.org
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent ba4420c2
Loading
Loading
Loading
Loading
+9 −18
Original line number Diff line number Diff line
@@ -398,7 +398,9 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
	struct drm_display_mode *mode1 = NULL;
	struct rs690_watermark wm0;
	struct rs690_watermark wm1;
	u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt;
	u32 tmp;
	u32 d1mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1);
	u32 d2mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1);
	fixed20_12 priority_mark02, priority_mark12, fill_rate;
	fixed20_12 a, b;

@@ -495,10 +497,6 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
			d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
			d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
		}
		WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
		WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
		WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
	} else if (mode0) {
		if (dfixed_trunc(wm0.dbpp) > 64)
			a.full = dfixed_mul(wm0.dbpp, wm0.num_line_pair);
@@ -528,13 +526,7 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
		d1mode_priority_a_cnt = dfixed_trunc(priority_mark02);
		if (rdev->disp_priority == 2)
			d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
		WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
		WREG32(R_006D48_D2MODE_PRIORITY_A_CNT,
			S_006D48_D2MODE_PRIORITY_A_OFF(1));
		WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT,
			S_006D4C_D2MODE_PRIORITY_B_OFF(1));
	} else {
	} else if (mode1) {
		if (dfixed_trunc(wm1.dbpp) > 64)
			a.full = dfixed_mul(wm1.dbpp, wm1.num_line_pair);
		else
@@ -563,14 +555,13 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
		d2mode_priority_a_cnt = dfixed_trunc(priority_mark12);
		if (rdev->disp_priority == 2)
			d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
		WREG32(R_006548_D1MODE_PRIORITY_A_CNT,
			S_006548_D1MODE_PRIORITY_A_OFF(1));
		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT,
			S_00654C_D1MODE_PRIORITY_B_OFF(1));
	}

	WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
	WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
	WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
	WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
}
}

uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg)
{
+9 −14
Original line number Diff line number Diff line
@@ -927,7 +927,9 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
	struct drm_display_mode *mode1 = NULL;
	struct rv515_watermark wm0;
	struct rv515_watermark wm1;
	u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt;
	u32 tmp;
	u32 d1mode_priority_a_cnt = MODE_PRIORITY_OFF;
	u32 d2mode_priority_a_cnt = MODE_PRIORITY_OFF;
	fixed20_12 priority_mark02, priority_mark12, fill_rate;
	fixed20_12 a, b;

@@ -1001,10 +1003,6 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
			d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
			d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
		}
		WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
		WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
		WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
		WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
	} else if (mode0) {
		if (dfixed_trunc(wm0.dbpp) > 64)
			a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair);
@@ -1034,11 +1032,7 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
		d1mode_priority_a_cnt = dfixed_trunc(priority_mark02);
		if (rdev->disp_priority == 2)
			d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
		WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
		WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
		WREG32(D2MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);
		WREG32(D2MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF);
	} else {
	} else if (mode1) {
		if (dfixed_trunc(wm1.dbpp) > 64)
			a.full = dfixed_div(wm1.dbpp, wm1.num_line_pair);
		else
@@ -1067,12 +1061,13 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
		d2mode_priority_a_cnt = dfixed_trunc(priority_mark12);
		if (rdev->disp_priority == 2)
			d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
		WREG32(D1MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);
		WREG32(D1MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF);
	}

	WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
	WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
	WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
	WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
}
}

void rv515_bandwidth_update(struct radeon_device *rdev)
{