r200.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  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 "drmP.h"
  29. #include "drm.h"
  30. #include "radeon_drm.h"
  31. #include "radeon_reg.h"
  32. #include "radeon.h"
  33. #include "r200_reg_safe.h"
  34. #include "r100_track.h"
  35. static int r200_get_vtx_size_0(uint32_t vtx_fmt_0)
  36. {
  37. int vtx_size, i;
  38. vtx_size = 2;
  39. if (vtx_fmt_0 & R200_VTX_Z0)
  40. vtx_size++;
  41. if (vtx_fmt_0 & R200_VTX_W0)
  42. vtx_size++;
  43. /* blend weight */
  44. if (vtx_fmt_0 & (0x7 << R200_VTX_WEIGHT_COUNT_SHIFT))
  45. vtx_size += (vtx_fmt_0 >> R200_VTX_WEIGHT_COUNT_SHIFT) & 0x7;
  46. if (vtx_fmt_0 & R200_VTX_PV_MATRIX_SEL)
  47. vtx_size++;
  48. if (vtx_fmt_0 & R200_VTX_N0)
  49. vtx_size += 3;
  50. if (vtx_fmt_0 & R200_VTX_POINT_SIZE)
  51. vtx_size++;
  52. if (vtx_fmt_0 & R200_VTX_DISCRETE_FOG)
  53. vtx_size++;
  54. if (vtx_fmt_0 & R200_VTX_SHININESS_0)
  55. vtx_size++;
  56. if (vtx_fmt_0 & R200_VTX_SHININESS_1)
  57. vtx_size++;
  58. for (i = 0; i < 8; i++) {
  59. int color_size = (vtx_fmt_0 >> (11 + 2*i)) & 0x3;
  60. switch (color_size) {
  61. case 0: break;
  62. case 1: vtx_size++; break;
  63. case 2: vtx_size += 3; break;
  64. case 3: vtx_size += 4; break;
  65. }
  66. }
  67. if (vtx_fmt_0 & R200_VTX_XY1)
  68. vtx_size += 2;
  69. if (vtx_fmt_0 & R200_VTX_Z1)
  70. vtx_size++;
  71. if (vtx_fmt_0 & R200_VTX_W1)
  72. vtx_size++;
  73. if (vtx_fmt_0 & R200_VTX_N1)
  74. vtx_size += 3;
  75. return vtx_size;
  76. }
  77. static int r200_get_vtx_size_1(uint32_t vtx_fmt_1)
  78. {
  79. int vtx_size, i, tex_size;
  80. vtx_size = 0;
  81. for (i = 0; i < 6; i++) {
  82. tex_size = (vtx_fmt_1 >> (i * 3)) & 0x7;
  83. if (tex_size > 4)
  84. continue;
  85. vtx_size += tex_size;
  86. }
  87. return vtx_size;
  88. }
  89. int r200_packet0_check(struct radeon_cs_parser *p,
  90. struct radeon_cs_packet *pkt,
  91. unsigned idx, unsigned reg)
  92. {
  93. struct radeon_cs_reloc *reloc;
  94. struct r100_cs_track *track;
  95. volatile uint32_t *ib;
  96. uint32_t tmp;
  97. int r;
  98. int i;
  99. int face;
  100. u32 tile_flags = 0;
  101. u32 idx_value;
  102. ib = p->ib->ptr;
  103. track = (struct r100_cs_track *)p->track;
  104. idx_value = radeon_get_ib_value(p, idx);
  105. switch (reg) {
  106. case RADEON_CRTC_GUI_TRIG_VLINE:
  107. r = r100_cs_packet_parse_vline(p);
  108. if (r) {
  109. DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
  110. idx, reg);
  111. r100_cs_dump_packet(p, pkt);
  112. return r;
  113. }
  114. break;
  115. /* FIXME: only allow PACKET3 blit? easier to check for out of
  116. * range access */
  117. case RADEON_DST_PITCH_OFFSET:
  118. case RADEON_SRC_PITCH_OFFSET:
  119. r = r100_reloc_pitch_offset(p, pkt, idx, reg);
  120. if (r)
  121. return r;
  122. break;
  123. case RADEON_RB3D_DEPTHOFFSET:
  124. r = r100_cs_packet_next_reloc(p, &reloc);
  125. if (r) {
  126. DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
  127. idx, reg);
  128. r100_cs_dump_packet(p, pkt);
  129. return r;
  130. }
  131. track->zb.robj = reloc->robj;
  132. track->zb.offset = idx_value;
  133. ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
  134. break;
  135. case RADEON_RB3D_COLOROFFSET:
  136. r = r100_cs_packet_next_reloc(p, &reloc);
  137. if (r) {
  138. DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
  139. idx, reg);
  140. r100_cs_dump_packet(p, pkt);
  141. return r;
  142. }
  143. track->cb[0].robj = reloc->robj;
  144. track->cb[0].offset = idx_value;
  145. ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
  146. break;
  147. case R200_PP_TXOFFSET_0:
  148. case R200_PP_TXOFFSET_1:
  149. case R200_PP_TXOFFSET_2:
  150. case R200_PP_TXOFFSET_3:
  151. case R200_PP_TXOFFSET_4:
  152. case R200_PP_TXOFFSET_5:
  153. i = (reg - R200_PP_TXOFFSET_0) / 24;
  154. r = r100_cs_packet_next_reloc(p, &reloc);
  155. if (r) {
  156. DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
  157. idx, reg);
  158. r100_cs_dump_packet(p, pkt);
  159. return r;
  160. }
  161. ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
  162. track->textures[i].robj = reloc->robj;
  163. break;
  164. case R200_PP_CUBIC_OFFSET_F1_0:
  165. case R200_PP_CUBIC_OFFSET_F2_0:
  166. case R200_PP_CUBIC_OFFSET_F3_0:
  167. case R200_PP_CUBIC_OFFSET_F4_0:
  168. case R200_PP_CUBIC_OFFSET_F5_0:
  169. case R200_PP_CUBIC_OFFSET_F1_1:
  170. case R200_PP_CUBIC_OFFSET_F2_1:
  171. case R200_PP_CUBIC_OFFSET_F3_1:
  172. case R200_PP_CUBIC_OFFSET_F4_1:
  173. case R200_PP_CUBIC_OFFSET_F5_1:
  174. case R200_PP_CUBIC_OFFSET_F1_2:
  175. case R200_PP_CUBIC_OFFSET_F2_2:
  176. case R200_PP_CUBIC_OFFSET_F3_2:
  177. case R200_PP_CUBIC_OFFSET_F4_2:
  178. case R200_PP_CUBIC_OFFSET_F5_2:
  179. case R200_PP_CUBIC_OFFSET_F1_3:
  180. case R200_PP_CUBIC_OFFSET_F2_3:
  181. case R200_PP_CUBIC_OFFSET_F3_3:
  182. case R200_PP_CUBIC_OFFSET_F4_3:
  183. case R200_PP_CUBIC_OFFSET_F5_3:
  184. case R200_PP_CUBIC_OFFSET_F1_4:
  185. case R200_PP_CUBIC_OFFSET_F2_4:
  186. case R200_PP_CUBIC_OFFSET_F3_4:
  187. case R200_PP_CUBIC_OFFSET_F4_4:
  188. case R200_PP_CUBIC_OFFSET_F5_4:
  189. case R200_PP_CUBIC_OFFSET_F1_5:
  190. case R200_PP_CUBIC_OFFSET_F2_5:
  191. case R200_PP_CUBIC_OFFSET_F3_5:
  192. case R200_PP_CUBIC_OFFSET_F4_5:
  193. case R200_PP_CUBIC_OFFSET_F5_5:
  194. i = (reg - R200_PP_TXOFFSET_0) / 24;
  195. face = (reg - ((i * 24) + R200_PP_TXOFFSET_0)) / 4;
  196. r = r100_cs_packet_next_reloc(p, &reloc);
  197. if (r) {
  198. DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
  199. idx, reg);
  200. r100_cs_dump_packet(p, pkt);
  201. return r;
  202. }
  203. track->textures[i].cube_info[face - 1].offset = idx_value;
  204. ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
  205. track->textures[i].cube_info[face - 1].robj = reloc->robj;
  206. break;
  207. case RADEON_RE_WIDTH_HEIGHT:
  208. track->maxy = ((idx_value >> 16) & 0x7FF);
  209. break;
  210. case RADEON_RB3D_COLORPITCH:
  211. r = r100_cs_packet_next_reloc(p, &reloc);
  212. if (r) {
  213. DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
  214. idx, reg);
  215. r100_cs_dump_packet(p, pkt);
  216. return r;
  217. }
  218. if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
  219. tile_flags |= RADEON_COLOR_TILE_ENABLE;
  220. if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
  221. tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
  222. tmp = idx_value & ~(0x7 << 16);
  223. tmp |= tile_flags;
  224. ib[idx] = tmp;
  225. track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK;
  226. break;
  227. case RADEON_RB3D_DEPTHPITCH:
  228. track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK;
  229. break;
  230. case RADEON_RB3D_CNTL:
  231. switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
  232. case 7:
  233. case 8:
  234. case 9:
  235. case 11:
  236. case 12:
  237. track->cb[0].cpp = 1;
  238. break;
  239. case 3:
  240. case 4:
  241. case 15:
  242. track->cb[0].cpp = 2;
  243. break;
  244. case 6:
  245. track->cb[0].cpp = 4;
  246. break;
  247. default:
  248. DRM_ERROR("Invalid color buffer format (%d) !\n",
  249. ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f));
  250. return -EINVAL;
  251. }
  252. if (idx_value & RADEON_DEPTHXY_OFFSET_ENABLE) {
  253. DRM_ERROR("No support for depth xy offset in kms\n");
  254. return -EINVAL;
  255. }
  256. track->z_enabled = !!(idx_value & RADEON_Z_ENABLE);
  257. break;
  258. case RADEON_RB3D_ZSTENCILCNTL:
  259. switch (idx_value & 0xf) {
  260. case 0:
  261. track->zb.cpp = 2;
  262. break;
  263. case 2:
  264. case 3:
  265. case 4:
  266. case 5:
  267. case 9:
  268. case 11:
  269. track->zb.cpp = 4;
  270. break;
  271. default:
  272. break;
  273. }
  274. break;
  275. case RADEON_RB3D_ZPASS_ADDR:
  276. r = r100_cs_packet_next_reloc(p, &reloc);
  277. if (r) {
  278. DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
  279. idx, reg);
  280. r100_cs_dump_packet(p, pkt);
  281. return r;
  282. }
  283. ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
  284. break;
  285. case RADEON_PP_CNTL:
  286. {
  287. uint32_t temp = idx_value >> 4;
  288. for (i = 0; i < track->num_texture; i++)
  289. track->textures[i].enabled = !!(temp & (1 << i));
  290. }
  291. break;
  292. case RADEON_SE_VF_CNTL:
  293. track->vap_vf_cntl = idx_value;
  294. break;
  295. case 0x210c:
  296. /* VAP_VF_MAX_VTX_INDX */
  297. track->max_indx = idx_value & 0x00FFFFFFUL;
  298. break;
  299. case R200_SE_VTX_FMT_0:
  300. track->vtx_size = r200_get_vtx_size_0(idx_value);
  301. break;
  302. case R200_SE_VTX_FMT_1:
  303. track->vtx_size += r200_get_vtx_size_1(idx_value);
  304. break;
  305. case R200_PP_TXSIZE_0:
  306. case R200_PP_TXSIZE_1:
  307. case R200_PP_TXSIZE_2:
  308. case R200_PP_TXSIZE_3:
  309. case R200_PP_TXSIZE_4:
  310. case R200_PP_TXSIZE_5:
  311. i = (reg - R200_PP_TXSIZE_0) / 32;
  312. track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1;
  313. track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
  314. break;
  315. case R200_PP_TXPITCH_0:
  316. case R200_PP_TXPITCH_1:
  317. case R200_PP_TXPITCH_2:
  318. case R200_PP_TXPITCH_3:
  319. case R200_PP_TXPITCH_4:
  320. case R200_PP_TXPITCH_5:
  321. i = (reg - R200_PP_TXPITCH_0) / 32;
  322. track->textures[i].pitch = idx_value + 32;
  323. break;
  324. case R200_PP_TXFILTER_0:
  325. case R200_PP_TXFILTER_1:
  326. case R200_PP_TXFILTER_2:
  327. case R200_PP_TXFILTER_3:
  328. case R200_PP_TXFILTER_4:
  329. case R200_PP_TXFILTER_5:
  330. i = (reg - R200_PP_TXFILTER_0) / 32;
  331. track->textures[i].num_levels = ((idx_value & R200_MAX_MIP_LEVEL_MASK)
  332. >> R200_MAX_MIP_LEVEL_SHIFT);
  333. tmp = (idx_value >> 23) & 0x7;
  334. if (tmp == 2 || tmp == 6)
  335. track->textures[i].roundup_w = false;
  336. tmp = (idx_value >> 27) & 0x7;
  337. if (tmp == 2 || tmp == 6)
  338. track->textures[i].roundup_h = false;
  339. break;
  340. case R200_PP_TXMULTI_CTL_0:
  341. case R200_PP_TXMULTI_CTL_1:
  342. case R200_PP_TXMULTI_CTL_2:
  343. case R200_PP_TXMULTI_CTL_3:
  344. case R200_PP_TXMULTI_CTL_4:
  345. case R200_PP_TXMULTI_CTL_5:
  346. i = (reg - R200_PP_TXMULTI_CTL_0) / 32;
  347. break;
  348. case R200_PP_TXFORMAT_X_0:
  349. case R200_PP_TXFORMAT_X_1:
  350. case R200_PP_TXFORMAT_X_2:
  351. case R200_PP_TXFORMAT_X_3:
  352. case R200_PP_TXFORMAT_X_4:
  353. case R200_PP_TXFORMAT_X_5:
  354. i = (reg - R200_PP_TXFORMAT_X_0) / 32;
  355. track->textures[i].txdepth = idx_value & 0x7;
  356. tmp = (idx_value >> 16) & 0x3;
  357. /* 2D, 3D, CUBE */
  358. switch (tmp) {
  359. case 0:
  360. case 5:
  361. case 6:
  362. case 7:
  363. track->textures[i].tex_coord_type = 0;
  364. break;
  365. case 1:
  366. track->textures[i].tex_coord_type = 1;
  367. break;
  368. case 2:
  369. track->textures[i].tex_coord_type = 2;
  370. break;
  371. }
  372. break;
  373. case R200_PP_TXFORMAT_0:
  374. case R200_PP_TXFORMAT_1:
  375. case R200_PP_TXFORMAT_2:
  376. case R200_PP_TXFORMAT_3:
  377. case R200_PP_TXFORMAT_4:
  378. case R200_PP_TXFORMAT_5:
  379. i = (reg - R200_PP_TXFORMAT_0) / 32;
  380. if (idx_value & R200_TXFORMAT_NON_POWER2) {
  381. track->textures[i].use_pitch = 1;
  382. } else {
  383. track->textures[i].use_pitch = 0;
  384. track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
  385. track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
  386. }
  387. switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) {
  388. case R200_TXFORMAT_I8:
  389. case R200_TXFORMAT_RGB332:
  390. case R200_TXFORMAT_Y8:
  391. track->textures[i].cpp = 1;
  392. break;
  393. case R200_TXFORMAT_AI88:
  394. case R200_TXFORMAT_ARGB1555:
  395. case R200_TXFORMAT_RGB565:
  396. case R200_TXFORMAT_ARGB4444:
  397. case R200_TXFORMAT_VYUY422:
  398. case R200_TXFORMAT_YVYU422:
  399. case R200_TXFORMAT_LDVDU655:
  400. case R200_TXFORMAT_DVDU88:
  401. case R200_TXFORMAT_AVYU4444:
  402. track->textures[i].cpp = 2;
  403. break;
  404. case R200_TXFORMAT_ARGB8888:
  405. case R200_TXFORMAT_RGBA8888:
  406. case R200_TXFORMAT_ABGR8888:
  407. case R200_TXFORMAT_BGR111110:
  408. case R200_TXFORMAT_LDVDU8888:
  409. track->textures[i].cpp = 4;
  410. break;
  411. case R200_TXFORMAT_DXT1:
  412. track->textures[i].cpp = 1;
  413. track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
  414. break;
  415. case R200_TXFORMAT_DXT23:
  416. case R200_TXFORMAT_DXT45:
  417. track->textures[i].cpp = 1;
  418. track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
  419. break;
  420. }
  421. track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf);
  422. track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf);
  423. break;
  424. case R200_PP_CUBIC_FACES_0:
  425. case R200_PP_CUBIC_FACES_1:
  426. case R200_PP_CUBIC_FACES_2:
  427. case R200_PP_CUBIC_FACES_3:
  428. case R200_PP_CUBIC_FACES_4:
  429. case R200_PP_CUBIC_FACES_5:
  430. tmp = idx_value;
  431. i = (reg - R200_PP_CUBIC_FACES_0) / 32;
  432. for (face = 0; face < 4; face++) {
  433. track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf);
  434. track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf);
  435. }
  436. break;
  437. default:
  438. printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
  439. reg, idx);
  440. return -EINVAL;
  441. }
  442. return 0;
  443. }
  444. void r200_set_safe_registers(struct radeon_device *rdev)
  445. {
  446. rdev->config.r100.reg_safe_bm = r200_reg_safe_bm;
  447. rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm);
  448. }