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/radeon/kms/r6xx+: voltage fixes drm/nouveau: drop leftover debugging drm/radeon: avoid warnings from r600/eg irq handlers on powered off card. drm/radeon/kms: add missing param for dce3.2 DP transmitter setup drm/radeon/kms/atom: fix duallink on some early DCE3.2 cards drm/nouveau: fix assumption that semaphore dmaobj is valid in x-chan sync drm/nv50/disp: fix gamma with page flipping overlay turned on drm/nouveau/pm: Prevent overflow in nouveau_perf_init() drm/nouveau: fix big-endian switch
This commit is contained in:
Коммит
f5fc5567dd
|
@ -262,7 +262,6 @@ static bool nouveau_dsm_detect(void)
|
|||
vga_count++;
|
||||
|
||||
retval = nouveau_dsm_pci_probe(pdev);
|
||||
printk("ret val is %d\n", retval);
|
||||
if (retval & NOUVEAU_DSM_HAS_MUX)
|
||||
has_dsm |= 1;
|
||||
if (retval & NOUVEAU_DSM_HAS_OPT)
|
||||
|
|
|
@ -339,11 +339,12 @@ semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
|
|||
int ret;
|
||||
|
||||
if (dev_priv->chipset < 0x84) {
|
||||
ret = RING_SPACE(chan, 3);
|
||||
ret = RING_SPACE(chan, 4);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_OFFSET, 2);
|
||||
BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 3);
|
||||
OUT_RING (chan, NvSema);
|
||||
OUT_RING (chan, sema->mem->start);
|
||||
OUT_RING (chan, 1);
|
||||
} else
|
||||
|
@ -351,10 +352,12 @@ semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
|
|||
struct nouveau_vma *vma = &dev_priv->fence.bo->vma;
|
||||
u64 offset = vma->offset + sema->mem->start;
|
||||
|
||||
ret = RING_SPACE(chan, 5);
|
||||
ret = RING_SPACE(chan, 7);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1);
|
||||
OUT_RING (chan, chan->vram_handle);
|
||||
BEGIN_RING(chan, NvSubSw, 0x0010, 4);
|
||||
OUT_RING (chan, upper_32_bits(offset));
|
||||
OUT_RING (chan, lower_32_bits(offset));
|
||||
|
@ -394,11 +397,12 @@ semaphore_release(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
|
|||
int ret;
|
||||
|
||||
if (dev_priv->chipset < 0x84) {
|
||||
ret = RING_SPACE(chan, 4);
|
||||
ret = RING_SPACE(chan, 5);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_OFFSET, 1);
|
||||
BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 2);
|
||||
OUT_RING (chan, NvSema);
|
||||
OUT_RING (chan, sema->mem->start);
|
||||
BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_RELEASE, 1);
|
||||
OUT_RING (chan, 1);
|
||||
|
@ -407,10 +411,12 @@ semaphore_release(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
|
|||
struct nouveau_vma *vma = &dev_priv->fence.bo->vma;
|
||||
u64 offset = vma->offset + sema->mem->start;
|
||||
|
||||
ret = RING_SPACE(chan, 5);
|
||||
ret = RING_SPACE(chan, 7);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1);
|
||||
OUT_RING (chan, chan->vram_handle);
|
||||
BEGIN_RING(chan, NvSubSw, 0x0010, 4);
|
||||
OUT_RING (chan, upper_32_bits(offset));
|
||||
OUT_RING (chan, lower_32_bits(offset));
|
||||
|
@ -504,22 +510,22 @@ nouveau_fence_channel_init(struct nouveau_channel *chan)
|
|||
struct nouveau_gpuobj *obj = NULL;
|
||||
int ret;
|
||||
|
||||
if (dev_priv->card_type >= NV_C0)
|
||||
goto out_initialised;
|
||||
if (dev_priv->card_type < NV_C0) {
|
||||
/* Create an NV_SW object for various sync purposes */
|
||||
ret = nouveau_gpuobj_gr_new(chan, NvSw, NV_SW);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Create an NV_SW object for various sync purposes */
|
||||
ret = nouveau_gpuobj_gr_new(chan, NvSw, NV_SW);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = RING_SPACE(chan, 2);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* we leave subchannel empty for nvc0 */
|
||||
ret = RING_SPACE(chan, 2);
|
||||
if (ret)
|
||||
return ret;
|
||||
BEGIN_RING(chan, NvSubSw, 0, 1);
|
||||
OUT_RING(chan, NvSw);
|
||||
BEGIN_RING(chan, NvSubSw, 0, 1);
|
||||
OUT_RING (chan, NvSw);
|
||||
FIRE_RING (chan);
|
||||
}
|
||||
|
||||
/* Create a DMA object for the shared cross-channel sync area. */
|
||||
/* Setup area of memory shared between all channels for x-chan sync */
|
||||
if (USE_SEMA(dev) && dev_priv->chipset < 0x84) {
|
||||
struct ttm_mem_reg *mem = &dev_priv->fence.bo->bo.mem;
|
||||
|
||||
|
@ -534,23 +540,8 @@ nouveau_fence_channel_init(struct nouveau_channel *chan)
|
|||
nouveau_gpuobj_ref(NULL, &obj);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = RING_SPACE(chan, 2);
|
||||
if (ret)
|
||||
return ret;
|
||||
BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1);
|
||||
OUT_RING(chan, NvSema);
|
||||
} else {
|
||||
ret = RING_SPACE(chan, 2);
|
||||
if (ret)
|
||||
return ret;
|
||||
BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1);
|
||||
OUT_RING (chan, chan->vram_handle); /* whole VM */
|
||||
}
|
||||
|
||||
FIRE_RING(chan);
|
||||
|
||||
out_initialised:
|
||||
INIT_LIST_HEAD(&chan->fence.pending);
|
||||
spin_lock_init(&chan->fence.lock);
|
||||
atomic_set(&chan->fence.last_sequence_irq, 0);
|
||||
|
|
|
@ -182,6 +182,11 @@ nouveau_perf_init(struct drm_device *dev)
|
|||
entries = perf[2];
|
||||
}
|
||||
|
||||
if (entries > NOUVEAU_PM_MAX_LEVEL) {
|
||||
NV_DEBUG(dev, "perf table has too many entries - buggy vbios?\n");
|
||||
entries = NOUVEAU_PM_MAX_LEVEL;
|
||||
}
|
||||
|
||||
entry = perf + headerlen;
|
||||
for (i = 0; i < entries; i++) {
|
||||
struct nouveau_pm_level *perflvl = &pm->perflvl[pm->nr_perflvl];
|
||||
|
|
|
@ -881,8 +881,8 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
|
|||
|
||||
#ifdef __BIG_ENDIAN
|
||||
/* Put the card in BE mode if it's not */
|
||||
if (nv_rd32(dev, NV03_PMC_BOOT_1))
|
||||
nv_wr32(dev, NV03_PMC_BOOT_1, 0x00000001);
|
||||
if (nv_rd32(dev, NV03_PMC_BOOT_1) != 0x01000001)
|
||||
nv_wr32(dev, NV03_PMC_BOOT_1, 0x01000001);
|
||||
|
||||
DRM_MEMORYBARRIER();
|
||||
#endif
|
||||
|
|
|
@ -409,7 +409,7 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
|
|||
struct nouveau_channel *evo = dispc->sync;
|
||||
int ret;
|
||||
|
||||
ret = RING_SPACE(evo, 24);
|
||||
ret = RING_SPACE(evo, chan ? 25 : 27);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
|
||||
|
@ -458,8 +458,19 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
|
|||
/* queue the flip on the crtc's "display sync" channel */
|
||||
BEGIN_RING(evo, 0, 0x0100, 1);
|
||||
OUT_RING (evo, 0xfffe0000);
|
||||
BEGIN_RING(evo, 0, 0x0084, 5);
|
||||
OUT_RING (evo, chan ? 0x00000100 : 0x00000010);
|
||||
if (chan) {
|
||||
BEGIN_RING(evo, 0, 0x0084, 1);
|
||||
OUT_RING (evo, 0x00000100);
|
||||
} else {
|
||||
BEGIN_RING(evo, 0, 0x0084, 1);
|
||||
OUT_RING (evo, 0x00000010);
|
||||
/* allows gamma somehow, PDISP will bitch at you if
|
||||
* you don't wait for vblank before changing this..
|
||||
*/
|
||||
BEGIN_RING(evo, 0, 0x00e0, 1);
|
||||
OUT_RING (evo, 0x40000000);
|
||||
}
|
||||
BEGIN_RING(evo, 0, 0x0088, 4);
|
||||
OUT_RING (evo, dispc->sem.offset);
|
||||
OUT_RING (evo, 0xf00d0000 | dispc->sem.value);
|
||||
OUT_RING (evo, 0x74b1e000);
|
||||
|
|
|
@ -140,11 +140,17 @@ void evergreen_pm_misc(struct radeon_device *rdev)
|
|||
struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
|
||||
|
||||
if (voltage->type == VOLTAGE_SW) {
|
||||
/* 0xff01 is a flag rather then an actual voltage */
|
||||
if (voltage->voltage == 0xff01)
|
||||
return;
|
||||
if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) {
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
rdev->pm.current_vddc = voltage->voltage;
|
||||
DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage);
|
||||
}
|
||||
/* 0xff01 is a flag rather then an actual voltage */
|
||||
if (voltage->vddci == 0xff01)
|
||||
return;
|
||||
if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) {
|
||||
radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI);
|
||||
rdev->pm.current_vddci = voltage->vddci;
|
||||
|
@ -2695,28 +2701,25 @@ static inline u32 evergreen_get_ih_wptr(struct radeon_device *rdev)
|
|||
|
||||
int evergreen_irq_process(struct radeon_device *rdev)
|
||||
{
|
||||
u32 wptr = evergreen_get_ih_wptr(rdev);
|
||||
u32 rptr = rdev->ih.rptr;
|
||||
u32 wptr;
|
||||
u32 rptr;
|
||||
u32 src_id, src_data;
|
||||
u32 ring_index;
|
||||
unsigned long flags;
|
||||
bool queue_hotplug = false;
|
||||
|
||||
DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
|
||||
if (!rdev->ih.enabled)
|
||||
if (!rdev->ih.enabled || rdev->shutdown)
|
||||
return IRQ_NONE;
|
||||
|
||||
spin_lock_irqsave(&rdev->ih.lock, flags);
|
||||
wptr = evergreen_get_ih_wptr(rdev);
|
||||
rptr = rdev->ih.rptr;
|
||||
DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
|
||||
|
||||
spin_lock_irqsave(&rdev->ih.lock, flags);
|
||||
if (rptr == wptr) {
|
||||
spin_unlock_irqrestore(&rdev->ih.lock, flags);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
if (rdev->shutdown) {
|
||||
spin_unlock_irqrestore(&rdev->ih.lock, flags);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
restart_ih:
|
||||
/* display interrupts */
|
||||
evergreen_irq_ack(rdev);
|
||||
|
|
|
@ -590,6 +590,9 @@ void r600_pm_misc(struct radeon_device *rdev)
|
|||
struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
|
||||
|
||||
if ((voltage->type == VOLTAGE_SW) && voltage->voltage) {
|
||||
/* 0xff01 is a flag rather then an actual voltage */
|
||||
if (voltage->voltage == 0xff01)
|
||||
return;
|
||||
if (voltage->voltage != rdev->pm.current_vddc) {
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
rdev->pm.current_vddc = voltage->voltage;
|
||||
|
@ -3294,27 +3297,26 @@ static inline u32 r600_get_ih_wptr(struct radeon_device *rdev)
|
|||
|
||||
int r600_irq_process(struct radeon_device *rdev)
|
||||
{
|
||||
u32 wptr = r600_get_ih_wptr(rdev);
|
||||
u32 rptr = rdev->ih.rptr;
|
||||
u32 wptr;
|
||||
u32 rptr;
|
||||
u32 src_id, src_data;
|
||||
u32 ring_index;
|
||||
unsigned long flags;
|
||||
bool queue_hotplug = false;
|
||||
|
||||
DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
|
||||
if (!rdev->ih.enabled)
|
||||
if (!rdev->ih.enabled || rdev->shutdown)
|
||||
return IRQ_NONE;
|
||||
|
||||
wptr = r600_get_ih_wptr(rdev);
|
||||
rptr = rdev->ih.rptr;
|
||||
DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
|
||||
|
||||
spin_lock_irqsave(&rdev->ih.lock, flags);
|
||||
|
||||
if (rptr == wptr) {
|
||||
spin_unlock_irqrestore(&rdev->ih.lock, flags);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
if (rdev->shutdown) {
|
||||
spin_unlock_irqrestore(&rdev->ih.lock, flags);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
restart_ih:
|
||||
/* display interrupts */
|
||||
|
|
|
@ -2607,6 +2607,10 @@ void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 v
|
|||
if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
|
||||
return;
|
||||
|
||||
/* 0xff01 is a flag rather then an actual voltage */
|
||||
if (voltage_level == 0xff01)
|
||||
return;
|
||||
|
||||
switch (crev) {
|
||||
case 1:
|
||||
args.v1.ucVoltageType = voltage_type;
|
||||
|
|
|
@ -1090,9 +1090,10 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
|||
break;
|
||||
}
|
||||
|
||||
if (is_dp)
|
||||
if (is_dp) {
|
||||
args.v2.acConfig.fCoherentMode = 1;
|
||||
else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
|
||||
args.v2.acConfig.fDPConnector = 1;
|
||||
} else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
|
||||
if (dig->coherent_mode)
|
||||
args.v2.acConfig.fCoherentMode = 1;
|
||||
if (radeon_encoder->pixel_clock > 165000)
|
||||
|
@ -1431,7 +1432,11 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
|
|||
if (is_dig) {
|
||||
switch (mode) {
|
||||
case DRM_MODE_DPMS_ON:
|
||||
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
|
||||
/* some early dce3.2 boards have a bug in their transmitter control table */
|
||||
if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730))
|
||||
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
|
||||
else
|
||||
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
|
||||
if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
|
||||
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
|
||||
|
||||
|
|
|
@ -105,6 +105,9 @@ void rv770_pm_misc(struct radeon_device *rdev)
|
|||
struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
|
||||
|
||||
if ((voltage->type == VOLTAGE_SW) && voltage->voltage) {
|
||||
/* 0xff01 is a flag rather then an actual voltage */
|
||||
if (voltage->voltage == 0xff01)
|
||||
return;
|
||||
if (voltage->voltage != rdev->pm.current_vddc) {
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
rdev->pm.current_vddc = voltage->voltage;
|
||||
|
|
Загрузка…
Ссылка в новой задаче