Merge branch 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-next
Summary:
- Add Exynos5420 SoC support to FIMD driver.
. This patch makes MIC(Mobile Image Compressor) IP to be bypassed in default
in case of Exynos5420 and later. The Display pipe line configuraion for
Exynos DRM driver will be considered through of graph concept later.
- Add Exynos5422 SoC support to MIPI-DSI driver.
. Exynos5422 SoC is similar to Exynos5433 SoC but software reset is different
each other so this patch consideres the difference.
- Get more precise clock divider value of FIMD controller.
. This patch changes DIV_ROUND_CLOSEST macro to be used instead of DIV_ROUND_UP.
- Refactor Exynos DRM device and driver registeration.
. This patch makes Exynos DRM driver to be easy-to-read and at the same time,
cleans it up by removing #ifdef ~ #endif things.
- Configure DMA-mapping address space common to Exynos DRM devices in more generic
without any hacks.
- some fixups and cleanups.
* 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: (26 commits)
drm/exynos/dsi: use core helper to create DSI packet
drm/exynos: use real device for DMA-mapping operations
drm/exynos: refactor driver and device registration code
drm/exynos: use arch independent types in uapi header
drm/exynos: remove platform data structures and include/drm/exynos_drm.h
drm/exynos/fimc: remove unused camera interface polarization code
drm/exynos: remove struct exynos_drm_panel_info
drm/exynos: add exynos5420 support for fimd
drm/exynos: use DIV_ROUND_CLOSEST to find the closest div
drm/exynos: remove incorrect ccflags from Makefile
drm/exynos/decon: make irq handler static
drm/exynos/hdmi: remove unused variable
drm/exynos/dsi: constify read only structures
drm/exynos/dsi: replace registry access macros with functions
drm/exynos: support exynos5422 mipi-dsi
drm/exynos/decon: fix disable clocks order
drm/exynos: fix incorrect cpu address for dma_mmap_attrs()
drm/exynos: exynos5433_decon: fix wrong state in decon_vblank_enable
drm/exynos: exynos5433_decon: fix wrong state assignment in decon_enable
drm/exynos: dsi: restore support for drm bridge
...
diff --git a/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt b/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
index 0e6f0c0..22756b3 100644
--- a/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
+++ b/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
@@ -6,6 +6,7 @@
"samsung,exynos4210-mipi-dsi" /* for Exynos4 SoCs */
"samsung,exynos4415-mipi-dsi" /* for Exynos4415 SoC */
"samsung,exynos5410-mipi-dsi" /* for Exynos5410/5420/5440 SoCs */
+ "samsung,exynos5422-mipi-dsi" /* for Exynos5422/5800 SoCs */
"samsung,exynos5433-mipi-dsi" /* for Exynos5433 SoCs */
- reg: physical base address and length of the registers set for the device
- interrupts: should contain DSI interrupt
diff --git a/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt b/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt
index 27c3ce0..c7c6b9a 100644
--- a/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt
+++ b/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt
@@ -12,7 +12,8 @@
"samsung,exynos3250-fimd"; /* for Exynos3250/3472 SoCs */
"samsung,exynos4210-fimd"; /* for Exynos4 SoCs */
"samsung,exynos4415-fimd"; /* for Exynos4415 SoC */
- "samsung,exynos5250-fimd"; /* for Exynos5 SoCs */
+ "samsung,exynos5250-fimd"; /* for Exynos5250 SoCs */
+ "samsung,exynos5420-fimd"; /* for Exynos5420/5422/5800 SoCs */
- reg: physical base address and length of the FIMD registers set.
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 83efca9..f17d392 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -1,6 +1,6 @@
config DRM_EXYNOS
tristate "DRM Support for Samsung SoC EXYNOS Series"
- depends on OF && DRM && (PLAT_SAMSUNG || ARCH_MULTIPLATFORM)
+ depends on OF && DRM && (ARCH_S3C64XX || ARCH_EXYNOS || ARCH_MULTIPLATFORM)
select DRM_KMS_HELPER
select DRM_KMS_FB_HELPER
select FB_CFB_FILLRECT
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 6496532..968b31c 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -2,7 +2,6 @@
# Makefile for the drm device driver. This driver provides support for the
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
-ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/exynos
exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fbdev.o \
exynos_drm_fb.o exynos_drm_gem.o exynos_drm_core.o \
exynos_drm_plane.o
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index 1bf6a21..5245bc5 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -93,7 +93,7 @@
if (test_bit(BIT_SUSPENDED, &ctx->flags))
return -EPERM;
- if (test_and_set_bit(BIT_IRQS_ENABLED, &ctx->flags)) {
+ if (!test_and_set_bit(BIT_IRQS_ENABLED, &ctx->flags)) {
val = VIDINTCON0_INTEN;
if (ctx->out_type == IFTYPE_I80)
val |= VIDINTCON0_FRAMEDONE;
@@ -402,8 +402,6 @@
decon_enable_vblank(ctx->crtc);
decon_commit(ctx->crtc);
-
- set_bit(BIT_SUSPENDED, &ctx->flags);
}
static void decon_disable(struct exynos_drm_crtc *crtc)
@@ -431,7 +429,7 @@
set_bit(BIT_SUSPENDED, &ctx->flags);
}
-void decon_te_irq_handler(struct exynos_drm_crtc *crtc)
+static void decon_te_irq_handler(struct exynos_drm_crtc *crtc)
{
struct decon_context *ctx = crtc->ctx;
@@ -582,9 +580,9 @@
static int exynos5433_decon_suspend(struct device *dev)
{
struct decon_context *ctx = dev_get_drvdata(dev);
- int i;
+ int i = ARRAY_SIZE(decon_clks_name);
- for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++)
+ while (--i >= 0)
clk_disable_unprepare(ctx->clks[i]);
return 0;
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index 52bda3b..9336107 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -60,7 +60,6 @@
wait_queue_head_t wait_vsync_queue;
atomic_t wait_vsync_event;
- struct exynos_drm_panel_info panel;
struct drm_encoder *encoder;
};
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 9fd12c62..cff8dc7 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -977,9 +977,7 @@
return 0;
}
- drm_display_mode_from_videomode(&dp->priv.vm, mode);
- mode->width_mm = dp->priv.width_mm;
- mode->height_mm = dp->priv.height_mm;
+ drm_display_mode_from_videomode(&dp->vm, mode);
connector->display_info.width_mm = mode->width_mm;
connector->display_info.height_mm = mode->height_mm;
@@ -1241,8 +1239,7 @@
{
int ret;
- ret = of_get_videomode(dp->dev->of_node, &dp->priv.vm,
- OF_USE_NATIVE_MODE);
+ ret = of_get_videomode(dp->dev->of_node, &dp->vm, OF_USE_NATIVE_MODE);
if (ret) {
DRM_ERROR("failed: of_get_videomode() : %d\n", ret);
return ret;
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index 66eec4b..b5c2d8f 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -16,6 +16,7 @@
#include <drm/drm_crtc.h>
#include <drm/drm_dp_helper.h>
#include <drm/exynos_drm.h>
+#include <video/videomode.h>
#include "exynos_drm_drv.h"
@@ -164,8 +165,7 @@
struct phy *phy;
int dpms_mode;
int hpd_gpio;
-
- struct exynos_drm_panel_info priv;
+ struct videomode vm;
};
/* exynos_dp_reg.c */
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 1e535f9..0dcfa04 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -130,6 +130,8 @@
exynos_atomic_commit_complete(commit);
}
+static struct device *exynos_drm_get_dma_device(void);
+
static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
{
struct exynos_drm_private *private;
@@ -147,6 +149,16 @@
dev_set_drvdata(dev->dev, dev);
dev->dev_private = (void *)private;
+ /* the first real CRTC device is used for all dma mapping operations */
+ private->dma_dev = exynos_drm_get_dma_device();
+ if (!private->dma_dev) {
+ DRM_ERROR("no device found for DMA mapping operations.\n");
+ ret = -ENODEV;
+ goto err_free_private;
+ }
+ DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n",
+ dev_name(private->dma_dev));
+
/*
* create mapping to manage iommu table and set a pointer to iommu
* mapping structure to iommu_mapping of private data.
@@ -481,70 +493,66 @@
/* forward declaration */
static struct platform_driver exynos_drm_platform_driver;
+struct exynos_drm_driver_info {
+ struct platform_driver *driver;
+ unsigned int flags;
+};
+
+#define DRM_COMPONENT_DRIVER BIT(0) /* supports component framework */
+#define DRM_VIRTUAL_DEVICE BIT(1) /* create virtual platform device */
+#define DRM_DMA_DEVICE BIT(2) /* can be used for dma allocations */
+
+#define DRV_PTR(drv, cond) (IS_ENABLED(cond) ? &drv : NULL)
+
/*
* Connector drivers should not be placed before associated crtc drivers,
* because connector requires pipe number of its crtc during initialization.
*/
-static struct platform_driver *const exynos_drm_kms_drivers[] = {
-#ifdef CONFIG_DRM_EXYNOS_FIMD
- &fimd_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS5433_DECON
- &exynos5433_decon_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS7_DECON
- &decon_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_MIC
- &mic_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_DP
- &dp_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_DSI
- &dsi_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_MIXER
- &mixer_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_HDMI
- &hdmi_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_VIDI
- &vidi_driver,
-#endif
+static struct exynos_drm_driver_info exynos_drm_drivers[] = {
+ {
+ DRV_PTR(fimd_driver, CONFIG_DRM_EXYNOS_FIMD),
+ DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
+ }, {
+ DRV_PTR(exynos5433_decon_driver, CONFIG_DRM_EXYNOS5433_DECON),
+ DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
+ }, {
+ DRV_PTR(decon_driver, CONFIG_DRM_EXYNOS7_DECON),
+ DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
+ }, {
+ DRV_PTR(mixer_driver, CONFIG_DRM_EXYNOS_MIXER),
+ DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
+ }, {
+ DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC),
+ DRM_COMPONENT_DRIVER
+ }, {
+ DRV_PTR(dp_driver, CONFIG_DRM_EXYNOS_DP),
+ DRM_COMPONENT_DRIVER
+ }, {
+ DRV_PTR(dsi_driver, CONFIG_DRM_EXYNOS_DSI),
+ DRM_COMPONENT_DRIVER
+ }, {
+ DRV_PTR(hdmi_driver, CONFIG_DRM_EXYNOS_HDMI),
+ DRM_COMPONENT_DRIVER
+ }, {
+ DRV_PTR(vidi_driver, CONFIG_DRM_EXYNOS_VIDI),
+ DRM_COMPONENT_DRIVER | DRM_VIRTUAL_DEVICE
+ }, {
+ DRV_PTR(g2d_driver, CONFIG_DRM_EXYNOS_G2D),
+ }, {
+ DRV_PTR(fimc_driver, CONFIG_DRM_EXYNOS_FIMC),
+ }, {
+ DRV_PTR(rotator_driver, CONFIG_DRM_EXYNOS_ROTATOR),
+ }, {
+ DRV_PTR(gsc_driver, CONFIG_DRM_EXYNOS_GSC),
+ }, {
+ DRV_PTR(ipp_driver, CONFIG_DRM_EXYNOS_IPP),
+ DRM_VIRTUAL_DEVICE
+ }, {
+ &exynos_drm_platform_driver,
+ DRM_VIRTUAL_DEVICE
+ }
};
-static struct platform_driver *const exynos_drm_non_kms_drivers[] = {
-#ifdef CONFIG_DRM_EXYNOS_G2D
- &g2d_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_FIMC
- &fimc_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_ROTATOR
- &rotator_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_GSC
- &gsc_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_IPP
- &ipp_driver,
-#endif
- &exynos_drm_platform_driver,
-};
-
-static struct platform_driver *const exynos_drm_drv_with_simple_dev[] = {
-#ifdef CONFIG_DRM_EXYNOS_VIDI
- &vidi_driver,
-#endif
-#ifdef CONFIG_DRM_EXYNOS_IPP
- &ipp_driver,
-#endif
- &exynos_drm_platform_driver,
-};
-#define PDEV_COUNT ARRAY_SIZE(exynos_drm_drv_with_simple_dev)
-
static int compare_dev(struct device *dev, void *data)
{
return dev == (struct device *)data;
@@ -555,11 +563,15 @@
struct component_match *match = NULL;
int i;
- for (i = 0; i < ARRAY_SIZE(exynos_drm_kms_drivers); ++i) {
- struct device_driver *drv = &exynos_drm_kms_drivers[i]->driver;
+ for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) {
+ struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
struct device *p = NULL, *d;
- while ((d = bus_find_device(&platform_bus_type, p, drv,
+ if (!info->driver || !(info->flags & DRM_COMPONENT_DRIVER))
+ continue;
+
+ while ((d = bus_find_device(&platform_bus_type, p,
+ &info->driver->driver,
(void *)platform_bus_type.match))) {
put_device(p);
component_match_add(dev, &match, compare_dev, d);
@@ -616,91 +628,102 @@
},
};
-static struct platform_device *exynos_drm_pdevs[PDEV_COUNT];
+static struct device *exynos_drm_get_dma_device(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) {
+ struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
+ struct device *dev;
+
+ if (!info->driver || !(info->flags & DRM_DMA_DEVICE))
+ continue;
+
+ while ((dev = bus_find_device(&platform_bus_type, NULL,
+ &info->driver->driver,
+ (void *)platform_bus_type.match))) {
+ put_device(dev);
+ return dev;
+ }
+ }
+ return NULL;
+}
static void exynos_drm_unregister_devices(void)
{
- int i = PDEV_COUNT;
+ int i;
- while (--i >= 0) {
- platform_device_unregister(exynos_drm_pdevs[i]);
- exynos_drm_pdevs[i] = NULL;
+ for (i = ARRAY_SIZE(exynos_drm_drivers) - 1; i >= 0; --i) {
+ struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
+ struct device *dev;
+
+ if (!info->driver || !(info->flags & DRM_VIRTUAL_DEVICE))
+ continue;
+
+ while ((dev = bus_find_device(&platform_bus_type, NULL,
+ &info->driver->driver,
+ (void *)platform_bus_type.match))) {
+ put_device(dev);
+ platform_device_unregister(to_platform_device(dev));
+ }
}
}
static int exynos_drm_register_devices(void)
{
+ struct platform_device *pdev;
int i;
- for (i = 0; i < PDEV_COUNT; ++i) {
- struct platform_driver *d = exynos_drm_drv_with_simple_dev[i];
- struct platform_device *pdev =
- platform_device_register_simple(d->driver.name, -1,
- NULL, 0);
+ for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) {
+ struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
- if (!IS_ERR(pdev)) {
- exynos_drm_pdevs[i] = pdev;
+ if (!info->driver || !(info->flags & DRM_VIRTUAL_DEVICE))
continue;
- }
- while (--i >= 0) {
- platform_device_unregister(exynos_drm_pdevs[i]);
- exynos_drm_pdevs[i] = NULL;
- }
- return PTR_ERR(pdev);
+ pdev = platform_device_register_simple(
+ info->driver->driver.name, -1, NULL, 0);
+ if (IS_ERR(pdev))
+ goto fail;
}
return 0;
+fail:
+ exynos_drm_unregister_devices();
+ return PTR_ERR(pdev);
}
-static void exynos_drm_unregister_drivers(struct platform_driver * const *drv,
- int count)
+static void exynos_drm_unregister_drivers(void)
{
- while (--count >= 0)
- platform_driver_unregister(drv[count]);
+ int i;
+
+ for (i = ARRAY_SIZE(exynos_drm_drivers) - 1; i >= 0; --i) {
+ struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
+
+ if (!info->driver)
+ continue;
+
+ platform_driver_unregister(info->driver);
+ }
}
-static int exynos_drm_register_drivers(struct platform_driver * const *drv,
- int count)
+static int exynos_drm_register_drivers(void)
{
int i, ret;
- for (i = 0; i < count; ++i) {
- ret = platform_driver_register(drv[i]);
- if (!ret)
+ for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) {
+ struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
+
+ if (!info->driver)
continue;
- while (--i >= 0)
- platform_driver_unregister(drv[i]);
-
- return ret;
+ ret = platform_driver_register(info->driver);
+ if (ret)
+ goto fail;
}
-
return 0;
-}
-
-static inline int exynos_drm_register_kms_drivers(void)
-{
- return exynos_drm_register_drivers(exynos_drm_kms_drivers,
- ARRAY_SIZE(exynos_drm_kms_drivers));
-}
-
-static inline int exynos_drm_register_non_kms_drivers(void)
-{
- return exynos_drm_register_drivers(exynos_drm_non_kms_drivers,
- ARRAY_SIZE(exynos_drm_non_kms_drivers));
-}
-
-static inline void exynos_drm_unregister_kms_drivers(void)
-{
- exynos_drm_unregister_drivers(exynos_drm_kms_drivers,
- ARRAY_SIZE(exynos_drm_kms_drivers));
-}
-
-static inline void exynos_drm_unregister_non_kms_drivers(void)
-{
- exynos_drm_unregister_drivers(exynos_drm_non_kms_drivers,
- ARRAY_SIZE(exynos_drm_non_kms_drivers));
+fail:
+ exynos_drm_unregister_drivers();
+ return ret;
}
static int exynos_drm_init(void)
@@ -711,19 +734,12 @@
if (ret)
return ret;
- ret = exynos_drm_register_kms_drivers();
+ ret = exynos_drm_register_drivers();
if (ret)
goto err_unregister_pdevs;
- ret = exynos_drm_register_non_kms_drivers();
- if (ret)
- goto err_unregister_kms_drivers;
-
return 0;
-err_unregister_kms_drivers:
- exynos_drm_unregister_kms_drivers();
-
err_unregister_pdevs:
exynos_drm_unregister_devices();
@@ -732,8 +748,7 @@
static void exynos_drm_exit(void)
{
- exynos_drm_unregister_non_kms_drivers();
- exynos_drm_unregister_kms_drivers();
+ exynos_drm_unregister_drivers();
exynos_drm_unregister_devices();
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 17b5ded..502f750 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -219,8 +219,10 @@
struct drm_crtc *crtc[MAX_CRTC];
struct drm_property *plane_zpos_property;
+ struct device *dma_dev;
unsigned long da_start;
unsigned long da_space_size;
+ void *mapping;
unsigned int pipe;
@@ -230,6 +232,13 @@
wait_queue_head_t wait;
};
+static inline struct device *to_dma_dev(struct drm_device *dev)
+{
+ struct exynos_drm_private *priv = dev->dev_private;
+
+ return priv->dma_dev;
+}
+
/*
* Exynos drm sub driver structure.
*
@@ -297,7 +306,6 @@
extern struct platform_driver dsi_driver;
extern struct platform_driver mixer_driver;
extern struct platform_driver hdmi_driver;
-extern struct platform_driver exynos_drm_common_hdmi_driver;
extern struct platform_driver vidi_driver;
extern struct platform_driver g2d_driver;
extern struct platform_driver fimc_driver;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 736115c..63c84a1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -10,6 +10,8 @@
* published by the Free Software Foundation.
*/
+#include <asm/unaligned.h>
+
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_mipi_dsi.h>
@@ -209,12 +211,6 @@
#define OLD_SCLK_MIPI_CLK_NAME "pll_clk"
-#define REG_ADDR(dsi, reg_idx) ((dsi)->reg_base + \
- dsi->driver_data->reg_ofs[(reg_idx)])
-#define DSI_WRITE(dsi, reg_idx, val) writel((val), \
- REG_ADDR((dsi), (reg_idx)))
-#define DSI_READ(dsi, reg_idx) readl(REG_ADDR((dsi), (reg_idx)))
-
static char *clk_names[5] = { "bus_clk", "sclk_mipi",
"phyclk_mipidphy0_bitclkdiv8", "phyclk_mipidphy0_rxclkesc0",
"sclk_rgb_vclk_to_dsim0" };
@@ -228,12 +224,8 @@
struct list_head list;
struct completion completed;
int result;
- u8 data_id;
- u8 data[2];
+ struct mipi_dsi_packet packet;
u16 flags;
-
- const u8 *tx_payload;
- u16 tx_len;
u16 tx_done;
u8 *rx_payload;
@@ -247,7 +239,7 @@
#define DSIM_STATE_VIDOUT_AVAILABLE BIT(3)
struct exynos_dsi_driver_data {
- unsigned int *reg_ofs;
+ const unsigned int *reg_ofs;
unsigned int plltmr_reg;
unsigned int has_freqband:1;
unsigned int has_clklane_stop:1;
@@ -255,7 +247,7 @@
unsigned int max_freq;
unsigned int wait_for_reset;
unsigned int num_bits_resol;
- unsigned int *reg_values;
+ const unsigned int *reg_values;
};
struct exynos_dsi {
@@ -324,7 +316,20 @@
DSIM_PHYTIMING2_REG,
NUM_REGS
};
-static unsigned int exynos_reg_ofs[] = {
+
+static inline void exynos_dsi_write(struct exynos_dsi *dsi, enum reg_idx idx,
+ u32 val)
+{
+
+ writel(val, dsi->reg_base + dsi->driver_data->reg_ofs[idx]);
+}
+
+static inline u32 exynos_dsi_read(struct exynos_dsi *dsi, enum reg_idx idx)
+{
+ return readl(dsi->reg_base + dsi->driver_data->reg_ofs[idx]);
+}
+
+static const unsigned int exynos_reg_ofs[] = {
[DSIM_STATUS_REG] = 0x00,
[DSIM_SWRST_REG] = 0x04,
[DSIM_CLKCTRL_REG] = 0x08,
@@ -348,7 +353,7 @@
[DSIM_PHYTIMING2_REG] = 0x6c,
};
-static unsigned int exynos5433_reg_ofs[] = {
+static const unsigned int exynos5433_reg_ofs[] = {
[DSIM_STATUS_REG] = 0x04,
[DSIM_SWRST_REG] = 0x0C,
[DSIM_CLKCTRL_REG] = 0x10,
@@ -390,7 +395,7 @@
PHYTIMING_HS_TRAIL
};
-static unsigned int reg_values[] = {
+static const unsigned int reg_values[] = {
[RESET_TYPE] = DSIM_SWRST,
[PLL_TIMER] = 500,
[STOP_STATE_CNT] = 0xf,
@@ -408,7 +413,25 @@
[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0b),
};
-static unsigned int exynos5433_reg_values[] = {
+static const unsigned int exynos5422_reg_values[] = {
+ [RESET_TYPE] = DSIM_SWRST,
+ [PLL_TIMER] = 500,
+ [STOP_STATE_CNT] = 0xf,
+ [PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0xaf),
+ [PHYCTRL_VREG_LP] = 0,
+ [PHYCTRL_SLEW_UP] = 0,
+ [PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x08),
+ [PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0d),
+ [PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x09),
+ [PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x30),
+ [PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0e),
+ [PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x0a),
+ [PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x0c),
+ [PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x11),
+ [PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0d),
+};
+
+static const unsigned int exynos5433_reg_values[] = {
[RESET_TYPE] = DSIM_FUNCRST,
[PLL_TIMER] = 22200,
[STOP_STATE_CNT] = 0xa,
@@ -426,7 +449,7 @@
[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0c),
};
-static struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
+static const struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
.reg_ofs = exynos_reg_ofs,
.plltmr_reg = 0x50,
.has_freqband = 1,
@@ -438,7 +461,7 @@
.reg_values = reg_values,
};
-static struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
+static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
.reg_ofs = exynos_reg_ofs,
.plltmr_reg = 0x50,
.has_freqband = 1,
@@ -450,7 +473,7 @@
.reg_values = reg_values,
};
-static struct exynos_dsi_driver_data exynos4415_dsi_driver_data = {
+static const struct exynos_dsi_driver_data exynos4415_dsi_driver_data = {
.reg_ofs = exynos_reg_ofs,
.plltmr_reg = 0x58,
.has_clklane_stop = 1,
@@ -461,7 +484,7 @@
.reg_values = reg_values,
};
-static struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
+static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
.reg_ofs = exynos_reg_ofs,
.plltmr_reg = 0x58,
.num_clks = 2,
@@ -471,7 +494,7 @@
.reg_values = reg_values,
};
-static struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
+static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
.reg_ofs = exynos5433_reg_ofs,
.plltmr_reg = 0xa0,
.has_clklane_stop = 1,
@@ -482,7 +505,18 @@
.reg_values = exynos5433_reg_values,
};
-static struct of_device_id exynos_dsi_of_match[] = {
+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,
+};
+
+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",
@@ -491,6 +525,8 @@
.data = &exynos4415_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 },
{ }
@@ -515,10 +551,10 @@
static void exynos_dsi_reset(struct exynos_dsi *dsi)
{
- struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
+ u32 reset_val = dsi->driver_data->reg_values[RESET_TYPE];
reinit_completion(&dsi->completed);
- DSI_WRITE(dsi, DSIM_SWRST_REG, driver_data->reg_values[RESET_TYPE]);
+ exynos_dsi_write(dsi, DSIM_SWRST_REG, reset_val);
}
#ifndef MHZ
@@ -621,7 +657,7 @@
reg |= DSIM_FREQ_BAND(band);
}
- DSI_WRITE(dsi, DSIM_PLLCTRL_REG, reg);
+ exynos_dsi_write(dsi, DSIM_PLLCTRL_REG, reg);
timeout = 1000;
do {
@@ -629,7 +665,7 @@
dev_err(dsi->dev, "PLL failed to stabilize\n");
return 0;
}
- reg = DSI_READ(dsi, DSIM_STATUS_REG);
+ reg = exynos_dsi_read(dsi, DSIM_STATUS_REG);
} while ((reg & DSIM_PLL_STABLE) == 0);
return fout;
@@ -659,7 +695,7 @@
dev_dbg(dsi->dev, "hs_clk = %lu, byte_clk = %lu, esc_clk = %lu\n",
hs_clk, byte_clk, esc_clk);
- reg = DSI_READ(dsi, DSIM_CLKCTRL_REG);
+ reg = exynos_dsi_read(dsi, DSIM_CLKCTRL_REG);
reg &= ~(DSIM_ESC_PRESCALER_MASK | DSIM_LANE_ESC_CLK_EN_CLK
| DSIM_LANE_ESC_CLK_EN_DATA_MASK | DSIM_PLL_BYPASS
| DSIM_BYTE_CLK_SRC_MASK);
@@ -669,7 +705,7 @@
| DSIM_LANE_ESC_CLK_EN_DATA(BIT(dsi->lanes) - 1)
| DSIM_BYTE_CLK_SRC(0)
| DSIM_TX_REQUEST_HSCLK;
- DSI_WRITE(dsi, DSIM_CLKCTRL_REG, reg);
+ exynos_dsi_write(dsi, DSIM_CLKCTRL_REG, reg);
return 0;
}
@@ -677,7 +713,7 @@
static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
{
struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
- unsigned int *reg_values = driver_data->reg_values;
+ const unsigned int *reg_values = driver_data->reg_values;
u32 reg;
if (driver_data->has_freqband)
@@ -686,7 +722,7 @@
/* B D-PHY: D-PHY Master & Slave Analog Block control */
reg = reg_values[PHYCTRL_ULPS_EXIT] | reg_values[PHYCTRL_VREG_LP] |
reg_values[PHYCTRL_SLEW_UP];
- DSI_WRITE(dsi, DSIM_PHYCTRL_REG, reg);
+ exynos_dsi_write(dsi, DSIM_PHYCTRL_REG, reg);
/*
* T LPX: Transmitted length of any Low-Power state period
@@ -694,7 +730,7 @@
* burst
*/
reg = reg_values[PHYTIMING_LPX] | reg_values[PHYTIMING_HS_EXIT];
- DSI_WRITE(dsi, DSIM_PHYTIMING_REG, reg);
+ exynos_dsi_write(dsi, DSIM_PHYTIMING_REG, reg);
/*
* T CLK-PREPARE: Time that the transmitter drives the Clock Lane LP-00
@@ -714,7 +750,7 @@
reg_values[PHYTIMING_CLK_POST] |
reg_values[PHYTIMING_CLK_TRAIL];
- DSI_WRITE(dsi, DSIM_PHYTIMING1_REG, reg);
+ exynos_dsi_write(dsi, DSIM_PHYTIMING1_REG, reg);
/*
* T HS-PREPARE: Time that the transmitter drives the Data Lane LP-00
@@ -727,29 +763,29 @@
*/
reg = reg_values[PHYTIMING_HS_PREPARE] | reg_values[PHYTIMING_HS_ZERO] |
reg_values[PHYTIMING_HS_TRAIL];
- DSI_WRITE(dsi, DSIM_PHYTIMING2_REG, reg);
+ exynos_dsi_write(dsi, DSIM_PHYTIMING2_REG, reg);
}
static void exynos_dsi_disable_clock(struct exynos_dsi *dsi)
{
u32 reg;
- reg = DSI_READ(dsi, DSIM_CLKCTRL_REG);
+ reg = exynos_dsi_read(dsi, DSIM_CLKCTRL_REG);
reg &= ~(DSIM_LANE_ESC_CLK_EN_CLK | DSIM_LANE_ESC_CLK_EN_DATA_MASK
| DSIM_ESC_CLKEN | DSIM_BYTE_CLKEN);
- DSI_WRITE(dsi, DSIM_CLKCTRL_REG, reg);
+ exynos_dsi_write(dsi, DSIM_CLKCTRL_REG, reg);
- reg = DSI_READ(dsi, DSIM_PLLCTRL_REG);
+ reg = exynos_dsi_read(dsi, DSIM_PLLCTRL_REG);
reg &= ~DSIM_PLL_EN;
- DSI_WRITE(dsi, DSIM_PLLCTRL_REG, reg);
+ exynos_dsi_write(dsi, DSIM_PLLCTRL_REG, reg);
}
static void exynos_dsi_enable_lane(struct exynos_dsi *dsi, u32 lane)
{
- u32 reg = DSI_READ(dsi, DSIM_CONFIG_REG);
+ u32 reg = exynos_dsi_read(dsi, DSIM_CONFIG_REG);
reg |= (DSIM_NUM_OF_DATA_LANE(dsi->lanes - 1) | DSIM_LANE_EN_CLK |
DSIM_LANE_EN(lane));
- DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
+ exynos_dsi_write(dsi, DSIM_CONFIG_REG, reg);
}
static int exynos_dsi_init_link(struct exynos_dsi *dsi)
@@ -760,14 +796,14 @@
u32 lanes_mask;
/* Initialize FIFO pointers */
- reg = DSI_READ(dsi, DSIM_FIFOCTRL_REG);
+ reg = exynos_dsi_read(dsi, DSIM_FIFOCTRL_REG);
reg &= ~0x1f;
- DSI_WRITE(dsi, DSIM_FIFOCTRL_REG, reg);
+ exynos_dsi_write(dsi, DSIM_FIFOCTRL_REG, reg);
usleep_range(9000, 11000);
reg |= 0x1f;
- DSI_WRITE(dsi, DSIM_FIFOCTRL_REG, reg);
+ exynos_dsi_write(dsi, DSIM_FIFOCTRL_REG, reg);
usleep_range(9000, 11000);
/* DSI configuration */
@@ -836,7 +872,7 @@
dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {
reg |= DSIM_CLKLANE_STOP;
}
- DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
+ exynos_dsi_write(dsi, DSIM_CONFIG_REG, reg);
lanes_mask = BIT(dsi->lanes) - 1;
exynos_dsi_enable_lane(dsi, lanes_mask);
@@ -849,19 +885,19 @@
return -EFAULT;
}
- reg = DSI_READ(dsi, DSIM_STATUS_REG);
+ reg = exynos_dsi_read(dsi, DSIM_STATUS_REG);
if ((reg & DSIM_STOP_STATE_DAT(lanes_mask))
!= DSIM_STOP_STATE_DAT(lanes_mask))
continue;
} while (!(reg & (DSIM_STOP_STATE_CLK | DSIM_TX_READY_HS_CLK)));
- reg = DSI_READ(dsi, DSIM_ESCMODE_REG);
+ reg = exynos_dsi_read(dsi, DSIM_ESCMODE_REG);
reg &= ~DSIM_STOP_STATE_CNT_MASK;
reg |= DSIM_STOP_STATE_CNT(driver_data->reg_values[STOP_STATE_CNT]);
- DSI_WRITE(dsi, DSIM_ESCMODE_REG, reg);
+ exynos_dsi_write(dsi, DSIM_ESCMODE_REG, reg);
reg = DSIM_BTA_TIMEOUT(0xff) | DSIM_LPDR_TIMEOUT(0xffff);
- DSI_WRITE(dsi, DSIM_TIMEOUT_REG, reg);
+ exynos_dsi_write(dsi, DSIM_TIMEOUT_REG, reg);
return 0;
}
@@ -876,20 +912,20 @@
reg = DSIM_CMD_ALLOW(0xf)
| DSIM_STABLE_VFP(vm->vfront_porch)
| DSIM_MAIN_VBP(vm->vback_porch);
- DSI_WRITE(dsi, DSIM_MVPORCH_REG, reg);
+ exynos_dsi_write(dsi, DSIM_MVPORCH_REG, reg);
reg = DSIM_MAIN_HFP(vm->hfront_porch)
| DSIM_MAIN_HBP(vm->hback_porch);
- DSI_WRITE(dsi, DSIM_MHPORCH_REG, reg);
+ exynos_dsi_write(dsi, DSIM_MHPORCH_REG, reg);
reg = DSIM_MAIN_VSA(vm->vsync_len)
| DSIM_MAIN_HSA(vm->hsync_len);
- DSI_WRITE(dsi, DSIM_MSYNC_REG, reg);
+ exynos_dsi_write(dsi, DSIM_MSYNC_REG, reg);
}
reg = DSIM_MAIN_HRESOL(vm->hactive, num_bits_resol) |
DSIM_MAIN_VRESOL(vm->vactive, num_bits_resol);
- DSI_WRITE(dsi, DSIM_MDRESOL_REG, reg);
+ exynos_dsi_write(dsi, DSIM_MDRESOL_REG, reg);
dev_dbg(dsi->dev, "LCD size = %dx%d\n", vm->hactive, vm->vactive);
}
@@ -898,12 +934,12 @@
{
u32 reg;
- reg = DSI_READ(dsi, DSIM_MDRESOL_REG);
+ reg = exynos_dsi_read(dsi, DSIM_MDRESOL_REG);
if (enable)
reg |= DSIM_MAIN_STAND_BY;
else
reg &= ~DSIM_MAIN_STAND_BY;
- DSI_WRITE(dsi, DSIM_MDRESOL_REG, reg);
+ exynos_dsi_write(dsi, DSIM_MDRESOL_REG, reg);
}
static int exynos_dsi_wait_for_hdr_fifo(struct exynos_dsi *dsi)
@@ -911,7 +947,7 @@
int timeout = 2000;
do {
- u32 reg = DSI_READ(dsi, DSIM_FIFOCTRL_REG);
+ u32 reg = exynos_dsi_read(dsi, DSIM_FIFOCTRL_REG);
if (!(reg & DSIM_SFR_HEADER_FULL))
return 0;
@@ -925,34 +961,35 @@
static void exynos_dsi_set_cmd_lpm(struct exynos_dsi *dsi, bool lpm)
{
- u32 v = DSI_READ(dsi, DSIM_ESCMODE_REG);
+ u32 v = exynos_dsi_read(dsi, DSIM_ESCMODE_REG);
if (lpm)
v |= DSIM_CMD_LPDT_LP;
else
v &= ~DSIM_CMD_LPDT_LP;
- DSI_WRITE(dsi, DSIM_ESCMODE_REG, v);
+ exynos_dsi_write(dsi, DSIM_ESCMODE_REG, v);
}
static void exynos_dsi_force_bta(struct exynos_dsi *dsi)
{
- u32 v = DSI_READ(dsi, DSIM_ESCMODE_REG);
+ u32 v = exynos_dsi_read(dsi, DSIM_ESCMODE_REG);
v |= DSIM_FORCE_BTA;
- DSI_WRITE(dsi, DSIM_ESCMODE_REG, v);
+ exynos_dsi_write(dsi, DSIM_ESCMODE_REG, v);
}
static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi,
struct exynos_dsi_transfer *xfer)
{
struct device *dev = dsi->dev;
- const u8 *payload = xfer->tx_payload + xfer->tx_done;
- u16 length = xfer->tx_len - xfer->tx_done;
+ struct mipi_dsi_packet *pkt = &xfer->packet;
+ const u8 *payload = pkt->payload + xfer->tx_done;
+ u16 length = pkt->payload_length - xfer->tx_done;
bool first = !xfer->tx_done;
u32 reg;
dev_dbg(dev, "< xfer %p: tx len %u, done %u, rx len %u, done %u\n",
- xfer, xfer->tx_len, xfer->tx_done, xfer->rx_len, xfer->rx_done);
+ xfer, length, xfer->tx_done, xfer->rx_len, xfer->rx_done);
if (length > DSI_TX_FIFO_SIZE)
length = DSI_TX_FIFO_SIZE;
@@ -961,9 +998,8 @@
/* Send payload */
while (length >= 4) {
- reg = (payload[3] << 24) | (payload[2] << 16)
- | (payload[1] << 8) | payload[0];
- DSI_WRITE(dsi, DSIM_PAYLOAD_REG, reg);
+ reg = get_unaligned_le32(payload);
+ exynos_dsi_write(dsi, DSIM_PAYLOAD_REG, reg);
payload += 4;
length -= 4;
}
@@ -978,10 +1014,7 @@
/* Fall through */
case 1:
reg |= payload[0];
- DSI_WRITE(dsi, DSIM_PAYLOAD_REG, reg);
- break;
- case 0:
- /* Do nothing */
+ exynos_dsi_write(dsi, DSIM_PAYLOAD_REG, reg);
break;
}
@@ -989,7 +1022,7 @@
if (!first)
return;
- reg = (xfer->data[1] << 16) | (xfer->data[0] << 8) | xfer->data_id;
+ reg = get_unaligned_le32(pkt->header);
if (exynos_dsi_wait_for_hdr_fifo(dsi)) {
dev_err(dev, "waiting for header FIFO timed out\n");
return;
@@ -1001,7 +1034,7 @@
dsi->state ^= DSIM_STATE_CMD_LPM;
}
- DSI_WRITE(dsi, DSIM_PKTHDR_REG, reg);
+ exynos_dsi_write(dsi, DSIM_PKTHDR_REG, reg);
if (xfer->flags & MIPI_DSI_MSG_REQ_ACK)
exynos_dsi_force_bta(dsi);
@@ -1017,7 +1050,7 @@
u32 reg;
if (first) {
- reg = DSI_READ(dsi, DSIM_RXFIFO_REG);
+ reg = exynos_dsi_read(dsi, DSIM_RXFIFO_REG);
switch (reg & 0x3f) {
case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:
@@ -1056,7 +1089,7 @@
/* Receive payload */
while (length >= 4) {
- reg = DSI_READ(dsi, DSIM_RXFIFO_REG);
+ reg = exynos_dsi_read(dsi, DSIM_RXFIFO_REG);
payload[0] = (reg >> 0) & 0xff;
payload[1] = (reg >> 8) & 0xff;
payload[2] = (reg >> 16) & 0xff;
@@ -1066,7 +1099,7 @@
}
if (length) {
- reg = DSI_READ(dsi, DSIM_RXFIFO_REG);
+ reg = exynos_dsi_read(dsi, DSIM_RXFIFO_REG);
switch (length) {
case 3:
payload[2] = (reg >> 16) & 0xff;
@@ -1085,7 +1118,7 @@
clear_fifo:
length = DSI_RX_FIFO_SIZE / 4;
do {
- reg = DSI_READ(dsi, DSIM_RXFIFO_REG);
+ reg = exynos_dsi_read(dsi, DSIM_RXFIFO_REG);
if (reg == DSI_RX_FIFO_EMPTY)
break;
} while (--length);
@@ -1110,13 +1143,14 @@
spin_unlock_irqrestore(&dsi->transfer_lock, flags);
- if (xfer->tx_len && xfer->tx_done == xfer->tx_len)
+ if (xfer->packet.payload_length &&
+ xfer->tx_done == xfer->packet.payload_length)
/* waiting for RX */
return;
exynos_dsi_send_to_fifo(dsi, xfer);
- if (xfer->tx_len || xfer->rx_len)
+ if (xfer->packet.payload_length || xfer->rx_len)
return;
xfer->result = 0;
@@ -1152,10 +1186,11 @@
spin_unlock_irqrestore(&dsi->transfer_lock, flags);
dev_dbg(dsi->dev,
- "> xfer %p, tx_len %u, tx_done %u, rx_len %u, rx_done %u\n",
- xfer, xfer->tx_len, xfer->tx_done, xfer->rx_len, xfer->rx_done);
+ "> xfer %p, tx_len %zu, tx_done %u, rx_len %u, rx_done %u\n",
+ xfer, xfer->packet.payload_length, xfer->tx_done, xfer->rx_len,
+ xfer->rx_done);
- if (xfer->tx_done != xfer->tx_len)
+ if (xfer->tx_done != xfer->packet.payload_length)
return true;
if (xfer->rx_done != xfer->rx_len)
@@ -1226,9 +1261,10 @@
wait_for_completion_timeout(&xfer->completed,
msecs_to_jiffies(DSI_XFER_TIMEOUT_MS));
if (xfer->result == -ETIMEDOUT) {
+ struct mipi_dsi_packet *pkt = &xfer->packet;
exynos_dsi_remove_transfer(dsi, xfer);
- dev_err(dsi->dev, "xfer timed out: %*ph %*ph\n", 2, xfer->data,
- xfer->tx_len, xfer->tx_payload);
+ dev_err(dsi->dev, "xfer timed out: %*ph %*ph\n", 4, pkt->header,
+ (int)pkt->payload_length, pkt->payload);
return -ETIMEDOUT;
}
@@ -1241,20 +1277,20 @@
struct exynos_dsi *dsi = dev_id;
u32 status;
- status = DSI_READ(dsi, DSIM_INTSRC_REG);
+ status = exynos_dsi_read(dsi, DSIM_INTSRC_REG);
if (!status) {
static unsigned long int j;
if (printk_timed_ratelimit(&j, 500))
dev_warn(dsi->dev, "spurious interrupt\n");
return IRQ_HANDLED;
}
- DSI_WRITE(dsi, DSIM_INTSRC_REG, status);
+ exynos_dsi_write(dsi, DSIM_INTSRC_REG, status);
if (status & DSIM_INT_SW_RST_RELEASE) {
u32 mask = ~(DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY |
DSIM_INT_SFR_HDR_FIFO_EMPTY | DSIM_INT_FRAME_DONE |
DSIM_INT_RX_ECC_ERR | DSIM_INT_SW_RST_RELEASE);
- DSI_WRITE(dsi, DSIM_INTMSK_REG, mask);
+ exynos_dsi_write(dsi, DSIM_INTMSK_REG, mask);
complete(&dsi->completed);
return IRQ_HANDLED;
}
@@ -1401,12 +1437,6 @@
return 0;
}
-/* distinguish between short and long DSI packet types */
-static bool exynos_dsi_is_short_dsi_type(u8 type)
-{
- return (type & 0x0f) <= 8;
-}
-
static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host,
const struct mipi_dsi_msg *msg)
{
@@ -1424,25 +1454,9 @@
dsi->state |= DSIM_STATE_INITIALIZED;
}
- if (msg->tx_len == 0)
- return -EINVAL;
-
- xfer.data_id = msg->type | (msg->channel << 6);
-
- if (exynos_dsi_is_short_dsi_type(msg->type)) {
- const char *tx_buf = msg->tx_buf;
-
- if (msg->tx_len > 2)
- return -EINVAL;
- xfer.tx_len = 0;
- xfer.data[0] = tx_buf[0];
- xfer.data[1] = (msg->tx_len == 2) ? tx_buf[1] : 0;
- } else {
- xfer.tx_len = msg->tx_len;
- xfer.data[0] = msg->tx_len & 0xff;
- xfer.data[1] = msg->tx_len >> 8;
- xfer.tx_payload = msg->tx_buf;
- }
+ ret = mipi_dsi_create_packet(&xfer.packet, msg);
+ if (ret < 0)
+ return ret;
xfer.rx_len = msg->rx_len;
xfer.rx_payload = msg->rx_buf;
@@ -1774,6 +1788,7 @@
bridge = of_drm_find_bridge(dsi->bridge_node);
if (bridge) {
+ encoder->bridge = bridge;
drm_bridge_attach(drm_dev, bridge);
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index f6118ba..4ae860c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -50,7 +50,7 @@
if (vm_size > exynos_gem->size)
return -EINVAL;
- ret = dma_mmap_attrs(helper->dev->dev, vma, exynos_gem->pages,
+ ret = dma_mmap_attrs(to_dma_dev(helper->dev), vma, exynos_gem->cookie,
exynos_gem->dma_addr, exynos_gem->size,
&exynos_gem->dma_attrs);
if (ret < 0) {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
index c747824..0525c56 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
@@ -163,7 +163,6 @@
u32 clk_frequency;
struct regmap *sysreg;
struct fimc_scaler sc;
- struct exynos_drm_ipp_pol pol;
int id;
int irq;
bool suspended;
@@ -260,32 +259,6 @@
fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
}
-static void fimc_set_polarity(struct fimc_context *ctx,
- struct exynos_drm_ipp_pol *pol)
-{
- u32 cfg;
-
- DRM_DEBUG_KMS("inv_pclk[%d]inv_vsync[%d]\n",
- pol->inv_pclk, pol->inv_vsync);
- DRM_DEBUG_KMS("inv_href[%d]inv_hsync[%d]\n",
- pol->inv_href, pol->inv_hsync);
-
- cfg = fimc_read(ctx, EXYNOS_CIGCTRL);
- cfg &= ~(EXYNOS_CIGCTRL_INVPOLPCLK | EXYNOS_CIGCTRL_INVPOLVSYNC |
- EXYNOS_CIGCTRL_INVPOLHREF | EXYNOS_CIGCTRL_INVPOLHSYNC);
-
- if (pol->inv_pclk)
- cfg |= EXYNOS_CIGCTRL_INVPOLPCLK;
- if (pol->inv_vsync)
- cfg |= EXYNOS_CIGCTRL_INVPOLVSYNC;
- if (pol->inv_href)
- cfg |= EXYNOS_CIGCTRL_INVPOLHREF;
- if (pol->inv_hsync)
- cfg |= EXYNOS_CIGCTRL_INVPOLHSYNC;
-
- fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
-}
-
static void fimc_handle_jpeg(struct fimc_context *ctx, bool enable)
{
u32 cfg;
@@ -1467,7 +1440,6 @@
/* If set ture, we can save jpeg about screen */
fimc_handle_jpeg(ctx, false);
fimc_set_scaler(ctx, &ctx->sc);
- fimc_set_polarity(ctx, &ctx->pol);
switch (cmd) {
case IPP_CMD_M2M:
@@ -1723,7 +1695,7 @@
goto err_put_clk;
}
- DRM_DEBUG_KMS("id[%d]ippdrv[0x%x]\n", ctx->id, (int)ippdrv);
+ DRM_DEBUG_KMS("id[%d]ippdrv[%p]\n", ctx->id, ippdrv);
spin_lock_init(&ctx->lock);
platform_set_drvdata(pdev, ctx);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 70194d0..51d484a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -94,12 +94,14 @@
unsigned int lcdblk_offset;
unsigned int lcdblk_vt_shift;
unsigned int lcdblk_bypass_shift;
+ unsigned int lcdblk_mic_bypass_shift;
unsigned int has_shadowcon:1;
unsigned int has_clksel:1;
unsigned int has_limited_fmt:1;
unsigned int has_vidoutcon:1;
unsigned int has_vtsel:1;
+ unsigned int has_mic_bypass:1;
};
static struct fimd_driver_data s3c64xx_fimd_driver_data = {
@@ -145,6 +147,18 @@
.has_vtsel = 1,
};
+static struct fimd_driver_data exynos5420_fimd_driver_data = {
+ .timing_base = 0x20000,
+ .lcdblk_offset = 0x214,
+ .lcdblk_vt_shift = 24,
+ .lcdblk_bypass_shift = 15,
+ .lcdblk_mic_bypass_shift = 11,
+ .has_shadowcon = 1,
+ .has_vidoutcon = 1,
+ .has_vtsel = 1,
+ .has_mic_bypass = 1,
+};
+
struct fimd_context {
struct device *dev;
struct drm_device *drm_dev;
@@ -168,7 +182,6 @@
atomic_t win_updated;
atomic_t triggering;
- struct exynos_drm_panel_info panel;
struct fimd_driver_data *driver_data;
struct drm_encoder *encoder;
};
@@ -184,6 +197,8 @@
.data = &exynos4415_fimd_driver_data },
{ .compatible = "samsung,exynos5250-fimd",
.data = &exynos5_fimd_driver_data },
+ { .compatible = "samsung,exynos5420-fimd",
+ .data = &exynos5420_fimd_driver_data },
{},
};
MODULE_DEVICE_TABLE(of, fimd_driver_dt_match);
@@ -380,7 +395,7 @@
}
/* Find the clock divider value that gets us closest to ideal_clk */
- clkdiv = DIV_ROUND_UP(clk_get_rate(ctx->lcd_clk), ideal_clk);
+ clkdiv = DIV_ROUND_CLOSEST(clk_get_rate(ctx->lcd_clk), ideal_clk);
return (clkdiv < 0x100) ? clkdiv : 0xff;
}
@@ -461,6 +476,18 @@
return;
}
+ /* TODO: When MIC is enabled for display path, the lcdblk_mic_bypass
+ * bit should be cleared.
+ */
+ if (driver_data->has_mic_bypass && ctx->sysreg &&
+ regmap_update_bits(ctx->sysreg,
+ driver_data->lcdblk_offset,
+ 0x1 << driver_data->lcdblk_mic_bypass_shift,
+ 0x1 << driver_data->lcdblk_mic_bypass_shift)) {
+ DRM_ERROR("Failed to update sysreg for bypass mic.\n");
+ return;
+ }
+
/* setup horizontal and vertical display size. */
val = VIDTCON2_LINEVAL(mode->vdisplay - 1) |
VIDTCON2_HOZVAL(mode->hdisplay - 1) |
@@ -861,7 +888,8 @@
* clock. On these SoCs the bootloader may enable it but any
* power domain off/on will reset it to disable state.
*/
- if (ctx->driver_data != &exynos5_fimd_driver_data)
+ if (ctx->driver_data != &exynos5_fimd_driver_data ||
+ ctx->driver_data != &exynos5420_fimd_driver_data)
return;
val = enable ? DP_MIE_CLK_DP_ENABLE : DP_MIE_CLK_DISABLE;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 9936981..193d360 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -259,7 +259,7 @@
init_dma_attrs(&g2d->cmdlist_dma_attrs);
dma_set_attr(DMA_ATTR_WRITE_COMBINE, &g2d->cmdlist_dma_attrs);
- g2d->cmdlist_pool_virt = dma_alloc_attrs(subdrv->drm_dev->dev,
+ g2d->cmdlist_pool_virt = dma_alloc_attrs(to_dma_dev(subdrv->drm_dev),
G2D_CMDLIST_POOL_SIZE,
&g2d->cmdlist_pool, GFP_KERNEL,
&g2d->cmdlist_dma_attrs);
@@ -293,7 +293,7 @@
return 0;
err:
- dma_free_attrs(subdrv->drm_dev->dev, G2D_CMDLIST_POOL_SIZE,
+ dma_free_attrs(to_dma_dev(subdrv->drm_dev), G2D_CMDLIST_POOL_SIZE,
g2d->cmdlist_pool_virt,
g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs);
return ret;
@@ -306,7 +306,8 @@
kfree(g2d->cmdlist_node);
if (g2d->cmdlist_pool_virt && g2d->cmdlist_pool) {
- dma_free_attrs(subdrv->drm_dev->dev, G2D_CMDLIST_POOL_SIZE,
+ dma_free_attrs(to_dma_dev(subdrv->drm_dev),
+ G2D_CMDLIST_POOL_SIZE,
g2d->cmdlist_pool_virt,
g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs);
}
@@ -1151,7 +1152,7 @@
goto err_free_event;
}
- cmd = (struct drm_exynos_g2d_cmd *)(uint32_t)req->cmd;
+ cmd = (struct drm_exynos_g2d_cmd *)(unsigned long)req->cmd;
if (copy_from_user(cmdlist->data + cmdlist->last,
(void __user *)cmd,
@@ -1169,7 +1170,8 @@
if (req->cmd_buf_nr) {
struct drm_exynos_g2d_cmd *cmd_buf;
- cmd_buf = (struct drm_exynos_g2d_cmd *)(uint32_t)req->cmd_buf;
+ cmd_buf = (struct drm_exynos_g2d_cmd *)
+ (unsigned long)req->cmd_buf;
if (copy_from_user(cmdlist->data + cmdlist->last,
(void __user *)cmd_buf,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 32358c5..54b6394 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -65,7 +65,7 @@
return -ENOMEM;
}
- exynos_gem->cookie = dma_alloc_attrs(dev->dev, exynos_gem->size,
+ exynos_gem->cookie = dma_alloc_attrs(to_dma_dev(dev), exynos_gem->size,
&exynos_gem->dma_addr, GFP_KERNEL,
&exynos_gem->dma_attrs);
if (!exynos_gem->cookie) {
@@ -73,7 +73,7 @@
goto err_free;
}
- ret = dma_get_sgtable_attrs(dev->dev, &sgt, exynos_gem->cookie,
+ ret = dma_get_sgtable_attrs(to_dma_dev(dev), &sgt, exynos_gem->cookie,
exynos_gem->dma_addr, exynos_gem->size,
&exynos_gem->dma_attrs);
if (ret < 0) {
@@ -98,7 +98,7 @@
err_sgt_free:
sg_free_table(&sgt);
err_dma_free:
- dma_free_attrs(dev->dev, exynos_gem->size, exynos_gem->cookie,
+ dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
exynos_gem->dma_addr, &exynos_gem->dma_attrs);
err_free:
drm_free_large(exynos_gem->pages);
@@ -118,7 +118,7 @@
DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n",
(unsigned long)exynos_gem->dma_addr, exynos_gem->size);
- dma_free_attrs(dev->dev, exynos_gem->size, exynos_gem->cookie,
+ dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
(dma_addr_t)exynos_gem->dma_addr,
&exynos_gem->dma_attrs);
@@ -218,7 +218,7 @@
return ERR_PTR(ret);
}
- DRM_DEBUG_KMS("created file object = 0x%x\n", (unsigned int)obj->filp);
+ DRM_DEBUG_KMS("created file object = %p\n", obj->filp);
return exynos_gem;
}
@@ -335,7 +335,7 @@
if (vm_size > exynos_gem->size)
return -EINVAL;
- ret = dma_mmap_attrs(drm_dev->dev, vma, exynos_gem->pages,
+ ret = dma_mmap_attrs(to_dma_dev(drm_dev), vma, exynos_gem->cookie,
exynos_gem->dma_addr, exynos_gem->size,
&exynos_gem->dma_attrs);
if (ret < 0) {
@@ -381,7 +381,7 @@
mutex_lock(&drm_dev->struct_mutex);
- nents = dma_map_sg(drm_dev->dev, sgt->sgl, sgt->nents, dir);
+ nents = dma_map_sg(to_dma_dev(drm_dev), sgt->sgl, sgt->nents, dir);
if (!nents) {
DRM_ERROR("failed to map sgl with dma.\n");
mutex_unlock(&drm_dev->struct_mutex);
@@ -396,7 +396,7 @@
struct sg_table *sgt,
enum dma_data_direction dir)
{
- dma_unmap_sg(drm_dev->dev, sgt->sgl, sgt->nents, dir);
+ dma_unmap_sg(to_dma_dev(drm_dev), sgt->sgl, sgt->nents, dir);
}
void exynos_drm_gem_free_object(struct drm_gem_object *obj)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
index 7aecd23..5d20da8 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
@@ -1723,7 +1723,7 @@
return ret;
}
- DRM_DEBUG_KMS("id[%d]ippdrv[0x%x]\n", ctx->id, (int)ippdrv);
+ DRM_DEBUG_KMS("id[%d]ippdrv[%p]\n", ctx->id, ippdrv);
mutex_init(&ctx->lock);
platform_set_drvdata(pdev, ctx);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.c b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
index d73b9ad..7ca09ee 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_iommu.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
@@ -9,7 +9,7 @@
* option) any later version.
*/
-#include <drmP.h>
+#include <drm/drmP.h>
#include <drm/exynos_drm.h>
#include <linux/dma-mapping.h>
@@ -30,7 +30,6 @@
{
struct dma_iommu_mapping *mapping = NULL;
struct exynos_drm_private *priv = drm_dev->dev_private;
- struct device *dev = drm_dev->dev;
if (!priv->da_start)
priv->da_start = EXYNOS_DEV_ADDR_START;
@@ -43,18 +42,9 @@
if (IS_ERR(mapping))
return PTR_ERR(mapping);
- dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms),
- GFP_KERNEL);
- if (!dev->dma_parms)
- goto error;
-
- dma_set_max_seg_size(dev, 0xffffffffu);
- dev->archdata.mapping = mapping;
+ priv->mapping = mapping;
return 0;
-error:
- arm_iommu_release_mapping(mapping);
- return -ENOMEM;
}
/*
@@ -67,9 +57,9 @@
*/
void drm_release_iommu_mapping(struct drm_device *drm_dev)
{
- struct device *dev = drm_dev->dev;
+ struct exynos_drm_private *priv = drm_dev->dev_private;
- arm_iommu_release_mapping(dev->archdata.mapping);
+ arm_iommu_release_mapping(priv->mapping);
}
/*
@@ -84,10 +74,10 @@
int drm_iommu_attach_device(struct drm_device *drm_dev,
struct device *subdrv_dev)
{
- struct device *dev = drm_dev->dev;
+ struct exynos_drm_private *priv = drm_dev->dev_private;
int ret;
- if (!dev->archdata.mapping)
+ if (!priv->mapping)
return 0;
subdrv_dev->dma_parms = devm_kzalloc(subdrv_dev,
@@ -101,23 +91,12 @@
if (subdrv_dev->archdata.mapping)
arm_iommu_detach_device(subdrv_dev);
- ret = arm_iommu_attach_device(subdrv_dev, dev->archdata.mapping);
+ ret = arm_iommu_attach_device(subdrv_dev, priv->mapping);
if (ret < 0) {
DRM_DEBUG_KMS("failed iommu attach.\n");
return ret;
}
- /*
- * Set dma_ops to drm_device just one time.
- *
- * The dma mapping api needs device object and the api is used
- * to allocate physial memory and map it with iommu table.
- * If iommu attach succeeded, the sub driver would have dma_ops
- * for iommu and also all sub drivers have same dma_ops.
- */
- if (get_dma_ops(dev) == get_dma_ops(NULL))
- set_dma_ops(dev, get_dma_ops(subdrv_dev));
-
return 0;
}
@@ -133,8 +112,8 @@
void drm_iommu_detach_device(struct drm_device *drm_dev,
struct device *subdrv_dev)
{
- struct device *dev = drm_dev->dev;
- struct dma_iommu_mapping *mapping = dev->archdata.mapping;
+ struct exynos_drm_private *priv = drm_dev->dev_private;
+ struct dma_iommu_mapping *mapping = priv->mapping;
if (!mapping || !mapping->domain)
return;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.h b/drivers/gpu/drm/exynos/exynos_drm_iommu.h
index dc1b544..5ffebe0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_iommu.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.h
@@ -29,9 +29,9 @@
static inline bool is_drm_iommu_supported(struct drm_device *drm_dev)
{
- struct device *dev = drm_dev->dev;
+ struct exynos_drm_private *priv = drm_dev->dev_private;
- return dev->archdata.mapping ? true : false;
+ return priv->mapping ? true : false;
}
#else
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index 3eab0d1..9c84ee7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -208,7 +208,7 @@
* e.g PAUSE state, queue buf, command control.
*/
list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
- DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]\n", count++, (int)ippdrv);
+ DRM_DEBUG_KMS("count[%d]ippdrv[%p]\n", count++, ippdrv);
mutex_lock(&ippdrv->cmd_lock);
list_for_each_entry(c_node, &ippdrv->cmd_list, list) {
@@ -388,8 +388,8 @@
}
property->prop_id = ret;
- DRM_DEBUG_KMS("created prop_id[%d]cmd[%d]ippdrv[0x%x]\n",
- property->prop_id, property->cmd, (int)ippdrv);
+ DRM_DEBUG_KMS("created prop_id[%d]cmd[%d]ippdrv[%p]\n",
+ property->prop_id, property->cmd, ippdrv);
/* stored property information and ippdrv in private data */
c_node->property = *property;
@@ -518,7 +518,7 @@
{
int i;
- DRM_DEBUG_KMS("node[0x%x]\n", (int)m_node);
+ DRM_DEBUG_KMS("node[%p]\n", m_node);
if (!m_node) {
DRM_ERROR("invalid dequeue node.\n");
@@ -562,7 +562,7 @@
m_node->buf_id = qbuf->buf_id;
INIT_LIST_HEAD(&m_node->list);
- DRM_DEBUG_KMS("m_node[0x%x]ops_id[%d]\n", (int)m_node, qbuf->ops_id);
+ DRM_DEBUG_KMS("m_node[%p]ops_id[%d]\n", m_node, qbuf->ops_id);
DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]\n", qbuf->prop_id, m_node->buf_id);
for_each_ipp_planar(i) {
@@ -582,8 +582,8 @@
buf_info->handles[i] = qbuf->handle[i];
buf_info->base[i] = *addr;
- DRM_DEBUG_KMS("i[%d]base[0x%x]hd[0x%lx]\n", i,
- buf_info->base[i], buf_info->handles[i]);
+ DRM_DEBUG_KMS("i[%d]base[%pad]hd[0x%lx]\n", i,
+ &buf_info->base[i], buf_info->handles[i]);
}
}
@@ -659,7 +659,7 @@
mutex_lock(&c_node->event_lock);
list_for_each_entry_safe(e, te, &c_node->event_list, base.link) {
- DRM_DEBUG_KMS("count[%d]e[0x%x]\n", count++, (int)e);
+ DRM_DEBUG_KMS("count[%d]e[%p]\n", count++, e);
/*
* qbuf == NULL condition means all event deletion.
@@ -750,7 +750,7 @@
/* find memory node from memory list */
list_for_each_entry(m_node, head, list) {
- DRM_DEBUG_KMS("count[%d]m_node[0x%x]\n", count++, (int)m_node);
+ DRM_DEBUG_KMS("count[%d]m_node[%p]\n", count++, m_node);
/* compare buffer id */
if (m_node->buf_id == qbuf->buf_id)
@@ -767,7 +767,7 @@
struct exynos_drm_ipp_ops *ops = NULL;
int ret = 0;
- DRM_DEBUG_KMS("node[0x%x]\n", (int)m_node);
+ DRM_DEBUG_KMS("node[%p]\n", m_node);
if (!m_node) {
DRM_ERROR("invalid queue node.\n");
@@ -1232,7 +1232,7 @@
m_node = list_first_entry(head,
struct drm_exynos_ipp_mem_node, list);
- DRM_DEBUG_KMS("m_node[0x%x]\n", (int)m_node);
+ DRM_DEBUG_KMS("m_node[%p]\n", m_node);
ret = ipp_set_mem_node(ippdrv, c_node, m_node);
if (ret) {
@@ -1601,8 +1601,8 @@
}
ippdrv->prop_list.ipp_id = ret;
- DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]ipp_id[%d]\n",
- count++, (int)ippdrv, ret);
+ DRM_DEBUG_KMS("count[%d]ippdrv[%p]ipp_id[%d]\n",
+ count++, ippdrv, ret);
/* store parent device for node */
ippdrv->parent_dev = dev;
@@ -1659,7 +1659,7 @@
file_priv->ipp_dev = dev;
- DRM_DEBUG_KMS("done priv[0x%x]\n", (int)dev);
+ DRM_DEBUG_KMS("done priv[%p]\n", dev);
return 0;
}
@@ -1676,8 +1676,8 @@
mutex_lock(&ippdrv->cmd_lock);
list_for_each_entry_safe(c_node, tc_node,
&ippdrv->cmd_list, list) {
- DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]\n",
- count++, (int)ippdrv);
+ DRM_DEBUG_KMS("count[%d]ippdrv[%p]\n",
+ count++, ippdrv);
if (c_node->filp == file) {
/*
diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c
index 4eaef36..9869d70 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_mic.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c
@@ -18,6 +18,7 @@
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/clk.h>
+#include <linux/component.h>
#include <drm/drmP.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
@@ -306,9 +307,9 @@
return ret;
}
-void mic_disable(struct drm_bridge *bridge) { }
+static void mic_disable(struct drm_bridge *bridge) { }
-void mic_post_disable(struct drm_bridge *bridge)
+static void mic_post_disable(struct drm_bridge *bridge)
{
struct exynos_mic *mic = bridge->driver_private;
int i;
@@ -328,7 +329,7 @@
mutex_unlock(&mic_mutex);
}
-void mic_pre_enable(struct drm_bridge *bridge)
+static void mic_pre_enable(struct drm_bridge *bridge)
{
struct exynos_mic *mic = bridge->driver_private;
int ret, i;
@@ -371,11 +372,35 @@
mutex_unlock(&mic_mutex);
}
-void mic_enable(struct drm_bridge *bridge) { }
+static void mic_enable(struct drm_bridge *bridge) { }
-void mic_destroy(struct drm_bridge *bridge)
+static const struct drm_bridge_funcs mic_bridge_funcs = {
+ .disable = mic_disable,
+ .post_disable = mic_post_disable,
+ .pre_enable = mic_pre_enable,
+ .enable = mic_enable,
+};
+
+static int exynos_mic_bind(struct device *dev, struct device *master,
+ void *data)
{
- struct exynos_mic *mic = bridge->driver_private;
+ struct exynos_mic *mic = dev_get_drvdata(dev);
+ int ret;
+
+ mic->bridge.funcs = &mic_bridge_funcs;
+ mic->bridge.of_node = dev->of_node;
+ mic->bridge.driver_private = mic;
+ ret = drm_bridge_add(&mic->bridge);
+ if (ret)
+ DRM_ERROR("mic: Failed to add MIC to the global bridge list\n");
+
+ return ret;
+}
+
+static void exynos_mic_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+ struct exynos_mic *mic = dev_get_drvdata(dev);
int i;
mutex_lock(&mic_mutex);
@@ -387,16 +412,16 @@
already_disabled:
mutex_unlock(&mic_mutex);
+
+ drm_bridge_remove(&mic->bridge);
}
-static const struct drm_bridge_funcs mic_bridge_funcs = {
- .disable = mic_disable,
- .post_disable = mic_post_disable,
- .pre_enable = mic_pre_enable,
- .enable = mic_enable,
+static const struct component_ops exynos_mic_component_ops = {
+ .bind = exynos_mic_bind,
+ .unbind = exynos_mic_unbind,
};
-int exynos_mic_probe(struct platform_device *pdev)
+static int exynos_mic_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct exynos_mic *mic;
@@ -435,17 +460,8 @@
goto err;
}
- mic->bridge.funcs = &mic_bridge_funcs;
- mic->bridge.of_node = dev->of_node;
- mic->bridge.driver_private = mic;
- ret = drm_bridge_add(&mic->bridge);
- if (ret) {
- DRM_ERROR("mic: Failed to add MIC to the global bridge list\n");
- goto err;
- }
-
for (i = 0; i < NUM_CLKS; i++) {
- mic->clks[i] = of_clk_get_by_name(dev->of_node, clk_names[i]);
+ mic->clks[i] = devm_clk_get(dev, clk_names[i]);
if (IS_ERR(mic->clks[i])) {
DRM_ERROR("mic: Failed to get clock (%s)\n",
clk_names[i]);
@@ -454,7 +470,10 @@
}
}
+ platform_set_drvdata(pdev, mic);
+
DRM_DEBUG_KMS("MIC has been probed\n");
+ return component_add(dev, &exynos_mic_component_ops);
err:
return ret;
@@ -462,14 +481,7 @@
static int exynos_mic_remove(struct platform_device *pdev)
{
- struct exynos_mic *mic = platform_get_drvdata(pdev);
- int i;
-
- drm_bridge_remove(&mic->bridge);
-
- for (i = NUM_CLKS - 1; i > -1; i--)
- clk_put(mic->clks[i]);
-
+ component_del(&pdev->dev, &exynos_mic_component_ops);
return 0;
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
index bea0f78..f18fbe4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
@@ -20,7 +20,6 @@
#include <drm/drmP.h>
#include <drm/exynos_drm.h>
#include "regs-rotator.h"
-#include "exynos_drm.h"
#include "exynos_drm_drv.h"
#include "exynos_drm_ipp.h"
@@ -754,7 +753,7 @@
goto err_ippdrv_register;
}
- DRM_DEBUG_KMS("ippdrv[0x%x]\n", (int)ippdrv);
+ DRM_DEBUG_KMS("ippdrv[%p]\n", ippdrv);
platform_set_drvdata(pdev, rot);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 65108cb..608b0af 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -223,7 +223,7 @@
}
}
-static int vidi_show_connection(struct device *dev,
+static ssize_t vidi_show_connection(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct vidi_context *ctx = dev_get_drvdata(dev);
@@ -238,7 +238,7 @@
return rc;
}
-static int vidi_store_connection(struct device *dev,
+static ssize_t vidi_store_connection(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
@@ -294,7 +294,9 @@
}
if (vidi->connection) {
- struct edid *raw_edid = (struct edid *)(uint32_t)vidi->edid;
+ struct edid *raw_edid;
+
+ raw_edid = (struct edid *)(unsigned long)vidi->edid;
if (!drm_edid_is_valid(raw_edid)) {
DRM_DEBUG_KMS("edid data is invalid.\n");
return -EINVAL;
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 21a29db..e148d72 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -867,10 +867,8 @@
{
u32 hdr_sum;
u8 chksum;
- u32 mod;
u8 ar;
- mod = hdmi_reg_read(hdata, HDMI_MODE_SEL);
if (hdata->dvi_mode) {
hdmi_reg_writeb(hdata, HDMI_VSI_CON,
HDMI_VSI_CON_DO_NOT_TRANSMIT);
diff --git a/include/drm/exynos_drm.h b/include/drm/exynos_drm.h
deleted file mode 100644
index cb65fa1..0000000
--- a/include/drm/exynos_drm.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* exynos_drm.h
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * Authors:
- * Inki Dae <inki.dae@samsung.com>
- * Joonyoung Shim <jy0922.shim@samsung.com>
- * Seung-Woo Kim <sw0312.kim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-#ifndef _EXYNOS_DRM_H_
-#define _EXYNOS_DRM_H_
-
-#include <uapi/drm/exynos_drm.h>
-#include <video/videomode.h>
-
-/**
- * A structure for lcd panel information.
- *
- * @timing: default video mode for initializing
- * @width_mm: physical size of lcd width.
- * @height_mm: physical size of lcd height.
- */
-struct exynos_drm_panel_info {
- struct videomode vm;
- u32 width_mm;
- u32 height_mm;
-};
-
-/**
- * Platform Specific Structure for DRM based FIMD.
- *
- * @panel: default panel info for initializing
- * @default_win: default window layer number to be used for UI.
- * @bpp: default bit per pixel.
- */
-struct exynos_drm_fimd_pdata {
- struct exynos_drm_panel_info panel;
- u32 vidcon0;
- u32 vidcon1;
- unsigned int default_win;
- unsigned int bpp;
-};
-
-/**
- * Platform Specific Structure for DRM based HDMI.
- *
- * @hdmi_dev: device point to specific hdmi driver.
- * @mixer_dev: device point to specific mixer driver.
- *
- * this structure is used for common hdmi driver and each device object
- * would be used to access specific device driver(hdmi or mixer driver)
- */
-struct exynos_drm_common_hdmi_pd {
- struct device *hdmi_dev;
- struct device *mixer_dev;
-};
-
-/**
- * Platform Specific Structure for DRM based HDMI core.
- *
- * @is_v13: set if hdmi version 13 is.
- * @cfg_hpd: function pointer to configure hdmi hotplug detection pin
- * @get_hpd: function pointer to get value of hdmi hotplug detection pin
- */
-struct exynos_drm_hdmi_pdata {
- bool is_v13;
- void (*cfg_hpd)(bool external);
- int (*get_hpd)(void);
-};
-
-/**
- * Platform Specific Structure for DRM based IPP.
- *
- * @inv_pclk: if set 1. invert pixel clock
- * @inv_vsync: if set 1. invert vsync signal for wb
- * @inv_href: if set 1. invert href signal
- * @inv_hsync: if set 1. invert hsync signal for wb
- */
-struct exynos_drm_ipp_pol {
- unsigned int inv_pclk;
- unsigned int inv_vsync;
- unsigned int inv_href;
- unsigned int inv_hsync;
-};
-
-/**
- * Platform Specific Structure for DRM based FIMC.
- *
- * @pol: current hardware block polarity settings.
- * @clk_rate: current hardware clock rate.
- */
-struct exynos_drm_fimc_pdata {
- struct exynos_drm_ipp_pol pol;
- int clk_rate;
-};
-
-#endif /* _EXYNOS_DRM_H_ */
diff --git a/include/uapi/drm/exynos_drm.h b/include/uapi/drm/exynos_drm.h
index 312c67d..d2a5bb1 100644
--- a/include/uapi/drm/exynos_drm.h
+++ b/include/uapi/drm/exynos_drm.h
@@ -28,8 +28,8 @@
*/
struct drm_exynos_gem_create {
__u64 size;
- unsigned int flags;
- unsigned int handle;
+ __u32 flags;
+ __u32 handle;
};
/**
@@ -42,8 +42,8 @@
* be set by driver.
*/
struct drm_exynos_gem_info {
- unsigned int handle;
- unsigned int flags;
+ __u32 handle;
+ __u32 flags;
__u64 size;
};
@@ -56,8 +56,8 @@
* @edid: the edid data pointer from user side.
*/
struct drm_exynos_vidi_connection {
- unsigned int connection;
- unsigned int extensions;
+ __u32 connection;
+ __u32 extensions;
__u64 edid;
};
@@ -206,9 +206,9 @@
* @pos: property of image position(src-cropped,dst-scaler).
*/
struct drm_exynos_ipp_config {
- enum drm_exynos_ops_id ops_id;
- enum drm_exynos_flip flip;
- enum drm_exynos_degree degree;
+ __u32 ops_id;
+ __u32 flip;
+ __u32 degree;
__u32 fmt;
struct drm_exynos_sz sz;
struct drm_exynos_pos pos;
@@ -233,7 +233,7 @@
*/
struct drm_exynos_ipp_property {
struct drm_exynos_ipp_config config[EXYNOS_DRM_OPS_MAX];
- enum drm_exynos_ipp_cmd cmd;
+ __u32 cmd;
__u32 ipp_id;
__u32 prop_id;
__u32 refresh_rate;
@@ -255,8 +255,8 @@
* @user_data: user data.
*/
struct drm_exynos_ipp_queue_buf {
- enum drm_exynos_ops_id ops_id;
- enum drm_exynos_ipp_buf_type buf_type;
+ __u32 ops_id;
+ __u32 buf_type;
__u32 prop_id;
__u32 buf_id;
__u32 handle[EXYNOS_DRM_PLANAR_MAX];
@@ -280,7 +280,7 @@
*/
struct drm_exynos_ipp_cmd_ctrl {
__u32 prop_id;
- enum drm_exynos_ipp_ctrl ctrl;
+ __u32 ctrl;
};
#define DRM_EXYNOS_GEM_CREATE 0x00