Commit 08502ceb authored by Aurabindo Pillai's avatar Aurabindo Pillai Committed by Alex Deucher

drm/amd/display: Add DCN401 dependant changes for DMCUB

Update for DCN 4.0.1.
Signed-off-by: default avatarAurabindo Pillai <aurabindo.pillai@amd.com>
Acked-by: default avatarRodrigo Siqueira <rodrigo.siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent a64a5212
......@@ -67,10 +67,6 @@
#include "inc/dmub_cmd.h"
#include "dc/dc_types.h"
#if defined(__cplusplus)
extern "C" {
#endif
#define DMUB_PC_SNAPSHOT_COUNT 10
/* Forward declarations */
......@@ -115,6 +111,7 @@ enum dmub_asic {
DMUB_ASIC_DCN321,
DMUB_ASIC_DCN35,
DMUB_ASIC_DCN351,
DMUB_ASIC_DCN401,
DMUB_ASIC_MAX,
};
......@@ -300,6 +297,7 @@ struct dmub_srv_hw_params {
bool ips_sequential_ono;
enum dmub_memory_access_type mem_access_type;
enum dmub_ips_disable_type disable_ips;
bool disallow_phy_access;
};
/**
......@@ -453,6 +451,19 @@ struct dmub_srv_hw_funcs {
void (*init_reg_offsets)(struct dmub_srv *dmub, struct dc_context *ctx);
void (*subvp_save_surf_addr)(struct dmub_srv *dmub, const struct dc_plane_address *addr, uint8_t subvp_index);
void (*send_reg_inbox0_cmd_msg)(struct dmub_srv *dmub,
union dmub_rb_cmd *cmd);
uint32_t (*read_reg_inbox0_rsp_int_status)(struct dmub_srv *dmub);
void (*read_reg_inbox0_cmd_rsp)(struct dmub_srv *dmub,
union dmub_rb_cmd *cmd);
void (*write_reg_inbox0_rsp_int_ack)(struct dmub_srv *dmub);
uint32_t (*read_reg_outbox0_rdy_int_status)(struct dmub_srv *dmub);
void (*write_reg_outbox0_rdy_int_ack)(struct dmub_srv *dmub);
void (*read_reg_outbox0_msg)(struct dmub_srv *dmub, uint32_t *msg);
void (*write_reg_outbox0_rsp)(struct dmub_srv *dmub, uint32_t *rsp);
uint32_t (*read_reg_outbox0_rsp_int_status)(struct dmub_srv *dmub);
void (*enable_reg_inbox0_rsp_int)(struct dmub_srv *dmub, bool enable);
void (*enable_reg_outbox0_rdy_int)(struct dmub_srv *dmub, bool enable);
};
/**
......@@ -496,6 +507,7 @@ struct dmub_srv {
const struct dmub_srv_dcn31_regs *regs_dcn31;
struct dmub_srv_dcn32_regs *regs_dcn32;
struct dmub_srv_dcn35_regs *regs_dcn35;
const struct dmub_srv_dcn401_regs *regs_dcn401;
struct dmub_srv_base_funcs funcs;
struct dmub_srv_hw_funcs hw_funcs;
......@@ -926,6 +938,26 @@ enum dmub_status dmub_srv_clear_inbox0_ack(struct dmub_srv *dmub);
*/
void dmub_srv_subvp_save_surf_addr(struct dmub_srv *dmub, const struct dc_plane_address *addr, uint8_t subvp_index);
/**
* dmub_srv_send_reg_inbox0_cmd() - send a dmub command and wait for the command
* being processed by DMUB.
* @dmub: The dmub service
* @cmd: The dmub command being sent. If with_replay is true, the function will
* update cmd with replied data.
* @with_reply: true if DMUB reply needs to be copied back to cmd. false if the
* cmd doesn't need to be replied.
* @timeout_us: timeout in microseconds.
*
* Return:
* DMUB_STATUS_OK - success
* DMUB_STATUS_TIMEOUT - DMUB fails to process the command within the timeout
* interval.
*/
enum dmub_status dmub_srv_send_reg_inbox0_cmd(
struct dmub_srv *dmub,
union dmub_rb_cmd *cmd,
bool with_reply, uint32_t timeout_us);
/**
* dmub_srv_set_power_state() - Track DC power state in dmub_srv
* @dmub: The dmub service
......@@ -938,8 +970,4 @@ void dmub_srv_subvp_save_surf_addr(struct dmub_srv *dmub, const struct dc_plane_
*/
void dmub_srv_set_power_state(struct dmub_srv *dmub, enum dmub_srv_power_state_type dmub_srv_power_state);
#if defined(__cplusplus)
}
#endif
#endif /* _DMUB_SRV_H_ */
......@@ -150,10 +150,6 @@
#define dmub_memset(dest, val, bytes) memset((dest), (val), (bytes))
#endif
#if defined(__cplusplus)
extern "C" {
#endif
/**
* OS/FW agnostic udelay
*/
......@@ -487,10 +483,6 @@ struct dmub_visual_confirm_color {
uint16_t panel_inst;
};
#if defined(__cplusplus)
}
#endif
//==============================================================================
//</DMUB_TYPES>=================================================================
//==============================================================================
......@@ -1582,6 +1574,223 @@ struct dmub_rb_cmd_fw_assisted_mclk_switch_v2 {
struct dmub_cmd_fw_assisted_mclk_switch_config_v2 config_data;
};
struct dmub_flip_addr_info {
uint32_t surf_addr_lo;
uint32_t surf_addr_c_lo;
uint32_t meta_addr_lo;
uint32_t meta_addr_c_lo;
uint16_t surf_addr_hi;
uint16_t surf_addr_c_hi;
uint16_t meta_addr_hi;
uint16_t meta_addr_c_hi;
};
struct dmub_fams2_flip_info {
union {
struct {
uint8_t is_immediate: 1;
} bits;
uint8_t all;
} config;
uint8_t otg_inst;
uint8_t pipe_mask;
uint8_t pad;
struct dmub_flip_addr_info addr_info;
};
struct dmub_rb_cmd_fams2_flip {
struct dmub_cmd_header header;
struct dmub_fams2_flip_info flip_info;
};
struct dmub_optc_state_v2 {
uint32_t v_total_min;
uint32_t v_total_max;
uint32_t v_total_mid;
uint32_t v_total_mid_frame_num;
uint8_t program_manual_trigger;
uint8_t tg_inst;
uint8_t pad[2];
};
struct dmub_optc_position {
uint32_t vpos;
uint32_t hpos;
uint32_t frame;
};
struct dmub_rb_cmd_fams2_drr_update {
struct dmub_cmd_header header;
struct dmub_optc_state_v2 dmub_optc_state_req;
};
/* HW and FW global configuration data for FAMS2 */
/* FAMS2 types and structs */
enum fams2_stream_type {
FAMS2_STREAM_TYPE_NONE = 0,
FAMS2_STREAM_TYPE_VBLANK = 1,
FAMS2_STREAM_TYPE_VACTIVE = 2,
FAMS2_STREAM_TYPE_DRR = 3,
FAMS2_STREAM_TYPE_SUBVP = 4,
};
/* dynamic stream state */
struct dmub_fams2_legacy_stream_dynamic_state {
uint8_t force_allow_at_vblank;
uint8_t pad[3];
};
struct dmub_fams2_subvp_stream_dynamic_state {
uint16_t viewport_start_hubp_vline;
uint16_t viewport_height_hubp_vlines;
uint16_t viewport_start_c_hubp_vline;
uint16_t viewport_height_c_hubp_vlines;
uint16_t phantom_viewport_height_hubp_vlines;
uint16_t phantom_viewport_height_c_hubp_vlines;
uint16_t microschedule_start_otg_vline;
uint16_t mall_start_otg_vline;
uint16_t mall_start_hubp_vline;
uint16_t mall_start_c_hubp_vline;
uint8_t force_allow_at_vblank_only;
uint8_t pad[3];
};
struct dmub_fams2_drr_stream_dynamic_state {
uint16_t stretched_vtotal;
uint8_t use_cur_vtotal;
uint8_t pad;
};
struct dmub_fams2_stream_dynamic_state {
uint64_t ref_tick;
uint32_t cur_vtotal;
uint16_t adjusted_allow_end_otg_vline;
uint8_t pad[2];
struct dmub_optc_position ref_otg_pos;
struct dmub_optc_position target_otg_pos;
union {
struct dmub_fams2_legacy_stream_dynamic_state legacy;
struct dmub_fams2_subvp_stream_dynamic_state subvp;
struct dmub_fams2_drr_stream_dynamic_state drr;
} sub_state;
};
/* static stream state */
struct dmub_fams2_legacy_stream_static_state {
uint8_t vactive_det_fill_delay_otg_vlines;
uint8_t programming_delay_otg_vlines;
};
struct dmub_fams2_subvp_stream_static_state {
uint16_t vratio_numerator;
uint16_t vratio_denominator;
uint16_t phantom_vtotal;
uint16_t phantom_vactive;
union {
struct {
uint8_t is_multi_planar : 1;
uint8_t is_yuv420 : 1;
} bits;
uint8_t all;
} config;
uint8_t programming_delay_otg_vlines;
uint8_t prefetch_to_mall_otg_vlines;
uint8_t phantom_otg_inst;
uint8_t phantom_pipe_mask;
uint8_t phantom_plane_pipe_masks[DMUB_MAX_PHANTOM_PLANES]; // phantom pipe mask per plane (for flip passthrough)
};
struct dmub_fams2_drr_stream_static_state {
uint16_t nom_stretched_vtotal;
uint8_t programming_delay_otg_vlines;
uint8_t only_stretch_if_required;
uint8_t pad[2];
};
struct dmub_fams2_stream_static_state {
enum fams2_stream_type type;
uint32_t otg_vline_time_ns;
uint32_t otg_vline_time_ticks;
uint16_t htotal;
uint16_t vtotal; // nominal vtotal
uint16_t vblank_start;
uint16_t vblank_end;
uint16_t max_vtotal;
uint16_t allow_start_otg_vline;
uint16_t allow_end_otg_vline;
uint16_t drr_keepout_otg_vline; // after this vline, vtotal cannot be changed
uint8_t scheduling_delay_otg_vlines; // min time to budget for ready to microschedule start
uint8_t contention_delay_otg_vlines; // time to budget for contention on execution
uint8_t vline_int_ack_delay_otg_vlines; // min time to budget for vertical interrupt firing
uint8_t allow_to_target_delay_otg_vlines; // time from allow vline to target vline
union {
struct {
uint8_t is_drr: 1; // stream is DRR enabled
uint8_t clamp_vtotal_min: 1; // clamp vtotal to min instead of nominal
uint8_t min_ttu_vblank_usable: 1; // if min ttu vblank is above wm, no force pstate is needed in blank
} bits;
uint8_t all;
} config;
uint8_t otg_inst;
uint8_t pipe_mask; // pipe mask for the whole config
uint8_t num_planes;
uint8_t plane_pipe_masks[DMUB_MAX_PLANES]; // pipe mask per plane (for flip passthrough)
uint8_t pad[DMUB_MAX_PLANES % 4];
union {
struct dmub_fams2_legacy_stream_static_state legacy;
struct dmub_fams2_subvp_stream_static_state subvp;
struct dmub_fams2_drr_stream_static_state drr;
} sub_state;
};
/**
* enum dmub_fams2_allow_delay_check_mode - macroscheduler mode for breaking on excessive
* p-state request to allow latency
*/
enum dmub_fams2_allow_delay_check_mode {
/* No check for request to allow delay */
FAMS2_ALLOW_DELAY_CHECK_NONE = 0,
/* Check for request to allow delay */
FAMS2_ALLOW_DELAY_CHECK_FROM_START = 1,
/* Check for prepare to allow delay */
FAMS2_ALLOW_DELAY_CHECK_FROM_PREPARE = 2,
};
union dmub_fams2_global_feature_config {
struct {
uint32_t enable: 1;
uint32_t enable_ppt_check: 1;
uint32_t enable_stall_recovery: 1;
uint32_t enable_debug: 1;
uint32_t enable_offload_flip: 1;
uint32_t enable_visual_confirm: 1;
uint32_t allow_delay_check_mode: 2;
uint32_t reserved: 24;
} bits;
uint32_t all;
};
struct dmub_cmd_fams2_global_config {
uint32_t max_allow_delay_us; // max delay to assert allow from uclk change begin
uint32_t lock_wait_time_us; // time to forecast acquisition of lock
uint32_t num_streams;
union dmub_fams2_global_feature_config features;
uint8_t pad[3];
};
union dmub_cmd_fams2_config {
struct dmub_cmd_fams2_global_config global;
struct dmub_fams2_stream_static_state stream;
};
/**
* DMUB rb command definition for FAMS2 (merged SubVP, FPO, Legacy)
*/
struct dmub_rb_cmd_fams2 {
struct dmub_cmd_header header;
union dmub_cmd_fams2_config config;
};
/**
* enum dmub_cmd_idle_opt_type - Idle optimization command type.
*/
......@@ -2263,6 +2472,9 @@ enum dmub_cmd_fams_type {
* on (for any SubVP cases that use a DRR display)
*/
DMUB_CMD__FAMS_SET_MANUAL_TRIGGER = 3,
DMUB_CMD__FAMS2_CONFIG = 4,
DMUB_CMD__FAMS2_DRR_UPDATE = 5,
DMUB_CMD__FAMS2_FLIP = 6,
};
/**
......@@ -3547,6 +3759,7 @@ enum hw_lock_client {
* Replay is the client of HW Lock Manager.
*/
HW_LOCK_CLIENT_REPLAY = 4,
HW_LOCK_CLIENT_FAMS2 = 5,
/**
* Invalid client.
*/
......@@ -4722,7 +4935,11 @@ union dmub_rb_cmd {
* Definition of a DMUB_CMD__PSP_ASSR_ENABLE command.
*/
struct dmub_rb_cmd_assr_enable assr_enable;
struct dmub_rb_cmd_fams2 fams2_config;
struct dmub_rb_cmd_fams2_drr_update fams2_drr_update;
struct dmub_rb_cmd_fams2_flip fams2_flip;
};
/**
......@@ -4759,10 +4976,6 @@ union dmub_rb_out_cmd {
//< DMUB_RB>====================================================================
//==============================================================================
#if defined(__cplusplus)
extern "C" {
#endif
/**
* struct dmub_rb_init_params - Initialization params for DMUB ringbuffer
*/
......@@ -5039,10 +5252,6 @@ static inline void dmub_rb_get_return_data(struct dmub_rb *rb,
dmub_memcpy(cmd, rd_ptr, DMUB_RB_CMD_SIZE);
}
#if defined(__cplusplus)
}
#endif
//==============================================================================
//</DMUB_RB>====================================================================
//==============================================================================
......
......@@ -26,6 +26,7 @@ DMUB += dmub_dcn31.o dmub_dcn314.o dmub_dcn315.o dmub_dcn316.o
DMUB += dmub_dcn32.o
DMUB += dmub_dcn35.o
DMUB += dmub_dcn351.o
DMUB += dmub_dcn401.o
AMD_DAL_DMUB = $(addprefix $(AMDDALPATH)/dmub/src/,$(DMUB))
......
......@@ -108,7 +108,6 @@ struct dmub_srv;
FN(reg, f4), v4)
/* Register field getting. */
#define REG_GET(reg_name, field, val) \
dmub_reg_get(CTX, REG(reg_name), FN(reg_name, field), val)
......
......@@ -38,6 +38,7 @@
#include "dmub_dcn32.h"
#include "dmub_dcn35.h"
#include "dmub_dcn351.h"
#include "dmub_dcn401.h"
#include "os_types.h"
/*
* Note: the DMUB service is standalone. No additional headers should be
......@@ -360,6 +361,52 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
funcs->should_detect = dmub_dcn35_should_detect;
break;
case DMUB_ASIC_DCN401:
dmub->regs_dcn401 = &dmub_srv_dcn401_regs;
funcs->configure_dmub_in_system_memory = dmub_dcn401_configure_dmub_in_system_memory;
funcs->send_inbox0_cmd = dmub_dcn401_send_inbox0_cmd;
funcs->clear_inbox0_ack_register = dmub_dcn401_clear_inbox0_ack_register;
funcs->read_inbox0_ack_register = dmub_dcn401_read_inbox0_ack_register;
funcs->reset = dmub_dcn401_reset;
funcs->reset_release = dmub_dcn401_reset_release;
funcs->backdoor_load = dmub_dcn401_backdoor_load;
funcs->backdoor_load_zfb_mode = dmub_dcn401_backdoor_load_zfb_mode;
funcs->setup_windows = dmub_dcn401_setup_windows;
funcs->setup_mailbox = dmub_dcn401_setup_mailbox;
funcs->get_inbox1_wptr = dmub_dcn401_get_inbox1_wptr;
funcs->get_inbox1_rptr = dmub_dcn401_get_inbox1_rptr;
funcs->set_inbox1_wptr = dmub_dcn401_set_inbox1_wptr;
funcs->setup_out_mailbox = dmub_dcn401_setup_out_mailbox;
funcs->get_outbox1_wptr = dmub_dcn401_get_outbox1_wptr;
funcs->set_outbox1_rptr = dmub_dcn401_set_outbox1_rptr;
funcs->is_supported = dmub_dcn401_is_supported;
funcs->is_hw_init = dmub_dcn401_is_hw_init;
funcs->set_gpint = dmub_dcn401_set_gpint;
funcs->is_gpint_acked = dmub_dcn401_is_gpint_acked;
funcs->get_gpint_response = dmub_dcn401_get_gpint_response;
funcs->get_gpint_dataout = dmub_dcn401_get_gpint_dataout;
funcs->get_fw_status = dmub_dcn401_get_fw_boot_status;
funcs->enable_dmub_boot_options = dmub_dcn401_enable_dmub_boot_options;
funcs->skip_dmub_panel_power_sequence = dmub_dcn401_skip_dmub_panel_power_sequence;
//outbox0 call stacks
funcs->setup_outbox0 = dmub_dcn401_setup_outbox0;
funcs->get_outbox0_wptr = dmub_dcn401_get_outbox0_wptr;
funcs->set_outbox0_rptr = dmub_dcn401_set_outbox0_rptr;
funcs->get_current_time = dmub_dcn401_get_current_time;
funcs->get_diagnostic_data = dmub_dcn401_get_diagnostic_data;
funcs->send_reg_inbox0_cmd_msg = dmub_dcn401_send_reg_inbox0_cmd_msg;
funcs->read_reg_inbox0_rsp_int_status = dmub_dcn401_read_reg_inbox0_rsp_int_status;
funcs->read_reg_inbox0_cmd_rsp = dmub_dcn401_read_reg_inbox0_cmd_rsp;
funcs->write_reg_inbox0_rsp_int_ack = dmub_dcn401_write_reg_inbox0_rsp_int_ack;
funcs->write_reg_outbox0_rdy_int_ack = dmub_dcn401_write_reg_outbox0_rdy_int_ack;
funcs->read_reg_outbox0_msg = dmub_dcn401_read_reg_outbox0_msg;
funcs->write_reg_outbox0_rsp = dmub_dcn401_write_reg_outbox0_rsp;
funcs->read_reg_outbox0_rdy_int_status = dmub_dcn401_read_reg_outbox0_rdy_int_status;
funcs->read_reg_outbox0_rsp_int_status = dmub_dcn401_read_reg_outbox0_rsp_int_status;
funcs->enable_reg_inbox0_rsp_int = dmub_dcn401_enable_reg_inbox0_rsp_int;
funcs->enable_reg_outbox0_rdy_int = dmub_dcn401_enable_reg_outbox0_rdy_int;
break;
default:
return false;
}
......@@ -677,6 +724,10 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub,
dmub->hw_funcs.setup_mailbox(dmub, &inbox1);
if (dmub->hw_funcs.setup_out_mailbox)
dmub->hw_funcs.setup_out_mailbox(dmub, &outbox1);
if (dmub->hw_funcs.enable_reg_inbox0_rsp_int)
dmub->hw_funcs.enable_reg_inbox0_rsp_int(dmub, true);
if (dmub->hw_funcs.enable_reg_outbox0_rdy_int)
dmub->hw_funcs.enable_reg_outbox0_rdy_int(dmub, true);
dmub_memset(&rb_params, 0, sizeof(rb_params));
rb_params.ctx = dmub;
......@@ -1105,6 +1156,42 @@ void dmub_srv_subvp_save_surf_addr(struct dmub_srv *dmub, const struct dc_plane_
}
}
enum dmub_status dmub_srv_send_reg_inbox0_cmd(
struct dmub_srv *dmub,
union dmub_rb_cmd *cmd,
bool with_reply, uint32_t timeout_us)
{
uint32_t rsp_ready = 0;
uint32_t i;
dmub->hw_funcs.send_reg_inbox0_cmd_msg(dmub, cmd);
for (i = 0; i < timeout_us; i++) {
rsp_ready = dmub->hw_funcs.read_reg_inbox0_rsp_int_status(dmub);
if (rsp_ready)
break;
udelay(1);
}
if (rsp_ready == 0)
return DMUB_STATUS_TIMEOUT;
if (with_reply)
dmub->hw_funcs.read_reg_inbox0_cmd_rsp(dmub, cmd);
dmub->hw_funcs.write_reg_inbox0_rsp_int_ack(dmub);
/* wait for rsp int status is cleared to initial state before exit */
for (; i <= timeout_us; i++) {
rsp_ready = dmub->hw_funcs.read_reg_inbox0_rsp_int_status(dmub);
if (rsp_ready == 0)
break;
udelay(1);
}
ASSERT(rsp_ready == 0);
return DMUB_STATUS_OK;
}
void dmub_srv_set_power_state(struct dmub_srv *dmub, enum dmub_srv_power_state_type dmub_srv_power_state)
{
if (!dmub || !dmub->hw_init)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment