Merge branch 'drm-next-5.1' of git://people.freedesktop.org/~agd5f/linux into drm-next
ttm: - Replace ref/unref naming with get/put amdgpu: - Revert DC clang fix, causes a segfault with some compiler versions - SR-IOV fix - PCIE fix for vega20 - Misc DC fixes Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexdeucher@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190201062345.7304-1-alexander.deucher@amd.com
This commit is contained in:
@@ -4658,8 +4658,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
||||
flip = kzalloc(sizeof(*flip), GFP_KERNEL);
|
||||
full = kzalloc(sizeof(*full), GFP_KERNEL);
|
||||
|
||||
if (!flip || !full)
|
||||
if (!flip || !full) {
|
||||
dm_error("Failed to allocate update bundles\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* update planes when needed */
|
||||
for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
|
||||
@@ -4883,6 +4885,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
||||
dc_state);
|
||||
mutex_unlock(&dm->dc_lock);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
kfree(flip);
|
||||
kfree(full);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4917,10 +4923,25 @@ static int amdgpu_dm_atomic_commit(struct drm_device *dev,
|
||||
*/
|
||||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
|
||||
struct dm_crtc_state *dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
|
||||
struct dm_crtc_state *dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
|
||||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
if (drm_atomic_crtc_needs_modeset(new_crtc_state) && dm_old_crtc_state->stream)
|
||||
if (drm_atomic_crtc_needs_modeset(new_crtc_state)
|
||||
&& dm_old_crtc_state->stream) {
|
||||
/*
|
||||
* If the stream is removed and CRC capture was
|
||||
* enabled on the CRTC the extra vblank reference
|
||||
* needs to be dropped since CRC capture will be
|
||||
* disabled.
|
||||
*/
|
||||
if (!dm_new_crtc_state->stream
|
||||
&& dm_new_crtc_state->crc_enabled) {
|
||||
drm_crtc_vblank_put(crtc);
|
||||
dm_new_crtc_state->crc_enabled = false;
|
||||
}
|
||||
|
||||
manage_dm_interrupts(adev, acrtc, false);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Add check here for SoC's that support hardware cursor plane, to
|
||||
@@ -5152,6 +5173,10 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
||||
continue;
|
||||
|
||||
manage_dm_interrupts(adev, acrtc, true);
|
||||
|
||||
/* The stream has changed so CRC capture needs to re-enabled. */
|
||||
if (dm_new_crtc_state->crc_enabled)
|
||||
amdgpu_dm_crtc_set_crc_source(crtc, "auto");
|
||||
}
|
||||
|
||||
/* update planes when needed per crtc*/
|
||||
|
@@ -64,8 +64,10 @@ amdgpu_dm_crtc_verify_crc_source(struct drm_crtc *crtc, const char *src_name,
|
||||
|
||||
int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
|
||||
{
|
||||
struct amdgpu_device *adev = crtc->dev->dev_private;
|
||||
struct dm_crtc_state *crtc_state = to_dm_crtc_state(crtc->state);
|
||||
struct dc_stream_state *stream_state = crtc_state->stream;
|
||||
bool enable;
|
||||
|
||||
enum amdgpu_dm_pipe_crc_source source = dm_parse_crc_source(src_name);
|
||||
|
||||
@@ -80,29 +82,33 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* When enabling CRC, we should also disable dithering. */
|
||||
if (source == AMDGPU_DM_PIPE_CRC_SOURCE_AUTO) {
|
||||
if (dc_stream_configure_crc(stream_state->ctx->dc,
|
||||
stream_state,
|
||||
true, true)) {
|
||||
crtc_state->crc_enabled = true;
|
||||
dc_stream_set_dither_option(stream_state,
|
||||
DITHER_OPTION_TRUN8);
|
||||
}
|
||||
else
|
||||
return -EINVAL;
|
||||
} else {
|
||||
if (dc_stream_configure_crc(stream_state->ctx->dc,
|
||||
stream_state,
|
||||
false, false)) {
|
||||
crtc_state->crc_enabled = false;
|
||||
dc_stream_set_dither_option(stream_state,
|
||||
DITHER_OPTION_DEFAULT);
|
||||
}
|
||||
else
|
||||
return -EINVAL;
|
||||
enable = (source == AMDGPU_DM_PIPE_CRC_SOURCE_AUTO);
|
||||
|
||||
mutex_lock(&adev->dm.dc_lock);
|
||||
if (!dc_stream_configure_crc(stream_state->ctx->dc, stream_state,
|
||||
enable, enable)) {
|
||||
mutex_unlock(&adev->dm.dc_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* When enabling CRC, we should also disable dithering. */
|
||||
dc_stream_set_dither_option(stream_state,
|
||||
enable ? DITHER_OPTION_TRUN8
|
||||
: DITHER_OPTION_DEFAULT);
|
||||
|
||||
mutex_unlock(&adev->dm.dc_lock);
|
||||
|
||||
/*
|
||||
* Reading the CRC requires the vblank interrupt handler to be
|
||||
* enabled. Keep a reference until CRC capture stops.
|
||||
*/
|
||||
if (!crtc_state->crc_enabled && enable)
|
||||
drm_crtc_vblank_get(crtc);
|
||||
else if (crtc_state->crc_enabled && !enable)
|
||||
drm_crtc_vblank_put(crtc);
|
||||
|
||||
crtc_state->crc_enabled = enable;
|
||||
|
||||
/* Reset crc_skipped on dm state */
|
||||
crtc_state->crc_skip_count = 0;
|
||||
return 0;
|
||||
|
@@ -263,6 +263,13 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* poll pending down reply before clear payload allocation table
|
||||
*/
|
||||
void dm_helpers_dp_mst_poll_pending_down_reply(
|
||||
struct dc_context *ctx,
|
||||
const struct dc_link *link)
|
||||
{}
|
||||
|
||||
/*
|
||||
* Clear payload allocation table before enable MST DP link.
|
||||
|
@@ -30,7 +30,7 @@ else ifneq ($(call cc-option, -mstack-alignment=16),)
|
||||
cc_stack_align := -mstack-alignment=16
|
||||
endif
|
||||
|
||||
calcs_ccflags := -mhard-float -msse -msse2 $(cc_stack_align)
|
||||
calcs_ccflags := -mhard-float -msse $(cc_stack_align)
|
||||
|
||||
CFLAGS_dcn_calcs.o := $(calcs_ccflags)
|
||||
CFLAGS_dcn_calc_auto.o := $(calcs_ccflags)
|
||||
|
@@ -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_max);
|
||||
|
||||
if (stream_update->periodic_fn_vsync_delta &&
|
||||
pipe_ctx->stream_res.tg->funcs->program_vline_interrupt)
|
||||
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, &pipe_ctx->stream->timing,
|
||||
pipe_ctx->stream->periodic_fn_vsync_delta);
|
||||
pipe_ctx->stream_res.tg, VLINE0, stream->vline0_config);
|
||||
|
||||
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) ||
|
||||
stream_update->vrr_infopacket ||
|
||||
|
@@ -1467,6 +1467,11 @@ static enum dc_status enable_link_dp_mst(
|
||||
if (link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN)
|
||||
return DC_OK;
|
||||
|
||||
/* to make sure the pending down rep can be processed
|
||||
* before clear payload table
|
||||
*/
|
||||
dm_helpers_dp_mst_poll_pending_down_reply(link->ctx, link);
|
||||
|
||||
/* clear payload table */
|
||||
dm_helpers_dp_mst_clear_payload_allocation_table(link->ctx, link);
|
||||
|
||||
|
@@ -45,6 +45,11 @@ struct freesync_context {
|
||||
bool dummy;
|
||||
};
|
||||
|
||||
struct vline_config {
|
||||
unsigned int start_line;
|
||||
unsigned int end_line;
|
||||
};
|
||||
|
||||
struct dc_stream_state {
|
||||
// sink is deprecated, new code should not reference
|
||||
// this pointer
|
||||
@@ -85,8 +90,6 @@ struct dc_stream_state {
|
||||
uint8_t qs_bit;
|
||||
uint8_t qy_bit;
|
||||
|
||||
unsigned long long periodic_fn_vsync_delta;
|
||||
|
||||
/* TODO: custom INFO packets */
|
||||
/* TODO: ABM info (DMCU) */
|
||||
/* PSR info */
|
||||
@@ -96,6 +99,9 @@ struct dc_stream_state {
|
||||
/* DMCU info */
|
||||
unsigned int abm_level;
|
||||
|
||||
struct vline_config vline0_config;
|
||||
struct vline_config vline1_config;
|
||||
|
||||
/* from core_stream struct */
|
||||
struct dc_context *ctx;
|
||||
|
||||
@@ -143,7 +149,9 @@ struct dc_stream_update {
|
||||
struct dc_info_packet *hdr_static_metadata;
|
||||
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_info_packet *vrr_infopacket;
|
||||
struct dc_info_packet *vsc_infopacket;
|
||||
|
@@ -92,68 +92,26 @@ static void optc1_disable_stereo(struct timing_generator *optc)
|
||||
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(
|
||||
struct timing_generator *optc,
|
||||
const struct dc_crtc_timing *dc_crtc_timing,
|
||||
unsigned long long vsync_delta)
|
||||
enum vline_select vline,
|
||||
struct vline_config vline_config)
|
||||
{
|
||||
|
||||
struct optc *optc1 = DCN10TG_FROM_TG(optc);
|
||||
|
||||
unsigned long long req_delta_tens_of_usec = div64_u64((vsync_delta + 9999), 10000);
|
||||
unsigned long long pix_clk_hundreds_khz = div64_u64((dc_crtc_timing->pix_clk_100hz + 999), 1000);
|
||||
uint32_t req_delta_lines = (uint32_t) div64_u64(
|
||||
(req_delta_tens_of_usec * pix_clk_hundreds_khz + dc_crtc_timing->h_total - 1),
|
||||
dc_crtc_timing->h_total);
|
||||
|
||||
uint32_t vsync_line = get_start_vline(optc, dc_crtc_timing);
|
||||
uint32_t start_line = 0;
|
||||
uint32_t end_line = 0;
|
||||
|
||||
if (req_delta_lines != 0)
|
||||
req_delta_lines--;
|
||||
|
||||
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);
|
||||
switch (vline) {
|
||||
case VLINE0:
|
||||
REG_SET_2(OTG_VERTICAL_INTERRUPT0_POSITION, 0,
|
||||
OTG_VERTICAL_INTERRUPT0_LINE_START, vline_config.start_line,
|
||||
OTG_VERTICAL_INTERRUPT0_LINE_END, vline_config.end_line);
|
||||
break;
|
||||
case VLINE1:
|
||||
REG_SET(OTG_VERTICAL_INTERRUPT1_POSITION, 0,
|
||||
OTG_VERTICAL_INTERRUPT1_LINE_START, vline_config.start_line);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -67,6 +67,8 @@
|
||||
SRI(OTG_CLOCK_CONTROL, OTG, inst),\
|
||||
SRI(OTG_VERTICAL_INTERRUPT0_CONTROL, 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_POSITION, OTG, inst),\
|
||||
SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\
|
||||
@@ -135,6 +137,8 @@ struct dcn_optc_registers {
|
||||
uint32_t OTG_CLOCK_CONTROL;
|
||||
uint32_t OTG_VERTICAL_INTERRUPT0_CONTROL;
|
||||
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_POSITION;
|
||||
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_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_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_POSITION, OTG_VERTICAL_INTERRUPT2_LINE_START, 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_LINE_START;\
|
||||
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_LINE_START;\
|
||||
type OPTC_INPUT_CLK_EN;\
|
||||
@@ -476,8 +484,8 @@ void optc1_program_timing(
|
||||
bool use_vbios);
|
||||
|
||||
void optc1_program_vline_interrupt(struct timing_generator *optc,
|
||||
const struct dc_crtc_timing *dc_crtc_timing,
|
||||
unsigned long long vsync_delta);
|
||||
enum vline_select vline,
|
||||
struct vline_config vline_config);
|
||||
|
||||
void optc1_program_global_sync(
|
||||
struct timing_generator *optc);
|
||||
|
@@ -57,6 +57,13 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
|
||||
struct dp_mst_stream_allocation_table *proposed_table,
|
||||
bool enable);
|
||||
|
||||
/*
|
||||
* poll pending down reply before clear payload allocation table
|
||||
*/
|
||||
void dm_helpers_dp_mst_poll_pending_down_reply(
|
||||
struct dc_context *ctx,
|
||||
const struct dc_link *link);
|
||||
|
||||
/*
|
||||
* Clear payload allocation table before enable MST DP link.
|
||||
*/
|
||||
|
@@ -30,7 +30,7 @@ else ifneq ($(call cc-option, -mstack-alignment=16),)
|
||||
cc_stack_align := -mstack-alignment=16
|
||||
endif
|
||||
|
||||
dml_ccflags := -mhard-float -msse -msse2 $(cc_stack_align)
|
||||
dml_ccflags := -mhard-float -msse $(cc_stack_align)
|
||||
|
||||
CFLAGS_display_mode_lib.o := $(dml_ccflags)
|
||||
CFLAGS_display_pipe_clocks.o := $(dml_ccflags)
|
||||
|
@@ -134,6 +134,15 @@ struct dc_crtc_timing;
|
||||
|
||||
struct drr_params;
|
||||
|
||||
struct vline_config;
|
||||
|
||||
|
||||
enum vline_select {
|
||||
VLINE0,
|
||||
VLINE1,
|
||||
VLINE2
|
||||
};
|
||||
|
||||
struct timing_generator_funcs {
|
||||
bool (*validate_timing)(struct timing_generator *tg,
|
||||
const struct dc_crtc_timing *timing);
|
||||
@@ -141,8 +150,8 @@ struct timing_generator_funcs {
|
||||
const struct dc_crtc_timing *timing,
|
||||
bool use_vbios);
|
||||
void (*program_vline_interrupt)(struct timing_generator *optc,
|
||||
const struct dc_crtc_timing *dc_crtc_timing,
|
||||
unsigned long long vsync_delta);
|
||||
enum vline_select vline,
|
||||
struct vline_config vline_config);
|
||||
bool (*enable_crtc)(struct timing_generator *tg);
|
||||
bool (*disable_crtc)(struct timing_generator *tg);
|
||||
bool (*is_counter_moving)(struct timing_generator *tg);
|
||||
|
@@ -144,6 +144,14 @@ enum dc_irq_source {
|
||||
DC_IRQ_SOURCE_DC5_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
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user