summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2009-03-18 19:29:10 +1000
committerBen Skeggs <bskeggs@redhat.com>2009-03-19 16:11:05 +1000
commit56887e62e7306a6b37f9c62c391fbf2592eb529b (patch)
tree130b09866c6f3f7eb43de25f36a616618750d89b
parent4fec64f1663441eea4b5a1e8550c6bf3cae6e1fb (diff)
nv50: some kms fixes
-rw-r--r--linux-core/nv50_crtc.c22
-rw-r--r--linux-core/nv50_dac.c10
-rw-r--r--linux-core/nv50_sor.c17
-rw-r--r--shared-core/nouveau_drv.h1
4 files changed, 34 insertions, 16 deletions
diff --git a/linux-core/nv50_crtc.c b/linux-core/nv50_crtc.c
index ed384253a..a01679e34 100644
--- a/linux-core/nv50_crtc.c
+++ b/linux-core/nv50_crtc.c
@@ -506,25 +506,39 @@ nv50_crtc_gamma_set(struct drm_crtc *drm_crtc, u16 *r, u16 *g, u16 *b,
nv50_crtc_lut_load(crtc);
}
+static int
+nv50_crtc_helper_set_config(struct drm_mode_set *set)
+{
+ struct drm_nouveau_private *dev_priv = set->crtc->dev->dev_private;
+ int ret;
+
+ dev_priv->in_modeset = true;
+ ret = drm_crtc_helper_set_config(set);
+ dev_priv->in_modeset = false;
+ return ret;
+}
+
static const struct drm_crtc_funcs nv50_crtc_funcs = {
.save = NULL,
.restore = NULL,
.cursor_set = nv50_crtc_cursor_set,
.cursor_move = nv50_crtc_cursor_move,
.gamma_set = nv50_crtc_gamma_set,
- .set_config = drm_crtc_helper_set_config,
+ .set_config = nv50_crtc_helper_set_config,
.destroy = nv50_crtc_destroy,
};
static void nv50_crtc_dpms(struct drm_crtc *drm_crtc, int mode)
{
+ struct drm_nouveau_private *dev_priv = drm_crtc->dev->dev_private;
+ struct nouveau_crtc *crtc = to_nouveau_crtc(drm_crtc);
+
+ if (dev_priv->in_modeset)
+ nv50_crtc_blank(crtc, true);
}
static void nv50_crtc_prepare(struct drm_crtc *drm_crtc)
{
- struct nouveau_crtc *crtc = to_nouveau_crtc(drm_crtc);
-
- nv50_crtc_blank(crtc, true);
}
static void nv50_crtc_commit(struct drm_crtc *drm_crtc)
diff --git a/linux-core/nv50_dac.c b/linux-core/nv50_dac.c
index 98c378faa..31c73d248 100644
--- a/linux-core/nv50_dac.c
+++ b/linux-core/nv50_dac.c
@@ -121,6 +121,11 @@ static void nv50_dac_dpms(struct drm_encoder *drm_encoder, int mode)
DRM_DEBUG("or %d\n", or);
+ if (dev_priv->in_modeset) {
+ nv50_dac_disconnect(encoder);
+ return;
+ }
+
/* wait for it to be done */
if (!nv_wait(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(or),
NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_PENDING, 0)) {
@@ -211,15 +216,14 @@ static void nv50_dac_mode_set(struct drm_encoder *drm_encoder,
mode_ctl |= 0x100;
}
- if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
mode_ctl2 |= NV50_DAC_MODE_CTRL2_NHSYNC;
- if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
mode_ctl2 |= NV50_DAC_MODE_CTRL2_NVSYNC;
OUT_MODE(NV50_DAC0_MODE_CTRL + offset, mode_ctl);
OUT_MODE(NV50_DAC0_MODE_CTRL2 + offset, mode_ctl2);
- OUT_MODE(NV50_UPDATE_DISPLAY, 0);
}
static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = {
diff --git a/linux-core/nv50_sor.c b/linux-core/nv50_sor.c
index a147fb668..ff3dd425e 100644
--- a/linux-core/nv50_sor.c
+++ b/linux-core/nv50_sor.c
@@ -80,6 +80,11 @@ static void nv50_sor_dpms(struct drm_encoder *drm_encoder, int mode)
DRM_DEBUG("or %d\n", encoder->or);
+ if (dev_priv->in_modeset) {
+ nv50_sor_disconnect(encoder);
+ return;
+ }
+
/* wait for it to be done */
if (!nv_wait(NV50_PDISPLAY_SOR_REGS_DPMS_CTRL(or),
NV50_PDISPLAY_SOR_REGS_DPMS_CTRL_PENDING, 0)) {
@@ -147,15 +152,10 @@ static bool nv50_sor_mode_fixup(struct drm_encoder *drm_encoder,
static void nv50_sor_prepare(struct drm_encoder *drm_encoder)
{
- struct nouveau_encoder *encoder = to_nouveau_encoder(drm_encoder);
-
- nv50_sor_dpms(drm_encoder, DRM_MODE_DPMS_OFF);
- nv50_sor_disconnect(encoder);
}
static void nv50_sor_commit(struct drm_encoder *drm_encoder)
{
- nv50_sor_dpms(drm_encoder, DRM_MODE_DPMS_ON);
}
static void nv50_sor_mode_set(struct drm_encoder *drm_encoder,
@@ -174,7 +174,7 @@ static void nv50_sor_mode_set(struct drm_encoder *drm_encoder,
mode_ctl |= NV50_SOR_MODE_CTRL_LVDS;
} else {
mode_ctl |= NV50_SOR_MODE_CTRL_TMDS;
- if (mode->clock > 165000)
+ if (adjusted_mode->clock > 165000)
mode_ctl |= NV50_SOR_MODE_CTRL_TMDS_DUAL_LINK;
}
@@ -183,14 +183,13 @@ static void nv50_sor_mode_set(struct drm_encoder *drm_encoder,
else
mode_ctl |= NV50_SOR_MODE_CTRL_CRTC0;
- if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
mode_ctl |= NV50_SOR_MODE_CTRL_NHSYNC;
- if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
mode_ctl |= NV50_SOR_MODE_CTRL_NVSYNC;
OUT_MODE(NV50_SOR0_MODE_CTRL + offset, mode_ctl);
- OUT_MODE(NV50_UPDATE_DISPLAY, 0);
}
static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = {
diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h
index 09f1bc96c..87ef8efa0 100644
--- a/shared-core/nouveau_drv.h
+++ b/shared-core/nouveau_drv.h
@@ -347,6 +347,7 @@ struct drm_nouveau_private {
struct list_head gpuobj_list;
void *display_priv; /* internal modesetting */
+ bool in_modeset;
struct bios bios;