// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Coda multi-standard codec IP
*
* Copyright (C) 2014 Philipp Zabel, Pengutronix
*/
#include <linux/bitops.h>
#include "coda.h"
#define XY2_INVERT BIT(7 )
#define XY2_ZERO BIT(6 )
#define XY2_TB_XOR BIT(5 )
#define XY2_XYSEL BIT(4 )
#define XY2_Y (1 << 4 )
#define XY2_X (0 << 4 )
#define XY2(luma_sel, luma_bit, chroma_sel, chroma_bit) \
(((XY2_## luma_sel) | (luma_bit)) << 8 | \
(XY2_## chroma_sel) | (chroma_bit))
static const u16 xy2ca_zero_map[16 ] = {
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
};
static const u16 xy2ca_tiled_map[16 ] = {
XY2(Y, 0 , Y, 0 ),
XY2(Y, 1 , Y, 1 ),
XY2(Y, 2 , Y, 2 ),
XY2(Y, 3 , X, 3 ),
XY2(X, 3 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
XY2(ZERO, 0 , ZERO, 0 ),
};
/*
* RA[15:0], CA[15:8] are hardwired to contain the 24-bit macroblock
* start offset (macroblock size is 16x16 for luma, 16x8 for chroma).
* Bits CA[4:0] are set using XY2CA above. BA[3:0] seems to be unused.
*/
#define RBC_CA (0 << 4 )
#define RBC_BA (1 << 4 )
#define RBC_RA (2 << 4 )
#define RBC_ZERO (3 << 4 )
#define RBC(luma_sel, luma_bit, chroma_sel, chroma_bit) \
(((RBC_## luma_sel) | (luma_bit)) << 6 | \
(RBC_## chroma_sel) | (chroma_bit))
static const u16 rbc2axi_tiled_map[32 ] = {
RBC(ZERO, 0 , ZERO, 0 ),
RBC(ZERO, 0 , ZERO, 0 ),
RBC(ZERO, 0 , ZERO, 0 ),
RBC(CA, 0 , CA, 0 ),
RBC(CA, 1 , CA, 1 ),
RBC(CA, 2 , CA, 2 ),
RBC(CA, 3 , CA, 3 ),
RBC(CA, 4 , CA, 8 ),
RBC(CA, 8 , CA, 9 ),
RBC(CA, 9 , CA, 10 ),
RBC(CA, 10 , CA, 11 ),
RBC(CA, 11 , CA, 12 ),
RBC(CA, 12 , CA, 13 ),
RBC(CA, 13 , CA, 14 ),
RBC(CA, 14 , CA, 15 ),
RBC(CA, 15 , RA, 0 ),
RBC(RA, 0 , RA, 1 ),
RBC(RA, 1 , RA, 2 ),
RBC(RA, 2 , RA, 3 ),
RBC(RA, 3 , RA, 4 ),
RBC(RA, 4 , RA, 5 ),
RBC(RA, 5 , RA, 6 ),
RBC(RA, 6 , RA, 7 ),
RBC(RA, 7 , RA, 8 ),
RBC(RA, 8 , RA, 9 ),
RBC(RA, 9 , RA, 10 ),
RBC(RA, 10 , RA, 11 ),
RBC(RA, 11 , RA, 12 ),
RBC(RA, 12 , RA, 13 ),
RBC(RA, 13 , RA, 14 ),
RBC(RA, 14 , RA, 15 ),
RBC(RA, 15 , ZERO, 0 ),
};
void coda_set_gdi_regs(struct coda_ctx *ctx)
{
struct coda_dev *dev = ctx->dev;
const u16 *xy2ca_map;
u32 xy2rbc_config;
int i;
switch (ctx->tiled_map_type) {
case GDI_LINEAR_FRAME_MAP:
default :
xy2ca_map = xy2ca_zero_map;
xy2rbc_config = 0 ;
break ;
case GDI_TILED_FRAME_MB_RASTER_MAP:
xy2ca_map = xy2ca_tiled_map;
xy2rbc_config = CODA9_XY2RBC_TILED_MAP |
CODA9_XY2RBC_CA_INC_HOR |
(16 - 1 ) << 12 | (8 - 1 ) << 4 ;
break ;
}
for (i = 0 ; i < 16 ; i++)
coda_write(dev, xy2ca_map[i],
CODA9_GDI_XY2_CAS_0 + 4 * i);
for (i = 0 ; i < 4 ; i++)
coda_write(dev, XY2(ZERO, 0 , ZERO, 0 ),
CODA9_GDI_XY2_BA_0 + 4 * i);
for (i = 0 ; i < 16 ; i++)
coda_write(dev, XY2(ZERO, 0 , ZERO, 0 ),
CODA9_GDI_XY2_RAS_0 + 4 * i);
coda_write(dev, xy2rbc_config, CODA9_GDI_XY2_RBC_CONFIG);
if (xy2rbc_config) {
for (i = 0 ; i < 32 ; i++)
coda_write(dev, rbc2axi_tiled_map[i],
CODA9_GDI_RBC2_AXI_0 + 4 * i);
}
}
Messung V0.5 in Prozent C=96 H=93 G=94