[Intel-gfx] [PATCH]DRM i915: IGD big FIFO support
Eric Anholt
eric at anholt.net
Fri May 22 21:39:51 CEST 2009
On Mon, 2009-05-18 at 10:44 +0800, Shaohua Li wrote:
> Big FIFO is a feature to put memory into self-refresh mode when CPU
> enters C3+ state. Gfx has a FIFO to buffer memory access, when the
> watermark of the FIFO is under threshold, Gfx doesn't need access
> memory, so at that time memory can be put into self-refresh mode.
>
> The watermark calculation is based on CPU C3 state exit latency. If
> watermark is wrong, when CPU enters C3+, display will be broken or
> flicker.
>
> I had a power measurement about the feature:
> environment: 1920x1400 display, Atom CPU with C4 enabled, system FSB
> is 667 and memory is DDR2 667. Launch X, and gives system several
> minutes to settle down, then test the power of the whole system in idle time:
> without big fifo, idle power is 19.8w
> with it, idle power is 18.6w
>
> The patch doesn't enable HPLL off for CxSR. Last time I heard it's broken
> in current IGD chip, if it works, then I'll add it later.
>
> Signed-off-by: Shaohua Li <shaohua.li at intel.com>
Nice, and thanks for including numbers in the commit message. A few
comments:
> +
> +#define HOSTBAR_SIZE (1024 * 16)
> +static int igd_get_freq(struct drm_device *dev, unsigned long *fsb,
> + unsigned long *mem)
> +{
> + struct pci_dev *host;
> + u64 mch_bar;
> + u32 tmp;
> + void *addr;
> +
> + host = pci_get_device(PCI_VENDOR_ID_INTEL, 0xa000, NULL);
> + if (!host)
> + host = pci_get_device(PCI_VENDOR_ID_INTEL, 0xa010, NULL);
> + if (!host)
> + return -ENODEV;
> + pci_read_config_dword(host, 0x48, &tmp);
> + mch_bar = tmp;
> + pci_read_config_dword(host, 0x4c, &tmp);
> + mch_bar |= ((u64)tmp) << 32;
> +
> + mch_bar &= ~((u64)(HOSTBAR_SIZE -1));
> + pci_dev_put(host);
> +
> + addr = ioremap(mch_bar, HOSTBAR_SIZE);
> + if (!addr)
> + return -ENOMEM;
> + tmp = *(u32 *)(addr + 0xc00);
> + iounmap(addr);
MCHBAR mapping is tricky. I think we'll need to use the same code here
as i915_gem_tiling.c, and that's changing in 2.6.31 to successfully
enable it (safely) more often.
> + switch (tmp & 0x7) {
> + case 1:
> + *fsb = 533; /* 133*4 */
> + break;
> + case 2:
> + *fsb = 800; /* 200*4 */
> + break;
> + case 3:
> + *fsb = 667; /* 167*4 */
> + break;
> + case 5:
> + *fsb = 400; /* 100*4 */
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + switch ((tmp >> 4) & 0x7) {
> + case 1:
> + *mem = 533;
> + break;
> + case 2:
> + *mem = 667;
> + break;
> + case 3:
> + *mem = 800;
> + break;
> + default:
> + return -EINVAL;
> + }
> + return 0;
> +}
> +
> +static void igd_setup_cxsr(struct drm_device *dev, unsigned long clock)
> +{
> + u32 reg;
> + unsigned long wm;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + struct cxsr_latency *latency;
> + unsigned long fsb, mem;
> + int i;
> + int pipes_enabled = 0;
> + struct drm_crtc *crtc;
> +
> + if (!IS_IGD(dev))
> + return;
> +
> + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
> + if (crtc->enabled)
> + pipes_enabled++;
> + }
> + if (pipes_enabled != 1) {
> + DRM_DEBUG("Two pipes are enabled, disable CxSR\n");
> + goto disable_cxsr;
> + }
> +
> + if (igd_get_freq(dev, &fsb, &mem))
> + goto disable_cxsr;
> +
> + for (i = 0; i < ARRAY_SIZE(igd_cxsr_latency); i++) {
> + latency = &igd_cxsr_latency[i];
> + if ((!!IS_IGDG(dev)) == latency->is_desktop &&
IS_IGDG is already a boolean.
--
Eric Anholt
eric at anholt.net eric.anholt at intel.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20090522/e99a2530/attachment.sig>
More information about the Intel-gfx
mailing list