forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
....@@ -734,8 +734,13 @@
734734 CRTC_OVERSCAN_COLOR_RED, overscan_color->color_r_cr);
735735 }
736736
737
-void dce120_tg_program_timing(struct timing_generator *tg,
737
+static void dce120_tg_program_timing(struct timing_generator *tg,
738738 const struct dc_crtc_timing *timing,
739
+ int vready_offset,
740
+ int vstartup_start,
741
+ int vupdate_offset,
742
+ int vupdate_width,
743
+ const enum signal_type signal,
739744 bool use_vbios)
740745 {
741746 if (use_vbios)
....@@ -814,13 +819,18 @@
814819
815820 static void dce120_timing_generator_set_static_screen_control(
816821 struct timing_generator *tg,
817
- uint32_t value)
822
+ uint32_t event_triggers,
823
+ uint32_t num_frames)
818824 {
819825 struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
820826
827
+ // By register spec, it only takes 8 bit value
828
+ if (num_frames > 0xFF)
829
+ num_frames = 0xFF;
830
+
821831 CRTC_REG_UPDATE_2(CRTC0_CRTC_STATIC_SCREEN_CONTROL,
822
- CRTC_STATIC_SCREEN_EVENT_MASK, value,
823
- CRTC_STATIC_SCREEN_FRAME_COUNT, 2);
832
+ CRTC_STATIC_SCREEN_EVENT_MASK, event_triggers,
833
+ CRTC_STATIC_SCREEN_FRAME_COUNT, num_frames);
824834 }
825835
826836 void dce120_timing_generator_set_test_pattern(
....@@ -1109,6 +1119,92 @@
11091119 return true;
11101120 }
11111121
1122
+
1123
+static bool dce120_is_tg_enabled(struct timing_generator *tg)
1124
+{
1125
+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1126
+ uint32_t value, field;
1127
+
1128
+ value = dm_read_reg_soc15(tg->ctx, mmCRTC0_CRTC_CONTROL,
1129
+ tg110->offsets.crtc);
1130
+ field = get_reg_field_value(value, CRTC0_CRTC_CONTROL,
1131
+ CRTC_CURRENT_MASTER_EN_STATE);
1132
+
1133
+ return field == 1;
1134
+}
1135
+
1136
+static bool dce120_configure_crc(struct timing_generator *tg,
1137
+ const struct crc_params *params)
1138
+{
1139
+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1140
+
1141
+ /* Cannot configure crc on a CRTC that is disabled */
1142
+ if (!dce120_is_tg_enabled(tg))
1143
+ return false;
1144
+
1145
+ /* First, disable CRC before we configure it. */
1146
+ dm_write_reg_soc15(tg->ctx, mmCRTC0_CRTC_CRC_CNTL,
1147
+ tg110->offsets.crtc, 0);
1148
+
1149
+ if (!params->enable)
1150
+ return true;
1151
+
1152
+ /* Program frame boundaries */
1153
+ /* Window A x axis start and end. */
1154
+ CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC0_WINDOWA_X_CONTROL,
1155
+ CRTC_CRC0_WINDOWA_X_START, params->windowa_x_start,
1156
+ CRTC_CRC0_WINDOWA_X_END, params->windowa_x_end);
1157
+
1158
+ /* Window A y axis start and end. */
1159
+ CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC0_WINDOWA_Y_CONTROL,
1160
+ CRTC_CRC0_WINDOWA_Y_START, params->windowa_y_start,
1161
+ CRTC_CRC0_WINDOWA_Y_END, params->windowa_y_end);
1162
+
1163
+ /* Window B x axis start and end. */
1164
+ CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC0_WINDOWB_X_CONTROL,
1165
+ CRTC_CRC0_WINDOWB_X_START, params->windowb_x_start,
1166
+ CRTC_CRC0_WINDOWB_X_END, params->windowb_x_end);
1167
+
1168
+ /* Window B y axis start and end. */
1169
+ CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC0_WINDOWB_Y_CONTROL,
1170
+ CRTC_CRC0_WINDOWB_Y_START, params->windowb_y_start,
1171
+ CRTC_CRC0_WINDOWB_Y_END, params->windowb_y_end);
1172
+
1173
+ /* Set crc mode and selection, and enable. Only using CRC0*/
1174
+ CRTC_REG_UPDATE_3(CRTC0_CRTC_CRC_CNTL,
1175
+ CRTC_CRC_EN, params->continuous_mode ? 1 : 0,
1176
+ CRTC_CRC0_SELECT, params->selection,
1177
+ CRTC_CRC_EN, 1);
1178
+
1179
+ return true;
1180
+}
1181
+
1182
+static bool dce120_get_crc(struct timing_generator *tg, uint32_t *r_cr,
1183
+ uint32_t *g_y, uint32_t *b_cb)
1184
+{
1185
+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
1186
+ uint32_t value, field;
1187
+
1188
+ value = dm_read_reg_soc15(tg->ctx, mmCRTC0_CRTC_CRC_CNTL,
1189
+ tg110->offsets.crtc);
1190
+ field = get_reg_field_value(value, CRTC0_CRTC_CRC_CNTL, CRTC_CRC_EN);
1191
+
1192
+ /* Early return if CRC is not enabled for this CRTC */
1193
+ if (!field)
1194
+ return false;
1195
+
1196
+ value = dm_read_reg_soc15(tg->ctx, mmCRTC0_CRTC_CRC0_DATA_RG,
1197
+ tg110->offsets.crtc);
1198
+ *r_cr = get_reg_field_value(value, CRTC0_CRTC_CRC0_DATA_RG, CRC0_R_CR);
1199
+ *g_y = get_reg_field_value(value, CRTC0_CRTC_CRC0_DATA_RG, CRC0_G_Y);
1200
+
1201
+ value = dm_read_reg_soc15(tg->ctx, mmCRTC0_CRTC_CRC0_DATA_B,
1202
+ tg110->offsets.crtc);
1203
+ *b_cb = get_reg_field_value(value, CRTC0_CRTC_CRC0_DATA_B, CRC0_B_CB);
1204
+
1205
+ return true;
1206
+}
1207
+
11121208 static const struct timing_generator_funcs dce120_tg_funcs = {
11131209 .validate_timing = dce120_tg_validate_timing,
11141210 .program_timing = dce120_tg_program_timing,
....@@ -1140,6 +1236,9 @@
11401236 .set_static_screen_control = dce120_timing_generator_set_static_screen_control,
11411237 .set_test_pattern = dce120_timing_generator_set_test_pattern,
11421238 .arm_vert_intr = dce120_arm_vert_intr,
1239
+ .is_tg_enabled = dce120_is_tg_enabled,
1240
+ .configure_crc = dce120_configure_crc,
1241
+ .get_crc = dce120_get_crc,
11431242 };
11441243
11451244