Commit 91c83f39 authored by Hugues Fruchet's avatar Hugues Fruchet Committed by Mauro Carvalho Chehab

[media] st-delta: rpmsg ipc support

IPC (Inter Process Communication) support for communication with
DELTA coprocessor firmware using rpmsg kernel framework.
Based on 4 services open/set_stream/decode/close and their associated
rpmsg messages.
The messages structures are duplicated on both host and firmware
side and are packed (use only of 32 bits size fields in messages
structures to ensure packing).
Each service is synchronous; service returns only when firmware
acknowledges the associated command message.
Due to significant parameters size exchanged from host to copro,
parameters are not inserted in rpmsg messages. Instead, parameters are
stored in physical memory shared between host and coprocessor.
Memory is non-cacheable, so no special operation is required
to ensure memory coherency on host and on coprocessor side.
Multi-instance support and re-entrance are ensured using host_hdl and
copro_hdl in message header exchanged between both host and coprocessor.
This avoids to manage tables on both sides to get back the running context
of each instance.
Acked-by: default avatarPeter Griffin <peter.griffin@linaro.org>
Signed-off-by: default avatarHugues Fruchet <hugues.fruchet@st.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent c502e583
...@@ -337,6 +337,7 @@ config VIDEO_STI_DELTA_DRIVER ...@@ -337,6 +337,7 @@ config VIDEO_STI_DELTA_DRIVER
default n default n
select VIDEOBUF2_DMA_CONTIG select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV select V4L2_MEM2MEM_DEV
select RPMSG
endif # VIDEO_STI_DELTA endif # VIDEO_STI_DELTA
......
obj-$(CONFIG_VIDEO_STI_DELTA_DRIVER) := st-delta.o obj-$(CONFIG_VIDEO_STI_DELTA_DRIVER) := st-delta.o
st-delta-y := delta-v4l2.o delta-mem.o st-delta-y := delta-v4l2.o delta-mem.o delta-ipc.o
This diff is collapsed.
/*
* Copyright (C) STMicroelectronics SA 2015
* Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
* License terms: GNU General Public License (GPL), version 2
*/
#ifndef DELTA_IPC_H
#define DELTA_IPC_H
int delta_ipc_init(struct delta_dev *delta);
void delta_ipc_exit(struct delta_dev *delta);
/*
* delta_ipc_open - open a decoding instance on firmware side
* @ctx: (in) delta context
* @name: (in) name of decoder to be used
* @param: (in) open command parameters specific to decoder
* @param.size: (in) size of parameter
* @param.data: (in) virtual address of parameter
* @ipc_buf_size: (in) size of IPC shared buffer between host
* and copro used to share command data.
* Client have to set here the size of the biggest
* command parameters (+ status if any).
* Allocation will be done in this function which
* will give back to client in @ipc_buf the virtual
* & physical addresses & size of shared IPC buffer.
* All the further command data (parameters + status)
* have to be written in this shared IPC buffer
* virtual memory. This is done to avoid
* unnecessary copies of command data.
* @ipc_buf: (out) allocated IPC shared buffer
* @ipc_buf.size: (out) allocated size
* @ipc_buf.vaddr: (out) virtual address where to copy
* further command data
* @hdl: (out) handle of decoding instance.
*/
int delta_ipc_open(struct delta_ctx *ctx, const char *name,
struct delta_ipc_param *param, u32 ipc_buf_size,
struct delta_buf **ipc_buf, void **hdl);
/*
* delta_ipc_set_stream - set information about stream to decoder
* @hdl: (in) handle of decoding instance.
* @param: (in) set stream command parameters specific to decoder
* @param.size: (in) size of parameter
* @param.data: (in) virtual address of parameter. Must be
* within IPC shared buffer range
*/
int delta_ipc_set_stream(void *hdl, struct delta_ipc_param *param);
/*
* delta_ipc_decode - frame decoding synchronous request, returns only
* after decoding completion on firmware side.
* @hdl: (in) handle of decoding instance.
* @param: (in) decode command parameters specific to decoder
* @param.size: (in) size of parameter
* @param.data: (in) virtual address of parameter. Must be
* within IPC shared buffer range
* @status: (in/out) decode command status specific to decoder
* @status.size: (in) size of status
* @status.data: (in/out) virtual address of status. Must be
* within IPC shared buffer range.
* Status is filled by decoding instance
* after decoding completion.
*/
int delta_ipc_decode(void *hdl, struct delta_ipc_param *param,
struct delta_ipc_param *status);
/*
* delta_ipc_close - close decoding instance
* @hdl: (in) handle of decoding instance to close.
*/
void delta_ipc_close(void *hdl);
#endif /* DELTA_IPC_H */
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <media/videobuf2-dma-contig.h> #include <media/videobuf2-dma-contig.h>
#include "delta.h" #include "delta.h"
#include "delta-ipc.h"
#define DELTA_NAME "st-delta" #define DELTA_NAME "st-delta"
...@@ -1703,6 +1704,14 @@ static int delta_probe(struct platform_device *pdev) ...@@ -1703,6 +1704,14 @@ static int delta_probe(struct platform_device *pdev)
pm_runtime_set_suspended(dev); pm_runtime_set_suspended(dev);
pm_runtime_enable(dev); pm_runtime_enable(dev);
/* init firmware ipc channel */
ret = delta_ipc_init(delta);
if (ret) {
dev_err(delta->dev, "%s failed to initialize firmware ipc channel\n",
DELTA_PREFIX);
goto err;
}
/* register all available decoders */ /* register all available decoders */
register_decoders(delta); register_decoders(delta);
...@@ -1747,6 +1756,8 @@ static int delta_remove(struct platform_device *pdev) ...@@ -1747,6 +1756,8 @@ static int delta_remove(struct platform_device *pdev)
{ {
struct delta_dev *delta = platform_get_drvdata(pdev); struct delta_dev *delta = platform_get_drvdata(pdev);
delta_ipc_exit(delta);
delta_unregister_device(delta); delta_unregister_device(delta);
destroy_workqueue(delta->work_queue); destroy_workqueue(delta->work_queue);
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#ifndef DELTA_H #ifndef DELTA_H
#define DELTA_H #define DELTA_H
#include <linux/rpmsg.h>
#include <media/v4l2-device.h> #include <media/v4l2-device.h>
#include <media/v4l2-mem2mem.h> #include <media/v4l2-mem2mem.h>
...@@ -199,6 +200,19 @@ struct delta_buf { ...@@ -199,6 +200,19 @@ struct delta_buf {
unsigned long attrs; unsigned long attrs;
}; };
struct delta_ipc_ctx {
int cb_err;
u32 copro_hdl;
struct completion done;
struct delta_buf ipc_buf_struct;
struct delta_buf *ipc_buf;
};
struct delta_ipc_param {
u32 size;
void *data;
};
struct delta_ctx; struct delta_ctx;
/* /*
...@@ -368,6 +382,7 @@ struct delta_dev; ...@@ -368,6 +382,7 @@ struct delta_dev;
* @fh: V4L2 file handle * @fh: V4L2 file handle
* @dev: device context * @dev: device context
* @dec: selected decoder context for this instance * @dec: selected decoder context for this instance
* @ipc_ctx: context of IPC communication with firmware
* @state: instance state * @state: instance state
* @frame_num: frame number * @frame_num: frame number
* @au_num: access unit number * @au_num: access unit number
...@@ -399,6 +414,8 @@ struct delta_ctx { ...@@ -399,6 +414,8 @@ struct delta_ctx {
struct v4l2_fh fh; struct v4l2_fh fh;
struct delta_dev *dev; struct delta_dev *dev;
const struct delta_dec *dec; const struct delta_dec *dec;
struct delta_ipc_ctx ipc_ctx;
enum delta_state state; enum delta_state state;
u32 frame_num; u32 frame_num;
u32 au_num; u32 au_num;
...@@ -447,6 +464,8 @@ struct delta_ctx { ...@@ -447,6 +464,8 @@ struct delta_ctx {
* @nb_of_streamformats:number of supported compressed video formats * @nb_of_streamformats:number of supported compressed video formats
* @instance_id: rolling counter identifying an instance (debug purpose) * @instance_id: rolling counter identifying an instance (debug purpose)
* @work_queue: decoding job work queue * @work_queue: decoding job work queue
* @rpmsg_driver: rpmsg IPC driver
* @rpmsg_device: rpmsg IPC device
*/ */
struct delta_dev { struct delta_dev {
struct v4l2_device v4l2_dev; struct v4l2_device v4l2_dev;
...@@ -466,6 +485,8 @@ struct delta_dev { ...@@ -466,6 +485,8 @@ struct delta_dev {
u32 nb_of_streamformats; u32 nb_of_streamformats;
u8 instance_id; u8 instance_id;
struct workqueue_struct *work_queue; struct workqueue_struct *work_queue;
struct rpmsg_driver rpmsg_driver;
struct rpmsg_device *rpmsg_device;
}; };
static inline char *frame_type_str(u32 flags) static inline char *frame_type_str(u32 flags)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment