Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bdk/display/vic.c
1476 views
1
/*
2
* VIC driver for Tegra X1
3
*
4
* Copyright (c) 2018-2024 CTCaer
5
*
6
* This program is free software; you can redistribute it and/or modify it
7
* under the terms and conditions of the GNU General Public License,
8
* version 2, as published by the Free Software Foundation.
9
*
10
* This program is distributed in the hope it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13
* more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
#include <string.h>
20
21
#include "vic.h"
22
#include <mem/heap.h>
23
#include <soc/bpmp.h>
24
#include <soc/clock.h>
25
#include <soc/timer.h>
26
#include <soc/t210.h>
27
#include <utils/types.h>
28
29
/* VIC Private registers */
30
#define PVIC_FALCON_PA_OFFSET 0x1000
31
#define PVIC_FALCON_ADDR 0x10AC
32
#define PVIC_FALCON_IDLESTATE 0x104C
33
34
/* VIC Control and Status registers. */
35
/* Fetch Control registers. */
36
#define VIC_FC_COMPOSE 0x10000
37
#define COMPOSE_START BIT(0)
38
39
#define VIC_FC_CFG_STRUCT_SLOT_INDEX 0x10B00
40
41
#define VIC_FC_CFG_STRUCT_SLOT_CFG0 0x10B04
42
#define SLOT_ENABLE BIT(0)
43
#define FIELD_CURRENT_ENABLE BIT(8)
44
45
#define VIC_FC_CFG_STRUCT_SLOT_CFG2 0x10B0C
46
#define CACHE_WIDTH(n) ((n) << 16)
47
#define CACHE_WIDTH_16BX16 0 // Block Linear.
48
#define CACHE_WIDTH_32BX8 1 // Block Linear. Recommended for Block Linear.
49
#define CACHE_WIDTH_64BX4 2 // Block Linear, Pitch. Recommended for Pitch.
50
#define CACHE_WIDTH_128BX2 3 // Block Linear, Pitch.
51
#define OUTPUT_FLIP_X BIT(20)
52
#define OUTPUT_FLIP_Y BIT(21)
53
#define OUTPUT_TRANSPOSE BIT(22)
54
55
#define VIC_FC_CFG_STRUCT_SLOT_SFC_SIZE 0x10B10
56
#define VIC_FC_CFG_STRUCT_SLOT_LUMA_SIZE 0x10B14
57
#define VIC_FC_CFG_STRUCT_SLOT_CHROMA_SIZE 0x10B18
58
#define VIC_FC_CFG_STRUCT_SLOT_SRC_RECT_LR 0x10B1C
59
#define VIC_FC_CFG_STRUCT_SLOT_SRC_RECT_TB 0x10B20
60
#define VIC_FC_CFG_STRUCT_SLOT_DST_RECT_LR 0x10B30
61
#define VIC_FC_CFG_STRUCT_SLOT_DST_RECT_TB 0x10B34
62
#define VIC_FC_CFG_STRUCT_TGT_RECT_LR 0x10B38
63
#define VIC_FC_CFG_STRUCT_TGT_RECT_TB 0x10B3C
64
#define VIC_FC_SLOT_MAP 0x10C00
65
66
#define VIC_FC_FCE_CTRL 0x11000
67
#define START_TRIGGER BIT(0)
68
#define HALT_TRIGGER BIT(1)
69
#define CLEAR_ERROR BIT(8)
70
71
#define VIC_FC_FCE_UCODE_ADDR 0x11200
72
#define VIC_FC_FCE_UCODE_INST 0x11300
73
74
/* Surface List registers. */
75
#define VIC_SL_CFG_STRUCT_SLOT_INDEX 0x12100
76
#define VIC_SL_CFG_STRUCT_SLOT_DST_RECT_LR 0x12200
77
#define VIC_SL_CFG_STRUCT_SLOT_DST_RECT_TB 0x12300
78
#define VIC_SL_CFG_STRUCT_TGT_RECT_LR 0x12400
79
#define VIC_SL_CFG_STRUCT_TGT_RECT_TB 0x12500
80
#define VIC_SL_CFG_STRUCT_SLOT_CFG0 0x12600
81
82
/* Surface Cache registers. */
83
#define VIC_SC_PRAMBASE 0x14000
84
#define VIC_SC_PRAMSIZE 0x14100
85
#define VIC_SC_SFC0_BASE_LUMA(n) (0x14300 + (n) * 0x100)
86
87
/* Blending Output registers. */
88
#define VIC_BL_TARGET_BASADR 0x22000
89
#define VIC_BL_CONFIG 0x22800
90
#define SUBPARTITION_MODE BIT(0)
91
#define PROCESS_CFG_STRUCT_TRIGGER BIT(2)
92
#define SLOTMASK(n) ((n) << 8)
93
94
#define VIC_BL_CFG_STRUCT_CFG0 0x22C00
95
#define VIC_BL_CFG_STRUCT_SFC_SIZE 0x22C04
96
#define VIC_BL_CFG_STRUCT_LUMA_SIZE 0x22C08
97
#define VIC_BL_CFG_STRUCT_CHROMA_SIZE 0x22C0C
98
#define VIC_BL_CFG_STRUCT_TGT_RECT_LR 0x22C10
99
#define VIC_BL_CFG_STRUCT_TGT_RECT_TB 0x22C14
100
101
// VIC_FC_CFG_STRUCT_SLOT_CFG2 & VIC_BL_CFG_STRUCT_CFG0.
102
#define BLK_KIND(n) ((n) << 8)
103
#define BLK_KIND_PITCH 0
104
#define BLK_KIND_GENERIC_16BX2 1
105
#define BLK_HEIGHT(n) ((n) << 12)
106
#define BLK_HEIGHT_ONE_GOB 0
107
#define BLK_HEIGHT_SIXTEEN_GOBS 4
108
109
// Generic size macros.
110
#define SIZE_WIDTH(n) (((n) - 1) << 0)
111
#define SIZE_HEIGHT(n) (((n) - 1) << 16)
112
#define RECT_LEFT(n) ((n) << 0)
113
#define RECT_RIGHT(n) (((n) - 1) << 16)
114
#define RECT_TOP(n) ((n) << 0)
115
#define RECT_BOTTOM(n) (((n) - 1) << 16)
116
117
#define FORMAT_PROGRESSIVE 0
118
#define SOFT_CLAMP_MIN 0
119
#define SOFT_CLAMP_MAX 0x3FFu
120
#define ALPHA_1_0 0x3FFu
121
122
typedef struct _OutputConfig {
123
u64 AlphaFillMode:3;
124
u64 AlphaFillSlot:3;
125
u64 BackgroundAlpha:10;
126
u64 BackgroundR:10;
127
u64 BackgroundG:10;
128
u64 BackgroundB:10;
129
u64 RegammaMode:2;
130
u64 OutputFlipX:1;
131
u64 OutputFlipY:1;
132
u64 OutputTranspose:1;
133
u64 rsvd1:1;
134
u64 rsvd2:12;
135
u64 TargetRectLeft:14;
136
u64 rsvd3:2;
137
u64 TargetRectRight:14;
138
u64 rsvd4:2;
139
u64 TargetRectTop:14;
140
u64 rsvd5:2;
141
u64 TargetRectBottom:14;
142
u64 rsvd6:2;
143
} OutputConfig;
144
145
typedef struct _OutputSurfaceConfig {
146
u64 OutPixelFormat:7;
147
u64 OutChromaLocHoriz:2;
148
u64 OutChromaLocVert:2;
149
u64 OutBlkKind:4;
150
u64 OutBlkHeight:4;
151
u64 rsvd0:3;
152
u64 rsvd1:10;
153
u64 OutSurfaceWidth:14;
154
u64 OutSurfaceHeight:14;
155
u64 rsvd2:4;
156
u64 OutLumaWidth:14;
157
u64 OutLumaHeight:14;
158
u64 rsvd3:4;
159
u64 OutChromaWidth:14;
160
u64 OutChromaHeight:14;
161
u64 rsvd4:4;
162
} OutputSurfaceConfig;
163
164
typedef struct _SlotConfig {
165
u64 SlotEnable:1;
166
u64 DeNoise:1;
167
u64 AdvancedDenoise:1;
168
u64 CadenceDetect:1;
169
u64 MotionMap:1;
170
u64 MMapCombine:1;
171
u64 IsEven:1;
172
u64 ChromaEven:1;
173
u64 CurrentFieldEnable:1;
174
u64 PrevFieldEnable:1;
175
u64 NextFieldEnable:1;
176
u64 NextNrFieldEnable:1;
177
u64 CurMotionFieldEnable:1;
178
u64 PrevMotionFieldEnable:1;
179
u64 PpMotionFieldEnable:1;
180
u64 CombMotionFieldEnable:1;
181
u64 FrameFormat:4;
182
u64 FilterLengthY:2;
183
u64 FilterLengthX:2;
184
u64 Panoramic:12;
185
u64 rsvd1:22;
186
u64 DetailFltClamp:6;
187
u64 FilterNoise:10;
188
u64 FilterDetail:10;
189
u64 ChromaNoise:10;
190
u64 ChromaDetail:10;
191
u64 DeinterlaceMode:4;
192
u64 MotionAccumWeight:3;
193
u64 NoiseIir:11;
194
u64 LightLevel:4;
195
u64 rsvd4:2;
196
u64 SoftClampLow:10;
197
u64 SoftClampHigh:10;
198
u64 rsvd5:3;
199
u64 rsvd6:9;
200
u64 PlanarAlpha:10;
201
u64 ConstantAlpha:1;
202
u64 StereoInterleave:3;
203
u64 ClipEnabled:1;
204
u64 ClearRectMask:8;
205
u64 DegammaMode:2;
206
u64 rsvd7:1;
207
u64 DecompressEnable:1;
208
u64 rsvd9:5;
209
u64 DecompressCtbCount:8;
210
u64 DecompressZbcColor:32;
211
u64 rsvd12:24;
212
u64 SourceRectLeft:30;
213
u64 rsvd14:2;
214
u64 SourceRectRight:30;
215
u64 rsvd15:2;
216
u64 SourceRectTop:30;
217
u64 rsvd16:2;
218
u64 SourceRectBottom:30;
219
u64 rsvd17:2;
220
u64 DestRectLeft:14;
221
u64 rsvd18:2;
222
u64 DestRectRight:14;
223
u64 rsvd19:2;
224
u64 DestRectTop:14;
225
u64 rsvd20:2;
226
u64 DestRectBottom:14;
227
u64 rsvd21:2;
228
u64 rsvd22:32;
229
u64 rsvd23:32;
230
} SlotConfig;
231
232
typedef struct _SlotSurfaceConfig {
233
u64 SlotPixelFormat:7;
234
u64 SlotChromaLocHoriz:2;
235
u64 SlotChromaLocVert:2;
236
u64 SlotBlkKind:4;
237
u64 SlotBlkHeight:4;
238
u64 SlotCacheWidth:3;
239
u64 rsvd0:10;
240
u64 SlotSurfaceWidth:14;
241
u64 SlotSurfaceHeight:14;
242
u64 rsvd1:4;
243
u64 SlotLumaWidth:14;
244
u64 SlotLumaHeight:14;
245
u64 rsvd2:4;
246
u64 SlotChromaWidth:14;
247
u64 SlotChromaHeight:14;
248
u64 rsvd3:4;
249
} SlotSurfaceConfig;
250
251
typedef struct _SlotStruct {
252
SlotConfig slot_cfg;
253
SlotSurfaceConfig slot_sfc_cfg;
254
255
// No need to configure. Reset to zeros.
256
u8 lumaKeyStruct[0x10];
257
u8 colorMatrixStruct[0x20];
258
u8 gamutMatrixStruct[0x20];
259
u8 blendingSlotStruct[0x10];
260
} SlotStruct;
261
262
typedef struct _vic_config_t {
263
// No need to configure. Reset to zeros.
264
u8 pipeConfig[0x10];
265
266
OutputConfig out_cfg;
267
OutputSurfaceConfig out_sfc_cfg;
268
269
// No need to configure. Reset to zeros.
270
u8 out_color_matrix[0x20];
271
u8 clear_rect[0x10 * 4];
272
273
SlotStruct slots[8];
274
} vic_config_t;
275
276
// VIC Fetch Control Engine microcode. Dumped from L4T r33.
277
u8 vic_fce_ucode[] = {
278
0x66, 0x00, 0x00, 0x00, 0x60, 0x07, 0x00, 0x00, 0x42, 0x40, 0x10, 0x00, 0x4E, 0x01, 0x40, 0x00,
279
0x6A, 0x07, 0x00, 0x00, 0x6E, 0x23, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x4E, 0x01, 0x04, 0x00,
280
0x6A, 0x0B, 0x00, 0x00, 0x6E, 0x1F, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x4E, 0x01, 0x10, 0x00,
281
0x6A, 0x0F, 0x00, 0x00, 0x6E, 0x1F, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x48, 0x80, 0x02, 0x00,
282
0x0E, 0x11, 0x00, 0x00, 0x6A, 0x14, 0x00, 0x00, 0x6E, 0x08, 0x06, 0x00, 0x6C, 0x00, 0x00, 0x00,
283
0x4E, 0x01, 0x08, 0x00, 0x6A, 0x18, 0x00, 0x00, 0x6E, 0x26, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00,
284
0x4E, 0x01, 0x20, 0x00, 0x6A, 0x1C, 0x00, 0x00, 0x6E, 0x26, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00,
285
0x4E, 0x01, 0x02, 0x00, 0x6A, 0x20, 0x00, 0x00, 0x6E, 0x24, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00,
286
0x56, 0x00, 0x10, 0x00, 0x56, 0x40, 0x10, 0x00, 0x22, 0x41, 0x01, 0x00, 0x6C, 0x00, 0x00, 0x00,
287
0x62, 0x80, 0x01, 0x00, 0x60, 0x47, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00, 0x01, 0x4A, 0x00, 0x00,
288
0x55, 0xC0, 0x20, 0x00, 0x00, 0x59, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00,
289
0x01, 0x93, 0x00, 0x00, 0x40, 0x82, 0x02, 0x00, 0x4E, 0x02, 0x00, 0x00, 0x6B, 0x34, 0x00, 0x00,
290
0x43, 0xC1, 0x10, 0x00, 0x42, 0x02, 0x03, 0x00, 0x00, 0x23, 0x01, 0x00, 0x24, 0xD4, 0x00, 0x00,
291
0x56, 0x40, 0x3D, 0x00, 0x04, 0xEB, 0x00, 0x00, 0x60, 0x07, 0x01, 0x00, 0x60, 0x47, 0x00, 0x00,
292
0x6A, 0x3E, 0x00, 0x00, 0x55, 0xC0, 0x30, 0x00, 0x48, 0x00, 0x01, 0x00, 0x48, 0x40, 0x01, 0x00,
293
0x48, 0x80, 0x01, 0x00, 0x6B, 0x28, 0x02, 0x00, 0x56, 0x40, 0x09, 0x00, 0x04, 0x4D, 0x01, 0x00,
294
0x06, 0x4D, 0x00, 0x00, 0x42, 0xC0, 0x03, 0x00, 0x56, 0x80, 0x09, 0x00, 0x04, 0xFE, 0x01, 0x00,
295
0x00, 0xF9, 0x01, 0x00, 0x4E, 0x02, 0x00, 0x00, 0x6B, 0x32, 0x02, 0x00, 0x55, 0x40, 0x2F, 0x00,
296
0x56, 0x80, 0x0D, 0x00, 0x4F, 0x00, 0x00, 0x00, 0x6A, 0x0D, 0x02, 0x00, 0x55, 0x40, 0x31, 0x00,
297
0x56, 0x80, 0x0B, 0x00, 0x0C, 0x2B, 0x00, 0x00, 0x6A, 0x13, 0x02, 0x00, 0x43, 0x45, 0x03, 0x00,
298
0x42, 0x86, 0x03, 0x00, 0x4D, 0x06, 0x02, 0x00, 0x6A, 0x0D, 0x02, 0x00, 0x42, 0x86, 0x03, 0x00,
299
0x22, 0x7E, 0x01, 0x00, 0x4E, 0x04, 0x00, 0x00, 0x6B, 0x32, 0x02, 0x00, 0x55, 0x40, 0x17, 0x00,
300
0x0D, 0x2C, 0x00, 0x00, 0x56, 0xC0, 0x09, 0x00, 0x6A, 0x1E, 0x02, 0x00, 0x48, 0xC0, 0x01, 0x00,
301
0x43, 0x04, 0x03, 0x00, 0x6C, 0x20, 0x02, 0x00, 0x55, 0x40, 0x19, 0x00, 0x01, 0x2C, 0x01, 0x00,
302
0x65, 0x23, 0x01, 0x00, 0x42, 0x42, 0x03, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x24, 0x14, 0x01, 0x00,
303
0x00, 0x2C, 0x01, 0x00, 0x24, 0x14, 0x01, 0x00, 0x00, 0x3C, 0x01, 0x00, 0x42, 0x04, 0x09, 0x00,
304
0x42, 0xC3, 0x02, 0x00, 0x65, 0x54, 0x01, 0x00, 0x65, 0x55, 0x01, 0x00, 0x42, 0x45, 0x0D, 0x00,
305
0x62, 0x03, 0x00, 0x00, 0x62, 0x44, 0x00, 0x00, 0x62, 0x85, 0x00, 0x00, 0x62, 0xC2, 0x00, 0x00,
306
0x22, 0x48, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x48, 0x00, 0x01, 0x00, 0x6C, 0x28, 0x02, 0x00,
307
0x62, 0x80, 0x01, 0x00, 0x60, 0x07, 0x00, 0x00, 0x60, 0x47, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00,
308
0x01, 0x01, 0x00, 0x00, 0x43, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x01, 0xCA, 0x01, 0x00,
309
0x60, 0x03, 0x01, 0x00, 0x01, 0xA0, 0x01, 0x00, 0x60, 0x40, 0x00, 0x00, 0x65, 0x01, 0x00, 0x00,
310
0x55, 0xC0, 0x2E, 0x00, 0x01, 0x18, 0x00, 0x00, 0x43, 0x00, 0x04, 0x00, 0x43, 0x41, 0x06, 0x00,
311
0x6F, 0x00, 0x00, 0x00, 0x61, 0xC1, 0x00, 0x00, 0x61, 0x42, 0x01, 0x00, 0x65, 0xB5, 0x00, 0x00,
312
0x65, 0x73, 0x01, 0x00, 0x65, 0x35, 0x01, 0x00, 0x65, 0x34, 0x01, 0x00, 0x42, 0x04, 0x0D, 0x00,
313
0x01, 0x14, 0x01, 0x00, 0x42, 0x04, 0x03, 0x00, 0x00, 0x20, 0x00, 0x00, 0x43, 0x03, 0x05, 0x00,
314
0x43, 0x85, 0x02, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x48, 0x46, 0x01, 0x00, 0x65, 0xEB, 0x00, 0x00,
315
0x00, 0x9A, 0x00, 0x00, 0x65, 0xB2, 0x01, 0x00, 0x00, 0xA6, 0x01, 0x00, 0x42, 0x86, 0x0D, 0x00,
316
0x61, 0x42, 0x01, 0x00, 0x01, 0xAE, 0x01, 0x00, 0x00, 0x71, 0x00, 0x00, 0x42, 0x82, 0x08, 0x00,
317
0x42, 0xC3, 0x08, 0x00, 0x48, 0x40, 0x01, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x6E, 0x34, 0x02, 0x00,
318
0x65, 0x79, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x6C, 0x36, 0x04, 0x00, 0x6E, 0x34, 0x02, 0x00,
319
0x48, 0x7F, 0x01, 0x00, 0x6C, 0x0A, 0x06, 0x00, 0x6E, 0x34, 0x02, 0x00, 0x6E, 0x05, 0x04, 0x00,
320
0x65, 0x79, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x41, 0x87, 0x03, 0x00, 0x65, 0xBA, 0x00, 0x00,
321
0x65, 0xB2, 0x00, 0x00, 0x42, 0x82, 0x02, 0x00, 0x00, 0x51, 0x00, 0x00, 0x61, 0xC1, 0x00, 0x00,
322
0x65, 0xFB, 0x00, 0x00, 0x65, 0xF3, 0x00, 0x00, 0x41, 0x87, 0x05, 0x00, 0x65, 0xF3, 0x00, 0x00,
323
0x42, 0xC3, 0x08, 0x00, 0x00, 0x59, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00,
324
0x56, 0xC0, 0x21, 0x00, 0x04, 0xDF, 0x01, 0x00, 0x43, 0xC7, 0x15, 0x00, 0x00, 0x38, 0x00, 0x00,
325
0x00, 0x79, 0x00, 0x00, 0x42, 0xC3, 0x20, 0x00, 0x43, 0xC3, 0x04, 0x00, 0x42, 0x00, 0x30, 0x00,
326
0x42, 0x41, 0x30, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x60, 0xC7, 0x01, 0x00,
327
0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00, 0x22, 0x7F, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00,
328
0x6E, 0x34, 0x02, 0x00, 0x6E, 0x05, 0x04, 0x00, 0x4B, 0x41, 0x00, 0x00, 0x60, 0xC7, 0x01, 0x00,
329
0x60, 0x87, 0x01, 0x00, 0x43, 0x86, 0x15, 0x00, 0x00, 0x30, 0x00, 0x00, 0x65, 0x39, 0x01, 0x00,
330
0x42, 0x04, 0x05, 0x00, 0x4E, 0x05, 0x7E, 0x00, 0x6A, 0x1B, 0x06, 0x00, 0x55, 0xC0, 0x3D, 0x00,
331
0x0A, 0x3C, 0x01, 0x00, 0x60, 0xC7, 0x01, 0x00, 0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00,
332
0x22, 0x7C, 0x09, 0x00, 0x22, 0x7F, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x65, 0x7A, 0x01, 0x00,
333
0x42, 0x45, 0x05, 0x00, 0x65, 0xBB, 0x01, 0x00, 0x42, 0x86, 0x05, 0x00, 0x55, 0xC0, 0x3D, 0x00,
334
0x0A, 0x7D, 0x01, 0x00, 0x0A, 0xBE, 0x01, 0x00, 0x07, 0xC7, 0x01, 0x00, 0x0B, 0x7D, 0x01, 0x00,
335
0x0B, 0xBE, 0x01, 0x00, 0x55, 0xC0, 0x3D, 0x00, 0x0A, 0x3C, 0x01, 0x00, 0x60, 0xC7, 0x01, 0x00,
336
0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00, 0x22, 0x7A, 0x05, 0x00, 0x22, 0x7B, 0x07, 0x00,
337
0x22, 0x7C, 0x09, 0x00, 0x22, 0x7D, 0x0B, 0x00, 0x22, 0x7E, 0x0D, 0x00, 0x22, 0x7F, 0x1F, 0x00,
338
0x6F, 0x00, 0x00, 0x00
339
};
340
341
vic_config_t __attribute__((aligned (0x100))) vic_cfg = {0};
342
343
u32 _vic_read_priv(u32 addr)
344
{
345
u32 addr_lsb = addr & 0xFF;
346
347
// Set address LSB.
348
if (addr_lsb)
349
VIC(PVIC_FALCON_ADDR) = addr_lsb >> 2;
350
351
// Set address.
352
u32 val = VIC(PVIC_FALCON_PA_OFFSET + (addr >> 6));
353
354
// Unset address LSB.
355
if (addr_lsb)
356
VIC(PVIC_FALCON_ADDR) = 0;
357
358
return val;
359
}
360
361
static void _vic_write_priv(u32 addr, u32 data)
362
{
363
u32 addr_lsb = addr & 0xFF;
364
365
// Set address LSB.
366
if (addr_lsb)
367
VIC(PVIC_FALCON_ADDR) = addr_lsb >> 2;
368
369
// Set address.
370
VIC(PVIC_FALCON_PA_OFFSET + (addr >> 6)) = data;
371
372
// Unset address LSB.
373
if (addr_lsb)
374
VIC(PVIC_FALCON_ADDR) = 0;
375
}
376
377
static int _vic_wait_idle()
378
{
379
u32 timeout_count = 15000; // 150ms.
380
381
while (VIC(PVIC_FALCON_IDLESTATE))
382
{
383
usleep(10);
384
385
timeout_count--;
386
if (!timeout_count)
387
return -1;
388
};
389
390
return 0;
391
}
392
393
void vic_set_surface(const vic_surface_t *sfc)
394
{
395
u32 flip_x = 0;
396
u32 flip_y = 0;
397
u32 swap_xy = 0;
398
u32 const_alpha = 0;
399
400
u32 width = sfc->width;
401
u32 height = sfc->height;
402
u32 pix_fmt = sfc->pix_fmt;
403
u32 src_buf = sfc->src_buf;
404
u32 dst_buf = sfc->dst_buf;
405
406
// Get format alpha type.
407
switch (sfc->pix_fmt)
408
{
409
case VIC_PIX_FORMAT_L8:
410
case VIC_PIX_FORMAT_X1B5G5R5:
411
case VIC_PIX_FORMAT_B5G5R5X1:
412
case VIC_PIX_FORMAT_X8B8G8R8:
413
case VIC_PIX_FORMAT_X8R8G8B8:
414
case VIC_PIX_FORMAT_B8G8R8X8:
415
case VIC_PIX_FORMAT_R8G8B8X8:
416
const_alpha = 1;
417
break;
418
419
case VIC_PIX_FORMAT_A8B8G8R8:
420
case VIC_PIX_FORMAT_A8R8G8B8:
421
case VIC_PIX_FORMAT_B8G8R8A8:
422
case VIC_PIX_FORMAT_R8G8B8A8:
423
default:
424
break;
425
}
426
427
// Get rotation parameters.
428
switch (sfc->rotation)
429
{
430
case VIC_ROTATION_90:
431
swap_xy = 1;
432
break;
433
434
case VIC_ROTATION_180:
435
flip_x = 1;
436
flip_y = 1;
437
break;
438
439
case VIC_ROTATION_270:
440
flip_x = 1;
441
swap_xy = 1;
442
break;
443
444
case VIC_ROTATION_0:
445
default:
446
break;
447
}
448
449
// Set output surface format.
450
vic_cfg.out_sfc_cfg.OutPixelFormat = pix_fmt;
451
vic_cfg.out_sfc_cfg.OutBlkKind = BLK_KIND_PITCH;
452
vic_cfg.out_sfc_cfg.OutBlkHeight = 0;
453
454
// Set output rotation/flip.
455
vic_cfg.out_cfg.OutputFlipX = flip_x;
456
vic_cfg.out_cfg.OutputFlipY = flip_y;
457
vic_cfg.out_cfg.OutputTranspose = swap_xy;
458
459
// Set output surface resolution.
460
vic_cfg.out_sfc_cfg.OutSurfaceWidth = width - 1;
461
vic_cfg.out_sfc_cfg.OutSurfaceHeight = height - 1;
462
vic_cfg.out_sfc_cfg.OutLumaWidth = width - 1;
463
vic_cfg.out_sfc_cfg.OutLumaHeight = height - 1;
464
465
// Set output destination rectangle. Anything outside will not be touched at output buffer.
466
vic_cfg.out_cfg.TargetRectLeft = 0;
467
vic_cfg.out_cfg.TargetRectRight = width - 1;
468
vic_cfg.out_cfg.TargetRectTop = 0;
469
vic_cfg.out_cfg.TargetRectBottom = height - 1;
470
471
// Initialize slot parameters.
472
vic_cfg.slots[0].slot_cfg.SlotEnable = 1;
473
vic_cfg.slots[0].slot_cfg.SoftClampLow = SOFT_CLAMP_MIN;
474
vic_cfg.slots[0].slot_cfg.SoftClampHigh = SOFT_CLAMP_MAX;
475
vic_cfg.slots[0].slot_cfg.PlanarAlpha = ALPHA_1_0;
476
vic_cfg.slots[0].slot_cfg.ConstantAlpha = const_alpha;
477
vic_cfg.slots[0].slot_cfg.FrameFormat = FORMAT_PROGRESSIVE;
478
479
// Set input source rectangle.
480
vic_cfg.slots[0].slot_cfg.SourceRectLeft = 0;
481
vic_cfg.slots[0].slot_cfg.SourceRectRight = (width - 1) << 16;
482
vic_cfg.slots[0].slot_cfg.SourceRectTop = 0;
483
vic_cfg.slots[0].slot_cfg.SourceRectBottom = (height - 1) << 16;
484
485
// Set input destination rectangle.
486
vic_cfg.slots[0].slot_cfg.DestRectLeft = 0;
487
vic_cfg.slots[0].slot_cfg.DestRectRight = (width - 1);
488
vic_cfg.slots[0].slot_cfg.DestRectTop = 0;
489
vic_cfg.slots[0].slot_cfg.DestRectBottom = (height - 1);
490
491
// Set input surface format.
492
vic_cfg.slots[0].slot_sfc_cfg.SlotPixelFormat = pix_fmt;
493
vic_cfg.slots[0].slot_sfc_cfg.SlotBlkKind = BLK_KIND_PITCH;
494
vic_cfg.slots[0].slot_sfc_cfg.SlotBlkHeight = 0;
495
vic_cfg.slots[0].slot_sfc_cfg.SlotCacheWidth = CACHE_WIDTH_64BX4;
496
497
// Set input surface resolution.
498
vic_cfg.slots[0].slot_sfc_cfg.SlotSurfaceWidth = width - 1;
499
vic_cfg.slots[0].slot_sfc_cfg.SlotSurfaceHeight = height - 1;
500
vic_cfg.slots[0].slot_sfc_cfg.SlotLumaWidth = width - 1;
501
vic_cfg.slots[0].slot_sfc_cfg.SlotLumaHeight = height - 1;
502
503
// Flush data.
504
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false);
505
506
// Set parameters base and size. Causes a parse by surface cache.
507
_vic_write_priv(VIC_SC_PRAMBASE, (u32)&vic_cfg >> 8);
508
_vic_write_priv(VIC_SC_PRAMSIZE, sizeof(vic_config_t) >> 6);
509
510
// Wait for surface cache to get ready.
511
_vic_wait_idle();
512
513
// Set slot mapping.
514
_vic_write_priv(VIC_FC_SLOT_MAP, 0xFFFFFFF0);
515
516
// Set input surface buffer.
517
_vic_write_priv(VIC_SC_SFC0_BASE_LUMA(0), src_buf >> 8);
518
519
// Set output surface buffer.
520
_vic_write_priv(VIC_BL_TARGET_BASADR, dst_buf >> 8);
521
522
// Set blending config and push changes to surface cache.
523
_vic_write_priv(VIC_BL_CONFIG, SLOTMASK(0x1F) | PROCESS_CFG_STRUCT_TRIGGER | SUBPARTITION_MODE);
524
525
// Wait for surface cache to get ready.
526
_vic_wait_idle();
527
}
528
529
int vic_compose()
530
{
531
// Wait for surface cache to get ready. Otherwise VIC will hang.
532
int res = _vic_wait_idle();
533
534
// Start composition of a single frame.
535
_vic_write_priv(VIC_FC_COMPOSE, COMPOSE_START);
536
537
return res;
538
}
539
540
int vic_init()
541
{
542
clock_enable_vic();
543
544
// Load Fetch Control Engine microcode.
545
for (u32 i = 0; i < sizeof(vic_fce_ucode) / sizeof(u32); i++)
546
{
547
_vic_write_priv(VIC_FC_FCE_UCODE_ADDR, (i * sizeof(u32)));
548
_vic_write_priv(VIC_FC_FCE_UCODE_INST, *(u32 *)&vic_fce_ucode[i * sizeof(u32)]);
549
}
550
551
// Start Fetch Control Engine.
552
_vic_write_priv(VIC_FC_FCE_CTRL, START_TRIGGER);
553
554
return _vic_wait_idle();
555
}
556
557
void vic_end()
558
{
559
clock_disable_vic();
560
}
561
562