.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
 };
 
 
        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;
 }
 
        .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(
 
 
        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);
 };
 
 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
 
        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];
 
        // 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(