blob: 7b31b3aac0e0664a8ddecc94a4723d45fe94fda5 [file] [log] [blame]
hai.cao8c827c02023-02-28 11:12:05 +08001// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2/*
3 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4 */
5
6#include <amlogic/cpu_id.h>
7#include <config.h>
8#include <common.h>
9#include <env.h>
10#include <amlogic/media/vpp/vpp.h>
11#ifdef CONFIG_AML_HDMITX20
12#include <amlogic/media/vout/hdmitx/hdmitx_module.h>
13#else
14#include <amlogic/media/vout/hdmitx21/hdmitx_module.h>
15#endif
16#include "vpp_reg.h"
17#include "vpp.h"
18#include "hdr2.h"
19
20#define VPP_PR(fmt, args...) printf("vpp: "fmt"", ## args)
21
22static unsigned char vpp_init_flag;
23
24/***************************** gamma table ****************************/
25#define GAMMA_SIZE (256)
26static unsigned short gamma_table_r[GAMMA_SIZE] = {
27 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
28 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124,
29 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188,
30 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252,
31 256, 260, 264, 268, 272, 276, 280, 284, 288, 292, 296, 300, 304, 308, 312, 316,
32 320, 324, 328, 332, 336, 340, 344, 348, 352, 356, 360, 364, 368, 372, 376, 380,
33 384, 388, 392, 396, 400, 404, 408, 412, 416, 420, 424, 428, 432, 436, 440, 444,
34 448, 452, 456, 460, 464, 468, 472, 476, 480, 484, 488, 492, 496, 500, 504, 508,
35 512, 516, 520, 524, 528, 532, 536, 540, 544, 548, 552, 556, 560, 564, 568, 572,
36 576, 580, 584, 588, 592, 596, 600, 604, 608, 612, 616, 620, 624, 628, 632, 636,
37 640, 644, 648, 652, 656, 660, 664, 668, 672, 676, 680, 684, 688, 692, 696, 700,
38 704, 708, 712, 716, 720, 724, 728, 732, 736, 740, 744, 748, 752, 756, 760, 764,
39 768, 772, 776, 780, 784, 788, 792, 796, 800, 804, 808, 812, 816, 820, 824, 828,
40 832, 836, 840, 844, 848, 852, 856, 860, 864, 868, 872, 876, 880, 884, 888, 892,
41 896, 900, 904, 908, 912, 916, 920, 924, 928, 932, 936, 940, 944, 948, 952, 956,
42 960, 964, 968, 972, 976, 980, 984, 988, 992, 996, 1000, 1004, 1008, 1012, 1016, 1020,
43};
44static unsigned short gamma_table_g[GAMMA_SIZE] = {
45 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
46 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124,
47 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188,
48 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252,
49 256, 260, 264, 268, 272, 276, 280, 284, 288, 292, 296, 300, 304, 308, 312, 316,
50 320, 324, 328, 332, 336, 340, 344, 348, 352, 356, 360, 364, 368, 372, 376, 380,
51 384, 388, 392, 396, 400, 404, 408, 412, 416, 420, 424, 428, 432, 436, 440, 444,
52 448, 452, 456, 460, 464, 468, 472, 476, 480, 484, 488, 492, 496, 500, 504, 508,
53 512, 516, 520, 524, 528, 532, 536, 540, 544, 548, 552, 556, 560, 564, 568, 572,
54 576, 580, 584, 588, 592, 596, 600, 604, 608, 612, 616, 620, 624, 628, 632, 636,
55 640, 644, 648, 652, 656, 660, 664, 668, 672, 676, 680, 684, 688, 692, 696, 700,
56 704, 708, 712, 716, 720, 724, 728, 732, 736, 740, 744, 748, 752, 756, 760, 764,
57 768, 772, 776, 780, 784, 788, 792, 796, 800, 804, 808, 812, 816, 820, 824, 828,
58 832, 836, 840, 844, 848, 852, 856, 860, 864, 868, 872, 876, 880, 884, 888, 892,
59 896, 900, 904, 908, 912, 916, 920, 924, 928, 932, 936, 940, 944, 948, 952, 956,
60 960, 964, 968, 972, 976, 980, 984, 988, 992, 996, 1000, 1004, 1008, 1012, 1016, 1020,
61};
62static unsigned short gamma_table_b[GAMMA_SIZE] = {
63 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
64 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124,
65 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188,
66 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252,
67 256, 260, 264, 268, 272, 276, 280, 284, 288, 292, 296, 300, 304, 308, 312, 316,
68 320, 324, 328, 332, 336, 340, 344, 348, 352, 356, 360, 364, 368, 372, 376, 380,
69 384, 388, 392, 396, 400, 404, 408, 412, 416, 420, 424, 428, 432, 436, 440, 444,
70 448, 452, 456, 460, 464, 468, 472, 476, 480, 484, 488, 492, 496, 500, 504, 508,
71 512, 516, 520, 524, 528, 532, 536, 540, 544, 548, 552, 556, 560, 564, 568, 572,
72 576, 580, 584, 588, 592, 596, 600, 604, 608, 612, 616, 620, 624, 628, 632, 636,
73 640, 644, 648, 652, 656, 660, 664, 668, 672, 676, 680, 684, 688, 692, 696, 700,
74 704, 708, 712, 716, 720, 724, 728, 732, 736, 740, 744, 748, 752, 756, 760, 764,
75 768, 772, 776, 780, 784, 788, 792, 796, 800, 804, 808, 812, 816, 820, 824, 828,
76 832, 836, 840, 844, 848, 852, 856, 860, 864, 868, 872, 876, 880, 884, 888, 892,
77 896, 900, 904, 908, 912, 916, 920, 924, 928, 932, 936, 940, 944, 948, 952, 956,
78 960, 964, 968, 972, 976, 980, 984, 988, 992, 996, 1000, 1004, 1008, 1012, 1016, 1020,
79};
80
81/***************************** gxl hdr ****************************/
82
83#define EOTF_LUT_SIZE 33
84#ifndef AML_S5_DISPLAY
85static unsigned int osd_eotf_r_mapping[EOTF_LUT_SIZE] = {
86 0x0000, 0x0200, 0x0400, 0x0600,
87 0x0800, 0x0a00, 0x0c00, 0x0e00,
88 0x1000, 0x1200, 0x1400, 0x1600,
89 0x1800, 0x1a00, 0x1c00, 0x1e00,
90 0x2000, 0x2200, 0x2400, 0x2600,
91 0x2800, 0x2a00, 0x2c00, 0x2e00,
92 0x3000, 0x3200, 0x3400, 0x3600,
93 0x3800, 0x3a00, 0x3c00, 0x3e00,
94 0x4000
95};
96
97static unsigned int osd_eotf_g_mapping[EOTF_LUT_SIZE] = {
98 0x0000, 0x0200, 0x0400, 0x0600,
99 0x0800, 0x0a00, 0x0c00, 0x0e00,
100 0x1000, 0x1200, 0x1400, 0x1600,
101 0x1800, 0x1a00, 0x1c00, 0x1e00,
102 0x2000, 0x2200, 0x2400, 0x2600,
103 0x2800, 0x2a00, 0x2c00, 0x2e00,
104 0x3000, 0x3200, 0x3400, 0x3600,
105 0x3800, 0x3a00, 0x3c00, 0x3e00,
106 0x4000
107};
108
109static unsigned int osd_eotf_b_mapping[EOTF_LUT_SIZE] = {
110 0x0000, 0x0200, 0x0400, 0x0600,
111 0x0800, 0x0a00, 0x0c00, 0x0e00,
112 0x1000, 0x1200, 0x1400, 0x1600,
113 0x1800, 0x1a00, 0x1c00, 0x1e00,
114 0x2000, 0x2200, 0x2400, 0x2600,
115 0x2800, 0x2a00, 0x2c00, 0x2e00,
116 0x3000, 0x3200, 0x3400, 0x3600,
117 0x3800, 0x3a00, 0x3c00, 0x3e00,
118 0x4000
119};
120
121static unsigned int video_eotf_r_mapping[EOTF_LUT_SIZE] = {
122 0x0000, 0x0200, 0x0400, 0x0600,
123 0x0800, 0x0a00, 0x0c00, 0x0e00,
124 0x1000, 0x1200, 0x1400, 0x1600,
125 0x1800, 0x1a00, 0x1c00, 0x1e00,
126 0x2000, 0x2200, 0x2400, 0x2600,
127 0x2800, 0x2a00, 0x2c00, 0x2e00,
128 0x3000, 0x3200, 0x3400, 0x3600,
129 0x3800, 0x3a00, 0x3c00, 0x3e00,
130 0x4000
131};
132
133static unsigned int video_eotf_g_mapping[EOTF_LUT_SIZE] = {
134 0x0000, 0x0200, 0x0400, 0x0600,
135 0x0800, 0x0a00, 0x0c00, 0x0e00,
136 0x1000, 0x1200, 0x1400, 0x1600,
137 0x1800, 0x1a00, 0x1c00, 0x1e00,
138 0x2000, 0x2200, 0x2400, 0x2600,
139 0x2800, 0x2a00, 0x2c00, 0x2e00,
140 0x3000, 0x3200, 0x3400, 0x3600,
141 0x3800, 0x3a00, 0x3c00, 0x3e00,
142 0x4000
143};
144
145static unsigned int video_eotf_b_mapping[EOTF_LUT_SIZE] = {
146 0x0000, 0x0200, 0x0400, 0x0600,
147 0x0800, 0x0a00, 0x0c00, 0x0e00,
148 0x1000, 0x1200, 0x1400, 0x1600,
149 0x1800, 0x1a00, 0x1c00, 0x1e00,
150 0x2000, 0x2200, 0x2400, 0x2600,
151 0x2800, 0x2a00, 0x2c00, 0x2e00,
152 0x3000, 0x3200, 0x3400, 0x3600,
153 0x3800, 0x3a00, 0x3c00, 0x3e00,
154 0x4000
155};
156#endif
157#define EOTF_COEFF_NORM(a) ((int)((((a) * 4096.0) + 1) / 2))
158#define EOTF_COEFF_SIZE 10
159#define EOTF_COEFF_RIGHTSHIFT 1
160#ifndef AML_S5_DISPLAY
161static int osd_eotf_coeff[EOTF_COEFF_SIZE] = {
162 EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0),
163 EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0),
164 EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0),
165 EOTF_COEFF_RIGHTSHIFT /* right shift */
166};
167
168static int video_eotf_coeff[EOTF_COEFF_SIZE] = {
169 EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0),
170 EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0),
171 EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0),
172 EOTF_COEFF_RIGHTSHIFT /* right shift */
173};
174
175/******************** osd oetf **************/
176
177#endif
178#define OSD_OETF_LUT_SIZE 41
179#ifndef AML_S5_DISPLAY
180static unsigned int osd_oetf_r_mapping[OSD_OETF_LUT_SIZE] = {
181 0, 150, 250, 330,
182 395, 445, 485, 520,
183 544, 632, 686, 725,
184 756, 782, 803, 822,
185 839, 854, 868, 880,
186 892, 902, 913, 922,
187 931, 939, 947, 954,
188 961, 968, 974, 981,
189 986, 993, 998, 1003,
190 1009, 1014, 1018, 1023,
191 0
192};
193
194static unsigned int osd_oetf_g_mapping[OSD_OETF_LUT_SIZE] = {
195 0, 0, 0, 0,
196 0, 32, 64, 96,
197 128, 160, 196, 224,
198 256, 288, 320, 352,
199 384, 416, 448, 480,
200 512, 544, 576, 608,
201 640, 672, 704, 736,
202 768, 800, 832, 864,
203 896, 928, 960, 992,
204 1023, 1023, 1023, 1023,
205 1023
206};
207
208static unsigned int osd_oetf_b_mapping[OSD_OETF_LUT_SIZE] = {
209 0, 0, 0, 0,
210 0, 32, 64, 96,
211 128, 160, 196, 224,
212 256, 288, 320, 352,
213 384, 416, 448, 480,
214 512, 544, 576, 608,
215 640, 672, 704, 736,
216 768, 800, 832, 864,
217 896, 928, 960, 992,
218 1023, 1023, 1023, 1023,
219 1023
220};
221
222/************ video oetf ***************/
223
224#define VIDEO_OETF_LUT_SIZE 289
225static unsigned int video_oetf_r_mapping[VIDEO_OETF_LUT_SIZE] = {
226 0, 0, 0, 0, 0, 0, 0, 0,
227 0, 0, 0, 0, 0, 0, 0, 0,
228 4, 8, 12, 16, 20, 24, 28, 32,
229 36, 40, 44, 48, 52, 56, 60, 64,
230 68, 72, 76, 80, 84, 88, 92, 96,
231 100, 104, 108, 112, 116, 120, 124, 128,
232 132, 136, 140, 144, 148, 152, 156, 160,
233 164, 168, 172, 176, 180, 184, 188, 192,
234 196, 200, 204, 208, 212, 216, 220, 224,
235 228, 232, 236, 240, 244, 248, 252, 256,
236 260, 264, 268, 272, 276, 280, 284, 288,
237 292, 296, 300, 304, 308, 312, 316, 320,
238 324, 328, 332, 336, 340, 344, 348, 352,
239 356, 360, 364, 368, 372, 376, 380, 384,
240 388, 392, 396, 400, 404, 408, 412, 416,
241 420, 424, 428, 432, 436, 440, 444, 448,
242 452, 456, 460, 464, 468, 472, 476, 480,
243 484, 488, 492, 496, 500, 504, 508, 512,
244 516, 520, 524, 528, 532, 536, 540, 544,
245 548, 552, 556, 560, 564, 568, 572, 576,
246 580, 584, 588, 592, 596, 600, 604, 608,
247 612, 616, 620, 624, 628, 632, 636, 640,
248 644, 648, 652, 656, 660, 664, 668, 672,
249 676, 680, 684, 688, 692, 696, 700, 704,
250 708, 712, 716, 720, 724, 728, 732, 736,
251 740, 744, 748, 752, 756, 760, 764, 768,
252 772, 776, 780, 784, 788, 792, 796, 800,
253 804, 808, 812, 816, 820, 824, 828, 832,
254 836, 840, 844, 848, 852, 856, 860, 864,
255 868, 872, 876, 880, 884, 888, 892, 896,
256 900, 904, 908, 912, 916, 920, 924, 928,
257 932, 936, 940, 944, 948, 952, 956, 960,
258 964, 968, 972, 976, 980, 984, 988, 992,
259 996, 1000, 1004, 1008, 1012, 1016, 1020, 1023,
260 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
261 1023
262};
263
264static unsigned int video_oetf_g_mapping[VIDEO_OETF_LUT_SIZE] = {
265 0, 0, 0, 0, 0, 0, 0, 0,
266 0, 0, 0, 0, 0, 0, 0, 0,
267 4, 8, 12, 16, 20, 24, 28, 32,
268 36, 40, 44, 48, 52, 56, 60, 64,
269 68, 72, 76, 80, 84, 88, 92, 96,
270 100, 104, 108, 112, 116, 120, 124, 128,
271 132, 136, 140, 144, 148, 152, 156, 160,
272 164, 168, 172, 176, 180, 184, 188, 192,
273 196, 200, 204, 208, 212, 216, 220, 224,
274 228, 232, 236, 240, 244, 248, 252, 256,
275 260, 264, 268, 272, 276, 280, 284, 288,
276 292, 296, 300, 304, 308, 312, 316, 320,
277 324, 328, 332, 336, 340, 344, 348, 352,
278 356, 360, 364, 368, 372, 376, 380, 384,
279 388, 392, 396, 400, 404, 408, 412, 416,
280 420, 424, 428, 432, 436, 440, 444, 448,
281 452, 456, 460, 464, 468, 472, 476, 480,
282 484, 488, 492, 496, 500, 504, 508, 512,
283 516, 520, 524, 528, 532, 536, 540, 544,
284 548, 552, 556, 560, 564, 568, 572, 576,
285 580, 584, 588, 592, 596, 600, 604, 608,
286 612, 616, 620, 624, 628, 632, 636, 640,
287 644, 648, 652, 656, 660, 664, 668, 672,
288 676, 680, 684, 688, 692, 696, 700, 704,
289 708, 712, 716, 720, 724, 728, 732, 736,
290 740, 744, 748, 752, 756, 760, 764, 768,
291 772, 776, 780, 784, 788, 792, 796, 800,
292 804, 808, 812, 816, 820, 824, 828, 832,
293 836, 840, 844, 848, 852, 856, 860, 864,
294 868, 872, 876, 880, 884, 888, 892, 896,
295 900, 904, 908, 912, 916, 920, 924, 928,
296 932, 936, 940, 944, 948, 952, 956, 960,
297 964, 968, 972, 976, 980, 984, 988, 992,
298 996, 1000, 1004, 1008, 1012, 1016, 1020, 1023,
299 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
300 1023
301};
302
303static unsigned int video_oetf_b_mapping[VIDEO_OETF_LUT_SIZE] = {
304 0, 0, 0, 0, 0, 0, 0, 0,
305 0, 0, 0, 0, 0, 0, 0, 0,
306 4, 8, 12, 16, 20, 24, 28, 32,
307 36, 40, 44, 48, 52, 56, 60, 64,
308 68, 72, 76, 80, 84, 88, 92, 96,
309 100, 104, 108, 112, 116, 120, 124, 128,
310 132, 136, 140, 144, 148, 152, 156, 160,
311 164, 168, 172, 176, 180, 184, 188, 192,
312 196, 200, 204, 208, 212, 216, 220, 224,
313 228, 232, 236, 240, 244, 248, 252, 256,
314 260, 264, 268, 272, 276, 280, 284, 288,
315 292, 296, 300, 304, 308, 312, 316, 320,
316 324, 328, 332, 336, 340, 344, 348, 352,
317 356, 360, 364, 368, 372, 376, 380, 384,
318 388, 392, 396, 400, 404, 408, 412, 416,
319 420, 424, 428, 432, 436, 440, 444, 448,
320 452, 456, 460, 464, 468, 472, 476, 480,
321 484, 488, 492, 496, 500, 504, 508, 512,
322 516, 520, 524, 528, 532, 536, 540, 544,
323 548, 552, 556, 560, 564, 568, 572, 576,
324 580, 584, 588, 592, 596, 600, 604, 608,
325 612, 616, 620, 624, 628, 632, 636, 640,
326 644, 648, 652, 656, 660, 664, 668, 672,
327 676, 680, 684, 688, 692, 696, 700, 704,
328 708, 712, 716, 720, 724, 728, 732, 736,
329 740, 744, 748, 752, 756, 760, 764, 768,
330 772, 776, 780, 784, 788, 792, 796, 800,
331 804, 808, 812, 816, 820, 824, 828, 832,
332 836, 840, 844, 848, 852, 856, 860, 864,
333 868, 872, 876, 880, 884, 888, 892, 896,
334 900, 904, 908, 912, 916, 920, 924, 928,
335 932, 936, 940, 944, 948, 952, 956, 960,
336 964, 968, 972, 976, 980, 984, 988, 992,
337 996, 1000, 1004, 1008, 1012, 1016, 1020, 1023,
338 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
339 1023
340};
341#endif
342#define COEFF_NORM(a) ((int)((((a) * 2048.0) + 1) / 2))
343#define COEFF_NORM12(a) ((int)((((a) * 8192.0) + 1) / 2))
344
345#define MATRIX_5x3_COEF_SIZE 24
346#ifndef AML_S5_DISPLAY
347/******* osd1 matrix0 *******/
348/* default rgb to yuv_limit */
349static int osd_matrix_coeff[MATRIX_5x3_COEF_SIZE] = {
350 0, 0, 0, /* pre offset */
351 COEFF_NORM(0.2126), COEFF_NORM(0.7152), COEFF_NORM(0.0722),
352 COEFF_NORM(-0.11457), COEFF_NORM(-0.38543), COEFF_NORM(0.5),
353 COEFF_NORM(0.5), COEFF_NORM(-0.45415), COEFF_NORM(-0.045847),
354 0, 0, 0, /* 30/31/32 */
355 0, 0, 0, /* 40/41/42 */
356 0, 512, 512, /* offset */
357 0, 0, 0 /* mode, right_shift, clip_en */
358};
359
360static int vd1_matrix_coeff[MATRIX_5x3_COEF_SIZE] = {
361 0, 0, 0, /* pre offset */
362 COEFF_NORM(1.0), COEFF_NORM(0.0), COEFF_NORM(0.0),
363 COEFF_NORM(0.0), COEFF_NORM(1.0), COEFF_NORM(0.0),
364 COEFF_NORM(0.0), COEFF_NORM(0.0), COEFF_NORM(1.0),
365 0, 0, 0, /* 30/31/32 */
366 0, 0, 0, /* 40/41/42 */
367 0, 0, 0, /* offset */
368 0, 0, 0 /* mode, right_shift, clip_en */
369};
370
371static int vd2_matrix_coeff[MATRIX_5x3_COEF_SIZE] = {
372 0, 0, 0, /* pre offset */
373 COEFF_NORM(1.0), COEFF_NORM(0.0), COEFF_NORM(0.0),
374 COEFF_NORM(0.0), COEFF_NORM(1.0), COEFF_NORM(0.0),
375 COEFF_NORM(0.0), COEFF_NORM(0.0), COEFF_NORM(1.0),
376 0, 0, 0, /* 30/31/32 */
377 0, 0, 0, /* 40/41/42 */
378 0, 0, 0, /* offset */
379 0, 0, 0 /* mode, right_shift, clip_en */
380};
381
382static int post_matrix_coeff[MATRIX_5x3_COEF_SIZE] = {
383 0, 0, 0, /* pre offset */
384 COEFF_NORM(1.0), COEFF_NORM(0.0), COEFF_NORM(0.0),
385 COEFF_NORM(0.0), COEFF_NORM(1.0), COEFF_NORM(0.0),
386 COEFF_NORM(0.0), COEFF_NORM(0.0), COEFF_NORM(1.0),
387 0, 0, 0, /* 30/31/32 */
388 0, 0, 0, /* 40/41/42 */
389 0, 0, 0, /* offset */
390 0, 0, 0 /* mode, right_shift, clip_en */
391};
392
393static int xvycc_matrix_coeff[MATRIX_5x3_COEF_SIZE] = {
394 0, 0, 0, /* pre offset */
395 COEFF_NORM(1.0), COEFF_NORM(0.0), COEFF_NORM(0.0),
396 COEFF_NORM(0.0), COEFF_NORM(1.0), COEFF_NORM(0.0),
397 COEFF_NORM(0.0), COEFF_NORM(0.0), COEFF_NORM(1.0),
398 0, 0, 0, /* 30/31/32 */
399 0, 0, 0, /* 40/41/42 */
400 0, 0, 0, /* offset */
401 0, 0, 0 /* mode, right_shift, clip_en */
402};
403#endif
404
405static int RGB709_to_YUV709l_coeff[MATRIX_5x3_COEF_SIZE] = {
406 0, 0, 0, /* pre offset */
407 COEFF_NORM(0.181873), COEFF_NORM(0.611831), COEFF_NORM(0.061765),
408 COEFF_NORM(-0.100251), COEFF_NORM(-0.337249), COEFF_NORM(0.437500),
409 COEFF_NORM(0.437500), COEFF_NORM(-0.397384), COEFF_NORM(-0.040116),
410 0, 0, 0, /* 10'/11'/12' */
411 0, 0, 0, /* 20'/21'/22' */
412 64, 512, 512, /* offset */
413 0, 0, 0 /* mode, right_shift, clip_en */
414};
415
416#ifndef AML_S5_DISPLAY
417/* eotf matrix: bypass */
418static int eotf_bypass_coeff[EOTF_COEFF_SIZE] = {
419 EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0),
420 EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0),
421 EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0),
422 EOTF_COEFF_RIGHTSHIFT /* right shift */
423};
424
425/* eotf lut: linear */
426static unsigned int eotf_33_linear_mapping[EOTF_LUT_SIZE] = {
427 0x0000, 0x0200, 0x0400, 0x0600,
428 0x0800, 0x0a00, 0x0c00, 0x0e00,
429 0x1000, 0x1200, 0x1400, 0x1600,
430 0x1800, 0x1a00, 0x1c00, 0x1e00,
431 0x2000, 0x2200, 0x2400, 0x2600,
432 0x2800, 0x2a00, 0x2c00, 0x2e00,
433 0x3000, 0x3200, 0x3400, 0x3600,
434 0x3800, 0x3a00, 0x3c00, 0x3e00,
435 0x4000
436};
437
438/* osd oetf lut: linear */
439static unsigned int oetf_41_linear_mapping[OSD_OETF_LUT_SIZE] = {
440 0, 0, 0, 0,
441 0, 32, 64, 96,
442 128, 160, 196, 224,
443 256, 288, 320, 352,
444 384, 416, 448, 480,
445 512, 544, 576, 608,
446 640, 672, 704, 736,
447 768, 800, 832, 864,
448 896, 928, 960, 992,
449 1023, 1023, 1023, 1023,
450 1023
451};
452#endif
453
454/*static int YUV709l_to_RGB709_coeff[MATRIX_5x3_COEF_SIZE] = { */
455/* -64, -512, -512, pre offset */
456/* COEFF_NORM(1.16895), COEFF_NORM(0.00000), COEFF_NORM(1.79977), */
457/* COEFF_NORM(1.16895), COEFF_NORM(-0.21408), COEFF_NORM(-0.53500), */
458/* COEFF_NORM(1.16895), COEFF_NORM(2.12069), COEFF_NORM(0.00000), */
459/* 0, 0, 0, 30/31/32 */
460/* 0, 0, 0, 40/41/42 */
461/* 0, 0, 0, offset */
462/* 0, 0, 0 mode, right_shift, clip_en */
463/*}; */
464
465static int YUV709l_to_RGB709_coeff12[MATRIX_5x3_COEF_SIZE] = {
466 -256, -2048, -2048, /* pre offset */
467 COEFF_NORM12(1.16895), COEFF_NORM12(0.00000), COEFF_NORM12(1.79977),
468 COEFF_NORM12(1.16895), COEFF_NORM12(-0.21408), COEFF_NORM12(-0.53500),
469 COEFF_NORM12(1.16895), COEFF_NORM12(2.12069), COEFF_NORM12(0.00000),
470 0, 0, 0, /* 30/31/32 */
471 0, 0, 0, /* 40/41/42 */
472 0, 0, 0, /* offset */
473 0, 0, 0 /* mode, right_shift, clip_en */
474};
475
476#define SIGN(a) ((a < 0) ? "-" : "+")
477#define DECI(a) ((a) / 1024)
478#define FRAC(a) ((((a) >= 0) ? \
479 ((a) & 0x3ff) : ((~(a) + 1) & 0x3ff)) * 10000 / 1024)
480
481#define INORM 50000
482#ifdef CONFIG_AML_HDMITX
483static u32 bt2020_primaries[3][2] = {
484 {0.17 * INORM + 0.5, 0.797 * INORM + 0.5}, /* G */
485 {0.131 * INORM + 0.5, 0.046 * INORM + 0.5}, /* B */
486 {0.708 * INORM + 0.5, 0.292 * INORM + 0.5}, /* R */
487};
488
489static u32 bt2020_white_point[2] = {
490 0.3127 * INORM + 0.5, 0.3290 * INORM + 0.5
491};
492#endif
493
494static int vpp_get_chip_type(void)
495{
496 unsigned int cpu_type;
497
498 cpu_type = get_cpu_id().family_id;
499 return cpu_type;
500}
501
502int is_osd_high_version(void)
503{
504 u32 family_id = get_cpu_id().family_id;
505
506 if (family_id == MESON_CPU_MAJOR_ID_G12A ||
507 family_id == MESON_CPU_MAJOR_ID_G12B ||
508 family_id >= MESON_CPU_MAJOR_ID_SM1)
509 return 1;
510 else
511 return 0;
512}
513
514/* OSD csc defines end */
515
516#ifndef AML_S5_DISPLAY
517static void vpp_set_matrix_default_init(void)
518{
519 /* default probe_sel, for highlight en */
520 vpp_reg_setb(VPP_MATRIX_CTRL, 0xf, 11, 4);
521}
522#endif
523
524static void vpp_top_post2_matrix_yuv2rgb(int vpp_top)
525{
526 int *m = NULL;
527 /* POST2 matrix: YUV limit -> RGB default is 12bit*/
528 m = YUV709l_to_RGB709_coeff12;
529
530 if (vpp_top == 0) {
531 /* VPP WRAP POST2 matrix */
532 vpp_reg_write(VPP_POST2_MATRIX_PRE_OFFSET0_1,
533 (((m[0] >> 2) & 0xfff) << 16) | ((m[1] >> 2) & 0xfff));
534 vpp_reg_write(VPP_POST2_MATRIX_PRE_OFFSET2,
535 (m[2] >> 2) & 0xfff);
536 vpp_reg_write(VPP_POST2_MATRIX_COEF00_01,
537 (((m[3] >> 2) & 0x1fff) << 16) | ((m[4] >> 2) & 0x1fff));
538 vpp_reg_write(VPP_POST2_MATRIX_COEF02_10,
539 (((m[5] >> 2) & 0x1fff) << 16) | ((m[6] >> 2) & 0x1fff));
540 vpp_reg_write(VPP_POST2_MATRIX_COEF11_12,
541 (((m[7] >> 2) & 0x1fff) << 16) | ((m[8] >> 2) & 0x1fff));
542 vpp_reg_write(VPP_POST2_MATRIX_COEF20_21,
543 (((m[9] >> 2) & 0x1fff) << 16) | ((m[10] >> 2) & 0x1fff));
544 vpp_reg_write(VPP_POST2_MATRIX_COEF22,
545 (m[11] >> 2) & 0x1fff);
546 vpp_reg_write(VPP_POST2_MATRIX_OFFSET0_1,
547 (((m[18] >> 2) & 0xfff) << 16) | ((m[19] >> 2) & 0xfff));
548 vpp_reg_write(VPP_POST2_MATRIX_OFFSET2,
549 (m[20] >> 2) & 0xfff);
550 vpp_reg_setb(VPP_POST2_MATRIX_EN_CTRL, 1, 0, 1);
551 } else if (vpp_top == 1) {
552 vpp_reg_write(VPP1_MATRIX_PRE_OFFSET0_1,
553 (((m[0] >> 2) & 0xfff) << 16) | ((m[1] >> 2) & 0xfff));
554 vpp_reg_write(VPP1_MATRIX_PRE_OFFSET2,
555 (m[2] >> 2) & 0xfff);
556 vpp_reg_write(VPP1_MATRIX_COEF00_01,
557 (((m[3] >> 2) & 0x1fff) << 16) | ((m[4] >> 2) & 0x1fff));
558 vpp_reg_write(VPP1_MATRIX_COEF02_10,
559 (((m[5] >> 2) & 0x1fff) << 16) | ((m[6] >> 2) & 0x1fff));
560 vpp_reg_write(VPP1_MATRIX_COEF11_12,
561 (((m[7] >> 2) & 0x1fff) << 16) | ((m[8] >> 2) & 0x1fff));
562 vpp_reg_write(VPP1_MATRIX_COEF20_21,
563 (((m[9] >> 2) & 0x1fff) << 16) | ((m[10] >> 2) & 0x1fff));
564 vpp_reg_write(VPP1_MATRIX_COEF22,
565 (m[11] >> 2) & 0x1fff);
566
567 vpp_reg_write(VPP1_MATRIX_OFFSET0_1,
568 (((m[18] >> 2) & 0xfff) << 16) | ((m[19] >> 2) & 0xfff));
569 vpp_reg_write(VPP1_MATRIX_OFFSET2,
570 (m[20] >> 2) & 0xfff);
571
572 vpp_reg_setb(VPP1_MATRIX_EN_CTRL, 1, 0, 1);
573 } else if (vpp_top == 2) {
574 vpp_reg_write(VPP2_MATRIX_PRE_OFFSET0_1,
575 (((m[0] >> 2) & 0xfff) << 16) | ((m[1] >> 2) & 0xfff));
576 vpp_reg_write(VPP2_MATRIX_PRE_OFFSET2,
577 (m[2] >> 2) & 0xfff);
578 vpp_reg_write(VPP2_MATRIX_COEF00_01,
579 (((m[3] >> 2) & 0x1fff) << 16) | ((m[4] >> 2) & 0x1fff));
580 vpp_reg_write(VPP2_MATRIX_COEF02_10,
581 (((m[5] >> 2) & 0x1fff) << 16) | ((m[6] >> 2) & 0x1fff));
582 vpp_reg_write(VPP2_MATRIX_COEF11_12,
583 (((m[7] >> 2) & 0x1fff) << 16) | ((m[8] >> 2) & 0x1fff));
584 vpp_reg_write(VPP2_MATRIX_COEF20_21,
585 (((m[9] >> 2) & 0x1fff) << 16) | ((m[10] >> 2) & 0x1fff));
586 vpp_reg_write(VPP2_MATRIX_COEF22,
587 (m[11] >> 2) & 0x1fff);
588
589 vpp_reg_write(VPP2_MATRIX_OFFSET0_1,
590 (((m[18] >> 2) & 0xfff) << 16) | ((m[19] >> 2) & 0xfff));
591 vpp_reg_write(VPP2_MATRIX_OFFSET2,
592 (m[20] >> 2) & 0xfff);
593
594 vpp_reg_setb(VPP2_MATRIX_EN_CTRL, 1, 0, 1);
595 }
596
597}
598static void vpp_set_matrix_ycbcr2rgb(int vd1_or_vd2_or_post, int mode)
599{
600 //VPP_PR("%s: %d, %d\n", __func__, vd1_or_vd2_or_post, mode);
601
602 if (is_osd_high_version()) {
603 /* vpp top0 */
604 vpp_top_post2_matrix_yuv2rgb(0);
605 VPP_PR("g12a/b post2(bit12) matrix: YUV limit -> RGB ..............\n");
606 return;
607 }
608#ifndef AML_S5_DISPLAY
609 if (vd1_or_vd2_or_post == 0) { //vd1
610 vpp_reg_setb(VPP_MATRIX_CTRL, 1, 5, 1);
611 vpp_reg_setb(VPP_MATRIX_CTRL, 1, 8, 3);
612 } else if (vd1_or_vd2_or_post == 1) { //vd2
613 vpp_reg_setb(VPP_MATRIX_CTRL, 1, 4, 1);
614 vpp_reg_setb(VPP_MATRIX_CTRL, 2, 8, 3);
615 } else if (vd1_or_vd2_or_post == 3) { //osd
616 vpp_reg_setb(VPP_MATRIX_CTRL, 1, 7, 1);
617 vpp_reg_setb(VPP_MATRIX_CTRL, 4, 8, 3);
618 } else if (vd1_or_vd2_or_post == 4) { //xvycc
619 vpp_reg_setb(VPP_MATRIX_CTRL, 1, 6, 1);
620 vpp_reg_setb(VPP_MATRIX_CTRL, 3, 8, 3);
621 } else {
622 vpp_reg_setb(VPP_MATRIX_CTRL, 1, 0, 1);
623 vpp_reg_setb(VPP_MATRIX_CTRL, 0, 8, 3);
624 if (mode == 0)
625 vpp_reg_setb(VPP_MATRIX_CTRL, 1, 1, 2);
626 else if (mode == 1)
627 vpp_reg_setb(VPP_MATRIX_CTRL, 0, 1, 2);
628 }
629
630 if (mode == 0) { /* 601 limit to RGB */
631 vpp_reg_write(VPP_MATRIX_PRE_OFFSET0_1, 0x0064C8FF);
632 vpp_reg_write(VPP_MATRIX_PRE_OFFSET2, 0x006400C8);
633 //1.164 0 1.596
634 //1.164 -0.392 -0.813
635 //1.164 2.017 0
636 vpp_reg_write(VPP_MATRIX_COEF00_01, 0x04A80000);
637 vpp_reg_write(VPP_MATRIX_COEF02_10, 0x066204A8);
638 vpp_reg_write(VPP_MATRIX_COEF11_12, 0x1e701cbf);
639 vpp_reg_write(VPP_MATRIX_COEF20_21, 0x04A80812);
640 vpp_reg_write(VPP_MATRIX_COEF22, 0x00000000);
641 vpp_reg_write(VPP_MATRIX_OFFSET0_1, 0x00000000);
642 vpp_reg_write(VPP_MATRIX_OFFSET2, 0x00000000);
643 vpp_reg_write(VPP_MATRIX_PRE_OFFSET0_1, 0x0FC00E00);
644 vpp_reg_write(VPP_MATRIX_PRE_OFFSET2, 0x00000E00);
645 } else if (mode == 1) { /* 601 limit to RGB */
646 vpp_reg_write(VPP_MATRIX_PRE_OFFSET0_1, 0x0000E00);
647 vpp_reg_write(VPP_MATRIX_PRE_OFFSET2, 0x0E00);
648 // 1 0 1.402
649 // 1 -0.34414 -0.71414
650 // 1 1.772 0
651 vpp_reg_write(VPP_MATRIX_COEF00_01, (0x400 << 16) |0);
652 vpp_reg_write(VPP_MATRIX_COEF02_10, (0x59c << 16) |0x400);
653 vpp_reg_write(VPP_MATRIX_COEF11_12, (0x1ea0 << 16) |0x1d24);
654 vpp_reg_write(VPP_MATRIX_COEF20_21, (0x400 << 16) |0x718);
655 vpp_reg_write(VPP_MATRIX_COEF22, 0x0);
656 vpp_reg_write(VPP_MATRIX_OFFSET0_1, 0x0);
657 vpp_reg_write(VPP_MATRIX_OFFSET2, 0x0);
658 } else if (mode == 2) { /* 709F to RGB */
659 vpp_reg_write(VPP_MATRIX_PRE_OFFSET0_1, 0x0000E00);
660 vpp_reg_write(VPP_MATRIX_PRE_OFFSET2, 0x0E00);
661 // 1 0 1.402
662 // 1 -0.34414 -0.71414
663 // 1 1.772 0
664 vpp_reg_write(VPP_MATRIX_COEF00_01, 0x04000000);
665 vpp_reg_write(VPP_MATRIX_COEF02_10, 0x064D0400);
666 vpp_reg_write(VPP_MATRIX_COEF11_12, 0x1F411E21);
667 vpp_reg_write(VPP_MATRIX_COEF20_21, 0x0400076D);
668 vpp_reg_write(VPP_MATRIX_COEF22, 0x0);
669 vpp_reg_write(VPP_MATRIX_OFFSET0_1, 0x0);
670 vpp_reg_write(VPP_MATRIX_OFFSET2, 0x0);
671 } else if (mode == 3) { /* 709L to RGB */
672 vpp_reg_write(VPP_MATRIX_PRE_OFFSET0_1, 0x0FC00E00);
673 vpp_reg_write(VPP_MATRIX_PRE_OFFSET2, 0x00000E00);
674 /* ycbcr limit range, 709 to RGB */
675 /* -16 1.164 0 1.793 0 */
676 /* -128 1.164 -0.213 -0.534 0 */
677 /* -128 1.164 2.115 0 0 */
678 vpp_reg_write(VPP_MATRIX_COEF00_01, 0x04A80000);
679 vpp_reg_write(VPP_MATRIX_COEF02_10, 0x072C04A8);
680 vpp_reg_write(VPP_MATRIX_COEF11_12, 0x1F261DDD);
681 vpp_reg_write(VPP_MATRIX_COEF20_21, 0x04A80876);
682 vpp_reg_write(VPP_MATRIX_COEF22, 0x0);
683 vpp_reg_write(VPP_MATRIX_OFFSET0_1, 0x0);
684 vpp_reg_write(VPP_MATRIX_OFFSET2, 0x0);
685 }
686 vpp_reg_setb(VPP_MATRIX_CLIP, 0, 5, 3);
687#endif
688}
689
690void set_vpp_matrix(int m_select, int *s, int on)
691{
692#ifndef AML_S5_DISPLAY
693 int *m = NULL;
694 int size = 0;
695 int i;
696
697 pr_info("set_vpp_matrix m_select = %d on = %d\n",m_select,on);
698
699 if (m_select == VPP_MATRIX_OSD) {
700 m = osd_matrix_coeff;
701 size = MATRIX_5x3_COEF_SIZE;
702 } else if (m_select == VPP_MATRIX_POST) {
703 m = post_matrix_coeff;
704 size = MATRIX_5x3_COEF_SIZE;
705 } else if (m_select == VPP_MATRIX_VD1) {
706 m = vd1_matrix_coeff;
707 size = MATRIX_5x3_COEF_SIZE;
708 } else if (m_select == VPP_MATRIX_VD2) {
709 m = vd2_matrix_coeff;
710 size = MATRIX_5x3_COEF_SIZE;
711 } else if (m_select == VPP_MATRIX_XVYCC) {
712 m = xvycc_matrix_coeff;
713 size = MATRIX_5x3_COEF_SIZE;
714 } else if (m_select == VPP_MATRIX_EOTF) {
715 m = video_eotf_coeff;
716 size = EOTF_COEFF_SIZE;
717 } else if (m_select == VPP_MATRIX_OSD_EOTF) {
718 m = osd_eotf_coeff;
719 size = EOTF_COEFF_SIZE;
720 } else
721 return;
722
723 if (s)
724 for (i = 0; i < size; i++)
725 m[i] = s[i];
726
727 if (m_select == VPP_MATRIX_OSD) {
728 /* osd matrix, VPP_MATRIX_0 */
729 vpp_reg_write(VIU_OSD1_MATRIX_PRE_OFFSET0_1,
730 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
731 vpp_reg_write(VIU_OSD1_MATRIX_PRE_OFFSET2,
732 m[2] & 0xfff);
733 vpp_reg_write(VIU_OSD1_MATRIX_COEF00_01,
734 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
735 vpp_reg_write(VIU_OSD1_MATRIX_COEF02_10,
736 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
737 vpp_reg_write(VIU_OSD1_MATRIX_COEF11_12,
738 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
739 vpp_reg_write(VIU_OSD1_MATRIX_COEF20_21,
740 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
741 if (m[21]) {
742 vpp_reg_write(VIU_OSD1_MATRIX_COEF22_30,
743 ((m[11] & 0x1fff) << 16) | (m[12] & 0x1fff));
744 vpp_reg_write(VIU_OSD1_MATRIX_COEF31_32,
745 ((m[13] & 0x1fff) << 16) | (m[14] & 0x1fff));
746 vpp_reg_write(VIU_OSD1_MATRIX_COEF40_41,
747 ((m[15] & 0x1fff) << 16) | (m[16] & 0x1fff));
748 vpp_reg_write(VIU_OSD1_MATRIX_COLMOD_COEF42,
749 m[17] & 0x1fff);
750 } else {
751 vpp_reg_write(VIU_OSD1_MATRIX_COEF22_30,
752 (m[11] & 0x1fff) << 16);
753 }
754 vpp_reg_write(VIU_OSD1_MATRIX_OFFSET0_1,
755 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
756 vpp_reg_write(VIU_OSD1_MATRIX_OFFSET2,
757 m[20] & 0xfff);
758 vpp_reg_setb(VIU_OSD1_MATRIX_COLMOD_COEF42,
759 m[21], 30, 2);
760 vpp_reg_setb(VIU_OSD1_MATRIX_COLMOD_COEF42,
761 m[22], 16, 3);
762 /* 23 reserved for clipping control */
763 vpp_reg_setb(VIU_OSD1_MATRIX_CTRL, on, 0, 1);
764 vpp_reg_setb(VIU_OSD1_MATRIX_CTRL, 0, 1, 1);
765 } else if (m_select == VPP_MATRIX_EOTF) {
766 /* eotf matrix, VPP_MATRIX_EOTF */
767 for (i = 0; i < 5; i++)
768 vpp_reg_write(VIU_EOTF_CTL + i + 1,
769 ((m[i * 2] & 0x1fff) << 16)
770 | (m[i * 2 + 1] & 0x1fff));
771
772 vpp_reg_setb(VIU_EOTF_CTL, on, 30, 1);
773 vpp_reg_setb(VIU_EOTF_CTL, on, 31, 1);
774 } else if (m_select == VPP_MATRIX_OSD_EOTF) {
775 /* osd eotf matrix, VPP_MATRIX_OSD_EOTF */
776 for (i = 0; i < 5; i++)
777 vpp_reg_write(VIU_OSD1_EOTF_CTL + i + 1,
778 ((m[i * 2] & 0x1fff) << 16)
779 | (m[i * 2 + 1] & 0x1fff));
780
781 vpp_reg_setb(VIU_OSD1_EOTF_CTL, on, 30, 1);
782 vpp_reg_setb(VIU_OSD1_EOTF_CTL, on, 31, 1);
783 } else {
784 /* vd1 matrix, VPP_MATRIX_1 */
785 /* post matrix, VPP_MATRIX_2 */
786 /* xvycc matrix, VPP_MATRIX_3 */
787 /* vd2 matrix, VPP_MATRIX_6 */
788 if (m_select == VPP_MATRIX_POST) {
789 /* post matrix */
790 m = post_matrix_coeff;
791 vpp_reg_setb(VPP_MATRIX_CTRL, on, 0, 1);
792 vpp_reg_setb(VPP_MATRIX_CTRL, 0, 8, 3);
793 } else if (m_select == VPP_MATRIX_VD1) {
794 /* vd1 matrix */
795 m = vd1_matrix_coeff;
796 vpp_reg_setb(VPP_MATRIX_CTRL, on, 5, 1);
797 vpp_reg_setb(VPP_MATRIX_CTRL, 1, 8, 3);
798 } else if (m_select == VPP_MATRIX_VD2) {
799 /* vd2 matrix */
800 m = vd2_matrix_coeff;
801 vpp_reg_setb(VPP_MATRIX_CTRL, on, 4, 1);
802 vpp_reg_setb(VPP_MATRIX_CTRL, 2, 8, 3);
803 } else if (m_select == VPP_MATRIX_XVYCC) {
804 /* xvycc matrix */
805 m = xvycc_matrix_coeff;
806 vpp_reg_setb(VPP_MATRIX_CTRL, on, 6, 1);
807 vpp_reg_setb(VPP_MATRIX_CTRL, 3, 8, 3);
808 }
809 vpp_reg_write(VPP_MATRIX_PRE_OFFSET0_1,
810 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
811 vpp_reg_write(VPP_MATRIX_PRE_OFFSET2,
812 m[2] & 0xfff);
813 vpp_reg_write(VPP_MATRIX_COEF00_01,
814 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
815 vpp_reg_write(VPP_MATRIX_COEF02_10,
816 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
817 vpp_reg_write(VPP_MATRIX_COEF11_12,
818 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
819 vpp_reg_write(VPP_MATRIX_COEF20_21,
820 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
821 vpp_reg_write(VPP_MATRIX_COEF22,
822 m[11] & 0x1fff);
823 if (m[21]) {
824 vpp_reg_write(VPP_MATRIX_COEF13_14,
825 ((m[12] & 0x1fff) << 16) | (m[13] & 0x1fff));
826 vpp_reg_write(VPP_MATRIX_COEF15_25,
827 ((m[14] & 0x1fff) << 16) | (m[17] & 0x1fff));
828 vpp_reg_write(VPP_MATRIX_COEF23_24,
829 ((m[15] & 0x1fff) << 16) | (m[16] & 0x1fff));
830 }
831 vpp_reg_write(VPP_MATRIX_OFFSET0_1,
832 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
833 vpp_reg_write(VPP_MATRIX_OFFSET2,
834 m[20] & 0xfff);
835 vpp_reg_setb(VPP_MATRIX_CLIP,
836 m[21], 3, 2);
837 vpp_reg_setb(VPP_MATRIX_CLIP,
838 m[22], 5, 3);
839 }
840#endif
841}
842
843const char lut_name[4][16] = {
844 "OSD_EOTF",
845 "OSD_OETF",
846 "EOTF",
847 "OETF",
848};
849
850#ifndef AML_S5_DISPLAY
851void set_vpp_lut(
852 enum vpp_lut_sel_e lut_sel,
853 unsigned int *r,
854 unsigned int *g,
855 unsigned int *b,
856 int on)
857{
858 unsigned int *r_map = NULL;
859 unsigned int *g_map = NULL;
860 unsigned int *b_map = NULL;
861 unsigned int addr_port;
862 unsigned int data_port;
863 unsigned int ctrl_port;
864 int i;
865
866 if (lut_sel == VPP_LUT_OSD_EOTF) {
867 r_map = osd_eotf_r_mapping;
868 g_map = osd_eotf_g_mapping;
869 b_map = osd_eotf_b_mapping;
870 addr_port = VIU_OSD1_EOTF_LUT_ADDR_PORT;
871 data_port = VIU_OSD1_EOTF_LUT_DATA_PORT;
872 ctrl_port = VIU_OSD1_EOTF_CTL;
873 } else if (lut_sel == VPP_LUT_EOTF) {
874 r_map = video_eotf_r_mapping;
875 g_map = video_eotf_g_mapping;
876 b_map = video_eotf_b_mapping;
877 addr_port = VIU_EOTF_LUT_ADDR_PORT;
878 data_port = VIU_EOTF_LUT_DATA_PORT;
879 ctrl_port = VIU_EOTF_CTL;
880 } else if (lut_sel == VPP_LUT_OSD_OETF) {
881 r_map = osd_oetf_r_mapping;
882 g_map = osd_oetf_g_mapping;
883 b_map = osd_oetf_b_mapping;
884 addr_port = VIU_OSD1_OETF_LUT_ADDR_PORT;
885 data_port = VIU_OSD1_OETF_LUT_DATA_PORT;
886 ctrl_port = VIU_OSD1_OETF_CTL;
887 } else if (lut_sel == VPP_LUT_OETF) {
888#if 0
889 load_knee_lut(on);
890 return;
891#else
892 r_map = video_oetf_r_mapping;
893 g_map = video_oetf_g_mapping;
894 b_map = video_oetf_b_mapping;
895 addr_port = XVYCC_LUT_R_ADDR_PORT;
896 data_port = XVYCC_LUT_R_DATA_PORT;
897 ctrl_port = XVYCC_LUT_CTL;
898#endif
899 } else
900 return;
901
902 if (lut_sel == VPP_LUT_OSD_OETF) {
903 if (r && r_map)
904 for (i = 0; i < OSD_OETF_LUT_SIZE; i++)
905 r_map[i] = r[i];
906 if (g && g_map)
907 for (i = 0; i < OSD_OETF_LUT_SIZE; i++)
908 g_map[i] = g[i];
909 if (r && r_map)
910 for (i = 0; i < OSD_OETF_LUT_SIZE; i++)
911 b_map[i] = b[i];
912 vpp_reg_write(addr_port, 0);
913 for (i = 0; i < 20; i++)
914 vpp_reg_write(data_port,
915 r_map[i * 2]
916 | (r_map[i * 2 + 1] << 16));
917 vpp_reg_write(data_port,
918 r_map[OSD_OETF_LUT_SIZE - 1]
919 | (g_map[0] << 16));
920 for (i = 0; i < 20; i++)
921 vpp_reg_write(data_port,
922 g_map[i * 2 + 1]
923 | (g_map[i * 2 + 2] << 16));
924 for (i = 0; i < 20; i++)
925 vpp_reg_write(data_port,
926 b_map[i * 2]
927 | (b_map[i * 2 + 1] << 16));
928 vpp_reg_write(data_port,
929 b_map[OSD_OETF_LUT_SIZE - 1]);
930 if (on)
931 vpp_reg_setb(ctrl_port, 7, 29, 3);
932 else
933 vpp_reg_setb(ctrl_port, 0, 29, 3);
934 } else if ((lut_sel == VPP_LUT_OSD_EOTF) || (lut_sel == VPP_LUT_EOTF)) {
935 if (r && r_map)
936 for (i = 0; i < EOTF_LUT_SIZE; i++)
937 r_map[i] = r[i];
938 if (g && g_map)
939 for (i = 0; i < EOTF_LUT_SIZE; i++)
940 g_map[i] = g[i];
941 if (r && r_map)
942 for (i = 0; i < EOTF_LUT_SIZE; i++)
943 b_map[i] = b[i];
944 vpp_reg_write(addr_port, 0);
945 for (i = 0; i < 16; i++)
946 vpp_reg_write(data_port,
947 r_map[i * 2]
948 | (r_map[i * 2 + 1] << 16));
949 vpp_reg_write(data_port,
950 r_map[EOTF_LUT_SIZE - 1]
951 | (g_map[0] << 16));
952 for (i = 0; i < 16; i++)
953 vpp_reg_write(data_port,
954 g_map[i * 2 + 1]
955 | (g_map[i * 2 + 2] << 16));
956 for (i = 0; i < 16; i++)
957 vpp_reg_write(data_port,
958 b_map[i * 2]
959 | (b_map[i * 2 + 1] << 16));
960 vpp_reg_write(data_port, b_map[EOTF_LUT_SIZE - 1]);
961 if (on)
962 vpp_reg_setb(ctrl_port, 7, 27, 3);
963 else
964 vpp_reg_setb(ctrl_port, 0, 27, 3);
965 vpp_reg_setb(ctrl_port, 1, 31, 1);
966 } else if (lut_sel == VPP_LUT_OETF) {
967 if (r && r_map)
968 for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++)
969 r_map[i] = r[i];
970 if (g && g_map)
971 for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++)
972 g_map[i] = g[i];
973 if (r && r_map)
974 for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++)
975 b_map[i] = b[i];
976 vpp_reg_write(ctrl_port, 0x0);
977 vpp_reg_write(addr_port, 0);
978 for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++)
979 vpp_reg_write(data_port, r_map[i]);
980 vpp_reg_write(addr_port + 2, 0);
981 for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++)
982 vpp_reg_write(data_port + 2, g_map[i]);
983 vpp_reg_write(addr_port + 4, 0);
984 for (i = 0; i < VIDEO_OETF_LUT_SIZE; i++)
985 vpp_reg_write(data_port + 4, b_map[i]);
986 if (on)
987 vpp_reg_write(ctrl_port, 0x7f);
988 else
989 vpp_reg_write(ctrl_port, 0x0);
990 }
991}
992#endif
993
994 /*
995for G12A, set osd2 matrix(10bit) RGB2YUV
996 */
997 #ifndef AML_S5_DISPLAY
998 static void set_osd1_rgb2yuv(bool on)
999 {
1000 int *m = NULL;
hai.cao8b0d0bc2023-06-14 14:08:57 +08001001 u32 chip_id = get_cpu_id().family_id;
hai.cao8c827c02023-02-28 11:12:05 +08001002
1003 if (is_osd_high_version()) {
1004 /* RGB -> 709 limit */
1005 m = RGB709_to_YUV709l_coeff;
hai.cao8b0d0bc2023-06-14 14:08:57 +08001006 if (chip_id != MESON_CPU_MAJOR_ID_S1A) {
1007 /* VPP WRAP OSD1 matrix */
1008 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_PRE_OFFSET0_1,
1009 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
1010 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_PRE_OFFSET2,
1011 m[2] & 0xfff);
1012 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_COEF00_01,
1013 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
1014 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_COEF02_10,
1015 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
1016 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_COEF11_12,
1017 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
1018 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_COEF20_21,
1019 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
1020 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_COEF22,
1021 m[11] & 0x1fff);
hai.cao8c827c02023-02-28 11:12:05 +08001022
hai.cao8b0d0bc2023-06-14 14:08:57 +08001023 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_OFFSET0_1,
1024 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
1025 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_OFFSET2,
1026 m[20] & 0xfff);
hai.cao8c827c02023-02-28 11:12:05 +08001027
hai.cao8b0d0bc2023-06-14 14:08:57 +08001028 vpp_reg_setb(VPP_WRAP_OSD1_MATRIX_EN_CTRL, on, 0, 1);
1029 } else {
1030 vpp_reg_write(VPP_OSD1_MATRIX_PRE_OFFSET0_1,
1031 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
1032 vpp_reg_write(VPP_OSD1_MATRIX_PRE_OFFSET2,
1033 m[2] & 0xfff);
1034 vpp_reg_write(VPP_OSD1_MATRIX_COEF00_01,
1035 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
1036 vpp_reg_write(VPP_OSD1_MATRIX_COEF02_10,
1037 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
1038 vpp_reg_write(VPP_OSD1_MATRIX_COEF11_12,
1039 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
1040 vpp_reg_write(VPP_OSD1_MATRIX_COEF20_21,
1041 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
1042 vpp_reg_write(VPP_OSD1_MATRIX_COEF22,
1043 m[11] & 0x1fff);
1044 vpp_reg_write(VPP_OSD1_MATRIX_OFFSET0_1,
1045 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
1046 vpp_reg_write(VPP_OSD1_MATRIX_OFFSET2,
1047 m[20] & 0xfff);
1048 vpp_reg_setb(VPP_OSD1_MATRIX_EN_CTRL, on, 0, 1);
hai.cao8c827c02023-02-28 11:12:05 +08001049
hai.cao8b0d0bc2023-06-14 14:08:57 +08001050 }
hai.cao8c827c02023-02-28 11:12:05 +08001051 VPP_PR("%s rgb2yuv on = %d..............\n", __func__, on);
1052 } else {
1053 vpp_reg_setb(VIU_OSD1_BLK0_CFG_W0, 0, 7, 1);
1054 /* eotf lut bypass */
1055 set_vpp_lut(VPP_LUT_OSD_EOTF,
1056 eotf_33_linear_mapping, /* R */
1057 eotf_33_linear_mapping, /* G */
1058 eotf_33_linear_mapping, /* B */
1059 CSC_OFF);
1060 /* eotf matrix bypass */
1061 set_vpp_matrix(VPP_MATRIX_OSD_EOTF,
1062 eotf_bypass_coeff,
1063 CSC_OFF);
1064 /* oetf lut bypass */
1065 set_vpp_lut(VPP_LUT_OSD_OETF,
1066 oetf_41_linear_mapping, /* R */
1067 oetf_41_linear_mapping, /* G */
1068 oetf_41_linear_mapping, /* B */
1069 CSC_OFF);
1070 /* osd matrix RGB709 to YUV709 limit */
1071 set_vpp_matrix(VPP_MATRIX_OSD,
1072 RGB709_to_YUV709l_coeff,
1073 CSC_ON);
1074 }
1075 }
1076
1077 /*
1078for G12A, set osd2 matrix(10bit) RGB2YUV
1079 */
1080static void set_osd2_rgb2yuv(bool on)
1081{
1082 int *m = NULL;
1083
1084 if (is_osd_high_version()) {
1085 /* RGB -> 709 limit */
1086 m = RGB709_to_YUV709l_coeff;
1087
1088 /* VPP WRAP OSD2 matrix */
1089 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_PRE_OFFSET0_1,
1090 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
1091 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_PRE_OFFSET2,
1092 m[2] & 0xfff);
1093 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_COEF00_01,
1094 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
1095 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_COEF02_10,
1096 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
1097 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_COEF11_12,
1098 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
1099 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_COEF20_21,
1100 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
1101 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_COEF22,
1102 m[11] & 0x1fff);
1103
1104 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_OFFSET0_1,
1105 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
1106 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_OFFSET2,
1107 m[20] & 0xfff);
1108
1109 vpp_reg_setb(VPP_WRAP_OSD2_MATRIX_EN_CTRL, on, 0, 1);
1110
1111 VPP_PR("%s rgb2yuv on = %d..............\n", __func__, on);
1112 }
1113}
1114
1115 /*
1116for G12A, set osd3 matrix(10bit) RGB2YUV
1117 */
1118static void set_osd3_rgb2yuv(bool on)
1119{
1120 int *m = NULL;
1121
1122 if (is_osd_high_version()) {
1123 /* RGB -> 709 limit */
1124 m = RGB709_to_YUV709l_coeff;
1125
1126 /* VPP WRAP OSD3 matrix */
1127 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_PRE_OFFSET0_1,
1128 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
1129 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_PRE_OFFSET2,
1130 m[2] & 0xfff);
1131 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_COEF00_01,
1132 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
1133 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_COEF02_10,
1134 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
1135 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_COEF11_12,
1136 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
1137 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_COEF20_21,
1138 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
1139 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_COEF22,
1140 m[11] & 0x1fff);
1141
1142 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_OFFSET0_1,
1143 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
1144 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_OFFSET2,
1145 m[20] & 0xfff);
1146
1147 vpp_reg_setb(VPP_WRAP_OSD3_MATRIX_EN_CTRL, on, 0, 1);
1148
1149 VPP_PR("%s rgb2yuv on = %d..............\n", __func__, on);
1150 }
1151}
1152
1153 /*
1154for T7, set osd4 matrix(10bit) RGB2YUV
1155 */
1156static void set_osd4_rgb2yuv(bool on)
1157{
1158 int *m = NULL;
1159
1160 if (is_osd_high_version()) {
1161 /* RGB -> 709 limit */
1162 m = RGB709_to_YUV709l_coeff;
1163
1164 /* VPP WRAP OSD3 matrix */
1165 vpp_reg_write(VIU_OSD4_MATRIX_PRE_OFFSET0_1,
1166 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
1167 vpp_reg_write(VIU_OSD4_MATRIX_PRE_OFFSET2,
1168 m[2] & 0xfff);
1169 vpp_reg_write(VIU_OSD4_MATRIX_COEF00_01,
1170 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
1171 vpp_reg_write(VIU_OSD4_MATRIX_COEF02_10,
1172 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
1173 vpp_reg_write(VIU_OSD4_MATRIX_COEF11_12,
1174 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
1175 vpp_reg_write(VIU_OSD4_MATRIX_COEF20_21,
1176 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
1177 vpp_reg_write(VIU_OSD4_MATRIX_COEF22,
1178 m[11] & 0x1fff);
1179
1180 vpp_reg_write(VIU_OSD4_MATRIX_OFFSET0_1,
1181 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
1182 vpp_reg_write(VIU_OSD4_MATRIX_OFFSET2,
1183 m[20] & 0xfff);
1184
1185 vpp_reg_setb(VIU_OSD4_MATRIX_EN_CTRL, on, 0, 1);
1186
1187 VPP_PR("T7 osd4 matrix rgb2yuv..............\n");
1188 }
1189}
1190#endif
1191
1192#ifndef AML_T7_DISPLAY
1193static void set_viu2_osd_matrix_rgb2yuv(bool on)
1194{
1195 int *m = RGB709_to_YUV709l_coeff;
1196
1197 /* RGB -> 709 limit */
1198 if (is_osd_high_version()) {
1199 /* VPP WRAP OSD3 matrix */
1200 vpp_reg_write(VIU2_OSD1_MATRIX_PRE_OFFSET0_1,
1201 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
1202 vpp_reg_write(VIU2_OSD1_MATRIX_PRE_OFFSET2,
1203 m[2] & 0xfff);
1204 vpp_reg_write(VIU2_OSD1_MATRIX_COEF00_01,
1205 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
1206 vpp_reg_write(VIU2_OSD1_MATRIX_COEF02_10,
1207 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
1208 vpp_reg_write(VIU2_OSD1_MATRIX_COEF11_12,
1209 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
1210 vpp_reg_write(VIU2_OSD1_MATRIX_COEF20_21,
1211 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
1212 vpp_reg_write(VIU2_OSD1_MATRIX_COEF22,
1213 m[11] & 0x1fff);
1214
1215 vpp_reg_write(VIU2_OSD1_MATRIX_OFFSET0_1,
1216 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
1217 vpp_reg_write(VIU2_OSD1_MATRIX_OFFSET2,
1218 m[20] & 0xfff);
1219
1220 vpp_reg_setb(VIU2_OSD1_MATRIX_EN_CTRL, on, 0, 1);
1221 }
1222}
1223#endif
1224
1225#ifndef AML_S5_DISPLAY
1226static void set_vpp_osd2_rgb2yuv(bool on)
1227{
1228 int *m = NULL;
1229
1230 /* RGB -> 709 limit */
1231 m = RGB709_to_YUV709l_coeff;
1232
1233 /* VPP WRAP OSD3 matrix */
1234 vpp_reg_write(VPP_OSD2_MATRIX_PRE_OFFSET0_1,
1235 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
1236 vpp_reg_write(VPP_OSD2_MATRIX_PRE_OFFSET2,
1237 m[2] & 0xfff);
1238 vpp_reg_write(VPP_OSD2_MATRIX_COEF00_01,
1239 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
1240 vpp_reg_write(VPP_OSD2_MATRIX_COEF02_10,
1241 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
1242 vpp_reg_write(VPP_OSD2_MATRIX_COEF11_12,
1243 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
1244 vpp_reg_write(VPP_OSD2_MATRIX_COEF20_21,
1245 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
1246 vpp_reg_write(VPP_OSD2_MATRIX_COEF22,
1247 m[11] & 0x1fff);
1248 vpp_reg_write(VPP_OSD2_MATRIX_OFFSET0_1,
1249 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
1250 vpp_reg_write(VPP_OSD2_MATRIX_OFFSET2,
1251 m[20] & 0xfff);
1252 vpp_reg_setb(VPP_OSD2_MATRIX_EN_CTRL, on, 0, 1);
1253 VPP_PR("vpp osd2 matrix rgb2yuv..............\n");
1254}
1255#endif
1256
1257/*
1258for txlx, set vpp default data path to u10
1259 */
1260static void set_vpp_bitdepth(void)
1261{
1262 u32 chip_id = get_cpu_id().family_id;
1263
1264 if (is_osd_high_version()) {
1265 /*after this step vd1 output data is U12,*/
1266 if (chip_id == MESON_CPU_MAJOR_ID_T7) {
1267 /* osd dolby bypass en */
1268 vpp_reg_setb(MALI_AFBCD_TOP_CTRL, 1, 14, 1);
1269 vpp_reg_setb(MALI_AFBCD_TOP_CTRL, 1, 19, 1);
1270 /* osd_din_ext 12bit */
1271 vpp_reg_setb(MALI_AFBCD_TOP_CTRL, 0, 15, 1);
1272 vpp_reg_setb(MALI_AFBCD_TOP_CTRL, 0, 20, 1);
1273
1274 vpp_reg_setb(MALI_AFBCD1_TOP_CTRL, 1, 19, 1);
1275 vpp_reg_setb(MALI_AFBCD1_TOP_CTRL, 0, 20, 1);
1276
1277 vpp_reg_setb(MALI_AFBCD2_TOP_CTRL, 1, 19, 1);
1278 vpp_reg_setb(MALI_AFBCD2_TOP_CTRL, 0, 20, 1);
1279 } else {
1280 vpp_reg_write(DOLBY_PATH_CTRL, 0xf);
1281 }
1282 }
1283}
1284
1285/* osd+video brightness */
1286static void video_adj2_brightness(int val)
1287{
1288 if (val < -255)
1289 val = -255;
1290 else if (val > 255)
1291 val = 255;
1292
1293 VPP_PR("brightness_post:%d\n", val);
1294
1295 vpp_reg_setb(VPP_VADJ2_Y, val << 1, 8, 10);
1296
1297#ifndef AML_S5_DISPLAY
1298 vpp_reg_setb(VPP_VADJ_CTRL, 1, 2, 1);
1299#endif
1300}
1301
1302/* osd+video contrast */
1303static void video_adj2_contrast(int val)
1304{
1305 if (val < -127)
1306 val = -127;
1307 else if (val > 127)
1308 val = 127;
1309
1310 VPP_PR("contrast_post:%d\n", val);
1311
1312 val += 0x80;
1313
1314 vpp_reg_setb(VPP_VADJ2_Y, val, 0, 8);
1315#ifndef AML_S5_DISPLAY
1316 vpp_reg_setb(VPP_VADJ_CTRL, 1, 2, 1);
1317#endif
1318}
1319
1320/* osd+video saturation/hue */
1321static void amvecm_saturation_hue_post(int sat, int hue)
1322{
1323 int hue_post; /*-25~25*/
1324 int saturation_post; /*-128~127*/
1325 int i, ma, mb, mab, mc, md;
1326 int hue_cos[] = {
1327 /*0~12*/
1328 256, 256, 256, 255, 255, 254, 253, 252, 251, 250,
1329 248, 247, 245, 243, 241, 239, 237, 234, 231, 229,
1330 226, 223, 220, 216, 213, 209 /*13~25*/
1331 };
1332 int hue_sin[] = {
1333 -147, -142, -137, -132, -126, -121, -115, -109, -104,
1334 -98, -92, -86, -80, /*-25~-13*/-74, -68, -62, -56,
1335 -50, -44, -38, -31, -25, -19, -13, -6, /*-12~-1*/
1336 0, /*0*/
1337 6, 13, 19, 25, 31, 38, 44, 50, 56,
1338 62, 68, 74, /*1~12*/ 80, 86, 92, 98, 104,
1339 109, 115, 121, 126, 132, 137, 142, 147 /*13~25*/
1340 };
1341
1342 if (sat < -128)
1343 sat = -128;
1344 else if (sat > 128)
1345 sat = 128;
1346
1347 if (hue < -25)
1348 hue = -25;
1349 else if (hue > 25)
1350 hue = 25;
1351
1352 VPP_PR("saturation sat_post:%d hue_post:%d\n", sat, hue);
1353
1354 saturation_post = sat;
1355 hue_post = hue;
1356 i = (hue_post > 0) ? hue_post : -hue_post;
1357 ma = (hue_cos[i]*(saturation_post + 128)) >> 7;
1358 mb = (hue_sin[25+hue_post]*(saturation_post + 128)) >> 7;
1359 if (ma > 511)
1360 ma = 511;
1361 if (ma < -512)
1362 ma = -512;
1363 if (mb > 511)
1364 mb = 511;
1365 if (mb < -512)
1366 mb = -512;
1367 mab = ((ma & 0x3ff) << 16) | (mb & 0x3ff);
1368
1369 vpp_reg_write(VPP_VADJ2_MA_MB, mab);
1370 mc = (s16)((mab<<22)>>22); /* mc = -mb */
1371 mc = 0 - mc;
1372 if (mc > 511)
1373 mc = 511;
1374 if (mc < -512)
1375 mc = -512;
1376 md = (s16)((mab<<6)>>22); /* md = ma; */
1377 mab = ((mc&0x3ff)<<16)|(md&0x3ff);
1378
1379 vpp_reg_write(VPP_VADJ2_MC_MD, mab);
1380#ifndef AML_S5_DISPLAY
1381 vpp_reg_setb(VPP_VADJ_CTRL, 1, 2, 1);
1382#endif
1383}
1384
1385/* init osd+video brightness/contrast/saturaion/hue */
1386void vpp_pq_init(int brightness, int contrast, int sat, int hue)
1387{
1388 video_adj2_brightness(brightness);
1389 video_adj2_contrast(contrast);
1390 amvecm_saturation_hue_post(sat, hue);
1391}
1392
1393void vpp_pq_load(void)
1394{
1395 int i = 0, cnt = 0;
1396 char const *pq = env_get("pq");
1397 char *tk, *str, *tmp[4];
1398 short val[4];
1399
1400 if (pq == NULL) {
1401 VPP_PR("%s pq val error !!!\n", __func__);
1402 return;
1403 }
1404
1405 str = strdup(pq);
1406
1407 for (tk = strsep(&str, ","); tk != NULL; tk = strsep(&str, ",")) {
1408 tmp[cnt] = tk;
1409
1410 if (++cnt > 3)
1411 break;
1412 }
1413
1414 if (cnt == 4) {
1415 for (i = 0; i < 4; i++) {
1416 val[i] = simple_strtol(tmp[i], NULL, 10);
1417 /* VPP_PR("pq[%d]: %d\n", i, val[i]); */
1418 }
1419 vpp_pq_init(val[0], val[1], val[2], val[3]);
1420 }
1421}
1422
1423void vpp_load_gamma_table(unsigned short *data, unsigned int len, enum vpp_gamma_sel_e flag)
1424{
1425 unsigned short *table = NULL;
1426 unsigned int i;
1427
1428 switch (flag) {
1429 case VPP_GAMMA_R:
1430 table = gamma_table_r;
1431 break;
1432 case VPP_GAMMA_G:
1433 table = gamma_table_g;
1434 break;
1435 case VPP_GAMMA_B:
1436 table = gamma_table_b;
1437 break;
1438 default:
1439 break;
1440 }
1441 if (table == NULL) {
1442 VPP_PR("error: %s: invalid flag: %d\n", __func__, flag);
1443 return;
1444 }
1445 if (len != GAMMA_SIZE) {
1446 VPP_PR("error: %s: invalid len: %d\n", __func__, len);
1447 return;
1448 }
1449
1450 for (i = 0; i < GAMMA_SIZE; i++)
1451 table[i] = data[i];
1452 VPP_PR("%s: successful\n", __func__);
1453}
1454
1455void vpp_enable_lcd_gamma_table(int index)
1456{
1457 unsigned int reg;
1458
1459 if (get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_T7) {
1460 switch (index) {
1461 case 1:
1462 reg = LCD_GAMMA_CNTL_PORT0 + 0x100;
1463 break;
1464 case 2:
1465 reg = LCD_GAMMA_CNTL_PORT0 + 0x200;
1466 break;
1467 case 0:
1468 default:
1469 reg = LCD_GAMMA_CNTL_PORT0;
1470 break;
1471 }
1472 } else {
1473 reg = L_GAMMA_CNTL_PORT;
1474 }
1475
1476 vpp_reg_setb(reg, 1, GAMMA_EN, 1);
1477}
1478
1479void vpp_disable_lcd_gamma_table(int index)
1480{
1481 unsigned int reg;
1482
1483 if (get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_T7) {
1484 switch (index) {
1485 case 1:
1486 reg = LCD_GAMMA_CNTL_PORT0 + 0x100;
1487 break;
1488 case 2:
1489 reg = LCD_GAMMA_CNTL_PORT0 + 0x200;
1490 break;
1491 case 0:
1492 default:
1493 reg = LCD_GAMMA_CNTL_PORT0;
1494 break;
1495 }
1496 } else {
1497 reg = L_GAMMA_CNTL_PORT;
1498 }
1499 vpp_reg_setb(reg, 0, GAMMA_EN, 1);
1500}
1501
1502#define GAMMA_RETRY 1000
1503static void vpp_set_lcd_gamma_table(int index, u16 *data, u32 rgb_mask)
1504{
1505 unsigned int reg_encl_en, reg_cntl_port, reg_data_port, reg_addr_port;
1506 int i;
1507 int cnt = 0;
1508
1509 if (get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_T7) {
1510 switch (index) {
1511 case 1:
1512 reg_encl_en = ENCL_VIDEO_EN + 0x600;
1513 reg_cntl_port = LCD_GAMMA_CNTL_PORT0 + 0x100;
1514 reg_data_port = LCD_GAMMA_DATA_PORT0 + 0x100;
1515 reg_addr_port = LCD_GAMMA_ADDR_PORT0 + 0x100;
1516 break;
1517 case 2:
1518 reg_encl_en = ENCL_VIDEO_EN + 0x800;
1519 reg_cntl_port = LCD_GAMMA_CNTL_PORT0 + 0x200;
1520 reg_data_port = LCD_GAMMA_DATA_PORT0 + 0x200;
1521 reg_addr_port = LCD_GAMMA_ADDR_PORT0 + 0x200;
1522 break;
1523 case 0:
1524 default:
1525 reg_encl_en = ENCL_VIDEO_EN;
1526 reg_cntl_port = LCD_GAMMA_CNTL_PORT0;
1527 reg_data_port = LCD_GAMMA_DATA_PORT0;
1528 reg_addr_port = LCD_GAMMA_ADDR_PORT0;
1529 break;
1530 }
1531 } else {
1532 reg_encl_en = ENCL_VIDEO_EN;
1533 reg_cntl_port = L_GAMMA_CNTL_PORT;
1534 reg_data_port = L_GAMMA_DATA_PORT;
1535 reg_addr_port = L_GAMMA_ADDR_PORT;
1536 }
1537
1538 if (get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_T7) {
1539 if (get_cpu_id().family_id == MESON_CPU_MAJOR_ID_T5M) {
1540 vpp_reg_write(reg_addr_port, (1 << 9));
1541 for (i = 0; i < 256; i++)
1542 vpp_reg_write(reg_data_port,
1543 (data[i] << 20) |
1544 (data[i] << 10) |
1545 (data[i] << 0));
1546 vpp_reg_write(reg_data_port,
1547 (0x3ff << 20) |
1548 (0x3ff << 10) |
1549 (0x3ff << 0));
1550 } else {
1551 vpp_reg_write(reg_addr_port, (1 << 8));
1552 for (i = 0; i < 256; i++)
1553 vpp_reg_write(reg_data_port,
1554 (data[i] << 20) |
1555 (data[i] << 10) |
1556 (data[i] << 0));
1557 }
1558 return;
1559 }
1560
1561 if (!(vpp_reg_read(reg_encl_en) & 0x1))
1562 return;
1563
1564 vpp_reg_setb(reg_cntl_port, 0, GAMMA_EN, 1);
1565
1566 while (!(vpp_reg_read(reg_cntl_port) & (0x1 << ADR_RDY))) {
1567 udelay(10);
1568 if (cnt++ > GAMMA_RETRY)
1569 break;
1570 }
1571 cnt = 0;
1572 vpp_reg_write(reg_addr_port, (0x1 << H_AUTO_INC) |
1573 (0x1 << rgb_mask) |
1574 (0x0 << HADR));
1575 for (i = 0; i < 256; i++) {
1576 while (!(vpp_reg_read(reg_cntl_port) & (0x1 << WR_RDY))) {
1577 udelay(10);
1578 if (cnt++ > GAMMA_RETRY)
1579 break;
1580 }
1581 cnt = 0;
1582 vpp_reg_write(reg_data_port, data[i]);
1583 }
1584 while (!(vpp_reg_read(reg_cntl_port) & (0x1 << ADR_RDY))) {
1585 udelay(10);
1586 if (cnt++ > GAMMA_RETRY)
1587 break;
1588 }
1589 vpp_reg_write(reg_addr_port, (0x1 << H_AUTO_INC) |
1590 (0x1 << rgb_mask) |
1591 (0x23 << HADR));
1592
1593}
1594
1595void vpp_init_lcd_gamma_table(int index)
1596{
1597 VPP_PR("%s\n", __func__);
1598
1599 vpp_disable_lcd_gamma_table(index);
1600
1601 vpp_set_lcd_gamma_table(index, gamma_table_r, H_SEL_R);
1602 vpp_set_lcd_gamma_table(index, gamma_table_g, H_SEL_G);
1603 vpp_set_lcd_gamma_table(index, gamma_table_b, H_SEL_B);
1604
1605 vpp_enable_lcd_gamma_table(index);
1606}
1607
1608void vpp_matrix_update(int type)
1609{
1610 if (vpp_init_flag == 0)
1611 return;
1612
1613 switch (type) {
1614 case VPP_CM_RGB:
1615 /* 709 limit to RGB */
1616 vpp_set_matrix_ycbcr2rgb(2, 3);
1617 break;
1618 case VPP_CM_YUV:
1619 break;
1620 default:
1621 break;
1622 }
1623}
1624
1625void vpp_viu2_matrix_update(int type)
1626{
1627 if (vpp_init_flag == 0)
1628 return;
1629
1630 if (get_cpu_id().family_id < MESON_CPU_MAJOR_ID_G12A)
1631 return;
1632
1633 switch (type) {
1634 case VPP_CM_RGB:
1635 /* default RGB */
1636 #ifndef AML_T7_DISPLAY
1637 set_viu2_osd_matrix_rgb2yuv(0);
1638 #else
1639 /* vpp_top1: yuv2rgb */
1640 vpp_top_post2_matrix_yuv2rgb(1);
1641 #endif
1642 break;
1643 case VPP_CM_YUV:
1644 /* RGB to 709 limit */
1645 #ifndef AML_T7_DISPLAY
1646 set_viu2_osd_matrix_rgb2yuv(1);
1647 #endif
1648 break;
1649 default:
1650 break;
1651 }
1652}
1653
1654void vpp_viu3_matrix_update(int type)
1655{
1656 if (vpp_init_flag == 0)
1657 return;
1658
1659 if (get_cpu_id().family_id < MESON_CPU_MAJOR_ID_G12A)
1660 return;
1661
1662 switch (type) {
1663 case VPP_CM_RGB:
1664 /* default RGB */
1665 //#ifndef AML_T7_DISPLAY
1666 //set_viu_osd_matrix_rgb2yuv(0);
1667 //#else
1668 /* vpp_top2: yuv2rgb */
1669 vpp_top_post2_matrix_yuv2rgb(2);
1670 //#endif
1671 break;
1672 case VPP_CM_YUV:
1673 /* RGB to 709 limit */
1674 #ifndef AML_T7_DISPLAY
1675 //set_viu2_osd_matrix_rgb2yuv(2);
1676 #endif
1677 break;
1678 default:
1679 break;
1680 }
1681}
1682
1683static void vpp_ofifo_init(void)
1684{
1685 unsigned int data32;
1686
1687 data32 = vpp_reg_read(VPP_OFIFO_SIZE);
hai.cao12deab32023-08-07 14:38:48 +08001688 if (get_cpu_id().family_id == MESON_CPU_MAJOR_ID_S1A)
1689 data32 |= 0x7ff;
1690 else
1691 data32 |= 0xfff;
hai.cao8c827c02023-02-28 11:12:05 +08001692 vpp_reg_write(VPP_OFIFO_SIZE, data32);
1693
1694 data32 = 0x08080808;
1695#ifndef AML_S5_DISPLAY
1696 vpp_reg_write(VPP_HOLD_LINES, data32);
1697#endif
1698}
1699
1700#ifdef CONFIG_AML_HDMITX
1701static void amvecm_cp_hdr_info(struct master_display_info_s *hdr_data)
1702{
1703 int i, j;
1704
1705 hdr_data->features =
1706 (0 << 30) /*sdr output 709*/
1707 | (1 << 29) /*video available*/
1708 | (5 << 26) /* unspecified */
1709 | (0 << 25) /* limit */
1710 | (1 << 24) /* color available */
1711 | (9 << 16) /* bt2020 */
1712 | (16 << 8) /* bt2020-10 */
1713 | (10 << 0); /* bt2020c */
1714
1715 for (i = 0; i < 3; i++)
1716 for (j = 0; j < 2; j++)
1717 hdr_data->primaries[i][j] =
1718 bt2020_primaries[i][j];
1719 hdr_data->white_point[0] = bt2020_white_point[0];
1720 hdr_data->white_point[1] = bt2020_white_point[1];
1721 /* default luminance */
1722 hdr_data->luminance[0] = 1000 * 10000;
1723 hdr_data->luminance[1] = 50;
1724
1725 /* content_light_level */
1726 hdr_data->max_content = 0;
1727 hdr_data->max_frame_average = 0;
1728 hdr_data->luminance[0] = hdr_data->luminance[0] / 10000;
1729 hdr_data->present_flag = 1;
1730}
1731#endif
1732
1733void hdr_tx_pkt_cb(void)
1734{
1735 int hdr_policy = 0;
1736#ifdef CONFIG_AML_HDMITX
1737 struct master_display_info_s hdr_data;
1738 struct hdr_info *hdrinfo = NULL;
1739#endif
1740 const char *hdr_policy_env = env_get("hdr_policy");
1741
1742 if (!hdr_policy_env)
1743 return;
1744
1745 hdr_policy = simple_strtoul(hdr_policy_env, NULL, 10);
1746#ifdef CONFIG_AML_HDMITX
1747 hdrinfo = hdmitx_get_rx_hdr_info();
1748
1749 if ((hdrinfo && hdrinfo->hdr_sup_eotf_smpte_st_2084) &&
1750 hdr_policy == 0) {
1751 if (is_hdmi_mode(env_get("outputmode"))) {
1752 hdr_func(OSD1_HDR, SDR_HDR);
1753 hdr_func(OSD2_HDR, SDR_HDR);
1754 hdr_func(VD1_HDR, SDR_HDR);
1755 }
1756 if (is_hdmi_mode(env_get("outputmode2")))
1757 hdr_func(OSD3_HDR, SDR_HDR);
1758 if (is_hdmi_mode(env_get("outputmode3")))
1759 hdr_func(OSD4_HDR, SDR_HDR);
1760 amvecm_cp_hdr_info(&hdr_data);
1761 hdmitx_set_drm_pkt(&hdr_data);
1762 }
1763#endif
1764
1765 VPP_PR("hdr_policy = %d\n", hdr_policy);
1766#ifdef CONFIG_AML_HDMITX
1767 if (hdrinfo)
1768 VPP_PR("Rx hdr_info.hdr_sup_eotf_smpte_st_2084 = %d\n",
1769 hdrinfo->hdr_sup_eotf_smpte_st_2084);
1770#endif
1771}
1772
1773static bool is_vpp_supported(int chip_id)
1774{
1775 if ((chip_id == MESON_CPU_MAJOR_ID_A1) ||
1776 (chip_id == MESON_CPU_MAJOR_ID_C1) ||
1777 (chip_id == MESON_CPU_MAJOR_ID_C2))
1778 return false;
1779 else
1780 return true;
1781}
1782
1783void vpp_init(void)
1784{
1785 int chip_id;
1786
1787 chip_id = vpp_get_chip_type();
1788 VPP_PR("%s, chip_id=%d\n", __func__, chip_id);
1789 if (!is_vpp_supported(chip_id)) {
1790 VPP_PR("%s, vpp not supported\n", __func__);
1791 return;
1792 }
1793 vpp_init_flag = 1;
1794
1795 /* init vpu fifo control register */
1796 vpp_ofifo_init();
1797
1798#ifndef AML_S5_DISPLAY
1799 vpp_set_matrix_default_init();
1800#endif
1801
1802 if (is_osd_high_version()) {
1803 /* >= g12a: osd out is rgb */
1804#ifndef AML_S5_DISPLAY
hai.cao8b0d0bc2023-06-14 14:08:57 +08001805 if (chip_id != MESON_CPU_MAJOR_ID_S1A)
1806 set_osd1_rgb2yuv(0);
1807 else
1808 set_osd1_rgb2yuv(1);
hai.cao8c827c02023-02-28 11:12:05 +08001809 set_osd2_rgb2yuv(0);
1810 if (chip_id != MESON_CPU_MAJOR_ID_TL1 &&
hai.cao8b0d0bc2023-06-14 14:08:57 +08001811 chip_id != MESON_CPU_MAJOR_ID_S4 &&
1812 chip_id != MESON_CPU_MAJOR_ID_S1A)
hai.cao8c827c02023-02-28 11:12:05 +08001813 set_osd3_rgb2yuv(0);
1814
1815 if (chip_id != MESON_CPU_MAJOR_ID_T7)
1816 set_vpp_osd2_rgb2yuv(1);
1817 else
1818 set_osd4_rgb2yuv(0);
1819#endif
1820 /* set vpp data path to u12 */
1821 set_vpp_bitdepth();
1822 hdr_func(OSD1_HDR, HDR_BYPASS | RGB_OSD);
1823 hdr_func(OSD2_HDR, HDR_BYPASS | RGB_OSD);
1824 hdr_func(OSD3_HDR, HDR_BYPASS | RGB_OSD);
1825 hdr_func(OSD4_HDR, HDR_BYPASS | RGB_OSD);
1826 hdr_func(VD1_HDR, HDR_BYPASS);
1827 hdr_func(VD2_HDR, HDR_BYPASS);
1828 } else {
1829 /* set dummy data default YUV black */
1830#ifndef AML_S5_DISPLAY
1831 vpp_reg_write(VPP_DUMMY_DATA1, 0x108080);
1832 /* osd1: rgb->yuv limit , osd2: yuv limit */
1833 set_osd1_rgb2yuv(1);
1834#endif
1835 }
1836}