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

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

drm/radeon/kms: improve bpc handling (v2)



Improve handling of bpc (bits per color) in radeon.
In most cases we want 8 except for HDMI, DP, LVDS, and eDP.

v2: handle DP better.

Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Tested-by: default avatarLennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 9923777d
Loading
Loading
Loading
Loading
+2 −5
Original line number Diff line number Diff line
@@ -588,8 +588,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
		if (encoder->crtc == crtc) {
			radeon_encoder = to_radeon_encoder(encoder);
			connector = radeon_get_connector_for_encoder(encoder);
			/* if (connector && connector->display_info.bpc)
				bpc = connector->display_info.bpc; */
			bpc = radeon_get_monitor_bpc(connector);
			encoder_mode = atombios_get_encoder_mode(encoder);
			is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock);
			if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
@@ -965,9 +964,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
		struct radeon_connector_atom_dig *dig_connector =
			radeon_connector->con_priv;
		int dp_clock;

		/* if (connector->display_info.bpc)
			bpc = connector->display_info.bpc; */
		bpc = radeon_get_monitor_bpc(connector);

		switch (encoder_mode) {
		case ATOM_ENCODER_MODE_DP_MST:
+2 −5
Original line number Diff line number Diff line
@@ -405,13 +405,10 @@ static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE],
/* get bpc from the EDID */
static int convert_bpc_to_bpp(int bpc)
{
#if 0
	if (bpc == 0)
		return 24;
	else
		return bpc * 3;
#endif
	return 24;
}

/* get the max pix clock supported by the link rate and lane num */
@@ -463,7 +460,7 @@ static int radeon_dp_get_dp_lane_number(struct drm_connector *connector,
					u8 dpcd[DP_DPCD_SIZE],
					int pix_clock)
{
	int bpp = convert_bpc_to_bpp(connector->display_info.bpc);
	int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector));
	int max_link_rate = dp_get_max_link_rate(dpcd);
	int max_lane_num = dp_get_max_lane_number(dpcd);
	int lane_num;
@@ -482,7 +479,7 @@ static int radeon_dp_get_dp_link_clock(struct drm_connector *connector,
				       u8 dpcd[DP_DPCD_SIZE],
				       int pix_clock)
{
	int bpp = convert_bpc_to_bpp(connector->display_info.bpc);
	int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector));
	int lane_num, max_pix_clock;

	if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
+2 −2
Original line number Diff line number Diff line
@@ -541,7 +541,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
		dp_clock = dig_connector->dp_clock;
		dp_lane_count = dig_connector->dp_lane_count;
		hpd_id = radeon_connector->hpd.hpd;
		/* bpc = connector->display_info.bpc; */
		bpc = radeon_get_monitor_bpc(connector);
	}

	/* no dig encoder assigned */
@@ -1159,7 +1159,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
		dp_lane_count = dig_connector->dp_lane_count;
		connector_object_id =
			(radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
		/* bpc = connector->display_info.bpc; */
		bpc = radeon_get_monitor_bpc(connector);
	}

	memset(&args, 0, sizeof(args));
+56 −0
Original line number Diff line number Diff line
@@ -84,6 +84,62 @@ static void radeon_property_change_mode(struct drm_encoder *encoder)
					 crtc->x, crtc->y, crtc->fb);
	}
}

int radeon_get_monitor_bpc(struct drm_connector *connector)
{
	struct drm_device *dev = connector->dev;
	struct radeon_device *rdev = dev->dev_private;
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
	struct radeon_connector_atom_dig *dig_connector;
	int bpc = 8;

	switch (connector->connector_type) {
	case DRM_MODE_CONNECTOR_DVII:
	case DRM_MODE_CONNECTOR_HDMIB:
		if (radeon_connector->use_digital) {
			if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
				if (connector->display_info.bpc)
					bpc = connector->display_info.bpc;
			}
		}
		break;
	case DRM_MODE_CONNECTOR_DVID:
	case DRM_MODE_CONNECTOR_HDMIA:
		if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
			if (connector->display_info.bpc)
				bpc = connector->display_info.bpc;
		}
		break;
	case DRM_MODE_CONNECTOR_DisplayPort:
		dig_connector = radeon_connector->con_priv;
		if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
		    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) ||
		    drm_detect_hdmi_monitor(radeon_connector->edid)) {
			if (connector->display_info.bpc)
				bpc = connector->display_info.bpc;
		}
		break;
	case DRM_MODE_CONNECTOR_eDP:
	case DRM_MODE_CONNECTOR_LVDS:
		if (connector->display_info.bpc)
			bpc = connector->display_info.bpc;
		else if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
			struct drm_connector_helper_funcs *connector_funcs =
				connector->helper_private;
			struct drm_encoder *encoder = connector_funcs->best_encoder(connector);
			struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
			struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;

			if (dig->lcd_misc & ATOM_PANEL_MISC_V13_6BIT_PER_COLOR)
				bpc = 6;
			else if (dig->lcd_misc & ATOM_PANEL_MISC_V13_8BIT_PER_COLOR)
				bpc = 8;
		}
		break;
	}
	return bpc;
}

static void
radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_connector_status status)
{
+1 −0
Original line number Diff line number Diff line
@@ -476,6 +476,7 @@ extern u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder);
extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector);
extern bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector);
extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector);
extern int radeon_get_monitor_bpc(struct drm_connector *connector);

extern void radeon_connector_hotplug(struct drm_connector *connector);
extern int radeon_dp_mode_valid_helper(struct drm_connector *connector,