示例#1
0
static int udl_get_modes(struct drm_connector *connector)
{
	struct udl_device *udl = connector->dev->dev_private;
	struct edid *edid;
	int ret;

	edid = (struct edid *)udl_get_edid(udl);
	if (!edid) {
		drm_mode_connector_update_edid_property(connector, NULL);
		return 0;
	}

	/*
	 * We only read the main block, but if the monitor reports extension
	 * blocks then the drm edid code expects them to be present, so patch
	 * the extension count to 0.
	 */
	edid->checksum += edid->extensions;
	edid->extensions = 0;

	drm_mode_connector_update_edid_property(connector, edid);
	ret = drm_add_edid_modes(connector, edid);
	kfree(edid);
	return ret;
}
示例#2
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;
}
示例#3
0
static int virtio_gpu_conn_get_modes(struct drm_connector *connector)
{
	struct virtio_gpu_output *output =
		drm_connector_to_virtio_gpu_output(connector);
	struct drm_display_mode *mode = NULL;
	int count, width, height;

	if (output->edid) {
		count = drm_add_edid_modes(connector, output->edid);
		if (count)
			return count;
	}

	width  = le32_to_cpu(output->info.r.width);
	height = le32_to_cpu(output->info.r.height);
	count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);

	if (width == 0 || height == 0) {
		width = XRES_DEF;
		height = YRES_DEF;
		drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
	} else {
		DRM_DEBUG("add mode: %dx%d\n", width, height);
		mode = drm_cvt_mode(connector->dev, width, height, 60,
				    false, false, false);
		mode->type |= DRM_MODE_TYPE_PREFERRED;
		drm_mode_probed_add(connector, mode);
		count++;
	}

	return count;
}
int drm_load_edid_firmware(struct drm_connector *connector)
{
	char *connector_name = drm_get_connector_name(connector);
	char *edidname = edid_firmware, *last, *colon;
	int ret = 0;

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

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

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

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

	drm_mode_connector_update_edid_property(connector,
	    (struct edid *) connector->display_info.raw_edid);

	return drm_add_edid_modes(connector, (struct edid *)
	    connector->display_info.raw_edid);
}
示例#5
0
static int imx_pd_connector_get_modes(struct drm_connector *connector)
{
	struct imx_parallel_display *imxpd = con_to_imxpd(connector);
	struct device_node *np = imxpd->dev->of_node;
	int num_modes = 0;

	if (imxpd->edid) {
		drm_mode_connector_update_edid_property(connector, imxpd->edid);
		num_modes = drm_add_edid_modes(connector, imxpd->edid);
	}

	if (imxpd->mode_valid) {
		struct drm_display_mode *mode = drm_mode_create(connector->dev);
		drm_mode_copy(mode, &imxpd->mode);
		mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
		drm_mode_probed_add(connector, mode);
		num_modes++;
	}

	if (np) {
		struct drm_display_mode *mode = drm_mode_create(connector->dev);
		of_get_drm_display_mode(np, &imxpd->mode, OF_USE_NATIVE_MODE);
		drm_mode_copy(mode, &imxpd->mode);
		mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
		drm_mode_probed_add(connector, mode);
		num_modes++;
	}

	return num_modes;
}
示例#6
0
int analogix_dp_get_modes(struct drm_connector *connector)
{
	struct analogix_dp_device *dp = to_dp(connector);
	struct edid *edid = (struct edid *)dp->edid;
	int ret, num_modes = 0;

	ret = analogix_dp_prepare_panel(dp, true, false);
	if (ret) {
		DRM_ERROR("Failed to prepare panel (%d)\n", ret);
		return 0;
	}

	if (analogix_dp_handle_edid(dp) == 0) {
		drm_mode_connector_update_edid_property(&dp->connector, edid);
		num_modes += drm_add_edid_modes(&dp->connector, edid);
	}

	if (dp->plat_data->panel)
		num_modes += drm_panel_get_modes(dp->plat_data->panel);

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

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

	return num_modes;
}
示例#7
0
文件: output.c 项目: 383530895/linux
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;
}
static int tda998x_connector_get_modes(struct drm_connector *connector)
{
	struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
	struct edid *edid;
	int n;

	/*
	 * If we get killed while waiting for the HPD timeout, return
	 * no modes found: we are not in a restartable path, so we
	 * can't handle signals gracefully.
	 */
	if (tda998x_edid_delay_wait(priv))
		return 0;

	if (priv->rev == TDA19988)
		reg_clear(priv, REG_TX4, TX4_PD_RAM);

	edid = drm_do_get_edid(connector, read_edid_block, priv);

	if (priv->rev == TDA19988)
		reg_set(priv, REG_TX4, TX4_PD_RAM);

	if (!edid) {
		dev_warn(&priv->hdmi->dev, "failed to read EDID\n");
		return 0;
	}

	drm_mode_connector_update_edid_property(connector, edid);
	n = drm_add_edid_modes(connector, edid);
	priv->is_hdmi_sink = drm_detect_hdmi_monitor(edid);
	kfree(edid);

	return n;
}
示例#9
0
static int imx_ldb_connector_get_modes(struct drm_connector *connector)
{
	struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector);
	int num_modes = 0;

	if (imx_ldb_ch->panel && imx_ldb_ch->panel->funcs &&
	    imx_ldb_ch->panel->funcs->get_modes) {
		num_modes = imx_ldb_ch->panel->funcs->get_modes(imx_ldb_ch->panel);
		if (num_modes > 0)
			return num_modes;
	}

	if (imx_ldb_ch->edid) {
		drm_mode_connector_update_edid_property(connector,
							imx_ldb_ch->edid);
		num_modes = drm_add_edid_modes(connector, imx_ldb_ch->edid);
	}

	if (imx_ldb_ch->mode_valid) {
		struct drm_display_mode *mode;

		mode = drm_mode_create(connector->dev);
		if (!mode)
			return -EINVAL;
		drm_mode_copy(mode, &imx_ldb_ch->mode);
		mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
		drm_mode_probed_add(connector, mode);
		num_modes++;
	}

	return num_modes;
}
示例#10
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);
}
示例#11
0
static int
tda998x_encoder_get_modes(struct tda998x_priv *priv,
			  struct drm_connector *connector)
{
	struct edid *edid;
	int n;

	if (priv->rev == TDA19988)
		reg_clear(priv, REG_TX4, TX4_PD_RAM);

	edid = drm_do_get_edid(connector, read_edid_block, priv);

	if (priv->rev == TDA19988)
		reg_set(priv, REG_TX4, TX4_PD_RAM);

	if (!edid) {
		dev_warn(&priv->hdmi->dev, "failed to read EDID\n");
		return 0;
	}

	drm_mode_connector_update_edid_property(connector, edid);
	n = drm_add_edid_modes(connector, edid);
	priv->is_hdmi_sink = drm_detect_hdmi_monitor(edid);
	kfree(edid);

	return n;
}
int drm_load_edid_firmware(struct drm_connector *connector)
{
	const char *connector_name = drm_get_connector_name(connector);
	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 = (struct 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);
	kfree(edid);

	return ret;
}
示例#13
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;
}
示例#14
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;
}
示例#15
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;
}
示例#16
0
文件: ptn3460.c 项目: 383530895/linux
int ptn3460_get_modes(struct drm_connector *connector)
{
	struct ptn3460_bridge *ptn_bridge;
	u8 *edid;
	int ret, num_modes;
	bool power_off;

	ptn_bridge = container_of(connector, struct ptn3460_bridge, connector);

	if (ptn_bridge->edid)
		return drm_add_edid_modes(connector, ptn_bridge->edid);

	power_off = !ptn_bridge->enabled;
	ptn3460_pre_enable(ptn_bridge->bridge);

	edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
	if (!edid) {
		DRM_ERROR("Failed to allocate edid\n");
		return 0;
	}

	ret = ptn3460_read_bytes(ptn_bridge, PTN3460_EDID_ADDR, edid,
			EDID_LENGTH);
	if (ret) {
		kfree(edid);
		num_modes = 0;
		goto out;
	}

	ptn_bridge->edid = (struct edid *)edid;
	drm_mode_connector_update_edid_property(connector, ptn_bridge->edid);

	num_modes = drm_add_edid_modes(connector, ptn_bridge->edid);

out:
	if (power_off)
		ptn3460_disable(ptn_bridge->bridge);

	return num_modes;
}
示例#17
0
static int udl_get_modes(struct drm_connector *connector)
{
	struct udl_device *udl = connector->dev->dev_private;
	struct edid *edid;
	int ret;

	edid = (struct edid *)udl_get_edid(udl);

	drm_mode_connector_update_edid_property(connector, edid);
	ret = drm_add_edid_modes(connector, edid);
	kfree(edid);
	return ret;
}
示例#18
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);
	connector->display_info.raw_edid = NULL;
	kfree(edid);

	return ret;
}
示例#19
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;
}
示例#20
0
static int omap_connector_get_modes(struct drm_connector *connector)
{
	struct omap_connector *omap_connector = to_omap_connector(connector);
	struct omap_dss_device *dssdev = omap_connector->dssdev;
	struct omap_dss_driver *dssdrv = dssdev->driver;
	struct drm_device *dev = connector->dev;
	int n = 0;

	DBG("%s", omap_connector->dssdev->name);

	/* if display exposes EDID, then we parse that in the normal way to
	 * build table of supported modes.. otherwise (ie. fixed resolution
	 * LCD panels) we just return a single mode corresponding to the
	 * currently configured timings:
	 */
	if (dssdrv->read_edid) {
		void *edid = kzalloc(MAX_EDID, GFP_KERNEL);

		if ((dssdrv->read_edid(dssdev, edid, MAX_EDID) > 0) &&
				drm_edid_is_valid(edid)) {
			drm_mode_connector_update_edid_property(
					connector, edid);
			n = drm_add_edid_modes(connector, edid);

			omap_connector->hdmi_mode =
				drm_detect_hdmi_monitor(edid);
		} else {
			drm_mode_connector_update_edid_property(
					connector, NULL);
		}

		kfree(edid);
	} else {
		struct drm_display_mode *mode = drm_mode_create(dev);
		struct videomode vm = {0};

		dssdrv->get_timings(dssdev, &vm);

		drm_display_mode_from_videomode(&vm, mode);

		mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
		drm_mode_set_name(mode);
		drm_mode_probed_add(connector, mode);

		n = 1;
	}

	return n;
}
示例#21
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);
}
示例#22
0
static int imx_pd_connector_get_modes(struct drm_connector *connector)
{
	struct imx_parallel_display *imxpd = con_to_imxpd(connector);
	struct device_node *np = imxpd->dev->of_node;
	int num_modes = 0;

	if (imxpd->panel && imxpd->panel->funcs &&
	    imxpd->panel->funcs->get_modes) {
		struct drm_display_info *di = &connector->display_info;

		num_modes = imxpd->panel->funcs->get_modes(imxpd->panel);
		if (!imxpd->bus_format && di->num_bus_formats)
			imxpd->bus_format = di->bus_formats[0];
		if (num_modes > 0)
			return num_modes;
	}

	if (imxpd->edid) {
		drm_mode_connector_update_edid_property(connector, imxpd->edid);
		num_modes = drm_add_edid_modes(connector, imxpd->edid);
	}

	if (imxpd->mode_valid) {
		struct drm_display_mode *mode = drm_mode_create(connector->dev);

		if (!mode)
			return -EINVAL;
		drm_mode_copy(mode, &imxpd->mode);
		mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
		drm_mode_probed_add(connector, mode);
		num_modes++;
	}

	if (np) {
		struct drm_display_mode *mode = drm_mode_create(connector->dev);

		if (!mode)
			return -EINVAL;
		of_get_drm_display_mode(np, &imxpd->mode, OF_USE_NATIVE_MODE);
		drm_mode_copy(mode, &imxpd->mode);
		mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
		drm_mode_probed_add(connector, mode);
		num_modes++;
	}

	return num_modes;
}
示例#23
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;
}
示例#24
0
static int edp_connector_get_modes(struct drm_connector *connector)
{
	struct edp_connector *edp_connector = to_edp_connector(connector);
	struct msm_edp *edp = edp_connector->edp;

	struct edid *drm_edid = NULL;
	int ret = 0;

	DBG("");
	ret = msm_edp_ctrl_get_panel_info(edp->ctrl, connector, &drm_edid);
	if (ret)
		return ret;

	drm_mode_connector_update_edid_property(connector, drm_edid);
	if (drm_edid)
		ret = drm_add_edid_modes(connector, drm_edid);

	return ret;
}
static int omap_connector_get_modes(struct drm_connector *connector)
{
	struct omap_connector *omap_connector = to_omap_connector(connector);
	struct omap_dss_device *dssdev = omap_connector->dssdev;
	struct omap_dss_driver *dssdrv = dssdev->driver;
	struct drm_device *dev = connector->dev;
	int n = 0;

	DBG("%s", omap_connector->dssdev->name);

	if (dssdrv->read_edid) {
		void *edid = kzalloc(MAX_EDID, GFP_KERNEL);

		if ((dssdrv->read_edid(dssdev, edid, MAX_EDID) > 0) &&
				drm_edid_is_valid(edid)) {
			drm_mode_connector_update_edid_property(
					connector, edid);
			n = drm_add_edid_modes(connector, edid);
			kfree(connector->display_info.raw_edid);
			connector->display_info.raw_edid = edid;
		} else {
			drm_mode_connector_update_edid_property(
					connector, NULL);
			connector->display_info.raw_edid = NULL;
			kfree(edid);
		}
	} else {
		struct drm_display_mode *mode = drm_mode_create(dev);
		struct omap_video_timings timings;

		dssdrv->get_timings(dssdev, &timings);

		copy_timings_omap_to_drm(mode, &timings);

		mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
		drm_mode_set_name(mode);
		drm_mode_probed_add(connector, mode);

		n = 1;
	}

	return n;
}
示例#26
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;
}
示例#27
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;
}
示例#28
0
static int exynos_drm_connector_get_modes(struct drm_connector *connector)
{
	struct exynos_drm_connector *exynos_connector =
					to_exynos_connector(connector);
	struct exynos_drm_manager *manager = exynos_connector->manager;
	struct exynos_drm_display_ops *display_ops = manager->display_ops;
	struct edid *edid = NULL;
	unsigned int count = 0;
	int ret;

	if (!display_ops) {
		DRM_DEBUG_KMS("display_ops is null.\n");
		return 0;
	}

	/*
	 * if get_edid() exists then get_edid() callback of hdmi side
	 * is called to get edid data through i2c interface else
	 * get timing from the FIMD driver(display controller).
	 *
	 * P.S. in case of lcd panel, count is always 1 if success
	 * because lcd panel has only one mode.
	 */
	if (display_ops->get_edid) {
		edid = display_ops->get_edid(manager->dev, connector);
		if (IS_ERR_OR_NULL(edid)) {
			ret = PTR_ERR(edid);
			edid = NULL;
			DRM_ERROR("Panel operation get_edid failed %d\n", ret);
			goto out;
		}

		count = drm_add_edid_modes(connector, edid);
		if (!count) {
			DRM_ERROR("Add edid modes failed %d\n", count);
			goto out;
		}

		drm_mode_connector_update_edid_property(connector, edid);
	} else {
		struct exynos_drm_panel_info *panel;
		struct drm_display_mode *mode = drm_mode_create(connector->dev);
		if (!mode) {
			DRM_ERROR("failed to create a new display mode.\n");
			return 0;
		}

		if (display_ops->get_panel)
			panel = display_ops->get_panel(manager->dev);
		else {
			drm_mode_destroy(connector->dev, mode);
			return 0;
		}

		convert_to_display_mode(mode, panel);
		connector->display_info.width_mm = mode->width_mm;
		connector->display_info.height_mm = mode->height_mm;

		mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
		drm_mode_set_name(mode);
		drm_mode_probed_add(connector, mode);

		count = 1;
	}

out:
	kfree(edid);
	return count;
}
示例#29
0
static int exynos_drm_connector_get_modes(struct drm_connector *connector)
{
	struct exynos_drm_connector *exynos_connector =
					to_exynos_connector(connector);
	struct exynos_drm_manager *manager = exynos_connector->manager;
	struct exynos_drm_display_ops *display_ops = manager->display_ops;
	unsigned int count;

	DRM_DEBUG_KMS("%s\n", __FILE__);

	if (!display_ops) {
		DRM_DEBUG_KMS("display_ops is null.\n");
		return 0;
	}

	/*
	 * if get_edid() exists then get_edid() callback of hdmi side
	 * is called to get edid data through i2c interface else
	 * get timing from the FIMD driver(display controller).
	 *
	 * P.S. in case of lcd panel, count is always 1 if success
	 * because lcd panel has only one mode.
	 */
	if (display_ops->get_edid) {
		int ret;
		void *edid;

		edid = kzalloc(MAX_EDID, GFP_KERNEL);
		if (!edid) {
			DRM_ERROR("failed to allocate edid\n");
			return 0;
		}

		ret = display_ops->get_edid(manager->dev, connector,
						edid, MAX_EDID);
		if (ret < 0) {
			DRM_ERROR("failed to get edid data.\n");
			kfree(edid);
			edid = NULL;
			return 0;
		}

		drm_mode_connector_update_edid_property(connector, edid);
		count = drm_add_edid_modes(connector, edid);

		kfree(connector->display_info.raw_edid);
		connector->display_info.raw_edid = edid;
	} else {
		struct drm_display_mode *mode = drm_mode_create(connector->dev);
		struct fb_videomode *timing;

		if (display_ops->get_timing)
			timing = display_ops->get_timing(manager->dev);
		else {
			drm_mode_destroy(connector->dev, mode);
			return 0;
		}

		convert_to_display_mode(mode, timing);

		mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
		drm_mode_set_name(mode);
		drm_mode_probed_add(connector, mode);

		count = 1;
	}

	return count;
}