mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-16 01:54:00 +00:00
Merge branch 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: drm: Include the connector name in the output_poll_execute() debug message drm/radeon/kms: fix bug in r600_gpu_is_lockup drm/radeon/kms: reorder display resume to avoid problems drm/radeon/kms/evergreen: reset the grbm blocks at resume and init drm/radeon/kms: fix evergreen asic reset Revert "drm: Don't try and disable an encoder that was never enabled" drm/radeon: Add early unregister of firmware fb's drm/radeon: use aperture size not vram size for overlap tests drm/radeon/kms/evergreen: flush hdp cache when flushing gart tlb drm/radeon/kms: disable the r600 cb offset checker for linear surfaces drm/radeon/kms: disable ss fixed ref divide drm/i915/bios: Reverse order of 100/120 Mhz SSC clocks agp/intel: Fix missed cached memory flags setting in i965_write_entry() drm/i915/sdvo: Only use the SDVO pin if it is in the valid range drm/i915/ringbuffer: Handle wrapping of the autoreported HEAD drm/i915/dp: Fix I2C/EDID handling with active DisplayPort to DVI converter
This commit is contained in:
commit
e819eb8687
@ -1192,12 +1192,19 @@ static void i9xx_chipset_flush(void)
|
||||
writel(1, intel_private.i9xx_flush_page);
|
||||
}
|
||||
|
||||
static void i965_write_entry(dma_addr_t addr, unsigned int entry,
|
||||
static void i965_write_entry(dma_addr_t addr,
|
||||
unsigned int entry,
|
||||
unsigned int flags)
|
||||
{
|
||||
u32 pte_flags;
|
||||
|
||||
pte_flags = I810_PTE_VALID;
|
||||
if (flags == AGP_USER_CACHED_MEMORY)
|
||||
pte_flags |= I830_PTE_SYSTEM_CACHED;
|
||||
|
||||
/* Shift high bits down */
|
||||
addr |= (addr >> 28) & 0xf0;
|
||||
writel(addr | I810_PTE_VALID, intel_private.gtt + entry);
|
||||
writel(addr | pte_flags, intel_private.gtt + entry);
|
||||
}
|
||||
|
||||
static bool gen6_check_flags(unsigned int flags)
|
||||
|
@ -241,7 +241,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
|
||||
}
|
||||
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
if (encoder->crtc && !drm_helper_encoder_in_use(encoder)) {
|
||||
if (!drm_helper_encoder_in_use(encoder)) {
|
||||
drm_encoder_disable(encoder);
|
||||
/* disconnector encoder from any connector */
|
||||
encoder->crtc = NULL;
|
||||
@ -874,7 +874,10 @@ static void output_poll_execute(struct work_struct *work)
|
||||
continue;
|
||||
|
||||
connector->status = connector->funcs->detect(connector, false);
|
||||
DRM_DEBUG_KMS("connector status updated to %d\n", connector->status);
|
||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
|
||||
connector->base.id,
|
||||
drm_get_connector_name(connector),
|
||||
old_status, connector->status);
|
||||
if (old_status != connector->status)
|
||||
changed = true;
|
||||
}
|
||||
|
@ -270,7 +270,7 @@ parse_general_features(struct drm_i915_private *dev_priv,
|
||||
general->ssc_freq ? 66 : 48;
|
||||
else if (IS_GEN5(dev) || IS_GEN6(dev))
|
||||
dev_priv->lvds_ssc_freq =
|
||||
general->ssc_freq ? 100 : 120;
|
||||
general->ssc_freq ? 120 : 100;
|
||||
else
|
||||
dev_priv->lvds_ssc_freq =
|
||||
general->ssc_freq ? 100 : 96;
|
||||
|
@ -479,6 +479,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
|
||||
uint16_t address = algo_data->address;
|
||||
uint8_t msg[5];
|
||||
uint8_t reply[2];
|
||||
unsigned retry;
|
||||
int msg_bytes;
|
||||
int reply_bytes;
|
||||
int ret;
|
||||
@ -513,14 +514,33 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
|
||||
break;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
ret = intel_dp_aux_ch(intel_dp,
|
||||
msg, msg_bytes,
|
||||
reply, reply_bytes);
|
||||
for (retry = 0; retry < 5; retry++) {
|
||||
ret = intel_dp_aux_ch(intel_dp,
|
||||
msg, msg_bytes,
|
||||
reply, reply_bytes);
|
||||
if (ret < 0) {
|
||||
DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (reply[0] & AUX_NATIVE_REPLY_MASK) {
|
||||
case AUX_NATIVE_REPLY_ACK:
|
||||
/* I2C-over-AUX Reply field is only valid
|
||||
* when paired with AUX ACK.
|
||||
*/
|
||||
break;
|
||||
case AUX_NATIVE_REPLY_NACK:
|
||||
DRM_DEBUG_KMS("aux_ch native nack\n");
|
||||
return -EREMOTEIO;
|
||||
case AUX_NATIVE_REPLY_DEFER:
|
||||
udelay(100);
|
||||
continue;
|
||||
default:
|
||||
DRM_ERROR("aux_ch invalid native reply 0x%02x\n",
|
||||
reply[0]);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
|
||||
switch (reply[0] & AUX_I2C_REPLY_MASK) {
|
||||
case AUX_I2C_REPLY_ACK:
|
||||
if (mode == MODE_I2C_READ) {
|
||||
@ -528,17 +548,20 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
|
||||
}
|
||||
return reply_bytes - 1;
|
||||
case AUX_I2C_REPLY_NACK:
|
||||
DRM_DEBUG_KMS("aux_ch nack\n");
|
||||
DRM_DEBUG_KMS("aux_i2c nack\n");
|
||||
return -EREMOTEIO;
|
||||
case AUX_I2C_REPLY_DEFER:
|
||||
DRM_DEBUG_KMS("aux_ch defer\n");
|
||||
DRM_DEBUG_KMS("aux_i2c defer\n");
|
||||
udelay(100);
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]);
|
||||
DRM_ERROR("aux_i2c invalid reply 0x%02x\n", reply[0]);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
}
|
||||
|
||||
DRM_ERROR("too many retries, giving up\n");
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -696,20 +696,17 @@ int intel_wait_ring_buffer(struct drm_device *dev,
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
u32 head;
|
||||
|
||||
head = intel_read_status_page(ring, 4);
|
||||
if (head) {
|
||||
ring->head = head & HEAD_ADDR;
|
||||
ring->space = ring->head - (ring->tail + 8);
|
||||
if (ring->space < 0)
|
||||
ring->space += ring->size;
|
||||
if (ring->space >= n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
trace_i915_ring_wait_begin (dev);
|
||||
end = jiffies + 3 * HZ;
|
||||
do {
|
||||
ring->head = I915_READ_HEAD(ring) & HEAD_ADDR;
|
||||
/* If the reported head position has wrapped or hasn't advanced,
|
||||
* fallback to the slow and accurate path.
|
||||
*/
|
||||
head = intel_read_status_page(ring, 4);
|
||||
if (head < ring->actual_head)
|
||||
head = I915_READ_HEAD(ring);
|
||||
ring->actual_head = head;
|
||||
ring->head = head & HEAD_ADDR;
|
||||
ring->space = ring->head - (ring->tail + 8);
|
||||
if (ring->space < 0)
|
||||
ring->space += ring->size;
|
||||
|
@ -30,8 +30,9 @@ struct intel_ring_buffer {
|
||||
struct drm_device *dev;
|
||||
struct drm_gem_object *gem_object;
|
||||
|
||||
unsigned int head;
|
||||
unsigned int tail;
|
||||
u32 actual_head;
|
||||
u32 head;
|
||||
u32 tail;
|
||||
int space;
|
||||
struct intel_hw_status_page status_page;
|
||||
|
||||
|
@ -1908,9 +1908,12 @@ intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv,
|
||||
speed = mapping->i2c_speed;
|
||||
}
|
||||
|
||||
sdvo->i2c = &dev_priv->gmbus[pin].adapter;
|
||||
intel_gmbus_set_speed(sdvo->i2c, speed);
|
||||
intel_gmbus_force_bit(sdvo->i2c, true);
|
||||
if (pin < GMBUS_NUM_PORTS) {
|
||||
sdvo->i2c = &dev_priv->gmbus[pin].adapter;
|
||||
intel_gmbus_set_speed(sdvo->i2c, speed);
|
||||
intel_gmbus_force_bit(sdvo->i2c, true);
|
||||
} else
|
||||
sdvo->i2c = &dev_priv->gmbus[GMBUS_PORT_DPB].adapter;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -253,7 +253,8 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
case DRM_MODE_DPMS_SUSPEND:
|
||||
case DRM_MODE_DPMS_OFF:
|
||||
drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
|
||||
atombios_blank_crtc(crtc, ATOM_ENABLE);
|
||||
if (radeon_crtc->enabled)
|
||||
atombios_blank_crtc(crtc, ATOM_ENABLE);
|
||||
if (ASIC_IS_DCE3(rdev))
|
||||
atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
|
||||
atombios_enable_crtc(crtc, ATOM_DISABLE);
|
||||
@ -530,7 +531,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
|
||||
dp_clock = dig_connector->dp_clock;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 /* doesn't work properly on some laptops */
|
||||
/* use recommended ref_div for ss */
|
||||
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
|
||||
if (ss_enabled) {
|
||||
@ -540,7 +541,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
if (ASIC_IS_AVIVO(rdev)) {
|
||||
/* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
|
||||
if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
|
||||
|
@ -748,6 +748,8 @@ void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev)
|
||||
unsigned i;
|
||||
u32 tmp;
|
||||
|
||||
WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
|
||||
|
||||
WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1));
|
||||
for (i = 0; i < rdev->usec_timeout; i++) {
|
||||
/* read MC_STATUS */
|
||||
@ -1922,7 +1924,6 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev)
|
||||
static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
|
||||
{
|
||||
struct evergreen_mc_save save;
|
||||
u32 srbm_reset = 0;
|
||||
u32 grbm_reset = 0;
|
||||
|
||||
dev_info(rdev->dev, "GPU softreset \n");
|
||||
@ -1961,16 +1962,6 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
|
||||
udelay(50);
|
||||
WREG32(GRBM_SOFT_RESET, 0);
|
||||
(void)RREG32(GRBM_SOFT_RESET);
|
||||
|
||||
/* reset all the system blocks */
|
||||
srbm_reset = SRBM_SOFT_RESET_ALL_MASK;
|
||||
|
||||
dev_info(rdev->dev, " SRBM_SOFT_RESET=0x%08X\n", srbm_reset);
|
||||
WREG32(SRBM_SOFT_RESET, srbm_reset);
|
||||
(void)RREG32(SRBM_SOFT_RESET);
|
||||
udelay(50);
|
||||
WREG32(SRBM_SOFT_RESET, 0);
|
||||
(void)RREG32(SRBM_SOFT_RESET);
|
||||
/* Wait a little for things to settle down */
|
||||
udelay(50);
|
||||
dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n",
|
||||
@ -1981,10 +1972,6 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
|
||||
RREG32(GRBM_STATUS_SE1));
|
||||
dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n",
|
||||
RREG32(SRBM_STATUS));
|
||||
/* After reset we need to reinit the asic as GPU often endup in an
|
||||
* incoherent state.
|
||||
*/
|
||||
atom_asic_init(rdev->mode_info.atom_context);
|
||||
evergreen_mc_resume(rdev, &save);
|
||||
return 0;
|
||||
}
|
||||
@ -2596,6 +2583,11 @@ int evergreen_resume(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* reset the asic, the gfx blocks are often in a bad state
|
||||
* after the driver is unloaded or after a resume
|
||||
*/
|
||||
if (radeon_asic_reset(rdev))
|
||||
dev_warn(rdev->dev, "GPU reset failed !\n");
|
||||
/* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
|
||||
* posting will perform necessary task to bring back GPU into good
|
||||
* shape.
|
||||
@ -2712,6 +2704,11 @@ int evergreen_init(struct radeon_device *rdev)
|
||||
r = radeon_atombios_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
/* reset the asic, the gfx blocks are often in a bad state
|
||||
* after the driver is unloaded or after a resume
|
||||
*/
|
||||
if (radeon_asic_reset(rdev))
|
||||
dev_warn(rdev->dev, "GPU reset failed !\n");
|
||||
/* Post card if necessary */
|
||||
if (!evergreen_card_posted(rdev)) {
|
||||
if (!rdev->bios) {
|
||||
|
@ -174,6 +174,7 @@
|
||||
#define HDP_NONSURFACE_BASE 0x2C04
|
||||
#define HDP_NONSURFACE_INFO 0x2C08
|
||||
#define HDP_NONSURFACE_SIZE 0x2C0C
|
||||
#define HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480
|
||||
#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0
|
||||
#define HDP_TILING_CONFIG 0x2F3C
|
||||
|
||||
|
@ -1342,13 +1342,19 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev)
|
||||
u32 srbm_status;
|
||||
u32 grbm_status;
|
||||
u32 grbm_status2;
|
||||
struct r100_gpu_lockup *lockup;
|
||||
int r;
|
||||
|
||||
if (rdev->family >= CHIP_RV770)
|
||||
lockup = &rdev->config.rv770.lockup;
|
||||
else
|
||||
lockup = &rdev->config.r600.lockup;
|
||||
|
||||
srbm_status = RREG32(R_000E50_SRBM_STATUS);
|
||||
grbm_status = RREG32(R_008010_GRBM_STATUS);
|
||||
grbm_status2 = RREG32(R_008014_GRBM_STATUS2);
|
||||
if (!G_008010_GUI_ACTIVE(grbm_status)) {
|
||||
r100_gpu_lockup_update(&rdev->config.r300.lockup, &rdev->cp);
|
||||
r100_gpu_lockup_update(lockup, &rdev->cp);
|
||||
return false;
|
||||
}
|
||||
/* force CP activities */
|
||||
@ -1360,7 +1366,7 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev)
|
||||
radeon_ring_unlock_commit(rdev);
|
||||
}
|
||||
rdev->cp.rptr = RREG32(R600_CP_RB_RPTR);
|
||||
return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, &rdev->cp);
|
||||
return r100_gpu_cp_is_lockup(rdev, lockup, &rdev->cp);
|
||||
}
|
||||
|
||||
int r600_asic_reset(struct radeon_device *rdev)
|
||||
|
@ -315,11 +315,10 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
|
||||
if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) {
|
||||
/* the initial DDX does bad things with the CB size occasionally */
|
||||
/* it rounds up height too far for slice tile max but the BO is smaller */
|
||||
tmp = (height - 7) * 8 * bpe;
|
||||
if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
|
||||
dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i]));
|
||||
return -EINVAL;
|
||||
}
|
||||
/* r600c,g also seem to flush at bad times in some apps resulting in
|
||||
* bogus values here. So for linear just allow anything to avoid breaking
|
||||
* broken userspace.
|
||||
*/
|
||||
} else {
|
||||
dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i]));
|
||||
return -EINVAL;
|
||||
|
@ -910,11 +910,6 @@ int radeon_resume_kms(struct drm_device *dev)
|
||||
radeon_pm_resume(rdev);
|
||||
radeon_restore_bios_scratch_regs(rdev);
|
||||
|
||||
/* turn on display hw */
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
|
||||
radeon_fbdev_set_suspend(rdev, 0);
|
||||
release_console_sem();
|
||||
|
||||
@ -922,6 +917,10 @@ int radeon_resume_kms(struct drm_device *dev)
|
||||
radeon_hpd_init(rdev);
|
||||
/* blat the mode back in */
|
||||
drm_helper_resume_force_mode(dev);
|
||||
/* turn on display hw */
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -232,9 +232,28 @@ static struct drm_driver driver_old = {
|
||||
|
||||
static struct drm_driver kms_driver;
|
||||
|
||||
static void radeon_kick_out_firmware_fb(struct pci_dev *pdev)
|
||||
{
|
||||
struct apertures_struct *ap;
|
||||
bool primary = false;
|
||||
|
||||
ap = alloc_apertures(1);
|
||||
ap->ranges[0].base = pci_resource_start(pdev, 0);
|
||||
ap->ranges[0].size = pci_resource_len(pdev, 0);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
|
||||
#endif
|
||||
remove_conflicting_framebuffers(ap, "radeondrmfb", primary);
|
||||
kfree(ap);
|
||||
}
|
||||
|
||||
static int __devinit
|
||||
radeon_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
/* Get rid of things like offb */
|
||||
radeon_kick_out_firmware_fb(pdev);
|
||||
|
||||
return drm_get_pci_dev(pdev, ent, &kms_driver);
|
||||
}
|
||||
|
||||
|
@ -245,7 +245,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
|
||||
goto out_unref;
|
||||
}
|
||||
info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base;
|
||||
info->apertures->ranges[0].size = rdev->mc.real_vram_size;
|
||||
info->apertures->ranges[0].size = rdev->mc.aper_size;
|
||||
|
||||
info->fix.mmio_start = 0;
|
||||
info->fix.mmio_len = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user