Commit 7d9ff5ee authored by Dave Airlie's avatar Dave Airlie

Merge tag 'amd-drm-fixes-5.7-2020-05-21' of...

Merge tag 'amd-drm-fixes-5.7-2020-05-21' of git://people.freedesktop.org/~agd5f/linux into drm-fixes

amd-drm-fixes-5.7-2020-05-21:

amdgpu:
- DP fix
- Floating point fix
- Fix cursor stutter issue
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Alex Deucher <alexdeucher@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200521222415.4122-1-alexander.deucher@amd.com
parents 9bf43039 31ecebee
...@@ -220,6 +220,30 @@ static enum dpcd_training_patterns ...@@ -220,6 +220,30 @@ static enum dpcd_training_patterns
return dpcd_tr_pattern; return dpcd_tr_pattern;
} }
static uint8_t dc_dp_initialize_scrambling_data_symbols(
struct dc_link *link,
enum dc_dp_training_pattern pattern)
{
uint8_t disable_scrabled_data_symbols = 0;
switch (pattern) {
case DP_TRAINING_PATTERN_SEQUENCE_1:
case DP_TRAINING_PATTERN_SEQUENCE_2:
case DP_TRAINING_PATTERN_SEQUENCE_3:
disable_scrabled_data_symbols = 1;
break;
case DP_TRAINING_PATTERN_SEQUENCE_4:
disable_scrabled_data_symbols = 0;
break;
default:
ASSERT(0);
DC_LOG_HW_LINK_TRAINING("%s: Invalid HW Training pattern: %d\n",
__func__, pattern);
break;
}
return disable_scrabled_data_symbols;
}
static inline bool is_repeater(struct dc_link *link, uint32_t offset) static inline bool is_repeater(struct dc_link *link, uint32_t offset)
{ {
return (!link->is_lttpr_mode_transparent && offset != 0); return (!link->is_lttpr_mode_transparent && offset != 0);
...@@ -252,6 +276,9 @@ static void dpcd_set_lt_pattern_and_lane_settings( ...@@ -252,6 +276,9 @@ static void dpcd_set_lt_pattern_and_lane_settings(
dpcd_pattern.v1_4.TRAINING_PATTERN_SET = dpcd_pattern.v1_4.TRAINING_PATTERN_SET =
dc_dp_training_pattern_to_dpcd_training_pattern(link, pattern); dc_dp_training_pattern_to_dpcd_training_pattern(link, pattern);
dpcd_pattern.v1_4.SCRAMBLING_DISABLE =
dc_dp_initialize_scrambling_data_symbols(link, pattern);
dpcd_lt_buffer[DP_TRAINING_PATTERN_SET - DP_TRAINING_PATTERN_SET] dpcd_lt_buffer[DP_TRAINING_PATTERN_SET - DP_TRAINING_PATTERN_SET]
= dpcd_pattern.raw; = dpcd_pattern.raw;
......
...@@ -1625,12 +1625,79 @@ void dcn10_pipe_control_lock( ...@@ -1625,12 +1625,79 @@ void dcn10_pipe_control_lock(
hws->funcs.verify_allow_pstate_change_high(dc); hws->funcs.verify_allow_pstate_change_high(dc);
} }
/**
* delay_cursor_until_vupdate() - Delay cursor update if too close to VUPDATE.
*
* Software keepout workaround to prevent cursor update locking from stalling
* out cursor updates indefinitely or from old values from being retained in
* the case where the viewport changes in the same frame as the cursor.
*
* The idea is to calculate the remaining time from VPOS to VUPDATE. If it's
* too close to VUPDATE, then stall out until VUPDATE finishes.
*
* TODO: Optimize cursor programming to be once per frame before VUPDATE
* to avoid the need for this workaround.
*/
static void delay_cursor_until_vupdate(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
struct dc_stream_state *stream = pipe_ctx->stream;
struct crtc_position position;
uint32_t vupdate_start, vupdate_end;
unsigned int lines_to_vupdate, us_to_vupdate, vpos;
unsigned int us_per_line, us_vupdate;
if (!dc->hwss.calc_vupdate_position || !dc->hwss.get_position)
return;
if (!pipe_ctx->stream_res.stream_enc || !pipe_ctx->stream_res.tg)
return;
dc->hwss.calc_vupdate_position(dc, pipe_ctx, &vupdate_start,
&vupdate_end);
dc->hwss.get_position(&pipe_ctx, 1, &position);
vpos = position.vertical_count;
/* Avoid wraparound calculation issues */
vupdate_start += stream->timing.v_total;
vupdate_end += stream->timing.v_total;
vpos += stream->timing.v_total;
if (vpos <= vupdate_start) {
/* VPOS is in VACTIVE or back porch. */
lines_to_vupdate = vupdate_start - vpos;
} else if (vpos > vupdate_end) {
/* VPOS is in the front porch. */
return;
} else {
/* VPOS is in VUPDATE. */
lines_to_vupdate = 0;
}
/* Calculate time until VUPDATE in microseconds. */
us_per_line =
stream->timing.h_total * 10000u / stream->timing.pix_clk_100hz;
us_to_vupdate = lines_to_vupdate * us_per_line;
/* 70 us is a conservative estimate of cursor update time*/
if (us_to_vupdate > 70)
return;
/* Stall out until the cursor update completes. */
us_vupdate = (vupdate_end - vupdate_start + 1) * us_per_line;
udelay(us_to_vupdate + us_vupdate);
}
void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock) void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock)
{ {
/* cursor lock is per MPCC tree, so only need to lock one pipe per stream */ /* cursor lock is per MPCC tree, so only need to lock one pipe per stream */
if (!pipe || pipe->top_pipe) if (!pipe || pipe->top_pipe)
return; return;
/* Prevent cursor lock from stalling out cursor updates. */
if (lock)
delay_cursor_until_vupdate(dc, pipe);
dc->res_pool->mpc->funcs->cursor_lock(dc->res_pool->mpc, dc->res_pool->mpc->funcs->cursor_lock(dc->res_pool->mpc,
pipe->stream_res.opp->inst, lock); pipe->stream_res.opp->inst, lock);
} }
...@@ -3236,7 +3303,7 @@ int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx) ...@@ -3236,7 +3303,7 @@ int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx)
return vertical_line_start; return vertical_line_start;
} }
static void dcn10_calc_vupdate_position( void dcn10_calc_vupdate_position(
struct dc *dc, struct dc *dc,
struct pipe_ctx *pipe_ctx, struct pipe_ctx *pipe_ctx,
uint32_t *start_line, uint32_t *start_line,
......
...@@ -34,6 +34,11 @@ struct dc; ...@@ -34,6 +34,11 @@ struct dc;
void dcn10_hw_sequencer_construct(struct dc *dc); void dcn10_hw_sequencer_construct(struct dc *dc);
int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx); int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx);
void dcn10_calc_vupdate_position(
struct dc *dc,
struct pipe_ctx *pipe_ctx,
uint32_t *start_line,
uint32_t *end_line);
void dcn10_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx); void dcn10_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx);
enum dc_status dcn10_enable_stream_timing( enum dc_status dcn10_enable_stream_timing(
struct pipe_ctx *pipe_ctx, struct pipe_ctx *pipe_ctx,
......
...@@ -72,6 +72,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { ...@@ -72,6 +72,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.set_clock = dcn10_set_clock, .set_clock = dcn10_set_clock,
.get_clock = dcn10_get_clock, .get_clock = dcn10_get_clock,
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
.calc_vupdate_position = dcn10_calc_vupdate_position,
}; };
static const struct hwseq_private_funcs dcn10_private_funcs = { static const struct hwseq_private_funcs dcn10_private_funcs = {
......
...@@ -83,6 +83,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { ...@@ -83,6 +83,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
.init_vm_ctx = dcn20_init_vm_ctx, .init_vm_ctx = dcn20_init_vm_ctx,
.set_flip_control_gsl = dcn20_set_flip_control_gsl, .set_flip_control_gsl = dcn20_set_flip_control_gsl,
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
.calc_vupdate_position = dcn10_calc_vupdate_position,
}; };
static const struct hwseq_private_funcs dcn20_private_funcs = { static const struct hwseq_private_funcs dcn20_private_funcs = {
......
...@@ -86,6 +86,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = { ...@@ -86,6 +86,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
.optimize_pwr_state = dcn21_optimize_pwr_state, .optimize_pwr_state = dcn21_optimize_pwr_state,
.exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state, .exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state,
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
.calc_vupdate_position = dcn10_calc_vupdate_position,
.set_cursor_position = dcn10_set_cursor_position, .set_cursor_position = dcn10_set_cursor_position,
.set_cursor_attribute = dcn10_set_cursor_attribute, .set_cursor_attribute = dcn10_set_cursor_attribute,
.set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level, .set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level,
......
...@@ -63,10 +63,8 @@ CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_rq_dlg_calc_21.o := $(dml_ccflags) ...@@ -63,10 +63,8 @@ CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_rq_dlg_calc_21.o := $(dml_ccflags)
endif endif
CFLAGS_$(AMDDALPATH)/dc/dml/dml1_display_rq_dlg_calc.o := $(dml_ccflags) CFLAGS_$(AMDDALPATH)/dc/dml/dml1_display_rq_dlg_calc.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/display_rq_dlg_helpers.o := $(dml_ccflags) CFLAGS_$(AMDDALPATH)/dc/dml/display_rq_dlg_helpers.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dml_common_defs.o := $(dml_ccflags)
DML = display_mode_lib.o display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \ DML = display_mode_lib.o display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \
dml_common_defs.o
ifdef CONFIG_DRM_AMD_DC_DCN ifdef CONFIG_DRM_AMD_DC_DCN
DML += display_mode_vba.o dcn20/display_rq_dlg_calc_20.o dcn20/display_mode_vba_20.o DML += display_mode_vba.o dcn20/display_rq_dlg_calc_20.o dcn20/display_mode_vba_20.o
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#ifndef __DML20_DISPLAY_RQ_DLG_CALC_H__ #ifndef __DML20_DISPLAY_RQ_DLG_CALC_H__
#define __DML20_DISPLAY_RQ_DLG_CALC_H__ #define __DML20_DISPLAY_RQ_DLG_CALC_H__
#include "../dml_common_defs.h"
#include "../display_rq_dlg_helpers.h" #include "../display_rq_dlg_helpers.h"
struct display_mode_lib; struct display_mode_lib;
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#ifndef __DML20V2_DISPLAY_RQ_DLG_CALC_H__ #ifndef __DML20V2_DISPLAY_RQ_DLG_CALC_H__
#define __DML20V2_DISPLAY_RQ_DLG_CALC_H__ #define __DML20V2_DISPLAY_RQ_DLG_CALC_H__
#include "../dml_common_defs.h"
#include "../display_rq_dlg_helpers.h" #include "../display_rq_dlg_helpers.h"
struct display_mode_lib; struct display_mode_lib;
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#ifndef __DML21_DISPLAY_RQ_DLG_CALC_H__ #ifndef __DML21_DISPLAY_RQ_DLG_CALC_H__
#define __DML21_DISPLAY_RQ_DLG_CALC_H__ #define __DML21_DISPLAY_RQ_DLG_CALC_H__
#include "../dml_common_defs.h" #include "dm_services.h"
#include "../display_rq_dlg_helpers.h" #include "../display_rq_dlg_helpers.h"
struct display_mode_lib; struct display_mode_lib;
......
...@@ -25,8 +25,10 @@ ...@@ -25,8 +25,10 @@
#ifndef __DISPLAY_MODE_LIB_H__ #ifndef __DISPLAY_MODE_LIB_H__
#define __DISPLAY_MODE_LIB_H__ #define __DISPLAY_MODE_LIB_H__
#include "dm_services.h"
#include "dml_common_defs.h" #include "dc_features.h"
#include "display_mode_structs.h"
#include "display_mode_enums.h"
#include "display_mode_vba.h" #include "display_mode_vba.h"
enum dml_project { enum dml_project {
......
...@@ -27,8 +27,6 @@ ...@@ -27,8 +27,6 @@
#ifndef __DML2_DISPLAY_MODE_VBA_H__ #ifndef __DML2_DISPLAY_MODE_VBA_H__
#define __DML2_DISPLAY_MODE_VBA_H__ #define __DML2_DISPLAY_MODE_VBA_H__
#include "dml_common_defs.h"
struct display_mode_lib; struct display_mode_lib;
void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib); void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib);
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#ifndef __DISPLAY_RQ_DLG_HELPERS_H__ #ifndef __DISPLAY_RQ_DLG_HELPERS_H__
#define __DISPLAY_RQ_DLG_HELPERS_H__ #define __DISPLAY_RQ_DLG_HELPERS_H__
#include "dml_common_defs.h"
#include "display_mode_lib.h" #include "display_mode_lib.h"
/* Function: Printer functions /* Function: Printer functions
......
...@@ -26,8 +26,6 @@ ...@@ -26,8 +26,6 @@
#ifndef __DISPLAY_RQ_DLG_CALC_H__ #ifndef __DISPLAY_RQ_DLG_CALC_H__
#define __DISPLAY_RQ_DLG_CALC_H__ #define __DISPLAY_RQ_DLG_CALC_H__
#include "dml_common_defs.h"
struct display_mode_lib; struct display_mode_lib;
#include "display_rq_dlg_helpers.h" #include "display_rq_dlg_helpers.h"
......
/*
* Copyright 2017 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "dml_common_defs.h"
#include "dcn_calc_math.h"
#include "dml_inline_defs.h"
double dml_round(double a)
{
double round_pt = 0.5;
double ceil = dml_ceil(a, 1);
double floor = dml_floor(a, 1);
if (a - floor >= round_pt)
return ceil;
else
return floor;
}
/*
* Copyright 2017 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __DC_COMMON_DEFS_H__
#define __DC_COMMON_DEFS_H__
#include "dm_services.h"
#include "dc_features.h"
#include "display_mode_structs.h"
#include "display_mode_enums.h"
double dml_round(double a);
#endif /* __DC_COMMON_DEFS_H__ */
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#ifndef __DML_INLINE_DEFS_H__ #ifndef __DML_INLINE_DEFS_H__
#define __DML_INLINE_DEFS_H__ #define __DML_INLINE_DEFS_H__
#include "dml_common_defs.h"
#include "dcn_calc_math.h" #include "dcn_calc_math.h"
#include "dml_logger.h" #include "dml_logger.h"
...@@ -75,6 +74,18 @@ static inline double dml_floor(double a, double granularity) ...@@ -75,6 +74,18 @@ static inline double dml_floor(double a, double granularity)
return (double) dcn_bw_floor2(a, granularity); return (double) dcn_bw_floor2(a, granularity);
} }
static inline double dml_round(double a)
{
double round_pt = 0.5;
double ceil = dml_ceil(a, 1);
double floor = dml_floor(a, 1);
if (a - floor >= round_pt)
return ceil;
else
return floor;
}
static inline int dml_log2(double x) static inline int dml_log2(double x)
{ {
return dml_round((double)dcn_bw_log(x, 2)); return dml_round((double)dcn_bw_log(x, 2));
...@@ -112,7 +123,7 @@ static inline double dml_log(double x, double base) ...@@ -112,7 +123,7 @@ static inline double dml_log(double x, double base)
static inline unsigned int dml_round_to_multiple(unsigned int num, static inline unsigned int dml_round_to_multiple(unsigned int num,
unsigned int multiple, unsigned int multiple,
bool up) unsigned char up)
{ {
unsigned int remainder; unsigned int remainder;
......
...@@ -92,6 +92,11 @@ struct hw_sequencer_funcs { ...@@ -92,6 +92,11 @@ struct hw_sequencer_funcs {
void (*get_position)(struct pipe_ctx **pipe_ctx, int num_pipes, void (*get_position)(struct pipe_ctx **pipe_ctx, int num_pipes,
struct crtc_position *position); struct crtc_position *position);
int (*get_vupdate_offset_from_vsync)(struct pipe_ctx *pipe_ctx); int (*get_vupdate_offset_from_vsync)(struct pipe_ctx *pipe_ctx);
void (*calc_vupdate_position)(
struct dc *dc,
struct pipe_ctx *pipe_ctx,
uint32_t *start_line,
uint32_t *end_line);
void (*enable_per_frame_crtc_position_reset)(struct dc *dc, void (*enable_per_frame_crtc_position_reset)(struct dc *dc,
int group_size, struct pipe_ctx *grouped_pipes[]); int group_size, struct pipe_ctx *grouped_pipes[]);
void (*enable_timing_synchronization)(struct dc *dc, void (*enable_timing_synchronization)(struct dc *dc,
......
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