Commit 5c7f0c27 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'imx-drm-fixes-2015-03-31' of git://git.pengutronix.de/git/pza/linux into drm-next

imx-drm limit fixes

Fix IPU IC downscaler to its hardware limitation of 4:1 and the
IPU DI pixel clock divider integer part to 8-bit.

* tag 'imx-drm-fixes-2015-03-31' of git://git.pengutronix.de/git/pza/linux:
  gpu: ipu-v3: turns out the IPU can only downsize 4:1
  gpu: ipu-v3: limit pixel clock divider to 8-bits
  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
parents fa37a8c8 8f361b27
...@@ -2131,6 +2131,7 @@ ...@@ -2131,6 +2131,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
......
...@@ -1567,6 +1567,7 @@ struct radeon_dpm { ...@@ -1567,6 +1567,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;
......
...@@ -76,7 +76,7 @@ static bool igp_read_bios_from_vram(struct radeon_device *rdev) ...@@ -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) ...@@ -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;
} }
......
...@@ -837,12 +837,8 @@ static void radeon_dpm_thermal_work_handler(struct work_struct *work) ...@@ -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, static bool radeon_dpm_single_display(struct radeon_device *rdev)
enum radeon_pm_state_type dpm_state)
{ {
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, ...@@ -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) ...@@ -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) ...@@ -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 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev) ...@@ -1069,6 +1080,7 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev)
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++) {
......
...@@ -495,7 +495,7 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data) ...@@ -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
......
...@@ -156,6 +156,9 @@ int vce_v2_0_resume(struct radeon_device *rdev) ...@@ -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);
......
...@@ -441,8 +441,7 @@ static void ipu_di_config_clock(struct ipu_di *di, ...@@ -441,8 +441,7 @@ static void ipu_di_config_clock(struct ipu_di *di,
in_rate = clk_get_rate(clk); in_rate = clk_get_rate(clk);
div = DIV_ROUND_CLOSEST(in_rate, sig->mode.pixelclock); div = DIV_ROUND_CLOSEST(in_rate, sig->mode.pixelclock);
if (div == 0) div = clamp(div, 1U, 255U);
div = 1;
clkgen0 = div << 4; clkgen0 = div << 4;
} }
...@@ -459,8 +458,7 @@ static void ipu_di_config_clock(struct ipu_di *di, ...@@ -459,8 +458,7 @@ static void ipu_di_config_clock(struct ipu_di *di,
clkrate = clk_get_rate(di->clk_ipu); clkrate = clk_get_rate(di->clk_ipu);
div = DIV_ROUND_CLOSEST(clkrate, sig->mode.pixelclock); div = DIV_ROUND_CLOSEST(clkrate, sig->mode.pixelclock);
if (div == 0) div = clamp(div, 1U, 255U);
div = 1;
rate = clkrate / div; rate = clkrate / div;
error = rate / (sig->mode.pixelclock / 1000); error = rate / (sig->mode.pixelclock / 1000);
...@@ -483,8 +481,7 @@ static void ipu_di_config_clock(struct ipu_di *di, ...@@ -483,8 +481,7 @@ static void ipu_di_config_clock(struct ipu_di *di,
in_rate = clk_get_rate(clk); in_rate = clk_get_rate(clk);
div = DIV_ROUND_CLOSEST(in_rate, sig->mode.pixelclock); div = DIV_ROUND_CLOSEST(in_rate, sig->mode.pixelclock);
if (div == 0) div = clamp(div, 1U, 255U);
div = 1;
clkgen0 = div << 4; clkgen0 = div << 4;
} }
......
...@@ -297,8 +297,8 @@ static int calc_resize_coeffs(struct ipu_ic *ic, ...@@ -297,8 +297,8 @@ static int calc_resize_coeffs(struct ipu_ic *ic,
return -EINVAL; return -EINVAL;
} }
/* Cannot downsize more than 8:1 */ /* Cannot downsize more than 4:1 */
if ((out_size << 3) < in_size) { if ((out_size << 2) < in_size) {
dev_err(ipu->dev, "Unsupported downsize\n"); dev_err(ipu->dev, "Unsupported downsize\n");
return -EINVAL; return -EINVAL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment