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