#define DC_LOGGER \
ctx->logger
-static inline void submit_dmub_read_modify_write(
- struct dc_reg_helper_state *offload,
- const struct dc_context *ctx)
-{
- struct dmub_rb_cmd_read_modify_write *cmd_buf = &offload->cmd_data.read_modify_write;
-
- offload->should_burst_write =
- (offload->same_addr_count == (DMUB_READ_MODIFY_WRITE_SEQ__MAX - 1));
- cmd_buf->header.payload_bytes =
- sizeof(struct dmub_cmd_read_modify_write_sequence) * offload->reg_seq_count;
-
- dc_wake_and_execute_dmub_cmd(ctx, &offload->cmd_data, DM_DMUB_WAIT_TYPE_NO_WAIT);
-
- memset(cmd_buf, 0, sizeof(*cmd_buf));
-
- offload->reg_seq_count = 0;
- offload->same_addr_count = 0;
-}
-
-static inline void submit_dmub_burst_write(
- struct dc_reg_helper_state *offload,
- const struct dc_context *ctx)
-{
- struct dmub_rb_cmd_burst_write *cmd_buf = &offload->cmd_data.burst_write;
-
- cmd_buf->header.payload_bytes =
- sizeof(uint32_t) * offload->reg_seq_count;
-
- dc_wake_and_execute_dmub_cmd(ctx, &offload->cmd_data, DM_DMUB_WAIT_TYPE_NO_WAIT);
-
- memset(cmd_buf, 0, sizeof(*cmd_buf));
-
- offload->reg_seq_count = 0;
-}
-
-static inline void submit_dmub_reg_wait(
- struct dc_reg_helper_state *offload,
- const struct dc_context *ctx)
-{
- struct dmub_rb_cmd_reg_wait *cmd_buf = &offload->cmd_data.reg_wait;
-
- dc_wake_and_execute_dmub_cmd(ctx, &offload->cmd_data, DM_DMUB_WAIT_TYPE_NO_WAIT);
-
- memset(cmd_buf, 0, sizeof(*cmd_buf));
- offload->reg_seq_count = 0;
-}
-
struct dc_reg_value_masks {
uint32_t value;
uint32_t mask;
}
}
-static void dmub_flush_buffer_execute(
- struct dc_reg_helper_state *offload,
- const struct dc_context *ctx)
-{
- submit_dmub_read_modify_write(offload, ctx);
-}
-
-static void dmub_flush_burst_write_buffer_execute(
- struct dc_reg_helper_state *offload,
- const struct dc_context *ctx)
-{
- submit_dmub_burst_write(offload, ctx);
-}
-
-static bool dmub_reg_value_burst_set_pack(const struct dc_context *ctx, uint32_t addr,
- uint32_t reg_val)
-{
- struct dc_reg_helper_state *offload = &ctx->dmub_srv->reg_helper_offload;
- struct dmub_rb_cmd_burst_write *cmd_buf = &offload->cmd_data.burst_write;
-
- /* flush command if buffer is full */
- if (offload->reg_seq_count == DMUB_BURST_WRITE_VALUES__MAX)
- dmub_flush_burst_write_buffer_execute(offload, ctx);
-
- if (offload->cmd_data.cmd_common.header.type == DMUB_CMD__REG_SEQ_BURST_WRITE &&
- addr != cmd_buf->addr) {
- dmub_flush_burst_write_buffer_execute(offload, ctx);
- return false;
- }
-
- cmd_buf->header.type = DMUB_CMD__REG_SEQ_BURST_WRITE;
- cmd_buf->header.sub_type = 0;
- cmd_buf->addr = addr;
- cmd_buf->write_values[offload->reg_seq_count] = reg_val;
- offload->reg_seq_count++;
-
- return true;
-}
-
-static uint32_t dmub_reg_value_pack(const struct dc_context *ctx, uint32_t addr,
- struct dc_reg_value_masks *field_value_mask)
-{
- struct dc_reg_helper_state *offload = &ctx->dmub_srv->reg_helper_offload;
- struct dmub_rb_cmd_read_modify_write *cmd_buf = &offload->cmd_data.read_modify_write;
- struct dmub_cmd_read_modify_write_sequence *seq;
-
- /* flush command if buffer is full */
- if (offload->cmd_data.cmd_common.header.type != DMUB_CMD__REG_SEQ_BURST_WRITE &&
- offload->reg_seq_count == DMUB_READ_MODIFY_WRITE_SEQ__MAX)
- dmub_flush_buffer_execute(offload, ctx);
-
- if (offload->should_burst_write) {
- if (dmub_reg_value_burst_set_pack(ctx, addr, field_value_mask->value))
- return field_value_mask->value;
- else
- offload->should_burst_write = false;
- }
-
- /* pack commands */
- cmd_buf->header.type = DMUB_CMD__REG_SEQ_READ_MODIFY_WRITE;
- cmd_buf->header.sub_type = 0;
- seq = &cmd_buf->seq[offload->reg_seq_count];
-
- if (offload->reg_seq_count) {
- if (cmd_buf->seq[offload->reg_seq_count - 1].addr == addr)
- offload->same_addr_count++;
- else
- offload->same_addr_count = 0;
- }
-
- seq->addr = addr;
- seq->modify_mask = field_value_mask->mask;
- seq->modify_value = field_value_mask->value;
- offload->reg_seq_count++;
-
- return field_value_mask->value;
-}
-
-static void dmub_reg_wait_done_pack(const struct dc_context *ctx, uint32_t addr,
- uint32_t mask, uint32_t shift, uint32_t condition_value, uint32_t time_out_us)
-{
- struct dc_reg_helper_state *offload = &ctx->dmub_srv->reg_helper_offload;
- struct dmub_rb_cmd_reg_wait *cmd_buf = &offload->cmd_data.reg_wait;
-
- cmd_buf->header.type = DMUB_CMD__REG_REG_WAIT;
- cmd_buf->header.sub_type = 0;
- cmd_buf->reg_wait.addr = addr;
- cmd_buf->reg_wait.condition_field_value = mask & (condition_value << shift);
- cmd_buf->reg_wait.mask = mask;
- cmd_buf->reg_wait.time_out_us = time_out_us;
-}
-
uint32_t generic_reg_update_ex(const struct dc_context *ctx,
uint32_t addr, int n,
uint8_t shift1, uint32_t mask1, uint32_t field_value1,
va_end(ap);
- if (ctx->dmub_srv &&
- ctx->dmub_srv->reg_helper_offload.gather_in_progress)
- return dmub_reg_value_pack(ctx, addr, &field_value_mask);
- /* todo: return void so we can decouple code running in driver from register states */
-
/* mmio write directly */
reg_val = dm_read_reg(ctx, addr);
reg_val = (reg_val & ~field_value_mask.mask) | field_value_mask.value;
/* mmio write directly */
reg_val = (reg_val & ~field_value_mask.mask) | field_value_mask.value;
- if (ctx->dmub_srv &&
- ctx->dmub_srv->reg_helper_offload.gather_in_progress) {
- return dmub_reg_value_burst_set_pack(ctx, addr, reg_val);
- /* todo: return void so we can decouple code running in driver from register states */
- }
-
dm_write_reg(ctx, addr, reg_val);
return reg_val;
}
uint32_t reg_val;
unsigned int i;
- if (ctx->dmub_srv &&
- ctx->dmub_srv->reg_helper_offload.gather_in_progress) {
- dmub_reg_wait_done_pack(ctx, addr, mask, shift, condition_value,
- delay_between_poll_us * time_out_num_tries);
- return;
- }
-
/*
* Something is terribly wrong if time out is > 3000ms.
* 3000ms is the maximum time needed for SMU to pass values back.
{
uint32_t value = 0;
- // when reg read, there should not be any offload.
- if (ctx->dmub_srv &&
- ctx->dmub_srv->reg_helper_offload.gather_in_progress) {
- ASSERT(false);
- }
-
dm_write_reg(ctx, addr_index, index);
value = dm_read_reg(ctx, addr_data);
return value;
}
-void reg_sequence_start_gather(const struct dc_context *ctx)
-{
- /* if reg sequence is supported and enabled, set flag to
- * indicate we want to have REG_SET, REG_UPDATE macro build
- * reg sequence command buffer rather than MMIO directly.
- */
-
- if (ctx->dmub_srv && ctx->dc->debug.dmub_offload_enabled) {
- struct dc_reg_helper_state *offload =
- &ctx->dmub_srv->reg_helper_offload;
-
- /* caller sequence mismatch. need to debug caller. offload will not work!!! */
- ASSERT(!offload->gather_in_progress);
-
- offload->gather_in_progress = true;
- }
-}
-
-void reg_sequence_start_execute(const struct dc_context *ctx)
-{
- struct dc_reg_helper_state *offload;
-
- if (!ctx->dmub_srv)
- return;
-
- offload = &ctx->dmub_srv->reg_helper_offload;
-
- if (offload && offload->gather_in_progress) {
- offload->gather_in_progress = false;
- offload->should_burst_write = false;
- switch (offload->cmd_data.cmd_common.header.type) {
- case DMUB_CMD__REG_SEQ_READ_MODIFY_WRITE:
- submit_dmub_read_modify_write(offload, ctx);
- break;
- case DMUB_CMD__REG_REG_WAIT:
- submit_dmub_reg_wait(offload, ctx);
- break;
- case DMUB_CMD__REG_SEQ_BURST_WRITE:
- submit_dmub_burst_write(offload, ctx);
- break;
- default:
- return;
- }
- }
-}
-
-void reg_sequence_wait_done(const struct dc_context *ctx)
-{
- /* callback to DM to poll for last submission done*/
- struct dc_reg_helper_state *offload;
-
- if (!ctx->dmub_srv)
- return;
-
- offload = &ctx->dmub_srv->reg_helper_offload;
-
- if (offload &&
- ctx->dc->debug.dmub_offload_enabled &&
- !ctx->dc->debug.dmcub_emulation) {
- dc_dmub_srv_wait_for_idle(ctx->dmub_srv, DM_DMUB_WAIT_TYPE_WAIT, NULL);
- }
-}
-
char *dce_version_to_string(const int version)
{
switch (version) {