drm: Merge tag 'v3.3-rc7' into drm-core-next
[linux-3.10.git] / drivers / gpu / drm / radeon / r600_cs.c
1 /*
2  * Copyright 2008 Advanced Micro Devices, Inc.
3  * Copyright 2008 Red Hat Inc.
4  * Copyright 2009 Jerome Glisse.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors: Dave Airlie
25  *          Alex Deucher
26  *          Jerome Glisse
27  */
28 #include <linux/kernel.h>
29 #include "drmP.h"
30 #include "radeon.h"
31 #include "r600d.h"
32 #include "r600_reg_safe.h"
33
34 static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p,
35                                         struct radeon_cs_reloc **cs_reloc);
36 static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p,
37                                         struct radeon_cs_reloc **cs_reloc);
38 typedef int (*next_reloc_t)(struct radeon_cs_parser*, struct radeon_cs_reloc**);
39 static next_reloc_t r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_mm;
40 extern void r600_cs_legacy_get_tiling_conf(struct drm_device *dev, u32 *npipes, u32 *nbanks, u32 *group_size);
41
42
43 struct r600_cs_track {
44         /* configuration we miror so that we use same code btw kms/ums */
45         u32                     group_size;
46         u32                     nbanks;
47         u32                     npipes;
48         /* value we track */
49         u32                     sq_config;
50         u32                     nsamples;
51         u32                     cb_color_base_last[8];
52         struct radeon_bo        *cb_color_bo[8];
53         u64                     cb_color_bo_mc[8];
54         u32                     cb_color_bo_offset[8];
55         struct radeon_bo        *cb_color_frag_bo[8];
56         struct radeon_bo        *cb_color_tile_bo[8];
57         u32                     cb_color_info[8];
58         u32                     cb_color_view[8];
59         u32                     cb_color_size_idx[8];
60         u32                     cb_target_mask;
61         u32                     cb_shader_mask;
62         u32                     cb_color_size[8];
63         u32                     vgt_strmout_en;
64         u32                     vgt_strmout_buffer_en;
65         struct radeon_bo        *vgt_strmout_bo[4];
66         u64                     vgt_strmout_bo_mc[4];
67         u32                     vgt_strmout_bo_offset[4];
68         u32                     vgt_strmout_size[4];
69         u32                     db_depth_control;
70         u32                     db_depth_info;
71         u32                     db_depth_size_idx;
72         u32                     db_depth_view;
73         u32                     db_depth_size;
74         u32                     db_offset;
75         struct radeon_bo        *db_bo;
76         u64                     db_bo_mc;
77 };
78
79 #define FMT_8_BIT(fmt, vc)   [fmt] = { 1, 1, 1, vc, CHIP_R600 }
80 #define FMT_16_BIT(fmt, vc)  [fmt] = { 1, 1, 2, vc, CHIP_R600 }
81 #define FMT_24_BIT(fmt)      [fmt] = { 1, 1, 4,  0, CHIP_R600 }
82 #define FMT_32_BIT(fmt, vc)  [fmt] = { 1, 1, 4, vc, CHIP_R600 }
83 #define FMT_48_BIT(fmt)      [fmt] = { 1, 1, 8,  0, CHIP_R600 }
84 #define FMT_64_BIT(fmt, vc)  [fmt] = { 1, 1, 8, vc, CHIP_R600 }
85 #define FMT_96_BIT(fmt)      [fmt] = { 1, 1, 12, 0, CHIP_R600 }
86 #define FMT_128_BIT(fmt, vc) [fmt] = { 1, 1, 16,vc, CHIP_R600 }
87
88 struct gpu_formats {
89         unsigned blockwidth;
90         unsigned blockheight;
91         unsigned blocksize;
92         unsigned valid_color;
93         enum radeon_family min_family;
94 };
95
96 static const struct gpu_formats color_formats_table[] = {
97         /* 8 bit */
98         FMT_8_BIT(V_038004_COLOR_8, 1),
99         FMT_8_BIT(V_038004_COLOR_4_4, 1),
100         FMT_8_BIT(V_038004_COLOR_3_3_2, 1),
101         FMT_8_BIT(V_038004_FMT_1, 0),
102
103         /* 16-bit */
104         FMT_16_BIT(V_038004_COLOR_16, 1),
105         FMT_16_BIT(V_038004_COLOR_16_FLOAT, 1),
106         FMT_16_BIT(V_038004_COLOR_8_8, 1),
107         FMT_16_BIT(V_038004_COLOR_5_6_5, 1),
108         FMT_16_BIT(V_038004_COLOR_6_5_5, 1),
109         FMT_16_BIT(V_038004_COLOR_1_5_5_5, 1),
110         FMT_16_BIT(V_038004_COLOR_4_4_4_4, 1),
111         FMT_16_BIT(V_038004_COLOR_5_5_5_1, 1),
112
113         /* 24-bit */
114         FMT_24_BIT(V_038004_FMT_8_8_8),
115
116         /* 32-bit */
117         FMT_32_BIT(V_038004_COLOR_32, 1),
118         FMT_32_BIT(V_038004_COLOR_32_FLOAT, 1),
119         FMT_32_BIT(V_038004_COLOR_16_16, 1),
120         FMT_32_BIT(V_038004_COLOR_16_16_FLOAT, 1),
121         FMT_32_BIT(V_038004_COLOR_8_24, 1),
122         FMT_32_BIT(V_038004_COLOR_8_24_FLOAT, 1),
123         FMT_32_BIT(V_038004_COLOR_24_8, 1),
124         FMT_32_BIT(V_038004_COLOR_24_8_FLOAT, 1),
125         FMT_32_BIT(V_038004_COLOR_10_11_11, 1),
126         FMT_32_BIT(V_038004_COLOR_10_11_11_FLOAT, 1),
127         FMT_32_BIT(V_038004_COLOR_11_11_10, 1),
128         FMT_32_BIT(V_038004_COLOR_11_11_10_FLOAT, 1),
129         FMT_32_BIT(V_038004_COLOR_2_10_10_10, 1),
130         FMT_32_BIT(V_038004_COLOR_8_8_8_8, 1),
131         FMT_32_BIT(V_038004_COLOR_10_10_10_2, 1),
132         FMT_32_BIT(V_038004_FMT_5_9_9_9_SHAREDEXP, 0),
133         FMT_32_BIT(V_038004_FMT_32_AS_8, 0),
134         FMT_32_BIT(V_038004_FMT_32_AS_8_8, 0),
135
136         /* 48-bit */
137         FMT_48_BIT(V_038004_FMT_16_16_16),
138         FMT_48_BIT(V_038004_FMT_16_16_16_FLOAT),
139
140         /* 64-bit */
141         FMT_64_BIT(V_038004_COLOR_X24_8_32_FLOAT, 1),
142         FMT_64_BIT(V_038004_COLOR_32_32, 1),
143         FMT_64_BIT(V_038004_COLOR_32_32_FLOAT, 1),
144         FMT_64_BIT(V_038004_COLOR_16_16_16_16, 1),
145         FMT_64_BIT(V_038004_COLOR_16_16_16_16_FLOAT, 1),
146
147         FMT_96_BIT(V_038004_FMT_32_32_32),
148         FMT_96_BIT(V_038004_FMT_32_32_32_FLOAT),
149
150         /* 128-bit */
151         FMT_128_BIT(V_038004_COLOR_32_32_32_32, 1),
152         FMT_128_BIT(V_038004_COLOR_32_32_32_32_FLOAT, 1),
153
154         [V_038004_FMT_GB_GR] = { 2, 1, 4, 0 },
155         [V_038004_FMT_BG_RG] = { 2, 1, 4, 0 },
156
157         /* block compressed formats */
158         [V_038004_FMT_BC1] = { 4, 4, 8, 0 },
159         [V_038004_FMT_BC2] = { 4, 4, 16, 0 },
160         [V_038004_FMT_BC3] = { 4, 4, 16, 0 },
161         [V_038004_FMT_BC4] = { 4, 4, 8, 0 },
162         [V_038004_FMT_BC5] = { 4, 4, 16, 0},
163         [V_038004_FMT_BC6] = { 4, 4, 16, 0, CHIP_CEDAR}, /* Evergreen-only */
164         [V_038004_FMT_BC7] = { 4, 4, 16, 0, CHIP_CEDAR}, /* Evergreen-only */
165
166         /* The other Evergreen formats */
167         [V_038004_FMT_32_AS_32_32_32_32] = { 1, 1, 4, 0, CHIP_CEDAR},
168 };
169
170 bool r600_fmt_is_valid_color(u32 format)
171 {
172         if (format >= ARRAY_SIZE(color_formats_table))
173                 return false;
174
175         if (color_formats_table[format].valid_color)
176                 return true;
177
178         return false;
179 }
180
181 bool r600_fmt_is_valid_texture(u32 format, enum radeon_family family)
182 {
183         if (format >= ARRAY_SIZE(color_formats_table))
184                 return false;
185
186         if (family < color_formats_table[format].min_family)
187                 return false;
188
189         if (color_formats_table[format].blockwidth > 0)
190                 return true;
191
192         return false;
193 }
194
195 int r600_fmt_get_blocksize(u32 format)
196 {
197         if (format >= ARRAY_SIZE(color_formats_table))
198                 return 0;
199
200         return color_formats_table[format].blocksize;
201 }
202
203 int r600_fmt_get_nblocksx(u32 format, u32 w)
204 {
205         unsigned bw;
206
207         if (format >= ARRAY_SIZE(color_formats_table))
208                 return 0;
209
210         bw = color_formats_table[format].blockwidth;
211         if (bw == 0)
212                 return 0;
213
214         return (w + bw - 1) / bw;
215 }
216
217 int r600_fmt_get_nblocksy(u32 format, u32 h)
218 {
219         unsigned bh;
220
221         if (format >= ARRAY_SIZE(color_formats_table))
222                 return 0;
223
224         bh = color_formats_table[format].blockheight;
225         if (bh == 0)
226                 return 0;
227
228         return (h + bh - 1) / bh;
229 }
230
231 struct array_mode_checker {
232         int array_mode;
233         u32 group_size;
234         u32 nbanks;
235         u32 npipes;
236         u32 nsamples;
237         u32 blocksize;
238 };
239
240 /* returns alignment in pixels for pitch/height/depth and bytes for base */
241 static int r600_get_array_mode_alignment(struct array_mode_checker *values,
242                                                 u32 *pitch_align,
243                                                 u32 *height_align,
244                                                 u32 *depth_align,
245                                                 u64 *base_align)
246 {
247         u32 tile_width = 8;
248         u32 tile_height = 8;
249         u32 macro_tile_width = values->nbanks;
250         u32 macro_tile_height = values->npipes;
251         u32 tile_bytes = tile_width * tile_height * values->blocksize * values->nsamples;
252         u32 macro_tile_bytes = macro_tile_width * macro_tile_height * tile_bytes;
253
254         switch (values->array_mode) {
255         case ARRAY_LINEAR_GENERAL:
256                 /* technically tile_width/_height for pitch/height */
257                 *pitch_align = 1; /* tile_width */
258                 *height_align = 1; /* tile_height */
259                 *depth_align = 1;
260                 *base_align = 1;
261                 break;
262         case ARRAY_LINEAR_ALIGNED:
263                 *pitch_align = max((u32)64, (u32)(values->group_size / values->blocksize));
264                 *height_align = 1;
265                 *depth_align = 1;
266                 *base_align = values->group_size;
267                 break;
268         case ARRAY_1D_TILED_THIN1:
269                 *pitch_align = max((u32)tile_width,
270                                    (u32)(values->group_size /
271                                          (tile_height * values->blocksize * values->nsamples)));
272                 *height_align = tile_height;
273                 *depth_align = 1;
274                 *base_align = values->group_size;
275                 break;
276         case ARRAY_2D_TILED_THIN1:
277                 *pitch_align = max((u32)macro_tile_width * tile_width,
278                                 (u32)((values->group_size * values->nbanks) /
279                                 (values->blocksize * values->nsamples * tile_width)));
280                 *height_align = macro_tile_height * tile_height;
281                 *depth_align = 1;
282                 *base_align = max(macro_tile_bytes,
283                                   (*pitch_align) * values->blocksize * (*height_align) * values->nsamples);
284                 break;
285         default:
286                 return -EINVAL;
287         }
288
289         return 0;
290 }
291
292 static void r600_cs_track_init(struct r600_cs_track *track)
293 {
294         int i;
295
296         /* assume DX9 mode */
297         track->sq_config = DX9_CONSTS;
298         for (i = 0; i < 8; i++) {
299                 track->cb_color_base_last[i] = 0;
300                 track->cb_color_size[i] = 0;
301                 track->cb_color_size_idx[i] = 0;
302                 track->cb_color_info[i] = 0;
303                 track->cb_color_view[i] = 0xFFFFFFFF;
304                 track->cb_color_bo[i] = NULL;
305                 track->cb_color_bo_offset[i] = 0xFFFFFFFF;
306                 track->cb_color_bo_mc[i] = 0xFFFFFFFF;
307         }
308         track->cb_target_mask = 0xFFFFFFFF;
309         track->cb_shader_mask = 0xFFFFFFFF;
310         track->db_bo = NULL;
311         track->db_bo_mc = 0xFFFFFFFF;
312         /* assume the biggest format and that htile is enabled */
313         track->db_depth_info = 7 | (1 << 25);
314         track->db_depth_view = 0xFFFFC000;
315         track->db_depth_size = 0xFFFFFFFF;
316         track->db_depth_size_idx = 0;
317         track->db_depth_control = 0xFFFFFFFF;
318
319         for (i = 0; i < 4; i++) {
320                 track->vgt_strmout_size[i] = 0;
321                 track->vgt_strmout_bo[i] = NULL;
322                 track->vgt_strmout_bo_offset[i] = 0xFFFFFFFF;
323                 track->vgt_strmout_bo_mc[i] = 0xFFFFFFFF;
324         }
325 }
326
327 static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
328 {
329         struct r600_cs_track *track = p->track;
330         u32 slice_tile_max, size, tmp;
331         u32 height, height_align, pitch, pitch_align, depth_align;
332         u64 base_offset, base_align;
333         struct array_mode_checker array_check;
334         volatile u32 *ib = p->ib->ptr;
335         unsigned array_mode;
336         u32 format;
337
338         if (G_0280A0_TILE_MODE(track->cb_color_info[i])) {
339                 dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n");
340                 return -EINVAL;
341         }
342         size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i];
343         format = G_0280A0_FORMAT(track->cb_color_info[i]);
344         if (!r600_fmt_is_valid_color(format)) {
345                 dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08X)\n",
346                          __func__, __LINE__, format,
347                         i, track->cb_color_info[i]);
348                 return -EINVAL;
349         }
350         /* pitch in pixels */
351         pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) * 8;
352         slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1;
353         slice_tile_max *= 64;
354         height = slice_tile_max / pitch;
355         if (height > 8192)
356                 height = 8192;
357         array_mode = G_0280A0_ARRAY_MODE(track->cb_color_info[i]);
358
359         base_offset = track->cb_color_bo_mc[i] + track->cb_color_bo_offset[i];
360         array_check.array_mode = array_mode;
361         array_check.group_size = track->group_size;
362         array_check.nbanks = track->nbanks;
363         array_check.npipes = track->npipes;
364         array_check.nsamples = track->nsamples;
365         array_check.blocksize = r600_fmt_get_blocksize(format);
366         if (r600_get_array_mode_alignment(&array_check,
367                                           &pitch_align, &height_align, &depth_align, &base_align)) {
368                 dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__,
369                          G_0280A0_ARRAY_MODE(track->cb_color_info[i]), i,
370                          track->cb_color_info[i]);
371                 return -EINVAL;
372         }
373         switch (array_mode) {
374         case V_0280A0_ARRAY_LINEAR_GENERAL:
375                 break;
376         case V_0280A0_ARRAY_LINEAR_ALIGNED:
377                 break;
378         case V_0280A0_ARRAY_1D_TILED_THIN1:
379                 /* avoid breaking userspace */
380                 if (height > 7)
381                         height &= ~0x7;
382                 break;
383         case V_0280A0_ARRAY_2D_TILED_THIN1:
384                 break;
385         default:
386                 dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__,
387                         G_0280A0_ARRAY_MODE(track->cb_color_info[i]), i,
388                         track->cb_color_info[i]);
389                 return -EINVAL;
390         }
391
392         if (!IS_ALIGNED(pitch, pitch_align)) {
393                 dev_warn(p->dev, "%s:%d cb pitch (%d, 0x%x, %d) invalid\n",
394                          __func__, __LINE__, pitch, pitch_align, array_mode);
395                 return -EINVAL;
396         }
397         if (!IS_ALIGNED(height, height_align)) {
398                 dev_warn(p->dev, "%s:%d cb height (%d, 0x%x, %d) invalid\n",
399                          __func__, __LINE__, height, height_align, array_mode);
400                 return -EINVAL;
401         }
402         if (!IS_ALIGNED(base_offset, base_align)) {
403                 dev_warn(p->dev, "%s offset[%d] 0x%llx 0x%llx, %d not aligned\n", __func__, i,
404                          base_offset, base_align, array_mode);
405                 return -EINVAL;
406         }
407
408         /* check offset */
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         }
421         if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
422                 if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) {
423                         /* the initial DDX does bad things with the CB size occasionally */
424                         /* it rounds up height too far for slice tile max but the BO is smaller */
425                         /* r600c,g also seem to flush at bad times in some apps resulting in
426                          * bogus values here. So for linear just allow anything to avoid breaking
427                          * broken userspace.
428                          */
429                 } else {
430                         dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big (%d %d) (%d %d %d)\n",
431                                  __func__, i, array_mode,
432                                  track->cb_color_bo_offset[i], tmp,
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));
437                         return -EINVAL;
438                 }
439         }
440         /* limit max tile */
441         tmp = (height * pitch) >> 6;
442         if (tmp < slice_tile_max)
443                 slice_tile_max = tmp;
444         tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) |
445                 S_028060_SLICE_TILE_MAX(slice_tile_max - 1);
446         ib[track->cb_color_size_idx[i]] = tmp;
447         return 0;
448 }
449
450 static int r600_cs_track_check(struct radeon_cs_parser *p)
451 {
452         struct r600_cs_track *track = p->track;
453         u32 tmp;
454         int r, i;
455         volatile u32 *ib = p->ib->ptr;
456
457         /* on legacy kernel we don't perform advanced check */
458         if (p->rdev == NULL)
459                 return 0;
460
461         /* check streamout */
462         if (track->vgt_strmout_en) {
463                 for (i = 0; i < 4; i++) {
464                         if (track->vgt_strmout_buffer_en & (1 << i)) {
465                                 if (track->vgt_strmout_bo[i]) {
466                                         u64 offset = (u64)track->vgt_strmout_bo_offset[i] +
467                                                 (u64)track->vgt_strmout_size[i];
468                                         if (offset > radeon_bo_size(track->vgt_strmout_bo[i])) {
469                                                 DRM_ERROR("streamout %d bo too small: 0x%llx, 0x%lx\n",
470                                                           i, offset,
471                                                           radeon_bo_size(track->vgt_strmout_bo[i]));
472                                                 return -EINVAL;
473                                         }
474                                 } else {
475                                         dev_warn(p->dev, "No buffer for streamout %d\n", i);
476                                         return -EINVAL;
477                                 }
478                         }
479                 }
480         }
481
482         /* check that we have a cb for each enabled target, we don't check
483          * shader_mask because it seems mesa isn't always setting it :(
484          */
485         tmp = track->cb_target_mask;
486         for (i = 0; i < 8; i++) {
487                 if ((tmp >> (i * 4)) & 0xF) {
488                         /* at least one component is enabled */
489                         if (track->cb_color_bo[i] == NULL) {
490                                 dev_warn(p->dev, "%s:%d mask 0x%08X | 0x%08X no cb for %d\n",
491                                         __func__, __LINE__, track->cb_target_mask, track->cb_shader_mask, i);
492                                 return -EINVAL;
493                         }
494                         /* perform rewrite of CB_COLOR[0-7]_SIZE */
495                         r = r600_cs_track_validate_cb(p, i);
496                         if (r)
497                                 return r;
498                 }
499         }
500         /* Check depth buffer */
501         if (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
502                 G_028800_Z_ENABLE(track->db_depth_control)) {
503                 u32 nviews, bpe, ntiles, size, slice_tile_max;
504                 u32 height, height_align, pitch, pitch_align, depth_align;
505                 u64 base_offset, base_align;
506                 struct array_mode_checker array_check;
507                 int array_mode;
508
509                 if (track->db_bo == NULL) {
510                         dev_warn(p->dev, "z/stencil with no depth buffer\n");
511                         return -EINVAL;
512                 }
513                 if (G_028010_TILE_SURFACE_ENABLE(track->db_depth_info)) {
514                         dev_warn(p->dev, "this kernel doesn't support z/stencil htile\n");
515                         return -EINVAL;
516                 }
517                 switch (G_028010_FORMAT(track->db_depth_info)) {
518                 case V_028010_DEPTH_16:
519                         bpe = 2;
520                         break;
521                 case V_028010_DEPTH_X8_24:
522                 case V_028010_DEPTH_8_24:
523                 case V_028010_DEPTH_X8_24_FLOAT:
524                 case V_028010_DEPTH_8_24_FLOAT:
525                 case V_028010_DEPTH_32_FLOAT:
526                         bpe = 4;
527                         break;
528                 case V_028010_DEPTH_X24_8_32_FLOAT:
529                         bpe = 8;
530                         break;
531                 default:
532                         dev_warn(p->dev, "z/stencil with invalid format %d\n", G_028010_FORMAT(track->db_depth_info));
533                         return -EINVAL;
534                 }
535                 if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) {
536                         if (!track->db_depth_size_idx) {
537                                 dev_warn(p->dev, "z/stencil buffer size not set\n");
538                                 return -EINVAL;
539                         }
540                         tmp = radeon_bo_size(track->db_bo) - track->db_offset;
541                         tmp = (tmp / bpe) >> 6;
542                         if (!tmp) {
543                                 dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %ld)\n",
544                                                 track->db_depth_size, bpe, track->db_offset,
545                                                 radeon_bo_size(track->db_bo));
546                                 return -EINVAL;
547                         }
548                         ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF);
549                 } else {
550                         size = radeon_bo_size(track->db_bo);
551                         /* pitch in pixels */
552                         pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8;
553                         slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
554                         slice_tile_max *= 64;
555                         height = slice_tile_max / pitch;
556                         if (height > 8192)
557                                 height = 8192;
558                         base_offset = track->db_bo_mc + track->db_offset;
559                         array_mode = G_028010_ARRAY_MODE(track->db_depth_info);
560                         array_check.array_mode = array_mode;
561                         array_check.group_size = track->group_size;
562                         array_check.nbanks = track->nbanks;
563                         array_check.npipes = track->npipes;
564                         array_check.nsamples = track->nsamples;
565                         array_check.blocksize = bpe;
566                         if (r600_get_array_mode_alignment(&array_check,
567                                                           &pitch_align, &height_align, &depth_align, &base_align)) {
568                                 dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
569                                          G_028010_ARRAY_MODE(track->db_depth_info),
570                                          track->db_depth_info);
571                                 return -EINVAL;
572                         }
573                         switch (array_mode) {
574                         case V_028010_ARRAY_1D_TILED_THIN1:
575                                 /* don't break userspace */
576                                 height &= ~0x7;
577                                 break;
578                         case V_028010_ARRAY_2D_TILED_THIN1:
579                                 break;
580                         default:
581                                 dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
582                                          G_028010_ARRAY_MODE(track->db_depth_info),
583                                          track->db_depth_info);
584                                 return -EINVAL;
585                         }
586
587                         if (!IS_ALIGNED(pitch, pitch_align)) {
588                                 dev_warn(p->dev, "%s:%d db pitch (%d, 0x%x, %d) invalid\n",
589                                          __func__, __LINE__, pitch, pitch_align, array_mode);
590                                 return -EINVAL;
591                         }
592                         if (!IS_ALIGNED(height, height_align)) {
593                                 dev_warn(p->dev, "%s:%d db height (%d, 0x%x, %d) invalid\n",
594                                          __func__, __LINE__, height, height_align, array_mode);
595                                 return -EINVAL;
596                         }
597                         if (!IS_ALIGNED(base_offset, base_align)) {
598                                 dev_warn(p->dev, "%s offset[%d] 0x%llx, 0x%llx, %d not aligned\n", __func__, i,
599                                          base_offset, base_align, array_mode);
600                                 return -EINVAL;
601                         }
602
603                         ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
604                         nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1;
605                         tmp = ntiles * bpe * 64 * nviews;
606                         if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) {
607                                 dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n",
608                                          array_mode,
609                                          track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset,
610                                          radeon_bo_size(track->db_bo));
611                                 return -EINVAL;
612                         }
613                 }
614         }
615         return 0;
616 }
617
618 /**
619  * r600_cs_packet_parse() - parse cp packet and point ib index to next packet
620  * @parser:     parser structure holding parsing context.
621  * @pkt:        where to store packet informations
622  *
623  * Assume that chunk_ib_index is properly set. Will return -EINVAL
624  * if packet is bigger than remaining ib size. or if packets is unknown.
625  **/
626 int r600_cs_packet_parse(struct radeon_cs_parser *p,
627                         struct radeon_cs_packet *pkt,
628                         unsigned idx)
629 {
630         struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx];
631         uint32_t header;
632
633         if (idx >= ib_chunk->length_dw) {
634                 DRM_ERROR("Can not parse packet at %d after CS end %d !\n",
635                           idx, ib_chunk->length_dw);
636                 return -EINVAL;
637         }
638         header = radeon_get_ib_value(p, idx);
639         pkt->idx = idx;
640         pkt->type = CP_PACKET_GET_TYPE(header);
641         pkt->count = CP_PACKET_GET_COUNT(header);
642         pkt->one_reg_wr = 0;
643         switch (pkt->type) {
644         case PACKET_TYPE0:
645                 pkt->reg = CP_PACKET0_GET_REG(header);
646                 break;
647         case PACKET_TYPE3:
648                 pkt->opcode = CP_PACKET3_GET_OPCODE(header);
649                 break;
650         case PACKET_TYPE2:
651                 pkt->count = -1;
652                 break;
653         default:
654                 DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx);
655                 return -EINVAL;
656         }
657         if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) {
658                 DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n",
659                           pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw);
660                 return -EINVAL;
661         }
662         return 0;
663 }
664
665 /**
666  * r600_cs_packet_next_reloc_mm() - parse next packet which should be reloc packet3
667  * @parser:             parser structure holding parsing context.
668  * @data:               pointer to relocation data
669  * @offset_start:       starting offset
670  * @offset_mask:        offset mask (to align start offset on)
671  * @reloc:              reloc informations
672  *
673  * Check next packet is relocation packet3, do bo validation and compute
674  * GPU offset using the provided start.
675  **/
676 static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p,
677                                         struct radeon_cs_reloc **cs_reloc)
678 {
679         struct radeon_cs_chunk *relocs_chunk;
680         struct radeon_cs_packet p3reloc;
681         unsigned idx;
682         int r;
683
684         if (p->chunk_relocs_idx == -1) {
685                 DRM_ERROR("No relocation chunk !\n");
686                 return -EINVAL;
687         }
688         *cs_reloc = NULL;
689         relocs_chunk = &p->chunks[p->chunk_relocs_idx];
690         r = r600_cs_packet_parse(p, &p3reloc, p->idx);
691         if (r) {
692                 return r;
693         }
694         p->idx += p3reloc.count + 2;
695         if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
696                 DRM_ERROR("No packet3 for relocation for packet at %d.\n",
697                           p3reloc.idx);
698                 return -EINVAL;
699         }
700         idx = radeon_get_ib_value(p, p3reloc.idx + 1);
701         if (idx >= relocs_chunk->length_dw) {
702                 DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
703                           idx, relocs_chunk->length_dw);
704                 return -EINVAL;
705         }
706         /* FIXME: we assume reloc size is 4 dwords */
707         *cs_reloc = p->relocs_ptr[(idx / 4)];
708         return 0;
709 }
710
711 /**
712  * r600_cs_packet_next_reloc_nomm() - parse next packet which should be reloc packet3
713  * @parser:             parser structure holding parsing context.
714  * @data:               pointer to relocation data
715  * @offset_start:       starting offset
716  * @offset_mask:        offset mask (to align start offset on)
717  * @reloc:              reloc informations
718  *
719  * Check next packet is relocation packet3, do bo validation and compute
720  * GPU offset using the provided start.
721  **/
722 static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p,
723                                         struct radeon_cs_reloc **cs_reloc)
724 {
725         struct radeon_cs_chunk *relocs_chunk;
726         struct radeon_cs_packet p3reloc;
727         unsigned idx;
728         int r;
729
730         if (p->chunk_relocs_idx == -1) {
731                 DRM_ERROR("No relocation chunk !\n");
732                 return -EINVAL;
733         }
734         *cs_reloc = NULL;
735         relocs_chunk = &p->chunks[p->chunk_relocs_idx];
736         r = r600_cs_packet_parse(p, &p3reloc, p->idx);
737         if (r) {
738                 return r;
739         }
740         p->idx += p3reloc.count + 2;
741         if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
742                 DRM_ERROR("No packet3 for relocation for packet at %d.\n",
743                           p3reloc.idx);
744                 return -EINVAL;
745         }
746         idx = radeon_get_ib_value(p, p3reloc.idx + 1);
747         if (idx >= relocs_chunk->length_dw) {
748                 DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
749                           idx, relocs_chunk->length_dw);
750                 return -EINVAL;
751         }
752         *cs_reloc = p->relocs;
753         (*cs_reloc)->lobj.gpu_offset = (u64)relocs_chunk->kdata[idx + 3] << 32;
754         (*cs_reloc)->lobj.gpu_offset |= relocs_chunk->kdata[idx + 0];
755         return 0;
756 }
757
758 /**
759  * r600_cs_packet_next_is_pkt3_nop() - test if next packet is packet3 nop for reloc
760  * @parser:             parser structure holding parsing context.
761  *
762  * Check next packet is relocation packet3, do bo validation and compute
763  * GPU offset using the provided start.
764  **/
765 static int r600_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p)
766 {
767         struct radeon_cs_packet p3reloc;
768         int r;
769
770         r = r600_cs_packet_parse(p, &p3reloc, p->idx);
771         if (r) {
772                 return 0;
773         }
774         if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
775                 return 0;
776         }
777         return 1;
778 }
779
780 /**
781  * r600_cs_packet_next_vline() - parse userspace VLINE packet
782  * @parser:             parser structure holding parsing context.
783  *
784  * Userspace sends a special sequence for VLINE waits.
785  * PACKET0 - VLINE_START_END + value
786  * PACKET3 - WAIT_REG_MEM poll vline status reg
787  * RELOC (P3) - crtc_id in reloc.
788  *
789  * This function parses this and relocates the VLINE START END
790  * and WAIT_REG_MEM packets to the correct crtc.
791  * It also detects a switched off crtc and nulls out the
792  * wait in that case.
793  */
794 static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p)
795 {
796         struct drm_mode_object *obj;
797         struct drm_crtc *crtc;
798         struct radeon_crtc *radeon_crtc;
799         struct radeon_cs_packet p3reloc, wait_reg_mem;
800         int crtc_id;
801         int r;
802         uint32_t header, h_idx, reg, wait_reg_mem_info;
803         volatile uint32_t *ib;
804
805         ib = p->ib->ptr;
806
807         /* parse the WAIT_REG_MEM */
808         r = r600_cs_packet_parse(p, &wait_reg_mem, p->idx);
809         if (r)
810                 return r;
811
812         /* check its a WAIT_REG_MEM */
813         if (wait_reg_mem.type != PACKET_TYPE3 ||
814             wait_reg_mem.opcode != PACKET3_WAIT_REG_MEM) {
815                 DRM_ERROR("vline wait missing WAIT_REG_MEM segment\n");
816                 return -EINVAL;
817         }
818
819         wait_reg_mem_info = radeon_get_ib_value(p, wait_reg_mem.idx + 1);
820         /* bit 4 is reg (0) or mem (1) */
821         if (wait_reg_mem_info & 0x10) {
822                 DRM_ERROR("vline WAIT_REG_MEM waiting on MEM rather than REG\n");
823                 return -EINVAL;
824         }
825         /* waiting for value to be equal */
826         if ((wait_reg_mem_info & 0x7) != 0x3) {
827                 DRM_ERROR("vline WAIT_REG_MEM function not equal\n");
828                 return -EINVAL;
829         }
830         if ((radeon_get_ib_value(p, wait_reg_mem.idx + 2) << 2) != AVIVO_D1MODE_VLINE_STATUS) {
831                 DRM_ERROR("vline WAIT_REG_MEM bad reg\n");
832                 return -EINVAL;
833         }
834
835         if (radeon_get_ib_value(p, wait_reg_mem.idx + 5) != AVIVO_D1MODE_VLINE_STAT) {
836                 DRM_ERROR("vline WAIT_REG_MEM bad bit mask\n");
837                 return -EINVAL;
838         }
839
840         /* jump over the NOP */
841         r = r600_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2);
842         if (r)
843                 return r;
844
845         h_idx = p->idx - 2;
846         p->idx += wait_reg_mem.count + 2;
847         p->idx += p3reloc.count + 2;
848
849         header = radeon_get_ib_value(p, h_idx);
850         crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1);
851         reg = CP_PACKET0_GET_REG(header);
852
853         obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
854         if (!obj) {
855                 DRM_ERROR("cannot find crtc %d\n", crtc_id);
856                 return -EINVAL;
857         }
858         crtc = obj_to_crtc(obj);
859         radeon_crtc = to_radeon_crtc(crtc);
860         crtc_id = radeon_crtc->crtc_id;
861
862         if (!crtc->enabled) {
863                 /* if the CRTC isn't enabled - we need to nop out the WAIT_REG_MEM */
864                 ib[h_idx + 2] = PACKET2(0);
865                 ib[h_idx + 3] = PACKET2(0);
866                 ib[h_idx + 4] = PACKET2(0);
867                 ib[h_idx + 5] = PACKET2(0);
868                 ib[h_idx + 6] = PACKET2(0);
869                 ib[h_idx + 7] = PACKET2(0);
870                 ib[h_idx + 8] = PACKET2(0);
871         } else if (crtc_id == 1) {
872                 switch (reg) {
873                 case AVIVO_D1MODE_VLINE_START_END:
874                         header &= ~R600_CP_PACKET0_REG_MASK;
875                         header |= AVIVO_D2MODE_VLINE_START_END >> 2;
876                         break;
877                 default:
878                         DRM_ERROR("unknown crtc reloc\n");
879                         return -EINVAL;
880                 }
881                 ib[h_idx] = header;
882                 ib[h_idx + 4] = AVIVO_D2MODE_VLINE_STATUS >> 2;
883         }
884
885         return 0;
886 }
887
888 static int r600_packet0_check(struct radeon_cs_parser *p,
889                                 struct radeon_cs_packet *pkt,
890                                 unsigned idx, unsigned reg)
891 {
892         int r;
893
894         switch (reg) {
895         case AVIVO_D1MODE_VLINE_START_END:
896                 r = r600_cs_packet_parse_vline(p);
897                 if (r) {
898                         DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
899                                         idx, reg);
900                         return r;
901                 }
902                 break;
903         default:
904                 printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
905                        reg, idx);
906                 return -EINVAL;
907         }
908         return 0;
909 }
910
911 static int r600_cs_parse_packet0(struct radeon_cs_parser *p,
912                                 struct radeon_cs_packet *pkt)
913 {
914         unsigned reg, i;
915         unsigned idx;
916         int r;
917
918         idx = pkt->idx + 1;
919         reg = pkt->reg;
920         for (i = 0; i <= pkt->count; i++, idx++, reg += 4) {
921                 r = r600_packet0_check(p, pkt, idx, reg);
922                 if (r) {
923                         return r;
924                 }
925         }
926         return 0;
927 }
928
929 /**
930  * r600_cs_check_reg() - check if register is authorized or not
931  * @parser: parser structure holding parsing context
932  * @reg: register we are testing
933  * @idx: index into the cs buffer
934  *
935  * This function will test against r600_reg_safe_bm and return 0
936  * if register is safe. If register is not flag as safe this function
937  * will test it against a list of register needind special handling.
938  */
939 static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
940 {
941         struct r600_cs_track *track = (struct r600_cs_track *)p->track;
942         struct radeon_cs_reloc *reloc;
943         u32 m, i, tmp, *ib;
944         int r;
945
946         i = (reg >> 7);
947         if (i >= ARRAY_SIZE(r600_reg_safe_bm)) {
948                 dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
949                 return -EINVAL;
950         }
951         m = 1 << ((reg >> 2) & 31);
952         if (!(r600_reg_safe_bm[i] & m))
953                 return 0;
954         ib = p->ib->ptr;
955         switch (reg) {
956         /* force following reg to 0 in an attempt to disable out buffer
957          * which will need us to better understand how it works to perform
958          * security check on it (Jerome)
959          */
960         case R_0288A8_SQ_ESGS_RING_ITEMSIZE:
961         case R_008C44_SQ_ESGS_RING_SIZE:
962         case R_0288B0_SQ_ESTMP_RING_ITEMSIZE:
963         case R_008C54_SQ_ESTMP_RING_SIZE:
964         case R_0288C0_SQ_FBUF_RING_ITEMSIZE:
965         case R_008C74_SQ_FBUF_RING_SIZE:
966         case R_0288B4_SQ_GSTMP_RING_ITEMSIZE:
967         case R_008C5C_SQ_GSTMP_RING_SIZE:
968         case R_0288AC_SQ_GSVS_RING_ITEMSIZE:
969         case R_008C4C_SQ_GSVS_RING_SIZE:
970         case R_0288BC_SQ_PSTMP_RING_ITEMSIZE:
971         case R_008C6C_SQ_PSTMP_RING_SIZE:
972         case R_0288C4_SQ_REDUC_RING_ITEMSIZE:
973         case R_008C7C_SQ_REDUC_RING_SIZE:
974         case R_0288B8_SQ_VSTMP_RING_ITEMSIZE:
975         case R_008C64_SQ_VSTMP_RING_SIZE:
976         case R_0288C8_SQ_GS_VERT_ITEMSIZE:
977                 /* get value to populate the IB don't remove */
978                 tmp =radeon_get_ib_value(p, idx);
979                 ib[idx] = 0;
980                 break;
981         case SQ_CONFIG:
982                 track->sq_config = radeon_get_ib_value(p, idx);
983                 break;
984         case R_028800_DB_DEPTH_CONTROL:
985                 track->db_depth_control = radeon_get_ib_value(p, idx);
986                 break;
987         case R_028010_DB_DEPTH_INFO:
988                 if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS) &&
989                     r600_cs_packet_next_is_pkt3_nop(p)) {
990                         r = r600_cs_packet_next_reloc(p, &reloc);
991                         if (r) {
992                                 dev_warn(p->dev, "bad SET_CONTEXT_REG "
993                                          "0x%04X\n", reg);
994                                 return -EINVAL;
995                         }
996                         track->db_depth_info = radeon_get_ib_value(p, idx);
997                         ib[idx] &= C_028010_ARRAY_MODE;
998                         track->db_depth_info &= C_028010_ARRAY_MODE;
999                         if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
1000                                 ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1);
1001                                 track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1);
1002                         } else {
1003                                 ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1);
1004                                 track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1);
1005                         }
1006                 } else
1007                         track->db_depth_info = radeon_get_ib_value(p, idx);
1008                 break;
1009         case R_028004_DB_DEPTH_VIEW:
1010                 track->db_depth_view = radeon_get_ib_value(p, idx);
1011                 break;
1012         case R_028000_DB_DEPTH_SIZE:
1013                 track->db_depth_size = radeon_get_ib_value(p, idx);
1014                 track->db_depth_size_idx = idx;
1015                 break;
1016         case R_028AB0_VGT_STRMOUT_EN:
1017                 track->vgt_strmout_en = radeon_get_ib_value(p, idx);
1018                 break;
1019         case R_028B20_VGT_STRMOUT_BUFFER_EN:
1020                 track->vgt_strmout_buffer_en = radeon_get_ib_value(p, idx);
1021                 break;
1022         case VGT_STRMOUT_BUFFER_BASE_0:
1023         case VGT_STRMOUT_BUFFER_BASE_1:
1024         case VGT_STRMOUT_BUFFER_BASE_2:
1025         case VGT_STRMOUT_BUFFER_BASE_3:
1026                 r = r600_cs_packet_next_reloc(p, &reloc);
1027                 if (r) {
1028                         dev_warn(p->dev, "bad SET_CONTEXT_REG "
1029                                         "0x%04X\n", reg);
1030                         return -EINVAL;
1031                 }
1032                 tmp = (reg - VGT_STRMOUT_BUFFER_BASE_0) / 16;
1033                 track->vgt_strmout_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8;
1034                 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1035                 track->vgt_strmout_bo[tmp] = reloc->robj;
1036                 track->vgt_strmout_bo_mc[tmp] = reloc->lobj.gpu_offset;
1037                 break;
1038         case VGT_STRMOUT_BUFFER_SIZE_0:
1039         case VGT_STRMOUT_BUFFER_SIZE_1:
1040         case VGT_STRMOUT_BUFFER_SIZE_2:
1041         case VGT_STRMOUT_BUFFER_SIZE_3:
1042                 tmp = (reg - VGT_STRMOUT_BUFFER_SIZE_0) / 16;
1043                 /* size in register is DWs, convert to bytes */
1044                 track->vgt_strmout_size[tmp] = radeon_get_ib_value(p, idx) * 4;
1045                 break;
1046         case CP_COHER_BASE:
1047                 r = r600_cs_packet_next_reloc(p, &reloc);
1048                 if (r) {
1049                         dev_warn(p->dev, "missing reloc for CP_COHER_BASE "
1050                                         "0x%04X\n", reg);
1051                         return -EINVAL;
1052                 }
1053                 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1054                 break;
1055         case R_028238_CB_TARGET_MASK:
1056                 track->cb_target_mask = radeon_get_ib_value(p, idx);
1057                 break;
1058         case R_02823C_CB_SHADER_MASK:
1059                 track->cb_shader_mask = radeon_get_ib_value(p, idx);
1060                 break;
1061         case R_028C04_PA_SC_AA_CONFIG:
1062                 tmp = G_028C04_MSAA_NUM_SAMPLES(radeon_get_ib_value(p, idx));
1063                 track->nsamples = 1 << tmp;
1064                 break;
1065         case R_0280A0_CB_COLOR0_INFO:
1066         case R_0280A4_CB_COLOR1_INFO:
1067         case R_0280A8_CB_COLOR2_INFO:
1068         case R_0280AC_CB_COLOR3_INFO:
1069         case R_0280B0_CB_COLOR4_INFO:
1070         case R_0280B4_CB_COLOR5_INFO:
1071         case R_0280B8_CB_COLOR6_INFO:
1072         case R_0280BC_CB_COLOR7_INFO:
1073                 if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS) &&
1074                      r600_cs_packet_next_is_pkt3_nop(p)) {
1075                         r = r600_cs_packet_next_reloc(p, &reloc);
1076                         if (r) {
1077                                 dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
1078                                 return -EINVAL;
1079                         }
1080                         tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4;
1081                         track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
1082                         if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
1083                                 ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1);
1084                                 track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1);
1085                         } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
1086                                 ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1);
1087                                 track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1);
1088                         }
1089                 } else {
1090                         tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4;
1091                         track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
1092                 }
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;
1105         case R_028060_CB_COLOR0_SIZE:
1106         case R_028064_CB_COLOR1_SIZE:
1107         case R_028068_CB_COLOR2_SIZE:
1108         case R_02806C_CB_COLOR3_SIZE:
1109         case R_028070_CB_COLOR4_SIZE:
1110         case R_028074_CB_COLOR5_SIZE:
1111         case R_028078_CB_COLOR6_SIZE:
1112         case R_02807C_CB_COLOR7_SIZE:
1113                 tmp = (reg - R_028060_CB_COLOR0_SIZE) / 4;
1114                 track->cb_color_size[tmp] = radeon_get_ib_value(p, idx);
1115                 track->cb_color_size_idx[tmp] = idx;
1116                 break;
1117                 /* This register were added late, there is userspace
1118                  * which does provide relocation for those but set
1119                  * 0 offset. In order to avoid breaking old userspace
1120                  * we detect this and set address to point to last
1121                  * CB_COLOR0_BASE, note that if userspace doesn't set
1122                  * CB_COLOR0_BASE before this register we will report
1123                  * error. Old userspace always set CB_COLOR0_BASE
1124                  * before any of this.
1125                  */
1126         case R_0280E0_CB_COLOR0_FRAG:
1127         case R_0280E4_CB_COLOR1_FRAG:
1128         case R_0280E8_CB_COLOR2_FRAG:
1129         case R_0280EC_CB_COLOR3_FRAG:
1130         case R_0280F0_CB_COLOR4_FRAG:
1131         case R_0280F4_CB_COLOR5_FRAG:
1132         case R_0280F8_CB_COLOR6_FRAG:
1133         case R_0280FC_CB_COLOR7_FRAG:
1134                 tmp = (reg - R_0280E0_CB_COLOR0_FRAG) / 4;
1135                 if (!r600_cs_packet_next_is_pkt3_nop(p)) {
1136                         if (!track->cb_color_base_last[tmp]) {
1137                                 dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg);
1138                                 return -EINVAL;
1139                         }
1140                         ib[idx] = track->cb_color_base_last[tmp];
1141                         track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp];
1142                 } else {
1143                         r = r600_cs_packet_next_reloc(p, &reloc);
1144                         if (r) {
1145                                 dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
1146                                 return -EINVAL;
1147                         }
1148                         ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1149                         track->cb_color_frag_bo[tmp] = reloc->robj;
1150                 }
1151                 break;
1152         case R_0280C0_CB_COLOR0_TILE:
1153         case R_0280C4_CB_COLOR1_TILE:
1154         case R_0280C8_CB_COLOR2_TILE:
1155         case R_0280CC_CB_COLOR3_TILE:
1156         case R_0280D0_CB_COLOR4_TILE:
1157         case R_0280D4_CB_COLOR5_TILE:
1158         case R_0280D8_CB_COLOR6_TILE:
1159         case R_0280DC_CB_COLOR7_TILE:
1160                 tmp = (reg - R_0280C0_CB_COLOR0_TILE) / 4;
1161                 if (!r600_cs_packet_next_is_pkt3_nop(p)) {
1162                         if (!track->cb_color_base_last[tmp]) {
1163                                 dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg);
1164                                 return -EINVAL;
1165                         }
1166                         ib[idx] = track->cb_color_base_last[tmp];
1167                         track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp];
1168                 } else {
1169                         r = r600_cs_packet_next_reloc(p, &reloc);
1170                         if (r) {
1171                                 dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
1172                                 return -EINVAL;
1173                         }
1174                         ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1175                         track->cb_color_tile_bo[tmp] = reloc->robj;
1176                 }
1177                 break;
1178         case CB_COLOR0_BASE:
1179         case CB_COLOR1_BASE:
1180         case CB_COLOR2_BASE:
1181         case CB_COLOR3_BASE:
1182         case CB_COLOR4_BASE:
1183         case CB_COLOR5_BASE:
1184         case CB_COLOR6_BASE:
1185         case CB_COLOR7_BASE:
1186                 r = r600_cs_packet_next_reloc(p, &reloc);
1187                 if (r) {
1188                         dev_warn(p->dev, "bad SET_CONTEXT_REG "
1189                                         "0x%04X\n", reg);
1190                         return -EINVAL;
1191                 }
1192                 tmp = (reg - CB_COLOR0_BASE) / 4;
1193                 track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8;
1194                 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1195                 track->cb_color_base_last[tmp] = ib[idx];
1196                 track->cb_color_bo[tmp] = reloc->robj;
1197                 track->cb_color_bo_mc[tmp] = reloc->lobj.gpu_offset;
1198                 break;
1199         case DB_DEPTH_BASE:
1200                 r = r600_cs_packet_next_reloc(p, &reloc);
1201                 if (r) {
1202                         dev_warn(p->dev, "bad SET_CONTEXT_REG "
1203                                         "0x%04X\n", reg);
1204                         return -EINVAL;
1205                 }
1206                 track->db_offset = radeon_get_ib_value(p, idx) << 8;
1207                 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1208                 track->db_bo = reloc->robj;
1209                 track->db_bo_mc = reloc->lobj.gpu_offset;
1210                 break;
1211         case DB_HTILE_DATA_BASE:
1212         case SQ_PGM_START_FS:
1213         case SQ_PGM_START_ES:
1214         case SQ_PGM_START_VS:
1215         case SQ_PGM_START_GS:
1216         case SQ_PGM_START_PS:
1217         case SQ_ALU_CONST_CACHE_GS_0:
1218         case SQ_ALU_CONST_CACHE_GS_1:
1219         case SQ_ALU_CONST_CACHE_GS_2:
1220         case SQ_ALU_CONST_CACHE_GS_3:
1221         case SQ_ALU_CONST_CACHE_GS_4:
1222         case SQ_ALU_CONST_CACHE_GS_5:
1223         case SQ_ALU_CONST_CACHE_GS_6:
1224         case SQ_ALU_CONST_CACHE_GS_7:
1225         case SQ_ALU_CONST_CACHE_GS_8:
1226         case SQ_ALU_CONST_CACHE_GS_9:
1227         case SQ_ALU_CONST_CACHE_GS_10:
1228         case SQ_ALU_CONST_CACHE_GS_11:
1229         case SQ_ALU_CONST_CACHE_GS_12:
1230         case SQ_ALU_CONST_CACHE_GS_13:
1231         case SQ_ALU_CONST_CACHE_GS_14:
1232         case SQ_ALU_CONST_CACHE_GS_15:
1233         case SQ_ALU_CONST_CACHE_PS_0:
1234         case SQ_ALU_CONST_CACHE_PS_1:
1235         case SQ_ALU_CONST_CACHE_PS_2:
1236         case SQ_ALU_CONST_CACHE_PS_3:
1237         case SQ_ALU_CONST_CACHE_PS_4:
1238         case SQ_ALU_CONST_CACHE_PS_5:
1239         case SQ_ALU_CONST_CACHE_PS_6:
1240         case SQ_ALU_CONST_CACHE_PS_7:
1241         case SQ_ALU_CONST_CACHE_PS_8:
1242         case SQ_ALU_CONST_CACHE_PS_9:
1243         case SQ_ALU_CONST_CACHE_PS_10:
1244         case SQ_ALU_CONST_CACHE_PS_11:
1245         case SQ_ALU_CONST_CACHE_PS_12:
1246         case SQ_ALU_CONST_CACHE_PS_13:
1247         case SQ_ALU_CONST_CACHE_PS_14:
1248         case SQ_ALU_CONST_CACHE_PS_15:
1249         case SQ_ALU_CONST_CACHE_VS_0:
1250         case SQ_ALU_CONST_CACHE_VS_1:
1251         case SQ_ALU_CONST_CACHE_VS_2:
1252         case SQ_ALU_CONST_CACHE_VS_3:
1253         case SQ_ALU_CONST_CACHE_VS_4:
1254         case SQ_ALU_CONST_CACHE_VS_5:
1255         case SQ_ALU_CONST_CACHE_VS_6:
1256         case SQ_ALU_CONST_CACHE_VS_7:
1257         case SQ_ALU_CONST_CACHE_VS_8:
1258         case SQ_ALU_CONST_CACHE_VS_9:
1259         case SQ_ALU_CONST_CACHE_VS_10:
1260         case SQ_ALU_CONST_CACHE_VS_11:
1261         case SQ_ALU_CONST_CACHE_VS_12:
1262         case SQ_ALU_CONST_CACHE_VS_13:
1263         case SQ_ALU_CONST_CACHE_VS_14:
1264         case SQ_ALU_CONST_CACHE_VS_15:
1265                 r = r600_cs_packet_next_reloc(p, &reloc);
1266                 if (r) {
1267                         dev_warn(p->dev, "bad SET_CONTEXT_REG "
1268                                         "0x%04X\n", reg);
1269                         return -EINVAL;
1270                 }
1271                 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1272                 break;
1273         case SX_MEMORY_EXPORT_BASE:
1274                 r = r600_cs_packet_next_reloc(p, &reloc);
1275                 if (r) {
1276                         dev_warn(p->dev, "bad SET_CONFIG_REG "
1277                                         "0x%04X\n", reg);
1278                         return -EINVAL;
1279                 }
1280                 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1281                 break;
1282         default:
1283                 dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
1284                 return -EINVAL;
1285         }
1286         return 0;
1287 }
1288
1289 unsigned r600_mip_minify(unsigned size, unsigned level)
1290 {
1291         unsigned val;
1292
1293         val = max(1U, size >> level);
1294         if (level > 0)
1295                 val = roundup_pow_of_two(val);
1296         return val;
1297 }
1298
1299 static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel,
1300                               unsigned w0, unsigned h0, unsigned d0, unsigned format,
1301                               unsigned block_align, unsigned height_align, unsigned base_align,
1302                               unsigned *l0_size, unsigned *mipmap_size)
1303 {
1304         unsigned offset, i, level;
1305         unsigned width, height, depth, size;
1306         unsigned blocksize;
1307         unsigned nbx, nby;
1308         unsigned nlevels = llevel - blevel + 1;
1309
1310         *l0_size = -1;
1311         blocksize = r600_fmt_get_blocksize(format);
1312
1313         w0 = r600_mip_minify(w0, 0);
1314         h0 = r600_mip_minify(h0, 0);
1315         d0 = r600_mip_minify(d0, 0);
1316         for(i = 0, offset = 0, level = blevel; i < nlevels; i++, level++) {
1317                 width = r600_mip_minify(w0, i);
1318                 nbx = r600_fmt_get_nblocksx(format, width);
1319
1320                 nbx = round_up(nbx, block_align);
1321
1322                 height = r600_mip_minify(h0, i);
1323                 nby = r600_fmt_get_nblocksy(format, height);
1324                 nby = round_up(nby, height_align);
1325
1326                 depth = r600_mip_minify(d0, i);
1327
1328                 size = nbx * nby * blocksize;
1329                 if (nfaces)
1330                         size *= nfaces;
1331                 else
1332                         size *= depth;
1333
1334                 if (i == 0)
1335                         *l0_size = size;
1336
1337                 if (i == 0 || i == 1)
1338                         offset = round_up(offset, base_align);
1339
1340                 offset += size;
1341         }
1342         *mipmap_size = offset;
1343         if (llevel == 0)
1344                 *mipmap_size = *l0_size;
1345         if (!blevel)
1346                 *mipmap_size -= *l0_size;
1347 }
1348
1349 /**
1350  * r600_check_texture_resource() - check if register is authorized or not
1351  * @p: parser structure holding parsing context
1352  * @idx: index into the cs buffer
1353  * @texture: texture's bo structure
1354  * @mipmap: mipmap's bo structure
1355  *
1356  * This function will check that the resource has valid field and that
1357  * the texture and mipmap bo object are big enough to cover this resource.
1358  */
1359 static int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
1360                                               struct radeon_bo *texture,
1361                                               struct radeon_bo *mipmap,
1362                                               u64 base_offset,
1363                                               u64 mip_offset,
1364                                               u32 tiling_flags)
1365 {
1366         struct r600_cs_track *track = p->track;
1367         u32 nfaces, llevel, blevel, w0, h0, d0;
1368         u32 word0, word1, l0_size, mipmap_size, word2, word3;
1369         u32 height_align, pitch, pitch_align, depth_align;
1370         u32 array, barray, larray;
1371         u64 base_align;
1372         struct array_mode_checker array_check;
1373         u32 format;
1374
1375         /* on legacy kernel we don't perform advanced check */
1376         if (p->rdev == NULL)
1377                 return 0;
1378
1379         /* convert to bytes */
1380         base_offset <<= 8;
1381         mip_offset <<= 8;
1382
1383         word0 = radeon_get_ib_value(p, idx + 0);
1384         if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
1385                 if (tiling_flags & RADEON_TILING_MACRO)
1386                         word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
1387                 else if (tiling_flags & RADEON_TILING_MICRO)
1388                         word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
1389         }
1390         word1 = radeon_get_ib_value(p, idx + 1);
1391         w0 = G_038000_TEX_WIDTH(word0) + 1;
1392         h0 = G_038004_TEX_HEIGHT(word1) + 1;
1393         d0 = G_038004_TEX_DEPTH(word1);
1394         nfaces = 1;
1395         array = 0;
1396         switch (G_038000_DIM(word0)) {
1397         case V_038000_SQ_TEX_DIM_1D:
1398         case V_038000_SQ_TEX_DIM_2D:
1399         case V_038000_SQ_TEX_DIM_3D:
1400                 break;
1401         case V_038000_SQ_TEX_DIM_CUBEMAP:
1402                 if (p->family >= CHIP_RV770)
1403                         nfaces = 8;
1404                 else
1405                         nfaces = 6;
1406                 break;
1407         case V_038000_SQ_TEX_DIM_1D_ARRAY:
1408         case V_038000_SQ_TEX_DIM_2D_ARRAY:
1409                 array = 1;
1410                 break;
1411         case V_038000_SQ_TEX_DIM_2D_MSAA:
1412         case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA:
1413         default:
1414                 dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0));
1415                 return -EINVAL;
1416         }
1417         format = G_038004_DATA_FORMAT(word1);
1418         if (!r600_fmt_is_valid_texture(format, p->family)) {
1419                 dev_warn(p->dev, "%s:%d texture invalid format %d\n",
1420                          __func__, __LINE__, format);
1421                 return -EINVAL;
1422         }
1423
1424         /* pitch in texels */
1425         pitch = (G_038000_PITCH(word0) + 1) * 8;
1426         array_check.array_mode = G_038000_TILE_MODE(word0);
1427         array_check.group_size = track->group_size;
1428         array_check.nbanks = track->nbanks;
1429         array_check.npipes = track->npipes;
1430         array_check.nsamples = 1;
1431         array_check.blocksize = r600_fmt_get_blocksize(format);
1432         if (r600_get_array_mode_alignment(&array_check,
1433                                           &pitch_align, &height_align, &depth_align, &base_align)) {
1434                 dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n",
1435                          __func__, __LINE__, G_038000_TILE_MODE(word0));
1436                 return -EINVAL;
1437         }
1438
1439         /* XXX check height as well... */
1440
1441         if (!IS_ALIGNED(pitch, pitch_align)) {
1442                 dev_warn(p->dev, "%s:%d tex pitch (%d, 0x%x, %d) invalid\n",
1443                          __func__, __LINE__, pitch, pitch_align, G_038000_TILE_MODE(word0));
1444                 return -EINVAL;
1445         }
1446         if (!IS_ALIGNED(base_offset, base_align)) {
1447                 dev_warn(p->dev, "%s:%d tex base offset (0x%llx, 0x%llx, %d) invalid\n",
1448                          __func__, __LINE__, base_offset, base_align, G_038000_TILE_MODE(word0));
1449                 return -EINVAL;
1450         }
1451         if (!IS_ALIGNED(mip_offset, base_align)) {
1452                 dev_warn(p->dev, "%s:%d tex mip offset (0x%llx, 0x%llx, %d) invalid\n",
1453                          __func__, __LINE__, mip_offset, base_align, G_038000_TILE_MODE(word0));
1454                 return -EINVAL;
1455         }
1456
1457         word2 = radeon_get_ib_value(p, idx + 2) << 8;
1458         word3 = radeon_get_ib_value(p, idx + 3) << 8;
1459
1460         word0 = radeon_get_ib_value(p, idx + 4);
1461         word1 = radeon_get_ib_value(p, idx + 5);
1462         blevel = G_038010_BASE_LEVEL(word0);
1463         llevel = G_038014_LAST_LEVEL(word1);
1464         if (blevel > llevel) {
1465                 dev_warn(p->dev, "texture blevel %d > llevel %d\n",
1466                          blevel, llevel);
1467         }
1468         if (array == 1) {
1469                 barray = G_038014_BASE_ARRAY(word1);
1470                 larray = G_038014_LAST_ARRAY(word1);
1471
1472                 nfaces = larray - barray + 1;
1473         }
1474         r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, format,
1475                           pitch_align, height_align, base_align,
1476                           &l0_size, &mipmap_size);
1477         /* using get ib will give us the offset into the texture bo */
1478         if ((l0_size + word2) > radeon_bo_size(texture)) {
1479                 dev_warn(p->dev, "texture bo too small ((%d %d) (%d %d) %d %d %d -> %d have %ld)\n",
1480                          w0, h0, pitch_align, height_align,
1481                          array_check.array_mode, format, word2,
1482                          l0_size, radeon_bo_size(texture));
1483                 dev_warn(p->dev, "alignments %d %d %d %lld\n", pitch, pitch_align, height_align, base_align);
1484                 return -EINVAL;
1485         }
1486         /* using get ib will give us the offset into the mipmap bo */
1487         word3 = radeon_get_ib_value(p, idx + 3) << 8;
1488         if ((mipmap_size + word3) > radeon_bo_size(mipmap)) {
1489                 /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n",
1490                   w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/
1491         }
1492         return 0;
1493 }
1494
1495 static bool r600_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
1496 {
1497         u32 m, i;
1498
1499         i = (reg >> 7);
1500         if (i >= ARRAY_SIZE(r600_reg_safe_bm)) {
1501                 dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
1502                 return false;
1503         }
1504         m = 1 << ((reg >> 2) & 31);
1505         if (!(r600_reg_safe_bm[i] & m))
1506                 return true;
1507         dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
1508         return false;
1509 }
1510
1511 static int r600_packet3_check(struct radeon_cs_parser *p,
1512                                 struct radeon_cs_packet *pkt)
1513 {
1514         struct radeon_cs_reloc *reloc;
1515         struct r600_cs_track *track;
1516         volatile u32 *ib;
1517         unsigned idx;
1518         unsigned i;
1519         unsigned start_reg, end_reg, reg;
1520         int r;
1521         u32 idx_value;
1522
1523         track = (struct r600_cs_track *)p->track;
1524         ib = p->ib->ptr;
1525         idx = pkt->idx + 1;
1526         idx_value = radeon_get_ib_value(p, idx);
1527
1528         switch (pkt->opcode) {
1529         case PACKET3_SET_PREDICATION:
1530         {
1531                 int pred_op;
1532                 int tmp;
1533                 if (pkt->count != 1) {
1534                         DRM_ERROR("bad SET PREDICATION\n");
1535                         return -EINVAL;
1536                 }
1537
1538                 tmp = radeon_get_ib_value(p, idx + 1);
1539                 pred_op = (tmp >> 16) & 0x7;
1540
1541                 /* for the clear predicate operation */
1542                 if (pred_op == 0)
1543                         return 0;
1544
1545                 if (pred_op > 2) {
1546                         DRM_ERROR("bad SET PREDICATION operation %d\n", pred_op);
1547                         return -EINVAL;
1548                 }
1549
1550                 r = r600_cs_packet_next_reloc(p, &reloc);
1551                 if (r) {
1552                         DRM_ERROR("bad SET PREDICATION\n");
1553                         return -EINVAL;
1554                 }
1555
1556                 ib[idx + 0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1557                 ib[idx + 1] = tmp + (upper_32_bits(reloc->lobj.gpu_offset) & 0xff);
1558         }
1559         break;
1560
1561         case PACKET3_START_3D_CMDBUF:
1562                 if (p->family >= CHIP_RV770 || pkt->count) {
1563                         DRM_ERROR("bad START_3D\n");
1564                         return -EINVAL;
1565                 }
1566                 break;
1567         case PACKET3_CONTEXT_CONTROL:
1568                 if (pkt->count != 1) {
1569                         DRM_ERROR("bad CONTEXT_CONTROL\n");
1570                         return -EINVAL;
1571                 }
1572                 break;
1573         case PACKET3_INDEX_TYPE:
1574         case PACKET3_NUM_INSTANCES:
1575                 if (pkt->count) {
1576                         DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES\n");
1577                         return -EINVAL;
1578                 }
1579                 break;
1580         case PACKET3_DRAW_INDEX:
1581                 if (pkt->count != 3) {
1582                         DRM_ERROR("bad DRAW_INDEX\n");
1583                         return -EINVAL;
1584                 }
1585                 r = r600_cs_packet_next_reloc(p, &reloc);
1586                 if (r) {
1587                         DRM_ERROR("bad DRAW_INDEX\n");
1588                         return -EINVAL;
1589                 }
1590                 ib[idx+0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1591                 ib[idx+1] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1592                 r = r600_cs_track_check(p);
1593                 if (r) {
1594                         dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1595                         return r;
1596                 }
1597                 break;
1598         case PACKET3_DRAW_INDEX_AUTO:
1599                 if (pkt->count != 1) {
1600                         DRM_ERROR("bad DRAW_INDEX_AUTO\n");
1601                         return -EINVAL;
1602                 }
1603                 r = r600_cs_track_check(p);
1604                 if (r) {
1605                         dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx);
1606                         return r;
1607                 }
1608                 break;
1609         case PACKET3_DRAW_INDEX_IMMD_BE:
1610         case PACKET3_DRAW_INDEX_IMMD:
1611                 if (pkt->count < 2) {
1612                         DRM_ERROR("bad DRAW_INDEX_IMMD\n");
1613                         return -EINVAL;
1614                 }
1615                 r = r600_cs_track_check(p);
1616                 if (r) {
1617                         dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1618                         return r;
1619                 }
1620                 break;
1621         case PACKET3_WAIT_REG_MEM:
1622                 if (pkt->count != 5) {
1623                         DRM_ERROR("bad WAIT_REG_MEM\n");
1624                         return -EINVAL;
1625                 }
1626                 /* bit 4 is reg (0) or mem (1) */
1627                 if (idx_value & 0x10) {
1628                         r = r600_cs_packet_next_reloc(p, &reloc);
1629                         if (r) {
1630                                 DRM_ERROR("bad WAIT_REG_MEM\n");
1631                                 return -EINVAL;
1632                         }
1633                         ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1634                         ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1635                 }
1636                 break;
1637         case PACKET3_SURFACE_SYNC:
1638                 if (pkt->count != 3) {
1639                         DRM_ERROR("bad SURFACE_SYNC\n");
1640                         return -EINVAL;
1641                 }
1642                 /* 0xffffffff/0x0 is flush all cache flag */
1643                 if (radeon_get_ib_value(p, idx + 1) != 0xffffffff ||
1644                     radeon_get_ib_value(p, idx + 2) != 0) {
1645                         r = r600_cs_packet_next_reloc(p, &reloc);
1646                         if (r) {
1647                                 DRM_ERROR("bad SURFACE_SYNC\n");
1648                                 return -EINVAL;
1649                         }
1650                         ib[idx+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1651                 }
1652                 break;
1653         case PACKET3_EVENT_WRITE:
1654                 if (pkt->count != 2 && pkt->count != 0) {
1655                         DRM_ERROR("bad EVENT_WRITE\n");
1656                         return -EINVAL;
1657                 }
1658                 if (pkt->count) {
1659                         r = r600_cs_packet_next_reloc(p, &reloc);
1660                         if (r) {
1661                                 DRM_ERROR("bad EVENT_WRITE\n");
1662                                 return -EINVAL;
1663                         }
1664                         ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1665                         ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1666                 }
1667                 break;
1668         case PACKET3_EVENT_WRITE_EOP:
1669                 if (pkt->count != 4) {
1670                         DRM_ERROR("bad EVENT_WRITE_EOP\n");
1671                         return -EINVAL;
1672                 }
1673                 r = r600_cs_packet_next_reloc(p, &reloc);
1674                 if (r) {
1675                         DRM_ERROR("bad EVENT_WRITE\n");
1676                         return -EINVAL;
1677                 }
1678                 ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1679                 ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1680                 break;
1681         case PACKET3_SET_CONFIG_REG:
1682                 start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_OFFSET;
1683                 end_reg = 4 * pkt->count + start_reg - 4;
1684                 if ((start_reg < PACKET3_SET_CONFIG_REG_OFFSET) ||
1685                     (start_reg >= PACKET3_SET_CONFIG_REG_END) ||
1686                     (end_reg >= PACKET3_SET_CONFIG_REG_END)) {
1687                         DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
1688                         return -EINVAL;
1689                 }
1690                 for (i = 0; i < pkt->count; i++) {
1691                         reg = start_reg + (4 * i);
1692                         r = r600_cs_check_reg(p, reg, idx+1+i);
1693                         if (r)
1694                                 return r;
1695                 }
1696                 break;
1697         case PACKET3_SET_CONTEXT_REG:
1698                 start_reg = (idx_value << 2) + PACKET3_SET_CONTEXT_REG_OFFSET;
1699                 end_reg = 4 * pkt->count + start_reg - 4;
1700                 if ((start_reg < PACKET3_SET_CONTEXT_REG_OFFSET) ||
1701                     (start_reg >= PACKET3_SET_CONTEXT_REG_END) ||
1702                     (end_reg >= PACKET3_SET_CONTEXT_REG_END)) {
1703                         DRM_ERROR("bad PACKET3_SET_CONTEXT_REG\n");
1704                         return -EINVAL;
1705                 }
1706                 for (i = 0; i < pkt->count; i++) {
1707                         reg = start_reg + (4 * i);
1708                         r = r600_cs_check_reg(p, reg, idx+1+i);
1709                         if (r)
1710                                 return r;
1711                 }
1712                 break;
1713         case PACKET3_SET_RESOURCE:
1714                 if (pkt->count % 7) {
1715                         DRM_ERROR("bad SET_RESOURCE\n");
1716                         return -EINVAL;
1717                 }
1718                 start_reg = (idx_value << 2) + PACKET3_SET_RESOURCE_OFFSET;
1719                 end_reg = 4 * pkt->count + start_reg - 4;
1720                 if ((start_reg < PACKET3_SET_RESOURCE_OFFSET) ||
1721                     (start_reg >= PACKET3_SET_RESOURCE_END) ||
1722                     (end_reg >= PACKET3_SET_RESOURCE_END)) {
1723                         DRM_ERROR("bad SET_RESOURCE\n");
1724                         return -EINVAL;
1725                 }
1726                 for (i = 0; i < (pkt->count / 7); i++) {
1727                         struct radeon_bo *texture, *mipmap;
1728                         u32 size, offset, base_offset, mip_offset;
1729
1730                         switch (G__SQ_VTX_CONSTANT_TYPE(radeon_get_ib_value(p, idx+(i*7)+6+1))) {
1731                         case SQ_TEX_VTX_VALID_TEXTURE:
1732                                 /* tex base */
1733                                 r = r600_cs_packet_next_reloc(p, &reloc);
1734                                 if (r) {
1735                                         DRM_ERROR("bad SET_RESOURCE\n");
1736                                         return -EINVAL;
1737                                 }
1738                                 base_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1739                                 if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
1740                                         if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
1741                                                 ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
1742                                         else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
1743                                                 ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
1744                                 }
1745                                 texture = reloc->robj;
1746                                 /* tex mip base */
1747                                 r = r600_cs_packet_next_reloc(p, &reloc);
1748                                 if (r) {
1749                                         DRM_ERROR("bad SET_RESOURCE\n");
1750                                         return -EINVAL;
1751                                 }
1752                                 mip_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1753                                 mipmap = reloc->robj;
1754                                 r = r600_check_texture_resource(p,  idx+(i*7)+1,
1755                                                                 texture, mipmap,
1756                                                                 base_offset + radeon_get_ib_value(p, idx+1+(i*7)+2),
1757                                                                 mip_offset + radeon_get_ib_value(p, idx+1+(i*7)+3),
1758                                                                 reloc->lobj.tiling_flags);
1759                                 if (r)
1760                                         return r;
1761                                 ib[idx+1+(i*7)+2] += base_offset;
1762                                 ib[idx+1+(i*7)+3] += mip_offset;
1763                                 break;
1764                         case SQ_TEX_VTX_VALID_BUFFER:
1765                                 /* vtx base */
1766                                 r = r600_cs_packet_next_reloc(p, &reloc);
1767                                 if (r) {
1768                                         DRM_ERROR("bad SET_RESOURCE\n");
1769                                         return -EINVAL;
1770                                 }
1771                                 offset = radeon_get_ib_value(p, idx+1+(i*7)+0);
1772                                 size = radeon_get_ib_value(p, idx+1+(i*7)+1) + 1;
1773                                 if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) {
1774                                         /* force size to size of the buffer */
1775                                         dev_warn(p->dev, "vbo resource seems too big (%d) for the bo (%ld)\n",
1776                                                  size + offset, radeon_bo_size(reloc->robj));
1777                                         ib[idx+1+(i*7)+1] = radeon_bo_size(reloc->robj);
1778                                 }
1779                                 ib[idx+1+(i*7)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff);
1780                                 ib[idx+1+(i*7)+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1781                                 break;
1782                         case SQ_TEX_VTX_INVALID_TEXTURE:
1783                         case SQ_TEX_VTX_INVALID_BUFFER:
1784                         default:
1785                                 DRM_ERROR("bad SET_RESOURCE\n");
1786                                 return -EINVAL;
1787                         }
1788                 }
1789                 break;
1790         case PACKET3_SET_ALU_CONST:
1791                 if (track->sq_config & DX9_CONSTS) {
1792                         start_reg = (idx_value << 2) + PACKET3_SET_ALU_CONST_OFFSET;
1793                         end_reg = 4 * pkt->count + start_reg - 4;
1794                         if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) ||
1795                             (start_reg >= PACKET3_SET_ALU_CONST_END) ||
1796                             (end_reg >= PACKET3_SET_ALU_CONST_END)) {
1797                                 DRM_ERROR("bad SET_ALU_CONST\n");
1798                                 return -EINVAL;
1799                         }
1800                 }
1801                 break;
1802         case PACKET3_SET_BOOL_CONST:
1803                 start_reg = (idx_value << 2) + PACKET3_SET_BOOL_CONST_OFFSET;
1804                 end_reg = 4 * pkt->count + start_reg - 4;
1805                 if ((start_reg < PACKET3_SET_BOOL_CONST_OFFSET) ||
1806                     (start_reg >= PACKET3_SET_BOOL_CONST_END) ||
1807                     (end_reg >= PACKET3_SET_BOOL_CONST_END)) {
1808                         DRM_ERROR("bad SET_BOOL_CONST\n");
1809                         return -EINVAL;
1810                 }
1811                 break;
1812         case PACKET3_SET_LOOP_CONST:
1813                 start_reg = (idx_value << 2) + PACKET3_SET_LOOP_CONST_OFFSET;
1814                 end_reg = 4 * pkt->count + start_reg - 4;
1815                 if ((start_reg < PACKET3_SET_LOOP_CONST_OFFSET) ||
1816                     (start_reg >= PACKET3_SET_LOOP_CONST_END) ||
1817                     (end_reg >= PACKET3_SET_LOOP_CONST_END)) {
1818                         DRM_ERROR("bad SET_LOOP_CONST\n");
1819                         return -EINVAL;
1820                 }
1821                 break;
1822         case PACKET3_SET_CTL_CONST:
1823                 start_reg = (idx_value << 2) + PACKET3_SET_CTL_CONST_OFFSET;
1824                 end_reg = 4 * pkt->count + start_reg - 4;
1825                 if ((start_reg < PACKET3_SET_CTL_CONST_OFFSET) ||
1826                     (start_reg >= PACKET3_SET_CTL_CONST_END) ||
1827                     (end_reg >= PACKET3_SET_CTL_CONST_END)) {
1828                         DRM_ERROR("bad SET_CTL_CONST\n");
1829                         return -EINVAL;
1830                 }
1831                 break;
1832         case PACKET3_SET_SAMPLER:
1833                 if (pkt->count % 3) {
1834                         DRM_ERROR("bad SET_SAMPLER\n");
1835                         return -EINVAL;
1836                 }
1837                 start_reg = (idx_value << 2) + PACKET3_SET_SAMPLER_OFFSET;
1838                 end_reg = 4 * pkt->count + start_reg - 4;
1839                 if ((start_reg < PACKET3_SET_SAMPLER_OFFSET) ||
1840                     (start_reg >= PACKET3_SET_SAMPLER_END) ||
1841                     (end_reg >= PACKET3_SET_SAMPLER_END)) {
1842                         DRM_ERROR("bad SET_SAMPLER\n");
1843                         return -EINVAL;
1844                 }
1845                 break;
1846         case PACKET3_SURFACE_BASE_UPDATE:
1847                 if (p->family >= CHIP_RV770 || p->family == CHIP_R600) {
1848                         DRM_ERROR("bad SURFACE_BASE_UPDATE\n");
1849                         return -EINVAL;
1850                 }
1851                 if (pkt->count) {
1852                         DRM_ERROR("bad SURFACE_BASE_UPDATE\n");
1853                         return -EINVAL;
1854                 }
1855                 break;
1856         case PACKET3_STRMOUT_BUFFER_UPDATE:
1857                 if (pkt->count != 4) {
1858                         DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (invalid count)\n");
1859                         return -EINVAL;
1860                 }
1861                 /* Updating memory at DST_ADDRESS. */
1862                 if (idx_value & 0x1) {
1863                         u64 offset;
1864                         r = r600_cs_packet_next_reloc(p, &reloc);
1865                         if (r) {
1866                                 DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing dst reloc)\n");
1867                                 return -EINVAL;
1868                         }
1869                         offset = radeon_get_ib_value(p, idx+1);
1870                         offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32;
1871                         if ((offset + 4) > radeon_bo_size(reloc->robj)) {
1872                                 DRM_ERROR("bad STRMOUT_BUFFER_UPDATE dst bo too small: 0x%llx, 0x%lx\n",
1873                                           offset + 4, radeon_bo_size(reloc->robj));
1874                                 return -EINVAL;
1875                         }
1876                         ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1877                         ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1878                 }
1879                 /* Reading data from SRC_ADDRESS. */
1880                 if (((idx_value >> 1) & 0x3) == 2) {
1881                         u64 offset;
1882                         r = r600_cs_packet_next_reloc(p, &reloc);
1883                         if (r) {
1884                                 DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing src reloc)\n");
1885                                 return -EINVAL;
1886                         }
1887                         offset = radeon_get_ib_value(p, idx+3);
1888                         offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
1889                         if ((offset + 4) > radeon_bo_size(reloc->robj)) {
1890                                 DRM_ERROR("bad STRMOUT_BUFFER_UPDATE src bo too small: 0x%llx, 0x%lx\n",
1891                                           offset + 4, radeon_bo_size(reloc->robj));
1892                                 return -EINVAL;
1893                         }
1894                         ib[idx+3] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1895                         ib[idx+4] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1896                 }
1897                 break;
1898         case PACKET3_COPY_DW:
1899                 if (pkt->count != 4) {
1900                         DRM_ERROR("bad COPY_DW (invalid count)\n");
1901                         return -EINVAL;
1902                 }
1903                 if (idx_value & 0x1) {
1904                         u64 offset;
1905                         /* SRC is memory. */
1906                         r = r600_cs_packet_next_reloc(p, &reloc);
1907                         if (r) {
1908                                 DRM_ERROR("bad COPY_DW (missing src reloc)\n");
1909                                 return -EINVAL;
1910                         }
1911                         offset = radeon_get_ib_value(p, idx+1);
1912                         offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32;
1913                         if ((offset + 4) > radeon_bo_size(reloc->robj)) {
1914                                 DRM_ERROR("bad COPY_DW src bo too small: 0x%llx, 0x%lx\n",
1915                                           offset + 4, radeon_bo_size(reloc->robj));
1916                                 return -EINVAL;
1917                         }
1918                         ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1919                         ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1920                 } else {
1921                         /* SRC is a reg. */
1922                         reg = radeon_get_ib_value(p, idx+1) << 2;
1923                         if (!r600_is_safe_reg(p, reg, idx+1))
1924                                 return -EINVAL;
1925                 }
1926                 if (idx_value & 0x2) {
1927                         u64 offset;
1928                         /* DST is memory. */
1929                         r = r600_cs_packet_next_reloc(p, &reloc);
1930                         if (r) {
1931                                 DRM_ERROR("bad COPY_DW (missing dst reloc)\n");
1932                                 return -EINVAL;
1933                         }
1934                         offset = radeon_get_ib_value(p, idx+3);
1935                         offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
1936                         if ((offset + 4) > radeon_bo_size(reloc->robj)) {
1937                                 DRM_ERROR("bad COPY_DW dst bo too small: 0x%llx, 0x%lx\n",
1938                                           offset + 4, radeon_bo_size(reloc->robj));
1939                                 return -EINVAL;
1940                         }
1941                         ib[idx+3] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1942                         ib[idx+4] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1943                 } else {
1944                         /* DST is a reg. */
1945                         reg = radeon_get_ib_value(p, idx+3) << 2;
1946                         if (!r600_is_safe_reg(p, reg, idx+3))
1947                                 return -EINVAL;
1948                 }
1949                 break;
1950         case PACKET3_NOP:
1951                 break;
1952         default:
1953                 DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode);
1954                 return -EINVAL;
1955         }
1956         return 0;
1957 }
1958
1959 int r600_cs_parse(struct radeon_cs_parser *p)
1960 {
1961         struct radeon_cs_packet pkt;
1962         struct r600_cs_track *track;
1963         int r;
1964
1965         if (p->track == NULL) {
1966                 /* initialize tracker, we are in kms */
1967                 track = kzalloc(sizeof(*track), GFP_KERNEL);
1968                 if (track == NULL)
1969                         return -ENOMEM;
1970                 r600_cs_track_init(track);
1971                 if (p->rdev->family < CHIP_RV770) {
1972                         track->npipes = p->rdev->config.r600.tiling_npipes;
1973                         track->nbanks = p->rdev->config.r600.tiling_nbanks;
1974                         track->group_size = p->rdev->config.r600.tiling_group_size;
1975                 } else if (p->rdev->family <= CHIP_RV740) {
1976                         track->npipes = p->rdev->config.rv770.tiling_npipes;
1977                         track->nbanks = p->rdev->config.rv770.tiling_nbanks;
1978                         track->group_size = p->rdev->config.rv770.tiling_group_size;
1979                 }
1980                 p->track = track;
1981         }
1982         do {
1983                 r = r600_cs_packet_parse(p, &pkt, p->idx);
1984                 if (r) {
1985                         kfree(p->track);
1986                         p->track = NULL;
1987                         return r;
1988                 }
1989                 p->idx += pkt.count + 2;
1990                 switch (pkt.type) {
1991                 case PACKET_TYPE0:
1992                         r = r600_cs_parse_packet0(p, &pkt);
1993                         break;
1994                 case PACKET_TYPE2:
1995                         break;
1996                 case PACKET_TYPE3:
1997                         r = r600_packet3_check(p, &pkt);
1998                         break;
1999                 default:
2000                         DRM_ERROR("Unknown packet type %d !\n", pkt.type);
2001                         kfree(p->track);
2002                         p->track = NULL;
2003                         return -EINVAL;
2004                 }
2005                 if (r) {
2006                         kfree(p->track);
2007                         p->track = NULL;
2008                         return r;
2009                 }
2010         } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
2011 #if 0
2012         for (r = 0; r < p->ib->length_dw; r++) {
2013                 printk(KERN_INFO "%05d  0x%08X\n", r, p->ib->ptr[r]);
2014                 mdelay(1);
2015         }
2016 #endif
2017         kfree(p->track);
2018         p->track = NULL;
2019         return 0;
2020 }
2021
2022 static int r600_cs_parser_relocs_legacy(struct radeon_cs_parser *p)
2023 {
2024         if (p->chunk_relocs_idx == -1) {
2025                 return 0;
2026         }
2027         p->relocs = kzalloc(sizeof(struct radeon_cs_reloc), GFP_KERNEL);
2028         if (p->relocs == NULL) {
2029                 return -ENOMEM;
2030         }
2031         return 0;
2032 }
2033
2034 /**
2035  * cs_parser_fini() - clean parser states
2036  * @parser:     parser structure holding parsing context.
2037  * @error:      error number
2038  *
2039  * If error is set than unvalidate buffer, otherwise just free memory
2040  * used by parsing context.
2041  **/
2042 static void r600_cs_parser_fini(struct radeon_cs_parser *parser, int error)
2043 {
2044         unsigned i;
2045
2046         kfree(parser->relocs);
2047         for (i = 0; i < parser->nchunks; i++) {
2048                 kfree(parser->chunks[i].kdata);
2049                 kfree(parser->chunks[i].kpage[0]);
2050                 kfree(parser->chunks[i].kpage[1]);
2051         }
2052         kfree(parser->chunks);
2053         kfree(parser->chunks_array);
2054 }
2055
2056 int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp,
2057                         unsigned family, u32 *ib, int *l)
2058 {
2059         struct radeon_cs_parser parser;
2060         struct radeon_cs_chunk *ib_chunk;
2061         struct radeon_ib fake_ib;
2062         struct r600_cs_track *track;
2063         int r;
2064
2065         /* initialize tracker */
2066         track = kzalloc(sizeof(*track), GFP_KERNEL);
2067         if (track == NULL)
2068                 return -ENOMEM;
2069         r600_cs_track_init(track);
2070         r600_cs_legacy_get_tiling_conf(dev, &track->npipes, &track->nbanks, &track->group_size);
2071         /* initialize parser */
2072         memset(&parser, 0, sizeof(struct radeon_cs_parser));
2073         parser.filp = filp;
2074         parser.dev = &dev->pdev->dev;
2075         parser.rdev = NULL;
2076         parser.family = family;
2077         parser.ib = &fake_ib;
2078         parser.track = track;
2079         fake_ib.ptr = ib;
2080         r = radeon_cs_parser_init(&parser, data);
2081         if (r) {
2082                 DRM_ERROR("Failed to initialize parser !\n");
2083                 r600_cs_parser_fini(&parser, r);
2084                 return r;
2085         }
2086         r = r600_cs_parser_relocs_legacy(&parser);
2087         if (r) {
2088                 DRM_ERROR("Failed to parse relocation !\n");
2089                 r600_cs_parser_fini(&parser, r);
2090                 return r;
2091         }
2092         /* Copy the packet into the IB, the parser will read from the
2093          * input memory (cached) and write to the IB (which can be
2094          * uncached). */
2095         ib_chunk = &parser.chunks[parser.chunk_ib_idx];
2096         parser.ib->length_dw = ib_chunk->length_dw;
2097         *l = parser.ib->length_dw;
2098         r = r600_cs_parse(&parser);
2099         if (r) {
2100                 DRM_ERROR("Invalid command stream !\n");
2101                 r600_cs_parser_fini(&parser, r);
2102                 return r;
2103         }
2104         r = radeon_cs_finish_pages(&parser);
2105         if (r) {
2106                 DRM_ERROR("Invalid command stream !\n");
2107                 r600_cs_parser_fini(&parser, r);
2108                 return r;
2109         }
2110         r600_cs_parser_fini(&parser, r);
2111         return r;
2112 }
2113
2114 void r600_cs_legacy_init(void)
2115 {
2116         r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_nomm;
2117 }