xref: /linux/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c (revision d4a292c5f8e65d2784b703c67179f4f7d0c7846c)
1 // SPDX-License-Identifier: MIT
2 //
3 // Copyright 2024 Advanced Micro Devices, Inc.
4 
5 #include "spl_debug.h"
6 #include "dc_spl_filters.h"
7 #include "dc_spl_isharp_filters.h"
8 
9 //========================================
10 // Delta Gain 1DLUT
11 // LUT content is packed as 4-bytes into one DWORD/entry
12 // A_start = 0.000000
13 // A_end   = 10.000000
14 // A_gain  = 3.000000
15 // B_start = 11.000000
16 // B_end   = 127.000000
17 // C_start = 40.000000
18 // C_end   = 127.000000
19 //========================================
20 static const uint32_t filter_isharp_1D_lut_3p0x[ISHARP_LUT_TABLE_SIZE] = {
21 0x03010000,
22 0x0F0B0805,
23 0x211E1813,
24 0x2B292624,
25 0x3533302E,
26 0x3E3C3A37,
27 0x46444240,
28 0x4D4B4A48,
29 0x5352504F,
30 0x59575655,
31 0x5D5C5B5A,
32 0x61605F5E,
33 0x64646362,
34 0x66666565,
35 0x68686767,
36 0x68686868,
37 0x68686868,
38 0x67676868,
39 0x65656666,
40 0x62636464,
41 0x5E5F6061,
42 0x5A5B5C5D,
43 0x55565759,
44 0x4F505253,
45 0x484A4B4D,
46 0x40424446,
47 0x373A3C3E,
48 0x2E303335,
49 0x2426292B,
50 0x191B1E21,
51 0x0D101316,
52 0x0003060A,
53 };
54 
55 // Blur and scale coefficients
56 //========================================================
57 // <using>			gen_BlurScale_coeffs.m
58 // <date>			25-Apr-2022
59 // <num_taps>		4
60 // <num_phases>		64
61 // <CoefType>		Blur & Scale LPF
62 // <CoefQuant>		S1.10
63 //========================================================
64 static const uint16_t filter_isharp_bs_4tap_in_6_64p[198] = {
65 0x0000, 0x00E5, 0x0237, 0x00E4, 0x0000, 0x0000,
66 0x0000, 0x00DE, 0x0237, 0x00EB, 0x0000, 0x0000,
67 0x0000, 0x00D7, 0x0236, 0x00F2, 0x0001, 0x0000,
68 0x0000, 0x00D0, 0x0235, 0x00FA, 0x0001, 0x0000,
69 0x0000, 0x00C9, 0x0234, 0x0101, 0x0002, 0x0000,
70 0x0000, 0x00C2, 0x0233, 0x0108, 0x0003, 0x0000,
71 0x0000, 0x00BB, 0x0232, 0x0110, 0x0003, 0x0000,
72 0x0000, 0x00B5, 0x0230, 0x0117, 0x0004, 0x0000,
73 0x0000, 0x00AE, 0x022E, 0x011F, 0x0005, 0x0000,
74 0x0000, 0x00A8, 0x022C, 0x0126, 0x0006, 0x0000,
75 0x0000, 0x00A2, 0x022A, 0x012D, 0x0007, 0x0000,
76 0x0000, 0x009C, 0x0228, 0x0134, 0x0008, 0x0000,
77 0x0000, 0x0096, 0x0225, 0x013C, 0x0009, 0x0000,
78 0x0000, 0x0090, 0x0222, 0x0143, 0x000B, 0x0000,
79 0x0000, 0x008A, 0x021F, 0x014B, 0x000C, 0x0000,
80 0x0000, 0x0085, 0x021C, 0x0151, 0x000E, 0x0000,
81 0x0000, 0x007F, 0x0218, 0x015A, 0x000F, 0x0000,
82 0x0000, 0x007A, 0x0215, 0x0160, 0x0011, 0x0000,
83 0x0000, 0x0074, 0x0211, 0x0168, 0x0013, 0x0000,
84 0x0000, 0x006F, 0x020D, 0x016F, 0x0015, 0x0000,
85 0x0000, 0x006A, 0x0209, 0x0176, 0x0017, 0x0000,
86 0x0000, 0x0065, 0x0204, 0x017E, 0x0019, 0x0000,
87 0x0000, 0x0060, 0x0200, 0x0185, 0x001B, 0x0000,
88 0x0000, 0x005C, 0x01FB, 0x018C, 0x001D, 0x0000,
89 0x0000, 0x0057, 0x01F6, 0x0193, 0x0020, 0x0000,
90 0x0000, 0x0053, 0x01F1, 0x019A, 0x0022, 0x0000,
91 0x0000, 0x004E, 0x01EC, 0x01A1, 0x0025, 0x0000,
92 0x0000, 0x004A, 0x01E6, 0x01A8, 0x0028, 0x0000,
93 0x0000, 0x0046, 0x01E1, 0x01AF, 0x002A, 0x0000,
94 0x0000, 0x0042, 0x01DB, 0x01B6, 0x002D, 0x0000,
95 0x0000, 0x003F, 0x01D5, 0x01BB, 0x0031, 0x0000,
96 0x0000, 0x003B, 0x01CF, 0x01C2, 0x0034, 0x0000,
97 0x0000, 0x0037, 0x01C9, 0x01C9, 0x0037, 0x0000
98 };
99 //========================================================
100 // <using>			gen_BlurScale_coeffs.m
101 // <date>			25-Apr-2022
102 // <num_taps>		4
103 // <num_phases>		64
104 // <CoefType>		Blur & Scale LPF
105 // <CoefQuant>		S1.10
106 //========================================================
107 static const uint16_t filter_isharp_bs_4tap_64p[132] = {
108 0x00E5, 0x0237, 0x00E4, 0x0000,
109 0x00DE, 0x0237, 0x00EB, 0x0000,
110 0x00D7, 0x0236, 0x00F2, 0x0001,
111 0x00D0, 0x0235, 0x00FA, 0x0001,
112 0x00C9, 0x0234, 0x0101, 0x0002,
113 0x00C2, 0x0233, 0x0108, 0x0003,
114 0x00BB, 0x0232, 0x0110, 0x0003,
115 0x00B5, 0x0230, 0x0117, 0x0004,
116 0x00AE, 0x022E, 0x011F, 0x0005,
117 0x00A8, 0x022C, 0x0126, 0x0006,
118 0x00A2, 0x022A, 0x012D, 0x0007,
119 0x009C, 0x0228, 0x0134, 0x0008,
120 0x0096, 0x0225, 0x013C, 0x0009,
121 0x0090, 0x0222, 0x0143, 0x000B,
122 0x008A, 0x021F, 0x014B, 0x000C,
123 0x0085, 0x021C, 0x0151, 0x000E,
124 0x007F, 0x0218, 0x015A, 0x000F,
125 0x007A, 0x0215, 0x0160, 0x0011,
126 0x0074, 0x0211, 0x0168, 0x0013,
127 0x006F, 0x020D, 0x016F, 0x0015,
128 0x006A, 0x0209, 0x0176, 0x0017,
129 0x0065, 0x0204, 0x017E, 0x0019,
130 0x0060, 0x0200, 0x0185, 0x001B,
131 0x005C, 0x01FB, 0x018C, 0x001D,
132 0x0057, 0x01F6, 0x0193, 0x0020,
133 0x0053, 0x01F1, 0x019A, 0x0022,
134 0x004E, 0x01EC, 0x01A1, 0x0025,
135 0x004A, 0x01E6, 0x01A8, 0x0028,
136 0x0046, 0x01E1, 0x01AF, 0x002A,
137 0x0042, 0x01DB, 0x01B6, 0x002D,
138 0x003F, 0x01D5, 0x01BB, 0x0031,
139 0x003B, 0x01CF, 0x01C2, 0x0034,
140 0x0037, 0x01C9, 0x01C9, 0x0037,
141 };
142 //========================================================
143 // <using>			gen_BlurScale_coeffs.m
144 // <date>			09-Jun-2022
145 // <num_taps>		3
146 // <num_phases>		64
147 // <CoefType>		Blur & Scale LPF
148 // <CoefQuant>		S1.10
149 //========================================================
150 static const uint16_t filter_isharp_bs_3tap_64p[99] = {
151 0x0200, 0x0200, 0x0000,
152 0x01F6, 0x0206, 0x0004,
153 0x01EC, 0x020B, 0x0009,
154 0x01E2, 0x0211, 0x000D,
155 0x01D8, 0x0216, 0x0012,
156 0x01CE, 0x021C, 0x0016,
157 0x01C4, 0x0221, 0x001B,
158 0x01BA, 0x0226, 0x0020,
159 0x01B0, 0x022A, 0x0026,
160 0x01A6, 0x022F, 0x002B,
161 0x019C, 0x0233, 0x0031,
162 0x0192, 0x0238, 0x0036,
163 0x0188, 0x023C, 0x003C,
164 0x017E, 0x0240, 0x0042,
165 0x0174, 0x0244, 0x0048,
166 0x016A, 0x0248, 0x004E,
167 0x0161, 0x024A, 0x0055,
168 0x0157, 0x024E, 0x005B,
169 0x014D, 0x0251, 0x0062,
170 0x0144, 0x0253, 0x0069,
171 0x013A, 0x0256, 0x0070,
172 0x0131, 0x0258, 0x0077,
173 0x0127, 0x025B, 0x007E,
174 0x011E, 0x025C, 0x0086,
175 0x0115, 0x025E, 0x008D,
176 0x010B, 0x0260, 0x0095,
177 0x0102, 0x0262, 0x009C,
178 0x00F9, 0x0263, 0x00A4,
179 0x00F0, 0x0264, 0x00AC,
180 0x00E7, 0x0265, 0x00B4,
181 0x00DF, 0x0264, 0x00BD,
182 0x00D6, 0x0265, 0x00C5,
183 0x00CD, 0x0266, 0x00CD,
184 };
185 
186 /* Converted Blur & Scale coeff tables from S1.10 to S1.12 */
187 static const uint16_t filter_isharp_bs_4tap_in_6_64p_s1_12[198] = {
188 0x0000, 0x0394, 0x08dc, 0x0390, 0x0000, 0x0000,
189 0x0000, 0x0378, 0x08dc, 0x03ac, 0x0000, 0x0000,
190 0x0000, 0x035c, 0x08d8, 0x03c8, 0x0004, 0x0000,
191 0x0000, 0x0340, 0x08d4, 0x03e8, 0x0004, 0x0000,
192 0x0000, 0x0324, 0x08d0, 0x0404, 0x0008, 0x0000,
193 0x0000, 0x0308, 0x08cc, 0x0420, 0x000c, 0x0000,
194 0x0000, 0x02ec, 0x08c8, 0x0440, 0x000c, 0x0000,
195 0x0000, 0x02d4, 0x08c0, 0x045c, 0x0010, 0x0000,
196 0x0000, 0x02b8, 0x08b8, 0x047c, 0x0014, 0x0000,
197 0x0000, 0x02a0, 0x08b0, 0x0498, 0x0018, 0x0000,
198 0x0000, 0x0288, 0x08a8, 0x04b4, 0x001c, 0x0000,
199 0x0000, 0x0270, 0x08a0, 0x04d0, 0x0020, 0x0000,
200 0x0000, 0x0258, 0x0894, 0x04f0, 0x0024, 0x0000,
201 0x0000, 0x0240, 0x0888, 0x050c, 0x002c, 0x0000,
202 0x0000, 0x0228, 0x087c, 0x052c, 0x0030, 0x0000,
203 0x0000, 0x0214, 0x0870, 0x0544, 0x0038, 0x0000,
204 0x0000, 0x01fc, 0x0860, 0x0568, 0x003c, 0x0000,
205 0x0000, 0x01e8, 0x0854, 0x0580, 0x0044, 0x0000,
206 0x0000, 0x01d0, 0x0844, 0x05a0, 0x004c, 0x0000,
207 0x0000, 0x01bc, 0x0834, 0x05bc, 0x0054, 0x0000,
208 0x0000, 0x01a8, 0x0824, 0x05d8, 0x005c, 0x0000,
209 0x0000, 0x0194, 0x0810, 0x05f8, 0x0064, 0x0000,
210 0x0000, 0x0180, 0x0800, 0x0614, 0x006c, 0x0000,
211 0x0000, 0x0170, 0x07ec, 0x0630, 0x0074, 0x0000,
212 0x0000, 0x015c, 0x07d8, 0x064c, 0x0080, 0x0000,
213 0x0000, 0x014c, 0x07c4, 0x0668, 0x0088, 0x0000,
214 0x0000, 0x0138, 0x07b0, 0x0684, 0x0094, 0x0000,
215 0x0000, 0x0128, 0x0798, 0x06a0, 0x00a0, 0x0000,
216 0x0000, 0x0118, 0x0784, 0x06bc, 0x00a8, 0x0000,
217 0x0000, 0x0108, 0x076c, 0x06d8, 0x00b4, 0x0000,
218 0x0000, 0x00fc, 0x0754, 0x06ec, 0x00c4, 0x0000,
219 0x0000, 0x00ec, 0x073c, 0x0708, 0x00d0, 0x0000,
220 0x0000, 0x00dc, 0x0724, 0x0724, 0x00dc, 0x0000,
221 };
222 
223 static const uint16_t filter_isharp_bs_4tap_64p_s1_12[132] = {
224 0x0394, 0x08dc, 0x0390, 0x0000,
225 0x0378, 0x08dc, 0x03ac, 0x0000,
226 0x035c, 0x08d8, 0x03c8, 0x0004,
227 0x0340, 0x08d4, 0x03e8, 0x0004,
228 0x0324, 0x08d0, 0x0404, 0x0008,
229 0x0308, 0x08cc, 0x0420, 0x000c,
230 0x02ec, 0x08c8, 0x0440, 0x000c,
231 0x02d4, 0x08c0, 0x045c, 0x0010,
232 0x02b8, 0x08b8, 0x047c, 0x0014,
233 0x02a0, 0x08b0, 0x0498, 0x0018,
234 0x0288, 0x08a8, 0x04b4, 0x001c,
235 0x0270, 0x08a0, 0x04d0, 0x0020,
236 0x0258, 0x0894, 0x04f0, 0x0024,
237 0x0240, 0x0888, 0x050c, 0x002c,
238 0x0228, 0x087c, 0x052c, 0x0030,
239 0x0214, 0x0870, 0x0544, 0x0038,
240 0x01fc, 0x0860, 0x0568, 0x003c,
241 0x01e8, 0x0854, 0x0580, 0x0044,
242 0x01d0, 0x0844, 0x05a0, 0x004c,
243 0x01bc, 0x0834, 0x05bc, 0x0054,
244 0x01a8, 0x0824, 0x05d8, 0x005c,
245 0x0194, 0x0810, 0x05f8, 0x0064,
246 0x0180, 0x0800, 0x0614, 0x006c,
247 0x0170, 0x07ec, 0x0630, 0x0074,
248 0x015c, 0x07d8, 0x064c, 0x0080,
249 0x014c, 0x07c4, 0x0668, 0x0088,
250 0x0138, 0x07b0, 0x0684, 0x0094,
251 0x0128, 0x0798, 0x06a0, 0x00a0,
252 0x0118, 0x0784, 0x06bc, 0x00a8,
253 0x0108, 0x076c, 0x06d8, 0x00b4,
254 0x00fc, 0x0754, 0x06ec, 0x00c4,
255 0x00ec, 0x073c, 0x0708, 0x00d0,
256 0x00dc, 0x0724, 0x0724, 0x00dc,
257 };
258 
259 static const uint16_t filter_isharp_bs_3tap_64p_s1_12[99] = {
260 0x0800, 0x0800, 0x0000,
261 0x07d8, 0x0818, 0x0010,
262 0x07b0, 0x082c, 0x0024,
263 0x0788, 0x0844, 0x0034,
264 0x0760, 0x0858, 0x0048,
265 0x0738, 0x0870, 0x0058,
266 0x0710, 0x0884, 0x006c,
267 0x06e8, 0x0898, 0x0080,
268 0x06c0, 0x08a8, 0x0098,
269 0x0698, 0x08bc, 0x00ac,
270 0x0670, 0x08cc, 0x00c4,
271 0x0648, 0x08e0, 0x00d8,
272 0x0620, 0x08f0, 0x00f0,
273 0x05f8, 0x0900, 0x0108,
274 0x05d0, 0x0910, 0x0120,
275 0x05a8, 0x0920, 0x0138,
276 0x0584, 0x0928, 0x0154,
277 0x055c, 0x0938, 0x016c,
278 0x0534, 0x0944, 0x0188,
279 0x0510, 0x094c, 0x01a4,
280 0x04e8, 0x0958, 0x01c0,
281 0x04c4, 0x0960, 0x01dc,
282 0x049c, 0x096c, 0x01f8,
283 0x0478, 0x0970, 0x0218,
284 0x0454, 0x0978, 0x0234,
285 0x042c, 0x0980, 0x0254,
286 0x0408, 0x0988, 0x0270,
287 0x03e4, 0x098c, 0x0290,
288 0x03c0, 0x0990, 0x02b0,
289 0x039c, 0x0994, 0x02d0,
290 0x037c, 0x0990, 0x02f4,
291 0x0358, 0x0994, 0x0314,
292 0x0334, 0x0998, 0x0334,
293 };
294 
295 /* Pre-generated 1DLUT for given setup and sharpness level */
296 static struct isharp_1D_lut_pregen filter_isharp_1D_lut_pregen[NUM_SHARPNESS_SETUPS] = {
297 	{
298 		0, 0,
299 		{
300 			0, 0, 0, 0, 0, 0, 0, 0,
301 			0, 0, 0, 0, 0, 0, 0, 0,
302 			0, 0, 0, 0, 0, 0, 0, 0,
303 			0, 0, 0, 0, 0, 0, 0, 0,
304 		}
305 	},
306 	{
307 		0, 0,
308 		{
309 			0, 0, 0, 0, 0, 0, 0, 0,
310 			0, 0, 0, 0, 0, 0, 0, 0,
311 			0, 0, 0, 0, 0, 0, 0, 0,
312 			0, 0, 0, 0, 0, 0, 0, 0,
313 		}
314 	},
315 	{
316 		0, 0,
317 		{
318 			0, 0, 0, 0, 0, 0, 0, 0,
319 			0, 0, 0, 0, 0, 0, 0, 0,
320 			0, 0, 0, 0, 0, 0, 0, 0,
321 			0, 0, 0, 0, 0, 0, 0, 0,
322 		}
323 	},
324 	{
325 		0, 0,
326 		{
327 			0, 0, 0, 0, 0, 0, 0, 0,
328 			0, 0, 0, 0, 0, 0, 0, 0,
329 			0, 0, 0, 0, 0, 0, 0, 0,
330 			0, 0, 0, 0, 0, 0, 0, 0,
331 		}
332 	},
333 };
334 
335 static struct scale_ratio_to_sharpness_level_adj sharpness_level_adj[NUM_SHARPNESS_ADJ_LEVELS] = {
336 	{1125, 1000, 0},
337 	{11, 10, 1},
338 	{1075, 1000, 2},
339 	{105, 100, 3},
340 	{1025, 1000, 4},
341 	{1, 1, 5},
342 };
343 
spl_calculate_sharpness_level_adj(struct spl_fixed31_32 ratio)344 static unsigned int spl_calculate_sharpness_level_adj(struct spl_fixed31_32 ratio)
345 {
346 	int j;
347 	struct spl_fixed31_32 ratio_level;
348 	struct scale_ratio_to_sharpness_level_adj *lookup_ptr;
349 	unsigned int sharpness_level_down_adj;
350 
351 	/*
352 	 * Adjust sharpness level based on current scaling ratio
353 	 *
354 	 * We have 5 discrete scaling ratios which we will use to adjust the
355 	 *  sharpness level down by 1 as we pass each ratio.  The ratios
356 	 *  are
357 	 *
358 	 * 1.125 upscale and higher - no adj
359 	 * 1.100 - under 1.125 - adj level down 1
360 	 * 1.075 - under 1.100 - adj level down 2
361 	 * 1.050 - under 1.075 - adj level down 3
362 	 * 1.025 - under 1.050 - adj level down 4
363 	 * 1.000 - under 1.025 - adj level down 5
364 	 *
365 	 */
366 	j = 0;
367 	sharpness_level_down_adj = 0;
368 	lookup_ptr = sharpness_level_adj;
369 	while (j < NUM_SHARPNESS_ADJ_LEVELS) {
370 		ratio_level = SPL_NAMESPACE(spl_fixpt_from_fraction(lookup_ptr->ratio_numer,
371 			lookup_ptr->ratio_denom));
372 		if (ratio.value >= ratio_level.value) {
373 			sharpness_level_down_adj = lookup_ptr->level_down_adj;
374 			break;
375 		}
376 		lookup_ptr++;
377 		j++;
378 	}
379 	return sharpness_level_down_adj;
380 }
381 
spl_calculate_sharpness_level(struct spl_fixed31_32 ratio,unsigned int discrete_sharpness_level,enum system_setup setup,struct spl_sharpness_range sharpness_range,enum scale_to_sharpness_policy scale_to_sharpness_policy)382 static unsigned int spl_calculate_sharpness_level(struct spl_fixed31_32 ratio,
383 		unsigned int discrete_sharpness_level, enum system_setup setup,
384 		struct spl_sharpness_range sharpness_range,
385 		enum scale_to_sharpness_policy scale_to_sharpness_policy)
386 {
387 	unsigned int sharpness_level = 0;
388 	unsigned int sharpness_level_down_adj = 0;
389 
390 	int min_sharpness, max_sharpness, mid_sharpness;
391 
392 	/*
393 	 * Adjust sharpness level if policy requires we adjust it based on
394 	 *  scale ratio.  Based on scale ratio, we may adjust the sharpness
395 	 *  level down by a certain number of steps.  We will not select
396 	 *  a sharpness value of 0 so the lowest sharpness level will be
397 	 *  0 or 1 depending on what the min_sharpness is
398 	 *
399 	 * If the policy is no required, this code maybe removed at a later
400 	 *  date
401 	 */
402 	switch (setup) {
403 
404 	case HDR_L:
405 		min_sharpness = sharpness_range.hdr_rgb_min;
406 		max_sharpness = sharpness_range.hdr_rgb_max;
407 		mid_sharpness = sharpness_range.hdr_rgb_mid;
408 		if (scale_to_sharpness_policy == SCALE_TO_SHARPNESS_ADJ_ALL)
409 			sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio);
410 		break;
411 	case HDR_NL:
412 		/* currently no use case, use Non-linear SDR values for now */
413 	case SDR_NL:
414 		min_sharpness = sharpness_range.sdr_yuv_min;
415 		max_sharpness = sharpness_range.sdr_yuv_max;
416 		mid_sharpness = sharpness_range.sdr_yuv_mid;
417 		if (scale_to_sharpness_policy >= SCALE_TO_SHARPNESS_ADJ_YUV)
418 			sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio);
419 		break;
420 	case SDR_L:
421 	default:
422 		min_sharpness = sharpness_range.sdr_rgb_min;
423 		max_sharpness = sharpness_range.sdr_rgb_max;
424 		mid_sharpness = sharpness_range.sdr_rgb_mid;
425 		if (scale_to_sharpness_policy == SCALE_TO_SHARPNESS_ADJ_ALL)
426 			sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio);
427 		break;
428 	}
429 
430 	if ((min_sharpness == 0) && (sharpness_level_down_adj >= discrete_sharpness_level))
431 		discrete_sharpness_level = 1;
432 	else if (sharpness_level_down_adj >= discrete_sharpness_level)
433 		discrete_sharpness_level = 0;
434 	else
435 		discrete_sharpness_level -= sharpness_level_down_adj;
436 
437 	int lower_half_step_size = (mid_sharpness - min_sharpness) / 5;
438 	int upper_half_step_size = (max_sharpness - mid_sharpness) / 5;
439 
440 	// lower half linear approximation
441 	if (discrete_sharpness_level < 5)
442 		sharpness_level = min_sharpness + (lower_half_step_size * discrete_sharpness_level);
443 	// upper half linear approximation
444 	else
445 		sharpness_level = mid_sharpness + (upper_half_step_size * (discrete_sharpness_level - 5));
446 
447 	return sharpness_level;
448 }
449 
SPL_NAMESPACE(spl_build_isharp_1dlut_from_reference_curve (struct spl_fixed31_32 ratio,enum system_setup setup,struct adaptive_sharpness sharpness,enum scale_to_sharpness_policy scale_to_sharpness_policy))450 void SPL_NAMESPACE(spl_build_isharp_1dlut_from_reference_curve(
451 	struct spl_fixed31_32 ratio, enum system_setup setup,
452 	struct adaptive_sharpness sharpness, enum scale_to_sharpness_policy scale_to_sharpness_policy))
453 {
454 	uint8_t *byte_ptr_1dlut_src, *byte_ptr_1dlut_dst;
455 	struct spl_fixed31_32 sharp_base, sharp_calc, sharp_level;
456 	int j;
457 	int size_1dlut;
458 	int sharp_calc_int;
459 	uint32_t filter_pregen_store[ISHARP_LUT_TABLE_SIZE];
460 
461 	/* Custom sharpnessX1000 value */
462 	unsigned int sharpnessX1000 = spl_calculate_sharpness_level(ratio,
463 			sharpness.sharpness_level, setup,
464 			sharpness.sharpness_range, scale_to_sharpness_policy);
465 	sharp_level = SPL_NAMESPACE(spl_fixpt_from_fraction(sharpnessX1000, 1000));
466 
467 	/*
468 	 * Check if pregen 1dlut table is already precalculated
469 	 * If numer/denom is different, then recalculate
470 	 */
471 	if ((filter_isharp_1D_lut_pregen[setup].sharpness_numer == sharpnessX1000) &&
472 		(filter_isharp_1D_lut_pregen[setup].sharpness_denom == 1000))
473 		return;
474 
475 	/*
476 	 * Calculate LUT_128_gained with this equation:
477 	 *
478 	 * LUT_128_gained[i] = (uint8)(0.5 + min(255,(double)(LUT_128[i])*sharpLevel/iGain))
479 	 *  where LUT_128[i] is contents of 3p0x isharp 1dlut
480 	 *  where sharpLevel is desired sharpness level
481 	 *  where iGain is base sharpness level 3.0
482 	 *  where LUT_128_gained[i] is adjusted 1dlut value based on desired sharpness level
483 	 */
484 	byte_ptr_1dlut_src = (uint8_t *)filter_isharp_1D_lut_3p0x;
485 	byte_ptr_1dlut_dst = (uint8_t *)filter_pregen_store;
486 	size_1dlut = sizeof(filter_isharp_1D_lut_3p0x);
487 	memset(byte_ptr_1dlut_dst, 0, size_1dlut);
488 	for (j = 0; j < size_1dlut; j++) {
489 		sharp_base = spl_fixpt_from_int((int)*byte_ptr_1dlut_src);
490 		sharp_calc = SPL_NAMESPACE(spl_fixpt_mul(sharp_base, sharp_level));
491 		sharp_calc = spl_fixpt_div(sharp_calc, spl_fixpt_from_int(3));
492 		sharp_calc = spl_fixpt_min(spl_fixpt_from_int(255), sharp_calc);
493 		sharp_calc = spl_fixpt_add(sharp_calc,
494 			SPL_NAMESPACE(spl_fixpt_from_fraction(1, 2)));
495 		sharp_calc_int = spl_fixpt_floor(sharp_calc);
496 		/* Clamp it at 0x7F so it doesn't wrap */
497 		if (sharp_calc_int > 127)
498 			sharp_calc_int = 127;
499 		*byte_ptr_1dlut_dst = (uint8_t)sharp_calc_int;
500 
501 		byte_ptr_1dlut_src++;
502 		byte_ptr_1dlut_dst++;
503 	}
504 
505 	/* Update 1dlut table and sharpness level */
506 	memcpy((void *)filter_isharp_1D_lut_pregen[setup].value, (void *)filter_pregen_store, size_1dlut);
507 	filter_isharp_1D_lut_pregen[setup].sharpness_numer = sharpnessX1000;
508 	filter_isharp_1D_lut_pregen[setup].sharpness_denom = 1000;
509 }
510 
SPL_NAMESPACE(spl_get_pregen_filter_isharp_1D_lut (enum system_setup setup))511 uint32_t *SPL_NAMESPACE(spl_get_pregen_filter_isharp_1D_lut(enum system_setup setup))
512 {
513 	return filter_isharp_1D_lut_pregen[setup].value;
514 }
515 
SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p (int taps))516 const uint16_t *SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p(int taps))
517 {
518 	if (taps == 3)
519 		return filter_isharp_bs_3tap_64p_s1_12;
520 	else if (taps == 4)
521 		return filter_isharp_bs_4tap_64p_s1_12;
522 	else if (taps == 6)
523 		return filter_isharp_bs_4tap_in_6_64p_s1_12;
524 	else {
525 		/* should never happen, bug */
526 		SPL_BREAK_TO_DEBUGGER();
527 		return NULL;
528 	}
529 }
530 
SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p_s1_10 (int taps))531 const uint16_t *SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p_s1_10(int taps))
532 {
533 	if (taps == 3)
534 		return filter_isharp_bs_3tap_64p;
535 	else if (taps == 4)
536 		return filter_isharp_bs_4tap_64p;
537 	else if (taps == 6)
538 		return filter_isharp_bs_4tap_in_6_64p;
539 	else {
540 		/* should never happen, bug */
541 		SPL_BREAK_TO_DEBUGGER();
542 		return NULL;
543 	}
544 }
545 
SPL_NAMESPACE(spl_set_blur_scale_data (struct dscl_prog_data * dscl_prog_data,const struct spl_scaler_data * data))546 void SPL_NAMESPACE(spl_set_blur_scale_data(struct dscl_prog_data *dscl_prog_data,
547 		const struct spl_scaler_data *data))
548 {
549 	dscl_prog_data->filter_blur_scale_h =
550 		SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p(data->taps.h_taps));
551 
552 	dscl_prog_data->filter_blur_scale_v =
553 		SPL_NAMESPACE(spl_dscl_get_blur_scale_coeffs_64p(data->taps.v_taps));
554 }
555