Subversion Repositories Kolibri OS

Rev

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

Rev 5271 Rev 6104
Line 28... Line 28...
28
#include "radeon.h"
28
#include "radeon.h"
Line 29... Line 29...
29
 
29
 
30
#include "atom.h"
30
#include "atom.h"
Line -... Line 31...
-
 
31
#include 
31
#include 
32
 
-
 
33
#include 
32
 
34
#include 
Line 33... Line -...
33
#include 
-
 
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;
35
#include 
46
        while ((r = a % b) != 0) {
-
 
47
                a = b;
-
 
48
                b = r;
-
 
Line 49... Line 36...
49
        }
36
#include 
50
        return b;
37
 
51
}
38
#include 
52
 
39
 
Line 165... Line 152...
165
		NI_OVL_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS)));
152
		NI_OVL_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS)));
166
	WREG32(NI_REGAMMA_CONTROL + radeon_crtc->crtc_offset,
153
	WREG32(NI_REGAMMA_CONTROL + radeon_crtc->crtc_offset,
167
	       (NI_GRPH_REGAMMA_MODE(NI_REGAMMA_BYPASS) |
154
	       (NI_GRPH_REGAMMA_MODE(NI_REGAMMA_BYPASS) |
168
		NI_OVL_REGAMMA_MODE(NI_REGAMMA_BYPASS)));
155
		NI_OVL_REGAMMA_MODE(NI_REGAMMA_BYPASS)));
169
	WREG32(NI_OUTPUT_CSC_CONTROL + radeon_crtc->crtc_offset,
156
	WREG32(NI_OUTPUT_CSC_CONTROL + radeon_crtc->crtc_offset,
170
	       (NI_OUTPUT_CSC_GRPH_MODE(NI_OUTPUT_CSC_BYPASS) |
157
	       (NI_OUTPUT_CSC_GRPH_MODE(radeon_crtc->output_csc) |
171
		NI_OUTPUT_CSC_OVL_MODE(NI_OUTPUT_CSC_BYPASS)));
158
		NI_OUTPUT_CSC_OVL_MODE(NI_OUTPUT_CSC_BYPASS)));
172
	/* XXX match this to the depth of the crtc fmt block, move to modeset? */
159
	/* XXX match this to the depth of the crtc fmt block, move to modeset? */
173
	WREG32(0x6940 + radeon_crtc->crtc_offset, 0);
160
	WREG32(0x6940 + radeon_crtc->crtc_offset, 0);
174
	if (ASIC_IS_DCE8(rdev)) {
161
	if (ASIC_IS_DCE8(rdev)) {
175
		/* XXX this only needs to be programmed once per crtc at startup,
162
		/* XXX this only needs to be programmed once per crtc at startup,
Line 265... Line 252...
265
 
252
 
266
	drm_crtc_cleanup(crtc);
253
	drm_crtc_cleanup(crtc);
267
	kfree(radeon_crtc);
254
	kfree(radeon_crtc);
Line -... Line 255...
-
 
255
}
-
 
256
 
-
 
257
void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
-
 
258
{
-
 
259
	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
-
 
260
	unsigned long flags;
-
 
261
	u32 update_pending;
-
 
262
	int vpos, hpos;
-
 
263
 
-
 
264
	/* can happen during initialization */
-
 
265
	if (radeon_crtc == NULL)
-
 
266
		return;
-
 
267
 
-
 
268
	/* Skip the pageflip completion check below (based on polling) on
-
 
269
	 * asics which reliably support hw pageflip completion irqs. pflip
-
 
270
	 * irqs are a reliable and race-free method of handling pageflip
-
 
271
	 * completion detection. A use_pflipirq module parameter < 2 allows
-
 
272
	 * to override this in case of asics with faulty pflip irqs.
-
 
273
	 * A module parameter of 0 would only use this polling based path,
-
 
274
	 * a parameter of 1 would use pflip irq only as a backup to this
-
 
275
	 * path, as in Linux 3.16.
-
 
276
	 */
-
 
277
	if ((radeon_use_pflipirq == 2) && ASIC_IS_DCE4(rdev))
-
 
278
		return;
-
 
279
 
-
 
280
	spin_lock_irqsave(&rdev->ddev->event_lock, flags);
-
 
281
	if (radeon_crtc->flip_status != RADEON_FLIP_SUBMITTED) {
-
 
282
		DRM_DEBUG_DRIVER("radeon_crtc->flip_status = %d != "
-
 
283
				 "RADEON_FLIP_SUBMITTED(%d)\n",
-
 
284
				 radeon_crtc->flip_status,
-
 
285
				 RADEON_FLIP_SUBMITTED);
-
 
286
		spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
-
 
287
		return;
-
 
288
	}
-
 
289
 
-
 
290
	update_pending = radeon_page_flip_pending(rdev, crtc_id);
-
 
291
 
-
 
292
	/* Has the pageflip already completed in crtc, or is it certain
-
 
293
	 * to complete in this vblank?
-
 
294
	 */
-
 
295
	if (update_pending &&
-
 
296
	    (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev,
-
 
297
							       crtc_id,
-
 
298
							       USE_REAL_VBLANKSTART,
-
 
299
							       &vpos, &hpos, NULL, NULL,
-
 
300
							       &rdev->mode_info.crtcs[crtc_id]->base.hwmode)) &&
-
 
301
	    ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) ||
-
 
302
	     (vpos < 0 && !ASIC_IS_AVIVO(rdev)))) {
-
 
303
		/* crtc didn't flip in this target vblank interval,
-
 
304
		 * but flip is pending in crtc. Based on the current
-
 
305
		 * scanout position we know that the current frame is
-
 
306
		 * (nearly) complete and the flip will (likely)
-
 
307
		 * complete before the start of the next frame.
-
 
308
		 */
-
 
309
		update_pending = 0;
-
 
310
	}
-
 
311
	spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
-
 
312
//	if (!update_pending)
-
 
313
//		radeon_crtc_handle_flip(rdev, crtc_id);
268
}
314
}
269
 
315
 
270
static int
316
static int
271
radeon_crtc_set_config(struct drm_mode_set *set)
317
radeon_crtc_set_config(struct drm_mode_set *set)
272
{
318
{
Line 630... Line 676...
630
		ref_div_min = pll->min_ref_div;
676
		ref_div_min = pll->min_ref_div;
Line 631... Line 677...
631
 
677
 
632
	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV &&
678
	if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV &&
633
	    pll->flags & RADEON_PLL_USE_REF_DIV)
679
	    pll->flags & RADEON_PLL_USE_REF_DIV)
-
 
680
		ref_div_max = pll->reference_div;
-
 
681
	else if (pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP)
-
 
682
		/* fix for problems on RS880 */
634
		ref_div_max = pll->reference_div;
683
		ref_div_max = min(pll->max_ref_div, 7u);
635
		else
684
		else
Line 636... Line 685...
636
		ref_div_max = pll->max_ref_div;
685
		ref_div_max = pll->max_ref_div;
637
 
686
 
Line 1014... Line 1063...
1014
static struct drm_prop_enum_list radeon_dither_enum_list[] =
1063
static struct drm_prop_enum_list radeon_dither_enum_list[] =
1015
{	{ RADEON_FMT_DITHER_DISABLE, "off" },
1064
{	{ RADEON_FMT_DITHER_DISABLE, "off" },
1016
	{ RADEON_FMT_DITHER_ENABLE, "on" },
1065
	{ RADEON_FMT_DITHER_ENABLE, "on" },
1017
};
1066
};
Line -... Line 1067...
-
 
1067
 
-
 
1068
static struct drm_prop_enum_list radeon_output_csc_enum_list[] =
-
 
1069
{	{ RADEON_OUTPUT_CSC_BYPASS, "bypass" },
-
 
1070
	{ RADEON_OUTPUT_CSC_TVRGB, "tvrgb" },
-
 
1071
	{ RADEON_OUTPUT_CSC_YCBCR601, "ycbcr601" },
-
 
1072
	{ RADEON_OUTPUT_CSC_YCBCR709, "ycbcr709" },
-
 
1073
};
1018
 
1074
 
1019
static int radeon_modeset_create_props(struct radeon_device *rdev)
1075
static int radeon_modeset_create_props(struct radeon_device *rdev)
1020
{
1076
{
Line 1021... Line 1077...
1021
	int sz;
1077
	int sz;
Line 1076... Line 1132...
1076
	rdev->mode_info.dither_property =
1132
	rdev->mode_info.dither_property =
1077
		drm_property_create_enum(rdev->ddev, 0,
1133
		drm_property_create_enum(rdev->ddev, 0,
1078
					 "dither",
1134
					 "dither",
1079
					 radeon_dither_enum_list, sz);
1135
					 radeon_dither_enum_list, sz);
Line -... Line 1136...
-
 
1136
 
-
 
1137
	sz = ARRAY_SIZE(radeon_output_csc_enum_list);
-
 
1138
	rdev->mode_info.output_csc_property =
-
 
1139
		drm_property_create_enum(rdev->ddev, 0,
-
 
1140
					 "output_csc",
-
 
1141
					 radeon_output_csc_enum_list, sz);
1080
 
1142
 
1081
	return 0;
1143
	return 0;
Line 1082... Line 1144...
1082
}
1144
}
1083
 
1145
 
Line 1406... Line 1468...
1406
 * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of
1468
 * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of
1407
 * this flag means that returned position may be offset by a constant but
1469
 * this flag means that returned position may be offset by a constant but
1408
 * unknown small number of scanlines wrt. real scanout position.
1470
 * unknown small number of scanlines wrt. real scanout position.
1409
 *
1471
 *
1410
 */
1472
 */
1411
int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int flags,
1473
int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
1412
			       int *vpos, int *hpos, void *stime, void *etime)
1474
			       unsigned int flags, int *vpos, int *hpos,
-
 
1475
			       ktime_t *stime, ktime_t *etime,
-
 
1476
			       const struct drm_display_mode *mode)
1413
{
1477
{
1414
	u32 stat_crtc = 0, vbl = 0, position = 0;
1478
	u32 stat_crtc = 0, vbl = 0, position = 0;
1415
	int vbl_start, vbl_end, vtotal, ret = 0;
1479
	int vbl_start, vbl_end, vtotal, ret = 0;
1416
	bool in_vbl = true;
1480
	bool in_vbl = true;
Line 1417... Line 1481...
1417
 
1481
 
Line -... Line 1482...
-
 
1482
	struct radeon_device *rdev = dev->dev_private;
-
 
1483
 
-
 
1484
	/* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */
-
 
1485
 
-
 
1486
	/* Get optional system timestamp before query. */
-
 
1487
	if (stime)
1418
	struct radeon_device *rdev = dev->dev_private;
1488
		*stime = ktime_get();
1419
 
1489
 
1420
	if (ASIC_IS_DCE4(rdev)) {
1490
	if (ASIC_IS_DCE4(rdev)) {
1421
		if (crtc == 0) {
1491
		if (pipe == 0) {
1422
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1492
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1423
				     EVERGREEN_CRTC0_REGISTER_OFFSET);
1493
				     EVERGREEN_CRTC0_REGISTER_OFFSET);
1424
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1494
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1425
					  EVERGREEN_CRTC0_REGISTER_OFFSET);
1495
					  EVERGREEN_CRTC0_REGISTER_OFFSET);
1426
			ret |= DRM_SCANOUTPOS_VALID;
1496
			ret |= DRM_SCANOUTPOS_VALID;
1427
		}
1497
		}
1428
		if (crtc == 1) {
1498
		if (pipe == 1) {
1429
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1499
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1430
				     EVERGREEN_CRTC1_REGISTER_OFFSET);
1500
				     EVERGREEN_CRTC1_REGISTER_OFFSET);
1431
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1501
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1432
					  EVERGREEN_CRTC1_REGISTER_OFFSET);
1502
					  EVERGREEN_CRTC1_REGISTER_OFFSET);
1433
			ret |= DRM_SCANOUTPOS_VALID;
1503
			ret |= DRM_SCANOUTPOS_VALID;
1434
		}
1504
		}
1435
		if (crtc == 2) {
1505
		if (pipe == 2) {
1436
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1506
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1437
				     EVERGREEN_CRTC2_REGISTER_OFFSET);
1507
				     EVERGREEN_CRTC2_REGISTER_OFFSET);
1438
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1508
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1439
					  EVERGREEN_CRTC2_REGISTER_OFFSET);
1509
					  EVERGREEN_CRTC2_REGISTER_OFFSET);
1440
			ret |= DRM_SCANOUTPOS_VALID;
1510
			ret |= DRM_SCANOUTPOS_VALID;
1441
		}
1511
		}
1442
		if (crtc == 3) {
1512
		if (pipe == 3) {
1443
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1513
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1444
				     EVERGREEN_CRTC3_REGISTER_OFFSET);
1514
				     EVERGREEN_CRTC3_REGISTER_OFFSET);
1445
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1515
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1446
					  EVERGREEN_CRTC3_REGISTER_OFFSET);
1516
					  EVERGREEN_CRTC3_REGISTER_OFFSET);
1447
			ret |= DRM_SCANOUTPOS_VALID;
1517
			ret |= DRM_SCANOUTPOS_VALID;
1448
		}
1518
		}
1449
		if (crtc == 4) {
1519
		if (pipe == 4) {
1450
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1520
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1451
				     EVERGREEN_CRTC4_REGISTER_OFFSET);
1521
				     EVERGREEN_CRTC4_REGISTER_OFFSET);
1452
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1522
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1453
					  EVERGREEN_CRTC4_REGISTER_OFFSET);
1523
					  EVERGREEN_CRTC4_REGISTER_OFFSET);
1454
			ret |= DRM_SCANOUTPOS_VALID;
1524
			ret |= DRM_SCANOUTPOS_VALID;
1455
		}
1525
		}
1456
		if (crtc == 5) {
1526
		if (pipe == 5) {
1457
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1527
			vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
1458
				     EVERGREEN_CRTC5_REGISTER_OFFSET);
1528
				     EVERGREEN_CRTC5_REGISTER_OFFSET);
1459
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1529
			position = RREG32(EVERGREEN_CRTC_STATUS_POSITION +
1460
					  EVERGREEN_CRTC5_REGISTER_OFFSET);
1530
					  EVERGREEN_CRTC5_REGISTER_OFFSET);
1461
			ret |= DRM_SCANOUTPOS_VALID;
1531
			ret |= DRM_SCANOUTPOS_VALID;
1462
		}
1532
		}
1463
	} else if (ASIC_IS_AVIVO(rdev)) {
1533
	} else if (ASIC_IS_AVIVO(rdev)) {
1464
		if (crtc == 0) {
1534
		if (pipe == 0) {
1465
			vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END);
1535
			vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END);
1466
			position = RREG32(AVIVO_D1CRTC_STATUS_POSITION);
1536
			position = RREG32(AVIVO_D1CRTC_STATUS_POSITION);
1467
			ret |= DRM_SCANOUTPOS_VALID;
1537
			ret |= DRM_SCANOUTPOS_VALID;
1468
		}
1538
		}
1469
		if (crtc == 1) {
1539
		if (pipe == 1) {
1470
			vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END);
1540
			vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END);
1471
			position = RREG32(AVIVO_D2CRTC_STATUS_POSITION);
1541
			position = RREG32(AVIVO_D2CRTC_STATUS_POSITION);
1472
			ret |= DRM_SCANOUTPOS_VALID;
1542
			ret |= DRM_SCANOUTPOS_VALID;
1473
		}
1543
		}
1474
	} else {
1544
	} else {
1475
		/* Pre-AVIVO: Different encoding of scanout pos and vblank interval. */
1545
		/* Pre-AVIVO: Different encoding of scanout pos and vblank interval. */
1476
		if (crtc == 0) {
1546
		if (pipe == 0) {
1477
			/* Assume vbl_end == 0, get vbl_start from
1547
			/* Assume vbl_end == 0, get vbl_start from
1478
			 * upper 16 bits.
1548
			 * upper 16 bits.
1479
			 */
1549
			 */
Line 1485... Line 1555...
1485
			if (!(stat_crtc & 1))
1555
			if (!(stat_crtc & 1))
1486
				in_vbl = false;
1556
				in_vbl = false;
Line 1487... Line 1557...
1487
 
1557
 
1488
			ret |= DRM_SCANOUTPOS_VALID;
1558
			ret |= DRM_SCANOUTPOS_VALID;
1489
		}
1559
		}
1490
		if (crtc == 1) {
1560
		if (pipe == 1) {
1491
			vbl = (RREG32(RADEON_CRTC2_V_TOTAL_DISP) &
1561
			vbl = (RREG32(RADEON_CRTC2_V_TOTAL_DISP) &
1492
				RADEON_CRTC_V_DISP) >> RADEON_CRTC_V_DISP_SHIFT;
1562
				RADEON_CRTC_V_DISP) >> RADEON_CRTC_V_DISP_SHIFT;
1493
			position = (RREG32(RADEON_CRTC2_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
1563
			position = (RREG32(RADEON_CRTC2_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL;
1494
			stat_crtc = RREG32(RADEON_CRTC2_STATUS);
1564
			stat_crtc = RREG32(RADEON_CRTC2_STATUS);
Line 1497... Line 1567...
1497
 
1567
 
1498
			ret |= DRM_SCANOUTPOS_VALID;
1568
			ret |= DRM_SCANOUTPOS_VALID;
1499
		}
1569
		}
Line -... Line 1570...
-
 
1570
	}
-
 
1571
 
-
 
1572
	/* Get optional system timestamp after query. */
-
 
1573
	if (etime)
-
 
1574
		*etime = ktime_get();
-
 
1575
 
1500
	}
1576
	/* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */
1501
 
1577
 
1502
	/* Decode into vertical and horizontal scanout position. */
1578
	/* Decode into vertical and horizontal scanout position. */
Line 1503... Line 1579...
1503
	*vpos = position & 0x1fff;
1579
	*vpos = position & 0x1fff;
Line 1510... Line 1586...
1510
		vbl_start = vbl & 0x1fff;
1586
		vbl_start = vbl & 0x1fff;
1511
		vbl_end = (vbl >> 16) & 0x1fff;
1587
		vbl_end = (vbl >> 16) & 0x1fff;
1512
	}
1588
	}
1513
	else {
1589
	else {
1514
		/* No: Fake something reasonable which gives at least ok results. */
1590
		/* No: Fake something reasonable which gives at least ok results. */
1515
		vbl_start = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay;
1591
		vbl_start = mode->crtc_vdisplay;
1516
		vbl_end = 0;
1592
		vbl_end = 0;
1517
	}
1593
	}
Line 1518... Line 1594...
1518
 
1594
 
1519
	/* Test scanout position against vblank region. */
1595
	/* Test scanout position against vblank region. */
Line 1526... Line 1602...
1526
	 * start of scanout.
1602
	 * start of scanout.
1527
	 */
1603
	 */
Line 1528... Line 1604...
1528
 
1604
 
1529
	/* Inside "upper part" of vblank area? Apply corrective offset if so: */
1605
	/* Inside "upper part" of vblank area? Apply corrective offset if so: */
1530
	if (in_vbl && (*vpos >= vbl_start)) {
1606
	if (in_vbl && (*vpos >= vbl_start)) {
1531
		vtotal = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal;
1607
		vtotal = mode->crtc_vtotal;
1532
		*vpos = *vpos - vtotal;
1608
		*vpos = *vpos - vtotal;
Line 1533... Line 1609...
1533
	}
1609
	}
1534
 
1610
 
Line 1548... Line 1624...
1548
	 * Happens, e.g., on ATI R500, R600.
1624
	 * Happens, e.g., on ATI R500, R600.
1549
	 *
1625
	 *
1550
	 * We only do this if DRM_CALLED_FROM_VBLIRQ.
1626
	 * We only do this if DRM_CALLED_FROM_VBLIRQ.
1551
	 */
1627
	 */
1552
	if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) {
1628
	if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) {
1553
		vbl_start = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay;
1629
		vbl_start = mode->crtc_vdisplay;
1554
		vtotal = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal;
1630
		vtotal = mode->crtc_vtotal;
Line 1555... Line 1631...
1555
 
1631
 
1556
		if (vbl_start - *vpos < vtotal / 100) {
1632
		if (vbl_start - *vpos < vtotal / 100) {
Line 1557... Line 1633...
1557
			*vpos -= vtotal;
1633
			*vpos -= vtotal;