diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c index ddc789daf3b1..4f864501e046 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c @@ -57,6 +57,8 @@ #define MCP_SYNC_PHY_LOCK 0x90 #define MCP_SYNC_PHY_UNLOCK 0x91 #define MCP_BL_SET_PWM_FRAC 0x6A /* Enable or disable Fractional PWM */ +#define CRC_WIN_NOTIFY 0x92 +#define CRC_STOP_UPDATE 0x93 #define MCP_SEND_EDID_CEA 0xA0 #define EDID_CEA_CMD_ACK 1 #define EDID_CEA_CMD_NACK 2 @@ -930,6 +932,84 @@ static bool dcn10_recv_edid_cea_ack(struct dmcu *dmcu, int *offset) #endif //(CONFIG_DRM_AMD_DC_DCN) +#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) +static void dcn10_forward_crc_window(struct dmcu *dmcu, + struct crc_region *crc_win, + struct otg_phy_mux *mux_mapping) +{ + struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu); + unsigned int dmcu_max_retry_on_wait_reg_ready = 801; + unsigned int dmcu_wait_reg_ready_interval = 100; + unsigned int crc_start = 0, crc_end = 0, otg_phy_mux = 0; + + /* If microcontroller is not running, do nothing */ + if (dmcu->dmcu_state != DMCU_RUNNING) + return; + + if (!crc_win) + return; + + /* waitDMCUReadyForCmd */ + REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, + dmcu_wait_reg_ready_interval, + dmcu_max_retry_on_wait_reg_ready); + + /* build up nitification data */ + crc_start = (((unsigned int) crc_win->x_start) << 16) | crc_win->y_start; + crc_end = (((unsigned int) crc_win->x_end) << 16) | crc_win->y_end; + otg_phy_mux = + (((unsigned int) mux_mapping->otg_output_num) << 16) | mux_mapping->phy_output_num; + + dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG1), + crc_start); + + dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG2), + crc_end); + + dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG3), + otg_phy_mux); + + /* setDMCUParam_Cmd */ + REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, + CRC_WIN_NOTIFY); + + /* notifyDMCUMsg */ + REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); +} + +static void dcn10_stop_crc_win_update(struct dmcu *dmcu, + struct otg_phy_mux *mux_mapping) +{ + struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu); + unsigned int dmcu_max_retry_on_wait_reg_ready = 801; + unsigned int dmcu_wait_reg_ready_interval = 100; + unsigned int otg_phy_mux = 0; + + /* If microcontroller is not running, do nothing */ + if (dmcu->dmcu_state != DMCU_RUNNING) + return; + + /* waitDMCUReadyForCmd */ + REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, + dmcu_wait_reg_ready_interval, + dmcu_max_retry_on_wait_reg_ready); + + /* build up nitification data */ + otg_phy_mux = + (((unsigned int) mux_mapping->otg_output_num) << 16) | mux_mapping->phy_output_num; + + dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG1), + otg_phy_mux); + + /* setDMCUParam_Cmd */ + REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, + CRC_STOP_UPDATE); + + /* notifyDMCUMsg */ + REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); +} +#endif + static const struct dmcu_funcs dce_funcs = { .dmcu_init = dce_dmcu_init, .load_iram = dce_dmcu_load_iram, @@ -953,6 +1033,10 @@ static const struct dmcu_funcs dcn10_funcs = { .send_edid_cea = dcn10_send_edid_cea, .recv_amd_vsdb = dcn10_recv_amd_vsdb, .recv_edid_cea_ack = dcn10_recv_edid_cea_ack, +#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) + .forward_crc_window = dcn10_forward_crc_window, + .stop_crc_win_update = dcn10_stop_crc_win_update, +#endif .is_dmcu_initialized = dcn10_is_dmcu_initialized }; |