diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine')
30 files changed, 106 insertions, 158 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c index 546fb6c99ab1..2ef07c0fcc2d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacgf119.c @@ -42,6 +42,7 @@ gf119_dac_state(struct nvkm_ior *dac, struct nvkm_ior_state *state) static const struct nvkm_ior_func gf119_dac = { .state = gf119_dac_state, + .power = nv50_dac_power, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c index 6598252888ee..48fbf8c34a53 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c @@ -90,40 +90,31 @@ nv50_dac_sense(NV50_DISP_MTHD_V1) return 0; } -int -nv50_dac_power(NV50_DISP_MTHD_V1) +static void +nv50_dac_power_wait(struct nvkm_device *device, const u32 doff) { - struct nvkm_device *device = disp->base.engine.subdev.device; - const u32 doff = outp->or * 0x800; - union { - struct nv50_disp_dac_pwr_v0 v0; - } *args = data; - u32 stat; - int ret = -ENOSYS; - - nvif_ioctl(object, "disp dac pwr size %d\n", size); - if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { - nvif_ioctl(object, "disp dac pwr vers %d state %d data %d " - "vsync %d hsync %d\n", - args->v0.version, args->v0.state, args->v0.data, - args->v0.vsync, args->v0.hsync); - stat = 0x00000040 * !args->v0.state; - stat |= 0x00000010 * !args->v0.data; - stat |= 0x00000004 * !args->v0.vsync; - stat |= 0x00000001 * !args->v0.hsync; - } else - return ret; - - nvkm_msec(device, 2000, - if (!(nvkm_rd32(device, 0x61a004 + doff) & 0x80000000)) - break; - ); - nvkm_mask(device, 0x61a004 + doff, 0xc000007f, 0x80000000 | stat); nvkm_msec(device, 2000, if (!(nvkm_rd32(device, 0x61a004 + doff) & 0x80000000)) break; ); - return 0; +} + +void +nv50_dac_power(struct nvkm_ior *dac, bool normal, bool pu, + bool data, bool vsync, bool hsync) +{ + struct nvkm_device *device = dac->disp->engine.subdev.device; + const u32 doff = nv50_ior_base(dac); + const u32 shift = normal ? 0 : 16; + const u32 state = 0x80000000 | (0x00000040 * ! pu | + 0x00000010 * ! data | + 0x00000004 * ! vsync | + 0x00000001 * ! hsync) << shift; + const u32 field = 0xc0000000 | (0x00000055 << shift); + + nv50_dac_power_wait(device, doff); + nvkm_mask(device, 0x61a004 + doff, field, state); + nv50_dac_power_wait(device, doff); } static void @@ -147,6 +138,7 @@ nv50_dac_state(struct nvkm_ior *dac, struct nvkm_ior_state *state) static const struct nvkm_ior_func nv50_dac = { .state = nv50_dac_state, + .power = nv50_dac_power, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c index dc2a602718cc..aa713b24a606 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c @@ -40,15 +40,11 @@ g84_disp = { .outp.external.dp = nv50_pior_dp_new, .dac.nr = 3, .dac.new = nv50_dac_new, - .dac.power = nv50_dac_power, .dac.sense = nv50_dac_sense, .sor.nr = 2, .sor.new = g84_sor_new, - .sor.power = nv50_sor_power, .sor.hdmi = g84_hdmi_ctrl, - .pior.nr = 3, - .pior.new = nv50_pior_new, - .pior.power = nv50_pior_power, + .pior = { .nr = 3, .new = nv50_pior_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c index 4a959de0d616..5c6c8640bab1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c @@ -41,15 +41,11 @@ g94_disp = { .outp.external.dp = nv50_pior_dp_new, .dac.nr = 3, .dac.new = nv50_dac_new, - .dac.power = nv50_dac_power, .dac.sense = nv50_dac_sense, .sor.nr = 4, .sor.new = g94_sor_new, - .sor.power = nv50_sor_power, .sor.hdmi = g84_hdmi_ctrl, - .pior.nr = 3, - .pior.new = nv50_pior_new, - .pior.power = nv50_pior_power, + .pior = { .nr = 3, .new = nv50_pior_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c index a030a2820709..05fdbdb1df50 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c @@ -508,11 +508,9 @@ gf119_disp = { .outp.internal.dp = gf119_sor_dp_new, .dac.nr = 3, .dac.new = gf119_dac_new, - .dac.power = nv50_dac_power, .dac.sense = nv50_dac_sense, .sor.nr = 4, .sor.new = gf119_sor_new, - .sor.power = nv50_sor_power, .sor.hda_eld = gf119_hda_eld, .sor.hdmi = gf119_hdmi_ctrl, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c index 3c3a327095fb..efbbbff0b93f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c @@ -40,11 +40,9 @@ gk104_disp = { .outp.internal.dp = gf119_sor_dp_new, .dac.nr = 3, .dac.new = gf119_dac_new, - .dac.power = nv50_dac_power, .dac.sense = nv50_dac_sense, .sor.nr = 4, .sor.new = gk104_sor_new, - .sor.power = nv50_sor_power, .sor.hda_eld = gf119_hda_eld, .sor.hdmi = gk104_hdmi_ctrl, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c index 84f774ae5f7e..bca825373dc1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c @@ -40,11 +40,9 @@ gk110_disp = { .outp.internal.dp = gf119_sor_dp_new, .dac.nr = 3, .dac.new = gf119_dac_new, - .dac.power = nv50_dac_power, .dac.sense = nv50_dac_sense, .sor.nr = 4, .sor.new = gk104_sor_new, - .sor.power = nv50_sor_power, .sor.hda_eld = gf119_hda_eld, .sor.hdmi = gk104_hdmi_ctrl, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c index 4e43fcdc2c7c..90fc36e96335 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c @@ -40,11 +40,9 @@ gm107_disp = { .outp.internal.dp = gm107_sor_dp_new, .dac.nr = 3, .dac.new = gf119_dac_new, - .dac.power = nv50_dac_power, .dac.sense = nv50_dac_sense, .sor.nr = 4, .sor.new = gm107_sor_new, - .sor.power = nv50_sor_power, .sor.hda_eld = gf119_hda_eld, .sor.hdmi = gk104_hdmi_ctrl, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c index 90cdc95c71ed..2e0f81e75124 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c @@ -40,11 +40,9 @@ gm200_disp = { .outp.internal.dp = gm200_sor_dp_new, .dac.nr = 3, .dac.new = gf119_dac_new, - .dac.power = nv50_dac_power, .dac.sense = nv50_dac_sense, .sor.nr = 4, .sor.new = gm200_sor_new, - .sor.power = nv50_sor_power, .sor.hda_eld = gf119_hda_eld, .sor.hdmi = gk104_hdmi_ctrl, .sor.magic = gm200_sor_magic, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c index f7ba3366024a..4b6a60d646cc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c @@ -39,7 +39,6 @@ gp100_disp = { .outp.internal.dp = gm200_sor_dp_new, .sor.nr = 4, .sor.new = gm200_sor_new, - .sor.power = nv50_sor_power, .sor.hda_eld = gf119_hda_eld, .sor.hdmi = gk104_hdmi_ctrl, .sor.magic = gm200_sor_magic, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c index 80010f2c94b2..26f745bf4bef 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gp102.c @@ -65,7 +65,6 @@ gp102_disp = { .outp.internal.dp = gm200_sor_dp_new, .sor.nr = 4, .sor.new = gm200_sor_new, - .sor.power = nv50_sor_power, .sor.hda_eld = gf119_hda_eld, .sor.hdmi = gk104_hdmi_ctrl, .sor.magic = gm200_sor_magic, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c index 3e9399be4d86..a41909e8ab1f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c @@ -40,15 +40,11 @@ gt200_disp = { .outp.external.dp = nv50_pior_dp_new, .dac.nr = 3, .dac.new = nv50_dac_new, - .dac.power = nv50_dac_power, .dac.sense = nv50_dac_sense, .sor.nr = 2, .sor.new = g84_sor_new, - .sor.power = nv50_sor_power, .sor.hdmi = g84_hdmi_ctrl, - .pior.nr = 3, - .pior.new = nv50_pior_new, - .pior.power = nv50_pior_power, + .pior = { .nr = 3, .new = nv50_pior_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c index 7c7ad97a4849..230e43ded8eb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c @@ -41,16 +41,12 @@ gt215_disp = { .outp.external.dp = nv50_pior_dp_new, .dac.nr = 3, .dac.new = nv50_dac_new, - .dac.power = nv50_dac_power, .dac.sense = nv50_dac_sense, .sor.nr = 4, .sor.new = gt215_sor_new, - .sor.power = nv50_sor_power, .sor.hda_eld = gt215_hda_eld, .sor.hdmi = gt215_hdmi_ctrl, - .pior.nr = 3, - .pior.new = nv50_pior_new, - .pior.power = nv50_pior_power, + .pior = { .nr = 3, .new = nv50_pior_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h index ef9d23a3b77b..9dd526cfe2a2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h @@ -40,6 +40,8 @@ struct nvkm_ior { struct nvkm_ior_func { void (*state)(struct nvkm_ior *, struct nvkm_ior_state *); + void (*power)(struct nvkm_ior *, bool normal, bool pu, + bool data, bool vsync, bool hsync); }; int nvkm_ior_new_(const struct nvkm_ior_func *func, struct nvkm_disp *, @@ -47,7 +49,17 @@ 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); +static inline u32 +nv50_ior_base(struct nvkm_ior *ior) +{ + return ior->id * 0x800; +} + +void nv50_dac_power(struct nvkm_ior *, bool, bool, bool, bool, bool); + void nv50_sor_state(struct nvkm_ior *, struct nvkm_ior_state *); +void nv50_sor_power(struct nvkm_ior *, bool, bool, bool, bool, bool); + void g94_sor_state(struct nvkm_ior *, struct nvkm_ior_state *); void gf119_sor_state(struct nvkm_ior *, struct nvkm_ior_state *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c index f8710425ea54..ee8c2324a351 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c @@ -39,15 +39,11 @@ mcp77_disp = { .outp.external.dp = nv50_pior_dp_new, .dac.nr = 3, .dac.new = nv50_dac_new, - .dac.power = nv50_dac_power, .dac.sense = nv50_dac_sense, .sor.nr = 4, .sor.new = mcp77_sor_new, - .sor.power = nv50_sor_power, .sor.hdmi = g84_hdmi_ctrl, - .pior.nr = 3, - .pior.new = nv50_pior_new, - .pior.power = nv50_pior_power, + .pior = { .nr = 3, .new = nv50_pior_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c index e417d1dbe4ce..6dccb3d2c8dc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c @@ -39,16 +39,12 @@ mcp89_disp = { .outp.external.dp = nv50_pior_dp_new, .dac.nr = 3, .dac.new = nv50_dac_new, - .dac.power = nv50_dac_power, .dac.sense = nv50_dac_sense, .sor.nr = 4, .sor.new = mcp89_sor_new, - .sor.power = nv50_sor_power, .sor.hda_eld = gt215_hda_eld, .sor.hdmi = gt215_hdmi_ctrl, - .pior.nr = 3, - .pior.new = nv50_pior_new, - .pior.power = nv50_pior_power, + .pior = { .nr = 3, .new = nv50_pior_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c index 99a94a65b1a3..f8986299dc54 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c @@ -846,14 +846,9 @@ nv50_disp = { .outp.external.dp = nv50_pior_dp_new, .dac.nr = 3, .dac.new = nv50_dac_new, - .dac.power = nv50_dac_power, .dac.sense = nv50_dac_sense, - .sor.nr = 2, - .sor.new = nv50_sor_new, - .sor.power = nv50_sor_power, - .pior.nr = 3, - .pior.new = nv50_pior_new, - .pior.power = nv50_pior_power, + .sor = { .nr = 2, .new = nv50_sor_new }, + .pior = { .nr = 3, .new = nv50_pior_new }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h index 0b1ea0b9394d..66180585df2a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h @@ -31,7 +31,6 @@ struct nv50_disp { void nv50_disp_super_1(struct nv50_disp *); -int nv50_dac_power(NV50_DISP_MTHD_V1); int nv50_dac_sense(NV50_DISP_MTHD_V1); int gt215_hda_eld(NV50_DISP_MTHD_V1); @@ -42,9 +41,6 @@ int gt215_hdmi_ctrl(NV50_DISP_MTHD_V1); int gf119_hdmi_ctrl(NV50_DISP_MTHD_V1); int gk104_hdmi_ctrl(NV50_DISP_MTHD_V1); -int nv50_sor_power(NV50_DISP_MTHD_V1); -int nv50_pior_power(NV50_DISP_MTHD_V1); - int nv50_disp_new_(const struct nv50_disp_func *, struct nvkm_device *, int index, int heads, struct nvkm_disp **); int gf119_disp_new_(const struct nv50_disp_func *, struct nvkm_device *, @@ -84,14 +80,12 @@ struct nv50_disp_func { struct { int nr; int (*new)(struct nvkm_disp *, int id); - int (*power)(NV50_DISP_MTHD_V1); int (*sense)(NV50_DISP_MTHD_V1); } dac; struct { int nr; int (*new)(struct nvkm_disp *, int id); - int (*power)(NV50_DISP_MTHD_V1); int (*hda_eld)(NV50_DISP_MTHD_V1); int (*hdmi)(NV50_DISP_MTHD_V1); void (*magic)(struct nvkm_output *); @@ -100,7 +94,6 @@ struct nv50_disp_func { struct { int nr; int (*new)(struct nvkm_disp *, int id); - int (*power)(NV50_DISP_MTHD_V1); } pior; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c index 73ec6d4ae554..486050d4692e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c @@ -22,15 +22,11 @@ * Authors: Ben Skeggs */ #include "ior.h" -#include "nv50.h" +#include "dp.h" -#include <core/client.h> #include <subdev/i2c.h> #include <subdev/timer.h> -#include <nvif/cl5070.h> -#include <nvif/unpack.h> - /****************************************************************************** * TMDS *****************************************************************************/ @@ -86,39 +82,28 @@ nv50_pior_dp_new(struct nvkm_disp *disp, int index, struct dcb_output *dcbE, index, dcbE, poutp); } -int -nv50_pior_power(NV50_DISP_MTHD_V1) +static void +nv50_pior_power_wait(struct nvkm_device *device, u32 poff) { - struct nvkm_device *device = disp->base.engine.subdev.device; - const u32 soff = outp->or * 0x800; - union { - struct nv50_disp_pior_pwr_v0 v0; - } *args = data; - u32 ctrl, type; - int ret = -ENOSYS; - - nvif_ioctl(object, "disp pior pwr size %d\n", size); - if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { - nvif_ioctl(object, "disp pior pwr vers %d state %d type %x\n", - args->v0.version, args->v0.state, args->v0.type); - if (args->v0.type > 0x0f) - return -EINVAL; - ctrl = !!args->v0.state; - type = args->v0.type; - } else - return ret; - - nvkm_msec(device, 2000, - if (!(nvkm_rd32(device, 0x61e004 + soff) & 0x80000000)) - break; - ); - nvkm_mask(device, 0x61e004 + soff, 0x80000101, 0x80000000 | ctrl); nvkm_msec(device, 2000, - if (!(nvkm_rd32(device, 0x61e004 + soff) & 0x80000000)) + if (!(nvkm_rd32(device, 0x61e004 + poff) & 0x80000000)) break; ); - disp->pior.type[outp->or] = type; - return 0; +} + +static void +nv50_pior_power(struct nvkm_ior *pior, bool normal, bool pu, + bool data, bool vsync, bool hsync) +{ + struct nvkm_device *device = pior->disp->engine.subdev.device; + const u32 poff = nv50_ior_base(pior); + const u32 shift = normal ? 0 : 16; + const u32 state = 0x80000000 | (0x00000001 * !!pu) << shift; + const u32 field = 0x80000000 | (0x00000101 << shift); + + nv50_pior_power_wait(device, poff); + nvkm_mask(device, 0x61e004 + poff, field, state); + nv50_pior_power_wait(device, poff); } static void @@ -143,6 +128,7 @@ nv50_pior_state(struct nvkm_ior *pior, struct nvkm_ior_state *state) static const struct nvkm_ior_func nv50_pior = { .state = nv50_pior_state, + .power = nv50_pior_power, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c index 9cf1365f5261..3f02e37f30bb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c @@ -24,6 +24,7 @@ #include "rootnv50.h" #include "dmacnv50.h" #include "head.h" +#include "ior.h" #include <core/client.h> #include <core/ramht.h> @@ -94,12 +95,8 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size) } switch (mthd * !!outp) { - case NV50_DISP_MTHD_V1_DAC_PWR: - return func->dac.power(object, disp, data, size, hidx, outp); case NV50_DISP_MTHD_V1_DAC_LOAD: return func->dac.sense(object, disp, data, size, hidx, outp); - case NV50_DISP_MTHD_V1_SOR_PWR: - return func->sor.power(object, disp, data, size, hidx, outp); case NV50_DISP_MTHD_V1_SOR_HDA_ELD: if (!func->sor.hda_eld) return -ENODEV; @@ -163,10 +160,6 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size) return ret; } break; - case NV50_DISP_MTHD_V1_PIOR_PWR: - if (!func->pior.power) - return -ENODEV; - return func->pior.power(object, disp, data, size, hidx, outp); default: break; } @@ -231,7 +224,21 @@ static int nv50_disp_root_init_(struct nvkm_object *object) { struct nv50_disp_root *root = nv50_disp_root(object); - return root->func->init(root); + struct nvkm_ior *ior; + int ret; + + ret = root->func->init(root); + if (ret) + return ret; + + /* Set 'normal' (ie. when it's attached to a head) state for + * each output resource to 'fully enabled'. + */ + list_for_each_entry(ior, &root->disp->base.ior, head) { + ior->func->power(ior, true, true, true, true, true); + } + + return 0; } static void * diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c index 5b467f0ca36c..bb0f503ee989 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg84.c @@ -24,6 +24,7 @@ static const struct nvkm_ior_func g84_sor = { .state = nv50_sor_state, + .power = nv50_sor_power, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c index 89dd16590470..3175bb3031b5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c @@ -304,6 +304,7 @@ g94_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state) static const struct nvkm_ior_func g94_sor = { .state = g94_sor_state, + .power = nv50_sor_power, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c index 56ff9d92b14e..dcab72a52964 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c @@ -156,6 +156,7 @@ gf119_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state) static const struct nvkm_ior_func gf119_sor = { .state = gf119_sor_state, + .power = nv50_sor_power, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c index e1d1fd25720b..ac7a5944487a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgk104.c @@ -24,6 +24,7 @@ static const struct nvkm_ior_func gk104_sor = { .state = gf119_sor_state, + .power = nv50_sor_power, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c index 96317c461b3c..8bca4dca1e11 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c @@ -56,6 +56,7 @@ gm107_sor_dp_new(struct nvkm_disp *disp, int index, static const struct nvkm_ior_func gm107_sor = { .state = gf119_sor_state, + .power = nv50_sor_power, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c index cc4bea30bb9b..0a4b9b967904 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c @@ -133,6 +133,7 @@ gm200_sor_magic(struct nvkm_output *outp) static const struct nvkm_ior_func gm200_sor = { .state = gf119_sor_state, + .power = nv50_sor_power, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c index 87d1c9ce4e7f..bec04ad40494 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgt215.c @@ -24,6 +24,7 @@ static const struct nvkm_ior_func gt215_sor = { .state = g94_sor_state, + .power = nv50_sor_power, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c index 78ddffab7a93..fc14e48fe84b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp77.c @@ -24,6 +24,7 @@ static const struct nvkm_ior_func mcp77_sor = { .state = g94_sor_state, + .power = nv50_sor_power, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c index 97433c17db71..37c1dacb7d67 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sormcp89.c @@ -24,6 +24,7 @@ static const struct nvkm_ior_func mcp89_sor = { .state = g94_sor_state, + .power = nv50_sor_power, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c index a1327e8fead1..543b6d0ee74c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c @@ -22,15 +22,10 @@ * Authors: Ben Skeggs */ #include "ior.h" -#include "nv50.h" #include "outp.h" -#include <core/client.h> #include <subdev/timer.h> -#include <nvif/cl5070.h> -#include <nvif/unpack.h> - static const struct nvkm_output_func nv50_sor_output_func = { }; @@ -43,40 +38,33 @@ nv50_sor_output_new(struct nvkm_disp *disp, int index, index, dcbE, poutp); } -int -nv50_sor_power(NV50_DISP_MTHD_V1) +static void +nv50_sor_power_wait(struct nvkm_device *device, u32 soff) { - struct nvkm_device *device = disp->base.engine.subdev.device; - union { - struct nv50_disp_sor_pwr_v0 v0; - } *args = data; - const u32 soff = outp->or * 0x800; - u32 stat; - int ret = -ENOSYS; - - nvif_ioctl(object, "disp sor pwr size %d\n", size); - if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { - nvif_ioctl(object, "disp sor pwr vers %d state %d\n", - args->v0.version, args->v0.state); - stat = !!args->v0.state; - } else - return ret; - - - nvkm_msec(device, 2000, - if (!(nvkm_rd32(device, 0x61c004 + soff) & 0x80000000)) - break; - ); - nvkm_mask(device, 0x61c004 + soff, 0x80000001, 0x80000000 | stat); nvkm_msec(device, 2000, if (!(nvkm_rd32(device, 0x61c004 + soff) & 0x80000000)) break; ); +} + +void +nv50_sor_power(struct nvkm_ior *sor, bool normal, bool pu, + bool data, bool vsync, bool hsync) +{ + struct nvkm_device *device = sor->disp->engine.subdev.device; + const u32 soff = nv50_ior_base(sor); + const u32 shift = normal ? 0 : 16; + const u32 state = 0x80000000 | (0x00000001 * !!pu) << shift; + const u32 field = 0x80000000 | (0x00000001 << shift); + + nv50_sor_power_wait(device, soff); + nvkm_mask(device, 0x61c004 + soff, field, state); + nv50_sor_power_wait(device, soff); + nvkm_msec(device, 2000, if (!(nvkm_rd32(device, 0x61c030 + soff) & 0x10000000)) break; ); - return 0; } void @@ -103,6 +91,7 @@ nv50_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state) static const struct nvkm_ior_func nv50_sor = { .state = nv50_sor_state, + .power = nv50_sor_power, }; int |