1/*
2 * Coda multi-standard codec IP
3 *
4 * Copyright (C) 2014 Philipp Zabel, Pengutronix
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/bitops.h>
13#include "coda.h"
14
15#define XY2_INVERT	BIT(7)
16#define XY2_ZERO	BIT(6)
17#define XY2_TB_XOR	BIT(5)
18#define XY2_XYSEL	BIT(4)
19#define XY2_Y		(1 << 4)
20#define XY2_X		(0 << 4)
21
22#define XY2(luma_sel, luma_bit, chroma_sel, chroma_bit) \
23	(((XY2_##luma_sel) | (luma_bit)) << 8 | \
24	 (XY2_##chroma_sel) | (chroma_bit))
25
26static const u16 xy2ca_zero_map[16] = {
27	XY2(ZERO, 0, ZERO, 0),
28	XY2(ZERO, 0, ZERO, 0),
29	XY2(ZERO, 0, ZERO, 0),
30	XY2(ZERO, 0, ZERO, 0),
31	XY2(ZERO, 0, ZERO, 0),
32	XY2(ZERO, 0, ZERO, 0),
33	XY2(ZERO, 0, ZERO, 0),
34	XY2(ZERO, 0, ZERO, 0),
35	XY2(ZERO, 0, ZERO, 0),
36	XY2(ZERO, 0, ZERO, 0),
37	XY2(ZERO, 0, ZERO, 0),
38	XY2(ZERO, 0, ZERO, 0),
39	XY2(ZERO, 0, ZERO, 0),
40	XY2(ZERO, 0, ZERO, 0),
41	XY2(ZERO, 0, ZERO, 0),
42	XY2(ZERO, 0, ZERO, 0),
43};
44
45static const u16 xy2ca_tiled_map[16] = {
46	XY2(Y,    0, Y,    0),
47	XY2(Y,    1, Y,    1),
48	XY2(Y,    2, Y,    2),
49	XY2(Y,    3, X,    3),
50	XY2(X,    3, ZERO, 0),
51	XY2(ZERO, 0, ZERO, 0),
52	XY2(ZERO, 0, ZERO, 0),
53	XY2(ZERO, 0, ZERO, 0),
54	XY2(ZERO, 0, ZERO, 0),
55	XY2(ZERO, 0, ZERO, 0),
56	XY2(ZERO, 0, ZERO, 0),
57	XY2(ZERO, 0, ZERO, 0),
58	XY2(ZERO, 0, ZERO, 0),
59	XY2(ZERO, 0, ZERO, 0),
60	XY2(ZERO, 0, ZERO, 0),
61	XY2(ZERO, 0, ZERO, 0),
62};
63
64/*
65 * RA[15:0], CA[15:8] are hardwired to contain the 24-bit macroblock
66 * start offset (macroblock size is 16x16 for luma, 16x8 for chroma).
67 * Bits CA[4:0] are set using XY2CA above. BA[3:0] seems to be unused.
68 */
69
70#define RBC_CA		(0 << 4)
71#define RBC_BA		(1 << 4)
72#define RBC_RA		(2 << 4)
73#define RBC_ZERO	(3 << 4)
74
75#define RBC(luma_sel, luma_bit, chroma_sel, chroma_bit) \
76	(((RBC_##luma_sel) | (luma_bit)) << 6 | \
77	 (RBC_##chroma_sel) | (chroma_bit))
78
79static const u16 rbc2axi_tiled_map[32] = {
80	RBC(ZERO, 0, ZERO, 0),
81	RBC(ZERO, 0, ZERO, 0),
82	RBC(ZERO, 0, ZERO, 0),
83	RBC(CA,   0, CA,   0),
84	RBC(CA,   1, CA,   1),
85	RBC(CA,   2, CA,   2),
86	RBC(CA,   3, CA,   3),
87	RBC(CA,   4, CA,   8),
88	RBC(CA,   8, CA,   9),
89	RBC(CA,   9, CA,  10),
90	RBC(CA,  10, CA,  11),
91	RBC(CA,  11, CA,  12),
92	RBC(CA,  12, CA,  13),
93	RBC(CA,  13, CA,  14),
94	RBC(CA,  14, CA,  15),
95	RBC(CA,  15, RA,   0),
96	RBC(RA,   0, RA,   1),
97	RBC(RA,   1, RA,   2),
98	RBC(RA,   2, RA,   3),
99	RBC(RA,   3, RA,   4),
100	RBC(RA,   4, RA,   5),
101	RBC(RA,   5, RA,   6),
102	RBC(RA,   6, RA,   7),
103	RBC(RA,   7, RA,   8),
104	RBC(RA,   8, RA,   9),
105	RBC(RA,   9, RA,  10),
106	RBC(RA,  10, RA,  11),
107	RBC(RA,  11, RA,  12),
108	RBC(RA,  12, RA,  13),
109	RBC(RA,  13, RA,  14),
110	RBC(RA,  14, RA,  15),
111	RBC(RA,  15, ZERO, 0),
112};
113
114void coda_set_gdi_regs(struct coda_ctx *ctx)
115{
116	struct coda_dev *dev = ctx->dev;
117	const u16 *xy2ca_map;
118	u32 xy2rbc_config;
119	int i;
120
121	switch (ctx->tiled_map_type) {
122	case GDI_LINEAR_FRAME_MAP:
123	default:
124		xy2ca_map = xy2ca_zero_map;
125		xy2rbc_config = 0;
126		break;
127	case GDI_TILED_FRAME_MB_RASTER_MAP:
128		xy2ca_map = xy2ca_tiled_map;
129		xy2rbc_config = CODA9_XY2RBC_TILED_MAP |
130				CODA9_XY2RBC_CA_INC_HOR |
131				(16 - 1) << 12 | (8 - 1) << 4;
132		break;
133	}
134
135	for (i = 0; i < 16; i++)
136		coda_write(dev, xy2ca_map[i],
137				CODA9_GDI_XY2_CAS_0 + 4 * i);
138	for (i = 0; i < 4; i++)
139		coda_write(dev, XY2(ZERO, 0, ZERO, 0),
140				CODA9_GDI_XY2_BA_0 + 4 * i);
141	for (i = 0; i < 16; i++)
142		coda_write(dev, XY2(ZERO, 0, ZERO, 0),
143				CODA9_GDI_XY2_RAS_0 + 4 * i);
144	coda_write(dev, xy2rbc_config, CODA9_GDI_XY2_RBC_CONFIG);
145	if (xy2rbc_config) {
146		for (i = 0; i < 32; i++)
147			coda_write(dev, rbc2axi_tiled_map[i],
148					CODA9_GDI_RBC2_AXI_0 + 4 * i);
149	}
150}
151