[PATCH v5 5/9] drm: Extend framebuffer_check to handle formats with cpp/char_per_block 0

2018-10-19 Thread Alexandru Gheorghe
For formats that are supported only with non-linear modifiers it
doesn't make to much sense to define cpp or char_per_block, so that
will be set to 0.

This patch adds a restriction to force having a modifier attached when
cpp/char_per_block is 0, and to bypass checking the pitch restriction.

This had been discussed here.
[1] 
https://people.freedesktop.org/~cbrill/dri-log/?channel=dri-devel_names==2018-09-13_html=true

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_framebuffer.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_framebuffer.c 
b/drivers/gpu/drm/drm_framebuffer.c
index 6aca8a1ccdb6..e346d0ad92e0 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -195,8 +195,13 @@ static int framebuffer_check(struct drm_device *dev,
for (i = 0; i < info->num_planes; i++) {
unsigned int width = fb_plane_width(r->width, info, i);
unsigned int height = fb_plane_height(r->height, info, i);
+   unsigned int block_size = info->char_per_block[i];
u64 min_pitch = drm_format_info_min_pitch(info, i, width);
 
+   if (!block_size && (r->modifier[i] == DRM_FORMAT_MOD_LINEAR)) {
+   DRM_DEBUG_KMS("Format requires non-linear modifier for 
plane %d\n", i);
+   return -EINVAL;
+   }
if (!r->handles[i]) {
DRM_DEBUG_KMS("no buffer object handle for plane %d\n", 
i);
return -EINVAL;
@@ -208,7 +213,7 @@ static int framebuffer_check(struct drm_device *dev,
if ((uint64_t) height * r->pitches[i] + r->offsets[i] > 
UINT_MAX)
return -ERANGE;
 
-   if (r->pitches[i] < min_pitch) {
+   if (block_size && r->pitches[i] < min_pitch) {
DRM_DEBUG_KMS("bad pitch %u for plane %d\n", 
r->pitches[i], i);
return -EINVAL;
}
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 9/9] drm/selftests: Add tests for drm_format_info* helpers

2018-10-19 Thread Alexandru Gheorghe
Add selftests for the following newly added functions:
 - drm_format_info_block_width
 - drm_format_info_block_height
 - drm_format_info_min_pitch

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/selftests/Makefile|   3 +-
 .../gpu/drm/selftests/drm_modeset_selftests.h |   3 +
 drivers/gpu/drm/selftests/test-drm_format.c   | 290 ++
 .../drm/selftests/test-drm_modeset_common.h   |   3 +
 4 files changed, 298 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/selftests/test-drm_format.c

diff --git a/drivers/gpu/drm/selftests/Makefile 
b/drivers/gpu/drm/selftests/Makefile
index 7e6581921da0..07b4f88b422a 100644
--- a/drivers/gpu/drm/selftests/Makefile
+++ b/drivers/gpu/drm/selftests/Makefile
@@ -1,3 +1,4 @@
-test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o
+test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \
+  test-drm_format.o
 
 obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o
diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h 
b/drivers/gpu/drm/selftests/drm_modeset_selftests.h
index 9771290ed228..4e203ac8c134 100644
--- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h
@@ -7,3 +7,6 @@
  * Tests are executed in order by igt/drm_selftests_helper
  */
 selftest(check_plane_state, igt_check_plane_state)
+selftest(check_drm_format_block_width, igt_check_drm_format_block_width)
+selftest(check_drm_format_block_height, igt_check_drm_format_block_height)
+selftest(check_drm_format_min_pitch, igt_check_drm_format_min_pitch)
diff --git a/drivers/gpu/drm/selftests/test-drm_format.c 
b/drivers/gpu/drm/selftests/test-drm_format.c
new file mode 100644
index ..5abfd5e28d7d
--- /dev/null
+++ b/drivers/gpu/drm/selftests/test-drm_format.c
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test cases for the drm_format functions
+ */
+
+#define pr_fmt(fmt) "drm_format: " fmt
+
+#include 
+#include 
+
+#include 
+
+#include "test-drm_modeset_common.h"
+
+int igt_check_drm_format_block_width(void *ignored)
+{
+   const struct drm_format_info *info = NULL;
+
+   /* Test invalid arguments */
+   FAIL_ON(drm_format_info_block_width(info, 0) != 0);
+   FAIL_ON(drm_format_info_block_width(info, -1) != 0);
+   FAIL_ON(drm_format_info_block_width(info, 1) != 0);
+
+   /* Test 1 plane format */
+   info = drm_format_info(DRM_FORMAT_XRGB);
+   FAIL_ON(!info);
+   FAIL_ON(drm_format_info_block_width(info, 0) != 1);
+   FAIL_ON(drm_format_info_block_width(info, 1) != 0);
+   FAIL_ON(drm_format_info_block_width(info, -1) != 0);
+
+   /* Test 2 planes format */
+   info = drm_format_info(DRM_FORMAT_NV12);
+   FAIL_ON(!info);
+   FAIL_ON(drm_format_info_block_width(info, 0) != 1);
+   FAIL_ON(drm_format_info_block_width(info, 1) != 1);
+   FAIL_ON(drm_format_info_block_width(info, 2) != 0);
+   FAIL_ON(drm_format_info_block_width(info, -1) != 0);
+
+   /* Test 3 planes format */
+   info = drm_format_info(DRM_FORMAT_YUV422);
+   FAIL_ON(!info);
+   FAIL_ON(drm_format_info_block_width(info, 0) != 1);
+   FAIL_ON(drm_format_info_block_width(info, 1) != 1);
+   FAIL_ON(drm_format_info_block_width(info, 2) != 1);
+   FAIL_ON(drm_format_info_block_width(info, 3) != 0);
+   FAIL_ON(drm_format_info_block_width(info, -1) != 0);
+
+   /* Test a tiled format */
+   info = drm_format_info(DRM_FORMAT_X0L0);
+   FAIL_ON(!info);
+   FAIL_ON(drm_format_info_block_width(info, 0) != 2);
+   FAIL_ON(drm_format_info_block_width(info, 1) != 0);
+   FAIL_ON(drm_format_info_block_width(info, -1) != 0);
+
+   return 0;
+}
+
+int igt_check_drm_format_block_height(void *ignored)
+{
+   const struct drm_format_info *info = NULL;
+
+   /* Test invalid arguments */
+   FAIL_ON(drm_format_info_block_height(info, 0) != 0);
+   FAIL_ON(drm_format_info_block_height(info, -1) != 0);
+   FAIL_ON(drm_format_info_block_height(info, 1) != 0);
+
+   /* Test 1 plane format */
+   info = drm_format_info(DRM_FORMAT_XRGB);
+   FAIL_ON(!info);
+   FAIL_ON(drm_format_info_block_height(info, 0) != 1);
+   FAIL_ON(drm_format_info_block_height(info, 1) != 0);
+   FAIL_ON(drm_format_info_block_height(info, -1) != 0);
+
+   /* Test 2 planes format */
+   info = drm_format_info(DRM_FORMAT_NV12);
+   FAIL_ON(!info);
+   FAIL_ON(drm_format_info_block_height(info, 0) != 1);
+   FAIL_ON(drm_format_info_block_height(info, 1) != 1);
+   FAIL_ON(drm_format_info_block_height(info, 2) != 0);
+   FAIL_ON(drm_format_info_block_height(info, -1) != 0);
+
+   /* Test 3 planes format */
+   info = drm_format_info(DRM_FORMAT_YUV422);
+   FAIL_ON(!info);
+   FAIL_ON(drm_format_info_block_height(info, 0) != 1);
+   FAIL_ON(drm_form

[PATCH v5 7/9] drm/afbc: Add AFBC modifier usage documentation

2018-10-19 Thread Alexandru Gheorghe
From: Brian Starkey 

AFBC is a flexible, proprietary, lossless compression protocol and
format, with a number of defined DRM format modifiers. To facilitate
consistency and compatibility between different AFBC producers and
consumers, document the expectations for usage of the AFBC DRM format
modifiers in a new .rst chapter.

Signed-off-by: Brian Starkey 
Reviewed-by: Liviu Dudau 
---
 Documentation/gpu/afbc.rst| 233 ++
 Documentation/gpu/drivers.rst |   1 +
 MAINTAINERS   |   1 +
 include/uapi/drm/drm_fourcc.h |   3 +
 4 files changed, 238 insertions(+)
 create mode 100644 Documentation/gpu/afbc.rst

diff --git a/Documentation/gpu/afbc.rst b/Documentation/gpu/afbc.rst
new file mode 100644
index ..922d955da192
--- /dev/null
+++ b/Documentation/gpu/afbc.rst
@@ -0,0 +1,233 @@
+===
+ Arm Framebuffer Compression (AFBC)
+===
+
+AFBC is a proprietary lossless image compression protocol and format.
+It provides fine-grained random access and minimizes the amount of
+data transferred between IP blocks.
+
+AFBC can be enabled on drivers which support it via use of the AFBC
+format modifiers defined in drm_fourcc.h. See DRM_FORMAT_MOD_ARM_AFBC(*).
+
+All users of the AFBC modifiers must follow the usage guidelines laid
+out in this document, to ensure compatibility across different AFBC
+producers and consumers.
+
+Components and Ordering
+===
+
+AFBC streams can contain several components - where a component
+corresponds to a color channel (i.e. R, G, B, X, A, Y, Cb, Cr).
+The assignment of input/output color channels must be consistent
+between the encoder and the decoder for correct operation, otherwise
+the consumer will interpret the decoded data incorrectly.
+
+Furthermore, when the lossless colorspace transform is used
+(AFBC_FORMAT_MOD_YTR, which should be enabled for RGB buffers for
+maximum compression efficiency), the component order must be:
+
+ * Component 0: R
+ * Component 1: G
+ * Component 2: B
+
+The component ordering is communicated via the fourcc code in the
+fourcc:modifier pair. In general, component '0' is considered to
+reside in the least-significant bits of the corresponding linear
+format. For example, COMP(bits):
+
+ * DRM_FORMAT_ABGR
+
+   * Component 0: R(8)
+   * Component 1: G(8)
+   * Component 2: B(8)
+   * Component 3: A(8)
+
+ * DRM_FORMAT_BGR888
+
+   * Component 0: R(8)
+   * Component 1: G(8)
+   * Component 2: B(8)
+
+ * DRM_FORMAT_YUYV
+
+   * Component 0: Y(8)
+   * Component 1: Cb(8, 2x1 subsampled)
+   * Component 2: Cr(8, 2x1 subsampled)
+
+In AFBC, 'X' components are not treated any differently from any other
+component. Therefore, an AFBC buffer with fourcc DRM_FORMAT_XBGR
+encodes with 4 components, like so:
+
+ * DRM_FORMAT_XBGR
+
+   * Component 0: R(8)
+   * Component 1: G(8)
+   * Component 2: B(8)
+   * Component 3: X(8)
+
+Please note, however, that the inclusion of a "wasted" 'X' channel is
+bad for compression efficiency, and so it's recommended to avoid
+formats containing 'X' bits. If a fourth component is
+required/expected by the encoder/decoder, then it is recommended to
+instead use an equivalent format with alpha, setting all alpha bits to
+'1'. If there is no requirement for a fourth component, then a format
+which doesn't include alpha can be used, e.g. DRM_FORMAT_BGR888.
+
+Number of Planes
+
+
+Formats which are typically multi-planar in linear layouts (e.g. YUV
+420), can be encoded into one, or multiple, AFBC planes. As with
+component order, the encoder and decoder must agree about the number
+of planes in order to correctly decode the buffer. The fourcc code is
+used to determine the number of encoded planes in an AFBC buffer,
+matching the number of planes for the linear (unmodified) format.
+Within each plane, the component ordering also follows the fourcc
+code:
+
+For example:
+
+ * DRM_FORMAT_YUYV: nplanes = 1
+
+   * Plane 0:
+
+ * Component 0: Y(8)
+ * Component 1: Cb(8, 2x1 subsampled)
+ * Component 2: Cr(8, 2x1 subsampled)
+
+ * DRM_FORMAT_NV12: nplanes = 2
+
+   * Plane 0:
+
+ * Component 0: Y(8)
+
+   * Plane 1:
+
+ * Component 0: Cb(8, 2x1 subsampled)
+ * Component 1: Cr(8, 2x1 subsampled)
+
+Cross-device interoperability
+=
+
+For maximum compatibility across devices, the table below defines
+canonical formats for use between AFBC-enabled devices. Formats which
+are listed here must be used exactly as specified when using the AFBC
+modifiers. Formats which are not listed should be avoided.
+
+.. flat-table:: AFBC formats
+
+   * - Fourcc code
+ - Description
+ - Planes/Components
+
+   * - DRM_FORMAT_ABGR2101010
+ - 10-bit per component RGB, with 2-bit alpha
+ - Plane 0: 4 components
+  * Component 0: R(10)
+  * Component 1: G(10)
+  * Component 2: B(10)
+ 

[PATCH v5 8/9] drm/selftest: Refactor test-drm_plane_helper

2018-10-19 Thread Alexandru Gheorghe
The idea is to split test implementations in different compilation
units, but have one single place where we define the list of tests,
in this case(drm_modeset_selftests.h).

Signed-off-by: Alexandru Gheorghe 
---
 ...er_selftests.h => drm_modeset_selftests.h} |  0
 .../drm/selftests/test-drm_modeset_common.c   | 11 ++-
 .../drm/selftests/test-drm_modeset_common.h   |  2 +-
 .../gpu/drm/selftests/test-drm_plane_helper.c | 19 +--
 4 files changed, 12 insertions(+), 20 deletions(-)
 rename drivers/gpu/drm/selftests/{drm_plane_helper_selftests.h => 
drm_modeset_selftests.h} (100%)

diff --git a/drivers/gpu/drm/selftests/drm_plane_helper_selftests.h 
b/drivers/gpu/drm/selftests/drm_modeset_selftests.h
similarity index 100%
rename from drivers/gpu/drm/selftests/drm_plane_helper_selftests.h
rename to drivers/gpu/drm/selftests/drm_modeset_selftests.h
diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.c 
b/drivers/gpu/drm/selftests/test-drm_modeset_common.c
index fad5209043f1..2a7f93774006 100644
--- a/drivers/gpu/drm/selftests/test-drm_modeset_common.c
+++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.c
@@ -7,9 +7,18 @@
 
 #include "test-drm_modeset_common.h"
 
+#define TESTS "drm_modeset_selftests.h"
+#include "drm_selftest.h"
+
+#include "drm_selftest.c"
+
 static int __init test_drm_modeset_init(void)
 {
-   return test_drm_plane_helper();
+   int err;
+
+   err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL);
+
+   return err > 0 ? 0 : err;
 }
 
 static void __exit test_drm_modeset_exit(void)
diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h 
b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
index bdeba264661f..b0065a2eb067 100644
--- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h
+++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
@@ -13,6 +13,6 @@
 
 #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n")
 
-int test_drm_plane_helper(void);
+int igt_check_plane_state(void *ignored);
 
 #endif
diff --git a/drivers/gpu/drm/selftests/test-drm_plane_helper.c 
b/drivers/gpu/drm/selftests/test-drm_plane_helper.c
index 0dad2f812a27..0a9553f51796 100644
--- a/drivers/gpu/drm/selftests/test-drm_plane_helper.c
+++ b/drivers/gpu/drm/selftests/test-drm_plane_helper.c
@@ -11,9 +11,6 @@
 
 #include "test-drm_modeset_common.h"
 
-#define TESTS "drm_plane_helper_selftests.h"
-#include "drm_selftest.h"
-
 static void set_src(struct drm_plane_state *plane_state,
unsigned src_x, unsigned src_y,
unsigned src_w, unsigned src_h)
@@ -76,7 +73,7 @@ static bool check_crtc_eq(struct drm_plane_state *plane_state,
return true;
 }
 
-static int igt_check_plane_state(void *ignored)
+int igt_check_plane_state(void *ignored)
 {
int ret;
 
@@ -220,17 +217,3 @@ static int igt_check_plane_state(void *ignored)
 
return 0;
 }
-
-#include "drm_selftest.c"
-
-/**
- * test_drm_plane_helper - Run drm plane helper selftests.
- */
-int test_drm_plane_helper(void)
-{
-   int err;
-
-   err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL);
-
-   return err > 0 ? 0 : err;
-}
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 0/9] Add method to describe tile/bit_level_packed formats

2018-10-19 Thread Alexandru Gheorghe
Changes since v4:
  - Rebased selftests on latest drm-misc-next

Changes since v3:
  - added an utility function that computes the minimum pitch.
  - switched drm_format_info to in-line member documentation.
  - Cleanup/Improved the kernel doc.
  - Added selftests for: drm_format_info* helpers.

There has been some discussion about extending drm core to handle
linear tile formats, in the series sent by me here [1] and how to
handle formats that are intended to be used just with
modifiers(particularly AFBC modifiers) on Brian series [2] and on IRC
here [3] and [4].

Hence, this big-merged series:

Patch 1: Just a preparation patch that converts the drm_format_info
kerneldoc to in-line documentation.

Patches 2-4: handle tiled formats both in core and in malidp driver,
this is done by extending drm_format_info with three new fields
char_per_block, block_w, block_h and consistently handle in the generic
code paths, both linear tiled formats and normal formats.
What's different from [1] is the interpretation of pitch for tile
formats which has been kept to be the same as for the other formats:
pitch = average_chars_per_pixel * width.

Patches 5-7: Introduce the YUV AFBC formats, the only thing noteworthy
here is that cpp/char_per_block are set to 0 for formats where it's
mandatory to be used together with a non-linear modifier and then that
is used to bypass pitch check in framebuffer_check for formats that
have cpp/char_per_block set to 0.

Patches 8-9: A small fix for test-drm-helper module and adds self
tests for drm_format_info* helpers. For the other touched functions we
need a bit more infrastructure to be able to unittest/selftest them,
since they need a stub drm_device and drm_file.

As a side note, igt master branch doesn't seem to be using
test-drm-helper.ko, so I just tested by loading/unloading the module
manually.


[1] https://lists.freedesktop.org/archives/dri-devel/2018-September/188245.html
[2] https://lists.freedesktop.org/archives/dri-devel/2018-September/189620.html
[3] 
https://people.freedesktop.org/~cbrill/dri-log/?channel=dri-devel_names==2018-09-13_html=true
[4] 
https://people.freedesktop.org/~cbrill/dri-log/?channel=dri-devel_names==2018-09-14_html=true


Alexandru Gheorghe (7):
  drm: fourcc: Convert drm_format_info kerneldoc to in-line member
documentation
  drm/fourcc: Add char_per_block, block_w and block_h in drm_format_info
  drm/fourcc: Add fourcc for Mali linear tiled formats
  drm: mali-dp: Enable Mali-DP tiled buffer formats
  drm: Extend framebuffer_check to handle formats with
cpp/char_per_block 0
  drm/selftest: Refactor test-drm_plane_helper
  drm/selftests: Add tests for drm_format_info* helpers

Brian Starkey (2):
  drm/fourcc: Add AFBC yuv fourccs for Mali
  drm/afbc: Add AFBC modifier usage documentation

 Documentation/gpu/afbc.rst| 233 ++
 Documentation/gpu/drivers.rst |   1 +
 MAINTAINERS   |   1 +
 drivers/gpu/drm/arm/malidp_hw.c   |  14 +-
 drivers/gpu/drm/arm/malidp_planes.c   |  23 +-
 drivers/gpu/drm/drm_fb_cma_helper.c   |  21 +-
 drivers/gpu/drm/drm_fb_helper.c   |   6 +
 drivers/gpu/drm/drm_fourcc.c  |  87 ++
 drivers/gpu/drm/drm_framebuffer.c |  11 +-
 drivers/gpu/drm/drm_gem_framebuffer_helper.c  |   2 +-
 drivers/gpu/drm/selftests/Makefile|   3 +-
 ...er_selftests.h => drm_modeset_selftests.h} |   3 +
 drivers/gpu/drm/selftests/test-drm_format.c   | 290 ++
 .../drm/selftests/test-drm_modeset_common.c   |  11 +-
 .../drm/selftests/test-drm_modeset_common.h   |   5 +-
 .../gpu/drm/selftests/test-drm_plane_helper.c |  19 +-
 include/drm/drm_fourcc.h  |  89 +-
 include/uapi/drm/drm_fourcc.h |  31 ++
 18 files changed, 806 insertions(+), 44 deletions(-)
 create mode 100644 Documentation/gpu/afbc.rst
 rename drivers/gpu/drm/selftests/{drm_plane_helper_selftests.h => 
drm_modeset_selftests.h} (61%)
 create mode 100644 drivers/gpu/drm/selftests/test-drm_format.c

-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 4/9] drm: mali-dp: Enable Mali-DP tiled buffer formats

2018-10-19 Thread Alexandru Gheorghe
Enable the following formats
- DRM_FORMAT_X0L0: DP650
- DRM_FORMAT_X0L2: DP550, DP650

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/arm/malidp_hw.c | 14 +++---
 drivers/gpu/drm/arm/malidp_planes.c | 23 +--
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index c94a4422e0e9..e01fc0e5b503 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -77,12 +77,18 @@ static const struct malidp_format_id malidp500_de_formats[] 
= {
{ DRM_FORMAT_YUYV, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 2) },\
{ DRM_FORMAT_UYVY, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 3) },\
{ DRM_FORMAT_NV12, DE_VIDEO1 | DE_VIDEO2 | SE_MEMWRITE, MALIDP_ID(5, 6) 
},  \
-   { DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }
+   { DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }, \
+   { DRM_FORMAT_X0L2, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 6)}
 
 static const struct malidp_format_id malidp550_de_formats[] = {
MALIDP_COMMON_FORMATS,
 };
 
+static const struct malidp_format_id malidp650_de_formats[] = {
+   MALIDP_COMMON_FORMATS,
+   { DRM_FORMAT_X0L0, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 4)},
+};
+
 static const struct malidp_layer malidp500_layers[] = {
{ DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, 
MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB },
{ DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, 
MALIDP_DE_LG_STRIDE, 0 },
@@ -595,6 +601,8 @@ static int malidp550_rotmem_required(struct 
malidp_hw_device *hwdev, u16 w, u16
case DRM_FORMAT_BGR565:
case DRM_FORMAT_UYVY:
case DRM_FORMAT_YUYV:
+   case DRM_FORMAT_X0L0:
+   case DRM_FORMAT_X0L2:
bytes_per_col = 32;
break;
/* 16 lines at 1.5 bytes per pixel */
@@ -860,8 +868,8 @@ const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES] = {
MALIDP550_DC_IRQ_SE,
.vsync_irq = MALIDP550_DC_IRQ_CONF_VALID,
},
-   .pixel_formats = malidp550_de_formats,
-   .n_pixel_formats = ARRAY_SIZE(malidp550_de_formats),
+   .pixel_formats = malidp650_de_formats,
+   .n_pixel_formats = ARRAY_SIZE(malidp650_de_formats),
.bus_align_bytes = 16,
},
.query_hw = malidp650_query_hw,
diff --git a/drivers/gpu/drm/arm/malidp_planes.c 
b/drivers/gpu/drm/arm/malidp_planes.c
index 49c37f6dd63e..33bbc29da774 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -196,13 +196,26 @@ static int malidp_de_plane_check(struct drm_plane *plane,
ms->n_planes = fb->format->num_planes;
for (i = 0; i < ms->n_planes; i++) {
u8 alignment = malidp_hw_get_pitch_align(mp->hwdev, rotated);
-   if (fb->pitches[i] & (alignment - 1)) {
+
+   if ((fb->pitches[i] * drm_format_info_block_height(fb->format, 
i))
+   & (alignment - 1)) {
DRM_DEBUG_KMS("Invalid pitch %u for plane %d\n",
  fb->pitches[i], i);
return -EINVAL;
}
}
 
+   if (fb->width % drm_format_info_block_width(fb->format, 0) ||
+   fb->height % drm_format_info_block_height(fb->format, 0)) {
+   DRM_DEBUG_KMS("Buffer width/height needs to be a multiple of 
tile sizes");
+   return -EINVAL;
+   }
+   if ((state->src_x >> 16) % drm_format_info_block_width(fb->format, 0) ||
+   (state->src_y >> 16) % drm_format_info_block_height(fb->format, 0)) 
{
+   DRM_DEBUG_KMS("Plane src_x/src_y needs to be a multiple of tile 
sizes");
+   return -EINVAL;
+   }
+
if ((state->crtc_w > mp->hwdev->max_line_size) ||
(state->crtc_h > mp->hwdev->max_line_size) ||
(state->crtc_w < mp->hwdev->min_line_size) ||
@@ -258,8 +271,14 @@ static void malidp_de_set_plane_pitches(struct 
malidp_plane *mp,
num_strides = (mp->hwdev->hw->features &
   MALIDP_DEVICE_LV_HAS_3_STRIDES) ? 3 : 2;
 
+   /*
+* The drm convention for pitch is that it needs to cover width * cpp,
+* but our hardware wants the pitch/stride to cover all rows included
+* in a tile.
+*/
for (i = 0; i < num_strides; ++i)
-   malidp_hw_write(mp->hwdev, pitches[i],
+   malidp_hw_write(mp->hwdev, pitches[i] *
+   
drm_format_info_block_height(

[PATCH v5 3/9] drm/fourcc: Add fourcc for Mali linear tiled formats

2018-10-19 Thread Alexandru Gheorghe
Mali-DP implements a number of tiled yuv formats which are not
currently described in drm_fourcc.h.
This adds those definitions and describes their memory layout by
using the newly added char_per_block, block_w, block_h.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_fourcc.c  | 12 
 include/uapi/drm/drm_fourcc.h | 14 ++
 2 files changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index a843a5fc8dbf..69caa577149c 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -228,6 +228,18 @@ const struct drm_format_info *__drm_format_info(u32 format)
{ .format = DRM_FORMAT_P010,.depth = 0,  
.num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true  },
{ .format = DRM_FORMAT_P012,.depth = 0,  
.num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true  },
{ .format = DRM_FORMAT_P016,.depth = 0,  
.num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true  },
+   { .format = DRM_FORMAT_Y0L0,.depth = 0,  
.num_planes = 1,
+ .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, 
.block_h = { 2, 0, 0},
+ .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true },
+   { .format = DRM_FORMAT_X0L0,.depth = 0,  
.num_planes = 1,
+ .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, 
.block_h = { 2, 0, 0},
+ .hsub = 2, .vsub = 2, .is_yuv = true },
+   { .format = DRM_FORMAT_Y0L2,.depth = 0,  
.num_planes = 1,
+ .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, 
.block_h = { 2, 0, 0},
+ .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true },
+   { .format = DRM_FORMAT_X0L2,.depth = 0,  
.num_planes = 1,
+ .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, 
.block_h = { 2, 0, 0},
+ .hsub = 2, .vsub = 2, .is_yuv = true },
};
 
unsigned int i;
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 600106adf91f..4de86dbf40ca 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -152,6 +152,20 @@ extern "C" {
 
 #define DRM_FORMAT_AYUVfourcc_code('A', 'Y', 'U', 'V') /* 
[31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
 
+/*
+ * packed YCbCr420 2x2 tiled formats
+ * first 64 bits will contain Y,Cb,Cr components for a 2x2 tile
+ */
+/* [63:0]   A3:A2:Y3:0:Cr0:0:Y2:0:A1:A0:Y1:0:Cb0:0:Y0:0  
1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian */
+#define DRM_FORMAT_Y0L0fourcc_code('Y', '0', 'L', '0')
+/* [63:0]   X3:X2:Y3:0:Cr0:0:Y2:0:X1:X0:Y1:0:Cb0:0:Y0:0  
1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian */
+#define DRM_FORMAT_X0L0fourcc_code('X', '0', 'L', '0')
+
+/* [63:0]   A3:A2:Y3:Cr0:Y2:A1:A0:Y1:Cb0:Y0  1:1:10:10:10:1:1:10:10:10 little 
endian */
+#define DRM_FORMAT_Y0L2fourcc_code('Y', '0', 'L', '2')
+/* [63:0]   X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0  1:1:10:10:10:1:1:10:10:10 little 
endian */
+#define DRM_FORMAT_X0L2fourcc_code('X', '0', 'L', '2')
+
 /*
  * 2 plane RGB + A
  * index 0 = RGB plane, same format as the corresponding non _A8 format has
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 6/9] drm/fourcc: Add AFBC yuv fourccs for Mali

2018-10-19 Thread Alexandru Gheorghe
From: Brian Starkey 

As we look to enable AFBC using DRM format modifiers, we run into
problems which we've historically handled via vendor-private details
(i.e. gralloc, on Android).

AFBC (as an encoding) is fully flexible, and for example YUV data can
be encoded into 1, 2 or 3 encoded "planes", much like the linear
equivalents. Component order is also meaningful, as AFBC doesn't
necessarily care about what each "channel" of the data it encodes
contains. Therefore ABGR and RGBA can be encoded in AFBC with
different representations. Similarly, 'X' components may be encoded
into AFBC streams in cases where a decoder expects to decode a 4th
component.

In addition, AFBC is a licensable IP, meaning that to support the
ecosystem we need to ensure that _all_ AFBC users are able to describe
the encodings that they need. This is much better achieved by
preserving meaning in the fourcc codes when they are combined with an
AFBC modifier.

In essence, we want to use the modifier to describe the parameters of
the AFBC encode/decode, and use the fourcc code to describe the data
being encoded/decoded.

To do anything different would be to introduce redundancy - we would
need to duplicate in the modifier information which is _already_
conveyed clearly and non-ambigiously by a fourcc code.

I hope that for RGB this is non-controversial.
(BGRA + MODIFIER_AFBC) is a different format from
(RGBA + MODIFIER_AFBC).

Possibly more controversial is that (XBGR + MODIFIER_AFBC)
is different from (BGR888 + MODIFIER_AFBC). I understand that in some
schemes it is not the case - but in AFBC it is so.

Where we run into problems is where there are not already fourcc codes
which represent the data which the AFBC encoder/decoder is processing.
To that end, we want to introduce new fourcc codes to describe the
data being encoded/decoded, in the places where none of the existing
fourcc codes are applicable.

Where we don't support an equivalent non-compressed layout, or where
no "obvious" linear layout exists, we are proposing adding fourcc
codes which have no associated linear layout - because any layout we
proposed would be completely arbitrary.

Some formats are following the naming conventions from [2].

The summary of the new formats is:
 DRM_FORMAT_VUY888 - Packed 8-bit YUV 444. Y followed by U then V.
 DRM_FORMAT_VUY101010 - Packed 10-bit YUV 444. Y followed by U then
V. No defined linear encoding.
 DRM_FORMAT_Y210 - Packed 10-bit YUV 422. Y followed by U (then Y)
   then V. 10-bit samples in 16-bit words.
 DRM_FORMAT_Y410 - Packed 10-bit YUV 444, with 2-bit alpha.
 DRM_FORMAT_P210 - Semi-planar 10-bit YUV 422. Y plane, followed by
   interleaved U-then-V plane. 10-bit samples in
   16-bit words.
 DRM_FORMAT_YUV420_8BIT - Packed 8-bit YUV 420. Y followed by U then
  V. No defined linear encoding
 DRM_FORMAT_YUV420_10BIT - Packed 10-bit YUV 420. Y followed by U
   then V. No defined linear encoding

Please also note that in the absence of AFBC, we would still need to
add Y410, Y210 and P210.

Full rationale follows:

YUV 444 8-bit, 1-plane
--
 The currently defined AYUV format encodes a 4th alpha component,
 which makes it unsuitable for representing a 3-component YUV 444
 AFBC stream.

 The proposed[1] XYUV format which is supported by Mali-DP in linear
 layout is also unsuitable, because the component order is the
 opposite of the AFBC version, and it encodes a 4th 'X' component.

 DRM_FORMAT_VUY888 is the "obvious" format for a 3-component, packed,
 YUV 444 8-bit format, with the component order which our HW expects to
 encode/decode. It conforms to the same naming convention as the
 existing packed YUV 444 format.
 The naming here is meant to be consistent with DRM_FORMAT_AYUV and
 DRM_FORMAT_XYUV[1]

YUV 444 10-bit, 1-plane
---
 There is no currently-defined YUV 444 10-bit format in
 drm_fourcc.h, irrespective of number of planes.

 The proposed[1] XVYU2101010 format which is supported by Mali-DP in
 linear layout uses the wrong component order, and also encodes a 4th
 'X' component, which doesn't match the AFBC version of YUV 444
 10-bit which we support.

 DRM_FORMAT_Y410 is the same layout as XVYU2101010, but with 2 bits of
 alpha.  This format is supported with linear layout by Mali GPUs. The
 naming follows[2].

 There is no "obvious" linear encoding for a 3-component 10:10:10
 packed format, and so DRM_FORMAT_VUY101010 defines a component
 order, but not a bit encoding. Again, the naming is meant to be
 consistent with DRM_FORMAT_AYUV.

YUV 422 8-bit, 1-plane
--
 The existing DRM_FORMAT_YUYV (and the other component orders) are
 single-planar YUV 422 8-bit formats. Following the convention of
 the component orders of the RGB formats, YUYV has the correct
 component order for our AFBC encoding (Y followed by U followed by
 

[PATCH v5 2/9] drm/fourcc: Add char_per_block, block_w and block_h in drm_format_info

2018-10-19 Thread Alexandru Gheorghe
For some pixel formats .cpp structure in drm_format info it's not
enough to describe the peculiarities of the pixel layout, for example
tiled formats or packed formats at bit level.

What's implemented here is to add three new members to drm_format_info
that could describe such formats:

- char_per_block[3]
- block_w[3]
- block_h[3]

char_per_block will be put in a union alongside cpp, for transparent
compatibility  with the existing format descriptions.

Regarding, block_w and block_h they are intended to be used through
their equivalent getters drm_format_info_block_width /
drm_format_info_block_height, the reason of the getters is to abstract
the fact that for normal formats block_w and block_h will be unset/0,
but the methods will be returning 1.

Additionally, convenience function drm_format_info_min_pitch had been
added that computes the minimum required pitch for a given pixel
format and buffer width.

Using that the following drm core functions had been updated to
generically handle both block and non-block formats:

- drm_fb_cma_get_gem_addr: for block formats it will just return the
  beginning of the block.
- framebuffer_check: Use the newly added drm_format_info_min_pitch.
- drm_gem_fb_create_with_funcs: Use the newly added
  drm_format_info_min_pitch.
- In places where is not expecting to handle block formats, like fbdev
  helpers I just added some warnings in case the block width/height
  are greater than 1.

Changes since v3:
 - Add helper function for computing the minimum required pitch.
 - Improve/cleanup documentation

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_fb_cma_helper.c  | 21 ++-
 drivers/gpu/drm/drm_fb_helper.c  |  6 ++
 drivers/gpu/drm/drm_fourcc.c | 62 
 drivers/gpu/drm/drm_framebuffer.c|  6 +-
 drivers/gpu/drm/drm_gem_framebuffer_helper.c |  2 +-
 include/drm/drm_fourcc.h | 61 ++-
 6 files changed, 149 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c 
b/drivers/gpu/drm/drm_fb_cma_helper.c
index d52344a03aa8..83941a8ca0e0 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -72,7 +72,9 @@ struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct 
drm_framebuffer *fb,
 EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj);
 
 /**
- * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer
+ * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer, for pixel
+ * formats where values are grouped in blocks this will get you the beginning 
of
+ * the block
  * @fb: The framebuffer
  * @state: Which state of drm plane
  * @plane: Which plane
@@ -87,6 +89,14 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer 
*fb,
struct drm_gem_cma_object *obj;
dma_addr_t paddr;
u8 h_div = 1, v_div = 1;
+   u32 block_w = drm_format_info_block_width(fb->format, plane);
+   u32 block_h = drm_format_info_block_height(fb->format, plane);
+   u32 block_size = fb->format->char_per_block[plane];
+   u32 sample_x;
+   u32 sample_y;
+   u32 block_start_y;
+   u32 num_hblocks;
+
 
obj = drm_fb_cma_get_gem_obj(fb, plane);
if (!obj)
@@ -99,8 +109,13 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer 
*fb,
v_div = fb->format->vsub;
}
 
-   paddr += (fb->format->cpp[plane] * (state->src_x >> 16)) / h_div;
-   paddr += (fb->pitches[plane] * (state->src_y >> 16)) / v_div;
+   sample_x = (state->src_x >> 16) / h_div;
+   sample_y = (state->src_y >> 16) / v_div;
+   block_start_y = (sample_y / block_h) * block_h;
+   num_hblocks = sample_x / block_w;
+
+   paddr += fb->pitches[plane] * block_start_y;
+   paddr += block_size * num_hblocks;
 
return paddr;
 }
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index a504a5e05676..9add0d7da744 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1595,6 +1595,10 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo 
*var,
if (var->pixclock != 0 || in_dbg_master())
return -EINVAL;
 
+   if ((drm_format_info_block_width(fb->format, 0) > 1) ||
+   (drm_format_info_block_height(fb->format, 0) > 1))
+   return -EINVAL;
+
/*
 * Changes struct fb_var_screeninfo are currently not pushed back
 * to KMS, hence fail if different settings are requested.
@@ -1969,6 +1973,8 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct 
drm_fb_helper *fb_helpe
 {
struct drm_framebuffer *fb = fb_helper->fb;
 
+   WARN_ON((drm_format_info_block_width(fb->format, 0) > 1) ||
+   (drm_format_info_block_height(fb->format, 0) > 1));
info->pseudo_palette = fb_helper->pseudo_palett

[PATCH v5 1/9] drm: fourcc: Convert drm_format_info kerneldoc to in-line member documentation

2018-10-19 Thread Alexandru Gheorghe
In-line member documentation seems to be desired way of documenting
structure members.

This change had been suggested by Daniel Vetter here:
https://lists.freedesktop.org/archives/dri-devel/2018-October/192176.html

Signed-off-by: Alexandru Gheorghe 
---
 include/drm/drm_fourcc.h | 30 --
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 865ef60c17af..345f11227e9e 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -52,25 +52,35 @@ struct drm_mode_fb_cmd2;
 
 /**
  * struct drm_format_info - information about a DRM format
- * @format: 4CC format identifier (DRM_FORMAT_*)
- * @depth: Color depth (number of bits per pixel excluding padding bits),
- * valid for a subset of RGB formats only. This is a legacy field, do not
- * use in new code and set to 0 for new formats.
- * @num_planes: Number of color planes (1 to 3)
- * @cpp: Number of bytes per pixel (per plane)
- * @hsub: Horizontal chroma subsampling factor
- * @vsub: Vertical chroma subsampling factor
- * @has_alpha: Does the format embeds an alpha component?
- * @is_yuv: Is it a YUV format?
  */
 struct drm_format_info {
+   /** @format: 4CC format identifier (DRM_FORMAT_*) */
u32 format;
+
+   /**
+* @depth:
+*
+* Color depth (number of bits per pixel excluding padding bits),
+* valid for a subset of RGB formats only. This is a legacy field, do
+* not use in new code and set to 0 for new formats.
+*/
u8 depth;
+
+   /** @num_planes: Number of color planes (1 to 3) */
u8 num_planes;
+
+   /** @cpp: Number of bytes per pixel (per plane) */
u8 cpp[3];
+
+   /** @hsub: Horizontal chroma subsampling factor */
u8 hsub;
+   /** @vsub: Vertical chroma subsampling factor */
u8 vsub;
+
+   /** @has_alpha: Does the format embeds an alpha component? */
bool has_alpha;
+
+   /** @is_yuv: Is it a YUV format? */
bool is_yuv;
 };
 
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 8/9] drm/selftests: Add module_exit for test-drm-helper

2018-10-12 Thread Alexandru Gheorghe
test-drm-helper.ko can't be rmmod-ed because it doesn't have a
module_exit,  that could be very inconvenient especially in the
development stage where we usually want to re-run the tests without
any rebooting.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/selftests/test-drm-helper.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/selftests/test-drm-helper.c 
b/drivers/gpu/drm/selftests/test-drm-helper.c
index a015712b43e8..a6a1818fdafd 100644
--- a/drivers/gpu/drm/selftests/test-drm-helper.c
+++ b/drivers/gpu/drm/selftests/test-drm-helper.c
@@ -241,7 +241,12 @@ static int __init test_drm_helper_init(void)
return err > 0 ? 0 : err;
 }
 
+static void __exit test_drm_helper_exit(void)
+{
+}
+
 module_init(test_drm_helper_init);
+module_exit(test_drm_helper_exit);
 
 MODULE_AUTHOR("Intel Corporation");
 MODULE_LICENSE("GPL");
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 4/9] drm: mali-dp: Enable Mali-DP tiled buffer formats

2018-10-12 Thread Alexandru Gheorghe
Enable the following formats
- DRM_FORMAT_X0L0: DP650
- DRM_FORMAT_X0L2: DP550, DP650

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/arm/malidp_hw.c | 14 +++---
 drivers/gpu/drm/arm/malidp_planes.c | 23 +--
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index c94a4422e0e9..e01fc0e5b503 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -77,12 +77,18 @@ static const struct malidp_format_id malidp500_de_formats[] 
= {
{ DRM_FORMAT_YUYV, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 2) },\
{ DRM_FORMAT_UYVY, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 3) },\
{ DRM_FORMAT_NV12, DE_VIDEO1 | DE_VIDEO2 | SE_MEMWRITE, MALIDP_ID(5, 6) 
},  \
-   { DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }
+   { DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }, \
+   { DRM_FORMAT_X0L2, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 6)}
 
 static const struct malidp_format_id malidp550_de_formats[] = {
MALIDP_COMMON_FORMATS,
 };
 
+static const struct malidp_format_id malidp650_de_formats[] = {
+   MALIDP_COMMON_FORMATS,
+   { DRM_FORMAT_X0L0, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 4)},
+};
+
 static const struct malidp_layer malidp500_layers[] = {
{ DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, 
MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB },
{ DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, 
MALIDP_DE_LG_STRIDE, 0 },
@@ -595,6 +601,8 @@ static int malidp550_rotmem_required(struct 
malidp_hw_device *hwdev, u16 w, u16
case DRM_FORMAT_BGR565:
case DRM_FORMAT_UYVY:
case DRM_FORMAT_YUYV:
+   case DRM_FORMAT_X0L0:
+   case DRM_FORMAT_X0L2:
bytes_per_col = 32;
break;
/* 16 lines at 1.5 bytes per pixel */
@@ -860,8 +868,8 @@ const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES] = {
MALIDP550_DC_IRQ_SE,
.vsync_irq = MALIDP550_DC_IRQ_CONF_VALID,
},
-   .pixel_formats = malidp550_de_formats,
-   .n_pixel_formats = ARRAY_SIZE(malidp550_de_formats),
+   .pixel_formats = malidp650_de_formats,
+   .n_pixel_formats = ARRAY_SIZE(malidp650_de_formats),
.bus_align_bytes = 16,
},
.query_hw = malidp650_query_hw,
diff --git a/drivers/gpu/drm/arm/malidp_planes.c 
b/drivers/gpu/drm/arm/malidp_planes.c
index 49c37f6dd63e..33bbc29da774 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -196,13 +196,26 @@ static int malidp_de_plane_check(struct drm_plane *plane,
ms->n_planes = fb->format->num_planes;
for (i = 0; i < ms->n_planes; i++) {
u8 alignment = malidp_hw_get_pitch_align(mp->hwdev, rotated);
-   if (fb->pitches[i] & (alignment - 1)) {
+
+   if ((fb->pitches[i] * drm_format_info_block_height(fb->format, 
i))
+   & (alignment - 1)) {
DRM_DEBUG_KMS("Invalid pitch %u for plane %d\n",
  fb->pitches[i], i);
return -EINVAL;
}
}
 
+   if (fb->width % drm_format_info_block_width(fb->format, 0) ||
+   fb->height % drm_format_info_block_height(fb->format, 0)) {
+   DRM_DEBUG_KMS("Buffer width/height needs to be a multiple of 
tile sizes");
+   return -EINVAL;
+   }
+   if ((state->src_x >> 16) % drm_format_info_block_width(fb->format, 0) ||
+   (state->src_y >> 16) % drm_format_info_block_height(fb->format, 0)) 
{
+   DRM_DEBUG_KMS("Plane src_x/src_y needs to be a multiple of tile 
sizes");
+   return -EINVAL;
+   }
+
if ((state->crtc_w > mp->hwdev->max_line_size) ||
(state->crtc_h > mp->hwdev->max_line_size) ||
(state->crtc_w < mp->hwdev->min_line_size) ||
@@ -258,8 +271,14 @@ static void malidp_de_set_plane_pitches(struct 
malidp_plane *mp,
num_strides = (mp->hwdev->hw->features &
   MALIDP_DEVICE_LV_HAS_3_STRIDES) ? 3 : 2;
 
+   /*
+* The drm convention for pitch is that it needs to cover width * cpp,
+* but our hardware wants the pitch/stride to cover all rows included
+* in a tile.
+*/
for (i = 0; i < num_strides; ++i)
-   malidp_hw_write(mp->hwdev, pitches[i],
+   malidp_hw_write(mp->hwdev, pitches[i] *
+   
drm_format_info_block_height(

[PATCH v4 5/9] drm: Extend framebuffer_check to handle formats with cpp/char_per_block 0

2018-10-12 Thread Alexandru Gheorghe
For formats that are supported only with non-linear modifiers it
doesn't make to much sense to define cpp or char_per_block, so that
will be set to 0.

This patch adds a restriction to force having a modifier attached when
cpp/char_per_block is 0, and to bypass checking the pitch restriction.

This had been discussed here.
[1] 
https://people.freedesktop.org/~cbrill/dri-log/?channel=dri-devel_names==2018-09-13_html=true

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_framebuffer.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_framebuffer.c 
b/drivers/gpu/drm/drm_framebuffer.c
index 6aca8a1ccdb6..e346d0ad92e0 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -195,8 +195,13 @@ static int framebuffer_check(struct drm_device *dev,
for (i = 0; i < info->num_planes; i++) {
unsigned int width = fb_plane_width(r->width, info, i);
unsigned int height = fb_plane_height(r->height, info, i);
+   unsigned int block_size = info->char_per_block[i];
u64 min_pitch = drm_format_info_min_pitch(info, i, width);
 
+   if (!block_size && (r->modifier[i] == DRM_FORMAT_MOD_LINEAR)) {
+   DRM_DEBUG_KMS("Format requires non-linear modifier for 
plane %d\n", i);
+   return -EINVAL;
+   }
if (!r->handles[i]) {
DRM_DEBUG_KMS("no buffer object handle for plane %d\n", 
i);
return -EINVAL;
@@ -208,7 +213,7 @@ static int framebuffer_check(struct drm_device *dev,
if ((uint64_t) height * r->pitches[i] + r->offsets[i] > 
UINT_MAX)
return -ERANGE;
 
-   if (r->pitches[i] < min_pitch) {
+   if (block_size && r->pitches[i] < min_pitch) {
DRM_DEBUG_KMS("bad pitch %u for plane %d\n", 
r->pitches[i], i);
return -EINVAL;
}
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 0/9] Add method to describe tile/bit_level_packed formats

2018-10-12 Thread Alexandru Gheorghe
Changes since v3:
  - added an utility function that computes the minimum pitch.
  - switched drm_format_info to in-line member documentation.
  - Cleanup/Improved the kernel doc.
  - Added selftests for: drm_format_info* helpers.

There has been some discussion about extending drm core to handle
linear tile formats, in the series sent by me here [1] and how to
handle formats that are intended to be used just with
modifiers(particularly AFBC modifiers) on Brian series [2] and on IRC
here [3] and [4].

Hence, this big-merged series:

Patch 1: Just a preparation patch that converts the drm_format_info
kerneldoc to in-line documentation.

Patches 2-4: handle tiled formats both in core and in malidp driver,
this is done by extending drm_format_info with three new fields
char_per_block, block_w, block_h and consistently handle in the generic
code paths, both linear tiled formats and normal formats.
What's different from [1] is the interpretation of pitch for tile
formats which has been kept to be the same as for the other formats:
pitch = average_chars_per_pixel * width.

Patches 5-7: Introduce the YUV AFBC formats, the only thing noteworthy
here is that cpp/char_per_block are set to 0 for formats where it's
mandatory to be used together with a non-linear modifier and then that
is used to bypass pitch check in framebuffer_check for formats that
have cpp/char_per_block set to 0.

Patches 8-9: A small fix for test-drm-helper module and adds self
tests for drm_format_info* helpers. For the other touched functions we
need a bit more infrastructure to be able to unittest/selftest them,
since they need a stub drm_device and drm_file.

As a side note, igt master branch doesn't seem to be using
test-drm-helper.ko, so I just tested by loading/unloading the module
manually.


[1] https://lists.freedesktop.org/archives/dri-devel/2018-September/188245.html
[2] https://lists.freedesktop.org/archives/dri-devel/2018-September/189620.html
[3] 
https://people.freedesktop.org/~cbrill/dri-log/?channel=dri-devel_names==2018-09-13_html=true
[4] 
https://people.freedesktop.org/~cbrill/dri-log/?channel=dri-devel_names==2018-09-14_html=true


Alexandru Gheorghe (7):
  drm: fourcc: Convert drm_format_info kerneldoc to in-line member
documentation
  drm/fourcc: Add char_per_block, block_w and block_h in drm_format_info
  drm/fourcc: Add fourcc for Mali linear tiled formats
  drm: mali-dp: Enable Mali-DP tiled buffer formats
  drm: Extend framebuffer_check to handle formats with
cpp/char_per_block 0
  drm/selftests: Add module_exit for test-drm-helper
  drm/selftests: Add tests for drm_format_info* helpers

Brian Starkey (2):
  drm/fourcc: Add AFBC yuv fourccs for Mali
  drm/afbc: Add AFBC modifier usage documentation

 Documentation/gpu/afbc.rst| 233 +++
 Documentation/gpu/drivers.rst |   1 +
 MAINTAINERS   |   1 +
 drivers/gpu/drm/arm/malidp_hw.c   |  14 +-
 drivers/gpu/drm/arm/malidp_planes.c   |  23 +-
 drivers/gpu/drm/drm_fb_cma_helper.c   |  21 +-
 drivers/gpu/drm/drm_fb_helper.c   |   6 +
 drivers/gpu/drm/drm_fourcc.c  |  87 ++
 drivers/gpu/drm/drm_framebuffer.c |  11 +-
 drivers/gpu/drm/drm_gem_framebuffer_helper.c  |   2 +-
 .../gpu/drm/selftests/drm_helper_selftests.h  |   3 +
 drivers/gpu/drm/selftests/test-drm-helper.c   | 271 ++
 include/drm/drm_fourcc.h  |  89 +-
 include/uapi/drm/drm_fourcc.h |  31 ++
 14 files changed, 770 insertions(+), 23 deletions(-)
 create mode 100644 Documentation/gpu/afbc.rst

-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 7/9] drm/afbc: Add AFBC modifier usage documentation

2018-10-12 Thread Alexandru Gheorghe
From: Brian Starkey 

AFBC is a flexible, proprietary, lossless compression protocol and
format, with a number of defined DRM format modifiers. To facilitate
consistency and compatibility between different AFBC producers and
consumers, document the expectations for usage of the AFBC DRM format
modifiers in a new .rst chapter.

Signed-off-by: Brian Starkey 
Reviewed-by: Liviu Dudau 
---
 Documentation/gpu/afbc.rst| 233 ++
 Documentation/gpu/drivers.rst |   1 +
 MAINTAINERS   |   1 +
 include/uapi/drm/drm_fourcc.h |   3 +
 4 files changed, 238 insertions(+)
 create mode 100644 Documentation/gpu/afbc.rst

diff --git a/Documentation/gpu/afbc.rst b/Documentation/gpu/afbc.rst
new file mode 100644
index ..922d955da192
--- /dev/null
+++ b/Documentation/gpu/afbc.rst
@@ -0,0 +1,233 @@
+===
+ Arm Framebuffer Compression (AFBC)
+===
+
+AFBC is a proprietary lossless image compression protocol and format.
+It provides fine-grained random access and minimizes the amount of
+data transferred between IP blocks.
+
+AFBC can be enabled on drivers which support it via use of the AFBC
+format modifiers defined in drm_fourcc.h. See DRM_FORMAT_MOD_ARM_AFBC(*).
+
+All users of the AFBC modifiers must follow the usage guidelines laid
+out in this document, to ensure compatibility across different AFBC
+producers and consumers.
+
+Components and Ordering
+===
+
+AFBC streams can contain several components - where a component
+corresponds to a color channel (i.e. R, G, B, X, A, Y, Cb, Cr).
+The assignment of input/output color channels must be consistent
+between the encoder and the decoder for correct operation, otherwise
+the consumer will interpret the decoded data incorrectly.
+
+Furthermore, when the lossless colorspace transform is used
+(AFBC_FORMAT_MOD_YTR, which should be enabled for RGB buffers for
+maximum compression efficiency), the component order must be:
+
+ * Component 0: R
+ * Component 1: G
+ * Component 2: B
+
+The component ordering is communicated via the fourcc code in the
+fourcc:modifier pair. In general, component '0' is considered to
+reside in the least-significant bits of the corresponding linear
+format. For example, COMP(bits):
+
+ * DRM_FORMAT_ABGR
+
+   * Component 0: R(8)
+   * Component 1: G(8)
+   * Component 2: B(8)
+   * Component 3: A(8)
+
+ * DRM_FORMAT_BGR888
+
+   * Component 0: R(8)
+   * Component 1: G(8)
+   * Component 2: B(8)
+
+ * DRM_FORMAT_YUYV
+
+   * Component 0: Y(8)
+   * Component 1: Cb(8, 2x1 subsampled)
+   * Component 2: Cr(8, 2x1 subsampled)
+
+In AFBC, 'X' components are not treated any differently from any other
+component. Therefore, an AFBC buffer with fourcc DRM_FORMAT_XBGR
+encodes with 4 components, like so:
+
+ * DRM_FORMAT_XBGR
+
+   * Component 0: R(8)
+   * Component 1: G(8)
+   * Component 2: B(8)
+   * Component 3: X(8)
+
+Please note, however, that the inclusion of a "wasted" 'X' channel is
+bad for compression efficiency, and so it's recommended to avoid
+formats containing 'X' bits. If a fourth component is
+required/expected by the encoder/decoder, then it is recommended to
+instead use an equivalent format with alpha, setting all alpha bits to
+'1'. If there is no requirement for a fourth component, then a format
+which doesn't include alpha can be used, e.g. DRM_FORMAT_BGR888.
+
+Number of Planes
+
+
+Formats which are typically multi-planar in linear layouts (e.g. YUV
+420), can be encoded into one, or multiple, AFBC planes. As with
+component order, the encoder and decoder must agree about the number
+of planes in order to correctly decode the buffer. The fourcc code is
+used to determine the number of encoded planes in an AFBC buffer,
+matching the number of planes for the linear (unmodified) format.
+Within each plane, the component ordering also follows the fourcc
+code:
+
+For example:
+
+ * DRM_FORMAT_YUYV: nplanes = 1
+
+   * Plane 0:
+
+ * Component 0: Y(8)
+ * Component 1: Cb(8, 2x1 subsampled)
+ * Component 2: Cr(8, 2x1 subsampled)
+
+ * DRM_FORMAT_NV12: nplanes = 2
+
+   * Plane 0:
+
+ * Component 0: Y(8)
+
+   * Plane 1:
+
+ * Component 0: Cb(8, 2x1 subsampled)
+ * Component 1: Cr(8, 2x1 subsampled)
+
+Cross-device interoperability
+=
+
+For maximum compatibility across devices, the table below defines
+canonical formats for use between AFBC-enabled devices. Formats which
+are listed here must be used exactly as specified when using the AFBC
+modifiers. Formats which are not listed should be avoided.
+
+.. flat-table:: AFBC formats
+
+   * - Fourcc code
+ - Description
+ - Planes/Components
+
+   * - DRM_FORMAT_ABGR2101010
+ - 10-bit per component RGB, with 2-bit alpha
+ - Plane 0: 4 components
+  * Component 0: R(10)
+  * Component 1: G(10)
+  * Component 2: B(10)
+ 

[PATCH v4 2/9] drm/fourcc: Add char_per_block, block_w and block_h in drm_format_info

2018-10-12 Thread Alexandru Gheorghe
For some pixel formats .cpp structure in drm_format info it's not
enough to describe the peculiarities of the pixel layout, for example
tiled formats or packed formats at bit level.

What's implemented here is to add three new members to drm_format_info
that could describe such formats:

- char_per_block[3]
- block_w[3]
- block_h[3]

char_per_block will be put in a union alongside cpp, for transparent
compatibility  with the existing format descriptions.

Regarding, block_w and block_h they are intended to be used through
their equivalent getters drm_format_info_block_width /
drm_format_info_block_height, the reason of the getters is to abstract
the fact that for normal formats block_w and block_h will be unset/0,
but the methods will be returning 1.

Additionally, convenience function drm_format_info_min_pitch had been
added that computes the minimum required pitch for a given pixel
format and buffer width.

Using that the following drm core functions had been updated to
generically handle both block and non-block formats:

- drm_fb_cma_get_gem_addr: for block formats it will just return the
  beginning of the block.
- framebuffer_check: Use the newly added drm_format_info_min_pitch.
- drm_gem_fb_create_with_funcs: Use the newly added
  drm_format_info_min_pitch.
- In places where is not expecting to handle block formats, like fbdev
  helpers I just added some warnings in case the block width/height
  are greater than 1.

Changes since v3:
 - Add helper function for computing the minimum required pitch.
 - Improve/cleanup documentation

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_fb_cma_helper.c  | 21 ++-
 drivers/gpu/drm/drm_fb_helper.c  |  6 ++
 drivers/gpu/drm/drm_fourcc.c | 62 
 drivers/gpu/drm/drm_framebuffer.c|  6 +-
 drivers/gpu/drm/drm_gem_framebuffer_helper.c |  2 +-
 include/drm/drm_fourcc.h | 61 ++-
 6 files changed, 149 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c 
b/drivers/gpu/drm/drm_fb_cma_helper.c
index d52344a03aa8..83941a8ca0e0 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -72,7 +72,9 @@ struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct 
drm_framebuffer *fb,
 EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj);
 
 /**
- * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer
+ * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer, for pixel
+ * formats where values are grouped in blocks this will get you the beginning 
of
+ * the block
  * @fb: The framebuffer
  * @state: Which state of drm plane
  * @plane: Which plane
@@ -87,6 +89,14 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer 
*fb,
struct drm_gem_cma_object *obj;
dma_addr_t paddr;
u8 h_div = 1, v_div = 1;
+   u32 block_w = drm_format_info_block_width(fb->format, plane);
+   u32 block_h = drm_format_info_block_height(fb->format, plane);
+   u32 block_size = fb->format->char_per_block[plane];
+   u32 sample_x;
+   u32 sample_y;
+   u32 block_start_y;
+   u32 num_hblocks;
+
 
obj = drm_fb_cma_get_gem_obj(fb, plane);
if (!obj)
@@ -99,8 +109,13 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer 
*fb,
v_div = fb->format->vsub;
}
 
-   paddr += (fb->format->cpp[plane] * (state->src_x >> 16)) / h_div;
-   paddr += (fb->pitches[plane] * (state->src_y >> 16)) / v_div;
+   sample_x = (state->src_x >> 16) / h_div;
+   sample_y = (state->src_y >> 16) / v_div;
+   block_start_y = (sample_y / block_h) * block_h;
+   num_hblocks = sample_x / block_w;
+
+   paddr += fb->pitches[plane] * block_start_y;
+   paddr += block_size * num_hblocks;
 
return paddr;
 }
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index a504a5e05676..9add0d7da744 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1595,6 +1595,10 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo 
*var,
if (var->pixclock != 0 || in_dbg_master())
return -EINVAL;
 
+   if ((drm_format_info_block_width(fb->format, 0) > 1) ||
+   (drm_format_info_block_height(fb->format, 0) > 1))
+   return -EINVAL;
+
/*
 * Changes struct fb_var_screeninfo are currently not pushed back
 * to KMS, hence fail if different settings are requested.
@@ -1969,6 +1973,8 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct 
drm_fb_helper *fb_helpe
 {
struct drm_framebuffer *fb = fb_helper->fb;
 
+   WARN_ON((drm_format_info_block_width(fb->format, 0) > 1) ||
+   (drm_format_info_block_height(fb->format, 0) > 1));
info->pseudo_palette = fb_helper->pseudo_palett

[PATCH v4 9/9] drm/selftests: Add tests for drm_format_info* helpers

2018-10-12 Thread Alexandru Gheorghe
Add selftests for the following newly added functions:
- drm_format_info_block_width
- drm_format_info_block_height
- drm_format_info_min_pitch

Signed-off-by: Alexandru Gheorghe 
---
 .../gpu/drm/selftests/drm_helper_selftests.h  |   3 +
 drivers/gpu/drm/selftests/test-drm-helper.c   | 277 ++
 2 files changed, 280 insertions(+)

diff --git a/drivers/gpu/drm/selftests/drm_helper_selftests.h 
b/drivers/gpu/drm/selftests/drm_helper_selftests.h
index 9771290ed228..4e203ac8c134 100644
--- a/drivers/gpu/drm/selftests/drm_helper_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_helper_selftests.h
@@ -7,3 +7,6 @@
  * Tests are executed in order by igt/drm_selftests_helper
  */
 selftest(check_plane_state, igt_check_plane_state)
+selftest(check_drm_format_block_width, igt_check_drm_format_block_width)
+selftest(check_drm_format_block_height, igt_check_drm_format_block_height)
+selftest(check_drm_format_min_pitch, igt_check_drm_format_min_pitch)
diff --git a/drivers/gpu/drm/selftests/test-drm-helper.c 
b/drivers/gpu/drm/selftests/test-drm-helper.c
index a6a1818fdafd..bea77f907d83 100644
--- a/drivers/gpu/drm/selftests/test-drm-helper.c
+++ b/drivers/gpu/drm/selftests/test-drm-helper.c
@@ -7,6 +7,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 
@@ -230,6 +231,282 @@ static int igt_check_plane_state(void *ignored)
return 0;
 }
 
+static int igt_check_drm_format_block_width(void *ignored)
+{
+   const struct drm_format_info *info = NULL;
+
+   /* Test invalid arguments */
+   FAIL_ON(drm_format_info_block_width(info, 0) != 0);
+   FAIL_ON(drm_format_info_block_width(info, -1) != 0);
+   FAIL_ON(drm_format_info_block_width(info, 1) != 0);
+
+   /* Test 1 plane format */
+   info = drm_format_info(DRM_FORMAT_XRGB);
+   FAIL_ON(!info);
+   FAIL_ON(drm_format_info_block_width(info, 0) != 1);
+   FAIL_ON(drm_format_info_block_width(info, 1) != 0);
+   FAIL_ON(drm_format_info_block_width(info, -1) != 0);
+
+   /* Test 2 planes format */
+   info = drm_format_info(DRM_FORMAT_NV12);
+   FAIL_ON(!info);
+   FAIL_ON(drm_format_info_block_width(info, 0) != 1);
+   FAIL_ON(drm_format_info_block_width(info, 1) != 1);
+   FAIL_ON(drm_format_info_block_width(info, 2) != 0);
+   FAIL_ON(drm_format_info_block_width(info, -1) != 0);
+
+   /* Test 3 planes format */
+   info = drm_format_info(DRM_FORMAT_YUV422);
+   FAIL_ON(!info);
+   FAIL_ON(drm_format_info_block_width(info, 0) != 1);
+   FAIL_ON(drm_format_info_block_width(info, 1) != 1);
+   FAIL_ON(drm_format_info_block_width(info, 2) != 1);
+   FAIL_ON(drm_format_info_block_width(info, 3) != 0);
+   FAIL_ON(drm_format_info_block_width(info, -1) != 0);
+
+   /* Test a tiled format */
+   info = drm_format_info(DRM_FORMAT_X0L0);
+   FAIL_ON(!info);
+   FAIL_ON(drm_format_info_block_width(info, 0) != 2);
+   FAIL_ON(drm_format_info_block_width(info, 1) != 0);
+   FAIL_ON(drm_format_info_block_width(info, -1) != 0);
+
+   return 0;
+}
+
+static int igt_check_drm_format_block_height(void *ignored)
+{
+   const struct drm_format_info *info = NULL;
+
+   /* Test invalid arguments */
+   FAIL_ON(drm_format_info_block_height(info, 0) != 0);
+   FAIL_ON(drm_format_info_block_height(info, -1) != 0);
+   FAIL_ON(drm_format_info_block_height(info, 1) != 0);
+
+   /* Test 1 plane format */
+   info = drm_format_info(DRM_FORMAT_XRGB);
+   FAIL_ON(!info);
+   FAIL_ON(drm_format_info_block_height(info, 0) != 1);
+   FAIL_ON(drm_format_info_block_height(info, 1) != 0);
+   FAIL_ON(drm_format_info_block_height(info, -1) != 0);
+
+   /* Test 2 planes format */
+   info = drm_format_info(DRM_FORMAT_NV12);
+   FAIL_ON(!info);
+   FAIL_ON(drm_format_info_block_height(info, 0) != 1);
+   FAIL_ON(drm_format_info_block_height(info, 1) != 1);
+   FAIL_ON(drm_format_info_block_height(info, 2) != 0);
+   FAIL_ON(drm_format_info_block_height(info, -1) != 0);
+
+   /* Test 3 planes format */
+   info = drm_format_info(DRM_FORMAT_YUV422);
+   FAIL_ON(!info);
+   FAIL_ON(drm_format_info_block_height(info, 0) != 1);
+   FAIL_ON(drm_format_info_block_height(info, 1) != 1);
+   FAIL_ON(drm_format_info_block_height(info, 2) != 1);
+   FAIL_ON(drm_format_info_block_height(info, 3) != 0);
+   FAIL_ON(drm_format_info_block_height(info, -1) != 0);
+
+   /* Test a tiled format */
+   info = drm_format_info(DRM_FORMAT_X0L0);
+   FAIL_ON(!info);
+   FAIL_ON(drm_format_info_block_height(info, 0) != 2);
+   FAIL_ON(drm_format_info_block_height(info, 1) != 0);
+   FAIL_ON(drm_format_info_block_height(info, -1) != 0);
+
+   return 0;
+}
+
+static int igt_check_drm_format_min_pitch(void *ignored)
+{
+   const struct drm_format_info *info = NULL;
+
+   /* Test invalid arguments */
+   FAIL_ON

[PATCH v4 6/9] drm/fourcc: Add AFBC yuv fourccs for Mali

2018-10-12 Thread Alexandru Gheorghe
From: Brian Starkey 

As we look to enable AFBC using DRM format modifiers, we run into
problems which we've historically handled via vendor-private details
(i.e. gralloc, on Android).

AFBC (as an encoding) is fully flexible, and for example YUV data can
be encoded into 1, 2 or 3 encoded "planes", much like the linear
equivalents. Component order is also meaningful, as AFBC doesn't
necessarily care about what each "channel" of the data it encodes
contains. Therefore ABGR and RGBA can be encoded in AFBC with
different representations. Similarly, 'X' components may be encoded
into AFBC streams in cases where a decoder expects to decode a 4th
component.

In addition, AFBC is a licensable IP, meaning that to support the
ecosystem we need to ensure that _all_ AFBC users are able to describe
the encodings that they need. This is much better achieved by
preserving meaning in the fourcc codes when they are combined with an
AFBC modifier.

In essence, we want to use the modifier to describe the parameters of
the AFBC encode/decode, and use the fourcc code to describe the data
being encoded/decoded.

To do anything different would be to introduce redundancy - we would
need to duplicate in the modifier information which is _already_
conveyed clearly and non-ambigiously by a fourcc code.

I hope that for RGB this is non-controversial.
(BGRA + MODIFIER_AFBC) is a different format from
(RGBA + MODIFIER_AFBC).

Possibly more controversial is that (XBGR + MODIFIER_AFBC)
is different from (BGR888 + MODIFIER_AFBC). I understand that in some
schemes it is not the case - but in AFBC it is so.

Where we run into problems is where there are not already fourcc codes
which represent the data which the AFBC encoder/decoder is processing.
To that end, we want to introduce new fourcc codes to describe the
data being encoded/decoded, in the places where none of the existing
fourcc codes are applicable.

Where we don't support an equivalent non-compressed layout, or where
no "obvious" linear layout exists, we are proposing adding fourcc
codes which have no associated linear layout - because any layout we
proposed would be completely arbitrary.

Some formats are following the naming conventions from [2].

The summary of the new formats is:
 DRM_FORMAT_VUY888 - Packed 8-bit YUV 444. Y followed by U then V.
 DRM_FORMAT_VUY101010 - Packed 10-bit YUV 444. Y followed by U then
V. No defined linear encoding.
 DRM_FORMAT_Y210 - Packed 10-bit YUV 422. Y followed by U (then Y)
   then V. 10-bit samples in 16-bit words.
 DRM_FORMAT_Y410 - Packed 10-bit YUV 444, with 2-bit alpha.
 DRM_FORMAT_P210 - Semi-planar 10-bit YUV 422. Y plane, followed by
   interleaved U-then-V plane. 10-bit samples in
   16-bit words.
 DRM_FORMAT_YUV420_8BIT - Packed 8-bit YUV 420. Y followed by U then
  V. No defined linear encoding
 DRM_FORMAT_YUV420_10BIT - Packed 10-bit YUV 420. Y followed by U
   then V. No defined linear encoding

Please also note that in the absence of AFBC, we would still need to
add Y410, Y210 and P210.

Full rationale follows:

YUV 444 8-bit, 1-plane
--
 The currently defined AYUV format encodes a 4th alpha component,
 which makes it unsuitable for representing a 3-component YUV 444
 AFBC stream.

 The proposed[1] XYUV format which is supported by Mali-DP in linear
 layout is also unsuitable, because the component order is the
 opposite of the AFBC version, and it encodes a 4th 'X' component.

 DRM_FORMAT_VUY888 is the "obvious" format for a 3-component, packed,
 YUV 444 8-bit format, with the component order which our HW expects to
 encode/decode. It conforms to the same naming convention as the
 existing packed YUV 444 format.
 The naming here is meant to be consistent with DRM_FORMAT_AYUV and
 DRM_FORMAT_XYUV[1]

YUV 444 10-bit, 1-plane
---
 There is no currently-defined YUV 444 10-bit format in
 drm_fourcc.h, irrespective of number of planes.

 The proposed[1] XVYU2101010 format which is supported by Mali-DP in
 linear layout uses the wrong component order, and also encodes a 4th
 'X' component, which doesn't match the AFBC version of YUV 444
 10-bit which we support.

 DRM_FORMAT_Y410 is the same layout as XVYU2101010, but with 2 bits of
 alpha.  This format is supported with linear layout by Mali GPUs. The
 naming follows[2].

 There is no "obvious" linear encoding for a 3-component 10:10:10
 packed format, and so DRM_FORMAT_VUY101010 defines a component
 order, but not a bit encoding. Again, the naming is meant to be
 consistent with DRM_FORMAT_AYUV.

YUV 422 8-bit, 1-plane
--
 The existing DRM_FORMAT_YUYV (and the other component orders) are
 single-planar YUV 422 8-bit formats. Following the convention of
 the component orders of the RGB formats, YUYV has the correct
 component order for our AFBC encoding (Y followed by U followed by
 

[PATCH v4 1/9] drm: fourcc: Convert drm_format_info kerneldoc to in-line member documentation

2018-10-12 Thread Alexandru Gheorghe
In-line member documentation seems to be desired way of documenting
structure members.

This change had been suggested by Daniel Vetter here:
https://lists.freedesktop.org/archives/dri-devel/2018-October/192176.html

Signed-off-by: Alexandru Gheorghe 
---
 include/drm/drm_fourcc.h | 30 --
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 865ef60c17af..345f11227e9e 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -52,25 +52,35 @@ struct drm_mode_fb_cmd2;
 
 /**
  * struct drm_format_info - information about a DRM format
- * @format: 4CC format identifier (DRM_FORMAT_*)
- * @depth: Color depth (number of bits per pixel excluding padding bits),
- * valid for a subset of RGB formats only. This is a legacy field, do not
- * use in new code and set to 0 for new formats.
- * @num_planes: Number of color planes (1 to 3)
- * @cpp: Number of bytes per pixel (per plane)
- * @hsub: Horizontal chroma subsampling factor
- * @vsub: Vertical chroma subsampling factor
- * @has_alpha: Does the format embeds an alpha component?
- * @is_yuv: Is it a YUV format?
  */
 struct drm_format_info {
+   /** @format: 4CC format identifier (DRM_FORMAT_*) */
u32 format;
+
+   /**
+* @depth:
+*
+* Color depth (number of bits per pixel excluding padding bits),
+* valid for a subset of RGB formats only. This is a legacy field, do
+* not use in new code and set to 0 for new formats.
+*/
u8 depth;
+
+   /** @num_planes: Number of color planes (1 to 3) */
u8 num_planes;
+
+   /** @cpp: Number of bytes per pixel (per plane) */
u8 cpp[3];
+
+   /** @hsub: Horizontal chroma subsampling factor */
u8 hsub;
+   /** @vsub: Vertical chroma subsampling factor */
u8 vsub;
+
+   /** @has_alpha: Does the format embeds an alpha component? */
bool has_alpha;
+
+   /** @is_yuv: Is it a YUV format? */
bool is_yuv;
 };
 
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 3/9] drm/fourcc: Add fourcc for Mali linear tiled formats

2018-10-12 Thread Alexandru Gheorghe
Mali-DP implements a number of tiled yuv formats which are not
currently described in drm_fourcc.h.
This adds those definitions and describes their memory layout by
using the newly added char_per_block, block_w, block_h.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_fourcc.c  | 12 
 include/uapi/drm/drm_fourcc.h | 14 ++
 2 files changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index a843a5fc8dbf..69caa577149c 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -228,6 +228,18 @@ const struct drm_format_info *__drm_format_info(u32 format)
{ .format = DRM_FORMAT_P010,.depth = 0,  
.num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true  },
{ .format = DRM_FORMAT_P012,.depth = 0,  
.num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true  },
{ .format = DRM_FORMAT_P016,.depth = 0,  
.num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true  },
+   { .format = DRM_FORMAT_Y0L0,.depth = 0,  
.num_planes = 1,
+ .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, 
.block_h = { 2, 0, 0},
+ .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true },
+   { .format = DRM_FORMAT_X0L0,.depth = 0,  
.num_planes = 1,
+ .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, 
.block_h = { 2, 0, 0},
+ .hsub = 2, .vsub = 2, .is_yuv = true },
+   { .format = DRM_FORMAT_Y0L2,.depth = 0,  
.num_planes = 1,
+ .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, 
.block_h = { 2, 0, 0},
+ .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true },
+   { .format = DRM_FORMAT_X0L2,.depth = 0,  
.num_planes = 1,
+ .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, 
.block_h = { 2, 0, 0},
+ .hsub = 2, .vsub = 2, .is_yuv = true },
};
 
unsigned int i;
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 600106adf91f..4de86dbf40ca 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -152,6 +152,20 @@ extern "C" {
 
 #define DRM_FORMAT_AYUVfourcc_code('A', 'Y', 'U', 'V') /* 
[31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
 
+/*
+ * packed YCbCr420 2x2 tiled formats
+ * first 64 bits will contain Y,Cb,Cr components for a 2x2 tile
+ */
+/* [63:0]   A3:A2:Y3:0:Cr0:0:Y2:0:A1:A0:Y1:0:Cb0:0:Y0:0  
1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian */
+#define DRM_FORMAT_Y0L0fourcc_code('Y', '0', 'L', '0')
+/* [63:0]   X3:X2:Y3:0:Cr0:0:Y2:0:X1:X0:Y1:0:Cb0:0:Y0:0  
1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian */
+#define DRM_FORMAT_X0L0fourcc_code('X', '0', 'L', '0')
+
+/* [63:0]   A3:A2:Y3:Cr0:Y2:A1:A0:Y1:Cb0:Y0  1:1:10:10:10:1:1:10:10:10 little 
endian */
+#define DRM_FORMAT_Y0L2fourcc_code('Y', '0', 'L', '2')
+/* [63:0]   X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0  1:1:10:10:10:1:1:10:10:10 little 
endian */
+#define DRM_FORMAT_X0L2fourcc_code('X', '0', 'L', '2')
+
 /*
  * 2 plane RGB + A
  * index 0 = RGB plane, same format as the corresponding non _A8 format has
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2] drm/malidp: Enable MMU prefetch on Mali-DP650

2018-10-01 Thread Alexandru Gheorghe
From: Jamie Fox 

Mali-DP650 supports warming up the SMMU translations, by sending
requsts to the SMMU before a buffer is read.

There are two modes supported:

- PARTIAL: could be enabled when the buffer is composed of 4K or 64K
  pages, the display hardware will send a configurable number of
  requests before the actual reading.

- FULL: could be enabled when the buffer is composed of 1M or 2M
  pages, the display hardware will send requests before reading for
  all pages composing the buffer.

This patch adds a mechanism for detecting the page size and set the
MMU prefetch mode if possible.

Changes since v1:
 - For imported buffers use the already populated
   drm_gem_cma_object.sgt instead of calling
   driver.gem_prime_get_sg_table, which works just for buffers
   allocated through the gem_cma API.

Signed-off-by: Jamie Fox 
Signed-off-by: Alexandru Gheorghe 
[rebased and re-ordered functions]
Signed-off-by: Liviu Dudau 
---
 drivers/gpu/drm/arm/malidp_drv.h|   8 +
 drivers/gpu/drm/arm/malidp_hw.c |  47 --
 drivers/gpu/drm/arm/malidp_hw.h |   1 +
 drivers/gpu/drm/arm/malidp_planes.c | 238 
 drivers/gpu/drm/arm/malidp_regs.h   |  11 ++
 5 files changed, 296 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.h b/drivers/gpu/drm/arm/malidp_drv.h
index e3eb0cb1f385..b76c86f18a56 100644
--- a/drivers/gpu/drm/arm/malidp_drv.h
+++ b/drivers/gpu/drm/arm/malidp_drv.h
@@ -55,6 +55,12 @@ struct malidp_plane {
const struct malidp_layer *layer;
 };
 
+enum mmu_prefetch_mode {
+   MALIDP_PREFETCH_MODE_NONE,
+   MALIDP_PREFETCH_MODE_PARTIAL,
+   MALIDP_PREFETCH_MODE_FULL,
+};
+
 struct malidp_plane_state {
struct drm_plane_state base;
 
@@ -63,6 +69,8 @@ struct malidp_plane_state {
/* internal format ID */
u8 format;
u8 n_planes;
+   enum mmu_prefetch_mode mmu_prefetch_mode;
+   u32 mmu_prefetch_pgsize;
 };
 
 #define to_malidp_plane(x) container_of(x, struct malidp_plane, base)
diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index 2781e462c1ed..c874ef4ac005 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -84,16 +84,45 @@ static const struct malidp_format_id malidp550_de_formats[] 
= {
 };
 
 static const struct malidp_layer malidp500_layers[] = {
-   { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, 
MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB },
-   { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, 
MALIDP_DE_LG_STRIDE, 0 },
-   { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE, 
MALIDP_DE_LG_STRIDE, 0 },
+   /* id, base address, fb pointer address base, stride offset,
+* yuv2rgb matrix offset, mmu control register offset
+*/
+   { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE,
+   MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB, 0 },
+   { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE,
+   MALIDP_DE_LG_STRIDE, 0, 0 },
+   { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE,
+   MALIDP_DE_LG_STRIDE, 0, 0 },
 };
 
 static const struct malidp_layer malidp550_layers[] = {
-   { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, 
MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB },
-   { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, 
MALIDP_DE_LG_STRIDE, 0 },
-   { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, 
MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB },
-   { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, 
MALIDP550_DE_LS_R1_STRIDE, 0 },
+   /* id, base address, fb pointer address base, stride offset,
+* yuv2rgb matrix offset, mmu control register offset
+*/
+   { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE,
+   MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 0 },
+   { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE,
+   MALIDP_DE_LG_STRIDE, 0, 0 },
+   { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE,
+   MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 0 },
+   { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE,
+   MALIDP550_DE_LS_R1_STRIDE, 0, 0 },
+};
+
+static const struct malidp_layer malidp650_layers[] = {
+   /* id, base address, fb pointer address base, stride offset,
+* yuv2rgb matrix offset, mmu control register offset
+*/
+   { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE,
+   MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB,
+   MALIDP650_DE_LV_MMU_CTRL },
+   { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE,
+   MALIDP_DE_LG_STRIDE, 0, MALIDP650_DE_LG_MMU_CTRL },
+   { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE,
+   MALIDP_DE_LV_STRIDE0

[PATCH v2] drm: Clarify DRM_MODE_REFLECT_X/Y documentation

2018-09-10 Thread Alexandru Gheorghe
DRM_MODE_REFLECT_X and DRM_MODE_REFLECT_Y meaning seems a bit unclear
to me, so try to clarify that with a bit of ascii graphics.

Changes since v1:
  - Move the ascii graphics in the kerneldoc where all plane
properties are already documented and make sure it's properly
rendered, suggestested by Daniel Vetter.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_blend.c | 22 ++
 include/uapi/drm/drm_mode.h |  3 ++-
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index 402b62d3f072..92f75c5c93ac 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -101,6 +101,28 @@
  * Without this property the rectangle is only scaled, but not rotated or
  * reflected.
  *
+ * Possbile values:
+ *
+ * "rotate-":
+ * Signals that a drm plane is rotated  degrees in counter
+ * clockwise direction.
+ *
+ * "reflect-":
+ * Signals that the contents of a drm plane is reflected along the
+ *  axis, in the same way as mirroring.
+ *
+ * reflect-x::
+ *
+ * |o || o|
+ * |  | -> |  |
+ * | v||v |
+ *
+ * reflect-y::
+ *
+ * |o || ^|
+ * |  | -> |  |
+ * | v||o |
+ *
  * zpos:
  * Z position is set up with drm_plane_create_zpos_immutable_property() and
  * drm_plane_create_zpos_property(). It controls the visibility of 
overlapping
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 8d67243952f4..d3e0fe31efc5 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -186,8 +186,9 @@ extern "C" {
 /*
  * DRM_MODE_REFLECT_
  *
- * Signals that the contents of a drm plane is reflected in the  axis,
+ * Signals that the contents of a drm plane is reflected along the  axis,
  * in the same way as mirroring.
+ * See kerneldoc chapter "Plane Composition Properties" for more details.
  *
  * This define is provided as a convenience, looking up the property id
  * using the name->prop id lookup is the preferred method.
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3] drm: Fix crtc color management when doing suspend/resume

2018-09-10 Thread Alexandru Gheorghe
When doing suspend/resume drivers usually use the
drm_atomic_helper_suspend/drm_atomic_helper_resume pair for saving the
state and then re-comitting it.

The problem is that drm_crtc_state has a bool field called
color_mgmt_changed, which mali-dp and other drivers uses it to detect
if coefficients need to be reprogrammed, but that never happens
because the saved state has color_mgmt_changed set to 0.

Fix that by setting color_mgmt_changed to true in
drm_atomic_helper_check_modeset when at least one of gamma_lut,
degamma_lut, ctm is different between the new and the old crtc state.

All current drivers that use color_mgmt_changed, either call directly
drm_atomic_helper_check_modeset or they use drm_atomic_helper_check
which calls drm_atomic_helper_check_modeset, so this makes unnecessary
the setting of color_mgmt_changed in places where
gamma_lut/degamma_lut/ctm are set in the new crtc_state.

Changes since v2:
  - Instead of setting color_mgmt_changed in commit_duplicated_set
just set it in check_modeset and clean up other place where it was
set, suggested by Maarten Lankhorst.

Changes since v3:
  - Rebased v2 on top of drm-misc-next and fix conflicts introduced by
the move of drm_atomic_crtc_set_property in drm_atomic_uapi.c.

Signed-off-by: Alexandru Gheorghe 
Reviewed-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_atomic_helper.c |  8 +++-
 drivers/gpu/drm/drm_atomic_uapi.c   | 12 +++-
 drivers/gpu/drm/drm_fb_helper.c |  1 -
 3 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 3cf1aa132778..53e60daa1bb6 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -612,6 +612,13 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
 
return -EINVAL;
}
+   if (new_crtc_state->degamma_lut != old_crtc_state->degamma_lut 
||
+   new_crtc_state->ctm != old_crtc_state->ctm ||
+   new_crtc_state->gamma_lut != old_crtc_state->gamma_lut) {
+   DRM_DEBUG_ATOMIC("[CRTC:%d:%s] color management 
changed\n",
+crtc->base.id, crtc->name);
+   new_crtc_state->color_mgmt_changed = true;
+   }
}
 
ret = handle_conflicting_encoders(state, false);
@@ -3948,7 +3955,6 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc 
*crtc,
replaced  = drm_property_replace_blob(_state->degamma_lut, NULL);
replaced |= drm_property_replace_blob(_state->ctm, NULL);
replaced |= drm_property_replace_blob(_state->gamma_lut, blob);
-   crtc_state->color_mgmt_changed |= replaced;
 
ret = drm_atomic_commit(state);
 
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index 26690a664ec6..686da206427e 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -434,29 +434,23 @@ static int drm_atomic_crtc_set_property(struct drm_crtc 
*crtc,
drm_property_blob_put(mode);
return ret;
} else if (property == config->degamma_lut_property) {
-   ret = drm_atomic_replace_property_blob_from_id(dev,
+   return drm_atomic_replace_property_blob_from_id(dev,
>degamma_lut,
val,
-1, sizeof(struct drm_color_lut),
);
-   state->color_mgmt_changed |= replaced;
-   return ret;
} else if (property == config->ctm_property) {
-   ret = drm_atomic_replace_property_blob_from_id(dev,
+   return drm_atomic_replace_property_blob_from_id(dev,
>ctm,
val,
sizeof(struct drm_color_ctm), -1,
);
-   state->color_mgmt_changed |= replaced;
-   return ret;
} else if (property == config->gamma_lut_property) {
-   ret = drm_atomic_replace_property_blob_from_id(dev,
+   return drm_atomic_replace_property_blob_from_id(dev,
>gamma_lut,
val,
-1, sizeof(struct drm_color_lut),
);
-   state->color_mgmt_changed |= replaced;
-   return ret;
} else if (property == config->prop_out_fence_ptr) {
s32 __user *fence_ptr = u64_to_user_ptr(val);
 
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 73cf10adebbf..a53e169e6824 100644
--- a/drivers/gpu/drm/drm

[PATCH v2] drm: Fix crtc color management when doing suspend/resume

2018-08-28 Thread Alexandru Gheorghe
When doing suspend/resume drivers usually use the
drm_atomic_helper_suspend/drm_atomic_helper_resume pair for saving the
state and then re-comitting it.

The problem is that drm_crtc_state has a bool field called
color_mgmt_changed, which mali-dp and other drivers uses it to detect
if coefficients need to be reprogrammed, but that never happens
because the saved state has color_mgmt_changed set to 0.

Fix that by setting color_mgmt_changed to true in
drm_atomic_helper_check_modeset when at least one of gamma_lut,
degamma_lut, ctm is different between the new and the old crtc state.

Also, this makes unnecessary the setting of color_mgmt_changed in
places where gamma_lut/degamma_lut/ctm are set in the new crtc_state.

Changes since v2:
  - Instead of setting color_mgmt_changed in commit_duplicated_set
just set it in check_modeset and clean up other place where it was
set, suggested by Maarten Lankhorst.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_atomic.c| 12 +++-
 drivers/gpu/drm/drm_atomic_helper.c |  8 +++-
 drivers/gpu/drm/drm_fb_helper.c |  1 -
 3 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index d0478abc01bd..9bcada3c299e 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -554,29 +554,23 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
drm_property_blob_put(mode);
return ret;
} else if (property == config->degamma_lut_property) {
-   ret = drm_atomic_replace_property_blob_from_id(dev,
+   return drm_atomic_replace_property_blob_from_id(dev,
>degamma_lut,
val,
-1, sizeof(struct drm_color_lut),
);
-   state->color_mgmt_changed |= replaced;
-   return ret;
} else if (property == config->ctm_property) {
-   ret = drm_atomic_replace_property_blob_from_id(dev,
+   return drm_atomic_replace_property_blob_from_id(dev,
>ctm,
val,
sizeof(struct drm_color_ctm), -1,
);
-   state->color_mgmt_changed |= replaced;
-   return ret;
} else if (property == config->gamma_lut_property) {
-   ret = drm_atomic_replace_property_blob_from_id(dev,
+   return drm_atomic_replace_property_blob_from_id(dev,
>gamma_lut,
val,
-1, sizeof(struct drm_color_lut),
);
-   state->color_mgmt_changed |= replaced;
-   return ret;
} else if (property == config->prop_out_fence_ptr) {
s32 __user *fence_ptr = u64_to_user_ptr(val);
 
diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 2c23a48482da..fe22e1ad468a 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -611,6 +611,13 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
 
return -EINVAL;
}
+   if (new_crtc_state->degamma_lut != old_crtc_state->degamma_lut 
||
+   new_crtc_state->ctm != old_crtc_state->ctm ||
+   new_crtc_state->gamma_lut != old_crtc_state->gamma_lut) {
+   DRM_DEBUG_ATOMIC("[CRTC:%d:%s] color management 
changed\n",
+crtc->base.id, crtc->name);
+   new_crtc_state->color_mgmt_changed = true;
+   }
}
 
ret = handle_conflicting_encoders(state, false);
@@ -3947,7 +3954,6 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc 
*crtc,
replaced  = drm_property_replace_blob(_state->degamma_lut, NULL);
replaced |= drm_property_replace_blob(_state->ctm, NULL);
replaced |= drm_property_replace_blob(_state->gamma_lut, blob);
-   crtc_state->color_mgmt_changed |= replaced;
 
ret = drm_atomic_commit(state);
 
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 4b0dd20bccb8..8541e95a5410 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1442,7 +1442,6 @@ static int setcmap_atomic(struct fb_cmap *cmap, struct 
fb_info *info)
replaced |= drm_property_replace_blob(_state->ctm, NULL);
replaced |= drm_property_replace_blob(_state->gamma_lut,
  gamma_lut);
-   crtc_sta

[PATCH] drm: Fix crtc color management when doing suspend/resume

2018-08-23 Thread Alexandru Gheorghe
When doing suspend/resume drivers usually use the
drm_atomic_helper_suspend/drm_atomic_helper_resume pair for saving the
state and then re-comitting it.

The problems is that drm_crtc_state has a bool field called
color_mgmt_changed, which mali-dp and other drivers uses it to detect
if coefficients need to be reprogrammed, but that never happens
because the save state has color_mgmt_changed set to 0.

Fix that by setting color_mgmt_changed to true if the crtc duplicated
state differs from the reset state.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_atomic_helper.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 6dd5036545ec..e88aa62bc822 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3196,8 +3196,13 @@ int drm_atomic_helper_commit_duplicated_state(struct 
drm_atomic_state *state,
for_each_new_plane_in_state(state, plane, new_plane_state, i)
state->planes[i].old_state = plane->state;
 
-   for_each_new_crtc_in_state(state, crtc, new_crtc_state, i)
+   for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
state->crtcs[i].old_state = crtc->state;
+   new_crtc_state->color_mgmt_changed =
+   new_crtc_state->degamma_lut != crtc->state->degamma_lut 
||
+   new_crtc_state->ctm != crtc->state->ctm ||
+   new_crtc_state->gamma_lut != crtc->state->gamma_lut;
+   }
 
for_each_new_connector_in_state(state, connector, new_conn_state, i)
state->connectors[i].old_state = connector->state;
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2] drm/malidp: Fix writeback in NV12

2018-08-22 Thread Alexandru Gheorghe
When we want to writeback to memory in NV12 format we need to program
the RGB2YUV coefficients. Currently, we don't program the coefficients
and NV12 doesn't work at all.

This patchset fixes that by programming a sane default(bt709, limited
range) as rgb2yuv coefficients.

In the long run, probably we need to think of a way for userspace to
be able to program that, but for now I think this is better than not
working at all or not advertising NV12 as a supported format for
memwrite.

Changes since v1:
 - Write the rgb2yuv coefficients only once, since we don't change
   them at all, just write them the first time NV12 is programmed,
   suggested by Brian Starkey, here [1]

[1] https://lists.freedesktop.org/archives/dri-devel/2018-August/186819.html

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/arm/malidp_hw.c   | 25 +++--
 drivers/gpu/drm/arm/malidp_hw.h   |  3 ++-
 drivers/gpu/drm/arm/malidp_mw.c   | 25 +
 drivers/gpu/drm/arm/malidp_regs.h |  2 ++
 4 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index c94a4422e0e9..2781e462c1ed 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -384,7 +384,8 @@ static long malidp500_se_calc_mclk(struct malidp_hw_device 
*hwdev,
 
 static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev,
 dma_addr_t *addrs, s32 *pitches,
-int num_planes, u16 w, u16 h, u32 fmt_id)
+int num_planes, u16 w, u16 h, u32 fmt_id,
+const s16 *rgb2yuv_coeffs)
 {
u32 base = MALIDP500_SE_MEMWRITE_BASE;
u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK);
@@ -416,6 +417,16 @@ static int malidp500_enable_memwrite(struct 
malidp_hw_device *hwdev,
 
malidp_hw_write(hwdev, MALIDP_DE_H_ACTIVE(w) | MALIDP_DE_V_ACTIVE(h),
MALIDP500_SE_MEMWRITE_OUT_SIZE);
+
+   if (rgb2yuv_coeffs) {
+   int i;
+
+   for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) {
+   malidp_hw_write(hwdev, rgb2yuv_coeffs[i],
+   MALIDP500_SE_RGB_YUV_COEFFS + i * 4);
+   }
+   }
+
malidp_hw_setbits(hwdev, MALIDP_SE_MEMWRITE_EN, MALIDP500_SE_CONTROL);
 
return 0;
@@ -658,7 +669,8 @@ static long malidp550_se_calc_mclk(struct malidp_hw_device 
*hwdev,
 
 static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev,
 dma_addr_t *addrs, s32 *pitches,
-int num_planes, u16 w, u16 h, u32 fmt_id)
+int num_planes, u16 w, u16 h, u32 fmt_id,
+const s16 *rgb2yuv_coeffs)
 {
u32 base = MALIDP550_SE_MEMWRITE_BASE;
u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK);
@@ -689,6 +701,15 @@ static int malidp550_enable_memwrite(struct 
malidp_hw_device *hwdev,
malidp_hw_setbits(hwdev, MALIDP550_SE_MEMWRITE_ONESHOT | 
MALIDP_SE_MEMWRITE_EN,
  MALIDP550_SE_CONTROL);
 
+   if (rgb2yuv_coeffs) {
+   int i;
+
+   for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) {
+   malidp_hw_write(hwdev, rgb2yuv_coeffs[i],
+   MALIDP550_SE_RGB_YUV_COEFFS + i * 4);
+   }
+   }
+
return 0;
 }
 
diff --git a/drivers/gpu/drm/arm/malidp_hw.h b/drivers/gpu/drm/arm/malidp_hw.h
index ad2e96915d44..9fc94c08190f 100644
--- a/drivers/gpu/drm/arm/malidp_hw.h
+++ b/drivers/gpu/drm/arm/malidp_hw.h
@@ -191,7 +191,8 @@ struct malidp_hw {
 * @param fmt_id - internal format ID of output buffer
 */
int (*enable_memwrite)(struct malidp_hw_device *hwdev, dma_addr_t 
*addrs,
-  s32 *pitches, int num_planes, u16 w, u16 h, u32 
fmt_id);
+  s32 *pitches, int num_planes, u16 w, u16 h, u32 
fmt_id,
+  const s16 *rgb2yuv_coeffs);
 
/*
 * Disable the writing to memory of the next frame's content.
diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c
index cfd718e7e97c..429a11e6473b 100644
--- a/drivers/gpu/drm/arm/malidp_mw.c
+++ b/drivers/gpu/drm/arm/malidp_mw.c
@@ -26,6 +26,8 @@ struct malidp_mw_connector_state {
s32 pitches[2];
u8 format;
u8 n_planes;
+   bool rgb2yuv_initialized;
+   const s16 *rgb2yuv_coeffs;
 };
 
 static int malidp_mw_connector_get_modes(struct drm_connector *connector)
@@ -84,7 +86,7 @@ static void malidp_mw_connector_destroy(struct drm_connector 
*connector)
 static struct drm_connector_state *
 malidp_mw_connector_duplicate_state(struct drm_connector *connector)
 {
-   struct malidp_mw_connector

[PATCH v2 4/5] drm: Add support for handling linear tile formats

2018-08-21 Thread Alexandru Gheorghe
The previous patch added tile_w and tile_h, which represent the
horizontal and vertical sizes of a tile.

This one uses that to plumb through drm core in order to be able to
handle linear tile formats without the need for drivers to roll up
their own implementation.

This patch had been written with Mali-dp X0L2 and X0L0 in mind which
is a 1 plane YCbCr 420 format with a 2x2 tile, that uses in average 2
bytes per pixel and where tiles are laid out in a linear manner.

Now what are the restrictions:

1. Pitch in bytes is expected to cover at least tile_h * width in
pixels. Due to this the places where the pitch is checked/used need to
be updated to take into consideration the tile_w, tile_h and
tile_size.
tile_size = cpp * tile_w * tile_h

2. When doing source cropping plane_src_x/y need to be a multiple of
tile_w/tile_h and we need to take into consideration the tile_w/tile_h
when computing the start address.

For all non-tiled formats the tile_w and tile_h will be 1, so if I
didn't miss anything nothing should change.

Regarding multi-planar linear tile formats, I'm not sure how those
should be handle I kind of assumed that tile_h/tile_w will have to be
divided by horizontal/subsampling. Anyway, I think it's best to just
put an warning in there and handle it when someone tries to add
support for them.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_atomic.c |  8 +++
 drivers/gpu/drm/drm_fb_cma_helper.c  | 11 -
 drivers/gpu/drm/drm_fourcc.c | 52 
 drivers/gpu/drm/drm_framebuffer.c| 19 +--
 drivers/gpu/drm/drm_gem_framebuffer_helper.c | 10 ++--
 include/drm/drm_fourcc.h |  2 +
 6 files changed, 94 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 3eb061e11e2e..7a3e893a4cd1 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1087,6 +1087,14 @@ static int drm_atomic_plane_check(struct drm_plane 
*plane,
return -ENOSPC;
}
 
+   /* Make sure source coordinates are a multiple of tile sizes */
+   if ((state->src_x >> 16) % state->fb->format->tile_w ||
+   (state->src_y >> 16) % state->fb->format->tile_h) {
+   DRM_DEBUG_ATOMIC("[PLANE:%d:%s] Source coordinates do not meet 
tile restrictions",
+plane->base.id, plane->name);
+   return -EINVAL;
+   }
+
if (plane_switching_crtc(state->state, plane, state)) {
DRM_DEBUG_ATOMIC("[PLANE:%d:%s] switching CRTC directly\n",
 plane->base.id, plane->name);
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c 
b/drivers/gpu/drm/drm_fb_cma_helper.c
index 47e0e2f6642d..4d8052adce67 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -87,6 +87,8 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb,
struct drm_gem_cma_object *obj;
dma_addr_t paddr;
u8 h_div = 1, v_div = 1;
+   u32 tile_w = drm_format_tile_width(fb->format, plane);
+   u32 tile_h = drm_format_tile_height(fb->format, plane);
 
obj = drm_fb_cma_get_gem_obj(fb, plane);
if (!obj)
@@ -99,8 +101,13 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer 
*fb,
v_div = fb->format->vsub;
}
 
-   paddr += (fb->format->cpp[plane] * (state->src_x >> 16)) / h_div;
-   paddr += (fb->pitches[plane] * (state->src_y >> 16)) / v_div;
+   paddr += (fb->format->cpp[plane] * tile_w * (state->src_x >> 16))
+   / h_div;
+   /*
+* For tile formats pitches are expected to cover at least
+* width * tile_h pixels
+*/
+   paddr += ((fb->pitches[plane] / tile_h) * (state->src_y >> 16)) / v_div;
 
return paddr;
 }
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index f55cd93ba2d0..d6c9c5aa4036 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -557,3 +557,55 @@ int drm_format_plane_height(int height, uint32_t format, 
int plane)
return height / info->vsub;
 }
 EXPORT_SYMBOL(drm_format_plane_height);
+
+/**
+ * drm_format_tile_width - width of a tile for tile formats, should be 1 for 
all
+ * non-tiled formats.
+ * @format: pixel format
+ * @plane: plane index
+ *
+ * Returns:
+ * The width of a tile, depending on the plane index and horizontal 
sub-sampling
+ */
+uint32_t drm_format_tile_width(const struct drm_format_info *info, int plane)
+{
+   WARN_ON(!info->tile_w);
+   if (plane == 0 || info->tile_w == 1)
+   return info->tile_w;
+
+   /*
+* Multi planar tiled formats have never been tested, check that
+* buffer restrictions and source

[PATCH v2 5/5] drm: mali-dp: Enable mali specific buffer formats

2018-08-21 Thread Alexandru Gheorghe
Enable the following formats
- DRM_FORMAT_XYUV
- DRM_FORMAT_XVYU2101010
- DRM_FORMAT_X0L0
- DRM_FORMAT_X0L2
- DRM_FORMAT_P010

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/arm/malidp_hw.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index c94a4422e0e9..472cae76e19b 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -74,10 +74,15 @@ static const struct malidp_format_id malidp500_de_formats[] 
= {
{ DRM_FORMAT_ABGR1555, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, 
MALIDP_ID(4, 1) }, \
{ DRM_FORMAT_RGB565, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, MALIDP_ID(4, 
2) }, \
{ DRM_FORMAT_BGR565, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, MALIDP_ID(4, 
3) }, \
+   { DRM_FORMAT_XYUV, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 0) }, \
{ DRM_FORMAT_YUYV, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 2) },\
{ DRM_FORMAT_UYVY, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 3) },\
+   { DRM_FORMAT_X0L0, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 4)}, \
{ DRM_FORMAT_NV12, DE_VIDEO1 | DE_VIDEO2 | SE_MEMWRITE, MALIDP_ID(5, 6) 
},  \
-   { DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }
+   { DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }, \
+   { DRM_FORMAT_XVYU2101010, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 0)}, \
+   { DRM_FORMAT_X0L2, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 6)}, \
+   { DRM_FORMAT_P010, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 7)}
 
 static const struct malidp_format_id malidp550_de_formats[] = {
MALIDP_COMMON_FORMATS,
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 3/5] drm/i915: Set tile sizes in drm_format_info

2018-08-21 Thread Alexandru Gheorghe
Two new fields had been added to drm_format_info struct, tile_w and
tile_h, this need to be set to 1 for all non-tiled formats.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/i915/intel_display.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index bd8956f2544d..fdc679e9dfa3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2440,10 +2440,14 @@ static unsigned int 
intel_fb_modifier_to_tiling(uint64_t fb_modifier)
  * main surface.
  */
 static const struct drm_format_info ccs_formats[] = {
-   { .format = DRM_FORMAT_XRGB, .depth = 24, .num_planes = 2, .cpp = { 
4, 1, }, .hsub = 8, .vsub = 16, },
-   { .format = DRM_FORMAT_XBGR, .depth = 24, .num_planes = 2, .cpp = { 
4, 1, }, .hsub = 8, .vsub = 16, },
-   { .format = DRM_FORMAT_ARGB, .depth = 32, .num_planes = 2, .cpp = { 
4, 1, }, .hsub = 8, .vsub = 16, },
-   { .format = DRM_FORMAT_ABGR, .depth = 32, .num_planes = 2, .cpp = { 
4, 1, }, .hsub = 8, .vsub = 16, },
+   { .format = DRM_FORMAT_XRGB, .depth = 24, .num_planes = 2, .cpp = { 
4, 1, },
+   .hsub = 8, .vsub = 16, .tile_w = 1, .tile_h = 1 },
+   { .format = DRM_FORMAT_XBGR, .depth = 24, .num_planes = 2, .cpp = { 
4, 1, },
+ .hsub = 8, .vsub = 16, .tile_w = 1, .tile_h = 1 },
+   { .format = DRM_FORMAT_ARGB, .depth = 32, .num_planes = 2, .cpp = { 
4, 1, },
+ .hsub = 8, .vsub = 16, .tile_w = 1, .tile_h = 1 },
+   { .format = DRM_FORMAT_ABGR, .depth = 32, .num_planes = 2, .cpp = { 
4, 1, },
+ .hsub = 8, .vsub = 16, .tile_w = 1, .tile_h = 1 },
 };
 
 static const struct drm_format_info *
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 2/5] drm/fourcc: Add tile width and height to drm_format_info

2018-08-21 Thread Alexandru Gheorghe
Add two new fields(tile_w and tile_h) to drm_format_info, which
represent the horizontal and vertical sizes of a tile in tiled
formats.
This fields will be used by the next patch to add support in drm
core for handling framebuffer restrictions and to correctly handle
source cropping.

Additionally, since I was touching drm_format_info table I decided to
break the lines to the 80 characters limit, they were already getting
out of hand, but let's not focus on that, I don't have any problem
going back to the original line sizes or style them other way, if
someone wants me to.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_fourcc.c | 352 +++
 include/drm/drm_fourcc.h |   4 +
 2 files changed, 281 insertions(+), 75 deletions(-)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 18bb960e9943..f55cd93ba2d0 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -105,81 +105,283 @@ EXPORT_SYMBOL(drm_get_format_name);
 const struct drm_format_info *__drm_format_info(u32 format)
 {
static const struct drm_format_info formats[] = {
-   { .format = DRM_FORMAT_C8,  .depth = 8,  
.num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_RGB332,  .depth = 8,  
.num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_BGR233,  .depth = 8,  
.num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_XRGB,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_XBGR,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_RGBX,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_BGRX,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_ARGB,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-   { .format = DRM_FORMAT_ABGR,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-   { .format = DRM_FORMAT_RGBA,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-   { .format = DRM_FORMAT_BGRA,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-   { .format = DRM_FORMAT_XRGB1555,.depth = 15, 
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_XBGR1555,.depth = 15, 
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_RGBX5551,.depth = 15, 
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_BGRX5551,.depth = 15, 
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_ARGB1555,.depth = 15, 
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-   { .format = DRM_FORMAT_ABGR1555,.depth = 15, 
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-   { .format = DRM_FORMAT_RGBA5551,.depth = 15, 
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-   { .format = DRM_FORMAT_BGRA5551,.depth = 15, 
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-   { .format = DRM_FORMAT_RGB565,  .depth = 16, 
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_BGR565,  .depth = 16, 
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_RGB888,  .depth = 24, 
.num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_BGR888,  .depth = 24, 
.num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_XRGB,.depth = 24, 
.num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_XBGR,.depth = 24, 
.num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_RGBX,.depth = 24, 
.num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_BGRX,.depth = 24, 
.num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
-   { .format = DRM_FORMAT_RGB565_A8,   .depth = 24, 
.num_planes = 2, .cpp = { 2, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true

[PATCH v2 1/5] drm/fourcc: Add new fourcc for malidp uncompressed formats

2018-08-21 Thread Alexandru Gheorghe
Malidp implements a number of yuv buffer formats which are not
currently described in drm_fourcc.h.
This adds those definitions and describes their memory layout.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_fourcc.c  |  7 +++
 include/uapi/drm/drm_fourcc.h | 27 ++-
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 35c1e2742c27..18bb960e9943 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -173,6 +173,13 @@ const struct drm_format_info *__drm_format_info(u32 format)
{ .format = DRM_FORMAT_UYVY,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_VYUY,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_AYUV,.depth = 0,  
.num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, 
.is_yuv = true },
+   { .format = DRM_FORMAT_XYUV,.depth = 0,  
.num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
+   { .format = DRM_FORMAT_XVYU2101010, .depth = 0,  
.num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
+   { .format = DRM_FORMAT_Y0L0,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 2, .has_alpha = true, 
.is_yuv = true },
+   { .format = DRM_FORMAT_X0L0,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true },
+   { .format = DRM_FORMAT_Y0L2,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 2, .has_alpha = true, 
.is_yuv = true },
+   { .format = DRM_FORMAT_X0L2,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true },
+   { .format = DRM_FORMAT_P010,.depth = 0,  
.num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 2, .is_yuv  = true },
};
 
unsigned int i;
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 21c50b39596f..5e01fbcd7a30 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -141,13 +141,31 @@ extern "C" {
 #define DRM_FORMAT_RGBA1010102 fourcc_code('R', 'A', '3', '0') /* [31:0] 
R:G:B:A 10:10:10:2 little endian */
 #define DRM_FORMAT_BGRA1010102 fourcc_code('B', 'A', '3', '0') /* [31:0] 
B:G:R:A 10:10:10:2 little endian */
 
-/* packed YCbCr */
+/* packed YCbCr422 */
 #define DRM_FORMAT_YUYVfourcc_code('Y', 'U', 'Y', 'V') /* 
[31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */
 #define DRM_FORMAT_YVYUfourcc_code('Y', 'V', 'Y', 'U') /* 
[31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */
 #define DRM_FORMAT_UYVYfourcc_code('U', 'Y', 'V', 'Y') /* 
[31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian */
 #define DRM_FORMAT_VYUYfourcc_code('V', 'Y', 'U', 'Y') /* 
[31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */
 
+/* packed YCbCr444 */
 #define DRM_FORMAT_AYUVfourcc_code('A', 'Y', 'U', 'V') /* 
[31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
+#define DRM_FORMAT_XYUVfourcc_code('X', 'Y', 'U', 'V') /* [31:0] 
X:Y:Cb:Cr 8:8:8:8 little endian */
+#define DRM_FORMAT_XVYU2101010 fourcc_code('X', 'V', '3', '0') /* [31:0] 
X:Cr:Y:Cb 2:10:10:10 little endian */
+
+/*
+ * packed YCbCr420 2x2 tiled formats
+ * first 64 bits will contain Y,Cb,Cr components for a 2x2 tile
+ */
+
+/* [63:0]   A3:A2:Y3:0:Cr0:0:Y2:0:A1:A0:Y1:0:Cb0:0:Y0:0  
1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian */
+#define DRM_FORMAT_Y0L0fourcc_code('Y', '0', 'L', '0')
+/* [63:0]   X3:X2:Y3:0:Cr0:0:Y2:0:X1:X0:Y1:0:Cb0:0:Y0:0  
1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian */
+#define DRM_FORMAT_X0L0fourcc_code('X', '0', 'L', '0')
+
+/* [63:0]   A3:A2:Y3:Cr0:Y2:A1:A0:Y1:Cb0:Y0  1:1:10:10:10:1:1:10:10:10 little 
endian */
+#define DRM_FORMAT_Y0L2fourcc_code('Y', '0', 'L', '2')
+/* [63:0]   X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0  1:1:10:10:10:1:1:10:10:10 little 
endian */
+#define DRM_FORMAT_X0L2fourcc_code('X', '0', 'L', '2')
 
 /*
  * 2 plane RGB + A
@@ -177,6 +195,13 @@ extern "C" {
 #define DRM_FORMAT_NV24fourcc_code('N', 'V', '2', '4') /* 
non-subsampled Cr:Cb plane */
 #define DRM_FORMAT_NV42fourcc_code('N', 'V', '4', '2') /* 
non-subsampled Cb:Cr plane */
 
+/*
+ * Each sample packed into the top 10 bits of a 16-bit word.
+ * Y plane: [63:0] Y3:0:Y2:0:Y1:0:Y0:0, 10:6:10:6:10:6:10:6
+ * CrCb plane: [63:0] Cr2:0:Cb2:0:Cr0:0:Cb0:0, 10:6:10:6:10:6:10:6
+ */
+#define DRM_FORMAT_P010fourcc_code('P', '0', '1', '0') /* 2x2 
subsampled Cr:Cb plane */
+
 /*
  * 3 plane YCbCr
  * index 0: Y plane

[PATCH v2 0/5] Add Mali DP non-compressed pixel formats

2018-08-21 Thread Alexandru Gheorghe
Change since v1 [1]:
  - Droped changes that add special handling of the tile formats
X0L0/X0L2 in the driver and extend drm_core, by adding tile_h and
tile_w in drm_format_info, suggested by Daniel Vetter here [2],
see patches 2 to 4.
  - Use a differnt fourcc code for DRM_FORMAT_XVYU2101010, as
suggested by Brian Starkey here [3].

Mali DP supports a bunch of pixel formats that don't have a fourcc
code defined in drm_fourcc.h, so this patchset adds the definition for
those formats and enables them in mali-dp driver.

The following new formats will be added:

Packed YCbCr444
* DRM_FORMAT_XYUV
* DRM_FORMAT_XVYU2101010

Two plane 10 bits format.
* DRM_FORMAT_P010

Packed YCbCr420 2x2 tiled formats
* DRM_FORMAT_Y0L0
* DRM_FORMAT_X0L0
* DRM_FORMAT_Y0L2
* DRM_FORMAT_X0L2
The difference between X0L0/X0L2 vs Y0L0/Y0L2 is that the later group
have two alpha bits per pixel.

This group is a bit special because we are dealing with a tiled format
where the first 64 bits in memory represent the pixels for a 2x2 tile,
so it needs a bit of special handling when it comes to:
 - pitch: needs to cover both rows that are in the same tile.
 - min allocation size: since a pitch cover both rows the formulas
   defined in drm_gem_fb_create don't work anymore.
 - handling of src_x and src_y offset: same as above since we are
   dealing with a tiled format drm_fb_cma_get_gem_obj doesn't return
   the correct address offset.

[1] https://lists.freedesktop.org/archives/dri-devel/2018-July/184597.html
[2] https://lists.freedesktop.org/archives/dri-devel/2018-August/186465.html
[3] https://lists.freedesktop.org/archives/dri-devel/2018-August/186057.html

Alexandru Gheorghe (5):
  drm/fourcc: Add new fourcc for malidp uncompressed formats
  drm/fourcc: Add tile width and height to drm_format_info
  drm/i915: Set tile sizes in drm_format_info
  drm: Add support for handling linear tile formats
  drm: mali-dp: Enable mali specific buffer formats

 drivers/gpu/drm/arm/malidp_hw.c  |   7 +-
 drivers/gpu/drm/drm_atomic.c |   8 +
 drivers/gpu/drm/drm_fb_cma_helper.c  |  11 +-
 drivers/gpu/drm/drm_fourcc.c | 397 +++
 drivers/gpu/drm/drm_framebuffer.c|  19 +-
 drivers/gpu/drm/drm_gem_framebuffer_helper.c |  10 +-
 drivers/gpu/drm/i915/intel_display.c |  12 +-
 include/drm/drm_fourcc.h |   6 +
 include/uapi/drm/drm_fourcc.h|  27 +-
 9 files changed, 415 insertions(+), 82 deletions(-)

-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/malidp: Fix writeback in NV12

2018-08-20 Thread Alexandru Gheorghe
When we want to writeback to memory in NV12 format we need to program
the RGB2YUV coefficients.
Currently, we don't program the coefficients and the NV12 doesn't work
at all.

This patchset fixes that by programming a sane default(bt709, limited
range) as rgb2yuv coefficients.

In the long run, probably we need to think of a way for userspace to
be able to program that, but for now I think this is better than not
working at all or not advertising NV12 as a supported format for
memwrite.

Reviewed-by: Liviu Dudau 
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/arm/malidp_hw.c   | 25 +++--
 drivers/gpu/drm/arm/malidp_hw.h   |  6 --
 drivers/gpu/drm/arm/malidp_mw.c   | 12 +++-
 drivers/gpu/drm/arm/malidp_regs.h |  2 ++
 4 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index c94a4422e0e9..2781e462c1ed 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -384,7 +384,8 @@ static long malidp500_se_calc_mclk(struct malidp_hw_device 
*hwdev,
 
 static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev,
 dma_addr_t *addrs, s32 *pitches,
-int num_planes, u16 w, u16 h, u32 fmt_id)
+int num_planes, u16 w, u16 h, u32 fmt_id,
+const s16 *rgb2yuv_coeffs)
 {
u32 base = MALIDP500_SE_MEMWRITE_BASE;
u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK);
@@ -416,6 +417,16 @@ static int malidp500_enable_memwrite(struct 
malidp_hw_device *hwdev,
 
malidp_hw_write(hwdev, MALIDP_DE_H_ACTIVE(w) | MALIDP_DE_V_ACTIVE(h),
MALIDP500_SE_MEMWRITE_OUT_SIZE);
+
+   if (rgb2yuv_coeffs) {
+   int i;
+
+   for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) {
+   malidp_hw_write(hwdev, rgb2yuv_coeffs[i],
+   MALIDP500_SE_RGB_YUV_COEFFS + i * 4);
+   }
+   }
+
malidp_hw_setbits(hwdev, MALIDP_SE_MEMWRITE_EN, MALIDP500_SE_CONTROL);
 
return 0;
@@ -658,7 +669,8 @@ static long malidp550_se_calc_mclk(struct malidp_hw_device 
*hwdev,
 
 static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev,
 dma_addr_t *addrs, s32 *pitches,
-int num_planes, u16 w, u16 h, u32 fmt_id)
+int num_planes, u16 w, u16 h, u32 fmt_id,
+const s16 *rgb2yuv_coeffs)
 {
u32 base = MALIDP550_SE_MEMWRITE_BASE;
u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK);
@@ -689,6 +701,15 @@ static int malidp550_enable_memwrite(struct 
malidp_hw_device *hwdev,
malidp_hw_setbits(hwdev, MALIDP550_SE_MEMWRITE_ONESHOT | 
MALIDP_SE_MEMWRITE_EN,
  MALIDP550_SE_CONTROL);
 
+   if (rgb2yuv_coeffs) {
+   int i;
+
+   for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) {
+   malidp_hw_write(hwdev, rgb2yuv_coeffs[i],
+   MALIDP550_SE_RGB_YUV_COEFFS + i * 4);
+   }
+   }
+
return 0;
 }
 
diff --git a/drivers/gpu/drm/arm/malidp_hw.h b/drivers/gpu/drm/arm/malidp_hw.h
index ad2e96915d44..d2ceb70305ca 100644
--- a/drivers/gpu/drm/arm/malidp_hw.h
+++ b/drivers/gpu/drm/arm/malidp_hw.h
@@ -190,8 +190,10 @@ struct malidp_hw {
 * @param h - height of the output frame
 * @param fmt_id - internal format ID of output buffer
 */
-   int (*enable_memwrite)(struct malidp_hw_device *hwdev, dma_addr_t 
*addrs,
-  s32 *pitches, int num_planes, u16 w, u16 h, u32 
fmt_id);
+   int (*enable_memwrite)(struct malidp_hw_device *hwdev,
+  dma_addr_t *addrs, s32 *pitches, int num_planes,
+  u16 w, u16 h, u32 fmt_id,
+  const s16 *rgb2yuv_coeffs);
 
/*
 * Disable the writing to memory of the next frame's content.
diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c
index cfd718e7e97c..0523ba5d27dd 100644
--- a/drivers/gpu/drm/arm/malidp_mw.c
+++ b/drivers/gpu/drm/arm/malidp_mw.c
@@ -213,6 +213,13 @@ int malidp_mw_connector_init(struct drm_device *drm)
return 0;
 }
 
+static const s16 rgb2yuv_coeffs_bt709_limited[MALIDP_COLORADJ_NUM_COEFFS] = {
+   47,  157,   16,
+   -26,  -87,  112,
+   112, -102,  -10,
+   16,  128,  128
+};
+
 void malidp_mw_atomic_commit(struct drm_device *drm,
 struct drm_atomic_state *old_state)
 {
@@ -242,7 +249,10 @@ void malidp_mw_atomic_commit(struct drm_device *drm,
 
hwdev->hw->enable_memwrite(hwdev, mw_state->addrs,

[PATCH] drm/malidp: Enable MMU prefetch on Mali-DP650

2018-08-20 Thread Alexandru Gheorghe
From: Jamie Fox 

Mali-DP650 supports warming up the SMMU translations, by sending
requsts to the SMMU before a buffer is read.

There are two modes supported:

- PARTIAL: could be enabled when the buffer is composed of 4K or 64K
  pages, the display hardware will send a configurable number of
  requests before the actual reading.

- FULL: could be enabled when the buffer is composed of 1M or 2M
  pages, the display hardware will send requests before reading for
  all pages composing the buffer.

This patch adds a mechanism for detecting the page size and set the
MMU prefetch mode if possible.

Signed-off-by: Jamie Fox 
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/arm/malidp_drv.h|   9 ++
 drivers/gpu/drm/arm/malidp_hw.c |  17 +-
 drivers/gpu/drm/arm/malidp_hw.h |   1 +
 drivers/gpu/drm/arm/malidp_planes.c | 233 
 drivers/gpu/drm/arm/malidp_regs.h   |  11 ++
 5 files changed, 269 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.h b/drivers/gpu/drm/arm/malidp_drv.h
index e3eb0cb1f385..2d824558216f 100644
--- a/drivers/gpu/drm/arm/malidp_drv.h
+++ b/drivers/gpu/drm/arm/malidp_drv.h
@@ -53,6 +53,13 @@ struct malidp_plane {
struct drm_plane base;
struct malidp_hw_device *hwdev;
const struct malidp_layer *layer;
+
+};
+
+enum mmu_prefetch_mode {
+   MALIDP_PREFETCH_MODE_NONE,
+   MALIDP_PREFETCH_MODE_PARTIAL,
+   MALIDP_PREFETCH_MODE_FULL,
 };
 
 struct malidp_plane_state {
@@ -63,6 +70,8 @@ struct malidp_plane_state {
/* internal format ID */
u8 format;
u8 n_planes;
+   enum mmu_prefetch_mode mmu_prefetch_mode;
+   u32 mmu_prefetch_pgsize;
 };
 
 #define to_malidp_plane(x) container_of(x, struct malidp_plane, base)
diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index c94a4422e0e9..4233be1c5709 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -96,6 +96,19 @@ static const struct malidp_layer malidp550_layers[] = {
{ DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, 
MALIDP550_DE_LS_R1_STRIDE, 0 },
 };
 
+static const struct malidp_layer malidp650_layers[] = {
+   { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE,
+   MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB,
+   MALIDP650_DE_LV_MMU_CTRL },
+   { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE,
+   MALIDP_DE_LG_STRIDE, 0, MALIDP650_DE_LG_MMU_CTRL },
+   { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE,
+   MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB,
+   MALIDP650_DE_LV_MMU_CTRL },
+   { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE,
+   MALIDP550_DE_LS_R1_STRIDE, 0, MALIDP650_DE_LS_MMU_CTRL },
+};
+
 #define SE_N_SCALING_COEFFS96
 static const u16 dp500_se_scaling_coeffs[][SE_N_SCALING_COEFFS] = {
[MALIDP_UPSCALING_COEFFS - 1] = {
@@ -832,8 +845,8 @@ const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES] = {
.dc_base = MALIDP550_DC_BASE,
.out_depth_base = MALIDP550_DE_OUTPUT_DEPTH,
.features = MALIDP_REGMAP_HAS_CLEARIRQ,
-   .n_layers = ARRAY_SIZE(malidp550_layers),
-   .layers = malidp550_layers,
+   .n_layers = ARRAY_SIZE(malidp650_layers),
+   .layers = malidp650_layers,
.de_irq_map = {
.irq_mask = MALIDP_DE_IRQ_UNDERRUN |
MALIDP650_DE_IRQ_DRIFT |
diff --git a/drivers/gpu/drm/arm/malidp_hw.h b/drivers/gpu/drm/arm/malidp_hw.h
index ad2e96915d44..39b92a9fb810 100644
--- a/drivers/gpu/drm/arm/malidp_hw.h
+++ b/drivers/gpu/drm/arm/malidp_hw.h
@@ -62,6 +62,7 @@ struct malidp_layer {
u16 ptr;/* address offset for the pointer register */
u16 stride_offset;  /* offset to the first stride register. */
s16 yuv2rgb_offset; /* offset to the YUV->RGB matrix entries */
+   u16 mmu_ctrl_offset;/* offset to the MMU control register */
 };
 
 enum malidp_scaling_coeff_set {
diff --git a/drivers/gpu/drm/arm/malidp_planes.c 
b/drivers/gpu/drm/arm/malidp_planes.c
index 29409a65d864..99c487be9a1d 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -10,11 +10,14 @@
  * ARM Mali DP plane manipulation routines.
  */
 
+#include 
+
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -56,6 +59,13 @@
  */
 #define MALIDP_ALPHA_LUT 0xffaa5500
 
+/* page sizes the MMU prefetcher can support */
+#define MALIDP_MMU_PREFETCH_PARTIAL_PGSIZES(SZ_4K | SZ_64K)
+#define MALIDP_MMU_PREFETCH_FULL_PGSIZES   (SZ_1M | SZ_2M)
+
+/* readahead for partial-frame prefetch */
+#define MALIDP_MMU_PREFETCH_READAHEAD  8
+
 static v

[PATCH] drm: Clarify DRM_MODE_REFLECT_X/Y documentation

2018-08-10 Thread Alexandru Gheorghe
DRM_MODE_REFLECT_X and DRM_MODE_REFLECT_Y meaning seems a bit unclear
to me, so try to clarify that with a bit of ascii graphics.

Signed-off-by: Alexandru Gheorghe 
---
 include/uapi/drm/drm_mode.h | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 8d67243952f4..ac5de85c93eb 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -186,9 +186,18 @@ extern "C" {
 /*
  * DRM_MODE_REFLECT_
  *
- * Signals that the contents of a drm plane is reflected in the  axis,
+ * Signals that the contents of a drm plane is reflected along the  axis,
  * in the same way as mirroring.
  *
+ * DRM_MODE_REFLECT_X
+ * |o || o|
+ * |  | -> |  |
+ * | v||v |
+ *
+ * DRM_MODE_REFLECT_Y
+ * |o || ^|
+ * |  | -> |  |
+ * | v||o |
  * This define is provided as a convenience, looking up the property id
  * using the name->prop id lookup is the preferred method.
  */
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 09/10] drm/vc4: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-08-04 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc.) to their default values.
Use that instead of duplicating the logic.

__drm_atomic_helper_plane_reset initializes the alpha property to its
max value, which is defined by the drm core as DRM_BLEND_ALPHA_OPAQUE,
so nothing changes regarding the alpha value.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/vc4/vc4_plane.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 9d7a36f148cf..688ad9bb0f08 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -200,9 +200,7 @@ static void vc4_plane_reset(struct drm_plane *plane)
if (!vc4_state)
return;
 
-   plane->state = _state->base;
-   plane->state->alpha = DRM_BLEND_ALPHA_OPAQUE;
-   vc4_state->base.plane = plane;
+   __drm_atomic_helper_plane_reset(plane, _state->base);
 }
 
 static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val)
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 05/10] drm/exynos: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-08-04 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc.) to their default values.
Use that instead of duplicating the logic.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/exynos/exynos_drm_plane.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c 
b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index eb9915da7dec..681328fbe7de 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -139,8 +139,7 @@ static void exynos_drm_plane_reset(struct drm_plane *plane)
 
exynos_state = kzalloc(sizeof(*exynos_state), GFP_KERNEL);
if (exynos_state) {
-   plane->state = _state->base;
-   plane->state->plane = plane;
+   __drm_atomic_helper_plane_reset(plane, _state->base);
plane->state->zpos = exynos_plane->config->zpos;
}
 }
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 08/10] drm/sun4i: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-08-04 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc.) to their default values.
Use that instead of duplicating the logic.

__drm_atomic_helper_plane_reset initializes the alpha property to its
max value, which is defined by the drm core as DRM_BLEND_ALPHA_OPAQUE,
so nothing changes regarding the alpha value.

Acked-by: Maxime Ripard 
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/sun4i/sun4i_layer.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c 
b/drivers/gpu/drm/sun4i/sun4i_layer.c
index 750ad24de1d7..78f77af8805a 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -35,9 +35,7 @@ static void sun4i_backend_layer_reset(struct drm_plane *plane)
 
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (state) {
-   plane->state = >state;
-   plane->state->plane = plane;
-   plane->state->alpha = DRM_BLEND_ALPHA_OPAQUE;
+   __drm_atomic_helper_plane_reset(plane, >state);
plane->state->zpos = layer->id;
}
 }
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 04/10] drm: atmel-hlcdc: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-08-04 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc.) to their default values.
Use that instead of duplicating the logic.

__drm_atomic_helper_plane_reset initializes the alpha property to its
max value, which is defined by the drm core as DRM_BLEND_ALPHA_OPAQUE,
so nothing changes regarding the alpha value.

Acked-by: Boris Brezillon 
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c 
b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index 04440064b9b7..9330a076e15a 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -942,10 +942,7 @@ static void atmel_hlcdc_plane_reset(struct drm_plane *p)
"Failed to allocate initial plane state\n");
return;
}
-
-   p->state = >base;
-   p->state->alpha = DRM_BLEND_ALPHA_OPAQUE;
-   p->state->plane = p;
+   __drm_atomic_helper_plane_reset(p, >base);
}
 }
 
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 10/10] drm/vmwgfx: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-08-04 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc.) to their default values.
Use that instead of duplicating the logic.

Reviewed-by: Sinclair Yeh 
Reviewed-by: Deepak Rawat 
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 4a0f0f41afa1..61824e360619 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -720,9 +720,7 @@ void vmw_du_plane_reset(struct drm_plane *plane)
return;
}
 
-   plane->state = >base;
-   plane->state->plane = plane;
-   plane->state->rotation = DRM_MODE_ROTATE_0;
+   __drm_atomic_helper_plane_reset(plane, >base);
 }
 
 
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 06/10] drm/imx: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-08-04 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc.) to their default values.
Use that instead of duplicating the logic.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/imx/ipuv3-plane.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c 
b/drivers/gpu/drm/imx/ipuv3-plane.c
index 203f247d4854..1bd4de03ce9e 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -281,16 +281,14 @@ static void ipu_plane_state_reset(struct drm_plane *plane)
ipu_state = to_ipu_plane_state(plane->state);
__drm_atomic_helper_plane_destroy_state(plane->state);
kfree(ipu_state);
+   plane->state = NULL;
}
 
ipu_state = kzalloc(sizeof(*ipu_state), GFP_KERNEL);
 
-   if (ipu_state) {
-   ipu_state->base.plane = plane;
-   ipu_state->base.rotation = DRM_MODE_ROTATE_0;
-   }
+   if (ipu_state)
+   __drm_atomic_helper_plane_reset(plane, _state->base);
 
-   plane->state = _state->base;
 }
 
 static struct drm_plane_state *
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 02/10] drm/amd/display: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-08-04 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc) to their default values.
Use that instead of duplicating the logic.

Reviewed-by: Harry Wentland 
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index ae09331eed00..8e4978d5b83f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2965,11 +2965,8 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
amdgpu_state = kzalloc(sizeof(*amdgpu_state), GFP_KERNEL);
WARN_ON(amdgpu_state == NULL);

-   if (amdgpu_state) {
-   plane->state = _state->base;
-   plane->state->plane = plane;
-   plane->state->rotation = DRM_MODE_ROTATE_0;
-   }
+   if (amdgpu_state)
+   __drm_atomic_helper_plane_reset(plane, _state->base);
 }
 
 static struct drm_plane_state *
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 00/10] Add helper for plane reset

2018-08-04 Thread Alexandru Gheorghe
No significant change since v2, fixed a spelling mistake and
added/removed some newlines in 01 and 07 patches.

I plan to apply the first patch of the series and the patches for
the drivers maintained through drm-misc(that go Reviewed/Ack) in
drm-misc-next on Monday.

For the other drivers please let me know if you want me to push them
in drm-misc-next as well.

Changes since v1: 
 - Make __drm_atomic_helper_plane_reset consistent with the other
   helpers and require that both plane and state not be NULL,
   suggested by Boris Brezillon and Philipp Zabel. Drivers already
   check for that.
 - Add a proper commit message for driver changes.

Drivers that subclass drm_plane need to copy the logic for linking the
drm_plane with its state and to initialize core properties to their
default values. E.g (alpha and rotation)

Having a helper to reset the plane_state makes sense because of multiple
reasons:
1. Eliminate code duplication.
2. Add a single place for initializing core properties to their
default values, no need for driver to do it if what the helper sets
makes sense for them.
3. No need to debug the driver when you enable a core property and
observe it doesn't have a proper default value.

Tested with mali-dp the other drivers are just built-tested.


Alexandru Gheorghe (10):
  drm/atomic: Add  __drm_atomic_helper_plane_reset
  drm/amd/display: Use __drm_atomic_helper_plane_reset instead of
copying the logic
  drm: mali-dp: Use __drm_atomic_helper_plane_reset instead of copying
the logic
  drm: atmel-hlcdc: Use __drm_atomic_helper_plane_reset instead of
copying the logic
  drm/exynos: Use __drm_atomic_helper_plane_reset instead of copying the
logic
  drm/imx: Use __drm_atomic_helper_plane_reset instead of copying the
logic
  drm: rcar-du: Use __drm_atomic_helper_plane_reset instead of copying
the logic
  drm/sun4i: Use __drm_atomic_helper_plane_reset instead of copying the
logic
  drm/vc4: Use __drm_atomic_helper_plane_reset instead of copying the
logic
  drm/vmwgfx: Use __drm_atomic_helper_plane_reset instead of copying the
logic

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  7 ++--
 drivers/gpu/drm/arm/malidp_planes.c   |  7 ++--
 .../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c   |  5 +--
 drivers/gpu/drm/drm_atomic_helper.c   | 33 ++-
 drivers/gpu/drm/exynos/exynos_drm_plane.c |  3 +-
 drivers/gpu/drm/imx/ipuv3-plane.c |  8 ++---
 drivers/gpu/drm/rcar-du/rcar_du_plane.c   |  6 ++--
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c |  5 +--
 drivers/gpu/drm/sun4i/sun4i_layer.c   |  4 +--
 drivers/gpu/drm/vc4/vc4_plane.c   |  4 +--
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c   |  4 +--
 include/drm/drm_atomic_helper.h   |  2 ++
 12 files changed, 41 insertions(+), 47 deletions(-)

-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 03/10] drm: mali-dp: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-08-04 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc.) to their default values.
Use that instead of duplicating the logic.

Reviewed-by: Ayan Kumar halder 
Acked-by: Liviu Dudau 
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/arm/malidp_planes.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_planes.c 
b/drivers/gpu/drm/arm/malidp_planes.c
index 29409a65d864..49c37f6dd63e 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -78,11 +78,8 @@ static void malidp_plane_reset(struct drm_plane *plane)
kfree(state);
plane->state = NULL;
state = kzalloc(sizeof(*state), GFP_KERNEL);
-   if (state) {
-   state->base.plane = plane;
-   state->base.rotation = DRM_MODE_ROTATE_0;
-   plane->state = >base;
-   }
+   if (state)
+   __drm_atomic_helper_plane_reset(plane, >base);
 }
 
 static struct
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 07/10] drm: rcar-du: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-08-04 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc.) to their default values.
Use that instead of duplicating the logic.

__drm_atomic_helper_plane_reset initializes the alpha property to its
max value, which is defined by the drm core as DRM_BLEND_ALPHA_OPAQUE,
so nothing changes regarding the alpha value.

Reviewed-by: Laurent Pinchart 
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/rcar-du/rcar_du_plane.c | 6 ++
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c   | 5 +
 2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c 
b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index c20f7ed48c8d..8861e715c248 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -690,14 +690,12 @@ static void rcar_du_plane_reset(struct drm_plane *plane)
if (state == NULL)
return;
 
+   __drm_atomic_helper_plane_reset(plane, >state);
+
state->hwindex = -1;
state->source = RCAR_DU_PLANE_MEMORY;
state->colorkey = RCAR_DU_COLORKEY_NONE;
state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
-
-   plane->state = >state;
-   plane->state->alpha = DRM_BLEND_ALPHA_OPAQUE;
-   plane->state->plane = plane;
 }
 
 static int rcar_du_plane_atomic_set_property(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c 
b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index 72eebeda518e..45eb777a16a4 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -346,11 +346,8 @@ static void rcar_du_vsp_plane_reset(struct drm_plane 
*plane)
if (state == NULL)
return;
 
-   state->state.alpha = DRM_BLEND_ALPHA_OPAQUE;
+   __drm_atomic_helper_plane_reset(plane, >state);
state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
-
-   plane->state = >state;
-   plane->state->plane = plane;
 }
 
 static const struct drm_plane_funcs rcar_du_vsp_plane_funcs = {
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 01/10] drm/atomic: Add __drm_atomic_helper_plane_reset

2018-08-04 Thread Alexandru Gheorghe
There are a lot of drivers that subclass drm_plane_state, all of them
duplicate the code that links together the plane with plane_state.

On top of that, drivers that enable core properties also have to
duplicate the code for initializing the properties to their default
values, which in all cases are the same as the defaults from core.

Change since v1:
- Make it consistent with the other helpers and require that both
  plane and state not be NULL, suggested by Boris Brezillon and
  Philipp Zabel.

Reviewed-by: Laurent Pinchart 
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_atomic_helper.c | 33 +
 include/drm/drm_atomic_helper.h |  2 ++
 2 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 866a2cc72ef6..6dd5036545ec 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3552,6 +3552,28 @@ void drm_atomic_helper_crtc_destroy_state(struct 
drm_crtc *crtc,
 }
 EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
 
+/**
+ * __drm_atomic_helper_plane_reset - resets planes state to default values
+ * @plane: plane object, must not be NULL
+ * @state: atomic plane state, must not be NULL
+ *
+ * Initializes plane state to default. This is useful for drivers that subclass
+ * the plane state.
+ */
+void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
+struct drm_plane_state *state)
+{
+   state->plane = plane;
+   state->rotation = DRM_MODE_ROTATE_0;
+
+   /* Reset the alpha value to fully opaque if it matters */
+   if (plane->alpha_property)
+   state->alpha = plane->alpha_property->values[1];
+
+   plane->state = state;
+}
+EXPORT_SYMBOL(__drm_atomic_helper_plane_reset);
+
 /**
  * drm_atomic_helper_plane_reset - default _plane_funcs.reset hook for 
planes
  * @plane: drm plane
@@ -3566,15 +3588,8 @@ void drm_atomic_helper_plane_reset(struct drm_plane 
*plane)
 
kfree(plane->state);
plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
-
-   if (plane->state) {
-   plane->state->plane = plane;
-   plane->state->rotation = DRM_MODE_ROTATE_0;
-
-   /* Reset the alpha value to fully opaque if it matters */
-   if (plane->alpha_property)
-   plane->state->alpha = plane->alpha_property->values[1];
-   }
+   if (plane->state)
+   __drm_atomic_helper_plane_reset(plane, plane->state);
 }
 EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
 
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 99e2a5297c69..f4c7ed876c97 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -156,6 +156,8 @@ void __drm_atomic_helper_crtc_destroy_state(struct 
drm_crtc_state *state);
 void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
  struct drm_crtc_state *state);
 
+void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
+struct drm_plane_state *state);
 void drm_atomic_helper_plane_reset(struct drm_plane *plane);
 void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
   struct drm_plane_state *state);
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 01/10] drm/atomic: Add __drm_atomic_helper_plane_reset

2018-07-26 Thread Alexandru Gheorghe
There are a lot of drivers that subclass drm_plane_state, all of them
duplicate the code that links toghether the plane with plane_state.

On top of that, drivers that enable core properties also have to
duplicate the code for initializing the properties to their default
values, which in all cases are the same as the defaults from core.

Change since v1:
- Make it consistent with the other helpers and require that both
  plane and state not be NULL, suggested by Boris Brezillon and
  Philipp Zabel.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_atomic_helper.c | 31 -
 include/drm/drm_atomic_helper.h |  2 ++
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 866a2cc72ef6..7f5aafc5b1a0 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3552,6 +3552,26 @@ void drm_atomic_helper_crtc_destroy_state(struct 
drm_crtc *crtc,
 }
 EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
 
+/**
+ * __drm_atomic_helper_plane_reset - resets planes state to default values
+ * @plane: plane object, must not be NULL
+ * @state: atomic plane state, must not be NULL
+ *
+ * Initializes plane state to default. This is useful for drivers that subclass
+ * the plane state.
+ */
+void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
+struct drm_plane_state *state)
+{
+   state->plane = plane;
+   state->rotation = DRM_MODE_ROTATE_0;
+   /* Reset the alpha value to fully opaque if it matters */
+   if (plane->alpha_property)
+   state->alpha = plane->alpha_property->values[1];
+   plane->state = state;
+}
+EXPORT_SYMBOL(__drm_atomic_helper_plane_reset);
+
 /**
  * drm_atomic_helper_plane_reset - default _plane_funcs.reset hook for 
planes
  * @plane: drm plane
@@ -3566,15 +3586,8 @@ void drm_atomic_helper_plane_reset(struct drm_plane 
*plane)
 
kfree(plane->state);
plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
-
-   if (plane->state) {
-   plane->state->plane = plane;
-   plane->state->rotation = DRM_MODE_ROTATE_0;
-
-   /* Reset the alpha value to fully opaque if it matters */
-   if (plane->alpha_property)
-   plane->state->alpha = plane->alpha_property->values[1];
-   }
+   if (plane->state)
+   __drm_atomic_helper_plane_reset(plane, plane->state);
 }
 EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
 
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 99e2a5297c69..f4c7ed876c97 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -156,6 +156,8 @@ void __drm_atomic_helper_crtc_destroy_state(struct 
drm_crtc_state *state);
 void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
  struct drm_crtc_state *state);
 
+void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
+struct drm_plane_state *state);
 void drm_atomic_helper_plane_reset(struct drm_plane *plane);
 void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
   struct drm_plane_state *state);
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 10/10] drm/vmwgfx: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-26 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc.) to their default values.
Use that instead of duplicating the logic.

Reviewed-by: Sinclair Yeh 
Reviewed-by: Deepak Rawat 
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 4a0f0f41afa1..61824e360619 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -720,9 +720,7 @@ void vmw_du_plane_reset(struct drm_plane *plane)
return;
}
 
-   plane->state = >base;
-   plane->state->plane = plane;
-   plane->state->rotation = DRM_MODE_ROTATE_0;
+   __drm_atomic_helper_plane_reset(plane, >base);
 }
 
 
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 05/10] drm/exynos: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-26 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc.) to their default values.
Use that instead of duplicating the logic.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/exynos/exynos_drm_plane.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c 
b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index eb9915da7dec..681328fbe7de 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -139,8 +139,7 @@ static void exynos_drm_plane_reset(struct drm_plane *plane)
 
exynos_state = kzalloc(sizeof(*exynos_state), GFP_KERNEL);
if (exynos_state) {
-   plane->state = _state->base;
-   plane->state->plane = plane;
+   __drm_atomic_helper_plane_reset(plane, _state->base);
plane->state->zpos = exynos_plane->config->zpos;
}
 }
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 04/10] drm: atmel-hlcdc: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-26 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc.) to their default values.
Use that instead of duplicating the logic.

__drm_atomic_helper_plane_reset initializes the alpha property to its
max value, which is defined by the drm core as DRM_BLEND_ALPHA_OPAQUE,
so nothing changes regarding the alpha value.

Acked-by: Boris Brezillon 
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c 
b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index 04440064b9b7..9330a076e15a 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -942,10 +942,7 @@ static void atmel_hlcdc_plane_reset(struct drm_plane *p)
"Failed to allocate initial plane state\n");
return;
}
-
-   p->state = >base;
-   p->state->alpha = DRM_BLEND_ALPHA_OPAQUE;
-   p->state->plane = p;
+   __drm_atomic_helper_plane_reset(p, >base);
}
 }
 
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 02/10] drm/amd/display: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-26 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc) to their default values.
Use that instead of duplicating the logic.

Reviewed-by: Harry Wentland 
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index ae09331eed00..8e4978d5b83f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2965,11 +2965,8 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
amdgpu_state = kzalloc(sizeof(*amdgpu_state), GFP_KERNEL);
WARN_ON(amdgpu_state == NULL);

-   if (amdgpu_state) {
-   plane->state = _state->base;
-   plane->state->plane = plane;
-   plane->state->rotation = DRM_MODE_ROTATE_0;
-   }
+   if (amdgpu_state)
+   __drm_atomic_helper_plane_reset(plane, _state->base);
 }
 
 static struct drm_plane_state *
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 03/10] drm: mali-dp: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-26 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc.) to their default values.
Use that instead of duplicating the logic.

Reviewed-by: Ayan Kumar halder 
Acked-by: Liviu Dudau 
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/arm/malidp_planes.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_planes.c 
b/drivers/gpu/drm/arm/malidp_planes.c
index 29409a65d864..49c37f6dd63e 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -78,11 +78,8 @@ static void malidp_plane_reset(struct drm_plane *plane)
kfree(state);
plane->state = NULL;
state = kzalloc(sizeof(*state), GFP_KERNEL);
-   if (state) {
-   state->base.plane = plane;
-   state->base.rotation = DRM_MODE_ROTATE_0;
-   plane->state = >base;
-   }
+   if (state)
+   __drm_atomic_helper_plane_reset(plane, >base);
 }
 
 static struct
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 09/10] drm/vc4: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-26 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc.) to their default values.
Use that instead of duplicating the logic.

__drm_atomic_helper_plane_reset initializes the alpha property to its
max value, which is defined by the drm core as DRM_BLEND_ALPHA_OPAQUE,
so nothing changes regarding the alpha value.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/vc4/vc4_plane.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 9d7a36f148cf..688ad9bb0f08 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -200,9 +200,7 @@ static void vc4_plane_reset(struct drm_plane *plane)
if (!vc4_state)
return;
 
-   plane->state = _state->base;
-   plane->state->alpha = DRM_BLEND_ALPHA_OPAQUE;
-   vc4_state->base.plane = plane;
+   __drm_atomic_helper_plane_reset(plane, _state->base);
 }
 
 static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val)
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 08/10] drm/sun4i: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-26 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc.) to their default values.
Use that instead of duplicating the logic.

__drm_atomic_helper_plane_reset initializes the alpha property to its
max value, which is defined by the drm core as DRM_BLEND_ALPHA_OPAQUE,
so nothing changes regarding the alpha value.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/sun4i/sun4i_layer.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c 
b/drivers/gpu/drm/sun4i/sun4i_layer.c
index 750ad24de1d7..78f77af8805a 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -35,9 +35,7 @@ static void sun4i_backend_layer_reset(struct drm_plane *plane)
 
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (state) {
-   plane->state = >state;
-   plane->state->plane = plane;
-   plane->state->alpha = DRM_BLEND_ALPHA_OPAQUE;
+   __drm_atomic_helper_plane_reset(plane, >state);
plane->state->zpos = layer->id;
}
 }
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 07/10] drm: rcar-du: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-26 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc.) to their default values.
Use that instead of duplicating the logic.

__drm_atomic_helper_plane_reset initializes the alpha property to its
max value, which is defined by the drm core as DRM_BLEND_ALPHA_OPAQUE,
so nothing changes regarding the alpha value.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +---
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c   | 4 +---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c 
b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index c20f7ed48c8d..19a9d5f6db1c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -689,15 +689,13 @@ static void rcar_du_plane_reset(struct drm_plane *plane)
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (state == NULL)
return;
+   __drm_atomic_helper_plane_reset(plane, >state);
 
state->hwindex = -1;
state->source = RCAR_DU_PLANE_MEMORY;
state->colorkey = RCAR_DU_COLORKEY_NONE;
state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
 
-   plane->state = >state;
-   plane->state->alpha = DRM_BLEND_ALPHA_OPAQUE;
-   plane->state->plane = plane;
 }
 
 static int rcar_du_plane_atomic_set_property(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c 
b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index 72eebeda518e..0a0aa490f805 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -346,11 +346,9 @@ static void rcar_du_vsp_plane_reset(struct drm_plane 
*plane)
if (state == NULL)
return;
 
-   state->state.alpha = DRM_BLEND_ALPHA_OPAQUE;
+   __drm_atomic_helper_plane_reset(plane, >state);
state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
 
-   plane->state = >state;
-   plane->state->plane = plane;
 }
 
 static const struct drm_plane_funcs rcar_du_vsp_plane_funcs = {
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 06/10] drm/imx: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-26 Thread Alexandru Gheorghe
A new helper function(__drm_atomic_helper_plane_reset) has been added
for linking a plane with its state and resetting the core
properties(alpha, rotation, etc.) to their default values.
Use that instead of duplicating the logic.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/imx/ipuv3-plane.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c 
b/drivers/gpu/drm/imx/ipuv3-plane.c
index 203f247d4854..1bd4de03ce9e 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -281,16 +281,14 @@ static void ipu_plane_state_reset(struct drm_plane *plane)
ipu_state = to_ipu_plane_state(plane->state);
__drm_atomic_helper_plane_destroy_state(plane->state);
kfree(ipu_state);
+   plane->state = NULL;
}
 
ipu_state = kzalloc(sizeof(*ipu_state), GFP_KERNEL);
 
-   if (ipu_state) {
-   ipu_state->base.plane = plane;
-   ipu_state->base.rotation = DRM_MODE_ROTATE_0;
-   }
+   if (ipu_state)
+   __drm_atomic_helper_plane_reset(plane, _state->base);
 
-   plane->state = _state->base;
 }
 
 static struct drm_plane_state *
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 00/10] Add helper for plane reset

2018-07-26 Thread Alexandru Gheorghe
Changes since v1: 
 - Make __drm_atomic_helper_plane_reset consistent with the other
   helpers and require that both plane and state not be NULL,
   suggested by Boris Brezillon and Philipp Zabel. Drivers already
   check for that.
 - Add a proper commit message for driver changes.

Drivers that subclass drm_plane need to copy the logic for linking the
drm_plane with its state and to initialize core properties to their
default values. E.g (alpha and rotation)

Having a helper to reset the plane_state makes sense because of multiple
reasons:
1. Eliminate code duplication.
2. Add a single place for initializing core properties to their
default values, no need for driver to do it if what the helper sets
makes sense for them.
3. No need to debug the driver when you enable a core property and
observe it doesn't have a proper default value.

Tested with mali-dp the other drivers are just built-tested.


Alexandru Gheorghe (10):
  drm/atomic: Add  __drm_atomic_helper_plane_reset
  drm/amd/display: Use __drm_atomic_helper_plane_reset instead of
copying the logic
  drm: mali-dp: Use __drm_atomic_helper_plane_reset instead of copying
the logic
  drm: atmel-hlcdc: Use __drm_atomic_helper_plane_reset instead of
copying the logic
  drm/exynos: Use __drm_atomic_helper_plane_reset instead of copying the
logic
  drm/imx: Use __drm_atomic_helper_plane_reset instead of copying the
logic
  drm: rcar-du: Use __drm_atomic_helper_plane_reset instead of copying
the logic
  drm/sun4i: Use __drm_atomic_helper_plane_reset instead of copying the
logic
  drm/vc4: Use __drm_atomic_helper_plane_reset instead of copying the
logic
  drm/vmwgfx: Use __drm_atomic_helper_plane_reset instead of copying the
logic

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  7 ++---
 drivers/gpu/drm/arm/malidp_planes.c   |  7 ++---
 .../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c   |  5 +--
 drivers/gpu/drm/drm_atomic_helper.c   | 31 +--
 drivers/gpu/drm/exynos/exynos_drm_plane.c |  3 +-
 drivers/gpu/drm/imx/ipuv3-plane.c |  8 ++---
 drivers/gpu/drm/rcar-du/rcar_du_plane.c   |  4 +--
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c |  4 +--
 drivers/gpu/drm/sun4i/sun4i_layer.c   |  4 +--
 drivers/gpu/drm/vc4/vc4_plane.c   |  4 +--
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c   |  4 +--
 include/drm/drm_atomic_helper.h   |  2 ++
 12 files changed, 38 insertions(+), 45 deletions(-)

-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 2/3] drm: Make drm_gem_fb_alloc available for drivers to use

2018-07-26 Thread Alexandru Gheorghe
Some drivers can't use drm_gem_fb_create, so instead of copying the
logic that does the framebuffer allocation allow them to use core
drm_gem_fb_alloc.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_gem_framebuffer_helper.c | 3 ++-
 include/drm/drm_gem_framebuffer_helper.h | 5 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index 2810d4131411..64eddf5a1bd9 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -57,7 +57,7 @@ struct drm_gem_object *drm_gem_fb_get_obj(struct 
drm_framebuffer *fb,
 }
 EXPORT_SYMBOL_GPL(drm_gem_fb_get_obj);
 
-static struct drm_framebuffer *
+struct drm_framebuffer *
 drm_gem_fb_alloc(struct drm_device *dev,
 const struct drm_mode_fb_cmd2 *mode_cmd,
 struct drm_gem_object **obj, unsigned int num_planes,
@@ -85,6 +85,7 @@ drm_gem_fb_alloc(struct drm_device *dev,
 
return fb;
 }
+EXPORT_SYMBOL_GPL(drm_gem_fb_alloc);
 
 /**
  * drm_gem_fb_destroy - Free GEM backed framebuffer
diff --git a/include/drm/drm_gem_framebuffer_helper.h 
b/include/drm/drm_gem_framebuffer_helper.h
index a38de7eb55b4..d20c1356000a 100644
--- a/include/drm/drm_gem_framebuffer_helper.h
+++ b/include/drm/drm_gem_framebuffer_helper.h
@@ -14,6 +14,11 @@ struct drm_simple_display_pipe;
 
 struct drm_gem_object *drm_gem_fb_get_obj(struct drm_framebuffer *fb,
  unsigned int plane);
+struct drm_framebuffer *
+drm_gem_fb_alloc(struct drm_device *dev,
+const struct drm_mode_fb_cmd2 *mode_cmd,
+struct drm_gem_object **obj, unsigned int num_planes,
+const struct drm_framebuffer_funcs *funcs);
 void drm_gem_fb_destroy(struct drm_framebuffer *fb);
 int drm_gem_fb_create_handle(struct drm_framebuffer *fb, struct drm_file *file,
 unsigned int *handle);
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/3] drm/fourcc: Add malidp yuv formats

2018-07-26 Thread Alexandru Gheorghe
Malidp implements a number of yuv buffer formats which are not
currently described in drm_fourcc.h.
This adds those definitions and describes their memory layout.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_fourcc.c  |  7 +++
 include/uapi/drm/drm_fourcc.h | 27 ++-
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 35c1e2742c27..18bb960e9943 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -173,6 +173,13 @@ const struct drm_format_info *__drm_format_info(u32 format)
{ .format = DRM_FORMAT_UYVY,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_VYUY,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_AYUV,.depth = 0,  
.num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, 
.is_yuv = true },
+   { .format = DRM_FORMAT_XYUV,.depth = 0,  
.num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
+   { .format = DRM_FORMAT_XVYU2101010, .depth = 0,  
.num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
+   { .format = DRM_FORMAT_Y0L0,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 2, .has_alpha = true, 
.is_yuv = true },
+   { .format = DRM_FORMAT_X0L0,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true },
+   { .format = DRM_FORMAT_Y0L2,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 2, .has_alpha = true, 
.is_yuv = true },
+   { .format = DRM_FORMAT_X0L2,.depth = 0,  
.num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true },
+   { .format = DRM_FORMAT_P010,.depth = 0,  
.num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 2, .is_yuv  = true },
};
 
unsigned int i;
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index d43949b5bb3e..ba2fd9e9815d 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -105,13 +105,31 @@ extern "C" {
 #define DRM_FORMAT_RGBA1010102 fourcc_code('R', 'A', '3', '0') /* [31:0] 
R:G:B:A 10:10:10:2 little endian */
 #define DRM_FORMAT_BGRA1010102 fourcc_code('B', 'A', '3', '0') /* [31:0] 
B:G:R:A 10:10:10:2 little endian */
 
-/* packed YCbCr */
+/* packed YCbCr422 */
 #define DRM_FORMAT_YUYVfourcc_code('Y', 'U', 'Y', 'V') /* 
[31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */
 #define DRM_FORMAT_YVYUfourcc_code('Y', 'V', 'Y', 'U') /* 
[31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */
 #define DRM_FORMAT_UYVYfourcc_code('U', 'Y', 'V', 'Y') /* 
[31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian */
 #define DRM_FORMAT_VYUYfourcc_code('V', 'Y', 'U', 'Y') /* 
[31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */
 
+/* packed YCbCr444 */
 #define DRM_FORMAT_AYUVfourcc_code('A', 'Y', 'U', 'V') /* 
[31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
+#define DRM_FORMAT_XYUVfourcc_code('X', 'Y', 'U', 'V') /* [31:0] 
X:Y:Cb:Cr 8:8:8:8 little endian */
+#define DRM_FORMAT_XVYU2101010 fourcc_code('V', 'U', '3', '0') /* [31:0] 
X:Cr:Y:Cb 2:10:10:10 little endian */
+
+/*
+ * packed YCbCr420 2x2 tiled formats
+ * first 64 bits will contain Y,Cb,Cr components for a 2x2 tile
+ */
+
+/* [63:0]   A3:A2:Y3:0:Cr0:0:Y2:0:A1:A0:Y1:0:Cb0:0:Y0:0  
1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian */
+#define DRM_FORMAT_Y0L0fourcc_code('Y', '0', 'L', '0')
+/* [63:0]   X3:X2:Y3:0:Cr0:0:Y2:0:X1:X0:Y1:0:Cb0:0:Y0:0  
1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian */
+#define DRM_FORMAT_X0L0fourcc_code('X', '0', 'L', '0')
+
+/* [63:0]   A3:A2:Y3:Cr0:Y2:A1:A0:Y1:Cb0:Y0  1:1:10:10:10:1:1:10:10:10 little 
endian */
+#define DRM_FORMAT_Y0L2fourcc_code('Y', '0', 'L', '2')
+/* [63:0]   X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0  1:1:10:10:10:1:1:10:10:10 little 
endian */
+#define DRM_FORMAT_X0L2fourcc_code('X', '0', 'L', '2')
 
 /*
  * 2 plane RGB + A
@@ -141,6 +159,13 @@ extern "C" {
 #define DRM_FORMAT_NV24fourcc_code('N', 'V', '2', '4') /* 
non-subsampled Cr:Cb plane */
 #define DRM_FORMAT_NV42fourcc_code('N', 'V', '4', '2') /* 
non-subsampled Cb:Cr plane */
 
+/*
+ * Each sample packed into the top 10 bits of a 16-bit word.
+ * Y plane: [63:0] Y3:0:Y2:0:Y1:0:Y0:0, 10:6:10:6:10:6:10:6
+ * CrCb plane: [63:0] Cr2:0:Cb2:0:Cr0:0:Cb0:0, 10:6:10:6:10:6:10:6
+ */
+#define DRM_FORMAT_P010fourcc_code('P', '0', '1', '0') /* 2x2 
subsampled Cr:Cb plane */
+
 /*
  * 3 plane YCbCr
  * index 0: Y plane

[PATCH 3/3] drm: mali-dp: Enable mali specific buffer formats

2018-07-26 Thread Alexandru Gheorghe
Enable the following formats
 - DRM_FORMAT_XYUV
 - DRM_FORMAT_XVYU2101010
 - DRM_FORMAT_X0L0
 - DRM_FORMAT_X0L2
 - DRM_FORMAT_P010

All formats respect the rules checked by core framebuffer_check except
DRM_FORMAT_X0L0 and DRM_FORMAT_X0L2 for which we neeed to take into
consideration that it's a 2x2 tiled format, so the following things
need special handling:

1) PITCH: needs to cover two rows.
2) GEM_SIZE: the core formula (drm_gem_fb_create_with_funcs) that
checks min_object size doesn't work anymore, so I added special check
in driver for X0L0 and X0L2.
3) SOURCE_CROPPING: drm_fb_cma_get_gem_addr doesn't properly retrieves
start address, so I added the right formula for DRM_FORMAT_X0L0 and
DRM_FORMAT_X0L2 inside the driver.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/arm/malidp_drv.c| 65 -
 drivers/gpu/drm/arm/malidp_hw.c |  7 +++-
 drivers/gpu/drm/arm/malidp_planes.c | 52 +++
 3 files changed, 114 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 5b7260557391..6745c4639dd4 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -258,8 +258,71 @@ static const struct drm_mode_config_helper_funcs 
malidp_mode_config_helpers = {
.atomic_commit_tail = malidp_atomic_commit_tail,
 };
 
+static const struct drm_framebuffer_funcs malidp_gem_fb_funcs = {
+   .destroy= drm_gem_fb_destroy,
+   .create_handle  = drm_gem_fb_create_handle,
+};
+
+struct drm_framebuffer *
+malidp_fb_create(struct drm_device *dev, struct drm_file *file,
+const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+   if (mode_cmd->pixel_format == DRM_FORMAT_X0L2 ||
+   mode_cmd->pixel_format == DRM_FORMAT_X0L0) {
+   const struct drm_format_info *info;
+   struct drm_gem_object *obj;
+   struct drm_framebuffer *fb = NULL;
+   const unsigned int tile_size = 2;
+   unsigned int min_size;
+
+   info = drm_format_info(mode_cmd->pixel_format &
+   ~DRM_FORMAT_BIG_ENDIAN);
+   /*
+* Pitch needs to take into consideration that we are dealing
+* with a tiled 2x2 format, so the pitch/stride need to cover
+* both rows
+*/
+   if (mode_cmd->pitches[0] < mode_cmd->width * info->cpp[0] *
+   tile_size) {
+   struct drm_format_name_buf format_name;
+
+   drm_get_format_name(mode_cmd->pixel_format,
+   _name);
+   DRM_DEBUG_KMS("Invalid pitch for format %s",
+ format_name.str);
+   return ERR_PTR(-EINVAL);
+   }
+   obj = drm_gem_object_lookup(file, mode_cmd->handles[0]);
+   if (!obj) {
+   DRM_DEBUG_KMS("Failed to lookup GEM object\n");
+   fb = ERR_PTR(-ENOENT);
+   goto err_gem_object_put;
+   }
+   min_size = mode_cmd->height / tile_size  * mode_cmd->pitches[0];
+   if (obj->size < min_size) {
+   drm_gem_object_put_unlocked(obj);
+   DRM_DEBUG_KMS("Object size is less than minimum"
+ " required\n");
+   fb = ERR_PTR(-EINVAL);
+   goto err_gem_object_put;
+   }
+
+   fb = drm_gem_fb_alloc(dev, mode_cmd, , 1,
+ _gem_fb_funcs);
+   if (IS_ERR(fb))
+   goto err_gem_object_put;
+   return fb;
+
+   err_gem_object_put:
+   drm_gem_object_put_unlocked(obj);
+   return fb;
+   }
+
+   return drm_gem_fb_create(dev, file, mode_cmd);
+}
+
 static const struct drm_mode_config_funcs malidp_mode_config_funcs = {
-   .fb_create = drm_gem_fb_create,
+   .fb_create = malidp_fb_create,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index c94a4422e0e9..472cae76e19b 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -74,10 +74,15 @@ static const struct malidp_format_id malidp500_de_formats[] 
= {
{ DRM_FORMAT_ABGR1555, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, 
MALIDP_ID(4, 1) }, \
{ DRM_FORMAT_RGB565, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, MALIDP_ID(4, 
2) }, \
{ DRM_FORMAT_BGR565, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, MALIDP_ID(4, 
3) }, \
+   { DRM_FOR

[PATCH 0/3] Add Mali DP pixel formats

2018-07-26 Thread Alexandru Gheorghe
Mali DP supports a bunch of pixel formats that don't have a fourcc
code defined in drm_fourcc.h, so this patchset adds the definition for
those formats and enables them in mali-dp driver.

The following new formats will be added:

Packed YCbCr444
* DRM_FORMAT_XYUV
* DRM_FORMAT_XVYU2101010

Two plane 10 bits format.
* DRM_FORMAT_P010

Packed YCbCr420 2x2 tiled formats
* DRM_FORMAT_Y0L0
* DRM_FORMAT_X0L0
* DRM_FORMAT_Y0L2
* DRM_FORMAT_X0L2
The difference between X0L0/X0L2 vs Y0L0/Y0L2 is that the later group
have two alpha bits per pixel.

This group is a bit special because we are dealing with a tiled format
where the first 64 bits in memory represent the pixels for a 2x2 tile,
so it needs a bit of special handling when it comes to:
 - pitch: needs to cover both rows that are in the same tile.
 - min allocation size: since a pitch cover both rows the formulas
   defined in drm_gem_fb_create don't work anymore.
 - handling of src_x and src_y offset: same as above since we are
   dealing with a tiled format drm_fb_cma_get_gem_obj doesn't return
   the correct address offset.

So, for this formats mali-dp needs a special implementation of
drm_fb_cma_get_gem_obj and drm_fb_cma_get_gem_addr which are more or
less clones of the core functions, except they take into account the
tile_size.

Other alternatives would be:
  1) Add a tile_size to drm_format_info and plumb the drm_core
 functions to proper handle this special formats.
  2) Add a driver hook that checks buffer min_size and avoid
 duplicating the code from drm_gem_fb_create_with_funcs.

If you have an opinion about how this should be handled feel free to
suggest it.

Alexandru Gheorghe (3):
  drm/fourcc: Add malidp yuv formats
  drm: Make drm_gem_fb_alloc available for drivers to use
  drm: mali-dp: Enable mali specific buffer formats

 drivers/gpu/drm/arm/malidp_drv.c | 65 +++-
 drivers/gpu/drm/arm/malidp_hw.c  |  7 ++-
 drivers/gpu/drm/arm/malidp_planes.c  | 52 +---
 drivers/gpu/drm/drm_fourcc.c |  7 +++
 drivers/gpu/drm/drm_gem_framebuffer_helper.c |  3 +-
 include/drm/drm_gem_framebuffer_helper.h |  5 ++
 include/uapi/drm/drm_fourcc.h| 27 +++-
 7 files changed, 154 insertions(+), 12 deletions(-)

-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 10/10] drm/vmwgfx: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-20 Thread Alexandru Gheorghe
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 466336b34fff..1e0fb3c79b50 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -720,9 +720,7 @@ void vmw_du_plane_reset(struct drm_plane *plane)
return;
}
 
-   plane->state = >base;
-   plane->state->plane = plane;
-   plane->state->rotation = DRM_MODE_ROTATE_0;
+   __drm_atomic_helper_plane_reset(plane, >base);
 }
 
 
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 06/10] drm/imx: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-20 Thread Alexandru Gheorghe
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/imx/ipuv3-plane.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c 
b/drivers/gpu/drm/imx/ipuv3-plane.c
index 203f247d4854..1bd4de03ce9e 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -281,16 +281,14 @@ static void ipu_plane_state_reset(struct drm_plane *plane)
ipu_state = to_ipu_plane_state(plane->state);
__drm_atomic_helper_plane_destroy_state(plane->state);
kfree(ipu_state);
+   plane->state = NULL;
}
 
ipu_state = kzalloc(sizeof(*ipu_state), GFP_KERNEL);
 
-   if (ipu_state) {
-   ipu_state->base.plane = plane;
-   ipu_state->base.rotation = DRM_MODE_ROTATE_0;
-   }
+   if (ipu_state)
+   __drm_atomic_helper_plane_reset(plane, _state->base);
 
-   plane->state = _state->base;
 }
 
 static struct drm_plane_state *
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 08/10] drm/sun4i: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-20 Thread Alexandru Gheorghe
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/sun4i/sun4i_layer.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c 
b/drivers/gpu/drm/sun4i/sun4i_layer.c
index 750ad24de1d7..78f77af8805a 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -35,9 +35,7 @@ static void sun4i_backend_layer_reset(struct drm_plane *plane)
 
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (state) {
-   plane->state = >state;
-   plane->state->plane = plane;
-   plane->state->alpha = DRM_BLEND_ALPHA_OPAQUE;
+   __drm_atomic_helper_plane_reset(plane, >state);
plane->state->zpos = layer->id;
}
 }
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 09/10] drm/vc4: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-20 Thread Alexandru Gheorghe
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/vc4/vc4_plane.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 9d7a36f148cf..688ad9bb0f08 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -200,9 +200,7 @@ static void vc4_plane_reset(struct drm_plane *plane)
if (!vc4_state)
return;
 
-   plane->state = _state->base;
-   plane->state->alpha = DRM_BLEND_ALPHA_OPAQUE;
-   vc4_state->base.plane = plane;
+   __drm_atomic_helper_plane_reset(plane, _state->base);
 }
 
 static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val)
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 07/10] drm: rcar-du: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-20 Thread Alexandru Gheorghe
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +---
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c   | 4 +---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c 
b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index c20f7ed48c8d..19a9d5f6db1c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -689,15 +689,13 @@ static void rcar_du_plane_reset(struct drm_plane *plane)
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (state == NULL)
return;
+   __drm_atomic_helper_plane_reset(plane, >state);
 
state->hwindex = -1;
state->source = RCAR_DU_PLANE_MEMORY;
state->colorkey = RCAR_DU_COLORKEY_NONE;
state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
 
-   plane->state = >state;
-   plane->state->alpha = DRM_BLEND_ALPHA_OPAQUE;
-   plane->state->plane = plane;
 }
 
 static int rcar_du_plane_atomic_set_property(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c 
b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index 72eebeda518e..0a0aa490f805 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -346,11 +346,9 @@ static void rcar_du_vsp_plane_reset(struct drm_plane 
*plane)
if (state == NULL)
return;
 
-   state->state.alpha = DRM_BLEND_ALPHA_OPAQUE;
+   __drm_atomic_helper_plane_reset(plane, >state);
state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
 
-   plane->state = >state;
-   plane->state->plane = plane;
 }
 
 static const struct drm_plane_funcs rcar_du_vsp_plane_funcs = {
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 05/10] drm/exynos: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-20 Thread Alexandru Gheorghe
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/exynos/exynos_drm_plane.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c 
b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index eb9915da7dec..681328fbe7de 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -139,8 +139,7 @@ static void exynos_drm_plane_reset(struct drm_plane *plane)
 
exynos_state = kzalloc(sizeof(*exynos_state), GFP_KERNEL);
if (exynos_state) {
-   plane->state = _state->base;
-   plane->state->plane = plane;
+   __drm_atomic_helper_plane_reset(plane, _state->base);
plane->state->zpos = exynos_plane->config->zpos;
}
 }
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 03/10] drm: mali-dp: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-20 Thread Alexandru Gheorghe
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/arm/malidp_planes.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_planes.c 
b/drivers/gpu/drm/arm/malidp_planes.c
index 29409a65d864..49c37f6dd63e 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -78,11 +78,8 @@ static void malidp_plane_reset(struct drm_plane *plane)
kfree(state);
plane->state = NULL;
state = kzalloc(sizeof(*state), GFP_KERNEL);
-   if (state) {
-   state->base.plane = plane;
-   state->base.rotation = DRM_MODE_ROTATE_0;
-   plane->state = >base;
-   }
+   if (state)
+   __drm_atomic_helper_plane_reset(plane, >base);
 }
 
 static struct
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 01/10] drm/atomic: Add __drm_atomic_helper_plane_reset

2018-07-20 Thread Alexandru Gheorghe
There are a lot of drivers that subclass drm_plane_state, all of them
duplicate the code that links toghether the plane with plane_state.

On top of that, drivers that enable core properties also have to
duplicate the code for initializing the properties to their default
values, which in all cases are the same as the defaults from core.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_atomic_helper.c | 32 +
 include/drm/drm_atomic_helper.h |  2 ++
 2 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 8008a7de2e10..e1c6f101652e 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3507,6 +3507,28 @@ void drm_atomic_helper_crtc_destroy_state(struct 
drm_crtc *crtc,
 }
 EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
 
+/**
+ * __drm_atomic_helper_plane_reset - resets planes state to default values
+ * @plane: plane object
+ * @new_state: atomic plane state
+ *
+ * Initializes plane state to default. This is useful for drivers that subclass
+ * the plane state.
+ */
+void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
+struct drm_plane_state *state)
+{
+   if (state) {
+   state->plane = plane;
+   state->rotation = DRM_MODE_ROTATE_0;
+   /* Reset the alpha value to fully opaque if it matters */
+   if (plane->alpha_property)
+   state->alpha = plane->alpha_property->values[1];
+   }
+   plane->state = state;
+}
+EXPORT_SYMBOL(__drm_atomic_helper_plane_reset);
+
 /**
  * drm_atomic_helper_plane_reset - default _plane_funcs.reset hook for 
planes
  * @plane: drm plane
@@ -3521,15 +3543,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane 
*plane)
 
kfree(plane->state);
plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
-
-   if (plane->state) {
-   plane->state->plane = plane;
-   plane->state->rotation = DRM_MODE_ROTATE_0;
-
-   /* Reset the alpha value to fully opaque if it matters */
-   if (plane->alpha_property)
-   plane->state->alpha = plane->alpha_property->values[1];
-   }
+   __drm_atomic_helper_plane_reset(plane, plane->state);
 }
 EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
 
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 26aaba58d6ce..2dd40c761dfd 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -155,6 +155,8 @@ void __drm_atomic_helper_crtc_destroy_state(struct 
drm_crtc_state *state);
 void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
  struct drm_crtc_state *state);
 
+void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
+struct drm_plane_state *state);
 void drm_atomic_helper_plane_reset(struct drm_plane *plane);
 void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
   struct drm_plane_state *state);
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 00/10] Add helper for plane reset

2018-07-20 Thread Alexandru Gheorghe
Drivers that subclass drm_plane need to copy the logic for linking the
drm_plane with its state and to initialize core properties to their
default values. E.g (alpha and rotation)

Having a helper to reset the plane_state makes sense because of multiple
reasons:
1. Eliminate code duplication.
2. Add a single place for initializing core properties to their
default values, no need for driver to do it if what the helper sets
makes sense for them.
3. No need to debug the driver when you enable a core property and
observe it doesn't have a proper default value.

Tested with mali-dp the other drivers are just built-tested.


Alexandru Gheorghe (10):
  drm/atomic: Add  __drm_atomic_helper_plane_reset
  drm/amd/display: Use __drm_atomic_helper_plane_reset instead of
copying the logic
  drm: mali-dp: Use __drm_atomic_helper_plane_reset instead of copying
the logic
  drm: atmel-hlcdc: Use __drm_atomic_helper_plane_reset instead of
copying the logic
  drm/exynos: Use __drm_atomic_helper_plane_reset instead of copying the
logic
  drm/imx: Use __drm_atomic_helper_plane_reset instead of copying the
logic
  drm: rcar-du: Use __drm_atomic_helper_plane_reset instead of copying
the logic
  drm/sun4i: Use __drm_atomic_helper_plane_reset instead of copying the
logic
  drm/vc4: Use __drm_atomic_helper_plane_reset instead of copying the
logic
  drm/vmwgfx: Use __drm_atomic_helper_plane_reset instead of copying the
logic

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  7 ++--
 drivers/gpu/drm/arm/malidp_planes.c   |  7 ++--
 .../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c   |  5 +--
 drivers/gpu/drm/drm_atomic_helper.c   | 32 +--
 drivers/gpu/drm/exynos/exynos_drm_plane.c |  3 +-
 drivers/gpu/drm/imx/ipuv3-plane.c |  8 ++---
 drivers/gpu/drm/rcar-du/rcar_du_plane.c   |  4 +--
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c |  4 +--
 drivers/gpu/drm/sun4i/sun4i_layer.c   |  4 +--
 drivers/gpu/drm/vc4/vc4_plane.c   |  4 +--
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c   |  4 +--
 include/drm/drm_atomic_helper.h   |  2 ++
 12 files changed, 39 insertions(+), 45 deletions(-)

-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 02/10] drm/amd/display: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-20 Thread Alexandru Gheorghe
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index ca017c1dd4da..c08157686782 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3013,11 +3013,8 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
amdgpu_state = kzalloc(sizeof(*amdgpu_state), GFP_KERNEL);
WARN_ON(amdgpu_state == NULL);

-   if (amdgpu_state) {
-   plane->state = _state->base;
-   plane->state->plane = plane;
-   plane->state->rotation = DRM_MODE_ROTATE_0;
-   }
+   if (amdgpu_state)
+   __drm_atomic_helper_plane_reset(plane, _state->base);
 }
 
 static struct drm_plane_state *
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 04/10] drm: atmel-hlcdc: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-07-20 Thread Alexandru Gheorghe
Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c 
b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index 04440064b9b7..9330a076e15a 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -942,10 +942,7 @@ static void atmel_hlcdc_plane_reset(struct drm_plane *p)
"Failed to allocate initial plane state\n");
return;
}
-
-   p->state = >base;
-   p->state->alpha = DRM_BLEND_ALPHA_OPAQUE;
-   p->state->plane = p;
+   __drm_atomic_helper_plane_reset(p, >base);
}
 }
 
-- 
2.18.0

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm: mali-dp: Call drm_crtc_vblank_reset on device init

2018-07-16 Thread Alexandru Gheorghe
Currently, if userspace calls drm_wait_vblank before the crtc is
activated the crtc vblank_enable hook is called, which in case of
malidp driver triggers some warninngs. This happens because on
device init we don't inform the drm core about the vblank state
by calling drm_crtc_vblank_on/off/reset which together with
drm_vblank_get have some magic that prevents calling drm_vblank_enable
when crtc is off.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/arm/malidp_drv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 4169a72..641d743 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -755,6 +755,7 @@ static int malidp_bind(struct device *dev)
drm->irq_enabled = true;
 
ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
+   drm_crtc_vblank_reset(>crtc);
if (ret < 0) {
DRM_ERROR("failed to initialise vblank\n");
goto vblank_fail;
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3] drm: mali-dp: Set encoder possible_clones

2018-07-16 Thread Alexandru Gheorghe
Set possible_clones field to report that the writeback connector and
the one driving the display could be enabled at the same time.

Signed-off-by: Alexandru Gheorghe 

Changes since v2:
  - Use proper style for multi-line comments.
---
 drivers/gpu/drm/arm/malidp_drv.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 5b72605..4169a72 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -616,6 +616,7 @@ static int malidp_bind(struct device *dev)
struct malidp_hw_device *hwdev;
struct platform_device *pdev = to_platform_device(dev);
struct of_device_id const *dev_id;
+   struct drm_encoder *encoder;
/* number of lines for the R, G and B output */
u8 output_width[MAX_OUTPUT_CHANNELS];
int ret = 0, i;
@@ -737,6 +738,16 @@ static int malidp_bind(struct device *dev)
goto bind_fail;
}
 
+   /*
+* We expect to have a maximum of two encoders one for the actual
+* display and a virtual one for the writeback connector
+*/
+   WARN_ON(drm->mode_config.num_encoder > 2);
+   list_for_each_entry(encoder, >mode_config.encoder_list, head) {
+   encoder->possible_clones =
+   (1 << drm->mode_config.num_encoder) -  1;
+   }
+
ret = malidp_irq_init(pdev);
if (ret < 0)
goto irq_init_fail;
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 3/3] drm: mali-dp: Set encoder possible_clones

2018-07-13 Thread Alexandru Gheorghe
Set possible_clones field to report that the writeback connector and
the one driving the display could be enabled at the same time.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/arm/malidp_drv.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 5b72605..08b5bb2 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -616,6 +616,7 @@ static int malidp_bind(struct device *dev)
struct malidp_hw_device *hwdev;
struct platform_device *pdev = to_platform_device(dev);
struct of_device_id const *dev_id;
+   struct drm_encoder *encoder;
/* number of lines for the R, G and B output */
u8 output_width[MAX_OUTPUT_CHANNELS];
int ret = 0, i;
@@ -737,6 +738,15 @@ static int malidp_bind(struct device *dev)
goto bind_fail;
}
 
+   /* We expect to have a maximum of two encoders one for the actual
+* display and a virtual one for the writeback connector
+*/
+   WARN_ON(drm->mode_config.num_encoder > 2);
+   list_for_each_entry(encoder, >mode_config.encoder_list, head) {
+   encoder->possible_clones =
+   (1 << drm->mode_config.num_encoder) -  1;
+   }
+
ret = malidp_irq_init(pdev);
if (ret < 0)
goto irq_init_fail;
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 1/3] drm: writeback: Fix doc that says connector should be disconnected

2018-07-13 Thread Alexandru Gheorghe
During iteration process one of the proposed mechanism for not
breaking existing userspace was to report writeback connectors as
disconnected, however the final version used
DRM_CLIENT_CAP_WRITEBACK_CONNECTORS for that purpose.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_writeback.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c
index 8273950..e7b6e5e 100644
--- a/drivers/gpu/drm/drm_writeback.c
+++ b/drivers/gpu/drm/drm_writeback.c
@@ -23,8 +23,8 @@
  * from a CRTC to a memory buffer. They are used and act similarly to other
  * types of connectors, with some important differences:
  *  - Writeback connectors don't provide a way to output visually to the user.
- *  - Writeback connectors should always report as "disconnected" (so that
- *clients which don't understand them will ignore them).
+ *  - Writeback connectors are visible to userspace only when the client sets
+ *DRM_CLIENT_CAP_WRITEBACK_CONNECTORS.
  *  - Writeback connectors don't have EDID.
  *
  * A framebuffer may only be attached to a writeback connector when the
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 2/3] drm: mali-dp: Report writeback connector as connected

2018-07-13 Thread Alexandru Gheorghe
Older version of this patch series reported writeback as disconnected
to avoid confusing userspace not aware of writeback connectors.
However, the version that got merged uses a special cap
(DRM_CLIENT_CAP_WRITEBACK_CONNECTORS) for this purpose.

This helps us avoid some special handling of writeback connector
in drm_helper_probe_single_connector_modes, see [1].

https://lists.freedesktop.org/archives/dri-devel/2018-July/183144.html

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/arm/malidp_mw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c
index cfd718e..ba6ae66 100644
--- a/drivers/gpu/drm/arm/malidp_mw.c
+++ b/drivers/gpu/drm/arm/malidp_mw.c
@@ -73,7 +73,7 @@ static void malidp_mw_connector_reset(struct drm_connector 
*connector)
 static enum drm_connector_status
 malidp_mw_connector_detect(struct drm_connector *connector, bool force)
 {
-   return connector_status_disconnected;
+   return connector_status_connected;
 }
 
 static void malidp_mw_connector_destroy(struct drm_connector *connector)
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm: mali-dp: Set encoder possible_clones

2018-07-12 Thread Alexandru Gheorghe
Set possible_clones field to report that the writeback connector and
the one driving the display could be enabled at the same time.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/arm/malidp_drv.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 5b72605..3664da9 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -616,6 +616,8 @@ static int malidp_bind(struct device *dev)
struct malidp_hw_device *hwdev;
struct platform_device *pdev = to_platform_device(dev);
struct of_device_id const *dev_id;
+   struct drm_encoder *encoder;
+   int num_encoders = 0;
/* number of lines for the R, G and B output */
u8 output_width[MAX_OUTPUT_CHANNELS];
int ret = 0, i;
@@ -737,6 +739,14 @@ static int malidp_bind(struct device *dev)
goto bind_fail;
}
 
+   list_for_each_entry(encoder, >mode_config.encoder_list, head) {
+   num_encoders++;
+   }
+
+   list_for_each_entry(encoder, >mode_config.encoder_list, head) {
+   encoder->possible_clones = (1 << num_encoders) -  1;
+   }
+
ret = malidp_irq_init(pdev);
if (ret < 0)
goto irq_init_fail;
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/probe-helper: Fix modes reporting for writeback connector

2018-07-12 Thread Alexandru Gheorghe
Writeback connector is reported as disconnected, currently this causes
the setting of the edid property to null and then exit.
In order to properly get the modes for writeback we need to add an
exception when connector type is DRM_MODE_CONNECTOR_WRITEBACK.

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_probe_helper.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_probe_helper.c 
b/drivers/gpu/drm/drm_probe_helper.c
index 52774339..c7bdbe2 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -472,7 +472,8 @@ int drm_helper_probe_single_connector_modes(struct 
drm_connector *connector,
 
dev->mode_config.poll_running = drm_kms_helper_poll;
 
-   if (connector->status == connector_status_disconnected) {
+   if (connector->status == connector_status_disconnected &&
+   connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) {
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
connector->base.id, connector->name);
drm_mode_connector_update_edid_property(connector, NULL);
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/atomic: Set current atomic state in drm_private_state

2018-05-30 Thread Alexandru Gheorghe
drm_private_state has a back pointer to the drm_atomic_state,
however that was not initialized in drm_atomic_get_private_obj_state
after duplication, as it is the case for other drm atomic getters

Signed-off-by: Alexandru Gheorghe 
---
 drivers/gpu/drm/drm_atomic.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 7d25c42..249aaf8 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1108,6 +1108,7 @@ drm_atomic_get_private_obj_state(struct drm_atomic_state 
*state,
state->private_objs[index].old_state = obj->state;
state->private_objs[index].new_state = obj_state;
state->private_objs[index].ptr = obj;
+   obj_state->state = state;
 
state->num_private_objs = num_objs;
 
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2] drm: mali-dp: Add debugfs file for reporting internal errors

2018-05-15 Thread Alexandru Gheorghe
Status register contains a lot of bits for reporting internal errors
inside Mali DP. Currently, we just silently ignore all of the errors,
that doesn't help when we are investigating different bugs, especially
on the FPGA models which have a lot of constraints, so we could easily
end up in AXI or underrun errors.

Add a new file called debug that contains an aggregate of the
errors reported by the Mali DP hardware.

E.g:
[root@alarm ~]# cat /sys/kernel/debug/dri/1/debug
[DE] num_errors : 167
[DE] last_error_status  : 0x0001
[DE] last_error_vblank : 385
[SE] num_errors : 3
[SE] last_error_status  : 0x00e23001
[SE] last_error_vblank : 201

Changes since v2:
- Add lock to protect the errors stats.
- Add possibility to reset the error stats by writing anything to the
  debug file.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 drivers/gpu/drm/arm/malidp_drv.c  | 104 ++
 drivers/gpu/drm/arm/malidp_drv.h  |  19 +++
 drivers/gpu/drm/arm/malidp_hw.c   |  46 ++---
 drivers/gpu/drm/arm/malidp_hw.h   |   1 +
 drivers/gpu/drm/arm/malidp_regs.h |   6 +++
 5 files changed, 169 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 8d20faa..8bfeb46 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -327,6 +328,106 @@ static int malidp_dumb_create(struct drm_file *file_priv,
return drm_gem_cma_dumb_create_internal(file_priv, drm, args);
 }
 
+#ifdef CONFIG_DEBUG_FS
+
+static void malidp_error_stats_init(struct malidp_error_stats *error_stats)
+{
+   error_stats->num_errors = 0;
+   error_stats->last_error_status = 0;
+   error_stats->last_error_vblank = -1;
+}
+
+void malidp_error(struct malidp_drm *malidp,
+ struct malidp_error_stats *error_stats, u32 status,
+ u64 vblank)
+{
+   unsigned long irqflags;
+
+   spin_lock_irqsave(>errors_lock, irqflags);
+   error_stats->last_error_status = status;
+   error_stats->last_error_vblank = vblank;
+   error_stats->num_errors++;
+   spin_unlock_irqrestore(>errors_lock, irqflags);
+}
+
+void malidp_error_stats_dump(const char *prefix,
+struct malidp_error_stats error_stats,
+struct seq_file *m)
+{
+   seq_printf(m, "[%s] num_errors : %d\n", prefix,
+  error_stats.num_errors);
+   seq_printf(m, "[%s] last_error_status  : 0x%08x\n", prefix,
+  error_stats.last_error_status);
+   seq_printf(m, "[%s] last_error_vblank : %lld\n", prefix,
+  error_stats.last_error_vblank);
+}
+
+static int malidp_show_stats(struct seq_file *m, void *arg)
+{
+   struct drm_device *drm = m->private;
+   struct malidp_drm *malidp = drm->dev_private;
+   unsigned long irqflags;
+   struct malidp_error_stats de_errors, se_errors;
+
+   spin_lock_irqsave(>errors_lock, irqflags);
+   de_errors = malidp->de_errors;
+   se_errors = malidp->se_errors;
+   spin_unlock_irqrestore(>errors_lock, irqflags);
+   malidp_error_stats_dump("DE", de_errors, m);
+   malidp_error_stats_dump("SE", se_errors, m);
+   return 0;
+}
+
+static int malidp_debugfs_open(struct inode *inode, struct file *file)
+{
+   return single_open(file, malidp_show_stats, inode->i_private);
+}
+
+static ssize_t malidp_debugfs_write(struct file *file, const char __user *ubuf,
+   size_t len, loff_t *offp)
+{
+   struct seq_file *m = file->private_data;
+   struct drm_device *drm = m->private;
+   struct malidp_drm *malidp = drm->dev_private;
+   unsigned long irqflags;
+
+   spin_lock_irqsave(>errors_lock, irqflags);
+   malidp_error_stats_init(>de_errors);
+   malidp_error_stats_init(>se_errors);
+   spin_unlock_irqrestore(>errors_lock, irqflags);
+   return len;
+}
+
+static const struct file_operations malidp_debugfs_fops = {
+   .owner = THIS_MODULE,
+   .open = malidp_debugfs_open,
+   .read = seq_read,
+   .write = malidp_debugfs_write,
+   .llseek = seq_lseek,
+   .release = single_release,
+};
+
+static int malidp_debugfs_init(struct drm_minor *minor)
+{
+   struct malidp_drm *malidp = minor->dev->dev_private;
+   struct dentry *dentry = NULL;
+
+   malidp_error_stats_init(>de_errors);
+   malidp_error_stats_init(>se_errors);
+   spin_lock_init(>errors_lock);
+   dentry = debugfs_create_file("debug",
+S_IRUGO | S_IWUSR,
+minor->debugfs_root, minor->dev,
+_

[PATCH] drm: mali-dp: Add debugfs file for reporting internal errors

2018-05-11 Thread Alexandru Gheorghe
Status register contains a lot of bits for reporting internal errors
inside Mali DP. Currently, we just silently ignore all of the erorrs,
that doesn't help when we are investigating different bugs, especially
on the FPGA models which have a lot of constrains, so we could easily
end up in AXI or underrun errors.

Add a new file called debug that contains an agregate of the
errors reported by the Mali DP hardware.

E.g:
[root@alarm ~]# cat /sys/kernel/debug/dri/1/debug
[DE] num_errors : 167
[DE] last_error_status  : 0x0001
[DE] last_error_vblank : 385
[SE] num_errors : 3
[SE] last_error_status  : 0x00e23001
[SE] last_error_vblank : 201

This a morphosis of the patch presented here [1], where the errors
where reported continuously via trace_printk.

[1] https://lists.freedesktop.org/archives/dri-devel/2018-February/167042.html

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 drivers/gpu/drm/arm/malidp_drv.c  | 61 +++
 drivers/gpu/drm/arm/malidp_drv.h  | 15 ++
 drivers/gpu/drm/arm/malidp_hw.c   | 46 -
 drivers/gpu/drm/arm/malidp_hw.h   |  1 +
 drivers/gpu/drm/arm/malidp_regs.h |  6 
 5 files changed, 122 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 8d20faa..70ce19a 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -29,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "malidp_drv.h"
 #include "malidp_regs.h"
@@ -327,6 +329,62 @@ static int malidp_dumb_create(struct drm_file *file_priv,
return drm_gem_cma_dumb_create_internal(file_priv, drm, args);
 }
 
+#ifdef CONFIG_DEBUG_FS
+
+static void malidp_error_stats_init(struct malidp_error_stats *error_stats)
+{
+   atomic_set(_stats->num_errors, 0);
+   atomic_set(_stats->last_error_status, 0);
+   atomic64_set(_stats->last_error_vblank, -1);
+}
+
+void malidp_error(struct malidp_error_stats *error_stats, u32 status,
+ u64 vblank)
+{
+   atomic_set(_stats->last_error_status, status);
+   atomic64_set(_stats->last_error_vblank, vblank);
+   atomic_inc(_stats->num_errors);
+}
+
+void malidp_error_stats_dump(const char *prefix,
+struct malidp_error_stats *error_stats,
+struct seq_file *m)
+{
+   seq_printf(m, "[%s] num_errors : %d\n", prefix,
+  atomic_read(_stats->num_errors));
+   seq_printf(m, "[%s] last_error_status  : 0x%08x\n", prefix,
+  atomic_read(_stats->last_error_status));
+   seq_printf(m, "[%s] last_error_vblank : %ld\n", prefix,
+  atomic64_read(_stats->last_error_vblank));
+}
+
+static int malidp_show_stats(struct seq_file *m, void *arg)
+{
+   struct drm_info_node *node = (struct drm_info_node *)m->private;
+   struct drm_device *drm = node->minor->dev;
+   struct malidp_drm *malidp = drm->dev_private;
+
+   malidp_error_stats_dump("DE", >de_errors, m);
+   malidp_error_stats_dump("SE", >se_errors, m);
+   return 0;
+}
+
+static struct drm_info_list malidp_debugfs_list[] = {
+   { "debug", malidp_show_stats, 0 },
+};
+
+static int malidp_debugfs_init(struct drm_minor *minor)
+{
+   struct malidp_drm *malidp = minor->dev->dev_private;
+
+   malidp_error_stats_init(>de_errors);
+   malidp_error_stats_init(>se_errors);
+   return drm_debugfs_create_files(malidp_debugfs_list,
+   ARRAY_SIZE(malidp_debugfs_list), minor->debugfs_root, minor);
+}
+
+#endif //CONFIG_DEBUG_FS
+
 static struct drm_driver malidp_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC |
   DRIVER_PRIME,
@@ -343,6 +401,9 @@ static struct drm_driver malidp_driver = {
.gem_prime_vmap = drm_gem_cma_prime_vmap,
.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
.gem_prime_mmap = drm_gem_cma_prime_mmap,
+#ifdef CONFIG_DEBUG_FS
+   .debugfs_init = malidp_debugfs_init,
+#endif
.fops = ,
.name = "mali-dp",
.desc = "ARM Mali Display Processor driver",
diff --git a/drivers/gpu/drm/arm/malidp_drv.h b/drivers/gpu/drm/arm/malidp_drv.h
index c70989b..c49056c 100644
--- a/drivers/gpu/drm/arm/malidp_drv.h
+++ b/drivers/gpu/drm/arm/malidp_drv.h
@@ -18,6 +18,12 @@
 #include 
 #include "malidp_hw.h"
 
+struct malidp_error_stats {
+   atomic_t num_errors;
+   atomic_t last_error_status;
+   atomic64_t last_error_vblank;
+};
+
 struct malidp_drm {
struct malidp_hw_device *dev;
struct drm_crtc crtc;
@@ -25,6 +31,10 @@ struct malidp_drm {
struct drm_pending_vblank_ev

[PATCH hwc v2 18/18] drm_hwcomposer: Flatten scene asynchronously

2018-04-11 Thread Alexandru Gheorghe
The steps for flattening a scene on a dedicated crtc are:

1. Find an available and unused crtc(the display connector is
disconnected).
2. Copy layers from active composition.
3. Plan layers of copy on the unused crtc. This is realized by using a
newly created DrmDisplayCompositor object.
4. Commit copy to the unsed crtc and get the result as a
writeback_comp.
5. Copy the writeback comp and commit(if needed) to the display. The
copying of the writeback comp is needed because the crtc might not be
on the same dri node so the buffers will have to be re-imported.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 drmdisplaycompositor.cpp | 173 ++-
 drmdisplaycompositor.h   |   5 ++
 2 files changed, 177 insertions(+), 1 deletion(-)

diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index cb670e6..72d0226 100644
--- a/drmdisplaycompositor.cpp
+++ b/drmdisplaycompositor.cpp
@@ -973,6 +973,84 @@ int DrmDisplayCompositor::ApplyComposition(
   return ret;
 }
 
+int DrmDisplayCompositor::FlattenOnDisplay(
+std::unique_ptr ,
+std::unique_ptr ,
+DrmConnector *writeback_conn, DrmMode _mode) {
+  int ret = 0;
+  ret = writeback_conn->UpdateModes();
+  if (ret) {
+ALOGE("Failed to update modes %d", ret);
+return ret;
+  }
+  for (const DrmMode  : writeback_conn->modes()) {
+if (mode.h_display() == src_mode.h_display() &&
+mode.v_display() == src_mode.v_display()) {
+  writeback->SetDisplayMode(mode);
+  mode_.mode = mode;
+  if (mode_.blob_id)
+drm_->DestroyPropertyBlob(mode_.blob_id);
+  std::tie(ret, mode_.blob_id) = CreateModeBlob(mode_.mode);
+  if (ret) {
+ALOGE("Failed to create mode blob for display %d", display_);
+return ret;
+  }
+  mode_.needs_modeset = true;
+  break;
+}
+  }
+  if (mode_.blob_id <= 0) {
+ALOGE("Failed to find similar mode");
+return -EINVAL;
+  }
+
+  std::vector primary_planes;
+  std::vector overlay_planes;
+  SquashState squash_state;
+  DrmCrtc *crtc = drm_->GetCrtcForDisplay(display_);
+  if (!crtc) {
+ALOGE("Failed to find crtc for display %d", display_);
+return -EINVAL;
+  }
+
+  // TODO what happens if planes could go to both CRTCs, don't think it's
+  // handled anywhere
+  for (auto  : drm_->planes()) {
+if (!plane->GetCrtcSupported(*crtc))
+  continue;
+if (plane->type() == DRM_PLANE_TYPE_PRIMARY)
+  primary_planes.push_back(plane.get());
+else if (plane->type() == DRM_PLANE_TYPE_OVERLAY)
+  overlay_planes.push_back(plane.get());
+  }
+  ret = src->Plan(_state, _planes, _planes);
+  if (ret) {
+ALOGE("Failed to plan the composition ret = %d", ret);
+return ret;
+  }
+  if (src->squash_regions().size() > 0) {
+ALOGE("Abandon we don't want to fire up the GPU");
+return -EINVAL;
+  }
+
+  // Disable the planes we're not using
+  for (auto i = primary_planes.begin(); i != primary_planes.end();) {
+src->AddPlaneDisable(*i);
+i = primary_planes.erase(i);
+  }
+  for (auto i = overlay_planes.begin(); i != overlay_planes.end();) {
+src->AddPlaneDisable(*i);
+i = overlay_planes.erase(i);
+  }
+
+  ret = WritebackComposite(src.get(), writeback.get(), writeback_conn);
+  if (ret) {
+ALOGE("Failed to writeback ret=%d", ret);
+return ret;
+  }
+  return 0;
+}
+
 int DrmDisplayCompositor::WritebackComposite(DrmDisplayComposition *src,
  DrmDisplayComposition *dst,
  DrmConnector *writeback_conn) {
@@ -1088,6 +1166,97 @@ int 
DrmDisplayCompositor::FlattenSynchronously(DrmConnector *writeback_conn) {
   return 0;
 }
 
+int DrmDisplayCompositor::FlattenAsynchronously(
+DrmConnector *writeback_conn) {
+  if (writeback_conn->display() == display_) {
+ALOGE("Cannot flatten asynchronously on the same display");
+return -EINVAL;
+  }
+  ALOGI("FlattenAsynchronously on a different display");
+  int ret = 0;
+  ResourceManager *resource_manager = drm_->resource_manager();
+  DrmResources *drm_resource =
+  resource_manager->GetDrmResources(writeback_conn->display());
+  if (!drm_resource) {
+ALOGE("Failed to find resources for display = %d",
+  writeback_conn->display());
+return -EINVAL;
+  }
+  DrmDisplayCompositor drmdisplaycompositor;
+  ret = drmdisplaycompositor.Init(drm_resource, writeback_conn->display());
+  if (ret) {
+ALOGE("Failed to init  drmdisplaycompositor = %d", ret);
+  }
+  /* Copy of the active_composition, needed because of two things:
+   * 1) Not to hold the lock for the whole time we are accessing
+   *active_composition
+   * 2) Will be committed on a crtc that might not be on the same
+   *dri node, so buffe

[PATCH hwc v2 16/18] drm_hwcomposer: Find writeback connector for scene flattening

2018-04-11 Thread Alexandru Gheorghe
Add logic for finding a suitable writeback connector, there are two
possibilities for finding an usable writeback connector:

1) Attached to the same CRTC as the display and can function
   concurrently with the display connector.

2) On a different CRTC and the display connector is not used (state !=
DRM_MODE_CONNECTED). What's not handled here and should be handle is
what happens if connector changes state while flattening, but since
hotplug is not wired yet, it's not something we should worry about.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 drmresources.cpp| 25 +
 drmresources.h  |  2 +-
 resourcemanager.cpp | 24 
 resourcemanager.h   |  1 +
 4 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/drmresources.cpp b/drmresources.cpp
index fef6835..70126a4 100644
--- a/drmresources.cpp
+++ b/drmresources.cpp
@@ -269,6 +269,31 @@ DrmConnector 
*DrmResources::GetWritebackConnectorForDisplay(int display) const {
   return NULL;
 }
 
+// TODO what happens when hotplugging
+DrmConnector *DrmResources::AvailableWritebackConnector(int display) const {
+  DrmConnector *writeback_conn = GetWritebackConnectorForDisplay(display);
+  DrmConnector *display_conn = GetConnectorForDisplay(display);
+  // If we have a writeback already attached to the same CRTC, just use that, 
if
+  // possible
+  if (display_conn && writeback_conn &&
+  writeback_conn->encoder()->can_clone(display_conn->encoder()))
+return writeback_conn;
+
+  // Use another CRTC if available and doesn't have any connector
+  for (auto  : crtcs_) {
+if (crtc->display() == display)
+  continue;
+display_conn = GetConnectorForDisplay(crtc->display());
+// If we have a display connected don't use it for writeback
+if (display_conn && display_conn->state() == DRM_MODE_CONNECTED)
+  continue;
+writeback_conn = GetWritebackConnectorForDisplay(crtc->display());
+if (writeback_conn)
+  return writeback_conn;
+  }
+  return NULL;
+}
+
 DrmCrtc *DrmResources::GetCrtcForDisplay(int display) const {
   for (auto  : crtcs_) {
 if (crtc->display() == display)
diff --git a/drmresources.h b/drmresources.h
index 4fb17fc..9176b8e 100644
--- a/drmresources.h
+++ b/drmresources.h
@@ -60,7 +60,7 @@ class DrmResources {
 
   DrmConnector *GetConnectorForDisplay(int display) const;
   DrmConnector *GetWritebackConnectorForDisplay(int display) const;
-  DrmConnector *FindWritebackConnector(int display) const;
+  DrmConnector *AvailableWritebackConnector(int display) const;
   DrmCrtc *GetCrtcForDisplay(int display) const;
   DrmPlane *GetPlane(uint32_t id) const;
   DrmEventListener *event_listener();
diff --git a/resourcemanager.cpp b/resourcemanager.cpp
index e7b654e..b2a4458 100644
--- a/resourcemanager.cpp
+++ b/resourcemanager.cpp
@@ -49,6 +49,30 @@ int ResourceManager::Init() {
(const hw_module_t **)_);
 }
 
+DrmConnector *ResourceManager::AvailableWritebackConnector(int display) {
+  DrmResources *drm_resource = GetDrmResources(display);
+  DrmConnector *writeback_conn = NULL;
+  if (drm_resource) {
+writeback_conn = drm_resource->AvailableWritebackConnector(display);
+if (writeback_conn) {
+  ALOGI("Use writeback connected to display %d\n",
+writeback_conn->display());
+  return writeback_conn;
+}
+  }
+  for (auto  : drms_) {
+if (drm.get() == drm_resource)
+  continue;
+writeback_conn = drm->AvailableWritebackConnector(display);
+if (writeback_conn) {
+  ALOGI("Use writeback connected to display %d\n",
+writeback_conn->display());
+  return writeback_conn;
+}
+  }
+  return writeback_conn;
+}
+
 DrmResources *ResourceManager::GetDrmResources(int display) {
   for (uint32_t i = 0; i < drms_.size(); i++) {
 if (drms_[i]->HandlesDisplay(display))
diff --git a/resourcemanager.h b/resourcemanager.h
index b8caa9a..57f7a2a 100644
--- a/resourcemanager.h
+++ b/resourcemanager.h
@@ -18,6 +18,7 @@ class ResourceManager {
   DrmResources *GetDrmResources(int display);
   std::shared_ptr GetImporter(int display);
   const gralloc_module_t *GetGralloc();
+  DrmConnector *AvailableWritebackConnector(int display);
 
  private:
   std::vector<std::unique_ptr> drms_;
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH hwc v2 17/18] drm_hwcomposer: Flatten scene synchronously

2018-04-11 Thread Alexandru Gheorghe
Flatten scene on the same CRTC as the one driving the display.
The active composition is played back to the display with a buffer
attached to the writeback connector.
Then we build a composition that has only one plane enabled and that
uses the result of the writeback as the input.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 drmdisplaycompositor.cpp | 203 +--
 drmdisplaycompositor.h   |   7 +-
 2 files changed, 204 insertions(+), 6 deletions(-)

diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index e535e8a..cb670e6 100644
--- a/drmdisplaycompositor.cpp
+++ b/drmdisplaycompositor.cpp
@@ -36,6 +36,7 @@
 #include "drmplane.h"
 #include "drmresources.h"
 #include "glworker.h"
+static const uint32_t kWaitWritebackFence = 100;  // ms
 
 namespace android {
 
@@ -523,7 +524,9 @@ int 
DrmDisplayCompositor::PrepareFrame(DrmDisplayComposition *display_comp) {
 }
 
 int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
-  bool test_only) {
+  bool test_only,
+  DrmDisplayComposition *writeback_comp,
+  DrmConnector *writeback_conn) {
   ATRACE_CALL();
 
   int ret = 0;
@@ -532,6 +535,7 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition 
*display_comp,
   std::vector _planes =
   display_comp->composition_planes();
   uint64_t out_fences[drm_->crtcs().size()];
+  int writeback_fence = -1;
 
   DrmConnector *connector = drm_->GetConnectorForDisplay(display_);
   if (!connector) {
@@ -550,9 +554,37 @@ int 
DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
 return -ENOMEM;
   }
 
+  if (writeback_comp != NULL) {
+if (writeback_conn == NULL)
+  return -EINVAL;
+if (writeback_conn->writeback_fb_id().id() == 0 ||
+writeback_conn->writeback_out_fence().id() == 0) {
+  ALOGE("Writeback properties don't exit");
+  return -EINVAL;
+}
+if (writeback_comp->layers().size() != 1) {
+  ALOGE("Invalid number of layers for writeback composition");
+  return -EINVAL;
+}
+ret = drmModeAtomicAddProperty(
+pset, writeback_conn->id(), writeback_conn->writeback_fb_id().id(),
+writeback_comp->layers().back().buffer->fb_id);
+if (ret < 0) {
+  ALOGE("Failed to add writeback_fb_id");
+  return ret;
+}
+ret = drmModeAtomicAddProperty(pset, writeback_conn->id(),
+   writeback_conn->writeback_out_fence().id(),
+   (uint64_t)_fence);
+if (ret < 0) {
+  ALOGE("Failed to add writeback_out_fence");
+  return ret;
+}
+  }
   if (crtc->out_fence_ptr_property().id() != 0) {
-ret = drmModeAtomicAddProperty(pset, crtc->id(), 
crtc->out_fence_ptr_property().id(),
-   (uint64_t) _fences[crtc->pipe()]);
+ret = drmModeAtomicAddProperty(pset, crtc->id(),
+   crtc->out_fence_ptr_property().id(),
+   (uint64_t)_fences[crtc->pipe()]);
 if (ret < 0) {
   ALOGE("Failed to add OUT_FENCE_PTR property to pset: %d", ret);
   drmModeAtomicFree(pset);
@@ -580,6 +612,15 @@ int 
DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
 }
   }
 
+  if (writeback_conn != NULL) {
+ret = drmModeAtomicAddProperty(pset, writeback_conn->id(),
+   writeback_conn->crtc_id_property().id(),
+   crtc->id());
+if (ret < 0) {
+  ALOGE("Failed to  attach writeback");
+}
+  }
+
   for (DrmCompositionPlane _plane : comp_planes) {
 DrmPlane *plane = comp_plane.plane();
 DrmCrtc *crtc = comp_plane.crtc();
@@ -729,8 +770,18 @@ int 
DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
 
   if (!ret) {
 uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
-if (test_only)
+if (test_only) {
   flags |= DRM_MODE_ATOMIC_TEST_ONLY;
+} else {
+  if (writeback_comp != NULL) {
+if (!CountdownExpired() && active_composition_) {
+  ALOGE("Writeback composition not needed, abort commit");
+  drmModeAtomicFree(pset);
+  return -EINVAL;
+};
+flags |= DRM_MODE_ATOMIC_NONBLOCK;
+  }
+}
 
 ret = drmModeAtomicCommit(drm_->fd(), pset, flags, drm_);
 if (ret) {
@@ -769,6 +820,13 @@ int 
DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
   if (crtc->out_fence_ptr_property().id()) {
 display_comp->set_out_fence((int) out_fences[crtc->pipe()]);
   }
+  if (writeback_fence >= 0) {
+if (writeback_com

[PATCH hwc v2 15/18] drm_hwcomposer: Add worker to trigger scene flattenning

2018-04-11 Thread Alexandru Gheorghe
Add a vsync worker that calls back into the DrmDisplayCompositor,
for now at every 60 vsyncs if the scene does not change we trigger
the flattening of the scene using the writeback connector.
Other, more complex and proper heuristics could be implemented later
on.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 drmdisplaycompositor.cpp | 45 ++---
 drmdisplaycompositor.h   | 12 +++-
 2 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index 576539b..e535e8a 100644
--- a/drmdisplaycompositor.cpp
+++ b/drmdisplaycompositor.cpp
@@ -39,6 +39,20 @@
 
 namespace android {
 
+class CompositorVsyncCallback : public VsyncCallback {
+ public:
+  CompositorVsyncCallback(DrmDisplayCompositor *compositor)
+  : compositor_(compositor) {
+  }
+
+  void Callback(int display, int64_t timestamp) {
+compositor_->Vsync(display, timestamp);
+  }
+
+ private:
+  DrmDisplayCompositor *compositor_;
+};
+
 void SquashState::Init(DrmHwcLayer *layers, size_t num_layers) {
   generation_number_++;
   valid_history_ = 0;
@@ -183,7 +197,8 @@ DrmDisplayCompositor::DrmDisplayCompositor()
   framebuffer_index_(0),
   squash_framebuffer_index_(0),
   dump_frames_composited_(0),
-  dump_last_timestamp_ns_(0) {
+  dump_last_timestamp_ns_(0),
+  flatten_countdown_(FLATTEN_COUNTDOWN_INIT) {
   struct timespec ts;
   if (clock_gettime(CLOCK_MONOTONIC, ))
 return;
@@ -193,7 +208,7 @@ DrmDisplayCompositor::DrmDisplayCompositor()
 DrmDisplayCompositor::~DrmDisplayCompositor() {
   if (!initialized_)
 return;
-
+  vsync_worker_.Exit();
   int ret = pthread_mutex_lock(_);
   if (ret)
 ALOGE("Failed to acquire compositor lock %d", ret);
@@ -222,7 +237,9 @@ int DrmDisplayCompositor::Init(DrmResources *drm, int 
display) {
 return ret;
   }
   planner_ = Planner::CreateInstance(drm);
-
+  vsync_worker_.Init(drm_, display_);
+  auto callback = std::make_shared(this);
+  vsync_worker_.RegisterCallback(callback);
   initialized_ = true;
   return 0;
 }
@@ -896,6 +913,10 @@ int DrmDisplayCompositor::ApplyComposition(
   return ret;
 }
 
+int DrmDisplayCompositor::FlattenScene() {
+  return -EINVAL;
+}
+
 int DrmDisplayCompositor::SquashAll() {
   AutoLock lock(_, "compositor");
   int ret = lock.Lock();
@@ -1044,6 +1065,24 @@ move_layers_back:
   return ret;
 }
 
+bool DrmDisplayCompositor::CountdownExpired() const {
+  return flatten_countdown_ <= 0;
+}
+
+void DrmDisplayCompositor::Vsync(int display, int64_t timestamp) {
+  AutoLock lock(_, __FUNCTION__);
+  if (lock.Lock())
+return;
+  flatten_countdown_--;
+  if (CountdownExpired()) {
+lock.Unlock();
+int ret = FlattenScene();
+ALOGI("scene flattening triggered for display %d at timestamp %" PRIu64
+  " result = %d \n",
+  display, timestamp, ret);
+  }
+}
+
 void DrmDisplayCompositor::Dump(std::ostringstream *out) const {
   int ret = pthread_mutex_lock(_);
   if (ret)
diff --git a/drmdisplaycompositor.h b/drmdisplaycompositor.h
index b35ef70..26201b9 100644
--- a/drmdisplaycompositor.h
+++ b/drmdisplaycompositor.h
@@ -29,11 +29,16 @@
 
 #include 
 #include 
+#include 
 
 // One for the front, one for the back, and one for cases where we need to
 // squash a frame that the hw can't display with hw overlays.
 #define DRM_DISPLAY_BUFFERS 3
 
+// If a scene is still for this number of vblanks flatten it to reduce power
+// consumption.
+#define FLATTEN_COUNTDOWN_INIT 60
+
 namespace android {
 
 class GLWorkerCompositor;
@@ -92,7 +97,7 @@ class DrmDisplayCompositor {
   int Composite();
   int SquashAll();
   void Dump(std::ostringstream *out) const;
-
+  void Vsync(int display, int64_t timestamp);
   std::tuple<uint32_t, uint32_t, int> GetActiveModeResolution();
 
   SquashState *squash_state() {
@@ -128,6 +133,9 @@ class DrmDisplayCompositor {
   void ClearDisplay();
   void ApplyFrame(std::unique_ptr composition,
   int status, bool writeback = false);
+  int FlattenScene();
+
+  bool CountdownExpired() const;
 
   std::tuple<int, uint32_t> CreateModeBlob(const DrmMode );
 
@@ -157,6 +165,8 @@ class DrmDisplayCompositor {
   // we need to reset them on every Dump() call.
   mutable uint64_t dump_frames_composited_;
   mutable uint64_t dump_last_timestamp_ns_;
+  VSyncWorker vsync_worker_;
+  int64_t flatten_countdown_;
   std::unique_ptr planner_;
 };
 }
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH hwc v2 12/18] drm_hwcomposer: Add utility function to create an initialized composition

2018-04-11 Thread Alexandru Gheorghe
There is a lot of boilerplate for creating an initialized
drmdisplaycomposition. This patch gathers that in a separate method.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 drmdisplaycompositor.cpp | 23 +++
 drmdisplaycompositor.h   |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index e556e86..6e5be24 100644
--- a/drmdisplaycompositor.cpp
+++ b/drmdisplaycompositor.cpp
@@ -221,6 +221,7 @@ int DrmDisplayCompositor::Init(DrmResources *drm, int 
display) {
 ALOGE("Failed to initialize drm compositor lock %d\n", ret);
 return ret;
   }
+  planner_ = Planner::CreateInstance(drm);
 
   initialized_ = true;
   return 0;
@@ -231,6 +232,28 @@ std::unique_ptr 
DrmDisplayCompositor::CreateComposition()
   return std::unique_ptr(new DrmDisplayComposition());
 }
 
+std::unique_ptr
+DrmDisplayCompositor::CreateInitializedComposition() const {
+  DrmCrtc *crtc = drm_->GetCrtcForDisplay(display_);
+  if (!crtc) {
+ALOGE("Failed to find crtc for display = %d", display_);
+return std::unique_ptr();
+  }
+  std::unique_ptr comp = CreateComposition();
+  std::shared_ptr importer =
+  drm_->resource_manager()->GetImporter(display_);
+  if (!importer) {
+ALOGE("Failed to find resources for display = %d", display_);
+return std::unique_ptr();
+  }
+  int ret = comp->Init(drm_, crtc, importer.get(), planner_.get(), 0);
+  if (ret) {
+ALOGE("Failed to init composition for display = %d", display_);
+return std::unique_ptr();
+  }
+  return comp;
+}
+
 std::tuple<uint32_t, uint32_t, int>
 DrmDisplayCompositor::GetActiveModeResolution() {
   DrmConnector *connector = drm_->GetConnectorForDisplay(display_);
diff --git a/drmdisplaycompositor.h b/drmdisplaycompositor.h
index f1965fb..ccaffb4 100644
--- a/drmdisplaycompositor.h
+++ b/drmdisplaycompositor.h
@@ -87,6 +87,7 @@ class DrmDisplayCompositor {
   int Init(DrmResources *drm, int display);
 
   std::unique_ptr CreateComposition() const;
+  std::unique_ptr CreateInitializedComposition() const;
   int ApplyComposition(std::unique_ptr composition);
   int Composite();
   int SquashAll();
@@ -155,6 +156,7 @@ class DrmDisplayCompositor {
   // we need to reset them on every Dump() call.
   mutable uint64_t dump_frames_composited_;
   mutable uint64_t dump_last_timestamp_ns_;
+  std::unique_ptr planner_;
 };
 }
 
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH hwc v2 14/18] drm_hwcomposer: Fix race in ApplyFrame

2018-04-11 Thread Alexandru Gheorghe
ApplyFrame holds the lock just when it swaps the value of
active_composition_, in a multithread context we could end up in a
situation where something is shown on the screen, but something else
is set in active_composition_. Fix it by holding the lock during
CommitFrame.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 drmdisplaycompositor.cpp | 40 +---
 drmdisplaycompositor.h   |  2 +-
 2 files changed, 18 insertions(+), 24 deletions(-)

diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index afd3b05..576539b 100644
--- a/drmdisplaycompositor.cpp
+++ b/drmdisplaycompositor.cpp
@@ -791,11 +791,6 @@ std::tuple<int, uint32_t> 
DrmDisplayCompositor::CreateModeBlob(
 }
 
 void DrmDisplayCompositor::ClearDisplay() {
-  AutoLock lock(_, "compositor");
-  int ret = lock.Lock();
-  if (ret)
-return;
-
   if (!active_composition_)
 return;
 
@@ -808,11 +803,25 @@ void DrmDisplayCompositor::ClearDisplay() {
 }
 
 void DrmDisplayCompositor::ApplyFrame(
-std::unique_ptr composition, int status) {
+std::unique_ptr composition, int status,
+bool writeback) {
+  AutoLock lock(_, __FUNCTION__);
+  if (lock.Lock())
+return;
   int ret = status;
-
-  if (!ret)
+  if (!ret) {
+if (writeback && !CountdownExpired()) {
+  ALOGE("Abort playing back scene");
+  return;
+}
 ret = CommitFrame(composition.get(), false);
+if (!ret) {
+  ++dump_frames_composited_;
+  if (active_composition_)
+active_composition_->SignalCompositionDone();
+  active_composition_.swap(composition);
+}
+  }
 
   if (ret) {
 ALOGE("Composite failed for display %d", display_);
@@ -821,21 +830,6 @@ void DrmDisplayCompositor::ApplyFrame(
 ClearDisplay();
 return;
   }
-  ++dump_frames_composited_;
-
-  if (active_composition_)
-active_composition_->SignalCompositionDone();
-
-  ret = pthread_mutex_lock(_);
-  if (ret)
-ALOGE("Failed to acquire lock for active_composition swap");
-
-  active_composition_.swap(composition);
-
-  if (!ret)
-ret = pthread_mutex_unlock(_);
-  if (ret)
-ALOGE("Failed to release lock for active_composition swap");
 }
 
 int DrmDisplayCompositor::ApplyComposition(
diff --git a/drmdisplaycompositor.h b/drmdisplaycompositor.h
index 0f8daad..b35ef70 100644
--- a/drmdisplaycompositor.h
+++ b/drmdisplaycompositor.h
@@ -127,7 +127,7 @@ class DrmDisplayCompositor {
 
   void ClearDisplay();
   void ApplyFrame(std::unique_ptr composition,
-  int status);
+  int status, bool writeback = false);
 
   std::tuple<int, uint32_t> CreateModeBlob(const DrmMode );
 
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH hwc v2 11/18] drm_hwcomposer: Add utility functions to copy displaycomposition internals

2018-04-11 Thread Alexandru Gheorghe
Add utility functions to copy the DrmHwcLayer and DrmCompositionPlanes
from another DrmDisplayComposition.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 drmdisplaycomposition.cpp | 29 +
 drmdisplaycomposition.h   |  3 +++
 2 files changed, 32 insertions(+)

diff --git a/drmdisplaycomposition.cpp b/drmdisplaycomposition.cpp
index 66e67a4..dd64f46 100644
--- a/drmdisplaycomposition.cpp
+++ b/drmdisplaycomposition.cpp
@@ -99,6 +99,35 @@ int DrmDisplayComposition::SetLayers(DrmHwcLayer *layers, 
size_t num_layers,
   return 0;
 }
 
+int DrmDisplayComposition::CopyLayers(DrmDisplayComposition *src) {
+  geometry_changed_ = true;
+  type_ = DRM_COMPOSITION_TYPE_FRAME;
+  std::shared_ptr importer =
+  drm_->resource_manager()->GetImporter(crtc()->display());
+  if (!importer) {
+ALOGE("Failed to find a valid importer");
+return -EINVAL;
+  }
+  for (DrmHwcLayer _layer : src->layers()) {
+DrmHwcLayer copy;
+copy.PopulateFromDrmHwcLayer(_layer);
+int ret = copy.ImportBuffer(importer.get(),
+drm_->resource_manager()->GetGralloc());
+if (ret) {
+  ALOGE("Failed to import buffer ret = %d", ret);
+  return -EINVAL;
+}
+layers_.emplace_back(std::move(copy));
+  }
+  return 0;
+}
+
+void DrmDisplayComposition::CopyCompPlanes(DrmDisplayComposition *src) {
+  for (auto comp_plane : src->composition_planes()) {
+composition_planes_.push_back(comp_plane);
+  }
+}
+
 int DrmDisplayComposition::SetDpmsMode(uint32_t dpms_mode) {
   if (!validate_composition_type(DRM_COMPOSITION_TYPE_DPMS))
 return -EINVAL;
diff --git a/drmdisplaycomposition.h b/drmdisplaycomposition.h
index 9183925..c646420 100644
--- a/drmdisplaycomposition.h
+++ b/drmdisplaycomposition.h
@@ -68,6 +68,7 @@ class DrmCompositionPlane {
 
   DrmCompositionPlane() = default;
   DrmCompositionPlane(DrmCompositionPlane &) = default;
+  DrmCompositionPlane(const DrmCompositionPlane ) = default;
   DrmCompositionPlane =(DrmCompositionPlane &) = default;
   DrmCompositionPlane(Type type, DrmPlane *plane, DrmCrtc *crtc)
   : type_(type), plane_(plane), crtc_(crtc) {
@@ -120,6 +121,8 @@ class DrmDisplayComposition {
Planner *planner, uint64_t frame_no);
 
   int SetLayers(DrmHwcLayer *layers, size_t num_layers, bool geometry_changed);
+  int CopyLayers(DrmDisplayComposition *src);
+  void CopyCompPlanes(DrmDisplayComposition *src);
   int AddPlaneComposition(DrmCompositionPlane plane);
   int AddPlaneDisable(DrmPlane *plane);
   int SetDpmsMode(uint32_t dpms_mode);
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH hwc v2 13/18] drm_hwcomposer: Pass buffer sizes to Prepareframebuffer

2018-04-11 Thread Alexandru Gheorghe
Currently Prepareframebuffer uses the mode of the connected connector
to decide how big the buffer should be, however when using the
drmdisplaycompositor just for flattening, the mode had not been set
yet, so we need a way to pass the desired buffer sizes.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 drmdisplaycompositor.cpp | 7 ---
 drmdisplaycompositor.h   | 3 ++-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index 6e5be24..afd3b05 100644
--- a/drmdisplaycompositor.cpp
+++ b/drmdisplaycompositor.cpp
@@ -268,14 +268,15 @@ DrmDisplayCompositor::GetActiveModeResolution() {
 }
 
 int DrmDisplayCompositor::PrepareFramebuffer(
-DrmFramebuffer , DrmDisplayComposition *display_comp) {
+DrmFramebuffer , DrmDisplayComposition *display_comp, uint32_t width,
+uint32_t height) {
   int ret = fb.WaitReleased(-1);
   if (ret) {
 ALOGE("Failed to wait for framebuffer release %d", ret);
 return ret;
   }
-  uint32_t width, height;
-  std::tie(width, height, ret) = GetActiveModeResolution();
+  if (width == 0 || height == 0)
+std::tie(width, height, ret) = GetActiveModeResolution();
   if (ret) {
 ALOGE(
 "Failed to allocate framebuffer because the display resolution could "
diff --git a/drmdisplaycompositor.h b/drmdisplaycompositor.h
index ccaffb4..0f8daad 100644
--- a/drmdisplaycompositor.h
+++ b/drmdisplaycompositor.h
@@ -115,7 +115,8 @@ class DrmDisplayCompositor {
   static const int kAcquireWaitTimeoutMs = 100;
 
   int PrepareFramebuffer(DrmFramebuffer ,
- DrmDisplayComposition *display_comp);
+ DrmDisplayComposition *display_comp,
+ uint32_t width = 0, uint32_t height = 0);
   int ApplySquash(DrmDisplayComposition *display_comp);
   int ApplyPreComposite(DrmDisplayComposition *display_comp);
   int PrepareFrame(DrmDisplayComposition *display_comp);
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH hwc v2 07/18] drm_hwcomposer: Add display field to Drmencoder

2018-04-11 Thread Alexandru Gheorghe
In the current implementation TryEncoderForDisplay just looks
at the crtc linked to the display, if that's not assigned to
a display it means the encoder could be used, otherwise iterate
to the list of possible_crtcs and find one which is not used.

This logic works fine when you have just one encoder connected to a
crtc but with two or more, like is the case when we attach a writeback
connector, we need to know if we already assigned the encoder to a
display.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 drmencoder.cpp | 14 ++
 drmencoder.h   |  4 
 2 files changed, 18 insertions(+)

diff --git a/drmencoder.cpp b/drmencoder.cpp
index 3d762f3..1da7ec3 100644
--- a/drmencoder.cpp
+++ b/drmencoder.cpp
@@ -27,6 +27,7 @@ DrmEncoder::DrmEncoder(drmModeEncoderPtr e, DrmCrtc 
*current_crtc,
const std::vector _crtcs)
 : id_(e->encoder_id),
   crtc_(current_crtc),
+  display_(-1),
   possible_crtcs_(possible_crtcs) {
 }
 
@@ -40,5 +41,18 @@ DrmCrtc *DrmEncoder::crtc() const {
 
 void DrmEncoder::set_crtc(DrmCrtc *crtc) {
   crtc_ = crtc;
+  set_display(crtc->display());
+}
+
+int DrmEncoder::display() const {
+  return display_;
+}
+
+void DrmEncoder::set_display(int display) {
+  display_ = display;
+}
+
+bool DrmEncoder::can_bind(int display) const {
+  return display_ == -1 || display_ == display;
 }
 }
diff --git a/drmencoder.h b/drmencoder.h
index 58ccbfb..7e06691 100644
--- a/drmencoder.h
+++ b/drmencoder.h
@@ -36,6 +36,9 @@ class DrmEncoder {
 
   DrmCrtc *crtc() const;
   void set_crtc(DrmCrtc *crtc);
+  bool can_bind(int display) const;
+  void set_display(int display);
+  int display() const;
 
   const std::vector _crtcs() const {
 return possible_crtcs_;
@@ -44,6 +47,7 @@ class DrmEncoder {
  private:
   uint32_t id_;
   DrmCrtc *crtc_;
+  int display_;
 
   std::vector possible_crtcs_;
 };
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH hwc v2 09/18] drm_hwcomposer: Handle writeback connectors

2018-04-11 Thread Alexandru Gheorghe
When writeback connectors are available assign them to displays, in
order to be able to use them for flattening of the current displayed
scene. The pipeline for each display will look like this:

CRTC  encoder  display connector.
 |--- writeback enc -- writeback connector.

However, the writeback connector will be later used/enabled only if
one of the following conditions are met:
 - Could be a clone of the display connector, as pointed by the
   possible_clones property.
 - The display_connector is disconnected, so we are safe to use it for
   flattening the scene that's already presented on another display.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 drmresources.cpp | 62 ++--
 drmresources.h   |  3 +++
 2 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/drmresources.cpp b/drmresources.cpp
index 39f50be..fef6835 100644
--- a/drmresources.cpp
+++ b/drmresources.cpp
@@ -64,6 +64,14 @@ int DrmResources::Init(ResourceManager *resource_manager, 
char *path,
 return ret;
   }
 
+#ifdef DRM_CLIENT_CAP_WRITEBACK_CONNECTORS
+  ret = drmSetClientCap(fd(), DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
+  if (ret) {
+ALOGI("Failed to set writeback cap %d", ret);
+ret = 0;
+  }
+#endif
+
   drmModeResPtr res = drmModeGetResources(fd());
   if (!res) {
 ALOGE("Failed to get DrmResources resources");
@@ -169,7 +177,7 @@ int DrmResources::Init(ResourceManager *resource_manager, 
char *path,
   conn->set_display(0);
   displays_[0] = 0;
   found_primary = true;
-} else {
+} else if (conn->external()) {
   conn->set_display(display_num);
   displays_[display_num] = display_num;
   ++display_num;
@@ -230,6 +238,8 @@ int DrmResources::Init(ResourceManager *resource_manager, 
char *path,
   }
 
   for (auto  : connectors_) {
+if (conn->writeback())
+  continue;
 ret = CreateDisplayPipe(conn.get());
 if (ret) {
   ALOGE("Failed CreateDisplayPipe %d with %d", conn->id(), ret);
@@ -245,7 +255,15 @@ bool DrmResources::HandlesDisplay(int display) const {
 
 DrmConnector *DrmResources::GetConnectorForDisplay(int display) const {
   for (auto  : connectors_) {
-if (conn->display() == display)
+if (conn->display() == display && !conn->writeback())
+  return conn.get();
+  }
+  return NULL;
+}
+
+DrmConnector *DrmResources::GetWritebackConnectorForDisplay(int display) const 
{
+  for (auto  : connectors_) {
+if (conn->display() == display && conn->writeback())
   return conn.get();
   }
   return NULL;
@@ -280,6 +298,7 @@ int DrmResources::TryEncoderForDisplay(int display, 
DrmEncoder *enc) {
   DrmCrtc *crtc = enc->crtc();
   if (crtc && crtc->can_bind(display)) {
 crtc->set_display(display);
+enc->set_display(display);
 return 0;
   }
 
@@ -306,6 +325,7 @@ int DrmResources::CreateDisplayPipe(DrmConnector 
*connector) {
   if (connector->encoder()) {
 int ret = TryEncoderForDisplay(display, connector->encoder());
 if (!ret) {
+  AttachWriteback(connector);
   return 0;
 } else if (ret != -EAGAIN) {
   ALOGE("Could not set mode %d/%d", display, ret);
@@ -317,6 +337,7 @@ int DrmResources::CreateDisplayPipe(DrmConnector 
*connector) {
 int ret = TryEncoderForDisplay(display, enc);
 if (!ret) {
   connector->set_encoder(enc);
+  AttachWriteback(connector);
   return 0;
 } else if (ret != -EAGAIN) {
   ALOGE("Could not set mode %d/%d", display, ret);
@@ -328,6 +349,43 @@ int DrmResources::CreateDisplayPipe(DrmConnector 
*connector) {
   return -ENODEV;
 }
 
+/*
+ * Attach writeback connector to the CRTC linked to the display_conn
+ *
+ */
+int DrmResources::AttachWriteback(DrmConnector *display_conn) {
+  int ret = -EINVAL;
+  if (display_conn->writeback())
+return -EINVAL;
+  DrmEncoder *display_enc = display_conn->encoder();
+  if (!display_enc)
+return -EINVAL;
+  DrmCrtc *display_crtc = display_enc->crtc();
+  if (!display_crtc)
+return -EINVAL;
+  if (GetWritebackConnectorForDisplay(display_crtc->display()) != NULL)
+return -EINVAL;
+  for (auto _conn : connectors_) {
+if (writeback_conn->display() >= 0 || !writeback_conn->writeback())
+  continue;
+for (DrmEncoder *writeback_enc : writeback_conn->possible_encoders()) {
+  for (DrmCrtc *possible_crtc : writeback_enc->possible_crtcs()) {
+if (possible_crtc != display_crtc)
+  continue;
+// Use just encoders which had not been bound already
+if (writeback_enc->can_bind(display_crtc->display())) {
+  writeback_enc->set_crtc(display_crtc);
+  writeback_conn->set_encoder(writeback_enc);
+  writeback_conn->set_display(display_crtc->display());
+ 

[PATCH hwc v2 06/18] drm_hwcomposer: Add writeback connector support

2018-04-11 Thread Alexandru Gheorghe
Writeback connector is a special case of connector, which can be
linked to a CRTC in order to get the result of the composition back to
a memory buffer. This had not been merged to the mainline kernel yet,
latest version of the kernel patches could be found here [1].

[1] https://lists.freedesktop.org/archives/dri-devel/2018-February/167703.html

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 drmconnector.cpp | 42 +-
 drmconnector.h   |  7 +++
 2 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drmconnector.cpp b/drmconnector.cpp
index 145518f..e482832 100644
--- a/drmconnector.cpp
+++ b/drmconnector.cpp
@@ -52,6 +52,26 @@ int DrmConnector::Init() {
 ALOGE("Could not get CRTC_ID property\n");
 return ret;
   }
+  if (writeback()) {
+ret = drm_->GetConnectorProperty(*this, "WRITEBACK_PIXEL_FORMATS",
+ _pixel_formats_);
+if (ret) {
+  ALOGE("Could not get WRITEBACK_PIXEL_FORMATS connector_id = %d\n", id_);
+  return ret;
+}
+ret =
+drm_->GetConnectorProperty(*this, "WRITEBACK_FB_ID", 
_fb_id_);
+if (ret) {
+  ALOGE("Could not get WRITEBACK_FB_ID connector_id = %d\n", id_);
+  return ret;
+}
+ret = drm_->GetConnectorProperty(*this, "WRITEBACK_OUT_FENCE_PTR",
+ _out_fence_);
+if (ret) {
+  ALOGE("Could not get WRITEBACK_OUT_FENCE_PTR connector_id = %d\n", id_);
+  return ret;
+}
+  }
   return 0;
 }
 
@@ -78,8 +98,16 @@ bool DrmConnector::external() const {
  type_ == DRM_MODE_CONNECTOR_VGA;
 }
 
+bool DrmConnector::writeback() const {
+#ifdef DRM_MODE_CONNECTOR_WRITEBACK
+  return type_ == DRM_MODE_CONNECTOR_WRITEBACK;
+#else
+  return false;
+#endif
+}
+
 bool DrmConnector::valid_type() const {
-  return internal() || external();
+  return internal() || external() || writeback();
 }
 
 int DrmConnector::UpdateModes() {
@@ -130,6 +158,18 @@ const DrmProperty ::crtc_id_property() const {
   return crtc_id_property_;
 }
 
+const DrmProperty ::writeback_pixel_formats() const {
+  return writeback_pixel_formats_;
+}
+
+const DrmProperty ::writeback_fb_id() const {
+  return writeback_fb_id_;
+}
+
+const DrmProperty ::writeback_out_fence() const {
+  return writeback_out_fence_;
+}
+
 DrmEncoder *DrmConnector::encoder() const {
   return encoder_;
 }
diff --git a/drmconnector.h b/drmconnector.h
index 5601e06..e139730 100644
--- a/drmconnector.h
+++ b/drmconnector.h
@@ -46,6 +46,7 @@ class DrmConnector {
 
   bool internal() const;
   bool external() const;
+  bool writeback() const;
   bool valid_type() const;
 
   int UpdateModes();
@@ -58,6 +59,9 @@ class DrmConnector {
 
   const DrmProperty _property() const;
   const DrmProperty _id_property() const;
+  const DrmProperty _pixel_formats() const;
+  const DrmProperty _fb_id() const;
+  const DrmProperty _out_fence() const;
 
   const std::vector _encoders() const {
 return possible_encoders_;
@@ -88,6 +92,9 @@ class DrmConnector {
 
   DrmProperty dpms_property_;
   DrmProperty crtc_id_property_;
+  DrmProperty writeback_pixel_formats_;
+  DrmProperty writeback_fb_id_;
+  DrmProperty writeback_out_fence_;
 
   std::vector possible_encoders_;
 };
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH hwc v2 10/18] drm_hwcomposer: hwcutils: Add function for cloning a DrmHwcLayer

2018-04-11 Thread Alexandru Gheorghe
When doing flattening of a composition on a different CRTC we need to be
able to clone a layer in order to import it and then pass it to another CRTC.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 drmhwcomposer.h |  1 +
 hwcutils.cpp| 11 +++
 2 files changed, 12 insertions(+)

diff --git a/drmhwcomposer.h b/drmhwcomposer.h
index f8440fb..b256caf 100644
--- a/drmhwcomposer.h
+++ b/drmhwcomposer.h
@@ -150,6 +150,7 @@ struct DrmHwcLayer {
 
   int InitFromHwcLayer(hwc_layer_1_t *sf_layer, Importer *importer,
const gralloc_module_t *gralloc);
+  int PopulateFromDrmHwcLayer(DrmHwcLayer *layer);
   int ImportBuffer(Importer *importer, const gralloc_module_t *gralloc);
 
   void SetTransform(int32_t sf_transform);
diff --git a/hwcutils.cpp b/hwcutils.cpp
index 53a7d82..ff37c3b 100644
--- a/hwcutils.cpp
+++ b/hwcutils.cpp
@@ -149,6 +149,17 @@ int DrmHwcLayer::InitFromHwcLayer(hwc_layer_1_t *sf_layer, 
Importer *importer,
   return ImportBuffer(importer, gralloc);
 }
 
+int DrmHwcLayer::PopulateFromDrmHwcLayer(DrmHwcLayer *src_layer) {
+  blending = src_layer->blending;
+  sf_handle = src_layer->sf_handle;
+  acquire_fence = dup(src_layer->acquire_fence.get());
+  display_frame = src_layer->display_frame;
+  alpha = src_layer->alpha;
+  source_crop = src_layer->source_crop;
+  transform = src_layer->transform;
+  return 0;
+}
+
 int DrmHwcLayer::ImportBuffer(Importer *importer,
   const gralloc_module_t *gralloc) {
   int ret = buffer.ImportBuffer(sf_handle, importer);
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH hwc v2 08/18] drm_hwcomposer: Parse and store possible_clones information

2018-04-11 Thread Alexandru Gheorghe
drmModeEncoder has a field called possible_clones. It's a bit mask
which tells if the encoder could be simultaneously connected, to the
same CRTC, with the encoders specified in the possible_clones mask.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 drmencoder.cpp   | 8 
 drmencoder.h | 4 
 drmresources.cpp | 9 -
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/drmencoder.cpp b/drmencoder.cpp
index 1da7ec3..ff675f5 100644
--- a/drmencoder.cpp
+++ b/drmencoder.cpp
@@ -39,6 +39,14 @@ DrmCrtc *DrmEncoder::crtc() const {
   return crtc_;
 }
 
+bool DrmEncoder::can_clone(DrmEncoder *encoder) {
+  return possible_clones_.find(encoder) != possible_clones_.end();
+}
+
+void DrmEncoder::add_possible_clone(DrmEncoder *possible_clone) {
+  possible_clones_[possible_clone] = true;
+}
+
 void DrmEncoder::set_crtc(DrmCrtc *crtc) {
   crtc_ = crtc;
   set_display(crtc->display());
diff --git a/drmencoder.h b/drmencoder.h
index 7e06691..5e7c010 100644
--- a/drmencoder.h
+++ b/drmencoder.h
@@ -21,6 +21,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 namespace android {
@@ -43,6 +44,8 @@ class DrmEncoder {
   const std::vector _crtcs() const {
 return possible_crtcs_;
   }
+  bool can_clone(DrmEncoder *encoder);
+  void add_possible_clone(DrmEncoder *possible_clone);
 
  private:
   uint32_t id_;
@@ -50,6 +53,7 @@ class DrmEncoder {
   int display_;
 
   std::vector possible_crtcs_;
+  std::map possible_clones_;
 };
 }
 
diff --git a/drmresources.cpp b/drmresources.cpp
index a5ddda0..39f50be 100644
--- a/drmresources.cpp
+++ b/drmresources.cpp
@@ -97,6 +97,7 @@ int DrmResources::Init(ResourceManager *resource_manager, 
char *path,
 crtcs_.emplace_back(std::move(crtc));
   }
 
+  std::vector possible_clones;
   for (int i = 0; !ret && i < res->count_encoders; ++i) {
 drmModeEncoderPtr e = drmModeGetEncoder(fd(), res->encoders[i]);
 if (!e) {
@@ -117,12 +118,18 @@ int DrmResources::Init(ResourceManager *resource_manager, 
char *path,
 
 std::unique_ptr enc(
 new DrmEncoder(e, current_crtc, possible_crtcs));
-
+possible_clones.push_back(e->possible_clones);
 drmModeFreeEncoder(e);
 
 encoders_.emplace_back(std::move(enc));
   }
 
+  for (uint32_t i = 0; i < encoders_.size(); i++) {
+for (uint32_t j = 0; j < encoders_.size(); j++)
+  if (possible_clones[i] & (1 << j))
+encoders_[i]->add_possible_clone(encoders_[j].get());
+  }
+
   for (int i = 0; !ret && i < res->count_connectors; ++i) {
 drmModeConnectorPtr c = drmModeGetConnector(fd(), res->connectors[i]);
 if (!c) {
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH hwc v2 04/18] drm_hwcomposer: Add resource manager class

2018-04-11 Thread Alexandru Gheorghe
Add a resource manager object that is responsible for detecting all
kms devices and allocates unique display numbers for every detected
display.

This is controlled by the value of hwc.drm.device property, if it ends
with a %, it will try to open minor devices until and error is detected.
E.g: /dev/dri/card%

Additionally, this will be used for finding an available writeback
connector that will be used for the flattening of the currently
displayed scene.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 Android.mk  |  1 +
 resourcemanager.cpp | 71 +
 resourcemanager.h   | 29 ++
 3 files changed, 101 insertions(+)
 create mode 100644 resourcemanager.cpp
 create mode 100644 resourcemanager.h

diff --git a/Android.mk b/Android.mk
index 1add286..736fe24 100644
--- a/Android.mk
+++ b/Android.mk
@@ -52,6 +52,7 @@ LOCAL_C_INCLUDES := \
 
 LOCAL_SRC_FILES := \
autolock.cpp \
+   resourcemanager.cpp \
drmresources.cpp \
drmconnector.cpp \
drmcrtc.cpp \
diff --git a/resourcemanager.cpp b/resourcemanager.cpp
new file mode 100644
index 000..e7b654e
--- /dev/null
+++ b/resourcemanager.cpp
@@ -0,0 +1,71 @@
+#include "resourcemanager.h"
+#include 
+#include 
+
+namespace android {
+
+ResourceManager::ResourceManager() : gralloc_(NULL) {
+}
+
+int ResourceManager::Init() {
+  char path_pattern[PROPERTY_VALUE_MAX];
+  property_get("hwc.drm.device", path_pattern, "/dev/dri/card%");
+
+  uint8_t minor = 0;
+  int last_display_index = 0;
+  int last_char = strlen(path_pattern) - 1;
+  do {
+char path[PROPERTY_VALUE_MAX];
+if (path_pattern[last_char] == '%') {
+  path_pattern[last_char] = '\0';
+  snprintf(path, PROPERTY_VALUE_MAX, "%s%d", path_pattern, minor);
+  path_pattern[last_char] = '%';
+} else {
+  snprintf(path, PROPERTY_VALUE_MAX, "%s", path_pattern);
+}
+std::unique_ptr drm = std::make_unique();
+last_display_index = drm->Init(this, path, last_display_index);
+if (last_display_index < 0) {
+  break;
+}
+std::shared_ptr importer;
+importer.reset(Importer::CreateInstance(drm.get()));
+if (!importer) {
+  ALOGE("Failed to create importer instance");
+  break;
+}
+importers_.push_back(importer);
+drms_.push_back(std::move(drm));
+minor++;
+last_display_index++;
+  } while (path_pattern[last_char] == '%');
+
+  if (!drms_.size()) {
+ALOGE("Failed to find any working drm device");
+return -EINVAL;
+  }
+
+  return hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
+   (const hw_module_t **)_);
+}
+
+DrmResources *ResourceManager::GetDrmResources(int display) {
+  for (uint32_t i = 0; i < drms_.size(); i++) {
+if (drms_[i]->HandlesDisplay(display))
+  return drms_[i].get();
+  }
+  return NULL;
+}
+
+std::shared_ptr ResourceManager::GetImporter(int display) {
+  for (uint32_t i = 0; i < drms_.size(); i++) {
+if (drms_[i]->HandlesDisplay(display))
+  return importers_[i];
+  }
+  return NULL;
+}
+
+const gralloc_module_t *ResourceManager::GetGralloc() {
+  return gralloc_;
+}
+}
diff --git a/resourcemanager.h b/resourcemanager.h
new file mode 100644
index 000..b8caa9a
--- /dev/null
+++ b/resourcemanager.h
@@ -0,0 +1,29 @@
+#ifndef RESOURCEMANAGER_H
+#define RESOURCEMANAGER_H
+
+#include "drmresources.h"
+#include "platform.h"
+
+namespace android {
+
+class DrmResources;
+class Importer;
+
+class ResourceManager {
+ public:
+  ResourceManager();
+  ResourceManager(const ResourceManager &) = delete;
+  ResourceManager =(const ResourceManager &) = delete;
+  int Init();
+  DrmResources *GetDrmResources(int display);
+  std::shared_ptr GetImporter(int display);
+  const gralloc_module_t *GetGralloc();
+
+ private:
+  std::vector<std::unique_ptr> drms_;
+  std::vector<std::shared_ptr> importers_;
+  const gralloc_module_t *gralloc_;
+};
+}
+
+#endif  // RESOURCEMANAGER_H
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH hwc v2 05/18] drm_hwcomposer: Enable resource manager support

2018-04-11 Thread Alexandru Gheorghe
Use the newly added ResourceManager for creating and detecting all the
drm devices instead of assuming that there is only one device.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 drmhwctwo.cpp| 34 +-
 drmhwctwo.h  |  4 +---
 drmresources.cpp | 25 ++---
 drmresources.h   | 14 +++---
 4 files changed, 43 insertions(+), 34 deletions(-)

diff --git a/drmhwctwo.cpp b/drmhwctwo.cpp
index dfca1a6..cddd5da 100644
--- a/drmhwctwo.cpp
+++ b/drmhwctwo.cpp
@@ -58,40 +58,32 @@ DrmHwcTwo::DrmHwcTwo() {
 }
 
 HWC2::Error DrmHwcTwo::Init() {
-  int ret = drm_.Init();
+  int ret = resource_manager_.Init();
   if (ret) {
-ALOGE("Can't initialize drm object %d", ret);
+ALOGE("Can't initialize the resource manager %d", ret);
 return HWC2::Error::NoResources;
   }
 
-  importer_.reset(Importer::CreateInstance(_));
-  if (!importer_) {
-ALOGE("Failed to create importer instance");
+  DrmResources *drm = resource_manager_.GetDrmResources(HWC_DISPLAY_PRIMARY);
+  std::shared_ptr importer =
+  resource_manager_.GetImporter(HWC_DISPLAY_PRIMARY);
+  if (!drm || !importer) {
+ALOGE("Failed to get a valid drmresource and importer");
 return HWC2::Error::NoResources;
   }
+  displays_.emplace(
+  std::piecewise_construct, std::forward_as_tuple(HWC_DISPLAY_PRIMARY),
+  std::forward_as_tuple(drm, importer, resource_manager_.GetGralloc(),
+HWC_DISPLAY_PRIMARY, HWC2::DisplayType::Physical));
 
-  ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
-  (const hw_module_t **)_);
-  if (ret) {
-ALOGE("Failed to open gralloc module %d", ret);
-return HWC2::Error::NoResources;
-  }
-
-  displays_.emplace(std::piecewise_construct,
-std::forward_as_tuple(HWC_DISPLAY_PRIMARY),
-std::forward_as_tuple(_, importer_, gralloc_,
-  HWC_DISPLAY_PRIMARY,
-  HWC2::DisplayType::Physical));
-
-  DrmCrtc *crtc = 
drm_.GetCrtcForDisplay(static_cast(HWC_DISPLAY_PRIMARY));
+  DrmCrtc *crtc = 
drm->GetCrtcForDisplay(static_cast(HWC_DISPLAY_PRIMARY));
   if (!crtc) {
 ALOGE("Failed to get crtc for display %d",
   static_cast(HWC_DISPLAY_PRIMARY));
 return HWC2::Error::BadDisplay;
   }
-
   std::vector display_planes;
-  for (auto  : drm_.planes()) {
+  for (auto  : drm->planes()) {
 if (plane->GetCrtcSupported(*crtc))
   display_planes.push_back(plane.get());
   }
diff --git a/drmhwctwo.h b/drmhwctwo.h
index 0490e2a..beb5d2d 100644
--- a/drmhwctwo.h
+++ b/drmhwctwo.h
@@ -262,9 +262,7 @@ class DrmHwcTwo : public hwc2_device_t {
   HWC2::Error RegisterCallback(int32_t descriptor, hwc2_callback_data_t data,
hwc2_function_pointer_t function);
 
-  DrmResources drm_;
-  std::shared_ptr importer_;  // Shared with HwcDisplay
-  const gralloc_module_t *gralloc_;
+  ResourceManager resource_manager_;
   std::map<hwc2_display_t, HwcDisplay> displays_;
   std::map<HWC2::Callback, HwcCallback> callbacks_;
 };
diff --git a/drmresources.cpp b/drmresources.cpp
index 32dd376..a5ddda0 100644
--- a/drmresources.cpp
+++ b/drmresources.cpp
@@ -42,10 +42,9 @@ DrmResources::~DrmResources() {
   event_listener_.Exit();
 }
 
-int DrmResources::Init() {
-  char path[PROPERTY_VALUE_MAX];
-  property_get("hwc.drm.device", path, "/dev/dri/card0");
-
+int DrmResources::Init(ResourceManager *resource_manager, char *path,
+   int start_display_index) {
+  resource_manager_ = resource_manager;
   /* TODO: Use drmOpenControl here instead */
   fd_.Set(open(path, O_RDWR));
   if (fd() < 0) {
@@ -76,8 +75,8 @@ int DrmResources::Init() {
   max_resolution_ =
   std::pair<uint32_t, uint32_t>(res->max_width, res->max_height);
 
-  bool found_primary = false;
-  int display_num = 1;
+  bool found_primary = start_display_index != 0;
+  int display_num = found_primary ? start_display_index : 1;
 
   for (int i = 0; !ret && i < res->count_crtcs; ++i) {
 drmModeCrtcPtr c = drmModeGetCrtc(fd(), res->crtcs[i]);
@@ -161,9 +160,11 @@ int DrmResources::Init() {
   for (auto  : connectors_) {
 if (conn->internal() && !found_primary) {
   conn->set_display(0);
+  displays_[0] = 0;
   found_primary = true;
 } else {
   conn->set_display(display_num);
+  displays_[display_num] = display_num;
   ++display_num;
 }
   }
@@ -171,7 +172,9 @@ int DrmResources::Init() {
   // Then look for primary amongst external connectors
   for (auto  : connectors_) {
 if (conn->external() && !found_primary) {
+  displays_.erase(conn->display());
   conn->set_display(0);
+  displays_[0] = 0;
   found_primary = true;
 }

[PATCH hwc v2 02/18] drm_hwcomposer: vsyncworker: Fix deadlock on exit path

2018-04-11 Thread Alexandru Gheorghe
vsyncworker::Routine assumes that when -EINTR is returned by
WaitForSignalOrExitLocked the lock as been released, which is not
true, so it hangs if a vsyncworker is never enabled and Exit is
called.

There are two code paths in WaitForSignalOrExitLocked that return
-EINTR, one releases the lock the other doesn't.
Looking at the clients of WaitForSignalOrExitLocked all assume the lock
is still held, except vsyncworker::Routine.
So, the proper fix needs two changes:
- Make WaitForSignalOrExitLocked consistent and always hold the lock
  when exiting.
- Release lock in vsynworker::Routine on all code paths.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 vsyncworker.cpp | 1 +
 worker.cpp  | 6 +++---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/vsyncworker.cpp b/vsyncworker.cpp
index 3bfe4be..7c0c741 100644
--- a/vsyncworker.cpp
+++ b/vsyncworker.cpp
@@ -120,6 +120,7 @@ void VSyncWorker::Routine() {
   if (!enabled_) {
 ret = WaitForSignalOrExitLocked();
 if (ret == -EINTR) {
+  Unlock();
   return;
 }
   }
diff --git a/worker.cpp b/worker.cpp
index da6c580..5b351e0 100644
--- a/worker.cpp
+++ b/worker.cpp
@@ -66,13 +66,13 @@ int Worker::WaitForSignalOrExitLocked(int64_t 
max_nanoseconds) {
 ret = -ETIMEDOUT;
   }
 
+  // release leaves mutex locked when going out of scope
+  lk.release();
+
   // exit takes precedence on timeout
   if (should_exit())
 ret = -EINTR;
 
-  // release leaves mutex locked when going out of scope
-  lk.release();
-
   return ret;
 }
 
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH hwc v2 03/18] drm_hwcomposer: drmeventlistener: Set nl_pid to 0

2018-04-11 Thread Alexandru Gheorghe
By setting nl_pid to 0, we let the kernel to assign a port for us.
In the current implementation there is no way we could create more
than one instance for drmeventlistener.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 drmeventlistener.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drmeventlistener.cpp b/drmeventlistener.cpp
index 984d1dd..5534182 100644
--- a/drmeventlistener.cpp
+++ b/drmeventlistener.cpp
@@ -46,7 +46,7 @@ int DrmEventListener::Init() {
   struct sockaddr_nl addr;
   memset(, 0, sizeof(addr));
   addr.nl_family = AF_NETLINK;
-  addr.nl_pid = getpid();
+  addr.nl_pid = 0;
   addr.nl_groups = 0x;
 
   int ret = bind(uevent_fd_.get(), (struct sockaddr *), sizeof(addr));
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH hwc v2 01/18] drm_hwcomposer: vsyncworker: Fix uninitialized enabled_ field

2018-04-11 Thread Alexandru Gheorghe
Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheor...@arm.com>
---
 vsyncworker.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/vsyncworker.cpp b/vsyncworker.cpp
index 3ad16fe..3bfe4be 100644
--- a/vsyncworker.cpp
+++ b/vsyncworker.cpp
@@ -35,6 +35,7 @@ VSyncWorker::VSyncWorker()
 : Worker("vsync", HAL_PRIORITY_URGENT_DISPLAY),
   drm_(NULL),
   display_(-1),
+  enabled_(false),
   last_timestamp_(-1) {
 }
 
-- 
2.7.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


  1   2   >