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:
 "Radeon is most of the work, one regression, one BUG fix in the new
  prime code, some fixes to init code to make streamout not lock up the
  hardware, and just some code to enable users to test HDMI audio on
  later hw (its off by default).

  Intel adds edp edid caching for some strange Dell Vostros that black
  screen on startup if keep reading their EDID, and a fix for a DP
  regression.

  Otherwise fix for via/sis and one to stop udl binding to multiple
  non-video usb."

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm/i915: cache the EDID for eDP panels
  Revert "drm/i915/dp: Use auxch precharge value of 5 everywhere"
  drm/i915: eDP aux needs vdd
  drm/i915: don't enumerate HDMID if an eDP panel is already active on the port
  drm/radeon: add support for STRMOUT_BASE_UPDATE on 7xx
  drm/radeon: add some additional 6xx/7xx/EG register init
  drm/radeon: enable HDMI on DCE5 (AKA NI excluding Aruba)
  drm sis: initialize object_idr
  drm via: initialize object_idr
  drm/radeon/prime: reserve/unreserve around pin
  drm/radeon: fix regression in dynpm due to multi-ring rework
  vga_switcheroo.h: fix pci_dev warning
  drm/udl: only bind to the video devices on the hub.
  • Loading branch information
torvalds committed Jun 17, 2012
2 parents 41a328b + c4af5c4 commit fb09185
Show file tree
Hide file tree
Showing 21 changed files with 156 additions and 29 deletions.
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -6558,7 +6558,7 @@ static void intel_setup_outputs(struct drm_device *dev)
if (I915_READ(HDMIC) & PORT_DETECTED)
intel_hdmi_init(dev, HDMIC);

if (I915_READ(HDMID) & PORT_DETECTED)
if (!dpd_is_edp && I915_READ(HDMID) & PORT_DETECTED)
intel_hdmi_init(dev, HDMID);

if (I915_READ(PCH_DP_C) & DP_DETECTED)
Expand Down
60 changes: 53 additions & 7 deletions drivers/gpu/drm/i915/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "drm.h"
#include "drm_crtc.h"
#include "drm_crtc_helper.h"
#include "drm_edid.h"
#include "intel_drv.h"
#include "i915_drm.h"
#include "i915_drv.h"
Expand Down Expand Up @@ -67,6 +68,8 @@ struct intel_dp {
struct drm_display_mode *panel_fixed_mode; /* for eDP */
struct delayed_work panel_vdd_work;
bool want_panel_vdd;
struct edid *edid; /* cached EDID for eDP */
int edid_mode_count;
};

/**
Expand Down Expand Up @@ -371,7 +374,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
int recv_bytes;
uint32_t status;
uint32_t aux_clock_divider;
int try, precharge = 5;
int try, precharge;

intel_dp_check_edp(intel_dp);
/* The clock divider is based off the hrawclk,
Expand All @@ -391,6 +394,11 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
else
aux_clock_divider = intel_hrawclk(dev) / 2;

if (IS_GEN6(dev))
precharge = 3;
else
precharge = 5;

/* Try to wait for any previous AUX channel activity */
for (try = 0; try < 3; try++) {
status = I915_READ(ch_ctl);
Expand Down Expand Up @@ -1973,13 +1981,17 @@ intel_dp_probe_oui(struct intel_dp *intel_dp)
if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
return;

ironlake_edp_panel_vdd_on(intel_dp);

if (intel_dp_aux_native_read_retry(intel_dp, DP_SINK_OUI, buf, 3))
DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
buf[0], buf[1], buf[2]);

if (intel_dp_aux_native_read_retry(intel_dp, DP_BRANCH_OUI, buf, 3))
DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
buf[0], buf[1], buf[2]);

ironlake_edp_panel_vdd_off(intel_dp, false);
}

static bool
Expand Down Expand Up @@ -2116,10 +2128,22 @@ intel_dp_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
{
struct intel_dp *intel_dp = intel_attached_dp(connector);
struct edid *edid;
int size;

if (is_edp(intel_dp)) {
if (!intel_dp->edid)
return NULL;

size = (intel_dp->edid->extensions + 1) * EDID_LENGTH;
edid = kmalloc(size, GFP_KERNEL);
if (!edid)
return NULL;

memcpy(edid, intel_dp->edid, size);
return edid;
}

ironlake_edp_panel_vdd_on(intel_dp);
edid = drm_get_edid(connector, adapter);
ironlake_edp_panel_vdd_off(intel_dp, false);
return edid;
}

Expand All @@ -2129,9 +2153,17 @@ intel_dp_get_edid_modes(struct drm_connector *connector, struct i2c_adapter *ada
struct intel_dp *intel_dp = intel_attached_dp(connector);
int ret;

ironlake_edp_panel_vdd_on(intel_dp);
if (is_edp(intel_dp)) {
drm_mode_connector_update_edid_property(connector,
intel_dp->edid);
ret = drm_add_edid_modes(connector, intel_dp->edid);
drm_edid_to_eld(connector,
intel_dp->edid);
connector->display_info.raw_edid = NULL;
return intel_dp->edid_mode_count;
}

ret = intel_ddc_get_modes(connector, adapter);
ironlake_edp_panel_vdd_off(intel_dp, false);
return ret;
}

Expand Down Expand Up @@ -2321,6 +2353,7 @@ static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
i2c_del_adapter(&intel_dp->adapter);
drm_encoder_cleanup(encoder);
if (is_edp(intel_dp)) {
kfree(intel_dp->edid);
cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
ironlake_panel_vdd_off_sync(intel_dp);
}
Expand Down Expand Up @@ -2504,11 +2537,14 @@ intel_dp_init(struct drm_device *dev, int output_reg)
break;
}

intel_dp_i2c_init(intel_dp, intel_connector, name);

/* Cache some DPCD data in the eDP case */
if (is_edp(intel_dp)) {
bool ret;
struct edp_power_seq cur, vbt;
u32 pp_on, pp_off, pp_div;
struct edid *edid;

pp_on = I915_READ(PCH_PP_ON_DELAYS);
pp_off = I915_READ(PCH_PP_OFF_DELAYS);
Expand Down Expand Up @@ -2576,9 +2612,19 @@ intel_dp_init(struct drm_device *dev, int output_reg)
intel_dp_destroy(&intel_connector->base);
return;
}
}

intel_dp_i2c_init(intel_dp, intel_connector, name);
ironlake_edp_panel_vdd_on(intel_dp);
edid = drm_get_edid(connector, &intel_dp->adapter);
if (edid) {
drm_mode_connector_update_edid_property(connector,
edid);
intel_dp->edid_mode_count =
drm_add_edid_modes(connector, edid);
drm_edid_to_eld(connector, edid);
intel_dp->edid = edid;
}
ironlake_edp_panel_vdd_off(intel_dp, false);
}

intel_encoder->hot_plug = intel_dp_hot_plug;

Expand Down
4 changes: 3 additions & 1 deletion drivers/gpu/drm/radeon/atombios_encoders.c
Original file line number Diff line number Diff line change
Expand Up @@ -1926,7 +1926,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,

if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
r600_hdmi_enable(encoder);
if (ASIC_IS_DCE4(rdev))
if (ASIC_IS_DCE6(rdev))
; /* TODO (use pointers instead of if-s?) */
else if (ASIC_IS_DCE4(rdev))
evergreen_hdmi_setmode(encoder, adjusted_mode);
else
r600_hdmi_setmode(encoder, adjusted_mode);
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/radeon/evergreen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1932,6 +1932,9 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.evergreen.sx_num_of_sets);
WREG32(SMX_DC_CTL0, smx_dc_ctl0);

if (rdev->family <= CHIP_SUMO2)
WREG32(SMX_SAR_CTL0, 0x00010000);

WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_size / 4) - 1) |
POSITION_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_pos_size / 4) - 1) |
SMX_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_smx_size / 4) - 1)));
Expand Down
3 changes: 0 additions & 3 deletions drivers/gpu/drm/radeon/evergreen_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,6 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
uint32_t offset;

if (ASIC_IS_DCE5(rdev))
return;

/* Silent, r600_hdmi_enable will raise WARN for us */
if (!dig->afmt->enabled)
return;
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/radeon/evergreend.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@
#define SCRATCH_UMSK 0x8540
#define SCRATCH_ADDR 0x8544

#define SMX_SAR_CTL0 0xA008
#define SMX_DC_CTL0 0xA020
#define USE_HASH_FUNCTION (1 << 0)
#define NUMBER_OF_SETS(x) ((x) << 1)
Expand Down
5 changes: 5 additions & 0 deletions drivers/gpu/drm/radeon/ni.c
Original file line number Diff line number Diff line change
Expand Up @@ -1303,6 +1303,10 @@ static int cayman_startup(struct radeon_device *rdev)
if (r)
return r;

r = r600_audio_init(rdev);
if (r)
return r;

return 0;
}

Expand All @@ -1329,6 +1333,7 @@ int cayman_resume(struct radeon_device *rdev)

int cayman_suspend(struct radeon_device *rdev)
{
r600_audio_fini(rdev);
/* FIXME: we should wait for ring to be empty */
radeon_ib_pool_suspend(rdev);
radeon_vm_manager_suspend(rdev);
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/radeon/r600.c
Original file line number Diff line number Diff line change
Expand Up @@ -1839,6 +1839,7 @@ void r600_gpu_init(struct radeon_device *rdev)
WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA |
NUM_CLIP_SEQ(3)));
WREG32(PA_SC_ENHANCE, FORCE_EOV_MAX_CLK_CNT(4095));
WREG32(VC_ENHANCE, 0);
}


Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/radeon/r600_audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ static bool radeon_dig_encoder(struct drm_encoder *encoder)
*/
static int r600_audio_chipset_supported(struct radeon_device *rdev)
{
return (rdev->family >= CHIP_R600 && !ASIC_IS_DCE5(rdev))
return (rdev->family >= CHIP_R600 && !ASIC_IS_DCE6(rdev))
|| rdev->family == CHIP_RS600
|| rdev->family == CHIP_RS690
|| rdev->family == CHIP_RS740;
Expand Down
42 changes: 42 additions & 0 deletions drivers/gpu/drm/radeon/r600_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2079,6 +2079,48 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
return -EINVAL;
}
break;
case PACKET3_STRMOUT_BASE_UPDATE:
if (p->family < CHIP_RV770) {
DRM_ERROR("STRMOUT_BASE_UPDATE only supported on 7xx\n");
return -EINVAL;
}
if (pkt->count != 1) {
DRM_ERROR("bad STRMOUT_BASE_UPDATE packet count\n");
return -EINVAL;
}
if (idx_value > 3) {
DRM_ERROR("bad STRMOUT_BASE_UPDATE index\n");
return -EINVAL;
}
{
u64 offset;

r = r600_cs_packet_next_reloc(p, &reloc);
if (r) {
DRM_ERROR("bad STRMOUT_BASE_UPDATE reloc\n");
return -EINVAL;
}

if (reloc->robj != track->vgt_strmout_bo[idx_value]) {
DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo does not match\n");
return -EINVAL;
}

offset = radeon_get_ib_value(p, idx+1) << 8;
if (offset != track->vgt_strmout_bo_offset[idx_value]) {
DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo offset does not match: 0x%llx, 0x%x\n",
offset, track->vgt_strmout_bo_offset[idx_value]);
return -EINVAL;
}

if ((offset + 4) > radeon_bo_size(reloc->robj)) {
DRM_ERROR("bad STRMOUT_BASE_UPDATE bo too small: 0x%llx, 0x%lx\n",
offset + 4, radeon_bo_size(reloc->robj));
return -EINVAL;
}
ib[idx+1] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
}
break;
case PACKET3_SURFACE_BASE_UPDATE:
if (p->family >= CHIP_RV770 || p->family == CHIP_R600) {
DRM_ERROR("bad SURFACE_BASE_UPDATE\n");
Expand Down
7 changes: 2 additions & 5 deletions drivers/gpu/drm/radeon/r600_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,6 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
uint32_t offset;

if (ASIC_IS_DCE5(rdev))
return;

/* Silent, r600_hdmi_enable will raise WARN for us */
if (!dig->afmt->enabled)
return;
Expand Down Expand Up @@ -483,7 +480,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
uint32_t offset;
u32 hdmi;

if (ASIC_IS_DCE5(rdev))
if (ASIC_IS_DCE6(rdev))
return;

/* Silent, r600_hdmi_enable will raise WARN for us */
Expand Down Expand Up @@ -543,7 +540,7 @@ void r600_hdmi_disable(struct drm_encoder *encoder)
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
uint32_t offset;

if (ASIC_IS_DCE5(rdev))
if (ASIC_IS_DCE6(rdev))
return;

/* Called for ATOM_ENCODER_MODE_HDMI only */
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/radeon/r600d.h
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@
#define TC_L2_SIZE(x) ((x)<<5)
#define L2_DISABLE_LATE_HIT (1<<9)

#define VC_ENHANCE 0x9714

#define VGT_CACHE_INVALIDATION 0x88C4
#define CACHE_INVALIDATION(x) ((x)<<0)
Expand Down Expand Up @@ -1163,6 +1164,7 @@
#define PACKET3_SET_CTL_CONST 0x6F
#define PACKET3_SET_CTL_CONST_OFFSET 0x0003cff0
#define PACKET3_SET_CTL_CONST_END 0x0003e200
#define PACKET3_STRMOUT_BASE_UPDATE 0x72 /* r7xx */
#define PACKET3_SURFACE_BASE_UPDATE 0x73


Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/radeon/radeon_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@
* 2.14.0 - add evergreen tiling informations
* 2.15.0 - add max_pipes query
* 2.16.0 - fix evergreen 2D tiled surface calculation
* 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx
*/
#define KMS_DRIVER_MAJOR 2
#define KMS_DRIVER_MINOR 16
#define KMS_DRIVER_MINOR 17
#define KMS_DRIVER_PATCHLEVEL 0
int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
int radeon_driver_unload_kms(struct drm_device *dev);
Expand Down
10 changes: 7 additions & 3 deletions drivers/gpu/drm/radeon/radeon_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -801,9 +801,13 @@ static void radeon_dynpm_idle_work_handler(struct work_struct *work)
int i;

for (i = 0; i < RADEON_NUM_RINGS; ++i) {
not_processed += radeon_fence_count_emitted(rdev, i);
if (not_processed >= 3)
break;
struct radeon_ring *ring = &rdev->ring[i];

if (ring->ready) {
not_processed += radeon_fence_count_emitted(rdev, i);
if (not_processed >= 3)
break;
}
}

if (not_processed >= 3) { /* should upclock */
Expand Down
10 changes: 8 additions & 2 deletions drivers/gpu/drm/radeon/radeon_prime.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,17 @@ struct dma_buf *radeon_gem_prime_export(struct drm_device *dev,
struct radeon_bo *bo = gem_to_radeon_bo(obj);
int ret = 0;

ret = radeon_bo_reserve(bo, false);
if (unlikely(ret != 0))
return ERR_PTR(ret);

/* pin buffer into GTT */
ret = radeon_bo_pin(bo, RADEON_GEM_DOMAIN_GTT, NULL);
if (ret)
if (ret) {
radeon_bo_unreserve(bo);
return ERR_PTR(ret);

}
radeon_bo_unreserve(bo);
return dma_buf_export(bo, &radeon_dmabuf_ops, obj->size, flags);
}

Expand Down
5 changes: 4 additions & 1 deletion drivers/gpu/drm/radeon/rv770.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,9 @@ static void rv770_gpu_init(struct radeon_device *rdev)
ACK_FLUSH_CTL(3) |
SYNC_FLUSH_CTL));

if (rdev->family != CHIP_RV770)
WREG32(SMX_SAR_CTL0, 0x00003f3f);

db_debug3 = RREG32(DB_DEBUG3);
db_debug3 &= ~DB_CLK_OFF_DELAY(0x1f);
switch (rdev->family) {
Expand Down Expand Up @@ -792,7 +795,7 @@ static void rv770_gpu_init(struct radeon_device *rdev)

WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA |
NUM_CLIP_SEQ(3)));

WREG32(VC_ENHANCE, 0);
}

void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
Expand Down
Loading

0 comments on commit fb09185

Please sign in to comment.