All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem
@ 2015-11-10 13:23 Marek Szyprowski
  2015-11-10 13:23 ` [PATCH 01/25] ARM: dts: exynos4: add rotator nodes Marek Szyprowski
                   ` (27 more replies)
  0 siblings, 28 replies; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

Dear All,

This patch series introduces a new life into Exynos IPP (Image Post
Processing) subsystem by integrating it (transparently for userspace
applications) with Exynos DRM core plane management. This means that all
CRTC drivers transparently get support for standard features of IPP
subsystem like rotation and scaling.

Support for features not supported natively by CRTC drivers is
implemented with a help of temporary framebuffers, where image data is
processed by IPP subsystem before performing the scanout by a CRTC driver.

This patchset is a first version of this 'new feature' and I would like
get some comments on the proposed approach. I plan to continue working
on enhancing Exynos DRM drivers and especially do the cleanup the IPP
subsystem.

Most of the new features are added by the last 2 patches. All other
patches are bugfixes in various Exynos DRM subdrivers and significant
core rewrite - introducing a subclass of drm_plane_state was needed and
all drivers have been converted to use it. Some initial cleanups in IPP
subsystem were also needed to let Exynos core to call it internally from
the driver core. This part will be cleaned even more in the future.


My solution has been tested on Exynos4412-based Odroid U3 and
Exynos5420-based Odroid XU3. To check rotation, cropping and scaling
I've developed a simple test application, which use atomic mode
setting/page flipping API. You can download it here:

https://git.linaro.org/?p=people/marek.szyprowski/atomictest.git

The application draws a rectangle with test pattern and then moves it
around the screen. To see how all mentioned features work (plane
rotation, cropping, scaling and off-screen display), please run the
following commands:

scaling + rotation:
# ./atomictest -b400x300 -f60 -t100 -m2x1 -x1x1

cropping + rotation:
# ./atomictest -b400x300 -f60 -t100 -m2x1 -c1x1

cropping + rotation + off-screen display:
# ./atomictest -b400x300 -f60 -t100 -m2x1 -c1x1 -o400x300

scaling + cropping + rotation:
# ./atomictest -b400x300 -f60 -t100 -m2x1 -x1x1 -c1x1 

For more information about parameters, run the application with -h
parameter or check the source code.


My TODO list (please comment the priority of those tasks):

1. add support for color space conversion, support for foreign pixel
formats and fb-modifiers to my plane-IPP integration code (currently
only RGB single plane modes are supported)

2. provide support for IPP features (framebuffer rotation, scaling,
cropping, color space conversion) with userspace atomic API instead of
(or together with) Exynos custom IPP ioctls; the important question is
weather the existing Exynos IPP API (userspace ioctls) should be kept or
can be removed (existing userspace API is misleading in many aspects).

3. simplify IPP subsystem core (the code looks over-engineered a bit,
there are also some known issues with error paths), remove
non-functional write-back and output modes

4. simplify interface to IPP HW-specific mem2mem subdrivers

5. implement output mode for IPP sub-drivers, use it where possible
instead of using temporary framebuffer (image data is then transferred
directly from scaling hw block to display engine via local path, no
temporary framebuffers are needed)

6. implement write-back feature with atomic API as respective CRTC
properties


Patches have been prepared on top of linux-next from 10-11-2015. First
2 patches should be applied to Samsung SoC tree, all other should go
to Exynos DRM tree.

Best regards
Marek Szyprowski
Samsung R&D Institute Poland


Patch summary:

Marek Szyprowski (21):
  ARM: dts: exynos4: add rotator nodes
  ARM: dts: exynos542x: add rotator node
  drm/exynos: gsc: add device tree support and remove usage of static
    mappings
  drm/exynos: rotator: convert to common clock framework
  drm/exynos: exynos7-decon: remove excessive check
  drm/exynos: move dma_addr attribute from exynos plane to exynos fb
  drm/exynos: introduce exynos_drm_plane_state structure
  drm/exynos: mixer: use crtc->state->adjusted_mode instead of
    crtc->mode
  drm/exynos: mixer: enable video overlay plane only when VP is
    available
  drm/exynos: introduce exynos_drm_plane_config structure
  drm/exynos: add generic check for plane state
  drm/exynos: mixer: use ratio precalculated in exynos_state
  drm/exynos: fix clipping when scalling is enabled
  drm/exynos: fimd: fix dma burst size setting for small plane size
  drm/exynos: add fb pointer to exynos_drm_plane_state
  drm/exynos: gem: set default alignment for dumb GEM buffers
  drm/exynos: gem: remove old unused prototypes
  drm/exynos: gem: simplify access to exynos gem object
  drm/exynos: ipp: make framework context global
  drm/exynos: add generic plane rotation property support
  drm/exynos: add support for plane scaling

Seung-Woo Kim (4):
  drm/exynos: gsc: prepare and unprepare gsc clock
  drm/exynos: gsc: fix wrong pm_runtime state
  drm/exynos: fix to calculate offset of each plane for ipp fimc
  drm/exynos: fix to calculate offset of each plane for ipp gsc

 .../devicetree/bindings/media/exynos5-gsc.txt      |   4 +
 arch/arm/boot/dts/exynos4.dtsi                     |  10 +-
 arch/arm/boot/dts/exynos4210.dtsi                  |   8 +
 arch/arm/boot/dts/exynos4x12.dtsi                  |   4 +
 arch/arm/boot/dts/exynos5420.dtsi                  |  19 ++
 drivers/gpu/drm/exynos/Kconfig                     |  10 +-
 drivers/gpu/drm/exynos/Makefile                    |   1 +
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c      |  48 ++--
 drivers/gpu/drm/exynos/exynos7_drm_decon.c         |  68 ++---
 drivers/gpu/drm/exynos/exynos_drm_drv.h            |  97 +++++--
 drivers/gpu/drm/exynos/exynos_drm_fb.c             |  16 +-
 drivers/gpu/drm/exynos/exynos_drm_fb.h             |   3 +-
 drivers/gpu/drm/exynos/exynos_drm_fimc.c           | 106 ++++++++
 drivers/gpu/drm/exynos/exynos_drm_fimd.c           |  88 ++++---
 drivers/gpu/drm/exynos/exynos_drm_g2d.c            |  48 ++--
 drivers/gpu/drm/exynos/exynos_drm_gem.c            |  54 +---
 drivers/gpu/drm/exynos/exynos_drm_gem.h            |  51 +---
 drivers/gpu/drm/exynos/exynos_drm_gsc.c            | 151 ++++++++++-
 drivers/gpu/drm/exynos/exynos_drm_ipp.c            | 237 +++++++++++++----
 drivers/gpu/drm/exynos/exynos_drm_ipp.h            |   8 +-
 drivers/gpu/drm/exynos/exynos_drm_plane.c          | 255 +++++++++++++------
 drivers/gpu/drm/exynos/exynos_drm_plane.h          |   7 +-
 drivers/gpu/drm/exynos/exynos_drm_plane_ipp.c      | 281 +++++++++++++++++++++
 drivers/gpu/drm/exynos/exynos_drm_plane_ipp.h      |  73 ++++++
 drivers/gpu/drm/exynos/exynos_drm_rotator.c        |   4 +-
 drivers/gpu/drm/exynos/exynos_drm_vidi.c           |  30 ++-
 drivers/gpu/drm/exynos/exynos_mixer.c              | 133 +++++-----
 drivers/gpu/drm/exynos/regs-gsc.h                  |   4 +-
 28 files changed, 1348 insertions(+), 470 deletions(-)
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_plane_ipp.c
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_plane_ipp.h

-- 
1.9.2

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH 01/25] ARM: dts: exynos4: add rotator nodes
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-13  2:23   ` Krzysztof Kozlowski
  2015-11-13  2:29   ` [PATCH 01/25] " Krzysztof Kozlowski
  2015-11-10 13:23 ` [PATCH 02/25] ARM: dts: exynos542x: add rotator node Marek Szyprowski
                   ` (26 subsequent siblings)
  27 siblings, 2 replies; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Javier Martinez Canillas, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, Andrzej Hajda,
	Tobias Jakobi, Marek Szyprowski

This patch adds device node for Rotator device to Exynos 4210 and 4x12
device tree files.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos4.dtsi    | 10 +++++++++-
 arch/arm/boot/dts/exynos4210.dtsi |  8 ++++++++
 arch/arm/boot/dts/exynos4x12.dtsi |  4 ++++
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 2f31f773b096..3fa575ad7693 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -718,6 +718,15 @@
 		iommus = <&sysmmu_jpeg>;
 	};
 
+	rotator: rotator@12810000 {
+		compatible = "samsung,exynos4210-rotator";
+		reg = <0x12810000 0x1000>;
+		interrupts = <0 83 0>;
+		clocks = <&clock CLK_ROTATOR>;
+		clock-names = "rotator";
+		iommus = <&sysmmu_rotator>;
+	};
+
 	hdmi: hdmi@12D00000 {
 		compatible = "samsung,exynos4210-hdmi";
 		reg = <0x12D00000 0x70000>;
@@ -945,7 +954,6 @@
 		interrupts = <5 0>;
 		clock-names = "sysmmu", "master";
 		clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
-		power-domains = <&pd_lcd0>;
 		#iommu-cells = <0>;
 	};
 
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 3e5ba665d200..b7474cf27e82 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -279,3 +279,11 @@
 		<&clock CLK_OUT_CPU>, <&clock CLK_XXTI>, <&clock CLK_XUSBXTI>;
 	#clock-cells = <1>;
 };
+
+&rotator {
+	power-domains = <&pd_lcd0>;
+};
+
+&sysmmu_rotator {
+	power-domains = <&pd_lcd0>;
+};
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index b77dac61ffb5..148b47ad3120 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -339,6 +339,10 @@
 	compatible = "samsung,exynos4212-jpeg";
 };
 
+&rotator {
+	compatible = "samsung,exynos4212-rotator";
+};
+
 &mixer {
 	compatible = "samsung,exynos4212-mixer";
 	clock-names = "mixer", "hdmi", "sclk_hdmi", "vp";
-- 
1.9.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 02/25] ARM: dts: exynos542x: add rotator node
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
  2015-11-10 13:23 ` [PATCH 01/25] ARM: dts: exynos4: add rotator nodes Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-13  2:28   ` Krzysztof Kozlowski
  2015-11-10 13:23 ` [PATCH 03/25] drm/exynos: gsc: prepare and unprepare gsc clock Marek Szyprowski
                   ` (25 subsequent siblings)
  27 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Javier Martinez Canillas, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, Andrzej Hajda,
	Tobias Jakobi, Marek Szyprowski

This patch adds device node for Rotator device to Exynos 542x device
tree file.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos5420.dtsi | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index 1b3d6c769a3c..48a0a55314f5 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -717,6 +717,15 @@
 		iommus = <&sysmmu_tv>;
 	};
 
+	rotator: rotator@11C00000 {
+		compatible = "samsung,exynos5250-rotator";
+		reg = <0x11C00000 0x64>;
+		interrupts = <0 84 0>;
+		clocks = <&clock CLK_ROTATOR>;
+		clock-names = "rotator";
+		iommus = <&sysmmu_rotator>;
+	};
+
 	gsc_0: video-scaler@13e00000 {
 		compatible = "samsung,exynos5-gsc";
 		reg = <0x13e00000 0x1000>;
@@ -1059,6 +1068,16 @@
 		#iommu-cells = <0>;
 	};
 
+	sysmmu_rotator: sysmmu@0x11D40000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11D40000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 0>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
+		#iommu-cells = <0>;
+	};
+
 	sysmmu_jpeg0: sysmmu@0x11F10000 {
 		compatible = "samsung,exynos-sysmmu";
 		reg = <0x11F10000 0x1000>;
-- 
1.9.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 03/25] drm/exynos: gsc: prepare and unprepare gsc clock
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
  2015-11-10 13:23 ` [PATCH 01/25] ARM: dts: exynos4: add rotator nodes Marek Szyprowski
  2015-11-10 13:23 ` [PATCH 02/25] ARM: dts: exynos542x: add rotator node Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-12 15:11   ` Gustavo Padovan
  2015-11-10 13:23 ` [PATCH 04/25] drm/exynos: gsc: fix wrong pm_runtime state Marek Szyprowski
                   ` (24 subsequent siblings)
  27 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

From: Seung-Woo Kim <sw0312.kim@samsung.com>

Ths patch changes the clk_enable and clk_disable call in gsc driver
into clk_prepare_enable and clk_disable_unprepare.

Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_gsc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
index 11b87d2a7913..72a9c84e06b6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
@@ -1215,10 +1215,10 @@ static int gsc_clk_ctrl(struct gsc_context *ctx, bool enable)
 	DRM_DEBUG_KMS("enable[%d]\n", enable);
 
 	if (enable) {
-		clk_enable(ctx->gsc_clk);
+		clk_prepare_enable(ctx->gsc_clk);
 		ctx->suspended = false;
 	} else {
-		clk_disable(ctx->gsc_clk);
+		clk_disable_unprepare(ctx->gsc_clk);
 		ctx->suspended = true;
 	}
 
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 04/25] drm/exynos: gsc: fix wrong pm_runtime state
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (2 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 03/25] drm/exynos: gsc: prepare and unprepare gsc clock Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-12 15:12   ` Gustavo Padovan
  2015-11-10 13:23 ` [PATCH 05/25] drm/exynos: gsc: add device tree support and remove usage of static mappings Marek Szyprowski
                   ` (23 subsequent siblings)
  27 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

From: Seung-Woo Kim <sw0312.kim@samsung.com>

At probe time, gsc clock is not enabled, so pm_runtime state should
be deactive. So this patch removes pm_runtime_set_active() from
gsc_probe().

Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_gsc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
index 72a9c84e06b6..ed55d37b6330 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
@@ -1713,7 +1713,6 @@ static int gsc_probe(struct platform_device *pdev)
 	mutex_init(&ctx->lock);
 	platform_set_drvdata(pdev, ctx);
 
-	pm_runtime_set_active(dev);
 	pm_runtime_enable(dev);
 
 	ret = exynos_drm_ippdrv_register(ippdrv);
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 05/25] drm/exynos: gsc: add device tree support and remove usage of static mappings
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (3 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 04/25] drm/exynos: gsc: fix wrong pm_runtime state Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-10 13:23 ` [PATCH 06/25] drm/exynos: fix to calculate offset of each plane for ipp fimc Marek Szyprowski
                   ` (22 subsequent siblings)
  27 siblings, 0 replies; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Javier Martinez Canillas, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, Andrzej Hajda,
	Tobias Jakobi, Marek Szyprowski

This patch adds device tree support for exynos_drm_gsc. This patch
also fixed build issue on non-Exynos platforms, thus dependency on
!ARCH_MULTIPLATFORM can be now removed. The driver cannot be used
simultaneously with V4L2 Mem2Mem GScaller driver thought.

Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
[updated commit message, removed the need for wb-lcd property, because
all gscallers have support for lcd writeback, replaced dependency on
!ARCH_MULTIPLATFORM with !VIDEO_SAMSUNG_EXYNOS_GSC]
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 .../devicetree/bindings/media/exynos5-gsc.txt      |  4 +++
 drivers/gpu/drm/exynos/Kconfig                     |  2 +-
 drivers/gpu/drm/exynos/exynos_drm_gsc.c            | 30 +++++++++++++++++++---
 drivers/gpu/drm/exynos/regs-gsc.h                  |  4 +--
 4 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/exynos5-gsc.txt b/Documentation/devicetree/bindings/media/exynos5-gsc.txt
index 0604d42f38d1..5fe9372abb37 100644
--- a/Documentation/devicetree/bindings/media/exynos5-gsc.txt
+++ b/Documentation/devicetree/bindings/media/exynos5-gsc.txt
@@ -7,6 +7,10 @@ Required properties:
 - reg: should contain G-Scaler physical address location and length.
 - interrupts: should contain G-Scaler interrupt number
 
+Optional properties:
+- samsung,sysreg: handle to syscon used to control the system registers to
+  set writeback input and destination
+
 Example:
 
 gsc_0:  gsc@0x13e00000 {
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 96e86cf4455b..83efca941388 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -118,7 +118,7 @@ config DRM_EXYNOS_ROTATOR
 
 config DRM_EXYNOS_GSC
 	bool "GScaler"
-	depends on DRM_EXYNOS_IPP && ARCH_EXYNOS5 && !ARCH_MULTIPLATFORM
+	depends on DRM_EXYNOS_IPP && ARCH_EXYNOS5 && !VIDEO_SAMSUNG_EXYNOS_GSC
 	help
 	  Choose this option if you want to use Exynos GSC for DRM.
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
index ed55d37b6330..7aecd23cfa11 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
@@ -15,7 +15,8 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/pm_runtime.h>
-#include <plat/map-base.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
 
 #include <drm/drmP.h>
 #include <drm/exynos_drm.h>
@@ -126,6 +127,7 @@ struct gsc_capability {
  * @ippdrv: prepare initialization using ippdrv.
  * @regs_res: register resources.
  * @regs: memory mapped io registers.
+ * @sysreg: handle to SYSREG block regmap.
  * @lock: locking of operations.
  * @gsc_clk: gsc gate clock.
  * @sc: scaler infomations.
@@ -138,6 +140,7 @@ struct gsc_context {
 	struct exynos_drm_ippdrv	ippdrv;
 	struct resource	*regs_res;
 	void __iomem	*regs;
+	struct regmap	*sysreg;
 	struct mutex	lock;
 	struct clk	*gsc_clk;
 	struct gsc_scaler	sc;
@@ -437,9 +440,12 @@ static int gsc_sw_reset(struct gsc_context *ctx)
 
 static void gsc_set_gscblk_fimd_wb(struct gsc_context *ctx, bool enable)
 {
-	u32 gscblk_cfg;
+	unsigned int gscblk_cfg;
 
-	gscblk_cfg = readl(SYSREG_GSCBLK_CFG1);
+	if (!ctx->sysreg)
+		return;
+
+	regmap_read(ctx->sysreg, SYSREG_GSCBLK_CFG1, &gscblk_cfg);
 
 	if (enable)
 		gscblk_cfg |= GSC_BLK_DISP1WB_DEST(ctx->id) |
@@ -448,7 +454,7 @@ static void gsc_set_gscblk_fimd_wb(struct gsc_context *ctx, bool enable)
 	else
 		gscblk_cfg |= GSC_BLK_PXLASYNC_LO_MASK_WB(ctx->id);
 
-	writel(gscblk_cfg, SYSREG_GSCBLK_CFG1);
+	regmap_write(ctx->sysreg, SYSREG_GSCBLK_CFG1, gscblk_cfg);
 }
 
 static void gsc_handle_irq(struct gsc_context *ctx, bool enable,
@@ -1663,6 +1669,15 @@ static int gsc_probe(struct platform_device *pdev)
 	if (!ctx)
 		return -ENOMEM;
 
+	if (dev->of_node) {
+		ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
+							"samsung,sysreg");
+		if (IS_ERR(ctx->sysreg)) {
+			dev_warn(dev, "failed to get system register.\n");
+			ctx->sysreg = NULL;
+		}
+	}
+
 	/* clock control */
 	ctx->gsc_clk = devm_clk_get(dev, "gscl");
 	if (IS_ERR(ctx->gsc_clk)) {
@@ -1796,6 +1811,12 @@ static const struct dev_pm_ops gsc_pm_ops = {
 	SET_RUNTIME_PM_OPS(gsc_runtime_suspend, gsc_runtime_resume, NULL)
 };
 
+static const struct of_device_id exynos_drm_gsc_of_match[] = {
+	{ .compatible = "samsung,exynos5-gsc" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, exynos_drm_gsc_of_match);
+
 struct platform_driver gsc_driver = {
 	.probe		= gsc_probe,
 	.remove		= gsc_remove,
@@ -1803,6 +1824,7 @@ struct platform_driver gsc_driver = {
 		.name	= "exynos-drm-gsc",
 		.owner	= THIS_MODULE,
 		.pm	= &gsc_pm_ops,
+		.of_match_table = of_match_ptr(exynos_drm_gsc_of_match),
 	},
 };
 
diff --git a/drivers/gpu/drm/exynos/regs-gsc.h b/drivers/gpu/drm/exynos/regs-gsc.h
index 9ad592707aaf..4704a993cbb7 100644
--- a/drivers/gpu/drm/exynos/regs-gsc.h
+++ b/drivers/gpu/drm/exynos/regs-gsc.h
@@ -273,12 +273,12 @@
 #define GSC_CLK_GATE_MODE_SNOOP_CNT(x)	((x) << 0)
 
 /* SYSCON. GSCBLK_CFG */
-#define SYSREG_GSCBLK_CFG1		(S3C_VA_SYS + 0x0224)
+#define SYSREG_GSCBLK_CFG1		0x0224
 #define GSC_BLK_DISP1WB_DEST(x)		(x << 10)
 #define GSC_BLK_SW_RESET_WB_DEST(x)	(1 << (18 + x))
 #define GSC_BLK_PXLASYNC_LO_MASK_WB(x)	(0 << (14 + x))
 #define GSC_BLK_GSCL_WB_IN_SRC_SEL(x)	(1 << (2 * x))
-#define SYSREG_GSCBLK_CFG2		(S3C_VA_SYS + 0x2000)
+#define SYSREG_GSCBLK_CFG2		0x2000
 #define PXLASYNC_LO_MASK_CAMIF_GSCL(x)	(1 << (x))
 
 #endif /* EXYNOS_REGS_GSC_H_ */
-- 
1.9.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 06/25] drm/exynos: fix to calculate offset of each plane for ipp fimc
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (4 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 05/25] drm/exynos: gsc: add device tree support and remove usage of static mappings Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-12 15:20   ` Tobias Jakobi
  2015-11-10 13:23 ` [PATCH 07/25] drm/exynos: fix to calculate offset of each plane for ipp gsc Marek Szyprowski
                   ` (21 subsequent siblings)
  27 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

From: Seung-Woo Kim <sw0312.kim@samsung.com>

NV12 and YUV420 formats are need to calculate offset of each plane
for ipp fimc in a gem buffer. Without proper offset, only Y plane
can be processed, so result shows green frame.
This patch fixes to calculate offset for cbcr planes for NV12 and
YUV420 formats.

Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_fimc.c | 106 +++++++++++++++++++++++++++++++
 drivers/gpu/drm/exynos/exynos_drm_ipp.c  |  15 ++++-
 drivers/gpu/drm/exynos/exynos_drm_ipp.h  |   2 +
 3 files changed, 121 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
index c747824f3c98..72a7ca188be5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
@@ -403,6 +403,97 @@ static void fimc_handle_lastend(struct fimc_context *ctx, bool enable)
 	fimc_write(ctx, cfg, EXYNOS_CIOCTRL);
 }
 
+static int fimc_set_planar_addr(struct drm_exynos_ipp_buf_info *buf_info,
+				u32 fmt, struct drm_exynos_sz *sz)
+{
+	dma_addr_t *base[EXYNOS_DRM_PLANAR_MAX];
+	uint64_t size[EXYNOS_DRM_PLANAR_MAX];
+	uint64_t ofs[EXYNOS_DRM_PLANAR_MAX];
+	bool bypass = false;
+	uint64_t tsize = 0;
+	int i;
+
+	for_each_ipp_planar(i) {
+		base[i] = &buf_info->base[i];
+		size[i] = buf_info->size[i];
+		ofs[i] = 0;
+		tsize += size[i];
+	}
+
+	if (!tsize) {
+		DRM_INFO("%s:failed to get buffer size.\n", __func__);
+		return 0;
+	}
+
+	switch (fmt) {
+	case DRM_FORMAT_NV12:
+	case DRM_FORMAT_NV21:
+	case DRM_FORMAT_NV16:
+	case DRM_FORMAT_NV61:
+		ofs[0] = sz->hsize * sz->vsize;
+		ofs[1] = ofs[0] >> 1;
+		if (*base[0] && *base[1]) {
+			if (size[0] + size[1] < ofs[0] + ofs[1])
+				goto err_info;
+			bypass = true;
+		}
+		break;
+	case DRM_FORMAT_YUV410:
+	case DRM_FORMAT_YVU410:
+	case DRM_FORMAT_YUV411:
+	case DRM_FORMAT_YVU411:
+	case DRM_FORMAT_YUV420:
+	case DRM_FORMAT_YVU420:
+	case DRM_FORMAT_YUV422:
+	case DRM_FORMAT_YVU422:
+	case DRM_FORMAT_YUV444:
+	case DRM_FORMAT_YVU444:
+		ofs[0] = sz->hsize * sz->vsize;
+		ofs[1] = ofs[2] = ofs[0] >> 2;
+		if (*base[0] && *base[1] && *base[2]) {
+			if (size[0]+size[1]+size[2] < ofs[0]+ofs[1]+ofs[2])
+				goto err_info;
+			bypass = true;
+		}
+		break;
+	case DRM_FORMAT_XRGB8888:
+	case DRM_FORMAT_ARGB8888:
+		ofs[0] = sz->hsize * sz->vsize << 2;
+		if (*base[0]) {
+			if (size[0] < ofs[0])
+				goto err_info;
+		}
+		bypass = true;
+		break;
+	default:
+		bypass = true;
+		break;
+	}
+
+	if (!bypass) {
+		*base[1] = *base[0] + ofs[0];
+		if (ofs[1] && ofs[2])
+			*base[2] = *base[1] + ofs[1];
+	}
+
+	DRM_DEBUG_KMS("%s:y[0x%x],cb[0x%x],cr[0x%x]\n", __func__,
+		*base[0], *base[1], *base[2]);
+
+	return 0;
+
+err_info:
+	DRM_ERROR("invalid size for fmt[0x%x]\n", fmt);
+
+	for_each_ipp_planar(i) {
+		base[i] = &buf_info->base[i];
+		size[i] = buf_info->size[i];
+
+		DRM_ERROR("buf[%d] - base[0x%x] sz[%llu] ofs[%llu]\n",
+			i, *base[i], size[i], ofs[i]);
+	}
+
+	return -EINVAL;
+}
 
 static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
 {
@@ -689,6 +780,7 @@ static int fimc_src_set_addr(struct device *dev,
 	struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node;
 	struct drm_exynos_ipp_property *property;
 	struct drm_exynos_ipp_config *config;
+	int ret;
 
 	if (!c_node) {
 		DRM_ERROR("failed to get c_node.\n");
@@ -709,6 +801,12 @@ static int fimc_src_set_addr(struct device *dev,
 	switch (buf_type) {
 	case IPP_BUF_ENQUEUE:
 		config = &property->config[EXYNOS_DRM_OPS_SRC];
+		ret = fimc_set_planar_addr(buf_info, config->fmt, &config->sz);
+		if (ret) {
+			dev_err(dev, "failed to set plane src addr.\n");
+			return ret;
+		}
+
 		fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_Y],
 			EXYNOS_CIIYSA0);
 
@@ -1148,6 +1246,7 @@ static int fimc_dst_set_addr(struct device *dev,
 	struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node;
 	struct drm_exynos_ipp_property *property;
 	struct drm_exynos_ipp_config *config;
+	int ret;
 
 	if (!c_node) {
 		DRM_ERROR("failed to get c_node.\n");
@@ -1168,6 +1267,11 @@ static int fimc_dst_set_addr(struct device *dev,
 	switch (buf_type) {
 	case IPP_BUF_ENQUEUE:
 		config = &property->config[EXYNOS_DRM_OPS_DST];
+		ret = fimc_set_planar_addr(buf_info, config->fmt, &config->sz);
+		if (ret) {
+			dev_err(dev, "failed to set plane dst addr.\n");
+			return ret;
+		}
 
 		fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_Y],
 			EXYNOS_CIOYSA(buf_id));
@@ -1562,6 +1666,8 @@ static void fimc_ippdrv_stop(struct device *dev, enum drm_exynos_ipp_cmd cmd)
 	/* reset sequence */
 	fimc_write(ctx, 0x0, EXYNOS_CIFCNTSEQ);
 
+	fimc_clear_addr(ctx);
+
 	/* Scaler disable */
 	fimc_clear_bits(ctx, EXYNOS_CISCCTRL, EXYNOS_CISCCTRL_SCALERSTART);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index 67d24236e745..408a14a9a180 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -571,6 +571,7 @@ static struct drm_exynos_ipp_mem_node
 		/* get dma address by handle */
 		if (qbuf->handle[i]) {
 			dma_addr_t *addr;
+			unsigned long size;
 
 			addr = exynos_drm_gem_get_dma_addr(drm_dev,
 					qbuf->handle[i], c_node->filp);
@@ -580,10 +581,20 @@ static struct drm_exynos_ipp_mem_node
 				return ERR_PTR(-EFAULT);
 			}
 
+			size = exynos_drm_gem_get_size(drm_dev,
+					qbuf->handle[i], c_node->filp);
+			if (!size) {
+				DRM_ERROR("failed to get size.\n");
+				ipp_put_mem_node(drm_dev, c_node, m_node);
+				return ERR_PTR(-EFAULT);
+			}
+
 			buf_info->handles[i] = qbuf->handle[i];
 			buf_info->base[i] = *addr;
-			DRM_DEBUG_KMS("i[%d]base[0x%x]hd[0x%lx]\n", i,
-				      buf_info->base[i], buf_info->handles[i]);
+			buf_info->size[i] = (uint64_t)size;
+			DRM_DEBUG_KMS("i[%d]base[%pad]hd[0x%lx]sz[%llx]\n", i,
+				      &buf_info->base[i], buf_info->handles[i],
+				      buf_info->size[i]);
 		}
 	}
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
index 2a61547a39d0..d4f0b588220b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
@@ -85,10 +85,12 @@ struct drm_exynos_ipp_cmd_node {
  *
  * @handles: Y, Cb, Cr each gem object handle.
  * @base: Y, Cb, Cr each planar address.
+ * @size: Y, Cb, Cr each planar size.
  */
 struct drm_exynos_ipp_buf_info {
 	unsigned long	handles[EXYNOS_DRM_PLANAR_MAX];
 	dma_addr_t	base[EXYNOS_DRM_PLANAR_MAX];
+	uint64_t	size[EXYNOS_DRM_PLANAR_MAX];
 };
 
 /*
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 07/25] drm/exynos: fix to calculate offset of each plane for ipp gsc
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (5 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 06/25] drm/exynos: fix to calculate offset of each plane for ipp fimc Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-10 13:23 ` [PATCH 08/25] drm/exynos: rotator: convert to common clock framework Marek Szyprowski
                   ` (20 subsequent siblings)
  27 siblings, 0 replies; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

From: Seung-Woo Kim <sw0312.kim@samsung.com>

NV12 and YUV420 formats are needed to calculate offset of each plane
in a gem buffer for ipp gsc. Without proper offset, only Y plane
can be processed, so result shows green frame. This patch fixes to
calculate offset for cbcr planes for NV12 and YUV420 formats.

Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_gsc.c | 116 ++++++++++++++++++++++++++++++++
 1 file changed, 116 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
index 7aecd23cfa11..2882b9347cc8 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
@@ -486,6 +486,98 @@ static void gsc_handle_irq(struct gsc_context *ctx, bool enable,
 	gsc_write(cfg, GSC_IRQ);
 }
 
+static int gsc_set_planar_addr(struct drm_exynos_ipp_buf_info *buf_info,
+		u32 fmt, struct drm_exynos_sz *sz)
+{
+	dma_addr_t *base[EXYNOS_DRM_PLANAR_MAX];
+	uint64_t size[EXYNOS_DRM_PLANAR_MAX];
+	uint64_t ofs[EXYNOS_DRM_PLANAR_MAX];
+	bool bypass = false;
+	uint64_t tsize = 0;
+	int i;
+
+	for_each_ipp_planar(i) {
+		base[i] = &buf_info->base[i];
+		size[i] = buf_info->size[i];
+		ofs[i] = 0;
+		tsize += size[i];
+		DRM_DEBUG_KMS("base[%d][0x%lx]s[%d][%llu]\n",
+				i, (unsigned long)*base[i], i, size[i]);
+	}
+
+	if (!tsize) {
+		DRM_INFO("failed to get buffer size.\n");
+		return 0;
+	}
+
+	switch (fmt) {
+	case DRM_FORMAT_NV12:
+	case DRM_FORMAT_NV21:
+	case DRM_FORMAT_NV16:
+	case DRM_FORMAT_NV61:
+		ofs[0] = sz->hsize * sz->vsize;
+		ofs[1] = ofs[0] >> 1;
+		if (*base[0] && *base[1]) {
+			if (size[0] + size[1] < ofs[0] + ofs[1])
+				goto err_info;
+			bypass = true;
+		}
+		break;
+	case DRM_FORMAT_YUV410:
+	case DRM_FORMAT_YVU410:
+	case DRM_FORMAT_YUV411:
+	case DRM_FORMAT_YVU411:
+	case DRM_FORMAT_YUV420:
+	case DRM_FORMAT_YVU420:
+	case DRM_FORMAT_YUV422:
+	case DRM_FORMAT_YVU422:
+	case DRM_FORMAT_YUV444:
+	case DRM_FORMAT_YVU444:
+		ofs[0] = sz->hsize * sz->vsize;
+		ofs[1] = ofs[2] = ofs[0] >> 2;
+		if (*base[0] && *base[1] && *base[2]) {
+			if (size[0]+size[1]+size[2] < ofs[0]+ofs[1]+ofs[2])
+				goto err_info;
+			bypass = true;
+		}
+	break;
+	case DRM_FORMAT_XRGB8888:
+		ofs[0] = sz->hsize * sz->vsize << 2;
+		if (*base[0]) {
+			if (size[0] < ofs[0])
+				goto err_info;
+		}
+		bypass = true;
+		break;
+	default:
+		bypass = true;
+		break;
+	}
+
+	if (!bypass) {
+		*base[1] = *base[0] + ofs[0];
+		if (ofs[1] && ofs[2])
+			*base[2] = *base[1] + ofs[1];
+	}
+
+	DRM_DEBUG_KMS("y[0x%lx],cb[0x%lx],cr[0x%lx]\n", (unsigned long)*base[0],
+			(unsigned long)*base[1], (unsigned long)*base[2]);
+
+	return 0;
+
+err_info:
+	DRM_ERROR("invalid size for fmt[0x%x]\n", fmt);
+
+	for_each_ipp_planar(i) {
+		base[i] = &buf_info->base[i];
+		size[i] = buf_info->size[i];
+
+		DRM_ERROR("base[%d][0x%lx]s[%d][%llu]ofs[%d][%llu]\n",
+			i, (unsigned long)*base[i], i, size[i], i, ofs[i]);
+	}
+
+	return -EINVAL;
+}
 
 static int gsc_src_set_fmt(struct device *dev, u32 fmt)
 {
@@ -715,6 +807,8 @@ static int gsc_src_set_addr(struct device *dev,
 	struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
 	struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node;
 	struct drm_exynos_ipp_property *property;
+	struct drm_exynos_ipp_config *config;
+	int ret;
 
 	if (!c_node) {
 		DRM_ERROR("failed to get c_node.\n");
@@ -734,6 +828,13 @@ static int gsc_src_set_addr(struct device *dev,
 	/* address register set */
 	switch (buf_type) {
 	case IPP_BUF_ENQUEUE:
+		config = &property->config[EXYNOS_DRM_OPS_SRC];
+		ret = gsc_set_planar_addr(buf_info, config->fmt, &config->sz);
+		if (ret) {
+			dev_err(dev, "failed to set plane src addr.\n");
+			return ret;
+		}
+
 		gsc_write(buf_info->base[EXYNOS_DRM_PLANAR_Y],
 			GSC_IN_BASE_ADDR_Y(buf_id));
 		gsc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB],
@@ -1170,6 +1271,8 @@ static int gsc_dst_set_addr(struct device *dev,
 	struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
 	struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node;
 	struct drm_exynos_ipp_property *property;
+	struct drm_exynos_ipp_config *config;
+	int ret;
 
 	if (!c_node) {
 		DRM_ERROR("failed to get c_node.\n");
@@ -1189,6 +1292,13 @@ static int gsc_dst_set_addr(struct device *dev,
 	/* address register set */
 	switch (buf_type) {
 	case IPP_BUF_ENQUEUE:
+		config = &property->config[EXYNOS_DRM_OPS_DST];
+		ret = gsc_set_planar_addr(buf_info, config->fmt, &config->sz);
+		if (ret) {
+			dev_err(dev, "failed to set plane dst addr.\n");
+			return ret;
+		}
+
 		gsc_write(buf_info->base[EXYNOS_DRM_PLANAR_Y],
 			GSC_OUT_BASE_ADDR_Y(buf_id));
 		gsc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB],
@@ -1320,6 +1430,12 @@ static irqreturn_t gsc_irq_handler(int irq, void *dev_id)
 		return IRQ_NONE;
 	}
 
+	if (c_node->state == IPP_STATE_STOP) {
+		DRM_ERROR("invalid state: prop_id[%d]\n",
+				c_node->property.prop_id);
+		return IRQ_HANDLED;
+	}
+
 	if (status & GSC_IRQ_STATUS_OR_FRM_DONE) {
 		dev_dbg(ippdrv->dev, "occurred frame done at %d, status 0x%x.\n",
 			ctx->id, status);
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 08/25] drm/exynos: rotator: convert to common clock framework
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (6 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 07/25] drm/exynos: fix to calculate offset of each plane for ipp gsc Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-12 18:13   ` Gustavo Padovan
  2015-11-10 13:23 ` [PATCH 09/25] drm/exynos: exynos7-decon: remove excessive check Marek Szyprowski
                   ` (19 subsequent siblings)
  27 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Javier Martinez Canillas, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, Andrzej Hajda,
	Tobias Jakobi, Marek Szyprowski

This driver was not used after introduction of common clock framework.
This patch adds missing prepare/unprepare calls and allows to use it
again with current kernel code.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_rotator.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
index 2f5c118f4c8e..bea0f7826d30 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
@@ -790,10 +790,10 @@ static int rotator_remove(struct platform_device *pdev)
 static int rotator_clk_crtl(struct rot_context *rot, bool enable)
 {
 	if (enable) {
-		clk_enable(rot->clock);
+		clk_prepare_enable(rot->clock);
 		rot->suspended = false;
 	} else {
-		clk_disable(rot->clock);
+		clk_disable_unprepare(rot->clock);
 		rot->suspended = true;
 	}
 
-- 
1.9.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 09/25] drm/exynos: exynos7-decon: remove excessive check
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (7 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 08/25] drm/exynos: rotator: convert to common clock framework Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-12 18:15   ` Gustavo Padovan
  2015-11-10 13:23 ` [PATCH 10/25] drm/exynos: move dma_addr attribute from exynos plane to exynos fb Marek Szyprowski
                   ` (18 subsequent siblings)
  27 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

Display area is already checked by exynos plane core, so there is no
need for such check in driver code.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos7_drm_decon.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index ead2b16e237d..d50c26a41e09 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -399,7 +399,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
 			       struct exynos_drm_plane *plane)
 {
 	struct decon_context *ctx = crtc->ctx;
-	struct drm_display_mode *mode = &crtc->base.state->adjusted_mode;
 	struct drm_plane_state *state = plane->base.state;
 	int padding;
 	unsigned long val, alpha;
@@ -441,15 +440,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
 	DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
 			plane->crtc_w, plane->crtc_h);
 
-	/*
-	 * OSD position.
-	 * In case the window layout goes of LCD layout, DECON fails.
-	 */
-	if ((plane->crtc_x + plane->crtc_w) > mode->hdisplay)
-		plane->crtc_x = mode->hdisplay - plane->crtc_w;
-	if ((plane->crtc_y + plane->crtc_h) > mode->vdisplay)
-		plane->crtc_y = mode->vdisplay - plane->crtc_h;
-
 	val = VIDOSDxA_TOPLEFT_X(plane->crtc_x) |
 		VIDOSDxA_TOPLEFT_Y(plane->crtc_y);
 	writel(val, ctx->regs + VIDOSD_A(win));
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 10/25] drm/exynos: move dma_addr attribute from exynos plane to exynos fb
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (8 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 09/25] drm/exynos: exynos7-decon: remove excessive check Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-12 18:25   ` Gustavo Padovan
  2015-11-10 13:23 ` [PATCH 11/25] drm/exynos: introduce exynos_drm_plane_state structure Marek Szyprowski
                   ` (17 subsequent siblings)
  27 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Javier Martinez Canillas, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, Andrzej Hajda,
	Tobias Jakobi, Marek Szyprowski

DMA address is a framebuffer attribute and the right place for it is
exynos_drm_framebuffer not exynos_drm_plane. This patch also introduces
helper function for getting dma address of the given framebuffer.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 13 ++++++++-----
 drivers/gpu/drm/exynos/exynos7_drm_decon.c    | 16 +++++++++-------
 drivers/gpu/drm/exynos/exynos_drm_drv.h       |  3 ---
 drivers/gpu/drm/exynos/exynos_drm_fb.c        | 16 ++++++----------
 drivers/gpu/drm/exynos/exynos_drm_fb.h        |  3 +--
 drivers/gpu/drm/exynos/exynos_drm_fimd.c      | 10 ++++++----
 drivers/gpu/drm/exynos/exynos_drm_plane.c     | 18 ------------------
 drivers/gpu/drm/exynos/exynos_drm_vidi.c      |  5 ++++-
 drivers/gpu/drm/exynos/exynos_mixer.c         |  7 ++++---
 9 files changed, 38 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index fbe1b3174f75..a3161b0428b9 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -21,6 +21,7 @@
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_crtc.h"
+#include "exynos_drm_fb.h"
 #include "exynos_drm_plane.h"
 #include "exynos_drm_iommu.h"
 
@@ -261,9 +262,11 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
 {
 	struct decon_context *ctx = crtc->ctx;
 	struct drm_plane_state *state = plane->base.state;
+	struct drm_framebuffer *fb = state->fb;
 	unsigned int win = plane->zpos;
-	unsigned int bpp = state->fb->bits_per_pixel >> 3;
-	unsigned int pitch = state->fb->pitches[0];
+	unsigned int bpp = fb->bits_per_pixel >> 3;
+	unsigned int pitch = fb->pitches[0];
+	dma_addr_t dma_addr = exynos_drm_fb_dma_addr(fb, 0);
 	u32 val;
 
 	if (test_bit(BIT_SUSPENDED, &ctx->flags))
@@ -284,9 +287,9 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
 		VIDOSD_Wx_ALPHA_B_F(0x0);
 	writel(val, ctx->addr + DECON_VIDOSDxD(win));
 
-	writel(plane->dma_addr[0], ctx->addr + DECON_VIDW0xADD0B0(win));
+	writel(dma_addr, ctx->addr + DECON_VIDW0xADD0B0(win));
 
-	val = plane->dma_addr[0] + pitch * plane->crtc_h;
+	val = dma_addr + pitch * plane->crtc_h;
 	writel(val, ctx->addr + DECON_VIDW0xADD1B0(win));
 
 	if (ctx->out_type != IFTYPE_HDMI)
@@ -297,7 +300,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
 			| BIT_VAL(plane->crtc_w * bpp, 14, 0);
 	writel(val, ctx->addr + DECON_VIDW0xADD2(win));
 
-	decon_win_set_pixfmt(ctx, win, state->fb);
+	decon_win_set_pixfmt(ctx, win, fb);
 
 	/* window enable */
 	decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0);
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index d50c26a41e09..15e1e165020f 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -30,6 +30,7 @@
 #include "exynos_drm_crtc.h"
 #include "exynos_drm_plane.h"
 #include "exynos_drm_drv.h"
+#include "exynos_drm_fb.h"
 #include "exynos_drm_fbdev.h"
 #include "exynos_drm_iommu.h"
 
@@ -400,13 +401,14 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
 {
 	struct decon_context *ctx = crtc->ctx;
 	struct drm_plane_state *state = plane->base.state;
+	struct drm_framebuffer *fb = state->fb;
 	int padding;
 	unsigned long val, alpha;
 	unsigned int last_x;
 	unsigned int last_y;
 	unsigned int win = plane->zpos;
-	unsigned int bpp = state->fb->bits_per_pixel >> 3;
-	unsigned int pitch = state->fb->pitches[0];
+	unsigned int bpp = fb->bits_per_pixel >> 3;
+	unsigned int pitch = fb->pitches[0];
 
 	if (ctx->suspended)
 		return;
@@ -422,14 +424,14 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
 	 */
 
 	/* buffer start address */
-	val = (unsigned long)plane->dma_addr[0];
+	val = (unsigned long)exynos_drm_fb_dma_addr(fb, 0);
 	writel(val, ctx->regs + VIDW_BUF_START(win));
 
-	padding = (pitch / bpp) - state->fb->width;
+	padding = (pitch / bpp) - fb->width;
 
 	/* buffer size */
-	writel(state->fb->width + padding, ctx->regs + VIDW_WHOLE_X(win));
-	writel(state->fb->height, ctx->regs + VIDW_WHOLE_Y(win));
+	writel(fb->width + padding, ctx->regs + VIDW_WHOLE_X(win));
+	writel(fb->height, ctx->regs + VIDW_WHOLE_Y(win));
 
 	/* offset from the start of the buffer to read */
 	writel(plane->src_x, ctx->regs + VIDW_OFFSET_X(win));
@@ -471,7 +473,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
 
 	writel(alpha, ctx->regs + VIDOSD_D(win));
 
-	decon_win_set_pixfmt(ctx, win, state->fb);
+	decon_win_set_pixfmt(ctx, win, fb);
 
 	/* hardware window 0 doesn't support color key. */
 	if (win != 0)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index f1eda7fa4e3c..dc41ffb26eb9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -54,8 +54,6 @@ enum exynos_drm_output_type {
  * @crtc_h: window height to be displayed (hardware screen).
  * @h_ratio: horizontal scaling ratio, 16.16 fixed point
  * @v_ratio: vertical scaling ratio, 16.16 fixed point
- * @dma_addr: array of bus(accessed by dma) address to the memory region
- *	      allocated for a overlay.
  * @zpos: order of overlay layer(z position).
  *
  * this structure is common to exynos SoC and its contents would be copied
@@ -74,7 +72,6 @@ struct exynos_drm_plane {
 	unsigned int crtc_h;
 	unsigned int h_ratio;
 	unsigned int v_ratio;
-	dma_addr_t dma_addr[MAX_FB_BUFFER];
 	unsigned int zpos;
 	struct drm_framebuffer *pending_fb;
 };
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index fcea28bdbc42..96d5db4ef63f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -37,6 +37,7 @@
 struct exynos_drm_fb {
 	struct drm_framebuffer	fb;
 	struct exynos_drm_gem	*exynos_gem[MAX_FB_BUFFER];
+	dma_addr_t			dma_addr[MAX_FB_BUFFER];
 };
 
 static int check_fb_gem_memory_type(struct drm_device *drm_dev,
@@ -135,6 +136,8 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
 			goto err;
 
 		exynos_fb->exynos_gem[i] = exynos_gem[i];
+		exynos_fb->dma_addr[i] = exynos_gem[i]->dma_addr
+						+ mode_cmd->offsets[i];
 	}
 
 	drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd);
@@ -189,21 +192,14 @@ err:
 	return ERR_PTR(ret);
 }
 
-struct exynos_drm_gem *exynos_drm_fb_gem(struct drm_framebuffer *fb, int index)
+dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index)
 {
 	struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
-	struct exynos_drm_gem *exynos_gem;
 
 	if (index >= MAX_FB_BUFFER)
-		return NULL;
+		return DMA_ERROR_CODE;
 
-	exynos_gem = exynos_fb->exynos_gem[index];
-	if (!exynos_gem)
-		return NULL;
-
-	DRM_DEBUG_KMS("dma_addr: 0x%lx\n", (unsigned long)exynos_gem->dma_addr);
-
-	return exynos_gem;
+	return exynos_fb->dma_addr[index];
 }
 
 static void exynos_drm_output_poll_changed(struct drm_device *dev)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.h b/drivers/gpu/drm/exynos/exynos_drm_fb.h
index 726a2d44371f..4357a82c51d9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.h
@@ -22,8 +22,7 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
 			    struct exynos_drm_gem **exynos_gem,
 			    int count);
 
-/* get gem object of a drm framebuffer */
-struct exynos_drm_gem *exynos_drm_fb_gem(struct drm_framebuffer *fb, int index);
+dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index);
 
 void exynos_drm_mode_config_init(struct drm_device *dev);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index bd75c1531cac..d39e960a837f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -29,6 +29,7 @@
 #include <drm/exynos_drm.h>
 
 #include "exynos_drm_drv.h"
+#include "exynos_drm_fb.h"
 #include "exynos_drm_fbdev.h"
 #include "exynos_drm_crtc.h"
 #include "exynos_drm_plane.h"
@@ -642,12 +643,13 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
 {
 	struct fimd_context *ctx = crtc->ctx;
 	struct drm_plane_state *state = plane->base.state;
+	struct drm_framebuffer *fb = state->fb;
 	dma_addr_t dma_addr;
 	unsigned long val, size, offset;
 	unsigned int last_x, last_y, buf_offsize, line_size;
 	unsigned int win = plane->zpos;
-	unsigned int bpp = state->fb->bits_per_pixel >> 3;
-	unsigned int pitch = state->fb->pitches[0];
+	unsigned int bpp = fb->bits_per_pixel >> 3;
+	unsigned int pitch = fb->pitches[0];
 
 	if (ctx->suspended)
 		return;
@@ -656,7 +658,7 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
 	offset += plane->src_y * pitch;
 
 	/* buffer start address */
-	dma_addr = plane->dma_addr[0] + offset;
+	dma_addr = exynos_drm_fb_dma_addr(fb, 0) + offset;
 	val = (unsigned long)dma_addr;
 	writel(val, ctx->regs + VIDWx_BUF_START(win, 0));
 
@@ -712,7 +714,7 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
 		DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val);
 	}
 
-	fimd_win_set_pixfmt(ctx, win, state->fb);
+	fimd_win_set_pixfmt(ctx, win, fb);
 
 	/* hardware window 0 doesn't support color key. */
 	if (win != 0)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index 179311760bb7..c725409421b8 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -120,28 +120,10 @@ static int exynos_plane_atomic_check(struct drm_plane *plane,
 				     struct drm_plane_state *state)
 {
 	struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
-	int nr;
-	int i;
 
 	if (!state->fb)
 		return 0;
 
-	nr = drm_format_num_planes(state->fb->pixel_format);
-	for (i = 0; i < nr; i++) {
-		struct exynos_drm_gem *exynos_gem =
-					exynos_drm_fb_gem(state->fb, i);
-		if (!exynos_gem) {
-			DRM_DEBUG_KMS("gem object is null\n");
-			return -EFAULT;
-		}
-
-		exynos_plane->dma_addr[i] = exynos_gem->dma_addr +
-					    state->fb->offsets[i];
-
-		DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n",
-				i, (unsigned long)exynos_plane->dma_addr[i]);
-	}
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 669362c53f49..3ce141236fad 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -24,6 +24,7 @@
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_crtc.h"
+#include "exynos_drm_fb.h"
 #include "exynos_drm_plane.h"
 #include "exynos_drm_vidi.h"
 
@@ -126,11 +127,13 @@ static void vidi_update_plane(struct exynos_drm_crtc *crtc,
 			      struct exynos_drm_plane *plane)
 {
 	struct vidi_context *ctx = crtc->ctx;
+	dma_addr_t addr;
 
 	if (ctx->suspended)
 		return;
 
-	DRM_DEBUG_KMS("dma_addr = %pad\n", plane->dma_addr);
+	addr = exynos_drm_fb_dma_addr(plane->base.fb, 0);
+	DRM_DEBUG_KMS("dma_addr = %pad\n", &addr);
 
 	if (ctx->vblank_on)
 		schedule_work(&ctx->work);
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index d09f8f9a8939..efb5d0435558 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -37,6 +37,7 @@
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_crtc.h"
+#include "exynos_drm_fb.h"
 #include "exynos_drm_plane.h"
 #include "exynos_drm_iommu.h"
 
@@ -422,8 +423,8 @@ static void vp_video_buffer(struct mixer_context *ctx,
 		return;
 	}
 
-	luma_addr[0] = plane->dma_addr[0];
-	chroma_addr[0] = plane->dma_addr[1];
+	luma_addr[0] = exynos_drm_fb_dma_addr(fb, 0);
+	chroma_addr[0] = exynos_drm_fb_dma_addr(fb, 1);
 
 	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
 		ctx->interlace = true;
@@ -575,7 +576,7 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
 	dst_y_offset = plane->crtc_y;
 
 	/* converting dma address base and source offset */
-	dma_addr = plane->dma_addr[0]
+	dma_addr = exynos_drm_fb_dma_addr(fb, 0)
 		+ (plane->src_x * fb->bits_per_pixel >> 3)
 		+ (plane->src_y * fb->pitches[0]);
 	src_x_offset = 0;
-- 
1.9.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 11/25] drm/exynos: introduce exynos_drm_plane_state structure
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (9 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 10/25] drm/exynos: move dma_addr attribute from exynos plane to exynos fb Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-13 11:46   ` Gustavo Padovan
  2015-11-10 13:23 ` [PATCH 12/25] drm/exynos: mixer: use crtc->state->adjusted_mode instead of crtc->mode Marek Szyprowski
                   ` (16 subsequent siblings)
  27 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

This patch introduces exynos_drm_plane_state structure, which subclasses
drm_plane_state and holds precalculated data suitable for configuring
Exynos hardware.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c |  21 ++---
 drivers/gpu/drm/exynos/exynos7_drm_decon.c    |  21 ++---
 drivers/gpu/drm/exynos/exynos_drm_drv.h       |  56 +++++++-----
 drivers/gpu/drm/exynos/exynos_drm_fimd.c      |  33 +++----
 drivers/gpu/drm/exynos/exynos_drm_plane.c     | 125 +++++++++++++++++++-------
 drivers/gpu/drm/exynos/exynos_mixer.c         |  61 +++++++------
 6 files changed, 197 insertions(+), 120 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index a3161b0428b9..27039468364b 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -260,9 +260,10 @@ static void decon_atomic_begin(struct exynos_drm_crtc *crtc,
 static void decon_update_plane(struct exynos_drm_crtc *crtc,
 			       struct exynos_drm_plane *plane)
 {
+	struct exynos_drm_plane_state *state =
+				to_exynos_plane_state(plane->base.state);
 	struct decon_context *ctx = crtc->ctx;
-	struct drm_plane_state *state = plane->base.state;
-	struct drm_framebuffer *fb = state->fb;
+	struct drm_framebuffer *fb = state->base.fb;
 	unsigned int win = plane->zpos;
 	unsigned int bpp = fb->bits_per_pixel >> 3;
 	unsigned int pitch = fb->pitches[0];
@@ -272,11 +273,11 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
 	if (test_bit(BIT_SUSPENDED, &ctx->flags))
 		return;
 
-	val = COORDINATE_X(plane->crtc_x) | COORDINATE_Y(plane->crtc_y);
+	val = COORDINATE_X(state->crtc.x) | COORDINATE_Y(state->crtc.y);
 	writel(val, ctx->addr + DECON_VIDOSDxA(win));
 
-	val = COORDINATE_X(plane->crtc_x + plane->crtc_w - 1) |
-		COORDINATE_Y(plane->crtc_y + plane->crtc_h - 1);
+	val = COORDINATE_X(state->crtc.x + state->crtc.w - 1) |
+		COORDINATE_Y(state->crtc.y + state->crtc.h - 1);
 	writel(val, ctx->addr + DECON_VIDOSDxB(win));
 
 	val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) |
@@ -289,15 +290,15 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
 
 	writel(dma_addr, ctx->addr + DECON_VIDW0xADD0B0(win));
 
-	val = dma_addr + pitch * plane->crtc_h;
+	val = dma_addr + pitch * state->src.h;
 	writel(val, ctx->addr + DECON_VIDW0xADD1B0(win));
 
 	if (ctx->out_type != IFTYPE_HDMI)
-		val = BIT_VAL(pitch - plane->crtc_w * bpp, 27, 14)
-			| BIT_VAL(plane->crtc_w * bpp, 13, 0);
+		val = BIT_VAL(pitch - state->crtc.w * bpp, 27, 14)
+			| BIT_VAL(state->crtc.w * bpp, 13, 0);
 	else
-		val = BIT_VAL(pitch - plane->crtc_w * bpp, 29, 15)
-			| BIT_VAL(plane->crtc_w * bpp, 14, 0);
+		val = BIT_VAL(pitch - state->crtc.w * bpp, 29, 15)
+			| BIT_VAL(state->crtc.w * bpp, 14, 0);
 	writel(val, ctx->addr + DECON_VIDW0xADD2(win));
 
 	decon_win_set_pixfmt(ctx, win, fb);
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index 15e1e165020f..7868d30d8eac 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -399,9 +399,10 @@ static void decon_atomic_begin(struct exynos_drm_crtc *crtc,
 static void decon_update_plane(struct exynos_drm_crtc *crtc,
 			       struct exynos_drm_plane *plane)
 {
+	struct exynos_drm_plane_state *state =
+				to_exynos_plane_state(plane->base.state);
 	struct decon_context *ctx = crtc->ctx;
-	struct drm_plane_state *state = plane->base.state;
-	struct drm_framebuffer *fb = state->fb;
+	struct drm_framebuffer *fb = state->base.fb;
 	int padding;
 	unsigned long val, alpha;
 	unsigned int last_x;
@@ -434,22 +435,22 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
 	writel(fb->height, ctx->regs + VIDW_WHOLE_Y(win));
 
 	/* offset from the start of the buffer to read */
-	writel(plane->src_x, ctx->regs + VIDW_OFFSET_X(win));
-	writel(plane->src_y, ctx->regs + VIDW_OFFSET_Y(win));
+	writel(state->src.x, ctx->regs + VIDW_OFFSET_X(win));
+	writel(state->src.y, ctx->regs + VIDW_OFFSET_Y(win));
 
 	DRM_DEBUG_KMS("start addr = 0x%lx\n",
 			(unsigned long)val);
 	DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
-			plane->crtc_w, plane->crtc_h);
+			state->crtc.w, state->crtc.h);
 
-	val = VIDOSDxA_TOPLEFT_X(plane->crtc_x) |
-		VIDOSDxA_TOPLEFT_Y(plane->crtc_y);
+	val = VIDOSDxA_TOPLEFT_X(state->crtc.x) |
+		VIDOSDxA_TOPLEFT_Y(state->crtc.y);
 	writel(val, ctx->regs + VIDOSD_A(win));
 
-	last_x = plane->crtc_x + plane->crtc_w;
+	last_x = state->crtc.x + state->crtc.w;
 	if (last_x)
 		last_x--;
-	last_y = plane->crtc_y + plane->crtc_h;
+	last_y = state->crtc.y + state->crtc.h;
 	if (last_y)
 		last_y--;
 
@@ -458,7 +459,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
 	writel(val, ctx->regs + VIDOSD_B(win));
 
 	DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n",
-			plane->crtc_x, plane->crtc_y, last_x, last_y);
+			state->crtc.x, state->crtc.y, last_x, last_y);
 
 	/* OSD alpha */
 	alpha = VIDOSDxC_ALPHA0_R_F(0x0) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index dc41ffb26eb9..482ed2c2ed89 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -38,22 +38,44 @@ enum exynos_drm_output_type {
 	EXYNOS_DISPLAY_TYPE_VIDI,
 };
 
+struct exynos_drm_rect {
+	unsigned int x, y;
+	unsigned int w, h;
+};
+
 /*
- * Exynos drm common overlay structure.
+ * Exynos drm plane state structure.
  *
- * @base: plane object
- * @src_x: offset x on a framebuffer to be displayed.
- *	- the unit is screen coordinates.
- * @src_y: offset y on a framebuffer to be displayed.
- *	- the unit is screen coordinates.
- * @src_w: width of a partial image to be displayed from framebuffer.
- * @src_h: height of a partial image to be displayed from framebuffer.
- * @crtc_x: offset x on hardware screen.
- * @crtc_y: offset y on hardware screen.
- * @crtc_w: window width to be displayed (hardware screen).
- * @crtc_h: window height to be displayed (hardware screen).
+ * @base: plane_state object (contains drm_framebuffer pointer)
+ * @src: rectangle of the source image data to be displayed (clipped to
+ *       visible part).
+ * @crtc: rectangle of the target image position on hardware screen
+ *       (clipped to visible part).
  * @h_ratio: horizontal scaling ratio, 16.16 fixed point
  * @v_ratio: vertical scaling ratio, 16.16 fixed point
+ *
+ * this structure consists plane state data that will be applied to hardware
+ * specific overlay info.
+ */
+
+struct exynos_drm_plane_state {
+	struct drm_plane_state base;
+	struct exynos_drm_rect crtc;
+	struct exynos_drm_rect src;
+	unsigned int h_ratio;
+	unsigned int v_ratio;
+};
+
+static inline struct exynos_drm_plane_state *
+to_exynos_plane_state(struct drm_plane_state *state)
+{
+	return container_of(state, struct exynos_drm_plane_state, base);
+}
+
+/*
+ * Exynos drm common overlay structure.
+ *
+ * @base: plane object
  * @zpos: order of overlay layer(z position).
  *
  * this structure is common to exynos SoC and its contents would be copied
@@ -62,16 +84,6 @@ enum exynos_drm_output_type {
 
 struct exynos_drm_plane {
 	struct drm_plane base;
-	unsigned int src_x;
-	unsigned int src_y;
-	unsigned int src_w;
-	unsigned int src_h;
-	unsigned int crtc_x;
-	unsigned int crtc_y;
-	unsigned int crtc_w;
-	unsigned int crtc_h;
-	unsigned int h_ratio;
-	unsigned int v_ratio;
 	unsigned int zpos;
 	struct drm_framebuffer *pending_fb;
 };
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index d39e960a837f..40fa621e3963 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -641,9 +641,10 @@ static void fimd_atomic_flush(struct exynos_drm_crtc *crtc,
 static void fimd_update_plane(struct exynos_drm_crtc *crtc,
 			      struct exynos_drm_plane *plane)
 {
+	struct exynos_drm_plane_state *state =
+				to_exynos_plane_state(plane->base.state);
 	struct fimd_context *ctx = crtc->ctx;
-	struct drm_plane_state *state = plane->base.state;
-	struct drm_framebuffer *fb = state->fb;
+	struct drm_framebuffer *fb = state->base.fb;
 	dma_addr_t dma_addr;
 	unsigned long val, size, offset;
 	unsigned int last_x, last_y, buf_offsize, line_size;
@@ -654,8 +655,8 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
 	if (ctx->suspended)
 		return;
 
-	offset = plane->src_x * bpp;
-	offset += plane->src_y * pitch;
+	offset = state->src.x * bpp;
+	offset += state->src.y * pitch;
 
 	/* buffer start address */
 	dma_addr = exynos_drm_fb_dma_addr(fb, 0) + offset;
@@ -663,18 +664,18 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
 	writel(val, ctx->regs + VIDWx_BUF_START(win, 0));
 
 	/* buffer end address */
-	size = pitch * plane->crtc_h;
+	size = pitch * state->crtc.h;
 	val = (unsigned long)(dma_addr + size);
 	writel(val, ctx->regs + VIDWx_BUF_END(win, 0));
 
 	DRM_DEBUG_KMS("start addr = 0x%lx, end addr = 0x%lx, size = 0x%lx\n",
 			(unsigned long)dma_addr, val, size);
 	DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
-			plane->crtc_w, plane->crtc_h);
+			state->crtc.w, state->crtc.h);
 
 	/* buffer size */
-	buf_offsize = pitch - (plane->crtc_w * bpp);
-	line_size = plane->crtc_w * bpp;
+	buf_offsize = pitch - (state->crtc.w * bpp);
+	line_size = state->crtc.w * bpp;
 	val = VIDW_BUF_SIZE_OFFSET(buf_offsize) |
 		VIDW_BUF_SIZE_PAGEWIDTH(line_size) |
 		VIDW_BUF_SIZE_OFFSET_E(buf_offsize) |
@@ -682,16 +683,16 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
 	writel(val, ctx->regs + VIDWx_BUF_SIZE(win, 0));
 
 	/* OSD position */
-	val = VIDOSDxA_TOPLEFT_X(plane->crtc_x) |
-		VIDOSDxA_TOPLEFT_Y(plane->crtc_y) |
-		VIDOSDxA_TOPLEFT_X_E(plane->crtc_x) |
-		VIDOSDxA_TOPLEFT_Y_E(plane->crtc_y);
+	val = VIDOSDxA_TOPLEFT_X(state->crtc.x) |
+		VIDOSDxA_TOPLEFT_Y(state->crtc.y) |
+		VIDOSDxA_TOPLEFT_X_E(state->crtc.x) |
+		VIDOSDxA_TOPLEFT_Y_E(state->crtc.y);
 	writel(val, ctx->regs + VIDOSD_A(win));
 
-	last_x = plane->crtc_x + plane->crtc_w;
+	last_x = state->crtc.x + state->crtc.w;
 	if (last_x)
 		last_x--;
-	last_y = plane->crtc_y + plane->crtc_h;
+	last_y = state->crtc.y + state->crtc.h;
 	if (last_y)
 		last_y--;
 
@@ -701,14 +702,14 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
 	writel(val, ctx->regs + VIDOSD_B(win));
 
 	DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n",
-			plane->crtc_x, plane->crtc_y, last_x, last_y);
+			state->crtc.x, state->crtc.y, last_x, last_y);
 
 	/* OSD size */
 	if (win != 3 && win != 4) {
 		u32 offset = VIDOSD_D(win);
 		if (win == 0)
 			offset = VIDOSD_C(win);
-		val = plane->crtc_w * plane->crtc_h;
+		val = state->crtc.w * state->crtc.h;
 		writel(val, ctx->regs + offset);
 
 		DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index c725409421b8..365a738042e2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -56,19 +56,35 @@ static int exynos_plane_get_size(int start, unsigned length, unsigned last)
 	return size;
 }
 
-static void exynos_plane_mode_set(struct drm_plane *plane,
-				  struct drm_crtc *crtc,
-				  struct drm_framebuffer *fb,
-				  int crtc_x, int crtc_y,
-				  unsigned int crtc_w, unsigned int crtc_h,
-				  uint32_t src_x, uint32_t src_y,
-				  uint32_t src_w, uint32_t src_h)
+static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state)
+
 {
-	struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
+	struct drm_plane_state *state = &exynos_state->base;
+	struct drm_crtc *crtc = exynos_state->base.crtc;
 	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
+	int crtc_x, crtc_y;
+	unsigned int crtc_w, crtc_h;
+	unsigned int src_x, src_y;
+	unsigned int src_w, src_h;
 	unsigned int actual_w;
 	unsigned int actual_h;
 
+	/*
+	 * The original src/dest coordinates are stored in exynos_state->base,
+	 * but we want to keep another copy internal to our driver that we can
+	 * clip/modify ourselves.
+	 */
+
+	crtc_x = state->crtc_x;
+	crtc_y = state->crtc_y;
+	crtc_w = state->crtc_w;
+	crtc_h = state->crtc_h;
+
+	src_x = state->src_x >> 16;
+	src_y = state->src_y >> 16;
+	src_w = state->src_w >> 16;
+	src_h = state->src_h >> 16;
+
 	actual_w = exynos_plane_get_size(crtc_x, crtc_w, mode->hdisplay);
 	actual_h = exynos_plane_get_size(crtc_y, crtc_h, mode->vdisplay);
 
@@ -85,46 +101,93 @@ static void exynos_plane_mode_set(struct drm_plane *plane,
 	}
 
 	/* set ratio */
-	exynos_plane->h_ratio = (src_w << 16) / crtc_w;
-	exynos_plane->v_ratio = (src_h << 16) / crtc_h;
+	exynos_state->h_ratio = (src_w << 16) / crtc_w;
+	exynos_state->v_ratio = (src_h << 16) / crtc_h;
 
 	/* set drm framebuffer data. */
-	exynos_plane->src_x = src_x;
-	exynos_plane->src_y = src_y;
-	exynos_plane->src_w = (actual_w * exynos_plane->h_ratio) >> 16;
-	exynos_plane->src_h = (actual_h * exynos_plane->v_ratio) >> 16;
+	exynos_state->src.x = src_x;
+	exynos_state->src.y = src_y;
+	exynos_state->src.w = (actual_w * exynos_state->h_ratio) >> 16;
+	exynos_state->src.h = (actual_h * exynos_state->v_ratio) >> 16;
 
 	/* set plane range to be displayed. */
-	exynos_plane->crtc_x = crtc_x;
-	exynos_plane->crtc_y = crtc_y;
-	exynos_plane->crtc_w = actual_w;
-	exynos_plane->crtc_h = actual_h;
+	exynos_state->crtc.x = crtc_x;
+	exynos_state->crtc.y = crtc_y;
+	exynos_state->crtc.w = actual_w;
+	exynos_state->crtc.h = actual_h;
 
 	DRM_DEBUG_KMS("plane : offset_x/y(%d,%d), width/height(%d,%d)",
-			exynos_plane->crtc_x, exynos_plane->crtc_y,
-			exynos_plane->crtc_w, exynos_plane->crtc_h);
+			exynos_state->crtc.x, exynos_state->crtc.y,
+			exynos_state->crtc.w, exynos_state->crtc.h);
+}
 
-	plane->crtc = crtc;
+static void exynos_drm_plane_reset(struct drm_plane *plane)
+{
+	struct exynos_drm_plane_state *exynos_state;
+
+	if (plane->state) {
+		exynos_state = to_exynos_plane_state(plane->state);
+		if (exynos_state->base.fb)
+			drm_framebuffer_unreference(exynos_state->base.fb);
+		kfree(exynos_state);
+		plane->state = NULL;
+	}
+
+	exynos_state = kzalloc(sizeof(*exynos_state), GFP_KERNEL);
+	if (exynos_state) {
+		plane->state = &exynos_state->base;
+		plane->state->plane = plane;
+	}
+}
+
+static struct drm_plane_state *
+exynos_drm_plane_duplicate_state(struct drm_plane *plane)
+{
+	struct exynos_drm_plane_state *exynos_state;
+	struct exynos_drm_plane_state *copy;
+
+	exynos_state = to_exynos_plane_state(plane->state);
+	copy = kzalloc(sizeof(*exynos_state), GFP_KERNEL);
+	if (!copy)
+		return NULL;
+
+	__drm_atomic_helper_plane_duplicate_state(plane, &copy->base);
+	return &copy->base;
+}
+
+static void exynos_drm_plane_destroy_state(struct drm_plane *plane,
+					   struct drm_plane_state *old_state)
+{
+	struct exynos_drm_plane_state *old_exynos_state =
+					to_exynos_plane_state(old_state);
+	__drm_atomic_helper_plane_destroy_state(plane, old_state);
+	kfree(old_exynos_state);
 }
 
 static struct drm_plane_funcs exynos_plane_funcs = {
 	.update_plane	= drm_atomic_helper_update_plane,
 	.disable_plane	= drm_atomic_helper_disable_plane,
 	.destroy	= drm_plane_cleanup,
-	.reset = drm_atomic_helper_plane_reset,
-	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
-	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+	.reset		= exynos_drm_plane_reset,
+	.atomic_duplicate_state = exynos_drm_plane_duplicate_state,
+	.atomic_destroy_state = exynos_drm_plane_destroy_state,
 };
 
 static int exynos_plane_atomic_check(struct drm_plane *plane,
 				     struct drm_plane_state *state)
 {
 	struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
+	struct exynos_drm_plane_state *exynos_state =
+						to_exynos_plane_state(state);
+	int ret = 0;
 
-	if (!state->fb)
+	if (!state->crtc || !state->fb)
 		return 0;
 
-	return 0;
+	/* translate state into exynos_state */
+	exynos_plane_mode_set(exynos_state);
+
+	return ret;
 }
 
 static void exynos_plane_atomic_update(struct drm_plane *plane,
@@ -137,12 +200,7 @@ static void exynos_plane_atomic_update(struct drm_plane *plane,
 	if (!state->crtc)
 		return;
 
-	exynos_plane_mode_set(plane, state->crtc, state->fb,
-			      state->crtc_x, state->crtc_y,
-			      state->crtc_w, state->crtc_h,
-			      state->src_x >> 16, state->src_y >> 16,
-			      state->src_w >> 16, state->src_h >> 16);
-
+	plane->crtc = state->crtc;
 	exynos_plane->pending_fb = state->fb;
 
 	if (exynos_crtc->ops->update_plane)
@@ -159,8 +217,7 @@ static void exynos_plane_atomic_disable(struct drm_plane *plane,
 		return;
 
 	if (exynos_crtc->ops->disable_plane)
-		exynos_crtc->ops->disable_plane(exynos_crtc,
-						exynos_plane);
+		exynos_crtc->ops->disable_plane(exynos_crtc, exynos_plane);
 }
 
 static const struct drm_plane_helper_funcs plane_helper_funcs = {
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index efb5d0435558..c3bd8cace37a 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -400,10 +400,11 @@ static void mixer_stop(struct mixer_context *ctx)
 static void vp_video_buffer(struct mixer_context *ctx,
 			    struct exynos_drm_plane *plane)
 {
+	struct exynos_drm_plane_state *state =
+				to_exynos_plane_state(plane->base.state);
 	struct mixer_resources *res = &ctx->mixer_res;
-	struct drm_plane_state *state = plane->base.state;
-	struct drm_framebuffer *fb = state->fb;
-	struct drm_display_mode *mode = &state->crtc->mode;
+	struct drm_framebuffer *fb = state->base.fb;
+	struct drm_display_mode *mode = &state->base.crtc->mode;
 	unsigned long flags;
 	dma_addr_t luma_addr[2], chroma_addr[2];
 	bool tiled_mode = false;
@@ -460,24 +461,24 @@ static void vp_video_buffer(struct mixer_context *ctx,
 	vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(fb->pitches[0]) |
 		VP_IMG_VSIZE(fb->height / 2));
 
-	vp_reg_write(res, VP_SRC_WIDTH, plane->src_w);
-	vp_reg_write(res, VP_SRC_HEIGHT, plane->src_h);
+	vp_reg_write(res, VP_SRC_WIDTH, state->src.w);
+	vp_reg_write(res, VP_SRC_HEIGHT, state->src.h);
 	vp_reg_write(res, VP_SRC_H_POSITION,
-			VP_SRC_H_POSITION_VAL(plane->src_x));
-	vp_reg_write(res, VP_SRC_V_POSITION, plane->src_y);
+			VP_SRC_H_POSITION_VAL(state->src.x));
+	vp_reg_write(res, VP_SRC_V_POSITION, state->src.y);
 
-	vp_reg_write(res, VP_DST_WIDTH, plane->crtc_w);
-	vp_reg_write(res, VP_DST_H_POSITION, plane->crtc_x);
+	vp_reg_write(res, VP_DST_WIDTH, state->crtc.w);
+	vp_reg_write(res, VP_DST_H_POSITION, state->crtc.x);
 	if (ctx->interlace) {
-		vp_reg_write(res, VP_DST_HEIGHT, plane->crtc_h / 2);
-		vp_reg_write(res, VP_DST_V_POSITION, plane->crtc_y / 2);
+		vp_reg_write(res, VP_DST_HEIGHT, state->crtc.h / 2);
+		vp_reg_write(res, VP_DST_V_POSITION, state->crtc.y / 2);
 	} else {
-		vp_reg_write(res, VP_DST_HEIGHT, plane->crtc_h);
-		vp_reg_write(res, VP_DST_V_POSITION, plane->crtc_y);
+		vp_reg_write(res, VP_DST_HEIGHT, state->crtc.h);
+		vp_reg_write(res, VP_DST_V_POSITION, state->crtc.y);
 	}
 
-	vp_reg_write(res, VP_H_RATIO, plane->h_ratio);
-	vp_reg_write(res, VP_V_RATIO, plane->v_ratio);
+	vp_reg_write(res, VP_H_RATIO, state->h_ratio);
+	vp_reg_write(res, VP_V_RATIO, state->v_ratio);
 
 	vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE);
 
@@ -509,15 +510,18 @@ static void mixer_layer_update(struct mixer_context *ctx)
 static int mixer_setup_scale(const struct exynos_drm_plane *plane,
 		unsigned int *x_ratio, unsigned int *y_ratio)
 {
-	if (plane->crtc_w != plane->src_w) {
-		if (plane->crtc_w == 2 * plane->src_w)
+	struct exynos_drm_plane_state *state =
+				to_exynos_plane_state(plane->base.state);
+
+	if (state->crtc.w != state->src.w) {
+		if (state->crtc.w == 2 * state->src.w)
 			*x_ratio = 1;
 		else
 			goto fail;
 	}
 
-	if (plane->crtc_h != plane->src_h) {
-		if (plane->crtc_h == 2 * plane->src_h)
+	if (state->crtc.h != state->src.h) {
+		if (state->crtc.h == 2 * state->src.h)
 			*y_ratio = 1;
 		else
 			goto fail;
@@ -533,10 +537,11 @@ fail:
 static void mixer_graph_buffer(struct mixer_context *ctx,
 			       struct exynos_drm_plane *plane)
 {
+	struct exynos_drm_plane_state *state =
+				to_exynos_plane_state(plane->base.state);
 	struct mixer_resources *res = &ctx->mixer_res;
-	struct drm_plane_state *state = plane->base.state;
-	struct drm_framebuffer *fb = state->fb;
-	struct drm_display_mode *mode = &state->crtc->mode;
+	struct drm_framebuffer *fb = state->base.fb;
+	struct drm_display_mode *mode = &state->base.crtc->mode;
 	unsigned long flags;
 	unsigned int win = plane->zpos;
 	unsigned int x_ratio = 0, y_ratio = 0;
@@ -572,13 +577,13 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
 	if (mixer_setup_scale(plane, &x_ratio, &y_ratio))
 		return;
 
-	dst_x_offset = plane->crtc_x;
-	dst_y_offset = plane->crtc_y;
+	dst_x_offset = state->crtc.x;
+	dst_y_offset = state->crtc.y;
 
 	/* converting dma address base and source offset */
 	dma_addr = exynos_drm_fb_dma_addr(fb, 0)
-		+ (plane->src_x * fb->bits_per_pixel >> 3)
-		+ (plane->src_y * fb->pitches[0]);
+		+ (state->src.x * fb->bits_per_pixel >> 3)
+		+ (state->src.y * fb->pitches[0]);
 	src_x_offset = 0;
 	src_y_offset = 0;
 
@@ -606,8 +611,8 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
 		mixer_reg_write(res, MXR_RESOLUTION, val);
 	}
 
-	val  = MXR_GRP_WH_WIDTH(plane->src_w);
-	val |= MXR_GRP_WH_HEIGHT(plane->src_h);
+	val  = MXR_GRP_WH_WIDTH(state->src.w);
+	val |= MXR_GRP_WH_HEIGHT(state->src.h);
 	val |= MXR_GRP_WH_H_SCALE(x_ratio);
 	val |= MXR_GRP_WH_V_SCALE(y_ratio);
 	mixer_reg_write(res, MXR_GRAPHIC_WH(win), val);
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 12/25] drm/exynos: mixer: use crtc->state->adjusted_mode instead of crtc->mode
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (10 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 11/25] drm/exynos: introduce exynos_drm_plane_state structure Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-13 11:47   ` Gustavo Padovan
  2015-11-10 13:23 ` [PATCH 13/25] drm/exynos: mixer: enable video overlay plane only when VP is available Marek Szyprowski
                   ` (15 subsequent siblings)
  27 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Javier Martinez Canillas, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, Andrzej Hajda,
	Tobias Jakobi, Marek Szyprowski

This patch replaces usage of crtc->mode with crtc->state->adjusted_mode
like it is already done in common plane code.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_mixer.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index c3bd8cace37a..a683edce5b68 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -402,9 +402,9 @@ static void vp_video_buffer(struct mixer_context *ctx,
 {
 	struct exynos_drm_plane_state *state =
 				to_exynos_plane_state(plane->base.state);
+	struct drm_display_mode *mode = &state->base.crtc->state->adjusted_mode;
 	struct mixer_resources *res = &ctx->mixer_res;
 	struct drm_framebuffer *fb = state->base.fb;
-	struct drm_display_mode *mode = &state->base.crtc->mode;
 	unsigned long flags;
 	dma_addr_t luma_addr[2], chroma_addr[2];
 	bool tiled_mode = false;
@@ -539,9 +539,9 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
 {
 	struct exynos_drm_plane_state *state =
 				to_exynos_plane_state(plane->base.state);
+	struct drm_display_mode *mode = &state->base.crtc->state->adjusted_mode;
 	struct mixer_resources *res = &ctx->mixer_res;
 	struct drm_framebuffer *fb = state->base.fb;
-	struct drm_display_mode *mode = &state->base.crtc->mode;
 	unsigned long flags;
 	unsigned int win = plane->zpos;
 	unsigned int x_ratio = 0, y_ratio = 0;
-- 
1.9.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 13/25] drm/exynos: mixer: enable video overlay plane only when VP is available
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (11 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 12/25] drm/exynos: mixer: use crtc->state->adjusted_mode instead of crtc->mode Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-13 11:49   ` Gustavo Padovan
  2015-11-10 13:23 ` [PATCH 14/25] drm/exynos: introduce exynos_drm_plane_config structure Marek Szyprowski
                   ` (14 subsequent siblings)
  27 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

Video overlay plane should be registered only when suitable hardware
sub-block (Video Processor) is available.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_mixer.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index a683edce5b68..015e85cabcc9 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1205,6 +1205,9 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data)
 		const uint32_t *formats;
 		unsigned int fcount;
 
+		if (zpos == VP_DEFAULT_WIN && !ctx->vp_enabled)
+			continue;
+
 		if (zpos < VP_DEFAULT_WIN) {
 			formats = mixer_formats;
 			fcount = ARRAY_SIZE(mixer_formats);
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 14/25] drm/exynos: introduce exynos_drm_plane_config structure
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (12 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 13/25] drm/exynos: mixer: enable video overlay plane only when VP is available Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-13 12:08   ` Gustavo Padovan
  2015-11-17 18:00   ` Tobias Jakobi
  2015-11-10 13:23 ` [PATCH 15/25] drm/exynos: add generic check for plane state Marek Szyprowski
                   ` (13 subsequent siblings)
  27 siblings, 2 replies; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

This patch adds common structure for keeping plane configuration and
capabilities data. This patch is inspired by similar code developed by
Tobias Jakobi.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 18 +++++++---
 drivers/gpu/drm/exynos/exynos7_drm_decon.c    | 23 +++++++-----
 drivers/gpu/drm/exynos/exynos_drm_drv.h       | 22 ++++++++++++
 drivers/gpu/drm/exynos/exynos_drm_fimd.c      | 25 ++++++++-----
 drivers/gpu/drm/exynos/exynos_drm_plane.c     | 34 ++++++++----------
 drivers/gpu/drm/exynos/exynos_drm_plane.h     |  7 ++--
 drivers/gpu/drm/exynos/exynos_drm_vidi.c      | 25 ++++++++-----
 drivers/gpu/drm/exynos/exynos_mixer.c         | 51 ++++++++++++++++-----------
 8 files changed, 131 insertions(+), 74 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index 27039468364b..3c8b8e0240fe 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -26,7 +26,6 @@
 #include "exynos_drm_iommu.h"
 
 #define WINDOWS_NR	3
-#define CURSOR_WIN	2
 #define MIN_FB_WIDTH_FOR_16WORD_BURST	128
 
 static const char * const decon_clks_name[] = {
@@ -57,6 +56,7 @@ struct decon_context {
 	struct drm_device		*drm_dev;
 	struct exynos_drm_crtc		*crtc;
 	struct exynos_drm_plane		planes[WINDOWS_NR];
+	struct exynos_drm_plane_config	configs[WINDOWS_NR];
 	void __iomem			*addr;
 	struct clk			*clks[ARRAY_SIZE(decon_clks_name)];
 	int				pipe;
@@ -72,6 +72,12 @@ static const uint32_t decon_formats[] = {
 	DRM_FORMAT_ARGB8888,
 };
 
+static const enum drm_plane_type decon_win_types[WINDOWS_NR] = {
+	DRM_PLANE_TYPE_PRIMARY,
+	DRM_PLANE_TYPE_OVERLAY,
+	DRM_PLANE_TYPE_CURSOR,
+};
+
 static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask,
 				  u32 val)
 {
@@ -499,7 +505,6 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
 	struct exynos_drm_private *priv = drm_dev->dev_private;
 	struct exynos_drm_plane *exynos_plane;
 	enum exynos_drm_output_type out_type;
-	enum drm_plane_type type;
 	unsigned int win;
 	int ret;
 
@@ -509,10 +514,13 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
 	for (win = ctx->first_win; win < WINDOWS_NR; win++) {
 		int tmp = (win == ctx->first_win) ? 0 : win;
 
-		type = exynos_plane_get_type(tmp, CURSOR_WIN);
+		ctx->configs[win].pixel_formats = decon_formats;
+		ctx->configs[win].num_pixel_formats = ARRAY_SIZE(decon_formats);
+		ctx->configs[win].zpos = win;
+		ctx->configs[win].type = decon_win_types[tmp];
+
 		ret = exynos_plane_init(drm_dev, &ctx->planes[win],
-				1 << ctx->pipe, type, decon_formats,
-				ARRAY_SIZE(decon_formats), win);
+					1 << ctx->pipe, &ctx->configs[win]);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index 7868d30d8eac..6b28e3f73e4e 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -41,13 +41,13 @@
 #define MIN_FB_WIDTH_FOR_16WORD_BURST 128
 
 #define WINDOWS_NR	2
-#define CURSOR_WIN	1
 
 struct decon_context {
 	struct device			*dev;
 	struct drm_device		*drm_dev;
 	struct exynos_drm_crtc		*crtc;
 	struct exynos_drm_plane		planes[WINDOWS_NR];
+	struct exynos_drm_plane_config	configs[WINDOWS_NR];
 	struct clk			*pclk;
 	struct clk			*aclk;
 	struct clk			*eclk;
@@ -82,6 +82,11 @@ static const uint32_t decon_formats[] = {
 	DRM_FORMAT_BGRA8888,
 };
 
+static const enum drm_plane_type decon_win_types[WINDOWS_NR] = {
+	DRM_PLANE_TYPE_PRIMARY,
+	DRM_PLANE_TYPE_CURSOR,
+};
+
 static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc)
 {
 	struct decon_context *ctx = crtc->ctx;
@@ -672,8 +677,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
 	struct decon_context *ctx = dev_get_drvdata(dev);
 	struct drm_device *drm_dev = data;
 	struct exynos_drm_plane *exynos_plane;
-	enum drm_plane_type type;
-	unsigned int zpos;
+	unsigned int i;
 	int ret;
 
 	ret = decon_ctx_initialize(ctx, drm_dev);
@@ -682,11 +686,14 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
 		return ret;
 	}
 
-	for (zpos = 0; zpos < WINDOWS_NR; zpos++) {
-		type = exynos_plane_get_type(zpos, CURSOR_WIN);
-		ret = exynos_plane_init(drm_dev, &ctx->planes[zpos],
-					1 << ctx->pipe, type, decon_formats,
-					ARRAY_SIZE(decon_formats), zpos);
+	for (i = 0; i < WINDOWS_NR; i++) {
+		ctx->configs[i].pixel_formats = decon_formats;
+		ctx->configs[i].num_pixel_formats = ARRAY_SIZE(decon_formats);
+		ctx->configs[i].zpos = i;
+		ctx->configs[i].type = decon_win_types[i];
+
+		ret = exynos_plane_init(drm_dev, &ctx->planes[i],
+					1 << ctx->pipe, &ctx->configs[i]);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 482ed2c2ed89..9624855128a1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -84,10 +84,32 @@ to_exynos_plane_state(struct drm_plane_state *state)
 
 struct exynos_drm_plane {
 	struct drm_plane base;
+	const struct exynos_drm_plane_config *config;
 	unsigned int zpos;
 	struct drm_framebuffer *pending_fb;
 };
 
+#define EXYNOS_DRM_PLANE_CAP_DOUBLE_X	(1 << 0)
+#define EXYNOS_DRM_PLANE_CAP_DOUBLE_Y	(1 << 1)
+
+/*
+ * Exynos DRM plane configuration structure.
+ *
+ * @zpos: z-position of the plane.
+ * @type: type of the plane (primary, cursor or overlay).
+ * @pixel_formats: supported pixel formats.
+ * @num_pixel_formats: number of elements in 'pixel_formats'.
+ * @capabilities: supported features (see EXYNOS_DRM_PLANE_CAP_*)
+ */
+
+struct exynos_drm_plane_config {
+	unsigned int zpos;
+	enum drm_plane_type type;
+	const uint32_t *pixel_formats;
+	unsigned int num_pixel_formats;
+	unsigned int capabilities;
+};
+
 /*
  * Exynos drm crtc ops
  *
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 40fa621e3963..44226b2b46c7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -88,7 +88,6 @@
 
 /* FIMD has totally five hardware windows. */
 #define WINDOWS_NR	5
-#define CURSOR_WIN	4
 
 struct fimd_driver_data {
 	unsigned int timing_base;
@@ -151,6 +150,7 @@ struct fimd_context {
 	struct drm_device		*drm_dev;
 	struct exynos_drm_crtc		*crtc;
 	struct exynos_drm_plane		planes[WINDOWS_NR];
+	struct exynos_drm_plane_config	configs[WINDOWS_NR];
 	struct clk			*bus_clk;
 	struct clk			*lcd_clk;
 	void __iomem			*regs;
@@ -188,6 +188,14 @@ static const struct of_device_id fimd_driver_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, fimd_driver_dt_match);
 
+static const enum drm_plane_type fimd_win_types[WINDOWS_NR] = {
+	DRM_PLANE_TYPE_PRIMARY,
+	DRM_PLANE_TYPE_OVERLAY,
+	DRM_PLANE_TYPE_OVERLAY,
+	DRM_PLANE_TYPE_OVERLAY,
+	DRM_PLANE_TYPE_CURSOR,
+};
+
 static const uint32_t fimd_formats[] = {
 	DRM_FORMAT_C8,
 	DRM_FORMAT_XRGB1555,
@@ -944,18 +952,19 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
 	struct drm_device *drm_dev = data;
 	struct exynos_drm_private *priv = drm_dev->dev_private;
 	struct exynos_drm_plane *exynos_plane;
-	enum drm_plane_type type;
-	unsigned int zpos;
+	unsigned int i;
 	int ret;
 
 	ctx->drm_dev = drm_dev;
 	ctx->pipe = priv->pipe++;
 
-	for (zpos = 0; zpos < WINDOWS_NR; zpos++) {
-		type = exynos_plane_get_type(zpos, CURSOR_WIN);
-		ret = exynos_plane_init(drm_dev, &ctx->planes[zpos],
-					1 << ctx->pipe, type, fimd_formats,
-					ARRAY_SIZE(fimd_formats), zpos);
+	for (i = 0; i < WINDOWS_NR; i++) {
+		ctx->configs[i].pixel_formats = fimd_formats;
+		ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats);
+		ctx->configs[i].zpos = i;
+		ctx->configs[i].type = fimd_win_types[i];
+		ret = exynos_plane_init(drm_dev, &ctx->planes[i],
+					1 << ctx->pipe, &ctx->configs[i]);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index 365a738042e2..b620d7a76799 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -246,28 +246,20 @@ static void exynos_plane_attach_zpos_property(struct drm_plane *plane,
 	drm_object_attach_property(&plane->base, prop, zpos);
 }
 
-enum drm_plane_type exynos_plane_get_type(unsigned int zpos,
-					  unsigned int cursor_win)
-{
-		if (zpos == DEFAULT_WIN)
-			return DRM_PLANE_TYPE_PRIMARY;
-		else if (zpos == cursor_win)
-			return DRM_PLANE_TYPE_CURSOR;
-		else
-			return DRM_PLANE_TYPE_OVERLAY;
-}
-
 int exynos_plane_init(struct drm_device *dev,
 		      struct exynos_drm_plane *exynos_plane,
-		      unsigned long possible_crtcs, enum drm_plane_type type,
-		      const uint32_t *formats, unsigned int fcount,
-		      unsigned int zpos)
+		      unsigned long possible_crtcs,
+		      const struct exynos_drm_plane_config *config)
 {
 	int err;
 
-	err = drm_universal_plane_init(dev, &exynos_plane->base, possible_crtcs,
-				       &exynos_plane_funcs, formats, fcount,
-				       type);
+	err = drm_universal_plane_init(dev, &exynos_plane->base,
+				       possible_crtcs,
+				       &exynos_plane_funcs,
+				       config->pixel_formats,
+				       config->num_pixel_formats,
+				       config->type);
+
 	if (err) {
 		DRM_ERROR("failed to initialize plane\n");
 		return err;
@@ -275,10 +267,12 @@ int exynos_plane_init(struct drm_device *dev,
 
 	drm_plane_helper_add(&exynos_plane->base, &plane_helper_funcs);
 
-	exynos_plane->zpos = zpos;
+	exynos_plane->zpos = config->zpos;
+	exynos_plane->config = config;
 
-	if (type == DRM_PLANE_TYPE_OVERLAY)
-		exynos_plane_attach_zpos_property(&exynos_plane->base, zpos);
+	if (config->type == DRM_PLANE_TYPE_OVERLAY)
+		exynos_plane_attach_zpos_property(&exynos_plane->base,
+						  config->zpos);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.h b/drivers/gpu/drm/exynos/exynos_drm_plane.h
index abb641e64c23..0dd096548284 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.h
@@ -9,10 +9,7 @@
  *
  */
 
-enum drm_plane_type exynos_plane_get_type(unsigned int zpos,
-					  unsigned int cursor_win);
 int exynos_plane_init(struct drm_device *dev,
 		      struct exynos_drm_plane *exynos_plane,
-		      unsigned long possible_crtcs, enum drm_plane_type type,
-		      const uint32_t *formats, unsigned int fcount,
-		      unsigned int zpos);
+		      unsigned long possible_crtcs,
+		      const struct exynos_drm_plane_config *config);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 3ce141236fad..90701647aef1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -30,7 +30,6 @@
 
 /* vidi has totally three virtual windows. */
 #define WINDOWS_NR		3
-#define CURSOR_WIN		2
 
 #define ctx_from_connector(c)	container_of(c, struct vidi_context, \
 					connector)
@@ -90,6 +89,12 @@ static const uint32_t formats[] = {
 	DRM_FORMAT_NV12,
 };
 
+static const enum drm_plane_type vidi_win_types[WINDOWS_NR] = {
+	DRM_PLANE_TYPE_PRIMARY,
+	DRM_PLANE_TYPE_OVERLAY,
+	DRM_PLANE_TYPE_CURSOR,
+};
+
 static int vidi_enable_vblank(struct exynos_drm_crtc *crtc)
 {
 	struct vidi_context *ctx = crtc->ctx;
@@ -442,17 +447,21 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
 	struct drm_device *drm_dev = data;
 	struct drm_encoder *encoder = &ctx->encoder;
 	struct exynos_drm_plane *exynos_plane;
-	enum drm_plane_type type;
-	unsigned int zpos;
+	struct exynos_drm_plane_config plane_config = { 0 };
+	unsigned int i;
 	int pipe, ret;
 
 	vidi_ctx_initialize(ctx, drm_dev);
 
-	for (zpos = 0; zpos < WINDOWS_NR; zpos++) {
-		type = exynos_plane_get_type(zpos, CURSOR_WIN);
-		ret = exynos_plane_init(drm_dev, &ctx->planes[zpos],
-					1 << ctx->pipe, type, formats,
-					ARRAY_SIZE(formats), zpos);
+	plane_config.pixel_formats = formats;
+	plane_config.num_pixel_formats = ARRAY_SIZE(formats);
+
+	for (i = 0; i < WINDOWS_NR; i++) {
+		plane_config.zpos = i;
+		plane_config.type = vidi_win_types(i);
+
+		ret = exynos_plane_init(drm_dev, &ctx->planes[i],
+					1 << ctx->pipe, &plane_config);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 015e85cabcc9..cdec3c1827c6 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -43,7 +43,6 @@
 
 #define MIXER_WIN_NR		3
 #define VP_DEFAULT_WIN		2
-#define CURSOR_WIN		1
 
 /* The pixelformats that are natively supported by the mixer. */
 #define MXR_FORMAT_RGB565	4
@@ -112,6 +111,31 @@ struct mixer_drv_data {
 	bool					has_sclk;
 };
 
+static const struct exynos_drm_plane_config plane_configs[MIXER_WIN_NR] = {
+	{
+		.zpos = 0,
+		.type = DRM_PLANE_TYPE_PRIMARY,
+		.pixel_formats = mixer_formats,
+		.num_pixel_formats = ARRAY_SIZE(mixer_formats),
+		.capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
+				EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
+	}, {
+		.zpos = 1,
+		.type = DRM_PLANE_TYPE_CURSOR,
+		.pixel_formats = mixer_formats,
+		.num_pixel_formats = ARRAY_SIZE(mixer_formats),
+		.capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
+				EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
+	}, {
+		.zpos = 2,
+		.type = DRM_PLANE_TYPE_OVERLAY,
+		.pixel_formats = vp_formats,
+		.num_pixel_formats = ARRAY_SIZE(vp_formats),
+		.capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
+				EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
+	},
+};
+
 static const u8 filter_y_horiz_tap8[] = {
 	0,	-1,	-1,	-1,	-1,	-1,	-1,	-1,
 	-1,	-1,	-1,	-1,	-1,	0,	0,	0,
@@ -1188,38 +1212,25 @@ static struct of_device_id mixer_match_types[] = {
 };
 MODULE_DEVICE_TABLE(of, mixer_match_types);
 
+
 static int mixer_bind(struct device *dev, struct device *manager, void *data)
 {
 	struct mixer_context *ctx = dev_get_drvdata(dev);
 	struct drm_device *drm_dev = data;
 	struct exynos_drm_plane *exynos_plane;
-	unsigned int zpos;
+	unsigned int i;
 	int ret;
 
 	ret = mixer_initialize(ctx, drm_dev);
 	if (ret)
 		return ret;
 
-	for (zpos = 0; zpos < MIXER_WIN_NR; zpos++) {
-		enum drm_plane_type type;
-		const uint32_t *formats;
-		unsigned int fcount;
-
-		if (zpos == VP_DEFAULT_WIN && !ctx->vp_enabled)
+	for (i = 0; i < MIXER_WIN_NR; i++) {
+		if (i == VP_DEFAULT_WIN && !ctx->vp_enabled)
 			continue;
 
-		if (zpos < VP_DEFAULT_WIN) {
-			formats = mixer_formats;
-			fcount = ARRAY_SIZE(mixer_formats);
-		} else {
-			formats = vp_formats;
-			fcount = ARRAY_SIZE(vp_formats);
-		}
-
-		type = exynos_plane_get_type(zpos, CURSOR_WIN);
-		ret = exynos_plane_init(drm_dev, &ctx->planes[zpos],
-					1 << ctx->pipe, type, formats, fcount,
-					zpos);
+		ret = exynos_plane_init(drm_dev, &ctx->planes[i],
+					1 << ctx->pipe, &plane_configs[i]);
 		if (ret)
 			return ret;
 	}
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 15/25] drm/exynos: add generic check for plane state
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (13 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 14/25] drm/exynos: introduce exynos_drm_plane_config structure Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-13 12:30   ` Gustavo Padovan
  2015-11-10 13:23 ` [PATCH 16/25] drm/exynos: mixer: use ratio precalculated in exynos_state Marek Szyprowski
                   ` (12 subsequent siblings)
  27 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

This patch adds generic check for plane state: pixel format and display
area dimensions, so drivers can always assume that they get valid plane
state to set.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_drv.h   |  2 ++
 drivers/gpu/drm/exynos/exynos_drm_plane.c | 51 +++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 9624855128a1..bee0696ccddc 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -24,6 +24,8 @@
 
 #define DEFAULT_WIN	0
 
+#define EXYNOS_BAD_PIXEL_FORMAT 0xffffffffu
+
 #define to_exynos_crtc(x)	container_of(x, struct exynos_drm_crtc, base)
 #define to_exynos_plane(x)	container_of(x, struct exynos_drm_plane, base)
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index b620d7a76799..e5af4cd5e287 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -173,6 +173,52 @@ static struct drm_plane_funcs exynos_plane_funcs = {
 	.atomic_destroy_state = exynos_drm_plane_destroy_state,
 };
 
+static int
+exynos_drm_plane_check_format(const struct exynos_drm_plane_config *config,
+			      struct exynos_drm_plane_state *state)
+{
+	uint32_t format = EXYNOS_BAD_PIXEL_FORMAT;
+	int i;
+
+	for (i = 0; i < config->num_pixel_formats; i++)
+		if (config->pixel_formats[i] == state->base.fb->pixel_format)
+			format = state->base.fb->pixel_format;
+
+	if (format == EXYNOS_BAD_PIXEL_FORMAT) {
+		DRM_DEBUG_KMS("unsupported pixel format");
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int
+exynos_drm_plane_check_size(const struct exynos_drm_plane_config *config,
+			    struct exynos_drm_plane_state *state)
+{
+	bool width_ok = false, height_ok = false;
+
+	if (state->src.w == state->crtc.w)
+		width_ok = true;
+
+	if (state->src.h == state->crtc.h)
+		height_ok = true;
+
+	if ((config->capabilities & EXYNOS_DRM_PLANE_CAP_DOUBLE_X) &&
+	    state->h_ratio == (1 << 15))
+		width_ok = true;
+
+	if ((config->capabilities & EXYNOS_DRM_PLANE_CAP_DOUBLE_Y) &&
+	    state->v_ratio == (1 << 15))
+		height_ok = true;
+
+	if (width_ok & height_ok)
+		return 0;
+
+	DRM_DEBUG_KMS("scalling is not supported");
+	return -ENOTSUPP;
+}
+
 static int exynos_plane_atomic_check(struct drm_plane *plane,
 				     struct drm_plane_state *state)
 {
@@ -187,6 +233,11 @@ static int exynos_plane_atomic_check(struct drm_plane *plane,
 	/* translate state into exynos_state */
 	exynos_plane_mode_set(exynos_state);
 
+	ret = exynos_drm_plane_check_format(exynos_plane->config, exynos_state);
+	if (ret)
+		return ret;
+
+	ret = exynos_drm_plane_check_size(exynos_plane->config, exynos_state);
 	return ret;
 }
 
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 16/25] drm/exynos: mixer: use ratio precalculated in exynos_state
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (14 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 15/25] drm/exynos: add generic check for plane state Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-13 12:35   ` Gustavo Padovan
  2015-11-10 13:23 ` [PATCH 17/25] drm/exynos: fix clipping when scalling is enabled Marek Szyprowski
                   ` (11 subsequent siblings)
  27 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

Common plane code already calculates and checks for supported scalling
modes, so additional code in mixer driver can be now removed.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_mixer.c | 33 +++------------------------------
 1 file changed, 3 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index cdec3c1827c6..467e98044751 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -531,33 +531,6 @@ static void mixer_layer_update(struct mixer_context *ctx)
 	mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
 }
 
-static int mixer_setup_scale(const struct exynos_drm_plane *plane,
-		unsigned int *x_ratio, unsigned int *y_ratio)
-{
-	struct exynos_drm_plane_state *state =
-				to_exynos_plane_state(plane->base.state);
-
-	if (state->crtc.w != state->src.w) {
-		if (state->crtc.w == 2 * state->src.w)
-			*x_ratio = 1;
-		else
-			goto fail;
-	}
-
-	if (state->crtc.h != state->src.h) {
-		if (state->crtc.h == 2 * state->src.h)
-			*y_ratio = 1;
-		else
-			goto fail;
-	}
-
-	return 0;
-
-fail:
-	DRM_DEBUG_KMS("only 2x width/height scaling of plane supported\n");
-	return -ENOTSUPP;
-}
-
 static void mixer_graph_buffer(struct mixer_context *ctx,
 			       struct exynos_drm_plane *plane)
 {
@@ -597,9 +570,9 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
 		return;
 	}
 
-	/* check if mixer supports requested scaling setup */
-	if (mixer_setup_scale(plane, &x_ratio, &y_ratio))
-		return;
+	/* ratio is already checked by common plane code */
+	x_ratio = state->h_ratio == (1 << 15);
+	y_ratio = state->v_ratio == (1 << 15);
 
 	dst_x_offset = state->crtc.x;
 	dst_y_offset = state->crtc.y;
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 17/25] drm/exynos: fix clipping when scalling is enabled
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (15 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 16/25] drm/exynos: mixer: use ratio precalculated in exynos_state Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-17 18:17   ` Tobias Jakobi
  2015-11-10 13:23 ` [PATCH 18/25] drm/exynos: fimd: fix dma burst size setting for small plane size Marek Szyprowski
                   ` (10 subsequent siblings)
  27 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

This patch fixes calculation of src x/y offset for negative crtc x/y
values when scalling is enabled. This fixes possible IOMMU fault when
scalling is enabled.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_plane.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index e5af4cd5e287..348bcec30489 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -85,25 +85,26 @@ static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state)
 	src_w = state->src_w >> 16;
 	src_h = state->src_h >> 16;
 
+	/* set ratio */
+	exynos_state->h_ratio = (src_w << 16) / crtc_w;
+	exynos_state->v_ratio = (src_h << 16) / crtc_h;
+
+	/* clip to visible area */
 	actual_w = exynos_plane_get_size(crtc_x, crtc_w, mode->hdisplay);
 	actual_h = exynos_plane_get_size(crtc_y, crtc_h, mode->vdisplay);
 
 	if (crtc_x < 0) {
 		if (actual_w)
-			src_x -= crtc_x;
+			src_x += ((-crtc_x) * exynos_state->h_ratio) >> 16;
 		crtc_x = 0;
 	}
 
 	if (crtc_y < 0) {
 		if (actual_h)
-			src_y -= crtc_y;
+			src_y += ((-crtc_y) * exynos_state->v_ratio) >> 16;
 		crtc_y = 0;
 	}
 
-	/* set ratio */
-	exynos_state->h_ratio = (src_w << 16) / crtc_w;
-	exynos_state->v_ratio = (src_h << 16) / crtc_h;
-
 	/* set drm framebuffer data. */
 	exynos_state->src.x = src_x;
 	exynos_state->src.y = src_y;
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 18/25] drm/exynos: fimd: fix dma burst size setting for small plane size
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (16 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 17/25] drm/exynos: fix clipping when scalling is enabled Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-12 15:17   ` Tobias Jakobi
  2015-11-10 13:23 ` [PATCH 19/25] drm/exynos: add fb pointer to exynos_drm_plane_state Marek Szyprowski
                   ` (9 subsequent siblings)
  27 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Javier Martinez Canillas, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, Andrzej Hajda,
	Tobias Jakobi, Marek Szyprowski

This patch fixes trashed display of buffers cropped to very small width.
Even if DMA is unstable and causes tearing when changing the burst size,
it is still better than displaying a garbage.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 44226b2b46c7..6c04ff6432d4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -487,7 +487,7 @@ static void fimd_commit(struct exynos_drm_crtc *crtc)
 
 
 static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
-				struct drm_framebuffer *fb)
+				uint32_t pixel_format, int width)
 {
 	unsigned long val;
 
@@ -498,11 +498,11 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
 	 * So the request format is ARGB8888 then change it to XRGB8888.
 	 */
 	if (ctx->driver_data->has_limited_fmt && !win) {
-		if (fb->pixel_format == DRM_FORMAT_ARGB8888)
-			fb->pixel_format = DRM_FORMAT_XRGB8888;
+		if (pixel_format == DRM_FORMAT_ARGB8888)
+			pixel_format = DRM_FORMAT_XRGB8888;
 	}
 
-	switch (fb->pixel_format) {
+	switch (pixel_format) {
 	case DRM_FORMAT_C8:
 		val |= WINCON0_BPPMODE_8BPP_PALETTE;
 		val |= WINCONx_BURSTLEN_8WORD;
@@ -538,17 +538,15 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
 		break;
 	}
 
-	DRM_DEBUG_KMS("bpp = %d\n", fb->bits_per_pixel);
-
 	/*
-	 * In case of exynos, setting dma-burst to 16Word causes permanent
-	 * tearing for very small buffers, e.g. cursor buffer. Burst Mode
-	 * switching which is based on plane size is not recommended as
-	 * plane size varies alot towards the end of the screen and rapid
-	 * movement causes unstable DMA which results into iommu crash/tear.
+	 * Setting dma-burst to 16Word causes permanent tearing for very small
+	 * buffers, e.g. cursor buffer. Burst Mode switching which based on
+	 * plane size is not recommended as plane size varies alot towards the
+	 * end of the screen and rapid movement causes unstable DMA, but it is
+	 * still better to change dma-burst than displaying garbage.
 	 */
 
-	if (fb->width < MIN_FB_WIDTH_FOR_16WORD_BURST) {
+	if (width < MIN_FB_WIDTH_FOR_16WORD_BURST) {
 		val &= ~WINCONx_BURSTLEN_MASK;
 		val |= WINCONx_BURSTLEN_4WORD;
 	}
@@ -723,7 +721,7 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
 		DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val);
 	}
 
-	fimd_win_set_pixfmt(ctx, win, fb);
+	fimd_win_set_pixfmt(ctx, win, fb->pixel_format, state->src.w);
 
 	/* hardware window 0 doesn't support color key. */
 	if (win != 0)
-- 
1.9.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 19/25] drm/exynos: add fb pointer to exynos_drm_plane_state
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (17 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 18/25] drm/exynos: fimd: fix dma burst size setting for small plane size Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-10 13:23 ` [PATCH 20/25] drm/exynos: gem: set default alignment for dumb GEM buffers Marek Szyprowski
                   ` (8 subsequent siblings)
  27 siblings, 0 replies; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

Add framebuffer pointer to exynos_drm_plane_state and tell drivers to use
it. This lets common plane code to set temporary framebuffer in the
future and drivers will use it without additional changes.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 2 +-
 drivers/gpu/drm/exynos/exynos7_drm_decon.c    | 2 +-
 drivers/gpu/drm/exynos/exynos_drm_drv.h       | 8 ++++++--
 drivers/gpu/drm/exynos/exynos_drm_fimd.c      | 2 +-
 drivers/gpu/drm/exynos/exynos_drm_plane.c     | 2 ++
 drivers/gpu/drm/exynos/exynos_mixer.c         | 4 ++--
 6 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index 3c8b8e0240fe..50c65ef6b9d3 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -269,7 +269,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
 	struct exynos_drm_plane_state *state =
 				to_exynos_plane_state(plane->base.state);
 	struct decon_context *ctx = crtc->ctx;
-	struct drm_framebuffer *fb = state->base.fb;
+	struct drm_framebuffer *fb = state->fb;
 	unsigned int win = plane->zpos;
 	unsigned int bpp = fb->bits_per_pixel >> 3;
 	unsigned int pitch = fb->pitches[0];
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index 6b28e3f73e4e..8a4d3066c992 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -407,7 +407,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
 	struct exynos_drm_plane_state *state =
 				to_exynos_plane_state(plane->base.state);
 	struct decon_context *ctx = crtc->ctx;
-	struct drm_framebuffer *fb = state->base.fb;
+	struct drm_framebuffer *fb = state->fb;
 	int padding;
 	unsigned long val, alpha;
 	unsigned int last_x;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index bee0696ccddc..9ed52b04c0ba 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -55,9 +55,12 @@ struct exynos_drm_rect {
  *       (clipped to visible part).
  * @h_ratio: horizontal scaling ratio, 16.16 fixed point
  * @v_ratio: vertical scaling ratio, 16.16 fixed point
+ * @fb: framebuffer with image data to be displayed (drivers should use this
+ *      instead of .base->fb)
  *
- * this structure consists plane state data that will be applied to hardware
- * specific overlay info.
+ * This structure consists plane state data that will be applied to hardware
+ * specific overlay info. Some data is duplicated (comparing with base state)
+ * to let common code to modify it for internal use.
  */
 
 struct exynos_drm_plane_state {
@@ -66,6 +69,7 @@ struct exynos_drm_plane_state {
 	struct exynos_drm_rect src;
 	unsigned int h_ratio;
 	unsigned int v_ratio;
+	struct drm_framebuffer *fb;
 };
 
 static inline struct exynos_drm_plane_state *
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 6c04ff6432d4..61452facc69a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -650,7 +650,7 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
 	struct exynos_drm_plane_state *state =
 				to_exynos_plane_state(plane->base.state);
 	struct fimd_context *ctx = crtc->ctx;
-	struct drm_framebuffer *fb = state->base.fb;
+	struct drm_framebuffer *fb = state->fb;
 	dma_addr_t dma_addr;
 	unsigned long val, size, offset;
 	unsigned int last_x, last_y, buf_offsize, line_size;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index 348bcec30489..c49b241cafe5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -117,6 +117,8 @@ static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state)
 	exynos_state->crtc.w = actual_w;
 	exynos_state->crtc.h = actual_h;
 
+	exynos_state->fb = state->fb;
+
 	DRM_DEBUG_KMS("plane : offset_x/y(%d,%d), width/height(%d,%d)",
 			exynos_state->crtc.x, exynos_state->crtc.y,
 			exynos_state->crtc.w, exynos_state->crtc.h);
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 467e98044751..541454c413a3 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -428,7 +428,7 @@ static void vp_video_buffer(struct mixer_context *ctx,
 				to_exynos_plane_state(plane->base.state);
 	struct drm_display_mode *mode = &state->base.crtc->state->adjusted_mode;
 	struct mixer_resources *res = &ctx->mixer_res;
-	struct drm_framebuffer *fb = state->base.fb;
+	struct drm_framebuffer *fb = state->fb;
 	unsigned long flags;
 	dma_addr_t luma_addr[2], chroma_addr[2];
 	bool tiled_mode = false;
@@ -538,7 +538,7 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
 				to_exynos_plane_state(plane->base.state);
 	struct drm_display_mode *mode = &state->base.crtc->state->adjusted_mode;
 	struct mixer_resources *res = &ctx->mixer_res;
-	struct drm_framebuffer *fb = state->base.fb;
+	struct drm_framebuffer *fb = state->fb;
 	unsigned long flags;
 	unsigned int win = plane->zpos;
 	unsigned int x_ratio = 0, y_ratio = 0;
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 20/25] drm/exynos: gem: set default alignment for dumb GEM buffers
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (18 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 19/25] drm/exynos: add fb pointer to exynos_drm_plane_state Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-10 13:23 ` [PATCH 21/25] drm/exynos: gem: remove old unused prototypes Marek Szyprowski
                   ` (7 subsequent siblings)
  27 siblings, 0 replies; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

This patch forces all GEM buffers to have pitch aligned at least to 8
pixels. This is a common requirement for various Exynos IPP blocks,
which otherwise won't be able to operate on buffers of random size.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_drv.h | 2 ++
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 9ed52b04c0ba..0890e6709f10 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -24,6 +24,8 @@
 
 #define DEFAULT_WIN	0
 
+#define EXYNOS_DRM_PITCH_ALIGN	8
+
 #define EXYNOS_BAD_PIXEL_FORMAT 0xffffffffu
 
 #define to_exynos_crtc(x)	container_of(x, struct exynos_drm_crtc, base)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 252eb301470c..b5db6e6cc043 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -417,7 +417,7 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
 	 *	with DRM_IOCTL_MODE_CREATE_DUMB command.
 	 */
 
-	args->pitch = args->width * ((args->bpp + 7) / 8);
+	args->pitch = roundup(args->width, EXYNOS_DRM_PITCH_ALIGN) * ((args->bpp + 7) / 8);
 	args->size = args->pitch * args->height;
 
 	if (is_drm_iommu_supported(dev))
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 21/25] drm/exynos: gem: remove old unused prototypes
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (19 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 20/25] drm/exynos: gem: set default alignment for dumb GEM buffers Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-10 13:23 ` [PATCH 22/25] drm/exynos: gem: simplify access to exynos gem object Marek Szyprowski
                   ` (6 subsequent siblings)
  27 siblings, 0 replies; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

This patch removes old, unused function prototypes from exynos_drm_gem.h.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_gem.h | 28 ----------------------------
 1 file changed, 28 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 37ab8b282db6..9ca5047959ec 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -55,8 +55,6 @@ struct exynos_drm_gem {
 	struct sg_table		*sgt;
 };
 
-struct page **exynos_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask);
-
 /* destroy a buffer with gem object */
 void exynos_drm_gem_destroy(struct exynos_drm_gem *exynos_gem);
 
@@ -91,10 +89,6 @@ void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
 					unsigned int gem_handle,
 					struct drm_file *filp);
 
-/* map user space allocated by malloc to pages. */
-int exynos_drm_gem_userptr_ioctl(struct drm_device *dev, void *data,
-				      struct drm_file *file_priv);
-
 /* get buffer information to memory region allocated by gem. */
 int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data,
 				      struct drm_file *file_priv);
@@ -123,28 +117,6 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
 /* set vm_flags and we can change the vm attribute to other one at here. */
 int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
 
-static inline int vma_is_io(struct vm_area_struct *vma)
-{
-	return !!(vma->vm_flags & (VM_IO | VM_PFNMAP));
-}
-
-/* get a copy of a virtual memory region. */
-struct vm_area_struct *exynos_gem_get_vma(struct vm_area_struct *vma);
-
-/* release a userspace virtual memory area. */
-void exynos_gem_put_vma(struct vm_area_struct *vma);
-
-/* get pages from user space. */
-int exynos_gem_get_pages_from_userptr(unsigned long start,
-						unsigned int npages,
-						struct page **pages,
-						struct vm_area_struct *vma);
-
-/* drop the reference to pages. */
-void exynos_gem_put_pages_to_userptr(struct page **pages,
-					unsigned int npages,
-					struct vm_area_struct *vma);
-
 /* map sgt with dma region. */
 int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev,
 				struct sg_table *sgt,
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 22/25] drm/exynos: gem: simplify access to exynos gem object
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (20 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 21/25] drm/exynos: gem: remove old unused prototypes Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-10 13:23 ` [PATCH 23/25] drm/exynos: ipp: make framework context global Marek Szyprowski
                   ` (5 subsequent siblings)
  27 siblings, 0 replies; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

Replace calls to exynos_drm_gem_get_{dma_addr,size}, by a simpler
function exynos_drm_gem_get(). This lets the caller to get access to
exynos_drm_gem object and extract any information about GEM object
without searching object tree for getting each parameter.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_g2d.c | 48 +++++++++++++-----------------
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 52 +++++----------------------------
 drivers/gpu/drm/exynos/exynos_drm_gem.h | 23 +++++----------
 drivers/gpu/drm/exynos/exynos_drm_ipp.c | 41 ++++++++++----------------
 drivers/gpu/drm/exynos/exynos_drm_ipp.h |  2 +-
 5 files changed, 52 insertions(+), 114 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index c17efdb238a6..7c83e64f9f1c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -179,7 +179,7 @@ struct g2d_buf_desc {
 struct g2d_buf_info {
 	unsigned int		map_nr;
 	enum g2d_reg_type	reg_types[MAX_REG_TYPE_NR];
-	unsigned long		handles[MAX_REG_TYPE_NR];
+	void			*obj[MAX_REG_TYPE_NR];
 	unsigned int		types[MAX_REG_TYPE_NR];
 	struct g2d_buf_desc	descs[MAX_REG_TYPE_NR];
 };
@@ -360,11 +360,10 @@ add_to_list:
 }
 
 static void g2d_userptr_put_dma_addr(struct drm_device *drm_dev,
-					unsigned long obj,
+					void *obj,
 					bool force)
 {
-	struct g2d_cmdlist_userptr *g2d_userptr =
-					(struct g2d_cmdlist_userptr *)obj;
+	struct g2d_cmdlist_userptr *g2d_userptr = obj;
 	struct page **pages;
 
 	if (!obj)
@@ -407,7 +406,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
 					unsigned long userptr,
 					unsigned long size,
 					struct drm_file *filp,
-					unsigned long *obj)
+					void **obj)
 {
 	struct drm_exynos_file_private *file_priv = filp->driver_priv;
 	struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv;
@@ -434,7 +433,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
 			 */
 			if (g2d_userptr->size == size) {
 				atomic_inc(&g2d_userptr->refcount);
-				*obj = (unsigned long)g2d_userptr;
+				*obj = g2d_userptr;
 
 				return &g2d_userptr->dma_addr;
 			}
@@ -517,7 +516,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
 		g2d_userptr->in_pool = true;
 	}
 
-	*obj = (unsigned long)g2d_userptr;
+	*obj = g2d_userptr;
 
 	return &g2d_userptr->dma_addr;
 
@@ -549,9 +548,7 @@ static void g2d_userptr_free_all(struct drm_device *drm_dev,
 
 	list_for_each_entry_safe(g2d_userptr, n, &g2d_priv->userptr_list, list)
 		if (g2d_userptr->in_pool)
-			g2d_userptr_put_dma_addr(drm_dev,
-						(unsigned long)g2d_userptr,
-						true);
+			g2d_userptr_put_dma_addr(drm_dev, g2d_userptr, true);
 
 	g2d->current_pool = 0;
 }
@@ -706,26 +703,23 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d,
 		buf_desc = &buf_info->descs[reg_type];
 
 		if (buf_info->types[reg_type] == BUF_TYPE_GEM) {
-			unsigned long size;
+			struct exynos_drm_gem *exynos_gem;
 
-			size = exynos_drm_gem_get_size(drm_dev, handle, file);
-			if (!size) {
+			exynos_gem = exynos_drm_gem_get(drm_dev, handle, file);
+			if (IS_ERR(exynos_gem)) {
 				ret = -EFAULT;
 				goto err;
 			}
 
 			if (!g2d_check_buf_desc_is_valid(buf_desc, reg_type,
-									size)) {
+							 exynos_gem->size)) {
+				exynos_drm_gem_put(drm_dev, exynos_gem);
 				ret = -EFAULT;
 				goto err;
 			}
 
-			addr = exynos_drm_gem_get_dma_addr(drm_dev, handle,
-								file);
-			if (IS_ERR(addr)) {
-				ret = -EFAULT;
-				goto err;
-			}
+			addr = &exynos_gem->dma_addr;
+			buf_info->obj[reg_type] = exynos_gem;
 		} else {
 			struct drm_exynos_g2d_userptr g2d_userptr;
 
@@ -745,7 +739,7 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d,
 							g2d_userptr.userptr,
 							g2d_userptr.size,
 							file,
-							&handle);
+							&buf_info->obj[reg_type]);
 			if (IS_ERR(addr)) {
 				ret = -EFAULT;
 				goto err;
@@ -754,7 +748,6 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d,
 
 		cmdlist->data[reg_pos + 1] = *addr;
 		buf_info->reg_types[i] = reg_type;
-		buf_info->handles[reg_type] = handle;
 	}
 
 	return 0;
@@ -775,22 +768,21 @@ static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d,
 	for (i = 0; i < buf_info->map_nr; i++) {
 		struct g2d_buf_desc *buf_desc;
 		enum g2d_reg_type reg_type;
-		unsigned long handle;
+		void *obj;
 
 		reg_type = buf_info->reg_types[i];
 
 		buf_desc = &buf_info->descs[reg_type];
-		handle = buf_info->handles[reg_type];
+		obj = buf_info->obj[reg_type];
 
 		if (buf_info->types[reg_type] == BUF_TYPE_GEM)
-			exynos_drm_gem_put_dma_addr(subdrv->drm_dev, handle,
-							filp);
+			exynos_drm_gem_put(subdrv->drm_dev, obj);
 		else
-			g2d_userptr_put_dma_addr(subdrv->drm_dev, handle,
+			g2d_userptr_put_dma_addr(subdrv->drm_dev, obj,
 							false);
 
 		buf_info->reg_types[i] = REG_TYPE_NONE;
-		buf_info->handles[reg_type] = 0;
+		buf_info->obj[reg_type] = NULL;
 		buf_info->types[reg_type] = 0;
 		memset(buf_desc, 0x00, sizeof(*buf_desc));
 	}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index b5db6e6cc043..382e65df5c03 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -169,26 +169,6 @@ void exynos_drm_gem_destroy(struct exynos_drm_gem *exynos_gem)
 	kfree(exynos_gem);
 }
 
-unsigned long exynos_drm_gem_get_size(struct drm_device *dev,
-						unsigned int gem_handle,
-						struct drm_file *file_priv)
-{
-	struct exynos_drm_gem *exynos_gem;
-	struct drm_gem_object *obj;
-
-	obj = drm_gem_object_lookup(dev, file_priv, gem_handle);
-	if (!obj) {
-		DRM_ERROR("failed to lookup gem object.\n");
-		return 0;
-	}
-
-	exynos_gem = to_exynos_gem(obj);
-
-	drm_gem_object_unreference_unlocked(obj);
-
-	return exynos_gem->size;
-}
-
 static struct exynos_drm_gem *exynos_drm_gem_init(struct drm_device *dev,
 						  unsigned long size)
 {
@@ -279,11 +259,10 @@ int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
 	return 0;
 }
 
-dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
-					unsigned int gem_handle,
-					struct drm_file *filp)
+struct exynos_drm_gem *exynos_drm_gem_get(struct drm_device *dev,
+					  unsigned int gem_handle,
+					  struct drm_file *filp)
 {
-	struct exynos_drm_gem *exynos_gem;
 	struct drm_gem_object *obj;
 
 	obj = drm_gem_object_lookup(dev, filp, gem_handle);
@@ -292,30 +271,13 @@ dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
 		return ERR_PTR(-EINVAL);
 	}
 
-	exynos_gem = to_exynos_gem(obj);
-
-	return &exynos_gem->dma_addr;
+	return to_exynos_gem(obj);
 }
 
-void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
-					unsigned int gem_handle,
-					struct drm_file *filp)
+void exynos_drm_gem_put(struct drm_device *dev,
+			struct exynos_drm_gem *exynos_gem)
 {
-	struct drm_gem_object *obj;
-
-	obj = drm_gem_object_lookup(dev, filp, gem_handle);
-	if (!obj) {
-		DRM_ERROR("failed to lookup gem object.\n");
-		return;
-	}
-
-	drm_gem_object_unreference_unlocked(obj);
-
-	/*
-	 * decrease obj->refcount one more time because we has already
-	 * increased it at exynos_drm_gem_get_dma_addr().
-	 */
-	drm_gem_object_unreference_unlocked(obj);
+	drm_gem_object_unreference_unlocked(&exynos_gem->base);
 }
 
 static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem *exynos_gem,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 9ca5047959ec..d4a49985c8ab 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -72,32 +72,25 @@ int exynos_drm_gem_create_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
+ * get exynos drm object from gem handle, this function could be used for
  * other drivers such as 2d/3d acceleration drivers.
  * with this function call, gem object reference count would be increased.
  */
-dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
-					unsigned int gem_handle,
-					struct drm_file *filp);
+struct exynos_drm_gem *exynos_drm_gem_get(struct drm_device *dev,
+					  unsigned int gem_handle,
+					  struct drm_file *filp);
 
 /*
- * put dma address from gem handle and this function could be used for
- * other drivers such as 2d/3d acceleration drivers.
- * with this function call, gem object reference count would be decreased.
+ * put exynos drm object acquired from exynos_drm_gem_get(),
+ * gem object reference count would be decreased.
  */
-void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
-					unsigned int gem_handle,
-					struct drm_file *filp);
+void exynos_drm_gem_put(struct drm_device *dev,
+			struct exynos_drm_gem *exynos_gem);
 
 /* get buffer information to memory region allocated by gem. */
 int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data,
 				      struct drm_file *file_priv);
 
-/* get buffer size to gem handle. */
-unsigned long exynos_drm_gem_get_size(struct drm_device *dev,
-						unsigned int gem_handle,
-						struct drm_file *file_priv);
-
 /* free gem object. */
 void exynos_drm_gem_free_object(struct drm_gem_object *obj);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index 408a14a9a180..0404e18d84cc 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -488,10 +488,9 @@ static int ipp_validate_mem_node(struct drm_device *drm_dev,
 		plane_size = width * height * bpp;
 		img_size += plane_size;
 
-		if (m_node->buf_info.handles[i]) {
-			size = exynos_drm_gem_get_size(drm_dev,
-					m_node->buf_info.handles[i],
-					c_node->filp);
+		if (m_node->buf_info.obj[i]) {
+			size = m_node->buf_info.obj[i]->size;
+
 			if (plane_size > size) {
 				DRM_ERROR(
 					"buffer %d is smaller than required\n",
@@ -529,10 +528,9 @@ static int ipp_put_mem_node(struct drm_device *drm_dev,
 
 	/* put gem buffer */
 	for_each_ipp_planar(i) {
-		unsigned long handle = m_node->buf_info.handles[i];
-		if (handle)
-			exynos_drm_gem_put_dma_addr(drm_dev, handle,
-							c_node->filp);
+		struct exynos_drm_gem *obj = m_node->buf_info.obj[i];
+		if (obj)
+			exynos_drm_gem_put(drm_dev, obj);
 	}
 
 	list_del(&m_node->list);
@@ -570,30 +568,23 @@ static struct drm_exynos_ipp_mem_node
 
 		/* get dma address by handle */
 		if (qbuf->handle[i]) {
-			dma_addr_t *addr;
-			unsigned long size;
+			struct exynos_drm_gem *exynos_gem;
 
-			addr = exynos_drm_gem_get_dma_addr(drm_dev,
-					qbuf->handle[i], c_node->filp);
-			if (IS_ERR(addr)) {
-				DRM_ERROR("failed to get addr.\n");
-				ipp_put_mem_node(drm_dev, c_node, m_node);
-				return ERR_PTR(-EFAULT);
-			}
+			exynos_gem = exynos_drm_gem_get(drm_dev,
+						qbuf->handle[i], c_node->filp);
 
-			size = exynos_drm_gem_get_size(drm_dev,
-					qbuf->handle[i], c_node->filp);
-			if (!size) {
-				DRM_ERROR("failed to get size.\n");
+			if (IS_ERR(exynos_gem)) {
+				DRM_ERROR("failed to get gem.\n");
 				ipp_put_mem_node(drm_dev, c_node, m_node);
 				return ERR_PTR(-EFAULT);
 			}
 
-			buf_info->handles[i] = qbuf->handle[i];
-			buf_info->base[i] = *addr;
-			buf_info->size[i] = (uint64_t)size;
+			buf_info->obj[i] = exynos_gem;
+			buf_info->base[i] = exynos_gem->dma_addr;
+			buf_info->size[i] = exynos_gem->size;
 			DRM_DEBUG_KMS("i[%d]base[%pad]hd[0x%lx]sz[%llx]\n", i,
-				      &buf_info->base[i], buf_info->handles[i],
+				      &buf_info->base[i],
+				      (long unsigned)qbuf->handle[i],
 				      buf_info->size[i]);
 		}
 	}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
index d4f0b588220b..1dc13bf57b16 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
@@ -88,7 +88,7 @@ struct drm_exynos_ipp_cmd_node {
  * @size: Y, Cb, Cr each planar size.
  */
 struct drm_exynos_ipp_buf_info {
-	unsigned long	handles[EXYNOS_DRM_PLANAR_MAX];
+	struct exynos_drm_gem	*obj[EXYNOS_DRM_PLANAR_MAX];
 	dma_addr_t	base[EXYNOS_DRM_PLANAR_MAX];
 	uint64_t	size[EXYNOS_DRM_PLANAR_MAX];
 };
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 23/25] drm/exynos: ipp: make framework context global
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (21 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 22/25] drm/exynos: gem: simplify access to exynos gem object Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-10 13:23 ` [PATCH 24/25] drm/exynos: add generic plane rotation property support Marek Szyprowski
                   ` (4 subsequent siblings)
  27 siblings, 0 replies; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Javier Martinez Canillas, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, Andrzej Hajda,
	Tobias Jakobi, Marek Szyprowski

IPP framework stored global context in driver data of its platform device.
This patch moves it to global variable to simplify access. There exists
only one such framework, so there is no drawback of this change.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_ipp.c | 50 ++++++++++-----------------------
 1 file changed, 15 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index 0404e18d84cc..44a6689e0f4c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -42,7 +42,6 @@
  * 7. need to power_on implement power and sysmmu ctrl.
  */
 
-#define get_ipp_context(dev)	platform_get_drvdata(to_platform_device(dev))
 #define ipp_is_m2m_cmd(c)	(c == IPP_CMD_M2M)
 
 /*
@@ -95,6 +94,7 @@ struct ipp_context {
 	struct workqueue_struct	*cmd_workq;
 };
 
+static struct ipp_context *ctx;
 static LIST_HEAD(exynos_drm_ippdrv_list);
 static DEFINE_MUTEX(exynos_drm_ippdrv_lock);
 static BLOCKING_NOTIFIER_HEAD(exynos_drm_ippnb_list);
@@ -226,9 +226,6 @@ static struct exynos_drm_ippdrv *ipp_find_drv_by_handle(u32 prop_id)
 int exynos_drm_ipp_get_property(struct drm_device *drm_dev, void *data,
 		struct drm_file *file)
 {
-	struct drm_exynos_file_private *file_priv = file->driver_priv;
-	struct device *dev = file_priv->ipp_dev;
-	struct ipp_context *ctx = get_ipp_context(dev);
 	struct drm_exynos_ipp_prop_list *prop_list = data;
 	struct exynos_drm_ippdrv *ippdrv;
 	int count = 0;
@@ -320,9 +317,6 @@ static struct drm_exynos_ipp_event_work *ipp_create_event_work(void)
 int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
 		struct drm_file *file)
 {
-	struct drm_exynos_file_private *file_priv = file->driver_priv;
-	struct device *dev = file_priv->ipp_dev;
-	struct ipp_context *ctx = get_ipp_context(dev);
 	struct drm_exynos_ipp_property *property = data;
 	struct exynos_drm_ippdrv *ippdrv;
 	struct drm_exynos_ipp_cmd_node *c_node;
@@ -803,22 +797,18 @@ static int ipp_set_mem_node(struct exynos_drm_ippdrv *ippdrv,
 	return ret;
 }
 
-static void ipp_handle_cmd_work(struct device *dev,
-		struct exynos_drm_ippdrv *ippdrv,
-		struct drm_exynos_ipp_cmd_work *cmd_work,
-		struct drm_exynos_ipp_cmd_node *c_node)
+static void ipp_handle_cmd_work(struct exynos_drm_ippdrv *ippdrv,
+				struct drm_exynos_ipp_cmd_work *cmd_work,
+				struct drm_exynos_ipp_cmd_node *c_node)
 {
-	struct ipp_context *ctx = get_ipp_context(dev);
-
 	cmd_work->ippdrv = ippdrv;
 	cmd_work->c_node = c_node;
 	queue_work(ctx->cmd_workq, &cmd_work->work);
 }
 
-static int ipp_queue_buf_with_run(struct device *dev,
-		struct drm_exynos_ipp_cmd_node *c_node,
-		struct drm_exynos_ipp_mem_node *m_node,
-		struct drm_exynos_ipp_queue_buf *qbuf)
+static int ipp_queue_buf_with_run(struct drm_exynos_ipp_cmd_node *c_node,
+				  struct drm_exynos_ipp_mem_node *m_node,
+				  struct drm_exynos_ipp_queue_buf *qbuf)
 {
 	struct exynos_drm_ippdrv *ippdrv;
 	struct drm_exynos_ipp_property *property;
@@ -859,7 +849,7 @@ static int ipp_queue_buf_with_run(struct device *dev,
 		struct drm_exynos_ipp_cmd_work *cmd_work = c_node->start_work;
 
 		cmd_work->ctrl = IPP_CTRL_PLAY;
-		ipp_handle_cmd_work(dev, ippdrv, cmd_work, c_node);
+		ipp_handle_cmd_work(ippdrv, cmd_work, c_node);
 	} else {
 		ret = ipp_set_mem_node(ippdrv, c_node, m_node);
 		if (ret) {
@@ -893,9 +883,6 @@ static void ipp_clean_queue_buf(struct drm_device *drm_dev,
 int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data,
 		struct drm_file *file)
 {
-	struct drm_exynos_file_private *file_priv = file->driver_priv;
-	struct device *dev = file_priv->ipp_dev;
-	struct ipp_context *ctx = get_ipp_context(dev);
 	struct drm_exynos_ipp_queue_buf *qbuf = data;
 	struct drm_exynos_ipp_cmd_node *c_node;
 	struct drm_exynos_ipp_mem_node *m_node;
@@ -950,7 +937,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data,
 			 * M2M case run play control for streaming feature.
 			 * other case set address and waiting.
 			 */
-			ret = ipp_queue_buf_with_run(dev, c_node, m_node, qbuf);
+			ret = ipp_queue_buf_with_run(c_node, m_node, qbuf);
 			if (ret) {
 				DRM_ERROR("failed to run command.\n");
 				goto err_clean_node;
@@ -1024,10 +1011,7 @@ err_status:
 int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
 		struct drm_file *file)
 {
-	struct drm_exynos_file_private *file_priv = file->driver_priv;
 	struct exynos_drm_ippdrv *ippdrv = NULL;
-	struct device *dev = file_priv->ipp_dev;
-	struct ipp_context *ctx = get_ipp_context(dev);
 	struct drm_exynos_ipp_cmd_ctrl *cmd_ctrl = data;
 	struct drm_exynos_ipp_cmd_work *cmd_work;
 	struct drm_exynos_ipp_cmd_node *c_node;
@@ -1073,12 +1057,12 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
 
 		cmd_work = c_node->start_work;
 		cmd_work->ctrl = cmd_ctrl->ctrl;
-		ipp_handle_cmd_work(dev, ippdrv, cmd_work, c_node);
+		ipp_handle_cmd_work(ippdrv, cmd_work, c_node);
 		break;
 	case IPP_CTRL_STOP:
 		cmd_work = c_node->stop_work;
 		cmd_work->ctrl = cmd_ctrl->ctrl;
-		ipp_handle_cmd_work(dev, ippdrv, cmd_work, c_node);
+		ipp_handle_cmd_work(ippdrv, cmd_work, c_node);
 
 		if (!wait_for_completion_timeout(&c_node->stop_complete,
 		    msecs_to_jiffies(300))) {
@@ -1098,7 +1082,7 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
 	case IPP_CTRL_PAUSE:
 		cmd_work = c_node->stop_work;
 		cmd_work->ctrl = cmd_ctrl->ctrl;
-		ipp_handle_cmd_work(dev, ippdrv, cmd_work, c_node);
+		ipp_handle_cmd_work(ippdrv, cmd_work, c_node);
 
 		if (!wait_for_completion_timeout(&c_node->stop_complete,
 		    msecs_to_jiffies(200))) {
@@ -1112,7 +1096,7 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
 		c_node->state = IPP_STATE_START;
 		cmd_work = c_node->start_work;
 		cmd_work->ctrl = cmd_ctrl->ctrl;
-		ipp_handle_cmd_work(dev, ippdrv, cmd_work, c_node);
+		ipp_handle_cmd_work(ippdrv, cmd_work, c_node);
 		break;
 	default:
 		DRM_ERROR("could not support this state currently.\n");
@@ -1597,7 +1581,6 @@ err_completion:
 
 static int ipp_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
 {
-	struct ipp_context *ctx = get_ipp_context(dev);
 	struct exynos_drm_ippdrv *ippdrv;
 	int ret, count = 0;
 
@@ -1649,7 +1632,6 @@ err:
 static void ipp_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
 {
 	struct exynos_drm_ippdrv *ippdrv, *t;
-	struct ipp_context *ctx = get_ipp_context(dev);
 
 	/* get ipp driver entry */
 	list_for_each_entry_safe(ippdrv, t, &exynos_drm_ippdrv_list, drv_list) {
@@ -1679,7 +1661,6 @@ static void ipp_subdrv_close(struct drm_device *drm_dev, struct device *dev,
 		struct drm_file *file)
 {
 	struct exynos_drm_ippdrv *ippdrv = NULL;
-	struct ipp_context *ctx = get_ipp_context(dev);
 	struct drm_exynos_ipp_cmd_node *c_node, *tc_node;
 	int count = 0;
 
@@ -1718,7 +1699,6 @@ static void ipp_subdrv_close(struct drm_device *drm_dev, struct device *dev,
 static int ipp_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct ipp_context *ctx;
 	struct exynos_drm_subdrv *subdrv;
 	int ret;
 
@@ -1787,8 +1767,6 @@ err_event_workq:
 
 static int ipp_remove(struct platform_device *pdev)
 {
-	struct ipp_context *ctx = platform_get_drvdata(pdev);
-
 	/* unregister sub driver */
 	exynos_drm_subdrv_unregister(&ctx->subdrv);
 
@@ -1803,6 +1781,8 @@ static int ipp_remove(struct platform_device *pdev)
 	destroy_workqueue(ctx->cmd_workq);
 	destroy_workqueue(ctx->event_workq);
 
+	ctx = NULL;
+
 	return 0;
 }
 
-- 
1.9.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 24/25] drm/exynos: add generic plane rotation property support
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (22 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 23/25] drm/exynos: ipp: make framework context global Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-10 13:23 ` [PATCH 25/25] drm/exynos: add support for plane scaling Marek Szyprowski
                   ` (3 subsequent siblings)
  27 siblings, 0 replies; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

This patch adds generic plane rotation property for all supported
drivers. This has been implemented with additional help from Exynos IPP
(Exynos Image Post-Processing subsystem) with temporary framebuffers.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/Kconfig                |   8 +
 drivers/gpu/drm/exynos/Makefile               |   1 +
 drivers/gpu/drm/exynos/exynos_drm_drv.h       |   8 +
 drivers/gpu/drm/exynos/exynos_drm_ipp.c       | 151 ++++++++++++++-
 drivers/gpu/drm/exynos/exynos_drm_ipp.h       |   4 +
 drivers/gpu/drm/exynos/exynos_drm_plane.c     |  22 ++-
 drivers/gpu/drm/exynos/exynos_drm_plane_ipp.c | 263 ++++++++++++++++++++++++++
 drivers/gpu/drm/exynos/exynos_drm_plane_ipp.h |  69 +++++++
 8 files changed, 523 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_plane_ipp.c
 create mode 100644 drivers/gpu/drm/exynos/exynos_drm_plane_ipp.h

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 83efca941388..e7d414aefbdc 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -104,6 +104,14 @@ config DRM_EXYNOS_IPP
 	help
 	  Choose this option if you want to use IPP feature for DRM.
 
+config DRM_EXYNOS_PLANE_IPP
+	depends on DRM_EXYNOS_IPP
+	bool "Use IPP framework for implementing unsupported plane properties"
+	help
+	  Choose this option if you want to let IPP framework to provide plane
+	  properties (like rotation, overlay scaling and more pixel formats),
+	  which are not supported by hardware CRTC drivers.
+
 config DRM_EXYNOS_FIMC
 	bool "FIMC"
 	depends on DRM_EXYNOS_IPP && MFD_SYSCON
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 6496532aaa91..92c3f7cac7a9 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -19,6 +19,7 @@ exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI)	+= exynos_hdmi.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI)	+= exynos_drm_vidi.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_G2D)	+= exynos_drm_g2d.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_IPP)	+= exynos_drm_ipp.o
+exynosdrm-$(CONFIG_DRM_EXYNOS_PLANE_IPP)	+= exynos_drm_plane_ipp.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_FIMC)	+= exynos_drm_fimc.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_ROTATOR)	+= exynos_drm_rotator.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_GSC)	+= exynos_drm_gsc.o
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 0890e6709f10..1d6b25330686 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -72,6 +72,12 @@ struct exynos_drm_plane_state {
 	unsigned int h_ratio;
 	unsigned int v_ratio;
 	struct drm_framebuffer *fb;
+	unsigned int rotation;
+
+	unsigned int ipp_needed;
+	struct exynos_drm_rect ipp_src;
+	struct exynos_drm_rect ipp_dst;
+	struct drm_framebuffer *ipp_fb;
 };
 
 static inline struct exynos_drm_plane_state *
@@ -95,6 +101,8 @@ struct exynos_drm_plane {
 	const struct exynos_drm_plane_config *config;
 	unsigned int zpos;
 	struct drm_framebuffer *pending_fb;
+	struct drm_framebuffer *ipp_cur_fb;
+	struct drm_framebuffer *ipp_next_fb;
 };
 
 #define EXYNOS_DRM_PLANE_CAP_DOUBLE_X	(1 << 0)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index 44a6689e0f4c..89d1c4371d39 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -20,6 +20,7 @@
 #include <drm/drmP.h>
 #include <drm/exynos_drm.h>
 #include "exynos_drm_drv.h"
+#include "exynos_drm_fb.h"
 #include "exynos_drm_gem.h"
 #include "exynos_drm_ipp.h"
 #include "exynos_drm_iommu.h"
@@ -1513,7 +1514,7 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
 
 	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);
+	wake_up(&e->base.file_priv->event_wait);
 	spin_unlock_irqrestore(&drm_dev->event_lock, flags);
 	mutex_unlock(&c_node->event_lock);
 
@@ -1579,6 +1580,154 @@ err_completion:
 		complete(&c_node->start_complete);
 }
 
+static struct drm_exynos_ipp_mem_node
+		*ipp_get_internal_mem_node(struct drm_device *drm_dev,
+		struct drm_exynos_ipp_cmd_node *c_node,
+		__u32 prop_id, enum drm_exynos_ops_id ops_id,
+		struct drm_framebuffer *fb)
+{
+	struct drm_exynos_ipp_mem_node *m_node;
+	struct drm_exynos_ipp_buf_info *buf_info;
+
+	m_node = kzalloc(sizeof(*m_node), GFP_KERNEL);
+	if (!m_node)
+		return ERR_PTR(-ENOMEM);
+
+	buf_info = &m_node->buf_info;
+
+	m_node->ops_id = ops_id;
+	m_node->prop_id = prop_id;
+	INIT_LIST_HEAD(&m_node->list);
+
+	DRM_DEBUG_KMS("m_node[0x%x]ops_id[%d]prop_id[%d]\n", (int)m_node, ops_id, prop_id);
+
+	buf_info->obj[0] = NULL;
+	buf_info->base[0] = exynos_drm_fb_dma_addr(fb, 0);
+	buf_info->size[0] = fb->pitches[0] * fb->height;
+
+	mutex_lock(&c_node->mem_lock);
+	list_add_tail(&m_node->list, &c_node->mem_list[ops_id]);
+	mutex_unlock(&c_node->mem_lock);
+
+	return m_node;
+}
+
+
+static int exynos_drm_ipp_internal_enqueue_buf(struct drm_device *drm_dev,
+		__u32 prop_id, enum drm_exynos_ops_id ops_id,
+		struct drm_framebuffer *fb)
+{
+	struct drm_exynos_ipp_cmd_node *c_node;
+	struct drm_exynos_ipp_mem_node *m_node;
+	int ret;
+	struct drm_exynos_ipp_queue_buf qbuf = {
+		.ops_id = ops_id,
+		.buf_type = IPP_BUF_ENQUEUE,
+		.prop_id = prop_id,
+	};
+
+	DRM_DEBUG_KMS("prop_id[%d]ops_id[%s]\n",
+		prop_id, ops_id ? "dst" : "src");
+
+	c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, prop_id);
+	if (!c_node) {
+		DRM_ERROR("failed to get command node.\n");
+		return -ENODEV;
+	}
+
+	m_node = ipp_get_internal_mem_node(drm_dev, c_node, prop_id,
+					   ops_id, fb);
+	if (IS_ERR(m_node)) {
+		DRM_ERROR("failed to get m_node.\n");
+		return PTR_ERR(m_node);
+	}
+
+	if (ops_id == EXYNOS_DRM_OPS_DST) {
+		ret = ipp_get_event(drm_dev, c_node, &qbuf);
+		if (ret) {
+			DRM_ERROR("failed to get event.\n");
+			goto err_clean_node;
+		}
+
+		ret = ipp_queue_buf_with_run(c_node, m_node, &qbuf);
+		if (ret) {
+			DRM_ERROR("failed to run command.\n");
+			goto err_clean_node;
+		}
+	}
+
+	return 0;
+
+err_clean_node:
+	DRM_ERROR("clean memory nodes.\n");
+
+	ipp_clean_queue_buf(drm_dev, c_node, &qbuf);
+	return ret;
+}
+
+int exynos_ipp_process_internal(struct drm_device *drm_dev,
+	struct drm_exynos_ipp_config *src_conf, struct drm_framebuffer *src_fb,
+	struct drm_exynos_ipp_config *dst_conf, struct drm_framebuffer *dst_fb)
+{
+	int ret;
+	struct drm_exynos_ipp_property property = {
+		.config = {
+			*src_conf,
+			*dst_conf,
+		},
+		.cmd = IPP_CMD_M2M,
+	};
+	struct drm_exynos_ipp_cmd_ctrl ctrl = {
+		/* .prop_id */
+		.ctrl = IPP_CTRL_PLAY,
+	};
+	struct drm_exynos_ipp_cmd_ctrl ctrl_stop = {
+		/* .prop_id */
+		.ctrl = IPP_CTRL_STOP,
+	};
+	struct drm_file virt_file = { };
+
+	INIT_LIST_HEAD(&virt_file.lhead);
+	INIT_LIST_HEAD(&virt_file.fbs);
+	mutex_init(&virt_file.fbs_lock);
+	INIT_LIST_HEAD(&virt_file.blobs);
+	INIT_LIST_HEAD(&virt_file.event_list);
+	init_waitqueue_head(&virt_file.event_wait);
+	virt_file.event_space = 4096;
+	virt_file.uid = current_euid();
+	virt_file.pid = get_pid(task_pid(current));
+	virt_file.authenticated = capable(CAP_SYS_ADMIN);
+	virt_file.lock_count = 0;
+
+	ret = exynos_drm_ipp_set_property(drm_dev, &property, &virt_file);
+	if (ret)
+		return ret;
+
+	ctrl.prop_id = property.prop_id;
+	ctrl_stop.prop_id = property.prop_id;
+
+	ret = exynos_drm_ipp_internal_enqueue_buf(drm_dev, property.prop_id,
+						  EXYNOS_DRM_OPS_SRC, src_fb);
+	if (ret)
+		goto cleanup;
+
+	ret = exynos_drm_ipp_internal_enqueue_buf(drm_dev, property.prop_id,
+						  EXYNOS_DRM_OPS_DST, dst_fb);
+	if (ret)
+		goto cleanup;
+
+	ret = exynos_drm_ipp_cmd_ctrl(drm_dev, &ctrl, &virt_file);
+	if (ret)
+		goto cleanup;
+
+	wait_event(virt_file.event_wait, !list_empty(&virt_file.event_list));
+
+cleanup:
+	exynos_drm_ipp_cmd_ctrl(drm_dev, &ctrl_stop, &virt_file);
+
+	return ret;
+}
+
 static int ipp_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
 {
 	struct exynos_drm_ippdrv *ippdrv;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
index 1dc13bf57b16..7e95437edecb 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
@@ -24,6 +24,10 @@
 #define IPP_GET_LCD_HEIGHT	_IOR('F', 303, int)
 #define IPP_SET_WRITEBACK	_IOW('F', 304, u32)
 
+int exynos_ipp_process_internal(struct drm_device *drm_dev,
+	struct drm_exynos_ipp_config *src_conf, struct drm_framebuffer *src_fb,
+	struct drm_exynos_ipp_config *dst_conf, struct drm_framebuffer *dst_fb);
+
 /* definition of state */
 enum drm_exynos_ipp_state {
 	IPP_STATE_IDLE,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index c49b241cafe5..e24285b148c2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -19,6 +19,7 @@
 #include "exynos_drm_fb.h"
 #include "exynos_drm_gem.h"
 #include "exynos_drm_plane.h"
+#include "exynos_drm_plane_ipp.h"
 
 /*
  * This function is to get X or Y size shown via screen. This needs length and
@@ -85,6 +86,8 @@ static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state)
 	src_w = state->src_w >> 16;
 	src_h = state->src_h >> 16;
 
+	exynos_plane_ipp_setup(exynos_state, &src_x, &src_y, &src_w, &src_h);
+
 	/* set ratio */
 	exynos_state->h_ratio = (src_w << 16) / crtc_w;
 	exynos_state->v_ratio = (src_h << 16) / crtc_h;
@@ -163,6 +166,13 @@ static void exynos_drm_plane_destroy_state(struct drm_plane *plane,
 {
 	struct exynos_drm_plane_state *old_exynos_state =
 					to_exynos_plane_state(old_state);
+	struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
+	/*
+	 * This is the only place in the code, where all temporary objects
+	 * used for processing are no longer used and can be freed.
+	 */
+	exynos_plane_ipp_cleanup(exynos_plane, old_exynos_state);
+
 	__drm_atomic_helper_plane_destroy_state(plane, old_state);
 	kfree(old_exynos_state);
 }
@@ -174,6 +184,7 @@ static struct drm_plane_funcs exynos_plane_funcs = {
 	.reset		= exynos_drm_plane_reset,
 	.atomic_duplicate_state = exynos_drm_plane_duplicate_state,
 	.atomic_destroy_state = exynos_drm_plane_destroy_state,
+	.set_property = drm_atomic_helper_plane_set_property,
 };
 
 static int
@@ -241,13 +252,18 @@ static int exynos_plane_atomic_check(struct drm_plane *plane,
 		return ret;
 
 	ret = exynos_drm_plane_check_size(exynos_plane->config, exynos_state);
-	return ret;
+	if (ret)
+		return ret;
+
+	return exynos_plane_ipp_check(exynos_plane, exynos_state);
 }
 
 static void exynos_plane_atomic_update(struct drm_plane *plane,
 				       struct drm_plane_state *old_state)
 {
 	struct drm_plane_state *state = plane->state;
+	struct exynos_drm_plane_state *exynos_state =
+						to_exynos_plane_state(state);
 	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(state->crtc);
 	struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
 
@@ -257,6 +273,8 @@ static void exynos_plane_atomic_update(struct drm_plane *plane,
 	plane->crtc = state->crtc;
 	exynos_plane->pending_fb = state->fb;
 
+	exynos_plane_ipp_update(exynos_plane, exynos_state);
+
 	if (exynos_crtc->ops->update_plane)
 		exynos_crtc->ops->update_plane(exynos_crtc, exynos_plane);
 }
@@ -328,5 +346,5 @@ int exynos_plane_init(struct drm_device *dev,
 		exynos_plane_attach_zpos_property(&exynos_plane->base,
 						  config->zpos);
 
-	return 0;
+	return exynos_plane_ipp_attach_properties(dev, exynos_plane);
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_plane_ipp.c
new file mode 100644
index 000000000000..126d0bde2ccf
--- /dev/null
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane_ipp.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics Co.Ltd
+ * Authors: Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <drm/drmP.h>
+
+#include <drm/exynos_drm.h>
+#include "exynos_drm_drv.h"
+#include "exynos_drm_fb.h"
+#include "exynos_drm_gem.h"
+#include "exynos_drm_ipp.h"
+#include "exynos_drm_plane.h"
+#include "exynos_drm_plane_ipp.h"
+#include "exynos_drm_iommu.h"
+
+static struct drm_framebuffer *exynos_plane_ipp_alloc_fb(struct drm_device *dev,
+					struct exynos_drm_plane_state *state)
+{
+	struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER] = { NULL };
+	struct drm_mode_fb_cmd2 mode_cmd = { 0 };
+	struct drm_framebuffer *fb;
+	unsigned int size;
+	unsigned int flags;
+
+	mode_cmd.width = state->ipp_dst.x + state->ipp_dst.w;
+	mode_cmd.height = state->ipp_dst.y + state->ipp_dst.h;
+	mode_cmd.pitches[0] = roundup(mode_cmd.width, EXYNOS_DRM_PITCH_ALIGN) *
+					(state->base.fb->bits_per_pixel >> 3);
+	mode_cmd.pixel_format = state->base.fb->pixel_format;
+
+	size = mode_cmd.height * mode_cmd.pitches[0];
+
+	if (is_drm_iommu_supported(dev))
+		flags = EXYNOS_BO_NONCONTIG | EXYNOS_BO_WC;
+	else
+		flags = EXYNOS_BO_CONTIG | EXYNOS_BO_WC;
+
+	exynos_gem[0] = exynos_drm_gem_create(dev, flags, size);
+	if (IS_ERR(exynos_gem[0]))
+		return ERR_PTR(PTR_ERR(exynos_gem[0]));
+
+	fb = exynos_drm_framebuffer_init(dev, &mode_cmd, exynos_gem, 1);
+	if (IS_ERR(fb)) {
+		exynos_drm_gem_destroy(exynos_gem[0]);
+		return fb;
+	}
+
+	return fb;
+}
+
+static bool exynos_plane_ipp_check_fb(struct drm_framebuffer *ipp_fb,
+				struct exynos_drm_plane_state *state)
+{
+	if (state->ipp_dst.x + state->ipp_dst.w <= ipp_fb->width &&
+	    state->ipp_dst.y + state->ipp_dst.h <= ipp_fb->height &&
+	    state->base.fb->pixel_format == ipp_fb->pixel_format &&
+	    state->base.fb->bits_per_pixel == ipp_fb->bits_per_pixel)
+		return true;
+	return false;
+}
+
+static int exynos_plane_ipp_transform(struct exynos_drm_plane_state *state)
+{
+	struct drm_framebuffer *src_fb = state->base.fb;
+	struct drm_framebuffer *dst_fb = state->ipp_fb;
+	struct drm_exynos_ipp_config src_config = {
+		.ops_id = EXYNOS_DRM_OPS_SRC,
+		.sz = {
+			.hsize = src_fb->pitches[0] /
+				 (src_fb->bits_per_pixel >> 3),
+			.vsize = src_fb->height,
+		},
+		.fmt = src_fb->pixel_format,
+		.pos = {
+			.x = state->ipp_src.x,
+			.y = state->ipp_src.y,
+			.w = state->ipp_src.w,
+			.h = state->ipp_src.h,
+		},
+	};
+	struct drm_exynos_ipp_config dst_config = {
+		.sz = {
+			.hsize = dst_fb->pitches[0] /
+				 (dst_fb->bits_per_pixel >> 3),
+			.vsize = dst_fb->height,
+		},
+		.fmt = dst_fb->pixel_format,
+		.pos = {
+			.x = state->ipp_dst.x,
+			.y = state->ipp_dst.y,
+			.w = state->ipp_dst.w,
+			.h = state->ipp_dst.h,
+		},
+	};
+	int degree = 0, flip = 0;
+
+	if (state->rotation & BIT(DRM_ROTATE_180))
+		degree = EXYNOS_DRM_DEGREE_180;
+	else if (state->rotation & BIT(DRM_ROTATE_90))
+		degree = EXYNOS_DRM_DEGREE_90;
+	else if (state->rotation & BIT(DRM_ROTATE_270))
+		degree = EXYNOS_DRM_DEGREE_270;
+
+	if (state->rotation & BIT(DRM_REFLECT_X))
+		flip |= EXYNOS_DRM_FLIP_HORIZONTAL;
+	if (state->rotation & BIT(DRM_REFLECT_Y))
+		flip |= EXYNOS_DRM_FLIP_VERTICAL;
+
+	dst_config.flip = flip;
+	dst_config.degree = degree;
+
+	return exynos_ipp_process_internal(src_fb->dev, &src_config, src_fb,
+					   &dst_config, dst_fb);
+}
+
+void exynos_plane_ipp_setup(struct exynos_drm_plane_state *state,
+			    unsigned int *src_x, unsigned int *src_y,
+			    unsigned int *src_w, unsigned int *src_h)
+{
+	int rotation = state->base.rotation;
+	int pre_x, pre_y, post_x, post_y;
+
+	state->rotation = rotation;
+
+	if (rotation == 0 || rotation == BIT(DRM_ROTATE_0))
+		return;
+
+	state->ipp_needed = true;
+
+	state->ipp_src.x = rounddown(*src_x, EXYNOS_DRM_PITCH_ALIGN);
+	state->ipp_src.y = rounddown(*src_y, EXYNOS_DRM_PITCH_ALIGN);
+	state->ipp_dst.x = 0;
+	state->ipp_dst.y = 0;
+
+	pre_x = *src_x & (EXYNOS_DRM_PITCH_ALIGN - 1);
+	pre_y = *src_y & (EXYNOS_DRM_PITCH_ALIGN - 1);
+
+	state->ipp_src.w = roundup(*src_w + pre_x, EXYNOS_DRM_PITCH_ALIGN);
+	state->ipp_src.h = roundup(*src_h + pre_y, EXYNOS_DRM_PITCH_ALIGN);
+	if (state->ipp_src.w > state->base.fb->pitches[0])
+		state->ipp_src.w = state->base.fb->pitches[0];
+	if (state->ipp_src.h > state->base.fb->height)
+		state->ipp_src.h = state->base.fb->height;
+
+	state->ipp_dst.w = state->ipp_src.w;
+	state->ipp_dst.h = state->ipp_src.h;
+
+	post_x = state->ipp_src.w - pre_x - *src_w;
+	post_y = state->ipp_src.h - pre_y - *src_h;
+
+	if (rotation & BIT(DRM_REFLECT_Y))
+		swap(pre_y, post_y);
+
+	if (rotation & BIT(DRM_REFLECT_X))
+		swap(pre_x, post_x);
+
+	switch (rotation & 0xf) {
+	case BIT(DRM_ROTATE_0):
+		*src_x = pre_x;
+		*src_y = pre_y;
+		break;
+	case BIT(DRM_ROTATE_90):
+		*src_x = post_y;
+		*src_y = pre_x;
+		swap(*src_w, *src_h);
+		swap(state->ipp_dst.w, state->ipp_dst.h);
+		break;
+	case BIT(DRM_ROTATE_180):
+		*src_x = post_x;
+		*src_y = post_y;
+		break;
+	case BIT(DRM_ROTATE_270):
+		*src_x = pre_y;
+		*src_y = post_x;
+		swap(*src_w, *src_h);
+		swap(state->ipp_dst.w, state->ipp_dst.h);
+		break;
+	}
+}
+
+int exynos_plane_ipp_check(struct exynos_drm_plane *plane,
+			   struct exynos_drm_plane_state *state)
+{
+	if (!state->ipp_needed)
+		return 0;
+
+	/* check if currently allocated ipp fb can be reused */
+	if (plane->ipp_next_fb &&
+		!exynos_plane_ipp_check_fb(plane->ipp_next_fb, state)) {
+		drm_framebuffer_unreference(plane->ipp_next_fb);
+		plane->ipp_next_fb = NULL;
+	}
+
+	/* allocate new ipp fb */
+	if (!plane->ipp_next_fb) {
+		struct drm_framebuffer *ipp_fb;
+
+		ipp_fb = exynos_plane_ipp_alloc_fb(plane->base.dev, state);
+		if (IS_ERR(ipp_fb))
+			return PTR_ERR(ipp_fb);
+		plane->ipp_next_fb = ipp_fb;
+	}
+
+	state->fb = state->ipp_fb = plane->ipp_next_fb;
+
+	/* perform transformation */
+	return exynos_plane_ipp_transform(state);
+}
+
+void exynos_plane_ipp_update(struct exynos_drm_plane *plane,
+			     struct exynos_drm_plane_state *state)
+{
+	if (!state->ipp_needed)
+		return;
+
+	if (plane->ipp_next_fb)
+		swap(plane->ipp_next_fb, plane->ipp_cur_fb);
+}
+
+void exynos_plane_ipp_cleanup(struct exynos_drm_plane *plane,
+			      struct exynos_drm_plane_state *old_state)
+{
+	struct exynos_drm_plane_state *state;
+
+	/* get current plane state */
+	state = to_exynos_plane_state(plane->base.state);
+
+	if (!state->ipp_needed) {
+		if (plane->ipp_cur_fb) {
+			drm_framebuffer_unreference(plane->ipp_cur_fb);
+			plane->ipp_cur_fb = NULL;
+		}
+		if (plane->ipp_next_fb) {
+			drm_framebuffer_unreference(plane->ipp_next_fb);
+			plane->ipp_next_fb = NULL;
+		}
+	}
+}
+
+int exynos_plane_ipp_attach_properties(struct drm_device *dev,
+				       struct exynos_drm_plane *plane)
+{
+	if (!dev->mode_config.rotation_property)
+		dev->mode_config.rotation_property =
+			drm_mode_create_rotation_property(dev,
+				BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_90) |
+				BIT(DRM_ROTATE_180) | BIT(DRM_ROTATE_270) |
+				BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y));
+
+	if (dev->mode_config.rotation_property)
+		drm_object_attach_property(&plane->base.base,
+					   dev->mode_config.rotation_property,
+					   BIT(DRM_ROTATE_0));
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_plane_ipp.h
new file mode 100644
index 000000000000..defb4f95e075
--- /dev/null
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane_ipp.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics Co.Ltd
+ * Authors: Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef _EXYNOS_DRM_PLANE_IPP_H_
+#define _EXYNOS_DRM_PLANE_IPP_H_
+
+#ifdef CONFIG_DRM_EXYNOS_PLANE_IPP
+
+void exynos_plane_ipp_setup(struct exynos_drm_plane_state *state,
+			    unsigned int *src_x, unsigned int *src_y,
+			    unsigned int *src_w, unsigned int *src_h);
+
+int exynos_plane_ipp_check(struct exynos_drm_plane *plane,
+			   struct exynos_drm_plane_state *state);
+
+void exynos_plane_ipp_update(struct exynos_drm_plane *plane,
+			     struct exynos_drm_plane_state *state);
+
+void exynos_plane_ipp_cleanup(struct exynos_drm_plane *plane,
+			      struct exynos_drm_plane_state *old_state);
+
+int exynos_plane_ipp_attach_properties(struct drm_device *dev,
+				       struct exynos_drm_plane *plane);
+
+#else
+
+static inline
+void exynos_plane_ipp_setup(struct exynos_drm_plane_state *state,
+			    unsigned int *src_x, unsigned int *src_y,
+			    unsigned int *src_w, unsigned int *src_h)
+{
+}
+
+static inline
+int exynos_plane_ipp_check(struct exynos_drm_plane *plane,
+			   struct exynos_drm_plane_state *state)
+{
+	return 0;
+}
+
+static inline
+void exynos_plane_ipp_update(struct exynos_drm_plane *plane,
+			     struct exynos_drm_plane_state *state)
+{
+}
+
+static inline
+void exynos_plane_ipp_cleanup(struct exynos_drm_plane *plane,
+			      struct exynos_drm_plane_state *old_state)
+{
+}
+
+static inline
+int exynos_plane_ipp_attach_properties(struct drm_device *dev,
+				       struct exynos_drm_plane *plane)
+{
+	return 0;
+}
+
+#endif
+#endif
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 25/25] drm/exynos: add support for plane scaling
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (23 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 24/25] drm/exynos: add generic plane rotation property support Marek Szyprowski
@ 2015-11-10 13:23 ` Marek Szyprowski
  2015-11-10 16:23 ` [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Tobias Jakobi
                   ` (2 subsequent siblings)
  27 siblings, 0 replies; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-10 13:23 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

This patch adds support for plane scaling. Minor changes were needed to
use existing Exynos IPP integration code for enabling scaling feature.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_plane.c     |  8 +++++---
 drivers/gpu/drm/exynos/exynos_drm_plane_ipp.c | 22 ++++++++++++++++++++--
 drivers/gpu/drm/exynos/exynos_drm_plane_ipp.h |  8 ++++++--
 3 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index e24285b148c2..0d0c451b4f6b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -57,7 +57,8 @@ static int exynos_plane_get_size(int start, unsigned length, unsigned last)
 	return size;
 }
 
-static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state)
+static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state,
+				  const struct exynos_drm_plane_config *config)
 
 {
 	struct drm_plane_state *state = &exynos_state->base;
@@ -86,7 +87,8 @@ static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state)
 	src_w = state->src_w >> 16;
 	src_h = state->src_h >> 16;
 
-	exynos_plane_ipp_setup(exynos_state, &src_x, &src_y, &src_w, &src_h);
+	exynos_plane_ipp_setup(exynos_state, config, &src_x, &src_y, &src_w,
+			       &src_h, &crtc_w, &crtc_h);
 
 	/* set ratio */
 	exynos_state->h_ratio = (src_w << 16) / crtc_w;
@@ -245,7 +247,7 @@ static int exynos_plane_atomic_check(struct drm_plane *plane,
 		return 0;
 
 	/* translate state into exynos_state */
-	exynos_plane_mode_set(exynos_state);
+	exynos_plane_mode_set(exynos_state, exynos_plane->config);
 
 	ret = exynos_drm_plane_check_format(exynos_plane->config, exynos_state);
 	if (ret)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_plane_ipp.c
index 126d0bde2ccf..2d12eb391262 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane_ipp.c
@@ -121,15 +121,24 @@ static int exynos_plane_ipp_transform(struct exynos_drm_plane_state *state)
 }
 
 void exynos_plane_ipp_setup(struct exynos_drm_plane_state *state,
+			    const struct exynos_drm_plane_config *config,
 			    unsigned int *src_x, unsigned int *src_y,
-			    unsigned int *src_w, unsigned int *src_h)
+			    unsigned int *src_w, unsigned int *src_h,
+			    unsigned int *crtc_w, unsigned int *crtc_h)
 {
 	int rotation = state->base.rotation;
 	int pre_x, pre_y, post_x, post_y;
 
 	state->rotation = rotation;
 
-	if (rotation == 0 || rotation == BIT(DRM_ROTATE_0))
+	/* check if ipp is really needed */
+	if (rotation == BIT(DRM_ROTATE_0) &&
+	    (*src_w == *crtc_w ||
+		((config->capabilities & EXYNOS_DRM_PLANE_CAP_DOUBLE_X) &&
+		*src_w * 2 == *crtc_w)) &&
+	    (*src_h == *crtc_h ||
+		((config->capabilities & EXYNOS_DRM_PLANE_CAP_DOUBLE_Y) &&
+		*src_h * 2 == *crtc_h)))
 		return;
 
 	state->ipp_needed = true;
@@ -183,6 +192,15 @@ void exynos_plane_ipp_setup(struct exynos_drm_plane_state *state,
 		swap(state->ipp_dst.w, state->ipp_dst.h);
 		break;
 	}
+
+	/* apply scalling */
+	state->ipp_dst.w = state->ipp_dst.w * *crtc_w / *src_w;
+	state->ipp_dst.h = state->ipp_dst.h * *crtc_h / *src_h;
+
+	*src_x = *src_x * *crtc_w / *src_w;
+	*src_y = *src_y * *crtc_h / *src_h;
+	*src_w = *crtc_w;
+	*src_h = *crtc_h;
 }
 
 int exynos_plane_ipp_check(struct exynos_drm_plane *plane,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_plane_ipp.h
index defb4f95e075..1709bb1a26e4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane_ipp.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane_ipp.h
@@ -15,8 +15,10 @@
 #ifdef CONFIG_DRM_EXYNOS_PLANE_IPP
 
 void exynos_plane_ipp_setup(struct exynos_drm_plane_state *state,
+			    const struct exynos_drm_plane_config *config,
 			    unsigned int *src_x, unsigned int *src_y,
-			    unsigned int *src_w, unsigned int *src_h);
+			    unsigned int *src_w, unsigned int *src_h,
+			    unsigned int *crtc_w, unsigned int *crtc_h);
 
 int exynos_plane_ipp_check(struct exynos_drm_plane *plane,
 			   struct exynos_drm_plane_state *state);
@@ -34,8 +36,10 @@ int exynos_plane_ipp_attach_properties(struct drm_device *dev,
 
 static inline
 void exynos_plane_ipp_setup(struct exynos_drm_plane_state *state,
+			    const struct exynos_drm_plane_config *config,
 			    unsigned int *src_x, unsigned int *src_y,
-			    unsigned int *src_w, unsigned int *src_h)
+			    unsigned int *src_w, unsigned int *src_h,
+			    unsigned int *crtc_w, unsigned int *crtc_h)
 {
 }
 
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (24 preceding siblings ...)
  2015-11-10 13:23 ` [PATCH 25/25] drm/exynos: add support for plane scaling Marek Szyprowski
@ 2015-11-10 16:23 ` Tobias Jakobi
  2015-11-11 22:30 ` Emil Velikov
  2015-11-12 11:14 ` Daniel Stone
  27 siblings, 0 replies; 70+ messages in thread
From: Tobias Jakobi @ 2015-11-10 16:23 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, linux-samsung-soc
  Cc: Javier Martinez Canillas, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, Andrzej Hajda

Hello Marek,

this looks very interesting. I'll try to integrate this with my mpv DRM
backend once the colorspace conversion bits are implemented.

I also wanted to suggest that using the IPP blocks (rotator, FIMC)
should be still be possible without any kind of display active. So
similar in the way I can use the G2D block without presenting anything
on the screen itself.

I'm take a closer look at the series later.

With best wishes,
Tobias




Marek Szyprowski wrote:
> Dear All,
> 
> This patch series introduces a new life into Exynos IPP (Image Post
> Processing) subsystem by integrating it (transparently for userspace
> applications) with Exynos DRM core plane management. This means that all
> CRTC drivers transparently get support for standard features of IPP
> subsystem like rotation and scaling.
> 
> Support for features not supported natively by CRTC drivers is
> implemented with a help of temporary framebuffers, where image data is
> processed by IPP subsystem before performing the scanout by a CRTC driver.
> 
> This patchset is a first version of this 'new feature' and I would like
> get some comments on the proposed approach. I plan to continue working
> on enhancing Exynos DRM drivers and especially do the cleanup the IPP
> subsystem.
> 
> Most of the new features are added by the last 2 patches. All other
> patches are bugfixes in various Exynos DRM subdrivers and significant
> core rewrite - introducing a subclass of drm_plane_state was needed and
> all drivers have been converted to use it. Some initial cleanups in IPP
> subsystem were also needed to let Exynos core to call it internally from
> the driver core. This part will be cleaned even more in the future.
> 
> 
> My solution has been tested on Exynos4412-based Odroid U3 and
> Exynos5420-based Odroid XU3. To check rotation, cropping and scaling
> I've developed a simple test application, which use atomic mode
> setting/page flipping API. You can download it here:
> 
> https://git.linaro.org/?p=people/marek.szyprowski/atomictest.git
> 
> The application draws a rectangle with test pattern and then moves it
> around the screen. To see how all mentioned features work (plane
> rotation, cropping, scaling and off-screen display), please run the
> following commands:
> 
> scaling + rotation:
> # ./atomictest -b400x300 -f60 -t100 -m2x1 -x1x1
> 
> cropping + rotation:
> # ./atomictest -b400x300 -f60 -t100 -m2x1 -c1x1
> 
> cropping + rotation + off-screen display:
> # ./atomictest -b400x300 -f60 -t100 -m2x1 -c1x1 -o400x300
> 
> scaling + cropping + rotation:
> # ./atomictest -b400x300 -f60 -t100 -m2x1 -x1x1 -c1x1 
> 
> For more information about parameters, run the application with -h
> parameter or check the source code.
> 
> 
> My TODO list (please comment the priority of those tasks):
> 
> 1. add support for color space conversion, support for foreign pixel
> formats and fb-modifiers to my plane-IPP integration code (currently
> only RGB single plane modes are supported)
> 
> 2. provide support for IPP features (framebuffer rotation, scaling,
> cropping, color space conversion) with userspace atomic API instead of
> (or together with) Exynos custom IPP ioctls; the important question is
> weather the existing Exynos IPP API (userspace ioctls) should be kept or
> can be removed (existing userspace API is misleading in many aspects).
> 
> 3. simplify IPP subsystem core (the code looks over-engineered a bit,
> there are also some known issues with error paths), remove
> non-functional write-back and output modes
> 
> 4. simplify interface to IPP HW-specific mem2mem subdrivers
> 
> 5. implement output mode for IPP sub-drivers, use it where possible
> instead of using temporary framebuffer (image data is then transferred
> directly from scaling hw block to display engine via local path, no
> temporary framebuffers are needed)
> 
> 6. implement write-back feature with atomic API as respective CRTC
> properties
> 
> 
> Patches have been prepared on top of linux-next from 10-11-2015. First
> 2 patches should be applied to Samsung SoC tree, all other should go
> to Exynos DRM tree.
> 
> Best regards
> Marek Szyprowski
> Samsung R&D Institute Poland
> 
> 
> Patch summary:
> 
> Marek Szyprowski (21):
>   ARM: dts: exynos4: add rotator nodes
>   ARM: dts: exynos542x: add rotator node
>   drm/exynos: gsc: add device tree support and remove usage of static
>     mappings
>   drm/exynos: rotator: convert to common clock framework
>   drm/exynos: exynos7-decon: remove excessive check
>   drm/exynos: move dma_addr attribute from exynos plane to exynos fb
>   drm/exynos: introduce exynos_drm_plane_state structure
>   drm/exynos: mixer: use crtc->state->adjusted_mode instead of
>     crtc->mode
>   drm/exynos: mixer: enable video overlay plane only when VP is
>     available
>   drm/exynos: introduce exynos_drm_plane_config structure
>   drm/exynos: add generic check for plane state
>   drm/exynos: mixer: use ratio precalculated in exynos_state
>   drm/exynos: fix clipping when scalling is enabled
>   drm/exynos: fimd: fix dma burst size setting for small plane size
>   drm/exynos: add fb pointer to exynos_drm_plane_state
>   drm/exynos: gem: set default alignment for dumb GEM buffers
>   drm/exynos: gem: remove old unused prototypes
>   drm/exynos: gem: simplify access to exynos gem object
>   drm/exynos: ipp: make framework context global
>   drm/exynos: add generic plane rotation property support
>   drm/exynos: add support for plane scaling
> 
> Seung-Woo Kim (4):
>   drm/exynos: gsc: prepare and unprepare gsc clock
>   drm/exynos: gsc: fix wrong pm_runtime state
>   drm/exynos: fix to calculate offset of each plane for ipp fimc
>   drm/exynos: fix to calculate offset of each plane for ipp gsc
> 
>  .../devicetree/bindings/media/exynos5-gsc.txt      |   4 +
>  arch/arm/boot/dts/exynos4.dtsi                     |  10 +-
>  arch/arm/boot/dts/exynos4210.dtsi                  |   8 +
>  arch/arm/boot/dts/exynos4x12.dtsi                  |   4 +
>  arch/arm/boot/dts/exynos5420.dtsi                  |  19 ++
>  drivers/gpu/drm/exynos/Kconfig                     |  10 +-
>  drivers/gpu/drm/exynos/Makefile                    |   1 +
>  drivers/gpu/drm/exynos/exynos5433_drm_decon.c      |  48 ++--
>  drivers/gpu/drm/exynos/exynos7_drm_decon.c         |  68 ++---
>  drivers/gpu/drm/exynos/exynos_drm_drv.h            |  97 +++++--
>  drivers/gpu/drm/exynos/exynos_drm_fb.c             |  16 +-
>  drivers/gpu/drm/exynos/exynos_drm_fb.h             |   3 +-
>  drivers/gpu/drm/exynos/exynos_drm_fimc.c           | 106 ++++++++
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c           |  88 ++++---
>  drivers/gpu/drm/exynos/exynos_drm_g2d.c            |  48 ++--
>  drivers/gpu/drm/exynos/exynos_drm_gem.c            |  54 +---
>  drivers/gpu/drm/exynos/exynos_drm_gem.h            |  51 +---
>  drivers/gpu/drm/exynos/exynos_drm_gsc.c            | 151 ++++++++++-
>  drivers/gpu/drm/exynos/exynos_drm_ipp.c            | 237 +++++++++++++----
>  drivers/gpu/drm/exynos/exynos_drm_ipp.h            |   8 +-
>  drivers/gpu/drm/exynos/exynos_drm_plane.c          | 255 +++++++++++++------
>  drivers/gpu/drm/exynos/exynos_drm_plane.h          |   7 +-
>  drivers/gpu/drm/exynos/exynos_drm_plane_ipp.c      | 281 +++++++++++++++++++++
>  drivers/gpu/drm/exynos/exynos_drm_plane_ipp.h      |  73 ++++++
>  drivers/gpu/drm/exynos/exynos_drm_rotator.c        |   4 +-
>  drivers/gpu/drm/exynos/exynos_drm_vidi.c           |  30 ++-
>  drivers/gpu/drm/exynos/exynos_mixer.c              | 133 +++++-----
>  drivers/gpu/drm/exynos/regs-gsc.h                  |   4 +-
>  28 files changed, 1348 insertions(+), 470 deletions(-)
>  create mode 100644 drivers/gpu/drm/exynos/exynos_drm_plane_ipp.c
>  create mode 100644 drivers/gpu/drm/exynos/exynos_drm_plane_ipp.h
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (25 preceding siblings ...)
  2015-11-10 16:23 ` [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Tobias Jakobi
@ 2015-11-11 22:30 ` Emil Velikov
  2015-11-12 11:14 ` Daniel Stone
  27 siblings, 0 replies; 70+ messages in thread
From: Emil Velikov @ 2015-11-11 22:30 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: ML dri-devel, moderated list:ARM/S5P EXYNOS AR...,
	Javier Martinez Canillas, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, Andrzej Hajda,
	Tobias Jakobi

Hello Marek,

On 10 November 2015 at 13:23, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> Dear All,
>
> This patch series introduces a new life into Exynos IPP (Image Post
> Processing) subsystem by integrating it (transparently for userspace
> applications) with Exynos DRM core plane management. This means that all
> CRTC drivers transparently get support for standard features of IPP
> subsystem like rotation and scaling.
>
> Support for features not supported natively by CRTC drivers is
> implemented with a help of temporary framebuffers, where image data is
> processed by IPP subsystem before performing the scanout by a CRTC driver.
>
> This patchset is a first version of this 'new feature' and I would like
> get some comments on the proposed approach. I plan to continue working
> on enhancing Exynos DRM drivers and especially do the cleanup the IPP
> subsystem.
>
> Most of the new features are added by the last 2 patches. All other
> patches are bugfixes in various Exynos DRM subdrivers and significant
> core rewrite - introducing a subclass of drm_plane_state was needed and
> all drivers have been converted to use it. Some initial cleanups in IPP
> subsystem were also needed to let Exynos core to call it internally from
> the driver core. This part will be cleaned even more in the future.
>
>
> My solution has been tested on Exynos4412-based Odroid U3 and
> Exynos5420-based Odroid XU3. To check rotation, cropping and scaling
> I've developed a simple test application, which use atomic mode
> setting/page flipping API. You can download it here:
>
> https://git.linaro.org/?p=people/marek.szyprowski/atomictest.git
>
Can I interest you in up-streaming this code into place such as libdrm
? This way other developers can benefit from your tool.

Admittedly I've not looked at the tool but it seems to me that it
duplicates some of the functionality we already in modetest (+atomic).
The latter of which send by your colleague Hyungwon Hwang [1] (and I
seemingly forgot do a final review/push). If you can share a few
cycles worth of review and/or importing your app.

Thanks
Emil

[1] http://lists.freedesktop.org/archives/dri-devel/2015-September/090748.html

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem
  2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
                   ` (26 preceding siblings ...)
  2015-11-11 22:30 ` Emil Velikov
@ 2015-11-12 11:14 ` Daniel Stone
  2015-11-12 12:44   ` Tobias Jakobi
  27 siblings, 1 reply; 70+ messages in thread
From: Daniel Stone @ 2015-11-12 11:14 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: dri-devel, linux-samsung-soc, Javier Martinez Canillas,
	Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz, Seung-Woo Kim,
	Andrzej Hajda, Tobias Jakobi, Daniel Vetter, eric

Hi Marek,

On 10 November 2015 at 13:23, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> This patch series introduces a new life into Exynos IPP (Image Post
> Processing) subsystem by integrating it (transparently for userspace
> applications) with Exynos DRM core plane management. This means that all
> CRTC drivers transparently get support for standard features of IPP
> subsystem like rotation and scaling.
>
> Support for features not supported natively by CRTC drivers is
> implemented with a help of temporary framebuffers, where image data is
> processed by IPP subsystem before performing the scanout by a CRTC driver.
>
> This patchset is a first version of this 'new feature' and I would like
> get some comments on the proposed approach. I plan to continue working
> on enhancing Exynos DRM drivers and especially do the cleanup the IPP
> subsystem.
>
> Most of the new features are added by the last 2 patches. All other
> patches are bugfixes in various Exynos DRM subdrivers and significant
> core rewrite - introducing a subclass of drm_plane_state was needed and
> all drivers have been converted to use it. Some initial cleanups in IPP
> subsystem were also needed to let Exynos core to call it internally from
> the driver core. This part will be cleaned even more in the future.

Hm, interesting. The RPi has a similar setup - VC4 can work either
online (realtime scanout) or offline (mem2mem). Once the scene crosses
a certain complexity boundary, it can no longer be composed in
realtime and must fall back to mem2mem before it can be displayed.

There was talk of having the fallback handled transparently in KMS for
VC4 - similar to this - but the conclusion seemed to be that it was an
inappropriate level of hidden complexity for KMS, and instead would
best be handled by something like HWComposer directing it. Using HWC
would then let you more intelligently split the scene from userspace
(e.g. flatten some components but retain others as active planes).

Dan V, Eric - thoughts?

Cheers,
Daniel

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem
  2015-11-12 11:14 ` Daniel Stone
@ 2015-11-12 12:44   ` Tobias Jakobi
  2015-11-12 14:46     ` Daniel Stone
  0 siblings, 1 reply; 70+ messages in thread
From: Tobias Jakobi @ 2015-11-12 12:44 UTC (permalink / raw)
  To: Daniel Stone, Marek Szyprowski
  Cc: Krzysztof Kozlowski, linux-samsung-soc,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, dri-devel,
	Andrzej Hajda, Javier Martinez Canillas

Hello,


Daniel Stone wrote:
> Hi Marek,
> 
> On 10 November 2015 at 13:23, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>> This patch series introduces a new life into Exynos IPP (Image Post
>> Processing) subsystem by integrating it (transparently for userspace
>> applications) with Exynos DRM core plane management. This means that all
>> CRTC drivers transparently get support for standard features of IPP
>> subsystem like rotation and scaling.
>>
>> Support for features not supported natively by CRTC drivers is
>> implemented with a help of temporary framebuffers, where image data is
>> processed by IPP subsystem before performing the scanout by a CRTC driver.
>>
>> This patchset is a first version of this 'new feature' and I would like
>> get some comments on the proposed approach. I plan to continue working
>> on enhancing Exynos DRM drivers and especially do the cleanup the IPP
>> subsystem.
>>
>> Most of the new features are added by the last 2 patches. All other
>> patches are bugfixes in various Exynos DRM subdrivers and significant
>> core rewrite - introducing a subclass of drm_plane_state was needed and
>> all drivers have been converted to use it. Some initial cleanups in IPP
>> subsystem were also needed to let Exynos core to call it internally from
>> the driver core. This part will be cleaned even more in the future.
> 
> Hm, interesting. The RPi has a similar setup - VC4 can work either
> online (realtime scanout) or offline (mem2mem). Once the scene crosses
> a certain complexity boundary, it can no longer be composed in
> realtime and must fall back to mem2mem before it can be displayed.
> 
> There was talk of having the fallback handled transparently in KMS for
> VC4 - similar to this - but the conclusion seemed to be that it was an
> inappropriate level of hidden complexity for KMS, and instead would
> best be handled by something like HWComposer directing it. Using HWC
> would then let you more intelligently split the scene from userspace
> (e.g. flatten some components but retain others as active planes).
I would be intererested in the performance implications of this
abstraction as well.

I'd like to use the Exynos FIMC for CSC and scaling, but this operation
of course takes some time.

I wonder how this interacts with page flipping. If I queue a pageflip
event with a buffer that needs to go through the IPP for display, where
does the delay caused by the operation factor it? If I understand this
correctly drmModePageFlip() still is going to return immediately, but I
might miss the next vblank period because the FIMC is still working on
the buffer.

My problem here is that this abstraction would take too much control
from the user.

Correct me if I have this wrong!


With best wishes,
Tobias


> 
> Dan V, Eric - thoughts?
> 
> Cheers,
> Daniel
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem
  2015-11-12 12:44   ` Tobias Jakobi
@ 2015-11-12 14:46     ` Daniel Stone
  2015-11-12 15:10       ` Tobias Jakobi
  2015-11-16 11:35       ` Marek Szyprowski
  0 siblings, 2 replies; 70+ messages in thread
From: Daniel Stone @ 2015-11-12 14:46 UTC (permalink / raw)
  To: Tobias Jakobi
  Cc: Marek Szyprowski, dri-devel, linux-samsung-soc,
	Javier Martinez Canillas, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, Andrzej Hajda,
	Daniel Vetter, Eric Anholt

Hi,

On 12 November 2015 at 12:44, Tobias Jakobi
<tjakobi@math.uni-bielefeld.de> wrote:
> Daniel Stone wrote:
>> On 10 November 2015 at 13:23, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>>> This patch series introduces a new life into Exynos IPP (Image Post
>>> Processing) subsystem by integrating it (transparently for userspace
>>> applications) with Exynos DRM core plane management. This means that all
>>> CRTC drivers transparently get support for standard features of IPP
>>> subsystem like rotation and scaling.
>>>
>>> Support for features not supported natively by CRTC drivers is
>>> implemented with a help of temporary framebuffers, where image data is
>>> processed by IPP subsystem before performing the scanout by a CRTC driver.
>>
>> Hm, interesting. The RPi has a similar setup - VC4 can work either
>> online (realtime scanout) or offline (mem2mem). Once the scene crosses
>> a certain complexity boundary, it can no longer be composed in
>> realtime and must fall back to mem2mem before it can be displayed.
>>
>> There was talk of having the fallback handled transparently in KMS for
>> VC4 - similar to this - but the conclusion seemed to be that it was an
>> inappropriate level of hidden complexity for KMS, and instead would
>> best be handled by something like HWComposer directing it. Using HWC
>> would then let you more intelligently split the scene from userspace
>> (e.g. flatten some components but retain others as active planes).
> I would be intererested in the performance implications of this
> abstraction as well.
>
> I'd like to use the Exynos FIMC for CSC and scaling, but this operation
> of course takes some time.
>
> I wonder how this interacts with page flipping. If I queue a pageflip
> event with a buffer that needs to go through the IPP for display, where
> does the delay caused by the operation factor it? If I understand this
> correctly drmModePageFlip() still is going to return immediately, but I
> might miss the next vblank period because the FIMC is still working on
> the buffer.

Hmm, from my reading of the patches, this didn't affect page-flip
timings. In the sync case, it would block until the buffer was
actually displayed, and in the async case, the event would still be
delivered at the right time. But you're right that it does introduce
hugely variable timings, which can be a problem for userspace which
tries to be intelligent. And even then potentially misleading from a
performance point of view: if userspace can rotate natively (e.g. as
part of a composition blit, or when rendering buffers in the first
place), then we can skip the extra work from G2D.

> My problem here is that this abstraction would take too much control
> from the user.
>
> Correct me if I have this wrong!

I believe that was the concern previously, yeah. :) That, and encoding
these semantics in a user-visible way could potentially be dangerous.

Cheers,
Daniel

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem
  2015-11-12 14:46     ` Daniel Stone
@ 2015-11-12 15:10       ` Tobias Jakobi
  2015-11-16 11:35       ` Marek Szyprowski
  1 sibling, 0 replies; 70+ messages in thread
From: Tobias Jakobi @ 2015-11-12 15:10 UTC (permalink / raw)
  To: Daniel Stone
  Cc: Marek Szyprowski, dri-devel, linux-samsung-soc,
	Javier Martinez Canillas, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, Andrzej Hajda,
	Daniel Vetter, Eric Anholt

Hey Daniel,


Daniel Stone wrote:
> Hi,
> 
> On 12 November 2015 at 12:44, Tobias Jakobi
> <tjakobi@math.uni-bielefeld.de> wrote:
>> Daniel Stone wrote:
>>> On 10 November 2015 at 13:23, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>>>> This patch series introduces a new life into Exynos IPP (Image Post
>>>> Processing) subsystem by integrating it (transparently for userspace
>>>> applications) with Exynos DRM core plane management. This means that all
>>>> CRTC drivers transparently get support for standard features of IPP
>>>> subsystem like rotation and scaling.
>>>>
>>>> Support for features not supported natively by CRTC drivers is
>>>> implemented with a help of temporary framebuffers, where image data is
>>>> processed by IPP subsystem before performing the scanout by a CRTC driver.
>>>
>>> Hm, interesting. The RPi has a similar setup - VC4 can work either
>>> online (realtime scanout) or offline (mem2mem). Once the scene crosses
>>> a certain complexity boundary, it can no longer be composed in
>>> realtime and must fall back to mem2mem before it can be displayed.
>>>
>>> There was talk of having the fallback handled transparently in KMS for
>>> VC4 - similar to this - but the conclusion seemed to be that it was an
>>> inappropriate level of hidden complexity for KMS, and instead would
>>> best be handled by something like HWComposer directing it. Using HWC
>>> would then let you more intelligently split the scene from userspace
>>> (e.g. flatten some components but retain others as active planes).
>> I would be intererested in the performance implications of this
>> abstraction as well.
>>
>> I'd like to use the Exynos FIMC for CSC and scaling, but this operation
>> of course takes some time.
>>
>> I wonder how this interacts with page flipping. If I queue a pageflip
>> event with a buffer that needs to go through the IPP for display, where
>> does the delay caused by the operation factor it? If I understand this
>> correctly drmModePageFlip() still is going to return immediately, but I
>> might miss the next vblank period because the FIMC is still working on
>> the buffer.
> 
> Hmm, from my reading of the patches, this didn't affect page-flip
> timings. In the sync case, it would block until the buffer was
> actually displayed, and in the async case, the event would still be
> delivered at the right time. But you're right that it does introduce
> hugely variable timings, which can be a problem for userspace which
> tries to be intelligent.
I guess this is an issue then, since the FIMC is mainly used in the
context of converting video frames. And a good video player probably
wants to have tight control over the presentation of video frames, to
control A/V sychronization and so on.



> And even then potentially misleading from a
> performance point of view: if userspace can rotate natively (e.g. as
> part of a composition blit, or when rendering buffers in the first
> place), then we can skip the extra work from G2D.
> 
>> My problem here is that this abstraction would take too much control
>> from the user.
>>
>> Correct me if I have this wrong!
> 
> I believe that was the concern previously, yeah. :) That, and encoding
> these semantics in a user-visible way could potentially be dangerous.
I guess the local path transfers would still make sense though, but if I
understand this correctly this would affect FIMD.


With best wishes,
Tobias



> 
> Cheers,
> Daniel
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 03/25] drm/exynos: gsc: prepare and unprepare gsc clock
  2015-11-10 13:23 ` [PATCH 03/25] drm/exynos: gsc: prepare and unprepare gsc clock Marek Szyprowski
@ 2015-11-12 15:11   ` Gustavo Padovan
  0 siblings, 0 replies; 70+ messages in thread
From: Gustavo Padovan @ 2015-11-12 15:11 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: dri-devel, linux-samsung-soc, Inki Dae, Joonyoung Shim,
	Seung-Woo Kim, Andrzej Hajda, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Tobias Jakobi,
	Javier Martinez Canillas

Hi Marek,

2015-11-10 Marek Szyprowski <m.szyprowski@samsung.com>:

> From: Seung-Woo Kim <sw0312.kim@samsung.com>
> 
> Ths patch changes the clk_enable and clk_disable call in gsc driver
> into clk_prepare_enable and clk_disable_unprepare.
> 
> Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_gsc.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

	Gustavo

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 04/25] drm/exynos: gsc: fix wrong pm_runtime state
  2015-11-10 13:23 ` [PATCH 04/25] drm/exynos: gsc: fix wrong pm_runtime state Marek Szyprowski
@ 2015-11-12 15:12   ` Gustavo Padovan
  0 siblings, 0 replies; 70+ messages in thread
From: Gustavo Padovan @ 2015-11-12 15:12 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Javier Martinez Canillas, Krzysztof Kozlowski, linux-samsung-soc,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, dri-devel,
	Andrzej Hajda, Tobias Jakobi

Hi Marek,

2015-11-10 Marek Szyprowski <m.szyprowski@samsung.com>:

> From: Seung-Woo Kim <sw0312.kim@samsung.com>
> 
> At probe time, gsc clock is not enabled, so pm_runtime state should
> be deactive. So this patch removes pm_runtime_set_active() from
> gsc_probe().
> 
> Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_gsc.c | 1 -
>  1 file changed, 1 deletion(-)

Reviewed-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

	Gustavo
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 18/25] drm/exynos: fimd: fix dma burst size setting for small plane size
  2015-11-10 13:23 ` [PATCH 18/25] drm/exynos: fimd: fix dma burst size setting for small plane size Marek Szyprowski
@ 2015-11-12 15:17   ` Tobias Jakobi
  2015-11-12 15:23     ` Daniel Stone
  0 siblings, 1 reply; 70+ messages in thread
From: Tobias Jakobi @ 2015-11-12 15:17 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, linux-samsung-soc
  Cc: Inki Dae, Joonyoung Shim, Seung-Woo Kim, Andrzej Hajda,
	Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz, Gustavo Padovan,
	Javier Martinez Canillas

This one looks a bit strange. It only changes the argument list of
fimd_win_set_pixfmt() but the commit message that it actually fixes
something.

The corresponding upstream commit:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=66367461e573321f0fbb0be0391165b5a54d5fe4

With best wishes,
Tobias


Marek Szyprowski wrote:
> This patch fixes trashed display of buffers cropped to very small width.
> Even if DMA is unstable and causes tearing when changing the burst size,
> it is still better than displaying a garbage.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c | 24 +++++++++++-------------
>  1 file changed, 11 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> index 44226b2b46c7..6c04ff6432d4 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> @@ -487,7 +487,7 @@ static void fimd_commit(struct exynos_drm_crtc *crtc)
>  
>  
>  static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
> -				struct drm_framebuffer *fb)
> +				uint32_t pixel_format, int width)
>  {
>  	unsigned long val;
>  
> @@ -498,11 +498,11 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
>  	 * So the request format is ARGB8888 then change it to XRGB8888.
>  	 */
>  	if (ctx->driver_data->has_limited_fmt && !win) {
> -		if (fb->pixel_format == DRM_FORMAT_ARGB8888)
> -			fb->pixel_format = DRM_FORMAT_XRGB8888;
> +		if (pixel_format == DRM_FORMAT_ARGB8888)
> +			pixel_format = DRM_FORMAT_XRGB8888;
>  	}
>  
> -	switch (fb->pixel_format) {
> +	switch (pixel_format) {
>  	case DRM_FORMAT_C8:
>  		val |= WINCON0_BPPMODE_8BPP_PALETTE;
>  		val |= WINCONx_BURSTLEN_8WORD;
> @@ -538,17 +538,15 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
>  		break;
>  	}
>  
> -	DRM_DEBUG_KMS("bpp = %d\n", fb->bits_per_pixel);
> -
>  	/*
> -	 * In case of exynos, setting dma-burst to 16Word causes permanent
> -	 * tearing for very small buffers, e.g. cursor buffer. Burst Mode
> -	 * switching which is based on plane size is not recommended as
> -	 * plane size varies alot towards the end of the screen and rapid
> -	 * movement causes unstable DMA which results into iommu crash/tear.
> +	 * Setting dma-burst to 16Word causes permanent tearing for very small
> +	 * buffers, e.g. cursor buffer. Burst Mode switching which based on
> +	 * plane size is not recommended as plane size varies alot towards the
> +	 * end of the screen and rapid movement causes unstable DMA, but it is
> +	 * still better to change dma-burst than displaying garbage.
>  	 */
>  
> -	if (fb->width < MIN_FB_WIDTH_FOR_16WORD_BURST) {
> +	if (width < MIN_FB_WIDTH_FOR_16WORD_BURST) {
>  		val &= ~WINCONx_BURSTLEN_MASK;
>  		val |= WINCONx_BURSTLEN_4WORD;
>  	}
> @@ -723,7 +721,7 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
>  		DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val);
>  	}
>  
> -	fimd_win_set_pixfmt(ctx, win, fb);
> +	fimd_win_set_pixfmt(ctx, win, fb->pixel_format, state->src.w);
>  
>  	/* hardware window 0 doesn't support color key. */
>  	if (win != 0)
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 06/25] drm/exynos: fix to calculate offset of each plane for ipp fimc
  2015-11-10 13:23 ` [PATCH 06/25] drm/exynos: fix to calculate offset of each plane for ipp fimc Marek Szyprowski
@ 2015-11-12 15:20   ` Tobias Jakobi
  2015-11-13  9:19     ` Marek Szyprowski
  0 siblings, 1 reply; 70+ messages in thread
From: Tobias Jakobi @ 2015-11-12 15:20 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, linux-samsung-soc
  Cc: Javier Martinez Canillas, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, Andrzej Hajda

Hello,



Marek Szyprowski wrote:
> From: Seung-Woo Kim <sw0312.kim@samsung.com>
> 
> NV12 and YUV420 formats are need to calculate offset of each plane
> for ipp fimc in a gem buffer. Without proper offset, only Y plane
> can be processed, so result shows green frame.
> This patch fixes to calculate offset for cbcr planes for NV12 and
> YUV420 formats.
> 
> Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_fimc.c | 106 +++++++++++++++++++++++++++++++
>  drivers/gpu/drm/exynos/exynos_drm_ipp.c  |  15 ++++-
>  drivers/gpu/drm/exynos/exynos_drm_ipp.h  |   2 +
>  3 files changed, 121 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
> index c747824f3c98..72a7ca188be5 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
> @@ -403,6 +403,97 @@ static void fimc_handle_lastend(struct fimc_context *ctx, bool enable)
>  	fimc_write(ctx, cfg, EXYNOS_CIOCTRL);
>  }
>  
> +static int fimc_set_planar_addr(struct drm_exynos_ipp_buf_info *buf_info,
> +				u32 fmt, struct drm_exynos_sz *sz)
> +{
> +	dma_addr_t *base[EXYNOS_DRM_PLANAR_MAX];
I think I've seen this at several other places already, but I never
fully understood it.

Why are we using dma_addr_t* here, instead of just dma_addr_t? I mean in
the following code the pointer is just in the dereferenced form anyway,
so why this added indirection?


With best wishes,
Tobias



> +	uint64_t size[EXYNOS_DRM_PLANAR_MAX];
> +	uint64_t ofs[EXYNOS_DRM_PLANAR_MAX];
> +	bool bypass = false;
> +	uint64_t tsize = 0;
> +	int i;
> +
> +	for_each_ipp_planar(i) {
> +		base[i] = &buf_info->base[i];
> +		size[i] = buf_info->size[i];
> +		ofs[i] = 0;
> +		tsize += size[i];
> +	}
> +
> +	if (!tsize) {
> +		DRM_INFO("%s:failed to get buffer size.\n", __func__);
> +		return 0;
> +	}
> +
> +	switch (fmt) {
> +	case DRM_FORMAT_NV12:
> +	case DRM_FORMAT_NV21:
> +	case DRM_FORMAT_NV16:
> +	case DRM_FORMAT_NV61:
> +		ofs[0] = sz->hsize * sz->vsize;
> +		ofs[1] = ofs[0] >> 1;
> +		if (*base[0] && *base[1]) {
> +			if (size[0] + size[1] < ofs[0] + ofs[1])
> +				goto err_info;
> +			bypass = true;
> +		}
> +		break;
> +	case DRM_FORMAT_YUV410:
> +	case DRM_FORMAT_YVU410:
> +	case DRM_FORMAT_YUV411:
> +	case DRM_FORMAT_YVU411:
> +	case DRM_FORMAT_YUV420:
> +	case DRM_FORMAT_YVU420:
> +	case DRM_FORMAT_YUV422:
> +	case DRM_FORMAT_YVU422:
> +	case DRM_FORMAT_YUV444:
> +	case DRM_FORMAT_YVU444:
> +		ofs[0] = sz->hsize * sz->vsize;
> +		ofs[1] = ofs[2] = ofs[0] >> 2;
> +		if (*base[0] && *base[1] && *base[2]) {
> +			if (size[0]+size[1]+size[2] < ofs[0]+ofs[1]+ofs[2])
> +				goto err_info;
> +			bypass = true;
> +		}
> +		break;
> +	case DRM_FORMAT_XRGB8888:
> +	case DRM_FORMAT_ARGB8888:
> +		ofs[0] = sz->hsize * sz->vsize << 2;
> +		if (*base[0]) {
> +			if (size[0] < ofs[0])
> +				goto err_info;
> +		}
> +		bypass = true;
> +		break;
> +	default:
> +		bypass = true;
> +		break;
> +	}
> +
> +	if (!bypass) {
> +		*base[1] = *base[0] + ofs[0];
> +		if (ofs[1] && ofs[2])
> +			*base[2] = *base[1] + ofs[1];
> +	}
> +
> +	DRM_DEBUG_KMS("%s:y[0x%x],cb[0x%x],cr[0x%x]\n", __func__,
> +		*base[0], *base[1], *base[2]);
> +
> +	return 0;
> +
> +err_info:
> +	DRM_ERROR("invalid size for fmt[0x%x]\n", fmt);
> +
> +	for_each_ipp_planar(i) {
> +		base[i] = &buf_info->base[i];
> +		size[i] = buf_info->size[i];
> +
> +		DRM_ERROR("buf[%d] - base[0x%x] sz[%llu] ofs[%llu]\n",
> +			i, *base[i], size[i], ofs[i]);
> +	}
> +
> +	return -EINVAL;
> +}
>  
>  static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
>  {
> @@ -689,6 +780,7 @@ static int fimc_src_set_addr(struct device *dev,
>  	struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node;
>  	struct drm_exynos_ipp_property *property;
>  	struct drm_exynos_ipp_config *config;
> +	int ret;
>  
>  	if (!c_node) {
>  		DRM_ERROR("failed to get c_node.\n");
> @@ -709,6 +801,12 @@ static int fimc_src_set_addr(struct device *dev,
>  	switch (buf_type) {
>  	case IPP_BUF_ENQUEUE:
>  		config = &property->config[EXYNOS_DRM_OPS_SRC];
> +		ret = fimc_set_planar_addr(buf_info, config->fmt, &config->sz);
> +		if (ret) {
> +			dev_err(dev, "failed to set plane src addr.\n");
> +			return ret;
> +		}
> +
>  		fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_Y],
>  			EXYNOS_CIIYSA0);
>  
> @@ -1148,6 +1246,7 @@ static int fimc_dst_set_addr(struct device *dev,
>  	struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node;
>  	struct drm_exynos_ipp_property *property;
>  	struct drm_exynos_ipp_config *config;
> +	int ret;
>  
>  	if (!c_node) {
>  		DRM_ERROR("failed to get c_node.\n");
> @@ -1168,6 +1267,11 @@ static int fimc_dst_set_addr(struct device *dev,
>  	switch (buf_type) {
>  	case IPP_BUF_ENQUEUE:
>  		config = &property->config[EXYNOS_DRM_OPS_DST];
> +		ret = fimc_set_planar_addr(buf_info, config->fmt, &config->sz);
> +		if (ret) {
> +			dev_err(dev, "failed to set plane dst addr.\n");
> +			return ret;
> +		}
>  
>  		fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_Y],
>  			EXYNOS_CIOYSA(buf_id));
> @@ -1562,6 +1666,8 @@ static void fimc_ippdrv_stop(struct device *dev, enum drm_exynos_ipp_cmd cmd)
>  	/* reset sequence */
>  	fimc_write(ctx, 0x0, EXYNOS_CIFCNTSEQ);
>  
> +	fimc_clear_addr(ctx);
> +
>  	/* Scaler disable */
>  	fimc_clear_bits(ctx, EXYNOS_CISCCTRL, EXYNOS_CISCCTRL_SCALERSTART);
>  
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
> index 67d24236e745..408a14a9a180 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
> @@ -571,6 +571,7 @@ static struct drm_exynos_ipp_mem_node
>  		/* get dma address by handle */
>  		if (qbuf->handle[i]) {
>  			dma_addr_t *addr;
> +			unsigned long size;
>  
>  			addr = exynos_drm_gem_get_dma_addr(drm_dev,
>  					qbuf->handle[i], c_node->filp);
> @@ -580,10 +581,20 @@ static struct drm_exynos_ipp_mem_node
>  				return ERR_PTR(-EFAULT);
>  			}
>  
> +			size = exynos_drm_gem_get_size(drm_dev,
> +					qbuf->handle[i], c_node->filp);
> +			if (!size) {
> +				DRM_ERROR("failed to get size.\n");
> +				ipp_put_mem_node(drm_dev, c_node, m_node);
> +				return ERR_PTR(-EFAULT);
> +			}
> +
>  			buf_info->handles[i] = qbuf->handle[i];
>  			buf_info->base[i] = *addr;
> -			DRM_DEBUG_KMS("i[%d]base[0x%x]hd[0x%lx]\n", i,
> -				      buf_info->base[i], buf_info->handles[i]);
> +			buf_info->size[i] = (uint64_t)size;
> +			DRM_DEBUG_KMS("i[%d]base[%pad]hd[0x%lx]sz[%llx]\n", i,
> +				      &buf_info->base[i], buf_info->handles[i],
> +				      buf_info->size[i]);
>  		}
>  	}
>  
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
> index 2a61547a39d0..d4f0b588220b 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.h
> +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
> @@ -85,10 +85,12 @@ struct drm_exynos_ipp_cmd_node {
>   *
>   * @handles: Y, Cb, Cr each gem object handle.
>   * @base: Y, Cb, Cr each planar address.
> + * @size: Y, Cb, Cr each planar size.
>   */
>  struct drm_exynos_ipp_buf_info {
>  	unsigned long	handles[EXYNOS_DRM_PLANAR_MAX];
>  	dma_addr_t	base[EXYNOS_DRM_PLANAR_MAX];
> +	uint64_t	size[EXYNOS_DRM_PLANAR_MAX];
>  };
>  
>  /*
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 18/25] drm/exynos: fimd: fix dma burst size setting for small plane size
  2015-11-12 15:17   ` Tobias Jakobi
@ 2015-11-12 15:23     ` Daniel Stone
  0 siblings, 0 replies; 70+ messages in thread
From: Daniel Stone @ 2015-11-12 15:23 UTC (permalink / raw)
  To: Tobias Jakobi
  Cc: Krzysztof Kozlowski, linux-samsung-soc,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, dri-devel,
	Andrzej Hajda, Javier Martinez Canillas, Marek Szyprowski

Hey Tobias,

On 12 November 2015 at 15:17, Tobias Jakobi
<tjakobi@math.uni-bielefeld.de> wrote:
> This one looks a bit strange. It only changes the argument list of
> fimd_win_set_pixfmt() but the commit message that it actually fixes
> something.
>
> The corresponding upstream commit:
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=66367461e573321f0fbb0be0391165b5a54d5fe4

It's subtle:

>> -     fimd_win_set_pixfmt(ctx, win, fb);
>> +     fimd_win_set_pixfmt(ctx, win, fb->pixel_format, state->src.w);

i.e. rather than checking the total width of the allocated fb, we
check the width we are _actually_ scanning out from the fb. So I think
the patch is correct.

Cheers,
Daniel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 08/25] drm/exynos: rotator: convert to common clock framework
  2015-11-10 13:23 ` [PATCH 08/25] drm/exynos: rotator: convert to common clock framework Marek Szyprowski
@ 2015-11-12 18:13   ` Gustavo Padovan
  0 siblings, 0 replies; 70+ messages in thread
From: Gustavo Padovan @ 2015-11-12 18:13 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: dri-devel, linux-samsung-soc, Inki Dae, Joonyoung Shim,
	Seung-Woo Kim, Andrzej Hajda, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Tobias Jakobi,
	Javier Martinez Canillas

Hi Marek,

2015-11-10 Marek Szyprowski <m.szyprowski@samsung.com>:

> This driver was not used after introduction of common clock framework.
> This patch adds missing prepare/unprepare calls and allows to use it
> again with current kernel code.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_rotator.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

	Gustavo

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 09/25] drm/exynos: exynos7-decon: remove excessive check
  2015-11-10 13:23 ` [PATCH 09/25] drm/exynos: exynos7-decon: remove excessive check Marek Szyprowski
@ 2015-11-12 18:15   ` Gustavo Padovan
  0 siblings, 0 replies; 70+ messages in thread
From: Gustavo Padovan @ 2015-11-12 18:15 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: dri-devel, linux-samsung-soc, Inki Dae, Joonyoung Shim,
	Seung-Woo Kim, Andrzej Hajda, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Tobias Jakobi,
	Javier Martinez Canillas

Hi Marek,

2015-11-10 Marek Szyprowski <m.szyprowski@samsung.com>:

> Display area is already checked by exynos plane core, so there is no
> need for such check in driver code.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos7_drm_decon.c | 10 ----------
>  1 file changed, 10 deletions(-)

Reviewed-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

	Gustavo

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/25] drm/exynos: move dma_addr attribute from exynos plane to exynos fb
  2015-11-10 13:23 ` [PATCH 10/25] drm/exynos: move dma_addr attribute from exynos plane to exynos fb Marek Szyprowski
@ 2015-11-12 18:25   ` Gustavo Padovan
  0 siblings, 0 replies; 70+ messages in thread
From: Gustavo Padovan @ 2015-11-12 18:25 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: dri-devel, linux-samsung-soc, Inki Dae, Joonyoung Shim,
	Seung-Woo Kim, Andrzej Hajda, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Tobias Jakobi,
	Javier Martinez Canillas

Hi Marek,

2015-11-10 Marek Szyprowski <m.szyprowski@samsung.com>:

> DMA address is a framebuffer attribute and the right place for it is
> exynos_drm_framebuffer not exynos_drm_plane. This patch also introduces
> helper function for getting dma address of the given framebuffer.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 13 ++++++++-----
>  drivers/gpu/drm/exynos/exynos7_drm_decon.c    | 16 +++++++++-------
>  drivers/gpu/drm/exynos/exynos_drm_drv.h       |  3 ---
>  drivers/gpu/drm/exynos/exynos_drm_fb.c        | 16 ++++++----------
>  drivers/gpu/drm/exynos/exynos_drm_fb.h        |  3 +--
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c      | 10 ++++++----
>  drivers/gpu/drm/exynos/exynos_drm_plane.c     | 18 ------------------
>  drivers/gpu/drm/exynos/exynos_drm_vidi.c      |  5 ++++-
>  drivers/gpu/drm/exynos/exynos_mixer.c         |  7 ++++---
>  9 files changed, 38 insertions(+), 53 deletions(-)

Reviewed-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

	Gustavo

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/25] ARM: dts: exynos4: add rotator nodes
  2015-11-10 13:23 ` [PATCH 01/25] ARM: dts: exynos4: add rotator nodes Marek Szyprowski
@ 2015-11-13  2:23   ` Krzysztof Kozlowski
  2015-11-13  8:31     ` Marek Szyprowski
  2015-11-13  2:29   ` [PATCH 01/25] " Krzysztof Kozlowski
  1 sibling, 1 reply; 70+ messages in thread
From: Krzysztof Kozlowski @ 2015-11-13  2:23 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, linux-samsung-soc
  Cc: Javier Martinez Canillas, Tobias Jakobi,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, Andrzej Hajda

On 10.11.2015 22:23, Marek Szyprowski wrote:
> This patch adds device node for Rotator device to Exynos 4210 and 4x12
> device tree files.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  arch/arm/boot/dts/exynos4.dtsi    | 10 +++++++++-
>  arch/arm/boot/dts/exynos4210.dtsi |  8 ++++++++
>  arch/arm/boot/dts/exynos4x12.dtsi |  4 ++++
>  3 files changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
> index 2f31f773b096..3fa575ad7693 100644
> --- a/arch/arm/boot/dts/exynos4.dtsi
> +++ b/arch/arm/boot/dts/exynos4.dtsi
> @@ -718,6 +718,15 @@
>  		iommus = <&sysmmu_jpeg>;
>  	};
>  
> +	rotator: rotator@12810000 {
> +		compatible = "samsung,exynos4210-rotator";
> +		reg = <0x12810000 0x1000>;
> +		interrupts = <0 83 0>;
> +		clocks = <&clock CLK_ROTATOR>;
> +		clock-names = "rotator";
> +		iommus = <&sysmmu_rotator>;
> +	};
> +
>  	hdmi: hdmi@12D00000 {
>  		compatible = "samsung,exynos4210-hdmi";
>  		reg = <0x12D00000 0x70000>;
> @@ -945,7 +954,6 @@
>  		interrupts = <5 0>;
>  		clock-names = "sysmmu", "master";
>  		clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
> -		power-domains = <&pd_lcd0>;

Hmm.... I wonder why you changed this. Sysmmu rotator and rotator are
not a part of LCD power domain on Exynos4x12 (or they should not be?)? Why?

Best regards,
Krzysztof


>  		#iommu-cells = <0>;
>  	};
>  
> diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
> index 3e5ba665d200..b7474cf27e82 100644
> --- a/arch/arm/boot/dts/exynos4210.dtsi
> +++ b/arch/arm/boot/dts/exynos4210.dtsi
> @@ -279,3 +279,11 @@
>  		<&clock CLK_OUT_CPU>, <&clock CLK_XXTI>, <&clock CLK_XUSBXTI>;
>  	#clock-cells = <1>;
>  };
> +
> +&rotator {
> +	power-domains = <&pd_lcd0>;
> +};
> +
> +&sysmmu_rotator {
> +	power-domains = <&pd_lcd0>;
> +};
> diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
> index b77dac61ffb5..148b47ad3120 100644
> --- a/arch/arm/boot/dts/exynos4x12.dtsi
> +++ b/arch/arm/boot/dts/exynos4x12.dtsi
> @@ -339,6 +339,10 @@
>  	compatible = "samsung,exynos4212-jpeg";
>  };
>  
> +&rotator {
> +	compatible = "samsung,exynos4212-rotator";
> +};
> +
>  &mixer {
>  	compatible = "samsung,exynos4212-mixer";
>  	clock-names = "mixer", "hdmi", "sclk_hdmi", "vp";
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 02/25] ARM: dts: exynos542x: add rotator node
  2015-11-10 13:23 ` [PATCH 02/25] ARM: dts: exynos542x: add rotator node Marek Szyprowski
@ 2015-11-13  2:28   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 70+ messages in thread
From: Krzysztof Kozlowski @ 2015-11-13  2:28 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, linux-samsung-soc
  Cc: Inki Dae, Joonyoung Shim, Seung-Woo Kim, Andrzej Hajda,
	Bartlomiej Zolnierkiewicz, Tobias Jakobi, Gustavo Padovan,
	Javier Martinez Canillas

On 10.11.2015 22:23, Marek Szyprowski wrote:
> This patch adds device node for Rotator device to Exynos 542x device
> tree file.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  arch/arm/boot/dts/exynos5420.dtsi | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 

Looks good, thanks!

Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>


Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/25] ARM: dts: exynos4: add rotator nodes
  2015-11-10 13:23 ` [PATCH 01/25] ARM: dts: exynos4: add rotator nodes Marek Szyprowski
  2015-11-13  2:23   ` Krzysztof Kozlowski
@ 2015-11-13  2:29   ` Krzysztof Kozlowski
  2015-11-13  8:32     ` Marek Szyprowski
  1 sibling, 1 reply; 70+ messages in thread
From: Krzysztof Kozlowski @ 2015-11-13  2:29 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, linux-samsung-soc
  Cc: Inki Dae, Joonyoung Shim, Seung-Woo Kim, Andrzej Hajda,
	Bartlomiej Zolnierkiewicz, Tobias Jakobi, Gustavo Padovan,
	Javier Martinez Canillas

On 10.11.2015 22:23, Marek Szyprowski wrote:
> This patch adds device node for Rotator device to Exynos 4210 and 4x12
> device tree files.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  arch/arm/boot/dts/exynos4.dtsi    | 10 +++++++++-
>  arch/arm/boot/dts/exynos4210.dtsi |  8 ++++++++
>  arch/arm/boot/dts/exynos4x12.dtsi |  4 ++++
>  3 files changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
> index 2f31f773b096..3fa575ad7693 100644
> --- a/arch/arm/boot/dts/exynos4.dtsi
> +++ b/arch/arm/boot/dts/exynos4.dtsi
> @@ -718,6 +718,15 @@
>  		iommus = <&sysmmu_jpeg>;
>  	};
>  
> +	rotator: rotator@12810000 {
> +		compatible = "samsung,exynos4210-rotator";
> +		reg = <0x12810000 0x1000>;

One more question after looking at second patch. You are mapping size of
0x1000 instead of 0x64. Any particular reason? (it does not really
matter... just wondering)

Best regards,
Krzysztof

> +		interrupts = <0 83 0>;
> +		clocks = <&clock CLK_ROTATOR>;
> +		clock-names = "rotator";
> +		iommus = <&sysmmu_rotator>;
> +	};
> +
>  	hdmi: hdmi@12D00000 {
>  		compatible = "samsung,exynos4210-hdmi";
>  		reg = <0x12D00000 0x70000>;
> @@ -945,7 +954,6 @@
>  		interrupts = <5 0>;
>  		clock-names = "sysmmu", "master";
>  		clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
> -		power-domains = <&pd_lcd0>;
>  		#iommu-cells = <0>;
>  	};
>  
> diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
> index 3e5ba665d200..b7474cf27e82 100644
> --- a/arch/arm/boot/dts/exynos4210.dtsi
> +++ b/arch/arm/boot/dts/exynos4210.dtsi
> @@ -279,3 +279,11 @@
>  		<&clock CLK_OUT_CPU>, <&clock CLK_XXTI>, <&clock CLK_XUSBXTI>;
>  	#clock-cells = <1>;
>  };
> +
> +&rotator {
> +	power-domains = <&pd_lcd0>;
> +};
> +
> +&sysmmu_rotator {
> +	power-domains = <&pd_lcd0>;
> +};
> diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
> index b77dac61ffb5..148b47ad3120 100644
> --- a/arch/arm/boot/dts/exynos4x12.dtsi
> +++ b/arch/arm/boot/dts/exynos4x12.dtsi
> @@ -339,6 +339,10 @@
>  	compatible = "samsung,exynos4212-jpeg";
>  };
>  
> +&rotator {
> +	compatible = "samsung,exynos4212-rotator";
> +};
> +
>  &mixer {
>  	compatible = "samsung,exynos4212-mixer";
>  	clock-names = "mixer", "hdmi", "sclk_hdmi", "vp";
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/25] ARM: dts: exynos4: add rotator nodes
  2015-11-13  2:23   ` Krzysztof Kozlowski
@ 2015-11-13  8:31     ` Marek Szyprowski
  2015-11-13  8:35       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-13  8:31 UTC (permalink / raw)
  To: Krzysztof Kozlowski, dri-devel, linux-samsung-soc
  Cc: Inki Dae, Joonyoung Shim, Seung-Woo Kim, Andrzej Hajda,
	Bartlomiej Zolnierkiewicz, Tobias Jakobi, Gustavo Padovan,
	Javier Martinez Canillas

Hello,

On 2015-11-13 03:23, Krzysztof Kozlowski wrote:
> On 10.11.2015 22:23, Marek Szyprowski wrote:
>> This patch adds device node for Rotator device to Exynos 4210 and 4x12
>> device tree files.
>>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>>   arch/arm/boot/dts/exynos4.dtsi    | 10 +++++++++-
>>   arch/arm/boot/dts/exynos4210.dtsi |  8 ++++++++
>>   arch/arm/boot/dts/exynos4x12.dtsi |  4 ++++
>>   3 files changed, 21 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
>> index 2f31f773b096..3fa575ad7693 100644
>> --- a/arch/arm/boot/dts/exynos4.dtsi
>> +++ b/arch/arm/boot/dts/exynos4.dtsi
>> @@ -718,6 +718,15 @@
>>   		iommus = <&sysmmu_jpeg>;
>>   	};
>>   
>> +	rotator: rotator@12810000 {
>> +		compatible = "samsung,exynos4210-rotator";
>> +		reg = <0x12810000 0x1000>;
>> +		interrupts = <0 83 0>;
>> +		clocks = <&clock CLK_ROTATOR>;
>> +		clock-names = "rotator";
>> +		iommus = <&sysmmu_rotator>;
>> +	};
>> +
>>   	hdmi: hdmi@12D00000 {
>>   		compatible = "samsung,exynos4210-hdmi";
>>   		reg = <0x12D00000 0x70000>;
>> @@ -945,7 +954,6 @@
>>   		interrupts = <5 0>;
>>   		clock-names = "sysmmu", "master";
>>   		clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
>> -		power-domains = <&pd_lcd0>;
> Hmm.... I wonder why you changed this. Sysmmu rotator and rotator are
> not a part of LCD power domain on Exynos4x12 (or they should not be?)? Why?

On Exynos 4210 rotator (and its SYSMMU) belongs to LCD0 power domain. On
Exynos 4x12 it belong to TOP power domain (which is always on and not
described in DTS).

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/25] ARM: dts: exynos4: add rotator nodes
  2015-11-13  2:29   ` [PATCH 01/25] " Krzysztof Kozlowski
@ 2015-11-13  8:32     ` Marek Szyprowski
  2015-11-13  8:36       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-13  8:32 UTC (permalink / raw)
  To: Krzysztof Kozlowski, dri-devel, linux-samsung-soc
  Cc: Inki Dae, Joonyoung Shim, Seung-Woo Kim, Andrzej Hajda,
	Bartlomiej Zolnierkiewicz, Tobias Jakobi, Gustavo Padovan,
	Javier Martinez Canillas

Hello,

On 2015-11-13 03:29, Krzysztof Kozlowski wrote:
> On 10.11.2015 22:23, Marek Szyprowski wrote:
>> This patch adds device node for Rotator device to Exynos 4210 and 4x12
>> device tree files.
>>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>>   arch/arm/boot/dts/exynos4.dtsi    | 10 +++++++++-
>>   arch/arm/boot/dts/exynos4210.dtsi |  8 ++++++++
>>   arch/arm/boot/dts/exynos4x12.dtsi |  4 ++++
>>   3 files changed, 21 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
>> index 2f31f773b096..3fa575ad7693 100644
>> --- a/arch/arm/boot/dts/exynos4.dtsi
>> +++ b/arch/arm/boot/dts/exynos4.dtsi
>> @@ -718,6 +718,15 @@
>>   		iommus = <&sysmmu_jpeg>;
>>   	};
>>   
>> +	rotator: rotator@12810000 {
>> +		compatible = "samsung,exynos4210-rotator";
>> +		reg = <0x12810000 0x1000>;
> One more question after looking at second patch. You are mapping size of
> 0x1000 instead of 0x64. Any particular reason? (it does not really
> matter... just wondering)

Nope, it might be just a copy/paste issue I've missed. Do you want to 
unify it to
0x64 or 0x1000?

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/25] ARM: dts: exynos4: add rotator nodes
  2015-11-13  8:31     ` Marek Szyprowski
@ 2015-11-13  8:35       ` Krzysztof Kozlowski
  2015-11-13 13:29         ` [PATCH v2 1/4] " Marek Szyprowski
  0 siblings, 1 reply; 70+ messages in thread
From: Krzysztof Kozlowski @ 2015-11-13  8:35 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, linux-samsung-soc
  Cc: Inki Dae, Joonyoung Shim, Seung-Woo Kim, Andrzej Hajda,
	Bartlomiej Zolnierkiewicz, Tobias Jakobi, Gustavo Padovan,
	Javier Martinez Canillas

On 13.11.2015 17:31, Marek Szyprowski wrote:
> Hello,
> 
> On 2015-11-13 03:23, Krzysztof Kozlowski wrote:
>> On 10.11.2015 22:23, Marek Szyprowski wrote:
>>> This patch adds device node for Rotator device to Exynos 4210 and 4x12
>>> device tree files.
>>>
>>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>> ---
>>>   arch/arm/boot/dts/exynos4.dtsi    | 10 +++++++++-
>>>   arch/arm/boot/dts/exynos4210.dtsi |  8 ++++++++
>>>   arch/arm/boot/dts/exynos4x12.dtsi |  4 ++++
>>>   3 files changed, 21 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm/boot/dts/exynos4.dtsi
>>> b/arch/arm/boot/dts/exynos4.dtsi
>>> index 2f31f773b096..3fa575ad7693 100644
>>> --- a/arch/arm/boot/dts/exynos4.dtsi
>>> +++ b/arch/arm/boot/dts/exynos4.dtsi
>>> @@ -718,6 +718,15 @@
>>>           iommus = <&sysmmu_jpeg>;
>>>       };
>>>   +    rotator: rotator@12810000 {
>>> +        compatible = "samsung,exynos4210-rotator";
>>> +        reg = <0x12810000 0x1000>;
>>> +        interrupts = <0 83 0>;
>>> +        clocks = <&clock CLK_ROTATOR>;
>>> +        clock-names = "rotator";
>>> +        iommus = <&sysmmu_rotator>;
>>> +    };
>>> +
>>>       hdmi: hdmi@12D00000 {
>>>           compatible = "samsung,exynos4210-hdmi";
>>>           reg = <0x12D00000 0x70000>;
>>> @@ -945,7 +954,6 @@
>>>           interrupts = <5 0>;
>>>           clock-names = "sysmmu", "master";
>>>           clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
>>> -        power-domains = <&pd_lcd0>;
>> Hmm.... I wonder why you changed this. Sysmmu rotator and rotator are
>> not a part of LCD power domain on Exynos4x12 (or they should not be?)?
>> Why?
> 
> On Exynos 4210 rotator (and its SYSMMU) belongs to LCD0 power domain. On
> Exynos 4x12 it belong to TOP power domain (which is always on and not
> described in DTS).

Indeed... The change makes sense but actually for sysmmu rotator should
be separated (especially that this was not mentioned in commit description).

Can you split the sysmmu part?

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/25] ARM: dts: exynos4: add rotator nodes
  2015-11-13  8:32     ` Marek Szyprowski
@ 2015-11-13  8:36       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 70+ messages in thread
From: Krzysztof Kozlowski @ 2015-11-13  8:36 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, linux-samsung-soc
  Cc: Inki Dae, Joonyoung Shim, Seung-Woo Kim, Andrzej Hajda,
	Bartlomiej Zolnierkiewicz, Tobias Jakobi, Gustavo Padovan,
	Javier Martinez Canillas

On 13.11.2015 17:32, Marek Szyprowski wrote:
> Hello,
> 
> On 2015-11-13 03:29, Krzysztof Kozlowski wrote:
>> On 10.11.2015 22:23, Marek Szyprowski wrote:
>>> This patch adds device node for Rotator device to Exynos 4210 and 4x12
>>> device tree files.
>>>
>>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>> ---
>>>   arch/arm/boot/dts/exynos4.dtsi    | 10 +++++++++-
>>>   arch/arm/boot/dts/exynos4210.dtsi |  8 ++++++++
>>>   arch/arm/boot/dts/exynos4x12.dtsi |  4 ++++
>>>   3 files changed, 21 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm/boot/dts/exynos4.dtsi
>>> b/arch/arm/boot/dts/exynos4.dtsi
>>> index 2f31f773b096..3fa575ad7693 100644
>>> --- a/arch/arm/boot/dts/exynos4.dtsi
>>> +++ b/arch/arm/boot/dts/exynos4.dtsi
>>> @@ -718,6 +718,15 @@
>>>           iommus = <&sysmmu_jpeg>;
>>>       };
>>>   +    rotator: rotator@12810000 {
>>> +        compatible = "samsung,exynos4210-rotator";
>>> +        reg = <0x12810000 0x1000>;
>> One more question after looking at second patch. You are mapping size of
>> 0x1000 instead of 0x64. Any particular reason? (it does not really
>> matter... just wondering)
> 
> Nope, it might be just a copy/paste issue I've missed. Do you want to
> unify it to
> 0x64 or 0x1000?

To 0x64, please. That would make it synced with datasheet.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 06/25] drm/exynos: fix to calculate offset of each plane for ipp fimc
  2015-11-12 15:20   ` Tobias Jakobi
@ 2015-11-13  9:19     ` Marek Szyprowski
  0 siblings, 0 replies; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-13  9:19 UTC (permalink / raw)
  To: Tobias Jakobi, dri-devel, linux-samsung-soc
  Cc: Inki Dae, Joonyoung Shim, Seung-Woo Kim, Andrzej Hajda,
	Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz, Gustavo Padovan,
	Javier Martinez Canillas

Hello,

On 2015-11-12 16:20, Tobias Jakobi wrote:
> Hello,
>
> Marek Szyprowski wrote:
>> From: Seung-Woo Kim <sw0312.kim@samsung.com>
>>
>> NV12 and YUV420 formats are need to calculate offset of each plane
>> for ipp fimc in a gem buffer. Without proper offset, only Y plane
>> can be processed, so result shows green frame.
>> This patch fixes to calculate offset for cbcr planes for NV12 and
>> YUV420 formats.
>>
>> Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>>   drivers/gpu/drm/exynos/exynos_drm_fimc.c | 106 +++++++++++++++++++++++++++++++
>>   drivers/gpu/drm/exynos/exynos_drm_ipp.c  |  15 ++++-
>>   drivers/gpu/drm/exynos/exynos_drm_ipp.h  |   2 +
>>   3 files changed, 121 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
>> index c747824f3c98..72a7ca188be5 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
>> @@ -403,6 +403,97 @@ static void fimc_handle_lastend(struct fimc_context *ctx, bool enable)
>>   	fimc_write(ctx, cfg, EXYNOS_CIOCTRL);
>>   }
>>   
>> +static int fimc_set_planar_addr(struct drm_exynos_ipp_buf_info *buf_info,
>> +				u32 fmt, struct drm_exynos_sz *sz)
>> +{
>> +	dma_addr_t *base[EXYNOS_DRM_PLANAR_MAX];
> I think I've seen this at several other places already, but I never
> fully understood it.
>
> Why are we using dma_addr_t* here, instead of just dma_addr_t? I mean in
> the following code the pointer is just in the dereferenced form anyway,
> so why this added indirection?

This function updates dma addresses stored in struct drm_exynos_ipp_buf_info
*buf_info (it adds offset related to specific pixel format), so using a 
pointer
makes all formulas shorter.

>> +	uint64_t size[EXYNOS_DRM_PLANAR_MAX];
>> +	uint64_t ofs[EXYNOS_DRM_PLANAR_MAX];
>> +	bool bypass = false;
>> +	uint64_t tsize = 0;
>> +	int i;
>> +
>> +	for_each_ipp_planar(i) {
>> +		base[i] = &buf_info->base[i];
>> +		size[i] = buf_info->size[i];
>> +		ofs[i] = 0;
>> +		tsize += size[i];
>> +	}
>> +
>> +	if (!tsize) {
>> +		DRM_INFO("%s:failed to get buffer size.\n", __func__);
>> +		return 0;
>> +	}
>> +
>> +	switch (fmt) {
>> +	case DRM_FORMAT_NV12:
>> +	case DRM_FORMAT_NV21:
>> +	case DRM_FORMAT_NV16:
>> +	case DRM_FORMAT_NV61:
>> +		ofs[0] = sz->hsize * sz->vsize;
>> +		ofs[1] = ofs[0] >> 1;
>> +		if (*base[0] && *base[1]) {
>> +			if (size[0] + size[1] < ofs[0] + ofs[1])
>> +				goto err_info;
>> +			bypass = true;
>> +		}
>> +		break;
>> +	case DRM_FORMAT_YUV410:
>> +	case DRM_FORMAT_YVU410:
>> +	case DRM_FORMAT_YUV411:
>> +	case DRM_FORMAT_YVU411:
>> +	case DRM_FORMAT_YUV420:
>> +	case DRM_FORMAT_YVU420:
>> +	case DRM_FORMAT_YUV422:
>> +	case DRM_FORMAT_YVU422:
>> +	case DRM_FORMAT_YUV444:
>> +	case DRM_FORMAT_YVU444:
>> +		ofs[0] = sz->hsize * sz->vsize;
>> +		ofs[1] = ofs[2] = ofs[0] >> 2;
>> +		if (*base[0] && *base[1] && *base[2]) {
>> +			if (size[0]+size[1]+size[2] < ofs[0]+ofs[1]+ofs[2])
>> +				goto err_info;
>> +			bypass = true;
>> +		}
>> +		break;
>> +	case DRM_FORMAT_XRGB8888:
>> +	case DRM_FORMAT_ARGB8888:
>> +		ofs[0] = sz->hsize * sz->vsize << 2;
>> +		if (*base[0]) {
>> +			if (size[0] < ofs[0])
>> +				goto err_info;
>> +		}
>> +		bypass = true;
>> +		break;
>> +	default:
>> +		bypass = true;
>> +		break;
>> +	}
>> +
>> +	if (!bypass) {
>> +		*base[1] = *base[0] + ofs[0];
>> +		if (ofs[1] && ofs[2])
>> +			*base[2] = *base[1] + ofs[1];
>> +	}
>> +
>> +	DRM_DEBUG_KMS("%s:y[0x%x],cb[0x%x],cr[0x%x]\n", __func__,
>> +		*base[0], *base[1], *base[2]);
>> +
>> +	return 0;
>> +
>> +err_info:
>> +	DRM_ERROR("invalid size for fmt[0x%x]\n", fmt);
>> +
>> +	for_each_ipp_planar(i) {
>> +		base[i] = &buf_info->base[i];
>> +		size[i] = buf_info->size[i];
>> +
>> +		DRM_ERROR("buf[%d] - base[0x%x] sz[%llu] ofs[%llu]\n",
>> +			i, *base[i], size[i], ofs[i]);
>> +	}
>> +
>> +	return -EINVAL;
>> +}
>>   
>>   static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
>>   {
>> @@ -689,6 +780,7 @@ static int fimc_src_set_addr(struct device *dev,
>>   	struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node;
>>   	struct drm_exynos_ipp_property *property;
>>   	struct drm_exynos_ipp_config *config;
>> +	int ret;
>>   
>>   	if (!c_node) {
>>   		DRM_ERROR("failed to get c_node.\n");
>> @@ -709,6 +801,12 @@ static int fimc_src_set_addr(struct device *dev,
>>   	switch (buf_type) {
>>   	case IPP_BUF_ENQUEUE:
>>   		config = &property->config[EXYNOS_DRM_OPS_SRC];
>> +		ret = fimc_set_planar_addr(buf_info, config->fmt, &config->sz);
>> +		if (ret) {
>> +			dev_err(dev, "failed to set plane src addr.\n");
>> +			return ret;
>> +		}
>> +
>>   		fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_Y],
>>   			EXYNOS_CIIYSA0);
>>   
>> @@ -1148,6 +1246,7 @@ static int fimc_dst_set_addr(struct device *dev,
>>   	struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node;
>>   	struct drm_exynos_ipp_property *property;
>>   	struct drm_exynos_ipp_config *config;
>> +	int ret;
>>   
>>   	if (!c_node) {
>>   		DRM_ERROR("failed to get c_node.\n");
>> @@ -1168,6 +1267,11 @@ static int fimc_dst_set_addr(struct device *dev,
>>   	switch (buf_type) {
>>   	case IPP_BUF_ENQUEUE:
>>   		config = &property->config[EXYNOS_DRM_OPS_DST];
>> +		ret = fimc_set_planar_addr(buf_info, config->fmt, &config->sz);
>> +		if (ret) {
>> +			dev_err(dev, "failed to set plane dst addr.\n");
>> +			return ret;
>> +		}
>>   
>>   		fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_Y],
>>   			EXYNOS_CIOYSA(buf_id));
>> @@ -1562,6 +1666,8 @@ static void fimc_ippdrv_stop(struct device *dev, enum drm_exynos_ipp_cmd cmd)
>>   	/* reset sequence */
>>   	fimc_write(ctx, 0x0, EXYNOS_CIFCNTSEQ);
>>   
>> +	fimc_clear_addr(ctx);
>> +
>>   	/* Scaler disable */
>>   	fimc_clear_bits(ctx, EXYNOS_CISCCTRL, EXYNOS_CISCCTRL_SCALERSTART);
>>   
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
>> index 67d24236e745..408a14a9a180 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
>> @@ -571,6 +571,7 @@ static struct drm_exynos_ipp_mem_node
>>   		/* get dma address by handle */
>>   		if (qbuf->handle[i]) {
>>   			dma_addr_t *addr;
>> +			unsigned long size;
>>   
>>   			addr = exynos_drm_gem_get_dma_addr(drm_dev,
>>   					qbuf->handle[i], c_node->filp);
>> @@ -580,10 +581,20 @@ static struct drm_exynos_ipp_mem_node
>>   				return ERR_PTR(-EFAULT);
>>   			}
>>   
>> +			size = exynos_drm_gem_get_size(drm_dev,
>> +					qbuf->handle[i], c_node->filp);
>> +			if (!size) {
>> +				DRM_ERROR("failed to get size.\n");
>> +				ipp_put_mem_node(drm_dev, c_node, m_node);
>> +				return ERR_PTR(-EFAULT);
>> +			}
>> +
>>   			buf_info->handles[i] = qbuf->handle[i];
>>   			buf_info->base[i] = *addr;
>> -			DRM_DEBUG_KMS("i[%d]base[0x%x]hd[0x%lx]\n", i,
>> -				      buf_info->base[i], buf_info->handles[i]);
>> +			buf_info->size[i] = (uint64_t)size;
>> +			DRM_DEBUG_KMS("i[%d]base[%pad]hd[0x%lx]sz[%llx]\n", i,
>> +				      &buf_info->base[i], buf_info->handles[i],
>> +				      buf_info->size[i]);
>>   		}
>>   	}
>>   
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
>> index 2a61547a39d0..d4f0b588220b 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.h
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
>> @@ -85,10 +85,12 @@ struct drm_exynos_ipp_cmd_node {
>>    *
>>    * @handles: Y, Cb, Cr each gem object handle.
>>    * @base: Y, Cb, Cr each planar address.
>> + * @size: Y, Cb, Cr each planar size.
>>    */
>>   struct drm_exynos_ipp_buf_info {
>>   	unsigned long	handles[EXYNOS_DRM_PLANAR_MAX];
>>   	dma_addr_t	base[EXYNOS_DRM_PLANAR_MAX];
>> +	uint64_t	size[EXYNOS_DRM_PLANAR_MAX];
>>   };
>>   
>>   /*
>>
>

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 11/25] drm/exynos: introduce exynos_drm_plane_state structure
  2015-11-10 13:23 ` [PATCH 11/25] drm/exynos: introduce exynos_drm_plane_state structure Marek Szyprowski
@ 2015-11-13 11:46   ` Gustavo Padovan
  0 siblings, 0 replies; 70+ messages in thread
From: Gustavo Padovan @ 2015-11-13 11:46 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Javier Martinez Canillas, Krzysztof Kozlowski, linux-samsung-soc,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, dri-devel,
	Andrzej Hajda, Tobias Jakobi

Hi Marek,

2015-11-10 Marek Szyprowski <m.szyprowski@samsung.com>:

> This patch introduces exynos_drm_plane_state structure, which subclasses
> drm_plane_state and holds precalculated data suitable for configuring
> Exynos hardware.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos5433_drm_decon.c |  21 ++---
>  drivers/gpu/drm/exynos/exynos7_drm_decon.c    |  21 ++---
>  drivers/gpu/drm/exynos/exynos_drm_drv.h       |  56 +++++++-----
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c      |  33 +++----
>  drivers/gpu/drm/exynos/exynos_drm_plane.c     | 125 +++++++++++++++++++-------
>  drivers/gpu/drm/exynos/exynos_mixer.c         |  61 +++++++------
>  6 files changed, 197 insertions(+), 120 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
> index a3161b0428b9..27039468364b 100644
> --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
> +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
> @@ -260,9 +260,10 @@ static void decon_atomic_begin(struct exynos_drm_crtc *crtc,
>  static void decon_update_plane(struct exynos_drm_crtc *crtc,
>  			       struct exynos_drm_plane *plane)
>  {
> +	struct exynos_drm_plane_state *state =
> +				to_exynos_plane_state(plane->base.state);
>  	struct decon_context *ctx = crtc->ctx;
> -	struct drm_plane_state *state = plane->base.state;
> -	struct drm_framebuffer *fb = state->fb;
> +	struct drm_framebuffer *fb = state->base.fb;
>  	unsigned int win = plane->zpos;
>  	unsigned int bpp = fb->bits_per_pixel >> 3;
>  	unsigned int pitch = fb->pitches[0];
> @@ -272,11 +273,11 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
>  	if (test_bit(BIT_SUSPENDED, &ctx->flags))
>  		return;
>  
> -	val = COORDINATE_X(plane->crtc_x) | COORDINATE_Y(plane->crtc_y);
> +	val = COORDINATE_X(state->crtc.x) | COORDINATE_Y(state->crtc.y);
>  	writel(val, ctx->addr + DECON_VIDOSDxA(win));
>  
> -	val = COORDINATE_X(plane->crtc_x + plane->crtc_w - 1) |
> -		COORDINATE_Y(plane->crtc_y + plane->crtc_h - 1);
> +	val = COORDINATE_X(state->crtc.x + state->crtc.w - 1) |
> +		COORDINATE_Y(state->crtc.y + state->crtc.h - 1);
>  	writel(val, ctx->addr + DECON_VIDOSDxB(win));
>  
>  	val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) |
> @@ -289,15 +290,15 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
>  
>  	writel(dma_addr, ctx->addr + DECON_VIDW0xADD0B0(win));
>  
> -	val = dma_addr + pitch * plane->crtc_h;
> +	val = dma_addr + pitch * state->src.h;
>  	writel(val, ctx->addr + DECON_VIDW0xADD1B0(win));
>  
>  	if (ctx->out_type != IFTYPE_HDMI)
> -		val = BIT_VAL(pitch - plane->crtc_w * bpp, 27, 14)
> -			| BIT_VAL(plane->crtc_w * bpp, 13, 0);
> +		val = BIT_VAL(pitch - state->crtc.w * bpp, 27, 14)
> +			| BIT_VAL(state->crtc.w * bpp, 13, 0);
>  	else
> -		val = BIT_VAL(pitch - plane->crtc_w * bpp, 29, 15)
> -			| BIT_VAL(plane->crtc_w * bpp, 14, 0);
> +		val = BIT_VAL(pitch - state->crtc.w * bpp, 29, 15)
> +			| BIT_VAL(state->crtc.w * bpp, 14, 0);
>  	writel(val, ctx->addr + DECON_VIDW0xADD2(win));
>  
>  	decon_win_set_pixfmt(ctx, win, fb);
> diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
> index 15e1e165020f..7868d30d8eac 100644
> --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
> +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
> @@ -399,9 +399,10 @@ static void decon_atomic_begin(struct exynos_drm_crtc *crtc,
>  static void decon_update_plane(struct exynos_drm_crtc *crtc,
>  			       struct exynos_drm_plane *plane)
>  {
> +	struct exynos_drm_plane_state *state =
> +				to_exynos_plane_state(plane->base.state);
>  	struct decon_context *ctx = crtc->ctx;
> -	struct drm_plane_state *state = plane->base.state;
> -	struct drm_framebuffer *fb = state->fb;
> +	struct drm_framebuffer *fb = state->base.fb;
>  	int padding;
>  	unsigned long val, alpha;
>  	unsigned int last_x;
> @@ -434,22 +435,22 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
>  	writel(fb->height, ctx->regs + VIDW_WHOLE_Y(win));
>  
>  	/* offset from the start of the buffer to read */
> -	writel(plane->src_x, ctx->regs + VIDW_OFFSET_X(win));
> -	writel(plane->src_y, ctx->regs + VIDW_OFFSET_Y(win));
> +	writel(state->src.x, ctx->regs + VIDW_OFFSET_X(win));
> +	writel(state->src.y, ctx->regs + VIDW_OFFSET_Y(win));
>  
>  	DRM_DEBUG_KMS("start addr = 0x%lx\n",
>  			(unsigned long)val);
>  	DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
> -			plane->crtc_w, plane->crtc_h);
> +			state->crtc.w, state->crtc.h);
>  
> -	val = VIDOSDxA_TOPLEFT_X(plane->crtc_x) |
> -		VIDOSDxA_TOPLEFT_Y(plane->crtc_y);
> +	val = VIDOSDxA_TOPLEFT_X(state->crtc.x) |
> +		VIDOSDxA_TOPLEFT_Y(state->crtc.y);
>  	writel(val, ctx->regs + VIDOSD_A(win));
>  
> -	last_x = plane->crtc_x + plane->crtc_w;
> +	last_x = state->crtc.x + state->crtc.w;
>  	if (last_x)
>  		last_x--;
> -	last_y = plane->crtc_y + plane->crtc_h;
> +	last_y = state->crtc.y + state->crtc.h;
>  	if (last_y)
>  		last_y--;
>  
> @@ -458,7 +459,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
>  	writel(val, ctx->regs + VIDOSD_B(win));
>  
>  	DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n",
> -			plane->crtc_x, plane->crtc_y, last_x, last_y);
> +			state->crtc.x, state->crtc.y, last_x, last_y);
>  
>  	/* OSD alpha */
>  	alpha = VIDOSDxC_ALPHA0_R_F(0x0) |
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
> index dc41ffb26eb9..482ed2c2ed89 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
> @@ -38,22 +38,44 @@ enum exynos_drm_output_type {
>  	EXYNOS_DISPLAY_TYPE_VIDI,
>  };
>  
> +struct exynos_drm_rect {
> +	unsigned int x, y;
> +	unsigned int w, h;
> +};
> +
>  /*
> - * Exynos drm common overlay structure.
> + * Exynos drm plane state structure.
>   *
> - * @base: plane object
> - * @src_x: offset x on a framebuffer to be displayed.
> - *	- the unit is screen coordinates.
> - * @src_y: offset y on a framebuffer to be displayed.
> - *	- the unit is screen coordinates.
> - * @src_w: width of a partial image to be displayed from framebuffer.
> - * @src_h: height of a partial image to be displayed from framebuffer.
> - * @crtc_x: offset x on hardware screen.
> - * @crtc_y: offset y on hardware screen.
> - * @crtc_w: window width to be displayed (hardware screen).
> - * @crtc_h: window height to be displayed (hardware screen).
> + * @base: plane_state object (contains drm_framebuffer pointer)
> + * @src: rectangle of the source image data to be displayed (clipped to
> + *       visible part).
> + * @crtc: rectangle of the target image position on hardware screen
> + *       (clipped to visible part).
>   * @h_ratio: horizontal scaling ratio, 16.16 fixed point
>   * @v_ratio: vertical scaling ratio, 16.16 fixed point
> + *
> + * this structure consists plane state data that will be applied to hardware
> + * specific overlay info.
> + */
> +
> +struct exynos_drm_plane_state {
> +	struct drm_plane_state base;
> +	struct exynos_drm_rect crtc;
> +	struct exynos_drm_rect src;
> +	unsigned int h_ratio;
> +	unsigned int v_ratio;
> +};
> +
> +static inline struct exynos_drm_plane_state *
> +to_exynos_plane_state(struct drm_plane_state *state)
> +{
> +	return container_of(state, struct exynos_drm_plane_state, base);
> +}
> +
> +/*
> + * Exynos drm common overlay structure.
> + *
> + * @base: plane object
>   * @zpos: order of overlay layer(z position).
>   *
>   * this structure is common to exynos SoC and its contents would be copied
> @@ -62,16 +84,6 @@ enum exynos_drm_output_type {
>  
>  struct exynos_drm_plane {
>  	struct drm_plane base;
> -	unsigned int src_x;
> -	unsigned int src_y;
> -	unsigned int src_w;
> -	unsigned int src_h;
> -	unsigned int crtc_x;
> -	unsigned int crtc_y;
> -	unsigned int crtc_w;
> -	unsigned int crtc_h;
> -	unsigned int h_ratio;
> -	unsigned int v_ratio;
>  	unsigned int zpos;
>  	struct drm_framebuffer *pending_fb;
>  };
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> index d39e960a837f..40fa621e3963 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> @@ -641,9 +641,10 @@ static void fimd_atomic_flush(struct exynos_drm_crtc *crtc,
>  static void fimd_update_plane(struct exynos_drm_crtc *crtc,
>  			      struct exynos_drm_plane *plane)
>  {
> +	struct exynos_drm_plane_state *state =
> +				to_exynos_plane_state(plane->base.state);
>  	struct fimd_context *ctx = crtc->ctx;
> -	struct drm_plane_state *state = plane->base.state;
> -	struct drm_framebuffer *fb = state->fb;
> +	struct drm_framebuffer *fb = state->base.fb;
>  	dma_addr_t dma_addr;
>  	unsigned long val, size, offset;
>  	unsigned int last_x, last_y, buf_offsize, line_size;
> @@ -654,8 +655,8 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
>  	if (ctx->suspended)
>  		return;
>  
> -	offset = plane->src_x * bpp;
> -	offset += plane->src_y * pitch;
> +	offset = state->src.x * bpp;
> +	offset += state->src.y * pitch;
>  
>  	/* buffer start address */
>  	dma_addr = exynos_drm_fb_dma_addr(fb, 0) + offset;
> @@ -663,18 +664,18 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
>  	writel(val, ctx->regs + VIDWx_BUF_START(win, 0));
>  
>  	/* buffer end address */
> -	size = pitch * plane->crtc_h;
> +	size = pitch * state->crtc.h;
>  	val = (unsigned long)(dma_addr + size);
>  	writel(val, ctx->regs + VIDWx_BUF_END(win, 0));
>  
>  	DRM_DEBUG_KMS("start addr = 0x%lx, end addr = 0x%lx, size = 0x%lx\n",
>  			(unsigned long)dma_addr, val, size);
>  	DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
> -			plane->crtc_w, plane->crtc_h);
> +			state->crtc.w, state->crtc.h);
>  
>  	/* buffer size */
> -	buf_offsize = pitch - (plane->crtc_w * bpp);
> -	line_size = plane->crtc_w * bpp;
> +	buf_offsize = pitch - (state->crtc.w * bpp);
> +	line_size = state->crtc.w * bpp;
>  	val = VIDW_BUF_SIZE_OFFSET(buf_offsize) |
>  		VIDW_BUF_SIZE_PAGEWIDTH(line_size) |
>  		VIDW_BUF_SIZE_OFFSET_E(buf_offsize) |
> @@ -682,16 +683,16 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
>  	writel(val, ctx->regs + VIDWx_BUF_SIZE(win, 0));
>  
>  	/* OSD position */
> -	val = VIDOSDxA_TOPLEFT_X(plane->crtc_x) |
> -		VIDOSDxA_TOPLEFT_Y(plane->crtc_y) |
> -		VIDOSDxA_TOPLEFT_X_E(plane->crtc_x) |
> -		VIDOSDxA_TOPLEFT_Y_E(plane->crtc_y);
> +	val = VIDOSDxA_TOPLEFT_X(state->crtc.x) |
> +		VIDOSDxA_TOPLEFT_Y(state->crtc.y) |
> +		VIDOSDxA_TOPLEFT_X_E(state->crtc.x) |
> +		VIDOSDxA_TOPLEFT_Y_E(state->crtc.y);
>  	writel(val, ctx->regs + VIDOSD_A(win));
>  
> -	last_x = plane->crtc_x + plane->crtc_w;
> +	last_x = state->crtc.x + state->crtc.w;
>  	if (last_x)
>  		last_x--;
> -	last_y = plane->crtc_y + plane->crtc_h;
> +	last_y = state->crtc.y + state->crtc.h;
>  	if (last_y)
>  		last_y--;
>  
> @@ -701,14 +702,14 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
>  	writel(val, ctx->regs + VIDOSD_B(win));
>  
>  	DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n",
> -			plane->crtc_x, plane->crtc_y, last_x, last_y);
> +			state->crtc.x, state->crtc.y, last_x, last_y);
>  
>  	/* OSD size */
>  	if (win != 3 && win != 4) {
>  		u32 offset = VIDOSD_D(win);
>  		if (win == 0)
>  			offset = VIDOSD_C(win);
> -		val = plane->crtc_w * plane->crtc_h;
> +		val = state->crtc.w * state->crtc.h;
>  		writel(val, ctx->regs + offset);
>  
>  		DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val);
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
> index c725409421b8..365a738042e2 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
> @@ -56,19 +56,35 @@ static int exynos_plane_get_size(int start, unsigned length, unsigned last)
>  	return size;
>  }
>  
> -static void exynos_plane_mode_set(struct drm_plane *plane,
> -				  struct drm_crtc *crtc,
> -				  struct drm_framebuffer *fb,
> -				  int crtc_x, int crtc_y,
> -				  unsigned int crtc_w, unsigned int crtc_h,
> -				  uint32_t src_x, uint32_t src_y,
> -				  uint32_t src_w, uint32_t src_h)
> +static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state)
> +
>  {
> -	struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
> +	struct drm_plane_state *state = &exynos_state->base;
> +	struct drm_crtc *crtc = exynos_state->base.crtc;
>  	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
> +	int crtc_x, crtc_y;
> +	unsigned int crtc_w, crtc_h;
> +	unsigned int src_x, src_y;
> +	unsigned int src_w, src_h;
>  	unsigned int actual_w;
>  	unsigned int actual_h;
>  
> +	/*
> +	 * The original src/dest coordinates are stored in exynos_state->base,
> +	 * but we want to keep another copy internal to our driver that we can
> +	 * clip/modify ourselves.
> +	 */
> +
> +	crtc_x = state->crtc_x;
> +	crtc_y = state->crtc_y;
> +	crtc_w = state->crtc_w;
> +	crtc_h = state->crtc_h;
> +
> +	src_x = state->src_x >> 16;
> +	src_y = state->src_y >> 16;
> +	src_w = state->src_w >> 16;
> +	src_h = state->src_h >> 16;
> +
>  	actual_w = exynos_plane_get_size(crtc_x, crtc_w, mode->hdisplay);
>  	actual_h = exynos_plane_get_size(crtc_y, crtc_h, mode->vdisplay);
>  
> @@ -85,46 +101,93 @@ static void exynos_plane_mode_set(struct drm_plane *plane,
>  	}
>  
>  	/* set ratio */
> -	exynos_plane->h_ratio = (src_w << 16) / crtc_w;
> -	exynos_plane->v_ratio = (src_h << 16) / crtc_h;
> +	exynos_state->h_ratio = (src_w << 16) / crtc_w;
> +	exynos_state->v_ratio = (src_h << 16) / crtc_h;
>  
>  	/* set drm framebuffer data. */
> -	exynos_plane->src_x = src_x;
> -	exynos_plane->src_y = src_y;
> -	exynos_plane->src_w = (actual_w * exynos_plane->h_ratio) >> 16;
> -	exynos_plane->src_h = (actual_h * exynos_plane->v_ratio) >> 16;
> +	exynos_state->src.x = src_x;
> +	exynos_state->src.y = src_y;
> +	exynos_state->src.w = (actual_w * exynos_state->h_ratio) >> 16;
> +	exynos_state->src.h = (actual_h * exynos_state->v_ratio) >> 16;
>  
>  	/* set plane range to be displayed. */
> -	exynos_plane->crtc_x = crtc_x;
> -	exynos_plane->crtc_y = crtc_y;
> -	exynos_plane->crtc_w = actual_w;
> -	exynos_plane->crtc_h = actual_h;
> +	exynos_state->crtc.x = crtc_x;
> +	exynos_state->crtc.y = crtc_y;
> +	exynos_state->crtc.w = actual_w;
> +	exynos_state->crtc.h = actual_h;
>  
>  	DRM_DEBUG_KMS("plane : offset_x/y(%d,%d), width/height(%d,%d)",
> -			exynos_plane->crtc_x, exynos_plane->crtc_y,
> -			exynos_plane->crtc_w, exynos_plane->crtc_h);
> +			exynos_state->crtc.x, exynos_state->crtc.y,
> +			exynos_state->crtc.w, exynos_state->crtc.h);
> +}
>  
> -	plane->crtc = crtc;
> +static void exynos_drm_plane_reset(struct drm_plane *plane)
> +{
> +	struct exynos_drm_plane_state *exynos_state;
> +
> +	if (plane->state) {
> +		exynos_state = to_exynos_plane_state(plane->state);
> +		if (exynos_state->base.fb)
> +			drm_framebuffer_unreference(exynos_state->base.fb);
> +		kfree(exynos_state);
> +		plane->state = NULL;
> +	}
> +
> +	exynos_state = kzalloc(sizeof(*exynos_state), GFP_KERNEL);
> +	if (exynos_state) {
> +		plane->state = &exynos_state->base;
> +		plane->state->plane = plane;
> +	}
> +}
> +
> +static struct drm_plane_state *
> +exynos_drm_plane_duplicate_state(struct drm_plane *plane)
> +{
> +	struct exynos_drm_plane_state *exynos_state;
> +	struct exynos_drm_plane_state *copy;
> +
> +	exynos_state = to_exynos_plane_state(plane->state);
> +	copy = kzalloc(sizeof(*exynos_state), GFP_KERNEL);
> +	if (!copy)
> +		return NULL;
> +
> +	__drm_atomic_helper_plane_duplicate_state(plane, &copy->base);
> +	return &copy->base;
> +}
> +
> +static void exynos_drm_plane_destroy_state(struct drm_plane *plane,
> +					   struct drm_plane_state *old_state)
> +{
> +	struct exynos_drm_plane_state *old_exynos_state =
> +					to_exynos_plane_state(old_state);
> +	__drm_atomic_helper_plane_destroy_state(plane, old_state);
> +	kfree(old_exynos_state);
>  }
>  
>  static struct drm_plane_funcs exynos_plane_funcs = {
>  	.update_plane	= drm_atomic_helper_update_plane,
>  	.disable_plane	= drm_atomic_helper_disable_plane,
>  	.destroy	= drm_plane_cleanup,
> -	.reset = drm_atomic_helper_plane_reset,
> -	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
> -	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
> +	.reset		= exynos_drm_plane_reset,
> +	.atomic_duplicate_state = exynos_drm_plane_duplicate_state,
> +	.atomic_destroy_state = exynos_drm_plane_destroy_state,
>  };
>  
>  static int exynos_plane_atomic_check(struct drm_plane *plane,
>  				     struct drm_plane_state *state)
>  {
>  	struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
> +	struct exynos_drm_plane_state *exynos_state =
> +						to_exynos_plane_state(state);
> +	int ret = 0;
>  
> -	if (!state->fb)
> +	if (!state->crtc || !state->fb)
>  		return 0;
>  
> -	return 0;
> +	/* translate state into exynos_state */
> +	exynos_plane_mode_set(exynos_state);
> +
> +	return ret;
>  }
>  
>  static void exynos_plane_atomic_update(struct drm_plane *plane,
> @@ -137,12 +200,7 @@ static void exynos_plane_atomic_update(struct drm_plane *plane,
>  	if (!state->crtc)
>  		return;
>  
> -	exynos_plane_mode_set(plane, state->crtc, state->fb,
> -			      state->crtc_x, state->crtc_y,
> -			      state->crtc_w, state->crtc_h,
> -			      state->src_x >> 16, state->src_y >> 16,
> -			      state->src_w >> 16, state->src_h >> 16);
> -
> +	plane->crtc = state->crtc;
>  	exynos_plane->pending_fb = state->fb;
>  
>  	if (exynos_crtc->ops->update_plane)
> @@ -159,8 +217,7 @@ static void exynos_plane_atomic_disable(struct drm_plane *plane,
>  		return;
>  
>  	if (exynos_crtc->ops->disable_plane)
> -		exynos_crtc->ops->disable_plane(exynos_crtc,
> -						exynos_plane);
> +		exynos_crtc->ops->disable_plane(exynos_crtc, exynos_plane);

Just a nitpick here: this change doesn't belong to this patch. Otherwise
looks good:

Reviewed-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

	Gustavo
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 12/25] drm/exynos: mixer: use crtc->state->adjusted_mode instead of crtc->mode
  2015-11-10 13:23 ` [PATCH 12/25] drm/exynos: mixer: use crtc->state->adjusted_mode instead of crtc->mode Marek Szyprowski
@ 2015-11-13 11:47   ` Gustavo Padovan
  0 siblings, 0 replies; 70+ messages in thread
From: Gustavo Padovan @ 2015-11-13 11:47 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: dri-devel, linux-samsung-soc, Inki Dae, Joonyoung Shim,
	Seung-Woo Kim, Andrzej Hajda, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Tobias Jakobi,
	Javier Martinez Canillas

Hi Marek,

2015-11-10 Marek Szyprowski <m.szyprowski@samsung.com>:

> This patch replaces usage of crtc->mode with crtc->state->adjusted_mode
> like it is already done in common plane code.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_mixer.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

	Gustavo

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 13/25] drm/exynos: mixer: enable video overlay plane only when VP is available
  2015-11-10 13:23 ` [PATCH 13/25] drm/exynos: mixer: enable video overlay plane only when VP is available Marek Szyprowski
@ 2015-11-13 11:49   ` Gustavo Padovan
  0 siblings, 0 replies; 70+ messages in thread
From: Gustavo Padovan @ 2015-11-13 11:49 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: dri-devel, linux-samsung-soc, Inki Dae, Joonyoung Shim,
	Seung-Woo Kim, Andrzej Hajda, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Tobias Jakobi,
	Javier Martinez Canillas

Hi Marek,

2015-11-10 Marek Szyprowski <m.szyprowski@samsung.com>:

> Video overlay plane should be registered only when suitable hardware
> sub-block (Video Processor) is available.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_mixer.c | 3 +++
>  1 file changed, 3 insertions(+)

Good catch.

Reviewed-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

	Gustavo

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 14/25] drm/exynos: introduce exynos_drm_plane_config structure
  2015-11-10 13:23 ` [PATCH 14/25] drm/exynos: introduce exynos_drm_plane_config structure Marek Szyprowski
@ 2015-11-13 12:08   ` Gustavo Padovan
  2015-11-17 18:00   ` Tobias Jakobi
  1 sibling, 0 replies; 70+ messages in thread
From: Gustavo Padovan @ 2015-11-13 12:08 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Javier Martinez Canillas, Krzysztof Kozlowski, linux-samsung-soc,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, dri-devel,
	Andrzej Hajda, Tobias Jakobi

Hi Marek,

2015-11-10 Marek Szyprowski <m.szyprowski@samsung.com>:

> This patch adds common structure for keeping plane configuration and
> capabilities data. This patch is inspired by similar code developed by
> Tobias Jakobi.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 18 +++++++---
>  drivers/gpu/drm/exynos/exynos7_drm_decon.c    | 23 +++++++-----
>  drivers/gpu/drm/exynos/exynos_drm_drv.h       | 22 ++++++++++++
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c      | 25 ++++++++-----
>  drivers/gpu/drm/exynos/exynos_drm_plane.c     | 34 ++++++++----------
>  drivers/gpu/drm/exynos/exynos_drm_plane.h     |  7 ++--
>  drivers/gpu/drm/exynos/exynos_drm_vidi.c      | 25 ++++++++-----
>  drivers/gpu/drm/exynos/exynos_mixer.c         | 51 ++++++++++++++++-----------
>  8 files changed, 131 insertions(+), 74 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
> index 27039468364b..3c8b8e0240fe 100644
> --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
> +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
> @@ -26,7 +26,6 @@
>  #include "exynos_drm_iommu.h"
>  
>  #define WINDOWS_NR	3
> -#define CURSOR_WIN	2
>  #define MIN_FB_WIDTH_FOR_16WORD_BURST	128
>  
>  static const char * const decon_clks_name[] = {
> @@ -57,6 +56,7 @@ struct decon_context {
>  	struct drm_device		*drm_dev;
>  	struct exynos_drm_crtc		*crtc;
>  	struct exynos_drm_plane		planes[WINDOWS_NR];
> +	struct exynos_drm_plane_config	configs[WINDOWS_NR];
>  	void __iomem			*addr;
>  	struct clk			*clks[ARRAY_SIZE(decon_clks_name)];
>  	int				pipe;
> @@ -72,6 +72,12 @@ static const uint32_t decon_formats[] = {
>  	DRM_FORMAT_ARGB8888,
>  };
>  
> +static const enum drm_plane_type decon_win_types[WINDOWS_NR] = {
> +	DRM_PLANE_TYPE_PRIMARY,
> +	DRM_PLANE_TYPE_OVERLAY,
> +	DRM_PLANE_TYPE_CURSOR,
> +};
> +
>  static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask,
>  				  u32 val)
>  {
> @@ -499,7 +505,6 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
>  	struct exynos_drm_private *priv = drm_dev->dev_private;
>  	struct exynos_drm_plane *exynos_plane;
>  	enum exynos_drm_output_type out_type;
> -	enum drm_plane_type type;
>  	unsigned int win;
>  	int ret;
>  
> @@ -509,10 +514,13 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
>  	for (win = ctx->first_win; win < WINDOWS_NR; win++) {
>  		int tmp = (win == ctx->first_win) ? 0 : win;
>  
> -		type = exynos_plane_get_type(tmp, CURSOR_WIN);
> +		ctx->configs[win].pixel_formats = decon_formats;
> +		ctx->configs[win].num_pixel_formats = ARRAY_SIZE(decon_formats);
> +		ctx->configs[win].zpos = win;
> +		ctx->configs[win].type = decon_win_types[tmp];
> +
>  		ret = exynos_plane_init(drm_dev, &ctx->planes[win],
> -				1 << ctx->pipe, type, decon_formats,
> -				ARRAY_SIZE(decon_formats), win);
> +					1 << ctx->pipe, &ctx->configs[win]);
>  		if (ret)
>  			return ret;
>  	}
> diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
> index 7868d30d8eac..6b28e3f73e4e 100644
> --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
> +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
> @@ -41,13 +41,13 @@
>  #define MIN_FB_WIDTH_FOR_16WORD_BURST 128
>  
>  #define WINDOWS_NR	2
> -#define CURSOR_WIN	1
>  
>  struct decon_context {
>  	struct device			*dev;
>  	struct drm_device		*drm_dev;
>  	struct exynos_drm_crtc		*crtc;
>  	struct exynos_drm_plane		planes[WINDOWS_NR];
> +	struct exynos_drm_plane_config	configs[WINDOWS_NR];
>  	struct clk			*pclk;
>  	struct clk			*aclk;
>  	struct clk			*eclk;
> @@ -82,6 +82,11 @@ static const uint32_t decon_formats[] = {
>  	DRM_FORMAT_BGRA8888,
>  };
>  
> +static const enum drm_plane_type decon_win_types[WINDOWS_NR] = {
> +	DRM_PLANE_TYPE_PRIMARY,
> +	DRM_PLANE_TYPE_CURSOR,
> +};
> +
>  static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc)
>  {
>  	struct decon_context *ctx = crtc->ctx;
> @@ -672,8 +677,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
>  	struct decon_context *ctx = dev_get_drvdata(dev);
>  	struct drm_device *drm_dev = data;
>  	struct exynos_drm_plane *exynos_plane;
> -	enum drm_plane_type type;
> -	unsigned int zpos;
> +	unsigned int i;
>  	int ret;
>  
>  	ret = decon_ctx_initialize(ctx, drm_dev);
> @@ -682,11 +686,14 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
>  		return ret;
>  	}
>  
> -	for (zpos = 0; zpos < WINDOWS_NR; zpos++) {
> -		type = exynos_plane_get_type(zpos, CURSOR_WIN);
> -		ret = exynos_plane_init(drm_dev, &ctx->planes[zpos],
> -					1 << ctx->pipe, type, decon_formats,
> -					ARRAY_SIZE(decon_formats), zpos);
> +	for (i = 0; i < WINDOWS_NR; i++) {
> +		ctx->configs[i].pixel_formats = decon_formats;
> +		ctx->configs[i].num_pixel_formats = ARRAY_SIZE(decon_formats);
> +		ctx->configs[i].zpos = i;
> +		ctx->configs[i].type = decon_win_types[i];
> +
> +		ret = exynos_plane_init(drm_dev, &ctx->planes[i],
> +					1 << ctx->pipe, &ctx->configs[i]);
>  		if (ret)
>  			return ret;
>  	}
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
> index 482ed2c2ed89..9624855128a1 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
> @@ -84,10 +84,32 @@ to_exynos_plane_state(struct drm_plane_state *state)
>  
>  struct exynos_drm_plane {
>  	struct drm_plane base;
> +	const struct exynos_drm_plane_config *config;
>  	unsigned int zpos;
>  	struct drm_framebuffer *pending_fb;
>  };
>  
> +#define EXYNOS_DRM_PLANE_CAP_DOUBLE_X	(1 << 0)
> +#define EXYNOS_DRM_PLANE_CAP_DOUBLE_Y	(1 << 1)

I would leave this for a follow-up patch and keep only the change to
plane config on this one.

> +
> +/*
> + * Exynos DRM plane configuration structure.
> + *
> + * @zpos: z-position of the plane.
> + * @type: type of the plane (primary, cursor or overlay).
> + * @pixel_formats: supported pixel formats.
> + * @num_pixel_formats: number of elements in 'pixel_formats'.
> + * @capabilities: supported features (see EXYNOS_DRM_PLANE_CAP_*)
> + */
> +
> +struct exynos_drm_plane_config {
> +	unsigned int zpos;
> +	enum drm_plane_type type;
> +	const uint32_t *pixel_formats;
> +	unsigned int num_pixel_formats;
> +	unsigned int capabilities;
> +};
> +
>  /*
>   * Exynos drm crtc ops
>   *
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> index 40fa621e3963..44226b2b46c7 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> @@ -88,7 +88,6 @@
>  
>  /* FIMD has totally five hardware windows. */
>  #define WINDOWS_NR	5
> -#define CURSOR_WIN	4
>  
>  struct fimd_driver_data {
>  	unsigned int timing_base;
> @@ -151,6 +150,7 @@ struct fimd_context {
>  	struct drm_device		*drm_dev;
>  	struct exynos_drm_crtc		*crtc;
>  	struct exynos_drm_plane		planes[WINDOWS_NR];
> +	struct exynos_drm_plane_config	configs[WINDOWS_NR];
>  	struct clk			*bus_clk;
>  	struct clk			*lcd_clk;
>  	void __iomem			*regs;
> @@ -188,6 +188,14 @@ static const struct of_device_id fimd_driver_dt_match[] = {
>  };
>  MODULE_DEVICE_TABLE(of, fimd_driver_dt_match);
>  
> +static const enum drm_plane_type fimd_win_types[WINDOWS_NR] = {
> +	DRM_PLANE_TYPE_PRIMARY,
> +	DRM_PLANE_TYPE_OVERLAY,
> +	DRM_PLANE_TYPE_OVERLAY,
> +	DRM_PLANE_TYPE_OVERLAY,
> +	DRM_PLANE_TYPE_CURSOR,
> +};
> +
>  static const uint32_t fimd_formats[] = {
>  	DRM_FORMAT_C8,
>  	DRM_FORMAT_XRGB1555,
> @@ -944,18 +952,19 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
>  	struct drm_device *drm_dev = data;
>  	struct exynos_drm_private *priv = drm_dev->dev_private;
>  	struct exynos_drm_plane *exynos_plane;
> -	enum drm_plane_type type;
> -	unsigned int zpos;
> +	unsigned int i;
>  	int ret;
>  
>  	ctx->drm_dev = drm_dev;
>  	ctx->pipe = priv->pipe++;
>  
> -	for (zpos = 0; zpos < WINDOWS_NR; zpos++) {
> -		type = exynos_plane_get_type(zpos, CURSOR_WIN);
> -		ret = exynos_plane_init(drm_dev, &ctx->planes[zpos],
> -					1 << ctx->pipe, type, fimd_formats,
> -					ARRAY_SIZE(fimd_formats), zpos);
> +	for (i = 0; i < WINDOWS_NR; i++) {
> +		ctx->configs[i].pixel_formats = fimd_formats;
> +		ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats);
> +		ctx->configs[i].zpos = i;
> +		ctx->configs[i].type = fimd_win_types[i];
> +		ret = exynos_plane_init(drm_dev, &ctx->planes[i],
> +					1 << ctx->pipe, &ctx->configs[i]);
>  		if (ret)
>  			return ret;
>  	}
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
> index 365a738042e2..b620d7a76799 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
> @@ -246,28 +246,20 @@ static void exynos_plane_attach_zpos_property(struct drm_plane *plane,
>  	drm_object_attach_property(&plane->base, prop, zpos);
>  }
>  
> -enum drm_plane_type exynos_plane_get_type(unsigned int zpos,
> -					  unsigned int cursor_win)
> -{
> -		if (zpos == DEFAULT_WIN)
> -			return DRM_PLANE_TYPE_PRIMARY;
> -		else if (zpos == cursor_win)
> -			return DRM_PLANE_TYPE_CURSOR;
> -		else
> -			return DRM_PLANE_TYPE_OVERLAY;
> -}
> -
>  int exynos_plane_init(struct drm_device *dev,
>  		      struct exynos_drm_plane *exynos_plane,
> -		      unsigned long possible_crtcs, enum drm_plane_type type,
> -		      const uint32_t *formats, unsigned int fcount,
> -		      unsigned int zpos)
> +		      unsigned long possible_crtcs,
> +		      const struct exynos_drm_plane_config *config)
>  {
>  	int err;
>  
> -	err = drm_universal_plane_init(dev, &exynos_plane->base, possible_crtcs,
> -				       &exynos_plane_funcs, formats, fcount,
> -				       type);
> +	err = drm_universal_plane_init(dev, &exynos_plane->base,
> +				       possible_crtcs,
> +				       &exynos_plane_funcs,
> +				       config->pixel_formats,
> +				       config->num_pixel_formats,
> +				       config->type);
> +
>  	if (err) {
>  		DRM_ERROR("failed to initialize plane\n");
>  		return err;
> @@ -275,10 +267,12 @@ int exynos_plane_init(struct drm_device *dev,
>  
>  	drm_plane_helper_add(&exynos_plane->base, &plane_helper_funcs);
>  
> -	exynos_plane->zpos = zpos;
> +	exynos_plane->zpos = config->zpos;
> +	exynos_plane->config = config;
>  
> -	if (type == DRM_PLANE_TYPE_OVERLAY)
> -		exynos_plane_attach_zpos_property(&exynos_plane->base, zpos);
> +	if (config->type == DRM_PLANE_TYPE_OVERLAY)
> +		exynos_plane_attach_zpos_property(&exynos_plane->base,
> +						  config->zpos);
>  
>  	return 0;
>  }
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.h b/drivers/gpu/drm/exynos/exynos_drm_plane.h
> index abb641e64c23..0dd096548284 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_plane.h
> +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.h
> @@ -9,10 +9,7 @@
>   *
>   */
>  
> -enum drm_plane_type exynos_plane_get_type(unsigned int zpos,
> -					  unsigned int cursor_win);
>  int exynos_plane_init(struct drm_device *dev,
>  		      struct exynos_drm_plane *exynos_plane,
> -		      unsigned long possible_crtcs, enum drm_plane_type type,
> -		      const uint32_t *formats, unsigned int fcount,
> -		      unsigned int zpos);
> +		      unsigned long possible_crtcs,
> +		      const struct exynos_drm_plane_config *config);
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
> index 3ce141236fad..90701647aef1 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
> @@ -30,7 +30,6 @@
>  
>  /* vidi has totally three virtual windows. */
>  #define WINDOWS_NR		3
> -#define CURSOR_WIN		2
>  
>  #define ctx_from_connector(c)	container_of(c, struct vidi_context, \
>  					connector)
> @@ -90,6 +89,12 @@ static const uint32_t formats[] = {
>  	DRM_FORMAT_NV12,
>  };
>  
> +static const enum drm_plane_type vidi_win_types[WINDOWS_NR] = {
> +	DRM_PLANE_TYPE_PRIMARY,
> +	DRM_PLANE_TYPE_OVERLAY,
> +	DRM_PLANE_TYPE_CURSOR,
> +};
> +
>  static int vidi_enable_vblank(struct exynos_drm_crtc *crtc)
>  {
>  	struct vidi_context *ctx = crtc->ctx;
> @@ -442,17 +447,21 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
>  	struct drm_device *drm_dev = data;
>  	struct drm_encoder *encoder = &ctx->encoder;
>  	struct exynos_drm_plane *exynos_plane;
> -	enum drm_plane_type type;
> -	unsigned int zpos;
> +	struct exynos_drm_plane_config plane_config = { 0 };
> +	unsigned int i;
>  	int pipe, ret;
>  
>  	vidi_ctx_initialize(ctx, drm_dev);
>  
> -	for (zpos = 0; zpos < WINDOWS_NR; zpos++) {
> -		type = exynos_plane_get_type(zpos, CURSOR_WIN);
> -		ret = exynos_plane_init(drm_dev, &ctx->planes[zpos],
> -					1 << ctx->pipe, type, formats,
> -					ARRAY_SIZE(formats), zpos);
> +	plane_config.pixel_formats = formats;
> +	plane_config.num_pixel_formats = ARRAY_SIZE(formats);
> +
> +	for (i = 0; i < WINDOWS_NR; i++) {
> +		plane_config.zpos = i;
> +		plane_config.type = vidi_win_types(i);
> +
> +		ret = exynos_plane_init(drm_dev, &ctx->planes[i],
> +					1 << ctx->pipe, &plane_config);
>  		if (ret)
>  			return ret;
>  	}
> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
> index 015e85cabcc9..cdec3c1827c6 100644
> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
> @@ -43,7 +43,6 @@
>  
>  #define MIXER_WIN_NR		3
>  #define VP_DEFAULT_WIN		2
> -#define CURSOR_WIN		1
>  
>  /* The pixelformats that are natively supported by the mixer. */
>  #define MXR_FORMAT_RGB565	4
> @@ -112,6 +111,31 @@ struct mixer_drv_data {
>  	bool					has_sclk;
>  };
>  
> +static const struct exynos_drm_plane_config plane_configs[MIXER_WIN_NR] = {
> +	{
> +		.zpos = 0,
> +		.type = DRM_PLANE_TYPE_PRIMARY,
> +		.pixel_formats = mixer_formats,
> +		.num_pixel_formats = ARRAY_SIZE(mixer_formats),
> +		.capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
> +				EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
> +	}, {
> +		.zpos = 1,
> +		.type = DRM_PLANE_TYPE_CURSOR,
> +		.pixel_formats = mixer_formats,
> +		.num_pixel_formats = ARRAY_SIZE(mixer_formats),
> +		.capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
> +				EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
> +	}, {
> +		.zpos = 2,
> +		.type = DRM_PLANE_TYPE_OVERLAY,
> +		.pixel_formats = vp_formats,
> +		.num_pixel_formats = ARRAY_SIZE(vp_formats),
> +		.capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
> +				EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
> +	},
> +};
> +
>  static const u8 filter_y_horiz_tap8[] = {
>  	0,	-1,	-1,	-1,	-1,	-1,	-1,	-1,
>  	-1,	-1,	-1,	-1,	-1,	0,	0,	0,
> @@ -1188,38 +1212,25 @@ static struct of_device_id mixer_match_types[] = {
>  };
>  MODULE_DEVICE_TABLE(of, mixer_match_types);
>  
> +

nitpick: Extra blank line here.

	Gustavo
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 15/25] drm/exynos: add generic check for plane state
  2015-11-10 13:23 ` [PATCH 15/25] drm/exynos: add generic check for plane state Marek Szyprowski
@ 2015-11-13 12:30   ` Gustavo Padovan
  0 siblings, 0 replies; 70+ messages in thread
From: Gustavo Padovan @ 2015-11-13 12:30 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: dri-devel, linux-samsung-soc, Inki Dae, Joonyoung Shim,
	Seung-Woo Kim, Andrzej Hajda, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Tobias Jakobi,
	Javier Martinez Canillas

Hi Marek,

2015-11-10 Marek Szyprowski <m.szyprowski@samsung.com>:

> This patch adds generic check for plane state: pixel format and display
> area dimensions, so drivers can always assume that they get valid plane
> state to set.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_drv.h   |  2 ++
>  drivers/gpu/drm/exynos/exynos_drm_plane.c | 51 +++++++++++++++++++++++++++++++
>  2 files changed, 53 insertions(+)

Reviewed-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

	Gustavo

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 16/25] drm/exynos: mixer: use ratio precalculated in exynos_state
  2015-11-10 13:23 ` [PATCH 16/25] drm/exynos: mixer: use ratio precalculated in exynos_state Marek Szyprowski
@ 2015-11-13 12:35   ` Gustavo Padovan
  0 siblings, 0 replies; 70+ messages in thread
From: Gustavo Padovan @ 2015-11-13 12:35 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: dri-devel, linux-samsung-soc, Inki Dae, Joonyoung Shim,
	Seung-Woo Kim, Andrzej Hajda, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Tobias Jakobi,
	Javier Martinez Canillas

Hi Marek,

2015-11-10 Marek Szyprowski <m.szyprowski@samsung.com>:

> Common plane code already calculates and checks for supported scalling
> modes, so additional code in mixer driver can be now removed.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_mixer.c | 33 +++------------------------------
>  1 file changed, 3 insertions(+), 30 deletions(-)

Reviewed-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

	Gustavo

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH v2 1/4] ARM: dts: exynos4: add rotator nodes
  2015-11-13  8:35       ` Krzysztof Kozlowski
@ 2015-11-13 13:29         ` Marek Szyprowski
  2015-11-13 13:29           ` [PATCH v2 2/4] ARM: dts: exynos4: fix power domain for sysmmu-rotator device Marek Szyprowski
                             ` (3 more replies)
  0 siblings, 4 replies; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-13 13:29 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

This patch adds device node for Rotator device to Exynos 4210 and 4x12
device tree files.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos4.dtsi    | 9 +++++++++
 arch/arm/boot/dts/exynos4210.dtsi | 4 ++++
 arch/arm/boot/dts/exynos4x12.dtsi | 4 ++++
 3 files changed, 17 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 2f31f77..3e01d4d 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -718,6 +718,15 @@
 		iommus = <&sysmmu_jpeg>;
 	};
 
+	rotator: rotator@12810000 {
+		compatible = "samsung,exynos4210-rotator";
+		reg = <0x12810000 0x64>;
+		interrupts = <0 83 0>;
+		clocks = <&clock CLK_ROTATOR>;
+		clock-names = "rotator";
+		iommus = <&sysmmu_rotator>;
+	};
+
 	hdmi: hdmi@12D00000 {
 		compatible = "samsung,exynos4210-hdmi";
 		reg = <0x12D00000 0x70000>;
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 3e5ba66..e3048ae 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -279,3 +279,7 @@
 		<&clock CLK_OUT_CPU>, <&clock CLK_XXTI>, <&clock CLK_XUSBXTI>;
 	#clock-cells = <1>;
 };
+
+&rotator {
+	power-domains = <&pd_lcd0>;
+};
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index b77dac61..148b47a 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -339,6 +339,10 @@
 	compatible = "samsung,exynos4212-jpeg";
 };
 
+&rotator {
+	compatible = "samsung,exynos4212-rotator";
+};
+
 &mixer {
 	compatible = "samsung,exynos4212-mixer";
 	clock-names = "mixer", "hdmi", "sclk_hdmi", "vp";
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v2 2/4] ARM: dts: exynos4: fix power domain for sysmmu-rotator device
  2015-11-13 13:29         ` [PATCH v2 1/4] " Marek Szyprowski
@ 2015-11-13 13:29           ` Marek Szyprowski
  2015-11-14 11:37             ` Krzysztof Kozlowski
  2015-11-13 13:29           ` [PATCH v2 3/4] ARM: dts: exynos5250: add rotator node Marek Szyprowski
                             ` (2 subsequent siblings)
  3 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-13 13:29 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

Rotator device and it's SYSMMU belongs to different power domains
on various Exynos4 SoC revisions: LCD0 for 4210 and TOP for 4x12. This
patch fixes this by moving power-domains property to exynos4210.dtsi. TOP
power domain is always enabled and it is not represented in DTS.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos4.dtsi    | 1 -
 arch/arm/boot/dts/exynos4210.dtsi | 4 ++++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 3e01d4d..f3fe611 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -954,7 +954,6 @@
 		interrupts = <5 0>;
 		clock-names = "sysmmu", "master";
 		clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
-		power-domains = <&pd_lcd0>;
 		#iommu-cells = <0>;
 	};
 
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index e3048ae..b7474cf2 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -283,3 +283,7 @@
 &rotator {
 	power-domains = <&pd_lcd0>;
 };
+
+&sysmmu_rotator {
+	power-domains = <&pd_lcd0>;
+};
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v2 3/4] ARM: dts: exynos5250: add rotator node
  2015-11-13 13:29         ` [PATCH v2 1/4] " Marek Szyprowski
  2015-11-13 13:29           ` [PATCH v2 2/4] ARM: dts: exynos4: fix power domain for sysmmu-rotator device Marek Szyprowski
@ 2015-11-13 13:29           ` Marek Szyprowski
  2015-11-14 11:37             ` Krzysztof Kozlowski
  2015-11-13 13:29           ` [PATCH v2 4/4] ARM: dts: exynos542x: " Marek Szyprowski
  2015-11-14 11:37           ` [PATCH v2 1/4] ARM: dts: exynos4: add rotator nodes Krzysztof Kozlowski
  3 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-13 13:29 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

This patch adds device node for Rotator device to Exynos 5250 device
tree file.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos5250.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 88b9cf5..33e2d5f 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -269,6 +269,15 @@
 		iommu-names = "left", "right";
 	};
 
+	rotator: rotator@11C00000 {
+		compatible = "samsung,exynos5250-rotator";
+		reg = <0x11C00000 0x64>;
+		interrupts = <0 84 0>;
+		clocks = <&clock CLK_ROTATOR>;
+		clock-names = "rotator";
+		iommus = <&sysmmu_rotator>;
+	};
+
 	tmu: tmu@10060000 {
 		compatible = "samsung,exynos5250-tmu";
 		reg = <0x10060000 0x100>;
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v2 4/4] ARM: dts: exynos542x: add rotator node
  2015-11-13 13:29         ` [PATCH v2 1/4] " Marek Szyprowski
  2015-11-13 13:29           ` [PATCH v2 2/4] ARM: dts: exynos4: fix power domain for sysmmu-rotator device Marek Szyprowski
  2015-11-13 13:29           ` [PATCH v2 3/4] ARM: dts: exynos5250: add rotator node Marek Szyprowski
@ 2015-11-13 13:29           ` Marek Szyprowski
  2015-11-14 11:37             ` Krzysztof Kozlowski
  2015-11-14 11:37           ` [PATCH v2 1/4] ARM: dts: exynos4: add rotator nodes Krzysztof Kozlowski
  3 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-13 13:29 UTC (permalink / raw)
  To: dri-devel, linux-samsung-soc
  Cc: Marek Szyprowski, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Tobias Jakobi, Gustavo Padovan, Javier Martinez Canillas

This patch adds device node for Rotator device and it's SYSMMU to Exynos
542x device tree file.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/boot/dts/exynos5420.dtsi | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index 1b3d6c7..48a0a55 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -717,6 +717,15 @@
 		iommus = <&sysmmu_tv>;
 	};
 
+	rotator: rotator@11C00000 {
+		compatible = "samsung,exynos5250-rotator";
+		reg = <0x11C00000 0x64>;
+		interrupts = <0 84 0>;
+		clocks = <&clock CLK_ROTATOR>;
+		clock-names = "rotator";
+		iommus = <&sysmmu_rotator>;
+	};
+
 	gsc_0: video-scaler@13e00000 {
 		compatible = "samsung,exynos5-gsc";
 		reg = <0x13e00000 0x1000>;
@@ -1059,6 +1068,16 @@
 		#iommu-cells = <0>;
 	};
 
+	sysmmu_rotator: sysmmu@0x11D40000 {
+		compatible = "samsung,exynos-sysmmu";
+		reg = <0x11D40000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <4 0>;
+		clock-names = "sysmmu", "master";
+		clocks = <&clock CLK_SMMU_ROTATOR>, <&clock CLK_ROTATOR>;
+		#iommu-cells = <0>;
+	};
+
 	sysmmu_jpeg0: sysmmu@0x11F10000 {
 		compatible = "samsung,exynos-sysmmu";
 		reg = <0x11F10000 0x1000>;
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH v2 4/4] ARM: dts: exynos542x: add rotator node
  2015-11-13 13:29           ` [PATCH v2 4/4] ARM: dts: exynos542x: " Marek Szyprowski
@ 2015-11-14 11:37             ` Krzysztof Kozlowski
  0 siblings, 0 replies; 70+ messages in thread
From: Krzysztof Kozlowski @ 2015-11-14 11:37 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, linux-samsung-soc
  Cc: k.kozlowski.k, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Bartlomiej Zolnierkiewicz, Tobias Jakobi,
	Gustavo Padovan, Javier Martinez Canillas

W dniu 13.11.2015 o 22:29, Marek Szyprowski pisze:
> This patch adds device node for Rotator device and it's SYSMMU to Exynos
> 542x device tree file.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  arch/arm/boot/dts/exynos5420.dtsi | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 

I reviewed it already...

Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v2 1/4] ARM: dts: exynos4: add rotator nodes
  2015-11-13 13:29         ` [PATCH v2 1/4] " Marek Szyprowski
                             ` (2 preceding siblings ...)
  2015-11-13 13:29           ` [PATCH v2 4/4] ARM: dts: exynos542x: " Marek Szyprowski
@ 2015-11-14 11:37           ` Krzysztof Kozlowski
  3 siblings, 0 replies; 70+ messages in thread
From: Krzysztof Kozlowski @ 2015-11-14 11:37 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, linux-samsung-soc
  Cc: k.kozlowski.k, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Bartlomiej Zolnierkiewicz, Tobias Jakobi,
	Gustavo Padovan, Javier Martinez Canillas

W dniu 13.11.2015 o 22:29, Marek Szyprowski pisze:
> This patch adds device node for Rotator device to Exynos 4210 and 4x12
> device tree files.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  arch/arm/boot/dts/exynos4.dtsi    | 9 +++++++++
>  arch/arm/boot/dts/exynos4210.dtsi | 4 ++++
>  arch/arm/boot/dts/exynos4x12.dtsi | 4 ++++
>  3 files changed, 17 insertions(+)
> 

Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v2 2/4] ARM: dts: exynos4: fix power domain for sysmmu-rotator device
  2015-11-13 13:29           ` [PATCH v2 2/4] ARM: dts: exynos4: fix power domain for sysmmu-rotator device Marek Szyprowski
@ 2015-11-14 11:37             ` Krzysztof Kozlowski
  0 siblings, 0 replies; 70+ messages in thread
From: Krzysztof Kozlowski @ 2015-11-14 11:37 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, linux-samsung-soc
  Cc: k.kozlowski.k, Inki Dae, Joonyoung Shim, Seung-Woo Kim,
	Andrzej Hajda, Bartlomiej Zolnierkiewicz, Tobias Jakobi,
	Gustavo Padovan, Javier Martinez Canillas

W dniu 13.11.2015 o 22:29, Marek Szyprowski pisze:
> Rotator device and it's SYSMMU belongs to different power domains
> on various Exynos4 SoC revisions: LCD0 for 4210 and TOP for 4x12. This
> patch fixes this by moving power-domains property to exynos4210.dtsi. TOP
> power domain is always enabled and it is not represented in DTS.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  arch/arm/boot/dts/exynos4.dtsi    | 1 -
>  arch/arm/boot/dts/exynos4210.dtsi | 4 ++++
>  2 files changed, 4 insertions(+), 1 deletion(-)
> 

Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v2 3/4] ARM: dts: exynos5250: add rotator node
  2015-11-13 13:29           ` [PATCH v2 3/4] ARM: dts: exynos5250: add rotator node Marek Szyprowski
@ 2015-11-14 11:37             ` Krzysztof Kozlowski
  0 siblings, 0 replies; 70+ messages in thread
From: Krzysztof Kozlowski @ 2015-11-14 11:37 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, linux-samsung-soc
  Cc: Javier Martinez Canillas, Bartlomiej Zolnierkiewicz,
	k.kozlowski.k, Seung-Woo Kim, Andrzej Hajda, Tobias Jakobi

W dniu 13.11.2015 o 22:29, Marek Szyprowski pisze:
> This patch adds device node for Rotator device to Exynos 5250 device
> tree file.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  arch/arm/boot/dts/exynos5250.dtsi | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 

Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>

Best regards,
Krzysztof


_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem
  2015-11-12 14:46     ` Daniel Stone
  2015-11-12 15:10       ` Tobias Jakobi
@ 2015-11-16 11:35       ` Marek Szyprowski
  2015-11-16 11:52         ` Daniel Stone
  1 sibling, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-16 11:35 UTC (permalink / raw)
  To: Daniel Stone, Tobias Jakobi
  Cc: dri-devel, linux-samsung-soc, Javier Martinez Canillas,
	Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz, Seung-Woo Kim,
	Andrzej Hajda, Daniel Vetter, Eric Anholt

Hello,

On 2015-11-12 15:46, Daniel Stone wrote:
> On 12 November 2015 at 12:44, Tobias Jakobi
> <tjakobi@math.uni-bielefeld.de> wrote:
>> Daniel Stone wrote:
>>> On 10 November 2015 at 13:23, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>>>> This patch series introduces a new life into Exynos IPP (Image Post
>>>> Processing) subsystem by integrating it (transparently for userspace
>>>> applications) with Exynos DRM core plane management. This means that all
>>>> CRTC drivers transparently get support for standard features of IPP
>>>> subsystem like rotation and scaling.
>>>>
>>>> Support for features not supported natively by CRTC drivers is
>>>> implemented with a help of temporary framebuffers, where image data is
>>>> processed by IPP subsystem before performing the scanout by a CRTC driver.
>>> Hm, interesting. The RPi has a similar setup - VC4 can work either
>>> online (realtime scanout) or offline (mem2mem). Once the scene crosses
>>> a certain complexity boundary, it can no longer be composed in
>>> realtime and must fall back to mem2mem before it can be displayed.
>>>
>>> There was talk of having the fallback handled transparently in KMS for
>>> VC4 - similar to this - but the conclusion seemed to be that it was an
>>> inappropriate level of hidden complexity for KMS, and instead would
>>> best be handled by something like HWComposer directing it. Using HWC
>>> would then let you more intelligently split the scene from userspace
>>> (e.g. flatten some components but retain others as active planes).
>> I would be intererested in the performance implications of this
>> abstraction as well.
>>
>> I'd like to use the Exynos FIMC for CSC and scaling, but this operation
>> of course takes some time.
>>
>> I wonder how this interacts with page flipping. If I queue a pageflip
>> event with a buffer that needs to go through the IPP for display, where
>> does the delay caused by the operation factor it? If I understand this
>> correctly drmModePageFlip() still is going to return immediately, but I
>> might miss the next vblank period because the FIMC is still working on
>> the buffer.
> Hmm, from my reading of the patches, this didn't affect page-flip
> timings. In the sync case, it would block until the buffer was
> actually displayed, and in the async case, the event would still be
> delivered at the right time. But you're right that it does introduce
> hugely variable timings, which can be a problem for userspace which
> tries to be intelligent. And even then potentially misleading from a
> performance point of view: if userspace can rotate natively (e.g. as
> part of a composition blit, or when rendering buffers in the first
> place), then we can skip the extra work from G2D.

Page flip events are delivered to userspace at the right time. You are right
that there will be some delay between scheduling a buffer for display 
and the
moment it gets displayed by hardware, but imho good application should sync
audio/video to the vblank events not the moment of scheduling a buffer. So
this delay should not influence on the final quality of displayed

The only problem I see, especially when color space conversion will be 
added,
is how to tell generic application that some modes are preferred / not
preferred, so application would prefer native modes which are faster. On the
other hand application should be aware of the fact that hw scaling is 
usually
faster / less power demanding than cpu scaling, so it is better to use such
mode with additional processing instead of doing that work with the cpu.

On the other hand Exynos hardware also provides so called LOCAL PATH feature
for image processing, in case of which no temporary buffer is needed. This
mode should not introduce a delay. Implementing it is on my TODO list.

>> My problem here is that this abstraction would take too much control
>> from the user.
>>
>> Correct me if I have this wrong!
> I believe that was the concern previously, yeah. :) That, and encoding
> these semantics in a user-visible way could potentially be dangerous.

I believe that having this feature is quite beneficial for generic 
applications
(like weston for example). It is especially very useful for video overlay
display, where scaling, rotation and colorspace conversion are typical
use-cases. An alternative would be to introduce some generic API for a frame
buffer conversions.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem
  2015-11-16 11:35       ` Marek Szyprowski
@ 2015-11-16 11:52         ` Daniel Stone
  2015-11-17 18:13           ` Tobias Jakobi
  0 siblings, 1 reply; 70+ messages in thread
From: Daniel Stone @ 2015-11-16 11:52 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Tobias Jakobi, dri-devel, linux-samsung-soc,
	Javier Martinez Canillas, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, Andrzej Hajda,
	Daniel Vetter, Eric Anholt

Hi Marek,

On 16 November 2015 at 11:35, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> On 2015-11-12 15:46, Daniel Stone wrote:
>> On 12 November 2015 at 12:44, Tobias Jakobi
>> <tjakobi@math.uni-bielefeld.de> wrote:
>>> I wonder how this interacts with page flipping. If I queue a pageflip
>>> event with a buffer that needs to go through the IPP for display, where
>>> does the delay caused by the operation factor it? If I understand this
>>> correctly drmModePageFlip() still is going to return immediately, but I
>>> might miss the next vblank period because the FIMC is still working on
>>> the buffer.
>>
>> Hmm, from my reading of the patches, this didn't affect page-flip
>> timings. In the sync case, it would block until the buffer was
>> actually displayed, and in the async case, the event would still be
>> delivered at the right time. But you're right that it does introduce
>> hugely variable timings, which can be a problem for userspace which
>> tries to be intelligent. And even then potentially misleading from a
>> performance point of view: if userspace can rotate natively (e.g. as
>> part of a composition blit, or when rendering buffers in the first
>> place), then we can skip the extra work from G2D.
>
>
> Page flip events are delivered to userspace at the right time. You are right
> that there will be some delay between scheduling a buffer for display and
> the
> moment it gets displayed by hardware, but imho good application should sync
> audio/video to the vblank events not the moment of scheduling a buffer. So
> this delay should not influence on the final quality of displayed

Yes, of course: Weston does that as well. But the problem is that it
introduces a delay into the very last part of the pipeline: if I
submit a pageflip 8ms before vblank is due, I no longer have a
guarantee that it will land in time for the next frame.

> The only problem I see, especially when color space conversion will be
> added,
> is how to tell generic application that some modes are preferred / not
> preferred, so application would prefer native modes which are faster. On the
> other hand application should be aware of the fact that hw scaling is
> usually
> faster / less power demanding than cpu scaling, so it is better to use such
> mode with additional processing instead of doing that work with the cpu.

Of course, yes. The alternative is usually the GPU rather than CPU: if
you tried to do it in CPU you wouldn't come anywhere close to native
framerate.

>>> My problem here is that this abstraction would take too much control
>>> from the user.
>>>
>>> Correct me if I have this wrong!
>>
>> I believe that was the concern previously, yeah. :) That, and encoding
>> these semantics in a user-visible way could potentially be dangerous.
>
> I believe that having this feature is quite beneficial for generic
> applications
> (like weston for example). It is especially very useful for video overlay
> display, where scaling, rotation and colorspace conversion are typical
> use-cases. An alternative would be to introduce some generic API for a frame
> buffer conversions.

Well, it depends really. Weston is aware of rotation and passes this
information down to the clients, which are able to provide pre-rotated
buffers, so from a pure performance/profiling point of view, really
the clients should be doing this. In the case of V4L2/media clients,
if they fed the buffer into IPP themselves and scheduled the rotation,
this would push the performance hit earlier in the pipeline, when you
have more parallelism and buffering, rather than at the very last
point where it's quite serialised. In the case of GL/GPU clients, they
could perform the rotation as part of their rendering pipeline, and in
fact get the transformation for free.

The objection isn't to the functionality itself - which is very
useful! - but that it's done in a way that makes it very opaque. It is
quite clever, but having this as part of the semantics of core
functionality is problematic in a lot of ways. When this was
previously proposed, e.g. for VC4, the conclusion seemed to be that
for these reasons, any memory-to-memory buffer processing should be
performed in a separate step with a new API.

Cheers,
Daniel

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 14/25] drm/exynos: introduce exynos_drm_plane_config structure
  2015-11-10 13:23 ` [PATCH 14/25] drm/exynos: introduce exynos_drm_plane_config structure Marek Szyprowski
  2015-11-13 12:08   ` Gustavo Padovan
@ 2015-11-17 18:00   ` Tobias Jakobi
  2015-11-18 10:25     ` Marek Szyprowski
  1 sibling, 1 reply; 70+ messages in thread
From: Tobias Jakobi @ 2015-11-17 18:00 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, linux-samsung-soc
  Cc: Inki Dae, Joonyoung Shim, Seung-Woo Kim, Andrzej Hajda,
	Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz, Gustavo Padovan,
	Javier Martinez Canillas

Hello Marek,


Marek Szyprowski wrote:
> This patch adds common structure for keeping plane configuration and
> capabilities data. This patch is inspired by similar code developed by
> Tobias Jakobi.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 18 +++++++---
>  drivers/gpu/drm/exynos/exynos7_drm_decon.c    | 23 +++++++-----
>  drivers/gpu/drm/exynos/exynos_drm_drv.h       | 22 ++++++++++++
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c      | 25 ++++++++-----
>  drivers/gpu/drm/exynos/exynos_drm_plane.c     | 34 ++++++++----------
>  drivers/gpu/drm/exynos/exynos_drm_plane.h     |  7 ++--
>  drivers/gpu/drm/exynos/exynos_drm_vidi.c      | 25 ++++++++-----
>  drivers/gpu/drm/exynos/exynos_mixer.c         | 51 ++++++++++++++++-----------
>  8 files changed, 131 insertions(+), 74 deletions(-)
> 
<SNIP>
> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
> index 015e85cabcc9..cdec3c1827c6 100644
> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
> @@ -43,7 +43,6 @@
>  
>  #define MIXER_WIN_NR		3
>  #define VP_DEFAULT_WIN		2
> -#define CURSOR_WIN		1
>  
>  /* The pixelformats that are natively supported by the mixer. */
>  #define MXR_FORMAT_RGB565	4
> @@ -112,6 +111,31 @@ struct mixer_drv_data {
>  	bool					has_sclk;
>  };
>  
> +static const struct exynos_drm_plane_config plane_configs[MIXER_WIN_NR] = {
> +	{
> +		.zpos = 0,
> +		.type = DRM_PLANE_TYPE_PRIMARY,
> +		.pixel_formats = mixer_formats,
> +		.num_pixel_formats = ARRAY_SIZE(mixer_formats),
> +		.capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
> +				EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
> +	}, {
> +		.zpos = 1,
> +		.type = DRM_PLANE_TYPE_CURSOR,
> +		.pixel_formats = mixer_formats,
> +		.num_pixel_formats = ARRAY_SIZE(mixer_formats),
> +		.capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
> +				EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
> +	}, {
> +		.zpos = 2,
> +		.type = DRM_PLANE_TYPE_OVERLAY,
> +		.pixel_formats = vp_formats,
> +		.num_pixel_formats = ARRAY_SIZE(vp_formats),
> +		.capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
> +				EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
As far as I know the video plane supports arbitrary scaling and provides
no dedicated 'pixel doubling' mode.


With best wishes,
Tobias


> +	},
> +};
> +
>  static const u8 filter_y_horiz_tap8[] = {
>  	0,	-1,	-1,	-1,	-1,	-1,	-1,	-1,
>  	-1,	-1,	-1,	-1,	-1,	0,	0,	0,
> @@ -1188,38 +1212,25 @@ static struct of_device_id mixer_match_types[] = {
>  };
>  MODULE_DEVICE_TABLE(of, mixer_match_types);
>  
> +
>  static int mixer_bind(struct device *dev, struct device *manager, void *data)
>  {
>  	struct mixer_context *ctx = dev_get_drvdata(dev);
>  	struct drm_device *drm_dev = data;
>  	struct exynos_drm_plane *exynos_plane;
> -	unsigned int zpos;
> +	unsigned int i;
>  	int ret;
>  
>  	ret = mixer_initialize(ctx, drm_dev);
>  	if (ret)
>  		return ret;
>  
> -	for (zpos = 0; zpos < MIXER_WIN_NR; zpos++) {
> -		enum drm_plane_type type;
> -		const uint32_t *formats;
> -		unsigned int fcount;
> -
> -		if (zpos == VP_DEFAULT_WIN && !ctx->vp_enabled)
> +	for (i = 0; i < MIXER_WIN_NR; i++) {
> +		if (i == VP_DEFAULT_WIN && !ctx->vp_enabled)
>  			continue;
>  
> -		if (zpos < VP_DEFAULT_WIN) {
> -			formats = mixer_formats;
> -			fcount = ARRAY_SIZE(mixer_formats);
> -		} else {
> -			formats = vp_formats;
> -			fcount = ARRAY_SIZE(vp_formats);
> -		}
> -
> -		type = exynos_plane_get_type(zpos, CURSOR_WIN);
> -		ret = exynos_plane_init(drm_dev, &ctx->planes[zpos],
> -					1 << ctx->pipe, type, formats, fcount,
> -					zpos);
> +		ret = exynos_plane_init(drm_dev, &ctx->planes[i],
> +					1 << ctx->pipe, &plane_configs[i]);
>  		if (ret)
>  			return ret;
>  	}
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem
  2015-11-16 11:52         ` Daniel Stone
@ 2015-11-17 18:13           ` Tobias Jakobi
  0 siblings, 0 replies; 70+ messages in thread
From: Tobias Jakobi @ 2015-11-17 18:13 UTC (permalink / raw)
  To: Daniel Stone, Marek Szyprowski
  Cc: dri-devel, linux-samsung-soc, Javier Martinez Canillas,
	Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz, Seung-Woo Kim,
	Andrzej Hajda, Daniel Vetter, Eric Anholt

Hello guys,


Daniel Stone wrote:
> Hi Marek,
> 
> On 16 November 2015 at 11:35, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>> On 2015-11-12 15:46, Daniel Stone wrote:
>>> On 12 November 2015 at 12:44, Tobias Jakobi
>>> <tjakobi@math.uni-bielefeld.de> wrote:
>>>> I wonder how this interacts with page flipping. If I queue a pageflip
>>>> event with a buffer that needs to go through the IPP for display, where
>>>> does the delay caused by the operation factor it? If I understand this
>>>> correctly drmModePageFlip() still is going to return immediately, but I
>>>> might miss the next vblank period because the FIMC is still working on
>>>> the buffer.
>>>
>>> Hmm, from my reading of the patches, this didn't affect page-flip
>>> timings. In the sync case, it would block until the buffer was
>>> actually displayed, and in the async case, the event would still be
>>> delivered at the right time. But you're right that it does introduce
>>> hugely variable timings, which can be a problem for userspace which
>>> tries to be intelligent. And even then potentially misleading from a
>>> performance point of view: if userspace can rotate natively (e.g. as
>>> part of a composition blit, or when rendering buffers in the first
>>> place), then we can skip the extra work from G2D.
>>
>>
>> Page flip events are delivered to userspace at the right time. You are right
>> that there will be some delay between scheduling a buffer for display and
>> the
>> moment it gets displayed by hardware, but imho good application should sync
>> audio/video to the vblank events not the moment of scheduling a buffer. So
>> this delay should not influence on the final quality of displayed
> 
> Yes, of course: Weston does that as well. But the problem is that it
> introduces a delay into the very last part of the pipeline: if I
> submit a pageflip 8ms before vblank is due, I no longer have a
> guarantee that it will land in time for the next frame.
That's what I meant by "tight control" in my last message. The general
assumption is that page flipping can be done almost instantaneously,
because it's usually just some reprogramming of hw registers.

Also coupling any conversion to the actual presentation removes too much
freedom IMO. If I understand this correctly then e.g. the FIMC can work
standalone, so a user potentially wants to run a conversion queue on it,
feeding raw frames to it, getting converted frames out of it. Probably
everything in a separate thread.

In a video decoding context the user would also buffer the output, so
that he always has some frames in advance.

Doesn't work anymore if we couple things here.


>> The only problem I see, especially when color space conversion will be
>> added,
>> is how to tell generic application that some modes are preferred / not
>> preferred, so application would prefer native modes which are faster. On the
>> other hand application should be aware of the fact that hw scaling is
>> usually
>> faster / less power demanding than cpu scaling, so it is better to use such
>> mode with additional processing instead of doing that work with the cpu.
> 
> Of course, yes. The alternative is usually the GPU rather than CPU: if
> you tried to do it in CPU you wouldn't come anywhere close to native
> framerate.
> 
>>>> My problem here is that this abstraction would take too much control
>>>> from the user.
>>>>
>>>> Correct me if I have this wrong!
>>>
>>> I believe that was the concern previously, yeah. :) That, and encoding
>>> these semantics in a user-visible way could potentially be dangerous.
>>
>> I believe that having this feature is quite beneficial for generic
>> applications
>> (like weston for example). It is especially very useful for video overlay
>> display, where scaling, rotation and colorspace conversion are typical
>> use-cases. An alternative would be to introduce some generic API for a frame
>> buffer conversions.
> 
> Well, it depends really. Weston is aware of rotation and passes this
> information down to the clients, which are able to provide pre-rotated
> buffers, so from a pure performance/profiling point of view, really
> the clients should be doing this. In the case of V4L2/media clients,
> if they fed the buffer into IPP themselves and scheduled the rotation,
> this would push the performance hit earlier in the pipeline, when you
> have more parallelism and buffering, rather than at the very last
> point where it's quite serialised. In the case of GL/GPU clients, they
> could perform the rotation as part of their rendering pipeline, and in
> fact get the transformation for free.
> 
> The objection isn't to the functionality itself - which is very
> useful! - but that it's done in a way that makes it very opaque. It is
> quite clever, but having this as part of the semantics of core
> functionality is problematic in a lot of ways. When this was
> previously proposed, e.g. for VC4, the conclusion seemed to be that
> for these reasons, any memory-to-memory buffer processing should be
> performed in a separate step with a new API.
I assume there wasn't any discussion about how such an API would look like?



With best wishes,
Tobias

> 
> Cheers,
> Daniel
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 17/25] drm/exynos: fix clipping when scalling is enabled
  2015-11-10 13:23 ` [PATCH 17/25] drm/exynos: fix clipping when scalling is enabled Marek Szyprowski
@ 2015-11-17 18:17   ` Tobias Jakobi
  0 siblings, 0 replies; 70+ messages in thread
From: Tobias Jakobi @ 2015-11-17 18:17 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, linux-samsung-soc
  Cc: Inki Dae, Joonyoung Shim, Seung-Woo Kim, Andrzej Hajda,
	Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz, Gustavo Padovan,
	Javier Martinez Canillas

Small typo:
'scalling' -> 'scaling'

With best wishes,
Tobias

Marek Szyprowski wrote:
> This patch fixes calculation of src x/y offset for negative crtc x/y
> values when scalling is enabled. This fixes possible IOMMU fault when
> scalling is enabled.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_plane.c | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
> index e5af4cd5e287..348bcec30489 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
> @@ -85,25 +85,26 @@ static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state)
>  	src_w = state->src_w >> 16;
>  	src_h = state->src_h >> 16;
>  
> +	/* set ratio */
> +	exynos_state->h_ratio = (src_w << 16) / crtc_w;
> +	exynos_state->v_ratio = (src_h << 16) / crtc_h;
> +
> +	/* clip to visible area */
>  	actual_w = exynos_plane_get_size(crtc_x, crtc_w, mode->hdisplay);
>  	actual_h = exynos_plane_get_size(crtc_y, crtc_h, mode->vdisplay);
>  
>  	if (crtc_x < 0) {
>  		if (actual_w)
> -			src_x -= crtc_x;
> +			src_x += ((-crtc_x) * exynos_state->h_ratio) >> 16;
>  		crtc_x = 0;
>  	}
>  
>  	if (crtc_y < 0) {
>  		if (actual_h)
> -			src_y -= crtc_y;
> +			src_y += ((-crtc_y) * exynos_state->v_ratio) >> 16;
>  		crtc_y = 0;
>  	}
>  
> -	/* set ratio */
> -	exynos_state->h_ratio = (src_w << 16) / crtc_w;
> -	exynos_state->v_ratio = (src_h << 16) / crtc_h;
> -
>  	/* set drm framebuffer data. */
>  	exynos_state->src.x = src_x;
>  	exynos_state->src.y = src_y;
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 14/25] drm/exynos: introduce exynos_drm_plane_config structure
  2015-11-17 18:00   ` Tobias Jakobi
@ 2015-11-18 10:25     ` Marek Szyprowski
  2015-11-18 15:40       ` Tobias Jakobi
  0 siblings, 1 reply; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-18 10:25 UTC (permalink / raw)
  To: Tobias Jakobi, dri-devel, linux-samsung-soc
  Cc: Inki Dae, Joonyoung Shim, Seung-Woo Kim, Andrzej Hajda,
	Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz, Gustavo Padovan,
	Javier Martinez Canillas

Hello,

On 2015-11-17 19:00, Tobias Jakobi wrote:
> Marek Szyprowski wrote:
>> This patch adds common structure for keeping plane configuration and
>> capabilities data. This patch is inspired by similar code developed by
>> Tobias Jakobi.
>>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>>   drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 18 +++++++---
>>   drivers/gpu/drm/exynos/exynos7_drm_decon.c    | 23 +++++++-----
>>   drivers/gpu/drm/exynos/exynos_drm_drv.h       | 22 ++++++++++++
>>   drivers/gpu/drm/exynos/exynos_drm_fimd.c      | 25 ++++++++-----
>>   drivers/gpu/drm/exynos/exynos_drm_plane.c     | 34 ++++++++----------
>>   drivers/gpu/drm/exynos/exynos_drm_plane.h     |  7 ++--
>>   drivers/gpu/drm/exynos/exynos_drm_vidi.c      | 25 ++++++++-----
>>   drivers/gpu/drm/exynos/exynos_mixer.c         | 51 ++++++++++++++++-----------
>>   8 files changed, 131 insertions(+), 74 deletions(-)
>>
> <SNIP>
>> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
>> index 015e85cabcc9..cdec3c1827c6 100644
>> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
>> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
>> @@ -43,7 +43,6 @@
>>   
>>   #define MIXER_WIN_NR		3
>>   #define VP_DEFAULT_WIN		2
>> -#define CURSOR_WIN		1
>>   
>>   /* The pixelformats that are natively supported by the mixer. */
>>   #define MXR_FORMAT_RGB565	4
>> @@ -112,6 +111,31 @@ struct mixer_drv_data {
>>   	bool					has_sclk;
>>   };
>>   
>> +static const struct exynos_drm_plane_config plane_configs[MIXER_WIN_NR] = {
>> +	{
>> +		.zpos = 0,
>> +		.type = DRM_PLANE_TYPE_PRIMARY,
>> +		.pixel_formats = mixer_formats,
>> +		.num_pixel_formats = ARRAY_SIZE(mixer_formats),
>> +		.capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
>> +				EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
>> +	}, {
>> +		.zpos = 1,
>> +		.type = DRM_PLANE_TYPE_CURSOR,
>> +		.pixel_formats = mixer_formats,
>> +		.num_pixel_formats = ARRAY_SIZE(mixer_formats),
>> +		.capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
>> +				EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
>> +	}, {
>> +		.zpos = 2,
>> +		.type = DRM_PLANE_TYPE_OVERLAY,
>> +		.pixel_formats = vp_formats,
>> +		.num_pixel_formats = ARRAY_SIZE(vp_formats),
>> +		.capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
>> +				EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
> As far as I know the video plane supports arbitrary scaling and provides
> no dedicated 'pixel doubling' mode.

Right, I've forgotten that, I will update the code then. BTW, do you plan to
submit your patches for Mixer, which fixes alpha blending setup?

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 14/25] drm/exynos: introduce exynos_drm_plane_config structure
  2015-11-18 10:25     ` Marek Szyprowski
@ 2015-11-18 15:40       ` Tobias Jakobi
  2015-11-19 10:34         ` Marek Szyprowski
  0 siblings, 1 reply; 70+ messages in thread
From: Tobias Jakobi @ 2015-11-18 15:40 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, linux-samsung-soc
  Cc: Inki Dae, Joonyoung Shim, Seung-Woo Kim, Andrzej Hajda,
	Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz, Gustavo Padovan,
	Javier Martinez Canillas

Hey Marek,


Marek Szyprowski wrote:
> Hello,
> 
> On 2015-11-17 19:00, Tobias Jakobi wrote:
>> Marek Szyprowski wrote:
>>> This patch adds common structure for keeping plane configuration and
>>> capabilities data. This patch is inspired by similar code developed by
>>> Tobias Jakobi.
>>>
>>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>> ---
>>>   drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 18 +++++++---
>>>   drivers/gpu/drm/exynos/exynos7_drm_decon.c    | 23 +++++++-----
>>>   drivers/gpu/drm/exynos/exynos_drm_drv.h       | 22 ++++++++++++
>>>   drivers/gpu/drm/exynos/exynos_drm_fimd.c      | 25 ++++++++-----
>>>   drivers/gpu/drm/exynos/exynos_drm_plane.c     | 34 ++++++++----------
>>>   drivers/gpu/drm/exynos/exynos_drm_plane.h     |  7 ++--
>>>   drivers/gpu/drm/exynos/exynos_drm_vidi.c      | 25 ++++++++-----
>>>   drivers/gpu/drm/exynos/exynos_mixer.c         | 51
>>> ++++++++++++++++-----------
>>>   8 files changed, 131 insertions(+), 74 deletions(-)
>>>
>> <SNIP>
>>> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c
>>> b/drivers/gpu/drm/exynos/exynos_mixer.c
>>> index 015e85cabcc9..cdec3c1827c6 100644
>>> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
>>> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
>>> @@ -43,7 +43,6 @@
>>>     #define MIXER_WIN_NR        3
>>>   #define VP_DEFAULT_WIN        2
>>> -#define CURSOR_WIN        1
>>>     /* The pixelformats that are natively supported by the mixer. */
>>>   #define MXR_FORMAT_RGB565    4
>>> @@ -112,6 +111,31 @@ struct mixer_drv_data {
>>>       bool                    has_sclk;
>>>   };
>>>   +static const struct exynos_drm_plane_config
>>> plane_configs[MIXER_WIN_NR] = {
>>> +    {
>>> +        .zpos = 0,
>>> +        .type = DRM_PLANE_TYPE_PRIMARY,
>>> +        .pixel_formats = mixer_formats,
>>> +        .num_pixel_formats = ARRAY_SIZE(mixer_formats),
>>> +        .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
>>> +                EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
>>> +    }, {
>>> +        .zpos = 1,
>>> +        .type = DRM_PLANE_TYPE_CURSOR,
>>> +        .pixel_formats = mixer_formats,
>>> +        .num_pixel_formats = ARRAY_SIZE(mixer_formats),
>>> +        .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
>>> +                EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
>>> +    }, {
>>> +        .zpos = 2,
>>> +        .type = DRM_PLANE_TYPE_OVERLAY,
>>> +        .pixel_formats = vp_formats,
>>> +        .num_pixel_formats = ARRAY_SIZE(vp_formats),
>>> +        .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
>>> +                EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
>> As far as I know the video plane supports arbitrary scaling and provides
>> no dedicated 'pixel doubling' mode.
> 
> Right, I've forgotten that, I will update the code then. BTW, do you
> plan to
> submit your patches for Mixer, which fixes alpha blending setup?
I'll try to send a new version out this weekend. Any specific branch I
should base these on? (e.g. Inki's exynos-drm-next)

- Tobias


> 
> Best regards

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 14/25] drm/exynos: introduce exynos_drm_plane_config structure
  2015-11-18 15:40       ` Tobias Jakobi
@ 2015-11-19 10:34         ` Marek Szyprowski
  0 siblings, 0 replies; 70+ messages in thread
From: Marek Szyprowski @ 2015-11-19 10:34 UTC (permalink / raw)
  To: Tobias Jakobi, dri-devel, linux-samsung-soc
  Cc: Javier Martinez Canillas, Krzysztof Kozlowski,
	Bartlomiej Zolnierkiewicz, Seung-Woo Kim, Andrzej Hajda

Hello,

On 2015-11-18 16:40, Tobias Jakobi wrote:
> Marek Szyprowski wrote:
>> On 2015-11-17 19:00, Tobias Jakobi wrote:
>>> Marek Szyprowski wrote:
>>>> This patch adds common structure for keeping plane configuration and
>>>> capabilities data. This patch is inspired by similar code developed by
>>>> Tobias Jakobi.
>>>>
>>>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>>>> ---
>>>>    drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 18 +++++++---
>>>>    drivers/gpu/drm/exynos/exynos7_drm_decon.c    | 23 +++++++-----
>>>>    drivers/gpu/drm/exynos/exynos_drm_drv.h       | 22 ++++++++++++
>>>>    drivers/gpu/drm/exynos/exynos_drm_fimd.c      | 25 ++++++++-----
>>>>    drivers/gpu/drm/exynos/exynos_drm_plane.c     | 34 ++++++++----------
>>>>    drivers/gpu/drm/exynos/exynos_drm_plane.h     |  7 ++--
>>>>    drivers/gpu/drm/exynos/exynos_drm_vidi.c      | 25 ++++++++-----
>>>>    drivers/gpu/drm/exynos/exynos_mixer.c         | 51
>>>> ++++++++++++++++-----------
>>>>    8 files changed, 131 insertions(+), 74 deletions(-)
>>>>
>>> <SNIP>
>>>> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c
>>>> b/drivers/gpu/drm/exynos/exynos_mixer.c
>>>> index 015e85cabcc9..cdec3c1827c6 100644
>>>> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
>>>> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
>>>> @@ -43,7 +43,6 @@
>>>>      #define MIXER_WIN_NR        3
>>>>    #define VP_DEFAULT_WIN        2
>>>> -#define CURSOR_WIN        1
>>>>      /* The pixelformats that are natively supported by the mixer. */
>>>>    #define MXR_FORMAT_RGB565    4
>>>> @@ -112,6 +111,31 @@ struct mixer_drv_data {
>>>>        bool                    has_sclk;
>>>>    };
>>>>    +static const struct exynos_drm_plane_config
>>>> plane_configs[MIXER_WIN_NR] = {
>>>> +    {
>>>> +        .zpos = 0,
>>>> +        .type = DRM_PLANE_TYPE_PRIMARY,
>>>> +        .pixel_formats = mixer_formats,
>>>> +        .num_pixel_formats = ARRAY_SIZE(mixer_formats),
>>>> +        .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
>>>> +                EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
>>>> +    }, {
>>>> +        .zpos = 1,
>>>> +        .type = DRM_PLANE_TYPE_CURSOR,
>>>> +        .pixel_formats = mixer_formats,
>>>> +        .num_pixel_formats = ARRAY_SIZE(mixer_formats),
>>>> +        .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
>>>> +                EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
>>>> +    }, {
>>>> +        .zpos = 2,
>>>> +        .type = DRM_PLANE_TYPE_OVERLAY,
>>>> +        .pixel_formats = vp_formats,
>>>> +        .num_pixel_formats = ARRAY_SIZE(vp_formats),
>>>> +        .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE_X |
>>>> +                EXYNOS_DRM_PLANE_CAP_DOUBLE_Y,
>>> As far as I know the video plane supports arbitrary scaling and provides
>>> no dedicated 'pixel doubling' mode.
>> Right, I've forgotten that, I will update the code then. BTW, do you
>> plan to
>> submit your patches for Mixer, which fixes alpha blending setup?
> I'll try to send a new version out this weekend. Any specific branch I
> should base these on? (e.g. Inki's exynos-drm-next)

exynos-drm-next will be okay.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 70+ messages in thread

end of thread, other threads:[~2015-11-19 10:34 UTC | newest]

Thread overview: 70+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-10 13:23 [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Marek Szyprowski
2015-11-10 13:23 ` [PATCH 01/25] ARM: dts: exynos4: add rotator nodes Marek Szyprowski
2015-11-13  2:23   ` Krzysztof Kozlowski
2015-11-13  8:31     ` Marek Szyprowski
2015-11-13  8:35       ` Krzysztof Kozlowski
2015-11-13 13:29         ` [PATCH v2 1/4] " Marek Szyprowski
2015-11-13 13:29           ` [PATCH v2 2/4] ARM: dts: exynos4: fix power domain for sysmmu-rotator device Marek Szyprowski
2015-11-14 11:37             ` Krzysztof Kozlowski
2015-11-13 13:29           ` [PATCH v2 3/4] ARM: dts: exynos5250: add rotator node Marek Szyprowski
2015-11-14 11:37             ` Krzysztof Kozlowski
2015-11-13 13:29           ` [PATCH v2 4/4] ARM: dts: exynos542x: " Marek Szyprowski
2015-11-14 11:37             ` Krzysztof Kozlowski
2015-11-14 11:37           ` [PATCH v2 1/4] ARM: dts: exynos4: add rotator nodes Krzysztof Kozlowski
2015-11-13  2:29   ` [PATCH 01/25] " Krzysztof Kozlowski
2015-11-13  8:32     ` Marek Szyprowski
2015-11-13  8:36       ` Krzysztof Kozlowski
2015-11-10 13:23 ` [PATCH 02/25] ARM: dts: exynos542x: add rotator node Marek Szyprowski
2015-11-13  2:28   ` Krzysztof Kozlowski
2015-11-10 13:23 ` [PATCH 03/25] drm/exynos: gsc: prepare and unprepare gsc clock Marek Szyprowski
2015-11-12 15:11   ` Gustavo Padovan
2015-11-10 13:23 ` [PATCH 04/25] drm/exynos: gsc: fix wrong pm_runtime state Marek Szyprowski
2015-11-12 15:12   ` Gustavo Padovan
2015-11-10 13:23 ` [PATCH 05/25] drm/exynos: gsc: add device tree support and remove usage of static mappings Marek Szyprowski
2015-11-10 13:23 ` [PATCH 06/25] drm/exynos: fix to calculate offset of each plane for ipp fimc Marek Szyprowski
2015-11-12 15:20   ` Tobias Jakobi
2015-11-13  9:19     ` Marek Szyprowski
2015-11-10 13:23 ` [PATCH 07/25] drm/exynos: fix to calculate offset of each plane for ipp gsc Marek Szyprowski
2015-11-10 13:23 ` [PATCH 08/25] drm/exynos: rotator: convert to common clock framework Marek Szyprowski
2015-11-12 18:13   ` Gustavo Padovan
2015-11-10 13:23 ` [PATCH 09/25] drm/exynos: exynos7-decon: remove excessive check Marek Szyprowski
2015-11-12 18:15   ` Gustavo Padovan
2015-11-10 13:23 ` [PATCH 10/25] drm/exynos: move dma_addr attribute from exynos plane to exynos fb Marek Szyprowski
2015-11-12 18:25   ` Gustavo Padovan
2015-11-10 13:23 ` [PATCH 11/25] drm/exynos: introduce exynos_drm_plane_state structure Marek Szyprowski
2015-11-13 11:46   ` Gustavo Padovan
2015-11-10 13:23 ` [PATCH 12/25] drm/exynos: mixer: use crtc->state->adjusted_mode instead of crtc->mode Marek Szyprowski
2015-11-13 11:47   ` Gustavo Padovan
2015-11-10 13:23 ` [PATCH 13/25] drm/exynos: mixer: enable video overlay plane only when VP is available Marek Szyprowski
2015-11-13 11:49   ` Gustavo Padovan
2015-11-10 13:23 ` [PATCH 14/25] drm/exynos: introduce exynos_drm_plane_config structure Marek Szyprowski
2015-11-13 12:08   ` Gustavo Padovan
2015-11-17 18:00   ` Tobias Jakobi
2015-11-18 10:25     ` Marek Szyprowski
2015-11-18 15:40       ` Tobias Jakobi
2015-11-19 10:34         ` Marek Szyprowski
2015-11-10 13:23 ` [PATCH 15/25] drm/exynos: add generic check for plane state Marek Szyprowski
2015-11-13 12:30   ` Gustavo Padovan
2015-11-10 13:23 ` [PATCH 16/25] drm/exynos: mixer: use ratio precalculated in exynos_state Marek Szyprowski
2015-11-13 12:35   ` Gustavo Padovan
2015-11-10 13:23 ` [PATCH 17/25] drm/exynos: fix clipping when scalling is enabled Marek Szyprowski
2015-11-17 18:17   ` Tobias Jakobi
2015-11-10 13:23 ` [PATCH 18/25] drm/exynos: fimd: fix dma burst size setting for small plane size Marek Szyprowski
2015-11-12 15:17   ` Tobias Jakobi
2015-11-12 15:23     ` Daniel Stone
2015-11-10 13:23 ` [PATCH 19/25] drm/exynos: add fb pointer to exynos_drm_plane_state Marek Szyprowski
2015-11-10 13:23 ` [PATCH 20/25] drm/exynos: gem: set default alignment for dumb GEM buffers Marek Szyprowski
2015-11-10 13:23 ` [PATCH 21/25] drm/exynos: gem: remove old unused prototypes Marek Szyprowski
2015-11-10 13:23 ` [PATCH 22/25] drm/exynos: gem: simplify access to exynos gem object Marek Szyprowski
2015-11-10 13:23 ` [PATCH 23/25] drm/exynos: ipp: make framework context global Marek Szyprowski
2015-11-10 13:23 ` [PATCH 24/25] drm/exynos: add generic plane rotation property support Marek Szyprowski
2015-11-10 13:23 ` [PATCH 25/25] drm/exynos: add support for plane scaling Marek Szyprowski
2015-11-10 16:23 ` [PATCH 00/25] Exynos DRM: new life of IPP (Image Post Processing) subsystem Tobias Jakobi
2015-11-11 22:30 ` Emil Velikov
2015-11-12 11:14 ` Daniel Stone
2015-11-12 12:44   ` Tobias Jakobi
2015-11-12 14:46     ` Daniel Stone
2015-11-12 15:10       ` Tobias Jakobi
2015-11-16 11:35       ` Marek Szyprowski
2015-11-16 11:52         ` Daniel Stone
2015-11-17 18:13           ` Tobias Jakobi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.