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;
}
Esempio n. 2
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. 3
0
static int analogix_dp_get_modes(struct drm_connector *connector)
{
	struct analogix_dp_device *dp = to_dp(connector);
	struct edid *edid;
	int ret, num_modes = 0;

	if (dp->plat_data->panel) {
		num_modes += drm_panel_get_modes(dp->plat_data->panel);
	} else {
		ret = analogix_dp_prepare_panel(dp, true, false);
		if (ret) {
			DRM_ERROR("Failed to prepare panel (%d)\n", ret);
			return 0;
		}

		edid = drm_get_edid(connector, &dp->aux.ddc);
		if (edid) {
			drm_mode_connector_update_edid_property(&dp->connector,
								edid);
			num_modes += drm_add_edid_modes(&dp->connector, edid);
			kfree(edid);
		}

		ret = analogix_dp_prepare_panel(dp, false, false);
		if (ret)
			DRM_ERROR("Failed to unprepare panel (%d)\n", ret);
	}

	if (dp->plat_data->get_modes)
		num_modes += dp->plat_data->get_modes(dp->plat_data, connector);

	return num_modes;
}
Esempio n. 4
0
static int tegra_connector_get_modes(struct drm_connector *connector)
{
	struct tegra_output *output = connector_to_output(connector);
	struct edid *edid = NULL;
	int err = 0;

	/*
	 * If the panel provides one or more modes, use them exclusively and
	 * ignore any other means of obtaining a mode.
	 */
	if (output->panel) {
		err = output->panel->funcs->get_modes(output->panel);
		if (err > 0)
			return err;
	}

	if (output->edid)
		edid = kmemdup(output->edid, sizeof(*edid), GFP_KERNEL);
	else if (output->ddc)
		edid = drm_get_edid(connector, output->ddc);

	drm_mode_connector_update_edid_property(connector, edid);

	if (edid) {
		err = drm_add_edid_modes(connector, edid);
		kfree(edid);
	}

	return err;
}
Esempio n. 5
0
static int msm_hdmi_connector_get_modes(struct drm_connector *connector)
{
	struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
	struct hdmi *hdmi = hdmi_connector->hdmi;
	struct edid *edid;
	uint32_t hdmi_ctrl;
	int ret = 0;

	hdmi_ctrl = hdmi_read(hdmi, REG_HDMI_CTRL);
	hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl | HDMI_CTRL_ENABLE);

	edid = drm_get_edid(connector, hdmi->i2c);

	hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl);

	hdmi->hdmi_mode = drm_detect_hdmi_monitor(edid);
	drm_connector_update_edid_property(connector, edid);

	if (edid) {
		ret = drm_add_edid_modes(connector, edid);
		kfree(edid);
	}

	return ret;
}
Esempio n. 6
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);
}
/**
 * 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;

	edid = drm_get_edid(connector, adapter);
	if (!edid)
		return 0;

	return intel_connector_update_modes(connector, edid);
}
Esempio n. 8
0
/*
 * Return the list of HDMI DDC modes if available.
 */
static int cdv_hdmi_get_modes(struct drm_connector *connector)
{
	struct gma_encoder *gma_encoder = gma_attached_encoder(connector);
	struct edid *edid = NULL;
	int ret = 0;

	edid = drm_get_edid(connector, &gma_encoder->i2c_bus->adapter);
	if (edid) {
		drm_mode_connector_update_edid_property(connector, edid);
		ret = drm_add_edid_modes(connector, edid);
		kfree(edid);
	}
	return ret;
}
Esempio n. 9
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,
			device_t adapter)
{
	struct edid *edid;
	int ret;

	edid = drm_get_edid(connector, adapter);
	if (!edid)
		return 0;

	ret = intel_connector_update_modes(connector, edid);
	kfree(edid);

	return ret;
}
Esempio n. 10
0
static void
intel_hdmi_sink_detect(struct drm_connector *connector)
{
	struct intel_output *intel_output = to_intel_output(connector);
	struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
	struct edid *edid = NULL;

	edid = drm_get_edid(&intel_output->base,
			    &intel_output->ddc_bus->adapter);
	if (edid != NULL) {
		hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
		kfree(edid);
		intel_output->base.display_info.raw_edid = NULL;
	}
}
Esempio n. 11
0
static int CRTConnectorHelperGetModes(struct drm_connector *psConnector)
{
	PVRPSB_CONNECTOR *psPVRConnector	= to_pvr_connector(psConnector);
	struct i2c_adapter *psAdapter		= psPVRConnector->psAdapter;
	struct edid *psEdid;

	psEdid = drm_get_edid(psConnector, psAdapter);
	if (psEdid == NULL)
	{
		return 0;
	}

	drm_mode_connector_update_edid_property(psConnector, psEdid);

	return drm_add_edid_modes(psConnector, psEdid);
}
Esempio n. 12
0
int msm_edp_ctrl_get_panel_info(struct edp_ctrl *ctrl,
		struct drm_connector *connector, struct edid **edid)
{
	int ret = 0;

	mutex_lock(&ctrl->dev_mutex);

	if (ctrl->edid) {
		if (edid) {
			DBG("Just return edid buffer");
			*edid = ctrl->edid;
		}
		goto unlock_ret;
	}

	if (!ctrl->power_on) {
		edp_ctrl_phy_aux_enable(ctrl, 1);
		edp_ctrl_irq_enable(ctrl, 1);
	}

	ret = drm_dp_link_probe(ctrl->drm_aux, &ctrl->dp_link);
	if (ret) {
		pr_err("%s: read dpcd cap failed, %d\n", __func__, ret);
		goto disable_ret;
	}

	/* Initialize link rate as panel max link rate */
	ctrl->link_rate = drm_dp_link_rate_to_bw_code(ctrl->dp_link.rate);

	ctrl->edid = drm_get_edid(connector, &ctrl->drm_aux->ddc);
	if (!ctrl->edid) {
		pr_err("%s: edid read fail\n", __func__);
		goto disable_ret;
	}

	if (edid)
		*edid = ctrl->edid;

disable_ret:
	if (!ctrl->power_on) {
		edp_ctrl_irq_enable(ctrl, 0);
		edp_ctrl_phy_aux_enable(ctrl, 0);
	}
unlock_ret:
	mutex_unlock(&ctrl->dev_mutex);
	return ret;
}
Esempio n. 13
0
enum dc_edid_status dm_helpers_read_local_edid(
		struct dc_context *ctx,
		struct dc_link *link,
		struct dc_sink *sink)
{
	struct amdgpu_dm_connector *aconnector = link->priv;
	struct i2c_adapter *ddc;
	int retry = 3;
	enum dc_edid_status edid_status;
	struct edid *edid;

	if (link->aux_mode)
		ddc = &aconnector->dm_dp_aux.aux.ddc;
	else
		ddc = &aconnector->i2c->base;

	/* some dongles read edid incorrectly the first time,
	 * do check sum and retry to make sure read correct edid.
	 */
	do {

		edid = drm_get_edid(&aconnector->base, ddc);

		if (!edid)
			return EDID_NO_RESPONSE;

		sink->dc_edid.length = EDID_LENGTH * (edid->extensions + 1);
		memmove(sink->dc_edid.raw_edid, (uint8_t *)edid, sink->dc_edid.length);

		/* We don't need the original edid anymore */
		kfree(edid);

		edid_status = dm_helpers_parse_edid_caps(
						ctx,
						&sink->dc_edid,
						&sink->edid_caps);

	} while (edid_status == EDID_BAD_CHECKSUM && --retry > 0);

	if (edid_status != EDID_OK)
		DRM_ERROR("EDID err: %d, on connector: %s",
				edid_status,
				aconnector->base.name);

	return edid_status;
}
Esempio n. 14
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;
}
Esempio n. 15
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. 16
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. 17
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. 18
0
static int sun4i_hdmi_get_modes(struct drm_connector *connector)
{
	struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
	struct edid *edid;
	int ret;

	edid = drm_get_edid(connector, hdmi->i2c);
	if (!edid)
		return 0;

	hdmi->hdmi_monitor = drm_detect_hdmi_monitor(edid);
	DRM_DEBUG_DRIVER("Monitor is %s monitor\n",
			 hdmi->hdmi_monitor ? "an HDMI" : "a DVI");

	drm_mode_connector_update_edid_property(connector, edid);
	cec_s_phys_addr_from_edid(hdmi->cec_adap, edid);
	ret = drm_add_edid_modes(connector, edid);
	kfree(edid);

	return ret;
}
Esempio n. 19
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. 20
0
static enum drm_connector_status
intel_hdmi_detect(struct drm_connector *connector)
{
	struct intel_output *intel_output = to_intel_output(connector);
	struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
	struct edid *edid = NULL;
	enum drm_connector_status status = connector_status_disconnected;

	hdmi_priv->has_hdmi_sink = false;
	edid = drm_get_edid(&intel_output->base,
			    intel_output->ddc_bus);

	if (edid) {
		if (edid->input & DRM_EDID_INPUT_DIGITAL) {
			status = connector_status_connected;
			hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
		}
		intel_output->base.display_info.raw_edid = NULL;
		kfree(edid);
	}

	return status;
}
Esempio n. 21
0
static int imx_hdmi_connector_get_modes(struct drm_connector *connector)
{
	struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
					     connector);
	struct edid *edid;
	int ret;

	if (!hdmi->ddc)
		return 0;

	edid = drm_get_edid(connector, hdmi->ddc);
	if (edid) {
		dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
			edid->width_cm, edid->height_cm);

		drm_mode_connector_update_edid_property(connector, edid);
		ret = drm_add_edid_modes(connector, edid);
		kfree(edid);
	} else {
		dev_dbg(hdmi->dev, "failed to get edid\n");
	}

	return 0;
}
static int mtk_hdmi_process_cmd(char *cmd, struct mediatek_hdmi *hctx)
{
	char *np;
	unsigned long res;

	mtk_hdmi_info("dbg cmd: %s\n", cmd);

	if (0 == strncmp(cmd, "getedid", 7)) {
		struct edid *edid_info = NULL;

		edid_info = drm_get_edid(&hctx->conn, hctx->ddc_adpt);
		if (!edid_info) {
			mtk_hdmi_err("get edid faied!\n");
			goto errcode;
		} else {
			int i = 0;
			u8 *edid_raw = (u8 *)edid_info;
			int size = EDID_LENGTH * (1 + edid_info->extensions);

			mtk_hdmi_output("get edid success! edid raw data:\n");
			for (i = 0; i < size; i++) {
				if (i % 8 == 0)
					mtk_hdmi_output("\n%02xH", i);
				mtk_hdmi_output(" %02x", edid_raw[i]);
			}
			mtk_hdmi_output("\n");
		}
	} else if (0 == strncmp(cmd, "status", 6)) {
		mtk_hdmi_info("cur dispaly: name:%s, hdisplay:%d\n",
			      hctx->display_node->mode.name,
			      hctx->display_node->mode.hdisplay);
		mtk_hdmi_info("hsync_start:%d,hsync_end:%d, htotal:%d",
			      hctx->display_node->mode.hsync_start,
			      hctx->display_node->mode.hsync_end,
			      hctx->display_node->mode.htotal);
		mtk_hdmi_info("hskew:%d, vdisplay:%d\n",
			      hctx->display_node->mode.hskew,
			      hctx->display_node->mode.vdisplay);
		mtk_hdmi_info("vsync_start:%d, vsync_end:%d, vtotal:%d",
			      hctx->display_node->mode.vsync_start,
			      hctx->display_node->mode.vsync_end,
			      hctx->display_node->mode.vtotal);
		mtk_hdmi_info("vscan:%d, flag:%d\n",
			      hctx->display_node->mode.vscan,
			      hctx->display_node->mode.flags);
		mtk_hdmi_info("current display mode:%s\n",
			      hctx->dvi_mode ? "dvi" : "hdmi");
	} else {
		np = strsep(&cmd, "=");
		if (0 != strncmp(np, "res", 3))
			goto errcode;

		np = strsep(&cmd, "=");
		if (kstrtoul(np, 10, &res))
			goto errcode;

		if (res >= ARRAY_SIZE(display_mode)) {
			mtk_hdmi_err("doesn't support this format, res = %ld\n",
				     res);
			goto errcode;
		}

		mtk_hdmi_info("set format %ld\n", res);
		mtk_hdmi_display_set_vid_format(hctx->display_node,
						&display_mode[res]);
	}

	return 0;

errcode:
	mtk_hdmi_err("invalid dbg command\n");
	return -1;
}