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:
Dave Airlie
2021-06-04 06:13:56 +10:00
164 changed files with 2704 additions and 1497 deletions

View File

@@ -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 ||

View File

@@ -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;

View File

@@ -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
*

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)
{

View File

@@ -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,
&lt_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, &lt_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, &lt_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(
&lt_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,
&lt_settings);
/* Configure lttpr mode */
if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT)
configure_lttpr_mode_non_transparent(link, &lt_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, &lt_settings, DPRX);
start_clock_recovery_pattern_early(link, lt_settings, DPRX);
/* 1. set link rate, lane count and spread. */
dpcd_set_link_settings(link, &lt_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, &lt_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,
&lt_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, &lt_settings, DPRX);
status = perform_clock_recovery_sequence(link, lt_settings, DPRX);
if (status == LINK_TRAINING_SUCCESS) {
status = perform_channel_equalization_sequence(link,
&lt_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,
&lt_settings);
/* reset previous training states */
dpcd_exit_training_mode(link);
/* configure link prior to entering training mode */
dpcd_configure_lttpr_mode(link, &lt_settings);
dp_set_fec_ready(link, lt_settings.should_set_fec_ready);
dpcd_configure_channel_coding(link, &lt_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, &lt_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,
&lt_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, &lt_settings);
}
/* 6. print status message*/
/* dump debug data */
print_status_message(link, &lt_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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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_ */

View File

@@ -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*/

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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),\

View File

@@ -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*/

View File

@@ -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);

View File

@@ -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;

View File

@@ -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_ */

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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*/

View File

@@ -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);

View File

@@ -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;

View File

@@ -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*/

View File

@@ -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);

View File

@@ -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__ */

View File

@@ -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 = {

View File

@@ -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,

View File

@@ -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*/

View File

@@ -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;

View File

@@ -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*/

View File

@@ -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) {

View File

@@ -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__ */

View File

@@ -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 = {

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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 = {

View File

@@ -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*/

View File

@@ -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 = {

View File

@@ -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,

View File

@@ -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 = {

View File

@@ -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];
};

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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__ */

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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(

View File

@@ -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);
};

View File

@@ -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)

View File

@@ -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(

View File

@@ -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;

View File

@@ -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 &&

View File

@@ -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++;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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_ */