#include <subdev/bios/init.h>
 #include <subdev/i2c.h>
 
-#include <engine/disp.h>
+#include "nv50.h"
 
 #include <nvif/class.h>
 
 nouveau_dp_train(struct work_struct *w)
 {
        struct nvkm_output_dp *outp = container_of(w, typeof(*outp), lt.work);
-       struct nouveau_disp *disp = nouveau_disp(outp);
+       struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
        const struct dp_rates *cfg = nouveau_dp_rates;
        struct dp_state _dp = {
                .outp = outp,
        u32 datarate = 0;
        int ret;
 
+       if (!outp->base.info.location && priv->sor.magic)
+               priv->sor.magic(&outp->base);
+
        /* bring capabilities within encoder limits */
-       if (nv_mclass(disp) < GF110_DISP)
+       if (nv_mclass(priv) < GF110_DISP)
                outp->dpcd[2] &= ~DPCD_RC02_TPS3_SUPPORTED;
        if ((outp->dpcd[2] & 0x1f) > outp->base.info.dpconf.link_nr) {
                outp->dpcd[2] &= ~DPCD_RC02_MAX_LANE_COUNT;
 
        priv->sor.power = nv50_sor_power;
        priv->sor.hda_eld = nvd0_hda_eld;
        priv->sor.hdmi = nvd0_hdmi_ctrl;
+       priv->sor.magic = gm204_sor_magic;
        return 0;
 }
 
 
                int (*hda_eld)(NV50_DISP_MTHD_V1);
                int (*hdmi)(NV50_DISP_MTHD_V1);
                u32 lvdsconf;
+               void (*magic)(struct nvkm_output *);
        } sor;
        struct {
                int nr;
 int nvd0_sor_dp_lnk_ctl(struct nvkm_output_dp *, int, int, bool);
 extern struct nouveau_oclass *nvd0_disp_outp_sclass[];
 
+void gm204_sor_magic(struct nvkm_output *outp);
 extern struct nvkm_output_dp_impl gm204_sor_dp_impl;
 
 #endif
 
 
                if (nvkm_output_dp_train(outp, pclk, true))
                        ERR("link not trained before attach\n");
+       } else {
+               if (priv->sor.magic)
+                       priv->sor.magic(outp);
        }
 
        exec_clkcmp(priv, head, 0, pclk, &conf);
 
        return gm204_sor_soff(outp) + !(outp->base.info.sorconf.link & 1) * 0x80;
 }
 
+void
+gm204_sor_magic(struct nvkm_output *outp)
+{
+       struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
+       const u32 soff = outp->or * 0x100;
+       const u32 data = outp->or + 1;
+       if (outp->info.sorconf.link & 1)
+               nv_mask(priv, 0x612308 + soff, 0x0000001f, 0x00000000 | data);
+       if (outp->info.sorconf.link & 2)
+               nv_mask(priv, 0x612388 + soff, 0x0000001f, 0x00000010 | data);
+}
+
 static inline u32
 gm204_sor_dp_lane_map(struct nv50_disp_priv *priv, u8 lane)
 {