Skip to content

Commit

Permalink
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Browse files Browse the repository at this point in the history
Pull drm fixes from Dave Airlie:
 "This is a bit larger than Id like, but I asked the Intel guys to pull
  in some Skylake fixes in the possibly vain hope that Skylake might be
  more functional now that I'm seeing production hardware shipping.

  For i915, it's mostly the same patch in a few places, making sure the
  hw doesn't turn off when we are programming it.

  Apart from that are two nouveau fixes, one for a module defer bug, and
  one for using nouveau on new Lenovo P50 models.

  Then there are a bunch of AMDGPU fixes, one is a fix for v4.4 vblank
  regressions, and some PM fixes"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (26 commits)
  drm/nouveau/disp/dp: ensure sink is powered up before attempting link training
  drm/nouveau: platform: Fix deferred probe
  drm/amdgpu: disable direct VM updates when vm_debug is set
  amdgpu: fix NULL pointer dereference at tonga_check_states_equal
  drm/i915/gen9: Verify and enforce dc6 state writes
  drm/i915/gen9: Check for DC state mismatch
  drm/radeon/pm: adjust display configuration after powerstate
  drm/amdgpu/pm: adjust display configuration after powerstate
  drm/amdgpu/pm: add some checks for PX
  drm/amdgpu: fix locking in force performance level
  drm/amdgpu/gfx8: fix priv reg interrupt enable
  drm/i915/skl: Ensure HW is powered during DDB HW state readout
  drm/i915/lvds: Ensure the HW is powered during HW state readout
  drm/i915/hdmi: Ensure the HW is powered during HW state readout
  drm/i915/dsi: Ensure the HW is powered during HW state readout
  drm/i915/dp: Ensure the HW is powered during HW state readout
  drm/i915: Ensure the HW is powered when accessing the CRC HW block
  drm/i915/ddi: Ensure the HW is powered during HW state readout
  drm/i915/crt: Ensure the HW is powered during HW state readout
  drm/i915: Ensure the HW is powered during HW access in assert_pipe
  ...
  • Loading branch information
Linus Torvalds committed Feb 26, 2016
2 parents 3d7b365 + 3772e72 commit 3acdb84
Show file tree
Hide file tree
Showing 24 changed files with 475 additions and 121 deletions.
18 changes: 15 additions & 3 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ static void amdgpu_flip_work_func(struct work_struct *__work)

struct drm_crtc *crtc = &amdgpuCrtc->base;
unsigned long flags;
unsigned i;
int vpos, hpos, stat, min_udelay;
unsigned i, repcnt = 4;
int vpos, hpos, stat, min_udelay = 0;
struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id];

amdgpu_flip_wait_fence(adev, &work->excl);
Expand All @@ -96,7 +96,7 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
* In practice this won't execute very often unless on very fast
* machines because the time window for this to happen is very small.
*/
for (;;) {
while (amdgpuCrtc->enabled && repcnt--) {
/* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank
* start in hpos, and to the "fudged earlier" vblank start in
* vpos.
Expand All @@ -114,10 +114,22 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
/* Sleep at least until estimated real start of hw vblank */
spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5);
if (min_udelay > vblank->framedur_ns / 2000) {
/* Don't wait ridiculously long - something is wrong */
repcnt = 0;
break;
}
usleep_range(min_udelay, 2 * min_udelay);
spin_lock_irqsave(&crtc->dev->event_lock, flags);
};

if (!repcnt)
DRM_DEBUG_DRIVER("Delay problem on crtc %d: min_udelay %d, "
"framedur %d, linedur %d, stat %d, vpos %d, "
"hpos %d\n", work->crtc_id, min_udelay,
vblank->framedur_ns / 1000,
vblank->linedur_ns / 1000, stat, vpos, hpos);

/* do the flip (mmio) */
adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base);
/* set the flip status */
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,8 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
break;
}
ttm_eu_backoff_reservation(&ticket, &list);
if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE))
if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE) &&
!amdgpu_vm_debug)
amdgpu_gem_va_update_vm(adev, bo_va, args->operation);

drm_gem_object_unreference_unlocked(gobj);
Expand Down
29 changes: 24 additions & 5 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev,
struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = ddev->dev_private;

if ((adev->flags & AMD_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON))
return snprintf(buf, PAGE_SIZE, "off\n");

if (adev->pp_enabled) {
enum amd_dpm_forced_level level;

Expand Down Expand Up @@ -140,6 +144,11 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
enum amdgpu_dpm_forced_level level;
int ret = 0;

/* Can't force performance level when the card is off */
if ((adev->flags & AMD_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON))
return -EINVAL;

if (strncmp("low", buf, strlen("low")) == 0) {
level = AMDGPU_DPM_FORCED_LEVEL_LOW;
} else if (strncmp("high", buf, strlen("high")) == 0) {
Expand All @@ -157,6 +166,7 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
mutex_lock(&adev->pm.mutex);
if (adev->pm.dpm.thermal_active) {
count = -EINVAL;
mutex_unlock(&adev->pm.mutex);
goto fail;
}
ret = amdgpu_dpm_force_performance_level(adev, level);
Expand All @@ -167,8 +177,6 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,
mutex_unlock(&adev->pm.mutex);
}
fail:
mutex_unlock(&adev->pm.mutex);

return count;
}

Expand All @@ -182,8 +190,14 @@ static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
char *buf)
{
struct amdgpu_device *adev = dev_get_drvdata(dev);
struct drm_device *ddev = adev->ddev;
int temp;

/* Can't get temperature when the card is off */
if ((adev->flags & AMD_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON))
return -EINVAL;

if (!adev->pp_enabled && !adev->pm.funcs->get_temperature)
temp = 0;
else
Expand Down Expand Up @@ -634,8 +648,6 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev)

/* update display watermarks based on new power state */
amdgpu_display_bandwidth_update(adev);
/* update displays */
amdgpu_dpm_display_configuration_changed(adev);

adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs;
adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count;
Expand All @@ -655,6 +667,9 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev)

amdgpu_dpm_post_set_power_state(adev);

/* update displays */
amdgpu_dpm_display_configuration_changed(adev);

if (adev->pm.funcs->force_performance_level) {
if (adev->pm.dpm.thermal_active) {
enum amdgpu_dpm_forced_level level = adev->pm.dpm.forced_level;
Expand Down Expand Up @@ -847,12 +862,16 @@ static int amdgpu_debugfs_pm_info(struct seq_file *m, void *data)
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
struct amdgpu_device *adev = dev->dev_private;
struct drm_device *ddev = adev->ddev;

if (!adev->pm.dpm_enabled) {
seq_printf(m, "dpm not enabled\n");
return 0;
}
if (adev->pp_enabled) {
if ((adev->flags & AMD_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON)) {
seq_printf(m, "PX asic powered off\n");
} else if (adev->pp_enabled) {
amdgpu_dpm_debugfs_print_current_performance_level(adev, m);
} else {
mutex_lock(&adev->pm.mutex);
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -4995,7 +4995,7 @@ static int gfx_v8_0_set_priv_reg_fault_state(struct amdgpu_device *adev,
case AMDGPU_IRQ_STATE_ENABLE:
cp_int_cntl = RREG32(mmCP_INT_CNTL_RING0);
cp_int_cntl = REG_SET_FIELD(cp_int_cntl, CP_INT_CNTL_RING0,
PRIV_REG_INT_ENABLE, 0);
PRIV_REG_INT_ENABLE, 1);
WREG32(mmCP_INT_CNTL_RING0, cp_int_cntl);
break;
default:
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
static int pem_init(struct pp_eventmgr *eventmgr)
{
int result = 0;
struct pem_event_data event_data;
struct pem_event_data event_data = { {0} };

/* Initialize PowerPlay feature info */
pem_init_feature_info(eventmgr);
Expand All @@ -52,7 +52,7 @@ static int pem_init(struct pp_eventmgr *eventmgr)

static void pem_fini(struct pp_eventmgr *eventmgr)
{
struct pem_event_data event_data;
struct pem_event_data event_data = { {0} };

pem_uninit_featureInfo(eventmgr);
pem_unregister_interrupts(eventmgr);
Expand Down
28 changes: 21 additions & 7 deletions drivers/gpu/drm/i915/i915_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,8 +825,11 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
}

for_each_pipe(dev_priv, pipe) {
if (!intel_display_power_is_enabled(dev_priv,
POWER_DOMAIN_PIPE(pipe))) {
enum intel_display_power_domain power_domain;

power_domain = POWER_DOMAIN_PIPE(pipe);
if (!intel_display_power_get_if_enabled(dev_priv,
power_domain)) {
seq_printf(m, "Pipe %c power disabled\n",
pipe_name(pipe));
continue;
Expand All @@ -840,6 +843,8 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
seq_printf(m, "Pipe %c IER:\t%08x\n",
pipe_name(pipe),
I915_READ(GEN8_DE_PIPE_IER(pipe)));

intel_display_power_put(dev_priv, power_domain);
}

seq_printf(m, "Display Engine port interrupt mask:\t%08x\n",
Expand Down Expand Up @@ -3985,6 +3990,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe];
struct intel_crtc *crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev,
pipe));
enum intel_display_power_domain power_domain;
u32 val = 0; /* shut up gcc */
int ret;

Expand All @@ -3995,7 +4001,8 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
if (pipe_crc->source && source)
return -EINVAL;

if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) {
power_domain = POWER_DOMAIN_PIPE(pipe);
if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) {
DRM_DEBUG_KMS("Trying to capture CRC while pipe is off\n");
return -EIO;
}
Expand All @@ -4012,7 +4019,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
ret = ivb_pipe_crc_ctl_reg(dev, pipe, &source, &val);

if (ret != 0)
return ret;
goto out;

/* none -> real source transition */
if (source) {
Expand All @@ -4024,8 +4031,10 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
entries = kcalloc(INTEL_PIPE_CRC_ENTRIES_NR,
sizeof(pipe_crc->entries[0]),
GFP_KERNEL);
if (!entries)
return -ENOMEM;
if (!entries) {
ret = -ENOMEM;
goto out;
}

/*
* When IPS gets enabled, the pipe CRC changes. Since IPS gets
Expand Down Expand Up @@ -4081,7 +4090,12 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
hsw_enable_ips(crtc);
}

return 0;
ret = 0;

out:
intel_display_power_put(dev_priv, power_domain);

return ret;
}

/*
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,7 @@ struct intel_csr {
uint32_t mmio_count;
i915_reg_t mmioaddr[8];
uint32_t mmiodata[8];
uint32_t dc_state;
};

#define DEV_INFO_FOR_EACH_FLAG(func, sep) \
Expand Down
13 changes: 10 additions & 3 deletions drivers/gpu/drm/i915/intel_crt.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,22 +71,29 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
struct intel_crt *crt = intel_encoder_to_crt(encoder);
enum intel_display_power_domain power_domain;
u32 tmp;
bool ret;

power_domain = intel_display_port_power_domain(encoder);
if (!intel_display_power_is_enabled(dev_priv, power_domain))
if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
return false;

ret = false;

tmp = I915_READ(crt->adpa_reg);

if (!(tmp & ADPA_DAC_ENABLE))
return false;
goto out;

if (HAS_PCH_CPT(dev))
*pipe = PORT_TO_PIPE_CPT(tmp);
else
*pipe = PORT_TO_PIPE(tmp);

return true;
ret = true;
out:
intel_display_power_put(dev_priv, power_domain);

return ret;
}

static unsigned int intel_crt_get_flags(struct intel_encoder *encoder)
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/intel_csr.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ void intel_csr_load_program(struct drm_i915_private *dev_priv)
I915_WRITE(dev_priv->csr.mmioaddr[i],
dev_priv->csr.mmiodata[i]);
}

dev_priv->csr.dc_state = 0;
}

static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
Expand Down
Loading

0 comments on commit 3acdb84

Please sign in to comment.