From 29c0ca7389ce8e259516d14397890bfe0ab462c8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 19 May 2017 23:59:35 +1000 Subject: [PATCH] drm/nouveau/disp/nv50-: fetch head/OR state at beginning of supervisor This data will be used by essentially every part of the supervisor handling process. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c | 19 +++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c | 19 +++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h | 9 ++++++++ drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c | 18 ++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h | 2 ++ .../gpu/drm/nouveau/nvkm/engine/disp/piornv50.c | 20 ++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c | 24 ++++++++++++++++++++++ .../gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c | 24 ++++++++++++++++++++++ .../gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c | 1 + .../gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c | 1 + .../gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c | 1 + .../gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c | 1 + .../gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c | 1 + .../gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c | 22 ++++++++++++++++++++ 17 files changed, 165 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c index 03a5bac..546fb6c9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c @@ -21,8 +21,27 @@ */ #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 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c index 5e2dbd5..6598252 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c @@ -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 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c index 2ffbb99..a030a28 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c @@ -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; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h index fd33eed6..ef9d23a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h @@ -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); \ diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c index 21bdf30..99a94a6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c @@ -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; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h index fe7ef0a..0b1ea0b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h @@ -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); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c index f81ba52..73ec6d4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c @@ -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 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c index 427e04c..5b467f0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c @@ -23,6 +23,7 @@ static const struct nvkm_ior_func g84_sor = { + .state = nv50_sor_state, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c index 87b0973..89dd165 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c @@ -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 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c index 6ad8af0..56ff9d9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c @@ -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 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c index a1946ec..e1d1fd2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c @@ -23,6 +23,7 @@ static const struct nvkm_ior_func gk104_sor = { + .state = gf119_sor_state, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c index 590d660..96317c4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c @@ -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 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c index df3917c..cc4bea3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c @@ -132,6 +132,7 @@ gm200_sor_magic(struct nvkm_output *outp) static const struct nvkm_ior_func gm200_sor = { + .state = gf119_sor_state, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c index dc20982..87d1c9c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c @@ -23,6 +23,7 @@ static const struct nvkm_ior_func gt215_sor = { + .state = g94_sor_state, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c index 09d4224..78ddffa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c @@ -23,6 +23,7 @@ static const struct nvkm_ior_func mcp77_sor = { + .state = g94_sor_state, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c index f8fba6c..97433c1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c @@ -23,6 +23,7 @@ static const struct nvkm_ior_func mcp89_sor = { + .state = g94_sor_state, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c index fb43307..a1327e8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c @@ -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 -- 2.7.4