Commit 9c5753bc authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/disp/nv50-: port OR power state control to nvkm_ior

Also removes the user-facing methods to these controls, as they're not
currently utilised by the DD anyway.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 29c0ca73
......@@ -27,30 +27,18 @@ struct nv50_disp_scanoutpos_v0 {
struct nv50_disp_mthd_v1 {
__u8 version;
#define NV50_DISP_MTHD_V1_DAC_PWR 0x10
#define NV50_DISP_MTHD_V1_DAC_LOAD 0x11
#define NV50_DISP_MTHD_V1_SOR_PWR 0x20
#define NV50_DISP_MTHD_V1_SOR_HDA_ELD 0x21
#define NV50_DISP_MTHD_V1_SOR_HDMI_PWR 0x22
#define NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT 0x23
#define NV50_DISP_MTHD_V1_SOR_DP_MST_LINK 0x25
#define NV50_DISP_MTHD_V1_SOR_DP_MST_VCPI 0x26
#define NV50_DISP_MTHD_V1_PIOR_PWR 0x30
__u8 method;
__u16 hasht;
__u16 hashm;
__u8 pad06[2];
};
struct nv50_disp_dac_pwr_v0 {
__u8 version;
__u8 state;
__u8 data;
__u8 vsync;
__u8 hsync;
__u8 pad05[3];
};
struct nv50_disp_dac_load_v0 {
__u8 version;
__u8 load;
......@@ -58,12 +46,6 @@ struct nv50_disp_dac_load_v0 {
__u32 data;
};
struct nv50_disp_sor_pwr_v0 {
__u8 version;
__u8 state;
__u8 pad02[6];
};
struct nv50_disp_sor_hda_eld_v0 {
__u8 version;
__u8 pad01[7];
......@@ -101,11 +83,4 @@ struct nv50_disp_sor_dp_mst_vcpi_v0 {
__u16 pbn;
__u16 aligned_pbn;
};
struct nv50_disp_pior_pwr_v0 {
__u8 version;
__u8 state;
__u8 type;
__u8 pad03[5];
};
#endif
......@@ -2459,30 +2459,6 @@ nv50_outp_atomic_check(struct drm_encoder *encoder,
/******************************************************************************
* DAC
*****************************************************************************/
static void
nv50_dac_dpms(struct drm_encoder *encoder, int mode)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nv50_disp *disp = nv50_disp(encoder->dev);
struct {
struct nv50_disp_mthd_v1 base;
struct nv50_disp_dac_pwr_v0 pwr;
} args = {
.base.version = 1,
.base.method = NV50_DISP_MTHD_V1_DAC_PWR,
.base.hasht = nv_encoder->dcb->hasht,
.base.hashm = nv_encoder->dcb->hashm,
.pwr.state = 1,
.pwr.data = 1,
.pwr.vsync = (mode != DRM_MODE_DPMS_SUSPEND &&
mode != DRM_MODE_DPMS_OFF),
.pwr.hsync = (mode != DRM_MODE_DPMS_STANDBY &&
mode != DRM_MODE_DPMS_OFF),
};
nvif_mthd(disp->disp, 0, &args, sizeof(args));
}
static void
nv50_dac_disable(struct drm_encoder *encoder)
{
......@@ -2584,7 +2560,6 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
static const struct drm_encoder_helper_funcs
nv50_dac_help = {
.dpms = nv50_dac_dpms,
.atomic_check = nv50_outp_atomic_check,
.enable = nv50_dac_enable,
.disable = nv50_dac_disable,
......@@ -3405,25 +3380,6 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max,
/******************************************************************************
* SOR
*****************************************************************************/
static void
nv50_sor_dpms(struct drm_encoder *encoder, int mode)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nv50_disp *disp = nv50_disp(encoder->dev);
struct {
struct nv50_disp_mthd_v1 base;
struct nv50_disp_sor_pwr_v0 pwr;
} args = {
.base.version = 1,
.base.method = NV50_DISP_MTHD_V1_SOR_PWR,
.base.hasht = nv_encoder->dcb->hasht,
.base.hashm = nv_encoder->dcb->hashm,
.pwr.state = mode == DRM_MODE_DPMS_ON,
};
nvif_mthd(disp->disp, 0, &args, sizeof(args));
}
static void
nv50_sor_update(struct nouveau_encoder *nv_encoder, u8 head,
struct drm_display_mode *mode, u8 proto, u8 depth)
......@@ -3602,7 +3558,6 @@ nv50_sor_enable(struct drm_encoder *encoder)
static const struct drm_encoder_helper_funcs
nv50_sor_help = {
.dpms = nv50_sor_dpms,
.atomic_check = nv50_outp_atomic_check,
.enable = nv50_sor_enable,
.disable = nv50_sor_disable,
......@@ -3686,26 +3641,6 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
/******************************************************************************
* PIOR
*****************************************************************************/
static void
nv50_pior_dpms(struct drm_encoder *encoder, int mode)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nv50_disp *disp = nv50_disp(encoder->dev);
struct {
struct nv50_disp_mthd_v1 base;
struct nv50_disp_pior_pwr_v0 pwr;
} args = {
.base.version = 1,
.base.method = NV50_DISP_MTHD_V1_PIOR_PWR,
.base.hasht = nv_encoder->dcb->hasht,
.base.hashm = nv_encoder->dcb->hashm,
.pwr.state = mode == DRM_MODE_DPMS_ON,
.pwr.type = nv_encoder->dcb->type,
};
nvif_mthd(disp->disp, 0, &args, sizeof(args));
}
static int
nv50_pior_atomic_check(struct drm_encoder *encoder,
struct drm_crtc_state *crtc_state,
......@@ -3790,7 +3725,6 @@ nv50_pior_enable(struct drm_encoder *encoder)
static const struct drm_encoder_helper_funcs
nv50_pior_help = {
.dpms = nv50_pior_dpms,
.atomic_check = nv50_pior_atomic_check,
.enable = nv50_pior_enable,
.disable = nv50_pior_disable,
......@@ -4355,14 +4289,8 @@ nv50_display_init(struct drm_device *dev)
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) {
const struct drm_encoder_helper_funcs *help;
struct nouveau_encoder *nv_encoder;
nv_encoder = nouveau_encoder(encoder);
help = encoder->helper_private;
if (help && help->dpms)
help->dpms(encoder, DRM_MODE_DPMS_ON);
struct nouveau_encoder *nv_encoder =
nouveau_encoder(encoder);
nv50_mstm_init(nv_encoder->dp.mstm);
}
}
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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,
};
......
......@@ -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,
};
......
......@@ -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,
};
......
......@@ -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,
};
......
......@@ -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,
......
......@@ -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,
......
......@@ -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,
......
......@@ -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
......
......@@ -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
......
......@@ -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 *);
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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;
};
......
......@@ -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
......
......@@ -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 *
......
......@@ -24,6 +24,7 @@
static const struct nvkm_ior_func
g84_sor = {
.state = nv50_sor_state,
.power = nv50_sor_power,
};
int
......
......@@ -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
......
......@@ -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
......
......@@ -24,6 +24,7 @@
static const struct nvkm_ior_func
gk104_sor = {
.state = gf119_sor_state,
.power = nv50_sor_power,
};
int
......
......@@ -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
......
......@@ -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
......
......@@ -24,6 +24,7 @@
static const struct nvkm_ior_func
gt215_sor = {
.state = g94_sor_state,
.power = nv50_sor_power,
};
int
......
......@@ -24,6 +24,7 @@
static const struct nvkm_ior_func
mcp77_sor = {
.state = g94_sor_state,
.power = nv50_sor_power,
};
int
......
......@@ -24,6 +24,7 @@
static const struct nvkm_ior_func
mcp89_sor = {
.state = g94_sor_state,
.power = nv50_sor_power,
};
int
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment