forked from luck/tmp_suning_uos_patched
Merge tag 'amd-drm-fixes-5.7-2020-04-29' of git://people.freedesktop.org/~agd5f/linux into drm-fixes
amd-drm-fixes-5.7-2020-04-29: amdgpu: - Fix a green screen on resume issue - PM fixes for SR-IOV - SDMA fix for navi - Renoir display fixes - Cursor and pageflip stuttering fixes - Misc additional display fixes UAPI: - Add additional DCC tiling flags for navi1x Used by: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4697 Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexdeucher@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200429212008.4306-1-alexander.deucher@amd.com
This commit is contained in:
commit
e3dcd86b3b
|
@ -85,9 +85,10 @@
|
|||
* - 3.34.0 - Non-DC can flip correctly between buffers with different pitches
|
||||
* - 3.35.0 - Add drm_amdgpu_info_device::tcc_disabled_mask
|
||||
* - 3.36.0 - Allow reading more status registers on si/cik
|
||||
* - 3.37.0 - L2 is invalidated before SDMA IBs, needed for correctness
|
||||
*/
|
||||
#define KMS_DRIVER_MAJOR 3
|
||||
#define KMS_DRIVER_MINOR 36
|
||||
#define KMS_DRIVER_MINOR 37
|
||||
#define KMS_DRIVER_PATCHLEVEL 0
|
||||
|
||||
int amdgpu_vram_limit = 0;
|
||||
|
|
|
@ -73,6 +73,22 @@
|
|||
#define SDMA_OP_AQL_COPY 0
|
||||
#define SDMA_OP_AQL_BARRIER_OR 0
|
||||
|
||||
#define SDMA_GCR_RANGE_IS_PA (1 << 18)
|
||||
#define SDMA_GCR_SEQ(x) (((x) & 0x3) << 16)
|
||||
#define SDMA_GCR_GL2_WB (1 << 15)
|
||||
#define SDMA_GCR_GL2_INV (1 << 14)
|
||||
#define SDMA_GCR_GL2_DISCARD (1 << 13)
|
||||
#define SDMA_GCR_GL2_RANGE(x) (((x) & 0x3) << 11)
|
||||
#define SDMA_GCR_GL2_US (1 << 10)
|
||||
#define SDMA_GCR_GL1_INV (1 << 9)
|
||||
#define SDMA_GCR_GLV_INV (1 << 8)
|
||||
#define SDMA_GCR_GLK_INV (1 << 7)
|
||||
#define SDMA_GCR_GLK_WB (1 << 6)
|
||||
#define SDMA_GCR_GLM_INV (1 << 5)
|
||||
#define SDMA_GCR_GLM_WB (1 << 4)
|
||||
#define SDMA_GCR_GL1_RANGE(x) (((x) & 0x3) << 2)
|
||||
#define SDMA_GCR_GLI_INV(x) (((x) & 0x3) << 0)
|
||||
|
||||
/*define for op field*/
|
||||
#define SDMA_PKT_HEADER_op_offset 0
|
||||
#define SDMA_PKT_HEADER_op_mask 0x000000FF
|
||||
|
|
|
@ -382,6 +382,18 @@ static void sdma_v5_0_ring_emit_ib(struct amdgpu_ring *ring,
|
|||
unsigned vmid = AMDGPU_JOB_GET_VMID(job);
|
||||
uint64_t csa_mc_addr = amdgpu_sdma_get_csa_mc_addr(ring, vmid);
|
||||
|
||||
/* Invalidate L2, because if we don't do it, we might get stale cache
|
||||
* lines from previous IBs.
|
||||
*/
|
||||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_GCR_REQ));
|
||||
amdgpu_ring_write(ring, 0);
|
||||
amdgpu_ring_write(ring, (SDMA_GCR_GL2_INV |
|
||||
SDMA_GCR_GL2_WB |
|
||||
SDMA_GCR_GLM_INV |
|
||||
SDMA_GCR_GLM_WB) << 16);
|
||||
amdgpu_ring_write(ring, 0xffffff80);
|
||||
amdgpu_ring_write(ring, 0xffff);
|
||||
|
||||
/* An IB packet must end on a 8 DW boundary--the next dword
|
||||
* must be on a 8-dword boundary. Our IB packet below is 6
|
||||
* dwords long, thus add x number of NOPs, such that, in
|
||||
|
@ -1595,7 +1607,7 @@ static const struct amdgpu_ring_funcs sdma_v5_0_ring_funcs = {
|
|||
SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
|
||||
SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 6 * 2 +
|
||||
10 + 10 + 10, /* sdma_v5_0_ring_emit_fence x3 for user fence, vm fence */
|
||||
.emit_ib_size = 7 + 6, /* sdma_v5_0_ring_emit_ib */
|
||||
.emit_ib_size = 5 + 7 + 6, /* sdma_v5_0_ring_emit_ib */
|
||||
.emit_ib = sdma_v5_0_ring_emit_ib,
|
||||
.emit_fence = sdma_v5_0_ring_emit_fence,
|
||||
.emit_pipeline_sync = sdma_v5_0_ring_emit_pipeline_sync,
|
||||
|
|
|
@ -3340,7 +3340,8 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
|
|||
const union dc_tiling_info *tiling_info,
|
||||
const uint64_t info,
|
||||
struct dc_plane_dcc_param *dcc,
|
||||
struct dc_plane_address *address)
|
||||
struct dc_plane_address *address,
|
||||
bool force_disable_dcc)
|
||||
{
|
||||
struct dc *dc = adev->dm.dc;
|
||||
struct dc_dcc_surface_param input;
|
||||
|
@ -3352,6 +3353,9 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
|
|||
memset(&input, 0, sizeof(input));
|
||||
memset(&output, 0, sizeof(output));
|
||||
|
||||
if (force_disable_dcc)
|
||||
return 0;
|
||||
|
||||
if (!offset)
|
||||
return 0;
|
||||
|
||||
|
@ -3401,7 +3405,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
|
|||
union dc_tiling_info *tiling_info,
|
||||
struct plane_size *plane_size,
|
||||
struct dc_plane_dcc_param *dcc,
|
||||
struct dc_plane_address *address)
|
||||
struct dc_plane_address *address,
|
||||
bool force_disable_dcc)
|
||||
{
|
||||
const struct drm_framebuffer *fb = &afb->base;
|
||||
int ret;
|
||||
|
@ -3507,7 +3512,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
|
|||
|
||||
ret = fill_plane_dcc_attributes(adev, afb, format, rotation,
|
||||
plane_size, tiling_info,
|
||||
tiling_flags, dcc, address);
|
||||
tiling_flags, dcc, address,
|
||||
force_disable_dcc);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -3599,7 +3605,8 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
|
|||
const struct drm_plane_state *plane_state,
|
||||
const uint64_t tiling_flags,
|
||||
struct dc_plane_info *plane_info,
|
||||
struct dc_plane_address *address)
|
||||
struct dc_plane_address *address,
|
||||
bool force_disable_dcc)
|
||||
{
|
||||
const struct drm_framebuffer *fb = plane_state->fb;
|
||||
const struct amdgpu_framebuffer *afb =
|
||||
|
@ -3681,7 +3688,8 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
|
|||
plane_info->rotation, tiling_flags,
|
||||
&plane_info->tiling_info,
|
||||
&plane_info->plane_size,
|
||||
&plane_info->dcc, address);
|
||||
&plane_info->dcc, address,
|
||||
force_disable_dcc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -3704,6 +3712,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
|
|||
struct dc_plane_info plane_info;
|
||||
uint64_t tiling_flags;
|
||||
int ret;
|
||||
bool force_disable_dcc = false;
|
||||
|
||||
ret = fill_dc_scaling_info(plane_state, &scaling_info);
|
||||
if (ret)
|
||||
|
@ -3718,9 +3727,11 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend;
|
||||
ret = fill_dc_plane_info_and_addr(adev, plane_state, tiling_flags,
|
||||
&plane_info,
|
||||
&dc_plane_state->address);
|
||||
&dc_plane_state->address,
|
||||
force_disable_dcc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -5342,6 +5353,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
|
|||
uint64_t tiling_flags;
|
||||
uint32_t domain;
|
||||
int r;
|
||||
bool force_disable_dcc = false;
|
||||
|
||||
dm_plane_state_old = to_dm_plane_state(plane->state);
|
||||
dm_plane_state_new = to_dm_plane_state(new_state);
|
||||
|
@ -5400,11 +5412,13 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
|
|||
dm_plane_state_old->dc_state != dm_plane_state_new->dc_state) {
|
||||
struct dc_plane_state *plane_state = dm_plane_state_new->dc_state;
|
||||
|
||||
force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend;
|
||||
fill_plane_buffer_attributes(
|
||||
adev, afb, plane_state->format, plane_state->rotation,
|
||||
tiling_flags, &plane_state->tiling_info,
|
||||
&plane_state->plane_size, &plane_state->dcc,
|
||||
&plane_state->address);
|
||||
&plane_state->address,
|
||||
force_disable_dcc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -6676,7 +6690,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
|||
fill_dc_plane_info_and_addr(
|
||||
dm->adev, new_plane_state, tiling_flags,
|
||||
&bundle->plane_infos[planes_count],
|
||||
&bundle->flip_addrs[planes_count].address);
|
||||
&bundle->flip_addrs[planes_count].address,
|
||||
false);
|
||||
|
||||
DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n",
|
||||
new_plane_state->plane->index,
|
||||
bundle->plane_infos[planes_count].dcc.enable);
|
||||
|
||||
bundle->surface_updates[planes_count].plane_info =
|
||||
&bundle->plane_infos[planes_count];
|
||||
|
@ -8096,7 +8115,8 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm,
|
|||
ret = fill_dc_plane_info_and_addr(
|
||||
dm->adev, new_plane_state, tiling_flags,
|
||||
plane_info,
|
||||
&flip_addr->address);
|
||||
&flip_addr->address,
|
||||
false);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
|
||||
|
|
|
@ -2908,6 +2908,12 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd
|
|||
sizeof(hpd_irq_dpcd_data),
|
||||
"Status: ");
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link)
|
||||
link->dc->hwss.blank_stream(pipe_ctx);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link)
|
||||
|
@ -2927,6 +2933,12 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd
|
|||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
|
||||
dc_link_reallocate_mst_payload(link);
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link)
|
||||
link->dc->hwss.unblank_stream(pipe_ctx, &previous_link_settings);
|
||||
}
|
||||
|
||||
status = false;
|
||||
if (out_link_loss)
|
||||
*out_link_loss = true;
|
||||
|
@ -4227,6 +4239,21 @@ void dp_set_fec_enable(struct dc_link *link, bool enable)
|
|||
void dpcd_set_source_specific_data(struct dc_link *link)
|
||||
{
|
||||
const uint32_t post_oui_delay = 30; // 30ms
|
||||
uint8_t dspc = 0;
|
||||
enum dc_status ret = DC_ERROR_UNEXPECTED;
|
||||
|
||||
ret = core_link_read_dpcd(link, DP_DOWN_STREAM_PORT_COUNT, &dspc,
|
||||
sizeof(dspc));
|
||||
|
||||
if (ret != DC_OK) {
|
||||
DC_LOG_ERROR("Error in DP aux read transaction,"
|
||||
" not writing source specific data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Return if OUI unsupported */
|
||||
if (!(dspc & DP_OUI_SUPPORT))
|
||||
return;
|
||||
|
||||
if (!link->dc->vendor_signature.is_valid) {
|
||||
struct dpcd_amd_signature amd_signature;
|
||||
|
|
|
@ -231,34 +231,6 @@ struct dc_stream_status *dc_stream_get_status(
|
|||
return dc_stream_get_status_from_state(dc->current_state, stream);
|
||||
}
|
||||
|
||||
static void delay_cursor_until_vupdate(struct pipe_ctx *pipe_ctx, struct dc *dc)
|
||||
{
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
unsigned int vupdate_line;
|
||||
unsigned int lines_to_vupdate, us_to_vupdate, vpos, nvpos;
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
unsigned int us_per_line;
|
||||
|
||||
if (stream->ctx->asic_id.chip_family == FAMILY_RV &&
|
||||
ASICREV_IS_RAVEN(stream->ctx->asic_id.hw_internal_rev)) {
|
||||
|
||||
vupdate_line = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
|
||||
if (!dc_stream_get_crtc_position(dc, &stream, 1, &vpos, &nvpos))
|
||||
return;
|
||||
|
||||
if (vpos >= vupdate_line)
|
||||
return;
|
||||
|
||||
us_per_line = stream->timing.h_total * 10000 / stream->timing.pix_clk_100hz;
|
||||
lines_to_vupdate = vupdate_line - vpos;
|
||||
us_to_vupdate = lines_to_vupdate * us_per_line;
|
||||
|
||||
/* 70 us is a conservative estimate of cursor update time*/
|
||||
if (us_to_vupdate < 70)
|
||||
udelay(us_to_vupdate);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* dc_stream_set_cursor_attributes() - Update cursor attributes and set cursor surface address
|
||||
|
@ -298,9 +270,7 @@ bool dc_stream_set_cursor_attributes(
|
|||
|
||||
if (!pipe_to_program) {
|
||||
pipe_to_program = pipe_ctx;
|
||||
|
||||
delay_cursor_until_vupdate(pipe_ctx, dc);
|
||||
dc->hwss.pipe_control_lock(dc, pipe_to_program, true);
|
||||
dc->hwss.cursor_lock(dc, pipe_to_program, true);
|
||||
}
|
||||
|
||||
dc->hwss.set_cursor_attribute(pipe_ctx);
|
||||
|
@ -309,7 +279,7 @@ bool dc_stream_set_cursor_attributes(
|
|||
}
|
||||
|
||||
if (pipe_to_program)
|
||||
dc->hwss.pipe_control_lock(dc, pipe_to_program, false);
|
||||
dc->hwss.cursor_lock(dc, pipe_to_program, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -349,16 +319,14 @@ bool dc_stream_set_cursor_position(
|
|||
|
||||
if (!pipe_to_program) {
|
||||
pipe_to_program = pipe_ctx;
|
||||
|
||||
delay_cursor_until_vupdate(pipe_ctx, dc);
|
||||
dc->hwss.pipe_control_lock(dc, pipe_to_program, true);
|
||||
dc->hwss.cursor_lock(dc, pipe_to_program, true);
|
||||
}
|
||||
|
||||
dc->hwss.set_cursor_position(pipe_ctx);
|
||||
}
|
||||
|
||||
if (pipe_to_program)
|
||||
dc->hwss.pipe_control_lock(dc, pipe_to_program, false);
|
||||
dc->hwss.cursor_lock(dc, pipe_to_program, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2757,6 +2757,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
|
|||
.disable_plane = dce110_power_down_fe,
|
||||
.pipe_control_lock = dce_pipe_control_lock,
|
||||
.interdependent_update_lock = NULL,
|
||||
.cursor_lock = dce_pipe_control_lock,
|
||||
.prepare_bandwidth = dce110_prepare_bandwidth,
|
||||
.optimize_bandwidth = dce110_optimize_bandwidth,
|
||||
.set_drr = set_drr,
|
||||
|
|
|
@ -1625,6 +1625,16 @@ void dcn10_pipe_control_lock(
|
|||
hws->funcs.verify_allow_pstate_change_high(dc);
|
||||
}
|
||||
|
||||
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 */
|
||||
if (!pipe || pipe->top_pipe)
|
||||
return;
|
||||
|
||||
dc->res_pool->mpc->funcs->cursor_lock(dc->res_pool->mpc,
|
||||
pipe->stream_res.opp->inst, lock);
|
||||
}
|
||||
|
||||
static bool wait_for_reset_trigger_to_occur(
|
||||
struct dc_context *dc_ctx,
|
||||
struct timing_generator *tg)
|
||||
|
|
|
@ -49,6 +49,7 @@ void dcn10_pipe_control_lock(
|
|||
struct dc *dc,
|
||||
struct pipe_ctx *pipe,
|
||||
bool lock);
|
||||
void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock);
|
||||
void dcn10_blank_pixel_data(
|
||||
struct dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
|
|
|
@ -50,6 +50,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
|
|||
.disable_audio_stream = dce110_disable_audio_stream,
|
||||
.disable_plane = dcn10_disable_plane,
|
||||
.pipe_control_lock = dcn10_pipe_control_lock,
|
||||
.cursor_lock = dcn10_cursor_lock,
|
||||
.interdependent_update_lock = dcn10_lock_all_pipes,
|
||||
.prepare_bandwidth = dcn10_prepare_bandwidth,
|
||||
.optimize_bandwidth = dcn10_optimize_bandwidth,
|
||||
|
|
|
@ -223,6 +223,9 @@ struct mpcc *mpc1_insert_plane(
|
|||
REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, dpp_id);
|
||||
REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, tree->opp_id);
|
||||
|
||||
/* Configure VUPDATE lock set for this MPCC to map to the OPP */
|
||||
REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, tree->opp_id);
|
||||
|
||||
/* update mpc tree mux setting */
|
||||
if (tree->opp_list == insert_above_mpcc) {
|
||||
/* insert the toppest mpcc */
|
||||
|
@ -318,6 +321,7 @@ void mpc1_remove_mpcc(
|
|||
REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
|
||||
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
|
||||
REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
|
||||
REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf);
|
||||
|
||||
/* mark this mpcc as not in use */
|
||||
mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id);
|
||||
|
@ -328,6 +332,7 @@ void mpc1_remove_mpcc(
|
|||
REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
|
||||
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
|
||||
REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
|
||||
REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -361,6 +366,7 @@ void mpc1_mpc_init(struct mpc *mpc)
|
|||
REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
|
||||
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
|
||||
REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
|
||||
REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf);
|
||||
|
||||
mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id);
|
||||
}
|
||||
|
@ -381,6 +387,7 @@ void mpc1_mpc_init_single_inst(struct mpc *mpc, unsigned int mpcc_id)
|
|||
REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
|
||||
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
|
||||
REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
|
||||
REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf);
|
||||
|
||||
mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id);
|
||||
|
||||
|
@ -453,6 +460,13 @@ void mpc1_read_mpcc_state(
|
|||
MPCC_BUSY, &s->busy);
|
||||
}
|
||||
|
||||
void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock)
|
||||
{
|
||||
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
|
||||
|
||||
REG_SET(CUR[opp_id], 0, CUR_VUPDATE_LOCK_SET, lock ? 1 : 0);
|
||||
}
|
||||
|
||||
static const struct mpc_funcs dcn10_mpc_funcs = {
|
||||
.read_mpcc_state = mpc1_read_mpcc_state,
|
||||
.insert_plane = mpc1_insert_plane,
|
||||
|
@ -464,6 +478,7 @@ static const struct mpc_funcs dcn10_mpc_funcs = {
|
|||
.assert_mpcc_idle_before_connect = mpc1_assert_mpcc_idle_before_connect,
|
||||
.init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw,
|
||||
.update_blending = mpc1_update_blending,
|
||||
.cursor_lock = mpc1_cursor_lock,
|
||||
.set_denorm = NULL,
|
||||
.set_denorm_clamp = NULL,
|
||||
.set_output_csc = NULL,
|
||||
|
|
|
@ -39,11 +39,12 @@
|
|||
SRII(MPCC_BG_G_Y, MPCC, inst),\
|
||||
SRII(MPCC_BG_R_CR, MPCC, inst),\
|
||||
SRII(MPCC_BG_B_CB, MPCC, inst),\
|
||||
SRII(MPCC_BG_B_CB, MPCC, inst),\
|
||||
SRII(MPCC_SM_CONTROL, MPCC, inst)
|
||||
SRII(MPCC_SM_CONTROL, MPCC, inst),\
|
||||
SRII(MPCC_UPDATE_LOCK_SEL, MPCC, inst)
|
||||
|
||||
#define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst) \
|
||||
SRII(MUX, MPC_OUT, inst)
|
||||
SRII(MUX, MPC_OUT, inst),\
|
||||
VUPDATE_SRII(CUR, VUPDATE_LOCK_SET, inst)
|
||||
|
||||
#define MPC_COMMON_REG_VARIABLE_LIST \
|
||||
uint32_t MPCC_TOP_SEL[MAX_MPCC]; \
|
||||
|
@ -55,7 +56,9 @@
|
|||
uint32_t MPCC_BG_R_CR[MAX_MPCC]; \
|
||||
uint32_t MPCC_BG_B_CB[MAX_MPCC]; \
|
||||
uint32_t MPCC_SM_CONTROL[MAX_MPCC]; \
|
||||
uint32_t MUX[MAX_OPP];
|
||||
uint32_t MUX[MAX_OPP]; \
|
||||
uint32_t MPCC_UPDATE_LOCK_SEL[MAX_MPCC]; \
|
||||
uint32_t CUR[MAX_OPP];
|
||||
|
||||
#define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\
|
||||
SF(MPCC0_MPCC_TOP_SEL, MPCC_TOP_SEL, mask_sh),\
|
||||
|
@ -78,7 +81,8 @@
|
|||
SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FIELD_ALT, mask_sh),\
|
||||
SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_FRAME_POL, mask_sh),\
|
||||
SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_TOP_POL, mask_sh),\
|
||||
SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh)
|
||||
SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh),\
|
||||
SF(MPCC0_MPCC_UPDATE_LOCK_SEL, MPCC_UPDATE_LOCK_SEL, mask_sh)
|
||||
|
||||
#define MPC_REG_FIELD_LIST(type) \
|
||||
type MPCC_TOP_SEL;\
|
||||
|
@ -101,7 +105,9 @@
|
|||
type MPCC_SM_FIELD_ALT;\
|
||||
type MPCC_SM_FORCE_NEXT_FRAME_POL;\
|
||||
type MPCC_SM_FORCE_NEXT_TOP_POL;\
|
||||
type MPC_OUT_MUX;
|
||||
type MPC_OUT_MUX;\
|
||||
type MPCC_UPDATE_LOCK_SEL;\
|
||||
type CUR_VUPDATE_LOCK_SET;
|
||||
|
||||
struct dcn_mpc_registers {
|
||||
MPC_COMMON_REG_VARIABLE_LIST
|
||||
|
@ -192,4 +198,6 @@ void mpc1_read_mpcc_state(
|
|||
int mpcc_inst,
|
||||
struct mpcc_state *s);
|
||||
|
||||
void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -181,6 +181,14 @@ enum dcn10_clk_src_array_id {
|
|||
.reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
|
||||
mm ## block ## id ## _ ## reg_name
|
||||
|
||||
#define VUPDATE_SRII(reg_name, block, id)\
|
||||
.reg_name[id] = BASE(mm ## reg_name ## 0 ## _ ## block ## id ## _BASE_IDX) + \
|
||||
mm ## reg_name ## 0 ## _ ## block ## id
|
||||
|
||||
/* set field/register/bitfield name */
|
||||
#define SFRB(field_name, reg_name, bitfield, post_fix)\
|
||||
.field_name = reg_name ## __ ## bitfield ## post_fix
|
||||
|
||||
/* NBIO */
|
||||
#define NBIO_BASE_INNER(seg) \
|
||||
NBIF_BASE__INST0_SEG ## seg
|
||||
|
@ -419,11 +427,13 @@ static const struct dcn_mpc_registers mpc_regs = {
|
|||
};
|
||||
|
||||
static const struct dcn_mpc_shift mpc_shift = {
|
||||
MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT)
|
||||
MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT),\
|
||||
SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, __SHIFT)
|
||||
};
|
||||
|
||||
static const struct dcn_mpc_mask mpc_mask = {
|
||||
MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK),
|
||||
MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK),\
|
||||
SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, _MASK)
|
||||
};
|
||||
|
||||
#define tg_regs(id)\
|
||||
|
|
|
@ -2294,7 +2294,8 @@ void dcn20_fpga_init_hw(struct dc *dc)
|
|||
|
||||
REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2);
|
||||
REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
|
||||
REG_WRITE(REFCLK_CNTL, 0);
|
||||
if (REG(REFCLK_CNTL))
|
||||
REG_WRITE(REFCLK_CNTL, 0);
|
||||
//
|
||||
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
|
|||
.disable_plane = dcn20_disable_plane,
|
||||
.pipe_control_lock = dcn20_pipe_control_lock,
|
||||
.interdependent_update_lock = dcn10_lock_all_pipes,
|
||||
.cursor_lock = dcn10_cursor_lock,
|
||||
.prepare_bandwidth = dcn20_prepare_bandwidth,
|
||||
.optimize_bandwidth = dcn20_optimize_bandwidth,
|
||||
.update_bandwidth = dcn20_update_bandwidth,
|
||||
|
|
|
@ -545,6 +545,7 @@ const struct mpc_funcs dcn20_mpc_funcs = {
|
|||
.mpc_init = mpc1_mpc_init,
|
||||
.mpc_init_single_inst = mpc1_mpc_init_single_inst,
|
||||
.update_blending = mpc2_update_blending,
|
||||
.cursor_lock = mpc1_cursor_lock,
|
||||
.get_mpcc_for_dpp = mpc2_get_mpcc_for_dpp,
|
||||
.wait_for_idle = mpc2_assert_idle_mpcc,
|
||||
.assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect,
|
||||
|
|
|
@ -179,7 +179,8 @@
|
|||
SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MAX_G_Y, mask_sh),\
|
||||
SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MIN_G_Y, mask_sh),\
|
||||
SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MAX_B_CB, mask_sh),\
|
||||
SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh)
|
||||
SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh),\
|
||||
SF(CUR_VUPDATE_LOCK_SET0, CUR_VUPDATE_LOCK_SET, mask_sh)
|
||||
|
||||
/*
|
||||
* DCN2 MPC_OCSC debug status register:
|
||||
|
|
|
@ -508,6 +508,10 @@ enum dcn20_clk_src_array_id {
|
|||
.block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
|
||||
mm ## block ## id ## _ ## reg_name
|
||||
|
||||
#define VUPDATE_SRII(reg_name, block, id)\
|
||||
.reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \
|
||||
mm ## reg_name ## _ ## block ## id
|
||||
|
||||
/* NBIO */
|
||||
#define NBIO_BASE_INNER(seg) \
|
||||
NBIO_BASE__INST0_SEG ## seg
|
||||
|
|
|
@ -53,6 +53,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
|
|||
.disable_plane = dcn20_disable_plane,
|
||||
.pipe_control_lock = dcn20_pipe_control_lock,
|
||||
.interdependent_update_lock = dcn10_lock_all_pipes,
|
||||
.cursor_lock = dcn10_cursor_lock,
|
||||
.prepare_bandwidth = dcn20_prepare_bandwidth,
|
||||
.optimize_bandwidth = dcn20_optimize_bandwidth,
|
||||
.update_bandwidth = dcn20_update_bandwidth,
|
||||
|
|
|
@ -284,7 +284,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
|
|||
.dram_channel_width_bytes = 4,
|
||||
.fabric_datapath_to_dcn_data_return_bytes = 32,
|
||||
.dcn_downspread_percent = 0.5,
|
||||
.downspread_percent = 0.5,
|
||||
.downspread_percent = 0.38,
|
||||
.dram_page_open_time_ns = 50.0,
|
||||
.dram_rw_turnaround_time_ns = 17.5,
|
||||
.dram_return_buffer_per_channel_bytes = 8192,
|
||||
|
@ -340,6 +340,10 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
|
|||
.block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
|
||||
mm ## block ## id ## _ ## reg_name
|
||||
|
||||
#define VUPDATE_SRII(reg_name, block, id)\
|
||||
.reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \
|
||||
mm ## reg_name ## _ ## block ## id
|
||||
|
||||
/* NBIO */
|
||||
#define NBIO_BASE_INNER(seg) \
|
||||
NBIF0_BASE__INST0_SEG ## seg
|
||||
|
@ -1374,64 +1378,49 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
|
|||
{
|
||||
struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
|
||||
struct clk_limit_table *clk_table = &bw_params->clk_table;
|
||||
unsigned int i, j, k;
|
||||
int closest_clk_lvl;
|
||||
struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
|
||||
unsigned int i, j, closest_clk_lvl;
|
||||
|
||||
// Default clock levels are used for diags, which may lead to overclocking.
|
||||
if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) && !IS_DIAG_DC(dc->ctx->dce_environment)) {
|
||||
if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
|
||||
dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
|
||||
dcn2_1_ip.max_num_dpp = pool->base.pipe_count;
|
||||
dcn2_1_soc.num_chans = bw_params->num_channels;
|
||||
|
||||
/* Vmin: leave lowest DCN clocks, override with dcfclk, fclk, memclk from fuse */
|
||||
dcn2_1_soc.clock_limits[0].state = 0;
|
||||
dcn2_1_soc.clock_limits[0].dcfclk_mhz = clk_table->entries[0].dcfclk_mhz;
|
||||
dcn2_1_soc.clock_limits[0].fabricclk_mhz = clk_table->entries[0].fclk_mhz;
|
||||
dcn2_1_soc.clock_limits[0].socclk_mhz = clk_table->entries[0].socclk_mhz;
|
||||
dcn2_1_soc.clock_limits[0].dram_speed_mts = clk_table->entries[0].memclk_mhz * 2;
|
||||
|
||||
/*
|
||||
* Other levels: find closest DCN clocks that fit the given clock limit using dcfclk
|
||||
* as indicator
|
||||
*/
|
||||
|
||||
closest_clk_lvl = -1;
|
||||
/* index currently being filled */
|
||||
k = 1;
|
||||
for (i = 1; i < clk_table->num_entries; i++) {
|
||||
/* loop backwards, skip duplicate state*/
|
||||
for (j = dcn2_1_soc.num_states - 1; j >= k; j--) {
|
||||
ASSERT(clk_table->num_entries);
|
||||
for (i = 0; i < clk_table->num_entries; i++) {
|
||||
/* loop backwards*/
|
||||
for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) {
|
||||
if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
|
||||
closest_clk_lvl = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if found a lvl that fits, use the DCN clks from it, if not, go to next clk limit*/
|
||||
if (closest_clk_lvl != -1) {
|
||||
dcn2_1_soc.clock_limits[k].state = i;
|
||||
dcn2_1_soc.clock_limits[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].socclk_mhz = clk_table->entries[i].socclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
|
||||
clock_limits[i].state = i;
|
||||
clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
|
||||
clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
|
||||
clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
|
||||
clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
|
||||
|
||||
dcn2_1_soc.clock_limits[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
|
||||
dcn2_1_soc.clock_limits[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
|
||||
dcn2_1_soc.clock_limits[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
|
||||
k++;
|
||||
}
|
||||
clock_limits[i].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
|
||||
clock_limits[i].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
|
||||
clock_limits[i].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
|
||||
clock_limits[i].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
|
||||
clock_limits[i].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
|
||||
clock_limits[i].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
|
||||
clock_limits[i].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
|
||||
}
|
||||
for (i = 0; i < clk_table->num_entries; i++)
|
||||
dcn2_1_soc.clock_limits[i] = clock_limits[i];
|
||||
if (clk_table->num_entries) {
|
||||
dcn2_1_soc.num_states = clk_table->num_entries;
|
||||
/* duplicate last level */
|
||||
dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1];
|
||||
dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states;
|
||||
}
|
||||
dcn2_1_soc.num_states = k;
|
||||
}
|
||||
|
||||
/* duplicate last level */
|
||||
dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1];
|
||||
dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states;
|
||||
|
||||
dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
|
||||
}
|
||||
|
||||
|
|
|
@ -210,6 +210,22 @@ struct mpc_funcs {
|
|||
struct mpcc_blnd_cfg *blnd_cfg,
|
||||
int mpcc_id);
|
||||
|
||||
/*
|
||||
* Lock cursor updates for the specified OPP.
|
||||
* OPP defines the set of MPCC that are locked together for cursor.
|
||||
*
|
||||
* Parameters:
|
||||
* [in] mpc - MPC context.
|
||||
* [in] opp_id - The OPP to lock cursor updates on
|
||||
* [in] lock - lock/unlock the OPP
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void (*cursor_lock)(
|
||||
struct mpc *mpc,
|
||||
int opp_id,
|
||||
bool lock);
|
||||
|
||||
struct mpcc* (*get_mpcc_for_dpp)(
|
||||
struct mpc_tree *tree,
|
||||
int dpp_id);
|
||||
|
|
|
@ -86,6 +86,7 @@ struct hw_sequencer_funcs {
|
|||
struct dc_state *context, bool lock);
|
||||
void (*set_flip_control_gsl)(struct pipe_ctx *pipe_ctx,
|
||||
bool flip_immediate);
|
||||
void (*cursor_lock)(struct dc *dc, struct pipe_ctx *pipe, bool lock);
|
||||
|
||||
/* Timing Related */
|
||||
void (*get_position)(struct pipe_ctx **pipe_ctx, int num_pipes,
|
||||
|
|
|
@ -1435,7 +1435,8 @@ static int pp_get_asic_baco_capability(void *handle, bool *cap)
|
|||
if (!hwmgr)
|
||||
return -EINVAL;
|
||||
|
||||
if (!hwmgr->pm_en || !hwmgr->hwmgr_func->get_asic_baco_capability)
|
||||
if (!(hwmgr->not_vf && amdgpu_dpm) ||
|
||||
!hwmgr->hwmgr_func->get_asic_baco_capability)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&hwmgr->smu_lock);
|
||||
|
@ -1452,8 +1453,7 @@ static int pp_get_asic_baco_state(void *handle, int *state)
|
|||
if (!hwmgr)
|
||||
return -EINVAL;
|
||||
|
||||
if (!(hwmgr->not_vf && amdgpu_dpm) ||
|
||||
!hwmgr->hwmgr_func->get_asic_baco_state)
|
||||
if (!hwmgr->pm_en || !hwmgr->hwmgr_func->get_asic_baco_state)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&hwmgr->smu_lock);
|
||||
|
@ -1470,7 +1470,8 @@ static int pp_set_asic_baco_state(void *handle, int state)
|
|||
if (!hwmgr)
|
||||
return -EINVAL;
|
||||
|
||||
if (!hwmgr->pm_en || !hwmgr->hwmgr_func->set_asic_baco_state)
|
||||
if (!(hwmgr->not_vf && amdgpu_dpm) ||
|
||||
!hwmgr->hwmgr_func->set_asic_baco_state)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&hwmgr->smu_lock);
|
||||
|
|
|
@ -346,6 +346,10 @@ struct drm_amdgpu_gem_userptr {
|
|||
#define AMDGPU_TILING_DCC_PITCH_MAX_MASK 0x3FFF
|
||||
#define AMDGPU_TILING_DCC_INDEPENDENT_64B_SHIFT 43
|
||||
#define AMDGPU_TILING_DCC_INDEPENDENT_64B_MASK 0x1
|
||||
#define AMDGPU_TILING_DCC_INDEPENDENT_128B_SHIFT 44
|
||||
#define AMDGPU_TILING_DCC_INDEPENDENT_128B_MASK 0x1
|
||||
#define AMDGPU_TILING_SCANOUT_SHIFT 63
|
||||
#define AMDGPU_TILING_SCANOUT_MASK 0x1
|
||||
|
||||
/* Set/Get helpers for tiling flags. */
|
||||
#define AMDGPU_TILING_SET(field, value) \
|
||||
|
|
Loading…
Reference in New Issue
Block a user