1// SPDX-License-Identifier: MIT
2
3#include <drm/drm_device.h>
4
5#include "radeon.h"
6
7/*
8 * Integrated TV out support based on the GATOS code by
9 * 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 10
23
24/*
25 * Indexes in h. code timing table for horizontal line position adjustment
26 */
27#define H_TABLE_POS1 6
28#define H_TABLE_POS2 8
29
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 233
37#define NTSC_TV_VFTOTAL 1
38#define NTSC_TV_LINES_PER_FRAME 525
39#define NTSC_TV_ZERO_H_SIZE 479166
40#define NTSC_TV_H_SIZE_UNIT 9478
41
42#define PAL_TV_CLOCK_T 188
43#define PAL_TV_VFTOTAL 3
44#define PAL_TV_LINES_PER_FRAME 625
45#define PAL_TV_ZERO_H_SIZE 473200
46#define PAL_TV_H_SIZE_UNIT 9360
47
48/* tv pll setting for 27 mhz ref clk */
49#define NTSC_TV_PLL_M_27 22
50#define NTSC_TV_PLL_N_27 175
51#define NTSC_TV_PLL_P_27 5
52
53#define PAL_TV_PLL_M_27 113
54#define PAL_TV_PLL_N_27 668
55#define PAL_TV_PLL_P_27 3
56
57/* tv pll setting for 14 mhz ref clk */
58#define NTSC_TV_PLL_M_14 33
59#define NTSC_TV_PLL_N_14 693
60#define NTSC_TV_PLL_P_14 7
61
62#define PAL_TV_PLL_M_14 19
63#define PAL_TV_PLL_N_14 353
64#define PAL_TV_PLL_P_14 5
65
66#define VERT_LEAD_IN_LINES 2
67#define FRAC_BITS 0xe
68#define FRAC_MASK 0x3fff
69
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 0
105};
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 0
122};
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 0
143};
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 0
162};
163
164/**********************************************************************
165 *
166 * availableModes
167 *
168 * Table of all allowed modes for tv output
169 *
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 else
250 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 else
261 const_ptr = &available_tv_modes[2];
262 } else {
263 if (pll->reference_freq == 2700)
264 const_ptr = &available_tv_modes[1];
265 else
266 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#endif
343
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_uv_adr: tv_dac->tv.tv_uv_adr);
397 v_table = radeon_get_vtiming_tables_addr(tv_uv_adr: 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, addr: h_table, value: 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, addr: v_table, value: 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 else
447 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 pixels
480 */
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 else
487 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 else
512 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: &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_EN
589 | RADEON_TVOUT_SCALE_EN
590 | (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 else
601 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 else
610 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 else
623 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 else
672 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 else
680 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, n_tests: 200, n_wait_loops: 800, cnt_threshold: 135);
763
764 WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET);
765
766 radeon_wait_pll_lock(encoder, n_tests: 300, n_wait_loops: 160, cnt_threshold: 27);
767 radeon_wait_pll_lock(encoder, n_tests: 200, n_wait_loops: 800, cnt_threshold: 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(value: 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(value: 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

source code of linux/drivers/gpu/drm/radeon/radeon_legacy_tv.c