mirror of
https://github.com/torvalds/linux.git
synced 2026-04-26 02:22:28 -04:00
Merge tag 'amd-drm-next-5.14-2021-06-02' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-5.14-2021-06-02:
amdgpu:
- GC/MM register access macro clean up for SR-IOV
- Beige Goby updates
- W=1 Fixes
- Aldebaran fixes
- Misc display fixes
- ACPI ATCS/ATIF handling rework
- SR-IOV fixes
- RAS fixes
- 16bpc fixed point format support
- Initial smartshift support
- RV/PCO power tuning fixes for suspend/resume
- More buffer object subclassing work
- Add new INFO query for additional vbios information
- Add new placement for preemptable SG buffers
amdkfd:
- Misc fixes
radeon:
- W=1 Fixes
- Misc cleanups
UAPI:
- Add new INFO query for additional vbios information
Useful for debugging vbios related issues. Proposed umr patch:
https://patchwork.freedesktop.org/patch/433297/
- 16bpc fixed point format support
IGT test:
https://lists.freedesktop.org/archives/igt-dev/2021-May/031507.html
Proposed Vulkan patch:
a25d480207
- Add a new GEM flag which is only used internally in the kernel driver. Userspace
is not allowed to set it.
drm:
- 16bpc fixed point format fourcc
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210602214009.4553-1-alexander.deucher@amd.com
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "dm_services_types.h"
|
||||
#include "dc.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "dc/inc/core_types.h"
|
||||
#include "dal_asic_id.h"
|
||||
#include "dmub/dmub_srv.h"
|
||||
@@ -314,10 +315,8 @@ get_crtc_by_otg_inst(struct amdgpu_device *adev,
|
||||
struct drm_crtc *crtc;
|
||||
struct amdgpu_crtc *amdgpu_crtc;
|
||||
|
||||
if (otg_inst == -1) {
|
||||
WARN_ON(1);
|
||||
if (WARN_ON(otg_inst == -1))
|
||||
return adev->mode_info.crtcs[0];
|
||||
}
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
@@ -396,8 +395,7 @@ static void dm_pflip_high_irq(void *interrupt_params)
|
||||
e = amdgpu_crtc->event;
|
||||
amdgpu_crtc->event = NULL;
|
||||
|
||||
if (!e)
|
||||
WARN_ON(1);
|
||||
WARN_ON(!e);
|
||||
|
||||
vrr_active = amdgpu_dm_vrr_active_irq(amdgpu_crtc);
|
||||
|
||||
@@ -600,14 +598,14 @@ static void dm_crtc_high_irq(void *interrupt_params)
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
/**
|
||||
* dm_dcn_vertical_interrupt0_high_irq() - Handles OTG Vertical interrupt0 for
|
||||
* DCN generation ASICs
|
||||
* @interrupt params - interrupt parameters
|
||||
* @interrupt_params: interrupt parameters
|
||||
*
|
||||
* Used to set crc window/read out crc value at vertical line 0 position
|
||||
*/
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
static void dm_dcn_vertical_interrupt0_high_irq(void *interrupt_params)
|
||||
{
|
||||
struct common_irq_params *irq_params = interrupt_params;
|
||||
@@ -981,7 +979,8 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
|
||||
abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu);
|
||||
}
|
||||
|
||||
adev->dm.dc->ctx->dmub_srv = dc_dmub_srv_create(adev->dm.dc, dmub_srv);
|
||||
if (!adev->dm.dc->ctx->dmub_srv)
|
||||
adev->dm.dc->ctx->dmub_srv = dc_dmub_srv_create(adev->dm.dc, dmub_srv);
|
||||
if (!adev->dm.dc->ctx->dmub_srv) {
|
||||
DRM_ERROR("Couldn't allocate DC DMUB server!\n");
|
||||
return -ENOMEM;
|
||||
@@ -1335,10 +1334,7 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (adev->dm.dc->ctx->dmub_srv) {
|
||||
dc_dmub_srv_destroy(&adev->dm.dc->ctx->dmub_srv);
|
||||
adev->dm.dc->ctx->dmub_srv = NULL;
|
||||
}
|
||||
dc_dmub_srv_destroy(&adev->dm.dc->ctx->dmub_srv);
|
||||
|
||||
if (dc_enable_dmub_notifications(adev->dm.dc)) {
|
||||
kfree(adev->dm.dmub_notify);
|
||||
@@ -1715,7 +1711,6 @@ static int dm_late_init(void *handle)
|
||||
unsigned int linear_lut[16];
|
||||
int i;
|
||||
struct dmcu *dmcu = NULL;
|
||||
bool ret = true;
|
||||
|
||||
dmcu = adev->dm.dc->res_pool->dmcu;
|
||||
|
||||
@@ -1732,18 +1727,23 @@ static int dm_late_init(void *handle)
|
||||
* 0xFFFF x 0.01 = 0x28F
|
||||
*/
|
||||
params.min_abm_backlight = 0x28F;
|
||||
|
||||
/* In the case where abm is implemented on dmcub,
|
||||
* dmcu object will be null.
|
||||
* ABM 2.4 and up are implemented on dmcub.
|
||||
*/
|
||||
if (dmcu)
|
||||
ret = dmcu_load_iram(dmcu, params);
|
||||
else if (adev->dm.dc->ctx->dmub_srv)
|
||||
ret = dmub_init_abm_config(adev->dm.dc->res_pool, params);
|
||||
* dmcu object will be null.
|
||||
* ABM 2.4 and up are implemented on dmcub.
|
||||
*/
|
||||
if (dmcu) {
|
||||
if (!dmcu_load_iram(dmcu, params))
|
||||
return -EINVAL;
|
||||
} else if (adev->dm.dc->ctx->dmub_srv) {
|
||||
struct dc_link *edp_links[MAX_NUM_EDP];
|
||||
int edp_num;
|
||||
|
||||
if (!ret)
|
||||
return -EINVAL;
|
||||
get_edp_links(adev->dm.dc, edp_links, &edp_num);
|
||||
for (i = 0; i < edp_num; i++) {
|
||||
if (!dmub_init_abm_config(adev->dm.dc->res_pool, params, i))
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return detect_mst_link_for_all_connectors(adev_to_drm(adev));
|
||||
}
|
||||
@@ -2008,7 +2008,6 @@ static int dm_suspend(void *handle)
|
||||
|
||||
amdgpu_dm_irq_suspend(adev);
|
||||
|
||||
|
||||
dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3);
|
||||
|
||||
return 0;
|
||||
@@ -2747,6 +2746,7 @@ static void handle_hpd_rx_irq(void *param)
|
||||
enum dc_connection_type new_connection_type = dc_connection_none;
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
union hpd_irq_data hpd_irq_data;
|
||||
bool lock_flag = 0;
|
||||
|
||||
memset(&hpd_irq_data, 0, sizeof(hpd_irq_data));
|
||||
|
||||
@@ -2776,15 +2776,28 @@ static void handle_hpd_rx_irq(void *param)
|
||||
}
|
||||
}
|
||||
|
||||
if (!amdgpu_in_reset(adev)) {
|
||||
/*
|
||||
* TODO: We need the lock to avoid touching DC state while it's being
|
||||
* modified during automated compliance testing, or when link loss
|
||||
* happens. While this should be split into subhandlers and proper
|
||||
* interfaces to avoid having to conditionally lock like this in the
|
||||
* outer layer, we need this workaround temporarily to allow MST
|
||||
* lightup in some scenarios to avoid timeout.
|
||||
*/
|
||||
if (!amdgpu_in_reset(adev) &&
|
||||
(hpd_rx_irq_check_link_loss_status(dc_link, &hpd_irq_data) ||
|
||||
hpd_irq_data.bytes.device_service_irq.bits.AUTOMATED_TEST)) {
|
||||
mutex_lock(&adev->dm.dc_lock);
|
||||
lock_flag = 1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_HDCP
|
||||
result = dc_link_handle_hpd_rx_irq(dc_link, &hpd_irq_data, NULL);
|
||||
#else
|
||||
result = dc_link_handle_hpd_rx_irq(dc_link, NULL, NULL);
|
||||
#endif
|
||||
if (!amdgpu_in_reset(adev) && lock_flag)
|
||||
mutex_unlock(&adev->dm.dc_lock);
|
||||
}
|
||||
|
||||
out:
|
||||
if (result && !is_mst_root_connector) {
|
||||
@@ -3407,7 +3420,7 @@ static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm)
|
||||
if (dm->backlight_caps.caps_valid)
|
||||
return;
|
||||
|
||||
amdgpu_acpi_get_backlight_caps(dm->adev, &caps);
|
||||
amdgpu_acpi_get_backlight_caps(&caps);
|
||||
if (caps.caps_valid) {
|
||||
dm->backlight_caps.caps_valid = true;
|
||||
if (caps.aux_support)
|
||||
@@ -3499,7 +3512,7 @@ static int amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
|
||||
rc = dc_link_set_backlight_level_nits(link[i], true, brightness[i],
|
||||
AUX_BL_DEFAULT_TRANSITION_TIME_MS);
|
||||
if (!rc) {
|
||||
DRM_ERROR("DM: Failed to update backlight via AUX on eDP[%d]\n", i);
|
||||
DRM_DEBUG("DM: Failed to update backlight via AUX on eDP[%d]\n", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3507,7 +3520,7 @@ static int amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
|
||||
for (i = 0; i < dm->num_of_edps; i++) {
|
||||
rc = dc_link_set_backlight_level(dm->backlight_link[i], brightness[i], 0);
|
||||
if (!rc) {
|
||||
DRM_ERROR("DM: Failed to update backlight on eDP[%d]\n", i);
|
||||
DRM_DEBUG("DM: Failed to update backlight on eDP[%d]\n", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -4953,6 +4966,14 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
|
||||
case DRM_FORMAT_ABGR16161616F:
|
||||
plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F;
|
||||
break;
|
||||
case DRM_FORMAT_XRGB16161616:
|
||||
case DRM_FORMAT_ARGB16161616:
|
||||
plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616;
|
||||
break;
|
||||
case DRM_FORMAT_XBGR16161616:
|
||||
case DRM_FORMAT_ABGR16161616:
|
||||
plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR(
|
||||
"Unsupported screen format %p4cc\n",
|
||||
@@ -5529,6 +5550,63 @@ static void dm_enable_per_frame_crtc_master_sync(struct dc_state *context)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
static void update_dsc_caps(struct amdgpu_dm_connector *aconnector,
|
||||
struct dc_sink *sink, struct dc_stream_state *stream,
|
||||
struct dsc_dec_dpcd_caps *dsc_caps)
|
||||
{
|
||||
stream->timing.flags.DSC = 0;
|
||||
|
||||
if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT) {
|
||||
dc_dsc_parse_dsc_dpcd(aconnector->dc_link->ctx->dc,
|
||||
aconnector->dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.raw,
|
||||
aconnector->dc_link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw,
|
||||
dsc_caps);
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
|
||||
struct dc_sink *sink, struct dc_stream_state *stream,
|
||||
struct dsc_dec_dpcd_caps *dsc_caps)
|
||||
{
|
||||
struct drm_connector *drm_connector = &aconnector->base;
|
||||
uint32_t link_bandwidth_kbps;
|
||||
|
||||
link_bandwidth_kbps = dc_link_bandwidth_kbps(aconnector->dc_link,
|
||||
dc_link_get_link_cap(aconnector->dc_link));
|
||||
/* Set DSC policy according to dsc_clock_en */
|
||||
dc_dsc_policy_set_enable_dsc_when_not_needed(
|
||||
aconnector->dsc_settings.dsc_force_enable == DSC_CLK_FORCE_ENABLE);
|
||||
|
||||
if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT) {
|
||||
|
||||
if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0],
|
||||
dsc_caps,
|
||||
aconnector->dc_link->ctx->dc->debug.dsc_min_slice_height_override,
|
||||
0,
|
||||
link_bandwidth_kbps,
|
||||
&stream->timing,
|
||||
&stream->timing.dsc_cfg)) {
|
||||
stream->timing.flags.DSC = 1;
|
||||
DRM_DEBUG_DRIVER("%s: [%s] DSC is selected from SST RX\n", __func__, drm_connector->name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Overwrite the stream flag if DSC is enabled through debugfs */
|
||||
if (aconnector->dsc_settings.dsc_force_enable == DSC_CLK_FORCE_ENABLE)
|
||||
stream->timing.flags.DSC = 1;
|
||||
|
||||
if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_num_slices_h)
|
||||
stream->timing.dsc_cfg.num_slices_h = aconnector->dsc_settings.dsc_num_slices_h;
|
||||
|
||||
if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_num_slices_v)
|
||||
stream->timing.dsc_cfg.num_slices_v = aconnector->dsc_settings.dsc_num_slices_v;
|
||||
|
||||
if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_bits_per_pixel)
|
||||
stream->timing.dsc_cfg.bits_per_pixel = aconnector->dsc_settings.dsc_bits_per_pixel;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct drm_display_mode *
|
||||
get_highest_refresh_rate_mode(struct amdgpu_dm_connector *aconnector,
|
||||
bool use_probed_modes)
|
||||
@@ -5625,12 +5703,12 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
||||
struct drm_display_mode saved_mode;
|
||||
struct drm_display_mode *freesync_mode = NULL;
|
||||
bool native_mode_found = false;
|
||||
bool recalculate_timing = dm_state ? (dm_state->scaling != RMX_OFF) : false;
|
||||
bool recalculate_timing = false;
|
||||
bool scale = dm_state ? (dm_state->scaling != RMX_OFF) : false;
|
||||
int mode_refresh;
|
||||
int preferred_refresh = 0;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
struct dsc_dec_dpcd_caps dsc_caps;
|
||||
uint32_t link_bandwidth_kbps;
|
||||
#endif
|
||||
struct dc_sink *sink = NULL;
|
||||
|
||||
@@ -5688,7 +5766,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
||||
*/
|
||||
DRM_DEBUG_DRIVER("No preferred mode found\n");
|
||||
} else {
|
||||
recalculate_timing |= amdgpu_freesync_vid_mode &&
|
||||
recalculate_timing = amdgpu_freesync_vid_mode &&
|
||||
is_freesync_video_mode(&mode, aconnector);
|
||||
if (recalculate_timing) {
|
||||
freesync_mode = get_highest_refresh_rate_mode(aconnector, false);
|
||||
@@ -5696,11 +5774,10 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
||||
mode = *freesync_mode;
|
||||
} else {
|
||||
decide_crtc_timing_for_drm_display_mode(
|
||||
&mode, preferred_mode,
|
||||
dm_state ? (dm_state->scaling != RMX_OFF) : false);
|
||||
}
|
||||
&mode, preferred_mode, scale);
|
||||
|
||||
preferred_refresh = drm_mode_vrefresh(preferred_mode);
|
||||
preferred_refresh = drm_mode_vrefresh(preferred_mode);
|
||||
}
|
||||
}
|
||||
|
||||
if (recalculate_timing)
|
||||
@@ -5712,7 +5789,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
||||
* If scaling is enabled and refresh rate didn't change
|
||||
* we copy the vic and polarities of the old timings
|
||||
*/
|
||||
if (!recalculate_timing || mode_refresh != preferred_refresh)
|
||||
if (!scale || mode_refresh != preferred_refresh)
|
||||
fill_stream_properties_from_drm_display_mode(
|
||||
stream, &mode, &aconnector->base, con_state, NULL,
|
||||
requested_bpc);
|
||||
@@ -5721,45 +5798,12 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
||||
stream, &mode, &aconnector->base, con_state, old_stream,
|
||||
requested_bpc);
|
||||
|
||||
stream->timing.flags.DSC = 0;
|
||||
|
||||
if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT) {
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
dc_dsc_parse_dsc_dpcd(aconnector->dc_link->ctx->dc,
|
||||
aconnector->dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.raw,
|
||||
aconnector->dc_link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw,
|
||||
&dsc_caps);
|
||||
link_bandwidth_kbps = dc_link_bandwidth_kbps(aconnector->dc_link,
|
||||
dc_link_get_link_cap(aconnector->dc_link));
|
||||
|
||||
if (aconnector->dsc_settings.dsc_force_enable != DSC_CLK_FORCE_DISABLE && dsc_caps.is_dsc_supported) {
|
||||
/* Set DSC policy according to dsc_clock_en */
|
||||
dc_dsc_policy_set_enable_dsc_when_not_needed(
|
||||
aconnector->dsc_settings.dsc_force_enable == DSC_CLK_FORCE_ENABLE);
|
||||
|
||||
if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0],
|
||||
&dsc_caps,
|
||||
aconnector->dc_link->ctx->dc->debug.dsc_min_slice_height_override,
|
||||
0,
|
||||
link_bandwidth_kbps,
|
||||
&stream->timing,
|
||||
&stream->timing.dsc_cfg))
|
||||
stream->timing.flags.DSC = 1;
|
||||
/* Overwrite the stream flag if DSC is enabled through debugfs */
|
||||
if (aconnector->dsc_settings.dsc_force_enable == DSC_CLK_FORCE_ENABLE)
|
||||
stream->timing.flags.DSC = 1;
|
||||
|
||||
if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_num_slices_h)
|
||||
stream->timing.dsc_cfg.num_slices_h = aconnector->dsc_settings.dsc_num_slices_h;
|
||||
|
||||
if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_num_slices_v)
|
||||
stream->timing.dsc_cfg.num_slices_v = aconnector->dsc_settings.dsc_num_slices_v;
|
||||
|
||||
if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_bits_per_pixel)
|
||||
stream->timing.dsc_cfg.bits_per_pixel = aconnector->dsc_settings.dsc_bits_per_pixel;
|
||||
}
|
||||
/* SST DSC determination policy */
|
||||
update_dsc_caps(aconnector, sink, stream, &dsc_caps);
|
||||
if (aconnector->dsc_settings.dsc_force_enable != DSC_CLK_FORCE_DISABLE && dsc_caps.is_dsc_supported)
|
||||
apply_dsc_policy_for_stream(aconnector, sink, stream, &dsc_caps);
|
||||
#endif
|
||||
}
|
||||
|
||||
update_stream_scaling_settings(&mode, dm_state, stream);
|
||||
|
||||
@@ -6558,9 +6602,8 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc,
|
||||
|
||||
dm_update_crtc_active_planes(crtc, crtc_state);
|
||||
|
||||
if (unlikely(!dm_crtc_state->stream &&
|
||||
modeset_required(crtc_state, NULL, dm_crtc_state->stream))) {
|
||||
WARN_ON(1);
|
||||
if (WARN_ON(unlikely(!dm_crtc_state->stream &&
|
||||
modeset_required(crtc_state, NULL, dm_crtc_state->stream)))) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -7059,6 +7102,10 @@ static const uint32_t rgb_formats[] = {
|
||||
DRM_FORMAT_XBGR2101010,
|
||||
DRM_FORMAT_ARGB2101010,
|
||||
DRM_FORMAT_ABGR2101010,
|
||||
DRM_FORMAT_XRGB16161616,
|
||||
DRM_FORMAT_XBGR16161616,
|
||||
DRM_FORMAT_ARGB16161616,
|
||||
DRM_FORMAT_ABGR16161616,
|
||||
DRM_FORMAT_XBGR8888,
|
||||
DRM_FORMAT_ABGR8888,
|
||||
DRM_FORMAT_RGB565,
|
||||
@@ -8967,7 +9014,10 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
||||
}
|
||||
|
||||
status = dc_stream_get_status(dm_new_crtc_state->stream);
|
||||
WARN_ON(!status);
|
||||
|
||||
if (WARN_ON(!status))
|
||||
continue;
|
||||
|
||||
WARN_ON(!status->plane_count);
|
||||
|
||||
/*
|
||||
@@ -9974,7 +10024,7 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state,
|
||||
|
||||
if (cursor_scale_w != primary_scale_w ||
|
||||
cursor_scale_h != primary_scale_h) {
|
||||
DRM_DEBUG_ATOMIC("Cursor plane scaling doesn't match primary plane\n");
|
||||
drm_dbg_atomic(crtc->dev, "Cursor plane scaling doesn't match primary plane\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -10010,11 +10060,11 @@ static int validate_overlay(struct drm_atomic_state *state)
|
||||
{
|
||||
int i;
|
||||
struct drm_plane *plane;
|
||||
struct drm_plane_state *old_plane_state, *new_plane_state;
|
||||
struct drm_plane_state *primary_state, *overlay_state = NULL;
|
||||
struct drm_plane_state *new_plane_state;
|
||||
struct drm_plane_state *primary_state, *cursor_state, *overlay_state = NULL;
|
||||
|
||||
/* Check if primary plane is contained inside overlay */
|
||||
for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
|
||||
for_each_new_plane_in_state_reverse(state, plane, new_plane_state, i) {
|
||||
if (plane->type == DRM_PLANE_TYPE_OVERLAY) {
|
||||
if (drm_atomic_plane_disabling(plane->state, new_plane_state))
|
||||
return 0;
|
||||
@@ -10041,6 +10091,14 @@ static int validate_overlay(struct drm_atomic_state *state)
|
||||
if (!primary_state->crtc)
|
||||
return 0;
|
||||
|
||||
/* check if cursor plane is enabled */
|
||||
cursor_state = drm_atomic_get_plane_state(state, overlay_state->crtc->cursor);
|
||||
if (IS_ERR(cursor_state))
|
||||
return PTR_ERR(cursor_state);
|
||||
|
||||
if (drm_atomic_plane_disabling(plane->state, cursor_state))
|
||||
return 0;
|
||||
|
||||
/* Perform the bounds check to ensure the overlay plane covers the primary */
|
||||
if (primary_state->crtc_x < overlay_state->crtc_x ||
|
||||
primary_state->crtc_y < overlay_state->crtc_y ||
|
||||
|
||||
@@ -160,6 +160,8 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto
|
||||
struct dc_sink *dc_sink = aconnector->dc_sink;
|
||||
struct drm_dp_mst_port *port = aconnector->port;
|
||||
u8 dsc_caps[16] = { 0 };
|
||||
u8 dsc_branch_dec_caps_raw[3] = { 0 }; // DSC branch decoder caps 0xA0 ~ 0xA2
|
||||
u8 *dsc_branch_dec_caps = NULL;
|
||||
|
||||
aconnector->dsc_aux = drm_dp_mst_dsc_aux_for_port(port);
|
||||
#if defined(CONFIG_HP_HOOK_WORKAROUND)
|
||||
@@ -182,9 +184,13 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto
|
||||
if (drm_dp_dpcd_read(aconnector->dsc_aux, DP_DSC_SUPPORT, dsc_caps, 16) < 0)
|
||||
return false;
|
||||
|
||||
if (drm_dp_dpcd_read(aconnector->dsc_aux,
|
||||
DP_DSC_BRANCH_OVERALL_THROUGHPUT_0, dsc_branch_dec_caps_raw, 3) == 3)
|
||||
dsc_branch_dec_caps = dsc_branch_dec_caps_raw;
|
||||
|
||||
if (!dc_dsc_parse_dsc_dpcd(aconnector->dc_link->ctx->dc,
|
||||
dsc_caps, NULL,
|
||||
&dc_sink->dsc_caps.dsc_dec_caps))
|
||||
dsc_caps, dsc_branch_dec_caps,
|
||||
&dc_sink->dsc_caps.dsc_dec_caps))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -979,7 +979,7 @@ static enum bp_result get_ss_info_from_internal_ss_info_tbl_V2_1(
|
||||
struct spread_spectrum_info *info);
|
||||
|
||||
/**
|
||||
* get_ss_info_from_table
|
||||
* get_ss_info_from_tbl
|
||||
* Get spread sprectrum information from the ASIC_InternalSS_Info Ver 2.1 or
|
||||
* SS_Info table from the VBIOS
|
||||
* There can not be more than 1 entry for ASIC_InternalSS_Info Ver 2.1 or
|
||||
@@ -1548,7 +1548,7 @@ static uint32_t get_ss_entry_number_from_ss_info_tbl(
|
||||
uint32_t id);
|
||||
|
||||
/**
|
||||
* BiosParserObject::GetNumberofSpreadSpectrumEntry
|
||||
* bios_parser_get_ss_entry_number
|
||||
* Get Number of SpreadSpectrum Entry from the ASIC_InternalSS_Info table from
|
||||
* the VBIOS that match the SSid (to be converted from signal)
|
||||
*
|
||||
@@ -1725,7 +1725,7 @@ static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_v2_1(
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* get_ss_entry_number_from_internal_ss_info_table_V3_1
|
||||
* get_ss_entry_number_from_internal_ss_info_tbl_V3_1
|
||||
* Get Number of SpreadSpectrum Entry from the ASIC_InternalSS_Info table of
|
||||
* the VBIOS that matches id
|
||||
*
|
||||
|
||||
@@ -114,7 +114,7 @@ bool dal_cmd_table_helper_controller_id_to_atom(
|
||||
}
|
||||
|
||||
/**
|
||||
* translate_transmitter_bp_to_atom - Translate the Transmitter to the
|
||||
* dal_cmd_table_helper_transmitter_bp_to_atom - Translate the Transmitter to the
|
||||
* corresponding ATOM BIOS value
|
||||
* @t: transmitter
|
||||
* returns: output digitalTransmitter
|
||||
|
||||
@@ -129,7 +129,7 @@ bool dal_cmd_table_helper_controller_id_to_atom2(
|
||||
}
|
||||
|
||||
/**
|
||||
* translate_transmitter_bp_to_atom2 - Translate the Transmitter to the
|
||||
* dal_cmd_table_helper_transmitter_bp_to_atom2 - Translate the Transmitter to the
|
||||
* corresponding ATOM BIOS value
|
||||
* @t: transmitter
|
||||
* returns: digitalTransmitter
|
||||
|
||||
@@ -2863,6 +2863,7 @@ static void populate_initial_data(
|
||||
data->bytes_per_pixel[num_displays + 4] = 4;
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
|
||||
data->bytes_per_pixel[num_displays + 4] = 8;
|
||||
break;
|
||||
@@ -2966,6 +2967,7 @@ static void populate_initial_data(
|
||||
data->bytes_per_pixel[num_displays + 4] = 4;
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
|
||||
data->bytes_per_pixel[num_displays + 4] = 8;
|
||||
break;
|
||||
|
||||
@@ -236,6 +236,7 @@ static enum dcn_bw_defs tl_pixel_format_to_bw_defs(enum surface_pixel_format for
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
|
||||
return dcn_bw_rgb_sub_32;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
|
||||
return dcn_bw_rgb_sub_64;
|
||||
@@ -375,6 +376,7 @@ static void pipe_ctx_to_e2e_pipe_params (
|
||||
input->src.viewport_height_c = input->src.viewport_height / 2;
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
|
||||
input->src.source_format = dm_444_64;
|
||||
|
||||
@@ -303,7 +303,7 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
||||
struct dc_stream_state *stream,
|
||||
struct dc_crtc_timing_adjust *adjust)
|
||||
{
|
||||
int i = 0;
|
||||
int i;
|
||||
bool ret = false;
|
||||
|
||||
stream->adjust.v_total_max = adjust->v_total_max;
|
||||
@@ -331,7 +331,7 @@ bool dc_stream_get_crtc_position(struct dc *dc,
|
||||
{
|
||||
/* TODO: Support multiple streams */
|
||||
const struct dc_stream_state *stream = streams[0];
|
||||
int i = 0;
|
||||
int i;
|
||||
bool ret = false;
|
||||
struct crtc_position position;
|
||||
|
||||
@@ -538,7 +538,7 @@ void dc_stream_set_dyn_expansion(struct dc *dc, struct dc_stream_state *stream,
|
||||
enum dc_dynamic_expansion option)
|
||||
{
|
||||
/* OPP FMT dyn expansion updates*/
|
||||
int i = 0;
|
||||
int i;
|
||||
struct pipe_ctx *pipe_ctx;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
@@ -596,7 +596,7 @@ void dc_stream_set_dither_option(struct dc_stream_state *stream,
|
||||
|
||||
bool dc_stream_set_gamut_remap(struct dc *dc, const struct dc_stream_state *stream)
|
||||
{
|
||||
int i = 0;
|
||||
int i;
|
||||
bool ret = false;
|
||||
struct pipe_ctx *pipes;
|
||||
|
||||
@@ -613,7 +613,7 @@ bool dc_stream_set_gamut_remap(struct dc *dc, const struct dc_stream_state *stre
|
||||
|
||||
bool dc_stream_program_csc_matrix(struct dc *dc, struct dc_stream_state *stream)
|
||||
{
|
||||
int i = 0;
|
||||
int i;
|
||||
bool ret = false;
|
||||
struct pipe_ctx *pipes;
|
||||
|
||||
@@ -639,8 +639,7 @@ void dc_stream_set_static_screen_params(struct dc *dc,
|
||||
int num_streams,
|
||||
const struct dc_static_screen_params *params)
|
||||
{
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int i, j;
|
||||
struct pipe_ctx *pipes_affected[MAX_PIPES];
|
||||
int num_pipes_affected = 0;
|
||||
|
||||
@@ -895,7 +894,7 @@ static void disable_all_writeback_pipes_for_stream(
|
||||
static void apply_ctx_interdependent_lock(struct dc *dc, struct dc_state *context,
|
||||
struct dc_stream_state *stream, bool lock)
|
||||
{
|
||||
int i = 0;
|
||||
int i;
|
||||
|
||||
/* Checks if interdependent update function pointer is NULL or not, takes care of DCE110 case */
|
||||
if (dc->hwss.interdependent_update_lock)
|
||||
@@ -1155,7 +1154,7 @@ static void enable_timing_multisync(
|
||||
struct dc *dc,
|
||||
struct dc_state *ctx)
|
||||
{
|
||||
int i = 0, multisync_count = 0;
|
||||
int i, multisync_count = 0;
|
||||
int pipe_count = dc->res_pool->pipe_count;
|
||||
struct pipe_ctx *multisync_pipes[MAX_PIPES] = { NULL };
|
||||
|
||||
@@ -3335,18 +3334,10 @@ void dc_hardware_release(struct dc *dc)
|
||||
#endif
|
||||
|
||||
/**
|
||||
*****************************************************************************
|
||||
* Function: dc_enable_dmub_notifications
|
||||
* dc_enable_dmub_notifications - Returns whether dmub notification can be enabled
|
||||
* @dc: dc structure
|
||||
*
|
||||
* @brief
|
||||
* Returns whether dmub notification can be enabled
|
||||
*
|
||||
* @param
|
||||
* [in] dc: dc structure
|
||||
*
|
||||
* @return
|
||||
* True to enable dmub notifications, False otherwise
|
||||
*****************************************************************************
|
||||
* Returns: True to enable dmub notifications, False otherwise
|
||||
*/
|
||||
bool dc_enable_dmub_notifications(struct dc *dc)
|
||||
{
|
||||
@@ -3355,21 +3346,13 @@ bool dc_enable_dmub_notifications(struct dc *dc)
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************
|
||||
* Function: dc_process_dmub_aux_transfer_async
|
||||
* dc_process_dmub_aux_transfer_async - Submits aux command to dmub via inbox message
|
||||
* Sets port index appropriately for legacy DDC
|
||||
* @dc: dc structure
|
||||
* @link_index: link index
|
||||
* @payload: aux payload
|
||||
*
|
||||
* @brief
|
||||
* Submits aux command to dmub via inbox message
|
||||
* Sets port index appropriately for legacy DDC
|
||||
*
|
||||
* @param
|
||||
* [in] dc: dc structure
|
||||
* [in] link_index: link index
|
||||
* [in] payload: aux payload
|
||||
*
|
||||
* @return
|
||||
* True if successful, False if failure
|
||||
*****************************************************************************
|
||||
* Returns: True if successful, False if failure
|
||||
*/
|
||||
bool dc_process_dmub_aux_transfer_async(struct dc *dc,
|
||||
uint32_t link_index,
|
||||
@@ -3428,16 +3411,8 @@ bool dc_process_dmub_aux_transfer_async(struct dc *dc,
|
||||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************
|
||||
* Function: dc_disable_accelerated_mode
|
||||
*
|
||||
* @brief
|
||||
* disable accelerated mode
|
||||
*
|
||||
* @param
|
||||
* [in] dc: dc structure
|
||||
*
|
||||
*****************************************************************************
|
||||
* dc_disable_accelerated_mode - disable accelerated mode
|
||||
* @dc: dc structure
|
||||
*/
|
||||
void dc_disable_accelerated_mode(struct dc *dc)
|
||||
{
|
||||
|
||||
@@ -25,8 +25,6 @@ static const uint8_t DP_VGA_LVDS_CONVERTER_ID_3[] = "dnomlA";
|
||||
link->ctx->logger
|
||||
#define DC_TRACE_LEVEL_MESSAGE(...) /* do nothing */
|
||||
|
||||
#define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE 0x50
|
||||
|
||||
/* maximum pre emphasis level allowed for each voltage swing level*/
|
||||
static const enum dc_pre_emphasis
|
||||
voltage_swing_to_pre_emphasis[] = { PRE_EMPHASIS_LEVEL3,
|
||||
@@ -39,14 +37,6 @@ enum {
|
||||
POST_LT_ADJ_REQ_TIMEOUT = 200
|
||||
};
|
||||
|
||||
enum {
|
||||
LINK_TRAINING_MAX_RETRY_COUNT = 5,
|
||||
/* to avoid infinite loop where-in the receiver
|
||||
* switches between different VS
|
||||
*/
|
||||
LINK_TRAINING_MAX_CR_RETRY = 100
|
||||
};
|
||||
|
||||
static bool decide_fallback_link_setting(
|
||||
struct dc_link_settings initial_link_settings,
|
||||
struct dc_link_settings *current_link_setting,
|
||||
@@ -97,7 +87,7 @@ static uint32_t get_eq_training_aux_rd_interval(
|
||||
return wait_in_micro_secs;
|
||||
}
|
||||
|
||||
static void wait_for_training_aux_rd_interval(
|
||||
void dp_wait_for_training_aux_rd_interval(
|
||||
struct dc_link *link,
|
||||
uint32_t wait_in_micro_secs)
|
||||
{
|
||||
@@ -108,7 +98,7 @@ static void wait_for_training_aux_rd_interval(
|
||||
wait_in_micro_secs);
|
||||
}
|
||||
|
||||
static enum dpcd_training_patterns
|
||||
enum dpcd_training_patterns
|
||||
dc_dp_training_pattern_to_dpcd_training_pattern(
|
||||
struct dc_link *link,
|
||||
enum dc_dp_training_pattern pattern)
|
||||
@@ -206,11 +196,12 @@ static enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *li
|
||||
return DP_TRAINING_PATTERN_SEQUENCE_2;
|
||||
}
|
||||
|
||||
static void dpcd_set_link_settings(
|
||||
enum dc_status dpcd_set_link_settings(
|
||||
struct dc_link *link,
|
||||
const struct link_training_settings *lt_settings)
|
||||
{
|
||||
uint8_t rate;
|
||||
enum dc_status status;
|
||||
|
||||
union down_spread_ctrl downspread = { {0} };
|
||||
union lane_count_set lane_count_set = { {0} };
|
||||
@@ -225,15 +216,16 @@ static void dpcd_set_link_settings(
|
||||
lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = 0;
|
||||
|
||||
|
||||
if (lt_settings->pattern_for_eq < DP_TRAINING_PATTERN_SEQUENCE_4) {
|
||||
if (link->ep_type == DISPLAY_ENDPOINT_PHY &&
|
||||
lt_settings->pattern_for_eq < DP_TRAINING_PATTERN_SEQUENCE_4) {
|
||||
lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED =
|
||||
link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED;
|
||||
}
|
||||
|
||||
core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL,
|
||||
status = core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL,
|
||||
&downspread.raw, sizeof(downspread));
|
||||
|
||||
core_link_write_dpcd(link, DP_LANE_COUNT_SET,
|
||||
status = core_link_write_dpcd(link, DP_LANE_COUNT_SET,
|
||||
&lane_count_set.raw, 1);
|
||||
|
||||
if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 &&
|
||||
@@ -249,12 +241,12 @@ static void dpcd_set_link_settings(
|
||||
core_link_read_dpcd(link, DP_SUPPORTED_LINK_RATES,
|
||||
supported_link_rates, sizeof(supported_link_rates));
|
||||
}
|
||||
core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1);
|
||||
core_link_write_dpcd(link, DP_LINK_RATE_SET,
|
||||
status = core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1);
|
||||
status = core_link_write_dpcd(link, DP_LINK_RATE_SET,
|
||||
<_settings->link_settings.link_rate_set, 1);
|
||||
} else {
|
||||
rate = (uint8_t) (lt_settings->link_settings.link_rate);
|
||||
core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1);
|
||||
status = core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1);
|
||||
}
|
||||
|
||||
if (rate) {
|
||||
@@ -278,9 +270,11 @@ static void dpcd_set_link_settings(
|
||||
DP_DOWNSPREAD_CTRL,
|
||||
lt_settings->link_settings.link_spread);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static uint8_t dc_dp_initialize_scrambling_data_symbols(
|
||||
uint8_t dc_dp_initialize_scrambling_data_symbols(
|
||||
struct dc_link *link,
|
||||
enum dc_dp_training_pattern pattern)
|
||||
{
|
||||
@@ -429,7 +423,7 @@ static void dpcd_set_lt_pattern_and_lane_settings(
|
||||
link->cur_lane_setting = lt_settings->lane_settings[0];
|
||||
}
|
||||
|
||||
static bool is_cr_done(enum dc_lane_count ln_count,
|
||||
bool dp_is_cr_done(enum dc_lane_count ln_count,
|
||||
union lane_status *dpcd_lane_status)
|
||||
{
|
||||
uint32_t lane;
|
||||
@@ -468,7 +462,7 @@ static inline bool is_interlane_aligned(union lane_align_status_updated align_st
|
||||
return align_status.bits.INTERLANE_ALIGN_DONE == 1;
|
||||
}
|
||||
|
||||
static void update_drive_settings(
|
||||
void dp_update_drive_settings(
|
||||
struct link_training_settings *dest,
|
||||
struct link_training_settings src)
|
||||
{
|
||||
@@ -612,7 +606,7 @@ static void find_max_drive_settings(
|
||||
|
||||
}
|
||||
|
||||
static void get_lane_status_and_drive_settings(
|
||||
enum dc_status dp_get_lane_status_and_drive_settings(
|
||||
struct dc_link *link,
|
||||
const struct link_training_settings *link_training_setting,
|
||||
union lane_status *ln_status,
|
||||
@@ -627,6 +621,7 @@ static void get_lane_status_and_drive_settings(
|
||||
union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
|
||||
struct link_training_settings request_settings = { {0} };
|
||||
uint32_t lane;
|
||||
enum dc_status status;
|
||||
|
||||
memset(req_settings, '\0', sizeof(struct link_training_settings));
|
||||
|
||||
@@ -637,7 +632,7 @@ static void get_lane_status_and_drive_settings(
|
||||
lane_adjust_offset = 3;
|
||||
}
|
||||
|
||||
core_link_read_dpcd(
|
||||
status = core_link_read_dpcd(
|
||||
link,
|
||||
lane01_status_address,
|
||||
(uint8_t *)(dpcd_buf),
|
||||
@@ -725,9 +720,10 @@ static void get_lane_status_and_drive_settings(
|
||||
* read DpcdAddress_AdjustRequestPostCursor2 = 0x020C
|
||||
*/
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void dpcd_set_lane_settings(
|
||||
enum dc_status dpcd_set_lane_settings(
|
||||
struct dc_link *link,
|
||||
const struct link_training_settings *link_training_setting,
|
||||
uint32_t offset)
|
||||
@@ -735,6 +731,7 @@ static void dpcd_set_lane_settings(
|
||||
union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = {{{0}}};
|
||||
uint32_t lane;
|
||||
unsigned int lane0_set_address;
|
||||
enum dc_status status;
|
||||
|
||||
lane0_set_address = DP_TRAINING_LANE0_SET;
|
||||
|
||||
@@ -762,7 +759,7 @@ static void dpcd_set_lane_settings(
|
||||
PRE_EMPHASIS_MAX_LEVEL ? 1 : 0);
|
||||
}
|
||||
|
||||
core_link_write_dpcd(link,
|
||||
status = core_link_write_dpcd(link,
|
||||
lane0_set_address,
|
||||
(uint8_t *)(dpcd_lane),
|
||||
link_training_setting->link_settings.lane_count);
|
||||
@@ -808,9 +805,10 @@ static void dpcd_set_lane_settings(
|
||||
}
|
||||
link->cur_lane_setting = link_training_setting->lane_settings[0];
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static bool is_max_vs_reached(
|
||||
bool dp_is_max_vs_reached(
|
||||
const struct link_training_settings *lt_settings)
|
||||
{
|
||||
uint32_t lane;
|
||||
@@ -852,19 +850,19 @@ static bool perform_post_lt_adj_req_sequence(
|
||||
union lane_align_status_updated
|
||||
dpcd_lane_status_updated;
|
||||
|
||||
get_lane_status_and_drive_settings(
|
||||
link,
|
||||
lt_settings,
|
||||
dpcd_lane_status,
|
||||
&dpcd_lane_status_updated,
|
||||
&req_settings,
|
||||
DPRX);
|
||||
dp_get_lane_status_and_drive_settings(
|
||||
link,
|
||||
lt_settings,
|
||||
dpcd_lane_status,
|
||||
&dpcd_lane_status_updated,
|
||||
&req_settings,
|
||||
DPRX);
|
||||
|
||||
if (dpcd_lane_status_updated.bits.
|
||||
POST_LT_ADJ_REQ_IN_PROGRESS == 0)
|
||||
return true;
|
||||
|
||||
if (!is_cr_done(lane_count, dpcd_lane_status))
|
||||
if (!dp_is_cr_done(lane_count, dpcd_lane_status))
|
||||
return false;
|
||||
|
||||
if (!is_ch_eq_done(lane_count, dpcd_lane_status) ||
|
||||
@@ -887,7 +885,7 @@ static bool perform_post_lt_adj_req_sequence(
|
||||
}
|
||||
|
||||
if (req_drv_setting_changed) {
|
||||
update_drive_settings(
|
||||
dp_update_drive_settings(
|
||||
lt_settings, req_settings);
|
||||
|
||||
dc_link_dp_set_drive_settings(link,
|
||||
@@ -939,7 +937,7 @@ static uint32_t translate_training_aux_read_interval(uint32_t dpcd_aux_read_inte
|
||||
return aux_rd_interval_us;
|
||||
}
|
||||
|
||||
static enum link_training_result get_cr_failure(enum dc_lane_count ln_count,
|
||||
enum link_training_result dp_get_cr_failure(enum dc_lane_count ln_count,
|
||||
union lane_status *dpcd_lane_status)
|
||||
{
|
||||
enum link_training_result result = LINK_TRAINING_SUCCESS;
|
||||
@@ -1003,14 +1001,14 @@ static enum link_training_result perform_channel_equalization_sequence(
|
||||
translate_training_aux_read_interval(
|
||||
link->dpcd_caps.lttpr_caps.aux_rd_interval[offset - 1]);
|
||||
|
||||
wait_for_training_aux_rd_interval(
|
||||
dp_wait_for_training_aux_rd_interval(
|
||||
link,
|
||||
wait_time_microsec);
|
||||
|
||||
/* 4. Read lane status and requested
|
||||
* drive settings as set by the sink*/
|
||||
|
||||
get_lane_status_and_drive_settings(
|
||||
dp_get_lane_status_and_drive_settings(
|
||||
link,
|
||||
lt_settings,
|
||||
dpcd_lane_status,
|
||||
@@ -1019,7 +1017,7 @@ static enum link_training_result perform_channel_equalization_sequence(
|
||||
offset);
|
||||
|
||||
/* 5. check CR done*/
|
||||
if (!is_cr_done(lane_count, dpcd_lane_status))
|
||||
if (!dp_is_cr_done(lane_count, dpcd_lane_status))
|
||||
return LINK_TRAINING_EQ_FAIL_CR;
|
||||
|
||||
/* 6. check CHEQ done*/
|
||||
@@ -1029,13 +1027,12 @@ static enum link_training_result perform_channel_equalization_sequence(
|
||||
return LINK_TRAINING_SUCCESS;
|
||||
|
||||
/* 7. update VS/PE/PC2 in lt_settings*/
|
||||
update_drive_settings(lt_settings, req_settings);
|
||||
dp_update_drive_settings(lt_settings, req_settings);
|
||||
}
|
||||
|
||||
return LINK_TRAINING_EQ_FAIL_EQ;
|
||||
|
||||
}
|
||||
#define TRAINING_AUX_RD_INTERVAL 100 //us
|
||||
|
||||
static void start_clock_recovery_pattern_early(struct dc_link *link,
|
||||
struct link_training_settings *lt_settings,
|
||||
@@ -1106,14 +1103,14 @@ static enum link_training_result perform_clock_recovery_sequence(
|
||||
if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT)
|
||||
wait_time_microsec = TRAINING_AUX_RD_INTERVAL;
|
||||
|
||||
wait_for_training_aux_rd_interval(
|
||||
dp_wait_for_training_aux_rd_interval(
|
||||
link,
|
||||
wait_time_microsec);
|
||||
|
||||
/* 4. Read lane status and requested drive
|
||||
* settings as set by the sink
|
||||
*/
|
||||
get_lane_status_and_drive_settings(
|
||||
dp_get_lane_status_and_drive_settings(
|
||||
link,
|
||||
lt_settings,
|
||||
dpcd_lane_status,
|
||||
@@ -1122,11 +1119,11 @@ static enum link_training_result perform_clock_recovery_sequence(
|
||||
offset);
|
||||
|
||||
/* 5. check CR done*/
|
||||
if (is_cr_done(lane_count, dpcd_lane_status))
|
||||
if (dp_is_cr_done(lane_count, dpcd_lane_status))
|
||||
return LINK_TRAINING_SUCCESS;
|
||||
|
||||
/* 6. max VS reached*/
|
||||
if (is_max_vs_reached(lt_settings))
|
||||
if (dp_is_max_vs_reached(lt_settings))
|
||||
break;
|
||||
|
||||
/* 7. same lane settings*/
|
||||
@@ -1141,7 +1138,7 @@ static enum link_training_result perform_clock_recovery_sequence(
|
||||
retries_cr = 0;
|
||||
|
||||
/* 8. update VS/PE/PC2 in lt_settings*/
|
||||
update_drive_settings(lt_settings, req_settings);
|
||||
dp_update_drive_settings(lt_settings, req_settings);
|
||||
|
||||
retry_count++;
|
||||
}
|
||||
@@ -1154,7 +1151,7 @@ static enum link_training_result perform_clock_recovery_sequence(
|
||||
|
||||
}
|
||||
|
||||
return get_cr_failure(lane_count, dpcd_lane_status);
|
||||
return dp_get_cr_failure(lane_count, dpcd_lane_status);
|
||||
}
|
||||
|
||||
static inline enum link_training_result dp_transition_to_video_idle(
|
||||
@@ -1173,8 +1170,16 @@ static inline enum link_training_result dp_transition_to_video_idle(
|
||||
* TPS4 must be used instead of POST_LT_ADJ_REQ.
|
||||
*/
|
||||
if (link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED != 1 ||
|
||||
lt_settings->pattern_for_eq == DP_TRAINING_PATTERN_SEQUENCE_4)
|
||||
lt_settings->pattern_for_eq == DP_TRAINING_PATTERN_SEQUENCE_4) {
|
||||
/* delay 5ms after Main Link output idle pattern and then check
|
||||
* DPCD 0202h.
|
||||
*/
|
||||
if (link->connector_signal != SIGNAL_TYPE_EDP && status == LINK_TRAINING_SUCCESS) {
|
||||
msleep(5);
|
||||
status = dp_check_link_loss_status(link, lt_settings);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
if (status == LINK_TRAINING_SUCCESS &&
|
||||
perform_post_lt_adj_req_sequence(link, lt_settings) == false)
|
||||
@@ -1327,9 +1332,14 @@ static inline void decide_8b_10b_training_settings(
|
||||
lt_settings->enhanced_framing = *overrides->enhanced_framing;
|
||||
else
|
||||
lt_settings->enhanced_framing = 1;
|
||||
|
||||
if (link->preferred_training_settings.fec_enable != NULL)
|
||||
lt_settings->should_set_fec_ready = *link->preferred_training_settings.fec_enable;
|
||||
else
|
||||
lt_settings->should_set_fec_ready = true;
|
||||
}
|
||||
|
||||
static void decide_training_settings(
|
||||
void dp_decide_training_settings(
|
||||
struct dc_link *link,
|
||||
const struct dc_link_settings *link_settings,
|
||||
const struct dc_link_training_overrides *overrides,
|
||||
@@ -1365,18 +1375,18 @@ uint8_t dp_convert_to_count(uint8_t lttpr_repeater_count)
|
||||
return 0; // invalid value
|
||||
}
|
||||
|
||||
static void configure_lttpr_mode_transparent(struct dc_link *link)
|
||||
enum dc_status configure_lttpr_mode_transparent(struct dc_link *link)
|
||||
{
|
||||
uint8_t repeater_mode = DP_PHY_REPEATER_MODE_TRANSPARENT;
|
||||
|
||||
DC_LOG_HW_LINK_TRAINING("%s\n Set LTTPR to Transparent Mode\n", __func__);
|
||||
core_link_write_dpcd(link,
|
||||
return core_link_write_dpcd(link,
|
||||
DP_PHY_REPEATER_MODE,
|
||||
(uint8_t *)&repeater_mode,
|
||||
sizeof(repeater_mode));
|
||||
}
|
||||
|
||||
static void configure_lttpr_mode_non_transparent(
|
||||
enum dc_status configure_lttpr_mode_non_transparent(
|
||||
struct dc_link *link,
|
||||
const struct link_training_settings *lt_settings)
|
||||
{
|
||||
@@ -1431,6 +1441,8 @@ static void configure_lttpr_mode_non_transparent(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void repeater_training_done(struct dc_link *link, uint32_t offset)
|
||||
@@ -1564,7 +1576,7 @@ bool dc_link_dp_perform_link_training_skip_aux(
|
||||
{
|
||||
struct link_training_settings lt_settings;
|
||||
|
||||
decide_training_settings(
|
||||
dp_decide_training_settings(
|
||||
link,
|
||||
link_setting,
|
||||
&link->preferred_training_settings,
|
||||
@@ -1579,7 +1591,7 @@ bool dc_link_dp_perform_link_training_skip_aux(
|
||||
dp_set_hw_lane_settings(link, <_settings, DPRX);
|
||||
|
||||
/* wait receiver to lock-on*/
|
||||
wait_for_training_aux_rd_interval(link, lt_settings.cr_pattern_time);
|
||||
dp_wait_for_training_aux_rd_interval(link, lt_settings.cr_pattern_time);
|
||||
|
||||
/* 2. Perform_channel_equalization_sequence. */
|
||||
|
||||
@@ -1590,7 +1602,7 @@ bool dc_link_dp_perform_link_training_skip_aux(
|
||||
dp_set_hw_lane_settings(link, <_settings, DPRX);
|
||||
|
||||
/* wait receiver to lock-on. */
|
||||
wait_for_training_aux_rd_interval(link, lt_settings.eq_pattern_time);
|
||||
dp_wait_for_training_aux_rd_interval(link, lt_settings.eq_pattern_time);
|
||||
|
||||
/* 3. Perform_link_training_int. */
|
||||
|
||||
@@ -1602,42 +1614,61 @@ bool dc_link_dp_perform_link_training_skip_aux(
|
||||
return true;
|
||||
}
|
||||
|
||||
enum link_training_result dc_link_dp_perform_link_training(
|
||||
struct dc_link *link,
|
||||
const struct dc_link_settings *link_setting,
|
||||
bool skip_video_pattern)
|
||||
enum dc_status dpcd_configure_lttpr_mode(struct dc_link *link, struct link_training_settings *lt_settings)
|
||||
{
|
||||
enum dc_status status = DC_OK;
|
||||
|
||||
if (lt_settings->lttpr_mode == LTTPR_MODE_TRANSPARENT)
|
||||
status = configure_lttpr_mode_transparent(link);
|
||||
|
||||
else if (lt_settings->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT)
|
||||
status = configure_lttpr_mode_non_transparent(link, lt_settings);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void dpcd_exit_training_mode(struct dc_link *link)
|
||||
{
|
||||
|
||||
/* clear training pattern set */
|
||||
dpcd_set_training_pattern(link, DP_TRAINING_PATTERN_VIDEOIDLE);
|
||||
}
|
||||
|
||||
enum dc_status dpcd_configure_channel_coding(struct dc_link *link,
|
||||
struct link_training_settings *lt_settings)
|
||||
{
|
||||
enum dp_link_encoding encoding =
|
||||
dp_get_link_encoding_format(
|
||||
<_settings->link_settings);
|
||||
enum dc_status status;
|
||||
|
||||
status = core_link_write_dpcd(
|
||||
link,
|
||||
DP_MAIN_LINK_CHANNEL_CODING_SET,
|
||||
(uint8_t *) &encoding,
|
||||
1);
|
||||
DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X MAIN_LINK_CHANNEL_CODING_SET = %x\n",
|
||||
__func__,
|
||||
DP_MAIN_LINK_CHANNEL_CODING_SET,
|
||||
encoding);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static enum link_training_result dp_perform_8b_10b_link_training(
|
||||
struct dc_link *link,
|
||||
struct link_training_settings *lt_settings)
|
||||
{
|
||||
enum link_training_result status = LINK_TRAINING_SUCCESS;
|
||||
struct link_training_settings lt_settings;
|
||||
|
||||
bool fec_enable;
|
||||
uint8_t repeater_cnt;
|
||||
uint8_t repeater_id;
|
||||
|
||||
decide_training_settings(
|
||||
link,
|
||||
link_setting,
|
||||
&link->preferred_training_settings,
|
||||
<_settings);
|
||||
|
||||
/* Configure lttpr mode */
|
||||
if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT)
|
||||
configure_lttpr_mode_non_transparent(link, <_settings);
|
||||
else if (link->lttpr_mode == LTTPR_MODE_TRANSPARENT)
|
||||
configure_lttpr_mode_transparent(link);
|
||||
|
||||
if (link->ctx->dc->work_arounds.lt_early_cr_pattern)
|
||||
start_clock_recovery_pattern_early(link, <_settings, DPRX);
|
||||
start_clock_recovery_pattern_early(link, lt_settings, DPRX);
|
||||
|
||||
/* 1. set link rate, lane count and spread. */
|
||||
dpcd_set_link_settings(link, <_settings);
|
||||
|
||||
if (link->preferred_training_settings.fec_enable != NULL)
|
||||
fec_enable = *link->preferred_training_settings.fec_enable;
|
||||
else
|
||||
fec_enable = true;
|
||||
|
||||
dp_set_fec_ready(link, fec_enable);
|
||||
dpcd_set_link_settings(link, lt_settings);
|
||||
|
||||
if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) {
|
||||
|
||||
@@ -1648,13 +1679,13 @@ enum link_training_result dc_link_dp_perform_link_training(
|
||||
|
||||
for (repeater_id = repeater_cnt; (repeater_id > 0 && status == LINK_TRAINING_SUCCESS);
|
||||
repeater_id--) {
|
||||
status = perform_clock_recovery_sequence(link, <_settings, repeater_id);
|
||||
status = perform_clock_recovery_sequence(link, lt_settings, repeater_id);
|
||||
|
||||
if (status != LINK_TRAINING_SUCCESS)
|
||||
break;
|
||||
|
||||
status = perform_channel_equalization_sequence(link,
|
||||
<_settings,
|
||||
lt_settings,
|
||||
repeater_id);
|
||||
|
||||
if (status != LINK_TRAINING_SUCCESS)
|
||||
@@ -1665,36 +1696,62 @@ enum link_training_result dc_link_dp_perform_link_training(
|
||||
}
|
||||
|
||||
if (status == LINK_TRAINING_SUCCESS) {
|
||||
status = perform_clock_recovery_sequence(link, <_settings, DPRX);
|
||||
status = perform_clock_recovery_sequence(link, lt_settings, DPRX);
|
||||
if (status == LINK_TRAINING_SUCCESS) {
|
||||
status = perform_channel_equalization_sequence(link,
|
||||
<_settings,
|
||||
lt_settings,
|
||||
DPRX);
|
||||
}
|
||||
}
|
||||
|
||||
/* 3. set training not in progress*/
|
||||
dpcd_set_training_pattern(link, DP_TRAINING_PATTERN_VIDEOIDLE);
|
||||
if ((status == LINK_TRAINING_SUCCESS) || !skip_video_pattern) {
|
||||
return status;
|
||||
}
|
||||
|
||||
enum link_training_result dc_link_dp_perform_link_training(
|
||||
struct dc_link *link,
|
||||
const struct dc_link_settings *link_settings,
|
||||
bool skip_video_pattern)
|
||||
{
|
||||
enum link_training_result status = LINK_TRAINING_SUCCESS;
|
||||
struct link_training_settings lt_settings;
|
||||
enum dp_link_encoding encoding =
|
||||
dp_get_link_encoding_format(link_settings);
|
||||
|
||||
/* decide training settings */
|
||||
dp_decide_training_settings(
|
||||
link,
|
||||
link_settings,
|
||||
&link->preferred_training_settings,
|
||||
<_settings);
|
||||
|
||||
/* reset previous training states */
|
||||
dpcd_exit_training_mode(link);
|
||||
|
||||
/* configure link prior to entering training mode */
|
||||
dpcd_configure_lttpr_mode(link, <_settings);
|
||||
dp_set_fec_ready(link, lt_settings.should_set_fec_ready);
|
||||
dpcd_configure_channel_coding(link, <_settings);
|
||||
|
||||
/* enter training mode:
|
||||
* Per DP specs starting from here, DPTX device shall not issue
|
||||
* Non-LT AUX transactions inside training mode.
|
||||
*/
|
||||
if (encoding == DP_8b_10b_ENCODING)
|
||||
status = dp_perform_8b_10b_link_training(link, <_settings);
|
||||
else
|
||||
ASSERT(0);
|
||||
|
||||
/* exit training mode and switch to video idle */
|
||||
dpcd_exit_training_mode(link);
|
||||
if ((status == LINK_TRAINING_SUCCESS) || !skip_video_pattern)
|
||||
status = dp_transition_to_video_idle(link,
|
||||
<_settings,
|
||||
status);
|
||||
}
|
||||
|
||||
/* delay 5ms after Main Link output idle pattern and then check
|
||||
* DPCD 0202h.
|
||||
*/
|
||||
if (link->connector_signal != SIGNAL_TYPE_EDP && status == LINK_TRAINING_SUCCESS) {
|
||||
msleep(5);
|
||||
status = dp_check_link_loss_status(link, <_settings);
|
||||
}
|
||||
|
||||
/* 6. print status message*/
|
||||
/* dump debug data */
|
||||
print_status_message(link, <_settings, status);
|
||||
|
||||
if (status != LINK_TRAINING_SUCCESS)
|
||||
link->ctx->dc->debug_data.ltFailCount++;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1899,7 +1956,7 @@ enum link_training_result dc_link_dp_sync_lt_attempt(
|
||||
enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_EXTERNAL;
|
||||
bool fec_enable = false;
|
||||
|
||||
decide_training_settings(
|
||||
dp_decide_training_settings(
|
||||
link,
|
||||
link_settings,
|
||||
lt_overrides,
|
||||
@@ -2070,7 +2127,7 @@ enum dc_status read_hpd_rx_irq_data(
|
||||
return retval;
|
||||
}
|
||||
|
||||
static bool hpd_rx_irq_check_link_loss_status(
|
||||
bool hpd_rx_irq_check_link_loss_status(
|
||||
struct dc_link *link,
|
||||
union hpd_irq_data *hpd_irq_dpcd_data)
|
||||
{
|
||||
@@ -4606,50 +4663,74 @@ enum dp_panel_mode dp_get_panel_mode(struct dc_link *link)
|
||||
return DP_PANEL_MODE_DEFAULT;
|
||||
}
|
||||
|
||||
void dp_set_fec_ready(struct dc_link *link, bool ready)
|
||||
enum dc_status dp_set_fec_ready(struct dc_link *link, bool ready)
|
||||
{
|
||||
/* FEC has to be "set ready" before the link training.
|
||||
* The policy is to always train with FEC
|
||||
* if the sink supports it and leave it enabled on link.
|
||||
* If FEC is not supported, disable it.
|
||||
*/
|
||||
struct link_encoder *link_enc = link->link_enc;
|
||||
struct link_encoder *link_enc = NULL;
|
||||
enum dc_status status = DC_OK;
|
||||
uint8_t fec_config = 0;
|
||||
|
||||
/* Access link encoder based on whether it is statically
|
||||
* or dynamically assigned to a link.
|
||||
*/
|
||||
if (link->is_dig_mapping_flexible &&
|
||||
link->dc->res_pool->funcs->link_encs_assign)
|
||||
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link);
|
||||
else
|
||||
link_enc = link->link_enc;
|
||||
ASSERT(link_enc);
|
||||
|
||||
if (!dc_link_should_enable_fec(link))
|
||||
return;
|
||||
return status;
|
||||
|
||||
if (link_enc->funcs->fec_set_ready &&
|
||||
link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
|
||||
if (ready) {
|
||||
fec_config = 1;
|
||||
if (core_link_write_dpcd(link,
|
||||
status = core_link_write_dpcd(link,
|
||||
DP_FEC_CONFIGURATION,
|
||||
&fec_config,
|
||||
sizeof(fec_config)) == DC_OK) {
|
||||
sizeof(fec_config));
|
||||
if (status == DC_OK) {
|
||||
link_enc->funcs->fec_set_ready(link_enc, true);
|
||||
link->fec_state = dc_link_fec_ready;
|
||||
} else {
|
||||
link->link_enc->funcs->fec_set_ready(link->link_enc, false);
|
||||
link_enc->funcs->fec_set_ready(link->link_enc, false);
|
||||
link->fec_state = dc_link_fec_not_ready;
|
||||
dm_error("dpcd write failed to set fec_ready");
|
||||
}
|
||||
} else if (link->fec_state == dc_link_fec_ready) {
|
||||
fec_config = 0;
|
||||
core_link_write_dpcd(link,
|
||||
status = core_link_write_dpcd(link,
|
||||
DP_FEC_CONFIGURATION,
|
||||
&fec_config,
|
||||
sizeof(fec_config));
|
||||
link->link_enc->funcs->fec_set_ready(
|
||||
link->link_enc, false);
|
||||
link_enc->funcs->fec_set_ready(link_enc, false);
|
||||
link->fec_state = dc_link_fec_not_ready;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void dp_set_fec_enable(struct dc_link *link, bool enable)
|
||||
{
|
||||
struct link_encoder *link_enc = link->link_enc;
|
||||
struct link_encoder *link_enc = NULL;
|
||||
|
||||
/* Access link encoder based on whether it is statically
|
||||
* or dynamically assigned to a link.
|
||||
*/
|
||||
if (link->is_dig_mapping_flexible &&
|
||||
link->dc->res_pool->funcs->link_encs_assign)
|
||||
link_enc = link_enc_cfg_get_link_enc_used_by_link(
|
||||
link->dc->current_state, link);
|
||||
else
|
||||
link_enc = link->link_enc;
|
||||
ASSERT(link_enc);
|
||||
|
||||
if (!dc_link_should_enable_fec(link))
|
||||
return;
|
||||
|
||||
@@ -611,6 +611,7 @@ static enum pixel_format convert_pixel_format_to_dalsurface(
|
||||
dal_pixel_format = PIXEL_FORMAT_420BPP10;
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
|
||||
default:
|
||||
dal_pixel_format = PIXEL_FORMAT_UNKNOWN;
|
||||
break;
|
||||
@@ -701,124 +702,23 @@ static void calculate_split_count_and_index(struct pipe_ctx *pipe_ctx, int *spli
|
||||
}
|
||||
}
|
||||
|
||||
static void calculate_viewport(struct pipe_ctx *pipe_ctx)
|
||||
/*
|
||||
* This is a preliminary vp size calculation to allow us to check taps support.
|
||||
* The result is completely overridden afterwards.
|
||||
*/
|
||||
static void calculate_viewport_size(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
|
||||
const struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
struct scaler_data *data = &pipe_ctx->plane_res.scl_data;
|
||||
struct rect surf_src = plane_state->src_rect;
|
||||
struct rect clip, dest;
|
||||
int vpc_div = (data->format == PIXEL_FORMAT_420BPP8
|
||||
|| data->format == PIXEL_FORMAT_420BPP10) ? 2 : 1;
|
||||
int split_count = 0;
|
||||
int split_idx = 0;
|
||||
bool orthogonal_rotation, flip_y_start, flip_x_start;
|
||||
|
||||
calculate_split_count_and_index(pipe_ctx, &split_count, &split_idx);
|
||||
|
||||
if (stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE ||
|
||||
stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM) {
|
||||
split_count = 0;
|
||||
split_idx = 0;
|
||||
data->viewport.width = dc_fixpt_ceil(dc_fixpt_mul_int(data->ratios.horz, data->recout.width));
|
||||
data->viewport.height = dc_fixpt_ceil(dc_fixpt_mul_int(data->ratios.vert, data->recout.height));
|
||||
data->viewport_c.width = dc_fixpt_ceil(dc_fixpt_mul_int(data->ratios.horz_c, data->recout.width));
|
||||
data->viewport_c.height = dc_fixpt_ceil(dc_fixpt_mul_int(data->ratios.vert_c, data->recout.height));
|
||||
if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 ||
|
||||
pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) {
|
||||
swap(data->viewport.width, data->viewport.height);
|
||||
swap(data->viewport_c.width, data->viewport_c.height);
|
||||
}
|
||||
|
||||
/* The actual clip is an intersection between stream
|
||||
* source and surface clip
|
||||
*/
|
||||
dest = plane_state->dst_rect;
|
||||
clip.x = stream->src.x > plane_state->clip_rect.x ?
|
||||
stream->src.x : plane_state->clip_rect.x;
|
||||
|
||||
clip.width = stream->src.x + stream->src.width <
|
||||
plane_state->clip_rect.x + plane_state->clip_rect.width ?
|
||||
stream->src.x + stream->src.width - clip.x :
|
||||
plane_state->clip_rect.x + plane_state->clip_rect.width - clip.x ;
|
||||
|
||||
clip.y = stream->src.y > plane_state->clip_rect.y ?
|
||||
stream->src.y : plane_state->clip_rect.y;
|
||||
|
||||
clip.height = stream->src.y + stream->src.height <
|
||||
plane_state->clip_rect.y + plane_state->clip_rect.height ?
|
||||
stream->src.y + stream->src.height - clip.y :
|
||||
plane_state->clip_rect.y + plane_state->clip_rect.height - clip.y ;
|
||||
|
||||
/*
|
||||
* Need to calculate how scan origin is shifted in vp space
|
||||
* to correctly rotate clip and dst
|
||||
*/
|
||||
get_vp_scan_direction(
|
||||
plane_state->rotation,
|
||||
plane_state->horizontal_mirror,
|
||||
&orthogonal_rotation,
|
||||
&flip_y_start,
|
||||
&flip_x_start);
|
||||
|
||||
if (orthogonal_rotation) {
|
||||
swap(clip.x, clip.y);
|
||||
swap(clip.width, clip.height);
|
||||
swap(dest.x, dest.y);
|
||||
swap(dest.width, dest.height);
|
||||
}
|
||||
if (flip_x_start) {
|
||||
clip.x = dest.x + dest.width - clip.x - clip.width;
|
||||
dest.x = 0;
|
||||
}
|
||||
if (flip_y_start) {
|
||||
clip.y = dest.y + dest.height - clip.y - clip.height;
|
||||
dest.y = 0;
|
||||
}
|
||||
|
||||
/* offset = surf_src.ofs + (clip.ofs - surface->dst_rect.ofs) * scl_ratio
|
||||
* num_pixels = clip.num_pix * scl_ratio
|
||||
*/
|
||||
data->viewport.x = surf_src.x + (clip.x - dest.x) * surf_src.width / dest.width;
|
||||
data->viewport.width = clip.width * surf_src.width / dest.width;
|
||||
|
||||
data->viewport.y = surf_src.y + (clip.y - dest.y) * surf_src.height / dest.height;
|
||||
data->viewport.height = clip.height * surf_src.height / dest.height;
|
||||
|
||||
/* Handle split */
|
||||
if (split_count) {
|
||||
/* extra pixels in the division remainder need to go to pipes after
|
||||
* the extra pixel index minus one(epimo) defined here as:
|
||||
*/
|
||||
int epimo = 0;
|
||||
|
||||
if (orthogonal_rotation) {
|
||||
if (flip_y_start)
|
||||
split_idx = split_count - split_idx;
|
||||
|
||||
epimo = split_count - data->viewport.height % (split_count + 1);
|
||||
|
||||
data->viewport.y += (data->viewport.height / (split_count + 1)) * split_idx;
|
||||
if (split_idx > epimo)
|
||||
data->viewport.y += split_idx - epimo - 1;
|
||||
data->viewport.height = data->viewport.height / (split_count + 1) + (split_idx > epimo ? 1 : 0);
|
||||
} else {
|
||||
if (flip_x_start)
|
||||
split_idx = split_count - split_idx;
|
||||
|
||||
epimo = split_count - data->viewport.width % (split_count + 1);
|
||||
|
||||
data->viewport.x += (data->viewport.width / (split_count + 1)) * split_idx;
|
||||
if (split_idx > epimo)
|
||||
data->viewport.x += split_idx - epimo - 1;
|
||||
data->viewport.width = data->viewport.width / (split_count + 1) + (split_idx > epimo ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Round down, compensate in init */
|
||||
data->viewport_c.x = data->viewport.x / vpc_div;
|
||||
data->viewport_c.y = data->viewport.y / vpc_div;
|
||||
data->inits.h_c = (data->viewport.x % vpc_div) != 0 ? dc_fixpt_half : dc_fixpt_zero;
|
||||
data->inits.v_c = (data->viewport.y % vpc_div) != 0 ? dc_fixpt_half : dc_fixpt_zero;
|
||||
|
||||
/* Round up, assume original video size always even dimensions */
|
||||
data->viewport_c.width = (data->viewport.width + vpc_div - 1) / vpc_div;
|
||||
data->viewport_c.height = (data->viewport.height + vpc_div - 1) / vpc_div;
|
||||
|
||||
data->viewport_unadjusted = data->viewport;
|
||||
data->viewport_c_unadjusted = data->viewport_c;
|
||||
}
|
||||
|
||||
static void calculate_recout(struct pipe_ctx *pipe_ctx)
|
||||
@@ -827,26 +727,21 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx)
|
||||
const struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
struct scaler_data *data = &pipe_ctx->plane_res.scl_data;
|
||||
struct rect surf_clip = plane_state->clip_rect;
|
||||
bool pri_split_tb = pipe_ctx->bottom_pipe &&
|
||||
pipe_ctx->bottom_pipe->plane_state == pipe_ctx->plane_state &&
|
||||
stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM;
|
||||
bool sec_split_tb = pipe_ctx->top_pipe &&
|
||||
pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state &&
|
||||
stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM;
|
||||
int split_count = 0;
|
||||
int split_idx = 0;
|
||||
bool split_tb = stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM;
|
||||
int split_count, split_idx;
|
||||
|
||||
calculate_split_count_and_index(pipe_ctx, &split_count, &split_idx);
|
||||
if (stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE)
|
||||
split_idx = 0;
|
||||
|
||||
/*
|
||||
* Only the leftmost ODM pipe should be offset by a nonzero distance
|
||||
*/
|
||||
if (!pipe_ctx->prev_odm_pipe) {
|
||||
if (!pipe_ctx->prev_odm_pipe || split_idx == split_count) {
|
||||
data->recout.x = stream->dst.x;
|
||||
if (stream->src.x < surf_clip.x)
|
||||
data->recout.x += (surf_clip.x - stream->src.x) * stream->dst.width
|
||||
/ stream->src.width;
|
||||
|
||||
} else
|
||||
data->recout.x = 0;
|
||||
|
||||
@@ -867,26 +762,31 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx)
|
||||
if (data->recout.height + data->recout.y > stream->dst.y + stream->dst.height)
|
||||
data->recout.height = stream->dst.y + stream->dst.height - data->recout.y;
|
||||
|
||||
/* Handle h & v split, handle rotation using viewport */
|
||||
if (sec_split_tb) {
|
||||
data->recout.y += data->recout.height / 2;
|
||||
/* Floor primary pipe, ceil 2ndary pipe */
|
||||
data->recout.height = (data->recout.height + 1) / 2;
|
||||
} else if (pri_split_tb)
|
||||
/* Handle h & v split */
|
||||
if (split_tb) {
|
||||
ASSERT(data->recout.height % 2 == 0);
|
||||
data->recout.height /= 2;
|
||||
else if (split_count) {
|
||||
/* extra pixels in the division remainder need to go to pipes after
|
||||
* the extra pixel index minus one(epimo) defined here as:
|
||||
*/
|
||||
int epimo = split_count - data->recout.width % (split_count + 1);
|
||||
|
||||
/*no recout offset due to odm */
|
||||
} else if (split_count) {
|
||||
if (!pipe_ctx->next_odm_pipe && !pipe_ctx->prev_odm_pipe) {
|
||||
/* extra pixels in the division remainder need to go to pipes after
|
||||
* the extra pixel index minus one(epimo) defined here as:
|
||||
*/
|
||||
int epimo = split_count - data->recout.width % (split_count + 1);
|
||||
|
||||
data->recout.x += (data->recout.width / (split_count + 1)) * split_idx;
|
||||
if (split_idx > epimo)
|
||||
data->recout.x += split_idx - epimo - 1;
|
||||
ASSERT(stream->view_format != VIEW_3D_FORMAT_SIDE_BY_SIDE || data->recout.width % 2 == 0);
|
||||
data->recout.width = data->recout.width / (split_count + 1) + (split_idx > epimo ? 1 : 0);
|
||||
} else {
|
||||
/* odm */
|
||||
if (split_idx == split_count) {
|
||||
/* rightmost pipe is the remainder recout */
|
||||
data->recout.width -= data->h_active * split_count - data->recout.x;
|
||||
data->recout.x = 0;
|
||||
} else
|
||||
data->recout.width = data->h_active - data->recout.x;
|
||||
}
|
||||
data->recout.width = data->recout.width / (split_count + 1) + (split_idx > epimo ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -940,9 +840,15 @@ static void calculate_scaling_ratios(struct pipe_ctx *pipe_ctx)
|
||||
pipe_ctx->plane_res.scl_data.ratios.vert_c, 19);
|
||||
}
|
||||
|
||||
static inline void adjust_vp_and_init_for_seamless_clip(
|
||||
|
||||
/*
|
||||
* We completely calculate vp offset, size and inits here based entirely on scaling
|
||||
* ratios and recout for pixel perfect pipe combine.
|
||||
*/
|
||||
static void calculate_init_and_vp(
|
||||
bool flip_scan_dir,
|
||||
int recout_skip,
|
||||
int recout_offset_within_recout_full,
|
||||
int recout_size,
|
||||
int src_size,
|
||||
int taps,
|
||||
struct fixed31_32 ratio,
|
||||
@@ -950,91 +856,87 @@ static inline void adjust_vp_and_init_for_seamless_clip(
|
||||
int *vp_offset,
|
||||
int *vp_size)
|
||||
{
|
||||
if (!flip_scan_dir) {
|
||||
/* Adjust for viewport end clip-off */
|
||||
if ((*vp_offset + *vp_size) < src_size) {
|
||||
int vp_clip = src_size - *vp_size - *vp_offset;
|
||||
int int_part = dc_fixpt_floor(dc_fixpt_sub(*init, ratio));
|
||||
struct fixed31_32 temp;
|
||||
int int_part;
|
||||
|
||||
int_part = int_part > 0 ? int_part : 0;
|
||||
*vp_size += int_part < vp_clip ? int_part : vp_clip;
|
||||
}
|
||||
|
||||
/* Adjust for non-0 viewport offset */
|
||||
if (*vp_offset) {
|
||||
int int_part;
|
||||
|
||||
*init = dc_fixpt_add(*init, dc_fixpt_mul_int(ratio, recout_skip));
|
||||
int_part = dc_fixpt_floor(*init) - *vp_offset;
|
||||
if (int_part < taps) {
|
||||
int int_adj = *vp_offset >= (taps - int_part) ?
|
||||
(taps - int_part) : *vp_offset;
|
||||
*vp_offset -= int_adj;
|
||||
*vp_size += int_adj;
|
||||
int_part += int_adj;
|
||||
} else if (int_part > taps) {
|
||||
*vp_offset += int_part - taps;
|
||||
*vp_size -= int_part - taps;
|
||||
int_part = taps;
|
||||
}
|
||||
init->value &= 0xffffffff;
|
||||
*init = dc_fixpt_add_int(*init, int_part);
|
||||
}
|
||||
} else {
|
||||
/* Adjust for non-0 viewport offset */
|
||||
if (*vp_offset) {
|
||||
int int_part = dc_fixpt_floor(dc_fixpt_sub(*init, ratio));
|
||||
|
||||
int_part = int_part > 0 ? int_part : 0;
|
||||
*vp_size += int_part < *vp_offset ? int_part : *vp_offset;
|
||||
*vp_offset -= int_part < *vp_offset ? int_part : *vp_offset;
|
||||
}
|
||||
|
||||
/* Adjust for viewport end clip-off */
|
||||
if ((*vp_offset + *vp_size) < src_size) {
|
||||
int int_part;
|
||||
int end_offset = src_size - *vp_offset - *vp_size;
|
||||
|
||||
/*
|
||||
* this is init if vp had no offset, keep in mind this is from the
|
||||
* right side of vp due to scan direction
|
||||
*/
|
||||
*init = dc_fixpt_add(*init, dc_fixpt_mul_int(ratio, recout_skip));
|
||||
/*
|
||||
* this is the difference between first pixel of viewport available to read
|
||||
* and init position, takning into account scan direction
|
||||
*/
|
||||
int_part = dc_fixpt_floor(*init) - end_offset;
|
||||
if (int_part < taps) {
|
||||
int int_adj = end_offset >= (taps - int_part) ?
|
||||
(taps - int_part) : end_offset;
|
||||
*vp_size += int_adj;
|
||||
int_part += int_adj;
|
||||
} else if (int_part > taps) {
|
||||
*vp_size += int_part - taps;
|
||||
int_part = taps;
|
||||
}
|
||||
init->value &= 0xffffffff;
|
||||
*init = dc_fixpt_add_int(*init, int_part);
|
||||
}
|
||||
/*
|
||||
* First of the taps starts sampling pixel number <init_int_part> corresponding to recout
|
||||
* pixel 1. Next recout pixel samples int part of <init + scaling ratio> and so on.
|
||||
* All following calculations are based on this logic.
|
||||
*
|
||||
* Init calculated according to formula:
|
||||
* init = (scaling_ratio + number_of_taps + 1) / 2
|
||||
* init_bot = init + scaling_ratio
|
||||
* to get pixel perfect combine add the fraction from calculating vp offset
|
||||
*/
|
||||
temp = dc_fixpt_mul_int(ratio, recout_offset_within_recout_full);
|
||||
*vp_offset = dc_fixpt_floor(temp);
|
||||
temp.value &= 0xffffffff;
|
||||
*init = dc_fixpt_truncate(dc_fixpt_add(dc_fixpt_div_int(
|
||||
dc_fixpt_add_int(ratio, taps + 1), 2), temp), 19);
|
||||
/*
|
||||
* If viewport has non 0 offset and there are more taps than covered by init then
|
||||
* we should decrease the offset and increase init so we are never sampling
|
||||
* outside of viewport.
|
||||
*/
|
||||
int_part = dc_fixpt_floor(*init);
|
||||
if (int_part < taps) {
|
||||
int_part = taps - int_part;
|
||||
if (int_part > *vp_offset)
|
||||
int_part = *vp_offset;
|
||||
*vp_offset -= int_part;
|
||||
*init = dc_fixpt_add_int(*init, int_part);
|
||||
}
|
||||
/*
|
||||
* If taps are sampling outside of viewport at end of recout and there are more pixels
|
||||
* available in the surface we should increase the viewport size, regardless set vp to
|
||||
* only what is used.
|
||||
*/
|
||||
temp = dc_fixpt_add(*init, dc_fixpt_mul_int(ratio, recout_size - 1));
|
||||
*vp_size = dc_fixpt_floor(temp);
|
||||
if (*vp_size + *vp_offset > src_size)
|
||||
*vp_size = src_size - *vp_offset;
|
||||
|
||||
/* We did all the math assuming we are scanning same direction as display does,
|
||||
* however mirror/rotation changes how vp scans vs how it is offset. If scan direction
|
||||
* is flipped we simply need to calculate offset from the other side of plane.
|
||||
* Note that outside of viewport all scaling hardware works in recout space.
|
||||
*/
|
||||
if (flip_scan_dir)
|
||||
*vp_offset = src_size - *vp_offset - *vp_size;
|
||||
}
|
||||
|
||||
static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx)
|
||||
static void calculate_inits_and_viewports(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
|
||||
const struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
struct pipe_ctx *odm_pipe = pipe_ctx;
|
||||
struct scaler_data *data = &pipe_ctx->plane_res.scl_data;
|
||||
struct rect src = pipe_ctx->plane_state->src_rect;
|
||||
int recout_skip_h, recout_skip_v, surf_size_h, surf_size_v;
|
||||
struct rect src = plane_state->src_rect;
|
||||
int vpc_div = (data->format == PIXEL_FORMAT_420BPP8
|
||||
|| data->format == PIXEL_FORMAT_420BPP10) ? 2 : 1;
|
||||
|| data->format == PIXEL_FORMAT_420BPP10) ? 2 : 1;
|
||||
int split_count, split_idx, ro_lb, ro_tb, recout_full_x, recout_full_y;
|
||||
bool orthogonal_rotation, flip_vert_scan_dir, flip_horz_scan_dir;
|
||||
int odm_idx = 0;
|
||||
|
||||
calculate_split_count_and_index(pipe_ctx, &split_count, &split_idx);
|
||||
/*
|
||||
* recout full is what the recout would have been if we didnt clip
|
||||
* the source plane at all. We only care about left(ro_lb) and top(ro_tb)
|
||||
* offsets of recout within recout full because those are the directions
|
||||
* we scan from and therefore the only ones that affect inits.
|
||||
*/
|
||||
recout_full_x = stream->dst.x + (plane_state->dst_rect.x - stream->src.x)
|
||||
* stream->dst.width / stream->src.width;
|
||||
recout_full_y = stream->dst.y + (plane_state->dst_rect.y - stream->src.y)
|
||||
* stream->dst.height / stream->src.height;
|
||||
if (pipe_ctx->prev_odm_pipe && split_idx)
|
||||
ro_lb = data->h_active * split_idx - recout_full_x;
|
||||
else
|
||||
ro_lb = data->recout.x - recout_full_x;
|
||||
ro_tb = data->recout.y - recout_full_y;
|
||||
ASSERT(ro_lb >= 0 && ro_tb >= 0);
|
||||
|
||||
/*
|
||||
* Need to calculate the scan direction for viewport to make adjustments
|
||||
* Work in recout rotation since that requires less transformations
|
||||
*/
|
||||
get_vp_scan_direction(
|
||||
plane_state->rotation,
|
||||
@@ -1043,145 +945,62 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx)
|
||||
&flip_vert_scan_dir,
|
||||
&flip_horz_scan_dir);
|
||||
|
||||
/* Calculate src rect rotation adjusted to recout space */
|
||||
surf_size_h = src.x + src.width;
|
||||
surf_size_v = src.y + src.height;
|
||||
if (flip_horz_scan_dir)
|
||||
src.x = 0;
|
||||
if (flip_vert_scan_dir)
|
||||
src.y = 0;
|
||||
if (orthogonal_rotation) {
|
||||
swap(src.x, src.y);
|
||||
swap(src.width, src.height);
|
||||
swap(flip_vert_scan_dir, flip_horz_scan_dir);
|
||||
}
|
||||
|
||||
/*modified recout_skip_h calculation due to odm having no recout offset*/
|
||||
while (odm_pipe->prev_odm_pipe) {
|
||||
odm_idx++;
|
||||
odm_pipe = odm_pipe->prev_odm_pipe;
|
||||
}
|
||||
/*odm_pipe is the leftmost pipe in the ODM group*/
|
||||
recout_skip_h = odm_idx * data->recout.width;
|
||||
|
||||
/* Recout matching initial vp offset = recout_offset - (stream dst offset +
|
||||
* ((surf dst offset - stream src offset) * 1/ stream scaling ratio)
|
||||
* - (surf surf_src offset * 1/ full scl ratio))
|
||||
*/
|
||||
recout_skip_h += odm_pipe->plane_res.scl_data.recout.x
|
||||
- (stream->dst.x + (plane_state->dst_rect.x - stream->src.x)
|
||||
* stream->dst.width / stream->src.width -
|
||||
src.x * plane_state->dst_rect.width / src.width
|
||||
* stream->dst.width / stream->src.width);
|
||||
|
||||
|
||||
recout_skip_v = data->recout.y - (stream->dst.y + (plane_state->dst_rect.y - stream->src.y)
|
||||
* stream->dst.height / stream->src.height -
|
||||
src.y * plane_state->dst_rect.height / src.height
|
||||
* stream->dst.height / stream->src.height);
|
||||
if (orthogonal_rotation)
|
||||
swap(recout_skip_h, recout_skip_v);
|
||||
/*
|
||||
* Init calculated according to formula:
|
||||
* init = (scaling_ratio + number_of_taps + 1) / 2
|
||||
* init_bot = init + scaling_ratio
|
||||
* init_c = init + truncated_vp_c_offset(from calculate viewport)
|
||||
*/
|
||||
data->inits.h = dc_fixpt_truncate(dc_fixpt_div_int(
|
||||
dc_fixpt_add_int(data->ratios.horz, data->taps.h_taps + 1), 2), 19);
|
||||
|
||||
data->inits.h_c = dc_fixpt_truncate(dc_fixpt_add(data->inits.h_c, dc_fixpt_div_int(
|
||||
dc_fixpt_add_int(data->ratios.horz_c, data->taps.h_taps_c + 1), 2)), 19);
|
||||
|
||||
data->inits.v = dc_fixpt_truncate(dc_fixpt_div_int(
|
||||
dc_fixpt_add_int(data->ratios.vert, data->taps.v_taps + 1), 2), 19);
|
||||
|
||||
data->inits.v_c = dc_fixpt_truncate(dc_fixpt_add(data->inits.v_c, dc_fixpt_div_int(
|
||||
dc_fixpt_add_int(data->ratios.vert_c, data->taps.v_taps_c + 1), 2)), 19);
|
||||
|
||||
/*
|
||||
* Taps, inits and scaling ratios are in recout space need to rotate
|
||||
* to viewport rotation before adjustment
|
||||
*/
|
||||
adjust_vp_and_init_for_seamless_clip(
|
||||
calculate_init_and_vp(
|
||||
flip_horz_scan_dir,
|
||||
recout_skip_h,
|
||||
surf_size_h,
|
||||
orthogonal_rotation ? data->taps.v_taps : data->taps.h_taps,
|
||||
orthogonal_rotation ? data->ratios.vert : data->ratios.horz,
|
||||
orthogonal_rotation ? &data->inits.v : &data->inits.h,
|
||||
ro_lb,
|
||||
data->recout.width,
|
||||
src.width,
|
||||
data->taps.h_taps,
|
||||
data->ratios.horz,
|
||||
&data->inits.h,
|
||||
&data->viewport.x,
|
||||
&data->viewport.width);
|
||||
adjust_vp_and_init_for_seamless_clip(
|
||||
calculate_init_and_vp(
|
||||
flip_horz_scan_dir,
|
||||
recout_skip_h,
|
||||
surf_size_h / vpc_div,
|
||||
orthogonal_rotation ? data->taps.v_taps_c : data->taps.h_taps_c,
|
||||
orthogonal_rotation ? data->ratios.vert_c : data->ratios.horz_c,
|
||||
orthogonal_rotation ? &data->inits.v_c : &data->inits.h_c,
|
||||
ro_lb,
|
||||
data->recout.width,
|
||||
src.width / vpc_div,
|
||||
data->taps.h_taps_c,
|
||||
data->ratios.horz_c,
|
||||
&data->inits.h_c,
|
||||
&data->viewport_c.x,
|
||||
&data->viewport_c.width);
|
||||
adjust_vp_and_init_for_seamless_clip(
|
||||
calculate_init_and_vp(
|
||||
flip_vert_scan_dir,
|
||||
recout_skip_v,
|
||||
surf_size_v,
|
||||
orthogonal_rotation ? data->taps.h_taps : data->taps.v_taps,
|
||||
orthogonal_rotation ? data->ratios.horz : data->ratios.vert,
|
||||
orthogonal_rotation ? &data->inits.h : &data->inits.v,
|
||||
ro_tb,
|
||||
data->recout.height,
|
||||
src.height,
|
||||
data->taps.v_taps,
|
||||
data->ratios.vert,
|
||||
&data->inits.v,
|
||||
&data->viewport.y,
|
||||
&data->viewport.height);
|
||||
adjust_vp_and_init_for_seamless_clip(
|
||||
calculate_init_and_vp(
|
||||
flip_vert_scan_dir,
|
||||
recout_skip_v,
|
||||
surf_size_v / vpc_div,
|
||||
orthogonal_rotation ? data->taps.h_taps_c : data->taps.v_taps_c,
|
||||
orthogonal_rotation ? data->ratios.horz_c : data->ratios.vert_c,
|
||||
orthogonal_rotation ? &data->inits.h_c : &data->inits.v_c,
|
||||
ro_tb,
|
||||
data->recout.height,
|
||||
src.height / vpc_div,
|
||||
data->taps.v_taps_c,
|
||||
data->ratios.vert_c,
|
||||
&data->inits.v_c,
|
||||
&data->viewport_c.y,
|
||||
&data->viewport_c.height);
|
||||
|
||||
/* Interlaced inits based on final vert inits */
|
||||
data->inits.v_bot = dc_fixpt_add(data->inits.v, data->ratios.vert);
|
||||
data->inits.v_c_bot = dc_fixpt_add(data->inits.v_c, data->ratios.vert_c);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* When handling 270 rotation in mixed SLS mode, we have
|
||||
* stream->timing.h_border_left that is non zero. If we are doing
|
||||
* pipe-splitting, this h_border_left value gets added to recout.x and when it
|
||||
* calls calculate_inits_and_adj_vp() and
|
||||
* adjust_vp_and_init_for_seamless_clip(), it can cause viewport.height for a
|
||||
* pipe to be incorrect.
|
||||
*
|
||||
* To fix this, instead of using stream->timing.h_border_left, we can use
|
||||
* stream->dst.x to represent the border instead. So we will set h_border_left
|
||||
* to 0 and shift the appropriate amount in stream->dst.x. We will then
|
||||
* perform all calculations in resource_build_scaling_params() based on this
|
||||
* and then restore the h_border_left and stream->dst.x to their original
|
||||
* values.
|
||||
*
|
||||
* shift_border_left_to_dst() will shift the amount of h_border_left to
|
||||
* stream->dst.x and set h_border_left to 0. restore_border_left_from_dst()
|
||||
* will restore h_border_left and stream->dst.x back to their original values
|
||||
* We also need to make sure pipe_ctx->plane_res.scl_data.h_active uses the
|
||||
* original h_border_left value in its calculation.
|
||||
*/
|
||||
static int shift_border_left_to_dst(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
int store_h_border_left = pipe_ctx->stream->timing.h_border_left;
|
||||
|
||||
if (store_h_border_left) {
|
||||
pipe_ctx->stream->timing.h_border_left = 0;
|
||||
pipe_ctx->stream->dst.x += store_h_border_left;
|
||||
if (orthogonal_rotation) {
|
||||
swap(data->viewport.x, data->viewport.y);
|
||||
swap(data->viewport.width, data->viewport.height);
|
||||
swap(data->viewport_c.x, data->viewport_c.y);
|
||||
swap(data->viewport_c.width, data->viewport_c.height);
|
||||
}
|
||||
return store_h_border_left;
|
||||
}
|
||||
|
||||
static void restore_border_left_from_dst(struct pipe_ctx *pipe_ctx,
|
||||
int store_h_border_left)
|
||||
{
|
||||
pipe_ctx->stream->dst.x -= store_h_border_left;
|
||||
pipe_ctx->stream->timing.h_border_left = store_h_border_left;
|
||||
data->viewport.x += src.x;
|
||||
data->viewport.y += src.y;
|
||||
ASSERT(src.x % vpc_div == 0 && src.y % vpc_div == 0);
|
||||
data->viewport_c.x += src.x / vpc_div;
|
||||
data->viewport_c.y += src.y / vpc_div;
|
||||
}
|
||||
|
||||
bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
||||
@@ -1189,48 +1008,45 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
||||
const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
|
||||
struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
|
||||
bool res = false;
|
||||
int store_h_border_left = shift_border_left_to_dst(pipe_ctx);
|
||||
DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
|
||||
/* Important: scaling ratio calculation requires pixel format,
|
||||
* lb depth calculation requires recout and taps require scaling ratios.
|
||||
* Inits require viewport, taps, ratios and recout of split pipe
|
||||
*/
|
||||
|
||||
pipe_ctx->plane_res.scl_data.format = convert_pixel_format_to_dalsurface(
|
||||
pipe_ctx->plane_state->format);
|
||||
|
||||
calculate_scaling_ratios(pipe_ctx);
|
||||
|
||||
calculate_viewport(pipe_ctx);
|
||||
|
||||
if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE ||
|
||||
pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE) {
|
||||
if (store_h_border_left) {
|
||||
restore_border_left_from_dst(pipe_ctx,
|
||||
store_h_border_left);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
calculate_recout(pipe_ctx);
|
||||
|
||||
/**
|
||||
* Setting line buffer pixel depth to 24bpp yields banding
|
||||
* on certain displays, such as the Sharp 4k
|
||||
/* Timing borders are part of vactive that we are also supposed to skip in addition
|
||||
* to any stream dst offset. Since dm logic assumes dst is in addressable
|
||||
* space we need to add the the left and top borders to dst offsets temporarily.
|
||||
* TODO: fix in DM, stream dst is supposed to be in vactive
|
||||
*/
|
||||
pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
|
||||
pipe_ctx->plane_res.scl_data.lb_params.alpha_en = plane_state->per_pixel_alpha;
|
||||
|
||||
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->stream->dst.x += timing->h_border_left;
|
||||
pipe_ctx->stream->dst.y += timing->v_border_top;
|
||||
|
||||
/* Calculate H and V active size */
|
||||
pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable +
|
||||
store_h_border_left + timing->h_border_right;
|
||||
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;
|
||||
if (pipe_ctx->next_odm_pipe || pipe_ctx->prev_odm_pipe)
|
||||
pipe_ctx->plane_res.scl_data.h_active /= get_num_odm_splits(pipe_ctx) + 1;
|
||||
|
||||
/* Taps calculations */
|
||||
/* depends on h_active */
|
||||
calculate_recout(pipe_ctx);
|
||||
/* depends on pixel format */
|
||||
calculate_scaling_ratios(pipe_ctx);
|
||||
/* depends on scaling ratios and recout, does not calculate offset yet */
|
||||
calculate_viewport_size(pipe_ctx);
|
||||
|
||||
/*
|
||||
* LB calculations depend on vp size, h/v_active and scaling ratios
|
||||
* Setting line buffer pixel depth to 24bpp yields banding
|
||||
* on certain displays, such as the Sharp 4k. 36bpp is needed
|
||||
* to support SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 and
|
||||
* SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616 with actual > 10 bpc
|
||||
* precision on at least DCN display engines.
|
||||
*/
|
||||
pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_36BPP;
|
||||
pipe_ctx->plane_res.scl_data.lb_params.alpha_en = plane_state->per_pixel_alpha;
|
||||
|
||||
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);
|
||||
@@ -1257,9 +1073,31 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
||||
&plane_state->scaling_quality);
|
||||
}
|
||||
|
||||
/*
|
||||
* Depends on recout, scaling ratios, h_active and taps
|
||||
* May need to re-check lb size after this in some obscure scenario
|
||||
*/
|
||||
if (res)
|
||||
/* May need to re-check lb size after this in some obscure scenario */
|
||||
calculate_inits_and_adj_vp(pipe_ctx);
|
||||
calculate_inits_and_viewports(pipe_ctx);
|
||||
|
||||
/*
|
||||
* Handle side by side and top bottom 3d recout offsets after vp calculation
|
||||
* since 3d is special and needs to calculate vp as if there is no recout offset
|
||||
* This may break with rotation, good thing we aren't mixing hw rotation and 3d
|
||||
*/
|
||||
if (pipe_ctx->top_pipe && pipe_ctx->top_pipe->plane_state == plane_state) {
|
||||
ASSERT(plane_state->rotation == ROTATION_ANGLE_0 ||
|
||||
(pipe_ctx->stream->view_format != VIEW_3D_FORMAT_TOP_AND_BOTTOM &&
|
||||
pipe_ctx->stream->view_format != VIEW_3D_FORMAT_SIDE_BY_SIDE));
|
||||
if (pipe_ctx->stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM)
|
||||
pipe_ctx->plane_res.scl_data.recout.y += pipe_ctx->plane_res.scl_data.recout.height;
|
||||
else if (pipe_ctx->stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE)
|
||||
pipe_ctx->plane_res.scl_data.recout.x += pipe_ctx->plane_res.scl_data.recout.width;
|
||||
}
|
||||
|
||||
if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE ||
|
||||
pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE)
|
||||
res = false;
|
||||
|
||||
DC_LOG_SCALER("%s pipe %d:\nViewport: height:%d width:%d x:%d y:%d Recout: height:%d width:%d x:%d y:%d HACTIVE:%d VACTIVE:%d\n"
|
||||
"src_rect: height:%d width:%d x:%d y:%d dst_rect: height:%d width:%d x:%d y:%d clip_rect: height:%d width:%d x:%d y:%d\n",
|
||||
@@ -1288,8 +1126,8 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
||||
plane_state->clip_rect.x,
|
||||
plane_state->clip_rect.y);
|
||||
|
||||
if (store_h_border_left)
|
||||
restore_border_left_from_dst(pipe_ctx, store_h_border_left);
|
||||
pipe_ctx->stream->dst.x -= timing->h_border_left;
|
||||
pipe_ctx->stream->dst.y -= timing->v_border_top;
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -3046,6 +2884,7 @@ unsigned int resource_pixel_format_to_bpp(enum surface_pixel_format format)
|
||||
#endif
|
||||
return 32;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
|
||||
return 64;
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
/* forward declaration */
|
||||
struct aux_payload;
|
||||
|
||||
#define DC_VER "3.2.136"
|
||||
#define DC_VER "3.2.137"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_PLANES 6
|
||||
@@ -1069,8 +1069,6 @@ bool dc_resource_is_dsc_encoding_supported(const struct dc *dc);
|
||||
*/
|
||||
bool dc_commit_state(struct dc *dc, struct dc_state *context);
|
||||
|
||||
void dc_power_down_on_boot(struct dc *dc);
|
||||
|
||||
struct dc_state *dc_create_state(struct dc *dc);
|
||||
struct dc_state *dc_copy_state(struct dc_state *src_ctx);
|
||||
void dc_retain_state(struct dc_state *context);
|
||||
|
||||
@@ -110,6 +110,15 @@ void dc_dmub_srv_wait_idle(struct dc_dmub_srv *dc_dmub_srv)
|
||||
DC_ERROR("Error waiting for DMUB idle: status=%d\n", status);
|
||||
}
|
||||
|
||||
void dc_dmub_srv_send_inbox0_cmd(struct dc_dmub_srv *dmub_srv,
|
||||
union dmub_inbox0_data_register data)
|
||||
{
|
||||
struct dmub_srv *dmub = dmub_srv->dmub;
|
||||
if (dmub->hw_funcs.send_inbox0_cmd)
|
||||
dmub->hw_funcs.send_inbox0_cmd(dmub, data);
|
||||
// TODO: Add wait command -- poll register for ACK
|
||||
}
|
||||
|
||||
bool dc_dmub_srv_cmd_with_reply_data(struct dc_dmub_srv *dc_dmub_srv, union dmub_rb_cmd *cmd)
|
||||
{
|
||||
struct dmub_srv *dmub;
|
||||
|
||||
@@ -66,4 +66,6 @@ bool dc_dmub_srv_get_dmub_outbox0_msg(const struct dc *dc, struct dmcub_trace_bu
|
||||
|
||||
void dc_dmub_trace_event_control(struct dc *dc, bool enable);
|
||||
|
||||
void dc_dmub_srv_send_inbox0_cmd(struct dc_dmub_srv *dmub_srv, union dmub_inbox0_data_register data);
|
||||
|
||||
#endif /* _DMUB_DC_SRV_H_ */
|
||||
|
||||
@@ -182,6 +182,8 @@ enum surface_pixel_format {
|
||||
SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS,
|
||||
/*64 bpp */
|
||||
SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616,
|
||||
/*swapped*/
|
||||
SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616,
|
||||
/*float*/
|
||||
SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F,
|
||||
/*swaped & float*/
|
||||
|
||||
@@ -216,6 +216,23 @@ static inline void get_edp_links(const struct dc *dc,
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool dc_get_edp_link_panel_inst(const struct dc *dc,
|
||||
const struct dc_link *link,
|
||||
unsigned int *inst_out)
|
||||
{
|
||||
struct dc_link *edp_links[MAX_NUM_EDP];
|
||||
int edp_num;
|
||||
|
||||
if (link->connector_signal != SIGNAL_TYPE_EDP)
|
||||
return false;
|
||||
get_edp_links(dc, edp_links, &edp_num);
|
||||
if ((edp_num > 1) && (link->link_index > edp_links[0]->link_index))
|
||||
*inst_out = 1;
|
||||
else
|
||||
*inst_out = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Set backlight level of an embedded panel (eDP, LVDS).
|
||||
* backlight_pwm_u16_16 is unsigned 32 bit with 16 bit integer
|
||||
* and 16 bit fractional, where 1.0 is max backlight value.
|
||||
@@ -316,7 +333,7 @@ bool dc_link_dp_perform_link_training_skip_aux(
|
||||
|
||||
enum link_training_result dc_link_dp_perform_link_training(
|
||||
struct dc_link *link,
|
||||
const struct dc_link_settings *link_setting,
|
||||
const struct dc_link_settings *link_settings,
|
||||
bool skip_video_pattern);
|
||||
|
||||
bool dc_link_dp_sync_lt_begin(struct dc_link *link);
|
||||
|
||||
@@ -179,6 +179,9 @@ struct dc_stream_state {
|
||||
|
||||
bool use_vsc_sdp_for_colorimetry;
|
||||
bool ignore_msa_timing_param;
|
||||
|
||||
bool freesync_on_desktop;
|
||||
|
||||
bool converter_disable_audio;
|
||||
uint8_t qs_bit;
|
||||
uint8_t qy_bit;
|
||||
|
||||
@@ -271,11 +271,6 @@ struct dc_edid_caps {
|
||||
struct dc_panel_patch panel_patch;
|
||||
};
|
||||
|
||||
struct view {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
};
|
||||
|
||||
struct dc_mode_flags {
|
||||
/* note: part of refresh rate flag*/
|
||||
uint32_t INTERLACE :1;
|
||||
|
||||
@@ -566,6 +566,7 @@ static void program_grph_pixel_format(
|
||||
* should problem swap endian*/
|
||||
format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010 ||
|
||||
format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS ||
|
||||
format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616 ||
|
||||
format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
|
||||
/* ABGR formats */
|
||||
red_xbar = 2;
|
||||
@@ -606,6 +607,7 @@ static void program_grph_pixel_format(
|
||||
fallthrough;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: /* shouldn't this get float too? */
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
|
||||
grph_depth = 3;
|
||||
grph_format = 0;
|
||||
break;
|
||||
|
||||
@@ -181,7 +181,6 @@ struct dce_mem_input_registers {
|
||||
SFB(blk, GRPH_ENABLE, GRPH_ENABLE, mask_sh),\
|
||||
SFB(blk, GRPH_CONTROL, GRPH_DEPTH, mask_sh),\
|
||||
SFB(blk, GRPH_CONTROL, GRPH_FORMAT, mask_sh),\
|
||||
SFB(blk, GRPH_CONTROL, GRPH_NUM_BANKS, mask_sh),\
|
||||
SFB(blk, GRPH_X_START, GRPH_X_START, mask_sh),\
|
||||
SFB(blk, GRPH_Y_START, GRPH_Y_START, mask_sh),\
|
||||
SFB(blk, GRPH_X_END, GRPH_X_END, mask_sh),\
|
||||
@@ -207,7 +206,6 @@ struct dce_mem_input_registers {
|
||||
SFB(blk, GRPH_ENABLE, GRPH_ENABLE, mask_sh),\
|
||||
SFB(blk, GRPH_CONTROL, GRPH_DEPTH, mask_sh),\
|
||||
SFB(blk, GRPH_CONTROL, GRPH_FORMAT, mask_sh),\
|
||||
SFB(blk, GRPH_CONTROL, GRPH_NUM_BANKS, mask_sh),\
|
||||
SFB(blk, GRPH_X_START, GRPH_X_START, mask_sh),\
|
||||
SFB(blk, GRPH_Y_START, GRPH_Y_START, mask_sh),\
|
||||
SFB(blk, GRPH_X_END, GRPH_X_END, mask_sh),\
|
||||
|
||||
@@ -794,7 +794,7 @@ static void program_bit_depth_reduction(
|
||||
enum dcp_out_trunc_round_mode trunc_mode;
|
||||
bool spatial_dither_enable;
|
||||
|
||||
ASSERT(depth < COLOR_DEPTH_121212); /* Invalid clamp bit depth */
|
||||
ASSERT(depth <= COLOR_DEPTH_121212); /* Invalid clamp bit depth */
|
||||
|
||||
spatial_dither_enable = bit_depth_params->flags.SPATIAL_DITHER_ENABLED;
|
||||
/* Default to 12 bit truncation without rounding */
|
||||
@@ -854,7 +854,7 @@ static void dce60_program_bit_depth_reduction(
|
||||
enum dcp_out_trunc_round_mode trunc_mode;
|
||||
bool spatial_dither_enable;
|
||||
|
||||
ASSERT(depth < COLOR_DEPTH_121212); /* Invalid clamp bit depth */
|
||||
ASSERT(depth <= COLOR_DEPTH_121212); /* Invalid clamp bit depth */
|
||||
|
||||
spatial_dither_enable = bit_depth_params->flags.SPATIAL_DITHER_ENABLED;
|
||||
/* Default to 12 bit truncation without rounding */
|
||||
@@ -1647,7 +1647,8 @@ void dce_transform_construct(
|
||||
xfm_dce->lb_pixel_depth_supported =
|
||||
LB_PIXEL_DEPTH_18BPP |
|
||||
LB_PIXEL_DEPTH_24BPP |
|
||||
LB_PIXEL_DEPTH_30BPP;
|
||||
LB_PIXEL_DEPTH_30BPP |
|
||||
LB_PIXEL_DEPTH_36BPP;
|
||||
|
||||
xfm_dce->lb_bits_per_entry = LB_BITS_PER_ENTRY;
|
||||
xfm_dce->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x6B0*/
|
||||
@@ -1675,7 +1676,8 @@ void dce60_transform_construct(
|
||||
xfm_dce->lb_pixel_depth_supported =
|
||||
LB_PIXEL_DEPTH_18BPP |
|
||||
LB_PIXEL_DEPTH_24BPP |
|
||||
LB_PIXEL_DEPTH_30BPP;
|
||||
LB_PIXEL_DEPTH_30BPP |
|
||||
LB_PIXEL_DEPTH_36BPP;
|
||||
|
||||
xfm_dce->lb_bits_per_entry = LB_BITS_PER_ENTRY;
|
||||
xfm_dce->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x6B0*/
|
||||
|
||||
@@ -172,16 +172,12 @@ static bool dmub_abm_set_level(struct abm *abm, uint32_t level)
|
||||
|
||||
static bool dmub_abm_init_config(struct abm *abm,
|
||||
const char *src,
|
||||
unsigned int bytes)
|
||||
unsigned int bytes,
|
||||
unsigned int inst)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
struct dc_context *dc = abm->ctx;
|
||||
uint32_t edp_id_count = dc->dc_edp_id_count;
|
||||
int i;
|
||||
uint8_t panel_mask = 0;
|
||||
|
||||
for (i = 0; i < edp_id_count; i++)
|
||||
panel_mask |= 0x01 << i;
|
||||
uint8_t panel_mask = 0x01 << inst;
|
||||
|
||||
// TODO: Optimize by only reading back final 4 bytes
|
||||
dmub_flush_buffer_mem(&dc->dmub_srv->dmub->scratch_mem_fb);
|
||||
|
||||
@@ -52,6 +52,14 @@ void dmub_hw_lock_mgr_cmd(struct dc_dmub_srv *dmub_srv,
|
||||
dc_dmub_srv_wait_idle(dmub_srv);
|
||||
}
|
||||
|
||||
void dmub_hw_lock_mgr_inbox0_cmd(struct dc_dmub_srv *dmub_srv,
|
||||
union dmub_inbox0_cmd_lock_hw hw_lock_cmd)
|
||||
{
|
||||
union dmub_inbox0_data_register data = { 0 };
|
||||
data.inbox0_cmd_lock_hw = hw_lock_cmd;
|
||||
dc_dmub_srv_send_inbox0_cmd(dmub_srv, data);
|
||||
}
|
||||
|
||||
bool should_use_dmub_lock(struct dc_link *link)
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -34,6 +34,9 @@ void dmub_hw_lock_mgr_cmd(struct dc_dmub_srv *dmub_srv,
|
||||
union dmub_hw_lock_flags *hw_locks,
|
||||
struct dmub_hw_lock_inst_flags *inst_flags);
|
||||
|
||||
void dmub_hw_lock_mgr_inbox0_cmd(struct dc_dmub_srv *dmub_srv,
|
||||
union dmub_inbox0_cmd_lock_hw hw_lock_cmd);
|
||||
|
||||
bool should_use_dmub_lock(struct dc_link *link);
|
||||
|
||||
#endif /*_DMUB_HW_LOCK_MGR_H_ */
|
||||
|
||||
@@ -27,19 +27,10 @@
|
||||
#include "dmub/inc/dmub_cmd.h"
|
||||
|
||||
/**
|
||||
*****************************************************************************
|
||||
* Function: dmub_enable_outbox_notification
|
||||
*
|
||||
* @brief
|
||||
* Sends inbox cmd to dmub to enable outbox1 messages with interrupt.
|
||||
* Dmub sends outbox1 message and triggers outbox1 interrupt.
|
||||
*
|
||||
* @param
|
||||
* [in] dc: dc structure
|
||||
*
|
||||
* @return
|
||||
* None
|
||||
*****************************************************************************
|
||||
* dmub_enable_outbox_notification - Sends inbox cmd to dmub to enable outbox1
|
||||
* messages with interrupt. Dmub sends outbox1
|
||||
* message and triggers outbox1 interrupt.
|
||||
* @dc: dc structure
|
||||
*/
|
||||
void dmub_enable_outbox_notification(struct dc *dc)
|
||||
{
|
||||
|
||||
@@ -63,6 +63,9 @@
|
||||
|
||||
#include "atomfirmware.h"
|
||||
|
||||
#include "dce110_hw_sequencer.h"
|
||||
#include "dcn10/dcn10_hw_sequencer.h"
|
||||
|
||||
#define GAMMA_HW_POINTS_NUM 256
|
||||
|
||||
/*
|
||||
@@ -264,6 +267,7 @@ static void build_prescale_params(struct ipp_prescale_params *prescale_params,
|
||||
prescale_params->scale = 0x2008;
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
|
||||
prescale_params->scale = 0x2000;
|
||||
break;
|
||||
|
||||
@@ -393,6 +393,7 @@ static void program_pixel_format(
|
||||
grph_format = 1;
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
|
||||
grph_depth = 3;
|
||||
|
||||
@@ -708,7 +708,8 @@ bool dce110_transform_v_construct(
|
||||
xfm_dce->lb_pixel_depth_supported =
|
||||
LB_PIXEL_DEPTH_18BPP |
|
||||
LB_PIXEL_DEPTH_24BPP |
|
||||
LB_PIXEL_DEPTH_30BPP;
|
||||
LB_PIXEL_DEPTH_30BPP |
|
||||
LB_PIXEL_DEPTH_36BPP;
|
||||
|
||||
xfm_dce->prescaler_on = true;
|
||||
xfm_dce->lb_bits_per_entry = LB_BITS_PER_ENTRY;
|
||||
|
||||
@@ -257,7 +257,8 @@ static void dpp1_setup_format_flags(enum surface_pixel_format input_format,\
|
||||
if (input_format == SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F ||
|
||||
input_format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F)
|
||||
*fmt = PIXEL_FORMAT_FLOAT;
|
||||
else if (input_format == SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616)
|
||||
else if (input_format == SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ||
|
||||
input_format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616)
|
||||
*fmt = PIXEL_FORMAT_FIXED16;
|
||||
else
|
||||
*fmt = PIXEL_FORMAT_FIXED;
|
||||
@@ -368,7 +369,8 @@ void dpp1_cnv_setup (
|
||||
select = INPUT_CSC_SELECT_ICSC;
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
pixel_format = 22;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
|
||||
pixel_format = 26; /* ARGB16161616_UNORM */
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
|
||||
pixel_format = 24;
|
||||
@@ -566,7 +568,8 @@ void dpp1_construct(
|
||||
dpp->lb_pixel_depth_supported =
|
||||
LB_PIXEL_DEPTH_18BPP |
|
||||
LB_PIXEL_DEPTH_24BPP |
|
||||
LB_PIXEL_DEPTH_30BPP;
|
||||
LB_PIXEL_DEPTH_30BPP |
|
||||
LB_PIXEL_DEPTH_36BPP;
|
||||
|
||||
dpp->lb_bits_per_entry = LB_BITS_PER_ENTRY;
|
||||
dpp->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x1404*/
|
||||
|
||||
@@ -631,8 +631,10 @@ static void dpp1_dscl_set_manual_ratio_init(
|
||||
SCL_V_INIT_INT, init_int);
|
||||
|
||||
if (REG(SCL_VERT_FILTER_INIT_BOT)) {
|
||||
init_frac = dc_fixpt_u0d19(data->inits.v_bot) << 5;
|
||||
init_int = dc_fixpt_floor(data->inits.v_bot);
|
||||
struct fixed31_32 bot = dc_fixpt_add(data->inits.v, data->ratios.vert);
|
||||
|
||||
init_frac = dc_fixpt_u0d19(bot) << 5;
|
||||
init_int = dc_fixpt_floor(bot);
|
||||
REG_SET_2(SCL_VERT_FILTER_INIT_BOT, 0,
|
||||
SCL_V_INIT_FRAC_BOT, init_frac,
|
||||
SCL_V_INIT_INT_BOT, init_int);
|
||||
@@ -645,8 +647,10 @@ static void dpp1_dscl_set_manual_ratio_init(
|
||||
SCL_V_INIT_INT_C, init_int);
|
||||
|
||||
if (REG(SCL_VERT_FILTER_INIT_BOT_C)) {
|
||||
init_frac = dc_fixpt_u0d19(data->inits.v_c_bot) << 5;
|
||||
init_int = dc_fixpt_floor(data->inits.v_c_bot);
|
||||
struct fixed31_32 bot = dc_fixpt_add(data->inits.v_c, data->ratios.vert_c);
|
||||
|
||||
init_frac = dc_fixpt_u0d19(bot) << 5;
|
||||
init_int = dc_fixpt_floor(bot);
|
||||
REG_SET_2(SCL_VERT_FILTER_INIT_BOT_C, 0,
|
||||
SCL_V_INIT_FRAC_BOT_C, init_frac,
|
||||
SCL_V_INIT_INT_BOT_C, init_int);
|
||||
|
||||
@@ -785,6 +785,7 @@ static bool hubbub1_dcc_support_pixel_format(
|
||||
*bytes_per_element = 4;
|
||||
return true;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
|
||||
*bytes_per_element = 8;
|
||||
|
||||
@@ -245,6 +245,7 @@ void hubp1_program_pixel_format(
|
||||
if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888
|
||||
|| format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010
|
||||
|| format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS
|
||||
|| format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616
|
||||
|| format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
|
||||
red_bar = 2;
|
||||
blue_bar = 3;
|
||||
@@ -277,8 +278,9 @@ void hubp1_program_pixel_format(
|
||||
SURFACE_PIXEL_FORMAT, 10);
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: /*we use crossbar already*/
|
||||
REG_UPDATE(DCSURF_SURFACE_CONFIG,
|
||||
SURFACE_PIXEL_FORMAT, 22);
|
||||
SURFACE_PIXEL_FORMAT, 26); /* ARGB16161616_UNORM */
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:/*we use crossbar already*/
|
||||
|
||||
@@ -2502,25 +2502,9 @@ static void dcn10_update_dpp(struct dpp *dpp, struct dc_plane_state *plane_state
|
||||
dpp->funcs->dpp_program_bias_and_scale(dpp, &bns_params);
|
||||
}
|
||||
|
||||
void dcn10_update_visual_confirm_color(struct dc *dc, struct pipe_ctx *pipe_ctx, struct tg_color *color, int mpcc_id)
|
||||
{
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
struct mpc *mpc = dc->res_pool->mpc;
|
||||
|
||||
if (dc->debug.visual_confirm == VISUAL_CONFIRM_HDR)
|
||||
hws->funcs.get_hdr_visual_confirm_color(pipe_ctx, color);
|
||||
else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE)
|
||||
hws->funcs.get_surface_visual_confirm_color(pipe_ctx, color);
|
||||
else
|
||||
color_space_to_black_color(
|
||||
dc, pipe_ctx->stream->output_color_space, color);
|
||||
|
||||
if (mpc->funcs->set_bg_color)
|
||||
mpc->funcs->set_bg_color(mpc, color, mpcc_id);
|
||||
}
|
||||
|
||||
void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
struct hubp *hubp = pipe_ctx->plane_res.hubp;
|
||||
struct mpcc_blnd_cfg blnd_cfg = {{0}};
|
||||
bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
|
||||
@@ -2529,6 +2513,18 @@ void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
struct mpc *mpc = dc->res_pool->mpc;
|
||||
struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params);
|
||||
|
||||
if (dc->debug.visual_confirm == VISUAL_CONFIRM_HDR) {
|
||||
hws->funcs.get_hdr_visual_confirm_color(
|
||||
pipe_ctx, &blnd_cfg.black_color);
|
||||
} else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) {
|
||||
hws->funcs.get_surface_visual_confirm_color(
|
||||
pipe_ctx, &blnd_cfg.black_color);
|
||||
} else {
|
||||
color_space_to_black_color(
|
||||
dc, pipe_ctx->stream->output_color_space,
|
||||
&blnd_cfg.black_color);
|
||||
}
|
||||
|
||||
if (per_pixel_alpha)
|
||||
blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA;
|
||||
else
|
||||
@@ -2560,8 +2556,6 @@ void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
*/
|
||||
mpcc_id = hubp->inst;
|
||||
|
||||
dc->hwss.update_visual_confirm_color(dc, pipe_ctx, &blnd_cfg.black_color, mpcc_id);
|
||||
|
||||
/* If there is no full update, don't need to touch MPC tree*/
|
||||
if (!pipe_ctx->plane_state->update_flags.bits.full_update) {
|
||||
mpc->funcs->update_blending(mpc, &blnd_cfg, mpcc_id);
|
||||
@@ -2599,7 +2593,7 @@ static void update_scaler(struct pipe_ctx *pipe_ctx)
|
||||
pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
|
||||
|
||||
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;
|
||||
pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_36BPP;
|
||||
/* scaler configuration */
|
||||
pipe_ctx->plane_res.dpp->funcs->dpp_set_scaler(
|
||||
pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data);
|
||||
|
||||
@@ -206,10 +206,4 @@ void dcn10_verify_allow_pstate_change_high(struct dc *dc);
|
||||
|
||||
void dcn10_get_dcc_en_bits(struct dc *dc, int *dcc_en_bits);
|
||||
|
||||
void dcn10_update_visual_confirm_color(
|
||||
struct dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct tg_color *color,
|
||||
int mpcc_id);
|
||||
|
||||
#endif /* __DC_HWSS_DCN10_H__ */
|
||||
|
||||
@@ -82,7 +82,6 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
|
||||
.set_abm_immediate_disable = dce110_set_abm_immediate_disable,
|
||||
.set_pipe = dce110_set_pipe,
|
||||
.get_dcc_en_bits = dcn10_get_dcc_en_bits,
|
||||
.update_visual_confirm_color = dcn10_update_visual_confirm_color,
|
||||
};
|
||||
|
||||
static const struct hwseq_private_funcs dcn10_private_funcs = {
|
||||
|
||||
@@ -64,8 +64,6 @@ void mpc1_set_bg_color(struct mpc *mpc,
|
||||
MPCC_BG_G_Y, bg_g_y);
|
||||
REG_SET(MPCC_BG_B_CB[bottommost_mpcc->mpcc_id], 0,
|
||||
MPCC_BG_B_CB, bg_b_cb);
|
||||
|
||||
bottommost_mpcc->blnd_cfg.black_color = *bg_color;
|
||||
}
|
||||
|
||||
static void mpc1_update_blending(
|
||||
@@ -248,8 +246,6 @@ struct mpcc *mpc1_insert_plane(
|
||||
}
|
||||
}
|
||||
|
||||
mpc->funcs->set_bg_color(mpc, &blnd_cfg->black_color, mpcc_id);
|
||||
|
||||
/* update the blending configuration */
|
||||
mpc->funcs->update_blending(mpc, blnd_cfg, mpcc_id);
|
||||
|
||||
@@ -499,7 +495,6 @@ static const struct mpc_funcs dcn10_mpc_funcs = {
|
||||
.set_output_csc = NULL,
|
||||
.set_output_gamma = NULL,
|
||||
.get_mpc_out_mux = mpc1_get_mpc_out_mux,
|
||||
.set_bg_color = mpc1_set_bg_color,
|
||||
};
|
||||
|
||||
void dcn10_mpc_construct(struct dcn10_mpc *mpc10,
|
||||
|
||||
@@ -166,7 +166,8 @@ static void dpp2_cnv_setup (
|
||||
select = DCN2_ICSC_SELECT_ICSC_A;
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
pixel_format = 22;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
|
||||
pixel_format = 26; /* ARGB16161616_UNORM */
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
|
||||
pixel_format = 24;
|
||||
@@ -431,7 +432,8 @@ bool dpp2_construct(
|
||||
dpp->lb_pixel_depth_supported =
|
||||
LB_PIXEL_DEPTH_18BPP |
|
||||
LB_PIXEL_DEPTH_24BPP |
|
||||
LB_PIXEL_DEPTH_30BPP;
|
||||
LB_PIXEL_DEPTH_30BPP |
|
||||
LB_PIXEL_DEPTH_36BPP;
|
||||
|
||||
dpp->lb_bits_per_entry = LB_BITS_PER_ENTRY;
|
||||
dpp->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x1404*/
|
||||
|
||||
@@ -158,6 +158,7 @@ bool hubbub2_dcc_support_pixel_format(
|
||||
*bytes_per_element = 4;
|
||||
return true;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
|
||||
*bytes_per_element = 8;
|
||||
|
||||
@@ -431,6 +431,7 @@ void hubp2_program_pixel_format(
|
||||
if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888
|
||||
|| format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010
|
||||
|| format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS
|
||||
|| format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616
|
||||
|| format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
|
||||
red_bar = 2;
|
||||
blue_bar = 3;
|
||||
@@ -463,8 +464,9 @@ void hubp2_program_pixel_format(
|
||||
SURFACE_PIXEL_FORMAT, 10);
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: /*we use crossbar already*/
|
||||
REG_UPDATE(DCSURF_SURFACE_CONFIG,
|
||||
SURFACE_PIXEL_FORMAT, 22);
|
||||
SURFACE_PIXEL_FORMAT, 26); /* ARGB16161616_UNORM */
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:/*we use crossbar already*/
|
||||
|
||||
@@ -1473,7 +1473,7 @@ static void dcn20_update_dchubp_dpp(
|
||||
plane_state->update_flags.bits.per_pixel_alpha_change ||
|
||||
pipe_ctx->stream->update_flags.bits.scaling) {
|
||||
pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->plane_state->per_pixel_alpha;
|
||||
ASSERT(pipe_ctx->plane_res.scl_data.lb_params.depth == LB_PIXEL_DEPTH_30BPP);
|
||||
ASSERT(pipe_ctx->plane_res.scl_data.lb_params.depth == LB_PIXEL_DEPTH_36BPP);
|
||||
/* scaler configuration */
|
||||
pipe_ctx->plane_res.dpp->funcs->dpp_set_scaler(
|
||||
pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data);
|
||||
@@ -2267,25 +2267,9 @@ void dcn20_get_mpctree_visual_confirm_color(
|
||||
*color = pipe_colors[top_pipe->pipe_idx];
|
||||
}
|
||||
|
||||
void dcn20_update_visual_confirm_color(struct dc *dc, struct pipe_ctx *pipe_ctx, struct tg_color *color, int mpcc_id)
|
||||
{
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
struct mpc *mpc = dc->res_pool->mpc;
|
||||
|
||||
/* input to MPCC is always RGB, by default leave black_color at 0 */
|
||||
if (dc->debug.visual_confirm == VISUAL_CONFIRM_HDR)
|
||||
hws->funcs.get_hdr_visual_confirm_color(pipe_ctx, color);
|
||||
else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE)
|
||||
hws->funcs.get_surface_visual_confirm_color(pipe_ctx, color);
|
||||
else if (dc->debug.visual_confirm == VISUAL_CONFIRM_MPCTREE)
|
||||
dcn20_get_mpctree_visual_confirm_color(pipe_ctx, color);
|
||||
|
||||
if (mpc->funcs->set_bg_color)
|
||||
mpc->funcs->set_bg_color(mpc, color, mpcc_id);
|
||||
}
|
||||
|
||||
void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
struct hubp *hubp = pipe_ctx->plane_res.hubp;
|
||||
struct mpcc_blnd_cfg blnd_cfg = { {0} };
|
||||
bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha;
|
||||
@@ -2294,6 +2278,15 @@ void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
struct mpc *mpc = dc->res_pool->mpc;
|
||||
struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params);
|
||||
|
||||
// input to MPCC is always RGB, by default leave black_color at 0
|
||||
if (dc->debug.visual_confirm == VISUAL_CONFIRM_HDR) {
|
||||
hws->funcs.get_hdr_visual_confirm_color(pipe_ctx, &blnd_cfg.black_color);
|
||||
} else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) {
|
||||
hws->funcs.get_surface_visual_confirm_color(pipe_ctx, &blnd_cfg.black_color);
|
||||
} else if (dc->debug.visual_confirm == VISUAL_CONFIRM_MPCTREE) {
|
||||
dcn20_get_mpctree_visual_confirm_color(pipe_ctx, &blnd_cfg.black_color);
|
||||
}
|
||||
|
||||
if (per_pixel_alpha)
|
||||
blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA;
|
||||
else
|
||||
@@ -2327,8 +2320,6 @@ void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
*/
|
||||
mpcc_id = hubp->inst;
|
||||
|
||||
dc->hwss.update_visual_confirm_color(dc, pipe_ctx, &blnd_cfg.black_color, mpcc_id);
|
||||
|
||||
/* If there is no full update, don't need to touch MPC tree*/
|
||||
if (!pipe_ctx->plane_state->update_flags.bits.full_update &&
|
||||
!pipe_ctx->update_flags.bits.mpcc) {
|
||||
|
||||
@@ -146,10 +146,5 @@ void dcn20_set_disp_pattern_generator(const struct dc *dc,
|
||||
const struct tg_color *solid_color,
|
||||
int width, int height, int offset);
|
||||
|
||||
void dcn20_update_visual_confirm_color(struct dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct tg_color *color,
|
||||
int mpcc_id);
|
||||
|
||||
#endif /* __DC_HWSS_DCN20_H__ */
|
||||
|
||||
|
||||
@@ -96,7 +96,6 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
|
||||
#endif
|
||||
.set_disp_pattern_generator = dcn20_set_disp_pattern_generator,
|
||||
.get_dcc_en_bits = dcn10_get_dcc_en_bits,
|
||||
.update_visual_confirm_color = dcn20_update_visual_confirm_color,
|
||||
};
|
||||
|
||||
static const struct hwseq_private_funcs dcn20_private_funcs = {
|
||||
|
||||
@@ -67,6 +67,7 @@ void mpc2_update_blending(
|
||||
REG_SET(MPCC_BOT_GAIN_INSIDE[mpcc_id], 0, MPCC_BOT_GAIN_INSIDE, blnd_cfg->bottom_inside_gain);
|
||||
REG_SET(MPCC_BOT_GAIN_OUTSIDE[mpcc_id], 0, MPCC_BOT_GAIN_OUTSIDE, blnd_cfg->bottom_outside_gain);
|
||||
|
||||
mpc1_set_bg_color(mpc, &blnd_cfg->black_color, mpcc_id);
|
||||
mpcc->blnd_cfg = *blnd_cfg;
|
||||
}
|
||||
|
||||
@@ -556,7 +557,6 @@ const struct mpc_funcs dcn20_mpc_funcs = {
|
||||
.set_output_gamma = mpc2_set_output_gamma,
|
||||
.power_on_mpc_mem_pwr = mpc20_power_on_ogam_lut,
|
||||
.get_mpc_out_mux = mpc1_get_mpc_out_mux,
|
||||
.set_bg_color = mpc1_set_bg_color,
|
||||
};
|
||||
|
||||
void dcn20_mpc_construct(struct dcn20_mpc *mpc20,
|
||||
|
||||
@@ -2289,12 +2289,14 @@ int dcn20_populate_dml_pipes_from_context(
|
||||
|
||||
pipes[pipe_cnt].pipe.src.source_scan = pln->rotation == ROTATION_ANGLE_90
|
||||
|| pln->rotation == ROTATION_ANGLE_270 ? dm_vert : dm_horz;
|
||||
pipes[pipe_cnt].pipe.src.viewport_y_y = scl->viewport_unadjusted.y;
|
||||
pipes[pipe_cnt].pipe.src.viewport_y_c = scl->viewport_c_unadjusted.y;
|
||||
pipes[pipe_cnt].pipe.src.viewport_width = scl->viewport_unadjusted.width;
|
||||
pipes[pipe_cnt].pipe.src.viewport_width_c = scl->viewport_c_unadjusted.width;
|
||||
pipes[pipe_cnt].pipe.src.viewport_height = scl->viewport_unadjusted.height;
|
||||
pipes[pipe_cnt].pipe.src.viewport_height_c = scl->viewport_c_unadjusted.height;
|
||||
pipes[pipe_cnt].pipe.src.viewport_y_y = scl->viewport.y;
|
||||
pipes[pipe_cnt].pipe.src.viewport_y_c = scl->viewport_c.y;
|
||||
pipes[pipe_cnt].pipe.src.viewport_width = scl->viewport.width;
|
||||
pipes[pipe_cnt].pipe.src.viewport_width_c = scl->viewport_c.width;
|
||||
pipes[pipe_cnt].pipe.src.viewport_height = scl->viewport.height;
|
||||
pipes[pipe_cnt].pipe.src.viewport_height_c = scl->viewport_c.height;
|
||||
pipes[pipe_cnt].pipe.src.viewport_width_max = pln->src_rect.width;
|
||||
pipes[pipe_cnt].pipe.src.viewport_height_max = pln->src_rect.height;
|
||||
pipes[pipe_cnt].pipe.src.surface_width_y = pln->plane_size.surface_size.width;
|
||||
pipes[pipe_cnt].pipe.src.surface_height_y = pln->plane_size.surface_size.height;
|
||||
pipes[pipe_cnt].pipe.src.surface_width_c = pln->plane_size.chroma_size.width;
|
||||
@@ -2363,6 +2365,7 @@ int dcn20_populate_dml_pipes_from_context(
|
||||
pipes[pipe_cnt].pipe.src.source_format = dm_420_10;
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
|
||||
pipes[pipe_cnt].pipe.src.source_format = dm_444_64;
|
||||
@@ -3236,7 +3239,7 @@ static noinline bool dcn20_validate_bandwidth_fp(struct dc *dc,
|
||||
voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false);
|
||||
dummy_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support;
|
||||
|
||||
if (voltage_supported && dummy_pstate_supported) {
|
||||
if (voltage_supported && (dummy_pstate_supported || !(context->stream_count))) {
|
||||
context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
|
||||
goto restore_dml_state;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,6 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
|
||||
.is_abm_supported = dcn21_is_abm_supported,
|
||||
.set_disp_pattern_generator = dcn20_set_disp_pattern_generator,
|
||||
.get_dcc_en_bits = dcn10_get_dcc_en_bits,
|
||||
.update_visual_confirm_color = dcn20_update_visual_confirm_color,
|
||||
};
|
||||
|
||||
static const struct hwseq_private_funcs dcn21_private_funcs = {
|
||||
|
||||
@@ -245,7 +245,8 @@ static void dpp3_cnv_setup (
|
||||
select = INPUT_CSC_SELECT_ICSC;
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
pixel_format = 22;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
|
||||
pixel_format = 26; /* ARGB16161616_UNORM */
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
|
||||
pixel_format = 24;
|
||||
@@ -1442,7 +1443,8 @@ bool dpp3_construct(
|
||||
dpp->lb_pixel_depth_supported =
|
||||
LB_PIXEL_DEPTH_18BPP |
|
||||
LB_PIXEL_DEPTH_24BPP |
|
||||
LB_PIXEL_DEPTH_30BPP;
|
||||
LB_PIXEL_DEPTH_30BPP |
|
||||
LB_PIXEL_DEPTH_36BPP;
|
||||
|
||||
dpp->lb_bits_per_entry = LB_BITS_PER_ENTRY;
|
||||
dpp->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x1404*/
|
||||
|
||||
@@ -99,7 +99,6 @@ static const struct hw_sequencer_funcs dcn30_funcs = {
|
||||
.set_pipe = dcn21_set_pipe,
|
||||
.set_disp_pattern_generator = dcn30_set_disp_pattern_generator,
|
||||
.get_dcc_en_bits = dcn10_get_dcc_en_bits,
|
||||
.update_visual_confirm_color = dcn20_update_visual_confirm_color,
|
||||
};
|
||||
|
||||
static const struct hwseq_private_funcs dcn30_private_funcs = {
|
||||
|
||||
@@ -1431,7 +1431,7 @@ const struct mpc_funcs dcn30_mpc_funcs = {
|
||||
.release_rmu = mpcc3_release_rmu,
|
||||
.power_on_mpc_mem_pwr = mpc3_power_on_ogam_lut,
|
||||
.get_mpc_out_mux = mpc1_get_mpc_out_mux,
|
||||
.set_bg_color = mpc1_set_bg_color,
|
||||
|
||||
};
|
||||
|
||||
void dcn30_mpc_construct(struct dcn30_mpc *mpc30,
|
||||
|
||||
@@ -101,7 +101,6 @@ static const struct hw_sequencer_funcs dcn301_funcs = {
|
||||
.get_dcc_en_bits = dcn10_get_dcc_en_bits,
|
||||
.optimize_pwr_state = dcn21_optimize_pwr_state,
|
||||
.exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state,
|
||||
.update_visual_confirm_color = dcn20_update_visual_confirm_color,
|
||||
};
|
||||
|
||||
static const struct hwseq_private_funcs dcn301_private_funcs = {
|
||||
|
||||
@@ -245,6 +245,8 @@ struct pp_smu_funcs_nv {
|
||||
#define PP_SMU_NUM_DCFCLK_DPM_LEVELS 8
|
||||
#define PP_SMU_NUM_FCLK_DPM_LEVELS 4
|
||||
#define PP_SMU_NUM_MEMCLK_DPM_LEVELS 4
|
||||
#define PP_SMU_NUM_DCLK_DPM_LEVELS 8
|
||||
#define PP_SMU_NUM_VCLK_DPM_LEVELS 8
|
||||
|
||||
struct dpm_clock {
|
||||
uint32_t Freq; // In MHz
|
||||
@@ -258,6 +260,8 @@ struct dpm_clocks {
|
||||
struct dpm_clock SocClocks[PP_SMU_NUM_SOCCLK_DPM_LEVELS];
|
||||
struct dpm_clock FClocks[PP_SMU_NUM_FCLK_DPM_LEVELS];
|
||||
struct dpm_clock MemClocks[PP_SMU_NUM_MEMCLK_DPM_LEVELS];
|
||||
struct dpm_clock VClocks[PP_SMU_NUM_VCLK_DPM_LEVELS];
|
||||
struct dpm_clock DClocks[PP_SMU_NUM_DCLK_DPM_LEVELS];
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -253,6 +253,8 @@ struct _vcs_dpi_display_pipe_source_params_st {
|
||||
unsigned int viewport_y_c;
|
||||
unsigned int viewport_width_c;
|
||||
unsigned int viewport_height_c;
|
||||
unsigned int viewport_width_max;
|
||||
unsigned int viewport_height_max;
|
||||
unsigned int data_pitch;
|
||||
unsigned int data_pitch_c;
|
||||
unsigned int meta_pitch;
|
||||
|
||||
@@ -630,6 +630,19 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (src->viewport_width_max) {
|
||||
int hdiv_c = src->source_format >= dm_420_8 && src->source_format <= dm_422_10 ? 2 : 1;
|
||||
int vdiv_c = src->source_format >= dm_420_8 && src->source_format <= dm_420_12 ? 2 : 1;
|
||||
|
||||
if (mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] > src->viewport_width_max)
|
||||
mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width_max;
|
||||
if (mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] > src->viewport_height_max)
|
||||
mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height_max;
|
||||
if (mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] > src->viewport_width_max / hdiv_c)
|
||||
mode_lib->vba.ViewportWidthChroma[mode_lib->vba.NumberOfActivePlanes] = src->viewport_width_max / hdiv_c;
|
||||
if (mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] > src->viewport_height_max / vdiv_c)
|
||||
mode_lib->vba.ViewportHeightChroma[mode_lib->vba.NumberOfActivePlanes] = src->viewport_height_max / vdiv_c;
|
||||
}
|
||||
|
||||
if (pipes[k].pipe.src.immediate_flip) {
|
||||
mode_lib->vba.ImmediateFlipSupport = true;
|
||||
|
||||
@@ -53,8 +53,8 @@
|
||||
*/
|
||||
|
||||
struct gpio_service *dal_gpio_service_create(
|
||||
enum dce_version dce_version_major,
|
||||
enum dce_version dce_version_minor,
|
||||
enum dce_version dce_version,
|
||||
enum dce_environment dce_environment,
|
||||
struct dc_context *ctx)
|
||||
{
|
||||
struct gpio_service *service;
|
||||
@@ -67,14 +67,14 @@ struct gpio_service *dal_gpio_service_create(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!dal_hw_translate_init(&service->translate, dce_version_major,
|
||||
dce_version_minor)) {
|
||||
if (!dal_hw_translate_init(&service->translate, dce_version,
|
||||
dce_environment)) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
goto failure_1;
|
||||
}
|
||||
|
||||
if (!dal_hw_factory_init(&service->factory, dce_version_major,
|
||||
dce_version_minor)) {
|
||||
if (!dal_hw_factory_init(&service->factory, dce_version,
|
||||
dce_environment)) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
goto failure_1;
|
||||
}
|
||||
|
||||
@@ -30,11 +30,21 @@
|
||||
#define LINK_TRAINING_RETRY_DELAY 50 /* ms */
|
||||
#define LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD 3200 /*us*/
|
||||
#define LINK_AUX_DEFAULT_TIMEOUT_PERIOD 552 /*us*/
|
||||
#define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE 0x50
|
||||
#define TRAINING_AUX_RD_INTERVAL 100 //us
|
||||
|
||||
struct dc_link;
|
||||
struct dc_stream_state;
|
||||
struct dc_link_settings;
|
||||
|
||||
enum {
|
||||
LINK_TRAINING_MAX_RETRY_COUNT = 5,
|
||||
/* to avoid infinite loop where-in the receiver
|
||||
* switches between different VS
|
||||
*/
|
||||
LINK_TRAINING_MAX_CR_RETRY = 100
|
||||
};
|
||||
|
||||
bool dp_verify_link_cap(
|
||||
struct dc_link *link,
|
||||
struct dc_link_settings *known_limit_link_setting,
|
||||
@@ -68,6 +78,10 @@ bool perform_link_training_with_retries(
|
||||
enum signal_type signal,
|
||||
bool do_fallback);
|
||||
|
||||
bool hpd_rx_irq_check_link_loss_status(
|
||||
struct dc_link *link,
|
||||
union hpd_irq_data *hpd_irq_dpcd_data);
|
||||
|
||||
bool is_mst_supported(struct dc_link *link);
|
||||
|
||||
bool detect_dp_sink_caps(struct dc_link *link);
|
||||
@@ -88,8 +102,51 @@ void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode);
|
||||
bool dp_overwrite_extended_receiver_cap(struct dc_link *link);
|
||||
|
||||
void dpcd_set_source_specific_data(struct dc_link *link);
|
||||
/* Write DPCD link configuration data. */
|
||||
enum dc_status dpcd_set_link_settings(
|
||||
struct dc_link *link,
|
||||
const struct link_training_settings *lt_settings);
|
||||
/* Write DPCD drive settings. */
|
||||
enum dc_status dpcd_set_lane_settings(
|
||||
struct dc_link *link,
|
||||
const struct link_training_settings *link_training_setting,
|
||||
uint32_t offset);
|
||||
/* Read training status and adjustment requests from DPCD. */
|
||||
enum dc_status dp_get_lane_status_and_drive_settings(
|
||||
struct dc_link *link,
|
||||
const struct link_training_settings *link_training_setting,
|
||||
union lane_status *ln_status,
|
||||
union lane_align_status_updated *ln_status_updated,
|
||||
struct link_training_settings *req_settings,
|
||||
uint32_t offset);
|
||||
|
||||
void dp_set_fec_ready(struct dc_link *link, bool ready);
|
||||
void dp_wait_for_training_aux_rd_interval(
|
||||
struct dc_link *link,
|
||||
uint32_t wait_in_micro_secs);
|
||||
|
||||
bool dp_is_cr_done(enum dc_lane_count ln_count,
|
||||
union lane_status *dpcd_lane_status);
|
||||
|
||||
enum link_training_result dp_get_cr_failure(enum dc_lane_count ln_count,
|
||||
union lane_status *dpcd_lane_status);
|
||||
|
||||
bool dp_is_max_vs_reached(
|
||||
const struct link_training_settings *lt_settings);
|
||||
|
||||
void dp_update_drive_settings(
|
||||
struct link_training_settings *dest,
|
||||
struct link_training_settings src);
|
||||
|
||||
enum dpcd_training_patterns
|
||||
dc_dp_training_pattern_to_dpcd_training_pattern(
|
||||
struct dc_link *link,
|
||||
enum dc_dp_training_pattern pattern);
|
||||
|
||||
uint8_t dc_dp_initialize_scrambling_data_symbols(
|
||||
struct dc_link *link,
|
||||
enum dc_dp_training_pattern pattern);
|
||||
|
||||
enum dc_status dp_set_fec_ready(struct dc_link *link, bool ready);
|
||||
void dp_set_fec_enable(struct dc_link *link, bool enable);
|
||||
bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
@@ -97,6 +154,13 @@ void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx);
|
||||
bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
|
||||
/* Initialize output parameter lt_settings. */
|
||||
void dp_decide_training_settings(
|
||||
struct dc_link *link,
|
||||
const struct dc_link_settings *link_setting,
|
||||
const struct dc_link_training_overrides *overrides,
|
||||
struct link_training_settings *lt_settings);
|
||||
|
||||
/* Convert PHY repeater count read from DPCD uint8_t. */
|
||||
uint8_t dp_convert_to_count(uint8_t lttpr_repeater_count);
|
||||
|
||||
@@ -105,5 +169,9 @@ enum link_training_result dp_check_link_loss_status(
|
||||
struct dc_link *link,
|
||||
const struct link_training_settings *link_training_setting);
|
||||
|
||||
enum dc_status dpcd_configure_lttpr_mode(
|
||||
struct dc_link *link,
|
||||
struct link_training_settings *lt_settings);
|
||||
|
||||
enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings *link_settings);
|
||||
#endif /* __DC_LINK_DP_H__ */
|
||||
|
||||
@@ -52,7 +52,8 @@ struct abm_funcs {
|
||||
unsigned int (*get_target_backlight)(struct abm *abm);
|
||||
bool (*init_abm_config)(struct abm *abm,
|
||||
const char *src,
|
||||
unsigned int bytes);
|
||||
unsigned int bytes,
|
||||
unsigned int inst);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -363,9 +363,6 @@ struct mpc_funcs {
|
||||
struct mpc *mpc,
|
||||
int opp_id);
|
||||
|
||||
void (*set_bg_color)(struct mpc *mpc,
|
||||
struct tg_color *bg_color,
|
||||
int mpcc_id);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -162,9 +162,7 @@ struct scl_inits {
|
||||
struct fixed31_32 h;
|
||||
struct fixed31_32 h_c;
|
||||
struct fixed31_32 v;
|
||||
struct fixed31_32 v_bot;
|
||||
struct fixed31_32 v_c;
|
||||
struct fixed31_32 v_c_bot;
|
||||
};
|
||||
|
||||
struct scaler_data {
|
||||
@@ -173,8 +171,6 @@ struct scaler_data {
|
||||
struct scaling_taps taps;
|
||||
struct rect viewport;
|
||||
struct rect viewport_c;
|
||||
struct rect viewport_unadjusted;
|
||||
struct rect viewport_c_unadjusted;
|
||||
struct rect recout;
|
||||
struct scaling_ratios ratios;
|
||||
struct scl_inits inits;
|
||||
|
||||
@@ -235,10 +235,6 @@ struct hw_sequencer_funcs {
|
||||
enum dc_color_depth color_depth,
|
||||
const struct tg_color *solid_color,
|
||||
int width, int height, int offset);
|
||||
void (*update_visual_confirm_color)(struct dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct tg_color *color,
|
||||
int mpcc_id);
|
||||
};
|
||||
|
||||
void color_space_to_black_color(
|
||||
|
||||
@@ -324,6 +324,7 @@ struct dmub_srv_hw_funcs {
|
||||
|
||||
uint32_t (*get_gpint_response)(struct dmub_srv *dmub);
|
||||
|
||||
void (*send_inbox0_cmd)(struct dmub_srv *dmub, union dmub_inbox0_data_register data);
|
||||
uint32_t (*get_current_time)(struct dmub_srv *dmub);
|
||||
};
|
||||
|
||||
|
||||
@@ -35,20 +35,13 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
*****************************************************************************
|
||||
* Function: dmub_srv_stat_get_notification
|
||||
* dmub_srv_stat_get_notification - Retrieves a dmub outbox notification, set up dmub notification
|
||||
* structure with message information. Also a pending bit if queue
|
||||
* is having more notifications
|
||||
* @dmub: dmub srv structure
|
||||
* @notify: dmub notification structure to be filled up
|
||||
*
|
||||
* @brief
|
||||
* Retrieves a dmub outbox notification, set up dmub notification
|
||||
* structure with message information. Also a pending bit if queue
|
||||
* is having more notifications
|
||||
*
|
||||
* @param [in] dmub: dmub srv structure
|
||||
* @param [out] pnotify: dmub notification structure to be filled up
|
||||
*
|
||||
* @return
|
||||
* dmub_status
|
||||
*****************************************************************************
|
||||
* Returns: dmub_status
|
||||
*/
|
||||
enum dmub_status dmub_srv_stat_get_notification(struct dmub_srv *dmub,
|
||||
struct dmub_notification *notify)
|
||||
|
||||
@@ -42,8 +42,8 @@ void dal_gpio_destroy(
|
||||
struct gpio **ptr);
|
||||
|
||||
struct gpio_service *dal_gpio_service_create(
|
||||
enum dce_version dce_version_major,
|
||||
enum dce_version dce_version_minor,
|
||||
enum dce_version dce_version,
|
||||
enum dce_environment dce_environment,
|
||||
struct dc_context *ctx);
|
||||
|
||||
struct gpio *dal_gpio_service_create_irq(
|
||||
|
||||
@@ -85,6 +85,7 @@ struct link_training_settings {
|
||||
enum dc_voltage_swing *voltage_swing;
|
||||
enum dc_pre_emphasis *pre_emphasis;
|
||||
enum dc_post_cursor2 *post_cursor2;
|
||||
bool should_set_fec_ready;
|
||||
|
||||
uint16_t cr_pattern_time;
|
||||
uint16_t eq_pattern_time;
|
||||
|
||||
@@ -516,7 +516,8 @@ bool mod_freesync_get_v_position(struct mod_freesync *mod_freesync,
|
||||
}
|
||||
|
||||
static void build_vrr_infopacket_data_v1(const struct mod_vrr_params *vrr,
|
||||
struct dc_info_packet *infopacket)
|
||||
struct dc_info_packet *infopacket,
|
||||
bool freesync_on_desktop)
|
||||
{
|
||||
/* PB1 = 0x1A (24bit AMD IEEE OUI (0x00001A) - Byte 0) */
|
||||
infopacket->sb[1] = 0x1A;
|
||||
@@ -542,10 +543,16 @@ static void build_vrr_infopacket_data_v1(const struct mod_vrr_params *vrr,
|
||||
vrr->state != VRR_STATE_UNSUPPORTED)
|
||||
infopacket->sb[6] |= 0x02;
|
||||
|
||||
/* PB6 = [Bit 2 = FreeSync Active] */
|
||||
if (vrr->state != VRR_STATE_DISABLED &&
|
||||
if (freesync_on_desktop) {
|
||||
/* PB6 = [Bit 2 = FreeSync Active] */
|
||||
if (vrr->state != VRR_STATE_DISABLED &&
|
||||
vrr->state != VRR_STATE_UNSUPPORTED)
|
||||
infopacket->sb[6] |= 0x04;
|
||||
infopacket->sb[6] |= 0x04;
|
||||
} else {
|
||||
if (vrr->state == VRR_STATE_ACTIVE_VARIABLE ||
|
||||
vrr->state == VRR_STATE_ACTIVE_FIXED)
|
||||
infopacket->sb[6] |= 0x04;
|
||||
}
|
||||
|
||||
// For v1 & 2 infoframes program nominal if non-fs mode, otherwise full range
|
||||
/* PB7 = FreeSync Minimum refresh rate (Hz) */
|
||||
@@ -824,13 +831,14 @@ static void build_vrr_infopacket_checksum(unsigned int *payload_size,
|
||||
|
||||
static void build_vrr_infopacket_v1(enum signal_type signal,
|
||||
const struct mod_vrr_params *vrr,
|
||||
struct dc_info_packet *infopacket)
|
||||
struct dc_info_packet *infopacket,
|
||||
bool freesync_on_desktop)
|
||||
{
|
||||
/* SPD info packet for FreeSync */
|
||||
unsigned int payload_size = 0;
|
||||
|
||||
build_vrr_infopacket_header_v1(signal, infopacket, &payload_size);
|
||||
build_vrr_infopacket_data_v1(vrr, infopacket);
|
||||
build_vrr_infopacket_data_v1(vrr, infopacket, freesync_on_desktop);
|
||||
build_vrr_infopacket_checksum(&payload_size, infopacket);
|
||||
|
||||
infopacket->valid = true;
|
||||
@@ -839,12 +847,13 @@ static void build_vrr_infopacket_v1(enum signal_type signal,
|
||||
static void build_vrr_infopacket_v2(enum signal_type signal,
|
||||
const struct mod_vrr_params *vrr,
|
||||
enum color_transfer_func app_tf,
|
||||
struct dc_info_packet *infopacket)
|
||||
struct dc_info_packet *infopacket,
|
||||
bool freesync_on_desktop)
|
||||
{
|
||||
unsigned int payload_size = 0;
|
||||
|
||||
build_vrr_infopacket_header_v2(signal, infopacket, &payload_size);
|
||||
build_vrr_infopacket_data_v1(vrr, infopacket);
|
||||
build_vrr_infopacket_data_v1(vrr, infopacket, freesync_on_desktop);
|
||||
|
||||
build_vrr_infopacket_fs2_data(app_tf, infopacket);
|
||||
|
||||
@@ -953,12 +962,12 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync,
|
||||
#endif
|
||||
break;
|
||||
case PACKET_TYPE_FS_V2:
|
||||
build_vrr_infopacket_v2(stream->signal, vrr, app_tf, infopacket);
|
||||
build_vrr_infopacket_v2(stream->signal, vrr, app_tf, infopacket, stream->freesync_on_desktop);
|
||||
break;
|
||||
case PACKET_TYPE_VRR:
|
||||
case PACKET_TYPE_FS_V1:
|
||||
default:
|
||||
build_vrr_infopacket_v1(stream->signal, vrr, infopacket);
|
||||
build_vrr_infopacket_v1(stream->signal, vrr, infopacket, stream->freesync_on_desktop);
|
||||
}
|
||||
|
||||
if (true == pack_sdp_v1_3 &&
|
||||
|
||||
@@ -29,8 +29,10 @@ static inline enum mod_hdcp_status validate_bksv(struct mod_hdcp *hdcp)
|
||||
{
|
||||
uint64_t n = 0;
|
||||
uint8_t count = 0;
|
||||
u8 bksv[sizeof(n)] = { };
|
||||
|
||||
memcpy(&n, hdcp->auth.msg.hdcp1.bksv, sizeof(uint64_t));
|
||||
memcpy(bksv, hdcp->auth.msg.hdcp1.bksv, sizeof(hdcp->auth.msg.hdcp1.bksv));
|
||||
n = *(uint64_t *)bksv;
|
||||
|
||||
while (n) {
|
||||
count++;
|
||||
|
||||
@@ -371,19 +371,6 @@ enum mod_hdcp_status mod_hdcp_hdcp1_link_maintenance(struct mod_hdcp *hdcp)
|
||||
return status;
|
||||
}
|
||||
|
||||
enum mod_hdcp_status mod_hdcp_hdcp1_get_link_encryption_status(struct mod_hdcp *hdcp,
|
||||
enum mod_hdcp_encryption_status *encryption_status)
|
||||
{
|
||||
*encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
|
||||
|
||||
if (mod_hdcp_hdcp1_link_maintenance(hdcp) != MOD_HDCP_STATUS_SUCCESS)
|
||||
return MOD_HDCP_STATUS_FAILURE;
|
||||
|
||||
*encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP1_ON;
|
||||
|
||||
return MOD_HDCP_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum mod_hdcp_status mod_hdcp_hdcp2_create_session(struct mod_hdcp *hdcp)
|
||||
{
|
||||
struct psp_context *psp = hdcp->config.psp.handle;
|
||||
|
||||
@@ -660,7 +660,8 @@ static void fill_iram_v_2_3(struct iram_table_v_2_2 *ram_table, struct dmcu_iram
|
||||
}
|
||||
|
||||
bool dmub_init_abm_config(struct resource_pool *res_pool,
|
||||
struct dmcu_iram_parameters params)
|
||||
struct dmcu_iram_parameters params,
|
||||
unsigned int inst)
|
||||
{
|
||||
struct iram_table_v_2_2 ram_table;
|
||||
struct abm_config_table config;
|
||||
@@ -669,7 +670,7 @@ bool dmub_init_abm_config(struct resource_pool *res_pool,
|
||||
uint32_t i, j = 0;
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (res_pool->abm == NULL && res_pool->multiple_abms[0] == NULL)
|
||||
if (res_pool->abm == NULL && res_pool->multiple_abms[inst] == NULL)
|
||||
return false;
|
||||
#else
|
||||
if (res_pool->abm == NULL)
|
||||
@@ -728,13 +729,13 @@ bool dmub_init_abm_config(struct resource_pool *res_pool,
|
||||
config.min_abm_backlight = ram_table.min_abm_backlight;
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (res_pool->multiple_abms[0])
|
||||
result = res_pool->multiple_abms[0]->funcs->init_abm_config(
|
||||
res_pool->multiple_abms[0], (char *)(&config), sizeof(struct abm_config_table));
|
||||
else
|
||||
if (res_pool->multiple_abms[inst]) {
|
||||
result = res_pool->multiple_abms[inst]->funcs->init_abm_config(
|
||||
res_pool->multiple_abms[inst], (char *)(&config), sizeof(struct abm_config_table), inst);
|
||||
} else
|
||||
#endif
|
||||
result = res_pool->abm->funcs->init_abm_config(
|
||||
res_pool->abm, (char *)(&config), sizeof(struct abm_config_table));
|
||||
res_pool->abm, (char *)(&config), sizeof(struct abm_config_table), 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ struct dmcu_iram_parameters {
|
||||
bool dmcu_load_iram(struct dmcu *dmcu,
|
||||
struct dmcu_iram_parameters params);
|
||||
bool dmub_init_abm_config(struct resource_pool *res_pool,
|
||||
struct dmcu_iram_parameters params);
|
||||
struct dmcu_iram_parameters params,
|
||||
unsigned int inst);
|
||||
|
||||
#endif /* MODULES_POWER_POWER_HELPERS_H_ */
|
||||
|
||||
Reference in New Issue
Block a user