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>
This commit is contained in:
parent
3607bfd398
commit
29c0ca7389
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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); \
|
||||
|
|
|
@ -678,6 +678,23 @@ nv50_disp_intr_unk10_0(struct nv50_disp *disp, int head)
|
|||
exec_script(disp, head, 1);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
static const struct nvkm_ior_func
|
||||
g84_sor = {
|
||||
.state = nv50_sor_state,
|
||||
};
|
||||
|
||||
int
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
static const struct nvkm_ior_func
|
||||
gk104_sor = {
|
||||
.state = gf119_sor_state,
|
||||
};
|
||||
|
||||
int
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -132,6 +132,7 @@ gm200_sor_magic(struct nvkm_output *outp)
|
|||
|
||||
static const struct nvkm_ior_func
|
||||
gm200_sor = {
|
||||
.state = gf119_sor_state,
|
||||
};
|
||||
|
||||
int
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
static const struct nvkm_ior_func
|
||||
gt215_sor = {
|
||||
.state = g94_sor_state,
|
||||
};
|
||||
|
||||
int
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
static const struct nvkm_ior_func
|
||||
mcp77_sor = {
|
||||
.state = g94_sor_state,
|
||||
};
|
||||
|
||||
int
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
static const struct nvkm_ior_func
|
||||
mcp89_sor = {
|
||||
.state = g94_sor_state,
|
||||
};
|
||||
|
||||
int
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue