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

Commit 07c42703 authored by Gustavo Padovan's avatar Gustavo Padovan Committed by Inki Dae
Browse files

drm/exynos: do not start enabling DP at bind() phase



The DP device will be properly enabled at the enable() call just
after the bind call finishes.

Changelog v2:
- no change

Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
Signed-off-by: default avatarInki Dae <inki.dae@samsung.com>
parent 663a233e
Loading
Loading
Loading
Loading
+77 −30
Original line number Diff line number Diff line
@@ -1009,9 +1009,9 @@ static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
{
	int ret;

	encoder->bridge = dp->bridge;
	dp->bridge->encoder = encoder;
	ret = drm_bridge_attach(encoder->dev, dp->bridge);
	encoder->bridge->next = dp->ptn_bridge;
	dp->ptn_bridge->encoder = encoder;
	ret = drm_bridge_attach(encoder->dev, dp->ptn_bridge);
	if (ret) {
		DRM_ERROR("Failed to attach bridge to drm\n");
		return ret;
@@ -1020,14 +1020,15 @@ static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
	return 0;
}

static int exynos_dp_create_connector(struct drm_encoder *encoder)
static int exynos_dp_bridge_attach(struct drm_bridge *bridge)
{
	struct exynos_dp_device *dp = encoder_to_dp(encoder);
	struct exynos_dp_device *dp = bridge->driver_private;
	struct drm_encoder *encoder = &dp->encoder;
	struct drm_connector *connector = &dp->connector;
	int ret;

	/* Pre-empt DP connector creation if there's a bridge */
	if (dp->bridge) {
	if (dp->ptn_bridge) {
		ret = exynos_drm_attach_lcd_bridge(dp, encoder);
		if (!ret)
			return 0;
@@ -1052,22 +1053,9 @@ static int exynos_dp_create_connector(struct drm_encoder *encoder)
	return ret;
}

static bool exynos_dp_mode_fixup(struct drm_encoder *encoder,
				 const struct drm_display_mode *mode,
				 struct drm_display_mode *adjusted_mode)
{
	return true;
}

static void exynos_dp_mode_set(struct drm_encoder *encoder,
			       struct drm_display_mode *mode,
			       struct drm_display_mode *adjusted_mode)
{
}

static void exynos_dp_enable(struct drm_encoder *encoder)
static void exynos_dp_bridge_enable(struct drm_bridge *bridge)
{
	struct exynos_dp_device *dp = encoder_to_dp(encoder);
	struct exynos_dp_device *dp = bridge->driver_private;
	struct exynos_drm_crtc *crtc = dp_to_crtc(dp);

	if (dp->dpms_mode == DRM_MODE_DPMS_ON)
@@ -1092,9 +1080,9 @@ static void exynos_dp_enable(struct drm_encoder *encoder)
	dp->dpms_mode = DRM_MODE_DPMS_ON;
}

static void exynos_dp_disable(struct drm_encoder *encoder)
static void exynos_dp_bridge_disable(struct drm_bridge *bridge)
{
	struct exynos_dp_device *dp = encoder_to_dp(encoder);
	struct exynos_dp_device *dp = bridge->driver_private;
	struct exynos_drm_crtc *crtc = dp_to_crtc(dp);

	if (dp->dpms_mode != DRM_MODE_DPMS_ON)
@@ -1123,6 +1111,69 @@ static void exynos_dp_disable(struct drm_encoder *encoder)
	dp->dpms_mode = DRM_MODE_DPMS_OFF;
}

static void exynos_dp_bridge_nop(struct drm_bridge *bridge)
{
	/* do nothing */
}

static const struct drm_bridge_funcs exynos_dp_bridge_funcs = {
	.enable = exynos_dp_bridge_enable,
	.disable = exynos_dp_bridge_disable,
	.pre_enable = exynos_dp_bridge_nop,
	.post_disable = exynos_dp_bridge_nop,
	.attach = exynos_dp_bridge_attach,
};

static int exynos_dp_create_connector(struct drm_encoder *encoder)
{
	struct exynos_dp_device *dp = encoder_to_dp(encoder);
	struct drm_device *drm_dev = dp->drm_dev;
	struct drm_bridge *bridge;
	int ret;

	bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL);
	if (!bridge) {
		DRM_ERROR("failed to allocate for drm bridge\n");
		return -ENOMEM;
	}

	dp->bridge = bridge;

	encoder->bridge = bridge;
	bridge->driver_private = dp;
	bridge->encoder = encoder;
	bridge->funcs = &exynos_dp_bridge_funcs;

	ret = drm_bridge_attach(drm_dev, bridge);
	if (ret) {
		DRM_ERROR("failed to attach drm bridge\n");
		return -EINVAL;
	}

	return 0;
}

static bool exynos_dp_mode_fixup(struct drm_encoder *encoder,
				 const struct drm_display_mode *mode,
				 struct drm_display_mode *adjusted_mode)
{
	return true;
}

static void exynos_dp_mode_set(struct drm_encoder *encoder,
			       struct drm_display_mode *mode,
			       struct drm_display_mode *adjusted_mode)
{
}

static void exynos_dp_enable(struct drm_encoder *encoder)
{
}

static void exynos_dp_disable(struct drm_encoder *encoder)
{
}

static struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = {
	.mode_fixup = exynos_dp_mode_fixup,
	.mode_set = exynos_dp_mode_set,
@@ -1238,7 +1289,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
		}
	}

	if (!dp->panel && !dp->bridge) {
	if (!dp->panel && !dp->ptn_bridge) {
		ret = exynos_dp_dt_parse_panel(dp);
		if (ret)
			return ret;
@@ -1289,10 +1340,6 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)

	INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug);

	phy_power_on(dp->phy);

	exynos_dp_init_dp(dp);

	ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler,
			irq_flags, "exynos-dp", dp);
	if (ret) {
@@ -1365,9 +1412,9 @@ static int exynos_dp_probe(struct platform_device *pdev)
	if (endpoint) {
		bridge_node = of_graph_get_remote_port_parent(endpoint);
		if (bridge_node) {
			dp->bridge = of_drm_find_bridge(bridge_node);
			dp->ptn_bridge = of_drm_find_bridge(bridge_node);
			of_node_put(bridge_node);
			if (!dp->bridge)
			if (!dp->ptn_bridge)
				return -EPROBE_DEFER;
		} else
			return -EPROBE_DEFER;
+1 −0
Original line number Diff line number Diff line
@@ -153,6 +153,7 @@ struct exynos_dp_device {
	struct drm_connector	connector;
	struct drm_panel	*panel;
	struct drm_bridge	*bridge;
	struct drm_bridge	*ptn_bridge;
	struct clk		*clock;
	unsigned int		irq;
	void __iomem		*reg_base;