Age | Commit message (Collapse) | Author | Files | Lines |
|
pcie_bif ras blocks needs to be initialized as early
as possible to handle fatal error detected in hw_init
phase. also align the pcie_bif ras sw_init with other
ras blocks
Signed-off-by: Hawking Zhang <[email protected]>
Reviewed-by: Stanley Yang <[email protected]>
Reviewed-by: Tao Zhou <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
To align with other IP blocks.
Signed-off-by: Hawking Zhang <[email protected]>
Reviewed-by: Stanley Yang <[email protected]>
Reviewed-by: Tao Zhou <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
To align with other IP blocks
Signed-off-by: Hawking Zhang <[email protected]>
Reviewed-by: Stanley Yang <[email protected]>
Reviewed-by: Tao Zhou <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Handle case when module is unloaded (kfd_exit) before a process space
(mm_struct) is released.
v2: Fixed potential race conditions by removing all kfd_process from
the process table first, then working on releasing the resources.
v3: Fixed loop element access / synchronization. Fixed extra empty lines.
Signed-off-by: David Belanger <[email protected]>
Reviewed-by: Felix Kuehling <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
This version brings along the following:
- FW Release 0.0.158.0
- Fixes to HDCP, DP MST and more
- Improvements on USB4 links and more
- Code re-architecture on link.h
Reviewed-by: Aric Cyr <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Aric Cyr <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[Why & How]
Add boot control bit to control dispclk and dppclk deep sleep
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Anthony Koo <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[Why & How]
Reversed assert condition when checking that phy_pix_clk[] is not 0
Reviewed-by: Alvin Lee <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Samson Tam <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[Why]
The log "DMUB HPD callback" is crucial to identify when DP tunneling
is been established and driver is notified of this event from DMUB.
Same log is shared for long and short hotplug event and we need to
check trailing DC debug log to distinguish between them two, making
debugging on DPIA related issues a bit more troublesome.
[How]
Clearly states in dmesg logs whether this is a long or short hotplug
event.
Reviewed-by: Hamza Mahfooz <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Stylon Wang <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[Why & How]
Make DCN32 functions available for more DCNs.
Reviewed-by: Chris Park <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Wesley Chalmers <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[Why]
If disable the mmhub vm contexts(set MMVM_CONTEXTS_DISABLE to 0xffff),
driver loading failed on vf due to fence fallback timer expired on all rings.
FLR cannot reset MMVM_CONTEXTS_DISABLE.
So this vf can not be recovered anymore unless trigger a whole gpu reset.
[How]
Under SRIOV, init MMVM_CONTEXTS_DISABLE in gmc11 golden register setting.
Signed-off-by: Yifan Zha <[email protected]>
Reviewed-by: Horace Chen <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[Why]
For dual displays where pixel rate is much higher on one display,
we may get underflow when DET is evenly allocated.
[How]
Allocate less DET segments for the lower pixel rate display and
more DET segments for the higher pixel rate display
Reviewed-by: Alvin Lee <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Samson Tam <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[Why]
Framedrops are observed while playing Vp9 and Av1 10 bit
video on 8k resolution using VSR while playback controls
are disappeared/appeared
[How]
Now ODM 2 to 1 is disabled for 5k or greater resolutions on VSR.
Cc: [email protected]
Cc: Mario Limonciello <[email protected]>
Reviewed-by: Alvin Lee <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Ayush Gupta <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[Why]
In USB4 DP tunneling, it's possible to have this scenario that
the path becomes unavailable and CM tears down the path a little bit late.
So, in this case, the HPD is high but fails to read any DPCD register.
That causes the link connection type to be set to sst.
And not all sinks are removed behind the MST branch.
[How]
Restore the link connection type if it fails to read DPCD register.
Cc: [email protected]
Cc: Mario Limonciello <[email protected]>
Reviewed-by: Wenjing Liu <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Cruise Hung <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[Why]
This is the fix for the defect of commit ab144f0b4ad6
("drm/amd/display: Allow individual control of eDP hotplug support").
[How]
To revise the default eDP hotplug setting and use the enum to git rid
of the magic number for different options.
Fixes: ab144f0b4ad6 ("drm/amd/display: Allow individual control of eDP hotplug support")
Cc: [email protected]
Cc: Mario Limonciello <[email protected]>
Reviewed-by: Wenjing Liu <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Robin Chen <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[WHY]
Writing to DRR registers such as OTG_V_TOTAL_MIN on the same frame as a
pipe commit can cause underflow.
Cc: [email protected]
Cc: Mario Limonciello <[email protected]>
Reviewed-by: Jun Lei <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Wesley Chalmers <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
8b/10b encoding needs to add 3% fec overhead into the pbn.
In the Synapcis Cascaded MST hub, the first stage MST branch device
needs the information to determine the timeslot count for the
second stage MST branch device. Missing this overhead will leads to
insufficient timeslot allocation.
Cc: [email protected]
Cc: Mario Limonciello <[email protected]>
Reviewed-by: Hersen Wu <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Fangzhi Zuo <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[WHY]
To validate the BW used for DPIAs per HostRouter
[HOW]
Add the Validate function in C source file
Reviewed-by: Wenjing Liu <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Mustapha Ghaddar <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[WHY]
Hot plugging and then hot unplugging leads to k1 and k2 values to
change, as signal is detected as a virtual signal on hot unplug. Writing
these values to OTG_PIXEL_RATE_DIV register might cause primary display
to blank (known hw bug).
[HOW]
No longer write k1 and k2 values to register if signal is virtual, we
have safe guards in place in the case that k1 and k2 is unassigned so
that an unknown value is not written to the register either.
Cc: [email protected]
Cc: Mario Limonciello <[email protected]>
Reviewed-by: Samson Tam <[email protected]>
Reviewed-by: Alvin Lee <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Saaem Rizvi <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[Why & How]
All dc subcomponents should call another dc component via function pointers
stored in a component structure. This is part of dc coding convention since
the beginning. The reason behind this is to improve encapsulation and
polymorphism. The function contract is extracted into a single link service
structure defined in link.h header file and implemented only in link_factory.c instead
of spreading across multiple files in link component file structure.
Reviewed-by: Jun Lei <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Wenjing Liu <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[WHY]
The VBIOS select the black boundary mode when using auto
scale mode. But it doesn't recover if there is no reset.
[HOW]
Clean the scaler boundary mode to default edge in the manual
scale mode.
Reviewed-by: Dmytro Laktyushkin <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Zhikai Zhai <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[Description]
- For pipe harvesting cases we must use DPP inst instead of
pipe index for DPP related programming
Reviewed-by: Jun Lei <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Alvin Lee <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[why]
Currently if invalid luminescence range is reported in edid,
then the driver doesn't have default range to fallback to.
[How]
Add default range if, the range is 0.
Reviewed-by: Roman Li <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Swapnil Patel <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Traditional synaptics hub has one MST branch device without virtual dpcd.
Synaptics cascaded hub has two chained MST branch devices. DSC decoding
is performed via root MST branch device, instead of the second MST branch
device.
Reviewed-by: Hersen Wu <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Fangzhi Zuo <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
The VCN firmware loading path enables the indirect SRAM mode if it's
advertised as supported. We might have some cases of FW issues that
prevents this mode to working properly though, ending-up in a failed
probe. An example below, observed in the Steam Deck:
[...]
[drm] failed to load ucode VCN0_RAM(0x3A)
[drm] psp gfx command LOAD_IP_FW(0x6) failed and response status is (0xFFFF0000)
amdgpu 0000:04:00.0: [drm:amdgpu_ring_test_helper [amdgpu]] *ERROR* ring vcn_dec_0 test failed (-110)
[drm:amdgpu_device_init.cold [amdgpu]] *ERROR* hw_init of IP block <vcn_v3_0> failed -110
amdgpu 0000:04:00.0: amdgpu: amdgpu_device_ip_init failed
amdgpu 0000:04:00.0: amdgpu: Fatal error during GPU init
[...]
Disabling the VCN block circumvents this, but it's a very invasive
workaround that turns off the entire feature. So, let's add a quirk
on VCN loading that checks for known problematic BIOSes on Vangogh,
so we can proactively disable the indirect SRAM mode and allow the
HW proper probe and VCN IP block to work fine.
Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2385
Fixes: 82132ecc5432 ("drm/amdgpu: enable Vangogh VCN indirect sram mode")
Cc: [email protected]
Cc: James Zhu <[email protected]>
Cc: Leo Liu <[email protected]>
Signed-off-by: Guilherme G. Piccoli <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
We should be checking if drm_dp_dpcd_read() returns the size that we are
asking it to read instead of just checking if it is greater than zero.
So, compare the return value of drm_dp_dpcd_read() to the requested
read size.
Reviewed-by: Rodrigo Siqueira <[email protected]>
Signed-off-by: Hamza Mahfooz <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Copy paste error.
Fixes: 384334120b66 ("drm/amdgpu/nv: don't expose AV1 if VCN0 is harvested")
Reported-by: Abaci Robot <[email protected]>
Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=4454
Cc: Jiapeng Chong <[email protected]>
Acked-by: Guchun Chen <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
When FB_DAMAGE_CLIPS are provided in a non-MPO scenario, the loop does
not use the counter i. This causes the fill_dc_dity_rect() to always
fill dirty_rects[0], causing graphical artifacts when a damage clip
aware DRM client sends more than 1 damage clip.
Instead, use the flip_addrs->dirty_rect_count which is incremented by
fill_dc_dirty_rect() on a successful fill.
Fixes: 30ebe41582d1 ("drm/amd/display: add FB_DAMAGE_CLIPS support")
Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2453
Signed-off-by: Benjamin Cheng <[email protected]>
Signed-off-by: Hamza Mahfooz <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Initialize hdp ras block only when mmhub ip block
supports ras features. Driver queries ras capabilities
after early_init, ras block init needs to be moved to
sw_init.
Signed-off-by: Hawking Zhang <[email protected]>
Reviewed-by: Stanley Yang <[email protected]>
Reviewed-by: Tao Zhou <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Initialize mmhub ras block only when mmhub ip block
supports ras features. Driver queries ras capabilities
after early_init, ras block init needs to be moved to
sw_init.
Signed-off-by: Hawking Zhang <[email protected]>
Reviewed-by: Stanley Yang <[email protected]>
Reviewed-by: Tao Zhou <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Use default gfx ras_late_init callback for gfx
ras block.
Signed-off-by: Hawking Zhang <[email protected]>
Reviewed-by: Stanley Yang <[email protected]>
Reviewed-by: Tao Zhou <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Initialize umc ras block only when umc ip block
supports ras. Driver queries ras capabilities after
early_init, ras block init needs to be moved to
sw_init.
Signed-off-by: Hawking Zhang <[email protected]>
Reviewed-by: Stanley Yang <[email protected]>
Reviewed-by: Tao Zhou <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Initialize vcn ras block only when vcn ip block
supports ras features. Driver queries ras capabilities
after early_init, ras block init needs to be moved to
sw_int.
Signed-off-by: Hawking Zhang <[email protected]>
Reviewed-by: Stanley Yang <[email protected]>
Reviewed-by: Tao Zhou <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Initialize jpeg ras block only when jpeg ip block
supports ras features. Driver queries ras capabilities
after early_init, ras block init needs to be moved to
sw_int.
Signed-off-by: Hawking Zhang <[email protected]>
Reviewed-by: Stanley Yang <[email protected]>
Reviewed-by: Tao Zhou <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Some amd asics having reliable hotplug support don't call
drm_kms_helper_poll_init in driver init sequence. However,
due to the unified suspend/resume path for all asics, because
the output_poll_work->func is not set for these asics, a warning
arrives when suspending.
[ 90.656049] <TASK>
[ 90.656050] ? console_unlock+0x4d/0x100
[ 90.656053] ? __irq_work_queue_local+0x27/0x60
[ 90.656056] ? irq_work_queue+0x2b/0x50
[ 90.656057] ? __wake_up_klogd+0x40/0x60
[ 90.656059] __cancel_work_timer+0xed/0x180
[ 90.656061] drm_kms_helper_poll_disable.cold+0x1f/0x2c [drm_kms_helper]
[ 90.656072] amdgpu_device_suspend+0x81/0x170 [amdgpu]
[ 90.656180] amdgpu_pmops_runtime_suspend+0xb5/0x1b0 [amdgpu]
[ 90.656269] pci_pm_runtime_suspend+0x61/0x1b0
drm_kms_helper_poll_enable/disable is valid when poll_init is called in
amdgpu code, which is only used in non DC path. So move such codes into
non-DC path code to get rid of such warnings.
v1: introduce use_kms_poll flag in amdgpu as the poll stuff check
v2: use dc_enabled as the flag to simply code
v3: move code into non DC path instead of relying on any flag
Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2411
Fixes: a4e771729a51 ("drm/probe_helper: sort out poll_running vs poll_enabled")
Reported-by: Bert Karwatzki <[email protected]>
Suggested-by: Dmitry Baryshkov <[email protected]>
Suggested-by: Alex Deucher <[email protected]>
Signed-off-by: Guchun Chen <[email protected]>
Reviewed-by: Alex Deucher <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
The convert from adev is redundant.
Signed-off-by: Guchun Chen <[email protected]>
Reviewed-by: Christian König <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
pm_sysfs_en is overlapped with pm.sysfs_initialized, so drop it
for simplifying code(no functional change).
Signed-off-by: Guchun Chen <[email protected]>
Acked-by: Christian König <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
This will be used for performance investigations.
Signed-off-by: Marek Olšák <[email protected]>
Reviewed-by: Christian König <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[Why]
On resume some displays are not ready for HDCP, so they will fail if we
start the hdcp authentintication too soon.
Add a delay so that the displays can be ready before we start.
NOTE: Previoulsy this delay was set to 3 seconds but it was causing
issues with compliance, 2 seconds should enough for compliance and the
s3 resume case.
[How]
Change the Delay to 2 seconds.
Reviewed-by: Aurabindo Pillai <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
Signed-off-by: Bhawanpreet Lakha <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
kgd_mem pointers returned by kfd_process_device_translate_handle are
only guaranteed to be valid while p->mutex is held. As soon as the mutex
is unlocked, another thread can free the BO.
Signed-off-by: Chia-I Wu <[email protected]>
Signed-off-by: Felix Kuehling <[email protected]>
Reviewed-by: Felix Kuehling <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
[Why]
Currently there aren't any methods to determine PSR state residency.
[How]
create a sysfs entry for reading residency and internally hook it up
to existing functionality of reading PSR residency from firmware.
[Hamza: dropped the link.h include and made checkpatch happy]
Signed-off-by: Shirish S <[email protected]>
Signed-off-by: Hamza Mahfooz <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
for sriov, we added a new flag to indicate av1 support,
this will override the original caps info.
Signed-off-by: Jane Jian <[email protected]>
Acked-by: Alex Deucher <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
During miration to vram prange->offset is valid after vram buffer is located,
either use old one or allocate a new one. Move svm_range_vram_node_new before
migrate for each vma to get valid prange->offset.
v2: squash in warning fix
Fixes: 9473b6b25b83 ("drm/amdkfd: Fix BO offset for multi-VMA page migration")
Signed-off-by: Xiaogang Chen <[email protected]>
Reviewed-by: Felix Kuehling <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Checked against database, copied from GC 9.4.2 header.
Signed-off-by: Tom St Denis <[email protected]>
Acked-by: Alex Deucher <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Temperature limits are not available for SMU v13.0.6. Also, edge
temperature is not tracked. Remove logic associated with those.
Signed-off-by: Lijo Lazar <[email protected]>
Reviewed-by: Hawking Zhang <[email protected]>
Reviewed-by: Yang Wang <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Swap is a function interface that provides exchange function. To avoid
code duplication, we can use swap function.
./drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c:359:57-58: WARNING opportunity for swap().
Reported-by: Abaci Robot <[email protected]>
Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=4448
Signed-off-by: Jiapeng Chong <[email protected]>
Signed-off-by: Hamza Mahfooz <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Always setup overdrive tables after resume. Preserve only some
user-defined settings in user_overdrive_table if they're set.
Copy restored user_overdrive_table into od_table to get correct
values.
On cold boot, BTC was triggered and GfxVfCurve was calibrated. We
got VfCurve settings (a). On resuming back, BTC will be triggered
again and GfxVfCurve will be recalibrated. VfCurve settings (b)
got may be different from those of cold boot. So if we reuse
those VfCurve settings (a) got on cold boot on suspend, we can
run into discrepencies.
Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1897
Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2276
Reviewed-by: Evan Quan <[email protected]>
Signed-off-by: Błażej Szczygieł <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Align the SMU driver interface version with PMFW to
suppress the version mismatch message on driver loading.
Signed-off-by: Tim Huang <[email protected]>
Reviewed-by: Alex Deucher <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
Set *q to NULL on errors, otherwise pqm_create_queue would free it
again.
Signed-off-by: Chia-I Wu <[email protected]>
Signed-off-by: Felix Kuehling <[email protected]>
Reviewed-by: Felix Kuehling <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
With gcc and W=1, there is this error
drivers/gpu/drm/amd/amdgpu/../display/dc/link/protocols/link_dp_dpia_bw.c:297:13: error:
variable ‘available’ set but not used [-Werror=unused-but-set-variable]
297 | int available = 0;
| ^~~~~~~~~
Since available is unused, remove it.
Signed-off-by: Tom Rix <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|
|
With gcc and W=1, there is this error
drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_mst_types.c:1214:31:
error: variable ‘res_pool’ set but not used [-Werror=unused-but-set-variable]
1214 | struct resource_pool *res_pool;
| ^~~~~~~~
Since res_pool is unused, remove it.
Signed-off-by: Tom Rix <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
|