diff options
Diffstat (limited to 'drivers/char/drm/mga_state.c')
-rw-r--r-- | drivers/char/drm/mga_state.c | 158 |
1 files changed, 112 insertions, 46 deletions
diff --git a/drivers/char/drm/mga_state.c b/drivers/char/drm/mga_state.c index 3c7a8f5ba501..05bbb4719376 100644 --- a/drivers/char/drm/mga_state.c +++ b/drivers/char/drm/mga_state.c | |||
@@ -53,16 +53,16 @@ static void mga_emit_clip_rect( drm_mga_private_t *dev_priv, | |||
53 | 53 | ||
54 | /* Force reset of DWGCTL on G400 (eliminates clip disable bit). | 54 | /* Force reset of DWGCTL on G400 (eliminates clip disable bit). |
55 | */ | 55 | */ |
56 | if ( dev_priv->chipset == MGA_CARD_TYPE_G400 ) { | 56 | if (dev_priv->chipset == MGA_CARD_TYPE_G400) { |
57 | DMA_BLOCK( MGA_DWGCTL, ctx->dwgctl, | 57 | DMA_BLOCK(MGA_DWGCTL, ctx->dwgctl, |
58 | MGA_LEN + MGA_EXEC, 0x80000000, | 58 | MGA_LEN + MGA_EXEC, 0x80000000, |
59 | MGA_DWGCTL, ctx->dwgctl, | 59 | MGA_DWGCTL, ctx->dwgctl, |
60 | MGA_LEN + MGA_EXEC, 0x80000000 ); | 60 | MGA_LEN + MGA_EXEC, 0x80000000); |
61 | } | 61 | } |
62 | DMA_BLOCK( MGA_DMAPAD, 0x00000000, | 62 | DMA_BLOCK(MGA_DMAPAD, 0x00000000, |
63 | MGA_CXBNDRY, (box->x2 << 16) | box->x1, | 63 | MGA_CXBNDRY, ((box->x2 - 1) << 16) | box->x1, |
64 | MGA_YTOP, box->y1 * pitch, | 64 | MGA_YTOP, box->y1 * pitch, |
65 | MGA_YBOT, box->y2 * pitch ); | 65 | MGA_YBOT, (box->y2 - 1) * pitch); |
66 | 66 | ||
67 | ADVANCE_DMA(); | 67 | ADVANCE_DMA(); |
68 | } | 68 | } |
@@ -260,12 +260,11 @@ static __inline__ void mga_g200_emit_pipe( drm_mga_private_t *dev_priv ) | |||
260 | 260 | ||
261 | /* Padding required to to hardware bug. | 261 | /* Padding required to to hardware bug. |
262 | */ | 262 | */ |
263 | DMA_BLOCK( MGA_DMAPAD, 0xffffffff, | 263 | DMA_BLOCK(MGA_DMAPAD, 0xffffffff, |
264 | MGA_DMAPAD, 0xffffffff, | 264 | MGA_DMAPAD, 0xffffffff, |
265 | MGA_DMAPAD, 0xffffffff, | 265 | MGA_DMAPAD, 0xffffffff, |
266 | MGA_WIADDR, (dev_priv->warp_pipe_phys[pipe] | | 266 | MGA_WIADDR, (dev_priv->warp_pipe_phys[pipe] | |
267 | MGA_WMODE_START | | 267 | MGA_WMODE_START | dev_priv->wagp_enable)); |
268 | MGA_WAGP_ENABLE) ); | ||
269 | 268 | ||
270 | ADVANCE_DMA(); | 269 | ADVANCE_DMA(); |
271 | } | 270 | } |
@@ -342,12 +341,11 @@ static __inline__ void mga_g400_emit_pipe( drm_mga_private_t *dev_priv ) | |||
342 | MGA_WR60, MGA_G400_WR_MAGIC ); /* tex1 height */ | 341 | MGA_WR60, MGA_G400_WR_MAGIC ); /* tex1 height */ |
343 | 342 | ||
344 | /* Padding required to to hardware bug */ | 343 | /* Padding required to to hardware bug */ |
345 | DMA_BLOCK( MGA_DMAPAD, 0xffffffff, | 344 | DMA_BLOCK(MGA_DMAPAD, 0xffffffff, |
346 | MGA_DMAPAD, 0xffffffff, | 345 | MGA_DMAPAD, 0xffffffff, |
347 | MGA_DMAPAD, 0xffffffff, | 346 | MGA_DMAPAD, 0xffffffff, |
348 | MGA_WIADDR2, (dev_priv->warp_pipe_phys[pipe] | | 347 | MGA_WIADDR2, (dev_priv->warp_pipe_phys[pipe] | |
349 | MGA_WMODE_START | | 348 | MGA_WMODE_START | dev_priv->wagp_enable)); |
350 | MGA_WAGP_ENABLE) ); | ||
351 | 349 | ||
352 | ADVANCE_DMA(); | 350 | ADVANCE_DMA(); |
353 | } | 351 | } |
@@ -459,9 +457,9 @@ static int mga_verify_state( drm_mga_private_t *dev_priv ) | |||
459 | if ( dirty & MGA_UPLOAD_TEX0 ) | 457 | if ( dirty & MGA_UPLOAD_TEX0 ) |
460 | ret |= mga_verify_tex( dev_priv, 0 ); | 458 | ret |= mga_verify_tex( dev_priv, 0 ); |
461 | 459 | ||
462 | if ( dev_priv->chipset == MGA_CARD_TYPE_G400 ) { | 460 | if (dev_priv->chipset >= MGA_CARD_TYPE_G400) { |
463 | if ( dirty & MGA_UPLOAD_TEX1 ) | 461 | if (dirty & MGA_UPLOAD_TEX1) |
464 | ret |= mga_verify_tex( dev_priv, 1 ); | 462 | ret |= mga_verify_tex(dev_priv, 1); |
465 | 463 | ||
466 | if ( dirty & MGA_UPLOAD_PIPE ) | 464 | if ( dirty & MGA_UPLOAD_PIPE ) |
467 | ret |= ( sarea_priv->warp_pipe > MGA_MAX_G400_PIPES ); | 465 | ret |= ( sarea_priv->warp_pipe > MGA_MAX_G400_PIPES ); |
@@ -686,12 +684,12 @@ static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf ) | |||
686 | 684 | ||
687 | BEGIN_DMA( 1 ); | 685 | BEGIN_DMA( 1 ); |
688 | 686 | ||
689 | DMA_BLOCK( MGA_DMAPAD, 0x00000000, | 687 | DMA_BLOCK(MGA_DMAPAD, 0x00000000, |
690 | MGA_DMAPAD, 0x00000000, | 688 | MGA_DMAPAD, 0x00000000, |
691 | MGA_SECADDRESS, (address | | 689 | MGA_SECADDRESS, (address | |
692 | MGA_DMA_VERTEX), | 690 | MGA_DMA_VERTEX), |
693 | MGA_SECEND, ((address + length) | | 691 | MGA_SECEND, ((address + length) | |
694 | MGA_PAGPXFER) ); | 692 | dev_priv->dma_access)); |
695 | 693 | ||
696 | ADVANCE_DMA(); | 694 | ADVANCE_DMA(); |
697 | } while ( ++i < sarea_priv->nbox ); | 695 | } while ( ++i < sarea_priv->nbox ); |
@@ -733,11 +731,11 @@ static void mga_dma_dispatch_indices( drm_device_t *dev, drm_buf_t *buf, | |||
733 | 731 | ||
734 | BEGIN_DMA( 1 ); | 732 | BEGIN_DMA( 1 ); |
735 | 733 | ||
736 | DMA_BLOCK( MGA_DMAPAD, 0x00000000, | 734 | DMA_BLOCK(MGA_DMAPAD, 0x00000000, |
737 | MGA_DMAPAD, 0x00000000, | 735 | MGA_DMAPAD, 0x00000000, |
738 | MGA_SETUPADDRESS, address + start, | 736 | MGA_SETUPADDRESS, address + start, |
739 | MGA_SETUPEND, ((address + end) | | 737 | MGA_SETUPEND, ((address + end) | |
740 | MGA_PAGPXFER) ); | 738 | dev_priv->dma_access)); |
741 | 739 | ||
742 | ADVANCE_DMA(); | 740 | ADVANCE_DMA(); |
743 | } while ( ++i < sarea_priv->nbox ); | 741 | } while ( ++i < sarea_priv->nbox ); |
@@ -764,7 +762,7 @@ static void mga_dma_dispatch_iload( drm_device_t *dev, drm_buf_t *buf, | |||
764 | drm_mga_private_t *dev_priv = dev->dev_private; | 762 | drm_mga_private_t *dev_priv = dev->dev_private; |
765 | drm_mga_buf_priv_t *buf_priv = buf->dev_private; | 763 | drm_mga_buf_priv_t *buf_priv = buf->dev_private; |
766 | drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state; | 764 | drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state; |
767 | u32 srcorg = buf->bus_address | MGA_SRCACC_AGP | MGA_SRCMAP_SYSMEM; | 765 | u32 srcorg = buf->bus_address | dev_priv->dma_access | MGA_SRCMAP_SYSMEM; |
768 | u32 y2; | 766 | u32 y2; |
769 | DMA_LOCALS; | 767 | DMA_LOCALS; |
770 | DRM_DEBUG( "buf=%d used=%d\n", buf->idx, buf->used ); | 768 | DRM_DEBUG( "buf=%d used=%d\n", buf->idx, buf->used ); |
@@ -1095,6 +1093,9 @@ static int mga_getparam( DRM_IOCTL_ARGS ) | |||
1095 | case MGA_PARAM_IRQ_NR: | 1093 | case MGA_PARAM_IRQ_NR: |
1096 | value = dev->irq; | 1094 | value = dev->irq; |
1097 | break; | 1095 | break; |
1096 | case MGA_PARAM_CARD_TYPE: | ||
1097 | value = dev_priv->chipset; | ||
1098 | break; | ||
1098 | default: | 1099 | default: |
1099 | return DRM_ERR(EINVAL); | 1100 | return DRM_ERR(EINVAL); |
1100 | } | 1101 | } |
@@ -1107,17 +1108,82 @@ static int mga_getparam( DRM_IOCTL_ARGS ) | |||
1107 | return 0; | 1108 | return 0; |
1108 | } | 1109 | } |
1109 | 1110 | ||
1111 | static int mga_set_fence(DRM_IOCTL_ARGS) | ||
1112 | { | ||
1113 | DRM_DEVICE; | ||
1114 | drm_mga_private_t *dev_priv = dev->dev_private; | ||
1115 | u32 temp; | ||
1116 | DMA_LOCALS; | ||
1117 | |||
1118 | if (!dev_priv) { | ||
1119 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
1120 | return DRM_ERR(EINVAL); | ||
1121 | } | ||
1122 | |||
1123 | DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); | ||
1124 | |||
1125 | /* I would normal do this assignment in the declaration of temp, | ||
1126 | * but dev_priv may be NULL. | ||
1127 | */ | ||
1128 | |||
1129 | temp = dev_priv->next_fence_to_post; | ||
1130 | dev_priv->next_fence_to_post++; | ||
1131 | |||
1132 | BEGIN_DMA(1); | ||
1133 | DMA_BLOCK(MGA_DMAPAD, 0x00000000, | ||
1134 | MGA_DMAPAD, 0x00000000, | ||
1135 | MGA_DMAPAD, 0x00000000, | ||
1136 | MGA_SOFTRAP, 0x00000000); | ||
1137 | ADVANCE_DMA(); | ||
1138 | |||
1139 | if (DRM_COPY_TO_USER( (u32 __user *) data, & temp, sizeof(u32))) { | ||
1140 | DRM_ERROR("copy_to_user\n"); | ||
1141 | return DRM_ERR(EFAULT); | ||
1142 | } | ||
1143 | |||
1144 | return 0; | ||
1145 | } | ||
1146 | |||
1147 | static int mga_wait_fence(DRM_IOCTL_ARGS) | ||
1148 | { | ||
1149 | DRM_DEVICE; | ||
1150 | drm_mga_private_t *dev_priv = dev->dev_private; | ||
1151 | u32 fence; | ||
1152 | |||
1153 | if (!dev_priv) { | ||
1154 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
1155 | return DRM_ERR(EINVAL); | ||
1156 | } | ||
1157 | |||
1158 | DRM_COPY_FROM_USER_IOCTL(fence, (u32 __user *) data, sizeof(u32)); | ||
1159 | |||
1160 | DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); | ||
1161 | |||
1162 | mga_driver_fence_wait(dev, & fence); | ||
1163 | |||
1164 | if (DRM_COPY_TO_USER( (u32 __user *) data, & fence, sizeof(u32))) { | ||
1165 | DRM_ERROR("copy_to_user\n"); | ||
1166 | return DRM_ERR(EFAULT); | ||
1167 | } | ||
1168 | |||
1169 | return 0; | ||
1170 | } | ||
1171 | |||
1110 | drm_ioctl_desc_t mga_ioctls[] = { | 1172 | drm_ioctl_desc_t mga_ioctls[] = { |
1111 | [DRM_IOCTL_NR(DRM_MGA_INIT)] = { mga_dma_init, 1, 1 }, | 1173 | [DRM_IOCTL_NR(DRM_MGA_INIT)] = {mga_dma_init, 1, 1}, |
1112 | [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = { mga_dma_flush, 1, 0 }, | 1174 | [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = {mga_dma_flush, 1, 0}, |
1113 | [DRM_IOCTL_NR(DRM_MGA_RESET)] = { mga_dma_reset, 1, 0 }, | 1175 | [DRM_IOCTL_NR(DRM_MGA_RESET)] = {mga_dma_reset, 1, 0}, |
1114 | [DRM_IOCTL_NR(DRM_MGA_SWAP)] = { mga_dma_swap, 1, 0 }, | 1176 | [DRM_IOCTL_NR(DRM_MGA_SWAP)] = {mga_dma_swap, 1, 0}, |
1115 | [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = { mga_dma_clear, 1, 0 }, | 1177 | [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = {mga_dma_clear, 1, 0}, |
1116 | [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, | 1178 | [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = {mga_dma_vertex, 1, 0}, |
1117 | [DRM_IOCTL_NR(DRM_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, | 1179 | [DRM_IOCTL_NR(DRM_MGA_INDICES)] = {mga_dma_indices, 1, 0}, |
1118 | [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, | 1180 | [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = {mga_dma_iload, 1, 0}, |
1119 | [DRM_IOCTL_NR(DRM_MGA_BLIT)] = { mga_dma_blit, 1, 0 }, | 1181 | [DRM_IOCTL_NR(DRM_MGA_BLIT)] = {mga_dma_blit, 1, 0}, |
1120 | [DRM_IOCTL_NR(DRM_MGA_GETPARAM)]= { mga_getparam, 1, 0 }, | 1182 | [DRM_IOCTL_NR(DRM_MGA_GETPARAM)] = {mga_getparam, 1, 0}, |
1183 | [DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, 1, 0}, | ||
1184 | [DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, 1, 0}, | ||
1185 | [DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, 1, 1}, | ||
1186 | |||
1121 | }; | 1187 | }; |
1122 | 1188 | ||
1123 | int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); | 1189 | int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); |