evergreen_cs.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356
  1. /*
  2. * Copyright 2010 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 "drmP.h"
  29. #include "radeon.h"
  30. #include "evergreend.h"
  31. #include "evergreen_reg_safe.h"
  32. static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p,
  33. struct radeon_cs_reloc **cs_reloc);
  34. struct evergreen_cs_track {
  35. u32 group_size;
  36. u32 nbanks;
  37. u32 npipes;
  38. /* value we track */
  39. u32 nsamples;
  40. u32 cb_color_base_last[12];
  41. struct radeon_bo *cb_color_bo[12];
  42. u32 cb_color_bo_offset[12];
  43. struct radeon_bo *cb_color_fmask_bo[8];
  44. struct radeon_bo *cb_color_cmask_bo[8];
  45. u32 cb_color_info[12];
  46. u32 cb_color_view[12];
  47. u32 cb_color_pitch_idx[12];
  48. u32 cb_color_slice_idx[12];
  49. u32 cb_color_dim_idx[12];
  50. u32 cb_color_dim[12];
  51. u32 cb_color_pitch[12];
  52. u32 cb_color_slice[12];
  53. u32 cb_color_cmask_slice[8];
  54. u32 cb_color_fmask_slice[8];
  55. u32 cb_target_mask;
  56. u32 cb_shader_mask;
  57. u32 vgt_strmout_config;
  58. u32 vgt_strmout_buffer_config;
  59. u32 db_depth_control;
  60. u32 db_depth_view;
  61. u32 db_depth_size;
  62. u32 db_depth_size_idx;
  63. u32 db_z_info;
  64. u32 db_z_idx;
  65. u32 db_z_read_offset;
  66. u32 db_z_write_offset;
  67. struct radeon_bo *db_z_read_bo;
  68. struct radeon_bo *db_z_write_bo;
  69. u32 db_s_info;
  70. u32 db_s_idx;
  71. u32 db_s_read_offset;
  72. u32 db_s_write_offset;
  73. struct radeon_bo *db_s_read_bo;
  74. struct radeon_bo *db_s_write_bo;
  75. };
  76. static void evergreen_cs_track_init(struct evergreen_cs_track *track)
  77. {
  78. int i;
  79. for (i = 0; i < 8; i++) {
  80. track->cb_color_fmask_bo[i] = NULL;
  81. track->cb_color_cmask_bo[i] = NULL;
  82. track->cb_color_cmask_slice[i] = 0;
  83. track->cb_color_fmask_slice[i] = 0;
  84. }
  85. for (i = 0; i < 12; i++) {
  86. track->cb_color_base_last[i] = 0;
  87. track->cb_color_bo[i] = NULL;
  88. track->cb_color_bo_offset[i] = 0xFFFFFFFF;
  89. track->cb_color_info[i] = 0;
  90. track->cb_color_view[i] = 0;
  91. track->cb_color_pitch_idx[i] = 0;
  92. track->cb_color_slice_idx[i] = 0;
  93. track->cb_color_dim[i] = 0;
  94. track->cb_color_pitch[i] = 0;
  95. track->cb_color_slice[i] = 0;
  96. track->cb_color_dim[i] = 0;
  97. }
  98. track->cb_target_mask = 0xFFFFFFFF;
  99. track->cb_shader_mask = 0xFFFFFFFF;
  100. track->db_depth_view = 0xFFFFC000;
  101. track->db_depth_size = 0xFFFFFFFF;
  102. track->db_depth_size_idx = 0;
  103. track->db_depth_control = 0xFFFFFFFF;
  104. track->db_z_info = 0xFFFFFFFF;
  105. track->db_z_idx = 0xFFFFFFFF;
  106. track->db_z_read_offset = 0xFFFFFFFF;
  107. track->db_z_write_offset = 0xFFFFFFFF;
  108. track->db_z_read_bo = NULL;
  109. track->db_z_write_bo = NULL;
  110. track->db_s_info = 0xFFFFFFFF;
  111. track->db_s_idx = 0xFFFFFFFF;
  112. track->db_s_read_offset = 0xFFFFFFFF;
  113. track->db_s_write_offset = 0xFFFFFFFF;
  114. track->db_s_read_bo = NULL;
  115. track->db_s_write_bo = NULL;
  116. }
  117. static inline int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
  118. {
  119. /* XXX fill in */
  120. return 0;
  121. }
  122. static int evergreen_cs_track_check(struct radeon_cs_parser *p)
  123. {
  124. struct evergreen_cs_track *track = p->track;
  125. /* we don't support stream out buffer yet */
  126. if (track->vgt_strmout_config || track->vgt_strmout_buffer_config) {
  127. dev_warn(p->dev, "this kernel doesn't support SMX output buffer\n");
  128. return -EINVAL;
  129. }
  130. /* XXX fill in */
  131. return 0;
  132. }
  133. /**
  134. * evergreen_cs_packet_parse() - parse cp packet and point ib index to next packet
  135. * @parser: parser structure holding parsing context.
  136. * @pkt: where to store packet informations
  137. *
  138. * Assume that chunk_ib_index is properly set. Will return -EINVAL
  139. * if packet is bigger than remaining ib size. or if packets is unknown.
  140. **/
  141. int evergreen_cs_packet_parse(struct radeon_cs_parser *p,
  142. struct radeon_cs_packet *pkt,
  143. unsigned idx)
  144. {
  145. struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx];
  146. uint32_t header;
  147. if (idx >= ib_chunk->length_dw) {
  148. DRM_ERROR("Can not parse packet at %d after CS end %d !\n",
  149. idx, ib_chunk->length_dw);
  150. return -EINVAL;
  151. }
  152. header = radeon_get_ib_value(p, idx);
  153. pkt->idx = idx;
  154. pkt->type = CP_PACKET_GET_TYPE(header);
  155. pkt->count = CP_PACKET_GET_COUNT(header);
  156. pkt->one_reg_wr = 0;
  157. switch (pkt->type) {
  158. case PACKET_TYPE0:
  159. pkt->reg = CP_PACKET0_GET_REG(header);
  160. break;
  161. case PACKET_TYPE3:
  162. pkt->opcode = CP_PACKET3_GET_OPCODE(header);
  163. break;
  164. case PACKET_TYPE2:
  165. pkt->count = -1;
  166. break;
  167. default:
  168. DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx);
  169. return -EINVAL;
  170. }
  171. if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) {
  172. DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n",
  173. pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw);
  174. return -EINVAL;
  175. }
  176. return 0;
  177. }
  178. /**
  179. * evergreen_cs_packet_next_reloc() - parse next packet which should be reloc packet3
  180. * @parser: parser structure holding parsing context.
  181. * @data: pointer to relocation data
  182. * @offset_start: starting offset
  183. * @offset_mask: offset mask (to align start offset on)
  184. * @reloc: reloc informations
  185. *
  186. * Check next packet is relocation packet3, do bo validation and compute
  187. * GPU offset using the provided start.
  188. **/
  189. static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p,
  190. struct radeon_cs_reloc **cs_reloc)
  191. {
  192. struct radeon_cs_chunk *relocs_chunk;
  193. struct radeon_cs_packet p3reloc;
  194. unsigned idx;
  195. int r;
  196. if (p->chunk_relocs_idx == -1) {
  197. DRM_ERROR("No relocation chunk !\n");
  198. return -EINVAL;
  199. }
  200. *cs_reloc = NULL;
  201. relocs_chunk = &p->chunks[p->chunk_relocs_idx];
  202. r = evergreen_cs_packet_parse(p, &p3reloc, p->idx);
  203. if (r) {
  204. return r;
  205. }
  206. p->idx += p3reloc.count + 2;
  207. if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
  208. DRM_ERROR("No packet3 for relocation for packet at %d.\n",
  209. p3reloc.idx);
  210. return -EINVAL;
  211. }
  212. idx = radeon_get_ib_value(p, p3reloc.idx + 1);
  213. if (idx >= relocs_chunk->length_dw) {
  214. DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
  215. idx, relocs_chunk->length_dw);
  216. return -EINVAL;
  217. }
  218. /* FIXME: we assume reloc size is 4 dwords */
  219. *cs_reloc = p->relocs_ptr[(idx / 4)];
  220. return 0;
  221. }
  222. /**
  223. * evergreen_cs_packet_next_is_pkt3_nop() - test if next packet is packet3 nop for reloc
  224. * @parser: parser structure holding parsing context.
  225. *
  226. * Check next packet is relocation packet3, do bo validation and compute
  227. * GPU offset using the provided start.
  228. **/
  229. static inline int evergreen_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p)
  230. {
  231. struct radeon_cs_packet p3reloc;
  232. int r;
  233. r = evergreen_cs_packet_parse(p, &p3reloc, p->idx);
  234. if (r) {
  235. return 0;
  236. }
  237. if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
  238. return 0;
  239. }
  240. return 1;
  241. }
  242. /**
  243. * evergreen_cs_packet_next_vline() - parse userspace VLINE packet
  244. * @parser: parser structure holding parsing context.
  245. *
  246. * Userspace sends a special sequence for VLINE waits.
  247. * PACKET0 - VLINE_START_END + value
  248. * PACKET3 - WAIT_REG_MEM poll vline status reg
  249. * RELOC (P3) - crtc_id in reloc.
  250. *
  251. * This function parses this and relocates the VLINE START END
  252. * and WAIT_REG_MEM packets to the correct crtc.
  253. * It also detects a switched off crtc and nulls out the
  254. * wait in that case.
  255. */
  256. static int evergreen_cs_packet_parse_vline(struct radeon_cs_parser *p)
  257. {
  258. struct drm_mode_object *obj;
  259. struct drm_crtc *crtc;
  260. struct radeon_crtc *radeon_crtc;
  261. struct radeon_cs_packet p3reloc, wait_reg_mem;
  262. int crtc_id;
  263. int r;
  264. uint32_t header, h_idx, reg, wait_reg_mem_info;
  265. volatile uint32_t *ib;
  266. ib = p->ib->ptr;
  267. /* parse the WAIT_REG_MEM */
  268. r = evergreen_cs_packet_parse(p, &wait_reg_mem, p->idx);
  269. if (r)
  270. return r;
  271. /* check its a WAIT_REG_MEM */
  272. if (wait_reg_mem.type != PACKET_TYPE3 ||
  273. wait_reg_mem.opcode != PACKET3_WAIT_REG_MEM) {
  274. DRM_ERROR("vline wait missing WAIT_REG_MEM segment\n");
  275. r = -EINVAL;
  276. return r;
  277. }
  278. wait_reg_mem_info = radeon_get_ib_value(p, wait_reg_mem.idx + 1);
  279. /* bit 4 is reg (0) or mem (1) */
  280. if (wait_reg_mem_info & 0x10) {
  281. DRM_ERROR("vline WAIT_REG_MEM waiting on MEM rather than REG\n");
  282. r = -EINVAL;
  283. return r;
  284. }
  285. /* waiting for value to be equal */
  286. if ((wait_reg_mem_info & 0x7) != 0x3) {
  287. DRM_ERROR("vline WAIT_REG_MEM function not equal\n");
  288. r = -EINVAL;
  289. return r;
  290. }
  291. if ((radeon_get_ib_value(p, wait_reg_mem.idx + 2) << 2) != EVERGREEN_VLINE_STATUS) {
  292. DRM_ERROR("vline WAIT_REG_MEM bad reg\n");
  293. r = -EINVAL;
  294. return r;
  295. }
  296. if (radeon_get_ib_value(p, wait_reg_mem.idx + 5) != EVERGREEN_VLINE_STAT) {
  297. DRM_ERROR("vline WAIT_REG_MEM bad bit mask\n");
  298. r = -EINVAL;
  299. return r;
  300. }
  301. /* jump over the NOP */
  302. r = evergreen_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2);
  303. if (r)
  304. return r;
  305. h_idx = p->idx - 2;
  306. p->idx += wait_reg_mem.count + 2;
  307. p->idx += p3reloc.count + 2;
  308. header = radeon_get_ib_value(p, h_idx);
  309. crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1);
  310. reg = CP_PACKET0_GET_REG(header);
  311. mutex_lock(&p->rdev->ddev->mode_config.mutex);
  312. obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
  313. if (!obj) {
  314. DRM_ERROR("cannot find crtc %d\n", crtc_id);
  315. r = -EINVAL;
  316. goto out;
  317. }
  318. crtc = obj_to_crtc(obj);
  319. radeon_crtc = to_radeon_crtc(crtc);
  320. crtc_id = radeon_crtc->crtc_id;
  321. if (!crtc->enabled) {
  322. /* if the CRTC isn't enabled - we need to nop out the WAIT_REG_MEM */
  323. ib[h_idx + 2] = PACKET2(0);
  324. ib[h_idx + 3] = PACKET2(0);
  325. ib[h_idx + 4] = PACKET2(0);
  326. ib[h_idx + 5] = PACKET2(0);
  327. ib[h_idx + 6] = PACKET2(0);
  328. ib[h_idx + 7] = PACKET2(0);
  329. ib[h_idx + 8] = PACKET2(0);
  330. } else {
  331. switch (reg) {
  332. case EVERGREEN_VLINE_START_END:
  333. header &= ~R600_CP_PACKET0_REG_MASK;
  334. header |= (EVERGREEN_VLINE_START_END + radeon_crtc->crtc_offset) >> 2;
  335. ib[h_idx] = header;
  336. ib[h_idx + 4] = (EVERGREEN_VLINE_STATUS + radeon_crtc->crtc_offset) >> 2;
  337. break;
  338. default:
  339. DRM_ERROR("unknown crtc reloc\n");
  340. r = -EINVAL;
  341. goto out;
  342. }
  343. }
  344. out:
  345. mutex_unlock(&p->rdev->ddev->mode_config.mutex);
  346. return r;
  347. }
  348. static int evergreen_packet0_check(struct radeon_cs_parser *p,
  349. struct radeon_cs_packet *pkt,
  350. unsigned idx, unsigned reg)
  351. {
  352. int r;
  353. switch (reg) {
  354. case EVERGREEN_VLINE_START_END:
  355. r = evergreen_cs_packet_parse_vline(p);
  356. if (r) {
  357. DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
  358. idx, reg);
  359. return r;
  360. }
  361. break;
  362. default:
  363. printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
  364. reg, idx);
  365. return -EINVAL;
  366. }
  367. return 0;
  368. }
  369. static int evergreen_cs_parse_packet0(struct radeon_cs_parser *p,
  370. struct radeon_cs_packet *pkt)
  371. {
  372. unsigned reg, i;
  373. unsigned idx;
  374. int r;
  375. idx = pkt->idx + 1;
  376. reg = pkt->reg;
  377. for (i = 0; i <= pkt->count; i++, idx++, reg += 4) {
  378. r = evergreen_packet0_check(p, pkt, idx, reg);
  379. if (r) {
  380. return r;
  381. }
  382. }
  383. return 0;
  384. }
  385. /**
  386. * evergreen_cs_check_reg() - check if register is authorized or not
  387. * @parser: parser structure holding parsing context
  388. * @reg: register we are testing
  389. * @idx: index into the cs buffer
  390. *
  391. * This function will test against evergreen_reg_safe_bm and return 0
  392. * if register is safe. If register is not flag as safe this function
  393. * will test it against a list of register needind special handling.
  394. */
  395. static inline int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
  396. {
  397. struct evergreen_cs_track *track = (struct evergreen_cs_track *)p->track;
  398. struct radeon_cs_reloc *reloc;
  399. u32 last_reg = ARRAY_SIZE(evergreen_reg_safe_bm);
  400. u32 m, i, tmp, *ib;
  401. int r;
  402. i = (reg >> 7);
  403. if (i > last_reg) {
  404. dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
  405. return -EINVAL;
  406. }
  407. m = 1 << ((reg >> 2) & 31);
  408. if (!(evergreen_reg_safe_bm[i] & m))
  409. return 0;
  410. ib = p->ib->ptr;
  411. switch (reg) {
  412. /* force following reg to 0 in an attemp to disable out buffer
  413. * which will need us to better understand how it works to perform
  414. * security check on it (Jerome)
  415. */
  416. case SQ_ESGS_RING_SIZE:
  417. case SQ_GSVS_RING_SIZE:
  418. case SQ_ESTMP_RING_SIZE:
  419. case SQ_GSTMP_RING_SIZE:
  420. case SQ_HSTMP_RING_SIZE:
  421. case SQ_LSTMP_RING_SIZE:
  422. case SQ_PSTMP_RING_SIZE:
  423. case SQ_VSTMP_RING_SIZE:
  424. case SQ_ESGS_RING_ITEMSIZE:
  425. case SQ_ESTMP_RING_ITEMSIZE:
  426. case SQ_GSTMP_RING_ITEMSIZE:
  427. case SQ_GSVS_RING_ITEMSIZE:
  428. case SQ_GS_VERT_ITEMSIZE:
  429. case SQ_GS_VERT_ITEMSIZE_1:
  430. case SQ_GS_VERT_ITEMSIZE_2:
  431. case SQ_GS_VERT_ITEMSIZE_3:
  432. case SQ_GSVS_RING_OFFSET_1:
  433. case SQ_GSVS_RING_OFFSET_2:
  434. case SQ_GSVS_RING_OFFSET_3:
  435. case SQ_HSTMP_RING_ITEMSIZE:
  436. case SQ_LSTMP_RING_ITEMSIZE:
  437. case SQ_PSTMP_RING_ITEMSIZE:
  438. case SQ_VSTMP_RING_ITEMSIZE:
  439. case VGT_TF_RING_SIZE:
  440. /* get value to populate the IB don't remove */
  441. tmp =radeon_get_ib_value(p, idx);
  442. ib[idx] = 0;
  443. break;
  444. case DB_DEPTH_CONTROL:
  445. track->db_depth_control = radeon_get_ib_value(p, idx);
  446. break;
  447. case DB_Z_INFO:
  448. r = evergreen_cs_packet_next_reloc(p, &reloc);
  449. if (r) {
  450. dev_warn(p->dev, "bad SET_CONTEXT_REG "
  451. "0x%04X\n", reg);
  452. return -EINVAL;
  453. }
  454. track->db_z_info = radeon_get_ib_value(p, idx);
  455. ib[idx] &= ~Z_ARRAY_MODE(0xf);
  456. track->db_z_info &= ~Z_ARRAY_MODE(0xf);
  457. if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
  458. ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
  459. track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
  460. } else {
  461. ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
  462. track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
  463. }
  464. break;
  465. case DB_STENCIL_INFO:
  466. track->db_s_info = radeon_get_ib_value(p, idx);
  467. break;
  468. case DB_DEPTH_VIEW:
  469. track->db_depth_view = radeon_get_ib_value(p, idx);
  470. break;
  471. case DB_DEPTH_SIZE:
  472. track->db_depth_size = radeon_get_ib_value(p, idx);
  473. track->db_depth_size_idx = idx;
  474. break;
  475. case DB_Z_READ_BASE:
  476. r = evergreen_cs_packet_next_reloc(p, &reloc);
  477. if (r) {
  478. dev_warn(p->dev, "bad SET_CONTEXT_REG "
  479. "0x%04X\n", reg);
  480. return -EINVAL;
  481. }
  482. track->db_z_read_offset = radeon_get_ib_value(p, idx);
  483. ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
  484. track->db_z_read_bo = reloc->robj;
  485. break;
  486. case DB_Z_WRITE_BASE:
  487. r = evergreen_cs_packet_next_reloc(p, &reloc);
  488. if (r) {
  489. dev_warn(p->dev, "bad SET_CONTEXT_REG "
  490. "0x%04X\n", reg);
  491. return -EINVAL;
  492. }
  493. track->db_z_write_offset = radeon_get_ib_value(p, idx);
  494. ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
  495. track->db_z_write_bo = reloc->robj;
  496. break;
  497. case DB_STENCIL_READ_BASE:
  498. r = evergreen_cs_packet_next_reloc(p, &reloc);
  499. if (r) {
  500. dev_warn(p->dev, "bad SET_CONTEXT_REG "
  501. "0x%04X\n", reg);
  502. return -EINVAL;
  503. }
  504. track->db_s_read_offset = radeon_get_ib_value(p, idx);
  505. ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
  506. track->db_s_read_bo = reloc->robj;
  507. break;
  508. case DB_STENCIL_WRITE_BASE:
  509. r = evergreen_cs_packet_next_reloc(p, &reloc);
  510. if (r) {
  511. dev_warn(p->dev, "bad SET_CONTEXT_REG "
  512. "0x%04X\n", reg);
  513. return -EINVAL;
  514. }
  515. track->db_s_write_offset = radeon_get_ib_value(p, idx);
  516. ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
  517. track->db_s_write_bo = reloc->robj;
  518. break;
  519. case VGT_STRMOUT_CONFIG:
  520. track->vgt_strmout_config = radeon_get_ib_value(p, idx);
  521. break;
  522. case VGT_STRMOUT_BUFFER_CONFIG:
  523. track->vgt_strmout_buffer_config = radeon_get_ib_value(p, idx);
  524. break;
  525. case CB_TARGET_MASK:
  526. track->cb_target_mask = radeon_get_ib_value(p, idx);
  527. break;
  528. case CB_SHADER_MASK:
  529. track->cb_shader_mask = radeon_get_ib_value(p, idx);
  530. break;
  531. case PA_SC_AA_CONFIG:
  532. tmp = radeon_get_ib_value(p, idx) & MSAA_NUM_SAMPLES_MASK;
  533. track->nsamples = 1 << tmp;
  534. break;
  535. case CB_COLOR0_VIEW:
  536. case CB_COLOR1_VIEW:
  537. case CB_COLOR2_VIEW:
  538. case CB_COLOR3_VIEW:
  539. case CB_COLOR4_VIEW:
  540. case CB_COLOR5_VIEW:
  541. case CB_COLOR6_VIEW:
  542. case CB_COLOR7_VIEW:
  543. tmp = (reg - CB_COLOR0_VIEW) / 0x3c;
  544. track->cb_color_view[tmp] = radeon_get_ib_value(p, idx);
  545. break;
  546. case CB_COLOR8_VIEW:
  547. case CB_COLOR9_VIEW:
  548. case CB_COLOR10_VIEW:
  549. case CB_COLOR11_VIEW:
  550. tmp = ((reg - CB_COLOR8_VIEW) / 0x1c) + 8;
  551. track->cb_color_view[tmp] = radeon_get_ib_value(p, idx);
  552. break;
  553. case CB_COLOR0_INFO:
  554. case CB_COLOR1_INFO:
  555. case CB_COLOR2_INFO:
  556. case CB_COLOR3_INFO:
  557. case CB_COLOR4_INFO:
  558. case CB_COLOR5_INFO:
  559. case CB_COLOR6_INFO:
  560. case CB_COLOR7_INFO:
  561. r = evergreen_cs_packet_next_reloc(p, &reloc);
  562. if (r) {
  563. dev_warn(p->dev, "bad SET_CONTEXT_REG "
  564. "0x%04X\n", reg);
  565. return -EINVAL;
  566. }
  567. tmp = (reg - CB_COLOR0_INFO) / 0x3c;
  568. track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
  569. if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
  570. ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
  571. track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
  572. } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
  573. ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
  574. track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
  575. }
  576. break;
  577. case CB_COLOR8_INFO:
  578. case CB_COLOR9_INFO:
  579. case CB_COLOR10_INFO:
  580. case CB_COLOR11_INFO:
  581. r = evergreen_cs_packet_next_reloc(p, &reloc);
  582. if (r) {
  583. dev_warn(p->dev, "bad SET_CONTEXT_REG "
  584. "0x%04X\n", reg);
  585. return -EINVAL;
  586. }
  587. tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8;
  588. track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
  589. if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
  590. ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
  591. track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
  592. } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
  593. ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
  594. track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
  595. }
  596. break;
  597. case CB_COLOR0_PITCH:
  598. case CB_COLOR1_PITCH:
  599. case CB_COLOR2_PITCH:
  600. case CB_COLOR3_PITCH:
  601. case CB_COLOR4_PITCH:
  602. case CB_COLOR5_PITCH:
  603. case CB_COLOR6_PITCH:
  604. case CB_COLOR7_PITCH:
  605. tmp = (reg - CB_COLOR0_PITCH) / 0x3c;
  606. track->cb_color_pitch[tmp] = radeon_get_ib_value(p, idx);
  607. track->cb_color_pitch_idx[tmp] = idx;
  608. break;
  609. case CB_COLOR8_PITCH:
  610. case CB_COLOR9_PITCH:
  611. case CB_COLOR10_PITCH:
  612. case CB_COLOR11_PITCH:
  613. tmp = ((reg - CB_COLOR8_PITCH) / 0x1c) + 8;
  614. track->cb_color_pitch[tmp] = radeon_get_ib_value(p, idx);
  615. track->cb_color_pitch_idx[tmp] = idx;
  616. break;
  617. case CB_COLOR0_SLICE:
  618. case CB_COLOR1_SLICE:
  619. case CB_COLOR2_SLICE:
  620. case CB_COLOR3_SLICE:
  621. case CB_COLOR4_SLICE:
  622. case CB_COLOR5_SLICE:
  623. case CB_COLOR6_SLICE:
  624. case CB_COLOR7_SLICE:
  625. tmp = (reg - CB_COLOR0_SLICE) / 0x3c;
  626. track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx);
  627. track->cb_color_slice_idx[tmp] = idx;
  628. break;
  629. case CB_COLOR8_SLICE:
  630. case CB_COLOR9_SLICE:
  631. case CB_COLOR10_SLICE:
  632. case CB_COLOR11_SLICE:
  633. tmp = ((reg - CB_COLOR8_SLICE) / 0x1c) + 8;
  634. track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx);
  635. track->cb_color_slice_idx[tmp] = idx;
  636. break;
  637. case CB_COLOR0_ATTRIB:
  638. case CB_COLOR1_ATTRIB:
  639. case CB_COLOR2_ATTRIB:
  640. case CB_COLOR3_ATTRIB:
  641. case CB_COLOR4_ATTRIB:
  642. case CB_COLOR5_ATTRIB:
  643. case CB_COLOR6_ATTRIB:
  644. case CB_COLOR7_ATTRIB:
  645. case CB_COLOR8_ATTRIB:
  646. case CB_COLOR9_ATTRIB:
  647. case CB_COLOR10_ATTRIB:
  648. case CB_COLOR11_ATTRIB:
  649. break;
  650. case CB_COLOR0_DIM:
  651. case CB_COLOR1_DIM:
  652. case CB_COLOR2_DIM:
  653. case CB_COLOR3_DIM:
  654. case CB_COLOR4_DIM:
  655. case CB_COLOR5_DIM:
  656. case CB_COLOR6_DIM:
  657. case CB_COLOR7_DIM:
  658. tmp = (reg - CB_COLOR0_DIM) / 0x3c;
  659. track->cb_color_dim[tmp] = radeon_get_ib_value(p, idx);
  660. track->cb_color_dim_idx[tmp] = idx;
  661. break;
  662. case CB_COLOR8_DIM:
  663. case CB_COLOR9_DIM:
  664. case CB_COLOR10_DIM:
  665. case CB_COLOR11_DIM:
  666. tmp = ((reg - CB_COLOR8_DIM) / 0x1c) + 8;
  667. track->cb_color_dim[tmp] = radeon_get_ib_value(p, idx);
  668. track->cb_color_dim_idx[tmp] = idx;
  669. break;
  670. case CB_COLOR0_FMASK:
  671. case CB_COLOR1_FMASK:
  672. case CB_COLOR2_FMASK:
  673. case CB_COLOR3_FMASK:
  674. case CB_COLOR4_FMASK:
  675. case CB_COLOR5_FMASK:
  676. case CB_COLOR6_FMASK:
  677. case CB_COLOR7_FMASK:
  678. tmp = (reg - CB_COLOR0_FMASK) / 0x3c;
  679. r = evergreen_cs_packet_next_reloc(p, &reloc);
  680. if (r) {
  681. dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
  682. return -EINVAL;
  683. }
  684. ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
  685. track->cb_color_fmask_bo[tmp] = reloc->robj;
  686. break;
  687. case CB_COLOR0_CMASK:
  688. case CB_COLOR1_CMASK:
  689. case CB_COLOR2_CMASK:
  690. case CB_COLOR3_CMASK:
  691. case CB_COLOR4_CMASK:
  692. case CB_COLOR5_CMASK:
  693. case CB_COLOR6_CMASK:
  694. case CB_COLOR7_CMASK:
  695. tmp = (reg - CB_COLOR0_CMASK) / 0x3c;
  696. r = evergreen_cs_packet_next_reloc(p, &reloc);
  697. if (r) {
  698. dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
  699. return -EINVAL;
  700. }
  701. ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
  702. track->cb_color_cmask_bo[tmp] = reloc->robj;
  703. break;
  704. case CB_COLOR0_FMASK_SLICE:
  705. case CB_COLOR1_FMASK_SLICE:
  706. case CB_COLOR2_FMASK_SLICE:
  707. case CB_COLOR3_FMASK_SLICE:
  708. case CB_COLOR4_FMASK_SLICE:
  709. case CB_COLOR5_FMASK_SLICE:
  710. case CB_COLOR6_FMASK_SLICE:
  711. case CB_COLOR7_FMASK_SLICE:
  712. tmp = (reg - CB_COLOR0_FMASK_SLICE) / 0x3c;
  713. track->cb_color_fmask_slice[tmp] = radeon_get_ib_value(p, idx);
  714. break;
  715. case CB_COLOR0_CMASK_SLICE:
  716. case CB_COLOR1_CMASK_SLICE:
  717. case CB_COLOR2_CMASK_SLICE:
  718. case CB_COLOR3_CMASK_SLICE:
  719. case CB_COLOR4_CMASK_SLICE:
  720. case CB_COLOR5_CMASK_SLICE:
  721. case CB_COLOR6_CMASK_SLICE:
  722. case CB_COLOR7_CMASK_SLICE:
  723. tmp = (reg - CB_COLOR0_CMASK_SLICE) / 0x3c;
  724. track->cb_color_cmask_slice[tmp] = radeon_get_ib_value(p, idx);
  725. break;
  726. case CB_COLOR0_BASE:
  727. case CB_COLOR1_BASE:
  728. case CB_COLOR2_BASE:
  729. case CB_COLOR3_BASE:
  730. case CB_COLOR4_BASE:
  731. case CB_COLOR5_BASE:
  732. case CB_COLOR6_BASE:
  733. case CB_COLOR7_BASE:
  734. r = evergreen_cs_packet_next_reloc(p, &reloc);
  735. if (r) {
  736. dev_warn(p->dev, "bad SET_CONTEXT_REG "
  737. "0x%04X\n", reg);
  738. return -EINVAL;
  739. }
  740. tmp = (reg - CB_COLOR0_BASE) / 0x3c;
  741. track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx);
  742. ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
  743. track->cb_color_base_last[tmp] = ib[idx];
  744. track->cb_color_bo[tmp] = reloc->robj;
  745. break;
  746. case CB_COLOR8_BASE:
  747. case CB_COLOR9_BASE:
  748. case CB_COLOR10_BASE:
  749. case CB_COLOR11_BASE:
  750. r = evergreen_cs_packet_next_reloc(p, &reloc);
  751. if (r) {
  752. dev_warn(p->dev, "bad SET_CONTEXT_REG "
  753. "0x%04X\n", reg);
  754. return -EINVAL;
  755. }
  756. tmp = ((reg - CB_COLOR8_BASE) / 0x1c) + 8;
  757. track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx);
  758. ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
  759. track->cb_color_base_last[tmp] = ib[idx];
  760. track->cb_color_bo[tmp] = reloc->robj;
  761. break;
  762. case CB_IMMED0_BASE:
  763. case CB_IMMED1_BASE:
  764. case CB_IMMED2_BASE:
  765. case CB_IMMED3_BASE:
  766. case CB_IMMED4_BASE:
  767. case CB_IMMED5_BASE:
  768. case CB_IMMED6_BASE:
  769. case CB_IMMED7_BASE:
  770. case CB_IMMED8_BASE:
  771. case CB_IMMED9_BASE:
  772. case CB_IMMED10_BASE:
  773. case CB_IMMED11_BASE:
  774. case DB_HTILE_DATA_BASE:
  775. case SQ_PGM_START_FS:
  776. case SQ_PGM_START_ES:
  777. case SQ_PGM_START_VS:
  778. case SQ_PGM_START_GS:
  779. case SQ_PGM_START_PS:
  780. case SQ_PGM_START_HS:
  781. case SQ_PGM_START_LS:
  782. case GDS_ADDR_BASE:
  783. case SQ_CONST_MEM_BASE:
  784. case SQ_ALU_CONST_CACHE_GS_0:
  785. case SQ_ALU_CONST_CACHE_GS_1:
  786. case SQ_ALU_CONST_CACHE_GS_2:
  787. case SQ_ALU_CONST_CACHE_GS_3:
  788. case SQ_ALU_CONST_CACHE_GS_4:
  789. case SQ_ALU_CONST_CACHE_GS_5:
  790. case SQ_ALU_CONST_CACHE_GS_6:
  791. case SQ_ALU_CONST_CACHE_GS_7:
  792. case SQ_ALU_CONST_CACHE_GS_8:
  793. case SQ_ALU_CONST_CACHE_GS_9:
  794. case SQ_ALU_CONST_CACHE_GS_10:
  795. case SQ_ALU_CONST_CACHE_GS_11:
  796. case SQ_ALU_CONST_CACHE_GS_12:
  797. case SQ_ALU_CONST_CACHE_GS_13:
  798. case SQ_ALU_CONST_CACHE_GS_14:
  799. case SQ_ALU_CONST_CACHE_GS_15:
  800. case SQ_ALU_CONST_CACHE_PS_0:
  801. case SQ_ALU_CONST_CACHE_PS_1:
  802. case SQ_ALU_CONST_CACHE_PS_2:
  803. case SQ_ALU_CONST_CACHE_PS_3:
  804. case SQ_ALU_CONST_CACHE_PS_4:
  805. case SQ_ALU_CONST_CACHE_PS_5:
  806. case SQ_ALU_CONST_CACHE_PS_6:
  807. case SQ_ALU_CONST_CACHE_PS_7:
  808. case SQ_ALU_CONST_CACHE_PS_8:
  809. case SQ_ALU_CONST_CACHE_PS_9:
  810. case SQ_ALU_CONST_CACHE_PS_10:
  811. case SQ_ALU_CONST_CACHE_PS_11:
  812. case SQ_ALU_CONST_CACHE_PS_12:
  813. case SQ_ALU_CONST_CACHE_PS_13:
  814. case SQ_ALU_CONST_CACHE_PS_14:
  815. case SQ_ALU_CONST_CACHE_PS_15:
  816. case SQ_ALU_CONST_CACHE_VS_0:
  817. case SQ_ALU_CONST_CACHE_VS_1:
  818. case SQ_ALU_CONST_CACHE_VS_2:
  819. case SQ_ALU_CONST_CACHE_VS_3:
  820. case SQ_ALU_CONST_CACHE_VS_4:
  821. case SQ_ALU_CONST_CACHE_VS_5:
  822. case SQ_ALU_CONST_CACHE_VS_6:
  823. case SQ_ALU_CONST_CACHE_VS_7:
  824. case SQ_ALU_CONST_CACHE_VS_8:
  825. case SQ_ALU_CONST_CACHE_VS_9:
  826. case SQ_ALU_CONST_CACHE_VS_10:
  827. case SQ_ALU_CONST_CACHE_VS_11:
  828. case SQ_ALU_CONST_CACHE_VS_12:
  829. case SQ_ALU_CONST_CACHE_VS_13:
  830. case SQ_ALU_CONST_CACHE_VS_14:
  831. case SQ_ALU_CONST_CACHE_VS_15:
  832. case SQ_ALU_CONST_CACHE_HS_0:
  833. case SQ_ALU_CONST_CACHE_HS_1:
  834. case SQ_ALU_CONST_CACHE_HS_2:
  835. case SQ_ALU_CONST_CACHE_HS_3:
  836. case SQ_ALU_CONST_CACHE_HS_4:
  837. case SQ_ALU_CONST_CACHE_HS_5:
  838. case SQ_ALU_CONST_CACHE_HS_6:
  839. case SQ_ALU_CONST_CACHE_HS_7:
  840. case SQ_ALU_CONST_CACHE_HS_8:
  841. case SQ_ALU_CONST_CACHE_HS_9:
  842. case SQ_ALU_CONST_CACHE_HS_10:
  843. case SQ_ALU_CONST_CACHE_HS_11:
  844. case SQ_ALU_CONST_CACHE_HS_12:
  845. case SQ_ALU_CONST_CACHE_HS_13:
  846. case SQ_ALU_CONST_CACHE_HS_14:
  847. case SQ_ALU_CONST_CACHE_HS_15:
  848. case SQ_ALU_CONST_CACHE_LS_0:
  849. case SQ_ALU_CONST_CACHE_LS_1:
  850. case SQ_ALU_CONST_CACHE_LS_2:
  851. case SQ_ALU_CONST_CACHE_LS_3:
  852. case SQ_ALU_CONST_CACHE_LS_4:
  853. case SQ_ALU_CONST_CACHE_LS_5:
  854. case SQ_ALU_CONST_CACHE_LS_6:
  855. case SQ_ALU_CONST_CACHE_LS_7:
  856. case SQ_ALU_CONST_CACHE_LS_8:
  857. case SQ_ALU_CONST_CACHE_LS_9:
  858. case SQ_ALU_CONST_CACHE_LS_10:
  859. case SQ_ALU_CONST_CACHE_LS_11:
  860. case SQ_ALU_CONST_CACHE_LS_12:
  861. case SQ_ALU_CONST_CACHE_LS_13:
  862. case SQ_ALU_CONST_CACHE_LS_14:
  863. case SQ_ALU_CONST_CACHE_LS_15:
  864. r = evergreen_cs_packet_next_reloc(p, &reloc);
  865. if (r) {
  866. dev_warn(p->dev, "bad SET_CONTEXT_REG "
  867. "0x%04X\n", reg);
  868. return -EINVAL;
  869. }
  870. ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
  871. break;
  872. default:
  873. dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
  874. return -EINVAL;
  875. }
  876. return 0;
  877. }
  878. /**
  879. * evergreen_check_texture_resource() - check if register is authorized or not
  880. * @p: parser structure holding parsing context
  881. * @idx: index into the cs buffer
  882. * @texture: texture's bo structure
  883. * @mipmap: mipmap's bo structure
  884. *
  885. * This function will check that the resource has valid field and that
  886. * the texture and mipmap bo object are big enough to cover this resource.
  887. */
  888. static inline int evergreen_check_texture_resource(struct radeon_cs_parser *p, u32 idx,
  889. struct radeon_bo *texture,
  890. struct radeon_bo *mipmap)
  891. {
  892. /* XXX fill in */
  893. return 0;
  894. }
  895. static int evergreen_packet3_check(struct radeon_cs_parser *p,
  896. struct radeon_cs_packet *pkt)
  897. {
  898. struct radeon_cs_reloc *reloc;
  899. struct evergreen_cs_track *track;
  900. volatile u32 *ib;
  901. unsigned idx;
  902. unsigned i;
  903. unsigned start_reg, end_reg, reg;
  904. int r;
  905. u32 idx_value;
  906. track = (struct evergreen_cs_track *)p->track;
  907. ib = p->ib->ptr;
  908. idx = pkt->idx + 1;
  909. idx_value = radeon_get_ib_value(p, idx);
  910. switch (pkt->opcode) {
  911. case PACKET3_CONTEXT_CONTROL:
  912. if (pkt->count != 1) {
  913. DRM_ERROR("bad CONTEXT_CONTROL\n");
  914. return -EINVAL;
  915. }
  916. break;
  917. case PACKET3_INDEX_TYPE:
  918. case PACKET3_NUM_INSTANCES:
  919. case PACKET3_CLEAR_STATE:
  920. if (pkt->count) {
  921. DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES/CLEAR_STATE\n");
  922. return -EINVAL;
  923. }
  924. break;
  925. case PACKET3_INDEX_BASE:
  926. if (pkt->count != 1) {
  927. DRM_ERROR("bad INDEX_BASE\n");
  928. return -EINVAL;
  929. }
  930. r = evergreen_cs_packet_next_reloc(p, &reloc);
  931. if (r) {
  932. DRM_ERROR("bad INDEX_BASE\n");
  933. return -EINVAL;
  934. }
  935. ib[idx+0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff);
  936. ib[idx+1] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
  937. r = evergreen_cs_track_check(p);
  938. if (r) {
  939. dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
  940. return r;
  941. }
  942. break;
  943. case PACKET3_DRAW_INDEX:
  944. if (pkt->count != 3) {
  945. DRM_ERROR("bad DRAW_INDEX\n");
  946. return -EINVAL;
  947. }
  948. r = evergreen_cs_packet_next_reloc(p, &reloc);
  949. if (r) {
  950. DRM_ERROR("bad DRAW_INDEX\n");
  951. return -EINVAL;
  952. }
  953. ib[idx+0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff);
  954. ib[idx+1] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
  955. r = evergreen_cs_track_check(p);
  956. if (r) {
  957. dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
  958. return r;
  959. }
  960. break;
  961. case PACKET3_DRAW_INDEX_2:
  962. if (pkt->count != 4) {
  963. DRM_ERROR("bad DRAW_INDEX_2\n");
  964. return -EINVAL;
  965. }
  966. r = evergreen_cs_packet_next_reloc(p, &reloc);
  967. if (r) {
  968. DRM_ERROR("bad DRAW_INDEX_2\n");
  969. return -EINVAL;
  970. }
  971. ib[idx+1] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff);
  972. ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
  973. r = evergreen_cs_track_check(p);
  974. if (r) {
  975. dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
  976. return r;
  977. }
  978. break;
  979. case PACKET3_DRAW_INDEX_AUTO:
  980. if (pkt->count != 1) {
  981. DRM_ERROR("bad DRAW_INDEX_AUTO\n");
  982. return -EINVAL;
  983. }
  984. r = evergreen_cs_track_check(p);
  985. if (r) {
  986. dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx);
  987. return r;
  988. }
  989. break;
  990. case PACKET3_DRAW_INDEX_MULTI_AUTO:
  991. if (pkt->count != 2) {
  992. DRM_ERROR("bad DRAW_INDEX_MULTI_AUTO\n");
  993. return -EINVAL;
  994. }
  995. r = evergreen_cs_track_check(p);
  996. if (r) {
  997. dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx);
  998. return r;
  999. }
  1000. break;
  1001. case PACKET3_DRAW_INDEX_IMMD:
  1002. if (pkt->count < 2) {
  1003. DRM_ERROR("bad DRAW_INDEX_IMMD\n");
  1004. return -EINVAL;
  1005. }
  1006. r = evergreen_cs_track_check(p);
  1007. if (r) {
  1008. dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
  1009. return r;
  1010. }
  1011. break;
  1012. case PACKET3_DRAW_INDEX_OFFSET:
  1013. if (pkt->count != 2) {
  1014. DRM_ERROR("bad DRAW_INDEX_OFFSET\n");
  1015. return -EINVAL;
  1016. }
  1017. r = evergreen_cs_track_check(p);
  1018. if (r) {
  1019. dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
  1020. return r;
  1021. }
  1022. break;
  1023. case PACKET3_DRAW_INDEX_OFFSET_2:
  1024. if (pkt->count != 3) {
  1025. DRM_ERROR("bad DRAW_INDEX_OFFSET_2\n");
  1026. return -EINVAL;
  1027. }
  1028. r = evergreen_cs_track_check(p);
  1029. if (r) {
  1030. dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
  1031. return r;
  1032. }
  1033. break;
  1034. case PACKET3_WAIT_REG_MEM:
  1035. if (pkt->count != 5) {
  1036. DRM_ERROR("bad WAIT_REG_MEM\n");
  1037. return -EINVAL;
  1038. }
  1039. /* bit 4 is reg (0) or mem (1) */
  1040. if (idx_value & 0x10) {
  1041. r = evergreen_cs_packet_next_reloc(p, &reloc);
  1042. if (r) {
  1043. DRM_ERROR("bad WAIT_REG_MEM\n");
  1044. return -EINVAL;
  1045. }
  1046. ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
  1047. ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
  1048. }
  1049. break;
  1050. case PACKET3_SURFACE_SYNC:
  1051. if (pkt->count != 3) {
  1052. DRM_ERROR("bad SURFACE_SYNC\n");
  1053. return -EINVAL;
  1054. }
  1055. /* 0xffffffff/0x0 is flush all cache flag */
  1056. if (radeon_get_ib_value(p, idx + 1) != 0xffffffff ||
  1057. radeon_get_ib_value(p, idx + 2) != 0) {
  1058. r = evergreen_cs_packet_next_reloc(p, &reloc);
  1059. if (r) {
  1060. DRM_ERROR("bad SURFACE_SYNC\n");
  1061. return -EINVAL;
  1062. }
  1063. ib[idx+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
  1064. }
  1065. break;
  1066. case PACKET3_EVENT_WRITE:
  1067. if (pkt->count != 2 && pkt->count != 0) {
  1068. DRM_ERROR("bad EVENT_WRITE\n");
  1069. return -EINVAL;
  1070. }
  1071. if (pkt->count) {
  1072. r = evergreen_cs_packet_next_reloc(p, &reloc);
  1073. if (r) {
  1074. DRM_ERROR("bad EVENT_WRITE\n");
  1075. return -EINVAL;
  1076. }
  1077. ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
  1078. ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
  1079. }
  1080. break;
  1081. case PACKET3_EVENT_WRITE_EOP:
  1082. if (pkt->count != 4) {
  1083. DRM_ERROR("bad EVENT_WRITE_EOP\n");
  1084. return -EINVAL;
  1085. }
  1086. r = evergreen_cs_packet_next_reloc(p, &reloc);
  1087. if (r) {
  1088. DRM_ERROR("bad EVENT_WRITE_EOP\n");
  1089. return -EINVAL;
  1090. }
  1091. ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
  1092. ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
  1093. break;
  1094. case PACKET3_EVENT_WRITE_EOS:
  1095. if (pkt->count != 3) {
  1096. DRM_ERROR("bad EVENT_WRITE_EOS\n");
  1097. return -EINVAL;
  1098. }
  1099. r = evergreen_cs_packet_next_reloc(p, &reloc);
  1100. if (r) {
  1101. DRM_ERROR("bad EVENT_WRITE_EOS\n");
  1102. return -EINVAL;
  1103. }
  1104. ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
  1105. ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
  1106. break;
  1107. case PACKET3_SET_CONFIG_REG:
  1108. start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START;
  1109. end_reg = 4 * pkt->count + start_reg - 4;
  1110. if ((start_reg < PACKET3_SET_CONFIG_REG_START) ||
  1111. (start_reg >= PACKET3_SET_CONFIG_REG_END) ||
  1112. (end_reg >= PACKET3_SET_CONFIG_REG_END)) {
  1113. DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
  1114. return -EINVAL;
  1115. }
  1116. for (i = 0; i < pkt->count; i++) {
  1117. reg = start_reg + (4 * i);
  1118. r = evergreen_cs_check_reg(p, reg, idx+1+i);
  1119. if (r)
  1120. return r;
  1121. }
  1122. break;
  1123. case PACKET3_SET_CONTEXT_REG:
  1124. start_reg = (idx_value << 2) + PACKET3_SET_CONTEXT_REG_START;
  1125. end_reg = 4 * pkt->count + start_reg - 4;
  1126. if ((start_reg < PACKET3_SET_CONTEXT_REG_START) ||
  1127. (start_reg >= PACKET3_SET_CONTEXT_REG_END) ||
  1128. (end_reg >= PACKET3_SET_CONTEXT_REG_END)) {
  1129. DRM_ERROR("bad PACKET3_SET_CONTEXT_REG\n");
  1130. return -EINVAL;
  1131. }
  1132. for (i = 0; i < pkt->count; i++) {
  1133. reg = start_reg + (4 * i);
  1134. r = evergreen_cs_check_reg(p, reg, idx+1+i);
  1135. if (r)
  1136. return r;
  1137. }
  1138. break;
  1139. case PACKET3_SET_RESOURCE:
  1140. if (pkt->count % 8) {
  1141. DRM_ERROR("bad SET_RESOURCE\n");
  1142. return -EINVAL;
  1143. }
  1144. start_reg = (idx_value << 2) + PACKET3_SET_RESOURCE_START;
  1145. end_reg = 4 * pkt->count + start_reg - 4;
  1146. if ((start_reg < PACKET3_SET_RESOURCE_START) ||
  1147. (start_reg >= PACKET3_SET_RESOURCE_END) ||
  1148. (end_reg >= PACKET3_SET_RESOURCE_END)) {
  1149. DRM_ERROR("bad SET_RESOURCE\n");
  1150. return -EINVAL;
  1151. }
  1152. for (i = 0; i < (pkt->count / 8); i++) {
  1153. struct radeon_bo *texture, *mipmap;
  1154. u32 size, offset;
  1155. switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) {
  1156. case SQ_TEX_VTX_VALID_TEXTURE:
  1157. /* tex base */
  1158. r = evergreen_cs_packet_next_reloc(p, &reloc);
  1159. if (r) {
  1160. DRM_ERROR("bad SET_RESOURCE (tex)\n");
  1161. return -EINVAL;
  1162. }
  1163. ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
  1164. if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
  1165. ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
  1166. else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
  1167. ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
  1168. texture = reloc->robj;
  1169. /* tex mip base */
  1170. r = evergreen_cs_packet_next_reloc(p, &reloc);
  1171. if (r) {
  1172. DRM_ERROR("bad SET_RESOURCE (tex)\n");
  1173. return -EINVAL;
  1174. }
  1175. ib[idx+1+(i*8)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
  1176. mipmap = reloc->robj;
  1177. r = evergreen_check_texture_resource(p, idx+1+(i*8),
  1178. texture, mipmap);
  1179. if (r)
  1180. return r;
  1181. break;
  1182. case SQ_TEX_VTX_VALID_BUFFER:
  1183. /* vtx base */
  1184. r = evergreen_cs_packet_next_reloc(p, &reloc);
  1185. if (r) {
  1186. DRM_ERROR("bad SET_RESOURCE (vtx)\n");
  1187. return -EINVAL;
  1188. }
  1189. offset = radeon_get_ib_value(p, idx+1+(i*8)+0);
  1190. size = radeon_get_ib_value(p, idx+1+(i*8)+1);
  1191. if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) {
  1192. /* force size to size of the buffer */
  1193. dev_warn(p->dev, "vbo resource seems too big for the bo\n");
  1194. ib[idx+1+(i*8)+1] = radeon_bo_size(reloc->robj);
  1195. }
  1196. ib[idx+1+(i*8)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff);
  1197. ib[idx+1+(i*8)+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
  1198. break;
  1199. case SQ_TEX_VTX_INVALID_TEXTURE:
  1200. case SQ_TEX_VTX_INVALID_BUFFER:
  1201. default:
  1202. DRM_ERROR("bad SET_RESOURCE\n");
  1203. return -EINVAL;
  1204. }
  1205. }
  1206. break;
  1207. case PACKET3_SET_ALU_CONST:
  1208. /* XXX fix me ALU const buffers only */
  1209. break;
  1210. case PACKET3_SET_BOOL_CONST:
  1211. start_reg = (idx_value << 2) + PACKET3_SET_BOOL_CONST_START;
  1212. end_reg = 4 * pkt->count + start_reg - 4;
  1213. if ((start_reg < PACKET3_SET_BOOL_CONST_START) ||
  1214. (start_reg >= PACKET3_SET_BOOL_CONST_END) ||
  1215. (end_reg >= PACKET3_SET_BOOL_CONST_END)) {
  1216. DRM_ERROR("bad SET_BOOL_CONST\n");
  1217. return -EINVAL;
  1218. }
  1219. break;
  1220. case PACKET3_SET_LOOP_CONST:
  1221. start_reg = (idx_value << 2) + PACKET3_SET_LOOP_CONST_START;
  1222. end_reg = 4 * pkt->count + start_reg - 4;
  1223. if ((start_reg < PACKET3_SET_LOOP_CONST_START) ||
  1224. (start_reg >= PACKET3_SET_LOOP_CONST_END) ||
  1225. (end_reg >= PACKET3_SET_LOOP_CONST_END)) {
  1226. DRM_ERROR("bad SET_LOOP_CONST\n");
  1227. return -EINVAL;
  1228. }
  1229. break;
  1230. case PACKET3_SET_CTL_CONST:
  1231. start_reg = (idx_value << 2) + PACKET3_SET_CTL_CONST_START;
  1232. end_reg = 4 * pkt->count + start_reg - 4;
  1233. if ((start_reg < PACKET3_SET_CTL_CONST_START) ||
  1234. (start_reg >= PACKET3_SET_CTL_CONST_END) ||
  1235. (end_reg >= PACKET3_SET_CTL_CONST_END)) {
  1236. DRM_ERROR("bad SET_CTL_CONST\n");
  1237. return -EINVAL;
  1238. }
  1239. break;
  1240. case PACKET3_SET_SAMPLER:
  1241. if (pkt->count % 3) {
  1242. DRM_ERROR("bad SET_SAMPLER\n");
  1243. return -EINVAL;
  1244. }
  1245. start_reg = (idx_value << 2) + PACKET3_SET_SAMPLER_START;
  1246. end_reg = 4 * pkt->count + start_reg - 4;
  1247. if ((start_reg < PACKET3_SET_SAMPLER_START) ||
  1248. (start_reg >= PACKET3_SET_SAMPLER_END) ||
  1249. (end_reg >= PACKET3_SET_SAMPLER_END)) {
  1250. DRM_ERROR("bad SET_SAMPLER\n");
  1251. return -EINVAL;
  1252. }
  1253. break;
  1254. case PACKET3_NOP:
  1255. break;
  1256. default:
  1257. DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode);
  1258. return -EINVAL;
  1259. }
  1260. return 0;
  1261. }
  1262. int evergreen_cs_parse(struct radeon_cs_parser *p)
  1263. {
  1264. struct radeon_cs_packet pkt;
  1265. struct evergreen_cs_track *track;
  1266. int r;
  1267. if (p->track == NULL) {
  1268. /* initialize tracker, we are in kms */
  1269. track = kzalloc(sizeof(*track), GFP_KERNEL);
  1270. if (track == NULL)
  1271. return -ENOMEM;
  1272. evergreen_cs_track_init(track);
  1273. track->npipes = p->rdev->config.evergreen.tiling_npipes;
  1274. track->nbanks = p->rdev->config.evergreen.tiling_nbanks;
  1275. track->group_size = p->rdev->config.evergreen.tiling_group_size;
  1276. p->track = track;
  1277. }
  1278. do {
  1279. r = evergreen_cs_packet_parse(p, &pkt, p->idx);
  1280. if (r) {
  1281. kfree(p->track);
  1282. p->track = NULL;
  1283. return r;
  1284. }
  1285. p->idx += pkt.count + 2;
  1286. switch (pkt.type) {
  1287. case PACKET_TYPE0:
  1288. r = evergreen_cs_parse_packet0(p, &pkt);
  1289. break;
  1290. case PACKET_TYPE2:
  1291. break;
  1292. case PACKET_TYPE3:
  1293. r = evergreen_packet3_check(p, &pkt);
  1294. break;
  1295. default:
  1296. DRM_ERROR("Unknown packet type %d !\n", pkt.type);
  1297. kfree(p->track);
  1298. p->track = NULL;
  1299. return -EINVAL;
  1300. }
  1301. if (r) {
  1302. kfree(p->track);
  1303. p->track = NULL;
  1304. return r;
  1305. }
  1306. } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
  1307. #if 0
  1308. for (r = 0; r < p->ib->length_dw; r++) {
  1309. printk(KERN_INFO "%05d 0x%08X\n", r, p->ib->ptr[r]);
  1310. mdelay(1);
  1311. }
  1312. #endif
  1313. kfree(p->track);
  1314. p->track = NULL;
  1315. return 0;
  1316. }