Commit 7f5c22d1 authored by Vitaly Prosyak's avatar Vitaly Prosyak Committed by Alex Deucher

drm/amd/display: RV stereo support

HDMI frame pack and DP frame alternate in band
Signed-off-by: default avatarVitaly Prosyak <vitaly.prosyak@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarHarry Wentland <Harry.Wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent aed8b319
...@@ -972,9 +972,7 @@ bool dcn_validate_bandwidth( ...@@ -972,9 +972,7 @@ bool dcn_validate_bandwidth(
if (pipe->surface) { if (pipe->surface) {
struct pipe_ctx *hsplit_pipe = pipe->bottom_pipe; struct pipe_ctx *hsplit_pipe = pipe->bottom_pipe;
if (v->dpp_per_plane[input_idx] == 2 || if (v->dpp_per_plane[input_idx] == 2) {
(pipe->stream->public.timing.timing_3d_format == TIMING_3D_FORMAT_TOP_AND_BOTTOM ||
pipe->stream->public.timing.timing_3d_format == TIMING_3D_FORMAT_SIDE_BY_SIDE)) {
if (hsplit_pipe && hsplit_pipe->surface == pipe->surface) { if (hsplit_pipe && hsplit_pipe->surface == pipe->surface) {
/* update previously split pipe */ /* update previously split pipe */
hsplit_pipe->pipe_dlg_param.vupdate_width = v->v_update_width[input_idx]; hsplit_pipe->pipe_dlg_param.vupdate_width = v->v_update_width[input_idx];
......
...@@ -832,6 +832,30 @@ static bool streams_changed( ...@@ -832,6 +832,30 @@ static bool streams_changed(
return false; return false;
} }
bool dc_enable_stereo(
struct dc *dc,
struct validate_context *context,
const struct dc_stream *streams[],
uint8_t stream_count)
{
bool ret = true;
int i, j;
struct pipe_ctx *pipe;
struct core_dc *core_dc = DC_TO_CORE(dc);
for (i = 0; i < MAX_PIPES; i++) {
if (context != NULL)
pipe = &context->res_ctx.pipe_ctx[i];
else
pipe = &core_dc->current_context->res_ctx.pipe_ctx[i];
for (j = 0 ; pipe && j < stream_count; j++) {
if (streams[j] && streams[j] == &pipe->stream->public &&
core_dc->hwss.setup_stereo)
core_dc->hwss.setup_stereo(pipe, core_dc);
}
}
return ret;
}
bool dc_commit_streams( bool dc_commit_streams(
struct dc *dc, struct dc *dc,
const struct dc_stream *streams[], const struct dc_stream *streams[],
...@@ -903,6 +927,7 @@ bool dc_commit_streams( ...@@ -903,6 +927,7 @@ bool dc_commit_streams(
DC_SURFACE_TO_CORE(context->stream_status[i].surfaces[j]); DC_SURFACE_TO_CORE(context->stream_status[i].surfaces[j]);
core_dc->hwss.apply_ctx_for_surface(core_dc, surface, context); core_dc->hwss.apply_ctx_for_surface(core_dc, surface, context);
dc_enable_stereo(dc, context, streams, stream_count);
} }
CONN_MSG_MODE(sink->link, "{%dx%d, %dx%d@%dKhz}", CONN_MSG_MODE(sink->link, "{%dx%d, %dx%d@%dKhz}",
......
...@@ -440,8 +440,8 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx) ...@@ -440,8 +440,8 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx)
bool sec_split = pipe_ctx->top_pipe && bool sec_split = pipe_ctx->top_pipe &&
pipe_ctx->top_pipe->surface == pipe_ctx->surface; pipe_ctx->top_pipe->surface == pipe_ctx->surface;
if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_SIDE_BY_SIDE || if (stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE ||
stream->timing.timing_3d_format == TIMING_3D_FORMAT_TOP_AND_BOTTOM) { stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM) {
pri_split = false; pri_split = false;
sec_split = false; sec_split = false;
} }
...@@ -568,8 +568,7 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx, struct view *recout_skip ...@@ -568,8 +568,7 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx, struct view *recout_skip
/* Handle h & vsplit */ /* Handle h & vsplit */
if (pipe_ctx->top_pipe && pipe_ctx->top_pipe->surface == if (pipe_ctx->top_pipe && pipe_ctx->top_pipe->surface ==
pipe_ctx->surface) { pipe_ctx->surface) {
if (stream->public.timing.timing_3d_format == if (stream->public.view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM) {
TIMING_3D_FORMAT_TOP_AND_BOTTOM) {
pipe_ctx->scl_data.recout.height /= 2; pipe_ctx->scl_data.recout.height /= 2;
pipe_ctx->scl_data.recout.y += pipe_ctx->scl_data.recout.height; pipe_ctx->scl_data.recout.y += pipe_ctx->scl_data.recout.height;
/* Floor primary pipe, ceil 2ndary pipe */ /* Floor primary pipe, ceil 2ndary pipe */
...@@ -581,8 +580,7 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx, struct view *recout_skip ...@@ -581,8 +580,7 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx, struct view *recout_skip
} }
} else if (pipe_ctx->bottom_pipe && } else if (pipe_ctx->bottom_pipe &&
pipe_ctx->bottom_pipe->surface == pipe_ctx->surface) { pipe_ctx->bottom_pipe->surface == pipe_ctx->surface) {
if (stream->public.timing.timing_3d_format == if (stream->public.view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM)
TIMING_3D_FORMAT_TOP_AND_BOTTOM)
pipe_ctx->scl_data.recout.height /= 2; pipe_ctx->scl_data.recout.height /= 2;
else else
pipe_ctx->scl_data.recout.width /= 2; pipe_ctx->scl_data.recout.width /= 2;
...@@ -626,7 +624,7 @@ static void calculate_scaling_ratios(struct pipe_ctx *pipe_ctx) ...@@ -626,7 +624,7 @@ static void calculate_scaling_ratios(struct pipe_ctx *pipe_ctx)
surf_src.height, surf_src.height,
surface->dst_rect.height); surface->dst_rect.height);
if (surface->stereo_format == PLANE_STEREO_FORMAT_SIDE_BY_SIDE) if (stream->public.view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE)
pipe_ctx->scl_data.ratios.horz.value *= 2; pipe_ctx->scl_data.ratios.horz.value *= 2;
else if (surface->stereo_format == PLANE_STEREO_FORMAT_TOP_AND_BOTTOM) else if (surface->stereo_format == PLANE_STEREO_FORMAT_TOP_AND_BOTTOM)
pipe_ctx->scl_data.ratios.vert.value *= 2; pipe_ctx->scl_data.ratios.vert.value *= 2;
...@@ -1772,6 +1770,8 @@ static void set_vendor_info_packet( ...@@ -1772,6 +1770,8 @@ static void set_vendor_info_packet(
enum dc_timing_3d_format format; enum dc_timing_3d_format format;
format = stream->public.timing.timing_3d_format; format = stream->public.timing.timing_3d_format;
if (stream->public.view_format == VIEW_3D_FORMAT_NONE)
format = TIMING_3D_FORMAT_NONE;
/* Can be different depending on packet content */ /* Can be different depending on packet content */
length = 5; length = 5;
......
...@@ -2057,6 +2057,11 @@ void dce110_update_pending_status(struct pipe_ctx *pipe_ctx) ...@@ -2057,6 +2057,11 @@ void dce110_update_pending_status(struct pipe_ctx *pipe_ctx)
pipe_ctx->mi->current_address = pipe_ctx->mi->request_address; pipe_ctx->mi->current_address = pipe_ctx->mi->request_address;
surface->status.current_address = pipe_ctx->mi->current_address; surface->status.current_address = pipe_ctx->mi->current_address;
if (pipe_ctx->mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
pipe_ctx->tg->funcs->is_stereo_left_eye) {
surface->status.is_right_eye =\
!pipe_ctx->tg->funcs->is_stereo_left_eye(pipe_ctx->tg);
}
} }
void dce110_power_down(struct core_dc *dc) void dce110_power_down(struct core_dc *dc)
...@@ -2576,6 +2581,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { ...@@ -2576,6 +2581,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
.set_static_screen_control = set_static_screen_control, .set_static_screen_control = set_static_screen_control,
.reset_hw_ctx_wrap = reset_hw_ctx_wrap, .reset_hw_ctx_wrap = reset_hw_ctx_wrap,
.prog_pixclk_crtc_otg = dce110_prog_pixclk_crtc_otg, .prog_pixclk_crtc_otg = dce110_prog_pixclk_crtc_otg,
.setup_stereo = NULL
}; };
bool dce110_hw_sequencer_construct(struct core_dc *dc) bool dce110_hw_sequencer_construct(struct core_dc *dc)
......
...@@ -896,8 +896,9 @@ static void reset_hw_ctx_wrap( ...@@ -896,8 +896,9 @@ static void reset_hw_ctx_wrap(
reset_hw_ctx(dc, context, reset_back_end_for_pipe); reset_hw_ctx(dc, context, reset_back_end_for_pipe);
} }
static bool patch_address_for_sbs_tb_stereo(
struct pipe_ctx *pipe_ctx, PHYSICAL_ADDRESS_LOC *addr) static bool patch_address_for_sbs_tb_stereo(struct pipe_ctx *pipe_ctx,
PHYSICAL_ADDRESS_LOC *addr)
{ {
struct core_surface *surface = pipe_ctx->surface; struct core_surface *surface = pipe_ctx->surface;
bool sec_split = pipe_ctx->top_pipe && bool sec_split = pipe_ctx->top_pipe &&
...@@ -912,6 +913,7 @@ static bool patch_address_for_sbs_tb_stereo( ...@@ -912,6 +913,7 @@ static bool patch_address_for_sbs_tb_stereo(
surface->public.address.grph_stereo.right_addr; surface->public.address.grph_stereo.right_addr;
return true; return true;
} }
return false; return false;
} }
...@@ -2061,6 +2063,66 @@ static void set_plane_config( ...@@ -2061,6 +2063,66 @@ static void set_plane_config(
program_gamut_remap(pipe_ctx); program_gamut_remap(pipe_ctx);
} }
static void dcn10_config_stereo_parameters(struct core_stream *stream,\
struct crtc_stereo_flags *flags)
{
enum view_3d_format view_format = stream->public.view_format;
enum dc_timing_3d_format timing_3d_format =\
stream->public.timing.timing_3d_format;
bool non_stereo_timing = false;
if (timing_3d_format == TIMING_3D_FORMAT_NONE ||
timing_3d_format == TIMING_3D_FORMAT_SIDE_BY_SIDE ||
timing_3d_format == TIMING_3D_FORMAT_TOP_AND_BOTTOM)
non_stereo_timing = true;
if (non_stereo_timing == false &&
view_format == VIEW_3D_FORMAT_FRAME_SEQUENTIAL) {
flags->PROGRAM_STEREO = 1;
flags->PROGRAM_POLARITY = 1;
if (timing_3d_format == TIMING_3D_FORMAT_INBAND_FA ||
timing_3d_format == TIMING_3D_FORMAT_DP_HDMI_INBAND_FA ||
timing_3d_format == TIMING_3D_FORMAT_SIDEBAND_FA) {
enum display_dongle_type dongle = \
stream->sink->link->public.ddc->dongle_type;
if (dongle == DISPLAY_DONGLE_DP_VGA_CONVERTER ||
dongle == DISPLAY_DONGLE_DP_DVI_CONVERTER ||
dongle == DISPLAY_DONGLE_DP_HDMI_CONVERTER)
flags->DISABLE_STEREO_DP_SYNC = 1;
}
flags->RIGHT_EYE_POLARITY =\
stream->public.timing.flags.RIGHT_EYE_3D_POLARITY;
if (timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
flags->FRAME_PACKED = 1;
}
return;
}
static void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx,
struct core_dc *dc)
{
struct crtc_stereo_flags flags = { 0 };
struct core_stream *stream = pipe_ctx->stream;
dcn10_config_stereo_parameters(stream, &flags);
pipe_ctx->opp->funcs->opp_set_stereo_polarity(
pipe_ctx->opp,
flags.PROGRAM_STEREO == 1 ? true:false,
stream->public.timing.flags.RIGHT_EYE_3D_POLARITY == 1 ? true:false);
pipe_ctx->tg->funcs->program_stereo(
pipe_ctx->tg,
&stream->public.timing,
&flags);
return;
}
static const struct hw_sequencer_funcs dcn10_funcs = { static const struct hw_sequencer_funcs dcn10_funcs = {
.program_gamut_remap = program_gamut_remap, .program_gamut_remap = program_gamut_remap,
.init_hw = init_hw, .init_hw = init_hw,
...@@ -2088,7 +2150,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = { ...@@ -2088,7 +2150,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.prog_pixclk_crtc_otg = dcn10_prog_pixclk_crtc_otg, .prog_pixclk_crtc_otg = dcn10_prog_pixclk_crtc_otg,
.set_drr = set_drr, .set_drr = set_drr,
.get_position = get_position, .get_position = get_position,
.set_static_screen_control = set_static_screen_control .set_static_screen_control = set_static_screen_control,
.setup_stereo = dcn10_setup_stereo
}; };
......
...@@ -821,10 +821,6 @@ static void get_pixel_clock_parameters( ...@@ -821,10 +821,6 @@ static void get_pixel_clock_parameters(
if (stream->public.timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) if (stream->public.timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
pixel_clk_params->requested_pix_clk /= 2; pixel_clk_params->requested_pix_clk /= 2;
if (stream->public.timing. timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING ||
stream->public.timing. timing_3d_format == TIMING_3D_FORMAT_SW_FRAME_PACKING ||
stream->public.timing. timing_3d_format == TIMING_3D_FORMAT_DP_HDMI_INBAND_FA)
pixel_clk_params->requested_pix_clk *= 2;
} }
static void build_clamping_params(struct core_stream *stream) static void build_clamping_params(struct core_stream *stream)
......
...@@ -271,8 +271,6 @@ static void tg_program_timing_generator( ...@@ -271,8 +271,6 @@ static void tg_program_timing_generator(
REG_UPDATE(OTG_H_TIMING_CNTL, REG_UPDATE(OTG_H_TIMING_CNTL,
OTG_H_TIMING_DIV_BY2, h_div_2); OTG_H_TIMING_DIV_BY2, h_div_2);
dcn10_disable_stereo( tg);
} }
/** tg_program_blanking /** tg_program_blanking
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment