1/* 2 * Integrated TV out support based on the GATOS code by 3 * Federico Ulivi <fulivi@lycos.com> 4 */ 5 6#ifdef HAVE_CONFIG_H 7#include "config.h" 8#endif 9 10#include <string.h> 11#include <stdio.h> 12 13/* X and server generic header files */ 14#include "xf86.h" 15#include "xf86_OSproc.h" 16#include "vgaHW.h" 17#include "xf86Modes.h" 18 19/* Driver data structures */ 20#include "radeon.h" 21#include "radeon_reg.h" 22#include "radeon_macros.h" 23#include "radeon_probe.h" 24#include "radeon_version.h" 25#include "radeon_tv.h" 26#include "radeon_atombios.h" 27 28/********************************************************************** 29 * 30 * ModeConstants 31 * 32 * Storage of constants related to a single video mode 33 * 34 **********************************************************************/ 35 36typedef struct 37{ 38 uint16_t horResolution; 39 uint16_t verResolution; 40 TVStd standard; 41 uint16_t horTotal; 42 uint16_t verTotal; 43 uint16_t horStart; 44 uint16_t horSyncStart; 45 uint16_t verSyncStart; 46 unsigned defRestart; 47 uint16_t crtcPLL_N; 48 uint8_t crtcPLL_M; 49 uint8_t crtcPLL_postDiv; 50 unsigned pixToTV; 51} TVModeConstants; 52 53static const uint16_t hor_timing_NTSC[] = 54{ 55 0x0007, 56 0x003f, 57 0x0263, 58 0x0a24, 59 0x2a6b, 60 0x0a36, 61 0x126d, /* H_TABLE_POS1 */ 62 0x1bfe, 63 0x1a8f, /* H_TABLE_POS2 */ 64 0x1ec7, 65 0x3863, 66 0x1bfe, 67 0x1bfe, 68 0x1a2a, 69 0x1e95, 70 0x0e31, 71 0x201b, 72 0 73}; 74 75static const uint16_t vert_timing_NTSC[] = 76{ 77 0x2001, 78 0x200d, 79 0x1006, 80 0x0c06, 81 0x1006, 82 0x1818, 83 0x21e3, 84 0x1006, 85 0x0c06, 86 0x1006, 87 0x1817, 88 0x21d4, 89 0x0002, 90 0 91}; 92 93static const uint16_t hor_timing_PAL[] = 94{ 95 0x0007, 96 0x0058, 97 0x027c, 98 0x0a31, 99 0x2a77, 100 0x0a95, 101 0x124f, /* H_TABLE_POS1 */ 102 0x1bfe, 103 0x1b22, /* H_TABLE_POS2 */ 104 0x1ef9, 105 0x387c, 106 0x1bfe, 107 0x1bfe, 108 0x1b31, 109 0x1eb5, 110 0x0e43, 111 0x201b, 112 0 113}; 114 115static const uint16_t vert_timing_PAL[] = 116{ 117 0x2001, 118 0x200c, 119 0x1005, 120 0x0c05, 121 0x1005, 122 0x1401, 123 0x1821, 124 0x2240, 125 0x1005, 126 0x0c05, 127 0x1005, 128 0x1401, 129 0x1822, 130 0x2230, 131 0x0002, 132 0 133}; 134 135/********************************************************************** 136 * 137 * availableModes 138 * 139 * Table of all allowed modes for tv output 140 * 141 **********************************************************************/ 142static const TVModeConstants availableTVModes[] = 143{ 144 { /* NTSC timing for 27 Mhz ref clk */ 145 800, /* horResolution */ 146 600, /* verResolution */ 147 TV_STD_NTSC, /* standard */ 148 990, /* horTotal */ 149 740, /* verTotal */ 150 813, /* horStart */ 151 824, /* horSyncStart */ 152 632, /* verSyncStart */ 153 625592, /* defRestart */ 154 592, /* crtcPLL_N */ 155 91, /* crtcPLL_M */ 156 4, /* crtcPLL_postDiv */ 157 1022, /* pixToTV */ 158 }, 159 { /* PAL timing for 27 Mhz ref clk */ 160 800, /* horResolution */ 161 600, /* verResolution */ 162 TV_STD_PAL, /* standard */ 163 1144, /* horTotal */ 164 706, /* verTotal */ 165 812, /* horStart */ 166 824, /* horSyncStart */ 167 669, /* verSyncStart */ 168 696700, /* defRestart */ 169 1382, /* crtcPLL_N */ 170 231, /* crtcPLL_M */ 171 4, /* crtcPLL_postDiv */ 172 759, /* pixToTV */ 173 }, 174 { /* NTSC timing for 14 Mhz ref clk */ 175 800, /* horResolution */ 176 600, /* verResolution */ 177 TV_STD_NTSC, /* standard */ 178 1018, /* horTotal */ 179 727, /* verTotal */ 180 813, /* horStart */ 181 840, /* horSyncStart */ 182 633, /* verSyncStart */ 183 630627, /* defRestart */ 184 347, /* crtcPLL_N */ 185 14, /* crtcPLL_M */ 186 8, /* crtcPLL_postDiv */ 187 1022, /* pixToTV */ 188 }, 189 { /* PAL timing for 14 Mhz ref clk */ 190 800, /* horResolution */ 191 600, /* verResolution */ 192 TV_STD_PAL, /* standard */ 193 1131, /* horTotal */ 194 742, /* verTotal */ 195 813, /* horStart */ 196 840, /* horSyncStart */ 197 633, /* verSyncStart */ 198 708369, /* defRestart */ 199 211, /* crtcPLL_N */ 200 9, /* crtcPLL_M */ 201 8, /* crtcPLL_postDiv */ 202 759, /* pixToTV */ 203 }, 204}; 205 206#define N_AVAILABLE_MODES (sizeof(availableModes) / sizeof(availableModes[ 0 ])) 207 208static long YCOEF_value[5] = { 2, 2, 0, 4, 0 }; 209static long YCOEF_EN_value[5] = { 1, 1, 0, 1, 0 }; 210static long SLOPE_value[5] = { 1, 2, 2, 4, 8 }; 211static long SLOPE_limit[5] = { 6, 5, 4, 3, 2 }; 212 213 214static void 215RADEONWaitPLLLock(ScrnInfoPtr pScrn, unsigned nTests, 216 unsigned nWaitLoops, unsigned cntThreshold) 217{ 218 RADEONInfoPtr info = RADEONPTR(pScrn); 219 unsigned char *RADEONMMIO = info->MMIO; 220 uint32_t savePLLTest; 221 unsigned i; 222 unsigned j; 223 224 OUTREG(RADEON_TEST_DEBUG_MUX, (INREG(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100); 225 226 savePLLTest = INPLL(pScrn, RADEON_PLL_TEST_CNTL); 227 228 OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest & ~RADEON_PLL_MASK_READ_B); 229 230 /* XXX: these should probably be OUTPLL to avoid various PLL errata */ 231 232 OUTREG8(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_TEST_CNTL); 233 234 for (i = 0; i < nTests; i++) { 235 OUTREG8(RADEON_CLOCK_CNTL_DATA + 3, 0); 236 237 for (j = 0; j < nWaitLoops; j++) 238 if (INREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cntThreshold) 239 break; 240 } 241 242 OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest); 243 244 OUTREG(RADEON_TEST_DEBUG_MUX, INREG(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff); 245} 246 247/* Write to TV FIFO RAM */ 248static void 249RADEONWriteTVFIFO(ScrnInfoPtr pScrn, uint16_t addr, 250 uint32_t value) 251{ 252 RADEONInfoPtr info = RADEONPTR(pScrn); 253 unsigned char *RADEONMMIO = info->MMIO; 254 uint32_t tmp; 255 int i = 0; 256 257 OUTREG(RADEON_TV_HOST_WRITE_DATA, value); 258 259 OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr); 260 OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_WT); 261 262 do { 263 tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL); 264 if ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0) 265 break; 266 i++; 267 } 268 while (i < 10000); 269 /*while ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0);*/ 270 271 OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0); 272} 273 274/* Read from TV FIFO RAM */ 275static uint32_t 276RADEONReadTVFIFO(ScrnInfoPtr pScrn, uint16_t addr) 277{ 278 RADEONInfoPtr info = RADEONPTR(pScrn); 279 unsigned char *RADEONMMIO = info->MMIO; 280 uint32_t tmp; 281 int i = 0; 282 283 OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr); 284 OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD); 285 286 do { 287 tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL); 288 if ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0) 289 break; 290 i++; 291 } 292 while (i < 10000); 293 /*while ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0);*/ 294 295 OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0); 296 297 return INREG(RADEON_TV_HOST_READ_DATA); 298} 299 300/* Get FIFO addresses of horizontal & vertical code timing tables from 301 * settings of uv_adr register. 302 */ 303static uint16_t 304RADEONGetHTimingTablesAddr(uint32_t tv_uv_adr) 305{ 306 uint16_t hTable; 307 308 switch ((tv_uv_adr & RADEON_HCODE_TABLE_SEL_MASK) >> RADEON_HCODE_TABLE_SEL_SHIFT) { 309 case 0: 310 hTable = RADEON_TV_MAX_FIFO_ADDR_INTERNAL; 311 break; 312 case 1: 313 hTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2; 314 break; 315 case 2: 316 hTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2; 317 break; 318 default: 319 /* Of course, this should never happen */ 320 hTable = 0; 321 break; 322 } 323 return hTable; 324} 325 326static uint16_t 327RADEONGetVTimingTablesAddr(uint32_t tv_uv_adr) 328{ 329 uint16_t vTable; 330 331 switch ((tv_uv_adr & RADEON_VCODE_TABLE_SEL_MASK) >> RADEON_VCODE_TABLE_SEL_SHIFT) { 332 case 0: 333 vTable = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1; 334 break; 335 case 1: 336 vTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1; 337 break; 338 case 2: 339 vTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1; 340 break; 341 default: 342 /* Of course, this should never happen */ 343 vTable = 0; 344 break; 345 } 346 return vTable; 347} 348 349/* Restore horizontal/vertical timing code tables */ 350static void 351RADEONRestoreTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr restore) 352{ 353 RADEONInfoPtr info = RADEONPTR(pScrn); 354 unsigned char *RADEONMMIO = info->MMIO; 355 uint16_t hTable; 356 uint16_t vTable; 357 uint32_t tmp; 358 unsigned i; 359 360 OUTREG(RADEON_TV_UV_ADR, restore->tv_uv_adr); 361 hTable = RADEONGetHTimingTablesAddr(restore->tv_uv_adr); 362 vTable = RADEONGetVTimingTablesAddr(restore->tv_uv_adr); 363 364 for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, hTable--) { 365 tmp = ((uint32_t)restore->h_code_timing[ i ] << 14) | ((uint32_t)restore->h_code_timing[ i + 1 ]); 366 RADEONWriteTVFIFO(pScrn, hTable, tmp); 367 if (restore->h_code_timing[ i ] == 0 || restore->h_code_timing[ i + 1 ] == 0) 368 break; 369 } 370 371 for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, vTable++) { 372 tmp = ((uint32_t)restore->v_code_timing[ i + 1 ] << 14) | ((uint32_t)restore->v_code_timing[ i ]); 373 RADEONWriteTVFIFO(pScrn, vTable, tmp); 374 if (restore->v_code_timing[ i ] == 0 || restore->v_code_timing[ i + 1 ] == 0) 375 break; 376 } 377} 378 379/* restore TV PLLs */ 380static void 381RADEONRestoreTVPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) 382{ 383 384 OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVCLK_SRC_SEL_TVPLL); 385 OUTPLL(pScrn, RADEON_TV_PLL_CNTL, restore->tv_pll_cntl); 386 OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVPLL_RESET, ~RADEON_TVPLL_RESET); 387 388 RADEONWaitPLLLock(pScrn, 200, 800, 135); 389 390 OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET); 391 392 RADEONWaitPLLLock(pScrn, 300, 160, 27); 393 RADEONWaitPLLLock(pScrn, 200, 800, 135); 394 395 OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~0xf); 396 OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVCLK_SRC_SEL_TVPLL, ~RADEON_TVCLK_SRC_SEL_TVPLL); 397 398 OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, (1 << RADEON_TVPDC_SHIFT), ~RADEON_TVPDC_MASK); 399 OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_SLEEP); 400} 401 402/* Restore TV horizontal/vertical settings */ 403static void 404RADEONRestoreTVHVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) 405{ 406 RADEONInfoPtr info = RADEONPTR(pScrn); 407 unsigned char *RADEONMMIO = info->MMIO; 408 409 OUTREG(RADEON_TV_RGB_CNTL, restore->tv_rgb_cntl); 410 411 OUTREG(RADEON_TV_HTOTAL, restore->tv_htotal); 412 OUTREG(RADEON_TV_HDISP, restore->tv_hdisp); 413 OUTREG(RADEON_TV_HSTART, restore->tv_hstart); 414 415 OUTREG(RADEON_TV_VTOTAL, restore->tv_vtotal); 416 OUTREG(RADEON_TV_VDISP, restore->tv_vdisp); 417 418 OUTREG(RADEON_TV_FTOTAL, restore->tv_ftotal); 419 420 OUTREG(RADEON_TV_VSCALER_CNTL1, restore->tv_vscaler_cntl1); 421 OUTREG(RADEON_TV_VSCALER_CNTL2, restore->tv_vscaler_cntl2); 422 423 OUTREG(RADEON_TV_Y_FALL_CNTL, restore->tv_y_fall_cntl); 424 OUTREG(RADEON_TV_Y_RISE_CNTL, restore->tv_y_rise_cntl); 425 OUTREG(RADEON_TV_Y_SAW_TOOTH_CNTL, restore->tv_y_saw_tooth_cntl); 426} 427 428/* restore TV RESTART registers */ 429static void 430RADEONRestoreTVRestarts(ScrnInfoPtr pScrn, RADEONSavePtr restore) 431{ 432 RADEONInfoPtr info = RADEONPTR(pScrn); 433 unsigned char *RADEONMMIO = info->MMIO; 434 435 OUTREG(RADEON_TV_FRESTART, restore->tv_frestart); 436 OUTREG(RADEON_TV_HRESTART, restore->tv_hrestart); 437 OUTREG(RADEON_TV_VRESTART, restore->tv_vrestart); 438} 439 440/* restore tv standard & output muxes */ 441static void 442RADEONRestoreTVOutputStd(ScrnInfoPtr pScrn, RADEONSavePtr restore) 443{ 444 RADEONInfoPtr info = RADEONPTR(pScrn); 445 unsigned char *RADEONMMIO = info->MMIO; 446 447 OUTREG(RADEON_TV_SYNC_CNTL, restore->tv_sync_cntl); 448 449 OUTREG(RADEON_TV_TIMING_CNTL, restore->tv_timing_cntl); 450 451 OUTREG(RADEON_TV_MODULATOR_CNTL1, restore->tv_modulator_cntl1); 452 OUTREG(RADEON_TV_MODULATOR_CNTL2, restore->tv_modulator_cntl2); 453 454 OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, restore->tv_pre_dac_mux_cntl); 455 456 OUTREG(RADEON_TV_CRC_CNTL, restore->tv_crc_cntl); 457} 458 459/* Restore TV out regs */ 460void 461RADEONRestoreTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) 462{ 463 RADEONInfoPtr info = RADEONPTR(pScrn); 464 unsigned char *RADEONMMIO = info->MMIO; 465 466 ErrorF("Entering Restore TV\n"); 467 468 OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl 469 | RADEON_TV_ASYNC_RST 470 | RADEON_CRT_ASYNC_RST 471 | RADEON_TV_FIFO_ASYNC_RST)); 472 473 /* Temporarily turn the TV DAC off */ 474 OUTREG(RADEON_TV_DAC_CNTL, ((restore->tv_dac_cntl & ~RADEON_TV_DAC_NBLANK) 475 | RADEON_TV_DAC_BGSLEEP 476 | RADEON_TV_DAC_RDACPD 477 | RADEON_TV_DAC_GDACPD 478 | RADEON_TV_DAC_BDACPD)); 479 480 ErrorF("Restore TV PLL\n"); 481 RADEONRestoreTVPLLRegisters(pScrn, restore); 482 483 ErrorF("Restore TVHV\n"); 484 RADEONRestoreTVHVRegisters(pScrn, restore); 485 486 OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl 487 | RADEON_TV_ASYNC_RST 488 | RADEON_CRT_ASYNC_RST)); 489 490 ErrorF("Restore TV Restarts\n"); 491 RADEONRestoreTVRestarts(pScrn, restore); 492 493 ErrorF("Restore Timing Tables\n"); 494 RADEONRestoreTVTimingTables(pScrn, restore); 495 496 497 OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl 498 | RADEON_TV_ASYNC_RST)); 499 500 ErrorF("Restore TV standard\n"); 501 RADEONRestoreTVOutputStd(pScrn, restore); 502 503 OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl); 504 505 OUTREG(RADEON_TV_GAIN_LIMIT_SETTINGS, restore->tv_gain_limit_settings); 506 OUTREG(RADEON_TV_LINEAR_GAIN_SETTINGS, restore->tv_linear_gain_settings); 507 508 OUTREG(RADEON_TV_DAC_CNTL, restore->tv_dac_cntl); 509 510 ErrorF("Leaving Restore TV\n"); 511} 512 513/* Save horizontal/vertical timing code tables */ 514static void 515RADEONSaveTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr save) 516{ 517 RADEONInfoPtr info = RADEONPTR(pScrn); 518 unsigned char *RADEONMMIO = info->MMIO; 519 uint16_t hTable; 520 uint16_t vTable; 521 uint32_t tmp; 522 unsigned i; 523 524 save->tv_uv_adr = INREG(RADEON_TV_UV_ADR); 525 hTable = RADEONGetHTimingTablesAddr(save->tv_uv_adr); 526 vTable = RADEONGetVTimingTablesAddr(save->tv_uv_adr); 527 528 /* 529 * Reset FIFO arbiter in order to be able to access FIFO RAM 530 */ 531 532 OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST 533 | RADEON_CRT_ASYNC_RST 534 | RADEON_RESTART_PHASE_FIX 535 | RADEON_CRT_FIFO_CE_EN 536 | RADEON_TV_FIFO_CE_EN 537 | RADEON_TV_ON)); 538 539 /*OUTREG(RADEON_TV_MASTER_CNTL, save->tv_master_cntl | RADEON_TV_ON);*/ 540 541 ErrorF("saveTimingTables: reading timing tables\n"); 542 543 for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2) { 544 tmp = RADEONReadTVFIFO(pScrn, hTable--); 545 save->h_code_timing[ i ] = (uint16_t)((tmp >> 14) & 0x3fff); 546 save->h_code_timing[ i + 1 ] = (uint16_t)(tmp & 0x3fff); 547 548 if (save->h_code_timing[ i ] == 0 || save->h_code_timing[ i + 1 ] == 0) 549 break; 550 } 551 552 for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2) { 553 tmp = RADEONReadTVFIFO(pScrn, vTable++); 554 save->v_code_timing[ i ] = (uint16_t)(tmp & 0x3fff); 555 save->v_code_timing[ i + 1 ] = (uint16_t)((tmp >> 14) & 0x3fff); 556 557 if (save->v_code_timing[ i ] == 0 || save->v_code_timing[ i + 1 ] == 0) 558 break; 559 } 560} 561 562/* read TV regs */ 563void 564RADEONSaveTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) 565{ 566 RADEONInfoPtr info = RADEONPTR(pScrn); 567 unsigned char *RADEONMMIO = info->MMIO; 568 569 ErrorF("Entering TV Save\n"); 570 571 save->tv_crc_cntl = INREG(RADEON_TV_CRC_CNTL); 572 save->tv_frestart = INREG(RADEON_TV_FRESTART); 573 save->tv_hrestart = INREG(RADEON_TV_HRESTART); 574 save->tv_vrestart = INREG(RADEON_TV_VRESTART); 575 save->tv_gain_limit_settings = INREG(RADEON_TV_GAIN_LIMIT_SETTINGS); 576 save->tv_hdisp = INREG(RADEON_TV_HDISP); 577 save->tv_hstart = INREG(RADEON_TV_HSTART); 578 save->tv_htotal = INREG(RADEON_TV_HTOTAL); 579 save->tv_linear_gain_settings = INREG(RADEON_TV_LINEAR_GAIN_SETTINGS); 580 save->tv_master_cntl = INREG(RADEON_TV_MASTER_CNTL); 581 save->tv_rgb_cntl = INREG(RADEON_TV_RGB_CNTL); 582 save->tv_modulator_cntl1 = INREG(RADEON_TV_MODULATOR_CNTL1); 583 save->tv_modulator_cntl2 = INREG(RADEON_TV_MODULATOR_CNTL2); 584 save->tv_pre_dac_mux_cntl = INREG(RADEON_TV_PRE_DAC_MUX_CNTL); 585 save->tv_sync_cntl = INREG(RADEON_TV_SYNC_CNTL); 586 save->tv_timing_cntl = INREG(RADEON_TV_TIMING_CNTL); 587 save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL); 588 save->tv_upsamp_and_gain_cntl = INREG(RADEON_TV_UPSAMP_AND_GAIN_CNTL); 589 save->tv_vdisp = INREG(RADEON_TV_VDISP); 590 save->tv_ftotal = INREG(RADEON_TV_FTOTAL); 591 save->tv_vscaler_cntl1 = INREG(RADEON_TV_VSCALER_CNTL1); 592 save->tv_vscaler_cntl2 = INREG(RADEON_TV_VSCALER_CNTL2); 593 save->tv_vtotal = INREG(RADEON_TV_VTOTAL); 594 save->tv_y_fall_cntl = INREG(RADEON_TV_Y_FALL_CNTL); 595 save->tv_y_rise_cntl = INREG(RADEON_TV_Y_RISE_CNTL); 596 save->tv_y_saw_tooth_cntl = INREG(RADEON_TV_Y_SAW_TOOTH_CNTL); 597 598 save->tv_pll_cntl = INPLL(pScrn, RADEON_TV_PLL_CNTL); 599 save->tv_pll_cntl1 = INPLL(pScrn, RADEON_TV_PLL_CNTL1); 600 601 ErrorF("Save TV timing tables\n"); 602 603 RADEONSaveTVTimingTables(pScrn, save); 604 605 ErrorF("TV Save done\n"); 606} 607 608 609/* Compute F,V,H restarts from default restart position and hPos & vPos 610 * Return TRUE when code timing table was changed 611 */ 612static Bool RADEONInitTVRestarts(xf86OutputPtr output, RADEONSavePtr save, 613 DisplayModePtr mode) 614{ 615 RADEONOutputPrivatePtr radeon_output = output->driver_private; 616 radeon_tvout_ptr tvout = &radeon_output->tvout; 617 RADEONInfoPtr info = RADEONPTR(output->scrn); 618 RADEONPLLPtr pll = &info->pll; 619 int restart; 620 unsigned hTotal; 621 unsigned vTotal; 622 unsigned fTotal; 623 int vOffset; 624 int hOffset; 625 uint16_t p1; 626 uint16_t p2; 627 Bool hChanged; 628 uint16_t hInc; 629 const TVModeConstants *constPtr; 630 631 /* FIXME: need to revisit this when we add more modes */ 632 if (tvout->tvStd == TV_STD_NTSC || 633 tvout->tvStd == TV_STD_NTSC_J || 634 tvout->tvStd == TV_STD_PAL_M) { 635 if (pll->reference_freq == 2700) 636 constPtr = &availableTVModes[0]; 637 else 638 constPtr = &availableTVModes[2]; 639 } else { 640 if (pll->reference_freq == 2700) 641 constPtr = &availableTVModes[1]; 642 else 643 constPtr = &availableTVModes[3]; 644 } 645 646 hTotal = constPtr->horTotal; 647 vTotal = constPtr->verTotal; 648 649 if (tvout->tvStd == TV_STD_NTSC || 650 tvout->tvStd == TV_STD_NTSC_J || 651 tvout->tvStd == TV_STD_PAL_M || 652 tvout->tvStd == TV_STD_PAL_60) 653 fTotal = NTSC_TV_VFTOTAL + 1; 654 else 655 fTotal = PAL_TV_VFTOTAL + 1; 656 657 /* Adjust positions 1&2 in hor. code timing table */ 658 hOffset = tvout->hPos * H_POS_UNIT; 659 660 if (tvout->tvStd == TV_STD_NTSC || 661 tvout->tvStd == TV_STD_NTSC_J || 662 tvout->tvStd == TV_STD_PAL_M) { 663 /* improve image centering */ 664 hOffset -= 50; 665 p1 = hor_timing_NTSC[ H_TABLE_POS1 ]; 666 p2 = hor_timing_NTSC[ H_TABLE_POS2 ]; 667 } else { 668 p1 = hor_timing_PAL[ H_TABLE_POS1 ]; 669 p2 = hor_timing_PAL[ H_TABLE_POS2 ]; 670 } 671 672 673 p1 = (uint16_t)((int)p1 + hOffset); 674 p2 = (uint16_t)((int)p2 - hOffset); 675 676 hChanged = (p1 != save->h_code_timing[ H_TABLE_POS1 ] || 677 p2 != save->h_code_timing[ H_TABLE_POS2 ]); 678 679 save->h_code_timing[ H_TABLE_POS1 ] = p1; 680 save->h_code_timing[ H_TABLE_POS2 ] = p2; 681 682 /* Convert hOffset from n. of TV clock periods to n. of CRTC clock periods (CRTC pixels) */ 683 hOffset = (hOffset * (int)(constPtr->pixToTV)) / 1000; 684 685 /* Adjust restart */ 686 restart = constPtr->defRestart; 687 688 /* 689 * Convert vPos TV lines to n. of CRTC pixels 690 * Be verrrrry careful when mixing signed & unsigned values in C.. 691 */ 692 if (tvout->tvStd == TV_STD_NTSC || 693 tvout->tvStd == TV_STD_NTSC_J || 694 tvout->tvStd == TV_STD_PAL_M || 695 tvout->tvStd == TV_STD_PAL_60) 696 vOffset = ((int)(vTotal * hTotal) * 2 * tvout->vPos) / (int)(NTSC_TV_LINES_PER_FRAME); 697 else 698 vOffset = ((int)(vTotal * hTotal) * 2 * tvout->vPos) / (int)(PAL_TV_LINES_PER_FRAME); 699 700 restart -= vOffset + hOffset; 701 702 ErrorF("computeRestarts: def = %u, h = %d, v = %d, p1=%04x, p2=%04x, restart = %d\n", 703 constPtr->defRestart , tvout->hPos , tvout->vPos , p1 , p2 , restart); 704 705 save->tv_hrestart = restart % hTotal; 706 restart /= hTotal; 707 save->tv_vrestart = restart % vTotal; 708 restart /= vTotal; 709 save->tv_frestart = restart % fTotal; 710 711 ErrorF("computeRestarts: F/H/V=%u,%u,%u\n", 712 (unsigned)save->tv_frestart, (unsigned)save->tv_vrestart, 713 (unsigned)save->tv_hrestart); 714 715 /* Compute H_INC from hSize */ 716 if (tvout->tvStd == TV_STD_NTSC || 717 tvout->tvStd == TV_STD_NTSC_J || 718 tvout->tvStd == TV_STD_PAL_M) 719 hInc = (uint16_t)((int)(constPtr->horResolution * 4096 * NTSC_TV_CLOCK_T) / 720 (tvout->hSize * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE))); 721 else 722 hInc = (uint16_t)((int)(constPtr->horResolution * 4096 * PAL_TV_CLOCK_T) / 723 (tvout->hSize * (int)(PAL_TV_H_SIZE_UNIT) + (int)(PAL_TV_ZERO_H_SIZE))); 724 725 save->tv_timing_cntl = (save->tv_timing_cntl & ~RADEON_H_INC_MASK) | 726 ((uint32_t)hInc << RADEON_H_INC_SHIFT); 727 728 ErrorF("computeRestarts: hSize=%d,hInc=%u\n" , tvout->hSize , hInc); 729 730 return hChanged; 731} 732 733/* intit TV-out regs */ 734void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save, 735 DisplayModePtr mode, BOOL IsPrimary) 736{ 737 ScrnInfoPtr pScrn = output->scrn; 738 RADEONOutputPrivatePtr radeon_output = output->driver_private; 739 radeon_tvout_ptr tvout = &radeon_output->tvout; 740 RADEONInfoPtr info = RADEONPTR(pScrn); 741 RADEONPLLPtr pll = &info->pll; 742 unsigned m, n, p; 743 unsigned i; 744 unsigned long vert_space, flicker_removal; 745 uint32_t tmp; 746 const TVModeConstants *constPtr; 747 const uint16_t *hor_timing; 748 const uint16_t *vert_timing; 749 radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); 750 radeon_tvdac_ptr tvdac = NULL; 751 752 if (radeon_encoder == NULL) 753 return; 754 755 tvdac = (radeon_tvdac_ptr)radeon_encoder->dev_priv; 756 757 if (tvdac == NULL) 758 return; 759 760 /* FIXME: need to revisit this when we add more modes */ 761 if (tvout->tvStd == TV_STD_NTSC || 762 tvout->tvStd == TV_STD_NTSC_J || 763 tvout->tvStd == TV_STD_PAL_M) { 764 if (pll->reference_freq == 2700) 765 constPtr = &availableTVModes[0]; 766 else 767 constPtr = &availableTVModes[2]; 768 } else { 769 if (pll->reference_freq == 2700) 770 constPtr = &availableTVModes[1]; 771 else 772 constPtr = &availableTVModes[3]; 773 } 774 775 save->tv_crc_cntl = 0; 776 777 save->tv_gain_limit_settings = (0x17f << RADEON_UV_GAIN_LIMIT_SHIFT) | 778 (0x5ff << RADEON_Y_GAIN_LIMIT_SHIFT); 779 780 save->tv_hdisp = constPtr->horResolution - 1; 781 save->tv_hstart = constPtr->horStart; 782 save->tv_htotal = constPtr->horTotal - 1; 783 784 save->tv_linear_gain_settings = (0x100 << RADEON_UV_GAIN_SHIFT) | 785 (0x100 << RADEON_Y_GAIN_SHIFT); 786 787 save->tv_master_cntl = (RADEON_VIN_ASYNC_RST 788 | RADEON_CRT_FIFO_CE_EN 789 | RADEON_TV_FIFO_CE_EN 790 | RADEON_TV_ON); 791 792 if (!IS_R300_VARIANT) 793 save->tv_master_cntl |= RADEON_TVCLK_ALWAYS_ONb; 794 795 if (tvout->tvStd == TV_STD_NTSC || 796 tvout->tvStd == TV_STD_NTSC_J) 797 save->tv_master_cntl |= RADEON_RESTART_PHASE_FIX; 798 799 save->tv_modulator_cntl1 = RADEON_SLEW_RATE_LIMIT 800 | RADEON_SYNC_TIP_LEVEL 801 | RADEON_YFLT_EN 802 | RADEON_UVFLT_EN 803 | (6 << RADEON_CY_FILT_BLEND_SHIFT); 804 805 if (tvout->tvStd == TV_STD_NTSC || 806 tvout->tvStd == TV_STD_NTSC_J) { 807 save->tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT) 808 | (0x3b << RADEON_BLANK_LEVEL_SHIFT); 809 save->tv_modulator_cntl2 = (-111 & RADEON_TV_U_BURST_LEVEL_MASK) | 810 ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT); 811 } else if (tvout->tvStd == TV_STD_SCART_PAL) { 812 save->tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN; 813 save->tv_modulator_cntl2 = (0 & RADEON_TV_U_BURST_LEVEL_MASK) | 814 ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT); 815 } else { 816 save->tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN 817 | (0x3b << RADEON_SET_UP_LEVEL_SHIFT) 818 | (0x3b << RADEON_BLANK_LEVEL_SHIFT); 819 save->tv_modulator_cntl2 = (-78 & RADEON_TV_U_BURST_LEVEL_MASK) | 820 ((62 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT); 821 } 822 823 save->pll_test_cntl = 0; 824 825 save->tv_pre_dac_mux_cntl = (RADEON_Y_RED_EN 826 | RADEON_C_GRN_EN 827 | RADEON_CMP_BLU_EN 828 | RADEON_DAC_DITHER_EN); 829 830 save->tv_rgb_cntl = (RADEON_RGB_DITHER_EN 831 | RADEON_TVOUT_SCALE_EN 832 | (0x0b << RADEON_UVRAM_READ_MARGIN_SHIFT) 833 | (0x07 << RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT) 834 | RADEON_RGB_ATTEN_SEL(0x3) 835 | RADEON_RGB_ATTEN_VAL(0xc)); 836 837 if (IsPrimary) { 838 if (radeon_output->Flags & RADEON_USE_RMX) 839 save->tv_rgb_cntl |= RADEON_RGB_SRC_SEL_RMX; 840 else 841 save->tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC1; 842 } else { 843 save->tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC2; 844 } 845 846 save->tv_sync_cntl = RADEON_SYNC_PUB | RADEON_TV_SYNC_IO_DRIVE; 847 848 save->tv_sync_size = constPtr->horResolution + 8; 849 850 if (tvout->tvStd == TV_STD_NTSC || 851 tvout->tvStd == TV_STD_NTSC_J || 852 tvout->tvStd == TV_STD_PAL_M || 853 tvout->tvStd == TV_STD_PAL_60) 854 vert_space = constPtr->verTotal * 2 * 10000 / NTSC_TV_LINES_PER_FRAME; 855 else 856 vert_space = constPtr->verTotal * 2 * 10000 / PAL_TV_LINES_PER_FRAME; 857 858 save->tv_vscaler_cntl1 = RADEON_Y_W_EN; 859 save->tv_vscaler_cntl1 = 860 (save->tv_vscaler_cntl1 & 0xe3ff0000) | (vert_space * (1 << FRAC_BITS) / 10000); 861 862 if (pll->reference_freq == 2700) 863 save->tv_vscaler_cntl1 |= RADEON_RESTART_FIELD; 864 865 if (constPtr->horResolution == 1024) 866 save->tv_vscaler_cntl1 |= (4 << RADEON_Y_DEL_W_SIG_SHIFT); 867 else 868 save->tv_vscaler_cntl1 |= (2 << RADEON_Y_DEL_W_SIG_SHIFT); 869 870 if (tvout->tvStd == TV_STD_NTSC || 871 tvout->tvStd == TV_STD_NTSC_J || 872 tvout->tvStd == TV_STD_PAL_M || 873 tvout->tvStd == TV_STD_PAL_60) 874 flicker_removal = 875 (float) constPtr->verTotal * 2.0 / NTSC_TV_LINES_PER_FRAME + 0.5; 876 else 877 flicker_removal = 878 (float) constPtr->verTotal * 2.0 / PAL_TV_LINES_PER_FRAME + 0.5; 879 880 if (flicker_removal < 3) 881 flicker_removal = 3; 882 for (i = 0; i < 6; ++i) { 883 if (flicker_removal == SLOPE_limit[i]) 884 break; 885 } 886 save->tv_y_saw_tooth_cntl = 887 (vert_space * SLOPE_value[i] * (1 << (FRAC_BITS - 1)) + 5001) / 10000 / 8 888 | ((SLOPE_value[i] * (1 << (FRAC_BITS - 1)) / 8) << 16); 889 save->tv_y_fall_cntl = 890 (YCOEF_EN_value[i] << 17) | ((YCOEF_value[i] * (1 << 8) / 8) << 24) | 891 RADEON_Y_FALL_PING_PONG | (272 * SLOPE_value[i] / 8) * (1 << (FRAC_BITS - 1)) / 892 1024; 893 save->tv_y_rise_cntl = 894 RADEON_Y_RISE_PING_PONG 895 | (flicker_removal * 1024 - 272) * SLOPE_value[i] / 8 * (1 << (FRAC_BITS - 1)) / 1024; 896 897 save->tv_vscaler_cntl2 = ((save->tv_vscaler_cntl2 & 0x00fffff0) 898 | (0x10 << 24) 899 | RADEON_DITHER_MODE 900 | RADEON_Y_OUTPUT_DITHER_EN 901 | RADEON_UV_OUTPUT_DITHER_EN 902 | RADEON_UV_TO_BUF_DITHER_EN); 903 904 tmp = (save->tv_vscaler_cntl1 >> RADEON_UV_INC_SHIFT) & RADEON_UV_INC_MASK; 905 tmp = ((16384 * 256 * 10) / tmp + 5) / 10; 906 tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000; 907 save->tv_timing_cntl = tmp; 908 909 if (tvout->tvStd == TV_STD_NTSC || 910 tvout->tvStd == TV_STD_NTSC_J || 911 tvout->tvStd == TV_STD_PAL_M || 912 tvout->tvStd == TV_STD_PAL_60) 913 save->tv_dac_cntl = tvdac->ntsc_tvdac_adj; 914 else 915 save->tv_dac_cntl = tvdac->pal_tvdac_adj; 916 917 save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD); 918 919 if (tvout->tvStd == TV_STD_NTSC || 920 tvout->tvStd == TV_STD_NTSC_J) 921 save->tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC; 922 else 923 save->tv_dac_cntl |= RADEON_TV_DAC_STD_PAL; 924 925#if 0 926 /* needs fixes for r4xx */ 927 save->tv_dac_cntl |= (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD 928 | RADEON_TV_DAC_BDACPD); 929 930 if (radeon_output->MonType == MT_CTV) { 931 save->tv_dac_cntl &= ~RADEON_TV_DAC_BDACPD; 932 } 933 934 if (radeon_output->MonType == MT_STV) { 935 save->tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD | 936 RADEON_TV_DAC_GDACPD); 937 } 938#endif 939 940 if (tvout->tvStd == TV_STD_NTSC || 941 tvout->tvStd == TV_STD_NTSC_J) { 942 if (pll->reference_freq == 2700) { 943 m = NTSC_TV_PLL_M_27; 944 n = NTSC_TV_PLL_N_27; 945 p = NTSC_TV_PLL_P_27; 946 } else { 947 m = NTSC_TV_PLL_M_14; 948 n = NTSC_TV_PLL_N_14; 949 p = NTSC_TV_PLL_P_14; 950 } 951 } else { 952 if (pll->reference_freq == 2700) { 953 m = PAL_TV_PLL_M_27; 954 n = PAL_TV_PLL_N_27; 955 p = PAL_TV_PLL_P_27; 956 } else { 957 m = PAL_TV_PLL_M_14; 958 n = PAL_TV_PLL_N_14; 959 p = PAL_TV_PLL_P_14; 960 } 961 } 962 save->tv_pll_cntl = (m & RADEON_TV_M0LO_MASK) | 963 (((m >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) | 964 ((n & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) | 965 (((n >> 9) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) | 966 ((p & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT); 967 968 save->tv_pll_cntl1 = (((4 & RADEON_TVPCP_MASK)<< RADEON_TVPCP_SHIFT) | 969 ((4 & RADEON_TVPVG_MASK) << RADEON_TVPVG_SHIFT) | 970 ((1 & RADEON_TVPDC_MASK)<< RADEON_TVPDC_SHIFT) | 971 RADEON_TVCLK_SRC_SEL_TVPLL | 972 RADEON_TVPLL_TEST_DIS); 973 974 save->tv_upsamp_and_gain_cntl = RADEON_YUPSAMP_EN | RADEON_UVUPSAMP_EN; 975 976 save->tv_uv_adr = 0xc8; 977 978 save->tv_vdisp = constPtr->verResolution - 1; 979 980 if (tvout->tvStd == TV_STD_NTSC || 981 tvout->tvStd == TV_STD_NTSC_J || 982 tvout->tvStd == TV_STD_PAL_M || 983 tvout->tvStd == TV_STD_PAL_60) 984 save->tv_ftotal = NTSC_TV_VFTOTAL; 985 else 986 save->tv_ftotal = PAL_TV_VFTOTAL; 987 988 save->tv_vtotal = constPtr->verTotal - 1; 989 990 if (tvout->tvStd == TV_STD_NTSC || 991 tvout->tvStd == TV_STD_NTSC_J || 992 tvout->tvStd == TV_STD_PAL_M) { 993 hor_timing = hor_timing_NTSC; 994 } else { 995 hor_timing = hor_timing_PAL; 996 } 997 998 if (tvout->tvStd == TV_STD_NTSC || 999 tvout->tvStd == TV_STD_NTSC_J || 1000 tvout->tvStd == TV_STD_PAL_M || 1001 tvout->tvStd == TV_STD_PAL_60) { 1002 vert_timing = vert_timing_NTSC; 1003 } else { 1004 vert_timing = vert_timing_PAL; 1005 } 1006 1007 for (i = 0; i < MAX_H_CODE_TIMING_LEN; i++) { 1008 if ((save->h_code_timing[ i ] = hor_timing[ i ]) == 0) 1009 break; 1010 } 1011 1012 for (i = 0; i < MAX_V_CODE_TIMING_LEN; i++) { 1013 if ((save->v_code_timing[ i ] = vert_timing[ i ]) == 0) 1014 break; 1015 } 1016 1017 /* 1018 * This must be called AFTER loading timing tables as they are modified by this function 1019 */ 1020 RADEONInitTVRestarts(output, save, mode); 1021 1022 save->dac_cntl &= ~RADEON_DAC_TVO_EN; 1023 1024 if (IS_R300_VARIANT) 1025 save->gpiopad_a = info->SavedReg->gpiopad_a & ~1; 1026 1027 if (IsPrimary) { 1028 save->disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; 1029 save->disp_output_cntl |= (RADEON_DISP_TVDAC_SOURCE_CRTC 1030 | RADEON_DISP_TV_SOURCE_CRTC); 1031 if (info->ChipFamily >= CHIP_FAMILY_R200) { 1032 save->disp_tv_out_cntl &= ~RADEON_DISP_TV_PATH_SRC_CRTC2; 1033 } else { 1034 save->disp_hw_debug |= RADEON_CRT2_DISP1_SEL; 1035 } 1036 } else { 1037 save->disp_output_cntl &= ~RADEON_DISP_DAC_SOURCE_MASK; 1038 save->disp_output_cntl |= RADEON_DISP_TV_SOURCE_CRTC; 1039 1040 if (info->ChipFamily >= CHIP_FAMILY_R200) { 1041 save->disp_tv_out_cntl |= RADEON_DISP_TV_PATH_SRC_CRTC2; 1042 } else { 1043 save->disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL; 1044 } 1045 } 1046} 1047 1048 1049/* Set hw registers for a new h/v position & h size */ 1050void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode) 1051{ 1052 ScrnInfoPtr pScrn = output->scrn; 1053 RADEONInfoPtr info = RADEONPTR(pScrn); 1054 unsigned char *RADEONMMIO = info->MMIO; 1055 Bool reloadTable; 1056 RADEONSavePtr restore = info->ModeReg; 1057 1058 reloadTable = RADEONInitTVRestarts(output, restore, mode); 1059 1060 RADEONRestoreTVRestarts(pScrn, restore); 1061 1062 OUTREG(RADEON_TV_TIMING_CNTL, restore->tv_timing_cntl); 1063 1064 if (reloadTable) { 1065 OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl 1066 | RADEON_TV_ASYNC_RST 1067 | RADEON_CRT_ASYNC_RST 1068 | RADEON_RESTART_PHASE_FIX); 1069 1070 RADEONRestoreTVTimingTables(pScrn, restore); 1071 1072 OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl); 1073 } 1074} 1075 1076void RADEONAdjustCrtcRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save, 1077 DisplayModePtr mode, xf86OutputPtr output) 1078{ 1079 const TVModeConstants *constPtr; 1080 RADEONOutputPrivatePtr radeon_output = output->driver_private; 1081 radeon_tvout_ptr tvout = &radeon_output->tvout; 1082 RADEONInfoPtr info = RADEONPTR(pScrn); 1083 RADEONPLLPtr pll = &info->pll; 1084 1085 /* FIXME: need to revisit this when we add more modes */ 1086 if (tvout->tvStd == TV_STD_NTSC || 1087 tvout->tvStd == TV_STD_NTSC_J || 1088 tvout->tvStd == TV_STD_PAL_M) { 1089 if (pll->reference_freq == 2700) 1090 constPtr = &availableTVModes[0]; 1091 else 1092 constPtr = &availableTVModes[2]; 1093 } else { 1094 if (pll->reference_freq == 2700) 1095 constPtr = &availableTVModes[1]; 1096 else 1097 constPtr = &availableTVModes[3]; 1098 } 1099 1100 save->crtc_h_total_disp = (((constPtr->horResolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) | 1101 (((constPtr->horTotal / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT); 1102 1103 save->crtc_h_sync_strt_wid = (save->crtc_h_sync_strt_wid 1104 & ~(RADEON_CRTC_H_SYNC_STRT_PIX | RADEON_CRTC_H_SYNC_STRT_CHAR)) | 1105 (((constPtr->horSyncStart / 8) - 1) << RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) | 1106 (constPtr->horSyncStart & 7); 1107 1108 save->crtc_v_total_disp = ((constPtr->verResolution - 1) << RADEON_CRTC_V_DISP_SHIFT) | 1109 ((constPtr->verTotal - 1) << RADEON_CRTC_V_TOTAL_SHIFT); 1110 1111 save->crtc_v_sync_strt_wid = (save->crtc_v_sync_strt_wid & ~RADEON_CRTC_V_SYNC_STRT) | 1112 ((constPtr->verSyncStart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT); 1113 1114} 1115 1116void RADEONAdjustPLLRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save, 1117 DisplayModePtr mode, xf86OutputPtr output) 1118{ 1119 unsigned postDiv; 1120 const TVModeConstants *constPtr; 1121 RADEONOutputPrivatePtr radeon_output = output->driver_private; 1122 radeon_tvout_ptr tvout = &radeon_output->tvout; 1123 RADEONInfoPtr info = RADEONPTR(pScrn); 1124 RADEONPLLPtr pll = &info->pll; 1125 1126 /* FIXME: need to revisit this when we add more modes */ 1127 if (tvout->tvStd == TV_STD_NTSC || 1128 tvout->tvStd == TV_STD_NTSC_J || 1129 tvout->tvStd == TV_STD_PAL_M) { 1130 if (pll->reference_freq == 2700) 1131 constPtr = &availableTVModes[0]; 1132 else 1133 constPtr = &availableTVModes[2]; 1134 } else { 1135 if (pll->reference_freq == 2700) 1136 constPtr = &availableTVModes[1]; 1137 else 1138 constPtr = &availableTVModes[3]; 1139 } 1140 1141 save->htotal_cntl = (constPtr->horTotal & 0x7 /*0xf*/) | RADEON_HTOT_CNTL_VGA_EN; 1142 1143 save->ppll_ref_div = constPtr->crtcPLL_M; 1144 1145 switch (constPtr->crtcPLL_postDiv) { 1146 case 1: 1147 postDiv = 0; 1148 break; 1149 case 2: 1150 postDiv = 1; 1151 break; 1152 case 3: 1153 postDiv = 4; 1154 break; 1155 case 4: 1156 postDiv = 2; 1157 break; 1158 case 6: 1159 postDiv = 6; 1160 break; 1161 case 8: 1162 postDiv = 3; 1163 break; 1164 case 12: 1165 postDiv = 7; 1166 break; 1167 case 16: 1168 default: 1169 postDiv = 5; 1170 break; 1171 } 1172 1173 save->ppll_div_3 = (constPtr->crtcPLL_N & 0x7ff) | (postDiv << 16); 1174 1175 save->pixclks_cntl &= ~(RADEON_PIX2CLK_SRC_SEL_MASK | RADEON_PIXCLK_TV_SRC_SEL); 1176 save->pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK; 1177 1178} 1179 1180void RADEONAdjustCrtc2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save, 1181 DisplayModePtr mode, xf86OutputPtr output) 1182{ 1183 const TVModeConstants *constPtr; 1184 RADEONOutputPrivatePtr radeon_output = output->driver_private; 1185 radeon_tvout_ptr tvout = &radeon_output->tvout; 1186 RADEONInfoPtr info = RADEONPTR(pScrn); 1187 RADEONPLLPtr pll = &info->pll; 1188 1189 /* FIXME: need to revisit this when we add more modes */ 1190 if (tvout->tvStd == TV_STD_NTSC || 1191 tvout->tvStd == TV_STD_NTSC_J || 1192 tvout->tvStd == TV_STD_PAL_M) { 1193 if (pll->reference_freq == 2700) 1194 constPtr = &availableTVModes[0]; 1195 else 1196 constPtr = &availableTVModes[2]; 1197 } else { 1198 if (pll->reference_freq == 2700) 1199 constPtr = &availableTVModes[1]; 1200 else 1201 constPtr = &availableTVModes[3]; 1202 } 1203 1204 save->crtc2_h_total_disp = (((constPtr->horResolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) | 1205 (((constPtr->horTotal / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT); 1206 1207 save->crtc2_h_sync_strt_wid = (save->crtc2_h_sync_strt_wid 1208 & ~(RADEON_CRTC_H_SYNC_STRT_PIX | RADEON_CRTC_H_SYNC_STRT_CHAR)) | 1209 (((constPtr->horSyncStart / 8) - 1) << RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) | 1210 (constPtr->horSyncStart & 7); 1211 1212 save->crtc2_v_total_disp = ((constPtr->verResolution - 1) << RADEON_CRTC_V_DISP_SHIFT) | 1213 ((constPtr->verTotal - 1) << RADEON_CRTC_V_TOTAL_SHIFT); 1214 1215 save->crtc2_v_sync_strt_wid = (save->crtc2_v_sync_strt_wid & ~RADEON_CRTC_V_SYNC_STRT) | 1216 ((constPtr->verSyncStart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT); 1217 1218} 1219 1220void RADEONAdjustPLL2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save, 1221 DisplayModePtr mode, xf86OutputPtr output) 1222{ 1223 unsigned postDiv; 1224 const TVModeConstants *constPtr; 1225 RADEONOutputPrivatePtr radeon_output = output->driver_private; 1226 radeon_tvout_ptr tvout = &radeon_output->tvout; 1227 RADEONInfoPtr info = RADEONPTR(pScrn); 1228 RADEONPLLPtr pll = &info->pll; 1229 1230 /* FIXME: need to revisit this when we add more modes */ 1231 if (tvout->tvStd == TV_STD_NTSC || 1232 tvout->tvStd == TV_STD_NTSC_J || 1233 tvout->tvStd == TV_STD_PAL_M) { 1234 if (pll->reference_freq == 2700) 1235 constPtr = &availableTVModes[0]; 1236 else 1237 constPtr = &availableTVModes[2]; 1238 } else { 1239 if (pll->reference_freq == 2700) 1240 constPtr = &availableTVModes[1]; 1241 else 1242 constPtr = &availableTVModes[3]; 1243 } 1244 1245 save->htotal_cntl2 = (constPtr->horTotal & 0x7); /* 0xf */ 1246 1247 save->p2pll_ref_div = constPtr->crtcPLL_M; 1248 1249 switch (constPtr->crtcPLL_postDiv) { 1250 case 1: 1251 postDiv = 0; 1252 break; 1253 case 2: 1254 postDiv = 1; 1255 break; 1256 case 3: 1257 postDiv = 4; 1258 break; 1259 case 4: 1260 postDiv = 2; 1261 break; 1262 case 6: 1263 postDiv = 6; 1264 break; 1265 case 8: 1266 postDiv = 3; 1267 break; 1268 case 12: 1269 postDiv = 7; 1270 break; 1271 case 16: 1272 default: 1273 postDiv = 5; 1274 break; 1275 } 1276 1277 save->p2pll_div_0 = (constPtr->crtcPLL_N & 0x7ff) | (postDiv << 16); 1278 1279 save->pixclks_cntl &= ~RADEON_PIX2CLK_SRC_SEL_MASK; 1280 save->pixclks_cntl |= (RADEON_PIX2CLK_SRC_SEL_P2PLLCLK 1281 | RADEON_PIXCLK_TV_SRC_SEL); 1282 1283} 1284