18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Coda multi-standard codec IP
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2014 Philipp Zabel, Pengutronix
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/bitops.h>
98c2ecf20Sopenharmony_ci#include "coda.h"
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#define XY2_INVERT	BIT(7)
128c2ecf20Sopenharmony_ci#define XY2_ZERO	BIT(6)
138c2ecf20Sopenharmony_ci#define XY2_TB_XOR	BIT(5)
148c2ecf20Sopenharmony_ci#define XY2_XYSEL	BIT(4)
158c2ecf20Sopenharmony_ci#define XY2_Y		(1 << 4)
168c2ecf20Sopenharmony_ci#define XY2_X		(0 << 4)
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#define XY2(luma_sel, luma_bit, chroma_sel, chroma_bit) \
198c2ecf20Sopenharmony_ci	(((XY2_##luma_sel) | (luma_bit)) << 8 | \
208c2ecf20Sopenharmony_ci	 (XY2_##chroma_sel) | (chroma_bit))
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_cistatic const u16 xy2ca_zero_map[16] = {
238c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
248c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
258c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
268c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
278c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
288c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
298c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
308c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
318c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
328c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
338c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
348c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
358c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
368c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
378c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
388c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
398c2ecf20Sopenharmony_ci};
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_cistatic const u16 xy2ca_tiled_map[16] = {
428c2ecf20Sopenharmony_ci	XY2(Y,    0, Y,    0),
438c2ecf20Sopenharmony_ci	XY2(Y,    1, Y,    1),
448c2ecf20Sopenharmony_ci	XY2(Y,    2, Y,    2),
458c2ecf20Sopenharmony_ci	XY2(Y,    3, X,    3),
468c2ecf20Sopenharmony_ci	XY2(X,    3, ZERO, 0),
478c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
488c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
498c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
508c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
518c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
528c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
538c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
548c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
558c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
568c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
578c2ecf20Sopenharmony_ci	XY2(ZERO, 0, ZERO, 0),
588c2ecf20Sopenharmony_ci};
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci/*
618c2ecf20Sopenharmony_ci * RA[15:0], CA[15:8] are hardwired to contain the 24-bit macroblock
628c2ecf20Sopenharmony_ci * start offset (macroblock size is 16x16 for luma, 16x8 for chroma).
638c2ecf20Sopenharmony_ci * Bits CA[4:0] are set using XY2CA above. BA[3:0] seems to be unused.
648c2ecf20Sopenharmony_ci */
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci#define RBC_CA		(0 << 4)
678c2ecf20Sopenharmony_ci#define RBC_BA		(1 << 4)
688c2ecf20Sopenharmony_ci#define RBC_RA		(2 << 4)
698c2ecf20Sopenharmony_ci#define RBC_ZERO	(3 << 4)
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci#define RBC(luma_sel, luma_bit, chroma_sel, chroma_bit) \
728c2ecf20Sopenharmony_ci	(((RBC_##luma_sel) | (luma_bit)) << 6 | \
738c2ecf20Sopenharmony_ci	 (RBC_##chroma_sel) | (chroma_bit))
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_cistatic const u16 rbc2axi_tiled_map[32] = {
768c2ecf20Sopenharmony_ci	RBC(ZERO, 0, ZERO, 0),
778c2ecf20Sopenharmony_ci	RBC(ZERO, 0, ZERO, 0),
788c2ecf20Sopenharmony_ci	RBC(ZERO, 0, ZERO, 0),
798c2ecf20Sopenharmony_ci	RBC(CA,   0, CA,   0),
808c2ecf20Sopenharmony_ci	RBC(CA,   1, CA,   1),
818c2ecf20Sopenharmony_ci	RBC(CA,   2, CA,   2),
828c2ecf20Sopenharmony_ci	RBC(CA,   3, CA,   3),
838c2ecf20Sopenharmony_ci	RBC(CA,   4, CA,   8),
848c2ecf20Sopenharmony_ci	RBC(CA,   8, CA,   9),
858c2ecf20Sopenharmony_ci	RBC(CA,   9, CA,  10),
868c2ecf20Sopenharmony_ci	RBC(CA,  10, CA,  11),
878c2ecf20Sopenharmony_ci	RBC(CA,  11, CA,  12),
888c2ecf20Sopenharmony_ci	RBC(CA,  12, CA,  13),
898c2ecf20Sopenharmony_ci	RBC(CA,  13, CA,  14),
908c2ecf20Sopenharmony_ci	RBC(CA,  14, CA,  15),
918c2ecf20Sopenharmony_ci	RBC(CA,  15, RA,   0),
928c2ecf20Sopenharmony_ci	RBC(RA,   0, RA,   1),
938c2ecf20Sopenharmony_ci	RBC(RA,   1, RA,   2),
948c2ecf20Sopenharmony_ci	RBC(RA,   2, RA,   3),
958c2ecf20Sopenharmony_ci	RBC(RA,   3, RA,   4),
968c2ecf20Sopenharmony_ci	RBC(RA,   4, RA,   5),
978c2ecf20Sopenharmony_ci	RBC(RA,   5, RA,   6),
988c2ecf20Sopenharmony_ci	RBC(RA,   6, RA,   7),
998c2ecf20Sopenharmony_ci	RBC(RA,   7, RA,   8),
1008c2ecf20Sopenharmony_ci	RBC(RA,   8, RA,   9),
1018c2ecf20Sopenharmony_ci	RBC(RA,   9, RA,  10),
1028c2ecf20Sopenharmony_ci	RBC(RA,  10, RA,  11),
1038c2ecf20Sopenharmony_ci	RBC(RA,  11, RA,  12),
1048c2ecf20Sopenharmony_ci	RBC(RA,  12, RA,  13),
1058c2ecf20Sopenharmony_ci	RBC(RA,  13, RA,  14),
1068c2ecf20Sopenharmony_ci	RBC(RA,  14, RA,  15),
1078c2ecf20Sopenharmony_ci	RBC(RA,  15, ZERO, 0),
1088c2ecf20Sopenharmony_ci};
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_civoid coda_set_gdi_regs(struct coda_ctx *ctx)
1118c2ecf20Sopenharmony_ci{
1128c2ecf20Sopenharmony_ci	struct coda_dev *dev = ctx->dev;
1138c2ecf20Sopenharmony_ci	const u16 *xy2ca_map;
1148c2ecf20Sopenharmony_ci	u32 xy2rbc_config;
1158c2ecf20Sopenharmony_ci	int i;
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	switch (ctx->tiled_map_type) {
1188c2ecf20Sopenharmony_ci	case GDI_LINEAR_FRAME_MAP:
1198c2ecf20Sopenharmony_ci	default:
1208c2ecf20Sopenharmony_ci		xy2ca_map = xy2ca_zero_map;
1218c2ecf20Sopenharmony_ci		xy2rbc_config = 0;
1228c2ecf20Sopenharmony_ci		break;
1238c2ecf20Sopenharmony_ci	case GDI_TILED_FRAME_MB_RASTER_MAP:
1248c2ecf20Sopenharmony_ci		xy2ca_map = xy2ca_tiled_map;
1258c2ecf20Sopenharmony_ci		xy2rbc_config = CODA9_XY2RBC_TILED_MAP |
1268c2ecf20Sopenharmony_ci				CODA9_XY2RBC_CA_INC_HOR |
1278c2ecf20Sopenharmony_ci				(16 - 1) << 12 | (8 - 1) << 4;
1288c2ecf20Sopenharmony_ci		break;
1298c2ecf20Sopenharmony_ci	}
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci	for (i = 0; i < 16; i++)
1328c2ecf20Sopenharmony_ci		coda_write(dev, xy2ca_map[i],
1338c2ecf20Sopenharmony_ci				CODA9_GDI_XY2_CAS_0 + 4 * i);
1348c2ecf20Sopenharmony_ci	for (i = 0; i < 4; i++)
1358c2ecf20Sopenharmony_ci		coda_write(dev, XY2(ZERO, 0, ZERO, 0),
1368c2ecf20Sopenharmony_ci				CODA9_GDI_XY2_BA_0 + 4 * i);
1378c2ecf20Sopenharmony_ci	for (i = 0; i < 16; i++)
1388c2ecf20Sopenharmony_ci		coda_write(dev, XY2(ZERO, 0, ZERO, 0),
1398c2ecf20Sopenharmony_ci				CODA9_GDI_XY2_RAS_0 + 4 * i);
1408c2ecf20Sopenharmony_ci	coda_write(dev, xy2rbc_config, CODA9_GDI_XY2_RBC_CONFIG);
1418c2ecf20Sopenharmony_ci	if (xy2rbc_config) {
1428c2ecf20Sopenharmony_ci		for (i = 0; i < 32; i++)
1438c2ecf20Sopenharmony_ci			coda_write(dev, rbc2axi_tiled_map[i],
1448c2ecf20Sopenharmony_ci					CODA9_GDI_RBC2_AXI_0 + 4 * i);
1458c2ecf20Sopenharmony_ci	}
1468c2ecf20Sopenharmony_ci}
147