From: Amy Zhang <amy.zh...@amd.com>

- Move PSR programming from link encoder to dmcu

Change-Id: I90b7917e2f236deeb2aac32559c27b25f3da997a
Signed-off-by: Amy Zhang <amy.zh...@amd.com>
Acked-by: Harry Wentland <harry.wentl...@amd.com>
Reviewed-by: Tony Cheng <tony.ch...@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c      |  21 +-
 drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c      | 208 +++++++++++++++
 drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h      | 107 +++++++-
 .../gpu/drm/amd/display/dc/dce/dce_link_encoder.c  | 280 +++------------------
 .../gpu/drm/amd/display/dc/dce/dce_link_encoder.h  |  73 +-----
 drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h       |   4 +
 .../gpu/drm/amd/display/dc/inc/hw/link_encoder.h   |   9 +-
 7 files changed, 376 insertions(+), 326 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 2b929393f68a..8eb6b342a49d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -40,6 +40,7 @@
 #include "abm.h"
 #include "fixed31_32.h"
 #include "dpcd_defs.h"
+#include "dmcu.h"
 
 #include "dce/dce_11_0_d.h"
 #include "dce/dce_11_0_enum.h"
@@ -1433,28 +1434,33 @@ bool dc_link_set_backlight_level(const struct dc_link 
*dc_link, uint32_t level,
 bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable)
 {
        struct core_link *link = DC_LINK_TO_CORE(dc_link);
+       struct dc_context *ctx = link->ctx;
+       struct core_dc *core_dc = DC_TO_CORE(ctx->dc);
+       struct dmcu *dmcu = core_dc->res_pool->dmcu;
+
+       if (dmcu != NULL && dc_link->psr_caps.psr_version > 0)
+               dmcu->funcs->set_psr_enable(dmcu, enable);
 
-       if (dc_link != NULL && dc_link->psr_caps.psr_version > 0)
-               link->link_enc->funcs->set_dmcu_psr_enable(link->link_enc,
-                                                               enable);
        return true;
 }
 
 bool dc_link_setup_psr(const struct dc_link *dc_link,
                const struct dc_stream *stream)
 {
-
        struct core_link *link = DC_LINK_TO_CORE(dc_link);
        struct dc_context *ctx = link->ctx;
        struct core_dc *core_dc = DC_TO_CORE(ctx->dc);
+       struct dmcu *dmcu = core_dc->res_pool->dmcu;
        struct core_stream *core_stream = DC_STREAM_TO_CORE(stream);
-       struct psr_dmcu_context psr_context = {0};
+       struct psr_context psr_context = {0};
        int i;
 
        psr_context.controllerId = CONTROLLER_ID_UNDEFINED;
 
 
-       if (dc_link != NULL && dc_link->psr_caps.psr_version > 0) {
+       if (dc_link != NULL &&
+               dmcu != NULL &&
+               dc_link->psr_caps.psr_version > 0) {
                /* updateSinkPsrDpcdConfig*/
                union dpcd_psr_configuration psr_configuration;
 
@@ -1552,8 +1558,7 @@ bool dc_link_setup_psr(const struct dc_link *dc_link,
                 */
                psr_context.frame_delay = 0;
 
-               link->link_enc->funcs->setup_dmcu_psr
-                       (link->link_enc, &psr_context);
+               dmcu->funcs->setup_psr(dmcu, link, &psr_context);
                return true;
        } else
                return false;
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 eb0e95f57aa9..44eeeeb888fe 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
@@ -23,6 +23,8 @@
  *
  */
 
+#include "core_types.h"
+#include "link_encoder.h"
 #include "dce_dmcu.h"
 #include "dm_services.h"
 #include "reg_helper.h"
@@ -42,6 +44,12 @@
 #define CTX \
        dmcu_dce->base.ctx
 
+/* PSR related commands */
+#define PSR_ENABLE 0x20
+#define PSR_EXIT 0x21
+#define PSR_SET 0x23
+#define MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK   0x00000001L
+
 bool dce_dmcu_load_iram(struct dmcu *dmcu,
                unsigned int start_offset,
                const char *src,
@@ -76,8 +84,208 @@ bool dce_dmcu_load_iram(struct dmcu *dmcu,
        return true;
 }
 
+static void dce_get_dmcu_psr_state(struct dmcu *dmcu, uint32_t *psr_state)
+{
+       struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
+
+       uint32_t count = 0;
+       uint32_t psrStateOffset = 0xf0;
+       uint32_t value = -1;
+
+       /* Enable write access to IRAM */
+       REG_UPDATE(DMCU_RAM_ACCESS_CTRL, IRAM_HOST_ACCESS_EN, 1);
+
+       while (REG(DCI_MEM_PWR_STATUS) && value != 0 && count++ < 10) {
+               dm_delay_in_microseconds(dmcu->ctx, 2);
+               REG_GET(DCI_MEM_PWR_STATUS, DMCU_IRAM_MEM_PWR_STATE, &value);
+       }
+       while (REG(DMU_MEM_PWR_CNTL) && value != 0 && count++ < 10) {
+               dm_delay_in_microseconds(dmcu->ctx, 2);
+               REG_GET(DMU_MEM_PWR_CNTL, DMCU_IRAM_MEM_PWR_STATE, &value);
+       }
+
+       /* Write address to IRAM_RD_ADDR in DMCU_IRAM_RD_CTRL */
+       REG_WRITE(DMCU_IRAM_RD_CTRL, psrStateOffset);
+
+       /* Read data from IRAM_RD_DATA in DMCU_IRAM_RD_DATA*/
+       *psr_state = REG_READ(DMCU_IRAM_RD_DATA);
+
+       /* Disable write access to IRAM after finished using IRAM
+        * in order to allow dynamic sleep state
+        */
+       REG_UPDATE(DMCU_RAM_ACCESS_CTRL, IRAM_HOST_ACCESS_EN, 0);
+}
+
+static void dce_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable)
+{
+       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 regValue;
+
+       unsigned int retryCount;
+       uint32_t psr_state = 0;
+
+       /* waitDMCUReadyForCmd */
+       do {
+               dm_delay_in_microseconds(dmcu->ctx,
+                               dmcu_wait_reg_ready_interval);
+               regValue = REG_READ(MASTER_COMM_CNTL_REG);
+               dmcu_max_retry_on_wait_reg_ready--;
+       } while
+       /* expected value is 0, loop while not 0*/
+       ((MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK & regValue) &&
+               dmcu_max_retry_on_wait_reg_ready > 0);
+
+       /* setDMCUParam_Cmd */
+       if (enable)
+               REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0,
+                               PSR_ENABLE);
+       else
+               REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0,
+                               PSR_EXIT);
+
+       /* notifyDMCUMsg */
+       REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
+
+       for (retryCount = 0; retryCount <= 100; retryCount++) {
+               dce_get_dmcu_psr_state(dmcu, &psr_state);
+               if (enable) {
+                       if (psr_state != 0)
+                               break;
+               } else {
+                       if (psr_state == 0)
+                               break;
+               }
+               dm_delay_in_microseconds(dmcu->ctx, 10);
+       }
+}
+
+static void dce_dmcu_setup_psr(struct dmcu *dmcu,
+               struct core_link *link,
+               struct psr_context *psr_context)
+{
+       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 regValue;
+
+       union dce_dmcu_psr_config_data_reg1 masterCmdData1;
+       union dce_dmcu_psr_config_data_reg2 masterCmdData2;
+       union dce_dmcu_psr_config_data_reg3 masterCmdData3;
+
+       link->link_enc->funcs->psr_program_dp_dphy_fast_training(link->link_enc,
+                       psr_context->psrExitLinkTrainingRequired);
+
+       /* Enable static screen interrupts for PSR supported display */
+       /* Disable the interrupt coming from other displays. */
+       REG_UPDATE_4(DMCU_INTERRUPT_TO_UC_EN_MASK,
+                       STATIC_SCREEN1_INT_TO_UC_EN, 0,
+                       STATIC_SCREEN2_INT_TO_UC_EN, 0,
+                       STATIC_SCREEN3_INT_TO_UC_EN, 0,
+                       STATIC_SCREEN4_INT_TO_UC_EN, 0);
+
+       switch (psr_context->controllerId) {
+       /* Driver uses case 1 for unconfigured */
+       case 1:
+               REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,
+                               STATIC_SCREEN1_INT_TO_UC_EN, 1);
+               break;
+       case 2:
+               REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,
+                               STATIC_SCREEN2_INT_TO_UC_EN, 1);
+               break;
+       case 3:
+               REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,
+                               STATIC_SCREEN3_INT_TO_UC_EN, 1);
+               break;
+       case 4:
+               REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,
+                               STATIC_SCREEN4_INT_TO_UC_EN, 1);
+               break;
+       case 5:
+               /* CZ/NL only has 4 CRTC!!
+                * really valid.
+                * There is no interrupt enable mask for these instances.
+                */
+               break;
+       case 6:
+               /* CZ/NL only has 4 CRTC!!
+                * These are here because they are defined in HW regspec,
+                * but not really valid. There is no interrupt enable mask
+                * for these instances.
+                */
+               break;
+       default:
+               REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,
+                               STATIC_SCREEN1_INT_TO_UC_EN, 1);
+               break;
+       }
+
+       link->link_enc->funcs->psr_program_secondary_packet(link->link_enc,
+                       psr_context->sdpTransmitLineNumDeadline);
+
+       if (psr_context->psr_level.bits.SKIP_SMU_NOTIFICATION)
+               REG_UPDATE(SMU_INTERRUPT_CONTROL, DC_SMU_INT_ENABLE, 1);
+
+       /* waitDMCUReadyForCmd */
+       do {
+               dm_delay_in_microseconds(dmcu->ctx,
+                               dmcu_wait_reg_ready_interval);
+               regValue = REG_READ(MASTER_COMM_CNTL_REG);
+               dmcu_max_retry_on_wait_reg_ready--;
+       } while
+       /* expected value is 0, loop while not 0*/
+       ((MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK & regValue) &&
+               dmcu_max_retry_on_wait_reg_ready > 0);
+
+       /* setDMCUParam_PSRHostConfigData */
+       masterCmdData1.u32All = 0;
+       masterCmdData1.bits.timehyst_frames = psr_context->timehyst_frames;
+       masterCmdData1.bits.hyst_lines = psr_context->hyst_lines;
+       masterCmdData1.bits.rfb_update_auto_en =
+                       psr_context->rfb_update_auto_en;
+       masterCmdData1.bits.dp_port_num = psr_context->transmitterId;
+       masterCmdData1.bits.dcp_sel = psr_context->controllerId;
+       masterCmdData1.bits.phy_type  = psr_context->phyType;
+       masterCmdData1.bits.frame_cap_ind =
+                       psr_context->psrFrameCaptureIndicationReq;
+       masterCmdData1.bits.aux_chan = psr_context->channel;
+       masterCmdData1.bits.aux_repeat = psr_context->aux_repeats;
+       dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG1),
+                                       masterCmdData1.u32All);
+
+       masterCmdData2.u32All = 0;
+       masterCmdData2.bits.dig_fe = psr_context->engineId;
+       masterCmdData2.bits.dig_be = psr_context->transmitterId;
+       masterCmdData2.bits.skip_wait_for_pll_lock =
+                       psr_context->skipPsrWaitForPllLock;
+       masterCmdData2.bits.frame_delay = psr_context->frame_delay;
+       masterCmdData2.bits.smu_phy_id = psr_context->smuPhyId;
+       masterCmdData2.bits.num_of_controllers =
+                       psr_context->numberOfControllers;
+       dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG2),
+                       masterCmdData2.u32All);
+
+       masterCmdData3.u32All = 0;
+       masterCmdData3.bits.psr_level = psr_context->psr_level.u32all;
+       dm_write_reg(dmcu->ctx, REG(MASTER_COMM_DATA_REG3),
+                       masterCmdData3.u32All);
+
+       /* setDMCUParam_Cmd */
+       REG_UPDATE(MASTER_COMM_CMD_REG,
+                       MASTER_COMM_CMD_REG_BYTE0, PSR_SET);
+
+       /* notifyDMCUMsg */
+       REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
+}
+
 static const struct dmcu_funcs dce_funcs = {
        .load_iram = dce_dmcu_load_iram,
+       .set_psr_enable = dce_dmcu_set_psr_enable,
+       .setup_psr = dce_dmcu_setup_psr,
 };
 
 static void dce_dmcu_construct(
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h 
b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h
index 33c1754f04f1..7dc25386c2bf 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h
@@ -33,7 +33,16 @@
        SR(DMCU_CTRL), \
        SR(DMCU_RAM_ACCESS_CTRL), \
        SR(DMCU_IRAM_WR_CTRL), \
-       SR(DMCU_IRAM_WR_DATA)
+       SR(DMCU_IRAM_WR_DATA), \
+       SR(MASTER_COMM_DATA_REG1), \
+       SR(MASTER_COMM_DATA_REG2), \
+       SR(MASTER_COMM_DATA_REG3), \
+       SR(MASTER_COMM_CMD_REG), \
+       SR(MASTER_COMM_CNTL_REG), \
+       SR(DMCU_IRAM_RD_CTRL), \
+       SR(DMCU_IRAM_RD_DATA), \
+       SR(DMCU_INTERRUPT_TO_UC_EN_MASK), \
+       SR(SMU_INTERRUPT_CONTROL)
 
 #define DMCU_DCE110_COMMON_REG_LIST() \
        DMCU_COMMON_REG_LIST_DCE_BASE(), \
@@ -48,18 +57,41 @@
        DMCU_SF(DMCU_RAM_ACCESS_CTRL, \
                        IRAM_HOST_ACCESS_EN, mask_sh), \
        DMCU_SF(DMCU_RAM_ACCESS_CTRL, \
-                       IRAM_WR_ADDR_AUTO_INC, mask_sh)
+                       IRAM_WR_ADDR_AUTO_INC, mask_sh), \
+       DMCU_SF(MASTER_COMM_CMD_REG, \
+                       MASTER_COMM_CMD_REG_BYTE0, mask_sh), \
+       DMCU_SF(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, mask_sh), \
+       DMCU_SF(DMCU_INTERRUPT_TO_UC_EN_MASK, \
+                       STATIC_SCREEN1_INT_TO_UC_EN, mask_sh), \
+       DMCU_SF(DMCU_INTERRUPT_TO_UC_EN_MASK, \
+                       STATIC_SCREEN2_INT_TO_UC_EN, mask_sh), \
+       DMCU_SF(DMCU_INTERRUPT_TO_UC_EN_MASK, \
+                       STATIC_SCREEN3_INT_TO_UC_EN, mask_sh), \
+       DMCU_SF(DMCU_INTERRUPT_TO_UC_EN_MASK, \
+                       STATIC_SCREEN4_INT_TO_UC_EN, mask_sh), \
+       DMCU_SF(SMU_INTERRUPT_CONTROL, DC_SMU_INT_ENABLE, mask_sh)
 
 #define DMCU_MASK_SH_LIST_DCE110(mask_sh) \
        DMCU_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh), \
        DMCU_SF(DCI_MEM_PWR_STATUS, \
-                       DMCU_IRAM_MEM_PWR_STATE, mask_sh)
+               DMCU_IRAM_MEM_PWR_STATE, mask_sh)
 
 #define DMCU_REG_FIELD_LIST(type) \
        type DMCU_IRAM_MEM_PWR_STATE; \
        type IRAM_HOST_ACCESS_EN; \
        type IRAM_WR_ADDR_AUTO_INC; \
-       type DMCU_ENABLE
+       type DMCU_ENABLE; \
+       type MASTER_COMM_CMD_REG_BYTE0; \
+       type MASTER_COMM_INTERRUPT; \
+       type DPHY_RX_FAST_TRAINING_CAPABLE; \
+       type DPHY_LOAD_BS_COUNT; \
+       type STATIC_SCREEN1_INT_TO_UC_EN; \
+       type STATIC_SCREEN2_INT_TO_UC_EN; \
+       type STATIC_SCREEN3_INT_TO_UC_EN; \
+       type STATIC_SCREEN4_INT_TO_UC_EN; \
+       type DP_SEC_GSP0_LINE_NUM; \
+       type DP_SEC_GSP0_PRIORITY; \
+       type DC_SMU_INT_ENABLE
 
 struct dce_dmcu_shift {
        DMCU_REG_FIELD_LIST(uint8_t);
@@ -76,6 +108,16 @@ struct dce_dmcu_registers {
        uint32_t DMU_MEM_PWR_CNTL;
        uint32_t DMCU_IRAM_WR_CTRL;
        uint32_t DMCU_IRAM_WR_DATA;
+
+       uint32_t MASTER_COMM_DATA_REG1;
+       uint32_t MASTER_COMM_DATA_REG2;
+       uint32_t MASTER_COMM_DATA_REG3;
+       uint32_t MASTER_COMM_CMD_REG;
+       uint32_t MASTER_COMM_CNTL_REG;
+       uint32_t DMCU_IRAM_RD_CTRL;
+       uint32_t DMCU_IRAM_RD_DATA;
+       uint32_t DMCU_INTERRUPT_TO_UC_EN_MASK;
+       uint32_t SMU_INTERRUPT_CONTROL;
 };
 
 struct dce_dmcu {
@@ -85,6 +127,63 @@ struct dce_dmcu {
        const struct dce_dmcu_mask *dmcu_mask;
 };
 
+/*******************************************************************
+ *   MASTER_COMM_DATA_REG1   Bit position    Data
+ *                           7:0                   hyst_frames[7:0]
+ *                           14:8              hyst_lines[6:0]
+ *                           15                    RFB_UPDATE_AUTO_EN
+ *                           18:16             phy_num[2:0]
+ *                           21:19             dcp_sel[2:0]
+ *                           22                    phy_type
+ *                           23                    frame_cap_ind
+ *                           26:24             aux_chan[2:0]
+ *                           30:27             aux_repeat[3:0]
+ *                           31:31             reserved[31:31]
+ ******************************************************************/
+union dce_dmcu_psr_config_data_reg1 {
+       struct {
+               unsigned int timehyst_frames:8;    /*[7:0]*/
+               unsigned int hyst_lines:7;         /*[14:8]*/
+               unsigned int rfb_update_auto_en:1; /*[15:15]*/
+               unsigned int dp_port_num:3;        /*[18:16]*/
+               unsigned int dcp_sel:3;            /*[21:19]*/
+               unsigned int phy_type:1;           /*[22:22]*/
+               unsigned int frame_cap_ind:1;      /*[23:23]*/
+               unsigned int aux_chan:3;           /*[26:24]*/
+               unsigned int aux_repeat:4;         /*[30:27]*/
+               unsigned int reserved:1;           /*[31:31]*/
+       } bits;
+       unsigned int u32All;
+};
+
+/*******************************************************************
+ *   MASTER_COMM_DATA_REG2
+ *******************************************************************/
+union dce_dmcu_psr_config_data_reg2 {
+       struct {
+               unsigned int dig_fe:3;                  /*[2:0]*/
+               unsigned int dig_be:3;                  /*[5:3]*/
+               unsigned int skip_wait_for_pll_lock:1;  /*[6:6]*/
+               unsigned int reserved:9;                /*[15:7]*/
+               unsigned int frame_delay:8;             /*[23:16]*/
+               unsigned int smu_phy_id:4;              /*[27:24]*/
+               unsigned int num_of_controllers:4;      /*[31:28]*/
+       } bits;
+       unsigned int u32All;
+};
+
+/*******************************************************************
+ *   MASTER_COMM_DATA_REG3
+ *******************************************************************/
+union dce_dmcu_psr_config_data_reg3 {
+       struct {
+               unsigned int psr_level:16;      /*[15:0]*/
+               unsigned int link_rate:4;       /*[19:16]*/
+               unsigned int reserved:12;       /*[31:20]*/
+       } bits;
+       unsigned int u32All;
+};
+
 struct dmcu *dce_dmcu_create(
        struct dc_context *ctx,
        const struct dce_dmcu_registers *regs,
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
index 305a9d86a5d2..a1d35ad85605 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
@@ -95,14 +95,6 @@
 /* For current ASICs pixel clock - 600MHz */
 #define MAX_ENCODER_CLOCK 600000
 
-/* PSR related commands */
-#define PSR_ENABLE 0x20
-#define PSR_EXIT 0x21
-#define PSR_SET 0x23
-
-/*TODO: Used for psr wakeup for set backlight level*/
-static unsigned int psr_crtc_offset;
-
 enum {
        DP_MST_UPDATE_MAX_RETRY = 50
 };
@@ -126,8 +118,9 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs 
= {
        .dp_set_phy_pattern = dce110_link_encoder_dp_set_phy_pattern,
        .update_mst_stream_allocation_table =
                dce110_link_encoder_update_mst_stream_allocation_table,
-       .set_dmcu_psr_enable = dce110_link_encoder_set_dmcu_psr_enable,
-       .setup_dmcu_psr = dce110_link_encoder_setup_dmcu_psr,
+       .psr_program_dp_dphy_fast_training =
+                       dce110_psr_program_dp_dphy_fast_training,
+       .psr_program_secondary_packet = dce110_psr_program_secondary_packet,
        .backlight_control = dce110_link_encoder_edp_backlight_control,
        .power_control = dce110_link_encoder_edp_power_control,
        .connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe,
@@ -136,7 +129,6 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs 
= {
        .destroy = dce110_link_encoder_destroy
 };
 
-
 static enum bp_result link_transmitter_control(
        struct dce110_link_encoder *enc110,
        struct bp_transmitter_control *cntl)
@@ -721,6 +713,40 @@ static bool is_panel_backlight_on(struct 
dce110_link_encoder *enc110)
        return value;
 }
 
+void dce110_psr_program_dp_dphy_fast_training(struct link_encoder *enc,
+                       bool exit_link_training_required)
+{
+       struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
+
+       if (exit_link_training_required)
+               REG_UPDATE(DP_DPHY_FAST_TRAINING,
+                               DPHY_RX_FAST_TRAINING_CAPABLE, 1);
+       else {
+               REG_UPDATE(DP_DPHY_FAST_TRAINING,
+                               DPHY_RX_FAST_TRAINING_CAPABLE, 0);
+               /*In DCE 11, we are able to pre-program a Force SR register
+                * to be able to trigger SR symbol after 5 idle patterns
+                * transmitted. Upon PSR Exit, DMCU can trigger
+                * DPHY_LOAD_BS_COUNT_START = 1. Upon writing 1 to
+                * DPHY_LOAD_BS_COUNT_START and the internal counter
+                * reaches DPHY_LOAD_BS_COUNT, the next BS symbol will be
+                * replaced by SR symbol once.
+                */
+
+               REG_UPDATE(DP_DPHY_BS_SR_SWAP_CNTL, DPHY_LOAD_BS_COUNT, 0x5);
+       }
+}
+
+void dce110_psr_program_secondary_packet(struct link_encoder *enc,
+                       unsigned int sdp_transmit_line_num_deadline)
+{
+       struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
+
+       REG_UPDATE_2(DP_SEC_CNTL1,
+               DP_SEC_GSP0_LINE_NUM, sdp_transmit_line_num_deadline,
+               DP_SEC_GSP0_PRIORITY, 1);
+}
+
 /*todo: cloned in stream enc, fix*/
 /*
  * @brief
@@ -1560,238 +1586,6 @@ void 
dce110_link_encoder_update_mst_stream_allocation_table(
        } while (retries < DP_MST_UPDATE_MAX_RETRY);
 }
 
-static void get_dmcu_psr_state(struct link_encoder *enc, uint32_t *psr_state)
-{
-       struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
-       struct dc_context *ctx = enc110->base.ctx;
-
-       uint32_t count = 0;
-       uint32_t psrStateOffset = 0xf0;
-       uint32_t value = -1;
-
-       /* Enable write access to IRAM */
-       REG_UPDATE(DMCU_RAM_ACCESS_CTRL, IRAM_HOST_ACCESS_EN, 1);
-
-       while (REG(DCI_MEM_PWR_STATUS) && value != 0 && count++ < 10) {
-               dm_delay_in_microseconds(ctx, 2);
-               REG_GET(DCI_MEM_PWR_STATUS, DMCU_IRAM_MEM_PWR_STATE, &value);
-       }
-       while (REG(DMU_MEM_PWR_CNTL) && value != 0 && count++ < 10) {
-               dm_delay_in_microseconds(ctx, 2);
-               REG_GET(DMU_MEM_PWR_CNTL, DMCU_IRAM_MEM_PWR_STATE, &value);
-       }
-
-       /* Write address to IRAM_RD_ADDR in DMCU_IRAM_RD_CTRL */
-       REG_WRITE(DMCU_IRAM_RD_CTRL, psrStateOffset);
-
-       /* Read data from IRAM_RD_DATA in DMCU_IRAM_RD_DATA*/
-       *psr_state = REG_READ(DMCU_IRAM_RD_DATA);
-
-       /* Disable write access to IRAM after finished using IRAM
-        * in order to allow dynamic sleep state
-        */
-       REG_UPDATE(DMCU_RAM_ACCESS_CTRL, IRAM_HOST_ACCESS_EN, 0);
-}
-
-void dce110_link_encoder_set_dmcu_psr_enable(struct link_encoder *enc,
-                                                               bool enable)
-{
-       struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
-       struct dc_context *ctx = enc110->base.ctx;
-
-       unsigned int dmcu_max_retry_on_wait_reg_ready = 801;
-       unsigned int dmcu_wait_reg_ready_interval = 100;
-
-       unsigned int regValue;
-
-       unsigned int retryCount;
-       uint32_t psr_state = 0;
-
-       /* waitDMCUReadyForCmd */
-       do {
-               dm_delay_in_microseconds(ctx, dmcu_wait_reg_ready_interval);
-               regValue = REG_READ(MASTER_COMM_CNTL_REG);
-               dmcu_max_retry_on_wait_reg_ready--;
-       } while
-       /* expected value is 0, loop while not 0*/
-       ((MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK & regValue) &&
-               dmcu_max_retry_on_wait_reg_ready > 0);
-
-       /* setDMCUParam_Cmd */
-       if (enable)
-               REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, 
PSR_ENABLE);
-       else
-               REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, 
PSR_EXIT);
-
-       /* notifyDMCUMsg */
-       REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
-
-       for (retryCount = 0; retryCount <= 100; retryCount++) {
-               get_dmcu_psr_state(enc, &psr_state);
-               if (enable) {
-                       if (psr_state != 0)
-                               break;
-               } else {
-                       if (psr_state == 0)
-                               break;
-               }
-               dm_delay_in_microseconds(ctx, 10);
-       }
-}
-
-void dce110_link_encoder_setup_dmcu_psr(struct link_encoder *enc,
-                       struct psr_dmcu_context *psr_context)
-{
-       struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
-       struct dc_context *ctx = enc110->base.ctx;
-
-       unsigned int dmcu_max_retry_on_wait_reg_ready = 801;
-       unsigned int dmcu_wait_reg_ready_interval = 100;
-       unsigned int regValue;
-
-       union dce110_dmcu_psr_config_data_reg1 masterCmdData1;
-       union dce110_dmcu_psr_config_data_reg2 masterCmdData2;
-       union dce110_dmcu_psr_config_data_reg3 masterCmdData3;
-
-       if (psr_context->psrExitLinkTrainingRequired)
-               REG_UPDATE(DP_DPHY_FAST_TRAINING, 
DPHY_RX_FAST_TRAINING_CAPABLE, 1);
-       else {
-               REG_UPDATE(DP_DPHY_FAST_TRAINING, 
DPHY_RX_FAST_TRAINING_CAPABLE, 0);
-               /*In DCE 11, we are able to pre-program a Force SR register
-                * to be able to trigger SR symbol after 5 idle patterns
-                * transmitted. Upon PSR Exit, DMCU can trigger
-                * DPHY_LOAD_BS_COUNT_START = 1. Upon writing 1 to
-                * DPHY_LOAD_BS_COUNT_START and the internal counter
-                * reaches DPHY_LOAD_BS_COUNT, the next BS symbol will be
-                * replaced by SR symbol once.
-                */
-
-               REG_UPDATE(DP_DPHY_BS_SR_SWAP_CNTL, DPHY_LOAD_BS_COUNT, 0x5);
-       }
-
-       /* Enable static screen interrupts for PSR supported display */
-       /* Disable the interrupt coming from other displays. */
-       REG_UPDATE_4(DMCU_INTERRUPT_TO_UC_EN_MASK,
-                       STATIC_SCREEN1_INT_TO_UC_EN, 0,
-                       STATIC_SCREEN2_INT_TO_UC_EN, 0,
-                       STATIC_SCREEN3_INT_TO_UC_EN, 0,
-                       STATIC_SCREEN4_INT_TO_UC_EN, 0);
-
-       switch (psr_context->controllerId) {
-       /* Driver uses case 1 for unconfigured */
-       case 1:
-               psr_crtc_offset = mmCRTC0_CRTC_STATIC_SCREEN_CONTROL -
-                               mmCRTC0_CRTC_STATIC_SCREEN_CONTROL;
-
-               REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,
-                               STATIC_SCREEN1_INT_TO_UC_EN, 1);
-               break;
-       case 2:
-               psr_crtc_offset = mmCRTC1_CRTC_STATIC_SCREEN_CONTROL -
-                               mmCRTC0_CRTC_STATIC_SCREEN_CONTROL;
-
-               REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,
-                               STATIC_SCREEN2_INT_TO_UC_EN, 1);
-               break;
-       case 3:
-               psr_crtc_offset = mmCRTC2_CRTC_STATIC_SCREEN_CONTROL -
-                               mmCRTC0_CRTC_STATIC_SCREEN_CONTROL;
-
-               REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,
-                               STATIC_SCREEN3_INT_TO_UC_EN, 1);
-               break;
-       case 4:
-               psr_crtc_offset = mmCRTC3_CRTC_STATIC_SCREEN_CONTROL -
-                               mmCRTC0_CRTC_STATIC_SCREEN_CONTROL;
-
-               REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,
-                               STATIC_SCREEN4_INT_TO_UC_EN, 1);
-               break;
-       case 5:
-               psr_crtc_offset = mmCRTC4_CRTC_STATIC_SCREEN_CONTROL -
-                               mmCRTC0_CRTC_STATIC_SCREEN_CONTROL;
-               /* CZ/NL only has 4 CRTC!!
-                * really valid.
-                * There is no interrupt enable mask for these instances.
-                */
-               break;
-       case 6:
-               psr_crtc_offset = mmCRTC5_CRTC_STATIC_SCREEN_CONTROL -
-                               mmCRTC0_CRTC_STATIC_SCREEN_CONTROL;
-               /* CZ/NL only has 4 CRTC!!
-                * These are here because they are defined in HW regspec,
-                * but not really valid. There is no interrupt enable mask
-                * for these instances.
-                */
-               break;
-       default:
-               psr_crtc_offset = mmCRTC0_CRTC_STATIC_SCREEN_CONTROL -
-                               mmCRTC0_CRTC_STATIC_SCREEN_CONTROL;
-
-               REG_UPDATE(DMCU_INTERRUPT_TO_UC_EN_MASK,
-                               STATIC_SCREEN1_INT_TO_UC_EN, 1);
-               break;
-       }
-
-       REG_UPDATE_2(DP_SEC_CNTL1,
-               DP_SEC_GSP0_LINE_NUM, psr_context->sdpTransmitLineNumDeadline,
-               DP_SEC_GSP0_PRIORITY, 1);
-
-       if (psr_context->psr_level.bits.SKIP_SMU_NOTIFICATION) {
-               REG_UPDATE(SMU_INTERRUPT_CONTROL, DC_SMU_INT_ENABLE, 1);
-       }
-
-       /* waitDMCUReadyForCmd */
-       do {
-               dm_delay_in_microseconds(ctx, dmcu_wait_reg_ready_interval);
-               regValue = REG_READ(MASTER_COMM_CNTL_REG);
-               dmcu_max_retry_on_wait_reg_ready--;
-       } while
-       /* expected value is 0, loop while not 0*/
-       ((MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK & regValue) &&
-               dmcu_max_retry_on_wait_reg_ready > 0);
-
-       /* setDMCUParam_PSRHostConfigData */
-       masterCmdData1.u32All = 0;
-       masterCmdData1.bits.timehyst_frames = psr_context->timehyst_frames;
-       masterCmdData1.bits.hyst_lines = psr_context->hyst_lines;
-       masterCmdData1.bits.rfb_update_auto_en =
-                       psr_context->rfb_update_auto_en;
-       masterCmdData1.bits.dp_port_num = psr_context->transmitterId;
-       masterCmdData1.bits.dcp_sel = psr_context->controllerId;
-       masterCmdData1.bits.phy_type  = psr_context->phyType;
-       masterCmdData1.bits.frame_cap_ind =
-                       psr_context->psrFrameCaptureIndicationReq;
-       masterCmdData1.bits.aux_chan = psr_context->channel;
-       masterCmdData1.bits.aux_repeat = psr_context->aux_repeats;
-       dm_write_reg(ctx, REG(MASTER_COMM_DATA_REG1),
-                                       masterCmdData1.u32All);
-
-       masterCmdData2.u32All = 0;
-       masterCmdData2.bits.dig_fe = psr_context->engineId;
-       masterCmdData2.bits.dig_be = psr_context->transmitterId;
-       masterCmdData2.bits.skip_wait_for_pll_lock =
-                       psr_context->skipPsrWaitForPllLock;
-       masterCmdData2.bits.frame_delay = psr_context->frame_delay;
-       masterCmdData2.bits.smu_phy_id = psr_context->smuPhyId;
-       masterCmdData2.bits.num_of_controllers =
-                       psr_context->numberOfControllers;
-       dm_write_reg(ctx, REG(MASTER_COMM_DATA_REG2),
-                       masterCmdData2.u32All);
-
-       masterCmdData3.u32All = 0;
-       masterCmdData3.bits.psr_level = psr_context->psr_level.u32all;
-       dm_write_reg(ctx, REG(MASTER_COMM_DATA_REG3),
-                       masterCmdData3.u32All);
-
-       /* setDMCUParam_Cmd */
-       REG_UPDATE(MASTER_COMM_CMD_REG,
-                       MASTER_COMM_CMD_REG_BYTE0, PSR_SET);
-
-       /* notifyDMCUMsg */
-       REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
-}
-
 void dce110_link_encoder_connect_dig_be_to_fe(
        struct link_encoder *enc,
        enum engine_id engine,
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h 
b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
index d382a6882d95..f337d607e36c 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
@@ -39,11 +39,6 @@
        SRI(DC_HPD_CONTROL, HPD, id)
 
 #define LE_COMMON_REG_LIST_BASE(id) \
-       SR(MASTER_COMM_DATA_REG1), \
-       SR(MASTER_COMM_DATA_REG2), \
-       SR(MASTER_COMM_DATA_REG3), \
-       SR(MASTER_COMM_CMD_REG), \
-       SR(MASTER_COMM_CNTL_REG), \
        SR(LVTMA_PWRSEQ_CNTL), \
        SR(LVTMA_PWRSEQ_STATE), \
        SR(DMCU_RAM_ACCESS_CTRL), \
@@ -149,62 +144,6 @@ struct dce110_link_encoder {
        const struct dce110_link_enc_hpd_registers *hpd_regs;
 };
 
-/*******************************************************************
-*   MASTER_COMM_DATA_REG1   Bit position    Data
-*                           7:0                    hyst_frames[7:0]
-*                           14:8               hyst_lines[6:0]
-*                           15             RFB_UPDATE_AUTO_EN
-*                           18:16              phy_num[2:0]
-*                           21:19              dcp_sel[2:0]
-*                           22             phy_type
-*                           23             frame_cap_ind
-*                           26:24              aux_chan[2:0]
-*                           30:27              aux_repeat[3:0]
-*                           31:31              reserved[31:31]
-*******************************************************************/
-union dce110_dmcu_psr_config_data_reg1 {
-       struct {
-               unsigned int timehyst_frames:8;    /*[7:0]*/
-               unsigned int hyst_lines:7;         /*[14:8]*/
-               unsigned int rfb_update_auto_en:1; /*[15:15]*/
-               unsigned int dp_port_num:3;        /*[18:16]*/
-               unsigned int dcp_sel:3;            /*[21:19]*/
-               unsigned int phy_type:1;           /*[22:22]*/
-               unsigned int frame_cap_ind:1;      /*[23:23]*/
-               unsigned int aux_chan:3;           /*[26:24]*/
-               unsigned int aux_repeat:4;         /*[30:27]*/
-               unsigned int reserved:1;           /*[31:31]*/
-       } bits;
-       unsigned int u32All;
-};
-
-/*******************************************************************
-*   MASTER_COMM_DATA_REG2
-*******************************************************************/
-union dce110_dmcu_psr_config_data_reg2 {
-       struct {
-               unsigned int dig_fe:3;                  /*[2:0]*/
-               unsigned int dig_be:3;                  /*[5:3]*/
-               unsigned int skip_wait_for_pll_lock:1;  /*[6:6]*/
-               unsigned int reserved:9;                /*[15:7]*/
-               unsigned int frame_delay:8;             /*[23:16]*/
-               unsigned int smu_phy_id:4;              /*[27:24]*/
-               unsigned int num_of_controllers:4;      /*[31:28]*/
-       } bits;
-       unsigned int u32All;
-};
-
-/*******************************************************************
-*   MASTER_COMM_DATA_REG3
-*******************************************************************/
-union dce110_dmcu_psr_config_data_reg3 {
-       struct {
-               unsigned int psr_level:16;      /*[15:0]*/
-               unsigned int link_rate:4;       /*[19:16]*/
-               unsigned int reserved:12;       /*[31:20]*/
-       } bits;
-       unsigned int u32All;
-};
 
 bool dce110_link_encoder_construct(
        struct dce110_link_encoder *enc110,
@@ -290,12 +229,6 @@ void 
dce110_link_encoder_update_mst_stream_allocation_table(
        struct link_encoder *enc,
        const struct link_mst_stream_allocation_table *table);
 
-void dce110_link_encoder_set_dmcu_psr_enable(
-               struct link_encoder *enc, bool enable);
-
-void dce110_link_encoder_setup_dmcu_psr(struct link_encoder *enc,
-                       struct psr_dmcu_context *psr_context);
-
 void dce110_link_encoder_edp_backlight_control(
        struct link_encoder *enc,
        bool enable);
@@ -317,4 +250,10 @@ void dce110_link_encoder_enable_hpd(struct link_encoder 
*enc);
 
 void dce110_link_encoder_disable_hpd(struct link_encoder *enc);
 
+void dce110_psr_program_dp_dphy_fast_training(struct link_encoder *enc,
+                       bool exit_link_training_required);
+
+void dce110_psr_program_secondary_packet(struct link_encoder *enc,
+                       unsigned int sdp_transmit_line_num_deadline);
+
 #endif /* __DC_LINK_ENCODER__DCE110_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
index 62012f091836..656cfdc79891 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
@@ -37,6 +37,10 @@ struct dmcu_funcs {
                        unsigned int start_offset,
                        const char *src,
                        unsigned int bytes);
+       void (*set_psr_enable)(struct dmcu *dmcu, bool enable);
+       void (*setup_psr)(struct dmcu *dmcu,
+                       struct core_link *link,
+                       struct psr_context *psr_context);
 };
 
 #endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
index 7b37b963666e..7307f96c7679 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
@@ -116,7 +116,7 @@ union psr_sink_psr_status {
        unsigned char raw;
 };
 
-struct psr_dmcu_context {
+struct psr_context {
        /* ddc line */
        enum channel_id channel;
        /* Transmitter id */
@@ -220,9 +220,10 @@ struct link_encoder_funcs {
        void (*update_mst_stream_allocation_table)(
                struct link_encoder *enc,
                const struct link_mst_stream_allocation_table *table);
-       void (*set_dmcu_psr_enable)(struct link_encoder *enc, bool enable);
-       void (*setup_dmcu_psr)(struct link_encoder *enc,
-                       struct psr_dmcu_context *psr_context);
+       void (*psr_program_dp_dphy_fast_training)(struct link_encoder *enc,
+                       bool exit_link_training_required);
+       void (*psr_program_secondary_packet)(struct link_encoder *enc,
+                               unsigned int sdp_transmit_line_num_deadline);
        void (*backlight_control) (struct link_encoder *enc,
                bool enable);
        void (*power_control) (struct link_encoder *enc,
-- 
2.9.3

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to