[v5,09/10] media: rkisp1: Add YC swap capability
Commit Message
The ISP version in the i.MX8MP has an MI_OUTPUT_ALIGN_FORMAT register
that the rk3399 does not have. This register allows swapping bytes,
which can be used to implement UYVY from YUYV.
Add a feature flag to signify the presence of this feature, and add it
to the i.MX8MP match data. Also add it as a flag to the format info in
the list of supported formats by the capture v4l2 devices, and update
enum_fmt and s_fmt to take it into account.
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com>
Tested-by: Adam Ford <aford173@gmail.com>
---
.../platform/rockchip/rkisp1/rkisp1-capture.c | 26 ++++++++++++++-----
.../platform/rockchip/rkisp1/rkisp1-common.h | 2 ++
.../platform/rockchip/rkisp1/rkisp1-dev.c | 3 ++-
3 files changed, 23 insertions(+), 8 deletions(-)
@@ -47,13 +47,15 @@ enum rkisp1_plane {
* @fourcc: pixel format
* @fmt_type: helper filed for pixel format
* @uv_swap: if cb cr swapped, for yuv
+ * @yc_swap: if y and cb/cr swapped, for yuv
* @write_format: defines how YCbCr self picture data is written to memory
* @output_format: defines sp output format
* @mbus: the mbus code on the src resizer pad that matches the pixel format
*/
struct rkisp1_capture_fmt_cfg {
u32 fourcc;
- u8 uv_swap;
+ u32 uv_swap : 1;
+ u32 yc_swap : 1;
u32 write_format;
u32 output_format;
u32 mbus;
@@ -1162,10 +1164,14 @@ rkisp1_fill_pixfmt(const struct rkisp1_capture *cap,
static const struct rkisp1_capture_fmt_cfg *
rkisp1_find_fmt_cfg(const struct rkisp1_capture *cap, const u32 pixelfmt)
{
+ bool yc_swap_support = rkisp1_has_feature(cap->rkisp1, MI_OUTPUT_ALIGN);
unsigned int i;
for (i = 0; i < cap->config->fmt_size; i++) {
- if (cap->config->fmts[i].fourcc == pixelfmt)
+ const struct rkisp1_capture_fmt_cfg *fmt = &cap->config->fmts[i];
+
+ if (fmt->fourcc == pixelfmt &&
+ (!fmt->yc_swap || yc_swap_support))
return &cap->config->fmts[i];
}
return NULL;
@@ -1234,23 +1240,29 @@ static int rkisp1_enum_fmt_vid_cap_mplane(struct file *file, void *priv,
{
struct rkisp1_capture *cap = video_drvdata(file);
const struct rkisp1_capture_fmt_cfg *fmt = NULL;
+ bool yc_swap_support = rkisp1_has_feature(cap->rkisp1, MI_OUTPUT_ALIGN);
unsigned int i, n = 0;
- if (!f->mbus_code) {
- if (f->index >= cap->config->fmt_size)
- return -EINVAL;
+ if (f->index >= cap->config->fmt_size)
+ return -EINVAL;
+ if (!f->mbus_code && yc_swap_support) {
fmt = &cap->config->fmts[f->index];
f->pixelformat = fmt->fourcc;
return 0;
}
for (i = 0; i < cap->config->fmt_size; i++) {
- if (cap->config->fmts[i].mbus != f->mbus_code)
+ fmt = &cap->config->fmts[i];
+
+ if (f->mbus_code && fmt->mbus != f->mbus_code)
+ continue;
+
+ if (!yc_swap_support && fmt->yc_swap)
continue;
if (n++ == f->index) {
- f->pixelformat = cap->config->fmts[i].fourcc;
+ f->pixelformat = fmt->fourcc;
return 0;
}
}
@@ -115,6 +115,7 @@ enum rkisp1_isp_pad {
* @RKISP1_FEATURE_SELF_PATH: The ISP has a self path
* @RKISP1_FEATURE_DUAL_CROP: The ISP has the dual crop block at the resizer input
* @RKISP1_FEATURE_DMA_34BIT: The ISP uses 34-bit DMA addresses
+ * @RKISP1_FEATURE_MI_OUTPUT_ALIGN: The ISP has the MI_OUTPUT_ALIGN_FORMAT register
*
* The ISP features are stored in a bitmask in &rkisp1_info.features and allow
* the driver to implement support for features present in some ISP versions
@@ -126,6 +127,7 @@ enum rkisp1_feature {
RKISP1_FEATURE_SELF_PATH = BIT(2),
RKISP1_FEATURE_DUAL_CROP = BIT(3),
RKISP1_FEATURE_DMA_34BIT = BIT(4),
+ RKISP1_FEATURE_MI_OUTPUT_ALIGN = BIT(5),
};
#define rkisp1_has_feature(rkisp1, feature) \
@@ -550,7 +550,8 @@ static const struct rkisp1_info imx8mp_isp_info = {
.isr_size = ARRAY_SIZE(imx8mp_isp_isrs),
.isp_ver = IMX8MP_V10,
.features = RKISP1_FEATURE_MAIN_STRIDE
- | RKISP1_FEATURE_DMA_34BIT,
+ | RKISP1_FEATURE_DMA_34BIT
+ | RKISP1_FEATURE_MI_OUTPUT_ALIGN,
};
static const struct of_device_id rkisp1_of_match[] = {