소스 검색

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

A few more fixes for 4.0 for radeon.  Sorry for the delay, I was
a little under the weather this week and time got away from me.

* 'drm-fixes-4.0' of git://people.freedesktop.org/~agd5f/linux:
  drm/radeon: programm the VCE fw BAR as well
  drm/radeon: always dump the ring content if it's available
  radeon: Do not directly dereference pointers to BIOS area.
  drm/radeon/dpm: fix 120hz handling harder
Dave Airlie 10 년 전
부모
커밋
91fd89660b

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

@@ -2129,6 +2129,7 @@
 #define VCE_UENC_REG_CLOCK_GATING	0x207c0
 #define VCE_UENC_REG_CLOCK_GATING	0x207c0
 #define VCE_SYS_INT_EN			0x21300
 #define VCE_SYS_INT_EN			0x21300
 #	define VCE_SYS_INT_TRAP_INTERRUPT_EN	(1 << 3)
 #	define VCE_SYS_INT_TRAP_INTERRUPT_EN	(1 << 3)
+#define VCE_LMI_VCPU_CACHE_40BIT_BAR	0x2145c
 #define VCE_LMI_CTRL2			0x21474
 #define VCE_LMI_CTRL2			0x21474
 #define VCE_LMI_CTRL			0x21498
 #define VCE_LMI_CTRL			0x21498
 #define VCE_LMI_VM_CTRL			0x214a0
 #define VCE_LMI_VM_CTRL			0x214a0

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

@@ -1565,6 +1565,7 @@ struct radeon_dpm {
 	int			new_active_crtc_count;
 	int			new_active_crtc_count;
 	u32			current_active_crtcs;
 	u32			current_active_crtcs;
 	int			current_active_crtc_count;
 	int			current_active_crtc_count;
+	bool single_display;
 	struct radeon_dpm_dynamic_state dyn_state;
 	struct radeon_dpm_dynamic_state dyn_state;
 	struct radeon_dpm_fan fan;
 	struct radeon_dpm_fan fan;
 	u32 tdp_limit;
 	u32 tdp_limit;

+ 7 - 3
drivers/gpu/drm/radeon/radeon_bios.c

@@ -76,7 +76,7 @@ static bool igp_read_bios_from_vram(struct radeon_device *rdev)
 
 
 static bool radeon_read_bios(struct radeon_device *rdev)
 static bool radeon_read_bios(struct radeon_device *rdev)
 {
 {
-	uint8_t __iomem *bios;
+	uint8_t __iomem *bios, val1, val2;
 	size_t size;
 	size_t size;
 
 
 	rdev->bios = NULL;
 	rdev->bios = NULL;
@@ -86,15 +86,19 @@ static bool radeon_read_bios(struct radeon_device *rdev)
 		return false;
 		return false;
 	}
 	}
 
 
-	if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
+	val1 = readb(&bios[0]);
+	val2 = readb(&bios[1]);
+
+	if (size == 0 || val1 != 0x55 || val2 != 0xaa) {
 		pci_unmap_rom(rdev->pdev, bios);
 		pci_unmap_rom(rdev->pdev, bios);
 		return false;
 		return false;
 	}
 	}
-	rdev->bios = kmemdup(bios, size, GFP_KERNEL);
+	rdev->bios = kzalloc(size, GFP_KERNEL);
 	if (rdev->bios == NULL) {
 	if (rdev->bios == NULL) {
 		pci_unmap_rom(rdev->pdev, bios);
 		pci_unmap_rom(rdev->pdev, bios);
 		return false;
 		return false;
 	}
 	}
+	memcpy_fromio(rdev->bios, bios, size);
 	pci_unmap_rom(rdev->pdev, bios);
 	pci_unmap_rom(rdev->pdev, bios);
 	return true;
 	return true;
 }
 }

+ 17 - 5
drivers/gpu/drm/radeon/radeon_pm.c

@@ -837,12 +837,8 @@ static void radeon_dpm_thermal_work_handler(struct work_struct *work)
 	radeon_pm_compute_clocks(rdev);
 	radeon_pm_compute_clocks(rdev);
 }
 }
 
 
-static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev,
-						     enum radeon_pm_state_type dpm_state)
+static bool radeon_dpm_single_display(struct radeon_device *rdev)
 {
 {
-	int i;
-	struct radeon_ps *ps;
-	u32 ui_class;
 	bool single_display = (rdev->pm.dpm.new_active_crtc_count < 2) ?
 	bool single_display = (rdev->pm.dpm.new_active_crtc_count < 2) ?
 		true : false;
 		true : false;
 
 
@@ -858,6 +854,17 @@ static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev,
 	if (single_display && (r600_dpm_get_vrefresh(rdev) >= 120))
 	if (single_display && (r600_dpm_get_vrefresh(rdev) >= 120))
 		single_display = false;
 		single_display = false;
 
 
+	return single_display;
+}
+
+static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev,
+						     enum radeon_pm_state_type dpm_state)
+{
+	int i;
+	struct radeon_ps *ps;
+	u32 ui_class;
+	bool single_display = radeon_dpm_single_display(rdev);
+
 	/* certain older asics have a separare 3D performance state,
 	/* certain older asics have a separare 3D performance state,
 	 * so try that first if the user selected performance
 	 * so try that first if the user selected performance
 	 */
 	 */
@@ -983,6 +990,7 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev)
 	struct radeon_ps *ps;
 	struct radeon_ps *ps;
 	enum radeon_pm_state_type dpm_state;
 	enum radeon_pm_state_type dpm_state;
 	int ret;
 	int ret;
+	bool single_display = radeon_dpm_single_display(rdev);
 
 
 	/* if dpm init failed */
 	/* if dpm init failed */
 	if (!rdev->pm.dpm_enabled)
 	if (!rdev->pm.dpm_enabled)
@@ -1007,6 +1015,9 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev)
 		/* vce just modifies an existing state so force a change */
 		/* vce just modifies an existing state so force a change */
 		if (ps->vce_active != rdev->pm.dpm.vce_active)
 		if (ps->vce_active != rdev->pm.dpm.vce_active)
 			goto force;
 			goto force;
+		/* user has made a display change (such as timing) */
+		if (rdev->pm.dpm.single_display != single_display)
+			goto force;
 		if ((rdev->family < CHIP_BARTS) || (rdev->flags & RADEON_IS_IGP)) {
 		if ((rdev->family < CHIP_BARTS) || (rdev->flags & RADEON_IS_IGP)) {
 			/* for pre-BTC and APUs if the num crtcs changed but state is the same,
 			/* for pre-BTC and APUs if the num crtcs changed but state is the same,
 			 * all we need to do is update the display configuration.
 			 * all we need to do is update the display configuration.
@@ -1069,6 +1080,7 @@ force:
 
 
 	rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs;
 	rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs;
 	rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count;
 	rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count;
+	rdev->pm.dpm.single_display = single_display;
 
 
 	/* wait for the rings to drain */
 	/* wait for the rings to drain */
 	for (i = 0; i < RADEON_NUM_RINGS; i++) {
 	for (i = 0; i < RADEON_NUM_RINGS; i++) {

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

@@ -495,7 +495,7 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data)
 	seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw);
 	seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw);
 	seq_printf(m, "%u dwords in ring\n", count);
 	seq_printf(m, "%u dwords in ring\n", count);
 
 
-	if (!ring->ready)
+	if (!ring->ring)
 		return 0;
 		return 0;
 
 
 	/* print 8 dw before current rptr as often it's the last executed
 	/* print 8 dw before current rptr as often it's the last executed

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

@@ -156,6 +156,9 @@ int vce_v2_0_resume(struct radeon_device *rdev)
 	WREG32(VCE_LMI_SWAP_CNTL1, 0);
 	WREG32(VCE_LMI_SWAP_CNTL1, 0);
 	WREG32(VCE_LMI_VM_CTRL, 0);
 	WREG32(VCE_LMI_VM_CTRL, 0);
 
 
+	WREG32(VCE_LMI_VCPU_CACHE_40BIT_BAR, addr >> 8);
+
+	addr &= 0xff;
 	size = RADEON_GPU_PAGE_ALIGN(rdev->vce_fw->size);
 	size = RADEON_GPU_PAGE_ALIGN(rdev->vce_fw->size);
 	WREG32(VCE_VCPU_CACHE_OFFSET0, addr & 0x7fffffff);
 	WREG32(VCE_VCPU_CACHE_OFFSET0, addr & 0x7fffffff);
 	WREG32(VCE_VCPU_CACHE_SIZE0, size);
 	WREG32(VCE_VCPU_CACHE_SIZE0, size);