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

Commit 1417f109 authored by Sean Paul's avatar Sean Paul Committed by Inki Dae
Browse files

drm/exynos: Move display implementation into dp



This patch moves the exynos_drm_display implementation from fimd into
the dp driver. This will allow for tighter integration of the dp driver
into the exynos drm driver.

Signed-off-by: default avatarSean Paul <seanpaul@chromium.org>
Signed-off-by: default avatarInki Dae <inki.dae@samsung.com>
parent 2e4e678a
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@ Required properties for dp-controller:
	-samsung,lane-count:
		number of lanes supported by the panel.
			LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
	- display-timings: timings for the connected panel as described by
		Documentation/devicetree/bindings/video/display-timing.txt

Optional properties for dp-controller:
	-interlaced:
@@ -84,4 +86,19 @@ Board Specific portion:
		samsung,color-depth = <1>;
		samsung,link-rate = <0x0a>;
		samsung,lane-count = <4>;

		display-timings {
			native-mode = <&lcd_timing>;
			lcd_timing: 1366x768 {
				clock-frequency = <70589280>;
				hactive = <1366>;
				vactive = <768>;
				hfront-porch = <40>;
				hback-porch = <40>;
				hsync-len = <32>;
				vback-porch = <10>;
				vfront-porch = <12>;
				vsync-len = <6>;
			};
		};
	};
+2 −0
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@ Required properties:

Optional Properties:
- samsung,power-domain: a phandle to FIMD power domain node.
- samsung,invert-vden: video enable signal is inverted
- samsung,invert-vclk: video clock signal is inverted

Example:

+81 −19
Original line number Diff line number Diff line
@@ -19,7 +19,12 @@
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
#include <video/of_display_timing.h>
#include <video/of_videomode.h>

#include <drm/drmP.h>

#include "exynos_drm_drv.h"
#include "exynos_dp_core.h"

static int exynos_dp_init_dp(struct exynos_dp_device *dp)
@@ -892,6 +897,35 @@ static void exynos_dp_hotplug(struct work_struct *work)
		dev_err(dp->dev, "unable to config video\n");
}

static bool exynos_dp_display_is_connected(struct exynos_drm_display *display)
{
	return true;
}

static void *exynos_dp_get_panel(struct exynos_drm_display *display)
{
	struct exynos_dp_device *dp = display->ctx;

	return &dp->panel;
}

static int exynos_dp_check_mode(struct exynos_drm_display *display,
			struct drm_display_mode *mode)
{
	return 0;
}

static struct exynos_drm_display_ops exynos_dp_display_ops = {
	.is_connected = exynos_dp_display_is_connected,
	.get_panel = exynos_dp_get_panel,
	.check_mode = exynos_dp_check_mode,
};

static struct exynos_drm_display exynos_dp_display = {
	.type = EXYNOS_DISPLAY_TYPE_LCD,
	.ops = &exynos_dp_display_ops,
};

static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
{
	struct device_node *dp_node = dev->of_node;
@@ -993,6 +1027,19 @@ static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
	return ret;
}

static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
{
	int ret;

	ret = of_get_videomode(dp->dev->of_node, &dp->panel.vm,
			OF_USE_NATIVE_MODE);
	if (ret) {
		DRM_ERROR("failed: of_get_videomode() : %d\n", ret);
		return ret;
	}
	return 0;
}

static void exynos_dp_phy_init(struct exynos_dp_device *dp)
{
	if (dp->phy) {
@@ -1019,6 +1066,28 @@ static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
	}
}

void exynos_dp_poweron(struct exynos_dp_device *dp)
{
	exynos_dp_phy_init(dp);

	clk_prepare_enable(dp->clock);

	exynos_dp_init_dp(dp);

	enable_irq(dp->irq);
}

void exynos_dp_poweroff(struct exynos_dp_device *dp)
{
	disable_irq(dp->irq);

	flush_work(&dp->hotplug_work);

	exynos_dp_phy_exit(dp);

	clk_disable_unprepare(dp->clock);
}

static int exynos_dp_probe(struct platform_device *pdev)
{
	struct resource *res;
@@ -1043,6 +1112,10 @@ static int exynos_dp_probe(struct platform_device *pdev)
	if (ret)
		return ret;

	ret = exynos_dp_dt_parse_panel(dp);
	if (ret)
		return ret;

	dp->clock = devm_clk_get(&pdev->dev, "dp");
	if (IS_ERR(dp->clock)) {
		dev_err(&pdev->dev, "failed to get clock\n");
@@ -1078,6 +1151,9 @@ static int exynos_dp_probe(struct platform_device *pdev)

	platform_set_drvdata(pdev, dp);

	exynos_dp_display.ctx = dp;
	exynos_drm_display_register(&exynos_dp_display);

	return 0;
}

@@ -1085,6 +1161,8 @@ static int exynos_dp_remove(struct platform_device *pdev)
{
	struct exynos_dp_device *dp = platform_get_drvdata(pdev);

	exynos_drm_display_unregister(&exynos_dp_display);

	flush_work(&dp->hotplug_work);

	exynos_dp_phy_exit(dp);
@@ -1100,14 +1178,7 @@ static int exynos_dp_suspend(struct device *dev)
{
	struct exynos_dp_device *dp = dev_get_drvdata(dev);

	disable_irq(dp->irq);

	flush_work(&dp->hotplug_work);

	exynos_dp_phy_exit(dp);

	clk_disable_unprepare(dp->clock);

	exynos_dp_poweroff(dp);
	return 0;
}

@@ -1115,14 +1186,7 @@ static int exynos_dp_resume(struct device *dev)
{
	struct exynos_dp_device *dp = dev_get_drvdata(dev);

	exynos_dp_phy_init(dp);

	clk_prepare_enable(dp->clock);

	exynos_dp_init_dp(dp);

	enable_irq(dp->irq);

	exynos_dp_poweron(dp);
	return 0;
}
#endif
@@ -1137,7 +1201,7 @@ static const struct of_device_id exynos_dp_match[] = {
};
MODULE_DEVICE_TABLE(of, exynos_dp_match);

static struct platform_driver exynos_dp_driver = {
struct platform_driver dp_driver = {
	.probe		= exynos_dp_probe,
	.remove		= exynos_dp_remove,
	.driver		= {
@@ -1148,8 +1212,6 @@ static struct platform_driver exynos_dp_driver = {
	},
};

module_platform_driver(exynos_dp_driver);

MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
MODULE_DESCRIPTION("Samsung SoC DP Driver");
MODULE_LICENSE("GPL");
+4 −0
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@
#ifndef _EXYNOS_DP_CORE_H
#define _EXYNOS_DP_CORE_H

#include <drm/exynos_drm.h>

#define DP_TIMEOUT_LOOP_COUNT 100
#define MAX_CR_LOOP 5
#define MAX_EQ_LOOP 5
@@ -152,6 +154,8 @@ struct exynos_dp_device {
	struct link_train	link_train;
	struct work_struct	hotplug_work;
	struct phy		*phy;

	struct exynos_drm_panel_info panel;
};

/* exynos_dp_reg.c */
+14 −0
Original line number Diff line number Diff line
@@ -357,6 +357,12 @@ static int __init exynos_drm_init(void)
{
	int ret;

#ifdef CONFIG_DRM_EXYNOS_DP
	ret = platform_driver_register(&dp_driver);
	if (ret < 0)
		goto out_dp;
#endif

#ifdef CONFIG_DRM_EXYNOS_FIMD
	ret = platform_driver_register(&fimd_driver);
	if (ret < 0)
@@ -471,6 +477,10 @@ static int __init exynos_drm_init(void)
#ifdef CONFIG_DRM_EXYNOS_FIMD
	platform_driver_unregister(&fimd_driver);
out_fimd:
#endif
#ifdef CONFIG_DRM_EXYNOS_DP
	platform_driver_unregister(&dp_driver);
out_dp:
#endif
	return ret;
}
@@ -514,6 +524,10 @@ static void __exit exynos_drm_exit(void)
#ifdef CONFIG_DRM_EXYNOS_FIMD
	platform_driver_unregister(&fimd_driver);
#endif

#ifdef CONFIG_DRM_EXYNOS_DP
	platform_driver_unregister(&dp_driver);
#endif
}

module_init(exynos_drm_init);
Loading