drm/nouveau/disp: move LVDS protocol information into acquire
Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Reviewed-by: Lyude Paul <lyude@redhat.com>
This commit is contained in:
parent
ea6143a86c
commit
9793083f1d
@ -1635,15 +1635,6 @@ nv50_sor_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *sta
|
||||
struct nv50_head_atom *asyh =
|
||||
nv50_head_atom(drm_atomic_get_new_crtc_state(state, &nv_crtc->base));
|
||||
struct drm_display_mode *mode = &asyh->state.adjusted_mode;
|
||||
struct {
|
||||
struct nv50_disp_mthd_v1 base;
|
||||
struct nv50_disp_sor_lvds_script_v0 lvds;
|
||||
} lvds = {
|
||||
.base.version = 1,
|
||||
.base.method = NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT,
|
||||
.base.hasht = nv_encoder->dcb->hasht,
|
||||
.base.hashm = nv_encoder->dcb->hashm,
|
||||
};
|
||||
struct nv50_disp *disp = nv50_disp(encoder->dev);
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||
@ -1652,7 +1643,7 @@ nv50_sor_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *sta
|
||||
struct nouveau_backlight *backlight;
|
||||
#endif
|
||||
struct nvbios *bios = &drm->vbios;
|
||||
bool hda = false;
|
||||
bool lvds_dual = false, lvds_8bpc = false, hda = false;
|
||||
u8 proto = NV507D_SOR_SET_CONTROL_PROTOCOL_CUSTOM;
|
||||
u8 depth = NV837D_SOR_SET_CONTROL_PIXEL_DEPTH_DEFAULT;
|
||||
|
||||
@ -1689,33 +1680,30 @@ nv50_sor_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *sta
|
||||
proto = NV507D_SOR_SET_CONTROL_PROTOCOL_LVDS_CUSTOM;
|
||||
|
||||
if (bios->fp_no_ddc) {
|
||||
if (bios->fp.dual_link)
|
||||
lvds.lvds.script |= 0x0100;
|
||||
if (bios->fp.if_is_24bit)
|
||||
lvds.lvds.script |= 0x0200;
|
||||
lvds_dual = bios->fp.dual_link;
|
||||
lvds_8bpc = bios->fp.if_is_24bit;
|
||||
} else {
|
||||
if (nv_connector->type == DCB_CONNECTOR_LVDS_SPWG) {
|
||||
if (((u8 *)nv_connector->edid)[121] == 2)
|
||||
lvds.lvds.script |= 0x0100;
|
||||
lvds_dual = true;
|
||||
} else
|
||||
if (mode->clock >= bios->fp.duallink_transition_clk) {
|
||||
lvds.lvds.script |= 0x0100;
|
||||
lvds_dual = true;
|
||||
}
|
||||
|
||||
if (lvds.lvds.script & 0x0100) {
|
||||
if (lvds_dual) {
|
||||
if (bios->fp.strapless_is_24bit & 2)
|
||||
lvds.lvds.script |= 0x0200;
|
||||
lvds_8bpc = true;
|
||||
} else {
|
||||
if (bios->fp.strapless_is_24bit & 1)
|
||||
lvds.lvds.script |= 0x0200;
|
||||
lvds_8bpc = true;
|
||||
}
|
||||
|
||||
if (asyh->or.bpc == 8)
|
||||
lvds.lvds.script |= 0x0200;
|
||||
lvds_8bpc = true;
|
||||
}
|
||||
|
||||
nvif_outp_acquire_lvds(&nv_encoder->outp);
|
||||
nvif_mthd(&disp->disp->object, 0, &lvds, sizeof(lvds));
|
||||
nvif_outp_acquire_lvds(&nv_encoder->outp, lvds_dual, lvds_8bpc);
|
||||
break;
|
||||
case DCB_OUTPUT_DP:
|
||||
nvif_outp_acquire_dp(&nv_encoder->outp, hda);
|
||||
|
@ -30,7 +30,6 @@ struct nv50_disp_mthd_v1 {
|
||||
__u8 version;
|
||||
#define NV50_DISP_MTHD_V1_SOR_HDA_ELD 0x21
|
||||
#define NV50_DISP_MTHD_V1_SOR_HDMI_PWR 0x22
|
||||
#define NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT 0x23
|
||||
#define NV50_DISP_MTHD_V1_SOR_DP_MST_LINK 0x25
|
||||
#define NV50_DISP_MTHD_V1_SOR_DP_MST_VCPI 0x26
|
||||
__u8 method;
|
||||
@ -58,13 +57,6 @@ struct nv50_disp_sor_hdmi_pwr_v0 {
|
||||
__u8 pad07[1];
|
||||
};
|
||||
|
||||
struct nv50_disp_sor_lvds_script_v0 {
|
||||
__u8 version;
|
||||
__u8 pad01[1];
|
||||
__u16 script;
|
||||
__u8 pad04[4];
|
||||
};
|
||||
|
||||
struct nv50_disp_sor_dp_mst_link_v0 {
|
||||
__u8 version;
|
||||
__u8 state;
|
||||
|
@ -40,6 +40,11 @@ union nvif_outp_acquire_args {
|
||||
__u8 hda;
|
||||
__u8 pad01[7];
|
||||
} tmds;
|
||||
struct {
|
||||
__u8 dual;
|
||||
__u8 bpc8;
|
||||
__u8 pad02[6];
|
||||
} lvds;
|
||||
struct {
|
||||
__u8 hda;
|
||||
__u8 pad01[7];
|
||||
|
@ -18,7 +18,7 @@ void nvif_outp_dtor(struct nvif_outp *);
|
||||
int nvif_outp_load_detect(struct nvif_outp *, u32 loadval);
|
||||
int nvif_outp_acquire_rgb_crt(struct nvif_outp *);
|
||||
int nvif_outp_acquire_tmds(struct nvif_outp *, bool hda);
|
||||
int nvif_outp_acquire_lvds(struct nvif_outp *);
|
||||
int nvif_outp_acquire_lvds(struct nvif_outp *, bool dual, bool bpc8);
|
||||
int nvif_outp_acquire_dp(struct nvif_outp *, bool hda);
|
||||
void nvif_outp_release(struct nvif_outp *);
|
||||
#endif
|
||||
|
@ -31,13 +31,7 @@ struct nvkm_disp {
|
||||
struct {
|
||||
unsigned long mask;
|
||||
int nr;
|
||||
} wndw, head, dac;
|
||||
|
||||
struct {
|
||||
unsigned long mask;
|
||||
int nr;
|
||||
u32 lvdsconf;
|
||||
} sor;
|
||||
} wndw, head, dac, sor;
|
||||
|
||||
struct {
|
||||
unsigned long mask;
|
||||
|
@ -66,13 +66,18 @@ nvif_outp_acquire_dp(struct nvif_outp *outp, bool hda)
|
||||
}
|
||||
|
||||
int
|
||||
nvif_outp_acquire_lvds(struct nvif_outp *outp)
|
||||
nvif_outp_acquire_lvds(struct nvif_outp *outp, bool dual, bool bpc8)
|
||||
{
|
||||
struct nvif_outp_acquire_v0 args;
|
||||
int ret;
|
||||
|
||||
args.lvds.dual = dual;
|
||||
args.lvds.bpc8 = bpc8;
|
||||
|
||||
ret = nvif_outp_acquire(outp, NVIF_OUTP_ACQUIRE_V0_LVDS, &args);
|
||||
NVIF_ERRON(ret, &outp->object, "[ACQUIRE proto:LVDS] or:%d link:%d", args.or, args.link);
|
||||
NVIF_ERRON(ret, &outp->object,
|
||||
"[ACQUIRE proto:LVDS dual:%d 8bpc:%d] or:%d link:%d",
|
||||
args.lvds.dual, args.lvds.bpc8, args.or, args.link);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1238,6 +1238,8 @@ nv50_disp_super_2_2(struct nvkm_disp *disp, struct nvkm_head *head)
|
||||
if (!ior)
|
||||
return;
|
||||
|
||||
outp = ior->asy.outp;
|
||||
|
||||
/* For some reason, NVIDIA decided not to:
|
||||
*
|
||||
* A) Give dual-link LVDS a separate EVO protocol, like for TMDS.
|
||||
@ -1247,13 +1249,13 @@ nv50_disp_super_2_2(struct nvkm_disp *disp, struct nvkm_head *head)
|
||||
* Override the values we usually read from HW with the same
|
||||
* data we pass though an ioctl instead.
|
||||
*/
|
||||
if (ior->type == SOR && ior->asy.proto == LVDS) {
|
||||
head->asy.or.depth = (disp->sor.lvdsconf & 0x0200) ? 24 : 18;
|
||||
ior->asy.link = (disp->sor.lvdsconf & 0x0100) ? 3 : 1;
|
||||
if (outp && ior->type == SOR && ior->asy.proto == LVDS) {
|
||||
head->asy.or.depth = outp->lvds.bpc8 ? 24 : 18;
|
||||
ior->asy.link = outp->lvds.dual ? 3 : 1;
|
||||
}
|
||||
|
||||
/* Handle any link training, etc. */
|
||||
if ((outp = ior->asy.outp) && outp->func->acquire)
|
||||
if (outp && outp->func->acquire)
|
||||
outp->func->acquire(outp);
|
||||
|
||||
/* Execute OnInt2 IED script. */
|
||||
|
@ -27,6 +27,11 @@ struct nvkm_outp {
|
||||
struct nvkm_ior *ior;
|
||||
|
||||
union {
|
||||
struct {
|
||||
bool dual;
|
||||
bool bpc8;
|
||||
} lvds;
|
||||
|
||||
struct {
|
||||
struct nvbios_dpout info;
|
||||
u8 version;
|
||||
|
@ -169,22 +169,6 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT: {
|
||||
union {
|
||||
struct nv50_disp_sor_lvds_script_v0 v0;
|
||||
} *args = data;
|
||||
int ret = -ENOSYS;
|
||||
nvif_ioctl(object, "disp sor lvds script size %d\n", size);
|
||||
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
|
||||
nvif_ioctl(object, "disp sor lvds script "
|
||||
"vers %d name %04x\n",
|
||||
args->v0.version, args->v0.script);
|
||||
disp->sor.lvdsconf = args->v0.script;
|
||||
return 0;
|
||||
} else
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
case NV50_DISP_MTHD_V1_SOR_DP_MST_LINK: {
|
||||
union {
|
||||
struct nv50_disp_sor_dp_mst_link_v0 v0;
|
||||
|
@ -37,6 +37,18 @@ nvkm_uoutp_mthd_release(struct nvkm_outp *outp, void *argv, u32 argc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nvkm_uoutp_mthd_acquire_lvds(struct nvkm_outp *outp, bool dual, bool bpc8)
|
||||
{
|
||||
if (outp->info.type != DCB_OUTPUT_LVDS)
|
||||
return -EINVAL;
|
||||
|
||||
outp->lvds.dual = dual;
|
||||
outp->lvds.bpc8 = bpc8;
|
||||
|
||||
return nvkm_outp_acquire(outp, NVKM_OUTP_USER, false);
|
||||
}
|
||||
|
||||
static int
|
||||
nvkm_uoutp_mthd_acquire(struct nvkm_outp *outp, void *argv, u32 argc)
|
||||
{
|
||||
@ -48,13 +60,15 @@ nvkm_uoutp_mthd_acquire(struct nvkm_outp *outp, void *argv, u32 argc)
|
||||
|
||||
switch (args->v0.proto) {
|
||||
case NVIF_OUTP_ACQUIRE_V0_RGB_CRT:
|
||||
case NVIF_OUTP_ACQUIRE_V0_LVDS:
|
||||
ret = nvkm_outp_acquire(outp, NVKM_OUTP_USER, false);
|
||||
break;
|
||||
case NVIF_OUTP_ACQUIRE_V0_TMDS:
|
||||
case NVIF_OUTP_ACQUIRE_V0_DP:
|
||||
ret = nvkm_outp_acquire(outp, NVKM_OUTP_USER, args->v0.dp.hda);
|
||||
break;
|
||||
case NVIF_OUTP_ACQUIRE_V0_LVDS:
|
||||
ret = nvkm_uoutp_mthd_acquire_lvds(outp, args->v0.lvds.dual, args->v0.lvds.bpc8);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user