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

Commit 9340d77f authored by Ilia Mirkin's avatar Ilia Mirkin Committed by Ben Skeggs
Browse files

drm/nouveau/disp: take sink support into account for exposing 594mhz



Scrambling is required for supporting any mode over 340MHz. If it's not
supported, reject any modes that would require it.

Signed-off-by: default avatarIlia Mirkin <imirkin@alum.mit.edu>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 7a406f8a
Loading
Loading
Loading
Loading
+22 −12
Original line number Diff line number Diff line
@@ -969,18 +969,33 @@ nouveau_connector_get_modes(struct drm_connector *connector)
}

static unsigned
get_tmds_link_bandwidth(struct drm_connector *connector, bool hdmi)
get_tmds_link_bandwidth(struct drm_connector *connector)
{
	struct nouveau_connector *nv_connector = nouveau_connector(connector);
	struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
	struct nouveau_drm *drm = nouveau_drm(connector->dev);
	struct dcb_output *dcb = nv_connector->detected_encoder->dcb;
	struct drm_display_info *info = NULL;
	const unsigned duallink_scale =
		nouveau_duallink && nv_encoder->dcb->duallink_possible ? 2 : 1;

	if (drm_detect_hdmi_monitor(nv_connector->edid))
		info = &nv_connector->base.display_info;

	if (hdmi) {
	if (info) {
		if (nouveau_hdmimhz > 0)
			return nouveau_hdmimhz * 1000;
		/* Note: these limits are conservative, some Fermi's
		 * can do 297 MHz. Unclear how this can be determined.
		 */
		if (drm->client.device.info.chipset >= 0x120) {
			const int max_tmds_clock =
				info->hdmi.scdc.scrambling.supported ?
				594000 : 340000;
			return info->max_tmds_clock ?
				min(info->max_tmds_clock, max_tmds_clock) :
				max_tmds_clock;
		}
		if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_KEPLER)
			return 297000;
		if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_FERMI)
@@ -988,13 +1003,13 @@ get_tmds_link_bandwidth(struct drm_connector *connector, bool hdmi)
	}
	if (dcb->location != DCB_LOC_ON_CHIP ||
	    drm->client.device.info.chipset >= 0x46)
		return 165000;
		return 165000 * duallink_scale;
	else if (drm->client.device.info.chipset >= 0x40)
		return 155000;
		return 155000 * duallink_scale;
	else if (drm->client.device.info.chipset >= 0x18)
		return 135000;
		return 135000 * duallink_scale;
	else
		return 112000;
		return 112000 * duallink_scale;
}

static enum drm_mode_status
@@ -1006,7 +1021,6 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
	struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
	unsigned min_clock = 25000, max_clock = min_clock;
	unsigned clock = mode->clock;
	bool hdmi;

	switch (nv_encoder->dcb->type) {
	case DCB_OUTPUT_LVDS:
@@ -1019,11 +1033,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
		max_clock = 400000;
		break;
	case DCB_OUTPUT_TMDS:
		hdmi = drm_detect_hdmi_monitor(nv_connector->edid);
		max_clock = get_tmds_link_bandwidth(connector, hdmi);
		if (!hdmi && nouveau_duallink &&
		    nv_encoder->dcb->duallink_possible)
			max_clock *= 2;
		max_clock = get_tmds_link_bandwidth(connector);
		break;
	case DCB_OUTPUT_ANALOG:
		max_clock = nv_encoder->dcb->crtconf.maxfreq;