From e495d0d7e36298f76336fdc58685ac4cacd454ba Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 23 Jan 2012 13:22:58 +1000 Subject: [PATCH] drm/nv50/disp: more accurate function to determine active crtcs Signed-off-by: Ben Skeggs Signed-off-by: Martin Peres --- drivers/gpu/drm/nouveau/nv50_display.c | 23 +++++++++++++++++++++++ drivers/gpu/drm/nouveau/nv50_display.h | 2 ++ drivers/gpu/drm/nouveau/nv50_pm.c | 11 +++-------- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 7ba28e08ee31..ce440e2e58ca 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -50,6 +50,29 @@ nv50_sor_nr(struct drm_device *dev) return 4; } +u32 +nv50_display_active_crtcs(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + u32 mask = 0; + int i; + + if (dev_priv->chipset < 0x90 || + dev_priv->chipset == 0x92 || + dev_priv->chipset == 0xa0) { + for (i = 0; i < 2; i++) + mask |= nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(i)); + } else { + for (i = 0; i < 4; i++) + mask |= nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(i)); + } + + for (i = 0; i < 3; i++) + mask |= nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_C(i)); + + return mask & 3; +} + static int evo_icmd(struct drm_device *dev, int ch, u32 mthd, u32 data) { diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h index 95874f7c043c..5d3dd14d2837 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.h +++ b/drivers/gpu/drm/nouveau/nv50_display.h @@ -74,6 +74,8 @@ void nv50_display_destroy(struct drm_device *dev); int nv50_crtc_blank(struct nouveau_crtc *, bool blank); int nv50_crtc_set_clock(struct drm_device *, int head, int pclk); +u32 nv50_display_active_crtcs(struct drm_device *); + int nv50_display_sync(struct drm_device *); int nv50_display_flip_next(struct drm_crtc *, struct drm_framebuffer *, struct nouveau_channel *chan); diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c b/drivers/gpu/drm/nouveau/nv50_pm.c index 17eb3277b1a0..109e473fd5f8 100644 --- a/drivers/gpu/drm/nouveau/nv50_pm.c +++ b/drivers/gpu/drm/nouveau/nv50_pm.c @@ -28,6 +28,7 @@ #include "nouveau_hw.h" #include "nouveau_pm.h" #include "nouveau_hwsq.h" +#include "nv50_display.h" enum clk_src { clk_src_crystal, @@ -535,6 +536,7 @@ calc_mclk(struct drm_device *dev, struct nouveau_pm_level *perflvl, struct nv50_pm_state *info) { struct drm_nouveau_private *dev_priv = dev->dev_private; + u32 crtc_mask = nv50_display_active_crtcs(dev); struct nouveau_mem_exec_func exec = { .dev = dev, .precharge = mclk_precharge, @@ -550,9 +552,8 @@ calc_mclk(struct drm_device *dev, struct nouveau_pm_level *perflvl, }; struct hwsq_ucode *hwsq = &info->mclk_hwsq; struct pll_lims pll; - u32 crtc_mask = 0; int N, M, P; - int ret, i; + int ret; /* use pcie refclock if possible, otherwise use mpll */ info->mctrl = nv_rd32(dev, 0x004008); @@ -569,12 +570,6 @@ calc_mclk(struct drm_device *dev, struct nouveau_pm_level *perflvl, info->mcoef = (N << 8) | M; } - /* determine active crtcs */ - for (i = 0; i < 2; i++) { - if (nv_rd32(dev, NV50_PDISPLAY_CRTC_C(i, CLOCK))) - crtc_mask |= (1 << i); - } - /* build the ucode which will reclock the memory for us */ hwsq_init(hwsq); if (crtc_mask) {