drm/nouveau/disp/nv50-: fetch head/OR state at beginning of supervisor
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:53 +0000 (14:04 +1000)
This data will be used by essentially every part of the supervisor
handling process.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
17 files changed:
drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c
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
drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c

index 03a5bac..546fb6c 100644 (file)
  */
 #include "ior.h"
 
+static void
+gf119_dac_state(struct nvkm_ior *dac, struct nvkm_ior_state *state)
+{
+       struct nvkm_device *device = dac->disp->engine.subdev.device;
+       const u32 coff = (state == &dac->asy) * 0x20000 + dac->id * 0x20;
+       u32 ctrl = nvkm_rd32(device, 0x640180 + coff);
+
+       state->proto_evo = (ctrl & 0x00000f00) >> 8;
+       switch (state->proto_evo) {
+       case 0: state->proto = CRT; break;
+       default:
+               state->proto = UNKNOWN;
+               break;
+       }
+
+       state->head = ctrl & 0x0000000f;
+}
+
 static const struct nvkm_ior_func
 gf119_dac = {
+       .state = gf119_dac_state,
 };
 
 int
index 5e2dbd5..6598252 100644 (file)
@@ -126,8 +126,27 @@ nv50_dac_power(NV50_DISP_MTHD_V1)
        return 0;
 }
 
+static void
+nv50_dac_state(struct nvkm_ior *dac, struct nvkm_ior_state *state)
+{
+       struct nvkm_device *device = dac->disp->engine.subdev.device;
+       const u32 coff = dac->id * 8 + (state == &dac->arm) * 4;
+       u32 ctrl = nvkm_rd32(device, 0x610b58 + coff);
+
+       state->proto_evo = (ctrl & 0x00000f00) >> 8;
+       switch (state->proto_evo) {
+       case 0: state->proto = CRT; break;
+       default:
+               state->proto = UNKNOWN;
+               break;
+       }
+
+       state->head = ctrl & 0x00000003;
+}
+
 static const struct nvkm_ior_func
 nv50_dac = {
+       .state = nv50_dac_state,
 };
 
 int
index 2ffbb99..a030a28 100644 (file)
@@ -362,6 +362,7 @@ gf119_disp_super(struct work_struct *work)
 
        if (disp->super & 0x00000001) {
                nv50_disp_chan_mthd(disp->chan[0], NV_DBG_DEBUG);
+               nv50_disp_super_1(disp);
                list_for_each_entry(head, &disp->base.head, head) {
                        if (!(mask[head->id] & 0x00001000))
                                continue;
index fd33eed..ef9d23a 100644 (file)
@@ -16,6 +16,8 @@ struct nvkm_ior {
        struct list_head head;
 
        struct nvkm_ior_state {
+               unsigned rgdiv;
+               unsigned proto_evo:4;
                enum nvkm_ior_proto {
                        CRT,
                        TMDS,
@@ -23,6 +25,8 @@ struct nvkm_ior {
                        DP,
                        UNKNOWN
                } proto:3;
+               unsigned link:2;
+               unsigned head:4;
        } arm, asy;
 
        /* Armed DP state. */
@@ -35,6 +39,7 @@ struct nvkm_ior {
 };
 
 struct nvkm_ior_func {
+       void (*state)(struct nvkm_ior *, struct nvkm_ior_state *);
 };
 
 int nvkm_ior_new_(const struct nvkm_ior_func *func, struct nvkm_disp *,
@@ -42,6 +47,10 @@ int nvkm_ior_new_(const struct nvkm_ior_func *func, struct nvkm_disp *,
 void nvkm_ior_del(struct nvkm_ior **);
 struct nvkm_ior *nvkm_ior_find(struct nvkm_disp *, enum nvkm_ior_type, int id);
 
+void nv50_sor_state(struct nvkm_ior *, struct nvkm_ior_state *);
+void g94_sor_state(struct nvkm_ior *, struct nvkm_ior_state *);
+void gf119_sor_state(struct nvkm_ior *, struct nvkm_ior_state *);
+
 #define IOR_MSG(i,l,f,a...) do {                                               \
        struct nvkm_ior *_ior = (i);                                           \
        nvkm_##l(&_ior->disp->engine.subdev, "%s: "f, _ior->name, ##a);        \
index 21bdf30..99a94a6 100644 (file)
@@ -679,6 +679,23 @@ nv50_disp_intr_unk10_0(struct nv50_disp *disp, int head)
 }
 
 void
+nv50_disp_super_1(struct nv50_disp *disp)
+{
+       struct nvkm_head *head;
+       struct nvkm_ior *ior;
+
+       list_for_each_entry(head, &disp->base.head, head) {
+               head->func->state(head, &head->arm);
+               head->func->state(head, &head->asy);
+       }
+
+       list_for_each_entry(ior, &disp->base.ior, head) {
+               ior->func->state(ior, &ior->arm);
+               ior->func->state(ior, &ior->asy);
+       }
+}
+
+void
 nv50_disp_super(struct work_struct *work)
 {
        struct nv50_disp *disp =
@@ -692,6 +709,7 @@ nv50_disp_super(struct work_struct *work)
 
        if (disp->super & 0x00000010) {
                nv50_disp_chan_mthd(disp->chan[0], NV_DBG_DEBUG);
+               nv50_disp_super_1(disp);
                list_for_each_entry(head, &disp->base.head, head) {
                        if (!(super & (0x00000020 << head->id)))
                                continue;
index fe7ef0a..0b1ea0b 100644 (file)
@@ -29,6 +29,8 @@ struct nv50_disp {
        struct nv50_disp_chan *chan[17];
 };
 
+void nv50_disp_super_1(struct nv50_disp *);
+
 int nv50_dac_power(NV50_DISP_MTHD_V1);
 int nv50_dac_sense(NV50_DISP_MTHD_V1);
 
index f81ba52..73ec6d4 100644 (file)
@@ -121,8 +121,28 @@ nv50_pior_power(NV50_DISP_MTHD_V1)
        return 0;
 }
 
+static void
+nv50_pior_state(struct nvkm_ior *pior, struct nvkm_ior_state *state)
+{
+       struct nvkm_device *device = pior->disp->engine.subdev.device;
+       const u32 coff = pior->id * 8 + (state == &pior->arm) * 4;
+       u32 ctrl = nvkm_rd32(device, 0x610b80 + coff);
+
+       state->proto_evo = (ctrl & 0x00000f00) >> 8;
+       state->rgdiv = 1;
+       switch (state->proto_evo) {
+       case 0: state->proto = TMDS; break;
+       default:
+               state->proto = UNKNOWN;
+               break;
+       }
+
+       state->head = ctrl & 0x00000003;
+}
+
 static const struct nvkm_ior_func
 nv50_pior = {
+       .state = nv50_pior_state,
 };
 
 int
index 427e04c..5b467f0 100644 (file)
@@ -23,6 +23,7 @@
 
 static const struct nvkm_ior_func
 g84_sor = {
+       .state = nv50_sor_state,
 };
 
 int
index 87b0973..89dd165 100644 (file)
@@ -278,8 +278,32 @@ nv50_disp_dptmds_war_2(struct nv50_disp *disp, struct dcb_output *outp)
        }
 }
 
+void
+g94_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 coff = sor->id * 8 + (state == &sor->arm) * 4;
+       u32 ctrl = nvkm_rd32(device, 0x610794 + coff);
+
+       state->proto_evo = (ctrl & 0x00000f00) >> 8;
+       switch (state->proto_evo) {
+       case 0: state->proto = LVDS; state->link = 1; break;
+       case 1: state->proto = TMDS; state->link = 1; break;
+       case 2: state->proto = TMDS; state->link = 2; break;
+       case 5: state->proto = TMDS; state->link = 3; break;
+       case 8: state->proto =   DP; state->link = 1; break;
+       case 9: state->proto =   DP; state->link = 2; break;
+       default:
+               state->proto = UNKNOWN;
+               break;
+       }
+
+       state->head = ctrl & 0x00000003;
+}
+
 static const struct nvkm_ior_func
 g94_sor = {
+       .state = g94_sor_state,
 };
 
 int
index 6ad8af0..56ff9d9 100644 (file)
@@ -130,8 +130,32 @@ gf119_sor_dp_new(struct nvkm_disp *disp, int index,
        return nvkm_output_dp_new_(&gf119_sor_dp_func, disp, index, dcbE, poutp);
 }
 
+void
+gf119_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 coff = (state == &sor->asy) * 0x20000 + sor->id * 0x20;
+       u32 ctrl = nvkm_rd32(device, 0x640200 + coff);
+
+       state->proto_evo = (ctrl & 0x00000f00) >> 8;
+       switch (state->proto_evo) {
+       case 0: state->proto = LVDS; state->link = 1; break;
+       case 1: state->proto = TMDS; state->link = 1; break;
+       case 2: state->proto = TMDS; state->link = 2; break;
+       case 5: state->proto = TMDS; state->link = 3; break;
+       case 8: state->proto =   DP; state->link = 1; break;
+       case 9: state->proto =   DP; state->link = 2; break;
+       default:
+               state->proto = UNKNOWN;
+               break;
+       }
+
+       state->head = ctrl & 0x0000000f;
+}
+
 static const struct nvkm_ior_func
 gf119_sor = {
+       .state = gf119_sor_state,
 };
 
 int
index a1946ec..e1d1fd2 100644 (file)
@@ -23,6 +23,7 @@
 
 static const struct nvkm_ior_func
 gk104_sor = {
+       .state = gf119_sor_state,
 };
 
 int
index 590d660..96317c4 100644 (file)
@@ -55,6 +55,7 @@ gm107_sor_dp_new(struct nvkm_disp *disp, int index,
 
 static const struct nvkm_ior_func
 gm107_sor = {
+       .state = gf119_sor_state,
 };
 
 int
index df3917c..cc4bea3 100644 (file)
@@ -132,6 +132,7 @@ gm200_sor_magic(struct nvkm_output *outp)
 
 static const struct nvkm_ior_func
 gm200_sor = {
+       .state = gf119_sor_state,
 };
 
 int
index dc20982..87d1c9c 100644 (file)
@@ -23,6 +23,7 @@
 
 static const struct nvkm_ior_func
 gt215_sor = {
+       .state = g94_sor_state,
 };
 
 int
index 09d4224..78ddffa 100644 (file)
@@ -23,6 +23,7 @@
 
 static const struct nvkm_ior_func
 mcp77_sor = {
+       .state = g94_sor_state,
 };
 
 int
index f8fba6c..97433c1 100644 (file)
@@ -23,6 +23,7 @@
 
 static const struct nvkm_ior_func
 mcp89_sor = {
+       .state = g94_sor_state,
 };
 
 int
index fb43307..a1327e8 100644 (file)
@@ -79,8 +79,30 @@ nv50_sor_power(NV50_DISP_MTHD_V1)
        return 0;
 }
 
+void
+nv50_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
+{
+       struct nvkm_device *device = sor->disp->engine.subdev.device;
+       const u32 coff = sor->id * 8 + (state == &sor->arm) * 4;
+       u32 ctrl = nvkm_rd32(device, 0x610b70 + coff);
+
+       state->proto_evo = (ctrl & 0x00000f00) >> 8;
+       switch (state->proto_evo) {
+       case 0: state->proto = LVDS; state->link = 1; break;
+       case 1: state->proto = TMDS; state->link = 1; break;
+       case 2: state->proto = TMDS; state->link = 2; break;
+       case 5: state->proto = TMDS; state->link = 3; break;
+       default:
+               state->proto = UNKNOWN;
+               break;
+       }
+
+       state->head = ctrl & 0x00000003;
+}
+
 static const struct nvkm_ior_func
 nv50_sor = {
+       .state = nv50_sor_state,
 };
 
 int