Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,14 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe.o
obj-$(CONFIG_VIDEO_TI_VPDMA) += ti-vpdma.o
obj-$(CONFIG_VIDEO_TI_SC) += ti-sc.o
obj-$(CONFIG_VIDEO_TI_CSC) += ti-csc.o
obj-$(CONFIG_VIDEO_TI_VIP) += ti-vip.o
ti-vpe-y := vpe.o
ti-vpdma-y := vpdma.o
ti-sc-y := sc.o
ti-csc-y := csc.o
ti-vip-y := vip.o
ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG
@@ -0,0 +1,279 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Color space converter library
*
* Copyright (c) 2013 Texas Instruments Inc.
*
* David Griego, <dagriego@biglakesoftware.com>
* Dale Farnsworth, <dale@farnsworth.org>
* Archit Taneja, <archit@ti.com>
*/
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include "csc.h"
/*
* 12 coefficients in the order:
* a0, b0, c0, a1, b1, c1, a2, b2, c2, d0, d1, d2
*/
struct quantization {
u16 coeff[12];
};
struct colorspace {
struct quantization limited;
struct quantization full;
};
struct encoding_direction {
struct colorspace r601;
struct colorspace r709;
};
struct csc_coeffs {
struct encoding_direction y2r;
struct encoding_direction r2y;
};
/* default colorspace coefficients */
static struct csc_coeffs csc_coeffs = {
.y2r = {
.r601 = {
.limited = {
{ /* SDTV */
0x0400, 0x0000, 0x057D, 0x0400, 0x1EA7, 0x1D35,
0x0400, 0x06EF, 0x1FFE, 0x0D40, 0x0210, 0x0C88,
}
},
.full = {
{ /* SDTV */
0x04A8, 0x1FFE, 0x0662, 0x04A8, 0x1E6F, 0x1CBF,
0x04A8, 0x0812, 0x1FFF, 0x0C84, 0x0220, 0x0BAC,
}
},
},
.r709 = {
.limited = {
{ /* HDTV */
0x0400, 0x0000, 0x0629, 0x0400, 0x1F45, 0x1E2B,
0x0400, 0x0742, 0x0000, 0x0CEC, 0x0148, 0x0C60,
}
},
.full = {
{ /* HDTV */
0x04A8, 0x0000, 0x072C, 0x04A8, 0x1F26, 0x1DDE,
0x04A8, 0x0873, 0x0000, 0x0C20, 0x0134, 0x0B7C,
}
},
},
},
.r2y = {
.r601 = {
.limited = {
{ /* SDTV */
0x0132, 0x0259, 0x0075, 0x1F50, 0x1EA5, 0x020B,
0x020B, 0x1E4A, 0x1FAB, 0x0000, 0x0200, 0x0200,
}
},
.full = {
{ /* SDTV */
0x0107, 0x0204, 0x0064, 0x1F68, 0x1ED6, 0x01C2,
0x01C2, 0x1E87, 0x1FB7, 0x0040, 0x0200, 0x0200,
}
},
},
.r709 = {
.limited = {
{ /* HDTV */
0x00DA, 0x02DC, 0x004A, 0x1F88, 0x1E6C, 0x020C,
0x020C, 0x1E24, 0x1FD0, 0x0000, 0x0200, 0x0200,
}
},
.full = {
{ /* HDTV */
0x00bb, 0x0275, 0x003f, 0x1f99, 0x1ea5, 0x01c2,
0x01c2, 0x1e67, 0x1fd7, 0x0040, 0x0200, 0x0200,
}
},
},
},
};
void csc_dump_regs(struct csc_data *csc)
{
struct device *dev = &csc->pdev->dev;
#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, \
ioread32(csc->base + CSC_##r))
dev_dbg(dev, "CSC Registers @ %pa:\n", &csc->res->start);
DUMPREG(CSC00);
DUMPREG(CSC01);
DUMPREG(CSC02);
DUMPREG(CSC03);
DUMPREG(CSC04);
DUMPREG(CSC05);
#undef DUMPREG
}
EXPORT_SYMBOL(csc_dump_regs);
void csc_set_coeff_bypass(struct csc_data *csc, u32 *csc_reg5)
{
*csc_reg5 |= CSC_BYPASS;
}
EXPORT_SYMBOL(csc_set_coeff_bypass);
/*
* set the color space converter coefficient shadow register values
*/
void csc_set_coeff(struct csc_data *csc, u32 *csc_reg0,
struct v4l2_format *src_fmt, struct v4l2_format *dst_fmt)
{
u32 *csc_reg5 = csc_reg0 + 5;
u32 *shadow_csc = csc_reg0;
u16 *coeff, *end_coeff;
const struct v4l2_pix_format *pix;
const struct v4l2_pix_format_mplane *mp;
const struct v4l2_format_info *src_finfo, *dst_finfo;
enum v4l2_ycbcr_encoding src_ycbcr_enc, dst_ycbcr_enc;
enum v4l2_quantization src_quantization, dst_quantization;
u32 src_pixelformat, dst_pixelformat;
if (V4L2_TYPE_IS_MULTIPLANAR(src_fmt->type)) {
mp = &src_fmt->fmt.pix_mp;
src_pixelformat = mp->pixelformat;
src_ycbcr_enc = mp->ycbcr_enc;
src_quantization = mp->quantization;
} else {
pix = &src_fmt->fmt.pix;
src_pixelformat = pix->pixelformat;
src_ycbcr_enc = pix->ycbcr_enc;
src_quantization = pix->quantization;
}
if (V4L2_TYPE_IS_MULTIPLANAR(dst_fmt->type)) {
mp = &dst_fmt->fmt.pix_mp;
dst_pixelformat = mp->pixelformat;
dst_ycbcr_enc = mp->ycbcr_enc;
dst_quantization = mp->quantization;
} else {
pix = &dst_fmt->fmt.pix;
dst_pixelformat = pix->pixelformat;
dst_ycbcr_enc = pix->ycbcr_enc;
dst_quantization = pix->quantization;
}
src_finfo = v4l2_format_info(src_pixelformat);
dst_finfo = v4l2_format_info(dst_pixelformat);
if (v4l2_is_format_yuv(src_finfo) &&
v4l2_is_format_rgb(dst_finfo)) {
/* Y2R */
/*
* These are not the standard default values but are
* set this way for historical compatibility
*/
if (src_ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
src_ycbcr_enc = V4L2_YCBCR_ENC_601;
if (src_quantization == V4L2_QUANTIZATION_DEFAULT)
src_quantization = V4L2_QUANTIZATION_FULL_RANGE;
if (src_ycbcr_enc == V4L2_YCBCR_ENC_601) {
if (src_quantization == V4L2_QUANTIZATION_FULL_RANGE)
coeff = csc_coeffs.y2r.r601.full.coeff;
else
coeff = csc_coeffs.y2r.r601.limited.coeff;
} else if (src_ycbcr_enc == V4L2_YCBCR_ENC_709) {
if (src_quantization == V4L2_QUANTIZATION_FULL_RANGE)
coeff = csc_coeffs.y2r.r709.full.coeff;
else
coeff = csc_coeffs.y2r.r709.limited.coeff;
} else {
/* Should never reach this, but it keeps gcc happy */
coeff = csc_coeffs.y2r.r601.full.coeff;
}
} else if (v4l2_is_format_rgb(src_finfo) &&
v4l2_is_format_yuv(dst_finfo)) {
/* R2Y */
/*
* These are not the standard default values but are
* set this way for historical compatibility
*/
if (dst_ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
dst_ycbcr_enc = V4L2_YCBCR_ENC_601;
if (dst_quantization == V4L2_QUANTIZATION_DEFAULT)
dst_quantization = V4L2_QUANTIZATION_FULL_RANGE;
if (dst_ycbcr_enc == V4L2_YCBCR_ENC_601) {
if (dst_quantization == V4L2_QUANTIZATION_FULL_RANGE)
coeff = csc_coeffs.r2y.r601.full.coeff;
else
coeff = csc_coeffs.r2y.r601.limited.coeff;
} else if (dst_ycbcr_enc == V4L2_YCBCR_ENC_709) {
if (dst_quantization == V4L2_QUANTIZATION_FULL_RANGE)
coeff = csc_coeffs.r2y.r709.full.coeff;
else
coeff = csc_coeffs.r2y.r709.limited.coeff;
} else {
/* Should never reach this, but it keeps gcc happy */
coeff = csc_coeffs.r2y.r601.full.coeff;
}
} else {
*csc_reg5 |= CSC_BYPASS;
return;
}
end_coeff = coeff + 12;
for (; coeff < end_coeff; coeff += 2)
*shadow_csc++ = (*(coeff + 1) << 16) | *coeff;
}
EXPORT_SYMBOL(csc_set_coeff);
struct csc_data *csc_create(struct platform_device *pdev, const char *res_name)
{
struct csc_data *csc;
dev_dbg(&pdev->dev, "csc_create\n");
csc = devm_kzalloc(&pdev->dev, sizeof(*csc), GFP_KERNEL);
if (!csc) {
dev_err(&pdev->dev, "couldn't alloc csc_data\n");
return ERR_PTR(-ENOMEM);
}
csc->pdev = pdev;
csc->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
res_name);
if (csc->res == NULL) {
dev_err(&pdev->dev, "missing '%s' platform resources data\n",
res_name);
return ERR_PTR(-ENODEV);
}
csc->base = devm_ioremap_resource(&pdev->dev, csc->res);
if (IS_ERR(csc->base))
return ERR_CAST(csc->base);
return csc;
}
EXPORT_SYMBOL(csc_create);
MODULE_DESCRIPTION("TI VIP/VPE Color Space Converter");
MODULE_AUTHOR("Texas Instruments Inc.");
MODULE_LICENSE("GPL v2");
@@ -0,0 +1,65 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2013 Texas Instruments Inc.
*
* David Griego, <dagriego@biglakesoftware.com>
* Dale Farnsworth, <dale@farnsworth.org>
* Archit Taneja, <archit@ti.com>
*/
#ifndef TI_CSC_H
#define TI_CSC_H
/* VPE color space converter regs */
#define CSC_CSC00 0x00
#define CSC_A0_MASK 0x1fff
#define CSC_A0_SHIFT 0
#define CSC_B0_MASK 0x1fff
#define CSC_B0_SHIFT 16
#define CSC_CSC01 0x04
#define CSC_C0_MASK 0x1fff
#define CSC_C0_SHIFT 0
#define CSC_A1_MASK 0x1fff
#define CSC_A1_SHIFT 16
#define CSC_CSC02 0x08
#define CSC_B1_MASK 0x1fff
#define CSC_B1_SHIFT 0
#define CSC_C1_MASK 0x1fff
#define CSC_C1_SHIFT 16
#define CSC_CSC03 0x0c
#define CSC_A2_MASK 0x1fff
#define CSC_A2_SHIFT 0
#define CSC_B2_MASK 0x1fff
#define CSC_B2_SHIFT 16
#define CSC_CSC04 0x10
#define CSC_C2_MASK 0x1fff
#define CSC_C2_SHIFT 0
#define CSC_D0_MASK 0x0fff
#define CSC_D0_SHIFT 16
#define CSC_CSC05 0x14
#define CSC_D1_MASK 0x0fff
#define CSC_D1_SHIFT 0
#define CSC_D2_MASK 0x0fff
#define CSC_D2_SHIFT 16
#define CSC_BYPASS (1 << 28)
struct csc_data {
void __iomem *base;
struct resource *res;
struct platform_device *pdev;
};
void csc_dump_regs(struct csc_data *csc);
void csc_set_coeff_bypass(struct csc_data *csc, u32 *csc_reg5);
void csc_set_coeff(struct csc_data *csc, u32 *csc_reg0,
struct v4l2_format *src_fmt, struct v4l2_format *dst_fmt);
struct csc_data *csc_create(struct platform_device *pdev, const char *res_name);
#endif
@@ -0,0 +1,306 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Scaler library
*
* Copyright (c) 2013 Texas Instruments Inc.
*
* David Griego, <dagriego@biglakesoftware.com>
* Dale Farnsworth, <dale@farnsworth.org>
* Archit Taneja, <archit@ti.com>
*/
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include "sc.h"
#include "sc_coeff.h"
void sc_dump_regs(struct sc_data *sc)
{
struct device *dev = &sc->pdev->dev;
#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, \
ioread32(sc->base + CFG_##r))
dev_dbg(dev, "SC Registers @ %pa:\n", &sc->res->start);
DUMPREG(SC0);
DUMPREG(SC1);
DUMPREG(SC2);
DUMPREG(SC3);
DUMPREG(SC4);
DUMPREG(SC5);
DUMPREG(SC6);
DUMPREG(SC8);
DUMPREG(SC9);
DUMPREG(SC10);
DUMPREG(SC11);
DUMPREG(SC12);
DUMPREG(SC13);
DUMPREG(SC17);
DUMPREG(SC18);
DUMPREG(SC19);
DUMPREG(SC20);
DUMPREG(SC21);
DUMPREG(SC22);
DUMPREG(SC23);
DUMPREG(SC24);
DUMPREG(SC25);
#undef DUMPREG
}
EXPORT_SYMBOL(sc_dump_regs);
/*
* set the horizontal scaler coefficients according to the ratio of output to
* input widths, after accounting for up to two levels of decimation
*/
void sc_set_hs_coeffs(struct sc_data *sc, void *addr, unsigned int src_w,
unsigned int dst_w)
{
int sixteenths;
int idx;
int i, j;
u16 *coeff_h = addr;
const u16 *cp;
if (dst_w > src_w) {
idx = HS_UP_SCALE;
} else {
if ((dst_w << 1) < src_w)
dst_w <<= 1; /* first level decimation */
if ((dst_w << 1) < src_w)
dst_w <<= 1; /* second level decimation */
if (dst_w == src_w) {
idx = HS_LE_16_16_SCALE;
} else {
sixteenths = (dst_w << 4) / src_w;
if (sixteenths < 8)
sixteenths = 8;
idx = HS_LT_9_16_SCALE + sixteenths - 8;
}
}
cp = scaler_hs_coeffs[idx];
for (i = 0; i < SC_NUM_PHASES * 2; i++) {
for (j = 0; j < SC_H_NUM_TAPS; j++)
*coeff_h++ = *cp++;
/*
* for each phase, the scaler expects space for 8 coefficients
* in it's memory. For the horizontal scaler, we copy the first
* 7 coefficients and skip the last slot to move to the next
* row to hold coefficients for the next phase
*/
coeff_h += SC_NUM_TAPS_MEM_ALIGN - SC_H_NUM_TAPS;
}
sc->load_coeff_h = true;
}
EXPORT_SYMBOL(sc_set_hs_coeffs);
/*
* set the vertical scaler coefficients according to the ratio of output to
* input heights
*/
void sc_set_vs_coeffs(struct sc_data *sc, void *addr, unsigned int src_h,
unsigned int dst_h)
{
int sixteenths;
int idx;
int i, j;
u16 *coeff_v = addr;
const u16 *cp;
if (dst_h > src_h) {
idx = VS_UP_SCALE;
} else if (dst_h == src_h) {
idx = VS_1_TO_1_SCALE;
} else {
sixteenths = (dst_h << 4) / src_h;
if (sixteenths < 8)
sixteenths = 8;
idx = VS_LT_9_16_SCALE + sixteenths - 8;
}
cp = scaler_vs_coeffs[idx];
for (i = 0; i < SC_NUM_PHASES * 2; i++) {
for (j = 0; j < SC_V_NUM_TAPS; j++)
*coeff_v++ = *cp++;
/*
* for the vertical scaler, we copy the first 5 coefficients and
* skip the last 3 slots to move to the next row to hold
* coefficients for the next phase
*/
coeff_v += SC_NUM_TAPS_MEM_ALIGN - SC_V_NUM_TAPS;
}
sc->load_coeff_v = true;
}
EXPORT_SYMBOL(sc_set_vs_coeffs);
void sc_config_scaler(struct sc_data *sc, u32 *sc_reg0, u32 *sc_reg8,
u32 *sc_reg17, unsigned int src_w, unsigned int src_h,
unsigned int dst_w, unsigned int dst_h)
{
struct device *dev = &sc->pdev->dev;
u32 val;
int dcm_x, dcm_shift;
bool use_rav;
unsigned long lltmp;
u32 lin_acc_inc, lin_acc_inc_u;
u32 col_acc_offset;
u16 factor = 0;
int row_acc_init_rav = 0, row_acc_init_rav_b = 0;
u32 row_acc_inc = 0, row_acc_offset = 0, row_acc_offset_b = 0;
/*
* location of SC register in payload memory with respect to the first
* register in the mmr address data block
*/
u32 *sc_reg9 = sc_reg8 + 1;
u32 *sc_reg12 = sc_reg8 + 4;
u32 *sc_reg13 = sc_reg8 + 5;
u32 *sc_reg24 = sc_reg17 + 7;
val = sc_reg0[0];
/* clear all the features(they may get enabled elsewhere later) */
val &= ~(CFG_SELFGEN_FID | CFG_TRIM | CFG_ENABLE_SIN2_VER_INTP |
CFG_INTERLACE_I | CFG_DCM_4X | CFG_DCM_2X | CFG_AUTO_HS |
CFG_ENABLE_EV | CFG_USE_RAV | CFG_INVT_FID | CFG_SC_BYPASS |
CFG_INTERLACE_O | CFG_Y_PK_EN | CFG_HP_BYPASS | CFG_LINEAR);
if (src_w == dst_w && src_h == dst_h) {
val |= CFG_SC_BYPASS;
sc_reg0[0] = val;
return;
}
/* we only support linear scaling for now */
val |= CFG_LINEAR;
/* configure horizontal scaler */
/* enable 2X or 4X decimation */
dcm_x = src_w / dst_w;
if (dcm_x > 4) {
val |= CFG_DCM_4X;
dcm_shift = 2;
} else if (dcm_x > 2) {
val |= CFG_DCM_2X;
dcm_shift = 1;
} else {
dcm_shift = 0;
}
lltmp = dst_w - 1;
lin_acc_inc = div64_u64(((u64)(src_w >> dcm_shift) - 1) << 24, lltmp);
lin_acc_inc_u = 0;
col_acc_offset = 0;
dev_dbg(dev, "hs config: src_w = %d, dst_w = %d, decimation = %s, lin_acc_inc = %08x\n",
src_w, dst_w, dcm_shift == 2 ? "4x" :
(dcm_shift == 1 ? "2x" : "none"), lin_acc_inc);
/* configure vertical scaler */
/* use RAV for vertical scaler if vertical downscaling is > 4x */
if (dst_h < (src_h >> 2)) {
use_rav = true;
val |= CFG_USE_RAV;
} else {
use_rav = false;
}
if (use_rav) {
/* use RAV */
factor = (u16) ((dst_h << 10) / src_h);
row_acc_init_rav = factor + ((1 + factor) >> 1);
if (row_acc_init_rav >= 1024)
row_acc_init_rav -= 1024;
row_acc_init_rav_b = row_acc_init_rav +
(1 + (row_acc_init_rav >> 1)) -
(1024 >> 1);
if (row_acc_init_rav_b < 0) {
row_acc_init_rav_b += row_acc_init_rav;
row_acc_init_rav *= 2;
}
dev_dbg(dev, "vs config(RAV): src_h = %d, dst_h = %d, factor = %d, acc_init = %08x, acc_init_b = %08x\n",
src_h, dst_h, factor, row_acc_init_rav,
row_acc_init_rav_b);
} else {
/* use polyphase */
row_acc_inc = ((src_h - 1) << 16) / (dst_h - 1);
row_acc_offset = 0;
row_acc_offset_b = 0;
dev_dbg(dev, "vs config(POLY): src_h = %d, dst_h = %d,row_acc_inc = %08x\n",
src_h, dst_h, row_acc_inc);
}
sc_reg0[0] = val;
sc_reg0[1] = row_acc_inc;
sc_reg0[2] = row_acc_offset;
sc_reg0[3] = row_acc_offset_b;
sc_reg0[4] = ((lin_acc_inc_u & CFG_LIN_ACC_INC_U_MASK) <<
CFG_LIN_ACC_INC_U_SHIFT) | (dst_w << CFG_TAR_W_SHIFT) |
(dst_h << CFG_TAR_H_SHIFT);
sc_reg0[5] = (src_w << CFG_SRC_W_SHIFT) | (src_h << CFG_SRC_H_SHIFT);
sc_reg0[6] = (row_acc_init_rav_b << CFG_ROW_ACC_INIT_RAV_B_SHIFT) |
(row_acc_init_rav << CFG_ROW_ACC_INIT_RAV_SHIFT);
*sc_reg9 = lin_acc_inc;
*sc_reg12 = col_acc_offset << CFG_COL_ACC_OFFSET_SHIFT;
*sc_reg13 = factor;
*sc_reg24 = (src_w << CFG_ORG_W_SHIFT) | (src_h << CFG_ORG_H_SHIFT);
}
EXPORT_SYMBOL(sc_config_scaler);
struct sc_data *sc_create(struct platform_device *pdev, const char *res_name)
{
struct sc_data *sc;
dev_dbg(&pdev->dev, "sc_create\n");
sc = devm_kzalloc(&pdev->dev, sizeof(*sc), GFP_KERNEL);
if (!sc) {
dev_err(&pdev->dev, "couldn't alloc sc_data\n");
return ERR_PTR(-ENOMEM);
}
sc->pdev = pdev;
sc->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
if (!sc->res) {
dev_err(&pdev->dev, "missing '%s' platform resources data\n",
res_name);
return ERR_PTR(-ENODEV);
}
sc->base = devm_ioremap_resource(&pdev->dev, sc->res);
if (IS_ERR(sc->base))
return ERR_CAST(sc->base);
return sc;
}
EXPORT_SYMBOL(sc_create);
MODULE_DESCRIPTION("TI VIP/VPE Scaler");
MODULE_AUTHOR("Texas Instruments Inc.");
MODULE_LICENSE("GPL v2");
@@ -0,0 +1,208 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2013 Texas Instruments Inc.
*
* David Griego, <dagriego@biglakesoftware.com>
* Dale Farnsworth, <dale@farnsworth.org>
* Archit Taneja, <archit@ti.com>
*/
#ifndef TI_SC_H
#define TI_SC_H
/* Scaler regs */
#define CFG_SC0 0x0
#define CFG_INTERLACE_O (1 << 0)
#define CFG_LINEAR (1 << 1)
#define CFG_SC_BYPASS (1 << 2)
#define CFG_INVT_FID (1 << 3)
#define CFG_USE_RAV (1 << 4)
#define CFG_ENABLE_EV (1 << 5)
#define CFG_AUTO_HS (1 << 6)
#define CFG_DCM_2X (1 << 7)
#define CFG_DCM_4X (1 << 8)
#define CFG_HP_BYPASS (1 << 9)
#define CFG_INTERLACE_I (1 << 10)
#define CFG_ENABLE_SIN2_VER_INTP (1 << 11)
#define CFG_Y_PK_EN (1 << 14)
#define CFG_TRIM (1 << 15)
#define CFG_SELFGEN_FID (1 << 16)
#define CFG_SC1 0x4
#define CFG_ROW_ACC_INC_MASK 0x07ffffff
#define CFG_ROW_ACC_INC_SHIFT 0
#define CFG_SC2 0x08
#define CFG_ROW_ACC_OFFSET_MASK 0x0fffffff
#define CFG_ROW_ACC_OFFSET_SHIFT 0
#define CFG_SC3 0x0c
#define CFG_ROW_ACC_OFFSET_B_MASK 0x0fffffff
#define CFG_ROW_ACC_OFFSET_B_SHIFT 0
#define CFG_SC4 0x10
#define CFG_TAR_H_MASK 0x07ff
#define CFG_TAR_H_SHIFT 0
#define CFG_TAR_W_MASK 0x07ff
#define CFG_TAR_W_SHIFT 12
#define CFG_LIN_ACC_INC_U_MASK 0x07
#define CFG_LIN_ACC_INC_U_SHIFT 24
#define CFG_NLIN_ACC_INIT_U_MASK 0x07
#define CFG_NLIN_ACC_INIT_U_SHIFT 28
#define CFG_SC5 0x14
#define CFG_SRC_H_MASK 0x07ff
#define CFG_SRC_H_SHIFT 0
#define CFG_SRC_W_MASK 0x07ff
#define CFG_SRC_W_SHIFT 12
#define CFG_NLIN_ACC_INC_U_MASK 0x07
#define CFG_NLIN_ACC_INC_U_SHIFT 24
#define CFG_SC6 0x18
#define CFG_ROW_ACC_INIT_RAV_MASK 0x03ff
#define CFG_ROW_ACC_INIT_RAV_SHIFT 0
#define CFG_ROW_ACC_INIT_RAV_B_MASK 0x03ff
#define CFG_ROW_ACC_INIT_RAV_B_SHIFT 10
#define CFG_SC8 0x20
#define CFG_NLIN_LEFT_MASK 0x07ff
#define CFG_NLIN_LEFT_SHIFT 0
#define CFG_NLIN_RIGHT_MASK 0x07ff
#define CFG_NLIN_RIGHT_SHIFT 12
#define CFG_SC9 0x24
#define CFG_LIN_ACC_INC CFG_SC9
#define CFG_SC10 0x28
#define CFG_NLIN_ACC_INIT CFG_SC10
#define CFG_SC11 0x2c
#define CFG_NLIN_ACC_INC CFG_SC11
#define CFG_SC12 0x30
#define CFG_COL_ACC_OFFSET_MASK 0x01ffffff
#define CFG_COL_ACC_OFFSET_SHIFT 0
#define CFG_SC13 0x34
#define CFG_SC_FACTOR_RAV_MASK 0xff
#define CFG_SC_FACTOR_RAV_SHIFT 0
#define CFG_CHROMA_INTP_THR_MASK 0x03ff
#define CFG_CHROMA_INTP_THR_SHIFT 12
#define CFG_DELTA_CHROMA_THR_MASK 0x0f
#define CFG_DELTA_CHROMA_THR_SHIFT 24
#define CFG_SC17 0x44
#define CFG_EV_THR_MASK 0x03ff
#define CFG_EV_THR_SHIFT 12
#define CFG_DELTA_LUMA_THR_MASK 0x0f
#define CFG_DELTA_LUMA_THR_SHIFT 24
#define CFG_DELTA_EV_THR_MASK 0x0f
#define CFG_DELTA_EV_THR_SHIFT 28
#define CFG_SC18 0x48
#define CFG_HS_FACTOR_MASK 0x03ff
#define CFG_HS_FACTOR_SHIFT 0
#define CFG_CONF_DEFAULT_MASK 0x01ff
#define CFG_CONF_DEFAULT_SHIFT 16
#define CFG_SC19 0x4c
#define CFG_HPF_COEFF0_MASK 0xff
#define CFG_HPF_COEFF0_SHIFT 0
#define CFG_HPF_COEFF1_MASK 0xff
#define CFG_HPF_COEFF1_SHIFT 8
#define CFG_HPF_COEFF2_MASK 0xff
#define CFG_HPF_COEFF2_SHIFT 16
#define CFG_HPF_COEFF3_MASK 0xff
#define CFG_HPF_COEFF3_SHIFT 23
#define CFG_SC20 0x50
#define CFG_HPF_COEFF4_MASK 0xff
#define CFG_HPF_COEFF4_SHIFT 0
#define CFG_HPF_COEFF5_MASK 0xff
#define CFG_HPF_COEFF5_SHIFT 8
#define CFG_HPF_NORM_SHIFT_MASK 0x07
#define CFG_HPF_NORM_SHIFT_SHIFT 16
#define CFG_NL_LIMIT_MASK 0x1ff
#define CFG_NL_LIMIT_SHIFT 20
#define CFG_SC21 0x54
#define CFG_NL_LO_THR_MASK 0x01ff
#define CFG_NL_LO_THR_SHIFT 0
#define CFG_NL_LO_SLOPE_MASK 0xff
#define CFG_NL_LO_SLOPE_SHIFT 16
#define CFG_SC22 0x58
#define CFG_NL_HI_THR_MASK 0x01ff
#define CFG_NL_HI_THR_SHIFT 0
#define CFG_NL_HI_SLOPE_SH_MASK 0x07
#define CFG_NL_HI_SLOPE_SH_SHIFT 16
#define CFG_SC23 0x5c
#define CFG_GRADIENT_THR_MASK 0x07ff
#define CFG_GRADIENT_THR_SHIFT 0
#define CFG_GRADIENT_THR_RANGE_MASK 0x0f
#define CFG_GRADIENT_THR_RANGE_SHIFT 12
#define CFG_MIN_GY_THR_MASK 0xff
#define CFG_MIN_GY_THR_SHIFT 16
#define CFG_MIN_GY_THR_RANGE_MASK 0x0f
#define CFG_MIN_GY_THR_RANGE_SHIFT 28
#define CFG_SC24 0x60
#define CFG_ORG_H_MASK 0x07ff
#define CFG_ORG_H_SHIFT 0
#define CFG_ORG_W_MASK 0x07ff
#define CFG_ORG_W_SHIFT 16
#define CFG_SC25 0x64
#define CFG_OFF_H_MASK 0x07ff
#define CFG_OFF_H_SHIFT 0
#define CFG_OFF_W_MASK 0x07ff
#define CFG_OFF_W_SHIFT 16
/* number of phases supported by the polyphase scalers */
#define SC_NUM_PHASES 32
/* number of taps used by horizontal polyphase scaler */
#define SC_H_NUM_TAPS 7
/* number of taps used by vertical polyphase scaler */
#define SC_V_NUM_TAPS 5
/* number of taps expected by the scaler in it's coefficient memory */
#define SC_NUM_TAPS_MEM_ALIGN 8
/* Maximum frame width the scaler can handle (in pixels) */
#define SC_MAX_PIXEL_WIDTH 2047
/* Maximum frame height the scaler can handle (in lines) */
#define SC_MAX_PIXEL_HEIGHT 2047
/*
* coefficient memory size in bytes:
* num phases x num sets(luma and chroma) x num taps(aligned) x coeff size
*/
#define SC_COEF_SRAM_SIZE (SC_NUM_PHASES * 2 * SC_NUM_TAPS_MEM_ALIGN * 2)
struct sc_data {
void __iomem *base;
struct resource *res;
dma_addr_t loaded_coeff_h; /* loaded h coeffs in SC */
dma_addr_t loaded_coeff_v; /* loaded v coeffs in SC */
bool load_coeff_h; /* have new h SC coeffs */
bool load_coeff_v; /* have new v SC coeffs */
struct platform_device *pdev;
};
void sc_dump_regs(struct sc_data *sc);
void sc_set_hs_coeffs(struct sc_data *sc, void *addr, unsigned int src_w,
unsigned int dst_w);
void sc_set_vs_coeffs(struct sc_data *sc, void *addr, unsigned int src_h,
unsigned int dst_h);
void sc_config_scaler(struct sc_data *sc, u32 *sc_reg0, u32 *sc_reg8,
u32 *sc_reg17, unsigned int src_w, unsigned int src_h,
unsigned int dst_w, unsigned int dst_h);
struct sc_data *sc_create(struct platform_device *pdev, const char *res_name);
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,717 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* TI VIP capture driver
*
* Copyright (C) 2025 Texas Instruments Incorpated - http://www.ti.com/
* David Griego, <dagriego@biglakesoftware.com>
* Dale Farnsworth, <dale@farnsworth.org>
* Yemike Abhilash Chandra, <y-abhilashchandra@ti.com>
*/
#ifndef __TI_VIP_H
#define __TI_VIP_H
#include <linux/videodev2.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-core.h>
#include <media/videobuf2-dma-contig.h>
#include <media/videobuf2-memops.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-async.h>
#include "vpdma.h"
#include "vpdma_priv.h"
#include "sc.h"
#include "csc.h"
#define VIP_INSTANCE1 1
#define VIP_INSTANCE2 2
#define VIP_INSTANCE3 3
#define VIP_SLICE1 0
#define VIP_SLICE2 1
#define VIP_NUM_SLICES 2
/*
* Additional client identifiers used for VPDMA configuration descriptors
*/
#define VIP_SLICE1_CFD_SC_CLIENT 7
#define VIP_SLICE2_CFD_SC_CLIENT 8
#define VIP_PORTA 0
#define VIP_PORTB 1
#define VIP_NUM_PORTS 2
#define VIP_MAX_PLANES 2
#define VIP_LUMA 0
#define VIP_CHROMA 1
#define VIP_CAP_STREAMS_PER_PORT 16
#define VIP_VBI_STREAMS_PER_PORT 16
#define VIP_MAX_SUBDEV 5
#define VPDMA_FIRMWARE "vpdma-1b8.bin"
/*
* This value needs to be at least as large as the number of entry in
* vip_formats[].
* When vip_formats[] is modified make sure to adjust this value also.
*/
#define VIP_MAX_ACTIVE_FMT 16
/*
* Colorspace conversion unit can be in one of 3 modes:
* NA - Not Available on this port
* Y2R - Needed for YUV to RGB on this port
* R2Y - Needed for RGB to YUV on this port
*/
enum vip_csc_state {
VIP_CSC_NA = 0,
VIP_CSC_Y2R,
VIP_CSC_R2Y,
};
/* buffer for one video frame */
struct vip_buffer {
/* common v4l buffer stuff */
struct vb2_v4l2_buffer vb;
struct list_head list;
bool drop;
};
/*
* struct vip_fmt - VIP media bus format information
* @fourcc: V4L2 pixel format FCC identifier
* @code: V4L2 media bus format code
* @colorspace: V4L2 colorspace identifier
* @coplanar: 1 if unpacked Luma and Chroma, 0 otherwise (packed/interleaved)
* @vpdma_fmt: VPDMA data format per plane.
* @finfo: Cache v4l2_format_info for associated fourcc
*/
struct vip_fmt {
u32 fourcc;
u32 code;
u32 colorspace;
u8 coplanar;
const struct vpdma_data_format *vpdma_fmt[VIP_MAX_PLANES];
const struct v4l2_format_info *finfo;
};
/*
* The vip_parser_data structures contains the memory mapped
* info to access the parser registers.
*/
struct vip_parser_data {
void __iomem *base;
struct platform_device *pdev;
};
/*
* The vip_shared structure contains data that is shared by both
* the VIP1 and VIP2 slices.
*/
struct vip_shared {
struct list_head list;
void __iomem *base;
struct vpdma_data vpdma_data;
struct vpdma_data *vpdma;
struct v4l2_device v4l2_dev;
struct vip_dev *devs[VIP_NUM_SLICES];
struct v4l2_ctrl_handler ctrl_handler;
};
struct vip_ctrl_module {
struct regmap *syscon_pol;
u32 syscon_offset;
u32 syscon_bit_field[4];
};
/*
* There are two vip_dev structure, one for each vip slice: VIP1 & VIP2.
*/
struct vip_dev {
struct v4l2_device v4l2_dev;
struct platform_device *pdev;
struct vip_shared *shared;
struct vip_ctrl_module *syscon;
int instance_id;
int slice_id;
int num_ports; /* count of open ports */
struct mutex mutex;
/* protects access to stream buffer queues */
spinlock_t slock;
int irq;
void __iomem *base;
struct vip_port *ports[VIP_NUM_PORTS];
char name[16];
/* parser data handle */
struct vip_parser_data *parser;
/* scaler data handle */
struct sc_data *sc;
/* scaler port assignation */
int sc_assigned;
/* csc data handle */
struct csc_data *csc;
/* csc port assignation */
int csc_assigned;
};
/*
* There are two vip_port structures for each vip_dev, one for port A
* and one for port B.
*/
struct vip_port {
struct vip_dev *dev;
int port_id;
unsigned int flags;
struct v4l2_rect c_rect; /* crop rectangle */
struct v4l2_mbus_framefmt mbus_framefmt;
struct v4l2_mbus_framefmt try_mbus_framefmt;
char name[16];
struct vip_fmt *fmt; /* current format info */
/* Number of channels/streams configured */
int num_streams_configured;
int num_streams; /* count of open streams */
struct vip_stream *cap_streams[VIP_CAP_STREAMS_PER_PORT];
struct v4l2_async_notifier notifier;
struct v4l2_subdev *subdev;
struct v4l2_fwnode_endpoint endpoint;
struct vip_fmt *active_fmt[VIP_MAX_ACTIVE_FMT];
int num_active_fmt;
/* have new shadow reg values */
bool load_mmrs;
/* shadow reg addr/data block */
struct vpdma_buf mmr_adb;
/* h coeff buffer */
struct vpdma_buf sc_coeff_h;
/* v coeff buffer */
struct vpdma_buf sc_coeff_v;
/* Show if scaler resource is available on this port */
bool scaler;
/* Show the csc resource state on this port */
enum vip_csc_state csc;
};
/*
* When handling multiplexed video, there can be multiple streams for each
* port. The vip_stream structure holds per-stream data.
*/
struct vip_stream {
struct video_device *vfd;
struct vip_port *port;
int stream_id;
int list_num;
int vfl_type;
char name[16];
struct work_struct recovery_work;
int num_recovery;
enum v4l2_field field; /* current field */
unsigned int sequence; /* current frame/field seq */
enum v4l2_field sup_field; /* supported field value */
unsigned int width; /* frame width */
unsigned int height; /* frame height */
unsigned int bytesperline; /* bytes per line in memory */
unsigned int sizeimage; /* image size in memory */
struct list_head vidq; /* incoming vip_bufs queue */
struct list_head dropq; /* drop vip_bufs queue */
struct list_head post_bufs; /* vip_bufs to be DMAed */
/* Maintain a list of used channels - Needed for VPDMA cleanup */
int vpdma_channels[VPDMA_MAX_CHANNELS];
int vpdma_channels_to_abort[VPDMA_MAX_CHANNELS];
struct vpdma_desc_list desc_list; /* DMA descriptor list */
struct vpdma_dtd *write_desc;
/* next unused desc_list addr */
void *desc_next;
struct vb2_queue vb_vidq;
};
/*
* VIP Enumerations
*/
enum data_path_select {
ALL_FIELDS_DATA_SELECT = 0,
VIP_CSC_SRC_DATA_SELECT,
VIP_SC_SRC_DATA_SELECT,
VIP_RGB_SRC_DATA_SELECT,
VIP_RGB_OUT_LO_DATA_SELECT,
VIP_RGB_OUT_HI_DATA_SELECT,
VIP_CHR_DS_1_SRC_DATA_SELECT,
VIP_CHR_DS_2_SRC_DATA_SELECT,
VIP_MULTI_CHANNEL_DATA_SELECT,
VIP_CHR_DS_1_DATA_BYPASS,
VIP_CHR_DS_2_DATA_BYPASS,
};
enum data_interface_modes {
SINGLE_24B_INTERFACE = 0,
SINGLE_16B_INTERFACE = 1,
DUAL_8B_INTERFACE = 2,
};
enum sync_types {
EMBEDDED_SYNC_SINGLE_YUV422 = 0,
EMBEDDED_SYNC_2X_MULTIPLEXED_YUV422 = 1,
EMBEDDED_SYNC_4X_MULTIPLEXED_YUV422 = 2,
EMBEDDED_SYNC_LINE_MULTIPLEXED_YUV422 = 3,
DISCRETE_SYNC_SINGLE_YUV422 = 4,
EMBEDDED_SYNC_SINGLE_RGB_OR_YUV444 = 5,
DISCRETE_SYNC_SINGLE_RGB_24B = 10,
};
#define VIP_NOT_ASSIGNED -1
/*
* Register offsets and field selectors
*/
#define VIP_PID_FUNC 0xf02
#define VIP_PID 0x0000
#define VIP_PID_MINOR_MASK 0x3f
#define VIP_PID_MINOR_SHIFT 0
#define VIP_PID_CUSTOM_MASK 0x03
#define VIP_PID_CUSTOM_SHIFT 6
#define VIP_PID_MAJOR_MASK 0x07
#define VIP_PID_MAJOR_SHIFT 8
#define VIP_PID_RTL_MASK 0x1f
#define VIP_PID_RTL_SHIFT 11
#define VIP_PID_FUNC_MASK 0xfff
#define VIP_PID_FUNC_SHIFT 16
#define VIP_PID_SCHEME_MASK 0x03
#define VIP_PID_SCHEME_SHIFT 30
#define VIP_SYSCONFIG 0x0010
#define VIP_SYSCONFIG_IDLE_MASK 0x03
#define VIP_SYSCONFIG_IDLE_SHIFT 2
#define VIP_SYSCONFIG_STANDBY_MASK 0x03
#define VIP_SYSCONFIG_STANDBY_SHIFT 4
#define VIP_FORCE_IDLE_MODE 0
#define VIP_NO_IDLE_MODE 1
#define VIP_SMART_IDLE_MODE 2
#define VIP_SMART_IDLE_WAKEUP_MODE 3
#define VIP_FORCE_STANDBY_MODE 0
#define VIP_NO_STANDBY_MODE 1
#define VIP_SMART_STANDBY_MODE 2
#define VIP_SMART_STANDBY_WAKEUP_MODE 3
#define VIP_INTC_INTX_OFFSET 0x0020
#define VIP_INT0_STATUS0_RAW_SET 0x0020
#define VIP_INT0_STATUS0_RAW VIP_INT0_STATUS0_RAW_SET
#define VIP_INT0_STATUS0_CLR 0x0028
#define VIP_INT0_STATUS0 VIP_INT0_STATUS0_CLR
#define VIP_INT0_ENABLE0_SET 0x0030
#define VIP_INT0_ENABLE0 VIP_INT0_ENABLE0_SET
#define VIP_INT0_ENABLE0_CLR 0x0038
#define VIP_INT0_LIST0_COMPLETE BIT(0)
#define VIP_INT0_LIST0_NOTIFY BIT(1)
#define VIP_INT0_LIST1_COMPLETE BIT(2)
#define VIP_INT0_LIST1_NOTIFY BIT(3)
#define VIP_INT0_LIST2_COMPLETE BIT(4)
#define VIP_INT0_LIST2_NOTIFY BIT(5)
#define VIP_INT0_LIST3_COMPLETE BIT(6)
#define VIP_INT0_LIST3_NOTIFY BIT(7)
#define VIP_INT0_LIST4_COMPLETE BIT(8)
#define VIP_INT0_LIST4_NOTIFY BIT(9)
#define VIP_INT0_LIST5_COMPLETE BIT(10)
#define VIP_INT0_LIST5_NOTIFY BIT(11)
#define VIP_INT0_LIST6_COMPLETE BIT(12)
#define VIP_INT0_LIST6_NOTIFY BIT(13)
#define VIP_INT0_LIST7_COMPLETE BIT(14)
#define VIP_INT0_LIST7_NOTIFY BIT(15)
#define VIP_INT0_DESCRIPTOR BIT(16)
#define VIP_VIP1_PARSER_INT BIT(20)
#define VIP_VIP2_PARSER_INT BIT(21)
#define VIP_INT0_STATUS1_RAW_SET 0x0024
#define VIP_INT0_STATUS1_RAW VIP_INT0_STATUS0_RAW_SET
#define VIP_INT0_STATUS1_CLR 0x002c
#define VIP_INT0_STATUS1 VIP_INT0_STATUS0_CLR
#define VIP_INT0_ENABLE1_SET 0x0034
#define VIP_INT0_ENABLE1 VIP_INT0_ENABLE0_SET
#define VIP_INT0_ENABLE1_CLR 0x003c
#define VIP_INT0_ENABLE1_STAT 0x004c
#define VIP_INT0_CHANNEL_GROUP0 BIT(0)
#define VIP_INT0_CHANNEL_GROUP1 BIT(1)
#define VIP_INT0_CHANNEL_GROUP2 BIT(2)
#define VIP_INT0_CHANNEL_GROUP3 BIT(3)
#define VIP_INT0_CHANNEL_GROUP4 BIT(4)
#define VIP_INT0_CHANNEL_GROUP5 BIT(5)
#define VIP_INT0_CLIENT BIT(7)
#define VIP_VIP1_DS1_UV_ERROR_INT BIT(22)
#define VIP_VIP1_DS2_UV_ERROR_INT BIT(23)
#define VIP_VIP2_DS1_UV_ERROR_INT BIT(24)
#define VIP_VIP2_DS2_UV_ERROR_INT BIT(25)
#define VIP_INTC_E0I 0x00a0
#define VIP_CLK_ENABLE 0x0100
#define VIP_VPDMA_CLK_ENABLE BIT(0)
#define VIP_VIP1_DATA_PATH_CLK_ENABLE BIT(16)
#define VIP_VIP2_DATA_PATH_CLK_ENABLE BIT(17)
#define VIP_CLK_RESET 0x0104
#define VIP_VPDMA_RESET BIT(0)
#define VIP_VPDMA_CLK_RESET_MASK 0x1
#define VIP_VPDMA_CLK_RESET_SHIFT 0
#define VIP_DATA_PATH_CLK_RESET_MASK 0x1
#define VIP_VIP1_DATA_PATH_RESET_SHIFT 16
#define VIP_VIP2_DATA_PATH_RESET_SHIFT 17
#define VIP_VIP1_DATA_PATH_RESET BIT(16)
#define VIP_VIP2_DATA_PATH_RESET BIT(17)
#define VIP_VIP1_PARSER_RESET BIT(18)
#define VIP_VIP2_PARSER_RESET BIT(19)
#define VIP_VIP1_CSC_RESET BIT(20)
#define VIP_VIP2_CSC_RESET BIT(21)
#define VIP_VIP1_SC_RESET BIT(22)
#define VIP_VIP2_SC_RESET BIT(23)
#define VIP_VIP1_DS1_RESET BIT(25)
#define VIP_VIP2_DS1_RESET BIT(26)
#define VIP_VIP1_DS2_RESET BIT(27)
#define VIP_VIP2_DS2_RESET BIT(28)
#define VIP_MAIN_RESET BIT(31)
#define VIP_VIP1_DATA_PATH_SELECT 0x010c
#define VIP_VIP2_DATA_PATH_SELECT 0x0110
#define VIP_CSC_SRC_SELECT_MASK 0x07
#define VIP_CSC_SRC_SELECT_SHFT 0
#define VIP_SC_SRC_SELECT_MASK 0x07
#define VIP_SC_SRC_SELECT_SHFT 3
#define VIP_RGB_SRC_SELECT BIT(6)
#define VIP_RGB_OUT_LO_SRC_SELECT BIT(7)
#define VIP_RGB_OUT_HI_SRC_SELECT BIT(8)
#define VIP_DS1_SRC_SELECT_MASK 0x07
#define VIP_DS1_SRC_SELECT_SHFT 9
#define VIP_DS2_SRC_SELECT_MASK 0x07
#define VIP_DS2_SRC_SELECT_SHFT 12
#define VIP_MULTI_CHANNEL_SELECT BIT(15)
#define VIP_DS1_BYPASS BIT(16)
#define VIP_DS2_BYPASS BIT(17)
#define VIP_TESTPORT_B_SELECT BIT(26)
#define VIP_TESTPORT_A_SELECT BIT(27)
#define VIP_DATAPATH_SELECT_MASK 0x0f
#define VIP_DATAPATH_SELECT_SHFT 28
#define VIP_PARSER_MAIN_CFG 0x0000
#define VIP_DATA_INTERFACE_MODE_MASK 0x03
#define VIP_DATA_INTERFACE_MODE_SHFT 0
#define VIP_CLIP_BLANK BIT(4)
#define VIP_CLIP_ACTIVE BIT(5)
#define VIP_SLICE0_PARSER 0x5500
#define VIP_SLICE1_PARSER 0x5a00
#define VIP_PARSER_PORTA_0 0x0004
#define VIP_PARSER_PORTB_0 0x000c
#define VIP_SYNC_TYPE_MASK 0x0f
#define VIP_SYNC_TYPE_SHFT 0
#define VIP_CTRL_CHANNEL_SEL_MASK 0x03
#define VIP_CTRL_CHANNEL_SEL_SHFT 4
#define VIP_ASYNC_FIFO_WR BIT(6)
#define VIP_ASYNC_FIFO_RD BIT(7)
#define VIP_PORT_ENABLE BIT(8)
#define VIP_FID_POLARITY BIT(9)
#define VIP_PIXCLK_EDGE_POLARITY BIT(10)
#define VIP_HSYNC_POLARITY BIT(11)
#define VIP_VSYNC_POLARITY BIT(12)
#define VIP_ACTVID_POLARITY BIT(13)
#define VIP_FID_DETECT_MODE BIT(14)
#define VIP_USE_ACTVID_HSYNC_ONLY BIT(15)
#define VIP_FID_SKEW_PRECOUNT_MASK 0x3f
#define VIP_FID_SKEW_PRECOUNT_SHFT 16
#define VIP_DISCRETE_BASIC_MODE BIT(22)
#define VIP_SW_RESET BIT(23)
#define VIP_FID_SKEW_POSTCOUNT_MASK 0x3f
#define VIP_FID_SKEW_POSTCOUNT_SHFT 24
#define VIP_ANALYZER_2X4X_SRCNUM_POS BIT(30)
#define VIP_ANALYZER_FVH_ERR_COR_EN BIT(31)
#define VIP_PARSER_PORTA_1 0x0008
#define VIP_PARSER_PORTB_1 0x0010
#define VIP_SRC0_NUMLINES_MASK 0x0fff
#define VIP_SRC0_NUMLINES_SHFT 0
#define VIP_ANC_CHAN_SEL_8B_MASK 0x03
#define VIP_ANC_CHAN_SEL_8B_SHFT 13
#define VIP_SRC0_NUMPIX_MASK 0x0fff
#define VIP_SRC0_NUMPIX_SHFT 16
#define VIP_REPACK_SEL_MASK 0x07
#define VIP_REPACK_SEL_SHFT 28
#define VIP_PARSER_FIQ_MASK 0x0014
#define VIP_PARSER_FIQ_CLR 0x0018
#define VIP_PARSER_FIQ_STATUS 0x001c
#define VIP_PORTA_VDET BIT(0)
#define VIP_PORTB_VDET BIT(1)
#define VIP_PORTA_ASYNC_FIFO_OF BIT(2)
#define VIP_PORTB_ASYNC_FIFO_OF BIT(3)
#define VIP_PORTA_OUTPUT_FIFO_YUV BIT(4)
#define VIP_PORTA_OUTPUT_FIFO_ANC BIT(6)
#define VIP_PORTB_OUTPUT_FIFO_YUV BIT(7)
#define VIP_PORTB_OUTPUT_FIFO_ANC BIT(9)
#define VIP_PORTA_CONN BIT(10)
#define VIP_PORTA_DISCONN BIT(11)
#define VIP_PORTB_CONN BIT(12)
#define VIP_PORTB_DISCONN BIT(13)
#define VIP_PORTA_SRC0_SIZE BIT(14)
#define VIP_PORTB_SRC0_SIZE BIT(15)
#define VIP_PORTA_YUV_PROTO_VIOLATION BIT(16)
#define VIP_PORTA_ANC_PROTO_VIOLATION BIT(17)
#define VIP_PORTB_YUV_PROTO_VIOLATION BIT(18)
#define VIP_PORTB_ANC_PROTO_VIOLATION BIT(19)
#define VIP_PORTA_CFG_DISABLE_COMPLETE BIT(20)
#define VIP_PORTB_CFG_DISABLE_COMPLETE BIT(21)
#define VIP_PARSER_PORTA_SOURCE_FID 0x0020
#define VIP_PARSER_PORTA_ENCODER_FID 0x0024
#define VIP_PARSER_PORTB_SOURCE_FID 0x0028
#define VIP_PARSER_PORTB_ENCODER_FID 0x002c
#define VIP_PARSER_PORTA_SRC0_SIZE 0x0030
#define VIP_PARSER_PORTB_SRC0_SIZE 0x0070
#define VIP_SOURCE_HEIGHT_MASK 0x0fff
#define VIP_SOURCE_HEIGHT_SHFT 0
#define VIP_SOURCE_WIDTH_MASK 0x0fff
#define VIP_SOURCE_WIDTH_SHFT 16
#define VIP_PARSER_PORTA_VDET_VEC 0x00b0
#define VIP_PARSER_PORTB_VDET_VEC 0x00b4
#define VIP_PARSER_PORTA_EXTRA2 0x00b8
#define VIP_PARSER_PORTB_EXTRA2 0x00c8
#define VIP_ANC_SKIP_NUMPIX_MASK 0x0fff
#define VIP_ANC_SKIP_NUMPIX_SHFT 0
#define VIP_ANC_BYPASS BIT(15)
#define VIP_ANC_USE_NUMPIX_MASK 0x0fff
#define VIP_ANC_USE_NUMPIX_SHFT 16
#define VIP_ANC_TARGET_SRCNUM_MASK 0x0f
#define VIP_ANC_TARGET_SRCNUM_SHFT 28
#define VIP_PARSER_PORTA_EXTRA3 0x00bc
#define VIP_PARSER_PORTB_EXTRA3 0x00cc
#define VIP_ANC_SKIP_NUMLINES_MASK 0x0fff
#define VIP_ANC_SKIP_NUMLINES_SHFT 0
#define VIP_ANC_USE_NUMLINES_MASK 0x0fff
#define VIP_ANC_USE_NUMLINES_SHFT 16
#define VIP_PARSER_PORTA_EXTRA4 0x00c0
#define VIP_PARSER_PORTB_EXTRA4 0x00d0
#define VIP_ACT_SKIP_NUMPIX_MASK 0x0fff
#define VIP_ACT_SKIP_NUMPIX_SHFT 0
#define VIP_ACT_BYPASS BIT(15)
#define VIP_ACT_USE_NUMPIX_MASK 0x0fff
#define VIP_ACT_USE_NUMPIX_SHFT 16
#define VIP_ACT_TARGET_SRCNUM_MASK 0x0f
#define VIP_ACT_TARGET_SRCNUM_SHFT 28
#define VIP_PARSER_PORTA_EXTRA5 0x00c4
#define VIP_PARSER_PORTB_EXTRA5 0x00d4
#define VIP_ACT_SKIP_NUMLINES_MASK 0x0fff
#define VIP_ACT_SKIP_NUMLINES_SHFT 0
#define VIP_ACT_USE_NUMLINES_MASK 0x0fff
#define VIP_ACT_USE_NUMLINES_SHFT 16
#define VIP_PARSER_PORTA_EXTRA6 0x00d8
#define VIP_PARSER_PORTB_EXTRA6 0x00dc
#define VIP_ANC_SRCNUM_STOP_IMM_SHFT 0
#define VIP_YUV_SRCNUM_STOP_IMM_SHFT 16
#define VIP_SLICE0_CSC 0x5700
#define VIP_SLICE1_CSC 0x5c00
#define VIP_CSC_CSC00 0x0200
#define VIP_CSC_A0_MASK 0x1fff
#define VIP_CSC_A0_SHFT 0
#define VIP_CSC_B0_MASK 0x1fff
#define VIP_CSC_B0_SHFT 16
#define VIP_CSC_CSC01 0x0204
#define VIP_CSC_C0_MASK 0x1fff
#define VIP_CSC_C0_SHFT 0
#define VIP_CSC_A1_MASK 0x1fff
#define VIP_CSC_A1_SHFT 16
#define VIP_CSC_CSC02 0x0208
#define VIP_CSC_B1_MASK 0x1fff
#define VIP_CSC_B1_SHFT 0
#define VIP_CSC_C1_MASK 0x1fff
#define VIP_CSC_C1_SHFT 16
#define VIP_CSC_CSC03 0x020c
#define VIP_CSC_A2_MASK 0x1fff
#define VIP_CSC_A2_SHFT 0
#define VIP_CSC_B2_MASK 0x1fff
#define VIP_CSC_B2_SHFT 16
#define VIP_CSC_CSC04 0x0210
#define VIP_CSC_C2_MASK 0x1fff
#define VIP_CSC_C2_SHFT 0
#define VIP_CSC_D0_MASK 0x0fff
#define VIP_CSC_D0_SHFT 16
#define VIP_CSC_CSC05 0x0214
#define VIP_CSC_D1_MASK 0x0fff
#define VIP_CSC_D1_SHFT 0
#define VIP_CSC_D2_MASK 0x0fff
#define VIP_CSC_D2_SHFT 16
#define VIP_CSC_BYPASS BIT(28)
#define VIP_SLICE0_SC 0x5800
#define VIP_SLICE1_SC 0x5d00
#define VIP_SC_MP_SC0 0x0300
#define VIP_INTERLACE_O BIT(0)
#define VIP_LINEAR BIT(1)
#define VIP_SC_BYPASS BIT(2)
#define VIP_INVT_FID BIT(3)
#define VIP_USE_RAV BIT(4)
#define VIP_ENABLE_EV BIT(5)
#define VIP_AUTH_HS BIT(6)
#define VIP_DCM_2X BIT(7)
#define VIP_DCM_4X BIT(8)
#define VIP_HP_BYPASS BIT(9)
#define VIP_INTERLACE_I BIT(10)
#define VIP_ENABLE_SIN2_VER_INTP BIT(11)
#define VIP_Y_PK_EN BIT(14)
#define VIP_TRIM BIT(15)
#define VIP_SELFGEN_FID BIT(16)
#define VIP_SC_MP_SC1 0x0304
#define VIP_ROW_ACC_INC_MASK 0x07ffffff
#define VIP_ROW_ACC_INC_SHFT 0
#define VIP_SC_MP_SC2 0x0308
#define VIP_ROW_ACC_OFFSET_MASK 0x0fffffff
#define VIP_ROW_ACC_OFFSET_SHFT 0
#define VIP_SC_MP_SC3 0x030c
#define VIP_ROW_ACC_OFFSET_B_MASK 0x0fffffff
#define VIP_ROW_ACC_OFFSET_B_SHFT 0
#define VIP_SC_MP_SC4 0x0310
#define VIP_TAR_H_MASK 0x07ff
#define VIP_TAR_H_SHFT 0
#define VIP_TAR_W_MASK 0x07ff
#define VIP_TAR_W_SHFT 12
#define VIP_LIN_ACC_INC_U_MASK 0x07
#define VIP_LIN_ACC_INC_U_SHFT 24
#define VIP_NLIN_ACC_INIT_U_MASK 0x07
#define VIP_NLIN_ACC_INIT_U_SHFT 28
#define VIP_SC_MP_SC5 0x0314
#define VIP_SRC_H_MASK 0x03ff
#define VIP_SRC_H_SHFT 0
#define VIP_SRC_W_MASK 0x07ff
#define VIP_SRC_W_SHFT 12
#define VIP_NLIN_ACC_INC_U_MASK 0x07
#define VIP_NLIN_ACC_INC_U_SHFT 24
#define VIP_SC_MP_SC6 0x0318
#define VIP_ROW_ACC_INIT_RAV_MASK 0x03ff
#define VIP_ROW_ACC_INIT_RAV_SHFT 0
#define VIP_ROW_ACC_INIT_RAV_B_MASK 0x03ff
#define VIP_ROW_ACC_INIT_RAV_B_SHFT 10
#define VIP_SC_MP_SC8 0x0320
#define VIP_NLIN_LEFT_MASK 0x07ff
#define VIP_NLIN_LEFT_SHFT 0
#define VIP_NLIN_RIGHT_MASK 0x07ff
#define VIP_NLIN_RIGHT_SHFT 12
#define VIP_SC_MP_SC9 0x0324
#define VIP_LIN_ACC_INC VIP_SC_MP_SC9
#define VIP_SC_MP_SC10 0x0328
#define VIP_NLIN_ACC_INIT VIP_SC_MP_SC10
#define VIP_SC_MP_SC11 0x032c
#define VIP_NLIN_ACC_INC VIP_SC_MP_SC11
#define VIP_SC_MP_SC12 0x0330
#define VIP_COL_ACC_OFFSET_MASK 0x01ffffff
#define VIP_COL_ACC_OFFSET_SHFT 0
#define VIP_SC_MP_SC13 0x0334
#define VIP_SC_FACTOR_RAV_MASK 0x03ff
#define VIP_SC_FACTOR_RAV_SHFT 0
#define VIP_CHROMA_INTP_THR_MASK 0x03ff
#define VIP_CHROMA_INTP_THR_SHFT 12
#define VIP_DELTA_CHROMA_THR_MASK 0x0f
#define VIP_DELTA_CHROMA_THR_SHFT 24
#define VIP_SC_MP_SC17 0x0344
#define VIP_EV_THR_MASK 0x03ff
#define VIP_EV_THR_SHFT 12
#define VIP_DELTA_LUMA_THR_MASK 0x0f
#define VIP_DELTA_LUMA_THR_SHFT 24
#define VIP_DELTA_EV_THR_MASK 0x0f
#define VIP_DELTA_EV_THR_SHFT 28
#define VIP_SC_MP_SC18 0x0348
#define VIP_HS_FACTOR_MASK 0x03ff
#define VIP_HS_FACTOR_SHFT 0
#define VIP_CONF_DEFAULT_MASK 0x01ff
#define VIP_CONF_DEFAULT_SHFT 16
#define VIP_SC_MP_SC19 0x034c
#define VIP_HPF_COEFF0_MASK 0xff
#define VIP_HPF_COEFF0_SHFT 0
#define VIP_HPF_COEFF1_MASK 0xff
#define VIP_HPF_COEFF1_SHFT 8
#define VIP_HPF_COEFF2_MASK 0xff
#define VIP_HPF_COEFF2_SHFT 16
#define VIP_HPF_COEFF3_MASK 0xff
#define VIP_HPF_COEFF3_SHFT 23
#define VIP_SC_MP_SC20 0x0350
#define VIP_HPF_COEFF4_MASK 0xff
#define VIP_HPF_COEFF4_SHFT 0
#define VIP_HPF_COEFF5_MASK 0xff
#define VIP_HPF_COEFF5_SHFT 8
#define VIP_HPF_NORM_SHFT_MASK 0x07
#define VIP_HPF_NORM_SHFT_SHFT 16
#define VIP_NL_LIMIT_MASK 0x1ff
#define VIP_NL_LIMIT_SHFT 20
#define VIP_SC_MP_SC21 0x0354
#define VIP_NL_LO_THR_MASK 0x01ff
#define VIP_NL_LO_THR_SHFT 0
#define VIP_NL_LO_SLOPE_MASK 0xff
#define VIP_NL_LO_SLOPE_SHFT 16
#define VIP_SC_MP_SC22 0x0358
#define VIP_NL_HI_THR_MASK 0x01ff
#define VIP_NL_HI_THR_SHFT 0
#define VIP_NL_HI_SLOPE_SH_MASK 0x07
#define VIP_NL_HI_SLOPE_SH_SHFT 16
#define VIP_SC_MP_SC23 0x035c
#define VIP_GRADIENT_THR_MASK 0x07ff
#define VIP_GRADIENT_THR_SHFT 0
#define VIP_GRADIENT_THR_RANGE_MASK 0x0f
#define VIP_GRADIENT_THR_RANGE_SHFT 12
#define VIP_MIN_GY_THR_MASK 0xff
#define VIP_MIN_GY_THR_SHFT 16
#define VIP_MIN_GY_THR_RANGE_MASK 0x0f
#define VIP_MIN_GY_THR_RANGE_SHFT 28
#define VIP_SC_MP_SC24 0x0360
#define VIP_ORG_H_MASK 0x07ff
#define VIP_ORG_H_SHFT 0
#define VIP_ORG_W_MASK 0x07ff
#define VIP_ORG_W_SHFT 16
#define VIP_SC_MP_SC25 0x0364
#define VIP_OFF_H_MASK 0x07ff
#define VIP_OFF_H_SHFT 0
#define VIP_OFF_W_MASK 0x07ff
#define VIP_OFF_W_SHFT 16
#define VIP_VPDMA_BASE 0xd000
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,287 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2013 Texas Instruments Inc.
*
* David Griego, <dagriego@biglakesoftware.com>
* Dale Farnsworth, <dale@farnsworth.org>
* Archit Taneja, <archit@ti.com>
*/
#ifndef __TI_VPDMA_H_
#define __TI_VPDMA_H_
#define VPDMA_MAX_NUM_LIST 8
/*
* A vpdma_buf tracks the size, DMA address and mapping status of each
* driver DMA area.
*/
struct vpdma_buf {
void *addr;
dma_addr_t dma_addr;
size_t size;
bool mapped;
};
struct vpdma_desc_list {
struct vpdma_buf buf;
void *next;
int type;
};
struct vpdma_data {
void __iomem *base;
struct platform_device *pdev;
spinlock_t lock;
bool hwlist_used[VPDMA_MAX_NUM_LIST];
void *hwlist_priv[VPDMA_MAX_NUM_LIST];
/* callback to VPE driver when the firmware is loaded */
void (*cb)(struct platform_device *pdev);
};
enum vpdma_data_format_type {
VPDMA_DATA_FMT_TYPE_YUV,
VPDMA_DATA_FMT_TYPE_RGB,
VPDMA_DATA_FMT_TYPE_MISC,
};
struct vpdma_data_format {
enum vpdma_data_format_type type;
int data_type;
u8 depth;
};
#define VPDMA_DESC_ALIGN 16 /* 16-byte descriptor alignment */
#define VPDMA_STRIDE_ALIGN 16 /*
* line stride of source and dest
* buffers should be 16 byte aligned
*/
#define VPDMA_MAX_STRIDE 65520 /* Max line stride 16 byte aligned */
#define VPDMA_DTD_DESC_SIZE 32 /* 8 words */
#define VPDMA_CFD_CTD_DESC_SIZE 16 /* 4 words */
#define VPDMA_LIST_TYPE_NORMAL 0
#define VPDMA_LIST_TYPE_SELF_MODIFYING 1
#define VPDMA_LIST_TYPE_DOORBELL 2
enum vpdma_yuv_formats {
VPDMA_DATA_FMT_Y444 = 0,
VPDMA_DATA_FMT_Y422,
VPDMA_DATA_FMT_Y420,
VPDMA_DATA_FMT_C444,
VPDMA_DATA_FMT_C422,
VPDMA_DATA_FMT_C420,
VPDMA_DATA_FMT_CB420,
VPDMA_DATA_FMT_YCR422,
VPDMA_DATA_FMT_YC444,
VPDMA_DATA_FMT_CRY422,
VPDMA_DATA_FMT_CBY422,
VPDMA_DATA_FMT_YCB422,
};
enum vpdma_rgb_formats {
VPDMA_DATA_FMT_RGB565 = 0,
VPDMA_DATA_FMT_ARGB16_1555,
VPDMA_DATA_FMT_ARGB16,
VPDMA_DATA_FMT_RGBA16_5551,
VPDMA_DATA_FMT_RGBA16,
VPDMA_DATA_FMT_ARGB24,
VPDMA_DATA_FMT_RGB24,
VPDMA_DATA_FMT_ARGB32,
VPDMA_DATA_FMT_RGBA24,
VPDMA_DATA_FMT_RGBA32,
VPDMA_DATA_FMT_BGR565,
VPDMA_DATA_FMT_ABGR16_1555,
VPDMA_DATA_FMT_ABGR16,
VPDMA_DATA_FMT_BGRA16_5551,
VPDMA_DATA_FMT_BGRA16,
VPDMA_DATA_FMT_ABGR24,
VPDMA_DATA_FMT_BGR24,
VPDMA_DATA_FMT_ABGR32,
VPDMA_DATA_FMT_BGRA24,
VPDMA_DATA_FMT_BGRA32,
};
enum vpdma_raw_formats {
VPDMA_DATA_FMT_RAW8 = 0,
VPDMA_DATA_FMT_RAW16,
};
enum vpdma_misc_formats {
VPDMA_DATA_FMT_MV = 0,
};
extern const struct vpdma_data_format vpdma_yuv_fmts[];
extern const struct vpdma_data_format vpdma_rgb_fmts[];
extern const struct vpdma_data_format vpdma_raw_fmts[];
extern const struct vpdma_data_format vpdma_misc_fmts[];
enum vpdma_frame_start_event {
VPDMA_FSEVENT_HDMI_FID = 0,
VPDMA_FSEVENT_DVO2_FID,
VPDMA_FSEVENT_HDCOMP_FID,
VPDMA_FSEVENT_SD_FID,
VPDMA_FSEVENT_LM_FID0,
VPDMA_FSEVENT_LM_FID1,
VPDMA_FSEVENT_LM_FID2,
VPDMA_FSEVENT_CHANNEL_ACTIVE,
};
/* max width configurations */
enum vpdma_max_width {
MAX_OUT_WIDTH_UNLIMITED = 0,
MAX_OUT_WIDTH_REG1,
MAX_OUT_WIDTH_REG2,
MAX_OUT_WIDTH_REG3,
MAX_OUT_WIDTH_352,
MAX_OUT_WIDTH_768,
MAX_OUT_WIDTH_1280,
MAX_OUT_WIDTH_1920,
};
/* max height configurations */
enum vpdma_max_height {
MAX_OUT_HEIGHT_UNLIMITED = 0,
MAX_OUT_HEIGHT_REG1,
MAX_OUT_HEIGHT_REG2,
MAX_OUT_HEIGHT_REG3,
MAX_OUT_HEIGHT_288,
MAX_OUT_HEIGHT_576,
MAX_OUT_HEIGHT_720,
MAX_OUT_HEIGHT_1080,
};
/*
* VPDMA channel numbers
*/
enum vpdma_channel {
VPE_CHAN_LUMA1_IN,
VPE_CHAN_CHROMA1_IN,
VPE_CHAN_LUMA2_IN,
VPE_CHAN_CHROMA2_IN,
VPE_CHAN_LUMA3_IN,
VPE_CHAN_CHROMA3_IN,
VPE_CHAN_MV_IN,
VPE_CHAN_MV_OUT,
VPE_CHAN_LUMA_OUT,
VPE_CHAN_CHROMA_OUT,
VPE_CHAN_RGB_OUT,
};
#define VIP_CHAN_VIP2_OFFSET 70
#define VIP_CHAN_MULT_PORTB_OFFSET 16
#define VIP_CHAN_YUV_PORTB_OFFSET 2
#define VIP_CHAN_RGB_PORTB_OFFSET 1
#define VPDMA_MAX_CHANNELS 256
/* flags for VPDMA data descriptors */
#define VPDMA_DATA_ODD_LINE_SKIP (1 << 0)
#define VPDMA_DATA_EVEN_LINE_SKIP (1 << 1)
#define VPDMA_DATA_FRAME_1D (1 << 2)
#define VPDMA_DATA_MODE_TILED (1 << 3)
/*
* client identifiers used for configuration descriptors
*/
#define CFD_MMR_CLIENT 0
#define CFD_SC_CLIENT 4
/* Address data block header format */
struct vpdma_adb_hdr {
u32 offset;
u32 nwords;
u32 reserved0;
u32 reserved1;
};
/* helpers for creating ADB headers for config descriptors MMRs as client */
#define ADB_ADDR(dma_buf, str, fld) ((dma_buf)->addr + offsetof(str, fld))
#define MMR_ADB_ADDR(buf, str, fld) ADB_ADDR(&(buf), struct str, fld)
#define VPDMA_SET_MMR_ADB_HDR(buf, str, hdr, regs, offset_a) \
do { \
struct vpdma_adb_hdr *h; \
struct str *adb = NULL; \
h = MMR_ADB_ADDR(buf, str, hdr); \
h->offset = (offset_a); \
h->nwords = sizeof(adb->regs) >> 2; \
} while (0)
/* vpdma descriptor buffer allocation and management */
int vpdma_alloc_desc_buf(struct vpdma_buf *buf, size_t size);
void vpdma_free_desc_buf(struct vpdma_buf *buf);
int vpdma_map_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf);
void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf);
/* vpdma descriptor list funcs */
int vpdma_create_desc_list(struct vpdma_desc_list *list, size_t size, int type);
void vpdma_reset_desc_list(struct vpdma_desc_list *list);
void vpdma_free_desc_list(struct vpdma_desc_list *list);
int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list,
int list_num);
bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num);
void vpdma_update_dma_addr(struct vpdma_data *vpdma,
struct vpdma_desc_list *list, dma_addr_t dma_addr,
void *write_dtd, int drop, int idx);
/* VPDMA hardware list funcs */
int vpdma_hwlist_alloc(struct vpdma_data *vpdma, void *priv);
void *vpdma_hwlist_get_priv(struct vpdma_data *vpdma, int list_num);
void *vpdma_hwlist_release(struct vpdma_data *vpdma, int list_num);
/* helpers for creating vpdma descriptors */
void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client,
struct vpdma_buf *blk, u32 dest_offset);
void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client,
struct vpdma_buf *adb);
void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list,
enum vpdma_channel chan);
void vpdma_add_abort_channel_ctd(struct vpdma_desc_list *list,
int chan_num);
void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
int stride, const struct v4l2_rect *c_rect,
const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
int max_w, int max_h, enum vpdma_channel chan, u32 flags);
void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width,
int stride, const struct v4l2_rect *c_rect,
const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
int max_w, int max_h, int raw_vpdma_chan, u32 flags);
void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
int stride, const struct v4l2_rect *c_rect,
const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
enum vpdma_channel chan, int field, u32 flags, int frame_width,
int frame_height, int start_h, int start_v);
int vpdma_list_cleanup(struct vpdma_data *vpdma, int list_num,
int *channels, int size);
/* vpdma list interrupt management */
void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int irq_num,
int list_num, bool enable);
void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num,
int list_num);
unsigned int vpdma_get_list_stat(struct vpdma_data *vpdma, int irq_num);
unsigned int vpdma_get_list_mask(struct vpdma_data *vpdma, int irq_num);
/* vpdma client configuration */
void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode,
enum vpdma_channel chan);
void vpdma_set_frame_start_event(struct vpdma_data *vpdma,
enum vpdma_frame_start_event fs_event, enum vpdma_channel chan);
void vpdma_set_max_size(struct vpdma_data *vpdma, int reg_addr,
u32 width, u32 height);
void vpdma_set_bg_color(struct vpdma_data *vpdma,
struct vpdma_data_format *fmt, u32 color);
void vpdma_dump_regs(struct vpdma_data *vpdma);
/* initialize vpdma, passed with VPE's platform device pointer */
int vpdma_create(struct platform_device *pdev, struct vpdma_data *vpdma,
void (*cb)(struct platform_device *pdev));
/* load vpdma firmware*/
int vpdma_load_firmware(struct vpdma_data *vpdma);
#endif
@@ -0,0 +1,639 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2013 Texas Instruments Inc.
*
* David Griego, <dagriego@biglakesoftware.com>
* Dale Farnsworth, <dale@farnsworth.org>
* Archit Taneja, <archit@ti.com>
*/
#ifndef _TI_VPDMA_PRIV_H_
#define _TI_VPDMA_PRIV_H_
/*
* VPDMA Register offsets
*/
/* Top level */
#define VPDMA_PID 0x00
#define VPDMA_LIST_ADDR 0x04
#define VPDMA_LIST_ATTR 0x08
#define VPDMA_LIST_STAT_SYNC 0x0c
#define VPDMA_BG_RGB 0x18
#define VPDMA_BG_YUV 0x1c
#define VPDMA_SETUP 0x30
#define VPDMA_MAX_SIZE1 0x34
#define VPDMA_MAX_SIZE2 0x38
#define VPDMA_MAX_SIZE3 0x3c
#define VPDMA_MAX_SIZE_WIDTH_MASK 0xffff
#define VPDMA_MAX_SIZE_WIDTH_SHFT 16
#define VPDMA_MAX_SIZE_HEIGHT_MASK 0xffff
#define VPDMA_MAX_SIZE_HEIGHT_SHFT 0
/* Interrupts */
#define VPDMA_INT_CHAN_STAT(grp) (0x40 + grp * 8)
#define VPDMA_INT_CHAN_MASK(grp) (VPDMA_INT_CHAN_STAT(grp) + 4)
#define VPDMA_INT_CLIENT0_STAT 0x78
#define VPDMA_INT_CLIENT0_MASK 0x7c
#define VPDMA_INT_CLIENT1_STAT 0x80
#define VPDMA_INT_CLIENT1_MASK 0x84
#define VPDMA_INT_LIST0_STAT 0x88
#define VPDMA_INT_LIST0_MASK 0x8c
#define VPDMA_INTX_OFFSET 0x50
#define VPDMA_PERFMON(i) (0x200 + i * 4)
/* VIP/VPE client registers */
#define VPDMA_DEI_CHROMA1_CSTAT 0x0300
#define VPDMA_DEI_LUMA1_CSTAT 0x0304
#define VPDMA_DEI_LUMA2_CSTAT 0x0308
#define VPDMA_DEI_CHROMA2_CSTAT 0x030c
#define VPDMA_DEI_LUMA3_CSTAT 0x0310
#define VPDMA_DEI_CHROMA3_CSTAT 0x0314
#define VPDMA_DEI_MV_IN_CSTAT 0x0330
#define VPDMA_DEI_MV_OUT_CSTAT 0x033c
#define VPDMA_VIP_LO_Y_CSTAT 0x0388
#define VPDMA_VIP_LO_UV_CSTAT 0x038c
#define VPDMA_VIP_UP_Y_CSTAT 0x0390
#define VPDMA_VIP_UP_UV_CSTAT 0x0394
#define VPDMA_VPI_CTL_CSTAT 0x03d0
/* Reg field info for VPDMA_CLIENT_CSTAT registers */
#define VPDMA_CSTAT_LINE_MODE_MASK 0x03
#define VPDMA_CSTAT_LINE_MODE_SHIFT 8
#define VPDMA_CSTAT_FRAME_START_MASK 0xf
#define VPDMA_CSTAT_FRAME_START_SHIFT 10
#define VPDMA_LIST_NUM_MASK 0x07
#define VPDMA_LIST_NUM_SHFT 24
#define VPDMA_LIST_STOP_SHFT 20
#define VPDMA_LIST_RDY_MASK 0x01
#define VPDMA_LIST_RDY_SHFT 19
#define VPDMA_LIST_TYPE_MASK 0x03
#define VPDMA_LIST_TYPE_SHFT 16
#define VPDMA_LIST_SIZE_MASK 0xffff
/*
* The YUV data type definition below are taken from
* both the TRM and i839 Errata information.
* Use the correct data type considering byte
* reordering of components.
*
* Also since the single use of "C" in the 422 case
* to mean "Cr" (i.e. V component). It was decided
* to explicitly label them CR to remove any confusion.
* Bear in mind that the type label refer to the memory
* packed order (LSB - MSB).
*/
#define DATA_TYPE_Y444 0x0
#define DATA_TYPE_Y422 0x1
#define DATA_TYPE_Y420 0x2
#define DATA_TYPE_C444 0x4
#define DATA_TYPE_C422 0x5
#define DATA_TYPE_C420 0x6
#define DATA_TYPE_CB420 0x16
#define DATA_TYPE_YC444 0x8
#define DATA_TYPE_YCB422 0x7
#define DATA_TYPE_YCR422 0x17
#define DATA_TYPE_CBY422 0x27
#define DATA_TYPE_CRY422 0x37
/*
* The RGB data type definition below are defined
* to follow Errata i819.
* The initial values were taken from:
* VPDMA_data_type_mapping_v0.2vayu_c.pdf
* But some of the ARGB definition appeared to be wrong
* in the document also. As they would yield RGBA instead.
* They have been corrected based on experimentation.
*/
#define DATA_TYPE_RGB16_565 0x10
#define DATA_TYPE_ARGB_1555 0x13
#define DATA_TYPE_ARGB_4444 0x14
#define DATA_TYPE_RGBA_5551 0x11
#define DATA_TYPE_RGBA_4444 0x12
#define DATA_TYPE_ARGB24_6666 0x18
#define DATA_TYPE_RGB24_888 0x16
#define DATA_TYPE_ARGB32_8888 0x17
#define DATA_TYPE_RGBA24_6666 0x15
#define DATA_TYPE_RGBA32_8888 0x19
#define DATA_TYPE_BGR16_565 0x0
#define DATA_TYPE_ABGR_1555 0x3
#define DATA_TYPE_ABGR_4444 0x4
#define DATA_TYPE_BGRA_5551 0x1
#define DATA_TYPE_BGRA_4444 0x2
#define DATA_TYPE_ABGR24_6666 0x8
#define DATA_TYPE_BGR24_888 0x6
#define DATA_TYPE_ABGR32_8888 0x7
#define DATA_TYPE_BGRA24_6666 0x5
#define DATA_TYPE_BGRA32_8888 0x9
#define DATA_TYPE_MV 0x3
/* VPDMA channel numbers, some are common between VIP/VPE and appear twice */
#define VPE_CHAN_NUM_LUMA1_IN 0
#define VPE_CHAN_NUM_CHROMA1_IN 1
#define VPE_CHAN_NUM_LUMA2_IN 2
#define VPE_CHAN_NUM_CHROMA2_IN 3
#define VPE_CHAN_NUM_LUMA3_IN 4
#define VPE_CHAN_NUM_CHROMA3_IN 5
#define VPE_CHAN_NUM_MV_IN 12
#define VPE_CHAN_NUM_MV_OUT 15
#define VIP1_CHAN_NUM_MULT_PORT_A_SRC0 38
#define VIP1_CHAN_NUM_MULT_ANC_A_SRC0 70
#define VPE_CHAN_NUM_LUMA_OUT 102
#define VPE_CHAN_NUM_CHROMA_OUT 103
#define VIP1_CHAN_NUM_PORT_A_LUMA 102
#define VIP1_CHAN_NUM_PORT_A_CHROMA 103
#define VPE_CHAN_NUM_RGB_OUT 106
#define VIP1_CHAN_NUM_PORT_A_RGB 106
#define VIP1_CHAN_NUM_PORT_B_RGB 107
/*
* a VPDMA address data block payload for a configuration descriptor needs to
* have each sub block length as a multiple of 16 bytes. Therefore, the overall
* size of the payload also needs to be a multiple of 16 bytes. The sub block
* lengths should be ensured to be aligned by the VPDMA user.
*/
#define VPDMA_ADB_SIZE_ALIGN 0x0f
/*
* data transfer descriptor
*/
struct vpdma_dtd {
u32 type_ctl_stride;
union {
u32 xfer_length_height;
u32 w1;
};
u32 start_addr;
u32 pkt_ctl;
union {
u32 frame_width_height; /* inbound */
u32 desc_write_addr; /* outbound */
};
union {
u32 start_h_v; /* inbound */
u32 max_width_height; /* outbound */
};
u32 client_attr0;
u32 client_attr1;
};
/* Data Transfer Descriptor specifics */
#define DTD_NO_NOTIFY 0
#define DTD_NOTIFY 1
#define DTD_PKT_TYPE 0xa
#define DTD_DIR_IN 0
#define DTD_DIR_OUT 1
/* type_ctl_stride */
#define DTD_DATA_TYPE_MASK 0x3f
#define DTD_DATA_TYPE_SHFT 26
#define DTD_NOTIFY_MASK 0x01
#define DTD_NOTIFY_SHFT 25
#define DTD_FIELD_MASK 0x01
#define DTD_FIELD_SHFT 24
#define DTD_1D_MASK 0x01
#define DTD_1D_SHFT 23
#define DTD_EVEN_LINE_SKIP_MASK 0x01
#define DTD_EVEN_LINE_SKIP_SHFT 20
#define DTD_ODD_LINE_SKIP_MASK 0x01
#define DTD_ODD_LINE_SKIP_SHFT 16
#define DTD_LINE_STRIDE_MASK 0xffff
#define DTD_LINE_STRIDE_SHFT 0
/* xfer_length_height */
#define DTD_LINE_LENGTH_MASK 0xffff
#define DTD_LINE_LENGTH_SHFT 16
#define DTD_XFER_HEIGHT_MASK 0xffff
#define DTD_XFER_HEIGHT_SHFT 0
/* pkt_ctl */
#define DTD_PKT_TYPE_MASK 0x1f
#define DTD_PKT_TYPE_SHFT 27
#define DTD_MODE_MASK 0x01
#define DTD_MODE_SHFT 26
#define DTD_DIR_MASK 0x01
#define DTD_DIR_SHFT 25
#define DTD_CHAN_MASK 0x01ff
#define DTD_CHAN_SHFT 16
#define DTD_PRI_MASK 0x0f
#define DTD_PRI_SHFT 9
#define DTD_NEXT_CHAN_MASK 0x01ff
#define DTD_NEXT_CHAN_SHFT 0
/* frame_width_height */
#define DTD_FRAME_WIDTH_MASK 0xffff
#define DTD_FRAME_WIDTH_SHFT 16
#define DTD_FRAME_HEIGHT_MASK 0xffff
#define DTD_FRAME_HEIGHT_SHFT 0
/* start_h_v */
#define DTD_H_START_MASK 0xffff
#define DTD_H_START_SHFT 16
#define DTD_V_START_MASK 0xffff
#define DTD_V_START_SHFT 0
#define DTD_DESC_START_MASK 0xffffffe0
#define DTD_DESC_START_SHIFT 5
#define DTD_WRITE_DESC_MASK 0x01
#define DTD_WRITE_DESC_SHIFT 2
#define DTD_DROP_DATA_MASK 0x01
#define DTD_DROP_DATA_SHIFT 1
#define DTD_USE_DESC_MASK 0x01
#define DTD_USE_DESC_SHIFT 0
/* max_width_height */
#define DTD_MAX_WIDTH_MASK 0x07
#define DTD_MAX_WIDTH_SHFT 4
#define DTD_MAX_HEIGHT_MASK 0x07
#define DTD_MAX_HEIGHT_SHFT 0
static inline u32 dtd_type_ctl_stride(int type, bool notify, int field,
bool one_d, bool even_line_skip, bool odd_line_skip,
int line_stride)
{
return (type << DTD_DATA_TYPE_SHFT) | (notify << DTD_NOTIFY_SHFT) |
(field << DTD_FIELD_SHFT) | (one_d << DTD_1D_SHFT) |
(even_line_skip << DTD_EVEN_LINE_SKIP_SHFT) |
(odd_line_skip << DTD_ODD_LINE_SKIP_SHFT) |
line_stride;
}
static inline u32 dtd_xfer_length_height(int line_length, int xfer_height)
{
return (line_length << DTD_LINE_LENGTH_SHFT) | xfer_height;
}
static inline u32 dtd_pkt_ctl(bool mode, bool dir, int chan, int pri,
int next_chan)
{
return (DTD_PKT_TYPE << DTD_PKT_TYPE_SHFT) | (mode << DTD_MODE_SHFT) |
(dir << DTD_DIR_SHFT) | (chan << DTD_CHAN_SHFT) |
(pri << DTD_PRI_SHFT) | next_chan;
}
static inline u32 dtd_frame_width_height(int width, int height)
{
return (width << DTD_FRAME_WIDTH_SHFT) | height;
}
static inline u32 dtd_desc_write_addr(unsigned int addr, bool write_desc,
bool drop_data, bool use_desc)
{
return (addr & DTD_DESC_START_MASK) |
(write_desc << DTD_WRITE_DESC_SHIFT) |
(drop_data << DTD_DROP_DATA_SHIFT) |
use_desc;
}
static inline u32 dtd_start_h_v(int h_start, int v_start)
{
return (h_start << DTD_H_START_SHFT) | v_start;
}
static inline u32 dtd_max_width_height(int max_width, int max_height)
{
return (max_width << DTD_MAX_WIDTH_SHFT) | max_height;
}
static inline int dtd_get_data_type(struct vpdma_dtd *dtd)
{
return dtd->type_ctl_stride >> DTD_DATA_TYPE_SHFT;
}
static inline bool dtd_get_notify(struct vpdma_dtd *dtd)
{
return (dtd->type_ctl_stride >> DTD_NOTIFY_SHFT) & DTD_NOTIFY_MASK;
}
static inline int dtd_get_field(struct vpdma_dtd *dtd)
{
return (dtd->type_ctl_stride >> DTD_FIELD_SHFT) & DTD_FIELD_MASK;
}
static inline bool dtd_get_1d(struct vpdma_dtd *dtd)
{
return (dtd->type_ctl_stride >> DTD_1D_SHFT) & DTD_1D_MASK;
}
static inline bool dtd_get_even_line_skip(struct vpdma_dtd *dtd)
{
return (dtd->type_ctl_stride >> DTD_EVEN_LINE_SKIP_SHFT)
& DTD_EVEN_LINE_SKIP_MASK;
}
static inline bool dtd_get_odd_line_skip(struct vpdma_dtd *dtd)
{
return (dtd->type_ctl_stride >> DTD_ODD_LINE_SKIP_SHFT)
& DTD_ODD_LINE_SKIP_MASK;
}
static inline int dtd_get_line_stride(struct vpdma_dtd *dtd)
{
return dtd->type_ctl_stride & DTD_LINE_STRIDE_MASK;
}
static inline int dtd_get_line_length(struct vpdma_dtd *dtd)
{
return dtd->xfer_length_height >> DTD_LINE_LENGTH_SHFT;
}
static inline int dtd_get_xfer_height(struct vpdma_dtd *dtd)
{
return dtd->xfer_length_height & DTD_XFER_HEIGHT_MASK;
}
static inline int dtd_get_pkt_type(struct vpdma_dtd *dtd)
{
return dtd->pkt_ctl >> DTD_PKT_TYPE_SHFT;
}
static inline bool dtd_get_mode(struct vpdma_dtd *dtd)
{
return (dtd->pkt_ctl >> DTD_MODE_SHFT) & DTD_MODE_MASK;
}
static inline bool dtd_get_dir(struct vpdma_dtd *dtd)
{
return (dtd->pkt_ctl >> DTD_DIR_SHFT) & DTD_DIR_MASK;
}
static inline int dtd_get_chan(struct vpdma_dtd *dtd)
{
return (dtd->pkt_ctl >> DTD_CHAN_SHFT) & DTD_CHAN_MASK;
}
static inline int dtd_get_priority(struct vpdma_dtd *dtd)
{
return (dtd->pkt_ctl >> DTD_PRI_SHFT) & DTD_PRI_MASK;
}
static inline int dtd_get_next_chan(struct vpdma_dtd *dtd)
{
return (dtd->pkt_ctl >> DTD_NEXT_CHAN_SHFT) & DTD_NEXT_CHAN_MASK;
}
static inline int dtd_get_frame_width(struct vpdma_dtd *dtd)
{
return dtd->frame_width_height >> DTD_FRAME_WIDTH_SHFT;
}
static inline int dtd_get_frame_height(struct vpdma_dtd *dtd)
{
return dtd->frame_width_height & DTD_FRAME_HEIGHT_MASK;
}
static inline int dtd_get_desc_write_addr(struct vpdma_dtd *dtd)
{
return dtd->desc_write_addr & DTD_DESC_START_MASK;
}
static inline bool dtd_get_write_desc(struct vpdma_dtd *dtd)
{
return (dtd->desc_write_addr >> DTD_WRITE_DESC_SHIFT) &
DTD_WRITE_DESC_MASK;
}
static inline bool dtd_get_drop_data(struct vpdma_dtd *dtd)
{
return (dtd->desc_write_addr >> DTD_DROP_DATA_SHIFT) &
DTD_DROP_DATA_MASK;
}
static inline bool dtd_get_use_desc(struct vpdma_dtd *dtd)
{
return dtd->desc_write_addr & DTD_USE_DESC_MASK;
}
static inline int dtd_get_h_start(struct vpdma_dtd *dtd)
{
return dtd->start_h_v >> DTD_H_START_SHFT;
}
static inline int dtd_get_v_start(struct vpdma_dtd *dtd)
{
return dtd->start_h_v & DTD_V_START_MASK;
}
static inline int dtd_get_max_width(struct vpdma_dtd *dtd)
{
return (dtd->max_width_height >> DTD_MAX_WIDTH_SHFT) &
DTD_MAX_WIDTH_MASK;
}
static inline int dtd_get_max_height(struct vpdma_dtd *dtd)
{
return (dtd->max_width_height >> DTD_MAX_HEIGHT_SHFT) &
DTD_MAX_HEIGHT_MASK;
}
/*
* configuration descriptor
*/
struct vpdma_cfd {
union {
u32 dest_addr_offset;
u32 w0;
};
union {
u32 block_len; /* in words */
u32 w1;
};
u32 payload_addr;
u32 ctl_payload_len; /* in words */
};
/* Configuration descriptor specifics */
#define CFD_PKT_TYPE 0xb
#define CFD_DIRECT 1
#define CFD_INDIRECT 0
#define CFD_CLS_ADB 0
#define CFD_CLS_BLOCK 1
/* block_len */
#define CFD__BLOCK_LEN_MASK 0xffff
#define CFD__BLOCK_LEN_SHFT 0
/* ctl_payload_len */
#define CFD_PKT_TYPE_MASK 0x1f
#define CFD_PKT_TYPE_SHFT 27
#define CFD_DIRECT_MASK 0x01
#define CFD_DIRECT_SHFT 26
#define CFD_CLASS_MASK 0x03
#define CFD_CLASS_SHFT 24
#define CFD_DEST_MASK 0xff
#define CFD_DEST_SHFT 16
#define CFD_PAYLOAD_LEN_MASK 0xffff
#define CFD_PAYLOAD_LEN_SHFT 0
static inline u32 cfd_pkt_payload_len(bool direct, int cls, int dest,
int payload_len)
{
return (CFD_PKT_TYPE << CFD_PKT_TYPE_SHFT) |
(direct << CFD_DIRECT_SHFT) |
(cls << CFD_CLASS_SHFT) |
(dest << CFD_DEST_SHFT) |
payload_len;
}
static inline int cfd_get_pkt_type(struct vpdma_cfd *cfd)
{
return cfd->ctl_payload_len >> CFD_PKT_TYPE_SHFT;
}
static inline bool cfd_get_direct(struct vpdma_cfd *cfd)
{
return (cfd->ctl_payload_len >> CFD_DIRECT_SHFT) & CFD_DIRECT_MASK;
}
static inline bool cfd_get_class(struct vpdma_cfd *cfd)
{
return (cfd->ctl_payload_len >> CFD_CLASS_SHFT) & CFD_CLASS_MASK;
}
static inline int cfd_get_dest(struct vpdma_cfd *cfd)
{
return (cfd->ctl_payload_len >> CFD_DEST_SHFT) & CFD_DEST_MASK;
}
static inline int cfd_get_payload_len(struct vpdma_cfd *cfd)
{
return cfd->ctl_payload_len & CFD_PAYLOAD_LEN_MASK;
}
/*
* control descriptor
*/
struct vpdma_ctd {
union {
u32 timer_value;
u32 list_addr;
u32 w0;
};
union {
u32 pixel_line_count;
u32 list_size;
u32 w1;
};
union {
u32 event;
u32 fid_ctl;
u32 w2;
};
u32 type_source_ctl;
};
/* control descriptor types */
#define CTD_TYPE_SYNC_ON_CLIENT 0
#define CTD_TYPE_SYNC_ON_LIST 1
#define CTD_TYPE_SYNC_ON_EXT 2
#define CTD_TYPE_SYNC_ON_LM_TIMER 3
#define CTD_TYPE_SYNC_ON_CHANNEL 4
#define CTD_TYPE_CHNG_CLIENT_IRQ 5
#define CTD_TYPE_SEND_IRQ 6
#define CTD_TYPE_RELOAD_LIST 7
#define CTD_TYPE_ABORT_CHANNEL 8
#define CTD_PKT_TYPE 0xc
/* timer_value */
#define CTD_TIMER_VALUE_MASK 0xffff
#define CTD_TIMER_VALUE_SHFT 0
/* pixel_line_count */
#define CTD_PIXEL_COUNT_MASK 0xffff
#define CTD_PIXEL_COUNT_SHFT 16
#define CTD_LINE_COUNT_MASK 0xffff
#define CTD_LINE_COUNT_SHFT 0
/* list_size */
#define CTD_LIST_SIZE_MASK 0xffff
#define CTD_LIST_SIZE_SHFT 0
/* event */
#define CTD_EVENT_MASK 0x0f
#define CTD_EVENT_SHFT 0
/* fid_ctl */
#define CTD_FID2_MASK 0x03
#define CTD_FID2_SHFT 4
#define CTD_FID1_MASK 0x03
#define CTD_FID1_SHFT 2
#define CTD_FID0_MASK 0x03
#define CTD_FID0_SHFT 0
/* type_source_ctl */
#define CTD_PKT_TYPE_MASK 0x1f
#define CTD_PKT_TYPE_SHFT 27
#define CTD_SOURCE_MASK 0xff
#define CTD_SOURCE_SHFT 16
#define CTD_CONTROL_MASK 0x0f
#define CTD_CONTROL_SHFT 0
static inline u32 ctd_pixel_line_count(int pixel_count, int line_count)
{
return (pixel_count << CTD_PIXEL_COUNT_SHFT) | line_count;
}
static inline u32 ctd_set_fid_ctl(int fid0, int fid1, int fid2)
{
return (fid2 << CTD_FID2_SHFT) | (fid1 << CTD_FID1_SHFT) | fid0;
}
static inline u32 ctd_type_source_ctl(int source, int control)
{
return (CTD_PKT_TYPE << CTD_PKT_TYPE_SHFT) |
(source << CTD_SOURCE_SHFT) | control;
}
static inline u32 ctd_get_pixel_count(struct vpdma_ctd *ctd)
{
return ctd->pixel_line_count >> CTD_PIXEL_COUNT_SHFT;
}
static inline int ctd_get_line_count(struct vpdma_ctd *ctd)
{
return ctd->pixel_line_count & CTD_LINE_COUNT_MASK;
}
static inline int ctd_get_event(struct vpdma_ctd *ctd)
{
return ctd->event & CTD_EVENT_MASK;
}
static inline int ctd_get_fid2_ctl(struct vpdma_ctd *ctd)
{
return (ctd->fid_ctl >> CTD_FID2_SHFT) & CTD_FID2_MASK;
}
static inline int ctd_get_fid1_ctl(struct vpdma_ctd *ctd)
{
return (ctd->fid_ctl >> CTD_FID1_SHFT) & CTD_FID1_MASK;
}
static inline int ctd_get_fid0_ctl(struct vpdma_ctd *ctd)
{
return ctd->fid_ctl & CTD_FID2_MASK;
}
static inline int ctd_get_pkt_type(struct vpdma_ctd *ctd)
{
return ctd->type_source_ctl >> CTD_PKT_TYPE_SHFT;
}
static inline int ctd_get_source(struct vpdma_ctd *ctd)
{
return (ctd->type_source_ctl >> CTD_SOURCE_SHFT) & CTD_SOURCE_MASK;
}
static inline int ctd_get_ctl(struct vpdma_ctd *ctd)
{
return ctd->type_source_ctl & CTD_CONTROL_MASK;
}
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,306 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2013 Texas Instruments Inc.
*
* David Griego, <dagriego@biglakesoftware.com>
* Dale Farnsworth, <dale@farnsworth.org>
* Archit Taneja, <archit@ti.com>
*/
#ifndef __TI_VPE_REGS_H
#define __TI_VPE_REGS_H
/* VPE register offsets and field selectors */
/* VPE top level regs */
#define VPE_PID 0x0000
#define VPE_PID_MINOR_MASK 0x3f
#define VPE_PID_MINOR_SHIFT 0
#define VPE_PID_CUSTOM_MASK 0x03
#define VPE_PID_CUSTOM_SHIFT 6
#define VPE_PID_MAJOR_MASK 0x07
#define VPE_PID_MAJOR_SHIFT 8
#define VPE_PID_RTL_MASK 0x1f
#define VPE_PID_RTL_SHIFT 11
#define VPE_PID_FUNC_MASK 0xfff
#define VPE_PID_FUNC_SHIFT 16
#define VPE_PID_SCHEME_MASK 0x03
#define VPE_PID_SCHEME_SHIFT 30
#define VPE_SYSCONFIG 0x0010
#define VPE_SYSCONFIG_IDLE_MASK 0x03
#define VPE_SYSCONFIG_IDLE_SHIFT 2
#define VPE_SYSCONFIG_STANDBY_MASK 0x03
#define VPE_SYSCONFIG_STANDBY_SHIFT 4
#define VPE_FORCE_IDLE_MODE 0
#define VPE_NO_IDLE_MODE 1
#define VPE_SMART_IDLE_MODE 2
#define VPE_SMART_IDLE_WAKEUP_MODE 3
#define VPE_FORCE_STANDBY_MODE 0
#define VPE_NO_STANDBY_MODE 1
#define VPE_SMART_STANDBY_MODE 2
#define VPE_SMART_STANDBY_WAKEUP_MODE 3
#define VPE_INT0_STATUS0_RAW_SET 0x0020
#define VPE_INT0_STATUS0_RAW VPE_INT0_STATUS0_RAW_SET
#define VPE_INT0_STATUS0_CLR 0x0028
#define VPE_INT0_STATUS0 VPE_INT0_STATUS0_CLR
#define VPE_INT0_ENABLE0_SET 0x0030
#define VPE_INT0_ENABLE0 VPE_INT0_ENABLE0_SET
#define VPE_INT0_ENABLE0_CLR 0x0038
#define VPE_INT0_LIST0_COMPLETE BIT(0)
#define VPE_INT0_LIST0_NOTIFY BIT(1)
#define VPE_INT0_LIST1_COMPLETE BIT(2)
#define VPE_INT0_LIST1_NOTIFY BIT(3)
#define VPE_INT0_LIST2_COMPLETE BIT(4)
#define VPE_INT0_LIST2_NOTIFY BIT(5)
#define VPE_INT0_LIST3_COMPLETE BIT(6)
#define VPE_INT0_LIST3_NOTIFY BIT(7)
#define VPE_INT0_LIST4_COMPLETE BIT(8)
#define VPE_INT0_LIST4_NOTIFY BIT(9)
#define VPE_INT0_LIST5_COMPLETE BIT(10)
#define VPE_INT0_LIST5_NOTIFY BIT(11)
#define VPE_INT0_LIST6_COMPLETE BIT(12)
#define VPE_INT0_LIST6_NOTIFY BIT(13)
#define VPE_INT0_LIST7_COMPLETE BIT(14)
#define VPE_INT0_LIST7_NOTIFY BIT(15)
#define VPE_INT0_DESCRIPTOR BIT(16)
#define VPE_DEI_FMD_INT BIT(18)
#define VPE_INT0_STATUS1_RAW_SET 0x0024
#define VPE_INT0_STATUS1_RAW VPE_INT0_STATUS1_RAW_SET
#define VPE_INT0_STATUS1_CLR 0x002c
#define VPE_INT0_STATUS1 VPE_INT0_STATUS1_CLR
#define VPE_INT0_ENABLE1_SET 0x0034
#define VPE_INT0_ENABLE1 VPE_INT0_ENABLE1_SET
#define VPE_INT0_ENABLE1_CLR 0x003c
#define VPE_INT0_CHANNEL_GROUP0 BIT(0)
#define VPE_INT0_CHANNEL_GROUP1 BIT(1)
#define VPE_INT0_CHANNEL_GROUP2 BIT(2)
#define VPE_INT0_CHANNEL_GROUP3 BIT(3)
#define VPE_INT0_CHANNEL_GROUP4 BIT(4)
#define VPE_INT0_CHANNEL_GROUP5 BIT(5)
#define VPE_INT0_CLIENT BIT(7)
#define VPE_DEI_ERROR_INT BIT(16)
#define VPE_DS1_UV_ERROR_INT BIT(22)
#define VPE_INTC_EOI 0x00a0
#define VPE_CLK_ENABLE 0x0100
#define VPE_VPEDMA_CLK_ENABLE BIT(0)
#define VPE_DATA_PATH_CLK_ENABLE BIT(1)
#define VPE_CLK_RESET 0x0104
#define VPE_VPDMA_CLK_RESET_MASK 0x1
#define VPE_VPDMA_CLK_RESET_SHIFT 0
#define VPE_DATA_PATH_CLK_RESET_MASK 0x1
#define VPE_DATA_PATH_CLK_RESET_SHIFT 1
#define VPE_MAIN_RESET_MASK 0x1
#define VPE_MAIN_RESET_SHIFT 31
#define VPE_CLK_FORMAT_SELECT 0x010c
#define VPE_CSC_SRC_SELECT_MASK 0x03
#define VPE_CSC_SRC_SELECT_SHIFT 0
#define VPE_RGB_OUT_SELECT BIT(8)
#define VPE_DS_SRC_SELECT_MASK 0x07
#define VPE_DS_SRC_SELECT_SHIFT 9
#define VPE_DS_BYPASS BIT(16)
#define VPE_COLOR_SEPARATE_422 BIT(18)
#define VPE_DS_SRC_DEI_SCALER (5 << VPE_DS_SRC_SELECT_SHIFT)
#define VPE_CSC_SRC_DEI_SCALER (3 << VPE_CSC_SRC_SELECT_SHIFT)
#define VPE_CLK_RANGE_MAP 0x011c
#define VPE_RANGE_RANGE_MAP_Y_MASK 0x07
#define VPE_RANGE_RANGE_MAP_Y_SHIFT 0
#define VPE_RANGE_RANGE_MAP_UV_MASK 0x07
#define VPE_RANGE_RANGE_MAP_UV_SHIFT 3
#define VPE_RANGE_MAP_ON BIT(6)
#define VPE_RANGE_REDUCTION_ON BIT(28)
/* VPE chrominance upsampler regs */
#define VPE_US1_R0 0x0304
#define VPE_US2_R0 0x0404
#define VPE_US3_R0 0x0504
#define VPE_US_C1_MASK 0x3fff
#define VPE_US_C1_SHIFT 2
#define VPE_US_C0_MASK 0x3fff
#define VPE_US_C0_SHIFT 18
#define VPE_US_MODE_MASK 0x03
#define VPE_US_MODE_SHIFT 16
#define VPE_ANCHOR_FID0_C1_MASK 0x3fff
#define VPE_ANCHOR_FID0_C1_SHIFT 2
#define VPE_ANCHOR_FID0_C0_MASK 0x3fff
#define VPE_ANCHOR_FID0_C0_SHIFT 18
#define VPE_US1_R1 0x0308
#define VPE_US2_R1 0x0408
#define VPE_US3_R1 0x0508
#define VPE_ANCHOR_FID0_C3_MASK 0x3fff
#define VPE_ANCHOR_FID0_C3_SHIFT 2
#define VPE_ANCHOR_FID0_C2_MASK 0x3fff
#define VPE_ANCHOR_FID0_C2_SHIFT 18
#define VPE_US1_R2 0x030c
#define VPE_US2_R2 0x040c
#define VPE_US3_R2 0x050c
#define VPE_INTERP_FID0_C1_MASK 0x3fff
#define VPE_INTERP_FID0_C1_SHIFT 2
#define VPE_INTERP_FID0_C0_MASK 0x3fff
#define VPE_INTERP_FID0_C0_SHIFT 18
#define VPE_US1_R3 0x0310
#define VPE_US2_R3 0x0410
#define VPE_US3_R3 0x0510
#define VPE_INTERP_FID0_C3_MASK 0x3fff
#define VPE_INTERP_FID0_C3_SHIFT 2
#define VPE_INTERP_FID0_C2_MASK 0x3fff
#define VPE_INTERP_FID0_C2_SHIFT 18
#define VPE_US1_R4 0x0314
#define VPE_US2_R4 0x0414
#define VPE_US3_R4 0x0514
#define VPE_ANCHOR_FID1_C1_MASK 0x3fff
#define VPE_ANCHOR_FID1_C1_SHIFT 2
#define VPE_ANCHOR_FID1_C0_MASK 0x3fff
#define VPE_ANCHOR_FID1_C0_SHIFT 18
#define VPE_US1_R5 0x0318
#define VPE_US2_R5 0x0418
#define VPE_US3_R5 0x0518
#define VPE_ANCHOR_FID1_C3_MASK 0x3fff
#define VPE_ANCHOR_FID1_C3_SHIFT 2
#define VPE_ANCHOR_FID1_C2_MASK 0x3fff
#define VPE_ANCHOR_FID1_C2_SHIFT 18
#define VPE_US1_R6 0x031c
#define VPE_US2_R6 0x041c
#define VPE_US3_R6 0x051c
#define VPE_INTERP_FID1_C1_MASK 0x3fff
#define VPE_INTERP_FID1_C1_SHIFT 2
#define VPE_INTERP_FID1_C0_MASK 0x3fff
#define VPE_INTERP_FID1_C0_SHIFT 18
#define VPE_US1_R7 0x0320
#define VPE_US2_R7 0x0420
#define VPE_US3_R7 0x0520
#define VPE_INTERP_FID0_C3_MASK 0x3fff
#define VPE_INTERP_FID0_C3_SHIFT 2
#define VPE_INTERP_FID0_C2_MASK 0x3fff
#define VPE_INTERP_FID0_C2_SHIFT 18
/* VPE de-interlacer regs */
#define VPE_DEI_FRAME_SIZE 0x0600
#define VPE_DEI_WIDTH_MASK 0x07ff
#define VPE_DEI_WIDTH_SHIFT 0
#define VPE_DEI_HEIGHT_MASK 0x07ff
#define VPE_DEI_HEIGHT_SHIFT 16
#define VPE_DEI_INTERLACE_BYPASS BIT(29)
#define VPE_DEI_FIELD_FLUSH BIT(30)
#define VPE_DEI_PROGRESSIVE BIT(31)
#define VPE_MDT_BYPASS 0x0604
#define VPE_MDT_TEMPMAX_BYPASS BIT(0)
#define VPE_MDT_SPATMAX_BYPASS BIT(1)
#define VPE_MDT_SF_THRESHOLD 0x0608
#define VPE_MDT_SF_SC_THR1_MASK 0xff
#define VPE_MDT_SF_SC_THR1_SHIFT 0
#define VPE_MDT_SF_SC_THR2_MASK 0xff
#define VPE_MDT_SF_SC_THR2_SHIFT 0
#define VPE_MDT_SF_SC_THR3_MASK 0xff
#define VPE_MDT_SF_SC_THR3_SHIFT 0
#define VPE_EDI_CONFIG 0x060c
#define VPE_EDI_INP_MODE_MASK 0x03
#define VPE_EDI_INP_MODE_SHIFT 0
#define VPE_EDI_ENABLE_3D BIT(2)
#define VPE_EDI_ENABLE_CHROMA_3D BIT(3)
#define VPE_EDI_CHROMA3D_COR_THR_MASK 0xff
#define VPE_EDI_CHROMA3D_COR_THR_SHIFT 8
#define VPE_EDI_DIR_COR_LOWER_THR_MASK 0xff
#define VPE_EDI_DIR_COR_LOWER_THR_SHIFT 16
#define VPE_EDI_COR_SCALE_FACTOR_MASK 0xff
#define VPE_EDI_COR_SCALE_FACTOR_SHIFT 23
#define VPE_DEI_EDI_LUT_R0 0x0610
#define VPE_EDI_LUT0_MASK 0x1f
#define VPE_EDI_LUT0_SHIFT 0
#define VPE_EDI_LUT1_MASK 0x1f
#define VPE_EDI_LUT1_SHIFT 8
#define VPE_EDI_LUT2_MASK 0x1f
#define VPE_EDI_LUT2_SHIFT 16
#define VPE_EDI_LUT3_MASK 0x1f
#define VPE_EDI_LUT3_SHIFT 24
#define VPE_DEI_EDI_LUT_R1 0x0614
#define VPE_EDI_LUT0_MASK 0x1f
#define VPE_EDI_LUT0_SHIFT 0
#define VPE_EDI_LUT1_MASK 0x1f
#define VPE_EDI_LUT1_SHIFT 8
#define VPE_EDI_LUT2_MASK 0x1f
#define VPE_EDI_LUT2_SHIFT 16
#define VPE_EDI_LUT3_MASK 0x1f
#define VPE_EDI_LUT3_SHIFT 24
#define VPE_DEI_EDI_LUT_R2 0x0618
#define VPE_EDI_LUT4_MASK 0x1f
#define VPE_EDI_LUT4_SHIFT 0
#define VPE_EDI_LUT5_MASK 0x1f
#define VPE_EDI_LUT5_SHIFT 8
#define VPE_EDI_LUT6_MASK 0x1f
#define VPE_EDI_LUT6_SHIFT 16
#define VPE_EDI_LUT7_MASK 0x1f
#define VPE_EDI_LUT7_SHIFT 24
#define VPE_DEI_EDI_LUT_R3 0x061c
#define VPE_EDI_LUT8_MASK 0x1f
#define VPE_EDI_LUT8_SHIFT 0
#define VPE_EDI_LUT9_MASK 0x1f
#define VPE_EDI_LUT9_SHIFT 8
#define VPE_EDI_LUT10_MASK 0x1f
#define VPE_EDI_LUT10_SHIFT 16
#define VPE_EDI_LUT11_MASK 0x1f
#define VPE_EDI_LUT11_SHIFT 24
#define VPE_DEI_FMD_WINDOW_R0 0x0620
#define VPE_FMD_WINDOW_MINX_MASK 0x07ff
#define VPE_FMD_WINDOW_MINX_SHIFT 0
#define VPE_FMD_WINDOW_MAXX_MASK 0x07ff
#define VPE_FMD_WINDOW_MAXX_SHIFT 16
#define VPE_FMD_WINDOW_ENABLE BIT(31)
#define VPE_DEI_FMD_WINDOW_R1 0x0624
#define VPE_FMD_WINDOW_MINY_MASK 0x07ff
#define VPE_FMD_WINDOW_MINY_SHIFT 0
#define VPE_FMD_WINDOW_MAXY_MASK 0x07ff
#define VPE_FMD_WINDOW_MAXY_SHIFT 16
#define VPE_DEI_FMD_CONTROL_R0 0x0628
#define VPE_FMD_ENABLE BIT(0)
#define VPE_FMD_LOCK BIT(1)
#define VPE_FMD_JAM_DIR BIT(2)
#define VPE_FMD_BED_ENABLE BIT(3)
#define VPE_FMD_CAF_FIELD_THR_MASK 0xff
#define VPE_FMD_CAF_FIELD_THR_SHIFT 16
#define VPE_FMD_CAF_LINE_THR_MASK 0xff
#define VPE_FMD_CAF_LINE_THR_SHIFT 24
#define VPE_DEI_FMD_CONTROL_R1 0x062c
#define VPE_FMD_CAF_THR_MASK 0x000fffff
#define VPE_FMD_CAF_THR_SHIFT 0
#define VPE_DEI_FMD_STATUS_R0 0x0630
#define VPE_FMD_CAF_MASK 0x000fffff
#define VPE_FMD_CAF_SHIFT 0
#define VPE_FMD_RESET BIT(24)
#define VPE_DEI_FMD_STATUS_R1 0x0634
#define VPE_FMD_FIELD_DIFF_MASK 0x0fffffff
#define VPE_FMD_FIELD_DIFF_SHIFT 0
#define VPE_DEI_FMD_STATUS_R2 0x0638
#define VPE_FMD_FRAME_DIFF_MASK 0x000fffff
#define VPE_FMD_FRAME_DIFF_SHIFT 0
#endif