drm/amd/display: Fixing hubp programming of 3dlut fast load

[why]
HUBP needs to know the size of the lut's destination in MPC.
This is currently defaulted to 17, and needs to be set for specific
lut size.

[how]
Define and apply the missing hubp field. Taking this opportunity
to consolidate the programming of 3dlut into a hubp and mpc function.

Reviewed-by: Krunoslav Kovac <krunoslav.kovac@amd.com>
Signed-off-by: Reza Amini <reza.amini@amd.com>
Signed-off-by: Roman Li <roman.li@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Reza Amini 2025-07-14 16:22:38 -04:00 committed by Alex Deucher
parent 3df957517f
commit e63e9f8b3d
8 changed files with 148 additions and 15 deletions

View File

@ -1311,6 +1311,32 @@ union dc_3dlut_state {
};
#define MATRIX_9C__DIM_128_ALIGNED_LEN 16 // 9+8 : 9 * 8 + 7 * 8 = 72 + 56 = 128 % 128 = 0
#define MATRIX_17C__DIM_128_ALIGNED_LEN 32 //17+15: 17 * 8 + 15 * 8 = 136 + 120 = 256 % 128 = 0
#define MATRIX_33C__DIM_128_ALIGNED_LEN 64 //17+47: 17 * 8 + 47 * 8 = 136 + 376 = 512 % 128 = 0
struct lut_rgb {
uint16_t b;
uint16_t g;
uint16_t r;
uint16_t padding;
};
//this structure maps directly to how the lut will read it from memory
struct lut_mem_mapping {
union {
//NATIVE MODE 1, 2
//RGB layout [b][g][r] //red is 128 byte aligned
//BGR layout [r][g][b] //blue is 128 byte aligned
struct lut_rgb rgb_17c[17][17][MATRIX_17C__DIM_128_ALIGNED_LEN];
struct lut_rgb rgb_33c[33][33][MATRIX_33C__DIM_128_ALIGNED_LEN];
//TRANSFORMED
uint16_t linear_rgb[(33*33*33*4/128+1)*128];
};
uint16_t size;
};
struct dc_rmcm_3dlut {
bool isInUse;
const struct dc_stream_state *stream;

View File

@ -671,6 +671,7 @@ struct dcn_fl_regs_st {
uint32_t lut_done;
uint32_t lut_addr_mode;
uint32_t lut_width;
uint32_t lut_mpc_width;
uint32_t lut_tmz;
uint32_t lut_crossbar_sel_r;
uint32_t lut_crossbar_sel_g;

View File

@ -264,6 +264,7 @@
type HUBP_3DLUT_DONE;\
type HUBP_3DLUT_ADDRESSING_MODE;\
type HUBP_3DLUT_WIDTH;\
type HUBP_3DLUT_MPC_WIDTH;\
type HUBP_3DLUT_TMZ;\
type HUBP_3DLUT_CROSSBAR_SELECT_Y_G;\
type HUBP_3DLUT_CROSSBAR_SELECT_CB_B;\

View File

@ -127,6 +127,43 @@ void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum hubp_3dlut_fl_forma
REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_FORMAT, format);
}
void hubp401_program_3dlut_fl_config(
struct hubp *hubp,
struct hubp_fl_3dlut_config *cfg)
{
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
uint32_t mpc_width = {(cfg->width == 17) ? 0 : 1};
uint32_t width = {cfg->width};
if (cfg->layout == DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR)
width = (cfg->width == 17) ? 4916 : 35940;
REG_UPDATE_2(_3DLUT_FL_CONFIG,
HUBP0_3DLUT_FL_MODE, cfg->mode,
HUBP0_3DLUT_FL_FORMAT, cfg->format);
REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE,
HUBP0_3DLUT_FL_BIAS, cfg->bias,
HUBP0_3DLUT_FL_SCALE, cfg->scale);
REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH,
HUBP_3DLUT_ADDRESS_HIGH, cfg->address.lut3d.addr.high_part);
REG_UPDATE(HUBP_3DLUT_ADDRESS_LOW,
HUBP_3DLUT_ADDRESS_LOW, cfg->address.lut3d.addr.low_part);
//cross bar
REG_UPDATE_8(HUBP_3DLUT_CONTROL,
HUBP_3DLUT_MPC_WIDTH, mpc_width,
HUBP_3DLUT_WIDTH, width,
HUBP_3DLUT_CROSSBAR_SELECT_CR_R, cfg->crossbar_bit_slice_cr_r,
HUBP_3DLUT_CROSSBAR_SELECT_Y_G, cfg->crossbar_bit_slice_y_g,
HUBP_3DLUT_CROSSBAR_SELECT_CB_B, cfg->crossbar_bit_slice_cb_b,
HUBP_3DLUT_ADDRESSING_MODE, cfg->addr_mode,
HUBP_3DLUT_TMZ, cfg->protection_bits,
HUBP_3DLUT_ENABLE, cfg->enabled ? 1 : 0);
}
void hubp401_update_mall_sel(struct hubp *hubp, uint32_t mall_sel, bool c_cursor)
{
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
@ -1033,6 +1070,7 @@ static struct hubp_funcs dcn401_hubp_funcs = {
.hubp_program_3dlut_fl_crossbar = hubp401_program_3dlut_fl_crossbar,
.hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done,
.hubp_clear_tiling = hubp401_clear_tiling,
.hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config,
};
bool hubp401_construct(

View File

@ -349,6 +349,10 @@ void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum hubp_3dlut_fl_forma
void hubp401_program_3dlut_fl_mode(struct hubp *hubp, enum hubp_3dlut_fl_mode mode);
void hubp401_program_3dlut_fl_config(
struct hubp *hubp,
struct hubp_fl_3dlut_config *cfg);
void hubp401_clear_tiling(struct hubp *hubp);
void hubp401_vready_at_or_After_vsync(struct hubp *hubp,

View File

@ -328,19 +328,25 @@ static void dcn10_log_hubp_states(struct dc *dc, void *log_ctx)
}
DTN_INFO("\n=======HUBP FL======\n");
DTN_INFO(
"HUBP FL: Enabled Done adr_mode width tmz xbar_sel_R xbar_sel_G xbar_sel_B adr_hi adr_low REFCYC Bias Scale Mode Format\n");
char pLabels[18][50] = {
"inst", "Enabled ", "Done ", "adr_mode ", "width ", "mpc_width ",
"tmz", "xbar_sel_R", "xbar_sel_G", "xbar_sel_B", "adr_hi ",
"adr_low", "REFCYC", "Bias", "Scale", "Mode",
"Format", "prefetch"};
for (i = 0; i < pool->pipe_count; i++) {
struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
struct dcn_fl_regs_st *fl_regs = &s->fl_regs;
struct _vcs_dpi_display_dlg_regs_st *dlg_regs = &s->dlg_attr;
if (!s->blank_en) {
DTN_INFO("[%2d]: %5xh %6xh %5d %6d %8xh %2xh %6xh %6d %8d %8d %7d %8xh %5x %5x %5x",
uint32_t values[] = {
pool->hubps[i]->inst,
fl_regs->lut_enable,
fl_regs->lut_done,
fl_regs->lut_addr_mode,
fl_regs->lut_width,
fl_regs->lut_mpc_width,
fl_regs->lut_tmz,
fl_regs->lut_crossbar_sel_r,
fl_regs->lut_crossbar_sel_g,
@ -351,8 +357,13 @@ static void dcn10_log_hubp_states(struct dc *dc, void *log_ctx)
fl_regs->lut_fl_bias,
fl_regs->lut_fl_scale,
fl_regs->lut_fl_mode,
fl_regs->lut_fl_format);
DTN_INFO("\n");
fl_regs->lut_fl_format,
dlg_regs->dst_y_prefetch};
int num_elements = 18;
for (int j = 0; j < num_elements; j++)
DTN_INFO("%s \t %8xh\n", pLabels[j], values[j]);
}
}
@ -541,19 +552,43 @@ static void dcn10_log_color_state(struct dc *dc,
dc->caps.color.mpc.ogam_ram,
dc->caps.color.mpc.ocsc);
DTN_INFO("===== MPC RMCM 3DLUT =====\n");
DTN_INFO("MPCC: SIZE MODE MODE_CUR RD_SEL 30BIT_EN WR_EN_MASK RAM_SEL OUT_NORM_FACTOR FL_SEL OUT_OFFSET OUT_SCALE FL_DONE SOFT_UNDERFLOW HARD_UNDERFLOW MEM_PWR_ST FORCE DIS MODE\n");
char pLabels[19][50] = {
"MPCC", "SIZE", "MODE", "MODE_CUR", "RD_SEL",
"30BIT_EN", "WR_EN_MASK", "RAM_SEL", "OUT_NORM_FACTOR", "FL_SEL",
"OUT_OFFSET", "OUT_SCALE", "FL_DONE", "SOFT_UNDERFLOW", "HARD_UNDERFLOW",
"MEM_PWR_ST", "FORCE", "DIS", "MODE"};
for (i = 0; i < pool->mpcc_count; i++) {
struct mpcc_state s = {0};
pool->mpc->funcs->read_mpcc_state(pool->mpc, i, &s);
if (s.opp_id != 0xf)
DTN_INFO("[%2d]: %4xh %4xh %6xh %4x %4x %4x %4x %4x %4xh %4xh %6xh %4x %4x %4x %4x %4x %4x %4x\n",
i, s.rmcm_regs.rmcm_3dlut_size, s.rmcm_regs.rmcm_3dlut_mode, s.rmcm_regs.rmcm_3dlut_mode_cur,
s.rmcm_regs.rmcm_3dlut_read_sel, s.rmcm_regs.rmcm_3dlut_30bit_en, s.rmcm_regs.rmcm_3dlut_wr_en_mask,
s.rmcm_regs.rmcm_3dlut_ram_sel, s.rmcm_regs.rmcm_3dlut_out_norm_factor, s.rmcm_regs.rmcm_3dlut_fl_sel,
s.rmcm_regs.rmcm_3dlut_out_offset_r, s.rmcm_regs.rmcm_3dlut_out_scale_r, s.rmcm_regs.rmcm_3dlut_fl_done,
s.rmcm_regs.rmcm_3dlut_fl_soft_underflow, s.rmcm_regs.rmcm_3dlut_fl_hard_underflow, s.rmcm_regs.rmcm_3dlut_mem_pwr_state,
s.rmcm_regs.rmcm_3dlut_mem_pwr_force, s.rmcm_regs.rmcm_3dlut_mem_pwr_dis, s.rmcm_regs.rmcm_3dlut_mem_pwr_mode);
if (s.opp_id != 0xf) {
uint32_t values[] = {
i,
s.rmcm_regs.rmcm_3dlut_size,
s.rmcm_regs.rmcm_3dlut_mode,
s.rmcm_regs.rmcm_3dlut_mode_cur,
s.rmcm_regs.rmcm_3dlut_read_sel,
s.rmcm_regs.rmcm_3dlut_30bit_en,
s.rmcm_regs.rmcm_3dlut_wr_en_mask,
s.rmcm_regs.rmcm_3dlut_ram_sel,
s.rmcm_regs.rmcm_3dlut_out_norm_factor,
s.rmcm_regs.rmcm_3dlut_fl_sel,
s.rmcm_regs.rmcm_3dlut_out_offset_r,
s.rmcm_regs.rmcm_3dlut_out_scale_r,
s.rmcm_regs.rmcm_3dlut_fl_done,
s.rmcm_regs.rmcm_3dlut_fl_soft_underflow,
s.rmcm_regs.rmcm_3dlut_fl_hard_underflow,
s.rmcm_regs.rmcm_3dlut_mem_pwr_state,
s.rmcm_regs.rmcm_3dlut_mem_pwr_force,
s.rmcm_regs.rmcm_3dlut_mem_pwr_dis,
s.rmcm_regs.rmcm_3dlut_mem_pwr_mode};
int num_elements = 19;
for (int j = 0; j < num_elements; j++)
DTN_INFO("%s \t %8xh\n", pLabels[j], values[j]);
}
}
DTN_INFO("\n");
DTN_INFO("===== MPC RMCM Shaper =====\n");

View File

@ -89,7 +89,7 @@ enum hubp_3dlut_fl_addressing_mode {
enum hubp_3dlut_fl_width {
hubp_3dlut_fl_width_17 = 17,
hubp_3dlut_fl_width_33 = 33,
hubp_3dlut_fl_width_transformed = 4916
hubp_3dlut_fl_width_transformed = 4916, //mpc default
};
enum hubp_3dlut_fl_crossbar_bit_slice {
@ -99,6 +99,22 @@ enum hubp_3dlut_fl_crossbar_bit_slice {
hubp_3dlut_fl_crossbar_bit_slice_48_63 = 3
};
struct hubp_fl_3dlut_config {
bool enabled;
enum hubp_3dlut_fl_width width;
enum hubp_3dlut_fl_mode mode;
enum hubp_3dlut_fl_format format;
uint16_t bias;
uint16_t scale;
struct dc_plane_address address;
enum hubp_3dlut_fl_addressing_mode addr_mode;
enum dc_cm2_gpu_mem_layout layout;
uint8_t protection_bits;
enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g;
enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b;
enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r;
};
struct hubp {
const struct hubp_funcs *funcs;
struct dc_context *ctx;
@ -288,6 +304,7 @@ struct hubp_funcs {
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b,
enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r);
int (*hubp_get_3dlut_fl_done)(struct hubp *hubp);
void (*hubp_program_3dlut_fl_config)(struct hubp *hubp, struct hubp_fl_3dlut_config *cfg);
void (*hubp_clear_tiling)(struct hubp *hubp);
};

View File

@ -115,6 +115,16 @@ enum MCM_LUT_ID {
MCM_LUT_SHAPER
};
struct mpc_fl_3dlut_config {
bool enabled;
uint16_t width;
bool select_lut_bank_a;
uint16_t bit_depth;
int hubp_index;
uint16_t bias;
uint16_t scale;
};
union mcm_lut_params {
const struct pwl_params *pwl;
const struct tetrahedral_params *lut3d;
@ -1098,6 +1108,7 @@ struct mpc_funcs {
* MPC RMCM new HW sequential programming functions
*/
struct {
void (*fl_3dlut_configure)(struct mpc *mpc, struct mpc_fl_3dlut_config *cfg, int mpcc_id);
void (*enable_3dlut_fl)(struct mpc *mpc, bool enable, int mpcc_id);
void (*update_3dlut_fast_load_select)(struct mpc *mpc, int mpcc_id, int hubp_idx);
void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id,