summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nvkm/engine/disp
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2017-05-19 23:59:35 +1000
committerBen Skeggs <bskeggs@redhat.com>2017-06-16 14:04:53 +1000
commit29c0ca7389ce8e259516d14397890bfe0ab462c8 (patch)
tree70bd9db7abef9bd8aa454d8d08823669e190bb9e /drivers/gpu/drm/nouveau/nvkm/engine/disp
parent3607bfd398204ddb11f63c09b1cc608adf85f96c (diff)
downloadlinux-stable-29c0ca7389ce8e259516d14397890bfe0ab462c8.tar.gz
linux-stable-29c0ca7389ce8e259516d14397890bfe0ab462c8.tar.bz2
linux-stable-29c0ca7389ce8e259516d14397890bfe0ab462c8.zip
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 <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine/disp')
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c18
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c20
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c24
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c24
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c22
17 files changed, 165 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c
index 03a5bace661b..546fb6c99ab1 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 5e2dbd5de511..6598252888ee 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 2ffbb995f134..a030a2820709 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 fd33eed68a2e..ef9d23a3b77b 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 21bdf301d37e..99a94a65b1a3 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 fe7ef0abef6e..0b1ea0b9394d 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 f81ba52c8c19..73ec6d4ae554 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 427e04c602e8..5b467f0ca36c 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 87b097327e29..89dd16590470 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 6ad8af038eae..56ff9d92b14e 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 a1946eca85ed..e1d1fd25720b 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 590d66002c58..96317c461b3c 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 df3917cb1cb9..cc4bea30bb9b 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 dc209826156e..87d1c9ce4e7f 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 09d42240510a..78ddffab7a93 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 f8fba6caad33..97433c17db71 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 fb43307466cd..a1327e8fead1 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