diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dmub')
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 30 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 173 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/Makefile | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn301.c | 55 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn301.h | 37 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn302.c | 55 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn302.h | 37 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c | 94 |
14 files changed, 455 insertions, 73 deletions
diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h index c6a8d6c54621..863cd9cc93ff 100644 --- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h @@ -88,9 +88,9 @@ enum dmub_asic { DMUB_ASIC_NONE = 0, DMUB_ASIC_DCN20, DMUB_ASIC_DCN21, -#ifdef CONFIG_DRM_AMD_DC_DCN3_0 DMUB_ASIC_DCN30, -#endif + DMUB_ASIC_DCN301, + DMUB_ASIC_DCN302, DMUB_ASIC_MAX, }; @@ -265,8 +265,12 @@ struct dmub_srv_hw_funcs { bool (*is_hw_init)(struct dmub_srv *dmub); bool (*is_phy_init)(struct dmub_srv *dmub); + void (*enable_dmub_boot_options)(struct dmub_srv *dmub); + + void (*skip_dmub_panel_power_sequence)(struct dmub_srv *dmub, bool skip); + + union dmub_fw_boot_status (*get_fw_status)(struct dmub_srv *dmub); - bool (*is_auto_load_done)(struct dmub_srv *dmub); void (*set_gpint)(struct dmub_srv *dmub, union dmub_gpint_data_register reg); @@ -309,6 +313,7 @@ struct dmub_srv_hw_params { uint64_t fb_offset; uint32_t psp_version; bool load_inst_const; + bool skip_panel_power_sequence; }; /** @@ -340,6 +345,9 @@ struct dmub_srv { uint64_t fb_base; uint64_t fb_offset; uint32_t psp_version; + + /* Feature capabilities reported by fw */ + struct dmub_feature_caps feature_caps; }; /** @@ -590,6 +598,22 @@ enum dmub_status dmub_srv_get_gpint_response(struct dmub_srv *dmub, */ void dmub_flush_buffer_mem(const struct dmub_fb *fb); +/** + * dmub_srv_get_fw_boot_status() - Returns the DMUB boot status bits. + * + * @dmub: the dmub service + * @status: out pointer for firmware status + * + * Return: + * DMUB_STATUS_OK - success + * DMUB_STATUS_INVALID - unspecified error, unsupported + */ +enum dmub_status dmub_srv_get_fw_boot_status(struct dmub_srv *dmub, + union dmub_fw_boot_status *status); + +enum dmub_status dmub_srv_cmd_with_reply_data(struct dmub_srv *dmub, + union dmub_rb_cmd *cmd); + #if defined(__cplusplus) } #endif diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index d103ec1eaa73..249a076d6f69 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -26,6 +26,15 @@ #ifndef _DMUB_CMD_H_ #define _DMUB_CMD_H_ +#if defined(_TEST_HARNESS) || defined(FPGA_USB4) +#include "dmub_fw_types.h" +#include "include_legacy/atomfirmware.h" + +#if defined(_TEST_HARNESS) +#include <string.h> +#endif +#else + #include <asm/byteorder.h> #include <linux/types.h> #include <linux/string.h> @@ -34,12 +43,14 @@ #include "atomfirmware.h" +#endif // defined(_TEST_HARNESS) || defined(FPGA_USB4) + /* Firmware versioning. */ #ifdef DMUB_EXPOSE_VERSION -#define DMUB_FW_VERSION_GIT_HASH 0x9cf8f05fe +#define DMUB_FW_VERSION_GIT_HASH 0xf51b86a #define DMUB_FW_VERSION_MAJOR 0 #define DMUB_FW_VERSION_MINOR 0 -#define DMUB_FW_VERSION_REVISION 35 +#define DMUB_FW_VERSION_REVISION 47 #define DMUB_FW_VERSION_TEST 0 #define DMUB_FW_VERSION_VBIOS 0 #define DMUB_FW_VERSION_HOTFIX 0 @@ -55,6 +66,8 @@ //<DMUB_TYPES>================================================================== /* Basic type definitions. */ +#define __forceinline inline + #define SET_ABM_PIPE_GRADUALLY_DISABLE 0 #define SET_ABM_PIPE_IMMEDIATELY_DISABLE 255 #define SET_ABM_PIPE_IMMEDIATE_KEEP_GAIN_DISABLE 254 @@ -104,12 +117,15 @@ union dmub_psr_debug_flags { uint32_t u32All; }; +struct dmub_feature_caps { + uint8_t psr; + uint8_t reserved[7]; +}; + #if defined(__cplusplus) } #endif - - //============================================================================== //</DMUB_TYPES>================================================================= //============================================================================== @@ -189,7 +205,10 @@ union dmub_fw_boot_options { uint32_t pemu_env : 1; uint32_t fpga_env : 1; uint32_t optimized_init : 1; - uint32_t reserved : 29; + uint32_t skip_phy_access : 1; + uint32_t disable_clk_gate: 1; + uint32_t skip_phy_init_panel_sequence: 1; + uint32_t reserved : 26; } bits; uint32_t all; }; @@ -272,6 +291,7 @@ enum dmub_gpint_command { * ARGS: Stream mask, 1 bit per active stream index. */ DMUB_GPINT__IDLE_OPT_NOTIFY_STREAM_MASK = 8, + DMUB_GPINT__PSR_RESIDENCY = 9, }; //============================================================================== @@ -297,7 +317,9 @@ enum dmub_cmd_type { DMUB_CMD__REG_SEQ_BURST_WRITE = 3, DMUB_CMD__REG_REG_WAIT = 4, DMUB_CMD__PLAT_54186_WA = 5, + DMUB_CMD__QUERY_FEATURE_CAPS = 6, DMUB_CMD__PSR = 64, + DMUB_CMD__MALL = 65, DMUB_CMD__ABM = 66, DMUB_CMD__HW_LOCK = 69, DMUB_CMD__DP_AUX_ACCESS = 70, @@ -316,7 +338,8 @@ enum dmub_out_cmd_type { struct dmub_cmd_header { unsigned int type : 8; unsigned int sub_type : 8; - unsigned int reserved0 : 8; + unsigned int ret_status : 1; + unsigned int reserved0 : 7; unsigned int payload_bytes : 6; /* up to 60 bytes */ unsigned int reserved1 : 2; }; @@ -425,6 +448,18 @@ struct dmub_rb_cmd_PLAT_54186_wa { struct dmub_cmd_PLAT_54186_wa flip; }; +struct dmub_rb_cmd_mall { + struct dmub_cmd_header header; + union dmub_addr cursor_copy_src; + union dmub_addr cursor_copy_dst; + uint32_t tmr_delay; + uint32_t tmr_scale; + uint16_t cursor_width; + uint16_t cursor_pitch; + uint16_t cursor_height; + uint8_t cursor_bpp; +}; + struct dmub_cmd_digx_encoder_control_data { union dig_encoder_control_parameters_v1_5 dig; }; @@ -477,6 +512,22 @@ enum dp_aux_request_action { DP_AUX_REQ_ACTION_DPCD_READ = 0x90 }; +enum aux_return_code_type { + AUX_RET_SUCCESS = 0, + AUX_RET_ERROR_UNKNOWN, + AUX_RET_ERROR_INVALID_REPLY, + AUX_RET_ERROR_TIMEOUT, + AUX_RET_ERROR_HPD_DISCON, + AUX_RET_ERROR_ENGINE_ACQUIRE, + AUX_RET_ERROR_INVALID_OPERATION, + AUX_RET_ERROR_PROTOCOL_ERROR, +}; + +enum aux_channel_type { + AUX_CHANNEL_LEGACY_DDC, + AUX_CHANNEL_DPIA +}; + /* DP AUX command */ struct aux_transaction_parameters { uint8_t is_i2c_over_aux; @@ -489,9 +540,10 @@ struct aux_transaction_parameters { struct dmub_cmd_dp_aux_control_data { uint32_t handle; - uint8_t port_index; + uint8_t instance; uint8_t sw_crc_enabled; uint16_t timeout; + enum aux_channel_type type; struct aux_transaction_parameters dpaux; }; @@ -515,7 +567,7 @@ struct aux_reply_data { struct aux_reply_control_data { uint32_t handle; - uint8_t phy_port_index; + uint8_t instance; uint8_t result; uint16_t pad; }; @@ -526,8 +578,19 @@ struct dmub_rb_cmd_dp_aux_reply { struct aux_reply_data reply_data; }; +/* DP HPD Notify command - OutBox Cmd */ +enum dp_hpd_type { + DP_HPD = 0, + DP_IRQ +}; + +enum dp_hpd_status { + DP_HPD_UNPLUG = 0, + DP_HPD_PLUG +}; + struct dp_hpd_data { - uint8_t phy_port_index; + uint8_t instance; uint8_t hpd_type; uint8_t hpd_status; uint8_t pad; @@ -549,6 +612,7 @@ enum dmub_cmd_psr_type { DMUB_CMD__PSR_ENABLE = 2, DMUB_CMD__PSR_DISABLE = 3, DMUB_CMD__PSR_SET_LEVEL = 4, + DMUB_CMD__PSR_FORCE_STATIC = 5, }; enum psr_version { @@ -556,12 +620,22 @@ enum psr_version { PSR_VERSION_UNSUPPORTED = 0xFFFFFFFF, }; +enum dmub_cmd_mall_type { + DMUB_CMD__MALL_ACTION_ALLOW = 0, + DMUB_CMD__MALL_ACTION_DISALLOW = 1, + DMUB_CMD__MALL_ACTION_COPY_CURSOR = 2, +}; + struct dmub_cmd_psr_copy_settings_data { union dmub_psr_debug_flags debug; uint16_t psr_level; uint8_t dpp_inst; + /* opp_inst and mpcc_inst will not be used in dmub fw, + * dmub fw will get active opp by reading odm registers. + */ uint8_t mpcc_inst; uint8_t opp_inst; + uint8_t otg_inst; uint8_t digfe_inst; uint8_t digbe_inst; @@ -570,7 +644,8 @@ struct dmub_cmd_psr_copy_settings_data { uint8_t smu_optimizations_en; uint8_t frame_delay; uint8_t frame_cap_ind; - uint8_t pad[3]; + uint8_t pad[2]; + uint8_t multi_disp_optimizations_en; uint16_t init_sdp_deadline; uint16_t pad2; }; @@ -603,6 +678,10 @@ struct dmub_rb_cmd_psr_set_version { struct dmub_cmd_psr_set_version_data psr_set_version_data; }; +struct dmub_rb_cmd_psr_force_static { + struct dmub_cmd_header header; +}; + union dmub_hw_lock_flags { struct { uint8_t lock_pipe : 1; @@ -662,27 +741,30 @@ enum dmub_cmd_abm_type { struct abm_config_table { /* Parameters for crgb conversion */ uint16_t crgb_thresh[NUM_POWER_FN_SEGS]; // 0B - uint16_t crgb_offset[NUM_POWER_FN_SEGS]; // 15B - uint16_t crgb_slope[NUM_POWER_FN_SEGS]; // 31B + uint16_t crgb_offset[NUM_POWER_FN_SEGS]; // 16B + uint16_t crgb_slope[NUM_POWER_FN_SEGS]; // 32B /* Parameters for custom curve */ - uint16_t backlight_thresholds[NUM_BL_CURVE_SEGS]; // 47B - uint16_t backlight_offsets[NUM_BL_CURVE_SEGS]; // 79B + uint16_t backlight_thresholds[NUM_BL_CURVE_SEGS]; // 48B + uint16_t backlight_offsets[NUM_BL_CURVE_SEGS]; // 78B - uint16_t ambient_thresholds_lux[NUM_AMBI_LEVEL]; // 111B - uint16_t min_abm_backlight; // 121B + uint16_t ambient_thresholds_lux[NUM_AMBI_LEVEL]; // 112B + uint16_t min_abm_backlight; // 122B - uint8_t min_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; // 123B - uint8_t max_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; // 143B - uint8_t bright_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; // 163B - uint8_t dark_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; // 183B - uint8_t hybrid_factor[NUM_AGGR_LEVEL]; // 203B - uint8_t contrast_factor[NUM_AGGR_LEVEL]; // 207B - uint8_t deviation_gain[NUM_AGGR_LEVEL]; // 211B - uint8_t min_knee[NUM_AGGR_LEVEL]; // 215B - uint8_t max_knee[NUM_AGGR_LEVEL]; // 219B - uint8_t iir_curve[NUM_AMBI_LEVEL]; // 223B - uint8_t pad3[3]; // 228B + uint8_t min_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; // 124B + uint8_t max_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; // 144B + uint8_t bright_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; // 164B + uint8_t dark_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; // 184B + uint8_t hybrid_factor[NUM_AGGR_LEVEL]; // 204B + uint8_t contrast_factor[NUM_AGGR_LEVEL]; // 208B + uint8_t deviation_gain[NUM_AGGR_LEVEL]; // 212B + uint8_t min_knee[NUM_AGGR_LEVEL]; // 216B + uint8_t max_knee[NUM_AGGR_LEVEL]; // 220B + uint8_t iir_curve[NUM_AMBI_LEVEL]; // 224B + uint8_t pad3[3]; // 229B + + uint16_t blRampReduction[NUM_AGGR_LEVEL]; // 232B + uint16_t blRampStart[NUM_AGGR_LEVEL]; // 240B }; struct dmub_cmd_abm_set_pipe_data { @@ -744,7 +826,16 @@ struct dmub_rb_cmd_abm_init_config { struct dmub_cmd_abm_init_config_data abm_init_config_data; }; -union dmub_rb_cmd { +struct dmub_cmd_query_feature_caps_data { + struct dmub_feature_caps feature_caps; +}; + +struct dmub_rb_cmd_query_feature_caps { + struct dmub_cmd_header header; + struct dmub_cmd_query_feature_caps_data query_feature_caps_data; +}; + + union dmub_rb_cmd { struct dmub_rb_cmd_lock_hw lock_hw; struct dmub_rb_cmd_read_modify_write read_modify_write; struct dmub_rb_cmd_reg_field_update_sequence reg_field_update_seq; @@ -760,7 +851,9 @@ union dmub_rb_cmd { struct dmub_rb_cmd_psr_copy_settings psr_copy_settings; struct dmub_rb_cmd_psr_enable psr_enable; struct dmub_rb_cmd_psr_set_level psr_set_level; + struct dmub_rb_cmd_psr_force_static psr_force_static; struct dmub_rb_cmd_PLAT_54186_wa PLAT_54186_wa; + struct dmub_rb_cmd_mall mall; struct dmub_rb_cmd_abm_set_pipe abm_set_pipe; struct dmub_rb_cmd_abm_set_backlight abm_set_backlight; struct dmub_rb_cmd_abm_set_level abm_set_level; @@ -769,6 +862,7 @@ union dmub_rb_cmd { struct dmub_rb_cmd_abm_init_config abm_init_config; struct dmub_rb_cmd_dp_aux_access dp_aux_access; struct dmub_rb_cmd_outbox1_enable outbox1_enable; + struct dmub_rb_cmd_query_feature_caps query_feature_caps; }; union dmub_rb_out_cmd { @@ -831,7 +925,7 @@ static inline bool dmub_rb_push_front(struct dmub_rb *rb, { uint64_t volatile *dst = (uint64_t volatile *)(rb->base_address) + rb->wrpt / sizeof(uint64_t); const uint64_t *src = (const uint64_t *)cmd; - int i; + uint8_t i; if (dmub_rb_full(rb)) return false; @@ -868,14 +962,14 @@ static inline bool dmub_rb_out_push_front(struct dmub_rb *rb, } static inline bool dmub_rb_front(struct dmub_rb *rb, - union dmub_rb_cmd *cmd) + union dmub_rb_cmd **cmd) { - uint8_t *rd_ptr = (uint8_t *)rb->base_address + rb->rptr; + uint8_t *rb_cmd = (uint8_t *)(rb->base_address) + rb->rptr; if (dmub_rb_empty(rb)) return false; - dmub_memcpy(cmd, rd_ptr, DMUB_RB_CMD_SIZE); + *cmd = (union dmub_rb_cmd *)rb_cmd; return true; } @@ -885,7 +979,7 @@ static inline bool dmub_rb_out_front(struct dmub_rb *rb, { const uint64_t volatile *src = (const uint64_t volatile *)(rb->base_address) + rb->rptr / sizeof(uint64_t); uint64_t *dst = (uint64_t *)cmd; - int i; + uint8_t i; if (dmub_rb_empty(rb)) return false; @@ -917,7 +1011,7 @@ static inline void dmub_rb_flush_pending(const struct dmub_rb *rb) while (rptr != wptr) { uint64_t volatile *data = (uint64_t volatile *)rb->base_address + rptr / sizeof(uint64_t); - int i; + uint8_t i; for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++) *data++; @@ -937,6 +1031,17 @@ static inline void dmub_rb_init(struct dmub_rb *rb, rb->wrpt = init_params->write_ptr; } +static inline void dmub_rb_get_return_data(struct dmub_rb *rb, + union dmub_rb_cmd *cmd) +{ + // Copy rb entry back into command + uint8_t *rd_ptr = (rb->rptr == 0) ? + (uint8_t *)rb->base_address + rb->capacity - DMUB_RB_CMD_SIZE : + (uint8_t *)rb->base_address + rb->rptr - DMUB_RB_CMD_SIZE; + + dmub_memcpy(cmd, rd_ptr, DMUB_RB_CMD_SIZE); +} + #if defined(__cplusplus) } #endif diff --git a/drivers/gpu/drm/amd/display/dmub/src/Makefile b/drivers/gpu/drm/amd/display/dmub/src/Makefile index bb584f39cad0..945287164cf2 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/Makefile +++ b/drivers/gpu/drm/amd/display/dmub/src/Makefile @@ -21,9 +21,8 @@ # DMUB = dmub_srv.o dmub_reg.o dmub_dcn20.o dmub_dcn21.o -ifdef CONFIG_DRM_AMD_DC_DCN3_0 -DMUB += dmub_dcn30.o -endif +DMUB += dmub_dcn30.o dmub_dcn301.o +DMUB += dmub_dcn302.o AMD_DAL_DMUB = $(addprefix $(AMDDALPATH)/dmub/src/,$(DMUB)) diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c index 2c4a2fe9311d..cafba1d23c6a 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c @@ -312,3 +312,26 @@ uint32_t dmub_dcn20_get_gpint_response(struct dmub_srv *dmub) { return REG_READ(DMCUB_SCRATCH7); } + +union dmub_fw_boot_status dmub_dcn20_get_fw_boot_status(struct dmub_srv *dmub) +{ + union dmub_fw_boot_status status; + + status.all = REG_READ(DMCUB_SCRATCH0); + return status; +} + +void dmub_dcn20_enable_dmub_boot_options(struct dmub_srv *dmub) +{ + union dmub_fw_boot_options boot_options = {0}; + + REG_WRITE(DMCUB_SCRATCH14, boot_options.all); +} + +void dmub_dcn20_skip_dmub_panel_power_sequence(struct dmub_srv *dmub, bool skip) +{ + union dmub_fw_boot_options boot_options; + boot_options.all = REG_READ(DMCUB_SCRATCH14); + boot_options.bits.skip_phy_init_panel_sequence = skip; + REG_WRITE(DMCUB_SCRATCH14, boot_options.all); +} diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h index a316f260f6ac..d438f365cbb0 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h @@ -192,4 +192,10 @@ bool dmub_dcn20_is_gpint_acked(struct dmub_srv *dmub, uint32_t dmub_dcn20_get_gpint_response(struct dmub_srv *dmub); +void dmub_dcn20_enable_dmub_boot_options(struct dmub_srv *dmub); + +void dmub_dcn20_skip_dmub_panel_power_sequence(struct dmub_srv *dmub, bool skip); + +union dmub_fw_boot_status dmub_dcn20_get_fw_boot_status(struct dmub_srv *dmub); + #endif /* _DMUB_DCN20_H_ */ diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.c index e8f488232e34..1cf67b3e4771 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.c @@ -53,11 +53,6 @@ const struct dmub_srv_common_regs dmub_srv_dcn21_regs = { /* Shared functions. */ -bool dmub_dcn21_is_auto_load_done(struct dmub_srv *dmub) -{ - return (REG_READ(DMCUB_SCRATCH0) == 3); -} - bool dmub_dcn21_is_phy_init(struct dmub_srv *dmub) { return REG_READ(DMCUB_SCRATCH10) == 0; diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.h index 2bbea237137b..6fd5b0cd4ef3 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn21.h @@ -34,8 +34,6 @@ extern const struct dmub_srv_common_regs dmub_srv_dcn21_regs; /* Hardware functions. */ -bool dmub_dcn21_is_auto_load_done(struct dmub_srv *dmub); - bool dmub_dcn21_is_phy_init(struct dmub_srv *dmub); #endif /* _DMUB_DCN21_H_ */ diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.c index 215178b8d415..f00df02ded81 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.c @@ -188,8 +188,3 @@ void dmub_dcn30_setup_windows(struct dmub_srv *dmub, DMCUB_REGION3_CW6_TOP_ADDRESS, cw6->region.top, DMCUB_REGION3_CW6_ENABLE, 1); } - -bool dmub_dcn30_is_auto_load_done(struct dmub_srv *dmub) -{ - return (REG_READ(DMCUB_SCRATCH0) > 0); -} diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.h index 4d8f52b8f12c..9a3afffd9b0f 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.h @@ -45,6 +45,5 @@ void dmub_dcn30_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw5, const struct dmub_window *cw6); -bool dmub_dcn30_is_auto_load_done(struct dmub_srv *dmub); #endif /* _DMUB_DCN30_H_ */ diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn301.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn301.c new file mode 100644 index 000000000000..197398257692 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn301.c @@ -0,0 +1,55 @@ +/* + * Copyright 2020 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#include "../dmub_srv.h" +#include "dmub_reg.h" +#include "dmub_dcn301.h" + +#include "dcn/dcn_3_0_1_offset.h" +#include "dcn/dcn_3_0_1_sh_mask.h" +#include "vangogh_ip_offset.h" + +#define BASE_INNER(seg) DCN_BASE__INST0_SEG##seg +#define CTX dmub +#define REGS dmub->regs + +/* Registers. */ + +const struct dmub_srv_common_regs dmub_srv_dcn301_regs = { +#define DMUB_SR(reg) REG_OFFSET(reg), + { DMUB_COMMON_REGS() }, +#undef DMUB_SR + +#define DMUB_SF(reg, field) FD_MASK(reg, field), + { DMUB_COMMON_FIELDS() }, +#undef DMUB_SF + +#define DMUB_SF(reg, field) FD_SHIFT(reg, field), + { DMUB_COMMON_FIELDS() }, +#undef DMUB_SF +}; + +/* Shared functions. */ + diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn301.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn301.h new file mode 100644 index 000000000000..faafaf300583 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn301.h @@ -0,0 +1,37 @@ +/* + * Copyright 2020 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef _DMUB_DCN301_H_ +#define _DMUB_DCN301_H_ + +#include "dmub_dcn20.h" + +/* Registers. */ + +extern const struct dmub_srv_common_regs dmub_srv_dcn301_regs; + +/* Hardware functions. */ + +#endif /* _DMUB_DCN301_H_ */ diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn302.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn302.c new file mode 100644 index 000000000000..f5db4437a882 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn302.c @@ -0,0 +1,55 @@ +/* + * Copyright 2020 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#include "../dmub_srv.h" +#include "dmub_reg.h" +#include "dmub_dcn302.h" + +#include "dimgrey_cavefish_ip_offset.h" +#include "dcn/dcn_3_0_0_offset.h" +#include "dcn/dcn_3_0_0_sh_mask.h" + +#define BASE_INNER(seg) DCN_BASE__INST0_SEG##seg +#define CTX dmub +#define REGS dmub->regs + +/* Registers. */ + +const struct dmub_srv_common_regs dmub_srv_dcn302_regs = { +#define DMUB_SR(reg) REG_OFFSET(reg), + { DMUB_COMMON_REGS() }, +#undef DMUB_SR + +#define DMUB_SF(reg, field) FD_MASK(reg, field), + { DMUB_COMMON_FIELDS() }, +#undef DMUB_SF + +#define DMUB_SF(reg, field) FD_SHIFT(reg, field), + { DMUB_COMMON_FIELDS() }, +#undef DMUB_SF +}; + +/* Shared functions. */ + diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn302.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn302.h new file mode 100644 index 000000000000..e2102c865d91 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn302.h @@ -0,0 +1,37 @@ +/* + * Copyright 2020 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef _DMUB_DCN302_H_ +#define _DMUB_DCN302_H_ + +#include "dmub_dcn20.h" + +/* Registers. */ + +extern const struct dmub_srv_common_regs dmub_srv_dcn302_regs; + +/* Hardware functions. */ + +#endif /* _DMUB_DCN302_H_ */ diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c index 08da423b24a1..f388d36af0b6 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -27,9 +27,9 @@ #include "dmub_dcn20.h" #include "dmub_dcn21.h" #include "dmub_cmd.h" -#ifdef CONFIG_DRM_AMD_DC_DCN3_0 #include "dmub_dcn30.h" -#endif +#include "dmub_dcn301.h" +#include "dmub_dcn302.h" #include "os_types.h" /* * Note: the DMUB service is standalone. No additional headers should be @@ -136,9 +136,9 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic) switch (asic) { case DMUB_ASIC_DCN20: case DMUB_ASIC_DCN21: -#ifdef CONFIG_DRM_AMD_DC_DCN3_0 case DMUB_ASIC_DCN30: -#endif + case DMUB_ASIC_DCN301: + case DMUB_ASIC_DCN302: dmub->regs = &dmub_srv_dcn20_regs; funcs->reset = dmub_dcn20_reset; @@ -153,22 +153,33 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic) funcs->set_gpint = dmub_dcn20_set_gpint; funcs->is_gpint_acked = dmub_dcn20_is_gpint_acked; funcs->get_gpint_response = dmub_dcn20_get_gpint_response; + funcs->get_fw_status = dmub_dcn20_get_fw_boot_status; + funcs->enable_dmub_boot_options = dmub_dcn20_enable_dmub_boot_options; + funcs->skip_dmub_panel_power_sequence = dmub_dcn20_skip_dmub_panel_power_sequence; if (asic == DMUB_ASIC_DCN21) { dmub->regs = &dmub_srv_dcn21_regs; - funcs->is_auto_load_done = dmub_dcn21_is_auto_load_done; funcs->is_phy_init = dmub_dcn21_is_phy_init; } -#ifdef CONFIG_DRM_AMD_DC_DCN3_0 if (asic == DMUB_ASIC_DCN30) { dmub->regs = &dmub_srv_dcn30_regs; - funcs->is_auto_load_done = dmub_dcn30_is_auto_load_done; funcs->backdoor_load = dmub_dcn30_backdoor_load; funcs->setup_windows = dmub_dcn30_setup_windows; } -#endif + if (asic == DMUB_ASIC_DCN301) { + dmub->regs = &dmub_srv_dcn301_regs; + + funcs->backdoor_load = dmub_dcn30_backdoor_load; + funcs->setup_windows = dmub_dcn30_setup_windows; + } + if (asic == DMUB_ASIC_DCN302) { + dmub->regs = &dmub_srv_dcn302_regs; + + funcs->backdoor_load = dmub_dcn30_backdoor_load; + funcs->setup_windows = dmub_dcn30_setup_windows; + } break; default: @@ -404,15 +415,16 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, cw1.region.base = DMUB_CW1_BASE; cw1.region.top = cw1.region.base + stack_fb->size - 1; - /** - * Read back all the instruction memory so we don't hang the - * DMCUB when backdoor loading if the write from x86 hasn't been - * flushed yet. This only occurs in backdoor loading. - */ - dmub_flush_buffer_mem(inst_fb); + if (params->load_inst_const && dmub->hw_funcs.backdoor_load) { + /** + * Read back all the instruction memory so we don't hang the + * DMCUB when backdoor loading if the write from x86 hasn't been + * flushed yet. This only occurs in backdoor loading. + */ + dmub_flush_buffer_mem(inst_fb); + dmub->hw_funcs.backdoor_load(dmub, &cw0, &cw1); + } - if (params->load_inst_const && dmub->hw_funcs.backdoor_load) - dmub->hw_funcs.backdoor_load(dmub, &cw0, &cw1); } if (dmub->hw_funcs.reset) @@ -524,11 +536,10 @@ enum dmub_status dmub_srv_wait_for_auto_load(struct dmub_srv *dmub, if (!dmub->hw_init) return DMUB_STATUS_INVALID; - if (!dmub->hw_funcs.is_auto_load_done) - return DMUB_STATUS_OK; - for (i = 0; i <= timeout_us; i += 100) { - if (dmub->hw_funcs.is_auto_load_done(dmub)) + union dmub_fw_boot_status status = dmub->hw_funcs.get_fw_status(dmub); + + if (status.bits.dal_fw && status.bits.mailbox_rdy) return DMUB_STATUS_OK; udelay(100); @@ -623,3 +634,46 @@ enum dmub_status dmub_srv_get_gpint_response(struct dmub_srv *dmub, return DMUB_STATUS_OK; } + +enum dmub_status dmub_srv_get_fw_boot_status(struct dmub_srv *dmub, + union dmub_fw_boot_status *status) +{ + status->all = 0; + + if (!dmub->sw_init) + return DMUB_STATUS_INVALID; + + if (dmub->hw_funcs.get_fw_status) + *status = dmub->hw_funcs.get_fw_status(dmub); + + return DMUB_STATUS_OK; +} + +enum dmub_status dmub_srv_cmd_with_reply_data(struct dmub_srv *dmub, + union dmub_rb_cmd *cmd) +{ + enum dmub_status status = DMUB_STATUS_OK; + + // Queue command + status = dmub_srv_cmd_queue(dmub, cmd); + + if (status != DMUB_STATUS_OK) + return status; + + // Execute command + status = dmub_srv_cmd_execute(dmub); + + if (status != DMUB_STATUS_OK) + return status; + + // Wait for DMUB to process command + status = dmub_srv_wait_for_idle(dmub, 100000); + + if (status != DMUB_STATUS_OK) + return status; + + // Copy data back from ring buffer into command + dmub_rb_get_return_data(&dmub->inbox1_rb, cmd); + + return status; +} |