Subversion Repositories Kolibri OS

Rev

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

Rev 2997 Rev 3192
Line 32... Line 32...
32
#include "atom-bits.h"
32
#include "atom-bits.h"
33
#include 
33
#include 
Line 34... Line 34...
34
 
34
 
35
/* move these to drm_dp_helper.c/h */
35
/* move these to drm_dp_helper.c/h */
36
#define DP_LINK_CONFIGURATION_SIZE 9
-
 
37
#define DP_LINK_STATUS_SIZE	   6
36
#define DP_LINK_CONFIGURATION_SIZE 9
Line 38... Line 37...
38
#define DP_DPCD_SIZE	           8
37
#define DP_DPCD_SIZE DP_RECEIVER_CAP_SIZE
39
 
38
 
40
static char *voltage_names[] = {
39
static char *voltage_names[] = {
41
        "0.4V", "0.6V", "0.8V", "1.2V"
40
        "0.4V", "0.6V", "0.8V", "1.2V"
Line 288... Line 287...
288
	return -EREMOTEIO;
287
	return -EREMOTEIO;
289
}
288
}
Line 290... Line 289...
290
 
289
 
Line 291... Line -...
291
/***** general DP utility functions *****/
-
 
292
 
-
 
293
static u8 dp_link_status(u8 link_status[DP_LINK_STATUS_SIZE], int r)
-
 
294
{
-
 
295
	return link_status[r - DP_LANE0_1_STATUS];
-
 
296
}
-
 
297
 
-
 
298
static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE],
-
 
299
			     int lane)
-
 
300
{
-
 
301
	int i = DP_LANE0_1_STATUS + (lane >> 1);
-
 
302
	int s = (lane & 1) * 4;
-
 
303
	u8 l = dp_link_status(link_status, i);
-
 
304
	return (l >> s) & 0xf;
-
 
305
}
-
 
306
 
-
 
307
static bool dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE],
-
 
308
				 int lane_count)
-
 
309
{
-
 
310
	int lane;
-
 
311
	u8 lane_status;
-
 
312
 
-
 
313
	for (lane = 0; lane < lane_count; lane++) {
-
 
314
		lane_status = dp_get_lane_status(link_status, lane);
-
 
315
		if ((lane_status & DP_LANE_CR_DONE) == 0)
-
 
316
			return false;
-
 
317
	}
-
 
318
	return true;
-
 
319
}
-
 
320
 
-
 
321
static bool dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE],
-
 
322
			     int lane_count)
-
 
323
{
-
 
324
	u8 lane_align;
-
 
325
	u8 lane_status;
-
 
326
	int lane;
-
 
327
 
-
 
328
	lane_align = dp_link_status(link_status,
-
 
329
				    DP_LANE_ALIGN_STATUS_UPDATED);
-
 
330
	if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
-
 
331
		return false;
-
 
332
	for (lane = 0; lane < lane_count; lane++) {
-
 
333
		lane_status = dp_get_lane_status(link_status, lane);
-
 
334
		if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS)
-
 
335
			return false;
-
 
336
	}
-
 
337
	return true;
-
 
338
}
-
 
339
 
-
 
340
static u8 dp_get_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE],
-
 
341
					int lane)
-
 
342
 
-
 
343
{
-
 
344
	int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
-
 
345
	int s = ((lane & 1) ?
-
 
346
		 DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :
-
 
347
		 DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT);
-
 
348
	u8 l = dp_link_status(link_status, i);
-
 
349
 
-
 
350
	return ((l >> s) & 0x3) << DP_TRAIN_VOLTAGE_SWING_SHIFT;
-
 
351
}
-
 
352
 
-
 
353
static u8 dp_get_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE],
-
 
354
					     int lane)
-
 
355
{
-
 
356
	int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
-
 
357
	int s = ((lane & 1) ?
-
 
358
		 DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :
-
 
359
		 DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT);
-
 
360
	u8 l = dp_link_status(link_status, i);
-
 
361
 
-
 
362
	return ((l >> s) & 0x3) << DP_TRAIN_PRE_EMPHASIS_SHIFT;
-
 
363
}
290
/***** general DP utility functions *****/
364
 
291
 
Line 365... Line 292...
365
#define DP_VOLTAGE_MAX         DP_TRAIN_VOLTAGE_SWING_1200
292
#define DP_VOLTAGE_MAX         DP_TRAIN_VOLTAGE_SWING_1200
366
#define DP_PRE_EMPHASIS_MAX    DP_TRAIN_PRE_EMPHASIS_9_5
293
#define DP_PRE_EMPHASIS_MAX    DP_TRAIN_PRE_EMPHASIS_9_5
Line 372... Line 299...
372
	u8 v = 0;
299
	u8 v = 0;
373
	u8 p = 0;
300
	u8 p = 0;
374
	int lane;
301
	int lane;
Line 375... Line 302...
375
 
302
 
376
	for (lane = 0; lane < lane_count; lane++) {
303
	for (lane = 0; lane < lane_count; lane++) {
377
		u8 this_v = dp_get_adjust_request_voltage(link_status, lane);
304
		u8 this_v = drm_dp_get_adjust_request_voltage(link_status, lane);
Line 378... Line 305...
378
		u8 this_p = dp_get_adjust_request_pre_emphasis(link_status, lane);
305
		u8 this_p = drm_dp_get_adjust_request_pre_emphasis(link_status, lane);
379
 
306
 
380
		DRM_DEBUG_KMS("requested signal parameters: lane %d voltage %s pre_emph %s\n",
307
		DRM_DEBUG_KMS("requested signal parameters: lane %d voltage %s pre_emph %s\n",
381
			  lane,
308
			  lane,
Line 418... Line 345...
418
				   int bpp)
345
				   int bpp)
419
{
346
{
420
	return (link_rate * lane_num * 8) / bpp;
347
	return (link_rate * lane_num * 8) / bpp;
421
}
348
}
Line 422... Line -...
422
 
-
 
423
static int dp_get_max_link_rate(u8 dpcd[DP_DPCD_SIZE])
-
 
424
{
-
 
425
	switch (dpcd[DP_MAX_LINK_RATE]) {
-
 
426
	case DP_LINK_BW_1_62:
-
 
427
	default:
-
 
428
		return 162000;
-
 
429
	case DP_LINK_BW_2_7:
-
 
430
		return 270000;
-
 
431
	case DP_LINK_BW_5_4:
-
 
432
		return 540000;
-
 
433
	}
-
 
434
}
-
 
435
 
-
 
436
static u8 dp_get_max_lane_number(u8 dpcd[DP_DPCD_SIZE])
-
 
437
{
-
 
438
	return dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
-
 
439
}
-
 
440
 
-
 
441
static u8 dp_get_dp_link_rate_coded(int link_rate)
-
 
442
{
-
 
443
	switch (link_rate) {
-
 
444
	case 162000:
-
 
445
	default:
-
 
446
		return DP_LINK_BW_1_62;
-
 
447
	case 270000:
-
 
448
		return DP_LINK_BW_2_7;
-
 
449
	case 540000:
-
 
450
		return DP_LINK_BW_5_4;
-
 
451
	}
-
 
452
}
-
 
453
 
349
 
Line 454... Line 350...
454
/***** radeon specific DP functions *****/
350
/***** radeon specific DP functions *****/
455
 
351
 
456
/* First get the min lane# when low rate is used according to pixel clock
352
/* First get the min lane# when low rate is used according to pixel clock
Line 460... Line 356...
460
static int radeon_dp_get_dp_lane_number(struct drm_connector *connector,
356
static int radeon_dp_get_dp_lane_number(struct drm_connector *connector,
461
					u8 dpcd[DP_DPCD_SIZE],
357
					u8 dpcd[DP_DPCD_SIZE],
462
					int pix_clock)
358
					int pix_clock)
463
{
359
{
464
	int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector));
360
	int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector));
465
	int max_link_rate = dp_get_max_link_rate(dpcd);
361
	int max_link_rate = drm_dp_max_link_rate(dpcd);
466
	int max_lane_num = dp_get_max_lane_number(dpcd);
362
	int max_lane_num = drm_dp_max_lane_count(dpcd);
467
	int lane_num;
363
	int lane_num;
468
	int max_dp_pix_clock;
364
	int max_dp_pix_clock;
Line 469... Line 365...
469
 
365
 
470
	for (lane_num = 1; lane_num < max_lane_num; lane_num <<= 1) {
366
	for (lane_num = 1; lane_num < max_lane_num; lane_num <<= 1) {
Line 498... Line 394...
498
		max_pix_clock = dp_get_max_dp_pix_clock(540000, lane_num, bpp);
394
		max_pix_clock = dp_get_max_dp_pix_clock(540000, lane_num, bpp);
499
		if (pix_clock <= max_pix_clock)
395
		if (pix_clock <= max_pix_clock)
500
			return 540000;
396
			return 540000;
501
	}
397
	}
Line 502... Line 398...
502
 
398
 
503
	return dp_get_max_link_rate(dpcd);
399
	return drm_dp_max_link_rate(dpcd);
Line 504... Line 400...
504
}
400
}
505
 
401
 
506
static u8 radeon_dp_encoder_service(struct radeon_device *rdev,
402
static u8 radeon_dp_encoder_service(struct radeon_device *rdev,
Line 549... Line 445...
549
}
445
}
Line 550... Line 446...
550
 
446
 
551
bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
447
bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
552
{
448
{
553
	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
449
	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
554
	u8 msg[25];
450
	u8 msg[DP_DPCD_SIZE];
Line -... Line 451...
-
 
451
	int ret, i;
-
 
452
 
555
	int ret, i;
453
    ENTER();
-
 
454
 
556
 
455
	ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, msg,
557
	ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, msg, 8, 0);
456
					DP_DPCD_SIZE, 0);
558
	if (ret > 0) {
457
	if (ret > 0) {
559
		memcpy(dig_connector->dpcd, msg, 8);
458
		memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
560
			DRM_DEBUG_KMS("DPCD: ");
459
			DRM_DEBUG_KMS("DPCD: ");
561
			for (i = 0; i < 8; i++)
460
		for (i = 0; i < DP_DPCD_SIZE; i++)
Line 562... Line 461...
562
				DRM_DEBUG_KMS("%02x ", msg[i]);
461
				DRM_DEBUG_KMS("%02x ", msg[i]);
563
			DRM_DEBUG_KMS("\n");
-
 
-
 
462
			DRM_DEBUG_KMS("\n");
564
 
463
 
565
		radeon_dp_probe_oui(radeon_connector);
464
		radeon_dp_probe_oui(radeon_connector);
-
 
465
        LEAVE();
566
 
466
		return true;
567
		return true;
467
	}
568
	}
468
    FAIL();
Line 569... Line 469...
569
	dig_connector->dpcd[0] = 0;
469
	dig_connector->dpcd[0] = 0;
Line 662... Line 562...
662
	u8 link_status[DP_LINK_STATUS_SIZE];
562
	u8 link_status[DP_LINK_STATUS_SIZE];
663
	struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
563
	struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
Line 664... Line 564...
664
 
564
 
665
	if (!radeon_dp_get_link_status(radeon_connector, link_status))
565
	if (!radeon_dp_get_link_status(radeon_connector, link_status))
666
		return false;
566
		return false;
667
	if (dp_channel_eq_ok(link_status, dig->dp_lane_count))
567
	if (drm_dp_channel_eq_ok(link_status, dig->dp_lane_count))
668
		return false;
568
		return false;
669
	return true;
569
	return true;
Line 670... Line 570...
670
}
570
}
Line 675... Line 575...
675
	struct drm_connector *connector;
575
	struct drm_connector *connector;
676
	struct radeon_connector *radeon_connector;
576
	struct radeon_connector *radeon_connector;
677
	int enc_id;
577
	int enc_id;
678
	int dp_clock;
578
	int dp_clock;
679
	int dp_lane_count;
579
	int dp_lane_count;
680
	int rd_interval;
-
 
681
	bool tp3_supported;
580
	bool tp3_supported;
682
	u8 dpcd[8];
581
	u8 dpcd[DP_RECEIVER_CAP_SIZE];
683
	u8 train_set[4];
582
	u8 train_set[4];
684
	u8 link_status[DP_LINK_STATUS_SIZE];
583
	u8 link_status[DP_LINK_STATUS_SIZE];
685
	u8 tries;
584
	u8 tries;
686
	bool use_dpencoder;
585
	bool use_dpencoder;
687
};
586
};
Line 763... Line 662...
763
	    dp_info->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)
662
	    dp_info->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)
764
		tmp |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
663
		tmp |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
765
	radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LANE_COUNT_SET, tmp);
664
	radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LANE_COUNT_SET, tmp);
Line 766... Line 665...
766
 
665
 
767
	/* set the link rate on the sink */
666
	/* set the link rate on the sink */
768
	tmp = dp_get_dp_link_rate_coded(dp_info->dp_clock);
667
	tmp = drm_dp_link_rate_to_bw_code(dp_info->dp_clock);
Line 769... Line 668...
769
	radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LINK_BW_SET, tmp);
668
	radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LINK_BW_SET, tmp);
770
 
669
 
771
	/* start training on the source */
670
	/* start training on the source */
Line 819... Line 718...
819
	/* clock recovery loop */
718
	/* clock recovery loop */
820
	clock_recovery = false;
719
	clock_recovery = false;
821
	dp_info->tries = 0;
720
	dp_info->tries = 0;
822
	voltage = 0xff;
721
	voltage = 0xff;
823
	while (1) {
722
	while (1) {
824
		if (dp_info->rd_interval == 0)
-
 
825
		udelay(100);
-
 
826
		else
-
 
827
			mdelay(dp_info->rd_interval * 4);
723
		drm_dp_link_train_clock_recovery_delay(dp_info->dpcd);
Line 828... Line 724...
828
 
724
 
829
		if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) {
725
		if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) {
830
			DRM_ERROR("displayport link status failed\n");
726
			DRM_ERROR("displayport link status failed\n");
831
			break;
727
			break;
Line 832... Line 728...
832
		}
728
		}
833
 
729
 
834
		if (dp_clock_recovery_ok(dp_info->link_status, dp_info->dp_lane_count)) {
730
		if (drm_dp_clock_recovery_ok(dp_info->link_status, dp_info->dp_lane_count)) {
835
			clock_recovery = true;
731
			clock_recovery = true;
Line 836... Line 732...
836
			break;
732
			break;
Line 884... Line 780...
884
 
780
 
885
	/* channel equalization loop */
781
	/* channel equalization loop */
886
	dp_info->tries = 0;
782
	dp_info->tries = 0;
887
	channel_eq = false;
783
	channel_eq = false;
888
	while (1) {
-
 
889
		if (dp_info->rd_interval == 0)
-
 
890
		udelay(400);
-
 
891
		else
784
	while (1) {
Line 892... Line 785...
892
			mdelay(dp_info->rd_interval * 4);
785
		drm_dp_link_train_channel_eq_delay(dp_info->dpcd);
893
 
786
 
894
		if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) {
787
		if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) {
895
			DRM_ERROR("displayport link status failed\n");
788
			DRM_ERROR("displayport link status failed\n");
Line 896... Line 789...
896
			break;
789
			break;
897
		}
790
		}
898
 
791
 
899
		if (dp_channel_eq_ok(dp_info->link_status, dp_info->dp_lane_count)) {
792
		if (drm_dp_channel_eq_ok(dp_info->link_status, dp_info->dp_lane_count)) {
Line 900... Line 793...
900
			channel_eq = true;
793
			channel_eq = true;
Line 972... Line 865...
972
	if (dig->linkb)
865
	if (dig->linkb)
973
		dp_info.enc_id |= ATOM_DP_CONFIG_LINK_B;
866
		dp_info.enc_id |= ATOM_DP_CONFIG_LINK_B;
974
	else
867
	else
975
		dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A;
868
		dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A;
Line 976... Line -...
976
 
-
 
977
	dp_info.rd_interval = radeon_read_dpcd_reg(radeon_connector, DP_TRAINING_AUX_RD_INTERVAL);
869
 
978
	tmp = radeon_read_dpcd_reg(radeon_connector, DP_MAX_LANE_COUNT);
870
	tmp = radeon_read_dpcd_reg(radeon_connector, DP_MAX_LANE_COUNT);
979
	if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
871
	if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
980
		dp_info.tp3_supported = true;
872
		dp_info.tp3_supported = true;
981
	else
873
	else
Line 982... Line 874...
982
		dp_info.tp3_supported = false;
874
		dp_info.tp3_supported = false;
983
 
875
 
984
	memcpy(dp_info.dpcd, dig_connector->dpcd, 8);
876
	memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE);
985
	dp_info.rdev = rdev;
877
	dp_info.rdev = rdev;
986
	dp_info.encoder = encoder;
878
	dp_info.encoder = encoder;
987
	dp_info.connector = connector;
879
	dp_info.connector = connector;