drm/nv50/disp: more accurate function to determine active crtcs

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Martin Peres <martin.peres@labri.fr>
This commit is contained in:
Ben Skeggs 2012-01-23 13:22:58 +10:00
parent 6bdf68c9a4
commit e495d0d7e3
3 changed files with 28 additions and 8 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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) {