diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-04-28 10:01:40 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-04-28 10:01:40 -0700 |
commit | 68a32ba14177d4a21c4a9a941cf1d7aea86d436f (patch) | |
tree | 945c20860766c22b19d1806d5b5db5b37bc65b65 /drivers/gpu/drm/amd/display/modules/freesync/freesync.c | |
parent | Merge tag 'media/v5.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media (diff) | |
parent | Merge tag 'drm-misc-next-fixes-2021-04-22' of git://anongit.freedesktop.org/drm/drm-misc into drm-next (diff) | |
download | linux-dev-68a32ba14177d4a21c4a9a941cf1d7aea86d436f.tar.xz linux-dev-68a32ba14177d4a21c4a9a941cf1d7aea86d436f.zip |
Merge tag 'drm-next-2021-04-28' of git://anongit.freedesktop.org/drm/drm
Pull drm updates from Dave Airlie:
"The usual lots of work all over the place.
i915 has gotten some Alderlake work and prelim DG1 code, along with a
major locking rework over the GEM code, and brings back the property
of timing out long running jobs using a watchdog. amdgpu has some
Alderbran support (new GPU), freesync HDMI support along with a lot
other fixes.
Outside of the drm, there is a new printf specifier added which should
have all the correct acks/sobs:
- printk fourcc modifier support added %p4cc
Summary:
core:
- drm_crtc_commit_wait
- atomic plane state helpers reworked for full state
- dma-buf heaps API rework
- edid: rework and improvements for displayid
dp-mst:
- better topology logging
bridge:
- Chipone ICN6211
- Lontium LT8912B
- anx7625 regulator support
panel:
- fix lt9611 4k panels handling
simple-kms:
- add plane state helpers
ttm:
- debugfs support
- removal of unused sysfs
- ignore signaled moved fences
- ioremap buffer according to mem caching
i915:
- Alderlake S enablement
- Conversion to dma_resv_locking
- Bring back watchdog timeout support
- legacy ioctl cleanups
- add GEM TDDO and RFC process
- DG1 LMEM preparation work
- intel_display.c refactoring
- Gen9/TGL PCH combination support
- eDP MSO Support
- multiple PSR instance support
- Link training debug updates
- Disable PSR2 support on JSL/EHL
- DDR5/LPDDR5 support for bw calcs
- LSPCON limited to gen9/10 platforms
- HSW/BDW async flip/VTd corruption workaround
- SAGV watermark fixes
- SNB hard hang on ring resume fix
- Limit imported dma-buf size
- move to use new tasklet API
- refactor KBL/TGL/ADL-S display/gt steppings
- refactoring legacy DP/HDMI, FB plane code out
amdgpu:
- uapi: add ioctl to query video capabilities
- Iniital AMD Freesync HDMI support
- Initial Adebaran support
- 10bpc dithering improvements
- DCN secure display support
- Drop legacy IO BAR requirements
- PCIE/S0ix/RAS/Prime/Reset fixes
- Display ASSR support
- SMU gfx busy queues for RV/PCO
- Initial LTTPR display work
amdkfd:
- MMU notifier fixes
- APU fixes
radeon:
- debugfs cleanps
- fw error handling ifix
- Flexible array cleanups
msm:
- big DSI phy/pll cleanup
- sc7280 initial support
- commong bandwidth scaling path
- shrinker locking contention fixes
- unpin/swap support for GEM objcets
ast:
- cursor plane handling reworked
tegra:
- don't register DP AUX channels before connectors
zynqmp:
- fix OOB struct padding memset
gma500:
- drop ttm and medfield support
exynos:
- request_irq cleanup function
mediatek:
- fine tune line time for EOTp
- MT8192 dpi support
- atomic crtc config updates
- don't support HDMI connector creation
mxsdb:
- imx8mm support
panfrost:
- MMU IRQ handling rework
qxl:
- locking fixes
- resource deallocation changes
sun4i:
- add alpha properties to UI/VI layers
vc4:
- RPi4 CEC support
vmwgfx:
- doc cleanups
arc:
- moved to drm/tiny"
* tag 'drm-next-2021-04-28' of git://anongit.freedesktop.org/drm/drm: (1390 commits)
drm/ttm: Don't count pages in SG BOs against pages_limit
drm/ttm: fix return value check
drm/bridge: lt8912b: fix incorrect handling of of_* return values
drm: bridge: fix LONTIUM use of mipi_dsi_() functions
drm: bridge: fix ANX7625 use of mipi_dsi_() functions
drm/amdgpu: page retire over debugfs mechanism
drm/radeon: Fix a missing check bug in radeon_dp_mst_detect()
drm/amd/display: Fix the Wunused-function warning
drm/radeon/r600: Fix variables that are not used after assignment
drm/amdgpu/smu7: fix CAC setting on TOPAZ
drm/amd/display: Update DCN302 SR Exit Latency
drm/amdgpu: enable ras eeprom on aldebaran
drm/amdgpu: RAS harvest on driver load
drm/amdgpu: add ras aldebaran ras eeprom driver
drm/amd/pm: increase time out value when sending msg to SMU
drm/amdgpu: add DMUB outbox event IRQ source define/complete/debug flag
drm/amd/pm: add the callback to get vbios bootup values for vangogh
drm/radeon: Fix size overflow
drm/amdgpu: Fix size overflow
drm/amdgpu: move mmhub ras_func init to ip specific file
...
Diffstat (limited to 'drivers/gpu/drm/amd/display/modules/freesync/freesync.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 69 |
1 files changed, 54 insertions, 15 deletions
diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index 4762273b5bb9..3f4f44b44e6a 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -118,7 +118,7 @@ static unsigned int calc_duration_in_us_from_v_total( return duration_in_us; } -static unsigned int calc_v_total_from_refresh( +unsigned int mod_freesync_calc_v_total_from_refresh( const struct dc_stream_state *stream, unsigned int refresh_in_uhz) { @@ -280,10 +280,10 @@ static void apply_below_the_range(struct core_freesync *core_freesync, /* Restore FreeSync */ in_out_vrr->adjust.v_total_min = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->max_refresh_in_uhz); in_out_vrr->adjust.v_total_max = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->min_refresh_in_uhz); /* BTR set to "active" so engage */ } else { @@ -442,16 +442,16 @@ static void apply_fixed_refresh(struct core_freesync *core_freesync, if (update) { if (in_out_vrr->fixed.fixed_active) { in_out_vrr->adjust.v_total_min = - calc_v_total_from_refresh( + mod_freesync_calc_v_total_from_refresh( stream, in_out_vrr->max_refresh_in_uhz); in_out_vrr->adjust.v_total_max = in_out_vrr->adjust.v_total_min; } else { in_out_vrr->adjust.v_total_min = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->max_refresh_in_uhz); in_out_vrr->adjust.v_total_max = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->min_refresh_in_uhz); } } @@ -543,8 +543,8 @@ static void build_vrr_infopacket_data_v1(const struct mod_vrr_params *vrr, infopacket->sb[6] |= 0x02; /* PB6 = [Bit 2 = FreeSync Active] */ - if (vrr->state == VRR_STATE_ACTIVE_VARIABLE || - vrr->state == VRR_STATE_ACTIVE_FIXED) + if (vrr->state != VRR_STATE_DISABLED && + vrr->state != VRR_STATE_UNSUPPORTED) infopacket->sb[6] |= 0x04; // For v1 & 2 infoframes program nominal if non-fs mode, otherwise full range @@ -903,12 +903,31 @@ static void build_vrr_infopacket_v3(enum signal_type signal, infopacket->valid = true; } +static void build_vrr_infopacket_sdp_v1_3(enum vrr_packet_type packet_type, + struct dc_info_packet *infopacket) +{ + uint8_t idx = 0, size = 0; + + size = ((packet_type == PACKET_TYPE_FS_V1) ? 0x08 : + (packet_type == PACKET_TYPE_FS_V3) ? 0x10 : + 0x09); + + for (idx = infopacket->hb2; idx > 1; idx--) // Data Byte Count: 0x1B + infopacket->sb[idx] = infopacket->sb[idx-1]; + + infopacket->sb[1] = size; // Length + infopacket->sb[0] = (infopacket->hb3 >> 2) & 0x3F;//Version + infopacket->hb3 = (0x13 << 2); // Header,SDP 1.3 + infopacket->hb2 = 0x1D; +} + void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync, const struct dc_stream_state *stream, const struct mod_vrr_params *vrr, enum vrr_packet_type packet_type, enum color_transfer_func app_tf, - struct dc_info_packet *infopacket) + struct dc_info_packet *infopacket, + bool pack_sdp_v1_3) { /* SPD info packet for FreeSync * VTEM info packet for HdmiVRR @@ -941,6 +960,12 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync, default: build_vrr_infopacket_v1(stream->signal, vrr, infopacket); } + + if (true == pack_sdp_v1_3 && + true == dc_is_dp_signal(stream->signal) && + packet_type != PACKET_TYPE_VRR && + packet_type != PACKET_TYPE_VTEM) + build_vrr_infopacket_sdp_v1_3(packet_type, infopacket); } void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, @@ -1057,10 +1082,10 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, refresh_range >= MIN_REFRESH_RANGE) { in_out_vrr->adjust.v_total_min = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->max_refresh_in_uhz); in_out_vrr->adjust.v_total_max = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->min_refresh_in_uhz); } else if (in_out_vrr->state == VRR_STATE_ACTIVE_FIXED) { in_out_vrr->fixed.target_refresh_in_uhz = @@ -1074,7 +1099,7 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, } else { in_out_vrr->fixed.fixed_active = true; in_out_vrr->adjust.v_total_min = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->fixed.target_refresh_in_uhz); in_out_vrr->adjust.v_total_max = in_out_vrr->adjust.v_total_min; @@ -1181,10 +1206,10 @@ void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync, /* Restore FreeSync */ if (in_out_vrr->btr.frame_counter == 0) { in_out_vrr->adjust.v_total_min = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->max_refresh_in_uhz); in_out_vrr->adjust.v_total_max = - calc_v_total_from_refresh(stream, + mod_freesync_calc_v_total_from_refresh(stream, in_out_vrr->min_refresh_in_uhz); } } @@ -1242,6 +1267,21 @@ unsigned long long mod_freesync_calc_nominal_field_rate( return nominal_field_rate_in_uhz; } +unsigned long long mod_freesync_calc_field_rate_from_timing( + unsigned int vtotal, unsigned int htotal, unsigned int pix_clk) +{ + unsigned long long field_rate_in_uhz = 0; + unsigned int total = htotal * vtotal; + + /* Calculate nominal field rate for stream, rounded up to nearest integer */ + field_rate_in_uhz = pix_clk; + field_rate_in_uhz *= 1000000ULL; + + field_rate_in_uhz = div_u64(field_rate_in_uhz, total); + + return field_rate_in_uhz; +} + bool mod_freesync_is_valid_range(uint32_t min_refresh_cap_in_uhz, uint32_t max_refresh_cap_in_uhz, uint32_t nominal_field_rate_in_uhz) @@ -1304,4 +1344,3 @@ bool mod_freesync_is_valid_range(uint32_t min_refresh_cap_in_uhz, return true; } - |