aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMarek Olšák <maraeo@gmail.com>2012-03-18 22:09:33 -0400
committerDave Airlie <airlied@redhat.com>2012-03-20 04:44:29 -0400
commit788571313870610bd7eb444e0fdc86f7e5541ee2 (patch)
treed793645cdc98918ca5323d8a555b0a45f11f4f79 /drivers
parent7df7c547c5aada8c6b9ee5ce14139e0ff5c66369 (diff)
drm/radeon/kms: compute GPU addresses correctly on evergreen
There are also two fixes: - In DRAW_INDEX_2, we read idx_value, but should have read idx+1. - When correcting SQ_VTX_CONSTANT_WORD1_0.SIZE, we should subtract the offset. Signed-off-by: Marek Olšák <maraeo@gmail.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/evergreen_cs.c130
1 files changed, 103 insertions, 27 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
index 4674a688ad40..b39a089a15c3 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -1811,6 +1811,8 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
1811 { 1811 {
1812 int pred_op; 1812 int pred_op;
1813 int tmp; 1813 int tmp;
1814 uint64_t offset;
1815
1814 if (pkt->count != 1) { 1816 if (pkt->count != 1) {
1815 DRM_ERROR("bad SET PREDICATION\n"); 1817 DRM_ERROR("bad SET PREDICATION\n");
1816 return -EINVAL; 1818 return -EINVAL;
@@ -1834,8 +1836,12 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
1834 return -EINVAL; 1836 return -EINVAL;
1835 } 1837 }
1836 1838
1837 ib[idx + 0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff); 1839 offset = reloc->lobj.gpu_offset +
1838 ib[idx + 1] = tmp + (upper_32_bits(reloc->lobj.gpu_offset) & 0xff); 1840 (idx_value & 0xfffffff0) +
1841 ((u64)(tmp & 0xff) << 32);
1842
1843 ib[idx + 0] = offset;
1844 ib[idx + 1] = (tmp & 0xffffff00) | (upper_32_bits(offset) & 0xff);
1839 } 1845 }
1840 break; 1846 break;
1841 case PACKET3_CONTEXT_CONTROL: 1847 case PACKET3_CONTEXT_CONTROL:
@@ -1863,6 +1869,9 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
1863 } 1869 }
1864 break; 1870 break;
1865 case PACKET3_INDEX_BASE: 1871 case PACKET3_INDEX_BASE:
1872 {
1873 uint64_t offset;
1874
1866 if (pkt->count != 1) { 1875 if (pkt->count != 1) {
1867 DRM_ERROR("bad INDEX_BASE\n"); 1876 DRM_ERROR("bad INDEX_BASE\n");
1868 return -EINVAL; 1877 return -EINVAL;
@@ -1872,15 +1881,24 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
1872 DRM_ERROR("bad INDEX_BASE\n"); 1881 DRM_ERROR("bad INDEX_BASE\n");
1873 return -EINVAL; 1882 return -EINVAL;
1874 } 1883 }
1875 ib[idx+0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff); 1884
1876 ib[idx+1] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; 1885 offset = reloc->lobj.gpu_offset +
1886 idx_value +
1887 ((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32);
1888
1889 ib[idx+0] = offset;
1890 ib[idx+1] = upper_32_bits(offset) & 0xff;
1891
1877 r = evergreen_cs_track_check(p); 1892 r = evergreen_cs_track_check(p);
1878 if (r) { 1893 if (r) {
1879 dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); 1894 dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1880 return r; 1895 return r;
1881 } 1896 }
1882 break; 1897 break;
1898 }
1883 case PACKET3_DRAW_INDEX: 1899 case PACKET3_DRAW_INDEX:
1900 {
1901 uint64_t offset;
1884 if (pkt->count != 3) { 1902 if (pkt->count != 3) {
1885 DRM_ERROR("bad DRAW_INDEX\n"); 1903 DRM_ERROR("bad DRAW_INDEX\n");
1886 return -EINVAL; 1904 return -EINVAL;
@@ -1890,15 +1908,25 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
1890 DRM_ERROR("bad DRAW_INDEX\n"); 1908 DRM_ERROR("bad DRAW_INDEX\n");
1891 return -EINVAL; 1909 return -EINVAL;
1892 } 1910 }
1893 ib[idx+0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff); 1911
1894 ib[idx+1] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; 1912 offset = reloc->lobj.gpu_offset +
1913 idx_value +
1914 ((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32);
1915
1916 ib[idx+0] = offset;
1917 ib[idx+1] = upper_32_bits(offset) & 0xff;
1918
1895 r = evergreen_cs_track_check(p); 1919 r = evergreen_cs_track_check(p);
1896 if (r) { 1920 if (r) {
1897 dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); 1921 dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1898 return r; 1922 return r;
1899 } 1923 }
1900 break; 1924 break;
1925 }
1901 case PACKET3_DRAW_INDEX_2: 1926 case PACKET3_DRAW_INDEX_2:
1927 {
1928 uint64_t offset;
1929
1902 if (pkt->count != 4) { 1930 if (pkt->count != 4) {
1903 DRM_ERROR("bad DRAW_INDEX_2\n"); 1931 DRM_ERROR("bad DRAW_INDEX_2\n");
1904 return -EINVAL; 1932 return -EINVAL;
@@ -1908,14 +1936,21 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
1908 DRM_ERROR("bad DRAW_INDEX_2\n"); 1936 DRM_ERROR("bad DRAW_INDEX_2\n");
1909 return -EINVAL; 1937 return -EINVAL;
1910 } 1938 }
1911 ib[idx+1] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff); 1939
1912 ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; 1940 offset = reloc->lobj.gpu_offset +
1941 radeon_get_ib_value(p, idx+1) +
1942 ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32);
1943
1944 ib[idx+1] = offset;
1945 ib[idx+2] = upper_32_bits(offset) & 0xff;
1946
1913 r = evergreen_cs_track_check(p); 1947 r = evergreen_cs_track_check(p);
1914 if (r) { 1948 if (r) {
1915 dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); 1949 dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1916 return r; 1950 return r;
1917 } 1951 }
1918 break; 1952 break;
1953 }
1919 case PACKET3_DRAW_INDEX_AUTO: 1954 case PACKET3_DRAW_INDEX_AUTO:
1920 if (pkt->count != 1) { 1955 if (pkt->count != 1) {
1921 DRM_ERROR("bad DRAW_INDEX_AUTO\n"); 1956 DRM_ERROR("bad DRAW_INDEX_AUTO\n");
@@ -2006,13 +2041,20 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
2006 } 2041 }
2007 /* bit 4 is reg (0) or mem (1) */ 2042 /* bit 4 is reg (0) or mem (1) */
2008 if (idx_value & 0x10) { 2043 if (idx_value & 0x10) {
2044 uint64_t offset;
2045
2009 r = evergreen_cs_packet_next_reloc(p, &reloc); 2046 r = evergreen_cs_packet_next_reloc(p, &reloc);
2010 if (r) { 2047 if (r) {
2011 DRM_ERROR("bad WAIT_REG_MEM\n"); 2048 DRM_ERROR("bad WAIT_REG_MEM\n");
2012 return -EINVAL; 2049 return -EINVAL;
2013 } 2050 }
2014 ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); 2051
2015 ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; 2052 offset = reloc->lobj.gpu_offset +
2053 (radeon_get_ib_value(p, idx+1) & 0xfffffffc) +
2054 ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32);
2055
2056 ib[idx+1] = (ib[idx+1] & 0x3) | (offset & 0xfffffffc);
2057 ib[idx+2] = upper_32_bits(offset) & 0xff;
2016 } 2058 }
2017 break; 2059 break;
2018 case PACKET3_SURFACE_SYNC: 2060 case PACKET3_SURFACE_SYNC:
@@ -2037,16 +2079,25 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
2037 return -EINVAL; 2079 return -EINVAL;
2038 } 2080 }
2039 if (pkt->count) { 2081 if (pkt->count) {
2082 uint64_t offset;
2083
2040 r = evergreen_cs_packet_next_reloc(p, &reloc); 2084 r = evergreen_cs_packet_next_reloc(p, &reloc);
2041 if (r) { 2085 if (r) {
2042 DRM_ERROR("bad EVENT_WRITE\n"); 2086 DRM_ERROR("bad EVENT_WRITE\n");
2043 return -EINVAL; 2087 return -EINVAL;
2044 } 2088 }
2045 ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); 2089 offset = reloc->lobj.gpu_offset +
2046 ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; 2090 (radeon_get_ib_value(p, idx+1) & 0xfffffff8) +
2091 ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32);
2092
2093 ib[idx+1] = offset & 0xfffffff8;
2094 ib[idx+2] = upper_32_bits(offset) & 0xff;
2047 } 2095 }
2048 break; 2096 break;
2049 case PACKET3_EVENT_WRITE_EOP: 2097 case PACKET3_EVENT_WRITE_EOP:
2098 {
2099 uint64_t offset;
2100
2050 if (pkt->count != 4) { 2101 if (pkt->count != 4) {
2051 DRM_ERROR("bad EVENT_WRITE_EOP\n"); 2102 DRM_ERROR("bad EVENT_WRITE_EOP\n");
2052 return -EINVAL; 2103 return -EINVAL;
@@ -2056,10 +2107,19 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
2056 DRM_ERROR("bad EVENT_WRITE_EOP\n"); 2107 DRM_ERROR("bad EVENT_WRITE_EOP\n");
2057 return -EINVAL; 2108 return -EINVAL;
2058 } 2109 }
2059 ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); 2110
2060 ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; 2111 offset = reloc->lobj.gpu_offset +
2112 (radeon_get_ib_value(p, idx+1) & 0xfffffffc) +
2113 ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32);
2114
2115 ib[idx+1] = offset & 0xfffffffc;
2116 ib[idx+2] = (ib[idx+2] & 0xffffff00) | (upper_32_bits(offset) & 0xff);
2061 break; 2117 break;
2118 }
2062 case PACKET3_EVENT_WRITE_EOS: 2119 case PACKET3_EVENT_WRITE_EOS:
2120 {
2121 uint64_t offset;
2122
2063 if (pkt->count != 3) { 2123 if (pkt->count != 3) {
2064 DRM_ERROR("bad EVENT_WRITE_EOS\n"); 2124 DRM_ERROR("bad EVENT_WRITE_EOS\n");
2065 return -EINVAL; 2125 return -EINVAL;
@@ -2069,9 +2129,15 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
2069 DRM_ERROR("bad EVENT_WRITE_EOS\n"); 2129 DRM_ERROR("bad EVENT_WRITE_EOS\n");
2070 return -EINVAL; 2130 return -EINVAL;
2071 } 2131 }
2072 ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); 2132
2073 ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; 2133 offset = reloc->lobj.gpu_offset +
2134 (radeon_get_ib_value(p, idx+1) & 0xfffffffc) +
2135 ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32);
2136
2137 ib[idx+1] = offset & 0xfffffffc;
2138 ib[idx+2] = (ib[idx+2] & 0xffffff00) | (upper_32_bits(offset) & 0xff);
2074 break; 2139 break;
2140 }
2075 case PACKET3_SET_CONFIG_REG: 2141 case PACKET3_SET_CONFIG_REG:
2076 start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START; 2142 start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START;
2077 end_reg = 4 * pkt->count + start_reg - 4; 2143 end_reg = 4 * pkt->count + start_reg - 4;
@@ -2164,6 +2230,8 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
2164 ib[idx+1+(i*8)+3] += moffset; 2230 ib[idx+1+(i*8)+3] += moffset;
2165 break; 2231 break;
2166 case SQ_TEX_VTX_VALID_BUFFER: 2232 case SQ_TEX_VTX_VALID_BUFFER:
2233 {
2234 uint64_t offset64;
2167 /* vtx base */ 2235 /* vtx base */
2168 r = evergreen_cs_packet_next_reloc(p, &reloc); 2236 r = evergreen_cs_packet_next_reloc(p, &reloc);
2169 if (r) { 2237 if (r) {
@@ -2175,11 +2243,15 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
2175 if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) { 2243 if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) {
2176 /* force size to size of the buffer */ 2244 /* force size to size of the buffer */
2177 dev_warn(p->dev, "vbo resource seems too big for the bo\n"); 2245 dev_warn(p->dev, "vbo resource seems too big for the bo\n");
2178 ib[idx+1+(i*8)+1] = radeon_bo_size(reloc->robj); 2246 ib[idx+1+(i*8)+1] = radeon_bo_size(reloc->robj) - offset;
2179 } 2247 }
2180 ib[idx+1+(i*8)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff); 2248
2181 ib[idx+1+(i*8)+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; 2249 offset64 = reloc->lobj.gpu_offset + offset;
2250 ib[idx+1+(i*8)+0] = offset64;
2251 ib[idx+1+(i*8)+2] = (ib[idx+1+(i*8)+2] & 0xffffff00) |
2252 (upper_32_bits(offset64) & 0xff);
2182 break; 2253 break;
2254 }
2183 case SQ_TEX_VTX_INVALID_TEXTURE: 2255 case SQ_TEX_VTX_INVALID_TEXTURE:
2184 case SQ_TEX_VTX_INVALID_BUFFER: 2256 case SQ_TEX_VTX_INVALID_BUFFER:
2185 default: 2257 default:
@@ -2255,8 +2327,9 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
2255 offset + 4, radeon_bo_size(reloc->robj)); 2327 offset + 4, radeon_bo_size(reloc->robj));
2256 return -EINVAL; 2328 return -EINVAL;
2257 } 2329 }
2258 ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); 2330 offset += reloc->lobj.gpu_offset;
2259 ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; 2331 ib[idx+1] = offset;
2332 ib[idx+2] = upper_32_bits(offset) & 0xff;
2260 } 2333 }
2261 /* Reading data from SRC_ADDRESS. */ 2334 /* Reading data from SRC_ADDRESS. */
2262 if (((idx_value >> 1) & 0x3) == 2) { 2335 if (((idx_value >> 1) & 0x3) == 2) {
@@ -2273,8 +2346,9 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
2273 offset + 4, radeon_bo_size(reloc->robj)); 2346 offset + 4, radeon_bo_size(reloc->robj));
2274 return -EINVAL; 2347 return -EINVAL;
2275 } 2348 }
2276 ib[idx+3] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); 2349 offset += reloc->lobj.gpu_offset;
2277 ib[idx+4] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; 2350 ib[idx+3] = offset;
2351 ib[idx+4] = upper_32_bits(offset) & 0xff;
2278 } 2352 }
2279 break; 2353 break;
2280 case PACKET3_COPY_DW: 2354 case PACKET3_COPY_DW:
@@ -2297,8 +2371,9 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
2297 offset + 4, radeon_bo_size(reloc->robj)); 2371 offset + 4, radeon_bo_size(reloc->robj));
2298 return -EINVAL; 2372 return -EINVAL;
2299 } 2373 }
2300 ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); 2374 offset += reloc->lobj.gpu_offset;
2301 ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; 2375 ib[idx+1] = offset;
2376 ib[idx+2] = upper_32_bits(offset) & 0xff;
2302 } else { 2377 } else {
2303 /* SRC is a reg. */ 2378 /* SRC is a reg. */
2304 reg = radeon_get_ib_value(p, idx+1) << 2; 2379 reg = radeon_get_ib_value(p, idx+1) << 2;
@@ -2320,8 +2395,9 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
2320 offset + 4, radeon_bo_size(reloc->robj)); 2395 offset + 4, radeon_bo_size(reloc->robj));
2321 return -EINVAL; 2396 return -EINVAL;
2322 } 2397 }
2323 ib[idx+3] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); 2398 offset += reloc->lobj.gpu_offset;
2324 ib[idx+4] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; 2399 ib[idx+3] = offset;
2400 ib[idx+4] = upper_32_bits(offset) & 0xff;
2325 } else { 2401 } else {
2326 /* DST is a reg. */ 2402 /* DST is a reg. */
2327 reg = radeon_get_ib_value(p, idx+3) << 2; 2403 reg = radeon_get_ib_value(p, idx+3) << 2;