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