.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2012 Samsung Electronics Co.Ltd |
---|
3 | 4 | * Authors: |
---|
4 | 5 | * YoungJun Cho <yj44.cho@samsung.com> |
---|
5 | 6 | * Eunchul Kim <chulspro.kim@samsung.com> |
---|
6 | | - * |
---|
7 | | - * This program is free software; you can redistribute it and/or modify |
---|
8 | | - * it under the terms of the GNU General Public License version 2 as |
---|
9 | | - * published by the Free Software Foundationr |
---|
10 | 7 | */ |
---|
11 | 8 | |
---|
12 | | -#include <linux/kernel.h> |
---|
| 9 | +#include <linux/clk.h> |
---|
13 | 10 | #include <linux/component.h> |
---|
14 | 11 | #include <linux/err.h> |
---|
15 | 12 | #include <linux/interrupt.h> |
---|
16 | 13 | #include <linux/io.h> |
---|
17 | | -#include <linux/platform_device.h> |
---|
18 | | -#include <linux/clk.h> |
---|
| 14 | +#include <linux/kernel.h> |
---|
19 | 15 | #include <linux/of_device.h> |
---|
| 16 | +#include <linux/platform_device.h> |
---|
20 | 17 | #include <linux/pm_runtime.h> |
---|
| 18 | +#include <linux/sizes.h> |
---|
21 | 19 | |
---|
22 | | -#include <drm/drmP.h> |
---|
| 20 | +#include <drm/drm_fourcc.h> |
---|
23 | 21 | #include <drm/exynos_drm.h> |
---|
24 | | -#include "regs-rotator.h" |
---|
| 22 | + |
---|
25 | 23 | #include "exynos_drm_drv.h" |
---|
26 | | -#include "exynos_drm_iommu.h" |
---|
27 | 24 | #include "exynos_drm_ipp.h" |
---|
| 25 | +#include "regs-rotator.h" |
---|
28 | 26 | |
---|
29 | 27 | /* |
---|
30 | 28 | * Rotator supports image crop/rotator and input/output DMA operations. |
---|
.. | .. |
---|
58 | 56 | struct rot_context { |
---|
59 | 57 | struct exynos_drm_ipp ipp; |
---|
60 | 58 | struct drm_device *drm_dev; |
---|
| 59 | + void *dma_priv; |
---|
61 | 60 | struct device *dev; |
---|
62 | 61 | void __iomem *regs; |
---|
63 | 62 | struct clk *clock; |
---|
.. | .. |
---|
244 | 243 | struct exynos_drm_ipp *ipp = &rot->ipp; |
---|
245 | 244 | |
---|
246 | 245 | rot->drm_dev = drm_dev; |
---|
247 | | - drm_iommu_attach_device(drm_dev, dev); |
---|
| 246 | + ipp->drm_dev = drm_dev; |
---|
| 247 | + exynos_drm_register_dma(drm_dev, dev, &rot->dma_priv); |
---|
248 | 248 | |
---|
249 | | - exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs, |
---|
| 249 | + exynos_drm_ipp_register(dev, ipp, &ipp_funcs, |
---|
250 | 250 | DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE, |
---|
251 | 251 | rot->formats, rot->num_formats, "rotator"); |
---|
252 | 252 | |
---|
.. | .. |
---|
259 | 259 | void *data) |
---|
260 | 260 | { |
---|
261 | 261 | struct rot_context *rot = dev_get_drvdata(dev); |
---|
262 | | - struct drm_device *drm_dev = data; |
---|
263 | 262 | struct exynos_drm_ipp *ipp = &rot->ipp; |
---|
264 | 263 | |
---|
265 | | - exynos_drm_ipp_unregister(drm_dev, ipp); |
---|
266 | | - drm_iommu_detach_device(rot->drm_dev, rot->dev); |
---|
| 264 | + exynos_drm_ipp_unregister(dev, ipp); |
---|
| 265 | + exynos_drm_unregister_dma(rot->drm_dev, rot->dev, &rot->dma_priv); |
---|
267 | 266 | } |
---|
268 | 267 | |
---|
269 | 268 | static const struct component_ops rotator_component_ops = { |
---|
.. | .. |
---|
294 | 293 | return PTR_ERR(rot->regs); |
---|
295 | 294 | |
---|
296 | 295 | irq = platform_get_irq(pdev, 0); |
---|
297 | | - if (irq < 0) { |
---|
298 | | - dev_err(dev, "failed to get irq\n"); |
---|
| 296 | + if (irq < 0) |
---|
299 | 297 | return irq; |
---|
300 | | - } |
---|
301 | 298 | |
---|
302 | 299 | ret = devm_request_irq(dev, irq, rotator_irq_handler, 0, dev_name(dev), |
---|
303 | 300 | rot); |
---|
.. | .. |
---|
357 | 354 | } |
---|
358 | 355 | #endif |
---|
359 | 356 | |
---|
| 357 | +static const struct drm_exynos_ipp_limit rotator_s5pv210_rbg888_limits[] = { |
---|
| 358 | + { IPP_SIZE_LIMIT(BUFFER, .h = { 8, SZ_16K }, .v = { 8, SZ_16K }) }, |
---|
| 359 | + { IPP_SIZE_LIMIT(AREA, .h.align = 2, .v.align = 2) }, |
---|
| 360 | +}; |
---|
| 361 | + |
---|
360 | 362 | static const struct drm_exynos_ipp_limit rotator_4210_rbg888_limits[] = { |
---|
361 | 363 | { IPP_SIZE_LIMIT(BUFFER, .h = { 8, SZ_16K }, .v = { 8, SZ_16K }) }, |
---|
362 | 364 | { IPP_SIZE_LIMIT(AREA, .h.align = 4, .v.align = 4) }, |
---|
.. | .. |
---|
372 | 374 | { IPP_SIZE_LIMIT(AREA, .h.align = 2, .v.align = 2) }, |
---|
373 | 375 | }; |
---|
374 | 376 | |
---|
| 377 | +static const struct drm_exynos_ipp_limit rotator_s5pv210_yuv_limits[] = { |
---|
| 378 | + { IPP_SIZE_LIMIT(BUFFER, .h = { 32, SZ_64K }, .v = { 32, SZ_64K }) }, |
---|
| 379 | + { IPP_SIZE_LIMIT(AREA, .h.align = 8, .v.align = 8) }, |
---|
| 380 | +}; |
---|
| 381 | + |
---|
375 | 382 | static const struct drm_exynos_ipp_limit rotator_4210_yuv_limits[] = { |
---|
376 | 383 | { IPP_SIZE_LIMIT(BUFFER, .h = { 32, SZ_64K }, .v = { 32, SZ_64K }) }, |
---|
377 | 384 | { IPP_SIZE_LIMIT(AREA, .h.align = 8, .v.align = 8) }, |
---|
.. | .. |
---|
380 | 387 | static const struct drm_exynos_ipp_limit rotator_4412_yuv_limits[] = { |
---|
381 | 388 | { IPP_SIZE_LIMIT(BUFFER, .h = { 32, SZ_32K }, .v = { 32, SZ_32K }) }, |
---|
382 | 389 | { IPP_SIZE_LIMIT(AREA, .h.align = 8, .v.align = 8) }, |
---|
| 390 | +}; |
---|
| 391 | + |
---|
| 392 | +static const struct exynos_drm_ipp_formats rotator_s5pv210_formats[] = { |
---|
| 393 | + { IPP_SRCDST_FORMAT(XRGB8888, rotator_s5pv210_rbg888_limits) }, |
---|
| 394 | + { IPP_SRCDST_FORMAT(NV12, rotator_s5pv210_yuv_limits) }, |
---|
383 | 395 | }; |
---|
384 | 396 | |
---|
385 | 397 | static const struct exynos_drm_ipp_formats rotator_4210_formats[] = { |
---|
.. | .. |
---|
395 | 407 | static const struct exynos_drm_ipp_formats rotator_5250_formats[] = { |
---|
396 | 408 | { IPP_SRCDST_FORMAT(XRGB8888, rotator_5250_rbg888_limits) }, |
---|
397 | 409 | { IPP_SRCDST_FORMAT(NV12, rotator_4412_yuv_limits) }, |
---|
| 410 | +}; |
---|
| 411 | + |
---|
| 412 | +static const struct rot_variant rotator_s5pv210_data = { |
---|
| 413 | + .formats = rotator_s5pv210_formats, |
---|
| 414 | + .num_formats = ARRAY_SIZE(rotator_s5pv210_formats), |
---|
398 | 415 | }; |
---|
399 | 416 | |
---|
400 | 417 | static const struct rot_variant rotator_4210_data = { |
---|
.. | .. |
---|
414 | 431 | |
---|
415 | 432 | static const struct of_device_id exynos_rotator_match[] = { |
---|
416 | 433 | { |
---|
| 434 | + .compatible = "samsung,s5pv210-rotator", |
---|
| 435 | + .data = &rotator_s5pv210_data, |
---|
| 436 | + }, { |
---|
417 | 437 | .compatible = "samsung,exynos4210-rotator", |
---|
418 | 438 | .data = &rotator_4210_data, |
---|
419 | 439 | }, { |
---|