Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'exynos-drm-next-for-v4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-next

- Refactoring of DMA and IOMMU code
. This patch series simplifies DMA mapping creation by avoiding looping
all components to get dma device object, reduces code size by merging
IOMMU and DMA code.
- Enhance plane alpha and blend mode support
. This patch series adds configurable plane and pixel blend mode support
for Exynos5433 DECON device.
- Fix color format setting of Mixer driver
. This patch series fixes color format and range setting by splitting
range and format.

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Inki Dae <inki.dae@samsung.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1544002853-11661-1-git-send-email-inki.dae@samsung.com

+314 -348
-5
drivers/gpu/drm/exynos/Kconfig
··· 10 10 11 11 if DRM_EXYNOS 12 12 13 - config DRM_EXYNOS_IOMMU 14 - bool 15 - depends on EXYNOS_IOMMU 16 - default y 17 - 18 13 comment "CRTCs" 19 14 20 15 config DRM_EXYNOS_FIMD
+1 -2
drivers/gpu/drm/exynos/Makefile
··· 4 4 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. 5 5 6 6 exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fb.o \ 7 - exynos_drm_gem.o exynos_drm_plane.o 7 + exynos_drm_gem.o exynos_drm_plane.o exynos_drm_dma.o 8 8 9 9 exynosdrm-$(CONFIG_DRM_FBDEV_EMULATION) += exynos_drm_fbdev.o 10 - exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o 11 10 exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o 12 11 exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o 13 12 exynosdrm-$(CONFIG_DRM_EXYNOS7_DECON) += exynos7_drm_decon.o
+82 -5
drivers/gpu/drm/exynos/exynos5433_drm_decon.c
··· 25 25 #include "exynos_drm_crtc.h" 26 26 #include "exynos_drm_fb.h" 27 27 #include "exynos_drm_plane.h" 28 - #include "exynos_drm_iommu.h" 29 28 #include "regs-decon5433.h" 30 29 31 30 #define DSD_CFG_MUX 0x1004 ··· 81 82 static const enum drm_plane_type decon_win_types[WINDOWS_NR] = { 82 83 [PRIMARY_WIN] = DRM_PLANE_TYPE_PRIMARY, 83 84 [CURSON_WIN] = DRM_PLANE_TYPE_CURSOR, 85 + }; 86 + 87 + static const unsigned int capabilities[WINDOWS_NR] = { 88 + 0, 89 + EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND, 90 + EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND, 91 + EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND, 92 + EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND, 84 93 }; 85 94 86 95 static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask, ··· 259 252 decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); 260 253 } 261 254 255 + static void decon_win_set_bldeq(struct decon_context *ctx, unsigned int win, 256 + unsigned int alpha, unsigned int pixel_alpha) 257 + { 258 + u32 mask = BLENDERQ_A_FUNC_F(0xf) | BLENDERQ_B_FUNC_F(0xf); 259 + u32 val = 0; 260 + 261 + switch (pixel_alpha) { 262 + case DRM_MODE_BLEND_PIXEL_NONE: 263 + case DRM_MODE_BLEND_COVERAGE: 264 + val |= BLENDERQ_A_FUNC_F(BLENDERQ_ALPHA_A); 265 + val |= BLENDERQ_B_FUNC_F(BLENDERQ_ONE_MINUS_ALPHA_A); 266 + break; 267 + case DRM_MODE_BLEND_PREMULTI: 268 + default: 269 + if (alpha != DRM_BLEND_ALPHA_OPAQUE) { 270 + val |= BLENDERQ_A_FUNC_F(BLENDERQ_ALPHA0); 271 + val |= BLENDERQ_B_FUNC_F(BLENDERQ_ONE_MINUS_ALPHA_A); 272 + } else { 273 + val |= BLENDERQ_A_FUNC_F(BLENDERQ_ONE); 274 + val |= BLENDERQ_B_FUNC_F(BLENDERQ_ONE_MINUS_ALPHA_A); 275 + } 276 + break; 277 + } 278 + decon_set_bits(ctx, DECON_BLENDERQx(win), mask, val); 279 + } 280 + 281 + static void decon_win_set_bldmod(struct decon_context *ctx, unsigned int win, 282 + unsigned int alpha, unsigned int pixel_alpha) 283 + { 284 + u32 win_alpha = alpha >> 8; 285 + u32 val = 0; 286 + 287 + switch (pixel_alpha) { 288 + case DRM_MODE_BLEND_PIXEL_NONE: 289 + break; 290 + case DRM_MODE_BLEND_COVERAGE: 291 + case DRM_MODE_BLEND_PREMULTI: 292 + default: 293 + val |= WINCONx_ALPHA_SEL_F; 294 + val |= WINCONx_BLD_PIX_F; 295 + val |= WINCONx_ALPHA_MUL_F; 296 + break; 297 + } 298 + decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_BLEND_MODE_MASK, val); 299 + 300 + if (alpha != DRM_BLEND_ALPHA_OPAQUE) { 301 + val = VIDOSD_Wx_ALPHA_R_F(win_alpha) | 302 + VIDOSD_Wx_ALPHA_G_F(win_alpha) | 303 + VIDOSD_Wx_ALPHA_B_F(win_alpha); 304 + decon_set_bits(ctx, DECON_VIDOSDxC(win), 305 + VIDOSDxC_ALPHA0_RGB_MASK, val); 306 + decon_set_bits(ctx, DECON_BLENDCON, BLEND_NEW, BLEND_NEW); 307 + } 308 + } 309 + 262 310 static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, 263 311 struct drm_framebuffer *fb) 264 312 { 313 + struct exynos_drm_plane plane = ctx->planes[win]; 314 + struct exynos_drm_plane_state *state = 315 + to_exynos_plane_state(plane.base.state); 316 + unsigned int alpha = state->base.alpha; 317 + unsigned int pixel_alpha; 265 318 unsigned long val; 319 + 320 + if (fb->format->has_alpha) 321 + pixel_alpha = state->base.pixel_blend_mode; 322 + else 323 + pixel_alpha = DRM_MODE_BLEND_PIXEL_NONE; 266 324 267 325 val = readl(ctx->addr + DECON_WINCONx(win)); 268 326 val &= WINCONx_ENWIN_F; ··· 351 279 case DRM_FORMAT_ARGB8888: 352 280 default: 353 281 val |= WINCONx_BPPMODE_32BPP_A8888; 354 - val |= WINCONx_WSWP_F | WINCONx_BLD_PIX_F | WINCONx_ALPHA_SEL_F; 282 + val |= WINCONx_WSWP_F; 355 283 val |= WINCONx_BURSTLEN_16WORD; 356 284 break; 357 285 } ··· 370 298 val &= ~WINCONx_BURSTLEN_MASK; 371 299 val |= WINCONx_BURSTLEN_8WORD; 372 300 } 301 + decon_set_bits(ctx, DECON_WINCONx(win), ~WINCONx_BLEND_MODE_MASK, val); 373 302 374 - writel(val, ctx->addr + DECON_WINCONx(win)); 303 + if (win > 0) { 304 + decon_win_set_bldmod(ctx, win, alpha, pixel_alpha); 305 + decon_win_set_bldeq(ctx, win, alpha, pixel_alpha); 306 + } 375 307 } 376 308 377 309 static void decon_shadow_protect(struct decon_context *ctx, bool protect) ··· 628 552 ctx->configs[win].num_pixel_formats = ARRAY_SIZE(decon_formats); 629 553 ctx->configs[win].zpos = win - ctx->first_win; 630 554 ctx->configs[win].type = decon_win_types[win]; 555 + ctx->configs[win].capabilities = capabilities[win]; 631 556 632 557 ret = exynos_plane_init(drm_dev, &ctx->planes[win], win, 633 558 &ctx->configs[win]); ··· 646 569 647 570 decon_clear_channels(ctx->crtc); 648 571 649 - return drm_iommu_attach_device(drm_dev, dev); 572 + return exynos_drm_register_dma(drm_dev, dev); 650 573 } 651 574 652 575 static void decon_unbind(struct device *dev, struct device *master, void *data) ··· 656 579 decon_disable(ctx->crtc); 657 580 658 581 /* detach this sub driver from iommu mapping if supported. */ 659 - drm_iommu_detach_device(ctx->drm_dev, ctx->dev); 582 + exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev); 660 583 } 661 584 662 585 static const struct component_ops decon_component_ops = {
+2 -3
drivers/gpu/drm/exynos/exynos7_drm_decon.c
··· 30 30 #include "exynos_drm_plane.h" 31 31 #include "exynos_drm_drv.h" 32 32 #include "exynos_drm_fb.h" 33 - #include "exynos_drm_iommu.h" 34 33 #include "regs-decon7.h" 35 34 36 35 /* ··· 132 133 133 134 decon_clear_channels(ctx->crtc); 134 135 135 - return drm_iommu_attach_device(drm_dev, ctx->dev); 136 + return exynos_drm_register_dma(drm_dev, ctx->dev); 136 137 } 137 138 138 139 static void decon_ctx_remove(struct decon_context *ctx) 139 140 { 140 141 /* detach this sub driver from iommu mapping if supported. */ 141 - drm_iommu_detach_device(ctx->drm_dev, ctx->dev); 142 + exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev); 142 143 } 143 144 144 145 static u32 decon_calc_clkdiv(struct decon_context *ctx,
+157
drivers/gpu/drm/exynos/exynos_drm_dma.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright (c) 2012 Samsung Electronics Co., Ltd. 4 + // Author: Inki Dae <inki.dae@samsung.com> 5 + // Author: Andrzej Hajda <a.hajda@samsung.com> 6 + 7 + #include <drm/drmP.h> 8 + #include <drm/exynos_drm.h> 9 + #include <linux/dma-iommu.h> 10 + #include <linux/dma-mapping.h> 11 + #include <linux/iommu.h> 12 + 13 + #include "exynos_drm_drv.h" 14 + 15 + #if defined(CONFIG_ARM_DMA_USE_IOMMU) 16 + #include <asm/dma-iommu.h> 17 + #else 18 + #define arm_iommu_create_mapping(...) ({ NULL; }) 19 + #define arm_iommu_attach_device(...) ({ -ENODEV; }) 20 + #define arm_iommu_release_mapping(...) ({ }) 21 + #define arm_iommu_detach_device(...) ({ }) 22 + #define to_dma_iommu_mapping(dev) NULL 23 + #endif 24 + 25 + #if !defined(CONFIG_IOMMU_DMA) 26 + #define iommu_dma_init_domain(...) ({ -EINVAL; }) 27 + #endif 28 + 29 + #define EXYNOS_DEV_ADDR_START 0x20000000 30 + #define EXYNOS_DEV_ADDR_SIZE 0x40000000 31 + 32 + static inline int configure_dma_max_seg_size(struct device *dev) 33 + { 34 + if (!dev->dma_parms) 35 + dev->dma_parms = kzalloc(sizeof(*dev->dma_parms), GFP_KERNEL); 36 + if (!dev->dma_parms) 37 + return -ENOMEM; 38 + 39 + dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); 40 + return 0; 41 + } 42 + 43 + static inline void clear_dma_max_seg_size(struct device *dev) 44 + { 45 + kfree(dev->dma_parms); 46 + dev->dma_parms = NULL; 47 + } 48 + 49 + /* 50 + * drm_iommu_attach_device- attach device to iommu mapping 51 + * 52 + * @drm_dev: DRM device 53 + * @subdrv_dev: device to be attach 54 + * 55 + * This function should be called by sub drivers to attach it to iommu 56 + * mapping. 57 + */ 58 + static int drm_iommu_attach_device(struct drm_device *drm_dev, 59 + struct device *subdrv_dev) 60 + { 61 + struct exynos_drm_private *priv = drm_dev->dev_private; 62 + int ret; 63 + 64 + if (get_dma_ops(priv->dma_dev) != get_dma_ops(subdrv_dev)) { 65 + DRM_ERROR("Device %s lacks support for IOMMU\n", 66 + dev_name(subdrv_dev)); 67 + return -EINVAL; 68 + } 69 + 70 + ret = configure_dma_max_seg_size(subdrv_dev); 71 + if (ret) 72 + return ret; 73 + 74 + if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) { 75 + if (to_dma_iommu_mapping(subdrv_dev)) 76 + arm_iommu_detach_device(subdrv_dev); 77 + 78 + ret = arm_iommu_attach_device(subdrv_dev, priv->mapping); 79 + } else if (IS_ENABLED(CONFIG_IOMMU_DMA)) { 80 + ret = iommu_attach_device(priv->mapping, subdrv_dev); 81 + } 82 + 83 + if (ret) 84 + clear_dma_max_seg_size(subdrv_dev); 85 + 86 + return 0; 87 + } 88 + 89 + /* 90 + * drm_iommu_detach_device -detach device address space mapping from device 91 + * 92 + * @drm_dev: DRM device 93 + * @subdrv_dev: device to be detached 94 + * 95 + * This function should be called by sub drivers to detach it from iommu 96 + * mapping 97 + */ 98 + static void drm_iommu_detach_device(struct drm_device *drm_dev, 99 + struct device *subdrv_dev) 100 + { 101 + struct exynos_drm_private *priv = drm_dev->dev_private; 102 + 103 + if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) 104 + arm_iommu_detach_device(subdrv_dev); 105 + else if (IS_ENABLED(CONFIG_IOMMU_DMA)) 106 + iommu_detach_device(priv->mapping, subdrv_dev); 107 + 108 + clear_dma_max_seg_size(subdrv_dev); 109 + } 110 + 111 + int exynos_drm_register_dma(struct drm_device *drm, struct device *dev) 112 + { 113 + struct exynos_drm_private *priv = drm->dev_private; 114 + 115 + if (!priv->dma_dev) { 116 + priv->dma_dev = dev; 117 + DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n", 118 + dev_name(dev)); 119 + } 120 + 121 + if (!IS_ENABLED(CONFIG_EXYNOS_IOMMU)) 122 + return 0; 123 + 124 + if (!priv->mapping) { 125 + void *mapping; 126 + 127 + if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) 128 + mapping = arm_iommu_create_mapping(&platform_bus_type, 129 + EXYNOS_DEV_ADDR_START, EXYNOS_DEV_ADDR_SIZE); 130 + else if (IS_ENABLED(CONFIG_IOMMU_DMA)) 131 + mapping = iommu_get_domain_for_dev(priv->dma_dev); 132 + 133 + if (IS_ERR(mapping)) 134 + return PTR_ERR(mapping); 135 + priv->mapping = mapping; 136 + } 137 + 138 + return drm_iommu_attach_device(drm, dev); 139 + } 140 + 141 + void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev) 142 + { 143 + if (IS_ENABLED(CONFIG_EXYNOS_IOMMU)) 144 + drm_iommu_detach_device(drm, dev); 145 + } 146 + 147 + void exynos_drm_cleanup_dma(struct drm_device *drm) 148 + { 149 + struct exynos_drm_private *priv = drm->dev_private; 150 + 151 + if (!IS_ENABLED(CONFIG_EXYNOS_IOMMU)) 152 + return; 153 + 154 + arm_iommu_release_mapping(priv->mapping); 155 + priv->mapping = NULL; 156 + priv->dma_dev = NULL; 157 + }
+7 -48
drivers/gpu/drm/exynos/exynos_drm_drv.c
··· 30 30 #include "exynos_drm_ipp.h" 31 31 #include "exynos_drm_vidi.h" 32 32 #include "exynos_drm_g2d.h" 33 - #include "exynos_drm_iommu.h" 34 33 35 34 #define DRIVER_NAME "exynos" 36 35 #define DRIVER_DESC "Samsung SoC DRM" ··· 174 175 175 176 #define DRM_COMPONENT_DRIVER BIT(0) /* supports component framework */ 176 177 #define DRM_VIRTUAL_DEVICE BIT(1) /* create virtual platform device */ 177 - #define DRM_DMA_DEVICE BIT(2) /* can be used for dma allocations */ 178 - #define DRM_FIMC_DEVICE BIT(3) /* devices shared with V4L2 subsystem */ 178 + #define DRM_FIMC_DEVICE BIT(2) /* devices shared with V4L2 subsystem */ 179 179 180 180 #define DRV_PTR(drv, cond) (IS_ENABLED(cond) ? &drv : NULL) 181 181 ··· 185 187 static struct exynos_drm_driver_info exynos_drm_drivers[] = { 186 188 { 187 189 DRV_PTR(fimd_driver, CONFIG_DRM_EXYNOS_FIMD), 188 - DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE 190 + DRM_COMPONENT_DRIVER 189 191 }, { 190 192 DRV_PTR(exynos5433_decon_driver, CONFIG_DRM_EXYNOS5433_DECON), 191 - DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE 193 + DRM_COMPONENT_DRIVER 192 194 }, { 193 195 DRV_PTR(decon_driver, CONFIG_DRM_EXYNOS7_DECON), 194 - DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE 196 + DRM_COMPONENT_DRIVER 195 197 }, { 196 198 DRV_PTR(mixer_driver, CONFIG_DRM_EXYNOS_MIXER), 197 - DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE 199 + DRM_COMPONENT_DRIVER 198 200 }, { 199 201 DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC), 200 202 DRM_COMPONENT_DRIVER ··· 265 267 return match ?: ERR_PTR(-ENODEV); 266 268 } 267 269 268 - static struct device *exynos_drm_get_dma_device(void) 269 - { 270 - int i; 271 - 272 - for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) { 273 - struct exynos_drm_driver_info *info = &exynos_drm_drivers[i]; 274 - struct device *dev; 275 - 276 - if (!info->driver || !(info->flags & DRM_DMA_DEVICE)) 277 - continue; 278 - 279 - while ((dev = bus_find_device(&platform_bus_type, NULL, 280 - &info->driver->driver, 281 - (void *)platform_bus_type.match))) { 282 - put_device(dev); 283 - return dev; 284 - } 285 - } 286 - return NULL; 287 - } 288 - 289 270 static int exynos_drm_bind(struct device *dev) 290 271 { 291 272 struct exynos_drm_private *private; ··· 288 311 289 312 dev_set_drvdata(dev, drm); 290 313 drm->dev_private = (void *)private; 291 - 292 - /* the first real CRTC device is used for all dma mapping operations */ 293 - private->dma_dev = exynos_drm_get_dma_device(); 294 - if (!private->dma_dev) { 295 - DRM_ERROR("no device found for DMA mapping operations.\n"); 296 - ret = -ENODEV; 297 - goto err_free_private; 298 - } 299 - DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n", 300 - dev_name(private->dma_dev)); 301 - 302 - /* create common IOMMU mapping for all devices attached to Exynos DRM */ 303 - ret = drm_create_iommu_mapping(drm); 304 - if (ret < 0) { 305 - DRM_ERROR("failed to create iommu mapping.\n"); 306 - goto err_free_private; 307 - } 308 314 309 315 drm_mode_config_init(drm); 310 316 ··· 345 385 component_unbind_all(drm->dev, drm); 346 386 err_mode_config_cleanup: 347 387 drm_mode_config_cleanup(drm); 348 - drm_release_iommu_mapping(drm); 349 - err_free_private: 388 + exynos_drm_cleanup_dma(drm); 350 389 kfree(private); 351 390 err_free_drm: 352 391 drm_dev_put(drm); ··· 364 405 365 406 component_unbind_all(drm->dev, drm); 366 407 drm_mode_config_cleanup(drm); 367 - drm_release_iommu_mapping(drm); 408 + exynos_drm_cleanup_dma(drm); 368 409 369 410 kfree(drm->dev_private); 370 411 drm->dev_private = NULL;
+11
drivers/gpu/drm/exynos/exynos_drm_drv.h
··· 214 214 return priv->dma_dev; 215 215 } 216 216 217 + static inline bool is_drm_iommu_supported(struct drm_device *drm_dev) 218 + { 219 + struct exynos_drm_private *priv = drm_dev->dev_private; 220 + 221 + return priv->mapping ? true : false; 222 + } 223 + 224 + int exynos_drm_register_dma(struct drm_device *drm, struct device *dev); 225 + void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev); 226 + void exynos_drm_cleanup_dma(struct drm_device *drm); 227 + 217 228 #ifdef CONFIG_DRM_EXYNOS_DPI 218 229 struct drm_encoder *exynos_dpi_probe(struct device *dev); 219 230 int exynos_dpi_remove(struct drm_encoder *encoder);
-1
drivers/gpu/drm/exynos/exynos_drm_fb.c
··· 24 24 #include "exynos_drm_drv.h" 25 25 #include "exynos_drm_fb.h" 26 26 #include "exynos_drm_fbdev.h" 27 - #include "exynos_drm_iommu.h" 28 27 #include "exynos_drm_crtc.h" 29 28 30 29 static int check_fb_gem_memory_type(struct drm_device *drm_dev,
-1
drivers/gpu/drm/exynos/exynos_drm_fbdev.c
··· 23 23 #include "exynos_drm_drv.h" 24 24 #include "exynos_drm_fb.h" 25 25 #include "exynos_drm_fbdev.h" 26 - #include "exynos_drm_iommu.h" 27 26 28 27 #define MAX_CONNECTOR 4 29 28 #define PREFERRED_BPP 32
+2 -3
drivers/gpu/drm/exynos/exynos_drm_fimc.c
··· 25 25 #include <drm/exynos_drm.h> 26 26 #include "regs-fimc.h" 27 27 #include "exynos_drm_drv.h" 28 - #include "exynos_drm_iommu.h" 29 28 #include "exynos_drm_ipp.h" 30 29 31 30 /* ··· 1128 1129 struct exynos_drm_ipp *ipp = &ctx->ipp; 1129 1130 1130 1131 ctx->drm_dev = drm_dev; 1131 - drm_iommu_attach_device(drm_dev, dev); 1132 + exynos_drm_register_dma(drm_dev, dev); 1132 1133 1133 1134 exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs, 1134 1135 DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE | ··· 1148 1149 struct exynos_drm_ipp *ipp = &ctx->ipp; 1149 1150 1150 1151 exynos_drm_ipp_unregister(drm_dev, ipp); 1151 - drm_iommu_detach_device(drm_dev, dev); 1152 + exynos_drm_unregister_dma(drm_dev, dev); 1152 1153 } 1153 1154 1154 1155 static const struct component_ops fimc_component_ops = {
+2 -3
drivers/gpu/drm/exynos/exynos_drm_fimd.c
··· 32 32 #include "exynos_drm_fb.h" 33 33 #include "exynos_drm_crtc.h" 34 34 #include "exynos_drm_plane.h" 35 - #include "exynos_drm_iommu.h" 36 35 37 36 /* 38 37 * FIMD stands for Fully Interactive Mobile Display and ··· 1010 1011 if (is_drm_iommu_supported(drm_dev)) 1011 1012 fimd_clear_channels(ctx->crtc); 1012 1013 1013 - return drm_iommu_attach_device(drm_dev, dev); 1014 + return exynos_drm_register_dma(drm_dev, dev); 1014 1015 } 1015 1016 1016 1017 static void fimd_unbind(struct device *dev, struct device *master, ··· 1020 1021 1021 1022 fimd_disable(ctx->crtc); 1022 1023 1023 - drm_iommu_detach_device(ctx->drm_dev, ctx->dev); 1024 + exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev); 1024 1025 1025 1026 if (ctx->encoder) 1026 1027 exynos_dpi_remove(ctx->encoder);
+2 -3
drivers/gpu/drm/exynos/exynos_drm_g2d.c
··· 25 25 #include "exynos_drm_drv.h" 26 26 #include "exynos_drm_g2d.h" 27 27 #include "exynos_drm_gem.h" 28 - #include "exynos_drm_iommu.h" 29 28 30 29 #define G2D_HW_MAJOR_VER 4 31 30 #define G2D_HW_MINOR_VER 1 ··· 1404 1405 return ret; 1405 1406 } 1406 1407 1407 - ret = drm_iommu_attach_device(drm_dev, dev); 1408 + ret = exynos_drm_register_dma(drm_dev, dev); 1408 1409 if (ret < 0) { 1409 1410 dev_err(dev, "failed to enable iommu.\n"); 1410 1411 g2d_fini_cmdlist(g2d); ··· 1429 1430 priv->g2d_dev = NULL; 1430 1431 1431 1432 cancel_work_sync(&g2d->runqueue_work); 1432 - drm_iommu_detach_device(g2d->drm_dev, dev); 1433 + exynos_drm_unregister_dma(g2d->drm_dev, dev); 1433 1434 } 1434 1435 1435 1436 static const struct component_ops g2d_component_ops = {
-1
drivers/gpu/drm/exynos/exynos_drm_gem.c
··· 19 19 20 20 #include "exynos_drm_drv.h" 21 21 #include "exynos_drm_gem.h" 22 - #include "exynos_drm_iommu.h" 23 22 24 23 static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem) 25 24 {
+2 -3
drivers/gpu/drm/exynos/exynos_drm_gsc.c
··· 24 24 #include <drm/exynos_drm.h> 25 25 #include "regs-gsc.h" 26 26 #include "exynos_drm_drv.h" 27 - #include "exynos_drm_iommu.h" 28 27 #include "exynos_drm_ipp.h" 29 28 30 29 /* ··· 1169 1170 struct exynos_drm_ipp *ipp = &ctx->ipp; 1170 1171 1171 1172 ctx->drm_dev = drm_dev; 1172 - drm_iommu_attach_device(drm_dev, dev); 1173 + exynos_drm_register_dma(drm_dev, dev); 1173 1174 1174 1175 exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs, 1175 1176 DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE | ··· 1189 1190 struct exynos_drm_ipp *ipp = &ctx->ipp; 1190 1191 1191 1192 exynos_drm_ipp_unregister(drm_dev, ipp); 1192 - drm_iommu_detach_device(drm_dev, dev); 1193 + exynos_drm_unregister_dma(drm_dev, dev); 1193 1194 } 1194 1195 1195 1196 static const struct component_ops gsc_component_ops = {
-111
drivers/gpu/drm/exynos/exynos_drm_iommu.c
··· 1 - /* exynos_drm_iommu.c 2 - * 3 - * Copyright (c) 2012 Samsung Electronics Co., Ltd. 4 - * Author: Inki Dae <inki.dae@samsung.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify it 7 - * under the terms of the GNU General Public License as published by the 8 - * Free Software Foundation; either version 2 of the License, or (at your 9 - * option) any later version. 10 - */ 11 - 12 - #include <drm/drmP.h> 13 - #include <drm/exynos_drm.h> 14 - 15 - #include <linux/dma-mapping.h> 16 - #include <linux/iommu.h> 17 - 18 - #include "exynos_drm_drv.h" 19 - #include "exynos_drm_iommu.h" 20 - 21 - static inline int configure_dma_max_seg_size(struct device *dev) 22 - { 23 - if (!dev->dma_parms) 24 - dev->dma_parms = kzalloc(sizeof(*dev->dma_parms), GFP_KERNEL); 25 - if (!dev->dma_parms) 26 - return -ENOMEM; 27 - 28 - dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); 29 - return 0; 30 - } 31 - 32 - static inline void clear_dma_max_seg_size(struct device *dev) 33 - { 34 - kfree(dev->dma_parms); 35 - dev->dma_parms = NULL; 36 - } 37 - 38 - /* 39 - * drm_create_iommu_mapping - create a mapping structure 40 - * 41 - * @drm_dev: DRM device 42 - */ 43 - int drm_create_iommu_mapping(struct drm_device *drm_dev) 44 - { 45 - struct exynos_drm_private *priv = drm_dev->dev_private; 46 - 47 - return __exynos_iommu_create_mapping(priv, EXYNOS_DEV_ADDR_START, 48 - EXYNOS_DEV_ADDR_SIZE); 49 - } 50 - 51 - /* 52 - * drm_release_iommu_mapping - release iommu mapping structure 53 - * 54 - * @drm_dev: DRM device 55 - */ 56 - void drm_release_iommu_mapping(struct drm_device *drm_dev) 57 - { 58 - struct exynos_drm_private *priv = drm_dev->dev_private; 59 - 60 - __exynos_iommu_release_mapping(priv); 61 - } 62 - 63 - /* 64 - * drm_iommu_attach_device- attach device to iommu mapping 65 - * 66 - * @drm_dev: DRM device 67 - * @subdrv_dev: device to be attach 68 - * 69 - * This function should be called by sub drivers to attach it to iommu 70 - * mapping. 71 - */ 72 - int drm_iommu_attach_device(struct drm_device *drm_dev, 73 - struct device *subdrv_dev) 74 - { 75 - struct exynos_drm_private *priv = drm_dev->dev_private; 76 - int ret; 77 - 78 - if (get_dma_ops(priv->dma_dev) != get_dma_ops(subdrv_dev)) { 79 - DRM_ERROR("Device %s lacks support for IOMMU\n", 80 - dev_name(subdrv_dev)); 81 - return -EINVAL; 82 - } 83 - 84 - ret = configure_dma_max_seg_size(subdrv_dev); 85 - if (ret) 86 - return ret; 87 - 88 - ret = __exynos_iommu_attach(priv, subdrv_dev); 89 - if (ret) 90 - clear_dma_max_seg_size(subdrv_dev); 91 - 92 - return 0; 93 - } 94 - 95 - /* 96 - * drm_iommu_detach_device -detach device address space mapping from device 97 - * 98 - * @drm_dev: DRM device 99 - * @subdrv_dev: device to be detached 100 - * 101 - * This function should be called by sub drivers to detach it from iommu 102 - * mapping 103 - */ 104 - void drm_iommu_detach_device(struct drm_device *drm_dev, 105 - struct device *subdrv_dev) 106 - { 107 - struct exynos_drm_private *priv = drm_dev->dev_private; 108 - 109 - __exynos_iommu_detach(priv, subdrv_dev); 110 - clear_dma_max_seg_size(subdrv_dev); 111 - }
-134
drivers/gpu/drm/exynos/exynos_drm_iommu.h
··· 1 - /* exynos_drm_iommu.h 2 - * 3 - * Copyright (c) 2012 Samsung Electronics Co., Ltd. 4 - * Authoer: Inki Dae <inki.dae@samsung.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify it 7 - * under the terms of the GNU General Public License as published by the 8 - * Free Software Foundation; either version 2 of the License, or (at your 9 - * option) any later version. 10 - */ 11 - 12 - #ifndef _EXYNOS_DRM_IOMMU_H_ 13 - #define _EXYNOS_DRM_IOMMU_H_ 14 - 15 - #define EXYNOS_DEV_ADDR_START 0x20000000 16 - #define EXYNOS_DEV_ADDR_SIZE 0x40000000 17 - 18 - #ifdef CONFIG_DRM_EXYNOS_IOMMU 19 - 20 - #if defined(CONFIG_ARM_DMA_USE_IOMMU) 21 - #include <asm/dma-iommu.h> 22 - 23 - static inline int __exynos_iommu_create_mapping(struct exynos_drm_private *priv, 24 - unsigned long start, unsigned long size) 25 - { 26 - priv->mapping = arm_iommu_create_mapping(&platform_bus_type, start, 27 - size); 28 - return IS_ERR(priv->mapping); 29 - } 30 - 31 - static inline void 32 - __exynos_iommu_release_mapping(struct exynos_drm_private *priv) 33 - { 34 - arm_iommu_release_mapping(priv->mapping); 35 - } 36 - 37 - static inline int __exynos_iommu_attach(struct exynos_drm_private *priv, 38 - struct device *dev) 39 - { 40 - if (dev->archdata.mapping) 41 - arm_iommu_detach_device(dev); 42 - 43 - return arm_iommu_attach_device(dev, priv->mapping); 44 - } 45 - 46 - static inline void __exynos_iommu_detach(struct exynos_drm_private *priv, 47 - struct device *dev) 48 - { 49 - arm_iommu_detach_device(dev); 50 - } 51 - 52 - #elif defined(CONFIG_IOMMU_DMA) 53 - #include <linux/dma-iommu.h> 54 - 55 - static inline int __exynos_iommu_create_mapping(struct exynos_drm_private *priv, 56 - unsigned long start, unsigned long size) 57 - { 58 - priv->mapping = iommu_get_domain_for_dev(priv->dma_dev); 59 - return 0; 60 - } 61 - 62 - static inline void __exynos_iommu_release_mapping(struct exynos_drm_private *priv) 63 - { 64 - priv->mapping = NULL; 65 - } 66 - 67 - static inline int __exynos_iommu_attach(struct exynos_drm_private *priv, 68 - struct device *dev) 69 - { 70 - struct iommu_domain *domain = priv->mapping; 71 - 72 - if (dev != priv->dma_dev) 73 - return iommu_attach_device(domain, dev); 74 - return 0; 75 - } 76 - 77 - static inline void __exynos_iommu_detach(struct exynos_drm_private *priv, 78 - struct device *dev) 79 - { 80 - struct iommu_domain *domain = priv->mapping; 81 - 82 - if (dev != priv->dma_dev) 83 - iommu_detach_device(domain, dev); 84 - } 85 - #else 86 - #error Unsupported architecture and IOMMU/DMA-mapping glue code 87 - #endif 88 - 89 - int drm_create_iommu_mapping(struct drm_device *drm_dev); 90 - 91 - void drm_release_iommu_mapping(struct drm_device *drm_dev); 92 - 93 - int drm_iommu_attach_device(struct drm_device *drm_dev, 94 - struct device *subdrv_dev); 95 - 96 - void drm_iommu_detach_device(struct drm_device *dev_dev, 97 - struct device *subdrv_dev); 98 - 99 - static inline bool is_drm_iommu_supported(struct drm_device *drm_dev) 100 - { 101 - struct exynos_drm_private *priv = drm_dev->dev_private; 102 - 103 - return priv->mapping ? true : false; 104 - } 105 - 106 - #else 107 - 108 - static inline int drm_create_iommu_mapping(struct drm_device *drm_dev) 109 - { 110 - return 0; 111 - } 112 - 113 - static inline void drm_release_iommu_mapping(struct drm_device *drm_dev) 114 - { 115 - } 116 - 117 - static inline int drm_iommu_attach_device(struct drm_device *drm_dev, 118 - struct device *subdrv_dev) 119 - { 120 - return 0; 121 - } 122 - 123 - static inline void drm_iommu_detach_device(struct drm_device *drm_dev, 124 - struct device *subdrv_dev) 125 - { 126 - } 127 - 128 - static inline bool is_drm_iommu_supported(struct drm_device *drm_dev) 129 - { 130 - return false; 131 - } 132 - 133 - #endif 134 - #endif
+2 -3
drivers/gpu/drm/exynos/exynos_drm_rotator.c
··· 23 23 #include <drm/exynos_drm.h> 24 24 #include "regs-rotator.h" 25 25 #include "exynos_drm_drv.h" 26 - #include "exynos_drm_iommu.h" 27 26 #include "exynos_drm_ipp.h" 28 27 29 28 /* ··· 243 244 struct exynos_drm_ipp *ipp = &rot->ipp; 244 245 245 246 rot->drm_dev = drm_dev; 246 - drm_iommu_attach_device(drm_dev, dev); 247 + exynos_drm_register_dma(drm_dev, dev); 247 248 248 249 exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs, 249 250 DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE, ··· 262 263 struct exynos_drm_ipp *ipp = &rot->ipp; 263 264 264 265 exynos_drm_ipp_unregister(drm_dev, ipp); 265 - drm_iommu_detach_device(rot->drm_dev, rot->dev); 266 + exynos_drm_unregister_dma(rot->drm_dev, rot->dev); 266 267 } 267 268 268 269 static const struct component_ops rotator_component_ops = {
+2 -3
drivers/gpu/drm/exynos/exynos_drm_scaler.c
··· 23 23 #include "regs-scaler.h" 24 24 #include "exynos_drm_fb.h" 25 25 #include "exynos_drm_drv.h" 26 - #include "exynos_drm_iommu.h" 27 26 #include "exynos_drm_ipp.h" 28 27 29 28 #define scaler_read(offset) readl(scaler->regs + (offset)) ··· 451 452 struct exynos_drm_ipp *ipp = &scaler->ipp; 452 453 453 454 scaler->drm_dev = drm_dev; 454 - drm_iommu_attach_device(drm_dev, dev); 455 + exynos_drm_register_dma(drm_dev, dev); 455 456 456 457 exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs, 457 458 DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE | ··· 472 473 struct exynos_drm_ipp *ipp = &scaler->ipp; 473 474 474 475 exynos_drm_ipp_unregister(drm_dev, ipp); 475 - drm_iommu_detach_device(scaler->drm_dev, scaler->dev); 476 + exynos_drm_unregister_dma(scaler->drm_dev, scaler->dev); 476 477 } 477 478 478 479 static const struct component_ops scaler_component_ops = {
+15 -15
drivers/gpu/drm/exynos/exynos_mixer.c
··· 40 40 #include "exynos_drm_crtc.h" 41 41 #include "exynos_drm_fb.h" 42 42 #include "exynos_drm_plane.h" 43 - #include "exynos_drm_iommu.h" 44 43 45 44 #define MIXER_WIN_NR 3 46 45 #define VP_DEFAULT_WIN 2 ··· 380 381 mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_SCAN_MASK); 381 382 } 382 383 383 - static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height) 384 + static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, struct drm_display_mode *mode) 384 385 { 386 + enum hdmi_quantization_range range = drm_default_rgb_quant_range(mode); 385 387 u32 val; 386 388 387 - switch (height) { 388 - case 480: 389 - case 576: 390 - val = MXR_CFG_RGB601_0_255; 391 - break; 392 - case 720: 393 - case 1080: 394 - default: 395 - val = MXR_CFG_RGB709_16_235; 389 + if (mode->vdisplay < 720) { 390 + val = MXR_CFG_RGB601; 391 + } else { 392 + val = MXR_CFG_RGB709; 393 + 396 394 /* Configure the BT.709 CSC matrix for full range RGB. */ 397 395 mixer_reg_write(ctx, MXR_CM_COEFF_Y, 398 396 MXR_CSC_CT( 0.184, 0.614, 0.063) | ··· 398 402 MXR_CSC_CT(-0.102, -0.338, 0.440)); 399 403 mixer_reg_write(ctx, MXR_CM_COEFF_CR, 400 404 MXR_CSC_CT( 0.440, -0.399, -0.040)); 401 - break; 402 405 } 406 + 407 + if (range == HDMI_QUANTIZATION_RANGE_FULL) 408 + val |= MXR_CFG_QUANT_RANGE_FULL; 409 + else 410 + val |= MXR_CFG_QUANT_RANGE_LIMITED; 403 411 404 412 mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK); 405 413 } ··· 461 461 struct drm_display_mode *mode = &ctx->crtc->base.state->adjusted_mode; 462 462 463 463 mixer_cfg_scan(ctx, mode->hdisplay, mode->vdisplay); 464 - mixer_cfg_rgb_fmt(ctx, mode->vdisplay); 464 + mixer_cfg_rgb_fmt(ctx, mode); 465 465 mixer_run(ctx); 466 466 } 467 467 ··· 878 878 } 879 879 } 880 880 881 - return drm_iommu_attach_device(drm_dev, mixer_ctx->dev); 881 + return exynos_drm_register_dma(drm_dev, mixer_ctx->dev); 882 882 } 883 883 884 884 static void mixer_ctx_remove(struct mixer_context *mixer_ctx) 885 885 { 886 - drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev); 886 + exynos_drm_unregister_dma(mixer_ctx->drm_dev, mixer_ctx->dev); 887 887 } 888 888 889 889 static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)
+22
drivers/gpu/drm/exynos/regs-decon5433.h
··· 104 104 #define WINCONx_BURSTLEN_16WORD (0x0 << 10) 105 105 #define WINCONx_BURSTLEN_8WORD (0x1 << 10) 106 106 #define WINCONx_BURSTLEN_4WORD (0x2 << 10) 107 + #define WINCONx_ALPHA_MUL_F (1 << 7) 107 108 #define WINCONx_BLD_PIX_F (1 << 6) 108 109 #define WINCONx_BPPMODE_MASK (0xf << 2) 109 110 #define WINCONx_BPPMODE_16BPP_565 (0x5 << 2) ··· 117 116 #define WINCONx_BPPMODE_16BPP_A4444 (0xe << 2) 118 117 #define WINCONx_ALPHA_SEL_F (1 << 1) 119 118 #define WINCONx_ENWIN_F (1 << 0) 119 + #define WINCONx_BLEND_MODE_MASK (0xc2) 120 120 121 121 /* SHADOWCON */ 122 122 #define SHADOWCON_PROTECT_MASK GENMASK(14, 10) 123 123 #define SHADOWCON_Wx_PROTECT(n) (1 << (10 + (n))) 124 + 125 + /* VIDOSDxC */ 126 + #define VIDOSDxC_ALPHA0_RGB_MASK (0xffffff) 124 127 125 128 /* VIDOSDxD */ 126 129 #define VIDOSD_Wx_ALPHA_R_F(n) (((n) & 0xff) << 16) ··· 210 205 #define CRCCTRL_CRCSTART_F (0x1 << 1) 211 206 #define CRCCTRL_CRCEN (0x1 << 0) 212 207 #define CRCCTRL_MASK (0x7) 208 + 209 + /* BLENDCON */ 210 + #define BLEND_NEW (1 << 0) 211 + 212 + /* BLENDERQx */ 213 + #define BLENDERQ_ZERO 0x0 214 + #define BLENDERQ_ONE 0x1 215 + #define BLENDERQ_ALPHA_A 0x2 216 + #define BLENDERQ_ONE_MINUS_ALPHA_A 0x3 217 + #define BLENDERQ_ALPHA0 0x6 218 + #define BLENDERQ_Q_FUNC_F(n) (n << 18) 219 + #define BLENDERQ_P_FUNC_F(n) (n << 12) 220 + #define BLENDERQ_B_FUNC_F(n) (n << 6) 221 + #define BLENDERQ_A_FUNC_F(n) (n << 0) 222 + 223 + /* BLENDCON */ 224 + #define BLEND_NEW (1 << 0) 213 225 214 226 #endif /* EXYNOS_REGS_DECON5433_H */
+5 -4
drivers/gpu/drm/exynos/regs-mixer.h
··· 85 85 /* bits for MXR_CFG */ 86 86 #define MXR_CFG_LAYER_UPDATE (1 << 31) 87 87 #define MXR_CFG_LAYER_UPDATE_COUNT_MASK (3 << 29) 88 - #define MXR_CFG_RGB601_0_255 (0 << 9) 89 - #define MXR_CFG_RGB601_16_235 (1 << 9) 90 - #define MXR_CFG_RGB709_0_255 (2 << 9) 91 - #define MXR_CFG_RGB709_16_235 (3 << 9) 88 + #define MXR_CFG_QUANT_RANGE_FULL (0 << 9) 89 + #define MXR_CFG_QUANT_RANGE_LIMITED (1 << 9) 90 + #define MXR_CFG_RGB601 (0 << 10) 91 + #define MXR_CFG_RGB709 (1 << 10) 92 + 92 93 #define MXR_CFG_RGB_FMT_MASK 0x600 93 94 #define MXR_CFG_OUT_YUV444 (0 << 8) 94 95 #define MXR_CFG_OUT_RGB888 (1 << 8)