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. 2
0
int drm_load_edid_firmware(struct drm_connector *connector)
{
	const char *connector_name = connector->name;
	char *edidname = edid_firmware, *last, *colon;
	int ret;
	struct edid *edid;

	if (*edidname == '\0')
		return 0;

	colon = strchr(edidname, ':');
	if (colon != NULL) {
		if (strncmp(connector_name, edidname, colon - edidname))
			return 0;
		edidname = colon + 1;
		if (*edidname == '\0')
			return 0;
	}

	last = edidname + strlen(edidname) - 1;
	if (*last == '\n')
		*last = '\0';

	edid = edid_load(connector, edidname, connector_name);
	if (IS_ERR_OR_NULL(edid))
		return 0;

	drm_mode_connector_update_edid_property(connector, edid);
	ret = drm_add_edid_modes(connector, edid);
	drm_edid_to_eld(connector, edid);
	kfree(edid);

	return ret;
}
Esempio n. 3
0
int
tegra_drm_connector_get_modes(struct drm_connector *connector)
{
	struct tegra_drm_encoder *output;
	struct edid *edid = NULL;
	int rv;

	output = container_of(connector, struct tegra_drm_encoder,
	     connector);

	/* Panel is first */
	if (output->panel != NULL) {
		/* XXX panel parsing */
		return (0);
	}

	/* static EDID is second*/
	edid = output->edid;

	/* EDID from monitor is last */
	if (edid == NULL)
		edid = drm_get_edid(connector, output->ddc);

	if (edid == NULL)
		return (0);

	/* Process EDID */
	drm_mode_connector_update_edid_property(connector, edid);
	rv = drm_add_edid_modes(connector, edid);
	drm_edid_to_eld(connector, edid);
	return (rv);
}
Esempio n. 4
0
int drm_load_edid_firmware(struct drm_connector *connector)
{
	const char *connector_name = connector->name;
	char *edidname, *last, *colon, *fwstr, *edidstr, *fallback = NULL;
	int ret;
	struct edid *edid;

	if (edid_firmware[0] == '\0')
		return 0;

	/*
	 * If there are multiple edid files specified and separated
	 * by commas, search through the list looking for one that
	 * matches the connector.
	 *
	 * If there's one or more that don't't specify a connector, keep
	 * the last one found one as a fallback.
	 */
	fwstr = kstrdup(edid_firmware, GFP_KERNEL);
	edidstr = fwstr;

	while ((edidname = strsep(&edidstr, ","))) {
		colon = strchr(edidname, ':');
		if (colon != NULL) {
			if (strncmp(connector_name, edidname, colon - edidname))
				continue;
			edidname = colon + 1;
			break;
		}

		if (*edidname != '\0') /* corner case: multiple ',' */
			fallback = edidname;
	}

	if (!edidname) {
		if (!fallback) {
			kfree(fwstr);
			return 0;
		}
		edidname = fallback;
	}

	last = edidname + strlen(edidname) - 1;
	if (*last == '\n')
		*last = '\0';

	edid = edid_load(connector, edidname, connector_name);
	kfree(fwstr);

	if (IS_ERR_OR_NULL(edid))
		return 0;

	drm_mode_connector_update_edid_property(connector, edid);
	ret = drm_add_edid_modes(connector, edid);
	drm_edid_to_eld(connector, edid);
	kfree(edid);

	return ret;
}
Esempio n. 5
0
/**
 * intel_connector_update_modes - update connector from edid
 * @connector: DRM connector device to use
 * @edid: previously read EDID information
 */
int intel_connector_update_modes(struct drm_connector *connector,
				struct edid *edid)
{
	int ret;

	drm_mode_connector_update_edid_property(connector, edid);
	ret = drm_add_edid_modes(connector, edid);
	drm_edid_to_eld(connector, edid);

	return ret;
}
/**
 * intel_connector_update_modes - update connector from edid
 * @connector: DRM connector device to use
 * @edid: previously read EDID information
 */
int intel_connector_update_modes(struct drm_connector *connector,
				struct edid *edid)
{
	int ret;

	drm_mode_connector_update_edid_property(connector, edid);
	ret = drm_add_edid_modes(connector, edid);
	drm_edid_to_eld(connector, edid);
	connector->display_info.raw_edid = NULL;
	kfree(edid);

	return ret;
}
Esempio n. 7
0
/**
 * intel_ddc_get_modes - get modelist from monitor
 * @connector: DRM connector device to use
 * @adapter: i2c adapter
 *
 * Fetch the EDID information from @connector using the DDC bus.
 */
int intel_ddc_get_modes(struct drm_connector *connector,
			struct i2c_adapter *adapter)
{
	struct edid *edid;
	int ret = 0;

	edid = drm_get_edid(connector, adapter);
	if (edid) {
		drm_mode_connector_update_edid_property(connector, edid);
		ret = drm_add_edid_modes(connector, edid);
		drm_edid_to_eld(connector, edid);
		connector->display_info.raw_edid = NULL;
		kfree(edid);
	}

	return ret;
}