Subversion Repositories Kolibri OS

Rev

Rev 3764 | Rev 5271 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3764 Rev 5078
Line 31... Line 31...
31
#include 
31
#include 
Line 32... Line 32...
32
 
32
 
33
#include 
33
#include 
Line -... Line 34...
-
 
34
#include 
-
 
35
 
-
 
36
/* Greatest common divisor */
-
 
37
unsigned long gcd(unsigned long a, unsigned long b)
-
 
38
{
-
 
39
        unsigned long r;
-
 
40
 
-
 
41
        if (a < b)
-
 
42
                swap(a, b);
-
 
43
 
-
 
44
        if (!b)
-
 
45
                return a;
-
 
46
        while ((r = a % b) != 0) {
-
 
47
                a = b;
-
 
48
                b = r;
-
 
49
        }
-
 
50
        return b;
34
#include 
51
}
35
 
52
 
36
static void avivo_crtc_load_lut(struct drm_crtc *crtc)
53
static void avivo_crtc_load_lut(struct drm_crtc *crtc)
37
{
54
{
38
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
55
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
Line 61... Line 78...
61
			     (radeon_crtc->lut_r[i] << 20) |
78
			     (radeon_crtc->lut_r[i] << 20) |
62
			     (radeon_crtc->lut_g[i] << 10) |
79
			     (radeon_crtc->lut_g[i] << 10) |
63
			     (radeon_crtc->lut_b[i] << 0));
80
			     (radeon_crtc->lut_b[i] << 0));
64
	}
81
	}
Line -... Line 82...
-
 
82
 
65
 
83
	/* Only change bit 0 of LUT_SEL, other bits are set elsewhere */
66
	WREG32(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id);
84
	WREG32_P(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id, ~1);
Line 67... Line 85...
67
}
85
}
68
 
86
 
69
static void dce4_crtc_load_lut(struct drm_crtc *crtc)
87
static void dce4_crtc_load_lut(struct drm_crtc *crtc)
Line 151... Line 169...
151
	WREG32(NI_OUTPUT_CSC_CONTROL + radeon_crtc->crtc_offset,
169
	WREG32(NI_OUTPUT_CSC_CONTROL + radeon_crtc->crtc_offset,
152
	       (NI_OUTPUT_CSC_GRPH_MODE(NI_OUTPUT_CSC_BYPASS) |
170
	       (NI_OUTPUT_CSC_GRPH_MODE(NI_OUTPUT_CSC_BYPASS) |
153
		NI_OUTPUT_CSC_OVL_MODE(NI_OUTPUT_CSC_BYPASS)));
171
		NI_OUTPUT_CSC_OVL_MODE(NI_OUTPUT_CSC_BYPASS)));
154
	/* XXX match this to the depth of the crtc fmt block, move to modeset? */
172
	/* XXX match this to the depth of the crtc fmt block, move to modeset? */
155
	WREG32(0x6940 + radeon_crtc->crtc_offset, 0);
173
	WREG32(0x6940 + radeon_crtc->crtc_offset, 0);
-
 
174
	if (ASIC_IS_DCE8(rdev)) {
-
 
175
		/* XXX this only needs to be programmed once per crtc at startup,
-
 
176
		 * not sure where the best place for it is
-
 
177
		 */
-
 
178
		WREG32(CIK_ALPHA_CONTROL + radeon_crtc->crtc_offset,
-
 
179
		       CIK_CURSOR_ALPHA_BLND_ENA);
156
 
180
	}
157
}
181
}
Line 158... Line 182...
158
 
182
 
159
static void legacy_crtc_load_lut(struct drm_crtc *crtc)
183
static void legacy_crtc_load_lut(struct drm_crtc *crtc)
160
{
184
{
Line 241... Line 265...
241
 
265
 
242
	drm_crtc_cleanup(crtc);
266
	drm_crtc_cleanup(crtc);
243
	kfree(radeon_crtc);
267
	kfree(radeon_crtc);
Line -... Line 268...
-
 
268
}
-
 
269
 
-
 
270
static int
-
 
271
radeon_crtc_set_config(struct drm_mode_set *set)
-
 
272
{
-
 
273
	struct drm_device *dev;
-
 
274
	struct radeon_device *rdev;
-
 
275
	struct drm_crtc *crtc;
-
 
276
	bool active = false;
-
 
277
	int ret;
-
 
278
 
-
 
279
	if (!set || !set->crtc)
-
 
280
		return -EINVAL;
-
 
281
 
-
 
282
	dev = set->crtc->dev;
-
 
283
 
-
 
284
	ret = drm_crtc_helper_set_config(set);
-
 
285
 
-
 
286
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
-
 
287
		if (crtc->enabled)
-
 
288
			active = true;
-
 
289
 
-
 
290
//   pm_runtime_mark_last_busy(dev->dev);
-
 
291
 
-
 
292
	rdev = dev->dev_private;
-
 
293
	/* if we have active crtcs and we don't have a power ref,
-
 
294
	   take the current one */
-
 
295
	if (active && !rdev->have_disp_power_ref) {
-
 
296
		rdev->have_disp_power_ref = true;
-
 
297
		return ret;
-
 
298
	}
-
 
299
	/* if we have no active crtcs, then drop the power ref
-
 
300
	   we got before */
-
 
301
	if (!active && rdev->have_disp_power_ref) {
-
 
302
//       pm_runtime_put_autosuspend(dev->dev);
-
 
303
		rdev->have_disp_power_ref = false;
-
 
304
	}
-
 
305
 
-
 
306
	/* drop the power reference we got coming in here */
-
 
307
//   pm_runtime_put_autosuspend(dev->dev);
244
}
308
	return ret;
245
 
309
}
246
static const struct drm_crtc_funcs radeon_crtc_funcs = {
310
static const struct drm_crtc_funcs radeon_crtc_funcs = {
247
    .cursor_set = NULL,
311
    .cursor_set = NULL,
248
    .cursor_move = NULL,
312
    .cursor_move = NULL,
249
	.gamma_set = radeon_crtc_gamma_set,
313
	.gamma_set = radeon_crtc_gamma_set,
250
	.set_config = drm_crtc_helper_set_config,
314
	.set_config = radeon_crtc_set_config,
251
	.destroy = radeon_crtc_destroy,
315
	.destroy = radeon_crtc_destroy,
Line 252... Line 316...
252
	.page_flip = NULL,
316
	.page_flip = NULL,
Line 266... Line 330...
266
 
330
 
267
	drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256);
331
	drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256);
268
	radeon_crtc->crtc_id = index;
332
	radeon_crtc->crtc_id = index;
Line -... Line 333...
-
 
333
	rdev->mode_info.crtcs[index] = radeon_crtc;
-
 
334
 
-
 
335
	if (rdev->family >= CHIP_BONAIRE) {
-
 
336
		radeon_crtc->max_cursor_width = CIK_CURSOR_WIDTH;
-
 
337
		radeon_crtc->max_cursor_height = CIK_CURSOR_HEIGHT;
-
 
338
	} else {
-
 
339
		radeon_crtc->max_cursor_width = CURSOR_WIDTH;
-
 
340
		radeon_crtc->max_cursor_height = CURSOR_HEIGHT;
-
 
341
	}
-
 
342
	dev->mode_config.cursor_width = radeon_crtc->max_cursor_width;
269
	rdev->mode_info.crtcs[index] = radeon_crtc;
343
	dev->mode_config.cursor_height = radeon_crtc->max_cursor_height;
270
 
344
 
271
#if 0
345
#if 0
272
	radeon_crtc->mode_set.crtc = &radeon_crtc->base;
346
	radeon_crtc->mode_set.crtc = &radeon_crtc->base;
273
	radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1);
347
	radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1);
Line 284... Line 358...
284
		radeon_atombios_init_crtc(dev, radeon_crtc);
358
		radeon_atombios_init_crtc(dev, radeon_crtc);
285
	else
359
	else
286
		radeon_legacy_init_crtc(dev, radeon_crtc);
360
		radeon_legacy_init_crtc(dev, radeon_crtc);
287
}
361
}
Line 288... Line 362...
288
 
362
 
289
static const char *encoder_names[37] = {
363
static const char *encoder_names[38] = {
290
	"NONE",
364
	"NONE",
291
	"INTERNAL_LVDS",
365
	"INTERNAL_LVDS",
292
	"INTERNAL_TMDS1",
366
	"INTERNAL_TMDS1",
293
	"INTERNAL_TMDS2",
367
	"INTERNAL_TMDS2",
Line 321... Line 395...
321
	"INTERNAL_KLDSCP_LVTMA",
395
	"INTERNAL_KLDSCP_LVTMA",
322
	"INTERNAL_UNIPHY1",
396
	"INTERNAL_UNIPHY1",
323
	"INTERNAL_UNIPHY2",
397
	"INTERNAL_UNIPHY2",
324
	"NUTMEG",
398
	"NUTMEG",
325
	"TRAVIS",
399
	"TRAVIS",
326
	"INTERNAL_VCE"
400
	"INTERNAL_VCE",
-
 
401
	"INTERNAL_UNIPHY3",
327
};
402
};
Line 328... Line 403...
328
 
403
 
329
static const char *hpd_names[6] = {
404
static const char *hpd_names[6] = {
330
	"HPD1",
405
	"HPD1",
Line 346... Line 421...
346
 
421
 
347
	DRM_INFO("Radeon Display Connectors\n");
422
	DRM_INFO("Radeon Display Connectors\n");
348
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
423
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
349
		radeon_connector = to_radeon_connector(connector);
424
		radeon_connector = to_radeon_connector(connector);
350
		DRM_INFO("Connector %d:\n", i);
425
		DRM_INFO("Connector %d:\n", i);
351
		DRM_INFO("  %s\n", drm_get_connector_name(connector));
426
		DRM_INFO("  %s\n", connector->name);
352
		if (radeon_connector->hpd.hpd != RADEON_HPD_NONE)
427
		if (radeon_connector->hpd.hpd != RADEON_HPD_NONE)
353
			DRM_INFO("  %s\n", hpd_names[radeon_connector->hpd.hpd]);
428
			DRM_INFO("  %s\n", hpd_names[radeon_connector->hpd.hpd]);
354
		if (radeon_connector->ddc_bus) {
429
		if (radeon_connector->ddc_bus) {
355
			DRM_INFO("  DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
430
			DRM_INFO("  DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
Line 436... Line 511...
436
	}
511
	}
Line 437... Line 512...
437
 
512
 
438
	return ret;
513
	return ret;
Line -... Line 514...
-
 
514
}
-
 
515
 
-
 
516
/* avivo */
-
 
517
 
-
 
518
/**
-
 
519
 * avivo_reduce_ratio - fractional number reduction
-
 
520
 *
-
 
521
 * @nom: nominator
-
 
522
 * @den: denominator
-
 
523
 * @nom_min: minimum value for nominator
-
 
524
 * @den_min: minimum value for denominator
439
}
525
 *
-
 
526
 * Find the greatest common divisor and apply it on both nominator and
-
 
527
 * denominator, but make nominator and denominator are at least as large
-
 
528
 * as their minimum values.
-
 
529
 */
440
 
530
static void avivo_reduce_ratio(unsigned *nom, unsigned *den,
441
int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
-
 
442
{
-
 
443
	struct drm_device *dev = radeon_connector->base.dev;
531
			       unsigned nom_min, unsigned den_min)
Line 444... Line 532...
444
	struct radeon_device *rdev = dev->dev_private;
532
{
445
	int ret = 0;
533
	unsigned tmp;
-
 
534
 
446
 
535
	/* reduce the numbers to a simpler ratio */
Line 447... Line 536...
447
	/* on hw with routers, select right port */
536
	tmp = gcd(*nom, *den);
448
	if (radeon_connector->router.ddc_valid)
537
	*nom /= tmp;
449
		radeon_router_select_ddc_port(radeon_connector);
538
	*den /= tmp;
450
 
-
 
451
	if (radeon_connector_encoder_get_dp_bridge_encoder_id(&radeon_connector->base) !=
539
 
452
	    ENCODER_OBJECT_ID_NONE) {
-
 
453
		struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
-
 
454
 
-
 
455
		if (dig->dp_i2c_bus)
-
 
456
			radeon_connector->edid = drm_get_edid(&radeon_connector->base,
-
 
457
							      &dig->dp_i2c_bus->adapter);
-
 
458
	} else if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
-
 
459
		   (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) {
-
 
460
		struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
-
 
461
 
-
 
462
		if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
-
 
463
		     dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) && dig->dp_i2c_bus)
-
 
464
			radeon_connector->edid = drm_get_edid(&radeon_connector->base,
-
 
465
							      &dig->dp_i2c_bus->adapter);
540
	/* make sure nominator is large enough */
466
		else if (radeon_connector->ddc_bus && !radeon_connector->edid)
-
 
467
			radeon_connector->edid = drm_get_edid(&radeon_connector->base,
-
 
468
							      &radeon_connector->ddc_bus->adapter);
-
 
469
	} else {
541
        if (*nom < nom_min) {
Line 470... Line 542...
470
		if (radeon_connector->ddc_bus && !radeon_connector->edid)
542
		tmp = DIV_ROUND_UP(nom_min, *nom);
471
			radeon_connector->edid = drm_get_edid(&radeon_connector->base,
543
		*nom *= tmp;
472
							      &radeon_connector->ddc_bus->adapter);
-
 
473
	}
-
 
474
 
-
 
475
	if (!radeon_connector->edid) {
544
		*den *= tmp;
476
		if (rdev->is_atom_bios) {
545
	}
477
			/* some laptops provide a hardcoded edid in rom for LCDs */
-
 
478
			if (((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_LVDS) ||
546
 
479
			     (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)))
547
	/* make sure the denominator is large enough */
480
				radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev);
-
 
481
		} else
-
 
482
	/* some servers provide a hardcoded edid in rom for KVMs */
-
 
483
			radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev);
-
 
484
	}
-
 
485
	if (radeon_connector->edid) {
-
 
486
		drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid);
-
 
487
		ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid);
548
	if (*den < den_min) {
Line 488... Line 549...
488
		return ret;
549
		tmp = DIV_ROUND_UP(den_min, *den);
489
	}
550
		*nom *= tmp;
-
 
551
		*den *= tmp;
-
 
552
	}
490
	drm_mode_connector_update_edid_property(&radeon_connector->base, NULL);
553
}
491
	return 0;
554
 
-
 
555
/**
-
 
556
 * avivo_get_fb_ref_div - feedback and ref divider calculation
-
 
557
 *
-
 
558
 * @nom: nominator
-
 
559
 * @den: denominator
-
 
560
 * @post_div: post divider
492
}
561
 * @fb_div_max: feedback divider maximum
-
 
562
 * @ref_div_max: reference divider maximum
-
 
563
 * @fb_div: resulting feedback divider
493
 
564
 * @ref_div: resulting reference divider
494
/* avivo */
565
 *
495
static void avivo_get_fb_div(struct radeon_pll *pll,
566
 * Calculate feedback and reference divider for a given post divider. Makes
-
 
567
 * sure we stay within the limits.
496
			     u32 target_clock,
568
 */
Line 497... Line 569...
497
			     u32 post_div,
569
static void avivo_get_fb_ref_div(unsigned nom, unsigned den, unsigned post_div,
498
			     u32 ref_div,
570
				 unsigned fb_div_max, unsigned ref_div_max,
499
			     u32 *fb_div,
571
				 unsigned *fb_div, unsigned *ref_div)
Line 500... Line 572...
500
			     u32 *frac_fb_div)
572
{
501
{
573
	/* limit reference * post divider to a maximum */
502
	u32 tmp = post_div * ref_div;
574
	ref_div_max = max(min(100 / post_div, ref_div_max), 1u);
503
 
575
 
-
 
576
	/* get matching reference and feedback divider */
504
	tmp *= target_clock;
577
	*ref_div = min(max(DIV_ROUND_CLOSEST(den, post_div), 1u), ref_div_max);
Line -... Line 578...
-
 
578
	*fb_div = DIV_ROUND_CLOSEST(nom * *ref_div * post_div, den);
-
 
579
 
-
 
580
	/* limit fb divider to its maximum */
-
 
581
        if (*fb_div > fb_div_max) {
-
 
582
		*ref_div = DIV_ROUND_CLOSEST(*ref_div * fb_div_max, *fb_div);
-
 
583
		*fb_div = fb_div_max;
-
 
584
	}
-
 
585
}
-
 
586
 
-
 
587
/**
-
 
588
 * radeon_compute_pll_avivo - compute PLL paramaters
-
 
589
 *
-
 
590
 * @pll: information about the PLL
505
	*fb_div = tmp / pll->reference_freq;
591
 * @dot_clock_p: resulting pixel clock
-
 
592
 * fb_div_p: resulting feedback divider
506
	*frac_fb_div = tmp % pll->reference_freq;
593
 * frac_fb_div_p: fractional part of the feedback divider
-
 
594
 * ref_div_p: resulting reference divider
-
 
595
 * post_div_p: resulting reference divider
-
 
596
 *
-
 
597
 * Try to calculate the PLL parameters to generate the given frequency:
507
 
598
 * dot_clock = (ref_freq * feedback_div) / (ref_div * post_div)
-
 
599
 */
508
        if (*fb_div > pll->max_feedback_div)
600
void radeon_compute_pll_avivo(struct radeon_pll *pll,
Line 509... Line 601...
509
		*fb_div = pll->max_feedback_div;
601
			      u32 freq,
-
 
602
			      u32 *dot_clock_p,
-
 
603
			      u32 *fb_div_p,
-
 
604
			      u32 *frac_fb_div_p,
-
 
605
			      u32 *ref_div_p,
-
 
606
			      u32 *post_div_p)
-
 
607
{
510
        else if (*fb_div < pll->min_feedback_div)
608
	unsigned target_clock = pll->flags & RADEON_PLL_USE_FRAC_FB_DIV ?
-
 
609
		freq : freq / 10;
Line 511... Line 610...
511
                *fb_div = pll->min_feedback_div;
610
 
-
 
611
	unsigned fb_div_min, fb_div_max, fb_div;
-
 
612
	unsigned post_div_min, post_div_max, post_div;
-
 
613
	unsigned ref_div_min, ref_div_max, ref_div;
-
 
614
	unsigned post_div_best, diff_best;
-
 
615
	unsigned nom, den;
512
}
616
 
513
 
617
	/* determine allowed feedback divider range */
514
static u32 avivo_get_post_div(struct radeon_pll *pll,
618
	fb_div_min = pll->min_feedback_div;
515
			      u32 target_clock)
619
	fb_div_max = pll->max_feedback_div;
516
{
620
 
-
 
621
	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
517
	u32 vco, post_div, tmp;
622
		fb_div_min *= 10;
518
 
623
		fb_div_max *= 10;
519
	if (pll->flags & RADEON_PLL_USE_POST_DIV)
624
	}
520
		return pll->post_div;
625
 
521
 
-
 
Line -... Line 626...
-
 
626
	/* determine allowed ref divider range */
-
 
627
	if (pll->flags & RADEON_PLL_USE_REF_DIV)
-
 
628
		ref_div_min = pll->reference_div;
522
	if (pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP) {
629
	else
-
 
630
		ref_div_min = pll->min_ref_div;
523
		if (pll->flags & RADEON_PLL_IS_LCD)
631
 
Line 524... Line 632...
524
			vco = pll->lcd_pll_out_min;
632
	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV &&
525
		else
633
	    pll->flags & RADEON_PLL_USE_REF_DIV)
526
			vco = pll->pll_out_min;
634
		ref_div_max = pll->reference_div;
527
	} else {
635
		else
-
 
636
		ref_div_max = pll->max_ref_div;
-
 
637
 
-
 
638
	/* determine allowed post divider range */
-
 
639
	if (pll->flags & RADEON_PLL_USE_POST_DIV) {
-
 
640
		post_div_min = pll->post_div;
528
		if (pll->flags & RADEON_PLL_IS_LCD)
641
		post_div_max = pll->post_div;
529
			vco = pll->lcd_pll_out_max;
642
	} else {
530
		else
643
		unsigned vco_min, vco_max;
Line -... Line 644...
-
 
644
 
531
			vco = pll->pll_out_max;
645
		if (pll->flags & RADEON_PLL_IS_LCD) {
532
	}
646
			vco_min = pll->lcd_pll_out_min;
533
 
647
			vco_max = pll->lcd_pll_out_max;
534
	post_div = vco / target_clock;
648
		} else {
Line -... Line 649...
-
 
649
			vco_min = pll->pll_out_min;
-
 
650
			vco_max = pll->pll_out_max;
535
	tmp = vco % target_clock;
651
		}
-
 
652
 
-
 
653
		if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
536
 
654
			vco_min *= 10;
Line -... Line 655...
-
 
655
			vco_max *= 10;
-
 
656
	}
537
	if (pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP) {
657
 
Line 538... Line 658...
538
		if (tmp)
658
		post_div_min = vco_min / target_clock;
539
			post_div++;
-
 
540
	} else {
-
 
541
		if (!tmp)
-
 
542
			post_div--;
-
 
543
	}
-
 
544
 
-
 
545
	if (post_div > pll->max_post_div)
-
 
546
		post_div = pll->max_post_div;
-
 
547
	else if (post_div < pll->min_post_div)
659
		if ((target_clock * post_div_min) < vco_min)
548
		post_div = pll->min_post_div;
-
 
549
 
-
 
Line -... Line 660...
-
 
660
			++post_div_min;
550
	return post_div;
661
		if (post_div_min < pll->min_post_div)
551
}
662
			post_div_min = pll->min_post_div;
-
 
663
 
-
 
664
		post_div_max = vco_max / target_clock;
-
 
665
		if ((target_clock * post_div_max) > vco_max)
Line 552... Line 666...
552
 
666
			--post_div_max;
-
 
667
		if (post_div_max > pll->max_post_div)
553
#define MAX_TOLERANCE 10
668
			post_div_max = pll->max_post_div;
554
 
669
	}
555
void radeon_compute_pll_avivo(struct radeon_pll *pll,
670
 
556
			      u32 freq,
671
	/* represent the searched ratio as fractional number */
-
 
672
	nom = target_clock;
557
			      u32 *dot_clock_p,
673
	den = pll->reference_freq;
558
			      u32 *fb_div_p,
674
 
559
			      u32 *frac_fb_div_p,
675
	/* reduce the numbers to a simpler ratio */
560
			      u32 *ref_div_p,
676
	avivo_reduce_ratio(&nom, &den, fb_div_min, post_div_min);
561
			      u32 *post_div_p)
-
 
562
{
677
 
563
	u32 target_clock = freq / 10;
678
	/* now search for a post divider */
564
	u32 post_div = avivo_get_post_div(pll, target_clock);
679
	if (pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP)
565
	u32 ref_div = pll->min_ref_div;
680
		post_div_best = post_div_min;
-
 
681
	else
-
 
682
		post_div_best = post_div_max;
566
	u32 fb_div = 0, frac_fb_div = 0, tmp;
683
	diff_best = ~0;
567
 
684
 
-
 
685
	for (post_div = post_div_min; post_div <= post_div_max; ++post_div) {
568
	if (pll->flags & RADEON_PLL_USE_REF_DIV)
686
		unsigned diff;
569
		ref_div = pll->reference_div;
-
 
570
 
-
 
571
	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
687
		avivo_get_fb_ref_div(nom, den, post_div, fb_div_max,
572
		avivo_get_fb_div(pll, target_clock, post_div, ref_div, &fb_div, &frac_fb_div);
688
				     ref_div_max, &fb_div, &ref_div);
573
		frac_fb_div = (100 * frac_fb_div) / pll->reference_freq;
689
		diff = abs(target_clock - (pll->reference_freq * fb_div) /
-
 
690
			(ref_div * post_div));
-
 
691
 
574
		if (frac_fb_div >= 5) {
692
		if (diff < diff_best || (diff == diff_best &&
575
			frac_fb_div -= 5;
693
		    !(pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP))) {
576
			frac_fb_div = frac_fb_div / 10;
694
 
577
			frac_fb_div++;
695
			post_div_best = post_div;
578
		}
-
 
579
		if (frac_fb_div >= 10) {
696
			diff_best = diff;
580
			fb_div++;
697
		}
581
			frac_fb_div = 0;
698
	}
Line -... Line 699...
-
 
699
	post_div = post_div_best;
582
		}
700
 
583
	} else {
701
	/* get the feedback and reference divider for the optimal value */
-
 
702
	avivo_get_fb_ref_div(nom, den, post_div, fb_div_max, ref_div_max,
-
 
703
			     &fb_div, &ref_div);
584
		while (ref_div <= pll->max_ref_div) {
704
 
585
			avivo_get_fb_div(pll, target_clock, post_div, ref_div,
705
	/* reduce the numbers to a simpler ratio once more */
-
 
706
	/* this also makes sure that the reference divider is large enough */
-
 
707
	avivo_reduce_ratio(&fb_div, &ref_div, fb_div_min, ref_div_min);
-
 
708
 
-
 
709
	/* avoid high jitter with small fractional dividers */
-
 
710
	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV && (fb_div % 10)) {
586
					 &fb_div, &frac_fb_div);
711
		fb_div_min = max(fb_div_min, (9 - (fb_div % 10)) * 20 + 50);
587
			if (frac_fb_div >= (pll->reference_freq / 2))
712
		if (fb_div < fb_div_min) {
-
 
713
			unsigned tmp = DIV_ROUND_UP(fb_div_min, fb_div);
588
				fb_div++;
714
			fb_div *= tmp;
589
			frac_fb_div = 0;
715
			ref_div *= tmp;
-
 
716
		}
590
			tmp = (pll->reference_freq * fb_div) / (post_div * ref_div);
717
	}
Line 591... Line 718...
591
			tmp = (tmp * 10000) / target_clock;
718
 
592
 
719
	/* and finally save the result */
593
			if (tmp > (10000 + MAX_TOLERANCE))
720
	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
Line 807... Line 934...
807
 
934
 
808
static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
935
static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
809
{
936
{
Line -... Line 937...
-
 
937
	struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
-
 
938
 
-
 
939
	if (radeon_fb->obj) {
810
	struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
940
		drm_gem_object_unreference_unlocked(radeon_fb->obj);
811
 
941
	}
812
	drm_framebuffer_cleanup(fb);
942
	drm_framebuffer_cleanup(fb);
Line 813... Line 943...
813
	kfree(radeon_fb);
943
	kfree(radeon_fb);
Line 872... Line 1002...
872
{	{ UNDERSCAN_OFF, "off" },
1002
{	{ UNDERSCAN_OFF, "off" },
873
	{ UNDERSCAN_ON, "on" },
1003
	{ UNDERSCAN_ON, "on" },
874
	{ UNDERSCAN_AUTO, "auto" },
1004
	{ UNDERSCAN_AUTO, "auto" },
875
};
1005
};
Line -... Line 1006...
-
 
1006
 
-
 
1007
static struct drm_prop_enum_list radeon_audio_enum_list[] =
-
 
1008
{	{ RADEON_AUDIO_DISABLE, "off" },
-
 
1009
	{ RADEON_AUDIO_ENABLE, "on" },
-
 
1010
	{ RADEON_AUDIO_AUTO, "auto" },
-
 
1011
};
-
 
1012
 
-
 
1013
/* XXX support different dither options? spatial, temporal, both, etc. */
-
 
1014
static struct drm_prop_enum_list radeon_dither_enum_list[] =
-
 
1015
{	{ RADEON_FMT_DITHER_DISABLE, "off" },
-
 
1016
	{ RADEON_FMT_DITHER_ENABLE, "on" },
-
 
1017
};
876
 
1018
 
877
static int radeon_modeset_create_props(struct radeon_device *rdev)
1019
static int radeon_modeset_create_props(struct radeon_device *rdev)
878
{
1020
{
Line 879... Line 1021...
879
	int sz;
1021
	int sz;
Line 922... Line 1064...
922
		drm_property_create_range(rdev->ddev, 0,
1064
		drm_property_create_range(rdev->ddev, 0,
923
					"underscan vborder", 0, 128);
1065
					"underscan vborder", 0, 128);
924
	if (!rdev->mode_info.underscan_vborder_property)
1066
	if (!rdev->mode_info.underscan_vborder_property)
925
		return -ENOMEM;
1067
		return -ENOMEM;
Line -... Line 1068...
-
 
1068
 
-
 
1069
	sz = ARRAY_SIZE(radeon_audio_enum_list);
-
 
1070
	rdev->mode_info.audio_property =
-
 
1071
		drm_property_create_enum(rdev->ddev, 0,
-
 
1072
					 "audio",
-
 
1073
					 radeon_audio_enum_list, sz);
-
 
1074
 
-
 
1075
	sz = ARRAY_SIZE(radeon_dither_enum_list);
-
 
1076
	rdev->mode_info.dither_property =
-
 
1077
		drm_property_create_enum(rdev->ddev, 0,
-
 
1078
					 "dither",
-
 
1079
					 radeon_dither_enum_list, sz);
926
 
1080
 
927
	return 0;
1081
	return 0;
Line 928... Line 1082...
928
}
1082
}
929
 
1083
 
Line 955... Line 1109...
955
	int i;
1109
	int i;
Line 956... Line 1110...
956
 
1110
 
957
	for (i = 0; i < RADEON_MAX_AFMT_BLOCKS; i++)
1111
	for (i = 0; i < RADEON_MAX_AFMT_BLOCKS; i++)
Line 958... Line 1112...
958
		rdev->mode_info.afmt[i] = NULL;
1112
		rdev->mode_info.afmt[i] = NULL;
959
 
1113
 
960
	if (ASIC_IS_DCE6(rdev)) {
1114
	if (ASIC_IS_NODCE(rdev)) {
-
 
1115
		/* nothing to do */
-
 
1116
	} else if (ASIC_IS_DCE4(rdev)) {
-
 
1117
		static uint32_t eg_offsets[] = {
-
 
1118
			EVERGREEN_CRTC0_REGISTER_OFFSET,
-
 
1119
			EVERGREEN_CRTC1_REGISTER_OFFSET,
-
 
1120
			EVERGREEN_CRTC2_REGISTER_OFFSET,
-
 
1121
			EVERGREEN_CRTC3_REGISTER_OFFSET,
-
 
1122
			EVERGREEN_CRTC4_REGISTER_OFFSET,
-
 
1123
			EVERGREEN_CRTC5_REGISTER_OFFSET,
-
 
1124
			0x13830 - 0x7030,
-
 
1125
		};
-
 
1126
		int num_afmt;
-
 
1127
 
961
		/* todo */
1128
		/* DCE8 has 7 audio blocks tied to DIG encoders */
962
	} else if (ASIC_IS_DCE4(rdev)) {
1129
		/* DCE6 has 6 audio blocks tied to DIG encoders */
963
		/* DCE4/5 has 6 audio blocks tied to DIG encoders */
-
 
964
		/* DCE4.1 has 2 audio blocks tied to DIG encoders */
1130
		/* DCE4/5 has 6 audio blocks tied to DIG encoders */
965
		rdev->mode_info.afmt[0] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL);
-
 
966
		if (rdev->mode_info.afmt[0]) {
1131
		/* DCE4.1 has 2 audio blocks tied to DIG encoders */
967
			rdev->mode_info.afmt[0]->offset = EVERGREEN_CRTC0_REGISTER_OFFSET;
-
 
968
			rdev->mode_info.afmt[0]->id = 0;
-
 
969
		}
1132
		if (ASIC_IS_DCE8(rdev))
970
		rdev->mode_info.afmt[1] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL);
-
 
971
		if (rdev->mode_info.afmt[1]) {
1133
			num_afmt = 7;
972
			rdev->mode_info.afmt[1]->offset = EVERGREEN_CRTC1_REGISTER_OFFSET;
-
 
973
			rdev->mode_info.afmt[1]->id = 1;
1134
		else if (ASIC_IS_DCE6(rdev))
974
		}
-
 
975
		if (!ASIC_IS_DCE41(rdev)) {
1135
			num_afmt = 6;
976
			rdev->mode_info.afmt[2] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL);
1136
		else if (ASIC_IS_DCE5(rdev))
977
			if (rdev->mode_info.afmt[2]) {
1137
			num_afmt = 6;
978
				rdev->mode_info.afmt[2]->offset = EVERGREEN_CRTC2_REGISTER_OFFSET;
-
 
979
				rdev->mode_info.afmt[2]->id = 2;
-
 
980
			}
1138
		else if (ASIC_IS_DCE41(rdev))
981
			rdev->mode_info.afmt[3] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL);
-
 
982
			if (rdev->mode_info.afmt[3]) {
1139
			num_afmt = 2;
983
				rdev->mode_info.afmt[3]->offset = EVERGREEN_CRTC3_REGISTER_OFFSET;
1140
		else /* DCE4 */
984
				rdev->mode_info.afmt[3]->id = 3;
1141
			num_afmt = 6;
985
			}
1142
 
986
			rdev->mode_info.afmt[4] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL);
-
 
987
			if (rdev->mode_info.afmt[4]) {
-
 
988
				rdev->mode_info.afmt[4]->offset = EVERGREEN_CRTC4_REGISTER_OFFSET;
-
 
989
				rdev->mode_info.afmt[4]->id = 4;
1143
		BUG_ON(num_afmt > ARRAY_SIZE(eg_offsets));
990
			}
1144
		for (i = 0; i < num_afmt; i++) {
991
			rdev->mode_info.afmt[5] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL);
1145
			rdev->mode_info.afmt[i] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL);
992
			if (rdev->mode_info.afmt[5]) {
1146
			if (rdev->mode_info.afmt[i]) {
993
				rdev->mode_info.afmt[5]->offset = EVERGREEN_CRTC5_REGISTER_OFFSET;
1147
				rdev->mode_info.afmt[i]->offset = eg_offsets[i];
994
				rdev->mode_info.afmt[5]->id = 5;
1148
				rdev->mode_info.afmt[i]->id = i;
995
			}
1149
			}
996
		}
1150
		}
997
	} else if (ASIC_IS_DCE3(rdev)) {
1151
	} else if (ASIC_IS_DCE3(rdev)) {
Line 1037... Line 1191...
1037
int radeon_modeset_init(struct radeon_device *rdev)
1191
int radeon_modeset_init(struct radeon_device *rdev)
1038
{
1192
{
1039
	int i;
1193
	int i;
1040
	int ret;
1194
	int ret;
Line -... Line 1195...
-
 
1195
 
-
 
1196
ENTER();
1041
 
1197
 
1042
	drm_mode_config_init(rdev->ddev);
1198
	drm_mode_config_init(rdev->ddev);
Line 1043... Line 1199...
1043
	rdev->mode_info.mode_config_initialized = true;
1199
	rdev->mode_info.mode_config_initialized = true;
Line 1093... Line 1249...
1093
 
1249
 
1094
	/* initialize hpd */
1250
	/* initialize hpd */
Line 1095... Line 1251...
1095
//   radeon_hpd_init(rdev);
1251
//   radeon_hpd_init(rdev);
1096
 
1252
 
1097
	/* setup afmt */
-
 
1098
//	radeon_afmt_init(rdev);
-
 
1099
 
-
 
Line 1100... Line 1253...
1100
	/* Initialize power management */
1253
	/* setup afmt */
-
 
1254
	radeon_afmt_init(rdev);
1101
//   radeon_pm_init(rdev);
1255
 
Line 1102... Line 1256...
1102
 
1256
	radeon_fbdev_init(rdev);
1103
	radeon_fbdev_init(rdev);
1257
 
Line 1104... Line 1258...
1104
//   drm_kms_helper_poll_init(rdev->ddev);
1258
LEAVE();
Line 1179... Line 1333...
1179
			/* fix up for overscan on hdmi */
1333
			/* fix up for overscan on hdmi */
1180
			if (ASIC_IS_AVIVO(rdev) &&
1334
			if (ASIC_IS_AVIVO(rdev) &&
1181
			    (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) &&
1335
			    (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) &&
1182
			    ((radeon_encoder->underscan_type == UNDERSCAN_ON) ||
1336
			    ((radeon_encoder->underscan_type == UNDERSCAN_ON) ||
1183
			     ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) &&
1337
			     ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) &&
1184
			      drm_detect_hdmi_monitor(radeon_connector->edid) &&
1338
			      drm_detect_hdmi_monitor(radeon_connector_edid(connector)) &&
1185
			      is_hdtv_mode(mode)))) {
1339
			      is_hdtv_mode(mode)))) {
1186
				if (radeon_encoder->underscan_hborder != 0)
1340
				if (radeon_encoder->underscan_hborder != 0)
1187
					radeon_crtc->h_border = radeon_encoder->underscan_hborder;
1341
					radeon_crtc->h_border = radeon_encoder->underscan_hborder;
1188
				else
1342
				else
1189
				radeon_crtc->h_border = (mode->hdisplay >> 5) + 16;
1343
				radeon_crtc->h_border = (mode->hdisplay >> 5) + 16;
Line 1225... Line 1379...
1225
	}
1379
	}
1226
	return true;
1380
	return true;
1227
}
1381
}
Line 1228... Line 1382...
1228
 
1382
 
1229
/*
1383
/*
-
 
1384
 * Retrieve current video scanout position of crtc on a given gpu, and
1230
 * Retrieve current video scanout position of crtc on a given gpu.
1385
 * an optional accurate timestamp of when query happened.
1231
 *
1386
 *
1232
 * \param dev Device to query.
1387
 * \param dev Device to query.
-
 
1388
 * \param crtc Crtc to query.
1233
 * \param crtc Crtc to query.
1389
 * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0).
1234
 * \param *vpos Location where vertical scanout position should be stored.
1390
 * \param *vpos Location where vertical scanout position should be stored.
-
 
1391
 * \param *hpos Location where horizontal scanout position should go.
-
 
1392
 * \param *stime Target location for timestamp taken immediately before
-
 
1393
 *               scanout position query. Can be NULL to skip timestamp.
-
 
1394
 * \param *etime Target location for timestamp taken immediately after
1235
 * \param *hpos Location where horizontal scanout position should go.
1395
 *               scanout position query. Can be NULL to skip timestamp.
1236
 *
1396
 *
1237
 * Returns vpos as a positive number while in active scanout area.
1397
 * Returns vpos as a positive number while in active scanout area.
1238
 * Returns vpos as a negative number inside vblank, counting the number
1398
 * Returns vpos as a negative number inside vblank, counting the number
1239
 * of scanlines to go until end of vblank, e.g., -1 means "one scanline
1399
 * of scanlines to go until end of vblank, e.g., -1 means "one scanline
Line 1246... Line 1406...
1246
 * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of
1406
 * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of
1247
 * this flag means that returned position may be offset by a constant but
1407
 * this flag means that returned position may be offset by a constant but
1248
 * unknown small number of scanlines wrt. real scanout position.
1408
 * unknown small number of scanlines wrt. real scanout position.
1249
 *
1409
 *
1250
 */
1410
 */
1251
int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int *hpos)
1411
int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int flags,
-
 
1412
			       int *vpos, int *hpos, void *stime, void *etime)
1252
{
1413
{
1253
	u32 stat_crtc = 0, vbl = 0, position = 0;
1414
	u32 stat_crtc = 0, vbl = 0, position = 0;
1254
	int vbl_start, vbl_end, vtotal, ret = 0;
1415
	int vbl_start, vbl_end, vtotal, ret = 0;
1255
	bool in_vbl = true;
1416
	bool in_vbl = true;
Line 1376... Line 1537...
1376
 
1537
 
1377
	/* In vblank? */
1538
	/* In vblank? */
1378
	if (in_vbl)
1539
	if (in_vbl)
Line -... Line 1540...
-
 
1540
		ret |= DRM_SCANOUTPOS_INVBL;
-
 
1541
 
-
 
1542
	/* Is vpos outside nominal vblank area, but less than
-
 
1543
	 * 1/100 of a frame height away from start of vblank?
-
 
1544
	 * If so, assume this isn't a massively delayed vblank
-
 
1545
	 * interrupt, but a vblank interrupt that fired a few
-
 
1546
	 * microseconds before true start of vblank. Compensate
-
 
1547
	 * by adding a full frame duration to the final timestamp.
-
 
1548
	 * Happens, e.g., on ATI R500, R600.
-
 
1549
	 *
-
 
1550
	 * We only do this if DRM_CALLED_FROM_VBLIRQ.
-
 
1551
	 */
-
 
1552
	if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) {
-
 
1553
		vbl_start = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay;
-
 
1554
		vtotal = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal;
-
 
1555
 
-
 
1556
		if (vbl_start - *vpos < vtotal / 100) {
-
 
1557
			*vpos -= vtotal;
-
 
1558
 
-
 
1559
			/* Signal this correction as "applied". */
-
 
1560
			ret |= 0x8;
-
 
1561
		}
1379
		ret |= DRM_SCANOUTPOS_INVBL;
1562
	}
1380
 
1563