`fops->show_fdinfo()` as part of the driver specific file operations registered
in the `struct drm_driver` object registered with the DRM core.
- One purpose of this output is to enable writing as generic as practicaly
+ One purpose of this output is to enable writing as generic as practically
feasible `top(1)` like userspace monitoring tools.
Given the differences between various DRM drivers the specification of the
engine. Taken together with drm-cycles-<keystr>, this can be used to calculate
percentage utilization of the engine, whereas drm-engine-<keystr> only reflects
time active without considering what frequency the engine is operating as a
- percentage of it's maximum frequency.
+ percentage of its maximum frequency.
Memory
^^^^^^
-------------------------------
:ref:`i915-usage-stats`
+:ref:`panfrost-usage-stats`
F: drivers/crypto/ccp/sev*
F: include/uapi/linux/psp-sev.h
+ AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER - DBC SUPPORT
+ S: Supported
+ F: drivers/crypto/ccp/dbc.c
+ F: drivers/crypto/ccp/dbc.h
+ F: drivers/crypto/ccp/platform-access.c
+ F: drivers/crypto/ccp/platform-access.h
+ F: include/uapi/linux/psp-dbc.h
+ F: tools/crypto/ccp/*.c
+ F: tools/crypto/ccp/*.py
+
AMD DISPLAY CORE
S: Maintained
- F: drivers/platform/x86/amd/pmc.c
+ F: drivers/platform/x86/amd/pmc/
AMD PMF DRIVER
AMPHION VPU CODEC V4L2 DRIVER
S: Maintained
S: Maintained
+ P: Documentation/process/maintainer-soc.rst
C: irc://irc.libera.chat/armlinux
T: git git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git
- F: Documentation/process/maintainer-soc.rst
+ F: Documentation/process/maintainer-soc*.rst
F: arch/arm/boot/dts/Makefile
F: arch/arm64/boot/dts/Makefile
S: Supported
T: git git://anongit.freedesktop.org/drm/drm-misc
+F: Documentation/gpu/panfrost.rst
F: drivers/gpu/drm/panfrost/
F: include/uapi/drm/panfrost_drm.h
F: arch/arm/boot/dts/amlogic/
F: arch/arm/mach-meson/
F: arch/arm64/boot/dts/amlogic/
+ F: drivers/pmdomain/amlogic/
F: drivers/mmc/host/meson*
F: drivers/phy/amlogic/
F: drivers/pinctrl/meson/
S: Maintained
+ F: Documentation/devicetree/bindings/sound/adi,ssm3515.yaml
F: Documentation/devicetree/bindings/sound/apple,*
F: sound/soc/apple/*
F: sound/soc/codecs/cs42l83-i2c.c
+ F: sound/soc/codecs/ssm3515.c
ARM/APPLE MACHINE SUPPORT
F: drivers/clk/clk-apple-nco.c
F: drivers/cpufreq/apple-soc-cpufreq.c
F: drivers/dma/apple-admac.c
+ F: drivers/pmdomain/apple/
F: drivers/i2c/busses/i2c-pasemi-core.c
F: drivers/i2c/busses/i2c-pasemi-platform.c
F: drivers/iommu/apple-dart.c
ARM/MICROCHIP (ARM64) SoC support
- M: Claudiu Beznea <claudiu.beznea@microchip.com>
+ M: Claudiu Beznea <claudiu.beznea@tuxon.dev>
S: Supported
T: git https://git.kernel.org/pub/scm/linux/kernel/git/at91/linux.git
ARM/Microchip (AT91) SoC support
- M: Claudiu Beznea <claudiu.beznea@microchip.com>
+ M: Claudiu Beznea <claudiu.beznea@tuxon.dev>
S: Supported
W: http://www.linux4sam.org
F: drivers/clk/clk-nomadik.c
F: drivers/clocksource/clksrc-dbx500-prcmu.c
F: drivers/dma/ste_dma40*
+ F: drivers/pmdomain/st/ste-ux500-pm-domain.c
F: drivers/hwspinlock/u8500_hsem.c
F: drivers/i2c/busses/i2c-nomadik.c
F: drivers/iio/adc/ab8500-gpadc.c
W: http://www.digriz.org.uk/ts78xx/kernel
F: arch/arm/mach-orion5x/ts78xx-*
- ARM/OXNAS platform support
- S: Maintained
- F: arch/arm/boot/dts/ox8*.dts*
- F: arch/arm/mach-oxnas/
- F: drivers/power/reset/oxnas-restart.c
- N: oxnas
-
ARM/QUALCOMM CHROMEBOOK SUPPORT
F: arch/arm64/boot/dts/qcom/sc7180*
F: arch/arm/mach-shmobile/
F: arch/arm64/boot/dts/renesas/
F: arch/riscv/boot/dts/renesas/
+ F: drivers/pmdomain/renesas/
F: drivers/soc/renesas/
F: include/linux/soc/renesas/
K: \brenesas,
S: Maintained
+ P: Documentation/process/maintainer-soc-clean-dts.rst
Q: https://patchwork.kernel.org/project/linux-samsung-soc/list/
C: irc://irc.libera.chat/linux-exynos
S: Maintained
- F: */*/*/vexpress*
- F: */*/vexpress*
- F: arch/arm/boot/dts/arm/vexpress*
+ N: mps2
+ N: vexpress
F: arch/arm/mach-versatile/
F: arch/arm64/boot/dts/arm/
- F: drivers/clk/versatile/clk-vexpress-osc.c
F: drivers/clocksource/timer-versatile.c
- N: mps2
+ X: drivers/cpufreq/vexpress-spc-cpufreq.c
+ X: Documentation/devicetree/bindings/arm/arm,vexpress-juno.yaml
ARM/VFP SUPPORT
ATMEL MACB ETHERNET DRIVER
- M: Claudiu Beznea <claudiu.beznea@microchip.com>
+ M: Claudiu Beznea <claudiu.beznea@tuxon.dev>
S: Supported
F: drivers/net/ethernet/cadence/
F: drivers/input/touchscreen/atmel_mxt_ts.c
ATMEL WIRELESS DRIVER
- S: Maintained
+ S: Orphan
W: http://www.thekelleys.org.uk/atmel
W: http://atmelwlandriver.sourceforge.net/
F: drivers/net/wireless/atmel/atmel*
B43 WIRELESS DRIVER
- S: Odd Fixes
+ S: Orphan
W: https://wireless.wiki.kernel.org/en/users/Drivers/b43
F: drivers/net/wireless/broadcom/b43/
F: include/linux/tnum.h
F: kernel/bpf/core.c
F: kernel/bpf/dispatcher.c
+ F: kernel/bpf/mprog.c
F: kernel/bpf/syscall.c
F: kernel/bpf/tnum.c
F: kernel/bpf/trampoline.c
S: Maintained
- F: Documentation/bpf/instruction-set.rst
+ F: Documentation/bpf/standardization/
BPF [GENERAL] (Safe Dynamic Programs and Tools)
F: tools/testing/selftests/bpf/
BPF [ITERATOR]
S: Maintained
F: kernel/bpf/*iter.c
S: Maintained
F: kernel/bpf/bpf_struct*
- BPF [NETWORKING] (tc BPF, sock_addr)
+ BPF [NETWORKING] (tcx & tc BPF, sock_addr)
S: Maintained
+ F: include/net/tcx.h
+ F: kernel/bpf/tcx.c
F: net/core/filter.c
F: net/sched/act_bpf.c
F: net/sched/cls_bpf.c
F: kernel/bpf/stackmap.c
F: kernel/trace/bpf_trace.c
+ BROADCOM ASP 2.0 ETHERNET DRIVER
+ S: Supported
+ F: Documentation/devicetree/bindings/net/brcm,asp-v2.0.yaml
+ F: drivers/net/ethernet/broadcom/asp2/
+
BROADCOM B44 10/100 ETHERNET DRIVER
F: drivers/irqchip/irq-bcm63*
F: drivers/irqchip/irq-bcm7*
F: drivers/irqchip/irq-brcmstb*
- F: drivers/soc/bcm/bcm63xx
+ F: drivers/pmdomain/bcm/bcm63xx-power.c
F: include/linux/bcm963xx_nvram.h
F: include/linux/bcm963xx_tag.h
S: Odd Fixes
- F: Documentation/devicetree/bindings/spi/spi-bcm63xx.txt
+ F: Documentation/devicetree/bindings/spi/brcm,bcm63xx-spi.yaml
F: drivers/spi/spi-bcm63xx.c
BROADCOM ETHERNET PHY DRIVERS
S: Supported
- F: Documentation/devicetree/bindings/gpio/brcm,kona-gpio.txt
+ F: Documentation/devicetree/bindings/gpio/brcm,kona-gpio.yaml
F: drivers/gpio/gpio-bcm-kona.c
BROADCOM MPI3 STORAGE CONTROLLER DRIVER
S: Maintained
T: git https://github.com/broadcom/stblinux.git
- F: drivers/soc/bcm/bcm63xx/bcm-pmb.c
+ F: drivers/pmdomain/bcm/bcm-pmb.c
F: include/dt-bindings/soc/bcm-pmb.h
BROADCOM SPECIFIC AMBA DRIVER (BCMA)
S: Maintained
W: https://btrfs.readthedocs.io
- W: https://btrfs.wiki.kernel.org/
Q: https://patchwork.kernel.org/project/linux-btrfs/list/
C: irc://irc.libera.chat/btrfs
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git
S: Maintained
F: Documentation/devicetree/bindings/media/cdns,*.txt
+ F: Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
F: drivers/media/platform/cadence/cdns-csi2*
CADENCE NAND DRIVER
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git
CHROME HARDWARE PLATFORM SUPPORT
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git
S: Maintained
F: Documentation/devicetree/bindings/sound/cirrus,cs*
+ F: drivers/mfd/cs42l43*
+ F: drivers/pinctrl/cirrus/pinctrl-cs42l43*
+ F: drivers/spi/spi-cs42l43*
F: include/dt-bindings/sound/cs*
+ F: include/linux/mfd/cs42l43*
F: include/sound/cs*
F: sound/pci/hda/cs*
F: sound/pci/hda/hda_cs_dsp_ctl.*
F: include/linux/compiler_attributes.h
COMPUTE EXPRESS LINK (CXL)
S: Maintained
F: Documentation/admin-guide/cgroup-v1/cpusets.rst
F: include/linux/cpuset.h
F: kernel/cgroup/cpuset.c
+ F: tools/testing/selftests/cgroup/test_cpuset.c
+ F: tools/testing/selftests/cgroup/test_cpuset_prs.sh
CONTROL GROUP - MEMORY RESOURCE CONTROLLER (MEMCG)
- S: Supported
+ S: Maintained
F: arch/arm/mach-exynos/pm.c
F: drivers/cpuidle/cpuidle-exynos.c
F: include/linux/platform_data/cpuidle-exynos.h
F: drivers/net/can/ctucanfd/
CW1200 WLAN driver
- S: Maintained
+ S: Orphan
F: drivers/net/wireless/st/cw1200/
CX18 VIDEO4LINUX DRIVER
F: Documentation/devicetree/bindings/mfd/dlg,da90*.yaml
F: Documentation/devicetree/bindings/regulator/da92*.txt
F: Documentation/devicetree/bindings/regulator/dlg,da9*.yaml
- F: Documentation/devicetree/bindings/regulator/slg51000.txt
+ F: Documentation/devicetree/bindings/regulator/dlg,slg51000.yaml
F: Documentation/devicetree/bindings/sound/da[79]*.txt
F: Documentation/devicetree/bindings/thermal/da90??-thermal.txt
F: Documentation/devicetree/bindings/watchdog/da90??-wdt.txt
DISTRIBUTED LOCK MANAGER (DLM)
S: Supported
W: http://sources.redhat.com/cluster/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm.git
S: Maintained
+ F: Documentation/maintainer/
F: Documentation/process/
DOCUMENTATION REPORTING ISSUES
F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.yaml
F: drivers/media/i2c/dw9714.c
- DONGWOON DW9768 LENS VOICE COIL DRIVER
- M: Dongchun Zhu <dongchun.zhu@mediatek.com>
+ DONGWOON DW9719 LENS VOICE COIL DRIVER
+ M: Daniel Scally <djrscally@gmail.com>
S: Maintained
T: git git://linuxtv.org/media_tree.git
+ F: drivers/media/i2c/dw9719.c
+
+ DONGWOON DW9768 LENS VOICE COIL DRIVER
+ S: Orphan
+ T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9768.yaml
F: drivers/media/i2c/dw9768.c
S: Maintained
W: https://01.org/linuxgraphics/gfx-docs/maintainer-tools/drm-misc.html
T: git git://anongit.freedesktop.org/drm/drm-misc
+F: Documentation/devicetree/bindings/display/
+F: Documentation/devicetree/bindings/gpu/
F: Documentation/gpu/
-F: drivers/gpu/drm/*
+F: drivers/gpu/drm/
F: drivers/gpu/vga/
-F: include/drm/drm*
+F: include/drm/drm
F: include/linux/vga*
-F: include/uapi/drm/drm*
+F: include/uapi/drm/
+X: drivers/gpu/drm/amd/
+X: drivers/gpu/drm/armada/
+X: drivers/gpu/drm/etnaviv/
+X: drivers/gpu/drm/exynos/
+X: drivers/gpu/drm/i915/
+X: drivers/gpu/drm/kmb/
+X: drivers/gpu/drm/mediatek/
+X: drivers/gpu/drm/msm/
+X: drivers/gpu/drm/nouveau/
+X: drivers/gpu/drm/radeon/
+X: drivers/gpu/drm/renesas/
+X: drivers/gpu/drm/tegra/
DRM DRIVERS FOR ALLWINNER A10
F: drivers/gpu/drm/ttm/
F: include/drm/ttm/
+ DRM AUTOMATED TESTING
+ S: Maintained
+ T: git git://anongit.freedesktop.org/drm/drm-misc
+ F: Documentation/gpu/automated_testing.rst
+ F: drivers/gpu/drm/ci/
+
DSBR100 USB FM RADIO DRIVER
S: Supported
F: drivers/mmc/host/cqhci*
+ EMS CPC-PCI CAN DRIVER
+ S: Maintained
+ F: drivers/net/can/sja1000/ems_pci.c
+
EMULEX 10Gbps iSCSI - OneConnect DRIVER
F: include/linux/of_net.h
F: include/linux/phy.h
F: include/linux/phy_fixed.h
+ F: include/linux/phylib_stubs.h
F: include/linux/platform_data/mdio-bcm-unimac.h
F: include/linux/platform_data/mdio-gpio.h
F: include/trace/events/mdio.h
S: Maintained
F: drivers/net/ethernet/freescale/fs_enet/
- F: include/linux/fs_enet_pd.h
FREESCALE SOC SOUND DRIVERS
F: include/linux/freezer.h
F: kernel/freezer.c
- FRONTSWAP API
- S: Maintained
- F: include/linux/frontswap.h
- F: mm/frontswap.c
-
FS-CACHE: LOCAL CACHING FOR NETWORK FILESYSTEMS
F: drivers/base/power/domain*.c
F: include/linux/pm_domain.h
+ GENERIC PM DOMAIN PROVIDERS
+ S: Supported
+ T: git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git
+ F: drivers/pmdomain/
+
GENERIC RESISTIVE TOUCHSCREEN ADC DRIVER
GFS2 FILE SYSTEM
S: Supported
B: https://bugzilla.kernel.org/enter_bug.cgi?product=File%20System&component=gfs2
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2.git
F: Documentation/networking/device_drivers/ethernet/google/gve.rst
F: drivers/net/ethernet/google
+ GOOGLE FIRMWARE DRIVERS
+ S: Maintained
+ T: git git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git
+ F: drivers/firmware/google/
+
GPD POCKET FAN DRIVER
S: Maintained
F: drivers/gpio/gpio-regmap.c
F: include/linux/gpio/regmap.h
+ K: (devm_)?gpio_regmap_(un)?register
GPIO SUBSYSTEM
F: drivers/crypto/hisilicon/hpre/hpre_main.c
HISILICON HNS3 PMU DRIVER
- M: Guangbin Huang <huangguangbin2@huawei.com>
+ M: Jijie Shao <shaojijie@huawei.com>
S: Supported
F: Documentation/admin-guide/perf/hns3-pmu.rst
F: drivers/perf/hisilicon/hns3_pmu.c
F: Documentation/devicetree/bindings/i2c/hisilicon,ascend910-i2c.yaml
F: drivers/i2c/busses/i2c-hisi.c
+ HISILICON KUNPENG SOC HCCS DRIVER
+ S: Maintained
+ F: Documentation/ABI/testing/sysfs-devices-platform-kunpeng_hccs
+ F: drivers/soc/hisilicon/kunpeng_hccs.c
+ F: drivers/soc/hisilicon/kunpeng_hccs.h
+
HISILICON LPC BUS DRIVER
S: Maintained
F: drivers/net/ethernet/hisilicon/
HISILICON PMU DRIVER
- M: Shaokun Zhang <zhangshaokun@hisilicon.com>
+ M: Yicong Yang <yangyicong@hisilicon.com>
S: Supported
W: http://www.hisilicon.com
F: include/linux/hisi_acc_qm.h
HISILICON ROCE DRIVER
S: Maintained
W: http://w1.fi/hostap-driver.html
F: drivers/net/wireless/intersil/hostap/
+ HP BIOSCFG DRIVER
+ S: Maintained
+ F: drivers/platform/x86/hp/hp-bioscfg/
+
HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER
S: Orphan
W: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
F: fs/hpfs/
+ HS3001 Hardware Temperature and Humidity Sensor
+ S: Maintained
+ F: drivers/hwmon/hs3001.c
+
HSI SUBSYSTEM
S: Maintained
F: arch/x86/kernel/cpu/hygon.c
HYNIX HI556 SENSOR DRIVER
- M: Shawn Tu <shawnx.tu@intel.com>
+ M: Sakari Ailus <sakari.ailus@linux.intel.com>
S: Maintained
T: git git://linuxtv.org/media_tree.git
F: drivers/media/i2c/hi846.c
HYNIX HI847 SENSOR DRIVER
- M: Shawn Tu <shawnx.tu@intel.com>
+ M: Sakari Ailus <sakari.ailus@linux.intel.com>
S: Maintained
F: drivers/media/i2c/hi847.c
HYPERBUS SUPPORT
S: Supported
Q: http://patchwork.ozlabs.org/project/linux-mtd/list/
S: Maintained
F: drivers/i2c/i2c-core-acpi.c
+ I2C ADDRESS TRANSLATOR (ATR)
+ S: Maintained
+ F: drivers/i2c/i2c-atr.c
+ F: include/linux/i2c-atr.h
+
I2C CONTROLLER DRIVER FOR NVIDIA GPU
S: Maintained
+ F: Documentation/ABI/testing/debugfs-tpmi
F: drivers/platform/x86/intel/tpmi.c
F: include/linux/intel_tpmi.h
F: include/trace/events/io_uring.h
F: include/uapi/linux/io_uring.h
F: io_uring/
- F: tools/io_uring/
IPMI SUBSYSTEM
F: scripts/mk*
F: scripts/mod/
F: scripts/package/
+ F: usr/
KERNEL HARDENING (not covered by other areas)
F: Documentation/dev-tools/kunit/
F: include/kunit/
F: lib/kunit/
+ F: rust/kernel/kunit.rs
+ F: scripts/rustdoc_test_*
F: tools/testing/kunit/
KERNEL USERMODE HELPER
F: arch/x86/include/uapi/asm/vmx.h
F: arch/x86/kvm/
F: arch/x86/kvm/*/
+ F: tools/testing/selftests/kvm/*/x86_64/
+ F: tools/testing/selftests/kvm/x86_64/
KERNFS
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson.git
- F: Documentation/loongarch/
- F: Documentation/translations/zh_CN/loongarch/
+ F: Documentation/arch/loongarch/
+ F: Documentation/translations/zh_CN/arch/loongarch/
F: arch/loongarch/
F: drivers/*/*loongarch*
F: drivers/clk/clk-loongson2.c
F: include/dt-bindings/clock/loongson,ls2k-clk.h
+ LOONGSON SPI DRIVER
+ S: Maintained
+ F: Documentation/devicetree/bindings/spi/loongson,ls2k-spi.yaml
+ F: drivers/spi/spi-loongson-core.c
+ F: drivers/spi/spi-loongson-pci.c
+ F: drivers/spi/spi-loongson-plat.c
+ F: drivers/spi/spi-loongson.h
+
LOONGSON-2 SOC SERIES GUTS DRIVER
F: Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml
F: drivers/soc/loongson/loongson2_guts.c
+ LOONGSON-2 SOC SERIES PM DRIVER
+ S: Maintained
+ F: Documentation/devicetree/bindings/soc/loongson/loongson,ls2k-pmc.yaml
+ F: drivers/soc/loongson/loongson2_pm.c
+
LOONGSON-2 SOC SERIES PINCTRL DRIVER
F: Documentation/devicetree/bindings/pinctrl/loongson,ls2k-pinctrl.yaml
F: drivers/pinctrl/pinctrl-loongson2.c
+ LOONGSON-2 SOC SERIES THERMAL DRIVER
+ S: Maintained
+ F: Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml
+ F: drivers/thermal/loongson2_thermal.c
+
LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
MAPLE TREE
S: Supported
F: Documentation/core-api/maple_tree.rst
F: drivers/net/ethernet/marvell/mvpp2/
MARVELL MWIFIEX WIRELESS DRIVER
- S: Maintained
+ S: Odd Fixes
F: drivers/net/wireless/marvell/mwifiex/
MARVELL MWL8K WIRELESS DRIVER
- S: Odd Fixes
+ S: Orphan
F: drivers/net/wireless/marvell/mwl8k.c
MARVELL NAND CONTROLLER DRIVER
MAXIM MUIC CHARGER DRIVERS FOR EXYNOS BASED BOARDS
- S: Supported
+ S: Maintained
F: Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml
F: Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml
- S: Supported
+ S: Maintained
F: Documentation/devicetree/bindings/*/maxim,max14577.yaml
F: Documentation/devicetree/bindings/*/maxim,max77686.yaml
F: include/linux/imx-media.h
F: include/media/imx.h
- MEDIA DRIVERS FOR FREESCALE IMX7
+ MEDIA DRIVERS FOR FREESCALE IMX7/8
S: Maintained
T: git git://linuxtv.org/media_tree.git
F: Documentation/admin-guide/media/imx7.rst
F: Documentation/devicetree/bindings/media/nxp,imx-mipi-csi2.yaml
F: Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml
+ F: Documentation/devicetree/bindings/media/nxp,imx8mq-mipi-csi2.yaml
F: drivers/media/platform/nxp/imx-mipi-csis.c
F: drivers/media/platform/nxp/imx7-media-csi.c
+ F: drivers/media/platform/nxp/imx8mq-mipi-csi2.c
MEDIA DRIVERS FOR HELENE
S: Supported
F: Documentation/devicetree/bindings/iommu/mediatek*
F: drivers/iommu/mtk_iommu*
+ F: include/dt-bindings/memory/mediatek,mt*-port.h
F: include/dt-bindings/memory/mt*-port.h
MEDIATEK JPEG DRIVER
F: include/linux/mm.h
F: include/linux/mmzone.h
F: include/linux/pagewalk.h
+ F: include/linux/rmap.h
F: include/trace/events/ksm.h
F: mm/
F: tools/mm/
F: drivers/spi/spi-at91-usart.c
MICROCHIP AUDIO ASOC DRIVERS
- M: Claudiu Beznea <claudiu.beznea@microchip.com>
+ M: Claudiu Beznea <claudiu.beznea@tuxon.dev>
S: Supported
F: Documentation/devicetree/bindings/sound/atmel*
F: drivers/crypto/atmel-ecc.*
MICROCHIP EIC DRIVER
- M: Claudiu Beznea <claudiu.beznea@microchip.com>
+ M: Claudiu Beznea <claudiu.beznea@tuxon.dev>
S: Supported
F: Documentation/devicetree/bindings/interrupt-controller/microchip,sama7g5-eic.yaml
F: include/video/atmel_lcdc.h
MICROCHIP MCP16502 PMIC DRIVER
- M: Claudiu Beznea <claudiu.beznea@microchip.com>
+ M: Claudiu Beznea <claudiu.beznea@tuxon.dev>
S: Supported
F: Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
F: drivers/mtd/nand/raw/atmel/*
MICROCHIP OTPC DRIVER
- M: Claudiu Beznea <claudiu.beznea@microchip.com>
+ M: Claudiu Beznea <claudiu.beznea@tuxon.dev>
S: Supported
F: Documentation/devicetree/bindings/nvmem/microchip,sama7g5-otpc.yaml
F: include/dt-bindings/nvmem/microchip,sama7g5-otpc.h
MICROCHIP PCI1XXXX GP DRIVER
S: Supported
F: drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.c
F: drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.h
F: drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c
+ F: drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_otpe2p.c
MICROCHIP PCI1XXXX I2C DRIVER
F: drivers/fpga/microchip-spi.c
MICROCHIP PWM DRIVER
- M: Claudiu Beznea <claudiu.beznea@microchip.com>
+ M: Claudiu Beznea <claudiu.beznea@tuxon.dev>
S: Supported
F: include/dt-bindings/iio/adc/at91-sama5d2_adc.h
MICROCHIP SAMA5D2-COMPATIBLE SHUTDOWN CONTROLLER
- M: Claudiu Beznea <claudiu.beznea@microchip.com>
+ M: Claudiu Beznea <claudiu.beznea@tuxon.dev>
S: Supported
F: Documentation/devicetree/bindings/power/reset/atmel,sama5d2-shdwc.yaml
F: drivers/power/reset/at91-sama5d2_shdwc.c
F: drivers/spi/spi-atmel.*
MICROCHIP SSC DRIVER
- M: Claudiu Beznea <claudiu.beznea@microchip.com>
+ M: Claudiu Beznea <claudiu.beznea@tuxon.dev>
S: Supported
F: Documentation/devicetree/bindings/misc/atmel-ssc.txt
MICROCHIP WILC1000 WIFI DRIVER
- M: Claudiu Beznea <claudiu.beznea@microchip.com>
+ M: Claudiu Beznea <claudiu.beznea@tuxon.dev>
S: Supported
F: drivers/net/wireless/microchip/wilc1000/
Q: https://patchwork.kernel.org/project/linux-mips/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git
F: Documentation/devicetree/bindings/mips/
- F: Documentation/mips/
+ F: Documentation/arch/mips/
F: arch/mips/
F: drivers/platform/mips/
F: include/dt-bindings/mips/
F: include/linux/mfd/ntxec.h
NETRONOME ETHERNET DRIVERS
- M: Simon Horman <simon.horman@corigine.com>
+ M: Louis Peens <louis.peens@corigine.com>
S: Maintained
F: net/netfilter/xt_SECMARK.c
F: net/netlabel/
+ NETWORKING [MACSEC]
+ S: Maintained
+ F: drivers/net/macsec.c
+ F: include/net/macsec.h
+ F: include/uapi/linux/if_macsec.h
+ K: macsec
+ K: \bmdo_
+
NETWORKING [MPTCP]
S: Maintained
- F: include/linux/net_mm.h
F: include/linux/tcp.h
F: include/net/tcp.h
F: include/trace/events/tcp.h
NOLIBC HEADER FILE
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/wtarreau/nolibc.git
F: tools/include/nolibc/
S: Maintained
+T: git git://anongit.freedesktop.org/drm/drm-misc
F: Documentation/devicetree/bindings/display/imx/nxp,imx8mq-dcss.yaml
F: drivers/gpu/drm/imx/dcss/
W: http://linux.omap.com/
Q: http://patchwork.kernel.org/project/linux-omap/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git
+ F: Documentation/devicetree/bindings/arm/ti/omap.yaml
F: arch/arm/configs/omap2plus_defconfig
F: arch/arm/mach-omap2/
F: drivers/bus/ti-sysc.c
F: fs/omfs/
OMNIVISION OG01A1B SENSOR DRIVER
- M: Shawn Tu <shawnx.tu@intel.com>
+ M: Sakari Ailus <sakari.ailus@linux.intel.com>
S: Maintained
F: drivers/media/i2c/og01a1b.c
F: drivers/media/i2c/ov01a10.c
OMNIVISION OV02A10 SENSOR DRIVER
- S: Maintained
+ S: Orphan
T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/i2c/ovti,ov02a10.yaml
F: drivers/media/i2c/ov02a10.c
OMNIVISION OV2680 SENSOR DRIVER
S: Maintained
T: git git://linuxtv.org/media_tree.git
OMNIVISION OV2740 SENSOR DRIVER
- R: Shawn Tu <shawnx.tu@intel.com>
+ R: Sakari Ailus <sakari.ailus@linux.intel.com>
S: Maintained
F: drivers/media/i2c/ov5647.c
OMNIVISION OV5670 SENSOR DRIVER
- M: Chiranjeevi Rapolu <chiranjeevi.rapolu@intel.com>
+ M: Sakari Ailus <sakari.ailus@linux.intel.com>
S: Maintained
T: git git://linuxtv.org/media_tree.git
F: drivers/media/i2c/ov5670.c
OMNIVISION OV5675 SENSOR DRIVER
- M: Shawn Tu <shawnx.tu@intel.com>
+ M: Sakari Ailus <sakari.ailus@linux.intel.com>
S: Maintained
T: git git://linuxtv.org/media_tree.git
F: include/media/i2c/ov772x.h
OMNIVISION OV7740 SENSOR DRIVER
- S: Maintained
+ S: Orphan
T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/i2c/ov7740.txt
F: drivers/media/i2c/ov7740.c
S: Supported
F: Documentation/networking/page_pool.rst
- F: include/net/page_pool.h
+ F: include/net/page_pool/
F: include/trace/events/page_pool.h
F: net/core/page_pool.c
PCI DRIVER FOR SYNOPSYS DESIGNWARE
S: Maintained
F: Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml
S: Supported
W: https://perf.wiki.kernel.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
+ T: git git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools.git perf-tools
+ T: git git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git perf-tools-next
F: arch/*/events/*
F: arch/*/events/*/*
F: arch/*/include/asm/perf_event.h
S: Maintained
W: http://wiki.enneenne.com/index.php/LinuxPPS_support
F: Documentation/ABI/testing/sysfs-pps
- F: Documentation/devicetree/bindings/pps/pps-gpio.txt
+ F: Documentation/devicetree/bindings/pps/pps-gpio.yaml
F: Documentation/driver-api/pps.rst
F: drivers/pps/
F: include/linux/pps*.h
PRESSURE STALL INFORMATION (PSI)
S: Maintained
F: include/linux/psi*
F: kernel/sched/psi.c
PRINTK
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux.git
F: include/linux/printk.h
F: include/linux/ptp_cl*
K: (?:\b|_)ptp(?:\b|_)
+ PTP MOCKUP CLOCK SUPPORT
+ S: Maintained
+ F: drivers/ptp/ptp_mock.c
+ F: include/linux/ptp_mock.h
+
PTP VIRTUAL CLOCK SUPPORT
QUALCOMM ATH12K WIRELESS DRIVER
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
S: Supported
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath10k
QUALCOMM ATHEROS ATH11K WIRELESS DRIVER
S: Supported
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath11k
S: Maintained
F: Documentation/devicetree/bindings/power/avs/qcom,cpr.yaml
- F: drivers/soc/qcom/cpr.c
+ F: drivers/pmdomain/qcom/cpr.c
QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096
F: Documentation/admin-guide/rtc.rst
F: Documentation/devicetree/bindings/rtc/
F: drivers/rtc/
- F: include/linux/platform_data/rtc-*
F: include/linux/rtc.h
F: include/linux/rtc/
F: include/uapi/linux/rtc.h
F: drivers/net/wireless/realtek/rtlwifi/
REALTEK WIRELESS DRIVER (rtw88)
- M: Yan-Hsuan Chuang <tony0620emma@gmail.com>
+ M: Ping-Ke Shih <pkshih@realtek.com>
S: Maintained
F: drivers/net/wireless/realtek/rtw88/
REISERFS FILE SYSTEM
- S: Supported
+ S: Obsolete
F: fs/reiserfs/
REMOTE PROCESSOR (REMOTEPROC) SUBSYSTEM
S: Orphan
W: https://wireless.wiki.kernel.org/
- T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
F: drivers/net/wireless/realtek/rtl818x/rtl8180/
RTL8187 WIRELESS DRIVER
S: Maintained
W: https://wireless.wiki.kernel.org/
- T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
F: drivers/net/wireless/realtek/rtl818x/rtl8187/
RTL8XXXU WIRELESS DRIVER (rtl8xxxu)
S: Supported
W: https://github.com/Rust-for-Linux/linux
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git
F: Documentation/driver-api/s390-drivers.rst
- F: Documentation/s390/
+ F: Documentation/arch/s390/
F: arch/s390/
F: drivers/s390/
F: drivers/watchdog/diag288_wdt.c
S: Supported
- F: Documentation/s390/pci.rst
+ F: Documentation/arch/s390/pci.rst
F: arch/s390/pci/
F: drivers/pci/hotplug/s390_pci_hpc.c
S: Supported
- F: Documentation/s390/vfio-ap*
+ F: Documentation/arch/s390/vfio-ap*
F: drivers/s390/crypto/vfio_ap*
S390 VFIO-CCW DRIVER
S: Supported
- F: Documentation/s390/vfio-ccw.rst
+ F: Documentation/arch/s390/vfio-ccw.rst
F: drivers/s390/cio/vfio_ccw*
F: include/uapi/linux/vfio_ccw.h
- S: Supported
+ S: Maintained
F: Documentation/devicetree/bindings/clock/samsung,s2mps11.yaml
F: Documentation/devicetree/bindings/mfd/samsung,s2m*.yaml
- S: Supported
+ S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
F: Documentation/devicetree/bindings/clock/samsung,*.yaml
F: drivers/tty/serdev/
F: include/linux/serdev.h
- SERIAL DRIVERS
- S: Maintained
- F: Documentation/devicetree/bindings/serial/
- F: drivers/tty/serial/
-
SERIAL IR RECEIVER
SGI XP/XPC/XPNET DRIVER
S: Maintained
F: drivers/misc/sgi-xp/
F: drivers/media/usb/siano/
F: drivers/media/usb/siano/
+ SIEMENS IPC LED DRIVERS
+ S: Maintained
+ F: drivers/leds/simple/
+
+ SIEMENS IPC PLATFORM DRIVERS
+ S: Maintained
+ F: drivers/platform/x86/siemens/
+ F: include/linux/platform_data/x86/simatic-ipc-base.h
+ F: include/linux/platform_data/x86/simatic-ipc.h
+
+ SIEMENS IPC WATCHDOG DRIVERS
+ S: Maintained
+ F: drivers/watchdog/simatic-ipc-wdt.c
+
SIFIVE DRIVERS
S: Odd Fixes
F: drivers/net/ethernet/smsc/smc91x.*
- SMM665 HARDWARE MONITOR DRIVER
- S: Maintained
- F: Documentation/hwmon/smm665.rst
- F: drivers/hwmon/smm665.c
-
SMSC EMC2103 HARDWARE MONITOR DRIVER
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
F: drivers/staging/
+ STANDALONE CACHE CONTROLLER DRIVERS
+ S: Maintained
+ T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
+ F: drivers/cache
+
STARFIRE/DURALAN NETWORK DRIVER
S: Odd Fixes
F: Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
F: drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
+ STARFIVE JH7110 DPHY RX DRIVER
+ S: Supported
+ F: Documentation/devicetree/bindings/phy/starfive,jh7110-dphy-rx.yaml
+ F: drivers/phy/starfive/phy-jh7110-dphy-rx.c
+
STARFIVE JH7110 MMC/SD/SDIO DRIVER
S: Supported
F: Documentation/devicetree/bindings/mmc/starfive*
F: drivers/mmc/host/dw_mmc-starfive.c
+ STARFIVE JH7110 PLL CLOCK DRIVER
+ S: Supported
+ F: Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
+ F: drivers/clk/starfive/clk-starfive-jh7110-pll.c
+
+ STARFIVE JH7110 SYSCON
+ S: Supported
+ F: Documentation/devicetree/bindings/soc/starfive/starfive,jh7110-syscon.yaml
+
STARFIVE JH7110 TDM DRIVER
S: Maintained
S: Supported
F: Documentation/devicetree/bindings/power/starfive*
- F: drivers/soc/starfive/jh71xx_pmu.c
+ F: drivers/pmdomain/starfive/jh71xx-pmu.c
F: include/dt-bindings/power/starfive,jh7110-pmu.h
STARFIVE SOC DRIVERS
S: Maintained
T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
+ F: Documentation/devicetree/bindings/soc/starfive/
F: drivers/soc/starfive/
STARFIVE TRNG DRIVER
F: Documentation/devicetree/bindings/watchdog/starfive*
F: drivers/watchdog/starfive-wdt.c
+ STARFIVE JH71X0 PCIE AND USB PHY DRIVER
+ S: Supported
+ F: Documentation/devicetree/bindings/phy/starfive,jh7110-pcie-phy.yaml
+ F: Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy.yaml
+ F: drivers/phy/starfive/phy-jh7110-pcie.c
+ F: drivers/phy/starfive/phy-jh7110-usb.c
+
STATIC BRANCH/CALL
F: include/linux/*/stm32-*tim*
STMMAC ETHERNET DRIVER
F: Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml
F: sound/soc/ti/
+ TEXAS INSTRUMENTS AUDIO (ASoC/HDA) DRIVERS
+ S: Maintained
+ F: Documentation/devicetree/bindings/sound/tas2552.txt
+ F: Documentation/devicetree/bindings/sound/tas2562.yaml
+ F: Documentation/devicetree/bindings/sound/tas2770.yaml
+ F: Documentation/devicetree/bindings/sound/tas27xx.yaml
+ F: Documentation/devicetree/bindings/sound/ti,pcm1681.txt
+ F: Documentation/devicetree/bindings/sound/ti,pcm3168a.yaml
+ F: Documentation/devicetree/bindings/sound/ti,tlv320*.yaml
+ F: Documentation/devicetree/bindings/sound/tlv320adcx140.yaml
+ F: Documentation/devicetree/bindings/sound/tlv320aic31xx.txt
+ F: Documentation/devicetree/bindings/sound/tpa6130a2.txt
+ F: include/sound/tas2*.h
+ F: include/sound/tlv320*.h
+ F: include/sound/tpa6130a2-plat.h
+ F: sound/pci/hda/tas2781_hda_i2c.c
+ F: sound/soc/codecs/pcm1681.c
+ F: sound/soc/codecs/pcm1789*.*
+ F: sound/soc/codecs/pcm179x*.*
+ F: sound/soc/codecs/pcm186x*.*
+ F: sound/soc/codecs/pcm3008.*
+ F: sound/soc/codecs/pcm3060*.*
+ F: sound/soc/codecs/pcm3168a*.*
+ F: sound/soc/codecs/pcm5102a.c
+ F: sound/soc/codecs/pcm512x*.*
+ F: sound/soc/codecs/tas2*.*
+ F: sound/soc/codecs/tlv320*.*
+ F: sound/soc/codecs/tpa6130a2.*
+
TEXAS INSTRUMENTS DMA DRIVERS
F: drivers/irqchip/irq-ti-sci-intr.c
F: drivers/reset/reset-ti-sci.c
F: drivers/soc/ti/ti_sci_inta_msi.c
- F: drivers/soc/ti/ti_sci_pm_domains.c
+ F: drivers/pmdomain/ti/ti_sci_pm_domains.c
F: include/dt-bindings/soc/ti,sci_pm_domain.h
F: include/linux/soc/ti/ti_sci_inta_msi.h
F: include/linux/soc/ti/ti_sci_protocol.h
F: drivers/mmc/host/tifm_sd.c
F: include/linux/tifm.h
+ TI FPD-LINK DRIVERS
+ S: Maintained
+ F: Documentation/devicetree/bindings/media/i2c/ti,ds90*
+ F: drivers/media/i2c/ds90*
+ F: include/media/i2c/ds90*
+
TI KEYSTONE MULTICORE NAVIGATOR DRIVERS
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
+ F: drivers/pmdomain/ti/omap_prm.c
F: drivers/soc/ti/*
TI LM49xxx FAMILY ASoC CODEC DRIVERS
F: Documentation/hwmon/tps546d24.rst
F: drivers/hwmon/pmbus/tps546d24.c
+ TQ SYSTEMS BOARD & DRIVER SUPPORT
+ S: Supported
+ W: https://www.tq-group.com/en/products/tq-embedded/
+ F: arch/arm/boot/dts/imx*mba*.dts*
+ F: arch/arm/boot/dts/imx*tqma*.dts*
+ F: arch/arm/boot/dts/mba*.dtsi
+ F: arch/arm64/boot/dts/freescale/imx*mba*.dts*
+ F: arch/arm64/boot/dts/freescale/imx*tqma*.dts*
+ F: arch/arm64/boot/dts/freescale/mba*.dtsi
+ F: drivers/gpio/gpio-tqmx86.c
+ F: drivers/mfd/tqmx86.c
+ F: drivers/watchdog/tqmx86_wdt.c
+
TRACING
F: kernel/trace/trace_sched_wakeup.c
TRADITIONAL CHINESE DOCUMENTATION
S: Maintained
W: https://github.com/srcres258/linux-doc
T: git git://github.com/srcres258/linux-doc.git doc-zh-tw
F: Documentation/translations/zh_TW/
- TTY LAYER
+ TTY LAYER AND SERIAL DRIVERS
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git
+ F: Documentation/devicetree/bindings/serial/
F: Documentation/driver-api/serial/
F: drivers/tty/
- F: drivers/tty/serial/serial_core.c
F: include/linux/selection.h
F: include/linux/serial.h
F: include/linux/serial_core.h
F: drivers/net/ethernet/dec/tulip/
TUN/TAP driver
S: Maintained
W: http://vtun.sourceforge.net/tun
F: Documentation/networking/tuntap.rst
F: arch/um/os-Linux/drivers/
+ F: drivers/net/tap.c
+ F: drivers/net/tun.c
TURBOCHANNEL SUBSYSTEM
F: fs/ufs/
UHID USERSPACE HID IO DRIVER
+ M: David Rheinsberg <david@readahead.eu>
S: Maintained
F: drivers/hid/uhid.c
F: drivers/usb/misc/apple-mfi-fastcharge.c
USB AR5523 WIRELESS DRIVER
- S: Maintained
+ S: Orphan
F: drivers/net/wireless/ath/ar5523/
USB ATTACHED SCSI
F: include/uapi/linux/usb/g_uvc.h
USB WIRELESS RNDIS DRIVER (rndis_wlan)
- S: Maintained
+ S: Orphan
F: drivers/net/wireless/legacy/rndis_wlan.c
USB XHCI DRIVER
S: Maintained
F: drivers/clk/ux500/
+ V4L2 ASYNC AND FWNODE FRAMEWORKS
+ S: Maintained
+ T: git git://linuxtv.org/media_tree.git
+ F: drivers/media/v4l2-core/v4l2-async.c
+ F: drivers/media/v4l2-core/v4l2-fwnode.c
+ F: include/media/v4l2-async.h
+ F: include/media/v4l2-fwnode.h
+
+ V4L2 LENS DRIVERS
+ S: Maintained
+ F: drivers/media/i2c/ak*
+ F: drivers/media/i2c/dw*
+ F: drivers/media/i2c/lm*
+
+ V4L2 CAMERA SENSOR DRIVERS
+ S: Maintained
+ F: Documentation/driver-api/media/camera-sensor.rst
+ F: Documentation/driver-api/media/tx-rx.rst
+ F: drivers/media/i2c/ar*
+ F: drivers/media/i2c/hi*
+ F: drivers/media/i2c/imx*
+ F: drivers/media/i2c/mt*
+ F: drivers/media/i2c/og*
+ F: drivers/media/i2c/ov*
+ F: drivers/media/i2c/s5*
+ F: drivers/media/i2c/st-vgxy61.c
+
VF610 NAND DRIVER
P: Documentation/driver-api/vfio-pci-device-specific-driver-acceptance.rst
F: drivers/vfio/pci/*/
+ VFIO PDS PCI DRIVER
+ S: Maintained
+ F: Documentation/networking/device_drivers/ethernet/amd/pds_vfio_pci.rst
+ F: drivers/vfio/pci/pds/
+
VFIO PLATFORM DRIVER
S: Maintained
F: drivers/block/virtio_blk.c
F: drivers/scsi/virtio_scsi.c
- F: drivers/vhost/scsi.c
F: include/uapi/linux/virtio_blk.h
F: include/uapi/linux/virtio_scsi.h
F: include/uapi/linux/vhost.h
F: kernel/vhost_task.c
+ VIRTIO HOST (VHOST-SCSI)
+ S: Maintained
+ F: drivers/vhost/scsi.c
+
VIRTIO I2C DRIVER
VSPRINTF
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux.git
F: Documentation/core-api/printk-formats.rst
W: https://www.net-swift.com
F: Documentation/networking/device_drivers/ethernet/wangxun/*
F: drivers/net/ethernet/wangxun/
+ F: drivers/net/pcs/pcs-xpcs-wx.c
WATCHDOG DEVICE DRIVERS
F: drivers/rtc/rtc-sd3078.c
WIIMOTE HID DRIVER
+ M: David Rheinsberg <david@readahead.eu>
S: Maintained
F: drivers/hid/hid-wiimote*
WL3501 WIRELESS PCMCIA CARD DRIVER
- S: Odd fixes
+ S: Orphan
F: drivers/net/wireless/legacy/wl3501*
WMI BINARY MOF DRIVER
- S: Orphan
+ S: Maintained
F: Documentation/ABI/stable/sysfs-platform-wmi-bmof
F: Documentation/wmi/devices/wmi-bmof.rst
F: drivers/platform/x86/wmi-bmof.c
X86 PLATFORM UV HPE SUPERDOME FLEX
S: Supported
F: include/xen/swiotlb-xen.h
XFS FILESYSTEM
S: Supported
W: http://xfs.org/
C: irc://irc.oftc.net/xfs
T: git git://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git
+ P: Documentation/filesystems/xfs-maintainer-entry-profile.rst
F: Documentation/ABI/testing/sysfs-fs-xfs
F: Documentation/admin-guide/xfs.rst
F: Documentation/filesystems/xfs-delayed-logging-design.rst
F: mm/zbud.c
ZD1211RW WIRELESS DRIVER
- S: Maintained
- W: http://zd1211.ath.cx/wiki/DriverRewrite
+ S: Orphan
F: drivers/net/wireless/zydas/zd1211rw/
ZD1301 MEDIA DRIVER
#include "soc21.h"
#include "navi10_ih.h"
#include "ih_v6_0.h"
+ #include "ih_v6_1.h"
#include "gfx_v10_0.h"
#include "gfx_v11_0.h"
#include "sdma_v5_0.h"
u8 harvest;
int num_base_addresses;
- u32 base_addr[];
+ u32 base_addr[] __counted_by(num_base_addresses);
};
struct ip_hw_id {
struct gc_info_v1_1 v1_1;
struct gc_info_v1_2 v1_2;
struct gc_info_v2_0 v2;
+ struct gc_info_v2_1 v2_1;
};
static int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev)
adev->gfx.config.num_sc_per_sh = le32_to_cpu(gc_info->v2.gc_num_sc_per_se) /
le32_to_cpu(gc_info->v2.gc_num_sh_per_se);
adev->gfx.config.num_packer_per_sc = le32_to_cpu(gc_info->v2.gc_num_packer_per_sc);
+ if (gc_info->v2.header.version_minor == 1) {
+ adev->gfx.config.gc_num_tcp_per_sa = le32_to_cpu(gc_info->v2_1.gc_num_tcp_per_sh);
+ adev->gfx.config.gc_tcp_size_per_cu = le32_to_cpu(gc_info->v2_1.gc_tcp_size_per_cu);
+ adev->gfx.config.gc_num_sdp_interface = le32_to_cpu(gc_info->v2_1.gc_num_sdp_interface); /* per XCD */
+ adev->gfx.config.gc_num_cu_per_sqc = le32_to_cpu(gc_info->v2_1.gc_num_cu_per_sqc);
+ adev->gfx.config.gc_l1_instruction_cache_size_per_sqc = le32_to_cpu(gc_info->v2_1.gc_instruction_cache_size_per_sqc);
+ adev->gfx.config.gc_l1_data_cache_size_per_sqc = le32_to_cpu(gc_info->v2_1.gc_scalar_data_cache_size_per_sqc);
+ adev->gfx.config.gc_tcc_size = le32_to_cpu(gc_info->v2_1.gc_tcc_size); /* per XCD */
+ }
break;
default:
dev_err(adev->dev,
union mall_info {
struct mall_info_v1_0 v1;
+ struct mall_info_v2_0 v2;
};
static int amdgpu_discovery_get_mall_info(struct amdgpu_device *adev)
adev->gmc.mall_size = mall_size;
adev->gmc.m_half_use = half_use;
break;
+ case 2:
+ mall_size_per_umc = le32_to_cpu(mall_info->v2.mall_size_per_umc);
+ adev->gmc.mall_size = mall_size_per_umc * adev->gmc.num_umc;
+ break;
default:
dev_err(adev->dev,
"Unhandled MALL info table %d.%d\n",
case IP_VERSION(6, 0, 2):
amdgpu_device_ip_block_add(adev, &ih_v6_0_ip_block);
break;
+ case IP_VERSION(6, 1, 0):
+ amdgpu_device_ip_block_add(adev, &ih_v6_1_ip_block);
+ break;
default:
dev_err(adev->dev,
"Failed to add ih ip block(OSSSYS_HWIP:0x%x)\n",
case IP_VERSION(13, 0, 8):
case IP_VERSION(13, 0, 10):
case IP_VERSION(13, 0, 11):
+ case IP_VERSION(14, 0, 0):
amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
break;
case IP_VERSION(13, 0, 4):
case IP_VERSION(6, 0, 1):
case IP_VERSION(6, 0, 2):
case IP_VERSION(6, 0, 3):
+ case IP_VERSION(6, 1, 0):
amdgpu_device_ip_block_add(adev, &sdma_v6_0_ip_block);
break;
default:
break;
case IP_VERSION(6, 0, 0):
case IP_VERSION(6, 0, 1):
+ case IP_VERSION(6, 1, 0):
adev->hdp.funcs = &hdp_v6_0_funcs;
break;
default:
break;
case IP_VERSION(13, 0, 6):
case IP_VERSION(13, 0, 8):
+ case IP_VERSION(14, 0, 0):
adev->smuio.funcs = &smuio_v13_0_6_funcs;
break;
default:
}
}
- /* dm_helpers_parse_edid_caps
- *
- * Parse edid caps
+ /**
+ * dm_helpers_parse_edid_caps() - Parse edid caps
*
+ * @link: current detected link
* @edid: [in] pointer to edid
- * edid_caps: [in] pointer to edid caps
- * @return
- * void
- * */
+ * @edid_caps: [in] pointer to edid caps
+ *
+ * Return: void
+ */
enum dc_edid_status dm_helpers_parse_edid_caps(
struct dc_link *link,
const struct dc_edid *edid,
if (sad_count <= 0)
return result;
- edid_caps->audio_mode_count = sad_count < DC_MAX_AUDIO_DESC_COUNT ? sad_count : DC_MAX_AUDIO_DESC_COUNT;
+ edid_caps->audio_mode_count = min(sad_count, DC_MAX_AUDIO_DESC_COUNT);
for (i = 0; i < edid_caps->audio_mode_count; ++i) {
struct cea_sad *sad = &sads[i];
{}
static void dm_helpers_construct_old_payload(
- struct dc_link *link,
- int pbn_per_slot,
+ struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_mst_topology_state *mst_state,
struct drm_dp_mst_atomic_payload *new_payload,
struct drm_dp_mst_atomic_payload *old_payload)
{
- struct link_mst_stream_allocation_table current_link_table =
- link->mst_stream_alloc_table;
- struct link_mst_stream_allocation *dc_alloc;
- int i;
+ struct drm_dp_mst_atomic_payload *pos;
+ int pbn_per_slot = mst_state->pbn_div;
+ u8 next_payload_vc_start = mgr->next_start_slot;
+ u8 payload_vc_start = new_payload->vc_start_slot;
+ u8 allocated_time_slots;
*old_payload = *new_payload;
* struct drm_dp_mst_atomic_payload are don't care fields
* while calling drm_dp_remove_payload_part2()
*/
- for (i = 0; i < current_link_table.stream_count; i++) {
- dc_alloc =
- ¤t_link_table.stream_allocations[i];
-
- if (dc_alloc->vcp_id == new_payload->vcpi) {
- old_payload->time_slots = dc_alloc->slot_count;
- old_payload->pbn = dc_alloc->slot_count * pbn_per_slot;
- break;
- }
+ list_for_each_entry(pos, &mst_state->payloads, next) {
+ if (pos != new_payload &&
+ pos->vc_start_slot > payload_vc_start &&
+ pos->vc_start_slot < next_payload_vc_start)
+ next_payload_vc_start = pos->vc_start_slot;
}
- /* make sure there is an old payload*/
- ASSERT(i != current_link_table.stream_count);
+ allocated_time_slots = next_payload_vc_start - payload_vc_start;
+ old_payload->time_slots = allocated_time_slots;
+ old_payload->pbn = allocated_time_slots * pbn_per_slot;
}
/*
/* Accessing the connector state is required for vcpi_slots allocation
* and directly relies on behaviour in commit check
* that blocks before commit guaranteeing that the state
- * is not gonna be swapped while still in use in commit tail */
+ * is not gonna be swapped while still in use in commit tail
+ */
if (!aconnector || !aconnector->mst_root)
return false;
drm_dp_add_payload_part1(mst_mgr, mst_state, new_payload);
} else {
/* construct old payload by VCPI*/
- dm_helpers_construct_old_payload(stream->link, mst_state->pbn_div,
- new_payload, &old_payload);
+ dm_helpers_construct_old_payload(mst_mgr, mst_state,
+ new_payload, &old_payload);
target_payload = &old_payload;
drm_dp_remove_payload_part1(mst_mgr, mst_state, new_payload);
/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
* AUX message. The sequence is slot 1-63 allocated sequence for each
* stream. AMD ASIC stream slot allocation should follow the same
- * sequence. copy DRM MST allocation to dc */
+ * sequence. copy DRM MST allocation to dc
+ */
fill_dc_mst_payload_table_from_drm(stream->link, enable, target_payload, proposed_table);
return true;
if (enable) {
ret = drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, new_payload);
} else {
- dm_helpers_construct_old_payload(stream->link, mst_state->pbn_div,
+ dm_helpers_construct_old_payload(mst_mgr, mst_state,
new_payload, &old_payload);
drm_dp_remove_payload_part2(mst_mgr, mst_state, &old_payload, new_payload);
}
total = log_ctx->pos + n + 1;
if (total > log_ctx->size) {
- char *buf = (char *)kvcalloc(total, sizeof(char), GFP_KERNEL);
+ char *buf = kvcalloc(total, sizeof(char), GFP_KERNEL);
if (buf) {
memcpy(buf, log_ctx->buf, log_ctx->pos);
ret = drm_dp_dpcd_write(aux, SYNAPTICS_RC_COMMAND, &rc_cmd, sizeof(rc_cmd));
if (ret < 0) {
- DRM_ERROR(" execute_synaptics_rc_command - write cmd ..., err = %d\n", ret);
+ DRM_ERROR("%s: write cmd ..., err = %d\n", __func__, ret);
return false;
}
drm_dp_dpcd_read(aux, SYNAPTICS_RC_DATA, data, length);
}
- DC_LOG_DC(" execute_synaptics_rc_command - success = %d\n", success);
+ DC_LOG_DC("%s: success = %d\n", __func__, success);
return success;
}
{
unsigned char data[16] = {0};
- DC_LOG_DC("Start apply_synaptics_fifo_reset_wa\n");
+ DC_LOG_DC("Start %s\n", __func__);
// Step 2
data[0] = 'P';
if (!execute_synaptics_rc_command(aux, true, 0x02, 0, 0, NULL))
return;
- DC_LOG_DC("Done apply_synaptics_fifo_reset_wa\n");
+ DC_LOG_DC("Done %s\n", __func__);
}
/* MST Dock */
struct dc_panel_config *panel_config)
{
// Feature DSC
- if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) {
+ if (amdgpu_dc_debug_mask & DC_DISABLE_DSC)
panel_config->dsc.disable_dsc_edp = true;
- }
}
void *dm_helpers_allocate_gpu_mem(
.num_bits_resol = 11,
.pll_p_offset = 13,
.reg_values = reg_values,
+ .pll_fin_min = 6,
+ .pll_fin_max = 12,
.m_min = 41,
.m_max = 125,
.min_freq = 500,
.num_bits_resol = 11,
.pll_p_offset = 13,
.reg_values = reg_values,
+ .pll_fin_min = 6,
+ .pll_fin_max = 12,
.m_min = 41,
.m_max = 125,
.min_freq = 500,
.num_bits_resol = 11,
.pll_p_offset = 13,
.reg_values = reg_values,
+ .pll_fin_min = 6,
+ .pll_fin_max = 12,
.m_min = 41,
.m_max = 125,
.min_freq = 500,
.num_bits_resol = 12,
.pll_p_offset = 13,
.reg_values = exynos5433_reg_values,
+ .pll_fin_min = 6,
+ .pll_fin_max = 12,
.m_min = 41,
.m_max = 125,
.min_freq = 500,
.num_bits_resol = 12,
.pll_p_offset = 13,
.reg_values = exynos5422_reg_values,
+ .pll_fin_min = 6,
+ .pll_fin_max = 12,
.m_min = 41,
.m_max = 125,
.min_freq = 500,
*/
.pll_p_offset = 14,
.reg_values = imx8mm_dsim_reg_values,
+ .pll_fin_min = 2,
+ .pll_fin_max = 30,
.m_min = 64,
.m_max = 1023,
.min_freq = 1050,
u16 m;
u32 reg;
- fin = dsi->pll_clk_rate;
+ if (dsi->pll_clk) {
+ /*
+ * Ensure that the reference clock is generated with a power of
+ * two divider from its parent, but close to the PLLs upper
+ * limit.
+ */
+ fin = clk_get_rate(clk_get_parent(dsi->pll_clk));
+ while (fin > driver_data->pll_fin_max * MHZ)
+ fin /= 2;
+ clk_set_rate(dsi->pll_clk, fin);
+
+ fin = clk_get_rate(dsi->pll_clk);
+ } else {
+ fin = dsi->pll_clk_rate;
+ }
+ dev_dbg(dsi->dev, "PLL ref clock freq %lu\n", fin);
+
fout = samsung_dsim_pll_find_pms(dsi, fin, freq, &p, &m, &s);
if (!fout) {
dev_err(dsi->dev,
u32 reg;
if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
- int byte_clk_khz = dsi->hs_clock / 1000 / 8;
- int hfp = (m->hsync_start - m->hdisplay) * byte_clk_khz / m->clock;
- int hbp = (m->htotal - m->hsync_end) * byte_clk_khz / m->clock;
- int hsa = (m->hsync_end - m->hsync_start) * byte_clk_khz / m->clock;
+ u64 byte_clk = dsi->hs_clock / 8;
+ u64 pix_clk = m->clock * 1000;
+
+ int hfp = DIV64_U64_ROUND_UP((m->hsync_start - m->hdisplay) * byte_clk, pix_clk);
+ int hbp = DIV64_U64_ROUND_UP((m->htotal - m->hsync_end) * byte_clk, pix_clk);
+ int hsa = DIV64_U64_ROUND_UP((m->hsync_end - m->hsync_start) * byte_clk, pix_clk);
/* remove packet overhead when possible */
hfp = max(hfp - 6, 0);
disable_irq(dsi->irq);
}
+ static void samsung_dsim_set_stop_state(struct samsung_dsim *dsi, bool enable)
+ {
+ u32 reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);
+
+ if (enable)
+ reg |= DSIM_FORCE_STOP_STATE;
+ else
+ reg &= ~DSIM_FORCE_STOP_STATE;
+
+ samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg);
+ }
+
static int samsung_dsim_init(struct samsung_dsim *dsi)
{
const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;
struct drm_bridge_state *old_bridge_state)
{
struct samsung_dsim *dsi = bridge_to_dsi(bridge);
- u32 reg;
if (samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) {
samsung_dsim_set_display_mode(dsi);
samsung_dsim_set_display_enable(dsi, true);
} else {
- reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);
- reg &= ~DSIM_FORCE_STOP_STATE;
- samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg);
+ samsung_dsim_set_stop_state(dsi, false);
}
dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
struct drm_bridge_state *old_bridge_state)
{
struct samsung_dsim *dsi = bridge_to_dsi(bridge);
- u32 reg;
if (!(dsi->state & DSIM_STATE_ENABLED))
return;
- if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) {
- reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);
- reg |= DSIM_FORCE_STOP_STATE;
- samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg);
- }
+ if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type))
+ samsung_dsim_set_stop_state(dsi, true);
dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
}
return ret;
}
- DRM_DEV_INFO(dev, "Attached %s device\n", device->name);
+ DRM_DEV_INFO(dev, "Attached %s device (lanes:%d bpp:%d mode-flags:0x%lx)\n",
+ device->name, device->lanes,
+ mipi_dsi_pixel_format_to_bpp(device->format),
+ device->mode_flags);
drm_bridge_add(&dsi->bridge);
if (ret)
return ret;
+ samsung_dsim_set_stop_state(dsi, false);
+
ret = mipi_dsi_create_packet(&xfer.packet, msg);
if (ret < 0)
return ret;
u32 lane_polarities[5] = { 0 };
struct device_node *endpoint;
int i, nr_lanes, ret;
- struct clk *pll_clk;
ret = samsung_dsim_of_read_u32(node, "samsung,pll-clock-frequency",
&dsi->pll_clk_rate, 1);
/* If it doesn't exist, read it from the clock instead of failing */
if (ret < 0) {
dev_dbg(dev, "Using sclk_mipi for pll clock frequency\n");
- pll_clk = devm_clk_get(dev, "sclk_mipi");
- if (!IS_ERR(pll_clk))
- dsi->pll_clk_rate = clk_get_rate(pll_clk);
- else
- return PTR_ERR(pll_clk);
+ dsi->pll_clk = devm_clk_get(dev, "sclk_mipi");
+ if (IS_ERR(dsi->pll_clk))
+ return PTR_ERR(dsi->pll_clk);
}
/* If it doesn't exist, use pixel clock instead of failing */
}
EXPORT_SYMBOL_GPL(samsung_dsim_probe);
-int samsung_dsim_remove(struct platform_device *pdev)
+void samsung_dsim_remove(struct platform_device *pdev)
{
struct samsung_dsim *dsi = platform_get_drvdata(pdev);
if (dsi->plat_data->host_ops && dsi->plat_data->host_ops->unregister_host)
dsi->plat_data->host_ops->unregister_host(dsi);
-
- return 0;
}
EXPORT_SYMBOL_GPL(samsung_dsim_remove);
static struct platform_driver samsung_dsim_driver = {
.probe = samsung_dsim_probe,
- .remove = samsung_dsim_remove,
+ .remove_new = samsung_dsim_remove,
.driver = {
.name = "samsung-dsim",
.pm = &samsung_dsim_pm_ops,
}
EXPORT_SYMBOL(drm_dp_dpcd_read_phy_link_status);
-static bool is_edid_digital_input_dp(const struct edid *edid)
+static bool is_edid_digital_input_dp(const struct drm_edid *drm_edid)
{
+ /* FIXME: get rid of drm_edid_raw() */
+ const struct edid *edid = drm_edid_raw(drm_edid);
+
return edid && edid->revision >= 4 &&
edid->input & DRM_EDID_INPUT_DIGITAL &&
(edid->input & DRM_EDID_DIGITAL_TYPE_MASK) == DRM_EDID_DIGITAL_TYPE_DP;
* drm_dp_downstream_is_tmds() - is the downstream facing port TMDS?
* @dpcd: DisplayPort configuration data
* @port_cap: port capabilities
- * @edid: EDID
+ * @drm_edid: EDID
*
* Returns: whether the downstream facing port is TMDS (HDMI/DVI).
*/
bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4],
- const struct edid *edid)
+ const struct drm_edid *drm_edid)
{
if (dpcd[DP_DPCD_REV] < 0x11) {
switch (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK) {
switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
case DP_DS_PORT_TYPE_DP_DUALMODE:
- if (is_edid_digital_input_dp(edid))
+ if (is_edid_digital_input_dp(drm_edid))
return false;
fallthrough;
case DP_DS_PORT_TYPE_DVI:
* drm_dp_downstream_max_tmds_clock() - extract downstream facing port max TMDS clock
* @dpcd: DisplayPort configuration data
* @port_cap: port capabilities
- * @edid: EDID
+ * @drm_edid: EDID
*
* Returns: HDMI/DVI downstream facing port max TMDS clock in kHz on success,
* or 0 if max TMDS clock not defined
*/
int drm_dp_downstream_max_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4],
- const struct edid *edid)
+ const struct drm_edid *drm_edid)
{
if (!drm_dp_is_branch(dpcd))
return 0;
switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
case DP_DS_PORT_TYPE_DP_DUALMODE:
- if (is_edid_digital_input_dp(edid))
+ if (is_edid_digital_input_dp(drm_edid))
return 0;
/*
* It's left up to the driver to check the
* drm_dp_downstream_min_tmds_clock() - extract downstream facing port min TMDS clock
* @dpcd: DisplayPort configuration data
* @port_cap: port capabilities
- * @edid: EDID
+ * @drm_edid: EDID
*
* Returns: HDMI/DVI downstream facing port min TMDS clock in kHz on success,
* or 0 if max TMDS clock not defined
*/
int drm_dp_downstream_min_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4],
- const struct edid *edid)
+ const struct drm_edid *drm_edid)
{
if (!drm_dp_is_branch(dpcd))
return 0;
switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
case DP_DS_PORT_TYPE_DP_DUALMODE:
- if (is_edid_digital_input_dp(edid))
+ if (is_edid_digital_input_dp(drm_edid))
return 0;
fallthrough;
case DP_DS_PORT_TYPE_DVI:
* bits per component
* @dpcd: DisplayPort configuration data
* @port_cap: downstream facing port capabilities
- * @edid: EDID
+ * @drm_edid: EDID
*
* Returns: Max bpc on success or 0 if max bpc not defined
*/
int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4],
- const struct edid *edid)
+ const struct drm_edid *drm_edid)
{
if (!drm_dp_is_branch(dpcd))
return 0;
case DP_DS_PORT_TYPE_DP:
return 0;
case DP_DS_PORT_TYPE_DP_DUALMODE:
- if (is_edid_digital_input_dp(edid))
+ if (is_edid_digital_input_dp(drm_edid))
return 0;
fallthrough;
case DP_DS_PORT_TYPE_HDMI:
* @m: pointer for debugfs file
* @dpcd: DisplayPort configuration data
* @port_cap: port capabilities
- * @edid: EDID
+ * @drm_edid: EDID
* @aux: DisplayPort AUX channel
*
*/
void drm_dp_downstream_debug(struct seq_file *m,
const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4],
- const struct edid *edid,
+ const struct drm_edid *drm_edid,
struct drm_dp_aux *aux)
{
bool detailed_cap_info = dpcd[DP_DOWNSTREAMPORT_PRESENT] &
if (clk > 0)
seq_printf(m, "\t\tMax dot clock: %d kHz\n", clk);
- clk = drm_dp_downstream_max_tmds_clock(dpcd, port_cap, edid);
+ clk = drm_dp_downstream_max_tmds_clock(dpcd, port_cap, drm_edid);
if (clk > 0)
seq_printf(m, "\t\tMax TMDS clock: %d kHz\n", clk);
- clk = drm_dp_downstream_min_tmds_clock(dpcd, port_cap, edid);
+ clk = drm_dp_downstream_min_tmds_clock(dpcd, port_cap, drm_edid);
if (clk > 0)
seq_printf(m, "\t\tMin TMDS clock: %d kHz\n", clk);
- bpc = drm_dp_downstream_max_bpc(dpcd, port_cap, edid);
+ bpc = drm_dp_downstream_max_bpc(dpcd, port_cap, drm_edid);
if (bpc > 0)
seq_printf(m, "\t\tMax bpc: %d\n", bpc);
int num_bpc = 0;
u8 color_depth = dsc_dpcd[DP_DSC_DEC_COLOR_DEPTH_CAP - DP_DSC_SUPPORT];
+ if (!drm_dp_sink_supports_dsc(dsc_dpcd))
+ return 0;
+
if (color_depth & DP_DSC_12_BPC)
dsc_bpc[num_bpc++] = 12;
if (color_depth & DP_DSC_10_BPC)
dsc_bpc[num_bpc++] = 10;
- if (color_depth & DP_DSC_8_BPC)
- dsc_bpc[num_bpc++] = 8;
+
+ /* A DP DSC Sink device shall support 8 bpc. */
+ dsc_bpc[num_bpc++] = 8;
return num_bpc;
}
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
+ spin_lock(&dev_priv->display.fb_tracking.lock);
+
seq_printf(m, "FB tracking busy bits: 0x%08x\n",
dev_priv->display.fb_tracking.busy_bits);
seq_printf(m, "FB tracking flip bits: 0x%08x\n",
dev_priv->display.fb_tracking.flip_bits);
+ spin_unlock(&dev_priv->display.fb_tracking.lock);
+
return 0;
}
{
struct intel_encoder *intel_encoder = intel_attached_encoder(connector);
struct intel_dp *intel_dp = enc_to_intel_dp(intel_encoder);
- const struct edid *edid = drm_edid_raw(connector->detect_edid);
seq_printf(m, "\tDPCD rev: %x\n", intel_dp->dpcd[DP_DPCD_REV]);
seq_printf(m, "\taudio support: %s\n",
str_yes_no(connector->base.display_info.has_audio));
drm_dp_downstream_debug(m, intel_dp->dpcd, intel_dp->downstream_ports,
- edid, &intel_dp->aux);
+ connector->detect_edid, &intel_dp->aux);
}
static void intel_dp_mst_info(struct seq_file *m,
if (IS_ERR(input_buffer))
return PTR_ERR(input_buffer);
- drm_dbg(&to_i915(dev)->drm,
- "Copied %d bytes from user\n", (unsigned int)len);
+ drm_dbg(dev, "Copied %d bytes from user\n", (unsigned int)len);
drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(connector, &conn_iter) {
status = kstrtoint(input_buffer, 10, &val);
if (status < 0)
break;
- drm_dbg(&to_i915(dev)->drm,
- "Got %d for test active\n", val);
+ drm_dbg(dev, "Got %d for test active\n", val);
/* To prevent erroneous activation of the compliance
* testing code, only accept an actual value of 1 here
*/
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
int source_max = intel_dp_max_source_lane_count(dig_port);
int sink_max = intel_dp->max_sink_lane_count;
- int fia_max = intel_tc_port_fia_max_lane_count(dig_port);
+ int lane_max = intel_tc_port_max_lane_count(dig_port);
int lttpr_max = drm_dp_lttpr_max_lane_count(intel_dp->lttpr_common_caps);
if (lttpr_max)
sink_max = min(sink_max, lttpr_max);
- return min3(source_max, sink_max, fia_max);
+ return min3(source_max, sink_max, lane_max);
}
int intel_dp_max_lane_count(struct intel_dp *intel_dp)
else if (IS_ALDERLAKE_P(dev_priv) || IS_ALDERLAKE_S(dev_priv) ||
IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv))
max_rate = 810000;
- else if (IS_JSL_EHL(dev_priv))
+ else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv))
max_rate = ehl_max_source_rate(intel_dp);
else
max_rate = icl_max_source_rate(intel_dp);
} else if (DISPLAY_VER(dev_priv) == 9) {
source_rates = skl_rates;
size = ARRAY_SIZE(skl_rates);
- } else if ((IS_HASWELL(dev_priv) && !IS_HSW_ULX(dev_priv)) ||
+ } else if ((IS_HASWELL(dev_priv) && !IS_HASWELL_ULX(dev_priv)) ||
IS_BROADWELL(dev_priv)) {
source_rates = hsw_rates;
size = ARRAY_SIZE(hsw_rates);
/*
* According to BSpec, 27 is the max DSC output bpp,
- * 8 is the min DSC output bpp
+ * 8 is the min DSC output bpp.
+ * While we can still clamp higher bpp values to 27, saving bandwidth,
+ * if it is required to oompress up to bpp < 8, means we can't do
+ * that and probably means we can't fit the required mode, even with
+ * DSC enabled.
*/
- bits_per_pixel = clamp_t(u32, bits_per_pixel, 8, 27);
+ if (bits_per_pixel < 8) {
+ drm_dbg_kms(&i915->drm, "Unsupported BPP %u, min 8\n",
+ bits_per_pixel);
+ return 0;
+ }
+ bits_per_pixel = min_t(u32, bits_per_pixel, 27);
} else {
/* Find the nearest match in the array of known BPPs from VESA */
for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
return bits_per_pixel;
}
- u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
- u32 link_clock, u32 lane_count,
- u32 mode_clock, u32 mode_hdisplay,
- bool bigjoiner,
- u32 pipe_bpp,
- u32 timeslots)
+ static
+ u32 get_max_compressed_bpp_with_joiner(struct drm_i915_private *i915,
+ u32 mode_clock, u32 mode_hdisplay,
+ bool bigjoiner)
+ {
+ u32 max_bpp_small_joiner_ram;
+
+ /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
+ max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) / mode_hdisplay;
+
+ if (bigjoiner) {
+ int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 24;
+ /* With bigjoiner multiple dsc engines are used in parallel so PPC is 2 */
+ int ppc = 2;
+ u32 max_bpp_bigjoiner =
+ i915->display.cdclk.max_cdclk_freq * ppc * bigjoiner_interface_bits /
+ intel_dp_mode_to_fec_clock(mode_clock);
+
+ max_bpp_small_joiner_ram *= 2;
+
+ return min(max_bpp_small_joiner_ram, max_bpp_bigjoiner);
+ }
+
+ return max_bpp_small_joiner_ram;
+ }
+
+ u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
+ u32 link_clock, u32 lane_count,
+ u32 mode_clock, u32 mode_hdisplay,
+ bool bigjoiner,
+ enum intel_output_format output_format,
+ u32 pipe_bpp,
+ u32 timeslots)
{
- u32 bits_per_pixel, max_bpp_small_joiner_ram;
+ u32 bits_per_pixel, joiner_max_bpp;
/*
* Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
bits_per_pixel = ((link_clock * lane_count) * timeslots) /
(intel_dp_mode_to_fec_clock(mode_clock) * 8);
+ /* Bandwidth required for 420 is half, that of 444 format */
+ if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+ bits_per_pixel *= 2;
+
+ /*
+ * According to DSC 1.2a Section 4.1.1 Table 4.1 the maximum
+ * supported PPS value can be 63.9375 and with the further
+ * mention that for 420, 422 formats, bpp should be programmed double
+ * the target bpp restricting our target bpp to be 31.9375 at max.
+ */
+ if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+ bits_per_pixel = min_t(u32, bits_per_pixel, 31);
+
drm_dbg_kms(&i915->drm, "Max link bpp is %u for %u timeslots "
"total bw %u pixel clock %u\n",
bits_per_pixel, timeslots,
(link_clock * lane_count * 8),
intel_dp_mode_to_fec_clock(mode_clock));
- /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
- max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) /
- mode_hdisplay;
-
- if (bigjoiner)
- max_bpp_small_joiner_ram *= 2;
-
- /*
- * Greatest allowed DSC BPP = MIN (output BPP from available Link BW
- * check, output bpp from small joiner RAM check)
- */
- bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
-
- if (bigjoiner) {
- u32 max_bpp_bigjoiner =
- i915->display.cdclk.max_cdclk_freq * 48 /
- intel_dp_mode_to_fec_clock(mode_clock);
-
- bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
- }
+ joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, mode_clock,
+ mode_hdisplay, bigjoiner);
+ bits_per_pixel = min(bits_per_pixel, joiner_max_bpp);
bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(i915, bits_per_pixel, pipe_bpp);
- /*
- * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
- * fractional part is 0
- */
- return bits_per_pixel << 4;
+ return bits_per_pixel;
}
u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
return false;
}
+ static bool
+ dfp_can_convert(struct intel_dp *intel_dp,
+ enum intel_output_format output_format,
+ enum intel_output_format sink_format)
+ {
+ switch (output_format) {
+ case INTEL_OUTPUT_FORMAT_RGB:
+ return dfp_can_convert_from_rgb(intel_dp, sink_format);
+ case INTEL_OUTPUT_FORMAT_YCBCR444:
+ return dfp_can_convert_from_ycbcr444(intel_dp, sink_format);
+ default:
+ MISSING_CASE(output_format);
+ return false;
+ }
+
+ return false;
+ }
+
static enum intel_output_format
intel_dp_output_format(struct intel_connector *connector,
enum intel_output_format sink_format)
{
struct intel_dp *intel_dp = intel_attached_dp(connector);
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ enum intel_output_format force_dsc_output_format =
+ intel_dp->force_dsc_output_format;
enum intel_output_format output_format;
+ if (force_dsc_output_format) {
+ if (source_can_output(intel_dp, force_dsc_output_format) &&
+ (!drm_dp_is_branch(intel_dp->dpcd) ||
+ sink_format != force_dsc_output_format ||
+ dfp_can_convert(intel_dp, force_dsc_output_format, sink_format)))
+ return force_dsc_output_format;
- if (intel_dp->force_dsc_output_format)
- return intel_dp->force_dsc_output_format;
+ drm_dbg_kms(&i915->drm, "Cannot force DSC output format\n");
+ }
if (sink_format == INTEL_OUTPUT_FORMAT_RGB ||
dfp_can_convert_from_rgb(intel_dp, sink_format))
return 8 * 3;
}
- static int intel_dp_output_bpp(enum intel_output_format output_format, int bpp)
+ int intel_dp_output_bpp(enum intel_output_format output_format, int bpp)
{
/*
* bpp value was assumed to RGB format. And YCbCr 4:2:0 output
int target_clock = mode->clock;
int max_rate, mode_rate, max_lanes, max_link_clock;
int max_dotclk = dev_priv->max_dotclk_freq;
- u16 dsc_max_output_bpp = 0;
+ u16 dsc_max_compressed_bpp = 0;
u8 dsc_slice_count = 0;
enum drm_mode_status status;
bool dsc = false, bigjoiner = false;
if (HAS_DSC(dev_priv) &&
drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)) {
+ enum intel_output_format sink_format, output_format;
+ int pipe_bpp;
+
+ sink_format = intel_dp_sink_format(connector, mode);
+ output_format = intel_dp_output_format(connector, sink_format);
/*
* TBD pass the connector BPC,
* for now U8_MAX so that max BPC on that platform would be picked
*/
- int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);
+ pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, U8_MAX);
/*
* Output bpp is stored in 6.4 format so right shift by 4 to get the
* integer value since we support only integer values of bpp.
*/
if (intel_dp_is_edp(intel_dp)) {
- dsc_max_output_bpp =
+ dsc_max_compressed_bpp =
drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4;
dsc_slice_count =
drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
true);
} else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
- dsc_max_output_bpp =
- intel_dp_dsc_get_output_bpp(dev_priv,
- max_link_clock,
- max_lanes,
- target_clock,
- mode->hdisplay,
- bigjoiner,
- pipe_bpp, 64) >> 4;
+ dsc_max_compressed_bpp =
+ intel_dp_dsc_get_max_compressed_bpp(dev_priv,
+ max_link_clock,
+ max_lanes,
+ target_clock,
+ mode->hdisplay,
+ bigjoiner,
+ output_format,
+ pipe_bpp, 64);
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
target_clock,
bigjoiner);
}
- dsc = dsc_max_output_bpp && dsc_slice_count;
+ dsc = dsc_max_compressed_bpp && dsc_slice_count;
}
/*
static bool intel_dp_source_supports_fec(struct intel_dp *intel_dp,
const struct intel_crtc_state *pipe_config)
{
+ struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
- /* On TGL, FEC is supported on all Pipes */
if (DISPLAY_VER(dev_priv) >= 12)
return true;
- if (DISPLAY_VER(dev_priv) == 11 && pipe_config->cpu_transcoder != TRANSCODER_A)
+ if (DISPLAY_VER(dev_priv) == 11 && encoder->port != PORT_A)
return true;
return false;
if (intel_dp->compliance.test_data.bpc != 0) {
int bpp = 3 * intel_dp->compliance.test_data.bpc;
- limits->min_bpp = limits->max_bpp = bpp;
+ limits->pipe.min_bpp = limits->pipe.max_bpp = bpp;
pipe_config->dither_force_disable = bpp == 6 * 3;
drm_dbg_kms(&i915->drm, "Setting pipe_bpp to %d\n", bpp);
int bpp, i, lane_count, clock = intel_dp_mode_clock(pipe_config, conn_state);
int mode_rate, link_rate, link_avail;
- for (bpp = limits->max_bpp; bpp >= limits->min_bpp; bpp -= 2 * 3) {
- int output_bpp = intel_dp_output_bpp(pipe_config->output_format, bpp);
+ for (bpp = to_bpp_int(limits->link.max_bpp_x16);
+ bpp >= to_bpp_int(limits->link.min_bpp_x16);
+ bpp -= 2 * 3) {
+ int link_bpp = intel_dp_output_bpp(pipe_config->output_format, bpp);
- mode_rate = intel_dp_link_required(clock, output_bpp);
+ mode_rate = intel_dp_link_required(clock, link_bpp);
for (i = 0; i < intel_dp->num_common_rates; i++) {
link_rate = intel_dp_common_rate(intel_dp, i);
return -EINVAL;
}
- int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
+ static
+ u8 intel_dp_dsc_max_src_input_bpc(struct drm_i915_private *i915)
+ {
+ /* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */
+ if (DISPLAY_VER(i915) >= 12)
+ return 12;
+ if (DISPLAY_VER(i915) == 11)
+ return 10;
+
+ return 0;
+ }
+
+ int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int i, num_bpc;
u8 dsc_bpc[3] = {0};
u8 dsc_max_bpc;
- /* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */
- if (DISPLAY_VER(i915) >= 12)
- dsc_max_bpc = min_t(u8, 12, max_req_bpc);
- else
- dsc_max_bpc = min_t(u8, 10, max_req_bpc);
+ dsc_max_bpc = intel_dp_dsc_max_src_input_bpc(i915);
+
+ if (!dsc_max_bpc)
+ return dsc_max_bpc;
+
+ dsc_max_bpc = min_t(u8, dsc_max_bpc, max_req_bpc);
num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd,
dsc_bpc);
return drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd, sink_dsc_format);
}
+ static bool is_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock,
+ u32 lane_count, u32 mode_clock,
+ enum intel_output_format output_format,
+ int timeslots)
+ {
+ u32 available_bw, required_bw;
+
+ available_bw = (link_clock * lane_count * timeslots) / 8;
+ required_bw = compressed_bpp * (intel_dp_mode_to_fec_clock(mode_clock));
+
+ return available_bw > required_bw;
+ }
+
+ static int dsc_compute_link_config(struct intel_dp *intel_dp,
+ struct intel_crtc_state *pipe_config,
+ struct link_config_limits *limits,
+ u16 compressed_bpp,
+ int timeslots)
+ {
+ const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
+ int link_rate, lane_count;
+ int i;
+
+ for (i = 0; i < intel_dp->num_common_rates; i++) {
+ link_rate = intel_dp_common_rate(intel_dp, i);
+ if (link_rate < limits->min_rate || link_rate > limits->max_rate)
+ continue;
+
+ for (lane_count = limits->min_lane_count;
+ lane_count <= limits->max_lane_count;
+ lane_count <<= 1) {
+ if (!is_bw_sufficient_for_dsc_config(compressed_bpp, link_rate, lane_count,
+ adjusted_mode->clock,
+ pipe_config->output_format,
+ timeslots))
+ continue;
+
+ pipe_config->lane_count = lane_count;
+ pipe_config->port_clock = link_rate;
+
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+ }
+
+ static
+ u16 intel_dp_dsc_max_sink_compressed_bppx16(struct intel_dp *intel_dp,
+ struct intel_crtc_state *pipe_config,
+ int bpc)
+ {
+ u16 max_bppx16 = drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd);
+
+ if (max_bppx16)
+ return max_bppx16;
+ /*
+ * If support not given in DPCD 67h, 68h use the Maximum Allowed bit rate
+ * values as given in spec Table 2-157 DP v2.0
+ */
+ switch (pipe_config->output_format) {
+ case INTEL_OUTPUT_FORMAT_RGB:
+ case INTEL_OUTPUT_FORMAT_YCBCR444:
+ return (3 * bpc) << 4;
+ case INTEL_OUTPUT_FORMAT_YCBCR420:
+ return (3 * (bpc / 2)) << 4;
+ default:
+ MISSING_CASE(pipe_config->output_format);
+ break;
+ }
+
+ return 0;
+ }
+
+ static int dsc_sink_min_compressed_bpp(struct intel_crtc_state *pipe_config)
+ {
+ /* From Mandatory bit rate range Support Table 2-157 (DP v2.0) */
+ switch (pipe_config->output_format) {
+ case INTEL_OUTPUT_FORMAT_RGB:
+ case INTEL_OUTPUT_FORMAT_YCBCR444:
+ return 8;
+ case INTEL_OUTPUT_FORMAT_YCBCR420:
+ return 6;
+ default:
+ MISSING_CASE(pipe_config->output_format);
+ break;
+ }
+
+ return 0;
+ }
+
+ static int dsc_sink_max_compressed_bpp(struct intel_dp *intel_dp,
+ struct intel_crtc_state *pipe_config,
+ int bpc)
+ {
+ return intel_dp_dsc_max_sink_compressed_bppx16(intel_dp,
+ pipe_config, bpc) >> 4;
+ }
+
+ static int dsc_src_min_compressed_bpp(void)
+ {
+ /* Min Compressed bpp supported by source is 8 */
+ return 8;
+ }
+
+ static int dsc_src_max_compressed_bpp(struct intel_dp *intel_dp)
+ {
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+ /*
+ * Max Compressed bpp for Gen 13+ is 27bpp.
+ * For earlier platform is 23bpp. (Bspec:49259).
+ */
+ if (DISPLAY_VER(i915) <= 12)
+ return 23;
+ else
+ return 27;
+ }
+
+ /*
+ * From a list of valid compressed bpps try different compressed bpp and find a
+ * suitable link configuration that can support it.
+ */
+ static int
+ icl_dsc_compute_link_config(struct intel_dp *intel_dp,
+ struct intel_crtc_state *pipe_config,
+ struct link_config_limits *limits,
+ int dsc_max_bpp,
+ int dsc_min_bpp,
+ int pipe_bpp,
+ int timeslots)
+ {
+ int i, ret;
+
+ /* Compressed BPP should be less than the Input DSC bpp */
+ dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1);
+
+ for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp); i++) {
+ if (valid_dsc_bpp[i] < dsc_min_bpp ||
+ valid_dsc_bpp[i] > dsc_max_bpp)
+ break;
+
+ ret = dsc_compute_link_config(intel_dp,
+ pipe_config,
+ limits,
+ valid_dsc_bpp[i],
+ timeslots);
+ if (ret == 0) {
+ pipe_config->dsc.compressed_bpp = valid_dsc_bpp[i];
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+ }
+
+ /*
+ * From XE_LPD onwards we supports compression bpps in steps of 1 up to
+ * uncompressed bpp-1. So we start from max compressed bpp and see if any
+ * link configuration is able to support that compressed bpp, if not we
+ * step down and check for lower compressed bpp.
+ */
+ static int
+ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp,
+ struct intel_crtc_state *pipe_config,
+ struct link_config_limits *limits,
+ int dsc_max_bpp,
+ int dsc_min_bpp,
+ int pipe_bpp,
+ int timeslots)
+ {
+ u16 compressed_bpp;
+ int ret;
+
+ /* Compressed BPP should be less than the Input DSC bpp */
+ dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1);
+
+ for (compressed_bpp = dsc_max_bpp;
+ compressed_bpp >= dsc_min_bpp;
+ compressed_bpp--) {
+ ret = dsc_compute_link_config(intel_dp,
+ pipe_config,
+ limits,
+ compressed_bpp,
+ timeslots);
+ if (ret == 0) {
+ pipe_config->dsc.compressed_bpp = compressed_bpp;
+ return 0;
+ }
+ }
+ return -EINVAL;
+ }
+
+ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
+ struct intel_crtc_state *pipe_config,
+ struct link_config_limits *limits,
+ int pipe_bpp,
+ int timeslots)
+ {
+ const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp;
+ int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp;
+ int dsc_joiner_max_bpp;
+
+ dsc_src_min_bpp = dsc_src_min_compressed_bpp();
+ dsc_sink_min_bpp = dsc_sink_min_compressed_bpp(pipe_config);
+ dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp);
+ dsc_min_bpp = max(dsc_min_bpp, to_bpp_int_roundup(limits->link.min_bpp_x16));
+
+ dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp);
+ dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(intel_dp, pipe_config, pipe_bpp / 3);
+ dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) : dsc_src_max_bpp;
+
+ dsc_joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, adjusted_mode->clock,
+ adjusted_mode->hdisplay,
+ pipe_config->bigjoiner_pipes);
+ dsc_max_bpp = min(dsc_max_bpp, dsc_joiner_max_bpp);
+ dsc_max_bpp = min(dsc_max_bpp, to_bpp_int(limits->link.max_bpp_x16));
+
+ if (DISPLAY_VER(i915) >= 13)
+ return xelpd_dsc_compute_link_config(intel_dp, pipe_config, limits,
+ dsc_max_bpp, dsc_min_bpp, pipe_bpp, timeslots);
+ return icl_dsc_compute_link_config(intel_dp, pipe_config, limits,
+ dsc_max_bpp, dsc_min_bpp, pipe_bpp, timeslots);
+ }
+
+ static
+ u8 intel_dp_dsc_min_src_input_bpc(struct drm_i915_private *i915)
+ {
+ /* Min DSC Input BPC for ICL+ is 8 */
+ return HAS_DSC(i915) ? 8 : 0;
+ }
+
+ static
+ bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915,
+ struct drm_connector_state *conn_state,
+ struct link_config_limits *limits,
+ int pipe_bpp)
+ {
+ u8 dsc_max_bpc, dsc_min_bpc, dsc_max_pipe_bpp, dsc_min_pipe_bpp;
+
+ dsc_max_bpc = min(intel_dp_dsc_max_src_input_bpc(i915), conn_state->max_requested_bpc);
+ dsc_min_bpc = intel_dp_dsc_min_src_input_bpc(i915);
+
+ dsc_max_pipe_bpp = min(dsc_max_bpc * 3, limits->pipe.max_bpp);
+ dsc_min_pipe_bpp = max(dsc_min_bpc * 3, limits->pipe.min_bpp);
+
+ return pipe_bpp >= dsc_min_pipe_bpp &&
+ pipe_bpp <= dsc_max_pipe_bpp;
+ }
+
+ static
+ int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp,
+ struct drm_connector_state *conn_state,
+ struct link_config_limits *limits)
+ {
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ int forced_bpp;
+
+ if (!intel_dp->force_dsc_bpc)
+ return 0;
+
+ forced_bpp = intel_dp->force_dsc_bpc * 3;
+
+ if (is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, forced_bpp)) {
+ drm_dbg_kms(&i915->drm, "Input DSC BPC forced to %d\n", intel_dp->force_dsc_bpc);
+ return forced_bpp;
+ }
+
+ drm_dbg_kms(&i915->drm, "Cannot force DSC BPC:%d, due to DSC BPC limits\n",
+ intel_dp->force_dsc_bpc);
+
+ return 0;
+ }
+
+ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
+ struct intel_crtc_state *pipe_config,
+ struct drm_connector_state *conn_state,
+ struct link_config_limits *limits,
+ int timeslots)
+ {
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ u8 max_req_bpc = conn_state->max_requested_bpc;
+ u8 dsc_max_bpc, dsc_max_bpp;
+ u8 dsc_min_bpc, dsc_min_bpp;
+ u8 dsc_bpc[3] = {0};
+ int forced_bpp, pipe_bpp;
+ int num_bpc, i, ret;
+
+ forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
+
+ if (forced_bpp) {
+ ret = dsc_compute_compressed_bpp(intel_dp, pipe_config,
+ limits, forced_bpp, timeslots);
+ if (ret == 0) {
+ pipe_config->pipe_bpp = forced_bpp;
+ return 0;
+ }
+ }
+
+ dsc_max_bpc = intel_dp_dsc_min_src_input_bpc(i915);
+ if (!dsc_max_bpc)
+ return -EINVAL;
+
+ dsc_max_bpc = min_t(u8, dsc_max_bpc, max_req_bpc);
+ dsc_max_bpp = min(dsc_max_bpc * 3, limits->pipe.max_bpp);
+
+ dsc_min_bpc = intel_dp_dsc_min_src_input_bpc(i915);
+ dsc_min_bpp = max(dsc_min_bpc * 3, limits->pipe.min_bpp);
+
+ /*
+ * Get the maximum DSC bpc that will be supported by any valid
+ * link configuration and compressed bpp.
+ */
+ num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd, dsc_bpc);
+ for (i = 0; i < num_bpc; i++) {
+ pipe_bpp = dsc_bpc[i] * 3;
+ if (pipe_bpp < dsc_min_bpp)
+ break;
+ if (pipe_bpp > dsc_max_bpp)
+ continue;
+ ret = dsc_compute_compressed_bpp(intel_dp, pipe_config,
+ limits, pipe_bpp, timeslots);
+ if (ret == 0) {
+ pipe_config->pipe_bpp = pipe_bpp;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+ }
+
+ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
+ struct intel_crtc_state *pipe_config,
+ struct drm_connector_state *conn_state,
+ struct link_config_limits *limits)
+ {
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ int pipe_bpp, forced_bpp;
+ int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp;
+ int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp;
+
+ forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
+
+ if (forced_bpp) {
+ pipe_bpp = forced_bpp;
+ } else {
+ int max_bpc = min(limits->pipe.max_bpp / 3, (int)conn_state->max_requested_bpc);
+
+ /* For eDP use max bpp that can be supported with DSC. */
+ pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, max_bpc);
+ if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, pipe_bpp)) {
+ drm_dbg_kms(&i915->drm,
+ "Computed BPC is not in DSC BPC limits\n");
+ return -EINVAL;
+ }
+ }
+ pipe_config->port_clock = limits->max_rate;
+ pipe_config->lane_count = limits->max_lane_count;
+
+ dsc_src_min_bpp = dsc_src_min_compressed_bpp();
+ dsc_sink_min_bpp = dsc_sink_min_compressed_bpp(pipe_config);
+ dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp);
+ dsc_min_bpp = max(dsc_min_bpp, to_bpp_int_roundup(limits->link.min_bpp_x16));
+
+ dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp);
+ dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(intel_dp, pipe_config, pipe_bpp / 3);
+ dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) : dsc_src_max_bpp;
+ dsc_max_bpp = min(dsc_max_bpp, to_bpp_int(limits->link.max_bpp_x16));
+
+ /* Compressed BPP should be less than the Input DSC bpp */
+ dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1);
+
+ pipe_config->dsc.compressed_bpp = max(dsc_min_bpp, dsc_max_bpp);
+
+ pipe_config->pipe_bpp = pipe_bpp;
+
+ return 0;
+ }
+
int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state,
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
const struct drm_display_mode *adjusted_mode =
&pipe_config->hw.adjusted_mode;
- int pipe_bpp;
int ret;
pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) &&
if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format))
return -EINVAL;
- if (compute_pipe_bpp)
- pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, conn_state->max_requested_bpc);
- else
- pipe_bpp = pipe_config->pipe_bpp;
-
- if (intel_dp->force_dsc_bpc) {
- pipe_bpp = intel_dp->force_dsc_bpc * 3;
- drm_dbg_kms(&dev_priv->drm, "Input DSC BPP forced to %d", pipe_bpp);
- }
-
- /* Min Input BPC for ICL+ is 8 */
- if (pipe_bpp < 8 * 3) {
- drm_dbg_kms(&dev_priv->drm,
- "No DSC support for less than 8bpc\n");
- return -EINVAL;
- }
-
/*
- * For now enable DSC for max bpp, max link rate, max lane count.
- * Optimize this later for the minimum possible link rate/lane count
- * with DSC enabled for the requested mode.
+ * compute pipe bpp is set to false for DP MST DSC case
+ * and compressed_bpp is calculated same time once
+ * vpci timeslots are allocated, because overall bpp
+ * calculation procedure is bit different for MST case.
*/
- pipe_config->pipe_bpp = pipe_bpp;
- pipe_config->port_clock = limits->max_rate;
- pipe_config->lane_count = limits->max_lane_count;
+ if (compute_pipe_bpp) {
+ if (intel_dp_is_edp(intel_dp))
+ ret = intel_edp_dsc_compute_pipe_bpp(intel_dp, pipe_config,
+ conn_state, limits);
+ else
+ ret = intel_dp_dsc_compute_pipe_bpp(intel_dp, pipe_config,
+ conn_state, limits, timeslots);
+ if (ret) {
+ drm_dbg_kms(&dev_priv->drm,
+ "No Valid pipe bpp for given mode ret = %d\n", ret);
+ return ret;
+ }
+ }
+ /* Calculate Slice count */
if (intel_dp_is_edp(intel_dp)) {
- pipe_config->dsc.compressed_bpp =
- min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4,
- pipe_config->pipe_bpp);
pipe_config->dsc.slice_count =
drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
true);
return -EINVAL;
}
} else {
- u16 dsc_max_output_bpp = 0;
u8 dsc_dp_slice_count;
- if (compute_pipe_bpp) {
- dsc_max_output_bpp =
- intel_dp_dsc_get_output_bpp(dev_priv,
- pipe_config->port_clock,
- pipe_config->lane_count,
- adjusted_mode->crtc_clock,
- adjusted_mode->crtc_hdisplay,
- pipe_config->bigjoiner_pipes,
- pipe_bpp,
- timeslots);
- /*
- * According to DSC 1.2a Section 4.1.1 Table 4.1 the maximum
- * supported PPS value can be 63.9375 and with the further
- * mention that bpp should be programmed double the target bpp
- * restricting our target bpp to be 31.9375 at max
- */
- if (pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
- dsc_max_output_bpp = min_t(u16, dsc_max_output_bpp, 31 << 4);
-
- if (!dsc_max_output_bpp) {
- drm_dbg_kms(&dev_priv->drm,
- "Compressed BPP not supported\n");
- return -EINVAL;
- }
- }
dsc_dp_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
adjusted_mode->crtc_clock,
return -EINVAL;
}
- /*
- * compute pipe bpp is set to false for DP MST DSC case
- * and compressed_bpp is calculated same time once
- * vpci timeslots are allocated, because overall bpp
- * calculation procedure is bit different for MST case.
- */
- if (compute_pipe_bpp) {
- pipe_config->dsc.compressed_bpp = min_t(u16,
- dsc_max_output_bpp >> 4,
- pipe_config->pipe_bpp);
- }
pipe_config->dsc.slice_count = dsc_dp_slice_count;
- drm_dbg_kms(&dev_priv->drm, "DSC: compressed bpp %d slice count %d\n",
- pipe_config->dsc.compressed_bpp,
- pipe_config->dsc.slice_count);
}
/*
* VDSC engine operates at 1 Pixel per clock, so if peak pixel rate
return 0;
}
- static int
- intel_dp_compute_link_config(struct intel_encoder *encoder,
- struct intel_crtc_state *pipe_config,
- struct drm_connector_state *conn_state,
- bool respect_downstream_limits)
+ /**
+ * intel_dp_compute_config_link_bpp_limits - compute output link bpp limits
+ * @intel_dp: intel DP
+ * @crtc_state: crtc state
+ * @dsc: DSC compression mode
+ * @limits: link configuration limits
+ *
+ * Calculates the output link min, max bpp values in @limits based on the
+ * pipe bpp range, @crtc_state and @dsc mode.
+ *
+ * Returns %true in case of success.
+ */
+ bool
+ intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state,
+ bool dsc,
+ struct link_config_limits *limits)
{
- struct drm_i915_private *i915 = to_i915(encoder->base.dev);
- struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+ struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
const struct drm_display_mode *adjusted_mode =
- &pipe_config->hw.adjusted_mode;
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- struct link_config_limits limits;
- bool joiner_needs_dsc = false;
- int ret;
+ &crtc_state->hw.adjusted_mode;
+ const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ const struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+ int max_link_bpp_x16;
- limits.min_rate = intel_dp_common_rate(intel_dp, 0);
- limits.max_rate = intel_dp_max_link_rate(intel_dp);
+ max_link_bpp_x16 = min(crtc_state->max_link_bpp_x16,
+ to_bpp_x16(limits->pipe.max_bpp));
- limits.min_lane_count = 1;
- limits.max_lane_count = intel_dp_max_lane_count(intel_dp);
+ if (!dsc) {
+ max_link_bpp_x16 = rounddown(max_link_bpp_x16, to_bpp_x16(2 * 3));
- limits.min_bpp = intel_dp_min_bpp(pipe_config->output_format);
- limits.max_bpp = intel_dp_max_bpp(intel_dp, pipe_config, respect_downstream_limits);
+ if (max_link_bpp_x16 < to_bpp_x16(limits->pipe.min_bpp))
+ return false;
+
+ limits->link.min_bpp_x16 = to_bpp_x16(limits->pipe.min_bpp);
+ } else {
+ /*
+ * TODO: set the DSC link limits already here, atm these are
+ * initialized only later in intel_edp_dsc_compute_pipe_bpp() /
+ * intel_dp_dsc_compute_pipe_bpp()
+ */
+ limits->link.min_bpp_x16 = 0;
+ }
+
+ limits->link.max_bpp_x16 = max_link_bpp_x16;
+
+ drm_dbg_kms(&i915->drm,
+ "[ENCODER:%d:%s][CRTC:%d:%s] DP link limits: pixel clock %d kHz DSC %s max lanes %d max rate %d max pipe_bpp %d max link_bpp " BPP_X16_FMT "\n",
+ encoder->base.base.id, encoder->base.name,
+ crtc->base.base.id, crtc->base.name,
+ adjusted_mode->crtc_clock,
+ dsc ? "on" : "off",
+ limits->max_lane_count,
+ limits->max_rate,
+ limits->pipe.max_bpp,
+ BPP_X16_ARGS(limits->link.max_bpp_x16));
+
+ return true;
+ }
+
+ static bool
+ intel_dp_compute_config_limits(struct intel_dp *intel_dp,
+ struct intel_crtc_state *crtc_state,
+ bool respect_downstream_limits,
+ bool dsc,
+ struct link_config_limits *limits)
+ {
+ limits->min_rate = intel_dp_common_rate(intel_dp, 0);
+ limits->max_rate = intel_dp_max_link_rate(intel_dp);
+
+ limits->min_lane_count = 1;
+ limits->max_lane_count = intel_dp_max_lane_count(intel_dp);
+
+ limits->pipe.min_bpp = intel_dp_min_bpp(crtc_state->output_format);
+ limits->pipe.max_bpp = intel_dp_max_bpp(intel_dp, crtc_state,
+ respect_downstream_limits);
if (intel_dp->use_max_params) {
/*
* configuration, and typically on older panels these
* values correspond to the native resolution of the panel.
*/
- limits.min_lane_count = limits.max_lane_count;
- limits.min_rate = limits.max_rate;
+ limits->min_lane_count = limits->max_lane_count;
+ limits->min_rate = limits->max_rate;
}
- intel_dp_adjust_compliance_config(intel_dp, pipe_config, &limits);
+ intel_dp_adjust_compliance_config(intel_dp, crtc_state, limits);
+
+ return intel_dp_compute_config_link_bpp_limits(intel_dp,
+ crtc_state,
+ dsc,
+ limits);
+ }
- drm_dbg_kms(&i915->drm, "DP link computation with max lane count %i "
- "max rate %d max bpp %d pixel clock %iKHz\n",
- limits.max_lane_count, limits.max_rate,
- limits.max_bpp, adjusted_mode->crtc_clock);
+ static int
+ intel_dp_compute_link_config(struct intel_encoder *encoder,
+ struct intel_crtc_state *pipe_config,
+ struct drm_connector_state *conn_state,
+ bool respect_downstream_limits)
+ {
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+ struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+ const struct drm_display_mode *adjusted_mode =
+ &pipe_config->hw.adjusted_mode;
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ struct link_config_limits limits;
+ bool joiner_needs_dsc = false;
+ bool dsc_needed;
+ int ret = 0;
if (intel_dp_need_bigjoiner(intel_dp, adjusted_mode->crtc_hdisplay,
adjusted_mode->crtc_clock))
*/
joiner_needs_dsc = DISPLAY_VER(i915) < 13 && pipe_config->bigjoiner_pipes;
- /*
- * Optimize for slow and wide for everything, because there are some
- * eDP 1.3 and 1.4 panels don't work well with fast and narrow.
- */
- ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, conn_state, &limits);
+ dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en ||
+ !intel_dp_compute_config_limits(intel_dp, pipe_config,
+ respect_downstream_limits,
+ false,
+ &limits);
- if (ret || joiner_needs_dsc || intel_dp->force_dsc_en) {
+ if (!dsc_needed) {
+ /*
+ * Optimize for slow and wide for everything, because there are some
+ * eDP 1.3 and 1.4 panels don't work well with fast and narrow.
+ */
+ ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config,
+ conn_state, &limits);
+ if (ret)
+ dsc_needed = true;
+ }
+
+ if (dsc_needed) {
drm_dbg_kms(&i915->drm, "Try DSC (fallback=%s, joiner=%s, force=%s)\n",
str_yes_no(ret), str_yes_no(joiner_needs_dsc),
str_yes_no(intel_dp->force_dsc_en));
+
+ if (!intel_dp_compute_config_limits(intel_dp, pipe_config,
+ respect_downstream_limits,
+ true,
+ &limits))
+ return -EINVAL;
+
ret = intel_dp_dsc_compute_config(intel_dp, pipe_config,
conn_state, &limits, 64, true);
if (ret < 0)
static void
intel_dp_drrs_compute_config(struct intel_connector *connector,
struct intel_crtc_state *pipe_config,
- int output_bpp)
+ int link_bpp)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
const struct drm_display_mode *downclock_mode =
int pixel_clock;
if (has_seamless_m_n(connector))
- pipe_config->seamless_m_n = true;
+ pipe_config->update_m_n = true;
if (!can_enable_drrs(connector, pipe_config, downclock_mode)) {
if (intel_cpu_transcoder_has_m2_n2(i915, pipe_config->cpu_transcoder))
if (pipe_config->splitter.enable)
pixel_clock /= pipe_config->splitter.link_count;
- intel_link_compute_m_n(output_bpp, pipe_config->lane_count, pixel_clock,
+ intel_link_compute_m_n(link_bpp, pipe_config->lane_count, pixel_clock,
pipe_config->port_clock, &pipe_config->dp_m2_n2,
pipe_config->fec_enable);
}
static bool intel_dp_has_audio(struct intel_encoder *encoder,
+ struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- struct intel_connector *connector = intel_dp->attached_connector;
const struct intel_digital_connector_state *intel_conn_state =
to_intel_digital_connector_state(conn_state);
+ struct intel_connector *connector =
+ to_intel_connector(conn_state->connector);
- if (!intel_dp_port_has_audio(i915, encoder->port))
+ if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
+ !intel_dp_port_has_audio(i915, encoder->port))
return false;
if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)
return ret;
}
- static void
+ void
intel_dp_audio_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state)
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct drm_connector *connector = conn_state->connector;
- pipe_config->sdp_split_enable =
- intel_dp_has_audio(encoder, conn_state) &&
- intel_dp_is_uhbr(pipe_config);
+ pipe_config->has_audio =
+ intel_dp_has_audio(encoder, pipe_config, conn_state) &&
+ intel_audio_compute_config(encoder, pipe_config, conn_state);
+
+ pipe_config->sdp_split_enable = pipe_config->has_audio &&
+ intel_dp_is_uhbr(pipe_config);
drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] SDP split enable: %s\n",
connector->base.id, connector->name,
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
const struct drm_display_mode *fixed_mode;
struct intel_connector *connector = intel_dp->attached_connector;
- int ret = 0, output_bpp;
+ int ret = 0, link_bpp;
if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && encoder->port != PORT_A)
pipe_config->has_pch_encoder = true;
- pipe_config->has_audio =
- intel_dp_has_audio(encoder, conn_state) &&
- intel_audio_compute_config(encoder, pipe_config, conn_state);
-
fixed_mode = intel_panel_fixed_mode(connector, adjusted_mode);
if (intel_dp_is_edp(intel_dp) && fixed_mode) {
ret = intel_panel_compute_config(connector, adjusted_mode);
pipe_config->limited_color_range =
intel_dp_limited_color_range(pipe_config, conn_state);
+ pipe_config->enhanced_framing =
+ drm_dp_enhanced_frame_cap(intel_dp->dpcd);
+
if (pipe_config->dsc.compression_enable)
- output_bpp = pipe_config->dsc.compressed_bpp;
+ link_bpp = pipe_config->dsc.compressed_bpp;
else
- output_bpp = intel_dp_output_bpp(pipe_config->output_format,
- pipe_config->pipe_bpp);
+ link_bpp = intel_dp_output_bpp(pipe_config->output_format,
+ pipe_config->pipe_bpp);
if (intel_dp->mso_link_count) {
int n = intel_dp->mso_link_count;
intel_dp_audio_compute_config(encoder, pipe_config, conn_state);
- intel_link_compute_m_n(output_bpp,
+ intel_link_compute_m_n(link_bpp,
pipe_config->lane_count,
adjusted_mode->crtc_clock,
pipe_config->port_clock,
intel_vrr_compute_config(pipe_config, conn_state);
intel_psr_compute_config(intel_dp, pipe_config, conn_state);
- intel_dp_drrs_compute_config(connector, pipe_config, output_bpp);
+ intel_dp_drrs_compute_config(connector, pipe_config, link_bpp);
intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, conn_state);
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct intel_connector *connector = intel_dp->attached_connector;
- const struct edid *edid;
-
- /* FIXME: Get rid of drm_edid_raw() */
- edid = drm_edid_raw(drm_edid);
intel_dp->dfp.max_bpc =
drm_dp_downstream_max_bpc(intel_dp->dpcd,
- intel_dp->downstream_ports, edid);
+ intel_dp->downstream_ports, drm_edid);
intel_dp->dfp.max_dotclock =
drm_dp_downstream_max_dotclock(intel_dp->dpcd,
intel_dp->dfp.min_tmds_clock =
drm_dp_downstream_min_tmds_clock(intel_dp->dpcd,
intel_dp->downstream_ports,
- edid);
+ drm_edid);
intel_dp->dfp.max_tmds_clock =
drm_dp_downstream_max_tmds_clock(intel_dp->dpcd,
intel_dp->downstream_ports,
- edid);
+ drm_edid);
intel_dp->dfp.pcon_max_frl_bw =
drm_dp_get_pcon_max_frl_bw(intel_dp->dpcd,
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct intel_connector *connector = intel_dp->attached_connector;
const struct drm_edid *drm_edid;
- const struct edid *edid;
bool vrr_capable;
intel_dp_unset_edid(intel_dp);
intel_dp_update_dfp(intel_dp, drm_edid);
intel_dp_update_420(intel_dp);
- /* FIXME: Get rid of drm_edid_raw() */
- edid = drm_edid_raw(drm_edid);
-
- drm_dp_cec_set_edid(&intel_dp->aux, edid);
+ drm_dp_cec_attach(&intel_dp->aux,
+ connector->base.display_info.source_physical_address);
}
static void
if (status != connector_status_connected && !intel_dp->is_mst)
intel_dp_unset_edid(intel_dp);
- /*
- * Make sure the refs for power wells enabled during detect are
- * dropped to avoid a new detect cycle triggered by HPD polling.
- */
- intel_display_power_flush_work(dev_priv);
-
if (!intel_dp_is_edp(intel_dp))
drm_dp_set_subconnector_property(connector,
status,
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct intel_encoder *intel_encoder = &dig_port->base;
struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
- enum intel_display_power_domain aux_domain =
- intel_aux_power_domain(dig_port);
- intel_wakeref_t wakeref;
drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s]\n",
connector->base.id, connector->name);
if (connector->status != connector_status_connected)
return;
- wakeref = intel_display_power_get(dev_priv, aux_domain);
-
intel_dp_set_edid(intel_dp);
-
- intel_display_power_put(dev_priv, aux_domain, wakeref);
}
static int intel_dp_get_modes(struct drm_connector *connector)
/*
* VBT and straps are liars. Also check HPD as that seems
* to be the most reliable piece of information available.
+ *
+ * ... expect on devices that forgot to hook HPD up for eDP
+ * (eg. Acer Chromebook C710), so we'll check it only if multiple
+ * ports are attempting to use the same AUX CH, according to VBT.
*/
- if (!intel_digital_port_connected(encoder)) {
+ if (intel_bios_dp_has_shared_aux_ch(encoder->devdata) &&
+ !intel_digital_port_connected(encoder)) {
/*
* If this fails, presume the DPCD answer came
* from some other port using the same AUX CH.
}
mutex_lock(&dev_priv->drm.mode_config.mutex);
- drm_edid = drm_edid_read_ddc(connector, &intel_dp->aux.ddc);
+ drm_edid = drm_edid_read_ddc(connector, connector->ddc);
if (!drm_edid) {
/* Fallback to EDID from ACPI OpRegion, if any */
drm_edid = intel_opregion_get_edid(intel_connector);
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp);
+ intel_dp_aux_init(intel_dp);
+
drm_dbg_kms(&dev_priv->drm,
"Adding %s connector on [ENCODER:%d:%s]\n",
type == DRM_MODE_CONNECTOR_eDP ? "eDP" : "DP",
intel_encoder->base.base.id, intel_encoder->base.name);
- drm_connector_init(dev, connector, &intel_dp_connector_funcs, type);
+ drm_connector_init_with_ddc(dev, connector, &intel_dp_connector_funcs,
+ type, &intel_dp->aux.ddc);
drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
if (!HAS_GMCH(dev_priv) && DISPLAY_VER(dev_priv) < 12)
intel_connector->polled = DRM_CONNECTOR_POLL_HPD;
- intel_dp_aux_init(intel_dp);
-
intel_connector_attach_encoder(intel_connector, intel_encoder);
if (HAS_DDI(dev_priv))
MDP_SSPP_TOP0_INTR,
MDP_SSPP_TOP0_INTR2,
MDP_SSPP_TOP0_HIST_INTR,
+ /* All MDP_INTFn_INTR should come sequentially */
MDP_INTF0_INTR,
MDP_INTF1_INTR,
MDP_INTF2_INTR,
MDP_INTF3_INTR,
MDP_INTF4_INTR,
MDP_INTF5_INTR,
+ MDP_INTF6_INTR,
+ MDP_INTF7_INTR,
+ MDP_INTF8_INTR,
MDP_INTF1_TEAR_INTR,
MDP_INTF2_TEAR_INTR,
MDP_AD4_0_INTR,
MDP_AD4_1_INTR,
- MDP_INTF0_7xxx_INTR,
- MDP_INTF1_7xxx_INTR,
- MDP_INTF1_7xxx_TEAR_INTR,
- MDP_INTF2_7xxx_INTR,
- MDP_INTF2_7xxx_TEAR_INTR,
- MDP_INTF3_7xxx_INTR,
- MDP_INTF4_7xxx_INTR,
- MDP_INTF5_7xxx_INTR,
- MDP_INTF6_7xxx_INTR,
- MDP_INTF7_7xxx_INTR,
- MDP_INTF8_7xxx_INTR,
MDP_INTR_MAX,
};
+ #define MDP_INTFn_INTR(intf) (MDP_INTF0_INTR + (intf - INTF_0))
+
#define DPU_IRQ_IDX(reg_idx, offset) (reg_idx * 32 + offset)
/**
u32 total_irqs;
spinlock_t irq_lock;
unsigned long irq_mask;
+ const struct dpu_intr_reg *intr_set;
struct {
void (*cb)(void *arg, int irq_idx);
void *arg;
atomic_t count;
- } irq_tbl[];
+ } irq_tbl[] __counted_by(total_irqs);
};
/**
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nv50_head *head = nv50_head(nv_encoder->crtc);
- struct nouveau_connector *nv_connector = nv50_outp_get_old_connector(state, nv_encoder);
#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
+ struct nouveau_connector *nv_connector = nv50_outp_get_old_connector(state, nv_encoder);
struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
struct nouveau_backlight *backlight = nv_connector->backlight;
-#endif
struct drm_dp_aux *aux = &nv_connector->aux;
int ret;
-#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
if (backlight && backlight->uses_dpcd) {
ret = drm_edp_backlight_disable(aux, &backlight->edp_info);
if (ret < 0)
nvif_outp_dtor(&nv_encoder->outp);
drm_encoder_cleanup(encoder);
+
+ mutex_destroy(&nv_encoder->dp.hpd_irq_lock);
kfree(encoder);
}
nv_encoder->i2c = ddc;
+ mutex_init(&nv_encoder->dp.hpd_irq_lock);
+
encoder = to_drm_encoder(nv_encoder);
drm_encoder_init(connector->dev, encoder, &nv50_pior_func, type,
"pior-%04x-%04x", dcbe->hasht, dcbe->hashm);
#include <drm/drm_edid.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_panel.h>
+#include <drm/drm_of.h>
/**
* struct panel_desc - Describes a simple panel.
dev_err(dev, "Reject override mode: No display_timing found\n");
}
+static int panel_simple_override_nondefault_lvds_datamapping(struct device *dev,
+ struct panel_simple *panel)
+{
+ int ret, bpc;
+
+ ret = drm_of_lvds_get_data_mapping(dev->of_node);
+ if (ret < 0) {
+ if (ret == -EINVAL)
+ dev_warn(dev, "Ignore invalid data-mapping property\n");
+
+ /*
+ * Ignore non-existing or malformatted property, fallback to
+ * default data-mapping, and return 0.
+ */
+ return 0;
+ }
+
+ switch (ret) {
+ default:
+ WARN_ON(1);
+ fallthrough;
+ case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
+ fallthrough;
+ case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
+ bpc = 8;
+ break;
+ case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
+ bpc = 6;
+ }
+
+ if (panel->desc->bpc != bpc || panel->desc->bus_format != ret) {
+ struct panel_desc *override_desc;
+
+ override_desc = devm_kmemdup(dev, panel->desc, sizeof(*panel->desc), GFP_KERNEL);
+ if (!override_desc)
+ return -ENOMEM;
+
+ override_desc->bus_format = ret;
+ override_desc->bpc = bpc;
+ panel->desc = override_desc;
+ }
+
+ return 0;
+}
+
static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
{
struct panel_simple *panel;
panel_simple_parse_panel_timing_node(dev, panel, &dt);
}
+ if (desc->connector_type == DRM_MODE_CONNECTOR_LVDS) {
+ /* Optional data-mapping property for overriding bus format */
+ err = panel_simple_override_nondefault_lvds_datamapping(dev, panel);
+ if (err)
+ goto free_ddc;
+ }
+
connector_type = desc->connector_type;
/* Catch common mistakes for panels. */
switch (connector_type) {
.connector_type = DRM_MODE_CONNECTOR_LVDS,
};
- static const struct drm_display_mode auo_g121ean01_mode = {
- .clock = 66700,
- .hdisplay = 1280,
- .hsync_start = 1280 + 58,
- .hsync_end = 1280 + 58 + 8,
- .htotal = 1280 + 58 + 8 + 70,
- .vdisplay = 800,
- .vsync_start = 800 + 6,
- .vsync_end = 800 + 6 + 4,
- .vtotal = 800 + 6 + 4 + 10,
+ static const struct display_timing auo_g121ean01_timing = {
+ .pixelclock = { 60000000, 74400000, 90000000 },
+ .hactive = { 1280, 1280, 1280 },
+ .hfront_porch = { 20, 50, 100 },
+ .hback_porch = { 20, 50, 100 },
+ .hsync_len = { 30, 100, 200 },
+ .vactive = { 800, 800, 800 },
+ .vfront_porch = { 2, 10, 25 },
+ .vback_porch = { 2, 10, 25 },
+ .vsync_len = { 4, 18, 50 },
};
static const struct panel_desc auo_g121ean01 = {
- .modes = &auo_g121ean01_mode,
- .num_modes = 1,
+ .timings = &auo_g121ean01_timing,
+ .num_timings = 1,
.bpc = 8,
.size = {
.width = 261,
};
static const struct display_timing innolux_g156hce_l01_timings = {
- .pixelclock = { 120000000, 144000000, 150000000 },
+ .pixelclock = { 120000000, 141860000, 150000000 },
.hactive = { 1920, 1920, 1920 },
.hfront_porch = { 80, 90, 100 },
.hback_porch = { 80, 90, 100 },
spin_lock_irqsave(&pfdevfreq->lock, irqflags);
panfrost_devfreq_update_utilization(pfdevfreq);
+ pfdevfreq->current_frequency = status->current_frequency;
status->total_time = ktime_to_ns(ktime_add(pfdevfreq->busy_time,
pfdevfreq->idle_time));
* keep going without it; any other error means that we are
* supposed to read the bin value, but we failed doing so.
*/
- if (ret != -ENOENT) {
+ if (ret != -ENOENT && ret != -EOPNOTSUPP) {
DRM_DEV_ERROR(dev, "Cannot read speed-bin (%d).", ret);
return ret;
}
struct devfreq *devfreq;
struct thermal_cooling_device *cooling;
struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
+ unsigned long freq = ULONG_MAX;
if (pfdev->comp->num_supplies > 1) {
/*
return ret;
}
+ /* Find the fastest defined rate */
+ opp = dev_pm_opp_find_freq_floor(dev, &freq);
+ if (IS_ERR(opp))
+ return PTR_ERR(opp);
+ pfdevfreq->fast_rate = freq;
+
dev_pm_opp_put(opp);
/*
};
struct cec_adapter;
-struct edid;
struct drm_connector;
+struct drm_edid;
/**
* struct drm_dp_aux_cec - DisplayPort CEC-Tunneling-over-AUX
const u8 port_cap[4], u8 type);
bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4],
- const struct edid *edid);
+ const struct drm_edid *drm_edid);
int drm_dp_downstream_max_dotclock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4]);
int drm_dp_downstream_max_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4],
- const struct edid *edid);
+ const struct drm_edid *drm_edid);
int drm_dp_downstream_min_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4],
- const struct edid *edid);
+ const struct drm_edid *drm_edid);
int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4],
- const struct edid *edid);
+ const struct drm_edid *drm_edid);
bool drm_dp_downstream_420_passthrough(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4]);
bool drm_dp_downstream_444_to_420_conversion(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
void drm_dp_downstream_debug(struct seq_file *m,
const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4],
- const struct edid *edid,
+ const struct drm_edid *drm_edid,
struct drm_dp_aux *aux);
enum drm_mode_subconnector
drm_dp_subconnector_type(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
void drm_dp_cec_register_connector(struct drm_dp_aux *aux,
struct drm_connector *connector);
void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux);
+ void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address);
void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid);
void drm_dp_cec_unset_edid(struct drm_dp_aux *aux);
#else
{
}
+ static inline void drm_dp_cec_attach(struct drm_dp_aux *aux,
+ u16 source_physical_address)
+ {
+ }
+
static inline void drm_dp_cec_set_edid(struct drm_dp_aux *aux,
const struct edid *edid)
{