drm/amd/display: Add Vline1 interrupt source to InterruptManager

[Why]
Enhanced sync need to use vertical_interrupt1.

[How]
Add vertical_interrupt1 source to irq manger,
Implment setup vline interrupt interface.

Signed-off-by: Fatemeh Darbehani <fatemeh.darbehani@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Fatemeh Darbehani 2019-01-11 11:00:26 -05:00 committed by Alex Deucher
parent 43a6a02eb3
commit 8fde60b7f3
6 changed files with 61 additions and 68 deletions

View File

@ -1463,11 +1463,13 @@ static void commit_planes_do_stream_update(struct dc *dc,
stream_update->adjust->v_total_min, stream_update->adjust->v_total_min,
stream_update->adjust->v_total_max); stream_update->adjust->v_total_max);
if (stream_update->periodic_fn_vsync_delta && if (stream_update->vline0_config && pipe_ctx->stream_res.tg->funcs->program_vline_interrupt)
pipe_ctx->stream_res.tg->funcs->program_vline_interrupt)
pipe_ctx->stream_res.tg->funcs->program_vline_interrupt( pipe_ctx->stream_res.tg->funcs->program_vline_interrupt(
pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, pipe_ctx->stream_res.tg, VLINE0, stream->vline0_config);
pipe_ctx->stream->periodic_fn_vsync_delta);
if (stream_update->vline1_config && pipe_ctx->stream_res.tg->funcs->program_vline_interrupt)
pipe_ctx->stream_res.tg->funcs->program_vline_interrupt(
pipe_ctx->stream_res.tg, VLINE1, stream->vline1_config);
if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) || if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
stream_update->vrr_infopacket || stream_update->vrr_infopacket ||

View File

@ -45,6 +45,11 @@ struct freesync_context {
bool dummy; bool dummy;
}; };
struct vline_config {
unsigned int start_line;
unsigned int end_line;
};
struct dc_stream_state { struct dc_stream_state {
// sink is deprecated, new code should not reference // sink is deprecated, new code should not reference
// this pointer // this pointer
@ -85,8 +90,6 @@ struct dc_stream_state {
uint8_t qs_bit; uint8_t qs_bit;
uint8_t qy_bit; uint8_t qy_bit;
unsigned long long periodic_fn_vsync_delta;
/* TODO: custom INFO packets */ /* TODO: custom INFO packets */
/* TODO: ABM info (DMCU) */ /* TODO: ABM info (DMCU) */
/* PSR info */ /* PSR info */
@ -96,6 +99,9 @@ struct dc_stream_state {
/* DMCU info */ /* DMCU info */
unsigned int abm_level; unsigned int abm_level;
struct vline_config vline0_config;
struct vline_config vline1_config;
/* from core_stream struct */ /* from core_stream struct */
struct dc_context *ctx; struct dc_context *ctx;
@ -143,7 +149,9 @@ struct dc_stream_update {
struct dc_info_packet *hdr_static_metadata; struct dc_info_packet *hdr_static_metadata;
unsigned int *abm_level; unsigned int *abm_level;
unsigned long long *periodic_fn_vsync_delta; struct vline_config *vline0_config;
struct vline_config *vline1_config;
struct dc_crtc_timing_adjust *adjust; struct dc_crtc_timing_adjust *adjust;
struct dc_info_packet *vrr_infopacket; struct dc_info_packet *vrr_infopacket;
struct dc_info_packet *vsc_infopacket; struct dc_info_packet *vsc_infopacket;

View File

@ -92,68 +92,26 @@ static void optc1_disable_stereo(struct timing_generator *optc)
OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0); OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0);
} }
static uint32_t get_start_vline(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing)
{
struct dc_crtc_timing patched_crtc_timing;
int vesa_sync_start;
int asic_blank_end;
int vertical_line_start;
patched_crtc_timing = *dc_crtc_timing;
optc1_apply_front_porch_workaround(optc, &patched_crtc_timing);
vesa_sync_start = patched_crtc_timing.v_addressable +
patched_crtc_timing.v_border_bottom +
patched_crtc_timing.v_front_porch;
asic_blank_end = (patched_crtc_timing.v_total -
vesa_sync_start -
patched_crtc_timing.v_border_top);
vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1;
if (vertical_line_start < 0)
vertical_line_start = 0;
return vertical_line_start;
}
void optc1_program_vline_interrupt( void optc1_program_vline_interrupt(
struct timing_generator *optc, struct timing_generator *optc,
const struct dc_crtc_timing *dc_crtc_timing, enum vline_select vline,
unsigned long long vsync_delta) struct vline_config vline_config)
{ {
struct optc *optc1 = DCN10TG_FROM_TG(optc); struct optc *optc1 = DCN10TG_FROM_TG(optc);
unsigned long long req_delta_tens_of_usec = div64_u64((vsync_delta + 9999), 10000); switch (vline) {
unsigned long long pix_clk_hundreds_khz = div64_u64((dc_crtc_timing->pix_clk_100hz + 999), 1000); case VLINE0:
uint32_t req_delta_lines = (uint32_t) div64_u64( REG_SET_2(OTG_VERTICAL_INTERRUPT0_POSITION, 0,
(req_delta_tens_of_usec * pix_clk_hundreds_khz + dc_crtc_timing->h_total - 1), OTG_VERTICAL_INTERRUPT0_LINE_START, vline_config.start_line,
dc_crtc_timing->h_total); OTG_VERTICAL_INTERRUPT0_LINE_END, vline_config.end_line);
break;
uint32_t vsync_line = get_start_vline(optc, dc_crtc_timing); case VLINE1:
uint32_t start_line = 0; REG_SET(OTG_VERTICAL_INTERRUPT1_POSITION, 0,
uint32_t end_line = 0; OTG_VERTICAL_INTERRUPT1_LINE_START, vline_config.start_line);
break;
if (req_delta_lines != 0) default:
req_delta_lines--; break;
}
if (req_delta_lines > vsync_line)
start_line = dc_crtc_timing->v_total - (req_delta_lines - vsync_line) + 2;
else
start_line = vsync_line - req_delta_lines;
end_line = start_line + 2;
if (start_line >= dc_crtc_timing->v_total)
start_line = start_line % dc_crtc_timing->v_total;
if (end_line >= dc_crtc_timing->v_total)
end_line = end_line % dc_crtc_timing->v_total;
REG_SET_2(OTG_VERTICAL_INTERRUPT0_POSITION, 0,
OTG_VERTICAL_INTERRUPT0_LINE_START, start_line,
OTG_VERTICAL_INTERRUPT0_LINE_END, end_line);
} }
/** /**

View File

@ -67,6 +67,8 @@
SRI(OTG_CLOCK_CONTROL, OTG, inst),\ SRI(OTG_CLOCK_CONTROL, OTG, inst),\
SRI(OTG_VERTICAL_INTERRUPT0_CONTROL, OTG, inst),\ SRI(OTG_VERTICAL_INTERRUPT0_CONTROL, OTG, inst),\
SRI(OTG_VERTICAL_INTERRUPT0_POSITION, OTG, inst),\ SRI(OTG_VERTICAL_INTERRUPT0_POSITION, OTG, inst),\
SRI(OTG_VERTICAL_INTERRUPT1_CONTROL, OTG, inst),\
SRI(OTG_VERTICAL_INTERRUPT1_POSITION, OTG, inst),\
SRI(OTG_VERTICAL_INTERRUPT2_CONTROL, OTG, inst),\ SRI(OTG_VERTICAL_INTERRUPT2_CONTROL, OTG, inst),\
SRI(OTG_VERTICAL_INTERRUPT2_POSITION, OTG, inst),\ SRI(OTG_VERTICAL_INTERRUPT2_POSITION, OTG, inst),\
SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\ SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\
@ -135,6 +137,8 @@ struct dcn_optc_registers {
uint32_t OTG_CLOCK_CONTROL; uint32_t OTG_CLOCK_CONTROL;
uint32_t OTG_VERTICAL_INTERRUPT0_CONTROL; uint32_t OTG_VERTICAL_INTERRUPT0_CONTROL;
uint32_t OTG_VERTICAL_INTERRUPT0_POSITION; uint32_t OTG_VERTICAL_INTERRUPT0_POSITION;
uint32_t OTG_VERTICAL_INTERRUPT1_CONTROL;
uint32_t OTG_VERTICAL_INTERRUPT1_POSITION;
uint32_t OTG_VERTICAL_INTERRUPT2_CONTROL; uint32_t OTG_VERTICAL_INTERRUPT2_CONTROL;
uint32_t OTG_VERTICAL_INTERRUPT2_POSITION; uint32_t OTG_VERTICAL_INTERRUPT2_POSITION;
uint32_t OPTC_INPUT_CLOCK_CONTROL; uint32_t OPTC_INPUT_CLOCK_CONTROL;
@ -227,6 +231,8 @@ struct dcn_optc_registers {
SF(OTG0_OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_INT_ENABLE, mask_sh),\ SF(OTG0_OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_INT_ENABLE, mask_sh),\
SF(OTG0_OTG_VERTICAL_INTERRUPT0_POSITION, OTG_VERTICAL_INTERRUPT0_LINE_START, mask_sh),\ SF(OTG0_OTG_VERTICAL_INTERRUPT0_POSITION, OTG_VERTICAL_INTERRUPT0_LINE_START, mask_sh),\
SF(OTG0_OTG_VERTICAL_INTERRUPT0_POSITION, OTG_VERTICAL_INTERRUPT0_LINE_END, mask_sh),\ SF(OTG0_OTG_VERTICAL_INTERRUPT0_POSITION, OTG_VERTICAL_INTERRUPT0_LINE_END, mask_sh),\
SF(OTG0_OTG_VERTICAL_INTERRUPT1_CONTROL, OTG_VERTICAL_INTERRUPT1_INT_ENABLE, mask_sh),\
SF(OTG0_OTG_VERTICAL_INTERRUPT1_POSITION, OTG_VERTICAL_INTERRUPT1_LINE_START, mask_sh),\
SF(OTG0_OTG_VERTICAL_INTERRUPT2_CONTROL, OTG_VERTICAL_INTERRUPT2_INT_ENABLE, mask_sh),\ SF(OTG0_OTG_VERTICAL_INTERRUPT2_CONTROL, OTG_VERTICAL_INTERRUPT2_INT_ENABLE, mask_sh),\
SF(OTG0_OTG_VERTICAL_INTERRUPT2_POSITION, OTG_VERTICAL_INTERRUPT2_LINE_START, mask_sh),\ SF(OTG0_OTG_VERTICAL_INTERRUPT2_POSITION, OTG_VERTICAL_INTERRUPT2_LINE_START, mask_sh),\
SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_EN, mask_sh),\ SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_EN, mask_sh),\
@ -361,6 +367,8 @@ struct dcn_optc_registers {
type OTG_VERTICAL_INTERRUPT0_INT_ENABLE;\ type OTG_VERTICAL_INTERRUPT0_INT_ENABLE;\
type OTG_VERTICAL_INTERRUPT0_LINE_START;\ type OTG_VERTICAL_INTERRUPT0_LINE_START;\
type OTG_VERTICAL_INTERRUPT0_LINE_END;\ type OTG_VERTICAL_INTERRUPT0_LINE_END;\
type OTG_VERTICAL_INTERRUPT1_INT_ENABLE;\
type OTG_VERTICAL_INTERRUPT1_LINE_START;\
type OTG_VERTICAL_INTERRUPT2_INT_ENABLE;\ type OTG_VERTICAL_INTERRUPT2_INT_ENABLE;\
type OTG_VERTICAL_INTERRUPT2_LINE_START;\ type OTG_VERTICAL_INTERRUPT2_LINE_START;\
type OPTC_INPUT_CLK_EN;\ type OPTC_INPUT_CLK_EN;\
@ -476,8 +484,8 @@ void optc1_program_timing(
bool use_vbios); bool use_vbios);
void optc1_program_vline_interrupt(struct timing_generator *optc, void optc1_program_vline_interrupt(struct timing_generator *optc,
const struct dc_crtc_timing *dc_crtc_timing, enum vline_select vline,
unsigned long long vsync_delta); struct vline_config vline_config);
void optc1_program_global_sync( void optc1_program_global_sync(
struct timing_generator *optc); struct timing_generator *optc);

View File

@ -134,6 +134,15 @@ struct dc_crtc_timing;
struct drr_params; struct drr_params;
struct vline_config;
enum vline_select {
VLINE0,
VLINE1,
VLINE2
};
struct timing_generator_funcs { struct timing_generator_funcs {
bool (*validate_timing)(struct timing_generator *tg, bool (*validate_timing)(struct timing_generator *tg,
const struct dc_crtc_timing *timing); const struct dc_crtc_timing *timing);
@ -141,8 +150,8 @@ struct timing_generator_funcs {
const struct dc_crtc_timing *timing, const struct dc_crtc_timing *timing,
bool use_vbios); bool use_vbios);
void (*program_vline_interrupt)(struct timing_generator *optc, void (*program_vline_interrupt)(struct timing_generator *optc,
const struct dc_crtc_timing *dc_crtc_timing, enum vline_select vline,
unsigned long long vsync_delta); struct vline_config vline_config);
bool (*enable_crtc)(struct timing_generator *tg); bool (*enable_crtc)(struct timing_generator *tg);
bool (*disable_crtc)(struct timing_generator *tg); bool (*disable_crtc)(struct timing_generator *tg);
bool (*is_counter_moving)(struct timing_generator *tg); bool (*is_counter_moving)(struct timing_generator *tg);

View File

@ -144,6 +144,14 @@ enum dc_irq_source {
DC_IRQ_SOURCE_DC5_VLINE0, DC_IRQ_SOURCE_DC5_VLINE0,
DC_IRQ_SOURCE_DC6_VLINE0, DC_IRQ_SOURCE_DC6_VLINE0,
DC_IRQ_SOURCE_DC1_VLINE1,
DC_IRQ_SOURCE_DC2_VLINE1,
DC_IRQ_SOURCE_DC3_VLINE1,
DC_IRQ_SOURCE_DC4_VLINE1,
DC_IRQ_SOURCE_DC5_VLINE1,
DC_IRQ_SOURCE_DC6_VLINE1,
DAL_IRQ_SOURCES_NUMBER DAL_IRQ_SOURCES_NUMBER
}; };