Commit cd98e85a authored by Steve Longerbeam's avatar Steve Longerbeam Committed by Philipp Zabel

gpu: ipu-v3: Add queued image conversion support

This patch implements image conversion support using the IC tasks, with
tiling to support scaling to and from images up to 4096x4096. Image
rotation is also supported. Image conversion requests are added to
a run queue under the IC tasks.

The internal API is subsystem agnostic (no V4L2 dependency except
for the use of V4L2 fourcc pixel formats).

Callers prepare for image conversion by calling
ipu_image_convert_prepare(), which initializes the parameters of
the conversion. The caller passes in the ipu and IC task to use for
the conversion, the input and output image formats, a rotation mode,
and a completion callback and completion context pointer:

struct ipu_image_converter_ctx *
ipu_image_convert_prepare(struct ipu_soc *ipu, enum ipu_ic_task ic_task,
                          struct ipu_image *in, struct ipu_image *out,
                          enum ipu_rotate_mode rot_mode,
                          ipu_image_converter_cb_t complete,
                          void *complete_context);

A new conversion context is created that is added to an IC task
context queue. The caller is given the new conversion context,
which can then be passed to the further APIs:

int ipu_image_convert_queue(struct ipu_image_converter_run *run);

This queues the given image conversion request run to a run queue,
and starts the conversion immediately if the run queue is empty. Only
the physaddr's of the input and output image buffers are needed,
since the conversion context was created previously with
ipu_image_convert_prepare(). When the conversion completes, the run
pointer is returned to the completion callback.

void ipu_image_convert_abort(struct ipu_image_converter_ctx *ctx);

This will abort any active or pending conversions for this context.
Any currently active or pending runs belonging to this context are
returned via the completion callback with an error status.

void ipu_image_convert_unprepare(struct ipu_image_converter_ctx *ctx);

Unprepares the conversion context. Any active or pending runs will
be aborted by calling ipu_image_convert_abort().
Signed-off-by: default avatarSteve Longerbeam <steve_longerbeam@mentor.com>
Signed-off-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
parent 8b9c3d50
obj-$(CONFIG_IMX_IPUV3_CORE) += imx-ipu-v3.o
imx-ipu-v3-objs := ipu-common.o ipu-cpmem.o ipu-csi.o ipu-dc.o ipu-di.o \
ipu-dp.o ipu-dmfc.o ipu-ic.o ipu-smfc.o ipu-vdi.o
ipu-dp.o ipu-dmfc.o ipu-ic.o ipu-image-convert.o \
ipu-smfc.o ipu-vdi.o
......@@ -978,6 +978,12 @@ static int ipu_submodules_init(struct ipu_soc *ipu,
goto err_vdi;
}
ret = ipu_image_convert_init(ipu, dev);
if (ret) {
unit = "image_convert";
goto err_image_convert;
}
ret = ipu_di_init(ipu, dev, 0, ipu_base + devtype->disp0_ofs,
IPU_CONF_DI0_EN, ipu_clk);
if (ret) {
......@@ -1032,6 +1038,8 @@ static int ipu_submodules_init(struct ipu_soc *ipu,
err_di_1:
ipu_di_exit(ipu, 0);
err_di_0:
ipu_image_convert_exit(ipu);
err_image_convert:
ipu_vdi_exit(ipu);
err_vdi:
ipu_ic_exit(ipu);
......@@ -1118,6 +1126,7 @@ static void ipu_submodules_exit(struct ipu_soc *ipu)
ipu_dc_exit(ipu);
ipu_di_exit(ipu, 1);
ipu_di_exit(ipu, 0);
ipu_image_convert_exit(ipu);
ipu_vdi_exit(ipu);
ipu_ic_exit(ipu);
ipu_csi_exit(ipu, 1);
......
This diff is collapsed.
......@@ -166,6 +166,7 @@ struct ipu_dmfc_priv;
struct ipu_di;
struct ipu_ic_priv;
struct ipu_vdi;
struct ipu_image_convert_priv;
struct ipu_smfc_priv;
struct ipu_devtype;
......@@ -199,6 +200,7 @@ struct ipu_soc {
struct ipu_csi *csi_priv[2];
struct ipu_ic_priv *ic_priv;
struct ipu_vdi *vdi_priv;
struct ipu_image_convert_priv *image_convert_priv;
struct ipu_smfc_priv *smfc_priv;
};
......@@ -233,6 +235,9 @@ int ipu_vdi_init(struct ipu_soc *ipu, struct device *dev,
unsigned long base, u32 module);
void ipu_vdi_exit(struct ipu_soc *ipu);
int ipu_image_convert_init(struct ipu_soc *ipu, struct device *dev);
void ipu_image_convert_exit(struct ipu_soc *ipu);
int ipu_di_init(struct ipu_soc *ipu, struct device *dev, int id,
unsigned long base, u32 module, struct clk *ipu_clk);
void ipu_di_exit(struct ipu_soc *ipu, int id);
......
/*
* Copyright (C) 2012-2016 Mentor Graphics Inc.
*
* i.MX Queued image conversion support, with tiling and rotation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#ifndef __IMX_IPU_IMAGE_CONVERT_H__
#define __IMX_IPU_IMAGE_CONVERT_H__
#include <video/imx-ipu-v3.h>
struct ipu_image_convert_ctx;
/**
* struct ipu_image_convert_run - image conversion run request struct
*
* @ctx: the conversion context
* @in_phys: dma addr of input image buffer for this run
* @out_phys: dma addr of output image buffer for this run
* @status: completion status of this run
*/
struct ipu_image_convert_run {
struct ipu_image_convert_ctx *ctx;
dma_addr_t in_phys;
dma_addr_t out_phys;
int status;
/* internal to image converter, callers don't touch */
struct list_head list;
};
/**
* ipu_image_convert_cb_t - conversion callback function prototype
*
* @run: the completed conversion run pointer
* @ctx: a private context pointer for the callback
*/
typedef void (*ipu_image_convert_cb_t)(struct ipu_image_convert_run *run,
void *ctx);
/**
* ipu_image_convert_enum_format() - enumerate the image converter's
* supported input and output pixel formats.
*
* @index: pixel format index
* @fourcc: v4l2 fourcc for this index
*
* Returns 0 with a valid index and fills in v4l2 fourcc, -EINVAL otherwise.
*
* In V4L2, drivers can call ipu_image_enum_format() in .enum_fmt.
*/
int ipu_image_convert_enum_format(int index, u32 *fourcc);
/**
* ipu_image_convert_adjust() - adjust input/output images to IPU restrictions.
*
* @in: input image format, adjusted on return
* @out: output image format, adjusted on return
* @rot_mode: rotation mode
*
* In V4L2, drivers can call ipu_image_convert_adjust() in .try_fmt.
*/
void ipu_image_convert_adjust(struct ipu_image *in, struct ipu_image *out,
enum ipu_rotate_mode rot_mode);
/**
* ipu_image_convert_verify() - verify that input/output image formats
* and rotation mode meet IPU restrictions.
*
* @in: input image format
* @out: output image format
* @rot_mode: rotation mode
*
* Returns 0 if the formats and rotation mode meet IPU restrictions,
* -EINVAL otherwise.
*/
int ipu_image_convert_verify(struct ipu_image *in, struct ipu_image *out,
enum ipu_rotate_mode rot_mode);
/**
* ipu_image_convert_prepare() - prepare a conversion context.
*
* @ipu: the IPU handle to use for the conversions
* @ic_task: the IC task to use for the conversions
* @in: input image format
* @out: output image format
* @rot_mode: rotation mode
* @complete: run completion callback
* @complete_context: a context pointer for the completion callback
*
* Returns an opaque conversion context pointer on success, error pointer
* on failure. The input/output formats and rotation mode must already meet
* IPU retrictions.
*
* In V4L2, drivers should call ipu_image_convert_prepare() at streamon.
*/
struct ipu_image_convert_ctx *
ipu_image_convert_prepare(struct ipu_soc *ipu, enum ipu_ic_task ic_task,
struct ipu_image *in, struct ipu_image *out,
enum ipu_rotate_mode rot_mode,
ipu_image_convert_cb_t complete,
void *complete_context);
/**
* ipu_image_convert_unprepare() - unprepare a conversion context.
*
* @ctx: the conversion context pointer to unprepare
*
* Aborts any active or pending conversions for this context and
* frees the context. Any currently active or pending runs belonging
* to this context are returned via the completion callback with an
* error run status.
*
* In V4L2, drivers should call ipu_image_convert_unprepare() at
* streamoff.
*/
void ipu_image_convert_unprepare(struct ipu_image_convert_ctx *ctx);
/**
* ipu_image_convert_queue() - queue a conversion run
*
* @run: the run request pointer
*
* ipu_image_convert_run must be dynamically allocated (_not_ as a local
* var) by callers and filled in with a previously prepared conversion
* context handle and the dma addr's of the input and output image buffers
* for this conversion run.
*
* When this conversion completes, the run pointer is returned via the
* completion callback. The caller is responsible for freeing the run
* object after it completes.
*
* In V4L2, drivers should call ipu_image_convert_queue() while
* streaming to queue the conversion of a received input buffer.
* For example mem2mem devices this would be called in .device_run.
*/
int ipu_image_convert_queue(struct ipu_image_convert_run *run);
/**
* ipu_image_convert_abort() - abort conversions
*
* @ctx: the conversion context pointer
*
* This will abort any active or pending conversions for this context.
* Any currently active or pending runs belonging to this context are
* returned via the completion callback with an error run status.
*/
void ipu_image_convert_abort(struct ipu_image_convert_ctx *ctx);
/**
* ipu_image_convert() - asynchronous image conversion request
*
* @ipu: the IPU handle to use for the conversion
* @ic_task: the IC task to use for the conversion
* @in: input image format
* @out: output image format
* @rot_mode: rotation mode
* @complete: run completion callback
* @complete_context: a context pointer for the completion callback
*
* Request a single image conversion. Returns the run that has been queued.
* A conversion context is automatically created and is available in run->ctx.
* As with ipu_image_convert_prepare(), the input/output formats and rotation
* mode must already meet IPU retrictions.
*
* On successful return the caller can queue more run requests if needed, using
* the prepared context in run->ctx. The caller is responsible for unpreparing
* the context when no more conversion requests are needed.
*/
struct ipu_image_convert_run *
ipu_image_convert(struct ipu_soc *ipu, enum ipu_ic_task ic_task,
struct ipu_image *in, struct ipu_image *out,
enum ipu_rotate_mode rot_mode,
ipu_image_convert_cb_t complete,
void *complete_context);
/**
* ipu_image_convert_sync() - synchronous single image conversion request
*
* @ipu: the IPU handle to use for the conversion
* @ic_task: the IC task to use for the conversion
* @in: input image format
* @out: output image format
* @rot_mode: rotation mode
*
* Carry out a single image conversion. Returns when the conversion
* completes. The input/output formats and rotation mode must already
* meet IPU retrictions. The created context is automatically unprepared
* and the run freed on return.
*/
int ipu_image_convert_sync(struct ipu_soc *ipu, enum ipu_ic_task ic_task,
struct ipu_image *in, struct ipu_image *out,
enum ipu_rotate_mode rot_mode);
#endif /* __IMX_IPU_IMAGE_CONVERT_H__ */
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