diff options
Diffstat (limited to 'common/recipes-kernel/linux/files/0838-drm-amd-dal-minor-mpo-fixes.patch')
-rw-r--r-- | common/recipes-kernel/linux/files/0838-drm-amd-dal-minor-mpo-fixes.patch | 498 |
1 files changed, 498 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0838-drm-amd-dal-minor-mpo-fixes.patch b/common/recipes-kernel/linux/files/0838-drm-amd-dal-minor-mpo-fixes.patch new file mode 100644 index 00000000..557e5f99 --- /dev/null +++ b/common/recipes-kernel/linux/files/0838-drm-amd-dal-minor-mpo-fixes.patch @@ -0,0 +1,498 @@ +From beae654b9cd427c3daaacdb4dbbe4b89446428b2 Mon Sep 17 00:00:00 2001 +From: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> +Date: Thu, 18 Feb 2016 17:14:31 -0500 +Subject: [PATCH 0838/1110] drm/amd/dal: minor mpo fixes + +Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> +Acked-by: Harry Wentland <harry.wentland@amd.com> +--- + drivers/gpu/drm/amd/dal/dc/core/dc.c | 14 +++-- + drivers/gpu/drm/amd/dal/dc/core/dc_target.c | 58 +++++++++++++++------ + drivers/gpu/drm/amd/dal/dc/dc_hw_types.h | 5 ++ + .../drm/amd/dal/dc/dce110/dce110_hw_sequencer.c | 60 +++++++++++++--------- + .../gpu/drm/amd/dal/dc/dce110/dce110_mem_input_v.c | 28 ++++++++-- + .../amd/dal/dc/dce110/dce110_timing_generator.c | 6 ++- + .../amd/dal/dc/dce110/dce110_timing_generator_v.c | 18 ++++--- + drivers/gpu/drm/amd/dal/dc/inc/core_types.h | 1 - + 8 files changed, 127 insertions(+), 63 deletions(-) + +diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc.c b/drivers/gpu/drm/amd/dal/dc/core/dc.c +index 1d25a39..9ecd60c 100644 +--- a/drivers/gpu/drm/amd/dal/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/dal/dc/core/dc.c +@@ -175,14 +175,12 @@ static void init_hw(struct dc *dc) + for (i = 0; i < dc->res_pool.pipe_count; i++) { + xfm = dc->res_pool.transforms[i]; + +- if (i != DCE110_UNDERLAY_IDX) { +- dc->hwss.enable_display_power_gating( +- dc->ctx, i, bp, +- PIPE_GATING_CONTROL_INIT); +- dc->hwss.enable_display_power_gating( +- dc->ctx, i, bp, +- PIPE_GATING_CONTROL_DISABLE); +- } ++ dc->hwss.enable_display_power_gating( ++ dc->ctx, i, bp, ++ PIPE_GATING_CONTROL_INIT); ++ dc->hwss.enable_display_power_gating( ++ dc->ctx, i, bp, ++ PIPE_GATING_CONTROL_DISABLE); + xfm->funcs->transform_power_up(xfm); + dc->hwss.enable_display_pipe_clock_gating( + dc->ctx, +diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_target.c b/drivers/gpu/drm/amd/dal/dc/core/dc_target.c +index 42c794a..ac917e5 100644 +--- a/drivers/gpu/drm/amd/dal/dc/core/dc_target.c ++++ b/drivers/gpu/drm/amd/dal/dc/core/dc_target.c +@@ -136,11 +136,35 @@ target_alloc_fail: + return NULL; + } + ++/* ++void ProgramPixelDurationV(unsigned int pixelClockInKHz ) ++{ ++ fixed31_32 pixel_duration = Fixed31_32(100000000, pixelClockInKHz) * 10; ++ unsigned int pixDurationInPico = round(pixel_duration); ++ ++ DPG_PIPE_ARBITRATION_CONTROL1 arb_control; ++ ++ arb_control.u32All = ReadReg (mmDPGV0_PIPE_ARBITRATION_CONTROL1); ++ arb_control.bits.PIXEL_DURATION = pixDurationInPico; ++ WriteReg (mmDPGV0_PIPE_ARBITRATION_CONTROL1, arb_control.u32All); ++ ++ arb_control.u32All = ReadReg (mmDPGV1_PIPE_ARBITRATION_CONTROL1); ++ arb_control.bits.PIXEL_DURATION = pixDurationInPico; ++ WriteReg (mmDPGV1_PIPE_ARBITRATION_CONTROL1, arb_control.u32All); ++ ++ WriteReg (mmDPGV0_PIPE_ARBITRATION_CONTROL2, 0x4000800); ++ WriteReg (mmDPGV0_REPEATER_PROGRAM, 0x11); ++ ++ WriteReg (mmDPGV1_PIPE_ARBITRATION_CONTROL2, 0x4000800); ++ WriteReg (mmDPGV1_REPEATER_PROGRAM, 0x11); ++} ++*/ + static int8_t acquire_first_free_underlay( + struct resource_context *res_ctx, + struct core_stream *stream) + { +- if (!res_ctx->pipe_ctx[3].stream) { ++ if (!res_ctx->pipe_ctx[DCE110_UNDERLAY_IDX].stream) { ++ struct dc_bios *dcb; + struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[DCE110_UNDERLAY_IDX]; + + pipe_ctx->tg = res_ctx->pool.timing_generators[DCE110_UNDERLAY_IDX]; +@@ -151,16 +175,18 @@ static int8_t acquire_first_free_underlay( + pipe_ctx->dis_clk = res_ctx->pool.display_clock; + pipe_ctx->pipe_idx = DCE110_UNDERLAY_IDX; + ++ dcb = dal_adapter_service_get_bios_parser( ++ res_ctx->pool.adapter_srv); ++ ++ stream->ctx->dc->hwss.enable_display_power_gating( ++ stream->ctx->dc->ctx, ++ DCE110_UNDERLAY_IDX, ++ dcb, PIPE_GATING_CONTROL_DISABLE); ++ + if (!pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, true)) { + dm_error("DC: failed to blank crtc!\n"); + BREAK_TO_DEBUGGER(); +- } else +- pipe_ctx->flags.blanked = true; +- +- pipe_ctx->tg->funcs->program_timing( +- pipe_ctx->tg, +- &stream->public.timing, +- true); ++ } + + if (!pipe_ctx->tg->funcs->enable_crtc(pipe_ctx->tg)) { + BREAK_TO_DEBUGGER(); +@@ -190,6 +216,7 @@ bool dc_commit_surfaces_to_target( + struct validate_context *context; + int current_enabled_surface_count = 0; + int new_enabled_surface_count = 0; ++ bool is_mpo_turning_on = false; + + context = dm_alloc(dc->ctx, sizeof(struct validate_context)); + *context = dc->current_context; +@@ -215,10 +242,11 @@ bool dc_commit_surfaces_to_target( + new_enabled_surface_count++; + + /* TODO unhack mpo */ +- if (new_surface_count == 2 && target_status->surface_count < 2) ++ if (new_surface_count == 2 && target_status->surface_count < 2) { + acquire_first_free_underlay(&context->res_ctx, + DC_STREAM_TO_CORE(dc_target->streams[0])); +- else if (new_surface_count < 2 && target_status->surface_count == 2) { ++ is_mpo_turning_on = true; ++ } else if (new_surface_count < 2 && target_status->surface_count == 2) { + context->res_ctx.pipe_ctx[DCE110_UNDERLAY_IDX].stream = NULL; + context->res_ctx.pipe_ctx[DCE110_UNDERLAY_IDX].surface = NULL; + } +@@ -253,7 +281,9 @@ bool dc_commit_surfaces_to_target( + goto unexpected_fail; + } + +- if (prev_disp_clk < context->bw_results.dispclk_khz) { ++ if (prev_disp_clk < context->bw_results.dispclk_khz || ++ (is_mpo_turning_on && ++ prev_disp_clk == context->bw_results.dispclk_khz)) { + dc->hwss.program_bw(dc, context); + pplib_apply_display_requirements(dc, context, + &context->pp_display_cfg); +@@ -355,8 +385,7 @@ void dc_target_enable_memory_requests(struct dc_target *dc_target) + if (!tg->funcs->set_blank(tg, false)) { + dm_error("DC: failed to unblank crtc!\n"); + BREAK_TO_DEBUGGER(); +- } else +- res_ctx->pipe_ctx[j].flags.blanked = false; ++ } + } + } + } +@@ -379,8 +408,7 @@ void dc_target_disable_memory_requests(struct dc_target *dc_target) + if (!tg->funcs->set_blank(tg, true)) { + dm_error("DC: failed to blank crtc!\n"); + BREAK_TO_DEBUGGER(); +- } else +- res_ctx->pipe_ctx[j].flags.blanked = true; ++ } + } + } + } +diff --git a/drivers/gpu/drm/amd/dal/dc/dc_hw_types.h b/drivers/gpu/drm/amd/dal/dc/dc_hw_types.h +index d1d2f57..ea8028c 100644 +--- a/drivers/gpu/drm/amd/dal/dc/dc_hw_types.h ++++ b/drivers/gpu/drm/amd/dal/dc/dc_hw_types.h +@@ -193,16 +193,19 @@ struct dc_tiling_info { + * POSSIBLE VALUES: 1,2,4,8 + */ + unsigned int bank_width; ++ unsigned int bank_width_c; + /* Specifies the number of tiles in the y direction to + * be incorporated into the same bank. + * Only applies to 2D and 3D tiling modes. + * POSSIBLE VALUES: 1,2,4,8 + */ + unsigned int bank_height; ++ unsigned int bank_height_c; + /* Specifies the macro tile aspect ratio. Only applies + * to 2D and 3D tiling modes. + */ + unsigned int tile_aspect; ++ unsigned int tile_aspect_c; + /* Specifies the number of bytes that will be stored + * contiguously for each tile. + * If the tile data requires more storage than this +@@ -213,6 +216,7 @@ struct dc_tiling_info { + * For color render targets, TILE_SPLIT >= 256B. + */ + enum tile_split_values tile_split; ++ enum tile_split_values tile_split_c; + /* Specifies the addressing within a tile. + * 0x0 - DISPLAY_MICRO_TILING + * 0x1 - THIN_MICRO_TILING +@@ -220,6 +224,7 @@ struct dc_tiling_info { + * 0x3 - ROTATED_MICRO_TILING + */ + enum tile_mode_values tile_mode; ++ enum tile_mode_values tile_mode_c; + /* Specifies the number of pipes and how they are + * interleaved in the surface. + * Refer to memory addressing document for complete +diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c +index 76c2cad..1e22e59 100644 +--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c +@@ -71,17 +71,17 @@ enum blender_mode { + + static const struct dce110_hw_seq_reg_offsets reg_offsets[] = { + { +- .dcfe = (mmDCFE0_DCFE_MEM_PWR_CTRL - mmDCFE_MEM_PWR_CTRL), ++ .dcfe = (mmDCFE0_DCFE_CLOCK_CONTROL - mmDCFE_CLOCK_CONTROL), + .blnd = (mmBLND0_BLND_CONTROL - mmBLND_CONTROL), + .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), + }, + { +- .dcfe = (mmDCFE1_DCFE_MEM_PWR_CTRL - mmDCFE_MEM_PWR_CTRL), ++ .dcfe = (mmDCFE1_DCFE_CLOCK_CONTROL - mmDCFE_CLOCK_CONTROL), + .blnd = (mmBLND1_BLND_CONTROL - mmBLND_CONTROL), + .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), + }, + { +- .dcfe = (mmDCFE2_DCFE_MEM_PWR_CTRL - mmDCFE_MEM_PWR_CTRL), ++ .dcfe = (mmDCFE2_DCFE_CLOCK_CONTROL - mmDCFE_CLOCK_CONTROL), + .blnd = (mmBLND2_BLND_CONTROL - mmBLND_CONTROL), + .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), + }, +@@ -115,7 +115,6 @@ static void dce110_enable_fe_clock( + uint32_t value = 0; + uint32_t addr; + +- /*TODO: proper offset*/ + addr = HW_REG_DCFE(mmDCFE_CLOCK_CONTROL, controller_id); + + value = dm_read_reg(ctx, addr); +@@ -258,6 +257,7 @@ static bool dce110_pipe_control_lock( + + dm_write_reg(ctx, addr, value); + ++ need_to_wait = false;/*todo: mpo optimization remove*/ + if (!lock && need_to_wait) { + uint8_t counter = 0; + const uint8_t counter_limit = 100; +@@ -361,25 +361,27 @@ static void dce110_set_blender_mode( + { + uint32_t value; + uint32_t addr = HW_REG_BLND(mmBLND_CONTROL, controller_id); +- uint32_t blnd_mode; +- uint32_t feedthrough = 0; ++ uint32_t alpha_mode = 2; ++ uint32_t blnd_mode = 0; ++ uint32_t feedthrough = 1; ++ uint32_t multiplied_mode = 0; + + switch (mode) { + case BLENDER_MODE_OTHER_PIPE: + feedthrough = 0; ++ alpha_mode = 0; + blnd_mode = 1; + break; + case BLENDER_MODE_BLENDING: + feedthrough = 0; ++ alpha_mode = 0; + blnd_mode = 2; ++ multiplied_mode = 1; + break; + case BLENDER_MODE_CURRENT_PIPE: + default: + if (controller_id == DCE110_UNDERLAY_IDX) + feedthrough = 0; +- else +- feedthrough = 1; +- blnd_mode = 0; + break; + } + +@@ -390,12 +392,21 @@ static void dce110_set_blender_mode( + feedthrough, + BLND_CONTROL, + BLND_FEEDTHROUGH_EN); +- ++ set_reg_field_value( ++ value, ++ alpha_mode, ++ BLND_CONTROL, ++ BLND_ALPHA_MODE); + set_reg_field_value( + value, + blnd_mode, + BLND_CONTROL, + BLND_MODE); ++ set_reg_field_value( ++ value, ++ multiplied_mode, ++ BLND_CONTROL, ++ BLND_MULTIPLIED_MODE); + + + dm_write_reg(ctx, addr, value); +@@ -456,6 +467,9 @@ static bool dce110_enable_display_power_gating( + else + cntl = ASIC_PIPE_DISABLE; + ++ if (controller_id == DCE110_UNDERLAY_IDX) ++ controller_id = CONTROLLER_ID_UNDERLAY0 - 1; ++ + if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0) + bp_result = dcb->funcs->enable_disp_power_gating( + dcb, controller_id + 1, cntl); +@@ -524,10 +538,10 @@ static bool set_gamma_ramp( + + opp->funcs->opp_power_on_regamma_lut(opp, true); + +- build_prescale_params(prescale_params, surface); +- +- if (ipp) ++ if (ipp) { ++ build_prescale_params(prescale_params, surface); + ipp->funcs->ipp_program_prescale(ipp, prescale_params); ++ } + + if (ramp) { + calculate_regamma_params(regamma_params, +@@ -778,8 +792,6 @@ static enum dc_status apply_single_controller_ctx_to_hw( + * programming, otherwise CRTC will be hung in bad state + */ + pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, true); +- pipe_ctx->flags.blanked = true; +- + + /* + * only disable stream in case it was ever enabled +@@ -957,8 +969,6 @@ static void disable_vga_and_power_gate_all_controllers( + * powergating. */ + enable_display_pipe_clock_gating(ctx, + true); +- if (i == DCE110_UNDERLAY_IDX) +- continue; + dc->hwss.enable_display_power_gating(ctx, i, dcb, + PIPE_GATING_CONTROL_ENABLE); + } +@@ -1385,6 +1395,10 @@ static void set_plane_config( + true); + + tg->funcs->program_timing(tg, crtc_timing, false); ++ tg->funcs->enable_advanced_request( ++ tg, ++ true, ++ &pipe_ctx->stream->public.timing); + + dc->hwss.enable_fe_clock(ctx, pipe_ctx->pipe_idx, true); + +@@ -1451,8 +1465,7 @@ static void update_plane_addrs(struct dc *dc, struct resource_context *res_ctx) + if (!pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, false)) { + dm_error("DC: failed to unblank crtc!\n"); + BREAK_TO_DEBUGGER(); +- } else +- pipe_ctx->flags.blanked = false; ++ } + } + } + +@@ -1476,12 +1489,9 @@ static void reset_single_pipe_hw_ctx( + } + + core_link_disable_stream(pipe_ctx); +- if (!pipe_ctx->flags.blanked) { +- if (!pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, true)) { +- dm_error("DC: failed to blank crtc!\n"); +- BREAK_TO_DEBUGGER(); +- } else +- pipe_ctx->flags.blanked = true; ++ if (!pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, true)) { ++ dm_error("DC: failed to blank crtc!\n"); ++ BREAK_TO_DEBUGGER(); + } + pipe_ctx->tg->funcs->disable_crtc(pipe_ctx->tg); + pipe_ctx->mi->funcs->free_mem_input( +diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input_v.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input_v.c +index 042bd3a..08620e6 100644 +--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input_v.c ++++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input_v.c +@@ -183,10 +183,6 @@ static void program_tiling( + { + uint32_t value = 0; + +- value = dm_read_reg( +- mem_input110->base.ctx, +- DCP_REG(mmUNP_GRPH_CONTROL)); +- + set_reg_field_value(value, info->num_banks, + UNP_GRPH_CONTROL, GRPH_NUM_BANKS); + +@@ -219,7 +215,29 @@ static void program_tiling( + + dm_write_reg( + mem_input110->base.ctx, +- DCP_REG(mmUNP_GRPH_CONTROL), ++ mmUNP_GRPH_CONTROL, ++ value); ++ ++ value = 0; ++ ++ set_reg_field_value(value, info->bank_width_c, ++ UNP_GRPH_CONTROL_C, GRPH_BANK_WIDTH_C); ++ ++ set_reg_field_value(value, info->bank_height_c, ++ UNP_GRPH_CONTROL_C, GRPH_BANK_HEIGHT_C); ++ ++ set_reg_field_value(value, info->tile_aspect_c, ++ UNP_GRPH_CONTROL_C, GRPH_MACRO_TILE_ASPECT_C); ++ ++ set_reg_field_value(value, info->tile_split_c, ++ UNP_GRPH_CONTROL_C, GRPH_TILE_SPLIT_C); ++ ++ set_reg_field_value(value, info->tile_mode_c, ++ UNP_GRPH_CONTROL_C, GRPH_MICRO_TILE_MODE_C); ++ ++ dm_write_reg( ++ mem_input110->base.ctx, ++ mmUNP_GRPH_CONTROL_C, + value); + } + +diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator.c +index ea5b064..4e3276b 100644 +--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator.c ++++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator.c +@@ -285,11 +285,15 @@ bool dce110_timing_generator_enable_crtc(struct timing_generator *tg) + + value = dm_read_reg(tg->ctx, + CRTC_REG(mmCRTC_MASTER_UPDATE_MODE)); +- set_reg_field_value(value, 3, ++ set_reg_field_value(value, 0, + CRTC_MASTER_UPDATE_MODE, MASTER_UPDATE_MODE); + dm_write_reg(tg->ctx, + CRTC_REG(mmCRTC_MASTER_UPDATE_MODE), value); + ++ /* TODO: may want this on for looking for underflow */ ++ value = 0; ++ dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_MASTER_UPDATE_MODE), value); ++ + result = tg->bp->funcs->enable_crtc(tg->bp, tg110->controller_id, true); + + return result == BP_RESULT_OK; +diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator_v.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator_v.c +index 51d77da..99e8809 100644 +--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator_v.c ++++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator_v.c +@@ -30,22 +30,24 @@ + + static bool dce110_timing_generator_v_enable_crtc(struct timing_generator *tg) + { +- /* +- * Set MASTER_UPDATE_MODE to 0 +- * This is needed for DRR, and also suggested to be default value by Syed. +- */ ++/* ++* Set MASTER_UPDATE_MODE to 0 ++* This is needed for DRR, and also suggested to be default value by Syed. ++*/ + + uint32_t value; + +- value = dm_read_reg(tg->ctx, +- mmCRTCV_MASTER_UPDATE_MODE); ++ value = 0; + set_reg_field_value(value, 0, + CRTCV_MASTER_UPDATE_MODE, MASTER_UPDATE_MODE); + dm_write_reg(tg->ctx, + mmCRTCV_MASTER_UPDATE_MODE, value); + +- value = dm_read_reg(tg->ctx, +- mmCRTCV_MASTER_EN); ++ /* TODO: may want this on for looking for underflow */ ++ value = 0; ++ dm_write_reg(tg->ctx, mmCRTCV_MASTER_UPDATE_MODE, value); ++ ++ value = 0; + set_reg_field_value(value, 1, + CRTCV_MASTER_EN, CRTC_MASTER_EN); + dm_write_reg(tg->ctx, +diff --git a/drivers/gpu/drm/amd/dal/dc/inc/core_types.h b/drivers/gpu/drm/amd/dal/dc/inc/core_types.h +index ff34292..70b4a85 100644 +--- a/drivers/gpu/drm/amd/dal/dc/inc/core_types.h ++++ b/drivers/gpu/drm/amd/dal/dc/inc/core_types.h +@@ -317,7 +317,6 @@ struct pipe_ctx { + uint8_t pipe_idx; + + struct flags { +- bool blanked; + bool unchanged; + bool timing_changed; + } flags; +-- +2.7.4 + |