Skip to content
Snippets Groups Projects
Commit 8c01994d authored by Michael Tretter's avatar Michael Tretter Committed by Frieder Schrempf
Browse files

drm/exynos: move bridge driver to bridges


As the driver is not platform dependent anymore, move it to the drm
bridge driver directory.

Signed-off-by: default avatarMichael Tretter <m.tretter@pengutronix.de>
parent dee2eb13
No related branches found
No related tags found
No related merge requests found
...@@ -125,6 +125,15 @@ config DRM_PARADE_PS8640 ...@@ -125,6 +125,15 @@ config DRM_PARADE_PS8640
The PS8640 is a high-performance and low-power The PS8640 is a high-performance and low-power
MIPI DSI to eDP converter MIPI DSI to eDP converter
config DRM_SAMSUNG_DSIM
tristate "Samsung MIPI DSI bridge"
depends on OF
select DRM_KMS_HELPER
select DRM_MIPI_DSI
select DRM_PANEL
help
Samsung MIPI DSI bridge driver.
config DRM_SIL_SII8620 config DRM_SIL_SII8620
tristate "Silicon Image SII8620 HDMI/MHL bridge" tristate "Silicon Image SII8620 HDMI/MHL bridge"
depends on OF depends on OF
......
...@@ -8,6 +8,7 @@ obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v ...@@ -8,6 +8,7 @@ obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v
obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o
obj-$(CONFIG_DRM_SAMSUNG_DSIM) += samsung-dsim.o
obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o
obj-$(CONFIG_DRM_SII902X) += sii902x.o obj-$(CONFIG_DRM_SII902X) += sii902x.o
obj-$(CONFIG_DRM_SII9234) += sii9234.o obj-$(CONFIG_DRM_SII9234) += sii9234.o
......
This diff is collapsed.
...@@ -17,7 +17,6 @@ comment "CRTCs" ...@@ -17,7 +17,6 @@ comment "CRTCs"
config DRM_EXYNOS_FIMD config DRM_EXYNOS_FIMD
bool "FIMD" bool "FIMD"
depends on !FB_S3C
select MFD_SYSCON select MFD_SYSCON
help help
Choose this option if you want to use Exynos FIMD for DRM. Choose this option if you want to use Exynos FIMD for DRM.
...@@ -29,7 +28,6 @@ config DRM_EXYNOS5433_DECON ...@@ -29,7 +28,6 @@ config DRM_EXYNOS5433_DECON
config DRM_EXYNOS7_DECON config DRM_EXYNOS7_DECON
bool "DECON on Exynos7" bool "DECON on Exynos7"
depends on !FB_S3C
help help
Choose this option if you want to use Exynos DECON for DRM. Choose this option if you want to use Exynos DECON for DRM.
...@@ -56,8 +54,7 @@ config DRM_EXYNOS_DPI ...@@ -56,8 +54,7 @@ config DRM_EXYNOS_DPI
config DRM_EXYNOS_DSI config DRM_EXYNOS_DSI
bool "MIPI-DSI host" bool "MIPI-DSI host"
depends on DRM_EXYNOS_FIMD || DRM_EXYNOS5433_DECON || DRM_EXYNOS7_DECON depends on DRM_EXYNOS_FIMD || DRM_EXYNOS5433_DECON || DRM_EXYNOS7_DECON
select DRM_MIPI_DSI select DRM_SAMSUNG_DSIM
select DRM_PANEL
default n default n
help help
This enables support for Exynos MIPI-DSI device. This enables support for Exynos MIPI-DSI device.
......
...@@ -11,7 +11,7 @@ exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o ...@@ -11,7 +11,7 @@ exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o
exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o
exynosdrm-$(CONFIG_DRM_EXYNOS7_DECON) += exynos7_drm_decon.o exynosdrm-$(CONFIG_DRM_EXYNOS7_DECON) += exynos7_drm_decon.o
exynosdrm-$(CONFIG_DRM_EXYNOS_DPI) += exynos_drm_dpi.o exynosdrm-$(CONFIG_DRM_EXYNOS_DPI) += exynos_drm_dpi.o
exynosdrm-$(CONFIG_DRM_EXYNOS_DSI) += exynos_drm_dsi.o exynos_drm_dsi_pltfm.o exynosdrm-$(CONFIG_DRM_EXYNOS_DSI) += exynos_drm_dsi.o
exynosdrm-$(CONFIG_DRM_EXYNOS_DP) += exynos_dp.o exynosdrm-$(CONFIG_DRM_EXYNOS_DP) += exynos_dp.o
exynosdrm-$(CONFIG_DRM_EXYNOS_MIXER) += exynos_mixer.o exynosdrm-$(CONFIG_DRM_EXYNOS_MIXER) += exynos_mixer.o
exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o
......
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0-only
/*
* Samsung SoC MIPI DSI Master driver.
*
* Copyright (c) 2014 Samsung Electronics Co., Ltd
*
* Contacts: Tomasz Figa <t.figa@samsung.com>
*/
#include <linux/component.h>
#include <linux/of_device.h>
#include <linux/of_graph.h>
#include <linux/pm_runtime.h>
#include <drm/drm_bridge.h>
#include <drm/drm_encoder.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>
#include "exynos_drm_crtc.h"
#include "exynos_drm_drv.h"
#include "exynos_drm_dsi.h"
enum {
DSI_PORT_IN,
DSI_PORT_OUT
};
struct exynos_dsi_pltfm {
struct exynos_dsi *dsi;
struct drm_encoder encoder;
};
static const unsigned int reg_values[] = {
[RESET_TYPE] = DSIM_SWRST,
[PLL_TIMER] = 500,
[STOP_STATE_CNT] = 0xf,
[PHYCTRL_ULPS_EXIT] = 0x0af,
[PHYCTRL_VREG_LP] = 0,
[PHYCTRL_SLEW_UP] = 0,
[PHYTIMING_LPX] = 0x06,
[PHYTIMING_HS_EXIT] = 0x0b,
[PHYTIMING_CLK_PREPARE] = 0x07,
[PHYTIMING_CLK_ZERO] = 0x27,
[PHYTIMING_CLK_POST] = 0x0d,
[PHYTIMING_CLK_TRAIL] = 0x08,
[PHYTIMING_HS_PREPARE] = 0x09,
[PHYTIMING_HS_ZERO] = 0x0d,
[PHYTIMING_HS_TRAIL] = 0x0b,
};
static const unsigned int exynos5422_reg_values[] = {
[RESET_TYPE] = DSIM_SWRST,
[PLL_TIMER] = 500,
[STOP_STATE_CNT] = 0xf,
[PHYCTRL_ULPS_EXIT] = 0xaf,
[PHYCTRL_VREG_LP] = 0,
[PHYCTRL_SLEW_UP] = 0,
[PHYTIMING_LPX] = 0x08,
[PHYTIMING_HS_EXIT] = 0x0d,
[PHYTIMING_CLK_PREPARE] = 0x09,
[PHYTIMING_CLK_ZERO] = 0x30,
[PHYTIMING_CLK_POST] = 0x0e,
[PHYTIMING_CLK_TRAIL] = 0x0a,
[PHYTIMING_HS_PREPARE] = 0x0c,
[PHYTIMING_HS_ZERO] = 0x11,
[PHYTIMING_HS_TRAIL] = 0x0d,
};
static const unsigned int exynos5433_reg_values[] = {
[RESET_TYPE] = DSIM_FUNCRST,
[PLL_TIMER] = 22200,
[STOP_STATE_CNT] = 0xa,
[PHYCTRL_ULPS_EXIT] = 0x190,
[PHYCTRL_VREG_LP] = 1,
[PHYCTRL_SLEW_UP] = 1,
[PHYTIMING_LPX] = 0x07,
[PHYTIMING_HS_EXIT] = 0x0c,
[PHYTIMING_CLK_PREPARE] = 0x09,
[PHYTIMING_CLK_ZERO] = 0x2d,
[PHYTIMING_CLK_POST] = 0x0e,
[PHYTIMING_CLK_TRAIL] = 0x09,
[PHYTIMING_HS_PREPARE] = 0x0b,
[PHYTIMING_HS_ZERO] = 0x10,
[PHYTIMING_HS_TRAIL] = 0x0c,
};
static int __exynos_dsi_host_attach(struct device *dev,
struct mipi_dsi_device *device)
{
struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev);
struct drm_device *drm = dsi->encoder.dev;
struct exynos_drm_crtc *crtc;
mutex_lock(&drm->mode_config.mutex);
crtc = exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD);
crtc->i80_mode = !(device->mode_flags & MIPI_DSI_MODE_VIDEO);
mutex_unlock(&drm->mode_config.mutex);
if (drm->mode_config.poll_enabled)
drm_kms_helper_hotplug_event(drm);
return 0;
}
static int __exynos_dsi_host_detach(struct device *dev,
struct mipi_dsi_device *device)
{
struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev);
struct drm_device *drm = dsi->encoder.dev;
if (drm->mode_config.poll_enabled)
drm_kms_helper_hotplug_event(drm);
return 0;
}
static void __exynos_dsi_te_handler(struct device *dev)
{
struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev);
exynos_drm_crtc_te_handler(dsi->encoder.crtc);
}
static const struct exynos_dsi_host_ops exynos_dsi_host_ops = {
.attach = __exynos_dsi_host_attach,
.detach = __exynos_dsi_host_detach,
.te_handler = __exynos_dsi_te_handler,
};
static const struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
.reg_ofs = EXYNOS_REG_OFS,
.plltmr_reg = 0x50,
.has_freqband = 1,
.has_clklane_stop = 1,
.num_clks = 2,
.max_freq = 1000,
.wait_for_reset = 1,
.num_bits_resol = 11,
.reg_values = reg_values,
.host_ops = &exynos_dsi_host_ops,
};
static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
.reg_ofs = EXYNOS_REG_OFS,
.plltmr_reg = 0x50,
.has_freqband = 1,
.has_clklane_stop = 1,
.num_clks = 2,
.max_freq = 1000,
.wait_for_reset = 1,
.num_bits_resol = 11,
.reg_values = reg_values,
.host_ops = &exynos_dsi_host_ops,
};
static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
.reg_ofs = EXYNOS_REG_OFS,
.plltmr_reg = 0x58,
.num_clks = 2,
.max_freq = 1000,
.wait_for_reset = 1,
.num_bits_resol = 11,
.reg_values = reg_values,
.host_ops = &exynos_dsi_host_ops,
};
static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
.reg_ofs = EXYNOS5433_REG_OFS,
.plltmr_reg = 0xa0,
.has_clklane_stop = 1,
.num_clks = 5,
.max_freq = 1500,
.wait_for_reset = 0,
.num_bits_resol = 12,
.reg_values = exynos5433_reg_values,
.host_ops = &exynos_dsi_host_ops,
};
static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
.reg_ofs = EXYNOS5433_REG_OFS,
.plltmr_reg = 0xa0,
.has_clklane_stop = 1,
.num_clks = 2,
.max_freq = 1500,
.wait_for_reset = 1,
.num_bits_resol = 12,
.reg_values = exynos5422_reg_values,
.host_ops = &exynos_dsi_host_ops,
};
static const struct of_device_id exynos_dsi_of_match[] = {
{ .compatible = "samsung,exynos3250-mipi-dsi",
.data = &exynos3_dsi_driver_data },
{ .compatible = "samsung,exynos4210-mipi-dsi",
.data = &exynos4_dsi_driver_data },
{ .compatible = "samsung,exynos5410-mipi-dsi",
.data = &exynos5_dsi_driver_data },
{ .compatible = "samsung,exynos5422-mipi-dsi",
.data = &exynos5422_dsi_driver_data },
{ .compatible = "samsung,exynos5433-mipi-dsi",
.data = &exynos5433_dsi_driver_data },
{ }
};
static int exynos_dsi_pltfm_bind(struct device *dev, struct device *master, void *data)
{
struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev);
struct drm_encoder *encoder = &dsi->encoder;
struct drm_device *drm_dev = data;
struct device_node *in_bridge_node;
struct drm_bridge *in_bridge;
int ret;
drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_LCD);
if (ret < 0)
return ret;
in_bridge_node = of_graph_get_remote_node(dev->of_node, DSI_PORT_IN, 0);
if (in_bridge_node) {
in_bridge = of_drm_find_bridge(in_bridge_node);
if (in_bridge)
drm_bridge_attach(encoder, in_bridge, NULL, 0);
of_node_put(in_bridge_node);
}
ret = exynos_dsi_bind(dsi->dsi, encoder);
if (ret)
goto err;
return 0;
err:
drm_encoder_cleanup(encoder);
return ret;
}
static void exynos_dsi_pltfm_unbind(struct device *dev, struct device *master,
void *data)
{
struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev);
struct drm_encoder *encoder = &dsi->encoder;
exynos_dsi_unbind(dsi->dsi);
drm_encoder_cleanup(encoder);
}
static const struct component_ops exynos_dsi_pltfm_component_ops = {
.bind = exynos_dsi_pltfm_bind,
.unbind = exynos_dsi_pltfm_unbind,
};
static int exynos_dsi_pltfm_probe(struct platform_device *pdev)
{
struct exynos_dsi_pltfm *dsi;
struct device *dev = &pdev->dev;
int ret;
dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
if (!dsi)
return -ENOMEM;
platform_set_drvdata(pdev, dsi);
dsi->dsi = exynos_dsi_probe(pdev);
if (IS_ERR(dsi->dsi))
return PTR_ERR(dsi->dsi);
pm_runtime_enable(dev);
ret = component_add(dev, &exynos_dsi_pltfm_component_ops);
if (ret)
goto err_disable_runtime;
return 0;
err_disable_runtime:
pm_runtime_disable(dev);
return ret;
}
static int exynos_dsi_pltfm_remove(struct platform_device *pdev)
{
struct exynos_dsi_pltfm *dsi = platform_get_drvdata(pdev);
pm_runtime_disable(&pdev->dev);
exynos_dsi_remove(dsi->dsi);
component_del(&pdev->dev, &exynos_dsi_pltfm_component_ops);
return 0;
}
static int __maybe_unused exynos_dsi_pltfm_suspend(struct device *dev)
{
struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev);
return exynos_dsi_suspend(dsi->dsi);
}
static int __maybe_unused exynos_dsi_pltfm_resume(struct device *dev)
{
struct exynos_dsi_pltfm *dsi = dev_get_drvdata(dev);
return exynos_dsi_resume(dsi->dsi);
}
static const struct dev_pm_ops exynos_dsi_pm_ops = {
SET_RUNTIME_PM_OPS(exynos_dsi_pltfm_suspend, exynos_dsi_pltfm_resume, NULL)
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
pm_runtime_force_resume)
};
struct platform_driver dsi_driver = {
.probe = exynos_dsi_pltfm_probe,
.remove = exynos_dsi_pltfm_remove,
.driver = {
.name = "exynos-dsi",
.owner = THIS_MODULE,
.pm = &exynos_dsi_pm_ops,
.of_match_table = exynos_dsi_of_match,
},
};
MODULE_AUTHOR("Tomasz Figa <t.figa@samsung.com>");
MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
MODULE_DESCRIPTION("Samsung SoC MIPI DSI Master");
MODULE_LICENSE("GPL v2");
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#define __EXYNOS_DRM_DSI__ #define __EXYNOS_DRM_DSI__
struct drm_encoder; struct drm_encoder;
struct exynos_dsi; struct samsung_dsim;
struct platform_device; struct platform_device;
struct mipi_dsi_device; struct mipi_dsi_device;
...@@ -12,13 +12,13 @@ enum exynos_reg_offset { ...@@ -12,13 +12,13 @@ enum exynos_reg_offset {
EXYNOS5433_REG_OFS EXYNOS5433_REG_OFS
}; };
struct exynos_dsi *exynos_dsi_probe(struct platform_device *pdev); struct samsung_dsim *samsung_dsim_probe(struct platform_device *pdev);
void exynos_dsi_remove(struct exynos_dsi *dsi); void samsung_dsim_remove(struct samsung_dsim *dsi);
int exynos_dsi_bind(struct exynos_dsi *dsi, struct drm_encoder *encoder); int samsung_dsim_bind(struct samsung_dsim *dsi, struct drm_encoder *encoder);
void exynos_dsi_unbind(struct exynos_dsi *dsi); void samsung_dsim_unbind(struct samsung_dsim *dsi);
int exynos_dsi_suspend(struct exynos_dsi *dsi); int samsung_dsim_suspend(struct samsung_dsim *dsi);
int exynos_dsi_resume(struct exynos_dsi *dsi); int samsung_dsim_resume(struct samsung_dsim *dsi);
enum reg_value_idx { enum reg_value_idx {
RESET_TYPE, RESET_TYPE,
...@@ -42,13 +42,13 @@ enum reg_value_idx { ...@@ -42,13 +42,13 @@ enum reg_value_idx {
#define DSIM_FUNCRST (1 << 16) #define DSIM_FUNCRST (1 << 16)
#define DSIM_SWRST (1 << 0) #define DSIM_SWRST (1 << 0)
struct exynos_dsi_host_ops { struct samsung_dsim_host_ops {
int (*attach)(struct device *dev, struct mipi_dsi_device *device); int (*attach)(struct device *dev, struct mipi_dsi_device *device);
int (*detach)(struct device *dev, struct mipi_dsi_device *device); int (*detach)(struct device *dev, struct mipi_dsi_device *device);
void (*te_handler)(struct device *dev); void (*te_handler)(struct device *dev);
}; };
struct exynos_dsi_driver_data { struct samsung_dsim_driver_data {
enum exynos_reg_offset reg_ofs; enum exynos_reg_offset reg_ofs;
unsigned int plltmr_reg; unsigned int plltmr_reg;
unsigned int has_freqband:1; unsigned int has_freqband:1;
...@@ -58,7 +58,7 @@ struct exynos_dsi_driver_data { ...@@ -58,7 +58,7 @@ struct exynos_dsi_driver_data {
unsigned int wait_for_reset; unsigned int wait_for_reset;
unsigned int num_bits_resol; unsigned int num_bits_resol;
const unsigned int *reg_values; const unsigned int *reg_values;
const struct exynos_dsi_host_ops *host_ops; const struct samsung_dsim_host_ops *host_ops;
}; };
#endif /* __EXYNOS_DRM_DSI__ */ #endif /* __EXYNOS_DRM_DSI__ */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment