drm/nouveau/disp/dp: add support for tps4
authorBen Skeggs <bskeggs@redhat.com>
Tue, 23 Nov 2021 08:17:54 +0000 (18:17 +1000)
committerKarol Herbst <kherbst@redhat.com>
Thu, 16 Dec 2021 17:46:10 +0000 (18:46 +0100)
Required for HBR3 and LTTPR.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Link: https://gitlab.freedesktop.org/drm/nouveau/-/merge_requests/17
drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c

index 8b49398a91c531baa8c2524465cdfea0367ae19b..565ee63c0f1d56ac77f6422ca5128c888e16f53b 100644 (file)
@@ -153,7 +153,7 @@ nvkm_dp_train_pattern(struct lt_state *lt, u8 pattern)
 
        nvkm_rdaux(dp->aux, DPCD_LC02, &sink_tp, 1);
        sink_tp &= ~DPCD_LC02_TRAINING_PATTERN_SET;
-       sink_tp |= pattern;
+       sink_tp |= (pattern != 4) ? pattern : 7;
 
        if (pattern != 0)
                sink_tp |=  DPCD_LC02_SCRAMBLING_DISABLE;
@@ -168,10 +168,17 @@ nvkm_dp_train_eq(struct lt_state *lt)
        bool eq_done = false, cr_done = true;
        int tries = 0, i;
 
-       if (lt->dp->dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED)
-               nvkm_dp_train_pattern(lt, 3);
-       else
-               nvkm_dp_train_pattern(lt, 2);
+       {
+               if (lt->dp->dpcd[DPCD_RC00_DPCD_REV] >= 0x14 &&
+                   lt->dp->dpcd[DPCD_RC03] & DPCD_RC03_TPS4_SUPPORTED)
+                       nvkm_dp_train_pattern(lt, 4);
+               else
+               if (lt->dp->dpcd[DPCD_RC00_DPCD_REV] >= 0x12 &&
+                   lt->dp->dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED)
+                       nvkm_dp_train_pattern(lt, 3);
+               else
+                       nvkm_dp_train_pattern(lt, 2);
+       }
 
        do {
                if ((tries &&
@@ -245,6 +252,8 @@ nvkm_dp_train_links(struct nvkm_dp *dp)
                 ior->dp.nr, ior->dp.bw * 27);
 
        /* Intersect misc. capabilities of the OR and sink. */
+       if (disp->engine.subdev.device->chipset < 0x110)
+               dp->dpcd[DPCD_RC03] &= ~DPCD_RC03_TPS4_SUPPORTED;
        if (disp->engine.subdev.device->chipset < 0xd0)
                dp->dpcd[DPCD_RC02] &= ~DPCD_RC02_TPS3_SUPPORTED;
        lt.pc2 = dp->dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED;
index 8a8d0da582779767db11ab71deb57dec2cddd873..1becf9da3ed7c6644fd477461f05182b434b9e8d 100644 (file)
@@ -45,6 +45,7 @@ void nvkm_dp_disable(struct nvkm_outp *, struct nvkm_ior *);
 #define DPCD_RC02_TPS3_SUPPORTED                                           0x40
 #define DPCD_RC02_MAX_LANE_COUNT                                           0x1f
 #define DPCD_RC03                                                       0x00003
+#define DPCD_RC03_TPS4_SUPPORTED                                           0x80
 #define DPCD_RC03_MAX_DOWNSPREAD                                           0x01
 #define DPCD_RC0E_AUX_RD_INTERVAL                                       0x0000e
 
@@ -54,7 +55,7 @@ void nvkm_dp_disable(struct nvkm_outp *, struct nvkm_ior *);
 #define DPCD_LC01_ENHANCED_FRAME_EN                                        0x80
 #define DPCD_LC01_LANE_COUNT_SET                                           0x1f
 #define DPCD_LC02                                                       0x00102
-#define DPCD_LC02_TRAINING_PATTERN_SET                                     0x03
+#define DPCD_LC02_TRAINING_PATTERN_SET                                     0x0f
 #define DPCD_LC02_SCRAMBLING_DISABLE                                       0x20
 #define DPCD_LC03(l)                                            ((l) +  0x00103)
 #define DPCD_LC03_MAX_PRE_EMPHASIS_REACHED                                 0x20
index 5aa7138f3472b6f849c75f9d2e164fe6bad16388..3696bfd3bfd74bff0c905d231d4be9665f598633 100644 (file)
@@ -35,6 +35,7 @@ gm107_sor_dp_pattern(struct nvkm_ior *sor, int pattern)
        case 1: data = 0x01010101; break;
        case 2: data = 0x02020202; break;
        case 3: data = 0x03030303; break;
+       case 4: data = 0x1b1b1b1b; break;
        default:
                WARN_ON(1);
                return;