static enum drm_connector_status cdv_hdmi_detect(
				struct drm_connector *connector, bool force)
{
	struct psb_intel_encoder *psb_intel_encoder =
					psb_intel_attached_encoder(connector);
	struct psb_intel_connector *psb_intel_connector =
					to_psb_intel_connector(connector);
	struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv;
	struct edid *edid = NULL;
	enum drm_connector_status status = connector_status_disconnected;

	edid = drm_get_edid(connector, &psb_intel_encoder->i2c_bus->adapter);

	hdmi_priv->has_hdmi_sink = false;
	hdmi_priv->has_hdmi_audio = false;
	if (edid) {
		if (edid->input & DRM_EDID_INPUT_DIGITAL) {
			status = connector_status_connected;
			hdmi_priv->has_hdmi_sink =
						drm_detect_hdmi_monitor(edid);
			hdmi_priv->has_hdmi_audio =
						drm_detect_monitor_audio(edid);
		}

		psb_intel_connector->base.display_info.raw_edid = NULL;
		kfree(edid);
	}
	return status;
}
static void
nouveau_audio_mode_set(struct drm_encoder *encoder,
		       struct drm_display_mode *mode)
{
	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
	struct nouveau_connector *nv_connector;
	struct drm_device *dev = encoder->dev;
	u32 or = nv_encoder->or * 0x800;
	int i;

	nv_connector = nouveau_encoder_connector_get(nv_encoder);
	if (!drm_detect_monitor_audio(nv_connector->edid)) {
		nouveau_audio_disconnect(encoder);
		return;
	}

	if (hdmi_sor(encoder)) {
		nv_mask(dev, 0x61c448 + or, 0x00000001, 0x00000001);

		drm_edid_to_eld(&nv_connector->base, nv_connector->edid);
		if (nv_connector->base.eld[0]) {
			u8 *eld = nv_connector->base.eld;
			for (i = 0; i < eld[2] * 4; i++)
				nv_wr32(dev, 0x61c440 + or, (i << 8) | eld[i]);
			for (i = eld[2] * 4; i < 0x60; i++)
				nv_wr32(dev, 0x61c440 + or, (i << 8) | 0x00);
			nv_mask(dev, 0x61c448 + or, 0x00000002, 0x00000002);
		}
	}
}
Esempio n. 3
0
static enum drm_connector_status
intel_hdmi_detect(struct drm_connector *connector, bool force)
{
	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
	struct drm_i915_private *dev_priv = connector->dev->dev_private;
	struct edid *edid;
	enum drm_connector_status status = connector_status_disconnected;

	intel_hdmi->has_hdmi_sink = false;
	intel_hdmi->has_audio = false;
	edid = drm_get_edid(connector,
			    intel_gmbus_get_adapter(dev_priv,
						    intel_hdmi->ddc_bus));

	if (edid) {
		if (edid->input & DRM_EDID_INPUT_DIGITAL) {
			status = connector_status_connected;
			if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI)
				intel_hdmi->has_hdmi_sink =
						drm_detect_hdmi_monitor(edid);
			intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
		}
		kfree(edid);
	}

	if (status == connector_status_connected) {
		if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO)
			intel_hdmi->has_audio =
				(intel_hdmi->force_audio == HDMI_AUDIO_ON);
	}

	return status;
}
Esempio n. 4
0
void evergreen_dp_enable(struct drm_encoder *encoder, bool enable)
{
	struct drm_device *dev = encoder->dev;
	struct radeon_device *rdev = dev->dev_private;
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
	struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);

	if (!dig || !dig->afmt)
		return;

	if (enable && drm_detect_monitor_audio(radeon_connector_edid(connector))) {
		struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
		struct radeon_connector_atom_dig *dig_connector;
		uint32_t val;

		WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + dig->afmt->offset,
			  AFMT_AUDIO_SAMPLE_SEND);

		WREG32(EVERGREEN_DP_SEC_TIMESTAMP + dig->afmt->offset,
		       EVERGREEN_DP_SEC_TIMESTAMP_MODE(1));

		if (!ASIC_IS_DCE6(rdev) && radeon_connector->con_priv) {
			dig_connector = radeon_connector->con_priv;
			val = RREG32(EVERGREEN_DP_SEC_AUD_N + dig->afmt->offset);
			val &= ~EVERGREEN_DP_SEC_N_BASE_MULTIPLE(0xf);

			if (dig_connector->dp_clock == 162000)
				val |= EVERGREEN_DP_SEC_N_BASE_MULTIPLE(3);
			else
				val |= EVERGREEN_DP_SEC_N_BASE_MULTIPLE(5);

			WREG32(EVERGREEN_DP_SEC_AUD_N + dig->afmt->offset, val);
		}

		WREG32(EVERGREEN_DP_SEC_CNTL + dig->afmt->offset,
			EVERGREEN_DP_SEC_ASP_ENABLE |		/* Audio packet transmission */
			EVERGREEN_DP_SEC_ATP_ENABLE |		/* Audio timestamp packet transmission */
			EVERGREEN_DP_SEC_AIP_ENABLE |		/* Audio infoframe packet transmission */
			EVERGREEN_DP_SEC_STREAM_ENABLE);	/* Master enable for secondary stream engine */
	} else {
		WREG32(EVERGREEN_DP_SEC_CNTL + dig->afmt->offset, 0);
		WREG32_AND(AFMT_AUDIO_PACKET_CONTROL + dig->afmt->offset,
			   ~AFMT_AUDIO_SAMPLE_SEND);
	}

	dig->afmt->enabled = enable;
}
Esempio n. 5
0
static enum drm_connector_status
intel_hdmi_detect(struct drm_connector *connector, bool force)
{
	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
	struct drm_i915_private *dev_priv = connector->dev->dev_private;
	struct edid *edid;
	enum drm_connector_status status = connector_status_disconnected;

	if (IS_G4X(connector->dev) && !g4x_hdmi_connected(intel_hdmi))
		return status;
#if 0
        /* HOTPLUG Detect is not working in some of VLV A0
         * boards. For those boards enable this WA
         */
	if (IS_VALLEYVIEW(connector->dev))
		return connector_status_connected;
#endif

	intel_hdmi->has_hdmi_sink = false;
	intel_hdmi->has_audio = false;
	edid = drm_get_edid(connector,
			    intel_gmbus_get_adapter(dev_priv,
						    intel_hdmi->ddc_bus));

	if (edid) {
		if (edid->input & DRM_EDID_INPUT_DIGITAL) {
			status = connector_status_connected;
			if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI)
				intel_hdmi->has_hdmi_sink =
						drm_detect_hdmi_monitor(edid);
			intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
		}
		connector->display_info.raw_edid = NULL;
		kfree(edid);
	}

	if (status == connector_status_connected) {
		if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO)
			intel_hdmi->has_audio =
				(intel_hdmi->force_audio == HDMI_AUDIO_ON);
	}

	return status;
}
Esempio n. 6
0
static enum drm_connector_status
intel_hdmi_detect(struct drm_connector *connector, bool force)
{
	struct drm_device *dev = connector->dev;
	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
	struct intel_digital_port *intel_dig_port =
		hdmi_to_dig_port(intel_hdmi);
	struct intel_encoder *intel_encoder = &intel_dig_port->base;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct edid *edid;
	enum drm_connector_status status = connector_status_disconnected;

	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
		      connector->base.id, drm_get_connector_name(connector));

	intel_hdmi->has_hdmi_sink = false;
	intel_hdmi->has_audio = false;
	intel_hdmi->rgb_quant_range_selectable = false;
	edid = drm_get_edid(connector,
			    intel_gmbus_get_adapter(dev_priv,
						    intel_hdmi->ddc_bus));

	if (edid) {
		if (edid->input & DRM_EDID_INPUT_DIGITAL) {
			status = connector_status_connected;
			if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI)
				intel_hdmi->has_hdmi_sink =
						drm_detect_hdmi_monitor(edid);
			intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
			intel_hdmi->rgb_quant_range_selectable =
				drm_rgb_quant_range_selectable(edid);
		}
		kfree(edid);
	}

	if (status == connector_status_connected) {
		if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO)
			intel_hdmi->has_audio =
				(intel_hdmi->force_audio == HDMI_AUDIO_ON);
		intel_encoder->type = INTEL_OUTPUT_HDMI;
	}

	return status;
}
Esempio n. 7
0
static bool
intel_hdmi_detect_audio(struct drm_connector *connector)
{
	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
	struct drm_i915_private *dev_priv = connector->dev->dev_private;
	struct edid *edid;
	bool has_audio = false;

	edid = drm_get_edid(connector,
			    intel_gmbus_get_adapter(dev_priv,
						    intel_hdmi->ddc_bus));
	if (edid) {
		if (edid->input & DRM_EDID_INPUT_DIGITAL)
			has_audio = drm_detect_monitor_audio(edid);
		kfree(edid);
	}

	return has_audio;
}
Esempio n. 8
0
static enum drm_connector_status
intel_hdmi_detect(struct drm_connector *connector, bool force)
{
	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
	struct intel_digital_port *intel_dig_port =
		hdmi_to_dig_port(intel_hdmi);
	struct intel_encoder *intel_encoder = &intel_dig_port->base;
	struct drm_i915_private *dev_priv = connector->dev->dev_private;
	struct edid *edid;
	enum drm_connector_status status = connector_status_disconnected;

	if (IS_G4X(connector->dev) && !g4x_hdmi_connected(intel_hdmi))
		return status;

	intel_hdmi->has_hdmi_sink = false;
	intel_hdmi->has_audio = false;
	edid = drm_get_edid(connector,
			    intel_gmbus_get_adapter(dev_priv,
						    intel_hdmi->ddc_bus));

	if (edid) {
		if (edid->input & DRM_EDID_INPUT_DIGITAL) {
			status = connector_status_connected;
			if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI)
				intel_hdmi->has_hdmi_sink =
						drm_detect_hdmi_monitor(edid);
			intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
		}
		free(edid, DRM_MEM_KMS);
	}

	if (status == connector_status_connected) {
		if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO)
			intel_hdmi->has_audio =
				(intel_hdmi->force_audio == HDMI_AUDIO_ON);
		intel_encoder->type = INTEL_OUTPUT_HDMI;
	}

	return status;
}
Esempio n. 9
0
void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable)
{
	struct drm_device *dev = encoder->dev;
	struct radeon_device *rdev = dev->dev_private;
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;

	if (!dig || !dig->afmt)
		return;

	if (enable) {
		struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);

		if (drm_detect_monitor_audio(radeon_connector_edid(connector))) {
			WREG32(HDMI_INFOFRAME_CONTROL0 + dig->afmt->offset,
			       HDMI_AVI_INFO_SEND | /* enable AVI info frames */
			       HDMI_AVI_INFO_CONT | /* required for audio info values to be updated */
			       HDMI_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */
			       HDMI_AUDIO_INFO_CONT); /* required for audio info values to be updated */
			WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + dig->afmt->offset,
				  AFMT_AUDIO_SAMPLE_SEND);
		} else {
			WREG32(HDMI_INFOFRAME_CONTROL0 + dig->afmt->offset,
			       HDMI_AVI_INFO_SEND | /* enable AVI info frames */
			       HDMI_AVI_INFO_CONT); /* required for audio info values to be updated */
			WREG32_AND(AFMT_AUDIO_PACKET_CONTROL + dig->afmt->offset,
				   ~AFMT_AUDIO_SAMPLE_SEND);
		}
	} else {
		WREG32_AND(AFMT_AUDIO_PACKET_CONTROL + dig->afmt->offset,
			   ~AFMT_AUDIO_SAMPLE_SEND);
		WREG32(HDMI_INFOFRAME_CONTROL0 + dig->afmt->offset, 0);
	}

	dig->afmt->enabled = enable;

	DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n",
		  enable ? "En" : "Dis", dig->afmt->offset, radeon_encoder->encoder_id);
}