mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-26 20:44:32 +08:00
drm/amd/display: Refactor FreeSync module
Remove dependency on internal sink map and instead use existing stream and plane state Signed-off-by: Anthony Koo <Anthony.Koo@amd.com> Signed-off-by: Harry Wentland <harry.wentland@amd.com> Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> Acked-by: Harry Wentland <harry.wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
8c3db1284a
commit
98e6436d3a
@ -839,8 +839,7 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
|
||||
|
||||
if (sink) {
|
||||
if (aconnector->dc_sink) {
|
||||
amdgpu_dm_remove_sink_from_freesync_module(
|
||||
connector);
|
||||
amdgpu_dm_update_freesync_caps(connector, NULL);
|
||||
/* retain and release bellow are used for
|
||||
* bump up refcount for sink because the link don't point
|
||||
* to it anymore after disconnect so on next crtc to connector
|
||||
@ -850,10 +849,10 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
|
||||
dc_sink_release(aconnector->dc_sink);
|
||||
}
|
||||
aconnector->dc_sink = sink;
|
||||
amdgpu_dm_add_sink_to_freesync_module(
|
||||
connector, aconnector->edid);
|
||||
amdgpu_dm_update_freesync_caps(connector,
|
||||
aconnector->edid);
|
||||
} else {
|
||||
amdgpu_dm_remove_sink_from_freesync_module(connector);
|
||||
amdgpu_dm_update_freesync_caps(connector, NULL);
|
||||
if (!aconnector->dc_sink)
|
||||
aconnector->dc_sink = aconnector->dc_em_sink;
|
||||
else if (aconnector->dc_sink != aconnector->dc_em_sink)
|
||||
@ -890,8 +889,7 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
|
||||
/* TODO: check if we still need the S3 mode update workaround.
|
||||
* If yes, put it here. */
|
||||
if (aconnector->dc_sink)
|
||||
amdgpu_dm_remove_sink_from_freesync_module(
|
||||
connector);
|
||||
amdgpu_dm_update_freesync_caps(connector, NULL);
|
||||
|
||||
aconnector->dc_sink = sink;
|
||||
if (sink->dc_edid.length == 0) {
|
||||
@ -904,10 +902,10 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
|
||||
drm_connector_update_edid_property(connector,
|
||||
aconnector->edid);
|
||||
}
|
||||
amdgpu_dm_add_sink_to_freesync_module(connector, aconnector->edid);
|
||||
amdgpu_dm_update_freesync_caps(connector, aconnector->edid);
|
||||
|
||||
} else {
|
||||
amdgpu_dm_remove_sink_from_freesync_module(connector);
|
||||
amdgpu_dm_update_freesync_caps(connector, NULL);
|
||||
drm_connector_update_edid_property(connector, NULL);
|
||||
aconnector->num_modes = 0;
|
||||
aconnector->dc_sink = NULL;
|
||||
@ -1580,26 +1578,68 @@ static void dm_bandwidth_update(struct amdgpu_device *adev)
|
||||
static int amdgpu_notify_freesync(struct drm_device *dev, void *data,
|
||||
struct drm_file *filp)
|
||||
{
|
||||
struct mod_freesync_params freesync_params;
|
||||
uint8_t num_streams;
|
||||
struct drm_atomic_state *state;
|
||||
struct drm_modeset_acquire_ctx ctx;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_state *old_con_state, *new_con_state;
|
||||
int ret = 0;
|
||||
uint8_t i;
|
||||
bool enable = false;
|
||||
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
int r = 0;
|
||||
drm_modeset_acquire_init(&ctx, 0);
|
||||
|
||||
/* Get freesync enable flag from DRM */
|
||||
state = drm_atomic_state_alloc(dev);
|
||||
if (!state) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
state->acquire_ctx = &ctx;
|
||||
|
||||
num_streams = dc_get_current_stream_count(adev->dm.dc);
|
||||
retry:
|
||||
drm_for_each_crtc(crtc, dev) {
|
||||
ret = drm_atomic_add_affected_connectors(state, crtc);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < num_streams; i++) {
|
||||
struct dc_stream_state *stream;
|
||||
stream = dc_get_stream_at_index(adev->dm.dc, i);
|
||||
|
||||
mod_freesync_update_state(adev->dm.freesync_module,
|
||||
&stream, 1, &freesync_params);
|
||||
/* TODO rework amdgpu_dm_commit_planes so we don't need this */
|
||||
ret = drm_atomic_add_affected_planes(state, crtc);
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return r;
|
||||
for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
|
||||
struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
|
||||
struct drm_crtc_state *new_crtc_state;
|
||||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
|
||||
struct dm_crtc_state *dm_new_crtc_state;
|
||||
|
||||
if (!acrtc) {
|
||||
ASSERT(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
|
||||
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
|
||||
|
||||
dm_new_crtc_state->freesync_enabled = enable;
|
||||
}
|
||||
|
||||
ret = drm_atomic_commit(state);
|
||||
|
||||
fail:
|
||||
if (ret == -EDEADLK) {
|
||||
drm_atomic_state_clear(state);
|
||||
drm_modeset_backoff(&ctx);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
drm_atomic_state_put(state);
|
||||
|
||||
out:
|
||||
drm_modeset_drop_locks(&ctx);
|
||||
drm_modeset_acquire_fini(&ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct amdgpu_display_funcs dm_display_funcs = {
|
||||
@ -2563,6 +2603,10 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc)
|
||||
dc_stream_retain(state->stream);
|
||||
}
|
||||
|
||||
state->adjust = cur->adjust;
|
||||
state->vrr_infopacket = cur->vrr_infopacket;
|
||||
state->freesync_enabled = cur->freesync_enabled;
|
||||
|
||||
/* TODO Duplicate dc_stream after objects are stream object is flattened */
|
||||
|
||||
return &state->base;
|
||||
@ -2770,13 +2814,15 @@ amdgpu_dm_connector_atomic_duplicate_state(struct drm_connector *connector)
|
||||
struct dm_connector_state *new_state =
|
||||
kmemdup(state, sizeof(*state), GFP_KERNEL);
|
||||
|
||||
if (new_state) {
|
||||
__drm_atomic_helper_connector_duplicate_state(connector,
|
||||
&new_state->base);
|
||||
return &new_state->base;
|
||||
}
|
||||
if (!new_state)
|
||||
return NULL;
|
||||
|
||||
return NULL;
|
||||
__drm_atomic_helper_connector_duplicate_state(connector, &new_state->base);
|
||||
|
||||
new_state->freesync_capable = state->freesync_capable;
|
||||
new_state->freesync_enable = state->freesync_enable;
|
||||
|
||||
return &new_state->base;
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs amdgpu_dm_connector_funcs = {
|
||||
@ -3786,8 +3832,6 @@ static void remove_stream(struct amdgpu_device *adev,
|
||||
struct dc_stream_state *stream)
|
||||
{
|
||||
/* this is the update mode case */
|
||||
if (adev->dm.freesync_module)
|
||||
mod_freesync_remove_stream(adev->dm.freesync_module, stream);
|
||||
|
||||
acrtc->otg_inst = -1;
|
||||
acrtc->enabled = false;
|
||||
@ -4055,6 +4099,11 @@ static bool commit_planes_to_stream(
|
||||
stream_update->dst = dc_stream->dst;
|
||||
stream_update->out_transfer_func = dc_stream->out_transfer_func;
|
||||
|
||||
if (dm_new_crtc_state->freesync_enabled != dm_old_crtc_state->freesync_enabled) {
|
||||
stream_update->vrr_infopacket = &dc_stream->vrr_infopacket;
|
||||
stream_update->adjust = &dc_stream->adjust;
|
||||
}
|
||||
|
||||
for (i = 0; i < new_plane_count; i++) {
|
||||
updates[i].surface = plane_states[i];
|
||||
updates[i].gamma =
|
||||
@ -4190,6 +4239,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
||||
spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
|
||||
}
|
||||
|
||||
dc_stream_attach->adjust = acrtc_state->adjust;
|
||||
dc_stream_attach->vrr_infopacket = acrtc_state->vrr_infopacket;
|
||||
|
||||
if (false == commit_planes_to_stream(dm->dc,
|
||||
plane_states_constructed,
|
||||
@ -4339,62 +4390,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
||||
}
|
||||
} /* for_each_crtc_in_state() */
|
||||
|
||||
/*
|
||||
* Add streams after required streams from new and replaced streams
|
||||
* are removed from freesync module
|
||||
*/
|
||||
if (adev->dm.freesync_module) {
|
||||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
|
||||
new_crtc_state, i) {
|
||||
struct amdgpu_dm_connector *aconnector = NULL;
|
||||
struct dm_connector_state *dm_new_con_state = NULL;
|
||||
struct amdgpu_crtc *acrtc = NULL;
|
||||
bool modeset_needed;
|
||||
|
||||
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
|
||||
dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
|
||||
modeset_needed = modeset_required(
|
||||
new_crtc_state,
|
||||
dm_new_crtc_state->stream,
|
||||
dm_old_crtc_state->stream);
|
||||
/* We add stream to freesync if:
|
||||
* 1. Said stream is not null, and
|
||||
* 2. A modeset is requested. This means that the
|
||||
* stream was removed previously, and needs to be
|
||||
* replaced.
|
||||
*/
|
||||
if (dm_new_crtc_state->stream == NULL ||
|
||||
!modeset_needed)
|
||||
continue;
|
||||
|
||||
acrtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
aconnector =
|
||||
amdgpu_dm_find_first_crtc_matching_connector(
|
||||
state, crtc);
|
||||
if (!aconnector) {
|
||||
DRM_DEBUG_DRIVER("Atomic commit: Failed to "
|
||||
"find connector for acrtc "
|
||||
"id:%d skipping freesync "
|
||||
"init\n",
|
||||
acrtc->crtc_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
mod_freesync_add_stream(adev->dm.freesync_module,
|
||||
dm_new_crtc_state->stream,
|
||||
&aconnector->caps);
|
||||
new_con_state = drm_atomic_get_new_connector_state(
|
||||
state, &aconnector->base);
|
||||
dm_new_con_state = to_dm_connector_state(new_con_state);
|
||||
|
||||
mod_freesync_set_user_enable(adev->dm.freesync_module,
|
||||
&dm_new_crtc_state->stream,
|
||||
1,
|
||||
&dm_new_con_state->user_enable);
|
||||
}
|
||||
}
|
||||
|
||||
if (dm_state->context) {
|
||||
dm_enable_per_frame_crtc_master_sync(dm_state->context);
|
||||
WARN_ON(!dc_commit_state(dm->dc, dm_state->context));
|
||||
@ -4448,6 +4443,9 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
||||
WARN_ON(!status);
|
||||
WARN_ON(!status->plane_count);
|
||||
|
||||
dm_new_crtc_state->stream->adjust = dm_new_crtc_state->adjust;
|
||||
dm_new_crtc_state->stream->vrr_infopacket = dm_new_crtc_state->vrr_infopacket;
|
||||
|
||||
/*TODO How it works with MPO ?*/
|
||||
if (!commit_planes_to_stream(
|
||||
dm->dc,
|
||||
@ -4480,11 +4478,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
||||
if (dm_new_crtc_state->stream == NULL || !modeset_needed)
|
||||
continue;
|
||||
|
||||
if (adev->dm.freesync_module)
|
||||
mod_freesync_notify_mode_change(
|
||||
adev->dm.freesync_module,
|
||||
&dm_new_crtc_state->stream, 1);
|
||||
|
||||
manage_dm_interrupts(adev, acrtc, true);
|
||||
}
|
||||
|
||||
@ -4667,7 +4660,42 @@ static int do_aquire_global_lock(struct drm_device *dev,
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
static int dm_update_crtcs_state(struct dc *dc,
|
||||
void set_freesync_on_stream(struct amdgpu_display_manager *dm,
|
||||
struct dm_crtc_state *new_crtc_state,
|
||||
struct dm_connector_state *new_con_state,
|
||||
struct dc_stream_state *new_stream)
|
||||
{
|
||||
struct mod_freesync_config config = {0};
|
||||
struct mod_vrr_params vrr = {0};
|
||||
struct dc_info_packet vrr_infopacket = {0};
|
||||
struct amdgpu_dm_connector *aconnector =
|
||||
to_amdgpu_dm_connector(new_con_state->base.connector);
|
||||
|
||||
if (new_con_state->freesync_capable &&
|
||||
new_con_state->freesync_enable) {
|
||||
config.state = new_crtc_state->freesync_enabled ?
|
||||
VRR_STATE_ACTIVE_VARIABLE :
|
||||
VRR_STATE_INACTIVE;
|
||||
config.min_refresh_in_uhz =
|
||||
aconnector->min_vfreq * 1000000;
|
||||
config.max_refresh_in_uhz =
|
||||
aconnector->max_vfreq * 1000000;
|
||||
}
|
||||
|
||||
mod_freesync_build_vrr_params(dm->freesync_module,
|
||||
new_stream,
|
||||
&config, &vrr);
|
||||
|
||||
mod_freesync_build_vrr_infopacket(dm->freesync_module,
|
||||
new_stream,
|
||||
&vrr,
|
||||
&vrr_infopacket);
|
||||
|
||||
new_crtc_state->adjust = vrr.adjust;
|
||||
new_crtc_state->vrr_infopacket = vrr_infopacket;
|
||||
}
|
||||
|
||||
static int dm_update_crtcs_state(struct amdgpu_display_manager *dm,
|
||||
struct drm_atomic_state *state,
|
||||
bool enable,
|
||||
bool *lock_and_validation_needed)
|
||||
@ -4737,6 +4765,9 @@ static int dm_update_crtcs_state(struct dc *dc,
|
||||
break;
|
||||
}
|
||||
|
||||
set_freesync_on_stream(dm, dm_new_crtc_state,
|
||||
dm_new_conn_state, new_stream);
|
||||
|
||||
if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) &&
|
||||
dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) {
|
||||
new_crtc_state->mode_changed = false;
|
||||
@ -4745,6 +4776,9 @@ static int dm_update_crtcs_state(struct dc *dc,
|
||||
}
|
||||
}
|
||||
|
||||
if (dm_old_crtc_state->freesync_enabled != dm_new_crtc_state->freesync_enabled)
|
||||
new_crtc_state->mode_changed = true;
|
||||
|
||||
if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
|
||||
goto next_crtc;
|
||||
|
||||
@ -4771,7 +4805,7 @@ static int dm_update_crtcs_state(struct dc *dc,
|
||||
|
||||
/* i.e. reset mode */
|
||||
if (dc_remove_stream_from_ctx(
|
||||
dc,
|
||||
dm->dc,
|
||||
dm_state->context,
|
||||
dm_old_crtc_state->stream) != DC_OK) {
|
||||
ret = -EINVAL;
|
||||
@ -4808,7 +4842,7 @@ static int dm_update_crtcs_state(struct dc *dc,
|
||||
crtc->base.id);
|
||||
|
||||
if (dc_add_stream_to_ctx(
|
||||
dc,
|
||||
dm->dc,
|
||||
dm_state->context,
|
||||
dm_new_crtc_state->stream) != DC_OK) {
|
||||
ret = -EINVAL;
|
||||
@ -4857,6 +4891,8 @@ next_crtc:
|
||||
goto fail;
|
||||
amdgpu_dm_set_ctm(dm_new_crtc_state);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -5024,8 +5060,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
goto fail;
|
||||
|
||||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
|
||||
struct dm_crtc_state *dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
|
||||
struct dm_crtc_state *dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
|
||||
|
||||
if (!drm_atomic_crtc_needs_modeset(new_crtc_state) &&
|
||||
!new_crtc_state->color_mgmt_changed)
|
||||
!new_crtc_state->color_mgmt_changed &&
|
||||
(dm_old_crtc_state->freesync_enabled == dm_new_crtc_state->freesync_enabled))
|
||||
continue;
|
||||
|
||||
if (!new_crtc_state->enable)
|
||||
@ -5051,13 +5091,13 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
}
|
||||
|
||||
/* Disable all crtcs which require disable */
|
||||
ret = dm_update_crtcs_state(dc, state, false, &lock_and_validation_needed);
|
||||
ret = dm_update_crtcs_state(&adev->dm, state, false, &lock_and_validation_needed);
|
||||
if (ret) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Enable all crtcs which require enable */
|
||||
ret = dm_update_crtcs_state(dc, state, true, &lock_and_validation_needed);
|
||||
ret = dm_update_crtcs_state(&adev->dm, state, true, &lock_and_validation_needed);
|
||||
if (ret) {
|
||||
goto fail;
|
||||
}
|
||||
@ -5150,8 +5190,8 @@ static bool is_dp_capable_without_timing_msa(struct dc *dc,
|
||||
|
||||
return capable;
|
||||
}
|
||||
void amdgpu_dm_add_sink_to_freesync_module(struct drm_connector *connector,
|
||||
struct edid *edid)
|
||||
void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
|
||||
struct edid *edid)
|
||||
{
|
||||
int i;
|
||||
bool edid_check_required;
|
||||
@ -5170,6 +5210,18 @@ void amdgpu_dm_add_sink_to_freesync_module(struct drm_connector *connector,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!edid) {
|
||||
dm_con_state = to_dm_connector_state(connector->state);
|
||||
|
||||
amdgpu_dm_connector->min_vfreq = 0;
|
||||
amdgpu_dm_connector->max_vfreq = 0;
|
||||
amdgpu_dm_connector->pixel_clock_mhz = 0;
|
||||
|
||||
dm_con_state->freesync_capable = false;
|
||||
dm_con_state->freesync_enable = false;
|
||||
return;
|
||||
}
|
||||
|
||||
dm_con_state = to_dm_connector_state(connector->state);
|
||||
|
||||
edid_check_required = false;
|
||||
@ -5220,46 +5272,10 @@ void amdgpu_dm_add_sink_to_freesync_module(struct drm_connector *connector,
|
||||
}
|
||||
|
||||
if (amdgpu_dm_connector->max_vfreq -
|
||||
amdgpu_dm_connector->min_vfreq > 10) {
|
||||
amdgpu_dm_connector->caps.supported = true;
|
||||
amdgpu_dm_connector->caps.min_refresh_in_micro_hz =
|
||||
amdgpu_dm_connector->min_vfreq * 1000000;
|
||||
amdgpu_dm_connector->caps.max_refresh_in_micro_hz =
|
||||
amdgpu_dm_connector->max_vfreq * 1000000;
|
||||
amdgpu_dm_connector->min_vfreq > 10) {
|
||||
|
||||
dm_con_state->freesync_capable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_dm_remove_sink_from_freesync_module(struct drm_connector *connector)
|
||||
{
|
||||
struct amdgpu_dm_connector *amdgpu_dm_connector =
|
||||
to_amdgpu_dm_connector(connector);
|
||||
struct dm_connector_state *dm_con_state;
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
|
||||
if (!amdgpu_dm_connector->dc_sink || !adev->dm.freesync_module) {
|
||||
DRM_ERROR("dc_sink NULL or no free_sync module.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!connector->state) {
|
||||
DRM_ERROR("%s - Connector has no state", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
dm_con_state = to_dm_connector_state(connector->state);
|
||||
|
||||
amdgpu_dm_connector->min_vfreq = 0;
|
||||
amdgpu_dm_connector->max_vfreq = 0;
|
||||
amdgpu_dm_connector->pixel_clock_mhz = 0;
|
||||
|
||||
memset(&amdgpu_dm_connector->caps, 0, sizeof(amdgpu_dm_connector->caps));
|
||||
|
||||
dm_con_state->freesync_capable = false;
|
||||
|
||||
dm_con_state->user_enable.enable_for_gaming = false;
|
||||
dm_con_state->user_enable.enable_for_static = false;
|
||||
dm_con_state->user_enable.enable_for_video = false;
|
||||
}
|
||||
|
@ -167,9 +167,6 @@ struct amdgpu_dm_connector {
|
||||
int max_vfreq ;
|
||||
int pixel_clock_mhz;
|
||||
|
||||
/*freesync caps*/
|
||||
struct mod_freesync_caps caps;
|
||||
|
||||
struct mutex hpd_lock;
|
||||
|
||||
bool fake_enable;
|
||||
@ -197,9 +194,13 @@ struct dm_crtc_state {
|
||||
|
||||
int crc_skip_count;
|
||||
bool crc_enabled;
|
||||
|
||||
bool freesync_enabled;
|
||||
struct dc_crtc_timing_adjust adjust;
|
||||
struct dc_info_packet vrr_infopacket;
|
||||
};
|
||||
|
||||
#define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base)
|
||||
#define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base)
|
||||
|
||||
struct dm_atomic_state {
|
||||
struct drm_atomic_state base;
|
||||
@ -216,7 +217,7 @@ struct dm_connector_state {
|
||||
uint8_t underscan_vborder;
|
||||
uint8_t underscan_hborder;
|
||||
bool underscan_enable;
|
||||
struct mod_freesync_user_enable user_enable;
|
||||
bool freesync_enable;
|
||||
bool freesync_capable;
|
||||
};
|
||||
|
||||
@ -250,11 +251,8 @@ enum drm_mode_status amdgpu_dm_connector_mode_valid(struct drm_connector *connec
|
||||
void dm_restore_drm_connector_state(struct drm_device *dev,
|
||||
struct drm_connector *connector);
|
||||
|
||||
void amdgpu_dm_add_sink_to_freesync_module(struct drm_connector *connector,
|
||||
struct edid *edid);
|
||||
|
||||
void
|
||||
amdgpu_dm_remove_sink_from_freesync_module(struct drm_connector *connector);
|
||||
void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
|
||||
struct edid *edid);
|
||||
|
||||
/* amdgpu_dm_crc.c */
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
@ -234,8 +234,9 @@ void dm_dp_mst_dc_sink_create(struct drm_connector *connector)
|
||||
dc_sink->priv = aconnector;
|
||||
aconnector->dc_sink = dc_sink;
|
||||
|
||||
amdgpu_dm_add_sink_to_freesync_module(
|
||||
connector, aconnector->edid);
|
||||
if (aconnector->dc_sink)
|
||||
amdgpu_dm_update_freesync_caps(
|
||||
connector, aconnector->edid);
|
||||
}
|
||||
|
||||
static int dm_dp_mst_get_modes(struct drm_connector *connector)
|
||||
@ -275,8 +276,9 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
|
||||
aconnector->dc_sink = dc_sink;
|
||||
|
||||
if (aconnector->dc_sink)
|
||||
amdgpu_dm_add_sink_to_freesync_module(
|
||||
amdgpu_dm_update_freesync_caps(
|
||||
connector, aconnector->edid);
|
||||
|
||||
}
|
||||
|
||||
drm_connector_update_edid_property(
|
||||
@ -439,7 +441,7 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
|
||||
|
||||
aconnector->port = NULL;
|
||||
if (aconnector->dc_sink) {
|
||||
amdgpu_dm_remove_sink_from_freesync_module(connector);
|
||||
amdgpu_dm_update_freesync_caps(connector, NULL);
|
||||
dc_link_remove_remote_sink(aconnector->dc_link, aconnector->dc_sink);
|
||||
dc_sink_release(aconnector->dc_sink);
|
||||
aconnector->dc_sink = NULL;
|
||||
|
@ -188,11 +188,9 @@ failed_alloc:
|
||||
*****************************************************************************
|
||||
*/
|
||||
bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
||||
struct dc_stream_state **streams, int num_streams,
|
||||
int vmin, int vmax)
|
||||
struct dc_stream_state *stream,
|
||||
struct dc_crtc_timing_adjust *adjust)
|
||||
{
|
||||
/* TODO: Support multiple streams */
|
||||
struct dc_stream_state *stream = streams[0];
|
||||
int i = 0;
|
||||
bool ret = false;
|
||||
|
||||
@ -200,11 +198,11 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
||||
struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (pipe->stream == stream && pipe->stream_res.stream_enc) {
|
||||
dc->hwss.set_drr(&pipe, 1, vmin, vmax);
|
||||
|
||||
/* build and update the info frame */
|
||||
resource_build_info_frame(pipe);
|
||||
dc->hwss.update_info_frame(pipe);
|
||||
pipe->stream->adjust = *adjust;
|
||||
dc->hwss.set_drr(&pipe,
|
||||
1,
|
||||
adjust->v_total_min,
|
||||
adjust->v_total_max);
|
||||
|
||||
ret = true;
|
||||
}
|
||||
@ -217,7 +215,7 @@ bool dc_stream_get_crtc_position(struct dc *dc,
|
||||
unsigned int *v_pos, unsigned int *nom_v_pos)
|
||||
{
|
||||
/* TODO: Support multiple streams */
|
||||
struct dc_stream_state *stream = streams[0];
|
||||
const struct dc_stream_state *stream = streams[0];
|
||||
int i = 0;
|
||||
bool ret = false;
|
||||
struct crtc_position position;
|
||||
@ -1257,8 +1255,25 @@ static enum surface_update_type check_update_surfaces_for_stream(
|
||||
if (stream_status == NULL || stream_status->plane_count != surface_count)
|
||||
return UPDATE_TYPE_FULL;
|
||||
|
||||
if (stream_update)
|
||||
return UPDATE_TYPE_FULL;
|
||||
/* some stream updates require passive update */
|
||||
if (stream_update) {
|
||||
if ((stream_update->src.height != 0) &&
|
||||
(stream_update->src.width != 0))
|
||||
return UPDATE_TYPE_FULL;
|
||||
|
||||
if ((stream_update->dst.height != 0) &&
|
||||
(stream_update->dst.width != 0))
|
||||
return UPDATE_TYPE_FULL;
|
||||
|
||||
if (stream_update->out_transfer_func)
|
||||
return UPDATE_TYPE_FULL;
|
||||
|
||||
if (stream_update->hdr_static_metadata)
|
||||
return UPDATE_TYPE_FULL;
|
||||
|
||||
if (stream_update->abm_level)
|
||||
return UPDATE_TYPE_FULL;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < surface_count; i++) {
|
||||
enum surface_update_type type =
|
||||
@ -1337,7 +1352,6 @@ static void commit_planes_for_stream(struct dc *dc,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Full fe update*/
|
||||
for (j = 0; j < dc->res_pool->pipe_count; j++) {
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
|
||||
|
||||
@ -1348,11 +1362,22 @@ static void commit_planes_for_stream(struct dc *dc,
|
||||
|
||||
top_pipe_to_program = pipe_ctx;
|
||||
|
||||
if (update_type == UPDATE_TYPE_FAST || !pipe_ctx->plane_state)
|
||||
if (!pipe_ctx->plane_state)
|
||||
continue;
|
||||
|
||||
/* Fast update*/
|
||||
// VRR program can be done as part of FAST UPDATE
|
||||
if (stream_update && stream_update->adjust)
|
||||
dc->hwss.set_drr(&pipe_ctx, 1,
|
||||
stream_update->adjust->v_total_min,
|
||||
stream_update->adjust->v_total_max);
|
||||
|
||||
/* Full fe update*/
|
||||
if (update_type == UPDATE_TYPE_FAST)
|
||||
continue;
|
||||
|
||||
stream_status =
|
||||
stream_get_status(context, pipe_ctx->stream);
|
||||
stream_get_status(context, pipe_ctx->stream);
|
||||
|
||||
dc->hwss.apply_ctx_for_surface(
|
||||
dc, pipe_ctx->stream, stream_status->plane_count, context);
|
||||
@ -1407,7 +1432,7 @@ static void commit_planes_for_stream(struct dc *dc,
|
||||
dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
|
||||
}
|
||||
|
||||
if (stream && stream_update && update_type > UPDATE_TYPE_FAST)
|
||||
if (stream && stream_update)
|
||||
for (j = 0; j < dc->res_pool->pipe_count; j++) {
|
||||
struct pipe_ctx *pipe_ctx =
|
||||
&context->res_ctx.pipe_ctx[j];
|
||||
@ -1415,7 +1440,8 @@ static void commit_planes_for_stream(struct dc *dc,
|
||||
if (pipe_ctx->stream != stream)
|
||||
continue;
|
||||
|
||||
if (stream_update->hdr_static_metadata) {
|
||||
if (stream_update->hdr_static_metadata ||
|
||||
(stream_update->vrr_infopacket)) {
|
||||
resource_build_info_frame(pipe_ctx);
|
||||
dc->hwss.update_info_frame(pipe_ctx);
|
||||
}
|
||||
|
@ -2389,6 +2389,9 @@ static bool retrieve_link_cap(struct dc_link *link)
|
||||
|
||||
dp_wa_power_up_0010FA(link, dpcd_data, sizeof(dpcd_data));
|
||||
|
||||
down_strm_port_count.raw = dpcd_data[DP_DOWN_STREAM_PORT_COUNT -
|
||||
DP_DPCD_REV];
|
||||
|
||||
link->dpcd_caps.allow_invalid_MSA_timing_param =
|
||||
down_strm_port_count.bits.IGNORE_MSA_TIMING_PARAM;
|
||||
|
||||
|
@ -2475,119 +2475,13 @@ static void set_spd_info_packet(
|
||||
{
|
||||
/* SPD info packet for FreeSync */
|
||||
|
||||
unsigned char checksum = 0;
|
||||
unsigned int idx, payload_size = 0;
|
||||
|
||||
/* Check if Freesync is supported. Return if false. If true,
|
||||
* set the corresponding bit in the info packet
|
||||
*/
|
||||
if (stream->freesync_ctx.supported == false)
|
||||
if (!stream->vrr_infopacket.valid)
|
||||
return;
|
||||
|
||||
if (dc_is_hdmi_signal(stream->signal)) {
|
||||
|
||||
/* HEADER */
|
||||
|
||||
/* HB0 = Packet Type = 0x83 (Source Product
|
||||
* Descriptor InfoFrame)
|
||||
*/
|
||||
info_packet->hb0 = HDMI_INFOFRAME_TYPE_SPD;
|
||||
|
||||
/* HB1 = Version = 0x01 */
|
||||
info_packet->hb1 = 0x01;
|
||||
|
||||
/* HB2 = [Bits 7:5 = 0] [Bits 4:0 = Length = 0x08] */
|
||||
info_packet->hb2 = 0x08;
|
||||
|
||||
payload_size = 0x08;
|
||||
|
||||
} else if (dc_is_dp_signal(stream->signal)) {
|
||||
|
||||
/* HEADER */
|
||||
|
||||
/* HB0 = Secondary-data Packet ID = 0 - Only non-zero
|
||||
* when used to associate audio related info packets
|
||||
*/
|
||||
info_packet->hb0 = 0x00;
|
||||
|
||||
/* HB1 = Packet Type = 0x83 (Source Product
|
||||
* Descriptor InfoFrame)
|
||||
*/
|
||||
info_packet->hb1 = HDMI_INFOFRAME_TYPE_SPD;
|
||||
|
||||
/* HB2 = [Bits 7:0 = Least significant eight bits -
|
||||
* For INFOFRAME, the value must be 1Bh]
|
||||
*/
|
||||
info_packet->hb2 = 0x1B;
|
||||
|
||||
/* HB3 = [Bits 7:2 = INFOFRAME SDP Version Number = 0x1]
|
||||
* [Bits 1:0 = Most significant two bits = 0x00]
|
||||
*/
|
||||
info_packet->hb3 = 0x04;
|
||||
|
||||
payload_size = 0x1B;
|
||||
}
|
||||
|
||||
/* PB1 = 0x1A (24bit AMD IEEE OUI (0x00001A) - Byte 0) */
|
||||
info_packet->sb[1] = 0x1A;
|
||||
|
||||
/* PB2 = 0x00 (24bit AMD IEEE OUI (0x00001A) - Byte 1) */
|
||||
info_packet->sb[2] = 0x00;
|
||||
|
||||
/* PB3 = 0x00 (24bit AMD IEEE OUI (0x00001A) - Byte 2) */
|
||||
info_packet->sb[3] = 0x00;
|
||||
|
||||
/* PB4 = Reserved */
|
||||
info_packet->sb[4] = 0x00;
|
||||
|
||||
/* PB5 = Reserved */
|
||||
info_packet->sb[5] = 0x00;
|
||||
|
||||
/* PB6 = [Bits 7:3 = Reserved] */
|
||||
info_packet->sb[6] = 0x00;
|
||||
|
||||
if (stream->freesync_ctx.supported == true)
|
||||
/* PB6 = [Bit 0 = FreeSync Supported] */
|
||||
info_packet->sb[6] |= 0x01;
|
||||
|
||||
if (stream->freesync_ctx.enabled == true)
|
||||
/* PB6 = [Bit 1 = FreeSync Enabled] */
|
||||
info_packet->sb[6] |= 0x02;
|
||||
|
||||
if (stream->freesync_ctx.active == true)
|
||||
/* PB6 = [Bit 2 = FreeSync Active] */
|
||||
info_packet->sb[6] |= 0x04;
|
||||
|
||||
/* PB7 = FreeSync Minimum refresh rate (Hz) */
|
||||
info_packet->sb[7] = (unsigned char) (stream->freesync_ctx.
|
||||
min_refresh_in_micro_hz / 1000000);
|
||||
|
||||
/* PB8 = FreeSync Maximum refresh rate (Hz)
|
||||
*
|
||||
* Note: We do not use the maximum capable refresh rate
|
||||
* of the panel, because we should never go above the field
|
||||
* rate of the mode timing set.
|
||||
*/
|
||||
info_packet->sb[8] = (unsigned char) (stream->freesync_ctx.
|
||||
nominal_refresh_in_micro_hz / 1000000);
|
||||
|
||||
/* PB9 - PB27 = Reserved */
|
||||
for (idx = 9; idx <= 27; idx++)
|
||||
info_packet->sb[idx] = 0x00;
|
||||
|
||||
/* Calculate checksum */
|
||||
checksum += info_packet->hb0;
|
||||
checksum += info_packet->hb1;
|
||||
checksum += info_packet->hb2;
|
||||
checksum += info_packet->hb3;
|
||||
|
||||
for (idx = 1; idx <= payload_size; idx++)
|
||||
checksum += info_packet->sb[idx];
|
||||
|
||||
/* PB0 = Checksum (one byte complement) */
|
||||
info_packet->sb[0] = (unsigned char) (0x100 - checksum);
|
||||
|
||||
info_packet->valid = true;
|
||||
*info_packet = stream->vrr_infopacket;
|
||||
}
|
||||
|
||||
static void set_hdr_static_info_packet(
|
||||
|
@ -708,12 +708,6 @@ struct crtc_trigger_info {
|
||||
enum trigger_delay delay;
|
||||
};
|
||||
|
||||
enum vrr_state {
|
||||
VRR_STATE_OFF = 0,
|
||||
VRR_STATE_VARIABLE,
|
||||
VRR_STATE_FIXED,
|
||||
};
|
||||
|
||||
struct dc_crtc_timing_adjust {
|
||||
uint32_t v_total_min;
|
||||
uint32_t v_total_max;
|
||||
|
@ -45,19 +45,25 @@ struct dc_stream_status {
|
||||
struct dc_link *link;
|
||||
};
|
||||
|
||||
// TODO: References to this needs to be removed..
|
||||
struct freesync_context {
|
||||
bool dummy;
|
||||
};
|
||||
|
||||
struct dc_stream_state {
|
||||
struct dc_sink *sink;
|
||||
struct dc_crtc_timing timing;
|
||||
struct dc_crtc_timing_adjust timing_adjust;
|
||||
struct vrr_params vrr_params;
|
||||
struct dc_crtc_timing_adjust adjust;
|
||||
struct dc_info_packet vrr_infopacket;
|
||||
|
||||
struct rect src; /* composition area */
|
||||
struct rect dst; /* stream addressable area */
|
||||
|
||||
struct audio_info audio_info;
|
||||
|
||||
// TODO: References to this needs to be removed..
|
||||
struct freesync_context freesync_ctx;
|
||||
|
||||
struct audio_info audio_info;
|
||||
|
||||
struct dc_info_packet hdr_static_metadata;
|
||||
PHYSICAL_ADDRESS_LOC dmdata_address;
|
||||
bool use_dynamic_meta;
|
||||
@ -120,6 +126,8 @@ struct dc_stream_update {
|
||||
unsigned int *abm_level;
|
||||
|
||||
unsigned long long *periodic_fn_vsync_delta;
|
||||
struct dc_crtc_timing_adjust *adjust;
|
||||
struct dc_info_packet *vrr_infopacket;
|
||||
};
|
||||
|
||||
bool dc_is_stream_unchanged(
|
||||
@ -258,10 +266,8 @@ bool dc_stream_set_cursor_position(
|
||||
|
||||
|
||||
bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
||||
struct dc_stream_state **stream,
|
||||
int num_streams,
|
||||
int vmin,
|
||||
int vmax);
|
||||
struct dc_stream_state *stream,
|
||||
struct dc_crtc_timing_adjust *adjust);
|
||||
|
||||
bool dc_stream_get_crtc_position(struct dc *dc,
|
||||
struct dc_stream_state **stream,
|
||||
@ -288,13 +294,6 @@ void dc_stream_set_static_screen_events(struct dc *dc,
|
||||
void dc_stream_set_dither_option(struct dc_stream_state *stream,
|
||||
enum dc_dither_option option);
|
||||
|
||||
|
||||
bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
||||
struct dc_stream_state **stream,
|
||||
int num_streams,
|
||||
int vmin,
|
||||
int vmax);
|
||||
|
||||
bool dc_stream_get_crtc_position(struct dc *dc,
|
||||
struct dc_stream_state **stream,
|
||||
int num_streams,
|
||||
|
@ -513,13 +513,11 @@ struct audio_info {
|
||||
struct audio_mode modes[DC_MAX_AUDIO_DESC_COUNT];
|
||||
};
|
||||
|
||||
struct vrr_params {
|
||||
enum vrr_state state;
|
||||
uint32_t window_min;
|
||||
uint32_t window_max;
|
||||
uint32_t inserted_frame_duration_in_us;
|
||||
uint32_t frames_to_insert;
|
||||
uint32_t frame_counter;
|
||||
enum dc_infoframe_type {
|
||||
DC_HDMI_INFOFRAME_TYPE_VENDOR = 0x81,
|
||||
DC_HDMI_INFOFRAME_TYPE_AVI = 0x82,
|
||||
DC_HDMI_INFOFRAME_TYPE_SPD = 0x83,
|
||||
DC_HDMI_INFOFRAME_TYPE_AUDIO = 0x84,
|
||||
};
|
||||
|
||||
struct dc_info_packet {
|
||||
@ -539,16 +537,6 @@ struct dc_plane_flip_time {
|
||||
unsigned int prev_update_time_in_us;
|
||||
};
|
||||
|
||||
// Will combine with vrr_params at some point.
|
||||
struct freesync_context {
|
||||
bool supported;
|
||||
bool enabled;
|
||||
bool active;
|
||||
|
||||
unsigned int min_refresh_in_micro_hz;
|
||||
unsigned int nominal_refresh_in_micro_hz;
|
||||
};
|
||||
|
||||
struct psr_config {
|
||||
unsigned char psr_version;
|
||||
unsigned int psr_rfb_setup_time;
|
||||
|
@ -1286,6 +1286,8 @@ static enum dc_status dce110_enable_stream_timing(
|
||||
struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx.
|
||||
pipe_ctx[pipe_ctx->pipe_idx];
|
||||
struct tg_color black_color = {0};
|
||||
struct drr_params params = {0};
|
||||
unsigned int event_triggers = 0;
|
||||
|
||||
if (!pipe_ctx_old->stream) {
|
||||
|
||||
@ -1315,9 +1317,19 @@ static enum dc_status dce110_enable_stream_timing(
|
||||
&stream->timing,
|
||||
true);
|
||||
|
||||
pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
|
||||
pipe_ctx->stream_res.tg,
|
||||
0x182);
|
||||
params.vertical_total_min = stream->adjust.v_total_min;
|
||||
params.vertical_total_max = stream->adjust.v_total_max;
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_drr)
|
||||
pipe_ctx->stream_res.tg->funcs->set_drr(
|
||||
pipe_ctx->stream_res.tg, ¶ms);
|
||||
|
||||
// DRR should set trigger event to monitor surface update event
|
||||
if (stream->adjust.v_total_min != 0 &&
|
||||
stream->adjust.v_total_max != 0)
|
||||
event_triggers = 0x80;
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control)
|
||||
pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
|
||||
pipe_ctx->stream_res.tg, event_triggers);
|
||||
}
|
||||
|
||||
if (!pipe_ctx_old->stream) {
|
||||
@ -1328,8 +1340,6 @@ static enum dc_status dce110_enable_stream_timing(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return DC_OK;
|
||||
}
|
||||
|
||||
@ -1719,16 +1729,24 @@ static void set_drr(struct pipe_ctx **pipe_ctx,
|
||||
{
|
||||
int i = 0;
|
||||
struct drr_params params = {0};
|
||||
// DRR should set trigger event to monitor surface update event
|
||||
unsigned int event_triggers = 0x80;
|
||||
|
||||
params.vertical_total_max = vmax;
|
||||
params.vertical_total_min = vmin;
|
||||
|
||||
/* TODO: If multiple pipes are to be supported, you need
|
||||
* some GSL stuff
|
||||
* some GSL stuff. Static screen triggers may be programmed differently
|
||||
* as well.
|
||||
*/
|
||||
|
||||
for (i = 0; i < num_pipes; i++) {
|
||||
pipe_ctx[i]->stream_res.tg->funcs->set_drr(pipe_ctx[i]->stream_res.tg, ¶ms);
|
||||
pipe_ctx[i]->stream_res.tg->funcs->set_drr(
|
||||
pipe_ctx[i]->stream_res.tg, ¶ms);
|
||||
|
||||
if (vmax != 0 && vmin != 0)
|
||||
pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
|
||||
pipe_ctx[i]->stream_res.tg,
|
||||
event_triggers);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -631,6 +631,8 @@ static enum dc_status dcn10_enable_stream_timing(
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
enum dc_color_space color_space;
|
||||
struct tg_color black_color = {0};
|
||||
struct drr_params params = {0};
|
||||
unsigned int event_triggers = 0;
|
||||
|
||||
/* by upper caller loop, pipe0 is parent pipe and be called first.
|
||||
* back end is set up by for pipe0. Other children pipe share back end
|
||||
@ -698,6 +700,19 @@ static enum dc_status dcn10_enable_stream_timing(
|
||||
return DC_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
params.vertical_total_min = stream->adjust.v_total_min;
|
||||
params.vertical_total_max = stream->adjust.v_total_max;
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_drr)
|
||||
pipe_ctx->stream_res.tg->funcs->set_drr(
|
||||
pipe_ctx->stream_res.tg, ¶ms);
|
||||
|
||||
// DRR should set trigger event to monitor surface update event
|
||||
if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0)
|
||||
event_triggers = 0x80;
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control)
|
||||
pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
|
||||
pipe_ctx->stream_res.tg, event_triggers);
|
||||
|
||||
/* TODO program crtc source select for non-virtual signal*/
|
||||
/* TODO program FMT */
|
||||
/* TODO setup link_enc */
|
||||
@ -2399,15 +2414,23 @@ static void set_drr(struct pipe_ctx **pipe_ctx,
|
||||
{
|
||||
int i = 0;
|
||||
struct drr_params params = {0};
|
||||
// DRR should set trigger event to monitor surface update event
|
||||
unsigned int event_triggers = 0x80;
|
||||
|
||||
params.vertical_total_max = vmax;
|
||||
params.vertical_total_min = vmin;
|
||||
|
||||
/* TODO: If multiple pipes are to be supported, you need
|
||||
* some GSL stuff
|
||||
* some GSL stuff. Static screen triggers may be programmed differently
|
||||
* as well.
|
||||
*/
|
||||
for (i = 0; i < num_pipes; i++) {
|
||||
pipe_ctx[i]->stream_res.tg->funcs->set_drr(pipe_ctx[i]->stream_res.tg, ¶ms);
|
||||
pipe_ctx[i]->stream_res.tg->funcs->set_drr(
|
||||
pipe_ctx[i]->stream_res.tg, ¶ms);
|
||||
if (vmax != 0 && vmin != 0)
|
||||
pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
|
||||
pipe_ctx[i]->stream_res.tg,
|
||||
event_triggers);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,18 +90,6 @@ union hdmi_info_packet {
|
||||
struct info_packet_raw_data packet_raw_data;
|
||||
};
|
||||
|
||||
struct info_packet {
|
||||
enum info_frame_flag flags;
|
||||
union hdmi_info_packet info_packet_hdmi;
|
||||
};
|
||||
|
||||
struct info_frame {
|
||||
struct info_packet avi_info_packet;
|
||||
struct info_packet gamut_packet;
|
||||
struct info_packet vendor_info_packet;
|
||||
struct info_packet spd_info_packet;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif /* __DAL_SET_MODE_TYPES_H__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -56,96 +56,72 @@
|
||||
|
||||
#include "dm_services.h"
|
||||
|
||||
struct mod_freesync *mod_freesync_create(struct dc *dc);
|
||||
void mod_freesync_destroy(struct mod_freesync *mod_freesync);
|
||||
|
||||
// Access structures
|
||||
struct mod_freesync {
|
||||
int dummy;
|
||||
};
|
||||
|
||||
enum mod_freesync_state {
|
||||
FREESYNC_STATE_NONE,
|
||||
FREESYNC_STATE_FULLSCREEN,
|
||||
FREESYNC_STATE_STATIC_SCREEN,
|
||||
FREESYNC_STATE_VIDEO
|
||||
};
|
||||
|
||||
enum mod_freesync_user_enable_mask {
|
||||
FREESYNC_USER_ENABLE_STATIC = 0x1,
|
||||
FREESYNC_USER_ENABLE_VIDEO = 0x2,
|
||||
FREESYNC_USER_ENABLE_GAMING = 0x4
|
||||
};
|
||||
|
||||
struct mod_freesync_user_enable {
|
||||
bool enable_for_static;
|
||||
bool enable_for_video;
|
||||
bool enable_for_gaming;
|
||||
};
|
||||
|
||||
// TODO: References to this should be removed
|
||||
struct mod_freesync_caps {
|
||||
bool supported;
|
||||
unsigned int min_refresh_in_micro_hz;
|
||||
unsigned int max_refresh_in_micro_hz;
|
||||
|
||||
bool btr_supported;
|
||||
};
|
||||
|
||||
struct mod_freesync_params {
|
||||
enum mod_freesync_state state;
|
||||
bool enable;
|
||||
unsigned int update_duration_in_ns;
|
||||
bool windowed_fullscreen;
|
||||
enum mod_vrr_state {
|
||||
VRR_STATE_UNSUPPORTED = 0,
|
||||
VRR_STATE_DISABLED,
|
||||
VRR_STATE_INACTIVE,
|
||||
VRR_STATE_ACTIVE_VARIABLE,
|
||||
VRR_STATE_ACTIVE_FIXED
|
||||
};
|
||||
|
||||
/*
|
||||
* Add stream to be tracked by module
|
||||
*/
|
||||
bool mod_freesync_add_stream(struct mod_freesync *mod_freesync,
|
||||
struct dc_stream_state *stream, struct mod_freesync_caps *caps);
|
||||
struct mod_freesync_config {
|
||||
enum mod_vrr_state state;
|
||||
bool ramping;
|
||||
bool btr;
|
||||
unsigned int min_refresh_in_uhz;
|
||||
unsigned int max_refresh_in_uhz;
|
||||
};
|
||||
|
||||
/*
|
||||
* Remove stream to be tracked by module
|
||||
*/
|
||||
bool mod_freesync_remove_stream(struct mod_freesync *mod_freesync,
|
||||
struct dc_stream_state *stream);
|
||||
struct mod_vrr_params_btr {
|
||||
bool btr_enabled;
|
||||
bool btr_active;
|
||||
uint32_t mid_point_in_us;
|
||||
uint32_t inserted_duration_in_us;
|
||||
uint32_t frames_to_insert;
|
||||
uint32_t frame_counter;
|
||||
};
|
||||
|
||||
/*
|
||||
* Update the freesync state flags for each display and program
|
||||
* freesync accordingly
|
||||
*/
|
||||
void mod_freesync_update_state(struct mod_freesync *mod_freesync,
|
||||
struct dc_stream_state **streams, int num_streams,
|
||||
struct mod_freesync_params *freesync_params);
|
||||
struct mod_vrr_params_fixed_refresh {
|
||||
bool fixed_active;
|
||||
bool ramping_active;
|
||||
bool ramping_done;
|
||||
uint32_t target_refresh_in_uhz;
|
||||
uint32_t frame_counter;
|
||||
};
|
||||
|
||||
bool mod_freesync_get_state(struct mod_freesync *mod_freesync,
|
||||
struct dc_stream_state *stream,
|
||||
struct mod_freesync_params *freesync_params);
|
||||
struct mod_vrr_params {
|
||||
bool supported;
|
||||
enum mod_vrr_state state;
|
||||
|
||||
bool mod_freesync_set_user_enable(struct mod_freesync *mod_freesync,
|
||||
struct dc_stream_state **streams, int num_streams,
|
||||
struct mod_freesync_user_enable *user_enable);
|
||||
uint32_t min_refresh_in_uhz;
|
||||
uint32_t max_duration_in_us;
|
||||
uint32_t max_refresh_in_uhz;
|
||||
uint32_t min_duration_in_us;
|
||||
|
||||
bool mod_freesync_get_user_enable(struct mod_freesync *mod_freesync,
|
||||
struct dc_stream_state *stream,
|
||||
struct mod_freesync_user_enable *user_enable);
|
||||
struct dc_crtc_timing_adjust adjust;
|
||||
|
||||
bool mod_freesync_get_static_ramp_active(struct mod_freesync *mod_freesync,
|
||||
struct dc_stream_state *stream,
|
||||
bool *is_ramp_active);
|
||||
struct mod_vrr_params_fixed_refresh fixed;
|
||||
|
||||
bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync,
|
||||
struct dc_stream_state *streams,
|
||||
unsigned int min_refresh,
|
||||
unsigned int max_refresh,
|
||||
struct mod_freesync_caps *caps);
|
||||
struct mod_vrr_params_btr btr;
|
||||
};
|
||||
|
||||
bool mod_freesync_get_min_max(struct mod_freesync *mod_freesync,
|
||||
struct dc_stream_state *stream,
|
||||
unsigned int *min_refresh,
|
||||
unsigned int *max_refresh);
|
||||
struct mod_freesync *mod_freesync_create(struct dc *dc);
|
||||
void mod_freesync_destroy(struct mod_freesync *mod_freesync);
|
||||
|
||||
bool mod_freesync_get_vmin_vmax(struct mod_freesync *mod_freesync,
|
||||
struct dc_stream_state *stream,
|
||||
const struct dc_stream_state *stream,
|
||||
unsigned int *vmin,
|
||||
unsigned int *vmax);
|
||||
|
||||
@ -154,18 +130,8 @@ bool mod_freesync_get_v_position(struct mod_freesync *mod_freesync,
|
||||
unsigned int *nom_v_pos,
|
||||
unsigned int *v_pos);
|
||||
|
||||
void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync,
|
||||
struct dc_stream_state **streams, int num_streams);
|
||||
|
||||
void mod_freesync_notify_mode_change(struct mod_freesync *mod_freesync,
|
||||
struct dc_stream_state **streams, int num_streams);
|
||||
|
||||
void mod_freesync_pre_update_plane_addresses(struct mod_freesync *mod_freesync,
|
||||
struct dc_stream_state **streams, int num_streams,
|
||||
unsigned int curr_time_stamp);
|
||||
|
||||
void mod_freesync_get_settings(struct mod_freesync *mod_freesync,
|
||||
struct dc_stream_state **streams, int num_streams,
|
||||
const struct mod_vrr_params *vrr,
|
||||
unsigned int *v_total_min, unsigned int *v_total_max,
|
||||
unsigned int *event_triggers,
|
||||
unsigned int *window_min, unsigned int *window_max,
|
||||
@ -173,4 +139,24 @@ void mod_freesync_get_settings(struct mod_freesync *mod_freesync,
|
||||
unsigned int *inserted_frames,
|
||||
unsigned int *inserted_duration_in_us);
|
||||
|
||||
void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync,
|
||||
const struct dc_stream_state *stream,
|
||||
const struct mod_vrr_params *vrr,
|
||||
struct dc_info_packet *infopacket);
|
||||
|
||||
void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,
|
||||
const struct dc_stream_state *stream,
|
||||
struct mod_freesync_config *in_config,
|
||||
struct mod_vrr_params *in_out_vrr);
|
||||
|
||||
void mod_freesync_handle_preflip(struct mod_freesync *mod_freesync,
|
||||
const struct dc_plane_state *plane,
|
||||
const struct dc_stream_state *stream,
|
||||
unsigned int curr_time_stamp_in_us,
|
||||
struct mod_vrr_params *in_out_vrr);
|
||||
|
||||
void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync,
|
||||
const struct dc_stream_state *stream,
|
||||
struct mod_vrr_params *in_out_vrr);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user