hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
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,
....@@ -778,7 +1011,7 @@
7781011 color_depth = COLOR_DEPTH_101010;
7791012 pixel_depth = 0;
7801013 expan_mode = 1;
781
- BREAK_TO_DEBUGGER();
1014
+ DC_LOG_DC("The pixel depth %d is not valid, set COLOR_DEPTH_101010 instead.", depth);
7821015 break;
7831016 }
7841017
....@@ -792,10 +1025,62 @@
7921025 if (!(xfm_dce->lb_pixel_depth_supported & depth)) {
7931026 /*we should use unsupported capabilities
7941027 * unless it is required by w/a*/
1028
+ DC_LOG_DC("%s: Capability not supported", __func__);
1029
+ }
1030
+}
1031
+
1032
+#if defined(CONFIG_DRM_AMD_DC_SI)
1033
+static void dce60_transform_set_pixel_storage_depth(
1034
+ struct transform *xfm,
1035
+ enum lb_pixel_depth depth,
1036
+ const struct bit_depth_reduction_params *bit_depth_params)
1037
+{
1038
+ struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
1039
+ int pixel_depth, expan_mode;
1040
+ enum dc_color_depth color_depth;
1041
+
1042
+ switch (depth) {
1043
+ case LB_PIXEL_DEPTH_18BPP:
1044
+ color_depth = COLOR_DEPTH_666;
1045
+ pixel_depth = 2;
1046
+ expan_mode = 1;
1047
+ break;
1048
+ case LB_PIXEL_DEPTH_24BPP:
1049
+ color_depth = COLOR_DEPTH_888;
1050
+ pixel_depth = 1;
1051
+ expan_mode = 1;
1052
+ break;
1053
+ case LB_PIXEL_DEPTH_30BPP:
1054
+ color_depth = COLOR_DEPTH_101010;
1055
+ pixel_depth = 0;
1056
+ expan_mode = 1;
1057
+ break;
1058
+ case LB_PIXEL_DEPTH_36BPP:
1059
+ color_depth = COLOR_DEPTH_121212;
1060
+ pixel_depth = 3;
1061
+ expan_mode = 0;
1062
+ break;
1063
+ default:
1064
+ color_depth = COLOR_DEPTH_101010;
1065
+ pixel_depth = 0;
1066
+ expan_mode = 1;
1067
+ BREAK_TO_DEBUGGER();
1068
+ break;
1069
+ }
1070
+
1071
+ set_denormalization(xfm_dce, color_depth);
1072
+ dce60_program_bit_depth_reduction(xfm_dce, color_depth, bit_depth_params);
1073
+
1074
+ /* DATA_FORMAT in DCE6 does not have PIXEL_DEPTH and PIXEL_EXPAN_MODE masks */
1075
+
1076
+ if (!(xfm_dce->lb_pixel_depth_supported & depth)) {
1077
+ /*we should use unsupported capabilities
1078
+ * unless it is required by w/a*/
7951079 DC_LOG_WARNING("%s: Capability not supported",
7961080 __func__);
7971081 }
7981082 }
1083
+#endif
7991084
8001085 static void program_gamut_remap(
8011086 struct dce_transform *xfm_dce,
....@@ -1335,6 +1620,21 @@
13351620 .transform_get_optimal_number_of_taps = dce_transform_get_optimal_number_of_taps
13361621 };
13371622
1623
+#if defined(CONFIG_DRM_AMD_DC_SI)
1624
+static const struct transform_funcs dce60_transform_funcs = {
1625
+ .transform_reset = dce_transform_reset,
1626
+ .transform_set_scaler = dce60_transform_set_scaler,
1627
+ .transform_set_gamut_remap = dce_transform_set_gamut_remap,
1628
+ .opp_set_csc_adjustment = dce110_opp_set_csc_adjustment,
1629
+ .opp_set_csc_default = dce110_opp_set_csc_default,
1630
+ .opp_power_on_regamma_lut = dce110_opp_power_on_regamma_lut,
1631
+ .opp_program_regamma_pwl = dce110_opp_program_regamma_pwl,
1632
+ .opp_set_regamma_mode = dce110_opp_set_regamma_mode,
1633
+ .transform_set_pixel_storage_depth = dce60_transform_set_pixel_storage_depth,
1634
+ .transform_get_optimal_number_of_taps = dce_transform_get_optimal_number_of_taps
1635
+};
1636
+#endif
1637
+
13381638 /*****************************************/
13391639 /* Constructor, Destructor */
13401640 /*****************************************/
....@@ -1365,3 +1665,32 @@
13651665 xfm_dce->lb_bits_per_entry = LB_BITS_PER_ENTRY;
13661666 xfm_dce->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x6B0*/
13671667 }
1668
+
1669
+#if defined(CONFIG_DRM_AMD_DC_SI)
1670
+void dce60_transform_construct(
1671
+ struct dce_transform *xfm_dce,
1672
+ struct dc_context *ctx,
1673
+ uint32_t inst,
1674
+ const struct dce_transform_registers *regs,
1675
+ const struct dce_transform_shift *xfm_shift,
1676
+ const struct dce_transform_mask *xfm_mask)
1677
+{
1678
+ xfm_dce->base.ctx = ctx;
1679
+
1680
+ xfm_dce->base.inst = inst;
1681
+ xfm_dce->base.funcs = &dce60_transform_funcs;
1682
+
1683
+ xfm_dce->regs = regs;
1684
+ xfm_dce->xfm_shift = xfm_shift;
1685
+ xfm_dce->xfm_mask = xfm_mask;
1686
+
1687
+ xfm_dce->prescaler_on = true;
1688
+ xfm_dce->lb_pixel_depth_supported =
1689
+ LB_PIXEL_DEPTH_18BPP |
1690
+ LB_PIXEL_DEPTH_24BPP |
1691
+ LB_PIXEL_DEPTH_30BPP;
1692
+
1693
+ xfm_dce->lb_bits_per_entry = LB_BITS_PER_ENTRY;
1694
+ xfm_dce->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x6B0*/
1695
+}
1696
+#endif