Skip to content

Commit b6fcc38

Browse files
Wayne Linalexdeucher
authored andcommitted
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 <[email protected]> Signed-off-by: Wayne Lin <[email protected]> Signed-off-by: Tom Chung <[email protected]> Tested-by: Daniel Wheeler <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 4a9a918 commit b6fcc38

File tree

8 files changed

+329
-137
lines changed

8 files changed

+329
-137
lines changed

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc,
510510
/* Enable or disable CRTC CRC generation */
511511
if (dm_is_crc_source_crtc(source) || source == AMDGPU_DM_PIPE_CRC_SOURCE_NONE) {
512512
if (!dc_stream_configure_crc(stream_state->ctx->dc,
513-
stream_state, NULL, enable, enable)) {
513+
stream_state, NULL, enable, enable, 0, true)) {
514514
ret = -EINVAL;
515515
goto unlock;
516516
}

drivers/gpu/drm/amd/display/dc/core/dc.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -687,15 +687,17 @@ dc_stream_forward_multiple_crc_window(struct dc_stream_state *stream,
687687
* @enable: Enable CRC if true, disable otherwise.
688688
* @continuous: Capture CRC on every frame if true. Otherwise, only capture
689689
* once.
690+
* @idx: Capture CRC on which CRC engine instance
691+
* @reset: Reset CRC engine before the configuration
690692
*
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.
693694
*
694695
* Return: %false if the stream is not found or CRC capture is not supported;
695696
* %true if the stream has been configured.
696697
*/
697698
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)
699701
{
700702
struct pipe_ctx *pipe;
701703
struct crc_params param;
@@ -739,6 +741,9 @@ bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
739741
param.continuous_mode = continuous;
740742
param.enable = enable;
741743

744+
param.crc_eng_inst = idx;
745+
param.reset = reset;
746+
742747
tg = pipe->stream_res.tg;
743748

744749
/* Only call if supported */

drivers/gpu/drm/amd/display/dc/dc_stream.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,9 @@ bool dc_stream_configure_crc(struct dc *dc,
550550
struct dc_stream_state *stream,
551551
struct crc_params *crc_window,
552552
bool enable,
553-
bool continuous);
553+
bool continuous,
554+
uint8_t idx,
555+
bool reset);
554556

555557
bool dc_stream_get_crc(struct dc *dc,
556558
struct dc_stream_state *stream,

drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c

Lines changed: 115 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2127,65 +2127,126 @@ bool dce110_configure_crc(struct timing_generator *tg,
21272127

21282128
cntl_addr = CRTC_REG(mmCRTC_CRC_CNTL);
21292129

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);
21322133

21332134
if (!params->enable)
21342135
return true;
21352136

21362137
/* 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);
2147-
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);
2158-
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);
2169-
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);
2180-
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);
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);
2150+
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);
2161+
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);
2172+
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);
2183+
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+
}
21892250

21902251
return true;
21912252
}

drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c

Lines changed: 62 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,39 +1100,73 @@ static bool dce120_configure_crc(struct timing_generator *tg,
11001100
if (!dce120_is_tg_enabled(tg))
11011101
return false;
11021102

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);
11061107

11071108
if (!params->enable)
11081109
return true;
11091110

11101111
/* 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);
1115-
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);
1120-
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);
1125-
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);
1130-
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);
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);
1118+
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);
1123+
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);
1128+
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);
1133+
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+
}
11361170

11371171
return true;
11381172
}

drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ struct crc_params {
141141

142142
bool continuous_mode;
143143
bool enable;
144+
145+
uint8_t crc_eng_inst;
146+
bool reset;
144147
};
145148

146149
/**

0 commit comments

Comments
 (0)