Linux-libre 5.4.47-gnu
[librecmc/linux-libre.git] / drivers / media / platform / coda / coda-gdi.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Coda multi-standard codec IP
4  *
5  * Copyright (C) 2014 Philipp Zabel, Pengutronix
6  */
7
8 #include <linux/bitops.h>
9 #include "coda.h"
10
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)
17
18 #define XY2(luma_sel, luma_bit, chroma_sel, chroma_bit) \
19         (((XY2_##luma_sel) | (luma_bit)) << 8 | \
20          (XY2_##chroma_sel) | (chroma_bit))
21
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),
39 };
40
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),
58 };
59
60 /*
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.
64  */
65
66 #define RBC_CA          (0 << 4)
67 #define RBC_BA          (1 << 4)
68 #define RBC_RA          (2 << 4)
69 #define RBC_ZERO        (3 << 4)
70
71 #define RBC(luma_sel, luma_bit, chroma_sel, chroma_bit) \
72         (((RBC_##luma_sel) | (luma_bit)) << 6 | \
73          (RBC_##chroma_sel) | (chroma_bit))
74
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),
108 };
109
110 void coda_set_gdi_regs(struct coda_ctx *ctx)
111 {
112         struct coda_dev *dev = ctx->dev;
113         const u16 *xy2ca_map;
114         u32 xy2rbc_config;
115         int i;
116
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;
129         }
130
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);
145         }
146 }