Home | History | Annotate | Line # | Download | only in src
      1 /*
      2  * Integrated TV out support based on the GATOS code by
      3  * Federico Ulivi <fulivi (at) 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 
     36 typedef 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 
     53 static 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 
     75 static 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 
     93 static 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 
    115 static 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  **********************************************************************/
    142 static 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 
    208 static long YCOEF_value[5] = { 2, 2, 0, 4, 0 };
    209 static long YCOEF_EN_value[5] = { 1, 1, 0, 1, 0 };
    210 static long SLOPE_value[5] = { 1, 2, 2, 4, 8 };
    211 static long SLOPE_limit[5] = { 6, 5, 4, 3, 2 };
    212 
    213 
    214 static void
    215 RADEONWaitPLLLock(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 */
    248 static void
    249 RADEONWriteTVFIFO(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 */
    275 static uint32_t
    276 RADEONReadTVFIFO(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  */
    303 static uint16_t
    304 RADEONGetHTimingTablesAddr(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 
    326 static uint16_t
    327 RADEONGetVTimingTablesAddr(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 */
    350 static void
    351 RADEONRestoreTVTimingTables(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 */
    380 static void
    381 RADEONRestoreTVPLLRegisters(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 */
    403 static void
    404 RADEONRestoreTVHVRegisters(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 */
    429 static void
    430 RADEONRestoreTVRestarts(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 */
    441 static void
    442 RADEONRestoreTVOutputStd(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 */
    460 void
    461 RADEONRestoreTVRegisters(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 */
    514 static void
    515 RADEONSaveTVTimingTables(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 */
    563 void
    564 RADEONSaveTVRegisters(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  */
    612 static 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 */
    734 void 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 */
   1050 void 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 
   1076 void 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 
   1116 void 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 
   1180 void 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 
   1220 void 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