912 lines · c
1// SPDX-License-Identifier: MIT2 3#include <drm/drm_device.h>4 5#include "radeon.h"6 7/*8 * Integrated TV out support based on the GATOS code by9 * Federico Ulivi <fulivi@lycos.com>10 */11 12 13/*14 * Limits of h/v positions (hPos & vPos)15 */16#define MAX_H_POSITION 5 /* Range: [-5..5], negative is on the left, 0 is default, positive is on the right */17#define MAX_V_POSITION 5 /* Range: [-5..5], negative is up, 0 is default, positive is down */18 19/*20 * Unit for hPos (in TV clock periods)21 */22#define H_POS_UNIT 1023 24/*25 * Indexes in h. code timing table for horizontal line position adjustment26 */27#define H_TABLE_POS1 628#define H_TABLE_POS2 829 30/*31 * Limits of hor. size (hSize)32 */33#define MAX_H_SIZE 5 /* Range: [-5..5], negative is smaller, positive is larger */34 35/* tv standard constants */36#define NTSC_TV_CLOCK_T 23337#define NTSC_TV_VFTOTAL 138#define NTSC_TV_LINES_PER_FRAME 52539#define NTSC_TV_ZERO_H_SIZE 47916640#define NTSC_TV_H_SIZE_UNIT 947841 42#define PAL_TV_CLOCK_T 18843#define PAL_TV_VFTOTAL 344#define PAL_TV_LINES_PER_FRAME 62545#define PAL_TV_ZERO_H_SIZE 47320046#define PAL_TV_H_SIZE_UNIT 936047 48/* tv pll setting for 27 mhz ref clk */49#define NTSC_TV_PLL_M_27 2250#define NTSC_TV_PLL_N_27 17551#define NTSC_TV_PLL_P_27 552 53#define PAL_TV_PLL_M_27 11354#define PAL_TV_PLL_N_27 66855#define PAL_TV_PLL_P_27 356 57/* tv pll setting for 14 mhz ref clk */58#define NTSC_TV_PLL_M_14 3359#define NTSC_TV_PLL_N_14 69360#define NTSC_TV_PLL_P_14 761 62#define PAL_TV_PLL_M_14 1963#define PAL_TV_PLL_N_14 35364#define PAL_TV_PLL_P_14 565 66#define VERT_LEAD_IN_LINES 267#define FRAC_BITS 0xe68#define FRAC_MASK 0x3fff69 70struct radeon_tv_mode_constants {71 uint16_t hor_resolution;72 uint16_t ver_resolution;73 enum radeon_tv_std standard;74 uint16_t hor_total;75 uint16_t ver_total;76 uint16_t hor_start;77 uint16_t hor_syncstart;78 uint16_t ver_syncstart;79 unsigned def_restart;80 uint16_t crtcPLL_N;81 uint8_t crtcPLL_M;82 uint8_t crtcPLL_post_div;83 unsigned pix_to_tv;84};85 86static const uint16_t hor_timing_NTSC[MAX_H_CODE_TIMING_LEN] = {87 0x0007,88 0x003f,89 0x0263,90 0x0a24,91 0x2a6b,92 0x0a36,93 0x126d, /* H_TABLE_POS1 */94 0x1bfe,95 0x1a8f, /* H_TABLE_POS2 */96 0x1ec7,97 0x3863,98 0x1bfe,99 0x1bfe,100 0x1a2a,101 0x1e95,102 0x0e31,103 0x201b,104 0105};106 107static const uint16_t vert_timing_NTSC[MAX_V_CODE_TIMING_LEN] = {108 0x2001,109 0x200d,110 0x1006,111 0x0c06,112 0x1006,113 0x1818,114 0x21e3,115 0x1006,116 0x0c06,117 0x1006,118 0x1817,119 0x21d4,120 0x0002,121 0122};123 124static const uint16_t hor_timing_PAL[MAX_H_CODE_TIMING_LEN] = {125 0x0007,126 0x0058,127 0x027c,128 0x0a31,129 0x2a77,130 0x0a95,131 0x124f, /* H_TABLE_POS1 */132 0x1bfe,133 0x1b22, /* H_TABLE_POS2 */134 0x1ef9,135 0x387c,136 0x1bfe,137 0x1bfe,138 0x1b31,139 0x1eb5,140 0x0e43,141 0x201b,142 0143};144 145static const uint16_t vert_timing_PAL[MAX_V_CODE_TIMING_LEN] = {146 0x2001,147 0x200c,148 0x1005,149 0x0c05,150 0x1005,151 0x1401,152 0x1821,153 0x2240,154 0x1005,155 0x0c05,156 0x1005,157 0x1401,158 0x1822,159 0x2230,160 0x0002,161 0162};163 164/**********************************************************************165 *166 * availableModes167 *168 * Table of all allowed modes for tv output169 *170 **********************************************************************/171static const struct radeon_tv_mode_constants available_tv_modes[] = {172 { /* NTSC timing for 27 Mhz ref clk */173 800, /* horResolution */174 600, /* verResolution */175 TV_STD_NTSC, /* standard */176 990, /* horTotal */177 740, /* verTotal */178 813, /* horStart */179 824, /* horSyncStart */180 632, /* verSyncStart */181 625592, /* defRestart */182 592, /* crtcPLL_N */183 91, /* crtcPLL_M */184 4, /* crtcPLL_postDiv */185 1022, /* pixToTV */186 },187 { /* PAL timing for 27 Mhz ref clk */188 800, /* horResolution */189 600, /* verResolution */190 TV_STD_PAL, /* standard */191 1144, /* horTotal */192 706, /* verTotal */193 812, /* horStart */194 824, /* horSyncStart */195 669, /* verSyncStart */196 696700, /* defRestart */197 1382, /* crtcPLL_N */198 231, /* crtcPLL_M */199 4, /* crtcPLL_postDiv */200 759, /* pixToTV */201 },202 { /* NTSC timing for 14 Mhz ref clk */203 800, /* horResolution */204 600, /* verResolution */205 TV_STD_NTSC, /* standard */206 1018, /* horTotal */207 727, /* verTotal */208 813, /* horStart */209 840, /* horSyncStart */210 633, /* verSyncStart */211 630627, /* defRestart */212 347, /* crtcPLL_N */213 14, /* crtcPLL_M */214 8, /* crtcPLL_postDiv */215 1022, /* pixToTV */216 },217 { /* PAL timing for 14 Mhz ref clk */218 800, /* horResolution */219 600, /* verResolution */220 TV_STD_PAL, /* standard */221 1131, /* horTotal */222 742, /* verTotal */223 813, /* horStart */224 840, /* horSyncStart */225 633, /* verSyncStart */226 708369, /* defRestart */227 211, /* crtcPLL_N */228 9, /* crtcPLL_M */229 8, /* crtcPLL_postDiv */230 759, /* pixToTV */231 },232};233 234#define N_AVAILABLE_MODES ARRAY_SIZE(available_tv_modes)235 236static const struct radeon_tv_mode_constants *radeon_legacy_tv_get_std_mode(struct radeon_encoder *radeon_encoder,237 uint16_t *pll_ref_freq)238{239 struct drm_device *dev = radeon_encoder->base.dev;240 struct radeon_device *rdev = dev->dev_private;241 struct radeon_crtc *radeon_crtc;242 struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;243 const struct radeon_tv_mode_constants *const_ptr;244 struct radeon_pll *pll;245 246 radeon_crtc = to_radeon_crtc(radeon_encoder->base.crtc);247 if (radeon_crtc->crtc_id == 1)248 pll = &rdev->clock.p2pll;249 else250 pll = &rdev->clock.p1pll;251 252 if (pll_ref_freq)253 *pll_ref_freq = pll->reference_freq;254 255 if (tv_dac->tv_std == TV_STD_NTSC ||256 tv_dac->tv_std == TV_STD_NTSC_J ||257 tv_dac->tv_std == TV_STD_PAL_M) {258 if (pll->reference_freq == 2700)259 const_ptr = &available_tv_modes[0];260 else261 const_ptr = &available_tv_modes[2];262 } else {263 if (pll->reference_freq == 2700)264 const_ptr = &available_tv_modes[1];265 else266 const_ptr = &available_tv_modes[3];267 }268 return const_ptr;269}270 271static long YCOEF_value[5] = { 2, 2, 0, 4, 0 };272static long YCOEF_EN_value[5] = { 1, 1, 0, 1, 0 };273static long SLOPE_value[5] = { 1, 2, 2, 4, 8 };274static long SLOPE_limit[5] = { 6, 5, 4, 3, 2 };275 276static void radeon_wait_pll_lock(struct drm_encoder *encoder, unsigned n_tests,277 unsigned n_wait_loops, unsigned cnt_threshold)278{279 struct drm_device *dev = encoder->dev;280 struct radeon_device *rdev = dev->dev_private;281 uint32_t save_pll_test;282 unsigned int i, j;283 284 WREG32(RADEON_TEST_DEBUG_MUX, (RREG32(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100);285 save_pll_test = RREG32_PLL(RADEON_PLL_TEST_CNTL);286 WREG32_PLL(RADEON_PLL_TEST_CNTL, save_pll_test & ~RADEON_PLL_MASK_READ_B);287 288 WREG8(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_TEST_CNTL);289 for (i = 0; i < n_tests; i++) {290 WREG8(RADEON_CLOCK_CNTL_DATA + 3, 0);291 for (j = 0; j < n_wait_loops; j++)292 if (RREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cnt_threshold)293 break;294 }295 WREG32_PLL(RADEON_PLL_TEST_CNTL, save_pll_test);296 WREG32(RADEON_TEST_DEBUG_MUX, RREG32(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff);297}298 299 300static void radeon_legacy_tv_write_fifo(struct radeon_encoder *radeon_encoder,301 uint16_t addr, uint32_t value)302{303 struct drm_device *dev = radeon_encoder->base.dev;304 struct radeon_device *rdev = dev->dev_private;305 uint32_t tmp;306 int i = 0;307 308 WREG32(RADEON_TV_HOST_WRITE_DATA, value);309 310 WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr);311 WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_WT);312 313 do {314 tmp = RREG32(RADEON_TV_HOST_RD_WT_CNTL);315 if ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0)316 break;317 i++;318 } while (i < 10000);319 WREG32(RADEON_TV_HOST_RD_WT_CNTL, 0);320}321 322#if 0 /* included for completeness */323static uint32_t radeon_legacy_tv_read_fifo(struct radeon_encoder *radeon_encoder, uint16_t addr)324{325 struct drm_device *dev = radeon_encoder->base.dev;326 struct radeon_device *rdev = dev->dev_private;327 uint32_t tmp;328 int i = 0;329 330 WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr);331 WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD);332 333 do {334 tmp = RREG32(RADEON_TV_HOST_RD_WT_CNTL);335 if ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0)336 break;337 i++;338 } while (i < 10000);339 WREG32(RADEON_TV_HOST_RD_WT_CNTL, 0);340 return RREG32(RADEON_TV_HOST_READ_DATA);341}342#endif343 344static uint16_t radeon_get_htiming_tables_addr(uint32_t tv_uv_adr)345{346 uint16_t h_table;347 348 switch ((tv_uv_adr & RADEON_HCODE_TABLE_SEL_MASK) >> RADEON_HCODE_TABLE_SEL_SHIFT) {349 case 0:350 h_table = RADEON_TV_MAX_FIFO_ADDR_INTERNAL;351 break;352 case 1:353 h_table = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2;354 break;355 case 2:356 h_table = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2;357 break;358 default:359 h_table = 0;360 break;361 }362 return h_table;363}364 365static uint16_t radeon_get_vtiming_tables_addr(uint32_t tv_uv_adr)366{367 uint16_t v_table;368 369 switch ((tv_uv_adr & RADEON_VCODE_TABLE_SEL_MASK) >> RADEON_VCODE_TABLE_SEL_SHIFT) {370 case 0:371 v_table = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1;372 break;373 case 1:374 v_table = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1;375 break;376 case 2:377 v_table = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1;378 break;379 default:380 v_table = 0;381 break;382 }383 return v_table;384}385 386static void radeon_restore_tv_timing_tables(struct radeon_encoder *radeon_encoder)387{388 struct drm_device *dev = radeon_encoder->base.dev;389 struct radeon_device *rdev = dev->dev_private;390 struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;391 uint16_t h_table, v_table;392 uint32_t tmp;393 int i;394 395 WREG32(RADEON_TV_UV_ADR, tv_dac->tv.tv_uv_adr);396 h_table = radeon_get_htiming_tables_addr(tv_dac->tv.tv_uv_adr);397 v_table = radeon_get_vtiming_tables_addr(tv_dac->tv.tv_uv_adr);398 399 for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, h_table--) {400 tmp = ((uint32_t)tv_dac->tv.h_code_timing[i] << 14) | ((uint32_t)tv_dac->tv.h_code_timing[i+1]);401 radeon_legacy_tv_write_fifo(radeon_encoder, h_table, tmp);402 if (tv_dac->tv.h_code_timing[i] == 0 || tv_dac->tv.h_code_timing[i + 1] == 0)403 break;404 }405 for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, v_table++) {406 tmp = ((uint32_t)tv_dac->tv.v_code_timing[i+1] << 14) | ((uint32_t)tv_dac->tv.v_code_timing[i]);407 radeon_legacy_tv_write_fifo(radeon_encoder, v_table, tmp);408 if (tv_dac->tv.v_code_timing[i] == 0 || tv_dac->tv.v_code_timing[i + 1] == 0)409 break;410 }411}412 413static void radeon_legacy_write_tv_restarts(struct radeon_encoder *radeon_encoder)414{415 struct drm_device *dev = radeon_encoder->base.dev;416 struct radeon_device *rdev = dev->dev_private;417 struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;418 WREG32(RADEON_TV_FRESTART, tv_dac->tv.frestart);419 WREG32(RADEON_TV_HRESTART, tv_dac->tv.hrestart);420 WREG32(RADEON_TV_VRESTART, tv_dac->tv.vrestart);421}422 423static bool radeon_legacy_tv_init_restarts(struct drm_encoder *encoder)424{425 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);426 struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;427 int restart;428 unsigned int h_total, v_total, f_total;429 int v_offset, h_offset;430 u16 p1, p2, h_inc;431 bool h_changed;432 const struct radeon_tv_mode_constants *const_ptr;433 434 const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);435 if (!const_ptr)436 return false;437 438 h_total = const_ptr->hor_total;439 v_total = const_ptr->ver_total;440 441 if (tv_dac->tv_std == TV_STD_NTSC ||442 tv_dac->tv_std == TV_STD_NTSC_J ||443 tv_dac->tv_std == TV_STD_PAL_M ||444 tv_dac->tv_std == TV_STD_PAL_60)445 f_total = NTSC_TV_VFTOTAL + 1;446 else447 f_total = PAL_TV_VFTOTAL + 1;448 449 /* adjust positions 1&2 in hor. cod timing table */450 h_offset = tv_dac->h_pos * H_POS_UNIT;451 452 if (tv_dac->tv_std == TV_STD_NTSC ||453 tv_dac->tv_std == TV_STD_NTSC_J ||454 tv_dac->tv_std == TV_STD_PAL_M) {455 h_offset -= 50;456 p1 = hor_timing_NTSC[H_TABLE_POS1];457 p2 = hor_timing_NTSC[H_TABLE_POS2];458 } else {459 p1 = hor_timing_PAL[H_TABLE_POS1];460 p2 = hor_timing_PAL[H_TABLE_POS2];461 }462 463 p1 = (u16)((int)p1 + h_offset);464 p2 = (u16)((int)p2 - h_offset);465 466 h_changed = (p1 != tv_dac->tv.h_code_timing[H_TABLE_POS1] ||467 p2 != tv_dac->tv.h_code_timing[H_TABLE_POS2]);468 469 tv_dac->tv.h_code_timing[H_TABLE_POS1] = p1;470 tv_dac->tv.h_code_timing[H_TABLE_POS2] = p2;471 472 /* Convert hOffset from n. of TV clock periods to n. of CRTC clock periods (CRTC pixels) */473 h_offset = (h_offset * (int)(const_ptr->pix_to_tv)) / 1000;474 475 /* adjust restart */476 restart = const_ptr->def_restart;477 478 /*479 * convert v_pos TV lines to n. of CRTC pixels480 */481 if (tv_dac->tv_std == TV_STD_NTSC ||482 tv_dac->tv_std == TV_STD_NTSC_J ||483 tv_dac->tv_std == TV_STD_PAL_M ||484 tv_dac->tv_std == TV_STD_PAL_60)485 v_offset = ((int)(v_total * h_total) * 2 * tv_dac->v_pos) / (int)(NTSC_TV_LINES_PER_FRAME);486 else487 v_offset = ((int)(v_total * h_total) * 2 * tv_dac->v_pos) / (int)(PAL_TV_LINES_PER_FRAME);488 489 restart -= v_offset + h_offset;490 491 DRM_DEBUG_KMS("compute_restarts: def = %u h = %d v = %d, p1 = %04x, p2 = %04x, restart = %d\n",492 const_ptr->def_restart, tv_dac->h_pos, tv_dac->v_pos, p1, p2, restart);493 494 tv_dac->tv.hrestart = restart % h_total;495 restart /= h_total;496 tv_dac->tv.vrestart = restart % v_total;497 restart /= v_total;498 tv_dac->tv.frestart = restart % f_total;499 500 DRM_DEBUG_KMS("compute_restart: F/H/V=%u,%u,%u\n",501 (unsigned)tv_dac->tv.frestart,502 (unsigned)tv_dac->tv.vrestart,503 (unsigned)tv_dac->tv.hrestart);504 505 /* compute h_inc from hsize */506 if (tv_dac->tv_std == TV_STD_NTSC ||507 tv_dac->tv_std == TV_STD_NTSC_J ||508 tv_dac->tv_std == TV_STD_PAL_M)509 h_inc = (u16)((int)(const_ptr->hor_resolution * 4096 * NTSC_TV_CLOCK_T) /510 (tv_dac->h_size * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE)));511 else512 h_inc = (u16)((int)(const_ptr->hor_resolution * 4096 * PAL_TV_CLOCK_T) /513 (tv_dac->h_size * (int)(PAL_TV_H_SIZE_UNIT) + (int)(PAL_TV_ZERO_H_SIZE)));514 515 tv_dac->tv.timing_cntl = (tv_dac->tv.timing_cntl & ~RADEON_H_INC_MASK) |516 ((u32)h_inc << RADEON_H_INC_SHIFT);517 518 DRM_DEBUG_KMS("compute_restart: h_size = %d h_inc = %d\n", tv_dac->h_size, h_inc);519 520 return h_changed;521}522 523void radeon_legacy_tv_mode_set(struct drm_encoder *encoder,524 struct drm_display_mode *mode,525 struct drm_display_mode *adjusted_mode)526{527 struct drm_device *dev = encoder->dev;528 struct radeon_device *rdev = dev->dev_private;529 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);530 struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;531 const struct radeon_tv_mode_constants *const_ptr;532 struct radeon_crtc *radeon_crtc;533 int i;534 uint16_t pll_ref_freq;535 uint32_t vert_space, flicker_removal, tmp;536 uint32_t tv_master_cntl, tv_rgb_cntl, tv_dac_cntl;537 uint32_t tv_modulator_cntl1, tv_modulator_cntl2;538 uint32_t tv_vscaler_cntl1, tv_vscaler_cntl2;539 uint32_t tv_pll_cntl, tv_ftotal;540 uint32_t tv_y_fall_cntl, tv_y_rise_cntl, tv_y_saw_tooth_cntl;541 uint32_t m, n, p;542 const uint16_t *hor_timing;543 const uint16_t *vert_timing;544 545 const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, &pll_ref_freq);546 if (!const_ptr)547 return;548 549 radeon_crtc = to_radeon_crtc(encoder->crtc);550 551 tv_master_cntl = (RADEON_VIN_ASYNC_RST |552 RADEON_CRT_FIFO_CE_EN |553 RADEON_TV_FIFO_CE_EN |554 RADEON_TV_ON);555 556 if (!ASIC_IS_R300(rdev))557 tv_master_cntl |= RADEON_TVCLK_ALWAYS_ONb;558 559 if (tv_dac->tv_std == TV_STD_NTSC ||560 tv_dac->tv_std == TV_STD_NTSC_J)561 tv_master_cntl |= RADEON_RESTART_PHASE_FIX;562 563 tv_modulator_cntl1 = (RADEON_SLEW_RATE_LIMIT |564 RADEON_SYNC_TIP_LEVEL |565 RADEON_YFLT_EN |566 RADEON_UVFLT_EN |567 (6 << RADEON_CY_FILT_BLEND_SHIFT));568 569 if (tv_dac->tv_std == TV_STD_NTSC ||570 tv_dac->tv_std == TV_STD_NTSC_J) {571 tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT) |572 (0x3b << RADEON_BLANK_LEVEL_SHIFT);573 tv_modulator_cntl2 = (-111 & RADEON_TV_U_BURST_LEVEL_MASK) |574 ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);575 } else if (tv_dac->tv_std == TV_STD_SCART_PAL) {576 tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN;577 tv_modulator_cntl2 = (0 & RADEON_TV_U_BURST_LEVEL_MASK) |578 ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);579 } else {580 tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN |581 (0x3b << RADEON_SET_UP_LEVEL_SHIFT) |582 (0x3b << RADEON_BLANK_LEVEL_SHIFT);583 tv_modulator_cntl2 = (-78 & RADEON_TV_U_BURST_LEVEL_MASK) |584 ((62 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);585 }586 587 588 tv_rgb_cntl = (RADEON_RGB_DITHER_EN589 | RADEON_TVOUT_SCALE_EN590 | (0x0b << RADEON_UVRAM_READ_MARGIN_SHIFT)591 | (0x07 << RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT)592 | RADEON_RGB_ATTEN_SEL(0x3)593 | RADEON_RGB_ATTEN_VAL(0xc));594 595 if (radeon_crtc->crtc_id == 1)596 tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC2;597 else {598 if (radeon_crtc->rmx_type != RMX_OFF)599 tv_rgb_cntl |= RADEON_RGB_SRC_SEL_RMX;600 else601 tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC1;602 }603 604 if (tv_dac->tv_std == TV_STD_NTSC ||605 tv_dac->tv_std == TV_STD_NTSC_J ||606 tv_dac->tv_std == TV_STD_PAL_M ||607 tv_dac->tv_std == TV_STD_PAL_60)608 vert_space = const_ptr->ver_total * 2 * 10000 / NTSC_TV_LINES_PER_FRAME;609 else610 vert_space = const_ptr->ver_total * 2 * 10000 / PAL_TV_LINES_PER_FRAME;611 612 tmp = RREG32(RADEON_TV_VSCALER_CNTL1);613 tmp &= 0xe3ff0000;614 tmp |= (vert_space * (1 << FRAC_BITS) / 10000);615 tv_vscaler_cntl1 = tmp;616 617 if (pll_ref_freq == 2700)618 tv_vscaler_cntl1 |= RADEON_RESTART_FIELD;619 620 if (const_ptr->hor_resolution == 1024)621 tv_vscaler_cntl1 |= (4 << RADEON_Y_DEL_W_SIG_SHIFT);622 else623 tv_vscaler_cntl1 |= (2 << RADEON_Y_DEL_W_SIG_SHIFT);624 625 /* scale up for int divide */626 tmp = const_ptr->ver_total * 2 * 1000;627 if (tv_dac->tv_std == TV_STD_NTSC ||628 tv_dac->tv_std == TV_STD_NTSC_J ||629 tv_dac->tv_std == TV_STD_PAL_M ||630 tv_dac->tv_std == TV_STD_PAL_60) {631 tmp /= NTSC_TV_LINES_PER_FRAME;632 } else {633 tmp /= PAL_TV_LINES_PER_FRAME;634 }635 flicker_removal = (tmp + 500) / 1000;636 637 if (flicker_removal < 3)638 flicker_removal = 3;639 for (i = 0; i < ARRAY_SIZE(SLOPE_limit); ++i) {640 if (flicker_removal == SLOPE_limit[i])641 break;642 }643 644 tv_y_saw_tooth_cntl = (vert_space * SLOPE_value[i] * (1 << (FRAC_BITS - 1)) +645 5001) / 10000 / 8 | ((SLOPE_value[i] *646 (1 << (FRAC_BITS - 1)) / 8) << 16);647 tv_y_fall_cntl =648 (YCOEF_EN_value[i] << 17) | ((YCOEF_value[i] * (1 << 8) / 8) << 24) |649 RADEON_Y_FALL_PING_PONG | (272 * SLOPE_value[i] / 8) * (1 << (FRAC_BITS - 1)) /650 1024;651 tv_y_rise_cntl = RADEON_Y_RISE_PING_PONG|652 (flicker_removal * 1024 - 272) * SLOPE_value[i] / 8 * (1 << (FRAC_BITS - 1)) / 1024;653 654 tv_vscaler_cntl2 = RREG32(RADEON_TV_VSCALER_CNTL2) & 0x00fffff0;655 tv_vscaler_cntl2 |= (0x10 << 24) |656 RADEON_DITHER_MODE |657 RADEON_Y_OUTPUT_DITHER_EN |658 RADEON_UV_OUTPUT_DITHER_EN |659 RADEON_UV_TO_BUF_DITHER_EN;660 661 tmp = (tv_vscaler_cntl1 >> RADEON_UV_INC_SHIFT) & RADEON_UV_INC_MASK;662 tmp = ((16384 * 256 * 10) / tmp + 5) / 10;663 tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000;664 tv_dac->tv.timing_cntl = tmp;665 666 if (tv_dac->tv_std == TV_STD_NTSC ||667 tv_dac->tv_std == TV_STD_NTSC_J ||668 tv_dac->tv_std == TV_STD_PAL_M ||669 tv_dac->tv_std == TV_STD_PAL_60)670 tv_dac_cntl = tv_dac->ntsc_tvdac_adj;671 else672 tv_dac_cntl = tv_dac->pal_tvdac_adj;673 674 tv_dac_cntl |= RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD;675 676 if (tv_dac->tv_std == TV_STD_NTSC ||677 tv_dac->tv_std == TV_STD_NTSC_J)678 tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;679 else680 tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;681 682 if (tv_dac->tv_std == TV_STD_NTSC ||683 tv_dac->tv_std == TV_STD_NTSC_J) {684 if (pll_ref_freq == 2700) {685 m = NTSC_TV_PLL_M_27;686 n = NTSC_TV_PLL_N_27;687 p = NTSC_TV_PLL_P_27;688 } else {689 m = NTSC_TV_PLL_M_14;690 n = NTSC_TV_PLL_N_14;691 p = NTSC_TV_PLL_P_14;692 }693 } else {694 if (pll_ref_freq == 2700) {695 m = PAL_TV_PLL_M_27;696 n = PAL_TV_PLL_N_27;697 p = PAL_TV_PLL_P_27;698 } else {699 m = PAL_TV_PLL_M_14;700 n = PAL_TV_PLL_N_14;701 p = PAL_TV_PLL_P_14;702 }703 }704 705 tv_pll_cntl = (m & RADEON_TV_M0LO_MASK) |706 (((m >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) |707 ((n & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) |708 (((n >> 9) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) |709 ((p & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT);710 711 tv_dac->tv.tv_uv_adr = 0xc8;712 713 if (tv_dac->tv_std == TV_STD_NTSC ||714 tv_dac->tv_std == TV_STD_NTSC_J ||715 tv_dac->tv_std == TV_STD_PAL_M ||716 tv_dac->tv_std == TV_STD_PAL_60) {717 tv_ftotal = NTSC_TV_VFTOTAL;718 hor_timing = hor_timing_NTSC;719 vert_timing = vert_timing_NTSC;720 } else {721 hor_timing = hor_timing_PAL;722 vert_timing = vert_timing_PAL;723 tv_ftotal = PAL_TV_VFTOTAL;724 }725 726 for (i = 0; i < MAX_H_CODE_TIMING_LEN; i++) {727 tv_dac->tv.h_code_timing[i] = hor_timing[i];728 if (tv_dac->tv.h_code_timing[i] == 0)729 break;730 }731 732 for (i = 0; i < MAX_V_CODE_TIMING_LEN; i++) {733 tv_dac->tv.v_code_timing[i] = vert_timing[i];734 if (tv_dac->tv.v_code_timing[i] == 0)735 break;736 }737 738 radeon_legacy_tv_init_restarts(encoder);739 740 /* play with DAC_CNTL */741 /* play with GPIOPAD_A */742 /* DISP_OUTPUT_CNTL */743 /* use reference freq */744 745 /* program the TV registers */746 WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST |747 RADEON_CRT_ASYNC_RST | RADEON_TV_FIFO_ASYNC_RST));748 749 tmp = RREG32(RADEON_TV_DAC_CNTL);750 tmp &= ~RADEON_TV_DAC_NBLANK;751 tmp |= RADEON_TV_DAC_BGSLEEP |752 RADEON_TV_DAC_RDACPD |753 RADEON_TV_DAC_GDACPD |754 RADEON_TV_DAC_BDACPD;755 WREG32(RADEON_TV_DAC_CNTL, tmp);756 757 /* TV PLL */758 WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVCLK_SRC_SEL_TVPLL);759 WREG32_PLL(RADEON_TV_PLL_CNTL, tv_pll_cntl);760 WREG32_PLL_P(RADEON_TV_PLL_CNTL1, RADEON_TVPLL_RESET, ~RADEON_TVPLL_RESET);761 762 radeon_wait_pll_lock(encoder, 200, 800, 135);763 764 WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET);765 766 radeon_wait_pll_lock(encoder, 300, 160, 27);767 radeon_wait_pll_lock(encoder, 200, 800, 135);768 769 WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~0xf);770 WREG32_PLL_P(RADEON_TV_PLL_CNTL1, RADEON_TVCLK_SRC_SEL_TVPLL, ~RADEON_TVCLK_SRC_SEL_TVPLL);771 772 WREG32_PLL_P(RADEON_TV_PLL_CNTL1, (1 << RADEON_TVPDC_SHIFT), ~RADEON_TVPDC_MASK);773 WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_SLEEP);774 775 /* TV HV */776 WREG32(RADEON_TV_RGB_CNTL, tv_rgb_cntl);777 WREG32(RADEON_TV_HTOTAL, const_ptr->hor_total - 1);778 WREG32(RADEON_TV_HDISP, const_ptr->hor_resolution - 1);779 WREG32(RADEON_TV_HSTART, const_ptr->hor_start);780 781 WREG32(RADEON_TV_VTOTAL, const_ptr->ver_total - 1);782 WREG32(RADEON_TV_VDISP, const_ptr->ver_resolution - 1);783 WREG32(RADEON_TV_FTOTAL, tv_ftotal);784 WREG32(RADEON_TV_VSCALER_CNTL1, tv_vscaler_cntl1);785 WREG32(RADEON_TV_VSCALER_CNTL2, tv_vscaler_cntl2);786 787 WREG32(RADEON_TV_Y_FALL_CNTL, tv_y_fall_cntl);788 WREG32(RADEON_TV_Y_RISE_CNTL, tv_y_rise_cntl);789 WREG32(RADEON_TV_Y_SAW_TOOTH_CNTL, tv_y_saw_tooth_cntl);790 791 WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST |792 RADEON_CRT_ASYNC_RST));793 794 /* TV restarts */795 radeon_legacy_write_tv_restarts(radeon_encoder);796 797 /* tv timings */798 radeon_restore_tv_timing_tables(radeon_encoder);799 800 WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST));801 802 /* tv std */803 WREG32(RADEON_TV_SYNC_CNTL, (RADEON_SYNC_PUB | RADEON_TV_SYNC_IO_DRIVE));804 WREG32(RADEON_TV_TIMING_CNTL, tv_dac->tv.timing_cntl);805 WREG32(RADEON_TV_MODULATOR_CNTL1, tv_modulator_cntl1);806 WREG32(RADEON_TV_MODULATOR_CNTL2, tv_modulator_cntl2);807 WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, (RADEON_Y_RED_EN |808 RADEON_C_GRN_EN |809 RADEON_CMP_BLU_EN |810 RADEON_DAC_DITHER_EN));811 812 WREG32(RADEON_TV_CRC_CNTL, 0);813 814 WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl);815 816 WREG32(RADEON_TV_GAIN_LIMIT_SETTINGS, ((0x17f << RADEON_UV_GAIN_LIMIT_SHIFT) |817 (0x5ff << RADEON_Y_GAIN_LIMIT_SHIFT)));818 WREG32(RADEON_TV_LINEAR_GAIN_SETTINGS, ((0x100 << RADEON_UV_GAIN_SHIFT) |819 (0x100 << RADEON_Y_GAIN_SHIFT)));820 821 WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);822 823}824 825void radeon_legacy_tv_adjust_crtc_reg(struct drm_encoder *encoder,826 uint32_t *h_total_disp, uint32_t *h_sync_strt_wid,827 uint32_t *v_total_disp, uint32_t *v_sync_strt_wid)828{829 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);830 const struct radeon_tv_mode_constants *const_ptr;831 uint32_t tmp;832 833 const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);834 if (!const_ptr)835 return;836 837 *h_total_disp = (((const_ptr->hor_resolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) |838 (((const_ptr->hor_total / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT);839 840 tmp = *h_sync_strt_wid;841 tmp &= ~(RADEON_CRTC_H_SYNC_STRT_PIX | RADEON_CRTC_H_SYNC_STRT_CHAR);842 tmp |= (((const_ptr->hor_syncstart / 8) - 1) << RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) |843 (const_ptr->hor_syncstart & 7);844 *h_sync_strt_wid = tmp;845 846 *v_total_disp = ((const_ptr->ver_resolution - 1) << RADEON_CRTC_V_DISP_SHIFT) |847 ((const_ptr->ver_total - 1) << RADEON_CRTC_V_TOTAL_SHIFT);848 849 tmp = *v_sync_strt_wid;850 tmp &= ~RADEON_CRTC_V_SYNC_STRT;851 tmp |= ((const_ptr->ver_syncstart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT);852 *v_sync_strt_wid = tmp;853}854 855static int get_post_div(int value)856{857 int post_div;858 switch (value) {859 case 1: post_div = 0; break;860 case 2: post_div = 1; break;861 case 3: post_div = 4; break;862 case 4: post_div = 2; break;863 case 6: post_div = 6; break;864 case 8: post_div = 3; break;865 case 12: post_div = 7; break;866 case 16:867 default: post_div = 5; break;868 }869 return post_div;870}871 872void radeon_legacy_tv_adjust_pll1(struct drm_encoder *encoder,873 uint32_t *htotal_cntl, uint32_t *ppll_ref_div,874 uint32_t *ppll_div_3, uint32_t *pixclks_cntl)875{876 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);877 const struct radeon_tv_mode_constants *const_ptr;878 879 const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);880 if (!const_ptr)881 return;882 883 *htotal_cntl = (const_ptr->hor_total & 0x7) | RADEON_HTOT_CNTL_VGA_EN;884 885 *ppll_ref_div = const_ptr->crtcPLL_M;886 887 *ppll_div_3 = (const_ptr->crtcPLL_N & 0x7ff) | (get_post_div(const_ptr->crtcPLL_post_div) << 16);888 *pixclks_cntl &= ~(RADEON_PIX2CLK_SRC_SEL_MASK | RADEON_PIXCLK_TV_SRC_SEL);889 *pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK;890}891 892void radeon_legacy_tv_adjust_pll2(struct drm_encoder *encoder,893 uint32_t *htotal2_cntl, uint32_t *p2pll_ref_div,894 uint32_t *p2pll_div_0, uint32_t *pixclks_cntl)895{896 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);897 const struct radeon_tv_mode_constants *const_ptr;898 899 const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);900 if (!const_ptr)901 return;902 903 *htotal2_cntl = (const_ptr->hor_total & 0x7);904 905 *p2pll_ref_div = const_ptr->crtcPLL_M;906 907 *p2pll_div_0 = (const_ptr->crtcPLL_N & 0x7ff) | (get_post_div(const_ptr->crtcPLL_post_div) << 16);908 *pixclks_cntl &= ~RADEON_PIX2CLK_SRC_SEL_MASK;909 *pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK | RADEON_PIXCLK_TV_SRC_SEL;910}911 912