}
 
 static int
-nvkm_dp_train_links(struct lt_state *lt)
+nvkm_dp_train_links(struct nvkm_dp *dp)
 {
-       struct nvkm_dp *dp = lt->dp;
        struct nvkm_ior *ior = dp->outp.ior;
        struct nvkm_disp *disp = dp->outp.disp;
        struct nvkm_subdev *subdev = &disp->engine.subdev;
                .crtc = -1,
                .execute = 1,
        };
+       struct lt_state lt = {
+               .dp = dp,
+       };
        u32 lnkcmp;
        u8 sink[2];
        int ret;
 
        /* Intersect misc. capabilities of the OR and sink. */
        if (disp->engine.subdev.device->chipset < 0xd0)
-               dp->dpcd[2] &= ~DPCD_RC02_TPS3_SUPPORTED;
-       lt->pc2 = dp->dpcd[2] & DPCD_RC02_TPS3_SUPPORTED;
+               dp->dpcd[DPCD_RC02] &= ~DPCD_RC02_TPS3_SUPPORTED;
+       lt.pc2 = dp->dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED;
 
        /* Set desired link configuration on the source. */
-       if ((lnkcmp = lt->dp->info.lnkcmp)) {
+       if ((lnkcmp = lt.dp->info.lnkcmp)) {
                if (dp->version < 0x30) {
                        while ((ior->dp.bw * 2700) < nvbios_rd16(bios, lnkcmp))
                                lnkcmp += 4;
        if (ior->dp.ef)
                sink[1] |= DPCD_LC01_ENHANCED_FRAME_EN;
 
-       return nvkm_wraux(dp->aux, DPCD_LC00_LINK_BW_SET, sink, 2);
+       ret = nvkm_wraux(dp->aux, DPCD_LC00_LINK_BW_SET, sink, 2);
+       if (ret)
+               return ret;
+
+       /* Attempt to train the link in this configuration. */
+       memset(lt.stat, 0x00, sizeof(lt.stat));
+       ret = nvkm_dp_train_cr(<);
+       if (ret == 0)
+               ret = nvkm_dp_train_eq(<);
+       nvkm_dp_train_pattern(<, 0);
+       return ret;
 }
 
 static void
-nvkm_dp_train_fini(struct lt_state *lt)
+nvkm_dp_train_fini(struct nvkm_dp *dp)
 {
-       struct nvkm_dp *dp = lt->dp;
        struct nvkm_subdev *subdev = &dp->outp.disp->engine.subdev;
        struct nvbios_init init = {
                .subdev = subdev,
 }
 
 static void
-nvkm_dp_train_init(struct lt_state *lt)
+nvkm_dp_train_init(struct nvkm_dp *dp)
 {
-       struct nvkm_dp *dp = lt->dp;
        struct nvkm_subdev *subdev = &dp->outp.disp->engine.subdev;
        struct nvbios_init init = {
                .subdev = subdev,
        const u8 outp_nr = dp->outp.info.dpconf.link_nr;
        const u8 outp_bw = dp->outp.info.dpconf.link_bw;
        const struct dp_rates *cfg;
-       struct lt_state lt = {
-               .dp = dp,
-       };
        u8  pwr;
        int ret;
 
        }
 
        /* Link training. */
-       nvkm_dp_train_init(<);
-       for (ret = -EINVAL, cfg = nvkm_dp_rates; cfg->rate; cfg++) {
+       nvkm_dp_train_init(dp);
+       for (ret = -EINVAL, cfg = nvkm_dp_rates; ret < 0 && cfg->rate; cfg++) {
                /* Skip configurations not supported by both OR and sink. */
                if (cfg[1].rate &&
                    (cfg->nr > outp_nr || cfg->bw > outp_bw ||
                ior->dp.nr = cfg->nr;
 
                /* Program selected link configuration. */
-               ret = nvkm_dp_train_links(<);
-               if (ret == 0) {
-                       /* Attempt to train the link in this configuration. */
-                       memset(lt.stat, 0x00, sizeof(lt.stat));
-                       if (!nvkm_dp_train_cr(<) &&
-                           !nvkm_dp_train_eq(<))
-                               break;
-               } else
-               if (ret) {
-                       /* nvkm_dp_train_links() handled training, or
-                        * we failed to communicate with the sink.
-                        */
-                       break;
-               }
+               ret = nvkm_dp_train_links(dp);
        }
-       nvkm_dp_train_pattern(<, 0);
-       nvkm_dp_train_fini(<);
+       nvkm_dp_train_fini(dp);
        if (ret < 0)
                OUTP_ERR(&dp->outp, "training failed");