drm/nouveau/disp: move LVDS protocol information into acquire
authorBen Skeggs <bskeggs@redhat.com>
Wed, 1 Jun 2022 10:46:32 +0000 (20:46 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Mon, 7 Nov 2022 02:59:29 +0000 (12:59 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
drivers/gpu/drm/nouveau/dispnv50/disp.c
drivers/gpu/drm/nouveau/include/nvif/cl5070.h
drivers/gpu/drm/nouveau/include/nvif/if0012.h
drivers/gpu/drm/nouveau/include/nvif/outp.h
drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h
drivers/gpu/drm/nouveau/nvif/outp.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c

index 093321a93046e46aea04bb4c126652791027df30..0a8404686f169902c43f48f372f48af3a63ba33e 100644 (file)
@@ -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);
index 37e669b9c4dcdd655ab4640d5d5c41c4f4e1388c..f371fc7a1d10039e1b8f93342ef86594a2b99b61 100644 (file)
@@ -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;
index 8bc00a8c525af691f088d5888f315462b6909db8..4fcb9e4f5d766006f83cd4b0056457375869c34d 100644 (file)
@@ -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];
index 2a45b57b1f75c14d5911c410064ede56af842d7d..e247d441afc1d342075f221b305847af55816b21 100644 (file)
@@ -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
index 8b5d8a434be863217d2e4f7fb00a8ddafc2b2501..eaf10f5d505e1244f4c80fd472f41977258b8639 100644 (file)
@@ -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;
index bd20f75045dc70648415291932d464022b3db362..58cd629657fb981d4c4d33f4cbff8b7d556d574b 100644 (file)
@@ -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;
 }
 
index a46e13cc9ff13674e8fa19fc56c90a295d96328d..55ac6d70e95000b1ba344c26a451125124cc7976 100644 (file)
@@ -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. */
index 3f3924c4195710ca716cd99d496343725507cce2..16aadcedcbda37f8bd8222050f68fbd77bd0f76f 100644 (file)
@@ -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;
index 341f244cddb71c725f66bc53368aff60b034d877..f028ab17f8cfdd5c1232641199f93bffac6a3d4b 100644 (file)
@@ -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;
index edbed699ade2b81ceeb0d9861a94a76c49eb1a74..7e0cef0f80a9a6db931020d4fb458e7130163039 100644 (file)
@@ -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;