* [PATCH v4,01/22] v4l2: add restricted memory flags
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,02/22] v4l2: handle restricted memory flags in queue setup Yunfei Dong
` (20 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
From: Jeffrey Kardatzke <jkardatzke@google.com>
Adds a V4L2 flag which indicates that a queue is using restricted
dmabufs and the corresponding capability flag.
Signed-off-by: Jeffrey Kardatzke <jkardatzke@google.com>
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
include/media/videobuf2-core.h | 8 +++++++-
include/uapi/linux/videodev2.h | 2 ++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 56719a26a46c..047d4798e423 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -518,6 +518,9 @@ struct vb2_buf_ops {
* ->finish().
* @non_coherent_mem: when set queue will attempt to allocate buffers using
* non-coherent memory.
+ * @allow_restricted_mem: when set user-space can pass the %V4L2_MEMORY_FLAG_RESTRICTED
+ * flag to indicate the dma bufs are restricted.
+ * @restricted_mem: when set queue will verify that the dma bufs are restricted.
* @lock: pointer to a mutex that protects the &struct vb2_queue. The
* driver can set this to a mutex to let the v4l2 core serialize
* the queuing ioctls. If the driver wants to handle locking
@@ -604,6 +607,8 @@ struct vb2_queue {
unsigned int uses_requests:1;
unsigned int allow_cache_hints:1;
unsigned int non_coherent_mem:1;
+ unsigned int allow_restricted_mem:1;
+ unsigned int restricted_mem:1;
struct mutex *lock;
void *owner;
@@ -773,7 +778,8 @@ void vb2_core_querybuf(struct vb2_queue *q, struct vb2_buffer *vb, void *pb);
* @q: pointer to &struct vb2_queue with videobuf2 queue.
* @memory: memory type, as defined by &enum vb2_memory.
* @flags: auxiliary queue/buffer management flags. Currently, the only
- * used flag is %V4L2_MEMORY_FLAG_NON_COHERENT.
+ * used flags are %V4L2_MEMORY_FLAG_NON_COHERENT and
+ * %V4L2_MEMORY_FLAG_RESTRICTED.
* @count: requested buffer count.
*
* Videobuf2 core helper to implement VIDIOC_REQBUF() operation. It is called
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 68e7ac178cc2..3e3f8d4b7c81 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -1026,6 +1026,7 @@ struct v4l2_requestbuffers {
};
#define V4L2_MEMORY_FLAG_NON_COHERENT (1 << 0)
+#define V4L2_MEMORY_FLAG_RESTRICTED (1 << 1)
/* capabilities for struct v4l2_requestbuffers and v4l2_create_buffers */
#define V4L2_BUF_CAP_SUPPORTS_MMAP (1 << 0)
@@ -1036,6 +1037,7 @@ struct v4l2_requestbuffers {
#define V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF (1 << 5)
#define V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS (1 << 6)
#define V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS (1 << 7)
+#define V4L2_BUF_CAP_SUPPORTS_RESTRICTED_MEM (1 << 8)
/**
* struct v4l2_plane - plane info for multi-planar buffers
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,02/22] v4l2: handle restricted memory flags in queue setup
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,01/22] v4l2: add restricted memory flags Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,03/22] v4l2: verify restricted dmabufs are used in restricted queue Yunfei Dong
` (19 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
From: Jeffrey Kardatzke <jkardatzke@google.com>
Validates the restricted memory flags when setting up a queue and
ensures the queue has the proper capability.
Signed-off-by: Jeffrey Kardatzke <jkardatzke@google.com>
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../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 41a832dd1426..7f5fd9ec9117 100644
--- a/drivers/media/common/videobuf2/videobuf2-core.c
+++ b/drivers/media/common/videobuf2/videobuf2-core.c
@@ -813,6 +813,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;
+}
+
int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
unsigned int flags, unsigned int *count)
{
@@ -820,6 +829,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;
int ret = 0;
@@ -862,6 +872,9 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
return 0;
}
+ if (restricted_mem && (!q->allow_restricted_mem || memory != V4L2_MEMORY_DMABUF))
+ return -EINVAL;
+
/*
* Make sure the requested values and current defaults are sane.
*/
@@ -882,6 +895,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.
@@ -986,6 +1000,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;
@@ -994,6 +1009,9 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
return -ENOBUFS;
}
+ if (restricted_mem && (!q->allow_restricted_mem || memory != V4L2_MEMORY_DMABUF))
+ return -EINVAL;
+
if (no_previous_buffers) {
if (q->waiting_in_dqbuf && *count) {
dprintk(q, 1, "another dup()ped fd is waiting for a buffer\n");
@@ -1015,6 +1033,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");
@@ -1022,6 +1041,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 54d572c3b515..e825b1e2e22f 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -686,6 +686,8 @@ static void fill_buf_caps(struct vb2_queue *q, u32 *caps)
*caps |= V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS;
if (q->supports_requests)
*caps |= V4L2_BUF_CAP_SUPPORTS_REQUESTS;
+ if (q->allow_restricted_mem && q->io_modes & VB2_DMABUF)
+ *caps |= V4L2_BUF_CAP_SUPPORTS_RESTRICTED_MEM;
}
static void validate_memory_flags(struct vb2_queue *q,
@@ -700,7 +702,7 @@ static void validate_memory_flags(struct vb2_queue *q,
*flags = 0;
} else {
/* Clear all unknown flags. */
- *flags &= V4L2_MEMORY_FLAG_NON_COHERENT;
+ *flags &= V4L2_MEMORY_FLAG_NON_COHERENT | V4L2_MEMORY_FLAG_RESTRICTED;
}
}
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,03/22] v4l2: verify restricted dmabufs are used in restricted queue
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,01/22] v4l2: add restricted memory flags Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,02/22] v4l2: handle restricted memory flags in queue setup Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,04/22] v4l: add documentation for restricted memory flag Yunfei Dong
` (18 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
From: Jeffrey Kardatzke <jkardatzke@google.com>
Verfies in the dmabuf implementations that if the restricted memory
flag is set for a queue that the dmabuf submitted to the queue is
unmappable.
Signed-off-by: Jeffrey Kardatzke <jkardatzke@google.com>
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
drivers/media/common/videobuf2/videobuf2-dma-contig.c | 8 ++++++++
drivers/media/common/videobuf2/videobuf2-dma-sg.c | 8 ++++++++
2 files changed, 16 insertions(+)
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
index 3d4fd4ef5310..f953570fef27 100644
--- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
@@ -710,6 +710,14 @@ static int vb2_dc_map_dmabuf(void *mem_priv)
return -EINVAL;
}
+ /* Verify the dmabuf is restricted if we are in restricted mode, this is done
+ * by validating there is no page entry for the dmabuf.
+ */
+ if (buf->vb->vb2_queue->restricted_mem && sg_page(sgt->sgl)) {
+ pr_err("restricted queue requires restricted dma_buf");
+ return -EINVAL;
+ }
+
/* checking if dmabuf is big enough to store contiguous chunk */
contig_size = vb2_dc_get_contiguous_size(sgt);
if (contig_size < buf->size) {
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
index 6975a71d740f..f87bd3f40b9b 100644
--- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
@@ -570,6 +570,14 @@ static int vb2_dma_sg_map_dmabuf(void *mem_priv)
return -EINVAL;
}
+ /* Verify the dmabuf is restricted if we are in restricted mode, this is done
+ * by validating there is no page entry for the dmabuf.
+ */
+ if (buf->vb->vb2_queue->restricted_mem && !sg_page(sgt->sgl)) {
+ pr_err("restricted queue requires restricted dma_buf");
+ return -EINVAL;
+ }
+
buf->dma_sgt = sgt;
buf->vaddr = NULL;
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,04/22] v4l: add documentation for restricted memory flag
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (2 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,03/22] v4l2: verify restricted dmabufs are used in restricted queue Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,05/22] dma-buf: heaps: Deduplicate docs and adopt common format Yunfei Dong
` (17 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
From: Jeffrey Kardatzke <jkardatzke@google.com>
Adds documentation for V4L2_MEMORY_FLAG_RESTRICTED.
Signed-off-by: Jeffrey Kardatzke <jkardatzke@google.com>
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
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 <mmap>` I/O and the
queue reports the :ref:`V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS
<V4L2-BUF-CAP-SUPPORTS-MMAP-CACHE-HINTS>` capability.
+ * .. _`V4L2-MEMORY-FLAG-RESTRICTED`:
+
+ - ``V4L2_MEMORY_FLAG_RESTRICTED``
+ - 0x00000002
+ - 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.
.. raw:: latex
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,05/22] dma-buf: heaps: Deduplicate docs and adopt common format
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (3 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,04/22] v4l: add documentation for restricted memory flag Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,06/22] dma-heap: Add proper kref handling on dma-buf heaps Yunfei Dong
` (16 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
From: "T.J. Mercier" <tjmercier@google.com>
The docs for dma_heap_get_name were incorrect, and since they were
duplicated in the header they were wrong there too.
The docs formatting was inconsistent so I tried to make it more
consistent across functions since I'm already in here doing cleanup.
Remove multiple unused includes and alphabetize.
Signed-off-by: T.J. Mercier <tjmercier@google.com>
Signed-off-by: Yong Wu <yong.wu@mediatek.com>
[Yong: Just add a comment for "priv" to mute build warning]
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
drivers/dma-buf/dma-heap.c | 27 +++++++++++++++------------
include/linux/dma-heap.h | 21 +--------------------
2 files changed, 16 insertions(+), 32 deletions(-)
diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
index 84ae708fafe7..22f6c193db0d 100644
--- a/drivers/dma-buf/dma-heap.c
+++ b/drivers/dma-buf/dma-heap.c
@@ -7,17 +7,15 @@
*/
#include <linux/cdev.h>
-#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/dma-buf.h>
+#include <linux/dma-heap.h>
#include <linux/err.h>
-#include <linux/xarray.h>
#include <linux/list.h>
-#include <linux/slab.h>
#include <linux/nospec.h>
-#include <linux/uaccess.h>
#include <linux/syscalls.h>
-#include <linux/dma-heap.h>
+#include <linux/uaccess.h>
+#include <linux/xarray.h>
#include <uapi/linux/dma-heap.h>
#define DEVNAME "dma_heap"
@@ -28,9 +26,10 @@
* struct dma_heap - represents a dmabuf heap in the system
* @name: used for debugging/device-node name
* @ops: ops struct for this heap
- * @heap_devt heap device node
- * @list list head connecting to list of heaps
- * @heap_cdev heap char device
+ * @priv: private data for this heap
+ * @heap_devt: heap device node
+ * @list: list head connecting to list of heaps
+ * @heap_cdev: heap char device
*
* Represents a heap of memory from which buffers can be made.
*/
@@ -193,11 +192,11 @@ static const struct file_operations dma_heap_fops = {
};
/**
- * dma_heap_get_drvdata() - get per-subdriver data for the heap
+ * dma_heap_get_drvdata - get per-heap driver data
* @heap: DMA-Heap to retrieve private data for
*
* Returns:
- * The per-subdriver data for the heap.
+ * The per-heap data for the heap.
*/
void *dma_heap_get_drvdata(struct dma_heap *heap)
{
@@ -205,8 +204,8 @@ void *dma_heap_get_drvdata(struct dma_heap *heap)
}
/**
- * dma_heap_get_name() - get heap name
- * @heap: DMA-Heap to retrieve private data for
+ * dma_heap_get_name - get heap name
+ * @heap: DMA-Heap to retrieve the name of
*
* Returns:
* The char* for the heap name.
@@ -216,6 +215,10 @@ const char *dma_heap_get_name(struct dma_heap *heap)
return heap->name;
}
+/**
+ * dma_heap_add - adds a heap to dmabuf heaps
+ * @exp_info: information needed to register this heap
+ */
struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
{
struct dma_heap *heap, *h, *err_ret;
diff --git a/include/linux/dma-heap.h b/include/linux/dma-heap.h
index 0c05561cad6e..fbe86ec889a8 100644
--- a/include/linux/dma-heap.h
+++ b/include/linux/dma-heap.h
@@ -9,14 +9,13 @@
#ifndef _DMA_HEAPS_H
#define _DMA_HEAPS_H
-#include <linux/cdev.h>
#include <linux/types.h>
struct dma_heap;
/**
* struct dma_heap_ops - ops to operate on a given heap
- * @allocate: allocate dmabuf and return struct dma_buf ptr
+ * @allocate: allocate dmabuf and return struct dma_buf ptr
*
* allocate returns dmabuf on success, ERR_PTR(-errno) on error.
*/
@@ -41,28 +40,10 @@ struct dma_heap_export_info {
void *priv;
};
-/**
- * dma_heap_get_drvdata() - get per-heap driver data
- * @heap: DMA-Heap to retrieve private data for
- *
- * Returns:
- * The per-heap data for the heap.
- */
void *dma_heap_get_drvdata(struct dma_heap *heap);
-/**
- * dma_heap_get_name() - get heap name
- * @heap: DMA-Heap to retrieve private data for
- *
- * Returns:
- * The char* for the heap name.
- */
const char *dma_heap_get_name(struct dma_heap *heap);
-/**
- * dma_heap_add - adds a heap to dmabuf heaps
- * @exp_info: information needed to register this heap
- */
struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info);
#endif /* _DMA_HEAPS_H */
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,06/22] dma-heap: Add proper kref handling on dma-buf heaps
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (4 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,05/22] dma-buf: heaps: Deduplicate docs and adopt common format Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,07/22] dma-heap: Provide accessors so that in-kernel drivers can allocate dmabufs from specific heaps Yunfei Dong
` (15 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
From: John Stultz <jstultz@google.com>
Add proper refcounting on the dma_heap structure.
While existing heaps are built-in, we may eventually
have heaps loaded from modules, and we'll need to be
able to properly handle the references to the heaps
Signed-off-by: John Stultz <jstultz@google.com>
Signed-off-by: T.J. Mercier <tjmercier@google.com>
Signed-off-by: Yong Wu <yong.wu@mediatek.com>
[Yong: Just add comment for "minor" and "refcount"]
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
drivers/dma-buf/dma-heap.c | 29 +++++++++++++++++++++++++++++
include/linux/dma-heap.h | 2 ++
2 files changed, 31 insertions(+)
diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
index 22f6c193db0d..97025ee8500f 100644
--- a/drivers/dma-buf/dma-heap.c
+++ b/drivers/dma-buf/dma-heap.c
@@ -11,6 +11,7 @@
#include <linux/dma-buf.h>
#include <linux/dma-heap.h>
#include <linux/err.h>
+#include <linux/kref.h>
#include <linux/list.h>
#include <linux/nospec.h>
#include <linux/syscalls.h>
@@ -30,6 +31,7 @@
* @heap_devt: heap device node
* @list: list head connecting to list of heaps
* @heap_cdev: heap char device
+ * @refcount: reference counter for this heap device
*
* Represents a heap of memory from which buffers can be made.
*/
@@ -40,6 +42,7 @@ struct dma_heap {
dev_t heap_devt;
struct list_head list;
struct cdev heap_cdev;
+ struct kref refcount;
};
static LIST_HEAD(heap_list);
@@ -240,6 +243,7 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
if (!heap)
return ERR_PTR(-ENOMEM);
+ kref_init(&heap->refcount);
heap->name = exp_info->name;
heap->ops = exp_info->ops;
heap->priv = exp_info->priv;
@@ -304,6 +308,31 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
return err_ret;
}
+static void dma_heap_release(struct kref *ref)
+{
+ struct dma_heap *heap = container_of(ref, struct dma_heap, refcount);
+ unsigned int minor = MINOR(heap->heap_devt);
+
+ mutex_lock(&heap_list_lock);
+ list_del(&heap->list);
+ mutex_unlock(&heap_list_lock);
+
+ device_destroy(dma_heap_class, heap->heap_devt);
+ cdev_del(&heap->heap_cdev);
+ xa_erase(&dma_heap_minors, minor);
+
+ kfree(heap);
+}
+
+/**
+ * dma_heap_put - drops a reference to a dmabuf heap, potentially freeing it
+ * @heap: DMA-Heap whose reference count to decrement
+ */
+void dma_heap_put(struct dma_heap *heap)
+{
+ kref_put(&heap->refcount, dma_heap_release);
+}
+
static char *dma_heap_devnode(const struct device *dev, umode_t *mode)
{
return kasprintf(GFP_KERNEL, "dma_heap/%s", dev_name(dev));
diff --git a/include/linux/dma-heap.h b/include/linux/dma-heap.h
index fbe86ec889a8..d57593f8a1bc 100644
--- a/include/linux/dma-heap.h
+++ b/include/linux/dma-heap.h
@@ -46,4 +46,6 @@ const char *dma_heap_get_name(struct dma_heap *heap);
struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info);
+void dma_heap_put(struct dma_heap *heap);
+
#endif /* _DMA_HEAPS_H */
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,07/22] dma-heap: Provide accessors so that in-kernel drivers can allocate dmabufs from specific heaps
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (5 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,06/22] dma-heap: Add proper kref handling on dma-buf heaps Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,08/22] media: mediatek: vcodec: add tee client interface to communiate with optee-os Yunfei Dong
` (14 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
From: John Stultz <jstultz@google.com>
This allows drivers who don't want to create their own
DMA-BUF exporter to be able to allocate DMA-BUFs directly
from existing DMA-BUF Heaps.
There is some concern that the premise of DMA-BUF heaps is
that userland knows better about what type of heap memory
is needed for a pipeline, so it would likely be best for
drivers to import and fill DMA-BUFs allocated by userland
instead of allocating one themselves, but this is still
up for debate.
Signed-off-by: John Stultz <jstultz@google.com>
Signed-off-by: T.J. Mercier <tjmercier@google.com>
Signed-off-by: Yong Wu <yong.wu@mediatek.com>
[Yong: Fix the checkpatch alignment warning]
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
drivers/dma-buf/dma-heap.c | 83 ++++++++++++++++++++++++++++++--------
include/linux/dma-heap.h | 6 +++
2 files changed, 73 insertions(+), 16 deletions(-)
diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
index 97025ee8500f..6efe833a4b10 100644
--- a/drivers/dma-buf/dma-heap.c
+++ b/drivers/dma-buf/dma-heap.c
@@ -51,12 +51,24 @@ static dev_t dma_heap_devt;
static struct class *dma_heap_class;
static DEFINE_XARRAY_ALLOC(dma_heap_minors);
-static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len,
- unsigned int fd_flags,
- unsigned int heap_flags)
+/**
+ * dma_heap_buffer_alloc - Allocate dma-buf from a dma_heap
+ * @heap: DMA-Heap to allocate from
+ * @len: size to allocate in bytes
+ * @fd_flags: flags to set on returned dma-buf fd
+ * @heap_flags: flags to pass to the dma heap
+ *
+ * This is for internal dma-buf allocations only. Free returned buffers with dma_buf_put().
+ */
+struct dma_buf *dma_heap_buffer_alloc(struct dma_heap *heap, size_t len,
+ unsigned int fd_flags,
+ unsigned int heap_flags)
{
- struct dma_buf *dmabuf;
- int fd;
+ if (fd_flags & ~DMA_HEAP_VALID_FD_FLAGS)
+ return ERR_PTR(-EINVAL);
+
+ if (heap_flags & ~DMA_HEAP_VALID_HEAP_FLAGS)
+ return ERR_PTR(-EINVAL);
/*
* Allocations from all heaps have to begin
@@ -64,9 +76,20 @@ static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len,
*/
len = PAGE_ALIGN(len);
if (!len)
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
+
+ return heap->ops->allocate(heap, len, fd_flags, heap_flags);
+}
+EXPORT_SYMBOL_GPL(dma_heap_buffer_alloc);
- dmabuf = heap->ops->allocate(heap, len, fd_flags, heap_flags);
+static int dma_heap_bufferfd_alloc(struct dma_heap *heap, size_t len,
+ unsigned int fd_flags,
+ unsigned int heap_flags)
+{
+ struct dma_buf *dmabuf;
+ int fd;
+
+ dmabuf = dma_heap_buffer_alloc(heap, len, fd_flags, heap_flags);
if (IS_ERR(dmabuf))
return PTR_ERR(dmabuf);
@@ -104,15 +127,9 @@ static long dma_heap_ioctl_allocate(struct file *file, void *data)
if (heap_allocation->fd)
return -EINVAL;
- if (heap_allocation->fd_flags & ~DMA_HEAP_VALID_FD_FLAGS)
- return -EINVAL;
-
- if (heap_allocation->heap_flags & ~DMA_HEAP_VALID_HEAP_FLAGS)
- return -EINVAL;
-
- fd = dma_heap_buffer_alloc(heap, heap_allocation->len,
- heap_allocation->fd_flags,
- heap_allocation->heap_flags);
+ fd = dma_heap_bufferfd_alloc(heap, heap_allocation->len,
+ heap_allocation->fd_flags,
+ heap_allocation->heap_flags);
if (fd < 0)
return fd;
@@ -205,6 +222,7 @@ void *dma_heap_get_drvdata(struct dma_heap *heap)
{
return heap->priv;
}
+EXPORT_SYMBOL_GPL(dma_heap_get_drvdata);
/**
* dma_heap_get_name - get heap name
@@ -217,6 +235,7 @@ const char *dma_heap_get_name(struct dma_heap *heap)
{
return heap->name;
}
+EXPORT_SYMBOL_GPL(dma_heap_get_name);
/**
* dma_heap_add - adds a heap to dmabuf heaps
@@ -307,6 +326,37 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
kfree(heap);
return err_ret;
}
+EXPORT_SYMBOL_GPL(dma_heap_add);
+
+/**
+ * dma_heap_find - get the heap registered with the specified name
+ * @name: Name of the DMA-Heap to find
+ *
+ * Returns:
+ * The DMA-Heap with the provided name.
+ *
+ * NOTE: DMA-Heaps returned from this function MUST be released using
+ * dma_heap_put() when the user is done to enable the heap to be unloaded.
+ */
+struct dma_heap *dma_heap_find(const char *name)
+{
+ struct dma_heap *h;
+
+ mutex_lock(&heap_list_lock);
+ list_for_each_entry(h, &heap_list, list) {
+ if (!kref_get_unless_zero(&h->refcount))
+ continue;
+
+ if (!strcmp(h->name, name)) {
+ mutex_unlock(&heap_list_lock);
+ return h;
+ }
+ dma_heap_put(h);
+ }
+ mutex_unlock(&heap_list_lock);
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(dma_heap_find);
static void dma_heap_release(struct kref *ref)
{
@@ -332,6 +382,7 @@ void dma_heap_put(struct dma_heap *heap)
{
kref_put(&heap->refcount, dma_heap_release);
}
+EXPORT_SYMBOL_GPL(dma_heap_put);
static char *dma_heap_devnode(const struct device *dev, umode_t *mode)
{
diff --git a/include/linux/dma-heap.h b/include/linux/dma-heap.h
index d57593f8a1bc..3cbf9bff2346 100644
--- a/include/linux/dma-heap.h
+++ b/include/linux/dma-heap.h
@@ -46,6 +46,12 @@ const char *dma_heap_get_name(struct dma_heap *heap);
struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info);
+struct dma_heap *dma_heap_find(const char *name);
+
void dma_heap_put(struct dma_heap *heap);
+struct dma_buf *dma_heap_buffer_alloc(struct dma_heap *heap, size_t len,
+ unsigned int fd_flags,
+ unsigned int heap_flags);
+
#endif /* _DMA_HEAPS_H */
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,08/22] media: mediatek: vcodec: add tee client interface to communiate with optee-os
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (6 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,07/22] dma-heap: Provide accessors so that in-kernel drivers can allocate dmabufs from specific heaps Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,09/22] media: mediatek: vcodec: allocate tee share memory Yunfei Dong
` (13 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
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 <yunfei.dong@mediatek.com>
---
.../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 849b89dd205c..b1a2107f2a1e 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 000000000000..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 <yunfei.dong@mediatek.com>
+ */
+
+#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;
+}
+
+int mtk_vcodec_dec_optee_private_init(struct mtk_vcodec_dec_dev *vcodec_dev)
+{
+ vcodec_dev->optee_private = devm_kzalloc(&vcodec_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(&vcodec_dev->optee_private->tee_active_cnt, 0);
+ mutex_init(&vcodec_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 = &optee_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:
+ export_uuid(session_arg.uuid, &mtk_vdec_lat_uuid);
+ session_func = MTK_VDEC_OPTEE_TA_LAT_SUBMIT_COMMAND;
+ ca_info = &optee_private->lat_ca;
+ break;
+ case MTK_VDEC_CORE:
+ export_uuid(session_arg.uuid, &mtk_vdec_core_uuid);
+ session_func = MTK_VDEC_OPTEE_TA_CORE_SUBMIT_COMMAND;
+ ca_info = &optee_private->core_ca;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ session_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC;
+ session_arg.num_params = 0;
+
+ err = tee_client_open_session(optee_private->tee_vdec_ctx, &session_arg, NULL);
+ if (err < 0 || session_arg.ret != 0) {
+ dev_err(dev, MTK_DBG_VCODEC_STR "open vdec tee session fail hw_id:%d err:%x.\n",
+ hardware_index, session_arg.ret);
+ return -EINVAL;
+ }
+ ca_info->vdec_session_id = session_arg.session;
+ ca_info->hw_id = hardware_index;
+ ca_info->vdec_session_func = session_func;
+
+ 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);
+
+ return err;
+}
+
+static void mtk_vcodec_dec_optee_deinit_hw_info(struct mtk_vdec_optee_private *optee_private,
+ enum mtk_vdec_hw_id hw_id)
+{
+ struct mtk_vdec_optee_ca_info *ca_info;
+
+ if (hw_id == MTK_VDEC_LAT0)
+ ca_info = &optee_private->lat_ca;
+ else
+ ca_info = &optee_private->core_ca;
+
+ tee_client_close_session(optee_private->tee_vdec_ctx, ca_info->vdec_session_id);
+}
+
+int mtk_vcodec_dec_optee_open(struct mtk_vdec_optee_private *optee_private)
+{
+ struct device *dev = &optee_private->vcodec_dev->plat_dev->dev;
+ int ret;
+
+ mutex_lock(&optee_private->tee_mutex);
+ if (atomic_inc_return(&optee_private->tee_active_cnt) > 1) {
+ mutex_unlock(&optee_private->tee_mutex);
+ dev_dbg(dev, MTK_DBG_VCODEC_STR "already init vdec optee private data!\n");
+ return 0;
+ }
+
+ /* Open context with TEE driver */
+ optee_private->tee_vdec_ctx = tee_client_open_context(NULL, mtk_vcodec_dec_optee_match,
+ NULL, NULL);
+ if (IS_ERR(optee_private->tee_vdec_ctx)) {
+ dev_err(dev, MTK_DBG_VCODEC_STR "optee vdec tee context failed.\n");
+ ret = PTR_ERR(optee_private->tee_vdec_ctx);
+ goto err_ctx_open;
+ }
+
+ ret = mtk_vcodec_dec_optee_init_hw_info(optee_private, MTK_VDEC_LAT0);
+ if (ret < 0)
+ goto err_lat_init;
+
+ if (IS_VDEC_LAT_ARCH(optee_private->vcodec_dev->vdec_pdata->hw_arch)) {
+ ret = mtk_vcodec_dec_optee_init_hw_info(optee_private, MTK_VDEC_CORE);
+ if (ret < 0)
+ goto err_core_init;
+ }
+
+ mutex_unlock(&optee_private->tee_mutex);
+ return 0;
+err_core_init:
+ mtk_vcodec_dec_optee_deinit_hw_info(optee_private, MTK_VDEC_LAT0);
+err_lat_init:
+ tee_client_close_context(optee_private->tee_vdec_ctx);
+err_ctx_open:
+
+ mutex_unlock(&optee_private->tee_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_optee_open);
+
+void mtk_vcodec_dec_optee_release(struct mtk_vdec_optee_private *optee_private)
+{
+ mutex_lock(&optee_private->tee_mutex);
+ if (!atomic_dec_and_test(&optee_private->tee_active_cnt)) {
+ mutex_unlock(&optee_private->tee_mutex);
+ return;
+ }
+
+ mtk_vcodec_dec_optee_deinit_hw_info(optee_private, MTK_VDEC_LAT0);
+ if (IS_VDEC_LAT_ARCH(optee_private->vcodec_dev->vdec_pdata->hw_arch))
+ mtk_vcodec_dec_optee_deinit_hw_info(optee_private, MTK_VDEC_CORE);
+
+ tee_client_close_context(optee_private->tee_vdec_ctx);
+ mutex_unlock(&optee_private->tee_mutex);
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_optee_release);
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.h b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.h
new file mode 100644
index 000000000000..8b1dca49331e
--- /dev/null
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2023 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong@mediatek.com>
+ */
+
+#ifndef _MTK_VCODEC_DEC_OPTEE_H_
+#define _MTK_VCODEC_DEC_OPTEE_H_
+
+#include <linux/tee_drv.h>
+#include <linux/uuid.h>
+
+#include "mtk_vcodec_dec_drv.h"
+
+/* The TA ID implemented in this TA */
+#define MTK_VDEC_OPTEE_TA_LAT_SUBMIT_COMMAND (0x10)
+#define MTK_VDEC_OPTEE_TA_CORE_SUBMIT_COMMAND (0x20)
+
+#define MTK_OPTEE_MAX_TEE_PARAMS 4
+
+/**
+ * struct mtk_vdec_optee_ca_info - ca related param
+ * @vdec_session_id: optee TA session identifier.
+ * @hw_id: hardware index.
+ * @vdec_session_func: trusted application function id used specific to the TA.
+ */
+struct mtk_vdec_optee_ca_info {
+ u32 vdec_session_id;
+ enum mtk_vdec_hw_id hw_id;
+ u32 vdec_session_func;
+};
+
+/**
+ * struct mtk_vdec_optee_private - optee private data
+ * @vcodec_dev: pointer to the mtk_vcodec_dev of the device
+ * @tee_vdec_ctx: decoder TEE context handler.
+ * @lat_ca: lat hardware information used to communicate with TA.
+ * @core_ca: core hardware information used to communicate with TA.
+ *
+ * @tee_active_cnt: used to mark whether need to init optee
+ * @tee_mutex: mutex lock used for optee
+ */
+struct mtk_vdec_optee_private {
+ struct mtk_vcodec_dec_dev *vcodec_dev;
+ struct tee_context *tee_vdec_ctx;
+
+ struct mtk_vdec_optee_ca_info lat_ca;
+ struct mtk_vdec_optee_ca_info core_ca;
+
+ atomic_t tee_active_cnt;
+ /* mutext used to lock optee open and release information. */
+ struct mutex tee_mutex;
+};
+
+/**
+ * mtk_vcodec_dec_optee_open - setup the communication channels with TA.
+ * @optee_private: optee private context
+ */
+int mtk_vcodec_dec_optee_open(struct mtk_vdec_optee_private *optee_private);
+
+/**
+ * mtk_vcodec_dec_optee_private_init - init optee parameters.
+ * @vcodec_dev: pointer to the mtk_vcodec_dev of the device
+ */
+int mtk_vcodec_dec_optee_private_init(struct mtk_vcodec_dec_dev *vcodec_dev);
+
+/**
+ * mtk_vcodec_dec_optee_release - close the communication channels with TA.
+ * @optee_private: optee private context
+ */
+void mtk_vcodec_dec_optee_release(struct mtk_vdec_optee_private *optee_private);
+
+#endif /* _MTK_VCODEC_FW_OPTEE_H_ */
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,09/22] media: mediatek: vcodec: allocate tee share memory
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (7 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,08/22] media: mediatek: vcodec: add tee client interface to communiate with optee-os Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,10/22] media: mediatek: vcodec: send share memory data to optee Yunfei Dong
` (12 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
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 <yunfei.dong@mediatek.com>
---
.../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 = &ca_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;
+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 = &optee_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:
+ if (i != 0) {
+ for (j = 0; j < i; j++)
+ mtk_vcodec_dec_optee_deinit_memref(ca_info, j);
+ }
+
+ tee_client_close_session(optee_private->tee_vdec_ctx, ca_info->vdec_session_id);
+
return err;
}
@@ -94,12 +168,16 @@ static void mtk_vcodec_dec_optee_deinit_hw_info(struct mtk_vdec_optee_private *o
enum mtk_vdec_hw_id hw_id)
{
struct mtk_vdec_optee_ca_info *ca_info;
+ int i;
if (hw_id == MTK_VDEC_LAT0)
ca_info = &optee_private->lat_ca;
else
ca_info = &optee_private->core_ca;
+ for (i = 0; i < OPTEE_MAX_INDEX; i++)
+ mtk_vcodec_dec_optee_deinit_memref(ca_info, i);
+
tee_client_close_session(optee_private->tee_vdec_ctx, ca_info->vdec_session_id);
}
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.h b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.h
index 8b1dca49331e..24aa63af9887 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.h
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.h
@@ -18,16 +18,48 @@
#define MTK_OPTEE_MAX_TEE_PARAMS 4
+#define MTK_VDEC_OPTEE_MSG_SIZE 128
+#define MTK_VDEC_OPTEE_HW_SIZE (8 * SZ_1K)
+
+/**
+ * struct mtk_vdec_optee_shm_memref - share memory reference params
+ * @msg_shm: message shared with TA in TEE.
+ * @msg_shm_ca_buf: ca buffer.
+ *
+ * @msg_shm_size: share message size.
+ * @param_type: each tee param types.
+ * @copy_to_ta: need to copy data from ca to share memory.
+ */
+struct mtk_vdec_optee_shm_memref {
+ struct tee_shm *msg_shm;
+ u8 *msg_shm_ca_buf;
+
+ u32 msg_shm_size;
+ u64 param_type;
+ bool copy_to_ta;
+};
+
/**
* struct mtk_vdec_optee_ca_info - ca related param
* @vdec_session_id: optee TA session identifier.
* @hw_id: hardware index.
* @vdec_session_func: trusted application function id used specific to the TA.
+ * @shm_memref: share memory reference params.
*/
struct mtk_vdec_optee_ca_info {
u32 vdec_session_id;
enum mtk_vdec_hw_id hw_id;
u32 vdec_session_func;
+ struct mtk_vdec_optee_shm_memref shm_memref[MTK_OPTEE_MAX_TEE_PARAMS];
+};
+
+/*
+ * enum mtk_vdec_optee_data_index - used to indentify each share memory information
+ */
+enum mtk_vdec_optee_data_index {
+ OPTEE_MSG_INDEX = 0,
+ OPTEE_DATA_INDEX,
+ OPTEE_MAX_INDEX,
};
/**
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,10/22] media: mediatek: vcodec: send share memory data to optee
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (8 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,09/22] media: mediatek: vcodec: allocate tee share memory Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,11/22] media: mediatek: vcodec: initialize msg and vsi information Yunfei Dong
` (11 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
Setting msg and vsi information to shared buffer, then call tee invoke
function to send it to optee-os.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../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(&optee_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 = &optee_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 = &optee_private->lat_ca;
+ else
+ ca_info = &optee_private->core_ca;
+
+ memset(&trans_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 = &ca_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",
+ data->msg_buf_size[index], shm_memref->msg_shm_size);
+ return -EINVAL;
+ }
+
+ ret = mtk_vcodec_dec_optee_fill_shm(&command_params[index], shm_memref,
+ data, index, dev);
+ if (ret)
+ return ret;
+ }
+
+ ret = tee_client_invoke_func(optee_private->tee_vdec_ctx, &trans_args, command_params);
+ if (ret < 0 || trans_args.ret != 0) {
+ dev_err(dev, MTK_DBG_VCODEC_STR "tee submit command fail: 0x%x 0x%x.\n",
+ trans_args.ret, ret);
+ return (ret < 0) ? ret : trans_args.ret;
+ }
+
+ /* clear all attrs, set all command param to unused */
+ for (index = 0; index < MTK_OPTEE_MAX_TEE_PARAMS; index++) {
+ data->msg_buf[index] = NULL;
+ data->msg_buf_size[index] = 0;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_optee_invokd_cmd);
+
+void *mtk_vcodec_dec_get_shm_buffer_va(struct mtk_vdec_optee_private *optee_private,
+ enum mtk_vdec_hw_id hw_id,
+ enum mtk_vdec_optee_data_index data_index)
+{
+ struct mtk_vdec_optee_ca_info *ca_info;
+
+ if (hw_id == MTK_VDEC_LAT0)
+ ca_info = &optee_private->lat_ca;
+ else
+ ca_info = &optee_private->core_ca;
+
+ return ca_info->shm_memref[data_index].msg_shm_ca_buf;
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_get_shm_buffer_va);
+
+int mtk_vcodec_dec_get_shm_buffer_size(struct mtk_vdec_optee_private *optee_private,
+ enum mtk_vdec_hw_id hw_id,
+ enum mtk_vdec_optee_data_index data_index)
+{
+ struct mtk_vdec_optee_ca_info *ca_info;
+
+ if (hw_id == MTK_VDEC_LAT0)
+ ca_info = &optee_private->lat_ca;
+ else
+ ca_info = &optee_private->core_ca;
+
+ return ca_info->shm_memref[data_index].msg_shm_size;
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_get_shm_buffer_size);
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.h b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.h
index 24aa63af9887..c24a567ec877 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.h
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_optee.h
@@ -62,6 +62,16 @@ enum mtk_vdec_optee_data_index {
OPTEE_MAX_INDEX,
};
+/**
+ * struct mtk_vdec_optee_data_to_shm - shm data used for TA
+ * @msg_buf: msg information to TA.
+ * @msg_buf_len: length of msg information.
+ */
+struct mtk_vdec_optee_data_to_shm {
+ void *msg_buf[MTK_OPTEE_MAX_TEE_PARAMS];
+ int msg_buf_size[MTK_OPTEE_MAX_TEE_PARAMS];
+};
+
/**
* struct mtk_vdec_optee_private - optee private data
* @vcodec_dev: pointer to the mtk_vcodec_dev of the device
@@ -102,4 +112,45 @@ int mtk_vcodec_dec_optee_private_init(struct mtk_vcodec_dec_dev *vcodec_dev);
*/
void mtk_vcodec_dec_optee_release(struct mtk_vdec_optee_private *optee_private);
+/**
+ * mtk_vcodec_dec_optee_set_data - set buffer to share memref.
+ * @vcodec_dev: normal world data used to init optee share memory
+ * @buf: normal world buffer address
+ * @buf_size: buf size
+ * @data_index: indentify each share memory informaiton
+ */
+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 data_index);
+
+/**
+ * mtk_vcodec_dec_optee_invokd_cmd - send share memory data to optee .
+ * @optee_private: optee private context
+ * @hw_id: hardware index
+ * @data: normal world data used to init optee share memory
+ */
+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);
+
+/**
+ * mtk_vcodec_dec_get_shm_buffer_va - close the communication channels with TA.
+ * @optee_private: optee private context
+ * @hw_id: hardware index
+ * @@data_index: indentify each share memory informaiton
+ */
+void *mtk_vcodec_dec_get_shm_buffer_va(struct mtk_vdec_optee_private *optee_private,
+ enum mtk_vdec_hw_id hw_id,
+ enum mtk_vdec_optee_data_index data_index);
+
+/**
+ * mtk_vcodec_dec_get_shm_buffer_size - close the communication channels with TA.
+ * @optee_private: optee private context
+ * @hw_id: hardware index
+ * @@data_index: indentify each share memory informaiton
+ */
+int mtk_vcodec_dec_get_shm_buffer_size(struct mtk_vdec_optee_private *optee_private,
+ enum mtk_vdec_hw_id hw_id,
+ enum mtk_vdec_optee_data_index data_index);
+
#endif /* _MTK_VCODEC_FW_OPTEE_H_ */
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,11/22] media: mediatek: vcodec: initialize msg and vsi information
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (9 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,10/22] media: mediatek: vcodec: send share memory data to optee Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,12/22] media: mediatek: vcodec: add interface to allocate/free secure memory Yunfei Dong
` (10 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
Need to initialize msg and vsi information before sending to optee-os, then
calling optee invoke command to send the information to optee-os.
For the optee communication interface is different with scp, using
flag to separate them.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../vcodec/decoder/mtk_vcodec_dec_drv.h | 2 +
.../mediatek/vcodec/decoder/vdec_vpu_if.c | 49 ++++++++++++++++---
.../mediatek/vcodec/decoder/vdec_vpu_if.h | 4 ++
3 files changed, 49 insertions(+), 6 deletions(-)
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 b1a2107f2a1e..47eca245dc07 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
@@ -175,6 +175,7 @@ struct mtk_vcodec_dec_pdata {
* @vpu_inst: vpu instance pointer.
*
* @is_10bit_bitstream: set to true if it's 10bit bitstream
+ * @is_secure_playback: Secure Video Playback (SVP) mode
*/
struct mtk_vcodec_dec_ctx {
enum mtk_instance_type type;
@@ -220,6 +221,7 @@ struct mtk_vcodec_dec_ctx {
void *vpu_inst;
bool is_10bit_bitstream;
+ bool is_secure_playback;
};
/**
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
index 82e57ae983d5..5336769a3fb5 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
@@ -148,7 +148,10 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len)
{
- int err, id, msgid;
+ struct mtk_vdec_optee_data_to_shm *optee_data;
+ int data_size, id, hw_id, msgid;
+ void *ack_msg, *data_msg;
+ int err;
msgid = *(uint32_t *)msg;
mtk_vdec_debug(vpu->ctx, "id=%X", msgid);
@@ -158,16 +161,46 @@ static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len)
if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) {
if (msgid == AP_IPIMSG_DEC_CORE ||
- msgid == AP_IPIMSG_DEC_CORE_END)
+ msgid == AP_IPIMSG_DEC_CORE_END) {
+ optee_data = &vpu->core_optee_info;
id = vpu->core_id;
- else
+ } else {
+ optee_data = &vpu->lat_optee_info;
id = vpu->id;
+ }
} else {
+ optee_data = &vpu->lat_optee_info;
id = vpu->id;
}
- err = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, id, msg,
- len, 2000);
+ if (!vpu->ctx->is_secure_playback) {
+ err = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, id, msg, len, 2000);
+ } else {
+ hw_id = (id == SCP_IPI_VDEC_LAT) ? MTK_VDEC_LAT0 : MTK_VDEC_CORE;
+
+ mtk_vcodec_dec_optee_set_data(optee_data, msg, len, OPTEE_MSG_INDEX);
+
+ /* There is no need to copy the data (VSI) message to shared memory,
+ * but we still need to set the buffer size to a non-zero value.
+ */
+ if (msgid == AP_IPIMSG_DEC_CORE || msgid == AP_IPIMSG_DEC_START) {
+ data_msg = mtk_vcodec_dec_get_shm_buffer_va(vpu->ctx->dev->optee_private,
+ hw_id, OPTEE_DATA_INDEX);
+ data_size = mtk_vcodec_dec_get_shm_buffer_size(vpu->ctx->dev->optee_private,
+ hw_id, OPTEE_DATA_INDEX);
+ mtk_vcodec_dec_optee_set_data(optee_data, data_msg, data_size,
+ OPTEE_DATA_INDEX);
+ }
+
+ err = mtk_vcodec_dec_optee_invokd_cmd(vpu->ctx->dev->optee_private,
+ hw_id, optee_data);
+ vpu->failure = err;
+
+ ack_msg = mtk_vcodec_dec_get_shm_buffer_va(vpu->ctx->dev->optee_private, hw_id,
+ OPTEE_MSG_INDEX);
+ vpu_dec_ipi_handler(ack_msg, 0, vpu->ctx->dev);
+ }
+
if (err) {
mtk_vdec_err(vpu->ctx, "send fail vpu_id=%d msg_id=%X status=%d",
id, msgid, err);
@@ -213,7 +246,11 @@ int vpu_dec_init(struct vdec_vpu_inst *vpu)
return err;
}
- if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) {
+ /* Using tee interface to communicate with optee os directly for SVP mode,
+ * fw ipi interface is used for normal playback.
+ */
+ if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE &&
+ !vpu->ctx->is_secure_playback) {
err = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler,
vpu->core_id, vpu->handler,
"vdec", vpu->ctx->dev);
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.h b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.h
index fbb3f34a73f0..946e5abcc7d3 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.h
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.h
@@ -28,6 +28,8 @@ struct mtk_vcodec_dec_ctx;
* @codec_type : use codec type to separate different codecs
* @capture_type: used capture type to separate different capture format
* @fb_sz : frame buffer size of each plane
+ * @lat_optee_info : used to send msg to optee shm buffer
+ * @core_optee_info : used to send msg to optee shm buffer
*/
struct vdec_vpu_inst {
int id;
@@ -44,6 +46,8 @@ struct vdec_vpu_inst {
unsigned int codec_type;
unsigned int capture_type;
unsigned int fb_sz[2];
+ struct mtk_vdec_optee_data_to_shm lat_optee_info;
+ struct mtk_vdec_optee_data_to_shm core_optee_info;
};
/**
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,12/22] media: mediatek: vcodec: add interface to allocate/free secure memory
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (10 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,11/22] media: mediatek: vcodec: initialize msg and vsi information Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,13/22] media: mediatek: vcodec: using shared memory as vsi address Yunfei Dong
` (9 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
Need to call dma heap interface to allocate/free secure memory when playing
secure video.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../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 9ce34a3b5ee6..5cb7c347322b 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 <tiffany.lin@mediatek.com>
*/
+#include <linux/dma-heap.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regmap.h>
+#include <uapi/linux/dma-heap.h>
#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;
@@ -76,9 +78,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 = &ctx->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_cm");
+ 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;
@@ -111,6 +175,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);
+ dma_buf_detach((struct dma_buf *)mem->va, mem->attach);
+ dma_buf_put((struct dma_buf *)mem->va);
+
+ mem->attach = NULL;
+ mem->sgt = NULL;
+ mem->va = NULL;
+ mem->dma_addr = 0;
+ mem->size = 0;
+}
+
+int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem)
+{
+ enum mtk_instance_type inst_type = *((unsigned int *)priv);
+ int ret;
+
+ if (inst_type == MTK_INST_DECODER) {
+ struct mtk_vcodec_dec_ctx *dec_ctx = priv;
+
+ if (dec_ctx->is_secure_playback) {
+ ret = mtk_vcodec_mem_alloc_sec(dec_ctx, mem);
+ goto alloc_end;
+ }
+ }
+
+ ret = mtk_vcodec_mem_alloc_nor(priv, mem);
+alloc_end:
+
+ return ret;
+}
+EXPORT_SYMBOL(mtk_vcodec_mem_alloc);
+
+void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem)
+{
+ enum mtk_instance_type inst_type = *((unsigned int *)priv);
+
+ if (inst_type == MTK_INST_DECODER) {
+ struct mtk_vcodec_dec_ctx *dec_ctx = priv;
+
+ if (dec_ctx->is_secure_playback) {
+ mtk_vcodec_mem_free_sec(mem);
+ return;
+ }
+ }
+
+ mtk_vcodec_mem_free_nor(priv, mem);
+}
EXPORT_SYMBOL(mtk_vcodec_mem_free);
void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dec_dev *dev, int hw_idx)
@@ -172,3 +287,4 @@ EXPORT_SYMBOL(mtk_vcodec_get_curr_ctx);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Mediatek video codec driver");
+MODULE_IMPORT_NS(DMA_BUF);
diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h
index 85f615cdd4d3..22078e757ed0 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h
@@ -18,6 +18,9 @@ struct mtk_vcodec_mem {
size_t size;
void *va;
dma_addr_t dma_addr;
+
+ struct dma_buf_attachment *attach;
+ struct sg_table *sgt;
};
struct mtk_vcodec_fb {
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,13/22] media: mediatek: vcodec: using shared memory as vsi address
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (11 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,12/22] media: mediatek: vcodec: add interface to allocate/free secure memory Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,14/22] media: mediatek: vcodec: Add capture format to support one plane memory Yunfei Dong
` (8 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
The vsi buffer is allocated by tee share memory for svp mode, need to
use the share memory as the vsi address to store vsi data.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../vcodec/decoder/vdec/vdec_h264_req_multi_if.c | 9 +++++++--
.../media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c | 8 ++++++--
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
index 0e741e0dc8ba..4967e0f0984d 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
@@ -417,8 +417,13 @@ static int vdec_h264_slice_init(struct mtk_vcodec_dec_ctx *ctx)
vsi_size = round_up(sizeof(struct vdec_h264_slice_vsi), VCODEC_DEC_ALIGNED_64);
inst->vsi = inst->vpu.vsi;
- inst->vsi_core =
- (struct vdec_h264_slice_vsi *)(((char *)inst->vpu.vsi) + vsi_size);
+ if (ctx->is_secure_playback)
+ inst->vsi_core =
+ mtk_vcodec_dec_get_shm_buffer_va(ctx->dev->optee_private, MTK_VDEC_CORE,
+ OPTEE_DATA_INDEX);
+ else
+ inst->vsi_core =
+ (struct vdec_h264_slice_vsi *)(((char *)inst->vpu.vsi) + vsi_size);
inst->resolution_changed = true;
inst->realloc_mv_buf = true;
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
index 5336769a3fb5..5c31641e9abe 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
@@ -18,8 +18,12 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg)
/* mapping VPU address to kernel virtual address */
/* the content in vsi is initialized to 0 in VPU */
- vpu->vsi = mtk_vcodec_fw_map_dm_addr(vpu->ctx->dev->fw_handler,
- msg->vpu_inst_addr);
+ if (vpu->ctx->is_secure_playback)
+ vpu->vsi = mtk_vcodec_dec_get_shm_buffer_va(vpu->ctx->dev->optee_private,
+ MTK_VDEC_LAT0, OPTEE_DATA_INDEX);
+ else
+ vpu->vsi = mtk_vcodec_fw_map_dm_addr(vpu->ctx->dev->fw_handler,
+ msg->vpu_inst_addr);
vpu->inst_addr = msg->vpu_inst_addr;
mtk_vdec_debug(vpu->ctx, "- vpu_inst_addr = 0x%x", vpu->inst_addr);
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,14/22] media: mediatek: vcodec: Add capture format to support one plane memory
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (12 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,13/22] media: mediatek: vcodec: using shared memory as vsi address Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,15/22] media: mediatek: vcodec: Add one plane format Yunfei Dong
` (7 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
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 <yunfei.dong@mediatek.com>
---
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
+ memory. Luma pixel in 16x32 tiles at the start, chroma pixel in 16x16
+ tiles at the end. The image height must be aligned with 32 and the image
+ width must be aligned with 16.
.. raw:: latex
\normalsize
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 273d83de2a87..315b906ed730 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -269,6 +269,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 33076af4dfdb..c38b12511bdb 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1511,6 +1511,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;
default:
if (fmt->description[0])
return;
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 3e3f8d4b7c81..53a3c908fcba 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -798,6 +798,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 */
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,15/22] media: mediatek: vcodec: Add one plane format
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (13 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,14/22] media: mediatek: vcodec: Add capture format to support one plane memory Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,16/22] media: mediatek: vcodec: support one plane capture buffer Yunfei Dong
` (6 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
Adding capture formats to support V4L2_PIX_FMT_MS21. This format has
one plane and only be used for secure video playback at current period.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c | 4 +++-
.../mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c | 9 ++++++++-
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c
index ba742f0e391d..604fdc8ee3ce 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c
@@ -49,7 +49,9 @@ static bool mtk_vdec_get_cap_fmt(struct mtk_vcodec_dec_ctx *ctx, int format_inde
num_frame_count++;
}
- if (num_frame_count == 1 || (!ctx->is_10bit_bitstream && fmt->fourcc == V4L2_PIX_FMT_MM21))
+ if ((!ctx->is_10bit_bitstream && fmt->fourcc == V4L2_PIX_FMT_MM21) ||
+ (ctx->is_secure_playback && fmt->fourcc == V4L2_PIX_FMT_MS21) ||
+ num_frame_count == 1)
return true;
q_data = &ctx->q_data[MTK_Q_DATA_SRC];
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
index d54b3833790d..cc42c942eb8a 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
@@ -229,7 +229,7 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = {
#define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
-static struct mtk_video_fmt mtk_video_formats[9];
+static struct mtk_video_fmt mtk_video_formats[10];
static struct mtk_video_fmt default_out_format;
static struct mtk_video_fmt default_cap_format;
@@ -770,6 +770,11 @@ static void mtk_vcodec_add_formats(unsigned int fourcc,
mtk_video_formats[count_formats].type = MTK_FMT_FRAME;
mtk_video_formats[count_formats].num_planes = 2;
break;
+ case V4L2_PIX_FMT_MS21:
+ mtk_video_formats[count_formats].fourcc = fourcc;
+ mtk_video_formats[count_formats].type = MTK_FMT_FRAME;
+ mtk_video_formats[count_formats].num_planes = 1;
+ break;
default:
mtk_v4l2_vdec_err(ctx, "Can not add unsupported format type");
return;
@@ -798,6 +803,8 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_dec_ctx *ctx)
cap_format_count++;
}
if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_MM21) {
+ mtk_vcodec_add_formats(V4L2_PIX_FMT_MS21, ctx);
+ cap_format_count++;
mtk_vcodec_add_formats(V4L2_PIX_FMT_MM21, ctx);
cap_format_count++;
}
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,16/22] media: mediatek: vcodec: support one plane capture buffer
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (14 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,15/22] media: mediatek: vcodec: Add one plane format Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,17/22] media: mediatek: vcodec: re-construct h264 driver to support svp mode Yunfei Dong
` (5 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
The capture buffer has two planes for format MM21, but user space only
allocate secure memory for plane[0], and the size is Y data + uv data.
The driver need to support one plane decoder for svp mode.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../mediatek/vcodec/decoder/mtk_vcodec_dec.c | 7 ++++-
.../vcodec/decoder/mtk_vcodec_dec_stateless.c | 26 ++++++++++---------
.../decoder/vdec/vdec_h264_req_common.c | 18 ++++++-------
.../mediatek/vcodec/decoder/vdec_drv_if.c | 4 +--
4 files changed, 31 insertions(+), 24 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c
index 604fdc8ee3ce..5d876a31e566 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c
@@ -653,7 +653,12 @@ static int vidioc_vdec_g_fmt(struct file *file, void *priv,
* So we just return picinfo yet, and update picinfo in
* stop_streaming hook function
*/
- q_data->sizeimage[0] = ctx->picinfo.fb_sz[0];
+
+ if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1 || ctx->is_secure_playback)
+ q_data->sizeimage[0] = ctx->picinfo.fb_sz[0] + ctx->picinfo.fb_sz[1];
+ else
+ q_data->sizeimage[0] = ctx->picinfo.fb_sz[0];
+
q_data->sizeimage[1] = ctx->picinfo.fb_sz[1];
q_data->bytesperline[0] = ctx->last_decoded_picinfo.buf_w;
q_data->bytesperline[1] = ctx->last_decoded_picinfo.buf_w;
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
index cc42c942eb8a..707ed57a412e 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
@@ -285,14 +285,14 @@ static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_dec_ctx *ctx)
framebuf = container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
pfb = &framebuf->frame_buffer;
- pfb->base_y.va = vb2_plane_vaddr(dst_buf, 0);
+ if (!ctx->is_secure_playback)
+ pfb->base_y.va = vb2_plane_vaddr(dst_buf, 0);
pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
pfb->base_y.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
- if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
+ if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2 && !ctx->is_secure_playback) {
pfb->base_c.va = vb2_plane_vaddr(dst_buf, 1);
- pfb->base_c.dma_addr =
- vb2_dma_contig_plane_dma_addr(dst_buf, 1);
+ pfb->base_c.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 1);
pfb->base_c.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
}
mtk_v4l2_vdec_dbg(1, ctx,
@@ -339,16 +339,18 @@ static void mtk_vdec_worker(struct work_struct *work)
mtk_v4l2_vdec_dbg(3, ctx, "[%d] (%d) id=%d, vb=%p", ctx->id,
vb2_src->vb2_queue->type, vb2_src->index, vb2_src);
- bs_src->va = vb2_plane_vaddr(vb2_src, 0);
- bs_src->dma_addr = vb2_dma_contig_plane_dma_addr(vb2_src, 0);
- bs_src->size = (size_t)vb2_src->planes[0].bytesused;
- if (!bs_src->va) {
- v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
- mtk_v4l2_vdec_err(ctx, "[%d] id=%d source buffer is NULL", ctx->id,
- vb2_src->index);
- return;
+ if (!ctx->is_secure_playback) {
+ bs_src->va = vb2_plane_vaddr(vb2_src, 0);
+ if (!bs_src->va) {
+ v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+ mtk_v4l2_vdec_err(ctx, "[%d] id=%d source buffer is NULL", ctx->id,
+ vb2_src->index);
+ return;
+ }
}
+ bs_src->dma_addr = vb2_dma_contig_plane_dma_addr(vb2_src, 0);
+ bs_src->size = (size_t)vb2_src->planes[0].bytesused;
mtk_v4l2_vdec_dbg(3, ctx, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p",
ctx->id, bs_src->va, &bs_src->dma_addr, bs_src->size, vb2_src);
/* Apply request controls. */
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_common.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_common.c
index 5ca20d75dc8e..5e0d55218363 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_common.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_common.c
@@ -79,15 +79,15 @@ void mtk_vdec_h264_fill_dpb_info(struct mtk_vcodec_dec_ctx *ctx,
vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
h264_dpb_info[index].field = vb2_v4l2->field;
- h264_dpb_info[index].y_dma_addr =
- vb2_dma_contig_plane_dma_addr(vb, 0);
- if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
- h264_dpb_info[index].c_dma_addr =
- vb2_dma_contig_plane_dma_addr(vb, 1);
- else
- h264_dpb_info[index].c_dma_addr =
- h264_dpb_info[index].y_dma_addr +
- ctx->picinfo.fb_sz[0];
+ h264_dpb_info[index].y_dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+ if (!ctx->is_secure_playback) {
+ if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
+ h264_dpb_info[index].c_dma_addr =
+ vb2_dma_contig_plane_dma_addr(vb, 1);
+ else
+ h264_dpb_info[index].c_dma_addr =
+ h264_dpb_info[index].y_dma_addr + ctx->picinfo.fb_sz[0];
+ }
}
}
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec_drv_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec_drv_if.c
index d0b459b1603f..fb3e4f75ed93 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec_drv_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_drv_if.c
@@ -73,14 +73,14 @@ int vdec_if_decode(struct mtk_vcodec_dec_ctx *ctx, struct mtk_vcodec_mem *bs,
{
int ret = 0;
- if (bs) {
+ if (bs && !ctx->is_secure_playback) {
if ((bs->dma_addr & 63) != 0) {
mtk_v4l2_vdec_err(ctx, "bs dma_addr should 64 byte align");
return -EINVAL;
}
}
- if (fb) {
+ if (fb && !ctx->is_secure_playback) {
if (((fb->base_y.dma_addr & 511) != 0) ||
((fb->base_c.dma_addr & 511) != 0)) {
mtk_v4l2_vdec_err(ctx, "frame buffer dma_addr should 512 byte align");
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,17/22] media: mediatek: vcodec: re-construct h264 driver to support svp mode
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (15 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,16/22] media: mediatek: vcodec: support one plane capture buffer Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,18/22] media: mediatek: vcodec: remove parse nal_info in kernel Yunfei Dong
` (4 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
Need secure buffer size to convert secure handle to secure
pa in optee-os, re-construct the vsi struct to store each
secure buffer size.
Separate svp and normal wait interrupt condition for svp mode
waiting hardware interrupt in optee-os.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../decoder/vdec/vdec_h264_req_multi_if.c | 261 +++++++++++-------
.../mediatek/vcodec/decoder/vdec_msg_queue.c | 9 +-
2 files changed, 168 insertions(+), 102 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
index 4967e0f0984d..a1a68487131c 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
@@ -60,14 +60,36 @@ struct vdec_h264_slice_lat_dec_param {
* @crc: Used to check whether hardware's status is right
*/
struct vdec_h264_slice_info {
+ u64 wdma_end_addr_offset;
u16 nal_info;
u16 timeout;
- u32 bs_buf_size;
- u64 bs_buf_addr;
- u64 y_fb_dma;
- u64 c_fb_dma;
u64 vdec_fb_va;
u32 crc[8];
+ u32 reserved;
+};
+
+/*
+ * struct vdec_h264_slice_mem - memory address and size
+ */
+struct vdec_h264_slice_mem {
+ union {
+ u64 buf;
+ u64 dma_addr;
+ };
+ union {
+ size_t size;
+ u64 dma_addr_end;
+ };
+};
+
+/**
+ * struct vdec_h264_slice_fb - frame buffer for decoding
+ * @y: current y buffer address info
+ * @c: current c buffer address info
+ */
+struct vdec_h264_slice_fb {
+ struct vdec_h264_slice_mem y;
+ struct vdec_h264_slice_mem c;
};
/**
@@ -92,18 +114,16 @@ struct vdec_h264_slice_info {
*/
struct vdec_h264_slice_vsi {
/* LAT dec addr */
- u64 wdma_err_addr;
- u64 wdma_start_addr;
- u64 wdma_end_addr;
- u64 slice_bc_start_addr;
- u64 slice_bc_end_addr;
- u64 row_info_start_addr;
- u64 row_info_end_addr;
- u64 trans_start;
- u64 trans_end;
- u64 wdma_end_addr_offset;
+ struct vdec_h264_slice_mem bs;
+ struct vdec_h264_slice_fb fb;
- u64 mv_buf_dma[H264_MAX_MV_NUM];
+ struct vdec_h264_slice_mem ube;
+ struct vdec_h264_slice_mem trans;
+ struct vdec_h264_slice_mem row_info;
+ struct vdec_h264_slice_mem err_map;
+ struct vdec_h264_slice_mem slice_bc;
+
+ struct vdec_h264_slice_mem mv_buf_dma[H264_MAX_MV_NUM];
struct vdec_h264_slice_info dec;
struct vdec_h264_slice_lat_dec_param h264_slice_params;
};
@@ -392,6 +412,100 @@ static void vdec_h264_slice_get_crop_info(struct vdec_h264_slice_inst *inst,
cr->left, cr->top, cr->width, cr->height);
}
+static void vdec_h264_slice_setup_lat_buffer(struct vdec_h264_slice_inst *inst,
+ struct mtk_vcodec_mem *bs,
+ struct vdec_lat_buf *lat_buf)
+{
+ struct mtk_vcodec_mem *mem;
+ int i;
+
+ inst->vsi->bs.dma_addr = (u64)bs->dma_addr;
+ inst->vsi->bs.size = bs->size;
+
+ for (i = 0; i < H264_MAX_MV_NUM; i++) {
+ mem = &inst->mv_buf[i];
+ inst->vsi->mv_buf_dma[i].dma_addr = mem->dma_addr;
+ inst->vsi->mv_buf_dma[i].size = mem->size;
+ }
+ inst->vsi->ube.dma_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr;
+ inst->vsi->ube.size = lat_buf->ctx->msg_queue.wdma_addr.size;
+
+ inst->vsi->row_info.dma_addr = 0;
+ inst->vsi->row_info.size = 0;
+
+ inst->vsi->err_map.dma_addr = lat_buf->wdma_err_addr.dma_addr;
+ inst->vsi->err_map.size = lat_buf->wdma_err_addr.size;
+
+ inst->vsi->slice_bc.dma_addr = lat_buf->slice_bc_addr.dma_addr;
+ inst->vsi->slice_bc.size = lat_buf->slice_bc_addr.size;
+
+ inst->vsi->trans.dma_addr_end = inst->ctx->msg_queue.wdma_rptr_addr;
+ inst->vsi->trans.dma_addr = inst->ctx->msg_queue.wdma_wptr_addr;
+}
+
+static int vdec_h264_slice_setup_core_buffer(struct vdec_h264_slice_inst *inst,
+ struct vdec_h264_slice_share_info *share_info,
+ struct vdec_lat_buf *lat_buf)
+{
+ struct mtk_vcodec_mem *mem;
+ struct mtk_vcodec_dec_ctx *ctx = inst->ctx;
+ struct vb2_v4l2_buffer *vb2_v4l2;
+ struct vdec_fb *fb;
+ u64 y_fb_dma, c_fb_dma = 0;
+ int i;
+
+ fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx);
+ if (!fb) {
+ mtk_vdec_err(ctx, "fb buffer is NULL");
+ return -EBUSY;
+ }
+
+ y_fb_dma = (u64)fb->base_y.dma_addr;
+ if (!ctx->is_secure_playback) {
+ if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
+ c_fb_dma =
+ y_fb_dma + inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;
+ else
+ c_fb_dma = (u64)fb->base_c.dma_addr;
+ }
+
+ mtk_vdec_debug(ctx, "[h264-core] y/c addr = 0x%llx 0x%llx", y_fb_dma, c_fb_dma);
+
+ inst->vsi_core->fb.y.dma_addr = y_fb_dma;
+ inst->vsi_core->fb.y.size = ctx->picinfo.fb_sz[0];
+ inst->vsi_core->fb.c.dma_addr = c_fb_dma;
+ inst->vsi_core->fb.c.size = ctx->picinfo.fb_sz[1];
+
+ inst->vsi_core->dec.vdec_fb_va = (unsigned long)fb;
+ inst->vsi_core->dec.nal_info = share_info->nal_info;
+
+ inst->vsi_core->ube.dma_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr;
+ inst->vsi_core->ube.size = lat_buf->ctx->msg_queue.wdma_addr.size;
+
+ inst->vsi_core->err_map.dma_addr = lat_buf->wdma_err_addr.dma_addr;
+ inst->vsi_core->err_map.size = lat_buf->wdma_err_addr.size;
+
+ inst->vsi_core->slice_bc.dma_addr = lat_buf->slice_bc_addr.dma_addr;
+ inst->vsi_core->slice_bc.size = lat_buf->slice_bc_addr.size;
+
+ inst->vsi_core->row_info.dma_addr = 0;
+ inst->vsi_core->row_info.size = 0;
+
+ inst->vsi_core->trans.dma_addr = share_info->trans_start;
+ inst->vsi_core->trans.dma_addr_end = share_info->trans_end;
+
+ for (i = 0; i < H264_MAX_MV_NUM; i++) {
+ mem = &inst->mv_buf[i];
+ inst->vsi_core->mv_buf_dma[i].dma_addr = mem->dma_addr;
+ inst->vsi_core->mv_buf_dma[i].size = mem->size;
+ }
+
+ vb2_v4l2 = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+ v4l2_m2m_buf_copy_metadata(&lat_buf->ts_info, vb2_v4l2, true);
+
+ return 0;
+}
+
static int vdec_h264_slice_init(struct mtk_vcodec_dec_ctx *ctx)
{
struct vdec_h264_slice_inst *inst;
@@ -457,64 +571,22 @@ static void vdec_h264_slice_deinit(void *h_vdec)
static int vdec_h264_slice_core_decode(struct vdec_lat_buf *lat_buf)
{
- struct vdec_fb *fb;
- u64 vdec_fb_va;
- u64 y_fb_dma, c_fb_dma;
- int err, timeout, i;
+ int err, timeout;
struct mtk_vcodec_dec_ctx *ctx = lat_buf->ctx;
struct vdec_h264_slice_inst *inst = ctx->drv_handle;
- struct vb2_v4l2_buffer *vb2_v4l2;
struct vdec_h264_slice_share_info *share_info = lat_buf->private_data;
- struct mtk_vcodec_mem *mem;
struct vdec_vpu_inst *vpu = &inst->vpu;
mtk_vdec_debug(ctx, "[h264-core] vdec_h264 core decode");
memcpy(&inst->vsi_core->h264_slice_params, &share_info->h264_slice_params,
sizeof(share_info->h264_slice_params));
- fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx);
- if (!fb) {
- err = -EBUSY;
- mtk_vdec_err(ctx, "fb buffer is NULL");
+ err = vdec_h264_slice_setup_core_buffer(inst, share_info, lat_buf);
+ if (err)
goto vdec_dec_end;
- }
-
- vdec_fb_va = (unsigned long)fb;
- y_fb_dma = (u64)fb->base_y.dma_addr;
- if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
- c_fb_dma =
- y_fb_dma + inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;
- else
- c_fb_dma = (u64)fb->base_c.dma_addr;
-
- mtk_vdec_debug(ctx, "[h264-core] y/c addr = 0x%llx 0x%llx", y_fb_dma, c_fb_dma);
-
- inst->vsi_core->dec.y_fb_dma = y_fb_dma;
- inst->vsi_core->dec.c_fb_dma = c_fb_dma;
- inst->vsi_core->dec.vdec_fb_va = vdec_fb_va;
- inst->vsi_core->dec.nal_info = share_info->nal_info;
- inst->vsi_core->wdma_start_addr =
- lat_buf->ctx->msg_queue.wdma_addr.dma_addr;
- inst->vsi_core->wdma_end_addr =
- lat_buf->ctx->msg_queue.wdma_addr.dma_addr +
- lat_buf->ctx->msg_queue.wdma_addr.size;
- inst->vsi_core->wdma_err_addr = lat_buf->wdma_err_addr.dma_addr;
- inst->vsi_core->slice_bc_start_addr = lat_buf->slice_bc_addr.dma_addr;
- inst->vsi_core->slice_bc_end_addr = lat_buf->slice_bc_addr.dma_addr +
- lat_buf->slice_bc_addr.size;
- inst->vsi_core->trans_start = share_info->trans_start;
- inst->vsi_core->trans_end = share_info->trans_end;
- for (i = 0; i < H264_MAX_MV_NUM; i++) {
- mem = &inst->mv_buf[i];
- inst->vsi_core->mv_buf_dma[i] = mem->dma_addr;
- }
-
- vb2_v4l2 = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
- v4l2_m2m_buf_copy_metadata(&lat_buf->ts_info, vb2_v4l2, true);
vdec_h264_slice_fill_decode_reflist(inst, &inst->vsi_core->h264_slice_params,
share_info);
-
err = vpu_dec_core(vpu);
if (err) {
mtk_vdec_err(ctx, "core decode err=%d", err);
@@ -573,12 +645,11 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
struct vdec_h264_slice_inst *inst = h_vdec;
struct vdec_vpu_inst *vpu = &inst->vpu;
struct mtk_video_dec_buf *src_buf_info;
- int nal_start_idx, err, timeout = 0, i;
+ int nal_start_idx, err, timeout = 0;
unsigned int data[2];
struct vdec_lat_buf *lat_buf;
struct vdec_h264_slice_share_info *share_info;
unsigned char *buf;
- struct mtk_vcodec_mem *mem;
if (vdec_msg_queue_init(&inst->ctx->msg_queue, inst->ctx,
vdec_h264_slice_core_decode,
@@ -617,11 +688,9 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
if (err)
goto err_free_fb_out;
- vdec_h264_insert_startcode(inst->ctx->dev, buf, &bs->size,
- &share_info->h264_slice_params.pps);
-
- inst->vsi->dec.bs_buf_addr = (uint64_t)bs->dma_addr;
- inst->vsi->dec.bs_buf_size = bs->size;
+ if (!inst->ctx->is_secure_playback)
+ vdec_h264_insert_startcode(inst->ctx->dev, buf, &bs->size,
+ &share_info->h264_slice_params.pps);
*res_chg = inst->resolution_changed;
if (inst->resolution_changed) {
@@ -634,38 +703,27 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
}
inst->resolution_changed = false;
}
- for (i = 0; i < H264_MAX_MV_NUM; i++) {
- mem = &inst->mv_buf[i];
- inst->vsi->mv_buf_dma[i] = mem->dma_addr;
- }
- inst->vsi->wdma_start_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr;
- inst->vsi->wdma_end_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr +
- lat_buf->ctx->msg_queue.wdma_addr.size;
- inst->vsi->wdma_err_addr = lat_buf->wdma_err_addr.dma_addr;
- inst->vsi->slice_bc_start_addr = lat_buf->slice_bc_addr.dma_addr;
- inst->vsi->slice_bc_end_addr = lat_buf->slice_bc_addr.dma_addr +
- lat_buf->slice_bc_addr.size;
-
- inst->vsi->trans_end = inst->ctx->msg_queue.wdma_rptr_addr;
- inst->vsi->trans_start = inst->ctx->msg_queue.wdma_wptr_addr;
- mtk_vdec_debug(inst->ctx, "lat:trans(0x%llx 0x%llx) err:0x%llx",
- inst->vsi->wdma_start_addr,
- inst->vsi->wdma_end_addr,
- inst->vsi->wdma_err_addr);
-
- mtk_vdec_debug(inst->ctx, "slice(0x%llx 0x%llx) rprt((0x%llx 0x%llx))",
- inst->vsi->slice_bc_start_addr,
- inst->vsi->slice_bc_end_addr,
- inst->vsi->trans_start,
- inst->vsi->trans_end);
+
+ vdec_h264_slice_setup_lat_buffer(inst, bs, lat_buf);
+ mtk_vdec_debug(inst->ctx, "lat:trans(0x%llx 0x%lx) err:0x%llx",
+ inst->vsi->ube.dma_addr, (unsigned long)inst->vsi->ube.size,
+ inst->vsi->err_map.dma_addr);
+
+ mtk_vdec_debug(inst->ctx, "slice(0x%llx 0x%lx) rprt((0x%llx 0x%llx))",
+ inst->vsi->slice_bc.dma_addr, (unsigned long)inst->vsi->slice_bc.size,
+ inst->vsi->trans.dma_addr, inst->vsi->trans.dma_addr_end);
err = vpu_dec_start(vpu, data, 2);
if (err) {
mtk_vdec_debug(inst->ctx, "lat decode err: %d", err);
goto err_free_fb_out;
}
- share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
- inst->vsi->wdma_end_addr_offset;
+ if (inst->ctx->is_secure_playback)
+ share_info->trans_end = inst->vsi->dec.wdma_end_addr_offset;
+ else
+ share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
+ inst->vsi->dec.wdma_end_addr_offset;
+
share_info->trans_start = inst->ctx->msg_queue.wdma_wptr_addr;
share_info->nal_info = inst->vsi->dec.nal_info;
@@ -691,8 +749,11 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
return -EINVAL;
}
- share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
- inst->vsi->wdma_end_addr_offset;
+ if (inst->ctx->is_secure_playback)
+ share_info->trans_end = inst->vsi->dec.wdma_end_addr_offset;
+ else
+ share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
+ inst->vsi->dec.wdma_end_addr_offset;
vdec_msg_queue_update_ube_wptr(&lat_buf->ctx->msg_queue, share_info->trans_end);
if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) {
@@ -737,10 +798,10 @@ static int vdec_h264_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs
mtk_vdec_debug(inst->ctx, "[h264-dec] [%d] y_dma=%llx c_dma=%llx",
inst->ctx->decoded_frame_cnt, y_fb_dma, c_fb_dma);
- inst->vsi_ctx.dec.bs_buf_addr = (u64)bs->dma_addr;
- inst->vsi_ctx.dec.bs_buf_size = bs->size;
- inst->vsi_ctx.dec.y_fb_dma = y_fb_dma;
- inst->vsi_ctx.dec.c_fb_dma = c_fb_dma;
+ inst->vsi_ctx.bs.dma_addr = (u64)bs->dma_addr;
+ inst->vsi_ctx.bs.size = bs->size;
+ inst->vsi_ctx.fb.y.dma_addr = y_fb_dma;
+ inst->vsi_ctx.fb.c.dma_addr = c_fb_dma;
inst->vsi_ctx.dec.vdec_fb_va = (u64)(uintptr_t)fb;
v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
@@ -770,7 +831,7 @@ static int vdec_h264_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs
for (i = 0; i < H264_MAX_MV_NUM; i++) {
mem = &inst->mv_buf[i];
- inst->vsi_ctx.mv_buf_dma[i] = mem->dma_addr;
+ inst->vsi_ctx.mv_buf_dma[i].dma_addr = mem->dma_addr;
}
}
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec_msg_queue.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec_msg_queue.c
index f283c4703dc6..c1310176ae05 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec_msg_queue.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_msg_queue.c
@@ -308,8 +308,13 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
msg_queue->wdma_addr.size = 0;
return -ENOMEM;
}
- msg_queue->wdma_rptr_addr = msg_queue->wdma_addr.dma_addr;
- msg_queue->wdma_wptr_addr = msg_queue->wdma_addr.dma_addr;
+ if (ctx->is_secure_playback) {
+ msg_queue->wdma_rptr_addr = 0;
+ msg_queue->wdma_wptr_addr = 0;
+ } else {
+ msg_queue->wdma_rptr_addr = msg_queue->wdma_addr.dma_addr;
+ msg_queue->wdma_wptr_addr = msg_queue->wdma_addr.dma_addr;
+ }
msg_queue->empty_lat_buf.ctx = ctx;
msg_queue->empty_lat_buf.core_decode = NULL;
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,18/22] media: mediatek: vcodec: remove parse nal_info in kernel
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (16 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,17/22] media: mediatek: vcodec: re-construct h264 driver to support svp mode Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,19/22] media: mediatek: vcodec: disable wait interrupt for svp mode Yunfei Dong
` (3 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
The hardware can parse syntax to get nal_info, needn't to use cpu.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../vcodec/decoder/vdec/vdec_h264_req_multi_if.c | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
index a1a68487131c..2dfb3043493e 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
@@ -645,11 +645,10 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
struct vdec_h264_slice_inst *inst = h_vdec;
struct vdec_vpu_inst *vpu = &inst->vpu;
struct mtk_video_dec_buf *src_buf_info;
- int nal_start_idx, err, timeout = 0;
+ int err, timeout = 0;
unsigned int data[2];
struct vdec_lat_buf *lat_buf;
struct vdec_h264_slice_share_info *share_info;
- unsigned char *buf;
if (vdec_msg_queue_init(&inst->ctx->msg_queue, inst->ctx,
vdec_h264_slice_core_decode,
@@ -673,14 +672,6 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
share_info = lat_buf->private_data;
src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
- buf = (unsigned char *)bs->va;
- nal_start_idx = mtk_vdec_h264_find_start_code(buf, bs->size);
- if (nal_start_idx < 0) {
- err = -EINVAL;
- goto err_free_fb_out;
- }
-
- inst->vsi->dec.nal_info = buf[nal_start_idx];
lat_buf->src_buf_req = src_buf_info->m2m_buf.vb.vb2_buf.req_obj.req;
v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb, &lat_buf->ts_info, true);
@@ -689,7 +680,7 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
goto err_free_fb_out;
if (!inst->ctx->is_secure_playback)
- vdec_h264_insert_startcode(inst->ctx->dev, buf, &bs->size,
+ vdec_h264_insert_startcode(inst->ctx->dev, bs->va, &bs->size,
&share_info->h264_slice_params.pps);
*res_chg = inst->resolution_changed;
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,19/22] media: mediatek: vcodec: disable wait interrupt for svp mode
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (17 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,18/22] media: mediatek: vcodec: remove parse nal_info in kernel Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,20/22] media: mediatek: vcodec: support tee decoder Yunfei Dong
` (2 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
Waiting interrupt in optee-os for svp mode, need to disable it in kernel
in case of interrupt is cleaned.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../vcodec/decoder/mtk_vcodec_dec_hw.c | 34 +++++------
.../vcodec/decoder/mtk_vcodec_dec_pm.c | 6 +-
.../decoder/vdec/vdec_h264_req_multi_if.c | 57 +++++++++++--------
3 files changed, 54 insertions(+), 43 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.c
index 881d5de41e05..1982c088c6da 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.c
@@ -72,26 +72,28 @@ static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv)
ctx = mtk_vcodec_get_curr_ctx(dev->main_dev, dev->hw_idx);
- /* check if HW active or not */
- cg_status = readl(dev->reg_base[VDEC_HW_SYS] + VDEC_HW_ACTIVE_ADDR);
- if (cg_status & VDEC_HW_ACTIVE_MASK) {
- mtk_v4l2_vdec_err(ctx, "vdec active is not 0x0 (0x%08x)", cg_status);
- return IRQ_HANDLED;
- }
+ if (!ctx->is_secure_playback) {
+ /* check if HW active or not */
+ cg_status = readl(dev->reg_base[VDEC_HW_SYS] + VDEC_HW_ACTIVE_ADDR);
+ if (cg_status & VDEC_HW_ACTIVE_MASK) {
+ mtk_v4l2_vdec_err(ctx, "vdec active is not 0x0 (0x%08x)", cg_status);
+ return IRQ_HANDLED;
+ }
- dec_done_status = readl(vdec_misc_addr);
- if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) !=
- MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
- return IRQ_HANDLED;
+ dec_done_status = readl(vdec_misc_addr);
+ if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) !=
+ MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
+ return IRQ_HANDLED;
- /* clear interrupt */
- writel(dec_done_status | VDEC_IRQ_CFG, vdec_misc_addr);
- writel(dec_done_status & ~VDEC_IRQ_CLR, vdec_misc_addr);
+ /* clear interrupt */
+ writel(dec_done_status | VDEC_IRQ_CFG, vdec_misc_addr);
+ writel(dec_done_status & ~VDEC_IRQ_CLR, vdec_misc_addr);
- wake_up_dec_ctx(ctx, MTK_INST_IRQ_RECEIVED, dev->hw_idx);
+ wake_up_dec_ctx(ctx, MTK_INST_IRQ_RECEIVED, dev->hw_idx);
- mtk_v4l2_vdec_dbg(3, ctx, "wake up ctx %d, dec_done_status=%x",
- ctx->id, dec_done_status);
+ mtk_v4l2_vdec_dbg(3, ctx, "wake up ctx %d, dec_done_status=%x",
+ ctx->id, dec_done_status);
+ }
return IRQ_HANDLED;
}
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_pm.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_pm.c
index aefd3e9e3061..a94eda936f16 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_pm.c
@@ -238,7 +238,8 @@ void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_dec_ctx *ctx, int hw_idx)
mtk_vcodec_dec_child_dev_on(ctx->dev, MTK_VDEC_LAT0);
mtk_vcodec_dec_child_dev_on(ctx->dev, hw_idx);
- mtk_vcodec_dec_enable_irq(ctx->dev, hw_idx);
+ if (!ctx->is_secure_playback)
+ mtk_vcodec_dec_enable_irq(ctx->dev, hw_idx);
if (IS_VDEC_INNER_RACING(ctx->dev->dec_capability))
mtk_vcodec_load_racing_info(ctx);
@@ -250,7 +251,8 @@ void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_dec_ctx *ctx, int hw_idx)
if (IS_VDEC_INNER_RACING(ctx->dev->dec_capability))
mtk_vcodec_record_racing_info(ctx);
- mtk_vcodec_dec_disable_irq(ctx->dev, hw_idx);
+ if (!ctx->is_secure_playback)
+ mtk_vcodec_dec_disable_irq(ctx->dev, hw_idx);
mtk_vcodec_dec_child_dev_off(ctx->dev, hw_idx);
if (IS_VDEC_LAT_ARCH(ctx->dev->vdec_pdata->hw_arch) &&
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
index 2dfb3043493e..3e2270399b6c 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
@@ -593,14 +593,16 @@ static int vdec_h264_slice_core_decode(struct vdec_lat_buf *lat_buf)
goto vdec_dec_end;
}
- /* wait decoder done interrupt */
- timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
- WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE);
- if (timeout)
- mtk_vdec_err(ctx, "core decode timeout: pic_%d", ctx->decoded_frame_cnt);
- inst->vsi_core->dec.timeout = !!timeout;
-
- vpu_dec_core_end(vpu);
+ if (!ctx->is_secure_playback) {
+ /* wait decoder done interrupt */
+ timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
+ WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE);
+ if (timeout)
+ mtk_vdec_err(ctx, "core decode timeout: pic_%d", ctx->decoded_frame_cnt);
+ inst->vsi_core->dec.timeout = !!timeout;
+
+ vpu_dec_core_end(vpu);
+ }
mtk_vdec_debug(ctx, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
ctx->decoded_frame_cnt,
inst->vsi_core->dec.crc[0], inst->vsi_core->dec.crc[1],
@@ -724,14 +726,16 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
vdec_msg_queue_qbuf(&inst->ctx->msg_queue.core_ctx, lat_buf);
}
- /* wait decoder done interrupt */
- timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
- WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0);
- if (timeout)
- mtk_vdec_err(inst->ctx, "lat decode timeout: pic_%d", inst->slice_dec_num);
- inst->vsi->dec.timeout = !!timeout;
+ if (!inst->ctx->is_secure_playback) {
+ /* wait decoder done interrupt */
+ timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
+ WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0);
+ if (timeout)
+ mtk_vdec_err(inst->ctx, "lat decode timeout: pic_%d", inst->slice_dec_num);
+ inst->vsi->dec.timeout = !!timeout;
- err = vpu_dec_end(vpu);
+ err = vpu_dec_end(vpu);
+ }
if (err == SLICE_HEADER_FULL || err == TRANS_BUFFER_FULL) {
if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability))
vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf);
@@ -831,16 +835,19 @@ static int vdec_h264_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs
if (err)
goto err_free_fb_out;
- /* wait decoder done interrupt */
- err = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
- WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE);
- if (err)
- mtk_vdec_err(inst->ctx, "decode timeout: pic_%d", inst->ctx->decoded_frame_cnt);
-
- inst->vsi->dec.timeout = !!err;
- err = vpu_dec_end(vpu);
- if (err)
- goto err_free_fb_out;
+ if (!inst->ctx->is_secure_playback) {
+ /* wait decoder done interrupt */
+ err = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
+ WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE);
+ if (err)
+ mtk_vdec_err(inst->ctx, "decode timeout: pic_%d",
+ inst->ctx->decoded_frame_cnt);
+
+ inst->vsi->dec.timeout = !!err;
+ err = vpu_dec_end(vpu);
+ if (err)
+ goto err_free_fb_out;
+ }
memcpy(&inst->vsi_ctx, inst->vpu.vsi, sizeof(inst->vsi_ctx));
mtk_vdec_debug(inst->ctx, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,20/22] media: mediatek: vcodec: support tee decoder
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (18 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,19/22] media: mediatek: vcodec: disable wait interrupt for svp mode Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,21/22] media: mediatek: vcodec: move vdec init interface to setup callback Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,22/22] media: mediatek: vcodec: support hevc svp for mt8188 Yunfei Dong
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
Initialize tee private data to support secure decoder.
Release tee related information for each instance when decoder
done.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
index f47c98faf068..08e7d250487b 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
@@ -310,6 +310,9 @@ static int fops_vcodec_release(struct file *file)
v4l2_fh_exit(&ctx->fh);
v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
+ if (ctx->is_secure_playback)
+ mtk_vcodec_dec_optee_release(dev->optee_private);
+
mtk_vcodec_dbgfs_remove(dev, ctx->id);
list_del_init(&ctx->list);
kfree(ctx);
@@ -466,6 +469,11 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
atomic_set(&dev->dec_active_cnt, 0);
memset(dev->vdec_racing_info, 0, sizeof(dev->vdec_racing_info));
mutex_init(&dev->dec_racing_info_mutex);
+ ret = mtk_vcodec_dec_optee_private_init(dev);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to init svp private.");
+ goto err_reg_cont;
+ }
ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, -1);
if (ret) {
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,21/22] media: mediatek: vcodec: move vdec init interface to setup callback
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (19 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,20/22] media: mediatek: vcodec: support tee decoder Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
2024-01-29 6:30 ` [PATCH v4,22/22] media: mediatek: vcodec: support hevc svp for mt8188 Yunfei Dong
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
Getting secure video playback (svp) flag when request output buffer, then
calling init interface to init svp parameters in optee-os.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../mediatek/vcodec/decoder/mtk_vcodec_dec.c | 139 +++++++++++-------
1 file changed, 89 insertions(+), 50 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c
index 5d876a31e566..667005ff49c0 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c
@@ -184,6 +184,69 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_dec_ctx *ctx)
q_data->bytesperline[1] = q_data->coded_width;
}
+static int mtk_vcodec_dec_init_pic_info(struct mtk_vcodec_dec_ctx *ctx, enum v4l2_buf_type type)
+{
+ const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
+ struct mtk_q_data *q_data;
+ int ret;
+
+ if (!ctx->current_codec)
+ return 0;
+
+ if (V4L2_TYPE_IS_OUTPUT(type) && ctx->state == MTK_STATE_FREE) {
+ q_data = mtk_vdec_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (!q_data)
+ return -EINVAL;
+
+ ret = vdec_if_init(ctx, q_data->fmt->fourcc);
+ if (ret) {
+ mtk_v4l2_vdec_err(ctx, "[%d]: vdec_if_init() fail ret=%d",
+ ctx->id, ret);
+ return -EINVAL;
+ }
+ ctx->state = MTK_STATE_INIT;
+ }
+
+ if (!dec_pdata->uses_stateless_api)
+ return 0;
+
+ /*
+ * If get pic info fail, need to use the default pic info params, or
+ * v4l2-compliance will fail
+ */
+ ret = vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo);
+ if (ret)
+ mtk_v4l2_vdec_err(ctx, "[%d]Error!! Get GET_PARAM_PICTURE_INFO Fail",
+ ctx->id);
+
+ q_data = mtk_vdec_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (q_data->fmt->num_planes == 1) {
+ q_data->sizeimage[0] = ctx->picinfo.fb_sz[0] + ctx->picinfo.fb_sz[1];
+ q_data->bytesperline[0] = ctx->picinfo.buf_w;
+ } else {
+ if (ctx->is_secure_playback)
+ q_data->sizeimage[0] = ctx->picinfo.fb_sz[0] + ctx->picinfo.fb_sz[1];
+ else
+ q_data->sizeimage[0] = ctx->picinfo.fb_sz[0];
+
+ q_data->bytesperline[0] = ctx->picinfo.buf_w;
+ q_data->sizeimage[1] = ctx->picinfo.fb_sz[1];
+ q_data->bytesperline[1] = ctx->picinfo.buf_w;
+ }
+
+ q_data->coded_width = ctx->picinfo.buf_w;
+ q_data->coded_height = ctx->picinfo.buf_h;
+
+ ctx->last_decoded_picinfo = ctx->picinfo;
+ mtk_v4l2_vdec_dbg(2, ctx,
+ "[%d] init() plane:%d wxh=%dx%d pic wxh=%dx%d sz=0x%x_0x%x",
+ ctx->id, q_data->fmt->num_planes,
+ ctx->picinfo.buf_w, ctx->picinfo.buf_h,
+ ctx->picinfo.pic_w, ctx->picinfo.pic_h,
+ q_data->sizeimage[0], q_data->sizeimage[1]);
+ return 0;
+}
+
static int vidioc_vdec_qbuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{
@@ -479,17 +542,7 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
ctx->ycbcr_enc = pix_mp->ycbcr_enc;
ctx->quantization = pix_mp->quantization;
ctx->xfer_func = pix_mp->xfer_func;
-
ctx->current_codec = fmt->fourcc;
- if (ctx->state == MTK_STATE_FREE) {
- ret = vdec_if_init(ctx, q_data->fmt->fourcc);
- if (ret) {
- mtk_v4l2_vdec_err(ctx, "[%d]: vdec_if_init() fail ret=%d",
- ctx->id, ret);
- return -EINVAL;
- }
- ctx->state = MTK_STATE_INIT;
- }
} else {
ctx->capture_fourcc = fmt->fourcc;
}
@@ -502,46 +555,11 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
ctx->picinfo.pic_w = pix_mp->width;
ctx->picinfo.pic_h = pix_mp->height;
- /*
- * If get pic info fail, need to use the default pic info params, or
- * v4l2-compliance will fail
- */
- ret = vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo);
- if (ret) {
- mtk_v4l2_vdec_err(ctx, "[%d]Error!! Get GET_PARAM_PICTURE_INFO Fail",
- ctx->id);
- }
-
- ctx->last_decoded_picinfo = ctx->picinfo;
-
- if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1) {
- ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] =
- ctx->picinfo.fb_sz[0] +
- ctx->picinfo.fb_sz[1];
- ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] =
- ctx->picinfo.buf_w;
- } else {
- ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] =
- ctx->picinfo.fb_sz[0];
- ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] =
- ctx->picinfo.buf_w;
- ctx->q_data[MTK_Q_DATA_DST].sizeimage[1] =
- ctx->picinfo.fb_sz[1];
- ctx->q_data[MTK_Q_DATA_DST].bytesperline[1] =
- ctx->picinfo.buf_w;
- }
-
- ctx->q_data[MTK_Q_DATA_DST].coded_width = ctx->picinfo.buf_w;
- ctx->q_data[MTK_Q_DATA_DST].coded_height = ctx->picinfo.buf_h;
- mtk_v4l2_vdec_dbg(2, ctx,
- "[%d] init() plane:%d wxh=%dx%d pic wxh=%dx%d sz=0x%x_0x%x",
- ctx->id, pix_mp->num_planes,
- ctx->picinfo.buf_w, ctx->picinfo.buf_h,
- ctx->picinfo.pic_w, ctx->picinfo.pic_h,
- ctx->q_data[MTK_Q_DATA_DST].sizeimage[0],
- ctx->q_data[MTK_Q_DATA_DST].sizeimage[1]);
+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ ret = mtk_vcodec_dec_init_pic_info(ctx, f->type);
}
- return 0;
+
+ return ret;
}
static int vidioc_enum_framesizes(struct file *file, void *priv,
@@ -722,7 +740,7 @@ int vb2ops_vdec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
{
struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(vq);
struct mtk_q_data *q_data;
- unsigned int i;
+ unsigned int i, ret;
q_data = mtk_vdec_get_q_data(ctx, vq->type);
@@ -731,6 +749,25 @@ int vb2ops_vdec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
return -EINVAL;
}
+ if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ if (vq->restricted_mem && !ctx->is_secure_playback) {
+ ret = mtk_vcodec_dec_optee_open(ctx->dev->optee_private);
+ if (ret) {
+ mtk_v4l2_vdec_err(ctx, "Failed to open decoder optee os");
+ return ret;
+ }
+ ctx->is_secure_playback = vq->restricted_mem;
+ mtk_v4l2_vdec_dbg(1, ctx, "Getting secure decoder mode:%d",
+ ctx->is_secure_playback);
+ }
+
+ ret = mtk_vcodec_dec_init_pic_info(ctx, vq->type);
+ if (ret) {
+ mtk_v4l2_vdec_err(ctx, "Failed to init picture information");
+ return ret;
+ }
+ }
+
if (*nplanes) {
if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
if (*nplanes != q_data->fmt->num_planes)
@@ -980,6 +1017,7 @@ int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
src_vq->lock = &ctx->dev->dev_mutex;
src_vq->dev = &ctx->dev->plat_dev->dev;
src_vq->allow_cache_hints = 1;
+ src_vq->allow_restricted_mem = 1;
ret = vb2_queue_init(src_vq);
if (ret) {
@@ -996,6 +1034,7 @@ int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
dst_vq->lock = &ctx->dev->dev_mutex;
dst_vq->dev = &ctx->dev->plat_dev->dev;
dst_vq->allow_cache_hints = 1;
+ dst_vq->allow_restricted_mem = 1;
ret = vb2_queue_init(dst_vq);
if (ret)
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v4,22/22] media: mediatek: vcodec: support hevc svp for mt8188
2024-01-29 6:30 [PATCH v4,00/22] media: add driver to support secure video decoder Yunfei Dong
` (20 preceding siblings ...)
2024-01-29 6:30 ` [PATCH v4,21/22] media: mediatek: vcodec: move vdec init interface to setup callback Yunfei Dong
@ 2024-01-29 6:30 ` Yunfei Dong
21 siblings, 0 replies; 23+ messages in thread
From: Yunfei Dong @ 2024-01-29 6:30 UTC (permalink / raw)
To: Jeffrey Kardatzke, Nícolas F . R . A . Prado,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert
Cc: Chen-Yu Tsai, Yong Wu, Hsin-Yi Wang, Fritz Koenig, Daniel Vetter,
Steve Cho, Yunfei Dong, Sumit Semwal, Brian Starkey, John Stultz,
T . J . Mercier, Christian König, Matthias Brugger,
dri-devel, linaro-mm-sig, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
Change hevc 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: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../decoder/vdec/vdec_hevc_req_multi_if.c | 89 +++++++++++--------
1 file changed, 54 insertions(+), 35 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c
index 06ed47df693b..8bf4bc13ae2d 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c
@@ -415,11 +415,14 @@ static void vdec_hevc_fill_dpb_info(struct mtk_vcodec_dec_ctx *ctx,
hevc_dpb_info[index].field = dpb->field_pic;
hevc_dpb_info[index].y_dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
- if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
- hevc_dpb_info[index].c_dma_addr = vb2_dma_contig_plane_dma_addr(vb, 1);
- else
- hevc_dpb_info[index].c_dma_addr =
- hevc_dpb_info[index].y_dma_addr + ctx->picinfo.fb_sz[0];
+ if (!ctx->is_secure_playback) {
+ if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
+ hevc_dpb_info[index].c_dma_addr =
+ vb2_dma_contig_plane_dma_addr(vb, 1);
+ else
+ hevc_dpb_info[index].c_dma_addr =
+ hevc_dpb_info[index].y_dma_addr + ctx->picinfo.fb_sz[0];
+ }
}
}
@@ -800,7 +803,7 @@ static int vdec_hevc_slice_setup_core_buffer(struct vdec_hevc_slice_inst *inst,
struct mtk_vcodec_dec_ctx *ctx = inst->ctx;
struct vb2_v4l2_buffer *vb2_v4l2;
struct vdec_fb *fb;
- u64 y_fb_dma, c_fb_dma;
+ u64 y_fb_dma, c_fb_dma = 0;
int i;
fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx);
@@ -810,18 +813,20 @@ static int vdec_hevc_slice_setup_core_buffer(struct vdec_hevc_slice_inst *inst,
}
y_fb_dma = (u64)fb->base_y.dma_addr;
- if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
- c_fb_dma =
- y_fb_dma + inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;
- else
- c_fb_dma = (u64)fb->base_c.dma_addr;
+ if (!ctx->is_secure_playback) {
+ if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
+ c_fb_dma =
+ y_fb_dma + inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;
+ else
+ c_fb_dma = (u64)fb->base_c.dma_addr;
+ }
mtk_vdec_debug(inst->ctx, "[hevc-core] y/c addr = 0x%llx 0x%llx", y_fb_dma, c_fb_dma);
inst->vsi_core->fb.y.dma_addr = y_fb_dma;
inst->vsi_core->fb.y.size = ctx->picinfo.fb_sz[0];
inst->vsi_core->fb.c.dma_addr = c_fb_dma;
- inst->vsi_core->fb.y.size = ctx->picinfo.fb_sz[1];
+ inst->vsi_core->fb.c.size = ctx->picinfo.fb_sz[1];
inst->vsi_core->dec.vdec_fb_va = (unsigned long)fb;
@@ -878,8 +883,13 @@ static int vdec_hevc_slice_init(struct mtk_vcodec_dec_ctx *ctx)
vsi_size = round_up(sizeof(struct vdec_hevc_slice_vsi), VCODEC_DEC_ALIGNED_64);
inst->vsi = inst->vpu.vsi;
- inst->vsi_core =
- (struct vdec_hevc_slice_vsi *)(((char *)inst->vpu.vsi) + vsi_size);
+ if (ctx->is_secure_playback)
+ inst->vsi_core =
+ mtk_vcodec_dec_get_shm_buffer_va(ctx->dev->optee_private, MTK_VDEC_CORE,
+ OPTEE_DATA_INDEX);
+ else
+ inst->vsi_core =
+ (struct vdec_hevc_slice_vsi *)(((char *)inst->vpu.vsi) + vsi_size);
inst->resolution_changed = true;
inst->realloc_mv_buf = true;
@@ -944,21 +954,22 @@ static int vdec_hevc_slice_core_decode(struct vdec_lat_buf *lat_buf)
goto vdec_dec_end;
}
- /* wait decoder done interrupt */
- timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
- WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE);
- if (timeout)
- mtk_vdec_err(ctx, "core decode timeout: pic_%d", ctx->decoded_frame_cnt);
- inst->vsi_core->dec.timeout = !!timeout;
+ if (!vpu->ctx->is_secure_playback) {
+ /* wait decoder done interrupt */
+ timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
+ WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE);
+ if (timeout)
+ mtk_vdec_err(ctx, "core decode timeout: pic_%d", ctx->decoded_frame_cnt);
+ inst->vsi_core->dec.timeout = !!timeout;
- vpu_dec_core_end(vpu);
- mtk_vdec_debug(ctx, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
- ctx->decoded_frame_cnt,
+ vpu_dec_core_end(vpu);
+ }
+ mtk_vdec_debug(ctx, "pic[%d] svp:%d crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
+ ctx->decoded_frame_cnt, ctx->is_secure_playback,
inst->vsi_core->dec.crc[0], inst->vsi_core->dec.crc[1],
inst->vsi_core->dec.crc[2], inst->vsi_core->dec.crc[3],
inst->vsi_core->dec.crc[4], inst->vsi_core->dec.crc[5],
inst->vsi_core->dec.crc[6], inst->vsi_core->dec.crc[7]);
-
vdec_dec_end:
vdec_msg_queue_update_ube_rptr(&lat_buf->ctx->msg_queue, share_info->trans.dma_addr_end);
ctx->dev->vdec_pdata->cap_to_disp(ctx, !!err, lat_buf->src_buf_req);
@@ -1015,14 +1026,17 @@ static int vdec_hevc_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
vdec_msg_queue_qbuf(&inst->ctx->msg_queue.core_ctx, lat_buf);
}
- /* wait decoder done interrupt */
- timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
- WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0);
- if (timeout)
- mtk_vdec_err(inst->ctx, "lat decode timeout: pic_%d", inst->slice_dec_num);
- inst->vsi->dec.timeout = !!timeout;
+ if (!inst->ctx->is_secure_playback) {
+ /* wait decoder done interrupt */
+ timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
+ WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0);
+ if (timeout)
+ mtk_vdec_err(inst->ctx, "lat decode timeout: pic_%d", inst->slice_dec_num);
+ inst->vsi->dec.timeout = !!timeout;
+
+ err = vpu_dec_end(vpu);
+ }
- err = vpu_dec_end(vpu);
if (err == SLICE_HEADER_FULL || err == TRANS_BUFFER_FULL) {
if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability))
vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf);
@@ -1031,8 +1045,11 @@ static int vdec_hevc_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
return -EINVAL;
}
- share_info->trans.dma_addr_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
- inst->vsi->dec.wdma_end_addr_offset;
+ if (inst->ctx->is_secure_playback)
+ share_info->trans.dma_addr_end = inst->vsi->dec.wdma_end_addr_offset;
+ else
+ share_info->trans.dma_addr_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
+ inst->vsi->dec.wdma_end_addr_offset;
vdec_msg_queue_update_ube_wptr(&lat_buf->ctx->msg_queue, share_info->trans.dma_addr_end);
if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) {
@@ -1040,8 +1057,10 @@ static int vdec_hevc_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
sizeof(share_info->hevc_slice_params));
vdec_msg_queue_qbuf(&inst->ctx->msg_queue.core_ctx, lat_buf);
}
- mtk_vdec_debug(inst->ctx, "dec num: %d lat crc: 0x%x 0x%x 0x%x", inst->slice_dec_num,
- inst->vsi->dec.crc[0], inst->vsi->dec.crc[1], inst->vsi->dec.crc[2]);
+
+ mtk_vdec_debug(inst->ctx, "dec num: %d lat crc: 0x%x 0x%x 0x%x 0x%x size:%d",
+ inst->slice_dec_num, inst->vsi->dec.crc[0], inst->vsi->dec.crc[1],
+ inst->vsi->dec.crc[2], inst->vsi->dec.crc[3], (unsigned int)bs->size);
inst->slice_dec_num++;
return 0;
--
2.18.0
^ permalink raw reply related [flat|nested] 23+ messages in thread