diff options
Diffstat (limited to 'drivers/gpu/drm/exynos')
21 files changed, 366 insertions, 416 deletions
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile index 6496532aaa91..968b31c522b2 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 162ab93e99cb..5245bc5e82e9 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -429,7 +429,7 @@ static void decon_disable(struct exynos_drm_crtc *crtc) 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; diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index 52bda3b42fe0..93361073af9a 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -60,7 +60,6 @@ struct decon_context { 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 673164b331c8..cff8dc788820 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.c +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c @@ -977,9 +977,7 @@ static int exynos_dp_get_modes(struct drm_connector *connector) 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; @@ -1155,13 +1153,6 @@ static int exynos_dp_create_connector(struct drm_encoder *encoder) 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) @@ -1177,7 +1168,6 @@ static void exynos_dp_disable(struct drm_encoder *encoder) } static const struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = { - .mode_fixup = exynos_dp_mode_fixup, .mode_set = exynos_dp_mode_set, .enable = exynos_dp_enable, .disable = exynos_dp_disable, @@ -1249,8 +1239,7 @@ static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp) { 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 66eec4b2d5c6..b5c2d8f47f9c 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 exynos_dp_device { 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_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c index 05350ae0785b..75e570f45259 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c @@ -128,13 +128,6 @@ static int exynos_dpi_create_connector(struct drm_encoder *encoder) return 0; } -static bool exynos_dpi_mode_fixup(struct drm_encoder *encoder, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - static void exynos_dpi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) @@ -162,7 +155,6 @@ static void exynos_dpi_disable(struct drm_encoder *encoder) } static const struct drm_encoder_helper_funcs exynos_dpi_encoder_helper_funcs = { - .mode_fixup = exynos_dpi_mode_fixup, .mode_set = exynos_dpi_mode_set, .enable = exynos_dpi_enable, .disable = exynos_dpi_disable, diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 68f0f36f6e7e..5344940c8a07 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -130,6 +130,8 @@ static void exynos_drm_atomic_work(struct work_struct *work) 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 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) 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. @@ -340,20 +352,6 @@ static void exynos_drm_preclose(struct drm_device *dev, static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file) { - struct drm_pending_event *e, *et; - unsigned long flags; - - if (!file->driver_priv) - return; - - spin_lock_irqsave(&dev->event_lock, flags); - /* Release all events handled by page flip handler but not freed. */ - list_for_each_entry_safe(e, et, &file->event_list, link) { - list_del(&e->link); - e->destroy(e); - } - spin_unlock_irqrestore(&dev->event_lock, flags); - kfree(file->driver_priv); file->driver_priv = NULL; } @@ -372,6 +370,8 @@ static const struct vm_operations_struct exynos_drm_gem_vm_ops = { static const struct drm_ioctl_desc exynos_ioctls[] = { DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl, DRM_AUTH | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MAP, exynos_drm_gem_map_ioctl, + DRM_AUTH | DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(EXYNOS_GEM_GET, exynos_drm_gem_get_ioctl, DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION, vidi_connection_ioctl, @@ -495,69 +495,65 @@ static const struct dev_pm_ops exynos_drm_pm_ops = { /* 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 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, +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 + } }; -#define PDEV_COUNT ARRAY_SIZE(exynos_drm_drv_with_simple_dev) static int compare_dev(struct device *dev, void *data) { @@ -569,11 +565,15 @@ static struct component_match *exynos_drm_match_add(struct device *dev) 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); @@ -630,91 +630,102 @@ static struct platform_driver exynos_drm_platform_driver = { }, }; -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; + + 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 (--i >= 0) { - platform_device_unregister(exynos_drm_pdevs[i]); - exynos_drm_pdevs[i] = NULL; + 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; -static int exynos_drm_register_drivers(struct platform_driver * const *drv, - int count) -{ - int i, ret; + for (i = ARRAY_SIZE(exynos_drm_drivers) - 1; i >= 0; --i) { + struct exynos_drm_driver_info *info = &exynos_drm_drivers[i]; - for (i = 0; i < count; ++i) { - ret = platform_driver_register(drv[i]); - if (!ret) + if (!info->driver) continue; - while (--i >= 0) - platform_driver_unregister(drv[i]); - - return ret; + platform_driver_unregister(info->driver); } - - return 0; } -static inline int exynos_drm_register_kms_drivers(void) +static int exynos_drm_register_drivers(void) { - return exynos_drm_register_drivers(exynos_drm_kms_drivers, - ARRAY_SIZE(exynos_drm_kms_drivers)); -} + int i, ret; -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)); -} + for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) { + struct exynos_drm_driver_info *info = &exynos_drm_drivers[i]; -static inline void exynos_drm_unregister_kms_drivers(void) -{ - exynos_drm_unregister_drivers(exynos_drm_kms_drivers, - ARRAY_SIZE(exynos_drm_kms_drivers)); -} + if (!info->driver) + continue; -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)); + ret = platform_driver_register(info->driver); + if (ret) + goto fail; + } + return 0; +fail: + exynos_drm_unregister_drivers(); + return ret; } static int exynos_drm_init(void) @@ -725,19 +736,12 @@ static int exynos_drm_init(void) 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(); @@ -746,8 +750,7 @@ err_unregister_pdevs: 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 17b5ded72ff1..502f750bad2a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -219,8 +219,10 @@ struct exynos_drm_private { 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 @@ struct exynos_drm_private { 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 dp_driver; 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 26e81d191f56..63c84a106c0b 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 exynos_dsi_transfer { 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 @@ struct exynos_dsi_transfer { #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 @@ struct exynos_dsi_driver_data { 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 @@ enum reg_idx { 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 @@ static unsigned int exynos_reg_ofs[] = { [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 @@ enum reg_value_idx { 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 @@ static unsigned int reg_values[] = { [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 @@ static unsigned int exynos5433_reg_values[] = { [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 @@ static struct exynos_dsi_driver_data exynos3_dsi_driver_data = { .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 @@ static struct exynos_dsi_driver_data exynos4_dsi_driver_data = { .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 @@ static struct exynos_dsi_driver_data exynos4415_dsi_driver_data = { .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 @@ static struct exynos_dsi_driver_data exynos5_dsi_driver_data = { .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 @@ static struct exynos_dsi_driver_data exynos5433_dsi_driver_data = { .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 @@ static struct of_device_id exynos_dsi_of_match[] = { .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_wait_for_reset(struct exynos_dsi *dsi) 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 @@ static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi, 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 @@ static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi, 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 @@ static int exynos_dsi_enable_clock(struct exynos_dsi *dsi) 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 @@ static int exynos_dsi_enable_clock(struct exynos_dsi *dsi) | 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 int exynos_dsi_enable_clock(struct exynos_dsi *dsi) 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 @@ static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi) /* 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 @@ static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi) * 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 @@ static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi) 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 @@ static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi) */ 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 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi) 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 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi) 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 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi) 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 @@ static void exynos_dsi_set_display_mode(struct exynos_dsi *dsi) 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 @@ static void exynos_dsi_set_display_enable(struct exynos_dsi *dsi, bool enable) { 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 @@ static int exynos_dsi_wait_for_hdr_fifo(struct exynos_dsi *dsi) 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 int exynos_dsi_wait_for_hdr_fifo(struct exynos_dsi *dsi) 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 @@ static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi, /* 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 @@ static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi, /* 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 @@ static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi, 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 @@ static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi, 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 @@ static void exynos_dsi_read_from_fifo(struct exynos_dsi *dsi, 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 @@ static void exynos_dsi_read_from_fifo(struct exynos_dsi *dsi, /* 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 @@ static void exynos_dsi_read_from_fifo(struct exynos_dsi *dsi, } 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 @@ static void exynos_dsi_read_from_fifo(struct exynos_dsi *dsi, 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 @@ again: 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 @@ static bool exynos_dsi_transfer_finish(struct exynos_dsi *dsi) 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 @@ static int exynos_dsi_transfer(struct exynos_dsi *dsi, 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 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id) 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 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host, 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 @@ static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host, 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; @@ -1597,13 +1611,6 @@ static int exynos_dsi_create_connector(struct drm_encoder *encoder) return 0; } -static bool exynos_dsi_mode_fixup(struct drm_encoder *encoder, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - static void exynos_dsi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) @@ -1623,7 +1630,6 @@ static void exynos_dsi_mode_set(struct drm_encoder *encoder, } static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = { - .mode_fixup = exynos_dsi_mode_fixup, .mode_set = exynos_dsi_mode_set, .enable = exynos_dsi_enable, .disable = exynos_dsi_disable, diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 8baabd813ff5..4ae860c44f1d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -50,7 +50,7 @@ static int exynos_drm_fb_mmap(struct fb_info *info, if (vm_size > exynos_gem->size) return -EINVAL; - ret = dma_mmap_attrs(helper->dev->dev, vma, exynos_gem->cookie, + 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 8a4f4a0211d0..0525c56145db 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c @@ -163,7 +163,6 @@ struct fimc_context { 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 @@ static void fimc_set_type_ctrl(struct fimc_context *ctx, enum fimc_wb wb) 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 @@ static int fimc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd) /* 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: diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 70194d0e4fe4..51d484ae9f49 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -94,12 +94,14 @@ struct fimd_driver_data { 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 @@ static struct fimd_driver_data exynos5_fimd_driver_data = { .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 @@ struct fimd_context { 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 @@ static const struct of_device_id fimd_driver_dt_match[] = { .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 @@ static u32 fimd_calc_clkdiv(struct fimd_context *ctx, } /* 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 @@ static void fimd_commit(struct exynos_drm_crtc *crtc) 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 @@ static void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable) * 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 8dfe6e113a88..193d3602dffb 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -259,7 +259,7 @@ static int g2d_init_cmdlist(struct g2d_data *g2d) 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 @@ static int g2d_init_cmdlist(struct g2d_data *g2d) 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 @@ static void g2d_fini_cmdlist(struct g2d_data *g2d) 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); } @@ -880,7 +881,6 @@ static void g2d_finish_event(struct g2d_data *g2d, u32 cmdlist_no) struct g2d_runqueue_node *runqueue_node = g2d->runqueue_node; struct drm_exynos_pending_g2d_event *e; struct timeval now; - unsigned long flags; if (list_empty(&runqueue_node->event_list)) return; @@ -893,10 +893,7 @@ static void g2d_finish_event(struct g2d_data *g2d, u32 cmdlist_no) e->event.tv_usec = now.tv_usec; e->event.cmdlist_no = cmdlist_no; - spin_lock_irqsave(&drm_dev->event_lock, flags); - list_move_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - spin_unlock_irqrestore(&drm_dev->event_lock, flags); + drm_send_event(drm_dev, &e->base); } static irqreturn_t g2d_irq_handler(int irq, void *dev_id) @@ -1072,7 +1069,6 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, struct drm_exynos_pending_g2d_event *e; struct g2d_cmdlist_node *node; struct g2d_cmdlist *cmdlist; - unsigned long flags; int size; int ret; @@ -1094,21 +1090,8 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, node->event = NULL; if (req->event_type != G2D_EVENT_NOT) { - spin_lock_irqsave(&drm_dev->event_lock, flags); - if (file->event_space < sizeof(e->event)) { - spin_unlock_irqrestore(&drm_dev->event_lock, flags); - ret = -ENOMEM; - goto err; - } - file->event_space -= sizeof(e->event); - spin_unlock_irqrestore(&drm_dev->event_lock, flags); - e = kzalloc(sizeof(*node->event), GFP_KERNEL); if (!e) { - spin_lock_irqsave(&drm_dev->event_lock, flags); - file->event_space += sizeof(e->event); - spin_unlock_irqrestore(&drm_dev->event_lock, flags); - ret = -ENOMEM; goto err; } @@ -1116,9 +1099,12 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, e->event.base.type = DRM_EXYNOS_G2D_EVENT; e->event.base.length = sizeof(e->event); e->event.user_data = req->user_data; - e->base.event = &e->event.base; - e->base.file_priv = file; - e->base.destroy = (void (*) (struct drm_pending_event *)) kfree; + + ret = drm_event_reserve_init(drm_dev, file, &e->base, &e->event.base); + if (ret) { + kfree(e); + goto err; + } node->event = e; } @@ -1220,12 +1206,8 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, err_unmap: g2d_unmap_cmdlist_gem(g2d, node, file); err_free_event: - if (node->event) { - spin_lock_irqsave(&drm_dev->event_lock, flags); - file->event_space += sizeof(e->event); - spin_unlock_irqrestore(&drm_dev->event_lock, flags); - kfree(node->event); - } + if (node->event) + drm_event_cancel_free(drm_dev, &node->event->base); err: g2d_put_cmdlist(g2d, node); return ret; diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 26b5e4bd55b6..2914d62d0d80 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -65,7 +65,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem) 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 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem) 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 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem) 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 @@ static void exynos_drm_free_buf(struct exynos_drm_gem *exynos_gem) 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); @@ -280,6 +280,15 @@ int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data, return 0; } +int exynos_drm_gem_map_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_exynos_gem_map *args = data; + + return exynos_drm_gem_dumb_map_offset(file_priv, dev, args->handle, + &args->offset); +} + dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev, unsigned int gem_handle, struct drm_file *filp) @@ -335,7 +344,7 @@ static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem *exynos_gem, if (vm_size > exynos_gem->size) return -EINVAL; - ret = dma_mmap_attrs(drm_dev->dev, vma, exynos_gem->cookie, + 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 +390,7 @@ int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev, 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 +405,7 @@ void exynos_gem_unmap_sgt_from_dma(struct drm_device *drm_dev, 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_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h index 9ca5047959ec..00223052b87b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h @@ -71,6 +71,10 @@ struct exynos_drm_gem *exynos_drm_gem_create(struct drm_device *dev, int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +/* get fake-offset of gem object that can be used with mmap. */ +int exynos_drm_gem_map_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + /* * get dma address from gem handle and this function could be used for * other drivers such as 2d/3d acceleration drivers. diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.c b/drivers/gpu/drm/exynos/exynos_drm_iommu.c index d73b9ad35b7a..7ca09ee19656 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 @@ int drm_create_iommu_mapping(struct drm_device *drm_dev) { 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 @@ int drm_create_iommu_mapping(struct drm_device *drm_dev) 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 @@ error: */ 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 @@ void drm_release_iommu_mapping(struct drm_device *drm_dev) 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 @@ int drm_iommu_attach_device(struct drm_device *drm_dev, 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 @@ int drm_iommu_attach_device(struct drm_device *drm_dev, 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 dc1b5441f491..5ffebe02ee4d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_iommu.h +++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.h @@ -29,9 +29,9 @@ void drm_iommu_detach_device(struct drm_device *dev_dev, 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 95eeb9116f10..9c84ee76f18a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -618,27 +618,18 @@ static void ipp_clean_mem_nodes(struct drm_device *drm_dev, mutex_unlock(&c_node->mem_lock); } -static void ipp_free_event(struct drm_pending_event *event) -{ - kfree(event); -} - static int ipp_get_event(struct drm_device *drm_dev, struct drm_exynos_ipp_cmd_node *c_node, struct drm_exynos_ipp_queue_buf *qbuf) { struct drm_exynos_ipp_send_event *e; - unsigned long flags; + int ret; DRM_DEBUG_KMS("ops_id[%d]buf_id[%d]\n", qbuf->ops_id, qbuf->buf_id); e = kzalloc(sizeof(*e), GFP_KERNEL); - if (!e) { - spin_lock_irqsave(&drm_dev->event_lock, flags); - c_node->filp->event_space += sizeof(e->event); - spin_unlock_irqrestore(&drm_dev->event_lock, flags); + if (!e) return -ENOMEM; - } /* make event */ e->event.base.type = DRM_EXYNOS_IPP_EVENT; @@ -646,9 +637,13 @@ static int ipp_get_event(struct drm_device *drm_dev, e->event.user_data = qbuf->user_data; e->event.prop_id = qbuf->prop_id; e->event.buf_id[EXYNOS_DRM_OPS_DST] = qbuf->buf_id; - e->base.event = &e->event.base; - e->base.file_priv = c_node->filp; - e->base.destroy = ipp_free_event; + + ret = drm_event_reserve_init(drm_dev, c_node->filp, &e->base, &e->event.base); + if (ret) { + kfree(e); + return ret; + } + mutex_lock(&c_node->event_lock); list_add_tail(&e->base.link, &c_node->event_list); mutex_unlock(&c_node->event_lock); @@ -1412,7 +1407,6 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv, struct drm_exynos_ipp_send_event *e; struct list_head *head; struct timeval now; - unsigned long flags; u32 tbuf_id[EXYNOS_DRM_OPS_MAX] = {0, }; int ret, i; @@ -1525,10 +1519,7 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv, for_each_ipp_ops(i) e->event.buf_id[i] = tbuf_id[i]; - spin_lock_irqsave(&drm_dev->event_lock, flags); - list_move_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - spin_unlock_irqrestore(&drm_dev->event_lock, flags); + drm_send_event(drm_dev, &e->base); mutex_unlock(&c_node->event_lock); DRM_DEBUG_KMS("done cmd[%d]prop_id[%d]buf_id[%d]\n", diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c index ce59f4443394..f18fbe43f55f 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" diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index b605bd7395ec..608b0afa337f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -412,13 +412,6 @@ static int vidi_create_connector(struct drm_encoder *encoder) return 0; } -static bool exynos_vidi_mode_fixup(struct drm_encoder *encoder, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - static void exynos_vidi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) @@ -434,7 +427,6 @@ static void exynos_vidi_disable(struct drm_encoder *encoder) } static const struct drm_encoder_helper_funcs exynos_vidi_encoder_helper_funcs = { - .mode_fixup = exynos_vidi_mode_fixup, .mode_set = exynos_vidi_mode_set, .enable = exynos_vidi_enable, .disable = exynos_vidi_disable, diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 21a29dbce18c..e148d728e28c 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -867,10 +867,8 @@ static void hdmi_reg_infoframe(struct hdmi_context *hdata, { 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); |