Commit c5d5b0ec authored by Wyatt Wood's avatar Wyatt Wood Committed by Alex Deucher

drm/amd/display: Implement abm config table copy to dmcub

[Why]
Driver must pass abm config table to dmub fw. This provides various
parameters for abm functionality.

[How]
There is too much data to be passed in an inbox message, so we must pass
this data using an indirect buffer.  Copy the table to cw7 via x86,
driver copies to fw_state structure.
Signed-off-by: default avatarWyatt Wood <wyatt.wood@amd.com>
Reviewed-by: default avatarNicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Acked-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent c06a545a
......@@ -447,7 +447,7 @@ static const struct abm_funcs dce_funcs = {
.set_backlight_level_pwm = dce_abm_set_backlight_level_pwm,
.get_current_backlight = dce_abm_get_current_backlight,
.get_target_backlight = dce_abm_get_target_backlight,
.load_abm_config = NULL,
.init_abm_config = NULL,
.set_abm_immediate_disable = dce_abm_immediate_disable
};
......
......@@ -348,11 +348,30 @@ static bool dmub_abm_set_backlight_level_pwm(
return true;
}
static bool dmub_abm_load_config(struct abm *abm,
unsigned int start_offset,
static bool dmub_abm_init_config(struct abm *abm,
const char *src,
unsigned int bytes)
{
union dmub_rb_cmd cmd;
struct dc_context *dc = abm->ctx;
// TODO: Optimize by only reading back final 4 bytes
dmub_flush_buffer_mem(&dc->dmub_srv->dmub->scratch_mem_fb);
// Copy iramtable into cw7
memcpy(dc->dmub_srv->dmub->scratch_mem_fb.cpu_addr, (void *)src, bytes);
// Fw will copy from cw7 to fw_state
cmd.abm_init_config.header.type = DMUB_CMD__ABM;
cmd.abm_init_config.header.sub_type = DMUB_CMD__ABM_INIT_CONFIG;
cmd.abm_init_config.abm_init_config_data.src.quad_part = dc->dmub_srv->dmub->scratch_mem_fb.gpu_addr;
cmd.abm_init_config.abm_init_config_data.bytes = bytes;
cmd.abm_init_config.header.payload_bytes = sizeof(struct dmub_cmd_abm_init_config_data);
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.abm_init_config.header);
dc_dmub_srv_cmd_execute(dc->dmub_srv);
dc_dmub_srv_wait_idle(dc->dmub_srv);
return true;
}
......@@ -365,7 +384,7 @@ static const struct abm_funcs abm_funcs = {
.get_current_backlight = dmub_abm_get_current_backlight,
.get_target_backlight = dmub_abm_get_target_backlight,
.set_abm_immediate_disable = dmub_abm_immediate_disable,
.load_abm_config = dmub_abm_load_config,
.init_abm_config = dmub_abm_init_config,
};
static void dmub_abm_construct(
......
......@@ -60,8 +60,7 @@ struct abm_funcs {
unsigned int (*get_current_backlight)(struct abm *abm);
unsigned int (*get_target_backlight)(struct abm *abm);
bool (*load_abm_config)(struct abm *abm,
unsigned int start_offset,
bool (*init_abm_config)(struct abm *abm,
const char *src,
unsigned int bytes);
};
......
......@@ -565,6 +565,16 @@ dmub_srv_send_gpint_command(struct dmub_srv *dmub,
enum dmub_status dmub_srv_get_gpint_response(struct dmub_srv *dmub,
uint32_t *response);
/**
* dmub_flush_buffer_mem() - Read back entire frame buffer region.
* This ensures that the write from x86 has been flushed and will not
* hang the DMCUB.
* @fb: frame buffer to flush
*
* Can be called after software initialization.
*/
void dmub_flush_buffer_mem(const struct dmub_fb *fb);
#if defined(__cplusplus)
}
#endif
......
......@@ -70,7 +70,7 @@ static inline uint32_t dmub_align(uint32_t val, uint32_t factor)
return (val + factor - 1) / factor * factor;
}
static void dmub_flush_buffer_mem(const struct dmub_fb *fb)
void dmub_flush_buffer_mem(const struct dmub_fb *fb)
{
const uint8_t *base = (const uint8_t *)fb->cpu_addr;
uint8_t buf[64];
......
......@@ -671,8 +671,8 @@ bool dmcu_load_iram(struct dmcu *dmcu,
// ABM 2.4 and up are implemented on dmcub
if (dmcu == NULL) {
fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params);
result = abm->funcs->load_abm_config(
abm, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2);
result = abm->funcs->init_abm_config(
abm, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2);
} else if (dmcu->dmcu_version.abm_version == 0x24) {
fill_iram_v_2_3((struct iram_table_v_2_2 *)ram_table, params);
result = dmcu->funcs->load_iram(
......
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