Merge branch 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-fixes
A couple of DP regression fixes, kepler memory reclocking fixes, and a fix for an annoying display issue that can pop up on resume. * 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: drm/nouveau/ram: fix test for gpio presence drm/nouveau/dp: workaround broken display drm/nouveau/dp: fix required link bandwidth calculations drm/nouveau/kms: restore fbcon after display has been resumed drm/nv50-/kms: pass a non-zero value for head to sor dpms methods drm/nouveau/fb: Prevent inlining of ramfuc_reg drm/gk104/ram: bash mpll bit 31 on
This commit is contained in:
commit
093fa5d053
10 changed files with 29 additions and 31 deletions
|
@ -1516,11 +1516,11 @@ nv50_disp_intr_unk20_2(struct nv50_disp_priv *priv, int head)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ((ctrl & 0x000f0000) >> 16) {
|
switch ((ctrl & 0x000f0000) >> 16) {
|
||||||
case 6: datarate = pclk * 30 / 8; break;
|
case 6: datarate = pclk * 30; break;
|
||||||
case 5: datarate = pclk * 24 / 8; break;
|
case 5: datarate = pclk * 24; break;
|
||||||
case 2:
|
case 2:
|
||||||
default:
|
default:
|
||||||
datarate = pclk * 18 / 8;
|
datarate = pclk * 18;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1159,11 +1159,11 @@ nvd0_disp_intr_unk2_2(struct nv50_disp_priv *priv, int head)
|
||||||
if (outp->info.type == DCB_OUTPUT_DP) {
|
if (outp->info.type == DCB_OUTPUT_DP) {
|
||||||
u32 sync = nv_rd32(priv, 0x660404 + (head * 0x300));
|
u32 sync = nv_rd32(priv, 0x660404 + (head * 0x300));
|
||||||
switch ((sync & 0x000003c0) >> 6) {
|
switch ((sync & 0x000003c0) >> 6) {
|
||||||
case 6: pclk = pclk * 30 / 8; break;
|
case 6: pclk = pclk * 30; break;
|
||||||
case 5: pclk = pclk * 24 / 8; break;
|
case 5: pclk = pclk * 24; break;
|
||||||
case 2:
|
case 2:
|
||||||
default:
|
default:
|
||||||
pclk = pclk * 18 / 8;
|
pclk = pclk * 18;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait)
|
||||||
struct nvkm_output_dp *outp = (void *)base;
|
struct nvkm_output_dp *outp = (void *)base;
|
||||||
bool retrain = true;
|
bool retrain = true;
|
||||||
u8 link[2], stat[3];
|
u8 link[2], stat[3];
|
||||||
u32 rate;
|
u32 linkrate;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
/* check that the link is trained at a high enough rate */
|
/* check that the link is trained at a high enough rate */
|
||||||
|
@ -44,8 +44,10 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
rate = link[0] * 27000 * (link[1] & DPCD_LC01_LANE_COUNT_SET);
|
linkrate = link[0] * 27000 * (link[1] & DPCD_LC01_LANE_COUNT_SET);
|
||||||
if (rate < ((datarate / 8) * 10)) {
|
linkrate = (linkrate * 8) / 10; /* 8B/10B coding overhead */
|
||||||
|
datarate = (datarate + 9) / 10; /* -> decakilobits */
|
||||||
|
if (linkrate < datarate) {
|
||||||
DBG("link not trained at sufficient rate\n");
|
DBG("link not trained at sufficient rate\n");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,7 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size)
|
||||||
struct nvkm_output_dp *outpdp = (void *)outp;
|
struct nvkm_output_dp *outpdp = (void *)outp;
|
||||||
switch (data) {
|
switch (data) {
|
||||||
case NV94_DISP_SOR_DP_PWR_STATE_OFF:
|
case NV94_DISP_SOR_DP_PWR_STATE_OFF:
|
||||||
|
nouveau_event_put(outpdp->irq);
|
||||||
((struct nvkm_output_dp_impl *)nv_oclass(outp))
|
((struct nvkm_output_dp_impl *)nv_oclass(outp))
|
||||||
->lnk_pwr(outpdp, 0);
|
->lnk_pwr(outpdp, 0);
|
||||||
atomic_set(&outpdp->lt.done, 0);
|
atomic_set(&outpdp->lt.done, 0);
|
||||||
|
|
|
@ -26,7 +26,7 @@ ramfuc_reg2(u32 addr1, u32 addr2)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct ramfuc_reg
|
static noinline struct ramfuc_reg
|
||||||
ramfuc_reg(u32 addr)
|
ramfuc_reg(u32 addr)
|
||||||
{
|
{
|
||||||
return ramfuc_reg2(addr, addr);
|
return ramfuc_reg2(addr, addr);
|
||||||
|
@ -107,7 +107,7 @@ ramfuc_nsec(struct ramfuc *ram, u32 nsec)
|
||||||
|
|
||||||
#define ram_init(s,p) ramfuc_init(&(s)->base, (p))
|
#define ram_init(s,p) ramfuc_init(&(s)->base, (p))
|
||||||
#define ram_exec(s,e) ramfuc_exec(&(s)->base, (e))
|
#define ram_exec(s,e) ramfuc_exec(&(s)->base, (e))
|
||||||
#define ram_have(s,r) ((s)->r_##r.addr != 0x000000)
|
#define ram_have(s,r) ((s)->r_##r.addr[0] != 0x000000)
|
||||||
#define ram_rd32(s,r) ramfuc_rd32(&(s)->base, &(s)->r_##r)
|
#define ram_rd32(s,r) ramfuc_rd32(&(s)->base, &(s)->r_##r)
|
||||||
#define ram_wr32(s,r,d) ramfuc_wr32(&(s)->base, &(s)->r_##r, (d))
|
#define ram_wr32(s,r,d) ramfuc_wr32(&(s)->base, &(s)->r_##r, (d))
|
||||||
#define ram_nuke(s,r) ramfuc_nuke(&(s)->base, &(s)->r_##r)
|
#define ram_nuke(s,r) ramfuc_nuke(&(s)->base, &(s)->r_##r)
|
||||||
|
|
|
@ -200,6 +200,7 @@ r1373f4_init(struct nve0_ramfuc *fuc)
|
||||||
/* (re)program mempll, if required */
|
/* (re)program mempll, if required */
|
||||||
if (ram->mode == 2) {
|
if (ram->mode == 2) {
|
||||||
ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000);
|
ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000);
|
||||||
|
ram_mask(fuc, 0x132000, 0x80000000, 0x80000000);
|
||||||
ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
|
ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
|
||||||
ram_mask(fuc, 0x132004, 0x103fffff, mcoef);
|
ram_mask(fuc, 0x132004, 0x103fffff, mcoef);
|
||||||
ram_mask(fuc, 0x132000, 0x00000001, 0x00000001);
|
ram_mask(fuc, 0x132000, 0x00000001, 0x00000001);
|
||||||
|
|
|
@ -652,12 +652,12 @@ int nouveau_pmops_resume(struct device *dev)
|
||||||
ret = nouveau_do_resume(drm_dev);
|
ret = nouveau_do_resume(drm_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (drm_dev->mode_config.num_crtc)
|
|
||||||
nouveau_fbcon_set_suspend(drm_dev, 0);
|
|
||||||
|
|
||||||
nouveau_fbcon_zfill_all(drm_dev);
|
if (drm_dev->mode_config.num_crtc) {
|
||||||
if (drm_dev->mode_config.num_crtc)
|
|
||||||
nouveau_display_resume(drm_dev);
|
nouveau_display_resume(drm_dev);
|
||||||
|
nouveau_fbcon_set_suspend(drm_dev, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -683,11 +683,12 @@ static int nouveau_pmops_thaw(struct device *dev)
|
||||||
ret = nouveau_do_resume(drm_dev);
|
ret = nouveau_do_resume(drm_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (drm_dev->mode_config.num_crtc)
|
|
||||||
nouveau_fbcon_set_suspend(drm_dev, 0);
|
if (drm_dev->mode_config.num_crtc) {
|
||||||
nouveau_fbcon_zfill_all(drm_dev);
|
|
||||||
if (drm_dev->mode_config.num_crtc)
|
|
||||||
nouveau_display_resume(drm_dev);
|
nouveau_display_resume(drm_dev);
|
||||||
|
nouveau_fbcon_set_suspend(drm_dev, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -531,17 +531,10 @@ nouveau_fbcon_set_suspend(struct drm_device *dev, int state)
|
||||||
if (state == 1)
|
if (state == 1)
|
||||||
nouveau_fbcon_save_disable_accel(dev);
|
nouveau_fbcon_save_disable_accel(dev);
|
||||||
fb_set_suspend(drm->fbcon->helper.fbdev, state);
|
fb_set_suspend(drm->fbcon->helper.fbdev, state);
|
||||||
if (state == 0)
|
if (state == 0) {
|
||||||
nouveau_fbcon_restore_accel(dev);
|
nouveau_fbcon_restore_accel(dev);
|
||||||
|
nouveau_fbcon_zfill(dev, drm->fbcon);
|
||||||
|
}
|
||||||
console_unlock();
|
console_unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nouveau_fbcon_zfill_all(struct drm_device *dev)
|
|
||||||
{
|
|
||||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
|
||||||
if (drm->fbcon) {
|
|
||||||
nouveau_fbcon_zfill(dev, drm->fbcon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -61,7 +61,6 @@ void nouveau_fbcon_gpu_lockup(struct fb_info *info);
|
||||||
int nouveau_fbcon_init(struct drm_device *dev);
|
int nouveau_fbcon_init(struct drm_device *dev);
|
||||||
void nouveau_fbcon_fini(struct drm_device *dev);
|
void nouveau_fbcon_fini(struct drm_device *dev);
|
||||||
void nouveau_fbcon_set_suspend(struct drm_device *dev, int state);
|
void nouveau_fbcon_set_suspend(struct drm_device *dev, int state);
|
||||||
void nouveau_fbcon_zfill_all(struct drm_device *dev);
|
|
||||||
void nouveau_fbcon_save_disable_accel(struct drm_device *dev);
|
void nouveau_fbcon_save_disable_accel(struct drm_device *dev);
|
||||||
void nouveau_fbcon_restore_accel(struct drm_device *dev);
|
void nouveau_fbcon_restore_accel(struct drm_device *dev);
|
||||||
|
|
||||||
|
|
|
@ -1741,7 +1741,8 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mthd = (ffs(nv_encoder->dcb->sorconf.link) - 1) << 2;
|
mthd = (ffs(nv_encoder->dcb->heads) - 1) << 3;
|
||||||
|
mthd |= (ffs(nv_encoder->dcb->sorconf.link) - 1) << 2;
|
||||||
mthd |= nv_encoder->or;
|
mthd |= nv_encoder->or;
|
||||||
|
|
||||||
if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
|
if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue