1/* mga_warp.c -- Matrox G200/G400 WARP engine management -*- linux-c -*- 2 * Created: Thu Jan 11 21:29:32 2001 by gareth@valinux.com 3 * 4 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the next 15 * paragraph) shall be included in all copies or substantial portions of the 16 * Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 * OTHER DEALINGS IN THE SOFTWARE. 25 * 26 * Authors: 27 * Gareth Hughes <gareth@valinux.com> 28 *
| 1/* mga_warp.c -- Matrox G200/G400 WARP engine management -*- linux-c -*- 2 * Created: Thu Jan 11 21:29:32 2001 by gareth@valinux.com 3 * 4 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the next 15 * paragraph) shall be included in all copies or substantial portions of the 16 * Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 * OTHER DEALINGS IN THE SOFTWARE. 25 * 26 * Authors: 27 * Gareth Hughes <gareth@valinux.com> 28 *
|
33#include "dev/drm/mga.h" 34#include "dev/drm/drmP.h" 35#include "dev/drm/drm.h" 36#include "dev/drm/mga_drm.h" 37#include "dev/drm/mga_drv.h" 38#include "dev/drm/mga_ucode.h" 39 40 41#define MGA_WARP_CODE_ALIGN 256 /* in bytes */ 42 43#define WARP_UCODE_SIZE( which ) \ 44 ((sizeof(which) / MGA_WARP_CODE_ALIGN + 1) * MGA_WARP_CODE_ALIGN) 45 46#define WARP_UCODE_INSTALL( which, where ) \ 47do { \ 48 DRM_DEBUG( " pcbase = 0x%08lx vcbase = %p\n", pcbase, vcbase );\ 49 dev_priv->warp_pipe_phys[where] = pcbase; \ 50 memcpy( vcbase, which, sizeof(which) ); \ 51 pcbase += WARP_UCODE_SIZE( which ); \ 52 vcbase += WARP_UCODE_SIZE( which ); \ 53} while (0) 54 55 56static unsigned int mga_warp_g400_microcode_size( drm_mga_private_t *dev_priv ) 57{ 58 unsigned int size; 59 60 size = ( WARP_UCODE_SIZE( warp_g400_tgz ) + 61 WARP_UCODE_SIZE( warp_g400_tgza ) + 62 WARP_UCODE_SIZE( warp_g400_tgzaf ) + 63 WARP_UCODE_SIZE( warp_g400_tgzf ) + 64 WARP_UCODE_SIZE( warp_g400_tgzs ) + 65 WARP_UCODE_SIZE( warp_g400_tgzsa ) + 66 WARP_UCODE_SIZE( warp_g400_tgzsaf ) + 67 WARP_UCODE_SIZE( warp_g400_tgzsf ) + 68 WARP_UCODE_SIZE( warp_g400_t2gz ) + 69 WARP_UCODE_SIZE( warp_g400_t2gza ) + 70 WARP_UCODE_SIZE( warp_g400_t2gzaf ) + 71 WARP_UCODE_SIZE( warp_g400_t2gzf ) + 72 WARP_UCODE_SIZE( warp_g400_t2gzs ) + 73 WARP_UCODE_SIZE( warp_g400_t2gzsa ) + 74 WARP_UCODE_SIZE( warp_g400_t2gzsaf ) + 75 WARP_UCODE_SIZE( warp_g400_t2gzsf ) ); 76 77 size = PAGE_ALIGN( size ); 78 79 DRM_DEBUG( "G400 ucode size = %d bytes\n", size ); 80 return size; 81} 82 83static unsigned int mga_warp_g200_microcode_size( drm_mga_private_t *dev_priv ) 84{ 85 unsigned int size; 86 87 size = ( WARP_UCODE_SIZE( warp_g200_tgz ) + 88 WARP_UCODE_SIZE( warp_g200_tgza ) + 89 WARP_UCODE_SIZE( warp_g200_tgzaf ) + 90 WARP_UCODE_SIZE( warp_g200_tgzf ) + 91 WARP_UCODE_SIZE( warp_g200_tgzs ) + 92 WARP_UCODE_SIZE( warp_g200_tgzsa ) + 93 WARP_UCODE_SIZE( warp_g200_tgzsaf ) + 94 WARP_UCODE_SIZE( warp_g200_tgzsf ) ); 95 96 size = PAGE_ALIGN( size ); 97 98 DRM_DEBUG( "G200 ucode size = %d bytes\n", size ); 99 return size; 100} 101 102static int mga_warp_install_g400_microcode( drm_mga_private_t *dev_priv ) 103{ 104 unsigned char *vcbase = dev_priv->warp->handle; 105 unsigned long pcbase = dev_priv->warp->offset; 106 unsigned int size; 107 108 size = mga_warp_g400_microcode_size( dev_priv ); 109 if ( size > dev_priv->warp->size ) { 110 DRM_ERROR( "microcode too large! (%u > %lu)\n", 111 size, dev_priv->warp->size ); 112 return DRM_ERR(ENOMEM); 113 } 114 115 memset( dev_priv->warp_pipe_phys, 0, 116 sizeof(dev_priv->warp_pipe_phys) ); 117 118 WARP_UCODE_INSTALL( warp_g400_tgz, MGA_WARP_TGZ ); 119 WARP_UCODE_INSTALL( warp_g400_tgzf, MGA_WARP_TGZF ); 120 WARP_UCODE_INSTALL( warp_g400_tgza, MGA_WARP_TGZA ); 121 WARP_UCODE_INSTALL( warp_g400_tgzaf, MGA_WARP_TGZAF ); 122 WARP_UCODE_INSTALL( warp_g400_tgzs, MGA_WARP_TGZS ); 123 WARP_UCODE_INSTALL( warp_g400_tgzsf, MGA_WARP_TGZSF ); 124 WARP_UCODE_INSTALL( warp_g400_tgzsa, MGA_WARP_TGZSA ); 125 WARP_UCODE_INSTALL( warp_g400_tgzsaf, MGA_WARP_TGZSAF ); 126 127 WARP_UCODE_INSTALL( warp_g400_t2gz, MGA_WARP_T2GZ ); 128 WARP_UCODE_INSTALL( warp_g400_t2gzf, MGA_WARP_T2GZF ); 129 WARP_UCODE_INSTALL( warp_g400_t2gza, MGA_WARP_T2GZA ); 130 WARP_UCODE_INSTALL( warp_g400_t2gzaf, MGA_WARP_T2GZAF ); 131 WARP_UCODE_INSTALL( warp_g400_t2gzs, MGA_WARP_T2GZS ); 132 WARP_UCODE_INSTALL( warp_g400_t2gzsf, MGA_WARP_T2GZSF ); 133 WARP_UCODE_INSTALL( warp_g400_t2gzsa, MGA_WARP_T2GZSA ); 134 WARP_UCODE_INSTALL( warp_g400_t2gzsaf, MGA_WARP_T2GZSAF ); 135 136 return 0; 137} 138 139static int mga_warp_install_g200_microcode( drm_mga_private_t *dev_priv ) 140{ 141 unsigned char *vcbase = dev_priv->warp->handle; 142 unsigned long pcbase = dev_priv->warp->offset; 143 unsigned int size; 144 145 size = mga_warp_g200_microcode_size( dev_priv ); 146 if ( size > dev_priv->warp->size ) { 147 DRM_ERROR( "microcode too large! (%u > %lu)\n", 148 size, dev_priv->warp->size ); 149 return DRM_ERR(ENOMEM); 150 } 151 152 memset( dev_priv->warp_pipe_phys, 0, 153 sizeof(dev_priv->warp_pipe_phys) ); 154 155 WARP_UCODE_INSTALL( warp_g200_tgz, MGA_WARP_TGZ ); 156 WARP_UCODE_INSTALL( warp_g200_tgzf, MGA_WARP_TGZF ); 157 WARP_UCODE_INSTALL( warp_g200_tgza, MGA_WARP_TGZA ); 158 WARP_UCODE_INSTALL( warp_g200_tgzaf, MGA_WARP_TGZAF ); 159 WARP_UCODE_INSTALL( warp_g200_tgzs, MGA_WARP_TGZS ); 160 WARP_UCODE_INSTALL( warp_g200_tgzsf, MGA_WARP_TGZSF ); 161 WARP_UCODE_INSTALL( warp_g200_tgzsa, MGA_WARP_TGZSA ); 162 WARP_UCODE_INSTALL( warp_g200_tgzsaf, MGA_WARP_TGZSAF ); 163 164 return 0; 165} 166 167int mga_warp_install_microcode( drm_mga_private_t *dev_priv ) 168{ 169 switch ( dev_priv->chipset ) { 170 case MGA_CARD_TYPE_G400: 171 return mga_warp_install_g400_microcode( dev_priv ); 172 case MGA_CARD_TYPE_G200: 173 return mga_warp_install_g200_microcode( dev_priv ); 174 default: 175 return DRM_ERR(EINVAL); 176 } 177} 178 179#define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE) 180 181int mga_warp_init( drm_mga_private_t *dev_priv ) 182{ 183 u32 wmisc; 184 185 /* FIXME: Get rid of these damned magic numbers... 186 */ 187 switch ( dev_priv->chipset ) { 188 case MGA_CARD_TYPE_G400: 189 MGA_WRITE( MGA_WIADDR2, MGA_WMODE_SUSPEND ); 190 MGA_WRITE( MGA_WGETMSB, 0x00000E00 ); 191 MGA_WRITE( MGA_WVRTXSZ, 0x00001807 ); 192 MGA_WRITE( MGA_WACCEPTSEQ, 0x18000000 ); 193 break; 194 case MGA_CARD_TYPE_G200: 195 MGA_WRITE( MGA_WIADDR, MGA_WMODE_SUSPEND ); 196 MGA_WRITE( MGA_WGETMSB, 0x1606 ); 197 MGA_WRITE( MGA_WVRTXSZ, 7 ); 198 break; 199 default: 200 return DRM_ERR(EINVAL); 201 } 202 203 MGA_WRITE( MGA_WMISC, (MGA_WUCODECACHE_ENABLE | 204 MGA_WMASTER_ENABLE | 205 MGA_WCACHEFLUSH_ENABLE) ); 206 wmisc = MGA_READ( MGA_WMISC ); 207 if ( wmisc != WMISC_EXPECTED ) { 208 DRM_ERROR( "WARP engine config failed! 0x%x != 0x%x\n", 209 wmisc, WMISC_EXPECTED ); 210 return DRM_ERR(EINVAL); 211 } 212 213 return 0; 214}
| 32#include "dev/drm/mga.h" 33#include "dev/drm/drmP.h" 34#include "dev/drm/drm.h" 35#include "dev/drm/mga_drm.h" 36#include "dev/drm/mga_drv.h" 37#include "dev/drm/mga_ucode.h" 38 39 40#define MGA_WARP_CODE_ALIGN 256 /* in bytes */ 41 42#define WARP_UCODE_SIZE( which ) \ 43 ((sizeof(which) / MGA_WARP_CODE_ALIGN + 1) * MGA_WARP_CODE_ALIGN) 44 45#define WARP_UCODE_INSTALL( which, where ) \ 46do { \ 47 DRM_DEBUG( " pcbase = 0x%08lx vcbase = %p\n", pcbase, vcbase );\ 48 dev_priv->warp_pipe_phys[where] = pcbase; \ 49 memcpy( vcbase, which, sizeof(which) ); \ 50 pcbase += WARP_UCODE_SIZE( which ); \ 51 vcbase += WARP_UCODE_SIZE( which ); \ 52} while (0) 53 54 55static unsigned int mga_warp_g400_microcode_size( drm_mga_private_t *dev_priv ) 56{ 57 unsigned int size; 58 59 size = ( WARP_UCODE_SIZE( warp_g400_tgz ) + 60 WARP_UCODE_SIZE( warp_g400_tgza ) + 61 WARP_UCODE_SIZE( warp_g400_tgzaf ) + 62 WARP_UCODE_SIZE( warp_g400_tgzf ) + 63 WARP_UCODE_SIZE( warp_g400_tgzs ) + 64 WARP_UCODE_SIZE( warp_g400_tgzsa ) + 65 WARP_UCODE_SIZE( warp_g400_tgzsaf ) + 66 WARP_UCODE_SIZE( warp_g400_tgzsf ) + 67 WARP_UCODE_SIZE( warp_g400_t2gz ) + 68 WARP_UCODE_SIZE( warp_g400_t2gza ) + 69 WARP_UCODE_SIZE( warp_g400_t2gzaf ) + 70 WARP_UCODE_SIZE( warp_g400_t2gzf ) + 71 WARP_UCODE_SIZE( warp_g400_t2gzs ) + 72 WARP_UCODE_SIZE( warp_g400_t2gzsa ) + 73 WARP_UCODE_SIZE( warp_g400_t2gzsaf ) + 74 WARP_UCODE_SIZE( warp_g400_t2gzsf ) ); 75 76 size = PAGE_ALIGN( size ); 77 78 DRM_DEBUG( "G400 ucode size = %d bytes\n", size ); 79 return size; 80} 81 82static unsigned int mga_warp_g200_microcode_size( drm_mga_private_t *dev_priv ) 83{ 84 unsigned int size; 85 86 size = ( WARP_UCODE_SIZE( warp_g200_tgz ) + 87 WARP_UCODE_SIZE( warp_g200_tgza ) + 88 WARP_UCODE_SIZE( warp_g200_tgzaf ) + 89 WARP_UCODE_SIZE( warp_g200_tgzf ) + 90 WARP_UCODE_SIZE( warp_g200_tgzs ) + 91 WARP_UCODE_SIZE( warp_g200_tgzsa ) + 92 WARP_UCODE_SIZE( warp_g200_tgzsaf ) + 93 WARP_UCODE_SIZE( warp_g200_tgzsf ) ); 94 95 size = PAGE_ALIGN( size ); 96 97 DRM_DEBUG( "G200 ucode size = %d bytes\n", size ); 98 return size; 99} 100 101static int mga_warp_install_g400_microcode( drm_mga_private_t *dev_priv ) 102{ 103 unsigned char *vcbase = dev_priv->warp->handle; 104 unsigned long pcbase = dev_priv->warp->offset; 105 unsigned int size; 106 107 size = mga_warp_g400_microcode_size( dev_priv ); 108 if ( size > dev_priv->warp->size ) { 109 DRM_ERROR( "microcode too large! (%u > %lu)\n", 110 size, dev_priv->warp->size ); 111 return DRM_ERR(ENOMEM); 112 } 113 114 memset( dev_priv->warp_pipe_phys, 0, 115 sizeof(dev_priv->warp_pipe_phys) ); 116 117 WARP_UCODE_INSTALL( warp_g400_tgz, MGA_WARP_TGZ ); 118 WARP_UCODE_INSTALL( warp_g400_tgzf, MGA_WARP_TGZF ); 119 WARP_UCODE_INSTALL( warp_g400_tgza, MGA_WARP_TGZA ); 120 WARP_UCODE_INSTALL( warp_g400_tgzaf, MGA_WARP_TGZAF ); 121 WARP_UCODE_INSTALL( warp_g400_tgzs, MGA_WARP_TGZS ); 122 WARP_UCODE_INSTALL( warp_g400_tgzsf, MGA_WARP_TGZSF ); 123 WARP_UCODE_INSTALL( warp_g400_tgzsa, MGA_WARP_TGZSA ); 124 WARP_UCODE_INSTALL( warp_g400_tgzsaf, MGA_WARP_TGZSAF ); 125 126 WARP_UCODE_INSTALL( warp_g400_t2gz, MGA_WARP_T2GZ ); 127 WARP_UCODE_INSTALL( warp_g400_t2gzf, MGA_WARP_T2GZF ); 128 WARP_UCODE_INSTALL( warp_g400_t2gza, MGA_WARP_T2GZA ); 129 WARP_UCODE_INSTALL( warp_g400_t2gzaf, MGA_WARP_T2GZAF ); 130 WARP_UCODE_INSTALL( warp_g400_t2gzs, MGA_WARP_T2GZS ); 131 WARP_UCODE_INSTALL( warp_g400_t2gzsf, MGA_WARP_T2GZSF ); 132 WARP_UCODE_INSTALL( warp_g400_t2gzsa, MGA_WARP_T2GZSA ); 133 WARP_UCODE_INSTALL( warp_g400_t2gzsaf, MGA_WARP_T2GZSAF ); 134 135 return 0; 136} 137 138static int mga_warp_install_g200_microcode( drm_mga_private_t *dev_priv ) 139{ 140 unsigned char *vcbase = dev_priv->warp->handle; 141 unsigned long pcbase = dev_priv->warp->offset; 142 unsigned int size; 143 144 size = mga_warp_g200_microcode_size( dev_priv ); 145 if ( size > dev_priv->warp->size ) { 146 DRM_ERROR( "microcode too large! (%u > %lu)\n", 147 size, dev_priv->warp->size ); 148 return DRM_ERR(ENOMEM); 149 } 150 151 memset( dev_priv->warp_pipe_phys, 0, 152 sizeof(dev_priv->warp_pipe_phys) ); 153 154 WARP_UCODE_INSTALL( warp_g200_tgz, MGA_WARP_TGZ ); 155 WARP_UCODE_INSTALL( warp_g200_tgzf, MGA_WARP_TGZF ); 156 WARP_UCODE_INSTALL( warp_g200_tgza, MGA_WARP_TGZA ); 157 WARP_UCODE_INSTALL( warp_g200_tgzaf, MGA_WARP_TGZAF ); 158 WARP_UCODE_INSTALL( warp_g200_tgzs, MGA_WARP_TGZS ); 159 WARP_UCODE_INSTALL( warp_g200_tgzsf, MGA_WARP_TGZSF ); 160 WARP_UCODE_INSTALL( warp_g200_tgzsa, MGA_WARP_TGZSA ); 161 WARP_UCODE_INSTALL( warp_g200_tgzsaf, MGA_WARP_TGZSAF ); 162 163 return 0; 164} 165 166int mga_warp_install_microcode( drm_mga_private_t *dev_priv ) 167{ 168 switch ( dev_priv->chipset ) { 169 case MGA_CARD_TYPE_G400: 170 return mga_warp_install_g400_microcode( dev_priv ); 171 case MGA_CARD_TYPE_G200: 172 return mga_warp_install_g200_microcode( dev_priv ); 173 default: 174 return DRM_ERR(EINVAL); 175 } 176} 177 178#define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE) 179 180int mga_warp_init( drm_mga_private_t *dev_priv ) 181{ 182 u32 wmisc; 183 184 /* FIXME: Get rid of these damned magic numbers... 185 */ 186 switch ( dev_priv->chipset ) { 187 case MGA_CARD_TYPE_G400: 188 MGA_WRITE( MGA_WIADDR2, MGA_WMODE_SUSPEND ); 189 MGA_WRITE( MGA_WGETMSB, 0x00000E00 ); 190 MGA_WRITE( MGA_WVRTXSZ, 0x00001807 ); 191 MGA_WRITE( MGA_WACCEPTSEQ, 0x18000000 ); 192 break; 193 case MGA_CARD_TYPE_G200: 194 MGA_WRITE( MGA_WIADDR, MGA_WMODE_SUSPEND ); 195 MGA_WRITE( MGA_WGETMSB, 0x1606 ); 196 MGA_WRITE( MGA_WVRTXSZ, 7 ); 197 break; 198 default: 199 return DRM_ERR(EINVAL); 200 } 201 202 MGA_WRITE( MGA_WMISC, (MGA_WUCODECACHE_ENABLE | 203 MGA_WMASTER_ENABLE | 204 MGA_WCACHEFLUSH_ENABLE) ); 205 wmisc = MGA_READ( MGA_WMISC ); 206 if ( wmisc != WMISC_EXPECTED ) { 207 DRM_ERROR( "WARP engine config failed! 0x%x != 0x%x\n", 208 wmisc, WMISC_EXPECTED ); 209 return DRM_ERR(EINVAL); 210 } 211 212 return 0; 213}
|