| .. | .. |
|---|
| 734 | 734 | CRTC_OVERSCAN_COLOR_RED, overscan_color->color_r_cr); |
|---|
| 735 | 735 | } |
|---|
| 736 | 736 | |
|---|
| 737 | | -void dce120_tg_program_timing(struct timing_generator *tg, |
|---|
| 737 | +static void dce120_tg_program_timing(struct timing_generator *tg, |
|---|
| 738 | 738 | 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, |
|---|
| 739 | 744 | bool use_vbios) |
|---|
| 740 | 745 | { |
|---|
| 741 | 746 | if (use_vbios) |
|---|
| .. | .. |
|---|
| 814 | 819 | |
|---|
| 815 | 820 | static void dce120_timing_generator_set_static_screen_control( |
|---|
| 816 | 821 | struct timing_generator *tg, |
|---|
| 817 | | - uint32_t value) |
|---|
| 822 | + uint32_t event_triggers, |
|---|
| 823 | + uint32_t num_frames) |
|---|
| 818 | 824 | { |
|---|
| 819 | 825 | struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); |
|---|
| 820 | 826 | |
|---|
| 827 | + // By register spec, it only takes 8 bit value |
|---|
| 828 | + if (num_frames > 0xFF) |
|---|
| 829 | + num_frames = 0xFF; |
|---|
| 830 | + |
|---|
| 821 | 831 | 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); |
|---|
| 824 | 834 | } |
|---|
| 825 | 835 | |
|---|
| 826 | 836 | void dce120_timing_generator_set_test_pattern( |
|---|
| .. | .. |
|---|
| 1109 | 1119 | return true; |
|---|
| 1110 | 1120 | } |
|---|
| 1111 | 1121 | |
|---|
| 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 | + |
|---|
| 1112 | 1208 | static const struct timing_generator_funcs dce120_tg_funcs = { |
|---|
| 1113 | 1209 | .validate_timing = dce120_tg_validate_timing, |
|---|
| 1114 | 1210 | .program_timing = dce120_tg_program_timing, |
|---|
| .. | .. |
|---|
| 1140 | 1236 | .set_static_screen_control = dce120_timing_generator_set_static_screen_control, |
|---|
| 1141 | 1237 | .set_test_pattern = dce120_timing_generator_set_test_pattern, |
|---|
| 1142 | 1238 | .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, |
|---|
| 1143 | 1242 | }; |
|---|
| 1144 | 1243 | |
|---|
| 1145 | 1244 | |
|---|