WIP FPC-III support
[linux/fpc-iii.git] / drivers / media / platform / coda / coda-gdi.c
blob59d65daca153766936c30799a3cfe1bbece6ff3b
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Coda multi-standard codec IP
5 * Copyright (C) 2014 Philipp Zabel, Pengutronix
6 */
8 #include <linux/bitops.h>
9 #include "coda.h"
11 #define XY2_INVERT BIT(7)
12 #define XY2_ZERO BIT(6)
13 #define XY2_TB_XOR BIT(5)
14 #define XY2_XYSEL BIT(4)
15 #define XY2_Y (1 << 4)
16 #define XY2_X (0 << 4)
18 #define XY2(luma_sel, luma_bit, chroma_sel, chroma_bit) \
19 (((XY2_##luma_sel) | (luma_bit)) << 8 | \
20 (XY2_##chroma_sel) | (chroma_bit))
22 static const u16 xy2ca_zero_map[16] = {
23 XY2(ZERO, 0, ZERO, 0),
24 XY2(ZERO, 0, ZERO, 0),
25 XY2(ZERO, 0, ZERO, 0),
26 XY2(ZERO, 0, ZERO, 0),
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),
41 static const u16 xy2ca_tiled_map[16] = {
42 XY2(Y, 0, Y, 0),
43 XY2(Y, 1, Y, 1),
44 XY2(Y, 2, Y, 2),
45 XY2(Y, 3, X, 3),
46 XY2(X, 3, ZERO, 0),
47 XY2(ZERO, 0, ZERO, 0),
48 XY2(ZERO, 0, ZERO, 0),
49 XY2(ZERO, 0, ZERO, 0),
50 XY2(ZERO, 0, 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),
61 * RA[15:0], CA[15:8] are hardwired to contain the 24-bit macroblock
62 * start offset (macroblock size is 16x16 for luma, 16x8 for chroma).
63 * Bits CA[4:0] are set using XY2CA above. BA[3:0] seems to be unused.
66 #define RBC_CA (0 << 4)
67 #define RBC_BA (1 << 4)
68 #define RBC_RA (2 << 4)
69 #define RBC_ZERO (3 << 4)
71 #define RBC(luma_sel, luma_bit, chroma_sel, chroma_bit) \
72 (((RBC_##luma_sel) | (luma_bit)) << 6 | \
73 (RBC_##chroma_sel) | (chroma_bit))
75 static const u16 rbc2axi_tiled_map[32] = {
76 RBC(ZERO, 0, ZERO, 0),
77 RBC(ZERO, 0, ZERO, 0),
78 RBC(ZERO, 0, ZERO, 0),
79 RBC(CA, 0, CA, 0),
80 RBC(CA, 1, CA, 1),
81 RBC(CA, 2, CA, 2),
82 RBC(CA, 3, CA, 3),
83 RBC(CA, 4, CA, 8),
84 RBC(CA, 8, CA, 9),
85 RBC(CA, 9, CA, 10),
86 RBC(CA, 10, CA, 11),
87 RBC(CA, 11, CA, 12),
88 RBC(CA, 12, CA, 13),
89 RBC(CA, 13, CA, 14),
90 RBC(CA, 14, CA, 15),
91 RBC(CA, 15, RA, 0),
92 RBC(RA, 0, RA, 1),
93 RBC(RA, 1, RA, 2),
94 RBC(RA, 2, RA, 3),
95 RBC(RA, 3, RA, 4),
96 RBC(RA, 4, RA, 5),
97 RBC(RA, 5, RA, 6),
98 RBC(RA, 6, RA, 7),
99 RBC(RA, 7, RA, 8),
100 RBC(RA, 8, RA, 9),
101 RBC(RA, 9, RA, 10),
102 RBC(RA, 10, RA, 11),
103 RBC(RA, 11, RA, 12),
104 RBC(RA, 12, RA, 13),
105 RBC(RA, 13, RA, 14),
106 RBC(RA, 14, RA, 15),
107 RBC(RA, 15, ZERO, 0),
110 void coda_set_gdi_regs(struct coda_ctx *ctx)
112 struct coda_dev *dev = ctx->dev;
113 const u16 *xy2ca_map;
114 u32 xy2rbc_config;
115 int i;
117 switch (ctx->tiled_map_type) {
118 case GDI_LINEAR_FRAME_MAP:
119 default:
120 xy2ca_map = xy2ca_zero_map;
121 xy2rbc_config = 0;
122 break;
123 case GDI_TILED_FRAME_MB_RASTER_MAP:
124 xy2ca_map = xy2ca_tiled_map;
125 xy2rbc_config = CODA9_XY2RBC_TILED_MAP |
126 CODA9_XY2RBC_CA_INC_HOR |
127 (16 - 1) << 12 | (8 - 1) << 4;
128 break;
131 for (i = 0; i < 16; i++)
132 coda_write(dev, xy2ca_map[i],
133 CODA9_GDI_XY2_CAS_0 + 4 * i);
134 for (i = 0; i < 4; i++)
135 coda_write(dev, XY2(ZERO, 0, ZERO, 0),
136 CODA9_GDI_XY2_BA_0 + 4 * i);
137 for (i = 0; i < 16; i++)
138 coda_write(dev, XY2(ZERO, 0, ZERO, 0),
139 CODA9_GDI_XY2_RAS_0 + 4 * i);
140 coda_write(dev, xy2rbc_config, CODA9_GDI_XY2_RBC_CONFIG);
141 if (xy2rbc_config) {
142 for (i = 0; i < 32; i++)
143 coda_write(dev, rbc2axi_tiled_map[i],
144 CODA9_GDI_RBC2_AXI_0 + 4 * i);