aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h2
-rw-r--r--drivers/gpu/drm/i915/intel_display.c186
2 files changed, 113 insertions, 75 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 6c0858484094..897a116cad14 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1618,7 +1618,7 @@
1618#define I830_FIFO_LINE_SIZE 32 1618#define I830_FIFO_LINE_SIZE 32
1619#define I945_FIFO_SIZE 127 /* 945 & 965 */ 1619#define I945_FIFO_SIZE 127 /* 945 & 965 */
1620#define I915_FIFO_SIZE 95 1620#define I915_FIFO_SIZE 95
1621#define I855GM_FIFO_SIZE 255 1621#define I855GM_FIFO_SIZE 127 /* In cachelines */
1622#define I830_FIFO_SIZE 95 1622#define I830_FIFO_SIZE 95
1623#define I915_MAX_WM 0x3f 1623#define I915_MAX_WM 0x3f
1624 1624
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 984645e26a2d..3fa0d63c83b9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1623,44 +1623,67 @@ static struct intel_watermark_params igd_cursor_hplloff_wm = {
1623 IGD_FIFO_LINE_SIZE 1623 IGD_FIFO_LINE_SIZE
1624}; 1624};
1625static struct intel_watermark_params i945_wm_info = { 1625static struct intel_watermark_params i945_wm_info = {
1626 I915_FIFO_LINE_SIZE, 1626 I945_FIFO_SIZE,
1627 I915_MAX_WM, 1627 I915_MAX_WM,
1628 1, 1628 1,
1629 0, 1629 2,
1630 IGD_FIFO_LINE_SIZE 1630 I915_FIFO_LINE_SIZE
1631}; 1631};
1632static struct intel_watermark_params i915_wm_info = { 1632static struct intel_watermark_params i915_wm_info = {
1633 I945_FIFO_SIZE, 1633 I915_FIFO_SIZE,
1634 I915_MAX_WM, 1634 I915_MAX_WM,
1635 1, 1635 1,
1636 0, 1636 2,
1637 I915_FIFO_LINE_SIZE 1637 I915_FIFO_LINE_SIZE
1638}; 1638};
1639static struct intel_watermark_params i855_wm_info = { 1639static struct intel_watermark_params i855_wm_info = {
1640 I855GM_FIFO_SIZE, 1640 I855GM_FIFO_SIZE,
1641 I915_MAX_WM, 1641 I915_MAX_WM,
1642 1, 1642 1,
1643 0, 1643 2,
1644 I830_FIFO_LINE_SIZE 1644 I830_FIFO_LINE_SIZE
1645}; 1645};
1646static struct intel_watermark_params i830_wm_info = { 1646static struct intel_watermark_params i830_wm_info = {
1647 I830_FIFO_SIZE, 1647 I830_FIFO_SIZE,
1648 I915_MAX_WM, 1648 I915_MAX_WM,
1649 1, 1649 1,
1650 0, 1650 2,
1651 I830_FIFO_LINE_SIZE 1651 I830_FIFO_LINE_SIZE
1652}; 1652};
1653 1653
1654/**
1655 * intel_calculate_wm - calculate watermark level
1656 * @clock_in_khz: pixel clock
1657 * @wm: chip FIFO params
1658 * @pixel_size: display pixel size
1659 * @latency_ns: memory latency for the platform
1660 *
1661 * Calculate the watermark level (the level at which the display plane will
1662 * start fetching from memory again). Each chip has a different display
1663 * FIFO size and allocation, so the caller needs to figure that out and pass
1664 * in the correct intel_watermark_params structure.
1665 *
1666 * As the pixel clock runs, the FIFO will be drained at a rate that depends
1667 * on the pixel size. When it reaches the watermark level, it'll start
1668 * fetching FIFO line sized based chunks from memory until the FIFO fills
1669 * past the watermark point. If the FIFO drains completely, a FIFO underrun
1670 * will occur, and a display engine hang could result.
1671 */
1654static unsigned long intel_calculate_wm(unsigned long clock_in_khz, 1672static unsigned long intel_calculate_wm(unsigned long clock_in_khz,
1655 struct intel_watermark_params *wm, 1673 struct intel_watermark_params *wm,
1656 int pixel_size, 1674 int pixel_size,
1657 unsigned long latency_ns) 1675 unsigned long latency_ns)
1658{ 1676{
1659 unsigned long bytes_required, wm_size; 1677 unsigned long entries_required, wm_size;
1678
1679 entries_required = (clock_in_khz * pixel_size * latency_ns) / 1000000;
1680 entries_required /= wm->cacheline_size;
1681
1682 DRM_DEBUG("FIFO entries required for mode: %d\n", entries_required);
1660 1683
1661 bytes_required = (clock_in_khz * pixel_size * latency_ns) / 1000000; 1684 wm_size = wm->fifo_size - (entries_required + wm->guard_size);
1662 bytes_required /= wm->cacheline_size; 1685
1663 wm_size = wm->fifo_size - bytes_required - wm->guard_size; 1686 DRM_DEBUG("FIFO watermark level: %d\n", wm_size);
1664 1687
1665 if (wm_size > wm->max_wm) 1688 if (wm_size > wm->max_wm)
1666 wm_size = wm->max_wm; 1689 wm_size = wm->max_wm;
@@ -1799,8 +1822,37 @@ static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock,
1799 return; 1822 return;
1800} 1823}
1801 1824
1802const static int latency_ns = 5000; /* default for non-igd platforms */ 1825const static int latency_ns = 3000; /* default for non-igd platforms */
1826
1827static int intel_get_fifo_size(struct drm_device *dev, int plane)
1828{
1829 struct drm_i915_private *dev_priv = dev->dev_private;
1830 uint32_t dsparb = I915_READ(DSPARB);
1831 int size;
1832
1833 if (IS_I9XX(dev)) {
1834 if (plane == 0)
1835 size = dsparb & 0x7f;
1836 else
1837 size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) -
1838 (dsparb & 0x7f);
1839 } else if (IS_I85X(dev)) {
1840 if (plane == 0)
1841 size = dsparb & 0x1ff;
1842 else
1843 size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) -
1844 (dsparb & 0x1ff);
1845 size >>= 1; /* Convert to cachelines */
1846 } else {
1847 size = dsparb & 0x7f;
1848 size >>= 1; /* Convert to cachelines */
1849 }
1850
1851 DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A",
1852 size);
1803 1853
1854 return size;
1855}
1804 1856
1805static void i965_update_wm(struct drm_device *dev) 1857static void i965_update_wm(struct drm_device *dev)
1806{ 1858{
@@ -1817,101 +1869,87 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
1817 int planeb_clock, int sr_hdisplay, int pixel_size) 1869 int planeb_clock, int sr_hdisplay, int pixel_size)
1818{ 1870{
1819 struct drm_i915_private *dev_priv = dev->dev_private; 1871 struct drm_i915_private *dev_priv = dev->dev_private;
1820 uint32_t fwater_lo = I915_READ(FW_BLC) & MM_FIFO_WATERMARK; 1872 uint32_t fwater_lo;
1821 uint32_t fwater_hi = I915_READ(FW_BLC2) & LM_FIFO_WATERMARK; 1873 uint32_t fwater_hi;
1822 int bsize, asize, cwm, bwm = 1, awm = 1, srwm = 1; 1874 int total_size, cacheline_size, cwm, srwm = 1;
1823 uint32_t dsparb = I915_READ(DSPARB); 1875 int planea_wm, planeb_wm;
1824 int planea_entries, planeb_entries; 1876 struct intel_watermark_params planea_params, planeb_params;
1825 struct intel_watermark_params *wm_params;
1826 unsigned long line_time_us; 1877 unsigned long line_time_us;
1827 int sr_clock, sr_entries = 0; 1878 int sr_clock, sr_entries = 0;
1828 1879
1880 /* Create copies of the base settings for each pipe */
1829 if (IS_I965GM(dev) || IS_I945GM(dev)) 1881 if (IS_I965GM(dev) || IS_I945GM(dev))
1830 wm_params = &i945_wm_info; 1882 planea_params = planeb_params = i945_wm_info;
1831 else if (IS_I9XX(dev)) 1883 else if (IS_I9XX(dev))
1832 wm_params = &i915_wm_info; 1884 planea_params = planeb_params = i915_wm_info;
1833 else 1885 else
1834 wm_params = &i855_wm_info; 1886 planea_params = planeb_params = i855_wm_info;
1835
1836 planea_entries = intel_calculate_wm(planea_clock, wm_params,
1837 pixel_size, latency_ns);
1838 planeb_entries = intel_calculate_wm(planeb_clock, wm_params,
1839 pixel_size, latency_ns);
1840 1887
1841 DRM_DEBUG("FIFO entries - A: %d, B: %d\n", planea_entries, 1888 /* Grab a couple of global values before we overwrite them */
1842 planeb_entries); 1889 total_size = planea_params.fifo_size;
1890 cacheline_size = planea_params.cacheline_size;
1843 1891
1844 if (IS_I9XX(dev)) { 1892 /* Update per-plane FIFO sizes */
1845 asize = dsparb & 0x7f; 1893 planea_params.fifo_size = intel_get_fifo_size(dev, 0);
1846 bsize = (dsparb >> DSPARB_CSTART_SHIFT) & 0x7f; 1894 planeb_params.fifo_size = intel_get_fifo_size(dev, 1);
1847 } else {
1848 asize = dsparb & 0x1ff;
1849 bsize = (dsparb >> DSPARB_BEND_SHIFT) & 0x1ff;
1850 }
1851 DRM_DEBUG("FIFO size - A: %d, B: %d\n", asize, bsize);
1852 1895
1853 /* Two extra entries for padding */ 1896 planea_wm = intel_calculate_wm(planea_clock, &planea_params,
1854 awm = asize - (planea_entries + 2); 1897 pixel_size, latency_ns);
1855 bwm = bsize - (planeb_entries + 2); 1898 planeb_wm = intel_calculate_wm(planeb_clock, &planeb_params,
1856 1899 pixel_size, latency_ns);
1857 /* Sanity check against potentially bad FIFO allocations */ 1900 DRM_DEBUG("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
1858 if (awm <= 0) {
1859 /* pipe is on but has too few FIFO entries */
1860 if (planea_entries != 0)
1861 DRM_DEBUG("plane A needs more FIFO entries\n");
1862 awm = 1;
1863 }
1864 if (bwm <= 0) {
1865 if (planeb_entries != 0)
1866 DRM_DEBUG("plane B needs more FIFO entries\n");
1867 bwm = 1;
1868 }
1869 1901
1870 /* 1902 /*
1871 * Overlay gets an aggressive default since video jitter is bad. 1903 * Overlay gets an aggressive default since video jitter is bad.
1872 */ 1904 */
1873 cwm = 2; 1905 cwm = 2;
1874 1906
1875 /* Calc sr entries for one pipe configs */ 1907 /* Calc sr entries for one plane configs */
1876 if (!planea_clock || !planeb_clock) { 1908 if (!planea_clock || !planeb_clock) {
1909 /* self-refresh has much higher latency */
1910 const static int sr_latency_ns = 6000;
1911
1877 sr_clock = planea_clock ? planea_clock : planeb_clock; 1912 sr_clock = planea_clock ? planea_clock : planeb_clock;
1878 line_time_us = (sr_hdisplay * 1000) / sr_clock; 1913 line_time_us = ((sr_hdisplay * 1000) / sr_clock);
1879 sr_entries = (((latency_ns / line_time_us) + 1) * pixel_size * 1914
1880 sr_hdisplay) / 1000; 1915 /* Use ns/us then divide to preserve precision */
1881 sr_entries = roundup(sr_entries / wm_params->cacheline_size, 1); 1916 sr_entries = (((sr_latency_ns / line_time_us) + 1) *
1882 if (sr_entries < wm_params->fifo_size) 1917 pixel_size * sr_hdisplay) / 1000;
1883 srwm = wm_params->fifo_size - sr_entries; 1918 sr_entries = roundup(sr_entries / cacheline_size, 1);
1919 DRM_DEBUG("self-refresh entries: %d\n", sr_entries);
1920 srwm = total_size - sr_entries;
1921 if (srwm < 0)
1922 srwm = 1;
1884 } 1923 }
1885 1924
1886 DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", 1925 DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n",
1887 awm, bwm, cwm, srwm); 1926 planea_wm, planeb_wm, cwm, srwm);
1888 1927
1889 fwater_lo = fwater_lo | ((bwm & 0x3f) << 16) | (awm & 0x3f); 1928 fwater_lo = ((planeb_wm & 0x3f) << 16) | (planea_wm & 0x3f);
1890 fwater_hi = fwater_hi | (cwm & 0x1f); 1929 fwater_hi = (cwm & 0x1f);
1930
1931 /* Set request length to 8 cachelines per fetch */
1932 fwater_lo = fwater_lo | (1 << 24) | (1 << 8);
1933 fwater_hi = fwater_hi | (1 << 8);
1891 1934
1892 I915_WRITE(FW_BLC, fwater_lo); 1935 I915_WRITE(FW_BLC, fwater_lo);
1893 I915_WRITE(FW_BLC2, fwater_hi); 1936 I915_WRITE(FW_BLC2, fwater_hi);
1894 if (IS_I9XX(dev)) 1937 if (IS_I9XX(dev))
1895 I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f)); 1938 I915_WRITE(FW_BLC_SELF, (srwm & 0x3f));
1896} 1939}
1897 1940
1898static void i830_update_wm(struct drm_device *dev, int planea_clock, 1941static void i830_update_wm(struct drm_device *dev, int planea_clock,
1899 int pixel_size) 1942 int pixel_size)
1900{ 1943{
1901 struct drm_i915_private *dev_priv = dev->dev_private; 1944 struct drm_i915_private *dev_priv = dev->dev_private;
1902 uint32_t dsparb = I915_READ(DSPARB);
1903 uint32_t fwater_lo = I915_READ(FW_BLC) & MM_FIFO_WATERMARK; 1945 uint32_t fwater_lo = I915_READ(FW_BLC) & MM_FIFO_WATERMARK;
1904 unsigned int asize, awm; 1946 int planea_wm;
1905 int planea_entries;
1906
1907 planea_entries = intel_calculate_wm(planea_clock, &i830_wm_info,
1908 pixel_size, latency_ns);
1909
1910 asize = dsparb & 0x7f;
1911 1947
1912 awm = asize - planea_entries; 1948 i830_wm_info.fifo_size = intel_get_fifo_size(dev, 0);
1913 1949
1914 fwater_lo = fwater_lo | awm; 1950 planea_wm = intel_calculate_wm(planea_clock, &i830_wm_info,
1951 pixel_size, latency_ns);
1952 fwater_lo = fwater_lo | planea_wm;
1915 1953
1916 I915_WRITE(FW_BLC, fwater_lo); 1954 I915_WRITE(FW_BLC, fwater_lo);
1917} 1955}
@@ -1984,7 +2022,7 @@ static void intel_update_watermarks(struct drm_device *dev)
1984 if (enabled <= 0) 2022 if (enabled <= 0)
1985 return; 2023 return;
1986 2024
1987 /* Single pipe configs can enable self refresh */ 2025 /* Single plane configs can enable self refresh */
1988 if (enabled == 1 && IS_IGD(dev)) 2026 if (enabled == 1 && IS_IGD(dev))
1989 igd_enable_cxsr(dev, sr_clock, pixel_size); 2027 igd_enable_cxsr(dev, sr_clock, pixel_size);
1990 else if (IS_IGD(dev)) 2028 else if (IS_IGD(dev))