aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-04-26 17:28:12 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-05-03 05:18:29 -0400
commiteb48eb005098cc6f845d281dd079baea7573f54c (patch)
tree18eef2f8743a764c34d6ea0cc0f202f2321fba0b /drivers/gpu/drm/i915
parent6ebebc9206fca1d20d90edec4873e819cc4051d0 (diff)
drm/i915: move the ips code to intel_pm.c
We now have a nice home for power management code, so let's use it! v2: Resolve conflict agains "Only enable IPS polling for gen5" Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c478
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h3
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c481
3 files changed, 487 insertions, 475 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 833ac8a0cf43..1b1f8e70df8d 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -36,14 +36,12 @@
36#include "i915_drm.h" 36#include "i915_drm.h"
37#include "i915_drv.h" 37#include "i915_drv.h"
38#include "i915_trace.h" 38#include "i915_trace.h"
39#include "../../../platform/x86/intel_ips.h"
40#include <linux/pci.h> 39#include <linux/pci.h>
41#include <linux/vgaarb.h> 40#include <linux/vgaarb.h>
42#include <linux/acpi.h> 41#include <linux/acpi.h>
43#include <linux/pnp.h> 42#include <linux/pnp.h>
44#include <linux/vga_switcheroo.h> 43#include <linux/vga_switcheroo.h>
45#include <linux/slab.h> 44#include <linux/slab.h>
46#include <linux/module.h>
47#include <acpi/video.h> 45#include <acpi/video.h>
48#include <asm/pat.h> 46#include <asm/pat.h>
49 47
@@ -1481,468 +1479,6 @@ static void i915_ironlake_get_mem_freq(struct drm_device *dev)
1481 } 1479 }
1482} 1480}
1483 1481
1484static const struct cparams {
1485 u16 i;
1486 u16 t;
1487 u16 m;
1488 u16 c;
1489} cparams[] = {
1490 { 1, 1333, 301, 28664 },
1491 { 1, 1066, 294, 24460 },
1492 { 1, 800, 294, 25192 },
1493 { 0, 1333, 276, 27605 },
1494 { 0, 1066, 276, 27605 },
1495 { 0, 800, 231, 23784 },
1496};
1497
1498unsigned long i915_chipset_val(struct drm_i915_private *dev_priv)
1499{
1500 u64 total_count, diff, ret;
1501 u32 count1, count2, count3, m = 0, c = 0;
1502 unsigned long now = jiffies_to_msecs(jiffies), diff1;
1503 int i;
1504
1505 diff1 = now - dev_priv->last_time1;
1506
1507 /* Prevent division-by-zero if we are asking too fast.
1508 * Also, we don't get interesting results if we are polling
1509 * faster than once in 10ms, so just return the saved value
1510 * in such cases.
1511 */
1512 if (diff1 <= 10)
1513 return dev_priv->chipset_power;
1514
1515 count1 = I915_READ(DMIEC);
1516 count2 = I915_READ(DDREC);
1517 count3 = I915_READ(CSIEC);
1518
1519 total_count = count1 + count2 + count3;
1520
1521 /* FIXME: handle per-counter overflow */
1522 if (total_count < dev_priv->last_count1) {
1523 diff = ~0UL - dev_priv->last_count1;
1524 diff += total_count;
1525 } else {
1526 diff = total_count - dev_priv->last_count1;
1527 }
1528
1529 for (i = 0; i < ARRAY_SIZE(cparams); i++) {
1530 if (cparams[i].i == dev_priv->c_m &&
1531 cparams[i].t == dev_priv->r_t) {
1532 m = cparams[i].m;
1533 c = cparams[i].c;
1534 break;
1535 }
1536 }
1537
1538 diff = div_u64(diff, diff1);
1539 ret = ((m * diff) + c);
1540 ret = div_u64(ret, 10);
1541
1542 dev_priv->last_count1 = total_count;
1543 dev_priv->last_time1 = now;
1544
1545 dev_priv->chipset_power = ret;
1546
1547 return ret;
1548}
1549
1550unsigned long i915_mch_val(struct drm_i915_private *dev_priv)
1551{
1552 unsigned long m, x, b;
1553 u32 tsfs;
1554
1555 tsfs = I915_READ(TSFS);
1556
1557 m = ((tsfs & TSFS_SLOPE_MASK) >> TSFS_SLOPE_SHIFT);
1558 x = I915_READ8(TR1);
1559
1560 b = tsfs & TSFS_INTR_MASK;
1561
1562 return ((m * x) / 127) - b;
1563}
1564
1565static u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid)
1566{
1567 static const struct v_table {
1568 u16 vd; /* in .1 mil */
1569 u16 vm; /* in .1 mil */
1570 } v_table[] = {
1571 { 0, 0, },
1572 { 375, 0, },
1573 { 500, 0, },
1574 { 625, 0, },
1575 { 750, 0, },
1576 { 875, 0, },
1577 { 1000, 0, },
1578 { 1125, 0, },
1579 { 4125, 3000, },
1580 { 4125, 3000, },
1581 { 4125, 3000, },
1582 { 4125, 3000, },
1583 { 4125, 3000, },
1584 { 4125, 3000, },
1585 { 4125, 3000, },
1586 { 4125, 3000, },
1587 { 4125, 3000, },
1588 { 4125, 3000, },
1589 { 4125, 3000, },
1590 { 4125, 3000, },
1591 { 4125, 3000, },
1592 { 4125, 3000, },
1593 { 4125, 3000, },
1594 { 4125, 3000, },
1595 { 4125, 3000, },
1596 { 4125, 3000, },
1597 { 4125, 3000, },
1598 { 4125, 3000, },
1599 { 4125, 3000, },
1600 { 4125, 3000, },
1601 { 4125, 3000, },
1602 { 4125, 3000, },
1603 { 4250, 3125, },
1604 { 4375, 3250, },
1605 { 4500, 3375, },
1606 { 4625, 3500, },
1607 { 4750, 3625, },
1608 { 4875, 3750, },
1609 { 5000, 3875, },
1610 { 5125, 4000, },
1611 { 5250, 4125, },
1612 { 5375, 4250, },
1613 { 5500, 4375, },
1614 { 5625, 4500, },
1615 { 5750, 4625, },
1616 { 5875, 4750, },
1617 { 6000, 4875, },
1618 { 6125, 5000, },
1619 { 6250, 5125, },
1620 { 6375, 5250, },
1621 { 6500, 5375, },
1622 { 6625, 5500, },
1623 { 6750, 5625, },
1624 { 6875, 5750, },
1625 { 7000, 5875, },
1626 { 7125, 6000, },
1627 { 7250, 6125, },
1628 { 7375, 6250, },
1629 { 7500, 6375, },
1630 { 7625, 6500, },
1631 { 7750, 6625, },
1632 { 7875, 6750, },
1633 { 8000, 6875, },
1634 { 8125, 7000, },
1635 { 8250, 7125, },
1636 { 8375, 7250, },
1637 { 8500, 7375, },
1638 { 8625, 7500, },
1639 { 8750, 7625, },
1640 { 8875, 7750, },
1641 { 9000, 7875, },
1642 { 9125, 8000, },
1643 { 9250, 8125, },
1644 { 9375, 8250, },
1645 { 9500, 8375, },
1646 { 9625, 8500, },
1647 { 9750, 8625, },
1648 { 9875, 8750, },
1649 { 10000, 8875, },
1650 { 10125, 9000, },
1651 { 10250, 9125, },
1652 { 10375, 9250, },
1653 { 10500, 9375, },
1654 { 10625, 9500, },
1655 { 10750, 9625, },
1656 { 10875, 9750, },
1657 { 11000, 9875, },
1658 { 11125, 10000, },
1659 { 11250, 10125, },
1660 { 11375, 10250, },
1661 { 11500, 10375, },
1662 { 11625, 10500, },
1663 { 11750, 10625, },
1664 { 11875, 10750, },
1665 { 12000, 10875, },
1666 { 12125, 11000, },
1667 { 12250, 11125, },
1668 { 12375, 11250, },
1669 { 12500, 11375, },
1670 { 12625, 11500, },
1671 { 12750, 11625, },
1672 { 12875, 11750, },
1673 { 13000, 11875, },
1674 { 13125, 12000, },
1675 { 13250, 12125, },
1676 { 13375, 12250, },
1677 { 13500, 12375, },
1678 { 13625, 12500, },
1679 { 13750, 12625, },
1680 { 13875, 12750, },
1681 { 14000, 12875, },
1682 { 14125, 13000, },
1683 { 14250, 13125, },
1684 { 14375, 13250, },
1685 { 14500, 13375, },
1686 { 14625, 13500, },
1687 { 14750, 13625, },
1688 { 14875, 13750, },
1689 { 15000, 13875, },
1690 { 15125, 14000, },
1691 { 15250, 14125, },
1692 { 15375, 14250, },
1693 { 15500, 14375, },
1694 { 15625, 14500, },
1695 { 15750, 14625, },
1696 { 15875, 14750, },
1697 { 16000, 14875, },
1698 { 16125, 15000, },
1699 };
1700 if (dev_priv->info->is_mobile)
1701 return v_table[pxvid].vm;
1702 else
1703 return v_table[pxvid].vd;
1704}
1705
1706void i915_update_gfx_val(struct drm_i915_private *dev_priv)
1707{
1708 struct timespec now, diff1;
1709 u64 diff;
1710 unsigned long diffms;
1711 u32 count;
1712
1713 if (dev_priv->info->gen != 5)
1714 return;
1715
1716 getrawmonotonic(&now);
1717 diff1 = timespec_sub(now, dev_priv->last_time2);
1718
1719 /* Don't divide by 0 */
1720 diffms = diff1.tv_sec * 1000 + diff1.tv_nsec / 1000000;
1721 if (!diffms)
1722 return;
1723
1724 count = I915_READ(GFXEC);
1725
1726 if (count < dev_priv->last_count2) {
1727 diff = ~0UL - dev_priv->last_count2;
1728 diff += count;
1729 } else {
1730 diff = count - dev_priv->last_count2;
1731 }
1732
1733 dev_priv->last_count2 = count;
1734 dev_priv->last_time2 = now;
1735
1736 /* More magic constants... */
1737 diff = diff * 1181;
1738 diff = div_u64(diff, diffms * 10);
1739 dev_priv->gfx_power = diff;
1740}
1741
1742unsigned long i915_gfx_val(struct drm_i915_private *dev_priv)
1743{
1744 unsigned long t, corr, state1, corr2, state2;
1745 u32 pxvid, ext_v;
1746
1747 pxvid = I915_READ(PXVFREQ_BASE + (dev_priv->cur_delay * 4));
1748 pxvid = (pxvid >> 24) & 0x7f;
1749 ext_v = pvid_to_extvid(dev_priv, pxvid);
1750
1751 state1 = ext_v;
1752
1753 t = i915_mch_val(dev_priv);
1754
1755 /* Revel in the empirically derived constants */
1756
1757 /* Correction factor in 1/100000 units */
1758 if (t > 80)
1759 corr = ((t * 2349) + 135940);
1760 else if (t >= 50)
1761 corr = ((t * 964) + 29317);
1762 else /* < 50 */
1763 corr = ((t * 301) + 1004);
1764
1765 corr = corr * ((150142 * state1) / 10000 - 78642);
1766 corr /= 100000;
1767 corr2 = (corr * dev_priv->corr);
1768
1769 state2 = (corr2 * state1) / 10000;
1770 state2 /= 100; /* convert to mW */
1771
1772 i915_update_gfx_val(dev_priv);
1773
1774 return dev_priv->gfx_power + state2;
1775}
1776
1777/* Global for IPS driver to get at the current i915 device */
1778static struct drm_i915_private *i915_mch_dev;
1779/*
1780 * Lock protecting IPS related data structures
1781 * - i915_mch_dev
1782 * - dev_priv->max_delay
1783 * - dev_priv->min_delay
1784 * - dev_priv->fmax
1785 * - dev_priv->gpu_busy
1786 */
1787static DEFINE_SPINLOCK(mchdev_lock);
1788
1789/**
1790 * i915_read_mch_val - return value for IPS use
1791 *
1792 * Calculate and return a value for the IPS driver to use when deciding whether
1793 * we have thermal and power headroom to increase CPU or GPU power budget.
1794 */
1795unsigned long i915_read_mch_val(void)
1796{
1797 struct drm_i915_private *dev_priv;
1798 unsigned long chipset_val, graphics_val, ret = 0;
1799
1800 spin_lock(&mchdev_lock);
1801 if (!i915_mch_dev)
1802 goto out_unlock;
1803 dev_priv = i915_mch_dev;
1804
1805 chipset_val = i915_chipset_val(dev_priv);
1806 graphics_val = i915_gfx_val(dev_priv);
1807
1808 ret = chipset_val + graphics_val;
1809
1810out_unlock:
1811 spin_unlock(&mchdev_lock);
1812
1813 return ret;
1814}
1815EXPORT_SYMBOL_GPL(i915_read_mch_val);
1816
1817/**
1818 * i915_gpu_raise - raise GPU frequency limit
1819 *
1820 * Raise the limit; IPS indicates we have thermal headroom.
1821 */
1822bool i915_gpu_raise(void)
1823{
1824 struct drm_i915_private *dev_priv;
1825 bool ret = true;
1826
1827 spin_lock(&mchdev_lock);
1828 if (!i915_mch_dev) {
1829 ret = false;
1830 goto out_unlock;
1831 }
1832 dev_priv = i915_mch_dev;
1833
1834 if (dev_priv->max_delay > dev_priv->fmax)
1835 dev_priv->max_delay--;
1836
1837out_unlock:
1838 spin_unlock(&mchdev_lock);
1839
1840 return ret;
1841}
1842EXPORT_SYMBOL_GPL(i915_gpu_raise);
1843
1844/**
1845 * i915_gpu_lower - lower GPU frequency limit
1846 *
1847 * IPS indicates we're close to a thermal limit, so throttle back the GPU
1848 * frequency maximum.
1849 */
1850bool i915_gpu_lower(void)
1851{
1852 struct drm_i915_private *dev_priv;
1853 bool ret = true;
1854
1855 spin_lock(&mchdev_lock);
1856 if (!i915_mch_dev) {
1857 ret = false;
1858 goto out_unlock;
1859 }
1860 dev_priv = i915_mch_dev;
1861
1862 if (dev_priv->max_delay < dev_priv->min_delay)
1863 dev_priv->max_delay++;
1864
1865out_unlock:
1866 spin_unlock(&mchdev_lock);
1867
1868 return ret;
1869}
1870EXPORT_SYMBOL_GPL(i915_gpu_lower);
1871
1872/**
1873 * i915_gpu_busy - indicate GPU business to IPS
1874 *
1875 * Tell the IPS driver whether or not the GPU is busy.
1876 */
1877bool i915_gpu_busy(void)
1878{
1879 struct drm_i915_private *dev_priv;
1880 bool ret = false;
1881
1882 spin_lock(&mchdev_lock);
1883 if (!i915_mch_dev)
1884 goto out_unlock;
1885 dev_priv = i915_mch_dev;
1886
1887 ret = dev_priv->busy;
1888
1889out_unlock:
1890 spin_unlock(&mchdev_lock);
1891
1892 return ret;
1893}
1894EXPORT_SYMBOL_GPL(i915_gpu_busy);
1895
1896/**
1897 * i915_gpu_turbo_disable - disable graphics turbo
1898 *
1899 * Disable graphics turbo by resetting the max frequency and setting the
1900 * current frequency to the default.
1901 */
1902bool i915_gpu_turbo_disable(void)
1903{
1904 struct drm_i915_private *dev_priv;
1905 bool ret = true;
1906
1907 spin_lock(&mchdev_lock);
1908 if (!i915_mch_dev) {
1909 ret = false;
1910 goto out_unlock;
1911 }
1912 dev_priv = i915_mch_dev;
1913
1914 dev_priv->max_delay = dev_priv->fstart;
1915
1916 if (!ironlake_set_drps(dev_priv->dev, dev_priv->fstart))
1917 ret = false;
1918
1919out_unlock:
1920 spin_unlock(&mchdev_lock);
1921
1922 return ret;
1923}
1924EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable);
1925
1926/**
1927 * Tells the intel_ips driver that the i915 driver is now loaded, if
1928 * IPS got loaded first.
1929 *
1930 * This awkward dance is so that neither module has to depend on the
1931 * other in order for IPS to do the appropriate communication of
1932 * GPU turbo limits to i915.
1933 */
1934static void
1935ips_ping_for_i915_load(void)
1936{
1937 void (*link)(void);
1938
1939 link = symbol_get(ips_link_to_i915_driver);
1940 if (link) {
1941 link();
1942 symbol_put(ips_link_to_i915_driver);
1943 }
1944}
1945
1946static void 1482static void
1947i915_mtrr_setup(struct drm_i915_private *dev_priv, unsigned long base, 1483i915_mtrr_setup(struct drm_i915_private *dev_priv, unsigned long base,
1948 unsigned long size) 1484 unsigned long size)
@@ -2152,14 +1688,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
2152 setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, 1688 setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed,
2153 (unsigned long) dev); 1689 (unsigned long) dev);
2154 1690
2155 if (IS_GEN5(dev)) { 1691 if (IS_GEN5(dev))
2156 spin_lock(&mchdev_lock); 1692 intel_gpu_ips_init(dev_priv);
2157 i915_mch_dev = dev_priv;
2158 dev_priv->mchdev_lock = &mchdev_lock;
2159 spin_unlock(&mchdev_lock);
2160
2161 ips_ping_for_i915_load();
2162 }
2163 1693
2164 return 0; 1694 return 0;
2165 1695
@@ -2194,9 +1724,7 @@ int i915_driver_unload(struct drm_device *dev)
2194 struct drm_i915_private *dev_priv = dev->dev_private; 1724 struct drm_i915_private *dev_priv = dev->dev_private;
2195 int ret; 1725 int ret;
2196 1726
2197 spin_lock(&mchdev_lock); 1727 intel_gpu_ips_teardown();
2198 i915_mch_dev = NULL;
2199 spin_unlock(&mchdev_lock);
2200 1728
2201 i915_teardown_sysfs(dev); 1729 i915_teardown_sysfs(dev);
2202 1730
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4b7ec449d3cc..f4f1e8bba535 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -462,5 +462,8 @@ extern void intel_init_pm(struct drm_device *dev);
462extern bool intel_fbc_enabled(struct drm_device *dev); 462extern bool intel_fbc_enabled(struct drm_device *dev);
463extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); 463extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval);
464extern void intel_update_fbc(struct drm_device *dev); 464extern void intel_update_fbc(struct drm_device *dev);
465/* IPS */
466extern void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
467extern void intel_gpu_ips_teardown(void);
465 468
466#endif /* __INTEL_DRV_H__ */ 469#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 0a3699908fdf..e0f016c24dce 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -28,6 +28,8 @@
28#include <linux/cpufreq.h> 28#include <linux/cpufreq.h>
29#include "i915_drv.h" 29#include "i915_drv.h"
30#include "intel_drv.h" 30#include "intel_drv.h"
31#include "../../../platform/x86/intel_ips.h"
32#include <linux/module.h>
31 33
32/* FBC, or Frame Buffer Compression, is a technique employed to compress the 34/* FBC, or Frame Buffer Compression, is a technique employed to compress the
33 * framebuffer contents in-memory, aiming at reducing the required bandwidth 35 * framebuffer contents in-memory, aiming at reducing the required bandwidth
@@ -2508,6 +2510,485 @@ static unsigned long intel_pxfreq(u32 vidfreq)
2508 return freq; 2510 return freq;
2509} 2511}
2510 2512
2513static const struct cparams {
2514 u16 i;
2515 u16 t;
2516 u16 m;
2517 u16 c;
2518} cparams[] = {
2519 { 1, 1333, 301, 28664 },
2520 { 1, 1066, 294, 24460 },
2521 { 1, 800, 294, 25192 },
2522 { 0, 1333, 276, 27605 },
2523 { 0, 1066, 276, 27605 },
2524 { 0, 800, 231, 23784 },
2525};
2526
2527unsigned long i915_chipset_val(struct drm_i915_private *dev_priv)
2528{
2529 u64 total_count, diff, ret;
2530 u32 count1, count2, count3, m = 0, c = 0;
2531 unsigned long now = jiffies_to_msecs(jiffies), diff1;
2532 int i;
2533
2534 diff1 = now - dev_priv->last_time1;
2535
2536 /* Prevent division-by-zero if we are asking too fast.
2537 * Also, we don't get interesting results if we are polling
2538 * faster than once in 10ms, so just return the saved value
2539 * in such cases.
2540 */
2541 if (diff1 <= 10)
2542 return dev_priv->chipset_power;
2543
2544 count1 = I915_READ(DMIEC);
2545 count2 = I915_READ(DDREC);
2546 count3 = I915_READ(CSIEC);
2547
2548 total_count = count1 + count2 + count3;
2549
2550 /* FIXME: handle per-counter overflow */
2551 if (total_count < dev_priv->last_count1) {
2552 diff = ~0UL - dev_priv->last_count1;
2553 diff += total_count;
2554 } else {
2555 diff = total_count - dev_priv->last_count1;
2556 }
2557
2558 for (i = 0; i < ARRAY_SIZE(cparams); i++) {
2559 if (cparams[i].i == dev_priv->c_m &&
2560 cparams[i].t == dev_priv->r_t) {
2561 m = cparams[i].m;
2562 c = cparams[i].c;
2563 break;
2564 }
2565 }
2566
2567 diff = div_u64(diff, diff1);
2568 ret = ((m * diff) + c);
2569 ret = div_u64(ret, 10);
2570
2571 dev_priv->last_count1 = total_count;
2572 dev_priv->last_time1 = now;
2573
2574 dev_priv->chipset_power = ret;
2575
2576 return ret;
2577}
2578
2579unsigned long i915_mch_val(struct drm_i915_private *dev_priv)
2580{
2581 unsigned long m, x, b;
2582 u32 tsfs;
2583
2584 tsfs = I915_READ(TSFS);
2585
2586 m = ((tsfs & TSFS_SLOPE_MASK) >> TSFS_SLOPE_SHIFT);
2587 x = I915_READ8(TR1);
2588
2589 b = tsfs & TSFS_INTR_MASK;
2590
2591 return ((m * x) / 127) - b;
2592}
2593
2594static u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid)
2595{
2596 static const struct v_table {
2597 u16 vd; /* in .1 mil */
2598 u16 vm; /* in .1 mil */
2599 } v_table[] = {
2600 { 0, 0, },
2601 { 375, 0, },
2602 { 500, 0, },
2603 { 625, 0, },
2604 { 750, 0, },
2605 { 875, 0, },
2606 { 1000, 0, },
2607 { 1125, 0, },
2608 { 4125, 3000, },
2609 { 4125, 3000, },
2610 { 4125, 3000, },
2611 { 4125, 3000, },
2612 { 4125, 3000, },
2613 { 4125, 3000, },
2614 { 4125, 3000, },
2615 { 4125, 3000, },
2616 { 4125, 3000, },
2617 { 4125, 3000, },
2618 { 4125, 3000, },
2619 { 4125, 3000, },
2620 { 4125, 3000, },
2621 { 4125, 3000, },
2622 { 4125, 3000, },
2623 { 4125, 3000, },
2624 { 4125, 3000, },
2625 { 4125, 3000, },
2626 { 4125, 3000, },
2627 { 4125, 3000, },
2628 { 4125, 3000, },
2629 { 4125, 3000, },
2630 { 4125, 3000, },
2631 { 4125, 3000, },
2632 { 4250, 3125, },
2633 { 4375, 3250, },
2634 { 4500, 3375, },
2635 { 4625, 3500, },
2636 { 4750, 3625, },
2637 { 4875, 3750, },
2638 { 5000, 3875, },
2639 { 5125, 4000, },
2640 { 5250, 4125, },
2641 { 5375, 4250, },
2642 { 5500, 4375, },
2643 { 5625, 4500, },
2644 { 5750, 4625, },
2645 { 5875, 4750, },
2646 { 6000, 4875, },
2647 { 6125, 5000, },
2648 { 6250, 5125, },
2649 { 6375, 5250, },
2650 { 6500, 5375, },
2651 { 6625, 5500, },
2652 { 6750, 5625, },
2653 { 6875, 5750, },
2654 { 7000, 5875, },
2655 { 7125, 6000, },
2656 { 7250, 6125, },
2657 { 7375, 6250, },
2658 { 7500, 6375, },
2659 { 7625, 6500, },
2660 { 7750, 6625, },
2661 { 7875, 6750, },
2662 { 8000, 6875, },
2663 { 8125, 7000, },
2664 { 8250, 7125, },
2665 { 8375, 7250, },
2666 { 8500, 7375, },
2667 { 8625, 7500, },
2668 { 8750, 7625, },
2669 { 8875, 7750, },
2670 { 9000, 7875, },
2671 { 9125, 8000, },
2672 { 9250, 8125, },
2673 { 9375, 8250, },
2674 { 9500, 8375, },
2675 { 9625, 8500, },
2676 { 9750, 8625, },
2677 { 9875, 8750, },
2678 { 10000, 8875, },
2679 { 10125, 9000, },
2680 { 10250, 9125, },
2681 { 10375, 9250, },
2682 { 10500, 9375, },
2683 { 10625, 9500, },
2684 { 10750, 9625, },
2685 { 10875, 9750, },
2686 { 11000, 9875, },
2687 { 11125, 10000, },
2688 { 11250, 10125, },
2689 { 11375, 10250, },
2690 { 11500, 10375, },
2691 { 11625, 10500, },
2692 { 11750, 10625, },
2693 { 11875, 10750, },
2694 { 12000, 10875, },
2695 { 12125, 11000, },
2696 { 12250, 11125, },
2697 { 12375, 11250, },
2698 { 12500, 11375, },
2699 { 12625, 11500, },
2700 { 12750, 11625, },
2701 { 12875, 11750, },
2702 { 13000, 11875, },
2703 { 13125, 12000, },
2704 { 13250, 12125, },
2705 { 13375, 12250, },
2706 { 13500, 12375, },
2707 { 13625, 12500, },
2708 { 13750, 12625, },
2709 { 13875, 12750, },
2710 { 14000, 12875, },
2711 { 14125, 13000, },
2712 { 14250, 13125, },
2713 { 14375, 13250, },
2714 { 14500, 13375, },
2715 { 14625, 13500, },
2716 { 14750, 13625, },
2717 { 14875, 13750, },
2718 { 15000, 13875, },
2719 { 15125, 14000, },
2720 { 15250, 14125, },
2721 { 15375, 14250, },
2722 { 15500, 14375, },
2723 { 15625, 14500, },
2724 { 15750, 14625, },
2725 { 15875, 14750, },
2726 { 16000, 14875, },
2727 { 16125, 15000, },
2728 };
2729 if (dev_priv->info->is_mobile)
2730 return v_table[pxvid].vm;
2731 else
2732 return v_table[pxvid].vd;
2733}
2734
2735void i915_update_gfx_val(struct drm_i915_private *dev_priv)
2736{
2737 struct timespec now, diff1;
2738 u64 diff;
2739 unsigned long diffms;
2740 u32 count;
2741
2742 if (dev_priv->info->gen != 5)
2743 return;
2744
2745 getrawmonotonic(&now);
2746 diff1 = timespec_sub(now, dev_priv->last_time2);
2747
2748 /* Don't divide by 0 */
2749 diffms = diff1.tv_sec * 1000 + diff1.tv_nsec / 1000000;
2750 if (!diffms)
2751 return;
2752
2753 count = I915_READ(GFXEC);
2754
2755 if (count < dev_priv->last_count2) {
2756 diff = ~0UL - dev_priv->last_count2;
2757 diff += count;
2758 } else {
2759 diff = count - dev_priv->last_count2;
2760 }
2761
2762 dev_priv->last_count2 = count;
2763 dev_priv->last_time2 = now;
2764
2765 /* More magic constants... */
2766 diff = diff * 1181;
2767 diff = div_u64(diff, diffms * 10);
2768 dev_priv->gfx_power = diff;
2769}
2770
2771unsigned long i915_gfx_val(struct drm_i915_private *dev_priv)
2772{
2773 unsigned long t, corr, state1, corr2, state2;
2774 u32 pxvid, ext_v;
2775
2776 pxvid = I915_READ(PXVFREQ_BASE + (dev_priv->cur_delay * 4));
2777 pxvid = (pxvid >> 24) & 0x7f;
2778 ext_v = pvid_to_extvid(dev_priv, pxvid);
2779
2780 state1 = ext_v;
2781
2782 t = i915_mch_val(dev_priv);
2783
2784 /* Revel in the empirically derived constants */
2785
2786 /* Correction factor in 1/100000 units */
2787 if (t > 80)
2788 corr = ((t * 2349) + 135940);
2789 else if (t >= 50)
2790 corr = ((t * 964) + 29317);
2791 else /* < 50 */
2792 corr = ((t * 301) + 1004);
2793
2794 corr = corr * ((150142 * state1) / 10000 - 78642);
2795 corr /= 100000;
2796 corr2 = (corr * dev_priv->corr);
2797
2798 state2 = (corr2 * state1) / 10000;
2799 state2 /= 100; /* convert to mW */
2800
2801 i915_update_gfx_val(dev_priv);
2802
2803 return dev_priv->gfx_power + state2;
2804}
2805
2806/* Global for IPS driver to get at the current i915 device */
2807static struct drm_i915_private *i915_mch_dev;
2808/*
2809 * Lock protecting IPS related data structures
2810 * - i915_mch_dev
2811 * - dev_priv->max_delay
2812 * - dev_priv->min_delay
2813 * - dev_priv->fmax
2814 * - dev_priv->gpu_busy
2815 */
2816static DEFINE_SPINLOCK(mchdev_lock);
2817
2818/**
2819 * i915_read_mch_val - return value for IPS use
2820 *
2821 * Calculate and return a value for the IPS driver to use when deciding whether
2822 * we have thermal and power headroom to increase CPU or GPU power budget.
2823 */
2824unsigned long i915_read_mch_val(void)
2825{
2826 struct drm_i915_private *dev_priv;
2827 unsigned long chipset_val, graphics_val, ret = 0;
2828
2829 spin_lock(&mchdev_lock);
2830 if (!i915_mch_dev)
2831 goto out_unlock;
2832 dev_priv = i915_mch_dev;
2833
2834 chipset_val = i915_chipset_val(dev_priv);
2835 graphics_val = i915_gfx_val(dev_priv);
2836
2837 ret = chipset_val + graphics_val;
2838
2839out_unlock:
2840 spin_unlock(&mchdev_lock);
2841
2842 return ret;
2843}
2844EXPORT_SYMBOL_GPL(i915_read_mch_val);
2845
2846/**
2847 * i915_gpu_raise - raise GPU frequency limit
2848 *
2849 * Raise the limit; IPS indicates we have thermal headroom.
2850 */
2851bool i915_gpu_raise(void)
2852{
2853 struct drm_i915_private *dev_priv;
2854 bool ret = true;
2855
2856 spin_lock(&mchdev_lock);
2857 if (!i915_mch_dev) {
2858 ret = false;
2859 goto out_unlock;
2860 }
2861 dev_priv = i915_mch_dev;
2862
2863 if (dev_priv->max_delay > dev_priv->fmax)
2864 dev_priv->max_delay--;
2865
2866out_unlock:
2867 spin_unlock(&mchdev_lock);
2868
2869 return ret;
2870}
2871EXPORT_SYMBOL_GPL(i915_gpu_raise);
2872
2873/**
2874 * i915_gpu_lower - lower GPU frequency limit
2875 *
2876 * IPS indicates we're close to a thermal limit, so throttle back the GPU
2877 * frequency maximum.
2878 */
2879bool i915_gpu_lower(void)
2880{
2881 struct drm_i915_private *dev_priv;
2882 bool ret = true;
2883
2884 spin_lock(&mchdev_lock);
2885 if (!i915_mch_dev) {
2886 ret = false;
2887 goto out_unlock;
2888 }
2889 dev_priv = i915_mch_dev;
2890
2891 if (dev_priv->max_delay < dev_priv->min_delay)
2892 dev_priv->max_delay++;
2893
2894out_unlock:
2895 spin_unlock(&mchdev_lock);
2896
2897 return ret;
2898}
2899EXPORT_SYMBOL_GPL(i915_gpu_lower);
2900
2901/**
2902 * i915_gpu_busy - indicate GPU business to IPS
2903 *
2904 * Tell the IPS driver whether or not the GPU is busy.
2905 */
2906bool i915_gpu_busy(void)
2907{
2908 struct drm_i915_private *dev_priv;
2909 bool ret = false;
2910
2911 spin_lock(&mchdev_lock);
2912 if (!i915_mch_dev)
2913 goto out_unlock;
2914 dev_priv = i915_mch_dev;
2915
2916 ret = dev_priv->busy;
2917
2918out_unlock:
2919 spin_unlock(&mchdev_lock);
2920
2921 return ret;
2922}
2923EXPORT_SYMBOL_GPL(i915_gpu_busy);
2924
2925/**
2926 * i915_gpu_turbo_disable - disable graphics turbo
2927 *
2928 * Disable graphics turbo by resetting the max frequency and setting the
2929 * current frequency to the default.
2930 */
2931bool i915_gpu_turbo_disable(void)
2932{
2933 struct drm_i915_private *dev_priv;
2934 bool ret = true;
2935
2936 spin_lock(&mchdev_lock);
2937 if (!i915_mch_dev) {
2938 ret = false;
2939 goto out_unlock;
2940 }
2941 dev_priv = i915_mch_dev;
2942
2943 dev_priv->max_delay = dev_priv->fstart;
2944
2945 if (!ironlake_set_drps(dev_priv->dev, dev_priv->fstart))
2946 ret = false;
2947
2948out_unlock:
2949 spin_unlock(&mchdev_lock);
2950
2951 return ret;
2952}
2953EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable);
2954
2955/**
2956 * Tells the intel_ips driver that the i915 driver is now loaded, if
2957 * IPS got loaded first.
2958 *
2959 * This awkward dance is so that neither module has to depend on the
2960 * other in order for IPS to do the appropriate communication of
2961 * GPU turbo limits to i915.
2962 */
2963static void
2964ips_ping_for_i915_load(void)
2965{
2966 void (*link)(void);
2967
2968 link = symbol_get(ips_link_to_i915_driver);
2969 if (link) {
2970 link();
2971 symbol_put(ips_link_to_i915_driver);
2972 }
2973}
2974
2975void intel_gpu_ips_init(struct drm_i915_private *dev_priv)
2976{
2977 spin_lock(&mchdev_lock);
2978 i915_mch_dev = dev_priv;
2979 dev_priv->mchdev_lock = &mchdev_lock;
2980 spin_unlock(&mchdev_lock);
2981
2982 ips_ping_for_i915_load();
2983}
2984
2985void intel_gpu_ips_teardown(void)
2986{
2987 spin_lock(&mchdev_lock);
2988 i915_mch_dev = NULL;
2989 spin_unlock(&mchdev_lock);
2990}
2991
2511void intel_init_emon(struct drm_device *dev) 2992void intel_init_emon(struct drm_device *dev)
2512{ 2993{
2513 struct drm_i915_private *dev_priv = dev->dev_private; 2994 struct drm_i915_private *dev_priv = dev->dev_private;