Re: [PATCH v6, 23/24] media: mediatek: vcodec: support av1 svp decoder for mt8188

2024-05-23 Thread Andrzej Pietrasiewicz

Hi Yunfei and Xiaoyong,

W dniu 16.05.2024 o 14:21, Yunfei Dong pisze:

From: Xiaoyong Lu 

Change av1 driver to support secure video playback(svp) for
mt8188. Need to map shared memory with optee interface and
wait interrupt in optee-os.

Signed-off-by: Xiaoyong Lu 
Signed-off-by: Yunfei Dong 
---
  .../vcodec/decoder/vdec/vdec_av1_req_lat_if.c | 97 ---
  1 file changed, 63 insertions(+), 34 deletions(-)

diff --git 
a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c 
b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
index bf21f2467a0f..a3ad35df7f73 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
@@ -58,6 +58,9 @@
  #define SEG_LVL_ALT_Q 0
  #define SECONDARY_FILTER_STRENGTH_NUM_BITS 2
  
+#define AV1_IQ_TABLE_SIZE	0x12200

+#define AV1_CDF_TABLE_SIZE 0xFE80
+
  static const short div_lut[DIV_LUT_NUM + 1] = {
16384, 16320, 16257, 16194, 16132, 16070, 16009, 15948, 15888, 15828, 
15768,
15709, 15650, 15592, 15534, 15477, 15420, 15364, 15308, 15252, 15197, 
15142,
@@ -641,6 +644,8 @@ struct vdec_av1_slice_fb {
   * @frame:current frame info
   * @state:status after decode done
   * @cur_lst_tile_id:  tile id for large scale
+ * @tile_group:tile group info
+ * @reservd:   reserved
   */
  struct vdec_av1_slice_vsi {
/* lat */
@@ -665,6 +670,8 @@ struct vdec_av1_slice_vsi {
struct vdec_av1_slice_frame frame;
struct vdec_av1_slice_state state;
u32 cur_lst_tile_id;
+   struct vdec_av1_slice_tile_group tile_group;
+   unsigned int reservd[4];
  };
  
  /**

@@ -692,7 +699,6 @@ struct vdec_av1_slice_pfc {
   * @cdf_temp:   cdf temp buffer
   * @tile:   tile buffer
   * @slots:  slots info
- * @tile_group: tile_group entry
   * @level:  level of current resolution
   * @width:  width of last picture
   * @height: height of last picture
@@ -717,7 +723,6 @@ struct vdec_av1_slice_instance {
struct mtk_vcodec_mem cdf_temp;
struct mtk_vcodec_mem tile;
struct vdec_av1_slice_slot slots;
-   struct vdec_av1_slice_tile_group tile_group;
  
  	/* for resolution change and get_pic_info */

enum vdec_av1_slice_resolution_level level;
@@ -774,24 +779,28 @@ static int vdec_av1_slice_init_cdf_table(struct 
vdec_av1_slice_instance *instanc
  
  	ctx = instance->ctx;

vsi = instance->vpu.vsi;
-   remote_cdf_table = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler,
-(u32)vsi->cdf_table_addr);
-   if (IS_ERR(remote_cdf_table)) {
-   mtk_vdec_err(ctx, "failed to map cdf table\n");
-   return PTR_ERR(remote_cdf_table);
-   }
-
-   mtk_vdec_debug(ctx, "map cdf table to 0x%p\n", remote_cdf_table);
  
  	if (instance->cdf_table.va)

mtk_vcodec_mem_free(ctx, >cdf_table);
+   vsi->cdf_table_size = AV1_CDF_TABLE_SIZE;
+   mtk_vdec_debug(ctx, "svp %d. cdf table size 0x%x\n",
+  instance->ctx->is_secure_playback, vsi->cdf_table_size);
instance->cdf_table.size = vsi->cdf_table_size;
  
  	ret = mtk_vcodec_mem_alloc(ctx, >cdf_table);

if (ret)
return ret;
  
-	memcpy(instance->cdf_table.va, remote_cdf_table, vsi->cdf_table_size);

+   if (!instance->ctx->is_secure_playback) {
+   remote_cdf_table = 
mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler,
+
(u32)vsi->cdf_table_addr);
+   if (IS_ERR(remote_cdf_table)) {
+   mtk_vdec_err(ctx, "failed to map cdf table\n");
+   return PTR_ERR(remote_cdf_table);
+   }
+
+   memcpy(instance->cdf_table.va, remote_cdf_table, 
vsi->cdf_table_size);
+   }
  


In the original version mtk_vcodec_fw_map_dm_addr() is called before
mtk_vcodec_mem_alloc(), so if the former fails, the function terminates
early. After this patch is applied mtk_vcodec_mem_alloc() is called first and
when it is successful mtk_vcodec_fw_map_dm_addr() is called which may fail.
In case it fails maybe mtk_vcodec_mem_free() should be called before returning?


return 0;
  }
@@ -805,25 +814,26 @@ static int vdec_av1_slice_init_iq_table(struct 
vdec_av1_slice_instance *instance
  
  	ctx = instance->ctx;

vsi = instance->vpu.vsi;
-   remote_iq_table = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler,
-   (u32)vsi->iq_table_addr);
-   if (IS_ERR(remote_iq_table)) {
-   mtk_vdec_err(ctx, "failed to map iq table\n");
-   return PTR_ERR(remote_iq_table);
-   }
-
-   mtk_vdec_debug(ctx, "map iq table to 0x%p\n", 

Re: [PATCH v6,14/24] media: mediatek: vcodec: Add capture format to support one plane memory

2024-05-23 Thread Andrzej Pietrasiewicz

Hi,

I'm having second thoughts, please see inline,

W dniu 22.05.2024 o 14:26, Andrzej Pietrasiewicz pisze:

Hi Yunfei,

W dniu 16.05.2024 o 14:20, Yunfei Dong pisze:

Define one uncompressed capture format V4L2_PIX_FMT_MS21 in order to
support one plane memory. The buffer size is luma + chroma, luma is
stored at the start and chrome is stored at the end.

Signed-off-by: Yunfei Dong 
---
  Documentation/userspace-api/media/v4l/pixfmt-reserved.rst | 8 
  drivers/media/v4l2-core/v4l2-common.c | 2 ++
  drivers/media/v4l2-core/v4l2-ioctl.c  | 1 +
  include/uapi/linux/videodev2.h    | 1 +
  4 files changed, 12 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst 
b/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
index 886ba7b08d6b..6ec899649d50 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
@@ -295,6 +295,14 @@ please make a proposal on the linux-media mailing list.
    - Compressed format used by Nuvoton NPCM video driver. This format is
  defined in Remote Framebuffer Protocol (RFC 6143, chapter 7.7.4 
Hextile
  Encoding).
+    * .. _V4L2-PIX-FMT-MS21:
+
+  - ``V4L2_PIX_FMT_MS21``
+  - 'MS21'
+  - This format has one plane, luma and chroma are stored in a contiguous


Maybe s/one/single ?


+    memory. Luma pixel in 16x32 tiles at the start, chroma pixel in 16x16


maybe the word "pixel" is reduntant here? What else than pixels could tile 
sizes mean?
Any padding between luma and chroma?


+    tiles at the end. The image height must be aligned with 32 and the 
image
+    width must be aligned with 16.


Maybe aligned to?


  .. raw:: latex
  \normalsize
diff --git a/drivers/media/v4l2-core/v4l2-common.c 
b/drivers/media/v4l2-core/v4l2-common.c
index 4165c815faef..5ae54cf48dc7 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -271,6 +271,8 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
    .block_w = { 16, 8, 0, 0 }, .block_h = { 32, 16, 0, 0 }},
  { .format = V4L2_PIX_FMT_MT2110R, .pixel_enc = V4L2_PIXEL_ENC_YUV, 
.mem_planes = 2, .comp_planes = 2, .bpp = { 5, 10, 0, 0 }, .bpp_div = { 4, 4, 
1, 1 }, .hdiv = 2, .vdiv = 2,
    .block_w = { 16, 8, 0, 0 }, .block_h = { 32, 16, 0, 0 }},
+    { .format = V4L2_PIX_FMT_MS21, pixel_enc = V4L2_PIXEL_ENC_YUV, 
.mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 
1 }, .hdiv = 2, .vdiv = 2,
+  .block_w = { 16, 8, 0, 0 }, .block_h = { 32, 16, 0, 0 }},
  /* YUV planar formats */
  { .format = V4L2_PIX_FMT_NV12,    .pixel_enc = V4L2_PIXEL_ENC_YUV, 
.mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 
1 }, .hdiv = 2, .vdiv = 2 },
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 4c76d17b4629..3a68f2b9e7a4 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1529,6 +1529,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
  case V4L2_PIX_FMT_MT2110T:    descr = "Mediatek 10bit Tile Mode"; 
break;
  case V4L2_PIX_FMT_MT2110R:    descr = "Mediatek 10bit Raster Mode"; 
break;
  case V4L2_PIX_FMT_HEXTILE:    descr = "Hextile Compressed Format"; 
break;
+    case V4L2_PIX_FMT_MS21:    descr = "MediaTek One Plane Format"; 
break;


s/One/Single ?



On the other hand "single" would be [in this case incorrectly] associated with
single-planar API, which would be totally confusing.

Still, the reality you are trying to model is complex: you use
MPLANE, yet there's a single plane in case of secure playback.

Regards,

Andrzej



Regards,

Andrzej


  default:
  if (fmt->description[0])
  return;
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 89eb1a3c6555..7aff2f2c8f9c 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -800,6 +800,7 @@ struct v4l2_pix_format {
  #define V4L2_PIX_FMT_MM21 v4l2_fourcc('M', 'M', '2', '1') /* Mediatek 
8-bit block mode, two non-contiguous planes */
  #define V4L2_PIX_FMT_MT2110T  v4l2_fourcc('M', 'T', '2', 'T') /* Mediatek 
10-bit block tile mode */
  #define V4L2_PIX_FMT_MT2110R  v4l2_fourcc('M', 'T', '2', 'R') /* Mediatek 
10-bit block raster mode */
+#define V4L2_PIX_FMT_MS21 v4l2_fourcc('M', 'S', '2', '1') /* MediaTek 
8-bit block mode with one plane */
  #define V4L2_PIX_FMT_INZI v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar 
Greyscale 10-bit and Depth 16-bit */
  #define V4L2_PIX_FMT_CNF4 v4l2_fourcc('C', 'N', 'F', '4') /* Intel 4-bit 
packed depth confidence information */
  #define V4L2_PIX_FMT_HI240    v4l2_fourcc('H', 'I', '2', '4') /* BTTV 8-bit 
dithered RGB */






Re: [PATCH v6,14/24] media: mediatek: vcodec: Add capture format to support one plane memory

2024-05-22 Thread Andrzej Pietrasiewicz

Hi Yunfei,

W dniu 16.05.2024 o 14:20, Yunfei Dong pisze:

Define one uncompressed capture format V4L2_PIX_FMT_MS21 in order to
support one plane memory. The buffer size is luma + chroma, luma is
stored at the start and chrome is stored at the end.

Signed-off-by: Yunfei Dong 
---
  Documentation/userspace-api/media/v4l/pixfmt-reserved.rst | 8 
  drivers/media/v4l2-core/v4l2-common.c | 2 ++
  drivers/media/v4l2-core/v4l2-ioctl.c  | 1 +
  include/uapi/linux/videodev2.h| 1 +
  4 files changed, 12 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst 
b/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
index 886ba7b08d6b..6ec899649d50 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
@@ -295,6 +295,14 @@ please make a proposal on the linux-media mailing list.
- Compressed format used by Nuvoton NPCM video driver. This format is
  defined in Remote Framebuffer Protocol (RFC 6143, chapter 7.7.4 
Hextile
  Encoding).
+* .. _V4L2-PIX-FMT-MS21:
+
+  - ``V4L2_PIX_FMT_MS21``
+  - 'MS21'
+  - This format has one plane, luma and chroma are stored in a contiguous


Maybe s/one/single ?


+memory. Luma pixel in 16x32 tiles at the start, chroma pixel in 16x16


maybe the word "pixel" is reduntant here? What else than pixels could tile 
sizes mean?
Any padding between luma and chroma?


+tiles at the end. The image height must be aligned with 32 and the 
image
+width must be aligned with 16.


Maybe aligned to?


  .. raw:: latex
  
  \normalsize

diff --git a/drivers/media/v4l2-core/v4l2-common.c 
b/drivers/media/v4l2-core/v4l2-common.c
index 4165c815faef..5ae54cf48dc7 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -271,6 +271,8 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
  .block_w = { 16, 8, 0, 0 }, .block_h = { 32, 16, 0, 0 }},
{ .format = V4L2_PIX_FMT_MT2110R, .pixel_enc = 
V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 5, 10, 0, 0 }, 
.bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 2,
  .block_w = { 16, 8, 0, 0 }, .block_h = { 32, 16, 0, 0 }},
+   { .format = V4L2_PIX_FMT_MS21, pixel_enc = V4L2_PIXEL_ENC_YUV, 
.mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 
1 }, .hdiv = 2, .vdiv = 2,
+ .block_w = { 16, 8, 0, 0 }, .block_h = { 32, 16, 0, 0 }},
  
  		/* YUV planar formats */

{ .format = V4L2_PIX_FMT_NV12,.pixel_enc = 
V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, 
.bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 4c76d17b4629..3a68f2b9e7a4 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1529,6 +1529,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
case V4L2_PIX_FMT_MT2110T:  descr = "Mediatek 10bit Tile 
Mode"; break;
case V4L2_PIX_FMT_MT2110R:  descr = "Mediatek 10bit Raster 
Mode"; break;
case V4L2_PIX_FMT_HEXTILE:  descr = "Hextile Compressed 
Format"; break;
+   case V4L2_PIX_FMT_MS21: descr = "MediaTek One Plane 
Format"; break;


s/One/Single ?

Regards,

Andrzej


default:
if (fmt->description[0])
return;
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 89eb1a3c6555..7aff2f2c8f9c 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -800,6 +800,7 @@ struct v4l2_pix_format {
  #define V4L2_PIX_FMT_MM21 v4l2_fourcc('M', 'M', '2', '1') /* Mediatek 
8-bit block mode, two non-contiguous planes */
  #define V4L2_PIX_FMT_MT2110T  v4l2_fourcc('M', 'T', '2', 'T') /* Mediatek 
10-bit block tile mode */
  #define V4L2_PIX_FMT_MT2110R  v4l2_fourcc('M', 'T', '2', 'R') /* Mediatek 
10-bit block raster mode */
+#define V4L2_PIX_FMT_MS21 v4l2_fourcc('M', 'S', '2', '1') /* MediaTek 
8-bit block mode with one plane */
  #define V4L2_PIX_FMT_INZI v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar 
Greyscale 10-bit and Depth 16-bit */
  #define V4L2_PIX_FMT_CNF4 v4l2_fourcc('C', 'N', 'F', '4') /* Intel 4-bit 
packed depth confidence information */
  #define V4L2_PIX_FMT_HI240v4l2_fourcc('H', 'I', '2', '4') /* BTTV 8-bit 
dithered RGB */




Re: [PATCH v6,12/24] media: mediatek: vcodec: add interface to allocate/free secure memory

2024-05-22 Thread Andrzej Pietrasiewicz

Hi Yunfei,

W dniu 16.05.2024 o 14:20, Yunfei Dong pisze:

Need to call dma heap interface to allocate/free secure memory when playing
secure video.

Signed-off-by: Yunfei Dong 
---
  .../media/platform/mediatek/vcodec/Kconfig|   1 +
  .../mediatek/vcodec/common/mtk_vcodec_util.c  | 122 +-
  .../mediatek/vcodec/common/mtk_vcodec_util.h  |   3 +
  3 files changed, 123 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/mediatek/vcodec/Kconfig 
b/drivers/media/platform/mediatek/vcodec/Kconfig
index bc8292232530..707865703e61 100644
--- a/drivers/media/platform/mediatek/vcodec/Kconfig
+++ b/drivers/media/platform/mediatek/vcodec/Kconfig
@@ -17,6 +17,7 @@ config VIDEO_MEDIATEK_VCODEC
depends on VIDEO_MEDIATEK_VPU || !VIDEO_MEDIATEK_VPU
depends on MTK_SCP || !MTK_SCP
depends on MTK_SMI || (COMPILE_TEST && MTK_SMI=n)
+   depends on DMABUF_HEAPS
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
select VIDEO_MEDIATEK_VCODEC_VPU if VIDEO_MEDIATEK_VPU
diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c 
b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c
index c60e4c193b25..5958dcd7965a 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c
@@ -5,9 +5,11 @@
  * Tiffany Lin 
  */
  
+#include 

  #include 
  #include 
  #include 
+#include 
  
  #include "../decoder/mtk_vcodec_dec_drv.h"

  #include "../encoder/mtk_vcodec_enc_drv.h"
@@ -45,7 +47,7 @@ int mtk_vcodec_write_vdecsys(struct mtk_vcodec_dec_ctx *ctx, 
unsigned int reg,
  }
  EXPORT_SYMBOL(mtk_vcodec_write_vdecsys);
  
-int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem)

+static int mtk_vcodec_mem_alloc_nor(void *priv, struct mtk_vcodec_mem *mem)
  {
enum mtk_instance_type inst_type = *((unsigned int *)priv);
struct platform_device *plat_dev;
@@ -75,9 +77,71 @@ int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem 
*mem)
  
  	return 0;

  }
-EXPORT_SYMBOL(mtk_vcodec_mem_alloc);
  
-void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem)

+static int mtk_vcodec_mem_alloc_sec(struct mtk_vcodec_dec_ctx *ctx, struct 
mtk_vcodec_mem *mem)
+{
+   struct device *dev = >dev->plat_dev->dev;
+   struct dma_buf *dma_buffer;
+   struct dma_heap *vdec_heap;
+   struct dma_buf_attachment *attach;
+   struct sg_table *sgt;
+   unsigned long size = mem->size;
+   int ret = 0;
+
+   if (!size)
+   return -EINVAL;
+
+   vdec_heap = dma_heap_find("restricted_mtk_cma");
+   if (!vdec_heap) {
+   mtk_v4l2_vdec_err(ctx, "dma heap find failed!");
+   return -EPERM;
+   }
+
+   dma_buffer = dma_heap_buffer_alloc(vdec_heap, size, 
DMA_HEAP_VALID_FD_FLAGS,
+  DMA_HEAP_VALID_HEAP_FLAGS);
+   if (IS_ERR_OR_NULL(dma_buffer)) {
+   mtk_v4l2_vdec_err(ctx, "dma heap alloc size=0x%lx failed!", 
size);
+   return PTR_ERR(dma_buffer);
+   }
+
+   attach = dma_buf_attach(dma_buffer, dev);
+   if (IS_ERR_OR_NULL(attach)) {
+   mtk_v4l2_vdec_err(ctx, "dma attach size=0x%lx failed!", size);
+   ret = PTR_ERR(attach);
+   goto err_attach;
+   }
+
+   sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
+   if (IS_ERR_OR_NULL(sgt)) {
+   mtk_v4l2_vdec_err(ctx, "dma map attach size=0x%lx failed!", 
size);
+   ret = PTR_ERR(sgt);
+   goto err_sgt;
+   }
+
+   mem->va = dma_buffer;
+   mem->dma_addr = (dma_addr_t)sg_dma_address((sgt)->sgl);
+
+   if (!mem->va || !mem->dma_addr) {
+   mtk_v4l2_vdec_err(ctx, "dma buffer size=0x%lx failed!", size);
+   ret = -EPERM;
+   goto err_addr;
+   }
+
+   mem->attach = attach;
+   mem->sgt = sgt;
+
+   return 0;
+err_addr:
+   dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
+err_sgt:
+   dma_buf_detach(dma_buffer, attach);
+err_attach:
+   dma_buf_put(dma_buffer);
+
+   return ret;
+}
+
+static void mtk_vcodec_mem_free_nor(void *priv, struct mtk_vcodec_mem *mem)
  {
enum mtk_instance_type inst_type = *((unsigned int *)priv);
struct platform_device *plat_dev;
@@ -110,6 +174,57 @@ void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem 
*mem)
mem->dma_addr = 0;
mem->size = 0;
  }
+
+static void mtk_vcodec_mem_free_sec(struct mtk_vcodec_mem *mem)
+{
+   if (mem->sgt)
+   dma_buf_unmap_attachment(mem->attach, mem->sgt, 
DMA_BIDIRECTIONAL);


is (!mem->sgt) possible at all here?

In mtk_vcodec_mem_alloc_sec() "if (IS_ERR_OR_NULL(sgt))" triggers an
error recovery path and the allocation fails. Do you ever try to free_sec()
a failed allocation?


+   dma_buf_detach((struct dma_buf *)mem->va, mem->attach);
+ 

Re: [PATCH v6,04/24] v4l: add documentation for restricted memory flag

2024-05-22 Thread Andrzej Pietrasiewicz

Hi Yunfei & Jeffrey,

W dniu 16.05.2024 o 14:20, Yunfei Dong pisze:

From: Jeffrey Kardatzke 

Adds documentation for V4L2_MEMORY_FLAG_RESTRICTED.



Why not in the patch where the flag is actually being added?
From that commit until this commit it would be undocumented.

While at it...


Signed-off-by: Jeffrey Kardatzke 
Signed-off-by: Yunfei Dong 
---
  Documentation/userspace-api/media/v4l/buffer.rst | 10 +-
  1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/Documentation/userspace-api/media/v4l/buffer.rst 
b/Documentation/userspace-api/media/v4l/buffer.rst
index 52bbee81c080..807e43bfed2b 100644
--- a/Documentation/userspace-api/media/v4l/buffer.rst
+++ b/Documentation/userspace-api/media/v4l/buffer.rst
@@ -696,7 +696,7 @@ enum v4l2_memory
  
  .. _memory-flags:
  
-Memory Consistency Flags

+Memory Flags
  
  
  .. raw:: latex

@@ -728,6 +728,14 @@ Memory Consistency Flags
only if the buffer is used for :ref:`memory mapping ` I/O and the
queue reports the :ref:`V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS
` capability.
+* .. _`V4L2-MEMORY-FLAG-RESTRICTED`:
+
+  - ``V4L2_MEMORY_FLAG_RESTRICTED``
+  - 0x0002
+  - The queued buffers are expected to be in restricted memory. If not, an
+   error will be returned. This flag can only be used with 
``V4L2_MEMORY_DMABUF``.
+   Typically restricted buffers are allocated using a restricted dma-heap. 
This flag
+   can only be specified if the ``V4L2_BUF_CAP_SUPPORTS_RESTRICTED_MEM`` 
is set.


is V4L2_BUF_CAP_SUPPORTS_RESTRICTED_MEM documented? Can it be referenced here
in a way similar to how V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS is?

Regards,

Andrzej

  
  .. raw:: latex
  




Re: [PATCH v6,09/24] media: mediatek: vcodec: allocate tee share memory

2024-05-22 Thread Andrzej Pietrasiewicz

Hi Yunfei,

W dniu 16.05.2024 o 14:20, Yunfei Dong pisze:

Allocate two share memory for each lat and core hardware used to share
information with optee-os. Msg buffer used to send ipi command and get ack
command with optee-os, data buffer used to store vsi information which
used for hardware decode.

Signed-off-by: Yunfei Dong 
---
  .../vcodec/decoder/mtk_vcodec_dec_optee.c | 80 ++-
  .../vcodec/decoder/mtk_vcodec_dec_optee.h | 32 
  2 files changed, 111 insertions(+), 1 deletion(-)

diff --git 
a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.c 
b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.c
index 38d9c1c1785a..611fb0e56480 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.c
@@ -47,13 +47,69 @@ int mtk_vcodec_dec_optee_private_init(struct 
mtk_vcodec_dec_dev *vcodec_dev)
  }
  EXPORT_SYMBOL_GPL(mtk_vcodec_dec_optee_private_init);
  
+static void mtk_vcodec_dec_optee_deinit_memref(struct mtk_vdec_optee_ca_info *ca_info,

+  enum mtk_vdec_optee_data_index 
data_index)
+{
+   tee_shm_free(ca_info->shm_memref[data_index].msg_shm);
+}
+
+static int mtk_vcodec_dec_optee_init_memref(struct tee_context *tee_vdec_ctx,
+   struct mtk_vdec_optee_ca_info 
*ca_info,
+   enum mtk_vdec_optee_data_index 
data_index)
+{
+   struct mtk_vdec_optee_shm_memref *shm_memref;
+   int alloc_size = 0, err = 0;
+   u64 shm_param_type = 0;
+   bool copy_buffer;
+
+   switch (data_index) {
+   case OPTEE_MSG_INDEX:
+   shm_param_type = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT;
+   alloc_size = MTK_VDEC_OPTEE_MSG_SIZE;
+   copy_buffer = true;
+   break;
+   case OPTEE_DATA_INDEX:
+   shm_param_type = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT;
+   alloc_size = MTK_VDEC_OPTEE_HW_SIZE;
+   copy_buffer = false;
+   break;
+   default:
+   pr_err(MTK_DBG_VCODEC_STR "tee invalid data_index: %d.\n", 
data_index);
+   return -EINVAL;
+   }
+
+   shm_memref = _info->shm_memref[data_index];
+
+   /* Allocate dynamic shared memory with decoder TA */
+   shm_memref->msg_shm_size = alloc_size;
+   shm_memref->param_type = shm_param_type;
+   shm_memref->copy_to_ta = copy_buffer;
+   shm_memref->msg_shm = tee_shm_alloc_kernel_buf(tee_vdec_ctx, 
shm_memref->msg_shm_size);
+   if (IS_ERR(shm_memref->msg_shm)) {
+   pr_err(MTK_DBG_VCODEC_STR "tee alloc buf fail: 
data_index:%d.\n", data_index);
+   return -ENOMEM;
+   }
+
+   shm_memref->msg_shm_ca_buf = tee_shm_get_va(shm_memref->msg_shm, 0);
+   if (IS_ERR(shm_memref->msg_shm_ca_buf)) {
+   pr_err(MTK_DBG_VCODEC_STR "tee get shm va fail: 
data_index:%d.\n", data_index);
+   err = PTR_ERR(shm_memref->msg_shm_ca_buf);
+   goto err_get_msg_va;
+   }
+
+   return err;


Anything other than a zero possible here? In error-free exectution the return
value of zero is set far away from here. And then both error-free execution
and error recovery end in "return err;" which looks kind of weird to me.
Maybe that's just my personal preference, but I'd prefer "return 0;" here.
Alternatively, maybe rename "err" as "ret"? This applies to all patches.

I wouldn't mind a blank line here to visually separate the error recovery path
from error-free execution. This applies to all patches.


+err_get_msg_va:
+   tee_shm_free(shm_memref->msg_shm);
+   return err;
+}
+
  static int mtk_vcodec_dec_optee_init_hw_info(struct mtk_vdec_optee_private 
*optee_private,
 enum mtk_vdec_hw_id hardware_index)
  {
struct device *dev = _private->vcodec_dev->plat_dev->dev;
struct tee_ioctl_open_session_arg session_arg;
struct mtk_vdec_optee_ca_info *ca_info;
-   int err = 0, session_func;
+   int err, i, j, session_func;
  
  	/* Open lat and core session with vdec TA. */

switch (hardware_index) {
@@ -87,6 +143,24 @@ static int mtk_vcodec_dec_optee_init_hw_info(struct 
mtk_vdec_optee_private *opte
dev_dbg(dev, MTK_DBG_VCODEC_STR "open vdec tee session hw_id:%d 
session_id=%x.\n",
hardware_index, ca_info->vdec_session_id);
  
+	/* Allocate dynamic shared memory with decoder TA */

+   for (i = 0; i < OPTEE_MAX_INDEX; i++) {
+   err = 
mtk_vcodec_dec_optee_init_memref(optee_private->tee_vdec_ctx, ca_info, i);
+   if (err) {
+   dev_err(dev, MTK_DBG_VCODEC_STR "init vdec memref failed: 
%d.\n", i);
+   goto err_init_memref;
+   }
+   }
+
+   return err;
+err_init_memref:
+

Re: [PATCH v6, 10/24] media: mediatek: vcodec: send share memory data to optee

2024-05-22 Thread Andrzej Pietrasiewicz

Hi Yunfei & Jeffrey,

W dniu 16.05.2024 o 14:20, Yunfei Dong pisze:

Setting msg and vsi information to shared buffer, then call tee invoke
function to send it to optee-os.

Signed-off-by: Yunfei Dong 
---
  .../vcodec/decoder/mtk_vcodec_dec_optee.c | 140 ++
  .../vcodec/decoder/mtk_vcodec_dec_optee.h |  51 +++
  2 files changed, 191 insertions(+)

diff --git 
a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.c 
b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.c
index 611fb0e56480..f29a8d143fee 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.c
@@ -241,3 +241,143 @@ void mtk_vcodec_dec_optee_release(struct 
mtk_vdec_optee_private *optee_private)
mutex_unlock(_private->tee_mutex);
  }
  EXPORT_SYMBOL_GPL(mtk_vcodec_dec_optee_release);
+
+static int mtk_vcodec_dec_optee_fill_shm(struct tee_param *command_params,
+struct mtk_vdec_optee_shm_memref 
*shm_memref,
+struct mtk_vdec_optee_data_to_shm 
*data,
+int index, struct device *dev)
+{
+   if (!data->msg_buf_size[index] || !data->msg_buf[index]) {
+   pr_err(MTK_DBG_VCODEC_STR "tee invalid buf param: %d.\n", 
index);
+   return -EINVAL;
+   }
+
+   *command_params = (struct tee_param) {
+   .attr = shm_memref->param_type,
+   .u.memref = {
+   .shm = shm_memref->msg_shm,
+   .size = data->msg_buf_size[index],
+   .shm_offs = 0,
+   },
+   };
+
+   if (!shm_memref->copy_to_ta) {
+   dev_dbg(dev, MTK_DBG_VCODEC_STR "share memref data: 0x%x 
param_type:%llu.\n",
+   *((unsigned int *)shm_memref->msg_shm_ca_buf), 
shm_memref->param_type);
+   return 0;
+   }
+
+   memset(shm_memref->msg_shm_ca_buf, 0, shm_memref->msg_shm_size);
+   memcpy(shm_memref->msg_shm_ca_buf, data->msg_buf[index], 
data->msg_buf_size[index]);
+
+   dev_dbg(dev, MTK_DBG_VCODEC_STR "share memref data => msg id:0x%x 0x%x 
param_type:%llu.\n",
+   *((unsigned int *)data->msg_buf[index]),
+   *((unsigned int *)shm_memref->msg_shm_ca_buf),
+   shm_memref->param_type);
+
+   return 0;
+}
+
+void mtk_vcodec_dec_optee_set_data(struct mtk_vdec_optee_data_to_shm *data,
+  void *buf, int buf_size,
+  enum mtk_vdec_optee_data_index index)
+{
+   data->msg_buf[index] = buf;
+   data->msg_buf_size[index] = buf_size;
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_optee_set_data);
+
+int mtk_vcodec_dec_optee_invokd_cmd(struct mtk_vdec_optee_private 
*optee_private,
+   enum mtk_vdec_hw_id hw_id,
+   struct mtk_vdec_optee_data_to_shm *data)
+{
+   struct device *dev = _private->vcodec_dev->plat_dev->dev;
+   struct tee_ioctl_invoke_arg trans_args;
+   struct tee_param command_params[MTK_OPTEE_MAX_TEE_PARAMS];
+   struct mtk_vdec_optee_ca_info *ca_info;
+   struct mtk_vdec_optee_shm_memref *shm_memref;
+   int ret, index;
+
+   if (hw_id == MTK_VDEC_LAT0)
+   ca_info = _private->lat_ca;
+   else
+   ca_info = _private->core_ca;


You seem to be using this in several places. Maybe create a helper?

static inline struct mtk_vdec_optee_ca_info *get_ca_info(
struct mtk_vdec_optee_private *optee_private,
enum mtk_vdec_hw_id hw_id)
{
return hw_id == MTK_VDEC_LAT0 ?
_private->lat_ca : _private->core_ca;
}

(you want to clean up the line breaks in this suggested function)

and then

ca_info = get_ca_info(optee_private, hw_id);


+
+   memset(_args, 0, sizeof(trans_args));
+   memset(command_params, 0, sizeof(command_params));
+
+   trans_args = (struct tee_ioctl_invoke_arg) {
+   .func = ca_info->vdec_session_func,
+   .session = ca_info->vdec_session_id,
+   .num_params = MTK_OPTEE_MAX_TEE_PARAMS,
+   };
+
+   /* Fill msg command parameters */
+   for (index = 0; index < MTK_OPTEE_MAX_TEE_PARAMS; index++) {
+   shm_memref = _info->shm_memref[index];
+
+   if (shm_memref->param_type == TEE_IOCTL_PARAM_ATTR_TYPE_NONE ||
+   data->msg_buf_size[index] == 0)
+   continue;
+
+   dev_dbg(dev, MTK_DBG_VCODEC_STR "tee share memory data size: %d -> 
%d.\n",
+   data->msg_buf_size[index], shm_memref->msg_shm_size);
+
+   if (data->msg_buf_size[index] > shm_memref->msg_shm_size) {
+   dev_err(dev, MTK_DBG_VCODEC_STR "tee buf size big than shm (%d 
-> %d).\n",


s/big/bigger ? Or 

Re: [PATCH v6,08/24] media: mediatek: vcodec: add tee client interface to communiate with optee-os

2024-05-22 Thread Andrzej Pietrasiewicz

Hi Yunfei & Jeffrey,

W dniu 16.05.2024 o 14:20, Yunfei Dong pisze:

Open tee context to initialize the environment in order to communication
with optee-os, then open tee session as the communication pipeline for
lat and core to send data for hardware decode.

Signed-off-by: Yunfei Dong 
---
  .../platform/mediatek/vcodec/decoder/Makefile |   1 +
  .../vcodec/decoder/mtk_vcodec_dec_drv.h   |   5 +
  .../vcodec/decoder/mtk_vcodec_dec_optee.c | 165 ++
  .../vcodec/decoder/mtk_vcodec_dec_optee.h |  73 
  4 files changed, 244 insertions(+)
  create mode 100644 
drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.c
  create mode 100644 
drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.h

diff --git a/drivers/media/platform/mediatek/vcodec/decoder/Makefile 
b/drivers/media/platform/mediatek/vcodec/decoder/Makefile
index 904cd22def84..1624933dfd5e 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/Makefile
+++ b/drivers/media/platform/mediatek/vcodec/decoder/Makefile
@@ -21,5 +21,6 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
mtk_vcodec_dec_stateful.o \
mtk_vcodec_dec_stateless.o \
mtk_vcodec_dec_pm.o \
+   mtk_vcodec_dec_optee.o \
  
  mtk-vcodec-dec-hw-y := mtk_vcodec_dec_hw.o

diff --git 
a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h 
b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
index f975db4293da..76a0323f993c 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
@@ -11,6 +11,7 @@
  #include "../common/mtk_vcodec_dbgfs.h"
  #include "../common/mtk_vcodec_fw_priv.h"
  #include "../common/mtk_vcodec_util.h"
+#include "mtk_vcodec_dec_optee.h"
  #include "vdec_msg_queue.h"
  
  #define MTK_VCODEC_DEC_NAME	"mtk-vcodec-dec"

@@ -261,6 +262,8 @@ struct mtk_vcodec_dec_ctx {
   * @dbgfs: debug log related information
   *
   * @chip_name: used to distinguish platforms and select the correct codec 
configuration values
+ *
+ * @optee_private: optee private data
   */
  struct mtk_vcodec_dec_dev {
struct v4l2_device v4l2_dev;
@@ -303,6 +306,8 @@ struct mtk_vcodec_dec_dev {
struct mtk_vcodec_dbgfs dbgfs;
  
  	enum mtk_vcodec_dec_chip_name chip_name;

+
+   struct mtk_vdec_optee_private *optee_private;
  };
  
  static inline struct mtk_vcodec_dec_ctx *fh_to_dec_ctx(struct v4l2_fh *fh)

diff --git 
a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.c 
b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.c
new file mode 100644
index ..38d9c1c1785a
--- /dev/null
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.c
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 MediaTek Inc.
+ * Author: Yunfei Dong 
+ */
+
+#include "mtk_vcodec_dec_drv.h"
+#include "mtk_vcodec_dec_optee.h"
+
+/*
+ * Randomly generated, and must correspond to the GUID on the TA side.
+ */
+static const uuid_t mtk_vdec_lat_uuid =
+   UUID_INIT(0xBC50D971, 0xD4C9, 0x42C4,
+ 0x82, 0xCB, 0x34, 0x3F, 0xB7, 0xF3, 0x78, 0x90);
+
+static const uuid_t mtk_vdec_core_uuid =
+   UUID_INIT(0xBC50D971, 0xD4C9, 0x42C4,
+ 0x82, 0xCB, 0x34, 0x3F, 0xB7, 0xF3, 0x78, 0x91);
+
+/*
+ * Check whether this driver supports decoder TA in the TEE instance,
+ * represented by the params (ver/data) of this function.
+ */
+static int mtk_vcodec_dec_optee_match(struct tee_ioctl_version_data *ver_data, 
const void *not_used)
+{
+   if (ver_data->impl_id == TEE_IMPL_ID_OPTEE)
+   return 1;
+   else
+   return 0;


maybe:

return ver_data->impl_id == TEE_IMPL_ID_OPTEE;


+}
+
+int mtk_vcodec_dec_optee_private_init(struct mtk_vcodec_dec_dev *vcodec_dev)
+{
+   vcodec_dev->optee_private = devm_kzalloc(_dev->plat_dev->dev,
+
sizeof(*vcodec_dev->optee_private),
+GFP_KERNEL);
+   if (!vcodec_dev->optee_private)
+   return -ENOMEM;
+
+   vcodec_dev->optee_private->vcodec_dev = vcodec_dev;
+
+   atomic_set(_dev->optee_private->tee_active_cnt, 0);
+   mutex_init(_dev->optee_private->tee_mutex);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_optee_private_init);
+
+static int mtk_vcodec_dec_optee_init_hw_info(struct mtk_vdec_optee_private 
*optee_private,
+enum mtk_vdec_hw_id hardware_index)
+{
+   struct device *dev = _private->vcodec_dev->plat_dev->dev;
+   struct tee_ioctl_open_session_arg session_arg;
+   struct mtk_vdec_optee_ca_info *ca_info;
+   int err = 0, session_func;
+
+   /* Open lat and core session with vdec TA. */
+   switch (hardware_index) {
+   case MTK_VDEC_LAT0:
+   

Re: [PATCH v6,02/24] v4l2: handle restricted memory flags in queue setup

2024-05-22 Thread Andrzej Pietrasiewicz

Hi Yunfei & Jeffrey,

W dniu 16.05.2024 o 14:20, Yunfei Dong pisze:

From: Jeffrey Kardatzke 

Validates the restricted memory flags when setting up a queue and
ensures the queue has the proper capability.

Signed-off-by: Jeffrey Kardatzke 
Signed-off-by: Yunfei Dong 
---
  .../media/common/videobuf2/videobuf2-core.c   | 21 +++
  .../media/common/videobuf2/videobuf2-v4l2.c   |  4 +++-
  2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/media/common/videobuf2/videobuf2-core.c 
b/drivers/media/common/videobuf2/videobuf2-core.c
index 358f1fe42975..fe4c0594ab81 100644
--- a/drivers/media/common/videobuf2/videobuf2-core.c
+++ b/drivers/media/common/videobuf2/videobuf2-core.c
@@ -831,6 +831,15 @@ static bool verify_coherency_flags(struct vb2_queue *q, 
bool non_coherent_mem)
return true;
  }
  
+static bool verify_restricted_mem_flags(struct vb2_queue *q, bool restricted_mem)

+{
+   if (restricted_mem != q->restricted_mem) {
+   dprintk(q, 1, "restricted memory model mismatch\n");
+   return false;
+   }
+   return true;
+}
+
  static int vb2_core_allocated_buffers_storage(struct vb2_queue *q)
  {
if (!q->bufs)
@@ -864,6 +873,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory 
memory,
unsigned int q_num_bufs = vb2_get_num_buffers(q);
unsigned plane_sizes[VB2_MAX_PLANES] = { };
bool non_coherent_mem = flags & V4L2_MEMORY_FLAG_NON_COHERENT;
+   bool restricted_mem = flags & V4L2_MEMORY_FLAG_RESTRICTED;
unsigned int i, first_index;
int ret = 0;
  
@@ -907,6 +917,9 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,

return 0;
}
  
+	if (restricted_mem && (!q->allow_restricted_mem || memory != VB2_MEMORY_DMABUF))

+   return -EINVAL;
+
/*
 * Make sure the requested values and current defaults are sane.
 */
@@ -924,6 +937,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory 
memory,
if (ret)
return ret;
set_queue_coherency(q, non_coherent_mem);
+   q->restricted_mem = restricted_mem;
  
  	/*

 * Ask the driver how many buffers and planes per buffer it requires.
@@ -1032,6 +1046,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum 
vb2_memory memory,
unsigned plane_sizes[VB2_MAX_PLANES] = { };
bool non_coherent_mem = flags & V4L2_MEMORY_FLAG_NON_COHERENT;
unsigned int q_num_bufs = vb2_get_num_buffers(q);
+   bool restricted_mem = flags & V4L2_MEMORY_FLAG_RESTRICTED;
bool no_previous_buffers = !q_num_bufs;
int ret = 0;
  
@@ -1040,6 +1055,9 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,

return -ENOBUFS;
}
  
+	if (restricted_mem && (!q->allow_restricted_mem || memory != VB2_MEMORY_DMABUF))

+   return -EINVAL;
+


This condition is repeated in another place. If it is ever to be
changed, the person changing it must remember to look at both
places. Maybe:

static inline int restricted_mem_mismatch(bool restricted_mem,
struct vb2_queue *q, enum vb2_memory memory)
{
return restricted_mem &&
(!q->allow_restricted_mem || memory != VB2_MEMORY_DMABUF) ?
-1 : 0;
}

(you probably want to clean up line breaks)

and:

if (restricted_mem_mismatch(restricted_mem, q, memory))
return -EINVAL;

Regards,

Andrzej


if (no_previous_buffers) {
if (q->waiting_in_dqbuf && *count) {
dprintk(q, 1, "another dup()ped fd is waiting for a 
buffer\n");
@@ -1058,6 +1076,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum 
vb2_memory memory,
return ret;
q->waiting_for_buffers = !q->is_output;
set_queue_coherency(q, non_coherent_mem);
+   q->restricted_mem = restricted_mem;
} else {
if (q->memory != memory) {
dprintk(q, 1, "memory model mismatch\n");
@@ -1065,6 +1084,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum 
vb2_memory memory,
}
if (!verify_coherency_flags(q, non_coherent_mem))
return -EINVAL;
+   if (!verify_restricted_mem_flags(q, restricted_mem))
+   return -EINVAL;
}
  
  	num_buffers = min(*count, q->max_num_buffers - q_num_bufs);

diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c 
b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index 293f3d5f1c4e..9ee24e537e0c 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -682,7 +682,7 @@ static void vb2_set_flags_and_caps(struct vb2_queue *q, u32 
memory,
*flags = 0;
} else {
/* Clear all unknown flags. */
-   *flags 

Re: [PATCH v2 0/3] usb: gadget: functionfs: DMABUF import interface

2023-03-31 Thread Andrzej Pietrasiewicz

Hi Paul,

W dniu 22.03.2023 o 10:21, Paul Cercueil pisze:

Hi,

This small patchset adds three new IOCTLs that can be used to attach,
detach, or transfer from/to a DMABUF object.

Changes since v1:
- patch [2/3] is new. I had to reuse a piece of code that was already
   duplicated in the driver, so I factorized the code.
- Make ffs_dma_resv_lock() static
- Add MODULE_IMPORT_NS(DMA_BUF);
- The attach/detach functions are now performed without locking the
   eps_lock spinlock. The transfer function starts with the spinlock
   unlocked, then locks it before allocating and queueing the USB
   transfer.



Can you share an example use case for these new features?
Is there a userspace that excercises the new ioctls?

Regards,

Andrzej


Re: [RFC PATCH v6] media: mediatek: vcodec: support stateless AV1 decoder

2022-11-29 Thread Andrzej Pietrasiewicz
= ctrl_quant->delta_q_v_ac;
+quant->qm_y = ctrl_quant->qm_y;
+quant->qm_u = ctrl_quant->qm_u;
+quant->qm_v = ctrl_quant->qm_v;


Can a common struct be introduced to hold these parameters?
And then copied in one go?

Maybe there's a good reason the code is the way it is now. However,
a series of "dumb" assignments (no value modifications) makes me
wonder.

  +cdef->cdef_y_strength[i] =

+ctrl_cdef->y_pri_strength[i] <<

SECONDARY_FILTER_STRENGTH_NUM_BITS |

+ctrl_cdef->y_sec_strength[i];
+cdef->cdef_uv_strength[i] =
+ctrl_cdef->uv_pri_strength[i] <<

SECONDARY_FILTER_STRENGTH_NUM_BITS |

+ctrl_cdef->uv_sec_strength[i];
+}
+}


Both vdec_av1_slice_setup_lf() and vdec_av1_slice_setup_cdef():

I'm wondering if the user of struct vdec_av1_slice_loop_filter and
struct
vdec_av1_slice_cdef could work with the uAPI variants of these structs?
Is there
a need for driver-specific mutations? (Maybe there is, the driver's
author
should know).

-->1.There is a mediatek map structure in kernel part which also has
the same structure in micro-processor.
2.Uapi v4l2 structure will not access in micro-processor, and mediatek
driver structure may not be all the same with v4l2.

so these will not need to change.


You know your hardware. If you say so, you must be right.



6.

+/* bs NULL means flush decoder */
+if (!bs)
+return vdec_av1_slice_flush(h_vdec, bs, fb, res_chg);
+
+lat_buf = vdec_msg_queue_dqbuf(>msg_queue.lat_ctx);
+if (!lat_buf) {
+mtk_vcodec_err(instance, "failed to get AV1 lat buf\n");


there exists vdec_msg_queue_deinit(). Should it be called in this (and
subsequent) error recovery path(s)?


+return -EBUSY;
+}


-->vdec_msg_queue_deinit is called when do deinit operation before stop
streaming.
But here is just error handle for current frame,  so it shouldnot call
vdec_msg_queue_deinit here.


This is confusing. It would be better if vdec_msg_queue_deinit() were
called from another place, not from the function which is called
per-frame. The "mirror location" for "before stop streaming" seems
"after start streaming", but I don't know.



7.

+src = v4l2_m2m_next_src_buf(instance->ctx->m2m_ctx);
+if (!src)
+return -EINVAL;
+
+lat_buf->src_buf_req = src->vb2_buf.req_obj.req;
+dst = _buf->ts_info;


the "ts_info" actually contains a struct vb2_v4l2_buffer. Why such a
name?

-->"ts_info" is not named by me, and i just use it here, so i will not
rename it.



fair enough


I ask the owner why it is named with ts_info and the answer is:
"This parame is used to store timestamp releated information from
output queue to capture queue."


So you reached out to the author of the "ts_info" name.
I haven't seen you asking here (maybe I haven't noticed?).
It is better to ask such a question in the mailing list rather than
in a private message.



8.

+/* frame header */
+ctrl_fh = (struct v4l2_ctrl_av1_frame *)
+  vdec_av1_get_ctrl_ptr(instance->ctx,
+V4L2_CID_STATELESS_AV1_FRAME);
+if (IS_ERR(ctrl_fh))
+return PTR_ERR(ctrl_fh);
+
+ctrl_seq = (struct v4l2_ctrl_av1_sequence *)
+   vdec_av1_get_ctrl_ptr(instance->ctx,
+ V4L2_CID_STATELESS_AV1_SEQUENCE);
+if (IS_ERR(ctrl_seq))
+return PTR_ERR(ctrl_seq);


Just to make sure: I assume request api is used? If so, does vdec's
framework
ensure that v4l2_ctrl_request_setup() has been called? It influences
what's
actually in ctrl->p_cur.p (current or previous value), and the
vdec_av1_get_ctrl_ptr() wrapper returns ctrl->p_cur.p.

-->v4l2_ctrl_request_setup() is called in  mtk_vdec_worker which is
before this function.



great


Thanks
Best Regards
xiaoyong Lu



Please avoid top-posting. It is easier for your reviewer to read your answers
inline. And, actually, it is easier for you not having to find the relevant
fragments, copy and then paste on top. Instead, try answering just below
reviewer's comments.

Also, when communicating on the mailing list eliminate the footer
which makes the readers wonder if they are allowed to read your
messages.

Regards,

Andrzej



On Thu, 2022-11-17 at 13:42 +0100, Andrzej Pietrasiewicz wrote:

Hi Xiaoyong Lu,

Sorry about chiming in only at v6. Please see inline below.

Andrzej

W dniu 17.11.2022 o 07:17, Xiaoyong Lu pisze:
> Add mediatek av1 decoder linux driver which use the stateless API
> in
> MT8195.
> 
> Signed-off-by: Xiaoyong Lu

> ---
> Changes from v5:
> 
> - change av1 PROFILE and LEVEL cfg

> - test by av1 fluster, result is 173/239
> 
> Changes from v4:
> 
> - convert vb2_find_timestamp to vb2_find_buffer

> - test by av1 fluster, result is 173/239
> 
> Changes from v3

Re: [RFC PATCH v6] media: mediatek: vcodec: support stateless AV1 decoder

2022-11-18 Thread Andrzej Pietrasiewicz

Hi again,

W dniu 17.11.2022 o 13:42, Andrzej Pietrasiewicz pisze:

Hi Xiaoyong Lu,

Sorry about chiming in only at v6. Please see inline below.

Andrzej

W dniu 17.11.2022 o 07:17, Xiaoyong Lu pisze:

Add mediatek av1 decoder linux driver which use the stateless API in
MT8195.

Signed-off-by: Xiaoyong Lu
---
Changes from v5:

- change av1 PROFILE and LEVEL cfg
- test by av1 fluster, result is 173/239

Changes from v4:

- convert vb2_find_timestamp to vb2_find_buffer
- test by av1 fluster, result is 173/239

Changes from v3:

- modify comment for struct vdec_av1_slice_slot
- add define SEG_LVL_ALT_Q
- change use_lr/use_chroma_lr parse from av1 spec
- use ARRAY_SIZE to replace size for loop_filter_level and 
loop_filter_mode_deltas

- change array size of loop_filter_mode_deltas from 4 to 2
- add define SECONDARY_FILTER_STRENGTH_NUM_BITS
- change some hex values from upper case to lower case
- change *dpb_sz equal to V4L2_AV1_TOTAL_REFS_PER_FRAME + 1
- test by av1 fluster, result is 173/239

Changes from v2:

- Match with av1 uapi v3 modify
- test by av1 fluster, result is 173/239

---
Reference series:
[1]: v3 of this series is presend by Daniel Almeida.
  message-id: 20220825225312.564619-1-daniel.alme...@collabora.com

  .../media/platform/mediatek/vcodec/Makefile   |    1 +
  .../vcodec/mtk_vcodec_dec_stateless.c |   47 +-
  .../platform/mediatek/vcodec/mtk_vcodec_drv.h |    1 +
  .../vcodec/vdec/vdec_av1_req_lat_if.c | 2234 +
  .../platform/mediatek/vcodec/vdec_drv_if.c    |    4 +
  .../platform/mediatek/vcodec/vdec_drv_if.h    |    1 +
  .../platform/mediatek/vcodec/vdec_msg_queue.c |   27 +
  .../platform/mediatek/vcodec/vdec_msg_queue.h |    4 +
  8 files changed, 2318 insertions(+), 1 deletion(-)
  create mode 100644 
drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c







+
+static void *vdec_av1_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id)
+{
+    struct v4l2_ctrl *ctrl = v4l2_ctrl_find(>ctrl_hdl, id);
+
+    if (!ctrl)
+    return ERR_PTR(-EINVAL);
+
+    return ctrl->p_cur.p;
+}


I see we keep repeating this kind of a v4l2_ctrl_find() wrapper in drivers.
The only reason this code cannot be factored out is the "context" struct pointer
pointing at structs of different types. Maybe we could

#define v4l2_get_ctrl_ptr(ctx, member, id) \
 __v4l2_get_ctrl_ptr((ctx), offsetof(typeof(*ctx), (member)), (id))

void *__v4l2_get_ctrl_ptr(void *ctx, size_t offset, u32 id)
{
 struct v4l2_ctrl_handler *hdl = (struct v4l2_ctrl_handler *)(ctx + offset);
 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, id);

 if (!ctrl)
     return ERR_PTR(-EINVAL);

 return ctrl->p_cur.p;
}

and reuse v4l2_get_ctrl_ptr() in drivers?

A similar kind of void* arithmetic happens in container_of, only with '-'.



When I think of it it seems a bit over-engineered to me now, it would
be better to give up the macro and simply pass struct v4l2_ctrl_handler *hdl.

Another second thought is that including such a wrapper in this patch
would make it too noisy if all potential users were to be updated.
A separate series would make more sense.

Regards,

Andrzej



Re: [RFC PATCH v7] media: mediatek: vcodec: support stateless AV1 decode

2022-11-17 Thread Andrzej Pietrasiewicz

Hi,

Did you receive my comments for v6?

Regards,

Andrzej

W dniu 17.11.2022 o 10:43, Xiaoyong Lu pisze:

Add mediatek av1 decoder linux driver which use the stateless API in
MT8195.

Signed-off-by: Xiaoyong Lu
---
Changes from v6:

- change slot_id type from u8 to s8
- test by av1 fluster, result is 173/239

Changes from v5:

- change av1 PROFILE and LEVEL cfg
- test by av1 fluster, result is 173/239

Changes from v4:

- convert vb2_find_timestamp to vb2_find_buffer
- test by av1 fluster, result is 173/239

Changes from v3:

- modify comment for struct vdec_av1_slice_slot
- add define SEG_LVL_ALT_Q
- change use_lr/use_chroma_lr parse from av1 spec
- use ARRAY_SIZE to replace size for loop_filter_level and 
loop_filter_mode_deltas
- change array size of loop_filter_mode_deltas from 4 to 2
- add define SECONDARY_FILTER_STRENGTH_NUM_BITS
- change some hex values from upper case to lower case
- change *dpb_sz equal to V4L2_AV1_TOTAL_REFS_PER_FRAME + 1
- test by av1 fluster, result is 173/239

Changes from v2:

- Match with av1 uapi v3 modify
- test by av1 fluster, result is 173/239

---
Reference series:
[1]: v3 of this series is presend by Daniel Almeida.
  message-id: 20220825225312.564619-1-daniel.alme...@collabora.com

  .../media/platform/mediatek/vcodec/Makefile   |1 +
  .../vcodec/mtk_vcodec_dec_stateless.c |   47 +-
  .../platform/mediatek/vcodec/mtk_vcodec_drv.h |1 +
  .../vcodec/vdec/vdec_av1_req_lat_if.c | 2234 +
  .../platform/mediatek/vcodec/vdec_drv_if.c|4 +
  .../platform/mediatek/vcodec/vdec_drv_if.h|1 +
  .../platform/mediatek/vcodec/vdec_msg_queue.c |   27 +
  .../platform/mediatek/vcodec/vdec_msg_queue.h |4 +
  8 files changed, 2318 insertions(+), 1 deletion(-)
  create mode 100644 
drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c

diff --git a/drivers/media/platform/mediatek/vcodec/Makefile 
b/drivers/media/platform/mediatek/vcodec/Makefile
index 93e7a343b5b0e..7537259130072 100644
--- a/drivers/media/platform/mediatek/vcodec/Makefile
+++ b/drivers/media/platform/mediatek/vcodec/Makefile
@@ -10,6 +10,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
vdec/vdec_vp8_req_if.o \
vdec/vdec_vp9_if.o \
vdec/vdec_vp9_req_lat_if.o \
+   vdec/vdec_av1_req_lat_if.o \
vdec/vdec_h264_req_if.o \
vdec/vdec_h264_req_common.o \
vdec/vdec_h264_req_multi_if.o \
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c 
b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
index c45bd2599bb2d..ceb6fabc67749 100644
--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
@@ -107,11 +107,51 @@ static const struct mtk_stateless_control 
mtk_stateless_controls[] = {
},
.codec_type = V4L2_PIX_FMT_VP9_FRAME,
},
+   {
+   .cfg = {
+   .id = V4L2_CID_STATELESS_AV1_SEQUENCE,
+
+   },
+   .codec_type = V4L2_PIX_FMT_AV1_FRAME,
+   },
+   {
+   .cfg = {
+   .id = V4L2_CID_STATELESS_AV1_FRAME,
+
+   },
+   .codec_type = V4L2_PIX_FMT_AV1_FRAME,
+   },
+   {
+   .cfg = {
+   .id = V4L2_CID_STATELESS_AV1_TILE_GROUP_ENTRY,
+   .dims = { V4L2_AV1_MAX_TILE_COUNT },
+
+   },
+   .codec_type = V4L2_PIX_FMT_AV1_FRAME,
+   },
+   {
+   .cfg = {
+   .id = V4L2_CID_STATELESS_AV1_PROFILE,
+   .min = V4L2_STATELESS_AV1_PROFILE_MAIN,
+   .def = V4L2_STATELESS_AV1_PROFILE_MAIN,
+   .max = V4L2_STATELESS_AV1_PROFILE_MAIN,
+   },
+   .codec_type = V4L2_PIX_FMT_AV1_FRAME,
+   },
+   {
+   .cfg = {
+   .id = V4L2_CID_STATELESS_AV1_LEVEL,
+   .min = V4L2_STATELESS_AV1_LEVEL_2_0,
+   .def = V4L2_STATELESS_AV1_LEVEL_4_0,
+   .max = V4L2_STATELESS_AV1_LEVEL_5_1,
+   },
+   .codec_type = V4L2_PIX_FMT_AV1_FRAME,
+   },
  };
  
  #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
  
-static struct mtk_video_fmt mtk_video_formats[5];

+static struct mtk_video_fmt mtk_video_formats[6];
  
  static struct mtk_video_fmt default_out_format;

  static struct mtk_video_fmt default_cap_format;
@@ -351,6 +391,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc,
case V4L2_PIX_FMT_H264_SLICE:
case V4L2_PIX_FMT_VP8_FRAME:
case V4L2_PIX_FMT_VP9_FRAME:
+   case V4L2_PIX_FMT_AV1_FRAME:
mtk_video_formats[count_formats].fourcc = fourcc;
mtk_video_formats[count_formats].type = MTK_FMT_DEC;
 

Re: [RFC PATCH v6] media: mediatek: vcodec: support stateless AV1 decoder

2022-11-17 Thread Andrzej Pietrasiewicz

Hi Xiaoyong Lu,

Sorry about chiming in only at v6. Please see inline below.

Andrzej

W dniu 17.11.2022 o 07:17, Xiaoyong Lu pisze:

Add mediatek av1 decoder linux driver which use the stateless API in
MT8195.

Signed-off-by: Xiaoyong Lu
---
Changes from v5:

- change av1 PROFILE and LEVEL cfg
- test by av1 fluster, result is 173/239

Changes from v4:

- convert vb2_find_timestamp to vb2_find_buffer
- test by av1 fluster, result is 173/239

Changes from v3:

- modify comment for struct vdec_av1_slice_slot
- add define SEG_LVL_ALT_Q
- change use_lr/use_chroma_lr parse from av1 spec
- use ARRAY_SIZE to replace size for loop_filter_level and 
loop_filter_mode_deltas
- change array size of loop_filter_mode_deltas from 4 to 2
- add define SECONDARY_FILTER_STRENGTH_NUM_BITS
- change some hex values from upper case to lower case
- change *dpb_sz equal to V4L2_AV1_TOTAL_REFS_PER_FRAME + 1
- test by av1 fluster, result is 173/239

Changes from v2:

- Match with av1 uapi v3 modify
- test by av1 fluster, result is 173/239

---
Reference series:
[1]: v3 of this series is presend by Daniel Almeida.
  message-id: 20220825225312.564619-1-daniel.alme...@collabora.com

  .../media/platform/mediatek/vcodec/Makefile   |1 +
  .../vcodec/mtk_vcodec_dec_stateless.c |   47 +-
  .../platform/mediatek/vcodec/mtk_vcodec_drv.h |1 +
  .../vcodec/vdec/vdec_av1_req_lat_if.c | 2234 +
  .../platform/mediatek/vcodec/vdec_drv_if.c|4 +
  .../platform/mediatek/vcodec/vdec_drv_if.h|1 +
  .../platform/mediatek/vcodec/vdec_msg_queue.c |   27 +
  .../platform/mediatek/vcodec/vdec_msg_queue.h |4 +
  8 files changed, 2318 insertions(+), 1 deletion(-)
  create mode 100644 
drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c

diff --git a/drivers/media/platform/mediatek/vcodec/Makefile 
b/drivers/media/platform/mediatek/vcodec/Makefile
index 93e7a343b5b0e..7537259130072 100644
--- a/drivers/media/platform/mediatek/vcodec/Makefile
+++ b/drivers/media/platform/mediatek/vcodec/Makefile
@@ -10,6 +10,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
vdec/vdec_vp8_req_if.o \
vdec/vdec_vp9_if.o \
vdec/vdec_vp9_req_lat_if.o \
+   vdec/vdec_av1_req_lat_if.o \
vdec/vdec_h264_req_if.o \
vdec/vdec_h264_req_common.o \
vdec/vdec_h264_req_multi_if.o \
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c 
b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
index c45bd2599bb2d..ceb6fabc67749 100644
--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
@@ -107,11 +107,51 @@ static const struct mtk_stateless_control 
mtk_stateless_controls[] = {
},
.codec_type = V4L2_PIX_FMT_VP9_FRAME,
},
+   {
+   .cfg = {
+   .id = V4L2_CID_STATELESS_AV1_SEQUENCE,
+
+   },
+   .codec_type = V4L2_PIX_FMT_AV1_FRAME,
+   },
+   {
+   .cfg = {
+   .id = V4L2_CID_STATELESS_AV1_FRAME,
+
+   },
+   .codec_type = V4L2_PIX_FMT_AV1_FRAME,
+   },
+   {
+   .cfg = {
+   .id = V4L2_CID_STATELESS_AV1_TILE_GROUP_ENTRY,
+   .dims = { V4L2_AV1_MAX_TILE_COUNT },
+
+   },
+   .codec_type = V4L2_PIX_FMT_AV1_FRAME,
+   },
+   {
+   .cfg = {
+   .id = V4L2_CID_STATELESS_AV1_PROFILE,
+   .min = V4L2_STATELESS_AV1_PROFILE_MAIN,
+   .def = V4L2_STATELESS_AV1_PROFILE_MAIN,
+   .max = V4L2_STATELESS_AV1_PROFILE_MAIN,
+   },
+   .codec_type = V4L2_PIX_FMT_AV1_FRAME,
+   },
+   {
+   .cfg = {
+   .id = V4L2_CID_STATELESS_AV1_LEVEL,
+   .min = V4L2_STATELESS_AV1_LEVEL_2_0,
+   .def = V4L2_STATELESS_AV1_LEVEL_4_0,
+   .max = V4L2_STATELESS_AV1_LEVEL_5_1,
+   },
+   .codec_type = V4L2_PIX_FMT_AV1_FRAME,
+   },
  };
  
  #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
  
-static struct mtk_video_fmt mtk_video_formats[5];

+static struct mtk_video_fmt mtk_video_formats[6];
  
  static struct mtk_video_fmt default_out_format;

  static struct mtk_video_fmt default_cap_format;
@@ -351,6 +391,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc,
case V4L2_PIX_FMT_H264_SLICE:
case V4L2_PIX_FMT_VP8_FRAME:
case V4L2_PIX_FMT_VP9_FRAME:
+   case V4L2_PIX_FMT_AV1_FRAME:
mtk_video_formats[count_formats].fourcc = fourcc;
mtk_video_formats[count_formats].type = MTK_FMT_DEC;
mtk_video_formats[count_formats].num_planes = 1;
@@ -407,6 +448,10 

Re: [PATCH] drm/rockchip: vop: Correct RK3399 VOP register fields

2022-02-08 Thread Andrzej Pietrasiewicz

Hi Brian,

Sorry about the delay.

W dniu 20.01.2022 o 01:11, Brian Norris pisze:

Commit 7707f7227f09 ("drm/rockchip: Add support for afbc") switched up
the rk3399_vop_big[] register windows, but it did so incorrectly.

The biggest problem is in rk3288_win23_data[] vs.
rk3368_win23_data[] .format field:

   RK3288's format: VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1)
   RK3368's format: VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5)

Bits 5:6 (i.e., shift 5, mask 0x3) are correct for RK3399, according to
the TRM.

There are a few other small differences between the 3288 and 3368
definitions that were swapped in commit 7707f7227f09. I reviewed them to
the best of my ability according to the RK3399 TRM and fixed them up.

This fixes IOMMU issues (and display errors) when testing with BG24
color formats.

Fixes: 7707f7227f09 ("drm/rockchip: Add support for afbc")
Cc: Andrzej Pietrasiewicz 
Cc: 
Signed-off-by: Brian Norris 


Tested-by: Andrzej Pietrasiewicz 


---
I'd appreciate notes or testing from Andrzej, since I'm not sure how he
tested his original AFBC work.

  drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 8 +---
  1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 1f7353f0684a..798b542e5916 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -902,6 +902,7 @@ static const struct vop_win_phy rk3399_win01_data = {
.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
+   .x_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 21),
.y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22),
.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
.dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
@@ -912,6 +913,7 @@ static const struct vop_win_phy rk3399_win01_data = {
.uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
.src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
.dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
+   .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
  };
  
  /*

@@ -922,11 +924,11 @@ static const struct vop_win_phy rk3399_win01_data = {
  static const struct vop_win_data rk3399_vop_win_data[] = {
{ .base = 0x00, .phy = _win01_data,
  .type = DRM_PLANE_TYPE_PRIMARY },
-   { .base = 0x40, .phy = _win01_data,
+   { .base = 0x40, .phy = _win01_data,
  .type = DRM_PLANE_TYPE_OVERLAY },
-   { .base = 0x00, .phy = _win23_data,
+   { .base = 0x00, .phy = _win23_data,
  .type = DRM_PLANE_TYPE_OVERLAY },
-   { .base = 0x50, .phy = _win23_data,
+   { .base = 0x50, .phy = _win23_data,
  .type = DRM_PLANE_TYPE_CURSOR },
  };
  




Re: [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate

2021-10-13 Thread Andrzej Pietrasiewicz

Hi,

W dniu 13.10.2021 o 03:08, yunfei.d...@mediatek.com pisze:

Hi Andrzej,


On Tue, 2021-10-12 at 16:27 +0200, Andrzej Pietrasiewicz wrote:

Hi Yunfei Dong,

W dniu 11.10.2021 o 09:02, Yunfei Dong pisze:

This series adds support for multi hardware decode into mtk-vcodec,
by first
adding use of_platform_populate to manage each hardware
information: interrupt,
clock, register bases and power. Secondly add core thread to deal
with core
hardware message, at the same time, add msg queue for different
hardware
share messages. Lastly, the architecture of different specs are not
the same,
using specs type to separate them.

This series has been tested with both MT8183 and MT8173. Decoding
was working
for both chips.

Patches 1~3 rewrite get register bases and power on/off interface.

Patch 4 add to support multi hardware.

Patch 5 separate video encoder and decoder document

Patches 6-15 add interfaces to support core hardware.


Which tree does the series apply to?


I don't understand your mean clearly. Media tree?

You can get the patches from this link:

https://patchwork.linuxtv.org/project/linux-media/cover/20211011070247.792-1-yunfei.d...@mediatek.com/



Here's what I get:

$ git remote update media_tree
Fetching media_tree

$ git branch
  master
* media_tree
  mediatek-master

$ git-pw --server https://patchwork.linuxtv.org/api/1.1 --project linux-media 
series apply 6465 -3

Failed to apply patch:
Applying: media: mtk-vcodec: Get numbers of register bases from DT
Applying: media: mtk-vcodec: Align vcodec wake up interrupt interface
Applying: media: mtk-vcodec: Refactor vcodec pm interface
Applying: media: mtk-vcodec: Manage multi hardware information
error: sha1 information is lacking or useless 
(drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c).

error: could not build fake ancestor
Patch failed at 0004 media: mtk-vcodec: Manage multi hardware information
Use 'git am --show-current-patch' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

Regards,

Andrzej


Re: [PATCH v7, 00/15] Support multi hardware decode using of_platform_populate

2021-10-12 Thread Andrzej Pietrasiewicz

Hi Yunfei Dong,

W dniu 11.10.2021 o 09:02, Yunfei Dong pisze:

This series adds support for multi hardware decode into mtk-vcodec, by first
adding use of_platform_populate to manage each hardware information: interrupt,
clock, register bases and power. Secondly add core thread to deal with core
hardware message, at the same time, add msg queue for different hardware
share messages. Lastly, the architecture of different specs are not the same,
using specs type to separate them.

This series has been tested with both MT8183 and MT8173. Decoding was working
for both chips.

Patches 1~3 rewrite get register bases and power on/off interface.

Patch 4 add to support multi hardware.

Patch 5 separate video encoder and decoder document

Patches 6-15 add interfaces to support core hardware.


Which tree does the series apply to?

Regards,

Andrzej


Re: [PATCH v3 2/2] tty/sysrq: Add configurable handler to execute a compound action

2020-10-02 Thread Andrzej Pietrasiewicz

Hi,

W dniu 02.10.2020 o 16:02, Greg Kroah-Hartman pisze:

On Fri, Oct 02, 2020 at 03:42:52PM +0200, Andrzej Pietrasiewicz wrote:

Hi,

W dniu 02.10.2020 o 14:54, Greg Kroah-Hartman pisze:

On Tue, Aug 18, 2020 at 01:28:25PM +0200, Andrzej Pietrasiewicz wrote:

Userland might want to execute e.g. 'w' (show blocked tasks), followed
by 's' (sync), followed by 1000 ms delay and then followed by 'c' (crash)
upon a single magic SysRq. Or one might want to execute the famous "Raising
Elephants Is So Utterly Boring" action. This patch adds a configurable
handler, triggered with 'C', for this exact purpose. The user specifies the
composition of the compound action using syntax similar to getopt, where
each letter corresponds to an individual action and a colon followed by a
number corresponds to a delay of that many milliseconds, e.g.:

ws:1000c

or

r:100eis:1000ub


A macro language for sysrq commands, who would have thought...

Anyway, _why_ would userland want to do something so crazy as this?
What is the use-case here?



A use-case is Chromebooks which do want to execute 'w', 's',
wait 1000ms and then 'c' under one key combination. Having that supported
upstream brings us one little step closer to those machines running
upstream kernel.


Who is causing that to "execute"?  Some daemon/program?


No, as far as I know they patch the kernel to change the behavior
of Sysrq-x combination, so the "execution" is triggered by the user.




Another argument for such a "macro language" is when a machine's system
keeps degrading over time, possibly degrading (relatively) fast.
"Raising Elephants Is So Utterly Boring" consists of 6 actions, each
of which requires pressing several keys. The user might be unable
to complete all the 6 steps, while a "macro" requires user's involvement
for carrying out just one step.


So you want to "preload" some commands ahead of time, for when you get
in trouble

It can be said this way, yes.



These should just be debugging / last resort types of things, how
regular are they being used in your systems?



The "REISUB" itself is a kind of a last resort thing.

It is true that it's not a very frequent situation, but does its being rare
preclude having such a function in the kernel?

While preparing this patch I wanted it to be flexible, but perhaps it is
too flexible for some reason? If the permissions of the module_param's
sysfs entry were changed to 0444 would it be better? Then the compound
action would still be configurable but only at boot time rather than at
boot time _and_ runtime.

Regards,

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


Re: [PATCH v3 2/2] tty/sysrq: Add configurable handler to execute a compound action

2020-10-02 Thread Andrzej Pietrasiewicz

Hi,

W dniu 02.10.2020 o 14:54, Greg Kroah-Hartman pisze:

On Tue, Aug 18, 2020 at 01:28:25PM +0200, Andrzej Pietrasiewicz wrote:

Userland might want to execute e.g. 'w' (show blocked tasks), followed
by 's' (sync), followed by 1000 ms delay and then followed by 'c' (crash)
upon a single magic SysRq. Or one might want to execute the famous "Raising
Elephants Is So Utterly Boring" action. This patch adds a configurable
handler, triggered with 'C', for this exact purpose. The user specifies the
composition of the compound action using syntax similar to getopt, where
each letter corresponds to an individual action and a colon followed by a
number corresponds to a delay of that many milliseconds, e.g.:

ws:1000c

or

r:100eis:1000ub


A macro language for sysrq commands, who would have thought...

Anyway, _why_ would userland want to do something so crazy as this?
What is the use-case here?



A use-case is Chromebooks which do want to execute 'w', 's',
wait 1000ms and then 'c' under one key combination. Having that supported
upstream brings us one little step closer to those machines running
upstream kernel.

Another argument for such a "macro language" is when a machine's system
keeps degrading over time, possibly degrading (relatively) fast.
"Raising Elephants Is So Utterly Boring" consists of 6 actions, each
of which requires pressing several keys. The user might be unable
to complete all the 6 steps, while a "macro" requires user's involvement
for carrying out just one step.

Regards,

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


Re: [PATCH v3 0/2] Add configurable handler to execute a compound action

2020-10-02 Thread Andrzej Pietrasiewicz

W dniu 02.10.2020 o 14:33, Andrzej Pietrasiewicz pisze:

W dniu 02.10.2020 o 14:31, Greg Kroah-Hartman pisze:

On Tue, Aug 18, 2020 at 01:28:23PM +0200, Andrzej Pietrasiewicz wrote:

This is a follow-up of this thread:

https://www.spinics.net/lists/linux-input/msg68446.html


lore.kernel.org is easier to pull stuff from :)

Anyway, what ever happened to this series?  Is there a newer one
somewhere?

thanks,

greg k-h



https://lkml.org/lkml/2020/8/18/440

Andrzej


Sorry about confusion.

This is the same thing, so there is nothing newer.

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


Re: [PATCH v3 0/2] Add configurable handler to execute a compound action

2020-10-02 Thread Andrzej Pietrasiewicz

W dniu 02.10.2020 o 14:31, Greg Kroah-Hartman pisze:

On Tue, Aug 18, 2020 at 01:28:23PM +0200, Andrzej Pietrasiewicz wrote:

This is a follow-up of this thread:

https://www.spinics.net/lists/linux-input/msg68446.html


lore.kernel.org is easier to pull stuff from :)

Anyway, what ever happened to this series?  Is there a newer one
somewhere?

thanks,

greg k-h



https://lkml.org/lkml/2020/8/18/440

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


[PATCH v3 0/2] Add configurable handler to execute a compound action

2020-08-18 Thread Andrzej Pietrasiewicz
This is a follow-up of this thread:

https://www.spinics.net/lists/linux-input/msg68446.html

It only touches DRM (dri-devel) in such a way that it changes the help
message of sysrq_drm_fb_helper_restore_op, otherwise it is unrelated to DRM.

Patch 2/2 adds a configurable handler to execute a compound action.

Userland might want to execute e.g. 'w' (show blocked tasks), followed
by 's' (sync), followed by 1000 ms delay and then followed by 'c' (crash)
upon a single magic SysRq. Or one might want to execute the famous "Raising
Elephants Is So Utterly Boring" action. This patch adds a configurable
handler, triggered with 'C', for this exact purpose. The user specifies the
composition of the compound action using syntax similar to getopt, where
each letter corresponds to an individual action and a colon followed by a
number corresponds to a delay of that many milliseconds, e.g.:

ws:1000c

or

r:100eis:1000ub

An example of userspace that wants to perform a compound action is
Chrome OS, where SysRq-X (pressed for the second time within a certain
time period from the first time) causes showing the locked tasks, syncing,
waiting a 1000 ms delay and crashing the system.

Since all the slots in the sysrq_key_table[] are already taken or reserved,
patch 1/2 extends it to cover also capital letter versions.

v2..v3:
- eliminated compile error in !CONFIG_INPUT case (kernel test robot)

v1..v2:
- used toupper() instead of opencoding it (Jiri Slaby)
- updated help message of sysrq_drm_fb_helper_restore_op (Jiri Slaby)
- used unsigned int for specifying delays (Jiri Slaby)
- improved printed messages formatting (Jiri Slaby)

Andrzej Pietrasiewicz (2):
  tty/sysrq: Extend the sysrq_key_table to cover capital letters
  tty/sysrq: Add configurable handler to execute a compound action

 Documentation/admin-guide/sysrq.rst |  11 +++
 drivers/gpu/drm/drm_fb_helper.c |   2 +-
 drivers/tty/sysrq.c | 129 +++-
 include/linux/sysrq.h   |   1 +
 4 files changed, 140 insertions(+), 3 deletions(-)


base-commit: 9123e3a74ec7b934a4a099e98af6a61c2f80bbf5
-- 
2.17.1

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


[PATCH v3 2/2] tty/sysrq: Add configurable handler to execute a compound action

2020-08-18 Thread Andrzej Pietrasiewicz
Userland might want to execute e.g. 'w' (show blocked tasks), followed
by 's' (sync), followed by 1000 ms delay and then followed by 'c' (crash)
upon a single magic SysRq. Or one might want to execute the famous "Raising
Elephants Is So Utterly Boring" action. This patch adds a configurable
handler, triggered with 'C', for this exact purpose. The user specifies the
composition of the compound action using syntax similar to getopt, where
each letter corresponds to an individual action and a colon followed by a
number corresponds to a delay of that many milliseconds, e.g.:

ws:1000c

or

r:100eis:1000ub

Signed-off-by: Andrzej Pietrasiewicz 
---
 Documentation/admin-guide/sysrq.rst |  9 
 drivers/tty/sysrq.c | 82 -
 include/linux/sysrq.h   |  1 +
 3 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/sysrq.rst 
b/Documentation/admin-guide/sysrq.rst
index 67dfa4c29093..80bdd8bf9636 100644
--- a/Documentation/admin-guide/sysrq.rst
+++ b/Documentation/admin-guide/sysrq.rst
@@ -32,6 +32,7 @@ to 1. Here is the list of possible values in 
/proc/sys/kernel/sysrq:
  64 =  0x40 - enable signalling of processes (term, kill, oom-kill)
 128 =  0x80 - allow reboot/poweroff
 256 = 0x100 - allow nicing of all RT tasks
+512 = 0x200 - allow compound action
 
 You can set the value in the file by the following command::
 
@@ -148,6 +149,14 @@ CommandFunction
 
 ``z``  Dump the ftrace buffer
 
+``C``  Execute a predefined, compound action. The action is defined with
+   sysrq.sysrq_compound_action module parameter, whose value contains 
known
+   command keys (except ``C`` to prevent recursion). The command keys 
can
+   be optionally followed by a colon and a number of milliseconds to 
wait
+   after executing the last action. For example:
+
+   sysrq.sysrq_compound_action=r:100eis:1000ub
+
 ``0``-``9`` Sets the console log level, controlling which kernel messages
 will be printed to your console. (``0``, for example would make
 it so that only emergency messages like PANICs or OOPSes would
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 959f9e121cc6..e4ddea87c6db 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -438,6 +439,15 @@ static const struct sysrq_key_op sysrq_unrt_op = {
.enable_mask= SYSRQ_ENABLE_RTNICE,
 };
 
+static void sysrq_action_compound(int key);
+
+static struct sysrq_key_op sysrq_action_compound_op = {
+   .handler= sysrq_action_compound,
+   .help_msg   = "execute-compound-action(C)",
+   .action_msg = "Execute compound action",
+   .enable_mask= SYSRQ_ENABLE_COMPOUND,
+};
+
 /* Key Operations table and lock */
 static DEFINE_SPINLOCK(sysrq_key_table_lock);
 
@@ -500,7 +510,7 @@ static const struct sysrq_key_op *sysrq_key_table[62] = {
_ftrace_dump_op,  /* z */
NULL,   /* A */
NULL,   /* B */
-   NULL,   /* C */
+   _action_compound_op,  /* C */
NULL,   /* D */
NULL,   /* E */
NULL,   /* F */
@@ -633,6 +643,7 @@ EXPORT_SYMBOL(handle_sysrq);
 
 #ifdef CONFIG_INPUT
 static int sysrq_reset_downtime_ms;
+static char *sysrq_compound_action;
 
 /* Simple translation table for the SysRq keys */
 static const unsigned char sysrq_xlate[KEY_CNT] =
@@ -786,6 +797,62 @@ static void sysrq_of_get_keyreset_config(void)
 {
 }
 #endif
+#define SYSRQ_COMPOUND_ACTION_VALIDATE 0
+#define SYSRQ_COMPOUND_ACTION_RUN  1
+
+static int sysrq_process_compound_action(int pass)
+{
+   const char *action = sysrq_compound_action;
+   const struct sysrq_key_op *op_p;
+   int ret;
+   unsigned int delay;
+
+   while (*action) {
+   op_p = __sysrq_get_key_op(*action);
+   if (!op_p)
+   return -EINVAL;
+
+   /* Don't allow calling ourselves recursively */
+   if (op_p == _action_compound_op)
+   return -EINVAL;
+
+   if (pass == SYSRQ_COMPOUND_ACTION_RUN)
+   __handle_sysrq(*action, false);
+
+   if (*++action == ':') {
+   ret = sscanf(action++, ":%u", );
+   if (ret < 1) /* we want at least ":[0-9]" => 1 item */
+   return -EINVAL;
+
+   while (*action >= '0' && *action <= '9')
+   ++action;
+   if (pass == SYSRQ_COMPOUND_ACTION_RUN)
+   mdelay(delay);
+   }
+  

[PATCH v3 1/2] tty/sysrq: Extend the sysrq_key_table to cover capital letters

2020-08-18 Thread Andrzej Pietrasiewicz
All slots in sysrq_key_table[] are either used, reserved or at least
commented with their intended use. This patch adds capital letter versions
available, which means adding 26 more entries.

For already existing SysRq operations the user presses Alt-SysRq-, and
for the newly added ones Alt-Shift-SysRq-.

Signed-off-by: Andrzej Pietrasiewicz 
---
 Documentation/admin-guide/sysrq.rst |  2 ++
 drivers/gpu/drm/drm_fb_helper.c |  2 +-
 drivers/tty/sysrq.c | 49 +++--
 3 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/Documentation/admin-guide/sysrq.rst 
b/Documentation/admin-guide/sysrq.rst
index e6424d8c5846..67dfa4c29093 100644
--- a/Documentation/admin-guide/sysrq.rst
+++ b/Documentation/admin-guide/sysrq.rst
@@ -79,6 +79,8 @@ On all
 
echo t > /proc/sysrq-trigger
 
+The :kbd:`` is case sensitive.
+
 What are the 'command' keys?
 
 
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 8697554ccd41..1543d9d10970 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -325,7 +325,7 @@ static void drm_fb_helper_sysrq(int dummy1)
 
 static const struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
.handler = drm_fb_helper_sysrq,
-   .help_msg = "force-fb(V)",
+   .help_msg = "force-fb(v)",
.action_msg = "Restore framebuffer console",
 };
 #else
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index a8e39b2cdd55..959f9e121cc6 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -440,7 +441,7 @@ static const struct sysrq_key_op sysrq_unrt_op = {
 /* Key Operations table and lock */
 static DEFINE_SPINLOCK(sysrq_key_table_lock);
 
-static const struct sysrq_key_op *sysrq_key_table[36] = {
+static const struct sysrq_key_op *sysrq_key_table[62] = {
_loglevel_op, /* 0 */
_loglevel_op, /* 1 */
_loglevel_op, /* 2 */
@@ -497,6 +498,32 @@ static const struct sysrq_key_op *sysrq_key_table[36] = {
/* y: May be registered on sparc64 for global register dump */
NULL,   /* y */
_ftrace_dump_op,  /* z */
+   NULL,   /* A */
+   NULL,   /* B */
+   NULL,   /* C */
+   NULL,   /* D */
+   NULL,   /* E */
+   NULL,   /* F */
+   NULL,   /* G */
+   NULL,   /* H */
+   NULL,   /* I */
+   NULL,   /* J */
+   NULL,   /* K */
+   NULL,   /* L */
+   NULL,   /* M */
+   NULL,   /* N */
+   NULL,   /* O */
+   NULL,   /* P */
+   NULL,   /* Q */
+   NULL,   /* R */
+   NULL,   /* S */
+   NULL,   /* T */
+   NULL,   /* U */
+   NULL,   /* V */
+   NULL,   /* W */
+   NULL,   /* X */
+   NULL,   /* Y */
+   NULL,   /* Z */
 };
 
 /* key2index calculation, -1 on invalid index */
@@ -508,6 +535,8 @@ static int sysrq_key_table_key2index(int key)
retval = key - '0';
else if ((key >= 'a') && (key <= 'z'))
retval = key + 10 - 'a';
+   else if ((key >= 'A') && (key <= 'Z'))
+   retval = key + 36 - 'A';
else
retval = -1;
return retval;
@@ -621,6 +650,8 @@ struct sysrq_state {
unsigned long key_down[BITS_TO_LONGS(KEY_CNT)];
unsigned int alt;
unsigned int alt_use;
+   unsigned int shift;
+   unsigned int shift_use;
bool active;
bool need_reinject;
bool reinjecting;
@@ -805,10 +836,20 @@ static bool sysrq_handle_keypress(struct sysrq_state 
*sysrq,
}
break;
 
+   case KEY_LEFTSHIFT:
+   case KEY_RIGHTSHIFT:
+   if (!value)
+   sysrq->shift = KEY_RESERVED;
+   else if (value != 2)
+   sysrq->shift = code;
+   break;
+
case KEY_SYSRQ:
if (value == 1 && sysrq->alt != KEY_RESERVED) {
sysrq->active = true;
sysrq->alt_use = sysrq->alt;
+   /* either RESERVED (

[PATCH v2 2/2] tty/sysrq: Add configurable handler to execute a compound action

2020-08-17 Thread Andrzej Pietrasiewicz
Userland might want to execute e.g. 'w' (show blocked tasks), followed
by 's' (sync), followed by 1000 ms delay and then followed by 'c' (crash)
upon a single magic SysRq. Or one might want to execute the famous "Raising
Elephants Is So Utterly Boring" action. This patch adds a configurable
handler, triggered with 'C', for this exact purpose. The user specifies the
composition of the compound action using syntax similar to getopt, where
each letter corresponds to an individual action and a colon followed by a
number corresponds to a delay of that many milliseconds, e.g.:

ws:1000c

or

r:100eis:1000ub

Signed-off-by: Andrzej Pietrasiewicz 
---
 Documentation/admin-guide/sysrq.rst |  9 
 drivers/tty/sysrq.c | 82 -
 include/linux/sysrq.h   |  1 +
 3 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/sysrq.rst 
b/Documentation/admin-guide/sysrq.rst
index 67dfa4c29093..80bdd8bf9636 100644
--- a/Documentation/admin-guide/sysrq.rst
+++ b/Documentation/admin-guide/sysrq.rst
@@ -32,6 +32,7 @@ to 1. Here is the list of possible values in 
/proc/sys/kernel/sysrq:
  64 =  0x40 - enable signalling of processes (term, kill, oom-kill)
 128 =  0x80 - allow reboot/poweroff
 256 = 0x100 - allow nicing of all RT tasks
+512 = 0x200 - allow compound action
 
 You can set the value in the file by the following command::
 
@@ -148,6 +149,14 @@ CommandFunction
 
 ``z``  Dump the ftrace buffer
 
+``C``  Execute a predefined, compound action. The action is defined with
+   sysrq.sysrq_compound_action module parameter, whose value contains 
known
+   command keys (except ``C`` to prevent recursion). The command keys 
can
+   be optionally followed by a colon and a number of milliseconds to 
wait
+   after executing the last action. For example:
+
+   sysrq.sysrq_compound_action=r:100eis:1000ub
+
 ``0``-``9`` Sets the console log level, controlling which kernel messages
 will be printed to your console. (``0``, for example would make
 it so that only emergency messages like PANICs or OOPSes would
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 959f9e121cc6..fec770de325b 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -438,6 +439,15 @@ static const struct sysrq_key_op sysrq_unrt_op = {
.enable_mask= SYSRQ_ENABLE_RTNICE,
 };
 
+static void sysrq_action_compound(int key);
+
+static struct sysrq_key_op sysrq_action_compound_op = {
+   .handler= sysrq_action_compound,
+   .help_msg   = "execute-compound-action(C)",
+   .action_msg = "Execute compound action",
+   .enable_mask= SYSRQ_ENABLE_COMPOUND,
+};
+
 /* Key Operations table and lock */
 static DEFINE_SPINLOCK(sysrq_key_table_lock);
 
@@ -500,7 +510,7 @@ static const struct sysrq_key_op *sysrq_key_table[62] = {
_ftrace_dump_op,  /* z */
NULL,   /* A */
NULL,   /* B */
-   NULL,   /* C */
+   _action_compound_op,  /* C */
NULL,   /* D */
NULL,   /* E */
NULL,   /* F */
@@ -633,6 +643,7 @@ EXPORT_SYMBOL(handle_sysrq);
 
 #ifdef CONFIG_INPUT
 static int sysrq_reset_downtime_ms;
+static char *sysrq_compound_action;
 
 /* Simple translation table for the SysRq keys */
 static const unsigned char sysrq_xlate[KEY_CNT] =
@@ -786,6 +797,62 @@ static void sysrq_of_get_keyreset_config(void)
 {
 }
 #endif
+#define SYSRQ_COMPOUND_ACTION_VALIDATE 0
+#define SYSRQ_COMPOUND_ACTION_RUN  1
+
+static int sysrq_process_compound_action(int pass)
+{
+   const char *action = sysrq_compound_action;
+   const struct sysrq_key_op *op_p;
+   int ret;
+   unsigned int delay;
+
+   while (*action) {
+   op_p = __sysrq_get_key_op(*action);
+   if (!op_p)
+   return -EINVAL;
+
+   /* Don't allow calling ourselves recursively */
+   if (op_p == _action_compound_op)
+   return -EINVAL;
+
+   if (pass == SYSRQ_COMPOUND_ACTION_RUN)
+   __handle_sysrq(*action, false);
+
+   if (*++action == ':') {
+   ret = sscanf(action++, ":%u", );
+   if (ret < 1) /* we want at least ":[0-9]" => 1 item */
+   return -EINVAL;
+
+   while (*action >= '0' && *action <= '9')
+   ++action;
+   if (pass == SYSRQ_COMPOUND_ACTION_RUN)
+   mdelay(delay);
+   }
+  

[PATCH v2 1/2] tty/sysrq: Extend the sysrq_key_table to cover capital letters

2020-08-17 Thread Andrzej Pietrasiewicz
All slots in sysrq_key_table[] are either used, reserved or at least
commented with their intended use. This patch adds capital letter versions
available, which means adding 26 more entries.

For already existing SysRq operations the user presses Alt-SysRq-, and
for the newly added ones Alt-Shift-SysRq-.

Signed-off-by: Andrzej Pietrasiewicz 
---
 Documentation/admin-guide/sysrq.rst |  2 ++
 drivers/gpu/drm/drm_fb_helper.c |  2 +-
 drivers/tty/sysrq.c | 49 +++--
 3 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/Documentation/admin-guide/sysrq.rst 
b/Documentation/admin-guide/sysrq.rst
index e6424d8c5846..67dfa4c29093 100644
--- a/Documentation/admin-guide/sysrq.rst
+++ b/Documentation/admin-guide/sysrq.rst
@@ -79,6 +79,8 @@ On all
 
echo t > /proc/sysrq-trigger
 
+The :kbd:`` is case sensitive.
+
 What are the 'command' keys?
 
 
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 8697554ccd41..1543d9d10970 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -325,7 +325,7 @@ static void drm_fb_helper_sysrq(int dummy1)
 
 static const struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
.handler = drm_fb_helper_sysrq,
-   .help_msg = "force-fb(V)",
+   .help_msg = "force-fb(v)",
.action_msg = "Restore framebuffer console",
 };
 #else
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index a8e39b2cdd55..959f9e121cc6 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -440,7 +441,7 @@ static const struct sysrq_key_op sysrq_unrt_op = {
 /* Key Operations table and lock */
 static DEFINE_SPINLOCK(sysrq_key_table_lock);
 
-static const struct sysrq_key_op *sysrq_key_table[36] = {
+static const struct sysrq_key_op *sysrq_key_table[62] = {
_loglevel_op, /* 0 */
_loglevel_op, /* 1 */
_loglevel_op, /* 2 */
@@ -497,6 +498,32 @@ static const struct sysrq_key_op *sysrq_key_table[36] = {
/* y: May be registered on sparc64 for global register dump */
NULL,   /* y */
_ftrace_dump_op,  /* z */
+   NULL,   /* A */
+   NULL,   /* B */
+   NULL,   /* C */
+   NULL,   /* D */
+   NULL,   /* E */
+   NULL,   /* F */
+   NULL,   /* G */
+   NULL,   /* H */
+   NULL,   /* I */
+   NULL,   /* J */
+   NULL,   /* K */
+   NULL,   /* L */
+   NULL,   /* M */
+   NULL,   /* N */
+   NULL,   /* O */
+   NULL,   /* P */
+   NULL,   /* Q */
+   NULL,   /* R */
+   NULL,   /* S */
+   NULL,   /* T */
+   NULL,   /* U */
+   NULL,   /* V */
+   NULL,   /* W */
+   NULL,   /* X */
+   NULL,   /* Y */
+   NULL,   /* Z */
 };
 
 /* key2index calculation, -1 on invalid index */
@@ -508,6 +535,8 @@ static int sysrq_key_table_key2index(int key)
retval = key - '0';
else if ((key >= 'a') && (key <= 'z'))
retval = key + 10 - 'a';
+   else if ((key >= 'A') && (key <= 'Z'))
+   retval = key + 36 - 'A';
else
retval = -1;
return retval;
@@ -621,6 +650,8 @@ struct sysrq_state {
unsigned long key_down[BITS_TO_LONGS(KEY_CNT)];
unsigned int alt;
unsigned int alt_use;
+   unsigned int shift;
+   unsigned int shift_use;
bool active;
bool need_reinject;
bool reinjecting;
@@ -805,10 +836,20 @@ static bool sysrq_handle_keypress(struct sysrq_state 
*sysrq,
}
break;
 
+   case KEY_LEFTSHIFT:
+   case KEY_RIGHTSHIFT:
+   if (!value)
+   sysrq->shift = KEY_RESERVED;
+   else if (value != 2)
+   sysrq->shift = code;
+   break;
+
case KEY_SYSRQ:
if (value == 1 && sysrq->alt != KEY_RESERVED) {
sysrq->active = true;
sysrq->alt_use = sysrq->alt;
+   /* either RESERVED (

[PATCH v2 0/2] Add configurable handler to execute a compound action

2020-08-17 Thread Andrzej Pietrasiewicz
This is a follow-up of this thread:

https://www.spinics.net/lists/linux-input/msg68446.html

It only touches DRM (dri-devel) in such a way that it changes the help
message of sysrq_drm_fb_helper_restore_op, otherwise it is unrelated to DRM.

Patch 2/2 adds a configurable handler to execute a compound action.

Userland might want to execute e.g. 'w' (show blocked tasks), followed
by 's' (sync), followed by 1000 ms delay and then followed by 'c' (crash)
upon a single magic SysRq. Or one might want to execute the famous "Raising
Elephants Is So Utterly Boring" action. This patch adds a configurable
handler, triggered with 'C', for this exact purpose. The user specifies the
composition of the compound action using syntax similar to getopt, where
each letter corresponds to an individual action and a colon followed by a
number corresponds to a delay of that many milliseconds, e.g.:

ws:1000c

or

r:100eis:1000ub

An example of userspace that wants to perform a compound action is
Chrome OS, where SysRq-X (pressed for the second time within a certain
time period from the first time) causes showing the locked tasks, syncing,
waiting a 1000 ms delay and crashing the system.

Since all the slots in the sysrq_key_table[] are already taken or reserved,
patch 1/2 extends it to cover also capital letter versions.

v1..v2:
- used toupper() instead of opencoding it (Jiri Slaby)
- updated help message of sysrq_drm_fb_helper_restore_op (Jiri Slaby)
- used unsigned int for specifying delays (Jiri Slaby)
- improved printed messages formatting (Jiri Slaby)

Andrzej Pietrasiewicz (2):
  tty/sysrq: Extend the sysrq_key_table to cover capital letters
  tty/sysrq: Add configurable handler to execute a compound action

 Documentation/admin-guide/sysrq.rst |  11 +++
 drivers/gpu/drm/drm_fb_helper.c |   2 +-
 drivers/tty/sysrq.c | 129 +++-
 include/linux/sysrq.h   |   1 +
 4 files changed, 140 insertions(+), 3 deletions(-)


base-commit: 9123e3a74ec7b934a4a099e98af6a61c2f80bbf5
-- 
2.17.1

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


Re: [PATCH] drm: Don't free a struct never allocated by drm_gem_fb_init()

2020-04-16 Thread Andrzej Pietrasiewicz

W dniu 15.04.2020 o 20:33, Daniel Vetter pisze:

On Wed, Apr 15, 2020 at 7:19 PM Andrzej Pietrasiewicz
 wrote:


drm_gem_fb_init() is passed the fb and never allocates it, so it should be
not the one freeing it. As it is now the second call to kfree() is possible
with the same fb. Coverity reported the following:

*** CID 1492613:  Memory - corruptions  (USE_AFTER_FREE)
/drivers/gpu/drm/drm_gem_framebuffer_helper.c: 230 in 
drm_gem_fb_create_with_funcs()
224 fb = kzalloc(sizeof(*fb), GFP_KERNEL);
225 if (!fb)
226 return ERR_PTR(-ENOMEM);
227
228 ret = drm_gem_fb_init_with_funcs(dev, fb, file, mode_cmd, 
funcs);
229 if (ret) {
vvv CID 1492613:  Memory - corruptions  (USE_AFTER_FREE)
vvv Calling "kfree" frees pointer "fb" which has already been freed. [Note: 
The source code implementation of the function has been overridden by a user model.]
230 kfree(fb);
231 return ERR_PTR(ret);
232 }
233
234 return fb;
235 }

drm_gem_fb_init_with_funcs() calls drm_gem_fb_init()
drm_gem_fb_init() calls kfree(fb)

Reported-by: coverity-bot 
Addresses-Coverity-ID: 1492613 ("Memory - corruptions")
Fixes: f2b816d78a94 ("drm/core: Allow drivers allocate a subclass of struct 
drm_framebuffer")
Signed-off-by: Andrzej Pietrasiewicz 


Reviewed-by: Daniel Vetter 


---
  drivers/gpu/drm/drm_gem_framebuffer_helper.c | 4 +---
  1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index cac15294aef6..ccc2c71fa491 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -76,10 +76,8 @@ drm_gem_fb_init(struct drm_device *dev,
 fb->obj[i] = obj[i];

 ret = drm_framebuffer_init(dev, fb, funcs);
-   if (ret) {
+   if (ret)
 drm_err(dev, "Failed to init framebuffer: %d\n", ret);
-   kfree(fb);
-   }

 return ret;
  }
--
2.17.1






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


[PATCH] drm: Don't free a struct never allocated by drm_gem_fb_init()

2020-04-15 Thread Andrzej Pietrasiewicz
drm_gem_fb_init() is passed the fb and never allocates it, so it should be
not the one freeing it. As it is now the second call to kfree() is possible
with the same fb. Coverity reported the following:

*** CID 1492613:  Memory - corruptions  (USE_AFTER_FREE)
/drivers/gpu/drm/drm_gem_framebuffer_helper.c: 230 in 
drm_gem_fb_create_with_funcs()
224 fb = kzalloc(sizeof(*fb), GFP_KERNEL);
225 if (!fb)
226 return ERR_PTR(-ENOMEM);
227
228 ret = drm_gem_fb_init_with_funcs(dev, fb, file, mode_cmd, 
funcs);
229 if (ret) {
vvv CID 1492613:  Memory - corruptions  (USE_AFTER_FREE)
vvv Calling "kfree" frees pointer "fb" which has already been freed. [Note: 
The source code implementation of the function has been overridden by a user 
model.]
230 kfree(fb);
231 return ERR_PTR(ret);
232 }
233
234 return fb;
235 }

drm_gem_fb_init_with_funcs() calls drm_gem_fb_init()
drm_gem_fb_init() calls kfree(fb)

Reported-by: coverity-bot 
Addresses-Coverity-ID: 1492613 ("Memory - corruptions")
Fixes: f2b816d78a94 ("drm/core: Allow drivers allocate a subclass of struct 
drm_framebuffer")
Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/drm_gem_framebuffer_helper.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index cac15294aef6..ccc2c71fa491 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -76,10 +76,8 @@ drm_gem_fb_init(struct drm_device *dev,
fb->obj[i] = obj[i];
 
ret = drm_framebuffer_init(dev, fb, funcs);
-   if (ret) {
+   if (ret)
drm_err(dev, "Failed to init framebuffer: %d\n", ret);
-   kfree(fb);
-   }
 
return ret;
 }
-- 
2.17.1

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


[PATCH 1/2] drm/core: Use proper debugging macro

2020-03-31 Thread Andrzej Pietrasiewicz
Use drm_dbg_kms() instead of DRM_DEBUG_KMS.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/drm_gem_framebuffer_helper.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index 7e3982c36baa..6fb1841fa71c 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -331,9 +331,9 @@ static int drm_gem_afbc_min_size(struct drm_device *dev,
case AFBC_FORMAT_MOD_BLOCK_SIZE_64x4:
case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4:
default:
-   DRM_DEBUG_KMS("Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n",
- mode_cmd->modifier[0]
- & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
+   drm_dbg_kms(dev, "Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n",
+   mode_cmd->modifier[0]
+   & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
return -EINVAL;
}
 
-- 
2.17.1

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


[PATCH 0/2] AFBC fixes

2020-03-31 Thread Andrzej Pietrasiewicz
This short series addresses the way bpp value is made available
for drm_gem_afbc_min_size(). It can be inferred from the format
if a driver hasn't set anything in cpp[0] (patch 2/2).

While at it, use proper debugging macro (patch 1/2).

Andrzej Pietrasiewicz (2):
  drm/core: Use proper debugging macro
  drm/core: Calculate bpp in afbc helper

 Documentation/gpu/todo.rst   | 15 ---
 drivers/gpu/drm/drm_gem_framebuffer_helper.c | 45 +++-
 include/drm/drm_framebuffer.h|  7 ---
 3 files changed, 35 insertions(+), 32 deletions(-)

-- 
2.17.1

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


[PATCH 2/2] drm/core: Calculate bpp in afbc helper

2020-03-31 Thread Andrzej Pietrasiewicz
Some drivers (komeda, malidp) don't set anything in cpp. If that is the
case the right value can be inferred from the format. Then the "bpp" member
can be eliminated from struct drm_afbc_framebuffer.

Signed-off-by: Andrzej Pietrasiewicz 
---
 Documentation/gpu/todo.rst   | 15 
 drivers/gpu/drm/drm_gem_framebuffer_helper.c | 39 
 include/drm/drm_framebuffer.h|  7 
 3 files changed, 32 insertions(+), 29 deletions(-)

diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 37a3a023c114..439656f55c5d 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -404,21 +404,6 @@ Contact: Laurent Pinchart, respective driver maintainers
 
 Level: Intermediate
 
-Encode cpp properly in malidp
--
-
-cpp (chars per pixel) is not encoded properly in malidp, zero is
-used instead. afbc implementation needs bpp or cpp, but if it is
-zero it needs to be provided elsewhere, and so the bpp field exists
-in struct drm_afbc_framebuffer.
-
-Properly encode cpp in malidp and remove the bpp field in struct
-drm_afbc_framebuffer.
-
-Contact: malidp maintainers
-
-Level: Intermediate
-
 Core refactorings
 =
 
diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index 6fb1841fa71c..cac15294aef6 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -309,11 +309,37 @@ drm_gem_fb_create_with_dirty(struct drm_device *dev, 
struct drm_file *file,
 }
 EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty);
 
+static __u32 drm_gem_afbc_get_bpp(struct drm_device *dev,
+ const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+   const struct drm_format_info *info;
+
+   info = drm_get_format_info(dev, mode_cmd);
+
+   /* use whatever a driver has set */
+   if (info->cpp[0])
+   return info->cpp[0] * 8;
+
+   /* guess otherwise */
+   switch (info->format) {
+   case DRM_FORMAT_YUV420_8BIT:
+   return 12;
+   case DRM_FORMAT_YUV420_10BIT:
+   return 15;
+   case DRM_FORMAT_VUY101010:
+   return 30;
+   default:
+   break;
+   }
+
+   /* all attempts failed */
+   return 0;
+}
+
 static int drm_gem_afbc_min_size(struct drm_device *dev,
 const struct drm_mode_fb_cmd2 *mode_cmd,
 struct drm_afbc_framebuffer *afbc_fb)
 {
-   const struct drm_format_info *info;
__u32 n_blocks, w_alignment, h_alignment, hdr_alignment;
/* remove bpp when all users properly encode cpp in drm_format_info */
__u32 bpp;
@@ -351,12 +377,11 @@ static int drm_gem_afbc_min_size(struct drm_device *dev,
afbc_fb->aligned_height = ALIGN(mode_cmd->height, h_alignment);
afbc_fb->offset = mode_cmd->offsets[0];
 
-   info = drm_get_format_info(dev, mode_cmd);
-   /*
-* Change to always using info->cpp[0]
-* when all users properly encode it
-*/
-   bpp = info->cpp[0] ? info->cpp[0] * 8 : afbc_fb->bpp;
+   bpp = drm_gem_afbc_get_bpp(dev, mode_cmd);
+   if (!bpp) {
+   drm_dbg_kms(dev, "Invalid AFBC bpp value: %d\n", bpp);
+   return -EINVAL;
+   }
 
n_blocks = (afbc_fb->aligned_width * afbc_fb->aligned_height)
   / AFBC_SUPERBLOCK_PIXELS;
diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
index b53c0332f040..be658ebbec72 100644
--- a/include/drm/drm_framebuffer.h
+++ b/include/drm/drm_framebuffer.h
@@ -331,13 +331,6 @@ struct drm_afbc_framebuffer {
 * @afbc_size: minimum size of afbc buffer
 */
u32 afbc_size;
-   /**
-* @bpp: bpp value for this afbc buffer
-* To be removed when users such as malidp
-* properly store the cpp in drm_format_info.
-* New users should not start using this field.
-*/
-   u32 bpp;
 };
 
 #define fb_to_afbc_fb(x) container_of(x, struct drm_afbc_framebuffer, base)
-- 
2.17.1

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


Re: [PATCHv7 2/6] drm/core: Add drm_afbc_framebuffer and a corresponding helper

2020-03-30 Thread Andrzej Pietrasiewicz

Hi Daniel,

W dniu 30.03.2020 o 19:01, Daniel Vetter pisze:

On Wed, Mar 11, 2020 at 3:55 PM Andrzej Pietrasiewicz
 wrote:


The new struct contains afbc-specific data.





diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 439656f55c5d..37a3a023c114 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -404,6 +404,21 @@ Contact: Laurent Pinchart, respective driver maintainers

  Level: Intermediate

+Encode cpp properly in malidp
+-
+
+cpp (chars per pixel) is not encoded properly in malidp, zero is
+used instead. afbc implementation needs bpp or cpp, but if it is
+zero it needs to be provided elsewhere, and so the bpp field exists
+in struct drm_afbc_framebuffer.
+
+Properly encode cpp in malidp and remove the bpp field in struct
+drm_afbc_framebuffer.
+
+Contact: malidp maintainers
+
+Level: Intermediate


Just stumbled over this todo, which is really surprising. Also
definitely not something I wanted to ack, earlier versions at least
didn't have this.

Why is this needed? drm_afbc_framebuffer contains a drm_framebuffer,
which has a pointer to drm_format_info, which we're always setting
(the core does that for all drivers, both for addfb and addfb2). Why
is that not good enough to get at cpp for everyone?

Cheers, Daniel



Let me quote James 
https://patchwork.freedesktop.org/patch/345603/#comment_653081:

"Seems we can remove this bpp or no need to define it as a pass in argument
for size check, maybe the komeda/malidp get_afbc_bpp() function mislead
you that afbc formats may have vendor specific bpp.

But the story is:

for afbc only formats like DRM_FORMAT_YUV420_8BIT/10BIT, we have set
nothing in drm_format_info, neither cpp nor block_size, so both malidp
or komeda introduce a get_bpp(), but actually the two funcs basically
are same.

So my suggestion is we can temporary use the get_afbc_bpp() in malidp
or komeda. and eventually I think we'd better set the block size
for these formats, then we can defines a common get_bpp() like pitch".

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


Re: [PATCH v1 2/6] drm/fb: fix kernel-doc in drm_framebuffer.h

2020-03-30 Thread Andrzej Pietrasiewicz

W dniu 28.03.2020 o 14:20, Sam Ravnborg pisze:

Fix following warnings:
drm_framebuffer.h:342: warning: Function parameter or member 'block_width' not 
described in 'drm_afbc_framebuffer'
drm_framebuffer.h:342: warning: Function parameter or member 'block_height' not 
described in 'drm_afbc_framebuffer'

Trivial spelling mistakes.

Signed-off-by: Sam Ravnborg 
Fixes: 55f7f72753ab ("drm/core: Add drm_afbc_framebuffer and a corresponding 
helper")
Cc: Andrzej Pietrasiewicz 
Cc: Emil Velikov 
Cc: James Qian Wang 
Cc: Daniel Vetter 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: Thomas Zimmermann 
Cc: David Airlie 
Cc: Daniel Vetter 
---
  include/drm/drm_framebuffer.h | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
index e9f1b0e2968d..b53c0332f040 100644
--- a/include/drm/drm_framebuffer.h
+++ b/include/drm/drm_framebuffer.h
@@ -308,11 +308,11 @@ struct drm_afbc_framebuffer {
 */
struct drm_framebuffer base;
/**
-* @block_widht: width of a single afbc block
+* @block_width: width of a single afbc block
 */
u32 block_width;
/**
-* @block_widht: height of a single afbc block
+* @block_height: height of a single afbc block
 */
u32 block_height;
/**



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


Re: [PATCHv7 6/6] drm/rockchip: Add support for afbc

2020-03-19 Thread Andrzej Pietrasiewicz

Hi Sandy,


W dniu 19.03.2020 o 03:57, Sandy Huang pisze:

Hi Emil,






--
2.17.1

Heiko, Sandy, being the maintainers of the Rockchip driver, can you
review/ack this patch?

I believe the intention is to merge the series via drm-misc. Andrzej
already has commit access.

-Emil


Thanks for you patch, maybe we need to consider the compatibility with px30 
platform afbc features,the main difference is:


1.  px30 support x offset and y offset display, and the state->src.x1 / 
state->src.y1  should be alibegned as 16pixel/line;


2.px30 only win1 can support afbdc format;




Actually I sent the patch, Emil kindly forwarded it to you.

Unfortunately I don't have px30 hardware, so I can't test. Can we
merge the patch as is (if you are ok with the way it is now) and then
I will help reviewing the patch adding px30 support on top of it?

Regards,

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


[PATCHv7 6/6] drm/rockchip: Add support for afbc

2020-03-11 Thread Andrzej Pietrasiewicz
This patch adds support for afbc handling. afbc is a compressed format
which reduces the necessary memory bandwidth.

Co-developed-by: Mark Yao 
Signed-off-by: Mark Yao 
Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   1 +
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  |  43 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 137 +++-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |  17 +++
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c |  83 +++-
 5 files changed, 276 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index c5b06048124e..e33c2dcd0d4b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -30,6 +30,7 @@ struct rockchip_crtc_state {
int output_mode;
int output_bpc;
int output_flags;
+   bool enable_afbc;
 };
 #define to_rockchip_crtc_state(s) \
container_of(s, struct rockchip_crtc_state, base)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 221e72e71432..9b13c784b347 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -57,8 +57,49 @@ static const struct drm_mode_config_helper_funcs 
rockchip_mode_config_helpers =
.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
 };
 
+static struct drm_framebuffer *
+rockchip_fb_create(struct drm_device *dev, struct drm_file *file,
+  const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+   struct drm_afbc_framebuffer *afbc_fb;
+   const struct drm_format_info *info;
+   int ret;
+
+   info = drm_get_format_info(dev, mode_cmd);
+   if (!info)
+   return ERR_PTR(-ENOMEM);
+
+   afbc_fb = kzalloc(sizeof(*afbc_fb), GFP_KERNEL);
+   if (!afbc_fb)
+   return ERR_PTR(-ENOMEM);
+
+   ret = drm_gem_fb_init_with_funcs(dev, _fb->base, file, mode_cmd,
+_drm_fb_funcs);
+   if (ret) {
+   kfree(afbc_fb);
+   return ERR_PTR(ret);
+   }
+
+   if (drm_is_afbc(mode_cmd->modifier[0])) {
+   int ret, i;
+
+   ret = drm_gem_fb_afbc_init(dev, mode_cmd, afbc_fb);
+   if (ret) {
+   struct drm_gem_object **obj = afbc_fb->base.obj;
+
+   for (i = 0; i < info->num_planes; ++i)
+   drm_gem_object_put_unlocked(obj[i]);
+
+   kfree(afbc_fb);
+   return ERR_PTR(ret);
+   }
+   }
+
+   return _fb->base;
+}
+
 static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
-   .fb_create = drm_gem_fb_create_with_dirty,
+   .fb_create = rockchip_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/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index cecb2cc781f5..b87d22eb6ae1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -91,9 +91,22 @@
 #define VOP_WIN_TO_INDEX(vop_win) \
((vop_win) - (vop_win)->vop->win)
 
+#define VOP_AFBC_SET(vop, name, v) \
+   do { \
+   if ((vop)->data->afbc) \
+   vop_reg_set((vop), &(vop)->data->afbc->name, \
+   0, ~0, v, #name); \
+   } while (0)
+
 #define to_vop(x) container_of(x, struct vop, crtc)
 #define to_vop_win(x) container_of(x, struct vop_win, base)
 
+#define AFBC_FMT_RGB5650x0
+#define AFBC_FMT_U8U8U8U8  0x5
+#define AFBC_FMT_U8U8U80x4
+
+#define AFBC_TILE_16x16BIT(4)
+
 /*
  * The coefficients of the following matrix are all fixed points.
  * The format is S2.10 for the 3x3 part of the matrix, and S9.12 for the 
offsets.
@@ -274,6 +287,29 @@ static enum vop_data_format vop_convert_format(uint32_t 
format)
}
 }
 
+static int vop_convert_afbc_format(uint32_t format)
+{
+   switch (format) {
+   case DRM_FORMAT_XRGB:
+   case DRM_FORMAT_ARGB:
+   case DRM_FORMAT_XBGR:
+   case DRM_FORMAT_ABGR:
+   return AFBC_FMT_U8U8U8U8;
+   case DRM_FORMAT_RGB888:
+   case DRM_FORMAT_BGR888:
+   return AFBC_FMT_U8U8U8;
+   case DRM_FORMAT_RGB565:
+   case DRM_FORMAT_BGR565:
+   return AFBC_FMT_RGB565;
+   /* either of the below should not be reachable */
+   default:
+   DRM_WARN_ONCE("unsupported AFBC format[%08x]\n", format);
+   return -EINVAL;
+   }
+
+   return -EINVAL;
+}
+
 static uint16_t

[PATCHv7 5/6] drm/arm/malidp: Switch to afbc helpers

2020-03-11 Thread Andrzej Pietrasiewicz
Use available afbc helpers.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/arm/malidp_drv.c | 44 +++-
 1 file changed, 4 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index b9715b19af94..bae532290c89 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -297,11 +297,7 @@ malidp_fb_create(struct drm_device *dev, struct drm_file 
*file,
return ERR_PTR(-ENOMEM);
}
 
-   if (mode_cmd->modifier[0]) {
-   int n_superblocks = 0;
-   struct drm_gem_object *objs = NULL;
-   u32 afbc_superblock_size = 0, afbc_superblock_height = 0;
-   u32 afbc_superblock_width = 0, afbc_size = 0;
+   if (drm_is_afbc(mode_cmd->modifier[0])) {
int bpp = 0;
 
if (malidp_format_mod_supported(dev, mode_cmd->pixel_format,
@@ -325,31 +321,8 @@ malidp_fb_create(struct drm_device *dev, struct drm_file 
*file,
goto free_fb;
}
 
-   switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
-   case AFBC_SIZE_16X16:
-   afbc_superblock_height = 16;
-   afbc_superblock_width = 16;
-   break;
-   default:
-   DRM_DEBUG_KMS("AFBC superblock size not supported\n");
-   goto free_fb;
-   }
-
-
-   n_superblocks = (mode_cmd->width / afbc_superblock_width) *
-   (mode_cmd->height / afbc_superblock_height);
-
bpp = malidp_format_get_bpp(info->format);
 
-   afbc_superblock_size =
-   (bpp * afbc_superblock_width * afbc_superblock_height)
-   / BITS_PER_BYTE;
-
-   afbc_size = ALIGN(n_superblocks * AFBC_HEADER_SIZE,
- AFBC_SUPERBLK_ALIGNMENT);
-   afbc_size += n_superblocks
-   * ALIGN(afbc_superblock_size, AFBC_SUPERBLK_ALIGNMENT);
-
if ((mode_cmd->width * bpp) !=
(mode_cmd->pitches[0] * BITS_PER_BYTE)) {
DRM_DEBUG_KMS("Invalid value of (pitch * BITS_PER_BYTE) 
(=%u) should be same as width (=%u) * bpp (=%u)\n",
@@ -358,20 +331,11 @@ malidp_fb_create(struct drm_device *dev, struct drm_file 
*file,
goto free_fb;
}
 
-   objs = drm_gem_object_lookup(file, mode_cmd->handles[0]);
-   if (!objs) {
-   DRM_DEBUG_KMS("Failed to lookup GEM object\n");
-   goto free_fb;
-   }
+   /* eliminate when cpp is properly encoded in drm_format_info */
+   afbc_fb->bpp = bpp;
 
-   if (objs->size < afbc_size) {
-   DRM_DEBUG_KMS("buffer size %zu/%u too small for AFBC\n",
- objs->size, afbc_size);
-   drm_gem_object_put_unlocked(objs);
+   if (drm_gem_fb_afbc_init(dev, mode_cmd, afbc_fb))
goto free_fb;
-   }
-
-   drm_gem_object_put_unlocked(objs);
}
 
return _fb->base;
-- 
2.17.1

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


[PATCHv7 4/6] drm/arm/malidp: Allocate an afbc-specific drm_framebuffer

2020-03-11 Thread Andrzej Pietrasiewicz
Prepare for using generic afbc helpers.

Use an existing helper which allows allocating a struct drm_framebuffer
in the driver.

afbc-specific checks should go after drm_gem_fb_init_with_funcs().

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/arm/malidp_drv.c | 50 +---
 1 file changed, 39 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index cafbd81e4c1e..b9715b19af94 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -269,13 +269,36 @@ 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_fb_funcs = {
+   .destroy= drm_gem_fb_destroy,
+   .create_handle  = drm_gem_fb_create_handle,
+};
+
 static struct drm_framebuffer *
 malidp_fb_create(struct drm_device *dev, struct drm_file *file,
 const struct drm_mode_fb_cmd2 *mode_cmd)
 {
+   struct drm_afbc_framebuffer *afbc_fb;
+   const struct drm_format_info *info;
+   int ret, i;
+
+   info = drm_get_format_info(dev, mode_cmd);
+   if (!info)
+   return ERR_PTR(-ENOMEM);
+
+   afbc_fb = kzalloc(sizeof(*afbc_fb), GFP_KERNEL);
+   if (!afbc_fb)
+   return ERR_PTR(-ENOMEM);
+
+   ret = drm_gem_fb_init_with_funcs(dev, _fb->base, file, mode_cmd,
+_fb_funcs);
+   if (ret) {
+   kfree(afbc_fb);
+   return ERR_PTR(-ENOMEM);
+   }
+
if (mode_cmd->modifier[0]) {
int n_superblocks = 0;
-   const struct drm_format_info *info;
struct drm_gem_object *objs = NULL;
u32 afbc_superblock_size = 0, afbc_superblock_height = 0;
u32 afbc_superblock_width = 0, afbc_size = 0;
@@ -283,23 +306,23 @@ malidp_fb_create(struct drm_device *dev, struct drm_file 
*file,
 
if (malidp_format_mod_supported(dev, mode_cmd->pixel_format,
mode_cmd->modifier[0]) == false)
-   return ERR_PTR(-EINVAL);
+   goto free_fb;
 
if (mode_cmd->offsets[0] != 0) {
DRM_DEBUG_KMS("AFBC buffer plane offset should be 0\n");
-   return ERR_PTR(-EINVAL);
+   goto free_fb;
}
 
switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
case AFBC_SIZE_16X16:
if ((mode_cmd->width % 16) || (mode_cmd->height % 16)) {
DRM_DEBUG_KMS("AFBC buffers must be aligned to 
16 pixels\n");
-   return ERR_PTR(-EINVAL);
+   goto free_fb;
}
break;
default:
DRM_DEBUG_KMS("Unsupported AFBC block size\n");
-   return ERR_PTR(-EINVAL);
+   goto free_fb;
}
 
switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
@@ -309,10 +332,9 @@ malidp_fb_create(struct drm_device *dev, struct drm_file 
*file,
break;
default:
DRM_DEBUG_KMS("AFBC superblock size not supported\n");
-   return ERR_PTR(-EINVAL);
+   goto free_fb;
}
 
-   info = drm_get_format_info(dev, mode_cmd);
 
n_superblocks = (mode_cmd->width / afbc_superblock_width) *
(mode_cmd->height / afbc_superblock_height);
@@ -333,26 +355,32 @@ malidp_fb_create(struct drm_device *dev, struct drm_file 
*file,
DRM_DEBUG_KMS("Invalid value of (pitch * BITS_PER_BYTE) 
(=%u) should be same as width (=%u) * bpp (=%u)\n",
  (mode_cmd->pitches[0] * BITS_PER_BYTE),
  mode_cmd->width, bpp);
-   return ERR_PTR(-EINVAL);
+   goto free_fb;
}
 
objs = drm_gem_object_lookup(file, mode_cmd->handles[0]);
if (!objs) {
DRM_DEBUG_KMS("Failed to lookup GEM object\n");
-   return ERR_PTR(-EINVAL);
+   goto free_fb;
}
 
if (objs->size < afbc_size) {
DRM_DEBUG_KMS("buffer size %zu/%u too small for AFBC\n",
  objs->size, afbc_size);
drm_gem_object_put_unlocked(objs);
-   return ERR_PTR(-EINVAL);
+   goto free_fb;
  

[PATCHv7 3/6] drm/arm/malidp: Factor-in framebuffer creation

2020-03-11 Thread Andrzej Pietrasiewicz
Consolidating framebuffer creation into one function will make it easier
to transition to generic afbc-aware helpers.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/arm/malidp_drv.c | 157 +--
 1 file changed, 66 insertions(+), 91 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 37d92a06318e..cafbd81e4c1e 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -269,112 +269,87 @@ static const struct drm_mode_config_helper_funcs 
malidp_mode_config_helpers = {
.atomic_commit_tail = malidp_atomic_commit_tail,
 };
 
-static bool
-malidp_verify_afbc_framebuffer_caps(struct drm_device *dev,
-   const struct drm_mode_fb_cmd2 *mode_cmd)
+static struct drm_framebuffer *
+malidp_fb_create(struct drm_device *dev, struct drm_file *file,
+const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-   if (malidp_format_mod_supported(dev, mode_cmd->pixel_format,
-   mode_cmd->modifier[0]) == false)
-   return false;
+   if (mode_cmd->modifier[0]) {
+   int n_superblocks = 0;
+   const struct drm_format_info *info;
+   struct drm_gem_object *objs = NULL;
+   u32 afbc_superblock_size = 0, afbc_superblock_height = 0;
+   u32 afbc_superblock_width = 0, afbc_size = 0;
+   int bpp = 0;
+
+   if (malidp_format_mod_supported(dev, mode_cmd->pixel_format,
+   mode_cmd->modifier[0]) == false)
+   return ERR_PTR(-EINVAL);
 
-   if (mode_cmd->offsets[0] != 0) {
-   DRM_DEBUG_KMS("AFBC buffers' plane offset should be 0\n");
-   return false;
-   }
+   if (mode_cmd->offsets[0] != 0) {
+   DRM_DEBUG_KMS("AFBC buffer plane offset should be 0\n");
+   return ERR_PTR(-EINVAL);
+   }
 
-   switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
-   case AFBC_SIZE_16X16:
-   if ((mode_cmd->width % 16) || (mode_cmd->height % 16)) {
-   DRM_DEBUG_KMS("AFBC buffers must be aligned to 16 
pixels\n");
-   return false;
+   switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
+   case AFBC_SIZE_16X16:
+   if ((mode_cmd->width % 16) || (mode_cmd->height % 16)) {
+   DRM_DEBUG_KMS("AFBC buffers must be aligned to 
16 pixels\n");
+   return ERR_PTR(-EINVAL);
+   }
+   break;
+   default:
+   DRM_DEBUG_KMS("Unsupported AFBC block size\n");
+   return ERR_PTR(-EINVAL);
}
-   break;
-   default:
-   DRM_DEBUG_KMS("Unsupported AFBC block size\n");
-   return false;
-   }
 
-   return true;
-}
+   switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
+   case AFBC_SIZE_16X16:
+   afbc_superblock_height = 16;
+   afbc_superblock_width = 16;
+   break;
+   default:
+   DRM_DEBUG_KMS("AFBC superblock size not supported\n");
+   return ERR_PTR(-EINVAL);
+   }
 
-static bool
-malidp_verify_afbc_framebuffer_size(struct drm_device *dev,
-   struct drm_file *file,
-   const struct drm_mode_fb_cmd2 *mode_cmd)
-{
-   int n_superblocks = 0;
-   const struct drm_format_info *info;
-   struct drm_gem_object *objs = NULL;
-   u32 afbc_superblock_size = 0, afbc_superblock_height = 0;
-   u32 afbc_superblock_width = 0, afbc_size = 0;
-   int bpp = 0;
-
-   switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
-   case AFBC_SIZE_16X16:
-   afbc_superblock_height = 16;
-   afbc_superblock_width = 16;
-   break;
-   default:
-   DRM_DEBUG_KMS("AFBC superblock size is not supported\n");
-   return false;
-   }
+   info = drm_get_format_info(dev, mode_cmd);
 
-   info = drm_get_format_info(dev, mode_cmd);
+   n_superblocks = (mode_cmd->width / afbc_superblock_width) *
+   (mode_cmd->height / afbc_superblock_height);
 
-   n_superblocks = (mode_cmd->width / afbc_superblock_width) *
-   (mode_cmd->height / afbc_superblock_height);
+   bpp = malidp_format_get_bpp(info->format);
 
-   bpp = malidp_format_get_bpp(info->format);
+   afbc_superblock_size =
+ 

[PATCHv7 1/6] drm/core: Allow drivers allocate a subclass of struct drm_framebuffer

2020-03-11 Thread Andrzej Pietrasiewicz
Allow allocating a specialized version of struct drm_framebuffer
by moving the actual fb allocation out of drm_gem_fb_create_with_funcs();
the respective functions names are adjusted to reflect that fact.
Please note, though, that standard size checks are performed on buffers,
so the drm_gem_fb_init_with_funcs() is useful for cases where those
standard size checks are appropriate or at least don't conflict the
checks to be performed in the specialized case.

Thanks to this change the drivers can call drm_gem_fb_init_with_funcs()
having allocated their special version of struct drm_framebuffer, exactly
the way the new version of drm_gem_fb_create_with_funcs() does.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/drm_gem_framebuffer_helper.c | 87 ++--
 include/drm/drm_gem_framebuffer_helper.h |  5 ++
 2 files changed, 67 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index 3a7ace19a902..86c1907c579a 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -54,19 +54,15 @@ 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 *
-drm_gem_fb_alloc(struct drm_device *dev,
+static int
+drm_gem_fb_init(struct drm_device *dev,
+struct drm_framebuffer *fb,
 const struct drm_mode_fb_cmd2 *mode_cmd,
 struct drm_gem_object **obj, unsigned int num_planes,
 const struct drm_framebuffer_funcs *funcs)
 {
-   struct drm_framebuffer *fb;
int ret, i;
 
-   fb = kzalloc(sizeof(*fb), GFP_KERNEL);
-   if (!fb)
-   return ERR_PTR(-ENOMEM);
-
drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
 
for (i = 0; i < num_planes; i++)
@@ -76,10 +72,9 @@ drm_gem_fb_alloc(struct drm_device *dev,
if (ret) {
drm_err(dev, "Failed to init framebuffer: %d\n", ret);
kfree(fb);
-   return ERR_PTR(ret);
}
 
-   return fb;
+   return ret;
 }
 
 /**
@@ -123,10 +118,13 @@ int drm_gem_fb_create_handle(struct drm_framebuffer *fb, 
struct drm_file *file,
 EXPORT_SYMBOL(drm_gem_fb_create_handle);
 
 /**
- * drm_gem_fb_create_with_funcs() - Helper function for the
- *  _mode_config_funcs.fb_create
- *  callback
+ * drm_gem_fb_init_with_funcs() - Helper function for implementing
+ *   _mode_config_funcs.fb_create
+ *   callback in cases when the driver
+ *   allocates a subclass of
+ *   struct drm_framebuffer
  * @dev: DRM device
+ * @fb: framebuffer object
  * @file: DRM file that holds the GEM handle(s) backing the framebuffer
  * @mode_cmd: Metadata from the userspace framebuffer creation request
  * @funcs: vtable to be used for the new framebuffer object
@@ -134,23 +132,26 @@ EXPORT_SYMBOL(drm_gem_fb_create_handle);
  * This function can be used to set _framebuffer_funcs for drivers that 
need
  * custom framebuffer callbacks. Use drm_gem_fb_create() if you don't need to
  * change _framebuffer_funcs. The function does buffer size validation.
+ * The buffer size validation is for a general case, though, so users should
+ * pay attention to the checks being appropriate for them or, at least,
+ * non-conflicting.
  *
  * Returns:
- * Pointer to a _framebuffer on success or an error pointer on failure.
+ * Zero or a negative error code.
  */
-struct drm_framebuffer *
-drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
-const struct drm_mode_fb_cmd2 *mode_cmd,
-const struct drm_framebuffer_funcs *funcs)
+int drm_gem_fb_init_with_funcs(struct drm_device *dev,
+  struct drm_framebuffer *fb,
+  struct drm_file *file,
+  const struct drm_mode_fb_cmd2 *mode_cmd,
+  const struct drm_framebuffer_funcs *funcs)
 {
const struct drm_format_info *info;
struct drm_gem_object *objs[4];
-   struct drm_framebuffer *fb;
int ret, i;
 
info = drm_get_format_info(dev, mode_cmd);
if (!info)
-   return ERR_PTR(-EINVAL);
+   return -EINVAL;
 
for (i = 0; i < info->num_planes; i++) {
unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
@@ -175,19 +176,55 @@ drm_gem_fb_create_with_funcs(struct drm_device *dev, 
struct drm_file *file,
}
}
 
-   fb = drm_gem_fb_alloc(dev, mode_cmd, objs, i, funcs);
-   if (IS_ERR(fb)) {
-   ret = PTR_ERR(fb);
+   ret = drm_gem_fb_init(dev, fb, mode_cmd, objs, i

[PATCHv7 2/6] drm/core: Add drm_afbc_framebuffer and a corresponding helper

2020-03-11 Thread Andrzej Pietrasiewicz
The new struct contains afbc-specific data.

The new function can be used by drivers which support afbc to complete
the preparation of struct drm_afbc_framebuffer. It must be called after
allocating the said struct and calling drm_gem_fb_init_with_funcs().

Signed-off-by: Andrzej Pietrasiewicz 
---
 Documentation/gpu/todo.rst   |  15 +++
 drivers/gpu/drm/drm_gem_framebuffer_helper.c | 108 +++
 include/drm/drm_framebuffer.h|  45 
 include/drm/drm_gem_framebuffer_helper.h |  10 ++
 4 files changed, 178 insertions(+)

diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 439656f55c5d..37a3a023c114 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -404,6 +404,21 @@ Contact: Laurent Pinchart, respective driver maintainers
 
 Level: Intermediate
 
+Encode cpp properly in malidp
+-
+
+cpp (chars per pixel) is not encoded properly in malidp, zero is
+used instead. afbc implementation needs bpp or cpp, but if it is
+zero it needs to be provided elsewhere, and so the bpp field exists
+in struct drm_afbc_framebuffer.
+
+Properly encode cpp in malidp and remove the bpp field in struct
+drm_afbc_framebuffer.
+
+Contact: malidp maintainers
+
+Level: Intermediate
+
 Core refactorings
 =
 
diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index 86c1907c579a..7e3982c36baa 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -21,6 +21,13 @@
 #include 
 #include 
 
+#define AFBC_HEADER_SIZE   16
+#define AFBC_TH_LAYOUT_ALIGNMENT   8
+#define AFBC_HDR_ALIGN 64
+#define AFBC_SUPERBLOCK_PIXELS 256
+#define AFBC_SUPERBLOCK_ALIGNMENT  128
+#define AFBC_TH_BODY_START_ALIGNMENT   4096
+
 /**
  * DOC: overview
  *
@@ -302,6 +309,107 @@ drm_gem_fb_create_with_dirty(struct drm_device *dev, 
struct drm_file *file,
 }
 EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty);
 
+static int drm_gem_afbc_min_size(struct drm_device *dev,
+const struct drm_mode_fb_cmd2 *mode_cmd,
+struct drm_afbc_framebuffer *afbc_fb)
+{
+   const struct drm_format_info *info;
+   __u32 n_blocks, w_alignment, h_alignment, hdr_alignment;
+   /* remove bpp when all users properly encode cpp in drm_format_info */
+   __u32 bpp;
+
+   switch (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
+   case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
+   afbc_fb->block_width = 16;
+   afbc_fb->block_height = 16;
+   break;
+   case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
+   afbc_fb->block_width = 32;
+   afbc_fb->block_height = 8;
+   break;
+   /* no user exists yet - fall through */
+   case AFBC_FORMAT_MOD_BLOCK_SIZE_64x4:
+   case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4:
+   default:
+   DRM_DEBUG_KMS("Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n",
+ mode_cmd->modifier[0]
+ & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
+   return -EINVAL;
+   }
+
+   /* tiled header afbc */
+   w_alignment = afbc_fb->block_width;
+   h_alignment = afbc_fb->block_height;
+   hdr_alignment = AFBC_HDR_ALIGN;
+   if (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_TILED) {
+   w_alignment *= AFBC_TH_LAYOUT_ALIGNMENT;
+   h_alignment *= AFBC_TH_LAYOUT_ALIGNMENT;
+   hdr_alignment = AFBC_TH_BODY_START_ALIGNMENT;
+   }
+
+   afbc_fb->aligned_width = ALIGN(mode_cmd->width, w_alignment);
+   afbc_fb->aligned_height = ALIGN(mode_cmd->height, h_alignment);
+   afbc_fb->offset = mode_cmd->offsets[0];
+
+   info = drm_get_format_info(dev, mode_cmd);
+   /*
+* Change to always using info->cpp[0]
+* when all users properly encode it
+*/
+   bpp = info->cpp[0] ? info->cpp[0] * 8 : afbc_fb->bpp;
+
+   n_blocks = (afbc_fb->aligned_width * afbc_fb->aligned_height)
+  / AFBC_SUPERBLOCK_PIXELS;
+   afbc_fb->afbc_size = ALIGN(n_blocks * AFBC_HEADER_SIZE, hdr_alignment);
+   afbc_fb->afbc_size += n_blocks * ALIGN(bpp * AFBC_SUPERBLOCK_PIXELS / 8,
+  AFBC_SUPERBLOCK_ALIGNMENT);
+
+   return 0;
+}
+
+/**
+ * drm_gem_fb_afbc_init() - Helper function for drivers using afbc to
+ * fill and validate all the afbc-specific
+ * struct drm_afbc_framebuffer members
+ *
+ * @dev: DRM device
+ * @afbc_fb: afbc-specific framebuffer
+ * @mode_cmd: Metadata from the userspace framebuffer creation request
+ * @afbc_fb: afbc framebuffer
+ *
+ * This function can be used b

[PATCHv7 0/6] Add AFBC support for Rockchip

2020-03-11 Thread Andrzej Pietrasiewicz
This series adds AFBC support for Rockchip. It is inspired by:

https://chromium.googlesource.com/chromiumos/third_party/kernel/+/refs/heads/factory-gru-9017.B-chromeos-4.4/drivers/gpu/drm/rockchip/rockchip_drm_vop.c

This is the seventh iteration of the afbc series, which addresses
comments received for v6.

Compared to v5 it simplifies the way afbc-related helpers are
exposed to their users.

A new struct drm_afbc_framebuffer is added, which stores afbc-related
driver-specific data. Interested drivers need to explicitly allocate
an instance of struct drm_afbc_framebuffer, use drm_gem_fb_init_with_funcs()
call drm_gem_fb_afbc_init() and do their specific afbc-related checks.

There are 3 interested drivers: malidp, komeda and rockchip and I only have
rockchip hardware. As Liviu reports, due to the coronavirus outbreak,
it is difficult to test komeda now, so, according to his suggestion,
I purposedly omit changes to komeda. Malidp is changed accordingly, though,
which is a proof that it can be done. Then adding afbc support for rockchip
follows the malidp example.

I kindly ask for reviewing the series. I need to mention that my ultimate
goal is merging afbc for rockchip and I don't have other hardware, so some
help from malidp developers/maintainers would be appreciated.

Rebased onto drm-misc-next.

v6..v7:
- used IS_ERR() instead of IS_ERR_OR_NULL() (Emil)
- made drm_gem_fb_afbc_init() symmetric in terms of not putting the objects
in case of error, it is now caller's responsibility (Emil)
- added an entry in Documentation/gpu/todo.rst about drivers not encoding
cpp in their format info (Emil)
- sticked to the 80 columns per line rule wherever possible, excluding
error messages so that they can be grepped (Emil)
- removed redundant WARN_ON() in rockchip_mod_supported() (Emil)
- made drm_gem_fb_init() and drm_gem_fb_init_with_funcs() return an int (James)
- factored in drm_afbc_get_superblock_wh() (James)
- eliminated unknown types error for u32/u64 (kbuild)

v5..v6:
- reworked the way afbc-specific helpers are exposed to drivers (Daniel)
- not checking block size mask in drm_is_afbc (James)
- fixed the test for afbc format (Boris)
- documented unused afbc format modifier values in drm_afbc_get_superblock_wh()
(Boris)
- changed drm_is_afbc to a macro
- renamed drm_gem_fb_lookup() to drm_gem_fb_objs_lookup() (James)
- eliminated storing block/tile alignment constraint in
 struct drm_afbc_framebuffer (James)
- eliminated storing afbc header alignment constraint
 in struct drm_afbc_framebuffer (James)
- eliminated storing afbc payload's offset in struct
drm_afbc_framebuffer (James)
- moved to taking bpp value from drm_format_info except malidp which doesn't
set it properly (James)
- removed unrelated coding style fixes in rockchip (Boris)
- consolidated 2-line error messages into one-liners in rockchip (Boris)
- added checking that there is at most one AFBC plane in
vop_crtc_atomic_check() (Boris)
- added checking that AFBC format is indeed supported in
rockchip_mod_supported() (Boris)
- removed requirement of exactly one color plane in rockchip_mod_supported()
- removed afbc_win hack in rockchip in favor of adding a field to crtc state
and ensuring only one AFBC plane in crtc's atomic check (Boris)

v4..v5:
- used proper way of subclassing drm_framebuffer (Daniel Vetter)
- added documentation to exported functions (Liviu Dudau)
- reordered new functions in drm_gem_framebuffer_helper.c to make a saner
diff (Liviu Dudau)
- used "2" suffix instead of "_special" for the special version of size
checks (Liviu Dudau)
- dropped unnecessarily added condition in drm_get_format_info() (Liviu
Dudau)
- dropped "block_size = 0;" trick in framebuffer_check() (Daniel Vetter)
- relaxed sticking to 80 characters per line rule in some cases

v3..v4:

- addressed (some) comments from Daniel Stone, Ezequiel Garcia, Daniel
Vetter and James Qian Wang - thank you for input
- refactored helpers to ease accommodating drivers with afbc needs
- moved afbc checks to helpers
- converted komeda, malidp and (the newly added) rockchip to use the afbc
helpers
- eliminated a separate, dedicated source code file

v2..v3:

- addressed (some) comments from Daniel Stone, Liviu Dudau, Daniel Vetter
and Brian Starkey - thank you all

In this iteration some rework has been done. The checking logic is now moved
to framebuffer_check() so it is common to all drivers. But the common part
is not good for komeda, so this series is not good for merging yet.
I kindly ask for feedback whether the changes are in the right direction.
I also kindly ask for input on how to accommodate komeda.

The CONFIG_DRM_AFBC option has been eliminated in favour of adding
drm_afbc.c to drm_kms_helper.

v1..v2:

- addressed comments from Daniel Stone, Ayan Halder, Mihail Atanassov
- coding style fixes

Andrzej Pietrasiewicz (6):
  drm/core: Allow drivers allocate a subclass of struct drm_framebuffer
  drm/core: Add drm_afbc_framebuffer and a 

[PATCHv6 6/6] drm/rockchip: Add support for afbc

2020-03-03 Thread Andrzej Pietrasiewicz
This patch adds support for afbc handling. afbc is a compressed format
which reduces the necessary memory bandwidth.

Co-developed-by: Mark Yao 
Signed-off-by: Mark Yao 
Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   1 +
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  |  32 -
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 136 +++-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |  12 ++
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c |  83 +++-
 5 files changed, 259 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index c5b06048124e..e33c2dcd0d4b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -30,6 +30,7 @@ struct rockchip_crtc_state {
int output_mode;
int output_bpc;
int output_flags;
+   bool enable_afbc;
 };
 #define to_rockchip_crtc_state(s) \
container_of(s, struct rockchip_crtc_state, base)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 221e72e71432..d153d84bca7b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -57,8 +57,38 @@ static const struct drm_mode_config_helper_funcs 
rockchip_mode_config_helpers =
.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
 };
 
+static struct drm_framebuffer *
+rockchip_fb_create(struct drm_device *dev, struct drm_file *file,
+  const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+   struct drm_afbc_framebuffer *afbc_fb;
+   struct drm_framebuffer *ret;
+
+   afbc_fb = kzalloc(sizeof(*afbc_fb), GFP_KERNEL);
+   if (!afbc_fb)
+   return ERR_PTR(-ENOMEM);
+
+   ret = drm_gem_fb_init_with_funcs(dev, _fb->base, file, mode_cmd, 
_drm_fb_funcs);
+   if (IS_ERR_OR_NULL(ret)) {
+   kfree(afbc_fb);
+   return ret;
+   }
+
+   if (drm_is_afbc(mode_cmd->modifier[0])) {
+   int r;
+
+   r = drm_gem_fb_afbc_init(dev, mode_cmd, afbc_fb);
+   if (r) {
+   kfree(afbc_fb);
+   ret = ERR_PTR(r);
+   }
+   }
+
+   return ret;
+}
+
 static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
-   .fb_create = drm_gem_fb_create_with_dirty,
+   .fb_create = rockchip_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/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index cecb2cc781f5..848d5e038f0a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -91,9 +91,21 @@
 #define VOP_WIN_TO_INDEX(vop_win) \
((vop_win) - (vop_win)->vop->win)
 
+#define VOP_AFBC_SET(vop, name, v) \
+   do { \
+   if ((vop)->data->afbc) \
+   vop_reg_set((vop), &(vop)->data->afbc->name, 0, ~0, v, 
#name); \
+   } while (0)
+
 #define to_vop(x) container_of(x, struct vop, crtc)
 #define to_vop_win(x) container_of(x, struct vop_win, base)
 
+#define AFBC_FMT_RGB5650x0
+#define AFBC_FMT_U8U8U8U8  0x5
+#define AFBC_FMT_U8U8U80x4
+
+#define AFBC_TILE_16x16BIT(4)
+
 /*
  * The coefficients of the following matrix are all fixed points.
  * The format is S2.10 for the 3x3 part of the matrix, and S9.12 for the 
offsets.
@@ -274,6 +286,29 @@ static enum vop_data_format vop_convert_format(uint32_t 
format)
}
 }
 
+static int vop_convert_afbc_format(uint32_t format)
+{
+   switch (format) {
+   case DRM_FORMAT_XRGB:
+   case DRM_FORMAT_ARGB:
+   case DRM_FORMAT_XBGR:
+   case DRM_FORMAT_ABGR:
+   return AFBC_FMT_U8U8U8U8;
+   case DRM_FORMAT_RGB888:
+   case DRM_FORMAT_BGR888:
+   return AFBC_FMT_U8U8U8;
+   case DRM_FORMAT_RGB565:
+   case DRM_FORMAT_BGR565:
+   return AFBC_FMT_RGB565;
+   /* either of the below should not be reachable */
+   default:
+   DRM_WARN_ONCE("unsupported AFBC format[%08x]\n", format);
+   return -EINVAL;
+   }
+
+   return -EINVAL;
+}
+
 static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src,
  uint32_t dst, bool is_horizontal,
  int vsu_mode, int *vskiplines)
@@ -598,6 +633,17 @@ static int vop_enable(struct drm_crtc *crtc, struct 
drm_crtc_state *old_state)
vop_win_disable(vop, vop_win);
}
}
+
+   if (vop->data->afbc) {
+   struct rockchip_crtc_state *s;
+ 

[PATCHv6 4/6] drm/arm/malidp: Allocate an afbc-specific drm_framebuffer

2020-03-03 Thread Andrzej Pietrasiewicz
Prepare for using generic afbc helpers.

Use an existing helper which allows allocating a struct drm_framebuffer
in the driver.

afbc-specific checks should go after drm_gem_fb_init_with_funcs().

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/arm/malidp_drv.c | 40 +---
 1 file changed, 31 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index b53fc01baf2b..c076d0fd5b28 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -269,10 +269,28 @@ 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_fb_funcs = {
+   .destroy= drm_gem_fb_destroy,
+   .create_handle  = drm_gem_fb_create_handle,
+};
+
 static struct drm_framebuffer *
 malidp_fb_create(struct drm_device *dev, struct drm_file *file,
 const struct drm_mode_fb_cmd2 *mode_cmd)
 {
+   struct drm_afbc_framebuffer *afbc_fb;
+   struct drm_framebuffer *ret;
+
+   afbc_fb = kzalloc(sizeof(*afbc_fb), GFP_KERNEL);
+   if (!afbc_fb)
+   return ERR_PTR(-ENOMEM);
+
+   ret = drm_gem_fb_init_with_funcs(dev, _fb->base, file, mode_cmd, 
_fb_funcs);
+   if (IS_ERR_OR_NULL(ret)) {
+   kfree(afbc_fb);
+   return ERR_PTR(-ENOMEM);
+   }
+
if (mode_cmd->modifier[0]) {
int n_superblocks = 0;
const struct drm_format_info *info;
@@ -283,23 +301,23 @@ malidp_fb_create(struct drm_device *dev, struct drm_file 
*file,
 
if (malidp_format_mod_supported(dev, mode_cmd->pixel_format,
mode_cmd->modifier[0]) == false)
-   return ERR_PTR(-EINVAL);
+   goto free_fb;
 
if (mode_cmd->offsets[0] != 0) {
DRM_DEBUG_KMS("AFBC buffers' plane offset should be 
0\n");
-   return ERR_PTR(-EINVAL);
+   goto free_fb;
}
 
switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
case AFBC_SIZE_16X16:
if ((mode_cmd->width % 16) || (mode_cmd->height % 16)) {
DRM_DEBUG_KMS("AFBC buffers must be aligned to 
16 pixels\n");
-   return ERR_PTR(-EINVAL);
+   goto free_fb;
}
break;
default:
DRM_DEBUG_KMS("Unsupported AFBC block size\n");
-   return ERR_PTR(-EINVAL);
+   goto free_fb;
}
 
switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
@@ -309,7 +327,7 @@ malidp_fb_create(struct drm_device *dev, struct drm_file 
*file,
break;
default:
DRM_DEBUG_KMS("AFBC superblock size is not 
supported\n");
-   return ERR_PTR(-EINVAL);
+   goto free_fb;
}
 
info = drm_get_format_info(dev, mode_cmd);
@@ -334,26 +352,30 @@ malidp_fb_create(struct drm_device *dev, struct drm_file 
*file,
  "should be same as width (=%u) * bpp 
(=%u)\n",
  (mode_cmd->pitches[0] * BITS_PER_BYTE),
  mode_cmd->width, bpp);
-   return ERR_PTR(-EINVAL);
+   goto free_fb;
}
 
objs = drm_gem_object_lookup(file, mode_cmd->handles[0]);
if (!objs) {
DRM_DEBUG_KMS("Failed to lookup GEM object\n");
-   return ERR_PTR(-EINVAL);
+   goto free_fb;
}
 
if (objs->size < afbc_size) {
DRM_DEBUG_KMS("buffer size (%zu) too small for AFBC 
buffer size = %u\n",
  objs->size, afbc_size);
drm_gem_object_put_unlocked(objs);
-   return ERR_PTR(-EINVAL);
+   goto free_fb;
}
 
drm_gem_object_put_unlocked(objs);
}
 
-   return drm_gem_fb_create(dev, file, mode_cmd);
+   return ret;
+
+free_fb:
+   kfree(afbc_fb);
+   return ERR_PTR(-EINVAL);
 }
 
 static const struct drm_mode_config_funcs malidp_mode_config_funcs = {
-- 
2.17.1

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


[PATCHv6 5/6] drm/arm/malidp: Switch to afbc helpers

2020-03-03 Thread Andrzej Pietrasiewicz
Use available afbc helpers.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/arm/malidp_drv.c | 44 +++-
 1 file changed, 4 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index c076d0fd5b28..d50b246ce42b 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -291,12 +291,8 @@ malidp_fb_create(struct drm_device *dev, struct drm_file 
*file,
return ERR_PTR(-ENOMEM);
}
 
-   if (mode_cmd->modifier[0]) {
-   int n_superblocks = 0;
+   if (drm_is_afbc(mode_cmd->modifier[0])) {
const struct drm_format_info *info;
-   struct drm_gem_object *objs = NULL;
-   u32 afbc_superblock_size = 0, afbc_superblock_height = 0;
-   u32 afbc_superblock_width = 0, afbc_size = 0;
int bpp = 0;
 
if (malidp_format_mod_supported(dev, mode_cmd->pixel_format,
@@ -320,32 +316,9 @@ malidp_fb_create(struct drm_device *dev, struct drm_file 
*file,
goto free_fb;
}
 
-   switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
-   case AFBC_SIZE_16X16:
-   afbc_superblock_height = 16;
-   afbc_superblock_width = 16;
-   break;
-   default:
-   DRM_DEBUG_KMS("AFBC superblock size is not 
supported\n");
-   goto free_fb;
-   }
-
info = drm_get_format_info(dev, mode_cmd);
-
-   n_superblocks = (mode_cmd->width / afbc_superblock_width) *
-   (mode_cmd->height / afbc_superblock_height);
-
bpp = malidp_format_get_bpp(info->format);
 
-   afbc_superblock_size =
-   (bpp * afbc_superblock_width * afbc_superblock_height)
-   / BITS_PER_BYTE;
-
-   afbc_size = ALIGN(n_superblocks * AFBC_HEADER_SIZE,
- AFBC_SUPERBLK_ALIGNMENT);
-   afbc_size += n_superblocks
-   * ALIGN(afbc_superblock_size, AFBC_SUPERBLK_ALIGNMENT);
-
if ((mode_cmd->width * bpp) !=
(mode_cmd->pitches[0] * BITS_PER_BYTE)) {
DRM_DEBUG_KMS("Invalid value of (pitch * BITS_PER_BYTE) 
(=%u) "
@@ -355,20 +328,11 @@ malidp_fb_create(struct drm_device *dev, struct drm_file 
*file,
goto free_fb;
}
 
-   objs = drm_gem_object_lookup(file, mode_cmd->handles[0]);
-   if (!objs) {
-   DRM_DEBUG_KMS("Failed to lookup GEM object\n");
-   goto free_fb;
-   }
+   /* eliminate when cpp is properly encoded in drm_format_info */
+   afbc_fb->bpp = bpp;
 
-   if (objs->size < afbc_size) {
-   DRM_DEBUG_KMS("buffer size (%zu) too small for AFBC 
buffer size = %u\n",
- objs->size, afbc_size);
-   drm_gem_object_put_unlocked(objs);
+   if (drm_gem_fb_afbc_init(dev, mode_cmd, afbc_fb))
goto free_fb;
-   }
-
-   drm_gem_object_put_unlocked(objs);
}
 
return ret;
-- 
2.17.1

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


[PATCHv6 3/6] drm/arm/malidp: Factor-in framebuffer creation

2020-03-03 Thread Andrzej Pietrasiewicz
Consolidating framebuffer creation into one function will make it easier
to transition to generic afbc-aware helpers.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/arm/malidp_drv.c | 158 +--
 1 file changed, 67 insertions(+), 91 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 37d92a06318e..b53fc01baf2b 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -269,112 +269,88 @@ static const struct drm_mode_config_helper_funcs 
malidp_mode_config_helpers = {
.atomic_commit_tail = malidp_atomic_commit_tail,
 };
 
-static bool
-malidp_verify_afbc_framebuffer_caps(struct drm_device *dev,
-   const struct drm_mode_fb_cmd2 *mode_cmd)
+static struct drm_framebuffer *
+malidp_fb_create(struct drm_device *dev, struct drm_file *file,
+const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-   if (malidp_format_mod_supported(dev, mode_cmd->pixel_format,
-   mode_cmd->modifier[0]) == false)
-   return false;
+   if (mode_cmd->modifier[0]) {
+   int n_superblocks = 0;
+   const struct drm_format_info *info;
+   struct drm_gem_object *objs = NULL;
+   u32 afbc_superblock_size = 0, afbc_superblock_height = 0;
+   u32 afbc_superblock_width = 0, afbc_size = 0;
+   int bpp = 0;
+
+   if (malidp_format_mod_supported(dev, mode_cmd->pixel_format,
+   mode_cmd->modifier[0]) == false)
+   return ERR_PTR(-EINVAL);
 
-   if (mode_cmd->offsets[0] != 0) {
-   DRM_DEBUG_KMS("AFBC buffers' plane offset should be 0\n");
-   return false;
-   }
+   if (mode_cmd->offsets[0] != 0) {
+   DRM_DEBUG_KMS("AFBC buffers' plane offset should be 
0\n");
+   return ERR_PTR(-EINVAL);
+   }
 
-   switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
-   case AFBC_SIZE_16X16:
-   if ((mode_cmd->width % 16) || (mode_cmd->height % 16)) {
-   DRM_DEBUG_KMS("AFBC buffers must be aligned to 16 
pixels\n");
-   return false;
+   switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
+   case AFBC_SIZE_16X16:
+   if ((mode_cmd->width % 16) || (mode_cmd->height % 16)) {
+   DRM_DEBUG_KMS("AFBC buffers must be aligned to 
16 pixels\n");
+   return ERR_PTR(-EINVAL);
+   }
+   break;
+   default:
+   DRM_DEBUG_KMS("Unsupported AFBC block size\n");
+   return ERR_PTR(-EINVAL);
}
-   break;
-   default:
-   DRM_DEBUG_KMS("Unsupported AFBC block size\n");
-   return false;
-   }
 
-   return true;
-}
+   switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
+   case AFBC_SIZE_16X16:
+   afbc_superblock_height = 16;
+   afbc_superblock_width = 16;
+   break;
+   default:
+   DRM_DEBUG_KMS("AFBC superblock size is not 
supported\n");
+   return ERR_PTR(-EINVAL);
+   }
 
-static bool
-malidp_verify_afbc_framebuffer_size(struct drm_device *dev,
-   struct drm_file *file,
-   const struct drm_mode_fb_cmd2 *mode_cmd)
-{
-   int n_superblocks = 0;
-   const struct drm_format_info *info;
-   struct drm_gem_object *objs = NULL;
-   u32 afbc_superblock_size = 0, afbc_superblock_height = 0;
-   u32 afbc_superblock_width = 0, afbc_size = 0;
-   int bpp = 0;
-
-   switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
-   case AFBC_SIZE_16X16:
-   afbc_superblock_height = 16;
-   afbc_superblock_width = 16;
-   break;
-   default:
-   DRM_DEBUG_KMS("AFBC superblock size is not supported\n");
-   return false;
-   }
+   info = drm_get_format_info(dev, mode_cmd);
 
-   info = drm_get_format_info(dev, mode_cmd);
+   n_superblocks = (mode_cmd->width / afbc_superblock_width) *
+   (mode_cmd->height / afbc_superblock_height);
 
-   n_superblocks = (mode_cmd->width / afbc_superblock_width) *
-   (mode_cmd->height / afbc_superblock_height);
+   bpp = malidp_format_get_bpp(info->format);
 
-   bpp = malidp_format_get_bpp(info->format);
+   afbc_superblock_size 

[PATCHv6 1/6] drm/core: Allow drivers allocate a subclass of struct drm_framebuffer

2020-03-03 Thread Andrzej Pietrasiewicz
Allow allocating a specialized version of struct drm_framebuffer
by moving the actual fb allocation out of drm_gem_fb_create_with_funcs();
the respective functions names are adjusted to reflect that fact.
Please note, though, that standard size checks are performed on buffers,
so the drm_gem_fb_init_with_funcs() is useful for cases where those
standard size checks are appropriate or at least don't conflict the
checks to be performed in the specialized case.

Thanks to this change the drivers can call drm_gem_fb_init_with_funcs()
having allocated their special version of struct drm_framebuffer, exactly
the way the new version of drm_gem_fb_create_with_funcs() does.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/drm_gem_framebuffer_helper.c | 65 +++-
 include/drm/drm_gem_framebuffer_helper.h |  5 ++
 2 files changed, 56 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index 3a7ace19a902..388a080cd2df 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -55,18 +55,14 @@ 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 *
-drm_gem_fb_alloc(struct drm_device *dev,
+drm_gem_fb_init(struct drm_device *dev,
+struct drm_framebuffer *fb,
 const struct drm_mode_fb_cmd2 *mode_cmd,
 struct drm_gem_object **obj, unsigned int num_planes,
 const struct drm_framebuffer_funcs *funcs)
 {
-   struct drm_framebuffer *fb;
int ret, i;
 
-   fb = kzalloc(sizeof(*fb), GFP_KERNEL);
-   if (!fb)
-   return ERR_PTR(-ENOMEM);
-
drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
 
for (i = 0; i < num_planes; i++)
@@ -123,10 +119,13 @@ int drm_gem_fb_create_handle(struct drm_framebuffer *fb, 
struct drm_file *file,
 EXPORT_SYMBOL(drm_gem_fb_create_handle);
 
 /**
- * drm_gem_fb_create_with_funcs() - Helper function for the
- *  _mode_config_funcs.fb_create
- *  callback
+ * drm_gem_fb_init_with_funcs() - Helper function for implementing
+ *   _mode_config_funcs.fb_create
+ *   callback in cases when the driver
+ *   allocates a subclass of
+ *   struct drm_framebuffer
  * @dev: DRM device
+ * @fb: framebuffer object
  * @file: DRM file that holds the GEM handle(s) backing the framebuffer
  * @mode_cmd: Metadata from the userspace framebuffer creation request
  * @funcs: vtable to be used for the new framebuffer object
@@ -134,18 +133,21 @@ EXPORT_SYMBOL(drm_gem_fb_create_handle);
  * This function can be used to set _framebuffer_funcs for drivers that 
need
  * custom framebuffer callbacks. Use drm_gem_fb_create() if you don't need to
  * change _framebuffer_funcs. The function does buffer size validation.
+ * The buffer size validation is for a general case, though, so users should
+ * pay attention to the checks being appropriate for them or, at least,
+ * non-conflicting.
  *
  * Returns:
  * Pointer to a _framebuffer on success or an error pointer on failure.
  */
 struct drm_framebuffer *
-drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
-const struct drm_mode_fb_cmd2 *mode_cmd,
-const struct drm_framebuffer_funcs *funcs)
+drm_gem_fb_init_with_funcs(struct drm_device *dev, struct drm_framebuffer *fb,
+  struct drm_file *file,
+  const struct drm_mode_fb_cmd2 *mode_cmd,
+  const struct drm_framebuffer_funcs *funcs)
 {
const struct drm_format_info *info;
struct drm_gem_object *objs[4];
-   struct drm_framebuffer *fb;
int ret, i;
 
info = drm_get_format_info(dev, mode_cmd);
@@ -175,7 +177,7 @@ drm_gem_fb_create_with_funcs(struct drm_device *dev, struct 
drm_file *file,
}
}
 
-   fb = drm_gem_fb_alloc(dev, mode_cmd, objs, i, funcs);
+   fb = drm_gem_fb_init(dev, fb, mode_cmd, objs, i, funcs);
if (IS_ERR(fb)) {
ret = PTR_ERR(fb);
goto err_gem_object_put;
@@ -189,6 +191,41 @@ drm_gem_fb_create_with_funcs(struct drm_device *dev, 
struct drm_file *file,
 
return ERR_PTR(ret);
 }
+EXPORT_SYMBOL_GPL(drm_gem_fb_init_with_funcs);
+
+/**
+ * drm_gem_fb_create_with_funcs() - Helper function for the
+ *  _mode_config_funcs.fb_create
+ *  callback
+ * @dev: DRM device
+ * @file: DRM file that holds the GEM handle(s) backing the framebuffer
+ * @mode_cmd: Metadata from the userspace framebuffer creation request
+ * @funcs: vtable to be used for the new framebuf

[PATCHv6 2/6] drm/core: Add drm_afbc_framebuffer and a corresponding helper

2020-03-03 Thread Andrzej Pietrasiewicz
The new struct contains afbc-specific data.

The new function can be used by drivers which support afbc to complete
the preparation of struct drm_afbc_framebuffer. It must be called after
allocating the said struct and calling drm_gem_fb_init_with_funcs().

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/drm_gem_framebuffer_helper.c | 121 +++
 include/drm/drm_framebuffer.h|  45 +++
 include/drm/drm_gem_framebuffer_helper.h |  11 ++
 3 files changed, 177 insertions(+)

diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index 388a080cd2df..2a30f5b6829f 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -21,6 +21,13 @@
 #include 
 #include 
 
+#define AFBC_HEADER_SIZE   16
+#define AFBC_TH_LAYOUT_ALIGNMENT   8
+#define AFBC_HDR_ALIGN 64
+#define AFBC_SUPERBLOCK_PIXELS 256
+#define AFBC_SUPERBLOCK_ALIGNMENT  128
+#define AFBC_TH_BODY_START_ALIGNMENT   4096
+
 /**
  * DOC: overview
  *
@@ -302,6 +309,120 @@ drm_gem_fb_create_with_dirty(struct drm_device *dev, 
struct drm_file *file,
 }
 EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty);
 
+/**
+ * drm_afbc_get_superblock_wh - extract afbc block width/height from modifier
+ * @modifier: the modifier to be looked at
+ * @w: address of a place to store the block width
+ * @h: address of a place to store the block height
+ *
+ * Returns: true if the modifier describes a supported block size
+ */
+bool drm_afbc_get_superblock_wh(u64 modifier, u32 *w, u32 *h)
+{
+   switch (modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
+   case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
+   *w = 16;
+   *h = 16;
+   break;
+   case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
+   *w = 32;
+   *h = 8;
+   break;
+   /* no user exists yet - fall through */
+   case AFBC_FORMAT_MOD_BLOCK_SIZE_64x4:
+   case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4:
+   default:
+   DRM_DEBUG_KMS("Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n",
+ modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
+   return false;
+   }
+   return true;
+}
+EXPORT_SYMBOL_GPL(drm_afbc_get_superblock_wh);
+
+static int drm_gem_afbc_min_size(struct drm_device *dev,
+const struct drm_mode_fb_cmd2 *mode_cmd,
+struct drm_afbc_framebuffer *afbc_fb)
+{
+   const struct drm_format_info *info;
+   u32 n_blocks, w_alignment, h_alignment, hdr_alignment;
+   u32 tmp_bpp; /* remove when all users properly encode cpp in 
drm_format_info */
+
+   if (!drm_afbc_get_superblock_wh(mode_cmd->modifier[0], 
_fb->block_width, _fb->block_height))
+   return -EINVAL;
+
+   /* tiled header afbc */
+   w_alignment = afbc_fb->block_width;
+   h_alignment = afbc_fb->block_height;
+   hdr_alignment = AFBC_HDR_ALIGN;
+   if (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_TILED) {
+   w_alignment *= AFBC_TH_LAYOUT_ALIGNMENT;
+   h_alignment *= AFBC_TH_LAYOUT_ALIGNMENT;
+   hdr_alignment = AFBC_TH_BODY_START_ALIGNMENT;
+   }
+
+   afbc_fb->aligned_width = ALIGN(mode_cmd->width, w_alignment);
+   afbc_fb->aligned_height = ALIGN(mode_cmd->height, h_alignment);
+   afbc_fb->offset = mode_cmd->offsets[0];
+
+   /* Change to always using info->cpp[0] when all users properly encode 
it */
+   info = drm_get_format_info(dev, mode_cmd);
+   tmp_bpp = info->cpp[0] ? info->cpp[0] * 8 : afbc_fb->bpp;
+
+   n_blocks = (afbc_fb->aligned_width * afbc_fb->aligned_height) / 
AFBC_SUPERBLOCK_PIXELS;
+   afbc_fb->afbc_size = ALIGN(n_blocks * AFBC_HEADER_SIZE, hdr_alignment);
+   afbc_fb->afbc_size += n_blocks * ALIGN(tmp_bpp * AFBC_SUPERBLOCK_PIXELS 
/ 8, AFBC_SUPERBLOCK_ALIGNMENT);
+
+   return 0;
+}
+
+/**
+ * drm_gem_fb_afbc_init() - Helper function for drivers using afbc to
+ * fill and validate all the afbc-specific
+ * struct drm_afbc_framebuffer members
+ *
+ * @dev: DRM device
+ * @afbc_fb: afbc-specific framebuffer
+ * @mode_cmd: Metadata from the userspace framebuffer creation request
+ * @afbc_fb: afbc framebuffer
+ *
+ * This function can be used by drivers which support afbc to complete
+ * the preparation of struct drm_afbc_framebuffer. It must be called after
+ * allocating the said struct and calling drm_gem_fb_init_with_funcs().
+ *
+ * Returns:
+ * Zero on success or a negative error value on failure.
+ */
+int drm_gem_fb_afbc_init(struct drm_device *dev, const struct drm_mode_fb_cmd2 
*mode_cmd,
+struct drm_afbc_framebuffer *afbc_fb)
+{
+   const struct drm_format_info *info;

[PATCHv6 0/6] Add AFBC support for Rockchip

2020-03-03 Thread Andrzej Pietrasiewicz
This series adds AFBC support for Rockchip. It is inspired by:

https://chromium.googlesource.com/chromiumos/third_party/kernel/+/refs/heads/factory-gru-9017.B-chromeos-4.4/drivers/gpu/drm/rockchip/rockchip_drm_vop.c

This is the sixth iteration of the afbc series.

Compared to v5 it simplifies the way afbc-related helpers are
exposed to their users.

A new struct drm_afbc_framebuffer is added, which stores afbc-related
driver-specific data. Interested drivers need to explicitly allocate
an instance of struct drm_afbc_framebuffer, use drm_gem_fb_init_with_funcs()
call drm_gem_fb_afbc_init() and do their specific afbc-related checks.

There are 3 interested drivers: malidp, komeda and rockchip and I only have
rockchip hardware. As Liviu reports, due to the coronavirus outbreak,
it is difficult to test komeda now, so, according to his suggestion,
I purposedly omit changes to komeda. Malidp is changed accordingly, though,
which is a proof that it can be done. Then adding afbc support for rockchip
follows the malidp example.

I kindly ask for reviewing the series. I need to mention that my ultimate
goal is merging afbc for rockchip and I don't have other hardware, so some
help from malidp developers/maintainers would be appreciated.

Rebased onto drm-misc-next.

v5..v6:
- reworked the way afbc-specific helpers are exposed to drivers (Daniel)
- not checking block size mask in drm_is_afbc (James)
- fixed the test for afbc format (Boris)
- documented unused afbc format modifier values in drm_afbc_get_superblock_wh()
(Boris)
- changed drm_is_afbc to a macro
- renamed drm_gem_fb_lookup() to drm_gem_fb_objs_lookup() (James)
- eliminated storing block/tile alignment constraint in
 struct drm_afbc_framebuffer (James)
- eliminated storing afbc header alignment constraint
 in struct drm_afbc_framebuffer (James)
- eliminated storing afbc payload's offset in struct
drm_afbc_framebuffer (James)
- moved to taking bpp value from drm_format_info except malidp which doesn't
set it properly (James)
- removed unrelated coding style fixes in rockchip (Boris)
- consolidated 2-line error messages into one-liners in rockchip (Boris)
- added checking that there is at most one AFBC plane in
vop_crtc_atomic_check() (Boris)
- added checking that AFBC format is indeed supported in
rockchip_mod_supported() (Boris)
- removed requirement of exactly one color plane in rockchip_mod_supported()
- removed afbc_win hack in rockchip in favor of adding a field to crtc state
and ensuring only one AFBC plane in crtc's atomic check (Boris)

v4..v5:
- used proper way of subclassing drm_framebuffer (Daniel Vetter)
- added documentation to exported functions (Liviu Dudau)
- reordered new functions in drm_gem_framebuffer_helper.c to make a saner
diff (Liviu Dudau)
- used "2" suffix instead of "_special" for the special version of size
checks (Liviu Dudau)
- dropped unnecessarily added condition in drm_get_format_info() (Liviu
Dudau)
- dropped "block_size = 0;" trick in framebuffer_check() (Daniel Vetter)
- relaxed sticking to 80 characters per line rule in some cases

v3..v4:

- addressed (some) comments from Daniel Stone, Ezequiel Garcia, Daniel
Vetter and James Qian Wang - thank you for input
- refactored helpers to ease accommodating drivers with afbc needs
- moved afbc checks to helpers
- converted komeda, malidp and (the newly added) rockchip to use the afbc
helpers
- eliminated a separate, dedicated source code file

v2..v3:

- addressed (some) comments from Daniel Stone, Liviu Dudau, Daniel Vetter
and Brian Starkey - thank you all

In this iteration some rework has been done. The checking logic is now moved
to framebuffer_check() so it is common to all drivers. But the common part
is not good for komeda, so this series is not good for merging yet.
I kindly ask for feedback whether the changes are in the right direction.
I also kindly ask for input on how to accommodate komeda.

The CONFIG_DRM_AFBC option has been eliminated in favour of adding
drm_afbc.c to drm_kms_helper.

v1..v2:

- addressed comments from Daniel Stone, Ayan Halder, Mihail Atanassov
- coding style fixes


Andrzej Pietrasiewicz (6):
  drm/core: Allow drivers allocate a subclass of struct drm_framebuffer
  drm/core: Add drm_afbc_framebuffer and a corresponding helper
  drm/arm/malidp: Factor-in framebuffer creation
  drm/arm/malidp: Allocate an afbc-specific drm_framebuffer
  drm/arm/malidp: Switch to afbc helpers
  drm/rockchip: Add support for afbc

 drivers/gpu/drm/arm/malidp_drv.c | 150 ++-
 drivers/gpu/drm/drm_gem_framebuffer_helper.c | 186 +--
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h  |   1 +
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c   |  32 +++-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c  | 136 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h  |  12 ++
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c  |  83 -
 include/drm/drm_framebuffer.h|  45 +
 include/dr

Re: [PATCHv4,04/36] drm/gem-fb-helper: Add special version of drm_gem_fb_size_check

2020-02-17 Thread Andrzej Pietrasiewicz

Hi James,

Thank you for the review.

Did you intentionally review patches from the v4 series or you simply
didn't notice the v5? There are some differences, the most notable one
is using proper way of subclassing a drm_framebuffer.
The v5 series was sent on 17th December 2019.

Andrzej

W dniu 17.02.2020 o 09:16, james qian wang (Arm Technology China) pisze:

Hi Andrzej:

Really a good idea for introducing this custom size check, it's very
useful for some Komeda/malidp format, espcially pitch_multiplier, maybe
in future we can add it into into the drm_format_info.

On Fri, Dec 13, 2019 at 04:58:35PM +0100, Andrzej Pietrasiewicz wrote:

The new version accepts a struct describing deviations from standard way of
doing the size checks. The caller must provide the respective values.

Signed-off-by: Andrzej Pietrasiewicz 
---
  drivers/gpu/drm/drm_gem_framebuffer_helper.c | 47 
  include/drm/drm_gem_framebuffer_helper.h | 16 +++
  2 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index 787edb9a916b..4201dc1f32a5 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -201,8 +201,9 @@ int drm_gem_fb_lookup(struct drm_device *dev,
  EXPORT_SYMBOL_GPL(drm_gem_fb_lookup);
  
  /**

- * drm_gem_fb_size_check() - Helper function for use in
- *  _mode_config_funcs.fb_create implementations
+ * drm_gem_fb_size_check_special() - Helper function for use in
+ *  _mode_config_funcs.fb_create
+ *  implementations
   * @dev: DRM device
   * @mode_cmd: Metadata from the userspace framebuffer creation request
   *
@@ -212,9 +213,10 @@ EXPORT_SYMBOL_GPL(drm_gem_fb_lookup);
   * Returns:
   * Zero on success or a negative error code on failure.
   */
-int drm_gem_fb_size_check(struct drm_device *dev,
- const struct drm_mode_fb_cmd2 *mode_cmd,
- struct drm_gem_object **objs)
+int drm_gem_fb_size_check_special(struct drm_device *dev,


How about name it to drm_gem_fb_custom_size_check()


+ const struct drm_mode_fb_cmd2 *mode_cmd,
+ const struct drm_size_check *check,
+ struct drm_gem_object **objs)
  {
const struct drm_format_info *info;
int i;
@@ -227,10 +229,19 @@ int drm_gem_fb_size_check(struct drm_device *dev,
unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
unsigned int min_size;
+   u32 pitch = mode_cmd->pitches[i];
+
+   if (check && check->use_pitch_multiplier)
+   if ((pitch * check->pitch_multiplier[i]) %
+   check->pitch_modulo)
+   return -EINVAL;
  
-		min_size = (height - 1) * mode_cmd->pitches[i]

-+ drm_format_info_min_pitch(info, i, width)
-+ mode_cmd->offsets[i];
+   if (check && check->use_min_size)
+   min_size = check->min_size[i];
+   else
+   min_size = (height - 1) * pitch
++ drm_format_info_min_pitch(info, i, width)
++ mode_cmd->offsets[i];
  
  		if (objs[i]->size < min_size)

return -EINVAL;
@@ -239,6 +250,26 @@ int drm_gem_fb_size_check(struct drm_device *dev,
return 0;
  
  }

+EXPORT_SYMBOL_GPL(drm_gem_fb_size_check_special);
+
+/**
+ * drm_gem_fb_size_check() - Helper function for use in
+ *  _mode_config_funcs.fb_create implementations
+ * @dev: DRM device
+ * @mode_cmd: Metadata from the userspace framebuffer creation request
+ *
+ * This function can be used to verify buffer sizes for all planes.
+ * It is caller's responsibility to put the objects on failure.
+ *
+ * Returns:
+ * Zero on success or a negative error code on failure.
+ */
+int drm_gem_fb_size_check(struct drm_device *dev,
+ const struct drm_mode_fb_cmd2 *mode_cmd,
+ struct drm_gem_object **objs)
+{
+   return drm_gem_fb_size_check_special(dev, mode_cmd, NULL, objs);
+}
  EXPORT_SYMBOL_GPL(drm_gem_fb_size_check);
  
  /**

diff --git a/include/drm/drm_gem_framebuffer_helper.h 
b/include/drm/drm_gem_framebuffer_helper.h
index c85d4b152e91..74304a268694 100644
--- a/include/drm/drm_gem_framebuffer_helper.h
+++ b/include/drm/drm_gem_framebuffer_helper.h
@@ -11,6 +11,18 @@ struct drm_mode_fb_cmd2;
  struct drm_plane;
  struct drm_plane_state;
  struct drm_simple_display_pipe;
+struct drm_size_check;
+
+/**
+ * struct drm_size_check - Desc

Re: [PATCHv5 00/34] Add AFBC support for Rockchip

2020-02-07 Thread Andrzej Pietrasiewicz

Hi All again,

@malidp and komeda folks: I kindly ask you to have your say. If there is
no interest from you (which is ok with me) I will resend the series
dropping the komeda and malidp part.

Andrzej

W dniu 30.01.2020 o 10:08, Andrzej Pietrasiewicz pisze:

Hi All,

A gentle reminder.

Please also see inline:

W dniu 17.12.2019 o 15:49, Andrzej Pietrasiewicz pisze:

This series adds AFBC support for Rockchip. It is inspired by:

https://chromium.googlesource.com/chromiumos/third_party/kernel/+/refs/heads/factory-gru-9017.B-chromeos-4.4/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 



This is the fifth iteration of the afbc series. Between v3 and v4 a lot of
rework has been done, the main goal of which was to move all afbc-related
checks to helpers, so that core does not deal with it.

A new struct drm_afbc_framebuffer is added, which stores afbc-related
driver-specific data. Because of that, in drivers that wish to
use this feature, the struct must be allocated directly in the driver
code rather than inside helpers, so the first portion of the patchset
does the necessary refactoring.

Then, there are 3 users of afbc: komeda, malidp and, finally, rockchip,
the latter being the ultimate purpose of this work and the 3 subsequent
portions of the patchset move komeda and malidp to generic helpers and add
afbc support to rockchip.


If changes in komeda and malidp is too much to digest at a time I can
focus on rockchip only. This would amount to patches 1-4 and 33-34.
After all the ultimate purpose of this work and time spent on it
is landing afbc support for rockchip.

Regards,

Andrzej


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


Re: [PATCHv5 00/34] Add AFBC support for Rockchip

2020-01-30 Thread Andrzej Pietrasiewicz

Hi Liviu,

W dniu 30.01.2020 o 12:44, Liviu Dudau pisze:

Hi Andrzej,

Sorry for the delay in reviewing the patches. I am hoping to get through the 
review
early next week if that is OK with you.


Thanks, that would be great.

Andrzej



Best regards,
Liviu

On Thu, Jan 30, 2020 at 10:08:15AM +0100, Andrzej Pietrasiewicz wrote:

Hi All,

A gentle reminder.

Please also see inline:

W dniu 17.12.2019 o 15:49, Andrzej Pietrasiewicz pisze:

This series adds AFBC support for Rockchip. It is inspired by:

https://chromium.googlesource.com/chromiumos/third_party/kernel/+/refs/heads/factory-gru-9017.B-chromeos-4.4/drivers/gpu/drm/rockchip/rockchip_drm_vop.c

This is the fifth iteration of the afbc series. Between v3 and v4 a lot of
rework has been done, the main goal of which was to move all afbc-related
checks to helpers, so that core does not deal with it.

A new struct drm_afbc_framebuffer is added, which stores afbc-related
driver-specific data. Because of that, in drivers that wish to
use this feature, the struct must be allocated directly in the driver
code rather than inside helpers, so the first portion of the patchset
does the necessary refactoring.

Then, there are 3 users of afbc: komeda, malidp and, finally, rockchip,
the latter being the ultimate purpose of this work and the 3 subsequent
portions of the patchset move komeda and malidp to generic helpers and add
afbc support to rockchip.


If changes in komeda and malidp is too much to digest at a time I can
focus on rockchip only. This would amount to patches 1-4 and 33-34.
After all the ultimate purpose of this work and time spent on it
is landing afbc support for rockchip.

Regards,

Andrzej




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


Re: [PATCHv5 00/34] Add AFBC support for Rockchip

2020-01-30 Thread Andrzej Pietrasiewicz

Hi All,

A gentle reminder.

Please also see inline:

W dniu 17.12.2019 o 15:49, Andrzej Pietrasiewicz pisze:

This series adds AFBC support for Rockchip. It is inspired by:

https://chromium.googlesource.com/chromiumos/third_party/kernel/+/refs/heads/factory-gru-9017.B-chromeos-4.4/drivers/gpu/drm/rockchip/rockchip_drm_vop.c

This is the fifth iteration of the afbc series. Between v3 and v4 a lot of
rework has been done, the main goal of which was to move all afbc-related
checks to helpers, so that core does not deal with it.

A new struct drm_afbc_framebuffer is added, which stores afbc-related
driver-specific data. Because of that, in drivers that wish to
use this feature, the struct must be allocated directly in the driver
code rather than inside helpers, so the first portion of the patchset
does the necessary refactoring.

Then, there are 3 users of afbc: komeda, malidp and, finally, rockchip,
the latter being the ultimate purpose of this work and the 3 subsequent
portions of the patchset move komeda and malidp to generic helpers and add
afbc support to rockchip.


If changes in komeda and malidp is too much to digest at a time I can
focus on rockchip only. This would amount to patches 1-4 and 33-34.
After all the ultimate purpose of this work and time spent on it
is landing afbc support for rockchip.

Regards,

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


[PATCH 2/4] drm/vc4: Provide ddc symlink in connector sysfs directory

2020-01-02 Thread Andrzej Pietrasiewicz
Use the ddc pointer provided by the generic connector.

Signed-off-by: Andrzej Pietrasiewicz 
Acked-by: Sam Ravnborg 
Reviewed-by: Emil Velikov 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 1c62c6c9244b..cea18dc15f77 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -267,7 +267,8 @@ static const struct drm_connector_helper_funcs 
vc4_hdmi_connector_helper_funcs =
 };
 
 static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
-struct drm_encoder 
*encoder)
+struct drm_encoder 
*encoder,
+struct i2c_adapter *ddc)
 {
struct drm_connector *connector;
struct vc4_hdmi_connector *hdmi_connector;
@@ -281,8 +282,10 @@ static struct drm_connector 
*vc4_hdmi_connector_init(struct drm_device *dev,
 
hdmi_connector->encoder = encoder;
 
-   drm_connector_init(dev, connector, _hdmi_connector_funcs,
-  DRM_MODE_CONNECTOR_HDMIA);
+   drm_connector_init_with_ddc(dev, connector,
+   _hdmi_connector_funcs,
+   DRM_MODE_CONNECTOR_HDMIA,
+   ddc);
drm_connector_helper_add(connector, _hdmi_connector_helper_funcs);
 
/* Create and attach TV margin props to this connector. */
@@ -1395,7 +1398,8 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
 DRM_MODE_ENCODER_TMDS, NULL);
drm_encoder_helper_add(hdmi->encoder, _hdmi_encoder_helper_funcs);
 
-   hdmi->connector = vc4_hdmi_connector_init(drm, hdmi->encoder);
+   hdmi->connector =
+   vc4_hdmi_connector_init(drm, hdmi->encoder, hdmi->ddc);
if (IS_ERR(hdmi->connector)) {
ret = PTR_ERR(hdmi->connector);
goto err_destroy_encoder;
-- 
2.17.1

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


[PATCH 0/4] Complete ddc symlink addition

2020-01-02 Thread Andrzej Pietrasiewicz
The series completes the process of adding ddc symlink in connector's
sysfs directory: of the initial submission only the below patches are
still pending, hence this resend. Rebased onto drm-misc-next as of
2020-01-02.

Andrzej Pietrasiewicz (4):
  drm/tegra: Provide ddc symlink in output connector sysfs directory
  drm/vc4: Provide ddc symlink in connector sysfs directory
  drm: zte: Provide ddc symlink in hdmi connector sysfs directory
  drm: zte: Provide ddc symlink in vga connector sysfs directory

 drivers/gpu/drm/tegra/hdmi.c   |  7 ---
 drivers/gpu/drm/tegra/sor.c|  7 ---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 12 
 drivers/gpu/drm/zte/zx_hdmi.c  |  6 --
 drivers/gpu/drm/zte/zx_vga.c   |  6 --
 5 files changed, 24 insertions(+), 14 deletions(-)

-- 
2.17.1

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


[PATCH 4/4] drm: zte: Provide ddc symlink in vga connector sysfs directory

2020-01-02 Thread Andrzej Pietrasiewicz
Use the ddc pointer provided by the generic connector.

Signed-off-by: Andrzej Pietrasiewicz 
Acked-by: Sam Ravnborg 
Reviewed-by: Emil Velikov 
---
 drivers/gpu/drm/zte/zx_vga.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/zte/zx_vga.c b/drivers/gpu/drm/zte/zx_vga.c
index 9b67e419280c..c4fa3bbaba78 100644
--- a/drivers/gpu/drm/zte/zx_vga.c
+++ b/drivers/gpu/drm/zte/zx_vga.c
@@ -165,8 +165,10 @@ static int zx_vga_register(struct drm_device *drm, struct 
zx_vga *vga)
 
vga->connector.polled = DRM_CONNECTOR_POLL_HPD;
 
-   ret = drm_connector_init(drm, connector, _vga_connector_funcs,
-DRM_MODE_CONNECTOR_VGA);
+   ret = drm_connector_init_with_ddc(drm, connector,
+ _vga_connector_funcs,
+ DRM_MODE_CONNECTOR_VGA,
+ >ddc->adap);
if (ret) {
DRM_DEV_ERROR(dev, "failed to init connector: %d\n", ret);
goto clean_encoder;
-- 
2.17.1

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


[PATCH 3/4] drm: zte: Provide ddc symlink in hdmi connector sysfs directory

2020-01-02 Thread Andrzej Pietrasiewicz
Use the ddc pointer provided by the generic connector.

Signed-off-by: Andrzej Pietrasiewicz 
Acked-by: Sam Ravnborg 
Reviewed-by: Emil Velikov 
---
 drivers/gpu/drm/zte/zx_hdmi.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/zte/zx_hdmi.c b/drivers/gpu/drm/zte/zx_hdmi.c
index a50f5a1f09b8..b98a1420dcd3 100644
--- a/drivers/gpu/drm/zte/zx_hdmi.c
+++ b/drivers/gpu/drm/zte/zx_hdmi.c
@@ -319,8 +319,10 @@ static int zx_hdmi_register(struct drm_device *drm, struct 
zx_hdmi *hdmi)
 
hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
 
-   drm_connector_init(drm, >connector, _hdmi_connector_funcs,
-  DRM_MODE_CONNECTOR_HDMIA);
+   drm_connector_init_with_ddc(drm, >connector,
+   _hdmi_connector_funcs,
+   DRM_MODE_CONNECTOR_HDMIA,
+   >ddc->adap);
drm_connector_helper_add(>connector,
 _hdmi_connector_helper_funcs);
 
-- 
2.17.1

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


[PATCH 1/4] drm/tegra: Provide ddc symlink in output connector sysfs directory

2020-01-02 Thread Andrzej Pietrasiewicz
Use the ddc pointer provided by the generic connector.

Signed-off-by: Andrzej Pietrasiewicz 
Acked-by: Sam Ravnborg 
Reviewed-by: Emil Velikov 
---
 drivers/gpu/drm/tegra/hdmi.c | 7 ---
 drivers/gpu/drm/tegra/sor.c  | 7 ---
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index 50269ffbcb6b..21a629adcb51 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -1430,9 +1430,10 @@ static int tegra_hdmi_init(struct host1x_client *client)
 
hdmi->output.dev = client->dev;
 
-   drm_connector_init(drm, >output.connector,
-  _hdmi_connector_funcs,
-  DRM_MODE_CONNECTOR_HDMIA);
+   drm_connector_init_with_ddc(drm, >output.connector,
+   _hdmi_connector_funcs,
+   DRM_MODE_CONNECTOR_HDMIA,
+   hdmi->output.ddc);
drm_connector_helper_add(>output.connector,
 _hdmi_connector_helper_funcs);
hdmi->output.connector.dpms = DRM_MODE_DPMS_OFF;
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index fbbb974c1e1a..7fbcb348c7ee 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -2836,9 +2836,10 @@ static int tegra_sor_init(struct host1x_client *client)
 
sor->output.dev = sor->dev;
 
-   drm_connector_init(drm, >output.connector,
-  _sor_connector_funcs,
-  connector);
+   drm_connector_init_with_ddc(drm, >output.connector,
+   _sor_connector_funcs,
+   connector,
+   sor->output.ddc);
drm_connector_helper_add(>output.connector,
 _sor_connector_helper_funcs);
sor->output.connector.dpms = DRM_MODE_DPMS_OFF;
-- 
2.17.1

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


[PATCHv5 31/34] drm/arm/malidp: Factor in afbc framebuffer verification

2019-12-17 Thread Andrzej Pietrasiewicz
Prepare for using generic afbc-aware helpers.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/arm/malidp_drv.c | 142 +++
 1 file changed, 68 insertions(+), 74 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index e1502666bce0..b53fc01baf2b 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -269,94 +269,88 @@ static const struct drm_mode_config_helper_funcs 
malidp_mode_config_helpers = {
.atomic_commit_tail = malidp_atomic_commit_tail,
 };
 
-static bool
-malidp_verify_afbc_framebuffer(struct drm_device *dev, struct drm_file *file,
-  const struct drm_mode_fb_cmd2 *mode_cmd)
+static struct drm_framebuffer *
+malidp_fb_create(struct drm_device *dev, struct drm_file *file,
+const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-   int n_superblocks = 0;
-   const struct drm_format_info *info;
-   struct drm_gem_object *objs = NULL;
-   u32 afbc_superblock_size = 0, afbc_superblock_height = 0;
-   u32 afbc_superblock_width = 0, afbc_size = 0;
-   int bpp = 0;
-
-   if (malidp_format_mod_supported(dev, mode_cmd->pixel_format,
-   mode_cmd->modifier[0]) == false)
-   return false;
-
-   if (mode_cmd->offsets[0] != 0) {
-   DRM_DEBUG_KMS("AFBC buffers' plane offset should be 0\n");
-   return false;
-   }
+   if (mode_cmd->modifier[0]) {
+   int n_superblocks = 0;
+   const struct drm_format_info *info;
+   struct drm_gem_object *objs = NULL;
+   u32 afbc_superblock_size = 0, afbc_superblock_height = 0;
+   u32 afbc_superblock_width = 0, afbc_size = 0;
+   int bpp = 0;
+
+   if (malidp_format_mod_supported(dev, mode_cmd->pixel_format,
+   mode_cmd->modifier[0]) == false)
+   return ERR_PTR(-EINVAL);
 
-   switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
-   case AFBC_SIZE_16X16:
-   if ((mode_cmd->width % 16) || (mode_cmd->height % 16)) {
-   DRM_DEBUG_KMS("AFBC buffers must be aligned to 16 
pixels\n");
-   return false;
+   if (mode_cmd->offsets[0] != 0) {
+   DRM_DEBUG_KMS("AFBC buffers' plane offset should be 
0\n");
+   return ERR_PTR(-EINVAL);
}
-   break;
-   default:
-   DRM_DEBUG_KMS("Unsupported AFBC block size\n");
-   return false;
-   }
 
-   switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
-   case AFBC_SIZE_16X16:
-   afbc_superblock_height = 16;
-   afbc_superblock_width = 16;
-   break;
-   default:
-   DRM_DEBUG_KMS("AFBC superblock size is not supported\n");
-   return false;
-   }
+   switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
+   case AFBC_SIZE_16X16:
+   if ((mode_cmd->width % 16) || (mode_cmd->height % 16)) {
+   DRM_DEBUG_KMS("AFBC buffers must be aligned to 
16 pixels\n");
+   return ERR_PTR(-EINVAL);
+   }
+   break;
+   default:
+   DRM_DEBUG_KMS("Unsupported AFBC block size\n");
+   return ERR_PTR(-EINVAL);
+   }
 
-   info = drm_get_format_info(dev, mode_cmd);
+   switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
+   case AFBC_SIZE_16X16:
+   afbc_superblock_height = 16;
+   afbc_superblock_width = 16;
+   break;
+   default:
+   DRM_DEBUG_KMS("AFBC superblock size is not 
supported\n");
+   return ERR_PTR(-EINVAL);
+   }
 
-   n_superblocks = (mode_cmd->width / afbc_superblock_width) *
-   (mode_cmd->height / afbc_superblock_height);
+   info = drm_get_format_info(dev, mode_cmd);
 
-   bpp = malidp_format_get_bpp(info->format);
+   n_superblocks = (mode_cmd->width / afbc_superblock_width) *
+   (mode_cmd->height / afbc_superblock_height);
 
-   afbc_superblock_size = (bpp * afbc_superblock_width * 
afbc_superblock_height)
-   / BITS_PER_BYTE;
+   bpp = malidp_format_get_bpp(info->format);
 
-   afbc_size = ALIGN(n_superblocks * AFBC_HEADER_SIZE, 
AFBC_SUPERBLK_ALIGNMENT);
-   afbc_size += n_superblocks * ALIGN(afbc_superblock_size, 
AFBC_SUPERBLK_ALIGNMENT);
+   afbc_superbloc

[PATCHv5 32/34] drm/arm/malidp: Use generic helpers for afbc checks

2019-12-17 Thread Andrzej Pietrasiewicz
Helpers are now available for checking afbc buffer properties. Use those.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/arm/malidp_drv.c | 71 ++--
 1 file changed, 30 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index b53fc01baf2b..4cbd920b48cd 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -273,12 +273,17 @@ static struct drm_framebuffer *
 malidp_fb_create(struct drm_device *dev, struct drm_file *file,
 const struct drm_mode_fb_cmd2 *mode_cmd)
 {
+   struct drm_size_check check = { 0 };
+   struct drm_gem_object *objs[4];
+   struct drm_afbc_framebuffer *afbc_fb;
+   int ret, i, num_planes;
+
+   afbc_fb = kzalloc(sizeof(*afbc_fb), GFP_KERNEL);
+   if (!afbc_fb)
+   return ERR_PTR(-ENOMEM);
+
if (mode_cmd->modifier[0]) {
-   int n_superblocks = 0;
const struct drm_format_info *info;
-   struct drm_gem_object *objs = NULL;
-   u32 afbc_superblock_size = 0, afbc_superblock_height = 0;
-   u32 afbc_superblock_width = 0, afbc_size = 0;
int bpp = 0;
 
if (malidp_format_mod_supported(dev, mode_cmd->pixel_format,
@@ -302,32 +307,9 @@ malidp_fb_create(struct drm_device *dev, struct drm_file 
*file,
return ERR_PTR(-EINVAL);
}
 
-   switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
-   case AFBC_SIZE_16X16:
-   afbc_superblock_height = 16;
-   afbc_superblock_width = 16;
-   break;
-   default:
-   DRM_DEBUG_KMS("AFBC superblock size is not 
supported\n");
-   return ERR_PTR(-EINVAL);
-   }
-
info = drm_get_format_info(dev, mode_cmd);
-
-   n_superblocks = (mode_cmd->width / afbc_superblock_width) *
-   (mode_cmd->height / afbc_superblock_height);
-
bpp = malidp_format_get_bpp(info->format);
 
-   afbc_superblock_size =
-   (bpp * afbc_superblock_width * afbc_superblock_height)
-   / BITS_PER_BYTE;
-
-   afbc_size = ALIGN(n_superblocks * AFBC_HEADER_SIZE,
- AFBC_SUPERBLK_ALIGNMENT);
-   afbc_size += n_superblocks
-   * ALIGN(afbc_superblock_size, AFBC_SUPERBLK_ALIGNMENT);
-
if ((mode_cmd->width * bpp) !=
(mode_cmd->pitches[0] * BITS_PER_BYTE)) {
DRM_DEBUG_KMS("Invalid value of (pitch * BITS_PER_BYTE) 
(=%u) "
@@ -336,24 +318,31 @@ malidp_fb_create(struct drm_device *dev, struct drm_file 
*file,
  mode_cmd->width, bpp);
return ERR_PTR(-EINVAL);
}
+   afbc_fb->bpp = bpp;
+   check.data = afbc_fb;
+   }
 
-   objs = drm_gem_object_lookup(file, mode_cmd->handles[0]);
-   if (!objs) {
-   DRM_DEBUG_KMS("Failed to lookup GEM object\n");
-   return ERR_PTR(-EINVAL);
-   }
+   ret = drm_gem_fb_lookup(dev, file, mode_cmd, objs);
+   if (ret < 0)
+   goto err_free;
+   num_planes = ret;
 
-   if (objs->size < afbc_size) {
-   DRM_DEBUG_KMS("buffer size (%zu) too small for AFBC 
buffer size = %u\n",
- objs->size, afbc_size);
-   drm_gem_object_put_unlocked(objs);
-   return ERR_PTR(-EINVAL);
-   }
+   ret = drm_gem_fb_size_check2(dev, mode_cmd, , objs);
+   if (ret < 0)
+   goto err_cleanup;
 
-   drm_gem_object_put_unlocked(objs);
-   }
+   ret = drm_gem_fb_init(_fb->base, dev, mode_cmd, objs, num_planes);
+   if (ret < 0)
+   goto err_cleanup;
+
+   return _fb->base;
 
-   return drm_gem_fb_create(dev, file, mode_cmd);
+err_cleanup:
+   for (i = 0; i < num_planes; ++i)
+   drm_gem_object_put_unlocked(objs[i]);
+err_free:
+   kfree(afbc_fb);
+   return ERR_PTR(ret);
 }
 
 static const struct drm_mode_config_funcs malidp_mode_config_funcs = {
-- 
2.17.1

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


[PATCHv5 33/34] drm/rockchip: Use helper for common task

2019-12-17 Thread Andrzej Pietrasiewicz
Use generic helper code.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 12 ++--
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 221e72e71432..5806f908aa53 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -18,6 +18,7 @@
 #include "rockchip_drm_fb.h"
 #include "rockchip_drm_gem.h"
 
+
 static const struct drm_framebuffer_funcs rockchip_drm_fb_funcs = {
.destroy   = drm_gem_fb_destroy,
.create_handle = drm_gem_fb_create_handle,
@@ -30,22 +31,13 @@ rockchip_fb_alloc(struct drm_device *dev, const struct 
drm_mode_fb_cmd2 *mode_cm
 {
struct drm_framebuffer *fb;
int ret;
-   int i;
 
fb = kzalloc(sizeof(*fb), GFP_KERNEL);
if (!fb)
return ERR_PTR(-ENOMEM);
 
-   drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
-
-   for (i = 0; i < num_planes; i++)
-   fb->obj[i] = obj[i];
-
-   ret = drm_framebuffer_init(dev, fb, _drm_fb_funcs);
+   ret = drm_gem_fb_init_with_funcs(fb, dev, mode_cmd, obj, num_planes, 
_drm_fb_funcs);
if (ret) {
-   DRM_DEV_ERROR(dev->dev,
- "Failed to initialize framebuffer: %d\n",
- ret);
kfree(fb);
return ERR_PTR(ret);
}
-- 
2.17.1

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


[PATCHv5 20/34] drm/komeda: Move helper invocation to after size checks

2019-12-17 Thread Andrzej Pietrasiewicz
Between the old and new place nothing depends on data retrieved with the
helper, so it is safe to move its invocation.
The err_cleanup case is changed accordingly.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 42ccd4647919..c2b29d4e6fbb 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -154,7 +154,6 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
if (ret < 0)
goto err_free;
 
-   drm_helper_mode_fill_fb_struct(dev, >base, mode_cmd);
info = drm_get_format_info(dev, mode_cmd);
 
if (mode_cmd->modifier[0]) {
@@ -185,6 +184,8 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
goto err_cleanup;
}
 
+   drm_helper_mode_fill_fb_struct(dev, >base, mode_cmd);
+
for (i = 0; i < info->num_planes; ++i)
kfb->base.obj[i] = objs[i];
 
@@ -200,7 +201,7 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
return >base;
 
 err_cleanup:
-   for (i = 0; i < kfb->base.format->num_planes; i++)
+   for (i = 0; i < info->num_planes; i++)
drm_gem_object_put_unlocked(objs[i]);
 err_free:
kfree(kfb);
-- 
2.17.1

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


[PATCHv5 01/34] drm/core: Add afbc helper functions

2019-12-17 Thread Andrzej Pietrasiewicz
Add checking if a modifier is afbc and getting afbc block size.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/drm_fourcc.c | 53 
 include/drm/drm_fourcc.h |  4 +++
 2 files changed, 57 insertions(+)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index b234bfaeda06..d14dd7c86020 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -29,6 +29,7 @@
 
 #include 
 #include 
+#include 
 
 static char printable_char(int c)
 {
@@ -393,3 +394,55 @@ uint64_t drm_format_info_min_pitch(const struct 
drm_format_info *info,
drm_format_info_block_height(info, plane));
 }
 EXPORT_SYMBOL(drm_format_info_min_pitch);
+
+/**
+ * drm_is_afbc - test if the modifier describes an afbc buffer
+ * @modifier - modifier to be tested
+ *
+ * Returns: true if the modifier describes an afbc buffer
+ */
+bool drm_is_afbc(u64 modifier)
+{
+   /* is it ARM AFBC? */
+   if ((modifier & DRM_FORMAT_MOD_ARM_AFBC(0)) == 0)
+   return false;
+
+   /* Block size must be known */
+   if ((modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) == 0)
+   return false;
+
+   return true;
+}
+EXPORT_SYMBOL_GPL(drm_is_afbc);
+
+/**
+ * drm_afbc_get_superblock_wh - extract afbc block width/height from modifier
+ * @modifier: the modifier to be looked at
+ * @w: address of a place to store the block width
+ * @h: address of a place to store the block height
+ *
+ * Returns: true if the modifier describes a supported block size
+ */
+bool drm_afbc_get_superblock_wh(u64 modifier, u32 *w, u32 *h)
+{
+   switch (modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
+   case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
+   *w = 16;
+   *h = 16;
+   break;
+   case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
+   *w = 32;
+   *h = 8;
+   break;
+   case AFBC_FORMAT_MOD_BLOCK_SIZE_64x4:
+   /* fall through */
+   case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4:
+   /* fall through */
+   default:
+   DRM_DEBUG_KMS("Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n",
+ modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
+   return false;
+   }
+   return true;
+}
+EXPORT_SYMBOL_GPL(drm_afbc_get_superblock_wh);
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 306d1efeb5e0..7eb23062bf45 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -320,4 +320,8 @@ uint64_t drm_format_info_min_pitch(const struct 
drm_format_info *info,
   int plane, unsigned int buffer_width);
 const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf 
*buf);
 
+bool drm_is_afbc(u64 modifier);
+
+bool drm_afbc_get_superblock_wh(u64 modifier, u32 *w, u32 *h);
+
 #endif /* __DRM_FOURCC_H__ */
-- 
2.17.1

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


[PATCHv5 27/34] drm/komeda: Move special helper invocation outside if-else

2019-12-17 Thread Andrzej Pietrasiewicz
The invocation is the same in both cases and is the last thing inside a
block, so move it outside the if-else clause.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.c| 10 +++---
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 7e02a04cdd11..bf4309b62d37 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -44,6 +44,8 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
struct drm_gem_object *objs[4];
struct komeda_fb *kfb;
const struct drm_format_info *info;
+   struct drm_size_check check = { 0 };
+
int ret = 0, i, num_planes;
 
kfb = kzalloc(sizeof(*kfb), GFP_KERNEL);
@@ -68,7 +70,6 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
info = drm_get_format_info(dev, mode_cmd);
 
if (mode_cmd->modifier[0]) {
-   struct drm_size_check check = { 0 };
u32 alignment_w = 0, alignment_h = 0;
u32 alignment_header, n_blocks, bpp;
 
@@ -109,11 +110,7 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
   + n_blocks * ALIGN(bpp * AFBC_SUPERBLK_PIXELS / 
8, AFBC_SUPERBLK_ALIGNMENT);
check.min_size[0] = kfb->afbc_size + mode_cmd->offsets[0];
check.use_min_size = true;
-
-   ret = drm_gem_fb_size_check2(dev, mode_cmd, , objs);
} else {
-   struct drm_size_check check = { 0 };
-
ret = komeda_fb_check_src_coords(kfb, 0, 0, mode_cmd->width,
 mode_cmd->height);
if (ret)
@@ -135,9 +132,8 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
check.pitch_modulo = mdev->chip.bus_width;
check.use_pitch_multiplier = true;
check.use_min_size = true;
-
-   ret = drm_gem_fb_size_check2(dev, mode_cmd, , objs);
}
+   ret = drm_gem_fb_size_check2(dev, mode_cmd, , objs);
if (ret < 0)
goto err_cleanup;
 
-- 
2.17.1

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


[PATCHv5 34/34] drm/rockchip: Add support for afbc

2019-12-17 Thread Andrzej Pietrasiewicz
This patch adds support for afbc handling. afbc is a compressed format
which reduces the necessary memory bandwidth.

Co-developed-by: Mark Yao 
Signed-off-by: Mark Yao 
Signed-off-by: Andrzej Pietrasiewicz 

# Conflicts:
#   drivers/gpu/drm/rockchip/rockchip_drm_fb.c
---
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  | 105 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 147 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |  12 ++
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c |  83 ++-
 4 files changed, 329 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 5806f908aa53..f26cbaa46135 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -18,6 +18,7 @@
 #include "rockchip_drm_fb.h"
 #include "rockchip_drm_gem.h"
 
+#define ROCKCHIP_MAX_AFBC_WIDTH2560
 
 static const struct drm_framebuffer_funcs rockchip_drm_fb_funcs = {
.destroy   = drm_gem_fb_destroy,
@@ -25,32 +26,122 @@ static const struct drm_framebuffer_funcs 
rockchip_drm_fb_funcs = {
.dirty = drm_atomic_helper_dirtyfb,
 };
 
+static int rockchip_afbc_post_check(struct drm_afbc_framebuffer *afbc_fb)
+{
+   if (afbc_fb->offset) {
+   DRM_WARN("AFBC plane offset must be zero!\n");
+   return -EINVAL;
+   }
+
+   if (afbc_fb->block_width != 16 || afbc_fb->block_height != 16) {
+   DRM_WARN("Unsupported AFBC block w/h [%d/%d]\n", 
afbc_fb->block_width, afbc_fb->block_height);
+   return -EINVAL;
+   }
+
+   if (afbc_fb->aligned_width > ROCKCHIP_MAX_AFBC_WIDTH) {
+   DRM_WARN("Unsupported width %d>%d\n", afbc_fb->aligned_width, 
ROCKCHIP_MAX_AFBC_WIDTH);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 static struct drm_framebuffer *
 rockchip_fb_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2 
*mode_cmd,
  struct drm_gem_object **obj, unsigned int num_planes)
 {
-   struct drm_framebuffer *fb;
+   struct drm_afbc_framebuffer *afbc_fb;
+   struct drm_size_check check = { 0 };
int ret;
 
-   fb = kzalloc(sizeof(*fb), GFP_KERNEL);
-   if (!fb)
+   afbc_fb = kzalloc(sizeof(*afbc_fb), GFP_KERNEL);
+   if (!afbc_fb)
return ERR_PTR(-ENOMEM);
 
-   ret = drm_gem_fb_init_with_funcs(fb, dev, mode_cmd, obj, num_planes, 
_drm_fb_funcs);
+   if (drm_is_afbc(mode_cmd->modifier[0])) {
+   const struct drm_format_info *info = drm_get_format_info(dev, 
mode_cmd);
+
+   afbc_fb->bpp = info->cpp[0] * 8;
+   check.data = afbc_fb;
+   }
+
+   ret = drm_gem_fb_size_check2(dev, mode_cmd, , obj);
if (ret) {
-   kfree(fb);
+   kfree(afbc_fb);
return ERR_PTR(ret);
}
 
-   return fb;
+   if (drm_is_afbc(mode_cmd->modifier[0]))
+   if (rockchip_afbc_post_check(afbc_fb)) {
+   kfree(afbc_fb);
+   return ERR_PTR(-EINVAL);
+   }
+
+   ret = drm_gem_fb_init_with_funcs(_fb->base, dev, mode_cmd, obj, 
num_planes, _drm_fb_funcs);
+   if (ret) {
+   kfree(afbc_fb);
+   return ERR_PTR(ret);
+   }
+
+   return _fb->base;
 }
 
 static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers 
= {
.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
 };
 
+
+static struct drm_framebuffer *
+rockchip_fb_create(struct drm_device *dev, struct drm_file *file,
+  const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+   struct drm_afbc_framebuffer *afbc_fb;
+   struct drm_size_check check = { 0 };
+   struct drm_gem_object *objs[4];
+   int ret, i, num_planes;
+
+   afbc_fb = kzalloc(sizeof(*afbc_fb), GFP_KERNEL);
+   if (!afbc_fb)
+   return ERR_PTR(-ENOMEM);
+
+   if (drm_is_afbc(mode_cmd->modifier[0])) {
+   const struct drm_format_info *info = drm_get_format_info(dev, 
mode_cmd);
+
+   afbc_fb->bpp = info->cpp[0] * 8;
+   check.data = afbc_fb;
+   }
+
+   ret = drm_gem_fb_lookup(dev, file, mode_cmd, objs);
+   if (ret < 0)
+   goto err_free;
+   num_planes = ret;
+
+   ret = drm_gem_fb_size_check2(dev, mode_cmd, , objs);
+   if (ret)
+   goto err_cleanup;
+
+   if (drm_is_afbc(mode_cmd->modifier[0]))
+   if (rockchip_afbc_post_check(afbc_fb)) {
+   ret = -EINVAL;
+   goto err_cleanup;
+   }
+
+   ret = drm_gem_fb_init_with_funcs(_fb->base, dev, mode_cmd, objs, 
num_planes, _drm_fb_funcs);
+   if (ret)
+   goto err_cleanup;
+
+   retur

[PATCHv5 18/34] drm/komeda: Move object assignments to framebuffer to after size checks

2019-12-17 Thread Andrzej Pietrasiewicz
The assignments are the same in both branches of the "if" statement and
nothing depends on them between their original position and the new
position, so this can be safely done.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index acffceeb26f1..d52278ca27fb 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -166,8 +166,6 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
 
ret = komeda_fb_afbc_size_check(kfb, info, objs, file,
mode_cmd);
-   for (i = 0; i < info->num_planes; ++i)
-   kfb->base.obj[i] = objs[i];
} else {
ret = komeda_fb_check_src_coords(kfb, 0, 0, kfb->base.width,
 kfb->base.height);
@@ -176,8 +174,6 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
 
ret = komeda_fb_none_afbc_size_check(mdev, info, objs,
 file, mode_cmd);
-   for (i = 0; i < info->num_planes; ++i)
-   kfb->base.obj[i] = objs[i];
}
if (ret < 0)
goto err_cleanup;
@@ -189,6 +185,9 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
goto err_cleanup;
}
 
+   for (i = 0; i < info->num_planes; ++i)
+   kfb->base.obj[i] = objs[i];
+
ret = drm_framebuffer_init(dev, >base, _fb_funcs);
if (ret < 0) {
DRM_DEBUG_KMS("failed to initialize fb\n");
-- 
2.17.1

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


[PATCHv5 12/34] drm/komeda: Factor out object lookups for non-afbc case

2019-12-17 Thread Andrzej Pietrasiewicz
Ultimately we want lookups happening only once in komeda's fb_create
implementation.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../arm/display/komeda/komeda_framebuffer.c   | 21 ---
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 08f31478c6a8..2014cd843aeb 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -100,6 +100,7 @@ static int
 komeda_fb_none_afbc_size_check(struct komeda_dev *mdev,
   struct komeda_fb *kfb,
   const struct drm_format_info *info,
+  struct drm_gem_object **objs,
   struct drm_file *file,
   const struct drm_mode_fb_cmd2 *mode_cmd)
 {
@@ -109,12 +110,7 @@ komeda_fb_none_afbc_size_check(struct komeda_dev *mdev,
u64 min_size;
 
for (i = 0; i < info->num_planes; i++) {
-   obj = drm_gem_object_lookup(file, mode_cmd->handles[i]);
-   if (!obj) {
-   DRM_DEBUG_KMS("Failed to lookup GEM object\n");
-   return -ENOENT;
-   }
-   fb->obj[i] = obj;
+   obj = objs[i];
 
block_h = drm_format_info_block_height(info, i);
if ((fb->pitches[i] * block_h) % mdev->chip.bus_width) {
@@ -174,14 +170,23 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
}
ret = komeda_fb_afbc_size_check(kfb, info, file, mode_cmd);
} else {
+   struct drm_gem_object *objs[4];
+
if (komeda_fb_check_src_coords(kfb, 0, 0, kfb->base.width,
   kfb->base.height)) {
kfree(kfb);
return ERR_PTR(-EINVAL);
}
+   ret = drm_gem_fb_lookup(dev, file, mode_cmd, objs);
+   if (ret < 0) {
+   kfree(kfb);
+   return ERR_PTR(ret);
+   }
 
-   ret = komeda_fb_none_afbc_size_check(mdev, kfb, info, file,
-mode_cmd);
+   ret = komeda_fb_none_afbc_size_check(mdev, kfb, info, objs,
+file, mode_cmd);
+   for (i = 0; i < info->num_planes; ++i)
+   kfb->base.obj[i] = objs[i];
}
if (ret < 0)
goto err_cleanup;
-- 
2.17.1

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


[PATCHv5 24/34] drm/komeda: Factor in the invocation of special helper

2019-12-17 Thread Andrzej Pietrasiewicz
Don't use a separate function to call the helper. The ultimate goal is
to unify non-afbc and afbc cases as much as possible and then moving the
helper invocation outside the if-else clause.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../arm/display/komeda/komeda_framebuffer.c   | 57 +++
 1 file changed, 20 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index d75176e24f24..766b6944c53c 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -87,41 +87,6 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb,
return 0;
 }
 
-static int
-komeda_fb_none_afbc_size_check(struct drm_device *dev,
-  const struct drm_format_info *info,
-  struct drm_gem_object **objs,
-  struct drm_file *file,
-  const struct drm_mode_fb_cmd2 *mode_cmd)
-{
-   struct komeda_dev *mdev = dev->dev_private;
-   struct drm_size_check check = { 0 };
-   struct drm_gem_object *obj;
-   u32 i;
-
-   for (i = 0; i < info->num_planes; i++) {
-   obj = objs[i];
-
-   check.pitch_multiplier[i] =
-   drm_format_info_block_height(info, i);
-
-   check.min_size[i] =
-   komeda_fb_get_pixel_addr_nofb(info,
- mode_cmd->modifier[0],
- mode_cmd->pitches,
- mode_cmd->offsets,
- obj,
- 0, mode_cmd->height, i)
-   - to_drm_gem_cma_obj(obj)->paddr;
-   }
-
-   check.pitch_modulo = mdev->chip.bus_width;
-   check.use_pitch_multiplier = true;
-   check.use_min_size = true;
-
-   return drm_gem_fb_size_check2(dev, mode_cmd, , objs);
-}
-
 struct drm_framebuffer *
 komeda_fb_create(struct drm_device *dev, struct drm_file *file,
 const struct drm_mode_fb_cmd2 *mode_cmd)
@@ -163,13 +128,31 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
ret = komeda_fb_afbc_size_check(kfb, info, objs, file,
mode_cmd);
} else {
+   struct drm_size_check check = { 0 };
+
ret = komeda_fb_check_src_coords(kfb, 0, 0, mode_cmd->width,
 mode_cmd->height);
if (ret)
goto err_cleanup;
 
-   ret = komeda_fb_none_afbc_size_check(dev, info, objs,
-file, mode_cmd);
+   for (i = 0; i < num_planes; i++) {
+   check.pitch_multiplier[i] =
+   drm_format_info_block_height(info, i);
+
+   check.min_size[i] =
+   komeda_fb_get_pixel_addr_nofb(info,
+   mode_cmd->modifier[0],
+   mode_cmd->pitches,
+   mode_cmd->offsets, objs[i],
+   0, mode_cmd->height, i)
+   - to_drm_gem_cma_obj(objs[i])->paddr;
+   }
+
+   check.pitch_modulo = mdev->chip.bus_width;
+   check.use_pitch_multiplier = true;
+   check.use_min_size = true;
+
+   ret = drm_gem_fb_size_check2(dev, mode_cmd, , objs);
}
if (ret < 0)
goto err_cleanup;
-- 
2.17.1

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


[PATCHv5 21/34] drm/komeda: Use helper for common tasks

2019-12-17 Thread Andrzej Pietrasiewicz
The replaced fragment is 1:1 with the helper code.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.c | 13 +++--
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index c2b29d4e6fbb..26d1a3cfb587 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -184,17 +184,10 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
goto err_cleanup;
}
 
-   drm_helper_mode_fill_fb_struct(dev, >base, mode_cmd);
-
-   for (i = 0; i < info->num_planes; ++i)
-   kfb->base.obj[i] = objs[i];
-
-   ret = drm_framebuffer_init(dev, >base, _fb_funcs);
-   if (ret < 0) {
-   DRM_DEBUG_KMS("failed to initialize fb\n");
-
+   ret = drm_gem_fb_init_with_funcs(>base, dev, mode_cmd, objs,
+info->num_planes, _fb_funcs);
+   if (ret < 0)
goto err_cleanup;
-   }
 
kfb->is_va = mdev->iommu ? true : false;
 
-- 
2.17.1

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


[PATCHv5 28/34] drm/komeda: Move to helper checking afbc buffer size

2019-12-17 Thread Andrzej Pietrasiewicz
Use generic helper code. Adapt struct komeda_fb users to new location
of respective data members.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../arm/display/komeda/d71/d71_component.c|  6 +--
 .../arm/display/komeda/komeda_framebuffer.c   | 44 +--
 .../arm/display/komeda/komeda_framebuffer.h   | 14 ++
 .../display/komeda/komeda_pipeline_state.c| 14 +++---
 4 files changed, 26 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index 8a02ade369db..5131e51e56d4 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -186,7 +186,7 @@ static void d71_layer_update_fb(struct komeda_component *c,
struct komeda_fb *kfb,
dma_addr_t *addr)
 {
-   struct drm_framebuffer *fb = >base;
+   struct drm_framebuffer *fb = >base.base;
const struct drm_format_info *info = fb->format;
u32 __iomem *reg = c->reg;
int block_h;
@@ -234,9 +234,9 @@ static void d71_layer_update(struct komeda_component *c,
 st->afbc_crop_b));
/* afbc 1.2 wants payload, afbc 1.0/1.1 wants end_addr */
if (fb->modifier & AFBC_FORMAT_MOD_TILED)
-   addr = st->addr[0] + kfb->offset_payload;
+   addr = st->addr[0] + kfb->base.offset_payload;
else
-   addr = st->addr[0] + kfb->afbc_size - 1;
+   addr = st->addr[0] + kfb->base.afbc_size - 1;
 
malidp_write32(reg, BLK_P1_PTR_LOW, lower_32_bits(addr));
malidp_write32(reg, BLK_P1_PTR_HIGH, upper_32_bits(addr));
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index bf4309b62d37..45318ed052a9 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -70,46 +70,26 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
info = drm_get_format_info(dev, mode_cmd);
 
if (mode_cmd->modifier[0]) {
-   u32 alignment_w = 0, alignment_h = 0;
-   u32 alignment_header, n_blocks, bpp;
-
if (num_planes != 1) {
DRM_DEBUG_KMS("AFBC requires exactly 1 plane.\n");
ret = -EINVAL;
goto err_cleanup;
}
 
-   if (!drm_afbc_get_superblock_wh(mode_cmd->modifier[0], 
_w, _h)) {
-   ret = -EINVAL;
-   goto err_cleanup;
-   }
-
/* tiled header afbc */
-   if (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_TILED) {
-   alignment_w *= AFBC_TH_LAYOUT_ALIGNMENT;
-   alignment_h *= AFBC_TH_LAYOUT_ALIGNMENT;
-   alignment_header = AFBC_TH_BODY_START_ALIGNMENT;
-   } else {
-   alignment_header = AFBC_BODY_START_ALIGNMENT;
-   }
-
-   kfb->aligned_w = ALIGN(mode_cmd->width, alignment_w);
-   kfb->aligned_h = ALIGN(mode_cmd->height, alignment_h);
+   if (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_TILED)
+   kfb->base.alignment_header = 
AFBC_TH_BODY_START_ALIGNMENT;
+   else
+   kfb->base.alignment_header = AFBC_BODY_START_ALIGNMENT;
 
-   if (mode_cmd->offsets[0] % alignment_header) {
+   if (mode_cmd->offsets[0] % kfb->base.alignment_header) {
DRM_DEBUG_KMS("afbc offset alignment check failed.\n");
ret = -EINVAL;
goto err_cleanup;
}
 
-   n_blocks = (kfb->aligned_w * kfb->aligned_h) / 
AFBC_SUPERBLK_PIXELS;
-   kfb->offset_payload = ALIGN(n_blocks * AFBC_HEADER_SIZE, 
alignment_header);
-
-   bpp = komeda_get_afbc_format_bpp(info, mode_cmd->modifier[0]);
-   kfb->afbc_size = kfb->offset_payload
-  + n_blocks * ALIGN(bpp * AFBC_SUPERBLK_PIXELS / 
8, AFBC_SUPERBLK_ALIGNMENT);
-   check.min_size[0] = kfb->afbc_size + mode_cmd->offsets[0];
-   check.use_min_size = true;
+   kfb->base.bpp = komeda_get_afbc_format_bpp(info, 
mode_cmd->modifier[0]);
+   check.data = >base;
} else {
ret = komeda_fb_check_src_coords(kfb, 0, 0, mode_cmd->width,
 mode_cmd->height);
@@ -144,14 +124,14 @@ komeda_fb_create(struct dr

[PATCHv5 30/34] drm/arm/malidp: Integrate verify functions

2019-12-17 Thread Andrzej Pietrasiewicz
The next step towards using generic afbc-aware helpers.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/arm/malidp_drv.c | 36 
 1 file changed, 9 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 961e5a3f5b08..e1502666bce0 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -270,9 +270,16 @@ static const struct drm_mode_config_helper_funcs 
malidp_mode_config_helpers = {
 };
 
 static bool
-malidp_verify_afbc_framebuffer_caps(struct drm_device *dev,
-   const struct drm_mode_fb_cmd2 *mode_cmd)
+malidp_verify_afbc_framebuffer(struct drm_device *dev, struct drm_file *file,
+  const struct drm_mode_fb_cmd2 *mode_cmd)
 {
+   int n_superblocks = 0;
+   const struct drm_format_info *info;
+   struct drm_gem_object *objs = NULL;
+   u32 afbc_superblock_size = 0, afbc_superblock_height = 0;
+   u32 afbc_superblock_width = 0, afbc_size = 0;
+   int bpp = 0;
+
if (malidp_format_mod_supported(dev, mode_cmd->pixel_format,
mode_cmd->modifier[0]) == false)
return false;
@@ -294,21 +301,6 @@ malidp_verify_afbc_framebuffer_caps(struct drm_device *dev,
return false;
}
 
-   return true;
-}
-
-static bool
-malidp_verify_afbc_framebuffer_size(struct drm_device *dev,
-   struct drm_file *file,
-   const struct drm_mode_fb_cmd2 *mode_cmd)
-{
-   int n_superblocks = 0;
-   const struct drm_format_info *info;
-   struct drm_gem_object *objs = NULL;
-   u32 afbc_superblock_size = 0, afbc_superblock_height = 0;
-   u32 afbc_superblock_width = 0, afbc_size = 0;
-   int bpp = 0;
-
switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) {
case AFBC_SIZE_16X16:
afbc_superblock_height = 16;
@@ -358,16 +350,6 @@ malidp_verify_afbc_framebuffer_size(struct drm_device *dev,
return true;
 }
 
-static bool
-malidp_verify_afbc_framebuffer(struct drm_device *dev, struct drm_file *file,
-  const struct drm_mode_fb_cmd2 *mode_cmd)
-{
-   if (!malidp_verify_afbc_framebuffer_caps(dev, mode_cmd))
-   return false;
-
-   return malidp_verify_afbc_framebuffer_size(dev, file, mode_cmd);
-}
-
 static struct drm_framebuffer *
 malidp_fb_create(struct drm_device *dev, struct drm_file *file,
 const struct drm_mode_fb_cmd2 *mode_cmd)
-- 
2.17.1

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


[PATCHv5 29/34] drm/arm/malidp: Make verify funcitons invocations independent

2019-12-17 Thread Andrzej Pietrasiewicz
This will make it easier to transition to generic afbc-aware helpers.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/arm/malidp_drv.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 37d92a06318e..961e5a3f5b08 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -362,10 +362,10 @@ static bool
 malidp_verify_afbc_framebuffer(struct drm_device *dev, struct drm_file *file,
   const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-   if (malidp_verify_afbc_framebuffer_caps(dev, mode_cmd))
-   return malidp_verify_afbc_framebuffer_size(dev, file, mode_cmd);
+   if (!malidp_verify_afbc_framebuffer_caps(dev, mode_cmd))
+   return false;
 
-   return false;
+   return malidp_verify_afbc_framebuffer_size(dev, file, mode_cmd);
 }
 
 static struct drm_framebuffer *
-- 
2.17.1

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


[PATCHv5 26/34] drm/komeda: Factor in the invocation of special helper, afbc case

2019-12-17 Thread Andrzej Pietrasiewicz
Prepare for unification with non-afbc case.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../arm/display/komeda/komeda_framebuffer.c   | 84 ---
 1 file changed, 37 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 2c9691b86cff..7e02a04cdd11 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -36,51 +36,6 @@ static const struct drm_framebuffer_funcs komeda_fb_funcs = {
.create_handle  = komeda_fb_create_handle,
 };
 
-static int
-komeda_fb_afbc_size_check(struct drm_device *dev,
- struct komeda_fb *kfb,
- const struct drm_format_info *info,
- struct drm_gem_object **objs,
- struct drm_file *file,
- const struct drm_mode_fb_cmd2 *mode_cmd)
-{
-   struct drm_size_check check = { 0 };
-   u32 alignment_w = 0, alignment_h = 0, alignment_header, n_blocks, bpp;
-
-   if (!drm_afbc_get_superblock_wh(mode_cmd->modifier[0], _w, 
_h))
-   return -EINVAL;
-
-   /* tiled header afbc */
-   if (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_TILED) {
-   alignment_w *= AFBC_TH_LAYOUT_ALIGNMENT;
-   alignment_h *= AFBC_TH_LAYOUT_ALIGNMENT;
-   alignment_header = AFBC_TH_BODY_START_ALIGNMENT;
-   } else {
-   alignment_header = AFBC_BODY_START_ALIGNMENT;
-   }
-
-   kfb->aligned_w = ALIGN(mode_cmd->width, alignment_w);
-   kfb->aligned_h = ALIGN(mode_cmd->height, alignment_h);
-
-   if (mode_cmd->offsets[0] % alignment_header) {
-   DRM_DEBUG_KMS("afbc offset alignment check failed.\n");
-   return -EINVAL;
-   }
-
-   n_blocks = (kfb->aligned_w * kfb->aligned_h) / AFBC_SUPERBLK_PIXELS;
-   kfb->offset_payload = ALIGN(n_blocks * AFBC_HEADER_SIZE,
-   alignment_header);
-
-   bpp = komeda_get_afbc_format_bpp(info, mode_cmd->modifier[0]);
-   kfb->afbc_size = kfb->offset_payload + n_blocks *
-ALIGN(bpp * AFBC_SUPERBLK_PIXELS / 8,
-  AFBC_SUPERBLK_ALIGNMENT);
-   check.min_size[0] = kfb->afbc_size + mode_cmd->offsets[0];
-   check.use_min_size = true;
-
-   return drm_gem_fb_size_check2(dev, mode_cmd, , objs);
-}
-
 struct drm_framebuffer *
 komeda_fb_create(struct drm_device *dev, struct drm_file *file,
 const struct drm_mode_fb_cmd2 *mode_cmd)
@@ -113,14 +68,49 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
info = drm_get_format_info(dev, mode_cmd);
 
if (mode_cmd->modifier[0]) {
+   struct drm_size_check check = { 0 };
+   u32 alignment_w = 0, alignment_h = 0;
+   u32 alignment_header, n_blocks, bpp;
+
if (num_planes != 1) {
DRM_DEBUG_KMS("AFBC requires exactly 1 plane.\n");
ret = -EINVAL;
goto err_cleanup;
}
 
-   ret = komeda_fb_afbc_size_check(dev, kfb, info, objs,
-   file, mode_cmd);
+   if (!drm_afbc_get_superblock_wh(mode_cmd->modifier[0], 
_w, _h)) {
+   ret = -EINVAL;
+   goto err_cleanup;
+   }
+
+   /* tiled header afbc */
+   if (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_TILED) {
+   alignment_w *= AFBC_TH_LAYOUT_ALIGNMENT;
+   alignment_h *= AFBC_TH_LAYOUT_ALIGNMENT;
+   alignment_header = AFBC_TH_BODY_START_ALIGNMENT;
+   } else {
+   alignment_header = AFBC_BODY_START_ALIGNMENT;
+   }
+
+   kfb->aligned_w = ALIGN(mode_cmd->width, alignment_w);
+   kfb->aligned_h = ALIGN(mode_cmd->height, alignment_h);
+
+   if (mode_cmd->offsets[0] % alignment_header) {
+   DRM_DEBUG_KMS("afbc offset alignment check failed.\n");
+   ret = -EINVAL;
+   goto err_cleanup;
+   }
+
+   n_blocks = (kfb->aligned_w * kfb->aligned_h) / 
AFBC_SUPERBLK_PIXELS;
+   kfb->offset_payload = ALIGN(n_blocks * AFBC_HEADER_SIZE, 
alignment_header);
+
+   bpp = komeda_get_afbc_format_bpp(info, mode_cmd->modifier[0]);
+   kfb->afbc_size = kfb->offset_payload
+  + n_blocks * ALIGN(bpp * AFBC_SUPERBLK_PIXELS / 
8, AFBC_SUPERBLK_ALIGNMENT);
+   check.min_size[0] = kfb->afbc_size + mode_cmd->offsets[0];
+   check.

[PATCHv5 03/34] drm/gem-fb-helper: Add special version of drm_gem_fb_size_check

2019-12-17 Thread Andrzej Pietrasiewicz
The new version accepts a struct describing deviations from standard way of
doing the size checks. The caller must provide the respective values.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/drm_gem_framebuffer_helper.c | 46 
 include/drm/drm_gem_framebuffer_helper.h | 16 +++
 2 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index b3494f6b66bb..d2fce1ec8f37 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -300,8 +300,8 @@ int drm_gem_fb_lookup(struct drm_device *dev,
 EXPORT_SYMBOL_GPL(drm_gem_fb_lookup);
 
 /**
- * drm_gem_fb_size_check() - Helper function for use in
- *  _mode_config_funcs.fb_create implementations
+ * drm_gem_fb_size_check2() - Helper function for use in
+ *   _mode_config_funcs.fb_create implementations
  * @dev: DRM device
  * @mode_cmd: Metadata from the userspace framebuffer creation request
  *
@@ -311,9 +311,10 @@ EXPORT_SYMBOL_GPL(drm_gem_fb_lookup);
  * Returns:
  * Zero on success or a negative error code on failure.
  */
-int drm_gem_fb_size_check(struct drm_device *dev,
- const struct drm_mode_fb_cmd2 *mode_cmd,
- struct drm_gem_object **objs)
+int drm_gem_fb_size_check2(struct drm_device *dev,
+  const struct drm_mode_fb_cmd2 *mode_cmd,
+  const struct drm_size_check *check,
+  struct drm_gem_object **objs)
 {
const struct drm_format_info *info;
int i;
@@ -326,10 +327,19 @@ int drm_gem_fb_size_check(struct drm_device *dev,
unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
unsigned int min_size;
+   u32 pitch = mode_cmd->pitches[i];
+
+   if (check && check->use_pitch_multiplier)
+   if ((pitch * check->pitch_multiplier[i]) %
+   check->pitch_modulo)
+   return -EINVAL;
 
-   min_size = (height - 1) * mode_cmd->pitches[i]
-+ drm_format_info_min_pitch(info, i, width)
-+ mode_cmd->offsets[i];
+   if (check && check->use_min_size)
+   min_size = check->min_size[i];
+   else
+   min_size = (height - 1) * pitch
++ drm_format_info_min_pitch(info, i, width)
++ mode_cmd->offsets[i];
 
if (objs[i]->size < min_size)
return -EINVAL;
@@ -338,6 +348,26 @@ int drm_gem_fb_size_check(struct drm_device *dev,
return 0;
 
 }
+EXPORT_SYMBOL_GPL(drm_gem_fb_size_check2);
+
+/**
+ * drm_gem_fb_size_check() - Helper function for use in
+ *  _mode_config_funcs.fb_create implementations
+ * @dev: DRM device
+ * @mode_cmd: Metadata from the userspace framebuffer creation request
+ *
+ * This function can be used to verify buffer sizes for all planes.
+ * It is caller's responsibility to put the objects on failure.
+ *
+ * Returns:
+ * Zero on success or a negative error code on failure.
+ */
+int drm_gem_fb_size_check(struct drm_device *dev,
+ const struct drm_mode_fb_cmd2 *mode_cmd,
+ struct drm_gem_object **objs)
+{
+   return drm_gem_fb_size_check2(dev, mode_cmd, NULL, objs);
+}
 EXPORT_SYMBOL_GPL(drm_gem_fb_size_check);
 
 static const struct drm_framebuffer_funcs drm_gem_fb_funcs_dirtyfb = {
diff --git a/include/drm/drm_gem_framebuffer_helper.h 
b/include/drm/drm_gem_framebuffer_helper.h
index c85d4b152e91..4955af96d6c3 100644
--- a/include/drm/drm_gem_framebuffer_helper.h
+++ b/include/drm/drm_gem_framebuffer_helper.h
@@ -11,6 +11,18 @@ struct drm_mode_fb_cmd2;
 struct drm_plane;
 struct drm_plane_state;
 struct drm_simple_display_pipe;
+struct drm_size_check;
+
+/**
+ * struct drm_size_check - Description of special requirements for size checks.
+ */
+struct drm_size_check {
+   unsigned int min_size[4];
+   bool use_min_size;
+   u32 pitch_multiplier[4];
+   u32 pitch_modulo;
+   bool use_pitch_multiplier;
+};
 
 struct drm_gem_object *drm_gem_fb_get_obj(struct drm_framebuffer *fb,
  unsigned int plane);
@@ -32,6 +44,10 @@ int drm_gem_fb_lookup(struct drm_device *dev,
  struct drm_file *file,
  const struct drm_mode_fb_cmd2 *mode_cmd,
  struct drm_gem_object **objs);
+int drm_gem_fb_size_check2(struct drm_device *dev,
+  const struct drm_mode_fb_cmd2 *mode_cmd,

[PATCHv5 23/34] drm/komeda: Use special helper for non-afbc size checks

2019-12-17 Thread Andrzej Pietrasiewicz
Use the generic helper code.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../arm/display/komeda/komeda_framebuffer.c   | 46 +--
 1 file changed, 21 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 9139fe5619be..d75176e24f24 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -88,42 +88,38 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb,
 }
 
 static int
-komeda_fb_none_afbc_size_check(struct komeda_dev *mdev,
+komeda_fb_none_afbc_size_check(struct drm_device *dev,
   const struct drm_format_info *info,
   struct drm_gem_object **objs,
   struct drm_file *file,
   const struct drm_mode_fb_cmd2 *mode_cmd)
 {
+   struct komeda_dev *mdev = dev->dev_private;
+   struct drm_size_check check = { 0 };
struct drm_gem_object *obj;
-   u32 i, block_h;
-   u64 min_size;
+   u32 i;
 
for (i = 0; i < info->num_planes; i++) {
obj = objs[i];
 
-   block_h = drm_format_info_block_height(info, i);
-   if ((mode_cmd->pitches[i] * block_h) % mdev->chip.bus_width) {
-   DRM_DEBUG_KMS("Pitch[%d]: 0x%x doesn't align to 0x%x\n",
- i, mode_cmd->pitches[i],
- mdev->chip.bus_width);
-   return -EINVAL;
-   }
-
-   min_size = komeda_fb_get_pixel_addr_nofb(info,
-mode_cmd->modifier[0],
-mode_cmd->pitches,
-mode_cmd->offsets,
-obj,
-0, mode_cmd->height, i)
-- to_drm_gem_cma_obj(obj)->paddr;
-   if (obj->size < min_size) {
-   DRM_DEBUG_KMS("The fb->obj[%d] size: 0x%zx lower than 
the minimum requirement: 0x%llx.\n",
- i, obj->size, min_size);
-   return -EINVAL;
-   }
+   check.pitch_multiplier[i] =
+   drm_format_info_block_height(info, i);
+
+   check.min_size[i] =
+   komeda_fb_get_pixel_addr_nofb(info,
+ mode_cmd->modifier[0],
+ mode_cmd->pitches,
+ mode_cmd->offsets,
+ obj,
+ 0, mode_cmd->height, i)
+   - to_drm_gem_cma_obj(obj)->paddr;
}
 
-   return 0;
+   check.pitch_modulo = mdev->chip.bus_width;
+   check.use_pitch_multiplier = true;
+   check.use_min_size = true;
+
+   return drm_gem_fb_size_check2(dev, mode_cmd, , objs);
 }
 
 struct drm_framebuffer *
@@ -172,7 +168,7 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
if (ret)
goto err_cleanup;
 
-   ret = komeda_fb_none_afbc_size_check(mdev, info, objs,
+   ret = komeda_fb_none_afbc_size_check(dev, info, objs,
 file, mode_cmd);
}
if (ret < 0)
-- 
2.17.1

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


[PATCHv5 19/34] drm/komeda: Make the size checks independent from framebuffer structure

2019-12-17 Thread Andrzej Pietrasiewicz
The same data is available in mode_cmd.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.c| 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index d52278ca27fb..42ccd4647919 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -155,9 +155,9 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
goto err_free;
 
drm_helper_mode_fill_fb_struct(dev, >base, mode_cmd);
-   info = kfb->base.format;
+   info = drm_get_format_info(dev, mode_cmd);
 
-   if (kfb->base.modifier) {
+   if (mode_cmd->modifier[0]) {
if (info->num_planes != 1) {
DRM_DEBUG_KMS("AFBC requires exactly 1 plane.\n");
ret = -EINVAL;
@@ -167,8 +167,8 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
ret = komeda_fb_afbc_size_check(kfb, info, objs, file,
mode_cmd);
} else {
-   ret = komeda_fb_check_src_coords(kfb, 0, 0, kfb->base.width,
-kfb->base.height);
+   ret = komeda_fb_check_src_coords(kfb, 0, 0, mode_cmd->width,
+mode_cmd->height);
if (ret)
goto err_cleanup;
 
@@ -179,7 +179,7 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
goto err_cleanup;
 
if (info->num_planes == 3)
-   if (kfb->base.pitches[1] != kfb->base.pitches[2]) {
+   if (mode_cmd->pitches[1] != mode_cmd->pitches[2]) {
DRM_DEBUG_KMS("The pitch[1] and [2] are not same\n");
ret = -EINVAL;
goto err_cleanup;
-- 
2.17.1

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


[PATCHv5 15/34] drm/komeda: Free komeda_fb_afbc_size_check from framebuffer dependency

2019-12-17 Thread Andrzej Pietrasiewicz
It does still depend on komeda_fb, but only for komeda-specific parameters.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../drm/arm/display/komeda/komeda_framebuffer.c   | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 6b11a1b21ef6..aa703aabbeee 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -43,18 +43,17 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb,
  struct drm_file *file,
  const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-   struct drm_framebuffer *fb = >base;
struct drm_gem_object *obj;
u32 alignment_w = 0, alignment_h = 0, alignment_header, n_blocks, bpp;
u64 min_size;
 
obj = objs[0];
 
-   if (!drm_afbc_get_superblock_wh(fb->modifier, _w, 
_h))
+   if (!drm_afbc_get_superblock_wh(mode_cmd->modifier[0], _w, 
_h))
return -EINVAL;
 
/* tiled header afbc */
-   if (fb->modifier & AFBC_FORMAT_MOD_TILED) {
+   if (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_TILED) {
alignment_w *= AFBC_TH_LAYOUT_ALIGNMENT;
alignment_h *= AFBC_TH_LAYOUT_ALIGNMENT;
alignment_header = AFBC_TH_BODY_START_ALIGNMENT;
@@ -62,10 +61,10 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb,
alignment_header = AFBC_BODY_START_ALIGNMENT;
}
 
-   kfb->aligned_w = ALIGN(fb->width, alignment_w);
-   kfb->aligned_h = ALIGN(fb->height, alignment_h);
+   kfb->aligned_w = ALIGN(mode_cmd->width, alignment_w);
+   kfb->aligned_h = ALIGN(mode_cmd->height, alignment_h);
 
-   if (fb->offsets[0] % alignment_header) {
+   if (mode_cmd->offsets[0] % alignment_header) {
DRM_DEBUG_KMS("afbc offset alignment check failed.\n");
return -EINVAL;
}
@@ -74,11 +73,11 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb,
kfb->offset_payload = ALIGN(n_blocks * AFBC_HEADER_SIZE,
alignment_header);
 
-   bpp = komeda_get_afbc_format_bpp(info, fb->modifier);
+   bpp = komeda_get_afbc_format_bpp(info, mode_cmd->modifier[0]);
kfb->afbc_size = kfb->offset_payload + n_blocks *
 ALIGN(bpp * AFBC_SUPERBLK_PIXELS / 8,
   AFBC_SUPERBLK_ALIGNMENT);
-   min_size = kfb->afbc_size + fb->offsets[0];
+   min_size = kfb->afbc_size + mode_cmd->offsets[0];
if (min_size > obj->size) {
DRM_DEBUG_KMS("afbc size check failed, obj_size: 0x%zx. 
min_size 0x%llx.\n",
  obj->size, min_size);
-- 
2.17.1

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


[PATCHv5 11/34] drm/komeda: Provide and use komeda_fb_get_pixel_addr variant not requiring a fb

2019-12-17 Thread Andrzej Pietrasiewicz
Add a variant of the function which doesn't need neither
struct drm_framebuffer nor container_of it. Maintain current interface
for existing users.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../arm/display/komeda/komeda_framebuffer.c   | 68 +++
 .../arm/display/komeda/komeda_framebuffer.h   |  7 ++
 2 files changed, 61 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 5d035f6a76a6..08f31478c6a8 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -123,7 +123,12 @@ komeda_fb_none_afbc_size_check(struct komeda_dev *mdev,
return -EINVAL;
}
 
-   min_size = komeda_fb_get_pixel_addr(kfb, 0, fb->height, i)
+   min_size = komeda_fb_get_pixel_addr_nofb(info,
+mode_cmd->modifier[0],
+mode_cmd->pitches,
+mode_cmd->offsets,
+obj,
+0, mode_cmd->height, i)
 - to_drm_gem_cma_obj(obj)->paddr;
if (obj->size < min_size) {
DRM_DEBUG_KMS("The fb->obj[%d] size: 0x%zx lower than 
the minimum requirement: 0x%llx.\n",
@@ -237,12 +242,56 @@ int komeda_fb_check_src_coords(const struct komeda_fb 
*kfb,
return 0;
 }
 
+dma_addr_t
+komeda_fb_get_pixel_addr_impl(const struct drm_format_info *format,
+ u64 modifier,
+ const unsigned int *pitches,
+ const unsigned int *offsets,
+ const struct drm_gem_cma_object *obj,
+ int x, int y, int plane)
+{
+   u32 offset, plane_x, plane_y, block_w, block_sz;
+
+   offset = offsets[plane];
+   if (modifier) {
+   block_w = drm_format_info_block_width(format, plane);
+   block_sz = format->char_per_block[plane];
+   plane_x = x / (plane ? format->hsub : 1);
+   plane_y = y / (plane ? format->vsub : 1);
+
+   offset += (plane_x / block_w) * block_sz
+   + plane_y * pitches[plane];
+   }
+
+   return obj->paddr + offset;
+}
+
+dma_addr_t
+komeda_fb_get_pixel_addr_nofb(const struct drm_format_info *format,
+ u64 modifier,
+ const unsigned int *pitches,
+ const unsigned int *offsets,
+ struct drm_gem_object *obj,
+ int x, int y, int plane)
+{
+   const struct drm_gem_cma_object *cma_obj;
+
+   if (plane >= format->num_planes) {
+   DRM_DEBUG_KMS("Out of max plane num.\n");
+   return -EINVAL;
+   }
+
+   cma_obj = to_drm_gem_cma_obj(obj);
+
+   return komeda_fb_get_pixel_addr_impl(format, modifier, pitches, offsets,
+cma_obj, x, y, plane);
+}
+
 dma_addr_t
 komeda_fb_get_pixel_addr(struct komeda_fb *kfb, int x, int y, int plane)
 {
struct drm_framebuffer *fb = >base;
const struct drm_gem_cma_object *obj;
-   u32 offset, plane_x, plane_y, block_w, block_sz;
 
if (plane >= fb->format->num_planes) {
DRM_DEBUG_KMS("Out of max plane num.\n");
@@ -251,18 +300,9 @@ komeda_fb_get_pixel_addr(struct komeda_fb *kfb, int x, int 
y, int plane)
 
obj = drm_fb_cma_get_gem_obj(fb, plane);
 
-   offset = fb->offsets[plane];
-   if (!fb->modifier) {
-   block_w = drm_format_info_block_width(fb->format, plane);
-   block_sz = fb->format->char_per_block[plane];
-   plane_x = x / (plane ? fb->format->hsub : 1);
-   plane_y = y / (plane ? fb->format->vsub : 1);
-
-   offset += (plane_x / block_w) * block_sz
-   + plane_y * fb->pitches[plane];
-   }
-
-   return obj->paddr + offset;
+   return komeda_fb_get_pixel_addr_impl(fb->format, fb->modifier,
+fb->pitches, fb->offsets,
+obj, x, y, plane);
 }
 
 /* if the fb can be supported by a specific layer */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h
index c61ca98a3a63..2f1f421d3e7f 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h
@@ -42,6 +42,13 @@ int komeda_fb_c

[PATCHv5 22/34] drm/komeda: Use return value of drm_gem_fb_lookup

2019-12-17 Thread Andrzej Pietrasiewicz
Reduce dependency of the function on the "info" variable as much as
possible.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.c   | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 26d1a3cfb587..9139fe5619be 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -134,7 +134,7 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
struct drm_gem_object *objs[4];
struct komeda_fb *kfb;
const struct drm_format_info *info;
-   int ret = 0, i;
+   int ret = 0, i, num_planes;
 
kfb = kzalloc(sizeof(*kfb), GFP_KERNEL);
if (!kfb)
@@ -153,11 +153,12 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
ret = drm_gem_fb_lookup(dev, file, mode_cmd, objs);
if (ret < 0)
goto err_free;
+   num_planes = ret;
 
info = drm_get_format_info(dev, mode_cmd);
 
if (mode_cmd->modifier[0]) {
-   if (info->num_planes != 1) {
+   if (num_planes != 1) {
DRM_DEBUG_KMS("AFBC requires exactly 1 plane.\n");
ret = -EINVAL;
goto err_cleanup;
@@ -177,7 +178,7 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
if (ret < 0)
goto err_cleanup;
 
-   if (info->num_planes == 3)
+   if (num_planes == 3)
if (mode_cmd->pitches[1] != mode_cmd->pitches[2]) {
DRM_DEBUG_KMS("The pitch[1] and [2] are not same\n");
ret = -EINVAL;
@@ -185,7 +186,7 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
}
 
ret = drm_gem_fb_init_with_funcs(>base, dev, mode_cmd, objs,
-info->num_planes, _fb_funcs);
+num_planes, _fb_funcs);
if (ret < 0)
goto err_cleanup;
 
@@ -194,7 +195,7 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
return >base;
 
 err_cleanup:
-   for (i = 0; i < info->num_planes; i++)
+   for (i = 0; i < num_planes; i++)
drm_gem_object_put_unlocked(objs[i]);
 err_free:
kfree(kfb);
-- 
2.17.1

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


[PATCHv5 16/34] drm/komeda: Simplify error handling

2019-12-17 Thread Andrzej Pietrasiewicz
Use less code to handle errors.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../arm/display/komeda/komeda_framebuffer.c   | 32 ---
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index aa703aabbeee..f50f83c68c70 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -145,8 +145,8 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
if (!kfb->format_caps) {
DRM_DEBUG_KMS("FMT %x is not supported.\n",
  mode_cmd->pixel_format);
-   kfree(kfb);
-   return ERR_PTR(-EINVAL);
+   ret = -EINVAL;
+   goto err_free;
}
 
drm_helper_mode_fill_fb_struct(dev, >base, mode_cmd);
@@ -157,15 +157,13 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
 
if (info->num_planes != 1) {
DRM_DEBUG_KMS("AFBC requires exactly 1 plane.\n");
-   kfree(kfb);
-   return ERR_PTR(-EINVAL);
+   ret = -EINVAL;
+   goto err_free;
}
 
ret = drm_gem_fb_lookup(dev, file, mode_cmd, objs);
-   if (ret < 0) {
-   kfree(kfb);
-   return ERR_PTR(ret);
-   }
+   if (ret < 0)
+   goto err_free;
 
ret = komeda_fb_afbc_size_check(kfb, info, objs, file,
mode_cmd);
@@ -174,16 +172,14 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
} else {
struct drm_gem_object *objs[4];
 
-   if (komeda_fb_check_src_coords(kfb, 0, 0, kfb->base.width,
-  kfb->base.height)) {
-   kfree(kfb);
-   return ERR_PTR(-EINVAL);
-   }
+   ret = komeda_fb_check_src_coords(kfb, 0, 0, kfb->base.width,
+kfb->base.height);
+   if (ret)
+   goto err_free;
+
ret = drm_gem_fb_lookup(dev, file, mode_cmd, objs);
-   if (ret < 0) {
-   kfree(kfb);
-   return ERR_PTR(ret);
-   }
+   if (ret < 0)
+   goto err_free;
 
ret = komeda_fb_none_afbc_size_check(mdev, info, objs,
 file, mode_cmd);
@@ -214,7 +210,7 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
 err_cleanup:
for (i = 0; i < kfb->base.format->num_planes; i++)
drm_gem_object_put_unlocked(kfb->base.obj[i]);
-
+err_free:
kfree(kfb);
return ERR_PTR(ret);
 }
-- 
2.17.1

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


[PATCHv5 14/34] drm/komeda: Factor out object lookups for afbc case

2019-12-17 Thread Andrzej Pietrasiewicz
Ultimately we want lookups happening only once in komeda's fb_create
implementation.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../arm/display/komeda/komeda_framebuffer.c   | 30 +++
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 43db95a76291..6b11a1b21ef6 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -39,6 +39,7 @@ static const struct drm_framebuffer_funcs komeda_fb_funcs = {
 static int
 komeda_fb_afbc_size_check(struct komeda_fb *kfb,
  const struct drm_format_info *info,
+ struct drm_gem_object **objs,
  struct drm_file *file,
  const struct drm_mode_fb_cmd2 *mode_cmd)
 {
@@ -47,11 +48,7 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb,
u32 alignment_w = 0, alignment_h = 0, alignment_header, n_blocks, bpp;
u64 min_size;
 
-   obj = drm_gem_object_lookup(file, mode_cmd->handles[0]);
-   if (!obj) {
-   DRM_DEBUG_KMS("Failed to lookup GEM object\n");
-   return -ENOENT;
-   }
+   obj = objs[0];
 
if (!drm_afbc_get_superblock_wh(fb->modifier, _w, 
_h))
return -EINVAL;
@@ -70,7 +67,7 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb,
 
if (fb->offsets[0] % alignment_header) {
DRM_DEBUG_KMS("afbc offset alignment check failed.\n");
-   goto check_failed;
+   return -EINVAL;
}
 
n_blocks = (kfb->aligned_w * kfb->aligned_h) / AFBC_SUPERBLK_PIXELS;
@@ -85,15 +82,10 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb,
if (min_size > obj->size) {
DRM_DEBUG_KMS("afbc size check failed, obj_size: 0x%zx. 
min_size 0x%llx.\n",
  obj->size, min_size);
-   goto check_failed;
+   return -EINVAL;
}
 
-   fb->obj[0] = obj;
return 0;
-
-check_failed:
-   drm_gem_object_put_unlocked(obj);
-   return -EINVAL;
 }
 
 static int
@@ -162,12 +154,24 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
info = kfb->base.format;
 
if (kfb->base.modifier) {
+   struct drm_gem_object *objs[4];
+
if (info->num_planes != 1) {
DRM_DEBUG_KMS("AFBC requires exactly 1 plane.\n");
kfree(kfb);
return ERR_PTR(-EINVAL);
}
-   ret = komeda_fb_afbc_size_check(kfb, info, file, mode_cmd);
+
+   ret = drm_gem_fb_lookup(dev, file, mode_cmd, objs);
+   if (ret < 0) {
+   kfree(kfb);
+   return ERR_PTR(ret);
+   }
+
+   ret = komeda_fb_afbc_size_check(kfb, info, objs, file,
+   mode_cmd);
+   for (i = 0; i < info->num_planes; ++i)
+   kfb->base.obj[i] = objs[i];
} else {
struct drm_gem_object *objs[4];
 
-- 
2.17.1

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


[PATCHv5 08/34] drm/komeda: Retrieve drm_format_info once

2019-12-17 Thread Andrzej Pietrasiewicz
Next step towards unifying afbc and non-afbc cases as much as possible.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../drm/arm/display/komeda/komeda_framebuffer.c | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 33181bdab16b..7004c3c8f8de 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -37,11 +37,12 @@ static const struct drm_framebuffer_funcs komeda_fb_funcs = 
{
 };
 
 static int
-komeda_fb_afbc_size_check(struct komeda_fb *kfb, struct drm_file *file,
+komeda_fb_afbc_size_check(struct komeda_fb *kfb,
+ const struct drm_format_info *info,
+ struct drm_file *file,
  const struct drm_mode_fb_cmd2 *mode_cmd)
 {
struct drm_framebuffer *fb = >base;
-   const struct drm_format_info *info = fb->format;
struct drm_gem_object *obj;
u32 alignment_w = 0, alignment_h = 0, alignment_header, n_blocks, bpp;
u64 min_size;
@@ -96,12 +97,13 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb, struct 
drm_file *file,
 }
 
 static int
-komeda_fb_none_afbc_size_check(struct komeda_dev *mdev, struct komeda_fb *kfb,
+komeda_fb_none_afbc_size_check(struct komeda_dev *mdev,
+  struct komeda_fb *kfb,
+  const struct drm_format_info *info,
   struct drm_file *file,
   const struct drm_mode_fb_cmd2 *mode_cmd)
 {
struct drm_framebuffer *fb = >base;
-   const struct drm_format_info *info = fb->format;
struct drm_gem_object *obj;
u32 i, block_h;
u64 min_size;
@@ -146,6 +148,7 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
 {
struct komeda_dev *mdev = dev->dev_private;
struct komeda_fb *kfb;
+   const struct drm_format_info *info;
int ret = 0, i;
 
kfb = kzalloc(sizeof(*kfb), GFP_KERNEL);
@@ -163,9 +166,10 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
}
 
drm_helper_mode_fill_fb_struct(dev, >base, mode_cmd);
+   info = kfb->base.format;
 
if (kfb->base.modifier) {
-   ret = komeda_fb_afbc_size_check(kfb, file, mode_cmd);
+   ret = komeda_fb_afbc_size_check(kfb, info, file, mode_cmd);
} else {
if (komeda_fb_check_src_coords(kfb, 0, 0, kfb->base.width,
   kfb->base.height)) {
@@ -173,7 +177,8 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
return ERR_PTR(-EINVAL);
}
 
-   ret = komeda_fb_none_afbc_size_check(mdev, kfb, file, mode_cmd);
+   ret = komeda_fb_none_afbc_size_check(mdev, kfb, info, file,
+mode_cmd);
}
if (ret < 0)
goto err_cleanup;
-- 
2.17.1

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


[PATCHv5 25/34] drm/komeda: Use special helper for afbc case size check

2019-12-17 Thread Andrzej Pietrasiewicz
Use generic helper code.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../arm/display/komeda/komeda_framebuffer.c   | 22 +++
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 766b6944c53c..2c9691b86cff 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -37,17 +37,15 @@ static const struct drm_framebuffer_funcs komeda_fb_funcs = 
{
 };
 
 static int
-komeda_fb_afbc_size_check(struct komeda_fb *kfb,
+komeda_fb_afbc_size_check(struct drm_device *dev,
+ struct komeda_fb *kfb,
  const struct drm_format_info *info,
  struct drm_gem_object **objs,
  struct drm_file *file,
  const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-   struct drm_gem_object *obj;
+   struct drm_size_check check = { 0 };
u32 alignment_w = 0, alignment_h = 0, alignment_header, n_blocks, bpp;
-   u64 min_size;
-
-   obj = objs[0];
 
if (!drm_afbc_get_superblock_wh(mode_cmd->modifier[0], _w, 
_h))
return -EINVAL;
@@ -77,14 +75,10 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb,
kfb->afbc_size = kfb->offset_payload + n_blocks *
 ALIGN(bpp * AFBC_SUPERBLK_PIXELS / 8,
   AFBC_SUPERBLK_ALIGNMENT);
-   min_size = kfb->afbc_size + mode_cmd->offsets[0];
-   if (min_size > obj->size) {
-   DRM_DEBUG_KMS("afbc size check failed, obj_size: 0x%zx. 
min_size 0x%llx.\n",
- obj->size, min_size);
-   return -EINVAL;
-   }
+   check.min_size[0] = kfb->afbc_size + mode_cmd->offsets[0];
+   check.use_min_size = true;
 
-   return 0;
+   return drm_gem_fb_size_check2(dev, mode_cmd, , objs);
 }
 
 struct drm_framebuffer *
@@ -125,8 +119,8 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
goto err_cleanup;
}
 
-   ret = komeda_fb_afbc_size_check(kfb, info, objs, file,
-   mode_cmd);
+   ret = komeda_fb_afbc_size_check(dev, kfb, info, objs,
+   file, mode_cmd);
} else {
struct drm_size_check check = { 0 };
 
-- 
2.17.1

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


[PATCHv5 17/34] drm/komeda: Move object lookup before size checks

2019-12-17 Thread Andrzej Pietrasiewicz
The lookup is performed the same way in both branches of the "if"
statement, so move the lookup to before the "if". err_cleanup case
is adjusted accordingly.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../arm/display/komeda/komeda_framebuffer.c   | 23 +++
 1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index f50f83c68c70..acffceeb26f1 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -131,6 +131,7 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
 const struct drm_mode_fb_cmd2 *mode_cmd)
 {
struct komeda_dev *mdev = dev->dev_private;
+   struct drm_gem_object *objs[4];
struct komeda_fb *kfb;
const struct drm_format_info *info;
int ret = 0, i;
@@ -149,37 +150,29 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
goto err_free;
}
 
+   ret = drm_gem_fb_lookup(dev, file, mode_cmd, objs);
+   if (ret < 0)
+   goto err_free;
+
drm_helper_mode_fill_fb_struct(dev, >base, mode_cmd);
info = kfb->base.format;
 
if (kfb->base.modifier) {
-   struct drm_gem_object *objs[4];
-
if (info->num_planes != 1) {
DRM_DEBUG_KMS("AFBC requires exactly 1 plane.\n");
ret = -EINVAL;
-   goto err_free;
+   goto err_cleanup;
}
 
-   ret = drm_gem_fb_lookup(dev, file, mode_cmd, objs);
-   if (ret < 0)
-   goto err_free;
-
ret = komeda_fb_afbc_size_check(kfb, info, objs, file,
mode_cmd);
for (i = 0; i < info->num_planes; ++i)
kfb->base.obj[i] = objs[i];
} else {
-   struct drm_gem_object *objs[4];
-
ret = komeda_fb_check_src_coords(kfb, 0, 0, kfb->base.width,
 kfb->base.height);
if (ret)
-   goto err_free;
-
-   ret = drm_gem_fb_lookup(dev, file, mode_cmd, objs);
-   if (ret < 0)
-   goto err_free;
+   goto err_cleanup;
 
ret = komeda_fb_none_afbc_size_check(mdev, info, objs,
 file, mode_cmd);
@@ -209,7 +202,7 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
 
 err_cleanup:
for (i = 0; i < kfb->base.format->num_planes; i++)
-   drm_gem_object_put_unlocked(kfb->base.obj[i]);
+   drm_gem_object_put_unlocked(objs[i]);
 err_free:
kfree(kfb);
return ERR_PTR(ret);
-- 
2.17.1

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


[PATCHv5 04/34] drm/gem-fb-helper: Add generic afbc size checks

2019-12-17 Thread Andrzej Pietrasiewicz
Extend the size-checking special function to handle afbc.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/drm_gem_framebuffer_helper.c | 49 +--
 include/drm/drm_framebuffer.h| 50 
 include/drm/drm_gem_framebuffer_helper.h |  1 +
 3 files changed, 96 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index d2fce1ec8f37..5fe9032a5ee8 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -21,6 +21,11 @@
 #include 
 #include 
 
+#define AFBC_HEADER_SIZE   16
+#define AFBC_TH_LAYOUT_ALIGNMENT   8
+#define AFBC_SUPERBLOCK_PIXELS 256
+#define AFBC_SUPERBLOCK_ALIGNMENT  128
+
 /**
  * DOC: overview
  *
@@ -299,6 +304,34 @@ int drm_gem_fb_lookup(struct drm_device *dev,
 }
 EXPORT_SYMBOL_GPL(drm_gem_fb_lookup);
 
+static int drm_gem_afbc_min_size(struct drm_device *dev,
+const struct drm_mode_fb_cmd2 *mode_cmd,
+struct drm_afbc_framebuffer *afbc_fb)
+{
+   u32 n_blocks;
+
+   if (!drm_afbc_get_superblock_wh(mode_cmd->modifier[0], 
_fb->block_width, _fb->block_height))
+   return -EINVAL;
+
+   /* tiled header afbc */
+   if (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_TILED) {
+   afbc_fb->block_width *= AFBC_TH_LAYOUT_ALIGNMENT;
+   afbc_fb->block_height *= AFBC_TH_LAYOUT_ALIGNMENT;
+   }
+
+   afbc_fb->aligned_width = ALIGN(mode_cmd->width, afbc_fb->block_width);
+   afbc_fb->aligned_height = ALIGN(mode_cmd->height, 
afbc_fb->block_height);
+   afbc_fb->offset = mode_cmd->offsets[0];
+
+   n_blocks = (afbc_fb->aligned_width * afbc_fb->aligned_height) / 
AFBC_SUPERBLOCK_PIXELS;
+   afbc_fb->offset_payload = ALIGN(n_blocks * AFBC_HEADER_SIZE, 
afbc_fb->alignment_header);
+
+   afbc_fb->afbc_size = afbc_fb->offset_payload
+  + n_blocks * ALIGN(afbc_fb->bpp * 
AFBC_SUPERBLOCK_PIXELS / 8, AFBC_SUPERBLOCK_ALIGNMENT);
+
+   return 0;
+}
+
 /**
  * drm_gem_fb_size_check2() - Helper function for use in
  *   _mode_config_funcs.fb_create implementations
@@ -334,19 +367,27 @@ int drm_gem_fb_size_check2(struct drm_device *dev,
check->pitch_modulo)
return -EINVAL;
 
-   if (check && check->use_min_size)
+   if (check && check->use_min_size) {
min_size = check->min_size[i];
-   else
+   } else if (check && check->data && 
drm_is_afbc(mode_cmd->modifier[0])) {
+   struct drm_afbc_framebuffer *afbc_fb;
+   int ret;
+
+   afbc_fb = check->data;
+   ret = drm_gem_afbc_min_size(dev, mode_cmd, afbc_fb);
+   if (ret < 0)
+   return ret;
+   min_size = ret;
+   } else {
min_size = (height - 1) * pitch
 + drm_format_info_min_pitch(info, i, width)
 + mode_cmd->offsets[i];
-
+   }
if (objs[i]->size < min_size)
return -EINVAL;
}
 
return 0;
-
 }
 EXPORT_SYMBOL_GPL(drm_gem_fb_size_check2);
 
diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
index c0e0256e3e98..c8a06e37585a 100644
--- a/include/drm/drm_framebuffer.h
+++ b/include/drm/drm_framebuffer.h
@@ -297,4 +297,54 @@ int drm_framebuffer_plane_width(int width,
 int drm_framebuffer_plane_height(int height,
 const struct drm_framebuffer *fb, int plane);
 
+/**
+ * struct drm_afbc_framebuffer - a special afbc frame buffer object
+ *
+ * A derived class of struct drm_framebuffer, dedicated for afbc use cases.
+ */
+struct drm_afbc_framebuffer {
+   /**
+* @base: base framebuffer structure.
+*/
+   struct drm_framebuffer base;
+   /**
+* @block_widht: width of a single afbc block
+*/
+   u32 block_width;
+   /**
+* @block_widht: height of a single afbc block
+*/
+   u32 block_height;
+   /**
+* @aligned_width: aligned frame buffer width
+*/
+   u32 aligned_width;
+   /**
+* @aligned_height: aligned frame buffer height
+*/
+   u32 aligned_height;
+   /**
+* @offset: offset of the first afbc header
+*/
+   u32 offset;
+   /**
+* @alignment_header: required alignment for afbc headers
+*/
+   u32 alignment_header;
+   /**
+* @afbc_size: minimum size of afbc

[PATCHv5 13/34] drm/komeda: Make komeda_fb_none_size_check independent from framebuffer

2019-12-17 Thread Andrzej Pietrasiewicz
All necessary data is now available in other data structures.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 2014cd843aeb..43db95a76291 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -98,13 +98,11 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb,
 
 static int
 komeda_fb_none_afbc_size_check(struct komeda_dev *mdev,
-  struct komeda_fb *kfb,
   const struct drm_format_info *info,
   struct drm_gem_object **objs,
   struct drm_file *file,
   const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-   struct drm_framebuffer *fb = >base;
struct drm_gem_object *obj;
u32 i, block_h;
u64 min_size;
@@ -113,9 +111,10 @@ komeda_fb_none_afbc_size_check(struct komeda_dev *mdev,
obj = objs[i];
 
block_h = drm_format_info_block_height(info, i);
-   if ((fb->pitches[i] * block_h) % mdev->chip.bus_width) {
+   if ((mode_cmd->pitches[i] * block_h) % mdev->chip.bus_width) {
DRM_DEBUG_KMS("Pitch[%d]: 0x%x doesn't align to 0x%x\n",
- i, fb->pitches[i], mdev->chip.bus_width);
+ i, mode_cmd->pitches[i],
+ mdev->chip.bus_width);
return -EINVAL;
}
 
@@ -183,7 +182,7 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
return ERR_PTR(ret);
}
 
-   ret = komeda_fb_none_afbc_size_check(mdev, kfb, info, objs,
+   ret = komeda_fb_none_afbc_size_check(mdev, info, objs,
 file, mode_cmd);
for (i = 0; i < info->num_planes; ++i)
kfb->base.obj[i] = objs[i];
-- 
2.17.1

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


[PATCHv5 09/34] drm/komeda: Explicitly require 1 plane for AFBC

2019-12-17 Thread Andrzej Pietrasiewicz
Apparently komeda silently assumes that there is only 1 plane in an AFBC
buffer. Make this assumption explicit.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 7004c3c8f8de..c0bc499a9c29 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -169,6 +169,11 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
info = kfb->base.format;
 
if (kfb->base.modifier) {
+   if (info->num_planes != 1) {
+   DRM_DEBUG_KMS("AFBC requires exactly 1 plane.\n");
+   kfree(kfb);
+   return ERR_PTR(-EINVAL);
+   }
ret = komeda_fb_afbc_size_check(kfb, info, file, mode_cmd);
} else {
if (komeda_fb_check_src_coords(kfb, 0, 0, kfb->base.width,
-- 
2.17.1

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


[PATCHv5 00/34] Add AFBC support for Rockchip

2019-12-17 Thread Andrzej Pietrasiewicz
This series adds AFBC support for Rockchip. It is inspired by:

https://chromium.googlesource.com/chromiumos/third_party/kernel/+/refs/heads/factory-gru-9017.B-chromeos-4.4/drivers/gpu/drm/rockchip/rockchip_drm_vop.c

This is the fifth iteration of the afbc series. Between v3 and v4 a lot of
rework has been done, the main goal of which was to move all afbc-related
checks to helpers, so that core does not deal with it.

A new struct drm_afbc_framebuffer is added, which stores afbc-related
driver-specific data. Because of that, in drivers that wish to
use this feature, the struct must be allocated directly in the driver
code rather than inside helpers, so the first portion of the patchset
does the necessary refactoring.

Then, there are 3 users of afbc: komeda, malidp and, finally, rockchip,
the latter being the ultimate purpose of this work and the 3 subsequent
portions of the patchset move komeda and malidp to generic helpers and add
afbc support to rockchip.

The idea is to make all afbc users follow a similar pattern. In fb_create()
they allocate struct drm_afbc_framebuffer, do their specific checks which
can be done before object lookups, do object lookups and a special version
of a size check, which understands struct drm_afbc_framebuffer, followed
by any other driver-specific checks and initializing the gem object.
The helpers for the common parts are factored out so that drivers
can use them.

The komeda driver has been the farthest away from such a pattern, so it
required most changes. However, due to the fact that I don't have any
komeda hardware I did the changes to komeda in an incremental fashion with
a series of (usually) very small, easy to understand steps. malidp was
pretty straightforward, and rockchip's afbc checks follow the pattern.

I kindly ask for reviewing the series. I need to mention that my ultimate
goal is merging afbc for rockchip and I don't have other hardware, so some
help from malidp and komeda developers/maintainers would be appreciated.

@Liviu, @James, @Mihail, @Brian: a kind request to you to have a look and
test the patchset, as I don't have appropriate hardware.

Rebased onto drm-misc-next.

v4..v5:
- used proper way of subclassing drm_framebuffer (Daniel Vetter)
- added documentation to exported functions (Liviu Dudau)
- reordered new functions in drm_gem_framebuffer_helper.c to make a saner
diff (Liviu Dudau)
- used "2" suffix instead of "_special" for the special version of size
checks (Liviu Dudau)
- dropped unnecessarily added condition in drm_get_format_info() (Liviu
Dudau)
- dropped "block_size = 0;" trick in framebuffer_check() (Daniel Vetter)
- relaxed sticking to 80 characters per line rule in some cases

v3..v4:

- addressed (some) comments from Daniel Stone, Ezequiel Garcia, Daniel
Vetter and James Qian Wang - thank you for input
- refactored helpers to ease accommodating drivers with afbc needs
- moved afbc checks to helpers
- converted komeda, malidp and (the newly added) rockchip to use the afbc
helpers
- eliminated a separate, dedicated source code file

v2..v3:

- addressed (some) comments from Daniel Stone, Liviu Dudau, Daniel Vetter
and Brian Starkey - thank you all

In this iteration some rework has been done. The checking logic is now moved
to framebuffer_check() so it is common to all drivers. But the common part
is not good for komeda, so this series is not good for merging yet.
I kindly ask for feedback whether the changes are in the right direction.
I also kindly ask for input on how to accommodate komeda.

The CONFIG_DRM_AFBC option has been eliminated in favour of adding
drm_afbc.c to drm_kms_helper.

v1..v2:

- addressed comments from Daniel Stone, Ayan Halder, Mihail Atanassov
- coding style fixes** BLURB HERE ***


Andrzej Pietrasiewicz (34):
  drm/core: Add afbc helper functions
  drm/gem-fb-helper: Allow drivers to allocate struct drm_framebuffer on
their own
  drm/gem-fb-helper: Add special version of drm_gem_fb_size_check
  drm/gem-fb-helper: Add generic afbc size checks
  drm/komeda: Use afbc helper
  drm/komeda: Move checking src coordinates to komeda_fb_create
  drm/komeda: Use the already available local variable
  drm/komeda: Retrieve drm_format_info once
  drm/komeda: Explicitly require 1 plane for AFBC
  drm/komeda: Move pitches comparison to komeda_fb_create
  drm/komeda: Provide and use komeda_fb_get_pixel_addr variant not
requiring a fb
  drm/komeda: Factor out object lookups for non-afbc case
  drm/komeda: Make komeda_fb_none_size_check independent from
framebuffer
  drm/komeda: Factor out object lookups for afbc case
  drm/komeda: Free komeda_fb_afbc_size_check from framebuffer dependency
  drm/komeda: Simplify error handling
  drm/komeda: Move object lookup before size checks
  drm/komeda: Move object assignments to framebuffer to after size
checks
  drm/komeda: Make the size checks independent from framebuffer
structure
  drm/komeda: Move helper invocation to after size c

[PATCHv5 07/34] drm/komeda: Use the already available local variable

2019-12-17 Thread Andrzej Pietrasiewicz
There is a local "info" variable which is exactly fb->format, so use it.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 5a1e5f621a8f..33181bdab16b 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -130,7 +130,7 @@ komeda_fb_none_afbc_size_check(struct komeda_dev *mdev, 
struct komeda_fb *kfb,
}
}
 
-   if (fb->format->num_planes == 3) {
+   if (info->num_planes == 3) {
if (fb->pitches[1] != fb->pitches[2]) {
DRM_DEBUG_KMS("The pitch[1] and [2] are not same\n");
return -EINVAL;
-- 
2.17.1

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


[PATCHv5 10/34] drm/komeda: Move pitches comparison to komeda_fb_create

2019-12-17 Thread Andrzej Pietrasiewicz
For AFBC case num_planes equals 1 so the check will not affect it.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../drm/arm/display/komeda/komeda_framebuffer.c| 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index c0bc499a9c29..5d035f6a76a6 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -132,13 +132,6 @@ komeda_fb_none_afbc_size_check(struct komeda_dev *mdev,
}
}
 
-   if (info->num_planes == 3) {
-   if (fb->pitches[1] != fb->pitches[2]) {
-   DRM_DEBUG_KMS("The pitch[1] and [2] are not same\n");
-   return -EINVAL;
-   }
-   }
-
return 0;
 }
 
@@ -188,6 +181,13 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
if (ret < 0)
goto err_cleanup;
 
+   if (info->num_planes == 3)
+   if (kfb->base.pitches[1] != kfb->base.pitches[2]) {
+   DRM_DEBUG_KMS("The pitch[1] and [2] are not same\n");
+   ret = -EINVAL;
+   goto err_cleanup;
+   }
+
ret = drm_framebuffer_init(dev, >base, _fb_funcs);
if (ret < 0) {
DRM_DEBUG_KMS("failed to initialize fb\n");
-- 
2.17.1

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


[PATCHv5 02/34] drm/gem-fb-helper: Allow drivers to allocate struct drm_framebuffer on their own

2019-12-17 Thread Andrzej Pietrasiewicz
Prepare tools for drivers which need to allocate a struct drm_framebuffer
(or a container of struct drm_framebuffer) explicitly, before calling
helpers. In such a case we need new helpers which omit allocating the
struct drm_framebuffer and this patch provides them. Consequently, they
are used also inside the helpers themselves.

The interested drivers will likely need to be able to perform object
lookups and size checks in separate invocations and this patch provides
that as well. Helpers themselves are updated, too.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/drm_gem_framebuffer_helper.c | 216 ++-
 include/drm/drm_gem_framebuffer_helper.h |  17 ++
 2 files changed, 181 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index b9bcd310ca2d..b3494f6b66bb 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -54,6 +54,69 @@ struct drm_gem_object *drm_gem_fb_get_obj(struct 
drm_framebuffer *fb,
 }
 EXPORT_SYMBOL_GPL(drm_gem_fb_get_obj);
 
+/**
+ * drm_gem_fb_init_with_funcs() - Initialize an already allocated framebuffer
+ * @fb: Framebuffer
+ * @dev: DRM device
+ * @mode_cmd: Metadata from the userspace framebuffer creation request
+ * @obj: GEM objects to be assigned to the framebuffer
+ * @num_planes: number of planes
+ * @funcs: vtable to be used for the framebuffer object
+ *
+ * This variant of the function allows passing a custom vtable.
+ *
+ * Returns:
+ * 0 on success or a negative error code
+ */
+int drm_gem_fb_init_with_funcs(struct drm_framebuffer *fb,
+  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)
+{
+   int ret, i;
+
+   drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
+
+   for (i = 0; i < num_planes; i++)
+   fb->obj[i] = obj[i];
+
+   ret = drm_framebuffer_init(dev, fb, funcs);
+   if (ret)
+   DRM_DEV_ERROR(dev->dev, "Failed to init framebuffer: %d\n", 
ret);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(drm_gem_fb_init_with_funcs);
+
+static const struct drm_framebuffer_funcs drm_gem_fb_funcs = {
+   .destroy= drm_gem_fb_destroy,
+   .create_handle  = drm_gem_fb_create_handle,
+};
+
+/**
+ * drm_gem_fb_init() - Initialize an already allocated framebuffer
+ * @fb: Framebuffer
+ * @dev: DRM device
+ * @mode_cmd: Metadata from the userspace framebuffer creation request
+ * @obj: GEM objects to be assigned to the framebuffer
+ * @num_planes: number of planes
+ *
+ * This variant of the function uses a default vtable.
+ *
+ * Returns:
+ * 0 on success or a negative error code
+ */
+int drm_gem_fb_init(struct drm_framebuffer *fb,
+   struct drm_device *dev,
+   const struct drm_mode_fb_cmd2 *mode_cmd,
+   struct drm_gem_object **obj, unsigned int num_planes)
+{
+   return drm_gem_fb_init_with_funcs(fb, dev, mode_cmd, obj, num_planes, 
_gem_fb_funcs);
+}
+EXPORT_SYMBOL_GPL(drm_gem_fb_init);
+
 static struct drm_framebuffer *
 drm_gem_fb_alloc(struct drm_device *dev,
 const struct drm_mode_fb_cmd2 *mode_cmd,
@@ -61,21 +124,14 @@ drm_gem_fb_alloc(struct drm_device *dev,
 const struct drm_framebuffer_funcs *funcs)
 {
struct drm_framebuffer *fb;
-   int ret, i;
+   int ret;
 
fb = kzalloc(sizeof(*fb), GFP_KERNEL);
if (!fb)
return ERR_PTR(-ENOMEM);
 
-   drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
-
-   for (i = 0; i < num_planes; i++)
-   fb->obj[i] = obj[i];
-
-   ret = drm_framebuffer_init(dev, fb, funcs);
+   ret = drm_gem_fb_init_with_funcs(fb, dev, mode_cmd, obj, num_planes, 
funcs);
if (ret) {
-   DRM_DEV_ERROR(dev->dev, "Failed to init framebuffer: %d\n",
- ret);
kfree(fb);
return ERR_PTR(ret);
}
@@ -144,59 +200,29 @@ drm_gem_fb_create_with_funcs(struct drm_device *dev, 
struct drm_file *file,
 const struct drm_mode_fb_cmd2 *mode_cmd,
 const struct drm_framebuffer_funcs *funcs)
 {
-   const struct drm_format_info *info;
struct drm_gem_object *objs[4];
struct drm_framebuffer *fb;
-   int ret, i;
-
-   info = drm_get_format_info(dev, mode_cmd);
-   if (!info)
-   return ERR_PTR(-EINVAL);
-
-   for (i = 0; i < info->num_planes; i++) {
-   unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
-   unsigned int height = mode_cmd->height / (i ? info->vsub : 1)

[PATCHv5 06/34] drm/komeda: Move checking src coordinates to komeda_fb_create

2019-12-17 Thread Andrzej Pietrasiewicz
Next step towards unifying afbc and non-afbc cases as much as possible.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../drm/arm/display/komeda/komeda_framebuffer.c| 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 2f993a9cfb8b..5a1e5f621a8f 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -106,9 +106,6 @@ komeda_fb_none_afbc_size_check(struct komeda_dev *mdev, 
struct komeda_fb *kfb,
u32 i, block_h;
u64 min_size;
 
-   if (komeda_fb_check_src_coords(kfb, 0, 0, fb->width, fb->height))
-   return -EINVAL;
-
for (i = 0; i < info->num_planes; i++) {
obj = drm_gem_object_lookup(file, mode_cmd->handles[i]);
if (!obj) {
@@ -167,10 +164,17 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
 
drm_helper_mode_fill_fb_struct(dev, >base, mode_cmd);
 
-   if (kfb->base.modifier)
+   if (kfb->base.modifier) {
ret = komeda_fb_afbc_size_check(kfb, file, mode_cmd);
-   else
+   } else {
+   if (komeda_fb_check_src_coords(kfb, 0, 0, kfb->base.width,
+  kfb->base.height)) {
+   kfree(kfb);
+   return ERR_PTR(-EINVAL);
+   }
+
ret = komeda_fb_none_afbc_size_check(mdev, kfb, file, mode_cmd);
+   }
if (ret < 0)
goto err_cleanup;
 
-- 
2.17.1

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


[PATCHv5 05/34] drm/komeda: Use afbc helper

2019-12-17 Thread Andrzej Pietrasiewicz
Makes the code shorter and more readable.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../drm/arm/display/komeda/komeda_framebuffer.c  | 16 ++--
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 1b01a625f40e..2f993a9cfb8b 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -52,20 +52,8 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb, struct 
drm_file *file,
return -ENOENT;
}
 
-   switch (fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
-   case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
-   alignment_w = 32;
-   alignment_h = 8;
-   break;
-   case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
-   alignment_w = 16;
-   alignment_h = 16;
-   break;
-   default:
-   WARN(1, "Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n",
-fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
-   break;
-   }
+   if (!drm_afbc_get_superblock_wh(fb->modifier, _w, 
_h))
+   return -EINVAL;
 
/* tiled header afbc */
if (fb->modifier & AFBC_FORMAT_MOD_TILED) {
-- 
2.17.1

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


Re: [PATCHv4 03/36] drm/gem-fb-helper: Allow drivers to allocate struct drm_framebuffer on their own

2019-12-16 Thread Andrzej Pietrasiewicz

Hi Liviu,

My way of thinking is explained below. Do you still find it problematic?

W dniu 16.12.2019 o 18:08, Liviu Dudau pisze:

Hi Andrzej,






+struct drm_framebuffer *
+drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
+const struct drm_mode_fb_cmd2 *mode_cmd,
+const struct drm_framebuffer_funcs *funcs)
+{
+   struct drm_gem_object *objs[4];
+   struct drm_framebuffer *fb;
+   int ret, num_planes;
+
+   ret = drm_gem_fb_lookup(dev, file, mode_cmd, objs);
+   if (ret < 0)
+   return ERR_PTR(ret);


here objs is guaranteed to have been filled...


+   num_planes = ret;
+
+   ret = drm_gem_fb_size_check(dev, mode_cmd, objs);


if drm_gem_fb_size_check() returns an error, then ...


+   if (ret)
+   fb = ERR_PTR(ret);
+   else
+   fb = drm_gem_fb_alloc(dev, mode_cmd, objs, num_planes, funcs);


 the else part is not taken, but ...


... nonetheless objs have already been looked up...



  
-	return ERR_PTR(ret);

+   if (IS_ERR(fb))
+   for (num_planes--; num_planes >= 0; num_planes--)
+   drm_gem_object_put_unlocked(objs[num_planes]);


... here you'll attempt to dereference the objs. I don't think that is correct.


... so it is safe to dereference objs here

Regards,

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


Re: [PATCHv4 05/36] drm/gem-fb-helper: Add generic afbc size checks

2019-12-16 Thread Andrzej Pietrasiewicz

Hi Liviu,

W dniu 16.12.2019 o 18:19, Liviu Dudau pisze:

Hi Andrzej,

On Fri, Dec 13, 2019 at 04:58:36PM +0100, Andrzej Pietrasiewicz wrote:

Extend the size-checking special function to handle afbc.

Signed-off-by: Andrzej Pietrasiewicz 
---
  drivers/gpu/drm/drm_fourcc.c | 10 +++-
  drivers/gpu/drm/drm_framebuffer.c|  3 +
  drivers/gpu/drm/drm_gem_framebuffer_helper.c | 60 ++--
  include/drm/drm_gem_framebuffer_helper.h | 16 ++
  4 files changed, 82 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index d14dd7c86020..9ac2175c5bee 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -323,8 +323,14 @@ drm_get_format_info(struct drm_device *dev,
  {
const struct drm_format_info *info = NULL;
  
-	if (dev->mode_config.funcs->get_format_info)

-   info = dev->mode_config.funcs->get_format_info(mode_cmd);
+   /* bypass driver callback if afbc */
+   if (!drm_is_afbc(mode_cmd->modifier[0]))
+   if (dev->mode_config.funcs->get_format_info) {
+   const struct drm_mode_config_funcs *funcs;
+
+   funcs = dev->mode_config.funcs;
+   info = funcs->get_format_info(mode_cmd);
+   }


What has this change to do with the rest of the patch? Also, I think this goes
against the idea that an AFBC-aware driver might return better data about the 
format
info than the drm_format_info() code.



The reason is the conclusion of my talk with danvet on irc:

https://people.freedesktop.org/~cbrill/dri-log/?channel=dri-devel_names==2019-11-13_html=true

I followed his advice - if I understood him correctly, that is.


As a bikeshed, I know it is useful for debugging to turn the oneliner into 3, 
but it
feels like not necessary here.


80 chars per line. If kept in one line, the limit is exceeded
with an additional indentation level present.

Regards,

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


Re: [PATCH] drm/i915: Provide ddc symlink in hdmi connector sysfs directory

2019-12-13 Thread Andrzej Pietrasiewicz

W dniu 28.11.2019 o 16:01, Andrzej Pietrasiewicz pisze:

Use the ddc pointer provided by the generic connector.



A gentle ping.

Andrzej


Signed-off-by: Andrzej Pietrasiewicz 
Acked-by: Sam Ravnborg 
Reviewed-by: Emil Velikov 
---
Rebased onto drm-intel-next-queued.

  drivers/gpu/drm/i915/display/intel_hdmi.c | 12 
  1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 29a174af5314..6ec8d14bccd7 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -3134,6 +3134,7 @@ void intel_hdmi_init_connector(struct intel_digital_port 
*intel_dig_port,
struct intel_encoder *intel_encoder = _dig_port->base;
struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
+   struct i2c_adapter *ddc;
enum port port = intel_encoder->port;
struct cec_connector_info conn_info;
  
@@ -3149,8 +3150,13 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,

 intel_encoder->base.name))
return;
  
-	drm_connector_init(dev, connector, _hdmi_connector_funcs,

-  DRM_MODE_CONNECTOR_HDMIA);
+   intel_hdmi->ddc_bus = intel_hdmi_ddc_pin(dev_priv, port);
+   ddc = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
+
+   drm_connector_init_with_ddc(dev, connector,
+   _hdmi_connector_funcs,
+   DRM_MODE_CONNECTOR_HDMIA,
+   ddc);
drm_connector_helper_add(connector, _hdmi_connector_helper_funcs);
  
  	connector->interlace_allowed = 1;

@@ -3160,8 +3166,6 @@ void intel_hdmi_init_connector(struct intel_digital_port 
*intel_dig_port,
if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
connector->ycbcr_420_allowed = true;
  
-	intel_hdmi->ddc_bus = intel_hdmi_ddc_pin(dev_priv, port);

-
intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
  
  	if (HAS_DDI(dev_priv))




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


[PATCHv4 35/36] drm/rockchip: Use helper for common task

2019-12-13 Thread Andrzej Pietrasiewicz
Use generic helper code.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 13 +++--
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 221e72e71432..28ce3a335798 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -18,6 +18,7 @@
 #include "rockchip_drm_fb.h"
 #include "rockchip_drm_gem.h"
 
+
 static const struct drm_framebuffer_funcs rockchip_drm_fb_funcs = {
.destroy   = drm_gem_fb_destroy,
.create_handle = drm_gem_fb_create_handle,
@@ -30,22 +31,14 @@ rockchip_fb_alloc(struct drm_device *dev, const struct 
drm_mode_fb_cmd2 *mode_cm
 {
struct drm_framebuffer *fb;
int ret;
-   int i;
 
fb = kzalloc(sizeof(*fb), GFP_KERNEL);
if (!fb)
return ERR_PTR(-ENOMEM);
 
-   drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
-
-   for (i = 0; i < num_planes; i++)
-   fb->obj[i] = obj[i];
-
-   ret = drm_framebuffer_init(dev, fb, _drm_fb_funcs);
+   ret = drm_gem_fb_init_with_funcs(fb, dev, mode_cmd, obj, num_planes,
+_drm_fb_funcs);
if (ret) {
-   DRM_DEV_ERROR(dev->dev,
- "Failed to initialize framebuffer: %d\n",
- ret);
kfree(fb);
return ERR_PTR(ret);
}
-- 
2.17.1

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


[PATCHv4 29/36] drm/komeda: Move special helper invocation outside if-else

2019-12-13 Thread Andrzej Pietrasiewicz
The invocation is the same in both cases and is the last thing inside a
block, so move it outside the if-else clause.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.c  | 12 +++-
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index ac7e099435c9..385df1fd776d 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -44,6 +44,8 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
struct drm_gem_object *objs[4];
struct komeda_fb *kfb;
const struct drm_format_info *info;
+   struct drm_size_check check = { 0 };
+
int ret = 0, i, num_planes;
 
kfb = kzalloc(sizeof(*kfb), GFP_KERNEL);
@@ -68,7 +70,6 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
info = drm_get_format_info(dev, mode_cmd);
 
if (mode_cmd->modifier[0]) {
-   struct drm_size_check check = { 0 };
u32 alignment_w = 0, alignment_h = 0;
u32 alignment_header, n_blocks, bpp;
 
@@ -113,12 +114,7 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
   AFBC_SUPERBLK_ALIGNMENT);
check.min_size[0] = kfb->afbc_size + mode_cmd->offsets[0];
check.use_min_size = true;
-
-   ret = drm_gem_fb_size_check_special(dev, mode_cmd, ,
-   objs);
} else {
-   struct drm_size_check check = { 0 };
-
ret = komeda_fb_check_src_coords(kfb, 0, 0, mode_cmd->width,
 mode_cmd->height);
if (ret)
@@ -140,10 +136,8 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
check.pitch_modulo = mdev->chip.bus_width;
check.use_pitch_multiplier = true;
check.use_min_size = true;
-
-   ret = drm_gem_fb_size_check_special(dev, mode_cmd, ,
-   objs);
}
+   ret = drm_gem_fb_size_check_special(dev, mode_cmd, , objs);
if (ret < 0)
goto err_cleanup;
 
-- 
2.17.1

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


[PATCHv4 23/36] drm/komeda: Use helper for common tasks

2019-12-13 Thread Andrzej Pietrasiewicz
The replaced fragment is 1:1 with the helper code.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.c | 13 +++--
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 1a03318ec73a..74c0caa51bdf 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -185,17 +185,10 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
goto err_cleanup;
}
 
-   drm_helper_mode_fill_fb_struct(dev, >base, mode_cmd);
-
-   for (i = 0; i < info->num_planes; ++i)
-   kfb->base.obj[i] = objs[i];
-
-   ret = drm_framebuffer_init(dev, >base, _fb_funcs);
-   if (ret < 0) {
-   DRM_DEBUG_KMS("failed to initialize fb\n");
-
+   ret = drm_gem_fb_init_with_funcs(>base, dev, mode_cmd, objs,
+info->num_planes, _fb_funcs);
+   if (ret < 0)
goto err_cleanup;
-   }
 
kfb->is_va = mdev->iommu ? true : false;
 
-- 
2.17.1

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


[PATCHv4 30/36] drm/komeda: Move to helper checking afbc buffer size

2019-12-13 Thread Andrzej Pietrasiewicz
Use generic helper code. Adapt struct komeda_fb users to new location
of respective data members.

Signed-off-by: Andrzej Pietrasiewicz 
---
 .../arm/display/komeda/d71/d71_component.c|  7 ++-
 .../arm/display/komeda/komeda_framebuffer.c   | 60 +--
 .../arm/display/komeda/komeda_framebuffer.h   |  8 ---
 .../display/komeda/komeda_pipeline_state.c| 11 ++--
 4 files changed, 39 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index 8a02ade369db..bab015f13ef3 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -4,6 +4,8 @@
  * Author: James.Qian.Wang 
  *
  */
+#include 
+#include 
 #include "d71_dev.h"
 #include "komeda_kms.h"
 #include "malidp_io.h"
@@ -234,9 +236,10 @@ static void d71_layer_update(struct komeda_component *c,
 st->afbc_crop_b));
/* afbc 1.2 wants payload, afbc 1.0/1.1 wants end_addr */
if (fb->modifier & AFBC_FORMAT_MOD_TILED)
-   addr = st->addr[0] + kfb->offset_payload;
+   addr = st->addr[0]
++ kfb->base.afbc_info->offset_payload;
else
-   addr = st->addr[0] + kfb->afbc_size - 1;
+   addr = st->addr[0] + kfb->base.afbc_info->afbc_size - 1;
 
malidp_write32(reg, BLK_P1_PTR_LOW, lower_32_bits(addr));
malidp_write32(reg, BLK_P1_PTR_HIGH, upper_32_bits(addr));
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index 385df1fd776d..d3e0f2c0d924 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -40,6 +40,13 @@ struct drm_framebuffer *
 komeda_fb_create(struct drm_device *dev, struct drm_file *file,
 const struct drm_mode_fb_cmd2 *mode_cmd)
 {
+#define KFB_ALIGN_MASK(type) \
+   (__alignof__(type) - 1)
+#define KFB_INFO_OFFSET(type1, type2)  \
+   ((sizeof(type1) + KFB_ALIGN_MASK(type2)) & ~KFB_ALIGN_MASK(type2))
+#define KFB_COMPOUND_SIZE(type1, type2) \
+   (KFB_INFO_OFFSET(type1, type2) + sizeof(type2))
+
struct komeda_dev *mdev = dev->dev_private;
struct drm_gem_object *objs[4];
struct komeda_fb *kfb;
@@ -48,9 +55,13 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
 
int ret = 0, i, num_planes;
 
-   kfb = kzalloc(sizeof(*kfb), GFP_KERNEL);
+   /* alloc in one chunk to ease freeing */
+   kfb = kzalloc(KFB_COMPOUND_SIZE(struct komeda_fb, struct drm_afbc),
+   GFP_KERNEL);
if (!kfb)
return ERR_PTR(-ENOMEM);
+   kfb->base.modifier_info =
+   kfb + KFB_INFO_OFFSET(struct komeda_fb, struct drm_afbc);
 
kfb->format_caps = komeda_get_format_caps(>fmt_tbl,
  mode_cmd->pixel_format,
@@ -70,50 +81,30 @@ komeda_fb_create(struct drm_device *dev, struct drm_file 
*file,
info = drm_get_format_info(dev, mode_cmd);
 
if (mode_cmd->modifier[0]) {
-   u32 alignment_w = 0, alignment_h = 0;
-   u32 alignment_header, n_blocks, bpp;
-
if (num_planes != 1) {
DRM_DEBUG_KMS("AFBC requires exactly 1 plane.\n");
ret = -EINVAL;
goto err_cleanup;
}
 
-   if (!drm_afbc_get_superblock_wh(mode_cmd->modifier[0],
-   _w, _h)) {
-   ret = -EINVAL;
-   goto err_cleanup;
-   }
-
/* tiled header afbc */
-   if (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_TILED) {
-   alignment_w *= AFBC_TH_LAYOUT_ALIGNMENT;
-   alignment_h *= AFBC_TH_LAYOUT_ALIGNMENT;
-   alignment_header = AFBC_TH_BODY_START_ALIGNMENT;
-   } else {
-   alignment_header = AFBC_BODY_START_ALIGNMENT;
-   }
-
-   kfb->aligned_w = ALIGN(mode_cmd->width, alignment_w);
-   kfb->aligned_h = ALIGN(mode_cmd->height, alignment_h);
-
-   if (mode_cmd->offsets[0] % alignment_header) {
+   if (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_TILED)
+   kfb->base.afbc_info->alignment_header =
+   AFBC_TH_BODY_START_ALIGNMENT;
+   else
+   kfb->base.afbc_info->alignment_header =
+  

  1   2   3   4   >