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 { ...@@ -27,30 +27,18 @@ struct nv50_disp_scanoutpos_v0 {
struct nv50_disp_mthd_v1 { struct nv50_disp_mthd_v1 {
__u8 version; __u8 version;
#define NV50_DISP_MTHD_V1_DAC_PWR 0x10
#define NV50_DISP_MTHD_V1_DAC_LOAD 0x11 #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_HDA_ELD 0x21
#define NV50_DISP_MTHD_V1_SOR_HDMI_PWR 0x22 #define NV50_DISP_MTHD_V1_SOR_HDMI_PWR 0x22
#define NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT 0x23 #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_LINK 0x25
#define NV50_DISP_MTHD_V1_SOR_DP_MST_VCPI 0x26 #define NV50_DISP_MTHD_V1_SOR_DP_MST_VCPI 0x26
#define NV50_DISP_MTHD_V1_PIOR_PWR 0x30
__u8 method; __u8 method;
__u16 hasht; __u16 hasht;
__u16 hashm; __u16 hashm;
__u8 pad06[2]; __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 { struct nv50_disp_dac_load_v0 {
__u8 version; __u8 version;
__u8 load; __u8 load;
...@@ -58,12 +46,6 @@ struct nv50_disp_dac_load_v0 { ...@@ -58,12 +46,6 @@ struct nv50_disp_dac_load_v0 {
__u32 data; __u32 data;
}; };
struct nv50_disp_sor_pwr_v0 {
__u8 version;
__u8 state;
__u8 pad02[6];
};
struct nv50_disp_sor_hda_eld_v0 { struct nv50_disp_sor_hda_eld_v0 {
__u8 version; __u8 version;
__u8 pad01[7]; __u8 pad01[7];
...@@ -101,11 +83,4 @@ struct nv50_disp_sor_dp_mst_vcpi_v0 { ...@@ -101,11 +83,4 @@ struct nv50_disp_sor_dp_mst_vcpi_v0 {
__u16 pbn; __u16 pbn;
__u16 aligned_pbn; __u16 aligned_pbn;
}; };
struct nv50_disp_pior_pwr_v0 {
__u8 version;
__u8 state;
__u8 type;
__u8 pad03[5];
};
#endif #endif
...@@ -2459,30 +2459,6 @@ nv50_outp_atomic_check(struct drm_encoder *encoder, ...@@ -2459,30 +2459,6 @@ nv50_outp_atomic_check(struct drm_encoder *encoder,
/****************************************************************************** /******************************************************************************
* DAC * 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 static void
nv50_dac_disable(struct drm_encoder *encoder) nv50_dac_disable(struct drm_encoder *encoder)
{ {
...@@ -2584,7 +2560,6 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) ...@@ -2584,7 +2560,6 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
static const struct drm_encoder_helper_funcs static const struct drm_encoder_helper_funcs
nv50_dac_help = { nv50_dac_help = {
.dpms = nv50_dac_dpms,
.atomic_check = nv50_outp_atomic_check, .atomic_check = nv50_outp_atomic_check,
.enable = nv50_dac_enable, .enable = nv50_dac_enable,
.disable = nv50_dac_disable, .disable = nv50_dac_disable,
...@@ -3405,25 +3380,6 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max, ...@@ -3405,25 +3380,6 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max,
/****************************************************************************** /******************************************************************************
* SOR * 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 static void
nv50_sor_update(struct nouveau_encoder *nv_encoder, u8 head, nv50_sor_update(struct nouveau_encoder *nv_encoder, u8 head,
struct drm_display_mode *mode, u8 proto, u8 depth) struct drm_display_mode *mode, u8 proto, u8 depth)
...@@ -3602,7 +3558,6 @@ nv50_sor_enable(struct drm_encoder *encoder) ...@@ -3602,7 +3558,6 @@ nv50_sor_enable(struct drm_encoder *encoder)
static const struct drm_encoder_helper_funcs static const struct drm_encoder_helper_funcs
nv50_sor_help = { nv50_sor_help = {
.dpms = nv50_sor_dpms,
.atomic_check = nv50_outp_atomic_check, .atomic_check = nv50_outp_atomic_check,
.enable = nv50_sor_enable, .enable = nv50_sor_enable,
.disable = nv50_sor_disable, .disable = nv50_sor_disable,
...@@ -3686,26 +3641,6 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe) ...@@ -3686,26 +3641,6 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
/****************************************************************************** /******************************************************************************
* PIOR * 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 static int
nv50_pior_atomic_check(struct drm_encoder *encoder, nv50_pior_atomic_check(struct drm_encoder *encoder,
struct drm_crtc_state *crtc_state, struct drm_crtc_state *crtc_state,
...@@ -3790,7 +3725,6 @@ nv50_pior_enable(struct drm_encoder *encoder) ...@@ -3790,7 +3725,6 @@ nv50_pior_enable(struct drm_encoder *encoder)
static const struct drm_encoder_helper_funcs static const struct drm_encoder_helper_funcs
nv50_pior_help = { nv50_pior_help = {
.dpms = nv50_pior_dpms,
.atomic_check = nv50_pior_atomic_check, .atomic_check = nv50_pior_atomic_check,
.enable = nv50_pior_enable, .enable = nv50_pior_enable,
.disable = nv50_pior_disable, .disable = nv50_pior_disable,
...@@ -4355,14 +4289,8 @@ nv50_display_init(struct drm_device *dev) ...@@ -4355,14 +4289,8 @@ nv50_display_init(struct drm_device *dev)
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) { if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) {
const struct drm_encoder_helper_funcs *help; struct nouveau_encoder *nv_encoder =
struct nouveau_encoder *nv_encoder; nouveau_encoder(encoder);
nv_encoder = nouveau_encoder(encoder);
help = encoder->helper_private;
if (help && help->dpms)
help->dpms(encoder, DRM_MODE_DPMS_ON);
nv50_mstm_init(nv_encoder->dp.mstm); nv50_mstm_init(nv_encoder->dp.mstm);
} }
} }
......
...@@ -42,6 +42,7 @@ gf119_dac_state(struct nvkm_ior *dac, struct nvkm_ior_state *state) ...@@ -42,6 +42,7 @@ gf119_dac_state(struct nvkm_ior *dac, struct nvkm_ior_state *state)
static const struct nvkm_ior_func static const struct nvkm_ior_func
gf119_dac = { gf119_dac = {
.state = gf119_dac_state, .state = gf119_dac_state,
.power = nv50_dac_power,
}; };
int int
......
...@@ -90,40 +90,31 @@ nv50_dac_sense(NV50_DISP_MTHD_V1) ...@@ -90,40 +90,31 @@ nv50_dac_sense(NV50_DISP_MTHD_V1)
return 0; return 0;
} }
int static void
nv50_dac_power(NV50_DISP_MTHD_V1) 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, nvkm_msec(device, 2000,
if (!(nvkm_rd32(device, 0x61a004 + doff) & 0x80000000)) if (!(nvkm_rd32(device, 0x61a004 + doff) & 0x80000000))
break; 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 static void
...@@ -147,6 +138,7 @@ nv50_dac_state(struct nvkm_ior *dac, struct nvkm_ior_state *state) ...@@ -147,6 +138,7 @@ nv50_dac_state(struct nvkm_ior *dac, struct nvkm_ior_state *state)
static const struct nvkm_ior_func static const struct nvkm_ior_func
nv50_dac = { nv50_dac = {
.state = nv50_dac_state, .state = nv50_dac_state,
.power = nv50_dac_power,
}; };
int int
......
...@@ -40,15 +40,11 @@ g84_disp = { ...@@ -40,15 +40,11 @@ g84_disp = {
.outp.external.dp = nv50_pior_dp_new, .outp.external.dp = nv50_pior_dp_new,
.dac.nr = 3, .dac.nr = 3,
.dac.new = nv50_dac_new, .dac.new = nv50_dac_new,
.dac.power = nv50_dac_power,
.dac.sense = nv50_dac_sense, .dac.sense = nv50_dac_sense,
.sor.nr = 2, .sor.nr = 2,
.sor.new = g84_sor_new, .sor.new = g84_sor_new,
.sor.power = nv50_sor_power,
.sor.hdmi = g84_hdmi_ctrl, .sor.hdmi = g84_hdmi_ctrl,
.pior.nr = 3, .pior = { .nr = 3, .new = nv50_pior_new },
.pior.new = nv50_pior_new,
.pior.power = nv50_pior_power,
}; };
int int
......
...@@ -41,15 +41,11 @@ g94_disp = { ...@@ -41,15 +41,11 @@ g94_disp = {
.outp.external.dp = nv50_pior_dp_new, .outp.external.dp = nv50_pior_dp_new,
.dac.nr = 3, .dac.nr = 3,
.dac.new = nv50_dac_new, .dac.new = nv50_dac_new,
.dac.power = nv50_dac_power,
.dac.sense = nv50_dac_sense, .dac.sense = nv50_dac_sense,
.sor.nr = 4, .sor.nr = 4,
.sor.new = g94_sor_new, .sor.new = g94_sor_new,
.sor.power = nv50_sor_power,
.sor.hdmi = g84_hdmi_ctrl, .sor.hdmi = g84_hdmi_ctrl,
.pior.nr = 3, .pior = { .nr = 3, .new = nv50_pior_new },
.pior.new = nv50_pior_new,
.pior.power = nv50_pior_power,
}; };
int int
......
...@@ -508,11 +508,9 @@ gf119_disp = { ...@@ -508,11 +508,9 @@ gf119_disp = {
.outp.internal.dp = gf119_sor_dp_new, .outp.internal.dp = gf119_sor_dp_new,
.dac.nr = 3, .dac.nr = 3,
.dac.new = gf119_dac_new, .dac.new = gf119_dac_new,
.dac.power = nv50_dac_power,
.dac.sense = nv50_dac_sense, .dac.sense = nv50_dac_sense,
.sor.nr = 4, .sor.nr = 4,
.sor.new = gf119_sor_new, .sor.new = gf119_sor_new,
.sor.power = nv50_sor_power,
.sor.hda_eld = gf119_hda_eld, .sor.hda_eld = gf119_hda_eld,
.sor.hdmi = gf119_hdmi_ctrl, .sor.hdmi = gf119_hdmi_ctrl,
}; };
......
...@@ -40,11 +40,9 @@ gk104_disp = { ...@@ -40,11 +40,9 @@ gk104_disp = {
.outp.internal.dp = gf119_sor_dp_new, .outp.internal.dp = gf119_sor_dp_new,
.dac.nr = 3, .dac.nr = 3,
.dac.new = gf119_dac_new, .dac.new = gf119_dac_new,
.dac.power = nv50_dac_power,
.dac.sense = nv50_dac_sense, .dac.sense = nv50_dac_sense,
.sor.nr = 4, .sor.nr = 4,
.sor.new = gk104_sor_new, .sor.new = gk104_sor_new,
.sor.power = nv50_sor_power,
.sor.hda_eld = gf119_hda_eld, .sor.hda_eld = gf119_hda_eld,
.sor.hdmi = gk104_hdmi_ctrl, .sor.hdmi = gk104_hdmi_ctrl,
}; };
......
...@@ -40,11 +40,9 @@ gk110_disp = { ...@@ -40,11 +40,9 @@ gk110_disp = {
.outp.internal.dp = gf119_sor_dp_new, .outp.internal.dp = gf119_sor_dp_new,
.dac.nr = 3, .dac.nr = 3,
.dac.new = gf119_dac_new, .dac.new = gf119_dac_new,
.dac.power = nv50_dac_power,
.dac.sense = nv50_dac_sense, .dac.sense = nv50_dac_sense,
.sor.nr = 4, .sor.nr = 4,
.sor.new = gk104_sor_new, .sor.new = gk104_sor_new,
.sor.power = nv50_sor_power,
.sor.hda_eld = gf119_hda_eld, .sor.hda_eld = gf119_hda_eld,
.sor.hdmi = gk104_hdmi_ctrl, .sor.hdmi = gk104_hdmi_ctrl,
}; };
......
...@@ -40,11 +40,9 @@ gm107_disp = { ...@@ -40,11 +40,9 @@ gm107_disp = {
.outp.internal.dp = gm107_sor_dp_new, .outp.internal.dp = gm107_sor_dp_new,
.dac.nr = 3, .dac.nr = 3,
.dac.new = gf119_dac_new, .dac.new = gf119_dac_new,
.dac.power = nv50_dac_power,
.dac.sense = nv50_dac_sense, .dac.sense = nv50_dac_sense,
.sor.nr = 4, .sor.nr = 4,
.sor.new = gm107_sor_new, .sor.new = gm107_sor_new,
.sor.power = nv50_sor_power,
.sor.hda_eld = gf119_hda_eld, .sor.hda_eld = gf119_hda_eld,
.sor.hdmi = gk104_hdmi_ctrl, .sor.hdmi = gk104_hdmi_ctrl,
}; };
......
...@@ -40,11 +40,9 @@ gm200_disp = { ...@@ -40,11 +40,9 @@ gm200_disp = {
.outp.internal.dp = gm200_sor_dp_new, .outp.internal.dp = gm200_sor_dp_new,
.dac.nr = 3, .dac.nr = 3,
.dac.new = gf119_dac_new, .dac.new = gf119_dac_new,
.dac.power = nv50_dac_power,
.dac.sense = nv50_dac_sense, .dac.sense = nv50_dac_sense,
.sor.nr = 4, .sor.nr = 4,
.sor.new = gm200_sor_new, .sor.new = gm200_sor_new,
.sor.power = nv50_sor_power,
.sor.hda_eld = gf119_hda_eld, .sor.hda_eld = gf119_hda_eld,
.sor.hdmi = gk104_hdmi_ctrl, .sor.hdmi = gk104_hdmi_ctrl,
.sor.magic = gm200_sor_magic, .sor.magic = gm200_sor_magic,
......
...@@ -39,7 +39,6 @@ gp100_disp = { ...@@ -39,7 +39,6 @@ gp100_disp = {
.outp.internal.dp = gm200_sor_dp_new, .outp.internal.dp = gm200_sor_dp_new,
.sor.nr = 4, .sor.nr = 4,
.sor.new = gm200_sor_new, .sor.new = gm200_sor_new,
.sor.power = nv50_sor_power,
.sor.hda_eld = gf119_hda_eld, .sor.hda_eld = gf119_hda_eld,
.sor.hdmi = gk104_hdmi_ctrl, .sor.hdmi = gk104_hdmi_ctrl,
.sor.magic = gm200_sor_magic, .sor.magic = gm200_sor_magic,
......
...@@ -65,7 +65,6 @@ gp102_disp = { ...@@ -65,7 +65,6 @@ gp102_disp = {
.outp.internal.dp = gm200_sor_dp_new, .outp.internal.dp = gm200_sor_dp_new,
.sor.nr = 4, .sor.nr = 4,
.sor.new = gm200_sor_new, .sor.new = gm200_sor_new,
.sor.power = nv50_sor_power,
.sor.hda_eld = gf119_hda_eld, .sor.hda_eld = gf119_hda_eld,
.sor.hdmi = gk104_hdmi_ctrl, .sor.hdmi = gk104_hdmi_ctrl,
.sor.magic = gm200_sor_magic, .sor.magic = gm200_sor_magic,
......
...@@ -40,15 +40,11 @@ gt200_disp = { ...@@ -40,15 +40,11 @@ gt200_disp = {
.outp.external.dp = nv50_pior_dp_new, .outp.external.dp = nv50_pior_dp_new,
.dac.nr = 3, .dac.nr = 3,
.dac.new = nv50_dac_new, .dac.new = nv50_dac_new,
.dac.power = nv50_dac_power,
.dac.sense = nv50_dac_sense, .dac.sense = nv50_dac_sense,
.sor.nr = 2, .sor.nr = 2,
.sor.new = g84_sor_new, .sor.new = g84_sor_new,
.sor.power = nv50_sor_power,
.sor.hdmi = g84_hdmi_ctrl, .sor.hdmi = g84_hdmi_ctrl,
.pior.nr = 3, .pior = { .nr = 3, .new = nv50_pior_new },
.pior.new = nv50_pior_new,
.pior.power = nv50_pior_power,
}; };
int int
......
...@@ -41,16 +41,12 @@ gt215_disp = { ...@@ -41,16 +41,12 @@ gt215_disp = {
.outp.external.dp = nv50_pior_dp_new, .outp.external.dp = nv50_pior_dp_new,
.dac.nr = 3, .dac.nr = 3,
.dac.new = nv50_dac_new, .dac.new = nv50_dac_new,
.dac.power = nv50_dac_power,
.dac.sense = nv50_dac_sense, .dac.sense = nv50_dac_sense,
.sor.nr = 4, .sor.nr = 4,
.sor.new = gt215_sor_new, .sor.new = gt215_sor_new,
.sor.power = nv50_sor_power,
.sor.hda_eld = gt215_hda_eld, .sor.hda_eld = gt215_hda_eld,
.sor.hdmi = gt215_hdmi_ctrl, .sor.hdmi = gt215_hdmi_ctrl,
.pior.nr = 3, .pior = { .nr = 3, .new = nv50_pior_new },
.pior.new = nv50_pior_new,
.pior.power = nv50_pior_power,
}; };
int int
......
...@@ -40,6 +40,8 @@ struct nvkm_ior { ...@@ -40,6 +40,8 @@ struct nvkm_ior {
struct nvkm_ior_func { struct nvkm_ior_func {
void (*state)(struct nvkm_ior *, struct nvkm_ior_state *); 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 *, 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 *, ...@@ -47,7 +49,17 @@ int nvkm_ior_new_(const struct nvkm_ior_func *func, struct nvkm_disp *,
void nvkm_ior_del(struct nvkm_ior **); void nvkm_ior_del(struct nvkm_ior **);
struct nvkm_ior *nvkm_ior_find(struct nvkm_disp *, enum nvkm_ior_type, int id); 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_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 g94_sor_state(struct nvkm_ior *, struct nvkm_ior_state *);
void gf119_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 = { ...@@ -39,15 +39,11 @@ mcp77_disp = {
.outp.external.dp = nv50_pior_dp_new, .outp.external.dp = nv50_pior_dp_new,
.dac.nr = 3, .dac.nr = 3,
.dac.new = nv50_dac_new, .dac.new = nv50_dac_new,
.dac.power = nv50_dac_power,
.dac.sense = nv50_dac_sense, .dac.sense = nv50_dac_sense,
.sor.nr = 4, .sor.nr = 4,
.sor.new = mcp77_sor_new, .sor.new = mcp77_sor_new,
.sor.power = nv50_sor_power,
.sor.hdmi = g84_hdmi_ctrl, .sor.hdmi = g84_hdmi_ctrl,
.pior.nr = 3, .pior = { .nr = 3, .new = nv50_pior_new },
.pior.new = nv50_pior_new,
.pior.power = nv50_pior_power,
}; };
int int
......
...@@ -39,16 +39,12 @@ mcp89_disp = { ...@@ -39,16 +39,12 @@ mcp89_disp = {
.outp.external.dp = nv50_pior_dp_new, .outp.external.dp = nv50_pior_dp_new,
.dac.nr = 3, .dac.nr = 3,
.dac.new = nv50_dac_new, .dac.new = nv50_dac_new,
.dac.power = nv50_dac_power,
.dac.sense = nv50_dac_sense, .dac.sense = nv50_dac_sense,
.sor.nr = 4, .sor.nr = 4,
.sor.new = mcp89_sor_new, .sor.new = mcp89_sor_new,
.sor.power = nv50_sor_power,
.sor.hda_eld = gt215_hda_eld, .sor.hda_eld = gt215_hda_eld,
.sor.hdmi = gt215_hdmi_ctrl, .sor.hdmi = gt215_hdmi_ctrl,
.pior.nr = 3, .pior = { .nr = 3, .new = nv50_pior_new },
.pior.new = nv50_pior_new,
.pior.power = nv50_pior_power,
}; };
int int
......
...@@ -846,14 +846,9 @@ nv50_disp = { ...@@ -846,14 +846,9 @@ nv50_disp = {
.outp.external.dp = nv50_pior_dp_new, .outp.external.dp = nv50_pior_dp_new,
.dac.nr = 3, .dac.nr = 3,
.dac.new = nv50_dac_new, .dac.new = nv50_dac_new,
.dac.power = nv50_dac_power,
.dac.sense = nv50_dac_sense, .dac.sense = nv50_dac_sense,
.sor.nr = 2, .sor = { .nr = 2, .new = nv50_sor_new },
.sor.new = nv50_sor_new, .pior = { .nr = 3, .new = nv50_pior_new },
.sor.power = nv50_sor_power,
.pior.nr = 3,
.pior.new = nv50_pior_new,
.pior.power = nv50_pior_power,
}; };
int int
......
...@@ -31,7 +31,6 @@ struct nv50_disp { ...@@ -31,7 +31,6 @@ struct nv50_disp {
void nv50_disp_super_1(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 nv50_dac_sense(NV50_DISP_MTHD_V1);
int gt215_hda_eld(NV50_DISP_MTHD_V1); int gt215_hda_eld(NV50_DISP_MTHD_V1);
...@@ -42,9 +41,6 @@ int gt215_hdmi_ctrl(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 gf119_hdmi_ctrl(NV50_DISP_MTHD_V1);
int gk104_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 nv50_disp_new_(const struct nv50_disp_func *, struct nvkm_device *,
int index, int heads, struct nvkm_disp **); int index, int heads, struct nvkm_disp **);
int gf119_disp_new_(const struct nv50_disp_func *, struct nvkm_device *, int gf119_disp_new_(const struct nv50_disp_func *, struct nvkm_device *,
...@@ -84,14 +80,12 @@ struct nv50_disp_func { ...@@ -84,14 +80,12 @@ struct nv50_disp_func {
struct { struct {
int nr; int nr;
int (*new)(struct nvkm_disp *, int id); int (*new)(struct nvkm_disp *, int id);
int (*power)(NV50_DISP_MTHD_V1);
int (*sense)(NV50_DISP_MTHD_V1); int (*sense)(NV50_DISP_MTHD_V1);
} dac; } dac;
struct { struct {
int nr; int nr;
int (*new)(struct nvkm_disp *, int id); int (*new)(struct nvkm_disp *, int id);
int (*power)(NV50_DISP_MTHD_V1);
int (*hda_eld)(NV50_DISP_MTHD_V1); int (*hda_eld)(NV50_DISP_MTHD_V1);
int (*hdmi)(NV50_DISP_MTHD_V1); int (*hdmi)(NV50_DISP_MTHD_V1);
void (*magic)(struct nvkm_output *); void (*magic)(struct nvkm_output *);
...@@ -100,7 +94,6 @@ struct nv50_disp_func { ...@@ -100,7 +94,6 @@ struct nv50_disp_func {
struct { struct {
int nr; int nr;
int (*new)(struct nvkm_disp *, int id); int (*new)(struct nvkm_disp *, int id);
int (*power)(NV50_DISP_MTHD_V1);
} pior; } pior;
}; };
......
...@@ -22,15 +22,11 @@ ...@@ -22,15 +22,11 @@
* Authors: Ben Skeggs * Authors: Ben Skeggs
*/ */
#include "ior.h" #include "ior.h"
#include "nv50.h" #include "dp.h"
#include <core/client.h>
#include <subdev/i2c.h> #include <subdev/i2c.h>
#include <subdev/timer.h> #include <subdev/timer.h>
#include <nvif/cl5070.h>
#include <nvif/unpack.h>
/****************************************************************************** /******************************************************************************
* TMDS * TMDS
*****************************************************************************/ *****************************************************************************/
...@@ -86,39 +82,28 @@ nv50_pior_dp_new(struct nvkm_disp *disp, int index, struct dcb_output *dcbE, ...@@ -86,39 +82,28 @@ nv50_pior_dp_new(struct nvkm_disp *disp, int index, struct dcb_output *dcbE,
index, dcbE, poutp); index, dcbE, poutp);
} }
int static void
nv50_pior_power(NV50_DISP_MTHD_V1) 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, nvkm_msec(device, 2000,
if (!(nvkm_rd32(device, 0x61e004 + soff) & 0x80000000)) if (!(nvkm_rd32(device, 0x61e004 + poff) & 0x80000000))
break; 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 static void
...@@ -143,6 +128,7 @@ nv50_pior_state(struct nvkm_ior *pior, struct nvkm_ior_state *state) ...@@ -143,6 +128,7 @@ nv50_pior_state(struct nvkm_ior *pior, struct nvkm_ior_state *state)
static const struct nvkm_ior_func static const struct nvkm_ior_func
nv50_pior = { nv50_pior = {
.state = nv50_pior_state, .state = nv50_pior_state,
.power = nv50_pior_power,
}; };
int int
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "rootnv50.h" #include "rootnv50.h"
#include "dmacnv50.h" #include "dmacnv50.h"
#include "head.h" #include "head.h"
#include "ior.h"
#include <core/client.h> #include <core/client.h>
#include <core/ramht.h> #include <core/ramht.h>
...@@ -94,12 +95,8 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size) ...@@ -94,12 +95,8 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
} }
switch (mthd * !!outp) { 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: case NV50_DISP_MTHD_V1_DAC_LOAD:
return func->dac.sense(object, disp, data, size, hidx, outp); 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: case NV50_DISP_MTHD_V1_SOR_HDA_ELD:
if (!func->sor.hda_eld) if (!func->sor.hda_eld)
return -ENODEV; return -ENODEV;
...@@ -163,10 +160,6 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size) ...@@ -163,10 +160,6 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
return ret; return ret;
} }
break; 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: default:
break; break;
} }
...@@ -231,7 +224,21 @@ static int ...@@ -231,7 +224,21 @@ static int
nv50_disp_root_init_(struct nvkm_object *object) nv50_disp_root_init_(struct nvkm_object *object)
{ {
struct nv50_disp_root *root = nv50_disp_root(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 * static void *
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
static const struct nvkm_ior_func static const struct nvkm_ior_func
g84_sor = { g84_sor = {
.state = nv50_sor_state, .state = nv50_sor_state,
.power = nv50_sor_power,
}; };
int int
......
...@@ -304,6 +304,7 @@ g94_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state) ...@@ -304,6 +304,7 @@ g94_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
static const struct nvkm_ior_func static const struct nvkm_ior_func
g94_sor = { g94_sor = {
.state = g94_sor_state, .state = g94_sor_state,
.power = nv50_sor_power,
}; };
int int
......
...@@ -156,6 +156,7 @@ gf119_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state) ...@@ -156,6 +156,7 @@ gf119_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
static const struct nvkm_ior_func static const struct nvkm_ior_func
gf119_sor = { gf119_sor = {
.state = gf119_sor_state, .state = gf119_sor_state,
.power = nv50_sor_power,
}; };
int int
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
static const struct nvkm_ior_func static const struct nvkm_ior_func
gk104_sor = { gk104_sor = {
.state = gf119_sor_state, .state = gf119_sor_state,
.power = nv50_sor_power,
}; };
int int
......
...@@ -56,6 +56,7 @@ gm107_sor_dp_new(struct nvkm_disp *disp, int index, ...@@ -56,6 +56,7 @@ gm107_sor_dp_new(struct nvkm_disp *disp, int index,
static const struct nvkm_ior_func static const struct nvkm_ior_func
gm107_sor = { gm107_sor = {
.state = gf119_sor_state, .state = gf119_sor_state,
.power = nv50_sor_power,
}; };
int int
......
...@@ -133,6 +133,7 @@ gm200_sor_magic(struct nvkm_output *outp) ...@@ -133,6 +133,7 @@ gm200_sor_magic(struct nvkm_output *outp)
static const struct nvkm_ior_func static const struct nvkm_ior_func
gm200_sor = { gm200_sor = {
.state = gf119_sor_state, .state = gf119_sor_state,
.power = nv50_sor_power,
}; };
int int
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
static const struct nvkm_ior_func static const struct nvkm_ior_func
gt215_sor = { gt215_sor = {
.state = g94_sor_state, .state = g94_sor_state,
.power = nv50_sor_power,
}; };
int int
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
static const struct nvkm_ior_func static const struct nvkm_ior_func
mcp77_sor = { mcp77_sor = {
.state = g94_sor_state, .state = g94_sor_state,
.power = nv50_sor_power,
}; };
int int
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
static const struct nvkm_ior_func static const struct nvkm_ior_func
mcp89_sor = { mcp89_sor = {
.state = g94_sor_state, .state = g94_sor_state,
.power = nv50_sor_power,
}; };
int int
......
...@@ -22,15 +22,10 @@ ...@@ -22,15 +22,10 @@
* Authors: Ben Skeggs * Authors: Ben Skeggs
*/ */
#include "ior.h" #include "ior.h"
#include "nv50.h"
#include "outp.h" #include "outp.h"
#include <core/client.h>
#include <subdev/timer.h> #include <subdev/timer.h>
#include <nvif/cl5070.h>
#include <nvif/unpack.h>
static const struct nvkm_output_func static const struct nvkm_output_func
nv50_sor_output_func = { nv50_sor_output_func = {
}; };
...@@ -43,40 +38,33 @@ nv50_sor_output_new(struct nvkm_disp *disp, int index, ...@@ -43,40 +38,33 @@ nv50_sor_output_new(struct nvkm_disp *disp, int index,
index, dcbE, poutp); index, dcbE, poutp);
} }
int static void
nv50_sor_power(NV50_DISP_MTHD_V1) 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, nvkm_msec(device, 2000,
if (!(nvkm_rd32(device, 0x61c004 + soff) & 0x80000000)) if (!(nvkm_rd32(device, 0x61c004 + soff) & 0x80000000))
break; 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, nvkm_msec(device, 2000,
if (!(nvkm_rd32(device, 0x61c030 + soff) & 0x10000000)) if (!(nvkm_rd32(device, 0x61c030 + soff) & 0x10000000))
break; break;
); );
return 0;
} }
void void
...@@ -103,6 +91,7 @@ nv50_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state) ...@@ -103,6 +91,7 @@ nv50_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
static const struct nvkm_ior_func static const struct nvkm_ior_func
nv50_sor = { nv50_sor = {
.state = nv50_sor_state, .state = nv50_sor_state,
.power = nv50_sor_power,
}; };
int 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