0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include <linux/pci.h>
0032 #include <linux/slab.h>
0033 #include <linux/uaccess.h>
0034
0035 #include <drm/drm_device.h>
0036 #include <drm/drm_file.h>
0037 #include <drm/drm_print.h>
0038 #include <drm/r128_drm.h>
0039
0040 #include "r128_drv.h"
0041
0042
0043
0044
0045
0046 static void r128_emit_clip_rects(drm_r128_private_t *dev_priv,
0047 struct drm_clip_rect *boxes, int count)
0048 {
0049 u32 aux_sc_cntl = 0x00000000;
0050 RING_LOCALS;
0051 DRM_DEBUG("\n");
0052
0053 BEGIN_RING((count < 3 ? count : 3) * 5 + 2);
0054
0055 if (count >= 1) {
0056 OUT_RING(CCE_PACKET0(R128_AUX1_SC_LEFT, 3));
0057 OUT_RING(boxes[0].x1);
0058 OUT_RING(boxes[0].x2 - 1);
0059 OUT_RING(boxes[0].y1);
0060 OUT_RING(boxes[0].y2 - 1);
0061
0062 aux_sc_cntl |= (R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR);
0063 }
0064 if (count >= 2) {
0065 OUT_RING(CCE_PACKET0(R128_AUX2_SC_LEFT, 3));
0066 OUT_RING(boxes[1].x1);
0067 OUT_RING(boxes[1].x2 - 1);
0068 OUT_RING(boxes[1].y1);
0069 OUT_RING(boxes[1].y2 - 1);
0070
0071 aux_sc_cntl |= (R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR);
0072 }
0073 if (count >= 3) {
0074 OUT_RING(CCE_PACKET0(R128_AUX3_SC_LEFT, 3));
0075 OUT_RING(boxes[2].x1);
0076 OUT_RING(boxes[2].x2 - 1);
0077 OUT_RING(boxes[2].y1);
0078 OUT_RING(boxes[2].y2 - 1);
0079
0080 aux_sc_cntl |= (R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR);
0081 }
0082
0083 OUT_RING(CCE_PACKET0(R128_AUX_SC_CNTL, 0));
0084 OUT_RING(aux_sc_cntl);
0085
0086 ADVANCE_RING();
0087 }
0088
0089 static __inline__ void r128_emit_core(drm_r128_private_t *dev_priv)
0090 {
0091 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
0092 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
0093 RING_LOCALS;
0094 DRM_DEBUG("\n");
0095
0096 BEGIN_RING(2);
0097
0098 OUT_RING(CCE_PACKET0(R128_SCALE_3D_CNTL, 0));
0099 OUT_RING(ctx->scale_3d_cntl);
0100
0101 ADVANCE_RING();
0102 }
0103
0104 static __inline__ void r128_emit_context(drm_r128_private_t *dev_priv)
0105 {
0106 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
0107 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
0108 RING_LOCALS;
0109 DRM_DEBUG("\n");
0110
0111 BEGIN_RING(13);
0112
0113 OUT_RING(CCE_PACKET0(R128_DST_PITCH_OFFSET_C, 11));
0114 OUT_RING(ctx->dst_pitch_offset_c);
0115 OUT_RING(ctx->dp_gui_master_cntl_c);
0116 OUT_RING(ctx->sc_top_left_c);
0117 OUT_RING(ctx->sc_bottom_right_c);
0118 OUT_RING(ctx->z_offset_c);
0119 OUT_RING(ctx->z_pitch_c);
0120 OUT_RING(ctx->z_sten_cntl_c);
0121 OUT_RING(ctx->tex_cntl_c);
0122 OUT_RING(ctx->misc_3d_state_cntl_reg);
0123 OUT_RING(ctx->texture_clr_cmp_clr_c);
0124 OUT_RING(ctx->texture_clr_cmp_msk_c);
0125 OUT_RING(ctx->fog_color_c);
0126
0127 ADVANCE_RING();
0128 }
0129
0130 static __inline__ void r128_emit_setup(drm_r128_private_t *dev_priv)
0131 {
0132 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
0133 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
0134 RING_LOCALS;
0135 DRM_DEBUG("\n");
0136
0137 BEGIN_RING(3);
0138
0139 OUT_RING(CCE_PACKET1(R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP));
0140 OUT_RING(ctx->setup_cntl);
0141 OUT_RING(ctx->pm4_vc_fpu_setup);
0142
0143 ADVANCE_RING();
0144 }
0145
0146 static __inline__ void r128_emit_masks(drm_r128_private_t *dev_priv)
0147 {
0148 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
0149 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
0150 RING_LOCALS;
0151 DRM_DEBUG("\n");
0152
0153 BEGIN_RING(5);
0154
0155 OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0));
0156 OUT_RING(ctx->dp_write_mask);
0157
0158 OUT_RING(CCE_PACKET0(R128_STEN_REF_MASK_C, 1));
0159 OUT_RING(ctx->sten_ref_mask_c);
0160 OUT_RING(ctx->plane_3d_mask_c);
0161
0162 ADVANCE_RING();
0163 }
0164
0165 static __inline__ void r128_emit_window(drm_r128_private_t *dev_priv)
0166 {
0167 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
0168 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
0169 RING_LOCALS;
0170 DRM_DEBUG("\n");
0171
0172 BEGIN_RING(2);
0173
0174 OUT_RING(CCE_PACKET0(R128_WINDOW_XY_OFFSET, 0));
0175 OUT_RING(ctx->window_xy_offset);
0176
0177 ADVANCE_RING();
0178 }
0179
0180 static __inline__ void r128_emit_tex0(drm_r128_private_t *dev_priv)
0181 {
0182 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
0183 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
0184 drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0];
0185 int i;
0186 RING_LOCALS;
0187 DRM_DEBUG("\n");
0188
0189 BEGIN_RING(7 + R128_MAX_TEXTURE_LEVELS);
0190
0191 OUT_RING(CCE_PACKET0(R128_PRIM_TEX_CNTL_C,
0192 2 + R128_MAX_TEXTURE_LEVELS));
0193 OUT_RING(tex->tex_cntl);
0194 OUT_RING(tex->tex_combine_cntl);
0195 OUT_RING(ctx->tex_size_pitch_c);
0196 for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++)
0197 OUT_RING(tex->tex_offset[i]);
0198
0199 OUT_RING(CCE_PACKET0(R128_CONSTANT_COLOR_C, 1));
0200 OUT_RING(ctx->constant_color_c);
0201 OUT_RING(tex->tex_border_color);
0202
0203 ADVANCE_RING();
0204 }
0205
0206 static __inline__ void r128_emit_tex1(drm_r128_private_t *dev_priv)
0207 {
0208 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
0209 drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1];
0210 int i;
0211 RING_LOCALS;
0212 DRM_DEBUG("\n");
0213
0214 BEGIN_RING(5 + R128_MAX_TEXTURE_LEVELS);
0215
0216 OUT_RING(CCE_PACKET0(R128_SEC_TEX_CNTL_C, 1 + R128_MAX_TEXTURE_LEVELS));
0217 OUT_RING(tex->tex_cntl);
0218 OUT_RING(tex->tex_combine_cntl);
0219 for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++)
0220 OUT_RING(tex->tex_offset[i]);
0221
0222 OUT_RING(CCE_PACKET0(R128_SEC_TEXTURE_BORDER_COLOR_C, 0));
0223 OUT_RING(tex->tex_border_color);
0224
0225 ADVANCE_RING();
0226 }
0227
0228 static void r128_emit_state(drm_r128_private_t *dev_priv)
0229 {
0230 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
0231 unsigned int dirty = sarea_priv->dirty;
0232
0233 DRM_DEBUG("dirty=0x%08x\n", dirty);
0234
0235 if (dirty & R128_UPLOAD_CORE) {
0236 r128_emit_core(dev_priv);
0237 sarea_priv->dirty &= ~R128_UPLOAD_CORE;
0238 }
0239
0240 if (dirty & R128_UPLOAD_CONTEXT) {
0241 r128_emit_context(dev_priv);
0242 sarea_priv->dirty &= ~R128_UPLOAD_CONTEXT;
0243 }
0244
0245 if (dirty & R128_UPLOAD_SETUP) {
0246 r128_emit_setup(dev_priv);
0247 sarea_priv->dirty &= ~R128_UPLOAD_SETUP;
0248 }
0249
0250 if (dirty & R128_UPLOAD_MASKS) {
0251 r128_emit_masks(dev_priv);
0252 sarea_priv->dirty &= ~R128_UPLOAD_MASKS;
0253 }
0254
0255 if (dirty & R128_UPLOAD_WINDOW) {
0256 r128_emit_window(dev_priv);
0257 sarea_priv->dirty &= ~R128_UPLOAD_WINDOW;
0258 }
0259
0260 if (dirty & R128_UPLOAD_TEX0) {
0261 r128_emit_tex0(dev_priv);
0262 sarea_priv->dirty &= ~R128_UPLOAD_TEX0;
0263 }
0264
0265 if (dirty & R128_UPLOAD_TEX1) {
0266 r128_emit_tex1(dev_priv);
0267 sarea_priv->dirty &= ~R128_UPLOAD_TEX1;
0268 }
0269
0270
0271 sarea_priv->context_state.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH;
0272
0273 sarea_priv->dirty &= ~R128_REQUIRE_QUIESCENCE;
0274 }
0275
0276 #if R128_PERFORMANCE_BOXES
0277
0278
0279
0280
0281 static void r128_clear_box(drm_r128_private_t *dev_priv,
0282 int x, int y, int w, int h, int r, int g, int b)
0283 {
0284 u32 pitch, offset;
0285 u32 fb_bpp, color;
0286 RING_LOCALS;
0287
0288 switch (dev_priv->fb_bpp) {
0289 case 16:
0290 fb_bpp = R128_GMC_DST_16BPP;
0291 color = (((r & 0xf8) << 8) |
0292 ((g & 0xfc) << 3) | ((b & 0xf8) >> 3));
0293 break;
0294 case 24:
0295 fb_bpp = R128_GMC_DST_24BPP;
0296 color = ((r << 16) | (g << 8) | b);
0297 break;
0298 case 32:
0299 fb_bpp = R128_GMC_DST_32BPP;
0300 color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
0301 break;
0302 default:
0303 return;
0304 }
0305
0306 offset = dev_priv->back_offset;
0307 pitch = dev_priv->back_pitch >> 3;
0308
0309 BEGIN_RING(6);
0310
0311 OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
0312 OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
0313 R128_GMC_BRUSH_SOLID_COLOR |
0314 fb_bpp |
0315 R128_GMC_SRC_DATATYPE_COLOR |
0316 R128_ROP3_P |
0317 R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_AUX_CLIP_DIS);
0318
0319 OUT_RING((pitch << 21) | (offset >> 5));
0320 OUT_RING(color);
0321
0322 OUT_RING((x << 16) | y);
0323 OUT_RING((w << 16) | h);
0324
0325 ADVANCE_RING();
0326 }
0327
0328 static void r128_cce_performance_boxes(drm_r128_private_t *dev_priv)
0329 {
0330 if (atomic_read(&dev_priv->idle_count) == 0)
0331 r128_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0);
0332 else
0333 atomic_set(&dev_priv->idle_count, 0);
0334 }
0335
0336 #endif
0337
0338
0339
0340
0341
0342 static void r128_print_dirty(const char *msg, unsigned int flags)
0343 {
0344 DRM_INFO("%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
0345 msg,
0346 flags,
0347 (flags & R128_UPLOAD_CORE) ? "core, " : "",
0348 (flags & R128_UPLOAD_CONTEXT) ? "context, " : "",
0349 (flags & R128_UPLOAD_SETUP) ? "setup, " : "",
0350 (flags & R128_UPLOAD_TEX0) ? "tex0, " : "",
0351 (flags & R128_UPLOAD_TEX1) ? "tex1, " : "",
0352 (flags & R128_UPLOAD_MASKS) ? "masks, " : "",
0353 (flags & R128_UPLOAD_WINDOW) ? "window, " : "",
0354 (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "",
0355 (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "");
0356 }
0357
0358 static void r128_cce_dispatch_clear(struct drm_device *dev,
0359 drm_r128_clear_t *clear)
0360 {
0361 drm_r128_private_t *dev_priv = dev->dev_private;
0362 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
0363 int nbox = sarea_priv->nbox;
0364 struct drm_clip_rect *pbox = sarea_priv->boxes;
0365 unsigned int flags = clear->flags;
0366 int i;
0367 RING_LOCALS;
0368 DRM_DEBUG("\n");
0369
0370 if (dev_priv->page_flipping && dev_priv->current_page == 1) {
0371 unsigned int tmp = flags;
0372
0373 flags &= ~(R128_FRONT | R128_BACK);
0374 if (tmp & R128_FRONT)
0375 flags |= R128_BACK;
0376 if (tmp & R128_BACK)
0377 flags |= R128_FRONT;
0378 }
0379
0380 for (i = 0; i < nbox; i++) {
0381 int x = pbox[i].x1;
0382 int y = pbox[i].y1;
0383 int w = pbox[i].x2 - x;
0384 int h = pbox[i].y2 - y;
0385
0386 DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n",
0387 pbox[i].x1, pbox[i].y1, pbox[i].x2,
0388 pbox[i].y2, flags);
0389
0390 if (flags & (R128_FRONT | R128_BACK)) {
0391 BEGIN_RING(2);
0392
0393 OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0));
0394 OUT_RING(clear->color_mask);
0395
0396 ADVANCE_RING();
0397 }
0398
0399 if (flags & R128_FRONT) {
0400 BEGIN_RING(6);
0401
0402 OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
0403 OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
0404 R128_GMC_BRUSH_SOLID_COLOR |
0405 (dev_priv->color_fmt << 8) |
0406 R128_GMC_SRC_DATATYPE_COLOR |
0407 R128_ROP3_P |
0408 R128_GMC_CLR_CMP_CNTL_DIS |
0409 R128_GMC_AUX_CLIP_DIS);
0410
0411 OUT_RING(dev_priv->front_pitch_offset_c);
0412 OUT_RING(clear->clear_color);
0413
0414 OUT_RING((x << 16) | y);
0415 OUT_RING((w << 16) | h);
0416
0417 ADVANCE_RING();
0418 }
0419
0420 if (flags & R128_BACK) {
0421 BEGIN_RING(6);
0422
0423 OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
0424 OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
0425 R128_GMC_BRUSH_SOLID_COLOR |
0426 (dev_priv->color_fmt << 8) |
0427 R128_GMC_SRC_DATATYPE_COLOR |
0428 R128_ROP3_P |
0429 R128_GMC_CLR_CMP_CNTL_DIS |
0430 R128_GMC_AUX_CLIP_DIS);
0431
0432 OUT_RING(dev_priv->back_pitch_offset_c);
0433 OUT_RING(clear->clear_color);
0434
0435 OUT_RING((x << 16) | y);
0436 OUT_RING((w << 16) | h);
0437
0438 ADVANCE_RING();
0439 }
0440
0441 if (flags & R128_DEPTH) {
0442 BEGIN_RING(6);
0443
0444 OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
0445 OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
0446 R128_GMC_BRUSH_SOLID_COLOR |
0447 (dev_priv->depth_fmt << 8) |
0448 R128_GMC_SRC_DATATYPE_COLOR |
0449 R128_ROP3_P |
0450 R128_GMC_CLR_CMP_CNTL_DIS |
0451 R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS);
0452
0453 OUT_RING(dev_priv->depth_pitch_offset_c);
0454 OUT_RING(clear->clear_depth);
0455
0456 OUT_RING((x << 16) | y);
0457 OUT_RING((w << 16) | h);
0458
0459 ADVANCE_RING();
0460 }
0461 }
0462 }
0463
0464 static void r128_cce_dispatch_swap(struct drm_device *dev)
0465 {
0466 drm_r128_private_t *dev_priv = dev->dev_private;
0467 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
0468 int nbox = sarea_priv->nbox;
0469 struct drm_clip_rect *pbox = sarea_priv->boxes;
0470 int i;
0471 RING_LOCALS;
0472 DRM_DEBUG("\n");
0473
0474 #if R128_PERFORMANCE_BOXES
0475
0476
0477 r128_cce_performance_boxes(dev_priv);
0478 #endif
0479
0480 for (i = 0; i < nbox; i++) {
0481 int x = pbox[i].x1;
0482 int y = pbox[i].y1;
0483 int w = pbox[i].x2 - x;
0484 int h = pbox[i].y2 - y;
0485
0486 BEGIN_RING(7);
0487
0488 OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5));
0489 OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL |
0490 R128_GMC_DST_PITCH_OFFSET_CNTL |
0491 R128_GMC_BRUSH_NONE |
0492 (dev_priv->color_fmt << 8) |
0493 R128_GMC_SRC_DATATYPE_COLOR |
0494 R128_ROP3_S |
0495 R128_DP_SRC_SOURCE_MEMORY |
0496 R128_GMC_CLR_CMP_CNTL_DIS |
0497 R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS);
0498
0499
0500
0501 if (dev_priv->current_page == 0) {
0502 OUT_RING(dev_priv->back_pitch_offset_c);
0503 OUT_RING(dev_priv->front_pitch_offset_c);
0504 } else {
0505 OUT_RING(dev_priv->front_pitch_offset_c);
0506 OUT_RING(dev_priv->back_pitch_offset_c);
0507 }
0508
0509 OUT_RING((x << 16) | y);
0510 OUT_RING((x << 16) | y);
0511 OUT_RING((w << 16) | h);
0512
0513 ADVANCE_RING();
0514 }
0515
0516
0517
0518
0519
0520 dev_priv->sarea_priv->last_frame++;
0521
0522 BEGIN_RING(2);
0523
0524 OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0));
0525 OUT_RING(dev_priv->sarea_priv->last_frame);
0526
0527 ADVANCE_RING();
0528 }
0529
0530 static void r128_cce_dispatch_flip(struct drm_device *dev)
0531 {
0532 drm_r128_private_t *dev_priv = dev->dev_private;
0533 RING_LOCALS;
0534 DRM_DEBUG("page=%d pfCurrentPage=%d\n",
0535 dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage);
0536
0537 #if R128_PERFORMANCE_BOXES
0538
0539
0540 r128_cce_performance_boxes(dev_priv);
0541 #endif
0542
0543 BEGIN_RING(4);
0544
0545 R128_WAIT_UNTIL_PAGE_FLIPPED();
0546 OUT_RING(CCE_PACKET0(R128_CRTC_OFFSET, 0));
0547
0548 if (dev_priv->current_page == 0)
0549 OUT_RING(dev_priv->back_offset);
0550 else
0551 OUT_RING(dev_priv->front_offset);
0552
0553 ADVANCE_RING();
0554
0555
0556
0557
0558
0559 dev_priv->sarea_priv->last_frame++;
0560 dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page =
0561 1 - dev_priv->current_page;
0562
0563 BEGIN_RING(2);
0564
0565 OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0));
0566 OUT_RING(dev_priv->sarea_priv->last_frame);
0567
0568 ADVANCE_RING();
0569 }
0570
0571 static void r128_cce_dispatch_vertex(struct drm_device *dev, struct drm_buf *buf)
0572 {
0573 drm_r128_private_t *dev_priv = dev->dev_private;
0574 drm_r128_buf_priv_t *buf_priv = buf->dev_private;
0575 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
0576 int format = sarea_priv->vc_format;
0577 int offset = buf->bus_address;
0578 int size = buf->used;
0579 int prim = buf_priv->prim;
0580 int i = 0;
0581 RING_LOCALS;
0582 DRM_DEBUG("buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox);
0583
0584 if (0)
0585 r128_print_dirty("dispatch_vertex", sarea_priv->dirty);
0586
0587 if (buf->used) {
0588 buf_priv->dispatched = 1;
0589
0590 if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS)
0591 r128_emit_state(dev_priv);
0592
0593 do {
0594
0595 if (i < sarea_priv->nbox) {
0596 r128_emit_clip_rects(dev_priv,
0597 &sarea_priv->boxes[i],
0598 sarea_priv->nbox - i);
0599 }
0600
0601
0602 BEGIN_RING(5);
0603
0604 OUT_RING(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM, 3));
0605 OUT_RING(offset);
0606 OUT_RING(size);
0607 OUT_RING(format);
0608 OUT_RING(prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST |
0609 (size << R128_CCE_VC_CNTL_NUM_SHIFT));
0610
0611 ADVANCE_RING();
0612
0613 i += 3;
0614 } while (i < sarea_priv->nbox);
0615 }
0616
0617 if (buf_priv->discard) {
0618 buf_priv->age = dev_priv->sarea_priv->last_dispatch;
0619
0620
0621 BEGIN_RING(2);
0622
0623 OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0));
0624 OUT_RING(buf_priv->age);
0625
0626 ADVANCE_RING();
0627
0628 buf->pending = 1;
0629 buf->used = 0;
0630
0631 buf_priv->dispatched = 0;
0632 }
0633
0634 dev_priv->sarea_priv->last_dispatch++;
0635
0636 sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;
0637 sarea_priv->nbox = 0;
0638 }
0639
0640 static void r128_cce_dispatch_indirect(struct drm_device *dev,
0641 struct drm_buf *buf, int start, int end)
0642 {
0643 drm_r128_private_t *dev_priv = dev->dev_private;
0644 drm_r128_buf_priv_t *buf_priv = buf->dev_private;
0645 RING_LOCALS;
0646 DRM_DEBUG("indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end);
0647
0648 if (start != end) {
0649 int offset = buf->bus_address + start;
0650 int dwords = (end - start + 3) / sizeof(u32);
0651
0652
0653
0654
0655
0656 if (dwords & 1) {
0657 u32 *data = (u32 *)
0658 ((char *)dev->agp_buffer_map->handle
0659 + buf->offset + start);
0660 data[dwords++] = cpu_to_le32(R128_CCE_PACKET2);
0661 }
0662
0663 buf_priv->dispatched = 1;
0664
0665
0666 BEGIN_RING(3);
0667
0668 OUT_RING(CCE_PACKET0(R128_PM4_IW_INDOFF, 1));
0669 OUT_RING(offset);
0670 OUT_RING(dwords);
0671
0672 ADVANCE_RING();
0673 }
0674
0675 if (buf_priv->discard) {
0676 buf_priv->age = dev_priv->sarea_priv->last_dispatch;
0677
0678
0679 BEGIN_RING(2);
0680
0681 OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0));
0682 OUT_RING(buf_priv->age);
0683
0684 ADVANCE_RING();
0685
0686 buf->pending = 1;
0687 buf->used = 0;
0688
0689 buf_priv->dispatched = 0;
0690 }
0691
0692 dev_priv->sarea_priv->last_dispatch++;
0693 }
0694
0695 static void r128_cce_dispatch_indices(struct drm_device *dev,
0696 struct drm_buf *buf,
0697 int start, int end, int count)
0698 {
0699 drm_r128_private_t *dev_priv = dev->dev_private;
0700 drm_r128_buf_priv_t *buf_priv = buf->dev_private;
0701 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
0702 int format = sarea_priv->vc_format;
0703 int offset = dev->agp_buffer_map->offset - dev_priv->cce_buffers_offset;
0704 int prim = buf_priv->prim;
0705 u32 *data;
0706 int dwords;
0707 int i = 0;
0708 RING_LOCALS;
0709 DRM_DEBUG("indices: s=%d e=%d c=%d\n", start, end, count);
0710
0711 if (0)
0712 r128_print_dirty("dispatch_indices", sarea_priv->dirty);
0713
0714 if (start != end) {
0715 buf_priv->dispatched = 1;
0716
0717 if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS)
0718 r128_emit_state(dev_priv);
0719
0720 dwords = (end - start + 3) / sizeof(u32);
0721
0722 data = (u32 *) ((char *)dev->agp_buffer_map->handle
0723 + buf->offset + start);
0724
0725 data[0] = cpu_to_le32(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM,
0726 dwords - 2));
0727
0728 data[1] = cpu_to_le32(offset);
0729 data[2] = cpu_to_le32(R128_MAX_VB_VERTS);
0730 data[3] = cpu_to_le32(format);
0731 data[4] = cpu_to_le32((prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
0732 (count << 16)));
0733
0734 if (count & 0x1) {
0735 #ifdef __LITTLE_ENDIAN
0736 data[dwords - 1] &= 0x0000ffff;
0737 #else
0738 data[dwords - 1] &= 0xffff0000;
0739 #endif
0740 }
0741
0742 do {
0743
0744 if (i < sarea_priv->nbox) {
0745 r128_emit_clip_rects(dev_priv,
0746 &sarea_priv->boxes[i],
0747 sarea_priv->nbox - i);
0748 }
0749
0750 r128_cce_dispatch_indirect(dev, buf, start, end);
0751
0752 i += 3;
0753 } while (i < sarea_priv->nbox);
0754 }
0755
0756 if (buf_priv->discard) {
0757 buf_priv->age = dev_priv->sarea_priv->last_dispatch;
0758
0759
0760 BEGIN_RING(2);
0761
0762 OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0));
0763 OUT_RING(buf_priv->age);
0764
0765 ADVANCE_RING();
0766
0767 buf->pending = 1;
0768
0769 buf_priv->dispatched = 0;
0770 }
0771
0772 dev_priv->sarea_priv->last_dispatch++;
0773
0774 sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;
0775 sarea_priv->nbox = 0;
0776 }
0777
0778 static int r128_cce_dispatch_blit(struct drm_device *dev,
0779 struct drm_file *file_priv,
0780 drm_r128_blit_t *blit)
0781 {
0782 drm_r128_private_t *dev_priv = dev->dev_private;
0783 struct drm_device_dma *dma = dev->dma;
0784 struct drm_buf *buf;
0785 drm_r128_buf_priv_t *buf_priv;
0786 u32 *data;
0787 int dword_shift, dwords;
0788 RING_LOCALS;
0789 DRM_DEBUG("\n");
0790
0791
0792
0793
0794
0795 switch (blit->format) {
0796 case R128_DATATYPE_ARGB8888:
0797 dword_shift = 0;
0798 break;
0799 case R128_DATATYPE_ARGB1555:
0800 case R128_DATATYPE_RGB565:
0801 case R128_DATATYPE_ARGB4444:
0802 case R128_DATATYPE_YVYU422:
0803 case R128_DATATYPE_VYUY422:
0804 dword_shift = 1;
0805 break;
0806 case R128_DATATYPE_CI8:
0807 case R128_DATATYPE_RGB8:
0808 dword_shift = 2;
0809 break;
0810 default:
0811 DRM_ERROR("invalid blit format %d\n", blit->format);
0812 return -EINVAL;
0813 }
0814
0815
0816
0817
0818
0819
0820 BEGIN_RING(2);
0821
0822 OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0));
0823 OUT_RING(R128_PC_RI_GUI | R128_PC_FLUSH_GUI);
0824
0825 ADVANCE_RING();
0826
0827
0828
0829 buf = dma->buflist[blit->idx];
0830 buf_priv = buf->dev_private;
0831
0832 if (buf->file_priv != file_priv) {
0833 DRM_ERROR("process %d using buffer owned by %p\n",
0834 task_pid_nr(current), buf->file_priv);
0835 return -EINVAL;
0836 }
0837 if (buf->pending) {
0838 DRM_ERROR("sending pending buffer %d\n", blit->idx);
0839 return -EINVAL;
0840 }
0841
0842 buf_priv->discard = 1;
0843
0844 dwords = (blit->width * blit->height) >> dword_shift;
0845
0846 data = (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
0847
0848 data[0] = cpu_to_le32(CCE_PACKET3(R128_CNTL_HOSTDATA_BLT, dwords + 6));
0849 data[1] = cpu_to_le32((R128_GMC_DST_PITCH_OFFSET_CNTL |
0850 R128_GMC_BRUSH_NONE |
0851 (blit->format << 8) |
0852 R128_GMC_SRC_DATATYPE_COLOR |
0853 R128_ROP3_S |
0854 R128_DP_SRC_SOURCE_HOST_DATA |
0855 R128_GMC_CLR_CMP_CNTL_DIS |
0856 R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS));
0857
0858 data[2] = cpu_to_le32((blit->pitch << 21) | (blit->offset >> 5));
0859 data[3] = cpu_to_le32(0xffffffff);
0860 data[4] = cpu_to_le32(0xffffffff);
0861 data[5] = cpu_to_le32((blit->y << 16) | blit->x);
0862 data[6] = cpu_to_le32((blit->height << 16) | blit->width);
0863 data[7] = cpu_to_le32(dwords);
0864
0865 buf->used = (dwords + 8) * sizeof(u32);
0866
0867 r128_cce_dispatch_indirect(dev, buf, 0, buf->used);
0868
0869
0870
0871
0872
0873 BEGIN_RING(2);
0874
0875 OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0));
0876 OUT_RING(R128_PC_FLUSH_GUI);
0877
0878 ADVANCE_RING();
0879
0880 return 0;
0881 }
0882
0883
0884
0885
0886
0887
0888
0889
0890 static int r128_cce_dispatch_write_span(struct drm_device *dev,
0891 drm_r128_depth_t *depth)
0892 {
0893 drm_r128_private_t *dev_priv = dev->dev_private;
0894 int count, x, y;
0895 u32 *buffer;
0896 u8 *mask;
0897 int i, buffer_size, mask_size;
0898 RING_LOCALS;
0899 DRM_DEBUG("\n");
0900
0901 count = depth->n;
0902 if (count > 4096 || count <= 0)
0903 return -EMSGSIZE;
0904
0905 if (copy_from_user(&x, depth->x, sizeof(x)))
0906 return -EFAULT;
0907 if (copy_from_user(&y, depth->y, sizeof(y)))
0908 return -EFAULT;
0909
0910 buffer_size = depth->n * sizeof(u32);
0911 buffer = memdup_user(depth->buffer, buffer_size);
0912 if (IS_ERR(buffer))
0913 return PTR_ERR(buffer);
0914
0915 mask_size = depth->n;
0916 if (depth->mask) {
0917 mask = memdup_user(depth->mask, mask_size);
0918 if (IS_ERR(mask)) {
0919 kfree(buffer);
0920 return PTR_ERR(mask);
0921 }
0922
0923 for (i = 0; i < count; i++, x++) {
0924 if (mask[i]) {
0925 BEGIN_RING(6);
0926
0927 OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
0928 OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
0929 R128_GMC_BRUSH_SOLID_COLOR |
0930 (dev_priv->depth_fmt << 8) |
0931 R128_GMC_SRC_DATATYPE_COLOR |
0932 R128_ROP3_P |
0933 R128_GMC_CLR_CMP_CNTL_DIS |
0934 R128_GMC_WR_MSK_DIS);
0935
0936 OUT_RING(dev_priv->depth_pitch_offset_c);
0937 OUT_RING(buffer[i]);
0938
0939 OUT_RING((x << 16) | y);
0940 OUT_RING((1 << 16) | 1);
0941
0942 ADVANCE_RING();
0943 }
0944 }
0945
0946 kfree(mask);
0947 } else {
0948 for (i = 0; i < count; i++, x++) {
0949 BEGIN_RING(6);
0950
0951 OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
0952 OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
0953 R128_GMC_BRUSH_SOLID_COLOR |
0954 (dev_priv->depth_fmt << 8) |
0955 R128_GMC_SRC_DATATYPE_COLOR |
0956 R128_ROP3_P |
0957 R128_GMC_CLR_CMP_CNTL_DIS |
0958 R128_GMC_WR_MSK_DIS);
0959
0960 OUT_RING(dev_priv->depth_pitch_offset_c);
0961 OUT_RING(buffer[i]);
0962
0963 OUT_RING((x << 16) | y);
0964 OUT_RING((1 << 16) | 1);
0965
0966 ADVANCE_RING();
0967 }
0968 }
0969
0970 kfree(buffer);
0971
0972 return 0;
0973 }
0974
0975 static int r128_cce_dispatch_write_pixels(struct drm_device *dev,
0976 drm_r128_depth_t *depth)
0977 {
0978 drm_r128_private_t *dev_priv = dev->dev_private;
0979 int count, *x, *y;
0980 u32 *buffer;
0981 u8 *mask;
0982 int i, xbuf_size, ybuf_size, buffer_size, mask_size;
0983 RING_LOCALS;
0984 DRM_DEBUG("\n");
0985
0986 count = depth->n;
0987 if (count > 4096 || count <= 0)
0988 return -EMSGSIZE;
0989
0990 xbuf_size = count * sizeof(*x);
0991 ybuf_size = count * sizeof(*y);
0992 x = memdup_user(depth->x, xbuf_size);
0993 if (IS_ERR(x))
0994 return PTR_ERR(x);
0995 y = memdup_user(depth->y, ybuf_size);
0996 if (IS_ERR(y)) {
0997 kfree(x);
0998 return PTR_ERR(y);
0999 }
1000 buffer_size = depth->n * sizeof(u32);
1001 buffer = memdup_user(depth->buffer, buffer_size);
1002 if (IS_ERR(buffer)) {
1003 kfree(x);
1004 kfree(y);
1005 return PTR_ERR(buffer);
1006 }
1007
1008 if (depth->mask) {
1009 mask_size = depth->n;
1010 mask = memdup_user(depth->mask, mask_size);
1011 if (IS_ERR(mask)) {
1012 kfree(x);
1013 kfree(y);
1014 kfree(buffer);
1015 return PTR_ERR(mask);
1016 }
1017
1018 for (i = 0; i < count; i++) {
1019 if (mask[i]) {
1020 BEGIN_RING(6);
1021
1022 OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
1023 OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
1024 R128_GMC_BRUSH_SOLID_COLOR |
1025 (dev_priv->depth_fmt << 8) |
1026 R128_GMC_SRC_DATATYPE_COLOR |
1027 R128_ROP3_P |
1028 R128_GMC_CLR_CMP_CNTL_DIS |
1029 R128_GMC_WR_MSK_DIS);
1030
1031 OUT_RING(dev_priv->depth_pitch_offset_c);
1032 OUT_RING(buffer[i]);
1033
1034 OUT_RING((x[i] << 16) | y[i]);
1035 OUT_RING((1 << 16) | 1);
1036
1037 ADVANCE_RING();
1038 }
1039 }
1040
1041 kfree(mask);
1042 } else {
1043 for (i = 0; i < count; i++) {
1044 BEGIN_RING(6);
1045
1046 OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
1047 OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
1048 R128_GMC_BRUSH_SOLID_COLOR |
1049 (dev_priv->depth_fmt << 8) |
1050 R128_GMC_SRC_DATATYPE_COLOR |
1051 R128_ROP3_P |
1052 R128_GMC_CLR_CMP_CNTL_DIS |
1053 R128_GMC_WR_MSK_DIS);
1054
1055 OUT_RING(dev_priv->depth_pitch_offset_c);
1056 OUT_RING(buffer[i]);
1057
1058 OUT_RING((x[i] << 16) | y[i]);
1059 OUT_RING((1 << 16) | 1);
1060
1061 ADVANCE_RING();
1062 }
1063 }
1064
1065 kfree(x);
1066 kfree(y);
1067 kfree(buffer);
1068
1069 return 0;
1070 }
1071
1072 static int r128_cce_dispatch_read_span(struct drm_device *dev,
1073 drm_r128_depth_t *depth)
1074 {
1075 drm_r128_private_t *dev_priv = dev->dev_private;
1076 int count, x, y;
1077 RING_LOCALS;
1078 DRM_DEBUG("\n");
1079
1080 count = depth->n;
1081 if (count > 4096 || count <= 0)
1082 return -EMSGSIZE;
1083
1084 if (copy_from_user(&x, depth->x, sizeof(x)))
1085 return -EFAULT;
1086 if (copy_from_user(&y, depth->y, sizeof(y)))
1087 return -EFAULT;
1088
1089 BEGIN_RING(7);
1090
1091 OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5));
1092 OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL |
1093 R128_GMC_DST_PITCH_OFFSET_CNTL |
1094 R128_GMC_BRUSH_NONE |
1095 (dev_priv->depth_fmt << 8) |
1096 R128_GMC_SRC_DATATYPE_COLOR |
1097 R128_ROP3_S |
1098 R128_DP_SRC_SOURCE_MEMORY |
1099 R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS);
1100
1101 OUT_RING(dev_priv->depth_pitch_offset_c);
1102 OUT_RING(dev_priv->span_pitch_offset_c);
1103
1104 OUT_RING((x << 16) | y);
1105 OUT_RING((0 << 16) | 0);
1106 OUT_RING((count << 16) | 1);
1107
1108 ADVANCE_RING();
1109
1110 return 0;
1111 }
1112
1113 static int r128_cce_dispatch_read_pixels(struct drm_device *dev,
1114 drm_r128_depth_t *depth)
1115 {
1116 drm_r128_private_t *dev_priv = dev->dev_private;
1117 int count, *x, *y;
1118 int i, xbuf_size, ybuf_size;
1119 RING_LOCALS;
1120 DRM_DEBUG("\n");
1121
1122 count = depth->n;
1123 if (count > 4096 || count <= 0)
1124 return -EMSGSIZE;
1125
1126 if (count > dev_priv->depth_pitch)
1127 count = dev_priv->depth_pitch;
1128
1129 xbuf_size = count * sizeof(*x);
1130 ybuf_size = count * sizeof(*y);
1131 x = kmalloc(xbuf_size, GFP_KERNEL);
1132 if (x == NULL)
1133 return -ENOMEM;
1134 y = kmalloc(ybuf_size, GFP_KERNEL);
1135 if (y == NULL) {
1136 kfree(x);
1137 return -ENOMEM;
1138 }
1139 if (copy_from_user(x, depth->x, xbuf_size)) {
1140 kfree(x);
1141 kfree(y);
1142 return -EFAULT;
1143 }
1144 if (copy_from_user(y, depth->y, ybuf_size)) {
1145 kfree(x);
1146 kfree(y);
1147 return -EFAULT;
1148 }
1149
1150 for (i = 0; i < count; i++) {
1151 BEGIN_RING(7);
1152
1153 OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5));
1154 OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL |
1155 R128_GMC_DST_PITCH_OFFSET_CNTL |
1156 R128_GMC_BRUSH_NONE |
1157 (dev_priv->depth_fmt << 8) |
1158 R128_GMC_SRC_DATATYPE_COLOR |
1159 R128_ROP3_S |
1160 R128_DP_SRC_SOURCE_MEMORY |
1161 R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS);
1162
1163 OUT_RING(dev_priv->depth_pitch_offset_c);
1164 OUT_RING(dev_priv->span_pitch_offset_c);
1165
1166 OUT_RING((x[i] << 16) | y[i]);
1167 OUT_RING((i << 16) | 0);
1168 OUT_RING((1 << 16) | 1);
1169
1170 ADVANCE_RING();
1171 }
1172
1173 kfree(x);
1174 kfree(y);
1175
1176 return 0;
1177 }
1178
1179
1180
1181
1182
1183 static void r128_cce_dispatch_stipple(struct drm_device *dev, u32 *stipple)
1184 {
1185 drm_r128_private_t *dev_priv = dev->dev_private;
1186 int i;
1187 RING_LOCALS;
1188 DRM_DEBUG("\n");
1189
1190 BEGIN_RING(33);
1191
1192 OUT_RING(CCE_PACKET0(R128_BRUSH_DATA0, 31));
1193 for (i = 0; i < 32; i++)
1194 OUT_RING(stipple[i]);
1195
1196 ADVANCE_RING();
1197 }
1198
1199
1200
1201
1202
1203 static int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *file_priv)
1204 {
1205 drm_r128_private_t *dev_priv = dev->dev_private;
1206 drm_r128_sarea_t *sarea_priv;
1207 drm_r128_clear_t *clear = data;
1208 DRM_DEBUG("\n");
1209
1210 LOCK_TEST_WITH_RETURN(dev, file_priv);
1211
1212 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1213
1214 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1215
1216 sarea_priv = dev_priv->sarea_priv;
1217
1218 if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
1219 sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
1220
1221 r128_cce_dispatch_clear(dev, clear);
1222 COMMIT_RING();
1223
1224
1225
1226 dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
1227
1228 return 0;
1229 }
1230
1231 static int r128_do_init_pageflip(struct drm_device *dev)
1232 {
1233 drm_r128_private_t *dev_priv = dev->dev_private;
1234 DRM_DEBUG("\n");
1235
1236 dev_priv->crtc_offset = R128_READ(R128_CRTC_OFFSET);
1237 dev_priv->crtc_offset_cntl = R128_READ(R128_CRTC_OFFSET_CNTL);
1238
1239 R128_WRITE(R128_CRTC_OFFSET, dev_priv->front_offset);
1240 R128_WRITE(R128_CRTC_OFFSET_CNTL,
1241 dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL);
1242
1243 dev_priv->page_flipping = 1;
1244 dev_priv->current_page = 0;
1245 dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page;
1246
1247 return 0;
1248 }
1249
1250 static int r128_do_cleanup_pageflip(struct drm_device *dev)
1251 {
1252 drm_r128_private_t *dev_priv = dev->dev_private;
1253 DRM_DEBUG("\n");
1254
1255 R128_WRITE(R128_CRTC_OFFSET, dev_priv->crtc_offset);
1256 R128_WRITE(R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl);
1257
1258 if (dev_priv->current_page != 0) {
1259 r128_cce_dispatch_flip(dev);
1260 COMMIT_RING();
1261 }
1262
1263 dev_priv->page_flipping = 0;
1264 return 0;
1265 }
1266
1267
1268
1269
1270
1271 static int r128_cce_flip(struct drm_device *dev, void *data, struct drm_file *file_priv)
1272 {
1273 drm_r128_private_t *dev_priv = dev->dev_private;
1274 DRM_DEBUG("\n");
1275
1276 LOCK_TEST_WITH_RETURN(dev, file_priv);
1277
1278 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1279
1280 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1281
1282 if (!dev_priv->page_flipping)
1283 r128_do_init_pageflip(dev);
1284
1285 r128_cce_dispatch_flip(dev);
1286
1287 COMMIT_RING();
1288 return 0;
1289 }
1290
1291 static int r128_cce_swap(struct drm_device *dev, void *data, struct drm_file *file_priv)
1292 {
1293 drm_r128_private_t *dev_priv = dev->dev_private;
1294 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
1295 DRM_DEBUG("\n");
1296
1297 LOCK_TEST_WITH_RETURN(dev, file_priv);
1298
1299 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1300
1301 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1302
1303 if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
1304 sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
1305
1306 r128_cce_dispatch_swap(dev);
1307 dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
1308 R128_UPLOAD_MASKS);
1309
1310 COMMIT_RING();
1311 return 0;
1312 }
1313
1314 static int r128_cce_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv)
1315 {
1316 drm_r128_private_t *dev_priv = dev->dev_private;
1317 struct drm_device_dma *dma = dev->dma;
1318 struct drm_buf *buf;
1319 drm_r128_buf_priv_t *buf_priv;
1320 drm_r128_vertex_t *vertex = data;
1321
1322 LOCK_TEST_WITH_RETURN(dev, file_priv);
1323
1324 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1325
1326 DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
1327 task_pid_nr(current), vertex->idx, vertex->count, vertex->discard);
1328
1329 if (vertex->idx < 0 || vertex->idx >= dma->buf_count) {
1330 DRM_ERROR("buffer index %d (of %d max)\n",
1331 vertex->idx, dma->buf_count - 1);
1332 return -EINVAL;
1333 }
1334 if (vertex->prim < 0 ||
1335 vertex->prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) {
1336 DRM_ERROR("buffer prim %d\n", vertex->prim);
1337 return -EINVAL;
1338 }
1339
1340 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1341 VB_AGE_TEST_WITH_RETURN(dev_priv);
1342
1343 buf = dma->buflist[vertex->idx];
1344 buf_priv = buf->dev_private;
1345
1346 if (buf->file_priv != file_priv) {
1347 DRM_ERROR("process %d using buffer owned by %p\n",
1348 task_pid_nr(current), buf->file_priv);
1349 return -EINVAL;
1350 }
1351 if (buf->pending) {
1352 DRM_ERROR("sending pending buffer %d\n", vertex->idx);
1353 return -EINVAL;
1354 }
1355
1356 buf->used = vertex->count;
1357 buf_priv->prim = vertex->prim;
1358 buf_priv->discard = vertex->discard;
1359
1360 r128_cce_dispatch_vertex(dev, buf);
1361
1362 COMMIT_RING();
1363 return 0;
1364 }
1365
1366 static int r128_cce_indices(struct drm_device *dev, void *data, struct drm_file *file_priv)
1367 {
1368 drm_r128_private_t *dev_priv = dev->dev_private;
1369 struct drm_device_dma *dma = dev->dma;
1370 struct drm_buf *buf;
1371 drm_r128_buf_priv_t *buf_priv;
1372 drm_r128_indices_t *elts = data;
1373 int count;
1374
1375 LOCK_TEST_WITH_RETURN(dev, file_priv);
1376
1377 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1378
1379 DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", task_pid_nr(current),
1380 elts->idx, elts->start, elts->end, elts->discard);
1381
1382 if (elts->idx < 0 || elts->idx >= dma->buf_count) {
1383 DRM_ERROR("buffer index %d (of %d max)\n",
1384 elts->idx, dma->buf_count - 1);
1385 return -EINVAL;
1386 }
1387 if (elts->prim < 0 ||
1388 elts->prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) {
1389 DRM_ERROR("buffer prim %d\n", elts->prim);
1390 return -EINVAL;
1391 }
1392
1393 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1394 VB_AGE_TEST_WITH_RETURN(dev_priv);
1395
1396 buf = dma->buflist[elts->idx];
1397 buf_priv = buf->dev_private;
1398
1399 if (buf->file_priv != file_priv) {
1400 DRM_ERROR("process %d using buffer owned by %p\n",
1401 task_pid_nr(current), buf->file_priv);
1402 return -EINVAL;
1403 }
1404 if (buf->pending) {
1405 DRM_ERROR("sending pending buffer %d\n", elts->idx);
1406 return -EINVAL;
1407 }
1408
1409 count = (elts->end - elts->start) / sizeof(u16);
1410 elts->start -= R128_INDEX_PRIM_OFFSET;
1411
1412 if (elts->start & 0x7) {
1413 DRM_ERROR("misaligned buffer 0x%x\n", elts->start);
1414 return -EINVAL;
1415 }
1416 if (elts->start < buf->used) {
1417 DRM_ERROR("no header 0x%x - 0x%x\n", elts->start, buf->used);
1418 return -EINVAL;
1419 }
1420
1421 buf->used = elts->end;
1422 buf_priv->prim = elts->prim;
1423 buf_priv->discard = elts->discard;
1424
1425 r128_cce_dispatch_indices(dev, buf, elts->start, elts->end, count);
1426
1427 COMMIT_RING();
1428 return 0;
1429 }
1430
1431 static int r128_cce_blit(struct drm_device *dev, void *data, struct drm_file *file_priv)
1432 {
1433 struct drm_device_dma *dma = dev->dma;
1434 drm_r128_private_t *dev_priv = dev->dev_private;
1435 drm_r128_blit_t *blit = data;
1436 int ret;
1437
1438 LOCK_TEST_WITH_RETURN(dev, file_priv);
1439
1440 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1441
1442 DRM_DEBUG("pid=%d index=%d\n", task_pid_nr(current), blit->idx);
1443
1444 if (blit->idx < 0 || blit->idx >= dma->buf_count) {
1445 DRM_ERROR("buffer index %d (of %d max)\n",
1446 blit->idx, dma->buf_count - 1);
1447 return -EINVAL;
1448 }
1449
1450 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1451 VB_AGE_TEST_WITH_RETURN(dev_priv);
1452
1453 ret = r128_cce_dispatch_blit(dev, file_priv, blit);
1454
1455 COMMIT_RING();
1456 return ret;
1457 }
1458
1459 int r128_cce_depth(struct drm_device *dev, void *data, struct drm_file *file_priv)
1460 {
1461 drm_r128_private_t *dev_priv = dev->dev_private;
1462 drm_r128_depth_t *depth = data;
1463 int ret;
1464
1465 LOCK_TEST_WITH_RETURN(dev, file_priv);
1466
1467 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1468
1469 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1470
1471 ret = -EINVAL;
1472 switch (depth->func) {
1473 case R128_WRITE_SPAN:
1474 ret = r128_cce_dispatch_write_span(dev, depth);
1475 break;
1476 case R128_WRITE_PIXELS:
1477 ret = r128_cce_dispatch_write_pixels(dev, depth);
1478 break;
1479 case R128_READ_SPAN:
1480 ret = r128_cce_dispatch_read_span(dev, depth);
1481 break;
1482 case R128_READ_PIXELS:
1483 ret = r128_cce_dispatch_read_pixels(dev, depth);
1484 break;
1485 }
1486
1487 COMMIT_RING();
1488 return ret;
1489 }
1490
1491 int r128_cce_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv)
1492 {
1493 drm_r128_private_t *dev_priv = dev->dev_private;
1494 drm_r128_stipple_t *stipple = data;
1495 u32 mask[32];
1496
1497 LOCK_TEST_WITH_RETURN(dev, file_priv);
1498
1499 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1500
1501 if (copy_from_user(&mask, stipple->mask, 32 * sizeof(u32)))
1502 return -EFAULT;
1503
1504 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1505
1506 r128_cce_dispatch_stipple(dev, mask);
1507
1508 COMMIT_RING();
1509 return 0;
1510 }
1511
1512 static int r128_cce_indirect(struct drm_device *dev, void *data, struct drm_file *file_priv)
1513 {
1514 drm_r128_private_t *dev_priv = dev->dev_private;
1515 struct drm_device_dma *dma = dev->dma;
1516 struct drm_buf *buf;
1517 drm_r128_buf_priv_t *buf_priv;
1518 drm_r128_indirect_t *indirect = data;
1519 #if 0
1520 RING_LOCALS;
1521 #endif
1522
1523 LOCK_TEST_WITH_RETURN(dev, file_priv);
1524
1525 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1526
1527 DRM_DEBUG("idx=%d s=%d e=%d d=%d\n",
1528 indirect->idx, indirect->start, indirect->end,
1529 indirect->discard);
1530
1531 if (indirect->idx < 0 || indirect->idx >= dma->buf_count) {
1532 DRM_ERROR("buffer index %d (of %d max)\n",
1533 indirect->idx, dma->buf_count - 1);
1534 return -EINVAL;
1535 }
1536
1537 buf = dma->buflist[indirect->idx];
1538 buf_priv = buf->dev_private;
1539
1540 if (buf->file_priv != file_priv) {
1541 DRM_ERROR("process %d using buffer owned by %p\n",
1542 task_pid_nr(current), buf->file_priv);
1543 return -EINVAL;
1544 }
1545 if (buf->pending) {
1546 DRM_ERROR("sending pending buffer %d\n", indirect->idx);
1547 return -EINVAL;
1548 }
1549
1550 if (indirect->start < buf->used) {
1551 DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n",
1552 indirect->start, buf->used);
1553 return -EINVAL;
1554 }
1555
1556 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1557 VB_AGE_TEST_WITH_RETURN(dev_priv);
1558
1559 buf->used = indirect->end;
1560 buf_priv->discard = indirect->discard;
1561
1562 #if 0
1563
1564
1565
1566 BEGIN_RING(2);
1567 RADEON_WAIT_UNTIL_3D_IDLE();
1568 ADVANCE_RING();
1569 #endif
1570
1571
1572
1573
1574
1575 r128_cce_dispatch_indirect(dev, buf, indirect->start, indirect->end);
1576
1577 COMMIT_RING();
1578 return 0;
1579 }
1580
1581 int r128_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
1582 {
1583 drm_r128_private_t *dev_priv = dev->dev_private;
1584 drm_r128_getparam_t *param = data;
1585 struct pci_dev *pdev = to_pci_dev(dev->dev);
1586 int value;
1587
1588 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1589
1590 DRM_DEBUG("pid=%d\n", task_pid_nr(current));
1591
1592 switch (param->param) {
1593 case R128_PARAM_IRQ_NR:
1594 value = pdev->irq;
1595 break;
1596 default:
1597 return -EINVAL;
1598 }
1599
1600 if (copy_to_user(param->value, &value, sizeof(int))) {
1601 DRM_ERROR("copy_to_user\n");
1602 return -EFAULT;
1603 }
1604
1605 return 0;
1606 }
1607
1608 void r128_driver_preclose(struct drm_device *dev, struct drm_file *file_priv)
1609 {
1610 if (dev->dev_private) {
1611 drm_r128_private_t *dev_priv = dev->dev_private;
1612 if (dev_priv->page_flipping)
1613 r128_do_cleanup_pageflip(dev);
1614 }
1615 }
1616 void r128_driver_lastclose(struct drm_device *dev)
1617 {
1618 r128_do_cleanup_cce(dev);
1619 }
1620
1621 const struct drm_ioctl_desc r128_ioctls[] = {
1622 DRM_IOCTL_DEF_DRV(R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1623 DRM_IOCTL_DEF_DRV(R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1624 DRM_IOCTL_DEF_DRV(R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1625 DRM_IOCTL_DEF_DRV(R128_CCE_RESET, r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1626 DRM_IOCTL_DEF_DRV(R128_CCE_IDLE, r128_cce_idle, DRM_AUTH),
1627 DRM_IOCTL_DEF_DRV(R128_RESET, r128_engine_reset, DRM_AUTH),
1628 DRM_IOCTL_DEF_DRV(R128_FULLSCREEN, r128_fullscreen, DRM_AUTH),
1629 DRM_IOCTL_DEF_DRV(R128_SWAP, r128_cce_swap, DRM_AUTH),
1630 DRM_IOCTL_DEF_DRV(R128_FLIP, r128_cce_flip, DRM_AUTH),
1631 DRM_IOCTL_DEF_DRV(R128_CLEAR, r128_cce_clear, DRM_AUTH),
1632 DRM_IOCTL_DEF_DRV(R128_VERTEX, r128_cce_vertex, DRM_AUTH),
1633 DRM_IOCTL_DEF_DRV(R128_INDICES, r128_cce_indices, DRM_AUTH),
1634 DRM_IOCTL_DEF_DRV(R128_BLIT, r128_cce_blit, DRM_AUTH),
1635 DRM_IOCTL_DEF_DRV(R128_DEPTH, r128_cce_depth, DRM_AUTH),
1636 DRM_IOCTL_DEF_DRV(R128_STIPPLE, r128_cce_stipple, DRM_AUTH),
1637 DRM_IOCTL_DEF_DRV(R128_INDIRECT, r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1638 DRM_IOCTL_DEF_DRV(R128_GETPARAM, r128_getparam, DRM_AUTH),
1639 };
1640
1641 int r128_max_ioctl = ARRAY_SIZE(r128_ioctls);