Merge branch 'drm-next-4.15-dc' of git://people.freedesktop.org/~agd5f/linux into drm-next

Last batch of new stuff for DC. Highlights:
- Fix some memory leaks
- S3 fixes
- Hotplug fixes
- Fix some CX multi-display issues
- MST fixes
- DML updates from the hw team
- Various code cleanups
- Misc bug fixes

* 'drm-next-4.15-dc' of git://people.freedesktop.org/~agd5f/linux: (155 commits)
  drm/amd/display:: Fix NULL pointer in Raven hotplug
  drm/amd/display: Fix memoryleak during S3 resume.
  drm/amd/display: add hardware_planes_only to list of affected planes
  drm/amd/display: Fix brace style
  drm/amd/display: Remove needless cast in amdgpu_dm_connector_init()
  drm/amd/display: Fix brace style in amdgpu_dm_connector_ddc_get_modes()
  drm/amd/display: Tidy up dm_drm_plane_reset()
  drm/amd/display: Fix indentation in create_eml_sink()
  drm/amd/display: Replace block with strncpy() in fill_audio_info()
  drm/amd/display: Fix brace style in amdgpu_dm_initialize_drm_device()
  drm/amd/display: Simplify handle_hpd_rx_irq()
  drm/amd/display: Fix brace style in dm_handle_hpd_rx_irq()
  drm/amd/display: Fix brace style in amdgpu_dm_update_connector_after_detect()
  drm/amd/display: Fix indentation in dm_resume()
  drm/amd/display: Fix indentation in dm_suspend()
  drm/amd/display: Simplify dm_late_init()
  amdgpu/dc: inline dml_round_to_multiple
  amdgpu/dc: drop dml_util_is_420
  drm/amd/display: Add bunch of missing license headers in DML
  amdgpu/dc: inline a bunch of the dml wrappers.
  ...
This commit is contained in:
Dave Airlie 2017-10-23 11:17:54 +10:00
commit af91113360
88 changed files with 13954 additions and 6128 deletions

View File

@ -17,6 +17,16 @@ config DRM_AMD_DC_PRE_VEGA
by default. This includes Polaris, Carrizo, Tonga, Bonaire,
and Hawaii.
config DRM_AMD_DC_FBC
bool "AMD FBC - Enable Frame Buffer Compression"
depends on DRM_AMD_DC
help
Choose this option if you want to use frame buffer compression
support.
This is a power optimisation feature, check its availability
on your hardware before enabling this option.
config DRM_AMD_DC_DCN1_0
bool "DCN 1.0 Raven family"
depends on DRM_AMD_DC && X86

View File

@ -538,9 +538,8 @@ static int detect_mst_link_for_all_connectors(struct drm_device *dev)
static int dm_late_init(void *handle)
{
struct drm_device *dev = ((struct amdgpu_device *)handle)->ddev;
int r = detect_mst_link_for_all_connectors(dev);
return r;
return detect_mst_link_for_all_connectors(dev);
}
static void s3_handle_mst(struct drm_device *dev, bool suspend)
@ -599,10 +598,7 @@ static int dm_suspend(void *handle)
WARN_ON(adev->dm.cached_state);
adev->dm.cached_state = drm_atomic_helper_suspend(adev->ddev);
dc_set_power_state(
dm->dc,
DC_ACPI_CM_POWER_STATE_D3
);
dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3);
return ret;
}
@ -632,10 +628,7 @@ static int dm_resume(void *handle)
struct amdgpu_display_manager *dm = &adev->dm;
/* power on hardware */
dc_set_power_state(
dm->dc,
DC_ACPI_CM_POWER_STATE_D0
);
dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
return 0;
}
@ -648,6 +641,11 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev)
struct drm_connector *connector;
struct drm_crtc *crtc;
struct drm_crtc_state *new_crtc_state;
struct dm_crtc_state *dm_crtc_state;
struct drm_plane *plane;
struct drm_plane_state *plane_state;
struct dm_plane_state *dm_plane_state;
struct dm_atomic_state *cached_state;
int ret = 0;
int i;
@ -686,6 +684,34 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev)
for_each_new_crtc_in_state(adev->dm.cached_state, crtc, new_crtc_state, i)
new_crtc_state->active_changed = true;
cached_state = to_dm_atomic_state(adev->dm.cached_state);
/*
* During suspend, the cached state is saved before all streams are
* disabled. Refresh cached state to match actual current state before
* restoring it.
*/
WARN_ON(kref_read(&cached_state->context->refcount) > 1);
dc_release_state(cached_state->context);
for_each_new_crtc_in_state(adev->dm.cached_state, crtc, new_crtc_state, i) {
dm_crtc_state = to_dm_crtc_state(new_crtc_state);
if (dm_crtc_state->stream) {
WARN_ON(kref_read(&dm_crtc_state->stream->refcount) > 1);
dc_stream_release(dm_crtc_state->stream);
dm_crtc_state->stream = NULL;
}
}
for_each_new_plane_in_state(adev->dm.cached_state, plane, plane_state, i) {
dm_plane_state = to_dm_plane_state(plane_state);
if (dm_plane_state->dc_state) {
WARN_ON(kref_read(&dm_plane_state->dc_state->refcount) > 1);
dc_plane_state_release(dm_plane_state->dc_state);
dm_plane_state->dc_state = NULL;
}
}
ret = drm_atomic_helper_resume(ddev, adev->dm.cached_state);
drm_atomic_state_put(adev->dm.cached_state);
@ -860,9 +886,9 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
connector);
aconnector->dc_sink = sink;
if (sink->dc_edid.length == 0)
if (sink->dc_edid.length == 0) {
aconnector->edid = NULL;
else {
} else {
aconnector->edid =
(struct edid *) sink->dc_edid.raw_edid;
@ -980,8 +1006,9 @@ static void dm_handle_hpd_rx_irq(struct amdgpu_dm_connector *aconnector)
dpcd_bytes_to_read);
new_irq_handled = false;
} else
} else {
break;
}
}
if (process_count == max_process_count)
@ -993,20 +1020,20 @@ static void handle_hpd_rx_irq(void *param)
struct amdgpu_dm_connector *aconnector = (struct amdgpu_dm_connector *)param;
struct drm_connector *connector = &aconnector->base;
struct drm_device *dev = connector->dev;
const struct dc_link *dc_link = aconnector->dc_link;
struct dc_link *dc_link = aconnector->dc_link;
bool is_mst_root_connector = aconnector->mst_mgr.mst_state;
/* TODO:Temporary add mutex to protect hpd interrupt not have a gpio
* conflict, after implement i2c helper, this mutex should be
* retired.
*/
if (aconnector->dc_link->type != dc_connection_mst_branch)
if (dc_link->type != dc_connection_mst_branch)
mutex_lock(&aconnector->hpd_lock);
if (dc_link_handle_hpd_rx_irq(aconnector->dc_link, NULL) &&
if (dc_link_handle_hpd_rx_irq(dc_link, NULL) &&
!is_mst_root_connector) {
/* Downstream Port status changed. */
if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPDRX)) {
if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) {
amdgpu_dm_update_connector_after_detect(aconnector);
@ -1018,10 +1045,10 @@ static void handle_hpd_rx_irq(void *param)
}
}
if ((dc_link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) ||
(dc_link->type == dc_connection_mst_branch))
(dc_link->type == dc_connection_mst_branch))
dm_handle_hpd_rx_irq(aconnector);
if (aconnector->dc_link->type != dc_connection_mst_branch)
if (dc_link->type != dc_connection_mst_branch)
mutex_unlock(&aconnector->hpd_lock);
}
@ -1381,9 +1408,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
goto fail_free_planes;
aencoder = kzalloc(sizeof(*aencoder), GFP_KERNEL);
if (!aencoder) {
if (!aencoder)
goto fail_free_connector;
}
if (amdgpu_dm_encoder_init(dm->ddev, aencoder, i)) {
DRM_ERROR("KMS: Failed to initialize encoder\n");
@ -1754,7 +1780,9 @@ static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
int r = amdgpu_bo_reserve(rbo, false);
if (unlikely(r)) {
DRM_ERROR("Unable to reserve buffer\n");
// Don't show error msg. when return -ERESTARTSYS
if (r != -ERESTARTSYS)
DRM_ERROR("Unable to reserve buffer: %d\n", r);
return r;
}
@ -2206,11 +2234,9 @@ static void fill_audio_info(struct audio_info *audio_info,
cea_revision = drm_connector->display_info.cea_rev;
while (i < AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS &&
edid_caps->display_name[i]) {
audio_info->display_name[i] = edid_caps->display_name[i];
i++;
}
strncpy(audio_info->display_name,
edid_caps->display_name,
AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS - 1);
if (cea_revision >= 3) {
audio_info->mode_count = edid_caps->audio_mode_count;
@ -2318,8 +2344,16 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
drm_connector = &aconnector->base;
if (!aconnector->dc_sink)
if (!aconnector->dc_sink) {
/*
* Exclude MST from creating fake_sink
* TODO: need to enable MST into fake_sink feature
*/
if (aconnector->mst_port)
goto stream_create_fail;
create_fake_sink(aconnector);
}
stream = dc_create_stream_for_sink(aconnector->dc_sink);
@ -2453,7 +2487,8 @@ amdgpu_dm_connector_detect(struct drm_connector *connector, bool force)
* 2. This interface *is called* in context of user-mode ioctl. Which
* makes it a bad place for *any* MST-related activit. */
if (aconnector->base.force == DRM_FORCE_UNSPECIFIED)
if (aconnector->base.force == DRM_FORCE_UNSPECIFIED &&
!aconnector->fake_enable)
connected = (aconnector->dc_sink != NULL);
else
connected = (aconnector->base.force == DRM_FORCE_ON);
@ -2681,8 +2716,7 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
(edid->extensions + 1) * EDID_LENGTH,
&init_params);
if (aconnector->base.force
== DRM_FORCE_ON)
if (aconnector->base.force == DRM_FORCE_ON)
aconnector->dc_sink = aconnector->dc_link->local_sink ?
aconnector->dc_link->local_sink :
aconnector->dc_em_sink;
@ -2746,7 +2780,7 @@ int amdgpu_dm_connector_mode_valid(struct drm_connector *connector,
stream->src.height = mode->vdisplay;
stream->dst = stream->src;
if (dc_validate_stream(adev->dm.dc, stream))
if (dc_validate_stream(adev->dm.dc, stream) == DC_OK)
result = MODE_OK;
dc_stream_release(stream);
@ -2791,7 +2825,7 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc,
if (!dm_crtc_state->stream)
return 0;
if (dc_validate_stream(dc, dm_crtc_state->stream))
if (dc_validate_stream(dc, dm_crtc_state->stream) == DC_OK)
return 0;
return ret;
@ -2835,13 +2869,13 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
plane->funcs->atomic_destroy_state(plane, plane->state);
amdgpu_state = kzalloc(sizeof(*amdgpu_state), GFP_KERNEL);
WARN_ON(amdgpu_state == NULL);
if (amdgpu_state) {
plane->state = &amdgpu_state->base;
plane->state->plane = plane;
plane->state->rotation = DRM_MODE_ROTATE_0;
} else
WARN_ON(1);
}
}
static struct drm_plane_state *
@ -2986,7 +3020,7 @@ static int dm_plane_atomic_check(struct drm_plane *plane,
if (!dm_plane_state->dc_state)
return 0;
if (dc_validate_plane(dc, dm_plane_state->dc_state))
if (dc_validate_plane(dc, dm_plane_state->dc_state) == DC_OK)
return 0;
return -EINVAL;
@ -3272,8 +3306,9 @@ static void amdgpu_dm_connector_ddc_get_modes(struct drm_connector *connector,
drm_edid_to_eld(connector, edid);
amdgpu_dm_get_native_mode(connector);
} else
} else {
amdgpu_dm_connector->num_modes = 0;
}
}
static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
@ -3421,7 +3456,8 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
struct dc *dc = dm->dc;
struct dc_link *link = dc_get_link_at_index(dc, link_index);
struct amdgpu_i2c_adapter *i2c;
((struct dc_link *)link)->priv = aconnector;
link->priv = aconnector;
DRM_DEBUG_DRIVER("%s()\n", __func__);
@ -3661,10 +3697,10 @@ static void handle_cursor_update(struct drm_plane *plane,
return;
DRM_DEBUG_DRIVER("%s: crtc_id=%d with size %d to %d\n",
__func__,
amdgpu_crtc->crtc_id,
plane->state->crtc_w,
plane->state->crtc_h);
__func__,
amdgpu_crtc->crtc_id,
plane->state->crtc_w,
plane->state->crtc_h);
ret = get_cursor_position(plane, crtc, &position);
if (ret)
@ -3691,14 +3727,15 @@ static void handle_cursor_update(struct drm_plane *plane,
attributes.pitch = attributes.width;
if (!dc_stream_set_cursor_attributes(crtc_state->stream,
&attributes))
DRM_ERROR("DC failed to set cursor attributes\n");
if (crtc_state->stream) {
if (!dc_stream_set_cursor_attributes(crtc_state->stream,
&attributes))
DRM_ERROR("DC failed to set cursor attributes\n");
if (crtc_state->stream)
if (!dc_stream_set_cursor_position(crtc_state->stream,
&position))
DRM_ERROR("DC failed to set cursor position\n");
}
}
static void prepare_flip_isr(struct amdgpu_crtc *acrtc)
@ -3726,7 +3763,8 @@ static void prepare_flip_isr(struct amdgpu_crtc *acrtc)
*/
static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
uint32_t target)
uint32_t target,
struct dc_state *state)
{
unsigned long flags;
uint32_t target_vblank;
@ -3797,7 +3835,13 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
surface_updates->flip_addr = &addr;
dc_update_planes_and_stream(adev->dm.dc, surface_updates, 1, acrtc_state->stream, NULL);
dc_commit_updates_for_stream(adev->dm.dc,
surface_updates,
1,
acrtc_state->stream,
NULL,
&surface_updates->surface,
state);
DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x \n",
__func__,
@ -3823,6 +3867,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
struct drm_crtc_state *new_pcrtc_state =
drm_atomic_get_new_crtc_state(state, pcrtc);
struct dm_crtc_state *acrtc_state = to_dm_crtc_state(new_pcrtc_state);
struct dm_atomic_state *dm_state = to_dm_atomic_state(state);
int planes_count = 0;
unsigned long flags;
@ -3880,7 +3925,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
amdgpu_dm_do_flip(
crtc,
fb,
drm_crtc_vblank_count(crtc) + *wait_for_vblank);
drm_crtc_vblank_count(crtc) + *wait_for_vblank,
dm_state->context);
}
}
@ -3900,7 +3946,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
if (false == dc_commit_planes_to_stream(dm->dc,
plane_states_constructed,
planes_count,
dc_stream_attach))
dc_stream_attach,
dm_state->context))
dm_error("%s: Failed to attach plane!\n", __func__);
} else {
/*TODO BUG Here should go disable planes on CRTC. */
@ -3931,6 +3978,8 @@ static int amdgpu_dm_atomic_commit(struct drm_device *dev,
if (drm_atomic_crtc_needs_modeset(new_crtc_state) && dm_old_crtc_state->stream)
manage_dm_interrupts(adev, acrtc, false);
}
/* Add check here for SoC's that support hardware cursor plane, to
* unset legacy_cursor_update */
return drm_atomic_helper_commit(dev, state, nonblock);
@ -4120,7 +4169,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
dm->dc,
status->plane_states,
status->plane_count,
dm_new_crtc_state->stream))
dm_new_crtc_state->stream,
dm_state->context))
dm_error("%s: Failed to update stream scaling!\n", __func__);
}
@ -4339,7 +4389,8 @@ static int dm_update_crtcs_state(struct dc *dc,
aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
/* TODO This hack should go away */
if (aconnector) {
if (aconnector && enable) {
// Make sure fake sink is created in plug-in scenario
new_con_state = drm_atomic_get_connector_state(state,
&aconnector->base);
@ -4368,12 +4419,13 @@ static int dm_update_crtcs_state(struct dc *dc,
}
}
if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->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;
DRM_DEBUG_DRIVER("Mode change not required, setting mode_changed to %d",
new_crtc_state->mode_changed);
new_crtc_state->mode_changed);
}
@ -4402,10 +4454,10 @@ static int dm_update_crtcs_state(struct dc *dc,
crtc->base.id);
/* i.e. reset mode */
if (!dc_remove_stream_from_ctx(
if (dc_remove_stream_from_ctx(
dc,
dm_state->context,
dm_old_crtc_state->stream)) {
dm_old_crtc_state->stream) != DC_OK) {
ret = -EINVAL;
goto fail;
}
@ -4416,6 +4468,13 @@ static int dm_update_crtcs_state(struct dc *dc,
*lock_and_validation_needed = true;
} else {/* Add stream for any updated/enabled CRTC */
/*
* Quick fix to prevent NULL pointer on new_stream when
* added MST connectors not found in existing crtc_state in the chained mode
* TODO: need to dig out the root cause of that
*/
if (!aconnector || (!aconnector->dc_sink && aconnector->mst_port))
goto next_crtc;
if (modereset_required(new_crtc_state))
goto next_crtc;
@ -4431,10 +4490,10 @@ static int dm_update_crtcs_state(struct dc *dc,
DRM_DEBUG_DRIVER("Enabling DRM crtc: %d\n",
crtc->base.id);
if (!dc_add_stream_to_ctx(
if (dc_add_stream_to_ctx(
dc,
dm_state->context,
dm_new_crtc_state->stream)) {
dm_new_crtc_state->stream) != DC_OK) {
ret = -EINVAL;
goto fail;
}
@ -4586,7 +4645,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
struct drm_connector *connector;
struct drm_connector_state *old_con_state, *new_con_state;
struct drm_crtc *crtc;
struct drm_crtc_state *new_crtc_state;
struct drm_crtc_state *old_crtc_state, *new_crtc_state;
/*
* This bool will be set for true for any modeset/reset
@ -4595,18 +4654,34 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
bool lock_and_validation_needed = false;
ret = drm_atomic_helper_check_modeset(dev, state);
if (ret) {
DRM_ERROR("Atomic state validation failed with error :%d !\n", ret);
return ret;
}
/*
* Hack: Commit needs planes right now, specifically for gamma
* TODO rework commit to check CRTC for gamma change
* legacy_cursor_update should be made false for SoC's having
* a dedicated hardware plane for cursor in amdgpu_dm_atomic_commit(),
* otherwise for software cursor plane,
* we should not add it to list of affected planes.
*/
for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
if (new_crtc_state->color_mgmt_changed) {
if (state->legacy_cursor_update) {
for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
if (new_crtc_state->color_mgmt_changed) {
ret = drm_atomic_add_affected_planes(state, crtc);
if (ret)
goto fail;
}
}
} else {
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
if (!new_crtc_state->enable)
continue;
ret = drm_atomic_add_affected_connectors(state, crtc);
if (ret)
return ret;
ret = drm_atomic_add_affected_planes(state, crtc);
if (ret)
goto fail;
@ -4684,7 +4759,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
if (ret)
goto fail;
if (!dc_validate_global_state(dc, dm_state->context)) {
if (dc_validate_global_state(dc, dm_state->context) != DC_OK) {
ret = -EINVAL;
goto fail;
}

View File

@ -208,24 +208,21 @@ static void remove_timer_handler(struct amdgpu_device *adev,
DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
}
if (handler_in == NULL) {
/* Remove ALL handlers. */
/* Remove ALL handlers. */
if (handler_in == NULL)
continue;
}
if (handler_in == handler_temp) {
/* Remove a SPECIFIC handler.
* Found our handler - we can stop here. */
/* Remove a SPECIFIC handler.
* Found our handler - we can stop here. */
if (handler_in == handler_temp)
break;
}
}
DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
if (handler_in != NULL && handler_removed == false) {
if (handler_in != NULL && handler_removed == false)
DRM_ERROR("DM_IRQ: handler: %p is not in the list!\n",
handler_in);
}
}
static bool
@ -435,7 +432,7 @@ int amdgpu_dm_irq_suspend(struct amdgpu_device *adev)
* Disable HW interrupt for HPD and HPDRX only since FLIP and VBLANK
* will be disabled from manage_dm_interrupts on disable CRTC.
*/
for (src = DC_IRQ_SOURCE_HPD1; src < DC_IRQ_SOURCE_HPD6RX; src++) {
for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6RX; src++) {
hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
@ -462,7 +459,7 @@ int amdgpu_dm_irq_resume_early(struct amdgpu_device *adev)
DRM_DEBUG_KMS("DM_IRQ: early resume\n");
/* re-enable short pulse interrupts HW interrupt */
for (src = DC_IRQ_SOURCE_HPD1RX; src < DC_IRQ_SOURCE_HPD6RX + 1; src++) {
for (src = DC_IRQ_SOURCE_HPD1RX; src <= DC_IRQ_SOURCE_HPD6RX; src++) {
hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
@ -488,7 +485,7 @@ int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev)
* Renable HW interrupt for HPD and only since FLIP and VBLANK
* will be enabled from manage_dm_interrupts on enable CRTC.
*/
for (src = DC_IRQ_SOURCE_HPD1; src < DC_IRQ_SOURCE_HPD6; src++) {
for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6; src++) {
hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))

View File

@ -174,14 +174,60 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {
.atomic_get_property = amdgpu_dm_connector_atomic_get_property
};
static int dm_connector_update_modes(struct drm_connector *connector,
struct edid *edid)
{
int ret;
ret = drm_add_edid_modes(connector, edid);
drm_edid_to_eld(connector, edid);
return ret;
}
static int dm_dp_mst_get_modes(struct drm_connector *connector)
{
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
int ret = 0;
ret = drm_add_edid_modes(&aconnector->base, aconnector->edid);
if (!aconnector)
return dm_connector_update_modes(connector, NULL);
drm_edid_to_eld(&aconnector->base, aconnector->edid);
if (!aconnector->edid) {
struct edid *edid;
struct dc_sink *dc_sink;
struct dc_sink_init_data init_params = {
.link = aconnector->dc_link,
.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
if (!edid) {
drm_mode_connector_update_edid_property(
&aconnector->base,
NULL);
return ret;
}
aconnector->edid = edid;
dc_sink = dc_link_add_remote_sink(
aconnector->dc_link,
(uint8_t *)edid,
(edid->extensions + 1) * EDID_LENGTH,
&init_params);
dc_sink->priv = aconnector;
aconnector->dc_sink = dc_sink;
if (aconnector->dc_sink)
amdgpu_dm_add_sink_to_freesync_module(
connector, edid);
drm_mode_connector_update_edid_property(
&aconnector->base, edid);
}
ret = dm_connector_update_modes(connector, aconnector->edid);
return ret;
}
@ -241,9 +287,10 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
struct amdgpu_device *adev = dev->dev_private;
struct amdgpu_dm_connector *aconnector;
struct drm_connector *connector;
struct drm_connector_list_iter conn_iter;
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(connector, &conn_iter) {
aconnector = to_amdgpu_dm_connector(connector);
if (aconnector->mst_port == master
&& !aconnector->port) {
@ -253,11 +300,11 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
aconnector->port = port;
drm_mode_connector_set_path_property(connector, pathprop);
drm_modeset_unlock(&dev->mode_config.connection_mutex);
drm_connector_list_iter_end(&conn_iter);
return &aconnector->base;
}
}
drm_modeset_unlock(&dev->mode_config.connection_mutex);
drm_connector_list_iter_end(&conn_iter);
aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
if (!aconnector)
@ -343,92 +390,20 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
{
struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr);
struct drm_device *dev = master->base.dev;
struct amdgpu_device *adev = dev->dev_private;
struct drm_connector *connector;
struct amdgpu_dm_connector *aconnector;
struct edid *edid;
struct dc_sink *dc_sink;
drm_modeset_lock_all(dev);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
aconnector = to_amdgpu_dm_connector(connector);
if (aconnector->port &&
aconnector->port->pdt != DP_PEER_DEVICE_NONE &&
aconnector->port->pdt != DP_PEER_DEVICE_MST_BRANCHING &&
!aconnector->dc_sink) {
/*
* This is plug in case, where port has been created but
* sink hasn't been created yet
*/
if (!aconnector->edid) {
struct dc_sink_init_data init_params = {
.link = aconnector->dc_link,
.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST};
edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
if (!edid) {
drm_mode_connector_update_edid_property(
&aconnector->base,
NULL);
continue;
}
aconnector->edid = edid;
dc_sink = dc_link_add_remote_sink(
aconnector->dc_link,
(uint8_t *)edid,
(edid->extensions + 1) * EDID_LENGTH,
&init_params);
dc_sink->priv = aconnector;
aconnector->dc_sink = dc_sink;
if (aconnector->dc_sink)
amdgpu_dm_add_sink_to_freesync_module(
connector,
edid);
dm_restore_drm_connector_state(connector->dev, connector);
} else
edid = aconnector->edid;
DRM_DEBUG_KMS("edid retrieved %p\n", edid);
drm_mode_connector_update_edid_property(
&aconnector->base,
aconnector->edid);
}
}
drm_modeset_unlock_all(dev);
schedule_work(&adev->dm.mst_hotplug_work);
drm_kms_helper_hotplug_event(dev);
}
static void dm_dp_mst_register_connector(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct amdgpu_device *adev = dev->dev_private;
int i;
drm_modeset_lock_all(dev);
if (adev->mode_info.rfbdev) {
/*Do not add if already registered in past*/
for (i = 0; i < adev->mode_info.rfbdev->helper.connector_count; i++) {
if (adev->mode_info.rfbdev->helper.connector_info[i]->connector
== connector) {
drm_modeset_unlock_all(dev);
return;
}
}
if (adev->mode_info.rfbdev)
drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector);
}
else
DRM_ERROR("adev->mode_info.rfbdev is NULL\n");
drm_modeset_unlock_all(dev);
drm_connector_register(connector);
}

View File

@ -35,6 +35,12 @@
#include "amdgpu_dm_irq.h"
#include "amdgpu_pm.h"
unsigned long long dm_get_timestamp(struct dc_context *ctx)
{
/* TODO: return actual timestamp */
return 0;
}
bool dm_write_persistent_data(struct dc_context *ctx,
const struct dc_sink *sink,
const char *module_name,

View File

@ -80,8 +80,6 @@ static bool construct(struct dc_context *ctx, struct dal_logger *logger,
logger->buffer_read_offset = 0;
logger->buffer_write_offset = 0;
logger->write_wrap_count = 0;
logger->read_wrap_count = 0;
logger->open_count = 0;
logger->flags.bits.ENABLE_CONSOLE = 1;
@ -162,23 +160,24 @@ static void log_to_debug_console(struct log_entry *entry)
}
/* Print everything unread existing in log_buffer to debug console*/
static void flush_to_debug_console(struct dal_logger *logger)
void dm_logger_flush_buffer(struct dal_logger *logger, bool should_warn)
{
int i = logger->buffer_read_offset;
char *string_start = &logger->log_buffer[i];
char *string_start = &logger->log_buffer[logger->buffer_read_offset];
dm_output_to_console(
"---------------- FLUSHING LOG BUFFER ----------------\n");
while (i < logger->buffer_write_offset) {
if (should_warn)
dm_output_to_console(
"---------------- FLUSHING LOG BUFFER ----------------\n");
while (logger->buffer_read_offset < logger->buffer_write_offset) {
if (logger->log_buffer[i] == '\0') {
if (logger->log_buffer[logger->buffer_read_offset] == '\0') {
dm_output_to_console("%s", string_start);
string_start = (char *)logger->log_buffer + i + 1;
string_start = logger->log_buffer + logger->buffer_read_offset + 1;
}
i++;
logger->buffer_read_offset++;
}
dm_output_to_console(
"-------------- END FLUSHING LOG BUFFER --------------\n\n");
if (should_warn)
dm_output_to_console(
"-------------- END FLUSHING LOG BUFFER --------------\n\n");
}
static void log_to_internal_buffer(struct log_entry *entry)
@ -195,35 +194,17 @@ static void log_to_internal_buffer(struct log_entry *entry)
if (size > 0 && size < logger->log_buffer_size) {
int total_free_space = 0;
int space_before_wrap = 0;
int buffer_space = logger->log_buffer_size -
logger->buffer_write_offset;
if (logger->buffer_write_offset > logger->buffer_read_offset) {
total_free_space = logger->log_buffer_size -
logger->buffer_write_offset +
logger->buffer_read_offset;
space_before_wrap = logger->log_buffer_size -
logger->buffer_write_offset;
} else if (logger->buffer_write_offset <
logger->buffer_read_offset) {
total_free_space = logger->log_buffer_size -
logger->buffer_read_offset +
logger->buffer_write_offset;
space_before_wrap = total_free_space;
} else if (logger->write_wrap_count !=
logger->read_wrap_count) {
/* Buffer is completely full already */
total_free_space = 0;
space_before_wrap = 0;
} else {
if (logger->buffer_write_offset == logger->buffer_read_offset) {
/* Buffer is empty, start writing at beginning */
total_free_space = logger->log_buffer_size;
space_before_wrap = logger->log_buffer_size;
buffer_space = logger->log_buffer_size;
logger->buffer_write_offset = 0;
logger->buffer_read_offset = 0;
}
if (space_before_wrap > size) {
if (buffer_space > size) {
/* No wrap around, copy 'size' bytes
* from 'entry->buf' to 'log_buffer'
*/
@ -232,28 +213,12 @@ static void log_to_internal_buffer(struct log_entry *entry)
entry->buf, size);
logger->buffer_write_offset += size;
} else if (total_free_space > size) {
/* We have enough room without flushing,
* but need to wrap around */
int space_after_wrap = total_free_space -
space_before_wrap;
memmove(logger->log_buffer +
logger->buffer_write_offset,
entry->buf, space_before_wrap);
memmove(logger->log_buffer, entry->buf +
space_before_wrap, space_after_wrap);
logger->buffer_write_offset = space_after_wrap;
logger->write_wrap_count++;
} else {
/* Not enough room remaining, we should flush
* existing logs */
/* Flush existing unread logs to console */
flush_to_debug_console(logger);
dm_logger_flush_buffer(logger, true);
/* Start writing to beginning of buffer */
memmove(logger->log_buffer, entry->buf, size);
@ -325,9 +290,10 @@ void dm_logger_write(
log_heading(&entry);
size = dm_log_to_buffer(
buffer, LOG_MAX_LINE_SIZE, msg, args);
buffer, LOG_MAX_LINE_SIZE - 1, msg, args);
entry.buf_offset += size;
buffer[entry.buf_offset + size] = '\0';
entry.buf_offset += size + 1;
/* --Flush log_entry buffer-- */
/* print to kernel console */

View File

@ -26,42 +26,5 @@
#ifndef __DAL_LOGGER_H__
#define __DAL_LOGGER_H__
/* Structure for keeping track of offsets, buffer, etc */
#define DAL_LOGGER_BUFFER_MAX_SIZE 2048
/*Connectivity log needs to output EDID, which needs at lease 256x3 bytes,
* change log line size to 896 to meet the request.
*/
#define LOG_MAX_LINE_SIZE 896
#include "include/logger_types.h"
struct dal_logger {
/* How far into the circular buffer has been read by dsat
* Read offset should never cross write offset. Write \0's to
* read data just to be sure?
*/
uint32_t buffer_read_offset;
/* How far into the circular buffer we have written
* Write offset should never cross read offset
*/
uint32_t buffer_write_offset;
uint32_t write_wrap_count;
uint32_t read_wrap_count;
uint32_t open_count;
char *log_buffer; /* Pointer to malloc'ed buffer */
uint32_t log_buffer_size; /* Size of circular buffer */
uint32_t mask; /*array of masks for major elements*/
union logger_flags flags;
struct dc_context *ctx;
};
#endif /* __DAL_LOGGER_H__ */

View File

@ -1042,13 +1042,13 @@ static enum bp_result get_embedded_panel_info_v2_1(
info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0;
info->lcd_timing.misc_info.H_REPLICATION_BY2 =
lvds->lcd_timing.miscinfo & ATOM_H_REPLICATIONBY2;
!!(lvds->lcd_timing.miscinfo & ATOM_H_REPLICATIONBY2);
info->lcd_timing.misc_info.V_REPLICATION_BY2 =
lvds->lcd_timing.miscinfo & ATOM_V_REPLICATIONBY2;
!!(lvds->lcd_timing.miscinfo & ATOM_V_REPLICATIONBY2);
info->lcd_timing.misc_info.COMPOSITE_SYNC =
lvds->lcd_timing.miscinfo & ATOM_COMPOSITESYNC;
!!(lvds->lcd_timing.miscinfo & ATOM_COMPOSITESYNC);
info->lcd_timing.misc_info.INTERLACE =
lvds->lcd_timing.miscinfo & ATOM_INTERLACE;
!!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE);
/* not provided by VBIOS*/
info->lcd_timing.misc_info.DOUBLE_CLOCK = 0;
@ -1056,7 +1056,7 @@ static enum bp_result get_embedded_panel_info_v2_1(
info->ss_id = 0;
info->realtek_eDPToLVDS =
(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID ? 1:0);
!!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID);
return BP_RESULT_OK;
}

View File

@ -5,7 +5,7 @@
CFLAGS_dcn_calcs.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_dcn_calc_auto.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_dcn_calc_math.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_dcn_calc_math.o := -mhard-float -msse -mpreferred-stack-boundary=4 -Wno-tautological-compare
BW_CALCS = dce_calcs.o bw_fixed.o custom_float.o

View File

@ -25,6 +25,41 @@
#include "dcn_calc_math.h"
float dcn_bw_mod(const float arg1, const float arg2)
{
if (arg1 != arg1)
return arg2;
if (arg2 != arg2)
return arg1;
return arg1 - arg1 * ((int) (arg1 / arg2));
}
float dcn_bw_min2(const float arg1, const float arg2)
{
if (arg1 != arg1)
return arg2;
if (arg2 != arg2)
return arg1;
return arg1 < arg2 ? arg1 : arg2;
}
unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2)
{
if (arg1 != arg1)
return arg2;
if (arg2 != arg2)
return arg1;
return arg1 > arg2 ? arg1 : arg2;
}
float dcn_bw_max2(const float arg1, const float arg2)
{
if (arg1 != arg1)
return arg2;
if (arg2 != arg2)
return arg1;
return arg1 > arg2 ? arg1 : arg2;
}
float dcn_bw_floor2(const float arg, const float significance)
{
if (significance == 0)
@ -40,6 +75,16 @@ float dcn_bw_ceil2(const float arg, const float significance)
return flr + 0.00001 >= arg ? arg : flr + significance;
}
float dcn_bw_max3(float v1, float v2, float v3)
{
return v3 > dcn_bw_max2(v1, v2) ? v3 : dcn_bw_max2(v1, v2);
}
float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5)
{
return dcn_bw_max3(v1, v2, v3) > dcn_bw_max2(v4, v5) ? dcn_bw_max3(v1, v2, v3) : dcn_bw_max2(v4, v5);
}
float dcn_bw_pow(float a, float exp)
{
float temp;

View File

@ -26,38 +26,14 @@
#ifndef _DCN_CALC_MATH_H_
#define _DCN_CALC_MATH_H_
static inline float dcn_bw_mod(const float arg1, const float arg2)
{
return arg1 - arg1 * ((int) (arg1 / arg2));
}
static inline float dcn_bw_min2(const float arg1, const float arg2)
{
return arg1 < arg2 ? arg1 : arg2;
}
static inline unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2)
{
return arg1 > arg2 ? arg1 : arg2;
}
static inline float dcn_bw_max2(const float arg1, const float arg2)
{
return arg1 > arg2 ? arg1 : arg2;
}
static inline float dcn_bw_max3(float v1, float v2, float v3)
{
return v3 > dcn_bw_max2(v1, v2) ? v3 : dcn_bw_max2(v1, v2);
}
static inline float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5)
{
return dcn_bw_max3(v1, v2, v3) > dcn_bw_max2(v4, v5) ? dcn_bw_max3(v1, v2, v3) : dcn_bw_max2(v4, v5);
}
float dcn_bw_mod(const float arg1, const float arg2);
float dcn_bw_min2(const float arg1, const float arg2);
unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2);
float dcn_bw_max2(const float arg1, const float arg2);
float dcn_bw_floor2(const float arg, const float significance);
float dcn_bw_ceil2(const float arg, const float significance);
float dcn_bw_max3(float v1, float v2, float v3);
float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5);
float dcn_bw_pow(float a, float exp);
float dcn_bw_log(float a, float b);

View File

@ -364,7 +364,8 @@ static void pipe_ctx_to_e2e_pipe_params (
}
input->dest.vactive = pipe->stream->timing.v_addressable;
input->dest.vactive = pipe->stream->timing.v_addressable + pipe->stream->timing.v_border_top
+ pipe->stream->timing.v_border_bottom;
input->dest.recout_width = pipe->plane_res.scl_data.recout.width;
input->dest.recout_height = pipe->plane_res.scl_data.recout.height;
@ -385,10 +386,6 @@ static void pipe_ctx_to_e2e_pipe_params (
- pipe->stream->timing.v_addressable
- pipe->stream->timing.v_border_bottom
- pipe->stream->timing.v_border_top;
input->dest.vsync_plus_back_porch = pipe->stream->timing.v_total
- pipe->stream->timing.v_addressable
- pipe->stream->timing.v_front_porch;
input->dest.pixel_rate_mhz = pipe->stream->timing.pix_clk_khz/1000.0;
input->dest.vstartup_start = pipe->pipe_dlg_param.vstartup_start;
input->dest.vupdate_offset = pipe->pipe_dlg_param.vupdate_offset;
@ -458,9 +455,9 @@ static void dcn_bw_calc_rq_dlg_ttu(
/*todo: soc->sr_enter_plus_exit_time??*/
dlg_sys_param.t_srx_delay_us = dc->dcn_ip->dcfclk_cstate_latency / v->dcf_clk_deep_sleep;
dml_rq_dlg_get_rq_params(dml, &rq_param, input.pipe.src);
extract_rq_regs(dml, rq_regs, rq_param);
dml_rq_dlg_get_dlg_params(
dml1_rq_dlg_get_rq_params(dml, &rq_param, input.pipe.src);
dml1_extract_rq_regs(dml, rq_regs, rq_param);
dml1_rq_dlg_get_dlg_params(
dml,
dlg_regs,
ttu_regs,
@ -473,96 +470,6 @@ static void dcn_bw_calc_rq_dlg_ttu(
pipe->plane_state->flip_immediate);
}
static void dcn_dml_wm_override(
const struct dcn_bw_internal_vars *v,
struct display_mode_lib *dml,
struct dc_state *context,
const struct resource_pool *pool)
{
int i, in_idx, active_count;
struct _vcs_dpi_display_e2e_pipe_params_st *input = kzalloc(pool->pipe_count * sizeof(struct _vcs_dpi_display_e2e_pipe_params_st),
GFP_KERNEL);
struct wm {
double urgent;
struct _vcs_dpi_cstate_pstate_watermarks_st cpstate;
double pte_meta_urgent;
} a;
for (i = 0, in_idx = 0; i < pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
if (!pipe->stream || !pipe->plane_state)
continue;
input[in_idx].clks_cfg.dcfclk_mhz = v->dcfclk;
input[in_idx].clks_cfg.dispclk_mhz = v->dispclk;
input[in_idx].clks_cfg.dppclk_mhz = v->dppclk;
input[in_idx].clks_cfg.refclk_mhz = pool->ref_clock_inKhz / 1000;
input[in_idx].clks_cfg.socclk_mhz = v->socclk;
input[in_idx].clks_cfg.voltage = v->voltage_level;
input[in_idx].dout.output_format = (v->output_format[in_idx] == dcn_bw_420) ? dm_420 : dm_444;
input[in_idx].dout.output_type = (v->output[in_idx] == dcn_bw_hdmi) ? dm_hdmi : dm_dp;
//input[in_idx].dout.output_standard;
switch (v->output_deep_color[in_idx]) {
case dcn_bw_encoder_12bpc:
input[in_idx].dout.output_bpc = dm_out_12;
break;
case dcn_bw_encoder_10bpc:
input[in_idx].dout.output_bpc = dm_out_10;
break;
case dcn_bw_encoder_8bpc:
default:
input[in_idx].dout.output_bpc = dm_out_8;
break;
}
pipe_ctx_to_e2e_pipe_params(pipe, &input[in_idx].pipe);
dml_rq_dlg_get_rq_reg(
dml,
&pipe->rq_regs,
input[in_idx].pipe.src);
in_idx++;
}
active_count = in_idx;
a.urgent = dml_wm_urgent_e2e(dml, input, active_count);
a.cpstate = dml_wm_cstate_pstate_e2e(dml, input, active_count);
a.pte_meta_urgent = dml_wm_pte_meta_urgent(dml, a.urgent);
context->bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns =
a.cpstate.cstate_exit_us * 1000;
context->bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns =
a.cpstate.cstate_enter_plus_exit_us * 1000;
context->bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns =
a.cpstate.pstate_change_us * 1000;
context->bw.dcn.watermarks.a.pte_meta_urgent_ns = a.pte_meta_urgent * 1000;
context->bw.dcn.watermarks.a.urgent_ns = a.urgent * 1000;
context->bw.dcn.watermarks.b = context->bw.dcn.watermarks.a;
context->bw.dcn.watermarks.c = context->bw.dcn.watermarks.a;
context->bw.dcn.watermarks.d = context->bw.dcn.watermarks.a;
for (i = 0, in_idx = 0; i < pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
if (!pipe->stream || !pipe->plane_state)
continue;
dml_rq_dlg_get_dlg_reg(dml,
&pipe->dlg_regs,
&pipe->ttu_regs,
input, active_count,
in_idx,
true,
true,
v->pte_enable == dcn_bw_yes,
pipe->plane_state->flip_immediate);
in_idx++;
}
kfree(input);
}
static void split_stream_across_pipes(
struct resource_context *res_ctx,
const struct resource_pool *pool,
@ -578,8 +485,10 @@ static void split_stream_across_pipes(
secondary_pipe->pipe_idx = pipe_idx;
secondary_pipe->plane_res.mi = pool->mis[secondary_pipe->pipe_idx];
secondary_pipe->plane_res.hubp = pool->hubps[secondary_pipe->pipe_idx];
secondary_pipe->plane_res.ipp = pool->ipps[secondary_pipe->pipe_idx];
secondary_pipe->plane_res.xfm = pool->transforms[secondary_pipe->pipe_idx];
secondary_pipe->plane_res.dpp = pool->dpps[secondary_pipe->pipe_idx];
if (primary_pipe->bottom_pipe) {
ASSERT(primary_pipe->bottom_pipe != secondary_pipe);
secondary_pipe->bottom_pipe = primary_pipe->bottom_pipe;
@ -719,6 +628,49 @@ static bool dcn_bw_apply_registry_override(struct dc *dc)
return updated;
}
void hack_disable_optional_pipe_split(struct dcn_bw_internal_vars *v)
{
/*
* disable optional pipe split by lower dispclk bounding box
* at DPM0
*/
v->max_dispclk[0] = v->max_dppclk_vmin0p65;
}
void hack_force_pipe_split(struct dcn_bw_internal_vars *v,
unsigned int pixel_rate_khz)
{
float pixel_rate_mhz = pixel_rate_khz / 1000;
/*
* force enabling pipe split by lower dpp clock for DPM0 to just
* below the specify pixel_rate, so bw calc would split pipe.
*/
if (pixel_rate_mhz < v->max_dppclk[0])
v->max_dppclk[0] = pixel_rate_mhz;
}
void hack_bounding_box(struct dcn_bw_internal_vars *v,
struct dc_debug *dbg,
struct dc_state *context)
{
if (dbg->pipe_split_policy == MPC_SPLIT_AVOID) {
hack_disable_optional_pipe_split(v);
}
if (dbg->pipe_split_policy == MPC_SPLIT_AVOID_MULT_DISP &&
context->stream_count >= 2) {
hack_disable_optional_pipe_split(v);
}
if (context->stream_count == 1 &&
dbg->force_single_disp_pipe_split) {
struct dc_stream_state *stream0 = context->streams[0];
hack_force_pipe_split(v, stream0->timing.pix_clk_khz);
}
}
bool dcn_validate_bandwidth(
struct dc *dc,
struct dc_state *context)
@ -730,6 +682,7 @@ bool dcn_validate_bandwidth(
bool bw_limit_pass;
float bw_limit;
PERFORMANCE_TRACE_START();
if (dcn_bw_apply_registry_override(dc))
dcn_bw_sync_calcs_and_dml(dc);
@ -850,9 +803,7 @@ bool dcn_validate_bandwidth(
v->phyclk_per_state[1] = v->phyclkv_mid0p72;
v->phyclk_per_state[0] = v->phyclkv_min0p65;
if (dc->debug.disable_pipe_split) {
v->max_dispclk[0] = v->max_dppclk_vmin0p65;
}
hack_bounding_box(v, &dc->debug, context);
if (v->voltage_override == dcn_bw_v_max0p9) {
v->voltage_override_level = number_of_states - 1;
@ -882,10 +833,11 @@ bool dcn_validate_bandwidth(
v->htotal[input_idx] = pipe->stream->timing.h_total;
v->vtotal[input_idx] = pipe->stream->timing.v_total;
v->vactive[input_idx] = pipe->stream->timing.v_addressable +
pipe->stream->timing.v_border_top + pipe->stream->timing.v_border_bottom;
v->v_sync_plus_back_porch[input_idx] = pipe->stream->timing.v_total
- pipe->stream->timing.v_addressable
- v->vactive[input_idx]
- pipe->stream->timing.v_front_porch;
v->vactive[input_idx] = pipe->stream->timing.v_addressable;
v->pixel_clock[input_idx] = pipe->stream->timing.pix_clk_khz / 1000.0f;
if (!pipe->plane_state) {
@ -1006,6 +958,10 @@ bool dcn_validate_bandwidth(
else
bw_consumed = v->fabric_and_dram_bandwidth_vmax0p9;
if (bw_consumed < v->fabric_and_dram_bandwidth)
if (dc->debug.voltage_align_fclk)
bw_consumed = v->fabric_and_dram_bandwidth;
display_pipe_configuration(v);
calc_wm_sets_and_perf_params(context, v);
context->bw.dcn.calc_clk.fclk_khz = (int)(bw_consumed * 1000000 /
@ -1018,9 +974,17 @@ bool dcn_validate_bandwidth(
context->bw.dcn.calc_clk.min_active_dram_ccm_us = (int)(v->min_active_dram_clock_change_margin);
context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz = (int)(v->dcf_clk_deep_sleep * 1000);
context->bw.dcn.calc_clk.dcfclk_khz = (int)(v->dcfclk * 1000);
context->bw.dcn.calc_clk.dispclk_khz = (int)(v->dispclk * 1000);
if (dc->debug.max_disp_clk == true)
context->bw.dcn.calc_clk.dispclk_khz = (int)(dc->dcn_soc->max_dispclk_vmax0p9 * 1000);
if (context->bw.dcn.calc_clk.dispclk_khz <
dc->debug.min_disp_clk_khz) {
context->bw.dcn.calc_clk.dispclk_khz =
dc->debug.min_disp_clk_khz;
}
context->bw.dcn.calc_clk.dppclk_div = (int)(v->dispclk_dppclk_ratio) == 2;
for (i = 0, input_idx = 0; i < pool->pipe_count; i++) {
@ -1108,9 +1072,6 @@ bool dcn_validate_bandwidth(
input_idx++;
}
if (dc->debug.use_dml_wm)
dcn_dml_wm_override(v, (struct display_mode_lib *)
&dc->dml, context, pool);
}
if (v->voltage_level == 0) {
@ -1129,6 +1090,8 @@ bool dcn_validate_bandwidth(
kernel_fpu_end();
PERFORMANCE_TRACE_END();
if (bw_limit_pass && v->voltage_level != 5)
return true;
else
@ -1263,7 +1226,7 @@ unsigned int dcn_find_dcfclk_suits_all(
else
dcf_clk = dc->dcn_soc->dcfclkv_min0p65*1000;
dm_logger_write(dc->ctx->logger, LOG_HW_MARKS,
dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_CALCS,
"\tdcf_clk for voltage = %d\n", dcf_clk);
return dcf_clk;
}
@ -1386,6 +1349,53 @@ void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc)
ranges.writer_wm_sets[3].min_drain_clk_khz = max_fclk_khz;
ranges.writer_wm_sets[3].max_drain_clk_khz = max_fclk_khz;
if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) {
ranges.reader_wm_sets[0].wm_inst = WM_A;
ranges.reader_wm_sets[0].min_drain_clk_khz = 300000;
ranges.reader_wm_sets[0].max_drain_clk_khz = 654000;
ranges.reader_wm_sets[0].min_fill_clk_khz = 800000;
ranges.reader_wm_sets[0].max_fill_clk_khz = 800000;
ranges.writer_wm_sets[0].wm_inst = WM_A;
ranges.writer_wm_sets[0].min_fill_clk_khz = 200000;
ranges.writer_wm_sets[0].max_fill_clk_khz = 757000;
ranges.writer_wm_sets[0].min_drain_clk_khz = 800000;
ranges.writer_wm_sets[0].max_drain_clk_khz = 800000;
ranges.reader_wm_sets[1].wm_inst = WM_B;
ranges.reader_wm_sets[1].min_drain_clk_khz = 300000;
ranges.reader_wm_sets[1].max_drain_clk_khz = 654000;
ranges.reader_wm_sets[1].min_fill_clk_khz = 933000;
ranges.reader_wm_sets[1].max_fill_clk_khz = 933000;
ranges.writer_wm_sets[1].wm_inst = WM_B;
ranges.writer_wm_sets[1].min_fill_clk_khz = 200000;
ranges.writer_wm_sets[1].max_fill_clk_khz = 757000;
ranges.writer_wm_sets[1].min_drain_clk_khz = 933000;
ranges.writer_wm_sets[1].max_drain_clk_khz = 933000;
ranges.reader_wm_sets[2].wm_inst = WM_C;
ranges.reader_wm_sets[2].min_drain_clk_khz = 300000;
ranges.reader_wm_sets[2].max_drain_clk_khz = 654000;
ranges.reader_wm_sets[2].min_fill_clk_khz = 1067000;
ranges.reader_wm_sets[2].max_fill_clk_khz = 1067000;
ranges.writer_wm_sets[2].wm_inst = WM_C;
ranges.writer_wm_sets[2].min_fill_clk_khz = 200000;
ranges.writer_wm_sets[2].max_fill_clk_khz = 757000;
ranges.writer_wm_sets[2].min_drain_clk_khz = 1067000;
ranges.writer_wm_sets[2].max_drain_clk_khz = 1067000;
ranges.reader_wm_sets[3].wm_inst = WM_D;
ranges.reader_wm_sets[3].min_drain_clk_khz = 300000;
ranges.reader_wm_sets[3].max_drain_clk_khz = 654000;
ranges.reader_wm_sets[3].min_fill_clk_khz = 1200000;
ranges.reader_wm_sets[3].max_fill_clk_khz = 1200000;
ranges.writer_wm_sets[3].wm_inst = WM_D;
ranges.writer_wm_sets[3].min_fill_clk_khz = 200000;
ranges.writer_wm_sets[3].max_fill_clk_khz = 757000;
ranges.writer_wm_sets[3].min_drain_clk_khz = 1200000;
ranges.writer_wm_sets[3].max_drain_clk_khz = 1200000;
}
/* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
pp->set_wm_ranges(&pp->pp_smu, &ranges);
}

View File

@ -38,6 +38,7 @@
#include "bios_parser_interface.h"
#include "include/irq_service_interface.h"
#include "transform.h"
#include "dpp.h"
#include "timing_generator.h"
#include "virtual/virtual_link_encoder.h"
@ -47,6 +48,7 @@
#include "dc_link_ddc.h"
#include "dm_helpers.h"
#include "mem_input.h"
#include "hubp.h"
/*******************************************************************************
@ -332,10 +334,19 @@ static void set_dither_option(struct dc_stream_state *stream,
{
struct bit_depth_reduction_params params;
struct dc_link *link = stream->status.link;
struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
struct pipe_ctx *pipes = NULL;
int i;
for (i = 0; i < MAX_PIPES; i++) {
if (link->dc->current_state->res_ctx.pipe_ctx[i].stream ==
stream) {
pipes = &link->dc->current_state->res_ctx.pipe_ctx[i];
break;
}
}
memset(&params, 0, sizeof(params));
if (!stream)
if (!pipes)
return;
if (option > DITHER_OPTION_MAX)
return;
@ -349,6 +360,36 @@ static void set_dither_option(struct dc_stream_state *stream,
opp_program_bit_depth_reduction(pipes->stream_res.opp, &params);
}
void set_dpms(
struct dc *dc,
struct dc_stream_state *stream,
bool dpms_off)
{
struct pipe_ctx *pipe_ctx = NULL;
int i;
for (i = 0; i < MAX_PIPES; i++) {
if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) {
pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
break;
}
}
if (!pipe_ctx) {
ASSERT(0);
return;
}
if (stream->dpms_off != dpms_off) {
stream->dpms_off = dpms_off;
if (dpms_off)
core_link_disable_stream(pipe_ctx,
KEEP_ACQUIRED_RESOURCE);
else
core_link_enable_stream(dc->current_state, pipe_ctx);
}
}
static void allocate_dc_stream_funcs(struct dc *dc)
{
if (dc->hwss.set_drr != NULL) {
@ -371,6 +412,9 @@ static void allocate_dc_stream_funcs(struct dc *dc)
dc->stream_funcs.set_dither_option =
set_dither_option;
dc->stream_funcs.set_dpms =
set_dpms;
dc->link_funcs.set_drive_settings =
set_drive_settings;
@ -507,7 +551,7 @@ static bool construct(struct dc *dc,
dc_version = resource_parse_asic_id(init_params->asic_id);
dc->ctx->dce_version = dc_version;
#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
dc->ctx->fbc_gpu_addr = init_params->fbc_gpu_addr;
#endif
/* Resource should construct all asic specific resources.
@ -749,7 +793,7 @@ bool dc_enable_stereo(
* Applies given context to HW and copy it into current context.
* It's up to the user to release the src context afterwards.
*/
static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
{
struct dc_bios *dcb = dc->ctx->dc_bios;
enum dc_status result = DC_ERROR_UNEXPECTED;
@ -763,41 +807,31 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
if (!dcb->funcs->is_accelerated_mode(dcb))
dc->hwss.enable_accelerated_mode(dc);
dc->hwss.ready_shared_resources(dc);
for (i = 0; i < dc->res_pool->pipe_count; i++) {
pipe = &context->res_ctx.pipe_ctx[i];
dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
}
result = dc->hwss.apply_ctx_to_hw(dc, context);
program_timing_sync(dc, context);
for (i = 0; i < context->stream_count; i++) {
const struct dc_sink *sink = context->streams[i]->sink;
for (j = 0; j < context->stream_status[i].plane_count; j++) {
dc->hwss.apply_ctx_for_surface(
dc, context->streams[i],
context->stream_status[i].plane_count,
context);
dc->hwss.apply_ctx_for_surface(
dc, context->streams[i],
context->stream_status[i].plane_count,
context);
/*
* enable stereo
* TODO rework dc_enable_stereo call to work with validation sets?
*/
for (k = 0; k < MAX_PIPES; k++) {
pipe = &context->res_ctx.pipe_ctx[k];
/*
* enable stereo
* TODO rework dc_enable_stereo call to work with validation sets?
*/
for (k = 0; k < MAX_PIPES; k++) {
pipe = &context->res_ctx.pipe_ctx[k];
for (l = 0 ; pipe && l < context->stream_count; l++) {
if (context->streams[l] &&
context->streams[l] == pipe->stream &&
dc->hwss.setup_stereo)
dc->hwss.setup_stereo(pipe, dc);
}
for (l = 0 ; pipe && l < context->stream_count; l++) {
if (context->streams[l] &&
context->streams[l] == pipe->stream &&
dc->hwss.setup_stereo)
dc->hwss.setup_stereo(pipe, dc);
}
}
CONN_MSG_MODE(sink->link, "{%dx%d, %dx%d@%dKhz}",
context->streams[i]->timing.h_addressable,
context->streams[i]->timing.v_addressable,
@ -806,8 +840,27 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
context->streams[i]->timing.pix_clk_khz);
}
dc->hwss.ready_shared_resources(dc, context);
for (i = 0; i < dc->res_pool->pipe_count; i++) {
pipe = &context->res_ctx.pipe_ctx[i];
dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
}
result = dc->hwss.apply_ctx_to_hw(dc, context);
program_timing_sync(dc, context);
dc_enable_stereo(dc, context, dc_streams, context->stream_count);
for (i = 0; i < context->stream_count; i++) {
for (j = 0; j < MAX_PIPES; j++) {
pipe = &context->res_ctx.pipe_ctx[j];
if (!pipe->top_pipe && pipe->stream == context->streams[i])
dc->hwss.pipe_control_lock(dc, pipe, false);
}
}
dc_release_state(dc->current_state);
dc->current_state = context;
@ -816,7 +869,7 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
dc->hwss.optimize_shared_resources(dc);
return (result == DC_OK);
return result;
}
bool dc_commit_state(struct dc *dc, struct dc_state *context)
@ -865,16 +918,24 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc)
return true;
}
/*
* TODO this whole function needs to go
*
* dc_surface_update is needlessly complex. See if we can just replace this
* with a dc_plane_state and follow the atomic model a bit more closely here.
*/
bool dc_commit_planes_to_stream(
struct dc *dc,
struct dc_plane_state **plane_states,
uint8_t new_plane_count,
struct dc_stream_state *dc_stream)
struct dc_stream_state *dc_stream,
struct dc_state *state)
{
/* no need to dynamically allocate this. it's pretty small */
struct dc_surface_update updates[MAX_SURFACES];
struct dc_flip_addrs flip_addr[MAX_SURFACES];
struct dc_plane_info plane_info[MAX_SURFACES];
struct dc_scaling_info scaling_info[MAX_SURFACES];
struct dc_flip_addrs *flip_addr;
struct dc_plane_info *plane_info;
struct dc_scaling_info *scaling_info;
int i;
struct dc_stream_update *stream_update =
kzalloc(sizeof(struct dc_stream_update), GFP_KERNEL);
@ -884,10 +945,14 @@ bool dc_commit_planes_to_stream(
return false;
}
flip_addr = kcalloc(MAX_SURFACES, sizeof(struct dc_flip_addrs),
GFP_KERNEL);
plane_info = kcalloc(MAX_SURFACES, sizeof(struct dc_plane_info),
GFP_KERNEL);
scaling_info = kcalloc(MAX_SURFACES, sizeof(struct dc_scaling_info),
GFP_KERNEL);
memset(updates, 0, sizeof(updates));
memset(flip_addr, 0, sizeof(flip_addr));
memset(plane_info, 0, sizeof(plane_info));
memset(scaling_info, 0, sizeof(scaling_info));
stream_update->src = dc_stream->src;
stream_update->dst = dc_stream->dst;
@ -920,14 +985,15 @@ bool dc_commit_planes_to_stream(
updates[i].scaling_info = &scaling_info[i];
}
dc_update_planes_and_stream(
dc_commit_updates_for_stream(
dc,
updates,
new_plane_count,
dc_stream, stream_update);
dc_post_update_surfaces_to_stream(dc);
dc_stream, stream_update, plane_states, state);
kfree(flip_addr);
kfree(plane_info);
kfree(scaling_info);
kfree(stream_update);
return true;
}
@ -1030,7 +1096,6 @@ static enum surface_update_type get_plane_info_update_type(
temp_plane_info.plane_size = u->surface->plane_size;
temp_plane_info.rotation = u->surface->rotation;
temp_plane_info.stereo_format = u->surface->stereo_format;
temp_plane_info.tiling_info = u->surface->tiling_info;
if (surface_index == 0)
temp_plane_info.visible = u->plane_info->visible;
@ -1043,10 +1108,26 @@ static enum surface_update_type get_plane_info_update_type(
if (pixel_format_to_bpp(u->plane_info->format) !=
pixel_format_to_bpp(u->surface->format)) {
/* different bytes per element will require full bandwidth
* and DML calculation
*/
return UPDATE_TYPE_FULL;
} else {
return UPDATE_TYPE_MED;
}
if (memcmp(&u->plane_info->tiling_info, &u->surface->tiling_info,
sizeof(union dc_tiling_info)) != 0) {
/* todo: below are HW dependent, we should add a hook to
* DCE/N resource and validated there.
*/
if (u->plane_info->tiling_info.gfx9.swizzle != DC_SW_LINEAR) {
/* swizzled mode requires RQ to be setup properly,
* thus need to run DML to calculate RQ settings
*/
return UPDATE_TYPE_FULL;
}
}
return UPDATE_TYPE_MED;
}
static enum surface_update_type get_scaling_info_update_type(
@ -1150,192 +1231,20 @@ static struct dc_stream_status *stream_get_status(
static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL;
void dc_update_planes_and_stream(struct dc *dc,
struct dc_surface_update *srf_updates, int surface_count,
static void commit_planes_for_stream(struct dc *dc,
struct dc_surface_update *srf_updates,
int surface_count,
struct dc_stream_state *stream,
struct dc_stream_update *stream_update)
struct dc_stream_update *stream_update,
enum surface_update_type update_type,
struct dc_state *context)
{
struct dc_state *context;
int i, j;
enum surface_update_type update_type;
const struct dc_stream_status *stream_status;
struct dc_context *dc_ctx = dc->ctx;
stream_status = dc_stream_get_status(stream);
ASSERT(stream_status);
if (!stream_status)
return; /* Cannot commit surface to stream that is not committed */
#ifdef ENABLE_FBC
if (srf_updates->flip_addr) {
if (srf_updates->flip_addr->address.grph.addr.low_part == 0)
ASSERT(0);
}
#endif
context = dc->current_state;
/* update current stream with the new updates */
if (stream_update) {
if ((stream_update->src.height != 0) &&
(stream_update->src.width != 0))
stream->src = stream_update->src;
if ((stream_update->dst.height != 0) &&
(stream_update->dst.width != 0))
stream->dst = stream_update->dst;
if (stream_update->out_transfer_func &&
stream_update->out_transfer_func !=
stream->out_transfer_func) {
if (stream->out_transfer_func != NULL)
dc_transfer_func_release(stream->out_transfer_func);
dc_transfer_func_retain(stream_update->out_transfer_func);
stream->out_transfer_func =
stream_update->out_transfer_func;
}
}
/* do not perform surface update if surface has invalid dimensions
* (all zero) and no scaling_info is provided
*/
if (surface_count > 0 &&
srf_updates->surface->src_rect.width == 0 &&
srf_updates->surface->src_rect.height == 0 &&
srf_updates->surface->dst_rect.width == 0 &&
srf_updates->surface->dst_rect.height == 0 &&
!srf_updates->scaling_info) {
ASSERT(false);
return;
}
update_type = dc_check_update_surfaces_for_stream(
dc, srf_updates, surface_count, stream_update, stream_status);
if (update_type >= update_surface_trace_level)
update_surface_trace(dc, srf_updates, surface_count);
if (update_type >= UPDATE_TYPE_FULL) {
struct dc_plane_state *new_planes[MAX_SURFACES] = {0};
for (i = 0; i < surface_count; i++)
new_planes[i] = srf_updates[i].surface;
/* initialize scratch memory for building context */
context = dc_create_state();
if (context == NULL) {
DC_ERROR("Failed to allocate new validate context!\n");
return;
}
dc_resource_state_copy_construct(
dc->current_state, context);
/*remove old surfaces from context */
if (!dc_rem_all_planes_for_stream(dc, stream, context)) {
BREAK_TO_DEBUGGER();
goto fail;
}
/* add surface to context */
if (!dc_add_all_planes_for_stream(dc, stream, new_planes, surface_count, context)) {
BREAK_TO_DEBUGGER();
goto fail;
}
}
/* save update parameters into surface */
for (i = 0; i < surface_count; i++) {
struct dc_plane_state *surface = srf_updates[i].surface;
if (srf_updates[i].flip_addr) {
surface->address = srf_updates[i].flip_addr->address;
surface->flip_immediate =
srf_updates[i].flip_addr->flip_immediate;
}
if (srf_updates[i].scaling_info) {
surface->scaling_quality =
srf_updates[i].scaling_info->scaling_quality;
surface->dst_rect =
srf_updates[i].scaling_info->dst_rect;
surface->src_rect =
srf_updates[i].scaling_info->src_rect;
surface->clip_rect =
srf_updates[i].scaling_info->clip_rect;
}
if (srf_updates[i].plane_info) {
surface->color_space =
srf_updates[i].plane_info->color_space;
surface->format =
srf_updates[i].plane_info->format;
surface->plane_size =
srf_updates[i].plane_info->plane_size;
surface->rotation =
srf_updates[i].plane_info->rotation;
surface->horizontal_mirror =
srf_updates[i].plane_info->horizontal_mirror;
surface->stereo_format =
srf_updates[i].plane_info->stereo_format;
surface->tiling_info =
srf_updates[i].plane_info->tiling_info;
surface->visible =
srf_updates[i].plane_info->visible;
surface->per_pixel_alpha =
srf_updates[i].plane_info->per_pixel_alpha;
surface->dcc =
srf_updates[i].plane_info->dcc;
}
if (update_type >= UPDATE_TYPE_MED) {
for (j = 0; j < dc->res_pool->pipe_count; j++) {
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
if (pipe_ctx->plane_state != surface)
continue;
resource_build_scaling_params(pipe_ctx);
}
}
if (srf_updates[i].gamma &&
srf_updates[i].gamma != surface->gamma_correction) {
if (surface->gamma_correction != NULL)
dc_gamma_release(&surface->gamma_correction);
dc_gamma_retain(srf_updates[i].gamma);
surface->gamma_correction = srf_updates[i].gamma;
}
if (srf_updates[i].in_transfer_func &&
srf_updates[i].in_transfer_func != surface->in_transfer_func) {
if (surface->in_transfer_func != NULL)
dc_transfer_func_release(
surface->
in_transfer_func);
dc_transfer_func_retain(
srf_updates[i].in_transfer_func);
surface->in_transfer_func =
srf_updates[i].in_transfer_func;
}
if (srf_updates[i].hdr_static_metadata)
surface->hdr_static_ctx =
*(srf_updates[i].hdr_static_metadata);
}
if (update_type == UPDATE_TYPE_FULL) {
if (!dc->res_pool->funcs->validate_bandwidth(dc, context)) {
BREAK_TO_DEBUGGER();
goto fail;
} else {
dc->hwss.set_bandwidth(dc, context, false);
context_clock_trace(dc, context);
}
dc->hwss.set_bandwidth(dc, context, false);
context_clock_trace(dc, context);
}
if (update_type > UPDATE_TYPE_FAST) {
@ -1346,8 +1255,14 @@ void dc_update_planes_and_stream(struct dc *dc,
}
}
if (surface_count == 0)
if (surface_count == 0) {
/*
* In case of turning off screen, no need to program front end a second time.
* just return after program front end.
*/
dc->hwss.apply_ctx_for_surface(dc, stream, surface_count, context);
return;
}
/* Lock pipes for provided surfaces, or all active if full update*/
for (i = 0; i < surface_count; i++) {
@ -1373,10 +1288,6 @@ void dc_update_planes_and_stream(struct dc *dc,
/* Full fe update*/
for (j = 0; j < dc->res_pool->pipe_count; j++) {
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
struct pipe_ctx *cur_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[j];
bool is_new_pipe_surface = cur_pipe_ctx->plane_state != pipe_ctx->plane_state;
struct dc_cursor_position position = { 0 };
if (update_type != UPDATE_TYPE_FULL || !pipe_ctx->plane_state)
continue;
@ -1387,17 +1298,6 @@ void dc_update_planes_and_stream(struct dc *dc,
dc->hwss.apply_ctx_for_surface(
dc, pipe_ctx->stream, stream_status->plane_count, context);
}
/* TODO: this is a hack w/a for switching from mpo to pipe split */
dc_stream_set_cursor_position(pipe_ctx->stream, &position);
if (is_new_pipe_surface) {
dc->hwss.update_plane_addr(dc, pipe_ctx);
dc->hwss.set_input_transfer_func(
pipe_ctx, pipe_ctx->plane_state);
dc->hwss.set_output_transfer_func(
pipe_ctx, pipe_ctx->stream);
}
}
if (update_type > UPDATE_TYPE_FAST)
@ -1423,7 +1323,9 @@ void dc_update_planes_and_stream(struct dc *dc,
if (update_type == UPDATE_TYPE_FAST)
continue;
if (srf_updates[i].in_transfer_func)
/* work around to program degamma regs for split pipe after set mode. */
if (srf_updates[i].in_transfer_func || (pipe_ctx->top_pipe &&
pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state))
dc->hwss.set_input_transfer_func(
pipe_ctx, pipe_ctx->plane_state);
@ -1459,27 +1361,89 @@ void dc_update_planes_and_stream(struct dc *dc,
break;
}
}
}
void dc_commit_updates_for_stream(struct dc *dc,
struct dc_surface_update *srf_updates,
int surface_count,
struct dc_stream_state *stream,
struct dc_stream_update *stream_update,
struct dc_plane_state **plane_states,
struct dc_state *state)
{
const struct dc_stream_status *stream_status;
enum surface_update_type update_type;
struct dc_state *context;
struct dc_context *dc_ctx = dc->ctx;
int i, j;
stream_status = dc_stream_get_status(stream);
context = dc->current_state;
update_type = dc_check_update_surfaces_for_stream(
dc, srf_updates, surface_count, stream_update, stream_status);
if (update_type >= update_surface_trace_level)
update_surface_trace(dc, srf_updates, surface_count);
if (update_type >= UPDATE_TYPE_FULL) {
/* initialize scratch memory for building context */
context = dc_create_state();
if (context == NULL) {
DC_ERROR("Failed to allocate new validate context!\n");
return;
}
dc_resource_state_copy_construct(state, context);
}
for (i = 0; i < surface_count; i++) {
struct dc_plane_state *surface = srf_updates[i].surface;
/* TODO: On flip we don't build the state, so it still has the
* old address. Which is why we are updating the address here
*/
if (srf_updates[i].flip_addr)
surface->address = srf_updates[i].flip_addr->address;
if (update_type >= UPDATE_TYPE_MED) {
for (j = 0; j < dc->res_pool->pipe_count; j++) {
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
if (pipe_ctx->plane_state != surface)
continue;
resource_build_scaling_params(pipe_ctx);
}
}
}
commit_planes_for_stream(
dc,
srf_updates,
surface_count,
stream,
stream_update,
update_type,
context);
if (update_type >= UPDATE_TYPE_FULL)
dc_post_update_surfaces_to_stream(dc);
if (dc->current_state != context) {
/* Since memory free requires elevated IRQL, an interrupt
* request is generated by mem free. If this happens
* between freeing and reassigning the context, our vsync
* interrupt will call into dc and cause a memory
* corruption BSOD. Hence, we first reassign the context,
* then free the old context.
*/
struct dc_state *old = dc->current_state;
dc->current_state = context;
dc_release_state(old);
}
return;
fail:
dc_release_state(context);
}
uint8_t dc_get_current_stream_count(struct dc *dc)

View File

@ -45,6 +45,7 @@
#include "dce/dce_11_0_enum.h"
#include "dce/dce_11_0_sh_mask.h"
#define EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK 0x007C /* Copied from atombios.h */
#define LINK_INFO(...) \
dm_logger_write(dc_ctx->logger, LOG_HW_HOTPLUG, \
__VA_ARGS__)
@ -78,14 +79,15 @@ static void destruct(struct dc_link *link)
dc_sink_release(link->remote_sinks[i]);
}
static struct gpio *get_hpd_gpio(const struct dc_link *link)
struct gpio *get_hpd_gpio(struct dc_bios *dcb,
struct graphics_object_id link_id,
struct gpio_service *gpio_service)
{
enum bp_result bp_result;
struct dc_bios *dcb = link->ctx->dc_bios;
struct graphics_object_hpd_info hpd_info;
struct gpio_pin_info pin_info;
if (dcb->funcs->get_hpd_info(dcb, link->link_id, &hpd_info) != BP_RESULT_OK)
if (dcb->funcs->get_hpd_info(dcb, link_id, &hpd_info) != BP_RESULT_OK)
return NULL;
bp_result = dcb->funcs->get_gpio_pin_info(dcb,
@ -97,7 +99,7 @@ static struct gpio *get_hpd_gpio(const struct dc_link *link)
}
return dal_gpio_service_create_irq(
link->ctx->gpio_service,
gpio_service,
pin_info.offset,
pin_info.mask);
}
@ -153,7 +155,7 @@ static bool program_hpd_filter(
}
/* Obtain HPD handle */
hpd = get_hpd_gpio(link);
hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
if (!hpd)
return result;
@ -186,7 +188,7 @@ static bool detect_sink(struct dc_link *link, enum dc_connection_type *type)
struct gpio *hpd_pin;
/* todo: may need to lock gpio access */
hpd_pin = get_hpd_gpio(link);
hpd_pin = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
if (hpd_pin == NULL)
goto hpd_gpio_failure;
@ -496,6 +498,7 @@ static void detect_dp(
}
if (is_mst_supported(link)) {
sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
link->type = dc_connection_mst_branch;
/*
* This call will initiate MST topology discovery. Which
@ -524,12 +527,11 @@ static void detect_dp(
if (reason == DETECT_REASON_BOOT)
boot = true;
if (dm_helpers_dp_mst_start_top_mgr(
if (!dm_helpers_dp_mst_start_top_mgr(
link->ctx,
link, boot)) {
link->type = dc_connection_mst_branch;
} else {
/* MST not supported */
link->type = dc_connection_single;
sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
}
}
@ -638,8 +640,8 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
if (link->dpcd_caps.sink_count.bits.SINK_COUNT)
link->dpcd_sink_count = link->dpcd_caps.sink_count.
bits.SINK_COUNT;
else
link->dpcd_sink_count = 1;
else
link->dpcd_sink_count = 1;
dal_ddc_service_set_transaction_type(
link->ddc,
@ -746,6 +748,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
if (link->type == dc_connection_mst_branch) {
LINK_INFO("link=%d, mst branch is now Disconnected\n",
link->link_index);
dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
link->mst_stream_alloc_table.stream_count = 0;
@ -770,7 +773,7 @@ static enum hpd_source_id get_hpd_line(
struct gpio *hpd;
enum hpd_source_id hpd_id = HPD_SOURCEID_UNKNOWN;
hpd = get_hpd_gpio(link);
hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
if (hpd) {
switch (dal_irq_get_source(hpd)) {
@ -940,7 +943,7 @@ static bool construct(
goto create_fail;
}
hpd_gpio = get_hpd_gpio(link);
hpd_gpio = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
if (hpd_gpio != NULL)
link->irq_source_hpd = dal_irq_get_source(hpd_gpio);
@ -1343,7 +1346,18 @@ static bool get_ext_hdmi_settings(struct pipe_ctx *pipe_ctx,
sizeof(integrated_info->dp2_ext_hdmi_6g_reg_settings));
result = true;
break;
case ENGINE_ID_DIGD:
settings->slv_addr = integrated_info->dp3_ext_hdmi_slv_addr;
settings->reg_num = integrated_info->dp3_ext_hdmi_6g_reg_num;
settings->reg_num_6g = integrated_info->dp3_ext_hdmi_6g_reg_num;
memmove(settings->reg_settings,
integrated_info->dp3_ext_hdmi_reg_settings,
sizeof(integrated_info->dp3_ext_hdmi_reg_settings));
memmove(settings->reg_settings_6g,
integrated_info->dp3_ext_hdmi_6g_reg_settings,
sizeof(integrated_info->dp3_ext_hdmi_6g_reg_settings));
result = true;
break;
default:
break;
}
@ -1680,7 +1694,9 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
is_over_340mhz = true;
if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
if ((pipe_ctx->stream->sink->link->chip_caps >> 2) == 0x2) {
unsigned short masked_chip_caps = pipe_ctx->stream->sink->link->chip_caps &
EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK;
if (masked_chip_caps == (0x2 << 2)) {
/* DP159, Retimer settings */
eng_id = pipe_ctx->stream_res.stream_enc->id;
@ -1691,7 +1707,7 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
write_i2c_default_retimer_setting(pipe_ctx,
is_vga_mode, is_over_340mhz);
}
} else if ((pipe_ctx->stream->sink->link->chip_caps >> 2) == 0x1) {
} else if (masked_chip_caps == (0x1 << 2)) {
/* PI3EQX1204, Redriver settings */
write_i2c_redriver_setting(pipe_ctx, is_over_340mhz);
}
@ -1782,7 +1798,7 @@ static void disable_link(struct dc_link *link, enum signal_type signal)
else
dp_disable_link_phy_mst(link, signal);
} else
link->link_enc->funcs->disable_output(link->link_enc, signal);
link->link_enc->funcs->disable_output(link->link_enc, signal, link);
}
enum dc_status dc_link_validate_mode_timing(
@ -2319,16 +2335,20 @@ void core_link_enable_stream(
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
allocate_mst_payload(pipe_ctx);
if (dc_is_dp_signal(pipe_ctx->stream->signal))
core_dc->hwss.unblank_stream(pipe_ctx,
&pipe_ctx->stream->sink->link->cur_link_settings);
}
void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option)
{
struct dc *core_dc = pipe_ctx->stream->ctx->dc;
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
deallocate_mst_payload(pipe_ctx);
core_dc->hwss.disable_stream(pipe_ctx);
core_dc->hwss.disable_stream(pipe_ctx, option);
disable_link(pipe_ctx->stream->sink->link, pipe_ctx->stream->signal);
}

View File

@ -1700,6 +1700,12 @@ static void dp_test_send_link_training(struct dc_link *link)
dp_retrain_link_dp_test(link, &link_settings, false);
}
/* TODO hbr2 compliance eye output is unstable
* (toggling on and off) with debugger break
* This caueses intermittent PHY automation failure
* Need to look into the root cause */
static uint8_t force_tps4_for_cp2520 = 1;
static void dp_test_send_phy_test_pattern(struct dc_link *link)
{
union phy_test_pattern dpcd_test_pattern;
@ -1758,10 +1764,16 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM;
break;
case PHY_TEST_PATTERN_CP2520_1:
test_pattern = DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
/* CP2520 pattern is unstable, temporarily use TPS4 instead */
test_pattern = (force_tps4_for_cp2520 == 1) ?
DP_TEST_PATTERN_TRAINING_PATTERN4 :
DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
break;
case PHY_TEST_PATTERN_CP2520_2:
test_pattern = DP_TEST_PATTERN_CP2520_2;
/* CP2520 pattern is unstable, temporarily use TPS4 instead */
test_pattern = (force_tps4_for_cp2520 == 1) ?
DP_TEST_PATTERN_TRAINING_PATTERN4 :
DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
break;
case PHY_TEST_PATTERN_CP2520_3:
test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;

View File

@ -89,12 +89,12 @@ void dp_enable_link_phy(
if (dc_is_dp_sst_signal(signal)) {
if (signal == SIGNAL_TYPE_EDP) {
link_enc->funcs->power_control(link_enc, true);
link->dc->hwss.edp_power_control(link->link_enc, true);
link_enc->funcs->enable_dp_output(
link_enc,
link_settings,
clock_source);
link_enc->funcs->backlight_control(link_enc, true);
link->dc->hwss.edp_backlight_control(link, true);
} else
link_enc->funcs->enable_dp_output(
link_enc,
@ -138,12 +138,12 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
dp_receiver_power_ctrl(link, false);
if (signal == SIGNAL_TYPE_EDP) {
link->link_enc->funcs->backlight_control(link->link_enc, false);
link->dc->hwss.edp_backlight_control(link, false);
edp_receiver_ready_T9(link);
link->link_enc->funcs->disable_output(link->link_enc, signal);
link->link_enc->funcs->power_control(link->link_enc, false);
link->link_enc->funcs->disable_output(link->link_enc, signal, link);
link->dc->hwss.edp_power_control(link->link_enc, false);
} else
link->link_enc->funcs->disable_output(link->link_enc, signal);
link->link_enc->funcs->disable_output(link->link_enc, signal, link);
/* Clear current link setting.*/
memset(&link->cur_link_settings, 0,
@ -282,11 +282,12 @@ void dp_retrain_link_dp_test(struct dc_link *link,
dp_receiver_power_ctrl(link, false);
link->dc->hwss.disable_stream(&pipes[i]);
link->dc->hwss.disable_stream(&pipes[i], KEEP_ACQUIRED_RESOURCE);
link->link_enc->funcs->disable_output(
link->link_enc,
SIGNAL_TYPE_DISPLAY_PORT);
SIGNAL_TYPE_DISPLAY_PORT,
link);
/* Clear current link setting. */
memset(&link->cur_link_settings, 0,

View File

@ -31,6 +31,7 @@
#include "opp.h"
#include "timing_generator.h"
#include "transform.h"
#include "dpp.h"
#include "core_types.h"
#include "set_mode_types.h"
#include "virtual/virtual_stream_encoder.h"
@ -242,7 +243,10 @@ bool resource_construct(
pool->stream_enc_count++;
}
}
dc->caps.dynamic_audio = false;
if (pool->audio_count < pool->stream_enc_count) {
dc->caps.dynamic_audio = true;
}
for (i = 0; i < num_virtual_links; i++) {
pool->stream_enc[pool->stream_enc_count] =
virtual_stream_encoder_create(
@ -846,12 +850,20 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
*/
pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable;
pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable;
pipe_ctx->plane_res.scl_data.recout.x += timing->h_border_left;
pipe_ctx->plane_res.scl_data.recout.y += timing->v_border_top;
pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable + timing->h_border_left + timing->h_border_right;
pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable + timing->v_border_top + timing->v_border_bottom;
/* Taps calculations */
res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
if (pipe_ctx->plane_res.xfm != NULL)
res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
if (pipe_ctx->plane_res.dpp != NULL)
res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps(
pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
if (!res) {
/* Try 24 bpp linebuffer */
@ -859,6 +871,9 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps(
pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
}
if (res)
@ -1021,9 +1036,9 @@ static int acquire_first_split_pipe(
memset(pipe_ctx, 0, sizeof(*pipe_ctx));
pipe_ctx->stream_res.tg = pool->timing_generators[i];
pipe_ctx->plane_res.mi = pool->mis[i];
pipe_ctx->plane_res.hubp = pool->hubps[i];
pipe_ctx->plane_res.ipp = pool->ipps[i];
pipe_ctx->plane_res.xfm = pool->transforms[i];
pipe_ctx->plane_res.dpp = pool->dpps[i];
pipe_ctx->stream_res.opp = pool->opps[i];
pipe_ctx->pipe_idx = i;
@ -1070,9 +1085,6 @@ bool dc_add_plane_to_context(
return false;
}
/* retain new surfaces */
dc_plane_state_retain(plane_state);
free_pipe = acquire_free_pipe_for_stream(context, pool, stream);
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
@ -1082,11 +1094,11 @@ bool dc_add_plane_to_context(
free_pipe = &context->res_ctx.pipe_ctx[pipe_idx];
}
#endif
if (!free_pipe) {
stream_status->plane_states[i] = NULL;
if (!free_pipe)
return false;
}
/* retain new surfaces */
dc_plane_state_retain(plane_state);
free_pipe->plane_state = plane_state;
if (head_pipe != free_pipe) {
@ -1178,8 +1190,8 @@ bool dc_remove_plane_from_context(
stream_status->plane_count--;
/* Trim back arrays */
for (i = 0; i < stream_status->plane_count; i++)
/* Start at the plane we've just released, and move all the planes one index forward to "trim" the array */
for (; i < stream_status->plane_count; i++)
stream_status->plane_states[i] = stream_status->plane_states[i + 1];
stream_status->plane_states[stream_status->plane_count] = NULL;
@ -1312,6 +1324,28 @@ bool dc_is_stream_unchanged(
return true;
}
bool dc_is_stream_scaling_unchanged(
struct dc_stream_state *old_stream, struct dc_stream_state *stream)
{
if (old_stream == stream)
return true;
if (old_stream == NULL || stream == NULL)
return false;
if (memcmp(&old_stream->src,
&stream->src,
sizeof(struct rect)) != 0)
return false;
if (memcmp(&old_stream->dst,
&stream->dst,
sizeof(struct rect)) != 0)
return false;
return true;
}
/* Maximum TMDS single link pixel clock 165MHz */
#define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000
@ -1330,7 +1364,7 @@ static void update_stream_engine_usage(
}
/* TODO: release audio object */
static void update_audio_usage(
void update_audio_usage(
struct resource_context *res_ctx,
const struct resource_pool *pool,
struct audio *audio,
@ -1356,8 +1390,10 @@ static int acquire_first_free_pipe(
pipe_ctx->stream_res.tg = pool->timing_generators[i];
pipe_ctx->plane_res.mi = pool->mis[i];
pipe_ctx->plane_res.hubp = pool->hubps[i];
pipe_ctx->plane_res.ipp = pool->ipps[i];
pipe_ctx->plane_res.xfm = pool->transforms[i];
pipe_ctx->plane_res.dpp = pool->dpps[i];
pipe_ctx->stream_res.opp = pool->opps[i];
pipe_ctx->pipe_idx = i;
@ -1414,12 +1450,17 @@ static struct audio *find_first_free_audio(
const struct resource_pool *pool)
{
int i;
for (i = 0; i < pool->audio_count; i++) {
if ((res_ctx->is_audio_acquired[i] == false) && (res_ctx->is_stream_enc_acquired[i] == true)) {
return pool->audios[i];
}
}
/*not found the matching one, first come first serve*/
for (i = 0; i < pool->audio_count; i++) {
if (res_ctx->is_audio_acquired[i] == false) {
return pool->audios[i];
}
}
return 0;
}
@ -1438,7 +1479,7 @@ bool resource_is_stream_unchanged(
return false;
}
bool dc_add_stream_to_ctx(
enum dc_status dc_add_stream_to_ctx(
struct dc *dc,
struct dc_state *new_ctx,
struct dc_stream_state *stream)
@ -1459,10 +1500,10 @@ bool dc_add_stream_to_ctx(
if (res != DC_OK)
DC_ERROR("Adding stream %p to context failed with err %d!\n", stream, res);
return res == DC_OK;
return res;
}
bool dc_remove_stream_from_ctx(
enum dc_status dc_remove_stream_from_ctx(
struct dc *dc,
struct dc_state *new_ctx,
struct dc_stream_state *stream)
@ -1632,10 +1673,11 @@ enum dc_status resource_map_pool_resources(
/* acquire new resources */
pipe_idx = acquire_first_free_pipe(&context->res_ctx, pool, stream);
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
#ifdef CONFIG_DRM_AMD_DC_DCN1_0
if (pipe_idx < 0)
acquire_first_split_pipe(&context->res_ctx, pool, stream);
pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream);
#endif
if (pipe_idx < 0)
return DC_NO_CONTROLLER_RESOURCE;
@ -1716,17 +1758,18 @@ void dc_resource_state_construct(
dst_ctx->dis_clk = dc->res_pool->display_clock;
}
bool dc_validate_global_state(
enum dc_status dc_validate_global_state(
struct dc *dc,
struct dc_state *new_ctx)
{
enum dc_status result = DC_ERROR_UNEXPECTED;
int i, j;
if (dc->res_pool->funcs->validate_global &&
dc->res_pool->funcs->validate_global(
dc, new_ctx) != DC_OK)
return false;
if (dc->res_pool->funcs->validate_global) {
result = dc->res_pool->funcs->validate_global(dc, new_ctx);
if (result != DC_OK)
return result;
}
for (i = 0; new_ctx && i < new_ctx->stream_count; i++) {
struct dc_stream_state *stream = new_ctx->streams[i];
@ -2713,7 +2756,7 @@ void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream,
fmt_bit_depth->pixel_encoding = pixel_encoding;
}
bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
{
struct dc *core_dc = dc;
struct dc_link *link = stream->sink->link;
@ -2737,16 +2780,16 @@ bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
link,
&stream->timing);
return res == DC_OK;
return res;
}
bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state)
enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state)
{
struct dc *core_dc = dc;
enum dc_status res = DC_OK;
/* TODO For now validates pixel format only */
if (core_dc->res_pool->funcs->validate_plane)
return core_dc->res_pool->funcs->validate_plane(plane_state) == DC_OK;
if (dc->res_pool->funcs->validate_plane)
return dc->res_pool->funcs->validate_plane(plane_state, &dc->caps);
return true;
return res;
}

View File

@ -173,7 +173,7 @@ struct dc_stream_status *dc_stream_get_status(
* Update the cursor attributes and set cursor surface address
*/
bool dc_stream_set_cursor_attributes(
const struct dc_stream_state *stream,
struct dc_stream_state *stream,
const struct dc_cursor_attributes *attributes)
{
int i;
@ -189,21 +189,51 @@ bool dc_stream_set_cursor_attributes(
return false;
}
if (attributes->address.quad_part == 0) {
dm_output_to_console("DC: Cursor address is 0!\n");
return false;
}
core_dc = stream->ctx->dc;
res_ctx = &core_dc->current_state->res_ctx;
for (i = 0; i < MAX_PIPES; i++) {
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
if (pipe_ctx->stream != stream || !pipe_ctx->plane_res.ipp)
if (pipe_ctx->stream != stream || (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp))
continue;
if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
continue;
pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
pipe_ctx->plane_res.ipp, attributes);
if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes != NULL)
pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
pipe_ctx->plane_res.ipp, attributes);
if (pipe_ctx->plane_res.hubp != NULL &&
pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes != NULL)
pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
pipe_ctx->plane_res.hubp, attributes);
if (pipe_ctx->plane_res.mi != NULL &&
pipe_ctx->plane_res.mi->funcs->set_cursor_attributes != NULL)
pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
pipe_ctx->plane_res.mi, attributes);
if (pipe_ctx->plane_res.xfm != NULL &&
pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes != NULL)
pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
pipe_ctx->plane_res.xfm, attributes);
if (pipe_ctx->plane_res.dpp != NULL &&
pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes != NULL)
pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
pipe_ctx->plane_res.dpp, attributes);
}
stream->cursor_attributes = *attributes;
return true;
}
@ -231,6 +261,10 @@ bool dc_stream_set_cursor_position(
for (i = 0; i < MAX_PIPES; i++) {
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
struct mem_input *mi = pipe_ctx->plane_res.mi;
struct hubp *hubp = pipe_ctx->plane_res.hubp;
struct transform *xfm = pipe_ctx->plane_res.xfm;
struct dpp *dpp = pipe_ctx->plane_res.dpp;
struct dc_cursor_position pos_cpy = *position;
struct dc_cursor_mi_param param = {
.pixel_clk_khz = stream->timing.pix_clk_khz,
@ -241,7 +275,9 @@ bool dc_stream_set_cursor_position(
};
if (pipe_ctx->stream != stream ||
!pipe_ctx->plane_res.ipp || !pipe_ctx->plane_state)
(!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) ||
!pipe_ctx->plane_state ||
(!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp))
continue;
if (pipe_ctx->plane_state->address.type
@ -251,7 +287,22 @@ bool dc_stream_set_cursor_position(
if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
pos_cpy.enable = false;
ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
if (ipp->funcs->ipp_cursor_set_position != NULL)
ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
if (mi != NULL && mi->funcs->set_cursor_position != NULL)
mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
if (hubp != NULL && hubp->funcs->set_cursor_position != NULL)
hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
if (xfm != NULL && xfm->funcs->set_cursor_position != NULL)
xfm->funcs->set_cursor_position(xfm, &pos_cpy, &param, hubp->curs_attr.width);
if (dpp != NULL && dpp->funcs->set_cursor_position != NULL)
dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width);
}
return true;

View File

@ -30,6 +30,7 @@
/* DC core (private) */
#include "core_types.h"
#include "transform.h"
#include "dpp.h"
/*******************************************************************************
* Private functions

View File

@ -38,7 +38,7 @@
#include "inc/compressor.h"
#include "dml/display_mode_lib.h"
#define DC_VER "3.1.01"
#define DC_VER "3.1.07"
#define MAX_SURFACES 3
#define MAX_STREAMS 6
@ -56,11 +56,12 @@ struct dc_caps {
uint32_t max_planes;
uint32_t max_downscale_ratio;
uint32_t i2c_speed_in_khz;
unsigned int max_cursor_size;
unsigned int max_video_width;
bool dcc_const_color;
bool dynamic_audio;
};
struct dc_dcc_surface_param {
struct dc_size surface_size;
enum surface_pixel_format format;
@ -132,6 +133,10 @@ struct dc_stream_state_funcs {
void (*set_dither_option)(struct dc_stream_state *stream,
enum dc_dither_option option);
void (*set_dpms)(struct dc *dc,
struct dc_stream_state *stream,
bool dpms_off);
};
struct link_training_settings;
@ -162,6 +167,23 @@ struct dc_config {
bool disable_disp_pll_sharing;
};
enum dcc_option {
DCC_ENABLE = 0,
DCC_DISABLE = 1,
DCC_HALF_REQ_DISALBE = 2,
};
enum pipe_split_policy {
MPC_SPLIT_DYNAMIC = 0,
MPC_SPLIT_AVOID = 1,
MPC_SPLIT_AVOID_MULT_DISP = 2,
};
enum wm_report_mode {
WM_REPORT_DEFAULT = 0,
WM_REPORT_OVERRIDE = 1,
};
struct dc_debug {
bool surface_visual_confirm;
bool sanity_checks;
@ -170,14 +192,21 @@ struct dc_debug {
bool timing_trace;
bool clock_trace;
bool validation_trace;
/* stutter efficiency related */
bool disable_stutter;
bool disable_dcc;
bool use_max_lb;
enum dcc_option disable_dcc;
enum pipe_split_policy pipe_split_policy;
bool force_single_disp_pipe_split;
bool voltage_align_fclk;
bool disable_dfs_bypass;
bool disable_dpp_power_gate;
bool disable_hubp_power_gate;
bool disable_pplib_wm_range;
bool use_dml_wm;
bool disable_pipe_split;
enum wm_report_mode pplib_wm_report_mode;
unsigned int min_disp_clk_khz;
int sr_exit_time_dpm0_ns;
int sr_enter_plus_exit_time_dpm0_ns;
int sr_exit_time_ns;
@ -191,6 +220,11 @@ struct dc_debug {
bool disable_dmcu;
bool disable_psr;
bool force_abm_enable;
bool disable_hbup_pg;
bool disable_dpp_pg;
bool disable_stereo_support;
bool vsr_support;
bool performance_trace;
};
struct dc_state;
struct resource_pool;
@ -233,7 +267,7 @@ struct dc {
struct dm_pp_display_configuration prev_display_config;
/* FBC compressor */
#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
struct compressor *fbc_compressor;
#endif
};
@ -268,7 +302,7 @@ struct dc_init_data {
struct dc_config flags;
uint32_t log_mask;
#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
uint64_t fbc_gpu_addr;
#endif
};
@ -285,6 +319,38 @@ enum {
TRANSFER_FUNC_POINTS = 1025
};
// Moved here from color module for linux
enum color_transfer_func {
transfer_func_unknown,
transfer_func_srgb,
transfer_func_bt709,
transfer_func_pq2084,
transfer_func_pq2084_interim,
transfer_func_linear_0_1,
transfer_func_linear_0_125,
transfer_func_dolbyvision,
transfer_func_gamma_22,
transfer_func_gamma_26
};
enum color_color_space {
color_space_unsupported,
color_space_srgb,
color_space_bt601,
color_space_bt709,
color_space_xv_ycc_bt601,
color_space_xv_ycc_bt709,
color_space_xr_rgb,
color_space_bt2020,
color_space_adobe,
color_space_dci_p3,
color_space_sc_rgb_ms_ref,
color_space_display_native,
color_space_app_ctrl,
color_space_dolby_vision,
color_space_custom_coordinates
};
struct dc_hdr_static_metadata {
/* display chromaticities and white point in units of 0.00001 */
unsigned int chromaticity_green_x;
@ -365,6 +431,12 @@ struct dc_plane_state {
struct dc_gamma *gamma_correction;
struct dc_transfer_func *in_transfer_func;
// sourceContentAttribute cache
bool is_source_input_valid;
struct dc_hdr_static_metadata source_input_mastering_info;
enum color_color_space source_input_color_space;
enum color_transfer_func source_input_tf;
enum dc_color_space color_space;
enum surface_pixel_format format;
enum dc_rotation_angle rotation;
@ -449,23 +521,6 @@ struct dc_flip_addrs {
/* TODO: add flip duration for FreeSync */
};
/*
* Set up surface attributes and associate to a stream
* The surfaces parameter is an absolute set of all surface active for the stream.
* If no surfaces are provided, the stream will be blanked; no memory read.
* Any flip related attribute changes must be done through this interface.
*
* After this call:
* Surfaces attributes are programmed and configured to be composed into stream.
* This does not trigger a flip. No surface address is programmed.
*/
bool dc_commit_planes_to_stream(
struct dc *dc,
struct dc_plane_state **plane_states,
uint8_t new_plane_count,
struct dc_stream_state *stream);
bool dc_post_update_surfaces_to_stream(
struct dc *dc);
@ -554,9 +609,12 @@ struct dc_stream_state {
int phy_pix_clk;
enum signal_type signal;
bool dpms_off;
struct dc_stream_status status;
struct dc_cursor_attributes cursor_attributes;
/* from stream struct */
struct kref refcount;
};
@ -569,11 +627,10 @@ struct dc_stream_update {
bool dc_is_stream_unchanged(
struct dc_stream_state *old_stream, struct dc_stream_state *stream);
bool dc_is_stream_scaling_unchanged(
struct dc_stream_state *old_stream, struct dc_stream_state *stream);
/*
* Setup stream attributes if no stream updates are provided
* there will be no impact on the stream parameters
*
* Set up surface attributes and associate to a stream
* The surfaces parameter is an absolute set of all surface active for the stream.
* If no surfaces are provided, the stream will be blanked; no memory read.
@ -582,14 +639,22 @@ bool dc_is_stream_unchanged(
* After this call:
* Surfaces attributes are programmed and configured to be composed into stream.
* This does not trigger a flip. No surface address is programmed.
*
*/
void dc_update_planes_and_stream(struct dc *dc,
struct dc_surface_update *surface_updates, int surface_count,
bool dc_commit_planes_to_stream(
struct dc *dc,
struct dc_plane_state **plane_states,
uint8_t new_plane_count,
struct dc_stream_state *dc_stream,
struct dc_stream_update *stream_update);
struct dc_state *state);
void dc_commit_updates_for_stream(struct dc *dc,
struct dc_surface_update *srf_updates,
int surface_count,
struct dc_stream_state *stream,
struct dc_stream_update *stream_update,
struct dc_plane_state **plane_states,
struct dc_state *state);
/*
* Log the current stream state.
*/
@ -616,12 +681,12 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream,
uint32_t *h_position,
uint32_t *v_position);
bool dc_add_stream_to_ctx(
enum dc_status dc_add_stream_to_ctx(
struct dc *dc,
struct dc_state *new_ctx,
struct dc_stream_state *stream);
bool dc_remove_stream_from_ctx(
enum dc_status dc_remove_stream_from_ctx(
struct dc *dc,
struct dc_state *new_ctx,
struct dc_stream_state *stream);
@ -660,11 +725,11 @@ struct dc_validation_set {
uint8_t plane_count;
};
bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream);
enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream);
bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state);
enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state);
bool dc_validate_global_state(
enum dc_status dc_validate_global_state(
struct dc *dc,
struct dc_state *new_ctx);
@ -991,7 +1056,7 @@ struct dc_sink *dc_sink_create(const struct dc_sink_init_data *init_params);
******************************************************************************/
/* TODO: Deprecated once we switch to dc_set_cursor_position */
bool dc_stream_set_cursor_attributes(
const struct dc_stream_state *stream,
struct dc_stream_state *stream,
const struct dc_cursor_attributes *attributes);
bool dc_stream_set_cursor_position(

View File

@ -204,6 +204,8 @@ enum surface_pixel_format {
/*grow 444 video here if necessary */
};
/* Pixel format */
enum pixel_format {
/*graph*/

View File

@ -92,7 +92,7 @@ struct dc_context {
bool created_bios;
struct gpio_service *gpio_service;
struct i2caux *i2caux;
#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
uint64_t fbc_gpu_addr;
#endif
};
@ -151,6 +151,7 @@ enum dc_edid_status {
EDID_BAD_INPUT,
EDID_NO_RESPONSE,
EDID_BAD_CHECKSUM,
EDID_THE_SAME,
};
/* audio capability from EDID*/

View File

@ -27,6 +27,10 @@
#include "hw_sequencer.h"
#define BL_REG_LIST()\
SR(LVTMA_PWRSEQ_CNTL), \
SR(LVTMA_PWRSEQ_STATE)
#define HWSEQ_DCEF_REG_LIST_DCE8() \
.DCFE_CLOCK_CONTROL[0] = mmCRTC0_CRTC_DCFE_CLOCK_CONTROL, \
.DCFE_CLOCK_CONTROL[1] = mmCRTC1_CRTC_DCFE_CLOCK_CONTROL, \
@ -86,24 +90,27 @@
SRII(BLND_CONTROL, BLND, 0),\
SRII(BLND_CONTROL, BLND, 1),\
SR(BLNDV_CONTROL),\
HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
HWSEQ_PIXEL_RATE_REG_LIST(CRTC),\
BL_REG_LIST()
#define HWSEQ_DCE8_REG_LIST() \
HWSEQ_DCEF_REG_LIST_DCE8(), \
HWSEQ_BLND_REG_LIST(), \
HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
HWSEQ_PIXEL_RATE_REG_LIST(CRTC),\
BL_REG_LIST()
#define HWSEQ_DCE10_REG_LIST() \
HWSEQ_DCEF_REG_LIST(), \
HWSEQ_BLND_REG_LIST(), \
HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
HWSEQ_PIXEL_RATE_REG_LIST(CRTC), \
BL_REG_LIST()
#define HWSEQ_ST_REG_LIST() \
HWSEQ_DCE11_REG_LIST_BASE(), \
.DCFE_CLOCK_CONTROL[2] = mmDCFEV_CLOCK_CONTROL, \
.CRTC_H_BLANK_START_END[2] = mmCRTCV_H_BLANK_START_END, \
.BLND_V_UPDATE_LOCK[2] = mmBLNDV_V_UPDATE_LOCK, \
.BLND_CONTROL[2] = mmBLNDV_CONTROL,
.BLND_CONTROL[2] = mmBLNDV_CONTROL
#define HWSEQ_CZ_REG_LIST() \
HWSEQ_DCE11_REG_LIST_BASE(), \
@ -123,16 +130,16 @@
SR(DCHUB_FB_LOCATION),\
SR(DCHUB_AGP_BASE),\
SR(DCHUB_AGP_BOT),\
SR(DCHUB_AGP_TOP)
SR(DCHUB_AGP_TOP), \
BL_REG_LIST()
#define HWSEQ_DCE112_REG_LIST() \
HWSEQ_DCE10_REG_LIST(), \
HWSEQ_PIXEL_RATE_REG_LIST(CRTC), \
HWSEQ_PHYPLL_REG_LIST(CRTC)
HWSEQ_PHYPLL_REG_LIST(CRTC), \
BL_REG_LIST()
#define HWSEQ_DCN_REG_LIST()\
HWSEQ_PIXEL_RATE_REG_LIST(OTG), \
HWSEQ_PHYPLL_REG_LIST(OTG), \
SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 0), \
SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 1), \
SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 2), \
@ -156,23 +163,15 @@
SR(REFCLK_CNTL), \
SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A),\
SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A),\
SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\
SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A),\
SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A),\
SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B),\
SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B),\
SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B),\
SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B),\
SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B),\
SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C),\
SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C),\
SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C),\
SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C),\
SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C),\
SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D),\
SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D),\
SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D),\
SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D),\
SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D),\
SR(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL),\
SR(DCHUBBUB_ARB_DRAM_STATE_CNTL),\
@ -181,7 +180,46 @@
SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
SR(DCHUBBUB_TEST_DEBUG_INDEX), \
SR(DCHUBBUB_TEST_DEBUG_DATA), \
SR(DC_IP_REQUEST_CNTL), \
SR(DIO_MEM_PWR_CTRL), \
SR(DCCG_GATE_DISABLE_CNTL), \
SR(DCCG_GATE_DISABLE_CNTL2), \
SR(DCFCLK_CNTL),\
SR(DCFCLK_CNTL), \
/* todo: get these from GVM instead of reading registers ourselves */\
MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32),\
MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32),\
MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32),\
MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32),\
MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32),\
MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32),\
MMHUB_SR(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32),\
MMHUB_SR(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32),\
MMHUB_SR(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB),\
MMHUB_SR(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB),\
MMHUB_SR(MC_VM_SYSTEM_APERTURE_LOW_ADDR),\
MMHUB_SR(MC_VM_SYSTEM_APERTURE_HIGH_ADDR)
#define HWSEQ_SR_WATERMARK_REG_LIST()\
SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\
SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A),\
SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B),\
SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B),\
SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C),\
SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C),\
SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D),\
SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D)
#define HWSEQ_DCN1_REG_LIST()\
HWSEQ_DCN_REG_LIST(), \
HWSEQ_SR_WATERMARK_REG_LIST(), \
HWSEQ_PIXEL_RATE_REG_LIST(OTG), \
HWSEQ_PHYPLL_REG_LIST(OTG), \
SR(DCHUBBUB_SDPIF_FB_TOP),\
SR(DCHUBBUB_SDPIF_FB_BASE),\
SR(DCHUBBUB_SDPIF_FB_OFFSET),\
SR(DCHUBBUB_SDPIF_AGP_BASE),\
SR(DCHUBBUB_SDPIF_AGP_BOT),\
SR(DCHUBBUB_SDPIF_AGP_TOP),\
SR(DOMAIN0_PG_CONFIG), \
SR(DOMAIN1_PG_CONFIG), \
SR(DOMAIN2_PG_CONFIG), \
@ -198,40 +236,19 @@
SR(DOMAIN5_PG_STATUS), \
SR(DOMAIN6_PG_STATUS), \
SR(DOMAIN7_PG_STATUS), \
SR(DIO_MEM_PWR_CTRL), \
SR(DCCG_GATE_DISABLE_CNTL), \
SR(DCCG_GATE_DISABLE_CNTL2), \
SR(DCFCLK_CNTL),\
SR(DCFCLK_CNTL), \
SR(D1VGA_CONTROL), \
SR(D2VGA_CONTROL), \
SR(D3VGA_CONTROL), \
SR(D4VGA_CONTROL), \
/* todo: get these from GVM instead of reading registers ourselves */\
MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32),\
MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32),\
MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32),\
MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32),\
MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32),\
MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32),\
MMHUB_SR(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32),\
MMHUB_SR(VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32),\
MMHUB_SR(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB),\
MMHUB_SR(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB),\
MMHUB_SR(MC_VM_SYSTEM_APERTURE_LOW_ADDR),\
MMHUB_SR(MC_VM_SYSTEM_APERTURE_HIGH_ADDR)
#define HWSEQ_DCN1_REG_LIST()\
HWSEQ_DCN_REG_LIST(), \
SR(DCHUBBUB_SDPIF_FB_TOP),\
SR(DCHUBBUB_SDPIF_FB_BASE),\
SR(DCHUBBUB_SDPIF_FB_OFFSET),\
SR(DCHUBBUB_SDPIF_AGP_BASE),\
SR(DCHUBBUB_SDPIF_AGP_BOT),\
SR(DCHUBBUB_SDPIF_AGP_TOP)
SR(DC_IP_REQUEST_CNTL), \
BL_REG_LIST()
struct dce_hwseq_registers {
/* Backlight registers */
uint32_t LVTMA_PWRSEQ_CNTL;
uint32_t LVTMA_PWRSEQ_STATE;
uint32_t DCFE_CLOCK_CONTROL[6];
uint32_t DCFEV_CLOCK_CONTROL;
uint32_t DC_MEM_GLOBAL_PWR_REQ_CNTL;
@ -376,20 +393,28 @@ struct dce_hwseq_registers {
HWS_SF(BLND_, V_UPDATE_LOCK, BLND_SCL_V_UPDATE_LOCK, mask_sh),\
HWS_SF(BLND_, V_UPDATE_LOCK, BLND_DCP_GRPH_SURF_V_UPDATE_LOCK, mask_sh),\
HWS_SF(BLND_, CONTROL, BLND_MODE, mask_sh),\
HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\
HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\
HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
#define HWSEQ_DCE10_MASK_SH_LIST(mask_sh)\
HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE_),\
HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND_),\
HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_), \
HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
#define HWSEQ_DCE11_MASK_SH_LIST(mask_sh)\
HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\
SF(DCFEV_CLOCK_CONTROL, DCFEV_CLOCK_ENABLE, mask_sh),\
HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\
HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\
HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
#define HWSEQ_DCE112_MASK_SH_LIST(mask_sh)\
HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\
HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\
HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\
HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_)
#define HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh)\
@ -397,14 +422,18 @@ struct dce_hwseq_registers {
SF(DCHUB_FB_LOCATION, FB_BASE, mask_sh),\
SF(DCHUB_AGP_BASE, AGP_BASE, mask_sh),\
SF(DCHUB_AGP_BOT, AGP_BOT, mask_sh),\
SF(DCHUB_AGP_TOP, AGP_TOP, mask_sh)
SF(DCHUB_AGP_TOP, AGP_TOP, mask_sh), \
HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
#define HWSEQ_DCE12_MASK_SH_LIST(mask_sh)\
HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE0_DCFE_),\
HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND0_BLND_),\
HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_),\
HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_),\
HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh)
HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh), \
HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
#define HWSEQ_DCN_MASK_SH_LIST(mask_sh)\
HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, OTG0_),\
@ -416,7 +445,36 @@ struct dce_hwseq_registers {
HWS_SF(DPP_TOP0_, DPP_CONTROL, DPP_CLOCK_ENABLE, mask_sh), \
HWS_SF(OPP_PIPE0_, OPP_PIPE_CONTROL, OPP_PIPE_CLOCK_EN, mask_sh),\
HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \
HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_SAT_LEVEL, DCHUBBUB_ARB_SAT_LEVEL, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh), \
HWS_SF(, DCFCLK_CNTL, DCFCLK_GATE_DIS, mask_sh)
#define HWSEQ_DCN1_MASK_SH_LIST(mask_sh)\
HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
HWS_SF1(OTG0_, PHYPLL_PIXEL_RATE_CNTL, PIXEL_RATE_PLL_SOURCE, mask_sh), \
HWS_SF(, DCHUBBUB_SDPIF_FB_TOP, SDPIF_FB_TOP, mask_sh), \
HWS_SF(, DCHUBBUB_SDPIF_FB_BASE, SDPIF_FB_BASE, mask_sh), \
HWS_SF(, DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, mask_sh), \
HWS_SF(, DCHUBBUB_SDPIF_AGP_BASE, SDPIF_AGP_BASE, mask_sh), \
HWS_SF(, DCHUBBUB_SDPIF_AGP_BOT, SDPIF_AGP_BOT, mask_sh), \
HWS_SF(, DCHUBBUB_SDPIF_AGP_TOP, SDPIF_AGP_TOP, mask_sh), \
HWS_SF(DPP_TOP0_, DPP_CONTROL, DPPCLK_RATE_CONTROL, mask_sh), \
/* todo: get these from GVM instead of reading registers ourselves */\
HWS_SF(, VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, PAGE_DIRECTORY_ENTRY_HI32, mask_sh),\
HWS_SF(, VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, PAGE_DIRECTORY_ENTRY_LO32, mask_sh),\
HWS_SF(, VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32, LOGICAL_PAGE_NUMBER_HI4, mask_sh),\
HWS_SF(, VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, LOGICAL_PAGE_NUMBER_LO32, mask_sh),\
HWS_SF(, VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32, PHYSICAL_PAGE_ADDR_HI4, mask_sh),\
HWS_SF(, VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32, PHYSICAL_PAGE_ADDR_LO32, mask_sh),\
HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, PHYSICAL_PAGE_NUMBER_MSB, mask_sh),\
HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, PHYSICAL_PAGE_NUMBER_LSB, mask_sh),\
HWS_SF(, MC_VM_SYSTEM_APERTURE_LOW_ADDR, LOGICAL_ADDR, mask_sh),\
HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
@ -441,34 +499,9 @@ struct dce_hwseq_registers {
HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_SAT_LEVEL, DCHUBBUB_ARB_SAT_LEVEL, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh), \
HWS_SF(, DCFCLK_CNTL, DCFCLK_GATE_DIS, mask_sh)
#define HWSEQ_DCN1_MASK_SH_LIST(mask_sh)\
HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
HWS_SF1(OTG0_, PHYPLL_PIXEL_RATE_CNTL, PIXEL_RATE_PLL_SOURCE, mask_sh), \
HWS_SF(, DCHUBBUB_SDPIF_FB_TOP, SDPIF_FB_TOP, mask_sh), \
HWS_SF(, DCHUBBUB_SDPIF_FB_BASE, SDPIF_FB_BASE, mask_sh), \
HWS_SF(, DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, mask_sh), \
HWS_SF(, DCHUBBUB_SDPIF_AGP_BASE, SDPIF_AGP_BASE, mask_sh), \
HWS_SF(, DCHUBBUB_SDPIF_AGP_BOT, SDPIF_AGP_BOT, mask_sh), \
HWS_SF(, DCHUBBUB_SDPIF_AGP_TOP, SDPIF_AGP_TOP, mask_sh), \
HWS_SF(DPP_TOP0_, DPP_CONTROL, DPPCLK_RATE_CONTROL, mask_sh), \
/* todo: get these from GVM instead of reading registers ourselves */\
HWS_SF(, VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, PAGE_DIRECTORY_ENTRY_HI32, mask_sh),\
HWS_SF(, VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, PAGE_DIRECTORY_ENTRY_LO32, mask_sh),\
HWS_SF(, VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32, LOGICAL_PAGE_NUMBER_HI4, mask_sh),\
HWS_SF(, VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, LOGICAL_PAGE_NUMBER_LO32, mask_sh),\
HWS_SF(, VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32, PHYSICAL_PAGE_ADDR_HI4, mask_sh),\
HWS_SF(, VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32, PHYSICAL_PAGE_ADDR_LO32, mask_sh),\
HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, PHYSICAL_PAGE_NUMBER_MSB, mask_sh),\
HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, PHYSICAL_PAGE_NUMBER_LSB, mask_sh),\
HWS_SF(, MC_VM_SYSTEM_APERTURE_LOW_ADDR, LOGICAL_ADDR, mask_sh)
HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
#define HWSEQ_REG_FIELD_LIST(type) \
type DCFE_CLOCK_ENABLE; \
@ -498,7 +531,9 @@ struct dce_hwseq_registers {
type PHYSICAL_PAGE_NUMBER_LSB;\
type LOGICAL_ADDR; \
type ENABLE_L1_TLB;\
type SYSTEM_ACCESS_MODE;
type SYSTEM_ACCESS_MODE;\
type LVTMA_BLON;\
type LVTMA_PWRSEQ_TARGET_STATE_R;
#define HWSEQ_DCN_REG_FIELD_LIST(type) \
type VUPDATE_NO_LOCK_EVENT_CLEAR; \
@ -524,6 +559,8 @@ struct dce_hwseq_registers {
type DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE;\
type DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE;\
type DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE;\
type DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE;\
type DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE;\
type DCHUBBUB_ARB_SAT_LEVEL;\
type DCHUBBUB_ARB_MIN_REQ_OUTSTAND;\
type OPP_PIPE_CLOCK_EN;\

View File

@ -37,6 +37,7 @@
#define CTX \
ipp_dce->base.ctx
static void dce_ipp_cursor_set_position(
struct input_pixel_processor *ipp,
const struct dc_cursor_position *position,
@ -133,6 +134,7 @@ static void dce_ipp_cursor_set_attributes(
REG_UPDATE(CUR_UPDATE, CURSOR_UPDATE_LOCK, false);
}
static void dce_ipp_program_prescale(
struct input_pixel_processor *ipp,
struct ipp_prescale_params *params)

View File

@ -82,13 +82,6 @@
#define DCE110_DIG_FE_SOURCE_SELECT_DIGF 0x20
#define DCE110_DIG_FE_SOURCE_SELECT_DIGG 0x40
/* all values are in milliseconds */
/* For eDP, after power-up/power/down,
* 300/500 msec max. delay from LCDVCC to black video generation */
#define PANEL_POWER_UP_TIMEOUT 300
#define PANEL_POWER_DOWN_TIMEOUT 500
#define HPD_CHECK_INTERVAL 10
/* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */
#define TMDS_MIN_PIXEL_CLOCK 25000
/* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */
@ -122,8 +115,6 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs = {
.psr_program_dp_dphy_fast_training =
dce110_psr_program_dp_dphy_fast_training,
.psr_program_secondary_packet = dce110_psr_program_secondary_packet,
.backlight_control = dce110_link_encoder_edp_backlight_control,
.power_control = dce110_link_encoder_edp_power_control,
.connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe,
.enable_hpd = dce110_link_encoder_enable_hpd,
.disable_hpd = dce110_link_encoder_disable_hpd,
@ -493,165 +484,6 @@ static void configure_encoder(
REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, 1);
}
static bool is_panel_powered_on(struct dce110_link_encoder *enc110)
{
bool ret;
uint32_t value;
REG_GET(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &value);
ret = value;
return ret == 1;
}
/* TODO duplicate of dc_link.c version */
static struct gpio *get_hpd_gpio(const struct link_encoder *enc)
{
enum bp_result bp_result;
struct dc_bios *dcb = enc->ctx->dc_bios;
struct graphics_object_hpd_info hpd_info;
struct gpio_pin_info pin_info;
if (dcb->funcs->get_hpd_info(dcb, enc->connector, &hpd_info) != BP_RESULT_OK)
return NULL;
bp_result = dcb->funcs->get_gpio_pin_info(dcb,
hpd_info.hpd_int_gpio_uid, &pin_info);
if (bp_result != BP_RESULT_OK) {
ASSERT(bp_result == BP_RESULT_NORECORD);
return NULL;
}
return dal_gpio_service_create_irq(
enc->ctx->gpio_service,
pin_info.offset,
pin_info.mask);
}
/*
* @brief
* eDP only.
*/
static void link_encoder_edp_wait_for_hpd_ready(
struct dce110_link_encoder *enc110,
bool power_up)
{
struct dc_context *ctx = enc110->base.ctx;
struct graphics_object_id connector = enc110->base.connector;
struct gpio *hpd;
bool edp_hpd_high = false;
uint32_t time_elapsed = 0;
uint32_t timeout = power_up ?
PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT;
if (dal_graphics_object_id_get_connector_id(connector) !=
CONNECTOR_ID_EDP) {
BREAK_TO_DEBUGGER();
return;
}
if (!power_up)
/* from KV, we will not HPD low after turning off VCC -
* instead, we will check the SW timer in power_up(). */
return;
/* when we power on/off the eDP panel,
* we need to wait until SENSE bit is high/low */
/* obtain HPD */
/* TODO what to do with this? */
hpd = get_hpd_gpio(&enc110->base);
if (!hpd) {
BREAK_TO_DEBUGGER();
return;
}
dal_gpio_open(hpd, GPIO_MODE_INTERRUPT);
/* wait until timeout or panel detected */
do {
uint32_t detected = 0;
dal_gpio_get_value(hpd, &detected);
if (!(detected ^ power_up)) {
edp_hpd_high = true;
break;
}
msleep(HPD_CHECK_INTERVAL);
time_elapsed += HPD_CHECK_INTERVAL;
} while (time_elapsed < timeout);
dal_gpio_close(hpd);
dal_gpio_destroy_irq(&hpd);
if (false == edp_hpd_high) {
dm_logger_write(ctx->logger, LOG_ERROR,
"%s: wait timed out!\n", __func__);
}
}
/*
* @brief
* eDP only. Control the power of the eDP panel.
*/
void dce110_link_encoder_edp_power_control(
struct link_encoder *enc,
bool power_up)
{
struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
struct dc_context *ctx = enc110->base.ctx;
struct bp_transmitter_control cntl = { 0 };
enum bp_result bp_result;
if (dal_graphics_object_id_get_connector_id(enc110->base.connector) !=
CONNECTOR_ID_EDP) {
BREAK_TO_DEBUGGER();
return;
}
if ((power_up && !is_panel_powered_on(enc110)) ||
(!power_up && is_panel_powered_on(enc110))) {
/* Send VBIOS command to prompt eDP panel power */
dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
"%s: Panel Power action: %s\n",
__func__, (power_up ? "On":"Off"));
cntl.action = power_up ?
TRANSMITTER_CONTROL_POWER_ON :
TRANSMITTER_CONTROL_POWER_OFF;
cntl.transmitter = enc110->base.transmitter;
cntl.connector_obj_id = enc110->base.connector;
cntl.coherent = false;
cntl.lanes_number = LANE_COUNT_FOUR;
cntl.hpd_sel = enc110->base.hpd_source;
bp_result = link_transmitter_control(enc110, &cntl);
if (BP_RESULT_OK != bp_result) {
dm_logger_write(ctx->logger, LOG_ERROR,
"%s: Panel Power bp_result: %d\n",
__func__, bp_result);
}
} else {
dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
"%s: Skipping Panel Power action: %s\n",
__func__, (power_up ? "On":"Off"));
}
link_encoder_edp_wait_for_hpd_ready(enc110, true);
}
static void aux_initialize(
struct dce110_link_encoder *enc110)
{
@ -674,16 +506,6 @@ static void aux_initialize(
}
/*todo: cloned in stream enc, fix*/
static bool is_panel_backlight_on(struct dce110_link_encoder *enc110)
{
uint32_t value;
REG_GET(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, &value);
return value;
}
void dce110_psr_program_dp_dphy_fast_training(struct link_encoder *enc,
bool exit_link_training_required)
{
@ -718,69 +540,6 @@ void dce110_psr_program_secondary_packet(struct link_encoder *enc,
DP_SEC_GSP0_PRIORITY, 1);
}
/*todo: cloned in stream enc, fix*/
/*
* @brief
* eDP only. Control the backlight of the eDP panel
*/
void dce110_link_encoder_edp_backlight_control(
struct link_encoder *enc,
bool enable)
{
struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
struct dc_context *ctx = enc110->base.ctx;
struct bp_transmitter_control cntl = { 0 };
if (dal_graphics_object_id_get_connector_id(enc110->base.connector)
!= CONNECTOR_ID_EDP) {
BREAK_TO_DEBUGGER();
return;
}
if (enable && is_panel_backlight_on(enc110)) {
dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
"%s: panel already powered up. Do nothing.\n",
__func__);
return;
}
if (!enable && !is_panel_backlight_on(enc110)) {
dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
"%s: panel already powered down. Do nothing.\n",
__func__);
return;
}
/* Send VBIOS command to control eDP panel backlight */
dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
"%s: backlight action: %s\n",
__func__, (enable ? "On":"Off"));
cntl.action = enable ?
TRANSMITTER_CONTROL_BACKLIGHT_ON :
TRANSMITTER_CONTROL_BACKLIGHT_OFF;
/*cntl.engine_id = ctx->engine;*/
cntl.transmitter = enc110->base.transmitter;
cntl.connector_obj_id = enc110->base.connector;
/*todo: unhardcode*/
cntl.lanes_number = LANE_COUNT_FOUR;
cntl.hpd_sel = enc110->base.hpd_source;
/* For eDP, the following delays might need to be considered
* after link training completed:
* idle period - min. accounts for required BS-Idle pattern,
* max. allows for source frame synchronization);
* 50 msec max. delay from valid video data from source
* to video on dislpay or backlight enable.
*
* Disable the delay for now.
* Enable it in the future if necessary.
*/
/* dc_service_sleep_in_milliseconds(50); */
link_transmitter_control(enc110, &cntl);
}
static bool is_dig_enabled(const struct dce110_link_encoder *enc110)
{
uint32_t value;
@ -998,11 +757,6 @@ void dce110_link_encoder_construct(
enc110->base.preferred_engine = ENGINE_ID_UNKNOWN;
}
dm_logger_write(init_data->ctx->logger, LOG_I2C_AUX,
"Using channel: %s [%d]\n",
DECODE_CHANNEL_ID(init_data->channel),
init_data->channel);
/* Override features with DCE-specific values */
if (BP_RESULT_OK == bp_funcs->get_encoder_cap_info(
enc110->base.ctx->dc_bios, enc110->base.id,
@ -1092,7 +846,7 @@ void dce110_link_encoder_hw_init(
ASSERT(result == BP_RESULT_OK);
} else if (enc110->base.connector.id == CONNECTOR_ID_EDP) {
enc->funcs->power_control(&enc110->base, true);
ctx->dc->hwss.edp_power_control(enc, true);
}
aux_initialize(enc110);
@ -1279,7 +1033,8 @@ void dce110_link_encoder_enable_dp_mst_output(
*/
void dce110_link_encoder_disable_output(
struct link_encoder *enc,
enum signal_type signal)
enum signal_type signal,
struct dc_link *link)
{
struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
struct dc_context *ctx = enc110->base.ctx;
@ -1291,7 +1046,7 @@ void dce110_link_encoder_disable_output(
return;
}
if (enc110->base.connector.id == CONNECTOR_ID_EDP)
dce110_link_encoder_edp_backlight_control(enc, false);
ctx->dc->hwss.edp_backlight_control(link, false);
/* Power-down RX and disable GPU PHY should be paired.
* Disabling PHY without powering down RX may cause
* symbol lock loss, on which we will get DP Sink interrupt. */

View File

@ -44,8 +44,6 @@
SRI(DC_HPD_CONTROL, HPD, id)
#define LE_COMMON_REG_LIST_BASE(id) \
SR(LVTMA_PWRSEQ_CNTL), \
SR(LVTMA_PWRSEQ_STATE), \
SR(DMCU_RAM_ACCESS_CTRL), \
SR(DMCU_IRAM_RD_CTRL), \
SR(DMCU_IRAM_RD_DATA), \
@ -104,8 +102,7 @@
LE_COMMON_REG_LIST_BASE(id), \
SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \
SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \
SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id), \
SR(DMU_MEM_PWR_CNTL)
SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id)
struct dce110_link_enc_aux_registers {
uint32_t AUX_CONTROL;
@ -117,10 +114,6 @@ struct dce110_link_enc_hpd_registers {
};
struct dce110_link_enc_registers {
/* Backlight registers */
uint32_t LVTMA_PWRSEQ_CNTL;
uint32_t LVTMA_PWRSEQ_STATE;
/* DMCU registers */
uint32_t MASTER_COMM_DATA_REG1;
uint32_t MASTER_COMM_DATA_REG2;
@ -236,7 +229,8 @@ void dce110_link_encoder_enable_dp_mst_output(
/* disable PHY output */
void dce110_link_encoder_disable_output(
struct link_encoder *link_enc,
enum signal_type signal);
enum signal_type signal,
struct dc_link *link);
/* set DP lane settings */
void dce110_link_encoder_dp_set_lane_settings(
@ -252,14 +246,6 @@ void dce110_link_encoder_update_mst_stream_allocation_table(
struct link_encoder *enc,
const struct link_mst_stream_allocation_table *table);
void dce110_link_encoder_edp_backlight_control(
struct link_encoder *enc,
bool enable);
void dce110_link_encoder_edp_power_control(
struct link_encoder *enc,
bool power_up);
void dce110_link_encoder_connect_dig_be_to_fe(
struct link_encoder *enc,
enum engine_id engine,

View File

@ -361,7 +361,7 @@ static void program_grph_pixel_format(
enum surface_pixel_format format)
{
uint32_t red_xbar = 0, blue_xbar = 0; /* no swap */
uint32_t grph_depth, grph_format;
uint32_t grph_depth = 0, grph_format = 0;
uint32_t sign = 0, floating = 0;
if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 ||
@ -685,9 +685,6 @@ void dce_mem_input_construct(
dce_mi->regs = regs;
dce_mi->shifts = mi_shift;
dce_mi->masks = mi_mask;
dce_mi->base.mpcc_id = 0xf;
dce_mi->base.opp_id = 0xf;
}
void dce112_mem_input_construct(

View File

@ -743,7 +743,7 @@ static void dce100_destroy_resource_pool(struct resource_pool **pool)
*pool = NULL;
}
enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state)
enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps)
{
if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)

View File

@ -16,7 +16,7 @@ struct resource_pool *dce100_create_resource_pool(
uint8_t num_virtual_links,
struct dc *dc);
enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state);
enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps);
enum dc_status dce100_add_stream_to_ctx(
struct dc *dc,

View File

@ -514,7 +514,7 @@ void dce110_compressor_construct(struct dce110_compressor *compressor,
compressor->base.lpt_channels_num = 0;
compressor->base.attached_inst = 0;
compressor->base.is_enabled = false;
#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
compressor->base.funcs = &dce110_compressor_funcs;
#endif

View File

@ -32,8 +32,9 @@
#include "dce110_hw_sequencer.h"
#include "dce110_timing_generator.h"
#include "dce/dce_hwseq.h"
#include "gpio_service_interface.h"
#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
#include "dce110_compressor.h"
#endif
@ -45,10 +46,10 @@
#include "transform.h"
#include "stream_encoder.h"
#include "link_encoder.h"
#include "link_hwss.h"
#include "clock_source.h"
#include "abm.h"
#include "audio.h"
#include "dce/dce_hwseq.h"
#include "reg_helper.h"
/* include DCE11 register header files */
@ -56,6 +57,24 @@
#include "dce/dce_11_0_sh_mask.h"
#include "custom_float.h"
/*
* All values are in milliseconds;
* For eDP, after power-up/power/down,
* 300/500 msec max. delay from LCDVCC to black video generation
*/
#define PANEL_POWER_UP_TIMEOUT 300
#define PANEL_POWER_DOWN_TIMEOUT 500
#define HPD_CHECK_INTERVAL 10
#define CTX \
hws->ctx
#define REG(reg)\
hws->regs->reg
#undef FN
#define FN(reg_name, field_name) \
hws->shifts->field_name, hws->masks->field_name
struct dce110_hw_seq_reg_offsets {
uint32_t crtc;
};
@ -761,10 +780,216 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
}
void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
/*todo: cloned in stream enc, fix*/
static bool is_panel_backlight_on(struct dce_hwseq *hws)
{
uint32_t value;
REG_GET(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, &value);
return value;
}
static bool is_panel_powered_on(struct dce_hwseq *hws)
{
uint32_t value;
REG_GET(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &value);
return value == 1;
}
static enum bp_result link_transmitter_control(
struct dc_bios *bios,
struct bp_transmitter_control *cntl)
{
enum bp_result result;
result = bios->funcs->transmitter_control(bios, cntl);
return result;
}
/*
* @brief
* eDP only.
*/
void hwss_edp_wait_for_hpd_ready(
struct link_encoder *enc,
bool power_up)
{
struct dc_context *ctx = enc->ctx;
struct graphics_object_id connector = enc->connector;
struct gpio *hpd;
bool edp_hpd_high = false;
uint32_t time_elapsed = 0;
uint32_t timeout = power_up ?
PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT;
if (dal_graphics_object_id_get_connector_id(connector)
!= CONNECTOR_ID_EDP) {
BREAK_TO_DEBUGGER();
return;
}
if (!power_up)
/*
* From KV, we will not HPD low after turning off VCC -
* instead, we will check the SW timer in power_up().
*/
return;
/*
* When we power on/off the eDP panel,
* we need to wait until SENSE bit is high/low.
*/
/* obtain HPD */
/* TODO what to do with this? */
hpd = get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service);
if (!hpd) {
BREAK_TO_DEBUGGER();
return;
}
dal_gpio_open(hpd, GPIO_MODE_INTERRUPT);
/* wait until timeout or panel detected */
do {
uint32_t detected = 0;
dal_gpio_get_value(hpd, &detected);
if (!(detected ^ power_up)) {
edp_hpd_high = true;
break;
}
msleep(HPD_CHECK_INTERVAL);
time_elapsed += HPD_CHECK_INTERVAL;
} while (time_elapsed < timeout);
dal_gpio_close(hpd);
dal_gpio_destroy_irq(&hpd);
if (false == edp_hpd_high) {
dm_logger_write(ctx->logger, LOG_ERROR,
"%s: wait timed out!\n", __func__);
}
}
void hwss_edp_power_control(
struct link_encoder *enc,
bool power_up)
{
struct dc_context *ctx = enc->ctx;
struct dce_hwseq *hwseq = ctx->dc->hwseq;
struct bp_transmitter_control cntl = { 0 };
enum bp_result bp_result;
if (dal_graphics_object_id_get_connector_id(enc->connector)
!= CONNECTOR_ID_EDP) {
BREAK_TO_DEBUGGER();
return;
}
if (power_up != is_panel_powered_on(hwseq)) {
/* Send VBIOS command to prompt eDP panel power */
dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
"%s: Panel Power action: %s\n",
__func__, (power_up ? "On":"Off"));
cntl.action = power_up ?
TRANSMITTER_CONTROL_POWER_ON :
TRANSMITTER_CONTROL_POWER_OFF;
cntl.transmitter = enc->transmitter;
cntl.connector_obj_id = enc->connector;
cntl.coherent = false;
cntl.lanes_number = LANE_COUNT_FOUR;
cntl.hpd_sel = enc->hpd_source;
bp_result = link_transmitter_control(ctx->dc_bios, &cntl);
if (bp_result != BP_RESULT_OK)
dm_logger_write(ctx->logger, LOG_ERROR,
"%s: Panel Power bp_result: %d\n",
__func__, bp_result);
} else {
dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
"%s: Skipping Panel Power action: %s\n",
__func__, (power_up ? "On":"Off"));
}
hwss_edp_wait_for_hpd_ready(enc, true);
}
/*todo: cloned in stream enc, fix*/
/*
* @brief
* eDP only. Control the backlight of the eDP panel
*/
void hwss_edp_backlight_control(
struct dc_link *link,
bool enable)
{
struct dce_hwseq *hws = link->dc->hwseq;
struct dc_context *ctx = link->dc->ctx;
struct bp_transmitter_control cntl = { 0 };
if (dal_graphics_object_id_get_connector_id(link->link_id)
!= CONNECTOR_ID_EDP) {
BREAK_TO_DEBUGGER();
return;
}
if (enable && is_panel_backlight_on(hws)) {
dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
"%s: panel already powered up. Do nothing.\n",
__func__);
return;
}
/* Send VBIOS command to control eDP panel backlight */
dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
"%s: backlight action: %s\n",
__func__, (enable ? "On":"Off"));
cntl.action = enable ?
TRANSMITTER_CONTROL_BACKLIGHT_ON :
TRANSMITTER_CONTROL_BACKLIGHT_OFF;
/*cntl.engine_id = ctx->engine;*/
cntl.transmitter = link->link_enc->transmitter;
cntl.connector_obj_id = link->link_enc->connector;
/*todo: unhardcode*/
cntl.lanes_number = LANE_COUNT_FOUR;
cntl.hpd_sel = link->link_enc->hpd_source;
/* For eDP, the following delays might need to be considered
* after link training completed:
* idle period - min. accounts for required BS-Idle pattern,
* max. allows for source frame synchronization);
* 50 msec max. delay from valid video data from source
* to video on dislpay or backlight enable.
*
* Disable the delay for now.
* Enable it in the future if necessary.
*/
/* dc_service_sleep_in_milliseconds(50); */
link_transmitter_control(link->dc->ctx->dc_bios, &cntl);
}
void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option)
{
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->sink->link;
struct dc *dc = pipe_ctx->stream->ctx->dc;
if (pipe_ctx->stream_res.audio) {
pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
@ -775,6 +1000,13 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
else
pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable(
pipe_ctx->stream_res.stream_enc);
/*don't free audio if it is from retrain or internal disable stream*/
if (option == FREE_ACQUIRED_RESOURCE && dc->caps.dynamic_audio == true) {
/*we have to dynamic arbitrate the audio endpoints*/
pipe_ctx->stream_res.audio = NULL;
/*we free the resource, need reset is_audio_acquired*/
update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, pipe_ctx->stream_res.audio, false);
}
/* TODO: notify audio driver for if audio modes list changed
* add audio mode list change flag */
@ -798,7 +1030,7 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
/* blank at encoder level */
if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
if (pipe_ctx->stream->sink->link->connector_signal == SIGNAL_TYPE_EDP)
link->link_enc->funcs->backlight_control(link->link_enc, false);
hwss_edp_backlight_control(link, false);
pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
}
link->link_enc->funcs->connect_dig_be_to_fe(
@ -820,7 +1052,7 @@ void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
params.link_settings.link_rate = link_settings->link_rate;
pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, &params);
if (link->connector_signal == SIGNAL_TYPE_EDP)
link->link_enc->funcs->backlight_control(link->link_enc, true);
hwss_edp_backlight_control(link, true);
}
@ -1132,33 +1364,21 @@ static enum dc_status apply_single_controller_ctx_to_hw(
resource_build_info_frame(pipe_ctx);
dce110_update_info_frame(pipe_ctx);
if (!pipe_ctx_old->stream) {
core_link_enable_stream(context, pipe_ctx);
if (dc_is_dp_signal(pipe_ctx->stream->signal))
dce110_unblank_stream(pipe_ctx,
&stream->sink->link->cur_link_settings);
if (!pipe_ctx->stream->dpms_off)
core_link_enable_stream(context, pipe_ctx);
}
pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
/* program_scaler and allocate_mem_input are not new asic */
if ((!pipe_ctx_old ||
memcmp(&pipe_ctx_old->plane_res.scl_data, &pipe_ctx->plane_res.scl_data,
sizeof(struct scaler_data)) != 0) &&
pipe_ctx->plane_state) {
program_scaler(dc, pipe_ctx);
}
/* mst support - use total stream count */
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
if (pipe_ctx->plane_res.mi->funcs->allocate_mem_input != NULL)
#endif
if (pipe_ctx->plane_res.mi != NULL) {
pipe_ctx->plane_res.mi->funcs->allocate_mem_input(
pipe_ctx->plane_res.mi,
stream->timing.h_total,
stream->timing.v_total,
stream->timing.pix_clk_khz,
context->stream_count);
pipe_ctx->plane_res.mi,
stream->timing.h_total,
stream->timing.v_total,
stream->timing.pix_clk_khz,
context->stream_count);
}
pipe_ctx->stream->sink->link->psr_enabled = false;
@ -1171,6 +1391,16 @@ static void power_down_encoders(struct dc *dc)
{
int i;
enum connector_id connector_id;
enum signal_type signal = SIGNAL_TYPE_NONE;
/* do not know BIOS back-front mapping, simply blank all. It will not
* hurt for non-DP
*/
for (i = 0; i < dc->res_pool->stream_enc_count; i++) {
dc->res_pool->stream_enc[i]->funcs->dp_blank(
dc->res_pool->stream_enc[i]);
}
for (i = 0; i < dc->link_count; i++) {
connector_id = dal_graphics_object_id_get_connector_id(dc->links[i]->link_id);
if ((connector_id == CONNECTOR_ID_DISPLAY_PORT) ||
@ -1178,10 +1408,12 @@ static void power_down_encoders(struct dc *dc)
if (!dc->links[i]->wa_flags.dp_keep_receiver_powered)
dp_receiver_power_ctrl(dc->links[i], false);
if (connector_id == CONNECTOR_ID_EDP)
signal = SIGNAL_TYPE_EDP;
}
dc->links[i]->link_enc->funcs->disable_output(
dc->links[i]->link_enc, SIGNAL_TYPE_NONE);
dc->links[i]->link_enc, signal, dc->links[i]);
}
}
@ -1218,7 +1450,7 @@ static void power_down_all_hw_blocks(struct dc *dc)
power_down_clock_sources(dc);
#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
if (dc->fbc_compressor)
dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
#endif
@ -1325,7 +1557,7 @@ static void set_safe_displaymarks(
SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK };
for (i = 0; i < MAX_PIPES; i++) {
if (res_ctx->pipe_ctx[i].stream == NULL)
if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL)
continue;
res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks(
@ -1334,6 +1566,7 @@ static void set_safe_displaymarks(
max_marks,
max_marks,
MAX_WATERMARK);
if (i == underlay_idx)
res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks(
res_ctx->pipe_ctx[i].plane_res.mi,
@ -1341,6 +1574,7 @@ static void set_safe_displaymarks(
max_marks,
max_marks,
MAX_WATERMARK);
}
}
@ -1391,7 +1625,7 @@ static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
if (events->cursor_update)
value |= 0x2;
#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
value |= 0x84;
#endif
@ -1521,7 +1755,7 @@ static void apply_min_clocks(
}
}
#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
/*
* Check if FBC can be enabled
@ -1644,7 +1878,10 @@ static void dce110_reset_hw_ctx_wrap(
pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
struct clock_source *old_clk = pipe_ctx_old->clock_source;
core_link_disable_stream(pipe_ctx_old);
/* disable already, no need to disable again */
if (pipe_ctx->stream && !pipe_ctx->stream->dpms_off)
core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE);
pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true);
if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) {
dm_error("DC: failed to blank crtc!\n");
@ -1713,7 +1950,7 @@ enum dc_status dce110_apply_ctx_to_hw(
set_safe_displaymarks(&context->res_ctx, dc->res_pool);
#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
if (dc->fbc_compressor)
dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
#endif
@ -1889,6 +2126,7 @@ enum dc_status dce110_apply_ctx_to_hw(
return status;
}
/* pplib is notified if disp_num changed */
dc->hwss.set_bandwidth(dc, context, true);
/* to save power */
@ -1896,7 +2134,7 @@ enum dc_status dce110_apply_ctx_to_hw(
dcb->funcs->set_scratch_critical_state(dcb, false);
#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
if (dc->fbc_compressor)
enable_fbc(dc, context);
@ -2305,7 +2543,7 @@ static void init_hw(struct dc *dc)
abm->funcs->init_backlight(abm);
abm->funcs->abm_init(abm);
}
#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
if (dc->fbc_compressor)
dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor);
#endif
@ -2490,6 +2728,8 @@ static void dce110_program_front_end_for_pipe(
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
struct xfm_grph_csc_adjustment adjust;
struct out_csc_color_matrix tbl_entry;
struct pipe_ctx *cur_pipe_ctx =
&dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
unsigned int i;
memset(&tbl_entry, 0, sizeof(tbl_entry));
@ -2553,6 +2793,15 @@ static void dce110_program_front_end_for_pipe(
program_scaler(dc, pipe_ctx);
#if defined(CONFIG_DRM_AMD_DC_FBC)
if (dc->fbc_compressor && old_pipe->stream) {
if (plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL)
dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
else
enable_fbc(dc, dc->current_state);
}
#endif
mi->funcs->mem_input_program_surface_config(
mi,
plane_state->format,
@ -2571,6 +2820,14 @@ static void dce110_program_front_end_for_pipe(
&plane_state->tiling_info,
plane_state->rotation);
/* Moved programming gamma from dc to hwss */
if (cur_pipe_ctx->plane_state != pipe_ctx->plane_state) {
dc->hwss.set_input_transfer_func(
pipe_ctx, pipe_ctx->plane_state);
dc->hwss.set_output_transfer_func(
pipe_ctx, pipe_ctx->stream);
}
dm_logger_write(dc->ctx->logger, LOG_SURFACE,
"Pipe:%d 0x%x: addr hi:0x%x, "
"addr low:0x%x, "
@ -2683,7 +2940,7 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
}
}
static void ready_shared_resources(struct dc *dc) {}
static void ready_shared_resources(struct dc *dc, struct dc_state *context) {}
static void optimize_shared_resources(struct dc *dc) {}
@ -2720,7 +2977,8 @@ static const struct hw_sequencer_funcs dce110_funcs = {
.wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect,
.ready_shared_resources = ready_shared_resources,
.optimize_shared_resources = optimize_shared_resources,
.edp_backlight_control = hwss_edp_backlight_control,
.edp_power_control = hwss_edp_power_control,
};
void dce110_hw_sequencer_construct(struct dc *dc)

View File

@ -47,7 +47,7 @@ void dce110_set_displaymarks(
void dce110_enable_stream(struct pipe_ctx *pipe_ctx);
void dce110_disable_stream(struct pipe_ctx *pipe_ctx);
void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option);
void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
struct dc_link_settings *link_settings);
@ -68,5 +68,14 @@ void dce110_fill_display_configs(
uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context);
void dp_receiver_power_ctrl(struct dc_link *link, bool on);
void hwss_edp_power_control(
struct link_encoder *enc,
bool power_up);
void hwss_edp_backlight_control(
struct dc_link *link,
bool enable);
#endif /* __DC_HWSS_DCE110_H__ */

View File

@ -52,7 +52,7 @@
#include "dce/dce_abm.h"
#include "dce/dce_dmcu.h"
#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
#include "dce110/dce110_compressor.h"
#endif
@ -849,7 +849,7 @@ static bool dce110_validate_bandwidth(
static bool dce110_validate_surface_sets(
struct dc_state *context)
{
int i;
int i, j;
for (i = 0; i < context->stream_count; i++) {
if (context->stream_status[i].plane_count == 0)
@ -858,14 +858,27 @@ static bool dce110_validate_surface_sets(
if (context->stream_status[i].plane_count > 2)
return false;
if ((context->stream_status[i].plane_states[i]->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) &&
(context->stream_status[i].plane_states[i]->src_rect.width > 1920 ||
context->stream_status[i].plane_states[i]->src_rect.height > 1080))
return false;
for (j = 0; j < context->stream_status[i].plane_count; j++) {
struct dc_plane_state *plane =
context->stream_status[i].plane_states[j];
/* irrespective of plane format, stream should be RGB encoded */
if (context->streams[i]->timing.pixel_encoding != PIXEL_ENCODING_RGB)
return false;
/* underlay validation */
if (plane->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
if ((plane->src_rect.width > 1920 ||
plane->src_rect.height > 1080))
return false;
/* irrespective of plane format,
* stream should be RGB encoded
*/
if (context->streams[i]->timing.pixel_encoding
!= PIXEL_ENCODING_RGB)
return false;
}
}
}
return true;
@ -1266,7 +1279,7 @@ static bool construct(
}
}
#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
dc->fbc_compressor = dce110_compressor_create(ctx);

View File

@ -3,8 +3,8 @@
DCN10 = dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o \
dcn10_dpp.o dcn10_opp.o dcn10_timing_generator.o \
dcn10_mem_input.o dcn10_mpc.o \
dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_dpp_cm_helper.o
dcn10_hubp.o dcn10_mpc.o \
dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_cm_common.o
AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10))

View File

@ -26,7 +26,7 @@
#include "reg_helper.h"
#include "dcn10_dpp.h"
#include "dcn10_dpp_cm_helper.h"
#include "dcn10_cm_common.h"
#define REG(reg) reg

View File

@ -23,8 +23,8 @@
*
*/
#ifndef __DAL_DPP_DCN10_CM_HELPER_H__
#define __DAL_DPP_DCN10_CM_HELPER_H__
#ifndef __DAL_DCN10_CM_COMMON_H__
#define __DAL_DCN10_CM_COMMON_H__
#define TF_HELPER_REG_FIELD_LIST(type) \
type exp_region0_lut_offset; \

View File

@ -39,14 +39,14 @@
#define BLACK_OFFSET_CBCR 0x8000
#define REG(reg)\
xfm->tf_regs->reg
dpp->tf_regs->reg
#define CTX \
xfm->base.ctx
dpp->base.ctx
#undef FN
#define FN(reg_name, field_name) \
xfm->tf_shift->field_name, xfm->tf_mask->field_name
dpp->tf_shift->field_name, dpp->tf_mask->field_name
enum pixel_format_description {
PIXEL_FORMAT_FIXED = 0,
@ -99,7 +99,7 @@ enum gamut_remap_select {
};
/* Program gamut remap in bypass mode */
void dpp_set_gamut_remap_bypass(struct dcn10_dpp *xfm)
void dpp_set_gamut_remap_bypass(struct dcn10_dpp *dpp)
{
REG_SET(CM_GAMUT_REMAP_CONTROL, 0,
CM_GAMUT_REMAP_MODE, 0);
@ -110,7 +110,7 @@ void dpp_set_gamut_remap_bypass(struct dcn10_dpp *xfm)
bool dpp_get_optimal_number_of_taps(
struct transform *xfm,
struct dpp *dpp,
struct scaler_data *scl_data,
const struct scaling_taps *in_taps)
{
@ -154,28 +154,29 @@ bool dpp_get_optimal_number_of_taps(
else
scl_data->taps.h_taps_c = in_taps->h_taps_c;
if (!xfm->ctx->dc->debug.always_scale) {
if (!dpp->ctx->dc->debug.always_scale) {
if (IDENTITY_RATIO(scl_data->ratios.horz))
scl_data->taps.h_taps = 1;
if (IDENTITY_RATIO(scl_data->ratios.vert))
scl_data->taps.v_taps = 1;
if (IDENTITY_RATIO(scl_data->ratios.horz_c))
scl_data->taps.h_taps_c = 1;
if (IDENTITY_RATIO(scl_data->ratios.vert_c))
scl_data->taps.v_taps_c = 1;
/*
* Spreadsheet doesn't handle taps_c is one properly,
* need to force Chroma to always be scaled to pass
* bandwidth validation.
*/
}
return true;
}
void dpp_reset(struct transform *xfm_base)
void dpp_reset(struct dpp *dpp_base)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
xfm->filter_h_c = NULL;
xfm->filter_v_c = NULL;
xfm->filter_h = NULL;
xfm->filter_v = NULL;
dpp->filter_h_c = NULL;
dpp->filter_v_c = NULL;
dpp->filter_h = NULL;
dpp->filter_v = NULL;
/* set boundary mode to 0 */
REG_SET(DSCL_CONTROL, 0, SCL_BOUNDARY_MODE, 0);
@ -183,28 +184,28 @@ void dpp_reset(struct transform *xfm_base)
static void dcn10_dpp_cm_set_regamma_pwl(
struct transform *xfm_base, const struct pwl_params *params)
static void dpp1_cm_set_regamma_pwl(
struct dpp *dpp_base, const struct pwl_params *params)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
dcn10_dpp_cm_power_on_regamma_lut(xfm_base, true);
dcn10_dpp_cm_configure_regamma_lut(xfm_base, xfm->is_write_to_ram_a_safe);
dpp1_cm_power_on_regamma_lut(dpp_base, true);
dpp1_cm_configure_regamma_lut(dpp_base, dpp->is_write_to_ram_a_safe);
if (xfm->is_write_to_ram_a_safe)
dcn10_dpp_cm_program_regamma_luta_settings(xfm_base, params);
if (dpp->is_write_to_ram_a_safe)
dpp1_cm_program_regamma_luta_settings(dpp_base, params);
else
dcn10_dpp_cm_program_regamma_lutb_settings(xfm_base, params);
dpp1_cm_program_regamma_lutb_settings(dpp_base, params);
dcn10_dpp_cm_program_regamma_lut(
xfm_base, params->rgb_resulted, params->hw_points_num);
dpp1_cm_program_regamma_lut(
dpp_base, params->rgb_resulted, params->hw_points_num);
}
static void dcn10_dpp_cm_set_regamma_mode(
struct transform *xfm_base,
static void dpp1_cm_set_regamma_mode(
struct dpp *dpp_base,
enum opp_regamma mode)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
uint32_t re_mode = 0;
uint32_t obuf_bypass = 0; /* need for pipe split */
uint32_t obuf_hupscale = 0;
@ -220,8 +221,8 @@ static void dcn10_dpp_cm_set_regamma_mode(
re_mode = 2;
break;
case OPP_REGAMMA_USER:
re_mode = xfm->is_write_to_ram_a_safe ? 3 : 4;
xfm->is_write_to_ram_a_safe = !xfm->is_write_to_ram_a_safe;
re_mode = dpp->is_write_to_ram_a_safe ? 3 : 4;
dpp->is_write_to_ram_a_safe = !dpp->is_write_to_ram_a_safe;
break;
default:
break;
@ -233,7 +234,7 @@ static void dcn10_dpp_cm_set_regamma_mode(
OBUF_H_2X_UPSCALE_EN, obuf_hupscale);
}
static void ippn10_setup_format_flags(enum surface_pixel_format input_format,\
static void dpp1_setup_format_flags(enum surface_pixel_format input_format,\
enum pixel_format_description *fmt)
{
@ -246,11 +247,11 @@ static void ippn10_setup_format_flags(enum surface_pixel_format input_format,\
*fmt = PIXEL_FORMAT_FIXED;
}
static void ippn10_set_degamma_format_float(
struct transform *xfm_base,
static void dpp1_set_degamma_format_float(
struct dpp *dpp_base,
bool is_float)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
if (is_float) {
REG_UPDATE(CM_IGAM_CONTROL, CM_IGAM_INPUT_FORMAT, 3);
@ -261,8 +262,8 @@ static void ippn10_set_degamma_format_float(
}
}
void ippn10_cnv_setup (
struct transform *xfm_base,
void dpp1_cnv_setup (
struct dpp *dpp_base,
enum surface_pixel_format input_format,
enum expansion_mode mode)
{
@ -272,10 +273,10 @@ void ippn10_cnv_setup (
enum dc_color_space color_space;
enum dcn10_input_csc_select select;
bool is_float;
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
bool force_disable_cursor = false;
ippn10_setup_format_flags(input_format, &fmt);
dpp1_setup_format_flags(input_format, &fmt);
alpha_en = 1;
pixel_format = 0;
color_space = COLOR_SPACE_SRGB;
@ -303,7 +304,7 @@ void ippn10_cnv_setup (
break;
}
ippn10_set_degamma_format_float(xfm_base, is_float);
dpp1_set_degamma_format_float(dpp_base, is_float);
switch (input_format) {
case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
@ -361,7 +362,7 @@ void ippn10_cnv_setup (
CNVC_SURFACE_PIXEL_FORMAT, pixel_format);
REG_UPDATE(FORMAT_CONTROL, FORMAT_CONTROL__ALPHA_EN, alpha_en);
ippn10_program_input_csc(xfm_base, color_space, select);
dpp1_program_input_csc(dpp_base, color_space, select);
if (force_disable_cursor) {
REG_UPDATE(CURSOR_CONTROL,
@ -371,54 +372,110 @@ void ippn10_cnv_setup (
}
}
static const struct transform_funcs dcn10_dpp_funcs = {
.transform_reset = dpp_reset,
.transform_set_scaler = dcn10_dpp_dscl_set_scaler_manual_scale,
.transform_get_optimal_number_of_taps = dpp_get_optimal_number_of_taps,
.transform_set_gamut_remap = dcn10_dpp_cm_set_gamut_remap,
.opp_set_csc_adjustment = dcn10_dpp_cm_set_output_csc_adjustment,
.opp_set_csc_default = dcn10_dpp_cm_set_output_csc_default,
.opp_power_on_regamma_lut = dcn10_dpp_cm_power_on_regamma_lut,
.opp_program_regamma_lut = dcn10_dpp_cm_program_regamma_lut,
.opp_configure_regamma_lut = dcn10_dpp_cm_configure_regamma_lut,
.opp_program_regamma_lutb_settings = dcn10_dpp_cm_program_regamma_lutb_settings,
.opp_program_regamma_luta_settings = dcn10_dpp_cm_program_regamma_luta_settings,
.opp_program_regamma_pwl = dcn10_dpp_cm_set_regamma_pwl,
.opp_set_regamma_mode = dcn10_dpp_cm_set_regamma_mode,
.ipp_set_degamma = ippn10_set_degamma,
.ipp_program_input_lut = ippn10_program_input_lut,
.ipp_program_degamma_pwl = ippn10_set_degamma_pwl,
.ipp_setup = ippn10_cnv_setup,
.ipp_full_bypass = ippn10_full_bypass,
void dpp1_set_cursor_attributes(
struct dpp *dpp_base,
const struct dc_cursor_attributes *attr)
{
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
enum dc_cursor_color_format color_format = attr->color_format;
REG_UPDATE_2(CURSOR0_CONTROL,
CUR0_MODE, color_format,
CUR0_EXPANSION_MODE, 0);
if (color_format == CURSOR_MODE_MONO) {
/* todo: clarify what to program these to */
REG_UPDATE(CURSOR0_COLOR0,
CUR0_COLOR0, 0x00000000);
REG_UPDATE(CURSOR0_COLOR1,
CUR0_COLOR1, 0xFFFFFFFF);
}
/* TODO: Fixed vs float */
REG_UPDATE_3(FORMAT_CONTROL,
CNVC_BYPASS, 0,
FORMAT_CONTROL__ALPHA_EN, 1,
FORMAT_EXPANSION_MODE, 0);
}
void dpp1_set_cursor_position(
struct dpp *dpp_base,
const struct dc_cursor_position *pos,
const struct dc_cursor_mi_param *param,
uint32_t width)
{
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
uint32_t cur_en = pos->enable ? 1 : 0;
if (src_x_offset >= (int)param->viewport_width)
cur_en = 0; /* not visible beyond right edge*/
if (src_x_offset + (int)width < 0)
cur_en = 0; /* not visible beyond left edge*/
REG_UPDATE(CURSOR0_CONTROL,
CUR0_ENABLE, cur_en);
}
static const struct dpp_funcs dcn10_dpp_funcs = {
.dpp_reset = dpp_reset,
.dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale,
.dpp_get_optimal_number_of_taps = dpp_get_optimal_number_of_taps,
.dpp_set_gamut_remap = dpp1_cm_set_gamut_remap,
.opp_set_csc_adjustment = dpp1_cm_set_output_csc_adjustment,
.opp_set_csc_default = dpp1_cm_set_output_csc_default,
.opp_power_on_regamma_lut = dpp1_cm_power_on_regamma_lut,
.opp_program_regamma_lut = dpp1_cm_program_regamma_lut,
.opp_configure_regamma_lut = dpp1_cm_configure_regamma_lut,
.opp_program_regamma_lutb_settings = dpp1_cm_program_regamma_lutb_settings,
.opp_program_regamma_luta_settings = dpp1_cm_program_regamma_luta_settings,
.opp_program_regamma_pwl = dpp1_cm_set_regamma_pwl,
.opp_set_regamma_mode = dpp1_cm_set_regamma_mode,
.ipp_set_degamma = dpp1_set_degamma,
.ipp_program_input_lut = dpp1_program_input_lut,
.ipp_program_degamma_pwl = dpp1_set_degamma_pwl,
.ipp_setup = dpp1_cnv_setup,
.ipp_full_bypass = dpp1_full_bypass,
.set_cursor_attributes = dpp1_set_cursor_attributes,
.set_cursor_position = dpp1_set_cursor_position,
};
static struct dpp_caps dcn10_dpp_cap = {
.dscl_data_proc_format = DSCL_DATA_PRCESSING_FIXED_FORMAT,
.dscl_calc_lb_num_partitions = dpp1_dscl_calc_lb_num_partitions,
};
/*****************************************/
/* Constructor, Destructor */
/*****************************************/
void dcn10_dpp_construct(
struct dcn10_dpp *xfm,
void dpp1_construct(
struct dcn10_dpp *dpp,
struct dc_context *ctx,
uint32_t inst,
const struct dcn_dpp_registers *tf_regs,
const struct dcn_dpp_shift *tf_shift,
const struct dcn_dpp_mask *tf_mask)
{
xfm->base.ctx = ctx;
dpp->base.ctx = ctx;
xfm->base.inst = inst;
xfm->base.funcs = &dcn10_dpp_funcs;
dpp->base.inst = inst;
dpp->base.funcs = &dcn10_dpp_funcs;
dpp->base.caps = &dcn10_dpp_cap;
xfm->tf_regs = tf_regs;
xfm->tf_shift = tf_shift;
xfm->tf_mask = tf_mask;
dpp->tf_regs = tf_regs;
dpp->tf_shift = tf_shift;
dpp->tf_mask = tf_mask;
xfm->lb_pixel_depth_supported =
dpp->lb_pixel_depth_supported =
LB_PIXEL_DEPTH_18BPP |
LB_PIXEL_DEPTH_24BPP |
LB_PIXEL_DEPTH_30BPP;
xfm->lb_bits_per_entry = LB_BITS_PER_ENTRY;
xfm->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x1404*/
dpp->lb_bits_per_entry = LB_BITS_PER_ENTRY;
dpp->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x1404*/
}

View File

@ -25,10 +25,10 @@
#ifndef __DAL_DPP_DCN10_H__
#define __DAL_DPP_DCN10_H__
#include "transform.h"
#include "dpp.h"
#define TO_DCN10_DPP(transform)\
container_of(transform, struct dcn10_dpp, base)
#define TO_DCN10_DPP(dpp)\
container_of(dpp, struct dcn10_dpp, base)
/* TODO: Use correct number of taps. Using polaris values for now */
#define LB_TOTAL_NUMBER_OF_ENTRIES 5124
@ -112,7 +112,9 @@
SRI(CM_DGAM_CONTROL, CM, id), \
SRI(FORMAT_CONTROL, CNVC_CFG, id), \
SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \
SRI(CURSOR0_CONTROL, CNVC_CUR, id)
SRI(CURSOR0_CONTROL, CNVC_CUR, id), \
SRI(CURSOR0_COLOR0, CNVC_CUR, id), \
SRI(CURSOR0_COLOR1, CNVC_CUR, id)
@ -162,7 +164,8 @@
SRI(CM_IGAM_LUT_RW_CONTROL, CM, id), \
SRI(CM_IGAM_LUT_RW_INDEX, CM, id), \
SRI(CM_IGAM_LUT_SEQ_COLOR, CM, id), \
SRI(CURSOR_CONTROL, CURSOR, id)
SRI(CURSOR_CONTROL, CURSOR, id), \
SRI(CM_CMOUT_CONTROL, CM, id)
#define TF_REG_LIST_SH_MASK_DCN(mask_sh)\
@ -302,7 +305,9 @@
TF_SF(CNVC_CFG0_CNVC_SURFACE_PIXEL_FORMAT, CNVC_SURFACE_PIXEL_FORMAT, mask_sh), \
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_MODE, mask_sh), \
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_EXPANSION_MODE, mask_sh), \
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh)
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh), \
TF_SF(CNVC_CUR0_CURSOR0_COLOR0, CUR0_COLOR0, mask_sh), \
TF_SF(CNVC_CUR0_CURSOR0_COLOR1, CUR0_COLOR1, mask_sh)
#define TF_REG_LIST_SH_MASK_DCN10(mask_sh)\
TF_REG_LIST_SH_MASK_DCN(mask_sh),\
@ -397,6 +402,7 @@
TF_SF(CM0_CM_CONTROL, CM_BYPASS_EN, mask_sh), \
TF_SF(CM0_CM_IGAM_LUT_SEQ_COLOR, CM_IGAM_LUT_SEQ_COLOR, mask_sh), \
TF_SF(CNVC_CFG0_FORMAT_CONTROL, OUTPUT_FP, mask_sh), \
TF_SF(CM0_CM_CMOUT_CONTROL, CM_CMOUT_ROUND_TRUNC_MODE, mask_sh), \
TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \
TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \
TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \
@ -545,6 +551,7 @@
type CM_RGAM_RAMA_EXP_REGION33_LUT_OFFSET; \
type CM_RGAM_RAMA_EXP_REGION33_NUM_SEGMENTS; \
type CM_RGAM_LUT_MODE; \
type CM_CMOUT_ROUND_TRUNC_MODE; \
type OBUF_BYPASS; \
type OBUF_H_2X_UPSCALE_EN; \
type CM_BLNDGAM_LUT_MODE; \
@ -989,7 +996,9 @@
type CUR0_EXPANSION_MODE; \
type CUR0_ENABLE; \
type CM_BYPASS; \
type FORMAT_CONTROL__ALPHA_EN
type FORMAT_CONTROL__ALPHA_EN; \
type CUR0_COLOR0; \
type CUR0_COLOR1
@ -1075,6 +1084,7 @@ struct dcn_dpp_registers {
uint32_t CM_RGAM_RAMA_REGION_0_1;
uint32_t CM_RGAM_RAMA_REGION_32_33;
uint32_t CM_RGAM_CONTROL;
uint32_t CM_CMOUT_CONTROL;
uint32_t OBUF_CONTROL;
uint32_t CM_BLNDGAM_LUT_WRITE_EN_MASK;
uint32_t CM_BLNDGAM_CONTROL;
@ -1237,10 +1247,12 @@ struct dcn_dpp_registers {
uint32_t CNVC_SURFACE_PIXEL_FORMAT;
uint32_t CURSOR_CONTROL;
uint32_t CURSOR0_CONTROL;
uint32_t CURSOR0_COLOR0;
uint32_t CURSOR0_COLOR1;
};
struct dcn10_dpp {
struct transform base;
struct dpp base;
const struct dcn_dpp_registers *tf_regs;
const struct dcn_dpp_shift *tf_shift;
@ -1256,107 +1268,116 @@ struct dcn10_dpp {
bool is_write_to_ram_a_safe;
};
enum dcn10_input_csc_select {
INPUT_CSC_SELECT_BYPASS = 0,
INPUT_CSC_SELECT_ICSC,
INPUT_CSC_SELECT_COMA
};
void ippn10_degamma_ram_select(
struct transform *xfm_base,
bool dpp1_dscl_is_lb_conf_valid(
int ceil_vratio,
int num_partitions,
int vtaps);
void dpp1_dscl_calc_lb_num_partitions(
const struct scaler_data *scl_data,
enum lb_memory_config lb_config,
int *num_part_y,
int *num_part_c);
void dpp1_degamma_ram_select(
struct dpp *dpp_base,
bool use_ram_a);
void ippn10_program_degamma_luta_settings(
struct transform *xfm_base,
void dpp1_program_degamma_luta_settings(
struct dpp *dpp_base,
const struct pwl_params *params);
void ippn10_program_degamma_lutb_settings(
struct transform *xfm_base,
void dpp1_program_degamma_lutb_settings(
struct dpp *dpp_base,
const struct pwl_params *params);
void ippn10_program_degamma_lut(
struct transform *xfm_base,
void dpp1_program_degamma_lut(
struct dpp *dpp_base,
const struct pwl_result_data *rgb,
uint32_t num,
bool is_ram_a);
void ippn10_power_on_degamma_lut(
struct transform *xfm_base,
void dpp1_power_on_degamma_lut(
struct dpp *dpp_base,
bool power_on);
void ippn10_program_input_csc(
struct transform *xfm_base,
void dpp1_program_input_csc(
struct dpp *dpp_base,
enum dc_color_space color_space,
enum dcn10_input_csc_select select);
void ippn10_program_input_lut(
struct transform *xfm_base,
void dpp1_program_input_lut(
struct dpp *dpp_base,
const struct dc_gamma *gamma);
void ippn10_full_bypass(struct transform *xfm_base);
void dpp1_full_bypass(struct dpp *dpp_base);
void ippn10_set_degamma(
struct transform *xfm_base,
void dpp1_set_degamma(
struct dpp *dpp_base,
enum ipp_degamma_mode mode);
void ippn10_set_degamma_pwl(struct transform *xfm_base,
void dpp1_set_degamma_pwl(struct dpp *dpp_base,
const struct pwl_params *params);
bool dpp_get_optimal_number_of_taps(
struct transform *xfm,
struct dpp *dpp,
struct scaler_data *scl_data,
const struct scaling_taps *in_taps);
void dpp_reset(struct transform *xfm_base);
void dpp_reset(struct dpp *dpp_base);
void dcn10_dpp_cm_program_regamma_lut(
struct transform *xfm_base,
void dpp1_cm_program_regamma_lut(
struct dpp *dpp_base,
const struct pwl_result_data *rgb,
uint32_t num);
void dcn10_dpp_cm_power_on_regamma_lut(
struct transform *xfm_base,
void dpp1_cm_power_on_regamma_lut(
struct dpp *dpp_base,
bool power_on);
void dcn10_dpp_cm_configure_regamma_lut(
struct transform *xfm_base,
void dpp1_cm_configure_regamma_lut(
struct dpp *dpp_base,
bool is_ram_a);
/*program re gamma RAM A*/
void dcn10_dpp_cm_program_regamma_luta_settings(
struct transform *xfm_base,
void dpp1_cm_program_regamma_luta_settings(
struct dpp *dpp_base,
const struct pwl_params *params);
/*program re gamma RAM B*/
void dcn10_dpp_cm_program_regamma_lutb_settings(
struct transform *xfm_base,
void dpp1_cm_program_regamma_lutb_settings(
struct dpp *dpp_base,
const struct pwl_params *params);
void dcn10_dpp_cm_set_output_csc_adjustment(
struct transform *xfm_base,
void dpp1_cm_set_output_csc_adjustment(
struct dpp *dpp_base,
const struct out_csc_color_matrix *tbl_entry);
void dcn10_dpp_cm_set_output_csc_default(
struct transform *xfm_base,
void dpp1_cm_set_output_csc_default(
struct dpp *dpp_base,
const struct default_adjustment *default_adjust);
void dcn10_dpp_cm_set_gamut_remap(
struct transform *xfm,
const struct xfm_grph_csc_adjustment *adjust);
void dpp1_cm_set_gamut_remap(
struct dpp *dpp,
const struct dpp_grph_csc_adjustment *adjust);
void dcn10_dpp_dscl_set_scaler_manual_scale(
struct transform *xfm_base,
void dpp1_dscl_set_scaler_manual_scale(
struct dpp *dpp_base,
const struct scaler_data *scl_data);
void ippn10_cnv_setup (
struct transform *xfm_base,
void dpp1_cnv_setup (
struct dpp *dpp_base,
enum surface_pixel_format input_format,
enum expansion_mode mode);
void ippn10_full_bypass(struct transform *xfm_base);
void dpp1_full_bypass(struct dpp *dpp_base);
void dcn10_dpp_construct(struct dcn10_dpp *xfm110,
void dpp1_construct(struct dcn10_dpp *dpp1,
struct dc_context *ctx,
uint32_t inst,
const struct dcn_dpp_registers *tf_regs,

View File

@ -29,8 +29,8 @@
#include "reg_helper.h"
#include "dcn10_dpp.h"
#include "dcn10_dpp_cm_helper.h"
#include "basics/conversion.h"
#include "dcn10_cm_common.h"
#define NUM_PHASES 64
#define HORZ_MAX_TAPS 8
@ -40,14 +40,14 @@
#define BLACK_OFFSET_CBCR 0x8000
#define REG(reg)\
xfm->tf_regs->reg
dpp->tf_regs->reg
#define CTX \
xfm->base.ctx
dpp->base.ctx
#undef FN
#define FN(reg_name, field_name) \
xfm->tf_shift->field_name, xfm->tf_mask->field_name
dpp->tf_shift->field_name, dpp->tf_mask->field_name
struct dcn10_input_csc_matrix {
enum dc_color_space color_space;
@ -120,7 +120,7 @@ static const struct dcn10_input_csc_matrix dcn10_input_csc_matrix[] = {
static void program_gamut_remap(
struct dcn10_dpp *xfm,
struct dcn10_dpp *dpp,
const uint16_t *regval,
enum gamut_remap_select select)
{
@ -146,10 +146,10 @@ static void program_gamut_remap(
break;
}
gam_regs.shifts.csc_c11 = xfm->tf_shift->CM_GAMUT_REMAP_C11;
gam_regs.masks.csc_c11 = xfm->tf_mask->CM_GAMUT_REMAP_C11;
gam_regs.shifts.csc_c12 = xfm->tf_shift->CM_GAMUT_REMAP_C12;
gam_regs.masks.csc_c12 = xfm->tf_mask->CM_GAMUT_REMAP_C12;
gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_GAMUT_REMAP_C11;
gam_regs.masks.csc_c11 = dpp->tf_mask->CM_GAMUT_REMAP_C11;
gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_GAMUT_REMAP_C12;
gam_regs.masks.csc_c12 = dpp->tf_mask->CM_GAMUT_REMAP_C12;
if (select == GAMUT_REMAP_COEFF) {
@ -157,7 +157,7 @@ static void program_gamut_remap(
gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34);
cm_helper_program_color_matrices(
xfm->base.ctx,
dpp->base.ctx,
regval,
&gam_regs);
@ -167,7 +167,7 @@ static void program_gamut_remap(
gam_regs.csc_c33_c34 = REG(CM_COMA_C33_C34);
cm_helper_program_color_matrices(
xfm->base.ctx,
dpp->base.ctx,
regval,
&gam_regs);
@ -177,7 +177,7 @@ static void program_gamut_remap(
gam_regs.csc_c33_c34 = REG(CM_COMB_C33_C34);
cm_helper_program_color_matrices(
xfm->base.ctx,
dpp->base.ctx,
regval,
&gam_regs);
}
@ -188,15 +188,15 @@ static void program_gamut_remap(
}
void dcn10_dpp_cm_set_gamut_remap(
struct transform *xfm,
const struct xfm_grph_csc_adjustment *adjust)
void dpp1_cm_set_gamut_remap(
struct dpp *dpp_base,
const struct dpp_grph_csc_adjustment *adjust)
{
struct dcn10_dpp *dcn_xfm = TO_DCN10_DPP(xfm);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW)
/* Bypass if type is bypass or hw */
program_gamut_remap(dcn_xfm, NULL, GAMUT_REMAP_BYPASS);
program_gamut_remap(dpp, NULL, GAMUT_REMAP_BYPASS);
else {
struct fixed31_32 arr_matrix[12];
uint16_t arr_reg_val[12];
@ -219,16 +219,16 @@ void dcn10_dpp_cm_set_gamut_remap(
convert_float_matrix(
arr_reg_val, arr_matrix, 12);
program_gamut_remap(dcn_xfm, arr_reg_val, GAMUT_REMAP_COEFF);
program_gamut_remap(dpp, arr_reg_val, GAMUT_REMAP_COEFF);
}
}
void dcn10_dpp_cm_set_output_csc_default(
struct transform *xfm_base,
void dpp1_cm_set_output_csc_default(
struct dpp *dpp_base,
const struct default_adjustment *default_adjust)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
uint32_t ocsc_mode = 0;
if (default_adjust != NULL) {
@ -260,35 +260,35 @@ void dcn10_dpp_cm_set_output_csc_default(
}
static void dcn10_dpp_cm_get_reg_field(
struct dcn10_dpp *xfm,
static void dpp1_cm_get_reg_field(
struct dcn10_dpp *dpp,
struct xfer_func_reg *reg)
{
reg->shifts.exp_region0_lut_offset = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET;
reg->masks.exp_region0_lut_offset = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET;
reg->shifts.exp_region0_num_segments = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
reg->masks.exp_region0_num_segments = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
reg->shifts.exp_region1_lut_offset = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET;
reg->masks.exp_region1_lut_offset = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET;
reg->shifts.exp_region1_num_segments = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
reg->masks.exp_region1_num_segments = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET;
reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET;
reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET;
reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET;
reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
reg->shifts.field_region_end = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_B;
reg->masks.field_region_end = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_B;
reg->shifts.field_region_end_slope = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B;
reg->masks.field_region_end_slope = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B;
reg->shifts.field_region_end_base = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_BASE_B;
reg->masks.field_region_end_base = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_BASE_B;
reg->shifts.field_region_linear_slope = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
reg->masks.field_region_linear_slope = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
reg->shifts.exp_region_start = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_B;
reg->masks.exp_region_start = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_B;
reg->shifts.exp_resion_start_segment = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B;
reg->masks.exp_resion_start_segment = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B;
reg->shifts.field_region_end = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_B;
reg->masks.field_region_end = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_B;
reg->shifts.field_region_end_slope = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B;
reg->masks.field_region_end_slope = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B;
reg->shifts.field_region_end_base = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_BASE_B;
reg->masks.field_region_end_base = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_BASE_B;
reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
reg->masks.field_region_linear_slope = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
reg->shifts.exp_region_start = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_B;
reg->masks.exp_region_start = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_B;
reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B;
reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B;
}
static void dcn10_dpp_cm_program_color_matrix(
struct dcn10_dpp *xfm,
static void dpp1_cm_program_color_matrix(
struct dcn10_dpp *dpp,
const struct out_csc_color_matrix *tbl_entry)
{
uint32_t mode;
@ -301,10 +301,10 @@ static void dcn10_dpp_cm_program_color_matrix(
return;
}
gam_regs.shifts.csc_c11 = xfm->tf_shift->CM_OCSC_C11;
gam_regs.masks.csc_c11 = xfm->tf_mask->CM_OCSC_C11;
gam_regs.shifts.csc_c12 = xfm->tf_shift->CM_OCSC_C12;
gam_regs.masks.csc_c12 = xfm->tf_mask->CM_OCSC_C12;
gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_OCSC_C11;
gam_regs.masks.csc_c11 = dpp->tf_mask->CM_OCSC_C11;
gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_OCSC_C12;
gam_regs.masks.csc_c12 = dpp->tf_mask->CM_OCSC_C12;
if (mode == 4) {
@ -312,7 +312,7 @@ static void dcn10_dpp_cm_program_color_matrix(
gam_regs.csc_c33_c34 = REG(CM_OCSC_C33_C34);
cm_helper_program_color_matrices(
xfm->base.ctx,
dpp->base.ctx,
tbl_entry->regval,
&gam_regs);
@ -322,17 +322,17 @@ static void dcn10_dpp_cm_program_color_matrix(
gam_regs.csc_c33_c34 = REG(CM_COMB_C33_C34);
cm_helper_program_color_matrices(
xfm->base.ctx,
dpp->base.ctx,
tbl_entry->regval,
&gam_regs);
}
}
void dcn10_dpp_cm_set_output_csc_adjustment(
struct transform *xfm_base,
void dpp1_cm_set_output_csc_adjustment(
struct dpp *dpp_base,
const struct out_csc_color_matrix *tbl_entry)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
//enum csc_color_mode config = CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
uint32_t ocsc_mode = 4;
@ -364,26 +364,26 @@ void dcn10_dpp_cm_set_output_csc_adjustment(
*/
REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode);
dcn10_dpp_cm_program_color_matrix(xfm, tbl_entry);
dpp1_cm_program_color_matrix(dpp, tbl_entry);
}
void dcn10_dpp_cm_power_on_regamma_lut(
struct transform *xfm_base,
void dpp1_cm_power_on_regamma_lut(
struct dpp *dpp_base,
bool power_on)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
REG_SET(CM_MEM_PWR_CTRL, 0,
RGAM_MEM_PWR_FORCE, power_on == true ? 0:1);
}
void dcn10_dpp_cm_program_regamma_lut(
struct transform *xfm_base,
void dpp1_cm_program_regamma_lut(
struct dpp *dpp_base,
const struct pwl_result_data *rgb,
uint32_t num)
{
uint32_t i;
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
for (i = 0 ; i < num; i++) {
REG_SET(CM_RGAM_LUT_DATA, 0, CM_RGAM_LUT_DATA, rgb[i].red_reg);
REG_SET(CM_RGAM_LUT_DATA, 0, CM_RGAM_LUT_DATA, rgb[i].green_reg);
@ -400,11 +400,11 @@ void dcn10_dpp_cm_program_regamma_lut(
}
void dcn10_dpp_cm_configure_regamma_lut(
struct transform *xfm_base,
void dpp1_cm_configure_regamma_lut(
struct dpp *dpp_base,
bool is_ram_a)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
REG_UPDATE(CM_RGAM_LUT_WRITE_EN_MASK,
CM_RGAM_LUT_WRITE_EN_MASK, 7);
@ -414,14 +414,14 @@ void dcn10_dpp_cm_configure_regamma_lut(
}
/*program re gamma RAM A*/
void dcn10_dpp_cm_program_regamma_luta_settings(
struct transform *xfm_base,
void dpp1_cm_program_regamma_luta_settings(
struct dpp *dpp_base,
const struct pwl_params *params)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
struct xfer_func_reg gam_regs;
dcn10_dpp_cm_get_reg_field(xfm, &gam_regs);
dpp1_cm_get_reg_field(dpp, &gam_regs);
gam_regs.start_cntl_b = REG(CM_RGAM_RAMA_START_CNTL_B);
gam_regs.start_cntl_g = REG(CM_RGAM_RAMA_START_CNTL_G);
@ -438,19 +438,19 @@ void dcn10_dpp_cm_program_regamma_luta_settings(
gam_regs.region_start = REG(CM_RGAM_RAMA_REGION_0_1);
gam_regs.region_end = REG(CM_RGAM_RAMA_REGION_32_33);
cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs);
cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
}
/*program re gamma RAM B*/
void dcn10_dpp_cm_program_regamma_lutb_settings(
struct transform *xfm_base,
void dpp1_cm_program_regamma_lutb_settings(
struct dpp *dpp_base,
const struct pwl_params *params)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
struct xfer_func_reg gam_regs;
dcn10_dpp_cm_get_reg_field(xfm, &gam_regs);
dpp1_cm_get_reg_field(dpp, &gam_regs);
gam_regs.start_cntl_b = REG(CM_RGAM_RAMB_START_CNTL_B);
gam_regs.start_cntl_g = REG(CM_RGAM_RAMB_START_CNTL_G);
@ -467,15 +467,15 @@ void dcn10_dpp_cm_program_regamma_lutb_settings(
gam_regs.region_start = REG(CM_RGAM_RAMB_REGION_0_1);
gam_regs.region_end = REG(CM_RGAM_RAMB_REGION_32_33);
cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs);
cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
}
void ippn10_program_input_csc(
struct transform *xfm_base,
void dpp1_program_input_csc(
struct dpp *dpp_base,
enum dc_color_space color_space,
enum dcn10_input_csc_select select)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
int i;
int arr_size = sizeof(dcn10_input_csc_matrix)/sizeof(struct dcn10_input_csc_matrix);
const uint16_t *regval = NULL;
@ -503,10 +503,10 @@ void ippn10_program_input_csc(
REG_SET(CM_ICSC_CONTROL, 0,
CM_ICSC_MODE, selection);
gam_regs.shifts.csc_c11 = xfm->tf_shift->CM_ICSC_C11;
gam_regs.masks.csc_c11 = xfm->tf_mask->CM_ICSC_C11;
gam_regs.shifts.csc_c12 = xfm->tf_shift->CM_ICSC_C12;
gam_regs.masks.csc_c12 = xfm->tf_mask->CM_ICSC_C12;
gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_ICSC_C11;
gam_regs.masks.csc_c11 = dpp->tf_mask->CM_ICSC_C11;
gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_ICSC_C12;
gam_regs.masks.csc_c12 = dpp->tf_mask->CM_ICSC_C12;
if (select == INPUT_CSC_SELECT_ICSC) {
@ -515,7 +515,7 @@ void ippn10_program_input_csc(
gam_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34);
cm_helper_program_color_matrices(
xfm->base.ctx,
dpp->base.ctx,
regval,
&gam_regs);
} else {
@ -524,21 +524,21 @@ void ippn10_program_input_csc(
gam_regs.csc_c33_c34 = REG(CM_COMA_C33_C34);
cm_helper_program_color_matrices(
xfm->base.ctx,
dpp->base.ctx,
regval,
&gam_regs);
}
}
/*program de gamma RAM B*/
void ippn10_program_degamma_lutb_settings(
struct transform *xfm_base,
void dpp1_program_degamma_lutb_settings(
struct dpp *dpp_base,
const struct pwl_params *params)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
struct xfer_func_reg gam_regs;
dcn10_dpp_cm_get_reg_field(xfm, &gam_regs);
dpp1_cm_get_reg_field(dpp, &gam_regs);
gam_regs.start_cntl_b = REG(CM_DGAM_RAMB_START_CNTL_B);
gam_regs.start_cntl_g = REG(CM_DGAM_RAMB_START_CNTL_G);
@ -556,18 +556,18 @@ void ippn10_program_degamma_lutb_settings(
gam_regs.region_end = REG(CM_DGAM_RAMB_REGION_14_15);
cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs);
cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
}
/*program de gamma RAM A*/
void ippn10_program_degamma_luta_settings(
struct transform *xfm_base,
void dpp1_program_degamma_luta_settings(
struct dpp *dpp_base,
const struct pwl_params *params)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
struct xfer_func_reg gam_regs;
dcn10_dpp_cm_get_reg_field(xfm, &gam_regs);
dpp1_cm_get_reg_field(dpp, &gam_regs);
gam_regs.start_cntl_b = REG(CM_DGAM_RAMA_START_CNTL_B);
gam_regs.start_cntl_g = REG(CM_DGAM_RAMA_START_CNTL_G);
@ -584,34 +584,35 @@ void ippn10_program_degamma_luta_settings(
gam_regs.region_start = REG(CM_DGAM_RAMA_REGION_0_1);
gam_regs.region_end = REG(CM_DGAM_RAMA_REGION_14_15);
cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs);
cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
}
void ippn10_power_on_degamma_lut(
struct transform *xfm_base,
void dpp1_power_on_degamma_lut(
struct dpp *dpp_base,
bool power_on)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
REG_SET(CM_MEM_PWR_CTRL, 0,
SHARED_MEM_PWR_DIS, power_on == true ? 0:1);
}
static void ippn10_enable_cm_block(
struct transform *xfm_base)
static void dpp1_enable_cm_block(
struct dpp *dpp_base)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
REG_UPDATE(CM_CMOUT_CONTROL, CM_CMOUT_ROUND_TRUNC_MODE, 8);
REG_UPDATE(CM_CONTROL, CM_BYPASS_EN, 0);
}
void ippn10_set_degamma(
struct transform *xfm_base,
void dpp1_set_degamma(
struct dpp *dpp_base,
enum ipp_degamma_mode mode)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
ippn10_enable_cm_block(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
dpp1_enable_cm_block(dpp_base);
switch (mode) {
case IPP_DEGAMMA_MODE_BYPASS:
@ -630,11 +631,11 @@ void ippn10_set_degamma(
}
}
void ippn10_degamma_ram_select(
struct transform *xfm_base,
void dpp1_degamma_ram_select(
struct dpp *dpp_base,
bool use_ram_a)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
if (use_ram_a)
REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 3);
@ -643,13 +644,13 @@ void ippn10_degamma_ram_select(
}
static bool ippn10_degamma_ram_inuse(
struct transform *xfm_base,
static bool dpp1_degamma_ram_inuse(
struct dpp *dpp_base,
bool *ram_a_inuse)
{
bool ret = false;
uint32_t status_reg = 0;
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
REG_GET(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_DGAM_CONFIG_STATUS,
&status_reg);
@ -664,15 +665,15 @@ static bool ippn10_degamma_ram_inuse(
return ret;
}
void ippn10_program_degamma_lut(
struct transform *xfm_base,
void dpp1_program_degamma_lut(
struct dpp *dpp_base,
const struct pwl_result_data *rgb,
uint32_t num,
bool is_ram_a)
{
uint32_t i;
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
REG_UPDATE(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_HOST_EN, 0);
REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK,
CM_DGAM_LUT_WRITE_EN_MASK, 7);
@ -694,27 +695,27 @@ void ippn10_program_degamma_lut(
}
}
void ippn10_set_degamma_pwl(struct transform *xfm_base,
void dpp1_set_degamma_pwl(struct dpp *dpp_base,
const struct pwl_params *params)
{
bool is_ram_a = true;
ippn10_power_on_degamma_lut(xfm_base, true);
ippn10_enable_cm_block(xfm_base);
ippn10_degamma_ram_inuse(xfm_base, &is_ram_a);
dpp1_power_on_degamma_lut(dpp_base, true);
dpp1_enable_cm_block(dpp_base);
dpp1_degamma_ram_inuse(dpp_base, &is_ram_a);
if (is_ram_a == true)
ippn10_program_degamma_lutb_settings(xfm_base, params);
dpp1_program_degamma_lutb_settings(dpp_base, params);
else
ippn10_program_degamma_luta_settings(xfm_base, params);
dpp1_program_degamma_luta_settings(dpp_base, params);
ippn10_program_degamma_lut(xfm_base, params->rgb_resulted,
dpp1_program_degamma_lut(dpp_base, params->rgb_resulted,
params->hw_points_num, !is_ram_a);
ippn10_degamma_ram_select(xfm_base, !is_ram_a);
dpp1_degamma_ram_select(dpp_base, !is_ram_a);
}
void ippn10_full_bypass(struct transform *xfm_base)
void dpp1_full_bypass(struct dpp *dpp_base)
{
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
/* Input pixel format: ARGB8888 */
REG_SET(CNVC_SURFACE_PIXEL_FORMAT, 0,
@ -727,19 +728,19 @@ void ippn10_full_bypass(struct transform *xfm_base)
FORMAT_EXPANSION_MODE, 0);
/* COLOR_KEYER_CONTROL.COLOR_KEYER_EN = 0 this should be default */
if (xfm->tf_mask->CM_BYPASS_EN)
if (dpp->tf_mask->CM_BYPASS_EN)
REG_SET(CM_CONTROL, 0, CM_BYPASS_EN, 1);
/* Setting degamma bypass for now */
REG_SET(CM_DGAM_CONTROL, 0, CM_DGAM_LUT_MODE, 0);
}
static bool ippn10_ingamma_ram_inuse(struct transform *xfm_base,
static bool dpp1_ingamma_ram_inuse(struct dpp *dpp_base,
bool *ram_a_inuse)
{
bool in_use = false;
uint32_t status_reg = 0;
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
REG_GET(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_DGAM_CONFIG_STATUS,
&status_reg);
@ -765,19 +766,19 @@ static bool ippn10_ingamma_ram_inuse(struct transform *xfm_base,
* In the future, this function should support additional input gamma methods,
* such as piecewise linear mapping, and input gamma bypass.
*/
void ippn10_program_input_lut(
struct transform *xfm_base,
void dpp1_program_input_lut(
struct dpp *dpp_base,
const struct dc_gamma *gamma)
{
int i;
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
bool rama_occupied = false;
uint32_t ram_num;
// Power on LUT memory.
REG_SET(CM_MEM_PWR_CTRL, 0, SHARED_MEM_PWR_DIS, 1);
ippn10_enable_cm_block(xfm_base);
dpp1_enable_cm_block(dpp_base);
// Determine whether to use RAM A or RAM B
ippn10_ingamma_ram_inuse(xfm_base, &rama_occupied);
dpp1_ingamma_ram_inuse(dpp_base, &rama_occupied);
if (!rama_occupied)
REG_UPDATE(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_SEL, 0);
else

View File

@ -31,6 +31,7 @@
#include "dcn10_dpp.h"
#include "basics/conversion.h"
#define NUM_PHASES 64
#define HORZ_MAX_TAPS 8
#define VERT_MAX_TAPS 8
@ -39,14 +40,14 @@
#define BLACK_OFFSET_CBCR 0x8000
#define REG(reg)\
xfm->tf_regs->reg
dpp->tf_regs->reg
#define CTX \
xfm->base.ctx
dpp->base.ctx
#undef FN
#define FN(reg_name, field_name) \
xfm->tf_shift->field_name, xfm->tf_mask->field_name
dpp->tf_shift->field_name, dpp->tf_mask->field_name
enum dcn10_coef_filter_type_sel {
SCL_COEF_LUMA_VERT_FILTER = 0,
@ -57,22 +58,6 @@ enum dcn10_coef_filter_type_sel {
SCL_COEF_ALPHA_HORZ_FILTER = 5
};
enum lb_memory_config {
/* Enable all 3 pieces of memory */
LB_MEMORY_CONFIG_0 = 0,
/* Enable only the first piece of memory */
LB_MEMORY_CONFIG_1 = 1,
/* Enable only the second piece of memory */
LB_MEMORY_CONFIG_2 = 2,
/* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the
* last piece of chroma memory used for the luma storage
*/
LB_MEMORY_CONFIG_3 = 3
};
enum dscl_autocal_mode {
AUTOCAL_MODE_OFF = 0,
@ -100,8 +85,8 @@ enum dscl_mode_sel {
DSCL_MODE_DSCL_BYPASS = 6
};
static void dpp_set_overscan(
struct dcn10_dpp *xfm,
static void dpp1_dscl_set_overscan(
struct dcn10_dpp *dpp,
const struct scaler_data *data)
{
uint32_t left = data->recout.x;
@ -128,8 +113,8 @@ static void dpp_set_overscan(
EXT_OVERSCAN_TOP, top);
}
static void dpp_set_otg_blank(
struct dcn10_dpp *xfm, const struct scaler_data *data)
static void dpp1_dscl_set_otg_blank(
struct dcn10_dpp *dpp, const struct scaler_data *data)
{
uint32_t h_blank_start = data->h_active;
uint32_t h_blank_end = 0;
@ -145,7 +130,7 @@ static void dpp_set_otg_blank(
OTG_V_BLANK_END, v_blank_end);
}
static int get_pixel_depth_val(enum lb_pixel_depth depth)
static int dpp1_dscl_get_pixel_depth_val(enum lb_pixel_depth depth)
{
if (depth == LB_PIXEL_DEPTH_30BPP)
return 0; /* 10 bpc */
@ -161,23 +146,36 @@ static int get_pixel_depth_val(enum lb_pixel_depth depth)
}
}
static enum dscl_mode_sel get_dscl_mode(
const struct scaler_data *data, bool dbg_always_scale)
static bool dpp1_dscl_is_video_format(enum pixel_format format)
{
if (format >= PIXEL_FORMAT_VIDEO_BEGIN
&& format <= PIXEL_FORMAT_VIDEO_END)
return true;
else
return false;
}
static bool dpp1_dscl_is_420_format(enum pixel_format format)
{
if (format == PIXEL_FORMAT_420BPP8 ||
format == PIXEL_FORMAT_420BPP10)
return true;
else
return false;
}
static enum dscl_mode_sel dpp1_dscl_get_dscl_mode(
struct dpp *dpp_base,
const struct scaler_data *data,
bool dbg_always_scale)
{
const long long one = dal_fixed31_32_one.value;
bool ycbcr = false;
bool format420 = false;
if (data->format == PIXEL_FORMAT_FP16)
return DSCL_MODE_DSCL_BYPASS;
if (data->format >= PIXEL_FORMAT_VIDEO_BEGIN
&& data->format <= PIXEL_FORMAT_VIDEO_END)
ycbcr = true;
if (data->format == PIXEL_FORMAT_420BPP8 ||
data->format == PIXEL_FORMAT_420BPP10)
format420 = true;
if (dpp_base->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) {
/* DSCL is processing data in fixed format */
if (data->format == PIXEL_FORMAT_FP16)
return DSCL_MODE_DSCL_BYPASS;
}
if (data->ratios.horz.value == one
&& data->ratios.vert.value == one
@ -186,8 +184,8 @@ static enum dscl_mode_sel get_dscl_mode(
&& !dbg_always_scale)
return DSCL_MODE_SCALING_444_BYPASS;
if (!format420) {
if (ycbcr)
if (!dpp1_dscl_is_420_format(data->format)) {
if (dpp1_dscl_is_video_format(data->format))
return DSCL_MODE_SCALING_444_YCBCR_ENABLE;
else
return DSCL_MODE_SCALING_444_RGB_ENABLE;
@ -200,16 +198,17 @@ static enum dscl_mode_sel get_dscl_mode(
return DSCL_MODE_SCALING_420_YCBCR_ENABLE;
}
static void dpp_set_lb(
struct dcn10_dpp *xfm,
static void dpp1_dscl_set_lb(
struct dcn10_dpp *dpp,
const struct line_buffer_params *lb_params,
enum lb_memory_config mem_size_config)
{
uint32_t pixel_depth = get_pixel_depth_val(lb_params->depth);
uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth;
/* LB */
if (xfm->tf_mask->PIXEL_DEPTH) {
if (dpp->base.caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) {
/* DSCL caps: pixel data processed in fixed format */
uint32_t pixel_depth = dpp1_dscl_get_pixel_depth_val(lb_params->depth);
uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth;
REG_SET_7(LB_DATA_FORMAT, 0,
PIXEL_DEPTH, pixel_depth, /* Pixel depth stored in LB */
PIXEL_EXPAN_MODE, lb_params->pixel_expan_mode, /* Pixel expansion mode */
@ -225,7 +224,7 @@ static void dpp_set_lb(
LB_MAX_PARTITIONS, 63);
}
static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
static const uint16_t *dpp1_dscl_get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
{
if (taps == 8)
return get_filter_8tap_64p(ratio);
@ -250,8 +249,8 @@ static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
}
}
static void dpp_set_scaler_filter(
struct dcn10_dpp *xfm,
static void dpp1_dscl_set_scaler_filter(
struct dcn10_dpp *dpp,
uint32_t taps,
enum dcn10_coef_filter_type_sel filter_type,
const uint16_t *filter)
@ -288,8 +287,8 @@ static void dpp_set_scaler_filter(
}
static void dpp_set_scl_filter(
struct dcn10_dpp *xfm,
static void dpp1_dscl_set_scl_filter(
struct dcn10_dpp *dpp,
const struct scaler_data *scl_data,
bool chroma_coef_mode)
{
@ -307,10 +306,10 @@ static void dpp_set_scl_filter(
h_2tap_hardcode_coef_en = scl_data->taps.h_taps < 3
&& scl_data->taps.h_taps_c < 3
&& (scl_data->taps.h_taps > 1 || scl_data->taps.h_taps_c > 1);
&& (scl_data->taps.h_taps > 1 && scl_data->taps.h_taps_c > 1);
v_2tap_hardcode_coef_en = scl_data->taps.v_taps < 3
&& scl_data->taps.v_taps_c < 3
&& (scl_data->taps.v_taps > 1 || scl_data->taps.v_taps_c > 1);
&& (scl_data->taps.v_taps > 1 && scl_data->taps.v_taps_c > 1);
h_2tap_sharp_en = h_2tap_hardcode_coef_en && h_2tap_sharp_factor != 0;
v_2tap_sharp_en = v_2tap_hardcode_coef_en && v_2tap_sharp_factor != 0;
@ -326,56 +325,56 @@ static void dpp_set_scl_filter(
if (!v_2tap_hardcode_coef_en || !h_2tap_hardcode_coef_en) {
bool filter_updated = false;
filter_h = get_filter_coeffs_64p(
filter_h = dpp1_dscl_get_filter_coeffs_64p(
scl_data->taps.h_taps, scl_data->ratios.horz);
filter_v = get_filter_coeffs_64p(
filter_v = dpp1_dscl_get_filter_coeffs_64p(
scl_data->taps.v_taps, scl_data->ratios.vert);
filter_updated = (filter_h && (filter_h != xfm->filter_h))
|| (filter_v && (filter_v != xfm->filter_v));
filter_updated = (filter_h && (filter_h != dpp->filter_h))
|| (filter_v && (filter_v != dpp->filter_v));
if (chroma_coef_mode) {
filter_h_c = get_filter_coeffs_64p(
filter_h_c = dpp1_dscl_get_filter_coeffs_64p(
scl_data->taps.h_taps_c, scl_data->ratios.horz_c);
filter_v_c = get_filter_coeffs_64p(
filter_v_c = dpp1_dscl_get_filter_coeffs_64p(
scl_data->taps.v_taps_c, scl_data->ratios.vert_c);
filter_updated = filter_updated || (filter_h_c && (filter_h_c != xfm->filter_h_c))
|| (filter_v_c && (filter_v_c != xfm->filter_v_c));
filter_updated = filter_updated || (filter_h_c && (filter_h_c != dpp->filter_h_c))
|| (filter_v_c && (filter_v_c != dpp->filter_v_c));
}
if (filter_updated) {
uint32_t scl_mode = REG_READ(SCL_MODE);
if (!h_2tap_hardcode_coef_en && filter_h) {
dpp_set_scaler_filter(
xfm, scl_data->taps.h_taps,
dpp1_dscl_set_scaler_filter(
dpp, scl_data->taps.h_taps,
SCL_COEF_LUMA_HORZ_FILTER, filter_h);
}
xfm->filter_h = filter_h;
dpp->filter_h = filter_h;
if (!v_2tap_hardcode_coef_en && filter_v) {
dpp_set_scaler_filter(
xfm, scl_data->taps.v_taps,
dpp1_dscl_set_scaler_filter(
dpp, scl_data->taps.v_taps,
SCL_COEF_LUMA_VERT_FILTER, filter_v);
}
xfm->filter_v = filter_v;
dpp->filter_v = filter_v;
if (chroma_coef_mode) {
if (!h_2tap_hardcode_coef_en && filter_h_c) {
dpp_set_scaler_filter(
xfm, scl_data->taps.h_taps_c,
dpp1_dscl_set_scaler_filter(
dpp, scl_data->taps.h_taps_c,
SCL_COEF_CHROMA_HORZ_FILTER, filter_h_c);
}
if (!v_2tap_hardcode_coef_en && filter_v_c) {
dpp_set_scaler_filter(
xfm, scl_data->taps.v_taps_c,
dpp1_dscl_set_scaler_filter(
dpp, scl_data->taps.v_taps_c,
SCL_COEF_CHROMA_VERT_FILTER, filter_v_c);
}
}
xfm->filter_h_c = filter_h_c;
xfm->filter_v_c = filter_v_c;
dpp->filter_h_c = filter_h_c;
dpp->filter_v_c = filter_v_c;
coef_ram_current = get_reg_field_value_ex(
scl_mode, xfm->tf_mask->SCL_COEF_RAM_SELECT_CURRENT,
xfm->tf_shift->SCL_COEF_RAM_SELECT_CURRENT);
scl_mode, dpp->tf_mask->SCL_COEF_RAM_SELECT_CURRENT,
dpp->tf_shift->SCL_COEF_RAM_SELECT_CURRENT);
/* Swap coefficient RAM and set chroma coefficient mode */
REG_SET_2(SCL_MODE, scl_mode,
@ -385,7 +384,7 @@ static void dpp_set_scl_filter(
}
}
static int get_lb_depth_bpc(enum lb_pixel_depth depth)
static int dpp1_dscl_get_lb_depth_bpc(enum lb_pixel_depth depth)
{
if (depth == LB_PIXEL_DEPTH_30BPP)
return 10;
@ -401,7 +400,7 @@ static int get_lb_depth_bpc(enum lb_pixel_depth depth)
}
}
static void calc_lb_num_partitions(
void dpp1_dscl_calc_lb_num_partitions(
const struct scaler_data *scl_data,
enum lb_memory_config lb_config,
int *num_part_y,
@ -411,7 +410,7 @@ static void calc_lb_num_partitions(
scl_data->viewport.width : scl_data->recout.width;
int line_size_c = scl_data->viewport_c.width < scl_data->recout.width ?
scl_data->viewport_c.width : scl_data->recout.width;
int lb_bpc = get_lb_depth_bpc(scl_data->lb_params.depth);
int lb_bpc = dpp1_dscl_get_lb_depth_bpc(scl_data->lb_params.depth);
int memory_line_size_y = (line_size * lb_bpc + 71) / 72; /* +71 to ceil */
int memory_line_size_c = (line_size_c * lb_bpc + 71) / 72; /* +71 to ceil */
int memory_line_size_a = (line_size + 5) / 6; /* +5 to ceil */
@ -426,6 +425,7 @@ static void calc_lb_num_partitions(
lb_memory_size_c = 1088;
lb_memory_size_a = 1312;
} else if (lb_config == LB_MEMORY_CONFIG_3) {
/* 420 mode: using 3rd mem from Y, Cr and Cb */
lb_memory_size = 816 + 1088 + 848 + 848 + 848;
lb_memory_size_c = 816 + 1088;
lb_memory_size_a = 984 + 1312 + 456;
@ -449,7 +449,7 @@ static void calc_lb_num_partitions(
}
static bool is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps)
bool dpp1_dscl_is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps)
{
if (ceil_vratio > 2)
return vtaps <= (num_partitions - ceil_vratio + 2);
@ -458,7 +458,7 @@ static bool is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps)
}
/*find first match configuration which meets the min required lb size*/
static enum lb_memory_config dpp10_find_lb_memory_config(
static enum lb_memory_config dpp1_dscl_find_lb_memory_config(struct dcn10_dpp *dpp,
const struct scaler_data *scl_data)
{
int num_part_y, num_part_c;
@ -466,75 +466,67 @@ static enum lb_memory_config dpp10_find_lb_memory_config(
int vtaps_c = scl_data->taps.v_taps_c;
int ceil_vratio = dal_fixed31_32_ceil(scl_data->ratios.vert);
int ceil_vratio_c = dal_fixed31_32_ceil(scl_data->ratios.vert_c);
enum lb_memory_config mem_cfg = LB_MEMORY_CONFIG_0;
calc_lb_num_partitions(
if (dpp->base.ctx->dc->debug.use_max_lb)
return mem_cfg;
dpp->base.caps->dscl_calc_lb_num_partitions(
scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c);
if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
&& is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
&& dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
return LB_MEMORY_CONFIG_1;
calc_lb_num_partitions(
dpp->base.caps->dscl_calc_lb_num_partitions(
scl_data, LB_MEMORY_CONFIG_2, &num_part_y, &num_part_c);
if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
&& is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
&& dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
return LB_MEMORY_CONFIG_2;
if (scl_data->format == PIXEL_FORMAT_420BPP8
|| scl_data->format == PIXEL_FORMAT_420BPP10) {
calc_lb_num_partitions(
dpp->base.caps->dscl_calc_lb_num_partitions(
scl_data, LB_MEMORY_CONFIG_3, &num_part_y, &num_part_c);
if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
&& is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
&& dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
return LB_MEMORY_CONFIG_3;
}
calc_lb_num_partitions(
dpp->base.caps->dscl_calc_lb_num_partitions(
scl_data, LB_MEMORY_CONFIG_0, &num_part_y, &num_part_c);
/*Ensure we can support the requested number of vtaps*/
ASSERT(is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
&& is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c));
ASSERT(dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
&& dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c));
return LB_MEMORY_CONFIG_0;
}
/*find first match configuration which meets the min required lb size*/
static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *xfm,
const struct scaler_data *scl_data)
{
enum lb_memory_config mem_cfg = LB_MEMORY_CONFIG_0;
if (xfm->tf_mask->PIXEL_DEPTH) {
mem_cfg = dpp10_find_lb_memory_config(scl_data);
}
return mem_cfg;
}
void dpp_set_scaler_auto_scale(
struct transform *xfm_base,
void dpp1_dscl_set_scaler_auto_scale(
struct dpp *dpp_base,
const struct scaler_data *scl_data)
{
enum lb_memory_config lb_config;
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
enum dscl_mode_sel dscl_mode = get_dscl_mode(
scl_data, xfm_base->ctx->dc->debug.always_scale);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
enum dscl_mode_sel dscl_mode = dpp1_dscl_get_dscl_mode(
dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale);
bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN
&& scl_data->format <= PIXEL_FORMAT_VIDEO_END;
dpp_set_overscan(xfm, scl_data);
dpp1_dscl_set_overscan(dpp, scl_data);
dpp_set_otg_blank(xfm, scl_data);
dpp1_dscl_set_otg_blank(dpp, scl_data);
REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode);
if (dscl_mode == DSCL_MODE_DSCL_BYPASS)
return;
lb_config = find_lb_memory_config(xfm, scl_data);
dpp_set_lb(xfm, &scl_data->lb_params, lb_config);
lb_config = dpp1_dscl_find_lb_memory_config(dpp, scl_data);
dpp1_dscl_set_lb(dpp, &scl_data->lb_params, lb_config);
if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS)
return;
@ -562,12 +554,12 @@ void dpp_set_scaler_auto_scale(
SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1,
SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1);
dpp_set_scl_filter(xfm, scl_data, ycbcr);
dpp1_dscl_set_scl_filter(dpp, scl_data, ycbcr);
}
static void dpp_set_manual_ratio_init(
struct dcn10_dpp *xfm, const struct scaler_data *data)
static void dpp1_dscl_set_manual_ratio_init(
struct dcn10_dpp *dpp, const struct scaler_data *data)
{
uint32_t init_frac = 0;
uint32_t init_int = 0;
@ -626,8 +618,8 @@ static void dpp_set_manual_ratio_init(
static void dpp_set_recout(
struct dcn10_dpp *xfm, const struct rect *recout)
static void dpp1_dscl_set_recout(
struct dcn10_dpp *dpp, const struct rect *recout)
{
REG_SET_2(RECOUT_START, 0,
/* First pixel of RECOUT */
@ -640,24 +632,24 @@ static void dpp_set_recout(
RECOUT_WIDTH, recout->width,
/* Number of RECOUT vertical lines */
RECOUT_HEIGHT, recout->height
- xfm->base.ctx->dc->debug.surface_visual_confirm * 4 *
(xfm->base.inst + 1));
- dpp->base.ctx->dc->debug.surface_visual_confirm * 4 *
(dpp->base.inst + 1));
}
/* Main function to program scaler and line buffer in manual scaling mode */
void dcn10_dpp_dscl_set_scaler_manual_scale(
struct transform *xfm_base,
void dpp1_dscl_set_scaler_manual_scale(
struct dpp *dpp_base,
const struct scaler_data *scl_data)
{
enum lb_memory_config lb_config;
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
enum dscl_mode_sel dscl_mode = get_dscl_mode(
scl_data, xfm_base->ctx->dc->debug.always_scale);
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
enum dscl_mode_sel dscl_mode = dpp1_dscl_get_dscl_mode(
dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale);
bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN
&& scl_data->format <= PIXEL_FORMAT_VIDEO_END;
/* Recout */
dpp_set_recout(xfm, &scl_data->recout);
dpp1_dscl_set_recout(dpp, &scl_data->recout);
/* MPC Size */
REG_SET_2(MPC_SIZE, 0,
@ -673,8 +665,8 @@ void dcn10_dpp_dscl_set_scaler_manual_scale(
return;
/* LB */
lb_config = find_lb_memory_config(xfm, scl_data);
dpp_set_lb(xfm, &scl_data->lb_params, lb_config);
lb_config = dpp1_dscl_find_lb_memory_config(dpp, scl_data);
dpp1_dscl_set_lb(dpp, &scl_data->lb_params, lb_config);
if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS)
return;
@ -697,7 +689,7 @@ void dcn10_dpp_dscl_set_scaler_manual_scale(
SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y);
/* Manually calculate scale ratio and init values */
dpp_set_manual_ratio_init(xfm, scl_data);
dpp1_dscl_set_manual_ratio_init(dpp, scl_data);
/* HTaps/VTaps */
REG_SET_4(SCL_TAP_CONTROL, 0,
@ -706,5 +698,5 @@ void dcn10_dpp_dscl_set_scaler_manual_scale(
SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1,
SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1);
dpp_set_scl_filter(xfm, scl_data, ycbcr);
dpp1_dscl_set_scl_filter(dpp, scl_data, ycbcr);
}

View File

@ -24,23 +24,23 @@
*/
#include "dm_services.h"
#include "dce_calcs.h"
#include "dcn10_mem_input.h"
#include "reg_helper.h"
#include "basics/conversion.h"
#include "dcn10_hubp.h"
#define REG(reg)\
mi->mi_regs->reg
hubp1->mi_regs->reg
#define CTX \
mi->base.ctx
hubp1->base.ctx
#undef FN
#define FN(reg_name, field_name) \
mi->mi_shift->field_name, mi->mi_mask->field_name
hubp1->mi_shift->field_name, hubp1->mi_mask->field_name
static void min10_set_blank(struct mem_input *mem_input, bool blank)
void hubp1_set_blank(struct hubp *hubp, bool blank)
{
struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
uint32_t blank_en = blank ? 1 : 0;
REG_UPDATE_2(DCHUBP_CNTL,
@ -51,24 +51,24 @@ static void min10_set_blank(struct mem_input *mem_input, bool blank)
REG_WAIT(DCHUBP_CNTL,
HUBP_NO_OUTSTANDING_REQ, 1,
1, 200);
mem_input->mpcc_id = 0xf;
mem_input->opp_id = 0xf;
hubp->mpcc_id = 0xf;
hubp->opp_id = 0xf;
}
}
static void min10_set_hubp_blank_en(struct mem_input *mem_input, bool blank)
static void hubp1_set_hubp_blank_en(struct hubp *hubp, bool blank)
{
struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
uint32_t blank_en = blank ? 1 : 0;
REG_UPDATE(DCHUBP_CNTL, HUBP_BLANK_EN, blank_en);
}
static void min10_vready_workaround(struct mem_input *mem_input,
static void hubp1_vready_workaround(struct hubp *hubp,
struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest)
{
uint32_t value = 0;
struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
/* set HBUBREQ_DEBUG_DB[12] = 1 */
value = REG_READ(HUBPREQ_DEBUG_DB);
@ -87,8 +87,8 @@ static void min10_vready_workaround(struct mem_input *mem_input,
REG_WRITE(HUBPREQ_DEBUG_DB, value);
}
static void min10_program_tiling(
struct dcn10_mem_input *mi,
void hubp1_program_tiling(
struct dcn10_hubp *hubp1,
const union dc_tiling_info *info,
const enum surface_pixel_format pixel_format)
{
@ -107,8 +107,8 @@ static void min10_program_tiling(
PIPE_ALIGNED, info->gfx9.pipe_aligned);
}
static void min10_program_size_and_rotation(
struct dcn10_mem_input *mi,
void hubp1_program_size_and_rotation(
struct dcn10_hubp *hubp1,
enum dc_rotation_angle rotation,
enum surface_pixel_format format,
const union plane_size *plane_size,
@ -169,8 +169,8 @@ static void min10_program_size_and_rotation(
H_MIRROR_EN, mirror);
}
static void min10_program_pixel_format(
struct dcn10_mem_input *mi,
void hubp1_program_pixel_format(
struct dcn10_hubp *hubp1,
enum surface_pixel_format format)
{
uint32_t red_bar = 3;
@ -245,12 +245,12 @@ static void min10_program_pixel_format(
/* don't see the need of program the xbar in DCN 1.0 */
}
static bool min10_program_surface_flip_and_addr(
struct mem_input *mem_input,
bool hubp1_program_surface_flip_and_addr(
struct hubp *hubp,
const struct dc_plane_address *address,
bool flip_immediate)
{
struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
/* program flip type */
REG_SET(DCSURF_FLIP_CONTROL, 0,
@ -387,28 +387,28 @@ static bool min10_program_surface_flip_and_addr(
break;
}
mem_input->request_address = *address;
hubp->request_address = *address;
if (flip_immediate)
mem_input->current_address = *address;
hubp->current_address = *address;
return true;
}
static void min10_dcc_control(struct mem_input *mem_input, bool enable,
void hubp1_dcc_control(struct hubp *hubp, bool enable,
bool independent_64b_blks)
{
uint32_t dcc_en = enable ? 1 : 0;
uint32_t dcc_ind_64b_blk = independent_64b_blks ? 1 : 0;
struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
PRIMARY_SURFACE_DCC_EN, dcc_en,
PRIMARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk);
}
static void min10_program_surface_config(
struct mem_input *mem_input,
void hubp1_program_surface_config(
struct hubp *hubp,
enum surface_pixel_format format,
union dc_tiling_info *tiling_info,
union plane_size *plane_size,
@ -416,20 +416,20 @@ static void min10_program_surface_config(
struct dc_plane_dcc_param *dcc,
bool horizontal_mirror)
{
struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
min10_dcc_control(mem_input, dcc->enable, dcc->grph.independent_64b_blks);
min10_program_tiling(mi, tiling_info, format);
min10_program_size_and_rotation(
mi, rotation, format, plane_size, dcc, horizontal_mirror);
min10_program_pixel_format(mi, format);
hubp1_dcc_control(hubp, dcc->enable, dcc->grph.independent_64b_blks);
hubp1_program_tiling(hubp1, tiling_info, format);
hubp1_program_size_and_rotation(
hubp1, rotation, format, plane_size, dcc, horizontal_mirror);
hubp1_program_pixel_format(hubp1, format);
}
static void min10_program_requestor(
struct mem_input *mem_input,
void hubp1_program_requestor(
struct hubp *hubp,
struct _vcs_dpi_display_rq_regs_st *rq_regs)
{
struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
REG_UPDATE(HUBPRET_CONTROL,
DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address);
@ -459,12 +459,12 @@ static void min10_program_requestor(
}
static void min10_program_deadline(
struct mem_input *mem_input,
void hubp1_program_deadline(
struct hubp *hubp,
struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
struct _vcs_dpi_display_ttu_regs_st *ttu_attr)
{
struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
/* DLG - Per hubp */
REG_SET_2(BLANK_OFFSET_0, 0,
@ -580,8 +580,8 @@ static void min10_program_deadline(
ttu_attr->refcyc_per_req_delivery_pre_c);
}
static void min10_setup(
struct mem_input *mem_input,
static void hubp1_setup(
struct hubp *hubp,
struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
struct _vcs_dpi_display_ttu_regs_st *ttu_attr,
struct _vcs_dpi_display_rq_regs_st *rq_regs,
@ -590,27 +590,15 @@ static void min10_setup(
/* otg is locked when this func is called. Register are double buffered.
* disable the requestors is not needed
*/
min10_program_requestor(mem_input, rq_regs);
min10_program_deadline(mem_input, dlg_attr, ttu_attr);
min10_vready_workaround(mem_input, pipe_dest);
hubp1_program_requestor(hubp, rq_regs);
hubp1_program_deadline(hubp, dlg_attr, ttu_attr);
hubp1_vready_workaround(hubp, pipe_dest);
}
static void min10_program_display_marks(
struct mem_input *mem_input,
struct dce_watermarks nbp,
struct dce_watermarks stutter,
struct dce_watermarks urgent,
uint32_t total_dest_line_time_ns)
{
/* only for dce
* dcn use only program_watermarks
*/
}
static bool min10_is_flip_pending(struct mem_input *mem_input)
bool hubp1_is_flip_pending(struct hubp *hubp)
{
uint32_t flip_pending = 0;
struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
struct dc_plane_address earliest_inuse_address;
REG_GET(DCSURF_FLIP_CONTROL,
@ -625,17 +613,20 @@ static bool min10_is_flip_pending(struct mem_input *mem_input)
if (flip_pending)
return true;
if (earliest_inuse_address.grph.addr.quad_part != mem_input->request_address.grph.addr.quad_part)
if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
return true;
mem_input->current_address = mem_input->request_address;
hubp->current_address = hubp->request_address;
return false;
}
static void min10_set_vm_system_aperture_settings(struct mem_input *mem_input,
uint32_t aperture_default_system = 1;
uint32_t context0_default_system; /* = 0;*/
static void hubp1_set_vm_system_aperture_settings(struct hubp *hubp,
struct vm_system_aperture_param *apt)
{
struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
PHYSICAL_ADDRESS_LOC mc_vm_apt_default;
PHYSICAL_ADDRESS_LOC mc_vm_apt_low;
PHYSICAL_ADDRESS_LOC mc_vm_apt_high;
@ -645,7 +636,7 @@ static void min10_set_vm_system_aperture_settings(struct mem_input *mem_input,
mc_vm_apt_high.quad_part = apt->sys_high.quad_part >> 12;
REG_SET_2(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0,
MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, 1, /* 1 = system physical memory */
MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, aperture_default_system, /* 1 = system physical memory */
MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mc_vm_apt_default.high_part);
REG_SET(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0,
MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mc_vm_apt_default.low_part);
@ -661,10 +652,10 @@ static void min10_set_vm_system_aperture_settings(struct mem_input *mem_input,
MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, mc_vm_apt_high.low_part);
}
static void min10_set_vm_context0_settings(struct mem_input *mem_input,
static void hubp1_set_vm_context0_settings(struct hubp *hubp,
const struct vm_context0_param *vm0)
{
struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
/* pte base */
REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, 0,
VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, vm0->pte_base.high_part);
@ -684,9 +675,9 @@ static void min10_set_vm_context0_settings(struct mem_input *mem_input,
VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, vm0->pte_end.low_part);
/* fault handling */
REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, 0,
VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, vm0->fault_default.high_part);
/* VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, 0 */
REG_SET_2(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, 0,
VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, vm0->fault_default.high_part,
VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, context0_default_system);
REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, 0,
VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, vm0->fault_default.low_part);
@ -696,12 +687,12 @@ static void min10_set_vm_context0_settings(struct mem_input *mem_input,
SYSTEM_ACCESS_MODE, 3);
}
static void min_set_viewport(
struct mem_input *mem_input,
void min_set_viewport(
struct hubp *hubp,
const struct rect *viewport,
const struct rect *viewport_c)
{
struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION, 0,
PRI_VIEWPORT_WIDTH, viewport->width,
@ -730,7 +721,7 @@ static void min_set_viewport(
PRI_VIEWPORT_Y_START_C, viewport_c->y);
}
void dcn10_mem_input_read_state(struct dcn10_mem_input *mi,
void hubp1_read_state(struct dcn10_hubp *hubp1,
struct dcn_hubp_state *s)
{
REG_GET(DCSURF_SURFACE_CONFIG,
@ -766,41 +757,204 @@ void dcn10_mem_input_read_state(struct dcn10_mem_input *mi,
QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm);
}
static struct mem_input_funcs dcn10_mem_input_funcs = {
.mem_input_program_display_marks = min10_program_display_marks,
.mem_input_program_surface_flip_and_addr =
min10_program_surface_flip_and_addr,
.mem_input_program_surface_config =
min10_program_surface_config,
.mem_input_is_flip_pending = min10_is_flip_pending,
.mem_input_setup = min10_setup,
.mem_input_set_vm_system_aperture_settings = min10_set_vm_system_aperture_settings,
.mem_input_set_vm_context0_settings = min10_set_vm_context0_settings,
.set_blank = min10_set_blank,
.dcc_control = min10_dcc_control,
enum cursor_pitch {
CURSOR_PITCH_64_PIXELS = 0,
CURSOR_PITCH_128_PIXELS,
CURSOR_PITCH_256_PIXELS
};
enum cursor_lines_per_chunk {
CURSOR_LINE_PER_CHUNK_2 = 1,
CURSOR_LINE_PER_CHUNK_4,
CURSOR_LINE_PER_CHUNK_8,
CURSOR_LINE_PER_CHUNK_16
};
static bool ippn10_cursor_program_control(
struct dcn10_hubp *hubp1,
bool pixel_data_invert,
enum dc_cursor_color_format color_format)
{
if (REG(CURSOR_SETTINS))
REG_SET_2(CURSOR_SETTINS, 0,
/* no shift of the cursor HDL schedule */
CURSOR0_DST_Y_OFFSET, 0,
/* used to shift the cursor chunk request deadline */
CURSOR0_CHUNK_HDL_ADJUST, 3);
else
REG_SET_2(CURSOR_SETTINGS, 0,
/* no shift of the cursor HDL schedule */
CURSOR0_DST_Y_OFFSET, 0,
/* used to shift the cursor chunk request deadline */
CURSOR0_CHUNK_HDL_ADJUST, 3);
return true;
}
static enum cursor_pitch ippn10_get_cursor_pitch(
unsigned int pitch)
{
enum cursor_pitch hw_pitch;
switch (pitch) {
case 64:
hw_pitch = CURSOR_PITCH_64_PIXELS;
break;
case 128:
hw_pitch = CURSOR_PITCH_128_PIXELS;
break;
case 256:
hw_pitch = CURSOR_PITCH_256_PIXELS;
break;
default:
DC_ERR("Invalid cursor pitch of %d. "
"Only 64/128/256 is supported on DCN.\n", pitch);
hw_pitch = CURSOR_PITCH_64_PIXELS;
break;
}
return hw_pitch;
}
static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk(
unsigned int cur_width,
enum dc_cursor_color_format format)
{
enum cursor_lines_per_chunk line_per_chunk;
if (format == CURSOR_MODE_MONO)
/* impl B. expansion in CUR Buffer reader */
line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
else if (cur_width <= 32)
line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
else if (cur_width <= 64)
line_per_chunk = CURSOR_LINE_PER_CHUNK_8;
else if (cur_width <= 128)
line_per_chunk = CURSOR_LINE_PER_CHUNK_4;
else
line_per_chunk = CURSOR_LINE_PER_CHUNK_2;
return line_per_chunk;
}
void hubp1_cursor_set_attributes(
struct hubp *hubp,
const struct dc_cursor_attributes *attr)
{
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch);
enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk(
attr->width, attr->color_format);
hubp->curs_attr = *attr;
REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH,
CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part);
REG_UPDATE(CURSOR_SURFACE_ADDRESS,
CURSOR_SURFACE_ADDRESS, attr->address.low_part);
REG_UPDATE_2(CURSOR_SIZE,
CURSOR_WIDTH, attr->width,
CURSOR_HEIGHT, attr->height);
REG_UPDATE_3(CURSOR_CONTROL,
CURSOR_MODE, attr->color_format,
CURSOR_PITCH, hw_pitch,
CURSOR_LINES_PER_CHUNK, lpc);
ippn10_cursor_program_control(hubp1,
attr->attribute_flags.bits.INVERT_PIXEL_DATA,
attr->color_format);
}
void hubp1_cursor_set_position(
struct hubp *hubp,
const struct dc_cursor_position *pos,
const struct dc_cursor_mi_param *param)
{
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
uint32_t cur_en = pos->enable ? 1 : 0;
uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
/*
* Guard aganst cursor_set_position() from being called with invalid
* attributes
*
* TODO: Look at combining cursor_set_position() and
* cursor_set_attributes() into cursor_update()
*/
if (hubp->curs_attr.address.quad_part == 0)
return;
dst_x_offset *= param->ref_clk_khz;
dst_x_offset /= param->pixel_clk_khz;
ASSERT(param->h_scale_ratio.value);
if (param->h_scale_ratio.value)
dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div(
dal_fixed31_32_from_int(dst_x_offset),
param->h_scale_ratio));
if (src_x_offset >= (int)param->viewport_width)
cur_en = 0; /* not visible beyond right edge*/
if (src_x_offset + (int)hubp->curs_attr.width < 0)
cur_en = 0; /* not visible beyond left edge*/
if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
hubp1_cursor_set_attributes(hubp, &hubp->curs_attr);
REG_UPDATE(CURSOR_CONTROL,
CURSOR_ENABLE, cur_en);
REG_SET_2(CURSOR_POSITION, 0,
CURSOR_X_POSITION, pos->x,
CURSOR_Y_POSITION, pos->y);
REG_SET_2(CURSOR_HOT_SPOT, 0,
CURSOR_HOT_SPOT_X, pos->x_hotspot,
CURSOR_HOT_SPOT_Y, pos->y_hotspot);
REG_SET(CURSOR_DST_OFFSET, 0,
CURSOR_DST_X_OFFSET, dst_x_offset);
/* TODO Handle surface pixel formats other than 4:4:4 */
}
static struct hubp_funcs dcn10_hubp_funcs = {
.hubp_program_surface_flip_and_addr =
hubp1_program_surface_flip_and_addr,
.hubp_program_surface_config =
hubp1_program_surface_config,
.hubp_is_flip_pending = hubp1_is_flip_pending,
.hubp_setup = hubp1_setup,
.hubp_set_vm_system_aperture_settings = hubp1_set_vm_system_aperture_settings,
.hubp_set_vm_context0_settings = hubp1_set_vm_context0_settings,
.set_blank = hubp1_set_blank,
.dcc_control = hubp1_dcc_control,
.mem_program_viewport = min_set_viewport,
.set_hubp_blank_en = min10_set_hubp_blank_en,
.set_hubp_blank_en = hubp1_set_hubp_blank_en,
.set_cursor_attributes = hubp1_cursor_set_attributes,
.set_cursor_position = hubp1_cursor_set_position,
};
/*****************************************/
/* Constructor, Destructor */
/*****************************************/
void dcn10_mem_input_construct(
struct dcn10_mem_input *mi,
void dcn10_hubp_construct(
struct dcn10_hubp *hubp1,
struct dc_context *ctx,
uint32_t inst,
const struct dcn_mi_registers *mi_regs,
const struct dcn_mi_shift *mi_shift,
const struct dcn_mi_mask *mi_mask)
{
mi->base.funcs = &dcn10_mem_input_funcs;
mi->base.ctx = ctx;
mi->mi_regs = mi_regs;
mi->mi_shift = mi_shift;
mi->mi_mask = mi_mask;
mi->base.inst = inst;
mi->base.opp_id = 0xf;
mi->base.mpcc_id = 0xf;
hubp1->base.funcs = &dcn10_hubp_funcs;
hubp1->base.ctx = ctx;
hubp1->mi_regs = mi_regs;
hubp1->mi_shift = mi_shift;
hubp1->mi_mask = mi_mask;
hubp1->base.inst = inst;
hubp1->base.opp_id = 0xf;
hubp1->base.mpcc_id = 0xf;
}

View File

@ -25,11 +25,10 @@
#ifndef __DC_MEM_INPUT_DCN10_H__
#define __DC_MEM_INPUT_DCN10_H__
#include "mem_input.h"
#define TO_DCN10_MEM_INPUT(mi)\
container_of(mi, struct dcn10_mem_input, base)
#include "hubp.h"
#define TO_DCN10_HUBP(hubp)\
container_of(hubp, struct dcn10_hubp, base)
#define MI_REG_LIST_DCN(id)\
SRI(DCHUBP_CNTL, HUBP, id),\
@ -118,7 +117,17 @@
SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, HUBPREQ, id),\
SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, HUBPREQ, id),\
SR(DCHUBBUB_SDPIF_FB_BASE),\
SR(DCHUBBUB_SDPIF_FB_OFFSET)
SR(DCHUBBUB_SDPIF_FB_OFFSET),\
SRI(CURSOR_SETTINS, HUBPREQ, id), \
SRI(CURSOR_SURFACE_ADDRESS_HIGH, CURSOR, id), \
SRI(CURSOR_SURFACE_ADDRESS, CURSOR, id), \
SRI(CURSOR_SIZE, CURSOR, id), \
SRI(CURSOR_CONTROL, CURSOR, id), \
SRI(CURSOR_POSITION, CURSOR, id), \
SRI(CURSOR_HOT_SPOT, CURSOR, id), \
SRI(CURSOR_DST_OFFSET, CURSOR, id)
struct dcn_mi_registers {
uint32_t DCHUBP_CNTL;
@ -215,6 +224,15 @@ struct dcn_mi_registers {
uint32_t DCN_VM_AGP_BASE;
uint32_t DCN_VM_AGP_BOT;
uint32_t DCN_VM_AGP_TOP;
uint32_t CURSOR_SETTINS;
uint32_t CURSOR_SETTINGS;
uint32_t CURSOR_SURFACE_ADDRESS_HIGH;
uint32_t CURSOR_SURFACE_ADDRESS;
uint32_t CURSOR_SIZE;
uint32_t CURSOR_CONTROL;
uint32_t CURSOR_POSITION;
uint32_t CURSOR_HOT_SPOT;
uint32_t CURSOR_DST_OFFSET;
};
#define MI_SF(reg_name, field_name, post_fix)\
@ -351,6 +369,7 @@ struct dcn_mi_registers {
MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, mask_sh),\
MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, mask_sh),\
MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, mask_sh),\
MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, mask_sh),\
MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, mask_sh),\
MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, MC_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, mask_sh),\
MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, MC_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, mask_sh),\
@ -360,7 +379,23 @@ struct dcn_mi_registers {
MI_SF(DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, mask_sh),\
MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, mask_sh),\
MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mask_sh),\
MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mask_sh)
MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mask_sh),\
MI_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_DST_Y_OFFSET, mask_sh), \
MI_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_CHUNK_HDL_ADJUST, mask_sh), \
MI_SF(CURSOR0_CURSOR_SURFACE_ADDRESS_HIGH, CURSOR_SURFACE_ADDRESS_HIGH, mask_sh), \
MI_SF(CURSOR0_CURSOR_SURFACE_ADDRESS, CURSOR_SURFACE_ADDRESS, mask_sh), \
MI_SF(CURSOR0_CURSOR_SIZE, CURSOR_WIDTH, mask_sh), \
MI_SF(CURSOR0_CURSOR_SIZE, CURSOR_HEIGHT, mask_sh), \
MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \
MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_2X_MAGNIFY, mask_sh), \
MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \
MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \
MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \
MI_SF(CURSOR0_CURSOR_POSITION, CURSOR_X_POSITION, mask_sh), \
MI_SF(CURSOR0_CURSOR_POSITION, CURSOR_Y_POSITION, mask_sh), \
MI_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_X, mask_sh), \
MI_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_Y, mask_sh), \
MI_SF(CURSOR0_CURSOR_DST_OFFSET, CURSOR_DST_X_OFFSET, mask_sh)
#define DCN_MI_REG_FIELD_LIST(type) \
type HUBP_BLANK_EN;\
@ -488,6 +523,7 @@ struct dcn_mi_registers {
type VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB;\
type VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB;\
type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB;\
type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM;\
type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB;\
type ENABLE_L1_TLB;\
type SYSTEM_ACCESS_MODE;\
@ -521,7 +557,24 @@ struct dcn_mi_registers {
type PHYSICAL_PAGE_ADDR_LO32;\
type PHYSICAL_PAGE_NUMBER_MSB;\
type PHYSICAL_PAGE_NUMBER_LSB;\
type LOGICAL_ADDR
type LOGICAL_ADDR;\
type CURSOR0_DST_Y_OFFSET; \
type CURSOR0_CHUNK_HDL_ADJUST; \
type CURSOR_SURFACE_ADDRESS_HIGH; \
type CURSOR_SURFACE_ADDRESS; \
type CURSOR_WIDTH; \
type CURSOR_HEIGHT; \
type CURSOR_MODE; \
type CURSOR_2X_MAGNIFY; \
type CURSOR_PITCH; \
type CURSOR_LINES_PER_CHUNK; \
type CURSOR_ENABLE; \
type CURSOR_X_POSITION; \
type CURSOR_Y_POSITION; \
type CURSOR_HOT_SPOT_X; \
type CURSOR_HOT_SPOT_Y; \
type CURSOR_DST_X_OFFSET; \
type OUTPUT_FP
struct dcn_mi_shift {
DCN_MI_REG_FIELD_LIST(uint8_t);
@ -531,21 +584,83 @@ struct dcn_mi_mask {
DCN_MI_REG_FIELD_LIST(uint32_t);
};
struct dcn10_mem_input {
struct mem_input base;
struct dcn10_hubp {
struct hubp base;
const struct dcn_mi_registers *mi_regs;
const struct dcn_mi_shift *mi_shift;
const struct dcn_mi_mask *mi_mask;
};
void dcn10_mem_input_construct(
struct dcn10_mem_input *mi,
void hubp1_program_surface_config(
struct hubp *hubp,
enum surface_pixel_format format,
union dc_tiling_info *tiling_info,
union plane_size *plane_size,
enum dc_rotation_angle rotation,
struct dc_plane_dcc_param *dcc,
bool horizontal_mirror);
void hubp1_program_deadline(
struct hubp *hubp,
struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
struct _vcs_dpi_display_ttu_regs_st *ttu_attr);
void hubp1_program_requestor(
struct hubp *hubp,
struct _vcs_dpi_display_rq_regs_st *rq_regs);
void hubp1_program_pixel_format(
struct dcn10_hubp *hubp,
enum surface_pixel_format format);
void hubp1_program_size_and_rotation(
struct dcn10_hubp *hubp,
enum dc_rotation_angle rotation,
enum surface_pixel_format format,
const union plane_size *plane_size,
struct dc_plane_dcc_param *dcc,
bool horizontal_mirror);
void hubp1_program_tiling(
struct dcn10_hubp *hubp,
const union dc_tiling_info *info,
const enum surface_pixel_format pixel_format);
void hubp1_dcc_control(struct hubp *hubp,
bool enable,
bool independent_64b_blks);
bool hubp1_program_surface_flip_and_addr(
struct hubp *hubp,
const struct dc_plane_address *address,
bool flip_immediate);
bool hubp1_is_flip_pending(struct hubp *hubp);
void hubp1_cursor_set_attributes(
struct hubp *hubp,
const struct dc_cursor_attributes *attr);
void hubp1_cursor_set_position(
struct hubp *hubp,
const struct dc_cursor_position *pos,
const struct dc_cursor_mi_param *param);
void hubp1_set_blank(struct hubp *hubp, bool blank);
void min_set_viewport(struct hubp *hubp,
const struct rect *viewport,
const struct rect *viewport_c);
void dcn10_hubp_construct(
struct dcn10_hubp *hubp1,
struct dc_context *ctx,
uint32_t inst,
const struct dcn_mi_registers *mi_regs,
const struct dcn_mi_shift *mi_shift,
const struct dcn_mi_mask *mi_mask);
struct dcn_hubp_state {
uint32_t pixel_format;
uint32_t inuse_addr_hi;
@ -562,7 +677,7 @@ struct dcn_hubp_state {
uint32_t qos_level_low_wm;
uint32_t qos_level_high_wm;
};
void dcn10_mem_input_read_state(struct dcn10_mem_input *mi,
void hubp1_read_state(struct dcn10_hubp *hubp1,
struct dcn_hubp_state *s);
#endif

View File

@ -31,7 +31,6 @@
#include "dce110/dce110_hw_sequencer.h"
#include "dce/dce_hwseq.h"
#include "abm.h"
#include "dcn10/dcn10_mem_input.h"
#include "dcn10/dcn10_timing_generator.h"
#include "dcn10/dcn10_dpp.h"
#include "dcn10/dcn10_mpc.h"
@ -41,6 +40,7 @@
#include "mpc.h"
#include "reg_helper.h"
#include "custom_float.h"
#include "dcn10_hubp.h"
#define CTX \
hws->ctx
@ -172,10 +172,10 @@ static void dcn10_log_hw_state(struct dc *dc)
"min_ttu_vblank \t qos_low_wm \t qos_high_wm \n");
for (i = 0; i < pool->pipe_count; i++) {
struct mem_input *mi = pool->mis[i];
struct hubp *hubp = pool->hubps[i];
struct dcn_hubp_state s;
dcn10_mem_input_read_state(TO_DCN10_MEM_INPUT(mi), &s);
hubp1_read_state(TO_DCN10_HUBP(hubp), &s);
DTN_INFO("[%d]:\t %xh \t %xh \t %d \t %d \t "
"%xh \t %xh \t %xh \t "
@ -245,15 +245,19 @@ static void verify_allow_pstate_change_high(
{
/* pstate latency is ~20us so if we wait over 40us and pstate allow
* still not asserted, we are probably stuck and going to hang
*
* TODO: Figure out why it takes ~100us on linux
* pstate takes around ~100us on linux. Unknown currently as to
* why it takes that long on linux
*/
static unsigned int pstate_wait_timeout_us = 40;
static unsigned int pstate_wait_timeout_us = 200;
static unsigned int pstate_wait_expected_timeout_us = 40;
static unsigned int max_sampled_pstate_wait_us; /* data collection */
static bool forced_pstate_allow; /* help with revert wa */
static bool should_log_hw_state; /* prevent hw state log by default */
unsigned int debug_index = 0x7;
unsigned int debug_data;
unsigned int force_allow_pstate = 0x30;
unsigned int i;
if (forced_pstate_allow) {
@ -261,7 +265,9 @@ static void verify_allow_pstate_change_high(
* we verify_allow_pstate_change_high. so disable force
* here so we can check status
*/
REG_WRITE(DCHUBBUB_ARB_DRAM_STATE_CNTL, 0);
REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0,
DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 0);
forced_pstate_allow = false;
}
@ -292,9 +298,15 @@ static void verify_allow_pstate_change_high(
for (i = 0; i < pstate_wait_timeout_us; i++) {
debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA);
if (debug_data & (1 << 30))
return;
if (debug_data & (1 << 30)) {
if (i > pstate_wait_expected_timeout_us)
dm_logger_write(hws->ctx->logger, LOG_WARNING,
"pstate took longer than expected ~%dus\n",
i);
return;
}
if (max_sampled_pstate_wait_us < i)
max_sampled_pstate_wait_us = i;
@ -304,13 +316,18 @@ static void verify_allow_pstate_change_high(
/* force pstate allow to prevent system hang
* and break to debugger to investigate
*/
REG_WRITE(DCHUBBUB_ARB_DRAM_STATE_CNTL, force_allow_pstate);
REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 1,
DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1);
forced_pstate_allow = true;
if (should_log_hw_state) {
dcn10_log_hw_state(hws->ctx->dc);
}
dm_logger_write(hws->ctx->logger, LOG_WARNING,
"pstate TEST_DEBUG_DATA: 0x%X\n",
debug_data);
BREAK_TO_DEBUGGER();
}
@ -451,7 +468,7 @@ static void program_watermarks(
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"URGENCY_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->a.urgent_ns, prog_wm_value);
@ -459,38 +476,37 @@ static void program_watermarks(
prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"PTE_META_URGENCY_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->a.pte_meta_urgent_ns, prog_wm_value);
prog_wm_value = convert_and_clamp(
watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
"SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) {
prog_wm_value = convert_and_clamp(
watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
prog_wm_value = convert_and_clamp(
watermarks->a.cstate_pstate.cstate_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
"SR_EXIT_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
prog_wm_value = convert_and_clamp(
watermarks->a.cstate_pstate.cstate_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"SR_EXIT_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
}
prog_wm_value = convert_and_clamp(
watermarks->a.cstate_pstate.pstate_change_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n\n",
watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
@ -500,7 +516,7 @@ static void program_watermarks(
prog_wm_value = convert_and_clamp(
watermarks->b.urgent_ns, refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"URGENCY_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->b.urgent_ns, prog_wm_value);
@ -510,36 +526,38 @@ static void program_watermarks(
watermarks->b.pte_meta_urgent_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"PTE_META_URGENCY_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->b.pte_meta_urgent_ns, prog_wm_value);
prog_wm_value = convert_and_clamp(
watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
"SR_ENTER_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) {
prog_wm_value = convert_and_clamp(
watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"SR_ENTER_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
prog_wm_value = convert_and_clamp(
watermarks->b.cstate_pstate.cstate_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
"SR_EXIT_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
prog_wm_value = convert_and_clamp(
watermarks->b.cstate_pstate.cstate_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"SR_EXIT_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
}
prog_wm_value = convert_and_clamp(
watermarks->b.cstate_pstate.pstate_change_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n"
"HW register value = 0x%x\n",
watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
@ -548,7 +566,7 @@ static void program_watermarks(
prog_wm_value = convert_and_clamp(
watermarks->c.urgent_ns, refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"URGENCY_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->c.urgent_ns, prog_wm_value);
@ -558,37 +576,38 @@ static void program_watermarks(
watermarks->c.pte_meta_urgent_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"PTE_META_URGENCY_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->c.pte_meta_urgent_ns, prog_wm_value);
prog_wm_value = convert_and_clamp(
watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
"SR_ENTER_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) {
prog_wm_value = convert_and_clamp(
watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"SR_ENTER_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
prog_wm_value = convert_and_clamp(
watermarks->c.cstate_pstate.cstate_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
"SR_EXIT_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
prog_wm_value = convert_and_clamp(
watermarks->c.cstate_pstate.cstate_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"SR_EXIT_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
}
prog_wm_value = convert_and_clamp(
watermarks->c.cstate_pstate.pstate_change_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n"
"HW register value = 0x%x\n",
watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
@ -597,7 +616,7 @@ static void program_watermarks(
prog_wm_value = convert_and_clamp(
watermarks->d.urgent_ns, refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"URGENCY_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->d.urgent_ns, prog_wm_value);
@ -606,37 +625,39 @@ static void program_watermarks(
watermarks->d.pte_meta_urgent_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"PTE_META_URGENCY_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->d.pte_meta_urgent_ns, prog_wm_value);
prog_wm_value = convert_and_clamp(
watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
"SR_ENTER_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) {
prog_wm_value = convert_and_clamp(
watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"SR_ENTER_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
prog_wm_value = convert_and_clamp(
watermarks->d.cstate_pstate.cstate_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
"SR_EXIT_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
prog_wm_value = convert_and_clamp(
watermarks->d.cstate_pstate.cstate_exit_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"SR_EXIT_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
}
prog_wm_value = convert_and_clamp(
watermarks->d.cstate_pstate.pstate_change_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n\n",
watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
@ -771,20 +792,22 @@ static void power_on_plane(
struct dce_hwseq *hws,
int plane_id)
{
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
dpp_pg_control(hws, plane_id, true);
hubp_pg_control(hws, plane_id, true);
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
dm_logger_write(hws->ctx->logger, LOG_DEBUG,
"Un-gated front end for pipe %d\n", plane_id);
if (REG(DC_IP_REQUEST_CNTL)) {
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
dpp_pg_control(hws, plane_id, true);
hubp_pg_control(hws, plane_id, true);
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
dm_logger_write(hws->ctx->logger, LOG_DEBUG,
"Un-gated front end for pipe %d\n", plane_id);
}
}
static void undo_DEGVIDCN10_253_wa(struct dc *dc)
{
struct dce_hwseq *hws = dc->hwseq;
struct mem_input *mi = dc->res_pool->mis[0];
struct hubp *hubp = dc->res_pool->hubps[0];
int pwr_status = 0;
REG_GET(DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, &pwr_status);
@ -792,7 +815,7 @@ static void undo_DEGVIDCN10_253_wa(struct dc *dc)
if (pwr_status == 2)
return;
mi->funcs->set_blank(mi, true);
hubp->funcs->set_blank(hubp, true);
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
@ -802,17 +825,13 @@ static void undo_DEGVIDCN10_253_wa(struct dc *dc)
IP_REQUEST_EN, 0);
}
static void ready_shared_resources(struct dc *dc)
{
if (dc->current_state->stream_count == 0 &&
!dc->debug.disable_stutter)
undo_DEGVIDCN10_253_wa(dc);
}
static void apply_DEGVIDCN10_253_wa(struct dc *dc)
{
struct dce_hwseq *hws = dc->hwseq;
struct mem_input *mi = dc->res_pool->mis[0];
struct hubp *hubp = dc->res_pool->hubps[0];
if (dc->debug.disable_stutter)
return;
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
@ -821,14 +840,7 @@ static void apply_DEGVIDCN10_253_wa(struct dc *dc)
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
mi->funcs->set_hubp_blank_en(mi, false);
}
static void optimize_shared_resources(struct dc *dc)
{
if (dc->current_state->stream_count == 0 &&
!dc->debug.disable_stutter)
apply_DEGVIDCN10_253_wa(dc);
hubp->funcs->set_hubp_blank_en(hubp, false);
}
static void bios_golden_init(struct dc *dc)
@ -887,12 +899,13 @@ static void dcn10_init_hw(struct dc *dc)
}
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct transform *xfm = dc->res_pool->transforms[i];
struct dpp *dpp = dc->res_pool->dpps[i];
struct timing_generator *tg = dc->res_pool->timing_generators[i];
xfm->funcs->transform_reset(xfm);
dpp->funcs->dpp_reset(dpp);
dc->res_pool->mpc->funcs->remove(
dc->res_pool->mpc, dc->res_pool->opps[i], i);
dc->res_pool->mpc, &(dc->res_pool->opps[i]->mpc_tree),
dc->res_pool->opps[i]->inst, i);
/* Blank controller using driver code instead of
* command table.
@ -1028,12 +1041,11 @@ static void reset_back_end_for_pipe(
return;
}
/* TODOFPGA break core_link_disable_stream into 2 functions:
* disable_stream and disable_link. disable_link will disable PHYPLL
* which is used by otg. Move disable_link after disable_crtc
*/
if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
core_link_disable_stream(pipe_ctx);
if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
/* DPMS may already disable */
if (!pipe_ctx->stream->dpms_off)
core_link_disable_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE);
}
/* by upper caller loop, parent pipe: pipe0, will be reset last.
* back end share by all pipes and will be disable only when disable
@ -1062,7 +1074,7 @@ static void reset_back_end_for_pipe(
static void plane_atomic_disconnect(struct dc *dc,
int fe_idx)
{
struct mem_input *mi = dc->res_pool->mis[fe_idx];
struct hubp *hubp = dc->res_pool->hubps[fe_idx];
struct mpc *mpc = dc->res_pool->mpc;
int opp_id, z_idx;
int mpcc_id = -1;
@ -1086,11 +1098,12 @@ static void plane_atomic_disconnect(struct dc *dc,
if (dc->debug.sanity_checks)
verify_allow_pstate_change_high(dc->hwseq);
mi->funcs->dcc_control(mi, false, false);
hubp->funcs->dcc_control(hubp, false, false);
if (dc->debug.sanity_checks)
verify_allow_pstate_change_high(dc->hwseq);
mpc->funcs->remove(mpc, dc->res_pool->opps[opp_id], fe_idx);
mpc->funcs->remove(mpc, &(dc->res_pool->opps[opp_id]->mpc_tree),
dc->res_pool->opps[opp_id]->inst, fe_idx);
}
/* disable HW used by plane.
@ -1099,20 +1112,20 @@ static void plane_atomic_disable(struct dc *dc,
int fe_idx)
{
struct dce_hwseq *hws = dc->hwseq;
struct mem_input *mi = dc->res_pool->mis[fe_idx];
struct hubp *hubp = dc->res_pool->hubps[fe_idx];
struct mpc *mpc = dc->res_pool->mpc;
int opp_id = mi->opp_id;
int opp_id = hubp->opp_id;
if (opp_id == 0xf)
return;
mpc->funcs->wait_for_idle(mpc, mi->mpcc_id);
dc->res_pool->opps[mi->opp_id]->mpcc_disconnect_pending[mi->mpcc_id] = false;
mpc->funcs->wait_for_idle(mpc, hubp->mpcc_id);
dc->res_pool->opps[hubp->opp_id]->mpcc_disconnect_pending[hubp->mpcc_id] = false;
/*dm_logger_write(dc->ctx->logger, LOG_ERROR,
"[debug_mpo: atomic disable finished on mpcc %d]\n",
fe_idx);*/
mi->funcs->set_blank(mi, true);
hubp->funcs->set_blank(hubp, true);
if (dc->debug.sanity_checks)
verify_allow_pstate_change_high(dc->hwseq);
@ -1137,20 +1150,22 @@ static void plane_atomic_disable(struct dc *dc,
static void plane_atomic_power_down(struct dc *dc, int fe_idx)
{
struct dce_hwseq *hws = dc->hwseq;
struct transform *xfm = dc->res_pool->transforms[fe_idx];
struct dpp *dpp = dc->res_pool->dpps[fe_idx];
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
dpp_pg_control(hws, fe_idx, false);
hubp_pg_control(hws, fe_idx, false);
xfm->funcs->transform_reset(xfm);
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
dm_logger_write(dc->ctx->logger, LOG_DEBUG,
"Power gated front end %d\n", fe_idx);
if (REG(DC_IP_REQUEST_CNTL)) {
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
dpp_pg_control(hws, fe_idx, false);
hubp_pg_control(hws, fe_idx, false);
dpp->funcs->dpp_reset(dpp);
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
dm_logger_write(dc->ctx->logger, LOG_DEBUG,
"Power gated front end %d\n", fe_idx);
if (dc->debug.sanity_checks)
verify_allow_pstate_change_high(dc->hwseq);
if (dc->debug.sanity_checks)
verify_allow_pstate_change_high(dc->hwseq);
}
}
@ -1160,7 +1175,7 @@ static void reset_front_end(
{
struct dce_hwseq *hws = dc->hwseq;
struct timing_generator *tg;
int opp_id = dc->res_pool->mis[fe_idx]->opp_id;
int opp_id = dc->res_pool->hubps[fe_idx]->opp_id;
/*Already reset*/
if (opp_id == 0xf)
@ -1192,7 +1207,7 @@ static void reset_front_end(
static void dcn10_power_down_fe(struct dc *dc, int fe_idx)
{
struct dce_hwseq *hws = dc->hwseq;
struct transform *xfm = dc->res_pool->transforms[fe_idx];
struct dpp *dpp = dc->res_pool->dpps[fe_idx];
reset_front_end(dc, fe_idx);
@ -1200,7 +1215,7 @@ static void dcn10_power_down_fe(struct dc *dc, int fe_idx)
IP_REQUEST_EN, 1);
dpp_pg_control(hws, fe_idx, false);
hubp_pg_control(hws, fe_idx, false);
xfm->funcs->transform_reset(xfm);
dpp->funcs->dpp_reset(dpp);
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
dm_logger_write(dc->ctx->logger, LOG_DEBUG,
@ -1275,6 +1290,9 @@ static void reset_hw_ctx_wrap(
if (!pipe_ctx_old->stream)
continue;
if (pipe_ctx_old->top_pipe)
continue;
if (!pipe_ctx->stream ||
pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
struct clock_source *old_clk = pipe_ctx_old->clock_source;
@ -1339,8 +1357,8 @@ static void dcn10_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_c
if (plane_state == NULL)
return;
addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr);
pipe_ctx->plane_res.mi->funcs->mem_input_program_surface_flip_and_addr(
pipe_ctx->plane_res.mi,
pipe_ctx->plane_res.hubp->funcs->hubp_program_surface_flip_and_addr(
pipe_ctx->plane_res.hubp,
&plane_state->address,
plane_state->flip_immediate);
plane_state->status.requested_address = plane_state->address;
@ -1351,34 +1369,34 @@ static void dcn10_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_c
static bool dcn10_set_input_transfer_func(
struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state)
{
struct transform *xfm_base = pipe_ctx->plane_res.xfm;
struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
const struct dc_transfer_func *tf = NULL;
bool result = true;
if (xfm_base == NULL)
if (dpp_base == NULL)
return false;
if (plane_state->in_transfer_func)
tf = plane_state->in_transfer_func;
if (plane_state->gamma_correction && dce_use_lut(plane_state))
xfm_base->funcs->ipp_program_input_lut(xfm_base,
dpp_base->funcs->ipp_program_input_lut(dpp_base,
plane_state->gamma_correction);
if (tf == NULL)
xfm_base->funcs->ipp_set_degamma(xfm_base, IPP_DEGAMMA_MODE_BYPASS);
dpp_base->funcs->ipp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS);
else if (tf->type == TF_TYPE_PREDEFINED) {
switch (tf->tf) {
case TRANSFER_FUNCTION_SRGB:
xfm_base->funcs->ipp_set_degamma(xfm_base,
dpp_base->funcs->ipp_set_degamma(dpp_base,
IPP_DEGAMMA_MODE_HW_sRGB);
break;
case TRANSFER_FUNCTION_BT709:
xfm_base->funcs->ipp_set_degamma(xfm_base,
dpp_base->funcs->ipp_set_degamma(dpp_base,
IPP_DEGAMMA_MODE_HW_xvYCC);
break;
case TRANSFER_FUNCTION_LINEAR:
xfm_base->funcs->ipp_set_degamma(xfm_base,
dpp_base->funcs->ipp_set_degamma(dpp_base,
IPP_DEGAMMA_MODE_BYPASS);
break;
case TRANSFER_FUNCTION_PQ:
@ -1389,7 +1407,7 @@ static bool dcn10_set_input_transfer_func(
break;
}
} else if (tf->type == TF_TYPE_BYPASS) {
xfm_base->funcs->ipp_set_degamma(xfm_base, IPP_DEGAMMA_MODE_BYPASS);
dpp_base->funcs->ipp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS);
} else {
/*TF_TYPE_DISTRIBUTED_POINTS*/
result = false;
@ -1716,25 +1734,25 @@ static bool dcn10_set_output_transfer_func(
struct pipe_ctx *pipe_ctx,
const struct dc_stream_state *stream)
{
struct transform *xfm = pipe_ctx->plane_res.xfm;
struct dpp *dpp = pipe_ctx->plane_res.dpp;
if (xfm == NULL)
if (dpp == NULL)
return false;
xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
dpp->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
if (stream->out_transfer_func &&
stream->out_transfer_func->type ==
TF_TYPE_PREDEFINED &&
stream->out_transfer_func->tf ==
TRANSFER_FUNCTION_SRGB) {
xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB);
dpp->funcs->opp_set_regamma_mode(dpp, OPP_REGAMMA_SRGB);
} else if (dcn10_translate_regamma_to_hw_format(
stream->out_transfer_func, &xfm->regamma_params)) {
xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params);
xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER);
stream->out_transfer_func, &dpp->regamma_params)) {
dpp->funcs->opp_program_regamma_pwl(dpp, &dpp->regamma_params);
dpp->funcs->opp_set_regamma_mode(dpp, OPP_REGAMMA_USER);
} else {
xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS);
dpp->funcs->opp_set_regamma_mode(dpp, OPP_REGAMMA_BYPASS);
}
return true;
@ -1745,8 +1763,8 @@ static void dcn10_pipe_control_lock(
struct pipe_ctx *pipe,
bool lock)
{
struct mem_input *mi = NULL;
mi = dc->res_pool->mis[pipe->pipe_idx];
struct hubp *hubp = NULL;
hubp = dc->res_pool->hubps[pipe->pipe_idx];
/* use TG master update lock to lock everything on the TG
* therefore only top pipe need to lock
*/
@ -1997,10 +2015,11 @@ static void dcn10_power_on_fe(
plane_state->dst_rect.height);
dm_logger_write(dc->ctx->logger, LOG_DC,
"Pipe %d: width, height, x, y\n"
"Pipe %d: width, height, x, y format:%d\n"
"viewport:%d, %d, %d, %d\n"
"recout: %d, %d, %d, %d\n",
pipe_ctx->pipe_idx,
plane_state->format,
pipe_ctx->plane_res.scl_data.viewport.width,
pipe_ctx->plane_res.scl_data.viewport.height,
pipe_ctx->plane_res.scl_data.viewport.x,
@ -2019,7 +2038,7 @@ static void dcn10_power_on_fe(
static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
{
struct xfm_grph_csc_adjustment adjust;
struct dpp_grph_csc_adjustment adjust;
memset(&adjust, 0, sizeof(adjust));
adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
@ -2055,7 +2074,7 @@ static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
gamut_remap_matrix.matrix[10];
}
pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp, &adjust);
}
@ -2077,7 +2096,7 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
tbl_entry.color_space = color_space;
//tbl_entry.regval = matrix;
pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.xfm, &tbl_entry);
pipe_ctx->plane_res.dpp->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.dpp, &tbl_entry);
}
}
static bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx)
@ -2167,7 +2186,7 @@ static void dcn10_get_surface_visual_confirm_color(
}
}
static void mmhub_read_vm_system_aperture_settings(struct dcn10_mem_input *mi,
static void mmhub_read_vm_system_aperture_settings(struct dcn10_hubp *hubp1,
struct vm_system_aperture_param *apt,
struct dce_hwseq *hws)
{
@ -2192,7 +2211,7 @@ static void mmhub_read_vm_system_aperture_settings(struct dcn10_mem_input *mi,
}
/* Temporary read settings, future will get values from kmd directly */
static void mmhub_read_vm_context0_settings(struct dcn10_mem_input *mi,
static void mmhub_read_vm_context0_settings(struct dcn10_hubp *hubp1,
struct vm_context0_param *vm0,
struct dce_hwseq *hws)
{
@ -2236,22 +2255,22 @@ static void mmhub_read_vm_context0_settings(struct dcn10_mem_input *mi,
vm0->pte_base.quad_part -= fb_offset.quad_part;
}
static void dcn10_program_pte_vm(struct mem_input *mem_input,
static void dcn10_program_pte_vm(struct hubp *hubp,
enum surface_pixel_format format,
union dc_tiling_info *tiling_info,
enum dc_rotation_angle rotation,
struct dce_hwseq *hws)
{
struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
struct vm_system_aperture_param apt = { {{ 0 } } };
struct vm_context0_param vm0 = { { { 0 } } };
mmhub_read_vm_system_aperture_settings(mi, &apt, hws);
mmhub_read_vm_context0_settings(mi, &vm0, hws);
mmhub_read_vm_system_aperture_settings(hubp1, &apt, hws);
mmhub_read_vm_context0_settings(hubp1, &vm0, hws);
mem_input->funcs->mem_input_set_vm_system_aperture_settings(mem_input, &apt);
mem_input->funcs->mem_input_set_vm_context0_settings(mem_input, &vm0);
hubp->funcs->hubp_set_vm_system_aperture_settings(hubp, &apt);
hubp->funcs->hubp_set_vm_context0_settings(hubp, &vm0);
}
static void update_dchubp_dpp(
@ -2260,11 +2279,10 @@ static void update_dchubp_dpp(
struct dc_state *context)
{
struct dce_hwseq *hws = dc->hwseq;
struct mem_input *mi = pipe_ctx->plane_res.mi;
struct transform *xfm = pipe_ctx->plane_res.xfm;
struct hubp *hubp = pipe_ctx->plane_res.hubp;
struct dpp *dpp = pipe_ctx->plane_res.dpp;
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
union plane_size size = plane_state->plane_size;
struct default_adjustment ocsc = {0};
struct mpcc_cfg mpcc_cfg = {0};
struct pipe_ctx *top_pipe;
bool per_pixel_alpha = plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
@ -2286,10 +2304,8 @@ static void update_dchubp_dpp(
*/
REG_UPDATE(DCHUBP_CNTL[pipe_ctx->pipe_idx], HUBP_VTG_SEL, pipe_ctx->stream_res.tg->inst);
dc->hwss.update_plane_addr(dc, pipe_ctx);
mi->funcs->mem_input_setup(
mi,
hubp->funcs->hubp_setup(
hubp,
&pipe_ctx->dlg_regs,
&pipe_ctx->ttu_regs,
&pipe_ctx->rq_regs,
@ -2299,19 +2315,20 @@ static void update_dchubp_dpp(
if (dc->config.gpu_vm_support)
dcn10_program_pte_vm(
pipe_ctx->plane_res.mi,
pipe_ctx->plane_res.hubp,
plane_state->format,
&plane_state->tiling_info,
plane_state->rotation,
hws
);
xfm->funcs->ipp_setup(xfm,
dpp->funcs->ipp_setup(dpp,
plane_state->format,
EXPANSION_MODE_ZERO);
mpcc_cfg.mi = mi;
mpcc_cfg.opp = pipe_ctx->stream_res.opp;
mpcc_cfg.dpp_id = hubp->inst;
mpcc_cfg.opp_id = pipe_ctx->stream_res.opp->inst;
mpcc_cfg.tree_cfg = &(pipe_ctx->stream_res.opp->mpc_tree);
for (top_pipe = pipe_ctx->top_pipe; top_pipe; top_pipe = top_pipe->top_pipe)
mpcc_cfg.z_index++;
if (dc->debug.surface_visual_confirm)
@ -2328,25 +2345,27 @@ static void update_dchubp_dpp(
mpcc_cfg.pre_multiplied_alpha = is_rgb_cspace(
pipe_ctx->stream->output_color_space)
&& per_pixel_alpha;
dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg);
hubp->mpcc_id = dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg);
hubp->opp_id = mpcc_cfg.opp_id;
pipe_ctx->plane_res.scl_data.lb_params.alpha_en = per_pixel_alpha;
pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
/* scaler configuration */
pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(
pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data);
mi->funcs->mem_program_viewport(mi,
pipe_ctx->plane_res.dpp->funcs->dpp_set_scaler(
pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data);
hubp->funcs->mem_program_viewport(hubp,
&pipe_ctx->plane_res.scl_data.viewport, &pipe_ctx->plane_res.scl_data.viewport_c);
/*gamut remap*/
program_gamut_remap(pipe_ctx);
/*TODO add adjustments parameters*/
ocsc.out_color_space = pipe_ctx->stream->output_color_space;
pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default(pipe_ctx->plane_res.xfm, &ocsc);
program_csc_matrix(pipe_ctx,
pipe_ctx->stream->output_color_space,
pipe_ctx->stream->csc_color_matrix.matrix);
mi->funcs->mem_input_program_surface_config(
mi,
hubp->funcs->hubp_program_surface_config(
hubp,
plane_state->format,
&plane_state->tiling_info,
&size,
@ -2354,8 +2373,10 @@ static void update_dchubp_dpp(
&plane_state->dcc,
plane_state->horizontal_mirror);
dc->hwss.update_plane_addr(dc, pipe_ctx);
if (is_pipe_tree_visible(pipe_ctx))
mi->funcs->set_blank(mi, false);
hubp->funcs->set_blank(hubp, false);
}
@ -2393,6 +2414,10 @@ static void program_all_pipe_in_tree(
}
if (pipe_ctx->plane_state != NULL) {
struct dc_cursor_position position = { 0 };
struct pipe_ctx *cur_pipe_ctx =
&dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
dcn10_power_on_fe(dc, pipe_ctx, context);
/* temporary dcn1 wa:
@ -2407,6 +2432,19 @@ static void program_all_pipe_in_tree(
toggle_watermark_change_req(dc->hwseq);
update_dchubp_dpp(dc, pipe_ctx, context);
/* TODO: this is a hack w/a for switching from mpo to pipe split */
dc_stream_set_cursor_position(pipe_ctx->stream, &position);
dc_stream_set_cursor_attributes(pipe_ctx->stream,
&pipe_ctx->stream->cursor_attributes);
if (cur_pipe_ctx->plane_state != pipe_ctx->plane_state) {
dc->hwss.set_input_transfer_func(
pipe_ctx, pipe_ctx->plane_state);
dc->hwss.set_output_transfer_func(
pipe_ctx, pipe_ctx->stream);
}
}
if (dc->debug.sanity_checks) {
@ -2445,6 +2483,30 @@ static void dcn10_pplib_apply_display_requirements(
dc->prev_display_config = *pp_display_cfg;
}
static void optimize_shared_resources(struct dc *dc)
{
if (dc->current_state->stream_count == 0) {
apply_DEGVIDCN10_253_wa(dc);
/* S0i2 message */
dcn10_pplib_apply_display_requirements(dc, dc->current_state);
}
if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE)
dcn_bw_notify_pplib_of_wm_ranges(dc);
}
static void ready_shared_resources(struct dc *dc, struct dc_state *context)
{
if (dc->current_state->stream_count == 0 &&
!dc->debug.disable_stutter)
undo_DEGVIDCN10_253_wa(dc);
/* S0i2 message */
if (dc->current_state->stream_count == 0 &&
context->stream_count != 0)
dcn10_pplib_apply_display_requirements(dc, context);
}
static void dcn10_apply_ctx_for_surface(
struct dc *dc,
const struct dc_stream_state *stream,
@ -2494,7 +2556,7 @@ static void dcn10_apply_ctx_for_surface(
*/
if (pipe_ctx->plane_state && !old_pipe_ctx->plane_state) {
if (pipe_ctx->plane_res.mi->opp_id != 0xf && pipe_ctx->stream_res.tg->inst == be_idx) {
if (pipe_ctx->plane_res.hubp->opp_id != 0xf && pipe_ctx->stream_res.tg->inst == be_idx) {
dcn10_power_down_fe(dc, pipe_ctx->pipe_idx);
/*
* power down fe will unlock when calling reset, need
@ -2518,9 +2580,10 @@ static void dcn10_apply_ctx_for_surface(
/* reset mpc */
dc->res_pool->mpc->funcs->remove(
dc->res_pool->mpc,
old_pipe_ctx->stream_res.opp,
&(old_pipe_ctx->stream_res.opp->mpc_tree),
old_pipe_ctx->stream_res.opp->inst,
old_pipe_ctx->pipe_idx);
old_pipe_ctx->stream_res.opp->mpcc_disconnect_pending[old_pipe_ctx->plane_res.mi->mpcc_id] = true;
old_pipe_ctx->stream_res.opp->mpcc_disconnect_pending[old_pipe_ctx->plane_res.hubp->mpcc_id] = true;
/*dm_logger_write(dc->ctx->logger, LOG_ERROR,
"[debug_mpo: apply_ctx disconnect pending on mpcc %d]\n",
@ -2532,6 +2595,7 @@ static void dcn10_apply_ctx_for_surface(
old_pipe_ctx->top_pipe = NULL;
old_pipe_ctx->bottom_pipe = NULL;
old_pipe_ctx->plane_state = NULL;
old_pipe_ctx->stream = NULL;
dm_logger_write(dc->ctx->logger, LOG_DC,
"Reset mpcc for pipe %d\n",
@ -2803,7 +2867,7 @@ static void dcn10_wait_for_mpcc_disconnect(
if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i]) {
res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, i);
pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i] = false;
res_pool->mis[i]->funcs->set_blank(res_pool->mis[i], true);
res_pool->hubps[i]->funcs->set_blank(res_pool->hubps[i], true);
/*dm_logger_write(dc->ctx->logger, LOG_ERROR,
"[debug_mpo: wait_for_mpcc finished waiting on mpcc %d]\n",
i);*/
@ -2834,11 +2898,11 @@ void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
return;
plane_state->status.is_flip_pending =
pipe_ctx->plane_res.mi->funcs->mem_input_is_flip_pending(
pipe_ctx->plane_res.mi);
pipe_ctx->plane_res.hubp->funcs->hubp_is_flip_pending(
pipe_ctx->plane_res.hubp);
plane_state->status.current_address = pipe_ctx->plane_res.mi->current_address;
if (pipe_ctx->plane_res.mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
plane_state->status.current_address = pipe_ctx->plane_res.hubp->current_address;
if (pipe_ctx->plane_res.hubp->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
tg->funcs->is_stereo_left_eye) {
plane_state->status.is_right_eye =
!tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg);
@ -2882,6 +2946,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect,
.ready_shared_resources = ready_shared_resources,
.optimize_shared_resources = optimize_shared_resources,
.edp_backlight_control = hwss_edp_backlight_control,
.edp_power_control = hwss_edp_power_control
};

View File

@ -37,188 +37,6 @@
#define CTX \
ippn10->base.ctx
static bool ippn10_cursor_program_control(
struct dcn10_ipp *ippn10,
bool pixel_data_invert,
enum dc_cursor_color_format color_format)
{
if (REG(CURSOR_SETTINS))
REG_SET_2(CURSOR_SETTINS, 0,
/* no shift of the cursor HDL schedule */
CURSOR0_DST_Y_OFFSET, 0,
/* used to shift the cursor chunk request deadline */
CURSOR0_CHUNK_HDL_ADJUST, 3);
else
REG_SET_2(CURSOR_SETTINGS, 0,
/* no shift of the cursor HDL schedule */
CURSOR0_DST_Y_OFFSET, 0,
/* used to shift the cursor chunk request deadline */
CURSOR0_CHUNK_HDL_ADJUST, 3);
REG_UPDATE_2(CURSOR0_CONTROL,
CUR0_MODE, color_format,
CUR0_EXPANSION_MODE, 0);
if (color_format == CURSOR_MODE_MONO) {
/* todo: clarify what to program these to */
REG_UPDATE(CURSOR0_COLOR0,
CUR0_COLOR0, 0x00000000);
REG_UPDATE(CURSOR0_COLOR1,
CUR0_COLOR1, 0xFFFFFFFF);
}
/* TODO: Fixed vs float */
REG_UPDATE_3(FORMAT_CONTROL,
CNVC_BYPASS, 0,
ALPHA_EN, 1,
FORMAT_EXPANSION_MODE, 0);
return true;
}
enum cursor_pitch {
CURSOR_PITCH_64_PIXELS = 0,
CURSOR_PITCH_128_PIXELS,
CURSOR_PITCH_256_PIXELS
};
enum cursor_lines_per_chunk {
CURSOR_LINE_PER_CHUNK_2 = 1,
CURSOR_LINE_PER_CHUNK_4,
CURSOR_LINE_PER_CHUNK_8,
CURSOR_LINE_PER_CHUNK_16
};
static enum cursor_pitch ippn10_get_cursor_pitch(
unsigned int pitch)
{
enum cursor_pitch hw_pitch;
switch (pitch) {
case 64:
hw_pitch = CURSOR_PITCH_64_PIXELS;
break;
case 128:
hw_pitch = CURSOR_PITCH_128_PIXELS;
break;
case 256:
hw_pitch = CURSOR_PITCH_256_PIXELS;
break;
default:
DC_ERR("Invalid cursor pitch of %d. "
"Only 64/128/256 is supported on DCN.\n", pitch);
hw_pitch = CURSOR_PITCH_64_PIXELS;
break;
}
return hw_pitch;
}
static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk(
unsigned int cur_width,
enum dc_cursor_color_format format)
{
enum cursor_lines_per_chunk line_per_chunk;
if (format == CURSOR_MODE_MONO)
/* impl B. expansion in CUR Buffer reader */
line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
else if (cur_width <= 32)
line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
else if (cur_width <= 64)
line_per_chunk = CURSOR_LINE_PER_CHUNK_8;
else if (cur_width <= 128)
line_per_chunk = CURSOR_LINE_PER_CHUNK_4;
else
line_per_chunk = CURSOR_LINE_PER_CHUNK_2;
return line_per_chunk;
}
static void ippn10_cursor_set_attributes(
struct input_pixel_processor *ipp,
const struct dc_cursor_attributes *attr)
{
struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp);
enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch);
enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk(
attr->width, attr->color_format);
ippn10->curs_attr = *attr;
REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH,
CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part);
REG_UPDATE(CURSOR_SURFACE_ADDRESS,
CURSOR_SURFACE_ADDRESS, attr->address.low_part);
REG_UPDATE_2(CURSOR_SIZE,
CURSOR_WIDTH, attr->width,
CURSOR_HEIGHT, attr->height);
REG_UPDATE_3(CURSOR_CONTROL,
CURSOR_MODE, attr->color_format,
CURSOR_PITCH, hw_pitch,
CURSOR_LINES_PER_CHUNK, lpc);
ippn10_cursor_program_control(ippn10,
attr->attribute_flags.bits.INVERT_PIXEL_DATA,
attr->color_format);
}
static void ippn10_cursor_set_position(
struct input_pixel_processor *ipp,
const struct dc_cursor_position *pos,
const struct dc_cursor_mi_param *param)
{
struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp);
int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
uint32_t cur_en = pos->enable ? 1 : 0;
uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
/*
* Guard aganst cursor_set_position() from being called with invalid
* attributes
*
* TODO: Look at combining cursor_set_position() and
* cursor_set_attributes() into cursor_update()
*/
if (ippn10->curs_attr.address.quad_part == 0)
return;
dst_x_offset *= param->ref_clk_khz;
dst_x_offset /= param->pixel_clk_khz;
ASSERT(param->h_scale_ratio.value);
if (param->h_scale_ratio.value)
dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div(
dal_fixed31_32_from_int(dst_x_offset),
param->h_scale_ratio));
if (src_x_offset >= (int)param->viewport_width)
cur_en = 0; /* not visible beyond right edge*/
if (src_x_offset + (int)ippn10->curs_attr.width < 0)
cur_en = 0; /* not visible beyond left edge*/
if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
ippn10_cursor_set_attributes(ipp, &ippn10->curs_attr);
REG_UPDATE(CURSOR_CONTROL,
CURSOR_ENABLE, cur_en);
REG_UPDATE(CURSOR0_CONTROL,
CUR0_ENABLE, cur_en);
REG_SET_2(CURSOR_POSITION, 0,
CURSOR_X_POSITION, pos->x,
CURSOR_Y_POSITION, pos->y);
REG_SET_2(CURSOR_HOT_SPOT, 0,
CURSOR_HOT_SPOT_X, pos->x_hotspot,
CURSOR_HOT_SPOT_Y, pos->y_hotspot);
REG_SET(CURSOR_DST_OFFSET, 0,
CURSOR_DST_X_OFFSET, dst_x_offset);
/* TODO Handle surface pixel formats other than 4:4:4 */
}
/*****************************************/
/* Constructor, Destructor */
/*****************************************/
@ -230,13 +48,6 @@ static void dcn10_ipp_destroy(struct input_pixel_processor **ipp)
}
static const struct ipp_funcs dcn10_ipp_funcs = {
.ipp_cursor_set_attributes = ippn10_cursor_set_attributes,
.ipp_cursor_set_position = ippn10_cursor_set_position,
.ipp_set_degamma = NULL,
.ipp_program_input_lut = NULL,
.ipp_full_bypass = NULL,
.ipp_setup = NULL,
.ipp_program_degamma_pwl = NULL,
.ipp_destroy = dcn10_ipp_destroy
};

View File

@ -65,7 +65,7 @@ static void mpc10_set_bg_color(
MPCC_BG_B_CB, bg_b_cb);
}
static void mpc10_assert_idle_mpcc(struct mpc *mpc, int id)
void mpc10_assert_idle_mpcc(struct mpc *mpc, int id)
{
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
@ -116,19 +116,21 @@ static void mpc10_assert_mpcc_idle_before_connect(struct dcn10_mpc *mpc10, int i
}
}
static void mpc10_mpcc_remove(
void mpc10_mpcc_remove(
struct mpc *mpc,
struct output_pixel_processor *opp,
struct mpc_tree_cfg *tree_cfg,
int opp_id,
int dpp_id)
{
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
int mpcc_id, z_idx;
for (z_idx = 0; z_idx < opp->mpc_tree.num_pipes; z_idx++)
if (opp->mpc_tree.dpp[z_idx] == dpp_id)
/* find z_idx for the dpp to be removed */
for (z_idx = 0; z_idx < tree_cfg->num_pipes; z_idx++)
if (tree_cfg->dpp[z_idx] == dpp_id)
break;
if (z_idx == opp->mpc_tree.num_pipes) {
if (z_idx == tree_cfg->num_pipes) {
/* In case of resume from S3/S4, remove mpcc from bios left over */
REG_SET(MPCC_OPP_ID[dpp_id], 0,
MPCC_OPP_ID, 0xf);
@ -139,7 +141,7 @@ static void mpc10_mpcc_remove(
return;
}
mpcc_id = opp->mpc_tree.mpcc[z_idx];
mpcc_id = tree_cfg->mpcc[z_idx];
REG_SET(MPCC_OPP_ID[mpcc_id], 0,
MPCC_OPP_ID, 0xf);
@ -149,82 +151,101 @@ static void mpc10_mpcc_remove(
MPCC_BOT_SEL, 0xf);
if (z_idx > 0) {
int top_mpcc_id = opp->mpc_tree.mpcc[z_idx - 1];
int top_mpcc_id = tree_cfg->mpcc[z_idx - 1];
if (z_idx + 1 < opp->mpc_tree.num_pipes)
if (z_idx + 1 < tree_cfg->num_pipes)
/* mpcc to be removed is in the middle of the tree */
REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0,
MPCC_BOT_SEL, opp->mpc_tree.mpcc[z_idx + 1]);
MPCC_BOT_SEL, tree_cfg->mpcc[z_idx + 1]);
else {
/* mpcc to be removed is at the bottom of the tree */
REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0,
MPCC_BOT_SEL, 0xf);
REG_UPDATE(MPCC_CONTROL[top_mpcc_id],
MPCC_MODE, MODE_TOP_ONLY);
}
} else if (opp->mpc_tree.num_pipes > 1)
REG_SET(MUX[opp->inst], 0,
MPC_OUT_MUX, opp->mpc_tree.mpcc[z_idx + 1]);
} else if (tree_cfg->num_pipes > 1)
/* mpcc to be removed is at the top of the tree */
REG_SET(MUX[opp_id], 0,
MPC_OUT_MUX, tree_cfg->mpcc[z_idx + 1]);
else
REG_SET(MUX[opp->inst], 0, MPC_OUT_MUX, 0xf);
/* mpcc to be removed is the only one in the tree */
REG_SET(MUX[opp_id], 0, MPC_OUT_MUX, 0xf);
/* mark this mpcc as not in use */
mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id);
opp->mpc_tree.num_pipes--;
for (; z_idx < opp->mpc_tree.num_pipes; z_idx++) {
opp->mpc_tree.dpp[z_idx] = opp->mpc_tree.dpp[z_idx + 1];
opp->mpc_tree.mpcc[z_idx] = opp->mpc_tree.mpcc[z_idx + 1];
tree_cfg->num_pipes--;
for (; z_idx < tree_cfg->num_pipes; z_idx++) {
tree_cfg->dpp[z_idx] = tree_cfg->dpp[z_idx + 1];
tree_cfg->mpcc[z_idx] = tree_cfg->mpcc[z_idx + 1];
}
opp->mpc_tree.dpp[opp->mpc_tree.num_pipes] = 0xdeadbeef;
opp->mpc_tree.mpcc[opp->mpc_tree.num_pipes] = 0xdeadbeef;
tree_cfg->dpp[tree_cfg->num_pipes] = 0xdeadbeef;
tree_cfg->mpcc[tree_cfg->num_pipes] = 0xdeadbeef;
}
static void mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg)
static void mpc10_add_to_tree_cfg(
struct mpc *mpc,
struct mpcc_cfg *cfg,
int mpcc_id)
{
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
int mpcc_mode = MODE_TOP_ONLY;
int position = cfg->z_index;
struct mpc_tree_cfg *tree_cfg = cfg->tree_cfg;
int alpha_blnd_mode = cfg->per_pixel_alpha ?
BLND_PP_ALPHA : BLND_GLOBAL_ALPHA;
int mpcc_mode = MODE_TOP_ONLY;
int mpcc_id, z_idx;
ASSERT(cfg->z_index < mpc10->num_mpcc);
for (z_idx = 0; z_idx < cfg->opp->mpc_tree.num_pipes; z_idx++)
if (cfg->opp->mpc_tree.dpp[z_idx] == cfg->mi->inst)
break;
if (z_idx == cfg->opp->mpc_tree.num_pipes) {
ASSERT(cfg->z_index <= cfg->opp->mpc_tree.num_pipes);
mpcc_id = mpc10_get_idle_mpcc_id(mpc10);
/*todo: remove hack*/
mpcc_id = cfg->mi->inst;
ASSERT(!(mpc10->mpcc_in_use_mask & 1 << mpcc_id));
if (mpc->ctx->dc->debug.sanity_checks)
mpc10_assert_mpcc_idle_before_connect(mpc10, mpcc_id);
} else {
ASSERT(cfg->z_index < cfg->opp->mpc_tree.num_pipes);
mpcc_id = cfg->opp->mpc_tree.mpcc[z_idx];
mpc10_mpcc_remove(mpc, cfg->opp, cfg->mi->inst);
}
int z_idx;
REG_SET(MPCC_OPP_ID[mpcc_id], 0,
MPCC_OPP_ID, cfg->opp->inst);
MPCC_OPP_ID, cfg->opp_id);
REG_SET(MPCC_TOP_SEL[mpcc_id], 0,
MPCC_TOP_SEL, cfg->mi->inst);
MPCC_TOP_SEL, cfg->dpp_id);
if (cfg->z_index > 0) {
int top_mpcc_id = cfg->opp->mpc_tree.mpcc[cfg->z_index - 1];
if (position == 0) {
/* idle dpp/mpcc is added to the top layer of tree */
REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0,
if (tree_cfg->num_pipes > 0) {
/* get instance of previous top mpcc */
int prev_top_mpcc_id = tree_cfg->mpcc[0];
REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
MPCC_BOT_SEL, prev_top_mpcc_id);
mpcc_mode = MODE_BLEND;
}
/* opp will get new output. from new added mpcc */
REG_SET(MUX[cfg->opp_id], 0, MPC_OUT_MUX, mpcc_id);
} else if (position == tree_cfg->num_pipes) {
/* idle dpp/mpcc is added to the bottom layer of tree */
/* get instance of previous bottom mpcc, set to middle layer */
int prev_bot_mpcc_id = tree_cfg->mpcc[tree_cfg->num_pipes - 1];
REG_SET(MPCC_BOT_SEL[prev_bot_mpcc_id], 0,
MPCC_BOT_SEL, mpcc_id);
REG_UPDATE(MPCC_CONTROL[top_mpcc_id],
REG_UPDATE(MPCC_CONTROL[prev_bot_mpcc_id],
MPCC_MODE, MODE_BLEND);
} else
REG_SET(MUX[cfg->opp->inst], 0, MPC_OUT_MUX, mpcc_id);
if (cfg->z_index < cfg->opp->mpc_tree.num_pipes) {
int bot_mpcc_id = cfg->opp->mpc_tree.mpcc[cfg->z_index];
/* mpcc_id become new bottom mpcc*/
REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
MPCC_BOT_SEL, bot_mpcc_id);
MPCC_BOT_SEL, 0xf);
} else {
/* idle dpp/mpcc is added to middle of tree */
int above_mpcc_id = tree_cfg->mpcc[position - 1];
int below_mpcc_id = tree_cfg->mpcc[position];
/* mpcc above new mpcc_id has new bottom mux*/
REG_SET(MPCC_BOT_SEL[above_mpcc_id], 0,
MPCC_BOT_SEL, mpcc_id);
REG_UPDATE(MPCC_CONTROL[above_mpcc_id],
MPCC_MODE, MODE_BLEND);
/* mpcc_id bottom mux is from below mpcc*/
REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
MPCC_BOT_SEL, below_mpcc_id);
mpcc_mode = MODE_BLEND;
}
@ -234,24 +255,91 @@ static void mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg)
MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha,
MPCC_BLND_ACTIVE_OVERLAP_ONLY, false);
/* update mpc_tree_cfg with new mpcc */
for (z_idx = tree_cfg->num_pipes; z_idx > position; z_idx--) {
tree_cfg->dpp[z_idx] = tree_cfg->dpp[z_idx - 1];
tree_cfg->mpcc[z_idx] = tree_cfg->mpcc[z_idx - 1];
}
tree_cfg->dpp[position] = cfg->dpp_id;
tree_cfg->mpcc[position] = mpcc_id;
tree_cfg->num_pipes++;
}
int mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg)
{
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
int mpcc_id, z_idx;
ASSERT(cfg->z_index < mpc10->num_mpcc);
/* check in dpp already exists in mpc tree */
for (z_idx = 0; z_idx < cfg->tree_cfg->num_pipes; z_idx++)
if (cfg->tree_cfg->dpp[z_idx] == cfg->dpp_id)
break;
if (z_idx == cfg->tree_cfg->num_pipes) {
ASSERT(cfg->z_index <= cfg->tree_cfg->num_pipes);
mpcc_id = mpc10_get_idle_mpcc_id(mpc10);
/*
* TODO: remove hack
* Note: currently there is a bug in init_hw such that
* on resume from hibernate, BIOS sets up MPCC0, and
* we do mpcc_remove but the mpcc cannot go to idle
* after remove. This cause us to pick mpcc1 here,
* which causes a pstate hang for yet unknown reason.
*/
mpcc_id = cfg->dpp_id;
/* end hack*/
ASSERT(!(mpc10->mpcc_in_use_mask & 1 << mpcc_id));
if (mpc->ctx->dc->debug.sanity_checks)
mpc10_assert_mpcc_idle_before_connect(mpc10, mpcc_id);
} else {
ASSERT(cfg->z_index < cfg->tree_cfg->num_pipes);
mpcc_id = cfg->tree_cfg->mpcc[z_idx];
mpc10_mpcc_remove(mpc, cfg->tree_cfg, cfg->opp_id, cfg->dpp_id);
}
/* add dpp/mpcc pair to mpc_tree_cfg and update mpcc registers */
mpc10_add_to_tree_cfg(mpc, cfg, mpcc_id);
/* set background color */
mpc10_set_bg_color(mpc10, &cfg->black_color, mpcc_id);
/* mark this mpcc as in use */
mpc10->mpcc_in_use_mask |= 1 << mpcc_id;
for (z_idx = cfg->opp->mpc_tree.num_pipes; z_idx > cfg->z_index; z_idx--) {
cfg->opp->mpc_tree.dpp[z_idx] = cfg->opp->mpc_tree.dpp[z_idx - 1];
cfg->opp->mpc_tree.mpcc[z_idx] = cfg->opp->mpc_tree.mpcc[z_idx - 1];
}
cfg->opp->mpc_tree.dpp[cfg->z_index] = cfg->mi->inst;
cfg->opp->mpc_tree.mpcc[cfg->z_index] = mpcc_id;
cfg->opp->mpc_tree.num_pipes++;
cfg->mi->opp_id = cfg->opp->inst;
cfg->mi->mpcc_id = mpcc_id;
return mpcc_id;
}
void mpc10_update_blend_mode(
struct mpc *mpc,
struct mpcc_cfg *cfg)
{
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
int mpcc_id, z_idx;
int alpha_blnd_mode = cfg->per_pixel_alpha ?
BLND_PP_ALPHA : BLND_GLOBAL_ALPHA;
/* find z_idx for the dpp that requires blending mode update*/
for (z_idx = 0; z_idx < cfg->tree_cfg->num_pipes; z_idx++)
if (cfg->tree_cfg->dpp[z_idx] == cfg->dpp_id)
break;
ASSERT(z_idx < cfg->tree_cfg->num_pipes);
mpcc_id = cfg->tree_cfg->mpcc[z_idx];
REG_UPDATE_2(MPCC_CONTROL[mpcc_id],
MPCC_ALPHA_BLND_MODE, alpha_blnd_mode,
MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha);
}
const struct mpc_funcs dcn10_mpc_funcs = {
.add = mpc10_mpcc_add,
.remove = mpc10_mpcc_remove,
.wait_for_idle = mpc10_assert_idle_mpcc
.wait_for_idle = mpc10_assert_idle_mpcc,
.update_blend_mode = mpc10_update_blend_mode,
};
void dcn10_mpc_construct(struct dcn10_mpc *mpc10,
@ -272,3 +360,4 @@ void dcn10_mpc_construct(struct dcn10_mpc *mpc10,
mpc10->mpcc_in_use_mask = 0;
mpc10->num_mpcc = num_mpcc;
}

View File

@ -34,7 +34,6 @@
#define MAX_OPP 6
#define MPC_COMMON_REG_LIST_DCN1_0(inst) \
SRII(MUX, MPC_OUT, inst),\
SRII(MPCC_TOP_SEL, MPCC, inst),\
SRII(MPCC_BOT_SEL, MPCC, inst),\
SRII(MPCC_CONTROL, MPCC, inst),\
@ -45,17 +44,19 @@
SRII(MPCC_BG_B_CB, MPCC, inst),\
SRII(MPCC_BG_B_CB, MPCC, inst)
struct dcn_mpc_registers {
uint32_t MPCC_TOP_SEL[MAX_MPCC];
uint32_t MPCC_BOT_SEL[MAX_MPCC];
uint32_t MPCC_CONTROL[MAX_MPCC];
uint32_t MPCC_STATUS[MAX_MPCC];
uint32_t MPCC_OPP_ID[MAX_MPCC];
uint32_t MPCC_BG_G_Y[MAX_MPCC];
uint32_t MPCC_BG_R_CR[MAX_MPCC];
uint32_t MPCC_BG_B_CB[MAX_MPCC];
#define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst) \
SRII(MUX, MPC_OUT, inst)
#define MPC_COMMON_REG_VARIABLE_LIST \
uint32_t MPCC_TOP_SEL[MAX_MPCC]; \
uint32_t MPCC_BOT_SEL[MAX_MPCC]; \
uint32_t MPCC_CONTROL[MAX_MPCC]; \
uint32_t MPCC_STATUS[MAX_MPCC]; \
uint32_t MPCC_OPP_ID[MAX_MPCC]; \
uint32_t MPCC_BG_G_Y[MAX_MPCC]; \
uint32_t MPCC_BG_R_CR[MAX_MPCC]; \
uint32_t MPCC_BG_B_CB[MAX_MPCC]; \
uint32_t MUX[MAX_OPP];
};
#define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\
SF(MPCC0_MPCC_TOP_SEL, MPCC_TOP_SEL, mask_sh),\
@ -87,6 +88,10 @@ struct dcn_mpc_registers {
type MPCC_BG_B_CB;\
type MPC_OUT_MUX;
struct dcn_mpc_registers {
MPC_COMMON_REG_VARIABLE_LIST
};
struct dcn_mpc_shift {
MPC_REG_FIELD_LIST(uint8_t)
};
@ -112,4 +117,22 @@ void dcn10_mpc_construct(struct dcn10_mpc *mpcc10,
const struct dcn_mpc_mask *mpc_mask,
int num_mpcc);
int mpc10_mpcc_add(
struct mpc *mpc,
struct mpcc_cfg *cfg);
void mpc10_mpcc_remove(
struct mpc *mpc,
struct mpc_tree_cfg *tree_cfg,
int opp_id,
int dpp_id);
void mpc10_assert_idle_mpcc(
struct mpc *mpc,
int id);
void mpc10_update_blend_mode(
struct mpc *mpc,
struct mpcc_cfg *cfg);
#endif

View File

@ -42,12 +42,12 @@
#include "dce/dce_stream_encoder.h"
#include "dce/dce_clocks.h"
#include "dce/dce_clock_source.h"
#include "dcn10/dcn10_mem_input.h"
#include "dce/dce_audio.h"
#include "dce/dce_hwseq.h"
#include "../virtual/virtual_stream_encoder.h"
#include "dce110/dce110_resource.h"
#include "dce112/dce112_resource.h"
#include "dcn10_hubp.h"
#include "vega10/soc15ip.h"
@ -329,7 +329,11 @@ static const struct dcn_mpc_registers mpc_regs = {
MPC_COMMON_REG_LIST_DCN1_0(0),
MPC_COMMON_REG_LIST_DCN1_0(1),
MPC_COMMON_REG_LIST_DCN1_0(2),
MPC_COMMON_REG_LIST_DCN1_0(3)
MPC_COMMON_REG_LIST_DCN1_0(3),
MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(0),
MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(1),
MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(2),
MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(3)
};
static const struct dcn_mpc_shift mpc_shift = {
@ -414,22 +418,24 @@ static const struct resource_caps res_cap = {
};
static const struct dc_debug debug_defaults_drv = {
.disable_dcc = false,
.sanity_checks = true,
.disable_dmcu = true,
.force_abm_enable = false,
.timing_trace = false,
.clock_trace = true,
/* spread sheet doesn't handle taps_c is one properly,
* need to enable scaler for video surface to pass
* bandwidth validation.*/
.always_scale = true,
.min_disp_clk_khz = 300000,
.disable_pplib_clock_request = true,
.disable_pplib_wm_range = false,
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
.use_dml_wm = false,
.disable_pipe_split = true
#endif
.pplib_wm_report_mode = WM_REPORT_DEFAULT,
.pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP,
.force_single_disp_pipe_split = true,
.disable_dcc = DCC_ENABLE,
.voltage_align_fclk = true,
.disable_stereo_support = true,
.vsr_support = true,
.performance_trace = false,
};
static const struct dc_debug debug_defaults_diags = {
@ -438,21 +444,17 @@ static const struct dc_debug debug_defaults_diags = {
.timing_trace = true,
.clock_trace = true,
.disable_stutter = true,
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
.disable_pplib_clock_request = true,
.disable_pplib_wm_range = true,
.use_dml_wm = false,
.disable_pipe_split = false
#endif
.disable_pplib_wm_range = true
};
static void dcn10_dpp_destroy(struct transform **xfm)
static void dcn10_dpp_destroy(struct dpp **dpp)
{
kfree(TO_DCN10_DPP(*xfm));
*xfm = NULL;
kfree(TO_DCN10_DPP(*dpp));
*dpp = NULL;
}
static struct transform *dcn10_dpp_create(
static struct dpp *dcn10_dpp_create(
struct dc_context *ctx,
uint32_t inst)
{
@ -462,8 +464,8 @@ static struct transform *dcn10_dpp_create(
if (!dpp)
return NULL;
dcn10_dpp_construct(dpp, ctx, inst,
&tf_regs[inst], &tf_shift, &tf_mask);
dpp1_construct(dpp, ctx, inst,
&tf_regs[inst], &tf_shift, &tf_mask);
return &dpp->base;
}
@ -702,15 +704,15 @@ static void destruct(struct dcn10_resource_pool *pool)
if (pool->base.opps[i] != NULL)
pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
if (pool->base.transforms[i] != NULL)
dcn10_dpp_destroy(&pool->base.transforms[i]);
if (pool->base.dpps[i] != NULL)
dcn10_dpp_destroy(&pool->base.dpps[i]);
if (pool->base.ipps[i] != NULL)
pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
if (pool->base.mis[i] != NULL) {
kfree(TO_DCN10_MEM_INPUT(pool->base.mis[i]));
pool->base.mis[i] = NULL;
if (pool->base.hubps[i] != NULL) {
kfree(TO_DCN10_HUBP(pool->base.hubps[i]));
pool->base.hubps[i] = NULL;
}
if (pool->base.irqs != NULL) {
@ -757,19 +759,19 @@ static void destruct(struct dcn10_resource_pool *pool)
kfree(pool->base.pp_smu);
}
static struct mem_input *dcn10_mem_input_create(
static struct hubp *dcn10_hubp_create(
struct dc_context *ctx,
uint32_t inst)
{
struct dcn10_mem_input *mem_inputn10 =
kzalloc(sizeof(struct dcn10_mem_input), GFP_KERNEL);
struct dcn10_hubp *hubp1 =
kzalloc(sizeof(struct dcn10_hubp), GFP_KERNEL);
if (!mem_inputn10)
if (!hubp1)
return NULL;
dcn10_mem_input_construct(mem_inputn10, ctx, inst,
&mi_regs[inst], &mi_shift, &mi_mask);
return &mem_inputn10->base;
dcn10_hubp_construct(hubp1, ctx, inst,
&mi_regs[inst], &mi_shift, &mi_mask);
return &hubp1->base;
}
static void get_pixel_clock_parameters(
@ -922,9 +924,9 @@ static struct pipe_ctx *dcn10_acquire_idle_pipe_for_layer(
idle_pipe->stream_res.tg = head_pipe->stream_res.tg;
idle_pipe->stream_res.opp = head_pipe->stream_res.opp;
idle_pipe->plane_res.mi = pool->mis[idle_pipe->pipe_idx];
idle_pipe->plane_res.hubp = pool->hubps[idle_pipe->pipe_idx];
idle_pipe->plane_res.ipp = pool->ipps[idle_pipe->pipe_idx];
idle_pipe->plane_res.xfm = pool->transforms[idle_pipe->pipe_idx];
idle_pipe->plane_res.dpp = pool->dpps[idle_pipe->pipe_idx];
return idle_pipe;
}
@ -1085,7 +1087,7 @@ static bool get_dcc_compression_cap(const struct dc *dc,
memset(output, 0, sizeof(*output));
if (dc->debug.disable_dcc)
if (dc->debug.disable_dcc == DCC_DISABLE)
return false;
if (!dcc_support_pixel_format(input->format,
@ -1129,6 +1131,10 @@ static bool get_dcc_compression_cap(const struct dc *dc,
dcc_control = dcc_control__128_128_xxx;
}
if (dc->debug.disable_dcc == DCC_HALF_REQ_DISALBE &&
dcc_control != dcc_control__256_256_xxx)
return false;
switch (dcc_control) {
case dcc_control__256_256_xxx:
output->grph.rgb.max_uncompressed_blk_size = 256;
@ -1146,6 +1152,7 @@ static bool get_dcc_compression_cap(const struct dc *dc,
output->grph.rgb.independent_64b_blks = true;
break;
}
output->capable = true;
output->const_color_support = false;
@ -1162,6 +1169,15 @@ static void dcn10_destroy_resource_pool(struct resource_pool **pool)
*pool = NULL;
}
static enum dc_status dcn10_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps)
{
if (plane_state->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
&& caps->max_video_width != 0
&& plane_state->src_rect.width > caps->max_video_width)
return DC_FAIL_SURFACE_VALIDATE;
return DC_OK;
}
static struct dc_cap_funcs cap_funcs = {
.get_dcc_compression_cap = get_dcc_compression_cap
@ -1173,6 +1189,7 @@ static struct resource_funcs dcn10_res_pool_funcs = {
.validate_guaranteed = dcn10_validate_guaranteed,
.validate_bandwidth = dcn_validate_bandwidth,
.acquire_idle_pipe_for_layer = dcn10_acquire_idle_pipe_for_layer,
.validate_plane = dcn10_validate_plane,
.add_stream_to_ctx = dcn10_add_stream_to_ctx
};
@ -1212,6 +1229,7 @@ static bool construct(
/* max pipe num for ASIC before check pipe fuses */
pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
dc->caps.max_video_width = 3840;
dc->caps.max_downscale_ratio = 200;
dc->caps.i2c_speed_in_khz = 100;
dc->caps.max_cursor_size = 256;
@ -1345,8 +1363,8 @@ static bool construct(
if ((pipe_fuses & (1 << i)) != 0)
continue;
pool->base.mis[j] = dcn10_mem_input_create(ctx, i);
if (pool->base.mis[j] == NULL) {
pool->base.hubps[j] = dcn10_hubp_create(ctx, i);
if (pool->base.hubps[j] == NULL) {
BREAK_TO_DEBUGGER();
dm_error(
"DC: failed to create memory input!\n");
@ -1361,8 +1379,8 @@ static bool construct(
goto ipp_create_fail;
}
pool->base.transforms[j] = dcn10_dpp_create(ctx, i);
if (pool->base.transforms[j] == NULL) {
pool->base.dpps[j] = dcn10_dpp_create(ctx, i);
if (pool->base.dpps[j] == NULL) {
BREAK_TO_DEBUGGER();
dm_error(
"DC: failed to create dpp!\n");

View File

@ -25,6 +25,7 @@
#include "reg_helper.h"
#include "dcn10_timing_generator.h"
#include "dc.h"
#define REG(reg)\
tgn10->tg_regs->reg
@ -299,6 +300,17 @@ static void tgn10_program_timing(
static void tgn10_unblank_crtc(struct timing_generator *tg)
{
struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
uint32_t vertical_interrupt_enable = 0;
REG_GET(OTG_VERTICAL_INTERRUPT2_CONTROL,
OTG_VERTICAL_INTERRUPT2_INT_ENABLE, &vertical_interrupt_enable);
/* temporary work around for vertical interrupt, once vertical interrupt enabled,
* this check will be removed.
*/
if (vertical_interrupt_enable)
REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL,
OTG_BLANK_DATA_DOUBLE_BUFFER_EN, 1);
REG_UPDATE_2(OTG_BLANK_CONTROL,
OTG_BLANK_DATA_EN, 0,
@ -487,6 +499,9 @@ static bool tgn10_validate_timing(
timing->timing_3d_format != TIMING_3D_FORMAT_INBAND_FA)
return false;
if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE &&
tg->ctx->dc->debug.disable_stereo_support)
return false;
/* Temporarily blocking interlacing mode until it's supported */
if (timing->flags.INTERLACE == 1)
return false;

View File

@ -65,17 +65,14 @@
SRI(OTG_NOM_VERT_POSITION, OTG, inst),\
SRI(OTG_BLACK_COLOR, OTG, inst),\
SRI(OTG_CLOCK_CONTROL, OTG, inst),\
SRI(OTG_VERTICAL_INTERRUPT2_CONTROL, OTG, inst),\
SRI(OTG_VERTICAL_INTERRUPT2_POSITION, OTG, inst),\
SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\
SRI(OPTC_DATA_SOURCE_SELECT, ODM, inst),\
SRI(OPTC_INPUT_GLOBAL_CONTROL, ODM, inst),\
SRI(OPPBUF_CONTROL, OPPBUF, inst),\
SRI(OPPBUF_3D_PARAMETERS_0, OPPBUF, inst),\
SRI(CONTROL, VTG, inst),\
SR(D1VGA_CONTROL),\
SR(D2VGA_CONTROL),\
SR(D3VGA_CONTROL),\
SR(D4VGA_CONTROL)
SRI(CONTROL, VTG, inst)
#define TG_COMMON_REG_LIST_DCN1_0(inst) \
TG_COMMON_REG_LIST_DCN(inst),\
@ -121,6 +118,7 @@ struct dcn_tg_registers {
uint32_t OTG_TEST_PATTERN_CONTROL;
uint32_t OTG_TEST_PATTERN_COLOR;
uint32_t OTG_CLOCK_CONTROL;
uint32_t OTG_VERTICAL_INTERRUPT2_CONTROL;
uint32_t OTG_VERTICAL_INTERRUPT2_POSITION;
uint32_t OPTC_INPUT_CLOCK_CONTROL;
uint32_t OPTC_DATA_SOURCE_SELECT;
@ -128,11 +126,6 @@ struct dcn_tg_registers {
uint32_t OPPBUF_CONTROL;
uint32_t OPPBUF_3D_PARAMETERS_0;
uint32_t CONTROL;
/*todo: move VGA to HWSS */
uint32_t D1VGA_CONTROL;
uint32_t D2VGA_CONTROL;
uint32_t D3VGA_CONTROL;
uint32_t D4VGA_CONTROL;
};
#define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\
@ -205,6 +198,7 @@ struct dcn_tg_registers {
SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_EN, mask_sh),\
SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_ON, mask_sh),\
SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_GATE_DIS, 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),\
SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_ON, mask_sh),\
@ -311,6 +305,7 @@ struct dcn_tg_registers {
type OTG_CLOCK_EN;\
type OTG_CLOCK_ON;\
type OTG_CLOCK_GATE_DIS;\
type OTG_VERTICAL_INTERRUPT2_INT_ENABLE;\
type OTG_VERTICAL_INTERRUPT2_LINE_START;\
type OPTC_INPUT_CLK_EN;\
type OPTC_INPUT_CLK_ON;\

View File

@ -38,51 +38,6 @@
#undef DEPRECATED
/*
*
* general debug capabilities
*
*/
#if defined(CONFIG_DEBUG_KERNEL) || defined(CONFIG_DEBUG_DRIVER)
#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB)
#define ASSERT_CRITICAL(expr) do { \
if (WARN_ON(!(expr))) { \
kgdb_breakpoint(); \
} \
} while (0)
#else
#define ASSERT_CRITICAL(expr) do { \
if (WARN_ON(!(expr))) { \
; \
} \
} while (0)
#endif
#if defined(CONFIG_DEBUG_KERNEL_DC)
#define ASSERT(expr) ASSERT_CRITICAL(expr)
#else
#define ASSERT(expr) WARN_ON(!(expr))
#endif
#define BREAK_TO_DEBUGGER() ASSERT(0)
#endif /* CONFIG_DEBUG_KERNEL || CONFIG_DEBUG_DRIVER */
#define DC_ERR(...) do { \
dm_error(__VA_ARGS__); \
BREAK_TO_DEBUGGER(); \
} while (0)
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
#include <asm/fpu/api.h>
#endif
#define dm_alloc(size) kzalloc(size, GFP_KERNEL)
#define dm_realloc(ptr, size) krealloc(ptr, size, GFP_KERNEL)
#define dm_free(ptr) kfree(ptr)
irq_handler_idx dm_register_interrupt(
struct dc_context *ctx,
struct dc_interrupt_params *int_params,
@ -418,6 +373,8 @@ bool dm_dmcu_set_pipe(struct dc_context *ctx, unsigned int controller_id);
#define dm_log_to_buffer(buffer, size, fmt, args)\
vsnprintf(buffer, size, fmt, args)
unsigned long long dm_get_timestamp(struct dc_context *ctx);
/*
* Debug and verification hooks
*/

View File

@ -3,17 +3,19 @@
# It provides the general basic services required by other DAL
# subcomponents.
CFLAGS_display_mode_vba.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_display_mode_lib.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_display_pipe_clocks.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_display_rq_dlg_calc.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_dml1_display_rq_dlg_calc.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_display_rq_dlg_helpers.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_display_watermark.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_soc_bounding_box.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_dml_common_defs.o := -mhard-float -msse -mpreferred-stack-boundary=4
DML = display_mode_lib.o display_rq_dlg_calc.o \
display_rq_dlg_helpers.o display_watermark.o \
soc_bounding_box.o dml_common_defs.o
display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \
soc_bounding_box.o dml_common_defs.o display_mode_vba.o
AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML))

View File

@ -25,9 +25,11 @@
#ifndef __DC_FEATURES_H__
#define __DC_FEATURES_H__
// local features
#define DC__PRESENT 1
#define DC__PRESENT__1 1
#define DC__NUM_DPP 4
#define DC__VOLTAGE_STATES 7
#define DC__NUM_DPP__4 1
#define DC__NUM_DPP__0_PRESENT 1
#define DC__NUM_DPP__1_PRESENT 1

View File

@ -24,14 +24,12 @@
*/
#ifndef __DISPLAY_MODE_ENUMS_H__
#define __DISPLAY_MODE_ENUMS_H__
enum output_encoder_class {
dm_dp = 0,
dm_hdmi = 1,
dm_wb = 2
dm_dp = 0, dm_hdmi = 1, dm_wb = 2, dm_edp
};
enum output_format_class {
dm_444 = 0,
dm_420 = 1
dm_444 = 0, dm_420 = 1, dm_n422, dm_s422
};
enum source_format_class {
dm_444_16 = 0,
@ -40,18 +38,16 @@ enum source_format_class {
dm_420_8 = 3,
dm_420_10 = 4,
dm_422_8 = 5,
dm_422_10 = 6
dm_422_10 = 6,
dm_444_8 = 7,
dm_mono_8,
dm_mono_16
};
enum output_bpc_class {
dm_out_6 = 0,
dm_out_8 = 1,
dm_out_10 = 2,
dm_out_12 = 3,
dm_out_16 = 4
dm_out_6 = 0, dm_out_8 = 1, dm_out_10 = 2, dm_out_12 = 3, dm_out_16 = 4
};
enum scan_direction_class {
dm_horz = 0,
dm_vert = 1
dm_horz = 0, dm_vert = 1
};
enum dm_swizzle_mode {
dm_sw_linear = 0,
@ -84,28 +80,32 @@ enum dm_swizzle_mode {
dm_sw_SPARE_14 = 27,
dm_sw_SPARE_15 = 28,
dm_sw_var_s_x = 29,
dm_sw_var_d_x = 30
dm_sw_var_d_x = 30,
dm_sw_64kb_r_x,
dm_sw_gfx7_2d_thin_lvp,
dm_sw_gfx7_2d_thin_gl
};
enum lb_depth {
dm_lb_10 = 30,
dm_lb_8 = 24,
dm_lb_6 = 18,
dm_lb_12 = 36
dm_lb_10 = 0, dm_lb_8 = 1, dm_lb_6 = 2, dm_lb_12 = 3, dm_lb_16
};
enum voltage_state {
dm_vmin = 0,
dm_vmid = 1,
dm_vnom = 2,
dm_vmax = 3,
dm_vmax_exceeded = 4
dm_vmin = 0, dm_vmid = 1, dm_vnom = 2, dm_vmax = 3
};
enum source_macro_tile_size {
dm_4k_tile = 0,
dm_64k_tile = 1,
dm_256k_tile = 2
dm_4k_tile = 0, dm_64k_tile = 1, dm_256k_tile = 2
};
enum cursor_bpp {
dm_cur_2bit = 0,
dm_cur_32bit = 1
dm_cur_2bit = 0, dm_cur_32bit = 1, dm_cur_64bit = 2
};
enum clock_change_support {
dm_dram_clock_change_uninitialized = 0,
dm_dram_clock_change_vactive,
dm_dram_clock_change_vblank,
dm_dram_clock_change_unsupported
};
enum output_standard {
dm_std_uninitialized = 0, dm_std_cvtr2, dm_std_cvt
};
#endif

View File

@ -24,6 +24,7 @@
*/
#include "display_mode_lib.h"
#include "dc_features.h"
static void set_soc_bounding_box(struct _vcs_dpi_soc_bounding_box_st *soc, enum dml_project project)
{
@ -126,21 +127,11 @@ static void set_ip_params(struct _vcs_dpi_ip_params_st *ip, enum dml_project pro
}
}
static void set_mode_evaluation(struct _vcs_dpi_mode_evaluation_st *me, enum dml_project project)
{
if (project == DML_PROJECT_RAVEN1) {
me->voltage_override = dm_vmin;
} else {
BREAK_TO_DEBUGGER(); /* Invalid Project Specified */
}
}
void dml_init_instance(struct display_mode_lib *lib, enum dml_project project)
{
if (lib->project != project) {
set_soc_bounding_box(&lib->soc, project);
set_ip_params(&lib->ip, project);
set_mode_evaluation(&lib->me, project);
lib->project = project;
}
}

View File

@ -25,11 +25,12 @@
#ifndef __DISPLAY_MODE_LIB_H__
#define __DISPLAY_MODE_LIB_H__
#include "dml_common_defs.h"
#include "soc_bounding_box.h"
#include "display_watermark.h"
#include "display_mode_vba.h"
#include "display_rq_dlg_calc.h"
#include "display_mode_support.h"
#include "dml1_display_rq_dlg_calc.h"
enum dml_project {
DML_PROJECT_UNDEFINED,
@ -39,10 +40,8 @@ enum dml_project {
struct display_mode_lib {
struct _vcs_dpi_ip_params_st ip;
struct _vcs_dpi_soc_bounding_box_st soc;
struct _vcs_dpi_mode_evaluation_st me;
enum dml_project project;
struct dml_ms_internal_vars vars;
struct _vcs_dpi_wm_calc_pipe_params_st wm_param[DC__NUM_PIPES__MAX];
struct vba_vars_st vba;
struct dal_logger *logger;
};

View File

@ -25,405 +25,533 @@
#ifndef __DISPLAY_MODE_STRUCTS_H__
#define __DISPLAY_MODE_STRUCTS_H__
typedef struct _vcs_dpi_voltage_scaling_st voltage_scaling_st;
typedef struct _vcs_dpi_soc_bounding_box_st soc_bounding_box_st;
typedef struct _vcs_dpi_ip_params_st ip_params_st;
typedef struct _vcs_dpi_display_pipe_source_params_st display_pipe_source_params_st;
typedef struct _vcs_dpi_display_output_params_st display_output_params_st;
typedef struct _vcs_dpi_display_bandwidth_st display_bandwidth_st;
typedef struct _vcs_dpi_scaler_ratio_depth_st scaler_ratio_depth_st;
typedef struct _vcs_dpi_scaler_taps_st scaler_taps_st;
typedef struct _vcs_dpi_display_pipe_dest_params_st display_pipe_dest_params_st;
typedef struct _vcs_dpi_display_pipe_params_st display_pipe_params_st;
typedef struct _vcs_dpi_display_clocks_and_cfg_st display_clocks_and_cfg_st;
typedef struct _vcs_dpi_display_e2e_pipe_params_st display_e2e_pipe_params_st;
typedef struct _vcs_dpi_dchub_buffer_sizing_st dchub_buffer_sizing_st;
typedef struct _vcs_dpi_watermarks_perf_st watermarks_perf_st;
typedef struct _vcs_dpi_cstate_pstate_watermarks_st cstate_pstate_watermarks_st;
typedef struct _vcs_dpi_wm_calc_pipe_params_st wm_calc_pipe_params_st;
typedef struct _vcs_dpi_vratio_pre_st vratio_pre_st;
typedef struct _vcs_dpi_display_data_rq_misc_params_st display_data_rq_misc_params_st;
typedef struct _vcs_dpi_display_data_rq_sizing_params_st display_data_rq_sizing_params_st;
typedef struct _vcs_dpi_display_data_rq_dlg_params_st display_data_rq_dlg_params_st;
typedef struct _vcs_dpi_display_cur_rq_dlg_params_st display_cur_rq_dlg_params_st;
typedef struct _vcs_dpi_display_rq_dlg_params_st display_rq_dlg_params_st;
typedef struct _vcs_dpi_display_rq_sizing_params_st display_rq_sizing_params_st;
typedef struct _vcs_dpi_display_rq_misc_params_st display_rq_misc_params_st;
typedef struct _vcs_dpi_display_rq_params_st display_rq_params_st;
typedef struct _vcs_dpi_display_dlg_regs_st display_dlg_regs_st;
typedef struct _vcs_dpi_display_ttu_regs_st display_ttu_regs_st;
typedef struct _vcs_dpi_display_data_rq_regs_st display_data_rq_regs_st;
typedef struct _vcs_dpi_display_rq_regs_st display_rq_regs_st;
typedef struct _vcs_dpi_display_dlg_sys_params_st display_dlg_sys_params_st;
typedef struct _vcs_dpi_display_dlg_prefetch_param_st display_dlg_prefetch_param_st;
typedef struct _vcs_dpi_display_pipe_clock_st display_pipe_clock_st;
typedef struct _vcs_dpi_display_arb_params_st display_arb_params_st;
struct _vcs_dpi_voltage_scaling_st {
int state;
double dscclk_mhz;
double dcfclk_mhz;
double socclk_mhz;
double dram_speed_mhz;
double fabricclk_mhz;
double dispclk_mhz;
double dppclk_mhz;
double dram_bw_per_chan_gbps;
double phyclk_mhz;
double socclk_mhz;
double dppclk_mhz;
};
struct _vcs_dpi_soc_bounding_box_st {
double sr_exit_time_us;
double sr_enter_plus_exit_time_us;
double urgent_latency_us;
double writeback_latency_us;
double ideal_dram_bw_after_urgent_percent;
unsigned int max_request_size_bytes;
struct _vcs_dpi_voltage_scaling_st vmin;
struct _vcs_dpi_voltage_scaling_st vmid;
struct _vcs_dpi_voltage_scaling_st vnom;
struct _vcs_dpi_voltage_scaling_st vmax;
double downspread_percent;
double dram_page_open_time_ns;
double dram_rw_turnaround_time_ns;
double dram_return_buffer_per_channel_bytes;
unsigned int round_trip_ping_latency_dcfclk_cycles;
unsigned int urgent_out_of_order_return_per_channel_bytes;
unsigned int channel_interleave_bytes;
unsigned int num_banks;
unsigned int num_chans;
unsigned int vmm_page_size_bytes;
double dram_clock_change_latency_us;
double writeback_dram_clock_change_latency_us;
unsigned int return_bus_width_bytes;
struct _vcs_dpi_soc_bounding_box_st {
double sr_exit_time_us;
double sr_enter_plus_exit_time_us;
double urgent_latency_us;
double writeback_latency_us;
double ideal_dram_bw_after_urgent_percent;
unsigned int max_request_size_bytes;
struct _vcs_dpi_voltage_scaling_st vmin;
struct _vcs_dpi_voltage_scaling_st vmid;
struct _vcs_dpi_voltage_scaling_st vnom;
struct _vcs_dpi_voltage_scaling_st vmax;
double downspread_percent;
double dram_page_open_time_ns;
double dram_rw_turnaround_time_ns;
double dram_return_buffer_per_channel_bytes;
double dram_channel_width_bytes;
double fabric_datapath_to_dcn_data_return_bytes;
double dcn_downspread_percent;
double dispclk_dppclk_vco_speed_mhz;
double dfs_vco_period_ps;
unsigned int round_trip_ping_latency_dcfclk_cycles;
unsigned int urgent_out_of_order_return_per_channel_bytes;
unsigned int channel_interleave_bytes;
unsigned int num_banks;
unsigned int num_chans;
unsigned int vmm_page_size_bytes;
double dram_clock_change_latency_us;
double writeback_dram_clock_change_latency_us;
unsigned int return_bus_width_bytes;
unsigned int voltage_override;
double xfc_bus_transport_time_us;
double xfc_xbuf_latency_tolerance_us;
struct _vcs_dpi_voltage_scaling_st clock_limits[7];
};
struct _vcs_dpi_ip_params_st {
unsigned int rob_buffer_size_kbytes;
unsigned int det_buffer_size_kbytes;
unsigned int dpte_buffer_size_in_pte_reqs;
unsigned int dpp_output_buffer_pixels;
unsigned int opp_output_buffer_lines;
unsigned int pixel_chunk_size_kbytes;
unsigned char pte_enable;
unsigned int pte_chunk_size_kbytes;
unsigned int meta_chunk_size_kbytes;
unsigned int writeback_chunk_size_kbytes;
unsigned int line_buffer_size_bits;
unsigned int max_line_buffer_lines;
struct _vcs_dpi_ip_params_st {
unsigned int max_inter_dcn_tile_repeaters;
unsigned int num_dsc;
unsigned int odm_capable;
unsigned int rob_buffer_size_kbytes;
unsigned int det_buffer_size_kbytes;
unsigned int dpte_buffer_size_in_pte_reqs;
unsigned int pde_proc_buffer_size_64k_reqs;
unsigned int dpp_output_buffer_pixels;
unsigned int opp_output_buffer_lines;
unsigned int pixel_chunk_size_kbytes;
unsigned char pte_enable;
unsigned int pte_chunk_size_kbytes;
unsigned int meta_chunk_size_kbytes;
unsigned int writeback_chunk_size_kbytes;
unsigned int line_buffer_size_bits;
unsigned int max_line_buffer_lines;
unsigned int writeback_luma_buffer_size_kbytes;
unsigned int writeback_chroma_buffer_size_kbytes;
unsigned int writeback_chroma_line_buffer_width_pixels;
unsigned int max_page_table_levels;
unsigned int max_num_dpp;
unsigned int max_num_otg;
unsigned int cursor_chunk_size;
unsigned int cursor_buffer_size;
unsigned int max_num_wb;
unsigned int max_dchub_pscl_bw_pix_per_clk;
unsigned int max_pscl_lb_bw_pix_per_clk;
unsigned int max_lb_vscl_bw_pix_per_clk;
unsigned int max_vscl_hscl_bw_pix_per_clk;
double max_hscl_ratio;
double max_vscl_ratio;
unsigned int hscl_mults;
unsigned int vscl_mults;
unsigned int max_hscl_taps;
unsigned int max_vscl_taps;
unsigned int xfc_supported;
unsigned int ptoi_supported;
unsigned int xfc_fill_constant_bytes;
double dispclk_ramp_margin_percent;
double xfc_fill_bw_overhead_percent;
double underscan_factor;
unsigned int min_vblank_lines;
unsigned int dppclk_delay_subtotal;
unsigned int dispclk_delay_subtotal;
unsigned int dcfclk_cstate_latency;
unsigned int dppclk_delay_scl;
unsigned int dppclk_delay_scl_lb_only;
unsigned int dppclk_delay_cnvc_formatter;
unsigned int dppclk_delay_cnvc_cursor;
unsigned int is_line_buffer_bpp_fixed;
unsigned int line_buffer_fixed_bpp;
unsigned int dcc_supported;
unsigned int IsLineBufferBppFixed;
unsigned int LineBufferFixedBpp;
unsigned int writeback_luma_buffer_size_kbytes;
unsigned int writeback_chroma_buffer_size_kbytes;
unsigned int max_num_dpp;
unsigned int max_num_wb;
unsigned int max_dchub_pscl_bw_pix_per_clk;
unsigned int max_pscl_lb_bw_pix_per_clk;
unsigned int max_lb_vscl_bw_pix_per_clk;
unsigned int max_vscl_hscl_bw_pix_per_clk;
double max_hscl_ratio;
double max_vscl_ratio;
unsigned int hscl_mults;
unsigned int vscl_mults;
unsigned int max_hscl_taps;
unsigned int max_vscl_taps;
double dispclk_ramp_margin_percent;
double underscan_factor;
unsigned int min_vblank_lines;
unsigned int dppclk_delay_subtotal;
unsigned int dispclk_delay_subtotal;
unsigned int dcfclk_cstate_latency;
unsigned int max_inter_dcn_tile_repeaters;
unsigned int can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one;
unsigned int bug_forcing_LC_req_same_size_fixed;
};
struct _vcs_dpi_display_pipe_source_params_st {
int source_format;
unsigned char dcc;
unsigned int dcc_rate;
unsigned char vm;
int source_scan;
int sw_mode;
int macro_tile_size;
unsigned char is_display_sw;
unsigned int viewport_width;
unsigned int viewport_height;
unsigned int viewport_width_c;
unsigned int viewport_height_c;
unsigned int data_pitch;
unsigned int data_pitch_c;
unsigned int meta_pitch;
unsigned int meta_pitch_c;
unsigned int cur0_src_width;
int cur0_bpp;
unsigned char is_hsplit;
unsigned int hsplit_grp;
struct _vcs_dpi_display_xfc_params_st {
double xfc_tslv_vready_offset_us;
double xfc_tslv_vupdate_width_us;
double xfc_tslv_vupdate_offset_us;
int xfc_slv_chunk_size_bytes;
};
struct _vcs_dpi_display_output_params_st {
int output_bpc;
int output_type;
int output_format;
int output_standard;
struct _vcs_dpi_display_pipe_source_params_st {
int source_format;
unsigned char dcc;
unsigned int dcc_override;
unsigned int dcc_rate;
unsigned char dcc_use_global;
unsigned char vm;
unsigned char vm_levels_force_en;
unsigned int vm_levels_force;
int source_scan;
int sw_mode;
int macro_tile_size;
unsigned char is_display_sw;
unsigned int viewport_width;
unsigned int viewport_height;
unsigned int viewport_y_y;
unsigned int viewport_y_c;
unsigned int viewport_width_c;
unsigned int viewport_height_c;
unsigned int data_pitch;
unsigned int data_pitch_c;
unsigned int meta_pitch;
unsigned int meta_pitch_c;
unsigned int cur0_src_width;
int cur0_bpp;
unsigned int cur1_src_width;
int cur1_bpp;
int num_cursors;
unsigned char is_hsplit;
unsigned char dynamic_metadata_enable;
unsigned int dynamic_metadata_lines_before_active;
unsigned int dynamic_metadata_xmit_bytes;
unsigned int hsplit_grp;
unsigned char xfc_enable;
unsigned char xfc_slave;
struct _vcs_dpi_display_xfc_params_st xfc_params;
};
struct writeback_st {
int wb_src_height;
int wb_dst_width;
int wb_dst_height;
int wb_pixel_format;
int wb_htaps_luma;
int wb_vtaps_luma;
int wb_htaps_chroma;
int wb_vtaps_chroma;
int wb_hratio;
int wb_vratio;
};
struct _vcs_dpi_display_bandwidth_st {
double total_bw_consumed_gbps;
double guaranteed_urgent_return_bw_gbps;
struct _vcs_dpi_display_output_params_st {
int dp_lanes;
int output_bpp;
int dsc_enable;
int wb_enable;
int output_bpc;
int output_type;
int output_format;
int output_standard;
int dsc_slices;
struct writeback_st wb;
};
struct _vcs_dpi_scaler_ratio_depth_st {
double hscl_ratio;
double vscl_ratio;
double hscl_ratio_c;
double vscl_ratio_c;
double vinit;
double vinit_c;
double vinit_bot;
double vinit_bot_c;
int lb_depth;
struct _vcs_dpi_display_bandwidth_st {
double total_bw_consumed_gbps;
double guaranteed_urgent_return_bw_gbps;
};
struct _vcs_dpi_scaler_taps_st {
unsigned int htaps;
unsigned int vtaps;
unsigned int htaps_c;
unsigned int vtaps_c;
struct _vcs_dpi_scaler_ratio_depth_st {
double hscl_ratio;
double vscl_ratio;
double hscl_ratio_c;
double vscl_ratio_c;
double vinit;
double vinit_c;
double vinit_bot;
double vinit_bot_c;
int lb_depth;
int scl_enable;
};
struct _vcs_dpi_display_pipe_dest_params_st {
unsigned int recout_width;
unsigned int recout_height;
unsigned int full_recout_width;
unsigned int full_recout_height;
unsigned int hblank_start;
unsigned int hblank_end;
unsigned int vblank_start;
unsigned int vblank_end;
unsigned int htotal;
unsigned int vtotal;
unsigned int vactive;
unsigned int vstartup_start;
unsigned int vupdate_offset;
unsigned int vupdate_width;
unsigned int vready_offset;
unsigned int vsync_plus_back_porch;
unsigned char interlaced;
unsigned char underscan;
double pixel_rate_mhz;
unsigned char syncronized_vblank_all_planes;
struct _vcs_dpi_scaler_taps_st {
unsigned int htaps;
unsigned int vtaps;
unsigned int htaps_c;
unsigned int vtaps_c;
};
struct _vcs_dpi_display_pipe_params_st {
struct _vcs_dpi_display_pipe_source_params_st src;
struct _vcs_dpi_display_pipe_dest_params_st dest;
struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth;
struct _vcs_dpi_scaler_taps_st scale_taps;
struct _vcs_dpi_display_pipe_dest_params_st {
unsigned int recout_width;
unsigned int recout_height;
unsigned int full_recout_width;
unsigned int full_recout_height;
unsigned int hblank_start;
unsigned int hblank_end;
unsigned int vblank_start;
unsigned int vblank_end;
unsigned int htotal;
unsigned int vtotal;
unsigned int vactive;
unsigned int hactive;
unsigned int vstartup_start;
unsigned int vupdate_offset;
unsigned int vupdate_width;
unsigned int vready_offset;
unsigned char interlaced;
unsigned char underscan;
double pixel_rate_mhz;
unsigned char synchronized_vblank_all_planes;
unsigned char otg_inst;
unsigned char odm_split_cnt;
unsigned char odm_combine;
};
struct _vcs_dpi_display_clocks_and_cfg_st {
int voltage;
double dppclk_mhz;
double refclk_mhz;
double dispclk_mhz;
double dcfclk_mhz;
double socclk_mhz;
struct _vcs_dpi_display_pipe_params_st {
display_pipe_source_params_st src;
display_pipe_dest_params_st dest;
scaler_ratio_depth_st scale_ratio_depth;
scaler_taps_st scale_taps;
};
struct _vcs_dpi_display_e2e_pipe_params_st {
struct _vcs_dpi_display_pipe_params_st pipe;
struct _vcs_dpi_display_output_params_st dout;
struct _vcs_dpi_display_clocks_and_cfg_st clks_cfg;
struct _vcs_dpi_display_clocks_and_cfg_st {
int voltage;
double dppclk_mhz;
double refclk_mhz;
double dispclk_mhz;
double dcfclk_mhz;
double socclk_mhz;
};
struct _vcs_dpi_dchub_buffer_sizing_st {
unsigned int swath_width_y;
unsigned int swath_height_y;
unsigned int swath_height_c;
unsigned int detail_buffer_size_y;
struct _vcs_dpi_display_e2e_pipe_params_st {
display_pipe_params_st pipe;
display_output_params_st dout;
display_clocks_and_cfg_st clks_cfg;
};
struct _vcs_dpi_watermarks_perf_st {
double stutter_eff_in_active_region_percent;
double urgent_latency_supported_us;
double non_urgent_latency_supported_us;
double dram_clock_change_margin_us;
double dram_access_eff_percent;
struct _vcs_dpi_dchub_buffer_sizing_st {
unsigned int swath_width_y;
unsigned int swath_height_y;
unsigned int swath_height_c;
unsigned int detail_buffer_size_y;
};
struct _vcs_dpi_cstate_pstate_watermarks_st {
double cstate_exit_us;
double cstate_enter_plus_exit_us;
double pstate_change_us;
struct _vcs_dpi_watermarks_perf_st {
double stutter_eff_in_active_region_percent;
double urgent_latency_supported_us;
double non_urgent_latency_supported_us;
double dram_clock_change_margin_us;
double dram_access_eff_percent;
};
struct _vcs_dpi_wm_calc_pipe_params_st {
unsigned int num_dpp;
int voltage;
int output_type;
double dcfclk_mhz;
double socclk_mhz;
double dppclk_mhz;
double pixclk_mhz;
unsigned char interlace_en;
unsigned char pte_enable;
unsigned char dcc_enable;
double dcc_rate;
double bytes_per_pixel_c;
double bytes_per_pixel_y;
unsigned int swath_width_y;
unsigned int swath_height_y;
unsigned int swath_height_c;
unsigned int det_buffer_size_y;
double h_ratio;
double v_ratio;
unsigned int h_taps;
unsigned int h_total;
unsigned int v_total;
unsigned int v_active;
unsigned int e2e_index;
double display_pipe_line_delivery_time;
double read_bw;
unsigned int lines_in_det_y;
unsigned int lines_in_det_y_rounded_down_to_swath;
double full_det_buffering_time;
double dcfclk_deepsleep_mhz_per_plane;
struct _vcs_dpi_cstate_pstate_watermarks_st {
double cstate_exit_us;
double cstate_enter_plus_exit_us;
double pstate_change_us;
};
struct _vcs_dpi_vratio_pre_st {
double vratio_pre_l;
double vratio_pre_c;
struct _vcs_dpi_wm_calc_pipe_params_st {
unsigned int num_dpp;
int voltage;
int output_type;
double dcfclk_mhz;
double socclk_mhz;
double dppclk_mhz;
double pixclk_mhz;
unsigned char interlace_en;
unsigned char pte_enable;
unsigned char dcc_enable;
double dcc_rate;
double bytes_per_pixel_c;
double bytes_per_pixel_y;
unsigned int swath_width_y;
unsigned int swath_height_y;
unsigned int swath_height_c;
unsigned int det_buffer_size_y;
double h_ratio;
double v_ratio;
unsigned int h_taps;
unsigned int h_total;
unsigned int v_total;
unsigned int v_active;
unsigned int e2e_index;
double display_pipe_line_delivery_time;
double read_bw;
unsigned int lines_in_det_y;
unsigned int lines_in_det_y_rounded_down_to_swath;
double full_det_buffering_time;
double dcfclk_deepsleep_mhz_per_plane;
};
struct _vcs_dpi_display_data_rq_misc_params_st {
unsigned int full_swath_bytes;
unsigned int stored_swath_bytes;
unsigned int blk256_height;
unsigned int blk256_width;
unsigned int req_height;
unsigned int req_width;
struct _vcs_dpi_vratio_pre_st {
double vratio_pre_l;
double vratio_pre_c;
};
struct _vcs_dpi_display_data_rq_sizing_params_st {
unsigned int chunk_bytes;
unsigned int min_chunk_bytes;
unsigned int meta_chunk_bytes;
unsigned int min_meta_chunk_bytes;
unsigned int mpte_group_bytes;
unsigned int dpte_group_bytes;
struct _vcs_dpi_display_data_rq_misc_params_st {
unsigned int full_swath_bytes;
unsigned int stored_swath_bytes;
unsigned int blk256_height;
unsigned int blk256_width;
unsigned int req_height;
unsigned int req_width;
};
struct _vcs_dpi_display_data_rq_dlg_params_st {
unsigned int swath_width_ub;
unsigned int swath_height;
unsigned int req_per_swath_ub;
unsigned int meta_pte_bytes_per_frame_ub;
unsigned int dpte_req_per_row_ub;
unsigned int dpte_groups_per_row_ub;
unsigned int dpte_row_height;
unsigned int dpte_bytes_per_row_ub;
unsigned int meta_chunks_per_row_ub;
unsigned int meta_req_per_row_ub;
unsigned int meta_row_height;
unsigned int meta_bytes_per_row_ub;
struct _vcs_dpi_display_data_rq_sizing_params_st {
unsigned int chunk_bytes;
unsigned int min_chunk_bytes;
unsigned int meta_chunk_bytes;
unsigned int min_meta_chunk_bytes;
unsigned int mpte_group_bytes;
unsigned int dpte_group_bytes;
};
struct _vcs_dpi_display_cur_rq_dlg_params_st {
unsigned char enable;
unsigned int swath_height;
unsigned int req_per_line;
struct _vcs_dpi_display_data_rq_dlg_params_st {
unsigned int swath_width_ub;
unsigned int swath_height;
unsigned int req_per_swath_ub;
unsigned int meta_pte_bytes_per_frame_ub;
unsigned int dpte_req_per_row_ub;
unsigned int dpte_groups_per_row_ub;
unsigned int dpte_row_height;
unsigned int dpte_bytes_per_row_ub;
unsigned int meta_chunks_per_row_ub;
unsigned int meta_req_per_row_ub;
unsigned int meta_row_height;
unsigned int meta_bytes_per_row_ub;
};
struct _vcs_dpi_display_rq_dlg_params_st {
struct _vcs_dpi_display_data_rq_dlg_params_st rq_l;
struct _vcs_dpi_display_data_rq_dlg_params_st rq_c;
struct _vcs_dpi_display_cur_rq_dlg_params_st rq_cur0;
struct _vcs_dpi_display_cur_rq_dlg_params_st {
unsigned char enable;
unsigned int swath_height;
unsigned int req_per_line;
};
struct _vcs_dpi_display_rq_sizing_params_st {
struct _vcs_dpi_display_data_rq_sizing_params_st rq_l;
struct _vcs_dpi_display_data_rq_sizing_params_st rq_c;
struct _vcs_dpi_display_rq_dlg_params_st {
display_data_rq_dlg_params_st rq_l;
display_data_rq_dlg_params_st rq_c;
display_cur_rq_dlg_params_st rq_cur0;
};
struct _vcs_dpi_display_rq_misc_params_st {
struct _vcs_dpi_display_data_rq_misc_params_st rq_l;
struct _vcs_dpi_display_data_rq_misc_params_st rq_c;
struct _vcs_dpi_display_rq_sizing_params_st {
display_data_rq_sizing_params_st rq_l;
display_data_rq_sizing_params_st rq_c;
};
struct _vcs_dpi_display_rq_params_st {
unsigned char yuv420;
unsigned char yuv420_10bpc;
struct _vcs_dpi_display_rq_misc_params_st misc;
struct _vcs_dpi_display_rq_sizing_params_st sizing;
struct _vcs_dpi_display_rq_dlg_params_st dlg;
struct _vcs_dpi_display_rq_misc_params_st {
display_data_rq_misc_params_st rq_l;
display_data_rq_misc_params_st rq_c;
};
struct _vcs_dpi_display_dlg_regs_st {
unsigned int refcyc_h_blank_end;
unsigned int dlg_vblank_end;
unsigned int min_dst_y_next_start;
unsigned int refcyc_per_htotal;
unsigned int refcyc_x_after_scaler;
unsigned int dst_y_after_scaler;
unsigned int dst_y_prefetch;
unsigned int dst_y_per_vm_vblank;
unsigned int dst_y_per_row_vblank;
unsigned int ref_freq_to_pix_freq;
unsigned int vratio_prefetch;
unsigned int vratio_prefetch_c;
unsigned int refcyc_per_pte_group_vblank_l;
unsigned int refcyc_per_pte_group_vblank_c;
unsigned int refcyc_per_meta_chunk_vblank_l;
unsigned int refcyc_per_meta_chunk_vblank_c;
unsigned int dst_y_per_pte_row_nom_l;
unsigned int dst_y_per_pte_row_nom_c;
unsigned int refcyc_per_pte_group_nom_l;
unsigned int refcyc_per_pte_group_nom_c;
unsigned int dst_y_per_meta_row_nom_l;
unsigned int dst_y_per_meta_row_nom_c;
unsigned int refcyc_per_meta_chunk_nom_l;
unsigned int refcyc_per_meta_chunk_nom_c;
unsigned int refcyc_per_line_delivery_pre_l;
unsigned int refcyc_per_line_delivery_pre_c;
unsigned int refcyc_per_line_delivery_l;
unsigned int refcyc_per_line_delivery_c;
unsigned int chunk_hdl_adjust_cur0;
struct _vcs_dpi_display_rq_params_st {
unsigned char yuv420;
unsigned char yuv420_10bpc;
display_rq_misc_params_st misc;
display_rq_sizing_params_st sizing;
display_rq_dlg_params_st dlg;
};
struct _vcs_dpi_display_ttu_regs_st {
unsigned int qos_level_low_wm;
unsigned int qos_level_high_wm;
unsigned int min_ttu_vblank;
unsigned int qos_level_flip;
unsigned int refcyc_per_req_delivery_l;
unsigned int refcyc_per_req_delivery_c;
unsigned int refcyc_per_req_delivery_cur0;
unsigned int refcyc_per_req_delivery_pre_l;
unsigned int refcyc_per_req_delivery_pre_c;
unsigned int refcyc_per_req_delivery_pre_cur0;
unsigned int qos_level_fixed_l;
unsigned int qos_level_fixed_c;
unsigned int qos_level_fixed_cur0;
unsigned int qos_ramp_disable_l;
unsigned int qos_ramp_disable_c;
unsigned int qos_ramp_disable_cur0;
struct _vcs_dpi_display_dlg_regs_st {
unsigned int refcyc_h_blank_end;
unsigned int dlg_vblank_end;
unsigned int min_dst_y_next_start;
unsigned int refcyc_per_htotal;
unsigned int refcyc_x_after_scaler;
unsigned int dst_y_after_scaler;
unsigned int dst_y_prefetch;
unsigned int dst_y_per_vm_vblank;
unsigned int dst_y_per_row_vblank;
unsigned int dst_y_per_vm_flip;
unsigned int dst_y_per_row_flip;
unsigned int ref_freq_to_pix_freq;
unsigned int vratio_prefetch;
unsigned int vratio_prefetch_c;
unsigned int refcyc_per_pte_group_vblank_l;
unsigned int refcyc_per_pte_group_vblank_c;
unsigned int refcyc_per_meta_chunk_vblank_l;
unsigned int refcyc_per_meta_chunk_vblank_c;
unsigned int refcyc_per_pte_group_flip_l;
unsigned int refcyc_per_pte_group_flip_c;
unsigned int refcyc_per_meta_chunk_flip_l;
unsigned int refcyc_per_meta_chunk_flip_c;
unsigned int dst_y_per_pte_row_nom_l;
unsigned int dst_y_per_pte_row_nom_c;
unsigned int refcyc_per_pte_group_nom_l;
unsigned int refcyc_per_pte_group_nom_c;
unsigned int dst_y_per_meta_row_nom_l;
unsigned int dst_y_per_meta_row_nom_c;
unsigned int refcyc_per_meta_chunk_nom_l;
unsigned int refcyc_per_meta_chunk_nom_c;
unsigned int refcyc_per_line_delivery_pre_l;
unsigned int refcyc_per_line_delivery_pre_c;
unsigned int refcyc_per_line_delivery_l;
unsigned int refcyc_per_line_delivery_c;
unsigned int chunk_hdl_adjust_cur0;
unsigned int chunk_hdl_adjust_cur1;
unsigned int vready_after_vcount0;
unsigned int dst_y_offset_cur0;
unsigned int dst_y_offset_cur1;
unsigned int xfc_reg_transfer_delay;
unsigned int xfc_reg_precharge_delay;
unsigned int xfc_reg_remote_surface_flip_latency;
unsigned int xfc_reg_prefetch_margin;
unsigned int dst_y_delta_drq_limit;
};
struct _vcs_dpi_display_data_rq_regs_st {
unsigned int chunk_size;
unsigned int min_chunk_size;
unsigned int meta_chunk_size;
unsigned int min_meta_chunk_size;
unsigned int dpte_group_size;
unsigned int mpte_group_size;
unsigned int swath_height;
unsigned int pte_row_height_linear;
struct _vcs_dpi_display_ttu_regs_st {
unsigned int qos_level_low_wm;
unsigned int qos_level_high_wm;
unsigned int min_ttu_vblank;
unsigned int qos_level_flip;
unsigned int refcyc_per_req_delivery_l;
unsigned int refcyc_per_req_delivery_c;
unsigned int refcyc_per_req_delivery_cur0;
unsigned int refcyc_per_req_delivery_cur1;
unsigned int refcyc_per_req_delivery_pre_l;
unsigned int refcyc_per_req_delivery_pre_c;
unsigned int refcyc_per_req_delivery_pre_cur0;
unsigned int refcyc_per_req_delivery_pre_cur1;
unsigned int qos_level_fixed_l;
unsigned int qos_level_fixed_c;
unsigned int qos_level_fixed_cur0;
unsigned int qos_level_fixed_cur1;
unsigned int qos_ramp_disable_l;
unsigned int qos_ramp_disable_c;
unsigned int qos_ramp_disable_cur0;
unsigned int qos_ramp_disable_cur1;
};
struct _vcs_dpi_display_rq_regs_st {
struct _vcs_dpi_display_data_rq_regs_st rq_regs_l;
struct _vcs_dpi_display_data_rq_regs_st rq_regs_c;
unsigned int drq_expansion_mode;
unsigned int prq_expansion_mode;
unsigned int mrq_expansion_mode;
unsigned int crq_expansion_mode;
unsigned int plane1_base_address;
struct _vcs_dpi_display_data_rq_regs_st {
unsigned int chunk_size;
unsigned int min_chunk_size;
unsigned int meta_chunk_size;
unsigned int min_meta_chunk_size;
unsigned int dpte_group_size;
unsigned int mpte_group_size;
unsigned int swath_height;
unsigned int pte_row_height_linear;
};
struct _vcs_dpi_display_dlg_sys_params_st {
double t_mclk_wm_us;
double t_urg_wm_us;
double t_sr_wm_us;
double t_extra_us;
double t_srx_delay_us;
double deepsleep_dcfclk_mhz;
double total_flip_bw;
unsigned int total_flip_bytes;
struct _vcs_dpi_display_rq_regs_st {
display_data_rq_regs_st rq_regs_l;
display_data_rq_regs_st rq_regs_c;
unsigned int drq_expansion_mode;
unsigned int prq_expansion_mode;
unsigned int mrq_expansion_mode;
unsigned int crq_expansion_mode;
unsigned int plane1_base_address;
};
struct _vcs_dpi_display_dlg_prefetch_param_st {
double prefetch_bw;
unsigned int flip_bytes;
struct _vcs_dpi_display_dlg_sys_params_st {
double t_mclk_wm_us;
double t_urg_wm_us;
double t_sr_wm_us;
double t_extra_us;
double mem_trip_us;
double t_srx_delay_us;
double deepsleep_dcfclk_mhz;
double total_flip_bw;
unsigned int total_flip_bytes;
};
struct _vcs_dpi_display_pipe_clock_st {
double dcfclk_mhz;
double dispclk_mhz;
double dppclk_mhz[4];
unsigned char dppclk_div[4];
struct _vcs_dpi_display_dlg_prefetch_param_st {
double prefetch_bw;
unsigned int flip_bytes;
};
struct _vcs_dpi_display_arb_params_st {
int max_req_outstanding;
int min_req_outstanding;
int sat_level_us;
struct _vcs_dpi_display_pipe_clock_st {
double dcfclk_mhz;
double dispclk_mhz;
double socclk_mhz;
double dscclk_mhz[6];
double dppclk_mhz[6];
};
struct _vcs_dpi_mode_evaluation_st {
int voltage_override;
struct _vcs_dpi_display_arb_params_st {
int max_req_outstanding;
int min_req_outstanding;
int sat_level_us;
};
#endif /*__DISPLAY_MODE_STRUCTS_H__*/

View File

@ -1,194 +0,0 @@
/*
* Copyright 2017 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __DISPLAY_MODE_SUPPORT_H__
#define __DISPLAY_MODE_SUPPORT_H__
#include "dml_common_defs.h"
struct display_mode_lib;
#define NumberOfStates 4
#define NumberOfStatesPlusTwo (NumberOfStates+2)
struct dml_ms_internal_vars {
double ScaleRatioSupport;
double SourceFormatPixelAndScanSupport;
double TotalReadBandwidthConsumedGBytePerSecond;
double TotalWriteBandwidthConsumedGBytePerSecond;
double TotalBandwidthConsumedGBytePerSecond;
double DCCEnabledInAnyPlane;
double ReturnBWToDCNPerState;
double CriticalPoint;
double WritebackLatencySupport;
double RequiredOutputBW;
double TotalNumberOfActiveWriteback;
double TotalAvailableWritebackSupport;
double MaximumSwathWidth;
double NumberOfDPPRequiredForDETSize;
double NumberOfDPPRequiredForLBSize;
double MinDispclkUsingSingleDPP;
double MinDispclkUsingDualDPP;
double ViewportSizeSupport;
double SwathWidthGranularityY;
double RoundedUpMaxSwathSizeBytesY;
double SwathWidthGranularityC;
double RoundedUpMaxSwathSizeBytesC;
double LinesInDETLuma;
double LinesInDETChroma;
double EffectiveLBLatencyHidingSourceLinesLuma;
double EffectiveLBLatencyHidingSourceLinesChroma;
double EffectiveDETLBLinesLuma;
double EffectiveDETLBLinesChroma;
double ProjectedDCFCLKDeepSleep;
double MetaReqHeightY;
double MetaReqWidthY;
double MetaSurfaceWidthY;
double MetaSurfaceHeightY;
double MetaPteBytesPerFrameY;
double MetaRowBytesY;
double MacroTileBlockSizeBytesY;
double MacroTileBlockHeightY;
double DataPTEReqHeightY;
double DataPTEReqWidthY;
double DPTEBytesPerRowY;
double MetaReqHeightC;
double MetaReqWidthC;
double MetaSurfaceWidthC;
double MetaSurfaceHeightC;
double MetaPteBytesPerFrameC;
double MetaRowBytesC;
double MacroTileBlockSizeBytesC;
double MacroTileBlockHeightC;
double MacroTileBlockWidthC;
double DataPTEReqHeightC;
double DataPTEReqWidthC;
double DPTEBytesPerRowC;
double VInitY;
double MaxPartialSwY;
double VInitC;
double MaxPartialSwC;
double dst_x_after_scaler;
double dst_y_after_scaler;
double TimeCalc;
double VUpdateOffset;
double TotalRepeaterDelay;
double VUpdateWidth;
double VReadyOffset;
double TimeSetup;
double ExtraLatency;
double MaximumVStartup;
double BWAvailableForImmediateFlip;
double TotalImmediateFlipBytes;
double TimeForMetaPTEWithImmediateFlip;
double TimeForMetaPTEWithoutImmediateFlip;
double TimeForMetaAndDPTERowWithImmediateFlip;
double TimeForMetaAndDPTERowWithoutImmediateFlip;
double LineTimesToRequestPrefetchPixelDataWithImmediateFlip;
double LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip;
double MaximumReadBandwidthWithPrefetchWithImmediateFlip;
double MaximumReadBandwidthWithPrefetchWithoutImmediateFlip;
double VoltageOverrideLevel;
double VoltageLevelWithImmediateFlip;
double VoltageLevelWithoutImmediateFlip;
double ImmediateFlipSupported;
double VoltageLevel;
double DCFCLK;
double FabricAndDRAMBandwidth;
double SwathWidthYSingleDPP[DC__NUM_PIPES__MAX];
double BytePerPixelInDETY[DC__NUM_PIPES__MAX];
double BytePerPixelInDETC[DC__NUM_PIPES__MAX];
double ReadBandwidth[DC__NUM_PIPES__MAX];
double WriteBandwidth[DC__NUM_PIPES__MAX];
double DCFCLKPerState[NumberOfStatesPlusTwo];
double FabricAndDRAMBandwidthPerState[NumberOfStatesPlusTwo];
double ReturnBWPerState[NumberOfStatesPlusTwo];
double BandwidthSupport[NumberOfStatesPlusTwo];
double UrgentRoundTripAndOutOfOrderLatencyPerState[NumberOfStatesPlusTwo];
double ROBSupport[NumberOfStatesPlusTwo];
double RequiredPHYCLK[DC__NUM_PIPES__MAX];
double DIOSupport[NumberOfStatesPlusTwo];
double PHYCLKPerState[NumberOfStatesPlusTwo];
double PSCL_FACTOR[DC__NUM_PIPES__MAX];
double PSCL_FACTOR_CHROMA[DC__NUM_PIPES__MAX];
double MinDPPCLKUsingSingleDPP[DC__NUM_PIPES__MAX];
double Read256BlockHeightY[DC__NUM_PIPES__MAX];
double Read256BlockWidthY[DC__NUM_PIPES__MAX];
double Read256BlockHeightC[DC__NUM_PIPES__MAX];
double Read256BlockWidthC[DC__NUM_PIPES__MAX];
double MaxSwathHeightY[DC__NUM_PIPES__MAX];
double MaxSwathHeightC[DC__NUM_PIPES__MAX];
double MinSwathHeightY[DC__NUM_PIPES__MAX];
double MinSwathHeightC[DC__NUM_PIPES__MAX];
double NumberOfDPPRequiredForDETAndLBSize[DC__NUM_PIPES__MAX];
double TotalNumberOfActiveDPP[NumberOfStatesPlusTwo * 2];
double RequiredDISPCLK[NumberOfStatesPlusTwo * 2];
double DISPCLK_DPPCLK_Support[NumberOfStatesPlusTwo * 2];
double MaxDispclk[NumberOfStatesPlusTwo];
double MaxDppclk[NumberOfStatesPlusTwo];
double NoOfDPP[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
double TotalAvailablePipesSupport[NumberOfStatesPlusTwo * 2];
double SwathWidthYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
double SwathHeightYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
double SwathHeightCPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
double DETBufferSizeYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
double UrgentLatencySupportUsPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
double UrgentLatencySupport[NumberOfStatesPlusTwo * 2];
double TotalNumberOfDCCActiveDPP[NumberOfStatesPlusTwo * 2];
double DPTEBytesPerRow[DC__NUM_PIPES__MAX];
double MetaPTEBytesPerFrame[DC__NUM_PIPES__MAX];
double MetaRowBytes[DC__NUM_PIPES__MAX];
double PrefillY[DC__NUM_PIPES__MAX];
double MaxNumSwY[DC__NUM_PIPES__MAX];
double PrefetchLinesY[DC__NUM_PIPES__MAX];
double PrefillC[DC__NUM_PIPES__MAX];
double MaxNumSwC[DC__NUM_PIPES__MAX];
double PrefetchLinesC[DC__NUM_PIPES__MAX];
double LineTimesForPrefetch[DC__NUM_PIPES__MAX];
double PrefetchBW[DC__NUM_PIPES__MAX];
double LinesForMetaPTEWithImmediateFlip[DC__NUM_PIPES__MAX];
double LinesForMetaPTEWithoutImmediateFlip[DC__NUM_PIPES__MAX];
double LinesForMetaAndDPTERowWithImmediateFlip[DC__NUM_PIPES__MAX];
double LinesForMetaAndDPTERowWithoutImmediateFlip[DC__NUM_PIPES__MAX];
double VRatioPreYWithImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
double VRatioPreCWithImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
double RequiredPrefetchPixelDataBWWithImmediateFlip[NumberOfStatesPlusTwo * 2
* DC__NUM_PIPES__MAX];
double VRatioPreYWithoutImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
double VRatioPreCWithoutImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
double RequiredPrefetchPixelDataBWWithoutImmediateFlip[NumberOfStatesPlusTwo * 2
* DC__NUM_PIPES__MAX];
double PrefetchSupportedWithImmediateFlip[NumberOfStatesPlusTwo * 2];
double PrefetchSupportedWithoutImmediateFlip[NumberOfStatesPlusTwo * 2];
double VRatioInPrefetchSupportedWithImmediateFlip[NumberOfStatesPlusTwo * 2];
double VRatioInPrefetchSupportedWithoutImmediateFlip[NumberOfStatesPlusTwo * 2];
double ModeSupportWithImmediateFlip[NumberOfStatesPlusTwo * 2];
double ModeSupportWithoutImmediateFlip[NumberOfStatesPlusTwo * 2];
double RequiredDISPCLKPerRatio[2];
double DPPPerPlanePerRatio[2 * DC__NUM_PIPES__MAX];
double DISPCLK_DPPCLK_SupportPerRatio[2];
struct _vcs_dpi_wm_calc_pipe_params_st planes[DC__NUM_PIPES__MAX];
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,598 @@
/*
* Copyright 2017 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __DML2_DISPLAY_MODE_VBA_H__
#define __DML2_DISPLAY_MODE_VBA_H__
#include "dml_common_defs.h"
struct display_mode_lib;
void set_prefetch_mode(struct display_mode_lib *mode_lib,
bool cstate_en,
bool pstate_en,
bool ignore_viewport_pos,
bool immediate_flip_support);
#define dml_get_attr_decl(attr) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes)
dml_get_attr_decl(clk_dcf_deepsleep);
dml_get_attr_decl(wm_urgent);
dml_get_attr_decl(wm_memory_trip);
dml_get_attr_decl(wm_writeback_urgent);
dml_get_attr_decl(wm_stutter_exit);
dml_get_attr_decl(wm_stutter_enter_exit);
dml_get_attr_decl(wm_dram_clock_change);
dml_get_attr_decl(wm_writeback_dram_clock_change);
dml_get_attr_decl(wm_xfc_underflow);
dml_get_attr_decl(stutter_efficiency_no_vblank);
dml_get_attr_decl(stutter_efficiency);
dml_get_attr_decl(urgent_latency);
dml_get_attr_decl(urgent_extra_latency);
dml_get_attr_decl(nonurgent_latency);
dml_get_attr_decl(dram_clock_change_latency);
dml_get_attr_decl(dispclk_calculated);
dml_get_attr_decl(total_data_read_bw);
dml_get_attr_decl(return_bw);
dml_get_attr_decl(tcalc);
#define dml_get_pipe_attr_decl(attr) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes, unsigned int which_pipe)
dml_get_pipe_attr_decl(dsc_delay);
dml_get_pipe_attr_decl(dppclk_calculated);
dml_get_pipe_attr_decl(dscclk_calculated);
dml_get_pipe_attr_decl(min_ttu_vblank);
dml_get_pipe_attr_decl(vratio_prefetch_l);
dml_get_pipe_attr_decl(vratio_prefetch_c);
dml_get_pipe_attr_decl(dst_x_after_scaler);
dml_get_pipe_attr_decl(dst_y_after_scaler);
dml_get_pipe_attr_decl(dst_y_per_vm_vblank);
dml_get_pipe_attr_decl(dst_y_per_row_vblank);
dml_get_pipe_attr_decl(dst_y_prefetch);
dml_get_pipe_attr_decl(dst_y_per_vm_flip);
dml_get_pipe_attr_decl(dst_y_per_row_flip);
dml_get_pipe_attr_decl(xfc_transfer_delay);
dml_get_pipe_attr_decl(xfc_precharge_delay);
dml_get_pipe_attr_decl(xfc_remote_surface_flip_latency);
dml_get_pipe_attr_decl(xfc_prefetch_margin);
unsigned int get_vstartup_calculated(
struct display_mode_lib *mode_lib,
const display_e2e_pipe_params_st *pipes,
unsigned int num_pipes,
unsigned int which_pipe);
double get_total_immediate_flip_bytes(
struct display_mode_lib *mode_lib,
const display_e2e_pipe_params_st *pipes,
unsigned int num_pipes);
double get_total_immediate_flip_bw(
struct display_mode_lib *mode_lib,
const display_e2e_pipe_params_st *pipes,
unsigned int num_pipes);
double get_total_prefetch_bw(
struct display_mode_lib *mode_lib,
const display_e2e_pipe_params_st *pipes,
unsigned int num_pipes);
unsigned int dml_get_voltage_level(
struct display_mode_lib *mode_lib,
const display_e2e_pipe_params_st *pipes,
unsigned int num_pipes);
bool Calculate256BBlockSizes(
enum source_format_class SourcePixelFormat,
enum dm_swizzle_mode SurfaceTiling,
unsigned int BytePerPixelY,
unsigned int BytePerPixelC,
unsigned int *BlockHeight256BytesY,
unsigned int *BlockHeight256BytesC,
unsigned int *BlockWidth256BytesY,
unsigned int *BlockWidth256BytesC);
struct vba_vars_st {
ip_params_st ip;
soc_bounding_box_st soc;
unsigned int MaximumMaxVStartupLines;
double cursor_bw[DC__NUM_DPP__MAX];
double meta_row_bw[DC__NUM_DPP__MAX];
double dpte_row_bw[DC__NUM_DPP__MAX];
double qual_row_bw[DC__NUM_DPP__MAX];
double WritebackDISPCLK;
double PSCL_THROUGHPUT_LUMA[DC__NUM_DPP__MAX];
double PSCL_THROUGHPUT_CHROMA[DC__NUM_DPP__MAX];
double DPPCLKUsingSingleDPPLuma;
double DPPCLKUsingSingleDPPChroma;
double DPPCLKUsingSingleDPP[DC__NUM_DPP__MAX];
double DISPCLKWithRamping;
double DISPCLKWithoutRamping;
double GlobalDPPCLK;
double DISPCLKWithRampingRoundedToDFSGranularity;
double DISPCLKWithoutRampingRoundedToDFSGranularity;
double MaxDispclkRoundedToDFSGranularity;
bool DCCEnabledAnyPlane;
double ReturnBandwidthToDCN;
unsigned int SwathWidthY[DC__NUM_DPP__MAX];
unsigned int SwathWidthSingleDPPY[DC__NUM_DPP__MAX];
double BytePerPixelDETY[DC__NUM_DPP__MAX];
double BytePerPixelDETC[DC__NUM_DPP__MAX];
double ReadBandwidthPlaneLuma[DC__NUM_DPP__MAX];
double ReadBandwidthPlaneChroma[DC__NUM_DPP__MAX];
unsigned int TotalActiveDPP;
unsigned int TotalDCCActiveDPP;
double UrgentRoundTripAndOutOfOrderLatency;
double DisplayPipeLineDeliveryTimeLuma[DC__NUM_DPP__MAX]; // WM
double DisplayPipeLineDeliveryTimeChroma[DC__NUM_DPP__MAX]; // WM
double LinesInDETY[DC__NUM_DPP__MAX]; // WM
double LinesInDETC[DC__NUM_DPP__MAX]; // WM
unsigned int LinesInDETYRoundedDownToSwath[DC__NUM_DPP__MAX]; // WM
unsigned int LinesInDETCRoundedDownToSwath[DC__NUM_DPP__MAX]; // WM
double FullDETBufferingTimeY[DC__NUM_DPP__MAX]; // WM
double FullDETBufferingTimeC[DC__NUM_DPP__MAX]; // WM
double MinFullDETBufferingTime;
double FrameTimeForMinFullDETBufferingTime;
double AverageReadBandwidthGBytePerSecond;
double PartOfBurstThatFitsInROB;
double StutterBurstTime;
//unsigned int NextPrefetchMode;
double VBlankTime;
double SmallestVBlank;
double DCFCLKDeepSleepPerPlane;
double EffectiveDETPlusLBLinesLuma;
double EffectiveDETPlusLBLinesChroma;
double UrgentLatencySupportUsLuma;
double UrgentLatencySupportUsChroma;
double UrgentLatencySupportUs[DC__NUM_DPP__MAX];
unsigned int DSCFormatFactor;
unsigned int BlockHeight256BytesY[DC__NUM_DPP__MAX];
unsigned int BlockHeight256BytesC[DC__NUM_DPP__MAX];
unsigned int BlockWidth256BytesY[DC__NUM_DPP__MAX];
unsigned int BlockWidth256BytesC[DC__NUM_DPP__MAX];
double VInitPreFillY[DC__NUM_DPP__MAX];
double VInitPreFillC[DC__NUM_DPP__MAX];
unsigned int MaxNumSwathY[DC__NUM_DPP__MAX];
unsigned int MaxNumSwathC[DC__NUM_DPP__MAX];
double PrefetchSourceLinesY[DC__NUM_DPP__MAX];
double PrefetchSourceLinesC[DC__NUM_DPP__MAX];
double PixelPTEBytesPerRow[DC__NUM_DPP__MAX];
double MetaRowByte[DC__NUM_DPP__MAX];
unsigned int dpte_row_height[DC__NUM_DPP__MAX];
unsigned int dpte_row_height_chroma[DC__NUM_DPP__MAX];
unsigned int meta_row_height[DC__NUM_DPP__MAX];
unsigned int meta_row_height_chroma[DC__NUM_DPP__MAX];
unsigned int MacroTileWidthY[DC__NUM_DPP__MAX];
unsigned int MacroTileWidthC[DC__NUM_DPP__MAX];
unsigned int MaxVStartupLines[DC__NUM_DPP__MAX];
double WritebackDelay[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
bool PrefetchModeSupported;
bool AllowDRAMClockChangeDuringVBlank[DC__NUM_DPP__MAX];
bool AllowDRAMSelfRefreshDuringVBlank[DC__NUM_DPP__MAX];
double RequiredPrefetchPixDataBW[DC__NUM_DPP__MAX];
double XFCRemoteSurfaceFlipDelay;
double TInitXFill;
double TslvChk;
double SrcActiveDrainRate;
double Tno_bw[DC__NUM_DPP__MAX];
bool ImmediateFlipSupported;
double prefetch_vm_bw[DC__NUM_DPP__MAX];
double prefetch_row_bw[DC__NUM_DPP__MAX];
bool ImmediateFlipSupportedForPipe[DC__NUM_DPP__MAX];
unsigned int VStartupLines;
double DisplayPipeLineDeliveryTimeLumaPrefetch[DC__NUM_DPP__MAX];
double DisplayPipeLineDeliveryTimeChromaPrefetch[DC__NUM_DPP__MAX];
unsigned int ActiveDPPs;
unsigned int LBLatencyHidingSourceLinesY;
unsigned int LBLatencyHidingSourceLinesC;
double ActiveDRAMClockChangeLatencyMargin[DC__NUM_DPP__MAX];
double MinActiveDRAMClockChangeMargin;
double XFCSlaveVUpdateOffset[DC__NUM_DPP__MAX];
double XFCSlaveVupdateWidth[DC__NUM_DPP__MAX];
double XFCSlaveVReadyOffset[DC__NUM_DPP__MAX];
double InitFillLevel;
double FinalFillMargin;
double FinalFillLevel;
double RemainingFillLevel;
double TFinalxFill;
//
// SOC Bounding Box Parameters
//
double SRExitTime;
double SREnterPlusExitTime;
double UrgentLatency;
double WritebackLatency;
double PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency;
double NumberOfChannels;
double DRAMChannelWidth;
double FabricDatapathToDCNDataReturn;
double ReturnBusWidth;
double Downspreading;
double DISPCLKDPPCLKDSCCLKDownSpreading;
double DISPCLKDPPCLKVCOSpeed;
double RoundTripPingLatencyCycles;
double UrgentOutOfOrderReturnPerChannel;
unsigned int VMMPageSize;
double DRAMClockChangeLatency;
double XFCBusTransportTime;
double XFCXBUFLatencyTolerance;
//
// IP Parameters
//
unsigned int ROBBufferSizeInKByte;
double DETBufferSizeInKByte;
unsigned int DPPOutputBufferPixels;
unsigned int OPPOutputBufferLines;
unsigned int PixelChunkSizeInKByte;
double ReturnBW;
bool VirtualMemoryEnable;
unsigned int MaxPageTableLevels;
unsigned int OverridePageTableLevels;
unsigned int PTEChunkSize;
unsigned int MetaChunkSize;
unsigned int WritebackChunkSize;
bool ODMCapability;
unsigned int NumberOfDSC;
unsigned int LineBufferSize;
unsigned int MaxLineBufferLines;
unsigned int WritebackInterfaceLumaBufferSize;
unsigned int WritebackInterfaceChromaBufferSize;
unsigned int WritebackChromaLineBufferWidth;
double MaxDCHUBToPSCLThroughput;
double MaxPSCLToLBThroughput;
unsigned int PTEBufferSizeInRequests;
double DISPCLKRampingMargin;
unsigned int MaxInterDCNTileRepeaters;
bool XFCSupported;
double XFCSlvChunkSize;
double XFCFillBWOverhead;
double XFCFillConstant;
double XFCTSlvVupdateOffset;
double XFCTSlvVupdateWidth;
double XFCTSlvVreadyOffset;
double DPPCLKDelaySubtotal;
double DPPCLKDelaySCL;
double DPPCLKDelaySCLLBOnly;
double DPPCLKDelayCNVCFormater;
double DPPCLKDelayCNVCCursor;
double DISPCLKDelaySubtotal;
bool ProgressiveToInterlaceUnitInOPP;
unsigned int PDEProcessingBufIn64KBReqs;
// Pipe/Plane Parameters
int VoltageLevel;
double FabricAndDRAMBandwidth;
double FabricClock;
double DRAMSpeed;
double DISPCLK;
double SOCCLK;
double DCFCLK;
unsigned int NumberOfActivePlanes;
unsigned int ViewportWidth[DC__NUM_DPP__MAX];
unsigned int ViewportHeight[DC__NUM_DPP__MAX];
unsigned int ViewportYStartY[DC__NUM_DPP__MAX];
unsigned int ViewportYStartC[DC__NUM_DPP__MAX];
unsigned int PitchY[DC__NUM_DPP__MAX];
unsigned int PitchC[DC__NUM_DPP__MAX];
double HRatio[DC__NUM_DPP__MAX];
double VRatio[DC__NUM_DPP__MAX];
unsigned int htaps[DC__NUM_DPP__MAX];
unsigned int vtaps[DC__NUM_DPP__MAX];
unsigned int HTAPsChroma[DC__NUM_DPP__MAX];
unsigned int VTAPsChroma[DC__NUM_DPP__MAX];
unsigned int HTotal[DC__NUM_DPP__MAX];
unsigned int VTotal[DC__NUM_DPP__MAX];
unsigned int DPPPerPlane[DC__NUM_DPP__MAX];
double PixelClock[DC__NUM_DPP__MAX];
double PixelClockBackEnd[DC__NUM_DPP__MAX];
double DPPCLK[DC__NUM_DPP__MAX];
bool DCCEnable[DC__NUM_DPP__MAX];
unsigned int DCCMetaPitchY[DC__NUM_DPP__MAX];
enum scan_direction_class SourceScan[DC__NUM_DPP__MAX];
enum source_format_class SourcePixelFormat[DC__NUM_DPP__MAX];
bool WritebackEnable[DC__NUM_DPP__MAX];
double WritebackDestinationWidth[DC__NUM_DPP__MAX];
double WritebackDestinationHeight[DC__NUM_DPP__MAX];
double WritebackSourceHeight[DC__NUM_DPP__MAX];
enum source_format_class WritebackPixelFormat[DC__NUM_DPP__MAX];
unsigned int WritebackLumaHTaps[DC__NUM_DPP__MAX];
unsigned int WritebackLumaVTaps[DC__NUM_DPP__MAX];
unsigned int WritebackChromaHTaps[DC__NUM_DPP__MAX];
unsigned int WritebackChromaVTaps[DC__NUM_DPP__MAX];
double WritebackHRatio[DC__NUM_DPP__MAX];
double WritebackVRatio[DC__NUM_DPP__MAX];
unsigned int HActive[DC__NUM_DPP__MAX];
unsigned int VActive[DC__NUM_DPP__MAX];
bool Interlace[DC__NUM_DPP__MAX];
enum dm_swizzle_mode SurfaceTiling[DC__NUM_DPP__MAX];
unsigned int ScalerRecoutWidth[DC__NUM_DPP__MAX];
bool DynamicMetadataEnable[DC__NUM_DPP__MAX];
unsigned int DynamicMetadataLinesBeforeActiveRequired[DC__NUM_DPP__MAX];
unsigned int DynamicMetadataTransmittedBytes[DC__NUM_DPP__MAX];
double DCCRate[DC__NUM_DPP__MAX];
bool ODMCombineEnabled[DC__NUM_DPP__MAX];
double OutputBpp[DC__NUM_DPP__MAX];
unsigned int NumberOfDSCSlices[DC__NUM_DPP__MAX];
bool DSCEnabled[DC__NUM_DPP__MAX];
unsigned int DSCDelay[DC__NUM_DPP__MAX];
unsigned int DSCInputBitPerComponent[DC__NUM_DPP__MAX];
enum output_format_class OutputFormat[DC__NUM_DPP__MAX];
enum output_encoder_class Output[DC__NUM_DPP__MAX];
unsigned int BlendingAndTiming[DC__NUM_DPP__MAX];
bool SynchronizedVBlank;
unsigned int NumberOfCursors[DC__NUM_DPP__MAX];
unsigned int CursorWidth[DC__NUM_DPP__MAX][DC__NUM_CURSOR__MAX];
unsigned int CursorBPP[DC__NUM_DPP__MAX][DC__NUM_CURSOR__MAX];
bool XFCEnabled[DC__NUM_DPP__MAX];
bool ScalerEnabled[DC__NUM_DPP__MAX];
// Intermediates/Informational
bool ImmediateFlipSupport;
unsigned int SwathHeightY[DC__NUM_DPP__MAX];
unsigned int SwathHeightC[DC__NUM_DPP__MAX];
unsigned int DETBufferSizeY[DC__NUM_DPP__MAX];
unsigned int DETBufferSizeC[DC__NUM_DPP__MAX];
unsigned int LBBitPerPixel[DC__NUM_DPP__MAX];
double LastPixelOfLineExtraWatermark;
double TotalDataReadBandwidth;
unsigned int TotalActiveWriteback;
unsigned int EffectiveLBLatencyHidingSourceLinesLuma;
unsigned int EffectiveLBLatencyHidingSourceLinesChroma;
double BandwidthAvailableForImmediateFlip;
unsigned int PrefetchMode;
bool IgnoreViewportPositioning;
double PrefetchBandwidth[DC__NUM_DPP__MAX];
bool ErrorResult[DC__NUM_DPP__MAX];
double PDEAndMetaPTEBytesFrame[DC__NUM_DPP__MAX];
//
// Calculated dml_ml->vba.Outputs
//
double DCFClkDeepSleep;
double UrgentWatermark;
double UrgentExtraLatency;
double MemoryTripWatermark;
double WritebackUrgentWatermark;
double StutterExitWatermark;
double StutterEnterPlusExitWatermark;
double DRAMClockChangeWatermark;
double WritebackDRAMClockChangeWatermark;
double StutterEfficiency;
double StutterEfficiencyNotIncludingVBlank;
double MinUrgentLatencySupportUs;
double NonUrgentLatencyTolerance;
double MinActiveDRAMClockChangeLatencySupported;
enum clock_change_support DRAMClockChangeSupport;
// These are the clocks calcuated by the library but they are not actually
// used explicitly. They are fetched by tests and then possibly used. The
// ultimate values to use are the ones specified by the parameters to DML
double DISPCLK_calculated;
double DSCCLK_calculated[DC__NUM_DPP__MAX];
double DPPCLK_calculated[DC__NUM_DPP__MAX];
unsigned int VStartup[DC__NUM_DPP__MAX];
unsigned int VUpdateOffsetPix[DC__NUM_DPP__MAX];
unsigned int VUpdateWidthPix[DC__NUM_DPP__MAX];
unsigned int VReadyOffsetPix[DC__NUM_DPP__MAX];
unsigned int VStartupRequiredWhenNotEnoughTimeForDynamicMetadata;
double ImmediateFlipBW;
unsigned int TotImmediateFlipBytes;
double TCalc;
double MinTTUVBlank[DC__NUM_DPP__MAX];
double VRatioPrefetchY[DC__NUM_DPP__MAX];
double VRatioPrefetchC[DC__NUM_DPP__MAX];
double DSTXAfterScaler[DC__NUM_DPP__MAX];
double DSTYAfterScaler[DC__NUM_DPP__MAX];
double DestinationLinesToRequestVMInVBlank[DC__NUM_DPP__MAX];
double DestinationLinesToRequestRowInVBlank[DC__NUM_DPP__MAX];
double DestinationLinesForPrefetch[DC__NUM_DPP__MAX];
double DestinationLinesToRequestRowInImmediateFlip[DC__NUM_DPP__MAX];
double DestinationLinesToRequestVMInImmediateFlip[DC__NUM_DPP__MAX];
double XFCTransferDelay[DC__NUM_DPP__MAX];
double XFCPrechargeDelay[DC__NUM_DPP__MAX];
double XFCRemoteSurfaceFlipLatency[DC__NUM_DPP__MAX];
double XFCPrefetchMargin[DC__NUM_DPP__MAX];
display_e2e_pipe_params_st cache_pipes[DC__NUM_DPP__MAX];
unsigned int cache_num_pipes;
unsigned int pipe_plane[DC__NUM_DPP__MAX];
/* vba mode support */
/*inputs*/
bool SupportGFX7CompatibleTilingIn32bppAnd64bpp;
double MaxHSCLRatio;
double MaxVSCLRatio;
unsigned int MaxNumWriteback;
bool WritebackLumaAndChromaScalingSupported;
bool Cursor64BppSupport;
double DCFCLKPerState[DC__VOLTAGE_STATES + 1];
double FabricClockPerState[DC__VOLTAGE_STATES + 1];
double SOCCLKPerState[DC__VOLTAGE_STATES + 1];
double PHYCLKPerState[DC__VOLTAGE_STATES + 1];
double MaxDppclk[DC__VOLTAGE_STATES + 1];
double MaxDSCCLK[DC__VOLTAGE_STATES + 1];
double DRAMSpeedPerState[DC__VOLTAGE_STATES + 1];
double MaxDispclk[DC__VOLTAGE_STATES + 1];
/*outputs*/
bool ScaleRatioAndTapsSupport;
bool SourceFormatPixelAndScanSupport;
unsigned int SwathWidthYSingleDPP[DC__NUM_DPP__MAX];
double BytePerPixelInDETY[DC__NUM_DPP__MAX];
double BytePerPixelInDETC[DC__NUM_DPP__MAX];
double TotalReadBandwidthConsumedGBytePerSecond;
double ReadBandwidth[DC__NUM_DPP__MAX];
double TotalWriteBandwidthConsumedGBytePerSecond;
double WriteBandwidth[DC__NUM_DPP__MAX];
double TotalBandwidthConsumedGBytePerSecond;
bool DCCEnabledInAnyPlane;
bool WritebackLatencySupport;
bool WritebackModeSupport;
bool Writeback10bpc420Supported;
bool BandwidthSupport[DC__VOLTAGE_STATES + 1];
unsigned int TotalNumberOfActiveWriteback;
double CriticalPoint;
double ReturnBWToDCNPerState;
double FabricAndDRAMBandwidthPerState[DC__VOLTAGE_STATES + 1];
double ReturnBWPerState[DC__VOLTAGE_STATES + 1];
double UrgentRoundTripAndOutOfOrderLatencyPerState[DC__VOLTAGE_STATES + 1];
bool ODMCombineEnablePerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
bool PTEBufferSizeNotExceededY[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
bool PTEBufferSizeNotExceededC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
bool PrefetchSupported[DC__VOLTAGE_STATES + 1];
bool VRatioInPrefetchSupported[DC__VOLTAGE_STATES + 1];
bool DISPCLK_DPPCLK_Support[DC__VOLTAGE_STATES + 1];
bool TotalAvailablePipesSupport[DC__VOLTAGE_STATES + 1];
bool UrgentLatencySupport[DC__VOLTAGE_STATES + 1];
bool ModeSupport[DC__VOLTAGE_STATES + 1];
bool DIOSupport[DC__VOLTAGE_STATES + 1];
bool NotEnoughDSCUnits[DC__VOLTAGE_STATES + 1];
bool DSCCLKRequiredMoreThanSupported[DC__VOLTAGE_STATES + 1];
bool ROBSupport[DC__VOLTAGE_STATES + 1];
bool PTEBufferSizeNotExceeded[DC__VOLTAGE_STATES + 1];
bool RequiresDSC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
bool IsErrorResult[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
bool ViewportSizeSupport[DC__VOLTAGE_STATES + 1];
bool prefetch_vm_bw_valid;
bool prefetch_row_bw_valid;
bool NumberOfOTGSupport;
bool NonsupportedDSCInputBPC;
bool WritebackScaleRatioAndTapsSupport;
bool CursorSupport;
bool PitchSupport;
double WritebackLineBufferLumaBufferSize;
double WritebackLineBufferChromaBufferSize;
double WritebackMinHSCLRatio;
double WritebackMinVSCLRatio;
double WritebackMaxHSCLRatio;
double WritebackMaxVSCLRatio;
double WritebackMaxHSCLTaps;
double WritebackMaxVSCLTaps;
unsigned int MaxNumDPP;
unsigned int MaxNumOTG;
double CursorBufferSize;
double CursorChunkSize;
unsigned int Mode;
unsigned int NoOfDPP[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
double OutputLinkDPLanes[DC__NUM_DPP__MAX];
double SwathWidthYPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
double SwathHeightYPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
double SwathHeightCPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
double UrgentLatencySupportUsPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
double VRatioPreY[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
double VRatioPreC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
double RequiredPrefetchPixelDataBW[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
double RequiredDPPCLK[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
double RequiredDISPCLK[DC__VOLTAGE_STATES + 1];
double TotalNumberOfActiveDPP[DC__VOLTAGE_STATES + 1];
double TotalNumberOfDCCActiveDPP[DC__VOLTAGE_STATES + 1];
double PrefetchBW[DC__NUM_DPP__MAX];
double PDEAndMetaPTEBytesPerFrame[DC__NUM_DPP__MAX];
double MetaRowBytes[DC__NUM_DPP__MAX];
double DPTEBytesPerRow[DC__NUM_DPP__MAX];
double PrefetchLinesY[DC__NUM_DPP__MAX];
double PrefetchLinesC[DC__NUM_DPP__MAX];
unsigned int MaxNumSwY[DC__NUM_DPP__MAX];
unsigned int MaxNumSwC[DC__NUM_DPP__MAX];
double PrefillY[DC__NUM_DPP__MAX];
double PrefillC[DC__NUM_DPP__MAX];
double LineTimesForPrefetch[DC__NUM_DPP__MAX];
double LinesForMetaPTE[DC__NUM_DPP__MAX];
double LinesForMetaAndDPTERow[DC__NUM_DPP__MAX];
double MinDPPCLKUsingSingleDPP[DC__NUM_DPP__MAX];
double RequiresFEC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
unsigned int OutputBppPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
double DSCDelayPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
unsigned int Read256BlockHeightY[DC__NUM_DPP__MAX];
unsigned int Read256BlockWidthY[DC__NUM_DPP__MAX];
unsigned int Read256BlockHeightC[DC__NUM_DPP__MAX];
unsigned int Read256BlockWidthC[DC__NUM_DPP__MAX];
unsigned int ImmediateFlipBytes[DC__NUM_DPP__MAX];
double MaxSwathHeightY[DC__NUM_DPP__MAX];
double MaxSwathHeightC[DC__NUM_DPP__MAX];
double MinSwathHeightY[DC__NUM_DPP__MAX];
double MinSwathHeightC[DC__NUM_DPP__MAX];
double PSCL_FACTOR[DC__NUM_DPP__MAX];
double PSCL_FACTOR_CHROMA[DC__NUM_DPP__MAX];
double MaximumVStartup[DC__NUM_DPP__MAX];
double AlignedDCCMetaPitch[DC__NUM_DPP__MAX];
double AlignedYPitch[DC__NUM_DPP__MAX];
double AlignedCPitch[DC__NUM_DPP__MAX];
double MaximumSwathWidth[DC__NUM_DPP__MAX];
double final_flip_bw[DC__NUM_DPP__MAX];
double ImmediateFlipSupportedForState[DC__VOLTAGE_STATES + 1];
double WritebackLumaVExtra;
double WritebackChromaVExtra;
double WritebackRequiredDISPCLK;
double MaximumSwathWidthSupport;
double MaximumSwathWidthInDETBuffer;
double MaximumSwathWidthInLineBuffer;
double MaxDispclkRoundedDownToDFSGranularity;
double MaxDppclkRoundedDownToDFSGranularity;
double PlaneRequiredDISPCLKWithoutODMCombine;
double PlaneRequiredDISPCLK;
double TotalNumberOfActiveOTG;
double FECOverhead;
double EffectiveFECOverhead;
unsigned int Outbpp;
unsigned int OutbppDSC;
double TotalDSCUnitsRequired;
double bpp;
unsigned int slices;
double SwathWidthGranularityY;
double RoundedUpMaxSwathSizeBytesY;
double SwathWidthGranularityC;
double RoundedUpMaxSwathSizeBytesC;
double LinesInDETLuma;
double LinesInDETChroma;
double EffectiveDETLBLinesLuma;
double EffectiveDETLBLinesChroma;
double ProjectedDCFCLKDeepSleep;
double PDEAndMetaPTEBytesPerFrameY;
double PDEAndMetaPTEBytesPerFrameC;
unsigned int MetaRowBytesY;
unsigned int MetaRowBytesC;
unsigned int DPTEBytesPerRowC;
unsigned int DPTEBytesPerRowY;
double ExtraLatency;
double TimeCalc;
double TWait;
double MaximumReadBandwidthWithPrefetch;
double total_dcn_read_bw_with_flip;
};
#endif /* _DML2_DISPLAY_MODE_VBA_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -22,103 +22,114 @@
* Authors: AMD
*
*/
#ifndef __DISPLAY_RQ_DLG_CALC_H__
#define __DISPLAY_RQ_DLG_CALC_H__
#ifndef __DML2_DISPLAY_RQ_DLG_CALC_H__
#define __DML2_DISPLAY_RQ_DLG_CALC_H__
#include "dml_common_defs.h"
#include "display_rq_dlg_helpers.h"
struct display_mode_lib;
void extract_rq_regs(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_rq_regs_st *rq_regs,
const struct _vcs_dpi_display_rq_params_st rq_param);
/* Function: dml_rq_dlg_get_rq_params
* Calculate requestor related parameters that register definition agnostic
* (i.e. this layer does try to separate real values from register defintion)
* Input:
* pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
* Output:
* rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.)
*/
// Function: dml_rq_dlg_get_rq_params
// Calculate requestor related parameters that register definition agnostic
// (i.e. this layer does try to separate real values from register definition)
// Input:
// pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
// Output:
// rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.)
//
void dml_rq_dlg_get_rq_params(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_rq_params_st *rq_param,
const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param);
display_rq_params_st *rq_param,
const display_pipe_source_params_st pipe_src_param);
/* Function: dml_rq_dlg_get_rq_reg
* Main entry point for test to get the register values out of this DML class.
* This function calls <get_rq_param> and <extract_rq_regs> fucntions to calculate
* and then populate the rq_regs struct
* Input:
* pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
* Output:
* rq_regs - struct that holds all the RQ registers field value.
* See also: <display_rq_regs_st>
*/
// Function: dml_rq_dlg_get_rq_reg
// Main entry point for test to get the register values out of this DML class.
// This function calls <get_rq_param> and <extract_rq_regs> fucntions to calculate
// and then populate the rq_regs struct
// Input:
// pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
// Output:
// rq_regs - struct that holds all the RQ registers field value.
// See also: <display_rq_regs_st>
void dml_rq_dlg_get_rq_reg(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_rq_regs_st *rq_regs,
const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param);
display_rq_regs_st *rq_regs,
const display_pipe_source_params_st pipe_src_param);
/* Function: dml_rq_dlg_get_dlg_params
* Calculate deadline related parameters
*/
void dml_rq_dlg_get_dlg_params(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_dlg_regs_st *dlg_regs,
struct _vcs_dpi_display_ttu_regs_st *ttu_regs,
const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param,
const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param,
const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param,
// Function: dml_rq_dlg_get_dlg_params
// Calculate deadline related parameters
//
void dml_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib,
const display_e2e_pipe_params_st *e2e_pipe_param,
const unsigned int num_pipes,
const unsigned int pipe_idx,
display_dlg_regs_st *disp_dlg_regs,
display_ttu_regs_st *disp_ttu_regs,
const display_rq_dlg_params_st rq_dlg_param,
const display_dlg_sys_params_st dlg_sys_param,
const bool cstate_en,
const bool pstate_en,
const bool vm_en,
const bool iflip_en);
const bool ignore_viewport_pos,
const bool immediate_flip_support);
/* Function: dml_rq_dlg_get_dlg_param_prefetch
* For flip_bw programming guide change, now dml needs to calculate the flip_bytes and prefetch_bw
* for ALL pipes and use this info to calculate the prefetch programming.
* Output: prefetch_param.prefetch_bw and flip_bytes
*/
// Function: dml_rq_dlg_get_dlg_param_prefetch
// For flip_bw programming guide change, now dml needs to calculate the flip_bytes and prefetch_bw
// for ALL pipes and use this info to calculate the prefetch programming.
// Output: prefetch_param.prefetch_bw and flip_bytes
void dml_rq_dlg_get_dlg_params_prefetch(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_dlg_prefetch_param_st *prefetch_param,
struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param,
struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param,
struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param,
display_dlg_prefetch_param_st *prefetch_param,
display_rq_dlg_params_st rq_dlg_param,
display_dlg_sys_params_st dlg_sys_param,
display_e2e_pipe_params_st e2e_pipe_param,
const bool cstate_en,
const bool pstate_en,
const bool vm_en);
/* Function: dml_rq_dlg_get_dlg_reg
* Calculate and return DLG and TTU register struct given the system setting
* Output:
* dlg_regs - output DLG register struct
* ttu_regs - output DLG TTU register struct
* Input:
* e2e_pipe_param - "compacted" array of e2e pipe param struct
* num_pipes - num of active "pipe" or "route"
* pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg
* cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered.
* Added for legacy or unrealistic timing tests.
*/
// Function: dml_rq_dlg_get_dlg_reg
// Calculate and return DLG and TTU register struct given the system setting
// Output:
// dlg_regs - output DLG register struct
// ttu_regs - output DLG TTU register struct
// Input:
// e2e_pipe_param - "compacted" array of e2e pipe param struct
// num_pipes - num of active "pipe" or "route"
// pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg
// cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered.
// Added for legacy or unrealistic timing tests.
void dml_rq_dlg_get_dlg_reg(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_dlg_regs_st *dlg_regs,
struct _vcs_dpi_display_ttu_regs_st *ttu_regs,
struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe_param,
display_dlg_regs_st *dlg_regs,
display_ttu_regs_st *ttu_regs,
display_e2e_pipe_params_st *e2e_pipe_param,
const unsigned int num_pipes,
const unsigned int pipe_idx,
const bool cstate_en,
const bool pstate_en,
const bool vm_en,
const bool iflip_en);
const bool ignore_viewport_pos,
const bool immediate_flip_support);
/* Function: dml_rq_dlg_get_row_heights
* Calculate dpte and meta row heights
*/
// Function: dml_rq_dlg_get_calculated_vstartup
// Calculate and return vstartup
// Output:
// unsigned int vstartup
// Input:
// e2e_pipe_param - "compacted" array of e2e pipe param struct
// num_pipes - num of active "pipe" or "route"
// pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg
// NOTE: this MUST be called after setting the prefetch mode!
unsigned int dml_rq_dlg_get_calculated_vstartup(
struct display_mode_lib *mode_lib,
display_e2e_pipe_params_st *e2e_pipe_param,
const unsigned int num_pipes,
const unsigned int pipe_idx);
// Function: dml_rq_dlg_get_row_heights
// Calculate dpte and meta row heights
void dml_rq_dlg_get_row_heights(
struct display_mode_lib *mode_lib,
unsigned int *o_dpte_row_height,
@ -131,9 +142,7 @@ void dml_rq_dlg_get_row_heights(
int source_scan,
int is_chroma);
/* Function: dml_rq_dlg_get_arb_params */
void dml_rq_dlg_get_arb_params(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_arb_params_st *arb_param);
// Function: dml_rq_dlg_get_arb_params
void dml_rq_dlg_get_arb_params(struct display_mode_lib *mode_lib, display_arb_params_st *arb_param);
#endif

View File

@ -25,296 +25,368 @@
#include "display_rq_dlg_helpers.h"
void print__rq_params_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_rq_params_st rq_param)
void print__rq_params_st(struct display_mode_lib *mode_lib, display_rq_params_st rq_param)
{
DTRACE("RQ_DLG_CALC: *************************** ");
DTRACE("RQ_DLG_CALC: DISPLAY_RQ_PARAM_ST");
DTRACE("RQ_DLG_CALC: <LUMA>");
dml_print("DML_RQ_DLG_CALC: ***************************\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_PARAM_ST\n");
dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_l);
DTRACE("RQ_DLG_CALC: <CHROMA> === ");
dml_print("DML_RQ_DLG_CALC: <CHROMA> ===\n");
print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_c);
DTRACE("RQ_DLG_CALC: <LUMA>");
dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_l);
DTRACE("RQ_DLG_CALC: <CHROMA>");
dml_print("DML_RQ_DLG_CALC: <CHROMA>\n");
print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_c);
DTRACE("RQ_DLG_CALC: <LUMA>");
dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_l);
DTRACE("RQ_DLG_CALC: <CHROMA>");
dml_print("DML_RQ_DLG_CALC: <CHROMA>\n");
print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_c);
DTRACE("RQ_DLG_CALC: *************************** ");
dml_print("DML_RQ_DLG_CALC: ***************************\n");
}
void print__data_rq_sizing_params_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing)
void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, display_data_rq_sizing_params_st rq_sizing)
{
DTRACE("RQ_DLG_CALC: ===================================== ");
DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_SIZING_PARAM_ST");
DTRACE("RQ_DLG_CALC: chunk_bytes = %0d", rq_sizing.chunk_bytes);
DTRACE("RQ_DLG_CALC: min_chunk_bytes = %0d", rq_sizing.min_chunk_bytes);
DTRACE("RQ_DLG_CALC: meta_chunk_bytes = %0d", rq_sizing.meta_chunk_bytes);
DTRACE("RQ_DLG_CALC: min_meta_chunk_bytes = %0d", rq_sizing.min_meta_chunk_bytes);
DTRACE("RQ_DLG_CALC: mpte_group_bytes = %0d", rq_sizing.mpte_group_bytes);
DTRACE("RQ_DLG_CALC: dpte_group_bytes = %0d", rq_sizing.dpte_group_bytes);
DTRACE("RQ_DLG_CALC: ===================================== ");
dml_print("DML_RQ_DLG_CALC: =====================================\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_SIZING_PARAM_ST\n");
dml_print("DML_RQ_DLG_CALC: chunk_bytes = %0d\n", rq_sizing.chunk_bytes);
dml_print("DML_RQ_DLG_CALC: min_chunk_bytes = %0d\n", rq_sizing.min_chunk_bytes);
dml_print("DML_RQ_DLG_CALC: meta_chunk_bytes = %0d\n", rq_sizing.meta_chunk_bytes);
dml_print(
"DML_RQ_DLG_CALC: min_meta_chunk_bytes = %0d\n",
rq_sizing.min_meta_chunk_bytes);
dml_print("DML_RQ_DLG_CALC: mpte_group_bytes = %0d\n", rq_sizing.mpte_group_bytes);
dml_print("DML_RQ_DLG_CALC: dpte_group_bytes = %0d\n", rq_sizing.dpte_group_bytes);
dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
void print__data_rq_dlg_params_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_data_rq_dlg_params_st rq_dlg_param)
void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, display_data_rq_dlg_params_st rq_dlg_param)
{
DTRACE("RQ_DLG_CALC: ===================================== ");
DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_DLG_PARAM_ST");
DTRACE("RQ_DLG_CALC: swath_width_ub = %0d", rq_dlg_param.swath_width_ub);
DTRACE("RQ_DLG_CALC: swath_height = %0d", rq_dlg_param.swath_height);
DTRACE("RQ_DLG_CALC: req_per_swath_ub = %0d", rq_dlg_param.req_per_swath_ub);
DTRACE(
"RQ_DLG_CALC: meta_pte_bytes_per_frame_ub = %0d",
dml_print("DML_RQ_DLG_CALC: =====================================\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_DLG_PARAM_ST\n");
dml_print(
"DML_RQ_DLG_CALC: swath_width_ub = %0d\n",
rq_dlg_param.swath_width_ub);
dml_print(
"DML_RQ_DLG_CALC: swath_height = %0d\n",
rq_dlg_param.swath_height);
dml_print(
"DML_RQ_DLG_CALC: req_per_swath_ub = %0d\n",
rq_dlg_param.req_per_swath_ub);
dml_print(
"DML_RQ_DLG_CALC: meta_pte_bytes_per_frame_ub = %0d\n",
rq_dlg_param.meta_pte_bytes_per_frame_ub);
DTRACE(
"RQ_DLG_CALC: dpte_req_per_row_ub = %0d",
dml_print(
"DML_RQ_DLG_CALC: dpte_req_per_row_ub = %0d\n",
rq_dlg_param.dpte_req_per_row_ub);
DTRACE(
"RQ_DLG_CALC: dpte_groups_per_row_ub = %0d",
dml_print(
"DML_RQ_DLG_CALC: dpte_groups_per_row_ub = %0d\n",
rq_dlg_param.dpte_groups_per_row_ub);
DTRACE("RQ_DLG_CALC: dpte_row_height = %0d", rq_dlg_param.dpte_row_height);
DTRACE(
"RQ_DLG_CALC: dpte_bytes_per_row_ub = %0d",
dml_print(
"DML_RQ_DLG_CALC: dpte_row_height = %0d\n",
rq_dlg_param.dpte_row_height);
dml_print(
"DML_RQ_DLG_CALC: dpte_bytes_per_row_ub = %0d\n",
rq_dlg_param.dpte_bytes_per_row_ub);
DTRACE(
"RQ_DLG_CALC: meta_chunks_per_row_ub = %0d",
dml_print(
"DML_RQ_DLG_CALC: meta_chunks_per_row_ub = %0d\n",
rq_dlg_param.meta_chunks_per_row_ub);
DTRACE(
"RQ_DLG_CALC: meta_req_per_row_ub = %0d",
dml_print(
"DML_RQ_DLG_CALC: meta_req_per_row_ub = %0d\n",
rq_dlg_param.meta_req_per_row_ub);
DTRACE("RQ_DLG_CALC: meta_row_height = %0d", rq_dlg_param.meta_row_height);
DTRACE(
"RQ_DLG_CALC: meta_bytes_per_row_ub = %0d",
dml_print(
"DML_RQ_DLG_CALC: meta_row_height = %0d\n",
rq_dlg_param.meta_row_height);
dml_print(
"DML_RQ_DLG_CALC: meta_bytes_per_row_ub = %0d\n",
rq_dlg_param.meta_bytes_per_row_ub);
DTRACE("RQ_DLG_CALC: ===================================== ");
dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
void print__data_rq_misc_params_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_data_rq_misc_params_st rq_misc_param)
void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, display_data_rq_misc_params_st rq_misc_param)
{
DTRACE("RQ_DLG_CALC: ===================================== ");
DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_MISC_PARAM_ST");
DTRACE("RQ_DLG_CALC: full_swath_bytes = %0d", rq_misc_param.full_swath_bytes);
DTRACE("RQ_DLG_CALC: stored_swath_bytes = %0d", rq_misc_param.stored_swath_bytes);
DTRACE("RQ_DLG_CALC: blk256_width = %0d", rq_misc_param.blk256_width);
DTRACE("RQ_DLG_CALC: blk256_height = %0d", rq_misc_param.blk256_height);
DTRACE("RQ_DLG_CALC: req_width = %0d", rq_misc_param.req_width);
DTRACE("RQ_DLG_CALC: req_height = %0d", rq_misc_param.req_height);
DTRACE("RQ_DLG_CALC: ===================================== ");
dml_print("DML_RQ_DLG_CALC: =====================================\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_MISC_PARAM_ST\n");
dml_print(
"DML_RQ_DLG_CALC: full_swath_bytes = %0d\n",
rq_misc_param.full_swath_bytes);
dml_print(
"DML_RQ_DLG_CALC: stored_swath_bytes = %0d\n",
rq_misc_param.stored_swath_bytes);
dml_print("DML_RQ_DLG_CALC: blk256_width = %0d\n", rq_misc_param.blk256_width);
dml_print("DML_RQ_DLG_CALC: blk256_height = %0d\n", rq_misc_param.blk256_height);
dml_print("DML_RQ_DLG_CALC: req_width = %0d\n", rq_misc_param.req_width);
dml_print("DML_RQ_DLG_CALC: req_height = %0d\n", rq_misc_param.req_height);
dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
void print__rq_dlg_params_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param)
void print__rq_dlg_params_st(struct display_mode_lib *mode_lib, display_rq_dlg_params_st rq_dlg_param)
{
DTRACE("RQ_DLG_CALC: ===================================== ");
DTRACE("RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST");
DTRACE("RQ_DLG_CALC: <LUMA> ");
dml_print("DML_RQ_DLG_CALC: =====================================\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST\n");
dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_l);
DTRACE("RQ_DLG_CALC: <CHROMA> ");
dml_print("DML_RQ_DLG_CALC: <CHROMA>\n");
print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_c);
DTRACE("RQ_DLG_CALC: ===================================== ");
dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
void print__dlg_sys_params_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param)
void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, display_dlg_sys_params_st dlg_sys_param)
{
DTRACE("RQ_DLG_CALC: ===================================== ");
DTRACE("RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST");
DTRACE("RQ_DLG_CALC: t_mclk_wm_us = %3.2f", dlg_sys_param.t_mclk_wm_us);
DTRACE("RQ_DLG_CALC: t_urg_wm_us = %3.2f", dlg_sys_param.t_urg_wm_us);
DTRACE("RQ_DLG_CALC: t_sr_wm_us = %3.2f", dlg_sys_param.t_sr_wm_us);
DTRACE("RQ_DLG_CALC: t_extra_us = %3.2f", dlg_sys_param.t_extra_us);
DTRACE("RQ_DLG_CALC: t_srx_delay_us = %3.2f", dlg_sys_param.t_srx_delay_us);
DTRACE("RQ_DLG_CALC: deepsleep_dcfclk_mhz = %3.2f", dlg_sys_param.deepsleep_dcfclk_mhz);
DTRACE("RQ_DLG_CALC: ===================================== ");
dml_print("DML_RQ_DLG_CALC: =====================================\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST\n");
dml_print("DML_RQ_DLG_CALC: t_mclk_wm_us = %3.2f\n", dlg_sys_param.t_mclk_wm_us);
dml_print("DML_RQ_DLG_CALC: t_urg_wm_us = %3.2f\n", dlg_sys_param.t_urg_wm_us);
dml_print("DML_RQ_DLG_CALC: t_sr_wm_us = %3.2f\n", dlg_sys_param.t_sr_wm_us);
dml_print("DML_RQ_DLG_CALC: t_extra_us = %3.2f\n", dlg_sys_param.t_extra_us);
dml_print(
"DML_RQ_DLG_CALC: t_srx_delay_us = %3.2f\n",
dlg_sys_param.t_srx_delay_us);
dml_print(
"DML_RQ_DLG_CALC: deepsleep_dcfclk_mhz = %3.2f\n",
dlg_sys_param.deepsleep_dcfclk_mhz);
dml_print(
"DML_RQ_DLG_CALC: total_flip_bw = %3.2f\n",
dlg_sys_param.total_flip_bw);
dml_print(
"DML_RQ_DLG_CALC: total_flip_bytes = %i\n",
dlg_sys_param.total_flip_bytes);
dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
void print__data_rq_regs_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_data_rq_regs_st rq_regs)
void print__data_rq_regs_st(struct display_mode_lib *mode_lib, display_data_rq_regs_st rq_regs)
{
DTRACE("RQ_DLG_CALC: ===================================== ");
DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_REGS_ST");
DTRACE("RQ_DLG_CALC: chunk_size = 0x%0x", rq_regs.chunk_size);
DTRACE("RQ_DLG_CALC: min_chunk_size = 0x%0x", rq_regs.min_chunk_size);
DTRACE("RQ_DLG_CALC: meta_chunk_size = 0x%0x", rq_regs.meta_chunk_size);
DTRACE("RQ_DLG_CALC: min_meta_chunk_size = 0x%0x", rq_regs.min_meta_chunk_size);
DTRACE("RQ_DLG_CALC: dpte_group_size = 0x%0x", rq_regs.dpte_group_size);
DTRACE("RQ_DLG_CALC: mpte_group_size = 0x%0x", rq_regs.mpte_group_size);
DTRACE("RQ_DLG_CALC: swath_height = 0x%0x", rq_regs.swath_height);
DTRACE("RQ_DLG_CALC: pte_row_height_linear = 0x%0x", rq_regs.pte_row_height_linear);
DTRACE("RQ_DLG_CALC: ===================================== ");
dml_print("DML_RQ_DLG_CALC: =====================================\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_REGS_ST\n");
dml_print("DML_RQ_DLG_CALC: chunk_size = 0x%0x\n", rq_regs.chunk_size);
dml_print("DML_RQ_DLG_CALC: min_chunk_size = 0x%0x\n", rq_regs.min_chunk_size);
dml_print("DML_RQ_DLG_CALC: meta_chunk_size = 0x%0x\n", rq_regs.meta_chunk_size);
dml_print(
"DML_RQ_DLG_CALC: min_meta_chunk_size = 0x%0x\n",
rq_regs.min_meta_chunk_size);
dml_print("DML_RQ_DLG_CALC: dpte_group_size = 0x%0x\n", rq_regs.dpte_group_size);
dml_print("DML_RQ_DLG_CALC: mpte_group_size = 0x%0x\n", rq_regs.mpte_group_size);
dml_print("DML_RQ_DLG_CALC: swath_height = 0x%0x\n", rq_regs.swath_height);
dml_print(
"DML_RQ_DLG_CALC: pte_row_height_linear = 0x%0x\n",
rq_regs.pte_row_height_linear);
dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
void print__rq_regs_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_rq_regs_st rq_regs)
void print__rq_regs_st(struct display_mode_lib *mode_lib, display_rq_regs_st rq_regs)
{
DTRACE("RQ_DLG_CALC: ===================================== ");
DTRACE("RQ_DLG_CALC: DISPLAY_RQ_REGS_ST");
DTRACE("RQ_DLG_CALC: <LUMA> ");
dml_print("DML_RQ_DLG_CALC: =====================================\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_REGS_ST\n");
dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
print__data_rq_regs_st(mode_lib, rq_regs.rq_regs_l);
DTRACE("RQ_DLG_CALC: <CHROMA> ");
dml_print("DML_RQ_DLG_CALC: <CHROMA>\n");
print__data_rq_regs_st(mode_lib, rq_regs.rq_regs_c);
DTRACE("RQ_DLG_CALC: drq_expansion_mode = 0x%0x", rq_regs.drq_expansion_mode);
DTRACE("RQ_DLG_CALC: prq_expansion_mode = 0x%0x", rq_regs.prq_expansion_mode);
DTRACE("RQ_DLG_CALC: mrq_expansion_mode = 0x%0x", rq_regs.mrq_expansion_mode);
DTRACE("RQ_DLG_CALC: crq_expansion_mode = 0x%0x", rq_regs.crq_expansion_mode);
DTRACE("RQ_DLG_CALC: plane1_base_address = 0x%0x", rq_regs.plane1_base_address);
DTRACE("RQ_DLG_CALC: ===================================== ");
dml_print("DML_RQ_DLG_CALC: drq_expansion_mode = 0x%0x\n", rq_regs.drq_expansion_mode);
dml_print("DML_RQ_DLG_CALC: prq_expansion_mode = 0x%0x\n", rq_regs.prq_expansion_mode);
dml_print("DML_RQ_DLG_CALC: mrq_expansion_mode = 0x%0x\n", rq_regs.mrq_expansion_mode);
dml_print("DML_RQ_DLG_CALC: crq_expansion_mode = 0x%0x\n", rq_regs.crq_expansion_mode);
dml_print("DML_RQ_DLG_CALC: plane1_base_address = 0x%0x\n", rq_regs.plane1_base_address);
dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
void print__dlg_regs_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_dlg_regs_st dlg_regs)
void print__dlg_regs_st(struct display_mode_lib *mode_lib, display_dlg_regs_st dlg_regs)
{
DTRACE("RQ_DLG_CALC: ===================================== ");
DTRACE("RQ_DLG_CALC: DISPLAY_DLG_REGS_ST ");
DTRACE(
"RQ_DLG_CALC: refcyc_h_blank_end = 0x%0x",
dml_print("DML_RQ_DLG_CALC: =====================================\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_DLG_REGS_ST\n");
dml_print(
"DML_RQ_DLG_CALC: refcyc_h_blank_end = 0x%0x\n",
dlg_regs.refcyc_h_blank_end);
DTRACE("RQ_DLG_CALC: dlg_vblank_end = 0x%0x", dlg_regs.dlg_vblank_end);
DTRACE(
"RQ_DLG_CALC: min_dst_y_next_start = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: dlg_vblank_end = 0x%0x\n",
dlg_regs.dlg_vblank_end);
dml_print(
"DML_RQ_DLG_CALC: min_dst_y_next_start = 0x%0x\n",
dlg_regs.min_dst_y_next_start);
DTRACE(
"RQ_DLG_CALC: refcyc_per_htotal = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_htotal = 0x%0x\n",
dlg_regs.refcyc_per_htotal);
DTRACE(
"RQ_DLG_CALC: refcyc_x_after_scaler = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_x_after_scaler = 0x%0x\n",
dlg_regs.refcyc_x_after_scaler);
DTRACE(
"RQ_DLG_CALC: dst_y_after_scaler = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: dst_y_after_scaler = 0x%0x\n",
dlg_regs.dst_y_after_scaler);
DTRACE("RQ_DLG_CALC: dst_y_prefetch = 0x%0x", dlg_regs.dst_y_prefetch);
DTRACE(
"RQ_DLG_CALC: dst_y_per_vm_vblank = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: dst_y_prefetch = 0x%0x\n",
dlg_regs.dst_y_prefetch);
dml_print(
"DML_RQ_DLG_CALC: dst_y_per_vm_vblank = 0x%0x\n",
dlg_regs.dst_y_per_vm_vblank);
DTRACE(
"RQ_DLG_CALC: dst_y_per_row_vblank = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: dst_y_per_row_vblank = 0x%0x\n",
dlg_regs.dst_y_per_row_vblank);
DTRACE(
"RQ_DLG_CALC: ref_freq_to_pix_freq = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: dst_y_per_vm_flip = 0x%0x\n",
dlg_regs.dst_y_per_vm_flip);
dml_print(
"DML_RQ_DLG_CALC: dst_y_per_row_flip = 0x%0x\n",
dlg_regs.dst_y_per_row_flip);
dml_print(
"DML_RQ_DLG_CALC: ref_freq_to_pix_freq = 0x%0x\n",
dlg_regs.ref_freq_to_pix_freq);
DTRACE("RQ_DLG_CALC: vratio_prefetch = 0x%0x", dlg_regs.vratio_prefetch);
DTRACE(
"RQ_DLG_CALC: vratio_prefetch_c = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: vratio_prefetch = 0x%0x\n",
dlg_regs.vratio_prefetch);
dml_print(
"DML_RQ_DLG_CALC: vratio_prefetch_c = 0x%0x\n",
dlg_regs.vratio_prefetch_c);
DTRACE(
"RQ_DLG_CALC: refcyc_per_pte_group_vblank_l = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_pte_group_vblank_l = 0x%0x\n",
dlg_regs.refcyc_per_pte_group_vblank_l);
DTRACE(
"RQ_DLG_CALC: refcyc_per_pte_group_vblank_c = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_pte_group_vblank_c = 0x%0x\n",
dlg_regs.refcyc_per_pte_group_vblank_c);
DTRACE(
"RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_l = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_l = 0x%0x\n",
dlg_regs.refcyc_per_meta_chunk_vblank_l);
DTRACE(
"RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_c = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_c = 0x%0x\n",
dlg_regs.refcyc_per_meta_chunk_vblank_c);
DTRACE(
"RQ_DLG_CALC: dst_y_per_pte_row_nom_l = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_pte_group_flip_l = 0x%0x\n",
dlg_regs.refcyc_per_pte_group_flip_l);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_pte_group_flip_c = 0x%0x\n",
dlg_regs.refcyc_per_pte_group_flip_c);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_meta_chunk_flip_l = 0x%0x\n",
dlg_regs.refcyc_per_meta_chunk_flip_l);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_meta_chunk_flip_c = 0x%0x\n",
dlg_regs.refcyc_per_meta_chunk_flip_c);
dml_print(
"DML_RQ_DLG_CALC: dst_y_per_pte_row_nom_l = 0x%0x\n",
dlg_regs.dst_y_per_pte_row_nom_l);
DTRACE(
"RQ_DLG_CALC: dst_y_per_pte_row_nom_c = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: dst_y_per_pte_row_nom_c = 0x%0x\n",
dlg_regs.dst_y_per_pte_row_nom_c);
DTRACE(
"RQ_DLG_CALC: refcyc_per_pte_group_nom_l = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_pte_group_nom_l = 0x%0x\n",
dlg_regs.refcyc_per_pte_group_nom_l);
DTRACE(
"RQ_DLG_CALC: refcyc_per_pte_group_nom_c = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_pte_group_nom_c = 0x%0x\n",
dlg_regs.refcyc_per_pte_group_nom_c);
DTRACE(
"RQ_DLG_CALC: dst_y_per_meta_row_nom_l = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: dst_y_per_meta_row_nom_l = 0x%0x\n",
dlg_regs.dst_y_per_meta_row_nom_l);
DTRACE(
"RQ_DLG_CALC: dst_y_per_meta_row_nom_c = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: dst_y_per_meta_row_nom_c = 0x%0x\n",
dlg_regs.dst_y_per_meta_row_nom_c);
DTRACE(
"RQ_DLG_CALC: refcyc_per_meta_chunk_nom_l = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_meta_chunk_nom_l = 0x%0x\n",
dlg_regs.refcyc_per_meta_chunk_nom_l);
DTRACE(
"RQ_DLG_CALC: refcyc_per_meta_chunk_nom_c = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_meta_chunk_nom_c = 0x%0x\n",
dlg_regs.refcyc_per_meta_chunk_nom_c);
DTRACE(
"RQ_DLG_CALC: refcyc_per_line_delivery_pre_l = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_line_delivery_pre_l = 0x%0x\n",
dlg_regs.refcyc_per_line_delivery_pre_l);
DTRACE(
"RQ_DLG_CALC: refcyc_per_line_delivery_pre_c = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_line_delivery_pre_c = 0x%0x\n",
dlg_regs.refcyc_per_line_delivery_pre_c);
DTRACE(
"RQ_DLG_CALC: refcyc_per_line_delivery_l = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_line_delivery_l = 0x%0x\n",
dlg_regs.refcyc_per_line_delivery_l);
DTRACE(
"RQ_DLG_CALC: refcyc_per_line_delivery_c = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_line_delivery_c = 0x%0x\n",
dlg_regs.refcyc_per_line_delivery_c);
DTRACE(
"RQ_DLG_CALC: chunk_hdl_adjust_cur0 = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: chunk_hdl_adjust_cur0 = 0x%0x\n",
dlg_regs.chunk_hdl_adjust_cur0);
DTRACE("RQ_DLG_CALC: ===================================== ");
dml_print(
"DML_RQ_DLG_CALC: dst_y_offset_cur1 = 0x%0x\n",
dlg_regs.dst_y_offset_cur1);
dml_print(
"DML_RQ_DLG_CALC: chunk_hdl_adjust_cur1 = 0x%0x\n",
dlg_regs.chunk_hdl_adjust_cur1);
dml_print(
"DML_RQ_DLG_CALC: vready_after_vcount0 = 0x%0x\n",
dlg_regs.vready_after_vcount0);
dml_print(
"DML_RQ_DLG_CALC: dst_y_delta_drq_limit = 0x%0x\n",
dlg_regs.dst_y_delta_drq_limit);
dml_print(
"DML_RQ_DLG_CALC: xfc_reg_transfer_delay = 0x%0x\n",
dlg_regs.xfc_reg_transfer_delay);
dml_print(
"DML_RQ_DLG_CALC: xfc_reg_precharge_delay = 0x%0x\n",
dlg_regs.xfc_reg_precharge_delay);
dml_print(
"DML_RQ_DLG_CALC: xfc_reg_remote_surface_flip_latency = 0x%0x\n",
dlg_regs.xfc_reg_remote_surface_flip_latency);
dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
void print__ttu_regs_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_ttu_regs_st ttu_regs)
void print__ttu_regs_st(struct display_mode_lib *mode_lib, display_ttu_regs_st ttu_regs)
{
DTRACE("RQ_DLG_CALC: ===================================== ");
DTRACE("RQ_DLG_CALC: DISPLAY_TTU_REGS_ST ");
DTRACE(
"RQ_DLG_CALC: qos_level_low_wm = 0x%0x",
dml_print("DML_RQ_DLG_CALC: =====================================\n");
dml_print("DML_RQ_DLG_CALC: DISPLAY_TTU_REGS_ST\n");
dml_print(
"DML_RQ_DLG_CALC: qos_level_low_wm = 0x%0x\n",
ttu_regs.qos_level_low_wm);
DTRACE(
"RQ_DLG_CALC: qos_level_high_wm = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: qos_level_high_wm = 0x%0x\n",
ttu_regs.qos_level_high_wm);
DTRACE("RQ_DLG_CALC: min_ttu_vblank = 0x%0x", ttu_regs.min_ttu_vblank);
DTRACE("RQ_DLG_CALC: qos_level_flip = 0x%0x", ttu_regs.qos_level_flip);
DTRACE(
"RQ_DLG_CALC: refcyc_per_req_delivery_pre_l = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: min_ttu_vblank = 0x%0x\n",
ttu_regs.min_ttu_vblank);
dml_print(
"DML_RQ_DLG_CALC: qos_level_flip = 0x%0x\n",
ttu_regs.qos_level_flip);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_l = 0x%0x\n",
ttu_regs.refcyc_per_req_delivery_pre_l);
DTRACE(
"RQ_DLG_CALC: refcyc_per_req_delivery_l = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_req_delivery_l = 0x%0x\n",
ttu_regs.refcyc_per_req_delivery_l);
DTRACE(
"RQ_DLG_CALC: refcyc_per_req_delivery_pre_c = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_c = 0x%0x\n",
ttu_regs.refcyc_per_req_delivery_pre_c);
DTRACE(
"RQ_DLG_CALC: refcyc_per_req_delivery_c = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_req_delivery_c = 0x%0x\n",
ttu_regs.refcyc_per_req_delivery_c);
DTRACE(
"RQ_DLG_CALC: refcyc_per_req_delivery_cur0 = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_req_delivery_cur0 = 0x%0x\n",
ttu_regs.refcyc_per_req_delivery_cur0);
DTRACE(
"RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur0 = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur0 = 0x%0x\n",
ttu_regs.refcyc_per_req_delivery_pre_cur0);
DTRACE(
"RQ_DLG_CALC: qos_level_fixed_l = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_req_delivery_cur1 = 0x%0x\n",
ttu_regs.refcyc_per_req_delivery_cur1);
dml_print(
"DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur1 = 0x%0x\n",
ttu_regs.refcyc_per_req_delivery_pre_cur1);
dml_print(
"DML_RQ_DLG_CALC: qos_level_fixed_l = 0x%0x\n",
ttu_regs.qos_level_fixed_l);
DTRACE(
"RQ_DLG_CALC: qos_ramp_disable_l = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: qos_ramp_disable_l = 0x%0x\n",
ttu_regs.qos_ramp_disable_l);
DTRACE(
"RQ_DLG_CALC: qos_level_fixed_c = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: qos_level_fixed_c = 0x%0x\n",
ttu_regs.qos_level_fixed_c);
DTRACE(
"RQ_DLG_CALC: qos_ramp_disable_c = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: qos_ramp_disable_c = 0x%0x\n",
ttu_regs.qos_ramp_disable_c);
DTRACE(
"RQ_DLG_CALC: qos_level_fixed_cur0 = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: qos_level_fixed_cur0 = 0x%0x\n",
ttu_regs.qos_level_fixed_cur0);
DTRACE(
"RQ_DLG_CALC: qos_ramp_disable_cur0 = 0x%0x",
dml_print(
"DML_RQ_DLG_CALC: qos_ramp_disable_cur0 = 0x%0x\n",
ttu_regs.qos_ramp_disable_cur0);
DTRACE("RQ_DLG_CALC: ===================================== ");
dml_print(
"DML_RQ_DLG_CALC: qos_level_fixed_cur1 = 0x%0x\n",
ttu_regs.qos_level_fixed_cur1);
dml_print(
"DML_RQ_DLG_CALC: qos_ramp_disable_cur1 = 0x%0x\n",
ttu_regs.qos_ramp_disable_cur1);
dml_print("DML_RQ_DLG_CALC: =====================================\n");
}

View File

@ -22,6 +22,7 @@
* Authors: AMD
*
*/
#ifndef __DISPLAY_RQ_DLG_HELPERS_H__
#define __DISPLAY_RQ_DLG_HELPERS_H__
@ -31,36 +32,16 @@
/* Function: Printer functions
* Print various struct
*/
void print__rq_params_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_rq_params_st rq_param);
void print__data_rq_sizing_params_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing);
void print__data_rq_dlg_params_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_data_rq_dlg_params_st rq_dlg_param);
void print__data_rq_misc_params_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_data_rq_misc_params_st rq_misc_param);
void print__rq_dlg_params_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param);
void print__dlg_sys_params_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param);
void print__rq_params_st(struct display_mode_lib *mode_lib, display_rq_params_st rq_param);
void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, display_data_rq_sizing_params_st rq_sizing);
void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, display_data_rq_dlg_params_st rq_dlg_param);
void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, display_data_rq_misc_params_st rq_misc_param);
void print__rq_dlg_params_st(struct display_mode_lib *mode_lib, display_rq_dlg_params_st rq_dlg_param);
void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, display_dlg_sys_params_st dlg_sys_param);
void print__data_rq_regs_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_data_rq_regs_st data_rq_regs);
void print__rq_regs_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_rq_regs_st rq_regs);
void print__dlg_regs_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_dlg_regs_st dlg_regs);
void print__ttu_regs_st(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_ttu_regs_st ttu_regs);
void print__data_rq_regs_st(struct display_mode_lib *mode_lib, display_data_rq_regs_st data_rq_regs);
void print__rq_regs_st(struct display_mode_lib *mode_lib, display_rq_regs_st rq_regs);
void print__dlg_regs_st(struct display_mode_lib *mode_lib, display_dlg_regs_st dlg_regs);
void print__ttu_regs_st(struct display_mode_lib *mode_lib, display_ttu_regs_st ttu_regs);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,98 +0,0 @@
/*
* Copyright 2017 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __DISPLAY_WATERMARK_H__
#define __DISPLAY_WATERMARK_H__
#include "dml_common_defs.h"
struct display_mode_lib;
double dml_wm_urgent_extra(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
unsigned int num_pipes);
double dml_wm_urgent_extra_max(struct display_mode_lib *mode_lib);
double dml_wm_urgent_e2e(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
unsigned int num_pipes);
double dml_wm_urgent(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_wm_calc_pipe_params_st *planes,
unsigned int num_planes);
double dml_wm_pte_meta_urgent(struct display_mode_lib *mode_lib, double urgent_wm_us);
double dml_wm_dcfclk_deepsleep_mhz_e2e(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
unsigned int num_pipes);
double dml_wm_dcfclk_deepsleep_mhz(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_wm_calc_pipe_params_st *planes,
unsigned int num_planes);
struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate_e2e(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
unsigned int num_pipes);
struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
unsigned int num_pipes);
double dml_wm_writeback_pstate_e2e(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
unsigned int num_pipes);
double dml_wm_writeback_pstate(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
unsigned int num_pipes);
double dml_wm_expected_stutter_eff_e2e(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
unsigned int num_pipes);
double dml_wm_expected_stutter_eff_e2e_with_vblank(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
unsigned int num_pipes);
unsigned int dml_wm_e2e_to_wm(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
unsigned int num_pipes,
struct _vcs_dpi_wm_calc_pipe_params_st *wm);
double dml_wm_calc_total_data_read_bw(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_wm_calc_pipe_params_st *planes,
unsigned int num_planes);
double dml_wm_calc_return_bw(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_wm_calc_pipe_params_st *planes,
unsigned int num_planes);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
/*
* Copyright 2017 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __DISPLAY_RQ_DLG_CALC_H__
#define __DISPLAY_RQ_DLG_CALC_H__
#include "dml_common_defs.h"
#include "display_rq_dlg_helpers.h"
struct display_mode_lib;
void dml1_extract_rq_regs(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_rq_regs_st *rq_regs,
const struct _vcs_dpi_display_rq_params_st rq_param);
/* Function: dml_rq_dlg_get_rq_params
* Calculate requestor related parameters that register definition agnostic
* (i.e. this layer does try to separate real values from register definition)
* Input:
* pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
* Output:
* rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.)
*/
void dml1_rq_dlg_get_rq_params(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_rq_params_st *rq_param,
const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param);
/* Function: dml_rq_dlg_get_dlg_params
* Calculate deadline related parameters
*/
void dml1_rq_dlg_get_dlg_params(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_dlg_regs_st *dlg_regs,
struct _vcs_dpi_display_ttu_regs_st *ttu_regs,
const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param,
const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param,
const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param,
const bool cstate_en,
const bool pstate_en,
const bool vm_en,
const bool iflip_en);
#endif

View File

@ -27,11 +27,12 @@
#include "../calcs/dcn_calc_math.h"
#include "dml_inline_defs.h"
double dml_round(double a)
{
double round_pt = 0.5;
double ceil = dml_ceil(a);
double floor = dml_floor(a);
double ceil = dml_ceil(a, 1);
double floor = dml_floor(a, 1);
if (a - floor >= round_pt)
return ceil;

View File

@ -22,6 +22,7 @@
* Authors: AMD
*
*/
#ifndef __DC_COMMON_DEFS_H__
#define __DC_COMMON_DEFS_H__
@ -30,7 +31,8 @@
#include "display_mode_structs.h"
#include "display_mode_enums.h"
#define DTRACE(str, ...) dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__);
#define dml_print(str, ...) {dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); }
#define DTRACE(str, ...) {dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); }
double dml_round(double a);

View File

@ -1,5 +1,31 @@
/*
* Copyright 2017 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __DML_INLINE_DEFS_H__
#define __DML_INLINE_DEFS_H__
#include "dml_common_defs.h"
#include "../calcs/dcn_calc_math.h"
@ -13,14 +39,29 @@ static inline double dml_max(double a, double b)
return (double) dcn_bw_max2(a, b);
}
static inline double dml_ceil(double a)
static inline double dml_max3(double a, double b, double c)
{
return (double) dcn_bw_ceil2(a, 1);
return dml_max(dml_max(a, b), c);
}
static inline double dml_floor(double a)
static inline double dml_max4(double a, double b, double c, double d)
{
return (double) dcn_bw_floor2(a, 1);
return dml_max(dml_max(a, b), dml_max(c, d));
}
static inline double dml_max5(double a, double b, double c, double d, double e)
{
return dml_max(dml_max4(a, b, c, d), e);
}
static inline double dml_ceil(double a, double granularity)
{
return (double) dcn_bw_ceil2(a, granularity);
}
static inline double dml_floor(double a, double granularity)
{
return (double) dcn_bw_floor2(a, granularity);
}
static inline int dml_log2(double x)

View File

@ -24,51 +24,46 @@
*/
#include "soc_bounding_box.h"
#include "display_mode_lib.h"
#include "dc_features.h"
#include "dml_inline_defs.h"
void dml_socbb_set_latencies(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_soc_bounding_box_st *from_box)
void dml_socbb_set_latencies(soc_bounding_box_st *to_box, soc_bounding_box_st *from_box)
{
struct _vcs_dpi_soc_bounding_box_st *to_box = &mode_lib->soc;
to_box->dram_clock_change_latency_us = from_box->dram_clock_change_latency_us;
to_box->sr_exit_time_us = from_box->sr_exit_time_us;
to_box->sr_enter_plus_exit_time_us = from_box->sr_enter_plus_exit_time_us;
to_box->urgent_latency_us = from_box->urgent_latency_us;
to_box->writeback_latency_us = from_box->writeback_latency_us;
DTRACE("box.dram_clock_change_latency_us: %f", from_box->dram_clock_change_latency_us);
DTRACE("box.sr_exit_time_us: %f", from_box->sr_exit_time_us);
DTRACE("box.sr_enter_plus_exit_time_us: %f", from_box->sr_enter_plus_exit_time_us);
DTRACE("box.urgent_latency_us: %f", from_box->urgent_latency_us);
DTRACE("box.writeback_latency_us: %f", from_box->writeback_latency_us);
}
struct _vcs_dpi_voltage_scaling_st dml_socbb_voltage_scaling(
struct _vcs_dpi_soc_bounding_box_st *box,
voltage_scaling_st dml_socbb_voltage_scaling(
const soc_bounding_box_st *soc,
enum voltage_state voltage)
{
switch (voltage) {
case dm_vmin:
return box->vmin;
case dm_vnom:
return box->vnom;
case dm_vmax:
default:
return box->vmax;
const voltage_scaling_st *voltage_state;
const voltage_scaling_st * const voltage_end = soc->clock_limits + DC__VOLTAGE_STATES;
for (voltage_state = soc->clock_limits;
voltage_state < voltage_end && voltage_state->state != voltage;
voltage_state++) {
}
if (voltage_state < voltage_end)
return *voltage_state;
return soc->clock_limits[DC__VOLTAGE_STATES - 1];
}
double dml_socbb_return_bw_mhz(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage)
double dml_socbb_return_bw_mhz(soc_bounding_box_st *box, enum voltage_state voltage)
{
double return_bw;
struct _vcs_dpi_voltage_scaling_st state = dml_socbb_voltage_scaling(box, voltage);
voltage_scaling_st state = dml_socbb_voltage_scaling(box, voltage);
return_bw = dml_min(
((double) box->return_bus_width_bytes) * state.dcfclk_mhz,
return_bw = dml_min((double) box->return_bus_width_bytes * state.dcfclk_mhz,
state.dram_bw_per_chan_gbps * 1000.0 * (double) box->num_chans
* box->ideal_dram_bw_after_urgent_percent / 100.0);
return_bw = dml_min((double) box->return_bus_width_bytes * state.fabricclk_mhz, return_bw);
return return_bw;
}

View File

@ -22,15 +22,14 @@
* Authors: AMD
*
*/
#ifndef __SOC_BOUNDING_BOX_H__
#define __SOC_BOUNDING_BOX_H__
#include "dml_common_defs.h"
struct display_mode_lib;
void dml_socbb_set_latencies(struct display_mode_lib *mode_lib, struct _vcs_dpi_soc_bounding_box_st *from_box);
struct _vcs_dpi_voltage_scaling_st dml_socbb_voltage_scaling(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage);
double dml_socbb_return_bw_mhz(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage);
void dml_socbb_set_latencies(soc_bounding_box_st *to_box, soc_bounding_box_st *from_box);
voltage_scaling_st dml_socbb_voltage_scaling(const soc_bounding_box_st *box, enum voltage_state voltage);
double dml_socbb_return_bw_mhz(soc_bounding_box_st *box, enum voltage_state voltage);
#endif

View File

@ -130,9 +130,8 @@ failure_2:
slot = service->busyness[index_of_id];
if (slot)
kfree(slot);
};
kfree(slot);
}
failure_1:
kfree(service);
@ -171,8 +170,7 @@ void dal_gpio_service_destroy(
do {
uint32_t *slot = (*ptr)->busyness[index_of_id];
if (slot)
kfree(slot);
kfree(slot);
++index_of_id;
} while (index_of_id < GPIO_ID_COUNT);

View File

@ -35,13 +35,14 @@ enum dc_status {
DC_FAIL_CONTROLLER_VALIDATE = 5,
DC_FAIL_ENC_VALIDATE = 6,
DC_FAIL_ATTACH_SURFACES = 7,
DC_FAIL_SURFACE_VALIDATE = 8,
DC_NO_DP_LINK_BANDWIDTH = 9,
DC_EXCEED_DONGLE_MAX_CLK = 10,
DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED = 11,
DC_FAIL_BANDWIDTH_VALIDATE = 12, /* BW and Watermark validation */
DC_FAIL_SCALING = 13,
DC_FAIL_DP_LINK_TRAINING = 14,
DC_FAIL_DETACH_SURFACES = 8,
DC_FAIL_SURFACE_VALIDATE = 9,
DC_NO_DP_LINK_BANDWIDTH = 10,
DC_EXCEED_DONGLE_MAX_CLK = 11,
DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED = 12,
DC_FAIL_BANDWIDTH_VALIDATE = 13, /* BW and Watermark validation */
DC_FAIL_SCALING = 14,
DC_FAIL_DP_LINK_TRAINING = 15,
DC_ERROR_UNEXPECTED = -1
};

View File

@ -32,6 +32,7 @@
#include "ddc_service_types.h"
#include "dc_bios_types.h"
#include "mem_input.h"
#include "hubp.h"
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
#include "mpc.h"
#endif
@ -58,6 +59,11 @@ struct link_init_data {
TODO: remove it when DC is complete. */
};
enum {
FREE_ACQUIRED_RESOURCE = 0,
KEEP_ACQUIRED_RESOURCE = 1,
};
struct dc_link *link_create(const struct link_init_data *init_params);
void link_destroy(struct dc_link **link);
@ -72,12 +78,13 @@ void core_link_enable_stream(
struct dc_state *state,
struct pipe_ctx *pipe_ctx);
void core_link_disable_stream(struct pipe_ctx *pipe_ctx);
void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option);
void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable);
/********** DAL Core*********************/
#include "display_clock.h"
#include "transform.h"
#include "dpp.h"
struct resource_pool;
struct dc_state;
@ -106,7 +113,7 @@ struct resource_funcs {
const struct resource_pool *pool,
struct dc_stream_state *stream);
enum dc_status (*validate_plane)(const struct dc_plane_state *plane_state);
enum dc_status (*validate_plane)(const struct dc_plane_state *plane_state, struct dc_caps *caps);
enum dc_status (*add_stream_to_ctx)(
struct dc *dc,
@ -124,8 +131,10 @@ struct audio_support{
struct resource_pool {
struct mem_input *mis[MAX_PIPES];
struct hubp *hubps[MAX_PIPES];
struct input_pixel_processor *ipps[MAX_PIPES];
struct transform *transforms[MAX_PIPES];
struct dpp *dpps[MAX_PIPES];
struct output_pixel_processor *opps[MAX_PIPES];
struct timing_generator *timing_generators[MAX_PIPES];
struct stream_encoder *stream_enc[MAX_PIPES * 2];
@ -173,10 +182,11 @@ struct stream_resource {
struct plane_resource {
struct scaler_data scl_data;
struct hubp *hubp;
struct mem_input *mi;
struct input_pixel_processor *ipp;
struct transform *xfm;
struct dpp *dpp;
};
struct pipe_ctx {

View File

@ -0,0 +1,134 @@
/*
* Copyright 2012-15 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __DAL_DPP_H__
#define __DAL_DPP_H__
#include "transform.h"
struct dpp {
const struct dpp_funcs *funcs;
struct dc_context *ctx;
int inst;
struct dpp_caps *caps;
struct pwl_params regamma_params;
};
struct dpp_grph_csc_adjustment {
struct fixed31_32 temperature_matrix[CSC_TEMPERATURE_MATRIX_SIZE];
enum graphics_gamut_adjust_type gamut_adjust_type;
};
struct dpp_funcs {
void (*dpp_reset)(struct dpp *dpp);
void (*dpp_set_scaler)(struct dpp *dpp,
const struct scaler_data *scl_data);
void (*dpp_set_pixel_storage_depth)(
struct dpp *dpp,
enum lb_pixel_depth depth,
const struct bit_depth_reduction_params *bit_depth_params);
bool (*dpp_get_optimal_number_of_taps)(
struct dpp *dpp,
struct scaler_data *scl_data,
const struct scaling_taps *in_taps);
void (*dpp_set_gamut_remap)(
struct dpp *dpp,
const struct dpp_grph_csc_adjustment *adjust);
void (*opp_set_csc_default)(
struct dpp *dpp,
const struct default_adjustment *default_adjust);
void (*opp_set_csc_adjustment)(
struct dpp *dpp,
const struct out_csc_color_matrix *tbl_entry);
void (*opp_power_on_regamma_lut)(
struct dpp *dpp,
bool power_on);
void (*opp_program_regamma_lut)(
struct dpp *dpp,
const struct pwl_result_data *rgb,
uint32_t num);
void (*opp_configure_regamma_lut)(
struct dpp *dpp,
bool is_ram_a);
void (*opp_program_regamma_lutb_settings)(
struct dpp *dpp,
const struct pwl_params *params);
void (*opp_program_regamma_luta_settings)(
struct dpp *dpp,
const struct pwl_params *params);
void (*opp_program_regamma_pwl)(
struct dpp *dpp, const struct pwl_params *params);
void (*opp_set_regamma_mode)(
struct dpp *dpp_base,
enum opp_regamma mode);
void (*ipp_set_degamma)(
struct dpp *dpp_base,
enum ipp_degamma_mode mode);
void (*ipp_program_input_lut)(
struct dpp *dpp_base,
const struct dc_gamma *gamma);
void (*ipp_program_degamma_pwl)(struct dpp *dpp_base,
const struct pwl_params *params);
void (*ipp_setup)(
struct dpp *dpp_base,
enum surface_pixel_format input_format,
enum expansion_mode mode);
void (*ipp_full_bypass)(struct dpp *dpp_base);
void (*set_cursor_attributes)(
struct dpp *dpp_base,
const struct dc_cursor_attributes *attr);
void (*set_cursor_position)(
struct dpp *dpp_base,
const struct dc_cursor_position *pos,
const struct dc_cursor_mi_param *param,
uint32_t width
);
};
#endif

View File

@ -0,0 +1,105 @@
/*
* Copyright 2012-15 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __DAL_HUBP_H__
#define __DAL_HUBP_H__
#include "mem_input.h"
struct hubp {
struct hubp_funcs *funcs;
struct dc_context *ctx;
struct dc_plane_address request_address;
struct dc_plane_address current_address;
int inst;
int opp_id;
int mpcc_id;
struct dc_cursor_attributes curs_attr;
};
struct hubp_funcs {
void (*hubp_setup)(
struct hubp *hubp,
struct _vcs_dpi_display_dlg_regs_st *dlg_regs,
struct _vcs_dpi_display_ttu_regs_st *ttu_regs,
struct _vcs_dpi_display_rq_regs_st *rq_regs,
struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest);
void (*dcc_control)(struct hubp *hubp, bool enable,
bool independent_64b_blks);
void (*mem_program_viewport)(
struct hubp *hubp,
const struct rect *viewport,
const struct rect *viewport_c);
bool (*hubp_program_surface_flip_and_addr)(
struct hubp *hubp,
const struct dc_plane_address *address,
bool flip_immediate);
void (*hubp_program_pte_vm)(
struct hubp *hubp,
enum surface_pixel_format format,
union dc_tiling_info *tiling_info,
enum dc_rotation_angle rotation);
void (*hubp_set_vm_system_aperture_settings)(
struct hubp *hubp,
struct vm_system_aperture_param *apt);
void (*hubp_set_vm_context0_settings)(
struct hubp *hubp,
const struct vm_context0_param *vm0);
void (*hubp_program_surface_config)(
struct hubp *hubp,
enum surface_pixel_format format,
union dc_tiling_info *tiling_info,
union plane_size *plane_size,
enum dc_rotation_angle rotation,
struct dc_plane_dcc_param *dcc,
bool horizontal_mirror);
bool (*hubp_is_flip_pending)(struct hubp *hubp);
void (*hubp_update_dchub)(struct hubp *hubp,
struct dchub_init_data *dh_data);
void (*set_blank)(struct hubp *hubp, bool blank);
void (*set_hubp_blank_en)(struct hubp *hubp, bool blank);
void (*set_cursor_attributes)(
struct hubp *hubp,
const struct dc_cursor_attributes *attr);
void (*set_cursor_position)(
struct hubp *hubp,
const struct dc_cursor_position *pos,
const struct dc_cursor_mi_param *param);
};
#endif

View File

@ -111,7 +111,7 @@ struct link_encoder_funcs {
const struct dc_link_settings *link_settings,
enum clock_source_id clock_source);
void (*disable_output)(struct link_encoder *link_enc,
enum signal_type signal);
enum signal_type signal, struct dc_link *link);
void (*dp_set_lane_settings)(struct link_encoder *enc,
const struct link_training_settings *link_settings);
void (*dp_set_phy_pattern)(struct link_encoder *enc,
@ -123,10 +123,6 @@ struct link_encoder_funcs {
bool exit_link_training_required);
void (*psr_program_secondary_packet)(struct link_encoder *enc,
unsigned int sdp_transmit_line_num_deadline);
void (*backlight_control) (struct link_encoder *enc,
bool enable);
void (*power_control) (struct link_encoder *enc,
bool power_up);
void (*connect_dig_be_to_fe)(struct link_encoder *enc,
enum engine_id engine,
bool connect);

View File

@ -69,8 +69,6 @@ struct mem_input {
struct dc_plane_address request_address;
struct dc_plane_address current_address;
int inst;
int opp_id;
int mpcc_id;
struct stutter_modes stutter_mode;
};
@ -163,6 +161,15 @@ struct mem_input_funcs {
void (*set_blank)(struct mem_input *mi, bool blank);
void (*set_hubp_blank_en)(struct mem_input *mi, bool blank);
void (*set_cursor_attributes)(
struct mem_input *mem_input,
const struct dc_cursor_attributes *attr);
void (*set_cursor_position)(
struct mem_input *mem_input,
const struct dc_cursor_position *pos,
const struct dc_cursor_mi_param *param);
};
#endif

View File

@ -29,8 +29,9 @@
#include "opp.h"
struct mpcc_cfg {
struct mem_input *mi;
struct output_pixel_processor *opp;
int dpp_id;
int opp_id;
struct mpc_tree_cfg *tree_cfg;
unsigned int z_index;
struct tg_color black_color;
@ -44,11 +45,17 @@ struct mpc {
};
struct mpc_funcs {
void (*add)(struct mpc *mpc, struct mpcc_cfg *cfg);
int (*add)(struct mpc *mpc, struct mpcc_cfg *cfg);
void (*remove)(struct mpc *mpc,
struct output_pixel_processor *opp,
struct mpc_tree_cfg *tree_cfg,
int opp_id,
int mpcc_inst);
void (*wait_for_idle)(struct mpc *mpc, int id);
void (*update_blend_mode)(struct mpc *mpc, struct mpcc_cfg *cfg);
};
#endif

View File

@ -38,6 +38,7 @@ struct transform {
const struct transform_funcs *funcs;
struct dc_context *ctx;
int inst;
struct dpp_caps *caps;
struct pwl_params regamma_params;
};
@ -109,6 +110,22 @@ enum graphics_gamut_adjust_type {
GRAPHICS_GAMUT_ADJUST_TYPE_SW /* use adjustments */
};
enum lb_memory_config {
/* Enable all 3 pieces of memory */
LB_MEMORY_CONFIG_0 = 0,
/* Enable only the first piece of memory */
LB_MEMORY_CONFIG_1 = 1,
/* Enable only the second piece of memory */
LB_MEMORY_CONFIG_2 = 2,
/* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the
* last piece of chroma memory used for the luma storage
*/
LB_MEMORY_CONFIG_3 = 3
};
struct xfm_grph_csc_adjustment {
struct fixed31_32 temperature_matrix[CSC_TEMPERATURE_MATRIX_SIZE];
enum graphics_gamut_adjust_type gamut_adjust_type;
@ -238,6 +255,17 @@ struct transform_funcs {
void (*ipp_full_bypass)(struct transform *xfm_base);
void (*set_cursor_attributes)(
struct transform *xfm_base,
const struct dc_cursor_attributes *attr);
void (*set_cursor_position)(
struct transform *xfm_base,
const struct dc_cursor_position *pos,
const struct dc_cursor_mi_param *param,
uint32_t width
);
};
const uint16_t *get_filter_2tap_16p(void);
@ -251,4 +279,33 @@ const uint16_t *get_filter_6tap_64p(struct fixed31_32 ratio);
const uint16_t *get_filter_7tap_64p(struct fixed31_32 ratio);
const uint16_t *get_filter_8tap_64p(struct fixed31_32 ratio);
/* Defines the pixel processing capability of the DSCL */
enum dscl_data_processing_format {
DSCL_DATA_PRCESSING_FIXED_FORMAT, /* The DSCL processes pixel data in fixed format */
DSCL_DATA_PRCESSING_FLOAT_FORMAT, /* The DSCL processes pixel data in float format */
};
/*
* The DPP capabilities structure contains enumerations to specify the
* HW processing features and an associated function pointers to
* provide the function interface that can be overloaded for implementations
* based on different capabilities
*/
struct dpp_caps {
/* DSCL processing pixel data in fixed or float format */
enum dscl_data_processing_format dscl_data_proc_format;
/* Calculates the number of partitions in the line buffer.
* The implementation of this function is overloaded for
* different versions of DSCL LB.
*/
void (*dscl_calc_lb_num_partitions)(
const struct scaler_data *scl_data,
enum lb_memory_config lb_config,
int *num_part_y,
int *num_part_c);
};
#endif

View File

@ -28,6 +28,7 @@
#include "dc_types.h"
#include "clock_source.h"
#include "inc/hw/timing_generator.h"
#include "inc/hw/link_encoder.h"
#include "core_status.h"
enum pipe_gating_control {
@ -133,7 +134,8 @@ struct hw_sequencer_funcs {
void (*enable_stream)(struct pipe_ctx *pipe_ctx);
void (*disable_stream)(struct pipe_ctx *pipe_ctx);
void (*disable_stream)(struct pipe_ctx *pipe_ctx,
int option);
void (*unblank_stream)(struct pipe_ctx *pipe_ctx,
struct dc_link_settings *link_settings);
@ -174,8 +176,14 @@ struct hw_sequencer_funcs {
struct resource_pool *res_pool,
struct pipe_ctx *pipe_ctx);
void (*ready_shared_resources)(struct dc *dc);
void (*ready_shared_resources)(struct dc *dc, struct dc_state *context);
void (*optimize_shared_resources)(struct dc *dc);
void (*edp_power_control)(
struct link_encoder *enc,
bool enable);
void (*edp_backlight_control)(
struct dc_link *link,
bool enable);
};
void color_space_to_black_color(

View File

@ -40,6 +40,10 @@ enum dc_status core_link_write_dpcd(
const uint8_t *data,
uint32_t size);
struct gpio *get_hpd_gpio(struct dc_bios *dcb,
struct graphics_object_id link_id,
struct gpio_service *gpio_service);
void dp_enable_link_phy(
struct dc_link *link,
enum signal_type signal,

View File

@ -164,4 +164,9 @@ bool pipe_need_reprogram(
void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream,
struct bit_depth_reduction_params *fmt_bit_depth);
void update_audio_usage(
struct resource_context *res_ctx,
const struct resource_pool *pool,
struct audio *audio,
bool acquired);
#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */

View File

@ -56,5 +56,45 @@
#endif
/*
*
* general debug capabilities
*
*/
#if defined(CONFIG_DEBUG_KERNEL) || defined(CONFIG_DEBUG_DRIVER)
#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB)
#define ASSERT_CRITICAL(expr) do { \
if (WARN_ON(!(expr))) { \
kgdb_breakpoint(); \
} \
} while (0)
#else
#define ASSERT_CRITICAL(expr) do { \
if (WARN_ON(!(expr))) { \
; \
} \
} while (0)
#endif
#if defined(CONFIG_DEBUG_KERNEL_DC)
#define ASSERT(expr) ASSERT_CRITICAL(expr)
#else
#define ASSERT(expr) WARN_ON(!(expr))
#endif
#define BREAK_TO_DEBUGGER() ASSERT(0)
#endif /* CONFIG_DEBUG_KERNEL || CONFIG_DEBUG_DRIVER */
#define DC_ERR(...) do { \
dm_error(__VA_ARGS__); \
BREAK_TO_DEBUGGER(); \
} while (0)
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
#include <asm/fpu/api.h>
#endif
#endif /* _OS_TYPES_H_ */

View File

@ -58,7 +58,8 @@ static void virtual_link_encoder_enable_dp_mst_output(
static void virtual_link_encoder_disable_output(
struct link_encoder *link_enc,
enum signal_type signal) {}
enum signal_type signal,
struct dc_link *link) {}
static void virtual_link_encoder_dp_set_lane_settings(
struct link_encoder *enc,
@ -72,14 +73,6 @@ static void virtual_link_encoder_update_mst_stream_allocation_table(
struct link_encoder *enc,
const struct link_mst_stream_allocation_table *table) {}
static void virtual_link_encoder_edp_backlight_control(
struct link_encoder *enc,
bool enable) {}
static void virtual_link_encoder_edp_power_control(
struct link_encoder *enc,
bool power_up) {}
static void virtual_link_encoder_connect_dig_be_to_fe(
struct link_encoder *enc,
enum engine_id engine,
@ -105,8 +98,6 @@ static const struct link_encoder_funcs virtual_lnk_enc_funcs = {
.dp_set_phy_pattern = virtual_link_encoder_dp_set_phy_pattern,
.update_mst_stream_allocation_table =
virtual_link_encoder_update_mst_stream_allocation_table,
.backlight_control = virtual_link_encoder_edp_backlight_control,
.power_control = virtual_link_encoder_edp_power_control,
.connect_dig_be_to_fe = virtual_link_encoder_connect_dig_be_to_fe,
.destroy = virtual_link_encoder_destroy
};

View File

@ -44,6 +44,8 @@ struct dal_logger *dal_logger_create(struct dc_context *ctx, uint32_t log_mask);
uint32_t dal_logger_destroy(struct dal_logger **logger);
void dm_logger_flush_buffer(struct dal_logger *logger, bool should_warn);
void dm_logger_write(
struct dal_logger *logger,
enum dc_log_type log_type,
@ -157,4 +159,30 @@ void context_clock_trace(
#define DTN_INFO_END() \
dm_dtn_log_end(dc_ctx)
#define PERFORMANCE_TRACE_START() \
unsigned long long perf_trc_start_stmp = dm_get_timestamp(dc->ctx); \
unsigned long long perf_trc_start_log_msk = dc->ctx->logger->mask; \
unsigned int perf_trc_start_log_flags = dc->ctx->logger->flags.value; \
if (dc->debug.performance_trace) {\
dm_logger_flush_buffer(dc->ctx->logger, false);\
dc->ctx->logger->mask = 1<<LOG_PERF_TRACE;\
dc->ctx->logger->flags.bits.ENABLE_CONSOLE = 0;\
dc->ctx->logger->flags.bits.ENABLE_BUFFER = 1;\
}
#define PERFORMANCE_TRACE_END() do {\
unsigned long long perf_trc_end_stmp = dm_get_timestamp(dc->ctx);\
if (dc->debug.performance_trace) {\
dm_logger_write(dc->ctx->logger, \
LOG_PERF_TRACE, \
"%s duration: %d ticks\n", __func__,\
perf_trc_end_stmp - perf_trc_start_stmp); \
if (perf_trc_start_log_msk != 1<<LOG_PERF_TRACE) {\
dc->ctx->logger->mask = perf_trc_start_log_msk;\
dc->ctx->logger->flags.value = perf_trc_start_log_flags;\
dm_logger_flush_buffer(dc->ctx->logger, false);\
} \
} \
} while (0)
#endif /* __DAL_LOGGER_INTERFACE_H__ */

View File

@ -64,8 +64,7 @@ enum dc_log_type {
LOG_EVENT_LINK_LOSS,
LOG_EVENT_UNDERFLOW,
LOG_IF_TRACE,
LOG_HW_MARKS,
LOG_PPLIB,
LOG_PERF_TRACE,
LOG_SECTION_TOTAL_COUNT
};
@ -131,4 +130,37 @@ struct dc_log_type_info {
char name[MAX_NAME_LEN];
};
/* Structure for keeping track of offsets, buffer, etc */
#define DAL_LOGGER_BUFFER_MAX_SIZE 2048
/*Connectivity log needs to output EDID, which needs at lease 256x3 bytes,
* change log line size to 896 to meet the request.
*/
#define LOG_MAX_LINE_SIZE 896
struct dal_logger {
/* How far into the circular buffer has been read by dsat
* Read offset should never cross write offset. Write \0's to
* read data just to be sure?
*/
uint32_t buffer_read_offset;
/* How far into the circular buffer we have written
* Write offset should never cross read offset
*/
uint32_t buffer_write_offset;
uint32_t open_count;
char *log_buffer; /* Pointer to malloc'ed buffer */
uint32_t log_buffer_size; /* Size of circular buffer */
uint32_t mask; /*array of masks for major elements*/
union logger_flags flags;
struct dc_context *ctx;
};
#endif /* __DAL_LOGGER_TYPES_H__ */