drm for 6.17-rc1

non-drm:
 rust:
 - make ETIMEDOUT available
 - add size constants up to SZ_2G
 - add DMA coherent allocation bindings
 mtd:
 - driver for Intel GPU non-volatile storage
 i2c
 - designware quirk for Intel xe
 
 core:
 - atomic helpers: tune enable/disable sequences
 - add task info to wedge API
 - refactor EDID quirks
 - connector: move HDR sink to drm_display_info
 - fourcc: half-float and 32-bit float formats
 - mode_config: pass format info to simplify
 
 dma-buf:
 - heaps: Give CMA heap a stable name
 
 ci:
 - add device tree validation and kunit
 
 displayport:
 - change AUX DPCD access probe address
 - add quirk for DPCD probe
 - add panel replay definitions
 - backlight control helpers
 
 fbdev:
 - make CONFIG_FIRMWARE_EDID available on all arches
 
 fence:
 - fix UAF issues
 
 format-helper:
 - improve tests
 
 gpusvm:
 - introduce devmem only flag for allocation
 - add timeslicing support to GPU SVM
 
 ttm:
 - improve eviction
 
 sched:
 - tracing improvements
 - kunit improvements
 - memory leak fixes
 - reset handling improvements
 
 color mgmt:
 - add hardware gamma LUT handling helpers
 
 bridge:
 - add destroy hook
 - switch to reference counted drm_bridge allocations
 - tc358767: convert to devm_drm_bridge_alloc
 - improve CEC handling
 
 panel:
 - switch to reference counter drm_panel allocations
 - fwnode panel lookup
 - Huiling hl055fhv028c support
 - Raspberry Pi 7" 720x1280 support
 - edp: KDC KD116N3730A05, N160JCE-ELL CMN, N116BCJ-EAK
 - simple: AUO P238HAN01
 - st7701: Winstar wf40eswaa6mnn0
 - visionox: rm69299-shift
 - Renesas R61307, Renesas R69328 support
 - DJN HX83112B
 
 hdmi:
 - add CEC handling
 - YUV420 output support
 
 xe:
 - WildCat Lake support
 - Enable PanthorLake by default
 - mark BMG as SRIOV capable
 - update firmware recommendations
 - Expose media OA units
 - aux-bux support for non-volatile memory
 - MTD intel-dg driver for non-volatile memory
 - Expose fan control and voltage regulator in sysfs
 - restructure migration for multi-device
 - Restore GuC submit UAF fix
 - make GEM shrinker drm managed
 - SRIOV VF Post-migration recovery of GGTT nodes
 - W/A additions/reworks
 - Prefetch support for svm ranges
 - Don't allocate managed BO for each policy change
 - HWMON fixes for BMG
 - Create LRC BO without VM
 - PCI ID updates
 - make SLPC debugfs files optional
 - rework eviction rejection of bound external BOs
 - consolidate PAT programming logic for pre/post Xe2
 - init changes for flicker-free boot
 - Enable GuC Dynamic Inhibit Context switch
 
 i915:
 - drm_panic support for i915/xe
 - initial flip queue off by default for LNL/PNL
 - Wildcat Lake Display support
 - Support for DSC fractional link bpp
 - Support for simultaneous Panel Replay and Adaptive sync
 - Support for PTL+ double buffer LUT
 - initial PIPEDMC event handling
 - drm_panel_follower support
 - DPLL interface renames
 - allocate struct intel_display dynamically
 - flip queue preperation
 - abstract DRAM detection better
 - avoid GuC scheduling stalls
 - remove DG1 force probe requirement
 - fix MEI interrupt handler on RT kernels
 - use backlight control helpers for eDP
 - more shared display code refactoring
 
 amdgpu:
 - add userq slot to INFO ioctl
 - SR-IOV hibernation support
 - Suspend improvements
 - Backlight improvements
 - Use scaling for non-native eDP modes
 - cleaner shader updates for GC 9.x
 - Remove fence slab
 - SDMA fw checks for userq support
 - RAS updates
 - DMCUB updates
 - DP tunneling fixes
 - Display idle D3 support
 - Per queue reset improvements
 - initial smartmux support
 
 amdkfd:
 - enable KFD on loongarch
 - mtype fix for ext coherent system memory
 
 radeon:
 - CS validation additional GL extensions
 - drop console lock during suspend/resume
 - bump driver version
 
 msm:
 - VM BIND support
 - CI: infrastructure updates
 - UBWC single source of truth
 - decouple GPU and KMS support
 - DP: rework I/O accessors
 - DPU: SM8750 support
 - DSI: SM8750 support
 - GPU: X1-45 support and speedbin support for X1-85
 - MDSS: SM8750 support
 
 nova:
 - register! macro improvements
 - DMA object abstraction
 - VBIOS parser + fwsec lookup
 - sysmem flush page support
 - falcon: generic falcon boot code and HAL
 - FWSEC-FRTS: fb setup and load/execute
 
 ivpu:
 - Add Wildcat Lake support
 - Add turbo flag
 
 ast:
 - improve hardware generations implementation
 
 imx:
 - IMX8qxq Display Controller support
 
 lima:
 - Rockchip RK3528 GPU support
 
 nouveau:
 - fence handling cleanup
 
 panfrost:
 - MT8370 support
 - bo labeling
 - 64-bit register access
 
 qaic:
 - add RAS support
 
 rockchip:
 - convert inno_hdmi to a bridge
 
 rz-du:
 - add RZ/V2H(P) support
 - MIPI-DSI DCS support
 
 sitronix:
 - ST7567 support
 
 sun4i:
 - add H616 support
 
 tidss:
 - add TI AM62L support
 - AM65x OLDI bridge support
 
 bochs:
 - drm panic support
 
 vkms:
 - YUV and R* format support
 - use faux device
 
 vmwgfx:
 - fence improvements
 
 hyperv:
 - move out of simple
 - add drm_panic support
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmiJM/0ACgkQDHTzWXnE
 hr6MpA/+JJKGdSdrE95QkaMcOZh/3e3areGXZ0V/RrrJXdB4/DoAfQSHhF0H7m7y
 MhBGVLGNMXq7KHrz28p1MjLHrE1mwmvJ6hZ4J076ed4u9naoCD0m6k5w5wiue+KL
 HyPR54ADxN0BYmgV0l/B0wj42KsHyTO4x4hdqPJu02V9Dtmx6FCh2ujkOF3p9nbK
 GMwWDttl4KEKljD0IvQ9YIYJ66crYGx/XmZi7JoWRrS104K/h1u8qZuXBp5jVKTy
 OZRAVyLdmJqdTOLH7l599MBBcEd/bNV37/LVwF4T5iFunEKOAiyN0QY0OR+IeRVh
 ZfOv2/gp4UNyIfyahQ7LKLgEilNPGHoPitvDJPvBZxW2UjwXVNvA1QfdK5DAlVRS
 D5NoFRjlFFCz8/c2hQwlKJ9o7eVgH3/pK0mwR7SPGQTuqzLFCrAfCuzUvg/gV++6
 JFqmGKMHeCoxO2o4GMrwjFttStP41usxtV/D+grcbPteNO9UyKJS4C38n4eamJXM
 a9Sy9APuAb6F0w5+yMItEF7TQifgmhIbm5AZHlxE1KoDQV6TdiIf1Gou5LeDGoL6
 OACbXHJPL52tUnfCRpbfI4tE/IVyYsfL01JnvZ5cZZWItXfcIz76ykJri+E0G60g
 yRl/zkimHKO4B0l/HSzal5xROXr+3VzeWehEiz/ot1VriP5OesA=
 =n9MO
 -----END PGP SIGNATURE-----

Merge tag 'drm-next-2025-07-30' of https://gitlab.freedesktop.org/drm/kernel

Pull drm updates from Dave Airlie:
 "Highlights:

   - Intel xe enable Panthor Lake, started adding WildCat Lake

   - amdgpu has a bunch of reset improvments along with the usual IP
     updates

   - msm got VM_BIND support which is important for vulkan sparse memory

   - more drm_panic users

   - gpusvm common code to handle a bunch of core SVM work outside
     drivers.

  Detail summary:

  Changes outside drm subdirectory:
   - 'shrink_shmem_memory()' for better shmem/hibernate interaction
   - Rust support infrastructure:
      - make ETIMEDOUT available
      - add size constants up to SZ_2G
      - add DMA coherent allocation bindings
   - mtd driver for Intel GPU non-volatile storage
   - i2c designware quirk for Intel xe

  core:
   - atomic helpers: tune enable/disable sequences
   - add task info to wedge API
   - refactor EDID quirks
   - connector: move HDR sink to drm_display_info
   - fourcc: half-float and 32-bit float formats
   - mode_config: pass format info to simplify

  dma-buf:
   - heaps: Give CMA heap a stable name

  ci:
   - add device tree validation and kunit

  displayport:
   - change AUX DPCD access probe address
   - add quirk for DPCD probe
   - add panel replay definitions
   - backlight control helpers

  fbdev:
   - make CONFIG_FIRMWARE_EDID available on all arches

  fence:
   - fix UAF issues

  format-helper:
   - improve tests

  gpusvm:
   - introduce devmem only flag for allocation
   - add timeslicing support to GPU SVM

  ttm:
   - improve eviction

  sched:
   - tracing improvements
   - kunit improvements
   - memory leak fixes
   - reset handling improvements

  color mgmt:
   - add hardware gamma LUT handling helpers

  bridge:
   - add destroy hook
   - switch to reference counted drm_bridge allocations
   - tc358767: convert to devm_drm_bridge_alloc
   - improve CEC handling

  panel:
   - switch to reference counter drm_panel allocations
   - fwnode panel lookup
   - Huiling hl055fhv028c support
   - Raspberry Pi 7" 720x1280 support
   - edp: KDC KD116N3730A05, N160JCE-ELL CMN, N116BCJ-EAK
   - simple: AUO P238HAN01
   - st7701: Winstar wf40eswaa6mnn0
   - visionox: rm69299-shift
   - Renesas R61307, Renesas R69328 support
   - DJN HX83112B

  hdmi:
   - add CEC handling
   - YUV420 output support

  xe:
   - WildCat Lake support
   - Enable PanthorLake by default
   - mark BMG as SRIOV capable
   - update firmware recommendations
   - Expose media OA units
   - aux-bux support for non-volatile memory
   - MTD intel-dg driver for non-volatile memory
   - Expose fan control and voltage regulator in sysfs
   - restructure migration for multi-device
   - Restore GuC submit UAF fix
   - make GEM shrinker drm managed
   - SRIOV VF Post-migration recovery of GGTT nodes
   - W/A additions/reworks
   - Prefetch support for svm ranges
   - Don't allocate managed BO for each policy change
   - HWMON fixes for BMG
   - Create LRC BO without VM
   - PCI ID updates
   - make SLPC debugfs files optional
   - rework eviction rejection of bound external BOs
   - consolidate PAT programming logic for pre/post Xe2
   - init changes for flicker-free boot
   - Enable GuC Dynamic Inhibit Context switch

  i915:
   - drm_panic support for i915/xe
   - initial flip queue off by default for LNL/PNL
   - Wildcat Lake Display support
   - Support for DSC fractional link bpp
   - Support for simultaneous Panel Replay and Adaptive sync
   - Support for PTL+ double buffer LUT
   - initial PIPEDMC event handling
   - drm_panel_follower support
   - DPLL interface renames
   - allocate struct intel_display dynamically
   - flip queue preperation
   - abstract DRAM detection better
   - avoid GuC scheduling stalls
   - remove DG1 force probe requirement
   - fix MEI interrupt handler on RT kernels
   - use backlight control helpers for eDP
   - more shared display code refactoring

  amdgpu:
   - add userq slot to INFO ioctl
   - SR-IOV hibernation support
   - Suspend improvements
   - Backlight improvements
   - Use scaling for non-native eDP modes
   - cleaner shader updates for GC 9.x
   - Remove fence slab
   - SDMA fw checks for userq support
   - RAS updates
   - DMCUB updates
   - DP tunneling fixes
   - Display idle D3 support
   - Per queue reset improvements
   - initial smartmux support

  amdkfd:
   - enable KFD on loongarch
   - mtype fix for ext coherent system memory

  radeon:
   - CS validation additional GL extensions
   - drop console lock during suspend/resume
   - bump driver version

  msm:
   - VM BIND support
   - CI: infrastructure updates
   - UBWC single source of truth
   - decouple GPU and KMS support
   - DP: rework I/O accessors
   - DPU: SM8750 support
   - DSI: SM8750 support
   - GPU: X1-45 support and speedbin support for X1-85
   - MDSS: SM8750 support

  nova:
   - register! macro improvements
   - DMA object abstraction
   - VBIOS parser + fwsec lookup
   - sysmem flush page support
   - falcon: generic falcon boot code and HAL
   - FWSEC-FRTS: fb setup and load/execute

  ivpu:
   - Add Wildcat Lake support
   - Add turbo flag

  ast:
   - improve hardware generations implementation

  imx:
   - IMX8qxq Display Controller support

  lima:
   - Rockchip RK3528 GPU support

  nouveau:
   - fence handling cleanup

  panfrost:
   - MT8370 support
   - bo labeling
   - 64-bit register access

  qaic:
   - add RAS support

  rockchip:
   - convert inno_hdmi to a bridge

  rz-du:
   - add RZ/V2H(P) support
   - MIPI-DSI DCS support

  sitronix:
   - ST7567 support

  sun4i:
   - add H616 support

  tidss:
   - add TI AM62L support
   - AM65x OLDI bridge support

  bochs:
   - drm panic support

  vkms:
   - YUV and R* format support
   - use faux device

  vmwgfx:
   - fence improvements

  hyperv:
   - move out of simple
   - add drm_panic support"

* tag 'drm-next-2025-07-30' of https://gitlab.freedesktop.org/drm/kernel: (1479 commits)
  drm/tidss: oldi: convert to devm_drm_bridge_alloc() API
  drm/tidss: encoder: convert to devm_drm_bridge_alloc()
  drm/amdgpu: move reset support type checks into the caller
  drm/amdgpu/sdma7: re-emit unprocessed state on ring reset
  drm/amdgpu/sdma6: re-emit unprocessed state on ring reset
  drm/amdgpu/sdma5.2: re-emit unprocessed state on ring reset
  drm/amdgpu/sdma5: re-emit unprocessed state on ring reset
  drm/amdgpu/gfx12: re-emit unprocessed state on ring reset
  drm/amdgpu/gfx11: re-emit unprocessed state on ring reset
  drm/amdgpu/gfx10: re-emit unprocessed state on ring reset
  drm/amdgpu/gfx9.4.3: re-emit unprocessed state on kcq reset
  drm/amdgpu/gfx9: re-emit unprocessed state on kcq reset
  drm/amdgpu: Add WARN_ON to the resource clear function
  drm/amd/pm: Use cached metrics data on SMUv13.0.6
  drm/amd/pm: Use cached data for min/max clocks
  gpu: nova-core: fix bounds check in PmuLookupTableEntry::new
  drm/amdgpu: Replace HQD terminology with slots naming
  drm/amdgpu: Add user queue instance count in HW IP info
  drm/amd/amdgpu: Add helper functions for isp buffers
  drm/amd/amdgpu: Initialize swnode for ISP MFD device
  ...
This commit is contained in:
Linus Torvalds 2025-07-30 19:26:49 -07:00
commit 260f6f4fda
1585 changed files with 64115 additions and 30259 deletions

View file

@ -148,3 +148,51 @@ Contact: intel-xe@lists.freedesktop.org
Description: RO. Fan 3 speed in RPM.
Only supported for particular Intel Xe graphics platforms.
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/power1_cap
Date: May 2025
KernelVersion: 6.15
Contact: intel-xe@lists.freedesktop.org
Description: RW. Card burst (PL2) power limit in microwatts.
The power controller will throttle the operating frequency
if the power averaged over a window (typically milli seconds)
exceeds this limit. A read value of 0 means that the PL2
power limit is disabled, writing 0 disables the limit.
PL2 is greater than PL1 and its time window is lesser
compared to PL1.
Only supported for particular Intel Xe graphics platforms.
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/power2_cap
Date: May 2025
KernelVersion: 6.15
Contact: intel-xe@lists.freedesktop.org
Description: RW. Package burst (PL2) power limit in microwatts.
The power controller will throttle the operating frequency
if the power averaged over a window (typically milli seconds)
exceeds this limit. A read value of 0 means that the PL2
power limit is disabled, writing 0 disables the limit.
PL2 is greater than PL1 and its time window is lesser
compared to PL1.
Only supported for particular Intel Xe graphics platforms.
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/power1_cap_interval
Date: May 2025
KernelVersion: 6.15
Contact: intel-xe@lists.freedesktop.org
Description: RW. Card burst power limit interval (Tau in PL2/Tau) in
milliseconds over which sustained power is averaged.
Only supported for particular Intel Xe graphics platforms.
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/power2_cap_interval
Date: May 2025
KernelVersion: 6.15
Contact: intel-xe@lists.freedesktop.org
Description: RW. Package burst power limit interval (Tau in PL2/Tau) in
milliseconds over which sustained power is averaged.
Only supported for particular Intel Xe graphics platforms.

View file

@ -0,0 +1,18 @@
What: /sys/bus/pci/drivers/qaic/XXXX:XX:XX.X/ce_count
Date: May 2025
KernelVersion: 6.17
Contact: dri-devel@lists.freedesktop.org
Description: Number of correctable errors received from device since driver is loaded.
What: /sys/bus/pci/drivers/qaic/XXXX:XX:XX.X/ue_count
Date: May 2025
KernelVersion: 6.17
Contact: dri-devel@lists.freedesktop.org
Description: Number of uncorrectable errors received from device since driver is loaded.
What: /sys/bus/pci/drivers/qaic/XXXX:XX:XX.X/ue_nonfatal_count
Date: May 2025
KernelVersion: 6.17
Contact: dri-devel@lists.freedesktop.org
Description: Number of uncorrectable non-fatal errors received from device since driver
is loaded.

View file

@ -24,9 +24,11 @@ properties:
- allwinner,sun50i-a64-de2-mixer-0
- allwinner,sun50i-a64-de2-mixer-1
- allwinner,sun50i-h6-de3-mixer-0
- allwinner,sun50i-h616-de33-mixer-0
reg:
maxItems: 1
reg: true
reg-names: true
clocks:
items:
@ -61,6 +63,34 @@ properties:
required:
- port@1
allOf:
- if:
properties:
compatible:
contains:
enum:
- allwinner,sun50i-h616-de33-mixer-0
then:
properties:
reg:
description: |
Registers for controlling individual layers of the display
engine (layers), global control (top), and display blending
control (display). Names are from Allwinner BSP kernel.
maxItems: 3
reg-names:
items:
- const: layers
- const: top
- const: display
required:
- reg-names
else:
properties:
reg:
maxItems: 1
required:
- compatible
- reg

View file

@ -0,0 +1,57 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-axi-performance-counter.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller AXI Performance Counter
description: |
Performance counters are provided to allow measurement of average bandwidth
and latency during operation. The following features are supported:
* Manual and timer controlled measurement mode.
* Measurement counters:
- GLOBAL_COUNTER for overall measurement time
- BUSY_COUNTER for number of data bus busy cycles
- DATA_COUNTER for number of data transfer cycles
- TRANSFER_COUNTER for number of transfers
- ADDRBUSY_COUNTER for number of address bus busy cycles
- LATENCY_COUNTER for average latency
* Counter overflow detection.
* Outstanding Transfer Counters (OTC) which are used for latency measurement
have to run immediately after reset, but can be disabled by software when
there is no need for latency measurement.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-axi-performance-counter
reg:
maxItems: 1
clocks:
maxItems: 1
required:
- compatible
- reg
- clocks
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/imx8-lpcg.h>
pmu@5618f000 {
compatible = "fsl,imx8qxp-dc-axi-performance-counter";
reg = <0x5618f000 0x90>;
clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
};

View file

@ -0,0 +1,204 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-blit-engine.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Blit Engine
description: |
A blit operation (block based image transfer) reads up to 3 source images
from memory and computes one destination image from it, which is written
back to memory. The following basic operations are supported:
* Buffer Fill
Fills a buffer with constant color
* Buffer Copy
Copies one source to a destination buffer.
* Image Blend
Combines two source images by a blending equation and writes result to
destination (which can be one of the sources).
* Image Rop2/3
Combines up to three source images by a logical equation (raster operation)
and writes result to destination (which can be one of the sources).
* Image Flip
Mirrors the source image in horizontal and/or vertical direction.
* Format Convert
Convert between the supported color and buffer formats.
* Color Transform
Modify colors by linear or non-linear transformations.
* Image Scale
Changes size of the source image.
* Image Rotate
Rotates the source image by any angle.
* Image Filter
Performs an FIR filter operation on the source image.
* Image Warp
Performs a re-sampling of the source image with any pattern. The sample
point positions are read from a compressed coordinate buffer.
* Buffer Pack
Writes an image with color components stored in up to three different
buffers (planar formats) into a single buffer (packed format).
* Chroma Resample
Converts between different YUV formats that differ in chroma sampling rate
(4:4:4, 4:2:2, 4:2:0).
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-blit-engine
reg:
maxItems: 2
reg-names:
items:
- const: pec
- const: cfg
"#address-cells":
const: 1
"#size-cells":
const: 1
ranges: true
patternProperties:
"^blitblend@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-blitblend
"^clut@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-clut
"^fetchdecode@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-fetchdecode
"^fetcheco@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-fetcheco
"^fetchwarp@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-fetchwarp
"^filter@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-filter
"^hscaler@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-hscaler
"^matrix@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-matrix
"^rop@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-rop
"^store@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-store
"^vscaler@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-vscaler
required:
- compatible
- reg
- reg-names
- "#address-cells"
- "#size-cells"
- ranges
additionalProperties: false
examples:
- |
blit-engine@56180820 {
compatible = "fsl,imx8qxp-dc-blit-engine";
reg = <0x56180820 0x13c>, <0x56181000 0x3400>;
reg-names = "pec", "cfg";
#address-cells = <1>;
#size-cells = <1>;
ranges;
fetchdecode@56180820 {
compatible = "fsl,imx8qxp-dc-fetchdecode";
reg = <0x56180820 0x10>, <0x56181000 0x404>;
reg-names = "pec", "cfg";
};
store@56180940 {
compatible = "fsl,imx8qxp-dc-store";
reg = <0x56180940 0x1c>, <0x56184000 0x5c>;
reg-names = "pec", "cfg";
interrupt-parent = <&dc0_intc>;
interrupts = <0>, <1>, <2>;
interrupt-names = "shdload", "framecomplete", "seqcomplete";
};
};

View file

@ -0,0 +1,41 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-blitblend.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Blit Blend Unit
description:
Combines two input frames to a single output frame, all frames having the
same dimension.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-blitblend
reg:
maxItems: 2
reg-names:
items:
- const: pec
- const: cfg
required:
- compatible
- reg
- reg-names
additionalProperties: false
examples:
- |
blitblend@56180920 {
compatible = "fsl,imx8qxp-dc-blitblend";
reg = <0x56180920 0x10>, <0x56183c00 0x3c>;
reg-names = "pec", "cfg";
};

View file

@ -0,0 +1,44 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-clut.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Color Lookup Table
description: |
The unit implements 3 look-up tables with 256 x 10 bit entries each. These
can be used for different kinds of applications. From 10-bit input values
only upper 8 bits are used.
The unit supports color lookup, index lookup, dithering and alpha masking.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-clut
reg:
maxItems: 2
reg-names:
items:
- const: pec
- const: cfg
required:
- compatible
- reg
- reg-names
additionalProperties: false
examples:
- |
clut@56180880 {
compatible = "fsl,imx8qxp-dc-clut";
reg = <0x56180880 0x10>, <0x56182400 0x404>;
reg-names = "pec", "cfg";
};

View file

@ -0,0 +1,67 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-command-sequencer.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Command Sequencer
description: |
The Command Sequencer is designed to autonomously process command lists.
By that it can load setups into the DC configuration and synchronize to
hardware events. This releases a system's CPU from workload, because it
does not need to wait for certain events. Also it simplifies SW architecture,
because no interrupt handlers are required. Setups are read via AXI bus,
while write access to configuration registers occurs directly via an internal
bus. This saves bandwidth for the AXI interconnect and improves the system
architecture in terms of safety aspects.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-command-sequencer
reg:
maxItems: 1
clocks:
maxItems: 1
interrupts:
maxItems: 5
interrupt-names:
items:
- const: error
- const: sw0
- const: sw1
- const: sw2
- const: sw3
sram:
$ref: /schemas/types.yaml#/definitions/phandle
description: phandle pointing to the mmio-sram device node
required:
- compatible
- reg
- clocks
- interrupts
- interrupt-names
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/imx8-lpcg.h>
command-sequencer@56180400 {
compatible = "fsl,imx8qxp-dc-command-sequencer";
reg = <0x56180400 0x1a4>;
clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
interrupt-parent = <&dc0_intc>;
interrupts = <36>, <37>, <38>, <39>, <40>;
interrupt-names = "error", "sw0", "sw1", "sw2", "sw3";
};

View file

@ -0,0 +1,44 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-constframe.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Constant Frame
description: |
The Constant Frame unit is used instead of a Fetch unit where generation of
constant color frames only is sufficient. This is the case for the background
planes of content and safety streams in a Display Controller.
The color can be setup to any RGBA value.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-constframe
reg:
maxItems: 2
reg-names:
items:
- const: pec
- const: cfg
required:
- compatible
- reg
- reg-names
additionalProperties: false
examples:
- |
constframe@56180960 {
compatible = "fsl,imx8qxp-dc-constframe";
reg = <0x56180960 0xc>, <0x56184400 0x20>;
reg-names = "pec", "cfg";
};

View file

@ -0,0 +1,152 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-display-engine.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Display Engine
description:
All Processing Units that operate in a display clock domain. Pixel pipeline
is driven by a video timing and cannot be stalled. Implements all display
specific processing.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-display-engine
reg:
maxItems: 2
reg-names:
items:
- const: top
- const: cfg
resets:
maxItems: 1
interrupts:
maxItems: 3
interrupt-names:
items:
- const: shdload
- const: framecomplete
- const: seqcomplete
power-domains:
maxItems: 1
"#address-cells":
const: 1
"#size-cells":
const: 1
ranges: true
patternProperties:
"^dither@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-dither
"^framegen@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-framegen
"^gammacor@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-gammacor
"^matrix@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-matrix
"^signature@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-signature
"^tcon@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-tcon
required:
- compatible
- reg
- reg-names
- interrupts
- interrupt-names
- power-domains
- "#address-cells"
- "#size-cells"
- ranges
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/imx8-lpcg.h>
#include <dt-bindings/firmware/imx/rsrc.h>
display-engine@5618b400 {
compatible = "fsl,imx8qxp-dc-display-engine";
reg = <0x5618b400 0x14>, <0x5618b800 0x1c00>;
reg-names = "top", "cfg";
interrupt-parent = <&dc0_intc>;
interrupts = <15>, <16>, <17>;
interrupt-names = "shdload", "framecomplete", "seqcomplete";
power-domains = <&pd IMX_SC_R_DC_0_PLL_0>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
framegen@5618b800 {
compatible = "fsl,imx8qxp-dc-framegen";
reg = <0x5618b800 0x98>;
clocks = <&dc0_disp_lpcg IMX_LPCG_CLK_0>;
interrupt-parent = <&dc0_intc>;
interrupts = <18>, <19>, <20>, <21>, <41>, <42>, <43>, <44>;
interrupt-names = "int0", "int1", "int2", "int3",
"primsync_on", "primsync_off",
"secsync_on", "secsync_off";
};
tcon@5618c800 {
compatible = "fsl,imx8qxp-dc-tcon";
reg = <0x5618c800 0x588>;
port {
dc0_disp0_dc0_pixel_combiner_ch0: endpoint {
remote-endpoint = <&dc0_pixel_combiner_ch0_dc0_disp0>;
};
};
};
};

View file

@ -0,0 +1,45 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-dither.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Dither Unit
description: |
The unit can increase the physical color resolution of a display from 5, 6, 7
or 8 bits per RGB channel to a virtual resolution of 10 bits. The physical
resolution can be set individually for each channel.
The resolution is increased by mixing the two physical colors that are nearest
to the virtual color code in a variable ratio either by time (temporal
dithering) or by position (spatial dithering).
An optimized algorithm for temporal dithering minimizes noise artifacts on the
output image.
The dither operation can be individually enabled or disabled for each pixel
using the alpha input bit.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-dither
reg:
maxItems: 1
required:
- compatible
- reg
additionalProperties: false
examples:
- |
dither@5618c400 {
compatible = "fsl,imx8qxp-dc-dither";
reg = <0x5618c400 0x14>;
};

View file

@ -0,0 +1,72 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-extdst.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller External Destination Interface
description: |
The External Destination unit is the interface between the internal pixel
processing pipeline of the Pixel Engine, which is 30-bit RGB plus 8-bit Alpha,
and a Display Engine.
It comprises the following built-in Gamma apply function.
+------X-----------------------+
| | ExtDst Unit |
| V |
| +-------+ |
| | Gamma | |
| +-------+ |
| | |
| V +
+------X-----------------------+
The output format is 24-bit RGB plus 1-bit Alpha. Conversion from 10 to 8
bits is done by LSBit truncation. Alpha output bit is 1 for input 255, 0
otherwise.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-extdst
reg:
maxItems: 2
reg-names:
items:
- const: pec
- const: cfg
interrupts:
maxItems: 3
interrupt-names:
items:
- const: shdload
- const: framecomplete
- const: seqcomplete
required:
- compatible
- reg
- reg-names
- interrupts
- interrupt-names
additionalProperties: false
examples:
- |
extdst@56180980 {
compatible = "fsl,imx8qxp-dc-extdst";
reg = <0x56180980 0x1c>, <0x56184800 0x28>;
reg-names = "pec", "cfg";
interrupt-parent = <&dc0_intc>;
interrupts = <3>, <4>, <5>;
interrupt-names = "shdload", "framecomplete", "seqcomplete";
};

View file

@ -0,0 +1,141 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-fetchunit.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Fetch Unit
description: |
The Fetch Unit is the interface between the AXI bus for source buffer access
and the internal pixel processing pipeline, which is 30-bit RGB plus 8-bit
Alpha.
It is used to generate foreground planes in Display Controllers and source
planes in Blit Engines, and comprises the following built-in functions to
convert a wide range of frame buffer types.
+---------X-----------------------------------------+
| | Fetch Unit |
| V |
| +---------+ |
| | | |
| | Decode | Decompression [Decode] |
| | | |
| +---------+ |
| | |
| V |
| +---------+ |
| | Clip & | Clip Window [All] |
| | Overlay | Plane composition [Layer, Warp] |
| | | |
| +---------+ |
| | |
| V |
| +---------+ |
| | Re- | Flip/Rotate/Repl./Drop [All] |
X--> | sample | Perspective/Affine warping [Persp] |
| | | | Arbitrary warping [Warp, Persp] |
| | +---------+ |
| | | |
| | V |
| | +---------+ |
| | | | |
| | | Palette | Color Palette [Layer, Decode] |
| | | | |
| | +---------+ |
| | | |
| | V |
| | +---------+ |
| | | Extract | Raw to RGBA/YUV [All] |
| | | & | Bit width expansion [All] |
| | | Expand | |
| | +---------+ |
| | | |
| | V |
| | +---------+ |
| | | | Planar to packed |
| |->| Combine | [Decode, Warp, Persp] |
| | | | |
| | +---------+ |
| | | |
| | V |
| | +---------+ |
| | | | YUV422 to YUV444 |
| | | Chroma | [Decode, Persp] |
| | | | |
| | +---------+ |
| | | |
| | V |
| | +---------+ |
| | | | YUV to RGB |
| | | Color | [Warp, Persp, Decode, Layer] |
| | | | |
| | +---------+ |
| | | |
| | V |
| | +---------+ |
| | | | Gamma removal |
| | | Gamma | [Warp, Persp, Decode, Layer] |
| | | | |
| | +---------+ |
| | | |
| | V |
| | +---------+ |
| | | | Alpla multiply, RGB pre-multiply |
| ->| Multiply| [Warp, Persp, Decode, Layer] |
| | | |
| --------- |
| | |
| V |
| +---------+ |
| | | Bilinear filter |
| | Filter | [Warp, Persp] |
| | | |
| +---------+ |
| | |
| V |
+---------X-----------------------------------------+
Note that different derivatives of the Fetch Unit exist. Each implements a
specific subset only of the pipeline stages shown above. Restrictions for the
units are specified in [square brackets].
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
enum:
- fsl,imx8qxp-dc-fetchdecode
- fsl,imx8qxp-dc-fetcheco
- fsl,imx8qxp-dc-fetchlayer
- fsl,imx8qxp-dc-fetchwarp
reg:
maxItems: 2
reg-names:
items:
- const: pec
- const: cfg
fsl,prg:
$ref: /schemas/types.yaml#/definitions/phandle
description:
Optional Prefetch Resolve Gasket associated with the Fetch Unit.
required:
- compatible
- reg
- reg-names
additionalProperties: false
examples:
- |
fetchlayer@56180ac0 {
compatible = "fsl,imx8qxp-dc-fetchlayer";
reg = <0x56180ac0 0xc>, <0x56188400 0x404>;
reg-names = "pec", "cfg";
};

View file

@ -0,0 +1,43 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-filter.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Filter Unit
description: |
5x5 FIR filter with 25 programmable coefficients.
Typical applications are image blurring, sharpening or support for edge
detection algorithms.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-filter
reg:
maxItems: 2
reg-names:
items:
- const: pec
- const: cfg
required:
- compatible
- reg
- reg-names
additionalProperties: false
examples:
- |
filter@56180900 {
compatible = "fsl,imx8qxp-dc-filter";
reg = <0x56180900 0x10>, <0x56183800 0x30>;
reg-names = "pec", "cfg";
};

View file

@ -0,0 +1,64 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-framegen.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Frame Generator
description:
The Frame Generator (FrameGen) module generates a programmable video timing
and optionally allows to synchronize the generated video timing to external
synchronization signals.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-framegen
reg:
maxItems: 1
clocks:
maxItems: 1
interrupts:
maxItems: 8
interrupt-names:
items:
- const: int0
- const: int1
- const: int2
- const: int3
- const: primsync_on
- const: primsync_off
- const: secsync_on
- const: secsync_off
required:
- compatible
- reg
- clocks
- interrupts
- interrupt-names
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/imx8-lpcg.h>
#include <dt-bindings/firmware/imx/rsrc.h>
framegen@5618b800 {
compatible = "fsl,imx8qxp-dc-framegen";
reg = <0x5618b800 0x98>;
clocks = <&dc0_disp_lpcg IMX_LPCG_CLK_0>;
interrupt-parent = <&dc0_intc>;
interrupts = <18>, <19>, <20>, <21>, <41>, <42>, <43>, <44>;
interrupt-names = "int0", "int1", "int2", "int3",
"primsync_on", "primsync_off",
"secsync_on", "secsync_off";
};

View file

@ -0,0 +1,32 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-gammacor.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Gamma Correction Unit
description: The unit supports non-linear color transformation.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-gammacor
reg:
maxItems: 1
required:
- compatible
- reg
additionalProperties: false
examples:
- |
gammacor@5618c000 {
compatible = "fsl,imx8qxp-dc-gammacor";
reg = <0x5618c000 0x20>;
};

View file

@ -0,0 +1,39 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-layerblend.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Layer Blend Unit
description: Combines two input frames to a single output frame.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-layerblend
reg:
maxItems: 2
reg-names:
items:
- const: pec
- const: cfg
required:
- compatible
- reg
- reg-names
additionalProperties: false
examples:
- |
layerblend@56180ba0 {
compatible = "fsl,imx8qxp-dc-layerblend";
reg = <0x56180ba0 0x10>, <0x5618a400 0x20>;
reg-names = "pec", "cfg";
};

View file

@ -0,0 +1,44 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-matrix.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Color Matrix
description:
The unit supports linear color transformation, alpha pre-multiply and
alpha masking.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-matrix
reg:
minItems: 1
maxItems: 2
reg-names:
oneOf:
- const: cfg # matrix in display engine
- items: # matrix in pixel engine
- const: pec
- const: cfg
required:
- compatible
- reg
- reg-names
additionalProperties: false
examples:
- |
matrix@5618bc00 {
compatible = "fsl,imx8qxp-dc-matrix";
reg = <0x5618bc00 0x3c>;
reg-names = "cfg";
};

View file

@ -0,0 +1,250 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Pixel Engine
description:
All Processing Units that operate in the AXI bus clock domain. Pixel
pipelines have the ability to stall when a destination is busy. Implements
all communication to memory resources and most of the image processing
functions. Interconnection of Processing Units is re-configurable.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-pixel-engine
reg:
maxItems: 1
clocks:
maxItems: 1
"#address-cells":
const: 1
"#size-cells":
const: 1
ranges: true
patternProperties:
"^blit-engine@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-blit-engine
"^constframe@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-constframe
"^extdst@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-extdst
"^fetchdecode@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-fetchdecode
"^fetcheco@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-fetcheco
"^fetchlayer@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-fetchlayer
"^fetchwarp@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-fetchwarp
"^hscaler@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-hscaler
"^layerblend@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-layerblend
"^matrix@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-matrix
"^safety@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-safety
"^vscaler@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-vscaler
required:
- compatible
- reg
- clocks
- "#address-cells"
- "#size-cells"
- ranges
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/imx8-lpcg.h>
pixel-engine@56180800 {
compatible = "fsl,imx8qxp-dc-pixel-engine";
reg = <0x56180800 0xac00>;
clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
constframe@56180960 {
compatible = "fsl,imx8qxp-dc-constframe";
reg = <0x56180960 0xc>, <0x56184400 0x20>;
reg-names = "pec", "cfg";
};
extdst@56180980 {
compatible = "fsl,imx8qxp-dc-extdst";
reg = <0x56180980 0x1c>, <0x56184800 0x28>;
reg-names = "pec", "cfg";
interrupt-parent = <&dc0_intc>;
interrupts = <3>, <4>, <5>;
interrupt-names = "shdload", "framecomplete", "seqcomplete";
};
constframe@561809a0 {
compatible = "fsl,imx8qxp-dc-constframe";
reg = <0x561809a0 0xc>, <0x56184c00 0x20>;
reg-names = "pec", "cfg";
};
extdst@561809c0 {
compatible = "fsl,imx8qxp-dc-extdst";
reg = <0x561809c0 0x1c>, <0x56185000 0x28>;
reg-names = "pec", "cfg";
interrupt-parent = <&dc0_intc>;
interrupts = <6>, <7>, <8>;
interrupt-names = "shdload", "framecomplete", "seqcomplete";
};
constframe@561809e0 {
compatible = "fsl,imx8qxp-dc-constframe";
reg = <0x561809e0 0xc>, <0x56185400 0x20>;
reg-names = "pec", "cfg";
};
extdst@56180a00 {
compatible = "fsl,imx8qxp-dc-extdst";
reg = <0x56180a00 0x1c>, <0x56185800 0x28>;
reg-names = "pec", "cfg";
interrupt-parent = <&dc0_intc>;
interrupts = <9>, <10>, <11>;
interrupt-names = "shdload", "framecomplete", "seqcomplete";
};
constframe@56180a20 {
compatible = "fsl,imx8qxp-dc-constframe";
reg = <0x56180a20 0xc>, <0x56185c00 0x20>;
reg-names = "pec", "cfg";
};
extdst@56180a40 {
compatible = "fsl,imx8qxp-dc-extdst";
reg = <0x56180a40 0x1c>, <0x56186000 0x28>;
reg-names = "pec", "cfg";
interrupt-parent = <&dc0_intc>;
interrupts = <12>, <13>, <14>;
interrupt-names = "shdload", "framecomplete", "seqcomplete";
};
fetchwarp@56180a60 {
compatible = "fsl,imx8qxp-dc-fetchwarp";
reg = <0x56180a60 0x10>, <0x56186400 0x190>;
reg-names = "pec", "cfg";
};
fetchlayer@56180ac0 {
compatible = "fsl,imx8qxp-dc-fetchlayer";
reg = <0x56180ac0 0xc>, <0x56188400 0x404>;
reg-names = "pec", "cfg";
};
layerblend@56180ba0 {
compatible = "fsl,imx8qxp-dc-layerblend";
reg = <0x56180ba0 0x10>, <0x5618a400 0x20>;
reg-names = "pec", "cfg";
};
layerblend@56180bc0 {
compatible = "fsl,imx8qxp-dc-layerblend";
reg = <0x56180bc0 0x10>, <0x5618a800 0x20>;
reg-names = "pec", "cfg";
};
layerblend@56180be0 {
compatible = "fsl,imx8qxp-dc-layerblend";
reg = <0x56180be0 0x10>, <0x5618ac00 0x20>;
reg-names = "pec", "cfg";
};
layerblend@56180c00 {
compatible = "fsl,imx8qxp-dc-layerblend";
reg = <0x56180c00 0x10>, <0x5618b000 0x20>;
reg-names = "pec", "cfg";
};
};

View file

@ -0,0 +1,43 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-rop.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Raster Operation Unit
description: |
The unit can combine up to three input frames to a single output frame, all
having the same dimension.
The unit supports logic operations, arithmetic operations and packing.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-rop
reg:
maxItems: 2
reg-names:
items:
- const: pec
- const: cfg
required:
- compatible
- reg
- reg-names
additionalProperties: false
examples:
- |
rop@56180860 {
compatible = "fsl,imx8qxp-dc-rop";
reg = <0x56180860 0x10>, <0x56182000 0x20>;
reg-names = "pec", "cfg";
};

View file

@ -0,0 +1,34 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-safety.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Safety Unit
description:
The unit allows corresponding processing units to be configured in a path
leading to multiple endpoints.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-safety
reg:
maxItems: 1
required:
- compatible
- reg
additionalProperties: false
examples:
- |
safety@56180800 {
compatible = "fsl,imx8qxp-dc-safety";
reg = <0x56180800 0x1c>;
};

View file

@ -0,0 +1,83 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-scaling-engine.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Scaling Engine
description: |
The unit can change the dimension of the input frame by nearest or linear
re-sampling with 1/32 sub pixel precision.
Internally it consist of two independent blocks for horizontal and vertical
scaling. The sequence of both operations is arbitrary.
Any frame dimensions between 1 and 16384 pixels in width and height are
supported, except that the vertical scaler has a frame width maximum
depending of the system's functional limitations.
In general all scale factors are supported inside the supported frame
dimensions. In range of scale factors 1/16..16 the filtered output colors
are LSBit precise (e.g. DC ripple free).
+-----------+
| Line |
| Buffer |
+-----------+
^
|
V
|\ +-----------+
------+ | | |
| | +-->| Vertical |----
| ----+ | | Scaler | |
| | |/ +-----------+ |
| | |
| | |
| | | |\
| ------------- -------------+-----+ |
Input --+ X | +--> Output
| ------------- -------------+-----+ |
| | | |/
| | |
| | |\ +-----------+ |
| ----+ | | | |
| | +-->| Horizontal|----
------+ | | Scaler |
|/ +-----------+
The unit supports downscaling, upscaling, sub pixel translation and bob
de-interlacing.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
enum:
- fsl,imx8qxp-dc-hscaler
- fsl,imx8qxp-dc-vscaler
reg:
maxItems: 2
reg-names:
items:
- const: pec
- const: cfg
required:
- compatible
- reg
- reg-names
additionalProperties: false
examples:
- |
hscaler@561808c0 {
compatible = "fsl,imx8qxp-dc-hscaler";
reg = <0x561808c0 0x10>, <0x56183000 0x18>;
reg-names = "pec", "cfg";
};

View file

@ -0,0 +1,53 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-signature.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Signature Unit
description: |
In order to control the correctness of display output, signature values can
be computed for each frame and compared against reference values. In case of
a mismatch (signature violation) a HW event can be triggered, for example a
SW interrupt.
This unit supports signature computation, reference check, evaluation windows,
alpha masking and panic modes.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-signature
reg:
maxItems: 1
interrupts:
maxItems: 3
interrupt-names:
items:
- const: shdload
- const: valid
- const: error
required:
- compatible
- reg
- interrupts
- interrupt-names
additionalProperties: false
examples:
- |
signature@5618d000 {
compatible = "fsl,imx8qxp-dc-signature";
reg = <0x5618d000 0x140>;
interrupt-parent = <&dc0_intc>;
interrupts = <22>, <23>, <24>;
interrupt-names = "shdload", "valid", "error";
};

View file

@ -0,0 +1,96 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-store.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Store Unit
description: |
The Store unit is the interface between the internal pixel processing
pipeline, which is 30-bit RGB plus 8-bit Alpha, and the AXI bus for
destination buffer access. It is used for the destination of Blit Engines.
It comprises a set of built-in functions to generate a wide range of buffer
formats. Note, that these are exactly inverse to corresponding functions in
the Fetch Unit.
+------X-------------------------+
| | Store Unit |
| V |
| +-------+ |
| | Gamma | Gamma apply |
| +-------+ |
| | |
| V |
| +-------+ |
| | Color | RGB to YUV |
| +-------+ |
| | |
| V |
| +-------+ |
| | Chroma| YUV444 to 422 |
| +-------+ |
| | |
| V |
| +-------+ |
| | Reduce| Bit width reduction |
| | | dithering |
| +-------+ |
| | |
| V |
| +-------+ |
| | Pack | RGBA/YUV to RAW |
| | Encode| or Compression |
| +-------+ |
| | |
| V |
+------X-------------------------+
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-store
reg:
maxItems: 2
reg-names:
items:
- const: pec
- const: cfg
interrupts:
maxItems: 3
interrupt-names:
items:
- const: shdload
- const: framecomplete
- const: seqcomplete
fsl,lts:
$ref: /schemas/types.yaml#/definitions/phandle
description:
Optional Linear Tile Store associated with the Store Unit.
required:
- compatible
- reg
- reg-names
- interrupts
- interrupt-names
additionalProperties: false
examples:
- |
store@56180940 {
compatible = "fsl,imx8qxp-dc-store";
reg = <0x56180940 0x1c>, <0x56184000 0x5c>;
reg-names = "pec", "cfg";
interrupt-parent = <&dc0_intc>;
interrupts = <0>, <1>, <2>;
interrupt-names = "shdload", "framecomplete", "seqcomplete";
};

View file

@ -0,0 +1,45 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc-tcon.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller Timing Controller
description:
The TCon can generate a wide range of customized synchronization signals and
does the mapping of the color bits to the output.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-tcon
reg:
maxItems: 1
port:
$ref: /schemas/graph.yaml#/properties/port
description: video output
required:
- compatible
- reg
- port
additionalProperties: false
examples:
- |
tcon@5618c800 {
compatible = "fsl,imx8qxp-dc-tcon";
reg = <0x5618c800 0x588>;
port {
dc0_disp0_dc0_pixel_combiner_ch0: endpoint {
remote-endpoint = <&dc0_pixel_combiner_ch0_dc0_disp0>;
};
};
};

View file

@ -0,0 +1,236 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/imx/fsl,imx8qxp-dc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller
description: |
The Freescale i.MX8qxp Display Controller(DC) is comprised of three main
components that include a blit engine for 2D graphics accelerations, display
controller for display output processing, as well as a command sequencer.
Display buffers Source buffers
(AXI read master) (AXI read master)
| .......... | | | |
+---------------------------+------------+------------------+-+-+------+
| Display Controller (DC) | .......... | | | | |
| | | | | | |
| @@@@@@@@@@@ +----------+------------+------------+ | | | |
A | | Command | | V V | | | | |
X <-+->| Sequencer | | @@@@@@@@@@@@@@@@@@@@@@@@@@@@ | V V V |
I | | (AXI CLK) | | | | | @@@@@@@@@@ |
| @@@@@@@@@@@ | | Pixel Engine | | | | |
| | | | (AXI CLK) | | | | |
| V | @@@@@@@@@@@@@@@@@@@@@@@@@@@@ | | | |
A | *********** | | | | | | | Blit | |
H <-+->| Configure | | V V V V | | Engine | |
B | | (CFG CLK) | | 00000000000 11111111111 | | (AXI CLK)| |
| *********** | | Display | | Display | | | | |
| | | Engine | | Engine | | | | |
| | | (Disp CLK)| | (Disp CLK)| | | | |
| @@@@@@@@@@@ | 00000000000 11111111111 | @@@@@@@@@@ |
I | | Common | | | | | | |
R <-+--| Control | | | Display | | | |
Q | | (AXI CLK) | | | Controller | | | |
| @@@@@@@@@@@ +------------------------------------+ | |
| | | ^ | |
+--------------------------+----------------+-------+---------+--------+
^ | | | |
| V V | V
Clocks & Resets Display Display Panic Destination
Output0 Output1 Control buffer
(AXI write master)
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc
reg:
maxItems: 1
clocks:
maxItems: 1
resets:
maxItems: 2
reset-names:
items:
- const: axi
- const: cfg
power-domains:
maxItems: 1
"#address-cells":
const: 1
"#size-cells":
const: 1
ranges: true
patternProperties:
"^command-sequencer@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-command-sequencer
"^display-engine@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-display-engine
"^interrupt-controller@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-intc
"^pixel-engine@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-pixel-engine
"^pmu@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: fsl,imx8qxp-dc-axi-performance-counter
required:
- compatible
- reg
- clocks
- power-domains
- "#address-cells"
- "#size-cells"
- ranges
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/imx8-lpcg.h>
#include <dt-bindings/firmware/imx/rsrc.h>
display-controller@56180000 {
compatible = "fsl,imx8qxp-dc";
reg = <0x56180000 0x40000>;
clocks = <&dc0_lpcg IMX_LPCG_CLK_4>;
power-domains = <&pd IMX_SC_R_DC_0>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
interrupt-controller@56180040 {
compatible = "fsl,imx8qxp-dc-intc";
reg = <0x56180040 0x60>;
clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
interrupt-controller;
interrupt-parent = <&dc0_irqsteer>;
#interrupt-cells = <1>;
interrupts = <448>, <449>, <450>, <64>,
<65>, <66>, <67>, <68>,
<69>, <70>, <193>, <194>,
<195>, <196>, <197>, <72>,
<73>, <74>, <75>, <76>,
<77>, <78>, <79>, <80>,
<81>, <199>, <200>, <201>,
<202>, <203>, <204>, <205>,
<206>, <207>, <208>, <5>,
<0>, <1>, <2>, <3>,
<4>, <82>, <83>, <84>,
<85>, <209>, <210>, <211>,
<212>;
interrupt-names = "store9_shdload",
"store9_framecomplete",
"store9_seqcomplete",
"extdst0_shdload",
"extdst0_framecomplete",
"extdst0_seqcomplete",
"extdst4_shdload",
"extdst4_framecomplete",
"extdst4_seqcomplete",
"extdst1_shdload",
"extdst1_framecomplete",
"extdst1_seqcomplete",
"extdst5_shdload",
"extdst5_framecomplete",
"extdst5_seqcomplete",
"disengcfg_shdload0",
"disengcfg_framecomplete0",
"disengcfg_seqcomplete0",
"framegen0_int0",
"framegen0_int1",
"framegen0_int2",
"framegen0_int3",
"sig0_shdload",
"sig0_valid",
"sig0_error",
"disengcfg_shdload1",
"disengcfg_framecomplete1",
"disengcfg_seqcomplete1",
"framegen1_int0",
"framegen1_int1",
"framegen1_int2",
"framegen1_int3",
"sig1_shdload",
"sig1_valid",
"sig1_error",
"reserved",
"cmdseq_error",
"comctrl_sw0",
"comctrl_sw1",
"comctrl_sw2",
"comctrl_sw3",
"framegen0_primsync_on",
"framegen0_primsync_off",
"framegen0_secsync_on",
"framegen0_secsync_off",
"framegen1_primsync_on",
"framegen1_primsync_off",
"framegen1_secsync_on",
"framegen1_secsync_off";
};
pixel-engine@56180800 {
compatible = "fsl,imx8qxp-dc-pixel-engine";
reg = <0x56180800 0xac00>;
clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
};
display-engine@5618b400 {
compatible = "fsl,imx8qxp-dc-display-engine";
reg = <0x5618b400 0x14>, <0x5618b800 0x1c00>;
reg-names = "top", "cfg";
interrupt-parent = <&dc0_intc>;
interrupts = <15>, <16>, <17>;
interrupt-names = "shdload", "framecomplete", "seqcomplete";
power-domains = <&pd IMX_SC_R_DC_0_PLL_0>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
};
};

View file

@ -38,6 +38,10 @@ properties:
- qcom,sm8450-dp
- qcom,sm8550-dp
- const: qcom,sm8350-dp
- items:
- enum:
- qcom,sm8750-dp
- const: qcom,sm8650-dp
reg:
minItems: 4

View file

@ -42,6 +42,7 @@ properties:
- qcom,sm8450-dsi-ctrl
- qcom,sm8550-dsi-ctrl
- qcom,sm8650-dsi-ctrl
- qcom,sm8750-dsi-ctrl
- const: qcom,mdss-dsi-ctrl
- enum:
- qcom,dsi-ctrl-6g-qcm2290
@ -70,11 +71,11 @@ properties:
- mnoc:: MNOC clock
- pixel:: Display pixel clock.
minItems: 3
maxItems: 9
maxItems: 12
clock-names:
minItems: 3
maxItems: 9
maxItems: 12
phys:
maxItems: 1
@ -109,7 +110,8 @@ properties:
minItems: 2
maxItems: 4
description: |
Parents of "byte" and "pixel" for the given platform.
For DSI on SM8650 and older: parents of "byte" and "pixel" for the given
platform.
For DSIv2 platforms this should contain "byte", "esc", "src" and
"pixel_src" clocks.
@ -218,8 +220,6 @@ required:
- clocks
- clock-names
- phys
- assigned-clocks
- assigned-clock-parents
- ports
allOf:
@ -244,6 +244,9 @@ allOf:
- const: byte
- const: pixel
- const: core
required:
- assigned-clocks
- assigned-clock-parents
- if:
properties:
@ -266,6 +269,9 @@ allOf:
- const: byte
- const: pixel
- const: core
required:
- assigned-clocks
- assigned-clock-parents
- if:
properties:
@ -288,6 +294,9 @@ allOf:
- const: pixel
- const: core
- const: core_mmss
required:
- assigned-clocks
- assigned-clock-parents
- if:
properties:
@ -309,6 +318,9 @@ allOf:
- const: core_mmss
- const: pixel
- const: core
required:
- assigned-clocks
- assigned-clock-parents
- if:
properties:
@ -346,6 +358,35 @@ allOf:
- const: core
- const: iface
- const: bus
required:
- assigned-clocks
- assigned-clock-parents
- if:
properties:
compatible:
contains:
enum:
- qcom,sm8750-dsi-ctrl
then:
properties:
clocks:
minItems: 12
maxItems: 12
clock-names:
items:
- const: byte
- const: byte_intf
- const: pixel
- const: core
- const: iface
- const: bus
- const: dsi_pll_pixel
- const: dsi_pll_byte
- const: esync
- const: osc
- const: byte_src
- const: pixel_src
- if:
properties:
@ -369,6 +410,9 @@ allOf:
- const: core_mmss
- const: pixel
- const: core
required:
- assigned-clocks
- assigned-clock-parents
unevaluatedProperties: false

View file

@ -25,6 +25,7 @@ properties:
- qcom,sm8450-dsi-phy-5nm
- qcom,sm8550-dsi-phy-4nm
- qcom,sm8650-dsi-phy-4nm
- qcom,sm8750-dsi-phy-3nm
reg:
items:

View file

@ -16,6 +16,7 @@ properties:
enum:
- qcom,sa8775p-dpu
- qcom,sm8650-dpu
- qcom,sm8750-dpu
- qcom,x1e80100-dpu
reg:

View file

@ -0,0 +1,470 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/qcom,sm8750-mdss.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SM8750 Display MDSS
maintainers:
- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
description:
SM8650 MSM Mobile Display Subsystem(MDSS), which encapsulates sub-blocks like
DPU display controller, DSI and DP interfaces etc.
$ref: /schemas/display/msm/mdss-common.yaml#
properties:
compatible:
const: qcom,sm8750-mdss
clocks:
items:
- description: Display AHB
- description: Display hf AXI
- description: Display core
iommus:
maxItems: 1
interconnects:
items:
- description: Interconnect path from mdp0 port to the data bus
- description: Interconnect path from CPU to the reg bus
interconnect-names:
items:
- const: mdp0-mem
- const: cpu-cfg
patternProperties:
"^display-controller@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: qcom,sm8750-dpu
"^displayport-controller@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
contains:
const: qcom,sm8750-dp
"^dsi@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
contains:
const: qcom,sm8750-dsi-ctrl
"^phy@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: qcom,sm8750-dsi-phy-3nm
required:
- compatible
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/interconnect/qcom,icc.h>
#include <dt-bindings/interconnect/qcom,sm8750-rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/phy/phy-qcom-qmp.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
display-subsystem@ae00000 {
compatible = "qcom,sm8750-mdss";
reg = <0x0ae00000 0x1000>;
reg-names = "mdss";
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&disp_cc_mdss_ahb_clk>,
<&gcc_disp_hf_axi_clk>,
<&disp_cc_mdss_mdp_clk>;
interconnects = <&mmss_noc MASTER_MDP QCOM_ICC_TAG_ALWAYS
&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
&config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
interconnect-names = "mdp0-mem",
"cpu-cfg";
resets = <&disp_cc_mdss_core_bcr>;
power-domains = <&mdss_gdsc>;
iommus = <&apps_smmu 0x800 0x2>;
interrupt-controller;
#interrupt-cells = <1>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
display-controller@ae01000 {
compatible = "qcom,sm8750-dpu";
reg = <0x0ae01000 0x93000>,
<0x0aeb0000 0x2008>;
reg-names = "mdp",
"vbif";
interrupts-extended = <&mdss 0>;
clocks = <&gcc_disp_hf_axi_clk>,
<&disp_cc_mdss_ahb_clk>,
<&disp_cc_mdss_mdp_lut_clk>,
<&disp_cc_mdss_mdp_clk>,
<&disp_cc_mdss_vsync_clk>;
clock-names = "nrt_bus",
"iface",
"lut",
"core",
"vsync";
assigned-clocks = <&disp_cc_mdss_vsync_clk>;
assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dpu_intf1_out: endpoint {
remote-endpoint = <&mdss_dsi0_in>;
};
};
port@1 {
reg = <1>;
dpu_intf2_out: endpoint {
remote-endpoint = <&mdss_dsi1_in>;
};
};
port@2 {
reg = <2>;
dpu_intf0_out: endpoint {
remote-endpoint = <&mdss_dp0_in>;
};
};
};
mdp_opp_table: opp-table {
compatible = "operating-points-v2";
opp-207000000 {
opp-hz = /bits/ 64 <207000000>;
required-opps = <&rpmhpd_opp_low_svs>;
};
opp-337000000 {
opp-hz = /bits/ 64 <337000000>;
required-opps = <&rpmhpd_opp_svs>;
};
opp-417000000 {
opp-hz = /bits/ 64 <417000000>;
required-opps = <&rpmhpd_opp_svs_l1>;
};
opp-532000000 {
opp-hz = /bits/ 64 <532000000>;
required-opps = <&rpmhpd_opp_nom>;
};
opp-575000000 {
opp-hz = /bits/ 64 <575000000>;
required-opps = <&rpmhpd_opp_nom_l1>;
};
};
};
dsi@ae94000 {
compatible = "qcom,sm8750-dsi-ctrl", "qcom,mdss-dsi-ctrl";
reg = <0x0ae94000 0x400>;
reg-names = "dsi_ctrl";
interrupts-extended = <&mdss 4>;
clocks = <&disp_cc_mdss_byte0_clk>,
<&disp_cc_mdss_byte0_intf_clk>,
<&disp_cc_mdss_pclk0_clk>,
<&disp_cc_mdss_esc0_clk>,
<&disp_cc_mdss_ahb_clk>,
<&gcc_disp_hf_axi_clk>,
<&mdss_dsi0_phy 1>,
<&mdss_dsi0_phy 0>,
<&disp_cc_esync0_clk>,
<&disp_cc_osc_clk>,
<&disp_cc_mdss_byte0_clk_src>,
<&disp_cc_mdss_pclk0_clk_src>;
clock-names = "byte",
"byte_intf",
"pixel",
"core",
"iface",
"bus",
"dsi_pll_pixel",
"dsi_pll_byte",
"esync",
"osc",
"byte_src",
"pixel_src";
operating-points-v2 = <&mdss_dsi_opp_table>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
phys = <&mdss_dsi0_phy>;
phy-names = "dsi";
vdda-supply = <&vreg_l3g_1p2>;
#address-cells = <1>;
#size-cells = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
mdss_dsi0_in: endpoint {
remote-endpoint = <&dpu_intf1_out>;
};
};
port@1 {
reg = <1>;
mdss_dsi0_out: endpoint {
remote-endpoint = <&panel0_in>;
data-lanes = <0 1 2 3>;
};
};
};
mdss_dsi_opp_table: opp-table {
compatible = "operating-points-v2";
opp-187500000 {
opp-hz = /bits/ 64 <187500000>;
required-opps = <&rpmhpd_opp_low_svs>;
};
opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
required-opps = <&rpmhpd_opp_svs>;
};
opp-358000000 {
opp-hz = /bits/ 64 <358000000>;
required-opps = <&rpmhpd_opp_svs_l1>;
};
};
};
mdss_dsi0_phy: phy@ae95000 {
compatible = "qcom,sm8750-dsi-phy-3nm";
reg = <0x0ae95000 0x200>,
<0x0ae95200 0x280>,
<0x0ae95500 0x400>;
reg-names = "dsi_phy",
"dsi_phy_lane",
"dsi_pll";
clocks = <&disp_cc_mdss_ahb_clk>,
<&rpmhcc RPMH_CXO_CLK>;
clock-names = "iface",
"ref";
vdds-supply = <&vreg_l3i_0p88>;
#clock-cells = <1>;
#phy-cells = <0>;
};
dsi@ae96000 {
compatible = "qcom,sm8750-dsi-ctrl", "qcom,mdss-dsi-ctrl";
reg = <0x0ae96000 0x400>;
reg-names = "dsi_ctrl";
interrupts-extended = <&mdss 5>;
clocks = <&disp_cc_mdss_byte1_clk>,
<&disp_cc_mdss_byte1_intf_clk>,
<&disp_cc_mdss_pclk1_clk>,
<&disp_cc_mdss_esc1_clk>,
<&disp_cc_mdss_ahb_clk>,
<&gcc_disp_hf_axi_clk>,
<&mdss_dsi1_phy 1>,
<&mdss_dsi1_phy 0>,
<&disp_cc_esync1_clk>,
<&disp_cc_osc_clk>,
<&disp_cc_mdss_byte1_clk_src>,
<&disp_cc_mdss_pclk1_clk_src>;
clock-names = "byte",
"byte_intf",
"pixel",
"core",
"iface",
"bus",
"dsi_pll_pixel",
"dsi_pll_byte",
"esync",
"osc",
"byte_src",
"pixel_src";
operating-points-v2 = <&mdss_dsi_opp_table>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
phys = <&mdss_dsi1_phy>;
phy-names = "dsi";
#address-cells = <1>;
#size-cells = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
mdss_dsi1_in: endpoint {
remote-endpoint = <&dpu_intf2_out>;
};
};
port@1 {
reg = <1>;
mdss_dsi1_out: endpoint {
};
};
};
};
mdss_dsi1_phy: phy@ae97000 {
compatible = "qcom,sm8750-dsi-phy-3nm";
reg = <0x0ae97000 0x200>,
<0x0ae97200 0x280>,
<0x0ae97500 0x400>;
reg-names = "dsi_phy",
"dsi_phy_lane",
"dsi_pll";
clocks = <&disp_cc_mdss_ahb_clk>,
<&rpmhcc RPMH_CXO_CLK>;
clock-names = "iface",
"ref";
#clock-cells = <1>;
#phy-cells = <0>;
};
displayport-controller@af54000 {
compatible = "qcom,sm8750-dp", "qcom,sm8650-dp";
reg = <0xaf54000 0x104>,
<0xaf54200 0xc0>,
<0xaf55000 0x770>,
<0xaf56000 0x9c>,
<0xaf57000 0x9c>;
interrupts-extended = <&mdss 12>;
clocks = <&disp_cc_mdss_ahb_clk>,
<&disp_cc_mdss_dptx0_aux_clk>,
<&disp_cc_mdss_dptx0_link_clk>,
<&disp_cc_mdss_dptx0_link_intf_clk>,
<&disp_cc_mdss_dptx0_pixel0_clk>;
clock-names = "core_iface",
"core_aux",
"ctrl_link",
"ctrl_link_iface",
"stream_pixel";
assigned-clocks = <&disp_cc_mdss_dptx0_link_clk_src>,
<&disp_cc_mdss_dptx0_pixel0_clk_src>;
assigned-clock-parents = <&usb_dp_qmpphy QMP_USB43DP_DP_LINK_CLK>,
<&usb_dp_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>;
operating-points-v2 = <&dp_opp_table>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
phys = <&usb_dp_qmpphy QMP_USB43DP_DP_PHY>;
phy-names = "dp";
#sound-dai-cells = <0>;
dp_opp_table: opp-table {
compatible = "operating-points-v2";
opp-192000000 {
opp-hz = /bits/ 64 <192000000>;
required-opps = <&rpmhpd_opp_low_svs_d1>;
};
opp-270000000 {
opp-hz = /bits/ 64 <270000000>;
required-opps = <&rpmhpd_opp_low_svs>;
};
opp-540000000 {
opp-hz = /bits/ 64 <540000000>;
required-opps = <&rpmhpd_opp_svs_l1>;
};
opp-810000000 {
opp-hz = /bits/ 64 <810000000>;
required-opps = <&rpmhpd_opp_nom>;
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
mdss_dp0_in: endpoint {
remote-endpoint = <&dpu_intf0_out>;
};
};
port@1 {
reg = <1>;
mdss_dp0_out: endpoint {
remote-endpoint = <&usb_dp_qmpphy_dp_in>;
};
};
};
};
};

View file

@ -0,0 +1,73 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/panel/himax,hx83112b.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Himax HX83112B-based DSI display panels
maintainers:
- Luca Weiss <luca@lucaweiss.eu>
description:
The Himax HX83112B is a generic DSI Panel IC used to control
LCD panels.
allOf:
- $ref: panel-common.yaml#
properties:
compatible:
contains:
const: djn,98-03057-6598b-i
reg:
maxItems: 1
iovcc-supply:
description: I/O voltage rail
vsn-supply:
description: Positive source voltage rail
vsp-supply:
description: Negative source voltage rail
required:
- compatible
- reg
- reset-gpios
- iovcc-supply
- vsn-supply
- vsp-supply
- port
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
dsi {
#address-cells = <1>;
#size-cells = <0>;
panel@0 {
compatible = "djn,98-03057-6598b-i";
reg = <0>;
reset-gpios = <&tlmm 61 GPIO_ACTIVE_LOW>;
iovcc-supply = <&pm8953_l6>;
vsn-supply = <&pmi632_lcdb_ncp>;
vsp-supply = <&pmi632_lcdb_ldo>;
port {
panel_in_0: endpoint {
remote-endpoint = <&dsi0_out>;
};
};
};
};
...

View file

@ -17,12 +17,17 @@ description:
properties:
compatible:
items:
- enum:
- hannstar,hsd060bhw4
- microchip,ac40t08a-mipi-panel
- powkiddy,x55-panel
- const: himax,hx8394
oneOf:
- items:
- enum:
- hannstar,hsd060bhw4
- microchip,ac40t08a-mipi-panel
- powkiddy,x55-panel
- const: himax,hx8394
- items:
- enum:
- huiling,hl055fhav028c
- const: himax,hx8399c
reg:
maxItems: 1

View file

@ -19,6 +19,7 @@ properties:
- ampire,am8001280g
- bananapi,lhr050h41
- feixin,k101-im2byl02
- raspberrypi,dsi-7inch
- startek,kd050hdfia020
- tdo,tl050hdv35
- wanchanglong,w552946aba

View file

@ -57,6 +57,8 @@ properties:
- auo,g121ean01
# AU Optronics Corporation 15.6" (1366x768) TFT LCD panel
- auo,g156xtn01
# AU Optronics Corporation 23.8" FHD (1920x1080) TFT LCD panel
- auo,p238han01
# AU Optronics Corporation 31.5" FHD (1920x1080) TFT LCD panel
- auo,p320hvn03
# AU Optronics Corporation 21.5" FHD (1920x1080) color TFT LCD panel

View file

@ -42,7 +42,6 @@ required:
- compatible
- port
- reg
- reset-gpios
additionalProperties: false

View file

@ -0,0 +1,94 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/panel/renesas,r61307.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Renesas R61307 based DSI Display Panel
maintainers:
- Svyatoslav Ryhel <clamor95@gmail.com>
description:
The Renesas R61307 is a generic DSI Panel IC used to control LCD panels.
allOf:
- $ref: panel-common.yaml#
properties:
compatible:
items:
- enum:
# KOE/HITACHI TX13D100VM0EAA 5.0" XGA TFT LCD panel
- hit,tx13d100vm0eaa
- koe,tx13d100vm0eaa
- const: renesas,r61307
reg:
maxItems: 1
vcc-supply:
description: Regulator for main power supply.
iovcc-supply:
description: Regulator for 1.8V IO power supply.
backlight: true
renesas,gamma:
$ref: /schemas/types.yaml#/definitions/uint32
description:
0 - disabled
1-3 - gamma setting A presets
enum: [0, 1, 2, 3]
renesas,column-inversion:
type: boolean
description: switch between line and column inversion. The line
inversion is set by default.
renesas,contrast:
type: boolean
description: digital contrast adjustment
reset-gpios: true
port: true
required:
- compatible
- port
- backlight
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
dsi {
#address-cells = <1>;
#size-cells = <0>;
panel@1 {
compatible = "koe,tx13d100vm0eaa", "renesas,r61307";
reg = <1>;
reset-gpios = <&gpio 176 GPIO_ACTIVE_LOW>;
renesas,gamma = <3>;
renesas,column-inversion;
renesas,contrast;
vcc-supply = <&vcc_3v0_lcd>;
iovcc-supply = <&iovcc_1v8_lcd>;
backlight = <&backlight>;
port {
panel_in: endpoint {
remote-endpoint = <&dsi_out>;
};
};
};
};
...

View file

@ -0,0 +1,73 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/panel/renesas,r69328.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Renesas R69328 based DSI Display Panel
maintainers:
- Svyatoslav Ryhel <clamor95@gmail.com>
description:
The Renesas R69328 is a generic DSI Panel IC used to control LCD panels.
allOf:
- $ref: panel-common.yaml#
properties:
compatible:
items:
- enum:
# JDI DX12D100VM0EAA 4.7" WXGA TFT LCD panel
- jdi,dx12d100vm0eaa
- const: renesas,r69328
reg:
maxItems: 1
vdd-supply:
description: Regulator for main power supply.
vddio-supply:
description: Regulator for 1.8V IO power supply.
backlight: true
reset-gpios: true
port: true
required:
- compatible
- port
- backlight
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
dsi {
#address-cells = <1>;
#size-cells = <0>;
panel@1 {
compatible = "jdi,dx12d100vm0eaa", "renesas,r69328";
reg = <1>;
reset-gpios = <&gpio 176 GPIO_ACTIVE_LOW>;
vdd-supply = <&vdd_3v0_lcd>;
vddio-supply = <&vdd_1v8_io>;
backlight = <&backlight>;
port {
panel_in: endpoint {
remote-endpoint = <&dsi_out>;
};
};
};
};
...

View file

@ -19,6 +19,8 @@ properties:
- const: samsung,atna33xc20
- items:
- enum:
# Samsung 13" 3K (2880×1920 pixels) eDP AMOLED panel
- samsung,atna30dw01
# Samsung 14" WQXGA+ (2880×1800 pixels) eDP AMOLED panel
- samsung,atna40yk20
# Samsung 14.5" WQXGA+ (2880x1800 pixels) eDP AMOLED panel

View file

@ -29,6 +29,7 @@ properties:
- densitron,dmt028vghmcmi-1a
- elida,kd50t048a
- techstar,ts8550b
- winstar,wf40eswaa6mnn0
- const: sitronix,st7701
reg:

View file

@ -18,7 +18,9 @@ allOf:
properties:
compatible:
const: visionox,rm69299-1080p-display
enum:
- visionox,rm69299-1080p-display
- visionox,rm69299-shift
reg:
maxItems: 1

View file

@ -20,6 +20,7 @@ properties:
- enum:
- renesas,r9a07g043u-du # RZ/G2UL
- renesas,r9a07g044-du # RZ/G2{L,LC}
- renesas,r9a09g057-du # RZ/V2H(P)
- items:
- enum:
- renesas,r9a07g054-du # RZ/V2L
@ -101,7 +102,12 @@ allOf:
required:
- port@0
else:
- if:
properties:
compatible:
contains:
const: renesas,r9a07g044-du
then:
properties:
ports:
properties:
@ -113,6 +119,21 @@ allOf:
required:
- port@0
- port@1
- if:
properties:
compatible:
contains:
const: renesas,r9a09g057-du
then:
properties:
ports:
properties:
port@0:
description: DSI
port@1: false
required:
- port@0
examples:
# RZ/G2L DU

View file

@ -58,12 +58,6 @@ properties:
power-domains:
maxItems: 1
"#address-cells":
const: 1
"#size-cells":
const: 0
required:
- compatible
- clocks

View file

@ -64,10 +64,10 @@ properties:
- description: Pixel clock for video port 0.
- description: Pixel clock for video port 1.
- description: Pixel clock for video port 2.
- description: Pixel clock for video port 3.
- description: Peripheral(vop grf/dsi) clock.
- description: Alternative pixel clock provided by HDMI0 PHY PLL.
- description: Alternative pixel clock provided by HDMI1 PHY PLL.
- {}
- {}
- {}
- {}
clock-names:
minItems: 5
@ -77,10 +77,10 @@ properties:
- const: dclk_vp0
- const: dclk_vp1
- const: dclk_vp2
- const: dclk_vp3
- const: pclk_vop
- const: pll_hdmiphy0
- const: pll_hdmiphy1
- {}
- {}
- {}
- {}
rockchip,grf:
$ref: /schemas/types.yaml#/definitions/phandle
@ -175,10 +175,24 @@ allOf:
then:
properties:
clocks:
maxItems: 5
minItems: 5
items:
- {}
- {}
- {}
- {}
- {}
- description: Alternative pixel clock provided by HDMI PHY PLL.
clock-names:
maxItems: 5
minItems: 5
items:
- {}
- {}
- {}
- {}
- {}
- const: pll_hdmiphy0
interrupts:
minItems: 4
@ -208,11 +222,29 @@ allOf:
properties:
clocks:
minItems: 7
maxItems: 9
items:
- {}
- {}
- {}
- {}
- {}
- description: Pixel clock for video port 3.
- description: Peripheral(vop grf/dsi) clock.
- description: Alternative pixel clock provided by HDMI0 PHY PLL.
- description: Alternative pixel clock provided by HDMI1 PHY PLL.
clock-names:
minItems: 7
maxItems: 9
items:
- {}
- {}
- {}
- {}
- {}
- const: dclk_vp3
- const: pclk_vop
- const: pll_hdmiphy0
- const: pll_hdmiphy1
interrupts:
maxItems: 1

View file

@ -0,0 +1,63 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/sitronix,st7567.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Sitronix ST7567 Display Controller
maintainers:
- Javier Martinez Canillas <javierm@redhat.com>
description:
Sitronix ST7567 is a driver and controller for monochrome
dot matrix LCD panels.
allOf:
- $ref: panel/panel-common.yaml#
properties:
compatible:
const: sitronix,st7567
reg:
maxItems: 1
width-mm: true
height-mm: true
panel-timing: true
required:
- compatible
- reg
- width-mm
- height-mm
- panel-timing
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
display@3f {
compatible = "sitronix,st7567";
reg = <0x3f>;
width-mm = <37>;
height-mm = <27>;
panel-timing {
hactive = <128>;
vactive = <64>;
hback-porch = <0>;
vback-porch = <0>;
clock-frequency = <0>;
hfront-porch = <0>;
hsync-len = <0>;
vfront-porch = <0>;
vsync-len = <0>;
};
};
};

View file

@ -0,0 +1,79 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/ti/ti,am625-oldi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments AM625 OLDI Transmitter
maintainers:
- Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
- Aradhya Bhatia <aradhya.bhatia@linux.dev>
description:
The AM625 TI Keystone OpenLDI transmitter (OLDI TX) supports serialized RGB
pixel data transmission between host and flat panel display over LVDS (Low
Voltage Differential Sampling) interface. The OLDI TX consists of 7-to-1 data
serializers, and 4-data and 1-clock LVDS outputs. It supports the LVDS output
formats "jeida-18", "jeida-24" and "vesa-18", and can accept 24-bit RGB or
padded and un-padded 18-bit RGB bus formats as input.
properties:
reg:
maxItems: 1
clocks:
maxItems: 1
description: serial clock input for the OLDI transmitters
clock-names:
const: serial
ti,companion-oldi:
$ref: /schemas/types.yaml#/definitions/phandle
description:
phandle to companion OLDI transmitter. This property is required for both
the OLDI TXes if they are expected to work either in dual-lvds mode or in
clone mode. This property should point to the other OLDI TX's phandle.
ti,secondary-oldi:
type: boolean
description:
Boolean property to mark the OLDI transmitter as the secondary one, when the
OLDI hardware is expected to run as a companion HW, in cases of dual-lvds
mode or clone mode. The primary OLDI hardware is responsible for all the
hardware configuration.
ti,oldi-io-ctrl:
$ref: /schemas/types.yaml#/definitions/phandle
description:
phandle to syscon device node mapping OLDI IO_CTRL registers found in the
control MMR region. These registers are required to toggle the I/O lane
power, and control its electrical characteristics.
ports:
$ref: /schemas/graph.yaml#/properties/ports
properties:
port@0:
$ref: /schemas/graph.yaml#/properties/port
description: Parallel RGB input port
port@1:
$ref: /schemas/graph.yaml#/properties/port
description: LVDS output port
required:
- port@0
- port@1
required:
- reg
- clocks
- clock-names
- ti,oldi-io-ctrl
- ports
additionalProperties: false
...

View file

@ -12,18 +12,25 @@ maintainers:
- Tomi Valkeinen <tomi.valkeinen@ti.com>
description: |
The AM625 and AM65x TI Keystone Display SubSystem with two output
The AM625 and AM65x TI Keystone Display SubSystem has two output
ports and two video planes. In AM65x DSS, the first video port
supports 1 OLDI TX and in AM625 DSS, the first video port output is
internally routed to 2 OLDI TXes. The second video port supports DPI
format. The first plane is full video plane with all features and the
second is a "lite plane" without scaling support.
The AM62L display subsystem has a single output port which supports DPI
format but it only supports single video "lite plane" which does not support
scaling. The output port is routed to SoC boundary via DPI interface and same
DPI signals are also routed internally to DSI Tx controller present within the
SoC. Due to clocking limitations only one of the interface i.e. either DSI or
DPI can be used at once.
properties:
compatible:
enum:
- ti,am625-dss
- ti,am62a7-dss
- ti,am62l-dss
- ti,am65x-dss
reg:
@ -91,6 +98,26 @@ properties:
For AM625 DSS, the internal DPI output port node from video
port 1.
For AM62A7 DSS, the port is tied off inside the SoC.
For AM62L DSS, the DSS DPI output port node from video port 1
or DSI Tx controller node connected to video port 1.
properties:
endpoint@0:
$ref: /schemas/graph.yaml#/properties/endpoint
description:
For AM625 DSS, VP Connection to OLDI0.
For AM65X DSS, OLDI output from the SoC.
endpoint@1:
$ref: /schemas/graph.yaml#/properties/endpoint
description:
For AM625 DSS, VP Connection to OLDI1.
anyOf:
- required:
- endpoint
- required:
- endpoint@0
- endpoint@1
port@1:
$ref: /schemas/graph.yaml#/properties/port
@ -112,6 +139,25 @@ properties:
Input memory (from main memory to dispc) bandwidth limit in
bytes per second
oldi-transmitters:
description:
Child node under the DSS, to describe all the OLDI transmitters connected
to the DSS videoports.
type: object
additionalProperties: false
properties:
"#address-cells":
const: 1
"#size-cells":
const: 0
patternProperties:
'^oldi@[0-1]$':
$ref: ti,am625-oldi.yaml#
description: OLDI transmitters connected to the DSS VPs
allOf:
- if:
properties:
@ -120,9 +166,36 @@ allOf:
const: ti,am62a7-dss
then:
properties:
oldi-transmitters: false
ports:
properties:
port@0: false
- if:
properties:
compatible:
contains:
const: ti,am62l-dss
then:
properties:
ports:
properties:
port@1: false
- if:
properties:
compatible:
contains:
enum:
- ti,am62l-dss
- ti,am65x-dss
then:
properties:
oldi-transmitters: false
ports:
properties:
port@0:
properties:
endpoint@1: false
required:
- compatible
@ -142,32 +215,135 @@ examples:
#include <dt-bindings/soc/ti,sci_pm_domain.h>
dss: dss@4a00000 {
compatible = "ti,am65x-dss";
reg = <0x04a00000 0x1000>, /* common */
<0x04a02000 0x1000>, /* vidl1 */
<0x04a06000 0x1000>, /* vid */
<0x04a07000 0x1000>, /* ovr1 */
<0x04a08000 0x1000>, /* ovr2 */
<0x04a0a000 0x1000>, /* vp1 */
<0x04a0b000 0x1000>, /* vp2 */
<0x04a01000 0x1000>; /* common1 */
compatible = "ti,am65x-dss";
reg = <0x04a00000 0x1000>, /* common */
<0x04a02000 0x1000>, /* vidl1 */
<0x04a06000 0x1000>, /* vid */
<0x04a07000 0x1000>, /* ovr1 */
<0x04a08000 0x1000>, /* ovr2 */
<0x04a0a000 0x1000>, /* vp1 */
<0x04a0b000 0x1000>, /* vp2 */
<0x04a01000 0x1000>; /* common1 */
reg-names = "common", "vidl1", "vid",
"ovr1", "ovr2", "vp1", "vp2", "common1";
ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
power-domains = <&k3_pds 67 TI_SCI_PD_EXCLUSIVE>;
clocks = <&k3_clks 67 1>,
<&k3_clks 216 1>,
<&k3_clks 67 2>;
clock-names = "fck", "vp1", "vp2";
interrupts = <GIC_SPI 166 IRQ_TYPE_EDGE_RISING>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
oldi_out0: endpoint {
remote-endpoint = <&lcd_in0>;
};
};
};
};
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/soc/ti,sci_pm_domain.h>
bus {
#address-cells = <2>;
#size-cells = <2>;
dss1: dss@30200000 {
compatible = "ti,am625-dss";
reg = <0x00 0x30200000 0x00 0x1000>, /* common */
<0x00 0x30202000 0x00 0x1000>, /* vidl1 */
<0x00 0x30206000 0x00 0x1000>, /* vid */
<0x00 0x30207000 0x00 0x1000>, /* ovr1 */
<0x00 0x30208000 0x00 0x1000>, /* ovr2 */
<0x00 0x3020a000 0x00 0x1000>, /* vp1 */
<0x00 0x3020b000 0x00 0x1000>, /* vp2 */
<0x00 0x30201000 0x00 0x1000>; /* common1 */
reg-names = "common", "vidl1", "vid",
"ovr1", "ovr2", "vp1", "vp2", "common1";
ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
power-domains = <&k3_pds 67 TI_SCI_PD_EXCLUSIVE>;
clocks = <&k3_clks 67 1>,
<&k3_clks 216 1>,
<&k3_clks 67 2>;
"ovr1", "ovr2", "vp1", "vp2", "common1";
power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
clocks = <&k3_clks 186 6>,
<&vp1_clock>,
<&k3_clks 186 2>;
clock-names = "fck", "vp1", "vp2";
interrupts = <GIC_SPI 166 IRQ_TYPE_EDGE_RISING>;
interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
oldi-transmitters {
#address-cells = <1>;
#size-cells = <0>;
oldi0: oldi@0 {
reg = <0>;
clocks = <&k3_clks 186 0>;
clock-names = "serial";
ti,companion-oldi = <&oldi1>;
ti,oldi-io-ctrl = <&dss_oldi_io_ctrl>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
oldi0_in: endpoint {
remote-endpoint = <&dpi0_out0>;
};
};
port@1 {
reg = <1>;
oldi0_out: endpoint {
remote-endpoint = <&panel_in0>;
};
};
};
};
oldi1: oldi@1 {
reg = <1>;
clocks = <&k3_clks 186 0>;
clock-names = "serial";
ti,secondary-oldi;
ti,companion-oldi = <&oldi0>;
ti,oldi-io-ctrl = <&dss_oldi_io_ctrl>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
oldi1_in: endpoint {
remote-endpoint = <&dpi0_out1>;
};
};
port@1 {
reg = <1>;
oldi1_out: endpoint {
remote-endpoint = <&panel_in1>;
};
};
};
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
oldi_out0: endpoint {
remote-endpoint = <&lcd_in0>;
};
reg = <0>;
dpi0_out0: endpoint@0 {
reg = <0>;
remote-endpoint = <&oldi0_in>;
};
dpi0_out1: endpoint@1 {
reg = <1>;
remote-endpoint = <&oldi1_in>;
};
};
port@1 {
reg = <1>;
dpi1_out: endpoint {
remote-endpoint = <&hdmi_bridge>;
};
};
};
};
};

View file

@ -43,6 +43,7 @@ properties:
- allwinner,sun55i-a523-mali
- mediatek,mt8188-mali
- mediatek,mt8192-mali
- mediatek,mt8370-mali
- const: arm,mali-valhall-jm # Mali Valhall GPU model/revision is fully discoverable
reg:
@ -226,7 +227,9 @@ allOf:
properties:
compatible:
contains:
const: mediatek,mt8186-mali
enum:
- mediatek,mt8186-mali
- mediatek,mt8370-mali
then:
properties:
power-domains:

View file

@ -47,6 +47,7 @@ properties:
- hisilicon,hi6220-mali
- mediatek,mt7623-mali
- rockchip,rk3328-mali
- rockchip,rk3528-mali
- const: arm,mali-450
# "arm,mali-300"
@ -148,6 +149,7 @@ allOf:
- rockchip,rk3188-mali
- rockchip,rk3228-mali
- rockchip,rk3328-mali
- rockchip,rk3528-mali
then:
required:
- resets

View file

@ -0,0 +1,318 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/interrupt-controller/fsl,imx8qxp-dc-intc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX8qxp Display Controller interrupt controller
description: |
The Display Controller has a built-in interrupt controller with the following
features for all relevant HW events:
* Enable bit (mask)
* Status bit (set by an HW event)
* Preset bit (can be used by SW to set status)
* Clear bit (used by SW to reset the status)
Each interrupt can be connected as IRQ (maskable) and/or NMI (non-maskable).
Alternatively the un-masked trigger signals for all HW events are provided,
allowing it to use a global interrupt controller instead.
Each interrupt can be protected against SW running in user mode. In that case,
only privileged AHB access can control the interrupt status.
maintainers:
- Liu Ying <victor.liu@nxp.com>
properties:
compatible:
const: fsl,imx8qxp-dc-intc
reg:
maxItems: 1
clocks:
maxItems: 1
interrupt-controller: true
"#interrupt-cells":
const: 1
interrupts:
items:
- description: store9 shadow load interrupt(blit engine)
- description: store9 frame complete interrupt(blit engine)
- description: store9 sequence complete interrupt(blit engine)
- description:
extdst0 shadow load interrupt
(display controller, content stream 0)
- description:
extdst0 frame complete interrupt
(display controller, content stream 0)
- description:
extdst0 sequence complete interrupt
(display controller, content stream 0)
- description:
extdst4 shadow load interrupt
(display controller, safety stream 0)
- description:
extdst4 frame complete interrupt
(display controller, safety stream 0)
- description:
extdst4 sequence complete interrupt
(display controller, safety stream 0)
- description:
extdst1 shadow load interrupt
(display controller, content stream 1)
- description:
extdst1 frame complete interrupt
(display controller, content stream 1)
- description:
extdst1 sequence complete interrupt
(display controller, content stream 1)
- description:
extdst5 shadow load interrupt
(display controller, safety stream 1)
- description:
extdst5 frame complete interrupt
(display controller, safety stream 1)
- description:
extdst5 sequence complete interrupt
(display controller, safety stream 1)
- description:
disengcfg0 shadow load interrupt
(display controller, display stream 0)
- description:
disengcfg0 frame complete interrupt
(display controller, display stream 0)
- description:
disengcfg0 sequence complete interrupt
(display controller, display stream 0)
- description:
framegen0 programmable interrupt0
(display controller, display stream 0)
- description:
framegen0 programmable interrupt1
(display controller, display stream 0)
- description:
framegen0 programmable interrupt2
(display controller, display stream 0)
- description:
framegen0 programmable interrupt3
(display controller, display stream 0)
- description:
signature0 shadow load interrupt
(display controller, display stream 0)
- description:
signature0 measurement valid interrupt
(display controller, display stream 0)
- description:
signature0 error condition interrupt
(display controller, display stream 0)
- description:
disengcfg1 shadow load interrupt
(display controller, display stream 1)
- description:
disengcfg1 frame complete interrupt
(display controller, display stream 1)
- description:
disengcfg1 sequence complete interrupt
(display controller, display stream 1)
- description:
framegen1 programmable interrupt0
(display controller, display stream 1)
- description:
framegen1 programmable interrupt1
(display controller, display stream 1)
- description:
framegen1 programmable interrupt2
(display controller, display stream 1)
- description:
framegen1 programmable interrupt3
(display controller, display stream 1)
- description:
signature1 shadow load interrupt
(display controller, display stream 1)
- description:
signature1 measurement valid interrupt
(display controller, display stream 1)
- description:
signature1 error condition interrupt
(display controller, display stream 1)
- description: reserved
- description:
command sequencer error condition interrupt(command sequencer)
- description:
common control software interrupt0(common control)
- description:
common control software interrupt1(common control)
- description:
common control software interrupt2(common control)
- description:
common control software interrupt3(common control)
- description:
framegen0 synchronization status activated interrupt
(display controller, safety stream 0)
- description:
framegen0 synchronization status deactivated interrupt
(display controller, safety stream 0)
- description:
framegen0 synchronization status activated interrupt
(display controller, content stream 0)
- description:
framegen0 synchronization status deactivated interrupt
(display controller, content stream 0)
- description:
framegen1 synchronization status activated interrupt
(display controller, safety stream 1)
- description:
framegen1 synchronization status deactivated interrupt
(display controller, safety stream 1)
- description:
framegen1 synchronization status activated interrupt
(display controller, content stream 1)
- description:
framegen1 synchronization status deactivated interrupt
(display controller, content stream 1)
minItems: 49
interrupt-names:
items:
- const: store9_shdload
- const: store9_framecomplete
- const: store9_seqcomplete
- const: extdst0_shdload
- const: extdst0_framecomplete
- const: extdst0_seqcomplete
- const: extdst4_shdload
- const: extdst4_framecomplete
- const: extdst4_seqcomplete
- const: extdst1_shdload
- const: extdst1_framecomplete
- const: extdst1_seqcomplete
- const: extdst5_shdload
- const: extdst5_framecomplete
- const: extdst5_seqcomplete
- const: disengcfg_shdload0
- const: disengcfg_framecomplete0
- const: disengcfg_seqcomplete0
- const: framegen0_int0
- const: framegen0_int1
- const: framegen0_int2
- const: framegen0_int3
- const: sig0_shdload
- const: sig0_valid
- const: sig0_error
- const: disengcfg_shdload1
- const: disengcfg_framecomplete1
- const: disengcfg_seqcomplete1
- const: framegen1_int0
- const: framegen1_int1
- const: framegen1_int2
- const: framegen1_int3
- const: sig1_shdload
- const: sig1_valid
- const: sig1_error
- const: reserved
- const: cmdseq_error
- const: comctrl_sw0
- const: comctrl_sw1
- const: comctrl_sw2
- const: comctrl_sw3
- const: framegen0_primsync_on
- const: framegen0_primsync_off
- const: framegen0_secsync_on
- const: framegen0_secsync_off
- const: framegen1_primsync_on
- const: framegen1_primsync_off
- const: framegen1_secsync_on
- const: framegen1_secsync_off
minItems: 49
required:
- compatible
- reg
- clocks
- interrupt-controller
- "#interrupt-cells"
- interrupts
- interrupt-names
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/imx8-lpcg.h>
interrupt-controller@56180040 {
compatible = "fsl,imx8qxp-dc-intc";
reg = <0x56180040 0x60>;
clocks = <&dc0_lpcg IMX_LPCG_CLK_5>;
interrupt-controller;
interrupt-parent = <&dc0_irqsteer>;
#interrupt-cells = <1>;
interrupts = <448>, <449>, <450>, <64>,
<65>, <66>, <67>, <68>,
<69>, <70>, <193>, <194>,
<195>, <196>, <197>, <72>,
<73>, <74>, <75>, <76>,
<77>, <78>, <79>, <80>,
<81>, <199>, <200>, <201>,
<202>, <203>, <204>, <205>,
<206>, <207>, <208>, <5>,
<0>, <1>, <2>, <3>,
<4>, <82>, <83>, <84>,
<85>, <209>, <210>, <211>,
<212>;
interrupt-names = "store9_shdload",
"store9_framecomplete",
"store9_seqcomplete",
"extdst0_shdload",
"extdst0_framecomplete",
"extdst0_seqcomplete",
"extdst4_shdload",
"extdst4_framecomplete",
"extdst4_seqcomplete",
"extdst1_shdload",
"extdst1_framecomplete",
"extdst1_seqcomplete",
"extdst5_shdload",
"extdst5_framecomplete",
"extdst5_seqcomplete",
"disengcfg_shdload0",
"disengcfg_framecomplete0",
"disengcfg_seqcomplete0",
"framegen0_int0",
"framegen0_int1",
"framegen0_int2",
"framegen0_int3",
"sig0_shdload",
"sig0_valid",
"sig0_error",
"disengcfg_shdload1",
"disengcfg_framecomplete1",
"disengcfg_seqcomplete1",
"framegen1_int0",
"framegen1_int1",
"framegen1_int2",
"framegen1_int3",
"sig1_shdload",
"sig1_valid",
"sig1_error",
"reserved",
"cmdseq_error",
"comctrl_sw0",
"comctrl_sw1",
"comctrl_sw2",
"comctrl_sw3",
"framegen0_primsync_on",
"framegen0_primsync_off",
"framegen0_secsync_on",
"framegen0_secsync_off",
"framegen1_primsync_on",
"framegen1_primsync_off",
"framegen1_secsync_on",
"framegen1_secsync_off";
};

View file

@ -23,7 +23,7 @@ properties:
const: operating-points-v2-adreno
patternProperties:
'^opp-[0-9]+$':
'^opp(-[0-9]+){1,2}$':
type: object
additionalProperties: false

View file

@ -405,6 +405,8 @@ patternProperties:
description: Diodes, Inc.
"^dioo,.*":
description: Dioo Microcircuit Co., Ltd
"^djn,.*":
description: Shenzhen DJN Optronics Technology Co., Ltd
"^dlc,.*":
description: DLC Display Co., Ltd.
"^dlg,.*":
@ -679,6 +681,8 @@ patternProperties:
description: Huawei Technologies Co., Ltd.
"^hugsun,.*":
description: Shenzhen Hugsun Technology Co. Ltd.
"^huiling,.*":
description: Shenzhen Huiling Information Technology Co., Ltd.
"^hwacom,.*":
description: HwaCom Systems Inc.
"^hxt,.*":

View file

@ -85,3 +85,21 @@ UMR
GPU debugging and diagnostics tool. Please see the umr
`documentation <https://umr.readthedocs.io/en/main/>`_ for more information
about its capabilities.
Debugging backlight brightness
==============================
Default backlight brightness is intended to be set via the policy advertised
by the firmware. Firmware will often provide different defaults for AC or DC.
Furthermore, some userspace software will save backlight brightness during
the previous boot and attempt to restore it.
Some firmware also has support for a feature called "Custom Backlight Curves"
where an input value for brightness is mapped along a linearly interpolated
curve of brightness values that better match display characteristics.
In the event of problems happening with backlight, there is a trace event
that can be enabled at bootup to log every brightness change request.
This can help isolate where the problem is. To enable the trace event add
the following to the kernel command line:
tp_printk trace_event=amdgpu_dm:amdgpu_dm_brightness:mod:amdgpu trace_buf_size=1M

View file

@ -446,6 +446,23 @@ telemetry information (devcoredump, syslog). This is useful because the first
hang is usually the most critical one which can result in consequential hangs or
complete wedging.
Task information
----------------
The information about which application (if any) was involved in the device
wedging is useful for userspace if they want to notify the user about what
happened (e.g. the compositor display a message to the user "The <task name>
caused a graphical error and the system recovered") or to implement policies
(e.g. the daemon may "ban" an task that keeps resetting the device). If the task
information is available, the uevent will display as ``PID=<pid>`` and
``TASK=<task name>``. Otherwise, ``PID`` and ``TASK`` will not appear in the
event string.
The reliability of this information is driver and hardware specific, and should
be taken with a caution regarding it's precision. To have a big picture of what
really happened, the devcoredump file provides much more detailed information
about the device state and about the event.
Consumer prerequisites
----------------------
@ -693,3 +710,22 @@ dma-buf interoperability
Please see Documentation/userspace-api/dma-buf-alloc-exchange.rst for
information on how dma-buf is integrated and exposed within DRM.
Trace events
============
See Documentation/trace/tracepoints.rst for information about using
Linux Kernel Tracepoints.
In the DRM subsystem, some events are considered stable uAPI to avoid
breaking tools (e.g.: GPUVis, umr) relying on them. Stable means that fields
cannot be removed, nor their formatting updated. Adding new fields is
possible, under the normal uAPI requirements.
Stable uAPI events
------------------
From ``drivers/gpu/drm/scheduler/gpu_scheduler_trace.h``
.. kernel-doc:: drivers/gpu/drm/scheduler/gpu_scheduler_trace.h
:doc: uAPI trace events

View file

@ -112,10 +112,10 @@ panel self refresh.
Atomic Plane Helpers
--------------------
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_atomic_plane.c
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_plane.c
:doc: atomic plane helpers
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_atomic_plane.c
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_plane.c
:internal:
Asynchronous Page Flip
@ -204,6 +204,12 @@ DMC Firmware Support
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dmc.c
:internal:
DMC Flip Queue
--------------------
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_flipq.c
:doc: DMC Flip Queue
DMC wakelock support
--------------------

View file

@ -0,0 +1,61 @@
.. SPDX-License-Identifier: GPL-2.0
==================================
Device Initialization (devinit)
==================================
The devinit process is complex and subject to change. This document provides a high-level
overview using the Ampere GPU family as an example. The goal is to provide a conceptual
overview of the process to aid in understanding the corresponding kernel code.
Device initialization (devinit) is a crucial sequence of register read/write operations
that occur after a GPU reset. The devinit sequence is essential for properly configuring
the GPU hardware before it can be used.
The devinit engine is an interpreter program that typically runs on the PMU (Power Management
Unit) microcontroller of the GPU. This interpreter executes a "script" of initialization
commands. The devinit engine itself is part of the VBIOS ROM in the same ROM image as the
FWSEC (Firmware Security) image (see fwsec.rst and vbios.rst) and it runs before the
nova-core driver is even loaded. On an Ampere GPU, the devinit ucode is separate from the
FWSEC ucode. It is launched by FWSEC, which runs on the GSP in 'heavy-secure' mode, while
devinit runs on the PMU in 'light-secure' mode.
Key Functions of devinit
------------------------
devinit performs several critical tasks:
1. Programming VRAM memory controller timings
2. Power sequencing
3. Clock and PLL (Phase-Locked Loop) configuration
4. Thermal management
Low-level Firmware Initialization Flow
--------------------------------------
Upon reset, several microcontrollers on the GPU (such as PMU, SEC2, GSP, etc.) run GPU
firmware (gfw) code to set up the GPU and its core parameters. Most of the GPU is
considered unusable until this initialization process completes.
These low-level GPU firmware components are typically:
1. Located in the VBIOS ROM in the same ROM partition (see vbios.rst and fwsec.rst).
2. Executed in sequence on different microcontrollers:
- The devinit engine typically but not necessarily runs on the PMU.
- On an Ampere GPU, the FWSEC typically runs on the GSP (GPU System Processor) in
heavy-secure mode.
Before the driver can proceed with further initialization, it must wait for a signal
indicating that core initialization is complete (known as GFW_BOOT). This signal is
asserted by the FWSEC running on the GSP in heavy-secure mode.
Runtime Considerations
----------------------
It's important to note that the devinit sequence also needs to run during suspend/resume
operations at runtime, not just during initial boot, as it is critical to power management.
Security and Access Control
---------------------------
The initialization process involves careful privilege management. For example, before
accessing certain completion status registers, the driver must check privilege level
masks. Some registers are only accessible after secure firmware (FWSEC) lowers the
privilege level to allow CPU (LS/low-secure) access. This is the case, for example,
when receiving the GFW_BOOT signal.

View file

@ -0,0 +1,158 @@
.. SPDX-License-Identifier: GPL-2.0
==============================
Falcon (FAst Logic Controller)
==============================
The following sections describe the Falcon core and the ucode running on it.
The descriptions are based on the Ampere GPU or earlier designs; however, they
should mostly apply to future designs as well, but everything is subject to
change. The overview provided here is mainly tailored towards understanding the
interactions of nova-core driver with the Falcon.
NVIDIA GPUs embed small RISC-like microcontrollers called Falcon cores, which
handle secure firmware tasks, initialization, and power management. Modern
NVIDIA GPUs may have multiple such Falcon instances (e.g., GSP (the GPU system
processor) and SEC2 (the security engine)) and also may integrate a RISC-V core.
This core is capable of running both RISC-V and Falcon code.
The code running on the Falcon cores is also called 'ucode', and will be
referred to as such in the following sections.
Falcons have separate instruction and data memories (IMEM/DMEM) and provide a
small DMA engine (via the FBIF - "Frame Buffer Interface") to load code from
system memory. The nova-core driver must reset and configure the Falcon, load
its firmware via DMA, and start its CPU.
Falcon security levels
======================
Falcons can run in Non-secure (NS), Light Secure (LS), or Heavy Secure (HS)
modes.
Heavy Secured (HS) also known as Privilege Level 3 (PL3)
--------------------------------------------------------
HS ucode is the most trusted code and has access to pretty much everything on
the chip. The HS binary includes a signature in it which is verified at boot.
This signature verification is done by the hardware itself, thus establishing a
root of trust. For example, the FWSEC-FRTS command (see fwsec.rst) runs on the
GSP in HS mode. FRTS, which involves setting up and loading content into the WPR
(Write Protect Region), has to be done by the HS ucode and cannot be done by the
host CPU or LS ucode.
Light Secured (LS or PL2) and Non Secured (NS or PL0)
-----------------------------------------------------
These modes are less secure than HS. Like HS, the LS or NS ucode binary also
typically includes a signature in it. To load firmware in LS or NS mode onto a
Falcon, another Falcon needs to be running in HS mode, which also establishes the
root of trust. For example, in the case of an Ampere GPU, the CPU runs the "Booter"
ucode in HS mode on the SEC2 Falcon, which then authenticates and runs the
run-time GSP binary (GSP-RM) in LS mode on the GSP Falcon. Similarly, as an
example, after reset on an Ampere, FWSEC runs on the GSP which then loads the
devinit engine onto the PMU in LS mode.
Root of trust establishment
---------------------------
To establish a root of trust, the code running on a Falcon must be immutable and
hardwired into a read-only memory (ROM). This follows industry norms for
verification of firmware. This code is called the Boot ROM (BROM). The nova-core
driver on the CPU communicates with Falcon's Boot ROM through various Falcon
registers prefixed with "BROM" (see regs.rs).
After nova-core driver reads the necessary ucode from VBIOS, it programs the
BROM and DMA registers to trigger the Falcon to load the HS ucode from the system
memory into the Falcon's IMEM/DMEM. Once the HS ucode is loaded, it is verified
by the Falcon's Boot ROM.
Once the verified HS code is running on a Falcon, it can verify and load other
LS/NS ucode binaries onto other Falcons and start them. The process of signature
verification is the same as HS; just in this case, the hardware (BROM) doesn't
compute the signature, but the HS ucode does.
The root of trust is therefore established as follows:
Hardware (Boot ROM running on the Falcon) -> HS ucode -> LS/NS ucode.
On an Ampere GPU, for example, the boot verification flow is:
Hardware (Boot ROM running on the SEC2) ->
HS ucode (Booter running on the SEC2) ->
LS ucode (GSP-RM running on the GSP)
.. note::
While the CPU can load HS ucode onto a Falcon microcontroller and have it
verified by the hardware and run, the CPU itself typically does not load
LS or NS ucode and run it. Loading of LS or NS ucode is done mainly by the
HS ucode. For example, on an Ampere GPU, after the Booter ucode runs on the
SEC2 in HS mode and loads the GSP-RM binary onto the GSP, it needs to run
the "SEC2-RTOS" ucode at runtime. This presents a problem: there is no
component to load the SEC2-RTOS ucode onto the SEC2. The CPU cannot load
LS code, and GSP-RM must run in LS mode. To overcome this, the GSP is
temporarily made to run HS ucode (which is itself loaded by the CPU via
the nova-core driver using a "GSP-provided sequencer") which then loads
the SEC2-RTOS ucode onto the SEC2 in LS mode. The GSP then resumes
running its own GSP-RM LS ucode.
Falcon memory subsystem and DMA engine
======================================
Falcons have separate instruction and data memories (IMEM/DMEM)
and contains a small DMA engine called FBDMA (Framebuffer DMA) which does
DMA transfers to/from the IMEM/DMEM memory inside the Falcon via the FBIF
(Framebuffer Interface), to external memory.
DMA transfers are possible from the Falcon's memory to both the system memory
and the framebuffer memory (VRAM).
To perform a DMA via the FBDMA, the FBIF is configured to decide how the memory
is accessed (also known as aperture type). In the nova-core driver, this is
determined by the `FalconFbifTarget` enum.
The IO-PMP block (Input/Output Physical Memory Protection) unit in the Falcon
controls access by the FBDMA to the external memory.
Conceptual diagram (not exact) of the Falcon and its memory subsystem is as follows::
External Memory (Framebuffer / System DRAM)
^ |
| |
| v
+-----------------------------------------------------+
| | |
| +---------------+ | |
| | FBIF |-------+ | FALCON
| | (FrameBuffer | Memory Interface | PROCESSOR
| | InterFace) | |
| | Apertures | |
| | Configures | |
| | mem access | |
| +-------^-------+ |
| | |
| | FBDMA uses configured FBIF apertures |
| | to access External Memory
| |
| +-------v--------+ +---------------+
| | FBDMA | cfg | RISC |
| | (FrameBuffer |<---->| CORE |----->. Direct Core Access
| | DMA Engine) | | | |
| | - Master dev. | | (can run both | |
| +-------^--------+ | Falcon and | |
| | cfg--->| RISC-V code) | |
| | / | | |
| | | +---------------+ | +------------+
| | | | | BROM |
| | | <--->| (Boot ROM) |
| | / | +------------+
| | v |
| +---------------+ |
| | IO-PMP | Controls access by FBDMA |
| | (IO Physical | and other IO Masters |
| | Memory Protect) |
| +-------^-------+ |
| | |
| | Protected Access Path for FBDMA |
| v |
| +---------------------------------------+ |
| | Memory | |
| | +---------------+ +------------+ | |
| | | IMEM | | DMEM | |<-----+
| | | (Instruction | | (Data | |
| | | Memory) | | Memory) | |
| | +---------------+ +------------+ |
| +---------------------------------------+
+-----------------------------------------------------+

View file

@ -0,0 +1,181 @@
.. SPDX-License-Identifier: (GPL-2.0+ OR MIT)
=========================
FWSEC (Firmware Security)
=========================
This document briefly/conceptually describes the FWSEC (Firmware Security) image
and its role in the GPU boot sequence. As such, this information is subject to
change in the future and is only current as of the Ampere GPU family. However,
hopefully the concepts described will be useful for understanding the kernel code
that deals with it. All the information is derived from publicly available
sources such as public drivers and documentation.
The role of FWSEC is to provide a secure boot process. It runs in
'Heavy-secure' mode, and performs firmware verification after a GPU reset
before loading various ucode images onto other microcontrollers on the GPU,
such as the PMU and GSP.
FWSEC itself is an application stored in the VBIOS ROM in the FWSEC partition of
ROM (see vbios.rst for more details). It contains different commands like FRTS
(Firmware Runtime Services) and SB (Secure Booting other microcontrollers after
reset and loading them with other non-FWSEC ucode). The kernel driver only needs
to perform FRTS, since Secure Boot (SB) has already completed by the time the driver
is loaded.
The FRTS command carves out the WPR2 region (Write protected region) which contains
data required for power management. Once setup, only HS mode ucode can access it
(see falcon.rst for privilege levels).
The FWSEC image is located in the VBIOS ROM in the partition of the ROM that contains
various ucode images (also known as applications) -- one of them being FWSEC. For how
it is extracted, see vbios.rst and the vbios.rs source code.
The Falcon data for each ucode images (including the FWSEC image) is a combination
of headers, data sections (DMEM) and instruction code sections (IMEM). All these
ucode images are stored in the same ROM partition and the PMU table is used to look
up the application to load it based on its application ID (see vbios.rs).
For the nova-core driver, the FWSEC contains an 'application interface' called
DMEMMAPPER. This interface is used to execute the 'FWSEC-FRTS' command, among others.
For Ampere, FWSEC is running on the GSP in Heavy-secure mode and runs FRTS.
FWSEC Memory Layout
-------------------
The memory layout of the FWSEC image is as follows::
+---------------------------------------------------------------+
| FWSEC ROM image (type 0xE0) |
| |
| +---------------------------------+ |
| | PMU Falcon Ucode Table | |
| | (PmuLookupTable) | |
| | +-------------------------+ | |
| | | Table Header | | |
| | | - version: 0x01 | | |
| | | - header_size: 6 | | |
| | | - entry_size: 6 | | |
| | | - entry_count: N | | |
| | | - desc_version:3(unused)| | |
| | +-------------------------+ | |
| | ... | |
| | +-------------------------+ | |
| | | Entry for FWSEC (0x85) | | |
| | | (PmuLookupTableEntry) | | |
| | | - app_id: 0x85 (FWSEC) |----|----+ |
| | | - target_id: 0x01 (PMU) | | | |
| | | - data: offset ---------|----|----|---+ look up FWSEC |
| | +-------------------------+ | | | |
| +---------------------------------+ | | |
| | | |
| | | |
| +---------------------------------+ | | |
| | FWSEC Ucode Component |<---+ | |
| | (aka Falcon data) | | |
| | +-------------------------+ | | |
| | | FalconUCodeDescV3 |<---|--------+ |
| | | - hdr | | |
| | | - stored_size | | |
| | | - pkc_data_offset | | |
| | | - interface_offset -----|----|----------------+ |
| | | - imem_phys_base | | | |
| | | - imem_load_size | | | |
| | | - imem_virt_base | | | |
| | | - dmem_phys_base | | | |
| | | - dmem_load_size | | | |
| | | - engine_id_mask | | | |
| | | - ucode_id | | | |
| | | - signature_count | | look up sig | |
| | | - signature_versions --------------+ | |
| | +-------------------------+ | | | |
| | (no gap) | | | |
| | +-------------------------+ | | | |
| | | Signatures Section |<---|-----+ | |
| | | (384 bytes per sig) | | | |
| | | - RSA-3K Signature 1 | | | |
| | | - RSA-3K Signature 2 | | | |
| | | ... | | | |
| | +-------------------------+ | | |
| | | | |
| | +-------------------------+ | | |
| | | IMEM Section (Code) | | | |
| | | | | | |
| | | Contains instruction | | | |
| | | code etc. | | | |
| | +-------------------------+ | | |
| | | | |
| | +-------------------------+ | | |
| | | DMEM Section (Data) | | | |
| | | | | | |
| | | +---------------------+ | | | |
| | | | Application | |<---|----------------+ |
| | | | Interface Table | | | |
| | | | (FalconAppifHdrV1) | | | |
| | | | Header: | | | |
| | | | - version: 0x01 | | | |
| | | | - header_size: 4 | | | |
| | | | - entry_size: 8 | | | |
| | | | - entry_count: N | | | |
| | | | | | | |
| | | | Entries: | | | |
| | | | +-----------------+ | | | |
| | | | | DEVINIT (ID 1) | | | | |
| | | | | - id: 0x01 | | | | |
| | | | | - dmemOffset X -|-|-|----+ |
| | | | +-----------------+ | | | |
| | | | +-----------------+ | | | |
| | | | | DMEMMAPPER(ID 4)| | | | |
| | | | | - id: 0x04 | | | | Used only for DevInit |
| | | | | (NVFW_FALCON_ | | | | application (not FWSEC) |
| | | | | APPIF_ID_DMEMMAPPER) | |
| | | | | - dmemOffset Y -|-|-|----|-----+ |
| | | | +-----------------+ | | | | |
| | | +---------------------+ | | | |
| | | | | | |
| | | +---------------------+ | | | |
| | | | DEVINIT Engine |<|----+ | Used by FWSEC |
| | | | Interface | | | | app. |
| | | +---------------------+ | | | |
| | | | | | |
| | | +---------------------+ | | | |
| | | | DMEM Mapper (ID 4) |<|----+-----+ |
| | | | (FalconAppifDmemmapperV3) | |
| | | | - signature: "DMAP" | | | |
| | | | - version: 0x0003 | | | |
| | | | - Size: 64 bytes | | | |
| | | | - cmd_in_buffer_off | |----|------------+ |
| | | | - cmd_in_buffer_size| | | | |
| | | | - cmd_out_buffer_off| |----|------------|-----+ |
| | | | - cmd_out_buffer_sz | | | | | |
| | | | - init_cmd | | | | | |
| | | | - features | | | | | |
| | | | - cmd_mask0/1 | | | | | |
| | | +---------------------+ | | | | |
| | | | | | | |
| | | +---------------------+ | | | | |
| | | | Command Input Buffer|<|----|------------+ | |
| | | | - Command data | | | | |
| | | | - Arguments | | | | |
| | | +---------------------+ | | | |
| | | | | | |
| | | +---------------------+ | | | |
| | | | Command Output |<|----|------------------+ |
| | | | Buffer | | | |
| | | | - Results | | | |
| | | | - Status | | | |
| | | +---------------------+ | | |
| | +-------------------------+ | |
| +---------------------------------+ |
| |
+---------------------------------------------------------------+
.. note::
This is using an GA-102 Ampere GPU as an example and could vary for future GPUs.
.. note::
The FWSEC image also plays a role in memory scrubbing (ECC initialization) and VPR
(Video Protected Region) initialization as well. Before the nova-core driver is even
loaded, the FWSEC image is running on the GSP in heavy-secure mode. After the devinit
sequence completes, it does VRAM memory scrubbing (ECC initialization). On consumer
GPUs, it scrubs only part of memory and then initiates 'async scrubbing'. Before this
async scrubbing completes, the unscrubbed VRAM cannot be used for allocation (thus DRM
memory allocators need to wait for this scrubbing to complete).

View file

@ -14,14 +14,17 @@ Tasks may have the following fields:
- ``Contact``: The person that can be contacted for further information about
the task.
A task might have `[ABCD]` code after its name. This code can be used to grep
into the code for `TODO` entries related to it.
Enablement (Rust)
=================
Tasks that are not directly related to nova-core, but are preconditions in terms
of required APIs.
FromPrimitive API
-----------------
FromPrimitive API [FPRI]
------------------------
Sometimes the need arises to convert a number to a value of an enum or a
structure.
@ -41,8 +44,27 @@ automatically generates the corresponding mappings between a value and a number.
| Complexity: Beginner
| Link: https://docs.rs/num/latest/num/trait.FromPrimitive.html
Generic register abstraction
----------------------------
Conversion from byte slices for types implementing FromBytes [TRSM]
-------------------------------------------------------------------
We retrieve several structures from byte streams coming from the BIOS or loaded
firmware. At the moment converting the bytes slice into the proper type require
an inelegant `unsafe` operation; this will go away once `FromBytes` implements
a proper `from_bytes` method.
| Complexity: Beginner
CoherentAllocation improvements [COHA]
--------------------------------------
`CoherentAllocation` needs a safe way to write into the allocation, and to
obtain slices within the allocation.
| Complexity: Beginner
| Contact: Abdiel Janulgue
Generic register abstraction [REGA]
-----------------------------------
Work out how register constants and structures can be automatically generated
through generalized macros.
@ -102,16 +124,40 @@ Usage:
let boot0 = Boot0::read(&bar);
pr_info!("Revision: {}\n", boot0.revision());
Note: a work-in-progress implementation currently resides in
A work-in-progress implementation currently resides in
`drivers/gpu/nova-core/regs/macros.rs` and is used in nova-core. It would be
nice to improve it (possibly using proc macros) and move it to the `kernel`
crate so it can be used by other components as well.
Features desired before this happens:
* Relative register with build-time base address validation,
* Arrays of registers with build-time index validation,
* Make I/O optional I/O (for field values that are not registers),
* Support other sizes than `u32`,
* Allow visibility control for registers and individual fields,
* Use Rust slice syntax to express fields ranges.
| Complexity: Advanced
| Contact: Alexandre Courbot
Delay / Sleep abstractions
--------------------------
Numerical operations [NUMM]
---------------------------
Nova uses integer operations that are not part of the standard library (or not
implemented in an optimized way for the kernel). These include:
- Aligning up and down to a power of two,
- The "Find Last Set Bit" (`fls` function of the C part of the kernel)
operation.
A `num` core kernel module is being designed to provide these operations.
| Complexity: Intermediate
| Contact: Alexandre Courbot
Delay / Sleep abstractions [DLAY]
---------------------------------
Rust abstractions for the kernel's delay() and sleep() functions.
@ -159,18 +205,6 @@ mailing list yet.
| Complexity: Intermediate
| Contact: Abdiel Janulgue
ELF utils
---------
Rust implementation of ELF header representation to retrieve section header
tables, names, and data from an ELF-formatted images.
There is preceding work from Abdiel Janulgue, which hasn't made it to the
mailing list yet.
| Complexity: Beginner
| Contact: Abdiel Janulgue
PCI MISC APIs
-------------
@ -179,12 +213,11 @@ capability, MSI API abstractions.
| Complexity: Beginner
Auxiliary bus abstractions
--------------------------
XArray bindings [XARR]
----------------------
Rust abstraction for the auxiliary bus APIs.
This is needed to connect nova-core to the nova-drm driver.
We need bindings for `xa_alloc`/`xa_alloc_cyclic` in order to generate the
auxiliary device IDs.
| Complexity: Intermediate
@ -216,15 +249,6 @@ Build the radix3 page table to map the firmware.
| Complexity: Intermediate
| Contact: Abdiel Janulgue
vBIOS support
-------------
Parse the vBIOS and probe the structures required for driver initialization.
| Contact: Dave Airlie
| Reference: Vec extensions
| Complexity: Intermediate
Initial Devinit support
-----------------------
@ -234,23 +258,6 @@ configuration.
| Contact: Dave Airlie
| Complexity: Beginner
Boot Falcon controller
----------------------
Infrastructure to load and execute falcon (sec2) firmware images; handle the
GSP falcon processor and fwsec loading.
| Complexity: Advanced
| Contact: Dave Airlie
GPU Timer support
-----------------
Support for the GPU's internal timer peripheral.
| Complexity: Beginner
| Contact: Dave Airlie
MMU / PT management
-------------------

View file

@ -0,0 +1,181 @@
.. SPDX-License-Identifier: (GPL-2.0+ OR MIT)
==========
VBIOS
==========
This document describes the layout of the VBIOS image which is a series of concatenated
images in the ROM of the GPU. The VBIOS is mirrored onto the BAR 0 space and is read
by both Boot ROM firmware (also known as IFR or init-from-rom firmware) on the GPU to
bootstrap various microcontrollers (PMU, SEC, GSP) with critical initialization before
the driver loads, as well as by the nova-core driver in the kernel to boot the GSP.
The format of the images in the ROM follow the "BIOS Specification" part of the
PCI specification, with Nvidia-specific extensions. The ROM images of type FwSec
are the ones that contain Falcon ucode and what we are mainly looking for.
As an example, the following are the different image types that can be found in the
VBIOS of an Ampere GA102 GPU which is supported by the nova-core driver.
- PciAt Image (Type 0x00) - This is the standard PCI BIOS image, whose name
likely comes from the "IBM PC/AT" architecture.
- EFI Image (Type 0x03) - This is the EFI BIOS image. It contains the UEFI GOP
driver that is used to display UEFI graphics output.
- First FwSec Image (Type 0xE0) - The first FwSec image (Secure Firmware)
- Second FwSec Image (Type 0xE0) - The second FwSec image (Secure Firmware)
contains various microcodes (also known as an applications) that do a range
of different functions. The FWSEC ucode is run in heavy-secure mode and
typically runs directly on the GSP (it could be running on a different
designated processor in future generations but as of Ampere, it is the GSP).
This firmware then loads other firmware ucodes onto the PMU and SEC2
microcontrollers for gfw initialization after GPU reset and before the driver
loads (see devinit.rst). The DEVINIT ucode is itself another ucode that is
stored in this ROM partition.
Once located, the Falcon ucodes have "Application Interfaces" in their data
memory (DMEM). For FWSEC, the application interface we use for FWSEC is the
"DMEM mapper" interface which is configured to run the "FRTS" command. This
command carves out the WPR2 (Write-Protected Region) in VRAM. It then places
important power-management data, called 'FRTS', into this region. The WPR2
region is only accessible to heavy-secure ucode.
.. note::
It is not clear why FwSec has 2 different partitions in the ROM, but they both
are of type 0xE0 and can be identified as such. This could be subject to change
in future generations.
VBIOS ROM Layout
----------------
The VBIOS layout is roughly a series of concatenated images laid out as follows::
+----------------------------------------------------------------------------+
| VBIOS (Starting at ROM_OFFSET: 0x300000) |
+----------------------------------------------------------------------------+
| +-----------------------------------------------+ |
| | PciAt Image (Type 0x00) | |
| +-----------------------------------------------+ |
| | +-------------------+ | |
| | | ROM Header | | |
| | | (Signature 0xAA55)| | |
| | +-------------------+ | |
| | | rom header's pci_data_struct_offset | |
| | | points to the PCIR structure | |
| | V | |
| | +-------------------+ | |
| | | PCIR Structure | | |
| | | (Signature "PCIR")| | |
| | | last_image: 0x80 | | |
| | | image_len: size | | |
| | | in 512-byte units | | |
| | +-------------------+ | |
| | | | |
| | | NPDE immediately follows PCIR | |
| | V | |
| | +-------------------+ | |
| | | NPDE Structure | | |
| | | (Signature "NPDE")| | |
| | | last_image: 0x00 | | |
| | +-------------------+ | |
| | | |
| | +-------------------+ | |
| | | BIT Header | (Signature scanning | |
| | | (Signature "BIT") | provides the location | |
| | +-------------------+ of the BIT table) | |
| | | header is | |
| | | followed by a table of tokens | |
| | V one of which is for falcon data. | |
| | +-------------------+ | |
| | | BIT Tokens | | |
| | | ______________ | | |
| | | | Falcon Data | | | |
| | | | Token (0x70)|---+------------>------------+--+ |
| | | +-------------+ | falcon_data_ptr() | | |
| | +-------------------+ | V |
| +-----------------------------------------------+ | |
| (no gap between images) | |
| +-----------------------------------------------+ | |
| | EFI Image (Type 0x03) | | |
| +-----------------------------------------------+ | |
| | Contains the UEFI GOP driver (Graphics Output)| | |
| | +-------------------+ | | |
| | | ROM Header | | | |
| | +-------------------+ | | |
| | | PCIR Structure | | | |
| | +-------------------+ | | |
| | | NPDE Structure | | | |
| | +-------------------+ | | |
| | | Image data | | | |
| | +-------------------+ | | |
| +-----------------------------------------------+ | |
| (no gap between images) | |
| +-----------------------------------------------+ | |
| | First FwSec Image (Type 0xE0) | | |
| +-----------------------------------------------+ | |
| | +-------------------+ | | |
| | | ROM Header | | | |
| | +-------------------+ | | |
| | | PCIR Structure | | | |
| | +-------------------+ | | |
| | | NPDE Structure | | | |
| | +-------------------+ | | |
| | | Image data | | | |
| | +-------------------+ | | |
| +-----------------------------------------------+ | |
| (no gap between images) | |
| +-----------------------------------------------+ | |
| | Second FwSec Image (Type 0xE0) | | |
| +-----------------------------------------------+ | |
| | +-------------------+ | | |
| | | ROM Header | | | |
| | +-------------------+ | | |
| | | PCIR Structure | | | |
| | +-------------------+ | | |
| | | NPDE Structure | | | |
| | +-------------------+ | | |
| | | | |
| | +-------------------+ | | |
| | | PMU Lookup Table | <- falcon_data_offset <----+ |
| | | +-------------+ | pmu_lookup_table | |
| | | | Entry 0x85 | | | |
| | | | FWSEC_PROD | | | |
| | | +-------------+ | | |
| | +-------------------+ | |
| | | | |
| | | points to | |
| | V | |
| | +-------------------+ | |
| | | FalconUCodeDescV3 | <- falcon_ucode_offset | |
| | | (FWSEC Firmware) | fwsec_header() | |
| | +-------------------+ | |
| | | immediately followed by... | |
| | V | |
| | +----------------------------+ | |
| | | Signatures + FWSEC Ucode | | |
| | | fwsec_sigs(), fwsec_ucode()| | |
| | +----------------------------+ | |
| +-----------------------------------------------+ |
| |
+----------------------------------------------------------------------------+
.. note::
This diagram is created based on an GA-102 Ampere GPU as an example and could
vary for future or other GPUs.
.. note::
For more explanations of acronyms, see the detailed descriptions in `vbios.rs`.
Falcon data Lookup
------------------
A key part of the VBIOS extraction code (vbios.rs) is to find the location of the
Falcon data in the VBIOS which contains the PMU lookup table. This lookup table is
used to find the required Falcon ucode based on an application ID.
The location of the PMU lookup table is found by scanning the BIT (`BIOS Information Table`_)
tokens for a token with the id `BIT_TOKEN_ID_FALCON_DATA` (0x70) which indicates the
offset of the same from the start of the VBIOS image. Unfortunately, the offset
does not account for the EFI image located between the PciAt and FwSec images.
The `vbios.rs` code compensates for this with appropriate arithmetic.
.. _`BIOS Information Table`: https://download.nvidia.com/open-gpu-doc/BIOS-Information-Table/1/BIOS-Information-Table.html

View file

@ -28,3 +28,7 @@ vGPU manager VFIO driver and the nova-drm driver.
core/guidelines
core/todo
core/vbios
core/devinit
core/fwsec
core/falcon

View file

@ -73,15 +73,21 @@ Overview of baseline design
.. kernel-doc:: drivers/gpu/drm/drm_gpusvm.c
:doc: Locking
.. kernel-doc:: drivers/gpu/drm/drm_gpusvm.c
:doc: Migration
.. kernel-doc:: drivers/gpu/drm/drm_gpusvm.c
:doc: Partial Unmapping of Ranges
.. kernel-doc:: drivers/gpu/drm/drm_gpusvm.c
:doc: Examples
Overview of drm_pagemap design
==============================
.. kernel-doc:: drivers/gpu/drm/drm_pagemap.c
:doc: Overview
.. kernel-doc:: drivers/gpu/drm/drm_pagemap.c
:doc: Migration
Possible future design features
===============================

View file

@ -515,6 +515,21 @@ Contact: Douglas Anderson <dianders@chromium.org>
Level: Starter
Remove devm_drm_put_bridge()
----------------------------
Due to how the panel bridge handles the drm_bridge object lifetime, special
care must be taken to dispose of the drm_bridge object when the
panel_bridge is removed. This is currently managed using
devm_drm_put_bridge(), but that is an unsafe, temporary workaround. To fix
that, the DRM panel lifetime needs to be reworked. After the rework is
done, remove devm_drm_put_bridge() and the TODO in
drm_panel_bridge_remove().
Contact: Maxime Ripard <mripard@kernel.org>,
Luca Ceresoli <luca.ceresoli@bootlin.com>
Level: Intermediate
Core refactorings
=================

View file

@ -89,6 +89,17 @@ You can also run subtests if you do not want to run the entire test::
sudo ./build/tests/kms_flip --run-subtest basic-plain-flip --device "sys:/sys/devices/platform/vkms"
sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" ./build/tests/kms_flip --run-subtest basic-plain-flip
Testing With KUnit
==================
KUnit (Kernel unit testing framework) provides a common framework for unit tests
within the Linux kernel.
More information in ../dev-tools/kunit/index.rst .
To run the VKMS KUnit tests::
tools/testing/kunit/kunit.py run --kunitconfig=drivers/gpu/drm/vkms/tests
TODO
====
@ -122,8 +133,8 @@ There's lots of plane features we could add support for:
- Scaling.
- Additional buffer formats, especially YUV formats for video like NV12.
Low/high bpp RGB formats would also be interesting.
- Additional buffer formats. Low/high bpp RGB formats would be interesting
[Good to get started].
- Async updates (currently only possible on cursor plane using the legacy
cursor api).

View file

@ -2,9 +2,15 @@
.. _xe_configfs:
============
===========
Xe Configfs
============
===========
.. kernel-doc:: drivers/gpu/drm/xe/xe_configfs.c
:doc: Xe Configfs
Internal API
============
.. kernel-doc:: drivers/gpu/drm/xe/xe_configfs.c
:internal:

View file

@ -19,7 +19,10 @@ following heaps:
- The ``cma`` heap allocates physically contiguous, cacheable,
buffers. Only present if a CMA region is present. Such a region is
usually created either through the kernel commandline through the
`cma` parameter, a memory region Device-Tree node with the
`linux,cma-default` property set, or through the `CMA_SIZE_MBYTES` or
`CMA_SIZE_PERCENTAGE` Kconfig options. Depending on the platform, it
might be called ``reserved``, ``linux,cma``, or ``default-pool``.
``cma`` parameter, a memory region Device-Tree node with the
``linux,cma-default`` property set, or through the ``CMA_SIZE_MBYTES`` or
``CMA_SIZE_PERCENTAGE`` Kconfig options. The heap's name in devtmpfs is
``default_cma_region``. For backwards compatibility, when the
``DMABUF_HEAPS_CMA_LEGACY`` Kconfig option is set, a duplicate node is
created following legacy naming conventions; the legacy name might be
``reserved``, ``linux,cma``, or ``default-pool``.

View file

@ -7603,10 +7603,12 @@ M: Javier Martinez Canillas <javierm@redhat.com>
L: dri-devel@lists.freedesktop.org
S: Maintained
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: drivers/firmware/sysfb*.c
F: drivers/gpu/drm/sysfb/
F: drivers/video/aperture.c
F: drivers/video/nomodeset.c
F: include/linux/aperture.h
F: include/linux/sysfb.h
F: include/video/nomodeset.h
DRM DRIVER FOR GENERIC EDP PANELS
@ -7822,6 +7824,7 @@ F: include/uapi/drm/nouveau_drm.h
CORE DRIVER FOR NVIDIA GPUS [RUST]
M: Danilo Krummrich <dakr@kernel.org>
M: Alexandre Courbot <acourbot@nvidia.com>
L: nouveau@lists.freedesktop.org
S: Supported
Q: https://patchwork.freedesktop.org/project/nouveau/
@ -7937,6 +7940,7 @@ F: drivers/gpu/drm/sitronix/st7586.c
DRM DRIVER FOR SITRONIX ST7571 PANELS
M: Marcus Folkesson <marcus.folkesson@gmail.com>
S: Maintained
F: Documentation/devicetree/bindings/display/sitronix,st7567.yaml
F: Documentation/devicetree/bindings/display/sitronix,st7571.yaml
F: drivers/gpu/drm/sitronix/st7571-i2c.c
@ -8168,6 +8172,14 @@ F: Documentation/devicetree/bindings/display/imx/
F: drivers/gpu/drm/imx/ipuv3/
F: drivers/gpu/ipu-v3/
DRM DRIVERS FOR FREESCALE IMX8 DISPLAY CONTROLLER
M: Liu Ying <victor.liu@nxp.com>
L: dri-devel@lists.freedesktop.org
S: Maintained
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc*.yaml
F: drivers/gpu/drm/imx/dc/
DRM DRIVERS FOR FREESCALE IMX BRIDGE
M: Liu Ying <victor.liu@nxp.com>
L: dri-devel@lists.freedesktop.org
@ -8328,6 +8340,7 @@ M: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
L: dri-devel@lists.freedesktop.org
S: Maintained
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: Documentation/devicetree/bindings/display/ti/ti,am625-oldi.yaml
F: Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
F: Documentation/devicetree/bindings/display/ti/ti,j721e-dss.yaml
F: Documentation/devicetree/bindings/display/ti/ti,k2g-dss.yaml
@ -8411,9 +8424,17 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: drivers/gpu/drm/scheduler/
F: include/drm/gpu_scheduler.h
DRM LOG
M: Jocelyn Falempe <jfalempe@redhat.com>
M: Javier Martinez Canillas <javierm@redhat.com>
L: dri-devel@lists.freedesktop.org
S: Supported
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: drivers/gpu/drm/clients/drm_log.c
DRM PANEL DRIVERS
M: Neil Armstrong <neil.armstrong@linaro.org>
R: Jessica Zhang <quic_jesszhan@quicinc.com>
R: Jessica Zhang <jessica.zhang@oss.qualcomm.com>
L: dri-devel@lists.freedesktop.org
S: Maintained
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
@ -8422,6 +8443,26 @@ F: drivers/gpu/drm/drm_panel.c
F: drivers/gpu/drm/panel/
F: include/drm/drm_panel.h
DRM PANIC
M: Jocelyn Falempe <jfalempe@redhat.com>
M: Javier Martinez Canillas <javierm@redhat.com>
L: dri-devel@lists.freedesktop.org
S: Supported
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: drivers/gpu/drm/drm_draw.c
F: drivers/gpu/drm/drm_draw_internal.h
F: drivers/gpu/drm/drm_panic*.c
F: include/drm/drm_panic*
DRM PANIC QR CODE
M: Jocelyn Falempe <jfalempe@redhat.com>
M: Javier Martinez Canillas <javierm@redhat.com>
L: dri-devel@lists.freedesktop.org
L: rust-for-linux@vger.kernel.org
S: Supported
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: drivers/gpu/drm/drm_panic_qr.rs
DRM PRIVACY-SCREEN CLASS
M: Hans de Goede <hansg@kernel.org>
L: dri-devel@lists.freedesktop.org
@ -12159,6 +12200,13 @@ L: linux-kernel@vger.kernel.org
S: Supported
F: arch/x86/include/asm/intel-family.h
INTEL DISCRETE GRAPHICS NVM MTD DRIVER
M: Alexander Usyskin <alexander.usyskin@intel.com>
L: linux-mtd@lists.infradead.org
S: Supported
F: drivers/mtd/devices/mtd_intel_dg.c
F: include/linux/intel_dg_nvm_aux.h
INTEL DRM DISPLAY FOR XE AND I915 DRIVERS
M: Jani Nikula <jani.nikula@linux.intel.com>
M: Rodrigo Vivi <rodrigo.vivi@intel.com>
@ -20528,6 +20576,7 @@ L: linux-arm-msm@vger.kernel.org
L: dri-devel@lists.freedesktop.org
S: Supported
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: Documentation/ABI/testing/sysfs-driver-qaic
F: Documentation/accel/qaic/
F: drivers/accel/qaic/
F: include/uapi/drm/qaic_accel.h

View file

@ -59,6 +59,22 @@
<&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
/*
* Please note that overriding compatibles is a discouraged practice and is a
* clear indication of nodes not being, well, compatible!
*
* This is a special case, where the GPU is the same as MT8188, but with one
* of the cores fused out in this lower-binned SoC.
*/
&gpu {
compatible = "mediatek,mt8370-mali", "arm,mali-valhall-jm";
power-domains = <&spm MT8188_POWER_DOMAIN_MFG2>,
<&spm MT8188_POWER_DOMAIN_MFG3>;
power-domain-names = "core0", "core1";
};
&ppi_cluster0 {
affinity = <&cpu0 &cpu1 &cpu2 &cpu3>;
};

View file

@ -213,8 +213,10 @@ arch_initcall(init_x86_sysctl);
*/
struct screen_info screen_info;
EXPORT_SYMBOL(screen_info);
#if defined(CONFIG_FIRMWARE_EDID)
struct edid_info edid_info;
EXPORT_SYMBOL_GPL(edid_info);
#endif
extern int root_mountflags;
@ -525,7 +527,9 @@ static void __init parse_boot_params(void)
{
ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev);
screen_info = boot_params.screen_info;
#if defined(CONFIG_FIRMWARE_EDID)
edid_info = boot_params.edid_info;
#endif
#ifdef CONFIG_X86_32
apm_info.bios = boot_params.apm_bios_info;
ist_info = boot_params.ist_info;

View file

@ -217,8 +217,6 @@ source "drivers/thunderbolt/Kconfig"
source "drivers/android/Kconfig"
source "drivers/gpu/trace/Kconfig"
source "drivers/nvdimm/Kconfig"
source "drivers/dax/Kconfig"

View file

@ -361,7 +361,7 @@ aie2_sched_job_timedout(struct drm_sched_job *sched_job)
aie2_hwctx_restart(xdna, hwctx);
mutex_unlock(&xdna->dev_lock);
return DRM_GPU_SCHED_STAT_NOMINAL;
return DRM_GPU_SCHED_STAT_RESET;
}
static const struct drm_sched_backend_ops sched_ops = {
@ -566,7 +566,7 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx)
.size = MAX_CHAIN_CMDBUF_SIZE,
};
abo = amdxdna_drm_alloc_dev_bo(&xdna->ddev, &args, client->filp, true);
abo = amdxdna_drm_alloc_dev_bo(&xdna->ddev, &args, client->filp);
if (IS_ERR(abo)) {
ret = PTR_ERR(abo);
goto free_cmd_bufs;
@ -848,7 +848,8 @@ int aie2_cmd_submit(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job,
goto up_sem;
}
ret = drm_sched_job_init(&job->base, &hwctx->priv->entity, 1, hwctx);
ret = drm_sched_job_init(&job->base, &hwctx->priv->entity, 1, hwctx,
hwctx->client->filp->client_id);
if (ret) {
XDNA_ERR(xdna, "DRM job init failed, ret %d", ret);
goto free_chain;

View file

@ -24,40 +24,79 @@
MODULE_IMPORT_NS("DMA_BUF");
static int
amdxdna_gem_insert_node_locked(struct amdxdna_gem_obj *abo, bool use_vmap)
amdxdna_gem_heap_alloc(struct amdxdna_gem_obj *abo)
{
struct amdxdna_client *client = abo->client;
struct amdxdna_dev *xdna = client->xdna;
struct amdxdna_mem *mem = &abo->mem;
struct amdxdna_gem_obj *heap;
u64 offset;
u32 align;
int ret;
mutex_lock(&client->mm_lock);
heap = client->dev_heap;
if (!heap) {
ret = -EINVAL;
goto unlock_out;
}
if (heap->mem.userptr == AMDXDNA_INVALID_ADDR) {
XDNA_ERR(xdna, "Invalid dev heap userptr");
ret = -EINVAL;
goto unlock_out;
}
if (mem->size == 0 || mem->size > heap->mem.size) {
XDNA_ERR(xdna, "Invalid dev bo size 0x%lx, limit 0x%lx",
mem->size, heap->mem.size);
ret = -EINVAL;
goto unlock_out;
}
align = 1 << max(PAGE_SHIFT, xdna->dev_info->dev_mem_buf_shift);
ret = drm_mm_insert_node_generic(&abo->dev_heap->mm, &abo->mm_node,
ret = drm_mm_insert_node_generic(&heap->mm, &abo->mm_node,
mem->size, align,
0, DRM_MM_INSERT_BEST);
if (ret) {
XDNA_ERR(xdna, "Failed to alloc dev bo memory, ret %d", ret);
return ret;
goto unlock_out;
}
mem->dev_addr = abo->mm_node.start;
offset = mem->dev_addr - abo->dev_heap->mem.dev_addr;
mem->userptr = abo->dev_heap->mem.userptr + offset;
mem->pages = &abo->dev_heap->base.pages[offset >> PAGE_SHIFT];
mem->nr_pages = mem->size >> PAGE_SHIFT;
offset = mem->dev_addr - heap->mem.dev_addr;
mem->userptr = heap->mem.userptr + offset;
mem->kva = heap->mem.kva + offset;
if (use_vmap) {
mem->kva = vmap(mem->pages, mem->nr_pages, VM_MAP, PAGE_KERNEL);
if (!mem->kva) {
XDNA_ERR(xdna, "Failed to vmap");
drm_mm_remove_node(&abo->mm_node);
return -EFAULT;
}
}
drm_gem_object_get(to_gobj(heap));
return 0;
unlock_out:
mutex_unlock(&client->mm_lock);
return ret;
}
static void
amdxdna_gem_destroy_obj(struct amdxdna_gem_obj *abo)
{
mutex_destroy(&abo->lock);
kfree(abo);
}
static void
amdxdna_gem_heap_free(struct amdxdna_gem_obj *abo)
{
struct amdxdna_gem_obj *heap;
mutex_lock(&abo->client->mm_lock);
drm_mm_remove_node(&abo->mm_node);
heap = abo->client->dev_heap;
drm_gem_object_put(to_gobj(heap));
mutex_unlock(&abo->client->mm_lock);
}
static bool amdxdna_hmm_invalidate(struct mmu_interval_notifier *mni,
@ -213,6 +252,20 @@ free_map:
return ret;
}
static void amdxdna_gem_dev_obj_free(struct drm_gem_object *gobj)
{
struct amdxdna_dev *xdna = to_xdna_dev(gobj->dev);
struct amdxdna_gem_obj *abo = to_xdna_obj(gobj);
XDNA_DBG(xdna, "BO type %d xdna_addr 0x%llx", abo->type, abo->mem.dev_addr);
if (abo->pinned)
amdxdna_gem_unpin(abo);
amdxdna_gem_heap_free(abo);
drm_gem_object_release(gobj);
amdxdna_gem_destroy_obj(abo);
}
static int amdxdna_insert_pages(struct amdxdna_gem_obj *abo,
struct vm_area_struct *vma)
{
@ -374,19 +427,6 @@ static void amdxdna_gem_obj_free(struct drm_gem_object *gobj)
if (abo->pinned)
amdxdna_gem_unpin(abo);
if (abo->type == AMDXDNA_BO_DEV) {
mutex_lock(&abo->client->mm_lock);
drm_mm_remove_node(&abo->mm_node);
mutex_unlock(&abo->client->mm_lock);
vunmap(abo->mem.kva);
drm_gem_object_put(to_gobj(abo->dev_heap));
drm_gem_object_release(gobj);
mutex_destroy(&abo->lock);
kfree(abo);
return;
}
if (abo->type == AMDXDNA_BO_DEV_HEAP)
drm_mm_takedown(&abo->mm);
@ -402,7 +442,7 @@ static void amdxdna_gem_obj_free(struct drm_gem_object *gobj)
}
static const struct drm_gem_object_funcs amdxdna_gem_dev_obj_funcs = {
.free = amdxdna_gem_obj_free,
.free = amdxdna_gem_dev_obj_free,
};
static const struct drm_gem_object_funcs amdxdna_gem_shmem_funcs = {
@ -527,6 +567,7 @@ amdxdna_drm_create_dev_heap(struct drm_device *dev,
struct drm_file *filp)
{
struct amdxdna_client *client = filp->driver_priv;
struct iosys_map map = IOSYS_MAP_INIT_VADDR(NULL);
struct amdxdna_dev *xdna = to_xdna_dev(dev);
struct drm_gem_shmem_object *shmem;
struct amdxdna_gem_obj *abo;
@ -553,18 +594,26 @@ amdxdna_drm_create_dev_heap(struct drm_device *dev,
shmem->map_wc = false;
abo = to_xdna_obj(&shmem->base);
abo->type = AMDXDNA_BO_DEV_HEAP;
abo->client = client;
abo->mem.dev_addr = client->xdna->dev_info->dev_mem_base;
drm_mm_init(&abo->mm, abo->mem.dev_addr, abo->mem.size);
ret = drm_gem_vmap(to_gobj(abo), &map);
if (ret) {
XDNA_ERR(xdna, "Vmap heap bo failed, ret %d", ret);
goto release_obj;
}
abo->mem.kva = map.vaddr;
client->dev_heap = abo;
drm_gem_object_get(to_gobj(abo));
mutex_unlock(&client->mm_lock);
return abo;
release_obj:
drm_gem_object_put(to_gobj(abo));
mm_unlock:
mutex_unlock(&client->mm_lock);
return ERR_PTR(ret);
@ -573,58 +622,32 @@ mm_unlock:
struct amdxdna_gem_obj *
amdxdna_drm_alloc_dev_bo(struct drm_device *dev,
struct amdxdna_drm_create_bo *args,
struct drm_file *filp, bool use_vmap)
struct drm_file *filp)
{
struct amdxdna_client *client = filp->driver_priv;
struct amdxdna_dev *xdna = to_xdna_dev(dev);
size_t aligned_sz = PAGE_ALIGN(args->size);
struct amdxdna_gem_obj *abo, *heap;
struct amdxdna_gem_obj *abo;
int ret;
mutex_lock(&client->mm_lock);
heap = client->dev_heap;
if (!heap) {
ret = -EINVAL;
goto mm_unlock;
}
if (heap->mem.userptr == AMDXDNA_INVALID_ADDR) {
XDNA_ERR(xdna, "Invalid dev heap userptr");
ret = -EINVAL;
goto mm_unlock;
}
if (args->size > heap->mem.size) {
XDNA_ERR(xdna, "Invalid dev bo size 0x%llx, limit 0x%lx",
args->size, heap->mem.size);
ret = -EINVAL;
goto mm_unlock;
}
abo = amdxdna_gem_create_obj(&xdna->ddev, aligned_sz);
if (IS_ERR(abo)) {
ret = PTR_ERR(abo);
goto mm_unlock;
}
if (IS_ERR(abo))
return abo;
to_gobj(abo)->funcs = &amdxdna_gem_dev_obj_funcs;
abo->type = AMDXDNA_BO_DEV;
abo->client = client;
abo->dev_heap = heap;
ret = amdxdna_gem_insert_node_locked(abo, use_vmap);
ret = amdxdna_gem_heap_alloc(abo);
if (ret) {
XDNA_ERR(xdna, "Failed to alloc dev bo memory, ret %d", ret);
goto mm_unlock;
amdxdna_gem_destroy_obj(abo);
return ERR_PTR(ret);
}
drm_gem_object_get(to_gobj(heap));
drm_gem_private_object_init(&xdna->ddev, to_gobj(abo), aligned_sz);
mutex_unlock(&client->mm_lock);
return abo;
mm_unlock:
mutex_unlock(&client->mm_lock);
return ERR_PTR(ret);
}
static struct amdxdna_gem_obj *
@ -632,10 +655,10 @@ amdxdna_drm_create_cmd_bo(struct drm_device *dev,
struct amdxdna_drm_create_bo *args,
struct drm_file *filp)
{
struct iosys_map map = IOSYS_MAP_INIT_VADDR(NULL);
struct amdxdna_dev *xdna = to_xdna_dev(dev);
struct drm_gem_shmem_object *shmem;
struct amdxdna_gem_obj *abo;
struct iosys_map map;
int ret;
if (args->size > XDNA_MAX_CMD_BO_SIZE) {
@ -692,7 +715,7 @@ int amdxdna_drm_create_bo_ioctl(struct drm_device *dev, void *data, struct drm_f
abo = amdxdna_drm_create_dev_heap(dev, args, filp);
break;
case AMDXDNA_BO_DEV:
abo = amdxdna_drm_alloc_dev_bo(dev, args, filp, false);
abo = amdxdna_drm_alloc_dev_bo(dev, args, filp);
break;
case AMDXDNA_BO_CMD:
abo = amdxdna_drm_create_cmd_bo(dev, args, filp);
@ -724,20 +747,13 @@ int amdxdna_gem_pin_nolock(struct amdxdna_gem_obj *abo)
struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev);
int ret;
if (abo->type == AMDXDNA_BO_DEV)
abo = abo->client->dev_heap;
if (is_import_bo(abo))
return 0;
switch (abo->type) {
case AMDXDNA_BO_SHMEM:
case AMDXDNA_BO_DEV_HEAP:
ret = drm_gem_shmem_pin(&abo->base);
break;
case AMDXDNA_BO_DEV:
ret = drm_gem_shmem_pin(&abo->dev_heap->base);
break;
default:
ret = -EOPNOTSUPP;
}
ret = drm_gem_shmem_pin(&abo->base);
XDNA_DBG(xdna, "BO type %d ret %d", abo->type, ret);
return ret;
@ -747,9 +763,6 @@ int amdxdna_gem_pin(struct amdxdna_gem_obj *abo)
{
int ret;
if (abo->type == AMDXDNA_BO_DEV)
abo = abo->dev_heap;
mutex_lock(&abo->lock);
ret = amdxdna_gem_pin_nolock(abo);
mutex_unlock(&abo->lock);
@ -759,12 +772,12 @@ int amdxdna_gem_pin(struct amdxdna_gem_obj *abo)
void amdxdna_gem_unpin(struct amdxdna_gem_obj *abo)
{
if (abo->type == AMDXDNA_BO_DEV)
abo = abo->client->dev_heap;
if (is_import_bo(abo))
return;
if (abo->type == AMDXDNA_BO_DEV)
abo = abo->dev_heap;
mutex_lock(&abo->lock);
drm_gem_shmem_unpin(&abo->base);
mutex_unlock(&abo->lock);
@ -855,10 +868,12 @@ int amdxdna_drm_sync_bo_ioctl(struct drm_device *dev,
if (is_import_bo(abo))
drm_clflush_sg(abo->base.sgt);
else if (abo->type == AMDXDNA_BO_DEV)
drm_clflush_pages(abo->mem.pages, abo->mem.nr_pages);
else
else if (abo->mem.kva)
drm_clflush_virt_range(abo->mem.kva + args->offset, args->size);
else if (abo->base.pages)
drm_clflush_pages(abo->base.pages, gobj->size >> PAGE_SHIFT);
else
drm_WARN(&xdna->ddev, 1, "Can not get flush memory");
amdxdna_gem_unpin(abo);

View file

@ -41,7 +41,6 @@ struct amdxdna_gem_obj {
/* Below members is uninitialized when needed */
struct drm_mm mm; /* For AMDXDNA_BO_DEV_HEAP */
struct amdxdna_gem_obj *dev_heap; /* For AMDXDNA_BO_DEV */
struct drm_mm_node mm_node; /* For AMDXDNA_BO_DEV */
u32 assigned_hwctx;
struct dma_buf *dma_buf;
@ -72,7 +71,7 @@ amdxdna_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf);
struct amdxdna_gem_obj *
amdxdna_drm_alloc_dev_bo(struct drm_device *dev,
struct amdxdna_drm_create_bo *args,
struct drm_file *filp, bool use_vmap);
struct drm_file *filp);
int amdxdna_gem_pin_nolock(struct amdxdna_gem_obj *abo);
int amdxdna_gem_pin(struct amdxdna_gem_obj *abo);

View file

@ -20,8 +20,6 @@
DEFINE_XARRAY_ALLOC(accel_minors_xa);
static struct dentry *accel_debugfs_root;
static const struct device_type accel_sysfs_device_minor = {
.name = "accel_minor"
};
@ -73,17 +71,6 @@ static const struct drm_info_list accel_debugfs_list[] = {
};
#define ACCEL_DEBUGFS_ENTRIES ARRAY_SIZE(accel_debugfs_list)
/**
* accel_debugfs_init() - Initialize debugfs for device
* @dev: Pointer to the device instance.
*
* This function creates a root directory for the device in debugfs.
*/
void accel_debugfs_init(struct drm_device *dev)
{
drm_debugfs_dev_init(dev, accel_debugfs_root);
}
/**
* accel_debugfs_register() - Register debugfs for device
* @dev: Pointer to the device instance.
@ -194,7 +181,6 @@ static const struct file_operations accel_stub_fops = {
void accel_core_exit(void)
{
unregister_chrdev(ACCEL_MAJOR, "accel");
debugfs_remove(accel_debugfs_root);
accel_sysfs_destroy();
WARN_ON(!xa_empty(&accel_minors_xa));
}
@ -209,8 +195,6 @@ int __init accel_core_init(void)
goto error;
}
accel_debugfs_root = debugfs_create_dir("accel", NULL);
ret = register_chrdev(ACCEL_MAJOR, "accel", &accel_stub_fops);
if (ret < 0)
DRM_ERROR("Cannot register ACCEL major: %d\n", ret);

View file

@ -1066,28 +1066,11 @@ static bool is_pci_link_healthy(struct hl_device *hdev)
return (device_id == hdev->pdev->device);
}
static void stringify_time_of_last_heartbeat(struct hl_device *hdev, char *time_str, size_t size,
bool is_pq_hb)
{
time64_t seconds = is_pq_hb ? hdev->heartbeat_debug_info.last_pq_heartbeat_ts
: hdev->heartbeat_debug_info.last_eq_heartbeat_ts;
struct tm tm;
if (!seconds)
return;
time64_to_tm(seconds, 0, &tm);
snprintf(time_str, size, "%ld-%02d-%02d %02d:%02d:%02d (UTC)",
tm.tm_year + 1900, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
}
static bool hl_device_eq_heartbeat_received(struct hl_device *hdev)
{
struct eq_heartbeat_debug_info *heartbeat_debug_info = &hdev->heartbeat_debug_info;
u32 cpu_q_id = heartbeat_debug_info->cpu_queue_id, pq_pi_mask = (HL_QUEUE_LENGTH << 1) - 1;
struct asic_fixed_properties *prop = &hdev->asic_prop;
char pq_time_str[64] = "N/A", eq_time_str[64] = "N/A";
if (!prop->cpucp_info.eq_health_check_supported)
return true;
@ -1095,17 +1078,15 @@ static bool hl_device_eq_heartbeat_received(struct hl_device *hdev)
if (!hdev->eq_heartbeat_received) {
dev_err(hdev->dev, "EQ heartbeat event was not received!\n");
stringify_time_of_last_heartbeat(hdev, pq_time_str, sizeof(pq_time_str), true);
stringify_time_of_last_heartbeat(hdev, eq_time_str, sizeof(eq_time_str), false);
dev_err(hdev->dev,
"EQ: {CI %u, HB counter %u, last HB time: %s}, PQ: {PI: %u, CI: %u (%u), last HB time: %s}\n",
"EQ: {CI %u, HB counter %u, last HB time: %ptTs}, PQ: {PI: %u, CI: %u (%u), last HB time: %ptTs}\n",
hdev->event_queue.ci,
heartbeat_debug_info->heartbeat_event_counter,
eq_time_str,
&hdev->heartbeat_debug_info.last_eq_heartbeat_ts,
hdev->kernel_queues[cpu_q_id].pi,
atomic_read(&hdev->kernel_queues[cpu_q_id].ci),
atomic_read(&hdev->kernel_queues[cpu_q_id].ci) & pq_pi_mask,
pq_time_str);
&hdev->heartbeat_debug_info.last_pq_heartbeat_ts);
hl_eq_dump(hdev, &hdev->event_queue);

View file

@ -704,6 +704,7 @@ static struct pci_device_id ivpu_pci_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_ARL) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_LNL) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PTL_P) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_WCL) },
{ }
};
MODULE_DEVICE_TABLE(pci, ivpu_pci_ids);

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2020-2024 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*/
#ifndef __IVPU_DRV_H__
@ -26,6 +26,7 @@
#define PCI_DEVICE_ID_ARL 0xad1d
#define PCI_DEVICE_ID_LNL 0x643e
#define PCI_DEVICE_ID_PTL_P 0xb03e
#define PCI_DEVICE_ID_WCL 0xfd3e
#define IVPU_HW_IP_37XX 37
#define IVPU_HW_IP_40XX 40
@ -165,6 +166,7 @@ struct ivpu_device {
int boot;
int jsm;
int tdr;
int inference;
int autosuspend;
int d0i3_entry_msg;
int state_dump_msg;
@ -207,10 +209,11 @@ extern bool ivpu_force_snoop;
#define IVPU_TEST_MODE_D0I3_MSG_ENABLE BIT(5)
#define IVPU_TEST_MODE_MIP_DISABLE BIT(6)
#define IVPU_TEST_MODE_DISABLE_TIMEOUTS BIT(8)
#define IVPU_TEST_MODE_TURBO BIT(9)
#define IVPU_TEST_MODE_CLK_RELINQ_DISABLE BIT(10)
#define IVPU_TEST_MODE_CLK_RELINQ_ENABLE BIT(11)
#define IVPU_TEST_MODE_D0I2_DISABLE BIT(12)
#define IVPU_TEST_MODE_TURBO_ENABLE BIT(9)
#define IVPU_TEST_MODE_TURBO_DISABLE BIT(10)
#define IVPU_TEST_MODE_CLK_RELINQ_DISABLE BIT(11)
#define IVPU_TEST_MODE_CLK_RELINQ_ENABLE BIT(12)
#define IVPU_TEST_MODE_D0I2_DISABLE BIT(13)
extern int ivpu_test_mode;
struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv);
@ -240,6 +243,7 @@ static inline int ivpu_hw_ip_gen(struct ivpu_device *vdev)
case PCI_DEVICE_ID_LNL:
return IVPU_HW_IP_40XX;
case PCI_DEVICE_ID_PTL_P:
case PCI_DEVICE_ID_WCL:
return IVPU_HW_IP_50XX;
default:
dump_stack();
@ -256,6 +260,7 @@ static inline int ivpu_hw_btrs_gen(struct ivpu_device *vdev)
return IVPU_HW_BTRS_MTL;
case PCI_DEVICE_ID_LNL:
case PCI_DEVICE_ID_PTL_P:
case PCI_DEVICE_ID_WCL:
return IVPU_HW_BTRS_LNL;
default:
dump_stack();

View file

@ -94,12 +94,14 @@ static void timeouts_init(struct ivpu_device *vdev)
vdev->timeout.boot = -1;
vdev->timeout.jsm = -1;
vdev->timeout.tdr = -1;
vdev->timeout.inference = -1;
vdev->timeout.autosuspend = -1;
vdev->timeout.d0i3_entry_msg = -1;
} else if (ivpu_is_fpga(vdev)) {
vdev->timeout.boot = 50;
vdev->timeout.jsm = 15000;
vdev->timeout.tdr = 30000;
vdev->timeout.inference = 900000;
vdev->timeout.autosuspend = -1;
vdev->timeout.d0i3_entry_msg = 500;
vdev->timeout.state_dump_msg = 10000;
@ -107,6 +109,7 @@ static void timeouts_init(struct ivpu_device *vdev)
vdev->timeout.boot = 50;
vdev->timeout.jsm = 500;
vdev->timeout.tdr = 10000;
vdev->timeout.inference = 300000;
vdev->timeout.autosuspend = 100;
vdev->timeout.d0i3_entry_msg = 100;
vdev->timeout.state_dump_msg = 10;
@ -114,6 +117,7 @@ static void timeouts_init(struct ivpu_device *vdev)
vdev->timeout.boot = 1000;
vdev->timeout.jsm = 500;
vdev->timeout.tdr = 2000;
vdev->timeout.inference = 60000;
if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
vdev->timeout.autosuspend = 10;
else

View file

@ -683,6 +683,7 @@ static void pwr_island_delay_set(struct ivpu_device *vdev)
return;
switch (ivpu_device_id(vdev)) {
case PCI_DEVICE_ID_WCL:
case PCI_DEVICE_ID_PTL_P:
post = high ? 18 : 0;
post1 = 0;

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2020-2024 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*/
#include <drm/drm_file.h>
@ -100,6 +100,43 @@ err_free_cmdq:
return NULL;
}
/**
* ivpu_cmdq_get_entry_count - Calculate the number of entries in the command queue.
* @cmdq: Pointer to the command queue structure.
*
* Returns the number of entries that can fit in the command queue memory.
*/
static inline u32 ivpu_cmdq_get_entry_count(struct ivpu_cmdq *cmdq)
{
size_t size = ivpu_bo_size(cmdq->mem) - sizeof(struct vpu_job_queue_header);
return size / sizeof(struct vpu_job_queue_entry);
}
/**
* ivpu_cmdq_get_flags - Get command queue flags based on input flags and test mode.
* @vdev: Pointer to the ivpu device structure.
* @flags: Input flags to determine the command queue flags.
*
* Returns the calculated command queue flags, considering both the input flags
* and the current test mode settings.
*/
static u32 ivpu_cmdq_get_flags(struct ivpu_device *vdev, u32 flags)
{
u32 cmdq_flags = 0;
if ((flags & DRM_IVPU_CMDQ_FLAG_TURBO) && (ivpu_hw_ip_gen(vdev) >= IVPU_HW_IP_40XX))
cmdq_flags |= VPU_JOB_QUEUE_FLAGS_TURBO_MODE;
/* Test mode can override the TURBO flag coming from the application */
if (ivpu_test_mode & IVPU_TEST_MODE_TURBO_ENABLE)
cmdq_flags |= VPU_JOB_QUEUE_FLAGS_TURBO_MODE;
if (ivpu_test_mode & IVPU_TEST_MODE_TURBO_DISABLE)
cmdq_flags &= ~VPU_JOB_QUEUE_FLAGS_TURBO_MODE;
return cmdq_flags;
}
static void ivpu_cmdq_free(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq)
{
ivpu_preemption_buffers_free(file_priv->vdev, file_priv, cmdq);
@ -107,8 +144,7 @@ static void ivpu_cmdq_free(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *c
kfree(cmdq);
}
static struct ivpu_cmdq *ivpu_cmdq_create(struct ivpu_file_priv *file_priv, u8 priority,
bool is_legacy)
static struct ivpu_cmdq *ivpu_cmdq_create(struct ivpu_file_priv *file_priv, u8 priority, u32 flags)
{
struct ivpu_device *vdev = file_priv->vdev;
struct ivpu_cmdq *cmdq = NULL;
@ -121,10 +157,6 @@ static struct ivpu_cmdq *ivpu_cmdq_create(struct ivpu_file_priv *file_priv, u8 p
ivpu_err(vdev, "Failed to allocate command queue\n");
return NULL;
}
cmdq->priority = priority;
cmdq->is_legacy = is_legacy;
ret = xa_alloc_cyclic(&file_priv->cmdq_xa, &cmdq->id, cmdq, file_priv->cmdq_limit,
&file_priv->cmdq_id_next, GFP_KERNEL);
if (ret < 0) {
@ -132,7 +164,15 @@ static struct ivpu_cmdq *ivpu_cmdq_create(struct ivpu_file_priv *file_priv, u8 p
goto err_free_cmdq;
}
ivpu_dbg(vdev, JOB, "Command queue %d created, ctx %d\n", cmdq->id, file_priv->ctx.id);
cmdq->entry_count = ivpu_cmdq_get_entry_count(cmdq);
cmdq->priority = priority;
cmdq->jobq = (struct vpu_job_queue *)ivpu_bo_vaddr(cmdq->mem);
cmdq->jobq->header.engine_idx = VPU_ENGINE_COMPUTE;
cmdq->jobq->header.flags = ivpu_cmdq_get_flags(vdev, flags);
ivpu_dbg(vdev, JOB, "Command queue %d created, ctx %d, flags 0x%08x\n",
cmdq->id, file_priv->ctx.id, cmdq->jobq->header.flags);
return cmdq;
err_free_cmdq:
@ -188,27 +228,14 @@ static int ivpu_register_db(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *
return ret;
}
static void ivpu_cmdq_jobq_init(struct ivpu_device *vdev, struct vpu_job_queue *jobq)
static void ivpu_cmdq_jobq_reset(struct ivpu_device *vdev, struct vpu_job_queue *jobq)
{
jobq->header.engine_idx = VPU_ENGINE_COMPUTE;
jobq->header.head = 0;
jobq->header.tail = 0;
if (ivpu_test_mode & IVPU_TEST_MODE_TURBO) {
ivpu_dbg(vdev, JOB, "Turbo mode enabled");
jobq->header.flags = VPU_JOB_QUEUE_FLAGS_TURBO_MODE;
}
wmb(); /* Flush WC buffer for jobq->header */
}
static inline u32 ivpu_cmdq_get_entry_count(struct ivpu_cmdq *cmdq)
{
size_t size = ivpu_bo_size(cmdq->mem) - sizeof(struct vpu_job_queue_header);
return size / sizeof(struct vpu_job_queue_entry);
}
static int ivpu_cmdq_register(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq)
{
struct ivpu_device *vdev = file_priv->vdev;
@ -219,10 +246,7 @@ static int ivpu_cmdq_register(struct ivpu_file_priv *file_priv, struct ivpu_cmdq
if (cmdq->db_id)
return 0;
cmdq->entry_count = ivpu_cmdq_get_entry_count(cmdq);
cmdq->jobq = (struct vpu_job_queue *)ivpu_bo_vaddr(cmdq->mem);
ivpu_cmdq_jobq_init(vdev, cmdq->jobq);
ivpu_cmdq_jobq_reset(vdev, cmdq->jobq);
if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) {
ret = ivpu_hws_cmdq_init(file_priv, cmdq, VPU_ENGINE_COMPUTE, cmdq->priority);
@ -291,9 +315,10 @@ static struct ivpu_cmdq *ivpu_cmdq_acquire_legacy(struct ivpu_file_priv *file_pr
break;
if (!cmdq) {
cmdq = ivpu_cmdq_create(file_priv, priority, true);
cmdq = ivpu_cmdq_create(file_priv, priority, 0);
if (!cmdq)
return NULL;
cmdq->is_legacy = true;
}
return cmdq;
@ -891,7 +916,7 @@ int ivpu_cmdq_create_ioctl(struct drm_device *dev, void *data, struct drm_file *
mutex_lock(&file_priv->lock);
cmdq = ivpu_cmdq_create(file_priv, ivpu_job_to_jsm_priority(args->priority), false);
cmdq = ivpu_cmdq_create(file_priv, ivpu_job_to_jsm_priority(args->priority), args->flags);
if (cmdq)
args->cmdq_id = cmdq->id;

View file

@ -33,8 +33,11 @@ static unsigned long ivpu_tdr_timeout_ms;
module_param_named(tdr_timeout_ms, ivpu_tdr_timeout_ms, ulong, 0644);
MODULE_PARM_DESC(tdr_timeout_ms, "Timeout for device hang detection, in milliseconds, 0 - default");
static unsigned long ivpu_inference_timeout_ms;
module_param_named(inference_timeout_ms, ivpu_inference_timeout_ms, ulong, 0644);
MODULE_PARM_DESC(inference_timeout_ms, "Inference maximum duration, in milliseconds, 0 - default");
#define PM_RESCHEDULE_LIMIT 5
#define PM_TDR_HEARTBEAT_LIMIT 30
static void ivpu_pm_prepare_cold_boot(struct ivpu_device *vdev)
{
@ -191,6 +194,10 @@ static void ivpu_job_timeout_work(struct work_struct *work)
{
struct ivpu_pm_info *pm = container_of(work, struct ivpu_pm_info, job_timeout_work.work);
struct ivpu_device *vdev = pm->vdev;
unsigned long timeout_ms = ivpu_tdr_timeout_ms ? ivpu_tdr_timeout_ms : vdev->timeout.tdr;
unsigned long inference_timeout_ms = ivpu_inference_timeout_ms ? ivpu_inference_timeout_ms :
vdev->timeout.inference;
u64 inference_max_retries;
u64 heartbeat;
if (ivpu_jsm_get_heartbeat(vdev, 0, &heartbeat) || heartbeat <= vdev->fw->last_heartbeat) {
@ -198,8 +205,10 @@ static void ivpu_job_timeout_work(struct work_struct *work)
goto recovery;
}
if (atomic_fetch_inc(&vdev->job_timeout_counter) > PM_TDR_HEARTBEAT_LIMIT) {
ivpu_err(vdev, "Job timeout detected, heartbeat limit exceeded\n");
inference_max_retries = DIV_ROUND_UP(inference_timeout_ms, timeout_ms);
if (atomic_fetch_inc(&vdev->job_timeout_counter) >= inference_max_retries) {
ivpu_err(vdev, "Job timeout detected, heartbeat limit (%lld) exceeded\n",
inference_max_retries);
goto recovery;
}

View file

@ -10,6 +10,7 @@ qaic-y := \
qaic_control.o \
qaic_data.o \
qaic_drv.o \
qaic_ras.o \
qaic_timesync.o \
sahara.o

View file

@ -167,6 +167,14 @@ struct qaic_device {
struct workqueue_struct *bootlog_wq;
/* Synchronizes access of pages in MHI bootlog device */
struct mutex bootlog_mutex;
/* MHI RAS channel device */
struct mhi_device *ras_ch;
/* Correctable error count */
unsigned int ce_count;
/* Un-correctable error count */
unsigned int ue_count;
/* Un-correctable non-fatal error count */
unsigned int ue_nf_count;
};
struct qaic_drm_device {
@ -213,8 +221,6 @@ struct qaic_bo {
bool sliced;
/* Request ID of this BO if it is queued for execution */
u16 req_id;
/* Handle assigned to this BO */
u32 handle;
/* Wait on this for completion of DMA transfer of this BO */
struct completion xfer_done;
/*

View file

@ -731,7 +731,6 @@ int qaic_create_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *fi
if (ret)
goto free_bo;
bo->handle = args->handle;
drm_gem_object_put(obj);
srcu_read_unlock(&qdev->dev_lock, qdev_rcu_id);
srcu_read_unlock(&usr->qddev_lock, usr_rcu_id);

View file

@ -29,6 +29,7 @@
#include "mhi_controller.h"
#include "qaic.h"
#include "qaic_debugfs.h"
#include "qaic_ras.h"
#include "qaic_timesync.h"
#include "sahara.h"
@ -695,6 +696,10 @@ static int __init qaic_init(void)
if (ret)
pr_debug("qaic: qaic_bootlog_register failed %d\n", ret);
ret = qaic_ras_register();
if (ret)
pr_debug("qaic: qaic_ras_register failed %d\n", ret);
return 0;
free_mhi:
@ -722,6 +727,7 @@ static void __exit qaic_exit(void)
* reinitializing the link_up state after the cleanup is done.
*/
link_up = true;
qaic_ras_unregister();
qaic_bootlog_unregister();
qaic_timesync_deinit();
sahara_unregister();

View file

@ -0,0 +1,642 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */
/* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */
#include <asm/byteorder.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/mhi.h>
#include "qaic.h"
#include "qaic_ras.h"
#define MAGIC 0x55AA
#define VERSION 0x2
#define HDR_SZ 12
#define NUM_TEMP_LVL 3
#define POWER_BREAK BIT(0)
enum msg_type {
MSG_PUSH, /* async push from device */
MSG_REQ, /* sync request to device */
MSG_RESP, /* sync response from device */
};
enum err_type {
CE, /* correctable error */
UE, /* uncorrectable error */
UE_NF, /* uncorrectable error that is non-fatal, expect a disruption */
ERR_TYPE_MAX,
};
static const char * const err_type_str[] = {
[CE] = "Correctable",
[UE] = "Uncorrectable",
[UE_NF] = "Uncorrectable Non-Fatal",
};
static const char * const err_class_str[] = {
[CE] = "Warning",
[UE] = "Fatal",
[UE_NF] = "Warning",
};
enum err_source {
SOC_MEM,
PCIE,
DDR,
SYS_BUS1,
SYS_BUS2,
NSP_MEM,
TSENS,
};
static const char * const err_src_str[TSENS + 1] = {
[SOC_MEM] = "SoC Memory",
[PCIE] = "PCIE",
[DDR] = "DDR",
[SYS_BUS1] = "System Bus source 1",
[SYS_BUS2] = "System Bus source 2",
[NSP_MEM] = "NSP Memory",
[TSENS] = "Temperature Sensors",
};
struct ras_data {
/* header start */
/* Magic number to validate the message */
u16 magic;
/* RAS version number */
u16 ver;
u32 seq_num;
/* RAS message type */
u8 type;
u8 id;
/* Size of RAS message without the header in byte */
u16 len;
/* header end */
s32 result;
/*
* Error source
* 0 : SoC Memory
* 1 : PCIE
* 2 : DDR
* 3 : System Bus source 1
* 4 : System Bus source 2
* 5 : NSP Memory
* 6 : Temperature Sensors
*/
u32 source;
/*
* Stores the error type, there are three types of error in RAS
* 0 : correctable error (CE)
* 1 : uncorrectable error (UE)
* 2 : uncorrectable error that is non-fatal (UE_NF)
*/
u32 err_type;
u32 err_threshold;
u32 ce_count;
u32 ue_count;
u32 intr_num;
/* Data specific to error source */
u8 syndrome[64];
} __packed;
struct soc_mem_syndrome {
u64 error_address[8];
} __packed;
struct nsp_mem_syndrome {
u32 error_address[8];
u8 nsp_id;
} __packed;
struct ddr_syndrome {
u32 count;
u32 irq_status;
u32 data_31_0[2];
u32 data_63_32[2];
u32 data_95_64[2];
u32 data_127_96[2];
u32 addr_lsb;
u16 addr_msb;
u16 parity_bits;
u16 instance;
u16 err_type;
} __packed;
struct tsens_syndrome {
u32 threshold_type;
s32 temp;
} __packed;
struct sysbus1_syndrome {
u32 slave;
u32 err_type;
u16 addr[8];
u8 instance;
} __packed;
struct sysbus2_syndrome {
u32 lsb3;
u32 msb3;
u32 lsb2;
u32 msb2;
u32 ext_id;
u16 path;
u16 op_type;
u16 len;
u16 redirect;
u8 valid;
u8 word_error;
u8 non_secure;
u8 opc;
u8 error_code;
u8 trans_type;
u8 addr_space;
u8 instance;
} __packed;
struct pcie_syndrome {
/* CE info */
u32 bad_tlp;
u32 bad_dllp;
u32 replay_rollover;
u32 replay_timeout;
u32 rx_err;
u32 internal_ce_count;
/* UE_NF info */
u32 fc_timeout;
u32 poison_tlp;
u32 ecrc_err;
u32 unsupported_req;
u32 completer_abort;
u32 completion_timeout;
/* UE info */
u32 addr;
u8 index;
/*
* Flag to indicate specific event of PCIe
* BIT(0): Power break (low power)
* BIT(1) to BIT(7): Reserved
*/
u8 flag;
} __packed;
static const char * const threshold_type_str[NUM_TEMP_LVL] = {
[0] = "lower",
[1] = "upper",
[2] = "critical",
};
static void ras_msg_to_cpu(struct ras_data *msg)
{
struct sysbus1_syndrome *sysbus1_syndrome = (struct sysbus1_syndrome *)&msg->syndrome[0];
struct sysbus2_syndrome *sysbus2_syndrome = (struct sysbus2_syndrome *)&msg->syndrome[0];
struct soc_mem_syndrome *soc_syndrome = (struct soc_mem_syndrome *)&msg->syndrome[0];
struct nsp_mem_syndrome *nsp_syndrome = (struct nsp_mem_syndrome *)&msg->syndrome[0];
struct tsens_syndrome *tsens_syndrome = (struct tsens_syndrome *)&msg->syndrome[0];
struct pcie_syndrome *pcie_syndrome = (struct pcie_syndrome *)&msg->syndrome[0];
struct ddr_syndrome *ddr_syndrome = (struct ddr_syndrome *)&msg->syndrome[0];
int i;
le16_to_cpus(&msg->magic);
le16_to_cpus(&msg->ver);
le32_to_cpus(&msg->seq_num);
le16_to_cpus(&msg->len);
le32_to_cpus(&msg->result);
le32_to_cpus(&msg->source);
le32_to_cpus(&msg->err_type);
le32_to_cpus(&msg->err_threshold);
le32_to_cpus(&msg->ce_count);
le32_to_cpus(&msg->ue_count);
le32_to_cpus(&msg->intr_num);
switch (msg->source) {
case SOC_MEM:
for (i = 0; i < 8; i++)
le64_to_cpus(&soc_syndrome->error_address[i]);
break;
case PCIE:
le32_to_cpus(&pcie_syndrome->bad_tlp);
le32_to_cpus(&pcie_syndrome->bad_dllp);
le32_to_cpus(&pcie_syndrome->replay_rollover);
le32_to_cpus(&pcie_syndrome->replay_timeout);
le32_to_cpus(&pcie_syndrome->rx_err);
le32_to_cpus(&pcie_syndrome->internal_ce_count);
le32_to_cpus(&pcie_syndrome->fc_timeout);
le32_to_cpus(&pcie_syndrome->poison_tlp);
le32_to_cpus(&pcie_syndrome->ecrc_err);
le32_to_cpus(&pcie_syndrome->unsupported_req);
le32_to_cpus(&pcie_syndrome->completer_abort);
le32_to_cpus(&pcie_syndrome->completion_timeout);
le32_to_cpus(&pcie_syndrome->addr);
break;
case DDR:
le16_to_cpus(&ddr_syndrome->instance);
le16_to_cpus(&ddr_syndrome->err_type);
le32_to_cpus(&ddr_syndrome->count);
le32_to_cpus(&ddr_syndrome->irq_status);
le32_to_cpus(&ddr_syndrome->data_31_0[0]);
le32_to_cpus(&ddr_syndrome->data_31_0[1]);
le32_to_cpus(&ddr_syndrome->data_63_32[0]);
le32_to_cpus(&ddr_syndrome->data_63_32[1]);
le32_to_cpus(&ddr_syndrome->data_95_64[0]);
le32_to_cpus(&ddr_syndrome->data_95_64[1]);
le32_to_cpus(&ddr_syndrome->data_127_96[0]);
le32_to_cpus(&ddr_syndrome->data_127_96[1]);
le16_to_cpus(&ddr_syndrome->parity_bits);
le16_to_cpus(&ddr_syndrome->addr_msb);
le32_to_cpus(&ddr_syndrome->addr_lsb);
break;
case SYS_BUS1:
le32_to_cpus(&sysbus1_syndrome->slave);
le32_to_cpus(&sysbus1_syndrome->err_type);
for (i = 0; i < 8; i++)
le16_to_cpus(&sysbus1_syndrome->addr[i]);
break;
case SYS_BUS2:
le16_to_cpus(&sysbus2_syndrome->op_type);
le16_to_cpus(&sysbus2_syndrome->len);
le16_to_cpus(&sysbus2_syndrome->redirect);
le16_to_cpus(&sysbus2_syndrome->path);
le32_to_cpus(&sysbus2_syndrome->ext_id);
le32_to_cpus(&sysbus2_syndrome->lsb2);
le32_to_cpus(&sysbus2_syndrome->msb2);
le32_to_cpus(&sysbus2_syndrome->lsb3);
le32_to_cpus(&sysbus2_syndrome->msb3);
break;
case NSP_MEM:
for (i = 0; i < 8; i++)
le32_to_cpus(&nsp_syndrome->error_address[i]);
break;
case TSENS:
le32_to_cpus(&tsens_syndrome->threshold_type);
le32_to_cpus(&tsens_syndrome->temp);
break;
}
}
static void decode_ras_msg(struct qaic_device *qdev, struct ras_data *msg)
{
struct sysbus1_syndrome *sysbus1_syndrome = (struct sysbus1_syndrome *)&msg->syndrome[0];
struct sysbus2_syndrome *sysbus2_syndrome = (struct sysbus2_syndrome *)&msg->syndrome[0];
struct soc_mem_syndrome *soc_syndrome = (struct soc_mem_syndrome *)&msg->syndrome[0];
struct nsp_mem_syndrome *nsp_syndrome = (struct nsp_mem_syndrome *)&msg->syndrome[0];
struct tsens_syndrome *tsens_syndrome = (struct tsens_syndrome *)&msg->syndrome[0];
struct pcie_syndrome *pcie_syndrome = (struct pcie_syndrome *)&msg->syndrome[0];
struct ddr_syndrome *ddr_syndrome = (struct ddr_syndrome *)&msg->syndrome[0];
char *class;
char *level;
if (msg->magic != MAGIC) {
pci_warn(qdev->pdev, "Dropping RAS message with invalid magic %x\n", msg->magic);
return;
}
if (!msg->ver || msg->ver > VERSION) {
pci_warn(qdev->pdev, "Dropping RAS message with invalid version %d\n", msg->ver);
return;
}
if (msg->type != MSG_PUSH) {
pci_warn(qdev->pdev, "Dropping non-PUSH RAS message\n");
return;
}
if (msg->len != sizeof(*msg) - HDR_SZ) {
pci_warn(qdev->pdev, "Dropping RAS message with invalid len %d\n", msg->len);
return;
}
if (msg->err_type >= ERR_TYPE_MAX) {
pci_warn(qdev->pdev, "Dropping RAS message with err type %d\n", msg->err_type);
return;
}
if (msg->err_type == UE)
level = KERN_ERR;
else
level = KERN_WARNING;
switch (msg->source) {
case SOC_MEM:
dev_printk(level, &qdev->pdev->dev, "RAS event.\nClass:%s\nDescription:%s %s %s\nError Threshold for this report %d\nSyndrome:\n 0x%llx\n 0x%llx\n 0x%llx\n 0x%llx\n 0x%llx\n 0x%llx\n 0x%llx\n 0x%llx\n",
err_class_str[msg->err_type],
err_type_str[msg->err_type],
"error from",
err_src_str[msg->source],
msg->err_threshold,
soc_syndrome->error_address[0],
soc_syndrome->error_address[1],
soc_syndrome->error_address[2],
soc_syndrome->error_address[3],
soc_syndrome->error_address[4],
soc_syndrome->error_address[5],
soc_syndrome->error_address[6],
soc_syndrome->error_address[7]);
break;
case PCIE:
dev_printk(level, &qdev->pdev->dev, "RAS event.\nClass:%s\nDescription:%s %s %s\nError Threshold for this report %d\n",
err_class_str[msg->err_type],
err_type_str[msg->err_type],
"error from",
err_src_str[msg->source],
msg->err_threshold);
switch (msg->err_type) {
case CE:
/*
* Modeled after AER prints. This continues the dev_printk() from a few
* lines up. We reduce duplication of code, but also avoid re-printing the
* PCI device info so that the end result looks uniform to the log user.
*/
printk(KERN_WARNING pr_fmt("Syndrome:\n Bad TLP count %d\n Bad DLLP count %d\n Replay Rollover count %d\n Replay Timeout count %d\n Recv Error count %d\n Internal CE count %d\n"),
pcie_syndrome->bad_tlp,
pcie_syndrome->bad_dllp,
pcie_syndrome->replay_rollover,
pcie_syndrome->replay_timeout,
pcie_syndrome->rx_err,
pcie_syndrome->internal_ce_count);
if (msg->ver > 0x1)
pr_warn(" Power break %s\n",
pcie_syndrome->flag & POWER_BREAK ? "ON" : "OFF");
break;
case UE:
printk(KERN_ERR pr_fmt("Syndrome:\n Index %d\n Address 0x%x\n"),
pcie_syndrome->index, pcie_syndrome->addr);
break;
case UE_NF:
printk(KERN_WARNING pr_fmt("Syndrome:\n FC timeout count %d\n Poisoned TLP count %d\n ECRC error count %d\n Unsupported request count %d\n Completer abort count %d\n Completion timeout count %d\n"),
pcie_syndrome->fc_timeout,
pcie_syndrome->poison_tlp,
pcie_syndrome->ecrc_err,
pcie_syndrome->unsupported_req,
pcie_syndrome->completer_abort,
pcie_syndrome->completion_timeout);
break;
default:
break;
}
break;
case DDR:
dev_printk(level, &qdev->pdev->dev, "RAS event.\nClass:%s\nDescription:%s %s %s\nError Threshold for this report %d\nSyndrome:\n Instance %d\n Count %d\n Data 31_0 0x%x 0x%x\n Data 63_32 0x%x 0x%x\n Data 95_64 0x%x 0x%x\n Data 127_96 0x%x 0x%x\n Parity bits 0x%x\n Address msb 0x%x\n Address lsb 0x%x\n",
err_class_str[msg->err_type],
err_type_str[msg->err_type],
"error from",
err_src_str[msg->source],
msg->err_threshold,
ddr_syndrome->instance,
ddr_syndrome->count,
ddr_syndrome->data_31_0[1],
ddr_syndrome->data_31_0[0],
ddr_syndrome->data_63_32[1],
ddr_syndrome->data_63_32[0],
ddr_syndrome->data_95_64[1],
ddr_syndrome->data_95_64[0],
ddr_syndrome->data_127_96[1],
ddr_syndrome->data_127_96[0],
ddr_syndrome->parity_bits,
ddr_syndrome->addr_msb,
ddr_syndrome->addr_lsb);
break;
case SYS_BUS1:
dev_printk(level, &qdev->pdev->dev, "RAS event.\nClass:%s\nDescription:%s %s %s\nError Threshold for this report %d\nSyndrome:\n instance %d\n %s\n err_type %d\n address0 0x%x\n address1 0x%x\n address2 0x%x\n address3 0x%x\n address4 0x%x\n address5 0x%x\n address6 0x%x\n address7 0x%x\n",
err_class_str[msg->err_type],
err_type_str[msg->err_type],
"error from",
err_src_str[msg->source],
msg->err_threshold,
sysbus1_syndrome->instance,
sysbus1_syndrome->slave ? "Slave" : "Master",
sysbus1_syndrome->err_type,
sysbus1_syndrome->addr[0],
sysbus1_syndrome->addr[1],
sysbus1_syndrome->addr[2],
sysbus1_syndrome->addr[3],
sysbus1_syndrome->addr[4],
sysbus1_syndrome->addr[5],
sysbus1_syndrome->addr[6],
sysbus1_syndrome->addr[7]);
break;
case SYS_BUS2:
dev_printk(level, &qdev->pdev->dev, "RAS event.\nClass:%s\nDescription:%s %s %s\nError Threshold for this report %d\nSyndrome:\n instance %d\n valid %d\n word error %d\n non-secure %d\n opc %d\n error code %d\n transaction type %d\n address space %d\n operation type %d\n len %d\n redirect %d\n path %d\n ext_id %d\n lsb2 %d\n msb2 %d\n lsb3 %d\n msb3 %d\n",
err_class_str[msg->err_type],
err_type_str[msg->err_type],
"error from",
err_src_str[msg->source],
msg->err_threshold,
sysbus2_syndrome->instance,
sysbus2_syndrome->valid,
sysbus2_syndrome->word_error,
sysbus2_syndrome->non_secure,
sysbus2_syndrome->opc,
sysbus2_syndrome->error_code,
sysbus2_syndrome->trans_type,
sysbus2_syndrome->addr_space,
sysbus2_syndrome->op_type,
sysbus2_syndrome->len,
sysbus2_syndrome->redirect,
sysbus2_syndrome->path,
sysbus2_syndrome->ext_id,
sysbus2_syndrome->lsb2,
sysbus2_syndrome->msb2,
sysbus2_syndrome->lsb3,
sysbus2_syndrome->msb3);
break;
case NSP_MEM:
dev_printk(level, &qdev->pdev->dev, "RAS event.\nClass:%s\nDescription:%s %s %s\nError Threshold for this report %d\nSyndrome:\n NSP ID %d\n 0x%x\n 0x%x\n 0x%x\n 0x%x\n 0x%x\n 0x%x\n 0x%x\n 0x%x\n",
err_class_str[msg->err_type],
err_type_str[msg->err_type],
"error from",
err_src_str[msg->source],
msg->err_threshold,
nsp_syndrome->nsp_id,
nsp_syndrome->error_address[0],
nsp_syndrome->error_address[1],
nsp_syndrome->error_address[2],
nsp_syndrome->error_address[3],
nsp_syndrome->error_address[4],
nsp_syndrome->error_address[5],
nsp_syndrome->error_address[6],
nsp_syndrome->error_address[7]);
break;
case TSENS:
if (tsens_syndrome->threshold_type >= NUM_TEMP_LVL) {
pci_warn(qdev->pdev, "Dropping RAS message with invalid temp threshold %d\n",
tsens_syndrome->threshold_type);
break;
}
if (msg->err_type)
class = "Fatal";
else if (tsens_syndrome->threshold_type)
class = "Critical";
else
class = "Warning";
dev_printk(level, &qdev->pdev->dev, "RAS event.\nClass:%s\nDescription:%s %s %s\nError Threshold for this report %d\nSyndrome:\n %s threshold\n %d deg C\n",
class,
err_type_str[msg->err_type],
"error from",
err_src_str[msg->source],
msg->err_threshold,
threshold_type_str[tsens_syndrome->threshold_type],
tsens_syndrome->temp);
break;
}
/* Uncorrectable errors are fatal */
if (msg->err_type == UE)
mhi_soc_reset(qdev->mhi_cntrl);
switch (msg->err_type) {
case CE:
if (qdev->ce_count != UINT_MAX)
qdev->ce_count++;
break;
case UE:
if (qdev->ce_count != UINT_MAX)
qdev->ue_count++;
break;
case UE_NF:
if (qdev->ce_count != UINT_MAX)
qdev->ue_nf_count++;
break;
default:
/* not possible */
break;
}
}
static ssize_t ce_count_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(dev));
return snprintf(buf, PAGE_SIZE, "%d\n", qdev->ce_count);
}
static ssize_t ue_count_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(dev));
return snprintf(buf, PAGE_SIZE, "%d\n", qdev->ue_count);
}
static ssize_t ue_nonfatal_count_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(dev));
return snprintf(buf, PAGE_SIZE, "%d\n", qdev->ue_nf_count);
}
static DEVICE_ATTR_RO(ce_count);
static DEVICE_ATTR_RO(ue_count);
static DEVICE_ATTR_RO(ue_nonfatal_count);
static struct attribute *ras_attrs[] = {
&dev_attr_ce_count.attr,
&dev_attr_ue_count.attr,
&dev_attr_ue_nonfatal_count.attr,
NULL,
};
static struct attribute_group ras_group = {
.attrs = ras_attrs,
};
static int qaic_ras_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id)
{
struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(mhi_dev->mhi_cntrl->cntrl_dev));
struct ras_data *resp;
int ret;
ret = mhi_prepare_for_transfer(mhi_dev);
if (ret)
return ret;
resp = kzalloc(sizeof(*resp), GFP_KERNEL);
if (!resp) {
mhi_unprepare_from_transfer(mhi_dev);
return -ENOMEM;
}
ret = mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, resp, sizeof(*resp), MHI_EOT);
if (ret) {
kfree(resp);
mhi_unprepare_from_transfer(mhi_dev);
return ret;
}
ret = device_add_group(&qdev->pdev->dev, &ras_group);
if (ret) {
mhi_unprepare_from_transfer(mhi_dev);
pci_dbg(qdev->pdev, "ras add sysfs failed %d\n", ret);
return ret;
}
dev_set_drvdata(&mhi_dev->dev, qdev);
qdev->ras_ch = mhi_dev;
return ret;
}
static void qaic_ras_mhi_remove(struct mhi_device *mhi_dev)
{
struct qaic_device *qdev;
qdev = dev_get_drvdata(&mhi_dev->dev);
qdev->ras_ch = NULL;
device_remove_group(&qdev->pdev->dev, &ras_group);
mhi_unprepare_from_transfer(mhi_dev);
}
static void qaic_ras_mhi_ul_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result *mhi_result) {}
static void qaic_ras_mhi_dl_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result *mhi_result)
{
struct qaic_device *qdev = dev_get_drvdata(&mhi_dev->dev);
struct ras_data *msg = mhi_result->buf_addr;
int ret;
if (mhi_result->transaction_status) {
kfree(msg);
return;
}
ras_msg_to_cpu(msg);
decode_ras_msg(qdev, msg);
ret = mhi_queue_buf(qdev->ras_ch, DMA_FROM_DEVICE, msg, sizeof(*msg), MHI_EOT);
if (ret) {
dev_err(&mhi_dev->dev, "Cannot requeue RAS recv buf %d\n", ret);
kfree(msg);
}
}
static const struct mhi_device_id qaic_ras_mhi_match_table[] = {
{ .chan = "QAIC_STATUS", },
{},
};
static struct mhi_driver qaic_ras_mhi_driver = {
.id_table = qaic_ras_mhi_match_table,
.remove = qaic_ras_mhi_remove,
.probe = qaic_ras_mhi_probe,
.ul_xfer_cb = qaic_ras_mhi_ul_xfer_cb,
.dl_xfer_cb = qaic_ras_mhi_dl_xfer_cb,
.driver = {
.name = "qaic_ras",
},
};
int qaic_ras_register(void)
{
return mhi_driver_register(&qaic_ras_mhi_driver);
}
void qaic_ras_unregister(void)
{
mhi_driver_unregister(&qaic_ras_mhi_driver);
}

View file

@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2020, The Linux Foundation. All rights reserved. */
#ifndef __QAIC_RAS_H__
#define __QAIC_RAS_H__
int qaic_ras_register(void);
void qaic_ras_unregister(void);
#endif /* __QAIC_RAS_H__ */

View file

@ -66,6 +66,20 @@ static pm_message_t pm_transition;
static DEFINE_MUTEX(async_wip_mtx);
static int async_error;
/**
* pm_hibernate_is_recovering - if recovering from hibernate due to error.
*
* Used to query if dev_pm_ops.thaw() is called for normal hibernation case or
* recovering from some error.
*
* Return: true for error case, false for normal case.
*/
bool pm_hibernate_is_recovering(void)
{
return pm_transition.event == PM_EVENT_RECOVER;
}
EXPORT_SYMBOL_GPL(pm_hibernate_is_recovering);
static const char *pm_verb(int event)
{
switch (event) {

View file

@ -36,7 +36,6 @@ config UDMABUF
depends on DMA_SHARED_BUFFER
depends on MEMFD_CREATE || COMPILE_TEST
depends on MMU
select VMAP_PFN
help
A driver to let userspace turn memfd regions into dma-bufs.
Qemu can use this to create host dmabufs for guest framebuffers.

View file

@ -218,7 +218,6 @@ static void dma_fence_chain_set_deadline(struct dma_fence *fence,
}
const struct dma_fence_ops dma_fence_chain_ops = {
.use_64bit_seqno = true,
.get_driver_name = dma_fence_chain_get_driver_name,
.get_timeline_name = dma_fence_chain_get_timeline_name,
.enable_signaling = dma_fence_chain_enable_signaling,
@ -252,7 +251,7 @@ void dma_fence_chain_init(struct dma_fence_chain *chain,
chain->prev_seqno = 0;
/* Try to reuse the context of the previous chain node. */
if (prev_chain && __dma_fence_is_later(seqno, prev->seqno, prev->ops)) {
if (prev_chain && __dma_fence_is_later(prev, seqno, prev->seqno)) {
context = prev->context;
chain->prev_seqno = prev->seqno;
} else {
@ -262,8 +261,8 @@ void dma_fence_chain_init(struct dma_fence_chain *chain,
seqno = max(prev->seqno, seqno);
}
dma_fence_init(&chain->base, &dma_fence_chain_ops,
&chain->lock, context, seqno);
dma_fence_init64(&chain->base, &dma_fence_chain_ops, &chain->lock,
context, seqno);
/*
* Chaining dma_fence_chain container together is only allowed through

View file

@ -511,12 +511,20 @@ dma_fence_wait_timeout(struct dma_fence *fence, bool intr, signed long timeout)
dma_fence_enable_sw_signaling(fence);
trace_dma_fence_wait_start(fence);
if (trace_dma_fence_wait_start_enabled()) {
rcu_read_lock();
trace_dma_fence_wait_start(fence);
rcu_read_unlock();
}
if (fence->ops->wait)
ret = fence->ops->wait(fence, intr, timeout);
else
ret = dma_fence_default_wait(fence, intr, timeout);
trace_dma_fence_wait_end(fence);
if (trace_dma_fence_wait_end_enabled()) {
rcu_read_lock();
trace_dma_fence_wait_end(fence);
rcu_read_unlock();
}
return ret;
}
EXPORT_SYMBOL(dma_fence_wait_timeout);
@ -533,16 +541,23 @@ void dma_fence_release(struct kref *kref)
struct dma_fence *fence =
container_of(kref, struct dma_fence, refcount);
rcu_read_lock();
trace_dma_fence_destroy(fence);
if (WARN(!list_empty(&fence->cb_list) &&
!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags),
"Fence %s:%s:%llx:%llx released with pending signals!\n",
fence->ops->get_driver_name(fence),
fence->ops->get_timeline_name(fence),
fence->context, fence->seqno)) {
if (!list_empty(&fence->cb_list) &&
!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
const char __rcu *timeline;
const char __rcu *driver;
unsigned long flags;
driver = dma_fence_driver_name(fence);
timeline = dma_fence_timeline_name(fence);
WARN(1,
"Fence %s:%s:%llx:%llx released with pending signals!\n",
rcu_dereference(driver), rcu_dereference(timeline),
fence->context, fence->seqno);
/*
* Failed to signal before release, likely a refcounting issue.
*
@ -556,6 +571,8 @@ void dma_fence_release(struct kref *kref)
spin_unlock_irqrestore(fence->lock, flags);
}
rcu_read_unlock();
if (fence->ops->release)
fence->ops->release(fence);
else
@ -982,13 +999,43 @@ EXPORT_SYMBOL(dma_fence_set_deadline);
*/
void dma_fence_describe(struct dma_fence *fence, struct seq_file *seq)
{
const char __rcu *timeline;
const char __rcu *driver;
rcu_read_lock();
timeline = dma_fence_timeline_name(fence);
driver = dma_fence_driver_name(fence);
seq_printf(seq, "%s %s seq %llu %ssignalled\n",
fence->ops->get_driver_name(fence),
fence->ops->get_timeline_name(fence), fence->seqno,
rcu_dereference(driver),
rcu_dereference(timeline),
fence->seqno,
dma_fence_is_signaled(fence) ? "" : "un");
rcu_read_unlock();
}
EXPORT_SYMBOL(dma_fence_describe);
static void
__dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,
spinlock_t *lock, u64 context, u64 seqno, unsigned long flags)
{
BUG_ON(!lock);
BUG_ON(!ops || !ops->get_driver_name || !ops->get_timeline_name);
kref_init(&fence->refcount);
fence->ops = ops;
INIT_LIST_HEAD(&fence->cb_list);
fence->lock = lock;
fence->context = context;
fence->seqno = seqno;
fence->flags = flags;
fence->error = 0;
trace_dma_fence_init(fence);
}
/**
* dma_fence_init - Initialize a custom fence.
* @fence: the fence to initialize
@ -1008,18 +1055,94 @@ void
dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,
spinlock_t *lock, u64 context, u64 seqno)
{
BUG_ON(!lock);
BUG_ON(!ops || !ops->get_driver_name || !ops->get_timeline_name);
kref_init(&fence->refcount);
fence->ops = ops;
INIT_LIST_HEAD(&fence->cb_list);
fence->lock = lock;
fence->context = context;
fence->seqno = seqno;
fence->flags = 0UL;
fence->error = 0;
trace_dma_fence_init(fence);
__dma_fence_init(fence, ops, lock, context, seqno, 0UL);
}
EXPORT_SYMBOL(dma_fence_init);
/**
* dma_fence_init64 - Initialize a custom fence with 64-bit seqno support.
* @fence: the fence to initialize
* @ops: the dma_fence_ops for operations on this fence
* @lock: the irqsafe spinlock to use for locking this fence
* @context: the execution context this fence is run on
* @seqno: a linear increasing sequence number for this context
*
* Initializes an allocated fence, the caller doesn't have to keep its
* refcount after committing with this fence, but it will need to hold a
* refcount again if &dma_fence_ops.enable_signaling gets called.
*
* Context and seqno are used for easy comparison between fences, allowing
* to check which fence is later by simply using dma_fence_later().
*/
void
dma_fence_init64(struct dma_fence *fence, const struct dma_fence_ops *ops,
spinlock_t *lock, u64 context, u64 seqno)
{
__dma_fence_init(fence, ops, lock, context, seqno,
BIT(DMA_FENCE_FLAG_SEQNO64_BIT));
}
EXPORT_SYMBOL(dma_fence_init64);
/**
* dma_fence_driver_name - Access the driver name
* @fence: the fence to query
*
* Returns a driver name backing the dma-fence implementation.
*
* IMPORTANT CONSIDERATION:
* Dma-fence contract stipulates that access to driver provided data (data not
* directly embedded into the object itself), such as the &dma_fence.lock and
* memory potentially accessed by the &dma_fence.ops functions, is forbidden
* after the fence has been signalled. Drivers are allowed to free that data,
* and some do.
*
* To allow safe access drivers are mandated to guarantee a RCU grace period
* between signalling the fence and freeing said data.
*
* As such access to the driver name is only valid inside a RCU locked section.
* The pointer MUST be both queried and USED ONLY WITHIN a SINGLE block guarded
* by the &rcu_read_lock and &rcu_read_unlock pair.
*/
const char __rcu *dma_fence_driver_name(struct dma_fence *fence)
{
RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
"RCU protection is required for safe access to returned string");
if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
return fence->ops->get_driver_name(fence);
else
return "detached-driver";
}
EXPORT_SYMBOL(dma_fence_driver_name);
/**
* dma_fence_timeline_name - Access the timeline name
* @fence: the fence to query
*
* Returns a timeline name provided by the dma-fence implementation.
*
* IMPORTANT CONSIDERATION:
* Dma-fence contract stipulates that access to driver provided data (data not
* directly embedded into the object itself), such as the &dma_fence.lock and
* memory potentially accessed by the &dma_fence.ops functions, is forbidden
* after the fence has been signalled. Drivers are allowed to free that data,
* and some do.
*
* To allow safe access drivers are mandated to guarantee a RCU grace period
* between signalling the fence and freeing said data.
*
* As such access to the driver name is only valid inside a RCU locked section.
* The pointer MUST be both queried and USED ONLY WITHIN a SINGLE block guarded
* by the &rcu_read_lock and &rcu_read_unlock pair.
*/
const char __rcu *dma_fence_timeline_name(struct dma_fence *fence)
{
RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
"RCU protection is required for safe access to returned string");
if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
return fence->ops->get_driver_name(fence);
else
return "signaled-timeline";
}
EXPORT_SYMBOL(dma_fence_timeline_name);

View file

@ -12,3 +12,13 @@ config DMABUF_HEAPS_CMA
Choose this option to enable dma-buf CMA heap. This heap is backed
by the Contiguous Memory Allocator (CMA). If your system has these
regions, you should say Y here.
config DMABUF_HEAPS_CMA_LEGACY
bool "Legacy DMA-BUF CMA Heap"
default y
depends on DMABUF_HEAPS_CMA
help
Add a duplicate CMA-backed dma-buf heap with legacy naming derived
from the CMA area's devicetree node, or "reserved" if the area is not
defined in the devicetree. This uses the same underlying allocator as
CONFIG_DMABUF_HEAPS_CMA.

View file

@ -9,6 +9,9 @@
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
* Andrew F. Davis <afd@ti.com>
*/
#define pr_fmt(fmt) "cma_heap: " fmt
#include <linux/cma.h>
#include <linux/dma-buf.h>
#include <linux/dma-heap.h>
@ -22,6 +25,7 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
#define DEFAULT_CMA_NAME "default_cma_region"
struct cma_heap {
struct dma_heap *heap;
@ -366,17 +370,17 @@ static const struct dma_heap_ops cma_heap_ops = {
.allocate = cma_heap_allocate,
};
static int __init __add_cma_heap(struct cma *cma, void *data)
static int __init __add_cma_heap(struct cma *cma, const char *name)
{
struct cma_heap *cma_heap;
struct dma_heap_export_info exp_info;
struct cma_heap *cma_heap;
cma_heap = kzalloc(sizeof(*cma_heap), GFP_KERNEL);
if (!cma_heap)
return -ENOMEM;
cma_heap->cma = cma;
exp_info.name = cma_get_name(cma);
exp_info.name = name;
exp_info.ops = &cma_heap_ops;
exp_info.priv = cma_heap;
@ -394,12 +398,30 @@ static int __init __add_cma_heap(struct cma *cma, void *data)
static int __init add_default_cma_heap(void)
{
struct cma *default_cma = dev_get_cma_area(NULL);
int ret = 0;
const char *legacy_cma_name;
int ret;
if (default_cma)
ret = __add_cma_heap(default_cma, NULL);
if (!default_cma)
return 0;
return ret;
ret = __add_cma_heap(default_cma, DEFAULT_CMA_NAME);
if (ret)
return ret;
if (IS_ENABLED(CONFIG_DMABUF_HEAPS_CMA_LEGACY)) {
legacy_cma_name = cma_get_name(default_cma);
if (!strcmp(legacy_cma_name, DEFAULT_CMA_NAME)) {
pr_warn("legacy name and default name are the same, skipping legacy heap\n");
return 0;
}
ret = __add_cma_heap(default_cma, legacy_cma_name);
if (ret)
pr_warn("failed to add legacy heap: %pe\n",
ERR_PTR(ret));
}
return 0;
}
module_init(add_default_cma_heap);
MODULE_DESCRIPTION("DMA-BUF CMA Heap");

View file

@ -33,7 +33,7 @@ struct system_heap_buffer {
struct dma_heap_attachment {
struct device *dev;
struct sg_table *table;
struct sg_table table;
struct list_head list;
bool mapped;
};
@ -52,29 +52,22 @@ static gfp_t order_flags[] = {HIGH_ORDER_GFP, HIGH_ORDER_GFP, LOW_ORDER_GFP};
static const unsigned int orders[] = {8, 4, 0};
#define NUM_ORDERS ARRAY_SIZE(orders)
static struct sg_table *dup_sg_table(struct sg_table *table)
static int dup_sg_table(struct sg_table *from, struct sg_table *to)
{
struct sg_table *new_table;
int ret, i;
struct scatterlist *sg, *new_sg;
int ret, i;
new_table = kzalloc(sizeof(*new_table), GFP_KERNEL);
if (!new_table)
return ERR_PTR(-ENOMEM);
ret = sg_alloc_table(to, from->orig_nents, GFP_KERNEL);
if (ret)
return ret;
ret = sg_alloc_table(new_table, table->orig_nents, GFP_KERNEL);
if (ret) {
kfree(new_table);
return ERR_PTR(-ENOMEM);
}
new_sg = new_table->sgl;
for_each_sgtable_sg(table, sg, i) {
new_sg = to->sgl;
for_each_sgtable_sg(from, sg, i) {
sg_set_page(new_sg, sg_page(sg), sg->length, sg->offset);
new_sg = sg_next(new_sg);
}
return new_table;
return 0;
}
static int system_heap_attach(struct dma_buf *dmabuf,
@ -82,19 +75,18 @@ static int system_heap_attach(struct dma_buf *dmabuf,
{
struct system_heap_buffer *buffer = dmabuf->priv;
struct dma_heap_attachment *a;
struct sg_table *table;
int ret;
a = kzalloc(sizeof(*a), GFP_KERNEL);
if (!a)
return -ENOMEM;
table = dup_sg_table(&buffer->sg_table);
if (IS_ERR(table)) {
ret = dup_sg_table(&buffer->sg_table, &a->table);
if (ret) {
kfree(a);
return -ENOMEM;
return ret;
}
a->table = table;
a->dev = attachment->dev;
INIT_LIST_HEAD(&a->list);
a->mapped = false;
@ -118,8 +110,7 @@ static void system_heap_detach(struct dma_buf *dmabuf,
list_del(&a->list);
mutex_unlock(&buffer->lock);
sg_free_table(a->table);
kfree(a->table);
sg_free_table(&a->table);
kfree(a);
}
@ -127,7 +118,7 @@ static struct sg_table *system_heap_map_dma_buf(struct dma_buf_attachment *attac
enum dma_data_direction direction)
{
struct dma_heap_attachment *a = attachment->priv;
struct sg_table *table = a->table;
struct sg_table *table = &a->table;
int ret;
ret = dma_map_sgtable(attachment->dev, table, direction, 0);
@ -162,7 +153,7 @@ static int system_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
list_for_each_entry(a, &buffer->attachments, list) {
if (!a->mapped)
continue;
dma_sync_sgtable_for_cpu(a->dev, a->table, direction);
dma_sync_sgtable_for_cpu(a->dev, &a->table, direction);
}
mutex_unlock(&buffer->lock);
@ -183,7 +174,7 @@ static int system_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
list_for_each_entry(a, &buffer->attachments, list) {
if (!a->mapped)
continue;
dma_sync_sgtable_for_device(a->dev, a->table, direction);
dma_sync_sgtable_for_device(a->dev, &a->table, direction);
}
mutex_unlock(&buffer->lock);

View file

@ -170,7 +170,7 @@ static bool timeline_fence_signaled(struct dma_fence *fence)
{
struct sync_timeline *parent = dma_fence_parent(fence);
return !__dma_fence_is_later(fence->seqno, parent->value, fence->ops);
return !__dma_fence_is_later(fence, fence->seqno, parent->value);
}
static void timeline_fence_set_deadline(struct dma_fence *fence, ktime_t deadline)

View file

@ -135,12 +135,18 @@ char *sync_file_get_name(struct sync_file *sync_file, char *buf, int len)
strscpy(buf, sync_file->user_name, len);
} else {
struct dma_fence *fence = sync_file->fence;
const char __rcu *timeline;
const char __rcu *driver;
rcu_read_lock();
driver = dma_fence_driver_name(fence);
timeline = dma_fence_timeline_name(fence);
snprintf(buf, len, "%s-%s%llu-%lld",
fence->ops->get_driver_name(fence),
fence->ops->get_timeline_name(fence),
rcu_dereference(driver),
rcu_dereference(timeline),
fence->context,
fence->seqno);
rcu_read_unlock();
}
return buf;
@ -262,9 +268,17 @@ err_put_fd:
static int sync_fill_fence_info(struct dma_fence *fence,
struct sync_fence_info *info)
{
strscpy(info->obj_name, fence->ops->get_timeline_name(fence),
const char __rcu *timeline;
const char __rcu *driver;
rcu_read_lock();
driver = dma_fence_driver_name(fence);
timeline = dma_fence_timeline_name(fence);
strscpy(info->obj_name, rcu_dereference(timeline),
sizeof(info->obj_name));
strscpy(info->driver_name, fence->ops->get_driver_name(fence),
strscpy(info->driver_name, rcu_dereference(driver),
sizeof(info->driver_name));
info->status = dma_fence_get_status(fence);
@ -273,6 +287,8 @@ static int sync_fill_fence_info(struct dma_fence *fence,
ktime_to_ns(dma_fence_timestamp(fence)) :
ktime_set(0, 0);
rcu_read_unlock();
return info->status;
}

View file

@ -109,29 +109,22 @@ static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma)
static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map)
{
struct udmabuf *ubuf = buf->priv;
unsigned long *pfns;
struct page **pages;
void *vaddr;
pgoff_t pg;
dma_resv_assert_held(buf->resv);
/**
* HVO may free tail pages, so just use pfn to map each folio
* into vmalloc area.
*/
pfns = kvmalloc_array(ubuf->pagecount, sizeof(*pfns), GFP_KERNEL);
if (!pfns)
pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL);
if (!pages)
return -ENOMEM;
for (pg = 0; pg < ubuf->pagecount; pg++) {
unsigned long pfn = folio_pfn(ubuf->folios[pg]);
for (pg = 0; pg < ubuf->pagecount; pg++)
pages[pg] = folio_page(ubuf->folios[pg],
ubuf->offsets[pg] >> PAGE_SHIFT);
pfn += ubuf->offsets[pg] >> PAGE_SHIFT;
pfns[pg] = pfn;
}
vaddr = vmap_pfn(pfns, ubuf->pagecount, PAGE_KERNEL);
kvfree(pfns);
vaddr = vm_map_ram(pages, ubuf->pagecount, -1);
kvfree(pages);
if (!vaddr)
return -EINVAL;

View file

@ -70,6 +70,7 @@ config DRM_KUNIT_TEST
select DRM_GEM_SHMEM_HELPER
select DRM_KUNIT_TEST_HELPERS
select DRM_LIB_RANDOM
select DRM_SYSFB_HELPER
select PRIME_NUMBERS
default KUNIT_ALL_TESTS
help

View file

@ -104,7 +104,11 @@ obj-$(CONFIG_DRM_PANEL_BACKLIGHT_QUIRKS) += drm_panel_backlight_quirks.o
#
obj-$(CONFIG_DRM_EXEC) += drm_exec.o
obj-$(CONFIG_DRM_GPUVM) += drm_gpuvm.o
obj-$(CONFIG_DRM_GPUSVM) += drm_gpusvm.o
drm_gpusvm_helper-y := \
drm_gpusvm.o\
drm_pagemap.o
obj-$(CONFIG_DRM_GPUSVM) += drm_gpusvm_helper.o
obj-$(CONFIG_DRM_BUDDY) += drm_buddy.o

View file

@ -229,9 +229,10 @@ static int adp_mipi_probe(struct platform_device *pdev)
{
struct adp_mipi_drv_private *adp;
adp = devm_kzalloc(&pdev->dev, sizeof(*adp), GFP_KERNEL);
if (!adp)
return -ENOMEM;
adp = devm_drm_bridge_alloc(&pdev->dev, struct adp_mipi_drv_private,
bridge, &adp_dsi_bridge_funcs);
if (IS_ERR(adp))
return PTR_ERR(adp);
adp->mipi = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(adp->mipi)) {
@ -241,7 +242,6 @@ static int adp_mipi_probe(struct platform_device *pdev)
adp->dsi.dev = &pdev->dev;
adp->dsi.ops = &adp_dsi_host_ops;
adp->bridge.funcs = &adp_dsi_bridge_funcs;
adp->bridge.of_node = pdev->dev.of_node;
adp->bridge.type = DRM_MODE_CONNECTOR_DSI;
dev_set_drvdata(&pdev->dev, adp);

Some files were not shown because too many files have changed in this diff Show more