diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_state.c')
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_state.c | 546 |
1 files changed, 302 insertions, 244 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 11c146b4921..23bb64fd775 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c @@ -25,12 +25,13 @@ * Authors: * Gareth Hughes <gareth@valinux.com> * Kevin E. Martin <martin@valinux.com> + * + * ------------------------ This file is DEPRECATED! ------------------------- */ -#include "drmP.h" -#include "drm.h" -#include "drm_sarea.h" -#include "radeon_drm.h" +#include <drm/drmP.h> +#include <drm/drm_buffer.h> +#include <drm/radeon_drm.h> #include "radeon_drv.h" /* ================================================================ @@ -91,21 +92,27 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * dev_priv, struct drm_file *file_priv, - int id, u32 *data) + int id, struct drm_buffer *buf) { + u32 *data; switch (id) { case RADEON_EMIT_PP_MISC: - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &data[(RADEON_RB3D_DEPTHOFFSET - RADEON_PP_MISC) / 4])) { + data = drm_buffer_pointer_to_dword(buf, + (RADEON_RB3D_DEPTHOFFSET - RADEON_PP_MISC) / 4); + + if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) { DRM_ERROR("Invalid depth buffer offset\n"); return -EINVAL; } + dev_priv->have_z_offset = 1; break; case RADEON_EMIT_PP_CNTL: - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &data[(RADEON_RB3D_COLOROFFSET - RADEON_PP_CNTL) / 4])) { + data = drm_buffer_pointer_to_dword(buf, + (RADEON_RB3D_COLOROFFSET - RADEON_PP_CNTL) / 4); + + if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) { DRM_ERROR("Invalid colour buffer offset\n"); return -EINVAL; } @@ -117,8 +124,8 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * case R200_EMIT_PP_TXOFFSET_3: case R200_EMIT_PP_TXOFFSET_4: case R200_EMIT_PP_TXOFFSET_5: - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &data[0])) { + data = drm_buffer_pointer_to_dword(buf, 0); + if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) { DRM_ERROR("Invalid R200 texture offset\n"); return -EINVAL; } @@ -127,8 +134,9 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * case RADEON_EMIT_PP_TXFILTER_0: case RADEON_EMIT_PP_TXFILTER_1: case RADEON_EMIT_PP_TXFILTER_2: - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &data[(RADEON_PP_TXOFFSET_0 - RADEON_PP_TXFILTER_0) / 4])) { + data = drm_buffer_pointer_to_dword(buf, + (RADEON_PP_TXOFFSET_0 - RADEON_PP_TXFILTER_0) / 4); + if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) { DRM_ERROR("Invalid R100 texture offset\n"); return -EINVAL; } @@ -142,9 +150,10 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * case R200_EMIT_PP_CUBIC_OFFSETS_5:{ int i; for (i = 0; i < 5; i++) { + data = drm_buffer_pointer_to_dword(buf, i); if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &data[i])) { + data)) { DRM_ERROR ("Invalid R200 cubic texture offset\n"); return -EINVAL; @@ -158,9 +167,10 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * case RADEON_EMIT_PP_CUBIC_OFFSETS_T2:{ int i; for (i = 0; i < 5; i++) { + data = drm_buffer_pointer_to_dword(buf, i); if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &data[i])) { + data)) { DRM_ERROR ("Invalid R100 cubic texture offset\n"); return -EINVAL; @@ -262,30 +272,31 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * return 0; } -static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * - dev_priv, - struct drm_file *file_priv, - drm_radeon_kcmd_buffer_t * - cmdbuf, - unsigned int *cmdsz) +static int radeon_check_and_fixup_packet3(drm_radeon_private_t * + dev_priv, + struct drm_file *file_priv, + drm_radeon_kcmd_buffer_t * + cmdbuf, + unsigned int *cmdsz) { - u32 *cmd = (u32 *) cmdbuf->buf; + u32 *cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0); u32 offset, narrays; int count, i, k; - *cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16); + count = ((*cmd & RADEON_CP_PACKET_COUNT_MASK) >> 16); + *cmdsz = 2 + count; - if ((cmd[0] & 0xc0000000) != RADEON_CP_PACKET3) { + if ((*cmd & 0xc0000000) != RADEON_CP_PACKET3) { DRM_ERROR("Not a type 3 packet\n"); return -EINVAL; } - if (4 * *cmdsz > cmdbuf->bufsz) { + if (4 * *cmdsz > drm_buffer_unprocessed(cmdbuf->buffer)) { DRM_ERROR("Packet size larger than size of data provided\n"); return -EINVAL; } - switch(cmd[0] & 0xff00) { + switch (*cmd & 0xff00) { /* XXX Are there old drivers needing other packets? */ case RADEON_3D_DRAW_IMMD: @@ -312,7 +323,6 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * break; case RADEON_3D_LOAD_VBPNTR: - count = (cmd[0] >> 16) & 0x3fff; if (count > 18) { /* 12 arrays max */ DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n", @@ -321,13 +331,16 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * } /* carefully check packet contents */ - narrays = cmd[1] & ~0xc000; + cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1); + + narrays = *cmd & ~0xc000; k = 0; i = 2; while ((k < narrays) && (i < (count + 2))) { i++; /* skip attribute field */ + cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, i); if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &cmd[i])) { + cmd)) { DRM_ERROR ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n", k, i); @@ -338,8 +351,10 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * if (k == narrays) break; /* have one more to process, they come in pairs */ + cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, i); + if (radeon_check_and_fixup_offset(dev_priv, - file_priv, &cmd[i])) + file_priv, cmd)) { DRM_ERROR ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n", @@ -363,7 +378,9 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * DRM_ERROR("Invalid 3d packet for r200-class chip\n"); return -EINVAL; } - if (radeon_check_and_fixup_offset(dev_priv, file_priv, &cmd[1])) { + + cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1); + if (radeon_check_and_fixup_offset(dev_priv, file_priv, cmd)) { DRM_ERROR("Invalid rndr_gen_indx offset\n"); return -EINVAL; } @@ -374,12 +391,15 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * DRM_ERROR("Invalid 3d packet for r100-class chip\n"); return -EINVAL; } - if ((cmd[1] & 0x8000ffff) != 0x80000810) { - DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]); + + cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1); + if ((*cmd & 0x8000ffff) != 0x80000810) { + DRM_ERROR("Invalid indx_buffer reg address %08X\n", *cmd); return -EINVAL; } - if (radeon_check_and_fixup_offset(dev_priv, file_priv, &cmd[2])) { - DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]); + cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 2); + if (radeon_check_and_fixup_offset(dev_priv, file_priv, cmd)) { + DRM_ERROR("Invalid indx_buffer offset is %08X\n", *cmd); return -EINVAL; } break; @@ -388,31 +408,34 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * case RADEON_CNTL_PAINT_MULTI: case RADEON_CNTL_BITBLT_MULTI: /* MSB of opcode: next DWORD GUI_CNTL */ - if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL + cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1); + if (*cmd & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { - offset = cmd[2] << 10; + u32 *cmd2 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 2); + offset = *cmd2 << 10; if (radeon_check_and_fixup_offset (dev_priv, file_priv, &offset)) { DRM_ERROR("Invalid first packet offset\n"); return -EINVAL; } - cmd[2] = (cmd[2] & 0xffc00000) | offset >> 10; + *cmd2 = (*cmd2 & 0xffc00000) | offset >> 10; } - if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && - (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { - offset = cmd[3] << 10; + if ((*cmd & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && + (*cmd & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { + u32 *cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3); + offset = *cmd3 << 10; if (radeon_check_and_fixup_offset (dev_priv, file_priv, &offset)) { DRM_ERROR("Invalid second packet offset\n"); return -EINVAL; } - cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10; + *cmd3 = (*cmd3 & 0xffc00000) | offset >> 10; } break; default: - DRM_ERROR("Invalid packet type %x\n", cmd[0] & 0xff00); + DRM_ERROR("Invalid packet type %x\n", *cmd & 0xff00); return -EINVAL; } @@ -423,8 +446,8 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * * CP hardware state programming functions */ -static __inline__ void radeon_emit_clip_rect(drm_radeon_private_t * dev_priv, - struct drm_clip_rect * box) +static void radeon_emit_clip_rect(drm_radeon_private_t * dev_priv, + struct drm_clip_rect * box) { RING_LOCALS; @@ -742,13 +765,14 @@ static struct { */ static void radeon_clear_box(drm_radeon_private_t * dev_priv, + struct drm_radeon_master_private *master_priv, int x, int y, int w, int h, int r, int g, int b) { u32 color; RING_LOCALS; - x += dev_priv->sarea_priv->boxes[0].x1; - y += dev_priv->sarea_priv->boxes[0].y1; + x += master_priv->sarea_priv->boxes[0].x1; + y += master_priv->sarea_priv->boxes[0].y1; switch (dev_priv->color_fmt) { case RADEON_COLOR_FORMAT_RGB565: @@ -776,7 +800,7 @@ static void radeon_clear_box(drm_radeon_private_t * dev_priv, RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS); - if (dev_priv->sarea_priv->pfCurrentPage == 1) { + if (master_priv->sarea_priv->pfCurrentPage == 1) { OUT_RING(dev_priv->front_pitch_offset); } else { OUT_RING(dev_priv->back_pitch_offset); @@ -790,7 +814,7 @@ static void radeon_clear_box(drm_radeon_private_t * dev_priv, ADVANCE_RING(); } -static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv) +static void radeon_cp_performance_boxes(drm_radeon_private_t *dev_priv, struct drm_radeon_master_private *master_priv) { /* Collapse various things into a wait flag -- trying to * guess if userspase slept -- better just to have them tell us. @@ -807,12 +831,12 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv) /* Purple box for page flipping */ if (dev_priv->stats.boxes & RADEON_BOX_FLIP) - radeon_clear_box(dev_priv, 4, 4, 8, 8, 255, 0, 255); + radeon_clear_box(dev_priv, master_priv, 4, 4, 8, 8, 255, 0, 255); /* Red box if we have to wait for idle at any point */ if (dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE) - radeon_clear_box(dev_priv, 16, 4, 8, 8, 255, 0, 0); + radeon_clear_box(dev_priv, master_priv, 16, 4, 8, 8, 255, 0, 0); /* Blue box: lost context? */ @@ -820,12 +844,12 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv) /* Yellow box for texture swaps */ if (dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD) - radeon_clear_box(dev_priv, 40, 4, 8, 8, 255, 255, 0); + radeon_clear_box(dev_priv, master_priv, 40, 4, 8, 8, 255, 255, 0); /* Green box if hardware never idles (as far as we can tell) */ if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE)) - radeon_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0); + radeon_clear_box(dev_priv, master_priv, 64, 4, 8, 8, 0, 255, 0); /* Draw bars indicating number of buffers allocated * (not a great measure, easily confused) @@ -834,7 +858,7 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv) if (dev_priv->stats.requested_bufs > 100) dev_priv->stats.requested_bufs = 100; - radeon_clear_box(dev_priv, 4, 16, + radeon_clear_box(dev_priv, master_priv, 4, 16, dev_priv->stats.requested_bufs, 4, 196, 128, 128); } @@ -848,11 +872,13 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv) */ static void radeon_cp_dispatch_clear(struct drm_device * dev, + struct drm_master *master, drm_radeon_clear_t * clear, drm_radeon_clear_rect_t * depth_boxes) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + struct drm_radeon_master_private *master_priv = master->driver_priv; + drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear; int nbox = sarea_priv->nbox; struct drm_clip_rect *pbox = sarea_priv->boxes; @@ -864,7 +890,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, dev_priv->stats.clears++; - if (dev_priv->sarea_priv->pfCurrentPage == 1) { + if (sarea_priv->pfCurrentPage == 1) { unsigned int tmp = flags; flags &= ~(RADEON_FRONT | RADEON_BACK); @@ -873,6 +899,12 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, if (tmp & RADEON_BACK) flags |= RADEON_FRONT; } + if (flags & (RADEON_DEPTH|RADEON_STENCIL)) { + if (!dev_priv->have_z_offset) { + printk_once(KERN_ERR "radeon: illegal depth clear request. Buggy mesa detected - please update.\n"); + flags &= ~(RADEON_DEPTH | RADEON_STENCIL); + } + } if (flags & (RADEON_FRONT | RADEON_BACK)) { @@ -890,7 +922,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, /* Make sure we restore the 3D state next time. */ - dev_priv->sarea_priv->ctx_owner = 0; + sarea_priv->ctx_owner = 0; for (i = 0; i < nbox; i++) { int x = pbox[i].x1; @@ -948,7 +980,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, } /* hyper z clear */ - /* no docs available, based on reverse engeneering by Stephane Marchesin */ + /* no docs available, based on reverse engineering by Stephane Marchesin */ if ((flags & (RADEON_DEPTH | RADEON_STENCIL)) && (flags & RADEON_CLEAR_FASTZ)) { @@ -967,7 +999,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, /* Make sure we restore the 3D state next time. * we haven't touched any "normal" state - still need this? */ - dev_priv->sarea_priv->ctx_owner = 0; + sarea_priv->ctx_owner = 0; if ((dev_priv->flags & RADEON_HAS_HIERZ) && (flags & RADEON_USE_HIERZ)) { @@ -1062,7 +1094,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, /* judging by the first tile offset needed, could possibly directly address/clear 4x4 tiles instead of 8x2 * 4x4 macro tiles, though would still need clear mask for - right/bottom if truely 4x4 granularity is desired ? */ + right/bottom if truly 4x4 granularity is desired ? */ OUT_RING(tileoffset * 16); /* the number of tiles to clear */ OUT_RING(nrtilesx + 1); @@ -1214,7 +1246,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, /* Make sure we restore the 3D state next time. */ - dev_priv->sarea_priv->ctx_owner = 0; + sarea_priv->ctx_owner = 0; for (i = 0; i < nbox; i++) { @@ -1285,7 +1317,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, /* Make sure we restore the 3D state next time. */ - dev_priv->sarea_priv->ctx_owner = 0; + sarea_priv->ctx_owner = 0; for (i = 0; i < nbox; i++) { @@ -1328,20 +1360,21 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, * wait on this value before performing the clear ioctl. We * need this because the card's so damned fast... */ - dev_priv->sarea_priv->last_clear++; + sarea_priv->last_clear++; BEGIN_RING(4); - RADEON_CLEAR_AGE(dev_priv->sarea_priv->last_clear); + RADEON_CLEAR_AGE(sarea_priv->last_clear); RADEON_WAIT_UNTIL_IDLE(); ADVANCE_RING(); } -static void radeon_cp_dispatch_swap(struct drm_device * dev) +static void radeon_cp_dispatch_swap(struct drm_device *dev, struct drm_master *master) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + struct drm_radeon_master_private *master_priv = master->driver_priv; + drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; int nbox = sarea_priv->nbox; struct drm_clip_rect *pbox = sarea_priv->boxes; int i; @@ -1351,7 +1384,7 @@ static void radeon_cp_dispatch_swap(struct drm_device * dev) /* Do some trivial performance monitoring... */ if (dev_priv->do_boxes) - radeon_cp_performance_boxes(dev_priv); + radeon_cp_performance_boxes(dev_priv, master_priv); /* Wait for the 3D stream to idle before dispatching the bitblt. * This will prevent data corruption between the two streams. @@ -1385,7 +1418,7 @@ static void radeon_cp_dispatch_swap(struct drm_device * dev) /* Make this work even if front & back are flipped: */ OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1)); - if (dev_priv->sarea_priv->pfCurrentPage == 0) { + if (sarea_priv->pfCurrentPage == 0) { OUT_RING(dev_priv->back_pitch_offset); OUT_RING(dev_priv->front_pitch_offset); } else { @@ -1405,31 +1438,32 @@ static void radeon_cp_dispatch_swap(struct drm_device * dev) * throttle the framerate by waiting for this value before * performing the swapbuffer ioctl. */ - dev_priv->sarea_priv->last_frame++; + sarea_priv->last_frame++; BEGIN_RING(4); - RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame); + RADEON_FRAME_AGE(sarea_priv->last_frame); RADEON_WAIT_UNTIL_2D_IDLE(); ADVANCE_RING(); } -static void radeon_cp_dispatch_flip(struct drm_device * dev) +void radeon_cp_dispatch_flip(struct drm_device *dev, struct drm_master *master) { drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_sarea *sarea = (struct drm_sarea *) dev_priv->sarea->handle; - int offset = (dev_priv->sarea_priv->pfCurrentPage == 1) + struct drm_radeon_master_private *master_priv = master->driver_priv; + struct drm_sarea *sarea = (struct drm_sarea *)master_priv->sarea->handle; + int offset = (master_priv->sarea_priv->pfCurrentPage == 1) ? dev_priv->front_offset : dev_priv->back_offset; RING_LOCALS; DRM_DEBUG("pfCurrentPage=%d\n", - dev_priv->sarea_priv->pfCurrentPage); + master_priv->sarea_priv->pfCurrentPage); /* Do some trivial performance monitoring... */ if (dev_priv->do_boxes) { dev_priv->stats.boxes |= RADEON_BOX_FLIP; - radeon_cp_performance_boxes(dev_priv); + radeon_cp_performance_boxes(dev_priv, master_priv); } /* Update the frame offsets for both CRTCs @@ -1441,7 +1475,7 @@ static void radeon_cp_dispatch_flip(struct drm_device * dev) ((sarea->frame.y * dev_priv->front_pitch + sarea->frame.x * (dev_priv->color_fmt - 2)) & ~7) + offset); - OUT_RING_REG(RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base + OUT_RING_REG(RADEON_CRTC2_OFFSET, master_priv->sarea_priv->crtc2_base + offset); ADVANCE_RING(); @@ -1450,13 +1484,13 @@ static void radeon_cp_dispatch_flip(struct drm_device * dev) * throttle the framerate by waiting for this value before * performing the swapbuffer ioctl. */ - dev_priv->sarea_priv->last_frame++; - dev_priv->sarea_priv->pfCurrentPage = - 1 - dev_priv->sarea_priv->pfCurrentPage; + master_priv->sarea_priv->last_frame++; + master_priv->sarea_priv->pfCurrentPage = + 1 - master_priv->sarea_priv->pfCurrentPage; BEGIN_RING(2); - RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame); + RADEON_FRAME_AGE(master_priv->sarea_priv->last_frame); ADVANCE_RING(); } @@ -1494,11 +1528,13 @@ typedef struct { } drm_radeon_tcl_prim_t; static void radeon_cp_dispatch_vertex(struct drm_device * dev, + struct drm_file *file_priv, struct drm_buf * buf, drm_radeon_tcl_prim_t * prim) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; + drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; int offset = dev_priv->gart_buffers_offset + buf->offset + prim->start; int numverts = (int)prim->numverts; int nbox = sarea_priv->nbox; @@ -1539,18 +1575,25 @@ static void radeon_cp_dispatch_vertex(struct drm_device * dev, } while (i < nbox); } -static void radeon_cp_discard_buffer(struct drm_device * dev, struct drm_buf * buf) +void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf) { drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_radeon_master_private *master_priv = master->driver_priv; drm_radeon_buf_priv_t *buf_priv = buf->dev_private; RING_LOCALS; - buf_priv->age = ++dev_priv->sarea_priv->last_dispatch; + buf_priv->age = ++master_priv->sarea_priv->last_dispatch; /* Emit the vertex buffer age */ - BEGIN_RING(2); - RADEON_DISPATCH_AGE(buf_priv->age); - ADVANCE_RING(); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { + BEGIN_RING(3); + R600_DISPATCH_AGE(buf_priv->age); + ADVANCE_RING(); + } else { + BEGIN_RING(2); + RADEON_DISPATCH_AGE(buf_priv->age); + ADVANCE_RING(); + } buf->pending = 1; buf->used = 0; @@ -1590,12 +1633,14 @@ static void radeon_cp_dispatch_indirect(struct drm_device * dev, } } -static void radeon_cp_dispatch_indices(struct drm_device * dev, +static void radeon_cp_dispatch_indices(struct drm_device *dev, + struct drm_master *master, struct drm_buf * elt_buf, drm_radeon_tcl_prim_t * prim) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + struct drm_radeon_master_private *master_priv = master->driver_priv; + drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; int offset = dev_priv->gart_buffers_offset + prim->offset; u32 *data; int dwords; @@ -1765,7 +1810,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev, } if (!buf) { DRM_DEBUG("EAGAIN\n"); - if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image))) + if (copy_to_user(tex->image, image, sizeof(*image))) return -EFAULT; return -EAGAIN; } @@ -1778,7 +1823,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev, #define RADEON_COPY_MT(_buf, _data, _width) \ do { \ - if (DRM_COPY_FROM_USER(_buf, _data, (_width))) {\ + if (copy_from_user(_buf, _data, (_width))) {\ DRM_ERROR("EFAULT on pad, %d bytes\n", (_width)); \ return -EFAULT; \ } \ @@ -1870,7 +1915,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev, ADVANCE_RING(); COMMIT_RING(); - radeon_cp_discard_buffer(dev, buf); + radeon_cp_discard_buffer(dev, file_priv->master, buf); /* Update the input parameters for next time */ image->y += height; @@ -1934,7 +1979,7 @@ static void radeon_apply_surface_regs(int surf_index, * Note that refcount can be at most 2, since during a free refcount=3 * might mean we have to allocate a new surface which might not always * be available. - * For example : we allocate three contigous surfaces ABC. If B is + * For example : we allocate three contiguous surfaces ABC. If B is * freed, we suddenly need two surfaces to store A and C, which might * not always be available. */ @@ -1970,7 +2015,7 @@ static int alloc_surface(drm_radeon_surface_alloc_t *new, /* find a virtual surface */ for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) - if (dev_priv->virt_surfaces[i].file_priv == 0) + if (dev_priv->virt_surfaces[i].file_priv == NULL) break; if (i == 2 * RADEON_MAX_SURFACES) { return -1; @@ -2110,7 +2155,8 @@ static int radeon_surface_free(struct drm_device *dev, void *data, struct drm_fi static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; + drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; drm_radeon_clear_t *clear = data; drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; DRM_DEBUG("\n"); @@ -2122,11 +2168,11 @@ static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file * if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; - if (DRM_COPY_FROM_USER(&depth_boxes, clear->depth_boxes, + if (copy_from_user(&depth_boxes, clear->depth_boxes, sarea_priv->nbox * sizeof(depth_boxes[0]))) return -EFAULT; - radeon_cp_dispatch_clear(dev, clear, depth_boxes); + radeon_cp_dispatch_clear(dev, file_priv->master, clear, depth_boxes); COMMIT_RING(); return 0; @@ -2134,9 +2180,10 @@ static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file * /* Not sure why this isn't set all the time: */ -static int radeon_do_init_pageflip(struct drm_device * dev) +static int radeon_do_init_pageflip(struct drm_device *dev, struct drm_master *master) { drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_radeon_master_private *master_priv = master->driver_priv; RING_LOCALS; DRM_DEBUG("\n"); @@ -2153,8 +2200,8 @@ static int radeon_do_init_pageflip(struct drm_device * dev) dev_priv->page_flipping = 1; - if (dev_priv->sarea_priv->pfCurrentPage != 1) - dev_priv->sarea_priv->pfCurrentPage = 0; + if (master_priv->sarea_priv->pfCurrentPage != 1) + master_priv->sarea_priv->pfCurrentPage = 0; return 0; } @@ -2172,9 +2219,9 @@ static int radeon_cp_flip(struct drm_device *dev, void *data, struct drm_file *f RING_SPACE_TEST_WITH_RETURN(dev_priv); if (!dev_priv->page_flipping) - radeon_do_init_pageflip(dev); + radeon_do_init_pageflip(dev, file_priv->master); - radeon_cp_dispatch_flip(dev); + radeon_cp_dispatch_flip(dev, file_priv->master); COMMIT_RING(); return 0; @@ -2183,7 +2230,9 @@ static int radeon_cp_flip(struct drm_device *dev, void *data, struct drm_file *f static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; + drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; + DRM_DEBUG("\n"); LOCK_TEST_WITH_RETURN(dev, file_priv); @@ -2193,8 +2242,11 @@ static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *f if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; - radeon_cp_dispatch_swap(dev); - dev_priv->sarea_priv->ctx_owner = 0; + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + r600_cp_dispatch_swap(dev, file_priv); + else + radeon_cp_dispatch_swap(dev, file_priv->master); + sarea_priv->ctx_owner = 0; COMMIT_RING(); return 0; @@ -2203,7 +2255,8 @@ static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *f static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; + drm_radeon_sarea_t *sarea_priv; struct drm_device_dma *dma = dev->dma; struct drm_buf *buf; drm_radeon_vertex_t *vertex = data; @@ -2211,6 +2264,8 @@ static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file LOCK_TEST_WITH_RETURN(dev, file_priv); + sarea_priv = master_priv->sarea_priv; + DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n", DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard); @@ -2263,13 +2318,13 @@ static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file prim.finish = vertex->count; /* unused */ prim.prim = vertex->prim; prim.numverts = vertex->count; - prim.vc_format = dev_priv->sarea_priv->vc_format; + prim.vc_format = sarea_priv->vc_format; - radeon_cp_dispatch_vertex(dev, buf, &prim); + radeon_cp_dispatch_vertex(dev, file_priv, buf, &prim); } if (vertex->discard) { - radeon_cp_discard_buffer(dev, buf); + radeon_cp_discard_buffer(dev, file_priv->master, buf); } COMMIT_RING(); @@ -2279,7 +2334,8 @@ static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; + drm_radeon_sarea_t *sarea_priv; struct drm_device_dma *dma = dev->dma; struct drm_buf *buf; drm_radeon_indices_t *elts = data; @@ -2288,6 +2344,8 @@ static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file LOCK_TEST_WITH_RETURN(dev, file_priv); + sarea_priv = master_priv->sarea_priv; + DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n", DRM_CURRENTPID, elts->idx, elts->start, elts->end, elts->discard); @@ -2353,11 +2411,11 @@ static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file prim.prim = elts->prim; prim.offset = 0; /* offset from start of dma buffers */ prim.numverts = RADEON_MAX_VB_VERTS; /* duh */ - prim.vc_format = dev_priv->sarea_priv->vc_format; + prim.vc_format = sarea_priv->vc_format; - radeon_cp_dispatch_indices(dev, buf, &prim); + radeon_cp_dispatch_indices(dev, file_priv->master, buf, &prim); if (elts->discard) { - radeon_cp_discard_buffer(dev, buf); + radeon_cp_discard_buffer(dev, file_priv->master, buf); } COMMIT_RING(); @@ -2378,7 +2436,7 @@ static int radeon_cp_texture(struct drm_device *dev, void *data, struct drm_file return -EINVAL; } - if (DRM_COPY_FROM_USER(&image, + if (copy_from_user(&image, (drm_radeon_tex_image_t __user *) tex->image, sizeof(image))) return -EFAULT; @@ -2386,7 +2444,10 @@ static int radeon_cp_texture(struct drm_device *dev, void *data, struct drm_file RING_SPACE_TEST_WITH_RETURN(dev_priv); VB_AGE_TEST_WITH_RETURN(dev_priv); - ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + ret = r600_cp_dispatch_texture(dev, file_priv, tex, &image); + else + ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image); return ret; } @@ -2399,7 +2460,7 @@ static int radeon_cp_stipple(struct drm_device *dev, void *data, struct drm_file LOCK_TEST_WITH_RETURN(dev, file_priv); - if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32))) + if (copy_from_user(&mask, stipple->mask, 32 * sizeof(u32))) return -EFAULT; RING_SPACE_TEST_WITH_RETURN(dev_priv); @@ -2453,22 +2514,24 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil buf->used = indirect->end; - /* Wait for the 3D stream to idle before the indirect buffer - * containing 2D acceleration commands is processed. - */ - BEGIN_RING(2); - - RADEON_WAIT_UNTIL_3D_IDLE(); - - ADVANCE_RING(); - /* Dispatch the indirect buffer full of commands from the * X server. This is insecure and is thus only available to * privileged clients. */ - radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + r600_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); + else { + /* Wait for the 3D stream to idle before the indirect buffer + * containing 2D acceleration commands is processed. + */ + BEGIN_RING(2); + RADEON_WAIT_UNTIL_3D_IDLE(); + ADVANCE_RING(); + radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); + } + if (indirect->discard) { - radeon_cp_discard_buffer(dev, buf); + radeon_cp_discard_buffer(dev, file_priv->master, buf); } COMMIT_RING(); @@ -2478,7 +2541,8 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; + drm_radeon_sarea_t *sarea_priv; struct drm_device_dma *dma = dev->dma; struct drm_buf *buf; drm_radeon_vertex2_t *vertex = data; @@ -2487,6 +2551,8 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file LOCK_TEST_WITH_RETURN(dev, file_priv); + sarea_priv = master_priv->sarea_priv; + DRM_DEBUG("pid=%d index=%d discard=%d\n", DRM_CURRENTPID, vertex->idx, vertex->discard); @@ -2519,13 +2585,13 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file drm_radeon_prim_t prim; drm_radeon_tcl_prim_t tclprim; - if (DRM_COPY_FROM_USER(&prim, &vertex->prim[i], sizeof(prim))) + if (copy_from_user(&prim, &vertex->prim[i], sizeof(prim))) return -EFAULT; if (prim.stateidx != laststate) { drm_radeon_state_t state; - if (DRM_COPY_FROM_USER(&state, + if (copy_from_user(&state, &vertex->state[prim.stateidx], sizeof(state))) return -EFAULT; @@ -2547,12 +2613,12 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file tclprim.offset = prim.numverts * 64; tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */ - radeon_cp_dispatch_indices(dev, buf, &tclprim); + radeon_cp_dispatch_indices(dev, file_priv->master, buf, &tclprim); } else { tclprim.numverts = prim.numverts; tclprim.offset = 0; /* not used */ - radeon_cp_dispatch_vertex(dev, buf, &tclprim); + radeon_cp_dispatch_vertex(dev, file_priv, buf, &tclprim); } if (sarea_priv->nbox == 1) @@ -2560,7 +2626,7 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file } if (vertex->discard) { - radeon_cp_discard_buffer(dev, buf); + radeon_cp_discard_buffer(dev, file_priv->master, buf); } COMMIT_RING(); @@ -2574,7 +2640,6 @@ static int radeon_emit_packets(drm_radeon_private_t * dev_priv, { int id = (int)header.packet.packet_id; int sz, reg; - int *data = (int *)cmdbuf->buf; RING_LOCALS; if (id >= RADEON_MAX_STATE_PACKETS) @@ -2583,23 +2648,22 @@ static int radeon_emit_packets(drm_radeon_private_t * dev_priv, sz = packet[id].len; reg = packet[id].start; - if (sz * sizeof(int) > cmdbuf->bufsz) { + if (sz * sizeof(u32) > drm_buffer_unprocessed(cmdbuf->buffer)) { DRM_ERROR("Packet size provided larger than data provided\n"); return -EINVAL; } - if (radeon_check_and_fixup_packets(dev_priv, file_priv, id, data)) { + if (radeon_check_and_fixup_packets(dev_priv, file_priv, id, + cmdbuf->buffer)) { DRM_ERROR("Packet verification failed\n"); return -EINVAL; } BEGIN_RING(sz + 1); OUT_RING(CP_PACKET0(reg, (sz - 1))); - OUT_RING_TABLE(data, sz); + OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz); ADVANCE_RING(); - cmdbuf->buf += sz * sizeof(int); - cmdbuf->bufsz -= sz * sizeof(int); return 0; } @@ -2616,10 +2680,8 @@ static __inline__ int radeon_emit_scalars(drm_radeon_private_t *dev_priv, OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0)); OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1)); - OUT_RING_TABLE(cmdbuf->buf, sz); + OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz); ADVANCE_RING(); - cmdbuf->buf += sz * sizeof(int); - cmdbuf->bufsz -= sz * sizeof(int); return 0; } @@ -2638,10 +2700,8 @@ static __inline__ int radeon_emit_scalars2(drm_radeon_private_t *dev_priv, OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0)); OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1)); - OUT_RING_TABLE(cmdbuf->buf, sz); + OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz); ADVANCE_RING(); - cmdbuf->buf += sz * sizeof(int); - cmdbuf->bufsz -= sz * sizeof(int); return 0; } @@ -2659,11 +2719,9 @@ static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv, OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0)); OUT_RING(start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1))); - OUT_RING_TABLE(cmdbuf->buf, sz); + OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz); ADVANCE_RING(); - cmdbuf->buf += sz * sizeof(int); - cmdbuf->bufsz -= sz * sizeof(int); return 0; } @@ -2677,7 +2735,7 @@ static __inline__ int radeon_emit_veclinear(drm_radeon_private_t *dev_priv, if (!sz) return 0; - if (sz * 4 > cmdbuf->bufsz) + if (sz * 4 > drm_buffer_unprocessed(cmdbuf->buffer)) return -EINVAL; BEGIN_RING(5 + sz); @@ -2685,11 +2743,9 @@ static __inline__ int radeon_emit_veclinear(drm_radeon_private_t *dev_priv, OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0)); OUT_RING(start | (1 << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1))); - OUT_RING_TABLE(cmdbuf->buf, sz); + OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz); ADVANCE_RING(); - cmdbuf->buf += sz * sizeof(int); - cmdbuf->bufsz -= sz * sizeof(int); return 0; } @@ -2711,11 +2767,9 @@ static int radeon_emit_packet3(struct drm_device * dev, } BEGIN_RING(cmdsz); - OUT_RING_TABLE(cmdbuf->buf, cmdsz); + OUT_RING_DRM_BUFFER(cmdbuf->buffer, cmdsz); ADVANCE_RING(); - cmdbuf->buf += cmdsz * 4; - cmdbuf->bufsz -= cmdsz * 4; return 0; } @@ -2745,7 +2799,7 @@ static int radeon_emit_packet3_cliprect(struct drm_device *dev, do { if (i < cmdbuf->nbox) { - if (DRM_COPY_FROM_USER(&box, &boxes[i], sizeof(box))) + if (copy_from_user(&box, &boxes[i], sizeof(box))) return -EFAULT; /* FIXME The second and subsequent times round * this loop, send a WAIT_UNTIL_3D_IDLE before @@ -2768,16 +2822,16 @@ static int radeon_emit_packet3_cliprect(struct drm_device *dev, } BEGIN_RING(cmdsz); - OUT_RING_TABLE(cmdbuf->buf, cmdsz); + OUT_RING_DRM_BUFFER(cmdbuf->buffer, cmdsz); ADVANCE_RING(); } while (++i < cmdbuf->nbox); if (cmdbuf->nbox == 1) cmdbuf->nbox = 0; + return 0; out: - cmdbuf->buf += cmdsz * 4; - cmdbuf->bufsz -= cmdsz * 4; + drm_buffer_advance(cmdbuf->buffer, cmdsz * 4); return 0; } @@ -2810,16 +2864,16 @@ static int radeon_emit_wait(struct drm_device * dev, int flags) return 0; } -static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_priv) +static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, + struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; struct drm_device_dma *dma = dev->dma; struct drm_buf *buf = NULL; + drm_radeon_cmd_header_t stack_header; int idx; drm_radeon_kcmd_buffer_t *cmdbuf = data; - drm_radeon_cmd_header_t header; - int orig_nbox, orig_bufsz; - char *kbuf = NULL; + int orig_nbox; LOCK_TEST_WITH_RETURN(dev, file_priv); @@ -2834,18 +2888,20 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file * races between checking values and using those values in other code, * and simply to avoid a lot of function calls to copy in data. */ - orig_bufsz = cmdbuf->bufsz; - if (orig_bufsz != 0) { - kbuf = drm_alloc(cmdbuf->bufsz, DRM_MEM_DRIVER); - if (kbuf == NULL) - return -ENOMEM; - if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf->buf, - cmdbuf->bufsz)) { - drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); - return -EFAULT; + if (cmdbuf->bufsz != 0) { + int rv; + void __user *buffer = cmdbuf->buffer; + rv = drm_buffer_alloc(&cmdbuf->buffer, cmdbuf->bufsz); + if (rv) + return rv; + rv = drm_buffer_copy_from_user(cmdbuf->buffer, buffer, + cmdbuf->bufsz); + if (rv) { + drm_buffer_free(cmdbuf->buffer); + return rv; } - cmdbuf->buf = kbuf; - } + } else + goto done; orig_nbox = cmdbuf->nbox; @@ -2853,24 +2909,23 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file int temp; temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf); - if (orig_bufsz != 0) - drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); + drm_buffer_free(cmdbuf->buffer); return temp; } /* microcode_version != r300 */ - while (cmdbuf->bufsz >= sizeof(header)) { + while (drm_buffer_unprocessed(cmdbuf->buffer) >= sizeof(stack_header)) { - header.i = *(int *)cmdbuf->buf; - cmdbuf->buf += sizeof(header); - cmdbuf->bufsz -= sizeof(header); + drm_radeon_cmd_header_t *header; + header = drm_buffer_read_object(cmdbuf->buffer, + sizeof(stack_header), &stack_header); - switch (header.header.cmd_type) { + switch (header->header.cmd_type) { case RADEON_CMD_PACKET: DRM_DEBUG("RADEON_CMD_PACKET\n"); if (radeon_emit_packets - (dev_priv, file_priv, header, cmdbuf)) { + (dev_priv, file_priv, *header, cmdbuf)) { DRM_ERROR("radeon_emit_packets failed\n"); goto err; } @@ -2878,7 +2933,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file case RADEON_CMD_SCALARS: DRM_DEBUG("RADEON_CMD_SCALARS\n"); - if (radeon_emit_scalars(dev_priv, header, cmdbuf)) { + if (radeon_emit_scalars(dev_priv, *header, cmdbuf)) { DRM_ERROR("radeon_emit_scalars failed\n"); goto err; } @@ -2886,7 +2941,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file case RADEON_CMD_VECTORS: DRM_DEBUG("RADEON_CMD_VECTORS\n"); - if (radeon_emit_vectors(dev_priv, header, cmdbuf)) { + if (radeon_emit_vectors(dev_priv, *header, cmdbuf)) { DRM_ERROR("radeon_emit_vectors failed\n"); goto err; } @@ -2894,7 +2949,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file case RADEON_CMD_DMA_DISCARD: DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n"); - idx = header.dma.buf_idx; + idx = header->dma.buf_idx; if (idx < 0 || idx >= dma->buf_count) { DRM_ERROR("buffer index %d (of %d max)\n", idx, dma->buf_count - 1); @@ -2909,7 +2964,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file goto err; } - radeon_cp_discard_buffer(dev, buf); + radeon_cp_discard_buffer(dev, file_priv->master, buf); break; case RADEON_CMD_PACKET3: @@ -2931,7 +2986,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file case RADEON_CMD_SCALARS2: DRM_DEBUG("RADEON_CMD_SCALARS2\n"); - if (radeon_emit_scalars2(dev_priv, header, cmdbuf)) { + if (radeon_emit_scalars2(dev_priv, *header, cmdbuf)) { DRM_ERROR("radeon_emit_scalars2 failed\n"); goto err; } @@ -2939,37 +2994,36 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file case RADEON_CMD_WAIT: DRM_DEBUG("RADEON_CMD_WAIT\n"); - if (radeon_emit_wait(dev, header.wait.flags)) { + if (radeon_emit_wait(dev, header->wait.flags)) { DRM_ERROR("radeon_emit_wait failed\n"); goto err; } break; case RADEON_CMD_VECLINEAR: DRM_DEBUG("RADEON_CMD_VECLINEAR\n"); - if (radeon_emit_veclinear(dev_priv, header, cmdbuf)) { + if (radeon_emit_veclinear(dev_priv, *header, cmdbuf)) { DRM_ERROR("radeon_emit_veclinear failed\n"); goto err; } break; default: - DRM_ERROR("bad cmd_type %d at %p\n", - header.header.cmd_type, - cmdbuf->buf - sizeof(header)); + DRM_ERROR("bad cmd_type %d at byte %d\n", + header->header.cmd_type, + cmdbuf->buffer->iterator); goto err; } } - if (orig_bufsz != 0) - drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); + drm_buffer_free(cmdbuf->buffer); + done: DRM_DEBUG("DONE\n"); COMMIT_RING(); return 0; err: - if (orig_bufsz != 0) - drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); + drm_buffer_free(cmdbuf->buffer); return -EINVAL; } @@ -2987,17 +3041,20 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil break; case RADEON_PARAM_LAST_FRAME: dev_priv->stats.last_frame_reads++; - value = GET_SCRATCH(0); + value = GET_SCRATCH(dev_priv, 0); break; case RADEON_PARAM_LAST_DISPATCH: - value = GET_SCRATCH(1); + value = GET_SCRATCH(dev_priv, 1); break; case RADEON_PARAM_LAST_CLEAR: dev_priv->stats.last_clear_reads++; - value = GET_SCRATCH(2); + value = GET_SCRATCH(dev_priv, 2); break; case RADEON_PARAM_IRQ_NR: - value = dev->irq; + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + value = 0; + else + value = dev->pdev->irq; break; case RADEON_PARAM_GART_BASE: value = dev_priv->gart_vm_start; @@ -3020,7 +3077,7 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil */ case RADEON_PARAM_SAREA_HANDLE: /* The lock is the first dword in the sarea. */ - value = (long)dev->lock.hw_lock; + /* no users of this parameter */ break; #endif case RADEON_PARAM_GART_TEX_HANDLE: @@ -3029,7 +3086,10 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil case RADEON_PARAM_SCRATCH_OFFSET: if (!dev_priv->writeback_works) return -EINVAL; - value = RADEON_SCRATCH_REG_OFFSET; + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + value = R600_SCRATCH_REG_OFFSET; + else + value = RADEON_SCRATCH_REG_OFFSET; break; case RADEON_PARAM_CARD_TYPE: if (dev_priv->flags & RADEON_IS_PCIE) @@ -3048,12 +3108,15 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil case RADEON_PARAM_NUM_GB_PIPES: value = dev_priv->num_gb_pipes; break; + case RADEON_PARAM_NUM_Z_PIPES: + value = dev_priv->num_z_pipes; + break; default: DRM_DEBUG("Invalid parameter %d\n", param->param); return -EINVAL; } - if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { + if (copy_to_user(param->value, &value, sizeof(int))) { DRM_ERROR("copy_to_user\n"); return -EFAULT; } @@ -3064,6 +3127,7 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; drm_radeon_setparam_t *sp = data; struct drm_radeon_driver_file_fields *radeon_priv; @@ -3078,12 +3142,14 @@ static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_fil DRM_DEBUG("color tiling disabled\n"); dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO; dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO; - dev_priv->sarea_priv->tiling_enabled = 0; + if (master_priv->sarea_priv) + master_priv->sarea_priv->tiling_enabled = 0; } else if (sp->value == 1) { DRM_DEBUG("color tiling enabled\n"); dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO; dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO; - dev_priv->sarea_priv->tiling_enabled = 1; + if (master_priv->sarea_priv) + master_priv->sarea_priv->tiling_enabled = 1; } break; case RADEON_SETPARAM_PCIGART_LOCATION: @@ -3129,14 +3195,7 @@ void radeon_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) void radeon_driver_lastclose(struct drm_device *dev) { - if (dev->dev_private) { - drm_radeon_private_t *dev_priv = dev->dev_private; - - if (dev_priv->sarea_priv && - dev_priv->sarea_priv->pfCurrentPage != 0) - radeon_cp_dispatch_flip(dev); - } - + radeon_surfaces_release(PCIGART_FILE_PRIV, dev->dev_private); radeon_do_release(dev); } @@ -3146,9 +3205,7 @@ int radeon_driver_open(struct drm_device *dev, struct drm_file *file_priv) struct drm_radeon_driver_file_fields *radeon_priv; DRM_DEBUG("\n"); - radeon_priv = - (struct drm_radeon_driver_file_fields *) - drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES); + radeon_priv = kmalloc(sizeof(*radeon_priv), GFP_KERNEL); if (!radeon_priv) return -ENOMEM; @@ -3167,37 +3224,38 @@ void radeon_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) struct drm_radeon_driver_file_fields *radeon_priv = file_priv->driver_priv; - drm_free(radeon_priv, sizeof(*radeon_priv), DRM_MEM_FILES); + kfree(radeon_priv); } struct drm_ioctl_desc radeon_ioctls[] = { - DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_RESET, radeon_engine_reset, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_SWAP, radeon_cp_swap, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_CLEAR, radeon_cp_clear, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_INDICES, radeon_cp_indices, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_FLIP, radeon_cp_flip, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_FREE, radeon_mem_free, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH) + DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_RESET, radeon_engine_reset, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_SWAP, radeon_cp_swap, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_CLEAR, radeon_cp_clear, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_INDICES, radeon_cp_indices, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_FLIP, radeon_cp_flip, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_FREE, radeon_mem_free, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH), + DRM_IOCTL_DEF_DRV(RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH) }; -int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); +int radeon_max_ioctl = ARRAY_SIZE(radeon_ioctls); |
