drm/nouveau/disp/g94-: port OR DP drive setting control to nvkm_ior
authorBen Skeggs <bskeggs@redhat.com>
Fri, 19 May 2017 13:59:35 +0000 (23:59 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 16 Jun 2017 04:04:56 +0000 (14:04 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
12 files changed:
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/ior.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c

index fecaa03eeb94f99e886f1e7c136b1d3a14f47a7e..2d8f93323309844645afda83ffe35baac12b683a 100644 (file)
@@ -73,9 +73,15 @@ static int
 nvkm_dp_train_drive(struct lt_state *lt, bool pc)
 {
        struct nvkm_dp *dp = lt->dp;
+       struct nvkm_ior *ior = dp->outp.ior;
+       struct nvkm_bios *bios = ior->disp->engine.subdev.device->bios;
+       struct nvbios_dpout info;
+       struct nvbios_dpcfg ocfg;
+       u8  ver, hdr, cnt, len;
+       u32 data;
        int ret, i;
 
-       for (i = 0; i < dp->outp.ior->dp.nr; i++) {
+       for (i = 0; i < ior->dp.nr; i++) {
                u8 lane = (lt->stat[4 + (i >> 1)] >> ((i & 1) * 4)) & 0xf;
                u8 lpc2 = (lt->pc2stat >> (i * 2)) & 0x3;
                u8 lpre = (lane & 0x0c) >> 2;
@@ -99,7 +105,21 @@ nvkm_dp_train_drive(struct lt_state *lt, bool pc)
 
                OUTP_TRACE(&dp->outp, "config lane %d %02x %02x",
                           i, lt->conf[i], lpc2);
-               dp->func->drv_ctl(dp, i, lvsw & 3, lpre & 3, lpc2 & 3);
+
+               data = nvbios_dpout_match(bios, dp->outp.info.hasht,
+                                               dp->outp.info.hashm,
+                                         &ver, &hdr, &cnt, &len, &info);
+               if (!data)
+                       continue;
+
+               data = nvbios_dpcfg_match(bios, data, lpc2 & 3, lvsw & 3,
+                                         lpre & 3, &ver, &hdr, &cnt, &len,
+                                         &ocfg);
+               if (!data)
+                       continue;
+
+               ior->func->dp.drive(ior, i, ocfg.pc, ocfg.dc,
+                                           ocfg.pe, ocfg.tx_pu);
        }
 
        ret = nvkm_wraux(dp->aux, DPCD_LC03(0), lt->conf, 4);
index 2bda157984cef7f457cce228ba7505615108d653..21f20bc92ae42b81b1ab8d276ee190ae71d5fe13 100644 (file)
@@ -33,7 +33,6 @@ struct nvkm_dp {
 #define nvkm_output_dp nvkm_dp
 
 struct nvkm_output_dp_func {
-       int (*drv_ctl)(struct nvkm_output_dp *, int ln, int vs, int pe, int pc);
        void (*vcpi)(struct nvkm_output_dp *, int head, u8 start_slot,
                     u8 num_slots, u16 pbn, u16 aligned_pbn);
 };
@@ -51,7 +50,6 @@ int g94_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
 
 int gf119_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
                     struct nvkm_output **);
-int gf119_sor_dp_drv_ctl(struct nvkm_dp *, int, int, int, int);
 void gf119_sor_dp_vcpi(struct nvkm_dp *, int, u8, u8, u16, u16);
 
 int gm107_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
index f88875dc22b6ff67123ba6087dbe10d5634f6b39..3295a6a23fb838c603247ede4b39e65c01826087 100644 (file)
@@ -56,6 +56,8 @@ struct nvkm_ior_func {
                int (*links)(struct nvkm_ior *, struct nvkm_i2c_aux *);
                void (*power)(struct nvkm_ior *, int nr);
                void (*pattern)(struct nvkm_ior *, int pattern);
+               void (*drive)(struct nvkm_ior *, int ln, int pc,
+                             int dc, int pe, int tx_pu);
        } dp;
 };
 
@@ -86,10 +88,12 @@ void g94_sor_state(struct nvkm_ior *, struct nvkm_ior_state *);
 int g94_sor_dp_links(struct nvkm_ior *, struct nvkm_i2c_aux *);
 void g94_sor_dp_power(struct nvkm_ior *, int);
 void g94_sor_dp_pattern(struct nvkm_ior *, int);
+void g94_sor_dp_drive(struct nvkm_ior *, int, int, int, int, int);
 
 void gf119_sor_state(struct nvkm_ior *, struct nvkm_ior_state *);
 int gf119_sor_dp_links(struct nvkm_ior *, struct nvkm_i2c_aux *);
 void gf119_sor_dp_pattern(struct nvkm_ior *, int);
+void gf119_sor_dp_drive(struct nvkm_ior *, int, int, int, int, int);
 
 void gm107_sor_dp_pattern(struct nvkm_ior *, int);
 
index e48251c378227e219311fc1f44894bc639db9119..80d4a0d34f142f21c09f22ee2a57000da2ebf2ff 100644 (file)
@@ -47,8 +47,6 @@ int nv50_sor_output_new(struct nvkm_disp *, int, struct dcb_output *,
 int nv50_pior_output_new(struct nvkm_disp *, int, struct dcb_output *,
                         struct nvkm_output **);
 
-u32 g94_sor_dp_lane_map(struct nvkm_device *, u8 lane);
-
 void gm200_sor_magic(struct nvkm_output *outp);
 
 #define OUTP_MSG(o,l,f,a...) do {                                              \
index 5b45c3ee4e5954dcfa11fbd9483ce2855ab095eb..a4a4749d3c4b7ed93b0d7c3af92ddafadf3caf4c 100644 (file)
 
 #include <subdev/timer.h>
 
-static inline u32
-g94_sor_soff(struct nvkm_output_dp *outp)
-{
-       return (ffs(outp->base.info.or) - 1) * 0x800;
-}
-
-static inline u32
-g94_sor_loff(struct nvkm_output_dp *outp)
-{
-       return g94_sor_soff(outp) + !(outp->base.info.sorconf.link & 1) * 0x80;
-}
-
-/*******************************************************************************
- * DisplayPort
- ******************************************************************************/
-u32
-g94_sor_dp_lane_map(struct nvkm_device *device, u8 lane)
-{
-       return nvkm_ior_find(device->disp, SOR, -1)->func->dp.lanes[lane] * 8;
-}
-
-static int
-g94_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc)
+void
+g94_sor_dp_drive(struct nvkm_ior *sor, int ln, int pc, int dc, int pe, int pu)
 {
-       struct nvkm_device *device = outp->base.disp->engine.subdev.device;
-       struct nvkm_bios *bios = device->bios;
-       const u32 shift = g94_sor_dp_lane_map(device, ln);
-       const u32 loff = g94_sor_loff(outp);
-       u32 addr, data[3];
-       u8  ver, hdr, cnt, len;
-       struct nvbios_dpout info;
-       struct nvbios_dpcfg ocfg;
-
-       addr = nvbios_dpout_match(bios, outp->base.info.hasht,
-                                       outp->base.info.hashm,
-                                 &ver, &hdr, &cnt, &len, &info);
-       if (!addr)
-               return -ENODEV;
-
-       addr = nvbios_dpcfg_match(bios, addr, 0, vs, pe,
-                                 &ver, &hdr, &cnt, &len, &ocfg);
-       if (!addr)
-               return -EINVAL;
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32  loff = nv50_sor_link(sor);
+       const u32 shift = sor->func->dp.lanes[ln] * 8;
+       u32 data[3];
 
        data[0] = nvkm_rd32(device, 0x61c118 + loff) & ~(0x000000ff << shift);
        data[1] = nvkm_rd32(device, 0x61c120 + loff) & ~(0x000000ff << shift);
        data[2] = nvkm_rd32(device, 0x61c130 + loff);
-       if ((data[2] & 0x0000ff00) < (ocfg.tx_pu << 8) || ln == 0)
-               data[2] = (data[2] & ~0x0000ff00) | (ocfg.tx_pu << 8);
-       nvkm_wr32(device, 0x61c118 + loff, data[0] | (ocfg.dc << shift));
-       nvkm_wr32(device, 0x61c120 + loff, data[1] | (ocfg.pe << shift));
+       if ((data[2] & 0x0000ff00) < (pu << 8) || ln == 0)
+               data[2] = (data[2] & ~0x0000ff00) | (pu << 8);
+       nvkm_wr32(device, 0x61c118 + loff, data[0] | (dc << shift));
+       nvkm_wr32(device, 0x61c120 + loff, data[1] | (pe << shift));
        nvkm_wr32(device, 0x61c130 + loff, data[2]);
-       return 0;
 }
 
 void
@@ -130,7 +93,6 @@ g94_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
 
 static const struct nvkm_output_dp_func
 g94_sor_dp_func = {
-       .drv_ctl = g94_sor_dp_drv_ctl,
 };
 
 int
@@ -298,6 +260,7 @@ g94_sor = {
                .links = g94_sor_dp_links,
                .power = g94_sor_dp_power,
                .pattern = g94_sor_dp_pattern,
+               .drive = g94_sor_dp_drive,
        },
 };
 
index 60a269ed2e0d9206f21d172554285ced06a1f5c7..48091e15c973c2a31543799cccf5a577f6f2626e 100644 (file)
@@ -35,53 +35,24 @@ gf119_sor_dp_vcpi(struct nvkm_output_dp *outp, int head, u8 slot,
        nvkm_mask(device, 0x61658c + hoff, 0xffffffff, (aligned << 16) | pbn);
 }
 
-static inline u32
-gf119_sor_soff(struct nvkm_output_dp *outp)
-{
-       return (ffs(outp->base.info.or) - 1) * 0x800;
-}
-
-static inline u32
-gf119_sor_loff(struct nvkm_output_dp *outp)
-{
-       return gf119_sor_soff(outp) + !(outp->base.info.sorconf.link & 1) * 0x80;
-}
-
-int
-gf119_sor_dp_drv_ctl(struct nvkm_output_dp *outp,
-                    int ln, int vs, int pe, int pc)
+void
+gf119_sor_dp_drive(struct nvkm_ior *sor, int ln, int pc, int dc, int pe, int pu)
 {
-       struct nvkm_device *device = outp->base.disp->engine.subdev.device;
-       struct nvkm_bios *bios = device->bios;
-       const u32 shift = g94_sor_dp_lane_map(device, ln);
-       const u32 loff = gf119_sor_loff(outp);
-       u32 addr, data[4];
-       u8  ver, hdr, cnt, len;
-       struct nvbios_dpout info;
-       struct nvbios_dpcfg ocfg;
-
-       addr = nvbios_dpout_match(bios, outp->base.info.hasht,
-                                       outp->base.info.hashm,
-                                 &ver, &hdr, &cnt, &len, &info);
-       if (!addr)
-               return -ENODEV;
-
-       addr = nvbios_dpcfg_match(bios, addr, pc, vs, pe,
-                                 &ver, &hdr, &cnt, &len, &ocfg);
-       if (!addr)
-               return -EINVAL;
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32  loff = nv50_sor_link(sor);
+       const u32 shift = sor->func->dp.lanes[ln] * 8;
+       u32 data[4];
 
        data[0] = nvkm_rd32(device, 0x61c118 + loff) & ~(0x000000ff << shift);
        data[1] = nvkm_rd32(device, 0x61c120 + loff) & ~(0x000000ff << shift);
        data[2] = nvkm_rd32(device, 0x61c130 + loff);
-       if ((data[2] & 0x0000ff00) < (ocfg.tx_pu << 8) || ln == 0)
-               data[2] = (data[2] & ~0x0000ff00) | (ocfg.tx_pu << 8);
-       nvkm_wr32(device, 0x61c118 + loff, data[0] | (ocfg.dc << shift));
-       nvkm_wr32(device, 0x61c120 + loff, data[1] | (ocfg.pe << shift));
+       if ((data[2] & 0x0000ff00) < (pu << 8) || ln == 0)
+               data[2] = (data[2] & ~0x0000ff00) | (pu << 8);
+       nvkm_wr32(device, 0x61c118 + loff, data[0] | (dc << shift));
+       nvkm_wr32(device, 0x61c120 + loff, data[1] | (pe << shift));
        nvkm_wr32(device, 0x61c130 + loff, data[2]);
        data[3] = nvkm_rd32(device, 0x61c13c + loff) & ~(0x000000ff << shift);
-       nvkm_wr32(device, 0x61c13c + loff, data[3] | (ocfg.pc << shift));
-       return 0;
+       nvkm_wr32(device, 0x61c13c + loff, data[3] | (pc << shift));
 }
 
 void
@@ -115,7 +86,6 @@ gf119_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
 
 static const struct nvkm_output_dp_func
 gf119_sor_dp_func = {
-       .drv_ctl = gf119_sor_dp_drv_ctl,
        .vcpi = gf119_sor_dp_vcpi,
 };
 
index fc6ac2ee25a5ad52a33a51fc9756009d39ff44ac..55a5a56b3723e09a957c8b90d1994c8db33398e1 100644 (file)
@@ -33,6 +33,7 @@ gk104_sor = {
                .links = gf119_sor_dp_links,
                .power = g94_sor_dp_power,
                .pattern = gf119_sor_dp_pattern,
+               .drive = gf119_sor_dp_drive,
        },
 };
 
index ae82f595f4595b82f0527a011f45bb27980be7b5..40c7eff35a9398eeda51b6f4fd3c9c519ee4119d 100644 (file)
@@ -38,7 +38,6 @@ gm107_sor_dp_pattern(struct nvkm_ior *sor, int pattern)
 
 static const struct nvkm_output_dp_func
 gm107_sor_dp_func = {
-       .drv_ctl = gf119_sor_dp_drv_ctl,
        .vcpi = gf119_sor_dp_vcpi,
 };
 
@@ -61,6 +60,7 @@ gm107_sor = {
                .links = gf119_sor_dp_links,
                .power = g94_sor_dp_power,
                .pattern = gm107_sor_dp_pattern,
+               .drive = gf119_sor_dp_drive,
        },
 };
 
index 2d32bcc8aa8a774598302bac226da0bfa08a6a35..5efec0f480fa3e6e557027e721be41e80843d6a3 100644 (file)
 #include "ior.h"
 #include "nv50.h"
 
-static inline u32
-gm200_sor_soff(struct nvkm_output_dp *outp)
+static void
+gm200_sor_dp_drive(struct nvkm_ior *sor, int ln, int pc, int dc, int pe, int pu)
 {
-       return (ffs(outp->base.info.or) - 1) * 0x800;
-}
-
-static inline u32
-gm200_sor_loff(struct nvkm_output_dp *outp)
-{
-       return gm200_sor_soff(outp) + !(outp->base.info.sorconf.link & 1) * 0x80;
-}
-
-static inline u32
-gm200_sor_dp_lane_map(struct nvkm_device *device, u8 lane)
-{
-       return nvkm_ior_find(device->disp, SOR, -1)->func->dp.lanes[lane] * 8;
-}
-
-static int
-gm200_sor_dp_drv_ctl(struct nvkm_output_dp *outp,
-                    int ln, int vs, int pe, int pc)
-{
-       struct nvkm_device *device = outp->base.disp->engine.subdev.device;
-       struct nvkm_bios *bios = device->bios;
-       const u32 shift = gm200_sor_dp_lane_map(device, ln);
-       const u32 loff = gm200_sor_loff(outp);
-       u32 addr, data[4];
-       u8  ver, hdr, cnt, len;
-       struct nvbios_dpout info;
-       struct nvbios_dpcfg ocfg;
-
-       addr = nvbios_dpout_match(bios, outp->base.info.hasht,
-                                       outp->base.info.hashm,
-                                 &ver, &hdr, &cnt, &len, &info);
-       if (!addr)
-               return -ENODEV;
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32  loff = nv50_sor_link(sor);
+       const u32 shift = sor->func->dp.lanes[ln] * 8;
+       u32 data[4];
 
-       addr = nvbios_dpcfg_match(bios, addr, pc, vs, pe,
-                                 &ver, &hdr, &cnt, &len, &ocfg);
-       if (!addr)
-               return -EINVAL;
-       ocfg.tx_pu &= 0x0f;
+       pu &= 0x0f;
 
        data[0] = nvkm_rd32(device, 0x61c118 + loff) & ~(0x000000ff << shift);
        data[1] = nvkm_rd32(device, 0x61c120 + loff) & ~(0x000000ff << shift);
        data[2] = nvkm_rd32(device, 0x61c130 + loff);
-       if ((data[2] & 0x00000f00) < (ocfg.tx_pu << 8) || ln == 0)
-               data[2] = (data[2] & ~0x00000f00) | (ocfg.tx_pu << 8);
-       nvkm_wr32(device, 0x61c118 + loff, data[0] | (ocfg.dc << shift));
-       nvkm_wr32(device, 0x61c120 + loff, data[1] | (ocfg.pe << shift));
+       if ((data[2] & 0x00000f00) < (pu << 8) || ln == 0)
+               data[2] = (data[2] & ~0x00000f00) | (pu << 8);
+       nvkm_wr32(device, 0x61c118 + loff, data[0] | (dc << shift));
+       nvkm_wr32(device, 0x61c120 + loff, data[1] | (pe << shift));
        nvkm_wr32(device, 0x61c130 + loff, data[2]);
        data[3] = nvkm_rd32(device, 0x61c13c + loff) & ~(0x000000ff << shift);
-       nvkm_wr32(device, 0x61c13c + loff, data[3] | (ocfg.pc << shift));
-       return 0;
+       nvkm_wr32(device, 0x61c13c + loff, data[3] | (pc << shift));
 }
 
 static const struct nvkm_output_dp_func
 gm200_sor_dp_func = {
-       .drv_ctl = gm200_sor_dp_drv_ctl,
        .vcpi = gf119_sor_dp_vcpi,
 };
 
@@ -117,6 +82,7 @@ gm200_sor = {
                .links = gf119_sor_dp_links,
                .power = g94_sor_dp_power,
                .pattern = gm107_sor_dp_pattern,
+               .drive = gm200_sor_dp_drive,
        },
 };
 
index 7dc8393a22b696427e0f4cc8f485570b27cb822f..eb084102baffa4849a91fc591bf6ce4939cae34d 100644 (file)
@@ -33,6 +33,7 @@ gt215_sor = {
                .links = g94_sor_dp_links,
                .power = g94_sor_dp_power,
                .pattern = g94_sor_dp_pattern,
+               .drive = g94_sor_dp_drive,
        },
 };
 
index 737aa7bf07a69e0db1fcca45a40c102792e0bf66..50d6c0d98e2005e7b04606ba7ab6335e24465e7a 100644 (file)
@@ -33,6 +33,7 @@ mcp77_sor = {
                .links = g94_sor_dp_links,
                .power = g94_sor_dp_power,
                .pattern = g94_sor_dp_pattern,
+               .drive = g94_sor_dp_drive,
        },
 };
 
index 2719d305c8cfbd2131c6c21ac3e7b84f49fc3dd6..385c4d13c58ec411c1223d48aa56b1874e3cde49 100644 (file)
@@ -33,6 +33,7 @@ mcp89_sor = {
                .links = g94_sor_dp_links,
                .power = g94_sor_dp_power,
                .pattern = g94_sor_dp_pattern,
+               .drive = g94_sor_dp_drive,
        },
 };