radeon_legacy_tv.c revision 254885
142421Syokota#include <sys/cdefs.h>
242421Syokota__FBSDID("$FreeBSD: head/sys/dev/drm2/radeon/radeon_legacy_tv.c 254885 2013-08-25 19:37:15Z dumbbell $");
342421Syokota
442421Syokota#include <dev/drm2/drmP.h>
542421Syokota#include <dev/drm2/drm_crtc_helper.h>
642421Syokota#include "radeon.h"
742421Syokota
842421Syokota/*
942421Syokota * Integrated TV out support based on the GATOS code by
1042421Syokota * Federico Ulivi <fulivi@lycos.com>
1142421Syokota */
1242421Syokota
1342421Syokota
1442421Syokota/*
1542421Syokota * Limits of h/v positions (hPos & vPos)
1642421Syokota */
1742421Syokota#define MAX_H_POSITION 5 /* Range: [-5..5], negative is on the left, 0 is default, positive is on the right */
1842421Syokota#define MAX_V_POSITION 5 /* Range: [-5..5], negative is up, 0 is default, positive is down */
1942421Syokota
2042421Syokota/*
2142421Syokota * Unit for hPos (in TV clock periods)
2242421Syokota */
2342421Syokota#define H_POS_UNIT 10
2442421Syokota
2542421Syokota/*
2642421Syokota * Indexes in h. code timing table for horizontal line position adjustment
2742421Syokota */
2842421Syokota#define H_TABLE_POS1 6
2942421Syokota#define H_TABLE_POS2 8
3042421Syokota
3142421Syokota/*
3242421Syokota * Limits of hor. size (hSize)
3342421Syokota */
3442421Syokota#define MAX_H_SIZE 5 /* Range: [-5..5], negative is smaller, positive is larger */
3542421Syokota
3642421Syokota/* tv standard constants */
3742421Syokota#define NTSC_TV_CLOCK_T 233
3842421Syokota#define NTSC_TV_VFTOTAL 1
3942421Syokota#define NTSC_TV_LINES_PER_FRAME 525
4042421Syokota#define NTSC_TV_ZERO_H_SIZE 479166
4142421Syokota#define NTSC_TV_H_SIZE_UNIT 9478
4242421Syokota
4342421Syokota#define PAL_TV_CLOCK_T 188
4442421Syokota#define PAL_TV_VFTOTAL 3
4542421Syokota#define PAL_TV_LINES_PER_FRAME 625
4642421Syokota#define PAL_TV_ZERO_H_SIZE 473200
4742421Syokota#define PAL_TV_H_SIZE_UNIT 9360
4842421Syokota
4942421Syokota/* tv pll setting for 27 mhz ref clk */
5042421Syokota#define NTSC_TV_PLL_M_27 22
5142421Syokota#define NTSC_TV_PLL_N_27 175
5242421Syokota#define NTSC_TV_PLL_P_27 5
5342421Syokota
5442421Syokota#define PAL_TV_PLL_M_27 113
5542421Syokota#define PAL_TV_PLL_N_27 668
5642421Syokota#define PAL_TV_PLL_P_27 3
5742421Syokota
5842421Syokota/* tv pll setting for 14 mhz ref clk */
5942421Syokota#define NTSC_TV_PLL_M_14 33
6042421Syokota#define NTSC_TV_PLL_N_14 693
6142421Syokota#define NTSC_TV_PLL_P_14 7
6242421Syokota
6342421Syokota#define PAL_TV_PLL_M_14 19
6442421Syokota#define PAL_TV_PLL_N_14 353
6542421Syokota#define PAL_TV_PLL_P_14 5
6642421Syokota
6742421Syokota#define VERT_LEAD_IN_LINES 2
6842421Syokota#define FRAC_BITS 0xe
6942421Syokota#define FRAC_MASK 0x3fff
7042421Syokota
7142421Syokotastruct radeon_tv_mode_constants {
7242421Syokota	uint16_t hor_resolution;
7342421Syokota	uint16_t ver_resolution;
7442421Syokota	enum radeon_tv_std standard;
7542421Syokota	uint16_t hor_total;
7642421Syokota	uint16_t ver_total;
7742421Syokota	uint16_t hor_start;
7842421Syokota	uint16_t hor_syncstart;
7942421Syokota	uint16_t ver_syncstart;
8042421Syokota	unsigned def_restart;
8142421Syokota	uint16_t crtcPLL_N;
8242421Syokota	uint8_t  crtcPLL_M;
8342421Syokota	uint8_t  crtcPLL_post_div;
8442421Syokota	unsigned pix_to_tv;
8542421Syokota};
8642421Syokota
8742421Syokotastatic const uint16_t hor_timing_NTSC[MAX_H_CODE_TIMING_LEN] = {
8842421Syokota	0x0007,
8942421Syokota	0x003f,
9042421Syokota	0x0263,
9142421Syokota	0x0a24,
9242421Syokota	0x2a6b,
9342421Syokota	0x0a36,
9442421Syokota	0x126d, /* H_TABLE_POS1 */
9542421Syokota	0x1bfe,
9642421Syokota	0x1a8f, /* H_TABLE_POS2 */
9742421Syokota	0x1ec7,
9842421Syokota	0x3863,
9942421Syokota	0x1bfe,
10042421Syokota	0x1bfe,
10142421Syokota	0x1a2a,
10242421Syokota	0x1e95,
10342421Syokota	0x0e31,
10442421Syokota	0x201b,
10542421Syokota	0
10642421Syokota};
10742421Syokota
10842421Syokotastatic const uint16_t vert_timing_NTSC[MAX_V_CODE_TIMING_LEN] = {
10942421Syokota	0x2001,
11042421Syokota	0x200d,
11142421Syokota	0x1006,
11242421Syokota	0x0c06,
11342421Syokota	0x1006,
11442421Syokota	0x1818,
11542421Syokota	0x21e3,
11642421Syokota	0x1006,
11742421Syokota	0x0c06,
11842421Syokota	0x1006,
11942421Syokota	0x1817,
12042421Syokota	0x21d4,
12142421Syokota	0x0002,
12242421Syokota	0
12342421Syokota};
12442421Syokota
12542421Syokotastatic const uint16_t hor_timing_PAL[MAX_H_CODE_TIMING_LEN] = {
12642421Syokota	0x0007,
12742421Syokota	0x0058,
12842421Syokota	0x027c,
12942421Syokota	0x0a31,
13042421Syokota	0x2a77,
13142421Syokota	0x0a95,
13242421Syokota	0x124f, /* H_TABLE_POS1 */
13342421Syokota	0x1bfe,
13442421Syokota	0x1b22, /* H_TABLE_POS2 */
13542421Syokota	0x1ef9,
13642421Syokota	0x387c,
13742421Syokota	0x1bfe,
13842421Syokota	0x1bfe,
13942421Syokota	0x1b31,
14042421Syokota	0x1eb5,
14142421Syokota	0x0e43,
14242421Syokota	0x201b,
14342421Syokota	0
14442421Syokota};
14542421Syokota
14642421Syokotastatic const uint16_t vert_timing_PAL[MAX_V_CODE_TIMING_LEN] = {
14742421Syokota	0x2001,
14842421Syokota	0x200c,
14942421Syokota	0x1005,
15042421Syokota	0x0c05,
15142421Syokota	0x1005,
15242421Syokota	0x1401,
15342421Syokota	0x1821,
15442421Syokota	0x2240,
15542421Syokota	0x1005,
15642421Syokota	0x0c05,
15742421Syokota	0x1005,
15842421Syokota	0x1401,
15942421Syokota	0x1822,
16042421Syokota	0x2230,
16142421Syokota	0x0002,
16242421Syokota	0
16342421Syokota};
16442421Syokota
16542421Syokota/**********************************************************************
16642421Syokota *
16742421Syokota * availableModes
16842421Syokota *
16942421Syokota * Table of all allowed modes for tv output
17042421Syokota *
17142421Syokota **********************************************************************/
17242421Syokotastatic const struct radeon_tv_mode_constants available_tv_modes[] = {
17342421Syokota	{   /* NTSC timing for 27 Mhz ref clk */
17442421Syokota		800,                /* horResolution */
17542421Syokota		600,                /* verResolution */
17642421Syokota		TV_STD_NTSC,        /* standard */
17742421Syokota		990,                /* horTotal */
17842421Syokota		740,                /* verTotal */
17942421Syokota		813,                /* horStart */
18042421Syokota		824,                /* horSyncStart */
18142421Syokota		632,                /* verSyncStart */
18242421Syokota		625592,             /* defRestart */
18342421Syokota		592,                /* crtcPLL_N */
18442421Syokota		91,                 /* crtcPLL_M */
18542421Syokota		4,                  /* crtcPLL_postDiv */
18642421Syokota		1022,               /* pixToTV */
18742421Syokota	},
18842421Syokota	{   /* PAL timing for 27 Mhz ref clk */
18942421Syokota		800,               /* horResolution */
19042421Syokota		600,               /* verResolution */
19142421Syokota		TV_STD_PAL,        /* standard */
19242421Syokota		1144,              /* horTotal */
19342421Syokota		706,               /* verTotal */
19442421Syokota		812,               /* horStart */
19542421Syokota		824,               /* horSyncStart */
19642421Syokota		669,               /* verSyncStart */
19742421Syokota		696700,            /* defRestart */
19842421Syokota		1382,              /* crtcPLL_N */
19942421Syokota		231,               /* crtcPLL_M */
20042421Syokota		4,                 /* crtcPLL_postDiv */
20142421Syokota		759,               /* pixToTV */
20242421Syokota	},
20342421Syokota	{   /* NTSC timing for 14 Mhz ref clk */
20442421Syokota		800,                /* horResolution */
20542421Syokota		600,                /* verResolution */
20642421Syokota		TV_STD_NTSC,        /* standard */
20742421Syokota		1018,               /* horTotal */
20842421Syokota		727,                /* verTotal */
20942421Syokota		813,                /* horStart */
21042421Syokota		840,                /* horSyncStart */
21142421Syokota		633,                /* verSyncStart */
21242421Syokota		630627,             /* defRestart */
21342421Syokota		347,                /* crtcPLL_N */
21442421Syokota		14,                 /* crtcPLL_M */
21542421Syokota		8,                  /* crtcPLL_postDiv */
21642421Syokota		1022,               /* pixToTV */
21742421Syokota	},
21842421Syokota	{ /* PAL timing for 14 Mhz ref clk */
21942421Syokota		800,                /* horResolution */
22042421Syokota		600,                /* verResolution */
22142421Syokota		TV_STD_PAL,         /* standard */
22242421Syokota		1131,               /* horTotal */
22342421Syokota		742,                /* verTotal */
22442421Syokota		813,                /* horStart */
22542421Syokota		840,                /* horSyncStart */
22642421Syokota		633,                /* verSyncStart */
22742421Syokota		708369,             /* defRestart */
22842421Syokota		211,                /* crtcPLL_N */
22942421Syokota		9,                  /* crtcPLL_M */
23042421Syokota		8,                  /* crtcPLL_postDiv */
23142421Syokota		759,                /* pixToTV */
23242421Syokota	},
23342421Syokota};
23442421Syokota
23542421Syokota#define N_AVAILABLE_MODES DRM_ARRAY_SIZE(available_tv_modes)
23642421Syokota
23742421Syokotastatic const struct radeon_tv_mode_constants *radeon_legacy_tv_get_std_mode(struct radeon_encoder *radeon_encoder,
23842421Syokota									    uint16_t *pll_ref_freq)
23942421Syokota{
24042421Syokota	struct drm_device *dev = radeon_encoder->base.dev;
24142421Syokota	struct radeon_device *rdev = dev->dev_private;
24242421Syokota	struct radeon_crtc *radeon_crtc;
24342421Syokota	struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
24442421Syokota	const struct radeon_tv_mode_constants *const_ptr;
24542421Syokota	struct radeon_pll *pll;
24642421Syokota
247	radeon_crtc = to_radeon_crtc(radeon_encoder->base.crtc);
248	if (radeon_crtc->crtc_id == 1)
249		pll = &rdev->clock.p2pll;
250	else
251		pll = &rdev->clock.p1pll;
252
253	if (pll_ref_freq)
254		*pll_ref_freq = pll->reference_freq;
255
256	if (tv_dac->tv_std == TV_STD_NTSC ||
257	    tv_dac->tv_std == TV_STD_NTSC_J ||
258	    tv_dac->tv_std == TV_STD_PAL_M) {
259		if (pll->reference_freq == 2700)
260			const_ptr = &available_tv_modes[0];
261		else
262			const_ptr = &available_tv_modes[2];
263	} else {
264		if (pll->reference_freq == 2700)
265			const_ptr = &available_tv_modes[1];
266		else
267			const_ptr = &available_tv_modes[3];
268	}
269	return const_ptr;
270}
271
272static long YCOEF_value[5] = { 2, 2, 0, 4, 0 };
273static long YCOEF_EN_value[5] = { 1, 1, 0, 1, 0 };
274static long SLOPE_value[5] = { 1, 2, 2, 4, 8 };
275static long SLOPE_limit[5] = { 6, 5, 4, 3, 2 };
276
277static void radeon_wait_pll_lock(struct drm_encoder *encoder, unsigned n_tests,
278				 unsigned n_wait_loops, unsigned cnt_threshold)
279{
280	struct drm_device *dev = encoder->dev;
281	struct radeon_device *rdev = dev->dev_private;
282	uint32_t save_pll_test;
283	unsigned int i, j;
284
285	WREG32(RADEON_TEST_DEBUG_MUX, (RREG32(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100);
286	save_pll_test = RREG32_PLL(RADEON_PLL_TEST_CNTL);
287	WREG32_PLL(RADEON_PLL_TEST_CNTL, save_pll_test & ~RADEON_PLL_MASK_READ_B);
288
289	WREG8(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_TEST_CNTL);
290	for (i = 0; i < n_tests; i++) {
291		WREG8(RADEON_CLOCK_CNTL_DATA + 3, 0);
292		for (j = 0; j < n_wait_loops; j++)
293			if (RREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cnt_threshold)
294				break;
295	}
296	WREG32_PLL(RADEON_PLL_TEST_CNTL, save_pll_test);
297	WREG32(RADEON_TEST_DEBUG_MUX, RREG32(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff);
298}
299
300
301static void radeon_legacy_tv_write_fifo(struct radeon_encoder *radeon_encoder,
302					uint16_t addr, uint32_t value)
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_WRITE_DATA, value);
310
311	WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr);
312	WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_WT);
313
314	do {
315		tmp = RREG32(RADEON_TV_HOST_RD_WT_CNTL);
316		if ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0)
317			break;
318		i++;
319	} while (i < 10000);
320	WREG32(RADEON_TV_HOST_RD_WT_CNTL, 0);
321}
322
323#if 0 /* included for completeness */
324static uint32_t radeon_legacy_tv_read_fifo(struct radeon_encoder *radeon_encoder, uint16_t addr)
325{
326	struct drm_device *dev = radeon_encoder->base.dev;
327	struct radeon_device *rdev = dev->dev_private;
328	uint32_t tmp;
329	int i = 0;
330
331	WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr);
332	WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD);
333
334	do {
335		tmp = RREG32(RADEON_TV_HOST_RD_WT_CNTL);
336		if ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0)
337			break;
338		i++;
339	} while (i < 10000);
340	WREG32(RADEON_TV_HOST_RD_WT_CNTL, 0);
341	return RREG32(RADEON_TV_HOST_READ_DATA);
342}
343#endif
344
345static uint16_t radeon_get_htiming_tables_addr(uint32_t tv_uv_adr)
346{
347	uint16_t h_table;
348
349	switch ((tv_uv_adr & RADEON_HCODE_TABLE_SEL_MASK) >> RADEON_HCODE_TABLE_SEL_SHIFT) {
350	case 0:
351		h_table = RADEON_TV_MAX_FIFO_ADDR_INTERNAL;
352		break;
353	case 1:
354		h_table = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2;
355		break;
356	case 2:
357		h_table = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2;
358		break;
359	default:
360		h_table = 0;
361		break;
362	}
363	return h_table;
364}
365
366static uint16_t radeon_get_vtiming_tables_addr(uint32_t tv_uv_adr)
367{
368	uint16_t v_table;
369
370	switch ((tv_uv_adr & RADEON_VCODE_TABLE_SEL_MASK) >> RADEON_VCODE_TABLE_SEL_SHIFT) {
371	case 0:
372		v_table = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1;
373		break;
374	case 1:
375		v_table = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1;
376		break;
377	case 2:
378		v_table = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1;
379		break;
380	default:
381		v_table = 0;
382		break;
383	}
384	return v_table;
385}
386
387static void radeon_restore_tv_timing_tables(struct radeon_encoder *radeon_encoder)
388{
389	struct drm_device *dev = radeon_encoder->base.dev;
390	struct radeon_device *rdev = dev->dev_private;
391	struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
392	uint16_t h_table, v_table;
393	uint32_t tmp;
394	int i;
395
396	WREG32(RADEON_TV_UV_ADR, tv_dac->tv.tv_uv_adr);
397	h_table = radeon_get_htiming_tables_addr(tv_dac->tv.tv_uv_adr);
398	v_table = radeon_get_vtiming_tables_addr(tv_dac->tv.tv_uv_adr);
399
400	for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, h_table--) {
401		tmp = ((uint32_t)tv_dac->tv.h_code_timing[i] << 14) | ((uint32_t)tv_dac->tv.h_code_timing[i+1]);
402		radeon_legacy_tv_write_fifo(radeon_encoder, h_table, tmp);
403		if (tv_dac->tv.h_code_timing[i] == 0 || tv_dac->tv.h_code_timing[i + 1] == 0)
404			break;
405	}
406	for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, v_table++) {
407		tmp = ((uint32_t)tv_dac->tv.v_code_timing[i+1] << 14) | ((uint32_t)tv_dac->tv.v_code_timing[i]);
408		radeon_legacy_tv_write_fifo(radeon_encoder, v_table, tmp);
409		if (tv_dac->tv.v_code_timing[i] == 0 || tv_dac->tv.v_code_timing[i + 1] == 0)
410			break;
411	}
412}
413
414static void radeon_legacy_write_tv_restarts(struct radeon_encoder *radeon_encoder)
415{
416	struct drm_device *dev = radeon_encoder->base.dev;
417	struct radeon_device *rdev = dev->dev_private;
418	struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
419	WREG32(RADEON_TV_FRESTART, tv_dac->tv.frestart);
420	WREG32(RADEON_TV_HRESTART, tv_dac->tv.hrestart);
421	WREG32(RADEON_TV_VRESTART, tv_dac->tv.vrestart);
422}
423
424static bool radeon_legacy_tv_init_restarts(struct drm_encoder *encoder)
425{
426	struct drm_device *dev = encoder->dev;
427	struct radeon_device *rdev = dev->dev_private;
428	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
429	struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
430	struct radeon_crtc *radeon_crtc;
431	int restart;
432	unsigned int h_total, v_total, f_total;
433	int v_offset, h_offset;
434	u16 p1, p2, h_inc;
435	bool h_changed;
436	const struct radeon_tv_mode_constants *const_ptr;
437	struct radeon_pll *pll;
438
439	radeon_crtc = to_radeon_crtc(radeon_encoder->base.crtc);
440	if (radeon_crtc->crtc_id == 1)
441		pll = &rdev->clock.p2pll;
442	else
443		pll = &rdev->clock.p1pll;
444
445	const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);
446	if (!const_ptr)
447		return false;
448
449	h_total = const_ptr->hor_total;
450	v_total = const_ptr->ver_total;
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	    tv_dac->tv_std == TV_STD_PAL_60)
456		f_total = NTSC_TV_VFTOTAL + 1;
457	else
458		f_total = PAL_TV_VFTOTAL + 1;
459
460	/* adjust positions 1&2 in hor. cod timing table */
461	h_offset = tv_dac->h_pos * H_POS_UNIT;
462
463	if (tv_dac->tv_std == TV_STD_NTSC ||
464	    tv_dac->tv_std == TV_STD_NTSC_J ||
465	    tv_dac->tv_std == TV_STD_PAL_M) {
466		h_offset -= 50;
467		p1 = hor_timing_NTSC[H_TABLE_POS1];
468		p2 = hor_timing_NTSC[H_TABLE_POS2];
469	} else {
470		p1 = hor_timing_PAL[H_TABLE_POS1];
471		p2 = hor_timing_PAL[H_TABLE_POS2];
472	}
473
474	p1 = (u16)((int)p1 + h_offset);
475	p2 = (u16)((int)p2 - h_offset);
476
477	h_changed = (p1 != tv_dac->tv.h_code_timing[H_TABLE_POS1] ||
478		     p2 != tv_dac->tv.h_code_timing[H_TABLE_POS2]);
479
480	tv_dac->tv.h_code_timing[H_TABLE_POS1] = p1;
481	tv_dac->tv.h_code_timing[H_TABLE_POS2] = p2;
482
483	/* Convert hOffset from n. of TV clock periods to n. of CRTC clock periods (CRTC pixels) */
484	h_offset = (h_offset * (int)(const_ptr->pix_to_tv)) / 1000;
485
486	/* adjust restart */
487	restart = const_ptr->def_restart;
488
489	/*
490	 * convert v_pos TV lines to n. of CRTC pixels
491	 */
492	if (tv_dac->tv_std == TV_STD_NTSC ||
493	    tv_dac->tv_std == TV_STD_NTSC_J ||
494	    tv_dac->tv_std == TV_STD_PAL_M ||
495	    tv_dac->tv_std == TV_STD_PAL_60)
496		v_offset = ((int)(v_total * h_total) * 2 * tv_dac->v_pos) / (int)(NTSC_TV_LINES_PER_FRAME);
497	else
498		v_offset = ((int)(v_total * h_total) * 2 * tv_dac->v_pos) / (int)(PAL_TV_LINES_PER_FRAME);
499
500	restart -= v_offset + h_offset;
501
502	DRM_DEBUG_KMS("compute_restarts: def = %u h = %d v = %d, p1 = %04x, p2 = %04x, restart = %d\n",
503		  const_ptr->def_restart, tv_dac->h_pos, tv_dac->v_pos, p1, p2, restart);
504
505	tv_dac->tv.hrestart = restart % h_total;
506	restart /= h_total;
507	tv_dac->tv.vrestart = restart % v_total;
508	restart /= v_total;
509	tv_dac->tv.frestart = restart % f_total;
510
511	DRM_DEBUG_KMS("compute_restart: F/H/V=%u,%u,%u\n",
512		  (unsigned)tv_dac->tv.frestart,
513		  (unsigned)tv_dac->tv.vrestart,
514		  (unsigned)tv_dac->tv.hrestart);
515
516	/* compute h_inc from hsize */
517	if (tv_dac->tv_std == TV_STD_NTSC ||
518	    tv_dac->tv_std == TV_STD_NTSC_J ||
519	    tv_dac->tv_std == TV_STD_PAL_M)
520		h_inc = (u16)((int)(const_ptr->hor_resolution * 4096 * NTSC_TV_CLOCK_T) /
521			      (tv_dac->h_size * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE)));
522	else
523		h_inc = (u16)((int)(const_ptr->hor_resolution * 4096 * PAL_TV_CLOCK_T) /
524			      (tv_dac->h_size * (int)(PAL_TV_H_SIZE_UNIT) + (int)(PAL_TV_ZERO_H_SIZE)));
525
526	tv_dac->tv.timing_cntl = (tv_dac->tv.timing_cntl & ~RADEON_H_INC_MASK) |
527		((u32)h_inc << RADEON_H_INC_SHIFT);
528
529	DRM_DEBUG_KMS("compute_restart: h_size = %d h_inc = %d\n", tv_dac->h_size, h_inc);
530
531	return h_changed;
532}
533
534void radeon_legacy_tv_mode_set(struct drm_encoder *encoder,
535			       struct drm_display_mode *mode,
536			       struct drm_display_mode *adjusted_mode)
537{
538	struct drm_device *dev = encoder->dev;
539	struct radeon_device *rdev = dev->dev_private;
540	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
541	struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
542	const struct radeon_tv_mode_constants *const_ptr;
543	struct radeon_crtc *radeon_crtc;
544	int i;
545	uint16_t pll_ref_freq;
546	uint32_t vert_space, flicker_removal, tmp;
547	uint32_t tv_master_cntl, tv_rgb_cntl, tv_dac_cntl;
548	uint32_t tv_modulator_cntl1, tv_modulator_cntl2;
549	uint32_t tv_vscaler_cntl1, tv_vscaler_cntl2;
550	uint32_t tv_pll_cntl, tv_pll_cntl1, tv_ftotal;
551	uint32_t tv_y_fall_cntl, tv_y_rise_cntl, tv_y_saw_tooth_cntl;
552	uint32_t m, n, p;
553	const uint16_t *hor_timing;
554	const uint16_t *vert_timing;
555
556	const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, &pll_ref_freq);
557	if (!const_ptr)
558		return;
559
560	radeon_crtc = to_radeon_crtc(encoder->crtc);
561
562	tv_master_cntl = (RADEON_VIN_ASYNC_RST |
563			  RADEON_CRT_FIFO_CE_EN |
564			  RADEON_TV_FIFO_CE_EN |
565			  RADEON_TV_ON);
566
567	if (!ASIC_IS_R300(rdev))
568		tv_master_cntl |= RADEON_TVCLK_ALWAYS_ONb;
569
570	if (tv_dac->tv_std == TV_STD_NTSC ||
571	    tv_dac->tv_std == TV_STD_NTSC_J)
572		tv_master_cntl |= RADEON_RESTART_PHASE_FIX;
573
574	tv_modulator_cntl1 = (RADEON_SLEW_RATE_LIMIT |
575			      RADEON_SYNC_TIP_LEVEL |
576			      RADEON_YFLT_EN |
577			      RADEON_UVFLT_EN |
578			      (6 << RADEON_CY_FILT_BLEND_SHIFT));
579
580	if (tv_dac->tv_std == TV_STD_NTSC ||
581	    tv_dac->tv_std == TV_STD_NTSC_J) {
582		tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT) |
583			(0x3b << RADEON_BLANK_LEVEL_SHIFT);
584		tv_modulator_cntl2 = (-111 & RADEON_TV_U_BURST_LEVEL_MASK) |
585			((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
586	} else if (tv_dac->tv_std == TV_STD_SCART_PAL) {
587		tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN;
588		tv_modulator_cntl2 = (0 & RADEON_TV_U_BURST_LEVEL_MASK) |
589			((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
590	} else {
591		tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN |
592			(0x3b << RADEON_SET_UP_LEVEL_SHIFT) |
593			(0x3b << RADEON_BLANK_LEVEL_SHIFT);
594		tv_modulator_cntl2 = (-78 & RADEON_TV_U_BURST_LEVEL_MASK) |
595			((62 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
596	}
597
598
599	tv_rgb_cntl = (RADEON_RGB_DITHER_EN
600		       | RADEON_TVOUT_SCALE_EN
601		       | (0x0b << RADEON_UVRAM_READ_MARGIN_SHIFT)
602		       | (0x07 << RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT)
603		       | RADEON_RGB_ATTEN_SEL(0x3)
604		       | RADEON_RGB_ATTEN_VAL(0xc));
605
606	if (radeon_crtc->crtc_id == 1)
607		tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC2;
608	else {
609		if (radeon_crtc->rmx_type != RMX_OFF)
610			tv_rgb_cntl |= RADEON_RGB_SRC_SEL_RMX;
611		else
612			tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC1;
613	}
614
615	if (tv_dac->tv_std == TV_STD_NTSC ||
616	    tv_dac->tv_std == TV_STD_NTSC_J ||
617	    tv_dac->tv_std == TV_STD_PAL_M ||
618	    tv_dac->tv_std == TV_STD_PAL_60)
619		vert_space = const_ptr->ver_total * 2 * 10000 / NTSC_TV_LINES_PER_FRAME;
620	else
621		vert_space = const_ptr->ver_total * 2 * 10000 / PAL_TV_LINES_PER_FRAME;
622
623	tmp = RREG32(RADEON_TV_VSCALER_CNTL1);
624	tmp &= 0xe3ff0000;
625	tmp |= (vert_space * (1 << FRAC_BITS) / 10000);
626	tv_vscaler_cntl1 = tmp;
627
628	if (pll_ref_freq == 2700)
629		tv_vscaler_cntl1 |= RADEON_RESTART_FIELD;
630
631	if (const_ptr->hor_resolution == 1024)
632		tv_vscaler_cntl1 |= (4 << RADEON_Y_DEL_W_SIG_SHIFT);
633	else
634		tv_vscaler_cntl1 |= (2 << RADEON_Y_DEL_W_SIG_SHIFT);
635
636	/* scale up for int divide */
637	tmp = const_ptr->ver_total * 2 * 1000;
638	if (tv_dac->tv_std == TV_STD_NTSC ||
639	    tv_dac->tv_std == TV_STD_NTSC_J ||
640	    tv_dac->tv_std == TV_STD_PAL_M ||
641	    tv_dac->tv_std == TV_STD_PAL_60) {
642		tmp /= NTSC_TV_LINES_PER_FRAME;
643	} else {
644		tmp /= PAL_TV_LINES_PER_FRAME;
645	}
646	flicker_removal = (tmp + 500) / 1000;
647
648	if (flicker_removal < 3)
649		flicker_removal = 3;
650	for (i = 0; i < DRM_ARRAY_SIZE(SLOPE_limit); ++i) {
651		if (flicker_removal == SLOPE_limit[i])
652			break;
653	}
654
655	tv_y_saw_tooth_cntl = (vert_space * SLOPE_value[i] * (1 << (FRAC_BITS - 1)) +
656				5001) / 10000 / 8 | ((SLOPE_value[i] *
657				(1 << (FRAC_BITS - 1)) / 8) << 16);
658	tv_y_fall_cntl =
659		(YCOEF_EN_value[i] << 17) | ((YCOEF_value[i] * (1 << 8) / 8) << 24) |
660		RADEON_Y_FALL_PING_PONG | (272 * SLOPE_value[i] / 8) * (1 << (FRAC_BITS - 1)) /
661		1024;
662	tv_y_rise_cntl = RADEON_Y_RISE_PING_PONG|
663		(flicker_removal * 1024 - 272) * SLOPE_value[i] / 8 * (1 << (FRAC_BITS - 1)) / 1024;
664
665	tv_vscaler_cntl2 = RREG32(RADEON_TV_VSCALER_CNTL2) & 0x00fffff0;
666	tv_vscaler_cntl2 |= (0x10 << 24) |
667		RADEON_DITHER_MODE |
668		RADEON_Y_OUTPUT_DITHER_EN |
669		RADEON_UV_OUTPUT_DITHER_EN |
670		RADEON_UV_TO_BUF_DITHER_EN;
671
672	tmp = (tv_vscaler_cntl1 >> RADEON_UV_INC_SHIFT) & RADEON_UV_INC_MASK;
673	tmp = ((16384 * 256 * 10) / tmp + 5) / 10;
674	tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000;
675	tv_dac->tv.timing_cntl = tmp;
676
677	if (tv_dac->tv_std == TV_STD_NTSC ||
678	    tv_dac->tv_std == TV_STD_NTSC_J ||
679	    tv_dac->tv_std == TV_STD_PAL_M ||
680	    tv_dac->tv_std == TV_STD_PAL_60)
681		tv_dac_cntl = tv_dac->ntsc_tvdac_adj;
682	else
683		tv_dac_cntl = tv_dac->pal_tvdac_adj;
684
685	tv_dac_cntl |= RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD;
686
687	if (tv_dac->tv_std == TV_STD_NTSC ||
688	    tv_dac->tv_std == TV_STD_NTSC_J)
689		tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
690	else
691		tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
692
693	if (tv_dac->tv_std == TV_STD_NTSC ||
694	    tv_dac->tv_std == TV_STD_NTSC_J) {
695		if (pll_ref_freq == 2700) {
696			m = NTSC_TV_PLL_M_27;
697			n = NTSC_TV_PLL_N_27;
698			p = NTSC_TV_PLL_P_27;
699		} else {
700			m = NTSC_TV_PLL_M_14;
701			n = NTSC_TV_PLL_N_14;
702			p = NTSC_TV_PLL_P_14;
703		}
704	} else {
705		if (pll_ref_freq == 2700) {
706			m = PAL_TV_PLL_M_27;
707			n = PAL_TV_PLL_N_27;
708			p = PAL_TV_PLL_P_27;
709		} else {
710			m = PAL_TV_PLL_M_14;
711			n = PAL_TV_PLL_N_14;
712			p = PAL_TV_PLL_P_14;
713		}
714	}
715
716	tv_pll_cntl = (m & RADEON_TV_M0LO_MASK) |
717		(((m >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) |
718		((n & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) |
719		(((n >> 9) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) |
720		((p & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT);
721
722	tv_pll_cntl1 = (((4 & RADEON_TVPCP_MASK) << RADEON_TVPCP_SHIFT) |
723			((4 & RADEON_TVPVG_MASK) << RADEON_TVPVG_SHIFT) |
724			((1 & RADEON_TVPDC_MASK) << RADEON_TVPDC_SHIFT) |
725			RADEON_TVCLK_SRC_SEL_TVPLL |
726			RADEON_TVPLL_TEST_DIS);
727
728	tv_dac->tv.tv_uv_adr = 0xc8;
729
730	if (tv_dac->tv_std == TV_STD_NTSC ||
731	    tv_dac->tv_std == TV_STD_NTSC_J ||
732	    tv_dac->tv_std == TV_STD_PAL_M ||
733	    tv_dac->tv_std == TV_STD_PAL_60) {
734		tv_ftotal = NTSC_TV_VFTOTAL;
735		hor_timing = hor_timing_NTSC;
736		vert_timing = vert_timing_NTSC;
737	} else {
738		hor_timing = hor_timing_PAL;
739		vert_timing = vert_timing_PAL;
740		tv_ftotal = PAL_TV_VFTOTAL;
741	}
742
743	for (i = 0; i < MAX_H_CODE_TIMING_LEN; i++) {
744		if ((tv_dac->tv.h_code_timing[i] = hor_timing[i]) == 0)
745			break;
746	}
747
748	for (i = 0; i < MAX_V_CODE_TIMING_LEN; i++) {
749		if ((tv_dac->tv.v_code_timing[i] = vert_timing[i]) == 0)
750			break;
751	}
752
753	radeon_legacy_tv_init_restarts(encoder);
754
755	/* play with DAC_CNTL */
756	/* play with GPIOPAD_A */
757	/* DISP_OUTPUT_CNTL */
758	/* use reference freq */
759
760	/* program the TV registers */
761	WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST |
762				       RADEON_CRT_ASYNC_RST | RADEON_TV_FIFO_ASYNC_RST));
763
764	tmp = RREG32(RADEON_TV_DAC_CNTL);
765	tmp &= ~RADEON_TV_DAC_NBLANK;
766	tmp |= RADEON_TV_DAC_BGSLEEP |
767		RADEON_TV_DAC_RDACPD |
768		RADEON_TV_DAC_GDACPD |
769		RADEON_TV_DAC_BDACPD;
770	WREG32(RADEON_TV_DAC_CNTL, tmp);
771
772	/* TV PLL */
773	WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVCLK_SRC_SEL_TVPLL);
774	WREG32_PLL(RADEON_TV_PLL_CNTL, tv_pll_cntl);
775	WREG32_PLL_P(RADEON_TV_PLL_CNTL1, RADEON_TVPLL_RESET, ~RADEON_TVPLL_RESET);
776
777	radeon_wait_pll_lock(encoder, 200, 800, 135);
778
779	WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET);
780
781	radeon_wait_pll_lock(encoder, 300, 160, 27);
782	radeon_wait_pll_lock(encoder, 200, 800, 135);
783
784	WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~0xf);
785	WREG32_PLL_P(RADEON_TV_PLL_CNTL1, RADEON_TVCLK_SRC_SEL_TVPLL, ~RADEON_TVCLK_SRC_SEL_TVPLL);
786
787	WREG32_PLL_P(RADEON_TV_PLL_CNTL1, (1 << RADEON_TVPDC_SHIFT), ~RADEON_TVPDC_MASK);
788	WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_SLEEP);
789
790	/* TV HV */
791	WREG32(RADEON_TV_RGB_CNTL, tv_rgb_cntl);
792	WREG32(RADEON_TV_HTOTAL, const_ptr->hor_total - 1);
793	WREG32(RADEON_TV_HDISP, const_ptr->hor_resolution - 1);
794	WREG32(RADEON_TV_HSTART, const_ptr->hor_start);
795
796	WREG32(RADEON_TV_VTOTAL, const_ptr->ver_total - 1);
797	WREG32(RADEON_TV_VDISP, const_ptr->ver_resolution - 1);
798	WREG32(RADEON_TV_FTOTAL, tv_ftotal);
799	WREG32(RADEON_TV_VSCALER_CNTL1, tv_vscaler_cntl1);
800	WREG32(RADEON_TV_VSCALER_CNTL2, tv_vscaler_cntl2);
801
802	WREG32(RADEON_TV_Y_FALL_CNTL, tv_y_fall_cntl);
803	WREG32(RADEON_TV_Y_RISE_CNTL, tv_y_rise_cntl);
804	WREG32(RADEON_TV_Y_SAW_TOOTH_CNTL, tv_y_saw_tooth_cntl);
805
806	WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST |
807				       RADEON_CRT_ASYNC_RST));
808
809	/* TV restarts */
810	radeon_legacy_write_tv_restarts(radeon_encoder);
811
812	/* tv timings */
813	radeon_restore_tv_timing_tables(radeon_encoder);
814
815	WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST));
816
817	/* tv std */
818	WREG32(RADEON_TV_SYNC_CNTL, (RADEON_SYNC_PUB | RADEON_TV_SYNC_IO_DRIVE));
819	WREG32(RADEON_TV_TIMING_CNTL, tv_dac->tv.timing_cntl);
820	WREG32(RADEON_TV_MODULATOR_CNTL1, tv_modulator_cntl1);
821	WREG32(RADEON_TV_MODULATOR_CNTL2, tv_modulator_cntl2);
822	WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, (RADEON_Y_RED_EN |
823					    RADEON_C_GRN_EN |
824					    RADEON_CMP_BLU_EN |
825					    RADEON_DAC_DITHER_EN));
826
827	WREG32(RADEON_TV_CRC_CNTL, 0);
828
829	WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl);
830
831	WREG32(RADEON_TV_GAIN_LIMIT_SETTINGS, ((0x17f << RADEON_UV_GAIN_LIMIT_SHIFT) |
832					       (0x5ff << RADEON_Y_GAIN_LIMIT_SHIFT)));
833	WREG32(RADEON_TV_LINEAR_GAIN_SETTINGS, ((0x100 << RADEON_UV_GAIN_SHIFT) |
834						(0x100 << RADEON_Y_GAIN_SHIFT)));
835
836	WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
837
838}
839
840void radeon_legacy_tv_adjust_crtc_reg(struct drm_encoder *encoder,
841				      uint32_t *h_total_disp, uint32_t *h_sync_strt_wid,
842				      uint32_t *v_total_disp, uint32_t *v_sync_strt_wid)
843{
844	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
845	const struct radeon_tv_mode_constants *const_ptr;
846	uint32_t tmp;
847
848	const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);
849	if (!const_ptr)
850		return;
851
852	*h_total_disp = (((const_ptr->hor_resolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) |
853		(((const_ptr->hor_total / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT);
854
855	tmp = *h_sync_strt_wid;
856	tmp &= ~(RADEON_CRTC_H_SYNC_STRT_PIX | RADEON_CRTC_H_SYNC_STRT_CHAR);
857	tmp |= (((const_ptr->hor_syncstart / 8) - 1) << RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) |
858		(const_ptr->hor_syncstart & 7);
859	*h_sync_strt_wid = tmp;
860
861	*v_total_disp = ((const_ptr->ver_resolution - 1) << RADEON_CRTC_V_DISP_SHIFT) |
862		((const_ptr->ver_total - 1) << RADEON_CRTC_V_TOTAL_SHIFT);
863
864	tmp = *v_sync_strt_wid;
865	tmp &= ~RADEON_CRTC_V_SYNC_STRT;
866	tmp |= ((const_ptr->ver_syncstart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT);
867	*v_sync_strt_wid = tmp;
868}
869
870static int get_post_div(int value)
871{
872	int post_div;
873	switch (value) {
874	case 1: post_div = 0; break;
875	case 2: post_div = 1; break;
876	case 3: post_div = 4; break;
877	case 4: post_div = 2; break;
878	case 6: post_div = 6; break;
879	case 8: post_div = 3; break;
880	case 12: post_div = 7; break;
881	case 16:
882	default: post_div = 5; break;
883	}
884	return post_div;
885}
886
887void radeon_legacy_tv_adjust_pll1(struct drm_encoder *encoder,
888				  uint32_t *htotal_cntl, uint32_t *ppll_ref_div,
889				  uint32_t *ppll_div_3, uint32_t *pixclks_cntl)
890{
891	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
892	const struct radeon_tv_mode_constants *const_ptr;
893
894	const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);
895	if (!const_ptr)
896		return;
897
898	*htotal_cntl = (const_ptr->hor_total & 0x7) | RADEON_HTOT_CNTL_VGA_EN;
899
900	*ppll_ref_div = const_ptr->crtcPLL_M;
901
902	*ppll_div_3 = (const_ptr->crtcPLL_N & 0x7ff) | (get_post_div(const_ptr->crtcPLL_post_div) << 16);
903	*pixclks_cntl &= ~(RADEON_PIX2CLK_SRC_SEL_MASK | RADEON_PIXCLK_TV_SRC_SEL);
904	*pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK;
905}
906
907void radeon_legacy_tv_adjust_pll2(struct drm_encoder *encoder,
908				  uint32_t *htotal2_cntl, uint32_t *p2pll_ref_div,
909				  uint32_t *p2pll_div_0, uint32_t *pixclks_cntl)
910{
911	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
912	const struct radeon_tv_mode_constants *const_ptr;
913
914	const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);
915	if (!const_ptr)
916		return;
917
918	*htotal2_cntl = (const_ptr->hor_total & 0x7);
919
920	*p2pll_ref_div = const_ptr->crtcPLL_M;
921
922	*p2pll_div_0 = (const_ptr->crtcPLL_N & 0x7ff) | (get_post_div(const_ptr->crtcPLL_post_div) << 16);
923	*pixclks_cntl &= ~RADEON_PIX2CLK_SRC_SEL_MASK;
924	*pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK | RADEON_PIXCLK_TV_SRC_SEL;
925}
926
927