Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: Add support to configure CRC window on specific CRC instance

[Why]
Have the need to specify the CRC window on specific CRC engine.
dc_stream_configure_crc() today calculates CRC on crc engine 0 only and always
resets CRC engine at first.

[How]
Add index parameter to dc_stream_configure_crc() for selecting the desired crc
engine. Additionally, add another parameter to specify whether to skip the
default reset of crc engine.

Reviewed-by: HaoPing Liu <haoping.liu@amd.com>
Signed-off-by: Wayne Lin <Wayne.Lin@amd.com>
Signed-off-by: Tom Chung <chiahsuan.chung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Wayne Lin and committed by
Alex Deucher
b6fcc386 4a9a9185

+317 -125
+1 -1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
··· 510 510 /* Enable or disable CRTC CRC generation */ 511 511 if (dm_is_crc_source_crtc(source) || source == AMDGPU_DM_PIPE_CRC_SOURCE_NONE) { 512 512 if (!dc_stream_configure_crc(stream_state->ctx->dc, 513 - stream_state, NULL, enable, enable)) { 513 + stream_state, NULL, enable, enable, 0, true)) { 514 514 ret = -EINVAL; 515 515 goto unlock; 516 516 }
+8 -3
drivers/gpu/drm/amd/display/dc/core/dc.c
··· 687 687 * @enable: Enable CRC if true, disable otherwise. 688 688 * @continuous: Capture CRC on every frame if true. Otherwise, only capture 689 689 * once. 690 + * @idx: Capture CRC on which CRC engine instance 691 + * @reset: Reset CRC engine before the configuration 690 692 * 691 - * By default, only CRC0 is configured, and the entire frame is used to 692 - * calculate the CRC. 693 + * By default, the entire frame is used to calculate the CRC. 693 694 * 694 695 * Return: %false if the stream is not found or CRC capture is not supported; 695 696 * %true if the stream has been configured. 696 697 */ 697 698 bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream, 698 - struct crc_params *crc_window, bool enable, bool continuous) 699 + struct crc_params *crc_window, bool enable, bool continuous, 700 + uint8_t idx, bool reset) 699 701 { 700 702 struct pipe_ctx *pipe; 701 703 struct crc_params param; ··· 740 738 param.selection = UNION_WINDOW_A_B; 741 739 param.continuous_mode = continuous; 742 740 param.enable = enable; 741 + 742 + param.crc_eng_inst = idx; 743 + param.reset = reset; 743 744 744 745 tg = pipe->stream_res.tg; 745 746
+3 -1
drivers/gpu/drm/amd/display/dc/dc_stream.h
··· 550 550 struct dc_stream_state *stream, 551 551 struct crc_params *crc_window, 552 552 bool enable, 553 - bool continuous); 553 + bool continuous, 554 + uint8_t idx, 555 + bool reset); 554 556 555 557 bool dc_stream_get_crc(struct dc *dc, 556 558 struct dc_stream_state *stream,
+111 -50
drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
··· 2127 2127 2128 2128 cntl_addr = CRTC_REG(mmCRTC_CRC_CNTL); 2129 2129 2130 - /* First, disable CRC before we configure it. */ 2131 - dm_write_reg(tg->ctx, cntl_addr, 0); 2130 + if (!params->enable || params->reset) 2131 + /* First, disable CRC before we configure it. */ 2132 + dm_write_reg(tg->ctx, cntl_addr, 0); 2132 2133 2133 2134 if (!params->enable) 2134 2135 return true; 2135 2136 2136 2137 /* Program frame boundaries */ 2137 - /* Window A x axis start and end. */ 2138 - value = 0; 2139 - addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_X_CONTROL); 2140 - set_reg_field_value(value, params->windowa_x_start, 2141 - CRTC_CRC0_WINDOWA_X_CONTROL, 2142 - CRTC_CRC0_WINDOWA_X_START); 2143 - set_reg_field_value(value, params->windowa_x_end, 2144 - CRTC_CRC0_WINDOWA_X_CONTROL, 2145 - CRTC_CRC0_WINDOWA_X_END); 2146 - dm_write_reg(tg->ctx, addr, value); 2138 + switch (params->crc_eng_inst) { 2139 + case 0: 2140 + /* Window A x axis start and end. */ 2141 + value = 0; 2142 + addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_X_CONTROL); 2143 + set_reg_field_value(value, params->windowa_x_start, 2144 + CRTC_CRC0_WINDOWA_X_CONTROL, 2145 + CRTC_CRC0_WINDOWA_X_START); 2146 + set_reg_field_value(value, params->windowa_x_end, 2147 + CRTC_CRC0_WINDOWA_X_CONTROL, 2148 + CRTC_CRC0_WINDOWA_X_END); 2149 + dm_write_reg(tg->ctx, addr, value); 2147 2150 2148 - /* Window A y axis start and end. */ 2149 - value = 0; 2150 - addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_Y_CONTROL); 2151 - set_reg_field_value(value, params->windowa_y_start, 2152 - CRTC_CRC0_WINDOWA_Y_CONTROL, 2153 - CRTC_CRC0_WINDOWA_Y_START); 2154 - set_reg_field_value(value, params->windowa_y_end, 2155 - CRTC_CRC0_WINDOWA_Y_CONTROL, 2156 - CRTC_CRC0_WINDOWA_Y_END); 2157 - dm_write_reg(tg->ctx, addr, value); 2151 + /* Window A y axis start and end. */ 2152 + value = 0; 2153 + addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_Y_CONTROL); 2154 + set_reg_field_value(value, params->windowa_y_start, 2155 + CRTC_CRC0_WINDOWA_Y_CONTROL, 2156 + CRTC_CRC0_WINDOWA_Y_START); 2157 + set_reg_field_value(value, params->windowa_y_end, 2158 + CRTC_CRC0_WINDOWA_Y_CONTROL, 2159 + CRTC_CRC0_WINDOWA_Y_END); 2160 + dm_write_reg(tg->ctx, addr, value); 2158 2161 2159 - /* Window B x axis start and end. */ 2160 - value = 0; 2161 - addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_X_CONTROL); 2162 - set_reg_field_value(value, params->windowb_x_start, 2163 - CRTC_CRC0_WINDOWB_X_CONTROL, 2164 - CRTC_CRC0_WINDOWB_X_START); 2165 - set_reg_field_value(value, params->windowb_x_end, 2166 - CRTC_CRC0_WINDOWB_X_CONTROL, 2167 - CRTC_CRC0_WINDOWB_X_END); 2168 - dm_write_reg(tg->ctx, addr, value); 2162 + /* Window B x axis start and end. */ 2163 + value = 0; 2164 + addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_X_CONTROL); 2165 + set_reg_field_value(value, params->windowb_x_start, 2166 + CRTC_CRC0_WINDOWB_X_CONTROL, 2167 + CRTC_CRC0_WINDOWB_X_START); 2168 + set_reg_field_value(value, params->windowb_x_end, 2169 + CRTC_CRC0_WINDOWB_X_CONTROL, 2170 + CRTC_CRC0_WINDOWB_X_END); 2171 + dm_write_reg(tg->ctx, addr, value); 2169 2172 2170 - /* Window B y axis start and end. */ 2171 - value = 0; 2172 - addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_Y_CONTROL); 2173 - set_reg_field_value(value, params->windowb_y_start, 2174 - CRTC_CRC0_WINDOWB_Y_CONTROL, 2175 - CRTC_CRC0_WINDOWB_Y_START); 2176 - set_reg_field_value(value, params->windowb_y_end, 2177 - CRTC_CRC0_WINDOWB_Y_CONTROL, 2178 - CRTC_CRC0_WINDOWB_Y_END); 2179 - dm_write_reg(tg->ctx, addr, value); 2173 + /* Window B y axis start and end. */ 2174 + value = 0; 2175 + addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_Y_CONTROL); 2176 + set_reg_field_value(value, params->windowb_y_start, 2177 + CRTC_CRC0_WINDOWB_Y_CONTROL, 2178 + CRTC_CRC0_WINDOWB_Y_START); 2179 + set_reg_field_value(value, params->windowb_y_end, 2180 + CRTC_CRC0_WINDOWB_Y_CONTROL, 2181 + CRTC_CRC0_WINDOWB_Y_END); 2182 + dm_write_reg(tg->ctx, addr, value); 2180 2183 2181 - /* Set crc mode and selection, and enable. Only using CRC0*/ 2182 - value = 0; 2183 - set_reg_field_value(value, params->continuous_mode ? 1 : 0, 2184 - CRTC_CRC_CNTL, CRTC_CRC_CONT_EN); 2185 - set_reg_field_value(value, params->selection, 2186 - CRTC_CRC_CNTL, CRTC_CRC0_SELECT); 2187 - set_reg_field_value(value, 1, CRTC_CRC_CNTL, CRTC_CRC_EN); 2188 - dm_write_reg(tg->ctx, cntl_addr, value); 2184 + /* Set crc mode and selection, and enable.*/ 2185 + value = 0; 2186 + set_reg_field_value(value, params->continuous_mode ? 1 : 0, 2187 + CRTC_CRC_CNTL, CRTC_CRC_CONT_EN); 2188 + set_reg_field_value(value, params->selection, 2189 + CRTC_CRC_CNTL, CRTC_CRC0_SELECT); 2190 + set_reg_field_value(value, 1, CRTC_CRC_CNTL, CRTC_CRC_EN); 2191 + dm_write_reg(tg->ctx, cntl_addr, value); 2192 + break; 2193 + case 1: 2194 + /* Window A x axis start and end. */ 2195 + value = 0; 2196 + addr = CRTC_REG(mmCRTC_CRC1_WINDOWA_X_CONTROL); 2197 + set_reg_field_value(value, params->windowa_x_start, 2198 + CRTC_CRC1_WINDOWA_X_CONTROL, 2199 + CRTC_CRC1_WINDOWA_X_START); 2200 + set_reg_field_value(value, params->windowa_x_end, 2201 + CRTC_CRC1_WINDOWA_X_CONTROL, 2202 + CRTC_CRC1_WINDOWA_X_END); 2203 + dm_write_reg(tg->ctx, addr, value); 2204 + 2205 + /* Window A y axis start and end. */ 2206 + value = 0; 2207 + addr = CRTC_REG(mmCRTC_CRC1_WINDOWA_Y_CONTROL); 2208 + set_reg_field_value(value, params->windowa_y_start, 2209 + CRTC_CRC1_WINDOWA_Y_CONTROL, 2210 + CRTC_CRC1_WINDOWA_Y_START); 2211 + set_reg_field_value(value, params->windowa_y_end, 2212 + CRTC_CRC1_WINDOWA_Y_CONTROL, 2213 + CRTC_CRC1_WINDOWA_Y_END); 2214 + dm_write_reg(tg->ctx, addr, value); 2215 + 2216 + /* Window B x axis start and end. */ 2217 + value = 0; 2218 + addr = CRTC_REG(mmCRTC_CRC1_WINDOWB_X_CONTROL); 2219 + set_reg_field_value(value, params->windowb_x_start, 2220 + CRTC_CRC1_WINDOWB_X_CONTROL, 2221 + CRTC_CRC1_WINDOWB_X_START); 2222 + set_reg_field_value(value, params->windowb_x_end, 2223 + CRTC_CRC1_WINDOWB_X_CONTROL, 2224 + CRTC_CRC1_WINDOWB_X_END); 2225 + dm_write_reg(tg->ctx, addr, value); 2226 + 2227 + /* Window B y axis start and end. */ 2228 + value = 0; 2229 + addr = CRTC_REG(mmCRTC_CRC1_WINDOWB_Y_CONTROL); 2230 + set_reg_field_value(value, params->windowb_y_start, 2231 + CRTC_CRC1_WINDOWB_Y_CONTROL, 2232 + CRTC_CRC1_WINDOWB_Y_START); 2233 + set_reg_field_value(value, params->windowb_y_end, 2234 + CRTC_CRC1_WINDOWB_Y_CONTROL, 2235 + CRTC_CRC1_WINDOWB_Y_END); 2236 + dm_write_reg(tg->ctx, addr, value); 2237 + 2238 + /* Set crc mode and selection, and enable.*/ 2239 + value = 0; 2240 + set_reg_field_value(value, params->continuous_mode ? 1 : 0, 2241 + CRTC_CRC_CNTL, CRTC_CRC_CONT_EN); 2242 + set_reg_field_value(value, params->selection, 2243 + CRTC_CRC_CNTL, CRTC_CRC1_SELECT); 2244 + set_reg_field_value(value, 1, CRTC_CRC_CNTL, CRTC_CRC_EN); 2245 + dm_write_reg(tg->ctx, cntl_addr, value); 2246 + break; 2247 + default: 2248 + return false; 2249 + } 2189 2250 2190 2251 return true; 2191 2252 }
+58 -24
drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
··· 1100 1100 if (!dce120_is_tg_enabled(tg)) 1101 1101 return false; 1102 1102 1103 - /* First, disable CRC before we configure it. */ 1104 - dm_write_reg_soc15(tg->ctx, mmCRTC0_CRTC_CRC_CNTL, 1105 - tg110->offsets.crtc, 0); 1103 + if (!params->enable || params->reset) 1104 + /* First, disable CRC before we configure it. */ 1105 + dm_write_reg_soc15(tg->ctx, mmCRTC0_CRTC_CRC_CNTL, 1106 + tg110->offsets.crtc, 0); 1106 1107 1107 1108 if (!params->enable) 1108 1109 return true; 1109 1110 1110 1111 /* Program frame boundaries */ 1111 - /* Window A x axis start and end. */ 1112 - CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC0_WINDOWA_X_CONTROL, 1113 - CRTC_CRC0_WINDOWA_X_START, params->windowa_x_start, 1114 - CRTC_CRC0_WINDOWA_X_END, params->windowa_x_end); 1112 + switch (params->crc_eng_inst) { 1113 + case 0: 1114 + /* Window A x axis start and end. */ 1115 + CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC0_WINDOWA_X_CONTROL, 1116 + CRTC_CRC0_WINDOWA_X_START, params->windowa_x_start, 1117 + CRTC_CRC0_WINDOWA_X_END, params->windowa_x_end); 1115 1118 1116 - /* Window A y axis start and end. */ 1117 - CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC0_WINDOWA_Y_CONTROL, 1118 - CRTC_CRC0_WINDOWA_Y_START, params->windowa_y_start, 1119 - CRTC_CRC0_WINDOWA_Y_END, params->windowa_y_end); 1119 + /* Window A y axis start and end. */ 1120 + CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC0_WINDOWA_Y_CONTROL, 1121 + CRTC_CRC0_WINDOWA_Y_START, params->windowa_y_start, 1122 + CRTC_CRC0_WINDOWA_Y_END, params->windowa_y_end); 1120 1123 1121 - /* Window B x axis start and end. */ 1122 - CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC0_WINDOWB_X_CONTROL, 1123 - CRTC_CRC0_WINDOWB_X_START, params->windowb_x_start, 1124 - CRTC_CRC0_WINDOWB_X_END, params->windowb_x_end); 1124 + /* Window B x axis start and end. */ 1125 + CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC0_WINDOWB_X_CONTROL, 1126 + CRTC_CRC0_WINDOWB_X_START, params->windowb_x_start, 1127 + CRTC_CRC0_WINDOWB_X_END, params->windowb_x_end); 1125 1128 1126 - /* Window B y axis start and end. */ 1127 - CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC0_WINDOWB_Y_CONTROL, 1128 - CRTC_CRC0_WINDOWB_Y_START, params->windowb_y_start, 1129 - CRTC_CRC0_WINDOWB_Y_END, params->windowb_y_end); 1129 + /* Window B y axis start and end. */ 1130 + CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC0_WINDOWB_Y_CONTROL, 1131 + CRTC_CRC0_WINDOWB_Y_START, params->windowb_y_start, 1132 + CRTC_CRC0_WINDOWB_Y_END, params->windowb_y_end); 1130 1133 1131 - /* Set crc mode and selection, and enable. Only using CRC0*/ 1132 - CRTC_REG_UPDATE_3(CRTC0_CRTC_CRC_CNTL, 1133 - CRTC_CRC_EN, params->continuous_mode ? 1 : 0, 1134 - CRTC_CRC0_SELECT, params->selection, 1135 - CRTC_CRC_EN, 1); 1134 + /* Set crc mode and selection, and enable.*/ 1135 + CRTC_REG_UPDATE_3(CRTC0_CRTC_CRC_CNTL, 1136 + CRTC_CRC_CONT_EN, params->continuous_mode ? 1 : 0, 1137 + CRTC_CRC0_SELECT, params->selection, 1138 + CRTC_CRC_EN, 1); 1139 + break; 1140 + case 1: 1141 + /* Window A x axis start and end. */ 1142 + CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC1_WINDOWA_X_CONTROL, 1143 + CRTC_CRC1_WINDOWA_X_START, params->windowa_x_start, 1144 + CRTC_CRC1_WINDOWA_X_END, params->windowa_x_end); 1145 + 1146 + /* Window A y axis start and end. */ 1147 + CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC1_WINDOWA_Y_CONTROL, 1148 + CRTC_CRC1_WINDOWA_Y_START, params->windowa_y_start, 1149 + CRTC_CRC1_WINDOWA_Y_END, params->windowa_y_end); 1150 + 1151 + /* Window B x axis start and end. */ 1152 + CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC1_WINDOWB_X_CONTROL, 1153 + CRTC_CRC1_WINDOWB_X_START, params->windowb_x_start, 1154 + CRTC_CRC1_WINDOWB_X_END, params->windowb_x_end); 1155 + 1156 + /* Window B y axis start and end. */ 1157 + CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC1_WINDOWB_Y_CONTROL, 1158 + CRTC_CRC1_WINDOWB_Y_START, params->windowb_y_start, 1159 + CRTC_CRC1_WINDOWB_Y_END, params->windowb_y_end); 1160 + 1161 + /* Set crc mode and selection, and enable */ 1162 + CRTC_REG_UPDATE_3(CRTC0_CRTC_CRC_CNTL, 1163 + CRTC_CRC_CONT_EN, params->continuous_mode ? 1 : 0, 1164 + CRTC_CRC1_SELECT, params->selection, 1165 + CRTC_CRC_EN, 1); 1166 + break; 1167 + default: 1168 + return false; 1169 + } 1136 1170 1137 1171 return true; 1138 1172 }
+3
drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
··· 141 141 142 142 bool continuous_mode; 143 143 bool enable; 144 + 145 + uint8_t crc_eng_inst; 146 + bool reset; 144 147 }; 145 148 146 149 /**
+56 -22
drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.c
··· 1470 1470 if (!optc1_is_tg_enabled(optc)) 1471 1471 return false; 1472 1472 1473 - REG_WRITE(OTG_CRC_CNTL, 0); 1473 + if (!params->enable || params->reset) 1474 + REG_WRITE(OTG_CRC_CNTL, 0); 1474 1475 1475 1476 if (!params->enable) 1476 1477 return true; 1477 1478 1478 1479 /* Program frame boundaries */ 1479 - /* Window A x axis start and end. */ 1480 - REG_UPDATE_2(OTG_CRC0_WINDOWA_X_CONTROL, 1481 - OTG_CRC0_WINDOWA_X_START, params->windowa_x_start, 1482 - OTG_CRC0_WINDOWA_X_END, params->windowa_x_end); 1480 + switch (params->crc_eng_inst) { 1481 + case 0: 1482 + /* Window A x axis start and end. */ 1483 + REG_UPDATE_2(OTG_CRC0_WINDOWA_X_CONTROL, 1484 + OTG_CRC0_WINDOWA_X_START, params->windowa_x_start, 1485 + OTG_CRC0_WINDOWA_X_END, params->windowa_x_end); 1483 1486 1484 - /* Window A y axis start and end. */ 1485 - REG_UPDATE_2(OTG_CRC0_WINDOWA_Y_CONTROL, 1486 - OTG_CRC0_WINDOWA_Y_START, params->windowa_y_start, 1487 - OTG_CRC0_WINDOWA_Y_END, params->windowa_y_end); 1487 + /* Window A y axis start and end. */ 1488 + REG_UPDATE_2(OTG_CRC0_WINDOWA_Y_CONTROL, 1489 + OTG_CRC0_WINDOWA_Y_START, params->windowa_y_start, 1490 + OTG_CRC0_WINDOWA_Y_END, params->windowa_y_end); 1488 1491 1489 - /* Window B x axis start and end. */ 1490 - REG_UPDATE_2(OTG_CRC0_WINDOWB_X_CONTROL, 1491 - OTG_CRC0_WINDOWB_X_START, params->windowb_x_start, 1492 - OTG_CRC0_WINDOWB_X_END, params->windowb_x_end); 1492 + /* Window B x axis start and end. */ 1493 + REG_UPDATE_2(OTG_CRC0_WINDOWB_X_CONTROL, 1494 + OTG_CRC0_WINDOWB_X_START, params->windowb_x_start, 1495 + OTG_CRC0_WINDOWB_X_END, params->windowb_x_end); 1493 1496 1494 - /* Window B y axis start and end. */ 1495 - REG_UPDATE_2(OTG_CRC0_WINDOWB_Y_CONTROL, 1496 - OTG_CRC0_WINDOWB_Y_START, params->windowb_y_start, 1497 - OTG_CRC0_WINDOWB_Y_END, params->windowb_y_end); 1497 + /* Window B y axis start and end. */ 1498 + REG_UPDATE_2(OTG_CRC0_WINDOWB_Y_CONTROL, 1499 + OTG_CRC0_WINDOWB_Y_START, params->windowb_y_start, 1500 + OTG_CRC0_WINDOWB_Y_END, params->windowb_y_end); 1498 1501 1499 - /* Set crc mode and selection, and enable. Only using CRC0*/ 1500 - REG_UPDATE_3(OTG_CRC_CNTL, 1501 - OTG_CRC_CONT_EN, params->continuous_mode ? 1 : 0, 1502 - OTG_CRC0_SELECT, params->selection, 1503 - OTG_CRC_EN, 1); 1502 + /* Set crc mode and selection, and enable.*/ 1503 + REG_UPDATE_3(OTG_CRC_CNTL, 1504 + OTG_CRC_CONT_EN, params->continuous_mode ? 1 : 0, 1505 + OTG_CRC0_SELECT, params->selection, 1506 + OTG_CRC_EN, 1); 1507 + break; 1508 + case 1: 1509 + /* Window A x axis start and end. */ 1510 + REG_UPDATE_2(OTG_CRC1_WINDOWA_X_CONTROL, 1511 + OTG_CRC1_WINDOWA_X_START, params->windowa_x_start, 1512 + OTG_CRC1_WINDOWA_X_END, params->windowa_x_end); 1513 + 1514 + /* Window A y axis start and end. */ 1515 + REG_UPDATE_2(OTG_CRC1_WINDOWA_Y_CONTROL, 1516 + OTG_CRC1_WINDOWA_Y_START, params->windowa_y_start, 1517 + OTG_CRC1_WINDOWA_Y_END, params->windowa_y_end); 1518 + 1519 + /* Window B x axis start and end. */ 1520 + REG_UPDATE_2(OTG_CRC1_WINDOWB_X_CONTROL, 1521 + OTG_CRC1_WINDOWB_X_START, params->windowb_x_start, 1522 + OTG_CRC1_WINDOWB_X_END, params->windowb_x_end); 1523 + 1524 + /* Window B y axis start and end. */ 1525 + REG_UPDATE_2(OTG_CRC1_WINDOWB_Y_CONTROL, 1526 + OTG_CRC1_WINDOWB_Y_START, params->windowb_y_start, 1527 + OTG_CRC1_WINDOWB_Y_END, params->windowb_y_end); 1528 + 1529 + /* Set crc mode and selection, and enable.*/ 1530 + REG_UPDATE_3(OTG_CRC_CNTL, 1531 + OTG_CRC_CONT_EN, params->continuous_mode ? 1 : 0, 1532 + OTG_CRC1_SELECT, params->selection, 1533 + OTG_CRC_EN, 1); 1534 + break; 1535 + default: 1536 + return false; 1537 + } 1504 1538 1505 1539 return true; 1506 1540 }
+77 -24
drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c
··· 183 183 { 184 184 struct optc *optc1 = DCN10TG_FROM_TG(optc); 185 185 186 + /* Cannot configure crc on a CRTC that is disabled */ 186 187 if (!optc1_is_tg_enabled(optc)) 187 188 return false; 188 - REG_WRITE(OTG_CRC_CNTL, 0); 189 + 190 + if (!params->enable || params->reset) 191 + REG_WRITE(OTG_CRC_CNTL, 0); 192 + 189 193 if (!params->enable) 190 194 return true; 191 - REG_UPDATE_2(OTG_CRC0_WINDOWA_X_CONTROL, 192 - OTG_CRC0_WINDOWA_X_START, params->windowa_x_start, 193 - OTG_CRC0_WINDOWA_X_END, params->windowa_x_end); 194 - REG_UPDATE_2(OTG_CRC0_WINDOWA_Y_CONTROL, 195 - OTG_CRC0_WINDOWA_Y_START, params->windowa_y_start, 196 - OTG_CRC0_WINDOWA_Y_END, params->windowa_y_end); 197 - REG_UPDATE_2(OTG_CRC0_WINDOWB_X_CONTROL, 198 - OTG_CRC0_WINDOWB_X_START, params->windowb_x_start, 199 - OTG_CRC0_WINDOWB_X_END, params->windowb_x_end); 200 - REG_UPDATE_2(OTG_CRC0_WINDOWB_Y_CONTROL, 201 - OTG_CRC0_WINDOWB_Y_START, params->windowb_y_start, 202 - OTG_CRC0_WINDOWB_Y_END, params->windowb_y_end); 203 - if (optc1->base.ctx->dc->debug.otg_crc_db && optc1->tg_mask->OTG_CRC_WINDOW_DB_EN != 0) { 204 - REG_UPDATE_4(OTG_CRC_CNTL, 205 - OTG_CRC_CONT_EN, params->continuous_mode ? 1 : 0, 206 - OTG_CRC0_SELECT, params->selection, 207 - OTG_CRC_EN, 1, 208 - OTG_CRC_WINDOW_DB_EN, 1); 209 - } else 210 - REG_UPDATE_3(OTG_CRC_CNTL, 211 - OTG_CRC_CONT_EN, params->continuous_mode ? 1 : 0, 212 - OTG_CRC0_SELECT, params->selection, 213 - OTG_CRC_EN, 1); 195 + 196 + /* Program frame boundaries */ 197 + switch (params->crc_eng_inst) { 198 + case 0: 199 + /* Window A x axis start and end. */ 200 + REG_UPDATE_2(OTG_CRC0_WINDOWA_X_CONTROL, 201 + OTG_CRC0_WINDOWA_X_START, params->windowa_x_start, 202 + OTG_CRC0_WINDOWA_X_END, params->windowa_x_end); 203 + 204 + /* Window A y axis start and end. */ 205 + REG_UPDATE_2(OTG_CRC0_WINDOWA_Y_CONTROL, 206 + OTG_CRC0_WINDOWA_Y_START, params->windowa_y_start, 207 + OTG_CRC0_WINDOWA_Y_END, params->windowa_y_end); 208 + 209 + /* Window B x axis start and end. */ 210 + REG_UPDATE_2(OTG_CRC0_WINDOWB_X_CONTROL, 211 + OTG_CRC0_WINDOWB_X_START, params->windowb_x_start, 212 + OTG_CRC0_WINDOWB_X_END, params->windowb_x_end); 213 + 214 + /* Window B y axis start and end. */ 215 + REG_UPDATE_2(OTG_CRC0_WINDOWB_Y_CONTROL, 216 + OTG_CRC0_WINDOWB_Y_START, params->windowb_y_start, 217 + OTG_CRC0_WINDOWB_Y_END, params->windowb_y_end); 218 + 219 + if (optc1->base.ctx->dc->debug.otg_crc_db && optc1->tg_mask->OTG_CRC_WINDOW_DB_EN != 0) 220 + REG_UPDATE_4(OTG_CRC_CNTL, 221 + OTG_CRC_CONT_EN, params->continuous_mode ? 1 : 0, 222 + OTG_CRC0_SELECT, params->selection, 223 + OTG_CRC_EN, 1, 224 + OTG_CRC_WINDOW_DB_EN, 1); 225 + else 226 + REG_UPDATE_3(OTG_CRC_CNTL, 227 + OTG_CRC_CONT_EN, params->continuous_mode ? 1 : 0, 228 + OTG_CRC0_SELECT, params->selection, 229 + OTG_CRC_EN, 1); 230 + break; 231 + case 1: 232 + /* Window A x axis start and end. */ 233 + REG_UPDATE_2(OTG_CRC1_WINDOWA_X_CONTROL, 234 + OTG_CRC1_WINDOWA_X_START, params->windowa_x_start, 235 + OTG_CRC1_WINDOWA_X_END, params->windowa_x_end); 236 + 237 + /* Window A y axis start and end. */ 238 + REG_UPDATE_2(OTG_CRC1_WINDOWA_Y_CONTROL, 239 + OTG_CRC1_WINDOWA_Y_START, params->windowa_y_start, 240 + OTG_CRC1_WINDOWA_Y_END, params->windowa_y_end); 241 + 242 + /* Window B x axis start and end. */ 243 + REG_UPDATE_2(OTG_CRC1_WINDOWB_X_CONTROL, 244 + OTG_CRC1_WINDOWB_X_START, params->windowb_x_start, 245 + OTG_CRC1_WINDOWB_X_END, params->windowb_x_end); 246 + 247 + /* Window B y axis start and end. */ 248 + REG_UPDATE_2(OTG_CRC1_WINDOWB_Y_CONTROL, 249 + OTG_CRC1_WINDOWB_Y_START, params->windowb_y_start, 250 + OTG_CRC1_WINDOWB_Y_END, params->windowb_y_end); 251 + 252 + if (optc1->base.ctx->dc->debug.otg_crc_db && optc1->tg_mask->OTG_CRC_WINDOW_DB_EN != 0) 253 + REG_UPDATE_4(OTG_CRC_CNTL, 254 + OTG_CRC_CONT_EN, params->continuous_mode ? 1 : 0, 255 + OTG_CRC1_SELECT, params->selection, 256 + OTG_CRC_EN, 1, 257 + OTG_CRC_WINDOW_DB_EN, 1); 258 + else 259 + REG_UPDATE_3(OTG_CRC_CNTL, 260 + OTG_CRC_CONT_EN, params->continuous_mode ? 1 : 0, 261 + OTG_CRC1_SELECT, params->selection, 262 + OTG_CRC_EN, 1); 263 + break; 264 + default: 265 + return false; 266 + } 214 267 return true; 215 268 } 216 269