drm/amd/display: Move all linux includes into OS types
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / dce110 / dce110_transform_v.c
1 /*
2  * Copyright 2012-15 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25
26 #include "dce110_transform_v.h"
27 #include "dm_services.h"
28 #include "dc.h"
29 #include "dce/dce_11_0_d.h"
30 #include "dce/dce_11_0_sh_mask.h"
31
32 #define SCLV_PHASES 64
33 #define DC_LOGGER \
34         xfm->ctx->logger
35
36 struct sclv_ratios_inits {
37         uint32_t h_int_scale_ratio_luma;
38         uint32_t h_int_scale_ratio_chroma;
39         uint32_t v_int_scale_ratio_luma;
40         uint32_t v_int_scale_ratio_chroma;
41         struct init_int_and_frac h_init_luma;
42         struct init_int_and_frac h_init_chroma;
43         struct init_int_and_frac v_init_luma;
44         struct init_int_and_frac v_init_chroma;
45 };
46
47 static void calculate_viewport(
48                 const struct scaler_data *scl_data,
49                 struct rect *luma_viewport,
50                 struct rect *chroma_viewport)
51 {
52         /*Do not set chroma vp for rgb444 pixel format*/
53         luma_viewport->x = scl_data->viewport.x - scl_data->viewport.x % 2;
54         luma_viewport->y = scl_data->viewport.y - scl_data->viewport.y % 2;
55         luma_viewport->width =
56                 scl_data->viewport.width - scl_data->viewport.width % 2;
57         luma_viewport->height =
58                 scl_data->viewport.height - scl_data->viewport.height % 2;
59         chroma_viewport->x = luma_viewport->x;
60         chroma_viewport->y = luma_viewport->y;
61         chroma_viewport->height = luma_viewport->height;
62         chroma_viewport->width = luma_viewport->width;
63
64         if (scl_data->format == PIXEL_FORMAT_420BPP8) {
65                 luma_viewport->height += luma_viewport->height % 2;
66                 luma_viewport->width += luma_viewport->width % 2;
67                 /*for 420 video chroma is 1/4 the area of luma, scaled
68                  *vertically and horizontally
69                  */
70                 chroma_viewport->x = luma_viewport->x / 2;
71                 chroma_viewport->y = luma_viewport->y / 2;
72                 chroma_viewport->height = luma_viewport->height / 2;
73                 chroma_viewport->width = luma_viewport->width / 2;
74         }
75 }
76
77 static void program_viewport(
78         struct dce_transform *xfm_dce,
79         struct rect *luma_view_port,
80         struct rect *chroma_view_port)
81 {
82         struct dc_context *ctx = xfm_dce->base.ctx;
83         uint32_t value = 0;
84         uint32_t addr = 0;
85
86         if (luma_view_port->width != 0 && luma_view_port->height != 0) {
87                 addr = mmSCLV_VIEWPORT_START;
88                 value = 0;
89                 set_reg_field_value(
90                         value,
91                         luma_view_port->x,
92                         SCLV_VIEWPORT_START,
93                         VIEWPORT_X_START);
94                 set_reg_field_value(
95                         value,
96                         luma_view_port->y,
97                         SCLV_VIEWPORT_START,
98                         VIEWPORT_Y_START);
99                 dm_write_reg(ctx, addr, value);
100
101                 addr = mmSCLV_VIEWPORT_SIZE;
102                 value = 0;
103                 set_reg_field_value(
104                         value,
105                         luma_view_port->height,
106                         SCLV_VIEWPORT_SIZE,
107                         VIEWPORT_HEIGHT);
108                 set_reg_field_value(
109                         value,
110                         luma_view_port->width,
111                         SCLV_VIEWPORT_SIZE,
112                         VIEWPORT_WIDTH);
113                 dm_write_reg(ctx, addr, value);
114         }
115
116         if (chroma_view_port->width != 0 && chroma_view_port->height != 0) {
117                 addr = mmSCLV_VIEWPORT_START_C;
118                 value = 0;
119                 set_reg_field_value(
120                         value,
121                         chroma_view_port->x,
122                         SCLV_VIEWPORT_START_C,
123                         VIEWPORT_X_START_C);
124                 set_reg_field_value(
125                         value,
126                         chroma_view_port->y,
127                         SCLV_VIEWPORT_START_C,
128                         VIEWPORT_Y_START_C);
129                 dm_write_reg(ctx, addr, value);
130
131                 addr = mmSCLV_VIEWPORT_SIZE_C;
132                 value = 0;
133                 set_reg_field_value(
134                         value,
135                         chroma_view_port->height,
136                         SCLV_VIEWPORT_SIZE_C,
137                         VIEWPORT_HEIGHT_C);
138                 set_reg_field_value(
139                         value,
140                         chroma_view_port->width,
141                         SCLV_VIEWPORT_SIZE_C,
142                         VIEWPORT_WIDTH_C);
143                 dm_write_reg(ctx, addr, value);
144         }
145 }
146
147 /*
148  * Function:
149  * void setup_scaling_configuration
150  *
151  * Purpose: setup scaling mode : bypass, RGb, YCbCr and nummber of taps
152  * Input:   data
153  *
154  * Output:
155  *  void
156  */
157 static bool setup_scaling_configuration(
158         struct dce_transform *xfm_dce,
159         const struct scaler_data *data)
160 {
161         bool is_scaling_needed = false;
162         struct dc_context *ctx = xfm_dce->base.ctx;
163         uint32_t value = 0;
164
165         set_reg_field_value(value, data->taps.h_taps - 1,
166                         SCLV_TAP_CONTROL, SCL_H_NUM_OF_TAPS);
167         set_reg_field_value(value, data->taps.v_taps - 1,
168                         SCLV_TAP_CONTROL, SCL_V_NUM_OF_TAPS);
169         set_reg_field_value(value, data->taps.h_taps_c - 1,
170                         SCLV_TAP_CONTROL, SCL_H_NUM_OF_TAPS_C);
171         set_reg_field_value(value, data->taps.v_taps_c - 1,
172                         SCLV_TAP_CONTROL, SCL_V_NUM_OF_TAPS_C);
173         dm_write_reg(ctx, mmSCLV_TAP_CONTROL, value);
174
175         value = 0;
176         if (data->taps.h_taps + data->taps.v_taps > 2) {
177                 set_reg_field_value(value, 1, SCLV_MODE, SCL_MODE);
178                 set_reg_field_value(value, 1, SCLV_MODE, SCL_PSCL_EN);
179                 is_scaling_needed = true;
180         } else {
181                 set_reg_field_value(value, 0, SCLV_MODE, SCL_MODE);
182                 set_reg_field_value(value, 0, SCLV_MODE, SCL_PSCL_EN);
183         }
184
185         if (data->taps.h_taps_c + data->taps.v_taps_c > 2) {
186                 set_reg_field_value(value, 1, SCLV_MODE, SCL_MODE_C);
187                 set_reg_field_value(value, 1, SCLV_MODE, SCL_PSCL_EN_C);
188                 is_scaling_needed = true;
189         } else if (data->format != PIXEL_FORMAT_420BPP8) {
190                 set_reg_field_value(
191                         value,
192                         get_reg_field_value(value, SCLV_MODE, SCL_MODE),
193                         SCLV_MODE,
194                         SCL_MODE_C);
195                 set_reg_field_value(
196                         value,
197                         get_reg_field_value(value, SCLV_MODE, SCL_PSCL_EN),
198                         SCLV_MODE,
199                         SCL_PSCL_EN_C);
200         } else {
201                 set_reg_field_value(value, 0, SCLV_MODE, SCL_MODE_C);
202                 set_reg_field_value(value, 0, SCLV_MODE, SCL_PSCL_EN_C);
203         }
204         dm_write_reg(ctx, mmSCLV_MODE, value);
205
206         value = 0;
207         /*
208          * 0 - Replaced out of bound pixels with black pixel
209          * (or any other required color)
210          * 1 - Replaced out of bound pixels with the edge pixel
211          */
212         set_reg_field_value(value, 1, SCLV_CONTROL, SCL_BOUNDARY_MODE);
213         dm_write_reg(ctx, mmSCLV_CONTROL, value);
214
215         return is_scaling_needed;
216 }
217
218 /*
219  * Function:
220  * void program_overscan
221  *
222  * Purpose: Programs overscan border
223  * Input:   overscan
224  *
225  * Output: void
226  */
227 static void program_overscan(
228                 struct dce_transform *xfm_dce,
229                 const struct scaler_data *data)
230 {
231         uint32_t overscan_left_right = 0;
232         uint32_t overscan_top_bottom = 0;
233
234         int overscan_right = data->h_active - data->recout.x - data->recout.width;
235         int overscan_bottom = data->v_active - data->recout.y - data->recout.height;
236
237         if (xfm_dce->base.ctx->dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE) {
238                 overscan_bottom += 2;
239                 overscan_right += 2;
240         }
241
242         if (overscan_right < 0) {
243                 BREAK_TO_DEBUGGER();
244                 overscan_right = 0;
245         }
246         if (overscan_bottom < 0) {
247                 BREAK_TO_DEBUGGER();
248                 overscan_bottom = 0;
249         }
250
251         set_reg_field_value(overscan_left_right, data->recout.x,
252                         EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_LEFT);
253
254         set_reg_field_value(overscan_left_right, overscan_right,
255                         EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_RIGHT);
256
257         set_reg_field_value(overscan_top_bottom, data->recout.y,
258                         EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_TOP);
259
260         set_reg_field_value(overscan_top_bottom, overscan_bottom,
261                         EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_BOTTOM);
262
263         dm_write_reg(xfm_dce->base.ctx,
264                         mmSCLV_EXT_OVERSCAN_LEFT_RIGHT,
265                         overscan_left_right);
266
267         dm_write_reg(xfm_dce->base.ctx,
268                         mmSCLV_EXT_OVERSCAN_TOP_BOTTOM,
269                         overscan_top_bottom);
270 }
271
272 static void set_coeff_update_complete(
273                 struct dce_transform *xfm_dce)
274 {
275         uint32_t value;
276
277         value = dm_read_reg(xfm_dce->base.ctx, mmSCLV_UPDATE);
278         set_reg_field_value(value, 1, SCLV_UPDATE, SCL_COEF_UPDATE_COMPLETE);
279         dm_write_reg(xfm_dce->base.ctx, mmSCLV_UPDATE, value);
280 }
281
282 static void program_multi_taps_filter(
283         struct dce_transform *xfm_dce,
284         int taps,
285         const uint16_t *coeffs,
286         enum ram_filter_type filter_type)
287 {
288         struct dc_context *ctx = xfm_dce->base.ctx;
289         int i, phase, pair;
290         int array_idx = 0;
291         int taps_pairs = (taps + 1) / 2;
292         int phases_to_program = SCLV_PHASES / 2 + 1;
293
294         uint32_t select = 0;
295         uint32_t power_ctl, power_ctl_off;
296
297         if (!coeffs)
298                 return;
299
300         /*We need to disable power gating on coeff memory to do programming*/
301         power_ctl = dm_read_reg(ctx, mmDCFEV_MEM_PWR_CTRL);
302         power_ctl_off = power_ctl;
303         set_reg_field_value(power_ctl_off, 1, DCFEV_MEM_PWR_CTRL, SCLV_COEFF_MEM_PWR_DIS);
304         dm_write_reg(ctx, mmDCFEV_MEM_PWR_CTRL, power_ctl_off);
305
306         /*Wait to disable gating:*/
307         for (i = 0; i < 10; i++) {
308                 if (get_reg_field_value(
309                                 dm_read_reg(ctx, mmDCFEV_MEM_PWR_STATUS),
310                                 DCFEV_MEM_PWR_STATUS,
311                                 SCLV_COEFF_MEM_PWR_STATE) == 0)
312                         break;
313
314                 udelay(1);
315         }
316
317         set_reg_field_value(select, filter_type, SCLV_COEF_RAM_SELECT, SCL_C_RAM_FILTER_TYPE);
318
319         for (phase = 0; phase < phases_to_program; phase++) {
320                 /*we always program N/2 + 1 phases, total phases N, but N/2-1 are just mirror
321                 phase 0 is unique and phase N/2 is unique if N is even*/
322                 set_reg_field_value(select, phase, SCLV_COEF_RAM_SELECT, SCL_C_RAM_PHASE);
323                 for (pair = 0; pair < taps_pairs; pair++) {
324                         uint32_t data = 0;
325
326                         set_reg_field_value(select, pair,
327                                         SCLV_COEF_RAM_SELECT, SCL_C_RAM_TAP_PAIR_IDX);
328
329                         dm_write_reg(ctx, mmSCLV_COEF_RAM_SELECT, select);
330
331                         set_reg_field_value(
332                                         data, 1,
333                                         SCLV_COEF_RAM_TAP_DATA,
334                                         SCL_C_RAM_EVEN_TAP_COEF_EN);
335                         set_reg_field_value(
336                                         data, coeffs[array_idx],
337                                         SCLV_COEF_RAM_TAP_DATA,
338                                         SCL_C_RAM_EVEN_TAP_COEF);
339
340                         if (taps % 2 && pair == taps_pairs - 1) {
341                                 set_reg_field_value(
342                                                 data, 0,
343                                                 SCLV_COEF_RAM_TAP_DATA,
344                                                 SCL_C_RAM_ODD_TAP_COEF_EN);
345                                 array_idx++;
346                         } else {
347                                 set_reg_field_value(
348                                                 data, 1,
349                                                 SCLV_COEF_RAM_TAP_DATA,
350                                                 SCL_C_RAM_ODD_TAP_COEF_EN);
351                                 set_reg_field_value(
352                                                 data, coeffs[array_idx + 1],
353                                                 SCLV_COEF_RAM_TAP_DATA,
354                                                 SCL_C_RAM_ODD_TAP_COEF);
355
356                                 array_idx += 2;
357                         }
358
359                         dm_write_reg(ctx, mmSCLV_COEF_RAM_TAP_DATA, data);
360                 }
361         }
362
363         /*We need to restore power gating on coeff memory to initial state*/
364         dm_write_reg(ctx, mmDCFEV_MEM_PWR_CTRL, power_ctl);
365 }
366
367 static void calculate_inits(
368         struct dce_transform *xfm_dce,
369         const struct scaler_data *data,
370         struct sclv_ratios_inits *inits,
371         struct rect *luma_viewport,
372         struct rect *chroma_viewport)
373 {
374         inits->h_int_scale_ratio_luma =
375                 dc_fixpt_u2d19(data->ratios.horz) << 5;
376         inits->v_int_scale_ratio_luma =
377                 dc_fixpt_u2d19(data->ratios.vert) << 5;
378         inits->h_int_scale_ratio_chroma =
379                 dc_fixpt_u2d19(data->ratios.horz_c) << 5;
380         inits->v_int_scale_ratio_chroma =
381                 dc_fixpt_u2d19(data->ratios.vert_c) << 5;
382
383         inits->h_init_luma.integer = 1;
384         inits->v_init_luma.integer = 1;
385         inits->h_init_chroma.integer = 1;
386         inits->v_init_chroma.integer = 1;
387 }
388
389 static void program_scl_ratios_inits(
390         struct dce_transform *xfm_dce,
391         struct sclv_ratios_inits *inits)
392 {
393         struct dc_context *ctx = xfm_dce->base.ctx;
394         uint32_t addr = mmSCLV_HORZ_FILTER_SCALE_RATIO;
395         uint32_t value = 0;
396
397         set_reg_field_value(
398                 value,
399                 inits->h_int_scale_ratio_luma,
400                 SCLV_HORZ_FILTER_SCALE_RATIO,
401                 SCL_H_SCALE_RATIO);
402         dm_write_reg(ctx, addr, value);
403
404         addr = mmSCLV_VERT_FILTER_SCALE_RATIO;
405         value = 0;
406         set_reg_field_value(
407                 value,
408                 inits->v_int_scale_ratio_luma,
409                 SCLV_VERT_FILTER_SCALE_RATIO,
410                 SCL_V_SCALE_RATIO);
411         dm_write_reg(ctx, addr, value);
412
413         addr = mmSCLV_HORZ_FILTER_SCALE_RATIO_C;
414         value = 0;
415         set_reg_field_value(
416                 value,
417                 inits->h_int_scale_ratio_chroma,
418                 SCLV_HORZ_FILTER_SCALE_RATIO_C,
419                 SCL_H_SCALE_RATIO_C);
420         dm_write_reg(ctx, addr, value);
421
422         addr = mmSCLV_VERT_FILTER_SCALE_RATIO_C;
423         value = 0;
424         set_reg_field_value(
425                 value,
426                 inits->v_int_scale_ratio_chroma,
427                 SCLV_VERT_FILTER_SCALE_RATIO_C,
428                 SCL_V_SCALE_RATIO_C);
429         dm_write_reg(ctx, addr, value);
430
431         addr = mmSCLV_HORZ_FILTER_INIT;
432         value = 0;
433         set_reg_field_value(
434                 value,
435                 inits->h_init_luma.fraction,
436                 SCLV_HORZ_FILTER_INIT,
437                 SCL_H_INIT_FRAC);
438         set_reg_field_value(
439                 value,
440                 inits->h_init_luma.integer,
441                 SCLV_HORZ_FILTER_INIT,
442                 SCL_H_INIT_INT);
443         dm_write_reg(ctx, addr, value);
444
445         addr = mmSCLV_VERT_FILTER_INIT;
446         value = 0;
447         set_reg_field_value(
448                 value,
449                 inits->v_init_luma.fraction,
450                 SCLV_VERT_FILTER_INIT,
451                 SCL_V_INIT_FRAC);
452         set_reg_field_value(
453                 value,
454                 inits->v_init_luma.integer,
455                 SCLV_VERT_FILTER_INIT,
456                 SCL_V_INIT_INT);
457         dm_write_reg(ctx, addr, value);
458
459         addr = mmSCLV_HORZ_FILTER_INIT_C;
460         value = 0;
461         set_reg_field_value(
462                 value,
463                 inits->h_init_chroma.fraction,
464                 SCLV_HORZ_FILTER_INIT_C,
465                 SCL_H_INIT_FRAC_C);
466         set_reg_field_value(
467                 value,
468                 inits->h_init_chroma.integer,
469                 SCLV_HORZ_FILTER_INIT_C,
470                 SCL_H_INIT_INT_C);
471         dm_write_reg(ctx, addr, value);
472
473         addr = mmSCLV_VERT_FILTER_INIT_C;
474         value = 0;
475         set_reg_field_value(
476                 value,
477                 inits->v_init_chroma.fraction,
478                 SCLV_VERT_FILTER_INIT_C,
479                 SCL_V_INIT_FRAC_C);
480         set_reg_field_value(
481                 value,
482                 inits->v_init_chroma.integer,
483                 SCLV_VERT_FILTER_INIT_C,
484                 SCL_V_INIT_INT_C);
485         dm_write_reg(ctx, addr, value);
486 }
487
488 static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
489 {
490         if (taps == 4)
491                 return get_filter_4tap_64p(ratio);
492         else if (taps == 2)
493                 return get_filter_2tap_64p();
494         else if (taps == 1)
495                 return NULL;
496         else {
497                 /* should never happen, bug */
498                 BREAK_TO_DEBUGGER();
499                 return NULL;
500         }
501 }
502
503 static bool dce110_xfmv_power_up_line_buffer(struct transform *xfm)
504 {
505         struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
506         uint32_t value;
507
508         value = dm_read_reg(xfm_dce->base.ctx, mmLBV_MEMORY_CTRL);
509
510         /*Use all three pieces of memory always*/
511         set_reg_field_value(value, 0, LBV_MEMORY_CTRL, LB_MEMORY_CONFIG);
512         /*hard coded number DCE11 1712(0x6B0) Partitions: 720/960/1712*/
513         set_reg_field_value(value, xfm_dce->lb_memory_size, LBV_MEMORY_CTRL,
514                         LB_MEMORY_SIZE);
515
516         dm_write_reg(xfm_dce->base.ctx, mmLBV_MEMORY_CTRL, value);
517
518         return true;
519 }
520
521 static void dce110_xfmv_set_scaler(
522         struct transform *xfm,
523         const struct scaler_data *data)
524 {
525         struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
526         bool is_scaling_required = false;
527         bool filter_updated = false;
528         const uint16_t *coeffs_v, *coeffs_h, *coeffs_h_c, *coeffs_v_c;
529         struct rect luma_viewport = {0};
530         struct rect chroma_viewport = {0};
531
532         dce110_xfmv_power_up_line_buffer(xfm);
533         /* 1. Calculate viewport, viewport programming should happen after init
534          * calculations as they may require an adjustment in the viewport.
535          */
536
537         calculate_viewport(data, &luma_viewport, &chroma_viewport);
538
539         /* 2. Program overscan */
540         program_overscan(xfm_dce, data);
541
542         /* 3. Program taps and configuration */
543         is_scaling_required = setup_scaling_configuration(xfm_dce, data);
544
545         if (is_scaling_required) {
546                 /* 4. Calculate and program ratio, filter initialization */
547
548                 struct sclv_ratios_inits inits = { 0 };
549
550                 calculate_inits(
551                         xfm_dce,
552                         data,
553                         &inits,
554                         &luma_viewport,
555                         &chroma_viewport);
556
557                 program_scl_ratios_inits(xfm_dce, &inits);
558
559                 coeffs_v = get_filter_coeffs_64p(data->taps.v_taps, data->ratios.vert);
560                 coeffs_h = get_filter_coeffs_64p(data->taps.h_taps, data->ratios.horz);
561                 coeffs_v_c = get_filter_coeffs_64p(data->taps.v_taps_c, data->ratios.vert_c);
562                 coeffs_h_c = get_filter_coeffs_64p(data->taps.h_taps_c, data->ratios.horz_c);
563
564                 if (coeffs_v != xfm_dce->filter_v
565                                 || coeffs_v_c != xfm_dce->filter_v_c
566                                 || coeffs_h != xfm_dce->filter_h
567                                 || coeffs_h_c != xfm_dce->filter_h_c) {
568                 /* 5. Program vertical filters */
569                         program_multi_taps_filter(
570                                         xfm_dce,
571                                         data->taps.v_taps,
572                                         coeffs_v,
573                                         FILTER_TYPE_RGB_Y_VERTICAL);
574                         program_multi_taps_filter(
575                                         xfm_dce,
576                                         data->taps.v_taps_c,
577                                         coeffs_v_c,
578                                         FILTER_TYPE_CBCR_VERTICAL);
579
580                 /* 6. Program horizontal filters */
581                         program_multi_taps_filter(
582                                         xfm_dce,
583                                         data->taps.h_taps,
584                                         coeffs_h,
585                                         FILTER_TYPE_RGB_Y_HORIZONTAL);
586                         program_multi_taps_filter(
587                                         xfm_dce,
588                                         data->taps.h_taps_c,
589                                         coeffs_h_c,
590                                         FILTER_TYPE_CBCR_HORIZONTAL);
591
592                         xfm_dce->filter_v = coeffs_v;
593                         xfm_dce->filter_v_c = coeffs_v_c;
594                         xfm_dce->filter_h = coeffs_h;
595                         xfm_dce->filter_h_c = coeffs_h_c;
596                         filter_updated = true;
597                 }
598         }
599
600         /* 7. Program the viewport */
601         program_viewport(xfm_dce, &luma_viewport, &chroma_viewport);
602
603         /* 8. Set bit to flip to new coefficient memory */
604         if (filter_updated)
605                 set_coeff_update_complete(xfm_dce);
606 }
607
608 static void dce110_xfmv_reset(struct transform *xfm)
609 {
610         struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
611
612         xfm_dce->filter_h = NULL;
613         xfm_dce->filter_v = NULL;
614         xfm_dce->filter_h_c = NULL;
615         xfm_dce->filter_v_c = NULL;
616 }
617
618 static void dce110_xfmv_set_gamut_remap(
619         struct transform *xfm,
620         const struct xfm_grph_csc_adjustment *adjust)
621 {
622         /* DO NOTHING*/
623 }
624
625 static void dce110_xfmv_set_pixel_storage_depth(
626         struct transform *xfm,
627         enum lb_pixel_depth depth,
628         const struct bit_depth_reduction_params *bit_depth_params)
629 {
630         struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
631         int pixel_depth = 0;
632         int expan_mode = 0;
633         uint32_t reg_data = 0;
634
635         switch (depth) {
636         case LB_PIXEL_DEPTH_18BPP:
637                 pixel_depth = 2;
638                 expan_mode  = 1;
639                 break;
640         case LB_PIXEL_DEPTH_24BPP:
641                 pixel_depth = 1;
642                 expan_mode  = 1;
643                 break;
644         case LB_PIXEL_DEPTH_30BPP:
645                 pixel_depth = 0;
646                 expan_mode  = 1;
647                 break;
648         case LB_PIXEL_DEPTH_36BPP:
649                 pixel_depth = 3;
650                 expan_mode  = 0;
651                 break;
652         default:
653                 BREAK_TO_DEBUGGER();
654                 break;
655         }
656
657         set_reg_field_value(
658                 reg_data,
659                 expan_mode,
660                 LBV_DATA_FORMAT,
661                 PIXEL_EXPAN_MODE);
662
663         set_reg_field_value(
664                 reg_data,
665                 pixel_depth,
666                 LBV_DATA_FORMAT,
667                 PIXEL_DEPTH);
668
669         dm_write_reg(xfm->ctx, mmLBV_DATA_FORMAT, reg_data);
670
671         if (!(xfm_dce->lb_pixel_depth_supported & depth)) {
672                 /*we should use unsupported capabilities
673                  *  unless it is required by w/a*/
674                 DC_LOG_WARNING("%s: Capability not supported",
675                         __func__);
676         }
677 }
678
679 static const struct transform_funcs dce110_xfmv_funcs = {
680         .transform_reset = dce110_xfmv_reset,
681         .transform_set_scaler = dce110_xfmv_set_scaler,
682         .transform_set_gamut_remap =
683                 dce110_xfmv_set_gamut_remap,
684         .opp_set_csc_default = dce110_opp_v_set_csc_default,
685         .opp_set_csc_adjustment = dce110_opp_v_set_csc_adjustment,
686         .opp_power_on_regamma_lut = dce110_opp_power_on_regamma_lut_v,
687         .opp_program_regamma_pwl = dce110_opp_program_regamma_pwl_v,
688         .opp_set_regamma_mode = dce110_opp_set_regamma_mode_v,
689         .transform_set_pixel_storage_depth =
690                         dce110_xfmv_set_pixel_storage_depth,
691         .transform_get_optimal_number_of_taps =
692                 dce_transform_get_optimal_number_of_taps
693 };
694 /*****************************************/
695 /* Constructor, Destructor               */
696 /*****************************************/
697
698 bool dce110_transform_v_construct(
699         struct dce_transform *xfm_dce,
700         struct dc_context *ctx)
701 {
702         xfm_dce->base.ctx = ctx;
703
704         xfm_dce->base.funcs = &dce110_xfmv_funcs;
705
706         xfm_dce->lb_pixel_depth_supported =
707                         LB_PIXEL_DEPTH_18BPP |
708                         LB_PIXEL_DEPTH_24BPP |
709                         LB_PIXEL_DEPTH_30BPP |
710                         LB_PIXEL_DEPTH_36BPP;
711
712         xfm_dce->prescaler_on = true;
713         xfm_dce->lb_bits_per_entry = LB_BITS_PER_ENTRY;
714         xfm_dce->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x6B0*/
715
716         return true;
717 }