Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f92a8b67 authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie
Browse files

drm/radeon/kms: handle dp sinks in atom encoder/transmitter tables

parent 4143e919
Loading
Loading
Loading
Loading
+69 −0
Original line number Diff line number Diff line
@@ -33,6 +33,75 @@

#define DP_LINK_STATUS_SIZE	6

/* move these to drm_dp_helper.c/h */

static const int dp_clocks[] = {
	54000,  // 1 lane, 1.62 Ghz
	90000,  // 1 lane, 2.70 Ghz
	108000, // 2 lane, 1.62 Ghz
	180000, // 2 lane, 2.70 Ghz
	216000, // 4 lane, 1.62 Ghz
	360000, // 4 lane, 2.70 Ghz
};

static const int num_dp_clocks = sizeof(dp_clocks) / sizeof(int);

int dp_lanes_for_mode_clock(int max_link_bw, int mode_clock)
{
	int i;

	switch (max_link_bw) {
	case DP_LINK_BW_1_62:
	default:
		for (i = 0; i < num_dp_clocks; i++) {
			if (i % 2)
				continue;
			if (dp_clocks[i] > mode_clock) {
				if (i < 2)
					return 1;
				else if (i < 4)
					return 2;
				else
					return 4;
			}
		}
		break;
	case DP_LINK_BW_2_7:
		for (i = 0; i < num_dp_clocks; i++) {
			if (dp_clocks[i] > mode_clock) {
				if (i < 2)
					return 1;
				else if (i < 4)
					return 2;
				else
					return 4;
			}
		}
		break;
	}

	return 0;
}

int dp_link_clock_for_mode_clock(int max_link_bw, int mode_clock)
{
	int i;

	switch (max_link_bw) {
	case DP_LINK_BW_1_62:
	default:
		return 162000;
		break;
	case DP_LINK_BW_2_7:
		for (i = 0; i < num_dp_clocks; i++) {
			if (dp_clocks[i] > mode_clock)
				return (i % 2) ? 270000 : 162000;
		}
	}

	return 0;
}

bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
			   int num_bytes, u8 *read_byte,
			   u8 read_buf_len, u8 delay)
+29 −12
Original line number Diff line number Diff line
@@ -554,6 +554,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
{
	struct drm_connector *connector;
	struct radeon_connector *radeon_connector;
	struct radeon_connector_atom_dig *radeon_dig_connector;

	connector = radeon_get_connector_for_encoder(encoder);
	if (!connector)
@@ -583,10 +584,10 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
		return ATOM_ENCODER_MODE_LVDS;
		break;
	case DRM_MODE_CONNECTOR_DisplayPort:
		/*if (radeon_output->MonType == MT_DP)
		radeon_dig_connector = radeon_connector->con_priv;
		if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT)
			return ATOM_ENCODER_MODE_DP;
		  else*/
		if (drm_detect_hdmi_monitor(radeon_connector->edid))
		else if (drm_detect_hdmi_monitor(radeon_connector->edid))
			return ATOM_ENCODER_MODE_HDMI;
		else
			return ATOM_ENCODER_MODE_DVI;
@@ -715,7 +716,15 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
		}
	}

	if (radeon_encoder->pixel_clock > 165000)
	args.ucEncoderMode = atombios_get_encoder_mode(encoder);

	if (args.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
		if (dp_link_clock_for_mode_clock(dig_connector->dpcd[1],
						 radeon_encoder->pixel_clock) == 270000)
			args.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
		args.ucLaneNum = dp_lanes_for_mode_clock(dig_connector->dpcd[1],
							 radeon_encoder->pixel_clock);
	} else if (radeon_encoder->pixel_clock > 165000)
		args.ucLaneNum = 8;
	else
		args.ucLaneNum = 4;
@@ -725,8 +734,6 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
	else
		args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;

	args.ucEncoderMode = atombios_get_encoder_mode(encoder);

	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);

}
@@ -749,6 +756,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
	struct drm_connector *connector;
	struct radeon_connector *radeon_connector;
	struct radeon_connector_atom_dig *dig_connector;
	bool is_dp = false;

	connector = radeon_get_connector_for_encoder(encoder);
	if (!connector)
@@ -766,6 +774,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t

	dig_connector = radeon_connector->con_priv;

	if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP)
		is_dp = true;

	memset(&args, 0, sizeof(args));

	if (ASIC_IS_DCE32(rdev))
@@ -790,14 +801,16 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
		args.v1.asMode.ucLaneSel = lane_num;
		args.v1.asMode.ucLaneSet = lane_set;
	} else {
		if (radeon_encoder->pixel_clock > 165000)
		if (is_dp)
			args.v1.usPixelClock =
				cpu_to_le16(dp_link_clock_for_mode_clock(dig_connector->dpcd[1],
									 radeon_encoder->pixel_clock) / 10);
		else if (radeon_encoder->pixel_clock > 165000)
			args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
		else
			args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
	}
	if (ASIC_IS_DCE32(rdev)) {
		if (radeon_encoder->pixel_clock > 165000)
			args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
		if (dig->dig_block)
			args.v2.acConfig.ucEncoderSel = 1;
		if (dig_connector->linkb)
@@ -818,7 +831,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
			break;
		}

		if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
		if (is_dp)
			args.v2.acConfig.fCoherentMode = 1;
		else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
			if (dig->coherent_mode)
				args.v2.acConfig.fCoherentMode = 1;
		}
@@ -866,7 +881,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
		else
			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;

		if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
		if (is_dp)
			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
		else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
			if (dig->coherent_mode)
				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
		}
+2 −0
Original line number Diff line number Diff line
@@ -366,6 +366,8 @@ struct radeon_framebuffer {
	struct drm_gem_object *obj;
};

extern int dp_lanes_for_mode_clock(int max_link_bw, int mode_clock);
extern int dp_link_clock_for_mode_clock(int max_link_bw, int mode_clock);
extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
extern void radeon_dp_getdpcd(struct radeon_connector *radeon_connector);
extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,