diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce/dce_abm.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c | 25 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/hw/abm.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/modules/power/power_helpers.c | 4 |
6 files changed, 37 insertions, 9 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c index a4dae31400fa..e345df621a6a 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c @@ -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 }; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c index 81c967917c5b..06435ecaf6a3 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c @@ -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( diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h index 9cca0ca30fee..0cae258a903e 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h @@ -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); }; diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h index c2671f2616c8..af678462f0e6 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h @@ -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 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 ce32cc7933c4..0be8a54cc475 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -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]; diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c index 8bf1bdd0f457..c1a95da6706f 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c @@ -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( |