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

Commit 1929041b authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux

Pill drm updates part 2 from Dave Airlie:
 "This is the follow-up pull, 3 pieces

  a) exynos next stuff, was delayed but looks okay to me, one patch in
     v4l bits but it was acked by v4l person.
  b) UAPI disintegration bits
  c) intel fixes - DP fixes, hang fixes, other misc fixes."

* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (52 commits)
  drm: exynos: hdmi: remove drm common hdmi platform data struct
  drm: exynos: hdmi: add support for exynos5 hdmi
  drm: exynos: hdmi: replace is_v13 with version check in hdmi
  drm: exynos: hdmi: add support for exynos5 mixer
  drm: exynos: hdmi: add support to disable video processor in mixer
  drm: exynos: hdmi: add support for platform variants for mixer
  drm: exynos: hdmi: add support for exynos5 hdmiphy
  drm: exynos: hdmi: add support for exynos5 ddc
  drm: exynos: remove drm hdmi platform data struct
  drm: exynos: hdmi: turn off HPD interrupt in HDMI chip
  drm: exynos: hdmi: use s5p-hdmi platform data
  drm: exynos: hdmi: fix interrupt handling
  drm: exynos: hdmi: support for platform variants
  media: s5p-hdmi: add HPD GPIO to platform data
  UAPI: (Scripted) Disintegrate include/drm
  drm/i915: Fix GT_MODE default value
  drm/i915: don't frob the vblank ts in finish_page_flip
  drm/i915: call drm_handle_vblank before finish_page_flip
  drm/i915: print warning if vmi915_gem_fault error is not handled
  drm/i915: EBUSY status handling added to i915_gem_fault().
  ...
parents d43b7167 1f31c69d
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -395,13 +395,14 @@ out:
 * \param adapter : i2c device adaptor
 * \return 1 on success
 */
static bool
bool
drm_probe_ddc(struct i2c_adapter *adapter)
{
	unsigned char out;

	return (drm_do_probe_ddc_edid(adapter, &out, 0, 1) == 0);
}
EXPORT_SYMBOL(drm_probe_ddc);

/**
 * drm_get_edid - get EDID data, if available
+17 −5
Original line number Diff line number Diff line
@@ -26,29 +26,41 @@ static int s5p_ddc_probe(struct i2c_client *client,
{
	hdmi_attach_ddc_client(client);

	dev_info(&client->adapter->dev, "attached s5p_ddc "
		"into i2c adapter successfully\n");
	dev_info(&client->adapter->dev,
		"attached %s into i2c adapter successfully\n",
		client->name);

	return 0;
}

static int s5p_ddc_remove(struct i2c_client *client)
{
	dev_info(&client->adapter->dev, "detached s5p_ddc "
		"from i2c adapter successfully\n");
	dev_info(&client->adapter->dev,
		"detached %s from i2c adapter successfully\n",
		client->name);

	return 0;
}

static struct i2c_device_id ddc_idtable[] = {
	{"s5p_ddc", 0},
	{"exynos5-hdmiddc", 0},
	{ },
};

static struct of_device_id hdmiddc_match_types[] = {
	{
		.compatible = "samsung,exynos5-hdmiddc",
	}, {
		/* end node */
	}
};

struct i2c_driver ddc_driver = {
	.driver = {
		.name = "s5p_ddc",
		.name = "exynos-hdmiddc",
		.owner = THIS_MODULE,
		.of_match_table = hdmiddc_match_types,
	},
	.id_table	= ddc_idtable,
	.probe		= s5p_ddc_probe,
+46 −4
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ struct exynos_drm_connector {
	struct drm_connector	drm_connector;
	uint32_t		encoder_id;
	struct exynos_drm_manager *manager;
	uint32_t		dpms;
};

/* convert exynos_video_timings to drm_display_mode */
@@ -149,8 +150,12 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
		count = drm_add_edid_modes(connector, edid);
		kfree(edid);
	} else {
		struct drm_display_mode *mode = drm_mode_create(connector->dev);
		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);
@@ -194,8 +199,7 @@ static int exynos_drm_connector_mode_valid(struct drm_connector *connector,
	return ret;
}

static struct drm_encoder *exynos_drm_best_encoder(
						struct drm_connector *connector)
struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector)
{
	struct drm_device *dev = connector->dev;
	struct exynos_drm_connector *exynos_connector =
@@ -224,6 +228,43 @@ static struct drm_connector_helper_funcs exynos_connector_helper_funcs = {
	.best_encoder	= exynos_drm_best_encoder,
};

void exynos_drm_display_power(struct drm_connector *connector, int mode)
{
	struct drm_encoder *encoder = exynos_drm_best_encoder(connector);
	struct exynos_drm_connector *exynos_connector;
	struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
	struct exynos_drm_display_ops *display_ops = manager->display_ops;

	exynos_connector = to_exynos_connector(connector);

	if (exynos_connector->dpms == mode) {
		DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n");
		return;
	}

	if (display_ops && display_ops->power_on)
		display_ops->power_on(manager->dev, mode);

	exynos_connector->dpms = mode;
}

static void exynos_drm_connector_dpms(struct drm_connector *connector,
					int mode)
{
	DRM_DEBUG_KMS("%s\n", __FILE__);

	/*
	 * in case that drm_crtc_helper_set_mode() is called,
	 * encoder/crtc->funcs->dpms() will be just returned
	 * because they already were DRM_MODE_DPMS_ON so only
	 * exynos_drm_display_power() will be called.
	 */
	drm_helper_connector_dpms(connector, mode);

	exynos_drm_display_power(connector, mode);

}

static int exynos_drm_connector_fill_modes(struct drm_connector *connector,
				unsigned int max_width, unsigned int max_height)
{
@@ -283,7 +324,7 @@ static void exynos_drm_connector_destroy(struct drm_connector *connector)
}

static struct drm_connector_funcs exynos_connector_funcs = {
	.dpms		= drm_helper_connector_dpms,
	.dpms		= exynos_drm_connector_dpms,
	.fill_modes	= exynos_drm_connector_fill_modes,
	.detect		= exynos_drm_connector_detect,
	.destroy	= exynos_drm_connector_destroy,
@@ -332,6 +373,7 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,

	exynos_connector->encoder_id = encoder->base.id;
	exynos_connector->manager = manager;
	exynos_connector->dpms = DRM_MODE_DPMS_OFF;
	connector->encoder = encoder;

	err = drm_mode_connector_attach_encoder(connector, encoder);
+4 −0
Original line number Diff line number Diff line
@@ -31,4 +31,8 @@
struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
						   struct drm_encoder *encoder);

struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector);

void exynos_drm_display_power(struct drm_connector *connector, int mode);

#endif
+69 −31
Original line number Diff line number Diff line
@@ -34,32 +34,14 @@

static LIST_HEAD(exynos_drm_subdrv_list);

static int exynos_drm_subdrv_probe(struct drm_device *dev,
static int exynos_drm_create_enc_conn(struct drm_device *dev,
					struct exynos_drm_subdrv *subdrv)
{
	struct drm_encoder *encoder;
	struct drm_connector *connector;

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

	if (subdrv->probe) {
	int ret;

		/*
		 * this probe callback would be called by sub driver
		 * after setting of all resources to this sub driver,
		 * such as clock, irq and register map are done or by load()
		 * of exynos drm driver.
		 *
		 * P.S. note that this driver is considered for modularization.
		 */
		ret = subdrv->probe(dev, subdrv->dev);
		if (ret)
			return ret;
	}

	if (!subdrv->manager)
		return 0;
	DRM_DEBUG_DRIVER("%s\n", __FILE__);

	subdrv->manager->dev = subdrv->dev;

@@ -78,24 +60,22 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev,
	connector = exynos_drm_connector_create(dev, encoder);
	if (!connector) {
		DRM_ERROR("failed to create connector\n");
		encoder->funcs->destroy(encoder);
		return -EFAULT;
		ret = -EFAULT;
		goto err_destroy_encoder;
	}

	subdrv->encoder = encoder;
	subdrv->connector = connector;

	return 0;

err_destroy_encoder:
	encoder->funcs->destroy(encoder);
	return ret;
}

static void exynos_drm_subdrv_remove(struct drm_device *dev,
				      struct exynos_drm_subdrv *subdrv)
static void exynos_drm_destroy_enc_conn(struct exynos_drm_subdrv *subdrv)
{
	DRM_DEBUG_DRIVER("%s\n", __FILE__);

	if (subdrv->remove)
		subdrv->remove(dev);

	if (subdrv->encoder) {
		struct drm_encoder *encoder = subdrv->encoder;
		encoder->funcs->destroy(encoder);
@@ -109,9 +89,43 @@ static void exynos_drm_subdrv_remove(struct drm_device *dev,
	}
}

static int exynos_drm_subdrv_probe(struct drm_device *dev,
					struct exynos_drm_subdrv *subdrv)
{
	if (subdrv->probe) {
		int ret;

		subdrv->drm_dev = dev;

		/*
		 * this probe callback would be called by sub driver
		 * after setting of all resources to this sub driver,
		 * such as clock, irq and register map are done or by load()
		 * of exynos drm driver.
		 *
		 * P.S. note that this driver is considered for modularization.
		 */
		ret = subdrv->probe(dev, subdrv->dev);
		if (ret)
			return ret;
	}

	return 0;
}

static void exynos_drm_subdrv_remove(struct drm_device *dev,
				      struct exynos_drm_subdrv *subdrv)
{
	DRM_DEBUG_DRIVER("%s\n", __FILE__);

	if (subdrv->remove)
		subdrv->remove(dev, subdrv->dev);
}

int exynos_drm_device_register(struct drm_device *dev)
{
	struct exynos_drm_subdrv *subdrv, *n;
	unsigned int fine_cnt = 0;
	int err;

	DRM_DEBUG_DRIVER("%s\n", __FILE__);
@@ -120,14 +134,36 @@ int exynos_drm_device_register(struct drm_device *dev)
		return -EINVAL;

	list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) {
		subdrv->drm_dev = dev;
		err = exynos_drm_subdrv_probe(dev, subdrv);
		if (err) {
			DRM_DEBUG("exynos drm subdrv probe failed.\n");
			list_del(&subdrv->list);
			continue;
		}

		/*
		 * if manager is null then it means that this sub driver
		 * doesn't need encoder and connector.
		 */
		if (!subdrv->manager) {
			fine_cnt++;
			continue;
		}

		err = exynos_drm_create_enc_conn(dev, subdrv);
		if (err) {
			DRM_DEBUG("failed to create encoder and connector.\n");
			exynos_drm_subdrv_remove(dev, subdrv);
			list_del(&subdrv->list);
			continue;
		}

		fine_cnt++;
	}

	if (!fine_cnt)
		return -EINVAL;

	return 0;
}
EXPORT_SYMBOL_GPL(exynos_drm_device_register);
@@ -143,8 +179,10 @@ int exynos_drm_device_unregister(struct drm_device *dev)
		return -EINVAL;
	}

	list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list)
	list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
		exynos_drm_subdrv_remove(dev, subdrv);
		exynos_drm_destroy_enc_conn(subdrv);
	}

	return 0;
}
Loading