aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2011-12-16 17:03:42 -0500
committerDave Airlie <airlied@redhat.com>2012-02-13 07:28:13 -0500
commit285484e2d55e76031b45926720c10b1aec8b782a (patch)
treeca2ddf80717feeafa5219485d3bfe32ab837666c /drivers/gpu/drm/radeon
parentdd220a00e8bd5ad7f98ecdc3eed699a7cfabdc27 (diff)
drm/radeon: add support for evergreen/ni tiling informations v11
evergreen and northern island gpu needs more informations for 2D tiling than previous r6xx/r7xx. Add field to tiling ioctl to allow userspace to provide those. The v8 cs checking change to track color view on r6xx/r7xx doesn't affect old userspace as old userspace always emited 0 for this register. v2 fix r6xx/r7xx 2D tiling computation v3 fix r6xx/r7xx height align for untiled surface & add support for tile split on evergreen and newer v4 improve tiling debugging output v5 fix tile split code for evergreen and newer v6 set proper tile split for crtc register v7 fix tile split limit value v8 add COLOR_VIEW checking to r6xx/r7xx checker, add evergreen cs checking, update safe reg for r600, evergreen and cayman. Evergreen checking need some work around for stencil alignment issues v9 fix tile split value range, fix compressed texture handling and mipmap calculation, allow evergreen check to be silencious in front of current broken userspace (depth/stencil alignment issue) v10 fix eg 3d texture and compressed texture, fix r600 depth array, fix r600 color view computation, add support for evergreen stencil split v11 more verbose debugging in some case Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c20
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c31
-rw-r--r--drivers/gpu/drm/radeon/evergreen_cs.c777
-rw-r--r--drivers/gpu/drm/radeon/evergreend.h368
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c103
-rw-r--r--drivers/gpu/drm/radeon/r600d.h14
-rw-r--r--drivers/gpu/drm/radeon/radeon.h13
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c46
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/cayman1
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/evergreen1
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/r6008
12 files changed, 1282 insertions, 103 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 742f17f009a9..72672ea3f6d3 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1031,6 +1031,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
1031 struct radeon_bo *rbo; 1031 struct radeon_bo *rbo;
1032 uint64_t fb_location; 1032 uint64_t fb_location;
1033 uint32_t fb_format, fb_pitch_pixels, tiling_flags; 1033 uint32_t fb_format, fb_pitch_pixels, tiling_flags;
1034 unsigned bankw, bankh, mtaspect, tile_split;
1034 u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE); 1035 u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE);
1035 u32 tmp, viewport_w, viewport_h; 1036 u32 tmp, viewport_w, viewport_h;
1036 int r; 1037 int r;
@@ -1121,20 +1122,13 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
1121 break; 1122 break;
1122 } 1123 }
1123 1124
1124 switch ((tmp & 0xf000) >> 12) {
1125 case 0: /* 1KB rows */
1126 default:
1127 fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_1KB);
1128 break;
1129 case 1: /* 2KB rows */
1130 fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_2KB);
1131 break;
1132 case 2: /* 4KB rows */
1133 fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_4KB);
1134 break;
1135 }
1136
1137 fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1); 1125 fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1);
1126
1127 evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split);
1128 fb_format |= EVERGREEN_GRPH_TILE_SPLIT(tile_split);
1129 fb_format |= EVERGREEN_GRPH_BANK_WIDTH(bankw);
1130 fb_format |= EVERGREEN_GRPH_BANK_HEIGHT(bankh);
1131 fb_format |= EVERGREEN_GRPH_MACRO_TILE_ASPECT(mtaspect);
1138 } else if (tiling_flags & RADEON_TILING_MICRO) 1132 } else if (tiling_flags & RADEON_TILING_MICRO)
1139 fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); 1133 fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1);
1140 1134
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index ae09fe82afbc..b7a7102e9653 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -43,6 +43,37 @@ void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
43extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev, 43extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
44 int ring, u32 cp_int_cntl); 44 int ring, u32 cp_int_cntl);
45 45
46void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw,
47 unsigned *bankh, unsigned *mtaspect,
48 unsigned *tile_split)
49{
50 *bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK;
51 *bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK;
52 *mtaspect = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK;
53 *tile_split = (tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK;
54 switch (*bankw) {
55 default:
56 case 1: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_1; break;
57 case 2: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_2; break;
58 case 4: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_4; break;
59 case 8: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_8; break;
60 }
61 switch (*bankh) {
62 default:
63 case 1: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_1; break;
64 case 2: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_2; break;
65 case 4: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_4; break;
66 case 8: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_8; break;
67 }
68 switch (*mtaspect) {
69 default:
70 case 1: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_1; break;
71 case 2: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_2; break;
72 case 4: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_4; break;
73 case 8: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_8; break;
74 }
75}
76
46void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) 77void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
47{ 78{
48 u16 ctl, v; 79 u16 ctl, v;
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
index 4e2cadcdf144..2ed17f761736 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -31,6 +31,9 @@
31#include "evergreen_reg_safe.h" 31#include "evergreen_reg_safe.h"
32#include "cayman_reg_safe.h" 32#include "cayman_reg_safe.h"
33 33
34#define MAX(a,b) (((a)>(b))?(a):(b))
35#define MIN(a,b) (((a)<(b))?(a):(b))
36
34static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, 37static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p,
35 struct radeon_cs_reloc **cs_reloc); 38 struct radeon_cs_reloc **cs_reloc);
36 39
@@ -54,6 +57,7 @@ struct evergreen_cs_track {
54 u32 cb_color_dim[12]; 57 u32 cb_color_dim[12];
55 u32 cb_color_pitch[12]; 58 u32 cb_color_pitch[12];
56 u32 cb_color_slice[12]; 59 u32 cb_color_slice[12];
60 u32 cb_color_attrib[12];
57 u32 cb_color_cmask_slice[8]; 61 u32 cb_color_cmask_slice[8];
58 u32 cb_color_fmask_slice[8]; 62 u32 cb_color_fmask_slice[8];
59 u32 cb_target_mask; 63 u32 cb_target_mask;
@@ -66,6 +70,7 @@ struct evergreen_cs_track {
66 u32 vgt_strmout_size[4]; 70 u32 vgt_strmout_size[4];
67 u32 db_depth_control; 71 u32 db_depth_control;
68 u32 db_depth_view; 72 u32 db_depth_view;
73 u32 db_depth_slice;
69 u32 db_depth_size; 74 u32 db_depth_size;
70 u32 db_depth_size_idx; 75 u32 db_depth_size_idx;
71 u32 db_z_info; 76 u32 db_z_info;
@@ -107,19 +112,6 @@ static u32 evergreen_cs_get_num_banks(u32 nbanks)
107 } 112 }
108} 113}
109 114
110static u32 evergreen_cs_get_tile_split(u32 row_size)
111{
112 switch (row_size) {
113 case 1:
114 default:
115 return ADDR_SURF_TILE_SPLIT_1KB;
116 case 2:
117 return ADDR_SURF_TILE_SPLIT_2KB;
118 case 4:
119 return ADDR_SURF_TILE_SPLIT_4KB;
120 }
121}
122
123static void evergreen_cs_track_init(struct evergreen_cs_track *track) 115static void evergreen_cs_track_init(struct evergreen_cs_track *track)
124{ 116{
125 int i; 117 int i;
@@ -136,7 +128,7 @@ static void evergreen_cs_track_init(struct evergreen_cs_track *track)
136 track->cb_color_bo[i] = NULL; 128 track->cb_color_bo[i] = NULL;
137 track->cb_color_bo_offset[i] = 0xFFFFFFFF; 129 track->cb_color_bo_offset[i] = 0xFFFFFFFF;
138 track->cb_color_info[i] = 0; 130 track->cb_color_info[i] = 0;
139 track->cb_color_view[i] = 0; 131 track->cb_color_view[i] = 0xFFFFFFFF;
140 track->cb_color_pitch_idx[i] = 0; 132 track->cb_color_pitch_idx[i] = 0;
141 track->cb_color_slice_idx[i] = 0; 133 track->cb_color_slice_idx[i] = 0;
142 track->cb_color_dim[i] = 0; 134 track->cb_color_dim[i] = 0;
@@ -172,10 +164,639 @@ static void evergreen_cs_track_init(struct evergreen_cs_track *track)
172 } 164 }
173} 165}
174 166
167struct eg_surface {
168 /* value gathered from cs */
169 unsigned nbx;
170 unsigned nby;
171 unsigned format;
172 unsigned mode;
173 unsigned nbanks;
174 unsigned bankw;
175 unsigned bankh;
176 unsigned tsplit;
177 unsigned mtilea;
178 unsigned nsamples;
179 /* output value */
180 unsigned bpe;
181 unsigned layer_size;
182 unsigned palign;
183 unsigned halign;
184 unsigned long base_align;
185};
186
187static int evergreen_surface_check_linear(struct radeon_cs_parser *p,
188 struct eg_surface *surf,
189 const char *prefix)
190{
191 surf->layer_size = surf->nbx * surf->nby * surf->bpe * surf->nsamples;
192 surf->base_align = surf->bpe;
193 surf->palign = 1;
194 surf->halign = 1;
195 return 0;
196}
197
198static int evergreen_surface_check_linear_aligned(struct radeon_cs_parser *p,
199 struct eg_surface *surf,
200 const char *prefix)
201{
202 struct evergreen_cs_track *track = p->track;
203 unsigned palign;
204
205 palign = MAX(64, track->group_size / surf->bpe);
206 surf->layer_size = surf->nbx * surf->nby * surf->bpe * surf->nsamples;
207 surf->base_align = track->group_size;
208 surf->palign = palign;
209 surf->halign = 1;
210 if (surf->nbx & (palign - 1)) {
211 if (prefix) {
212 dev_warn(p->dev, "%s:%d %s pitch %d invalid must be aligned with %d\n",
213 __func__, __LINE__, prefix, surf->nbx, palign);
214 }
215 return -EINVAL;
216 }
217 return 0;
218}
219
220static int evergreen_surface_check_1d(struct radeon_cs_parser *p,
221 struct eg_surface *surf,
222 const char *prefix)
223{
224 struct evergreen_cs_track *track = p->track;
225 unsigned palign;
226
227 palign = track->group_size / (8 * surf->bpe * surf->nsamples);
228 palign = MAX(8, palign);
229 surf->layer_size = surf->nbx * surf->nby * surf->bpe;
230 surf->base_align = track->group_size;
231 surf->palign = palign;
232 surf->halign = 8;
233 if ((surf->nbx & (palign - 1))) {
234 if (prefix) {
235 dev_warn(p->dev, "%s:%d %s pitch %d invalid must be aligned with %d (%d %d %d)\n",
236 __func__, __LINE__, prefix, surf->nbx, palign,
237 track->group_size, surf->bpe, surf->nsamples);
238 }
239 return -EINVAL;
240 }
241 if ((surf->nby & (8 - 1))) {
242 if (prefix) {
243 dev_warn(p->dev, "%s:%d %s height %d invalid must be aligned with 8\n",
244 __func__, __LINE__, prefix, surf->nby);
245 }
246 return -EINVAL;
247 }
248 return 0;
249}
250
251static int evergreen_surface_check_2d(struct radeon_cs_parser *p,
252 struct eg_surface *surf,
253 const char *prefix)
254{
255 struct evergreen_cs_track *track = p->track;
256 unsigned palign, halign, tileb, slice_pt;
257
258 tileb = 64 * surf->bpe * surf->nsamples;
259 palign = track->group_size / (8 * surf->bpe * surf->nsamples);
260 palign = MAX(8, palign);
261 slice_pt = 1;
262 if (tileb > surf->tsplit) {
263 slice_pt = tileb / surf->tsplit;
264 }
265 tileb = tileb / slice_pt;
266 /* macro tile width & height */
267 palign = (8 * surf->bankw * track->npipes) * surf->mtilea;
268 halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea;
269 surf->layer_size = surf->nbx * surf->nby * surf->bpe * slice_pt;
270 surf->base_align = (palign / 8) * (halign / 8) * tileb;
271 surf->palign = palign;
272 surf->halign = halign;
273
274 if ((surf->nbx & (palign - 1))) {
275 if (prefix) {
276 dev_warn(p->dev, "%s:%d %s pitch %d invalid must be aligned with %d\n",
277 __func__, __LINE__, prefix, surf->nbx, palign);
278 }
279 return -EINVAL;
280 }
281 if ((surf->nby & (halign - 1))) {
282 if (prefix) {
283 dev_warn(p->dev, "%s:%d %s height %d invalid must be aligned with %d\n",
284 __func__, __LINE__, prefix, surf->nby, halign);
285 }
286 return -EINVAL;
287 }
288
289 return 0;
290}
291
292static int evergreen_surface_check(struct radeon_cs_parser *p,
293 struct eg_surface *surf,
294 const char *prefix)
295{
296 /* some common value computed here */
297 surf->bpe = r600_fmt_get_blocksize(surf->format);
298
299 switch (surf->mode) {
300 case ARRAY_LINEAR_GENERAL:
301 return evergreen_surface_check_linear(p, surf, prefix);
302 case ARRAY_LINEAR_ALIGNED:
303 return evergreen_surface_check_linear_aligned(p, surf, prefix);
304 case ARRAY_1D_TILED_THIN1:
305 return evergreen_surface_check_1d(p, surf, prefix);
306 case ARRAY_2D_TILED_THIN1:
307 return evergreen_surface_check_2d(p, surf, prefix);
308 default:
309 dev_warn(p->dev, "%s:%d invalid array mode %d\n",
310 __func__, __LINE__, surf->mode);
311 return -EINVAL;
312 }
313 return -EINVAL;
314}
315
316static int evergreen_surface_value_conv_check(struct radeon_cs_parser *p,
317 struct eg_surface *surf,
318 const char *prefix)
319{
320 switch (surf->mode) {
321 case ARRAY_2D_TILED_THIN1:
322 break;
323 case ARRAY_LINEAR_GENERAL:
324 case ARRAY_LINEAR_ALIGNED:
325 case ARRAY_1D_TILED_THIN1:
326 return 0;
327 default:
328 dev_warn(p->dev, "%s:%d invalid array mode %d\n",
329 __func__, __LINE__, surf->mode);
330 return -EINVAL;
331 }
332
333 switch (surf->nbanks) {
334 case 0: surf->nbanks = 2; break;
335 case 1: surf->nbanks = 4; break;
336 case 2: surf->nbanks = 8; break;
337 case 3: surf->nbanks = 16; break;
338 default:
339 dev_warn(p->dev, "%s:%d %s invalid number of banks %d\n",
340 __func__, __LINE__, prefix, surf->nbanks);
341 return -EINVAL;
342 }
343 switch (surf->bankw) {
344 case 0: surf->bankw = 1; break;
345 case 1: surf->bankw = 2; break;
346 case 2: surf->bankw = 4; break;
347 case 3: surf->bankw = 8; break;
348 default:
349 dev_warn(p->dev, "%s:%d %s invalid bankw %d\n",
350 __func__, __LINE__, prefix, surf->bankw);
351 return -EINVAL;
352 }
353 switch (surf->bankh) {
354 case 0: surf->bankh = 1; break;
355 case 1: surf->bankh = 2; break;
356 case 2: surf->bankh = 4; break;
357 case 3: surf->bankh = 8; break;
358 default:
359 dev_warn(p->dev, "%s:%d %s invalid bankh %d\n",
360 __func__, __LINE__, prefix, surf->bankh);
361 return -EINVAL;
362 }
363 switch (surf->mtilea) {
364 case 0: surf->mtilea = 1; break;
365 case 1: surf->mtilea = 2; break;
366 case 2: surf->mtilea = 4; break;
367 case 3: surf->mtilea = 8; break;
368 default:
369 dev_warn(p->dev, "%s:%d %s invalid macro tile aspect %d\n",
370 __func__, __LINE__, prefix, surf->mtilea);
371 return -EINVAL;
372 }
373 switch (surf->tsplit) {
374 case 0: surf->tsplit = 64; break;
375 case 1: surf->tsplit = 128; break;
376 case 2: surf->tsplit = 256; break;
377 case 3: surf->tsplit = 512; break;
378 case 4: surf->tsplit = 1024; break;
379 case 5: surf->tsplit = 2048; break;
380 case 6: surf->tsplit = 4096; break;
381 default:
382 dev_warn(p->dev, "%s:%d %s invalid tile split %d\n",
383 __func__, __LINE__, prefix, surf->tsplit);
384 return -EINVAL;
385 }
386 return 0;
387}
388
389static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned id)
390{
391 struct evergreen_cs_track *track = p->track;
392 struct eg_surface surf;
393 unsigned pitch, slice, mslice;
394 unsigned long offset;
395 int r;
396
397 mslice = G_028C6C_SLICE_MAX(track->cb_color_view[id]) + 1;
398 pitch = track->cb_color_pitch[id];
399 slice = track->cb_color_slice[id];
400 surf.nbx = (pitch + 1) * 8;
401 surf.nby = ((slice + 1) * 64) / surf.nbx;
402 surf.mode = G_028C70_ARRAY_MODE(track->cb_color_info[id]);
403 surf.format = G_028C70_FORMAT(track->cb_color_info[id]);
404 surf.tsplit = G_028C74_TILE_SPLIT(track->cb_color_attrib[id]);
405 surf.nbanks = G_028C74_NUM_BANKS(track->cb_color_attrib[id]);
406 surf.bankw = G_028C74_BANK_WIDTH(track->cb_color_attrib[id]);
407 surf.bankh = G_028C74_BANK_HEIGHT(track->cb_color_attrib[id]);
408 surf.mtilea = G_028C74_MACRO_TILE_ASPECT(track->cb_color_attrib[id]);
409 surf.nsamples = 1;
410
411 if (!r600_fmt_is_valid_color(surf.format)) {
412 dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08x)\n",
413 __func__, __LINE__, surf.format,
414 id, track->cb_color_info[id]);
415 return -EINVAL;
416 }
417
418 r = evergreen_surface_value_conv_check(p, &surf, "cb");
419 if (r) {
420 return r;
421 }
422
423 r = evergreen_surface_check(p, &surf, "cb");
424 if (r) {
425 dev_warn(p->dev, "%s:%d cb[%d] invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
426 __func__, __LINE__, id, track->cb_color_pitch[id],
427 track->cb_color_slice[id], track->cb_color_attrib[id],
428 track->cb_color_info[id]);
429 return r;
430 }
431
432 offset = track->cb_color_bo_offset[id] << 8;
433 if (offset & (surf.base_align - 1)) {
434 dev_warn(p->dev, "%s:%d cb[%d] bo base %ld not aligned with %ld\n",
435 __func__, __LINE__, id, offset, surf.base_align);
436 return -EINVAL;
437 }
438
439 offset += surf.layer_size * mslice;
440 if (offset > radeon_bo_size(track->cb_color_bo[id])) {
441 dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, "
442 "offset %d, max layer %d, bo size %ld, slice %d)\n",
443 __func__, __LINE__, id, surf.layer_size,
444 track->cb_color_bo_offset[id] << 8, mslice,
445 radeon_bo_size(track->cb_color_bo[id]), slice);
446 dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n",
447 __func__, __LINE__, surf.nbx, surf.nby,
448 surf.mode, surf.bpe, surf.nsamples,
449 surf.bankw, surf.bankh,
450 surf.tsplit, surf.mtilea);
451 return -EINVAL;
452 }
453
454 return 0;
455}
456
457static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
458{
459 struct evergreen_cs_track *track = p->track;
460 struct eg_surface surf;
461 unsigned pitch, slice, mslice;
462 unsigned long offset;
463 int r;
464
465 mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
466 pitch = G_028058_PITCH_TILE_MAX(track->db_depth_size);
467 slice = track->db_depth_slice;
468 surf.nbx = (pitch + 1) * 8;
469 surf.nby = ((slice + 1) * 64) / surf.nbx;
470 surf.mode = G_028040_ARRAY_MODE(track->db_z_info);
471 surf.format = G_028044_FORMAT(track->db_s_info);
472 surf.tsplit = G_028044_TILE_SPLIT(track->db_s_info);
473 surf.nbanks = G_028040_NUM_BANKS(track->db_z_info);
474 surf.bankw = G_028040_BANK_WIDTH(track->db_z_info);
475 surf.bankh = G_028040_BANK_HEIGHT(track->db_z_info);
476 surf.mtilea = G_028040_MACRO_TILE_ASPECT(track->db_z_info);
477 surf.nsamples = 1;
478
479 if (surf.format != 1) {
480 dev_warn(p->dev, "%s:%d stencil invalid format %d\n",
481 __func__, __LINE__, surf.format);
482 return -EINVAL;
483 }
484 /* replace by color format so we can use same code */
485 surf.format = V_028C70_COLOR_8;
486
487 r = evergreen_surface_value_conv_check(p, &surf, "stencil");
488 if (r) {
489 return r;
490 }
491
492 r = evergreen_surface_check(p, &surf, NULL);
493 if (r) {
494 /* old userspace doesn't compute proper depth/stencil alignment
495 * check that alignment against a bigger byte per elements and
496 * only report if that alignment is wrong too.
497 */
498 surf.format = V_028C70_COLOR_8_8_8_8;
499 r = evergreen_surface_check(p, &surf, "stencil");
500 if (r) {
501 dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
502 __func__, __LINE__, track->db_depth_size,
503 track->db_depth_slice, track->db_s_info, track->db_z_info);
504 }
505 return r;
506 }
507
508 offset = track->db_s_read_offset << 8;
509 if (offset & (surf.base_align - 1)) {
510 dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n",
511 __func__, __LINE__, offset, surf.base_align);
512 return -EINVAL;
513 }
514 offset += surf.layer_size * mslice;
515 if (offset > radeon_bo_size(track->db_s_read_bo)) {
516 dev_warn(p->dev, "%s:%d stencil read bo too small (layer size %d, "
517 "offset %ld, max layer %d, bo size %ld)\n",
518 __func__, __LINE__, surf.layer_size,
519 (unsigned long)track->db_s_read_offset << 8, mslice,
520 radeon_bo_size(track->db_s_read_bo));
521 dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
522 __func__, __LINE__, track->db_depth_size,
523 track->db_depth_slice, track->db_s_info, track->db_z_info);
524 return -EINVAL;
525 }
526
527 offset = track->db_s_write_offset << 8;
528 if (offset & (surf.base_align - 1)) {
529 dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n",
530 __func__, __LINE__, offset, surf.base_align);
531 return -EINVAL;
532 }
533 offset += surf.layer_size * mslice;
534 if (offset > radeon_bo_size(track->db_s_write_bo)) {
535 dev_warn(p->dev, "%s:%d stencil write bo too small (layer size %d, "
536 "offset %ld, max layer %d, bo size %ld)\n",
537 __func__, __LINE__, surf.layer_size,
538 (unsigned long)track->db_s_write_offset << 8, mslice,
539 radeon_bo_size(track->db_s_write_bo));
540 return -EINVAL;
541 }
542
543 return 0;
544}
545
546static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p)
547{
548 struct evergreen_cs_track *track = p->track;
549 struct eg_surface surf;
550 unsigned pitch, slice, mslice;
551 unsigned long offset;
552 int r;
553
554 mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
555 pitch = G_028058_PITCH_TILE_MAX(track->db_depth_size);
556 slice = track->db_depth_slice;
557 surf.nbx = (pitch + 1) * 8;
558 surf.nby = ((slice + 1) * 64) / surf.nbx;
559 surf.mode = G_028040_ARRAY_MODE(track->db_z_info);
560 surf.format = G_028040_FORMAT(track->db_z_info);
561 surf.tsplit = G_028040_TILE_SPLIT(track->db_z_info);
562 surf.nbanks = G_028040_NUM_BANKS(track->db_z_info);
563 surf.bankw = G_028040_BANK_WIDTH(track->db_z_info);
564 surf.bankh = G_028040_BANK_HEIGHT(track->db_z_info);
565 surf.mtilea = G_028040_MACRO_TILE_ASPECT(track->db_z_info);
566 surf.nsamples = 1;
567
568 switch (surf.format) {
569 case V_028040_Z_16:
570 surf.format = V_028C70_COLOR_16;
571 break;
572 case V_028040_Z_24:
573 case V_028040_Z_32_FLOAT:
574 surf.format = V_028C70_COLOR_8_8_8_8;
575 break;
576 default:
577 dev_warn(p->dev, "%s:%d depth invalid format %d\n",
578 __func__, __LINE__, surf.format);
579 return -EINVAL;
580 }
581
582 r = evergreen_surface_value_conv_check(p, &surf, "depth");
583 if (r) {
584 dev_warn(p->dev, "%s:%d depth invalid (0x%08x 0x%08x 0x%08x)\n",
585 __func__, __LINE__, track->db_depth_size,
586 track->db_depth_slice, track->db_z_info);
587 return r;
588 }
589
590 r = evergreen_surface_check(p, &surf, "depth");
591 if (r) {
592 dev_warn(p->dev, "%s:%d depth invalid (0x%08x 0x%08x 0x%08x)\n",
593 __func__, __LINE__, track->db_depth_size,
594 track->db_depth_slice, track->db_z_info);
595 return r;
596 }
597
598 offset = track->db_z_read_offset << 8;
599 if (offset & (surf.base_align - 1)) {
600 dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n",
601 __func__, __LINE__, offset, surf.base_align);
602 return -EINVAL;
603 }
604 offset += surf.layer_size * mslice;
605 if (offset > radeon_bo_size(track->db_z_read_bo)) {
606 dev_warn(p->dev, "%s:%d depth read bo too small (layer size %d, "
607 "offset %ld, max layer %d, bo size %ld)\n",
608 __func__, __LINE__, surf.layer_size,
609 (unsigned long)track->db_z_read_offset << 8, mslice,
610 radeon_bo_size(track->db_z_read_bo));
611 return -EINVAL;
612 }
613
614 offset = track->db_z_write_offset << 8;
615 if (offset & (surf.base_align - 1)) {
616 dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n",
617 __func__, __LINE__, offset, surf.base_align);
618 return -EINVAL;
619 }
620 offset += surf.layer_size * mslice;
621 if (offset > radeon_bo_size(track->db_z_write_bo)) {
622 dev_warn(p->dev, "%s:%d depth write bo too small (layer size %d, "
623 "offset %ld, max layer %d, bo size %ld)\n",
624 __func__, __LINE__, surf.layer_size,
625 (unsigned long)track->db_z_write_offset << 8, mslice,
626 radeon_bo_size(track->db_z_write_bo));
627 return -EINVAL;
628 }
629
630 return 0;
631}
632
633static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p,
634 struct radeon_bo *texture,
635 struct radeon_bo *mipmap,
636 unsigned idx)
637{
638 struct eg_surface surf;
639 unsigned long toffset, moffset;
640 unsigned dim, llevel, mslice, width, height, depth, i;
641 u32 texdw[7];
642 int r;
643
644 texdw[0] = radeon_get_ib_value(p, idx + 0);
645 texdw[1] = radeon_get_ib_value(p, idx + 1);
646 texdw[2] = radeon_get_ib_value(p, idx + 2);
647 texdw[3] = radeon_get_ib_value(p, idx + 3);
648 texdw[4] = radeon_get_ib_value(p, idx + 4);
649 texdw[5] = radeon_get_ib_value(p, idx + 5);
650 texdw[6] = radeon_get_ib_value(p, idx + 6);
651 texdw[7] = radeon_get_ib_value(p, idx + 7);
652 dim = G_030000_DIM(texdw[0]);
653 llevel = G_030014_LAST_LEVEL(texdw[5]);
654 mslice = G_030014_LAST_ARRAY(texdw[5]) + 1;
655 width = G_030000_TEX_WIDTH(texdw[0]) + 1;
656 height = G_030004_TEX_HEIGHT(texdw[1]) + 1;
657 depth = G_030004_TEX_DEPTH(texdw[1]) + 1;
658 surf.format = G_03001C_DATA_FORMAT(texdw[7]);
659 surf.nbx = (G_030000_PITCH(texdw[0]) + 1) * 8;
660 surf.nbx = r600_fmt_get_nblocksx(surf.format, surf.nbx);
661 surf.nby = r600_fmt_get_nblocksy(surf.format, height);
662 surf.mode = G_030004_ARRAY_MODE(texdw[1]);
663 surf.tsplit = G_030018_TILE_SPLIT(texdw[6]);
664 surf.nbanks = G_03001C_NUM_BANKS(texdw[7]);
665 surf.bankw = G_03001C_BANK_WIDTH(texdw[7]);
666 surf.bankh = G_03001C_BANK_HEIGHT(texdw[7]);
667 surf.mtilea = G_03001C_MACRO_TILE_ASPECT(texdw[7]);
668 surf.nsamples = 1;
669 toffset = texdw[2] << 8;
670 moffset = texdw[3] << 8;
671
672 if (!r600_fmt_is_valid_texture(surf.format, p->family)) {
673 dev_warn(p->dev, "%s:%d texture invalid format %d\n",
674 __func__, __LINE__, surf.format);
675 return -EINVAL;
676 }
677 switch (dim) {
678 case V_030000_SQ_TEX_DIM_1D:
679 case V_030000_SQ_TEX_DIM_2D:
680 case V_030000_SQ_TEX_DIM_CUBEMAP:
681 case V_030000_SQ_TEX_DIM_1D_ARRAY:
682 case V_030000_SQ_TEX_DIM_2D_ARRAY:
683 depth = 1;
684 case V_030000_SQ_TEX_DIM_3D:
685 break;
686 default:
687 dev_warn(p->dev, "%s:%d texture invalid dimension %d\n",
688 __func__, __LINE__, dim);
689 return -EINVAL;
690 }
691
692 r = evergreen_surface_value_conv_check(p, &surf, "texture");
693 if (r) {
694 return r;
695 }
696
697 /* align height */
698 evergreen_surface_check(p, &surf, NULL);
699 surf.nby = ALIGN(surf.nby, surf.halign);
700
701 r = evergreen_surface_check(p, &surf, "texture");
702 if (r) {
703 dev_warn(p->dev, "%s:%d texture invalid 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
704 __func__, __LINE__, texdw[0], texdw[1], texdw[4],
705 texdw[5], texdw[6], texdw[7]);
706 return r;
707 }
708
709 /* check texture size */
710 if (toffset & (surf.base_align - 1)) {
711 dev_warn(p->dev, "%s:%d texture bo base %ld not aligned with %ld\n",
712 __func__, __LINE__, toffset, surf.base_align);
713 return -EINVAL;
714 }
715 if (moffset & (surf.base_align - 1)) {
716 dev_warn(p->dev, "%s:%d mipmap bo base %ld not aligned with %ld\n",
717 __func__, __LINE__, moffset, surf.base_align);
718 return -EINVAL;
719 }
720 if (dim == SQ_TEX_DIM_3D) {
721 toffset += surf.layer_size * depth;
722 } else {
723 toffset += surf.layer_size * mslice;
724 }
725 if (toffset > radeon_bo_size(texture)) {
726 dev_warn(p->dev, "%s:%d texture bo too small (layer size %d, "
727 "offset %ld, max layer %d, depth %d, bo size %ld) (%d %d)\n",
728 __func__, __LINE__, surf.layer_size,
729 (unsigned long)texdw[2] << 8, mslice,
730 depth, radeon_bo_size(texture),
731 surf.nbx, surf.nby);
732 return -EINVAL;
733 }
734
735 /* check mipmap size */
736 for (i = 1; i <= llevel; i++) {
737 unsigned w, h, d;
738
739 w = r600_mip_minify(width, i);
740 h = r600_mip_minify(height, i);
741 d = r600_mip_minify(depth, i);
742 surf.nbx = r600_fmt_get_nblocksx(surf.format, w);
743 surf.nby = r600_fmt_get_nblocksy(surf.format, h);
744
745 switch (surf.mode) {
746 case ARRAY_2D_TILED_THIN1:
747 if (surf.nbx < surf.palign || surf.nby < surf.halign) {
748 surf.mode = ARRAY_1D_TILED_THIN1;
749 }
750 /* recompute alignment */
751 evergreen_surface_check(p, &surf, NULL);
752 break;
753 case ARRAY_LINEAR_GENERAL:
754 case ARRAY_LINEAR_ALIGNED:
755 case ARRAY_1D_TILED_THIN1:
756 break;
757 default:
758 dev_warn(p->dev, "%s:%d invalid array mode %d\n",
759 __func__, __LINE__, surf.mode);
760 return -EINVAL;
761 }
762 surf.nbx = ALIGN(surf.nbx, surf.palign);
763 surf.nby = ALIGN(surf.nby, surf.halign);
764
765 r = evergreen_surface_check(p, &surf, "mipmap");
766 if (r) {
767 return r;
768 }
769
770 if (dim == SQ_TEX_DIM_3D) {
771 moffset += surf.layer_size * d;
772 } else {
773 moffset += surf.layer_size * mslice;
774 }
775 if (moffset > radeon_bo_size(mipmap)) {
776 dev_warn(p->dev, "%s:%d mipmap [%d] bo too small (layer size %d, "
777 "offset %ld, coffset %ld, max layer %d, depth %d, "
778 "bo size %ld) level0 (%d %d %d)\n",
779 __func__, __LINE__, i, surf.layer_size,
780 (unsigned long)texdw[3] << 8, moffset, mslice,
781 d, radeon_bo_size(mipmap),
782 width, height, depth);
783 dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n",
784 __func__, __LINE__, surf.nbx, surf.nby,
785 surf.mode, surf.bpe, surf.nsamples,
786 surf.bankw, surf.bankh,
787 surf.tsplit, surf.mtilea);
788 return -EINVAL;
789 }
790 }
791
792 return 0;
793}
794
175static int evergreen_cs_track_check(struct radeon_cs_parser *p) 795static int evergreen_cs_track_check(struct radeon_cs_parser *p)
176{ 796{
177 struct evergreen_cs_track *track = p->track; 797 struct evergreen_cs_track *track = p->track;
178 int i, j; 798 unsigned tmp, i, j;
799 int r;
179 800
180 /* check streamout */ 801 /* check streamout */
181 for (i = 0; i < 4; i++) { 802 for (i = 0; i < 4; i++) {
@@ -200,7 +821,38 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p)
200 } 821 }
201 } 822 }
202 823
203 /* XXX fill in */ 824 /* check that we have a cb for each enabled target
825 */
826 tmp = track->cb_target_mask;
827 for (i = 0; i < 8; i++) {
828 if ((tmp >> (i * 4)) & 0xF) {
829 /* at least one component is enabled */
830 if (track->cb_color_bo[i] == NULL) {
831 dev_warn(p->dev, "%s:%d mask 0x%08X | 0x%08X no cb for %d\n",
832 __func__, __LINE__, track->cb_target_mask, track->cb_shader_mask, i);
833 return -EINVAL;
834 }
835 /* check cb */
836 r = evergreen_cs_track_validate_cb(p, i);
837 if (r) {
838 return r;
839 }
840 }
841 }
842
843 /* Check stencil buffer */
844 if (G_028800_STENCIL_ENABLE(track->db_depth_control)) {
845 r = evergreen_cs_track_validate_stencil(p);
846 if (r)
847 return r;
848 }
849 /* Check depth buffer */
850 if (G_028800_Z_WRITE_ENABLE(track->db_depth_control)) {
851 r = evergreen_cs_track_validate_depth(p);
852 if (r)
853 return r;
854 }
855
204 return 0; 856 return 0;
205} 857}
206 858
@@ -561,8 +1213,16 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
561 ib[idx] |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); 1213 ib[idx] |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
562 track->db_z_info |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); 1214 track->db_z_info |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
563 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { 1215 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
1216 unsigned bankw, bankh, mtaspect, tile_split;
1217
1218 evergreen_tiling_fields(reloc->lobj.tiling_flags,
1219 &bankw, &bankh, &mtaspect,
1220 &tile_split);
564 ib[idx] |= DB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); 1221 ib[idx] |= DB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
565 ib[idx] |= DB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size)); 1222 ib[idx] |= DB_TILE_SPLIT(tile_split) |
1223 DB_BANK_WIDTH(bankw) |
1224 DB_BANK_HEIGHT(bankh) |
1225 DB_MACRO_TILE_ASPECT(mtaspect);
566 } 1226 }
567 } 1227 }
568 break; 1228 break;
@@ -576,6 +1236,9 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
576 track->db_depth_size = radeon_get_ib_value(p, idx); 1236 track->db_depth_size = radeon_get_ib_value(p, idx);
577 track->db_depth_size_idx = idx; 1237 track->db_depth_size_idx = idx;
578 break; 1238 break;
1239 case R_02805C_DB_DEPTH_SLICE:
1240 track->db_depth_slice = radeon_get_ib_value(p, idx);
1241 break;
579 case DB_Z_READ_BASE: 1242 case DB_Z_READ_BASE:
580 r = evergreen_cs_packet_next_reloc(p, &reloc); 1243 r = evergreen_cs_packet_next_reloc(p, &reloc);
581 if (r) { 1244 if (r) {
@@ -786,6 +1449,29 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
786 case CB_COLOR5_ATTRIB: 1449 case CB_COLOR5_ATTRIB:
787 case CB_COLOR6_ATTRIB: 1450 case CB_COLOR6_ATTRIB:
788 case CB_COLOR7_ATTRIB: 1451 case CB_COLOR7_ATTRIB:
1452 r = evergreen_cs_packet_next_reloc(p, &reloc);
1453 if (r) {
1454 dev_warn(p->dev, "bad SET_CONTEXT_REG "
1455 "0x%04X\n", reg);
1456 return -EINVAL;
1457 }
1458 if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
1459 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
1460 unsigned bankw, bankh, mtaspect, tile_split;
1461
1462 evergreen_tiling_fields(reloc->lobj.tiling_flags,
1463 &bankw, &bankh, &mtaspect,
1464 &tile_split);
1465 ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
1466 ib[idx] |= CB_TILE_SPLIT(tile_split) |
1467 CB_BANK_WIDTH(bankw) |
1468 CB_BANK_HEIGHT(bankh) |
1469 CB_MACRO_TILE_ASPECT(mtaspect);
1470 }
1471 }
1472 tmp = ((reg - CB_COLOR0_ATTRIB) / 0x3c);
1473 track->cb_color_attrib[tmp] = ib[idx];
1474 break;
789 case CB_COLOR8_ATTRIB: 1475 case CB_COLOR8_ATTRIB:
790 case CB_COLOR9_ATTRIB: 1476 case CB_COLOR9_ATTRIB:
791 case CB_COLOR10_ATTRIB: 1477 case CB_COLOR10_ATTRIB:
@@ -796,10 +1482,22 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
796 "0x%04X\n", reg); 1482 "0x%04X\n", reg);
797 return -EINVAL; 1483 return -EINVAL;
798 } 1484 }
799 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { 1485 if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
800 ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); 1486 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
801 ib[idx] |= CB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size)); 1487 unsigned bankw, bankh, mtaspect, tile_split;
1488
1489 evergreen_tiling_fields(reloc->lobj.tiling_flags,
1490 &bankw, &bankh, &mtaspect,
1491 &tile_split);
1492 ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
1493 ib[idx] |= CB_TILE_SPLIT(tile_split) |
1494 CB_BANK_WIDTH(bankw) |
1495 CB_BANK_HEIGHT(bankh) |
1496 CB_MACRO_TILE_ASPECT(mtaspect);
1497 }
802 } 1498 }
1499 tmp = ((reg - CB_COLOR8_ATTRIB) / 0x1c) + 8;
1500 track->cb_color_attrib[tmp] = ib[idx];
803 break; 1501 break;
804 case CB_COLOR0_DIM: 1502 case CB_COLOR0_DIM:
805 case CB_COLOR1_DIM: 1503 case CB_COLOR1_DIM:
@@ -1057,24 +1755,6 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
1057 return 0; 1755 return 0;
1058} 1756}
1059 1757
1060/**
1061 * evergreen_check_texture_resource() - check if register is authorized or not
1062 * @p: parser structure holding parsing context
1063 * @idx: index into the cs buffer
1064 * @texture: texture's bo structure
1065 * @mipmap: mipmap's bo structure
1066 *
1067 * This function will check that the resource has valid field and that
1068 * the texture and mipmap bo object are big enough to cover this resource.
1069 */
1070static int evergreen_check_texture_resource(struct radeon_cs_parser *p, u32 idx,
1071 struct radeon_bo *texture,
1072 struct radeon_bo *mipmap)
1073{
1074 /* XXX fill in */
1075 return 0;
1076}
1077
1078static bool evergreen_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) 1758static bool evergreen_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
1079{ 1759{
1080 u32 last_reg, m, i; 1760 u32 last_reg, m, i;
@@ -1431,6 +2111,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
1431 } 2111 }
1432 for (i = 0; i < (pkt->count / 8); i++) { 2112 for (i = 0; i < (pkt->count / 8); i++) {
1433 struct radeon_bo *texture, *mipmap; 2113 struct radeon_bo *texture, *mipmap;
2114 u32 toffset, moffset;
1434 u32 size, offset; 2115 u32 size, offset;
1435 2116
1436 switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) { 2117 switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) {
@@ -1441,30 +2122,38 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
1441 DRM_ERROR("bad SET_RESOURCE (tex)\n"); 2122 DRM_ERROR("bad SET_RESOURCE (tex)\n");
1442 return -EINVAL; 2123 return -EINVAL;
1443 } 2124 }
1444 ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1445 if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { 2125 if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
1446 ib[idx+1+(i*8)+1] |= 2126 ib[idx+1+(i*8)+1] |=
1447 TEX_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); 2127 TEX_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
1448 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { 2128 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
1449 ib[idx+1+(i*8)+6] |= 2129 unsigned bankw, bankh, mtaspect, tile_split;
1450 TEX_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size)); 2130
2131 evergreen_tiling_fields(reloc->lobj.tiling_flags,
2132 &bankw, &bankh, &mtaspect,
2133 &tile_split);
2134 ib[idx+1+(i*8)+6] |= TEX_TILE_SPLIT(tile_split);
1451 ib[idx+1+(i*8)+7] |= 2135 ib[idx+1+(i*8)+7] |=
2136 TEX_BANK_WIDTH(bankw) |
2137 TEX_BANK_HEIGHT(bankh) |
2138 MACRO_TILE_ASPECT(mtaspect) |
1452 TEX_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); 2139 TEX_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
1453 } 2140 }
1454 } 2141 }
1455 texture = reloc->robj; 2142 texture = reloc->robj;
2143 toffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1456 /* tex mip base */ 2144 /* tex mip base */
1457 r = evergreen_cs_packet_next_reloc(p, &reloc); 2145 r = evergreen_cs_packet_next_reloc(p, &reloc);
1458 if (r) { 2146 if (r) {
1459 DRM_ERROR("bad SET_RESOURCE (tex)\n"); 2147 DRM_ERROR("bad SET_RESOURCE (tex)\n");
1460 return -EINVAL; 2148 return -EINVAL;
1461 } 2149 }
1462 ib[idx+1+(i*8)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); 2150 moffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1463 mipmap = reloc->robj; 2151 mipmap = reloc->robj;
1464 r = evergreen_check_texture_resource(p, idx+1+(i*8), 2152 r = evergreen_cs_track_validate_texture(p, texture, mipmap, idx+1+(i*8));
1465 texture, mipmap);
1466 if (r) 2153 if (r)
1467 return r; 2154 return r;
2155 ib[idx+1+(i*8)+2] += toffset;
2156 ib[idx+1+(i*8)+3] += moffset;
1468 break; 2157 break;
1469 case SQ_TEX_VTX_VALID_BUFFER: 2158 case SQ_TEX_VTX_VALID_BUFFER:
1470 /* vtx base */ 2159 /* vtx base */
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
index 50d20da5b5f0..eb5708c7159d 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -926,7 +926,70 @@
926#define DB_DEBUG4 0x983C 926#define DB_DEBUG4 0x983C
927#define DB_WATERMARKS 0x9854 927#define DB_WATERMARKS 0x9854
928#define DB_DEPTH_CONTROL 0x28800 928#define DB_DEPTH_CONTROL 0x28800
929#define R_028800_DB_DEPTH_CONTROL 0x028800
930#define S_028800_STENCIL_ENABLE(x) (((x) & 0x1) << 0)
931#define G_028800_STENCIL_ENABLE(x) (((x) >> 0) & 0x1)
932#define C_028800_STENCIL_ENABLE 0xFFFFFFFE
933#define S_028800_Z_ENABLE(x) (((x) & 0x1) << 1)
934#define G_028800_Z_ENABLE(x) (((x) >> 1) & 0x1)
935#define C_028800_Z_ENABLE 0xFFFFFFFD
936#define S_028800_Z_WRITE_ENABLE(x) (((x) & 0x1) << 2)
937#define G_028800_Z_WRITE_ENABLE(x) (((x) >> 2) & 0x1)
938#define C_028800_Z_WRITE_ENABLE 0xFFFFFFFB
939#define S_028800_ZFUNC(x) (((x) & 0x7) << 4)
940#define G_028800_ZFUNC(x) (((x) >> 4) & 0x7)
941#define C_028800_ZFUNC 0xFFFFFF8F
942#define S_028800_BACKFACE_ENABLE(x) (((x) & 0x1) << 7)
943#define G_028800_BACKFACE_ENABLE(x) (((x) >> 7) & 0x1)
944#define C_028800_BACKFACE_ENABLE 0xFFFFFF7F
945#define S_028800_STENCILFUNC(x) (((x) & 0x7) << 8)
946#define G_028800_STENCILFUNC(x) (((x) >> 8) & 0x7)
947#define C_028800_STENCILFUNC 0xFFFFF8FF
948#define V_028800_STENCILFUNC_NEVER 0x00000000
949#define V_028800_STENCILFUNC_LESS 0x00000001
950#define V_028800_STENCILFUNC_EQUAL 0x00000002
951#define V_028800_STENCILFUNC_LEQUAL 0x00000003
952#define V_028800_STENCILFUNC_GREATER 0x00000004
953#define V_028800_STENCILFUNC_NOTEQUAL 0x00000005
954#define V_028800_STENCILFUNC_GEQUAL 0x00000006
955#define V_028800_STENCILFUNC_ALWAYS 0x00000007
956#define S_028800_STENCILFAIL(x) (((x) & 0x7) << 11)
957#define G_028800_STENCILFAIL(x) (((x) >> 11) & 0x7)
958#define C_028800_STENCILFAIL 0xFFFFC7FF
959#define V_028800_STENCIL_KEEP 0x00000000
960#define V_028800_STENCIL_ZERO 0x00000001
961#define V_028800_STENCIL_REPLACE 0x00000002
962#define V_028800_STENCIL_INCR 0x00000003
963#define V_028800_STENCIL_DECR 0x00000004
964#define V_028800_STENCIL_INVERT 0x00000005
965#define V_028800_STENCIL_INCR_WRAP 0x00000006
966#define V_028800_STENCIL_DECR_WRAP 0x00000007
967#define S_028800_STENCILZPASS(x) (((x) & 0x7) << 14)
968#define G_028800_STENCILZPASS(x) (((x) >> 14) & 0x7)
969#define C_028800_STENCILZPASS 0xFFFE3FFF
970#define S_028800_STENCILZFAIL(x) (((x) & 0x7) << 17)
971#define G_028800_STENCILZFAIL(x) (((x) >> 17) & 0x7)
972#define C_028800_STENCILZFAIL 0xFFF1FFFF
973#define S_028800_STENCILFUNC_BF(x) (((x) & 0x7) << 20)
974#define G_028800_STENCILFUNC_BF(x) (((x) >> 20) & 0x7)
975#define C_028800_STENCILFUNC_BF 0xFF8FFFFF
976#define S_028800_STENCILFAIL_BF(x) (((x) & 0x7) << 23)
977#define G_028800_STENCILFAIL_BF(x) (((x) >> 23) & 0x7)
978#define C_028800_STENCILFAIL_BF 0xFC7FFFFF
979#define S_028800_STENCILZPASS_BF(x) (((x) & 0x7) << 26)
980#define G_028800_STENCILZPASS_BF(x) (((x) >> 26) & 0x7)
981#define C_028800_STENCILZPASS_BF 0xE3FFFFFF
982#define S_028800_STENCILZFAIL_BF(x) (((x) & 0x7) << 29)
983#define G_028800_STENCILZFAIL_BF(x) (((x) >> 29) & 0x7)
984#define C_028800_STENCILZFAIL_BF 0x1FFFFFFF
929#define DB_DEPTH_VIEW 0x28008 985#define DB_DEPTH_VIEW 0x28008
986#define R_028008_DB_DEPTH_VIEW 0x00028008
987#define S_028008_SLICE_START(x) (((x) & 0x7FF) << 0)
988#define G_028008_SLICE_START(x) (((x) >> 0) & 0x7FF)
989#define C_028008_SLICE_START 0xFFFFF800
990#define S_028008_SLICE_MAX(x) (((x) & 0x7FF) << 13)
991#define G_028008_SLICE_MAX(x) (((x) >> 13) & 0x7FF)
992#define C_028008_SLICE_MAX 0xFF001FFF
930#define DB_HTILE_DATA_BASE 0x28014 993#define DB_HTILE_DATA_BASE 0x28014
931#define DB_Z_INFO 0x28040 994#define DB_Z_INFO 0x28040
932# define Z_ARRAY_MODE(x) ((x) << 4) 995# define Z_ARRAY_MODE(x) ((x) << 4)
@@ -934,12 +997,59 @@
934# define DB_NUM_BANKS(x) (((x) & 0x3) << 12) 997# define DB_NUM_BANKS(x) (((x) & 0x3) << 12)
935# define DB_BANK_WIDTH(x) (((x) & 0x3) << 16) 998# define DB_BANK_WIDTH(x) (((x) & 0x3) << 16)
936# define DB_BANK_HEIGHT(x) (((x) & 0x3) << 20) 999# define DB_BANK_HEIGHT(x) (((x) & 0x3) << 20)
1000# define DB_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 24)
1001#define R_028040_DB_Z_INFO 0x028040
1002#define S_028040_FORMAT(x) (((x) & 0x3) << 0)
1003#define G_028040_FORMAT(x) (((x) >> 0) & 0x3)
1004#define C_028040_FORMAT 0xFFFFFFFC
1005#define V_028040_Z_INVALID 0x00000000
1006#define V_028040_Z_16 0x00000001
1007#define V_028040_Z_24 0x00000002
1008#define V_028040_Z_32_FLOAT 0x00000003
1009#define S_028040_ARRAY_MODE(x) (((x) & 0xF) << 4)
1010#define G_028040_ARRAY_MODE(x) (((x) >> 4) & 0xF)
1011#define C_028040_ARRAY_MODE 0xFFFFFF0F
1012#define S_028040_READ_SIZE(x) (((x) & 0x1) << 28)
1013#define G_028040_READ_SIZE(x) (((x) >> 28) & 0x1)
1014#define C_028040_READ_SIZE 0xEFFFFFFF
1015#define S_028040_TILE_SURFACE_ENABLE(x) (((x) & 0x1) << 29)
1016#define G_028040_TILE_SURFACE_ENABLE(x) (((x) >> 29) & 0x1)
1017#define C_028040_TILE_SURFACE_ENABLE 0xDFFFFFFF
1018#define S_028040_ZRANGE_PRECISION(x) (((x) & 0x1) << 31)
1019#define G_028040_ZRANGE_PRECISION(x) (((x) >> 31) & 0x1)
1020#define C_028040_ZRANGE_PRECISION 0x7FFFFFFF
1021#define S_028040_TILE_SPLIT(x) (((x) & 0x7) << 8)
1022#define G_028040_TILE_SPLIT(x) (((x) >> 8) & 0x7)
1023#define S_028040_NUM_BANKS(x) (((x) & 0x3) << 12)
1024#define G_028040_NUM_BANKS(x) (((x) >> 12) & 0x3)
1025#define S_028040_BANK_WIDTH(x) (((x) & 0x3) << 16)
1026#define G_028040_BANK_WIDTH(x) (((x) >> 16) & 0x3)
1027#define S_028040_BANK_HEIGHT(x) (((x) & 0x3) << 20)
1028#define G_028040_BANK_HEIGHT(x) (((x) >> 20) & 0x3)
1029#define S_028040_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 24)
1030#define G_028040_MACRO_TILE_ASPECT(x) (((x) >> 24) & 0x3)
937#define DB_STENCIL_INFO 0x28044 1031#define DB_STENCIL_INFO 0x28044
1032#define R_028044_DB_STENCIL_INFO 0x028044
1033#define S_028044_FORMAT(x) (((x) & 0x1) << 0)
1034#define G_028044_FORMAT(x) (((x) >> 0) & 0x1)
1035#define C_028044_FORMAT 0xFFFFFFFE
1036#define G_028044_TILE_SPLIT(x) (((x) >> 8) & 0x7)
938#define DB_Z_READ_BASE 0x28048 1037#define DB_Z_READ_BASE 0x28048
939#define DB_STENCIL_READ_BASE 0x2804c 1038#define DB_STENCIL_READ_BASE 0x2804c
940#define DB_Z_WRITE_BASE 0x28050 1039#define DB_Z_WRITE_BASE 0x28050
941#define DB_STENCIL_WRITE_BASE 0x28054 1040#define DB_STENCIL_WRITE_BASE 0x28054
942#define DB_DEPTH_SIZE 0x28058 1041#define DB_DEPTH_SIZE 0x28058
1042#define R_028058_DB_DEPTH_SIZE 0x028058
1043#define S_028058_PITCH_TILE_MAX(x) (((x) & 0x7FF) << 0)
1044#define G_028058_PITCH_TILE_MAX(x) (((x) >> 0) & 0x7FF)
1045#define C_028058_PITCH_TILE_MAX 0xFFFFF800
1046#define S_028058_HEIGHT_TILE_MAX(x) (((x) & 0x7FF) << 11)
1047#define G_028058_HEIGHT_TILE_MAX(x) (((x) >> 11) & 0x7FF)
1048#define C_028058_HEIGHT_TILE_MAX 0xFFC007FF
1049#define R_02805C_DB_DEPTH_SLICE 0x02805C
1050#define S_02805C_SLICE_TILE_MAX(x) (((x) & 0x3FFFFF) << 0)
1051#define G_02805C_SLICE_TILE_MAX(x) (((x) >> 0) & 0x3FFFFF)
1052#define C_02805C_SLICE_TILE_MAX 0xFFC00000
943 1053
944#define SQ_PGM_START_PS 0x28840 1054#define SQ_PGM_START_PS 0x28840
945#define SQ_PGM_START_VS 0x2885c 1055#define SQ_PGM_START_VS 0x2885c
@@ -983,6 +1093,114 @@
983#define CB_COLOR0_PITCH 0x28c64 1093#define CB_COLOR0_PITCH 0x28c64
984#define CB_COLOR0_SLICE 0x28c68 1094#define CB_COLOR0_SLICE 0x28c68
985#define CB_COLOR0_VIEW 0x28c6c 1095#define CB_COLOR0_VIEW 0x28c6c
1096#define R_028C6C_CB_COLOR0_VIEW 0x00028C6C
1097#define S_028C6C_SLICE_START(x) (((x) & 0x7FF) << 0)
1098#define G_028C6C_SLICE_START(x) (((x) >> 0) & 0x7FF)
1099#define C_028C6C_SLICE_START 0xFFFFF800
1100#define S_028C6C_SLICE_MAX(x) (((x) & 0x7FF) << 13)
1101#define G_028C6C_SLICE_MAX(x) (((x) >> 13) & 0x7FF)
1102#define C_028C6C_SLICE_MAX 0xFF001FFF
1103#define R_028C70_CB_COLOR0_INFO 0x028C70
1104#define S_028C70_ENDIAN(x) (((x) & 0x3) << 0)
1105#define G_028C70_ENDIAN(x) (((x) >> 0) & 0x3)
1106#define C_028C70_ENDIAN 0xFFFFFFFC
1107#define S_028C70_FORMAT(x) (((x) & 0x3F) << 2)
1108#define G_028C70_FORMAT(x) (((x) >> 2) & 0x3F)
1109#define C_028C70_FORMAT 0xFFFFFF03
1110#define V_028C70_COLOR_INVALID 0x00000000
1111#define V_028C70_COLOR_8 0x00000001
1112#define V_028C70_COLOR_4_4 0x00000002
1113#define V_028C70_COLOR_3_3_2 0x00000003
1114#define V_028C70_COLOR_16 0x00000005
1115#define V_028C70_COLOR_16_FLOAT 0x00000006
1116#define V_028C70_COLOR_8_8 0x00000007
1117#define V_028C70_COLOR_5_6_5 0x00000008
1118#define V_028C70_COLOR_6_5_5 0x00000009
1119#define V_028C70_COLOR_1_5_5_5 0x0000000A
1120#define V_028C70_COLOR_4_4_4_4 0x0000000B
1121#define V_028C70_COLOR_5_5_5_1 0x0000000C
1122#define V_028C70_COLOR_32 0x0000000D
1123#define V_028C70_COLOR_32_FLOAT 0x0000000E
1124#define V_028C70_COLOR_16_16 0x0000000F
1125#define V_028C70_COLOR_16_16_FLOAT 0x00000010
1126#define V_028C70_COLOR_8_24 0x00000011
1127#define V_028C70_COLOR_8_24_FLOAT 0x00000012
1128#define V_028C70_COLOR_24_8 0x00000013
1129#define V_028C70_COLOR_24_8_FLOAT 0x00000014
1130#define V_028C70_COLOR_10_11_11 0x00000015
1131#define V_028C70_COLOR_10_11_11_FLOAT 0x00000016
1132#define V_028C70_COLOR_11_11_10 0x00000017
1133#define V_028C70_COLOR_11_11_10_FLOAT 0x00000018
1134#define V_028C70_COLOR_2_10_10_10 0x00000019
1135#define V_028C70_COLOR_8_8_8_8 0x0000001A
1136#define V_028C70_COLOR_10_10_10_2 0x0000001B
1137#define V_028C70_COLOR_X24_8_32_FLOAT 0x0000001C
1138#define V_028C70_COLOR_32_32 0x0000001D
1139#define V_028C70_COLOR_32_32_FLOAT 0x0000001E
1140#define V_028C70_COLOR_16_16_16_16 0x0000001F
1141#define V_028C70_COLOR_16_16_16_16_FLOAT 0x00000020
1142#define V_028C70_COLOR_32_32_32_32 0x00000022
1143#define V_028C70_COLOR_32_32_32_32_FLOAT 0x00000023
1144#define V_028C70_COLOR_32_32_32_FLOAT 0x00000030
1145#define S_028C70_ARRAY_MODE(x) (((x) & 0xF) << 8)
1146#define G_028C70_ARRAY_MODE(x) (((x) >> 8) & 0xF)
1147#define C_028C70_ARRAY_MODE 0xFFFFF0FF
1148#define V_028C70_ARRAY_LINEAR_GENERAL 0x00000000
1149#define V_028C70_ARRAY_LINEAR_ALIGNED 0x00000001
1150#define V_028C70_ARRAY_1D_TILED_THIN1 0x00000002
1151#define V_028C70_ARRAY_2D_TILED_THIN1 0x00000004
1152#define S_028C70_NUMBER_TYPE(x) (((x) & 0x7) << 12)
1153#define G_028C70_NUMBER_TYPE(x) (((x) >> 12) & 0x7)
1154#define C_028C70_NUMBER_TYPE 0xFFFF8FFF
1155#define V_028C70_NUMBER_UNORM 0x00000000
1156#define V_028C70_NUMBER_SNORM 0x00000001
1157#define V_028C70_NUMBER_USCALED 0x00000002
1158#define V_028C70_NUMBER_SSCALED 0x00000003
1159#define V_028C70_NUMBER_UINT 0x00000004
1160#define V_028C70_NUMBER_SINT 0x00000005
1161#define V_028C70_NUMBER_SRGB 0x00000006
1162#define V_028C70_NUMBER_FLOAT 0x00000007
1163#define S_028C70_COMP_SWAP(x) (((x) & 0x3) << 15)
1164#define G_028C70_COMP_SWAP(x) (((x) >> 15) & 0x3)
1165#define C_028C70_COMP_SWAP 0xFFFE7FFF
1166#define V_028C70_SWAP_STD 0x00000000
1167#define V_028C70_SWAP_ALT 0x00000001
1168#define V_028C70_SWAP_STD_REV 0x00000002
1169#define V_028C70_SWAP_ALT_REV 0x00000003
1170#define S_028C70_FAST_CLEAR(x) (((x) & 0x1) << 17)
1171#define G_028C70_FAST_CLEAR(x) (((x) >> 17) & 0x1)
1172#define C_028C70_FAST_CLEAR 0xFFFDFFFF
1173#define S_028C70_COMPRESSION(x) (((x) & 0x3) << 18)
1174#define G_028C70_COMPRESSION(x) (((x) >> 18) & 0x3)
1175#define C_028C70_COMPRESSION 0xFFF3FFFF
1176#define S_028C70_BLEND_CLAMP(x) (((x) & 0x1) << 19)
1177#define G_028C70_BLEND_CLAMP(x) (((x) >> 19) & 0x1)
1178#define C_028C70_BLEND_CLAMP 0xFFF7FFFF
1179#define S_028C70_BLEND_BYPASS(x) (((x) & 0x1) << 20)
1180#define G_028C70_BLEND_BYPASS(x) (((x) >> 20) & 0x1)
1181#define C_028C70_BLEND_BYPASS 0xFFEFFFFF
1182#define S_028C70_SIMPLE_FLOAT(x) (((x) & 0x1) << 21)
1183#define G_028C70_SIMPLE_FLOAT(x) (((x) >> 21) & 0x1)
1184#define C_028C70_SIMPLE_FLOAT 0xFFDFFFFF
1185#define S_028C70_ROUND_MODE(x) (((x) & 0x1) << 22)
1186#define G_028C70_ROUND_MODE(x) (((x) >> 22) & 0x1)
1187#define C_028C70_ROUND_MODE 0xFFBFFFFF
1188#define S_028C70_TILE_COMPACT(x) (((x) & 0x1) << 23)
1189#define G_028C70_TILE_COMPACT(x) (((x) >> 23) & 0x1)
1190#define C_028C70_TILE_COMPACT 0xFF7FFFFF
1191#define S_028C70_SOURCE_FORMAT(x) (((x) & 0x3) << 24)
1192#define G_028C70_SOURCE_FORMAT(x) (((x) >> 24) & 0x3)
1193#define C_028C70_SOURCE_FORMAT 0xFCFFFFFF
1194#define V_028C70_EXPORT_4C_32BPC 0x0
1195#define V_028C70_EXPORT_4C_16BPC 0x1
1196#define V_028C70_EXPORT_2C_32BPC 0x2 /* Do not use */
1197#define S_028C70_RAT(x) (((x) & 0x1) << 26)
1198#define G_028C70_RAT(x) (((x) >> 26) & 0x1)
1199#define C_028C70_RAT 0xFBFFFFFF
1200#define S_028C70_RESOURCE_TYPE(x) (((x) & 0x7) << 27)
1201#define G_028C70_RESOURCE_TYPE(x) (((x) >> 27) & 0x7)
1202#define C_028C70_RESOURCE_TYPE 0xC7FFFFFF
1203
986#define CB_COLOR0_INFO 0x28c70 1204#define CB_COLOR0_INFO 0x28c70
987# define CB_FORMAT(x) ((x) << 2) 1205# define CB_FORMAT(x) ((x) << 2)
988# define CB_ARRAY_MODE(x) ((x) << 8) 1206# define CB_ARRAY_MODE(x) ((x) << 8)
@@ -993,6 +1211,20 @@
993# define CB_SOURCE_FORMAT(x) ((x) << 24) 1211# define CB_SOURCE_FORMAT(x) ((x) << 24)
994# define CB_SF_EXPORT_FULL 0 1212# define CB_SF_EXPORT_FULL 0
995# define CB_SF_EXPORT_NORM 1 1213# define CB_SF_EXPORT_NORM 1
1214#define R_028C74_CB_COLOR0_ATTRIB 0x028C74
1215#define S_028C74_NON_DISP_TILING_ORDER(x) (((x) & 0x1) << 4)
1216#define G_028C74_NON_DISP_TILING_ORDER(x) (((x) >> 4) & 0x1)
1217#define C_028C74_NON_DISP_TILING_ORDER 0xFFFFFFEF
1218#define S_028C74_TILE_SPLIT(x) (((x) & 0xf) << 5)
1219#define G_028C74_TILE_SPLIT(x) (((x) >> 5) & 0xf)
1220#define S_028C74_NUM_BANKS(x) (((x) & 0x3) << 10)
1221#define G_028C74_NUM_BANKS(x) (((x) >> 10) & 0x3)
1222#define S_028C74_BANK_WIDTH(x) (((x) & 0x3) << 13)
1223#define G_028C74_BANK_WIDTH(x) (((x) >> 13) & 0x3)
1224#define S_028C74_BANK_HEIGHT(x) (((x) & 0x3) << 16)
1225#define G_028C74_BANK_HEIGHT(x) (((x) >> 16) & 0x3)
1226#define S_028C74_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 19)
1227#define G_028C74_MACRO_TILE_ASPECT(x) (((x) >> 19) & 0x3)
996#define CB_COLOR0_ATTRIB 0x28c74 1228#define CB_COLOR0_ATTRIB 0x28c74
997# define CB_TILE_SPLIT(x) (((x) & 0x7) << 5) 1229# define CB_TILE_SPLIT(x) (((x) & 0x7) << 5)
998# define ADDR_SURF_TILE_SPLIT_64B 0 1230# define ADDR_SURF_TILE_SPLIT_64B 0
@@ -1017,6 +1249,7 @@
1017# define ADDR_SURF_BANK_HEIGHT_2 1 1249# define ADDR_SURF_BANK_HEIGHT_2 1
1018# define ADDR_SURF_BANK_HEIGHT_4 2 1250# define ADDR_SURF_BANK_HEIGHT_4 2
1019# define ADDR_SURF_BANK_HEIGHT_8 3 1251# define ADDR_SURF_BANK_HEIGHT_8 3
1252# define CB_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 19)
1020#define CB_COLOR0_DIM 0x28c78 1253#define CB_COLOR0_DIM 0x28c78
1021/* only CB0-7 blocks have these regs */ 1254/* only CB0-7 blocks have these regs */
1022#define CB_COLOR0_CMASK 0x28c7c 1255#define CB_COLOR0_CMASK 0x28c7c
@@ -1205,9 +1438,144 @@
1205#define SQ_TEX_RESOURCE_WORD6_0 0x30018 1438#define SQ_TEX_RESOURCE_WORD6_0 0x30018
1206# define TEX_TILE_SPLIT(x) (((x) & 0x7) << 29) 1439# define TEX_TILE_SPLIT(x) (((x) & 0x7) << 29)
1207#define SQ_TEX_RESOURCE_WORD7_0 0x3001c 1440#define SQ_TEX_RESOURCE_WORD7_0 0x3001c
1441# define MACRO_TILE_ASPECT(x) (((x) & 0x3) << 6)
1208# define TEX_BANK_WIDTH(x) (((x) & 0x3) << 8) 1442# define TEX_BANK_WIDTH(x) (((x) & 0x3) << 8)
1209# define TEX_BANK_HEIGHT(x) (((x) & 0x3) << 10) 1443# define TEX_BANK_HEIGHT(x) (((x) & 0x3) << 10)
1210# define TEX_NUM_BANKS(x) (((x) & 0x3) << 16) 1444# define TEX_NUM_BANKS(x) (((x) & 0x3) << 16)
1445#define R_030000_SQ_TEX_RESOURCE_WORD0_0 0x030000
1446#define S_030000_DIM(x) (((x) & 0x7) << 0)
1447#define G_030000_DIM(x) (((x) >> 0) & 0x7)
1448#define C_030000_DIM 0xFFFFFFF8
1449#define V_030000_SQ_TEX_DIM_1D 0x00000000
1450#define V_030000_SQ_TEX_DIM_2D 0x00000001
1451#define V_030000_SQ_TEX_DIM_3D 0x00000002
1452#define V_030000_SQ_TEX_DIM_CUBEMAP 0x00000003
1453#define V_030000_SQ_TEX_DIM_1D_ARRAY 0x00000004
1454#define V_030000_SQ_TEX_DIM_2D_ARRAY 0x00000005
1455#define V_030000_SQ_TEX_DIM_2D_MSAA 0x00000006
1456#define V_030000_SQ_TEX_DIM_2D_ARRAY_MSAA 0x00000007
1457#define S_030000_NON_DISP_TILING_ORDER(x) (((x) & 0x1) << 5)
1458#define G_030000_NON_DISP_TILING_ORDER(x) (((x) >> 5) & 0x1)
1459#define C_030000_NON_DISP_TILING_ORDER 0xFFFFFFDF
1460#define S_030000_PITCH(x) (((x) & 0xFFF) << 6)
1461#define G_030000_PITCH(x) (((x) >> 6) & 0xFFF)
1462#define C_030000_PITCH 0xFFFC003F
1463#define S_030000_TEX_WIDTH(x) (((x) & 0x3FFF) << 18)
1464#define G_030000_TEX_WIDTH(x) (((x) >> 18) & 0x3FFF)
1465#define C_030000_TEX_WIDTH 0x0003FFFF
1466#define R_030004_SQ_TEX_RESOURCE_WORD1_0 0x030004
1467#define S_030004_TEX_HEIGHT(x) (((x) & 0x3FFF) << 0)
1468#define G_030004_TEX_HEIGHT(x) (((x) >> 0) & 0x3FFF)
1469#define C_030004_TEX_HEIGHT 0xFFFFC000
1470#define S_030004_TEX_DEPTH(x) (((x) & 0x1FFF) << 14)
1471#define G_030004_TEX_DEPTH(x) (((x) >> 14) & 0x1FFF)
1472#define C_030004_TEX_DEPTH 0xF8003FFF
1473#define S_030004_ARRAY_MODE(x) (((x) & 0xF) << 28)
1474#define G_030004_ARRAY_MODE(x) (((x) >> 28) & 0xF)
1475#define C_030004_ARRAY_MODE 0x0FFFFFFF
1476#define R_030008_SQ_TEX_RESOURCE_WORD2_0 0x030008
1477#define S_030008_BASE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0)
1478#define G_030008_BASE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF)
1479#define C_030008_BASE_ADDRESS 0x00000000
1480#define R_03000C_SQ_TEX_RESOURCE_WORD3_0 0x03000C
1481#define S_03000C_MIP_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0)
1482#define G_03000C_MIP_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF)
1483#define C_03000C_MIP_ADDRESS 0x00000000
1484#define R_030010_SQ_TEX_RESOURCE_WORD4_0 0x030010
1485#define S_030010_FORMAT_COMP_X(x) (((x) & 0x3) << 0)
1486#define G_030010_FORMAT_COMP_X(x) (((x) >> 0) & 0x3)
1487#define C_030010_FORMAT_COMP_X 0xFFFFFFFC
1488#define V_030010_SQ_FORMAT_COMP_UNSIGNED 0x00000000
1489#define V_030010_SQ_FORMAT_COMP_SIGNED 0x00000001
1490#define V_030010_SQ_FORMAT_COMP_UNSIGNED_BIASED 0x00000002
1491#define S_030010_FORMAT_COMP_Y(x) (((x) & 0x3) << 2)
1492#define G_030010_FORMAT_COMP_Y(x) (((x) >> 2) & 0x3)
1493#define C_030010_FORMAT_COMP_Y 0xFFFFFFF3
1494#define S_030010_FORMAT_COMP_Z(x) (((x) & 0x3) << 4)
1495#define G_030010_FORMAT_COMP_Z(x) (((x) >> 4) & 0x3)
1496#define C_030010_FORMAT_COMP_Z 0xFFFFFFCF
1497#define S_030010_FORMAT_COMP_W(x) (((x) & 0x3) << 6)
1498#define G_030010_FORMAT_COMP_W(x) (((x) >> 6) & 0x3)
1499#define C_030010_FORMAT_COMP_W 0xFFFFFF3F
1500#define S_030010_NUM_FORMAT_ALL(x) (((x) & 0x3) << 8)
1501#define G_030010_NUM_FORMAT_ALL(x) (((x) >> 8) & 0x3)
1502#define C_030010_NUM_FORMAT_ALL 0xFFFFFCFF
1503#define V_030010_SQ_NUM_FORMAT_NORM 0x00000000
1504#define V_030010_SQ_NUM_FORMAT_INT 0x00000001
1505#define V_030010_SQ_NUM_FORMAT_SCALED 0x00000002
1506#define S_030010_SRF_MODE_ALL(x) (((x) & 0x1) << 10)
1507#define G_030010_SRF_MODE_ALL(x) (((x) >> 10) & 0x1)
1508#define C_030010_SRF_MODE_ALL 0xFFFFFBFF
1509#define V_030010_SRF_MODE_ZERO_CLAMP_MINUS_ONE 0x00000000
1510#define V_030010_SRF_MODE_NO_ZERO 0x00000001
1511#define S_030010_FORCE_DEGAMMA(x) (((x) & 0x1) << 11)
1512#define G_030010_FORCE_DEGAMMA(x) (((x) >> 11) & 0x1)
1513#define C_030010_FORCE_DEGAMMA 0xFFFFF7FF
1514#define S_030010_ENDIAN_SWAP(x) (((x) & 0x3) << 12)
1515#define G_030010_ENDIAN_SWAP(x) (((x) >> 12) & 0x3)
1516#define C_030010_ENDIAN_SWAP 0xFFFFCFFF
1517#define S_030010_DST_SEL_X(x) (((x) & 0x7) << 16)
1518#define G_030010_DST_SEL_X(x) (((x) >> 16) & 0x7)
1519#define C_030010_DST_SEL_X 0xFFF8FFFF
1520#define V_030010_SQ_SEL_X 0x00000000
1521#define V_030010_SQ_SEL_Y 0x00000001
1522#define V_030010_SQ_SEL_Z 0x00000002
1523#define V_030010_SQ_SEL_W 0x00000003
1524#define V_030010_SQ_SEL_0 0x00000004
1525#define V_030010_SQ_SEL_1 0x00000005
1526#define S_030010_DST_SEL_Y(x) (((x) & 0x7) << 19)
1527#define G_030010_DST_SEL_Y(x) (((x) >> 19) & 0x7)
1528#define C_030010_DST_SEL_Y 0xFFC7FFFF
1529#define S_030010_DST_SEL_Z(x) (((x) & 0x7) << 22)
1530#define G_030010_DST_SEL_Z(x) (((x) >> 22) & 0x7)
1531#define C_030010_DST_SEL_Z 0xFE3FFFFF
1532#define S_030010_DST_SEL_W(x) (((x) & 0x7) << 25)
1533#define G_030010_DST_SEL_W(x) (((x) >> 25) & 0x7)
1534#define C_030010_DST_SEL_W 0xF1FFFFFF
1535#define S_030010_BASE_LEVEL(x) (((x) & 0xF) << 28)
1536#define G_030010_BASE_LEVEL(x) (((x) >> 28) & 0xF)
1537#define C_030010_BASE_LEVEL 0x0FFFFFFF
1538#define R_030014_SQ_TEX_RESOURCE_WORD5_0 0x030014
1539#define S_030014_LAST_LEVEL(x) (((x) & 0xF) << 0)
1540#define G_030014_LAST_LEVEL(x) (((x) >> 0) & 0xF)
1541#define C_030014_LAST_LEVEL 0xFFFFFFF0
1542#define S_030014_BASE_ARRAY(x) (((x) & 0x1FFF) << 4)
1543#define G_030014_BASE_ARRAY(x) (((x) >> 4) & 0x1FFF)
1544#define C_030014_BASE_ARRAY 0xFFFE000F
1545#define S_030014_LAST_ARRAY(x) (((x) & 0x1FFF) << 17)
1546#define G_030014_LAST_ARRAY(x) (((x) >> 17) & 0x1FFF)
1547#define C_030014_LAST_ARRAY 0xC001FFFF
1548#define R_030018_SQ_TEX_RESOURCE_WORD6_0 0x030018
1549#define S_030018_MAX_ANISO(x) (((x) & 0x7) << 0)
1550#define G_030018_MAX_ANISO(x) (((x) >> 0) & 0x7)
1551#define C_030018_MAX_ANISO 0xFFFFFFF8
1552#define S_030018_PERF_MODULATION(x) (((x) & 0x7) << 3)
1553#define G_030018_PERF_MODULATION(x) (((x) >> 3) & 0x7)
1554#define C_030018_PERF_MODULATION 0xFFFFFFC7
1555#define S_030018_INTERLACED(x) (((x) & 0x1) << 6)
1556#define G_030018_INTERLACED(x) (((x) >> 6) & 0x1)
1557#define C_030018_INTERLACED 0xFFFFFFBF
1558#define S_030018_TILE_SPLIT(x) (((x) & 0x7) << 29)
1559#define G_030018_TILE_SPLIT(x) (((x) >> 29) & 0x7)
1560#define R_03001C_SQ_TEX_RESOURCE_WORD7_0 0x03001C
1561#define S_03001C_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 6)
1562#define G_03001C_MACRO_TILE_ASPECT(x) (((x) >> 6) & 0x3)
1563#define S_03001C_BANK_WIDTH(x) (((x) & 0x3) << 8)
1564#define G_03001C_BANK_WIDTH(x) (((x) >> 8) & 0x3)
1565#define S_03001C_BANK_HEIGHT(x) (((x) & 0x3) << 10)
1566#define G_03001C_BANK_HEIGHT(x) (((x) >> 10) & 0x3)
1567#define S_03001C_NUM_BANKS(x) (((x) & 0x3) << 16)
1568#define G_03001C_NUM_BANKS(x) (((x) >> 16) & 0x3)
1569#define S_03001C_TYPE(x) (((x) & 0x3) << 30)
1570#define G_03001C_TYPE(x) (((x) >> 30) & 0x3)
1571#define C_03001C_TYPE 0x3FFFFFFF
1572#define V_03001C_SQ_TEX_VTX_INVALID_TEXTURE 0x00000000
1573#define V_03001C_SQ_TEX_VTX_INVALID_BUFFER 0x00000001
1574#define V_03001C_SQ_TEX_VTX_VALID_TEXTURE 0x00000002
1575#define V_03001C_SQ_TEX_VTX_VALID_BUFFER 0x00000003
1576#define S_03001C_DATA_FORMAT(x) (((x) & 0x3F) << 0)
1577#define G_03001C_DATA_FORMAT(x) (((x) >> 0) & 0x3F)
1578#define C_03001C_DATA_FORMAT 0xFFFFFFC0
1211 1579
1212#define SQ_VTX_CONSTANT_WORD0_0 0x30000 1580#define SQ_VTX_CONSTANT_WORD0_0 0x30000
1213#define SQ_VTX_CONSTANT_WORD1_0 0x30004 1581#define SQ_VTX_CONSTANT_WORD1_0 0x30004
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 9f17571eea62..5cbe948ef16e 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -55,6 +55,7 @@ struct r600_cs_track {
55 struct radeon_bo *cb_color_frag_bo[8]; 55 struct radeon_bo *cb_color_frag_bo[8];
56 struct radeon_bo *cb_color_tile_bo[8]; 56 struct radeon_bo *cb_color_tile_bo[8];
57 u32 cb_color_info[8]; 57 u32 cb_color_info[8];
58 u32 cb_color_view[8];
58 u32 cb_color_size_idx[8]; 59 u32 cb_color_size_idx[8];
59 u32 cb_target_mask; 60 u32 cb_target_mask;
60 u32 cb_shader_mask; 61 u32 cb_shader_mask;
@@ -77,9 +78,9 @@ struct r600_cs_track {
77 78
78#define FMT_8_BIT(fmt, vc) [fmt] = { 1, 1, 1, vc, CHIP_R600 } 79#define FMT_8_BIT(fmt, vc) [fmt] = { 1, 1, 1, vc, CHIP_R600 }
79#define FMT_16_BIT(fmt, vc) [fmt] = { 1, 1, 2, vc, CHIP_R600 } 80#define FMT_16_BIT(fmt, vc) [fmt] = { 1, 1, 2, vc, CHIP_R600 }
80#define FMT_24_BIT(fmt) [fmt] = { 1, 1, 3, 0, CHIP_R600 } 81#define FMT_24_BIT(fmt) [fmt] = { 1, 1, 4, 0, CHIP_R600 }
81#define FMT_32_BIT(fmt, vc) [fmt] = { 1, 1, 4, vc, CHIP_R600 } 82#define FMT_32_BIT(fmt, vc) [fmt] = { 1, 1, 4, vc, CHIP_R600 }
82#define FMT_48_BIT(fmt) [fmt] = { 1, 1, 6, 0, CHIP_R600 } 83#define FMT_48_BIT(fmt) [fmt] = { 1, 1, 8, 0, CHIP_R600 }
83#define FMT_64_BIT(fmt, vc) [fmt] = { 1, 1, 8, vc, CHIP_R600 } 84#define FMT_64_BIT(fmt, vc) [fmt] = { 1, 1, 8, vc, CHIP_R600 }
84#define FMT_96_BIT(fmt) [fmt] = { 1, 1, 12, 0, CHIP_R600 } 85#define FMT_96_BIT(fmt) [fmt] = { 1, 1, 12, 0, CHIP_R600 }
85#define FMT_128_BIT(fmt, vc) [fmt] = { 1, 1, 16,vc, CHIP_R600 } 86#define FMT_128_BIT(fmt, vc) [fmt] = { 1, 1, 16,vc, CHIP_R600 }
@@ -111,7 +112,7 @@ static const struct gpu_formats color_formats_table[] = {
111 112
112 /* 24-bit */ 113 /* 24-bit */
113 FMT_24_BIT(V_038004_FMT_8_8_8), 114 FMT_24_BIT(V_038004_FMT_8_8_8),
114 115
115 /* 32-bit */ 116 /* 32-bit */
116 FMT_32_BIT(V_038004_COLOR_32, 1), 117 FMT_32_BIT(V_038004_COLOR_32, 1),
117 FMT_32_BIT(V_038004_COLOR_32_FLOAT, 1), 118 FMT_32_BIT(V_038004_COLOR_32_FLOAT, 1),
@@ -166,22 +167,22 @@ static const struct gpu_formats color_formats_table[] = {
166 [V_038004_FMT_32_AS_32_32_32_32] = { 1, 1, 4, 0, CHIP_CEDAR}, 167 [V_038004_FMT_32_AS_32_32_32_32] = { 1, 1, 4, 0, CHIP_CEDAR},
167}; 168};
168 169
169static bool fmt_is_valid_color(u32 format) 170bool r600_fmt_is_valid_color(u32 format)
170{ 171{
171 if (format >= ARRAY_SIZE(color_formats_table)) 172 if (format >= ARRAY_SIZE(color_formats_table))
172 return false; 173 return false;
173 174
174 if (color_formats_table[format].valid_color) 175 if (color_formats_table[format].valid_color)
175 return true; 176 return true;
176 177
177 return false; 178 return false;
178} 179}
179 180
180static bool fmt_is_valid_texture(u32 format, enum radeon_family family) 181bool r600_fmt_is_valid_texture(u32 format, enum radeon_family family)
181{ 182{
182 if (format >= ARRAY_SIZE(color_formats_table)) 183 if (format >= ARRAY_SIZE(color_formats_table))
183 return false; 184 return false;
184 185
185 if (family < color_formats_table[format].min_family) 186 if (family < color_formats_table[format].min_family)
186 return false; 187 return false;
187 188
@@ -191,7 +192,7 @@ static bool fmt_is_valid_texture(u32 format, enum radeon_family family)
191 return false; 192 return false;
192} 193}
193 194
194static int fmt_get_blocksize(u32 format) 195int r600_fmt_get_blocksize(u32 format)
195{ 196{
196 if (format >= ARRAY_SIZE(color_formats_table)) 197 if (format >= ARRAY_SIZE(color_formats_table))
197 return 0; 198 return 0;
@@ -199,7 +200,7 @@ static int fmt_get_blocksize(u32 format)
199 return color_formats_table[format].blocksize; 200 return color_formats_table[format].blocksize;
200} 201}
201 202
202static int fmt_get_nblocksx(u32 format, u32 w) 203int r600_fmt_get_nblocksx(u32 format, u32 w)
203{ 204{
204 unsigned bw; 205 unsigned bw;
205 206
@@ -213,7 +214,7 @@ static int fmt_get_nblocksx(u32 format, u32 w)
213 return (w + bw - 1) / bw; 214 return (w + bw - 1) / bw;
214} 215}
215 216
216static int fmt_get_nblocksy(u32 format, u32 h) 217int r600_fmt_get_nblocksy(u32 format, u32 h)
217{ 218{
218 unsigned bh; 219 unsigned bh;
219 220
@@ -260,7 +261,7 @@ static int r600_get_array_mode_alignment(struct array_mode_checker *values,
260 break; 261 break;
261 case ARRAY_LINEAR_ALIGNED: 262 case ARRAY_LINEAR_ALIGNED:
262 *pitch_align = max((u32)64, (u32)(values->group_size / values->blocksize)); 263 *pitch_align = max((u32)64, (u32)(values->group_size / values->blocksize));
263 *height_align = tile_height; 264 *height_align = 1;
264 *depth_align = 1; 265 *depth_align = 1;
265 *base_align = values->group_size; 266 *base_align = values->group_size;
266 break; 267 break;
@@ -273,10 +274,9 @@ static int r600_get_array_mode_alignment(struct array_mode_checker *values,
273 *base_align = values->group_size; 274 *base_align = values->group_size;
274 break; 275 break;
275 case ARRAY_2D_TILED_THIN1: 276 case ARRAY_2D_TILED_THIN1:
276 *pitch_align = max((u32)macro_tile_width, 277 *pitch_align = max((u32)macro_tile_width * tile_width,
277 (u32)(((values->group_size / tile_height) / 278 (u32)((values->group_size * values->nbanks) /
278 (values->blocksize * values->nsamples)) * 279 (values->blocksize * values->nsamples * tile_width)));
279 values->nbanks)) * tile_width;
280 *height_align = macro_tile_height * tile_height; 280 *height_align = macro_tile_height * tile_height;
281 *depth_align = 1; 281 *depth_align = 1;
282 *base_align = max(macro_tile_bytes, 282 *base_align = max(macro_tile_bytes,
@@ -300,6 +300,7 @@ static void r600_cs_track_init(struct r600_cs_track *track)
300 track->cb_color_size[i] = 0; 300 track->cb_color_size[i] = 0;
301 track->cb_color_size_idx[i] = 0; 301 track->cb_color_size_idx[i] = 0;
302 track->cb_color_info[i] = 0; 302 track->cb_color_info[i] = 0;
303 track->cb_color_view[i] = 0xFFFFFFFF;
303 track->cb_color_bo[i] = NULL; 304 track->cb_color_bo[i] = NULL;
304 track->cb_color_bo_offset[i] = 0xFFFFFFFF; 305 track->cb_color_bo_offset[i] = 0xFFFFFFFF;
305 track->cb_color_bo_mc[i] = 0xFFFFFFFF; 306 track->cb_color_bo_mc[i] = 0xFFFFFFFF;
@@ -333,13 +334,14 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
333 volatile u32 *ib = p->ib->ptr; 334 volatile u32 *ib = p->ib->ptr;
334 unsigned array_mode; 335 unsigned array_mode;
335 u32 format; 336 u32 format;
337
336 if (G_0280A0_TILE_MODE(track->cb_color_info[i])) { 338 if (G_0280A0_TILE_MODE(track->cb_color_info[i])) {
337 dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n"); 339 dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n");
338 return -EINVAL; 340 return -EINVAL;
339 } 341 }
340 size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i]; 342 size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i];
341 format = G_0280A0_FORMAT(track->cb_color_info[i]); 343 format = G_0280A0_FORMAT(track->cb_color_info[i]);
342 if (!fmt_is_valid_color(format)) { 344 if (!r600_fmt_is_valid_color(format)) {
343 dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08X)\n", 345 dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08X)\n",
344 __func__, __LINE__, format, 346 __func__, __LINE__, format,
345 i, track->cb_color_info[i]); 347 i, track->cb_color_info[i]);
@@ -360,7 +362,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
360 array_check.nbanks = track->nbanks; 362 array_check.nbanks = track->nbanks;
361 array_check.npipes = track->npipes; 363 array_check.npipes = track->npipes;
362 array_check.nsamples = track->nsamples; 364 array_check.nsamples = track->nsamples;
363 array_check.blocksize = fmt_get_blocksize(format); 365 array_check.blocksize = r600_fmt_get_blocksize(format);
364 if (r600_get_array_mode_alignment(&array_check, 366 if (r600_get_array_mode_alignment(&array_check,
365 &pitch_align, &height_align, &depth_align, &base_align)) { 367 &pitch_align, &height_align, &depth_align, &base_align)) {
366 dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, 368 dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__,
@@ -404,7 +406,18 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
404 } 406 }
405 407
406 /* check offset */ 408 /* check offset */
407 tmp = fmt_get_nblocksy(format, height) * fmt_get_nblocksx(format, pitch) * fmt_get_blocksize(format); 409 tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * r600_fmt_get_blocksize(format);
410 switch (array_mode) {
411 default:
412 case V_0280A0_ARRAY_LINEAR_GENERAL:
413 case V_0280A0_ARRAY_LINEAR_ALIGNED:
414 tmp += track->cb_color_view[i] & 0xFF;
415 break;
416 case V_0280A0_ARRAY_1D_TILED_THIN1:
417 case V_0280A0_ARRAY_2D_TILED_THIN1:
418 tmp += G_028080_SLICE_MAX(track->cb_color_view[i]) * tmp;
419 break;
420 }
408 if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { 421 if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
409 if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { 422 if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) {
410 /* the initial DDX does bad things with the CB size occasionally */ 423 /* the initial DDX does bad things with the CB size occasionally */
@@ -414,10 +427,13 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
414 * broken userspace. 427 * broken userspace.
415 */ 428 */
416 } else { 429 } else {
417 dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big\n", __func__, i, 430 dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big (%d %d) (%d %d %d)\n",
418 array_mode, 431 __func__, i, array_mode,
419 track->cb_color_bo_offset[i], tmp, 432 track->cb_color_bo_offset[i], tmp,
420 radeon_bo_size(track->cb_color_bo[i])); 433 radeon_bo_size(track->cb_color_bo[i]),
434 pitch, height, r600_fmt_get_nblocksx(format, pitch),
435 r600_fmt_get_nblocksy(format, height),
436 r600_fmt_get_blocksize(format));
421 return -EINVAL; 437 return -EINVAL;
422 } 438 }
423 } 439 }
@@ -1075,6 +1091,17 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
1075 track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); 1091 track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
1076 } 1092 }
1077 break; 1093 break;
1094 case R_028080_CB_COLOR0_VIEW:
1095 case R_028084_CB_COLOR1_VIEW:
1096 case R_028088_CB_COLOR2_VIEW:
1097 case R_02808C_CB_COLOR3_VIEW:
1098 case R_028090_CB_COLOR4_VIEW:
1099 case R_028094_CB_COLOR5_VIEW:
1100 case R_028098_CB_COLOR6_VIEW:
1101 case R_02809C_CB_COLOR7_VIEW:
1102 tmp = (reg - R_028080_CB_COLOR0_VIEW) / 4;
1103 track->cb_color_view[tmp] = radeon_get_ib_value(p, idx);
1104 break;
1078 case R_028060_CB_COLOR0_SIZE: 1105 case R_028060_CB_COLOR0_SIZE:
1079 case R_028064_CB_COLOR1_SIZE: 1106 case R_028064_CB_COLOR1_SIZE:
1080 case R_028068_CB_COLOR2_SIZE: 1107 case R_028068_CB_COLOR2_SIZE:
@@ -1259,7 +1286,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
1259 return 0; 1286 return 0;
1260} 1287}
1261 1288
1262static unsigned mip_minify(unsigned size, unsigned level) 1289unsigned r600_mip_minify(unsigned size, unsigned level)
1263{ 1290{
1264 unsigned val; 1291 unsigned val;
1265 1292
@@ -1281,22 +1308,22 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel,
1281 unsigned nlevels = llevel - blevel + 1; 1308 unsigned nlevels = llevel - blevel + 1;
1282 1309
1283 *l0_size = -1; 1310 *l0_size = -1;
1284 blocksize = fmt_get_blocksize(format); 1311 blocksize = r600_fmt_get_blocksize(format);
1285 1312
1286 w0 = mip_minify(w0, 0); 1313 w0 = r600_mip_minify(w0, 0);
1287 h0 = mip_minify(h0, 0); 1314 h0 = r600_mip_minify(h0, 0);
1288 d0 = mip_minify(d0, 0); 1315 d0 = r600_mip_minify(d0, 0);
1289 for(i = 0, offset = 0, level = blevel; i < nlevels; i++, level++) { 1316 for(i = 0, offset = 0, level = blevel; i < nlevels; i++, level++) {
1290 width = mip_minify(w0, i); 1317 width = r600_mip_minify(w0, i);
1291 nbx = fmt_get_nblocksx(format, width); 1318 nbx = r600_fmt_get_nblocksx(format, width);
1292 1319
1293 nbx = round_up(nbx, block_align); 1320 nbx = round_up(nbx, block_align);
1294 1321
1295 height = mip_minify(h0, i); 1322 height = r600_mip_minify(h0, i);
1296 nby = fmt_get_nblocksy(format, height); 1323 nby = r600_fmt_get_nblocksy(format, height);
1297 nby = round_up(nby, height_align); 1324 nby = round_up(nby, height_align);
1298 1325
1299 depth = mip_minify(d0, i); 1326 depth = r600_mip_minify(d0, i);
1300 1327
1301 size = nbx * nby * blocksize; 1328 size = nbx * nby * blocksize;
1302 if (nfaces) 1329 if (nfaces)
@@ -1387,7 +1414,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx,
1387 return -EINVAL; 1414 return -EINVAL;
1388 } 1415 }
1389 format = G_038004_DATA_FORMAT(word1); 1416 format = G_038004_DATA_FORMAT(word1);
1390 if (!fmt_is_valid_texture(format, p->family)) { 1417 if (!r600_fmt_is_valid_texture(format, p->family)) {
1391 dev_warn(p->dev, "%s:%d texture invalid format %d\n", 1418 dev_warn(p->dev, "%s:%d texture invalid format %d\n",
1392 __func__, __LINE__, format); 1419 __func__, __LINE__, format);
1393 return -EINVAL; 1420 return -EINVAL;
@@ -1400,7 +1427,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx,
1400 array_check.nbanks = track->nbanks; 1427 array_check.nbanks = track->nbanks;
1401 array_check.npipes = track->npipes; 1428 array_check.npipes = track->npipes;
1402 array_check.nsamples = 1; 1429 array_check.nsamples = 1;
1403 array_check.blocksize = fmt_get_blocksize(format); 1430 array_check.blocksize = r600_fmt_get_blocksize(format);
1404 if (r600_get_array_mode_alignment(&array_check, 1431 if (r600_get_array_mode_alignment(&array_check,
1405 &pitch_align, &height_align, &depth_align, &base_align)) { 1432 &pitch_align, &height_align, &depth_align, &base_align)) {
1406 dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", 1433 dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n",
@@ -1433,6 +1460,10 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx,
1433 word1 = radeon_get_ib_value(p, idx + 5); 1460 word1 = radeon_get_ib_value(p, idx + 5);
1434 blevel = G_038010_BASE_LEVEL(word0); 1461 blevel = G_038010_BASE_LEVEL(word0);
1435 llevel = G_038014_LAST_LEVEL(word1); 1462 llevel = G_038014_LAST_LEVEL(word1);
1463 if (blevel > llevel) {
1464 dev_warn(p->dev, "texture blevel %d > llevel %d\n",
1465 blevel, llevel);
1466 }
1436 if (array == 1) { 1467 if (array == 1) {
1437 barray = G_038014_BASE_ARRAY(word1); 1468 barray = G_038014_BASE_ARRAY(word1);
1438 larray = G_038014_LAST_ARRAY(word1); 1469 larray = G_038014_LAST_ARRAY(word1);
@@ -1444,8 +1475,10 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx,
1444 &l0_size, &mipmap_size); 1475 &l0_size, &mipmap_size);
1445 /* using get ib will give us the offset into the texture bo */ 1476 /* using get ib will give us the offset into the texture bo */
1446 if ((l0_size + word2) > radeon_bo_size(texture)) { 1477 if ((l0_size + word2) > radeon_bo_size(texture)) {
1447 dev_warn(p->dev, "texture bo too small (%d %d %d %d -> %d have %ld)\n", 1478 dev_warn(p->dev, "texture bo too small ((%d %d) (%d %d) %d %d %d -> %d have %ld)\n",
1448 w0, h0, format, word2, l0_size, radeon_bo_size(texture)); 1479 w0, h0, pitch_align, height_align,
1480 array_check.array_mode, format, word2,
1481 l0_size, radeon_bo_size(texture));
1449 dev_warn(p->dev, "alignments %d %d %d %lld\n", pitch, pitch_align, height_align, base_align); 1482 dev_warn(p->dev, "alignments %d %d %d %lld\n", pitch, pitch_align, height_align, base_align);
1450 return -EINVAL; 1483 return -EINVAL;
1451 } 1484 }
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index aa9d7c352da6..2ba460b5b62f 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -78,6 +78,20 @@
78 78
79#define CB_COLOR0_SIZE 0x28060 79#define CB_COLOR0_SIZE 0x28060
80#define CB_COLOR0_VIEW 0x28080 80#define CB_COLOR0_VIEW 0x28080
81#define R_028080_CB_COLOR0_VIEW 0x028080
82#define S_028080_SLICE_START(x) (((x) & 0x7FF) << 0)
83#define G_028080_SLICE_START(x) (((x) >> 0) & 0x7FF)
84#define C_028080_SLICE_START 0xFFFFF800
85#define S_028080_SLICE_MAX(x) (((x) & 0x7FF) << 13)
86#define G_028080_SLICE_MAX(x) (((x) >> 13) & 0x7FF)
87#define C_028080_SLICE_MAX 0xFF001FFF
88#define R_028084_CB_COLOR1_VIEW 0x028084
89#define R_028088_CB_COLOR2_VIEW 0x028088
90#define R_02808C_CB_COLOR3_VIEW 0x02808C
91#define R_028090_CB_COLOR4_VIEW 0x028090
92#define R_028094_CB_COLOR5_VIEW 0x028094
93#define R_028098_CB_COLOR6_VIEW 0x028098
94#define R_02809C_CB_COLOR7_VIEW 0x02809C
81#define CB_COLOR0_INFO 0x280a0 95#define CB_COLOR0_INFO 0x280a0
82# define CB_FORMAT(x) ((x) << 2) 96# define CB_FORMAT(x) ((x) << 2)
83# define CB_ARRAY_MODE(x) ((x) << 8) 97# define CB_ARRAY_MODE(x) ((x) << 8)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 1668ec1ee770..884e0d4b114f 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -242,6 +242,9 @@ extern int rv6xx_get_temp(struct radeon_device *rdev);
242extern int rv770_get_temp(struct radeon_device *rdev); 242extern int rv770_get_temp(struct radeon_device *rdev);
243extern int evergreen_get_temp(struct radeon_device *rdev); 243extern int evergreen_get_temp(struct radeon_device *rdev);
244extern int sumo_get_temp(struct radeon_device *rdev); 244extern int sumo_get_temp(struct radeon_device *rdev);
245extern void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw,
246 unsigned *bankh, unsigned *mtaspect,
247 unsigned *tile_split);
245 248
246/* 249/*
247 * Fences. 250 * Fences.
@@ -1750,6 +1753,16 @@ int r600_vram_scratch_init(struct radeon_device *rdev);
1750void r600_vram_scratch_fini(struct radeon_device *rdev); 1753void r600_vram_scratch_fini(struct radeon_device *rdev);
1751 1754
1752/* 1755/*
1756 * r600 cs checking helper
1757 */
1758unsigned r600_mip_minify(unsigned size, unsigned level);
1759bool r600_fmt_is_valid_color(u32 format);
1760bool r600_fmt_is_valid_texture(u32 format, enum radeon_family family);
1761int r600_fmt_get_blocksize(u32 format);
1762int r600_fmt_get_nblocksx(u32 format, u32 w);
1763int r600_fmt_get_nblocksy(u32 format, u32 h);
1764
1765/*
1753 * r600 functions used by radeon_encoder.c 1766 * r600 functions used by radeon_encoder.c
1754 */ 1767 */
1755extern void r600_hdmi_enable(struct drm_encoder *encoder); 1768extern void r600_hdmi_enable(struct drm_encoder *encoder);
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 713d066e9d41..498d21d50ba3 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -55,9 +55,10 @@
55 * 2.11.0 - backend map, initial compute support for the CS checker 55 * 2.11.0 - backend map, initial compute support for the CS checker
56 * 2.12.0 - RADEON_CS_KEEP_TILING_FLAGS 56 * 2.12.0 - RADEON_CS_KEEP_TILING_FLAGS
57 * 2.13.0 - virtual memory support, streamout 57 * 2.13.0 - virtual memory support, streamout
58 * 2.14.0 - add evergreen tiling informations
58 */ 59 */
59#define KMS_DRIVER_MAJOR 2 60#define KMS_DRIVER_MAJOR 2
60#define KMS_DRIVER_MINOR 13 61#define KMS_DRIVER_MINOR 14
61#define KMS_DRIVER_PATCHLEVEL 0 62#define KMS_DRIVER_PATCHLEVEL 0
62int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); 63int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
63int radeon_driver_unload_kms(struct drm_device *dev); 64int radeon_driver_unload_kms(struct drm_device *dev);
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index d45df1763598..342deaccc152 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -445,8 +445,54 @@ static void radeon_bo_clear_surface_reg(struct radeon_bo *bo)
445int radeon_bo_set_tiling_flags(struct radeon_bo *bo, 445int radeon_bo_set_tiling_flags(struct radeon_bo *bo,
446 uint32_t tiling_flags, uint32_t pitch) 446 uint32_t tiling_flags, uint32_t pitch)
447{ 447{
448 struct radeon_device *rdev = bo->rdev;
448 int r; 449 int r;
449 450
451 if (rdev->family >= CHIP_CEDAR) {
452 unsigned bankw, bankh, mtaspect, tilesplit, stilesplit;
453
454 bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK;
455 bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK;
456 mtaspect = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK;
457 tilesplit = (tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK;
458 stilesplit = (tiling_flags >> RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK;
459 switch (bankw) {
460 case 0:
461 case 1:
462 case 2:
463 case 4:
464 case 8:
465 break;
466 default:
467 return -EINVAL;
468 }
469 switch (bankh) {
470 case 0:
471 case 1:
472 case 2:
473 case 4:
474 case 8:
475 break;
476 default:
477 return -EINVAL;
478 }
479 switch (mtaspect) {
480 case 0:
481 case 1:
482 case 2:
483 case 4:
484 case 8:
485 break;
486 default:
487 return -EINVAL;
488 }
489 if (tilesplit > 6) {
490 return -EINVAL;
491 }
492 if (stilesplit > 6) {
493 return -EINVAL;
494 }
495 }
450 r = radeon_bo_reserve(bo, false); 496 r = radeon_bo_reserve(bo, false);
451 if (unlikely(r != 0)) 497 if (unlikely(r != 0))
452 return r; 498 return r;
diff --git a/drivers/gpu/drm/radeon/reg_srcs/cayman b/drivers/gpu/drm/radeon/reg_srcs/cayman
index 0eac19ec595f..7b526d3ceac1 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/cayman
+++ b/drivers/gpu/drm/radeon/reg_srcs/cayman
@@ -80,7 +80,6 @@ cayman 0x9400
800x0002802C DB_DEPTH_CLEAR 800x0002802C DB_DEPTH_CLEAR
810x00028030 PA_SC_SCREEN_SCISSOR_TL 810x00028030 PA_SC_SCREEN_SCISSOR_TL
820x00028034 PA_SC_SCREEN_SCISSOR_BR 820x00028034 PA_SC_SCREEN_SCISSOR_BR
830x0002805C DB_DEPTH_SLICE
840x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0 830x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0
850x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1 840x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1
860x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2 850x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2
diff --git a/drivers/gpu/drm/radeon/reg_srcs/evergreen b/drivers/gpu/drm/radeon/reg_srcs/evergreen
index 4e3f208eef77..7f4339463e31 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/evergreen
+++ b/drivers/gpu/drm/radeon/reg_srcs/evergreen
@@ -96,7 +96,6 @@ evergreen 0x9400
960x0002802C DB_DEPTH_CLEAR 960x0002802C DB_DEPTH_CLEAR
970x00028030 PA_SC_SCREEN_SCISSOR_TL 970x00028030 PA_SC_SCREEN_SCISSOR_TL
980x00028034 PA_SC_SCREEN_SCISSOR_BR 980x00028034 PA_SC_SCREEN_SCISSOR_BR
990x0002805C DB_DEPTH_SLICE
1000x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0 990x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0
1010x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1 1000x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1
1020x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2 1010x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600
index a1fc242df5da..79d245527ba8 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/r600
+++ b/drivers/gpu/drm/radeon/reg_srcs/r600
@@ -754,14 +754,6 @@ r600 0x9400
7540x00028114 CB_COLOR5_MASK 7540x00028114 CB_COLOR5_MASK
7550x00028118 CB_COLOR6_MASK 7550x00028118 CB_COLOR6_MASK
7560x0002811C CB_COLOR7_MASK 7560x0002811C CB_COLOR7_MASK
7570x00028080 CB_COLOR0_VIEW
7580x00028084 CB_COLOR1_VIEW
7590x00028088 CB_COLOR2_VIEW
7600x0002808C CB_COLOR3_VIEW
7610x00028090 CB_COLOR4_VIEW
7620x00028094 CB_COLOR5_VIEW
7630x00028098 CB_COLOR6_VIEW
7640x0002809C CB_COLOR7_VIEW
7650x00028808 CB_COLOR_CONTROL 7570x00028808 CB_COLOR_CONTROL
7660x0002842C CB_FOG_BLUE 7580x0002842C CB_FOG_BLUE
7670x00028428 CB_FOG_GREEN 7590x00028428 CB_FOG_GREEN