linux-stable/drivers
maxime@cerno.tech defc98a013 drm/vc4: hdmi: Fix HSM clock too low on Pi4
[ Upstream commit 3bc6a37f59 ]

Commit ae71ab585c ("drm/vc4: hdmi: Enforce the minimum rate at
runtime_resume") reintroduced the call to clk_set_min_rate in an attempt
to fix the boot without a monitor connected on the RaspberryPi3.

However, that introduced a regression breaking the display output
entirely (black screen but no vblank timeout) on the Pi4.

This is due to the fact that we now have in a typical modeset at boot,
in vc4_hdmi_encoder_pre_crtc_configure(), we have a first call to
clk_set_min_rate() asking for the minimum rate of the HSM clock for our
given resolution, and then a call to pm_runtime_resume_and_get(). We
will thus execute vc4_hdmi_runtime_resume() which, since the commit
mentioned above, will call clk_set_min_rate() a second time with the
absolute minimum rate we want to enforce on the HSM clock.

We're thus effectively erasing the minimum mandated by the mode we're
trying to set. The fact that only the Pi4 is affected is due to the fact
that it uses a different clock driver that tries to minimize the HSM
clock at all time. It will thus lower the HSM clock rate to 120MHz on
the second clk_set_min_rate() call.

The Pi3 doesn't use the same driver and will not change the frequency on
the second clk_set_min_rate() call since it's still within the new
boundaries and it doesn't have the code to minimize the clock rate as
needed. So even though the boundaries are still off, the clock rate is
still the right one for our given mode, so everything works.

There is a lot of moving parts, so I couldn't find any obvious
solution:

  - Reverting the original is not an option, as that would break the Pi3
    again.

  - We can't move the clk_set_min_rate() call in _pre_crtc_configure()
    since because, on the Pi3, the HSM clock has the CLK_SET_RATE_GATE
    flag which prevents the clock rate from being changed after it's
    been enabled. Our calls to clk_set_min_rate() can change it, so they
    need to be done before clk_prepare_enable().

  - We can't remove the call to clk_prepare_enable() from the
    runtime_resume hook to put it into _pre_crtc_configure() either,
    since we need that clock to be enabled to access the registers, and
    we can't count on the fact that the display will be active in all
    situations (doing any CEC operation, or listing the modes while
    inactive are valid for example()).

  - We can't drop the call to clk_set_min_rate() in
    _pre_crtc_configure() since we would need to still enforce the
    minimum rate for a given resolution, and runtime_resume doesn't have
    access to the current mode, if there's any.

  - We can't copy the TMDS character rate into vc4_hdmi and reuse it
    since, because it's part of the KMS atomic state, it needs to be
    protected by a mutex. Unfortunately, some functions (CEC operations,
    mostly) can be reentrant (through the CEC framework) and still need
    a pm_runtime_get.

However, we can work around this issue by leveraging the fact that the
clk_set_min_rate() calls set boundaries for its given struct clk, and
that each different clk_get() call will return a different instance of
struct clk. The clock framework will then aggregate the boundaries for
each struct clk instances linked to a given clock, plus its hardware
boundaries, and will use that.

We can thus get an extra HSM clock user for runtime_pm use only, and use
our different clock instances depending on the context: runtime_pm will
use its own to set the absolute minimum clock setup so that we never
lock the CPU waiting for a register access, and the modeset part will
set its requirement for the current resolution. And we let the CCF do
the coordination.

It's not an ideal solution, but it's fairly unintrusive and doesn't
really change any part of the logic so it looks like a rather safe fix.

Link: https://bugzilla.redhat.com/show_bug.cgi?id=2136234
Fixes: ae71ab585c ("drm/vc4: hdmi: Enforce the minimum rate at runtime_resume")
Reported-by: Peter Robinson <pbrobinson@gmail.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Tested-by: Peter Robinson <pbrobinson@gmail.com>
Link: https://lore.kernel.org/r/20221021131339.2203291-1-maxime@cerno.tech
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2022-11-16 10:03:52 +01:00
..
accessibility TTY / Serial driver changes for 6.0-rc1 2022-08-08 11:31:40 -07:00
acpi ACPI: NUMA: Add CXL CFMWS 'nodes' to the possible nodes set 2022-11-10 18:17:31 +01:00
amba ARM: 9229/1: amba: Fix use-after-free in amba_read_periphid() 2022-08-30 11:12:52 +01:00
android Char/Misc driver fixes for 6.0-rc4 2022-09-02 10:50:08 -07:00
ata ata: palmld: fix return value check in palmld_pata_probe() 2022-11-10 18:17:17 +01:00
atm atm: idt77252: fix use-after-free bugs caused by tst_timer 2022-08-08 20:51:59 -07:00
auxdisplay
base PM: domains: Fix handling of unavailable/disabled idle states 2022-11-04 00:00:32 +09:00
bcma
block ublk_drv: return flag of UBLK_F_URING_CMD_COMP_IN_TASK in case of module 2022-11-10 18:17:29 +01:00
bluetooth Bluetooth: virtio_bt: Use skb_put to set length 2022-11-10 18:17:21 +01:00
bus bus: mhi: host: Fix up null pointer access in mhi_irq_handler 2022-08-29 22:33:46 +05:30
cdrom
char hwrng: bcm2835 - use hwrng_msleep() instead of cpu_relax() 2022-11-10 18:17:24 +01:00
clk clk: renesas: r8a779g0: Add SASYNCPER clocks 2022-11-10 18:17:30 +01:00
clocksource clocksource/drivers/timer-gxp: Add missing error handling in gxp_timer_probe 2022-10-21 12:39:00 +02:00
comedi pci-v5.20-changes 2022-08-04 19:30:35 -07:00
connector
counter counter: 104-quad-8: Fix race getting function mode and direction 2022-11-04 00:00:23 +09:00
cpufreq cpufreq: intel_pstate: hybrid: Use known scaling factor for P-cores 2022-11-04 00:00:20 +09:00
cpuidle cpuidle: riscv-sbi: Fix CPU_PM_CPU_IDLE_ENTER_xyz() macro usage 2022-10-21 12:38:56 +02:00
crypto crypto: cavium - prevent integer overflow loading firmware 2022-10-21 12:39:01 +02:00
cxl cxl/region: Recycle region ids 2022-11-16 10:03:50 +01:00
dax devdax: Fix soft-reservation memory description 2022-09-24 18:05:53 -07:00
dca
devfreq More power management updates for 5.20-rc1 2022-08-08 14:29:00 -07:00
dio
dma dmaengine: dw-edma: Remove runtime PM support 2022-10-21 12:39:26 +02:00
dma-buf udmabuf: Set ubuf->sg = NULL if the creation of sg table fails 2022-10-21 12:39:13 +02:00
edac powerpc updates for 6.0 2022-08-06 16:38:17 -07:00
eisa
extcon
firewire firewire: net: Make use of get_unaligned_be48(), put_unaligned_be48() 2022-07-28 22:21:54 -07:00
firmware efi: efivars: Fix variable writes with unsupported query_variable_store() 2022-11-10 18:17:34 +01:00
fpga fpga: prevent integer overflow in dfl_feature_ioctl_set_irq() 2022-10-21 12:38:42 +02:00
fsi fsi: master-ast-cf: Fix missing of_node_put in fsi_master_acf_probe 2022-10-21 12:39:26 +02:00
gnss
gpio gpio: rockchip: request GPIO mux to pinctrl when setting direction 2022-10-21 12:37:45 +02:00
gpu drm/vc4: hdmi: Fix HSM clock too low on Pi4 2022-11-16 10:03:52 +01:00
greybus
hid HID: hyperv: fix possible memory leak in mousevsc_probe() 2022-11-16 10:03:52 +01:00
hsi HSI: ssi_protocol: fix potential resource leak in ssip_pn_open() 2022-10-21 12:39:23 +02:00
hte
hv Drivers: hv: Never allocate anything besides framebuffer from framebuffer memory region 2022-09-05 17:02:15 +00:00
hwmon hwmon/coretemp: Handle large core ID value 2022-10-29 10:08:30 +02:00
hwspinlock hwspinlock: qcom: correct MMIO max register for newer SoCs 2022-11-16 10:03:50 +01:00
hwtracing coresight: cti: Fix hang in cti_disable_hw() 2022-11-04 00:00:22 +09:00
i2c i2c: piix4: Fix adapter not be removed in piix4_remove() 2022-11-10 18:17:30 +01:00
i3c
idle Power management updates for 5.20-rc1 2022-08-02 11:17:00 -07:00
iio iio: adc: stm32-adc: fix channel sampling time init 2022-11-10 18:17:22 +01:00
infiniband RDMA/qedr: clean up work queue on failure in qedr_alloc_resources() 2022-11-10 18:17:16 +01:00
input Input: xpad - fix wireless 360 controller breaking after suspend 2022-10-15 08:02:59 +02:00
interconnect
iommu iommu/vt-d: Clean up si_domain in the init_dmars() error path 2022-10-29 10:08:35 +02:00
ipack
irqchip irqchip/loongson-pch-lpc: Add dependence on LoongArch 2022-09-16 09:25:51 +01:00
isdn isdn: mISDN: netjet: fix wrong check of device registration 2022-11-10 18:17:20 +01:00
leds leds: lm3601x: Don't use mutex after it was destroyed 2022-10-21 12:38:02 +02:00
macintosh
mailbox mailbox: bcm-ferxrm-mailbox: Fix error check for dma_map_sg 2022-10-21 12:38:55 +02:00
mcb
md dm: remove unnecessary assignment statement in alloc_dev() 2022-10-29 10:08:34 +02:00
media media: platform: cros-ec: Add Kuldax to the match table 2022-11-10 18:17:23 +01:00
memory memory: of: Fix refcount leak bug in of_lpddr3_get_ddr_timings() 2022-10-21 12:38:31 +02:00
memstick MMC core: 2022-08-04 19:41:09 -07:00
message
mfd mfd: da9061: Fix Failed to set Two-Wire Bus Mode. 2022-10-21 12:38:52 +02:00
misc misc: ocxl: fix possible refcount leak in afu_ioctl() 2022-10-21 12:38:42 +02:00
mmc mmc: sdhci-esdhc-imx: Propagate ESDHC_FLAG_HS400* only on 8bit bus 2022-11-04 00:00:23 +09:00
most
mtd mtd: rawnand: intel: Add missing of_node_put() in ebu_nand_probe() 2022-11-04 00:00:28 +09:00
mux
net wifi: brcmfmac: Fix potential buffer overflow in brcmf_fweh_event_worker() 2022-11-10 18:17:40 +01:00
nfc nfc: nfcmrvl: Fix potential memory leak in nfcmrvl_i2c_nci_send() 2022-11-10 18:17:17 +01:00
ntb NTB: epf: Allow more flexibility in the memory BAR map method 2022-08-09 17:54:03 -04:00
nubus
nvdimm Merge branch 'for-6.0/dax' into libnvdimm-fixes 2022-09-24 18:14:12 -07:00
nvme nvme-pci: disable write zeroes on various Kingston SSD 2022-11-10 18:17:26 +01:00
nvmem nvmem: core: Fix memleak in nvmem_register() 2022-10-21 12:37:40 +02:00
of of: fdt: fix off-by-one error in unflatten_dt_nodes() 2022-08-16 11:29:57 -06:00
opp OPP: Fix an un-initialized variable usage 2022-08-16 10:48:08 +05:30
parisc parisc: Export iosapic_serial_irq() symbol for serial port driver 2022-11-10 18:17:35 +01:00
parport
pci PCI: Sanitise firmware BAR assignments behind a PCI-PCI bridge 2022-10-21 12:37:43 +02:00
pcmcia
peci peci: cpu: Fix use-after-free in adev_release() 2022-08-15 20:31:35 +02:00
perf RISC-V: Re-enable counter access from userspace 2022-10-21 12:37:39 +02:00
phy phy: stm32: fix an error code in probe 2022-11-16 10:03:50 +01:00
pinctrl pinctrl: ocelot: Fix incorrect trigger of the interrupt. 2022-11-04 00:00:28 +09:00
platform platform/x86/amd: pmc: remove CONFIG_DEBUG_FS checks 2022-11-04 00:00:16 +09:00
pnp
power power: supply: adp5061: fix out-of-bounds read in adp5061_get_chg_type() 2022-10-21 12:39:22 +02:00
powercap powercap: intel_rapl: fix UBSAN shift-out-of-bounds issue 2022-10-21 12:39:04 +02:00
pps
ps3
ptp SPDX changes for 6.0-rc1 2022-08-04 12:12:54 -07:00
pwm SPDX changes for 6.0-rc1 2022-08-04 12:12:54 -07:00
rapidio
ras
regulator regulator: core: Prevent integer underflow 2022-10-21 12:39:08 +02:00
remoteproc remoteproc: Harden rproc_handle_vdev() against integer overflow 2022-10-21 12:38:45 +02:00
reset reset: npcm: fix iprst2 and iprst4 setting 2022-09-22 17:48:35 +02:00
rpmsg rpmsg: char: Avoid double destroy of default endpoint 2022-10-21 12:37:53 +02:00
rtc rtc: spear: set range max 2022-08-09 00:56:41 +02:00
s390 s390/cio: fix out-of-bounds access on cio_ignore free 2022-11-04 00:00:24 +09:00
sbus
scsi scsi: core: Restrict legal sdev_state transitions via sysfs 2022-11-10 18:17:25 +01:00
sh
siox
slimbus slimbus: qcom-ngd: Add error handling in of_qcom_slim_ngd_register 2022-10-21 12:38:49 +02:00
soc soc/tegra: fuse: Drop Kconfig dependency on TEGRA20_APB_DMA 2022-10-21 12:38:34 +02:00
soundwire soundwire: qcom: check for outanding writes before doing a read 2022-11-16 10:03:50 +01:00
spi spi: mediatek: Fix package division error 2022-11-16 10:03:51 +01:00
spmi spmi: pmic-arb: correct duplicate APID to PPID mapping logic 2022-10-21 12:38:53 +02:00
ssb
staging media: hantro: HEVC: Fix chroma offset computation 2022-11-10 18:17:24 +01:00
target SCSI misc on 20220813 2022-08-13 13:41:48 -07:00
tc
tee tee: fix compiler warning in tee_shm_register() 2022-08-25 11:40:06 +02:00
thermal thermal: intel_powerclamp: Use first online CPU as control_cpu 2022-10-26 12:22:55 +02:00
thunderbolt thunderbolt: Add DP OUT resource when DP tunnel is discovered 2022-11-16 10:03:48 +01:00
tty parisc: Make 8250_gsc driver dependend on CONFIG_PARISC 2022-11-10 18:17:35 +01:00
ufs scsi: ufs: core: Reduce the power mode change timeout 2022-08-19 21:34:36 -04:00
uio
usb usb: dwc3: gadget: Don't delay End Transfer on delayed_status 2022-11-10 18:17:14 +01:00
vdpa vdpa/mlx5: Fix MQ to support non power of two num queues 2022-09-27 18:32:45 -04:00
vfio VFIO fix for v6.0-rc5 2022-09-09 07:44:33 -04:00
vhost vhost/vsock: Use kvmalloc/kvfree for larger packets. 2022-10-21 12:38:19 +02:00
video fbdev/core: Avoid uninitialized read in aperture_remove_conflicting_pci_device() 2022-11-04 00:00:24 +09:00
virt kunit: fix Kconfig for build-in tests USB4 and Nitro Enclaves 2022-09-01 13:00:48 -06:00
virtio virtio: kerneldocs fixes and enhancements 2022-08-16 01:40:24 -04:00
vlynq
w1
watchdog linux-watchdog 5.20-rc1 tag 2022-08-08 15:04:04 -07:00
xen xen/gntdev: Accommodate VMA splitting 2022-10-21 12:37:43 +02:00
zorro
Kconfig
Makefile Staging driver patches for 6.0-rc1 2022-08-04 12:01:42 -07:00