drm/nv50/disp: call into core to handle dac/sor power state changes
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
2d0aca2119
commit
ef22c8bb7b
@ -653,9 +653,17 @@ nv50_disp_base_ofuncs = {
|
|||||||
.fini = nv50_disp_base_fini,
|
.fini = nv50_disp_base_fini,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct nouveau_omthds
|
||||||
|
nv50_disp_base_omthds[] = {
|
||||||
|
{ SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd },
|
||||||
|
{ DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd },
|
||||||
|
{ DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
|
||||||
static struct nouveau_oclass
|
static struct nouveau_oclass
|
||||||
nv50_disp_base_oclass[] = {
|
nv50_disp_base_oclass[] = {
|
||||||
{ NV50_DISP_CLASS, &nv50_disp_base_ofuncs },
|
{ NV50_DISP_CLASS, &nv50_disp_base_ofuncs, nv50_disp_base_omthds },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -798,6 +806,8 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||||||
priv->head.nr = 2;
|
priv->head.nr = 2;
|
||||||
priv->dac.nr = 3;
|
priv->dac.nr = 3;
|
||||||
priv->sor.nr = 2;
|
priv->sor.nr = 2;
|
||||||
|
priv->dac.power = nv50_dac_power;
|
||||||
|
priv->sor.power = nv50_sor_power;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&priv->base.vblank.list);
|
INIT_LIST_HEAD(&priv->base.vblank.list);
|
||||||
spin_lock_init(&priv->base.vblank.lock);
|
spin_lock_init(&priv->base.vblank.lock);
|
||||||
|
@ -38,8 +38,6 @@ struct nv50_disp_priv {
|
|||||||
} sor;
|
} sor;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct nouveau_omthds nva3_disp_base_omthds[];
|
|
||||||
|
|
||||||
#define DAC_MTHD(n) (n), (n) + 0x03
|
#define DAC_MTHD(n) (n), (n) + 0x03
|
||||||
|
|
||||||
int nv50_dac_mthd(struct nouveau_object *, u32, void *, u32);
|
int nv50_dac_mthd(struct nouveau_object *, u32, void *, u32);
|
||||||
@ -107,6 +105,10 @@ extern struct nouveau_ofuncs nv50_disp_base_ofuncs;
|
|||||||
extern struct nouveau_oclass nv50_disp_cclass;
|
extern struct nouveau_oclass nv50_disp_cclass;
|
||||||
void nv50_disp_intr(struct nouveau_subdev *);
|
void nv50_disp_intr(struct nouveau_subdev *);
|
||||||
|
|
||||||
|
extern struct nouveau_omthds nv84_disp_base_omthds[];
|
||||||
|
|
||||||
|
extern struct nouveau_omthds nva3_disp_base_omthds[];
|
||||||
|
|
||||||
extern struct nouveau_ofuncs nvd0_disp_mast_ofuncs;
|
extern struct nouveau_ofuncs nvd0_disp_mast_ofuncs;
|
||||||
extern struct nouveau_ofuncs nvd0_disp_sync_ofuncs;
|
extern struct nouveau_ofuncs nvd0_disp_sync_ofuncs;
|
||||||
extern struct nouveau_ofuncs nvd0_disp_ovly_ofuncs;
|
extern struct nouveau_ofuncs nvd0_disp_ovly_ofuncs;
|
||||||
|
@ -39,9 +39,18 @@ nv84_disp_sclass[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct nouveau_omthds
|
||||||
|
nv84_disp_base_omthds[] = {
|
||||||
|
{ SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd },
|
||||||
|
{ SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd },
|
||||||
|
{ DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd },
|
||||||
|
{ DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
|
||||||
static struct nouveau_oclass
|
static struct nouveau_oclass
|
||||||
nv84_disp_base_oclass[] = {
|
nv84_disp_base_oclass[] = {
|
||||||
{ NV84_DISP_CLASS, &nv50_disp_base_ofuncs },
|
{ NV84_DISP_CLASS, &nv50_disp_base_ofuncs, nv84_disp_base_omthds },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -66,6 +75,8 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||||||
priv->head.nr = 2;
|
priv->head.nr = 2;
|
||||||
priv->dac.nr = 3;
|
priv->dac.nr = 3;
|
||||||
priv->sor.nr = 2;
|
priv->sor.nr = 2;
|
||||||
|
priv->dac.power = nv50_dac_power;
|
||||||
|
priv->sor.power = nv50_sor_power;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&priv->base.vblank.list);
|
INIT_LIST_HEAD(&priv->base.vblank.list);
|
||||||
spin_lock_init(&priv->base.vblank.lock);
|
spin_lock_init(&priv->base.vblank.lock);
|
||||||
|
@ -39,9 +39,24 @@ nv94_disp_sclass[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct nouveau_omthds
|
||||||
|
nv94_disp_base_omthds[] = {
|
||||||
|
{ SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd },
|
||||||
|
{ SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd },
|
||||||
|
{ SOR_MTHD(NV94_DISP_SOR_DP_TRAIN) , nv50_sor_mthd },
|
||||||
|
{ SOR_MTHD(NV94_DISP_SOR_DP_LNKCTL) , nv50_sor_mthd },
|
||||||
|
{ SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(0)), nv50_sor_mthd },
|
||||||
|
{ SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(1)), nv50_sor_mthd },
|
||||||
|
{ SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(2)), nv50_sor_mthd },
|
||||||
|
{ SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(3)), nv50_sor_mthd },
|
||||||
|
{ DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd },
|
||||||
|
{ DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
|
||||||
static struct nouveau_oclass
|
static struct nouveau_oclass
|
||||||
nv94_disp_base_oclass[] = {
|
nv94_disp_base_oclass[] = {
|
||||||
{ NV94_DISP_CLASS, &nv50_disp_base_ofuncs },
|
{ NV94_DISP_CLASS, &nv50_disp_base_ofuncs, nv94_disp_base_omthds },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -66,6 +81,8 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||||||
priv->head.nr = 2;
|
priv->head.nr = 2;
|
||||||
priv->dac.nr = 3;
|
priv->dac.nr = 3;
|
||||||
priv->sor.nr = 4;
|
priv->sor.nr = 4;
|
||||||
|
priv->dac.power = nv50_dac_power;
|
||||||
|
priv->sor.power = nv50_sor_power;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&priv->base.vblank.list);
|
INIT_LIST_HEAD(&priv->base.vblank.list);
|
||||||
spin_lock_init(&priv->base.vblank.lock);
|
spin_lock_init(&priv->base.vblank.lock);
|
||||||
|
@ -41,7 +41,7 @@ nva0_disp_sclass[] = {
|
|||||||
|
|
||||||
static struct nouveau_oclass
|
static struct nouveau_oclass
|
||||||
nva0_disp_base_oclass[] = {
|
nva0_disp_base_oclass[] = {
|
||||||
{ NVA0_DISP_CLASS, &nv50_disp_base_ofuncs },
|
{ NVA0_DISP_CLASS, &nv50_disp_base_ofuncs, nv84_disp_base_omthds },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -66,6 +66,8 @@ nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||||||
priv->head.nr = 2;
|
priv->head.nr = 2;
|
||||||
priv->dac.nr = 3;
|
priv->dac.nr = 3;
|
||||||
priv->sor.nr = 2;
|
priv->sor.nr = 2;
|
||||||
|
priv->dac.power = nv50_dac_power;
|
||||||
|
priv->sor.power = nv50_sor_power;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&priv->base.vblank.list);
|
INIT_LIST_HEAD(&priv->base.vblank.list);
|
||||||
spin_lock_init(&priv->base.vblank.lock);
|
spin_lock_init(&priv->base.vblank.lock);
|
||||||
|
@ -57,7 +57,7 @@ nva3_disp_base_omthds[] = {
|
|||||||
|
|
||||||
static struct nouveau_oclass
|
static struct nouveau_oclass
|
||||||
nva3_disp_base_oclass[] = {
|
nva3_disp_base_oclass[] = {
|
||||||
{ NVA3_DISP_CLASS, &nv50_disp_base_ofuncs },
|
{ NVA3_DISP_CLASS, &nv50_disp_base_ofuncs, nva3_disp_base_omthds },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -82,6 +82,8 @@ nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||||||
priv->head.nr = 2;
|
priv->head.nr = 2;
|
||||||
priv->dac.nr = 3;
|
priv->dac.nr = 3;
|
||||||
priv->sor.nr = 4;
|
priv->sor.nr = 4;
|
||||||
|
priv->dac.power = nv50_dac_power;
|
||||||
|
priv->sor.power = nv50_sor_power;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&priv->base.vblank.list);
|
INIT_LIST_HEAD(&priv->base.vblank.list);
|
||||||
spin_lock_init(&priv->base.vblank.lock);
|
spin_lock_init(&priv->base.vblank.lock);
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
#include "nouveau_crtc.h"
|
#include "nouveau_crtc.h"
|
||||||
#include "nv50_display.h"
|
#include "nv50_display.h"
|
||||||
|
|
||||||
|
#include <core/class.h>
|
||||||
|
|
||||||
#include <subdev/timer.h>
|
#include <subdev/timer.h>
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -124,7 +126,7 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
|
|||||||
static void
|
static void
|
||||||
nv50_dac_dpms(struct drm_encoder *encoder, int mode)
|
nv50_dac_dpms(struct drm_encoder *encoder, int mode)
|
||||||
{
|
{
|
||||||
struct nouveau_device *device = nouveau_dev(encoder->dev);
|
struct nv50_display *priv = nv50_display(encoder->dev);
|
||||||
struct nouveau_drm *drm = nouveau_drm(encoder->dev);
|
struct nouveau_drm *drm = nouveau_drm(encoder->dev);
|
||||||
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
|
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
@ -132,19 +134,10 @@ nv50_dac_dpms(struct drm_encoder *encoder, int mode)
|
|||||||
|
|
||||||
NV_DEBUG(drm, "or %d mode %d\n", or, mode);
|
NV_DEBUG(drm, "or %d mode %d\n", or, mode);
|
||||||
|
|
||||||
/* wait for it to be done */
|
|
||||||
if (!nv_wait(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or),
|
|
||||||
NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING, 0)) {
|
|
||||||
NV_ERROR(drm, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or);
|
|
||||||
NV_ERROR(drm, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or,
|
|
||||||
nv_rd32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
val = nv_rd32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or)) & ~0x7F;
|
|
||||||
|
|
||||||
if (mode != DRM_MODE_DPMS_ON)
|
if (mode != DRM_MODE_DPMS_ON)
|
||||||
val |= NV50_PDISPLAY_DAC_DPMS_CTRL_BLANKED;
|
val = NV50_PDISPLAY_DAC_DPMS_CTRL_BLANKED;
|
||||||
|
else
|
||||||
|
val = 0;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case DRM_MODE_DPMS_STANDBY:
|
case DRM_MODE_DPMS_STANDBY:
|
||||||
@ -162,8 +155,7 @@ nv50_dac_dpms(struct drm_encoder *encoder, int mode)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
nv_wr32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or), val |
|
nv_call(priv->core, NV50_DISP_DAC_PWR + or, val);
|
||||||
NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
#include "nouveau_crtc.h"
|
#include "nouveau_crtc.h"
|
||||||
#include "nv50_display.h"
|
#include "nv50_display.h"
|
||||||
|
|
||||||
|
#include <core/class.h>
|
||||||
|
|
||||||
#include <subdev/timer.h>
|
#include <subdev/timer.h>
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
@ -267,12 +269,11 @@ nv50_sor_disconnect(struct drm_encoder *encoder)
|
|||||||
static void
|
static void
|
||||||
nv50_sor_dpms(struct drm_encoder *encoder, int mode)
|
nv50_sor_dpms(struct drm_encoder *encoder, int mode)
|
||||||
{
|
{
|
||||||
struct nouveau_device *device = nouveau_dev(encoder->dev);
|
struct nv50_display *priv = nv50_display(encoder->dev);
|
||||||
struct nouveau_drm *drm = nouveau_drm(encoder->dev);
|
struct nouveau_drm *drm = nouveau_drm(encoder->dev);
|
||||||
struct drm_device *dev = encoder->dev;
|
struct drm_device *dev = encoder->dev;
|
||||||
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
|
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
|
||||||
struct drm_encoder *enc;
|
struct drm_encoder *enc;
|
||||||
uint32_t val;
|
|
||||||
int or = nv_encoder->or;
|
int or = nv_encoder->or;
|
||||||
|
|
||||||
NV_DEBUG(drm, "or %d type %d mode %d\n", or, nv_encoder->dcb->type, mode);
|
NV_DEBUG(drm, "or %d type %d mode %d\n", or, nv_encoder->dcb->type, mode);
|
||||||
@ -292,29 +293,7 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wait for it to be done */
|
nv_call(priv->core, NV50_DISP_SOR_PWR + or, (mode == DRM_MODE_DPMS_ON));
|
||||||
if (!nv_wait(device, NV50_PDISPLAY_SOR_DPMS_CTRL(or),
|
|
||||||
NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING, 0)) {
|
|
||||||
NV_ERROR(drm, "timeout: SOR_DPMS_CTRL_PENDING(%d) == 0\n", or);
|
|
||||||
NV_ERROR(drm, "SOR_DPMS_CTRL(%d) = 0x%08x\n", or,
|
|
||||||
nv_rd32(device, NV50_PDISPLAY_SOR_DPMS_CTRL(or)));
|
|
||||||
}
|
|
||||||
|
|
||||||
val = nv_rd32(device, NV50_PDISPLAY_SOR_DPMS_CTRL(or));
|
|
||||||
|
|
||||||
if (mode == DRM_MODE_DPMS_ON)
|
|
||||||
val |= NV50_PDISPLAY_SOR_DPMS_CTRL_ON;
|
|
||||||
else
|
|
||||||
val &= ~NV50_PDISPLAY_SOR_DPMS_CTRL_ON;
|
|
||||||
|
|
||||||
nv_wr32(device, NV50_PDISPLAY_SOR_DPMS_CTRL(or), val |
|
|
||||||
NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING);
|
|
||||||
if (!nv_wait(device, NV50_PDISPLAY_SOR_DPMS_STATE(or),
|
|
||||||
NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) {
|
|
||||||
NV_ERROR(drm, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", or);
|
|
||||||
NV_ERROR(drm, "SOR_DPMS_STATE(%d) = 0x%08x\n", or,
|
|
||||||
nv_rd32(device, NV50_PDISPLAY_SOR_DPMS_STATE(or)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
|
if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
|
||||||
struct dp_train_func func = {
|
struct dp_train_func func = {
|
||||||
|
Loading…
Reference in New Issue
Block a user