1/* 2 * (C) Copyright IBM Corporation 2005 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * on the rights to use, copy, modify, merge, publish, distribute, sub 9 * license, and/or sell copies of the Software, and to permit persons to whom 10 * the Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 25/** 26 * \file mga_bios.c 27 * Routines for processing the PInS data stored in the MGA BIOS. 28 * 29 * The structure of this code was inspired by similar routines in the Linux 30 * kernel matroxfb code. Specifically, the routines in matroxfb_misc.c. In 31 * addition, that code was used in place of documentation about the structure 32 * of the PInS data for non-G450 cards. 33 * 34 * \author Ian Romanick <idr@us.ibm.com> 35 */ 36 37#ifdef HAVE_CONFIG_H 38#include "config.h" 39#endif 40 41/* All drivers should typically include these */ 42#include "xf86.h" 43#include "xf86_OSproc.h" 44 45/* All drivers need this */ 46 47#include "compiler.h" 48 49/* Drivers that need to access the PCI config space directly need this */ 50#include "xf86Pci.h" 51 52#include <X11/Xmd.h> 53 54#include "mga.h" 55 56#if defined(DEBUG) 57#define BIOS_DEBUG 58#endif 59 60/** 61 * Read a little-endian, unaligned data value and return as 16-bit. 62 */ 63static __inline__ CARD16 get_u16( const CARD8 * data ) 64{ 65 CARD16 temp; 66 67 temp = data[1]; 68 temp <<= 8; 69 temp += data[0]; 70 return temp; 71} 72 73 74/** 75 * Read a little-endian, unaligned data value and return as 32-bit. 76 */ 77static __inline__ CARD32 get_u32( const CARD8 * data ) 78{ 79 CARD32 temp; 80 81 82 temp = data[3]; 83 temp <<= 8; 84 temp += data[2]; 85 temp <<= 8; 86 temp += data[1]; 87 temp <<= 8; 88 temp += data[0]; 89 90 return temp; 91} 92 93 94/** 95 * Parse version 0x01XX of the BIOS PInS structure. 96 * 97 * Version 0x01XX of the BIOS PInS structure is only found in Millennium cards. 98 * 99 * \todo 100 * There used to be an "OverclockMem" option that would scale the memory clock 101 * by 12 instead 10. Add support for this back in. 102 */ 103static void mga_parse_bios_ver_1( struct mga_bios_values * bios, 104 const CARD8 * bios_data ) 105{ 106 unsigned maxdac; 107 108 if ( get_u16( & bios_data[24] ) ) { 109 maxdac = get_u16( & bios_data[24] ) * 10; 110 } 111 else { 112 /* There is some disagreement here between the Linux kernel matroxfb 113 * driver and the old X.org mga driver. matroxfb has case-statements 114 * for 0 and 1 (with the values below), and the mga driver has 115 * case-statements for 1 and 2 (with the values below). The default 116 * value for the mga driver is 17500, but the default value for the 117 * matroxfb driver is 240000. 118 */ 119 120 switch( bios_data[22] ) { 121 case 0: maxdac = 175000; break; 122 case 1: maxdac = 220000; break; 123 case 2: maxdac = 250000; break; 124 default: maxdac = 240000; break; 125 } 126 } 127 128 if ( get_u16( & bios_data[28] ) ) { 129 bios->mem_clock = get_u16( & bios_data[28] ) * 10; 130 } 131 132 if ( (bios_data[48] & 0x01) == 0 ) { 133 bios->fast_bitblt = TRUE; 134 } 135 136 bios->pixel.max_freq = maxdac; 137} 138 139 140/** 141 * Parse version 0x02XX of the BIOS PInS structure. 142 * 143 * Version 0x02XX of the BIOS PInS structure is only found in Millennium II 144 * and Mystique cards. 145 */ 146static void mga_parse_bios_ver_2( struct mga_bios_values * bios, 147 const CARD8 * bios_data ) 148{ 149 if ( bios_data[41] != 0xff ) { 150 const unsigned maxdac = (bios_data[41] + 100) * 1000; 151 152 bios->pixel.max_freq = maxdac; 153 bios->system.max_freq = maxdac; 154 } 155 156 if ( bios_data[43] != 0xff ) { 157 const unsigned system_pll = (bios_data[43] + 100) * 1000; 158 bios->mem_clock = system_pll; 159 } 160} 161 162 163/** 164 * Parse version 0x03XX of the BIOS PInS structure. 165 * 166 * Version 0x03XX of the BIOS PInS structure is only found in G100 and G200 167 * cards. 168 */ 169static void mga_parse_bios_ver_3( struct mga_bios_values * bios, 170 const CARD8 * bios_data ) 171{ 172 if ( bios_data[36] != 0xff ) { 173 const unsigned maxdac = (bios_data[36] + 100) * 1000; 174 175 bios->pixel.max_freq = maxdac; 176 bios->system.max_freq = maxdac; 177 } 178 179 if ( (bios_data[52] & 0x20) != 0 ) { 180 bios->pll_ref_freq = 14318; 181 } 182} 183 184 185/** 186 * Parse version 0x04XX of the BIOS PInS structure. 187 * 188 * Version 0x04XX of the BIOS PInS structure is only found in G400 cards. 189 */ 190static void mga_parse_bios_ver_4( struct mga_bios_values * bios, 191 const CARD8 * bios_data ) 192{ 193 if ( bios_data[39] != 0xff ) { 194 const unsigned maxdac = bios_data[39] * 4 * 1000; 195 196 bios->pixel.max_freq = maxdac; 197 bios->system.max_freq = maxdac; 198 } 199 200 if ( bios_data[38] != 0xff ) { 201 const unsigned maxdac = bios_data[38] * 4 * 1000; 202 203 bios->system.max_freq = maxdac; 204 } 205 206 if ( (bios_data[92] & 0x01) != 0 ) { 207 bios->pll_ref_freq = 14318; 208 } 209 210 bios->host_interface = (bios_data[95] >> 3) & 0x07; 211 212 if ( bios_data[65] != 0xff ) { 213 const unsigned system_pll = bios_data[65] * 4 * 1000; 214 bios->mem_clock = system_pll; 215 } 216} 217 218 219/** 220 * Parse version 0x05XX of the BIOS PInS structure. 221 * 222 * Version 0x05XX of the BIOS PInS structure is only found in G450 and G550 223 * cards. 224 */ 225static void mga_parse_bios_ver_5( struct mga_bios_values * bios, 226 const CARD8 * bios_data ) 227{ 228 const unsigned scale = (bios_data[4] != 0) ? 8000 : 6000; 229 230 231 if ( bios_data[38] != 0xff ) { 232 const unsigned maxdac = bios_data[38] * scale; 233 234 bios->pixel.max_freq = maxdac; 235 bios->system.max_freq = maxdac; 236 bios->video.max_freq = maxdac; 237 } 238 239 if ( bios_data[36] != 0xff ) { 240 const unsigned maxdac = bios_data[36] * scale; 241 242 bios->system.max_freq = maxdac; 243 bios->video.max_freq = maxdac; 244 } 245 246 if ( bios_data[37] != 0xff ) { 247 const unsigned maxdac = bios_data[37] * scale; 248 249 bios->video.max_freq = maxdac; 250 } 251 252 253 if ( bios_data[123] != 0xff ) { 254 const unsigned mindac = bios_data[123] * scale; 255 256 bios->pixel.min_freq = mindac; 257 bios->system.min_freq = mindac; 258 bios->video.min_freq = mindac; 259 } 260 261 if ( bios_data[121] != 0xff ) { 262 const unsigned mindac = bios_data[121] * scale; 263 264 bios->system.min_freq = mindac; 265 bios->video.min_freq = mindac; 266 } 267 268 if ( bios_data[122] != 0xff ) { 269 const unsigned mindac = bios_data[122] * scale; 270 271 bios->video.min_freq = mindac; 272 } 273 274 275 if ( bios_data[92] != 0xff ) { 276 const unsigned system_pll = bios_data[92] * 4 * 1000; 277 bios->mem_clock = system_pll; 278 } 279 280 if ( (bios_data[110] & 0x01) != 0 ) { 281 bios->pll_ref_freq = 14318; 282 } 283 284 bios->host_interface = (bios_data[113] >> 3) & 0x07; 285} 286 287 288/** 289 * Read the BIOS data from the card and initialize internal values. 290 */ 291 292Bool mga_read_and_process_bios( ScrnInfoPtr pScrn ) 293{ 294 CARD8 bios_data[0x20000]; 295 unsigned offset; 296 MGAPtr pMga = MGAPTR(pScrn); 297#ifndef XSERVER_LIBPCIACCESS 298 Bool pciBIOS = TRUE; 299#endif 300 static const unsigned expected_length[] = { 0, 64, 64, 64, 128, 128 }; 301 unsigned version; 302 unsigned pins_len; 303 const CARD8 * pins_data; 304 int err; 305#ifdef BIOS_DEBUG 306 static const char * const host_interface_strings[8] = { 307 "Reserved", 308 "Reserved", 309 "Reserved", 310 "Hybrid (AGP 4x on data transfers only)", 311 "PCI", 312 "AGP 1x", 313 "AGP 2x", 314 "AGP 4x" 315 }; 316#endif 317 318 319 /* Initialize the stored BIOS data to some reasonable values for the 320 * card at hand. This is done now so that even if the PInS data block 321 * isn't found or can't be read we'll still have some reasonable values 322 * to use. 323 */ 324 if (pMga->chip_attribs) 325 (void) memcpy(& pMga->bios, & pMga->chip_attribs->default_bios_values, 326 sizeof(struct mga_bios_values)); 327 328 329 /* If the BIOS address was probed, it was found from the PCI config space 330 * If it was given in the config file, try to guess when it looks like it 331 * might be controlled by the PCI config space. 332 */ 333 334#ifdef XSERVER_LIBPCIACCESS 335 err = pci_device_read_rom(pMga->PciInfo, bios_data); 336#else 337 if (pMga->BiosFrom == X_DEFAULT) { 338 pciBIOS = FALSE; 339 } 340 else if (pMga->BiosFrom == X_CONFIG && pMga->BiosAddress < 0x100000) { 341 pciBIOS = TRUE; 342 } 343 344 if (pciBIOS) { 345 rlen = xf86ReadPciBIOS(0, pMga->PciTag, pMga->framebuffer_bar, 346 bios_data, sizeof(bios_data)); 347 } 348 else { 349 rlen = xf86ReadDomainMemory(pMga->PciTag, pMga->BiosAddress, 350 sizeof(bios_data), bios_data); 351 } 352 353 err = rlen < (bios_data[2] << 9); 354#endif 355 356 if (err) { 357 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 358 "Could not retrieve video BIOS!\n"); 359 return FALSE; 360 } 361 362 /* Get the output mode set by the BIOS */ 363 pMga->BiosOutputMode = bios_data[0x7ff1]; 364 365 /* Get the video BIOS info block */ 366 if (strncmp((char *)(&bios_data[45]), "MATROX", 6)) { 367 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 368 "Video BIOS info block not detected!\n"); 369 return FALSE; 370 } 371 372#if X_BYTE_ORDER == X_BIG_ENDIAN 373 /* The offset information that is included in the BIOS on PC Matrox cards 374 * is not there on PowerPC cards. Instead, we have to search the BIOS 375 * image for the magic signature. This is the 16-bit value 0x412d. This 376 * value is followed by the length of the PInS block. We know that this 377 * must (currently) be either 0x80 or 0x40. 378 * 379 * Happy hunting. 380 */ 381 for (offset = 0 ; offset < 0x7ffc ; offset++) { 382 if ((bios_data[offset] == 0x2e) && (bios_data[offset+1] == 0x41) 383 && ((bios_data[offset+2] == 0x80) || (bios_data[offset+2] == 0x40))) { 384 break; 385 } 386 } 387 388 if (offset == 0x7ffc) { 389 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 390 "Video BIOS PInS data not found!\n"); 391 return FALSE; 392 } 393#else 394 /* Get the info block offset */ 395 offset = (unsigned)((bios_data[0x7ffd] << 8) | bios_data[0x7ffc]); 396#endif 397 398 /* Let the world know what we are up to */ 399 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 400 "Video BIOS info block at offset 0x%05lX\n", 401 (long)(offset)); 402 403 404 /* Determine the version of the PInS block. This will determine how the 405 * data is processed. Only the first version of the PInS data structure 406 * did *NOT* have the initial 0x412e (in little-endian order!) signature. 407 */ 408 409 pins_data = & bios_data[ offset ]; 410 if ( (pins_data[0] == 0x2e) && (pins_data[1] == 0x41) ) { 411 version = pins_data[5]; 412 pins_len = pins_data[2]; 413 } 414 else { 415 version = 1; 416 pins_len = get_u16( pins_data ); 417 } 418 419 420 if ( (version < 1) || (version > 5) ) { 421 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 422 "PInS data version (%u) not supported.\n", version); 423 return FALSE; 424 } 425 426 if ( pins_len != expected_length[ version ] ) { 427 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 428 "PInS data length (%u) does not match expected length (%u)" 429 " for version %u.X.\n", 430 pins_len, expected_length[ version ], version); 431 return FALSE; 432 } 433 434 switch( version ) { 435 case 1: mga_parse_bios_ver_1( & pMga->bios, pins_data ); break; 436 case 2: mga_parse_bios_ver_2( & pMga->bios, pins_data ); break; 437 case 3: mga_parse_bios_ver_3( & pMga->bios, pins_data ); break; 438 case 4: mga_parse_bios_ver_4( & pMga->bios, pins_data ); break; 439 case 5: mga_parse_bios_ver_5( & pMga->bios, pins_data ); break; 440 } 441 442#ifdef BIOS_DEBUG 443 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 444 "system VCO = [%u, %u]\n", 445 pMga->bios.system.min_freq, pMga->bios.system.max_freq); 446 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 447 "pixel VCO = [%u, %u]\n", 448 pMga->bios.pixel.min_freq, pMga->bios.pixel.max_freq); 449 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 450 "video VCO = [%u, %u]\n", 451 pMga->bios.video.min_freq, pMga->bios.video.max_freq); 452 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 453 "memory clock = %ukHz\n", pMga->bios.mem_clock); 454 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 455 "PLL reference frequency = %ukHz\n", 456 pMga->bios.pll_ref_freq); 457 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 458 "%s fast bitblt\n", 459 (pMga->bios.fast_bitblt) ? "Has" : "Does not have"); 460 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 461 "Host interface: %s (%u)\n", 462 host_interface_strings[ pMga->bios.host_interface ], 463 pMga->bios.host_interface); 464#endif 465 466 return TRUE; 467} 468