blob: 901572042a4497941b424e2718c0a0815f9a9d26 [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;
1001
1002 if (is_osd_high_version()) {
1003 /* RGB -> 709 limit */
1004 m = RGB709_to_YUV709l_coeff;
1005
1006 /* VPP WRAP OSD1 matrix */
1007 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_PRE_OFFSET0_1,
1008 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
1009 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_PRE_OFFSET2,
1010 m[2] & 0xfff);
1011 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_COEF00_01,
1012 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
1013 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_COEF02_10,
1014 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
1015 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_COEF11_12,
1016 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
1017 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_COEF20_21,
1018 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
1019 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_COEF22,
1020 m[11] & 0x1fff);
1021
1022 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_OFFSET0_1,
1023 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
1024 vpp_reg_write(VPP_WRAP_OSD1_MATRIX_OFFSET2,
1025 m[20] & 0xfff);
1026
1027 vpp_reg_setb(VPP_WRAP_OSD1_MATRIX_EN_CTRL, on, 0, 1);
1028
1029 VPP_PR("%s rgb2yuv on = %d..............\n", __func__, on);
1030 } else {
1031 vpp_reg_setb(VIU_OSD1_BLK0_CFG_W0, 0, 7, 1);
1032 /* eotf lut bypass */
1033 set_vpp_lut(VPP_LUT_OSD_EOTF,
1034 eotf_33_linear_mapping, /* R */
1035 eotf_33_linear_mapping, /* G */
1036 eotf_33_linear_mapping, /* B */
1037 CSC_OFF);
1038 /* eotf matrix bypass */
1039 set_vpp_matrix(VPP_MATRIX_OSD_EOTF,
1040 eotf_bypass_coeff,
1041 CSC_OFF);
1042 /* oetf lut bypass */
1043 set_vpp_lut(VPP_LUT_OSD_OETF,
1044 oetf_41_linear_mapping, /* R */
1045 oetf_41_linear_mapping, /* G */
1046 oetf_41_linear_mapping, /* B */
1047 CSC_OFF);
1048 /* osd matrix RGB709 to YUV709 limit */
1049 set_vpp_matrix(VPP_MATRIX_OSD,
1050 RGB709_to_YUV709l_coeff,
1051 CSC_ON);
1052 }
1053 }
1054
1055 /*
1056for G12A, set osd2 matrix(10bit) RGB2YUV
1057 */
1058static void set_osd2_rgb2yuv(bool on)
1059{
1060 int *m = NULL;
1061
1062 if (is_osd_high_version()) {
1063 /* RGB -> 709 limit */
1064 m = RGB709_to_YUV709l_coeff;
1065
1066 /* VPP WRAP OSD2 matrix */
1067 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_PRE_OFFSET0_1,
1068 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
1069 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_PRE_OFFSET2,
1070 m[2] & 0xfff);
1071 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_COEF00_01,
1072 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
1073 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_COEF02_10,
1074 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
1075 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_COEF11_12,
1076 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
1077 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_COEF20_21,
1078 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
1079 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_COEF22,
1080 m[11] & 0x1fff);
1081
1082 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_OFFSET0_1,
1083 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
1084 vpp_reg_write(VPP_WRAP_OSD2_MATRIX_OFFSET2,
1085 m[20] & 0xfff);
1086
1087 vpp_reg_setb(VPP_WRAP_OSD2_MATRIX_EN_CTRL, on, 0, 1);
1088
1089 VPP_PR("%s rgb2yuv on = %d..............\n", __func__, on);
1090 }
1091}
1092
1093 /*
1094for G12A, set osd3 matrix(10bit) RGB2YUV
1095 */
1096static void set_osd3_rgb2yuv(bool on)
1097{
1098 int *m = NULL;
1099
1100 if (is_osd_high_version()) {
1101 /* RGB -> 709 limit */
1102 m = RGB709_to_YUV709l_coeff;
1103
1104 /* VPP WRAP OSD3 matrix */
1105 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_PRE_OFFSET0_1,
1106 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
1107 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_PRE_OFFSET2,
1108 m[2] & 0xfff);
1109 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_COEF00_01,
1110 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
1111 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_COEF02_10,
1112 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
1113 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_COEF11_12,
1114 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
1115 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_COEF20_21,
1116 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
1117 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_COEF22,
1118 m[11] & 0x1fff);
1119
1120 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_OFFSET0_1,
1121 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
1122 vpp_reg_write(VPP_WRAP_OSD3_MATRIX_OFFSET2,
1123 m[20] & 0xfff);
1124
1125 vpp_reg_setb(VPP_WRAP_OSD3_MATRIX_EN_CTRL, on, 0, 1);
1126
1127 VPP_PR("%s rgb2yuv on = %d..............\n", __func__, on);
1128 }
1129}
1130
1131 /*
1132for T7, set osd4 matrix(10bit) RGB2YUV
1133 */
1134static void set_osd4_rgb2yuv(bool on)
1135{
1136 int *m = NULL;
1137
1138 if (is_osd_high_version()) {
1139 /* RGB -> 709 limit */
1140 m = RGB709_to_YUV709l_coeff;
1141
1142 /* VPP WRAP OSD3 matrix */
1143 vpp_reg_write(VIU_OSD4_MATRIX_PRE_OFFSET0_1,
1144 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
1145 vpp_reg_write(VIU_OSD4_MATRIX_PRE_OFFSET2,
1146 m[2] & 0xfff);
1147 vpp_reg_write(VIU_OSD4_MATRIX_COEF00_01,
1148 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
1149 vpp_reg_write(VIU_OSD4_MATRIX_COEF02_10,
1150 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
1151 vpp_reg_write(VIU_OSD4_MATRIX_COEF11_12,
1152 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
1153 vpp_reg_write(VIU_OSD4_MATRIX_COEF20_21,
1154 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
1155 vpp_reg_write(VIU_OSD4_MATRIX_COEF22,
1156 m[11] & 0x1fff);
1157
1158 vpp_reg_write(VIU_OSD4_MATRIX_OFFSET0_1,
1159 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
1160 vpp_reg_write(VIU_OSD4_MATRIX_OFFSET2,
1161 m[20] & 0xfff);
1162
1163 vpp_reg_setb(VIU_OSD4_MATRIX_EN_CTRL, on, 0, 1);
1164
1165 VPP_PR("T7 osd4 matrix rgb2yuv..............\n");
1166 }
1167}
1168#endif
1169
1170#ifndef AML_T7_DISPLAY
1171static void set_viu2_osd_matrix_rgb2yuv(bool on)
1172{
1173 int *m = RGB709_to_YUV709l_coeff;
1174
1175 /* RGB -> 709 limit */
1176 if (is_osd_high_version()) {
1177 /* VPP WRAP OSD3 matrix */
1178 vpp_reg_write(VIU2_OSD1_MATRIX_PRE_OFFSET0_1,
1179 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
1180 vpp_reg_write(VIU2_OSD1_MATRIX_PRE_OFFSET2,
1181 m[2] & 0xfff);
1182 vpp_reg_write(VIU2_OSD1_MATRIX_COEF00_01,
1183 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
1184 vpp_reg_write(VIU2_OSD1_MATRIX_COEF02_10,
1185 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
1186 vpp_reg_write(VIU2_OSD1_MATRIX_COEF11_12,
1187 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
1188 vpp_reg_write(VIU2_OSD1_MATRIX_COEF20_21,
1189 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
1190 vpp_reg_write(VIU2_OSD1_MATRIX_COEF22,
1191 m[11] & 0x1fff);
1192
1193 vpp_reg_write(VIU2_OSD1_MATRIX_OFFSET0_1,
1194 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
1195 vpp_reg_write(VIU2_OSD1_MATRIX_OFFSET2,
1196 m[20] & 0xfff);
1197
1198 vpp_reg_setb(VIU2_OSD1_MATRIX_EN_CTRL, on, 0, 1);
1199 }
1200}
1201#endif
1202
1203#ifndef AML_S5_DISPLAY
1204static void set_vpp_osd2_rgb2yuv(bool on)
1205{
1206 int *m = NULL;
1207
1208 /* RGB -> 709 limit */
1209 m = RGB709_to_YUV709l_coeff;
1210
1211 /* VPP WRAP OSD3 matrix */
1212 vpp_reg_write(VPP_OSD2_MATRIX_PRE_OFFSET0_1,
1213 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
1214 vpp_reg_write(VPP_OSD2_MATRIX_PRE_OFFSET2,
1215 m[2] & 0xfff);
1216 vpp_reg_write(VPP_OSD2_MATRIX_COEF00_01,
1217 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
1218 vpp_reg_write(VPP_OSD2_MATRIX_COEF02_10,
1219 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
1220 vpp_reg_write(VPP_OSD2_MATRIX_COEF11_12,
1221 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
1222 vpp_reg_write(VPP_OSD2_MATRIX_COEF20_21,
1223 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
1224 vpp_reg_write(VPP_OSD2_MATRIX_COEF22,
1225 m[11] & 0x1fff);
1226 vpp_reg_write(VPP_OSD2_MATRIX_OFFSET0_1,
1227 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
1228 vpp_reg_write(VPP_OSD2_MATRIX_OFFSET2,
1229 m[20] & 0xfff);
1230 vpp_reg_setb(VPP_OSD2_MATRIX_EN_CTRL, on, 0, 1);
1231 VPP_PR("vpp osd2 matrix rgb2yuv..............\n");
1232}
1233#endif
1234
1235/*
1236for txlx, set vpp default data path to u10
1237 */
1238static void set_vpp_bitdepth(void)
1239{
1240 u32 chip_id = get_cpu_id().family_id;
1241
1242 if (is_osd_high_version()) {
1243 /*after this step vd1 output data is U12,*/
1244 if (chip_id == MESON_CPU_MAJOR_ID_T7) {
1245 /* osd dolby bypass en */
1246 vpp_reg_setb(MALI_AFBCD_TOP_CTRL, 1, 14, 1);
1247 vpp_reg_setb(MALI_AFBCD_TOP_CTRL, 1, 19, 1);
1248 /* osd_din_ext 12bit */
1249 vpp_reg_setb(MALI_AFBCD_TOP_CTRL, 0, 15, 1);
1250 vpp_reg_setb(MALI_AFBCD_TOP_CTRL, 0, 20, 1);
1251
1252 vpp_reg_setb(MALI_AFBCD1_TOP_CTRL, 1, 19, 1);
1253 vpp_reg_setb(MALI_AFBCD1_TOP_CTRL, 0, 20, 1);
1254
1255 vpp_reg_setb(MALI_AFBCD2_TOP_CTRL, 1, 19, 1);
1256 vpp_reg_setb(MALI_AFBCD2_TOP_CTRL, 0, 20, 1);
1257 } else {
1258 vpp_reg_write(DOLBY_PATH_CTRL, 0xf);
1259 }
1260 }
1261}
1262
1263/* osd+video brightness */
1264static void video_adj2_brightness(int val)
1265{
1266 if (val < -255)
1267 val = -255;
1268 else if (val > 255)
1269 val = 255;
1270
1271 VPP_PR("brightness_post:%d\n", val);
1272
1273 vpp_reg_setb(VPP_VADJ2_Y, val << 1, 8, 10);
1274
1275#ifndef AML_S5_DISPLAY
1276 vpp_reg_setb(VPP_VADJ_CTRL, 1, 2, 1);
1277#endif
1278}
1279
1280/* osd+video contrast */
1281static void video_adj2_contrast(int val)
1282{
1283 if (val < -127)
1284 val = -127;
1285 else if (val > 127)
1286 val = 127;
1287
1288 VPP_PR("contrast_post:%d\n", val);
1289
1290 val += 0x80;
1291
1292 vpp_reg_setb(VPP_VADJ2_Y, val, 0, 8);
1293#ifndef AML_S5_DISPLAY
1294 vpp_reg_setb(VPP_VADJ_CTRL, 1, 2, 1);
1295#endif
1296}
1297
1298/* osd+video saturation/hue */
1299static void amvecm_saturation_hue_post(int sat, int hue)
1300{
1301 int hue_post; /*-25~25*/
1302 int saturation_post; /*-128~127*/
1303 int i, ma, mb, mab, mc, md;
1304 int hue_cos[] = {
1305 /*0~12*/
1306 256, 256, 256, 255, 255, 254, 253, 252, 251, 250,
1307 248, 247, 245, 243, 241, 239, 237, 234, 231, 229,
1308 226, 223, 220, 216, 213, 209 /*13~25*/
1309 };
1310 int hue_sin[] = {
1311 -147, -142, -137, -132, -126, -121, -115, -109, -104,
1312 -98, -92, -86, -80, /*-25~-13*/-74, -68, -62, -56,
1313 -50, -44, -38, -31, -25, -19, -13, -6, /*-12~-1*/
1314 0, /*0*/
1315 6, 13, 19, 25, 31, 38, 44, 50, 56,
1316 62, 68, 74, /*1~12*/ 80, 86, 92, 98, 104,
1317 109, 115, 121, 126, 132, 137, 142, 147 /*13~25*/
1318 };
1319
1320 if (sat < -128)
1321 sat = -128;
1322 else if (sat > 128)
1323 sat = 128;
1324
1325 if (hue < -25)
1326 hue = -25;
1327 else if (hue > 25)
1328 hue = 25;
1329
1330 VPP_PR("saturation sat_post:%d hue_post:%d\n", sat, hue);
1331
1332 saturation_post = sat;
1333 hue_post = hue;
1334 i = (hue_post > 0) ? hue_post : -hue_post;
1335 ma = (hue_cos[i]*(saturation_post + 128)) >> 7;
1336 mb = (hue_sin[25+hue_post]*(saturation_post + 128)) >> 7;
1337 if (ma > 511)
1338 ma = 511;
1339 if (ma < -512)
1340 ma = -512;
1341 if (mb > 511)
1342 mb = 511;
1343 if (mb < -512)
1344 mb = -512;
1345 mab = ((ma & 0x3ff) << 16) | (mb & 0x3ff);
1346
1347 vpp_reg_write(VPP_VADJ2_MA_MB, mab);
1348 mc = (s16)((mab<<22)>>22); /* mc = -mb */
1349 mc = 0 - mc;
1350 if (mc > 511)
1351 mc = 511;
1352 if (mc < -512)
1353 mc = -512;
1354 md = (s16)((mab<<6)>>22); /* md = ma; */
1355 mab = ((mc&0x3ff)<<16)|(md&0x3ff);
1356
1357 vpp_reg_write(VPP_VADJ2_MC_MD, mab);
1358#ifndef AML_S5_DISPLAY
1359 vpp_reg_setb(VPP_VADJ_CTRL, 1, 2, 1);
1360#endif
1361}
1362
1363/* init osd+video brightness/contrast/saturaion/hue */
1364void vpp_pq_init(int brightness, int contrast, int sat, int hue)
1365{
1366 video_adj2_brightness(brightness);
1367 video_adj2_contrast(contrast);
1368 amvecm_saturation_hue_post(sat, hue);
1369}
1370
1371void vpp_pq_load(void)
1372{
1373 int i = 0, cnt = 0;
1374 char const *pq = env_get("pq");
1375 char *tk, *str, *tmp[4];
1376 short val[4];
1377
1378 if (pq == NULL) {
1379 VPP_PR("%s pq val error !!!\n", __func__);
1380 return;
1381 }
1382
1383 str = strdup(pq);
1384
1385 for (tk = strsep(&str, ","); tk != NULL; tk = strsep(&str, ",")) {
1386 tmp[cnt] = tk;
1387
1388 if (++cnt > 3)
1389 break;
1390 }
1391
1392 if (cnt == 4) {
1393 for (i = 0; i < 4; i++) {
1394 val[i] = simple_strtol(tmp[i], NULL, 10);
1395 /* VPP_PR("pq[%d]: %d\n", i, val[i]); */
1396 }
1397 vpp_pq_init(val[0], val[1], val[2], val[3]);
1398 }
1399}
1400
1401void vpp_load_gamma_table(unsigned short *data, unsigned int len, enum vpp_gamma_sel_e flag)
1402{
1403 unsigned short *table = NULL;
1404 unsigned int i;
1405
1406 switch (flag) {
1407 case VPP_GAMMA_R:
1408 table = gamma_table_r;
1409 break;
1410 case VPP_GAMMA_G:
1411 table = gamma_table_g;
1412 break;
1413 case VPP_GAMMA_B:
1414 table = gamma_table_b;
1415 break;
1416 default:
1417 break;
1418 }
1419 if (table == NULL) {
1420 VPP_PR("error: %s: invalid flag: %d\n", __func__, flag);
1421 return;
1422 }
1423 if (len != GAMMA_SIZE) {
1424 VPP_PR("error: %s: invalid len: %d\n", __func__, len);
1425 return;
1426 }
1427
1428 for (i = 0; i < GAMMA_SIZE; i++)
1429 table[i] = data[i];
1430 VPP_PR("%s: successful\n", __func__);
1431}
1432
1433void vpp_enable_lcd_gamma_table(int index)
1434{
1435 unsigned int reg;
1436
1437 if (get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_T7) {
1438 switch (index) {
1439 case 1:
1440 reg = LCD_GAMMA_CNTL_PORT0 + 0x100;
1441 break;
1442 case 2:
1443 reg = LCD_GAMMA_CNTL_PORT0 + 0x200;
1444 break;
1445 case 0:
1446 default:
1447 reg = LCD_GAMMA_CNTL_PORT0;
1448 break;
1449 }
1450 } else {
1451 reg = L_GAMMA_CNTL_PORT;
1452 }
1453
1454 vpp_reg_setb(reg, 1, GAMMA_EN, 1);
1455}
1456
1457void vpp_disable_lcd_gamma_table(int index)
1458{
1459 unsigned int reg;
1460
1461 if (get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_T7) {
1462 switch (index) {
1463 case 1:
1464 reg = LCD_GAMMA_CNTL_PORT0 + 0x100;
1465 break;
1466 case 2:
1467 reg = LCD_GAMMA_CNTL_PORT0 + 0x200;
1468 break;
1469 case 0:
1470 default:
1471 reg = LCD_GAMMA_CNTL_PORT0;
1472 break;
1473 }
1474 } else {
1475 reg = L_GAMMA_CNTL_PORT;
1476 }
1477 vpp_reg_setb(reg, 0, GAMMA_EN, 1);
1478}
1479
1480#define GAMMA_RETRY 1000
1481static void vpp_set_lcd_gamma_table(int index, u16 *data, u32 rgb_mask)
1482{
1483 unsigned int reg_encl_en, reg_cntl_port, reg_data_port, reg_addr_port;
1484 int i;
1485 int cnt = 0;
1486
1487 if (get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_T7) {
1488 switch (index) {
1489 case 1:
1490 reg_encl_en = ENCL_VIDEO_EN + 0x600;
1491 reg_cntl_port = LCD_GAMMA_CNTL_PORT0 + 0x100;
1492 reg_data_port = LCD_GAMMA_DATA_PORT0 + 0x100;
1493 reg_addr_port = LCD_GAMMA_ADDR_PORT0 + 0x100;
1494 break;
1495 case 2:
1496 reg_encl_en = ENCL_VIDEO_EN + 0x800;
1497 reg_cntl_port = LCD_GAMMA_CNTL_PORT0 + 0x200;
1498 reg_data_port = LCD_GAMMA_DATA_PORT0 + 0x200;
1499 reg_addr_port = LCD_GAMMA_ADDR_PORT0 + 0x200;
1500 break;
1501 case 0:
1502 default:
1503 reg_encl_en = ENCL_VIDEO_EN;
1504 reg_cntl_port = LCD_GAMMA_CNTL_PORT0;
1505 reg_data_port = LCD_GAMMA_DATA_PORT0;
1506 reg_addr_port = LCD_GAMMA_ADDR_PORT0;
1507 break;
1508 }
1509 } else {
1510 reg_encl_en = ENCL_VIDEO_EN;
1511 reg_cntl_port = L_GAMMA_CNTL_PORT;
1512 reg_data_port = L_GAMMA_DATA_PORT;
1513 reg_addr_port = L_GAMMA_ADDR_PORT;
1514 }
1515
1516 if (get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_T7) {
1517 if (get_cpu_id().family_id == MESON_CPU_MAJOR_ID_T5M) {
1518 vpp_reg_write(reg_addr_port, (1 << 9));
1519 for (i = 0; i < 256; i++)
1520 vpp_reg_write(reg_data_port,
1521 (data[i] << 20) |
1522 (data[i] << 10) |
1523 (data[i] << 0));
1524 vpp_reg_write(reg_data_port,
1525 (0x3ff << 20) |
1526 (0x3ff << 10) |
1527 (0x3ff << 0));
1528 } else {
1529 vpp_reg_write(reg_addr_port, (1 << 8));
1530 for (i = 0; i < 256; i++)
1531 vpp_reg_write(reg_data_port,
1532 (data[i] << 20) |
1533 (data[i] << 10) |
1534 (data[i] << 0));
1535 }
1536 return;
1537 }
1538
1539 if (!(vpp_reg_read(reg_encl_en) & 0x1))
1540 return;
1541
1542 vpp_reg_setb(reg_cntl_port, 0, GAMMA_EN, 1);
1543
1544 while (!(vpp_reg_read(reg_cntl_port) & (0x1 << ADR_RDY))) {
1545 udelay(10);
1546 if (cnt++ > GAMMA_RETRY)
1547 break;
1548 }
1549 cnt = 0;
1550 vpp_reg_write(reg_addr_port, (0x1 << H_AUTO_INC) |
1551 (0x1 << rgb_mask) |
1552 (0x0 << HADR));
1553 for (i = 0; i < 256; i++) {
1554 while (!(vpp_reg_read(reg_cntl_port) & (0x1 << WR_RDY))) {
1555 udelay(10);
1556 if (cnt++ > GAMMA_RETRY)
1557 break;
1558 }
1559 cnt = 0;
1560 vpp_reg_write(reg_data_port, data[i]);
1561 }
1562 while (!(vpp_reg_read(reg_cntl_port) & (0x1 << ADR_RDY))) {
1563 udelay(10);
1564 if (cnt++ > GAMMA_RETRY)
1565 break;
1566 }
1567 vpp_reg_write(reg_addr_port, (0x1 << H_AUTO_INC) |
1568 (0x1 << rgb_mask) |
1569 (0x23 << HADR));
1570
1571}
1572
1573void vpp_init_lcd_gamma_table(int index)
1574{
1575 VPP_PR("%s\n", __func__);
1576
1577 vpp_disable_lcd_gamma_table(index);
1578
1579 vpp_set_lcd_gamma_table(index, gamma_table_r, H_SEL_R);
1580 vpp_set_lcd_gamma_table(index, gamma_table_g, H_SEL_G);
1581 vpp_set_lcd_gamma_table(index, gamma_table_b, H_SEL_B);
1582
1583 vpp_enable_lcd_gamma_table(index);
1584}
1585
1586void vpp_matrix_update(int type)
1587{
1588 if (vpp_init_flag == 0)
1589 return;
1590
1591 switch (type) {
1592 case VPP_CM_RGB:
1593 /* 709 limit to RGB */
1594 vpp_set_matrix_ycbcr2rgb(2, 3);
1595 break;
1596 case VPP_CM_YUV:
1597 break;
1598 default:
1599 break;
1600 }
1601}
1602
1603void vpp_viu2_matrix_update(int type)
1604{
1605 if (vpp_init_flag == 0)
1606 return;
1607
1608 if (get_cpu_id().family_id < MESON_CPU_MAJOR_ID_G12A)
1609 return;
1610
1611 switch (type) {
1612 case VPP_CM_RGB:
1613 /* default RGB */
1614 #ifndef AML_T7_DISPLAY
1615 set_viu2_osd_matrix_rgb2yuv(0);
1616 #else
1617 /* vpp_top1: yuv2rgb */
1618 vpp_top_post2_matrix_yuv2rgb(1);
1619 #endif
1620 break;
1621 case VPP_CM_YUV:
1622 /* RGB to 709 limit */
1623 #ifndef AML_T7_DISPLAY
1624 set_viu2_osd_matrix_rgb2yuv(1);
1625 #endif
1626 break;
1627 default:
1628 break;
1629 }
1630}
1631
1632void vpp_viu3_matrix_update(int type)
1633{
1634 if (vpp_init_flag == 0)
1635 return;
1636
1637 if (get_cpu_id().family_id < MESON_CPU_MAJOR_ID_G12A)
1638 return;
1639
1640 switch (type) {
1641 case VPP_CM_RGB:
1642 /* default RGB */
1643 //#ifndef AML_T7_DISPLAY
1644 //set_viu_osd_matrix_rgb2yuv(0);
1645 //#else
1646 /* vpp_top2: yuv2rgb */
1647 vpp_top_post2_matrix_yuv2rgb(2);
1648 //#endif
1649 break;
1650 case VPP_CM_YUV:
1651 /* RGB to 709 limit */
1652 #ifndef AML_T7_DISPLAY
1653 //set_viu2_osd_matrix_rgb2yuv(2);
1654 #endif
1655 break;
1656 default:
1657 break;
1658 }
1659}
1660
1661static void vpp_ofifo_init(void)
1662{
1663 unsigned int data32;
1664
1665 data32 = vpp_reg_read(VPP_OFIFO_SIZE);
1666 data32 |= 0xfff;
1667 vpp_reg_write(VPP_OFIFO_SIZE, data32);
1668
1669 data32 = 0x08080808;
1670#ifndef AML_S5_DISPLAY
1671 vpp_reg_write(VPP_HOLD_LINES, data32);
1672#endif
1673}
1674
1675#ifdef CONFIG_AML_HDMITX
1676static void amvecm_cp_hdr_info(struct master_display_info_s *hdr_data)
1677{
1678 int i, j;
1679
1680 hdr_data->features =
1681 (0 << 30) /*sdr output 709*/
1682 | (1 << 29) /*video available*/
1683 | (5 << 26) /* unspecified */
1684 | (0 << 25) /* limit */
1685 | (1 << 24) /* color available */
1686 | (9 << 16) /* bt2020 */
1687 | (16 << 8) /* bt2020-10 */
1688 | (10 << 0); /* bt2020c */
1689
1690 for (i = 0; i < 3; i++)
1691 for (j = 0; j < 2; j++)
1692 hdr_data->primaries[i][j] =
1693 bt2020_primaries[i][j];
1694 hdr_data->white_point[0] = bt2020_white_point[0];
1695 hdr_data->white_point[1] = bt2020_white_point[1];
1696 /* default luminance */
1697 hdr_data->luminance[0] = 1000 * 10000;
1698 hdr_data->luminance[1] = 50;
1699
1700 /* content_light_level */
1701 hdr_data->max_content = 0;
1702 hdr_data->max_frame_average = 0;
1703 hdr_data->luminance[0] = hdr_data->luminance[0] / 10000;
1704 hdr_data->present_flag = 1;
1705}
1706#endif
1707
1708void hdr_tx_pkt_cb(void)
1709{
1710 int hdr_policy = 0;
1711#ifdef CONFIG_AML_HDMITX
1712 struct master_display_info_s hdr_data;
1713 struct hdr_info *hdrinfo = NULL;
1714#endif
1715 const char *hdr_policy_env = env_get("hdr_policy");
1716
1717 if (!hdr_policy_env)
1718 return;
1719
1720 hdr_policy = simple_strtoul(hdr_policy_env, NULL, 10);
1721#ifdef CONFIG_AML_HDMITX
1722 hdrinfo = hdmitx_get_rx_hdr_info();
1723
1724 if ((hdrinfo && hdrinfo->hdr_sup_eotf_smpte_st_2084) &&
1725 hdr_policy == 0) {
1726 if (is_hdmi_mode(env_get("outputmode"))) {
1727 hdr_func(OSD1_HDR, SDR_HDR);
1728 hdr_func(OSD2_HDR, SDR_HDR);
1729 hdr_func(VD1_HDR, SDR_HDR);
1730 }
1731 if (is_hdmi_mode(env_get("outputmode2")))
1732 hdr_func(OSD3_HDR, SDR_HDR);
1733 if (is_hdmi_mode(env_get("outputmode3")))
1734 hdr_func(OSD4_HDR, SDR_HDR);
1735 amvecm_cp_hdr_info(&hdr_data);
1736 hdmitx_set_drm_pkt(&hdr_data);
1737 }
1738#endif
1739
1740 VPP_PR("hdr_policy = %d\n", hdr_policy);
1741#ifdef CONFIG_AML_HDMITX
1742 if (hdrinfo)
1743 VPP_PR("Rx hdr_info.hdr_sup_eotf_smpte_st_2084 = %d\n",
1744 hdrinfo->hdr_sup_eotf_smpte_st_2084);
1745#endif
1746}
1747
1748static bool is_vpp_supported(int chip_id)
1749{
1750 if ((chip_id == MESON_CPU_MAJOR_ID_A1) ||
1751 (chip_id == MESON_CPU_MAJOR_ID_C1) ||
1752 (chip_id == MESON_CPU_MAJOR_ID_C2))
1753 return false;
1754 else
1755 return true;
1756}
1757
1758void vpp_init(void)
1759{
1760 int chip_id;
1761
1762 chip_id = vpp_get_chip_type();
1763 VPP_PR("%s, chip_id=%d\n", __func__, chip_id);
1764 if (!is_vpp_supported(chip_id)) {
1765 VPP_PR("%s, vpp not supported\n", __func__);
1766 return;
1767 }
1768 vpp_init_flag = 1;
1769
1770 /* init vpu fifo control register */
1771 vpp_ofifo_init();
1772
1773#ifndef AML_S5_DISPLAY
1774 vpp_set_matrix_default_init();
1775#endif
1776
1777 if (is_osd_high_version()) {
1778 /* >= g12a: osd out is rgb */
1779#ifndef AML_S5_DISPLAY
1780 set_osd1_rgb2yuv(0);
1781 set_osd2_rgb2yuv(0);
1782 if (chip_id != MESON_CPU_MAJOR_ID_TL1 &&
1783 chip_id != MESON_CPU_MAJOR_ID_S4)
1784 set_osd3_rgb2yuv(0);
1785
1786 if (chip_id != MESON_CPU_MAJOR_ID_T7)
1787 set_vpp_osd2_rgb2yuv(1);
1788 else
1789 set_osd4_rgb2yuv(0);
1790#endif
1791 /* set vpp data path to u12 */
1792 set_vpp_bitdepth();
1793 hdr_func(OSD1_HDR, HDR_BYPASS | RGB_OSD);
1794 hdr_func(OSD2_HDR, HDR_BYPASS | RGB_OSD);
1795 hdr_func(OSD3_HDR, HDR_BYPASS | RGB_OSD);
1796 hdr_func(OSD4_HDR, HDR_BYPASS | RGB_OSD);
1797 hdr_func(VD1_HDR, HDR_BYPASS);
1798 hdr_func(VD2_HDR, HDR_BYPASS);
1799 } else {
1800 /* set dummy data default YUV black */
1801#ifndef AML_S5_DISPLAY
1802 vpp_reg_write(VPP_DUMMY_DATA1, 0x108080);
1803 /* osd1: rgb->yuv limit , osd2: yuv limit */
1804 set_osd1_rgb2yuv(1);
1805#endif
1806 }
1807}