mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-03 20:34:23 -04:00
drm/amd/display: Extend dc_stream_get_crc to support 2nd crc engine
[Why & How] Since now we can set multiple crc windows for secure display, add a new input parameter for dc_stream_get_crc to indicate to fetch crc from which crc engine. Reviewed-by: HaoPing Liu <haoping.liu@amd.com> Signed-off-by: Wayne Lin <Wayne.Lin@amd.com> Signed-off-by: Roman Li <roman.li@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
@@ -709,7 +709,7 @@ void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc)
|
||||
}
|
||||
|
||||
if (dm_is_crc_source_crtc(cur_crc_src)) {
|
||||
if (!dc_stream_get_crc(stream_state->ctx->dc, stream_state,
|
||||
if (!dc_stream_get_crc(stream_state->ctx->dc, stream_state, 0,
|
||||
&crcs[0], &crcs[1], &crcs[2]))
|
||||
return;
|
||||
|
||||
|
||||
@@ -753,6 +753,7 @@ bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
|
||||
*
|
||||
* @dc: DC object.
|
||||
* @stream: The DC stream state of the stream to get CRCs from.
|
||||
* @idx: index of crc engine to get CRC from
|
||||
* @r_cr: CRC value for the red component.
|
||||
* @g_y: CRC value for the green component.
|
||||
* @b_cb: CRC value for the blue component.
|
||||
@@ -762,7 +763,7 @@ bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
|
||||
* Return:
|
||||
* %false if stream is not found, or if CRCs are not enabled.
|
||||
*/
|
||||
bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream,
|
||||
bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream, uint8_t idx,
|
||||
uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
|
||||
{
|
||||
int i;
|
||||
@@ -783,7 +784,7 @@ bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream,
|
||||
tg = pipe->stream_res.tg;
|
||||
|
||||
if (tg->funcs->get_crc)
|
||||
return tg->funcs->get_crc(tg, r_cr, g_y, b_cb);
|
||||
return tg->funcs->get_crc(tg, idx, r_cr, g_y, b_cb);
|
||||
DC_LOG_WARNING("CRC capture not supported.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -554,6 +554,7 @@ bool dc_stream_configure_crc(struct dc *dc,
|
||||
|
||||
bool dc_stream_get_crc(struct dc *dc,
|
||||
struct dc_stream_state *stream,
|
||||
uint8_t idx,
|
||||
uint32_t *r_cr,
|
||||
uint32_t *g_y,
|
||||
uint32_t *b_cb);
|
||||
|
||||
@@ -2190,7 +2190,7 @@ bool dce110_configure_crc(struct timing_generator *tg,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dce110_get_crc(struct timing_generator *tg,
|
||||
bool dce110_get_crc(struct timing_generator *tg, uint8_t idx,
|
||||
uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
|
||||
{
|
||||
uint32_t addr = 0;
|
||||
@@ -2206,14 +2206,30 @@ bool dce110_get_crc(struct timing_generator *tg,
|
||||
if (!field)
|
||||
return false;
|
||||
|
||||
addr = CRTC_REG(mmCRTC_CRC0_DATA_RG);
|
||||
value = dm_read_reg(tg->ctx, addr);
|
||||
*r_cr = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_R_CR);
|
||||
*g_y = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_G_Y);
|
||||
switch (idx) {
|
||||
case 0:
|
||||
addr = CRTC_REG(mmCRTC_CRC0_DATA_RG);
|
||||
value = dm_read_reg(tg->ctx, addr);
|
||||
*r_cr = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_R_CR);
|
||||
*g_y = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_G_Y);
|
||||
|
||||
addr = CRTC_REG(mmCRTC_CRC0_DATA_B);
|
||||
value = dm_read_reg(tg->ctx, addr);
|
||||
*b_cb = get_reg_field_value(value, CRTC_CRC0_DATA_B, CRC0_B_CB);
|
||||
addr = CRTC_REG(mmCRTC_CRC0_DATA_B);
|
||||
value = dm_read_reg(tg->ctx, addr);
|
||||
*b_cb = get_reg_field_value(value, CRTC_CRC0_DATA_B, CRC0_B_CB);
|
||||
break;
|
||||
case 1:
|
||||
addr = CRTC_REG(mmCRTC_CRC1_DATA_RG);
|
||||
value = dm_read_reg(tg->ctx, addr);
|
||||
*r_cr = get_reg_field_value(value, CRTC_CRC1_DATA_RG, CRC1_R_CR);
|
||||
*g_y = get_reg_field_value(value, CRTC_CRC1_DATA_RG, CRC1_G_Y);
|
||||
|
||||
addr = CRTC_REG(mmCRTC_CRC1_DATA_B);
|
||||
value = dm_read_reg(tg->ctx, addr);
|
||||
*b_cb = get_reg_field_value(value, CRTC_CRC1_DATA_B, CRC1_B_CB);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ bool dce110_arm_vert_intr(
|
||||
bool dce110_configure_crc(struct timing_generator *tg,
|
||||
const struct crc_params *params);
|
||||
|
||||
bool dce110_get_crc(struct timing_generator *tg,
|
||||
bool dce110_get_crc(struct timing_generator *tg, uint8_t idx,
|
||||
uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb);
|
||||
|
||||
bool dce110_is_two_pixels_per_container(const struct dc_crtc_timing *timing);
|
||||
|
||||
@@ -1137,8 +1137,8 @@ static bool dce120_configure_crc(struct timing_generator *tg,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool dce120_get_crc(struct timing_generator *tg, uint32_t *r_cr,
|
||||
uint32_t *g_y, uint32_t *b_cb)
|
||||
static bool dce120_get_crc(struct timing_generator *tg, uint8_t idx,
|
||||
uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
|
||||
{
|
||||
struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
|
||||
uint32_t value, field;
|
||||
@@ -1151,14 +1151,30 @@ static bool dce120_get_crc(struct timing_generator *tg, uint32_t *r_cr,
|
||||
if (!field)
|
||||
return false;
|
||||
|
||||
value = dm_read_reg_soc15(tg->ctx, mmCRTC0_CRTC_CRC0_DATA_RG,
|
||||
tg110->offsets.crtc);
|
||||
*r_cr = get_reg_field_value(value, CRTC0_CRTC_CRC0_DATA_RG, CRC0_R_CR);
|
||||
*g_y = get_reg_field_value(value, CRTC0_CRTC_CRC0_DATA_RG, CRC0_G_Y);
|
||||
switch (idx) {
|
||||
case 0:
|
||||
value = dm_read_reg_soc15(tg->ctx, mmCRTC0_CRTC_CRC0_DATA_RG,
|
||||
tg110->offsets.crtc);
|
||||
*r_cr = get_reg_field_value(value, CRTC0_CRTC_CRC0_DATA_RG, CRC0_R_CR);
|
||||
*g_y = get_reg_field_value(value, CRTC0_CRTC_CRC0_DATA_RG, CRC0_G_Y);
|
||||
|
||||
value = dm_read_reg_soc15(tg->ctx, mmCRTC0_CRTC_CRC0_DATA_B,
|
||||
tg110->offsets.crtc);
|
||||
*b_cb = get_reg_field_value(value, CRTC0_CRTC_CRC0_DATA_B, CRC0_B_CB);
|
||||
value = dm_read_reg_soc15(tg->ctx, mmCRTC0_CRTC_CRC0_DATA_B,
|
||||
tg110->offsets.crtc);
|
||||
*b_cb = get_reg_field_value(value, CRTC0_CRTC_CRC0_DATA_B, CRC0_B_CB);
|
||||
break;
|
||||
case 1:
|
||||
value = dm_read_reg_soc15(tg->ctx, mmCRTC0_CRTC_CRC1_DATA_RG,
|
||||
tg110->offsets.crtc);
|
||||
*r_cr = get_reg_field_value(value, CRTC0_CRTC_CRC1_DATA_RG, CRC1_R_CR);
|
||||
*g_y = get_reg_field_value(value, CRTC0_CRTC_CRC1_DATA_RG, CRC1_G_Y);
|
||||
|
||||
value = dm_read_reg_soc15(tg->ctx, mmCRTC0_CRTC_CRC1_DATA_B,
|
||||
tg110->offsets.crtc);
|
||||
*b_cb = get_reg_field_value(value, CRTC0_CRTC_CRC1_DATA_B, CRC1_B_CB);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ void optc1_enable_crtc_reset(struct timing_generator *optc,
|
||||
|
||||
bool optc1_configure_crc(struct timing_generator *optc, const struct crc_params *params);
|
||||
|
||||
bool optc1_get_crc(struct timing_generator *optc,
|
||||
bool optc1_get_crc(struct timing_generator *optc, uint8_t idx,
|
||||
uint32_t *r_cr,
|
||||
uint32_t *g_y,
|
||||
uint32_t *b_cb);
|
||||
|
||||
@@ -291,7 +291,7 @@ struct timing_generator_funcs {
|
||||
* @get_crc: Get CRCs for the given timing generator. Return false if
|
||||
* CRCs are not enabled (via configure_crc).
|
||||
*/
|
||||
bool (*get_crc)(struct timing_generator *tg,
|
||||
bool (*get_crc)(struct timing_generator *tg, uint8_t idx,
|
||||
uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb);
|
||||
|
||||
void (*program_manual_trigger)(struct timing_generator *optc);
|
||||
|
||||
@@ -1510,6 +1510,7 @@ bool optc1_configure_crc(struct timing_generator *optc,
|
||||
* optc1_get_crc - Capture CRC result per component
|
||||
*
|
||||
* @optc: timing_generator instance.
|
||||
* @idx: index of crc engine to get CRC from
|
||||
* @r_cr: 16-bit primary CRC signature for red data.
|
||||
* @g_y: 16-bit primary CRC signature for green data.
|
||||
* @b_cb: 16-bit primary CRC signature for blue data.
|
||||
@@ -1521,7 +1522,7 @@ bool optc1_configure_crc(struct timing_generator *optc,
|
||||
* If CRC is disabled, return false; otherwise, return true, and the CRC
|
||||
* results in the parameters.
|
||||
*/
|
||||
bool optc1_get_crc(struct timing_generator *optc,
|
||||
bool optc1_get_crc(struct timing_generator *optc, uint8_t idx,
|
||||
uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
|
||||
{
|
||||
uint32_t field = 0;
|
||||
@@ -1533,14 +1534,30 @@ bool optc1_get_crc(struct timing_generator *optc,
|
||||
if (!field)
|
||||
return false;
|
||||
|
||||
/* OTG_CRC0_DATA_RG has the CRC16 results for the red and green component */
|
||||
REG_GET_2(OTG_CRC0_DATA_RG,
|
||||
CRC0_R_CR, r_cr,
|
||||
CRC0_G_Y, g_y);
|
||||
switch (idx) {
|
||||
case 0:
|
||||
/* OTG_CRC0_DATA_RG has the CRC16 results for the red and green component */
|
||||
REG_GET_2(OTG_CRC0_DATA_RG,
|
||||
CRC0_R_CR, r_cr,
|
||||
CRC0_G_Y, g_y);
|
||||
|
||||
/* OTG_CRC0_DATA_B has the CRC16 results for the blue component */
|
||||
REG_GET(OTG_CRC0_DATA_B,
|
||||
CRC0_B_CB, b_cb);
|
||||
/* OTG_CRC0_DATA_B has the CRC16 results for the blue component */
|
||||
REG_GET(OTG_CRC0_DATA_B,
|
||||
CRC0_B_CB, b_cb);
|
||||
break;
|
||||
case 1:
|
||||
/* OTG_CRC1_DATA_RG has the CRC16 results for the red and green component */
|
||||
REG_GET_2(OTG_CRC1_DATA_RG,
|
||||
CRC1_R_CR, r_cr,
|
||||
CRC1_G_Y, g_y);
|
||||
|
||||
/* OTG_CRC1_DATA_B has the CRC16 results for the blue component */
|
||||
REG_GET(OTG_CRC1_DATA_B,
|
||||
CRC1_B_CB, b_cb);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -86,6 +86,12 @@
|
||||
SRI(OTG_CRC0_WINDOWA_Y_CONTROL, OTG, inst),\
|
||||
SRI(OTG_CRC0_WINDOWB_X_CONTROL, OTG, inst),\
|
||||
SRI(OTG_CRC0_WINDOWB_Y_CONTROL, OTG, inst),\
|
||||
SRI(OTG_CRC1_DATA_RG, OTG, inst),\
|
||||
SRI(OTG_CRC1_DATA_B, OTG, inst),\
|
||||
SRI(OTG_CRC1_WINDOWA_X_CONTROL, OTG, inst),\
|
||||
SRI(OTG_CRC1_WINDOWA_Y_CONTROL, OTG, inst),\
|
||||
SRI(OTG_CRC1_WINDOWB_X_CONTROL, OTG, inst),\
|
||||
SRI(OTG_CRC1_WINDOWB_Y_CONTROL, OTG, inst),\
|
||||
SR(GSL_SOURCE_SELECT),\
|
||||
SRI(OTG_GLOBAL_CONTROL2, OTG, inst),\
|
||||
SRI(OTG_TRIGA_MANUAL_TRIG, OTG, inst)
|
||||
@@ -315,6 +321,7 @@ struct dcn_optc_registers {
|
||||
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_CHECK_ALL_FIELDS, mask_sh),\
|
||||
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_CONT_EN, mask_sh),\
|
||||
SF(OTG0_OTG_CRC_CNTL, OTG_CRC0_SELECT, mask_sh),\
|
||||
SF(OTG0_OTG_CRC_CNTL, OTG_CRC1_SELECT, mask_sh),\
|
||||
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_EN, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_DATA_RG, CRC0_R_CR, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_DATA_RG, CRC0_G_Y, mask_sh),\
|
||||
@@ -327,6 +334,17 @@ struct dcn_optc_registers {
|
||||
SF(OTG0_OTG_CRC0_WINDOWB_X_CONTROL, OTG_CRC0_WINDOWB_X_END, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_START, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_END, mask_sh),\
|
||||
SF(OTG0_OTG_CRC1_DATA_RG, CRC1_R_CR, mask_sh),\
|
||||
SF(OTG0_OTG_CRC1_DATA_RG, CRC1_G_Y, mask_sh),\
|
||||
SF(OTG0_OTG_CRC1_DATA_B, CRC1_B_CB, mask_sh),\
|
||||
SF(OTG0_OTG_CRC1_WINDOWA_X_CONTROL, OTG_CRC1_WINDOWA_X_START, mask_sh),\
|
||||
SF(OTG0_OTG_CRC1_WINDOWA_X_CONTROL, OTG_CRC1_WINDOWA_X_END, mask_sh),\
|
||||
SF(OTG0_OTG_CRC1_WINDOWA_Y_CONTROL, OTG_CRC1_WINDOWA_Y_START, mask_sh),\
|
||||
SF(OTG0_OTG_CRC1_WINDOWA_Y_CONTROL, OTG_CRC1_WINDOWA_Y_END, mask_sh),\
|
||||
SF(OTG0_OTG_CRC1_WINDOWB_X_CONTROL, OTG_CRC1_WINDOWB_X_START, mask_sh),\
|
||||
SF(OTG0_OTG_CRC1_WINDOWB_X_CONTROL, OTG_CRC1_WINDOWB_X_END, mask_sh),\
|
||||
SF(OTG0_OTG_CRC1_WINDOWB_Y_CONTROL, OTG_CRC1_WINDOWB_Y_START, mask_sh),\
|
||||
SF(OTG0_OTG_CRC1_WINDOWB_Y_CONTROL, OTG_CRC1_WINDOWB_Y_END, mask_sh),\
|
||||
SF(GSL_SOURCE_SELECT, GSL0_READY_SOURCE_SEL, mask_sh),\
|
||||
SF(GSL_SOURCE_SELECT, GSL1_READY_SOURCE_SEL, mask_sh),\
|
||||
SF(GSL_SOURCE_SELECT, GSL2_READY_SOURCE_SEL, mask_sh),\
|
||||
@@ -482,6 +500,7 @@ struct dcn_optc_registers {
|
||||
type OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN;\
|
||||
type OTG_CRC_CONT_EN;\
|
||||
type OTG_CRC0_SELECT;\
|
||||
type OTG_CRC1_SELECT;\
|
||||
type OTG_CRC_EN;\
|
||||
type CRC0_R_CR;\
|
||||
type CRC0_G_Y;\
|
||||
|
||||
Reference in New Issue
Block a user