mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 09:04:39 +02:00
drm/amd/display: LSDMA support
[Why] Driver should be able to send LSDMA commands to DMCUB [How] Driver can now send LSDMA commands to DMCUB. DMCUB should process them and send to LSDMA controller. Reviewed-by: Alvin Lee <alvin.lee2@amd.com> Signed-off-by: Ostrowski Rafal <rostrows@amd.com> Signed-off-by: Fangzhi Zuo <jerry.zuo@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
6954103400
commit
00c9c4236d
|
|
@ -1984,3 +1984,202 @@ void dc_dmub_srv_ips_query_residency_info(struct dc_dmub_srv *dc_dmub_srv, struc
|
|||
DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY))
|
||||
output->histogram[i] = 0;
|
||||
}
|
||||
|
||||
bool dmub_lsdma_init(struct dc_dmub_srv *dc_dmub_srv)
|
||||
{
|
||||
struct dc_context *dc_ctx = dc_dmub_srv->ctx;
|
||||
union dmub_rb_cmd cmd;
|
||||
enum dm_dmub_wait_type wait_type;
|
||||
struct dmub_cmd_lsdma_data *lsdma_data = &cmd.lsdma.lsdma_data;
|
||||
bool result;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
cmd.cmd_common.header.type = DMUB_CMD__LSDMA;
|
||||
cmd.cmd_common.header.sub_type = DMUB_CMD__LSDMA_INIT_CONFIG;
|
||||
wait_type = DM_DMUB_WAIT_TYPE_NO_WAIT;
|
||||
|
||||
lsdma_data->u.init_data.gpu_addr_base.quad_part = dc_ctx->dmub_srv->dmub->lsdma_rb_fb.gpu_addr;
|
||||
lsdma_data->u.init_data.ring_size = dc_ctx->dmub_srv->dmub->lsdma_rb_fb.size;
|
||||
|
||||
result = dc_wake_and_execute_dmub_cmd(dc_ctx, &cmd, wait_type);
|
||||
|
||||
if (!result)
|
||||
DC_ERROR("LSDMA Init failed in DMUB");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool dmub_lsdma_send_linear_copy_packet(
|
||||
struct dc_dmub_srv *dc_dmub_srv,
|
||||
uint64_t src_addr,
|
||||
uint64_t dst_addr,
|
||||
uint32_t count)
|
||||
{
|
||||
struct dc_context *dc_ctx = dc_dmub_srv->ctx;
|
||||
union dmub_rb_cmd cmd;
|
||||
enum dm_dmub_wait_type wait_type;
|
||||
struct dmub_cmd_lsdma_data *lsdma_data = &cmd.lsdma.lsdma_data;
|
||||
bool result;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
cmd.cmd_common.header.type = DMUB_CMD__LSDMA;
|
||||
cmd.cmd_common.header.sub_type = DMUB_CMD__LSDMA_LINEAR_COPY;
|
||||
wait_type = DM_DMUB_WAIT_TYPE_NO_WAIT;
|
||||
|
||||
lsdma_data->u.linear_copy_data.count = count - 1; // LSDMA controller expects bytes to copy -1
|
||||
lsdma_data->u.linear_copy_data.src_lo = src_addr & 0xFFFFFFFF;
|
||||
lsdma_data->u.linear_copy_data.src_hi = (src_addr >> 32) & 0xFFFFFFFF;
|
||||
lsdma_data->u.linear_copy_data.dst_lo = dst_addr & 0xFFFFFFFF;
|
||||
lsdma_data->u.linear_copy_data.dst_hi = (dst_addr >> 32) & 0xFFFFFFFF;
|
||||
|
||||
result = dc_wake_and_execute_dmub_cmd(dc_ctx, &cmd, wait_type);
|
||||
|
||||
if (!result)
|
||||
DC_ERROR("LSDMA Linear Copy failed in DMUB");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool dmub_lsdma_send_tiled_to_tiled_copy_command(
|
||||
struct dc_dmub_srv *dc_dmub_srv,
|
||||
struct lsdma_send_tiled_to_tiled_copy_command_params params)
|
||||
{
|
||||
struct dc_context *dc_ctx = dc_dmub_srv->ctx;
|
||||
union dmub_rb_cmd cmd;
|
||||
enum dm_dmub_wait_type wait_type;
|
||||
struct dmub_cmd_lsdma_data *lsdma_data = &cmd.lsdma.lsdma_data;
|
||||
bool result;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
cmd.cmd_common.header.type = DMUB_CMD__LSDMA;
|
||||
cmd.cmd_common.header.sub_type = DMUB_CMD__LSDMA_TILED_TO_TILED_COPY;
|
||||
wait_type = DM_DMUB_WAIT_TYPE_NO_WAIT;
|
||||
|
||||
lsdma_data->u.tiled_copy_data.src_addr_lo = params.src_addr & 0xFFFFFFFF;
|
||||
lsdma_data->u.tiled_copy_data.src_addr_hi = (params.src_addr >> 32) & 0xFFFFFFFF;
|
||||
lsdma_data->u.tiled_copy_data.dst_addr_lo = params.dst_addr & 0xFFFFFFFF;
|
||||
lsdma_data->u.tiled_copy_data.dst_addr_hi = (params.dst_addr >> 32) & 0xFFFFFFFF;
|
||||
lsdma_data->u.tiled_copy_data.src_x = params.src_x;
|
||||
lsdma_data->u.tiled_copy_data.src_y = params.src_y;
|
||||
lsdma_data->u.tiled_copy_data.dst_x = params.dst_x;
|
||||
lsdma_data->u.tiled_copy_data.dst_y = params.dst_y;
|
||||
lsdma_data->u.tiled_copy_data.src_width = params.src_width - 1; // LSDMA controller expects width -1
|
||||
lsdma_data->u.tiled_copy_data.dst_width = params.dst_width - 1; // LSDMA controller expects width -1
|
||||
lsdma_data->u.tiled_copy_data.src_swizzle_mode = params.swizzle_mode;
|
||||
lsdma_data->u.tiled_copy_data.dst_swizzle_mode = params.swizzle_mode;
|
||||
lsdma_data->u.tiled_copy_data.src_element_size = params.element_size;
|
||||
lsdma_data->u.tiled_copy_data.dst_element_size = params.element_size;
|
||||
lsdma_data->u.tiled_copy_data.rect_x = params.rect_x;
|
||||
lsdma_data->u.tiled_copy_data.rect_y = params.rect_y;
|
||||
lsdma_data->u.tiled_copy_data.dcc = params.dcc;
|
||||
lsdma_data->u.tiled_copy_data.tmz = params.tmz;
|
||||
lsdma_data->u.tiled_copy_data.read_compress = params.read_compress;
|
||||
lsdma_data->u.tiled_copy_data.write_compress = params.write_compress;
|
||||
lsdma_data->u.tiled_copy_data.src_height = params.src_height - 1; // LSDMA controller expects height -1
|
||||
lsdma_data->u.tiled_copy_data.dst_height = params.dst_height - 1; // LSDMA controller expects height -1
|
||||
lsdma_data->u.tiled_copy_data.data_format = params.data_format;
|
||||
lsdma_data->u.tiled_copy_data.max_com = params.max_com;
|
||||
lsdma_data->u.tiled_copy_data.max_uncom = params.max_uncom;
|
||||
|
||||
result = dc_wake_and_execute_dmub_cmd(dc_ctx, &cmd, wait_type);
|
||||
|
||||
if (!result)
|
||||
DC_ERROR("LSDMA Tiled to Tiled Copy failed in DMUB");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool dmub_lsdma_send_pio_copy_command(
|
||||
struct dc_dmub_srv *dc_dmub_srv,
|
||||
uint64_t src_addr,
|
||||
uint64_t dst_addr,
|
||||
uint32_t byte_count,
|
||||
uint32_t overlap_disable)
|
||||
{
|
||||
struct dc_context *dc_ctx = dc_dmub_srv->ctx;
|
||||
union dmub_rb_cmd cmd;
|
||||
enum dm_dmub_wait_type wait_type;
|
||||
struct dmub_cmd_lsdma_data *lsdma_data = &cmd.lsdma.lsdma_data;
|
||||
bool result;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
cmd.cmd_common.header.type = DMUB_CMD__LSDMA;
|
||||
cmd.cmd_common.header.sub_type = DMUB_CMD__LSDMA_PIO_COPY;
|
||||
wait_type = DM_DMUB_WAIT_TYPE_NO_WAIT;
|
||||
|
||||
lsdma_data->u.pio_copy_data.packet.fields.byte_count = byte_count;
|
||||
lsdma_data->u.pio_copy_data.packet.fields.overlap_disable = overlap_disable;
|
||||
lsdma_data->u.pio_copy_data.src_lo = src_addr & 0xFFFFFFFF;
|
||||
lsdma_data->u.pio_copy_data.src_hi = (src_addr >> 32) & 0xFFFFFFFF;
|
||||
lsdma_data->u.pio_copy_data.dst_lo = dst_addr & 0xFFFFFFFF;
|
||||
lsdma_data->u.pio_copy_data.dst_hi = (dst_addr >> 32) & 0xFFFFFFFF;
|
||||
|
||||
result = dc_wake_and_execute_dmub_cmd(dc_ctx, &cmd, wait_type);
|
||||
|
||||
if (!result)
|
||||
DC_ERROR("LSDMA PIO Copy failed in DMUB");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool dmub_lsdma_send_pio_constfill_command(
|
||||
struct dc_dmub_srv *dc_dmub_srv,
|
||||
uint64_t dst_addr,
|
||||
uint32_t byte_count,
|
||||
uint32_t data)
|
||||
{
|
||||
struct dc_context *dc_ctx = dc_dmub_srv->ctx;
|
||||
union dmub_rb_cmd cmd;
|
||||
enum dm_dmub_wait_type wait_type;
|
||||
struct dmub_cmd_lsdma_data *lsdma_data = &cmd.lsdma.lsdma_data;
|
||||
bool result;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
cmd.cmd_common.header.type = DMUB_CMD__LSDMA;
|
||||
cmd.cmd_common.header.sub_type = DMUB_CMD__LSDMA_PIO_CONSTFILL;
|
||||
wait_type = DM_DMUB_WAIT_TYPE_NO_WAIT;
|
||||
|
||||
lsdma_data->u.pio_constfill_data.packet.fields.constant_fill = 1;
|
||||
lsdma_data->u.pio_constfill_data.packet.fields.byte_count = byte_count;
|
||||
lsdma_data->u.pio_constfill_data.dst_lo = dst_addr & 0xFFFFFFFF;
|
||||
lsdma_data->u.pio_constfill_data.dst_hi = (dst_addr >> 32) & 0xFFFFFFFF;
|
||||
lsdma_data->u.pio_constfill_data.data = data;
|
||||
|
||||
result = dc_wake_and_execute_dmub_cmd(dc_ctx, &cmd, wait_type);
|
||||
|
||||
if (!result)
|
||||
DC_ERROR("LSDMA PIO Constfill failed in DMUB");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool dmub_lsdma_send_poll_reg_write_command(struct dc_dmub_srv *dc_dmub_srv, uint32_t reg_addr, uint32_t reg_data)
|
||||
{
|
||||
struct dc_context *dc_ctx = dc_dmub_srv->ctx;
|
||||
union dmub_rb_cmd cmd;
|
||||
enum dm_dmub_wait_type wait_type;
|
||||
struct dmub_cmd_lsdma_data *lsdma_data = &cmd.lsdma.lsdma_data;
|
||||
bool result;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
cmd.cmd_common.header.type = DMUB_CMD__LSDMA;
|
||||
cmd.cmd_common.header.sub_type = DMUB_CMD__LSDMA_POLL_REG_WRITE;
|
||||
wait_type = DM_DMUB_WAIT_TYPE_NO_WAIT;
|
||||
|
||||
lsdma_data->u.reg_write_data.reg_addr = reg_addr;
|
||||
lsdma_data->u.reg_write_data.reg_data = reg_data;
|
||||
|
||||
result = dc_wake_and_execute_dmub_cmd(dc_ctx, &cmd, wait_type);
|
||||
|
||||
if (!result)
|
||||
DC_ERROR("LSDMA Poll Reg failed in DMUB");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -248,4 +248,59 @@ bool dc_dmub_srv_ips_residency_cntl(struct dc_dmub_srv *dc_dmub_srv, bool start_
|
|||
* @output: Output struct to copy the the residency info to
|
||||
*/
|
||||
void dc_dmub_srv_ips_query_residency_info(struct dc_dmub_srv *dc_dmub_srv, struct ips_residency_info *output);
|
||||
|
||||
bool dmub_lsdma_init(struct dc_dmub_srv *dc_dmub_srv);
|
||||
bool dmub_lsdma_send_linear_copy_packet(
|
||||
struct dc_dmub_srv *dc_dmub_srv,
|
||||
uint64_t src_addr,
|
||||
uint64_t dst_addr,
|
||||
uint32_t count);
|
||||
bool dmub_lsdma_send_pio_copy_command(
|
||||
struct dc_dmub_srv *dc_dmub_srv,
|
||||
uint64_t src_addr,
|
||||
uint64_t dst_addr,
|
||||
uint32_t byte_count,
|
||||
uint32_t overlap_disable);
|
||||
bool dmub_lsdma_send_pio_constfill_command(
|
||||
struct dc_dmub_srv *dc_dmub_srv,
|
||||
uint64_t dst_addr,
|
||||
uint32_t byte_count,
|
||||
uint32_t data);
|
||||
|
||||
struct lsdma_send_tiled_to_tiled_copy_command_params {
|
||||
uint64_t src_addr;
|
||||
uint64_t dst_addr;
|
||||
|
||||
uint32_t src_x : 16;
|
||||
uint32_t src_y : 16;
|
||||
|
||||
uint32_t dst_x : 16;
|
||||
uint32_t dst_y : 16;
|
||||
|
||||
uint32_t src_width : 16;
|
||||
uint32_t dst_width : 16;
|
||||
|
||||
uint32_t rect_x : 16;
|
||||
uint32_t rect_y : 16;
|
||||
|
||||
uint32_t src_height : 16;
|
||||
uint32_t dst_height : 16;
|
||||
|
||||
uint32_t data_format : 6;
|
||||
uint32_t swizzle_mode : 5;
|
||||
uint32_t element_size : 3;
|
||||
uint32_t dcc : 1;
|
||||
uint32_t tmz : 1;
|
||||
uint32_t read_compress : 2;
|
||||
uint32_t write_compress : 2;
|
||||
uint32_t max_com : 2;
|
||||
uint32_t max_uncom : 1;
|
||||
uint32_t padding : 9;
|
||||
};
|
||||
|
||||
bool dmub_lsdma_send_tiled_to_tiled_copy_command(
|
||||
struct dc_dmub_srv *dc_dmub_srv,
|
||||
struct lsdma_send_tiled_to_tiled_copy_command_params params);
|
||||
bool dmub_lsdma_send_poll_reg_write_command(struct dc_dmub_srv *dc_dmub_srv, uint32_t reg_addr, uint32_t reg_data);
|
||||
|
||||
#endif /* _DMUB_DC_SRV_H_ */
|
||||
|
|
|
|||
|
|
@ -131,6 +131,7 @@ enum dmub_window_id {
|
|||
DMUB_WINDOW_7_SCRATCH_MEM,
|
||||
DMUB_WINDOW_IB_MEM,
|
||||
DMUB_WINDOW_SHARED_STATE,
|
||||
DMUB_WINDOW_LSDMA_BUFFER,
|
||||
DMUB_WINDOW_TOTAL,
|
||||
};
|
||||
|
||||
|
|
@ -579,6 +580,7 @@ struct dmub_srv {
|
|||
|
||||
enum dmub_srv_power_state_type power_state;
|
||||
struct dmub_diagnostic_data debug;
|
||||
struct dmub_fb lsdma_rb_fb;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -68,6 +68,9 @@
|
|||
/* Default indirect buffer size. */
|
||||
#define DMUB_IB_MEM_SIZE (1280)
|
||||
|
||||
/* Default LSDMA ring buffer size. */
|
||||
#define DMUB_LSDMA_RB_SIZE (64 * 1024)
|
||||
|
||||
/* Number of windows in use. */
|
||||
#define DMUB_NUM_WINDOWS (DMUB_WINDOW_TOTAL)
|
||||
/* Base addresses. */
|
||||
|
|
@ -564,6 +567,7 @@ enum dmub_status
|
|||
window_sizes[DMUB_WINDOW_7_SCRATCH_MEM] = DMUB_SCRATCH_MEM_SIZE;
|
||||
window_sizes[DMUB_WINDOW_IB_MEM] = DMUB_IB_MEM_SIZE;
|
||||
window_sizes[DMUB_WINDOW_SHARED_STATE] = max(DMUB_FW_HEADER_SHARED_STATE_SIZE, shared_state_size);
|
||||
window_sizes[DMUB_WINDOW_LSDMA_BUFFER] = DMUB_LSDMA_RB_SIZE;
|
||||
|
||||
out->fb_size =
|
||||
dmub_srv_calc_regions_for_memory_type(params, out, window_sizes, DMUB_WINDOW_MEMORY_TYPE_FB);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user