Commit 0057b36a authored by Sung Joon Kim's avatar Sung Joon Kim Committed by Alex Deucher

drm/amd/display: Send message to notify the DPIA host router bandwidth

[why]
Tell the system about the current host router bandwidth to be used to
measure and calculate the right voltage to be used.

[how]
Send SMU message of each DPIA host router bandwidth.
Reviewed-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Acked-by: default avatarHamza Mahfooz <hamza.mahfooz@amd.com>
Signed-off-by: default avatarSung Joon Kim <sungjoon.kim@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent a157dcc5
...@@ -218,6 +218,57 @@ static void dcn35_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr, ...@@ -218,6 +218,57 @@ static void dcn35_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
} }
} }
static uint8_t get_lowest_dpia_index(const struct dc_link *link)
{
const struct dc *dc_struct = link->dc;
uint8_t idx = 0xFF;
int i;
for (i = 0; i < MAX_PIPES * 2; ++i) {
if (!dc_struct->links[i] || dc_struct->links[i]->ep_type != DISPLAY_ENDPOINT_USB4_DPIA)
continue;
if (idx > dc_struct->links[i]->link_index)
idx = dc_struct->links[i]->link_index;
}
return idx;
}
static void dcn35_notify_host_router_bw(struct clk_mgr *clk_mgr_base, struct dc_state *context,
bool safe_to_lower)
{
struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
uint32_t host_router_bw_kbps[MAX_HOST_ROUTERS_NUM] = { 0 };
int i;
for (i = 0; i < context->stream_count; ++i) {
const struct dc_stream_state *stream = context->streams[i];
const struct dc_link *link = stream->link;
uint8_t lowest_dpia_index = 0, hr_index = 0;
if (!link)
continue;
lowest_dpia_index = get_lowest_dpia_index(link);
if (link->link_index < lowest_dpia_index)
continue;
hr_index = (link->link_index - lowest_dpia_index) / 2;
host_router_bw_kbps[hr_index] += dc_bandwidth_in_kbps_from_timing(
&stream->timing, dc_link_get_highest_encoding_format(link));
}
for (i = 0; i < MAX_HOST_ROUTERS_NUM; ++i) {
new_clocks->host_router_bw_kbps[i] = host_router_bw_kbps[i];
if (should_set_clock(safe_to_lower, new_clocks->host_router_bw_kbps[i], clk_mgr_base->clks.host_router_bw_kbps[i])) {
clk_mgr_base->clks.host_router_bw_kbps[i] = new_clocks->host_router_bw_kbps[i];
dcn35_smu_notify_host_router_bw(clk_mgr, i, new_clocks->host_router_bw_kbps[i]);
}
}
}
void dcn35_update_clocks(struct clk_mgr *clk_mgr_base, void dcn35_update_clocks(struct clk_mgr *clk_mgr_base,
struct dc_state *context, struct dc_state *context,
bool safe_to_lower) bool safe_to_lower)
...@@ -342,6 +393,10 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base, ...@@ -342,6 +393,10 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base,
dcn35_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower); dcn35_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
} }
// notify PMFW of bandwidth per DPIA tunnel
if (dc->debug.notify_dpia_hr_bw)
dcn35_notify_host_router_bw(clk_mgr_base, context, safe_to_lower);
// notify DMCUB of latest clocks // notify DMCUB of latest clocks
memset(&cmd, 0, sizeof(cmd)); memset(&cmd, 0, sizeof(cmd));
cmd.notify_clocks.header.type = DMUB_CMD__CLK_MGR; cmd.notify_clocks.header.type = DMUB_CMD__CLK_MGR;
......
...@@ -89,7 +89,8 @@ ...@@ -89,7 +89,8 @@
#define VBIOSSMC_MSG_DisableLSdma 0x1A ///< Disable LSDMA; only sent by VBIOS #define VBIOSSMC_MSG_DisableLSdma 0x1A ///< Disable LSDMA; only sent by VBIOS
#define VBIOSSMC_MSG_DpControllerPhyStatus 0x1B ///< Inform PMFW about the pre conditions for turning SLDO2 on/off . bit[0]==1 precondition is met, bit[1-2] are for DPPHY number #define VBIOSSMC_MSG_DpControllerPhyStatus 0x1B ///< Inform PMFW about the pre conditions for turning SLDO2 on/off . bit[0]==1 precondition is met, bit[1-2] are for DPPHY number
#define VBIOSSMC_MSG_QueryIPS2Support 0x1C ///< Return 1: support; else not supported #define VBIOSSMC_MSG_QueryIPS2Support 0x1C ///< Return 1: support; else not supported
#define VBIOSSMC_Message_Count 0x1D #define VBIOSSMC_MSG_NotifyHostRouterBW 0x1D
#define VBIOSSMC_Message_Count 0x1E
#define VBIOSSMC_Status_BUSY 0x0 #define VBIOSSMC_Status_BUSY 0x0
#define VBIOSSMC_Result_OK 0x1 #define VBIOSSMC_Result_OK 0x1
...@@ -98,6 +99,14 @@ ...@@ -98,6 +99,14 @@
#define VBIOSSMC_Result_CmdRejectedPrereq 0xFD #define VBIOSSMC_Result_CmdRejectedPrereq 0xFD
#define VBIOSSMC_Result_CmdRejectedBusy 0xFC #define VBIOSSMC_Result_CmdRejectedBusy 0xFC
union dcn35_dpia_host_router_bw {
struct {
uint32_t hr_id : 16;
uint32_t bw_mbps : 16;
} bits;
uint32_t all;
};
/* /*
* Function to be used instead of REG_WAIT macro because the wait ends when * Function to be used instead of REG_WAIT macro because the wait ends when
* the register is NOT EQUAL to zero, and because `the translation in msg_if.h * the register is NOT EQUAL to zero, and because `the translation in msg_if.h
...@@ -487,3 +496,13 @@ int dcn35_smu_get_ips_supported(struct clk_mgr_internal *clk_mgr) ...@@ -487,3 +496,13 @@ int dcn35_smu_get_ips_supported(struct clk_mgr_internal *clk_mgr)
//smu_print("%s: VBIOSSMC_MSG_QueryIPS2Support return = %x\n", __func__, retv); //smu_print("%s: VBIOSSMC_MSG_QueryIPS2Support return = %x\n", __func__, retv);
return retv; return retv;
} }
void dcn35_smu_notify_host_router_bw(struct clk_mgr_internal *clk_mgr, uint32_t hr_id, uint32_t bw_kbps)
{
union dcn35_dpia_host_router_bw msg_data = { 0 };
msg_data.bits.hr_id = hr_id;
msg_data.bits.bw_mbps = bw_kbps / 1000;
dcn35_smu_send_msg_with_param(clk_mgr, VBIOSSMC_MSG_NotifyHostRouterBW, msg_data.all);
}
...@@ -198,4 +198,6 @@ int dcn35_smu_exit_low_power_state(struct clk_mgr_internal *clk_mgr); ...@@ -198,4 +198,6 @@ int dcn35_smu_exit_low_power_state(struct clk_mgr_internal *clk_mgr);
int dcn35_smu_get_ips_supported(struct clk_mgr_internal *clk_mgr); int dcn35_smu_get_ips_supported(struct clk_mgr_internal *clk_mgr);
int dcn35_smu_get_dtbclk(struct clk_mgr_internal *clk_mgr); int dcn35_smu_get_dtbclk(struct clk_mgr_internal *clk_mgr);
int dcn35_smu_get_dprefclk(struct clk_mgr_internal *clk_mgr); int dcn35_smu_get_dprefclk(struct clk_mgr_internal *clk_mgr);
void dcn35_smu_notify_host_router_bw(struct clk_mgr_internal *clk_mgr, uint32_t hr_id, uint32_t bw_kbps);
#endif /* DAL_DC_35_SMU_H_ */ #endif /* DAL_DC_35_SMU_H_ */
...@@ -62,6 +62,7 @@ struct dmub_notification; ...@@ -62,6 +62,7 @@ struct dmub_notification;
#define MAX_STREAMS 6 #define MAX_STREAMS 6
#define MIN_VIEWPORT_SIZE 12 #define MIN_VIEWPORT_SIZE 12
#define MAX_NUM_EDP 2 #define MAX_NUM_EDP 2
#define MAX_HOST_ROUTERS_NUM 2
/* Display Core Interfaces */ /* Display Core Interfaces */
struct dc_versions { struct dc_versions {
...@@ -594,6 +595,7 @@ struct dc_clocks { ...@@ -594,6 +595,7 @@ struct dc_clocks {
bool prev_p_state_change_support; bool prev_p_state_change_support;
bool fclk_prev_p_state_change_support; bool fclk_prev_p_state_change_support;
int num_ways; int num_ways;
int host_router_bw_kbps[MAX_HOST_ROUTERS_NUM];
/* /*
* @fw_based_mclk_switching * @fw_based_mclk_switching
...@@ -1045,6 +1047,7 @@ struct dc_debug_options { ...@@ -1045,6 +1047,7 @@ struct dc_debug_options {
unsigned int force_easf; unsigned int force_easf;
unsigned int force_sharpness; unsigned int force_sharpness;
unsigned int force_lls; unsigned int force_lls;
bool notify_dpia_hr_bw;
}; };
......
...@@ -765,6 +765,7 @@ static const struct dc_debug_options debug_defaults_drv = { ...@@ -765,6 +765,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.ips2_entry_delay_us = 800, .ips2_entry_delay_us = 800,
.disable_dmub_reallow_idle = false, .disable_dmub_reallow_idle = false,
.static_screen_wait_frames = 2, .static_screen_wait_frames = 2,
.notify_dpia_hr_bw = true,
}; };
static const struct dc_panel_config panel_config_defaults = { static const struct dc_panel_config panel_config_defaults = {
......
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