Skip to content

Commit

Permalink
drm/amd/display: Only program surface flip for video plane via dmcub
Browse files Browse the repository at this point in the history
Only need to do surface flip for video plane via dmcub.

Signed-off-by: Yongqiang Sun <yongqiang.sun@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Harry Wentland <harry.wentland@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
  • Loading branch information
Yongqiang Sun authored and Alex Deucher committed Jan 16, 2020
1 parent 9f21f37 commit bae9c49
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 75 deletions.
130 changes: 68 additions & 62 deletions drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c
Original file line number Diff line number Diff line change
Expand Up @@ -690,86 +690,98 @@ void hubp21_validate_dml_output(struct hubp *hubp,
dml_dlg_attr->refcyc_per_meta_chunk_flip_l, dlg_attr.refcyc_per_meta_chunk_flip_l);
}

static void program_surface_flip_and_addr(struct hubp *hubp, struct dmub_rb_cmd_flip *surface_flip)
static void program_surface_flip_and_addr(struct hubp *hubp, struct surface_flip_registers *flip_regs)
{
struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp);

REG_UPDATE_3(DCSURF_FLIP_CONTROL,
SURFACE_FLIP_TYPE, surface_flip->flip.flip_params.immediate,
SURFACE_FLIP_MODE_FOR_STEREOSYNC, surface_flip->flip.flip_params.grph_stereo,
SURFACE_FLIP_IN_STEREOSYNC, surface_flip->flip.flip_params.grph_stereo);
SURFACE_FLIP_TYPE, flip_regs->immediate,
SURFACE_FLIP_MODE_FOR_STEREOSYNC, flip_regs->grph_stereo,
SURFACE_FLIP_IN_STEREOSYNC, flip_regs->grph_stereo);

REG_UPDATE(VMID_SETTINGS_0,
VMID, surface_flip->flip.flip_params.vmid);
VMID, flip_regs->vmid);

REG_UPDATE_8(DCSURF_SURFACE_CONTROL,
PRIMARY_SURFACE_TMZ, surface_flip->flip.flip_params.tmz_surface,
PRIMARY_SURFACE_TMZ_C, surface_flip->flip.flip_params.tmz_surface,
PRIMARY_META_SURFACE_TMZ, surface_flip->flip.flip_params.tmz_surface,
PRIMARY_META_SURFACE_TMZ_C, surface_flip->flip.flip_params.tmz_surface,
SECONDARY_SURFACE_TMZ, surface_flip->flip.flip_params.tmz_surface,
SECONDARY_SURFACE_TMZ_C, surface_flip->flip.flip_params.tmz_surface,
SECONDARY_META_SURFACE_TMZ, surface_flip->flip.flip_params.tmz_surface,
SECONDARY_META_SURFACE_TMZ_C, surface_flip->flip.flip_params.tmz_surface);
PRIMARY_SURFACE_TMZ, flip_regs->tmz_surface,
PRIMARY_SURFACE_TMZ_C, flip_regs->tmz_surface,
PRIMARY_META_SURFACE_TMZ, flip_regs->tmz_surface,
PRIMARY_META_SURFACE_TMZ_C, flip_regs->tmz_surface,
SECONDARY_SURFACE_TMZ, flip_regs->tmz_surface,
SECONDARY_SURFACE_TMZ_C, flip_regs->tmz_surface,
SECONDARY_META_SURFACE_TMZ, flip_regs->tmz_surface,
SECONDARY_META_SURFACE_TMZ_C, flip_regs->tmz_surface);

REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0,
PRIMARY_META_SURFACE_ADDRESS_HIGH_C,
surface_flip->flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C);
flip_regs->DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C);

REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 0,
PRIMARY_META_SURFACE_ADDRESS_C,
surface_flip->flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_C);
flip_regs->DCSURF_PRIMARY_META_SURFACE_ADDRESS_C);

REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
PRIMARY_META_SURFACE_ADDRESS_HIGH,
surface_flip->flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH);
flip_regs->DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH);

REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
PRIMARY_META_SURFACE_ADDRESS,
surface_flip->flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS);
flip_regs->DCSURF_PRIMARY_META_SURFACE_ADDRESS);

REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH, 0,
SECONDARY_META_SURFACE_ADDRESS_HIGH,
surface_flip->flip.DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH);
flip_regs->DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH);

REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS, 0,
SECONDARY_META_SURFACE_ADDRESS,
surface_flip->flip.DCSURF_SECONDARY_META_SURFACE_ADDRESS);
flip_regs->DCSURF_SECONDARY_META_SURFACE_ADDRESS);


REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, 0,
SECONDARY_SURFACE_ADDRESS_HIGH,
surface_flip->flip.DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH);
flip_regs->DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH);

REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS, 0,
SECONDARY_SURFACE_ADDRESS,
surface_flip->flip.DCSURF_SECONDARY_SURFACE_ADDRESS);
flip_regs->DCSURF_SECONDARY_SURFACE_ADDRESS);


REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0,
PRIMARY_SURFACE_ADDRESS_HIGH_C,
surface_flip->flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C);
flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C);

REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0,
PRIMARY_SURFACE_ADDRESS_C,
surface_flip->flip.DCSURF_PRIMARY_SURFACE_ADDRESS_C);
flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_C);

REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
PRIMARY_SURFACE_ADDRESS_HIGH,
surface_flip->flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH);
flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH);

REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
PRIMARY_SURFACE_ADDRESS,
surface_flip->flip.DCSURF_PRIMARY_SURFACE_ADDRESS);
flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS);
}

void program_surface_flip_and_addr_dmcub(struct hubp *hubp, struct dmub_rb_cmd_flip *surface_flip)
void dmcub_PLAT_54186_wa(struct hubp *hubp, struct surface_flip_registers *flip_regs)
{
struct dc_dmub_srv *dmcub = hubp->ctx->dmub_srv;
struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp);
struct dmub_rb_cmd_PLAT_54186_wa PLAT_54186_wa = { 0 };

PLAT_54186_wa.header.type = DMUB_CMD__PLAT_54186_WA;
PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS;
PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_C = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_C;
PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH;
PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C;
PLAT_54186_wa.flip.flip_params.grph_stereo = flip_regs->grph_stereo;
PLAT_54186_wa.flip.flip_params.hubp_inst = hubp->inst;
PLAT_54186_wa.flip.flip_params.immediate = flip_regs->immediate;
PLAT_54186_wa.flip.flip_params.tmz_surface = flip_regs->tmz_surface;
PLAT_54186_wa.flip.flip_params.vmid = flip_regs->vmid;

PERF_TRACE(); // TODO: remove after performance is stable.
dc_dmub_srv_cmd_queue(dmcub, &surface_flip->header);
dc_dmub_srv_cmd_queue(dmcub, &PLAT_54186_wa.header);
PERF_TRACE(); // TODO: remove after performance is stable.
dc_dmub_srv_cmd_execute(dmcub);
PERF_TRACE(); // TODO: remove after performance is stable.
Expand All @@ -782,15 +794,11 @@ bool hubp21_program_surface_flip_and_addr(
const struct dc_plane_address *address,
bool flip_immediate)
{
struct dmub_rb_cmd_flip surface_flip = { 0 };
bool grph_stereo = false;
struct dc_debug_options *debug = &hubp->ctx->dc->debug;
struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp);
struct surface_flip_registers flip_regs = { 0 };

surface_flip.header.type = DMUB_CMD__SURFACE_FLIP;

surface_flip.flip.flip_params.vmid = address->vmid;
surface_flip.flip.flip_params.hubp_inst = hubp->inst;
flip_regs.vmid = address->vmid;

switch (address->type) {
case PLN_ADDR_TYPE_GRAPHICS:
Expand All @@ -800,15 +808,15 @@ bool hubp21_program_surface_flip_and_addr(
}

if (address->grph.meta_addr.quad_part != 0) {
surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS =
flip_regs.DCSURF_PRIMARY_META_SURFACE_ADDRESS =
address->grph.meta_addr.low_part;
surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH =
flip_regs.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH =
address->grph.meta_addr.high_part;
}

surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS =
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS =
address->grph.addr.low_part;
surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH =
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH =
address->grph.addr.high_part;
break;
case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
Expand All @@ -817,30 +825,30 @@ bool hubp21_program_surface_flip_and_addr(
break;

if (address->video_progressive.luma_meta_addr.quad_part != 0) {
surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS =
flip_regs.DCSURF_PRIMARY_META_SURFACE_ADDRESS =
address->video_progressive.luma_meta_addr.low_part;
surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH =
flip_regs.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH =
address->video_progressive.luma_meta_addr.high_part;

surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_C =
flip_regs.DCSURF_PRIMARY_META_SURFACE_ADDRESS_C =
address->video_progressive.chroma_meta_addr.low_part;
surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C =
flip_regs.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C =
address->video_progressive.chroma_meta_addr.high_part;
}

surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS =
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS =
address->video_progressive.luma_addr.low_part;
surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH =
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH =
address->video_progressive.luma_addr.high_part;

if (debug->nv12_iflip_vm_wa) {
surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_C =
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS_C =
address->video_progressive.chroma_addr.low_part + hubp21->PLAT_54186_wa_chroma_addr_offset;
} else
surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_C =
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS_C =
address->video_progressive.chroma_addr.low_part;

surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C =
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C =
address->video_progressive.chroma_addr.high_part;

break;
Expand All @@ -850,30 +858,30 @@ bool hubp21_program_surface_flip_and_addr(
if (address->grph_stereo.right_addr.quad_part == 0)
break;

grph_stereo = true;
flip_regs.grph_stereo = true;

if (address->grph_stereo.right_meta_addr.quad_part != 0) {
surface_flip.flip.DCSURF_SECONDARY_META_SURFACE_ADDRESS =
flip_regs.DCSURF_SECONDARY_META_SURFACE_ADDRESS =
address->grph_stereo.right_meta_addr.low_part;
surface_flip.flip.DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH =
flip_regs.DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH =
address->grph_stereo.right_meta_addr.high_part;
}

if (address->grph_stereo.left_meta_addr.quad_part != 0) {
surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS =
flip_regs.DCSURF_PRIMARY_META_SURFACE_ADDRESS =
address->grph_stereo.left_meta_addr.low_part;
surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH =
flip_regs.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH =
address->grph_stereo.left_meta_addr.high_part;
}

surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS =
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS =
address->grph_stereo.left_addr.low_part;
surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH =
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH =
address->grph_stereo.left_addr.high_part;

surface_flip.flip.DCSURF_SECONDARY_SURFACE_ADDRESS =
flip_regs.DCSURF_SECONDARY_SURFACE_ADDRESS =
address->grph_stereo.right_addr.low_part;
surface_flip.flip.DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH =
flip_regs.DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH =
address->grph_stereo.right_addr.high_part;

break;
Expand All @@ -882,15 +890,13 @@ bool hubp21_program_surface_flip_and_addr(
break;
}

surface_flip.flip.flip_params.vmid = address->vmid;
surface_flip.flip.flip_params.grph_stereo = grph_stereo;
surface_flip.flip.flip_params.tmz_surface = address->tmz_surface;
surface_flip.flip.flip_params.immediate = flip_immediate;
flip_regs.tmz_surface = address->tmz_surface;
flip_regs.immediate = flip_immediate;

if (hubp->ctx->dc->debug.enable_dmcub_surface_flip)
program_surface_flip_and_addr_dmcub(hubp, &surface_flip);
if (hubp->ctx->dc->debug.enable_dmcub_surface_flip && address->type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
dmcub_PLAT_54186_wa(hubp, &flip_regs);
else
program_surface_flip_and_addr(hubp, &surface_flip);
program_surface_flip_and_addr(hubp, &flip_regs);

hubp->request_address = *address;

Expand Down
20 changes: 20 additions & 0 deletions drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,26 @@ struct hubp {
bool power_gated;
};

struct surface_flip_registers {
uint32_t DCSURF_SURFACE_CONTROL;
uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH;
uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS;
uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH;
uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS;
uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C;
uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_C;
uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C;
uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_C;
uint32_t DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH;
uint32_t DCSURF_SECONDARY_META_SURFACE_ADDRESS;
uint32_t DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH;
uint32_t DCSURF_SECONDARY_SURFACE_ADDRESS;
bool tmz_surface;
bool immediate;
uint8_t vmid;
bool grph_stereo;
};

struct hubp_funcs {
void (*hubp_setup)(
struct hubp *hubp,
Expand Down
19 changes: 6 additions & 13 deletions drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ enum dmub_cmd_type {
DMUB_CMD__REG_SEQ_FIELD_UPDATE_SEQ = 2,
DMUB_CMD__REG_SEQ_BURST_WRITE = 3,
DMUB_CMD__REG_REG_WAIT = 4,
DMUB_CMD__SURFACE_FLIP = 5,
DMUB_CMD__PLAT_54186_WA = 5,
DMUB_CMD__PSR = 64,
DMUB_CMD__VBIOS = 128,
};
Expand Down Expand Up @@ -151,20 +151,12 @@ struct dmub_rb_cmd_reg_wait {
#define PHYSICAL_ADDRESS_LOC union large_integer
#endif

struct dmub_cmd_surface_flip {
struct dmub_cmd_PLAT_54186_wa {
uint32_t DCSURF_SURFACE_CONTROL;
uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH;
uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS;
uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH;
uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS;
uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C;
uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_C;
uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C;
uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_C;
uint32_t DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH;
uint32_t DCSURF_SECONDARY_META_SURFACE_ADDRESS;
uint32_t DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH;
uint32_t DCSURF_SECONDARY_SURFACE_ADDRESS;
struct {
uint8_t hubp_inst : 4;
uint8_t tmz_surface : 1;
Expand All @@ -173,11 +165,12 @@ struct dmub_cmd_surface_flip {
uint8_t grph_stereo : 1;
uint32_t reserved : 21;
} flip_params;
uint32_t reserved[9];
};

struct dmub_rb_cmd_flip {
struct dmub_rb_cmd_PLAT_54186_wa {
struct dmub_cmd_header header;
struct dmub_cmd_surface_flip flip;
struct dmub_cmd_PLAT_54186_wa flip;
};

struct dmub_cmd_digx_encoder_control_data {
Expand Down Expand Up @@ -287,7 +280,7 @@ union dmub_rb_cmd {
struct dmub_rb_cmd_psr_enable psr_enable;
struct dmub_rb_cmd_psr_copy_settings psr_copy_settings;
struct dmub_rb_cmd_psr_set_level psr_set_level;
struct dmub_rb_cmd_flip surface_flip;
struct dmub_rb_cmd_PLAT_54186_wa PLAT_54186_wa;
struct dmub_rb_cmd_psr_setup psr_setup;
};

Expand Down

0 comments on commit bae9c49

Please sign in to comment.