mirror of
https://github.com/torvalds/linux.git
synced 2024-12-25 12:21:37 +00:00
drm/i915: move emon functionality into intel_pm module
This moves the Ironlake energy monitoring functionality into intel_pm module. Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org> Acked-by: Ben Widawsky <benjamin.widawsky@intel.com> Signed-off-by: Eugeni Dodonov <eugeni.dodonov@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
2b4e57bd7a
commit
dde18883de
@ -6351,92 +6351,6 @@ static const struct drm_mode_config_funcs intel_mode_funcs = {
|
|||||||
.output_poll_changed = intel_fb_output_poll_changed,
|
.output_poll_changed = intel_fb_output_poll_changed,
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned long intel_pxfreq(u32 vidfreq)
|
|
||||||
{
|
|
||||||
unsigned long freq;
|
|
||||||
int div = (vidfreq & 0x3f0000) >> 16;
|
|
||||||
int post = (vidfreq & 0x3000) >> 12;
|
|
||||||
int pre = (vidfreq & 0x7);
|
|
||||||
|
|
||||||
if (!pre)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
freq = ((div * 133333) / ((1<<post) * pre));
|
|
||||||
|
|
||||||
return freq;
|
|
||||||
}
|
|
||||||
|
|
||||||
void intel_init_emon(struct drm_device *dev)
|
|
||||||
{
|
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
||||||
u32 lcfuse;
|
|
||||||
u8 pxw[16];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Disable to program */
|
|
||||||
I915_WRITE(ECR, 0);
|
|
||||||
POSTING_READ(ECR);
|
|
||||||
|
|
||||||
/* Program energy weights for various events */
|
|
||||||
I915_WRITE(SDEW, 0x15040d00);
|
|
||||||
I915_WRITE(CSIEW0, 0x007f0000);
|
|
||||||
I915_WRITE(CSIEW1, 0x1e220004);
|
|
||||||
I915_WRITE(CSIEW2, 0x04000004);
|
|
||||||
|
|
||||||
for (i = 0; i < 5; i++)
|
|
||||||
I915_WRITE(PEW + (i * 4), 0);
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
I915_WRITE(DEW + (i * 4), 0);
|
|
||||||
|
|
||||||
/* Program P-state weights to account for frequency power adjustment */
|
|
||||||
for (i = 0; i < 16; i++) {
|
|
||||||
u32 pxvidfreq = I915_READ(PXVFREQ_BASE + (i * 4));
|
|
||||||
unsigned long freq = intel_pxfreq(pxvidfreq);
|
|
||||||
unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >>
|
|
||||||
PXVFREQ_PX_SHIFT;
|
|
||||||
unsigned long val;
|
|
||||||
|
|
||||||
val = vid * vid;
|
|
||||||
val *= (freq / 1000);
|
|
||||||
val *= 255;
|
|
||||||
val /= (127*127*900);
|
|
||||||
if (val > 0xff)
|
|
||||||
DRM_ERROR("bad pxval: %ld\n", val);
|
|
||||||
pxw[i] = val;
|
|
||||||
}
|
|
||||||
/* Render standby states get 0 weight */
|
|
||||||
pxw[14] = 0;
|
|
||||||
pxw[15] = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) |
|
|
||||||
(pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]);
|
|
||||||
I915_WRITE(PXW + (i * 4), val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adjust magic regs to magic values (more experimental results) */
|
|
||||||
I915_WRITE(OGW0, 0);
|
|
||||||
I915_WRITE(OGW1, 0);
|
|
||||||
I915_WRITE(EG0, 0x00007f00);
|
|
||||||
I915_WRITE(EG1, 0x0000000e);
|
|
||||||
I915_WRITE(EG2, 0x000e0000);
|
|
||||||
I915_WRITE(EG3, 0x68000300);
|
|
||||||
I915_WRITE(EG4, 0x42000000);
|
|
||||||
I915_WRITE(EG5, 0x00140031);
|
|
||||||
I915_WRITE(EG6, 0);
|
|
||||||
I915_WRITE(EG7, 0);
|
|
||||||
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
I915_WRITE(PXWL + (i * 4), 0);
|
|
||||||
|
|
||||||
/* Enable PMON + select events */
|
|
||||||
I915_WRITE(ECR, 0x80000019);
|
|
||||||
|
|
||||||
lcfuse = I915_READ(LCFUSE02);
|
|
||||||
|
|
||||||
dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ironlake_init_clock_gating(struct drm_device *dev)
|
static void ironlake_init_clock_gating(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
@ -2492,3 +2492,89 @@ void ironlake_enable_rc6(struct drm_device *dev)
|
|||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long intel_pxfreq(u32 vidfreq)
|
||||||
|
{
|
||||||
|
unsigned long freq;
|
||||||
|
int div = (vidfreq & 0x3f0000) >> 16;
|
||||||
|
int post = (vidfreq & 0x3000) >> 12;
|
||||||
|
int pre = (vidfreq & 0x7);
|
||||||
|
|
||||||
|
if (!pre)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
freq = ((div * 133333) / ((1<<post) * pre));
|
||||||
|
|
||||||
|
return freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
void intel_init_emon(struct drm_device *dev)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
u32 lcfuse;
|
||||||
|
u8 pxw[16];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Disable to program */
|
||||||
|
I915_WRITE(ECR, 0);
|
||||||
|
POSTING_READ(ECR);
|
||||||
|
|
||||||
|
/* Program energy weights for various events */
|
||||||
|
I915_WRITE(SDEW, 0x15040d00);
|
||||||
|
I915_WRITE(CSIEW0, 0x007f0000);
|
||||||
|
I915_WRITE(CSIEW1, 0x1e220004);
|
||||||
|
I915_WRITE(CSIEW2, 0x04000004);
|
||||||
|
|
||||||
|
for (i = 0; i < 5; i++)
|
||||||
|
I915_WRITE(PEW + (i * 4), 0);
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
I915_WRITE(DEW + (i * 4), 0);
|
||||||
|
|
||||||
|
/* Program P-state weights to account for frequency power adjustment */
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
u32 pxvidfreq = I915_READ(PXVFREQ_BASE + (i * 4));
|
||||||
|
unsigned long freq = intel_pxfreq(pxvidfreq);
|
||||||
|
unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >>
|
||||||
|
PXVFREQ_PX_SHIFT;
|
||||||
|
unsigned long val;
|
||||||
|
|
||||||
|
val = vid * vid;
|
||||||
|
val *= (freq / 1000);
|
||||||
|
val *= 255;
|
||||||
|
val /= (127*127*900);
|
||||||
|
if (val > 0xff)
|
||||||
|
DRM_ERROR("bad pxval: %ld\n", val);
|
||||||
|
pxw[i] = val;
|
||||||
|
}
|
||||||
|
/* Render standby states get 0 weight */
|
||||||
|
pxw[14] = 0;
|
||||||
|
pxw[15] = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) |
|
||||||
|
(pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]);
|
||||||
|
I915_WRITE(PXW + (i * 4), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust magic regs to magic values (more experimental results) */
|
||||||
|
I915_WRITE(OGW0, 0);
|
||||||
|
I915_WRITE(OGW1, 0);
|
||||||
|
I915_WRITE(EG0, 0x00007f00);
|
||||||
|
I915_WRITE(EG1, 0x0000000e);
|
||||||
|
I915_WRITE(EG2, 0x000e0000);
|
||||||
|
I915_WRITE(EG3, 0x68000300);
|
||||||
|
I915_WRITE(EG4, 0x42000000);
|
||||||
|
I915_WRITE(EG5, 0x00140031);
|
||||||
|
I915_WRITE(EG6, 0);
|
||||||
|
I915_WRITE(EG7, 0);
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
I915_WRITE(PXWL + (i * 4), 0);
|
||||||
|
|
||||||
|
/* Enable PMON + select events */
|
||||||
|
I915_WRITE(ECR, 0x80000019);
|
||||||
|
|
||||||
|
lcfuse = I915_READ(LCFUSE02);
|
||||||
|
|
||||||
|
dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user