diff options
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 66 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 242 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 171 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 56 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_sysfs.c | 127 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_trace.h | 28 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 47 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 53 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 318 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_overlay.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_panel.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 56 |
17 files changed, 955 insertions, 255 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 5363e9c66c27..4fa00fcfbc96 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -1765,6 +1765,64 @@ static const struct file_operations i915_max_freq_fops = { | |||
1765 | }; | 1765 | }; |
1766 | 1766 | ||
1767 | static ssize_t | 1767 | static ssize_t |
1768 | i915_min_freq_read(struct file *filp, char __user *ubuf, size_t max, | ||
1769 | loff_t *ppos) | ||
1770 | { | ||
1771 | struct drm_device *dev = filp->private_data; | ||
1772 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1773 | char buf[80]; | ||
1774 | int len; | ||
1775 | |||
1776 | len = snprintf(buf, sizeof(buf), | ||
1777 | "min freq: %d\n", dev_priv->min_delay * 50); | ||
1778 | |||
1779 | if (len > sizeof(buf)) | ||
1780 | len = sizeof(buf); | ||
1781 | |||
1782 | return simple_read_from_buffer(ubuf, max, ppos, buf, len); | ||
1783 | } | ||
1784 | |||
1785 | static ssize_t | ||
1786 | i915_min_freq_write(struct file *filp, const char __user *ubuf, size_t cnt, | ||
1787 | loff_t *ppos) | ||
1788 | { | ||
1789 | struct drm_device *dev = filp->private_data; | ||
1790 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1791 | char buf[20]; | ||
1792 | int val = 1; | ||
1793 | |||
1794 | if (cnt > 0) { | ||
1795 | if (cnt > sizeof(buf) - 1) | ||
1796 | return -EINVAL; | ||
1797 | |||
1798 | if (copy_from_user(buf, ubuf, cnt)) | ||
1799 | return -EFAULT; | ||
1800 | buf[cnt] = 0; | ||
1801 | |||
1802 | val = simple_strtoul(buf, NULL, 0); | ||
1803 | } | ||
1804 | |||
1805 | DRM_DEBUG_DRIVER("Manually setting min freq to %d\n", val); | ||
1806 | |||
1807 | /* | ||
1808 | * Turbo will still be enabled, but won't go below the set value. | ||
1809 | */ | ||
1810 | dev_priv->min_delay = val / 50; | ||
1811 | |||
1812 | gen6_set_rps(dev, val / 50); | ||
1813 | |||
1814 | return cnt; | ||
1815 | } | ||
1816 | |||
1817 | static const struct file_operations i915_min_freq_fops = { | ||
1818 | .owner = THIS_MODULE, | ||
1819 | .open = simple_open, | ||
1820 | .read = i915_min_freq_read, | ||
1821 | .write = i915_min_freq_write, | ||
1822 | .llseek = default_llseek, | ||
1823 | }; | ||
1824 | |||
1825 | static ssize_t | ||
1768 | i915_cache_sharing_read(struct file *filp, | 1826 | i915_cache_sharing_read(struct file *filp, |
1769 | char __user *ubuf, | 1827 | char __user *ubuf, |
1770 | size_t max, | 1828 | size_t max, |
@@ -1997,6 +2055,12 @@ int i915_debugfs_init(struct drm_minor *minor) | |||
1997 | return ret; | 2055 | return ret; |
1998 | 2056 | ||
1999 | ret = i915_debugfs_create(minor->debugfs_root, minor, | 2057 | ret = i915_debugfs_create(minor->debugfs_root, minor, |
2058 | "i915_min_freq", | ||
2059 | &i915_min_freq_fops); | ||
2060 | if (ret) | ||
2061 | return ret; | ||
2062 | |||
2063 | ret = i915_debugfs_create(minor->debugfs_root, minor, | ||
2000 | "i915_cache_sharing", | 2064 | "i915_cache_sharing", |
2001 | &i915_cache_sharing_fops); | 2065 | &i915_cache_sharing_fops); |
2002 | if (ret) | 2066 | if (ret) |
@@ -2028,6 +2092,8 @@ void i915_debugfs_cleanup(struct drm_minor *minor) | |||
2028 | 1, minor); | 2092 | 1, minor); |
2029 | drm_debugfs_remove_files((struct drm_info_list *) &i915_max_freq_fops, | 2093 | drm_debugfs_remove_files((struct drm_info_list *) &i915_max_freq_fops, |
2030 | 1, minor); | 2094 | 1, minor); |
2095 | drm_debugfs_remove_files((struct drm_info_list *) &i915_min_freq_fops, | ||
2096 | 1, minor); | ||
2031 | drm_debugfs_remove_files((struct drm_info_list *) &i915_cache_sharing_fops, | 2097 | drm_debugfs_remove_files((struct drm_info_list *) &i915_cache_sharing_fops, |
2032 | 1, minor); | 2098 | 1, minor); |
2033 | drm_debugfs_remove_files((struct drm_info_list *) &i915_ring_stop_fops, | 2099 | drm_debugfs_remove_files((struct drm_info_list *) &i915_ring_stop_fops, |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index f94792626b94..262a74d1f852 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1803,6 +1803,7 @@ struct drm_ioctl_desc i915_ioctls[] = { | |||
1803 | DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 1803 | DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
1804 | DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 1804 | DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
1805 | DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, intel_sprite_get_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 1805 | DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, intel_sprite_get_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
1806 | DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_AUTH|DRM_UNLOCKED), | ||
1806 | }; | 1807 | }; |
1807 | 1808 | ||
1808 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); | 1809 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b0b676abde0d..7cc36dbffbd8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -657,6 +657,8 @@ typedef struct drm_i915_private { | |||
657 | /** PPGTT used for aliasing the PPGTT with the GTT */ | 657 | /** PPGTT used for aliasing the PPGTT with the GTT */ |
658 | struct i915_hw_ppgtt *aliasing_ppgtt; | 658 | struct i915_hw_ppgtt *aliasing_ppgtt; |
659 | 659 | ||
660 | u32 *l3_remap_info; | ||
661 | |||
660 | struct shrinker inactive_shrinker; | 662 | struct shrinker inactive_shrinker; |
661 | 663 | ||
662 | /** | 664 | /** |
@@ -817,6 +819,8 @@ typedef struct drm_i915_private { | |||
817 | 819 | ||
818 | struct drm_property *broadcast_rgb_property; | 820 | struct drm_property *broadcast_rgb_property; |
819 | struct drm_property *force_audio_property; | 821 | struct drm_property *force_audio_property; |
822 | |||
823 | struct work_struct parity_error_work; | ||
820 | } drm_i915_private_t; | 824 | } drm_i915_private_t; |
821 | 825 | ||
822 | /* Iterate over initialised rings */ | 826 | /* Iterate over initialised rings */ |
@@ -1237,6 +1241,8 @@ int i915_gem_get_tiling(struct drm_device *dev, void *data, | |||
1237 | struct drm_file *file_priv); | 1241 | struct drm_file *file_priv); |
1238 | int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, | 1242 | int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, |
1239 | struct drm_file *file_priv); | 1243 | struct drm_file *file_priv); |
1244 | int i915_gem_wait_ioctl(struct drm_device *dev, void *data, | ||
1245 | struct drm_file *file_priv); | ||
1240 | void i915_gem_load(struct drm_device *dev); | 1246 | void i915_gem_load(struct drm_device *dev); |
1241 | int i915_gem_init_object(struct drm_gem_object *obj); | 1247 | int i915_gem_init_object(struct drm_gem_object *obj); |
1242 | int __must_check i915_gem_flush_ring(struct intel_ring_buffer *ring, | 1248 | int __must_check i915_gem_flush_ring(struct intel_ring_buffer *ring, |
@@ -1315,6 +1321,7 @@ int __must_check i915_gem_object_set_domain(struct drm_i915_gem_object *obj, | |||
1315 | int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); | 1321 | int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); |
1316 | int __must_check i915_gem_init(struct drm_device *dev); | 1322 | int __must_check i915_gem_init(struct drm_device *dev); |
1317 | int __must_check i915_gem_init_hw(struct drm_device *dev); | 1323 | int __must_check i915_gem_init_hw(struct drm_device *dev); |
1324 | void i915_gem_l3_remap(struct drm_device *dev); | ||
1318 | void i915_gem_init_swizzling(struct drm_device *dev); | 1325 | void i915_gem_init_swizzling(struct drm_device *dev); |
1319 | void i915_gem_init_ppgtt(struct drm_device *dev); | 1326 | void i915_gem_init_ppgtt(struct drm_device *dev); |
1320 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); | 1327 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); |
@@ -1323,8 +1330,8 @@ int __must_check i915_gem_idle(struct drm_device *dev); | |||
1323 | int __must_check i915_add_request(struct intel_ring_buffer *ring, | 1330 | int __must_check i915_add_request(struct intel_ring_buffer *ring, |
1324 | struct drm_file *file, | 1331 | struct drm_file *file, |
1325 | struct drm_i915_gem_request *request); | 1332 | struct drm_i915_gem_request *request); |
1326 | int __must_check i915_wait_request(struct intel_ring_buffer *ring, | 1333 | int __must_check i915_wait_seqno(struct intel_ring_buffer *ring, |
1327 | uint32_t seqno); | 1334 | uint32_t seqno); |
1328 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); | 1335 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); |
1329 | int __must_check | 1336 | int __must_check |
1330 | i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, | 1337 | i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 288d7b8f49ae..af67803e635f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1899,34 +1899,82 @@ i915_gem_check_olr(struct intel_ring_buffer *ring, u32 seqno) | |||
1899 | return ret; | 1899 | return ret; |
1900 | } | 1900 | } |
1901 | 1901 | ||
1902 | /** | ||
1903 | * __wait_seqno - wait until execution of seqno has finished | ||
1904 | * @ring: the ring expected to report seqno | ||
1905 | * @seqno: duh! | ||
1906 | * @interruptible: do an interruptible wait (normally yes) | ||
1907 | * @timeout: in - how long to wait (NULL forever); out - how much time remaining | ||
1908 | * | ||
1909 | * Returns 0 if the seqno was found within the alloted time. Else returns the | ||
1910 | * errno with remaining time filled in timeout argument. | ||
1911 | */ | ||
1902 | static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, | 1912 | static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, |
1903 | bool interruptible) | 1913 | bool interruptible, struct timespec *timeout) |
1904 | { | 1914 | { |
1905 | drm_i915_private_t *dev_priv = ring->dev->dev_private; | 1915 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
1906 | int ret = 0; | 1916 | struct timespec before, now, wait_time={1,0}; |
1917 | unsigned long timeout_jiffies; | ||
1918 | long end; | ||
1919 | bool wait_forever = true; | ||
1907 | 1920 | ||
1908 | if (i915_seqno_passed(ring->get_seqno(ring), seqno)) | 1921 | if (i915_seqno_passed(ring->get_seqno(ring), seqno)) |
1909 | return 0; | 1922 | return 0; |
1910 | 1923 | ||
1911 | trace_i915_gem_request_wait_begin(ring, seqno); | 1924 | trace_i915_gem_request_wait_begin(ring, seqno); |
1925 | |||
1926 | if (timeout != NULL) { | ||
1927 | wait_time = *timeout; | ||
1928 | wait_forever = false; | ||
1929 | } | ||
1930 | |||
1931 | timeout_jiffies = timespec_to_jiffies(&wait_time); | ||
1932 | |||
1912 | if (WARN_ON(!ring->irq_get(ring))) | 1933 | if (WARN_ON(!ring->irq_get(ring))) |
1913 | return -ENODEV; | 1934 | return -ENODEV; |
1914 | 1935 | ||
1936 | /* Record current time in case interrupted by signal, or wedged * */ | ||
1937 | getrawmonotonic(&before); | ||
1938 | |||
1915 | #define EXIT_COND \ | 1939 | #define EXIT_COND \ |
1916 | (i915_seqno_passed(ring->get_seqno(ring), seqno) || \ | 1940 | (i915_seqno_passed(ring->get_seqno(ring), seqno) || \ |
1917 | atomic_read(&dev_priv->mm.wedged)) | 1941 | atomic_read(&dev_priv->mm.wedged)) |
1942 | do { | ||
1943 | if (interruptible) | ||
1944 | end = wait_event_interruptible_timeout(ring->irq_queue, | ||
1945 | EXIT_COND, | ||
1946 | timeout_jiffies); | ||
1947 | else | ||
1948 | end = wait_event_timeout(ring->irq_queue, EXIT_COND, | ||
1949 | timeout_jiffies); | ||
1918 | 1950 | ||
1919 | if (interruptible) | 1951 | if (atomic_read(&dev_priv->mm.wedged)) |
1920 | ret = wait_event_interruptible(ring->irq_queue, | 1952 | end = -EAGAIN; |
1921 | EXIT_COND); | 1953 | } while (end == 0 && wait_forever); |
1922 | else | 1954 | |
1923 | wait_event(ring->irq_queue, EXIT_COND); | 1955 | getrawmonotonic(&now); |
1924 | 1956 | ||
1925 | ring->irq_put(ring); | 1957 | ring->irq_put(ring); |
1926 | trace_i915_gem_request_wait_end(ring, seqno); | 1958 | trace_i915_gem_request_wait_end(ring, seqno); |
1927 | #undef EXIT_COND | 1959 | #undef EXIT_COND |
1928 | 1960 | ||
1929 | return ret; | 1961 | if (timeout) { |
1962 | struct timespec sleep_time = timespec_sub(now, before); | ||
1963 | *timeout = timespec_sub(*timeout, sleep_time); | ||
1964 | } | ||
1965 | |||
1966 | switch (end) { | ||
1967 | case -EAGAIN: /* Wedged */ | ||
1968 | case -ERESTARTSYS: /* Signal */ | ||
1969 | return (int)end; | ||
1970 | case 0: /* Timeout */ | ||
1971 | if (timeout) | ||
1972 | set_normalized_timespec(timeout, 0, 0); | ||
1973 | return -ETIME; | ||
1974 | default: /* Completed */ | ||
1975 | WARN_ON(end < 0); /* We're not aware of other errors */ | ||
1976 | return 0; | ||
1977 | } | ||
1930 | } | 1978 | } |
1931 | 1979 | ||
1932 | /** | 1980 | /** |
@@ -1934,8 +1982,7 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, | |||
1934 | * request and object lists appropriately for that event. | 1982 | * request and object lists appropriately for that event. |
1935 | */ | 1983 | */ |
1936 | int | 1984 | int |
1937 | i915_wait_request(struct intel_ring_buffer *ring, | 1985 | i915_wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno) |
1938 | uint32_t seqno) | ||
1939 | { | 1986 | { |
1940 | drm_i915_private_t *dev_priv = ring->dev->dev_private; | 1987 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
1941 | int ret = 0; | 1988 | int ret = 0; |
@@ -1950,9 +1997,7 @@ i915_wait_request(struct intel_ring_buffer *ring, | |||
1950 | if (ret) | 1997 | if (ret) |
1951 | return ret; | 1998 | return ret; |
1952 | 1999 | ||
1953 | ret = __wait_seqno(ring, seqno, dev_priv->mm.interruptible); | 2000 | ret = __wait_seqno(ring, seqno, dev_priv->mm.interruptible, NULL); |
1954 | if (atomic_read(&dev_priv->mm.wedged)) | ||
1955 | ret = -EAGAIN; | ||
1956 | 2001 | ||
1957 | return ret; | 2002 | return ret; |
1958 | } | 2003 | } |
@@ -1975,7 +2020,7 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj) | |||
1975 | * it. | 2020 | * it. |
1976 | */ | 2021 | */ |
1977 | if (obj->active) { | 2022 | if (obj->active) { |
1978 | ret = i915_wait_request(obj->ring, obj->last_rendering_seqno); | 2023 | ret = i915_wait_seqno(obj->ring, obj->last_rendering_seqno); |
1979 | if (ret) | 2024 | if (ret) |
1980 | return ret; | 2025 | return ret; |
1981 | i915_gem_retire_requests_ring(obj->ring); | 2026 | i915_gem_retire_requests_ring(obj->ring); |
@@ -1985,6 +2030,110 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj) | |||
1985 | } | 2030 | } |
1986 | 2031 | ||
1987 | /** | 2032 | /** |
2033 | * Ensures that an object will eventually get non-busy by flushing any required | ||
2034 | * write domains, emitting any outstanding lazy request and retiring and | ||
2035 | * completed requests. | ||
2036 | */ | ||
2037 | static int | ||
2038 | i915_gem_object_flush_active(struct drm_i915_gem_object *obj) | ||
2039 | { | ||
2040 | int ret; | ||
2041 | |||
2042 | if (obj->active) { | ||
2043 | ret = i915_gem_object_flush_gpu_write_domain(obj); | ||
2044 | if (ret) | ||
2045 | return ret; | ||
2046 | |||
2047 | ret = i915_gem_check_olr(obj->ring, | ||
2048 | obj->last_rendering_seqno); | ||
2049 | if (ret) | ||
2050 | return ret; | ||
2051 | i915_gem_retire_requests_ring(obj->ring); | ||
2052 | } | ||
2053 | |||
2054 | return 0; | ||
2055 | } | ||
2056 | |||
2057 | /** | ||
2058 | * i915_gem_wait_ioctl - implements DRM_IOCTL_I915_GEM_WAIT | ||
2059 | * @DRM_IOCTL_ARGS: standard ioctl arguments | ||
2060 | * | ||
2061 | * Returns 0 if successful, else an error is returned with the remaining time in | ||
2062 | * the timeout parameter. | ||
2063 | * -ETIME: object is still busy after timeout | ||
2064 | * -ERESTARTSYS: signal interrupted the wait | ||
2065 | * -ENONENT: object doesn't exist | ||
2066 | * Also possible, but rare: | ||
2067 | * -EAGAIN: GPU wedged | ||
2068 | * -ENOMEM: damn | ||
2069 | * -ENODEV: Internal IRQ fail | ||
2070 | * -E?: The add request failed | ||
2071 | * | ||
2072 | * The wait ioctl with a timeout of 0 reimplements the busy ioctl. With any | ||
2073 | * non-zero timeout parameter the wait ioctl will wait for the given number of | ||
2074 | * nanoseconds on an object becoming unbusy. Since the wait itself does so | ||
2075 | * without holding struct_mutex the object may become re-busied before this | ||
2076 | * function completes. A similar but shorter * race condition exists in the busy | ||
2077 | * ioctl | ||
2078 | */ | ||
2079 | int | ||
2080 | i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) | ||
2081 | { | ||
2082 | struct drm_i915_gem_wait *args = data; | ||
2083 | struct drm_i915_gem_object *obj; | ||
2084 | struct intel_ring_buffer *ring = NULL; | ||
2085 | struct timespec timeout; | ||
2086 | u32 seqno = 0; | ||
2087 | int ret = 0; | ||
2088 | |||
2089 | timeout = ns_to_timespec(args->timeout_ns); | ||
2090 | |||
2091 | ret = i915_mutex_lock_interruptible(dev); | ||
2092 | if (ret) | ||
2093 | return ret; | ||
2094 | |||
2095 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->bo_handle)); | ||
2096 | if (&obj->base == NULL) { | ||
2097 | mutex_unlock(&dev->struct_mutex); | ||
2098 | return -ENOENT; | ||
2099 | } | ||
2100 | |||
2101 | /* Need to make sure the object gets inactive eventually. */ | ||
2102 | ret = i915_gem_object_flush_active(obj); | ||
2103 | if (ret) | ||
2104 | goto out; | ||
2105 | |||
2106 | if (obj->active) { | ||
2107 | seqno = obj->last_rendering_seqno; | ||
2108 | ring = obj->ring; | ||
2109 | } | ||
2110 | |||
2111 | if (seqno == 0) | ||
2112 | goto out; | ||
2113 | |||
2114 | /* Do this after OLR check to make sure we make forward progress polling | ||
2115 | * on this IOCTL with a 0 timeout (like busy ioctl) | ||
2116 | */ | ||
2117 | if (!args->timeout_ns) { | ||
2118 | ret = -ETIME; | ||
2119 | goto out; | ||
2120 | } | ||
2121 | |||
2122 | drm_gem_object_unreference(&obj->base); | ||
2123 | mutex_unlock(&dev->struct_mutex); | ||
2124 | |||
2125 | ret = __wait_seqno(ring, seqno, true, &timeout); | ||
2126 | WARN_ON(!timespec_valid(&timeout)); | ||
2127 | args->timeout_ns = timespec_to_ns(&timeout); | ||
2128 | return ret; | ||
2129 | |||
2130 | out: | ||
2131 | drm_gem_object_unreference(&obj->base); | ||
2132 | mutex_unlock(&dev->struct_mutex); | ||
2133 | return ret; | ||
2134 | } | ||
2135 | |||
2136 | /** | ||
1988 | * i915_gem_object_sync - sync an object to a ring. | 2137 | * i915_gem_object_sync - sync an object to a ring. |
1989 | * | 2138 | * |
1990 | * @obj: object which may be in use on another ring. | 2139 | * @obj: object which may be in use on another ring. |
@@ -2160,7 +2309,7 @@ static int i915_ring_idle(struct intel_ring_buffer *ring) | |||
2160 | return ret; | 2309 | return ret; |
2161 | } | 2310 | } |
2162 | 2311 | ||
2163 | return i915_wait_request(ring, i915_gem_next_request_seqno(ring)); | 2312 | return i915_wait_seqno(ring, i915_gem_next_request_seqno(ring)); |
2164 | } | 2313 | } |
2165 | 2314 | ||
2166 | int i915_gpu_idle(struct drm_device *dev) | 2315 | int i915_gpu_idle(struct drm_device *dev) |
@@ -2364,7 +2513,7 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj) | |||
2364 | } | 2513 | } |
2365 | 2514 | ||
2366 | if (obj->last_fenced_seqno) { | 2515 | if (obj->last_fenced_seqno) { |
2367 | ret = i915_wait_request(obj->ring, obj->last_fenced_seqno); | 2516 | ret = i915_wait_seqno(obj->ring, obj->last_fenced_seqno); |
2368 | if (ret) | 2517 | if (ret) |
2369 | return ret; | 2518 | return ret; |
2370 | 2519 | ||
@@ -3030,7 +3179,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) | |||
3030 | if (seqno == 0) | 3179 | if (seqno == 0) |
3031 | return 0; | 3180 | return 0; |
3032 | 3181 | ||
3033 | ret = __wait_seqno(ring, seqno, true); | 3182 | ret = __wait_seqno(ring, seqno, true, NULL); |
3034 | if (ret == 0) | 3183 | if (ret == 0) |
3035 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0); | 3184 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0); |
3036 | 3185 | ||
@@ -3199,30 +3348,9 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
3199 | * become non-busy without any further actions, therefore emit any | 3348 | * become non-busy without any further actions, therefore emit any |
3200 | * necessary flushes here. | 3349 | * necessary flushes here. |
3201 | */ | 3350 | */ |
3202 | args->busy = obj->active; | 3351 | ret = i915_gem_object_flush_active(obj); |
3203 | if (args->busy) { | ||
3204 | /* Unconditionally flush objects, even when the gpu still uses this | ||
3205 | * object. Userspace calling this function indicates that it wants to | ||
3206 | * use this buffer rather sooner than later, so issuing the required | ||
3207 | * flush earlier is beneficial. | ||
3208 | */ | ||
3209 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { | ||
3210 | ret = i915_gem_flush_ring(obj->ring, | ||
3211 | 0, obj->base.write_domain); | ||
3212 | } else { | ||
3213 | ret = i915_gem_check_olr(obj->ring, | ||
3214 | obj->last_rendering_seqno); | ||
3215 | } | ||
3216 | 3352 | ||
3217 | /* Update the active list for the hardware's current position. | 3353 | args->busy = obj->active; |
3218 | * Otherwise this only updates on a delayed timer or when irqs | ||
3219 | * are actually unmasked, and our working set ends up being | ||
3220 | * larger than required. | ||
3221 | */ | ||
3222 | i915_gem_retire_requests_ring(obj->ring); | ||
3223 | |||
3224 | args->busy = obj->active; | ||
3225 | } | ||
3226 | 3354 | ||
3227 | drm_gem_object_unreference(&obj->base); | 3355 | drm_gem_object_unreference(&obj->base); |
3228 | unlock: | 3356 | unlock: |
@@ -3435,6 +3563,38 @@ i915_gem_idle(struct drm_device *dev) | |||
3435 | return 0; | 3563 | return 0; |
3436 | } | 3564 | } |
3437 | 3565 | ||
3566 | void i915_gem_l3_remap(struct drm_device *dev) | ||
3567 | { | ||
3568 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3569 | u32 misccpctl; | ||
3570 | int i; | ||
3571 | |||
3572 | if (!IS_IVYBRIDGE(dev)) | ||
3573 | return; | ||
3574 | |||
3575 | if (!dev_priv->mm.l3_remap_info) | ||
3576 | return; | ||
3577 | |||
3578 | misccpctl = I915_READ(GEN7_MISCCPCTL); | ||
3579 | I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE); | ||
3580 | POSTING_READ(GEN7_MISCCPCTL); | ||
3581 | |||
3582 | for (i = 0; i < GEN7_L3LOG_SIZE; i += 4) { | ||
3583 | u32 remap = I915_READ(GEN7_L3LOG_BASE + i); | ||
3584 | if (remap && remap != dev_priv->mm.l3_remap_info[i/4]) | ||
3585 | DRM_DEBUG("0x%x was already programmed to %x\n", | ||
3586 | GEN7_L3LOG_BASE + i, remap); | ||
3587 | if (remap && !dev_priv->mm.l3_remap_info[i/4]) | ||
3588 | DRM_DEBUG_DRIVER("Clearing remapped register\n"); | ||
3589 | I915_WRITE(GEN7_L3LOG_BASE + i, dev_priv->mm.l3_remap_info[i/4]); | ||
3590 | } | ||
3591 | |||
3592 | /* Make sure all the writes land before disabling dop clock gating */ | ||
3593 | POSTING_READ(GEN7_L3LOG_BASE); | ||
3594 | |||
3595 | I915_WRITE(GEN7_MISCCPCTL, misccpctl); | ||
3596 | } | ||
3597 | |||
3438 | void i915_gem_init_swizzling(struct drm_device *dev) | 3598 | void i915_gem_init_swizzling(struct drm_device *dev) |
3439 | { | 3599 | { |
3440 | drm_i915_private_t *dev_priv = dev->dev_private; | 3600 | drm_i915_private_t *dev_priv = dev->dev_private; |
@@ -3524,6 +3684,8 @@ i915_gem_init_hw(struct drm_device *dev) | |||
3524 | drm_i915_private_t *dev_priv = dev->dev_private; | 3684 | drm_i915_private_t *dev_priv = dev->dev_private; |
3525 | int ret; | 3685 | int ret; |
3526 | 3686 | ||
3687 | i915_gem_l3_remap(dev); | ||
3688 | |||
3527 | i915_gem_init_swizzling(dev); | 3689 | i915_gem_init_swizzling(dev); |
3528 | 3690 | ||
3529 | ret = intel_init_render_ring_buffer(dev); | 3691 | ret = intel_init_render_ring_buffer(dev); |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b1fe0edda955..75e0b029e1fa 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -375,6 +375,86 @@ static void gen6_pm_rps_work(struct work_struct *work) | |||
375 | mutex_unlock(&dev_priv->dev->struct_mutex); | 375 | mutex_unlock(&dev_priv->dev->struct_mutex); |
376 | } | 376 | } |
377 | 377 | ||
378 | |||
379 | /** | ||
380 | * ivybridge_parity_work - Workqueue called when a parity error interrupt | ||
381 | * occurred. | ||
382 | * @work: workqueue struct | ||
383 | * | ||
384 | * Doesn't actually do anything except notify userspace. As a consequence of | ||
385 | * this event, userspace should try to remap the bad rows since statistically | ||
386 | * it is likely the same row is more likely to go bad again. | ||
387 | */ | ||
388 | static void ivybridge_parity_work(struct work_struct *work) | ||
389 | { | ||
390 | drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, | ||
391 | parity_error_work); | ||
392 | u32 error_status, row, bank, subbank; | ||
393 | char *parity_event[5]; | ||
394 | uint32_t misccpctl; | ||
395 | unsigned long flags; | ||
396 | |||
397 | /* We must turn off DOP level clock gating to access the L3 registers. | ||
398 | * In order to prevent a get/put style interface, acquire struct mutex | ||
399 | * any time we access those registers. | ||
400 | */ | ||
401 | mutex_lock(&dev_priv->dev->struct_mutex); | ||
402 | |||
403 | misccpctl = I915_READ(GEN7_MISCCPCTL); | ||
404 | I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE); | ||
405 | POSTING_READ(GEN7_MISCCPCTL); | ||
406 | |||
407 | error_status = I915_READ(GEN7_L3CDERRST1); | ||
408 | row = GEN7_PARITY_ERROR_ROW(error_status); | ||
409 | bank = GEN7_PARITY_ERROR_BANK(error_status); | ||
410 | subbank = GEN7_PARITY_ERROR_SUBBANK(error_status); | ||
411 | |||
412 | I915_WRITE(GEN7_L3CDERRST1, GEN7_PARITY_ERROR_VALID | | ||
413 | GEN7_L3CDERRST1_ENABLE); | ||
414 | POSTING_READ(GEN7_L3CDERRST1); | ||
415 | |||
416 | I915_WRITE(GEN7_MISCCPCTL, misccpctl); | ||
417 | |||
418 | spin_lock_irqsave(&dev_priv->irq_lock, flags); | ||
419 | dev_priv->gt_irq_mask &= ~GT_GEN7_L3_PARITY_ERROR_INTERRUPT; | ||
420 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | ||
421 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); | ||
422 | |||
423 | mutex_unlock(&dev_priv->dev->struct_mutex); | ||
424 | |||
425 | parity_event[0] = "L3_PARITY_ERROR=1"; | ||
426 | parity_event[1] = kasprintf(GFP_KERNEL, "ROW=%d", row); | ||
427 | parity_event[2] = kasprintf(GFP_KERNEL, "BANK=%d", bank); | ||
428 | parity_event[3] = kasprintf(GFP_KERNEL, "SUBBANK=%d", subbank); | ||
429 | parity_event[4] = NULL; | ||
430 | |||
431 | kobject_uevent_env(&dev_priv->dev->primary->kdev.kobj, | ||
432 | KOBJ_CHANGE, parity_event); | ||
433 | |||
434 | DRM_DEBUG("Parity error: Row = %d, Bank = %d, Sub bank = %d.\n", | ||
435 | row, bank, subbank); | ||
436 | |||
437 | kfree(parity_event[3]); | ||
438 | kfree(parity_event[2]); | ||
439 | kfree(parity_event[1]); | ||
440 | } | ||
441 | |||
442 | static void ivybridge_handle_parity_error(struct drm_device *dev) | ||
443 | { | ||
444 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
445 | unsigned long flags; | ||
446 | |||
447 | if (!IS_IVYBRIDGE(dev)) | ||
448 | return; | ||
449 | |||
450 | spin_lock_irqsave(&dev_priv->irq_lock, flags); | ||
451 | dev_priv->gt_irq_mask |= GT_GEN7_L3_PARITY_ERROR_INTERRUPT; | ||
452 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | ||
453 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); | ||
454 | |||
455 | queue_work(dev_priv->wq, &dev_priv->parity_error_work); | ||
456 | } | ||
457 | |||
378 | static void snb_gt_irq_handler(struct drm_device *dev, | 458 | static void snb_gt_irq_handler(struct drm_device *dev, |
379 | struct drm_i915_private *dev_priv, | 459 | struct drm_i915_private *dev_priv, |
380 | u32 gt_iir) | 460 | u32 gt_iir) |
@@ -394,6 +474,9 @@ static void snb_gt_irq_handler(struct drm_device *dev, | |||
394 | DRM_ERROR("GT error interrupt 0x%08x\n", gt_iir); | 474 | DRM_ERROR("GT error interrupt 0x%08x\n", gt_iir); |
395 | i915_handle_error(dev, false); | 475 | i915_handle_error(dev, false); |
396 | } | 476 | } |
477 | |||
478 | if (gt_iir & GT_GEN7_L3_PARITY_ERROR_INTERRUPT) | ||
479 | ivybridge_handle_parity_error(dev); | ||
397 | } | 480 | } |
398 | 481 | ||
399 | static void gen6_queue_rps_work(struct drm_i915_private *dev_priv, | 482 | static void gen6_queue_rps_work(struct drm_i915_private *dev_priv, |
@@ -1649,7 +1732,6 @@ static void ironlake_irq_preinstall(struct drm_device *dev) | |||
1649 | 1732 | ||
1650 | atomic_set(&dev_priv->irq_received, 0); | 1733 | atomic_set(&dev_priv->irq_received, 0); |
1651 | 1734 | ||
1652 | |||
1653 | I915_WRITE(HWSTAM, 0xeffe); | 1735 | I915_WRITE(HWSTAM, 0xeffe); |
1654 | 1736 | ||
1655 | /* XXX hotplug from PCH */ | 1737 | /* XXX hotplug from PCH */ |
@@ -1812,13 +1894,13 @@ static int ivybridge_irq_postinstall(struct drm_device *dev) | |||
1812 | DE_PIPEA_VBLANK_IVB); | 1894 | DE_PIPEA_VBLANK_IVB); |
1813 | POSTING_READ(DEIER); | 1895 | POSTING_READ(DEIER); |
1814 | 1896 | ||
1815 | dev_priv->gt_irq_mask = ~0; | 1897 | dev_priv->gt_irq_mask = ~GT_GEN7_L3_PARITY_ERROR_INTERRUPT; |
1816 | 1898 | ||
1817 | I915_WRITE(GTIIR, I915_READ(GTIIR)); | 1899 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
1818 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | 1900 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); |
1819 | 1901 | ||
1820 | render_irqs = GT_USER_INTERRUPT | GEN6_BSD_USER_INTERRUPT | | 1902 | render_irqs = GT_USER_INTERRUPT | GEN6_BSD_USER_INTERRUPT | |
1821 | GEN6_BLITTER_USER_INTERRUPT; | 1903 | GEN6_BLITTER_USER_INTERRUPT | GT_GEN7_L3_PARITY_ERROR_INTERRUPT; |
1822 | I915_WRITE(GTIER, render_irqs); | 1904 | I915_WRITE(GTIER, render_irqs); |
1823 | POSTING_READ(GTIER); | 1905 | POSTING_READ(GTIER); |
1824 | 1906 | ||
@@ -2167,9 +2249,9 @@ static int i915_irq_postinstall(struct drm_device *dev) | |||
2167 | hotplug_en |= HDMIC_HOTPLUG_INT_EN; | 2249 | hotplug_en |= HDMIC_HOTPLUG_INT_EN; |
2168 | if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) | 2250 | if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) |
2169 | hotplug_en |= HDMID_HOTPLUG_INT_EN; | 2251 | hotplug_en |= HDMID_HOTPLUG_INT_EN; |
2170 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS) | 2252 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_I915) |
2171 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; | 2253 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; |
2172 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS) | 2254 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_I915) |
2173 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; | 2255 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; |
2174 | if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) { | 2256 | if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) { |
2175 | hotplug_en |= CRT_HOTPLUG_INT_EN; | 2257 | hotplug_en |= CRT_HOTPLUG_INT_EN; |
@@ -2329,10 +2411,8 @@ static void i965_irq_preinstall(struct drm_device * dev) | |||
2329 | 2411 | ||
2330 | atomic_set(&dev_priv->irq_received, 0); | 2412 | atomic_set(&dev_priv->irq_received, 0); |
2331 | 2413 | ||
2332 | if (I915_HAS_HOTPLUG(dev)) { | 2414 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
2333 | I915_WRITE(PORT_HOTPLUG_EN, 0); | 2415 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); |
2334 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); | ||
2335 | } | ||
2336 | 2416 | ||
2337 | I915_WRITE(HWSTAM, 0xeffe); | 2417 | I915_WRITE(HWSTAM, 0xeffe); |
2338 | for_each_pipe(pipe) | 2418 | for_each_pipe(pipe) |
@@ -2345,11 +2425,13 @@ static void i965_irq_preinstall(struct drm_device * dev) | |||
2345 | static int i965_irq_postinstall(struct drm_device *dev) | 2425 | static int i965_irq_postinstall(struct drm_device *dev) |
2346 | { | 2426 | { |
2347 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 2427 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2428 | u32 hotplug_en; | ||
2348 | u32 enable_mask; | 2429 | u32 enable_mask; |
2349 | u32 error_mask; | 2430 | u32 error_mask; |
2350 | 2431 | ||
2351 | /* Unmask the interrupts that we always want on. */ | 2432 | /* Unmask the interrupts that we always want on. */ |
2352 | dev_priv->irq_mask = ~(I915_ASLE_INTERRUPT | | 2433 | dev_priv->irq_mask = ~(I915_ASLE_INTERRUPT | |
2434 | I915_DISPLAY_PORT_INTERRUPT | | ||
2353 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | | 2435 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | |
2354 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | | 2436 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | |
2355 | I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | | 2437 | I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | |
@@ -2365,13 +2447,6 @@ static int i965_irq_postinstall(struct drm_device *dev) | |||
2365 | dev_priv->pipestat[0] = 0; | 2447 | dev_priv->pipestat[0] = 0; |
2366 | dev_priv->pipestat[1] = 0; | 2448 | dev_priv->pipestat[1] = 0; |
2367 | 2449 | ||
2368 | if (I915_HAS_HOTPLUG(dev)) { | ||
2369 | /* Enable in IER... */ | ||
2370 | enable_mask |= I915_DISPLAY_PORT_INTERRUPT; | ||
2371 | /* and unmask in IMR */ | ||
2372 | dev_priv->irq_mask &= ~I915_DISPLAY_PORT_INTERRUPT; | ||
2373 | } | ||
2374 | |||
2375 | /* | 2450 | /* |
2376 | * Enable some error detection, note the instruction error mask | 2451 | * Enable some error detection, note the instruction error mask |
2377 | * bit is reserved, so we leave it masked. | 2452 | * bit is reserved, so we leave it masked. |
@@ -2391,36 +2466,40 @@ static int i965_irq_postinstall(struct drm_device *dev) | |||
2391 | I915_WRITE(IER, enable_mask); | 2466 | I915_WRITE(IER, enable_mask); |
2392 | POSTING_READ(IER); | 2467 | POSTING_READ(IER); |
2393 | 2468 | ||
2394 | if (I915_HAS_HOTPLUG(dev)) { | 2469 | /* Note HDMI and DP share hotplug bits */ |
2395 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); | 2470 | hotplug_en = 0; |
2396 | 2471 | if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) | |
2397 | /* Note HDMI and DP share bits */ | 2472 | hotplug_en |= HDMIB_HOTPLUG_INT_EN; |
2398 | if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) | 2473 | if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS) |
2399 | hotplug_en |= HDMIB_HOTPLUG_INT_EN; | 2474 | hotplug_en |= HDMIC_HOTPLUG_INT_EN; |
2400 | if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS) | 2475 | if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) |
2401 | hotplug_en |= HDMIC_HOTPLUG_INT_EN; | 2476 | hotplug_en |= HDMID_HOTPLUG_INT_EN; |
2402 | if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) | 2477 | if (IS_G4X(dev)) { |
2403 | hotplug_en |= HDMID_HOTPLUG_INT_EN; | 2478 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_G4X) |
2404 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS) | ||
2405 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; | 2479 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; |
2406 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS) | 2480 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_G4X) |
2407 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; | 2481 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; |
2408 | if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) { | 2482 | } else { |
2409 | hotplug_en |= CRT_HOTPLUG_INT_EN; | 2483 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_I965) |
2484 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; | ||
2485 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_I965) | ||
2486 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; | ||
2487 | } | ||
2488 | if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) { | ||
2489 | hotplug_en |= CRT_HOTPLUG_INT_EN; | ||
2410 | 2490 | ||
2411 | /* Programming the CRT detection parameters tends | 2491 | /* Programming the CRT detection parameters tends |
2412 | to generate a spurious hotplug event about three | 2492 | to generate a spurious hotplug event about three |
2413 | seconds later. So just do it once. | 2493 | seconds later. So just do it once. |
2414 | */ | 2494 | */ |
2415 | if (IS_G4X(dev)) | 2495 | if (IS_G4X(dev)) |
2416 | hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; | 2496 | hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; |
2417 | hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; | 2497 | hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; |
2418 | } | 2498 | } |
2419 | 2499 | ||
2420 | /* Ignore TV since it's buggy */ | 2500 | /* Ignore TV since it's buggy */ |
2421 | 2501 | ||
2422 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); | 2502 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); |
2423 | } | ||
2424 | 2503 | ||
2425 | intel_opregion_enable_asle(dev); | 2504 | intel_opregion_enable_asle(dev); |
2426 | 2505 | ||
@@ -2478,8 +2557,7 @@ static irqreturn_t i965_irq_handler(DRM_IRQ_ARGS) | |||
2478 | ret = IRQ_HANDLED; | 2557 | ret = IRQ_HANDLED; |
2479 | 2558 | ||
2480 | /* Consume port. Then clear IIR or we'll miss events */ | 2559 | /* Consume port. Then clear IIR or we'll miss events */ |
2481 | if ((I915_HAS_HOTPLUG(dev)) && | 2560 | if (iir & I915_DISPLAY_PORT_INTERRUPT) { |
2482 | (iir & I915_DISPLAY_PORT_INTERRUPT)) { | ||
2483 | u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); | 2561 | u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); |
2484 | 2562 | ||
2485 | DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", | 2563 | DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", |
@@ -2552,10 +2630,8 @@ static void i965_irq_uninstall(struct drm_device * dev) | |||
2552 | if (!dev_priv) | 2630 | if (!dev_priv) |
2553 | return; | 2631 | return; |
2554 | 2632 | ||
2555 | if (I915_HAS_HOTPLUG(dev)) { | 2633 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
2556 | I915_WRITE(PORT_HOTPLUG_EN, 0); | 2634 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); |
2557 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); | ||
2558 | } | ||
2559 | 2635 | ||
2560 | I915_WRITE(HWSTAM, 0xffffffff); | 2636 | I915_WRITE(HWSTAM, 0xffffffff); |
2561 | for_each_pipe(pipe) | 2637 | for_each_pipe(pipe) |
@@ -2576,6 +2652,7 @@ void intel_irq_init(struct drm_device *dev) | |||
2576 | INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); | 2652 | INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); |
2577 | INIT_WORK(&dev_priv->error_work, i915_error_work_func); | 2653 | INIT_WORK(&dev_priv->error_work, i915_error_work_func); |
2578 | INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); | 2654 | INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); |
2655 | INIT_WORK(&dev_priv->parity_error_work, ivybridge_parity_work); | ||
2579 | 2656 | ||
2580 | dev->driver->get_vblank_counter = i915_get_vblank_counter; | 2657 | dev->driver->get_vblank_counter = i915_get_vblank_counter; |
2581 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ | 2658 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 48d5e8e051cf..35113d8d7b05 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -1566,20 +1566,34 @@ | |||
1566 | #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) | 1566 | #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) |
1567 | 1567 | ||
1568 | #define PORT_HOTPLUG_STAT 0x61114 | 1568 | #define PORT_HOTPLUG_STAT 0x61114 |
1569 | #define HDMIB_HOTPLUG_INT_STATUS (1 << 29) | 1569 | /* HDMI/DP bits are gen4+ */ |
1570 | #define DPB_HOTPLUG_INT_STATUS (1 << 29) | 1570 | #define DPB_HOTPLUG_LIVE_STATUS (1 << 29) |
1571 | #define HDMIC_HOTPLUG_INT_STATUS (1 << 28) | 1571 | #define DPC_HOTPLUG_LIVE_STATUS (1 << 28) |
1572 | #define DPC_HOTPLUG_INT_STATUS (1 << 28) | 1572 | #define DPD_HOTPLUG_LIVE_STATUS (1 << 27) |
1573 | #define HDMID_HOTPLUG_INT_STATUS (1 << 27) | 1573 | #define DPD_HOTPLUG_INT_STATUS (3 << 21) |
1574 | #define DPD_HOTPLUG_INT_STATUS (1 << 27) | 1574 | #define DPC_HOTPLUG_INT_STATUS (3 << 19) |
1575 | #define DPB_HOTPLUG_INT_STATUS (3 << 17) | ||
1576 | /* HDMI bits are shared with the DP bits */ | ||
1577 | #define HDMIB_HOTPLUG_LIVE_STATUS (1 << 29) | ||
1578 | #define HDMIC_HOTPLUG_LIVE_STATUS (1 << 28) | ||
1579 | #define HDMID_HOTPLUG_LIVE_STATUS (1 << 27) | ||
1580 | #define HDMID_HOTPLUG_INT_STATUS (3 << 21) | ||
1581 | #define HDMIC_HOTPLUG_INT_STATUS (3 << 19) | ||
1582 | #define HDMIB_HOTPLUG_INT_STATUS (3 << 17) | ||
1583 | /* CRT/TV common between gen3+ */ | ||
1575 | #define CRT_HOTPLUG_INT_STATUS (1 << 11) | 1584 | #define CRT_HOTPLUG_INT_STATUS (1 << 11) |
1576 | #define TV_HOTPLUG_INT_STATUS (1 << 10) | 1585 | #define TV_HOTPLUG_INT_STATUS (1 << 10) |
1577 | #define CRT_HOTPLUG_MONITOR_MASK (3 << 8) | 1586 | #define CRT_HOTPLUG_MONITOR_MASK (3 << 8) |
1578 | #define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) | 1587 | #define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) |
1579 | #define CRT_HOTPLUG_MONITOR_MONO (2 << 8) | 1588 | #define CRT_HOTPLUG_MONITOR_MONO (2 << 8) |
1580 | #define CRT_HOTPLUG_MONITOR_NONE (0 << 8) | 1589 | #define CRT_HOTPLUG_MONITOR_NONE (0 << 8) |
1581 | #define SDVOC_HOTPLUG_INT_STATUS (1 << 7) | 1590 | /* SDVO is different across gen3/4 */ |
1582 | #define SDVOB_HOTPLUG_INT_STATUS (1 << 6) | 1591 | #define SDVOC_HOTPLUG_INT_STATUS_G4X (1 << 3) |
1592 | #define SDVOB_HOTPLUG_INT_STATUS_G4X (1 << 2) | ||
1593 | #define SDVOC_HOTPLUG_INT_STATUS_I965 (3 << 4) | ||
1594 | #define SDVOB_HOTPLUG_INT_STATUS_I965 (3 << 2) | ||
1595 | #define SDVOC_HOTPLUG_INT_STATUS_I915 (1 << 7) | ||
1596 | #define SDVOB_HOTPLUG_INT_STATUS_I915 (1 << 6) | ||
1583 | 1597 | ||
1584 | /* SDVO port control */ | 1598 | /* SDVO port control */ |
1585 | #define SDVOB 0x61140 | 1599 | #define SDVOB 0x61140 |
@@ -1711,8 +1725,10 @@ | |||
1711 | #define VIDEO_DIP_PORT_C (2 << 29) | 1725 | #define VIDEO_DIP_PORT_C (2 << 29) |
1712 | #define VIDEO_DIP_PORT_D (3 << 29) | 1726 | #define VIDEO_DIP_PORT_D (3 << 29) |
1713 | #define VIDEO_DIP_PORT_MASK (3 << 29) | 1727 | #define VIDEO_DIP_PORT_MASK (3 << 29) |
1728 | #define VIDEO_DIP_ENABLE_GCP (1 << 25) | ||
1714 | #define VIDEO_DIP_ENABLE_AVI (1 << 21) | 1729 | #define VIDEO_DIP_ENABLE_AVI (1 << 21) |
1715 | #define VIDEO_DIP_ENABLE_VENDOR (2 << 21) | 1730 | #define VIDEO_DIP_ENABLE_VENDOR (2 << 21) |
1731 | #define VIDEO_DIP_ENABLE_GAMUT (4 << 21) | ||
1716 | #define VIDEO_DIP_ENABLE_SPD (8 << 21) | 1732 | #define VIDEO_DIP_ENABLE_SPD (8 << 21) |
1717 | #define VIDEO_DIP_SELECT_AVI (0 << 19) | 1733 | #define VIDEO_DIP_SELECT_AVI (0 << 19) |
1718 | #define VIDEO_DIP_SELECT_VENDOR (1 << 19) | 1734 | #define VIDEO_DIP_SELECT_VENDOR (1 << 19) |
@@ -1723,7 +1739,11 @@ | |||
1723 | #define VIDEO_DIP_FREQ_2VSYNC (2 << 16) | 1739 | #define VIDEO_DIP_FREQ_2VSYNC (2 << 16) |
1724 | #define VIDEO_DIP_FREQ_MASK (3 << 16) | 1740 | #define VIDEO_DIP_FREQ_MASK (3 << 16) |
1725 | /* HSW and later: */ | 1741 | /* HSW and later: */ |
1742 | #define VIDEO_DIP_ENABLE_VSC_HSW (1 << 20) | ||
1743 | #define VIDEO_DIP_ENABLE_GCP_HSW (1 << 16) | ||
1726 | #define VIDEO_DIP_ENABLE_AVI_HSW (1 << 12) | 1744 | #define VIDEO_DIP_ENABLE_AVI_HSW (1 << 12) |
1745 | #define VIDEO_DIP_ENABLE_VS_HSW (1 << 8) | ||
1746 | #define VIDEO_DIP_ENABLE_GMP_HSW (1 << 4) | ||
1727 | #define VIDEO_DIP_ENABLE_SPD_HSW (1 << 0) | 1747 | #define VIDEO_DIP_ENABLE_SPD_HSW (1 << 0) |
1728 | 1748 | ||
1729 | /* Panel power sequencing */ | 1749 | /* Panel power sequencing */ |
@@ -4111,6 +4131,26 @@ | |||
4111 | #define GEN6_RC6 3 | 4131 | #define GEN6_RC6 3 |
4112 | #define GEN6_RC7 4 | 4132 | #define GEN6_RC7 4 |
4113 | 4133 | ||
4134 | #define GEN7_MISCCPCTL (0x9424) | ||
4135 | #define GEN7_DOP_CLOCK_GATE_ENABLE (1<<0) | ||
4136 | |||
4137 | /* IVYBRIDGE DPF */ | ||
4138 | #define GEN7_L3CDERRST1 0xB008 /* L3CD Error Status 1 */ | ||
4139 | #define GEN7_L3CDERRST1_ROW_MASK (0x7ff<<14) | ||
4140 | #define GEN7_PARITY_ERROR_VALID (1<<13) | ||
4141 | #define GEN7_L3CDERRST1_BANK_MASK (3<<11) | ||
4142 | #define GEN7_L3CDERRST1_SUBBANK_MASK (7<<8) | ||
4143 | #define GEN7_PARITY_ERROR_ROW(reg) \ | ||
4144 | ((reg & GEN7_L3CDERRST1_ROW_MASK) >> 14) | ||
4145 | #define GEN7_PARITY_ERROR_BANK(reg) \ | ||
4146 | ((reg & GEN7_L3CDERRST1_BANK_MASK) >> 11) | ||
4147 | #define GEN7_PARITY_ERROR_SUBBANK(reg) \ | ||
4148 | ((reg & GEN7_L3CDERRST1_SUBBANK_MASK) >> 8) | ||
4149 | #define GEN7_L3CDERRST1_ENABLE (1<<7) | ||
4150 | |||
4151 | #define GEN7_L3LOG_BASE 0xB070 | ||
4152 | #define GEN7_L3LOG_SIZE 0x80 | ||
4153 | |||
4114 | #define G4X_AUD_VID_DID 0x62020 | 4154 | #define G4X_AUD_VID_DID 0x62020 |
4115 | #define INTEL_AUDIO_DEVCL 0x808629FB | 4155 | #define INTEL_AUDIO_DEVCL 0x808629FB |
4116 | #define INTEL_AUDIO_DEVBLC 0x80862801 | 4156 | #define INTEL_AUDIO_DEVBLC 0x80862801 |
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 79f83445afa0..2f5388af8df9 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/stat.h> | 30 | #include <linux/stat.h> |
31 | #include <linux/sysfs.h> | 31 | #include <linux/sysfs.h> |
32 | #include "intel_drv.h" | ||
32 | #include "i915_drv.h" | 33 | #include "i915_drv.h" |
33 | 34 | ||
34 | static u32 calc_residency(struct drm_device *dev, const u32 reg) | 35 | static u32 calc_residency(struct drm_device *dev, const u32 reg) |
@@ -92,20 +93,134 @@ static struct attribute_group rc6_attr_group = { | |||
92 | .attrs = rc6_attrs | 93 | .attrs = rc6_attrs |
93 | }; | 94 | }; |
94 | 95 | ||
95 | void i915_setup_sysfs(struct drm_device *dev) | 96 | static int l3_access_valid(struct drm_device *dev, loff_t offset) |
97 | { | ||
98 | if (!IS_IVYBRIDGE(dev)) | ||
99 | return -EPERM; | ||
100 | |||
101 | if (offset % 4 != 0) | ||
102 | return -EINVAL; | ||
103 | |||
104 | if (offset >= GEN7_L3LOG_SIZE) | ||
105 | return -ENXIO; | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static ssize_t | ||
111 | i915_l3_read(struct file *filp, struct kobject *kobj, | ||
112 | struct bin_attribute *attr, char *buf, | ||
113 | loff_t offset, size_t count) | ||
114 | { | ||
115 | struct device *dev = container_of(kobj, struct device, kobj); | ||
116 | struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev); | ||
117 | struct drm_device *drm_dev = dminor->dev; | ||
118 | struct drm_i915_private *dev_priv = drm_dev->dev_private; | ||
119 | uint32_t misccpctl; | ||
120 | int i, ret; | ||
121 | |||
122 | ret = l3_access_valid(drm_dev, offset); | ||
123 | if (ret) | ||
124 | return ret; | ||
125 | |||
126 | ret = i915_mutex_lock_interruptible(drm_dev); | ||
127 | if (ret) | ||
128 | return ret; | ||
129 | |||
130 | misccpctl = I915_READ(GEN7_MISCCPCTL); | ||
131 | I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE); | ||
132 | |||
133 | for (i = offset; count >= 4 && i < GEN7_L3LOG_SIZE; i += 4, count -= 4) | ||
134 | *((uint32_t *)(&buf[i])) = I915_READ(GEN7_L3LOG_BASE + i); | ||
135 | |||
136 | I915_WRITE(GEN7_MISCCPCTL, misccpctl); | ||
137 | |||
138 | mutex_unlock(&drm_dev->struct_mutex); | ||
139 | |||
140 | return i - offset; | ||
141 | } | ||
142 | |||
143 | static ssize_t | ||
144 | i915_l3_write(struct file *filp, struct kobject *kobj, | ||
145 | struct bin_attribute *attr, char *buf, | ||
146 | loff_t offset, size_t count) | ||
96 | { | 147 | { |
148 | struct device *dev = container_of(kobj, struct device, kobj); | ||
149 | struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev); | ||
150 | struct drm_device *drm_dev = dminor->dev; | ||
151 | struct drm_i915_private *dev_priv = drm_dev->dev_private; | ||
152 | u32 *temp = NULL; /* Just here to make handling failures easy */ | ||
97 | int ret; | 153 | int ret; |
98 | 154 | ||
99 | /* ILK doesn't have any residency information */ | 155 | ret = l3_access_valid(drm_dev, offset); |
100 | if (INTEL_INFO(dev)->gen < 6) | 156 | if (ret) |
101 | return; | 157 | return ret; |
102 | 158 | ||
103 | ret = sysfs_merge_group(&dev->primary->kdev.kobj, &rc6_attr_group); | 159 | ret = i915_mutex_lock_interruptible(drm_dev); |
104 | if (ret) | 160 | if (ret) |
105 | DRM_ERROR("sysfs setup failed\n"); | 161 | return ret; |
162 | |||
163 | if (!dev_priv->mm.l3_remap_info) { | ||
164 | temp = kzalloc(GEN7_L3LOG_SIZE, GFP_KERNEL); | ||
165 | if (!temp) { | ||
166 | mutex_unlock(&drm_dev->struct_mutex); | ||
167 | return -ENOMEM; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | ret = i915_gpu_idle(drm_dev); | ||
172 | if (ret) { | ||
173 | kfree(temp); | ||
174 | mutex_unlock(&drm_dev->struct_mutex); | ||
175 | return ret; | ||
176 | } | ||
177 | |||
178 | /* TODO: Ideally we really want a GPU reset here to make sure errors | ||
179 | * aren't propagated. Since I cannot find a stable way to reset the GPU | ||
180 | * at this point it is left as a TODO. | ||
181 | */ | ||
182 | if (temp) | ||
183 | dev_priv->mm.l3_remap_info = temp; | ||
184 | |||
185 | memcpy(dev_priv->mm.l3_remap_info + (offset/4), | ||
186 | buf + (offset/4), | ||
187 | count); | ||
188 | |||
189 | i915_gem_l3_remap(drm_dev); | ||
190 | |||
191 | mutex_unlock(&drm_dev->struct_mutex); | ||
192 | |||
193 | return count; | ||
194 | } | ||
195 | |||
196 | static struct bin_attribute dpf_attrs = { | ||
197 | .attr = {.name = "l3_parity", .mode = (S_IRUSR | S_IWUSR)}, | ||
198 | .size = GEN7_L3LOG_SIZE, | ||
199 | .read = i915_l3_read, | ||
200 | .write = i915_l3_write, | ||
201 | .mmap = NULL | ||
202 | }; | ||
203 | |||
204 | void i915_setup_sysfs(struct drm_device *dev) | ||
205 | { | ||
206 | int ret; | ||
207 | |||
208 | if (INTEL_INFO(dev)->gen >= 6) { | ||
209 | ret = sysfs_merge_group(&dev->primary->kdev.kobj, | ||
210 | &rc6_attr_group); | ||
211 | if (ret) | ||
212 | DRM_ERROR("RC6 residency sysfs setup failed\n"); | ||
213 | } | ||
214 | |||
215 | if (IS_IVYBRIDGE(dev)) { | ||
216 | ret = device_create_bin_file(&dev->primary->kdev, &dpf_attrs); | ||
217 | if (ret) | ||
218 | DRM_ERROR("l3 parity sysfs setup failed\n"); | ||
219 | } | ||
106 | } | 220 | } |
107 | 221 | ||
108 | void i915_teardown_sysfs(struct drm_device *dev) | 222 | void i915_teardown_sysfs(struct drm_device *dev) |
109 | { | 223 | { |
224 | device_remove_bin_file(&dev->primary->kdev, &dpf_attrs); | ||
110 | sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group); | 225 | sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group); |
111 | } | 226 | } |
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index dac7bba4d9da..fe90b3a84a6d 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h | |||
@@ -311,9 +311,33 @@ DEFINE_EVENT(i915_gem_request, i915_gem_request_retire, | |||
311 | TP_ARGS(ring, seqno) | 311 | TP_ARGS(ring, seqno) |
312 | ); | 312 | ); |
313 | 313 | ||
314 | DEFINE_EVENT(i915_gem_request, i915_gem_request_wait_begin, | 314 | TRACE_EVENT(i915_gem_request_wait_begin, |
315 | TP_PROTO(struct intel_ring_buffer *ring, u32 seqno), | 315 | TP_PROTO(struct intel_ring_buffer *ring, u32 seqno), |
316 | TP_ARGS(ring, seqno) | 316 | TP_ARGS(ring, seqno), |
317 | |||
318 | TP_STRUCT__entry( | ||
319 | __field(u32, dev) | ||
320 | __field(u32, ring) | ||
321 | __field(u32, seqno) | ||
322 | __field(bool, blocking) | ||
323 | ), | ||
324 | |||
325 | /* NB: the blocking information is racy since mutex_is_locked | ||
326 | * doesn't check that the current thread holds the lock. The only | ||
327 | * other option would be to pass the boolean information of whether | ||
328 | * or not the class was blocking down through the stack which is | ||
329 | * less desirable. | ||
330 | */ | ||
331 | TP_fast_assign( | ||
332 | __entry->dev = ring->dev->primary->index; | ||
333 | __entry->ring = ring->id; | ||
334 | __entry->seqno = seqno; | ||
335 | __entry->blocking = mutex_is_locked(&ring->dev->struct_mutex); | ||
336 | ), | ||
337 | |||
338 | TP_printk("dev=%u, ring=%u, seqno=%u, blocking=%s", | ||
339 | __entry->dev, __entry->ring, __entry->seqno, | ||
340 | __entry->blocking ? "yes (NB)" : "no") | ||
317 | ); | 341 | ); |
318 | 342 | ||
319 | DEFINE_EVENT(i915_gem_request, i915_gem_request_wait_end, | 343 | DEFINE_EVENT(i915_gem_request, i915_gem_request_wait_end, |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 46d1e886c692..f33fe1a1c33e 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -726,8 +726,7 @@ void intel_ddi_mode_set(struct drm_encoder *encoder, | |||
726 | 726 | ||
727 | I915_WRITE(DDI_FUNC_CTL(pipe), temp); | 727 | I915_WRITE(DDI_FUNC_CTL(pipe), temp); |
728 | 728 | ||
729 | intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); | 729 | intel_hdmi->set_infoframes(encoder, adjusted_mode); |
730 | intel_hdmi_set_spd_infoframe(encoder); | ||
731 | } | 730 | } |
732 | 731 | ||
733 | void intel_ddi_dpms(struct drm_encoder *encoder, int mode) | 732 | void intel_ddi_dpms(struct drm_encoder *encoder, int mode) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a7c727d0c105..add1a15dc8b3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -4405,25 +4405,10 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
4405 | &clock, | 4405 | &clock, |
4406 | &reduced_clock); | 4406 | &reduced_clock); |
4407 | } | 4407 | } |
4408 | /* SDVO TV has fixed PLL values depend on its clock range, | 4408 | |
4409 | this mirrors vbios setting. */ | 4409 | if (is_sdvo && is_tv) |
4410 | if (is_sdvo && is_tv) { | 4410 | i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock); |
4411 | if (adjusted_mode->clock >= 100000 | 4411 | |
4412 | && adjusted_mode->clock < 140500) { | ||
4413 | clock.p1 = 2; | ||
4414 | clock.p2 = 10; | ||
4415 | clock.n = 3; | ||
4416 | clock.m1 = 16; | ||
4417 | clock.m2 = 8; | ||
4418 | } else if (adjusted_mode->clock >= 140500 | ||
4419 | && adjusted_mode->clock <= 200000) { | ||
4420 | clock.p1 = 1; | ||
4421 | clock.p2 = 10; | ||
4422 | clock.n = 6; | ||
4423 | clock.m1 = 12; | ||
4424 | clock.m2 = 8; | ||
4425 | } | ||
4426 | } | ||
4427 | 4412 | ||
4428 | /* FDI link */ | 4413 | /* FDI link */ |
4429 | pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); | 4414 | pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); |
@@ -4431,16 +4416,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
4431 | /* CPU eDP doesn't require FDI link, so just set DP M/N | 4416 | /* CPU eDP doesn't require FDI link, so just set DP M/N |
4432 | according to current link config */ | 4417 | according to current link config */ |
4433 | if (is_cpu_edp) { | 4418 | if (is_cpu_edp) { |
4434 | target_clock = mode->clock; | ||
4435 | intel_edp_link_config(edp_encoder, &lane, &link_bw); | 4419 | intel_edp_link_config(edp_encoder, &lane, &link_bw); |
4436 | } else { | 4420 | } else { |
4437 | /* [e]DP over FDI requires target mode clock | ||
4438 | instead of link clock */ | ||
4439 | if (is_dp) | ||
4440 | target_clock = mode->clock; | ||
4441 | else | ||
4442 | target_clock = adjusted_mode->clock; | ||
4443 | |||
4444 | /* FDI is a binary signal running at ~2.7GHz, encoding | 4421 | /* FDI is a binary signal running at ~2.7GHz, encoding |
4445 | * each output octet as 10 bits. The actual frequency | 4422 | * each output octet as 10 bits. The actual frequency |
4446 | * is stored as a divider into a 100MHz clock, and the | 4423 | * is stored as a divider into a 100MHz clock, and the |
@@ -4451,6 +4428,14 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
4451 | link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; | 4428 | link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; |
4452 | } | 4429 | } |
4453 | 4430 | ||
4431 | /* [e]DP over FDI requires target mode clock instead of link clock. */ | ||
4432 | if (edp_encoder) | ||
4433 | target_clock = intel_edp_target_clock(edp_encoder, mode); | ||
4434 | else if (is_dp) | ||
4435 | target_clock = mode->clock; | ||
4436 | else | ||
4437 | target_clock = adjusted_mode->clock; | ||
4438 | |||
4454 | /* determine panel color depth */ | 4439 | /* determine panel color depth */ |
4455 | temp = I915_READ(PIPECONF(pipe)); | 4440 | temp = I915_READ(PIPECONF(pipe)); |
4456 | temp &= ~PIPE_BPC_MASK; | 4441 | temp &= ~PIPE_BPC_MASK; |
@@ -4662,16 +4647,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
4662 | if (is_lvds && has_reduced_clock && i915_powersave) { | 4647 | if (is_lvds && has_reduced_clock && i915_powersave) { |
4663 | I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2); | 4648 | I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2); |
4664 | intel_crtc->lowfreq_avail = true; | 4649 | intel_crtc->lowfreq_avail = true; |
4665 | if (HAS_PIPE_CXSR(dev)) { | ||
4666 | DRM_DEBUG_KMS("enabling CxSR downclocking\n"); | ||
4667 | pipeconf |= PIPECONF_CXSR_DOWNCLOCK; | ||
4668 | } | ||
4669 | } else { | 4650 | } else { |
4670 | I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp); | 4651 | I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp); |
4671 | if (HAS_PIPE_CXSR(dev)) { | ||
4672 | DRM_DEBUG_KMS("disabling CxSR downclocking\n"); | ||
4673 | pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; | ||
4674 | } | ||
4675 | } | 4652 | } |
4676 | } | 4653 | } |
4677 | 4654 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c0449324143c..76a708029dcb 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -155,6 +155,18 @@ intel_edp_link_config(struct intel_encoder *intel_encoder, | |||
155 | *link_bw = 270000; | 155 | *link_bw = 270000; |
156 | } | 156 | } |
157 | 157 | ||
158 | int | ||
159 | intel_edp_target_clock(struct intel_encoder *intel_encoder, | ||
160 | struct drm_display_mode *mode) | ||
161 | { | ||
162 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); | ||
163 | |||
164 | if (intel_dp->panel_fixed_mode) | ||
165 | return intel_dp->panel_fixed_mode->clock; | ||
166 | else | ||
167 | return mode->clock; | ||
168 | } | ||
169 | |||
158 | static int | 170 | static int |
159 | intel_dp_max_lane_count(struct intel_dp *intel_dp) | 171 | intel_dp_max_lane_count(struct intel_dp *intel_dp) |
160 | { | 172 | { |
@@ -225,7 +237,7 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes) | |||
225 | static bool | 237 | static bool |
226 | intel_dp_adjust_dithering(struct intel_dp *intel_dp, | 238 | intel_dp_adjust_dithering(struct intel_dp *intel_dp, |
227 | struct drm_display_mode *mode, | 239 | struct drm_display_mode *mode, |
228 | struct drm_display_mode *adjusted_mode) | 240 | bool adjust_mode) |
229 | { | 241 | { |
230 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); | 242 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); |
231 | int max_lanes = intel_dp_max_lane_count(intel_dp); | 243 | int max_lanes = intel_dp_max_lane_count(intel_dp); |
@@ -239,8 +251,8 @@ intel_dp_adjust_dithering(struct intel_dp *intel_dp, | |||
239 | if (mode_rate > max_rate) | 251 | if (mode_rate > max_rate) |
240 | return false; | 252 | return false; |
241 | 253 | ||
242 | if (adjusted_mode) | 254 | if (adjust_mode) |
243 | adjusted_mode->private_flags | 255 | mode->private_flags |
244 | |= INTEL_MODE_DP_FORCE_6BPC; | 256 | |= INTEL_MODE_DP_FORCE_6BPC; |
245 | 257 | ||
246 | return true; | 258 | return true; |
@@ -263,7 +275,7 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
263 | return MODE_PANEL; | 275 | return MODE_PANEL; |
264 | } | 276 | } |
265 | 277 | ||
266 | if (!intel_dp_adjust_dithering(intel_dp, mode, NULL)) | 278 | if (!intel_dp_adjust_dithering(intel_dp, mode, false)) |
267 | return MODE_CLOCK_HIGH; | 279 | return MODE_CLOCK_HIGH; |
268 | 280 | ||
269 | if (mode->clock < 10000) | 281 | if (mode->clock < 10000) |
@@ -706,25 +718,20 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
706 | intel_fixed_panel_mode(intel_dp->panel_fixed_mode, adjusted_mode); | 718 | intel_fixed_panel_mode(intel_dp->panel_fixed_mode, adjusted_mode); |
707 | intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN, | 719 | intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN, |
708 | mode, adjusted_mode); | 720 | mode, adjusted_mode); |
709 | /* | ||
710 | * the mode->clock is used to calculate the Data&Link M/N | ||
711 | * of the pipe. For the eDP the fixed clock should be used. | ||
712 | */ | ||
713 | mode->clock = intel_dp->panel_fixed_mode->clock; | ||
714 | } | 721 | } |
715 | 722 | ||
716 | if (mode->flags & DRM_MODE_FLAG_DBLCLK) | 723 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) |
717 | return false; | 724 | return false; |
718 | 725 | ||
719 | DRM_DEBUG_KMS("DP link computation with max lane count %i " | 726 | DRM_DEBUG_KMS("DP link computation with max lane count %i " |
720 | "max bw %02x pixel clock %iKHz\n", | 727 | "max bw %02x pixel clock %iKHz\n", |
721 | max_lane_count, bws[max_clock], mode->clock); | 728 | max_lane_count, bws[max_clock], adjusted_mode->clock); |
722 | 729 | ||
723 | if (!intel_dp_adjust_dithering(intel_dp, mode, adjusted_mode)) | 730 | if (!intel_dp_adjust_dithering(intel_dp, adjusted_mode, true)) |
724 | return false; | 731 | return false; |
725 | 732 | ||
726 | bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; | 733 | bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; |
727 | mode_rate = intel_dp_link_required(mode->clock, bpp); | 734 | mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp); |
728 | 735 | ||
729 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { | 736 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { |
730 | for (clock = 0; clock <= max_clock; clock++) { | 737 | for (clock = 0; clock <= max_clock; clock++) { |
@@ -1922,7 +1929,7 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1922 | DP |= DP_LINK_TRAIN_OFF; | 1929 | DP |= DP_LINK_TRAIN_OFF; |
1923 | } | 1930 | } |
1924 | 1931 | ||
1925 | if (!HAS_PCH_CPT(dev) && | 1932 | if (HAS_PCH_IBX(dev) && |
1926 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { | 1933 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { |
1927 | struct drm_crtc *crtc = intel_dp->base.base.crtc; | 1934 | struct drm_crtc *crtc = intel_dp->base.base.crtc; |
1928 | 1935 | ||
@@ -2099,25 +2106,23 @@ g4x_dp_detect(struct intel_dp *intel_dp) | |||
2099 | { | 2106 | { |
2100 | struct drm_device *dev = intel_dp->base.base.dev; | 2107 | struct drm_device *dev = intel_dp->base.base.dev; |
2101 | struct drm_i915_private *dev_priv = dev->dev_private; | 2108 | struct drm_i915_private *dev_priv = dev->dev_private; |
2102 | uint32_t temp, bit; | 2109 | uint32_t bit; |
2103 | 2110 | ||
2104 | switch (intel_dp->output_reg) { | 2111 | switch (intel_dp->output_reg) { |
2105 | case DP_B: | 2112 | case DP_B: |
2106 | bit = DPB_HOTPLUG_INT_STATUS; | 2113 | bit = DPB_HOTPLUG_LIVE_STATUS; |
2107 | break; | 2114 | break; |
2108 | case DP_C: | 2115 | case DP_C: |
2109 | bit = DPC_HOTPLUG_INT_STATUS; | 2116 | bit = DPC_HOTPLUG_LIVE_STATUS; |
2110 | break; | 2117 | break; |
2111 | case DP_D: | 2118 | case DP_D: |
2112 | bit = DPD_HOTPLUG_INT_STATUS; | 2119 | bit = DPD_HOTPLUG_LIVE_STATUS; |
2113 | break; | 2120 | break; |
2114 | default: | 2121 | default: |
2115 | return connector_status_unknown; | 2122 | return connector_status_unknown; |
2116 | } | 2123 | } |
2117 | 2124 | ||
2118 | temp = I915_READ(PORT_HOTPLUG_STAT); | 2125 | if ((I915_READ(PORT_HOTPLUG_STAT) & bit) == 0) |
2119 | |||
2120 | if ((temp & bit) == 0) | ||
2121 | return connector_status_disconnected; | 2126 | return connector_status_disconnected; |
2122 | 2127 | ||
2123 | return intel_dp_detect_dpcd(intel_dp); | 2128 | return intel_dp_detect_dpcd(intel_dp); |
@@ -2520,19 +2525,19 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
2520 | case DP_B: | 2525 | case DP_B: |
2521 | case PCH_DP_B: | 2526 | case PCH_DP_B: |
2522 | dev_priv->hotplug_supported_mask |= | 2527 | dev_priv->hotplug_supported_mask |= |
2523 | HDMIB_HOTPLUG_INT_STATUS; | 2528 | DPB_HOTPLUG_INT_STATUS; |
2524 | name = "DPDDC-B"; | 2529 | name = "DPDDC-B"; |
2525 | break; | 2530 | break; |
2526 | case DP_C: | 2531 | case DP_C: |
2527 | case PCH_DP_C: | 2532 | case PCH_DP_C: |
2528 | dev_priv->hotplug_supported_mask |= | 2533 | dev_priv->hotplug_supported_mask |= |
2529 | HDMIC_HOTPLUG_INT_STATUS; | 2534 | DPC_HOTPLUG_INT_STATUS; |
2530 | name = "DPDDC-C"; | 2535 | name = "DPDDC-C"; |
2531 | break; | 2536 | break; |
2532 | case DP_D: | 2537 | case DP_D: |
2533 | case PCH_DP_D: | 2538 | case PCH_DP_D: |
2534 | dev_priv->hotplug_supported_mask |= | 2539 | dev_priv->hotplug_supported_mask |= |
2535 | HDMID_HOTPLUG_INT_STATUS; | 2540 | DPD_HOTPLUG_INT_STATUS; |
2536 | name = "DPDDC-D"; | 2541 | name = "DPDDC-D"; |
2537 | break; | 2542 | break; |
2538 | } | 2543 | } |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3e0918834e7e..c35edd7ca84d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -301,6 +301,8 @@ struct intel_hdmi { | |||
301 | enum hdmi_force_audio force_audio; | 301 | enum hdmi_force_audio force_audio; |
302 | void (*write_infoframe)(struct drm_encoder *encoder, | 302 | void (*write_infoframe)(struct drm_encoder *encoder, |
303 | struct dip_infoframe *frame); | 303 | struct dip_infoframe *frame); |
304 | void (*set_infoframes)(struct drm_encoder *encoder, | ||
305 | struct drm_display_mode *adjusted_mode); | ||
304 | }; | 306 | }; |
305 | 307 | ||
306 | static inline struct drm_crtc * | 308 | static inline struct drm_crtc * |
@@ -343,9 +345,6 @@ extern void intel_attach_broadcast_rgb_property(struct drm_connector *connector) | |||
343 | extern void intel_crt_init(struct drm_device *dev); | 345 | extern void intel_crt_init(struct drm_device *dev); |
344 | extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); | 346 | extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); |
345 | extern struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder); | 347 | extern struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder); |
346 | extern void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, | ||
347 | struct drm_display_mode *adjusted_mode); | ||
348 | extern void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder); | ||
349 | extern void intel_dip_infoframe_csum(struct dip_infoframe *avi_if); | 348 | extern void intel_dip_infoframe_csum(struct dip_infoframe *avi_if); |
350 | extern bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, | 349 | extern bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, |
351 | bool is_sdvob); | 350 | bool is_sdvob); |
@@ -360,6 +359,8 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
360 | struct drm_display_mode *adjusted_mode); | 359 | struct drm_display_mode *adjusted_mode); |
361 | extern bool intel_dpd_is_edp(struct drm_device *dev); | 360 | extern bool intel_dpd_is_edp(struct drm_device *dev); |
362 | extern void intel_edp_link_config(struct intel_encoder *, int *, int *); | 361 | extern void intel_edp_link_config(struct intel_encoder *, int *, int *); |
362 | extern int intel_edp_target_clock(struct intel_encoder *, | ||
363 | struct drm_display_mode *mode); | ||
363 | extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder); | 364 | extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder); |
364 | extern int intel_plane_init(struct drm_device *dev, enum pipe pipe); | 365 | extern int intel_plane_init(struct drm_device *dev, enum pipe pipe); |
365 | extern void intel_flush_display_plane(struct drm_i915_private *dev_priv, | 366 | extern void intel_flush_display_plane(struct drm_i915_private *dev_priv, |
@@ -372,7 +373,7 @@ extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | |||
372 | struct drm_display_mode *adjusted_mode); | 373 | struct drm_display_mode *adjusted_mode); |
373 | extern void intel_pch_panel_fitting(struct drm_device *dev, | 374 | extern void intel_pch_panel_fitting(struct drm_device *dev, |
374 | int fitting_mode, | 375 | int fitting_mode, |
375 | struct drm_display_mode *mode, | 376 | const struct drm_display_mode *mode, |
376 | struct drm_display_mode *adjusted_mode); | 377 | struct drm_display_mode *adjusted_mode); |
377 | extern u32 intel_panel_get_max_backlight(struct drm_device *dev); | 378 | extern u32 intel_panel_get_max_backlight(struct drm_device *dev); |
378 | extern u32 intel_panel_get_backlight(struct drm_device *dev); | 379 | extern u32 intel_panel_get_backlight(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 2ead3bf7c21d..b507d38faa10 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -121,36 +121,31 @@ static void g4x_write_infoframe(struct drm_encoder *encoder, | |||
121 | uint32_t *data = (uint32_t *)frame; | 121 | uint32_t *data = (uint32_t *)frame; |
122 | struct drm_device *dev = encoder->dev; | 122 | struct drm_device *dev = encoder->dev; |
123 | struct drm_i915_private *dev_priv = dev->dev_private; | 123 | struct drm_i915_private *dev_priv = dev->dev_private; |
124 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | ||
125 | u32 val = I915_READ(VIDEO_DIP_CTL); | 124 | u32 val = I915_READ(VIDEO_DIP_CTL); |
126 | unsigned i, len = DIP_HEADER_SIZE + frame->len; | 125 | unsigned i, len = DIP_HEADER_SIZE + frame->len; |
127 | 126 | ||
128 | val &= ~VIDEO_DIP_PORT_MASK; | 127 | WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); |
129 | if (intel_hdmi->sdvox_reg == SDVOB) | ||
130 | val |= VIDEO_DIP_PORT_B; | ||
131 | else if (intel_hdmi->sdvox_reg == SDVOC) | ||
132 | val |= VIDEO_DIP_PORT_C; | ||
133 | else | ||
134 | return; | ||
135 | 128 | ||
136 | val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ | 129 | val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ |
137 | val |= g4x_infoframe_index(frame); | 130 | val |= g4x_infoframe_index(frame); |
138 | 131 | ||
139 | val &= ~g4x_infoframe_enable(frame); | 132 | val &= ~g4x_infoframe_enable(frame); |
140 | val |= VIDEO_DIP_ENABLE; | ||
141 | 133 | ||
142 | I915_WRITE(VIDEO_DIP_CTL, val); | 134 | I915_WRITE(VIDEO_DIP_CTL, val); |
143 | 135 | ||
136 | mmiowb(); | ||
144 | for (i = 0; i < len; i += 4) { | 137 | for (i = 0; i < len; i += 4) { |
145 | I915_WRITE(VIDEO_DIP_DATA, *data); | 138 | I915_WRITE(VIDEO_DIP_DATA, *data); |
146 | data++; | 139 | data++; |
147 | } | 140 | } |
141 | mmiowb(); | ||
148 | 142 | ||
149 | val |= g4x_infoframe_enable(frame); | 143 | val |= g4x_infoframe_enable(frame); |
150 | val &= ~VIDEO_DIP_FREQ_MASK; | 144 | val &= ~VIDEO_DIP_FREQ_MASK; |
151 | val |= VIDEO_DIP_FREQ_VSYNC; | 145 | val |= VIDEO_DIP_FREQ_VSYNC; |
152 | 146 | ||
153 | I915_WRITE(VIDEO_DIP_CTL, val); | 147 | I915_WRITE(VIDEO_DIP_CTL, val); |
148 | POSTING_READ(VIDEO_DIP_CTL); | ||
154 | } | 149 | } |
155 | 150 | ||
156 | static void ibx_write_infoframe(struct drm_encoder *encoder, | 151 | static void ibx_write_infoframe(struct drm_encoder *encoder, |
@@ -160,46 +155,32 @@ static void ibx_write_infoframe(struct drm_encoder *encoder, | |||
160 | struct drm_device *dev = encoder->dev; | 155 | struct drm_device *dev = encoder->dev; |
161 | struct drm_i915_private *dev_priv = dev->dev_private; | 156 | struct drm_i915_private *dev_priv = dev->dev_private; |
162 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 157 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
163 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | ||
164 | int reg = TVIDEO_DIP_CTL(intel_crtc->pipe); | 158 | int reg = TVIDEO_DIP_CTL(intel_crtc->pipe); |
165 | unsigned i, len = DIP_HEADER_SIZE + frame->len; | 159 | unsigned i, len = DIP_HEADER_SIZE + frame->len; |
166 | u32 val = I915_READ(reg); | 160 | u32 val = I915_READ(reg); |
167 | 161 | ||
168 | val &= ~VIDEO_DIP_PORT_MASK; | 162 | WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); |
169 | switch (intel_hdmi->sdvox_reg) { | ||
170 | case HDMIB: | ||
171 | val |= VIDEO_DIP_PORT_B; | ||
172 | break; | ||
173 | case HDMIC: | ||
174 | val |= VIDEO_DIP_PORT_C; | ||
175 | break; | ||
176 | case HDMID: | ||
177 | val |= VIDEO_DIP_PORT_D; | ||
178 | break; | ||
179 | default: | ||
180 | return; | ||
181 | } | ||
182 | |||
183 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
184 | 163 | ||
185 | val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ | 164 | val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ |
186 | val |= g4x_infoframe_index(frame); | 165 | val |= g4x_infoframe_index(frame); |
187 | 166 | ||
188 | val &= ~g4x_infoframe_enable(frame); | 167 | val &= ~g4x_infoframe_enable(frame); |
189 | val |= VIDEO_DIP_ENABLE; | ||
190 | 168 | ||
191 | I915_WRITE(reg, val); | 169 | I915_WRITE(reg, val); |
192 | 170 | ||
171 | mmiowb(); | ||
193 | for (i = 0; i < len; i += 4) { | 172 | for (i = 0; i < len; i += 4) { |
194 | I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); | 173 | I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); |
195 | data++; | 174 | data++; |
196 | } | 175 | } |
176 | mmiowb(); | ||
197 | 177 | ||
198 | val |= g4x_infoframe_enable(frame); | 178 | val |= g4x_infoframe_enable(frame); |
199 | val &= ~VIDEO_DIP_FREQ_MASK; | 179 | val &= ~VIDEO_DIP_FREQ_MASK; |
200 | val |= VIDEO_DIP_FREQ_VSYNC; | 180 | val |= VIDEO_DIP_FREQ_VSYNC; |
201 | 181 | ||
202 | I915_WRITE(reg, val); | 182 | I915_WRITE(reg, val); |
183 | POSTING_READ(reg); | ||
203 | } | 184 | } |
204 | 185 | ||
205 | static void cpt_write_infoframe(struct drm_encoder *encoder, | 186 | static void cpt_write_infoframe(struct drm_encoder *encoder, |
@@ -213,32 +194,31 @@ static void cpt_write_infoframe(struct drm_encoder *encoder, | |||
213 | unsigned i, len = DIP_HEADER_SIZE + frame->len; | 194 | unsigned i, len = DIP_HEADER_SIZE + frame->len; |
214 | u32 val = I915_READ(reg); | 195 | u32 val = I915_READ(reg); |
215 | 196 | ||
216 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 197 | WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); |
217 | 198 | ||
218 | val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ | 199 | val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ |
219 | val |= g4x_infoframe_index(frame); | 200 | val |= g4x_infoframe_index(frame); |
220 | 201 | ||
221 | /* The DIP control register spec says that we need to update the AVI | 202 | /* The DIP control register spec says that we need to update the AVI |
222 | * infoframe without clearing its enable bit */ | 203 | * infoframe without clearing its enable bit */ |
223 | if (frame->type == DIP_TYPE_AVI) | 204 | if (frame->type != DIP_TYPE_AVI) |
224 | val |= VIDEO_DIP_ENABLE_AVI; | ||
225 | else | ||
226 | val &= ~g4x_infoframe_enable(frame); | 205 | val &= ~g4x_infoframe_enable(frame); |
227 | 206 | ||
228 | val |= VIDEO_DIP_ENABLE; | ||
229 | |||
230 | I915_WRITE(reg, val); | 207 | I915_WRITE(reg, val); |
231 | 208 | ||
209 | mmiowb(); | ||
232 | for (i = 0; i < len; i += 4) { | 210 | for (i = 0; i < len; i += 4) { |
233 | I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); | 211 | I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); |
234 | data++; | 212 | data++; |
235 | } | 213 | } |
214 | mmiowb(); | ||
236 | 215 | ||
237 | val |= g4x_infoframe_enable(frame); | 216 | val |= g4x_infoframe_enable(frame); |
238 | val &= ~VIDEO_DIP_FREQ_MASK; | 217 | val &= ~VIDEO_DIP_FREQ_MASK; |
239 | val |= VIDEO_DIP_FREQ_VSYNC; | 218 | val |= VIDEO_DIP_FREQ_VSYNC; |
240 | 219 | ||
241 | I915_WRITE(reg, val); | 220 | I915_WRITE(reg, val); |
221 | POSTING_READ(reg); | ||
242 | } | 222 | } |
243 | 223 | ||
244 | static void vlv_write_infoframe(struct drm_encoder *encoder, | 224 | static void vlv_write_infoframe(struct drm_encoder *encoder, |
@@ -252,26 +232,28 @@ static void vlv_write_infoframe(struct drm_encoder *encoder, | |||
252 | unsigned i, len = DIP_HEADER_SIZE + frame->len; | 232 | unsigned i, len = DIP_HEADER_SIZE + frame->len; |
253 | u32 val = I915_READ(reg); | 233 | u32 val = I915_READ(reg); |
254 | 234 | ||
255 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 235 | WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); |
256 | 236 | ||
257 | val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ | 237 | val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ |
258 | val |= g4x_infoframe_index(frame); | 238 | val |= g4x_infoframe_index(frame); |
259 | 239 | ||
260 | val &= ~g4x_infoframe_enable(frame); | 240 | val &= ~g4x_infoframe_enable(frame); |
261 | val |= VIDEO_DIP_ENABLE; | ||
262 | 241 | ||
263 | I915_WRITE(reg, val); | 242 | I915_WRITE(reg, val); |
264 | 243 | ||
244 | mmiowb(); | ||
265 | for (i = 0; i < len; i += 4) { | 245 | for (i = 0; i < len; i += 4) { |
266 | I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), *data); | 246 | I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), *data); |
267 | data++; | 247 | data++; |
268 | } | 248 | } |
249 | mmiowb(); | ||
269 | 250 | ||
270 | val |= g4x_infoframe_enable(frame); | 251 | val |= g4x_infoframe_enable(frame); |
271 | val &= ~VIDEO_DIP_FREQ_MASK; | 252 | val &= ~VIDEO_DIP_FREQ_MASK; |
272 | val |= VIDEO_DIP_FREQ_VSYNC; | 253 | val |= VIDEO_DIP_FREQ_VSYNC; |
273 | 254 | ||
274 | I915_WRITE(reg, val); | 255 | I915_WRITE(reg, val); |
256 | POSTING_READ(reg); | ||
275 | } | 257 | } |
276 | 258 | ||
277 | static void hsw_write_infoframe(struct drm_encoder *encoder, | 259 | static void hsw_write_infoframe(struct drm_encoder *encoder, |
@@ -289,18 +271,19 @@ static void hsw_write_infoframe(struct drm_encoder *encoder, | |||
289 | if (data_reg == 0) | 271 | if (data_reg == 0) |
290 | return; | 272 | return; |
291 | 273 | ||
292 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
293 | |||
294 | val &= ~hsw_infoframe_enable(frame); | 274 | val &= ~hsw_infoframe_enable(frame); |
295 | I915_WRITE(ctl_reg, val); | 275 | I915_WRITE(ctl_reg, val); |
296 | 276 | ||
277 | mmiowb(); | ||
297 | for (i = 0; i < len; i += 4) { | 278 | for (i = 0; i < len; i += 4) { |
298 | I915_WRITE(data_reg + i, *data); | 279 | I915_WRITE(data_reg + i, *data); |
299 | data++; | 280 | data++; |
300 | } | 281 | } |
282 | mmiowb(); | ||
301 | 283 | ||
302 | val |= hsw_infoframe_enable(frame); | 284 | val |= hsw_infoframe_enable(frame); |
303 | I915_WRITE(ctl_reg, val); | 285 | I915_WRITE(ctl_reg, val); |
286 | POSTING_READ(ctl_reg); | ||
304 | } | 287 | } |
305 | 288 | ||
306 | static void intel_set_infoframe(struct drm_encoder *encoder, | 289 | static void intel_set_infoframe(struct drm_encoder *encoder, |
@@ -308,14 +291,11 @@ static void intel_set_infoframe(struct drm_encoder *encoder, | |||
308 | { | 291 | { |
309 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | 292 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
310 | 293 | ||
311 | if (!intel_hdmi->has_hdmi_sink) | ||
312 | return; | ||
313 | |||
314 | intel_dip_infoframe_csum(frame); | 294 | intel_dip_infoframe_csum(frame); |
315 | intel_hdmi->write_infoframe(encoder, frame); | 295 | intel_hdmi->write_infoframe(encoder, frame); |
316 | } | 296 | } |
317 | 297 | ||
318 | void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, | 298 | static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, |
319 | struct drm_display_mode *adjusted_mode) | 299 | struct drm_display_mode *adjusted_mode) |
320 | { | 300 | { |
321 | struct dip_infoframe avi_if = { | 301 | struct dip_infoframe avi_if = { |
@@ -330,7 +310,7 @@ void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, | |||
330 | intel_set_infoframe(encoder, &avi_if); | 310 | intel_set_infoframe(encoder, &avi_if); |
331 | } | 311 | } |
332 | 312 | ||
333 | void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder) | 313 | static void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder) |
334 | { | 314 | { |
335 | struct dip_infoframe spd_if; | 315 | struct dip_infoframe spd_if; |
336 | 316 | ||
@@ -345,6 +325,213 @@ void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder) | |||
345 | intel_set_infoframe(encoder, &spd_if); | 325 | intel_set_infoframe(encoder, &spd_if); |
346 | } | 326 | } |
347 | 327 | ||
328 | static void g4x_set_infoframes(struct drm_encoder *encoder, | ||
329 | struct drm_display_mode *adjusted_mode) | ||
330 | { | ||
331 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | ||
332 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | ||
333 | u32 reg = VIDEO_DIP_CTL; | ||
334 | u32 val = I915_READ(reg); | ||
335 | u32 port; | ||
336 | |||
337 | /* If the registers were not initialized yet, they might be zeroes, | ||
338 | * which means we're selecting the AVI DIP and we're setting its | ||
339 | * frequency to once. This seems to really confuse the HW and make | ||
340 | * things stop working (the register spec says the AVI always needs to | ||
341 | * be sent every VSync). So here we avoid writing to the register more | ||
342 | * than we need and also explicitly select the AVI DIP and explicitly | ||
343 | * set its frequency to every VSync. Avoiding to write it twice seems to | ||
344 | * be enough to solve the problem, but being defensive shouldn't hurt us | ||
345 | * either. */ | ||
346 | val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC; | ||
347 | |||
348 | if (!intel_hdmi->has_hdmi_sink) { | ||
349 | if (!(val & VIDEO_DIP_ENABLE)) | ||
350 | return; | ||
351 | val &= ~VIDEO_DIP_ENABLE; | ||
352 | I915_WRITE(reg, val); | ||
353 | POSTING_READ(reg); | ||
354 | return; | ||
355 | } | ||
356 | |||
357 | switch (intel_hdmi->sdvox_reg) { | ||
358 | case SDVOB: | ||
359 | port = VIDEO_DIP_PORT_B; | ||
360 | break; | ||
361 | case SDVOC: | ||
362 | port = VIDEO_DIP_PORT_C; | ||
363 | break; | ||
364 | default: | ||
365 | return; | ||
366 | } | ||
367 | |||
368 | if (port != (val & VIDEO_DIP_PORT_MASK)) { | ||
369 | if (val & VIDEO_DIP_ENABLE) { | ||
370 | val &= ~VIDEO_DIP_ENABLE; | ||
371 | I915_WRITE(reg, val); | ||
372 | POSTING_READ(reg); | ||
373 | } | ||
374 | val &= ~VIDEO_DIP_PORT_MASK; | ||
375 | val |= port; | ||
376 | } | ||
377 | |||
378 | val |= VIDEO_DIP_ENABLE; | ||
379 | val &= ~VIDEO_DIP_ENABLE_VENDOR; | ||
380 | |||
381 | I915_WRITE(reg, val); | ||
382 | POSTING_READ(reg); | ||
383 | |||
384 | intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); | ||
385 | intel_hdmi_set_spd_infoframe(encoder); | ||
386 | } | ||
387 | |||
388 | static void ibx_set_infoframes(struct drm_encoder *encoder, | ||
389 | struct drm_display_mode *adjusted_mode) | ||
390 | { | ||
391 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | ||
392 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | ||
393 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | ||
394 | u32 reg = TVIDEO_DIP_CTL(intel_crtc->pipe); | ||
395 | u32 val = I915_READ(reg); | ||
396 | u32 port; | ||
397 | |||
398 | /* See the big comment in g4x_set_infoframes() */ | ||
399 | val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC; | ||
400 | |||
401 | if (!intel_hdmi->has_hdmi_sink) { | ||
402 | if (!(val & VIDEO_DIP_ENABLE)) | ||
403 | return; | ||
404 | val &= ~VIDEO_DIP_ENABLE; | ||
405 | I915_WRITE(reg, val); | ||
406 | POSTING_READ(reg); | ||
407 | return; | ||
408 | } | ||
409 | |||
410 | switch (intel_hdmi->sdvox_reg) { | ||
411 | case HDMIB: | ||
412 | port = VIDEO_DIP_PORT_B; | ||
413 | break; | ||
414 | case HDMIC: | ||
415 | port = VIDEO_DIP_PORT_C; | ||
416 | break; | ||
417 | case HDMID: | ||
418 | port = VIDEO_DIP_PORT_D; | ||
419 | break; | ||
420 | default: | ||
421 | return; | ||
422 | } | ||
423 | |||
424 | if (port != (val & VIDEO_DIP_PORT_MASK)) { | ||
425 | if (val & VIDEO_DIP_ENABLE) { | ||
426 | val &= ~VIDEO_DIP_ENABLE; | ||
427 | I915_WRITE(reg, val); | ||
428 | POSTING_READ(reg); | ||
429 | } | ||
430 | val &= ~VIDEO_DIP_PORT_MASK; | ||
431 | val |= port; | ||
432 | } | ||
433 | |||
434 | val |= VIDEO_DIP_ENABLE; | ||
435 | val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT | | ||
436 | VIDEO_DIP_ENABLE_GCP); | ||
437 | |||
438 | I915_WRITE(reg, val); | ||
439 | POSTING_READ(reg); | ||
440 | |||
441 | intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); | ||
442 | intel_hdmi_set_spd_infoframe(encoder); | ||
443 | } | ||
444 | |||
445 | static void cpt_set_infoframes(struct drm_encoder *encoder, | ||
446 | struct drm_display_mode *adjusted_mode) | ||
447 | { | ||
448 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | ||
449 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | ||
450 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | ||
451 | u32 reg = TVIDEO_DIP_CTL(intel_crtc->pipe); | ||
452 | u32 val = I915_READ(reg); | ||
453 | |||
454 | /* See the big comment in g4x_set_infoframes() */ | ||
455 | val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC; | ||
456 | |||
457 | if (!intel_hdmi->has_hdmi_sink) { | ||
458 | if (!(val & VIDEO_DIP_ENABLE)) | ||
459 | return; | ||
460 | val &= ~(VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI); | ||
461 | I915_WRITE(reg, val); | ||
462 | POSTING_READ(reg); | ||
463 | return; | ||
464 | } | ||
465 | |||
466 | /* Set both together, unset both together: see the spec. */ | ||
467 | val |= VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI; | ||
468 | val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT | | ||
469 | VIDEO_DIP_ENABLE_GCP); | ||
470 | |||
471 | I915_WRITE(reg, val); | ||
472 | POSTING_READ(reg); | ||
473 | |||
474 | intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); | ||
475 | intel_hdmi_set_spd_infoframe(encoder); | ||
476 | } | ||
477 | |||
478 | static void vlv_set_infoframes(struct drm_encoder *encoder, | ||
479 | struct drm_display_mode *adjusted_mode) | ||
480 | { | ||
481 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | ||
482 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | ||
483 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | ||
484 | u32 reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe); | ||
485 | u32 val = I915_READ(reg); | ||
486 | |||
487 | /* See the big comment in g4x_set_infoframes() */ | ||
488 | val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC; | ||
489 | |||
490 | if (!intel_hdmi->has_hdmi_sink) { | ||
491 | if (!(val & VIDEO_DIP_ENABLE)) | ||
492 | return; | ||
493 | val &= ~VIDEO_DIP_ENABLE; | ||
494 | I915_WRITE(reg, val); | ||
495 | POSTING_READ(reg); | ||
496 | return; | ||
497 | } | ||
498 | |||
499 | val |= VIDEO_DIP_ENABLE; | ||
500 | val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT | | ||
501 | VIDEO_DIP_ENABLE_GCP); | ||
502 | |||
503 | I915_WRITE(reg, val); | ||
504 | POSTING_READ(reg); | ||
505 | |||
506 | intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); | ||
507 | intel_hdmi_set_spd_infoframe(encoder); | ||
508 | } | ||
509 | |||
510 | static void hsw_set_infoframes(struct drm_encoder *encoder, | ||
511 | struct drm_display_mode *adjusted_mode) | ||
512 | { | ||
513 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | ||
514 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | ||
515 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | ||
516 | u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->pipe); | ||
517 | u32 val = I915_READ(reg); | ||
518 | |||
519 | if (!intel_hdmi->has_hdmi_sink) { | ||
520 | I915_WRITE(reg, 0); | ||
521 | POSTING_READ(reg); | ||
522 | return; | ||
523 | } | ||
524 | |||
525 | val &= ~(VIDEO_DIP_ENABLE_VSC_HSW | VIDEO_DIP_ENABLE_GCP_HSW | | ||
526 | VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW); | ||
527 | |||
528 | I915_WRITE(reg, val); | ||
529 | POSTING_READ(reg); | ||
530 | |||
531 | intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); | ||
532 | intel_hdmi_set_spd_infoframe(encoder); | ||
533 | } | ||
534 | |||
348 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, | 535 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, |
349 | struct drm_display_mode *mode, | 536 | struct drm_display_mode *mode, |
350 | struct drm_display_mode *adjusted_mode) | 537 | struct drm_display_mode *adjusted_mode) |
@@ -355,7 +542,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
355 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | 542 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
356 | u32 sdvox; | 543 | u32 sdvox; |
357 | 544 | ||
358 | sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE; | 545 | sdvox = SDVO_ENCODING_HDMI; |
359 | if (!HAS_PCH_SPLIT(dev)) | 546 | if (!HAS_PCH_SPLIT(dev)) |
360 | sdvox |= intel_hdmi->color_range; | 547 | sdvox |= intel_hdmi->color_range; |
361 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | 548 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
@@ -388,8 +575,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
388 | I915_WRITE(intel_hdmi->sdvox_reg, sdvox); | 575 | I915_WRITE(intel_hdmi->sdvox_reg, sdvox); |
389 | POSTING_READ(intel_hdmi->sdvox_reg); | 576 | POSTING_READ(intel_hdmi->sdvox_reg); |
390 | 577 | ||
391 | intel_hdmi_set_avi_infoframe(encoder, adjusted_mode); | 578 | intel_hdmi->set_infoframes(encoder, adjusted_mode); |
392 | intel_hdmi_set_spd_infoframe(encoder); | ||
393 | } | 579 | } |
394 | 580 | ||
395 | static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | 581 | static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) |
@@ -452,6 +638,27 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, | |||
452 | return true; | 638 | return true; |
453 | } | 639 | } |
454 | 640 | ||
641 | static bool g4x_hdmi_connected(struct intel_hdmi *intel_hdmi) | ||
642 | { | ||
643 | struct drm_device *dev = intel_hdmi->base.base.dev; | ||
644 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
645 | uint32_t bit; | ||
646 | |||
647 | switch (intel_hdmi->sdvox_reg) { | ||
648 | case SDVOB: | ||
649 | bit = HDMIB_HOTPLUG_LIVE_STATUS; | ||
650 | break; | ||
651 | case SDVOC: | ||
652 | bit = HDMIC_HOTPLUG_LIVE_STATUS; | ||
653 | break; | ||
654 | default: | ||
655 | bit = 0; | ||
656 | break; | ||
657 | } | ||
658 | |||
659 | return I915_READ(PORT_HOTPLUG_STAT) & bit; | ||
660 | } | ||
661 | |||
455 | static enum drm_connector_status | 662 | static enum drm_connector_status |
456 | intel_hdmi_detect(struct drm_connector *connector, bool force) | 663 | intel_hdmi_detect(struct drm_connector *connector, bool force) |
457 | { | 664 | { |
@@ -460,6 +667,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) | |||
460 | struct edid *edid; | 667 | struct edid *edid; |
461 | enum drm_connector_status status = connector_status_disconnected; | 668 | enum drm_connector_status status = connector_status_disconnected; |
462 | 669 | ||
670 | if (IS_G4X(connector->dev) && !g4x_hdmi_connected(intel_hdmi)) | ||
671 | return status; | ||
672 | |||
463 | intel_hdmi->has_hdmi_sink = false; | 673 | intel_hdmi->has_hdmi_sink = false; |
464 | intel_hdmi->has_audio = false; | 674 | intel_hdmi->has_audio = false; |
465 | edid = drm_get_edid(connector, | 675 | edid = drm_get_edid(connector, |
@@ -633,7 +843,6 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
633 | struct intel_encoder *intel_encoder; | 843 | struct intel_encoder *intel_encoder; |
634 | struct intel_connector *intel_connector; | 844 | struct intel_connector *intel_connector; |
635 | struct intel_hdmi *intel_hdmi; | 845 | struct intel_hdmi *intel_hdmi; |
636 | int i; | ||
637 | 846 | ||
638 | intel_hdmi = kzalloc(sizeof(struct intel_hdmi), GFP_KERNEL); | 847 | intel_hdmi = kzalloc(sizeof(struct intel_hdmi), GFP_KERNEL); |
639 | if (!intel_hdmi) | 848 | if (!intel_hdmi) |
@@ -710,26 +919,19 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
710 | 919 | ||
711 | if (!HAS_PCH_SPLIT(dev)) { | 920 | if (!HAS_PCH_SPLIT(dev)) { |
712 | intel_hdmi->write_infoframe = g4x_write_infoframe; | 921 | intel_hdmi->write_infoframe = g4x_write_infoframe; |
713 | I915_WRITE(VIDEO_DIP_CTL, 0); | 922 | intel_hdmi->set_infoframes = g4x_set_infoframes; |
714 | } else if (IS_VALLEYVIEW(dev)) { | 923 | } else if (IS_VALLEYVIEW(dev)) { |
715 | intel_hdmi->write_infoframe = vlv_write_infoframe; | 924 | intel_hdmi->write_infoframe = vlv_write_infoframe; |
716 | for_each_pipe(i) | 925 | intel_hdmi->set_infoframes = vlv_set_infoframes; |
717 | I915_WRITE(VLV_TVIDEO_DIP_CTL(i), 0); | ||
718 | } else if (IS_HASWELL(dev)) { | 926 | } else if (IS_HASWELL(dev)) { |
719 | /* FIXME: Haswell has a new set of DIP frame registers, but we are | ||
720 | * just doing the minimal required for HDMI to work at this stage. | ||
721 | */ | ||
722 | intel_hdmi->write_infoframe = hsw_write_infoframe; | 927 | intel_hdmi->write_infoframe = hsw_write_infoframe; |
723 | for_each_pipe(i) | 928 | intel_hdmi->set_infoframes = hsw_set_infoframes; |
724 | I915_WRITE(HSW_TVIDEO_DIP_CTL(i), 0); | ||
725 | } else if (HAS_PCH_IBX(dev)) { | 929 | } else if (HAS_PCH_IBX(dev)) { |
726 | intel_hdmi->write_infoframe = ibx_write_infoframe; | 930 | intel_hdmi->write_infoframe = ibx_write_infoframe; |
727 | for_each_pipe(i) | 931 | intel_hdmi->set_infoframes = ibx_set_infoframes; |
728 | I915_WRITE(TVIDEO_DIP_CTL(i), 0); | ||
729 | } else { | 932 | } else { |
730 | intel_hdmi->write_infoframe = cpt_write_infoframe; | 933 | intel_hdmi->write_infoframe = cpt_write_infoframe; |
731 | for_each_pipe(i) | 934 | intel_hdmi->set_infoframes = cpt_set_infoframes; |
732 | I915_WRITE(TVIDEO_DIP_CTL(i), 0); | ||
733 | } | 935 | } |
734 | 936 | ||
735 | if (IS_HASWELL(dev)) | 937 | if (IS_HASWELL(dev)) |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 458743da3774..830d0dd610e1 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -226,7 +226,7 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay, | |||
226 | } | 226 | } |
227 | overlay->last_flip_req = request->seqno; | 227 | overlay->last_flip_req = request->seqno; |
228 | overlay->flip_tail = tail; | 228 | overlay->flip_tail = tail; |
229 | ret = i915_wait_request(ring, overlay->last_flip_req); | 229 | ret = i915_wait_seqno(ring, overlay->last_flip_req); |
230 | if (ret) | 230 | if (ret) |
231 | return ret; | 231 | return ret; |
232 | i915_gem_retire_requests(dev); | 232 | i915_gem_retire_requests(dev); |
@@ -452,7 +452,7 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay) | |||
452 | if (overlay->last_flip_req == 0) | 452 | if (overlay->last_flip_req == 0) |
453 | return 0; | 453 | return 0; |
454 | 454 | ||
455 | ret = i915_wait_request(ring, overlay->last_flip_req); | 455 | ret = i915_wait_seqno(ring, overlay->last_flip_req); |
456 | if (ret) | 456 | if (ret) |
457 | return ret; | 457 | return ret; |
458 | i915_gem_retire_requests(dev); | 458 | i915_gem_retire_requests(dev); |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 2a1625d84a69..7180cc828f94 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -56,7 +56,7 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | |||
56 | void | 56 | void |
57 | intel_pch_panel_fitting(struct drm_device *dev, | 57 | intel_pch_panel_fitting(struct drm_device *dev, |
58 | int fitting_mode, | 58 | int fitting_mode, |
59 | struct drm_display_mode *mode, | 59 | const struct drm_display_mode *mode, |
60 | struct drm_display_mode *adjusted_mode) | 60 | struct drm_display_mode *adjusted_mode) |
61 | { | 61 | { |
62 | struct drm_i915_private *dev_priv = dev->dev_private; | 62 | struct drm_i915_private *dev_priv = dev->dev_private; |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index e5b84ff89ca5..f30850b079e9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -438,6 +438,9 @@ static int init_render_ring(struct intel_ring_buffer *ring) | |||
438 | if (INTEL_INFO(dev)->gen >= 6) | 438 | if (INTEL_INFO(dev)->gen >= 6) |
439 | I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING)); | 439 | I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING)); |
440 | 440 | ||
441 | if (IS_IVYBRIDGE(dev)) | ||
442 | I915_WRITE_IMR(ring, ~GEN6_RENDER_L3_PARITY_ERROR); | ||
443 | |||
441 | return ret; | 444 | return ret; |
442 | } | 445 | } |
443 | 446 | ||
@@ -825,7 +828,11 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring) | |||
825 | 828 | ||
826 | spin_lock_irqsave(&dev_priv->irq_lock, flags); | 829 | spin_lock_irqsave(&dev_priv->irq_lock, flags); |
827 | if (ring->irq_refcount++ == 0) { | 830 | if (ring->irq_refcount++ == 0) { |
828 | I915_WRITE_IMR(ring, ~ring->irq_enable_mask); | 831 | if (IS_IVYBRIDGE(dev) && ring->id == RCS) |
832 | I915_WRITE_IMR(ring, ~(ring->irq_enable_mask | | ||
833 | GEN6_RENDER_L3_PARITY_ERROR)); | ||
834 | else | ||
835 | I915_WRITE_IMR(ring, ~ring->irq_enable_mask); | ||
829 | dev_priv->gt_irq_mask &= ~ring->irq_enable_mask; | 836 | dev_priv->gt_irq_mask &= ~ring->irq_enable_mask; |
830 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | 837 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); |
831 | POSTING_READ(GTIMR); | 838 | POSTING_READ(GTIMR); |
@@ -844,7 +851,10 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring) | |||
844 | 851 | ||
845 | spin_lock_irqsave(&dev_priv->irq_lock, flags); | 852 | spin_lock_irqsave(&dev_priv->irq_lock, flags); |
846 | if (--ring->irq_refcount == 0) { | 853 | if (--ring->irq_refcount == 0) { |
847 | I915_WRITE_IMR(ring, ~0); | 854 | if (IS_IVYBRIDGE(dev) && ring->id == RCS) |
855 | I915_WRITE_IMR(ring, ~GEN6_RENDER_L3_PARITY_ERROR); | ||
856 | else | ||
857 | I915_WRITE_IMR(ring, ~0); | ||
848 | dev_priv->gt_irq_mask |= ring->irq_enable_mask; | 858 | dev_priv->gt_irq_mask |= ring->irq_enable_mask; |
849 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); | 859 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); |
850 | POSTING_READ(GTIMR); | 860 | POSTING_READ(GTIMR); |
@@ -1100,7 +1110,7 @@ static int intel_ring_wait_seqno(struct intel_ring_buffer *ring, u32 seqno) | |||
1100 | was_interruptible = dev_priv->mm.interruptible; | 1110 | was_interruptible = dev_priv->mm.interruptible; |
1101 | dev_priv->mm.interruptible = false; | 1111 | dev_priv->mm.interruptible = false; |
1102 | 1112 | ||
1103 | ret = i915_wait_request(ring, seqno); | 1113 | ret = i915_wait_seqno(ring, seqno); |
1104 | 1114 | ||
1105 | dev_priv->mm.interruptible = was_interruptible; | 1115 | dev_priv->mm.interruptible = was_interruptible; |
1106 | if (!ret) | 1116 | if (!ret) |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index b6a9d45fc3c6..2f5106a488c5 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -140,9 +140,6 @@ struct intel_sdvo { | |||
140 | 140 | ||
141 | /* DDC bus used by this SDVO encoder */ | 141 | /* DDC bus used by this SDVO encoder */ |
142 | uint8_t ddc_bus; | 142 | uint8_t ddc_bus; |
143 | |||
144 | /* Input timings for adjusted_mode */ | ||
145 | struct intel_sdvo_dtd input_dtd; | ||
146 | }; | 143 | }; |
147 | 144 | ||
148 | struct intel_sdvo_connector { | 145 | struct intel_sdvo_connector { |
@@ -953,11 +950,15 @@ intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo, | |||
953 | return true; | 950 | return true; |
954 | } | 951 | } |
955 | 952 | ||
953 | /* Asks the sdvo controller for the preferred input mode given the output mode. | ||
954 | * Unfortunately we have to set up the full output mode to do that. */ | ||
956 | static bool | 955 | static bool |
957 | intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo, | 956 | intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo, |
958 | struct drm_display_mode *mode, | 957 | struct drm_display_mode *mode, |
959 | struct drm_display_mode *adjusted_mode) | 958 | struct drm_display_mode *adjusted_mode) |
960 | { | 959 | { |
960 | struct intel_sdvo_dtd input_dtd; | ||
961 | |||
961 | /* Reset the input timing to the screen. Assume always input 0. */ | 962 | /* Reset the input timing to the screen. Assume always input 0. */ |
962 | if (!intel_sdvo_set_target_input(intel_sdvo)) | 963 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
963 | return false; | 964 | return false; |
@@ -969,10 +970,10 @@ intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo, | |||
969 | return false; | 970 | return false; |
970 | 971 | ||
971 | if (!intel_sdvo_get_preferred_input_timing(intel_sdvo, | 972 | if (!intel_sdvo_get_preferred_input_timing(intel_sdvo, |
972 | &intel_sdvo->input_dtd)) | 973 | &input_dtd)) |
973 | return false; | 974 | return false; |
974 | 975 | ||
975 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &intel_sdvo->input_dtd); | 976 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
976 | 977 | ||
977 | return true; | 978 | return true; |
978 | } | 979 | } |
@@ -993,17 +994,17 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
993 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) | 994 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) |
994 | return false; | 995 | return false; |
995 | 996 | ||
996 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, | 997 | (void) intel_sdvo_get_preferred_input_mode(intel_sdvo, |
997 | mode, | 998 | mode, |
998 | adjusted_mode); | 999 | adjusted_mode); |
999 | } else if (intel_sdvo->is_lvds) { | 1000 | } else if (intel_sdvo->is_lvds) { |
1000 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, | 1001 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, |
1001 | intel_sdvo->sdvo_lvds_fixed_mode)) | 1002 | intel_sdvo->sdvo_lvds_fixed_mode)) |
1002 | return false; | 1003 | return false; |
1003 | 1004 | ||
1004 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, | 1005 | (void) intel_sdvo_get_preferred_input_mode(intel_sdvo, |
1005 | mode, | 1006 | mode, |
1006 | adjusted_mode); | 1007 | adjusted_mode); |
1007 | } | 1008 | } |
1008 | 1009 | ||
1009 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | 1010 | /* Make the CRTC code factor in the SDVO pixel multiplier. The |
@@ -1057,7 +1058,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1057 | intel_sdvo->sdvo_lvds_fixed_mode); | 1058 | intel_sdvo->sdvo_lvds_fixed_mode); |
1058 | else | 1059 | else |
1059 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); | 1060 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); |
1060 | (void) intel_sdvo_set_output_timing(intel_sdvo, &output_dtd); | 1061 | if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd)) |
1062 | DRM_INFO("Setting output timings on %s failed\n", | ||
1063 | SDVO_NAME(intel_sdvo)); | ||
1061 | 1064 | ||
1062 | /* Set the input timing to the screen. Assume always input 0. */ | 1065 | /* Set the input timing to the screen. Assume always input 0. */ |
1063 | if (!intel_sdvo_set_target_input(intel_sdvo)) | 1066 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
@@ -1079,7 +1082,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1079 | * adjusted_mode. | 1082 | * adjusted_mode. |
1080 | */ | 1083 | */ |
1081 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | 1084 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
1082 | (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); | 1085 | if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) |
1086 | DRM_INFO("Setting input timings on %s failed\n", | ||
1087 | SDVO_NAME(intel_sdvo)); | ||
1083 | 1088 | ||
1084 | switch (pixel_multiplier) { | 1089 | switch (pixel_multiplier) { |
1085 | default: | 1090 | default: |
@@ -1376,7 +1381,7 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) | |||
1376 | 1381 | ||
1377 | /* add 30ms delay when the output type might be TV */ | 1382 | /* add 30ms delay when the output type might be TV */ |
1378 | if (intel_sdvo->caps.output_flags & SDVO_TV_MASK) | 1383 | if (intel_sdvo->caps.output_flags & SDVO_TV_MASK) |
1379 | mdelay(30); | 1384 | msleep(30); |
1380 | 1385 | ||
1381 | if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) | 1386 | if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) |
1382 | return connector_status_unknown; | 1387 | return connector_status_unknown; |
@@ -2521,6 +2526,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2521 | struct drm_i915_private *dev_priv = dev->dev_private; | 2526 | struct drm_i915_private *dev_priv = dev->dev_private; |
2522 | struct intel_encoder *intel_encoder; | 2527 | struct intel_encoder *intel_encoder; |
2523 | struct intel_sdvo *intel_sdvo; | 2528 | struct intel_sdvo *intel_sdvo; |
2529 | u32 hotplug_mask; | ||
2524 | int i; | 2530 | int i; |
2525 | 2531 | ||
2526 | intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); | 2532 | intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); |
@@ -2552,10 +2558,18 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2552 | } | 2558 | } |
2553 | } | 2559 | } |
2554 | 2560 | ||
2555 | if (intel_sdvo->is_sdvob) | 2561 | hotplug_mask = 0; |
2556 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; | 2562 | if (IS_G4X(dev)) { |
2557 | else | 2563 | hotplug_mask = intel_sdvo->is_sdvob ? |
2558 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; | 2564 | SDVOB_HOTPLUG_INT_STATUS_G4X : SDVOC_HOTPLUG_INT_STATUS_G4X; |
2565 | } else if (IS_GEN4(dev)) { | ||
2566 | hotplug_mask = intel_sdvo->is_sdvob ? | ||
2567 | SDVOB_HOTPLUG_INT_STATUS_I965 : SDVOC_HOTPLUG_INT_STATUS_I965; | ||
2568 | } else { | ||
2569 | hotplug_mask = intel_sdvo->is_sdvob ? | ||
2570 | SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915; | ||
2571 | } | ||
2572 | dev_priv->hotplug_supported_mask |= hotplug_mask; | ||
2559 | 2573 | ||
2560 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); | 2574 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); |
2561 | 2575 | ||