forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c
....@@ -146,6 +146,33 @@
146146 return true;
147147 }
148148
149
+#if defined(CONFIG_DRM_AMD_DC_SI)
150
+static bool dce60_setup_scaling_configuration(
151
+ struct dce_transform *xfm_dce,
152
+ const struct scaler_data *data)
153
+{
154
+ REG_SET(SCL_BYPASS_CONTROL, 0, SCL_BYPASS_MODE, 0);
155
+
156
+ if (data->taps.h_taps + data->taps.v_taps <= 2) {
157
+ /* Set bypass */
158
+
159
+ /* DCE6 has no SCL_MODE register, skip scale mode programming */
160
+
161
+ return false;
162
+ }
163
+
164
+ REG_SET_2(SCL_TAP_CONTROL, 0,
165
+ SCL_H_NUM_OF_TAPS, data->taps.h_taps - 1,
166
+ SCL_V_NUM_OF_TAPS, data->taps.v_taps - 1);
167
+
168
+ /* DCE6 has no SCL_MODE register, skip scale mode programming */
169
+
170
+ /* DCE6 has no SCL_BOUNDARY_MODE bit, skip replace out of bound pixels */
171
+
172
+ return true;
173
+}
174
+#endif
175
+
149176 static void program_overscan(
150177 struct dce_transform *xfm_dce,
151178 const struct scaler_data *data)
....@@ -279,6 +306,36 @@
279306 inits->v_init.fraction = dc_fixpt_u0d19(v_init) << 5;
280307 }
281308
309
+#if defined(CONFIG_DRM_AMD_DC_SI)
310
+static void dce60_calculate_inits(
311
+ struct dce_transform *xfm_dce,
312
+ const struct scaler_data *data,
313
+ struct sclh_ratios_inits *inits)
314
+{
315
+ struct fixed31_32 v_init;
316
+
317
+ inits->h_int_scale_ratio =
318
+ dc_fixpt_u2d19(data->ratios.horz) << 5;
319
+ inits->v_int_scale_ratio =
320
+ dc_fixpt_u2d19(data->ratios.vert) << 5;
321
+
322
+ /* DCE6 h_init_luma setting inspired by DCE110 */
323
+ inits->h_init_luma.integer = 1;
324
+
325
+ /* DCE6 h_init_chroma setting inspired by DCE110 */
326
+ inits->h_init_chroma.integer = 1;
327
+
328
+ v_init =
329
+ dc_fixpt_div_int(
330
+ dc_fixpt_add(
331
+ data->ratios.vert,
332
+ dc_fixpt_from_int(data->taps.v_taps + 1)),
333
+ 2);
334
+ inits->v_init.integer = dc_fixpt_floor(v_init);
335
+ inits->v_init.fraction = dc_fixpt_u0d19(v_init) << 5;
336
+}
337
+#endif
338
+
282339 static void program_scl_ratios_inits(
283340 struct dce_transform *xfm_dce,
284341 struct scl_ratios_inits *inits)
....@@ -300,6 +357,36 @@
300357
301358 REG_WRITE(SCL_AUTOMATIC_MODE_CONTROL, 0);
302359 }
360
+
361
+#if defined(CONFIG_DRM_AMD_DC_SI)
362
+static void dce60_program_scl_ratios_inits(
363
+ struct dce_transform *xfm_dce,
364
+ struct sclh_ratios_inits *inits)
365
+{
366
+
367
+ REG_SET(SCL_HORZ_FILTER_SCALE_RATIO, 0,
368
+ SCL_H_SCALE_RATIO, inits->h_int_scale_ratio);
369
+
370
+ REG_SET(SCL_VERT_FILTER_SCALE_RATIO, 0,
371
+ SCL_V_SCALE_RATIO, inits->v_int_scale_ratio);
372
+
373
+ /* DCE6 has SCL_HORZ_FILTER_INIT_RGB_LUMA register */
374
+ REG_SET_2(SCL_HORZ_FILTER_INIT_RGB_LUMA, 0,
375
+ SCL_H_INIT_INT_RGB_Y, inits->h_init_luma.integer,
376
+ SCL_H_INIT_FRAC_RGB_Y, inits->h_init_luma.fraction);
377
+
378
+ /* DCE6 has SCL_HORZ_FILTER_INIT_CHROMA register */
379
+ REG_SET_2(SCL_HORZ_FILTER_INIT_CHROMA, 0,
380
+ SCL_H_INIT_INT_CBCR, inits->h_init_chroma.integer,
381
+ SCL_H_INIT_FRAC_CBCR, inits->h_init_chroma.fraction);
382
+
383
+ REG_SET_2(SCL_VERT_FILTER_INIT, 0,
384
+ SCL_V_INIT_INT, inits->v_init.integer,
385
+ SCL_V_INIT_FRAC, inits->v_init.fraction);
386
+
387
+ REG_WRITE(SCL_AUTOMATIC_MODE_CONTROL, 0);
388
+}
389
+#endif
303390
304391 static const uint16_t *get_filter_coeffs_16p(int taps, struct fixed31_32 ratio)
305392 {
....@@ -398,6 +485,91 @@
398485
399486 REG_UPDATE(LB_DATA_FORMAT, ALPHA_EN, data->lb_params.alpha_en);
400487 }
488
+
489
+#if defined(CONFIG_DRM_AMD_DC_SI)
490
+static void dce60_transform_set_scaler(
491
+ struct transform *xfm,
492
+ const struct scaler_data *data)
493
+{
494
+ struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
495
+ bool is_scaling_required;
496
+ bool filter_updated = false;
497
+ const uint16_t *coeffs_v, *coeffs_h;
498
+
499
+ /*Use whole line buffer memory always*/
500
+ REG_SET(DC_LB_MEMORY_SPLIT, 0,
501
+ DC_LB_MEMORY_CONFIG, 0);
502
+
503
+ REG_SET(DC_LB_MEM_SIZE, 0,
504
+ DC_LB_MEM_SIZE, xfm_dce->lb_memory_size);
505
+
506
+ /* Clear SCL_F_SHARP_CONTROL value to 0 */
507
+ REG_WRITE(SCL_F_SHARP_CONTROL, 0);
508
+
509
+ /* 1. Program overscan */
510
+ program_overscan(xfm_dce, data);
511
+
512
+ /* 2. Program taps and configuration */
513
+ is_scaling_required = dce60_setup_scaling_configuration(xfm_dce, data);
514
+
515
+ if (is_scaling_required) {
516
+ /* 3. Calculate and program ratio, DCE6 filter initialization */
517
+ struct sclh_ratios_inits inits = { 0 };
518
+
519
+ /* DCE6 has specific calculate_inits() function */
520
+ dce60_calculate_inits(xfm_dce, data, &inits);
521
+
522
+ /* DCE6 has specific program_scl_ratios_inits() function */
523
+ dce60_program_scl_ratios_inits(xfm_dce, &inits);
524
+
525
+ coeffs_v = get_filter_coeffs_16p(data->taps.v_taps, data->ratios.vert);
526
+ coeffs_h = get_filter_coeffs_16p(data->taps.h_taps, data->ratios.horz);
527
+
528
+ if (coeffs_v != xfm_dce->filter_v || coeffs_h != xfm_dce->filter_h) {
529
+ /* 4. Program vertical filters */
530
+ if (xfm_dce->filter_v == NULL)
531
+ REG_SET(SCL_VERT_FILTER_CONTROL, 0,
532
+ SCL_V_2TAP_HARDCODE_COEF_EN, 0);
533
+ program_multi_taps_filter(
534
+ xfm_dce,
535
+ data->taps.v_taps,
536
+ coeffs_v,
537
+ FILTER_TYPE_RGB_Y_VERTICAL);
538
+ program_multi_taps_filter(
539
+ xfm_dce,
540
+ data->taps.v_taps,
541
+ coeffs_v,
542
+ FILTER_TYPE_ALPHA_VERTICAL);
543
+
544
+ /* 5. Program horizontal filters */
545
+ if (xfm_dce->filter_h == NULL)
546
+ REG_SET(SCL_HORZ_FILTER_CONTROL, 0,
547
+ SCL_H_2TAP_HARDCODE_COEF_EN, 0);
548
+ program_multi_taps_filter(
549
+ xfm_dce,
550
+ data->taps.h_taps,
551
+ coeffs_h,
552
+ FILTER_TYPE_RGB_Y_HORIZONTAL);
553
+ program_multi_taps_filter(
554
+ xfm_dce,
555
+ data->taps.h_taps,
556
+ coeffs_h,
557
+ FILTER_TYPE_ALPHA_HORIZONTAL);
558
+
559
+ xfm_dce->filter_v = coeffs_v;
560
+ xfm_dce->filter_h = coeffs_h;
561
+ filter_updated = true;
562
+ }
563
+ }
564
+
565
+ /* 6. Program the viewport */
566
+ program_viewport(xfm_dce, &data->viewport);
567
+
568
+ /* DCE6 has no SCL_COEF_UPDATE_COMPLETE bit to flip to new coefficient memory */
569
+
570
+ /* DCE6 DATA_FORMAT register does not support ALPHA_EN */
571
+}
572
+#endif
401573
402574 /*****************************************************************************
403575 * set_clamp
....@@ -664,6 +836,67 @@
664836 bit_depth_params->flags.HIGHPASS_RANDOM);
665837 }
666838
839
+#if defined(CONFIG_DRM_AMD_DC_SI)
840
+/*****************************************************************************
841
+ * dce60_transform_bit_depth_reduction program
842
+ *
843
+ * @brief
844
+ * Programs the DCP bit depth reduction registers (Clamp, Round/Truncate,
845
+ * Dither) for dce
846
+ *
847
+ * @param depth : bit depth to set the clamp to (should match denorm)
848
+ *
849
+ ******************************************************************************/
850
+static void dce60_program_bit_depth_reduction(
851
+ struct dce_transform *xfm_dce,
852
+ enum dc_color_depth depth,
853
+ const struct bit_depth_reduction_params *bit_depth_params)
854
+{
855
+ enum dcp_out_trunc_round_depth trunc_round_depth;
856
+ enum dcp_out_trunc_round_mode trunc_mode;
857
+ bool spatial_dither_enable;
858
+
859
+ ASSERT(depth < COLOR_DEPTH_121212); /* Invalid clamp bit depth */
860
+
861
+ spatial_dither_enable = bit_depth_params->flags.SPATIAL_DITHER_ENABLED;
862
+ /* Default to 12 bit truncation without rounding */
863
+ trunc_round_depth = DCP_OUT_TRUNC_ROUND_DEPTH_12BIT;
864
+ trunc_mode = DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE;
865
+
866
+ if (bit_depth_params->flags.TRUNCATE_ENABLED) {
867
+ /* Don't enable dithering if truncation is enabled */
868
+ spatial_dither_enable = false;
869
+ trunc_mode = bit_depth_params->flags.TRUNCATE_MODE ?
870
+ DCP_OUT_TRUNC_ROUND_MODE_ROUND :
871
+ DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE;
872
+
873
+ if (bit_depth_params->flags.TRUNCATE_DEPTH == 0 ||
874
+ bit_depth_params->flags.TRUNCATE_DEPTH == 1)
875
+ trunc_round_depth = DCP_OUT_TRUNC_ROUND_DEPTH_8BIT;
876
+ else if (bit_depth_params->flags.TRUNCATE_DEPTH == 2)
877
+ trunc_round_depth = DCP_OUT_TRUNC_ROUND_DEPTH_10BIT;
878
+ else {
879
+ /*
880
+ * Invalid truncate/round depth. Setting here to 12bit
881
+ * to prevent use-before-initialize errors.
882
+ */
883
+ trunc_round_depth = DCP_OUT_TRUNC_ROUND_DEPTH_12BIT;
884
+ BREAK_TO_DEBUGGER();
885
+ }
886
+ }
887
+
888
+ /* DCE6 has no OUT_CLAMP_CONTROL_* registers - set_clamp() is skipped */
889
+ set_round(xfm_dce, trunc_mode, trunc_round_depth);
890
+ set_dither(xfm_dce,
891
+ spatial_dither_enable,
892
+ DCP_SPATIAL_DITHER_MODE_A_AA_A,
893
+ DCP_SPATIAL_DITHER_DEPTH_30BPP,
894
+ bit_depth_params->flags.FRAME_RANDOM,
895
+ bit_depth_params->flags.RGB_RANDOM,
896
+ bit_depth_params->flags.HIGHPASS_RANDOM);
897
+}
898
+#endif
899
+
667900 static int dce_transform_get_max_num_of_supported_lines(
668901 struct dce_transform *xfm_dce,
669902 enum lb_pixel_depth depth,
....@@ -796,6 +1029,59 @@
7961029 __func__);
7971030 }
7981031 }
1032
+
1033
+#if defined(CONFIG_DRM_AMD_DC_SI)
1034
+static void dce60_transform_set_pixel_storage_depth(
1035
+ struct transform *xfm,
1036
+ enum lb_pixel_depth depth,
1037
+ const struct bit_depth_reduction_params *bit_depth_params)
1038
+{
1039
+ struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
1040
+ int pixel_depth, expan_mode;
1041
+ enum dc_color_depth color_depth;
1042
+
1043
+ switch (depth) {
1044
+ case LB_PIXEL_DEPTH_18BPP:
1045
+ color_depth = COLOR_DEPTH_666;
1046
+ pixel_depth = 2;
1047
+ expan_mode = 1;
1048
+ break;
1049
+ case LB_PIXEL_DEPTH_24BPP:
1050
+ color_depth = COLOR_DEPTH_888;
1051
+ pixel_depth = 1;
1052
+ expan_mode = 1;
1053
+ break;
1054
+ case LB_PIXEL_DEPTH_30BPP:
1055
+ color_depth = COLOR_DEPTH_101010;
1056
+ pixel_depth = 0;
1057
+ expan_mode = 1;
1058
+ break;
1059
+ case LB_PIXEL_DEPTH_36BPP:
1060
+ color_depth = COLOR_DEPTH_121212;
1061
+ pixel_depth = 3;
1062
+ expan_mode = 0;
1063
+ break;
1064
+ default:
1065
+ color_depth = COLOR_DEPTH_101010;
1066
+ pixel_depth = 0;
1067
+ expan_mode = 1;
1068
+ BREAK_TO_DEBUGGER();
1069
+ break;
1070
+ }
1071
+
1072
+ set_denormalization(xfm_dce, color_depth);
1073
+ dce60_program_bit_depth_reduction(xfm_dce, color_depth, bit_depth_params);
1074
+
1075
+ /* DATA_FORMAT in DCE6 does not have PIXEL_DEPTH and PIXEL_EXPAN_MODE masks */
1076
+
1077
+ if (!(xfm_dce->lb_pixel_depth_supported & depth)) {
1078
+ /*we should use unsupported capabilities
1079
+ * unless it is required by w/a*/
1080
+ DC_LOG_WARNING("%s: Capability not supported",
1081
+ __func__);
1082
+ }
1083
+}
1084
+#endif
7991085
8001086 static void program_gamut_remap(
8011087 struct dce_transform *xfm_dce,
....@@ -1335,6 +1621,21 @@
13351621 .transform_get_optimal_number_of_taps = dce_transform_get_optimal_number_of_taps
13361622 };
13371623
1624
+#if defined(CONFIG_DRM_AMD_DC_SI)
1625
+static const struct transform_funcs dce60_transform_funcs = {
1626
+ .transform_reset = dce_transform_reset,
1627
+ .transform_set_scaler = dce60_transform_set_scaler,
1628
+ .transform_set_gamut_remap = dce_transform_set_gamut_remap,
1629
+ .opp_set_csc_adjustment = dce110_opp_set_csc_adjustment,
1630
+ .opp_set_csc_default = dce110_opp_set_csc_default,
1631
+ .opp_power_on_regamma_lut = dce110_opp_power_on_regamma_lut,
1632
+ .opp_program_regamma_pwl = dce110_opp_program_regamma_pwl,
1633
+ .opp_set_regamma_mode = dce110_opp_set_regamma_mode,
1634
+ .transform_set_pixel_storage_depth = dce60_transform_set_pixel_storage_depth,
1635
+ .transform_get_optimal_number_of_taps = dce_transform_get_optimal_number_of_taps
1636
+};
1637
+#endif
1638
+
13381639 /*****************************************/
13391640 /* Constructor, Destructor */
13401641 /*****************************************/
....@@ -1365,3 +1666,32 @@
13651666 xfm_dce->lb_bits_per_entry = LB_BITS_PER_ENTRY;
13661667 xfm_dce->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x6B0*/
13671668 }
1669
+
1670
+#if defined(CONFIG_DRM_AMD_DC_SI)
1671
+void dce60_transform_construct(
1672
+ struct dce_transform *xfm_dce,
1673
+ struct dc_context *ctx,
1674
+ uint32_t inst,
1675
+ const struct dce_transform_registers *regs,
1676
+ const struct dce_transform_shift *xfm_shift,
1677
+ const struct dce_transform_mask *xfm_mask)
1678
+{
1679
+ xfm_dce->base.ctx = ctx;
1680
+
1681
+ xfm_dce->base.inst = inst;
1682
+ xfm_dce->base.funcs = &dce60_transform_funcs;
1683
+
1684
+ xfm_dce->regs = regs;
1685
+ xfm_dce->xfm_shift = xfm_shift;
1686
+ xfm_dce->xfm_mask = xfm_mask;
1687
+
1688
+ xfm_dce->prescaler_on = true;
1689
+ xfm_dce->lb_pixel_depth_supported =
1690
+ LB_PIXEL_DEPTH_18BPP |
1691
+ LB_PIXEL_DEPTH_24BPP |
1692
+ LB_PIXEL_DEPTH_30BPP;
1693
+
1694
+ xfm_dce->lb_bits_per_entry = LB_BITS_PER_ENTRY;
1695
+ xfm_dce->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x6B0*/
1696
+}
1697
+#endif