summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc/dcn10
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn10')
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c192
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c22
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h35
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c56
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c77
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c39
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h25
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c600
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h14
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h14
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c28
16 files changed, 800 insertions, 320 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
index 53ba3600ee6a..881a1bff94d2 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
@@ -232,10 +232,11 @@ bool cm_helper_convert_to_custom_float(
return true;
}
-
+/* driver uses 32 regions or less, but DCN HW has 34, extra 2 are set to 0 */
#define MAX_REGIONS_NUMBER 34
#define MAX_LOW_POINT 25
-#define NUMBER_SEGMENTS 32
+#define NUMBER_REGIONS 32
+#define NUMBER_SW_SEGMENTS 16
bool cm_helper_translate_curve_to_hw_format(
const struct dc_transfer_func *output_tf,
@@ -251,7 +252,7 @@ bool cm_helper_translate_curve_to_hw_format(
struct fixed31_32 y1_min;
struct fixed31_32 y3_max;
- int32_t segment_start, segment_end;
+ int32_t region_start, region_end;
int32_t i;
uint32_t j, k, seg_distr[MAX_REGIONS_NUMBER], increment, start_index, hw_points;
@@ -271,11 +272,11 @@ bool cm_helper_translate_curve_to_hw_format(
/* 32 segments
* segments are from 2^-25 to 2^7
*/
- for (i = 0; i < 32 ; i++)
+ for (i = 0; i < NUMBER_REGIONS ; i++)
seg_distr[i] = 3;
- segment_start = -25;
- segment_end = 7;
+ region_start = -MAX_LOW_POINT;
+ region_end = NUMBER_REGIONS - MAX_LOW_POINT;
} else {
/* 10 segments
* segment is from 2^-10 to 2^0
@@ -289,14 +290,14 @@ bool cm_helper_translate_curve_to_hw_format(
seg_distr[5] = 4;
seg_distr[6] = 4;
seg_distr[7] = 4;
- seg_distr[8] = 5;
- seg_distr[9] = 5;
+ seg_distr[8] = 4;
+ seg_distr[9] = 4;
- segment_start = -10;
- segment_end = 0;
+ region_start = -10;
+ region_end = 0;
}
- for (i = segment_end - segment_start; i < MAX_REGIONS_NUMBER ; i++)
+ for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++)
seg_distr[i] = -1;
for (k = 0; k < MAX_REGIONS_NUMBER; k++) {
@@ -305,10 +306,12 @@ bool cm_helper_translate_curve_to_hw_format(
}
j = 0;
- for (k = 0; k < (segment_end - segment_start); k++) {
- increment = NUMBER_SEGMENTS / (1 << seg_distr[k]);
- start_index = (segment_start + k + MAX_LOW_POINT) * NUMBER_SEGMENTS;
- for (i = start_index; i < start_index + NUMBER_SEGMENTS; i += increment) {
+ for (k = 0; k < (region_end - region_start); k++) {
+ increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]);
+ start_index = (region_start + k + MAX_LOW_POINT) *
+ NUMBER_SW_SEGMENTS;
+ for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS;
+ i += increment) {
if (j == hw_points - 1)
break;
rgb_resulted[j].red = output_tf->tf_pts.red[i];
@@ -319,15 +322,15 @@ bool cm_helper_translate_curve_to_hw_format(
}
/* last point */
- start_index = (segment_end + MAX_LOW_POINT) * NUMBER_SEGMENTS;
+ start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS;
rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index];
rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
- dal_fixed31_32_from_int(segment_start));
+ dal_fixed31_32_from_int(region_start));
arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
- dal_fixed31_32_from_int(segment_end));
+ dal_fixed31_32_from_int(region_end));
y_r = rgb_resulted[0].red;
y_g = rgb_resulted[0].green;
@@ -413,3 +416,156 @@ bool cm_helper_translate_curve_to_hw_format(
return true;
}
+
+#define NUM_DEGAMMA_REGIONS 12
+
+
+bool cm_helper_translate_curve_to_degamma_hw_format(
+ const struct dc_transfer_func *output_tf,
+ struct pwl_params *lut_params)
+{
+ struct curve_points *arr_points;
+ struct pwl_result_data *rgb_resulted;
+ struct pwl_result_data *rgb;
+ struct pwl_result_data *rgb_plus_1;
+ struct fixed31_32 y_r;
+ struct fixed31_32 y_g;
+ struct fixed31_32 y_b;
+ struct fixed31_32 y1_min;
+ struct fixed31_32 y3_max;
+
+ int32_t region_start, region_end;
+ int32_t i;
+ uint32_t j, k, seg_distr[MAX_REGIONS_NUMBER], increment, start_index, hw_points;
+
+ if (output_tf == NULL || lut_params == NULL || output_tf->type == TF_TYPE_BYPASS)
+ return false;
+
+ PERF_TRACE();
+
+ arr_points = lut_params->arr_points;
+ rgb_resulted = lut_params->rgb_resulted;
+ hw_points = 0;
+
+ memset(lut_params, 0, sizeof(struct pwl_params));
+ memset(seg_distr, 0, sizeof(seg_distr));
+
+ region_start = -NUM_DEGAMMA_REGIONS;
+ region_end = 0;
+
+
+ for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++)
+ seg_distr[i] = -1;
+ /* 12 segments
+ * segments are from 2^-12 to 0
+ */
+ for (i = 0; i < NUM_DEGAMMA_REGIONS ; i++)
+ seg_distr[i] = 4;
+
+ for (k = 0; k < MAX_REGIONS_NUMBER; k++) {
+ if (seg_distr[k] != -1)
+ hw_points += (1 << seg_distr[k]);
+ }
+
+ j = 0;
+ for (k = 0; k < (region_end - region_start); k++) {
+ increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]);
+ start_index = (region_start + k + MAX_LOW_POINT) *
+ NUMBER_SW_SEGMENTS;
+ for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS;
+ i += increment) {
+ if (j == hw_points - 1)
+ break;
+ rgb_resulted[j].red = output_tf->tf_pts.red[i];
+ rgb_resulted[j].green = output_tf->tf_pts.green[i];
+ rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
+ j++;
+ }
+ }
+
+ /* last point */
+ start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS;
+ rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index];
+ rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
+ rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
+
+ arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
+ dal_fixed31_32_from_int(region_start));
+ arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
+ dal_fixed31_32_from_int(region_end));
+
+ y_r = rgb_resulted[0].red;
+ y_g = rgb_resulted[0].green;
+ y_b = rgb_resulted[0].blue;
+
+ y1_min = dal_fixed31_32_min(y_r, dal_fixed31_32_min(y_g, y_b));
+
+ arr_points[0].y = y1_min;
+ arr_points[0].slope = dal_fixed31_32_div(arr_points[0].y, arr_points[0].x);
+ y_r = rgb_resulted[hw_points - 1].red;
+ y_g = rgb_resulted[hw_points - 1].green;
+ y_b = rgb_resulted[hw_points - 1].blue;
+
+ /* see comment above, m_arrPoints[1].y should be the Y value for the
+ * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1)
+ */
+ y3_max = dal_fixed31_32_max(y_r, dal_fixed31_32_max(y_g, y_b));
+
+ arr_points[1].y = y3_max;
+
+ arr_points[1].slope = dal_fixed31_32_zero;
+
+ if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
+ /* for PQ, we want to have a straight line from last HW X point,
+ * and the slope to be such that we hit 1.0 at 10000 nits.
+ */
+ const struct fixed31_32 end_value =
+ dal_fixed31_32_from_int(125);
+
+ arr_points[1].slope = dal_fixed31_32_div(
+ dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y),
+ dal_fixed31_32_sub(end_value, arr_points[1].x));
+ }
+
+ lut_params->hw_points_num = hw_points;
+
+ i = 1;
+ for (k = 0; k < MAX_REGIONS_NUMBER && i < MAX_REGIONS_NUMBER; k++) {
+ if (seg_distr[k] != -1) {
+ lut_params->arr_curve_points[k].segments_num =
+ seg_distr[k];
+ lut_params->arr_curve_points[i].offset =
+ lut_params->arr_curve_points[k].offset + (1 << seg_distr[k]);
+ }
+ i++;
+ }
+
+ if (seg_distr[k] != -1)
+ lut_params->arr_curve_points[k].segments_num = seg_distr[k];
+
+ rgb = rgb_resulted;
+ rgb_plus_1 = rgb_resulted + 1;
+
+ i = 1;
+ while (i != hw_points + 1) {
+ if (dal_fixed31_32_lt(rgb_plus_1->red, rgb->red))
+ rgb_plus_1->red = rgb->red;
+ if (dal_fixed31_32_lt(rgb_plus_1->green, rgb->green))
+ rgb_plus_1->green = rgb->green;
+ if (dal_fixed31_32_lt(rgb_plus_1->blue, rgb->blue))
+ rgb_plus_1->blue = rgb->blue;
+
+ rgb->delta_red = dal_fixed31_32_sub(rgb_plus_1->red, rgb->red);
+ rgb->delta_green = dal_fixed31_32_sub(rgb_plus_1->green, rgb->green);
+ rgb->delta_blue = dal_fixed31_32_sub(rgb_plus_1->blue, rgb->blue);
+
+ ++rgb_plus_1;
+ ++rgb;
+ ++i;
+ }
+ cm_helper_convert_to_custom_float(rgb_resulted,
+ lut_params->arr_points,
+ hw_points, false);
+
+ return true;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h
index 64e476b83bcb..7a531b02871f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h
@@ -106,4 +106,9 @@ bool cm_helper_translate_curve_to_hw_format(
const struct dc_transfer_func *output_tf,
struct pwl_params *lut_params, bool fixpoint);
+bool cm_helper_translate_curve_to_degamma_hw_format(
+ const struct dc_transfer_func *output_tf,
+ struct pwl_params *lut_params);
+
+
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
index f2a08b156cf0..e305c28c98de 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
@@ -196,7 +196,7 @@ static void dpp1_cm_set_regamma_pwl(
case OPP_REGAMMA_SRGB:
re_mode = 1;
break;
- case OPP_REGAMMA_3_6:
+ case OPP_REGAMMA_XVYCC:
re_mode = 2;
break;
case OPP_REGAMMA_USER:
@@ -424,6 +424,24 @@ void dpp1_set_cursor_position(
}
+void dpp1_dppclk_control(
+ struct dpp *dpp_base,
+ bool dppclk_div,
+ bool enable)
+{
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
+
+ if (enable) {
+ if (dpp->tf_mask->DPPCLK_RATE_CONTROL)
+ REG_UPDATE_2(DPP_CONTROL,
+ DPPCLK_RATE_CONTROL, dppclk_div,
+ DPP_CLOCK_ENABLE, 1);
+ else
+ REG_UPDATE(DPP_CONTROL, DPP_CLOCK_ENABLE, 1);
+ } else
+ REG_UPDATE(DPP_CONTROL, DPP_CLOCK_ENABLE, 0);
+}
+
static const struct dpp_funcs dcn10_dpp_funcs = {
.dpp_reset = dpp_reset,
.dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale,
@@ -445,6 +463,8 @@ static const struct dpp_funcs dcn10_dpp_funcs = {
.dpp_full_bypass = dpp1_full_bypass,
.set_cursor_attributes = dpp1_set_cursor_attributes,
.set_cursor_position = dpp1_set_cursor_position,
+ .dpp_dppclk_control = dpp1_dppclk_control,
+ .dpp_set_hdr_multiplier = dpp1_set_hdr_multiplier,
};
static struct dpp_caps dcn10_dpp_cap = {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
index f56ee4d08d89..17b062a8f88a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
@@ -112,7 +112,9 @@
SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \
SRI(CURSOR0_CONTROL, CNVC_CUR, id), \
SRI(CURSOR0_COLOR0, CNVC_CUR, id), \
- SRI(CURSOR0_COLOR1, CNVC_CUR, id)
+ SRI(CURSOR0_COLOR1, CNVC_CUR, id), \
+ SRI(DPP_CONTROL, DPP_TOP, id), \
+ SRI(CM_HDR_MULT_COEF, CM, id)
@@ -306,7 +308,9 @@
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_EXPANSION_MODE, mask_sh), \
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh), \
TF_SF(CNVC_CUR0_CURSOR0_COLOR0, CUR0_COLOR0, mask_sh), \
- TF_SF(CNVC_CUR0_CURSOR0_COLOR1, CUR0_COLOR1, mask_sh)
+ TF_SF(CNVC_CUR0_CURSOR0_COLOR1, CUR0_COLOR1, mask_sh), \
+ TF_SF(DPP_TOP0_DPP_CONTROL, DPP_CLOCK_ENABLE, mask_sh), \
+ TF_SF(CM0_CM_HDR_MULT_COEF, CM_HDR_MULT_COEF, mask_sh)
#define TF_REG_LIST_SH_MASK_DCN10(mask_sh)\
TF_REG_LIST_SH_MASK_DCN(mask_sh),\
@@ -410,7 +414,8 @@
TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \
TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \
TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \
- TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh)
+ TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \
+ TF_SF(DPP_TOP0_DPP_CONTROL, DPPCLK_RATE_CONTROL, mask_sh)
#define TF_REG_FIELD_LIST(type) \
type EXT_OVERSCAN_LEFT; \
@@ -1007,7 +1012,10 @@
type CM_BYPASS; \
type FORMAT_CONTROL__ALPHA_EN; \
type CUR0_COLOR0; \
- type CUR0_COLOR1;
+ type CUR0_COLOR1; \
+ type DPPCLK_RATE_CONTROL; \
+ type DPP_CLOCK_ENABLE; \
+ type CM_HDR_MULT_COEF;
struct dcn_dpp_shift {
TF_REG_FIELD_LIST(uint8_t)
@@ -1252,7 +1260,9 @@ struct dcn_dpp_mask {
uint32_t CURSOR_CONTROL; \
uint32_t CURSOR0_CONTROL; \
uint32_t CURSOR0_COLOR0; \
- uint32_t CURSOR0_COLOR1;
+ uint32_t CURSOR0_COLOR1; \
+ uint32_t DPP_CONTROL; \
+ uint32_t CM_HDR_MULT_COEF;
struct dcn_dpp_registers {
DPP_COMMON_REG_VARIABLE_LIST
@@ -1287,6 +1297,12 @@ void dpp1_set_cursor_attributes(
struct dpp *dpp_base,
enum dc_cursor_color_format color_format);
+void dpp1_set_cursor_position(
+ struct dpp *dpp_base,
+ const struct dc_cursor_position *pos,
+ const struct dc_cursor_mi_param *param,
+ uint32_t width);
+
bool dpp1_dscl_is_lb_conf_valid(
int ceil_vratio,
int num_partitions,
@@ -1397,6 +1413,15 @@ void dpp1_cnv_setup (
void dpp1_full_bypass(struct dpp *dpp_base);
+void dpp1_dppclk_control(
+ struct dpp *dpp_base,
+ bool dppclk_div,
+ bool enable);
+
+void dpp1_set_hdr_multiplier(
+ struct dpp *dpp_base,
+ uint32_t multiplier);
+
void dpp1_construct(struct dcn10_dpp *dpp1,
struct dc_context *ctx,
uint32_t inst,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c
index a5b099023652..fb32975e4b67 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c
@@ -193,6 +193,7 @@ void dpp1_cm_set_gamut_remap(
const struct dpp_grph_csc_adjustment *adjust)
{
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
+ int i = 0;
if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW)
/* Bypass if type is bypass or hw */
@@ -201,20 +202,8 @@ void dpp1_cm_set_gamut_remap(
struct fixed31_32 arr_matrix[12];
uint16_t arr_reg_val[12];
- arr_matrix[0] = adjust->temperature_matrix[0];
- arr_matrix[1] = adjust->temperature_matrix[1];
- arr_matrix[2] = adjust->temperature_matrix[2];
- arr_matrix[3] = dal_fixed31_32_zero;
-
- arr_matrix[4] = adjust->temperature_matrix[3];
- arr_matrix[5] = adjust->temperature_matrix[4];
- arr_matrix[6] = adjust->temperature_matrix[5];
- arr_matrix[7] = dal_fixed31_32_zero;
-
- arr_matrix[8] = adjust->temperature_matrix[6];
- arr_matrix[9] = adjust->temperature_matrix[7];
- arr_matrix[10] = adjust->temperature_matrix[8];
- arr_matrix[11] = dal_fixed31_32_zero;
+ for (i = 0; i < 12; i++)
+ arr_matrix[i] = adjust->temperature_matrix[i];
convert_float_matrix(
arr_reg_val, arr_matrix, 12);
@@ -309,6 +298,32 @@ static void dpp1_cm_get_reg_field(
reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B;
}
+static void dpp1_cm_get_degamma_reg_field(
+ struct dcn10_dpp *dpp,
+ struct xfer_func_reg *reg)
+{
+ reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_DGAM_RAMA_EXP_REGION0_LUT_OFFSET;
+ reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_DGAM_RAMA_EXP_REGION0_LUT_OFFSET;
+ reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_DGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
+ reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_DGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
+ reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_DGAM_RAMA_EXP_REGION1_LUT_OFFSET;
+ reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_DGAM_RAMA_EXP_REGION1_LUT_OFFSET;
+ reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_DGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
+ reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_DGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
+
+ reg->shifts.field_region_end = dpp->tf_shift->CM_DGAM_RAMB_EXP_REGION_END_B;
+ reg->masks.field_region_end = dpp->tf_mask->CM_DGAM_RAMB_EXP_REGION_END_B;
+ reg->shifts.field_region_end_slope = dpp->tf_shift->CM_DGAM_RAMB_EXP_REGION_END_SLOPE_B;
+ reg->masks.field_region_end_slope = dpp->tf_mask->CM_DGAM_RAMB_EXP_REGION_END_SLOPE_B;
+ reg->shifts.field_region_end_base = dpp->tf_shift->CM_DGAM_RAMB_EXP_REGION_END_BASE_B;
+ reg->masks.field_region_end_base = dpp->tf_mask->CM_DGAM_RAMB_EXP_REGION_END_BASE_B;
+ reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_DGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
+ reg->masks.field_region_linear_slope = dpp->tf_mask->CM_DGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
+ reg->shifts.exp_region_start = dpp->tf_shift->CM_DGAM_RAMB_EXP_REGION_START_B;
+ reg->masks.exp_region_start = dpp->tf_mask->CM_DGAM_RAMB_EXP_REGION_START_B;
+ reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_DGAM_RAMB_EXP_REGION_START_SEGMENT_B;
+ reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_DGAM_RAMB_EXP_REGION_START_SEGMENT_B;
+}
void dpp1_cm_set_output_csc_adjustment(
struct dpp *dpp_base,
const uint16_t *regval)
@@ -513,7 +528,7 @@ void dpp1_program_degamma_lutb_settings(
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
struct xfer_func_reg gam_regs;
- dpp1_cm_get_reg_field(dpp, &gam_regs);
+ dpp1_cm_get_degamma_reg_field(dpp, &gam_regs);
gam_regs.start_cntl_b = REG(CM_DGAM_RAMB_START_CNTL_B);
gam_regs.start_cntl_g = REG(CM_DGAM_RAMB_START_CNTL_G);
@@ -542,7 +557,7 @@ void dpp1_program_degamma_luta_settings(
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
struct xfer_func_reg gam_regs;
- dpp1_cm_get_reg_field(dpp, &gam_regs);
+ dpp1_cm_get_degamma_reg_field(dpp, &gam_regs);
gam_regs.start_cntl_b = REG(CM_DGAM_RAMA_START_CNTL_B);
gam_regs.start_cntl_g = REG(CM_DGAM_RAMA_START_CNTL_G);
@@ -789,3 +804,12 @@ void dpp1_program_input_lut(
REG_UPDATE(CM_IGAM_CONTROL, CM_IGAM_LUT_MODE, rama_occupied ? 3 : 2);
REG_GET(CM_IGAM_CONTROL, CM_IGAM_LUT_MODE, &ram_num);
}
+
+void dpp1_set_hdr_multiplier(
+ struct dpp *dpp_base,
+ uint32_t multiplier)
+{
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
+
+ REG_UPDATE(CM_HDR_MULT_COEF, CM_HDR_MULT_COEF, multiplier);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
index eb8317187f30..738f67ffd1b4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
@@ -30,6 +30,8 @@
#define CTX \
hubbub->ctx
+#define DC_LOGGER \
+ hubbub->ctx->logger
#define REG(reg)\
hubbub->regs->reg
@@ -100,7 +102,6 @@ bool hubbub1_verify_allow_pstate_change_high(
static unsigned int max_sampled_pstate_wait_us; /* data collection */
static bool forced_pstate_allow; /* help with revert wa */
- unsigned int debug_index = 0x7;
unsigned int debug_data;
unsigned int i;
@@ -115,7 +116,9 @@ bool hubbub1_verify_allow_pstate_change_high(
forced_pstate_allow = false;
}
- /* description "3-0: Pipe0 cursor0 QOS
+ /* RV1:
+ * dchubbubdebugind, at: 0x7
+ * description "3-0: Pipe0 cursor0 QOS
* 7-4: Pipe1 cursor0 QOS
* 11-8: Pipe2 cursor0 QOS
* 15-12: Pipe3 cursor0 QOS
@@ -137,7 +140,8 @@ bool hubbub1_verify_allow_pstate_change_high(
* 31: SOC pstate change request
*/
- REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, debug_index);
+
+ REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, hubbub->debug_test_index_pstate);
for (i = 0; i < pstate_wait_timeout_us; i++) {
debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA);
@@ -145,8 +149,7 @@ bool hubbub1_verify_allow_pstate_change_high(
if (debug_data & (1 << 30)) {
if (i > pstate_wait_expected_timeout_us)
- dm_logger_write(hubbub->ctx->logger, LOG_WARNING,
- "pstate took longer than expected ~%dus\n",
+ DC_LOG_WARNING("pstate took longer than expected ~%dus\n",
i);
return true;
@@ -165,8 +168,7 @@ bool hubbub1_verify_allow_pstate_change_high(
DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1);
forced_pstate_allow = true;
- dm_logger_write(hubbub->ctx->logger, LOG_WARNING,
- "pstate TEST_DEBUG_DATA: 0x%X\n",
+ DC_LOG_WARNING("pstate TEST_DEBUG_DATA: 0x%X\n",
debug_data);
return false;
@@ -209,16 +211,14 @@ void hubbub1_program_watermarks(
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "URGENCY_WATERMARK_A calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->a.urgent_ns, prog_wm_value);
prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "PTE_META_URGENCY_WATERMARK_A calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->a.pte_meta_urgent_ns, prog_wm_value);
@@ -227,8 +227,7 @@ void hubbub1_program_watermarks(
watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
@@ -237,8 +236,7 @@ void hubbub1_program_watermarks(
watermarks->a.cstate_pstate.cstate_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "SR_EXIT_WATERMARK_A calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
}
@@ -247,8 +245,7 @@ void hubbub1_program_watermarks(
watermarks->a.cstate_pstate.pstate_change_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n\n",
watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
@@ -257,8 +254,7 @@ void hubbub1_program_watermarks(
prog_wm_value = convert_and_clamp(
watermarks->b.urgent_ns, refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "URGENCY_WATERMARK_B calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->b.urgent_ns, prog_wm_value);
@@ -267,8 +263,7 @@ void hubbub1_program_watermarks(
watermarks->b.pte_meta_urgent_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "PTE_META_URGENCY_WATERMARK_B calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->b.pte_meta_urgent_ns, prog_wm_value);
@@ -278,8 +273,7 @@ void hubbub1_program_watermarks(
watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "SR_ENTER_WATERMARK_B calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
@@ -288,8 +282,7 @@ void hubbub1_program_watermarks(
watermarks->b.cstate_pstate.cstate_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "SR_EXIT_WATERMARK_B calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
}
@@ -298,8 +291,7 @@ void hubbub1_program_watermarks(
watermarks->b.cstate_pstate.pstate_change_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n"
+ DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n"
"HW register value = 0x%x\n",
watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
@@ -307,8 +299,7 @@ void hubbub1_program_watermarks(
prog_wm_value = convert_and_clamp(
watermarks->c.urgent_ns, refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "URGENCY_WATERMARK_C calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->c.urgent_ns, prog_wm_value);
@@ -317,8 +308,7 @@ void hubbub1_program_watermarks(
watermarks->c.pte_meta_urgent_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "PTE_META_URGENCY_WATERMARK_C calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->c.pte_meta_urgent_ns, prog_wm_value);
@@ -328,8 +318,7 @@ void hubbub1_program_watermarks(
watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "SR_ENTER_WATERMARK_C calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
@@ -338,8 +327,7 @@ void hubbub1_program_watermarks(
watermarks->c.cstate_pstate.cstate_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "SR_EXIT_WATERMARK_C calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
}
@@ -348,8 +336,7 @@ void hubbub1_program_watermarks(
watermarks->c.cstate_pstate.pstate_change_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n"
+ DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n"
"HW register value = 0x%x\n",
watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
@@ -357,8 +344,7 @@ void hubbub1_program_watermarks(
prog_wm_value = convert_and_clamp(
watermarks->d.urgent_ns, refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "URGENCY_WATERMARK_D calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->d.urgent_ns, prog_wm_value);
@@ -366,8 +352,7 @@ void hubbub1_program_watermarks(
watermarks->d.pte_meta_urgent_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "PTE_META_URGENCY_WATERMARK_D calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->d.pte_meta_urgent_ns, prog_wm_value);
@@ -377,8 +362,7 @@ void hubbub1_program_watermarks(
watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "SR_ENTER_WATERMARK_D calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
@@ -387,8 +371,7 @@ void hubbub1_program_watermarks(
watermarks->d.cstate_pstate.cstate_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "SR_EXIT_WATERMARK_D calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
}
@@ -398,8 +381,7 @@ void hubbub1_program_watermarks(
watermarks->d.cstate_pstate.pstate_change_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
- dm_logger_write(hubbub->ctx->logger, LOG_BANDWIDTH_CALCS,
- "DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
+ DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n\n",
watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
@@ -512,5 +494,6 @@ void hubbub1_construct(struct hubbub *hubbub,
hubbub->shifts = hubbub_shift;
hubbub->masks = hubbub_mask;
+ hubbub->debug_test_index_pstate = 0x7;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
index d5c97844312f..a16e908821a0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
@@ -185,6 +185,7 @@ struct hubbub {
const struct dcn_hubbub_registers *regs;
const struct dcn_hubbub_shift *shifts;
const struct dcn_hubbub_mask *masks;
+ unsigned int debug_test_index_pstate;
};
void hubbub1_update_dchub(
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
index 585b33384002..39b72f696ae9 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
@@ -73,6 +73,9 @@ static void hubp1_disconnect(struct hubp *hubp)
REG_UPDATE(DCHUBP_CNTL,
HUBP_TTU_DISABLE, 1);
+
+ REG_UPDATE(CURSOR_CONTROL,
+ CURSOR_ENABLE, 0);
}
static void hubp1_set_hubp_blank_en(struct hubp *hubp, bool blank)
@@ -296,8 +299,9 @@ bool hubp1_program_surface_flip_and_addr(
if (address->grph.addr.quad_part == 0)
break;
- REG_UPDATE(DCSURF_SURFACE_CONTROL,
- PRIMARY_SURFACE_TMZ, address->tmz_surface);
+ REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
+ PRIMARY_SURFACE_TMZ, address->tmz_surface,
+ PRIMARY_META_SURFACE_TMZ, address->tmz_surface);
if (address->grph.meta_addr.quad_part != 0) {
REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
@@ -322,8 +326,11 @@ bool hubp1_program_surface_flip_and_addr(
|| address->video_progressive.chroma_addr.quad_part == 0)
break;
- REG_UPDATE(DCSURF_SURFACE_CONTROL,
- PRIMARY_SURFACE_TMZ, address->tmz_surface);
+ REG_UPDATE_4(DCSURF_SURFACE_CONTROL,
+ PRIMARY_SURFACE_TMZ, address->tmz_surface,
+ PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
+ PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
+ PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface);
if (address->video_progressive.luma_meta_addr.quad_part != 0) {
REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0,
@@ -365,8 +372,11 @@ bool hubp1_program_surface_flip_and_addr(
if (address->grph_stereo.right_addr.quad_part == 0)
break;
- REG_UPDATE(DCSURF_SURFACE_CONTROL,
- PRIMARY_SURFACE_TMZ, address->tmz_surface);
+ REG_UPDATE_4(DCSURF_SURFACE_CONTROL,
+ PRIMARY_SURFACE_TMZ, address->tmz_surface,
+ PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
+ PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
+ PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface);
if (address->grph_stereo.right_meta_addr.quad_part != 0) {
@@ -909,6 +919,21 @@ void hubp1_cursor_set_position(
/* TODO Handle surface pixel formats other than 4:4:4 */
}
+void hubp1_clk_cntl(struct hubp *hubp, bool enable)
+{
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
+ uint32_t clk_enable = enable ? 1 : 0;
+
+ REG_UPDATE(HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, clk_enable);
+}
+
+void hubp1_vtg_sel(struct hubp *hubp, uint32_t otg_inst)
+{
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
+
+ REG_UPDATE(DCHUBP_CNTL, HUBP_VTG_SEL, otg_inst);
+}
+
static struct hubp_funcs dcn10_hubp_funcs = {
.hubp_program_surface_flip_and_addr =
hubp1_program_surface_flip_and_addr,
@@ -925,6 +950,8 @@ static struct hubp_funcs dcn10_hubp_funcs = {
.set_cursor_attributes = hubp1_cursor_set_attributes,
.set_cursor_position = hubp1_cursor_set_position,
.hubp_disconnect = hubp1_disconnect,
+ .hubp_clk_cntl = hubp1_clk_cntl,
+ .hubp_vtg_sel = hubp1_vtg_sel,
};
/*****************************************/
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
index 33e91d9c010f..4a3703e12ea1 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
@@ -96,7 +96,8 @@
SRI(DCN_SURF0_TTU_CNTL1, HUBPREQ, id),\
SRI(DCN_SURF1_TTU_CNTL0, HUBPREQ, id),\
SRI(DCN_SURF1_TTU_CNTL1, HUBPREQ, id),\
- SRI(DCN_VM_MX_L1_TLB_CNTL, HUBPREQ, id)
+ SRI(DCN_VM_MX_L1_TLB_CNTL, HUBPREQ, id),\
+ SRI(HUBP_CLK_CNTL, HUBP, id)
#define HUBP_REG_LIST_DCN10(id)\
HUBP_REG_LIST_DCN(id),\
@@ -230,7 +231,8 @@
uint32_t CURSOR_CONTROL; \
uint32_t CURSOR_POSITION; \
uint32_t CURSOR_HOT_SPOT; \
- uint32_t CURSOR_DST_OFFSET
+ uint32_t CURSOR_DST_OFFSET; \
+ uint32_t HUBP_CLK_CNTL
#define HUBP_SF(reg_name, field_name, post_fix)\
.field_name = reg_name ## __ ## field_name ## post_fix
@@ -240,6 +242,7 @@
HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_TTU_DISABLE, mask_sh),\
HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_UNDERFLOW_STATUS, mask_sh),\
HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_NO_OUTSTANDING_REQ, mask_sh),\
+ HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_VTG_SEL, mask_sh),\
HUBP_SF(HUBP0_DCSURF_ADDR_CONFIG, NUM_PIPES, mask_sh),\
HUBP_SF(HUBP0_DCSURF_ADDR_CONFIG, NUM_BANKS, mask_sh),\
HUBP_SF(HUBP0_DCSURF_ADDR_CONFIG, PIPE_INTERLEAVE, mask_sh),\
@@ -293,6 +296,9 @@
HUBP_SF(HUBPREQ0_DCSURF_SURFACE_EARLIEST_INUSE_C, SURFACE_EARLIEST_INUSE_ADDRESS_C, mask_sh),\
HUBP_SF(HUBPREQ0_DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C, SURFACE_EARLIEST_INUSE_ADDRESS_HIGH_C, mask_sh),\
HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_SURFACE_TMZ, mask_sh),\
+ HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_SURFACE_TMZ_C, mask_sh),\
+ HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_META_SURFACE_TMZ, mask_sh),\
+ HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_META_SURFACE_TMZ_C, mask_sh),\
HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_SURFACE_DCC_EN, mask_sh),\
HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_SURFACE_DCC_IND_64B_BLK, mask_sh),\
HUBP_SF(HUBPRET0_HUBPRET_CONTROL, DET_BUF_PLANE1_BASE_ADDRESS, mask_sh),\
@@ -352,7 +358,8 @@
HUBP_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL0, QoS_RAMP_DISABLE, mask_sh),\
HUBP_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL1, REFCYC_PER_REQ_DELIVERY_PRE, mask_sh),\
HUBP_SF(HUBPREQ0_DCN_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, mask_sh),\
- HUBP_SF(HUBPREQ0_DCN_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE, mask_sh)
+ HUBP_SF(HUBPREQ0_DCN_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE, mask_sh),\
+ HUBP_SF(HUBP0_HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, mask_sh)
#define HUBP_MASK_SH_LIST_DCN10(mask_sh)\
HUBP_MASK_SH_LIST_DCN(mask_sh),\
@@ -398,6 +405,7 @@
type HUBP_BLANK_EN;\
type HUBP_TTU_DISABLE;\
type HUBP_NO_OUTSTANDING_REQ;\
+ type HUBP_VTG_SEL;\
type HUBP_UNDERFLOW_STATUS;\
type NUM_PIPES;\
type NUM_BANKS;\
@@ -452,6 +460,13 @@
type SURFACE_EARLIEST_INUSE_ADDRESS_C;\
type SURFACE_EARLIEST_INUSE_ADDRESS_HIGH_C;\
type PRIMARY_SURFACE_TMZ;\
+ type PRIMARY_SURFACE_TMZ_C;\
+ type SECONDARY_SURFACE_TMZ;\
+ type SECONDARY_SURFACE_TMZ_C;\
+ type PRIMARY_META_SURFACE_TMZ;\
+ type PRIMARY_META_SURFACE_TMZ_C;\
+ type SECONDARY_META_SURFACE_TMZ;\
+ type SECONDARY_META_SURFACE_TMZ_C;\
type PRIMARY_SURFACE_DCC_EN;\
type PRIMARY_SURFACE_DCC_IND_64B_BLK;\
type DET_BUF_PLANE1_BASE_ADDRESS;\
@@ -524,6 +539,7 @@
type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB;\
type ENABLE_L1_TLB;\
type SYSTEM_ACCESS_MODE;\
+ type HUBP_CLOCK_ENABLE;\
type MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM;\
type MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB;\
type MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB;\
@@ -653,6 +669,9 @@ void min_set_viewport(struct hubp *hubp,
const struct rect *viewport,
const struct rect *viewport_c);
+void hubp1_clk_cntl(struct hubp *hubp, bool enable);
+void hubp1_vtg_sel(struct hubp *hubp, uint32_t otg_inst);
+
void dcn10_hubp_construct(
struct dcn10_hubp *hubp1,
struct dc_context *ctx,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index 82572863acab..8b0f6b8a5627 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -45,6 +45,8 @@
#include "dcn10_hubbub.h"
#include "dcn10_cm_common.h"
+#define DC_LOGGER \
+ ctx->logger
#define CTX \
hws->ctx
#define REG(reg)\
@@ -133,7 +135,7 @@ void dcn10_log_hw_state(struct dc *dc)
DTN_INFO("[%d]:\t %xh \t %xh \t %d \t %d \t "
"%xh \t %xh \t %xh \t "
"%d \t %d \t %d \t %xh \t",
- i,
+ hubp->inst,
s.pixel_format,
s.inuse_addr_hi,
s.viewport_width,
@@ -155,7 +157,7 @@ void dcn10_log_hw_state(struct dc *dc)
DTN_INFO("OTG:\t v_bs \t v_be \t v_ss \t v_se \t vpol \t vmax \t vmin \t "
"h_bs \t h_be \t h_ss \t h_se \t hpol \t htot \t vtot \t underflow\n");
- for (i = 0; i < pool->res_cap->num_timing_generator; i++) {
+ for (i = 0; i < pool->timing_generator_count; i++) {
struct timing_generator *tg = pool->timing_generators[i];
struct dcn_otg_state s = {0};
@@ -168,7 +170,7 @@ void dcn10_log_hw_state(struct dc *dc)
DTN_INFO("[%d]:\t %d \t %d \t %d \t %d \t "
"%d \t %d \t %d \t %d \t %d \t %d \t "
"%d \t %d \t %d \t %d \t %d \t ",
- i,
+ tg->inst,
s.v_blank_start,
s.v_blank_end,
s.v_sync_a_start,
@@ -193,26 +195,6 @@ void dcn10_log_hw_state(struct dc *dc)
DTN_INFO_END();
}
-static void enable_dppclk(
- struct dce_hwseq *hws,
- uint8_t plane_id,
- uint32_t requested_pix_clk,
- bool dppclk_div)
-{
- dm_logger_write(hws->ctx->logger, LOG_SURFACE,
- "dppclk_rate_control for pipe %d programed to %d\n",
- plane_id,
- dppclk_div);
-
- if (hws->shifts->DPPCLK_RATE_CONTROL)
- REG_UPDATE_2(DPP_CONTROL[plane_id],
- DPPCLK_RATE_CONTROL, dppclk_div,
- DPP_CLOCK_ENABLE, 1);
- else
- REG_UPDATE(DPP_CONTROL[plane_id],
- DPP_CLOCK_ENABLE, 1);
-}
-
static void enable_power_gating_plane(
struct dce_hwseq *hws,
bool enable)
@@ -238,10 +220,34 @@ static void enable_power_gating_plane(
static void disable_vga(
struct dce_hwseq *hws)
{
+ unsigned int in_vga1_mode = 0;
+ unsigned int in_vga2_mode = 0;
+ unsigned int in_vga3_mode = 0;
+ unsigned int in_vga4_mode = 0;
+
+ REG_GET(D1VGA_CONTROL, D1VGA_MODE_ENABLE, &in_vga1_mode);
+ REG_GET(D2VGA_CONTROL, D2VGA_MODE_ENABLE, &in_vga2_mode);
+ REG_GET(D3VGA_CONTROL, D3VGA_MODE_ENABLE, &in_vga3_mode);
+ REG_GET(D4VGA_CONTROL, D4VGA_MODE_ENABLE, &in_vga4_mode);
+
+ if (in_vga1_mode == 0 && in_vga2_mode == 0 &&
+ in_vga3_mode == 0 && in_vga4_mode == 0)
+ return;
+
REG_WRITE(D1VGA_CONTROL, 0);
REG_WRITE(D2VGA_CONTROL, 0);
REG_WRITE(D3VGA_CONTROL, 0);
REG_WRITE(D4VGA_CONTROL, 0);
+
+ /* HW Engineer's Notes:
+ * During switch from vga->extended, if we set the VGA_TEST_ENABLE and
+ * then hit the VGA_TEST_RENDER_START, then the DCHUBP timing gets updated correctly.
+ *
+ * Then vBIOS will have it poll for the VGA_TEST_RENDER_DONE and unset
+ * VGA_TEST_ENABLE, to leave it in the same state as before.
+ */
+ REG_UPDATE(VGA_TEST_CONTROL, VGA_TEST_ENABLE, 1);
+ REG_UPDATE(VGA_TEST_CONTROL, VGA_TEST_RENDER_START, 1);
}
static void dpp_pg_control(
@@ -348,6 +354,7 @@ static void power_on_plane(
struct dce_hwseq *hws,
int plane_id)
{
+ struct dc_context *ctx = hws->ctx;
if (REG(DC_IP_REQUEST_CNTL)) {
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
@@ -355,7 +362,7 @@ static void power_on_plane(
hubp_pg_control(hws, plane_id, true);
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
- dm_logger_write(hws->ctx->logger, LOG_DEBUG,
+ DC_LOG_DEBUG(
"Un-gated front end for pipe %d\n", plane_id);
}
}
@@ -546,7 +553,7 @@ static void reset_back_end_for_pipe(
struct dc_state *context)
{
int i;
-
+ struct dc_context *ctx = dc->ctx;
if (pipe_ctx->stream_res.stream_enc == NULL) {
pipe_ctx->stream = NULL;
return;
@@ -556,6 +563,22 @@ static void reset_back_end_for_pipe(
/* DPMS may already disable */
if (!pipe_ctx->stream->dpms_off)
core_link_disable_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE);
+ else if (pipe_ctx->stream_res.audio) {
+ /*
+ * if stream is already disabled outside of commit streams path,
+ * audio disable was skipped. Need to do it here
+ */
+ pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
+
+ if (dc->caps.dynamic_audio == true) {
+ /*we have to dynamic arbitrate the audio endpoints*/
+ pipe_ctx->stream_res.audio = NULL;
+ /*we free the resource, need reset is_audio_acquired*/
+ update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, pipe_ctx->stream_res.audio, false);
+ }
+
+ }
+
}
/* by upper caller loop, parent pipe: pipe0, will be reset last.
@@ -576,8 +599,7 @@ static void reset_back_end_for_pipe(
return;
pipe_ctx->stream = NULL;
- dm_logger_write(dc->ctx->logger, LOG_DEBUG,
- "Reset back end for pipe %d, tg:%d\n",
+ DC_LOG_DEBUG("Reset back end for pipe %d, tg:%d\n",
pipe_ctx->pipe_idx, pipe_ctx->stream_res.tg->inst);
}
@@ -597,29 +619,22 @@ static void dcn10_verify_allow_pstate_change_high(struct dc *dc)
/* trigger HW to start disconnect plane from stream on the next vsync */
static void plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
- int fe_idx = pipe_ctx->pipe_idx;
- struct hubp *hubp = dc->res_pool->hubps[fe_idx];
+ struct hubp *hubp = pipe_ctx->plane_res.hubp;
+ int dpp_id = pipe_ctx->plane_res.dpp->inst;
struct mpc *mpc = dc->res_pool->mpc;
- int opp_id;
struct mpc_tree *mpc_tree_params;
struct mpcc *mpcc_to_remove = NULL;
+ struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
- /* look at tree rather than mi here to know if we already reset */
- for (opp_id = 0; opp_id < dc->res_pool->pipe_count; opp_id++) {
- struct output_pixel_processor *opp = dc->res_pool->opps[opp_id];
-
- mpc_tree_params = &(opp->mpc_tree_params);
- mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, fe_idx);
- if (mpcc_to_remove != NULL)
- break;
- }
+ mpc_tree_params = &(opp->mpc_tree_params);
+ mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id);
/*Already reset*/
- if (opp_id == dc->res_pool->pipe_count)
+ if (mpcc_to_remove == NULL)
return;
mpc->funcs->remove_mpcc(mpc, mpc_tree_params, mpcc_to_remove);
- dc->res_pool->opps[opp_id]->mpcc_disconnect_pending[fe_idx] = true;
+ opp->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
dc->optimized_required = true;
@@ -630,21 +645,22 @@ static void plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
dcn10_verify_allow_pstate_change_high(dc);
}
-static void plane_atomic_power_down(struct dc *dc, int fe_idx)
+static void plane_atomic_power_down(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
struct dce_hwseq *hws = dc->hwseq;
- struct dpp *dpp = dc->res_pool->dpps[fe_idx];
+ struct dpp *dpp = pipe_ctx->plane_res.dpp;
+ struct dc_context *ctx = dc->ctx;
if (REG(DC_IP_REQUEST_CNTL)) {
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
- dpp_pg_control(hws, fe_idx, false);
- hubp_pg_control(hws, fe_idx, false);
+ dpp_pg_control(hws, dpp->inst, false);
+ hubp_pg_control(hws, pipe_ctx->plane_res.hubp->inst, false);
dpp->funcs->dpp_reset(dpp);
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
- dm_logger_write(dc->ctx->logger, LOG_DEBUG,
- "Power gated front end %d\n", fe_idx);
+ DC_LOG_DEBUG(
+ "Power gated front end %d\n", pipe_ctx->pipe_idx);
}
}
@@ -653,26 +669,25 @@ static void plane_atomic_power_down(struct dc *dc, int fe_idx)
*/
static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
- int fe_idx = pipe_ctx->pipe_idx;
- struct dce_hwseq *hws = dc->hwseq;
- struct hubp *hubp = dc->res_pool->hubps[fe_idx];
+ struct hubp *hubp = pipe_ctx->plane_res.hubp;
+ struct dpp *dpp = pipe_ctx->plane_res.dpp;
int opp_id = hubp->opp_id;
dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx);
- REG_UPDATE(HUBP_CLK_CNTL[fe_idx],
- HUBP_CLOCK_ENABLE, 0);
- REG_UPDATE(DPP_CONTROL[fe_idx],
- DPP_CLOCK_ENABLE, 0);
+ hubp->funcs->hubp_clk_cntl(hubp, false);
+
+ dpp->funcs->dpp_dppclk_control(dpp, false, false);
- if (opp_id != 0xf && dc->res_pool->opps[opp_id]->mpc_tree_params.opp_list == NULL)
- REG_UPDATE(OPP_PIPE_CONTROL[opp_id],
- OPP_PIPE_CLOCK_EN, 0);
+ if (opp_id != 0xf && pipe_ctx->stream_res.opp->mpc_tree_params.opp_list == NULL)
+ pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control(
+ pipe_ctx->stream_res.opp,
+ false);
hubp->power_gated = true;
dc->optimized_required = false; /* We're powering off, no need to optimize */
- plane_atomic_power_down(dc, fe_idx);
+ plane_atomic_power_down(dc, pipe_ctx);
pipe_ctx->stream = NULL;
memset(&pipe_ctx->stream_res, 0, sizeof(pipe_ctx->stream_res));
@@ -684,15 +699,16 @@ static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
static void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
- if (dc->res_pool->hubps[pipe_ctx->pipe_idx]->power_gated)
+ struct dc_context *ctx = dc->ctx;
+
+ if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated)
return;
plane_atomic_disable(dc, pipe_ctx);
apply_DEGVIDCN10_253_wa(dc);
- dm_logger_write(dc->ctx->logger, LOG_DC,
- "Power down front end %d\n",
+ DC_LOG_DC("Power down front end %d\n",
pipe_ctx->pipe_idx);
}
@@ -720,26 +736,25 @@ static void dcn10_init_hw(struct dc *dc)
}
enable_power_gating_plane(dc->hwseq, true);
- return;
- }
- /* end of FPGA. Below if real ASIC */
+ } else {
- if (!dcb->funcs->is_accelerated_mode(dcb)) {
- bios_golden_init(dc);
- disable_vga(dc->hwseq);
- }
+ if (!dcb->funcs->is_accelerated_mode(dcb)) {
+ bios_golden_init(dc);
+ disable_vga(dc->hwseq);
+ }
- for (i = 0; i < dc->link_count; i++) {
- /* Power up AND update implementation according to the
- * required signal (which may be different from the
- * default signal on connector).
- */
- struct dc_link *link = dc->links[i];
+ for (i = 0; i < dc->link_count; i++) {
+ /* Power up AND update implementation according to the
+ * required signal (which may be different from the
+ * default signal on connector).
+ */
+ struct dc_link *link = dc->links[i];
- if (link->link_enc->connector.id == CONNECTOR_ID_EDP)
- dc->hwss.edp_power_control(link, true);
+ if (link->link_enc->connector.id == CONNECTOR_ID_EDP)
+ dc->hwss.edp_power_control(link, true);
- link->link_enc->funcs->hw_init(link->link_enc);
+ link->link_enc->funcs->hw_init(link->link_enc);
+ }
}
for (i = 0; i < dc->res_pool->pipe_count; i++) {
@@ -768,18 +783,21 @@ static void dcn10_init_hw(struct dc *dc)
struct timing_generator *tg = dc->res_pool->timing_generators[i];
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
struct hubp *hubp = dc->res_pool->hubps[i];
+ struct dpp *dpp = dc->res_pool->dpps[i];
pipe_ctx->stream_res.tg = tg;
pipe_ctx->pipe_idx = i;
pipe_ctx->plane_res.hubp = hubp;
- hubp->mpcc_id = i;
+ pipe_ctx->plane_res.dpp = dpp;
+ pipe_ctx->plane_res.mpcc_inst = dpp->inst;
+ hubp->mpcc_id = dpp->inst;
hubp->opp_id = 0xf;
hubp->power_gated = false;
dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
- dc->res_pool->opps[i]->mpcc_disconnect_pending[i] = true;
+ dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
plane_atomic_disconnect(dc, pipe_ctx);
@@ -804,6 +822,10 @@ static void dcn10_init_hw(struct dc *dc)
tg->funcs->tg_init(tg);
}
+ /* end of FPGA. Below if real ASIC */
+ if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
+ return;
+
for (i = 0; i < dc->res_pool->audio_count; i++) {
struct audio *audio = dc->res_pool->audios[i];
@@ -922,7 +944,10 @@ static bool dcn10_set_input_transfer_func(struct pipe_ctx *pipe_ctx,
if (plane_state->in_transfer_func)
tf = plane_state->in_transfer_func;
- if (plane_state->gamma_correction && dce_use_lut(plane_state))
+ if (plane_state->gamma_correction &&
+ plane_state->gamma_correction->is_identity)
+ dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS);
+ else if (plane_state->gamma_correction && dce_use_lut(plane_state->format))
dpp_base->funcs->dpp_program_input_lut(dpp_base, plane_state->gamma_correction);
if (tf == NULL)
@@ -993,8 +1018,6 @@ static void dcn10_pipe_control_lock(
struct pipe_ctx *pipe,
bool lock)
{
- struct hubp *hubp = NULL;
- hubp = dc->res_pool->hubps[pipe->pipe_idx];
/* use TG master update lock to lock everything on the TG
* therefore only top pipe need to lock
*/
@@ -1097,7 +1120,7 @@ static void dcn10_enable_per_frame_crtc_position_reset(
DC_SYNC_INFO("Waiting for trigger\n");
- for (i = 1; i < group_size; i++)
+ for (i = 0; i < group_size; i++)
wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg);
DC_SYNC_INFO("Multi-display sync is complete\n");
@@ -1107,7 +1130,7 @@ static void dcn10_enable_per_frame_crtc_position_reset(
struct dc *core_dc,
struct pipe_ctx *pipe_ctx)
{
- dm_logger_write(core_dc->ctx->logger, LOG_BANDWIDTH_CALCS,
+ DC_LOG_BANDWIDTH_CALCS(core_dc->ctx->logger,
"\n============== DML TTU Output parameters [%d] ==============\n"
"qos_level_low_wm: %d, \n"
"qos_level_high_wm: %d, \n"
@@ -1137,7 +1160,7 @@ static void dcn10_enable_per_frame_crtc_position_reset(
pipe_ctx->ttu_regs.refcyc_per_req_delivery_pre_c
);
- dm_logger_write(core_dc->ctx->logger, LOG_BANDWIDTH_CALCS,
+ DC_LOG_BANDWIDTH_CALCS(core_dc->ctx->logger,
"\n============== DML DLG Output parameters [%d] ==============\n"
"refcyc_h_blank_end: %d, \n"
"dlg_vblank_end: %d, \n"
@@ -1172,7 +1195,7 @@ static void dcn10_enable_per_frame_crtc_position_reset(
pipe_ctx->dlg_regs.refcyc_per_pte_group_nom_l
);
- dm_logger_write(core_dc->ctx->logger, LOG_BANDWIDTH_CALCS,
+ DC_LOG_BANDWIDTH_CALCS(core_dc->ctx->logger,
"\ndst_y_per_meta_row_nom_l: %d, \n"
"refcyc_per_meta_chunk_nom_l: %d, \n"
"refcyc_per_line_delivery_pre_l: %d, \n"
@@ -1202,7 +1225,7 @@ static void dcn10_enable_per_frame_crtc_position_reset(
pipe_ctx->dlg_regs.refcyc_per_line_delivery_c
);
- dm_logger_write(core_dc->ctx->logger, LOG_BANDWIDTH_CALCS,
+ DC_LOG_BANDWIDTH_CALCS(core_dc->ctx->logger,
"\n============== DML RQ Output parameters [%d] ==============\n"
"chunk_size: %d \n"
"min_chunk_size: %d \n"
@@ -1323,19 +1346,19 @@ static void dcn10_enable_plane(
undo_DEGVIDCN10_253_wa(dc);
power_on_plane(dc->hwseq,
- pipe_ctx->pipe_idx);
+ pipe_ctx->plane_res.hubp->inst);
/* enable DCFCLK current DCHUB */
- REG_UPDATE(HUBP_CLK_CNTL[pipe_ctx->pipe_idx],
- HUBP_CLOCK_ENABLE, 1);
+ pipe_ctx->plane_res.hubp->funcs->hubp_clk_cntl(pipe_ctx->plane_res.hubp, true);
/* make sure OPP_PIPE_CLOCK_EN = 1 */
- REG_UPDATE(OPP_PIPE_CONTROL[pipe_ctx->stream_res.tg->inst],
- OPP_PIPE_CLOCK_EN, 1);
+ pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control(
+ pipe_ctx->stream_res.opp,
+ true);
/* TODO: enable/disable in dm as per update type.
if (plane_state) {
- dm_logger_write(dc->ctx->logger, LOG_DC,
+ DC_LOG_DC(dc->ctx->logger,
"Pipe:%d 0x%x: addr hi:0x%x, "
"addr low:0x%x, "
"src: %d, %d, %d,"
@@ -1353,7 +1376,7 @@ static void dcn10_enable_plane(
plane_state->dst_rect.width,
plane_state->dst_rect.height);
- dm_logger_write(dc->ctx->logger, LOG_DC,
+ DC_LOG_DC(dc->ctx->logger,
"Pipe %d: width, height, x, y format:%d\n"
"viewport:%d, %d, %d, %d\n"
"recout: %d, %d, %d, %d\n",
@@ -1380,6 +1403,7 @@ static void dcn10_enable_plane(
static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
{
+ int i = 0;
struct dpp_grph_csc_adjustment adjust;
memset(&adjust, 0, sizeof(adjust));
adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
@@ -1387,33 +1411,9 @@ static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
- adjust.temperature_matrix[0] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[0];
- adjust.temperature_matrix[1] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[1];
- adjust.temperature_matrix[2] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[2];
- adjust.temperature_matrix[3] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[4];
- adjust.temperature_matrix[4] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[5];
- adjust.temperature_matrix[5] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[6];
- adjust.temperature_matrix[6] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[8];
- adjust.temperature_matrix[7] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[9];
- adjust.temperature_matrix[8] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[10];
+ for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
+ adjust.temperature_matrix[i] =
+ pipe_ctx->stream->gamut_remap_matrix.matrix[i];
}
pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp, &adjust);
@@ -1474,7 +1474,7 @@ static bool is_pipe_tree_visible(struct pipe_ctx *pipe_ctx)
return false;
}
-static bool is_rgb_cspace(enum dc_color_space output_color_space)
+bool is_rgb_cspace(enum dc_color_space output_color_space)
{
switch (output_color_space) {
case COLOR_SPACE_SRGB:
@@ -1612,6 +1612,7 @@ static void update_dpp(struct dpp *dpp, struct dc_plane_state *plane_state)
dpp->funcs->dpp_program_bias_and_scale(dpp, &bns_params);
}
+
static void update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
struct hubp *hubp = pipe_ctx->plane_res.hubp;
@@ -1702,22 +1703,28 @@ static void update_dchubp_dpp(
struct pipe_ctx *pipe_ctx,
struct dc_state *context)
{
- struct dce_hwseq *hws = dc->hwseq;
struct hubp *hubp = pipe_ctx->plane_res.hubp;
struct dpp *dpp = pipe_ctx->plane_res.dpp;
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
union plane_size size = plane_state->plane_size;
/* depends on DML calculation, DPP clock value may change dynamically */
+ /* If request max dpp clk is lower than current dispclk, no need to
+ * divided by 2
+ */
if (plane_state->update_flags.bits.full_update) {
- enable_dppclk(
- dc->hwseq,
- pipe_ctx->pipe_idx,
- pipe_ctx->stream_res.pix_clk_params.requested_pix_clk,
- context->bw.dcn.calc_clk.dppclk_div);
- dc->current_state->bw.dcn.cur_clk.dppclk_div =
- context->bw.dcn.calc_clk.dppclk_div;
- context->bw.dcn.cur_clk.dppclk_div = context->bw.dcn.calc_clk.dppclk_div;
+ bool should_divided_by_2 = context->bw.dcn.calc_clk.dppclk_khz <=
+ context->bw.dcn.cur_clk.dispclk_khz / 2;
+
+ dpp->funcs->dpp_dppclk_control(
+ dpp,
+ should_divided_by_2,
+ true);
+
+ dc->current_state->bw.dcn.cur_clk.dppclk_khz =
+ should_divided_by_2 ?
+ context->bw.dcn.cur_clk.dispclk_khz / 2 :
+ context->bw.dcn.cur_clk.dispclk_khz;
}
/* TODO: Need input parameter to tell current DCHUB pipe tie to which OTG
@@ -1725,7 +1732,7 @@ static void update_dchubp_dpp(
* VTG is 1:1 mapping with OTG. Each pipe HUBP will select which VTG
*/
if (plane_state->update_flags.bits.full_update) {
- REG_UPDATE(DCHUBP_CNTL[pipe_ctx->pipe_idx], HUBP_VTG_SEL, pipe_ctx->stream_res.tg->inst);
+ hubp->funcs->hubp_vtg_sel(hubp, pipe_ctx->stream_res.tg->inst);
hubp->funcs->hubp_setup(
hubp,
@@ -1761,6 +1768,11 @@ static void update_dchubp_dpp(
&pipe_ctx->plane_res.scl_data.viewport_c);
}
+ if (pipe_ctx->stream->cursor_attributes.address.quad_part != 0) {
+ dc->hwss.set_cursor_position(pipe_ctx);
+ dc->hwss.set_cursor_attribute(pipe_ctx);
+ }
+
if (plane_state->update_flags.bits.full_update) {
/*gamut remap*/
program_gamut_remap(pipe_ctx);
@@ -1773,6 +1785,7 @@ static void update_dchubp_dpp(
}
if (plane_state->update_flags.bits.full_update ||
+ plane_state->update_flags.bits.pixel_format_change ||
plane_state->update_flags.bits.horizontal_mirror_change ||
plane_state->update_flags.bits.rotation_change ||
plane_state->update_flags.bits.swizzle_change ||
@@ -1797,14 +1810,62 @@ static void update_dchubp_dpp(
hubp->funcs->set_blank(hubp, false);
}
+static void dcn10_otg_blank(
+ struct dc *dc,
+ struct stream_resource stream_res,
+ struct dc_stream_state *stream,
+ bool blank)
+{
+ enum dc_color_space color_space;
+ struct tg_color black_color = {0};
+
+ /* program otg blank color */
+ color_space = stream->output_color_space;
+ color_space_to_black_color(dc, color_space, &black_color);
+
+ if (stream_res.tg->funcs->set_blank_color)
+ stream_res.tg->funcs->set_blank_color(
+ stream_res.tg,
+ &black_color);
+
+ if (!blank) {
+ if (stream_res.tg->funcs->set_blank)
+ stream_res.tg->funcs->set_blank(stream_res.tg, blank);
+ if (stream_res.abm)
+ stream_res.abm->funcs->set_abm_level(stream_res.abm, stream->abm_level);
+ } else if (blank) {
+ if (stream_res.abm)
+ stream_res.abm->funcs->set_abm_immediate_disable(stream_res.abm);
+ if (stream_res.tg->funcs->set_blank)
+ stream_res.tg->funcs->set_blank(stream_res.tg, blank);
+ }
+}
+
+static void set_hdr_multiplier(struct pipe_ctx *pipe_ctx)
+{
+ struct fixed31_32 multiplier = dal_fixed31_32_from_fraction(
+ pipe_ctx->plane_state->sdr_white_level, 80);
+ uint32_t hw_mult = 0x1f000; // 1.0 default multiplier
+ struct custom_float_format fmt;
+
+ fmt.exponenta_bits = 6;
+ fmt.mantissa_bits = 12;
+ fmt.sign = true;
+
+ if (pipe_ctx->plane_state->sdr_white_level > 80)
+ convert_to_custom_float_format(multiplier, &fmt, &hw_mult);
+
+ pipe_ctx->plane_res.dpp->funcs->dpp_set_hdr_multiplier(
+ pipe_ctx->plane_res.dpp, hw_mult);
+}
static void program_all_pipe_in_tree(
struct dc *dc,
struct pipe_ctx *pipe_ctx,
struct dc_state *context)
{
-
if (pipe_ctx->top_pipe == NULL) {
+ bool blank = !is_pipe_tree_visible(pipe_ctx);
pipe_ctx->stream_res.tg->dlg_otg_param.vready_offset = pipe_ctx->pipe_dlg_param.vready_offset;
pipe_ctx->stream_res.tg->dlg_otg_param.vstartup_start = pipe_ctx->pipe_dlg_param.vstartup_start;
@@ -1815,22 +1876,21 @@ static void program_all_pipe_in_tree(
pipe_ctx->stream_res.tg->funcs->program_global_sync(
pipe_ctx->stream_res.tg);
- if (pipe_ctx->stream_res.tg->funcs->set_blank)
- pipe_ctx->stream_res.tg->funcs->set_blank(
- pipe_ctx->stream_res.tg,
- !is_pipe_tree_visible(pipe_ctx));
+ dcn10_otg_blank(dc, pipe_ctx->stream_res,
+ pipe_ctx->stream, blank);
}
if (pipe_ctx->plane_state != NULL) {
- struct pipe_ctx *cur_pipe_ctx =
- &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
-
if (pipe_ctx->plane_state->update_flags.bits.full_update)
dcn10_enable_plane(dc, pipe_ctx, context);
update_dchubp_dpp(dc, pipe_ctx, context);
- if (cur_pipe_ctx->plane_state != pipe_ctx->plane_state)
+ set_hdr_multiplier(pipe_ctx);
+
+ if (pipe_ctx->plane_state->update_flags.bits.full_update ||
+ pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
+ pipe_ctx->plane_state->update_flags.bits.gamma_change)
dc->hwss.set_input_transfer_func(pipe_ctx, pipe_ctx->plane_state);
/* dcn10_translate_regamma_to_hw_format takes 750us to finish
@@ -1843,8 +1903,9 @@ static void program_all_pipe_in_tree(
dc->hwss.set_output_transfer_func(pipe_ctx, pipe_ctx->stream);
}
- if (pipe_ctx->bottom_pipe != NULL && pipe_ctx->bottom_pipe != pipe_ctx)
+ if (pipe_ctx->bottom_pipe != NULL && pipe_ctx->bottom_pipe != pipe_ctx) {
program_all_pipe_in_tree(dc, pipe_ctx->bottom_pipe, context);
+ }
}
static void dcn10_pplib_apply_display_requirements(
@@ -1853,16 +1914,10 @@ static void dcn10_pplib_apply_display_requirements(
{
struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg;
- pp_display_cfg->all_displays_in_sync = false;/*todo*/
- pp_display_cfg->nb_pstate_switch_disable = false;
pp_display_cfg->min_engine_clock_khz = context->bw.dcn.cur_clk.dcfclk_khz;
pp_display_cfg->min_memory_clock_khz = context->bw.dcn.cur_clk.fclk_khz;
pp_display_cfg->min_engine_clock_deep_sleep_khz = context->bw.dcn.cur_clk.dcfclk_deep_sleep_khz;
pp_display_cfg->min_dcfc_deep_sleep_clock_khz = context->bw.dcn.cur_clk.dcfclk_deep_sleep_khz;
- pp_display_cfg->avail_mclk_switch_time_us =
- context->bw.dcn.cur_clk.dram_ccm_us > 0 ? context->bw.dcn.cur_clk.dram_ccm_us : 0;
- pp_display_cfg->avail_mclk_switch_time_in_disp_active_us =
- context->bw.dcn.cur_clk.min_active_dram_ccm_us > 0 ? context->bw.dcn.cur_clk.min_active_dram_ccm_us : 0;
pp_display_cfg->min_dcfclock_khz = context->bw.dcn.cur_clk.dcfclk_khz;
pp_display_cfg->disp_clk_khz = context->bw.dcn.cur_clk.dispclk_khz;
dce110_fill_display_configs(context, pp_display_cfg);
@@ -1925,28 +1980,23 @@ static void dcn10_apply_ctx_for_surface(
{
int i;
struct timing_generator *tg;
- struct output_pixel_processor *opp;
bool removed_pipe[4] = { false };
unsigned int ref_clk_mhz = dc->res_pool->ref_clock_inKhz/1000;
bool program_water_mark = false;
-
+ struct dc_context *ctx = dc->ctx;
struct pipe_ctx *top_pipe_to_program =
find_top_pipe_for_stream(dc, context, stream);
if (!top_pipe_to_program)
return;
- opp = top_pipe_to_program->stream_res.opp;
-
tg = top_pipe_to_program->stream_res.tg;
- tg->funcs->lock(tg);
+ dcn10_pipe_control_lock(dc, top_pipe_to_program, true);
if (num_planes == 0) {
-
/* OTG blank before remove all front end */
- if (tg->funcs->set_blank)
- tg->funcs->set_blank(tg, true);
+ dcn10_otg_blank(dc, top_pipe_to_program->stream_res, top_pipe_to_program->stream, true);
}
/* Disconnect unused mpcc */
@@ -1964,7 +2014,7 @@ static void dcn10_apply_ctx_for_surface(
if (old_pipe_ctx->stream_res.tg == tg &&
old_pipe_ctx->plane_res.hubp &&
old_pipe_ctx->plane_res.hubp->opp_id != 0xf) {
- dcn10_disable_plane(dc, pipe_ctx);
+ dcn10_disable_plane(dc, old_pipe_ctx);
/*
* power down fe will unlock when calling reset, need
* to lock it back here. Messy, need rework.
@@ -1980,7 +2030,7 @@ static void dcn10_apply_ctx_for_surface(
plane_atomic_disconnect(dc, old_pipe_ctx);
removed_pipe[i] = true;
- dm_logger_write(dc->ctx->logger, LOG_DC,
+ DC_LOG_DC(
"Reset mpcc for pipe %d\n",
old_pipe_ctx->pipe_idx);
}
@@ -1989,7 +2039,7 @@ static void dcn10_apply_ctx_for_surface(
if (num_planes > 0)
program_all_pipe_in_tree(dc, top_pipe_to_program, context);
- tg->funcs->unlock(tg);
+ dcn10_pipe_control_lock(dc, top_pipe_to_program, false);
if (num_planes == 0)
false_optc_underflow_wa(dc, stream, tg);
@@ -2023,7 +2073,7 @@ static void dcn10_apply_ctx_for_surface(
dcn10_verify_allow_pstate_change_high(dc);
}
}
-/* dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_CALCS,
+/* DC_LOG_BANDWIDTH_CALCS(dc->ctx->logger,
"\n============== Watermark parameters ==============\n"
"a.urgent_ns: %d \n"
"a.cstate_enter_plus_exit: %d \n"
@@ -2046,7 +2096,7 @@ static void dcn10_apply_ctx_for_surface(
context->bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns,
context->bw.dcn.watermarks.b.pte_meta_urgent_ns
);
- dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_CALCS,
+ DC_LOG_BANDWIDTH_CALCS(dc->ctx->logger,
"\nc.urgent_ns: %d \n"
"c.cstate_enter_plus_exit: %d \n"
"c.cstate_exit: %d \n"
@@ -2072,6 +2122,101 @@ static void dcn10_apply_ctx_for_surface(
*/
}
+static inline bool should_set_clock(bool decrease_allowed, int calc_clk, int cur_clk)
+{
+ return ((decrease_allowed && calc_clk < cur_clk) || calc_clk > cur_clk);
+}
+
+static int determine_dppclk_threshold(struct dc *dc, struct dc_state *context)
+{
+ bool request_dpp_div = context->bw.dcn.calc_clk.dispclk_khz >
+ context->bw.dcn.calc_clk.dppclk_khz;
+ bool dispclk_increase = context->bw.dcn.calc_clk.dispclk_khz >
+ context->bw.dcn.cur_clk.dispclk_khz;
+ int disp_clk_threshold = context->bw.dcn.calc_clk.max_supported_dppclk_khz;
+ bool cur_dpp_div = context->bw.dcn.cur_clk.dispclk_khz >
+ context->bw.dcn.cur_clk.dppclk_khz;
+
+ /* increase clock, looking for div is 0 for current, request div is 1*/
+ if (dispclk_increase) {
+ /* already divided by 2, no need to reach target clk with 2 steps*/
+ if (cur_dpp_div)
+ return context->bw.dcn.calc_clk.dispclk_khz;
+
+ /* request disp clk is lower than maximum supported dpp clk,
+ * no need to reach target clk with two steps.
+ */
+ if (context->bw.dcn.calc_clk.dispclk_khz <= disp_clk_threshold)
+ return context->bw.dcn.calc_clk.dispclk_khz;
+
+ /* target dpp clk not request divided by 2, still within threshold */
+ if (!request_dpp_div)
+ return context->bw.dcn.calc_clk.dispclk_khz;
+
+ } else {
+ /* decrease clock, looking for current dppclk divided by 2,
+ * request dppclk not divided by 2.
+ */
+
+ /* current dpp clk not divided by 2, no need to ramp*/
+ if (!cur_dpp_div)
+ return context->bw.dcn.calc_clk.dispclk_khz;
+
+ /* current disp clk is lower than current maximum dpp clk,
+ * no need to ramp
+ */
+ if (context->bw.dcn.cur_clk.dispclk_khz <= disp_clk_threshold)
+ return context->bw.dcn.calc_clk.dispclk_khz;
+
+ /* request dpp clk need to be divided by 2 */
+ if (request_dpp_div)
+ return context->bw.dcn.calc_clk.dispclk_khz;
+ }
+
+ return disp_clk_threshold;
+}
+
+static void ramp_up_dispclk_with_dpp(struct dc *dc, struct dc_state *context)
+{
+ int i;
+ bool request_dpp_div = context->bw.dcn.calc_clk.dispclk_khz >
+ context->bw.dcn.calc_clk.dppclk_khz;
+
+ int dispclk_to_dpp_threshold = determine_dppclk_threshold(dc, context);
+
+ /* set disp clk to dpp clk threshold */
+ dc->res_pool->display_clock->funcs->set_clock(
+ dc->res_pool->display_clock,
+ dispclk_to_dpp_threshold);
+
+ /* update request dpp clk division option */
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
+
+ if (!pipe_ctx->plane_state)
+ continue;
+
+ pipe_ctx->plane_res.dpp->funcs->dpp_dppclk_control(
+ pipe_ctx->plane_res.dpp,
+ request_dpp_div,
+ true);
+ }
+
+ /* If target clk not same as dppclk threshold, set to target clock */
+ if (dispclk_to_dpp_threshold != context->bw.dcn.calc_clk.dispclk_khz) {
+ dc->res_pool->display_clock->funcs->set_clock(
+ dc->res_pool->display_clock,
+ context->bw.dcn.calc_clk.dispclk_khz);
+ }
+
+ context->bw.dcn.cur_clk.dispclk_khz =
+ context->bw.dcn.calc_clk.dispclk_khz;
+ context->bw.dcn.cur_clk.dppclk_khz =
+ context->bw.dcn.calc_clk.dppclk_khz;
+ context->bw.dcn.cur_clk.max_supported_dppclk_khz =
+ context->bw.dcn.calc_clk.max_supported_dppclk_khz;
+}
+
static void dcn10_set_bandwidth(
struct dc *dc,
struct dc_state *context,
@@ -2089,31 +2234,33 @@ static void dcn10_set_bandwidth(
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
return;
- if (decrease_allowed || context->bw.dcn.calc_clk.dispclk_khz
- > dc->current_state->bw.dcn.cur_clk.dispclk_khz) {
- dc->res_pool->display_clock->funcs->set_clock(
- dc->res_pool->display_clock,
- context->bw.dcn.calc_clk.dispclk_khz);
- dc->current_state->bw.dcn.cur_clk.dispclk_khz =
- context->bw.dcn.calc_clk.dispclk_khz;
- }
- if (decrease_allowed || context->bw.dcn.calc_clk.dcfclk_khz
- > dc->current_state->bw.dcn.cur_clk.dcfclk_khz) {
+ if (should_set_clock(
+ decrease_allowed,
+ context->bw.dcn.calc_clk.dcfclk_khz,
+ dc->current_state->bw.dcn.cur_clk.dcfclk_khz)) {
+ context->bw.dcn.cur_clk.dcfclk_khz =
+ context->bw.dcn.calc_clk.dcfclk_khz;
smu_req.hard_min_dcefclk_khz =
context->bw.dcn.calc_clk.dcfclk_khz;
}
- if (decrease_allowed || context->bw.dcn.calc_clk.fclk_khz
- > dc->current_state->bw.dcn.cur_clk.fclk_khz) {
- smu_req.hard_min_fclk_khz = context->bw.dcn.calc_clk.fclk_khz;
- }
- if (decrease_allowed || context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz
- > dc->current_state->bw.dcn.cur_clk.dcfclk_deep_sleep_khz) {
- dc->current_state->bw.dcn.calc_clk.dcfclk_deep_sleep_khz =
- context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz;
+
+ if (should_set_clock(
+ decrease_allowed,
+ context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz,
+ dc->current_state->bw.dcn.cur_clk.dcfclk_deep_sleep_khz)) {
context->bw.dcn.cur_clk.dcfclk_deep_sleep_khz =
context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz;
}
+ if (should_set_clock(
+ decrease_allowed,
+ context->bw.dcn.calc_clk.fclk_khz,
+ dc->current_state->bw.dcn.cur_clk.fclk_khz)) {
+ context->bw.dcn.cur_clk.fclk_khz =
+ context->bw.dcn.calc_clk.fclk_khz;
+ smu_req.hard_min_fclk_khz = context->bw.dcn.calc_clk.fclk_khz;
+ }
+
smu_req.display_count = context->stream_count;
if (pp_smu->set_display_requirement)
@@ -2121,21 +2268,17 @@ static void dcn10_set_bandwidth(
*smu_req_cur = smu_req;
- /* Decrease in freq is increase in period so opposite comparison for dram_ccm */
- if (decrease_allowed || context->bw.dcn.calc_clk.dram_ccm_us
- < dc->current_state->bw.dcn.cur_clk.dram_ccm_us) {
- dc->current_state->bw.dcn.calc_clk.dram_ccm_us =
- context->bw.dcn.calc_clk.dram_ccm_us;
- context->bw.dcn.cur_clk.dram_ccm_us =
- context->bw.dcn.calc_clk.dram_ccm_us;
- }
- if (decrease_allowed || context->bw.dcn.calc_clk.min_active_dram_ccm_us
- < dc->current_state->bw.dcn.cur_clk.min_active_dram_ccm_us) {
- dc->current_state->bw.dcn.calc_clk.min_active_dram_ccm_us =
- context->bw.dcn.calc_clk.min_active_dram_ccm_us;
- context->bw.dcn.cur_clk.min_active_dram_ccm_us =
- context->bw.dcn.calc_clk.min_active_dram_ccm_us;
+ /* make sure dcf clk is before dpp clk to
+ * make sure we have enough voltage to run dpp clk
+ */
+ if (should_set_clock(
+ decrease_allowed,
+ context->bw.dcn.calc_clk.dispclk_khz,
+ dc->current_state->bw.dcn.cur_clk.dispclk_khz)) {
+
+ ramp_up_dispclk_with_dpp(dc, context);
}
+
dcn10_pplib_apply_display_requirements(dc, context);
if (dc->debug.sanity_checks) {
@@ -2184,6 +2327,8 @@ static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
value |= 0x80;
if (events->cursor_update)
value |= 0x2;
+ if (events->force_trigger)
+ value |= 0x1;
for (i = 0; i < num_pipes; i++)
pipe_ctx[i]->stream_res.tg->funcs->
@@ -2256,12 +2401,24 @@ static void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct dc *dc)
return;
}
+static struct hubp *get_hubp_by_inst(struct resource_pool *res_pool, int mpcc_inst)
+{
+ int i;
+
+ for (i = 0; i < res_pool->pipe_count; i++) {
+ if (res_pool->hubps[i]->inst == mpcc_inst)
+ return res_pool->hubps[i];
+ }
+ ASSERT(false);
+ return NULL;
+}
+
static void dcn10_wait_for_mpcc_disconnect(
struct dc *dc,
struct resource_pool *res_pool,
struct pipe_ctx *pipe_ctx)
{
- int i;
+ int mpcc_inst;
if (dc->debug.sanity_checks) {
dcn10_verify_allow_pstate_change_high(dc);
@@ -2270,12 +2427,14 @@ static void dcn10_wait_for_mpcc_disconnect(
if (!pipe_ctx->stream_res.opp)
return;
- for (i = 0; i < MAX_PIPES; i++) {
- if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i]) {
- res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, i);
- pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i] = false;
- res_pool->hubps[i]->funcs->set_blank(res_pool->hubps[i], true);
- /*dm_logger_write(dc->ctx->logger, LOG_ERROR,
+ for (mpcc_inst = 0; mpcc_inst < MAX_PIPES; mpcc_inst++) {
+ if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst]) {
+ struct hubp *hubp = get_hubp_by_inst(res_pool, mpcc_inst);
+
+ res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, mpcc_inst);
+ pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst] = false;
+ hubp->funcs->set_blank(hubp, true);
+ /*DC_LOG_ERROR(dc->ctx->logger,
"[debug_mpo: wait_for_mpcc finished waiting on mpcc %d]\n",
i);*/
}
@@ -2296,7 +2455,7 @@ static bool dcn10_dummy_display_power_gating(
return true;
}
-void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
+static void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
{
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
struct timing_generator *tg = pipe_ctx->stream_res.tg;
@@ -2316,12 +2475,46 @@ void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
}
}
-void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
+static void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
{
if (hws->ctx->dc->res_pool->hubbub != NULL)
hubbub1_update_dchub(hws->ctx->dc->res_pool->hubbub, dh_data);
}
+static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
+{
+ struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
+ struct hubp *hubp = pipe_ctx->plane_res.hubp;
+ struct dpp *dpp = pipe_ctx->plane_res.dpp;
+ struct dc_cursor_mi_param param = {
+ .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz,
+ .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz,
+ .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x,
+ .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width,
+ .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz
+ };
+
+ if (pipe_ctx->plane_state->address.type
+ == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
+ pos_cpy.enable = false;
+
+ if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
+ pos_cpy.enable = false;
+
+ hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
+ dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width);
+}
+
+static void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
+{
+ struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
+
+ pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
+ pipe_ctx->plane_res.hubp, attributes);
+ pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
+ pipe_ctx->plane_res.dpp, attributes->color_format);
+}
+
static const struct hw_sequencer_funcs dcn10_funcs = {
.program_gamut_remap = program_gamut_remap,
.program_csc_matrix = program_csc_matrix,
@@ -2342,6 +2535,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.enable_stream = dce110_enable_stream,
.disable_stream = dce110_disable_stream,
.unblank_stream = dce110_unblank_stream,
+ .blank_stream = dce110_blank_stream,
.enable_display_power_gating = dcn10_dummy_display_power_gating,
.disable_plane = dcn10_disable_plane,
.pipe_control_lock = dcn10_pipe_control_lock,
@@ -2362,6 +2556,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.edp_backlight_control = hwss_edp_backlight_control,
.edp_power_control = hwss_edp_power_control,
.edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
+ .set_cursor_position = dcn10_set_cursor_position,
+ .set_cursor_attribute = dcn10_set_cursor_attribute
};
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
index b9d326082717..6c526b5095d9 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
@@ -35,5 +35,6 @@ extern void fill_display_configs(
const struct dc_state *context,
struct dm_pp_display_configuration *pp_display_cfg);
+bool is_rgb_cspace(enum dc_color_space output_color_space);
#endif /* __DC_HWSS_DCN10_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h
index d7b5bd20352a..819b749c6e31 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h
@@ -33,7 +33,6 @@
#define IPP_REG_LIST_DCN(id) \
SRI(FORMAT_CONTROL, CNVC_CFG, id), \
- SRI(DPP_CONTROL, DPP_TOP, id), \
SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \
SRI(CURSOR0_CONTROL, CNVC_CUR, id), \
SRI(CURSOR0_COLOR0, CNVC_CUR, id), \
@@ -130,7 +129,6 @@ struct dcn10_ipp_mask {
};
struct dcn10_ipp_registers {
- uint32_t DPP_CONTROL;
uint32_t CURSOR_SETTINS;
uint32_t CURSOR_SETTINGS;
uint32_t CNVC_SURFACE_PIXEL_FORMAT;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
index f6ba0eef4489..77a1a9d541a4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
@@ -367,6 +367,14 @@ void opp1_program_oppbuf(
}
+void opp1_pipe_clock_control(struct output_pixel_processor *opp, bool enable)
+{
+ struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp);
+ uint32_t regval = enable ? 1 : 0;
+
+ REG_UPDATE(OPP_PIPE_CONTROL, OPP_PIPE_CLOCK_EN, regval);
+}
+
/*****************************************/
/* Constructor, Destructor */
/*****************************************/
@@ -382,6 +390,7 @@ static struct opp_funcs dcn10_opp_funcs = {
.opp_program_fmt = opp1_program_fmt,
.opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction,
.opp_program_stereo = opp1_program_stereo,
+ .opp_pipe_clock_control = opp1_pipe_clock_control,
.opp_destroy = opp1_destroy
};
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h
index bc5058af6266..0f10adea000c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h
@@ -44,7 +44,8 @@
SRI(FMT_MAP420_MEMORY_CONTROL, FMT, id), \
SRI(OPPBUF_CONTROL, OPPBUF, id),\
SRI(OPPBUF_3D_PARAMETERS_0, OPPBUF, id), \
- SRI(OPPBUF_3D_PARAMETERS_1, OPPBUF, id)
+ SRI(OPPBUF_3D_PARAMETERS_1, OPPBUF, id), \
+ SRI(OPP_PIPE_CONTROL, OPP_PIPE, id)
#define OPP_REG_LIST_DCN10(id) \
OPP_REG_LIST_DCN(id)
@@ -61,7 +62,8 @@
uint32_t OPPBUF_CONTROL; \
uint32_t OPPBUF_CONTROL1; \
uint32_t OPPBUF_3D_PARAMETERS_0; \
- uint32_t OPPBUF_3D_PARAMETERS_1
+ uint32_t OPPBUF_3D_PARAMETERS_1; \
+ uint32_t OPP_PIPE_CONTROL
#define OPP_MASK_SH_LIST_DCN(mask_sh) \
OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN, mask_sh), \
@@ -89,7 +91,8 @@
OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_ACTIVE_WIDTH, mask_sh),\
OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_PIXEL_REPETITION, mask_sh),\
OPP_SF(OPPBUF0_OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE1_SIZE, mask_sh), \
- OPP_SF(OPPBUF0_OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE2_SIZE, mask_sh)
+ OPP_SF(OPPBUF0_OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE2_SIZE, mask_sh), \
+ OPP_SF(OPP_PIPE0_OPP_PIPE_CONTROL, OPP_PIPE_CLOCK_EN, mask_sh)
#define OPP_MASK_SH_LIST_DCN10(mask_sh) \
OPP_MASK_SH_LIST_DCN(mask_sh), \
@@ -125,7 +128,8 @@
type OPPBUF_OVERLAP_PIXEL_NUM;\
type OPPBUF_NUM_SEGMENT_PADDED_PIXELS; \
type OPPBUF_3D_VACT_SPACE1_SIZE; \
- type OPPBUF_3D_VACT_SPACE2_SIZE
+ type OPPBUF_3D_VACT_SPACE2_SIZE; \
+ type OPP_PIPE_CLOCK_EN
struct dcn10_opp_registers {
OPP_COMMON_REG_VARIABLE_LIST;
@@ -176,6 +180,8 @@ void opp1_program_stereo(
bool enable,
const struct dc_crtc_timing *timing);
+void opp1_pipe_clock_control(struct output_pixel_processor *opp, bool enable);
+
void opp1_destroy(struct output_pixel_processor **opp);
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
index a3c7c2012f05..d25e7bf0d0d7 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
@@ -83,6 +83,8 @@
struct dcn_optc_registers {
+ uint32_t OTG_GLOBAL_CONTROL1;
+ uint32_t OTG_GLOBAL_CONTROL2;
uint32_t OTG_VERT_SYNC_CONTROL;
uint32_t OTG_MASTER_UPDATE_MODE;
uint32_t OTG_GSL_CONTROL;
@@ -126,12 +128,12 @@ struct dcn_optc_registers {
uint32_t OTG_VERTICAL_INTERRUPT2_POSITION;
uint32_t OPTC_INPUT_CLOCK_CONTROL;
uint32_t OPTC_DATA_SOURCE_SELECT;
+ uint32_t OPTC_MEMORY_CONFIG;
uint32_t OPTC_INPUT_GLOBAL_CONTROL;
uint32_t CONTROL;
uint32_t OTG_GSL_WINDOW_X;
uint32_t OTG_GSL_WINDOW_Y;
uint32_t OTG_VUPDATE_KEEPOUT;
- uint32_t OTG_DSC_START_POSITION;
};
#define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\
@@ -241,7 +243,7 @@ struct dcn_optc_registers {
SF(OTG0_OTG_TEST_PATTERN_COLOR, OTG_TEST_PATTERN_DATA, mask_sh),\
SF(ODM0_OPTC_DATA_SOURCE_SELECT, OPTC_SRC_SEL, mask_sh)
-#define TG_REG_FIELD_LIST(type) \
+#define TG_REG_FIELD_LIST_DCN1_0(type) \
type VSTARTUP_START;\
type VUPDATE_OFFSET;\
type VUPDATE_WIDTH;\
@@ -326,10 +328,9 @@ struct dcn_optc_registers {
type OPTC_INPUT_CLK_EN;\
type OPTC_INPUT_CLK_ON;\
type OPTC_INPUT_CLK_GATE_DIS;\
- type OPTC_SRC_SEL;\
- type OPTC_SEG0_SRC_SEL;\
type OPTC_UNDERFLOW_OCCURRED_STATUS;\
type OPTC_UNDERFLOW_CLEAR;\
+ type OPTC_SRC_SEL;\
type VTG0_ENABLE;\
type VTG0_FP2;\
type VTG0_VCOUNT_INIT;\
@@ -352,10 +353,11 @@ struct dcn_optc_registers {
type OTG_MASTER_UPDATE_LOCK_GSL_EN;\
type MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET;\
type MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET;\
- type OTG_DSC_START_POSITION_X;\
- type OTG_DSC_START_POSITION_LINE_NUM;\
type OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN;
+#define TG_REG_FIELD_LIST(type) \
+ TG_REG_FIELD_LIST_DCN1_0(type)
+
struct dcn_optc_shift {
TG_REG_FIELD_LIST(uint8_t)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
index 44825e2c9ebb..02bd664aed3e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -50,7 +50,8 @@
#include "dcn10_hubp.h"
#include "dcn10_hubbub.h"
-#include "soc15ip.h"
+#include "soc15_hw_ip.h"
+#include "vega10_ip_offset.h"
#include "dcn/dcn_1_0_offset.h"
#include "dcn/dcn_1_0_sh_mask.h"
@@ -365,6 +366,7 @@ static const struct dcn_optc_mask tg_mask = {
static const struct bios_registers bios_regs = {
+ NBIO_SR(BIOS_SCRATCH_3),
NBIO_SR(BIOS_SCRATCH_6)
};
@@ -438,7 +440,11 @@ static const struct dc_debug debug_defaults_drv = {
.timing_trace = false,
.clock_trace = true,
- .min_disp_clk_khz = 300000,
+ /* raven smu dones't allow 0 disp clk,
+ * smu min disp clk limit is 50Mhz
+ * keep min disp clk 100Mhz avoid smu hang
+ */
+ .min_disp_clk_khz = 100000,
.disable_pplib_clock_request = true,
.disable_pplib_wm_range = false,
@@ -450,6 +456,7 @@ static const struct dc_debug debug_defaults_drv = {
.disable_stereo_support = true,
.vsr_support = true,
.performance_trace = false,
+ .az_endpoint_mute_only = true,
};
static const struct dc_debug debug_defaults_diags = {
@@ -818,7 +825,7 @@ static void get_pixel_clock_parameters(
pixel_clk_params->requested_pix_clk = stream->timing.pix_clk_khz;
pixel_clk_params->encoder_object_id = stream->sink->link->link_enc->id;
pixel_clk_params->signal_type = pipe_ctx->stream->signal;
- pixel_clk_params->controller_id = pipe_ctx->pipe_idx + 1;
+ pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1;
/* TODO: un-hardcode*/
pixel_clk_params->requested_sym_clk = LINK_RATE_LOW *
LINK_RATE_REF_FREQ_IN_KHZ;
@@ -960,11 +967,13 @@ static struct pipe_ctx *dcn10_acquire_idle_pipe_for_layer(
idle_pipe->stream = head_pipe->stream;
idle_pipe->stream_res.tg = head_pipe->stream_res.tg;
+ idle_pipe->stream_res.abm = head_pipe->stream_res.abm;
idle_pipe->stream_res.opp = head_pipe->stream_res.opp;
idle_pipe->plane_res.hubp = pool->hubps[idle_pipe->pipe_idx];
idle_pipe->plane_res.ipp = pool->ipps[idle_pipe->pipe_idx];
idle_pipe->plane_res.dpp = pool->dpps[idle_pipe->pipe_idx];
+ idle_pipe->plane_res.mpcc_inst = pool->dpps[idle_pipe->pipe_idx]->inst;
return idle_pipe;
}
@@ -1316,13 +1325,11 @@ static bool construct(
}
}
- if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
- pool->base.display_clock = dce120_disp_clk_create(ctx);
- if (pool->base.display_clock == NULL) {
- dm_error("DC: failed to create display clock!\n");
- BREAK_TO_DEBUGGER();
- goto fail;
- }
+ pool->base.display_clock = dce120_disp_clk_create(ctx);
+ if (pool->base.display_clock == NULL) {
+ dm_error("DC: failed to create display clock!\n");
+ BREAK_TO_DEBUGGER();
+ goto fail;
}
pool->base.dmcu = dcn10_dmcu_create(ctx,
@@ -1445,6 +1452,7 @@ static bool construct(
/* valid pipe num */
pool->base.pipe_count = j;
+ pool->base.timing_generator_count = j;
/* within dml lib, it is hard code to 4. If ASIC pipe is fused,
* the value may be changed