mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
drm changes for 6.5-rc1:
core: - replace strlcpy with strscpy - EDID changes to support further conversion to struct drm_edid - Move i915 DSC parameter code to common DRM helpers - Add Colorspace functionality aperture: - ignore framebuffers with non-primary devices fbdev: - use fbdev i/o helpers - add Kconfig options for fb_ops helpers - use new fb io helpers directly in drivers sysfs: - export DRM connector ID scheduler: - Avoid an infinite loop ttm: - store function table in .rodata - Add query for TTM mem limit - Add NUMA awareness to pools - Export ttm_pool_fini() bridge: - fsl-ldb: support i.MX6SX - lt9211, lt9611: remove blanking packets - tc358768: implement input bus formats, devm cleanups - ti-snd65dsi86: implement wait_hpd_asserted - analogix: fix endless probe loop - samsung-dsim: support swapped clock, fix enabling, support var clock - display-connector: Add support for external power supply - imx: Fix module linking - tc358762: Support reset GPIO panel: - nt36523: Support Lenovo J606F - st7703: Support Anbernic RG353V-V2 - InnoLux G070ACE-L01 support - boe-tv101wum-nl6: Improve initialization - sharp-ls043t1le001: Mode fixes - simple: BOE EV121WXM-N10-1850, S6D7AA0 - Ampire AM-800480L1TMQW-T00H - Rocktech RK043FN48H - Starry himax83102-j02 - Starry ili9882t amdgpu: - add new ctx query flag to handle reset better - add new query/set shadow buffer for rdna3 - DCN 3.2/3.1.x/3.0.x updates - Enable DC_FP on loongarch - PCIe fix for RDNA2 - improve DC FAMS/SubVP support for better power management - partition support for lots of engines - Take NUMA into account when allocating memory - Add new DRM_AMDGPU_WERROR config parameter to help with CI - Initial SMU13 overdrive support - Add support for new colorspace KMS API - W=1 fixes amdkfd: - Query TTM mem limit rather than hardcoding it - GC 9.4.3 partition support - Handle NUMA for partitions - Add debugger interface for enabling gdb - Add KFD event age tracking radeon: - Fix possible UAF i915: - new getparam for PXP support - GSC/MEI proxy driver - Meteorlake display enablement - avoid clearing preallocated framebuffers with TTM - implement framebuffer mmap support - Disable sampler indirect state in bindless heap - Enable fdinfo for GuC backends - GuC loading and firmware table handling fixes - Various refactors for multi-tile enablement - Define MOCS and PAT tables for MTL - GSC/MEI support for Meteorlake - PMU multi-tile support - Large driver kernel doc cleanup - Allow VRR toggling and arbitrary refresh rates - Support async flips on linear buffers on display ver 12+ - Expose CRTC CTM property on ILK/SNB/VLV - New debugfs for display clock frequencies - Hotplug refactoring - Display refactoring - I915_GEM_CREATE_EXT_SET_PAT for Mesa on Meteorlake - Use large rings for compute contexts - HuC loading for MTL - Allow user to set cache at BO creation - MTL powermanagement enhancements - Switch to dedicated workqueues to stop using flush_scheduled_work() - Move display runtime init under display/ - Remove 10bit gamma on desktop gen3 parts, they don't support it habanalabs: - uapi: return 0 for user queries if there was a h/w or f/w error - Add pci health check when we lose connection with the firmware. This can be used to distinguish between pci link down and firmware getting stuck. - Add more info to the error print when TPC interrupt occur. - Firmware fixes msm: - Adreno A660 bindings - SM8350 MDSS bindings fix - Added support for DPU on sm6350 and sm6375 platforms - Implemented tearcheck support to support vsync on SM150 and newer platforms - Enabled missing features (DSPP, DSC, split display) on sc8180x, sc8280xp, sm8450 - Added support for DSI and 28nm DSI PHY on MSM8226 platform - Added support for DSI on sm6350 and sm6375 platforms - Added support for display controller on MSM8226 platform - A690 GPU support - Move cmdstream dumping out of fence signaling path - a610 support - Support for a6xx devices without GMU nouveau: - NULL ptr before deref fixes armada: - implement fbdev emulation as client sun4i: - fix mipi-dsi dotclock - release clocks vc4: - rgb range toggle property - BT601 / BT2020 HDMI support vkms: - convert to drmm helpers - add reflection and rotation support - fix rgb565 conversion gma500: - fix iomem access shmobile: - support renesas soc platform - enable fbdev mxsfb: - Add support for i.MX93 LCDIF stm: - dsi: Use devm_ helper - ltdc: Fix potential invalid pointer deref renesas: - Group drivers in renesas subdirectory to prepare for new platform - Drop deprecated R-Car H3 ES1.x support meson: - Add support for MIPI DSI displays virtio: - add sync object support mediatek: - Add display binding document for MT6795 -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmSc3UwACgkQDHTzWXnE hr69fQ/+PF9L7FSB/qfjaoqJnk6wJyCehv7pDX2/UK7FUrW0e4EwNVx4KKIRqO/P pKSU9wRlC72ViGgqOYnw0pwzuh45630vWo1stbgxipU2cvM6Ywlq8FiQFdymFe+P tLYWe5MR55Y+E9Y+bCrKn2yvQ7v+f6EZ6ITIX7mrXL77Bpxhv58VzmZawkxmw5MV vwhSqJaaeeWNoyfSIDdN8Oj9fE6ScTyiA0YisOP6jnK/TiQofXQxFrMIdKctCcoA HjolfEEPVCDOSBipkV3hLiyN8lXmt47BmuHp9opSL/g1aASteVeD1/GrccTaA4xV ah+Jx1hBLcH5sm8CZzbCcHhNu3ILnPCFZFCx8gwflQqmDIOZvoMdL75j7lgqJZG8 TePEiifG3kYO/ZiDc5TUBdeMfbgeehPOsxbvOlA3LxJrgyxe/5o9oejX2Uvvzhoq 9fno1PLqeCILqYaMiCocJwyTw/2VKYCCH7Wiypd4o3h0nmAbbqPT3KeZgNOjoa2X GXpiIU9rTQ8LZgSmOXdCt2rc9Jb6q+eCiDgrZzAukbP8veQyOvO16Nx1+XzLhOYc BfjEOoA7nBJD+UPLWkwj42gKtoEWN7IOMTHgcK11d8jdpGISGupl/1nntGhYk0jO +3RRZXMB/Gjwe9ge4K9bFC81pbfuAE7ELQtPsgV9LapMmWHKccY= =FmUA -----END PGP SIGNATURE----- Merge tag 'drm-next-2023-06-29' of git://anongit.freedesktop.org/drm/drm Pull drm updates from Dave Airlie: "There is one set of patches to misc for a i915 gsc/mei proxy driver. Otherwise it's mostly amdgpu/i915/msm, lots of hw enablement and lots of refactoring. core: - replace strlcpy with strscpy - EDID changes to support further conversion to struct drm_edid - Move i915 DSC parameter code to common DRM helpers - Add Colorspace functionality aperture: - ignore framebuffers with non-primary devices fbdev: - use fbdev i/o helpers - add Kconfig options for fb_ops helpers - use new fb io helpers directly in drivers sysfs: - export DRM connector ID scheduler: - Avoid an infinite loop ttm: - store function table in .rodata - Add query for TTM mem limit - Add NUMA awareness to pools - Export ttm_pool_fini() bridge: - fsl-ldb: support i.MX6SX - lt9211, lt9611: remove blanking packets - tc358768: implement input bus formats, devm cleanups - ti-snd65dsi86: implement wait_hpd_asserted - analogix: fix endless probe loop - samsung-dsim: support swapped clock, fix enabling, support var clock - display-connector: Add support for external power supply - imx: Fix module linking - tc358762: Support reset GPIO panel: - nt36523: Support Lenovo J606F - st7703: Support Anbernic RG353V-V2 - InnoLux G070ACE-L01 support - boe-tv101wum-nl6: Improve initialization - sharp-ls043t1le001: Mode fixes - simple: BOE EV121WXM-N10-1850, S6D7AA0 - Ampire AM-800480L1TMQW-T00H - Rocktech RK043FN48H - Starry himax83102-j02 - Starry ili9882t amdgpu: - add new ctx query flag to handle reset better - add new query/set shadow buffer for rdna3 - DCN 3.2/3.1.x/3.0.x updates - Enable DC_FP on loongarch - PCIe fix for RDNA2 - improve DC FAMS/SubVP support for better power management - partition support for lots of engines - Take NUMA into account when allocating memory - Add new DRM_AMDGPU_WERROR config parameter to help with CI - Initial SMU13 overdrive support - Add support for new colorspace KMS API - W=1 fixes amdkfd: - Query TTM mem limit rather than hardcoding it - GC 9.4.3 partition support - Handle NUMA for partitions - Add debugger interface for enabling gdb - Add KFD event age tracking radeon: - Fix possible UAF i915: - new getparam for PXP support - GSC/MEI proxy driver - Meteorlake display enablement - avoid clearing preallocated framebuffers with TTM - implement framebuffer mmap support - Disable sampler indirect state in bindless heap - Enable fdinfo for GuC backends - GuC loading and firmware table handling fixes - Various refactors for multi-tile enablement - Define MOCS and PAT tables for MTL - GSC/MEI support for Meteorlake - PMU multi-tile support - Large driver kernel doc cleanup - Allow VRR toggling and arbitrary refresh rates - Support async flips on linear buffers on display ver 12+ - Expose CRTC CTM property on ILK/SNB/VLV - New debugfs for display clock frequencies - Hotplug refactoring - Display refactoring - I915_GEM_CREATE_EXT_SET_PAT for Mesa on Meteorlake - Use large rings for compute contexts - HuC loading for MTL - Allow user to set cache at BO creation - MTL powermanagement enhancements - Switch to dedicated workqueues to stop using flush_scheduled_work() - Move display runtime init under display/ - Remove 10bit gamma on desktop gen3 parts, they don't support it habanalabs: - uapi: return 0 for user queries if there was a h/w or f/w error - Add pci health check when we lose connection with the firmware. This can be used to distinguish between pci link down and firmware getting stuck. - Add more info to the error print when TPC interrupt occur. - Firmware fixes msm: - Adreno A660 bindings - SM8350 MDSS bindings fix - Added support for DPU on sm6350 and sm6375 platforms - Implemented tearcheck support to support vsync on SM150 and newer platforms - Enabled missing features (DSPP, DSC, split display) on sc8180x, sc8280xp, sm8450 - Added support for DSI and 28nm DSI PHY on MSM8226 platform - Added support for DSI on sm6350 and sm6375 platforms - Added support for display controller on MSM8226 platform - A690 GPU support - Move cmdstream dumping out of fence signaling path - a610 support - Support for a6xx devices without GMU nouveau: - NULL ptr before deref fixes armada: - implement fbdev emulation as client sun4i: - fix mipi-dsi dotclock - release clocks vc4: - rgb range toggle property - BT601 / BT2020 HDMI support vkms: - convert to drmm helpers - add reflection and rotation support - fix rgb565 conversion gma500: - fix iomem access shmobile: - support renesas soc platform - enable fbdev mxsfb: - Add support for i.MX93 LCDIF stm: - dsi: Use devm_ helper - ltdc: Fix potential invalid pointer deref renesas: - Group drivers in renesas subdirectory to prepare for new platform - Drop deprecated R-Car H3 ES1.x support meson: - Add support for MIPI DSI displays virtio: - add sync object support mediatek: - Add display binding document for MT6795" * tag 'drm-next-2023-06-29' of git://anongit.freedesktop.org/drm/drm: (1791 commits) drm/i915: Fix a NULL vs IS_ERR() bug drm/i915: make i915_drm_client_fdinfo() reference conditional again drm/i915/huc: Fix missing error code in intel_huc_init() drm/i915/gsc: take a wakeref for the proxy-init-completion check drm/msm/a6xx: Add A610 speedbin support drm/msm/a6xx: Add A619_holi speedbin support drm/msm/a6xx: Use adreno_is_aXYZ macros in speedbin matching drm/msm/a6xx: Use "else if" in GPU speedbin rev matching drm/msm/a6xx: Fix some A619 tunables drm/msm/a6xx: Add A610 support drm/msm/a6xx: Add support for A619_holi drm/msm/adreno: Disable has_cached_coherent in GMU wrapper configurations drm/msm/a6xx: Introduce GMU wrapper support drm/msm/a6xx: Move CX GMU power counter enablement to hw_init drm/msm/a6xx: Extend and explain UBWC config drm/msm/a6xx: Remove both GBIF and RBBM GBIF halt on hw init drm/msm/a6xx: Add a helper for software-resetting the GPU drm/msm/a6xx: Improve a6xx_bus_clear_pending_transactions() drm/msm/a6xx: Move a6xx_bus_clear_pending_transactions to a6xx_gpu drm/msm/a6xx: Move force keepalive vote removal to a6xx_gmu_force_off() ...
This commit is contained in:
commit
1b722407a1
1
.mailmap
1
.mailmap
@ -332,6 +332,7 @@ Mauro Carvalho Chehab <mchehab@kernel.org> <m.chehab@samsung.com>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@s-opensource.com>
|
||||
Maxim Mikityanskiy <maxtram95@gmail.com> <maximmi@mellanox.com>
|
||||
Maxim Mikityanskiy <maxtram95@gmail.com> <maximmi@nvidia.com>
|
||||
Maxime Ripard <mripard@kernel.org> <maxime@cerno.tech>
|
||||
Maxime Ripard <mripard@kernel.org> <maxime.ripard@bootlin.com>
|
||||
Maxime Ripard <mripard@kernel.org> <maxime.ripard@free-electrons.com>
|
||||
Mayuresh Janorkar <mayur@ti.com>
|
||||
|
@ -0,0 +1,118 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
# Copyright 2020 BayLibre, SAS
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/amlogic,meson-g12a-dw-mipi-dsi.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic specific extensions to the Synopsys Designware MIPI DSI Host Controller
|
||||
|
||||
maintainers:
|
||||
- Neil Armstrong <neil.armstrong@linaro.org>
|
||||
|
||||
description: |
|
||||
The Amlogic Meson Synopsys Designware Integration is composed of
|
||||
- A Synopsys DesignWare MIPI DSI Host Controller IP
|
||||
- A TOP control block controlling the Clocks & Resets of the IP
|
||||
|
||||
allOf:
|
||||
- $ref: dsi-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- amlogic,meson-g12a-dw-mipi-dsi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 3
|
||||
maxItems: 4
|
||||
|
||||
clock-names:
|
||||
minItems: 3
|
||||
items:
|
||||
- const: pclk
|
||||
- const: bit
|
||||
- const: px
|
||||
- const: meas
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: top
|
||||
|
||||
phys:
|
||||
maxItems: 1
|
||||
|
||||
phy-names:
|
||||
items:
|
||||
- const: dphy
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Input node to receive pixel data.
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: DSI output node to panel.
|
||||
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- phys
|
||||
- phy-names
|
||||
- ports
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
dsi@6000 {
|
||||
compatible = "amlogic,meson-g12a-dw-mipi-dsi";
|
||||
reg = <0x6000 0x400>;
|
||||
resets = <&reset_top>;
|
||||
reset-names = "top";
|
||||
clocks = <&clk_pclk>, <&bit_clk>, <&clk_px>;
|
||||
clock-names = "pclk", "bit", "px";
|
||||
phys = <&mipi_dphy>;
|
||||
phy-names = "dphy";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
/* VPU VENC Input */
|
||||
mipi_dsi_venc_port: port@0 {
|
||||
reg = <0>;
|
||||
|
||||
mipi_dsi_in: endpoint {
|
||||
remote-endpoint = <&dpi_out>;
|
||||
};
|
||||
};
|
||||
|
||||
/* DSI Output */
|
||||
mipi_dsi_panel_port: port@1 {
|
||||
reg = <1>;
|
||||
|
||||
mipi_out_panel: endpoint {
|
||||
remote-endpoint = <&mipi_in_panel>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
@ -96,6 +96,11 @@ properties:
|
||||
description:
|
||||
A port node pointing to the HDMI-TX port node.
|
||||
|
||||
port@2:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description:
|
||||
A port node pointing to the DPI port node (e.g. DSI or LVDS transceiver).
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
|
@ -17,6 +17,7 @@ description: |
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx6sx-ldb
|
||||
- fsl,imx8mp-ldb
|
||||
- fsl,imx93-ldb
|
||||
|
||||
@ -64,7 +65,9 @@ allOf:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: fsl,imx93-ldb
|
||||
enum:
|
||||
- fsl,imx6sx-ldb
|
||||
- fsl,imx93-ldb
|
||||
then:
|
||||
properties:
|
||||
ports:
|
||||
|
@ -70,7 +70,9 @@ properties:
|
||||
samsung,burst-clock-frequency:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
DSIM high speed burst mode frequency.
|
||||
DSIM high speed burst mode frequency. If absent,
|
||||
the pixel clock from the attached device or bridge
|
||||
will be used instead.
|
||||
|
||||
samsung,esc-clock-frequency:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
@ -80,7 +82,8 @@ properties:
|
||||
samsung,pll-clock-frequency:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
DSIM oscillator clock frequency.
|
||||
DSIM oscillator clock frequency. If absent, the clock frequency
|
||||
of sclk_mipi will be used instead.
|
||||
|
||||
phys:
|
||||
maxItems: 1
|
||||
@ -100,20 +103,42 @@ properties:
|
||||
specified.
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
DSI output port node to the panel or the next bridge
|
||||
in the chain.
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/media/video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
data-lanes:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
uniqueItems: true
|
||||
items:
|
||||
enum: [ 1, 2, 3, 4 ]
|
||||
|
||||
lane-polarities:
|
||||
minItems: 1
|
||||
maxItems: 5
|
||||
description:
|
||||
The Samsung MIPI DSI IP requires that all the data lanes have
|
||||
the same polarity.
|
||||
|
||||
dependencies:
|
||||
lane-polarities: [data-lanes]
|
||||
|
||||
required:
|
||||
- clock-names
|
||||
- clocks
|
||||
- compatible
|
||||
- interrupts
|
||||
- reg
|
||||
- samsung,burst-clock-frequency
|
||||
- samsung,esc-clock-frequency
|
||||
- samsung,pll-clock-frequency
|
||||
|
||||
allOf:
|
||||
- $ref: ../dsi-controller.yaml#
|
||||
|
@ -21,6 +21,9 @@ properties:
|
||||
maxItems: 1
|
||||
description: virtual channel number of a DSI peripheral
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
|
||||
vddc-supply:
|
||||
description: Regulator for 1.2V internal core power.
|
||||
|
||||
|
@ -4,16 +4,24 @@
|
||||
$id: http://devicetree.org/schemas/display/bridge/toshiba,tc358767.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Toshiba TC358767 eDP bridge
|
||||
title: Toshiba TC358767/TC358867/TC9595 DSI/DPI/eDP bridge
|
||||
|
||||
maintainers:
|
||||
- Andrey Gusakov <andrey.gusakov@cogentembedded.com>
|
||||
|
||||
description: The TC358767 is bridge device which converts DSI/DPI to eDP/DP
|
||||
description: |
|
||||
The TC358767/TC358867/TC9595 is bridge device which
|
||||
converts DSI/DPI to eDP/DP .
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: toshiba,tc358767
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- toshiba,tc358867
|
||||
- toshiba,tc9595
|
||||
- const: toshiba,tc358767
|
||||
- const: toshiba,tc358767
|
||||
|
||||
reg:
|
||||
enum:
|
||||
|
@ -36,6 +36,9 @@ properties:
|
||||
description: GPIO signal to enable DDC bus
|
||||
maxItems: 1
|
||||
|
||||
hdmi-pwr-supply:
|
||||
description: Power supply for the HDMI +5V Power pin
|
||||
|
||||
port:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Connection to controller providing HDMI signals
|
||||
|
@ -21,6 +21,7 @@ properties:
|
||||
- fsl,imx28-lcdif
|
||||
- fsl,imx6sx-lcdif
|
||||
- fsl,imx8mp-lcdif
|
||||
- fsl,imx93-lcdif
|
||||
- items:
|
||||
- enum:
|
||||
- fsl,imx6sl-lcdif
|
||||
@ -88,7 +89,9 @@ allOf:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: fsl,imx8mp-lcdif
|
||||
enum:
|
||||
- fsl,imx8mp-lcdif
|
||||
- fsl,imx93-lcdif
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
@ -107,6 +110,7 @@ allOf:
|
||||
enum:
|
||||
- fsl,imx6sx-lcdif
|
||||
- fsl,imx8mp-lcdif
|
||||
- fsl,imx93-lcdif
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
@ -123,6 +127,7 @@ allOf:
|
||||
- fsl,imx8mm-lcdif
|
||||
- fsl,imx8mn-lcdif
|
||||
- fsl,imx8mp-lcdif
|
||||
- fsl,imx93-lcdif
|
||||
then:
|
||||
required:
|
||||
- power-domains
|
||||
|
@ -27,6 +27,7 @@ properties:
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt2712-disp-aal
|
||||
- mediatek,mt6795-disp-aal
|
||||
- const: mediatek,mt8173-disp-aal
|
||||
- items:
|
||||
- enum:
|
||||
|
@ -33,6 +33,7 @@ properties:
|
||||
- const: mediatek,mt2701-disp-color
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt6795-disp-color
|
||||
- mediatek,mt8183-disp-color
|
||||
- mediatek,mt8186-disp-color
|
||||
- mediatek,mt8188-disp-color
|
||||
|
@ -17,15 +17,20 @@ description: |
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- mediatek,mt2701-dpi
|
||||
- mediatek,mt7623-dpi
|
||||
- mediatek,mt8173-dpi
|
||||
- mediatek,mt8183-dpi
|
||||
- mediatek,mt8186-dpi
|
||||
- mediatek,mt8188-dp-intf
|
||||
- mediatek,mt8192-dpi
|
||||
- mediatek,mt8195-dp-intf
|
||||
oneOf:
|
||||
- enum:
|
||||
- mediatek,mt2701-dpi
|
||||
- mediatek,mt7623-dpi
|
||||
- mediatek,mt8173-dpi
|
||||
- mediatek,mt8183-dpi
|
||||
- mediatek,mt8186-dpi
|
||||
- mediatek,mt8188-dp-intf
|
||||
- mediatek,mt8192-dpi
|
||||
- mediatek,mt8195-dp-intf
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt6795-dpi
|
||||
- const: mediatek,mt8183-dpi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -22,13 +22,18 @@ allOf:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- mediatek,mt2701-dsi
|
||||
- mediatek,mt7623-dsi
|
||||
- mediatek,mt8167-dsi
|
||||
- mediatek,mt8173-dsi
|
||||
- mediatek,mt8183-dsi
|
||||
- mediatek,mt8186-dsi
|
||||
oneOf:
|
||||
- enum:
|
||||
- mediatek,mt2701-dsi
|
||||
- mediatek,mt7623-dsi
|
||||
- mediatek,mt8167-dsi
|
||||
- mediatek,mt8173-dsi
|
||||
- mediatek,mt8183-dsi
|
||||
- mediatek,mt8186-dsi
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt6795-dsi
|
||||
- const: mediatek,mt8173-dsi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -24,6 +24,10 @@ properties:
|
||||
- enum:
|
||||
- mediatek,mt8173-disp-gamma
|
||||
- mediatek,mt8183-disp-gamma
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt6795-disp-gamma
|
||||
- const: mediatek,mt8173-disp-gamma
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt8186-disp-gamma
|
||||
|
@ -24,6 +24,9 @@ properties:
|
||||
- enum:
|
||||
- mediatek,mt8173-disp-merge
|
||||
- mediatek,mt8195-disp-merge
|
||||
- items:
|
||||
- const: mediatek,mt6795-disp-merge
|
||||
- const: mediatek,mt8173-disp-merge
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -24,6 +24,9 @@ properties:
|
||||
- enum:
|
||||
- mediatek,mt2712-disp-od
|
||||
- mediatek,mt8173-disp-od
|
||||
- items:
|
||||
- const: mediatek,mt6795-disp-od
|
||||
- const: mediatek,mt8173-disp-od
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -31,6 +31,10 @@ properties:
|
||||
- mediatek,mt7623-disp-ovl
|
||||
- mediatek,mt2712-disp-ovl
|
||||
- const: mediatek,mt2701-disp-ovl
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt6795-disp-ovl
|
||||
- const: mediatek,mt8173-disp-ovl
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt8188-disp-ovl
|
||||
|
@ -37,6 +37,10 @@ properties:
|
||||
- mediatek,mt7623-disp-rdma
|
||||
- mediatek,mt2712-disp-rdma
|
||||
- const: mediatek,mt2701-disp-rdma
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt6795-disp-rdma
|
||||
- const: mediatek,mt8173-disp-rdma
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt8186-disp-rdma
|
||||
|
@ -23,6 +23,9 @@ properties:
|
||||
oneOf:
|
||||
- enum:
|
||||
- mediatek,mt8173-disp-split
|
||||
- items:
|
||||
- const: mediatek,mt6795-disp-split
|
||||
- const: mediatek,mt8173-disp-split
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -24,6 +24,9 @@ properties:
|
||||
oneOf:
|
||||
- enum:
|
||||
- mediatek,mt8173-disp-ufoe
|
||||
- items:
|
||||
- const: mediatek,mt6795-disp-ufoe
|
||||
- const: mediatek,mt8173-disp-ufoe
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -23,6 +23,9 @@ properties:
|
||||
oneOf:
|
||||
- enum:
|
||||
- mediatek,mt8173-disp-wdma
|
||||
- items:
|
||||
- const: mediatek,mt6795-disp-wdma
|
||||
- const: mediatek,mt8173-disp-wdma
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -29,6 +29,7 @@ properties:
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,sm8450-dp
|
||||
- qcom,sm8550-dp
|
||||
- const: qcom,sm8350-dp
|
||||
|
||||
reg:
|
||||
|
@ -15,6 +15,7 @@ properties:
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,apq8064-dsi-ctrl
|
||||
- qcom,msm8226-dsi-ctrl
|
||||
- qcom,msm8916-dsi-ctrl
|
||||
- qcom,msm8953-dsi-ctrl
|
||||
- qcom,msm8974-dsi-ctrl
|
||||
@ -26,6 +27,8 @@ properties:
|
||||
- qcom,sdm660-dsi-ctrl
|
||||
- qcom,sdm845-dsi-ctrl
|
||||
- qcom,sm6115-dsi-ctrl
|
||||
- qcom,sm6350-dsi-ctrl
|
||||
- qcom,sm6375-dsi-ctrl
|
||||
- qcom,sm8150-dsi-ctrl
|
||||
- qcom,sm8250-dsi-ctrl
|
||||
- qcom,sm8350-dsi-ctrl
|
||||
@ -256,6 +259,7 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,msm8226-dsi-ctrl
|
||||
- qcom,msm8974-dsi-ctrl
|
||||
then:
|
||||
properties:
|
||||
@ -297,6 +301,7 @@ allOf:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,msm8998-dsi-ctrl
|
||||
- qcom,sm6350-dsi-ctrl
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
@ -364,6 +369,7 @@ allOf:
|
||||
enum:
|
||||
- qcom,sdm845-dsi-ctrl
|
||||
- qcom,sm6115-dsi-ctrl
|
||||
- qcom,sm6375-dsi-ctrl
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
|
@ -15,10 +15,11 @@ allOf:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,dsi-phy-28nm-8226
|
||||
- qcom,dsi-phy-28nm-8960
|
||||
- qcom,dsi-phy-28nm-hpm
|
||||
- qcom,dsi-phy-28nm-hpm-fam-b
|
||||
- qcom,dsi-phy-28nm-lp
|
||||
- qcom,dsi-phy-28nm-8960
|
||||
|
||||
reg:
|
||||
items:
|
||||
|
@ -19,16 +19,18 @@ description: |
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- pattern: '^qcom,adreno-gmu-6[0-9][0-9]\.[0-9]$'
|
||||
- const: qcom,adreno-gmu
|
||||
oneOf:
|
||||
- items:
|
||||
- pattern: '^qcom,adreno-gmu-6[0-9][0-9]\.[0-9]$'
|
||||
- const: qcom,adreno-gmu
|
||||
- const: qcom,adreno-gmu-wrapper
|
||||
|
||||
reg:
|
||||
minItems: 3
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
reg-names:
|
||||
minItems: 3
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
clocks:
|
||||
@ -44,7 +46,6 @@ properties:
|
||||
- description: GMU HFI interrupt
|
||||
- description: GMU interrupt
|
||||
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: hfi
|
||||
@ -72,14 +73,8 @@ required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- power-domains
|
||||
- power-domain-names
|
||||
- iommus
|
||||
- operating-points-v2
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
@ -122,6 +117,7 @@ allOf:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,adreno-gmu-635.0
|
||||
- qcom,adreno-gmu-660.1
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
@ -217,6 +213,28 @@ allOf:
|
||||
- const: axi
|
||||
- const: memnoc
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: qcom,adreno-gmu-wrapper
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- description: GMU wrapper register space
|
||||
reg-names:
|
||||
items:
|
||||
- const: gmu
|
||||
else:
|
||||
required:
|
||||
- clocks
|
||||
- clock-names
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- iommus
|
||||
- operating-points-v2
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gpucc-sdm845.h>
|
||||
@ -249,3 +267,12 @@ examples:
|
||||
iommus = <&adreno_smmu 5>;
|
||||
operating-points-v2 = <&gmu_opp_table>;
|
||||
};
|
||||
|
||||
gmu_wrapper: gmu@596a000 {
|
||||
compatible = "qcom,adreno-gmu-wrapper";
|
||||
reg = <0x0596a000 0x30000>;
|
||||
reg-names = "gmu";
|
||||
power-domains = <&gpucc GPU_CX_GDSC>,
|
||||
<&gpucc GPU_GX_GDSC>;
|
||||
power-domain-names = "cx", "gx";
|
||||
};
|
||||
|
@ -36,10 +36,7 @@ properties:
|
||||
|
||||
reg-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: kgsl_3d0_reg_memory
|
||||
- const: cx_mem
|
||||
- const: cx_dbgc
|
||||
maxItems: 3
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
@ -157,16 +154,62 @@ allOf:
|
||||
required:
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
pattern: '^qcom,adreno-6[0-9][0-9]\.[0-9]$'
|
||||
|
||||
then: # Since Adreno 6xx series clocks should be defined in GMU
|
||||
enum:
|
||||
- qcom,adreno-610.0
|
||||
- qcom,adreno-619.1
|
||||
then:
|
||||
properties:
|
||||
clocks: false
|
||||
clock-names: false
|
||||
clocks:
|
||||
minItems: 6
|
||||
maxItems: 6
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: core
|
||||
description: GPU Core clock
|
||||
- const: iface
|
||||
description: GPU Interface clock
|
||||
- const: mem_iface
|
||||
description: GPU Memory Interface clock
|
||||
- const: alt_mem_iface
|
||||
description: GPU Alternative Memory Interface clock
|
||||
- const: gmu
|
||||
description: CX GMU clock
|
||||
- const: xo
|
||||
description: GPUCC clocksource clock
|
||||
|
||||
reg-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: kgsl_3d0_reg_memory
|
||||
- const: cx_dbgc
|
||||
|
||||
required:
|
||||
- clocks
|
||||
- clock-names
|
||||
else:
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
pattern: '^qcom,adreno-6[0-9][0-9]\.[0-9]$'
|
||||
|
||||
then: # Starting with A6xx, the clocks are usually defined in the GMU node
|
||||
properties:
|
||||
clocks: false
|
||||
clock-names: false
|
||||
|
||||
reg-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: kgsl_3d0_reg_memory
|
||||
- const: cx_mem
|
||||
- const: cx_dbgc
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
@ -22,6 +22,7 @@ properties:
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,apq8084-mdp5
|
||||
- qcom,msm8226-mdp5
|
||||
- qcom,msm8916-mdp5
|
||||
- qcom,msm8917-mdp5
|
||||
- qcom,msm8953-mdp5
|
||||
|
@ -125,6 +125,7 @@ patternProperties:
|
||||
- qcom,dsi-phy-14nm-660
|
||||
- qcom,dsi-phy-14nm-8953
|
||||
- qcom,dsi-phy-20nm
|
||||
- qcom,dsi-phy-28nm-8226
|
||||
- qcom,dsi-phy-28nm-hpm
|
||||
- qcom,dsi-phy-28nm-lp
|
||||
- qcom,hdmi-phy-8084
|
||||
|
@ -13,7 +13,10 @@ $ref: /schemas/display/msm/dpu-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sc7180-dpu
|
||||
enum:
|
||||
- qcom,sc7180-dpu
|
||||
- qcom,sm6350-dpu
|
||||
- qcom,sm6375-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
@ -26,6 +29,7 @@ properties:
|
||||
- const: vbif
|
||||
|
||||
clocks:
|
||||
minItems: 6
|
||||
items:
|
||||
- description: Display hf axi clock
|
||||
- description: Display ahb clock
|
||||
@ -33,8 +37,10 @@ properties:
|
||||
- description: Display lut clock
|
||||
- description: Display core clock
|
||||
- description: Display vsync clock
|
||||
- description: Display core throttle clock
|
||||
|
||||
clock-names:
|
||||
minItems: 6
|
||||
items:
|
||||
- const: bus
|
||||
- const: iface
|
||||
@ -42,6 +48,7 @@ properties:
|
||||
- const: lut
|
||||
- const: core
|
||||
- const: vsync
|
||||
- const: throttle
|
||||
|
||||
required:
|
||||
- compatible
|
||||
@ -52,6 +59,20 @@ required:
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm6375-dpu
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 7
|
||||
|
||||
clock-names:
|
||||
minItems: 7
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-sc7180.h>
|
||||
|
@ -0,0 +1,213 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sm6350-mdss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SM6350 Display MDSS
|
||||
|
||||
maintainers:
|
||||
- Krishna Manikandan <quic_mkrishn@quicinc.com>
|
||||
|
||||
description:
|
||||
SM6350 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,sm6350-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB clock from gcc
|
||||
- description: Display AXI clock from gcc
|
||||
- description: Display core clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: core
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
maxItems: 2
|
||||
|
||||
interconnect-names:
|
||||
maxItems: 2
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm6350-dpu
|
||||
|
||||
"^dsi@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sm6350-dsi-ctrl
|
||||
- const: qcom,mdss-dsi-ctrl
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,dsi-phy-10nm
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-sm6350.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sm6350.h>
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-subsystem@ae00000 {
|
||||
compatible = "qcom,sm6350-mdss";
|
||||
reg = <0x0ae00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
|
||||
power-domains = <&dispcc MDSS_GDSC>;
|
||||
|
||||
clocks = <&gcc GCC_DISP_AHB_CLK>,
|
||||
<&gcc GCC_DISP_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>;
|
||||
clock-names = "iface", "bus", "core";
|
||||
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
iommus = <&apps_smmu 0x800 0x2>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sm6350-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc GCC_DISP_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ROT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "bus", "iface", "rot", "lut", "core",
|
||||
"vsync";
|
||||
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ROT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>;
|
||||
assigned-clock-rates = <300000000>,
|
||||
<19200000>,
|
||||
<19200000>,
|
||||
<19200000>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmhpd SM6350_CX>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dpu_intf2_out: endpoint {
|
||||
remote-endpoint = <&dsi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi@ae94000 {
|
||||
compatible = "qcom,sm6350-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <4>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ESC0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_AXI_CLK>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>;
|
||||
assigned-clock-parents = <&dsi0_phy 0>, <&dsi0_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmhpd SM6350_MX>;
|
||||
|
||||
phys = <&dsi0_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi0_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi0_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi0_phy: phy@ae94400 {
|
||||
compatible = "qcom,dsi-phy-10nm";
|
||||
reg = <0x0ae94400 0x200>,
|
||||
<0x0ae94600 0x280>,
|
||||
<0x0ae94a00 0x1e0>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, <&rpmhcc RPMH_CXO_CLK>;
|
||||
clock-names = "iface", "ref";
|
||||
};
|
||||
};
|
||||
...
|
@ -0,0 +1,215 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sm6375-mdss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SM6375 Display MDSS
|
||||
|
||||
maintainers:
|
||||
- Konrad Dybcio <konrad.dybcio@linaro.org>
|
||||
|
||||
description:
|
||||
SM6375 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,sm6375-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB clock from gcc
|
||||
- description: Display AHB clock
|
||||
- description: Display core clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: ahb
|
||||
- const: core
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
maxItems: 2
|
||||
|
||||
interconnect-names:
|
||||
maxItems: 2
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm6375-dpu
|
||||
|
||||
"^dsi@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sm6375-dsi-ctrl
|
||||
- const: qcom,mdss-dsi-ctrl
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm6375-dsi-phy-7nm
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmcc.h>
|
||||
#include <dt-bindings/clock/qcom,sm6375-gcc.h>
|
||||
#include <dt-bindings/clock/qcom,sm6375-dispcc.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-subsystem@5e00000 {
|
||||
compatible = "qcom,sm6375-mdss";
|
||||
reg = <0x05e00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
|
||||
power-domains = <&dispcc MDSS_GDSC>;
|
||||
|
||||
clocks = <&gcc GCC_DISP_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>;
|
||||
clock-names = "iface", "ahb", "core";
|
||||
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
iommus = <&apps_smmu 0x820 0x2>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
display-controller@5e01000 {
|
||||
compatible = "qcom,sm6375-dpu";
|
||||
reg = <0x05e01000 0x8e030>,
|
||||
<0x05eb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ROT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>,
|
||||
<&gcc GCC_DISP_THROTTLE_CORE_CLK>;
|
||||
clock-names = "bus",
|
||||
"iface",
|
||||
"rot",
|
||||
"lut",
|
||||
"core",
|
||||
"vsync",
|
||||
"throttle";
|
||||
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
assigned-clock-rates = <19200000>;
|
||||
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmpd SM6375_VDDCX>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dpu_intf2_out: endpoint {
|
||||
remote-endpoint = <&dsi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi@5e94000 {
|
||||
compatible = "qcom,sm6375-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x05e94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <4>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ESC0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>;
|
||||
assigned-clock-parents = <&mdss_dsi0_phy 0>, <&mdss_dsi0_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmpd SM6375_VDDMX>;
|
||||
|
||||
phys = <&mdss_dsi0_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi0_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi0_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdss_dsi0_phy: phy@5e94400 {
|
||||
compatible = "qcom,sm6375-dsi-phy-7nm";
|
||||
reg = <0x05e94400 0x200>,
|
||||
<0x05e94600 0x280>,
|
||||
<0x05e94900 0x264>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&rpmcc RPM_SMD_XO_CLK_SRC>;
|
||||
clock-names = "iface", "ref";
|
||||
};
|
||||
};
|
||||
...
|
@ -64,7 +64,7 @@ patternProperties:
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,dsi-phy-5nm-8350
|
||||
const: qcom,sm8350-dsi-phy-5nm
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
@ -32,6 +32,10 @@ properties:
|
||||
- innolux,hj110iz-01a
|
||||
# STARRY 2081101QFH032011-53G 10.1" WUXGA TFT LCD panel
|
||||
- starry,2081101qfh032011-53g
|
||||
# STARRY himax83102-j02 10.51" WUXGA TFT LCD panel
|
||||
- starry,himax83102-j02
|
||||
# STARRY ili9882t 10.51" WUXGA TFT LCD panel
|
||||
- starry,ili9882t
|
||||
|
||||
reg:
|
||||
description: the virtual channel number of a DSI peripheral
|
||||
|
@ -19,11 +19,16 @@ allOf:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- xiaomi,elish-boe-nt36523
|
||||
- xiaomi,elish-csot-nt36523
|
||||
- const: novatek,nt36523
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- xiaomi,elish-boe-nt36523
|
||||
- xiaomi,elish-csot-nt36523
|
||||
- const: novatek,nt36523
|
||||
- items:
|
||||
- enum:
|
||||
- lenovo,j606f-boe-nt36523w
|
||||
- const: novatek,nt36523w
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
@ -34,6 +39,7 @@ properties:
|
||||
|
||||
reg: true
|
||||
ports: true
|
||||
rotation: true
|
||||
backlight: true
|
||||
|
||||
required:
|
||||
|
@ -33,6 +33,8 @@ properties:
|
||||
- ampire,am-1280800n3tzqw-t00h
|
||||
# Ampire AM-480272H3TMQW-T01H 4.3" WQVGA TFT LCD panel
|
||||
- ampire,am-480272h3tmqw-t01h
|
||||
# Ampire AM-800480L1TMQW-T00H 5" WVGA TFT LCD panel
|
||||
- ampire,am-800480l1tmqw-t00h
|
||||
# Ampire AM-800480R3TMQW-A1H 7.0" WVGA TFT LCD panel
|
||||
- ampire,am800480r3tmqwa1h
|
||||
# Ampire AM-800600P5TMQW-TB8H 8.0" SVGA TFT LCD panel
|
||||
@ -77,6 +79,8 @@ properties:
|
||||
- auo,t215hvn01
|
||||
# Shanghai AVIC Optoelectronics 7" 1024x600 color TFT-LCD panel
|
||||
- avic,tm070ddh03
|
||||
# BOE EV121WXM-N10-1850 12.1" WXGA (1280x800) TFT LCD panel
|
||||
- boe,ev121wxm-n10-1850
|
||||
# BOE HV070WSA-100 7.01" WSVGA TFT LCD panel
|
||||
- boe,hv070wsa-100
|
||||
# BOE OPTOELECTRONICS TECHNOLOGY 10.1" WXGA TFT LCD panel
|
||||
@ -174,6 +178,8 @@ properties:
|
||||
- innolux,at043tn24
|
||||
# Innolux AT070TN92 7.0" WQVGA TFT LCD panel
|
||||
- innolux,at070tn92
|
||||
# Innolux G070ACE-L01 7" WVGA (800x480) TFT LCD panel
|
||||
- innolux,g070ace-l01
|
||||
# Innolux G070Y2-L01 7" WVGA (800x480) TFT LCD panel
|
||||
- innolux,g070y2-l01
|
||||
# Innolux G070Y2-T02 7" WVGA (800x480) TFT LCD TTL panel
|
||||
@ -280,6 +286,8 @@ properties:
|
||||
- rocktech,rk101ii01d-ct
|
||||
# Rocktech Display Ltd. RK070ER9427 800(RGB)x480 TFT LCD panel
|
||||
- rocktech,rk070er9427
|
||||
# Rocktech Display Ltd. RK043FN48H 4.3" 480x272 LCD-TFT panel
|
||||
- rocktech,rk043fn48h
|
||||
# Samsung 13.3" FHD (1920x1080 pixels) eDP AMOLED panel
|
||||
- samsung,atna33xc20
|
||||
# Samsung 12.2" (2560x1600 pixels) TFT LCD panel
|
||||
|
@ -20,6 +20,8 @@ allOf:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
# Anberic RG353V-V2 5.0" 640x480 TFT LCD panel
|
||||
- anbernic,rg353v-panel-v2
|
||||
# Rocktech JH057N00900 5.5" 720x1440 TFT LCD panel
|
||||
- rocktech,jh057n00900
|
||||
# Xingbangda XBD599 5.99" 720x1440 TFT LCD panel
|
||||
|
@ -0,0 +1,70 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/samsung,s6d7aa0.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung S6D7AA0 MIPI-DSI LCD panel controller
|
||||
|
||||
maintainers:
|
||||
- Artur Weber <aweber.kernel@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
# 1280x800 LSL080AL02 panel
|
||||
- samsung,lsl080al02
|
||||
# 1024x768 LSL080AL03 panel
|
||||
- samsung,lsl080al03
|
||||
# 1024x768 LTL101AT01 panel
|
||||
- samsung,ltl101at01
|
||||
- const: samsung,s6d7aa0
|
||||
|
||||
reg: true
|
||||
|
||||
backlight:
|
||||
description:
|
||||
Backlight to use for the panel. If this property is set on panels
|
||||
that have DSI-based backlight control (LSL080AL03 and LTL101AT01),
|
||||
it overrides the DSI-based backlight.
|
||||
|
||||
reset-gpios:
|
||||
description: Reset GPIO pin, usually GPIO_ACTIVE_LOW.
|
||||
|
||||
power-supply:
|
||||
description:
|
||||
Main power supply for the panel; the exact voltage differs between
|
||||
panels, and is usually somewhere around 3.3-5v.
|
||||
|
||||
vmipi-supply:
|
||||
description: VMIPI supply, usually 1.8v.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reset-gpios
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
dsi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
panel@0 {
|
||||
compatible = "samsung,lsl080al02", "samsung,s6d7aa0";
|
||||
reg = <0>;
|
||||
power-supply = <&display_3v3_supply>;
|
||||
reset-gpios = <&gpf0 4 GPIO_ACTIVE_LOW>;
|
||||
backlight = <&backlight>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@ -5,6 +5,8 @@ Ryzen 4000 series, RENOIR, DCN 2.1, 9.3, VCN 2.2, 4.1.2, 11.0.3
|
||||
Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx, RAVEN2, DCN 1.0, 9.2.2, VCN 1.0.1, 4.1.1, 10.0.1
|
||||
SteamDeck, VANGOGH, DCN 3.0.1, 10.3.1, VCN 3.1.0, 5.2.1, 11.5.0
|
||||
Ryzen 5000 series / Ryzen 7x30 series, GREEN SARDINE / Cezanne / Barcelo / Barcelo-R, DCN 2.1, 9.3, VCN 2.2, 4.1.1, 12.0.1
|
||||
Ryzen 6000 series / Ryzen 7x35 series, YELLOW CARP / Rembrandt / Rembrandt+, 3.1.2, 10.3.3, VCN 3.1.1, 5.2.3, 13.0.3
|
||||
Ryzen 6000 series / Ryzen 7x35 series / Ryzen 7x36 series, YELLOW CARP / Rembrandt / Rembrandt-R, 3.1.2, 10.3.3, VCN 3.1.1, 5.2.3, 13.0.3
|
||||
Ryzen 7000 series (AM5), Raphael, 3.1.5, 10.3.6, 3.1.2, 5.2.6, 13.0.5
|
||||
Ryzen 7x45 series (FL1), / Dragon Range, 3.1.5, 10.3.6, 3.1.2, 5.2.6, 13.0.5
|
||||
Ryzen 7x20 series, Mendocino, 3.1.6, 10.3.7, 3.1.1, 5.2.7, 13.0.8
|
||||
Ryzen 7x40 series, Phoenix, 3.1.4, 11.0.1 / 11.0.4, 4.0.2, 6.0.1, 13.0.4 / 13.0.11
|
|
@ -24,7 +24,7 @@ File format specification
|
||||
- All keys shall be prefixed with `drm-`.
|
||||
- Whitespace between the delimiter and first non-whitespace character shall be
|
||||
ignored when parsing.
|
||||
- Neither keys or values are allowed to contain whitespace characters.
|
||||
- Keys are not allowed to contain whitespace characters.
|
||||
- Numerical key value pairs can end with optional unit string.
|
||||
- Data type of the value is fixed as defined in the specification.
|
||||
|
||||
@ -39,12 +39,13 @@ Data types
|
||||
----------
|
||||
|
||||
- <uint> - Unsigned integer without defining the maximum value.
|
||||
- <str> - String excluding any above defined reserved characters or whitespace.
|
||||
- <keystr> - String excluding any above defined reserved characters or whitespace.
|
||||
- <valstr> - String.
|
||||
|
||||
Mandatory fully standardised keys
|
||||
---------------------------------
|
||||
|
||||
- drm-driver: <str>
|
||||
- drm-driver: <valstr>
|
||||
|
||||
String shall contain the name this driver registered as via the respective
|
||||
`struct drm_driver` data structure.
|
||||
@ -52,6 +53,9 @@ String shall contain the name this driver registered as via the respective
|
||||
Optional fully standardised keys
|
||||
--------------------------------
|
||||
|
||||
Identification
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
- drm-pdev: <aaaa:bb.cc.d>
|
||||
|
||||
For PCI devices this should contain the PCI slot address of the device in
|
||||
@ -69,10 +73,13 @@ scope of each device, in which case `drm-pdev` shall be present as well.
|
||||
Userspace should make sure to not double account any usage statistics by using
|
||||
the above described criteria in order to associate data to individual clients.
|
||||
|
||||
- drm-engine-<str>: <uint> ns
|
||||
Utilization
|
||||
^^^^^^^^^^^
|
||||
|
||||
- drm-engine-<keystr>: <uint> ns
|
||||
|
||||
GPUs usually contain multiple execution engines. Each shall be given a stable
|
||||
and unique name (str), with possible values documented in the driver specific
|
||||
and unique name (keystr), with possible values documented in the driver specific
|
||||
documentation.
|
||||
|
||||
Value shall be in specified time units which the respective GPU engine spent
|
||||
@ -84,31 +91,19 @@ larger value within a reasonable period. Upon observing a value lower than what
|
||||
was previously read, userspace is expected to stay with that larger previous
|
||||
value until a monotonic update is seen.
|
||||
|
||||
- drm-engine-capacity-<str>: <uint>
|
||||
- drm-engine-capacity-<keystr>: <uint>
|
||||
|
||||
Engine identifier string must be the same as the one specified in the
|
||||
drm-engine-<str> tag and shall contain a greater than zero number in case the
|
||||
drm-engine-<keystr> tag and shall contain a greater than zero number in case the
|
||||
exported engine corresponds to a group of identical hardware engines.
|
||||
|
||||
In the absence of this tag parser shall assume capacity of one. Zero capacity
|
||||
is not allowed.
|
||||
|
||||
- drm-memory-<str>: <uint> [KiB|MiB]
|
||||
|
||||
Each possible memory type which can be used to store buffer objects by the
|
||||
GPU in question shall be given a stable and unique name to be returned as the
|
||||
string here.
|
||||
|
||||
Value shall reflect the amount of storage currently consumed by the buffer
|
||||
object belong to this client, in the respective memory region.
|
||||
|
||||
Default unit shall be bytes with optional unit specifiers of 'KiB' or 'MiB'
|
||||
indicating kibi- or mebi-bytes.
|
||||
|
||||
- drm-cycles-<str> <uint>
|
||||
- drm-cycles-<keystr>: <uint>
|
||||
|
||||
Engine identifier string must be the same as the one specified in the
|
||||
drm-engine-<str> tag and shall contain the number of busy cycles for the given
|
||||
drm-engine-<keystr> tag and shall contain the number of busy cycles for the given
|
||||
engine.
|
||||
|
||||
Values are not required to be constantly monotonic if it makes the driver
|
||||
@ -117,16 +112,60 @@ larger value within a reasonable period. Upon observing a value lower than what
|
||||
was previously read, userspace is expected to stay with that larger previous
|
||||
value until a monotonic update is seen.
|
||||
|
||||
- drm-maxfreq-<str> <uint> [Hz|MHz|KHz]
|
||||
- drm-maxfreq-<keystr>: <uint> [Hz|MHz|KHz]
|
||||
|
||||
Engine identifier string must be the same as the one specified in the
|
||||
drm-engine-<str> tag and shall contain the maximum frequency for the given
|
||||
engine. Taken together with drm-cycles-<str>, this can be used to calculate
|
||||
percentage utilization of the engine, whereas drm-engine-<str> only reflects
|
||||
drm-engine-<keystr> tag and shall contain the maximum frequency for the given
|
||||
engine. Taken together with drm-cycles-<keystr>, this can be used to calculate
|
||||
percentage utilization of the engine, whereas drm-engine-<keystr> only reflects
|
||||
time active without considering what frequency the engine is operating as a
|
||||
percentage of it's maximum frequency.
|
||||
|
||||
Memory
|
||||
^^^^^^
|
||||
|
||||
- drm-memory-<region>: <uint> [KiB|MiB]
|
||||
|
||||
Each possible memory type which can be used to store buffer objects by the
|
||||
GPU in question shall be given a stable and unique name to be returned as the
|
||||
string here. The name "memory" is reserved to refer to normal system memory.
|
||||
|
||||
Value shall reflect the amount of storage currently consumed by the buffer
|
||||
objects belong to this client, in the respective memory region.
|
||||
|
||||
Default unit shall be bytes with optional unit specifiers of 'KiB' or 'MiB'
|
||||
indicating kibi- or mebi-bytes.
|
||||
|
||||
- drm-shared-<region>: <uint> [KiB|MiB]
|
||||
|
||||
The total size of buffers that are shared with another file (ie. have more
|
||||
than a single handle).
|
||||
|
||||
- drm-total-<region>: <uint> [KiB|MiB]
|
||||
|
||||
The total size of buffers that including shared and private memory.
|
||||
|
||||
- drm-resident-<region>: <uint> [KiB|MiB]
|
||||
|
||||
The total size of buffers that are resident in the specified region.
|
||||
|
||||
- drm-purgeable-<region>: <uint> [KiB|MiB]
|
||||
|
||||
The total size of buffers that are purgeable.
|
||||
|
||||
- drm-active-<region>: <uint> [KiB|MiB]
|
||||
|
||||
The total size of buffers that are active on one or more engines.
|
||||
|
||||
Implementation Details
|
||||
======================
|
||||
|
||||
Drivers should use drm_show_fdinfo() in their `struct file_operations`, and
|
||||
implement &drm_driver.show_fdinfo if they wish to provide any stats which
|
||||
are not provided by drm_show_fdinfo(). But even driver specific stats should
|
||||
be documented above and where possible, aligned with other drivers.
|
||||
|
||||
Driver specific implementations
|
||||
===============================
|
||||
-------------------------------
|
||||
|
||||
:ref:`i915-usage-stats`
|
||||
|
@ -31,3 +31,7 @@ host such documentation:
|
||||
.. toctree::
|
||||
|
||||
i915_vm_bind.rst
|
||||
|
||||
.. toctree::
|
||||
|
||||
xe.rst
|
||||
|
235
Documentation/gpu/rfc/xe.rst
Normal file
235
Documentation/gpu/rfc/xe.rst
Normal file
@ -0,0 +1,235 @@
|
||||
==========================
|
||||
Xe – Merge Acceptance Plan
|
||||
==========================
|
||||
Xe is a new driver for Intel GPUs that supports both integrated and
|
||||
discrete platforms starting with Tiger Lake (first Intel Xe Architecture).
|
||||
|
||||
This document aims to establish a merge plan for the Xe, by writing down clear
|
||||
pre-merge goals, in order to avoid unnecessary delays.
|
||||
|
||||
Xe – Overview
|
||||
=============
|
||||
The main motivation of Xe is to have a fresh base to work from that is
|
||||
unencumbered by older platforms, whilst also taking the opportunity to
|
||||
rearchitect our driver to increase sharing across the drm subsystem, both
|
||||
leveraging and allowing us to contribute more towards other shared components
|
||||
like TTM and drm/scheduler.
|
||||
|
||||
This is also an opportunity to start from the beginning with a clean uAPI that is
|
||||
extensible by design and already aligned with the modern userspace needs. For
|
||||
this reason, the memory model is solely based on GPU Virtual Address space
|
||||
bind/unbind (‘VM_BIND’) of GEM buffer objects (BOs) and execution only supporting
|
||||
explicit synchronization. With persistent mapping across the execution, the
|
||||
userspace does not need to provide a list of all required mappings during each
|
||||
submission.
|
||||
|
||||
The new driver leverages a lot from i915. As for display, the intent is to share
|
||||
the display code with the i915 driver so that there is maximum reuse there.
|
||||
|
||||
As for the power management area, the goal is to have a much-simplified support
|
||||
for the system suspend states (S-states), PCI device suspend states (D-states),
|
||||
GPU/Render suspend states (R-states) and frequency management. It should leverage
|
||||
as much as possible all the existent PCI-subsystem infrastructure (pm and
|
||||
runtime_pm) and underlying firmware components such PCODE and GuC for the power
|
||||
states and frequency decisions.
|
||||
|
||||
Repository:
|
||||
|
||||
https://gitlab.freedesktop.org/drm/xe/kernel (branch drm-xe-next)
|
||||
|
||||
Xe – Platforms
|
||||
==============
|
||||
Currently, Xe is already functional and has experimental support for multiple
|
||||
platforms starting from Tiger Lake, with initial support in userspace implemented
|
||||
in Mesa (for Iris and Anv, our OpenGL and Vulkan drivers), as well as in NEO
|
||||
(for OpenCL and Level0).
|
||||
|
||||
During a transition period, platforms will be supported by both Xe and i915.
|
||||
However, the force_probe mechanism existent in both drivers will allow only one
|
||||
official and by-default probe at a given time.
|
||||
|
||||
For instance, in order to probe a DG2 which PCI ID is 0x5690 by Xe instead of
|
||||
i915, the following set of parameters need to be used:
|
||||
|
||||
```
|
||||
i915.force_probe=!5690 xe.force_probe=5690
|
||||
```
|
||||
|
||||
In both drivers, the ‘.require_force_probe’ protection forces the user to use the
|
||||
force_probe parameter while the driver is under development. This protection is
|
||||
only removed when the support for the platform and the uAPI are stable. Stability
|
||||
which needs to be demonstrated by CI results.
|
||||
|
||||
In order to avoid user space regressions, i915 will continue to support all the
|
||||
current platforms that are already out of this protection. Xe support will be
|
||||
forever experimental and dependent on the usage of force_probe for these
|
||||
platforms.
|
||||
|
||||
When the time comes for Xe, the protection will be lifted on Xe and kept in i915.
|
||||
|
||||
Xe driver will be protected with both STAGING Kconfig and force_probe. Changes in
|
||||
the uAPI are expected while the driver is behind these protections. STAGING will
|
||||
be removed when the driver uAPI gets to a mature state where we can guarantee the
|
||||
‘no regression’ rule. Then force_probe will be lifted only for future platforms
|
||||
that will be productized with Xe driver, but not with i915.
|
||||
|
||||
Xe – Pre-Merge Goals
|
||||
====================
|
||||
|
||||
Drm_scheduler
|
||||
-------------
|
||||
Xe primarily uses Firmware based scheduling (GuC FW). However, it will use
|
||||
drm_scheduler as the scheduler ‘frontend’ for userspace submission in order to
|
||||
resolve syncobj and dma-buf implicit sync dependencies. However, drm_scheduler is
|
||||
not yet prepared to handle the 1-to-1 relationship between drm_gpu_scheduler and
|
||||
drm_sched_entity.
|
||||
|
||||
Deeper changes to drm_scheduler should *not* be required to get Xe accepted, but
|
||||
some consensus needs to be reached between Xe and other community drivers that
|
||||
could also benefit from this work, for coupling FW based/assisted submission such
|
||||
as the ARM’s new Mali GPU driver, and others.
|
||||
|
||||
As a key measurable result, the patch series introducing Xe itself shall not
|
||||
depend on any other patch touching drm_scheduler itself that was not yet merged
|
||||
through drm-misc. This, by itself, already includes the reach of an agreement for
|
||||
uniform 1 to 1 relationship implementation / usage across drivers.
|
||||
|
||||
GPU VA
|
||||
------
|
||||
Two main goals of Xe are meeting together here:
|
||||
|
||||
1) Have an uAPI that aligns with modern UMD needs.
|
||||
|
||||
2) Early upstream engagement.
|
||||
|
||||
RedHat engineers working on Nouveau proposed a new DRM feature to handle keeping
|
||||
track of GPU virtual address mappings. This is still not merged upstream, but
|
||||
this aligns very well with our goals and with our VM_BIND. The engagement with
|
||||
upstream and the port of Xe towards GPUVA is already ongoing.
|
||||
|
||||
As a key measurable result, Xe needs to be aligned with the GPU VA and working in
|
||||
our tree. Missing Nouveau patches should *not* block Xe and any needed GPUVA
|
||||
related patch should be independent and present on dri-devel or acked by
|
||||
maintainers to go along with the first Xe pull request towards drm-next.
|
||||
|
||||
DRM_VM_BIND
|
||||
-----------
|
||||
Nouveau, and Xe are all implementing ‘VM_BIND’ and new ‘Exec’ uAPIs in order to
|
||||
fulfill the needs of the modern uAPI. Xe merge should *not* be blocked on the
|
||||
development of a common new drm_infrastructure. However, the Xe team needs to
|
||||
engage with the community to explore the options of a common API.
|
||||
|
||||
As a key measurable result, the DRM_VM_BIND needs to be documented in this file
|
||||
below, or this entire block deleted if the consensus is for independent drivers
|
||||
vm_bind ioctls.
|
||||
|
||||
Although having a common DRM level IOCTL for VM_BIND is not a requirement to get
|
||||
Xe merged, it is mandatory to enforce the overall locking scheme for all major
|
||||
structs and list (so vm and vma). So, a consensus is needed, and possibly some
|
||||
common helpers. If helpers are needed, they should be also documented in this
|
||||
document.
|
||||
|
||||
ASYNC VM_BIND
|
||||
-------------
|
||||
Although having a common DRM level IOCTL for VM_BIND is not a requirement to get
|
||||
Xe merged, it is mandatory to have a consensus with other drivers and Mesa.
|
||||
It needs to be clear how to handle async VM_BIND and interactions with userspace
|
||||
memory fences. Ideally with helper support so people don't get it wrong in all
|
||||
possible ways.
|
||||
|
||||
As a key measurable result, the benefits of ASYNC VM_BIND and a discussion of
|
||||
various flavors, error handling and a sample API should be documented here or in
|
||||
a separate document pointed to by this document.
|
||||
|
||||
Userptr integration and vm_bind
|
||||
-------------------------------
|
||||
Different drivers implement different ways of dealing with execution of userptr.
|
||||
With multiple drivers currently introducing support to VM_BIND, the goal is to
|
||||
aim for a DRM consensus on what’s the best way to have that support. To some
|
||||
extent this is already getting addressed itself with the GPUVA where likely the
|
||||
userptr will be a GPUVA with a NULL GEM call VM bind directly on the userptr.
|
||||
However, there are more aspects around the rules for that and the usage of
|
||||
mmu_notifiers, locking and other aspects.
|
||||
|
||||
This task here has the goal of introducing a documentation of the basic rules.
|
||||
|
||||
The documentation *needs* to first live in this document (API session below) and
|
||||
then moved to another more specific document or at Xe level or at DRM level.
|
||||
|
||||
Documentation should include:
|
||||
|
||||
* The userptr part of the VM_BIND api.
|
||||
|
||||
* Locking, including the page-faulting case.
|
||||
|
||||
* O(1) complexity under VM_BIND.
|
||||
|
||||
Some parts of userptr like mmu_notifiers should become GPUVA or DRM helpers when
|
||||
the second driver supporting VM_BIND+userptr appears. Details to be defined when
|
||||
the time comes.
|
||||
|
||||
Long running compute: minimal data structure/scaffolding
|
||||
--------------------------------------------------------
|
||||
The generic scheduler code needs to include the handling of endless compute
|
||||
contexts, with the minimal scaffolding for preempt-ctx fences (probably on the
|
||||
drm_sched_entity) and making sure drm_scheduler can cope with the lack of job
|
||||
completion fence.
|
||||
|
||||
The goal is to achieve a consensus ahead of Xe initial pull-request, ideally with
|
||||
this minimal drm/scheduler work, if needed, merged to drm-misc in a way that any
|
||||
drm driver, including Xe, could re-use and add their own individual needs on top
|
||||
in a next stage. However, this should not block the initial merge.
|
||||
|
||||
This is a non-blocker item since the driver without the support for the long
|
||||
running compute enabled is not a showstopper.
|
||||
|
||||
Display integration with i915
|
||||
-----------------------------
|
||||
In order to share the display code with the i915 driver so that there is maximum
|
||||
reuse, the i915/display/ code is built twice, once for i915.ko and then for
|
||||
xe.ko. Currently, the i915/display code in Xe tree is polluted with many 'ifdefs'
|
||||
depending on the build target. The goal is to refactor both Xe and i915/display
|
||||
code simultaneously in order to get a clean result before they land upstream, so
|
||||
that display can already be part of the initial pull request towards drm-next.
|
||||
|
||||
However, display code should not gate the acceptance of Xe in upstream. Xe
|
||||
patches will be refactored in a way that display code can be removed, if needed,
|
||||
from the first pull request of Xe towards drm-next. The expectation is that when
|
||||
both drivers are part of the drm-tip, the introduction of cleaner patches will be
|
||||
easier and speed up.
|
||||
|
||||
Drm_exec
|
||||
--------
|
||||
Helper to make dma_resv locking for a big number of buffers is getting removed in
|
||||
the drm_exec series proposed in https://patchwork.freedesktop.org/patch/524376/
|
||||
If that happens, Xe needs to change and incorporate the changes in the driver.
|
||||
The goal is to engage with the Community to understand if the best approach is to
|
||||
move that to the drivers that are using it or if we should keep the helpers in
|
||||
place waiting for Xe to get merged.
|
||||
|
||||
This item ties into the GPUVA, VM_BIND, and even long-running compute support.
|
||||
|
||||
As a key measurable result, we need to have a community consensus documented in
|
||||
this document and the Xe driver prepared for the changes, if necessary.
|
||||
|
||||
Dev_coredump
|
||||
------------
|
||||
|
||||
Xe needs to align with other drivers on the way that the error states are
|
||||
dumped, avoiding a Xe only error_state solution. The goal is to use devcoredump
|
||||
infrastructure to report error states, since it produces a standardized way
|
||||
by exposing a virtual and temporary /sys/class/devcoredump device.
|
||||
|
||||
As the key measurable result, Xe driver needs to provide GPU snapshots captured
|
||||
at hang time through devcoredump, but without depending on any core modification
|
||||
of devcoredump infrastructure itself.
|
||||
|
||||
Later, when we are in-tree, the goal is to collaborate with devcoredump
|
||||
infrastructure with overall possible improvements, like multiple file support
|
||||
for better organization of the dumps, snapshot support, dmesg extra print,
|
||||
and whatever may make sense and help the overall infrastructure.
|
||||
|
||||
Xe – uAPI high level overview
|
||||
=============================
|
||||
|
||||
...Warning: To be done in follow up patches after/when/where the main consensus in various items are individually reached.
|
@ -276,11 +276,8 @@ Various hold-ups:
|
||||
- Need to switch to drm_fbdev_generic_setup(), otherwise a lot of the custom fb
|
||||
setup code can't be deleted.
|
||||
|
||||
- Many drivers wrap drm_gem_fb_create() only to check for valid formats. For
|
||||
atomic drivers we could check for valid formats by calling
|
||||
drm_plane_check_pixel_format() against all planes, and pass if any plane
|
||||
supports the format. For non-atomic that's not possible since like the format
|
||||
list for the primary plane is fake and we'd therefor reject valid formats.
|
||||
- Need to switch to drm_gem_fb_create(), as now drm_gem_fb_create() checks for
|
||||
valid formats for atomic drivers.
|
||||
|
||||
- Many drivers subclass drm_framebuffer, we'd need a embedding compatible
|
||||
version of the varios drm_gem_fb_create functions. Maybe called
|
||||
|
@ -118,14 +118,9 @@ Add Plane Features
|
||||
|
||||
There's lots of plane features we could add support for:
|
||||
|
||||
- ARGB format on primary plane: blend the primary plane into background with
|
||||
translucent alpha.
|
||||
|
||||
- Add background color KMS property[Good to get started].
|
||||
|
||||
- Full alpha blending on all planes.
|
||||
|
||||
- Rotation, scaling.
|
||||
- Scaling.
|
||||
|
||||
- Additional buffer formats, especially YUV formats for video like NV12.
|
||||
Low/high bpp RGB formats would also be interesting.
|
||||
|
14
MAINTAINERS
14
MAINTAINERS
@ -6604,6 +6604,7 @@ M: Rob Clark <robdclark@gmail.com>
|
||||
M: Abhinav Kumar <quic_abhinavk@quicinc.com>
|
||||
M: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
R: Sean Paul <sean@poorly.run>
|
||||
R: Marijn Suijten <marijn.suijten@somainline.org>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
L: freedreno@lists.freedesktop.org
|
||||
@ -6724,6 +6725,12 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/display/panel/samsung,s6d27a1.yaml
|
||||
F: drivers/gpu/drm/panel/panel-samsung-s6d27a1.c
|
||||
|
||||
DRM DRIVER FOR SAMSUNG S6D7AA0 PANELS
|
||||
M: Artur Weber <aweber.kernel@gmail.com>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/display/panel/samsung,s6d7aa0.yaml
|
||||
F: drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c
|
||||
|
||||
DRM DRIVER FOR SITRONIX ST7586 PANELS
|
||||
M: David Lechner <david@lechnology.com>
|
||||
S: Maintained
|
||||
@ -6796,6 +6803,7 @@ F: drivers/gpu/drm/udl/
|
||||
DRM DRIVER FOR VIRTUAL KERNEL MODESETTING (VKMS)
|
||||
M: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com>
|
||||
M: Melissa Wen <melissa.srw@gmail.com>
|
||||
M: Maíra Canal <mairacanal@riseup.net>
|
||||
R: Haneen Mohammed <hamohammed.sa@gmail.com>
|
||||
R: Daniel Vetter <daniel@ffwll.ch>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
@ -6898,6 +6906,7 @@ S: Maintained
|
||||
T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||
F: Documentation/devicetree/bindings/display/bridge/
|
||||
F: drivers/gpu/drm/bridge/
|
||||
F: drivers/gpu/drm/drm_bridge.c
|
||||
F: include/drm/drm_bridge.h
|
||||
|
||||
DRM DRIVERS FOR EXYNOS
|
||||
@ -7006,8 +7015,7 @@ F: Documentation/devicetree/bindings/display/bridge/renesas,dsi-csi2-tx.yaml
|
||||
F: Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.yaml
|
||||
F: Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml
|
||||
F: Documentation/devicetree/bindings/display/renesas,du.yaml
|
||||
F: drivers/gpu/drm/rcar-du/
|
||||
F: drivers/gpu/drm/shmobile/
|
||||
F: drivers/gpu/drm/renesas/
|
||||
F: include/linux/platform_data/shmob_drm.h
|
||||
|
||||
DRM DRIVERS FOR ROCKCHIP
|
||||
@ -17486,6 +17494,8 @@ F: include/dt-bindings/clock/qcom,*
|
||||
|
||||
QUALCOMM CLOUD AI (QAIC) DRIVER
|
||||
M: Jeffrey Hugo <quic_jhugo@quicinc.com>
|
||||
R: Carl Vanderlip <quic_carlv@quicinc.com>
|
||||
R: Pranjal Ramajor Asha Kanojiya <quic_pkanojiy@quicinc.com>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Supported
|
||||
|
@ -1,20 +1,8 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
}
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
@ -1,19 +1,6 @@
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
}
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
@ -5,19 +5,6 @@
|
||||
#ifndef __ASM_FB_H_
|
||||
#define __ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
}
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* __ASM_FB_H_ */
|
||||
|
@ -2,11 +2,14 @@
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/efi.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
|
||||
struct file;
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
@ -15,10 +18,26 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
else
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
}
|
||||
#define fb_pgprotect fb_pgprotect
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n)
|
||||
{
|
||||
return 0;
|
||||
memcpy(to, (void __force *)from, n);
|
||||
}
|
||||
#define fb_memcpy_fromio fb_memcpy_fromio
|
||||
|
||||
static inline void fb_memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
|
||||
{
|
||||
memcpy((void __force *)to, from, n);
|
||||
}
|
||||
#define fb_memcpy_toio fb_memcpy_toio
|
||||
|
||||
static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n)
|
||||
{
|
||||
memset((void __force *)addr, c, n);
|
||||
}
|
||||
#define fb_memset fb_memset_io
|
||||
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
@ -5,19 +5,27 @@
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n)
|
||||
{
|
||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
memcpy(to, (void __force *)from, n);
|
||||
}
|
||||
#define fb_memcpy_fromio fb_memcpy_fromio
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
static inline void fb_memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
|
||||
{
|
||||
return 0;
|
||||
memcpy((void __force *)to, from, n);
|
||||
}
|
||||
#define fb_memcpy_toio fb_memcpy_toio
|
||||
|
||||
static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n)
|
||||
{
|
||||
memset((void __force *)addr, c, n);
|
||||
}
|
||||
#define fb_memset fb_memset_io
|
||||
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
@ -2,22 +2,18 @@
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
struct file;
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
#ifdef CONFIG_MMU
|
||||
#ifdef CONFIG_SUN3
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
pgprot_val(vma->vm_page_prot) |= SUN3_PAGE_NOCACHE;
|
||||
}
|
||||
#else
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
if (CPU_IS_020_OR_030)
|
||||
pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE030;
|
||||
if (CPU_IS_040_OR_060) {
|
||||
@ -25,15 +21,11 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
/* Use no-cache mode, serialized */
|
||||
pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE_S;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_SUN3 */
|
||||
#else
|
||||
#define fb_pgprotect(...) do {} while (0)
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#define fb_pgprotect fb_pgprotect
|
||||
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
@ -1,19 +1,39 @@
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
struct file;
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
}
|
||||
#define fb_pgprotect fb_pgprotect
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
/*
|
||||
* MIPS doesn't define __raw_ I/O macros, so the helpers
|
||||
* in <asm-generic/fb.h> don't generate fb_readq() and
|
||||
* fb_write(). We have to provide them here.
|
||||
*
|
||||
* TODO: Convert MIPS to generic I/O. The helpers below can
|
||||
* then be removed.
|
||||
*/
|
||||
#ifdef CONFIG_64BIT
|
||||
static inline u64 fb_readq(const volatile void __iomem *addr)
|
||||
{
|
||||
return 0;
|
||||
return __raw_readq(addr);
|
||||
}
|
||||
#define fb_readq fb_readq
|
||||
|
||||
static inline void fb_writeq(u64 b, volatile void __iomem *addr)
|
||||
{
|
||||
__raw_writeq(b, addr);
|
||||
}
|
||||
#define fb_writeq fb_writeq
|
||||
#endif
|
||||
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
@ -11,7 +11,7 @@
|
||||
# Copyright (C) 1994 by Linus Torvalds
|
||||
# Portions Copyright (C) 1999 The Puffin Group
|
||||
#
|
||||
# Modified for PA-RISC Linux by Paul Lahaie, Alex deVries,
|
||||
# Modified for PA-RISC Linux by Paul Lahaie, Alex deVries,
|
||||
# Mike Shaver, Helge Deller and Martin K. Petersen
|
||||
#
|
||||
|
||||
@ -119,6 +119,8 @@ export LIBGCC
|
||||
|
||||
libs-y += arch/parisc/lib/ $(LIBGCC)
|
||||
|
||||
drivers-y += arch/parisc/video/
|
||||
|
||||
boot := arch/parisc/boot
|
||||
|
||||
PALO := $(shell if (which palo 2>&1); then : ; \
|
||||
|
@ -2,23 +2,13 @@
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
struct fb_info;
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_FB_STI)
|
||||
#if defined(CONFIG_STI_CORE)
|
||||
int fb_is_primary_device(struct fb_info *info);
|
||||
#else
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#define fb_is_primary_device fb_is_primary_device
|
||||
#endif
|
||||
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
3
arch/parisc/video/Makefile
Normal file
3
arch/parisc/video/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
obj-$(CONFIG_STI_CORE) += fbdev.o
|
26
arch/parisc/video/fbdev.c
Normal file
26
arch/parisc/video/fbdev.c
Normal file
@ -0,0 +1,26 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
|
||||
* Copyright (C) 2001-2020 Helge Deller <deller@gmx.de>
|
||||
* Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
*/
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <video/sticore.h>
|
||||
|
||||
int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
struct sti_struct *sti;
|
||||
|
||||
sti = sti_get_rom(0);
|
||||
|
||||
/* if no built-in graphics card found, allow any fb driver as default */
|
||||
if (!sti)
|
||||
return true;
|
||||
|
||||
/* return true if it's the default built-in framebuffer driver */
|
||||
return (sti->info == info);
|
||||
}
|
||||
EXPORT_SYMBOL(fb_is_primary_device);
|
@ -2,8 +2,8 @@
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
@ -13,10 +13,8 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
vma->vm_end - vma->vm_start,
|
||||
vma->vm_page_prot);
|
||||
}
|
||||
#define fb_pgprotect fb_pgprotect
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
@ -2,19 +2,6 @@
|
||||
#ifndef _ASM_FB_H_
|
||||
#define _ASM_FB_H_
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
}
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_FB_H_ */
|
||||
|
@ -60,6 +60,7 @@ libs-y += arch/sparc/prom/
|
||||
libs-y += arch/sparc/lib/
|
||||
|
||||
drivers-$(CONFIG_PM) += arch/sparc/power/
|
||||
drivers-$(CONFIG_FB) += arch/sparc/video/
|
||||
|
||||
boot := arch/sparc/boot
|
||||
|
||||
|
@ -1,34 +1,41 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _SPARC_FB_H_
|
||||
#define _SPARC_FB_H_
|
||||
#include <linux/console.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/prom.h>
|
||||
|
||||
#include <linux/io.h>
|
||||
|
||||
struct fb_info;
|
||||
struct file;
|
||||
struct vm_area_struct;
|
||||
|
||||
#ifdef CONFIG_SPARC32
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
#ifdef CONFIG_SPARC64
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
{ }
|
||||
#define fb_pgprotect fb_pgprotect
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int fb_is_primary_device(struct fb_info *info)
|
||||
int fb_is_primary_device(struct fb_info *info);
|
||||
#define fb_is_primary_device fb_is_primary_device
|
||||
|
||||
static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n)
|
||||
{
|
||||
struct device *dev = info->device;
|
||||
struct device_node *node;
|
||||
|
||||
if (console_set_on_cmdline)
|
||||
return 0;
|
||||
|
||||
node = dev->of_node;
|
||||
if (node &&
|
||||
node == of_console_device)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
sbus_memcpy_fromio(to, from, n);
|
||||
}
|
||||
#define fb_memcpy_fromio fb_memcpy_fromio
|
||||
|
||||
static inline void fb_memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
|
||||
{
|
||||
sbus_memcpy_toio(to, from, n);
|
||||
}
|
||||
#define fb_memcpy_toio fb_memcpy_toio
|
||||
|
||||
static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n)
|
||||
{
|
||||
sbus_memset_io(addr, c, n);
|
||||
}
|
||||
#define fb_memset fb_memset_io
|
||||
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _SPARC_FB_H_ */
|
||||
|
3
arch/sparc/video/Makefile
Normal file
3
arch/sparc/video/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
obj-$(CONFIG_FB) += fbdev.o
|
23
arch/sparc/video/fbdev.c
Normal file
23
arch/sparc/video/fbdev.c
Normal file
@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/console.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/prom.h>
|
||||
|
||||
int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
struct device *dev = info->device;
|
||||
struct device_node *node;
|
||||
|
||||
if (console_set_on_cmdline)
|
||||
return 0;
|
||||
|
||||
node = dev->of_node;
|
||||
if (node && node == of_console_device)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(fb_is_primary_device);
|
@ -2,21 +2,16 @@
|
||||
#ifndef _ASM_X86_FB_H
|
||||
#define _ASM_X86_FB_H
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/page.h>
|
||||
struct fb_info;
|
||||
struct file;
|
||||
struct vm_area_struct;
|
||||
|
||||
static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
|
||||
unsigned long off)
|
||||
{
|
||||
unsigned long prot;
|
||||
void fb_pgprotect(struct file *file, struct vm_area_struct *vma, unsigned long off);
|
||||
#define fb_pgprotect fb_pgprotect
|
||||
|
||||
prot = pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK;
|
||||
if (boot_cpu_data.x86 > 3)
|
||||
pgprot_val(vma->vm_page_prot) =
|
||||
prot | cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS);
|
||||
}
|
||||
int fb_is_primary_device(struct fb_info *info);
|
||||
#define fb_is_primary_device fb_is_primary_device
|
||||
|
||||
extern int fb_is_primary_device(struct fb_info *info);
|
||||
#include <asm-generic/fb.h>
|
||||
|
||||
#endif /* _ASM_X86_FB_H */
|
||||
|
@ -6,36 +6,38 @@
|
||||
* for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/vgaarb.h>
|
||||
#include <asm/fb.h>
|
||||
|
||||
void fb_pgprotect(struct file *file, struct vm_area_struct *vma, unsigned long off)
|
||||
{
|
||||
unsigned long prot;
|
||||
|
||||
prot = pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK;
|
||||
if (boot_cpu_data.x86 > 3)
|
||||
pgprot_val(vma->vm_page_prot) =
|
||||
prot | cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS);
|
||||
}
|
||||
EXPORT_SYMBOL(fb_pgprotect);
|
||||
|
||||
int fb_is_primary_device(struct fb_info *info)
|
||||
{
|
||||
struct device *device = info->device;
|
||||
struct pci_dev *default_device = vga_default_device();
|
||||
struct pci_dev *pci_dev;
|
||||
struct resource *res;
|
||||
|
||||
if (!device || !dev_is_pci(device))
|
||||
return 0;
|
||||
|
||||
pci_dev = to_pci_dev(device);
|
||||
|
||||
if (default_device) {
|
||||
if (pci_dev == default_device)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
res = pci_dev->resource + PCI_ROM_RESOURCE;
|
||||
|
||||
if (res->flags & IORESOURCE_ROM_SHADOW)
|
||||
if (pci_dev == vga_default_device())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(fb_is_primary_device);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -27,12 +27,6 @@ static int cb_map_mem(struct hl_ctx *ctx, struct hl_cb *cb)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!hdev->mmu_enable) {
|
||||
dev_err_ratelimited(hdev->dev,
|
||||
"Cannot map CB because MMU is disabled\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cb->is_mmu_mapped)
|
||||
return 0;
|
||||
|
||||
|
@ -280,14 +280,8 @@ bool cs_needs_timeout(struct hl_cs *cs)
|
||||
|
||||
static bool is_cb_patched(struct hl_device *hdev, struct hl_cs_job *job)
|
||||
{
|
||||
/*
|
||||
* Patched CB is created for external queues jobs, and for H/W queues
|
||||
* jobs if the user CB was allocated by driver and MMU is disabled.
|
||||
*/
|
||||
return (job->queue_type == QUEUE_TYPE_EXT ||
|
||||
(job->queue_type == QUEUE_TYPE_HW &&
|
||||
job->is_kernel_allocated_cb &&
|
||||
!hdev->mmu_enable));
|
||||
/* Patched CB is created for external queues jobs */
|
||||
return (job->queue_type == QUEUE_TYPE_EXT);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -363,14 +357,13 @@ static void hl_complete_job(struct hl_device *hdev, struct hl_cs_job *job)
|
||||
}
|
||||
}
|
||||
|
||||
/* For H/W queue jobs, if a user CB was allocated by driver and MMU is
|
||||
* enabled, the user CB isn't released in cs_parser() and thus should be
|
||||
/* For H/W queue jobs, if a user CB was allocated by driver,
|
||||
* the user CB isn't released in cs_parser() and thus should be
|
||||
* released here. This is also true for INT queues jobs which were
|
||||
* allocated by driver.
|
||||
*/
|
||||
if ((job->is_kernel_allocated_cb &&
|
||||
((job->queue_type == QUEUE_TYPE_HW && hdev->mmu_enable) ||
|
||||
job->queue_type == QUEUE_TYPE_INT))) {
|
||||
if (job->is_kernel_allocated_cb &&
|
||||
(job->queue_type == QUEUE_TYPE_HW || job->queue_type == QUEUE_TYPE_INT)) {
|
||||
atomic_dec(&job->user_cb->cs_cnt);
|
||||
hl_cb_put(job->user_cb);
|
||||
}
|
||||
@ -804,12 +797,14 @@ out:
|
||||
|
||||
static void cs_timedout(struct work_struct *work)
|
||||
{
|
||||
struct hl_cs *cs = container_of(work, struct hl_cs, work_tdr.work);
|
||||
bool skip_reset_on_timeout, device_reset = false;
|
||||
struct hl_device *hdev;
|
||||
u64 event_mask = 0x0;
|
||||
uint timeout_sec;
|
||||
int rc;
|
||||
struct hl_cs *cs = container_of(work, struct hl_cs,
|
||||
work_tdr.work);
|
||||
bool skip_reset_on_timeout = cs->skip_reset_on_timeout, device_reset = false;
|
||||
|
||||
skip_reset_on_timeout = cs->skip_reset_on_timeout;
|
||||
|
||||
rc = cs_get_unless_zero(cs);
|
||||
if (!rc)
|
||||
@ -840,29 +835,31 @@ static void cs_timedout(struct work_struct *work)
|
||||
event_mask |= HL_NOTIFIER_EVENT_CS_TIMEOUT;
|
||||
}
|
||||
|
||||
timeout_sec = jiffies_to_msecs(hdev->timeout_jiffies) / 1000;
|
||||
|
||||
switch (cs->type) {
|
||||
case CS_TYPE_SIGNAL:
|
||||
dev_err(hdev->dev,
|
||||
"Signal command submission %llu has not finished in time!\n",
|
||||
cs->sequence);
|
||||
"Signal command submission %llu has not finished in %u seconds!\n",
|
||||
cs->sequence, timeout_sec);
|
||||
break;
|
||||
|
||||
case CS_TYPE_WAIT:
|
||||
dev_err(hdev->dev,
|
||||
"Wait command submission %llu has not finished in time!\n",
|
||||
cs->sequence);
|
||||
"Wait command submission %llu has not finished in %u seconds!\n",
|
||||
cs->sequence, timeout_sec);
|
||||
break;
|
||||
|
||||
case CS_TYPE_COLLECTIVE_WAIT:
|
||||
dev_err(hdev->dev,
|
||||
"Collective Wait command submission %llu has not finished in time!\n",
|
||||
cs->sequence);
|
||||
"Collective Wait command submission %llu has not finished in %u seconds!\n",
|
||||
cs->sequence, timeout_sec);
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(hdev->dev,
|
||||
"Command submission %llu has not finished in time!\n",
|
||||
cs->sequence);
|
||||
"Command submission %llu has not finished in %u seconds!\n",
|
||||
cs->sequence, timeout_sec);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1139,11 +1136,10 @@ static void force_complete_cs(struct hl_device *hdev)
|
||||
spin_unlock(&hdev->cs_mirror_lock);
|
||||
}
|
||||
|
||||
void hl_abort_waitings_for_completion(struct hl_device *hdev)
|
||||
void hl_abort_waiting_for_cs_completions(struct hl_device *hdev)
|
||||
{
|
||||
force_complete_cs(hdev);
|
||||
force_complete_multi_cs(hdev);
|
||||
hl_release_pending_user_interrupts(hdev);
|
||||
}
|
||||
|
||||
static void job_wq_completion(struct work_struct *work)
|
||||
@ -1948,8 +1944,7 @@ static int cs_ioctl_signal_wait_create_jobs(struct hl_device *hdev,
|
||||
else
|
||||
cb_size = hdev->asic_funcs->get_signal_cb_size(hdev);
|
||||
|
||||
cb = hl_cb_kernel_create(hdev, cb_size,
|
||||
q_type == QUEUE_TYPE_HW && hdev->mmu_enable);
|
||||
cb = hl_cb_kernel_create(hdev, cb_size, q_type == QUEUE_TYPE_HW);
|
||||
if (!cb) {
|
||||
atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt);
|
||||
atomic64_inc(&cntr->out_of_mem_drop_cnt);
|
||||
@ -2152,7 +2147,7 @@ static int cs_ioctl_unreserve_signals(struct hl_fpriv *hpriv, u32 handle_id)
|
||||
|
||||
hdev->asic_funcs->hw_queues_unlock(hdev);
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2167,15 +2162,21 @@ static int cs_ioctl_unreserve_signals(struct hl_fpriv *hpriv, u32 handle_id)
|
||||
|
||||
/* Release the id and free allocated memory of the handle */
|
||||
idr_remove(&mgr->handles, handle_id);
|
||||
|
||||
/* unlock before calling ctx_put, where we might sleep */
|
||||
spin_unlock(&mgr->lock);
|
||||
hl_ctx_put(encaps_sig_hdl->ctx);
|
||||
kfree(encaps_sig_hdl);
|
||||
goto out;
|
||||
} else {
|
||||
rc = -EINVAL;
|
||||
dev_err(hdev->dev, "failed to unreserve signals, cannot find handler\n");
|
||||
}
|
||||
out:
|
||||
|
||||
out_unlock:
|
||||
spin_unlock(&mgr->lock);
|
||||
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -255,9 +255,6 @@ static int vm_show(struct seq_file *s, void *data)
|
||||
u64 j;
|
||||
int i;
|
||||
|
||||
if (!dev_entry->hdev->mmu_enable)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&dev_entry->ctx_mem_hash_mutex);
|
||||
|
||||
list_for_each_entry(ctx, &dev_entry->ctx_mem_hash_list, debugfs_list) {
|
||||
@ -436,9 +433,6 @@ static int mmu_show(struct seq_file *s, void *data)
|
||||
u64 virt_addr = dev_entry->mmu_addr, phys_addr;
|
||||
int i;
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
return 0;
|
||||
|
||||
if (dev_entry->mmu_asid == HL_KERNEL_ASID_ID)
|
||||
ctx = hdev->kernel_ctx;
|
||||
else
|
||||
@ -496,9 +490,6 @@ static ssize_t mmu_asid_va_write(struct file *file, const char __user *buf,
|
||||
char *c;
|
||||
ssize_t rc;
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
return count;
|
||||
|
||||
if (count > sizeof(kbuf) - 1)
|
||||
goto err;
|
||||
if (copy_from_user(kbuf, buf, count))
|
||||
@ -535,9 +526,6 @@ static int mmu_ack_error(struct seq_file *s, void *data)
|
||||
struct hl_device *hdev = dev_entry->hdev;
|
||||
int rc;
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
return 0;
|
||||
|
||||
if (!dev_entry->mmu_cap_mask) {
|
||||
dev_err(hdev->dev, "mmu_cap_mask is not set\n");
|
||||
goto err;
|
||||
@ -563,9 +551,6 @@ static ssize_t mmu_ack_error_value_write(struct file *file,
|
||||
char kbuf[MMU_KBUF_SIZE];
|
||||
ssize_t rc;
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
return count;
|
||||
|
||||
if (count > sizeof(kbuf) - 1)
|
||||
goto err;
|
||||
|
||||
@ -661,9 +646,6 @@ static bool hl_is_device_va(struct hl_device *hdev, u64 addr)
|
||||
{
|
||||
struct asic_fixed_properties *prop = &hdev->asic_prop;
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
goto out;
|
||||
|
||||
if (prop->dram_supports_virtual_memory &&
|
||||
(addr >= prop->dmmu.start_addr && addr < prop->dmmu.end_addr))
|
||||
return true;
|
||||
@ -675,7 +657,7 @@ static bool hl_is_device_va(struct hl_device *hdev, u64 addr)
|
||||
if (addr >= prop->pmmu_huge.start_addr &&
|
||||
addr < prop->pmmu_huge.end_addr)
|
||||
return true;
|
||||
out:
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -685,9 +667,6 @@ static bool hl_is_device_internal_memory_va(struct hl_device *hdev, u64 addr,
|
||||
struct asic_fixed_properties *prop = &hdev->asic_prop;
|
||||
u64 dram_start_addr, dram_end_addr;
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
return false;
|
||||
|
||||
if (prop->dram_supports_virtual_memory) {
|
||||
dram_start_addr = prop->dmmu.start_addr;
|
||||
dram_end_addr = prop->dmmu.end_addr;
|
||||
@ -1756,17 +1735,15 @@ static void add_files_to_device(struct hl_device *hdev, struct hl_dbg_device_ent
|
||||
}
|
||||
}
|
||||
|
||||
void hl_debugfs_add_device(struct hl_device *hdev)
|
||||
int hl_debugfs_device_init(struct hl_device *hdev)
|
||||
{
|
||||
struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
|
||||
int count = ARRAY_SIZE(hl_debugfs_list);
|
||||
|
||||
dev_entry->hdev = hdev;
|
||||
dev_entry->entry_arr = kmalloc_array(count,
|
||||
sizeof(struct hl_debugfs_entry),
|
||||
GFP_KERNEL);
|
||||
dev_entry->entry_arr = kmalloc_array(count, sizeof(struct hl_debugfs_entry), GFP_KERNEL);
|
||||
if (!dev_entry->entry_arr)
|
||||
return;
|
||||
return -ENOMEM;
|
||||
|
||||
dev_entry->data_dma_blob_desc.size = 0;
|
||||
dev_entry->data_dma_blob_desc.data = NULL;
|
||||
@ -1787,21 +1764,14 @@ void hl_debugfs_add_device(struct hl_device *hdev)
|
||||
spin_lock_init(&dev_entry->userptr_spinlock);
|
||||
mutex_init(&dev_entry->ctx_mem_hash_mutex);
|
||||
|
||||
dev_entry->root = debugfs_create_dir(dev_name(hdev->dev),
|
||||
hl_debug_root);
|
||||
|
||||
add_files_to_device(hdev, dev_entry, dev_entry->root);
|
||||
if (!hdev->asic_prop.fw_security_enabled)
|
||||
add_secured_nodes(dev_entry, dev_entry->root);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hl_debugfs_remove_device(struct hl_device *hdev)
|
||||
void hl_debugfs_device_fini(struct hl_device *hdev)
|
||||
{
|
||||
struct hl_dbg_device_entry *entry = &hdev->hl_debugfs;
|
||||
int i;
|
||||
|
||||
debugfs_remove_recursive(entry->root);
|
||||
|
||||
mutex_destroy(&entry->ctx_mem_hash_mutex);
|
||||
mutex_destroy(&entry->file_mutex);
|
||||
|
||||
@ -1814,6 +1784,24 @@ void hl_debugfs_remove_device(struct hl_device *hdev)
|
||||
kfree(entry->entry_arr);
|
||||
}
|
||||
|
||||
void hl_debugfs_add_device(struct hl_device *hdev)
|
||||
{
|
||||
struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
|
||||
|
||||
dev_entry->root = debugfs_create_dir(dev_name(hdev->dev), hl_debug_root);
|
||||
|
||||
add_files_to_device(hdev, dev_entry, dev_entry->root);
|
||||
if (!hdev->asic_prop.fw_security_enabled)
|
||||
add_secured_nodes(dev_entry, dev_entry->root);
|
||||
}
|
||||
|
||||
void hl_debugfs_remove_device(struct hl_device *hdev)
|
||||
{
|
||||
struct hl_dbg_device_entry *entry = &hdev->hl_debugfs;
|
||||
|
||||
debugfs_remove_recursive(entry->root);
|
||||
}
|
||||
|
||||
void hl_debugfs_add_file(struct hl_fpriv *hpriv)
|
||||
{
|
||||
struct hl_dbg_device_entry *dev_entry = &hpriv->hdev->hl_debugfs;
|
||||
|
@ -674,7 +674,7 @@ static int device_init_cdev(struct hl_device *hdev, struct class *class,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int device_cdev_sysfs_add(struct hl_device *hdev)
|
||||
static int cdev_sysfs_debugfs_add(struct hl_device *hdev)
|
||||
{
|
||||
int rc;
|
||||
|
||||
@ -699,7 +699,9 @@ static int device_cdev_sysfs_add(struct hl_device *hdev)
|
||||
goto delete_ctrl_cdev_device;
|
||||
}
|
||||
|
||||
hdev->cdev_sysfs_created = true;
|
||||
hl_debugfs_add_device(hdev);
|
||||
|
||||
hdev->cdev_sysfs_debugfs_created = true;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -710,11 +712,12 @@ delete_cdev_device:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void device_cdev_sysfs_del(struct hl_device *hdev)
|
||||
static void cdev_sysfs_debugfs_remove(struct hl_device *hdev)
|
||||
{
|
||||
if (!hdev->cdev_sysfs_created)
|
||||
if (!hdev->cdev_sysfs_debugfs_created)
|
||||
goto put_devices;
|
||||
|
||||
hl_debugfs_remove_device(hdev);
|
||||
hl_sysfs_fini(hdev);
|
||||
cdev_device_del(&hdev->cdev_ctrl, hdev->dev_ctrl);
|
||||
cdev_device_del(&hdev->cdev, hdev->dev);
|
||||
@ -981,6 +984,18 @@ static void device_early_fini(struct hl_device *hdev)
|
||||
hdev->asic_funcs->early_fini(hdev);
|
||||
}
|
||||
|
||||
static bool is_pci_link_healthy(struct hl_device *hdev)
|
||||
{
|
||||
u16 vendor_id;
|
||||
|
||||
if (!hdev->pdev)
|
||||
return false;
|
||||
|
||||
pci_read_config_word(hdev->pdev, PCI_VENDOR_ID, &vendor_id);
|
||||
|
||||
return (vendor_id == PCI_VENDOR_ID_HABANALABS);
|
||||
}
|
||||
|
||||
static void hl_device_heartbeat(struct work_struct *work)
|
||||
{
|
||||
struct hl_device *hdev = container_of(work, struct hl_device,
|
||||
@ -995,7 +1010,8 @@ static void hl_device_heartbeat(struct work_struct *work)
|
||||
goto reschedule;
|
||||
|
||||
if (hl_device_operational(hdev, NULL))
|
||||
dev_err(hdev->dev, "Device heartbeat failed!\n");
|
||||
dev_err(hdev->dev, "Device heartbeat failed! PCI link is %s\n",
|
||||
is_pci_link_healthy(hdev) ? "healthy" : "broken");
|
||||
|
||||
info.err_type = HL_INFO_FW_HEARTBEAT_ERR;
|
||||
info.event_mask = &event_mask;
|
||||
@ -1157,6 +1173,16 @@ static void take_release_locks(struct hl_device *hdev)
|
||||
mutex_unlock(&hdev->fpriv_ctrl_list_lock);
|
||||
}
|
||||
|
||||
static void hl_abort_waiting_for_completions(struct hl_device *hdev)
|
||||
{
|
||||
hl_abort_waiting_for_cs_completions(hdev);
|
||||
|
||||
/* Release all pending user interrupts, each pending user interrupt
|
||||
* holds a reference to a user context.
|
||||
*/
|
||||
hl_release_pending_user_interrupts(hdev);
|
||||
}
|
||||
|
||||
static void cleanup_resources(struct hl_device *hdev, bool hard_reset, bool fw_reset,
|
||||
bool skip_wq_flush)
|
||||
{
|
||||
@ -1176,10 +1202,7 @@ static void cleanup_resources(struct hl_device *hdev, bool hard_reset, bool fw_r
|
||||
/* flush the MMU prefetch workqueue */
|
||||
flush_workqueue(hdev->prefetch_wq);
|
||||
|
||||
/* Release all pending user interrupts, each pending user interrupt
|
||||
* holds a reference to user context
|
||||
*/
|
||||
hl_release_pending_user_interrupts(hdev);
|
||||
hl_abort_waiting_for_completions(hdev);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1921,7 +1944,7 @@ out:
|
||||
|
||||
hl_ctx_put(ctx);
|
||||
|
||||
hl_abort_waitings_for_completion(hdev);
|
||||
hl_abort_waiting_for_completions(hdev);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -2034,7 +2057,7 @@ out_err:
|
||||
int hl_device_init(struct hl_device *hdev)
|
||||
{
|
||||
int i, rc, cq_cnt, user_interrupt_cnt, cq_ready_cnt;
|
||||
bool add_cdev_sysfs_on_err = false;
|
||||
bool expose_interfaces_on_err = false;
|
||||
|
||||
rc = create_cdev(hdev);
|
||||
if (rc)
|
||||
@ -2150,16 +2173,22 @@ int hl_device_init(struct hl_device *hdev)
|
||||
hdev->device_release_watchdog_timeout_sec = HL_DEVICE_RELEASE_WATCHDOG_TIMEOUT_SEC;
|
||||
|
||||
hdev->memory_scrub_val = MEM_SCRUB_DEFAULT_VAL;
|
||||
hl_debugfs_add_device(hdev);
|
||||
|
||||
/* debugfs nodes are created in hl_ctx_init so it must be called after
|
||||
* hl_debugfs_add_device.
|
||||
rc = hl_debugfs_device_init(hdev);
|
||||
if (rc) {
|
||||
dev_err(hdev->dev, "failed to initialize debugfs entry structure\n");
|
||||
kfree(hdev->kernel_ctx);
|
||||
goto mmu_fini;
|
||||
}
|
||||
|
||||
/* The debugfs entry structure is accessed in hl_ctx_init(), so it must be called after
|
||||
* hl_debugfs_device_init().
|
||||
*/
|
||||
rc = hl_ctx_init(hdev, hdev->kernel_ctx, true);
|
||||
if (rc) {
|
||||
dev_err(hdev->dev, "failed to initialize kernel context\n");
|
||||
kfree(hdev->kernel_ctx);
|
||||
goto remove_device_from_debugfs;
|
||||
goto debugfs_device_fini;
|
||||
}
|
||||
|
||||
rc = hl_cb_pool_init(hdev);
|
||||
@ -2175,11 +2204,10 @@ int hl_device_init(struct hl_device *hdev)
|
||||
}
|
||||
|
||||
/*
|
||||
* From this point, override rc (=0) in case of an error to allow
|
||||
* debugging (by adding char devices and create sysfs nodes as part of
|
||||
* the error flow).
|
||||
* From this point, override rc (=0) in case of an error to allow debugging
|
||||
* (by adding char devices and creating sysfs/debugfs files as part of the error flow).
|
||||
*/
|
||||
add_cdev_sysfs_on_err = true;
|
||||
expose_interfaces_on_err = true;
|
||||
|
||||
/* Device is now enabled as part of the initialization requires
|
||||
* communication with the device firmware to get information that
|
||||
@ -2221,15 +2249,13 @@ int hl_device_init(struct hl_device *hdev)
|
||||
}
|
||||
|
||||
/*
|
||||
* Expose devices and sysfs nodes to user.
|
||||
* From here there is no need to add char devices and create sysfs nodes
|
||||
* in case of an error.
|
||||
* Expose devices and sysfs/debugfs files to user.
|
||||
* From here there is no need to expose them in case of an error.
|
||||
*/
|
||||
add_cdev_sysfs_on_err = false;
|
||||
rc = device_cdev_sysfs_add(hdev);
|
||||
expose_interfaces_on_err = false;
|
||||
rc = cdev_sysfs_debugfs_add(hdev);
|
||||
if (rc) {
|
||||
dev_err(hdev->dev,
|
||||
"Failed to add char devices and sysfs nodes\n");
|
||||
dev_err(hdev->dev, "Failed to add char devices and sysfs/debugfs files\n");
|
||||
rc = 0;
|
||||
goto out_disabled;
|
||||
}
|
||||
@ -2275,8 +2301,8 @@ release_ctx:
|
||||
if (hl_ctx_put(hdev->kernel_ctx) != 1)
|
||||
dev_err(hdev->dev,
|
||||
"kernel ctx is still alive on initialization failure\n");
|
||||
remove_device_from_debugfs:
|
||||
hl_debugfs_remove_device(hdev);
|
||||
debugfs_device_fini:
|
||||
hl_debugfs_device_fini(hdev);
|
||||
mmu_fini:
|
||||
hl_mmu_fini(hdev);
|
||||
eq_fini:
|
||||
@ -2300,15 +2326,11 @@ free_dev:
|
||||
put_device(hdev->dev);
|
||||
out_disabled:
|
||||
hdev->disabled = true;
|
||||
if (add_cdev_sysfs_on_err)
|
||||
device_cdev_sysfs_add(hdev);
|
||||
if (hdev->pdev)
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"Failed to initialize hl%d. Device %s is NOT usable !\n",
|
||||
hdev->cdev_idx, dev_name(&(hdev)->pdev->dev));
|
||||
else
|
||||
pr_err("Failed to initialize hl%d. Device %s is NOT usable !\n",
|
||||
hdev->cdev_idx, dev_name(&(hdev)->pdev->dev));
|
||||
if (expose_interfaces_on_err)
|
||||
cdev_sysfs_debugfs_add(hdev);
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"Failed to initialize hl%d. Device %s is NOT usable !\n",
|
||||
hdev->cdev_idx, dev_name(&hdev->pdev->dev));
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -2427,8 +2449,6 @@ void hl_device_fini(struct hl_device *hdev)
|
||||
if ((hdev->kernel_ctx) && (hl_ctx_put(hdev->kernel_ctx) != 1))
|
||||
dev_err(hdev->dev, "kernel ctx is still alive\n");
|
||||
|
||||
hl_debugfs_remove_device(hdev);
|
||||
|
||||
hl_dec_fini(hdev);
|
||||
|
||||
hl_vm_fini(hdev);
|
||||
@ -2453,8 +2473,10 @@ void hl_device_fini(struct hl_device *hdev)
|
||||
|
||||
device_early_fini(hdev);
|
||||
|
||||
/* Hide devices and sysfs nodes from user */
|
||||
device_cdev_sysfs_del(hdev);
|
||||
/* Hide devices and sysfs/debugfs files from user */
|
||||
cdev_sysfs_debugfs_remove(hdev);
|
||||
|
||||
hl_debugfs_device_fini(hdev);
|
||||
|
||||
pr_info("removed device successfully\n");
|
||||
}
|
||||
@ -2667,3 +2689,11 @@ void hl_handle_fw_err(struct hl_device *hdev, struct hl_info_fw_err_info *info)
|
||||
if (info->event_mask)
|
||||
*info->event_mask |= HL_NOTIFIER_EVENT_CRITICL_FW_ERR;
|
||||
}
|
||||
|
||||
void hl_enable_err_info_capture(struct hl_error_info *captured_err_info)
|
||||
{
|
||||
vfree(captured_err_info->page_fault_info.user_mappings);
|
||||
memset(captured_err_info, 0, sizeof(struct hl_error_info));
|
||||
atomic_set(&captured_err_info->cs_timeout.write_enable, 1);
|
||||
captured_err_info->undef_opcode.write_enable = true;
|
||||
}
|
||||
|
@ -71,38 +71,124 @@ free_fw_ver:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* extract_u32_until_given_char() - given a string of the format "<u32><char>*", extract the u32.
|
||||
* @str: the given string
|
||||
* @ver_num: the pointer to the extracted u32 to be returned to the caller.
|
||||
* @given_char: the given char at the end of the u32 in the string
|
||||
*
|
||||
* Return: Upon success, return a pointer to the given_char in the string. Upon failure, return NULL
|
||||
*/
|
||||
static char *extract_u32_until_given_char(char *str, u32 *ver_num, char given_char)
|
||||
{
|
||||
char num_str[8] = {}, *ch;
|
||||
|
||||
ch = strchrnul(str, given_char);
|
||||
if (*ch == '\0' || ch == str || ch - str >= sizeof(num_str))
|
||||
return NULL;
|
||||
|
||||
memcpy(num_str, str, ch - str);
|
||||
if (kstrtou32(num_str, 10, ver_num))
|
||||
return NULL;
|
||||
return ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* hl_get_sw_major_minor_subminor() - extract the FW's SW version major, minor, sub-minor
|
||||
* from the version string
|
||||
* @hdev: pointer to the hl_device
|
||||
* @fw_str: the FW's version string
|
||||
*
|
||||
* The extracted version is set in the hdev fields: fw_sw_{major/minor/sub_minor}_ver.
|
||||
*
|
||||
* fw_str is expected to have one of two possible formats, examples:
|
||||
* 1) 'Preboot version hl-gaudi2-1.9.0-fw-42.0.1-sec-3'
|
||||
* 2) 'Preboot version hl-gaudi2-1.9.0-rc-fw-42.0.1-sec-3'
|
||||
* In those examples, the SW major,minor,subminor are correspondingly: 1,9,0.
|
||||
*
|
||||
* Return: 0 for success or a negative error code for failure.
|
||||
*/
|
||||
static int hl_get_sw_major_minor_subminor(struct hl_device *hdev, const char *fw_str)
|
||||
{
|
||||
char *end, *start;
|
||||
|
||||
end = strnstr(fw_str, "-rc-", VERSION_MAX_LEN);
|
||||
if (end == fw_str)
|
||||
return -EINVAL;
|
||||
|
||||
if (!end)
|
||||
end = strnstr(fw_str, "-fw-", VERSION_MAX_LEN);
|
||||
|
||||
if (end == fw_str)
|
||||
return -EINVAL;
|
||||
|
||||
if (!end)
|
||||
return -EINVAL;
|
||||
|
||||
for (start = end - 1; start != fw_str; start--) {
|
||||
if (*start == '-')
|
||||
break;
|
||||
}
|
||||
|
||||
if (start == fw_str)
|
||||
return -EINVAL;
|
||||
|
||||
/* start/end point each to the starting and ending hyphen of the sw version e.g. -1.9.0- */
|
||||
start++;
|
||||
start = extract_u32_until_given_char(start, &hdev->fw_sw_major_ver, '.');
|
||||
if (!start)
|
||||
goto err_zero_ver;
|
||||
|
||||
start++;
|
||||
start = extract_u32_until_given_char(start, &hdev->fw_sw_minor_ver, '.');
|
||||
if (!start)
|
||||
goto err_zero_ver;
|
||||
|
||||
start++;
|
||||
start = extract_u32_until_given_char(start, &hdev->fw_sw_sub_minor_ver, '-');
|
||||
if (!start)
|
||||
goto err_zero_ver;
|
||||
|
||||
return 0;
|
||||
|
||||
err_zero_ver:
|
||||
hdev->fw_sw_major_ver = 0;
|
||||
hdev->fw_sw_minor_ver = 0;
|
||||
hdev->fw_sw_sub_minor_ver = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* hl_get_preboot_major_minor() - extract the FW's version major, minor from the version string.
|
||||
* @hdev: pointer to the hl_device
|
||||
* @preboot_ver: the FW's version string
|
||||
*
|
||||
* preboot_ver is expected to be the format of <major>.<minor>.<sub minor>*, e.g: 42.0.1-sec-3
|
||||
* The extracted version is set in the hdev fields: fw_inner_{major/minor}_ver.
|
||||
*
|
||||
* Return: 0 on success, negative error code for failure.
|
||||
*/
|
||||
static int hl_get_preboot_major_minor(struct hl_device *hdev, char *preboot_ver)
|
||||
{
|
||||
char major[8], minor[8], *first_dot, *second_dot;
|
||||
int rc;
|
||||
|
||||
first_dot = strnstr(preboot_ver, ".", 10);
|
||||
if (first_dot) {
|
||||
strscpy(major, preboot_ver, first_dot - preboot_ver + 1);
|
||||
rc = kstrtou32(major, 10, &hdev->fw_major_version);
|
||||
} else {
|
||||
rc = -EINVAL;
|
||||
preboot_ver = extract_u32_until_given_char(preboot_ver, &hdev->fw_inner_major_ver, '.');
|
||||
if (!preboot_ver) {
|
||||
dev_err(hdev->dev, "Error parsing preboot major version\n");
|
||||
goto err_zero_ver;
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
dev_err(hdev->dev, "Error %d parsing preboot major version\n", rc);
|
||||
return rc;
|
||||
preboot_ver++;
|
||||
|
||||
preboot_ver = extract_u32_until_given_char(preboot_ver, &hdev->fw_inner_minor_ver, '.');
|
||||
if (!preboot_ver) {
|
||||
dev_err(hdev->dev, "Error parsing preboot minor version\n");
|
||||
goto err_zero_ver;
|
||||
}
|
||||
return 0;
|
||||
|
||||
/* skip the first dot */
|
||||
first_dot++;
|
||||
|
||||
second_dot = strnstr(first_dot, ".", 10);
|
||||
if (second_dot) {
|
||||
strscpy(minor, first_dot, second_dot - first_dot + 1);
|
||||
rc = kstrtou32(minor, 10, &hdev->fw_minor_version);
|
||||
} else {
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
if (rc)
|
||||
dev_err(hdev->dev, "Error %d parsing preboot minor version\n", rc);
|
||||
return rc;
|
||||
err_zero_ver:
|
||||
hdev->fw_inner_major_ver = 0;
|
||||
hdev->fw_inner_minor_ver = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int hl_request_fw(struct hl_device *hdev,
|
||||
@ -505,6 +591,20 @@ void hl_fw_cpu_accessible_dma_pool_free(struct hl_device *hdev, size_t size,
|
||||
size);
|
||||
}
|
||||
|
||||
int hl_fw_send_soft_reset(struct hl_device *hdev)
|
||||
{
|
||||
struct cpucp_packet pkt;
|
||||
int rc;
|
||||
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
pkt.ctl = cpu_to_le32(CPUCP_PACKET_SOFT_RESET << CPUCP_PKT_CTL_OPCODE_SHIFT);
|
||||
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), 0, NULL);
|
||||
if (rc)
|
||||
dev_err(hdev->dev, "failed to send soft-reset msg (err = %d)\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int hl_fw_send_device_activity(struct hl_device *hdev, bool open)
|
||||
{
|
||||
struct cpucp_packet pkt;
|
||||
@ -1268,8 +1368,10 @@ void hl_fw_ask_hard_reset_without_linux(struct hl_device *hdev)
|
||||
|
||||
void hl_fw_ask_halt_machine_without_linux(struct hl_device *hdev)
|
||||
{
|
||||
struct static_fw_load_mgr *static_loader =
|
||||
&hdev->fw_loader.static_loader;
|
||||
struct fw_load_mgr *fw_loader = &hdev->fw_loader;
|
||||
u32 status, cpu_boot_status_reg, cpu_timeout;
|
||||
struct static_fw_load_mgr *static_loader;
|
||||
struct pre_fw_load_props *pre_fw_load;
|
||||
int rc;
|
||||
|
||||
if (hdev->device_cpu_is_halted)
|
||||
@ -1277,12 +1379,28 @@ void hl_fw_ask_halt_machine_without_linux(struct hl_device *hdev)
|
||||
|
||||
/* Stop device CPU to make sure nothing bad happens */
|
||||
if (hdev->asic_prop.dynamic_fw_load) {
|
||||
pre_fw_load = &fw_loader->pre_fw_load;
|
||||
cpu_timeout = fw_loader->cpu_timeout;
|
||||
cpu_boot_status_reg = pre_fw_load->cpu_boot_status_reg;
|
||||
|
||||
rc = hl_fw_dynamic_send_protocol_cmd(hdev, &hdev->fw_loader,
|
||||
COMMS_GOTO_WFE, 0, false,
|
||||
hdev->fw_loader.cpu_timeout);
|
||||
if (rc)
|
||||
COMMS_GOTO_WFE, 0, false, cpu_timeout);
|
||||
if (rc) {
|
||||
dev_err(hdev->dev, "Failed sending COMMS_GOTO_WFE\n");
|
||||
} else {
|
||||
rc = hl_poll_timeout(
|
||||
hdev,
|
||||
cpu_boot_status_reg,
|
||||
status,
|
||||
status == CPU_BOOT_STATUS_IN_WFE,
|
||||
hdev->fw_poll_interval_usec,
|
||||
cpu_timeout);
|
||||
if (rc)
|
||||
dev_err(hdev->dev, "Current status=%u. Timed-out updating to WFE\n",
|
||||
status);
|
||||
}
|
||||
} else {
|
||||
static_loader = &hdev->fw_loader.static_loader;
|
||||
WREG32(static_loader->kmd_msg_to_cpu_reg, KMD_MSG_GOTO_WFE);
|
||||
msleep(static_loader->cpu_reset_wait_msec);
|
||||
|
||||
@ -2151,6 +2269,7 @@ static int hl_fw_dynamic_read_device_fw_version(struct hl_device *hdev,
|
||||
struct asic_fixed_properties *prop = &hdev->asic_prop;
|
||||
char *preboot_ver, *boot_ver;
|
||||
char btl_ver[32];
|
||||
int rc;
|
||||
|
||||
switch (fwc) {
|
||||
case FW_COMP_BOOT_FIT:
|
||||
@ -2164,20 +2283,20 @@ static int hl_fw_dynamic_read_device_fw_version(struct hl_device *hdev,
|
||||
break;
|
||||
case FW_COMP_PREBOOT:
|
||||
strscpy(prop->preboot_ver, fw_version, VERSION_MAX_LEN);
|
||||
preboot_ver = strnstr(prop->preboot_ver, "Preboot",
|
||||
VERSION_MAX_LEN);
|
||||
preboot_ver = strnstr(prop->preboot_ver, "Preboot", VERSION_MAX_LEN);
|
||||
dev_info(hdev->dev, "preboot full version: '%s'\n", preboot_ver);
|
||||
|
||||
if (preboot_ver && preboot_ver != prop->preboot_ver) {
|
||||
strscpy(btl_ver, prop->preboot_ver,
|
||||
min((int) (preboot_ver - prop->preboot_ver), 31));
|
||||
dev_info(hdev->dev, "%s\n", btl_ver);
|
||||
}
|
||||
|
||||
rc = hl_get_sw_major_minor_subminor(hdev, preboot_ver);
|
||||
if (rc)
|
||||
return rc;
|
||||
preboot_ver = extract_fw_ver_from_str(prop->preboot_ver);
|
||||
if (preboot_ver) {
|
||||
int rc;
|
||||
|
||||
dev_info(hdev->dev, "preboot version %s\n", preboot_ver);
|
||||
|
||||
rc = hl_get_preboot_major_minor(hdev, preboot_ver);
|
||||
kfree(preboot_ver);
|
||||
if (rc)
|
||||
@ -2367,16 +2486,6 @@ static int hl_fw_dynamic_load_image(struct hl_device *hdev,
|
||||
if (rc)
|
||||
goto release_fw;
|
||||
|
||||
/* update state according to boot stage */
|
||||
if (cur_fwc == FW_COMP_BOOT_FIT) {
|
||||
struct cpu_dyn_regs *dyn_regs;
|
||||
|
||||
dyn_regs = &fw_loader->dynamic_loader.comm_desc.cpu_dyn_regs;
|
||||
hl_fw_boot_fit_update_state(hdev,
|
||||
le32_to_cpu(dyn_regs->cpu_boot_dev_sts0),
|
||||
le32_to_cpu(dyn_regs->cpu_boot_dev_sts1));
|
||||
}
|
||||
|
||||
/* copy boot fit to space allocated by FW */
|
||||
rc = hl_fw_dynamic_copy_image(hdev, fw, fw_loader);
|
||||
if (rc)
|
||||
@ -2679,6 +2788,14 @@ static int hl_fw_dynamic_init_cpu(struct hl_device *hdev,
|
||||
goto protocol_err;
|
||||
}
|
||||
|
||||
rc = hl_fw_dynamic_wait_for_boot_fit_active(hdev, fw_loader);
|
||||
if (rc)
|
||||
goto protocol_err;
|
||||
|
||||
hl_fw_boot_fit_update_state(hdev,
|
||||
le32_to_cpu(dyn_regs->cpu_boot_dev_sts0),
|
||||
le32_to_cpu(dyn_regs->cpu_boot_dev_sts1));
|
||||
|
||||
/*
|
||||
* when testing FW load (without Linux) on PLDM we don't want to
|
||||
* wait until boot fit is active as it may take several hours.
|
||||
@ -2688,10 +2805,6 @@ static int hl_fw_dynamic_init_cpu(struct hl_device *hdev,
|
||||
if (hdev->pldm && !(hdev->fw_components & FW_TYPE_LINUX))
|
||||
return 0;
|
||||
|
||||
rc = hl_fw_dynamic_wait_for_boot_fit_active(hdev, fw_loader);
|
||||
if (rc)
|
||||
goto protocol_err;
|
||||
|
||||
/* Enable DRAM scrambling before Linux boot and after successful
|
||||
* UBoot
|
||||
*/
|
||||
@ -2725,7 +2838,8 @@ static int hl_fw_dynamic_init_cpu(struct hl_device *hdev,
|
||||
if (rc)
|
||||
goto protocol_err;
|
||||
|
||||
hl_fw_linux_update_state(hdev, le32_to_cpu(dyn_regs->cpu_boot_dev_sts0),
|
||||
hl_fw_linux_update_state(hdev,
|
||||
le32_to_cpu(dyn_regs->cpu_boot_dev_sts0),
|
||||
le32_to_cpu(dyn_regs->cpu_boot_dev_sts1));
|
||||
|
||||
hl_fw_dynamic_update_linux_interrupt_if(hdev);
|
||||
|
@ -36,6 +36,8 @@
|
||||
struct hl_device;
|
||||
struct hl_fpriv;
|
||||
|
||||
#define PCI_VENDOR_ID_HABANALABS 0x1da3
|
||||
|
||||
/* Use upper bits of mmap offset to store habana driver specific information.
|
||||
* bits[63:59] - Encode mmap type
|
||||
* bits[45:0] - mmap offset value
|
||||
@ -113,18 +115,6 @@ enum hl_mmu_page_table_location {
|
||||
MMU_NUM_PGT_LOCATIONS /* num of PGT locations */
|
||||
};
|
||||
|
||||
/**
|
||||
* enum hl_mmu_enablement - what mmu modules to enable
|
||||
* @MMU_EN_NONE: mmu disabled.
|
||||
* @MMU_EN_ALL: enable all.
|
||||
* @MMU_EN_PMMU_ONLY: Enable only the PMMU leaving the DMMU disabled.
|
||||
*/
|
||||
enum hl_mmu_enablement {
|
||||
MMU_EN_NONE = 0,
|
||||
MMU_EN_ALL = 1,
|
||||
MMU_EN_PMMU_ONLY = 3, /* N/A for Goya/Gaudi */
|
||||
};
|
||||
|
||||
/*
|
||||
* HL_RSVD_SOBS 'sync stream' reserved sync objects per QMAN stream
|
||||
* HL_RSVD_MONS 'sync stream' reserved monitors per QMAN stream
|
||||
@ -2568,12 +2558,7 @@ void hl_wreg(struct hl_device *hdev, u32 reg, u32 val);
|
||||
ktime_t __timeout; \
|
||||
u32 __elbi_read; \
|
||||
int __rc = 0; \
|
||||
if (hdev->pdev) \
|
||||
__timeout = ktime_add_us(ktime_get(), timeout_us); \
|
||||
else \
|
||||
__timeout = ktime_add_us(ktime_get(),\
|
||||
min((u64)(timeout_us * 10), \
|
||||
(u64) HL_SIM_MAX_TIMEOUT_US)); \
|
||||
__timeout = ktime_add_us(ktime_get(), timeout_us); \
|
||||
might_sleep_if(sleep_us); \
|
||||
for (;;) { \
|
||||
if (elbi) { \
|
||||
@ -2625,13 +2610,7 @@ void hl_wreg(struct hl_device *hdev, u32 reg, u32 val);
|
||||
u8 __arr_idx; \
|
||||
int __rc = 0; \
|
||||
\
|
||||
if (hdev->pdev) \
|
||||
__timeout = ktime_add_us(ktime_get(), timeout_us); \
|
||||
else \
|
||||
__timeout = ktime_add_us(ktime_get(),\
|
||||
min(((u64)timeout_us * 10), \
|
||||
(u64) HL_SIM_MAX_TIMEOUT_US)); \
|
||||
\
|
||||
__timeout = ktime_add_us(ktime_get(), timeout_us); \
|
||||
might_sleep_if(sleep_us); \
|
||||
if (arr_size >= 64) \
|
||||
__rc = -EINVAL; \
|
||||
@ -2689,12 +2668,8 @@ void hl_wreg(struct hl_device *hdev, u32 reg, u32 val);
|
||||
mem_written_by_device) \
|
||||
({ \
|
||||
ktime_t __timeout; \
|
||||
if (hdev->pdev) \
|
||||
__timeout = ktime_add_us(ktime_get(), timeout_us); \
|
||||
else \
|
||||
__timeout = ktime_add_us(ktime_get(),\
|
||||
min((u64)(timeout_us * 100), \
|
||||
(u64) HL_SIM_MAX_TIMEOUT_US)); \
|
||||
\
|
||||
__timeout = ktime_add_us(ktime_get(), timeout_us); \
|
||||
might_sleep_if(sleep_us); \
|
||||
for (;;) { \
|
||||
/* Verify we read updates done by other cores or by device */ \
|
||||
@ -3225,8 +3200,11 @@ struct hl_reset_info {
|
||||
* @captured_err_info: holds information about errors.
|
||||
* @reset_info: holds current device reset information.
|
||||
* @stream_master_qid_arr: pointer to array with QIDs of master streams.
|
||||
* @fw_major_version: major version of current loaded preboot.
|
||||
* @fw_minor_version: minor version of current loaded preboot.
|
||||
* @fw_inner_major_ver: the major of current loaded preboot inner version.
|
||||
* @fw_inner_minor_ver: the minor of current loaded preboot inner version.
|
||||
* @fw_sw_major_ver: the major of current loaded preboot SW version.
|
||||
* @fw_sw_minor_ver: the minor of current loaded preboot SW version.
|
||||
* @fw_sw_sub_minor_ver: the sub-minor of current loaded preboot SW version.
|
||||
* @dram_used_mem: current DRAM memory consumption.
|
||||
* @memory_scrub_val: the value to which the dram will be scrubbed to using cb scrub_device_dram
|
||||
* @timeout_jiffies: device CS timeout value.
|
||||
@ -3287,7 +3265,7 @@ struct hl_reset_info {
|
||||
* @in_debug: whether the device is in a state where the profiling/tracing infrastructure
|
||||
* can be used. This indication is needed because in some ASICs we need to do
|
||||
* specific operations to enable that infrastructure.
|
||||
* @cdev_sysfs_created: were char devices and sysfs nodes created.
|
||||
* @cdev_sysfs_debugfs_created: were char devices and sysfs/debugfs files created.
|
||||
* @stop_on_err: true if engines should stop on error.
|
||||
* @supports_sync_stream: is sync stream supported.
|
||||
* @sync_stream_queue_idx: helper index for sync stream queues initialization.
|
||||
@ -3314,7 +3292,7 @@ struct hl_reset_info {
|
||||
* @nic_ports_mask: Controls which NIC ports are enabled. Used only for testing.
|
||||
* @fw_components: Controls which f/w components to load to the device. There are multiple f/w
|
||||
* stages and sometimes we want to stop at a certain stage. Used only for testing.
|
||||
* @mmu_enable: Whether to enable or disable the device MMU(s). Used only for testing.
|
||||
* @mmu_disable: Disable the device MMU(s). Used only for testing.
|
||||
* @cpu_queues_enable: Whether to enable queues communication vs. the f/w. Used only for testing.
|
||||
* @pldm: Whether we are running in Palladium environment. Used only for testing.
|
||||
* @hard_reset_on_fw_events: Whether to do device hard-reset when a fatal event is received from
|
||||
@ -3412,8 +3390,11 @@ struct hl_device {
|
||||
struct hl_reset_info reset_info;
|
||||
|
||||
u32 *stream_master_qid_arr;
|
||||
u32 fw_major_version;
|
||||
u32 fw_minor_version;
|
||||
u32 fw_inner_major_ver;
|
||||
u32 fw_inner_minor_ver;
|
||||
u32 fw_sw_major_ver;
|
||||
u32 fw_sw_minor_ver;
|
||||
u32 fw_sw_sub_minor_ver;
|
||||
atomic64_t dram_used_mem;
|
||||
u64 memory_scrub_val;
|
||||
u64 timeout_jiffies;
|
||||
@ -3451,7 +3432,7 @@ struct hl_device {
|
||||
u8 init_done;
|
||||
u8 device_cpu_disabled;
|
||||
u8 in_debug;
|
||||
u8 cdev_sysfs_created;
|
||||
u8 cdev_sysfs_debugfs_created;
|
||||
u8 stop_on_err;
|
||||
u8 supports_sync_stream;
|
||||
u8 sync_stream_queue_idx;
|
||||
@ -3474,7 +3455,7 @@ struct hl_device {
|
||||
/* Parameters for bring-up to be upstreamed */
|
||||
u64 nic_ports_mask;
|
||||
u64 fw_components;
|
||||
u8 mmu_enable;
|
||||
u8 mmu_disable;
|
||||
u8 cpu_queues_enable;
|
||||
u8 pldm;
|
||||
u8 hard_reset_on_fw_events;
|
||||
@ -3547,9 +3528,15 @@ struct hl_ioctl_desc {
|
||||
hl_ioctl_t *func;
|
||||
};
|
||||
|
||||
static inline bool hl_is_fw_ver_below_1_9(struct hl_device *hdev)
|
||||
static inline bool hl_is_fw_sw_ver_below(struct hl_device *hdev, u32 fw_sw_major, u32 fw_sw_minor)
|
||||
{
|
||||
return (hdev->fw_major_version < 42);
|
||||
if (hdev->fw_sw_major_ver < fw_sw_major)
|
||||
return true;
|
||||
if (hdev->fw_sw_major_ver > fw_sw_major)
|
||||
return false;
|
||||
if (hdev->fw_sw_minor_ver < fw_sw_minor)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3813,8 +3800,6 @@ struct pgt_info *hl_mmu_hr_get_alloc_next_hop(struct hl_ctx *ctx,
|
||||
u64 curr_pte, bool *is_new_hop);
|
||||
int hl_mmu_hr_get_tlb_info(struct hl_ctx *ctx, u64 virt_addr, struct hl_mmu_hop_info *hops,
|
||||
struct hl_hr_mmu_funcs *hr_func);
|
||||
void hl_mmu_swap_out(struct hl_ctx *ctx);
|
||||
void hl_mmu_swap_in(struct hl_ctx *ctx);
|
||||
int hl_mmu_if_set_funcs(struct hl_device *hdev);
|
||||
void hl_mmu_v1_set_funcs(struct hl_device *hdev, struct hl_mmu_funcs *mmu);
|
||||
void hl_mmu_v2_hr_set_funcs(struct hl_device *hdev, struct hl_mmu_funcs *mmu);
|
||||
@ -3872,6 +3857,7 @@ int hl_fw_dram_replaced_row_get(struct hl_device *hdev,
|
||||
int hl_fw_dram_pending_row_get(struct hl_device *hdev, u32 *pend_rows_num);
|
||||
int hl_fw_cpucp_engine_core_asid_set(struct hl_device *hdev, u32 asid);
|
||||
int hl_fw_send_device_activity(struct hl_device *hdev, bool open);
|
||||
int hl_fw_send_soft_reset(struct hl_device *hdev);
|
||||
int hl_pci_bars_map(struct hl_device *hdev, const char * const name[3],
|
||||
bool is_wc[3]);
|
||||
int hl_pci_elbi_read(struct hl_device *hdev, u64 addr, u32 *data);
|
||||
@ -3921,7 +3907,7 @@ void hl_dec_fini(struct hl_device *hdev);
|
||||
void hl_dec_ctx_fini(struct hl_ctx *ctx);
|
||||
|
||||
void hl_release_pending_user_interrupts(struct hl_device *hdev);
|
||||
void hl_abort_waitings_for_completion(struct hl_device *hdev);
|
||||
void hl_abort_waiting_for_cs_completions(struct hl_device *hdev);
|
||||
int hl_cs_signal_sob_wraparound_handler(struct hl_device *hdev, u32 q_idx,
|
||||
struct hl_hw_sob **hw_sob, u32 count, bool encaps_sig);
|
||||
|
||||
@ -3958,11 +3944,14 @@ void hl_handle_page_fault(struct hl_device *hdev, u64 addr, u16 eng_id, bool is_
|
||||
u64 *event_mask);
|
||||
void hl_handle_critical_hw_err(struct hl_device *hdev, u16 event_id, u64 *event_mask);
|
||||
void hl_handle_fw_err(struct hl_device *hdev, struct hl_info_fw_err_info *info);
|
||||
void hl_enable_err_info_capture(struct hl_error_info *captured_err_info);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
||||
void hl_debugfs_init(void);
|
||||
void hl_debugfs_fini(void);
|
||||
int hl_debugfs_device_init(struct hl_device *hdev);
|
||||
void hl_debugfs_device_fini(struct hl_device *hdev);
|
||||
void hl_debugfs_add_device(struct hl_device *hdev);
|
||||
void hl_debugfs_remove_device(struct hl_device *hdev);
|
||||
void hl_debugfs_add_file(struct hl_fpriv *hpriv);
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/habanalabs.h>
|
||||
@ -54,8 +55,6 @@ module_param(boot_error_status_mask, ulong, 0444);
|
||||
MODULE_PARM_DESC(boot_error_status_mask,
|
||||
"Mask of the error status during device CPU boot (If bitX is cleared then error X is masked. Default all 1's)");
|
||||
|
||||
#define PCI_VENDOR_ID_HABANALABS 0x1da3
|
||||
|
||||
#define PCI_IDS_GOYA 0x0001
|
||||
#define PCI_IDS_GAUDI 0x1000
|
||||
#define PCI_IDS_GAUDI_SEC 0x1010
|
||||
@ -220,9 +219,7 @@ int hl_device_open(struct inode *inode, struct file *filp)
|
||||
|
||||
hl_debugfs_add_file(hpriv);
|
||||
|
||||
memset(&hdev->captured_err_info, 0, sizeof(hdev->captured_err_info));
|
||||
atomic_set(&hdev->captured_err_info.cs_timeout.write_enable, 1);
|
||||
hdev->captured_err_info.undef_opcode.write_enable = true;
|
||||
hl_enable_err_info_capture(&hdev->captured_err_info);
|
||||
|
||||
hdev->open_counter++;
|
||||
hdev->last_successful_open_jif = jiffies;
|
||||
@ -307,7 +304,6 @@ static void set_driver_behavior_per_device(struct hl_device *hdev)
|
||||
{
|
||||
hdev->nic_ports_mask = 0;
|
||||
hdev->fw_components = FW_TYPE_ALL_TYPES;
|
||||
hdev->mmu_enable = MMU_EN_ALL;
|
||||
hdev->cpu_queues_enable = 1;
|
||||
hdev->pldm = 0;
|
||||
hdev->hard_reset_on_fw_events = 1;
|
||||
@ -382,7 +378,6 @@ static int fixup_device_params(struct hl_device *hdev)
|
||||
/* If CPU queues not enabled, no way to do heartbeat */
|
||||
if (!hdev->cpu_queues_enable)
|
||||
hdev->heartbeat = 0;
|
||||
|
||||
fixup_device_params_per_asic(hdev, tmp_timeout);
|
||||
|
||||
return 0;
|
||||
|
@ -62,7 +62,7 @@ static int hw_ip_info(struct hl_device *hdev, struct hl_info_args *args)
|
||||
hw_ip.device_id = hdev->asic_funcs->get_pci_id(hdev);
|
||||
hw_ip.sram_base_address = prop->sram_user_base_address;
|
||||
hw_ip.dram_base_address =
|
||||
hdev->mmu_enable && prop->dram_supports_virtual_memory ?
|
||||
prop->dram_supports_virtual_memory ?
|
||||
prop->dmmu.start_addr : prop->dram_user_base_address;
|
||||
hw_ip.tpc_enabled_mask = prop->tpc_enabled_mask & 0xFF;
|
||||
hw_ip.tpc_enabled_mask_ext = prop->tpc_enabled_mask;
|
||||
@ -71,11 +71,8 @@ static int hw_ip_info(struct hl_device *hdev, struct hl_info_args *args)
|
||||
|
||||
dram_available_size = prop->dram_size - dram_kmd_size;
|
||||
|
||||
if (hdev->mmu_enable == MMU_EN_ALL)
|
||||
hw_ip.dram_size = DIV_ROUND_DOWN_ULL(dram_available_size,
|
||||
prop->dram_page_size) * prop->dram_page_size;
|
||||
else
|
||||
hw_ip.dram_size = dram_available_size;
|
||||
hw_ip.dram_size = DIV_ROUND_DOWN_ULL(dram_available_size, prop->dram_page_size) *
|
||||
prop->dram_page_size;
|
||||
|
||||
if (hw_ip.dram_size > PAGE_SIZE)
|
||||
hw_ip.dram_enabled = 1;
|
||||
@ -842,15 +839,15 @@ static int hw_err_info(struct hl_fpriv *hpriv, struct hl_info_args *args)
|
||||
struct hw_err_info *info;
|
||||
int rc;
|
||||
|
||||
if ((!user_buf_size) || (!user_buf))
|
||||
if (!user_buf)
|
||||
return -EINVAL;
|
||||
|
||||
if (user_buf_size < sizeof(struct hl_info_hw_err_event))
|
||||
return -ENOMEM;
|
||||
|
||||
info = &hdev->captured_err_info.hw_err;
|
||||
if (!info->event_info_available)
|
||||
return -ENOENT;
|
||||
return 0;
|
||||
|
||||
if (user_buf_size < sizeof(struct hl_info_hw_err_event))
|
||||
return -ENOMEM;
|
||||
|
||||
rc = copy_to_user(user_buf, &info->event, sizeof(struct hl_info_hw_err_event));
|
||||
return rc ? -EFAULT : 0;
|
||||
@ -864,15 +861,15 @@ static int fw_err_info(struct hl_fpriv *hpriv, struct hl_info_args *args)
|
||||
struct fw_err_info *info;
|
||||
int rc;
|
||||
|
||||
if ((!user_buf_size) || (!user_buf))
|
||||
if (!user_buf)
|
||||
return -EINVAL;
|
||||
|
||||
if (user_buf_size < sizeof(struct hl_info_fw_err_event))
|
||||
return -ENOMEM;
|
||||
|
||||
info = &hdev->captured_err_info.fw_err;
|
||||
if (!info->event_info_available)
|
||||
return -ENOENT;
|
||||
return 0;
|
||||
|
||||
if (user_buf_size < sizeof(struct hl_info_fw_err_event))
|
||||
return -ENOMEM;
|
||||
|
||||
rc = copy_to_user(user_buf, &info->event, sizeof(struct hl_info_fw_err_event));
|
||||
return rc ? -EFAULT : 0;
|
||||
@ -1198,7 +1195,7 @@ static long _hl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg,
|
||||
|
||||
out_err:
|
||||
if (retcode)
|
||||
dev_dbg(dev, "error in ioctl: pid=%d, cmd=0x%02x, nr=0x%02x\n",
|
||||
dev_dbg_ratelimited(dev, "error in ioctl: pid=%d, cmd=0x%02x, nr=0x%02x\n",
|
||||
task_pid_nr(current), cmd, nr);
|
||||
|
||||
if (kdata != stack_kdata)
|
||||
@ -1222,7 +1219,7 @@ long hl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
if ((nr >= HL_COMMAND_START) && (nr < HL_COMMAND_END)) {
|
||||
ioctl = &hl_ioctls[nr];
|
||||
} else {
|
||||
dev_err(hdev->dev, "invalid ioctl: pid=%d, nr=0x%02x\n",
|
||||
dev_dbg_ratelimited(hdev->dev, "invalid ioctl: pid=%d, nr=0x%02x\n",
|
||||
task_pid_nr(current), nr);
|
||||
return -ENOTTY;
|
||||
}
|
||||
@ -1245,7 +1242,7 @@ long hl_ioctl_control(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
if (nr == _IOC_NR(HL_IOCTL_INFO)) {
|
||||
ioctl = &hl_ioctls_control[nr];
|
||||
} else {
|
||||
dev_err(hdev->dev_ctrl, "invalid ioctl: pid=%d, nr=0x%02x\n",
|
||||
dev_dbg_ratelimited(hdev->dev_ctrl, "invalid ioctl: pid=%d, nr=0x%02x\n",
|
||||
task_pid_nr(current), nr);
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
@ -430,7 +430,7 @@ irqreturn_t hl_irq_handler_eq(int irq, void *arg)
|
||||
cur_eqe_index = FIELD_GET(EQ_CTL_INDEX_MASK, cur_eqe);
|
||||
if ((hdev->event_queue.check_eqe_index) &&
|
||||
(((eq->prev_eqe_index + 1) & EQ_CTL_INDEX_MASK) != cur_eqe_index)) {
|
||||
dev_dbg(hdev->dev,
|
||||
dev_err(hdev->dev,
|
||||
"EQE %#x in queue is ready but index does not match %d!=%d",
|
||||
cur_eqe,
|
||||
((eq->prev_eqe_index + 1) & EQ_CTL_INDEX_MASK),
|
||||
|
@ -1034,30 +1034,6 @@ static void unmap_phys_pg_pack(struct hl_ctx *ctx, u64 vaddr,
|
||||
}
|
||||
}
|
||||
|
||||
static int get_paddr_from_handle(struct hl_ctx *ctx, struct hl_mem_in *args,
|
||||
u64 *paddr)
|
||||
{
|
||||
struct hl_device *hdev = ctx->hdev;
|
||||
struct hl_vm *vm = &hdev->vm;
|
||||
struct hl_vm_phys_pg_pack *phys_pg_pack;
|
||||
u32 handle;
|
||||
|
||||
handle = lower_32_bits(args->map_device.handle);
|
||||
spin_lock(&vm->idr_lock);
|
||||
phys_pg_pack = idr_find(&vm->phys_pg_pack_handles, handle);
|
||||
if (!phys_pg_pack) {
|
||||
spin_unlock(&vm->idr_lock);
|
||||
dev_err(hdev->dev, "no match for handle %u\n", handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*paddr = phys_pg_pack->pages[0];
|
||||
|
||||
spin_unlock(&vm->idr_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* map_device_va() - map the given memory.
|
||||
* @ctx: pointer to the context structure.
|
||||
@ -2094,76 +2070,6 @@ err_free_dmabuf_wrapper:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int mem_ioctl_no_mmu(struct hl_fpriv *hpriv, union hl_mem_args *args)
|
||||
{
|
||||
struct hl_device *hdev = hpriv->hdev;
|
||||
u64 block_handle, device_addr = 0;
|
||||
struct hl_ctx *ctx = hpriv->ctx;
|
||||
u32 handle = 0, block_size;
|
||||
int rc;
|
||||
|
||||
switch (args->in.op) {
|
||||
case HL_MEM_OP_ALLOC:
|
||||
if (args->in.alloc.mem_size == 0) {
|
||||
dev_err(hdev->dev, "alloc size must be larger than 0\n");
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Force contiguous as there are no real MMU
|
||||
* translations to overcome physical memory gaps
|
||||
*/
|
||||
args->in.flags |= HL_MEM_CONTIGUOUS;
|
||||
rc = alloc_device_memory(ctx, &args->in, &handle);
|
||||
|
||||
memset(args, 0, sizeof(*args));
|
||||
args->out.handle = (__u64) handle;
|
||||
break;
|
||||
|
||||
case HL_MEM_OP_FREE:
|
||||
rc = free_device_memory(ctx, &args->in);
|
||||
break;
|
||||
|
||||
case HL_MEM_OP_MAP:
|
||||
if (args->in.flags & HL_MEM_USERPTR) {
|
||||
dev_err(hdev->dev, "Failed to map host memory when MMU is disabled\n");
|
||||
rc = -EPERM;
|
||||
} else {
|
||||
rc = get_paddr_from_handle(ctx, &args->in, &device_addr);
|
||||
memset(args, 0, sizeof(*args));
|
||||
args->out.device_virt_addr = device_addr;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case HL_MEM_OP_UNMAP:
|
||||
rc = 0;
|
||||
break;
|
||||
|
||||
case HL_MEM_OP_MAP_BLOCK:
|
||||
rc = map_block(hdev, args->in.map_block.block_addr, &block_handle, &block_size);
|
||||
args->out.block_handle = block_handle;
|
||||
args->out.block_size = block_size;
|
||||
break;
|
||||
|
||||
case HL_MEM_OP_EXPORT_DMABUF_FD:
|
||||
dev_err(hdev->dev, "Failed to export dma-buf object when MMU is disabled\n");
|
||||
rc = -EPERM;
|
||||
break;
|
||||
|
||||
case HL_MEM_OP_TS_ALLOC:
|
||||
rc = allocate_timestamps_buffers(hpriv, &args->in, &args->out.handle);
|
||||
break;
|
||||
default:
|
||||
dev_err(hdev->dev, "Unknown opcode for memory IOCTL\n");
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void ts_buff_release(struct hl_mmap_mem_buf *buf)
|
||||
{
|
||||
struct hl_ts_buff *ts_buff = buf->private;
|
||||
@ -2282,9 +2188,6 @@ int hl_mem_ioctl(struct hl_fpriv *hpriv, void *data)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
return mem_ioctl_no_mmu(hpriv, args);
|
||||
|
||||
switch (args->in.op) {
|
||||
case HL_MEM_OP_ALLOC:
|
||||
if (args->in.alloc.mem_size == 0) {
|
||||
@ -2779,13 +2682,10 @@ int hl_vm_ctx_init(struct hl_ctx *ctx)
|
||||
atomic64_set(&ctx->dram_phys_mem, 0);
|
||||
|
||||
/*
|
||||
* - If MMU is enabled, init the ranges as usual.
|
||||
* - If MMU is disabled, in case of host mapping, the returned address
|
||||
* is the given one.
|
||||
* In case of DRAM mapping, the returned address is the physical
|
||||
* address of the memory related to the given handle.
|
||||
*/
|
||||
if (!ctx->hdev->mmu_enable)
|
||||
if (ctx->hdev->mmu_disable)
|
||||
return 0;
|
||||
|
||||
dram_range_start = prop->dmmu.start_addr;
|
||||
@ -2835,7 +2735,7 @@ void hl_vm_ctx_fini(struct hl_ctx *ctx)
|
||||
struct hl_mem_in args;
|
||||
int i;
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
if (hdev->mmu_disable)
|
||||
return;
|
||||
|
||||
hl_debugfs_remove_ctx_mem_hash(hdev, ctx);
|
||||
|
@ -44,7 +44,7 @@ int hl_mmu_init(struct hl_device *hdev)
|
||||
{
|
||||
int rc = -EOPNOTSUPP;
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
if (hdev->mmu_disable)
|
||||
return 0;
|
||||
|
||||
mutex_init(&hdev->mmu_lock);
|
||||
@ -82,7 +82,7 @@ fini_dr_mmu:
|
||||
*/
|
||||
void hl_mmu_fini(struct hl_device *hdev)
|
||||
{
|
||||
if (!hdev->mmu_enable)
|
||||
if (hdev->mmu_disable)
|
||||
return;
|
||||
|
||||
if (hdev->mmu_func[MMU_DR_PGT].fini != NULL)
|
||||
@ -107,7 +107,7 @@ int hl_mmu_ctx_init(struct hl_ctx *ctx)
|
||||
struct hl_device *hdev = ctx->hdev;
|
||||
int rc = -EOPNOTSUPP;
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
if (hdev->mmu_disable)
|
||||
return 0;
|
||||
|
||||
if (hdev->mmu_func[MMU_DR_PGT].ctx_init != NULL) {
|
||||
@ -145,7 +145,7 @@ void hl_mmu_ctx_fini(struct hl_ctx *ctx)
|
||||
{
|
||||
struct hl_device *hdev = ctx->hdev;
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
if (hdev->mmu_disable)
|
||||
return;
|
||||
|
||||
if (hdev->mmu_func[MMU_DR_PGT].ctx_fini != NULL)
|
||||
@ -233,7 +233,7 @@ int hl_mmu_unmap_page(struct hl_ctx *ctx, u64 virt_addr, u32 page_size, bool flu
|
||||
u64 real_virt_addr;
|
||||
bool is_dram_addr;
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
if (hdev->mmu_disable)
|
||||
return 0;
|
||||
|
||||
is_dram_addr = hl_is_dram_va(hdev, virt_addr);
|
||||
@ -301,7 +301,7 @@ int hl_mmu_map_page(struct hl_ctx *ctx, u64 virt_addr, u64 phys_addr, u32 page_s
|
||||
bool is_dram_addr;
|
||||
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
if (hdev->mmu_disable)
|
||||
return 0;
|
||||
|
||||
is_dram_addr = hl_is_dram_va(hdev, virt_addr);
|
||||
@ -472,46 +472,6 @@ int hl_mmu_unmap_contiguous(struct hl_ctx *ctx, u64 virt_addr, u32 size)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* hl_mmu_swap_out - marks all mapping of the given ctx as swapped out
|
||||
*
|
||||
* @ctx: pointer to the context structure
|
||||
*
|
||||
*/
|
||||
void hl_mmu_swap_out(struct hl_ctx *ctx)
|
||||
{
|
||||
struct hl_device *hdev = ctx->hdev;
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
return;
|
||||
|
||||
if (hdev->mmu_func[MMU_DR_PGT].swap_out != NULL)
|
||||
hdev->mmu_func[MMU_DR_PGT].swap_out(ctx);
|
||||
|
||||
if (hdev->mmu_func[MMU_HR_PGT].swap_out != NULL)
|
||||
hdev->mmu_func[MMU_HR_PGT].swap_out(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* hl_mmu_swap_in - marks all mapping of the given ctx as swapped in
|
||||
*
|
||||
* @ctx: pointer to the context structure
|
||||
*
|
||||
*/
|
||||
void hl_mmu_swap_in(struct hl_ctx *ctx)
|
||||
{
|
||||
struct hl_device *hdev = ctx->hdev;
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
return;
|
||||
|
||||
if (hdev->mmu_func[MMU_DR_PGT].swap_in != NULL)
|
||||
hdev->mmu_func[MMU_DR_PGT].swap_in(ctx);
|
||||
|
||||
if (hdev->mmu_func[MMU_HR_PGT].swap_in != NULL)
|
||||
hdev->mmu_func[MMU_HR_PGT].swap_in(ctx);
|
||||
}
|
||||
|
||||
static void hl_mmu_pa_page_with_offset(struct hl_ctx *ctx, u64 virt_addr,
|
||||
struct hl_mmu_hop_info *hops,
|
||||
u64 *phys_addr)
|
||||
@ -594,7 +554,7 @@ int hl_mmu_get_tlb_info(struct hl_ctx *ctx, u64 virt_addr,
|
||||
int pgt_residency, rc;
|
||||
bool is_dram_addr;
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
if (hdev->mmu_disable)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
prop = &hdev->asic_prop;
|
||||
@ -625,7 +585,7 @@ int hl_mmu_get_tlb_info(struct hl_ctx *ctx, u64 virt_addr,
|
||||
|
||||
int hl_mmu_if_set_funcs(struct hl_device *hdev)
|
||||
{
|
||||
if (!hdev->mmu_enable)
|
||||
if (hdev->mmu_disable)
|
||||
return 0;
|
||||
|
||||
switch (hdev->asic_type) {
|
||||
|
@ -284,14 +284,14 @@ void hl_secure_block(struct hl_device *hdev,
|
||||
* @instance_offset: offset between instances
|
||||
* @pb_blocks: blocks array
|
||||
* @blocks_array_size: blocks array size
|
||||
* @regs_array: register array
|
||||
* @regs_array_size: register array size
|
||||
* @user_regs_array: unsecured register array
|
||||
* @user_regs_array_size: unsecured register array size
|
||||
* @mask: enabled instances mask: 1- enabled, 0- disabled
|
||||
*/
|
||||
int hl_init_pb_with_mask(struct hl_device *hdev, u32 num_dcores,
|
||||
u32 dcore_offset, u32 num_instances, u32 instance_offset,
|
||||
const u32 pb_blocks[], u32 blocks_array_size,
|
||||
const u32 *regs_array, u32 regs_array_size, u64 mask)
|
||||
const u32 *user_regs_array, u32 user_regs_array_size, u64 mask)
|
||||
{
|
||||
int i, j;
|
||||
struct hl_block_glbl_sec *glbl_sec;
|
||||
@ -303,8 +303,8 @@ int hl_init_pb_with_mask(struct hl_device *hdev, u32 num_dcores,
|
||||
return -ENOMEM;
|
||||
|
||||
hl_secure_block(hdev, glbl_sec, blocks_array_size);
|
||||
hl_unsecure_registers(hdev, regs_array, regs_array_size, 0, pb_blocks,
|
||||
glbl_sec, blocks_array_size);
|
||||
hl_unsecure_registers(hdev, user_regs_array, user_regs_array_size, 0,
|
||||
pb_blocks, glbl_sec, blocks_array_size);
|
||||
|
||||
/* Fill all blocks with the same configuration */
|
||||
for (i = 0 ; i < num_dcores ; i++) {
|
||||
@ -336,19 +336,19 @@ int hl_init_pb_with_mask(struct hl_device *hdev, u32 num_dcores,
|
||||
* @instance_offset: offset between instances
|
||||
* @pb_blocks: blocks array
|
||||
* @blocks_array_size: blocks array size
|
||||
* @regs_array: register array
|
||||
* @regs_array_size: register array size
|
||||
* @user_regs_array: unsecured register array
|
||||
* @user_regs_array_size: unsecured register array size
|
||||
*
|
||||
*/
|
||||
int hl_init_pb(struct hl_device *hdev, u32 num_dcores, u32 dcore_offset,
|
||||
u32 num_instances, u32 instance_offset,
|
||||
const u32 pb_blocks[], u32 blocks_array_size,
|
||||
const u32 *regs_array, u32 regs_array_size)
|
||||
const u32 *user_regs_array, u32 user_regs_array_size)
|
||||
{
|
||||
return hl_init_pb_with_mask(hdev, num_dcores, dcore_offset,
|
||||
num_instances, instance_offset, pb_blocks,
|
||||
blocks_array_size, regs_array, regs_array_size,
|
||||
ULLONG_MAX);
|
||||
blocks_array_size, user_regs_array,
|
||||
user_regs_array_size, ULLONG_MAX);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -364,15 +364,15 @@ int hl_init_pb(struct hl_device *hdev, u32 num_dcores, u32 dcore_offset,
|
||||
* @instance_offset: offset between instances
|
||||
* @pb_blocks: blocks array
|
||||
* @blocks_array_size: blocks array size
|
||||
* @regs_range_array: register range array
|
||||
* @regs_range_array_size: register range array size
|
||||
* @user_regs_range_array: unsecured register range array
|
||||
* @user_regs_range_array_size: unsecured register range array size
|
||||
* @mask: enabled instances mask: 1- enabled, 0- disabled
|
||||
*/
|
||||
int hl_init_pb_ranges_with_mask(struct hl_device *hdev, u32 num_dcores,
|
||||
u32 dcore_offset, u32 num_instances, u32 instance_offset,
|
||||
const u32 pb_blocks[], u32 blocks_array_size,
|
||||
const struct range *regs_range_array, u32 regs_range_array_size,
|
||||
u64 mask)
|
||||
const struct range *user_regs_range_array,
|
||||
u32 user_regs_range_array_size, u64 mask)
|
||||
{
|
||||
int i, j, rc = 0;
|
||||
struct hl_block_glbl_sec *glbl_sec;
|
||||
@ -384,8 +384,8 @@ int hl_init_pb_ranges_with_mask(struct hl_device *hdev, u32 num_dcores,
|
||||
return -ENOMEM;
|
||||
|
||||
hl_secure_block(hdev, glbl_sec, blocks_array_size);
|
||||
rc = hl_unsecure_registers_range(hdev, regs_range_array,
|
||||
regs_range_array_size, 0, pb_blocks, glbl_sec,
|
||||
rc = hl_unsecure_registers_range(hdev, user_regs_range_array,
|
||||
user_regs_range_array_size, 0, pb_blocks, glbl_sec,
|
||||
blocks_array_size);
|
||||
if (rc)
|
||||
goto free_glbl_sec;
|
||||
@ -422,19 +422,20 @@ free_glbl_sec:
|
||||
* @instance_offset: offset between instances
|
||||
* @pb_blocks: blocks array
|
||||
* @blocks_array_size: blocks array size
|
||||
* @regs_range_array: register range array
|
||||
* @regs_range_array_size: register range array size
|
||||
* @user_regs_range_array: unsecured register range array
|
||||
* @user_regs_range_array_size: unsecured register range array size
|
||||
*
|
||||
*/
|
||||
int hl_init_pb_ranges(struct hl_device *hdev, u32 num_dcores,
|
||||
u32 dcore_offset, u32 num_instances, u32 instance_offset,
|
||||
const u32 pb_blocks[], u32 blocks_array_size,
|
||||
const struct range *regs_range_array, u32 regs_range_array_size)
|
||||
const struct range *user_regs_range_array,
|
||||
u32 user_regs_range_array_size)
|
||||
{
|
||||
return hl_init_pb_ranges_with_mask(hdev, num_dcores, dcore_offset,
|
||||
num_instances, instance_offset, pb_blocks,
|
||||
blocks_array_size, regs_range_array,
|
||||
regs_range_array_size, ULLONG_MAX);
|
||||
blocks_array_size, user_regs_range_array,
|
||||
user_regs_range_array_size, ULLONG_MAX);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -447,14 +448,14 @@ int hl_init_pb_ranges(struct hl_device *hdev, u32 num_dcores,
|
||||
* @instance_offset: offset between instances
|
||||
* @pb_blocks: blocks array
|
||||
* @blocks_array_size: blocks array size
|
||||
* @regs_array: register array
|
||||
* @regs_array_size: register array size
|
||||
* @user_regs_array: unsecured register array
|
||||
* @user_regs_array_size: unsecured register array size
|
||||
*
|
||||
*/
|
||||
int hl_init_pb_single_dcore(struct hl_device *hdev, u32 dcore_offset,
|
||||
u32 num_instances, u32 instance_offset,
|
||||
const u32 pb_blocks[], u32 blocks_array_size,
|
||||
const u32 *regs_array, u32 regs_array_size)
|
||||
const u32 *user_regs_array, u32 user_regs_array_size)
|
||||
{
|
||||
int i, rc = 0;
|
||||
struct hl_block_glbl_sec *glbl_sec;
|
||||
@ -466,8 +467,8 @@ int hl_init_pb_single_dcore(struct hl_device *hdev, u32 dcore_offset,
|
||||
return -ENOMEM;
|
||||
|
||||
hl_secure_block(hdev, glbl_sec, blocks_array_size);
|
||||
rc = hl_unsecure_registers(hdev, regs_array, regs_array_size, 0,
|
||||
pb_blocks, glbl_sec, blocks_array_size);
|
||||
rc = hl_unsecure_registers(hdev, user_regs_array, user_regs_array_size,
|
||||
0, pb_blocks, glbl_sec, blocks_array_size);
|
||||
if (rc)
|
||||
goto free_glbl_sec;
|
||||
|
||||
@ -495,8 +496,8 @@ free_glbl_sec:
|
||||
* @instance_offset: offset between instances
|
||||
* @pb_blocks: blocks array
|
||||
* @blocks_array_size: blocks array size
|
||||
* @regs_range_array: register range array
|
||||
* @regs_range_array_size: register range array size
|
||||
* @user_regs_range_array: unsecured register range array
|
||||
* @user_regs_range_array_size: unsecured register range array size
|
||||
*
|
||||
*/
|
||||
int hl_init_pb_ranges_single_dcore(struct hl_device *hdev, u32 dcore_offset,
|
||||
|
@ -114,13 +114,6 @@ static u32 gaudi_stream_master[GAUDI_STREAM_MASTER_ARR_SIZE] = {
|
||||
GAUDI_QUEUE_ID_DMA_1_3
|
||||
};
|
||||
|
||||
static const char gaudi_irq_name[GAUDI_MSI_ENTRIES][GAUDI_MAX_STRING_LEN] = {
|
||||
"gaudi cq 0_0", "gaudi cq 0_1", "gaudi cq 0_2", "gaudi cq 0_3",
|
||||
"gaudi cq 1_0", "gaudi cq 1_1", "gaudi cq 1_2", "gaudi cq 1_3",
|
||||
"gaudi cq 5_0", "gaudi cq 5_1", "gaudi cq 5_2", "gaudi cq 5_3",
|
||||
"gaudi cpu eq"
|
||||
};
|
||||
|
||||
static const u8 gaudi_dma_assignment[GAUDI_DMA_MAX] = {
|
||||
[GAUDI_PCI_DMA_1] = GAUDI_ENGINE_ID_DMA_0,
|
||||
[GAUDI_PCI_DMA_2] = GAUDI_ENGINE_ID_DMA_1,
|
||||
@ -1476,8 +1469,7 @@ static int gaudi_collective_wait_create_job(struct hl_device *hdev,
|
||||
}
|
||||
|
||||
/* Allocate internal mapped CB for non patched CBs */
|
||||
cb = hl_cb_kernel_create(hdev, cb_size,
|
||||
hdev->mmu_enable && !patched_cb);
|
||||
cb = hl_cb_kernel_create(hdev, cb_size, !patched_cb);
|
||||
if (!cb) {
|
||||
atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt);
|
||||
atomic64_inc(&cntr->out_of_mem_drop_cnt);
|
||||
@ -3651,9 +3643,6 @@ static int gaudi_mmu_init(struct hl_device *hdev)
|
||||
u64 hop0_addr;
|
||||
int rc, i;
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
return 0;
|
||||
|
||||
if (gaudi->hw_cap_initialized & HW_CAP_MMU)
|
||||
return 0;
|
||||
|
||||
|
@ -57,13 +57,13 @@
|
||||
|
||||
#define GAUDI2_NA_EVENT_CAUSE 0xFF
|
||||
#define GAUDI2_NUM_OF_QM_ERR_CAUSE 18
|
||||
#define GAUDI2_NUM_OF_QM_LCP_ERR_CAUSE 25
|
||||
#define GAUDI2_NUM_OF_LOWER_QM_ERR_CAUSE 25
|
||||
#define GAUDI2_NUM_OF_QM_ARB_ERR_CAUSE 3
|
||||
#define GAUDI2_NUM_OF_ARC_SEI_ERR_CAUSE 14
|
||||
#define GAUDI2_NUM_OF_CPU_SEI_ERR_CAUSE 3
|
||||
#define GAUDI2_NUM_OF_QM_SEI_ERR_CAUSE 2
|
||||
#define GAUDI2_NUM_OF_ROT_ERR_CAUSE 22
|
||||
#define GAUDI2_NUM_OF_TPC_INTR_CAUSE 30
|
||||
#define GAUDI2_NUM_OF_TPC_INTR_CAUSE 31
|
||||
#define GAUDI2_NUM_OF_DEC_ERR_CAUSE 25
|
||||
#define GAUDI2_NUM_OF_MME_ERR_CAUSE 16
|
||||
#define GAUDI2_NUM_OF_MME_SBTE_ERR_CAUSE 5
|
||||
@ -162,6 +162,9 @@
|
||||
#define PSOC_RAZWI_ENG_STR_SIZE 128
|
||||
#define PSOC_RAZWI_MAX_ENG_PER_RTR 5
|
||||
|
||||
/* HW scrambles only bits 0-25 */
|
||||
#define HW_UNSCRAMBLED_BITS_MASK GENMASK_ULL(63, 26)
|
||||
|
||||
struct gaudi2_razwi_info {
|
||||
u32 axuser_xy;
|
||||
u32 rtr_ctrl;
|
||||
@ -801,7 +804,7 @@ static const char * const gaudi2_qman_error_cause[GAUDI2_NUM_OF_QM_ERR_CAUSE] =
|
||||
"PQC L2H error"
|
||||
};
|
||||
|
||||
static const char * const gaudi2_qman_lower_cp_error_cause[GAUDI2_NUM_OF_QM_LCP_ERR_CAUSE] = {
|
||||
static const char * const gaudi2_lower_qman_error_cause[GAUDI2_NUM_OF_LOWER_QM_ERR_CAUSE] = {
|
||||
"RSVD0",
|
||||
"CQ AXI HBW error",
|
||||
"CP AXI HBW error",
|
||||
@ -891,6 +894,7 @@ static const char * const gaudi2_tpc_interrupts_cause[GAUDI2_NUM_OF_TPC_INTR_CAU
|
||||
"invalid_lock_access",
|
||||
"LD_L protection violation",
|
||||
"ST_L protection violation",
|
||||
"D$ L0CS mismatch",
|
||||
};
|
||||
|
||||
static const char * const guadi2_mme_error_cause[GAUDI2_NUM_OF_MME_ERR_CAUSE] = {
|
||||
@ -3615,6 +3619,12 @@ static int gaudi2_sw_init(struct hl_device *hdev)
|
||||
|
||||
prop->supports_compute_reset = true;
|
||||
|
||||
/* Event queue sanity check added in FW version 1.11 */
|
||||
if (hl_is_fw_sw_ver_below(hdev, 1, 11))
|
||||
hdev->event_queue.check_eqe_index = false;
|
||||
else
|
||||
hdev->event_queue.check_eqe_index = true;
|
||||
|
||||
hdev->asic_funcs->set_pci_memory_regions(hdev);
|
||||
|
||||
rc = gaudi2_special_blocks_iterator_config(hdev);
|
||||
@ -3630,8 +3640,8 @@ static int gaudi2_sw_init(struct hl_device *hdev)
|
||||
special_blocks_free:
|
||||
gaudi2_special_blocks_iterator_free(hdev);
|
||||
free_scratchpad_mem:
|
||||
hl_asic_dma_pool_free(hdev, gaudi2->scratchpad_kernel_address,
|
||||
gaudi2->scratchpad_bus_address);
|
||||
hl_asic_dma_free_coherent(hdev, PAGE_SIZE, gaudi2->scratchpad_kernel_address,
|
||||
gaudi2->scratchpad_bus_address);
|
||||
free_virt_msix_db_mem:
|
||||
hl_cpu_accessible_dma_pool_free(hdev, prop->pmmu.page_size, gaudi2->virt_msix_db_cpu_addr);
|
||||
free_cpu_accessible_dma_pool:
|
||||
@ -4526,7 +4536,7 @@ static int gaudi2_set_tpc_engine_mode(struct hl_device *hdev, u32 engine_id, u32
|
||||
reg_base = gaudi2_tpc_cfg_blocks_bases[tpc_id];
|
||||
reg_addr = reg_base + TPC_CFG_STALL_OFFSET;
|
||||
reg_val = FIELD_PREP(DCORE0_TPC0_CFG_TPC_STALL_V_MASK,
|
||||
!!(engine_command == HL_ENGINE_STALL));
|
||||
(engine_command == HL_ENGINE_STALL) ? 1 : 0);
|
||||
WREG32(reg_addr, reg_val);
|
||||
|
||||
if (engine_command == HL_ENGINE_RESUME) {
|
||||
@ -4550,7 +4560,7 @@ static int gaudi2_set_mme_engine_mode(struct hl_device *hdev, u32 engine_id, u32
|
||||
reg_base = gaudi2_mme_ctrl_lo_blocks_bases[mme_id];
|
||||
reg_addr = reg_base + MME_CTRL_LO_QM_STALL_OFFSET;
|
||||
reg_val = FIELD_PREP(DCORE0_MME_CTRL_LO_QM_STALL_V_MASK,
|
||||
!!(engine_command == HL_ENGINE_STALL));
|
||||
(engine_command == HL_ENGINE_STALL) ? 1 : 0);
|
||||
WREG32(reg_addr, reg_val);
|
||||
|
||||
return 0;
|
||||
@ -4571,7 +4581,7 @@ static int gaudi2_set_edma_engine_mode(struct hl_device *hdev, u32 engine_id, u3
|
||||
reg_base = gaudi2_dma_core_blocks_bases[edma_id];
|
||||
reg_addr = reg_base + EDMA_CORE_CFG_STALL_OFFSET;
|
||||
reg_val = FIELD_PREP(DCORE0_EDMA0_CORE_CFG_1_HALT_MASK,
|
||||
!!(engine_command == HL_ENGINE_STALL));
|
||||
(engine_command == HL_ENGINE_STALL) ? 1 : 0);
|
||||
WREG32(reg_addr, reg_val);
|
||||
|
||||
if (engine_command == HL_ENGINE_STALL) {
|
||||
@ -6148,18 +6158,24 @@ static int gaudi2_execute_soft_reset(struct hl_device *hdev, bool driver_perform
|
||||
u32 poll_timeout_us)
|
||||
{
|
||||
struct cpu_dyn_regs *dyn_regs = &hdev->fw_loader.dynamic_loader.comm_desc.cpu_dyn_regs;
|
||||
int rc = 0;
|
||||
|
||||
if (!driver_performs_reset) {
|
||||
/* set SP to indicate reset request sent to FW */
|
||||
if (dyn_regs->cpu_rst_status)
|
||||
WREG32(le32_to_cpu(dyn_regs->cpu_rst_status), CPU_RST_STATUS_NA);
|
||||
else
|
||||
WREG32(mmCPU_RST_STATUS_TO_HOST, CPU_RST_STATUS_NA);
|
||||
if (hl_is_fw_sw_ver_below(hdev, 1, 10)) {
|
||||
/* set SP to indicate reset request sent to FW */
|
||||
if (dyn_regs->cpu_rst_status)
|
||||
WREG32(le32_to_cpu(dyn_regs->cpu_rst_status), CPU_RST_STATUS_NA);
|
||||
else
|
||||
WREG32(mmCPU_RST_STATUS_TO_HOST, CPU_RST_STATUS_NA);
|
||||
WREG32(le32_to_cpu(dyn_regs->gic_host_soft_rst_irq),
|
||||
gaudi2_irq_map_table[GAUDI2_EVENT_CPU_SOFT_RESET].cpu_id);
|
||||
|
||||
WREG32(le32_to_cpu(dyn_regs->gic_host_soft_rst_irq),
|
||||
gaudi2_irq_map_table[GAUDI2_EVENT_CPU_SOFT_RESET].cpu_id);
|
||||
|
||||
return gaudi2_get_soft_rst_done_indication(hdev, poll_timeout_us);
|
||||
/* wait for f/w response */
|
||||
rc = gaudi2_get_soft_rst_done_indication(hdev, poll_timeout_us);
|
||||
} else {
|
||||
rc = hl_fw_send_soft_reset(hdev);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Block access to engines, QMANs and SM during reset, these
|
||||
@ -7231,7 +7247,7 @@ static bool gaudi2_get_tpc_idle_status(struct hl_device *hdev, u64 *mask_arr, u8
|
||||
|
||||
gaudi2_iterate_tpcs(hdev, &tpc_iter);
|
||||
|
||||
return tpc_idle_data.is_idle;
|
||||
return *tpc_idle_data.is_idle;
|
||||
}
|
||||
|
||||
static bool gaudi2_get_decoder_idle_status(struct hl_device *hdev, u64 *mask_arr, u8 mask_len,
|
||||
@ -7737,137 +7753,28 @@ static bool gaudi2_handle_ecc_event(struct hl_device *hdev, u16 event_type,
|
||||
return !!ecc_data->is_critical;
|
||||
}
|
||||
|
||||
/*
|
||||
* gaudi2_queue_idx_dec - decrement queue index (pi/ci) and handle wrap
|
||||
*
|
||||
* @idx: the current pi/ci value
|
||||
* @q_len: the queue length (power of 2)
|
||||
*
|
||||
* @return the cyclically decremented index
|
||||
*/
|
||||
static inline u32 gaudi2_queue_idx_dec(u32 idx, u32 q_len)
|
||||
static void print_lower_qman_data_on_err(struct hl_device *hdev, u64 qman_base)
|
||||
{
|
||||
u32 mask = q_len - 1;
|
||||
u32 lo, hi, cq_ptr_size, arc_cq_ptr_size;
|
||||
u64 cq_ptr, arc_cq_ptr, cp_current_inst;
|
||||
|
||||
/*
|
||||
* modular decrement is equivalent to adding (queue_size -1)
|
||||
* later we take LSBs to make sure the value is in the
|
||||
* range [0, queue_len - 1]
|
||||
*/
|
||||
return (idx + q_len - 1) & mask;
|
||||
}
|
||||
lo = RREG32(qman_base + QM_CQ_PTR_LO_4_OFFSET);
|
||||
hi = RREG32(qman_base + QM_CQ_PTR_HI_4_OFFSET);
|
||||
cq_ptr = ((u64) hi) << 32 | lo;
|
||||
cq_ptr_size = RREG32(qman_base + QM_CQ_TSIZE_4_OFFSET);
|
||||
|
||||
/**
|
||||
* gaudi2_print_sw_config_stream_data - print SW config stream data
|
||||
*
|
||||
* @hdev: pointer to the habanalabs device structure
|
||||
* @stream: the QMAN's stream
|
||||
* @qman_base: base address of QMAN registers block
|
||||
*/
|
||||
static void gaudi2_print_sw_config_stream_data(struct hl_device *hdev,
|
||||
u32 stream, u64 qman_base)
|
||||
{
|
||||
u64 cq_ptr_lo, cq_ptr_hi, cq_tsize, cq_ptr;
|
||||
u32 cq_ptr_lo_off, size;
|
||||
lo = RREG32(qman_base + QM_ARC_CQ_PTR_LO_OFFSET);
|
||||
hi = RREG32(qman_base + QM_ARC_CQ_PTR_HI_OFFSET);
|
||||
arc_cq_ptr = ((u64) hi) << 32 | lo;
|
||||
arc_cq_ptr_size = RREG32(qman_base + QM_ARC_CQ_TSIZE_OFFSET);
|
||||
|
||||
cq_ptr_lo_off = mmDCORE0_TPC0_QM_CQ_PTR_LO_1 - mmDCORE0_TPC0_QM_CQ_PTR_LO_0;
|
||||
lo = RREG32(qman_base + QM_CP_CURRENT_INST_LO_4_OFFSET);
|
||||
hi = RREG32(qman_base + QM_CP_CURRENT_INST_HI_4_OFFSET);
|
||||
cp_current_inst = ((u64) hi) << 32 | lo;
|
||||
|
||||
cq_ptr_lo = qman_base + (mmDCORE0_TPC0_QM_CQ_PTR_LO_0 - mmDCORE0_TPC0_QM_BASE) +
|
||||
stream * cq_ptr_lo_off;
|
||||
|
||||
cq_ptr_hi = cq_ptr_lo + (mmDCORE0_TPC0_QM_CQ_PTR_HI_0 - mmDCORE0_TPC0_QM_CQ_PTR_LO_0);
|
||||
|
||||
cq_tsize = cq_ptr_lo + (mmDCORE0_TPC0_QM_CQ_TSIZE_0 - mmDCORE0_TPC0_QM_CQ_PTR_LO_0);
|
||||
|
||||
cq_ptr = (((u64) RREG32(cq_ptr_hi)) << 32) | RREG32(cq_ptr_lo);
|
||||
size = RREG32(cq_tsize);
|
||||
dev_info(hdev->dev, "stop on err: stream: %u, addr: %#llx, size: %x\n",
|
||||
stream, cq_ptr, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* gaudi2_print_last_pqes_on_err - print last PQEs on error
|
||||
*
|
||||
* @hdev: pointer to the habanalabs device structure
|
||||
* @qid_base: first QID of the QMAN (out of 4 streams)
|
||||
* @stream: the QMAN's stream
|
||||
* @qman_base: base address of QMAN registers block
|
||||
* @pr_sw_conf: if true print the SW config stream data (CQ PTR and SIZE)
|
||||
*/
|
||||
static void gaudi2_print_last_pqes_on_err(struct hl_device *hdev, u32 qid_base, u32 stream,
|
||||
u64 qman_base, bool pr_sw_conf)
|
||||
{
|
||||
u32 ci, qm_ci_stream_off;
|
||||
struct hl_hw_queue *q;
|
||||
u64 pq_ci;
|
||||
int i;
|
||||
|
||||
q = &hdev->kernel_queues[qid_base + stream];
|
||||
|
||||
qm_ci_stream_off = mmDCORE0_TPC0_QM_PQ_CI_1 - mmDCORE0_TPC0_QM_PQ_CI_0;
|
||||
pq_ci = qman_base + (mmDCORE0_TPC0_QM_PQ_CI_0 - mmDCORE0_TPC0_QM_BASE) +
|
||||
stream * qm_ci_stream_off;
|
||||
|
||||
hdev->asic_funcs->hw_queues_lock(hdev);
|
||||
|
||||
if (pr_sw_conf)
|
||||
gaudi2_print_sw_config_stream_data(hdev, stream, qman_base);
|
||||
|
||||
ci = RREG32(pq_ci);
|
||||
|
||||
/* we should start printing form ci -1 */
|
||||
ci = gaudi2_queue_idx_dec(ci, HL_QUEUE_LENGTH);
|
||||
|
||||
for (i = 0; i < PQ_FETCHER_CACHE_SIZE; i++) {
|
||||
struct hl_bd *bd;
|
||||
u64 addr;
|
||||
u32 len;
|
||||
|
||||
bd = q->kernel_address;
|
||||
bd += ci;
|
||||
|
||||
len = le32_to_cpu(bd->len);
|
||||
/* len 0 means uninitialized entry- break */
|
||||
if (!len)
|
||||
break;
|
||||
|
||||
addr = le64_to_cpu(bd->ptr);
|
||||
|
||||
dev_info(hdev->dev, "stop on err PQE(stream %u): ci: %u, addr: %#llx, size: %x\n",
|
||||
stream, ci, addr, len);
|
||||
|
||||
/* get previous ci, wrap if needed */
|
||||
ci = gaudi2_queue_idx_dec(ci, HL_QUEUE_LENGTH);
|
||||
}
|
||||
|
||||
hdev->asic_funcs->hw_queues_unlock(hdev);
|
||||
}
|
||||
|
||||
/**
|
||||
* print_qman_data_on_err - extract QMAN data on error
|
||||
*
|
||||
* @hdev: pointer to the habanalabs device structure
|
||||
* @qid_base: first QID of the QMAN (out of 4 streams)
|
||||
* @stream: the QMAN's stream
|
||||
* @qman_base: base address of QMAN registers block
|
||||
*
|
||||
* This function attempt to extract as much data as possible on QMAN error.
|
||||
* On upper CP print the SW config stream data and last 8 PQEs.
|
||||
* On lower CP print SW config data and last PQEs of ALL 4 upper CPs
|
||||
*/
|
||||
static void print_qman_data_on_err(struct hl_device *hdev, u32 qid_base, u32 stream, u64 qman_base)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
if (stream != QMAN_STREAMS) {
|
||||
gaudi2_print_last_pqes_on_err(hdev, qid_base, stream, qman_base, true);
|
||||
return;
|
||||
}
|
||||
|
||||
gaudi2_print_sw_config_stream_data(hdev, stream, qman_base);
|
||||
|
||||
for (i = 0 ; i < QMAN_STREAMS ; i++)
|
||||
gaudi2_print_last_pqes_on_err(hdev, qid_base, i, qman_base, false);
|
||||
dev_info(hdev->dev,
|
||||
"LowerQM. CQ: {ptr %#llx, size %u}, ARC_CQ: {ptr %#llx, size %u}, CP: {instruction %#llx}\n",
|
||||
cq_ptr, cq_ptr_size, arc_cq_ptr, arc_cq_ptr_size, cp_current_inst);
|
||||
}
|
||||
|
||||
static int gaudi2_handle_qman_err_generic(struct hl_device *hdev, u16 event_type,
|
||||
@ -7888,8 +7795,8 @@ static int gaudi2_handle_qman_err_generic(struct hl_device *hdev, u16 event_type
|
||||
continue;
|
||||
|
||||
if (i == QMAN_STREAMS) {
|
||||
snprintf(reg_desc, ARRAY_SIZE(reg_desc), "LowerCP");
|
||||
num_error_causes = GAUDI2_NUM_OF_QM_LCP_ERR_CAUSE;
|
||||
snprintf(reg_desc, ARRAY_SIZE(reg_desc), "LowerQM");
|
||||
num_error_causes = GAUDI2_NUM_OF_LOWER_QM_ERR_CAUSE;
|
||||
} else {
|
||||
snprintf(reg_desc, ARRAY_SIZE(reg_desc), "stream%u", i);
|
||||
num_error_causes = GAUDI2_NUM_OF_QM_ERR_CAUSE;
|
||||
@ -7900,12 +7807,13 @@ static int gaudi2_handle_qman_err_generic(struct hl_device *hdev, u16 event_type
|
||||
gaudi2_print_event(hdev, event_type, true,
|
||||
"%s. err cause: %s", reg_desc,
|
||||
i == QMAN_STREAMS ?
|
||||
gaudi2_qman_lower_cp_error_cause[j] :
|
||||
gaudi2_lower_qman_error_cause[j] :
|
||||
gaudi2_qman_error_cause[j]);
|
||||
error_count++;
|
||||
}
|
||||
|
||||
print_qman_data_on_err(hdev, qid_base, i, qman_base);
|
||||
if (i == QMAN_STREAMS)
|
||||
print_lower_qman_data_on_err(hdev, qman_base);
|
||||
}
|
||||
|
||||
arb_err_val = RREG32(arb_err_addr);
|
||||
@ -8033,7 +7941,7 @@ static void gaudi2_ack_module_razwi_event_handler(struct hl_device *hdev,
|
||||
u8 module_sub_idx, u64 *event_mask)
|
||||
{
|
||||
bool via_sft = false;
|
||||
u32 hbw_rtr_id, lbw_rtr_id, dcore_id, dcore_rtr_id, eng_id;
|
||||
u32 hbw_rtr_id, lbw_rtr_id, dcore_id, dcore_rtr_id, eng_id, binned_idx;
|
||||
u64 hbw_rtr_mstr_if_base_addr, lbw_rtr_mstr_if_base_addr;
|
||||
u32 hbw_shrd_aw = 0, hbw_shrd_ar = 0;
|
||||
u32 lbw_shrd_aw = 0, lbw_shrd_ar = 0;
|
||||
@ -8041,15 +7949,21 @@ static void gaudi2_ack_module_razwi_event_handler(struct hl_device *hdev,
|
||||
|
||||
switch (module) {
|
||||
case RAZWI_TPC:
|
||||
sprintf(initiator_name, "TPC_%u", module_idx);
|
||||
if (hdev->tpc_binning) {
|
||||
binned_idx = __ffs(hdev->tpc_binning);
|
||||
if (binned_idx == module_idx)
|
||||
module_idx = TPC_ID_DCORE0_TPC6;
|
||||
}
|
||||
|
||||
hbw_rtr_id = gaudi2_tpc_initiator_hbw_rtr_id[module_idx];
|
||||
|
||||
if (hl_is_fw_ver_below_1_9(hdev) &&
|
||||
if (hl_is_fw_sw_ver_below(hdev, 1, 9) &&
|
||||
!hdev->asic_prop.fw_security_enabled &&
|
||||
((module_idx == 0) || (module_idx == 1)))
|
||||
lbw_rtr_id = DCORE0_RTR0;
|
||||
else
|
||||
lbw_rtr_id = gaudi2_tpc_initiator_lbw_rtr_id[module_idx];
|
||||
sprintf(initiator_name, "TPC_%u", module_idx);
|
||||
break;
|
||||
case RAZWI_MME:
|
||||
sprintf(initiator_name, "MME_%u", module_idx);
|
||||
@ -8108,9 +8022,14 @@ static void gaudi2_ack_module_razwi_event_handler(struct hl_device *hdev,
|
||||
sprintf(initiator_name, "NIC_%u", module_idx);
|
||||
break;
|
||||
case RAZWI_DEC:
|
||||
sprintf(initiator_name, "DEC_%u", module_idx);
|
||||
if (hdev->decoder_binning) {
|
||||
binned_idx = __ffs(hdev->decoder_binning);
|
||||
if (binned_idx == module_idx)
|
||||
module_idx = DEC_ID_PCIE_VDEC1;
|
||||
}
|
||||
hbw_rtr_id = gaudi2_dec_initiator_hbw_rtr_id[module_idx];
|
||||
lbw_rtr_id = gaudi2_dec_initiator_lbw_rtr_id[module_idx];
|
||||
sprintf(initiator_name, "DEC_%u", module_idx);
|
||||
break;
|
||||
case RAZWI_ROT:
|
||||
hbw_rtr_id = gaudi2_rot_initiator_hbw_rtr_id[module_idx];
|
||||
@ -8251,6 +8170,7 @@ static bool gaudi2_handle_psoc_razwi_happened(struct hl_device *hdev, u32 razwi_
|
||||
u16 num_of_eng, eng_id[PSOC_RAZWI_MAX_ENG_PER_RTR];
|
||||
char eng_name_str[PSOC_RAZWI_ENG_STR_SIZE];
|
||||
bool razwi_happened = false;
|
||||
u64 addr;
|
||||
int i;
|
||||
|
||||
num_of_eng = gaudi2_psoc_razwi_get_engines(common_razwi_info, ARRAY_SIZE(common_razwi_info),
|
||||
@ -8269,43 +8189,53 @@ static bool gaudi2_handle_psoc_razwi_happened(struct hl_device *hdev, u32 razwi_
|
||||
if (RREG32(base[i] + DEC_RAZWI_HBW_AW_SET)) {
|
||||
addr_hi = RREG32(base[i] + DEC_RAZWI_HBW_AW_ADDR_HI);
|
||||
addr_lo = RREG32(base[i] + DEC_RAZWI_HBW_AW_ADDR_LO);
|
||||
dev_err(hdev->dev,
|
||||
addr = ((u64)addr_hi << 32) + addr_lo;
|
||||
if (addr) {
|
||||
dev_err(hdev->dev,
|
||||
"PSOC HBW AW RAZWI: %s, address (aligned to 128 byte): 0x%llX\n",
|
||||
eng_name_str, ((u64)addr_hi << 32) + addr_lo);
|
||||
hl_handle_razwi(hdev, ((u64)addr_hi << 32) + addr_lo, &eng_id[0],
|
||||
eng_name_str, addr);
|
||||
hl_handle_razwi(hdev, addr, &eng_id[0],
|
||||
num_of_eng, HL_RAZWI_HBW | HL_RAZWI_WRITE, event_mask);
|
||||
razwi_happened = true;
|
||||
razwi_happened = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (RREG32(base[i] + DEC_RAZWI_HBW_AR_SET)) {
|
||||
addr_hi = RREG32(base[i] + DEC_RAZWI_HBW_AR_ADDR_HI);
|
||||
addr_lo = RREG32(base[i] + DEC_RAZWI_HBW_AR_ADDR_LO);
|
||||
dev_err(hdev->dev,
|
||||
addr = ((u64)addr_hi << 32) + addr_lo;
|
||||
if (addr) {
|
||||
dev_err(hdev->dev,
|
||||
"PSOC HBW AR RAZWI: %s, address (aligned to 128 byte): 0x%llX\n",
|
||||
eng_name_str, ((u64)addr_hi << 32) + addr_lo);
|
||||
hl_handle_razwi(hdev, ((u64)addr_hi << 32) + addr_lo, &eng_id[0],
|
||||
eng_name_str, addr);
|
||||
hl_handle_razwi(hdev, addr, &eng_id[0],
|
||||
num_of_eng, HL_RAZWI_HBW | HL_RAZWI_READ, event_mask);
|
||||
razwi_happened = true;
|
||||
razwi_happened = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (RREG32(base[i] + DEC_RAZWI_LBW_AW_SET)) {
|
||||
addr_lo = RREG32(base[i] + DEC_RAZWI_LBW_AW_ADDR);
|
||||
dev_err(hdev->dev,
|
||||
if (addr_lo) {
|
||||
dev_err(hdev->dev,
|
||||
"PSOC LBW AW RAZWI: %s, address (aligned to 128 byte): 0x%X\n",
|
||||
eng_name_str, addr_lo);
|
||||
hl_handle_razwi(hdev, addr_lo, &eng_id[0],
|
||||
hl_handle_razwi(hdev, addr_lo, &eng_id[0],
|
||||
num_of_eng, HL_RAZWI_LBW | HL_RAZWI_WRITE, event_mask);
|
||||
razwi_happened = true;
|
||||
razwi_happened = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (RREG32(base[i] + DEC_RAZWI_LBW_AR_SET)) {
|
||||
addr_lo = RREG32(base[i] + DEC_RAZWI_LBW_AR_ADDR);
|
||||
dev_err(hdev->dev,
|
||||
"PSOC LBW AR RAZWI: %s, address (aligned to 128 byte): 0x%X\n",
|
||||
eng_name_str, addr_lo);
|
||||
hl_handle_razwi(hdev, addr_lo, &eng_id[0],
|
||||
if (addr_lo) {
|
||||
dev_err(hdev->dev,
|
||||
"PSOC LBW AR RAZWI: %s, address (aligned to 128 byte): 0x%X\n",
|
||||
eng_name_str, addr_lo);
|
||||
hl_handle_razwi(hdev, addr_lo, &eng_id[0],
|
||||
num_of_eng, HL_RAZWI_LBW | HL_RAZWI_READ, event_mask);
|
||||
razwi_happened = true;
|
||||
razwi_happened = true;
|
||||
}
|
||||
}
|
||||
/* In common case the loop will break, when there is only one engine id, or
|
||||
* several engines with the same router. The exceptional case is with psoc razwi
|
||||
@ -8789,13 +8719,13 @@ static int gaudi2_handle_kdma_core_event(struct hl_device *hdev, u16 event_type,
|
||||
return error_count;
|
||||
}
|
||||
|
||||
static int gaudi2_handle_dma_core_event(struct hl_device *hdev, u16 event_type, int sts_addr)
|
||||
static int gaudi2_handle_dma_core_event(struct hl_device *hdev, u16 event_type, u64 intr_cause)
|
||||
{
|
||||
u32 error_count = 0, sts_val = RREG32(sts_addr);
|
||||
u32 error_count = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < GAUDI2_NUM_OF_DMA_CORE_INTR_CAUSE ; i++)
|
||||
if (sts_val & BIT(i)) {
|
||||
if (intr_cause & BIT(i)) {
|
||||
gaudi2_print_event(hdev, event_type, true,
|
||||
"err cause: %s", gaudi2_dma_core_interrupts_cause[i]);
|
||||
error_count++;
|
||||
@ -8806,27 +8736,6 @@ static int gaudi2_handle_dma_core_event(struct hl_device *hdev, u16 event_type,
|
||||
return error_count;
|
||||
}
|
||||
|
||||
static int gaudi2_handle_pdma_core_event(struct hl_device *hdev, u16 event_type, int pdma_idx)
|
||||
{
|
||||
u32 sts_addr;
|
||||
|
||||
sts_addr = mmPDMA0_CORE_ERR_CAUSE + pdma_idx * PDMA_OFFSET;
|
||||
return gaudi2_handle_dma_core_event(hdev, event_type, sts_addr);
|
||||
}
|
||||
|
||||
static int gaudi2_handle_edma_core_event(struct hl_device *hdev, u16 event_type, int edma_idx)
|
||||
{
|
||||
static const int edma_event_index_map[] = {2, 3, 0, 1, 6, 7, 4, 5};
|
||||
u32 sts_addr, index;
|
||||
|
||||
index = edma_event_index_map[edma_idx];
|
||||
|
||||
sts_addr = mmDCORE0_EDMA0_CORE_ERR_CAUSE +
|
||||
DCORE_OFFSET * (index / NUM_OF_EDMA_PER_DCORE) +
|
||||
DCORE_EDMA_OFFSET * (index % NUM_OF_EDMA_PER_DCORE);
|
||||
return gaudi2_handle_dma_core_event(hdev, event_type, sts_addr);
|
||||
}
|
||||
|
||||
static void gaudi2_print_pcie_mstr_rr_mstr_if_razwi_info(struct hl_device *hdev, u64 *event_mask)
|
||||
{
|
||||
u32 mstr_if_base_addr = mmPCIE_MSTR_RR_MSTR_IF_RR_SHRD_HBW_BASE, razwi_happened_addr;
|
||||
@ -8866,6 +8775,9 @@ static int gaudi2_print_pcie_addr_dec_info(struct hl_device *hdev, u16 event_typ
|
||||
u32 error_count = 0;
|
||||
int i;
|
||||
|
||||
gaudi2_print_event(hdev, event_type, true,
|
||||
"intr_cause_data: %#llx", intr_cause_data);
|
||||
|
||||
for (i = 0 ; i < GAUDI2_NUM_OF_PCIE_ADDR_DEC_ERR_CAUSE ; i++) {
|
||||
if (!(intr_cause_data & BIT_ULL(i)))
|
||||
continue;
|
||||
@ -8874,16 +8786,15 @@ static int gaudi2_print_pcie_addr_dec_info(struct hl_device *hdev, u16 event_typ
|
||||
"err cause: %s", gaudi2_pcie_addr_dec_error_cause[i]);
|
||||
error_count++;
|
||||
|
||||
switch (intr_cause_data & BIT_ULL(i)) {
|
||||
case PCIE_WRAP_PCIE_IC_SEI_INTR_IND_AXI_LBW_ERR_INTR_MASK:
|
||||
hl_check_for_glbl_errors(hdev);
|
||||
break;
|
||||
case PCIE_WRAP_PCIE_IC_SEI_INTR_IND_BAD_ACCESS_INTR_MASK:
|
||||
gaudi2_print_pcie_mstr_rr_mstr_if_razwi_info(hdev, event_mask);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Always check for LBW and HBW additional info as the indication itself is
|
||||
* sometimes missing
|
||||
*/
|
||||
}
|
||||
|
||||
hl_check_for_glbl_errors(hdev);
|
||||
gaudi2_print_pcie_mstr_rr_mstr_if_razwi_info(hdev, event_mask);
|
||||
|
||||
return error_count;
|
||||
}
|
||||
|
||||
@ -8937,11 +8848,16 @@ static void gaudi2_handle_page_error(struct hl_device *hdev, u64 mmu_base, bool
|
||||
addr <<= 32;
|
||||
addr |= RREG32(mmu_base + MMU_OFFSET(mmDCORE0_HMMU0_MMU_PAGE_ERROR_CAPTURE_VA));
|
||||
|
||||
if (!is_pmmu)
|
||||
addr = gaudi2_mmu_descramble_addr(hdev, addr);
|
||||
if (is_pmmu) {
|
||||
dev_err_ratelimited(hdev->dev, "PMMU page fault on va 0x%llx\n", addr);
|
||||
} else {
|
||||
|
||||
addr = gaudi2_mmu_descramble_addr(hdev, addr);
|
||||
addr &= HW_UNSCRAMBLED_BITS_MASK;
|
||||
dev_err_ratelimited(hdev->dev, "HMMU page fault on va range 0x%llx - 0x%llx\n",
|
||||
addr, addr + ~HW_UNSCRAMBLED_BITS_MASK);
|
||||
}
|
||||
|
||||
dev_err_ratelimited(hdev->dev, "%s page fault on va 0x%llx\n",
|
||||
is_pmmu ? "PMMU" : "HMMU", addr);
|
||||
hl_handle_page_fault(hdev, addr, 0, is_pmmu, event_mask);
|
||||
|
||||
WREG32(mmu_base + MMU_OFFSET(mmDCORE0_HMMU0_MMU_ACCESS_PAGE_ERROR_VALID), 0);
|
||||
@ -9709,19 +9625,19 @@ static void gaudi2_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_ent
|
||||
case GAUDI2_EVENT_KDMA_CH0_AXI_ERR_RSP:
|
||||
case GAUDI2_EVENT_KDMA0_CORE:
|
||||
error_count = gaudi2_handle_kdma_core_event(hdev, event_type,
|
||||
le64_to_cpu(eq_entry->intr_cause.intr_cause_data));
|
||||
le64_to_cpu(eq_entry->intr_cause.intr_cause_data));
|
||||
event_mask |= HL_NOTIFIER_EVENT_GENERAL_HW_ERR;
|
||||
break;
|
||||
|
||||
case GAUDI2_EVENT_HDMA2_CORE ... GAUDI2_EVENT_HDMA5_CORE:
|
||||
index = event_type - GAUDI2_EVENT_HDMA2_CORE;
|
||||
error_count = gaudi2_handle_edma_core_event(hdev, event_type, index);
|
||||
error_count = gaudi2_handle_dma_core_event(hdev, event_type,
|
||||
le64_to_cpu(eq_entry->intr_cause.intr_cause_data));
|
||||
event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR;
|
||||
break;
|
||||
|
||||
case GAUDI2_EVENT_PDMA0_CORE ... GAUDI2_EVENT_PDMA1_CORE:
|
||||
index = event_type - GAUDI2_EVENT_PDMA0_CORE;
|
||||
error_count = gaudi2_handle_pdma_core_event(hdev, event_type, index);
|
||||
error_count = gaudi2_handle_dma_core_event(hdev, event_type,
|
||||
le64_to_cpu(eq_entry->intr_cause.intr_cause_data));
|
||||
event_mask |= HL_NOTIFIER_EVENT_USER_ENGINE_ERR;
|
||||
break;
|
||||
|
||||
|
@ -98,7 +98,7 @@
|
||||
#define GAUDI2_DEFAULT_CARD_NAME "HL225"
|
||||
|
||||
#define QMAN_STREAMS 4
|
||||
#define PQ_FETCHER_CACHE_SIZE 8
|
||||
|
||||
#define NUM_OF_MME_SBTE_PORTS 5
|
||||
#define NUM_OF_MME_WB_PORTS 2
|
||||
|
||||
|
@ -479,6 +479,7 @@ static const u32 gaudi2_pb_dcr0_edma0_unsecured_regs[] = {
|
||||
mmDCORE0_EDMA0_CORE_CTX_TE_NUMROWS,
|
||||
mmDCORE0_EDMA0_CORE_CTX_IDX,
|
||||
mmDCORE0_EDMA0_CORE_CTX_IDX_INC,
|
||||
mmDCORE0_EDMA0_CORE_RD_LBW_RATE_LIM_CFG,
|
||||
mmDCORE0_EDMA0_QM_CQ_CFG0_0,
|
||||
mmDCORE0_EDMA0_QM_CQ_CFG0_1,
|
||||
mmDCORE0_EDMA0_QM_CQ_CFG0_2,
|
||||
@ -1533,6 +1534,10 @@ static const u32 gaudi2_pb_dcr0_tpc0_unsecured_regs[] = {
|
||||
mmDCORE0_TPC0_CFG_QM_KERNEL_CONFIG,
|
||||
mmDCORE0_TPC0_CFG_QM_KERNEL_ID,
|
||||
mmDCORE0_TPC0_CFG_QM_POWER_LOOP,
|
||||
mmDCORE0_TPC0_CFG_TSB_CFG_MTRR_2_0,
|
||||
mmDCORE0_TPC0_CFG_TSB_CFG_MTRR_2_1,
|
||||
mmDCORE0_TPC0_CFG_TSB_CFG_MTRR_2_2,
|
||||
mmDCORE0_TPC0_CFG_TSB_CFG_MTRR_2_3,
|
||||
mmDCORE0_TPC0_CFG_LUT_FUNC32_BASE2_ADDR_LO,
|
||||
mmDCORE0_TPC0_CFG_LUT_FUNC32_BASE2_ADDR_HI,
|
||||
mmDCORE0_TPC0_CFG_LUT_FUNC64_BASE2_ADDR_LO,
|
||||
@ -1541,6 +1546,7 @@ static const u32 gaudi2_pb_dcr0_tpc0_unsecured_regs[] = {
|
||||
mmDCORE0_TPC0_CFG_LUT_FUNC128_BASE2_ADDR_HI,
|
||||
mmDCORE0_TPC0_CFG_LUT_FUNC256_BASE2_ADDR_LO,
|
||||
mmDCORE0_TPC0_CFG_LUT_FUNC256_BASE2_ADDR_HI,
|
||||
mmDCORE0_TPC0_CFG_FP8_143_BIAS,
|
||||
mmDCORE0_TPC0_CFG_ROUND_CSR,
|
||||
mmDCORE0_TPC0_CFG_CONV_ROUND_CSR,
|
||||
mmDCORE0_TPC0_CFG_SEMAPHORE,
|
||||
@ -3442,15 +3448,6 @@ static int gaudi2_init_protection_bits(struct hl_device *hdev)
|
||||
ARRAY_SIZE(gaudi2_pb_thermal_sensor0), NULL, HL_PB_NA);
|
||||
}
|
||||
|
||||
/* HBM */
|
||||
/* Temporarily skip until SW-63348 is solved
|
||||
* instance_offset = mmHBM1_MC0_BASE - mmHBM0_MC0_BASE;
|
||||
* rc |= hl_init_pb_with_mask(hdev, HL_PB_SHARED, HL_PB_NA, GAUDI2_HBM_NUM,
|
||||
* instance_offset, gaudi2_pb_hbm,
|
||||
* ARRAY_SIZE(gaudi2_pb_hbm), NULL, HL_PB_NA,
|
||||
* prop->dram_enabled_mask);
|
||||
*/
|
||||
|
||||
/* Scheduler ARCs */
|
||||
instance_offset = mmARC_FARM_ARC1_AUX_BASE - mmARC_FARM_ARC0_AUX_BASE;
|
||||
rc |= hl_init_pb_ranges(hdev, HL_PB_SHARED, HL_PB_NA,
|
||||
|
@ -2671,9 +2671,6 @@ int goya_mmu_init(struct hl_device *hdev)
|
||||
u64 hop0_addr;
|
||||
int rc, i;
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
return 0;
|
||||
|
||||
if (goya->hw_cap_initialized & HW_CAP_MMU)
|
||||
return 0;
|
||||
|
||||
|
@ -371,13 +371,8 @@ static int goya_etr_validate_address(struct hl_device *hdev, u64 addr,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hdev->mmu_enable) {
|
||||
range_start = prop->dmmu.start_addr;
|
||||
range_end = prop->dmmu.end_addr;
|
||||
} else {
|
||||
range_start = prop->dram_user_base_address;
|
||||
range_end = prop->dram_end_address;
|
||||
}
|
||||
range_start = prop->dmmu.start_addr;
|
||||
range_end = prop->dmmu.end_addr;
|
||||
|
||||
return hl_mem_area_inside_range(addr, size, range_start, range_end);
|
||||
}
|
||||
|
@ -359,7 +359,7 @@ struct hl_eq_entry {
|
||||
union {
|
||||
__le64 data_placeholder;
|
||||
struct hl_eq_ecc_data ecc_data;
|
||||
struct hl_eq_hbm_ecc_data hbm_ecc_data; /* Gaudi1 HBM */
|
||||
struct hl_eq_hbm_ecc_data hbm_ecc_data; /* Obsolete */
|
||||
struct hl_eq_sm_sei_data sm_sei_data;
|
||||
struct cpucp_pkt_sync_err pkt_sync_err;
|
||||
struct hl_eq_fw_alive fw_alive;
|
||||
@ -653,7 +653,7 @@ enum pq_init_status {
|
||||
* which address is passed via the CpuCp packet. In addition, the host's driver
|
||||
* passes the max size it allows the CpuCP to write to the structure, to prevent
|
||||
* data corruption in case of mismatched driver/FW versions.
|
||||
* Relevant only to Gaudi.
|
||||
* Obsolete.
|
||||
*
|
||||
* CPUCP_PACKET_GENERIC_PASSTHROUGH -
|
||||
* Generic opcode for all firmware info that is only passed to host
|
||||
@ -665,6 +665,9 @@ enum pq_init_status {
|
||||
*
|
||||
* CPUCP_PACKET_REGISTER_INTERRUPTS -
|
||||
* Packet to register interrupts indicating LKD is ready to receive events from FW.
|
||||
*
|
||||
* CPUCP_PACKET_SOFT_RESET -
|
||||
* Packet to perform soft-reset.
|
||||
*/
|
||||
|
||||
enum cpucp_packet_id {
|
||||
@ -731,6 +734,7 @@ enum cpucp_packet_id {
|
||||
CPUCP_PACKET_RESERVED11, /* not used */
|
||||
CPUCP_PACKET_RESERVED12, /* internal */
|
||||
CPUCP_PACKET_REGISTER_INTERRUPTS, /* internal */
|
||||
CPUCP_PACKET_SOFT_RESET, /* internal */
|
||||
CPUCP_PACKET_ID_MAX /* must be last */
|
||||
};
|
||||
|
||||
@ -864,19 +868,19 @@ struct cpucp_array_data_packet {
|
||||
enum cpucp_led_index {
|
||||
CPUCP_LED0_INDEX = 0,
|
||||
CPUCP_LED1_INDEX,
|
||||
CPUCP_LED2_INDEX
|
||||
CPUCP_LED2_INDEX,
|
||||
CPUCP_LED_MAX_INDEX = CPUCP_LED2_INDEX
|
||||
};
|
||||
|
||||
/*
|
||||
* enum cpucp_packet_rc - Error return code
|
||||
* @cpucp_packet_success -> in case of success.
|
||||
* @cpucp_packet_invalid -> this is to support Goya and Gaudi platform.
|
||||
* @cpucp_packet_invalid -> this is to support first generation platforms.
|
||||
* @cpucp_packet_fault -> in case of processing error like failing to
|
||||
* get device binding or semaphore etc.
|
||||
* @cpucp_packet_invalid_pkt -> when cpucp packet is un-supported. This is
|
||||
* supported Greco onwards.
|
||||
* @cpucp_packet_invalid_pkt -> when cpucp packet is un-supported.
|
||||
* @cpucp_packet_invalid_params -> when checking parameter like length of buffer
|
||||
* or attribute value etc. Supported Greco onwards.
|
||||
* or attribute value etc.
|
||||
* @cpucp_packet_rc_max -> It indicates size of enum so should be at last.
|
||||
*/
|
||||
enum cpucp_packet_rc {
|
||||
@ -1361,7 +1365,7 @@ struct cpucp_dev_info_signed {
|
||||
#define DCORE_MON_REGS_SZ 512
|
||||
/*
|
||||
* struct dcore_monitor_regs_data - DCORE monitor regs data.
|
||||
* the structure follows sync manager block layout. relevant only to Gaudi.
|
||||
* the structure follows sync manager block layout. Obsolete.
|
||||
* @mon_pay_addrl: array of payload address low bits.
|
||||
* @mon_pay_addrh: array of payload address high bits.
|
||||
* @mon_pay_data: array of payload data.
|
||||
@ -1376,7 +1380,7 @@ struct dcore_monitor_regs_data {
|
||||
__le32 mon_status[DCORE_MON_REGS_SZ];
|
||||
};
|
||||
|
||||
/* contains SM data for each SYNC_MNGR (relevant only to Gaudi) */
|
||||
/* contains SM data for each SYNC_MNGR (Obsolete) */
|
||||
struct cpucp_monitor_dump {
|
||||
struct dcore_monitor_regs_data sync_mngr_w_s;
|
||||
struct dcore_monitor_regs_data sync_mngr_e_s;
|
||||
|
@ -35,6 +35,7 @@ enum cpu_boot_err {
|
||||
CPU_BOOT_ERR_TPM_FAIL = 20,
|
||||
CPU_BOOT_ERR_TMP_THRESH_INIT_FAIL = 21,
|
||||
CPU_BOOT_ERR_EEPROM_FAIL = 22,
|
||||
CPU_BOOT_ERR_ENG_ARC_MEM_SCRUB_FAIL = 23,
|
||||
CPU_BOOT_ERR_ENABLED = 31,
|
||||
CPU_BOOT_ERR_SCND_EN = 63,
|
||||
CPU_BOOT_ERR_LAST = 64 /* we have 2 registers of 32 bits */
|
||||
@ -51,6 +52,7 @@ enum cpu_boot_err {
|
||||
(1 << CPU_BOOT_ERR_DEVICE_UNUSABLE_FAIL) | \
|
||||
(1 << CPU_BOOT_ERR_BINNING_FAIL) | \
|
||||
(1 << CPU_BOOT_ERR_DRAM_SKIPPED) | \
|
||||
(1 << CPU_BOOT_ERR_ENG_ARC_MEM_SCRUB_FAIL) | \
|
||||
(1 << CPU_BOOT_ERR_EEPROM_FAIL))
|
||||
|
||||
/*
|
||||
@ -132,6 +134,9 @@ enum cpu_boot_err {
|
||||
* CPU_BOOT_ERR_EEPROM_FAIL Failed reading EEPROM data. Defaults
|
||||
* are used.
|
||||
*
|
||||
* CPU_BOOT_ERR_ENG_ARC_MEM_SCRUB_FAIL Failed scrubbing the Engines/ARCFarm
|
||||
* memories. Boot disabled until reset.
|
||||
*
|
||||
* CPU_BOOT_ERR0_ENABLED Error registers enabled.
|
||||
* This is a main indication that the
|
||||
* running FW populates the error
|
||||
@ -157,6 +162,7 @@ enum cpu_boot_err {
|
||||
#define CPU_BOOT_ERR0_TPM_FAIL (1 << CPU_BOOT_ERR_TPM_FAIL)
|
||||
#define CPU_BOOT_ERR0_TMP_THRESH_INIT_FAIL (1 << CPU_BOOT_ERR_TMP_THRESH_INIT_FAIL)
|
||||
#define CPU_BOOT_ERR0_EEPROM_FAIL (1 << CPU_BOOT_ERR_EEPROM_FAIL)
|
||||
#define CPU_BOOT_ERR0_ENG_ARC_MEM_SCRUB_FAIL (1 << CPU_BOOT_ERR_ENG_ARC_MEM_SCRUB_FAIL)
|
||||
#define CPU_BOOT_ERR0_ENABLED (1 << CPU_BOOT_ERR_ENABLED)
|
||||
#define CPU_BOOT_ERR1_ENABLED (1 << CPU_BOOT_ERR_ENABLED)
|
||||
|
||||
@ -744,36 +750,6 @@ struct comms_status {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* HL_MODULES_MAX_NUM is determined by the size of modules_mask in struct
|
||||
* hl_component_versions
|
||||
*/
|
||||
enum hl_modules {
|
||||
HL_MODULES_BOOT_INFO = 0,
|
||||
HL_MODULES_EEPROM,
|
||||
HL_MODULES_FDT,
|
||||
HL_MODULES_I2C,
|
||||
HL_MODULES_LZ4,
|
||||
HL_MODULES_MBEDTLS,
|
||||
HL_MODULES_MAX_NUM = 16
|
||||
};
|
||||
|
||||
/**
|
||||
* HL_COMPONENTS_MAX_NUM is determined by the size of components_mask in
|
||||
* struct cpucp_versions
|
||||
*/
|
||||
enum hl_components {
|
||||
HL_COMPONENTS_PID = 0,
|
||||
HL_COMPONENTS_MGMT,
|
||||
HL_COMPONENTS_PREBOOT,
|
||||
HL_COMPONENTS_PPBOOT,
|
||||
HL_COMPONENTS_ARMCP,
|
||||
HL_COMPONENTS_CPLD,
|
||||
HL_COMPONENTS_UBOOT,
|
||||
HL_COMPONENTS_FUSE,
|
||||
HL_COMPONENTS_MAX_NUM = 16
|
||||
};
|
||||
|
||||
#define NAME_MAX_LEN 32 /* bytes */
|
||||
struct hl_module_data {
|
||||
__u8 name[NAME_MAX_LEN];
|
||||
@ -787,8 +763,6 @@ struct hl_module_data {
|
||||
* @component: version of the component itself.
|
||||
* @fw_os: Firmware OS Version.
|
||||
* @comp_name: Name of the component.
|
||||
* @modules_mask: i'th bit (from LSB) is a flag - on if module i in enum
|
||||
* hl_modules is used.
|
||||
* @modules_counter: number of set bits in modules_mask.
|
||||
* @reserved: reserved for future use.
|
||||
* @modules: versions of the component's modules. Elborated explanation in
|
||||
@ -800,9 +774,8 @@ struct hl_component_versions {
|
||||
__u8 component[VERSION_MAX_LEN];
|
||||
__u8 fw_os[VERSION_MAX_LEN];
|
||||
__u8 comp_name[NAME_MAX_LEN];
|
||||
__le16 modules_mask;
|
||||
__u8 modules_counter;
|
||||
__u8 reserved[1];
|
||||
__u8 reserved[3];
|
||||
struct hl_module_data modules[];
|
||||
};
|
||||
|
||||
|
@ -242,6 +242,17 @@
|
||||
#define QM_FENCE2_OFFSET (mmPDMA0_QM_CP_FENCE2_RDATA_0 - mmPDMA0_QM_BASE)
|
||||
#define QM_SEI_STATUS_OFFSET (mmPDMA0_QM_SEI_STATUS - mmPDMA0_QM_BASE)
|
||||
|
||||
#define QM_CQ_PTR_LO_4_OFFSET (mmPDMA0_QM_CQ_PTR_LO_4 - mmPDMA0_QM_BASE)
|
||||
#define QM_CQ_PTR_HI_4_OFFSET (mmPDMA0_QM_CQ_PTR_HI_4 - mmPDMA0_QM_BASE)
|
||||
#define QM_CQ_TSIZE_4_OFFSET (mmPDMA0_QM_CQ_TSIZE_4 - mmPDMA0_QM_BASE)
|
||||
|
||||
#define QM_ARC_CQ_PTR_LO_OFFSET (mmPDMA0_QM_ARC_CQ_PTR_LO - mmPDMA0_QM_BASE)
|
||||
#define QM_ARC_CQ_PTR_HI_OFFSET (mmPDMA0_QM_ARC_CQ_PTR_HI - mmPDMA0_QM_BASE)
|
||||
#define QM_ARC_CQ_TSIZE_OFFSET (mmPDMA0_QM_ARC_CQ_TSIZE - mmPDMA0_QM_BASE)
|
||||
|
||||
#define QM_CP_CURRENT_INST_LO_4_OFFSET (mmPDMA0_QM_CP_CURRENT_INST_LO_4 - mmPDMA0_QM_BASE)
|
||||
#define QM_CP_CURRENT_INST_HI_4_OFFSET (mmPDMA0_QM_CP_CURRENT_INST_HI_4 - mmPDMA0_QM_BASE)
|
||||
|
||||
#define SFT_OFFSET (mmSFT1_HBW_RTR_IF0_RTR_H3_BASE - mmSFT0_HBW_RTR_IF0_RTR_H3_BASE)
|
||||
#define SFT_IF_RTR_OFFSET (mmSFT0_HBW_RTR_IF1_RTR_H3_BASE - mmSFT0_HBW_RTR_IF0_RTR_H3_BASE)
|
||||
|
||||
|
@ -62,7 +62,7 @@ struct gaudi2_cold_rst_data {
|
||||
u32 fake_security_enable : 1;
|
||||
u32 fake_sig_validation_en : 1;
|
||||
u32 bist_skip_enable : 1;
|
||||
u32 bist_need_iatu_config : 1;
|
||||
u32 reserved1 : 1;
|
||||
u32 fake_bis_compliant : 1;
|
||||
u32 wd_rst_cause_arm : 1;
|
||||
u32 wd_rst_cause_arcpid : 1;
|
||||
|
@ -72,7 +72,7 @@ static int cfag12864bfb_probe(struct platform_device *device)
|
||||
if (!info)
|
||||
goto none;
|
||||
|
||||
info->screen_base = (char __iomem *) cfag12864b_buffer;
|
||||
info->screen_buffer = cfag12864b_buffer;
|
||||
info->screen_size = CFAG12864B_SIZE;
|
||||
info->fbops = &cfag12864bfb_ops;
|
||||
info->fix = cfag12864bfb_fix;
|
||||
|
@ -640,7 +640,7 @@ static int ht16k33_fbdev_probe(struct device *dev, struct ht16k33_priv *priv,
|
||||
|
||||
INIT_DELAYED_WORK(&priv->work, ht16k33_fb_update);
|
||||
fbdev->info->fbops = &ht16k33_fb_ops;
|
||||
fbdev->info->screen_base = (char __iomem *) fbdev->buffer;
|
||||
fbdev->info->screen_buffer = fbdev->buffer;
|
||||
fbdev->info->screen_size = HT16K33_FB_SIZE;
|
||||
fbdev->info->fix = ht16k33_fb_fix;
|
||||
fbdev->info->var = ht16k33_fb_var;
|
||||
|
@ -660,7 +660,7 @@ EXPORT_SYMBOL_GPL(dma_resv_get_singleton);
|
||||
* dma_resv_lock() already
|
||||
* RETURNS
|
||||
* Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or
|
||||
* greater than zer on success.
|
||||
* greater than zero on success.
|
||||
*/
|
||||
long dma_resv_wait_timeout(struct dma_resv *obj, enum dma_resv_usage usage,
|
||||
bool intr, unsigned long timeout)
|
||||
|
@ -85,7 +85,7 @@ static struct sync_timeline *sync_timeline_create(const char *name)
|
||||
|
||||
kref_init(&obj->kref);
|
||||
obj->context = dma_fence_context_alloc(1);
|
||||
strlcpy(obj->name, name, sizeof(obj->name));
|
||||
strscpy(obj->name, name, sizeof(obj->name));
|
||||
|
||||
obj->pt_tree = RB_ROOT;
|
||||
INIT_LIST_HEAD(&obj->pt_list);
|
||||
|
@ -128,4 +128,4 @@ unlock_mutex:
|
||||
}
|
||||
|
||||
/* must execute after PCI subsystem for EFI quirks */
|
||||
device_initcall(sysfb_init);
|
||||
subsys_initcall_sync(sysfb_init);
|
||||
|
@ -95,6 +95,7 @@ config DRM_KUNIT_TEST
|
||||
config DRM_KMS_HELPER
|
||||
tristate
|
||||
depends on DRM
|
||||
select FB_SYS_HELPERS_DEFERRED if DRM_FBDEV_EMULATION
|
||||
help
|
||||
CRTC helpers for KMS drivers.
|
||||
|
||||
@ -132,14 +133,6 @@ config DRM_FBDEV_EMULATION
|
||||
bool "Enable legacy fbdev support for your modesetting driver"
|
||||
depends on DRM_KMS_HELPER
|
||||
depends on FB=y || FB=DRM_KMS_HELPER
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
select FB_DEFERRED_IO
|
||||
select FB_SYS_FOPS
|
||||
select FB_SYS_FILLRECT
|
||||
select FB_SYS_COPYAREA
|
||||
select FB_SYS_IMAGEBLIT
|
||||
select FRAMEBUFFER_CONSOLE if !EXPERT
|
||||
select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
|
||||
default y
|
||||
@ -223,6 +216,7 @@ config DRM_TTM_HELPER
|
||||
config DRM_GEM_DMA_HELPER
|
||||
tristate
|
||||
depends on DRM
|
||||
select FB_SYS_HELPERS if DRM_FBDEV_EMULATION
|
||||
help
|
||||
Choose this if you need the GEM DMA helper functions
|
||||
|
||||
@ -295,9 +289,7 @@ source "drivers/gpu/drm/armada/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/atmel-hlcdc/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/rcar-du/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/shmobile/Kconfig"
|
||||
source "drivers/gpu/drm/renesas/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/sun4i/Kconfig"
|
||||
|
||||
|
@ -140,6 +140,7 @@ obj-$(CONFIG_DRM_TTM) += ttm/
|
||||
obj-$(CONFIG_DRM_SCHED) += scheduler/
|
||||
obj-$(CONFIG_DRM_RADEON)+= radeon/
|
||||
obj-$(CONFIG_DRM_AMDGPU)+= amd/amdgpu/
|
||||
obj-$(CONFIG_DRM_AMDGPU)+= amd/amdxcp/
|
||||
obj-$(CONFIG_DRM_I915) += i915/
|
||||
obj-$(CONFIG_DRM_KMB_DISPLAY) += kmb/
|
||||
obj-$(CONFIG_DRM_MGAG200) += mgag200/
|
||||
@ -156,8 +157,7 @@ obj-$(CONFIG_DRM_UDL) += udl/
|
||||
obj-$(CONFIG_DRM_AST) += ast/
|
||||
obj-$(CONFIG_DRM_ARMADA) += armada/
|
||||
obj-$(CONFIG_DRM_ATMEL_HLCDC) += atmel-hlcdc/
|
||||
obj-y += rcar-du/
|
||||
obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
|
||||
obj-y += renesas/
|
||||
obj-y += omapdrm/
|
||||
obj-$(CONFIG_DRM_SUN4I) += sun4i/
|
||||
obj-y += tilcdc/
|
||||
|
@ -69,6 +69,16 @@ config DRM_AMDGPU_USERPTR
|
||||
This option selects CONFIG_HMM and CONFIG_HMM_MIRROR if it
|
||||
isn't already selected to enabled full userptr support.
|
||||
|
||||
config DRM_AMDGPU_WERROR
|
||||
bool "Force the compiler to throw an error instead of a warning when compiling"
|
||||
depends on DRM_AMDGPU
|
||||
depends on EXPERT
|
||||
depends on !COMPILE_TEST
|
||||
default n
|
||||
help
|
||||
Add -Werror to the build flags for amdgpu.ko.
|
||||
Only enable this if you are warning code for amdgpu.ko.
|
||||
|
||||
source "drivers/gpu/drm/amd/acp/Kconfig"
|
||||
source "drivers/gpu/drm/amd/display/Kconfig"
|
||||
source "drivers/gpu/drm/amd/amdkfd/Kconfig"
|
||||
|
@ -39,6 +39,26 @@ ccflags-y := -I$(FULL_AMD_PATH)/include/asic_reg \
|
||||
-I$(FULL_AMD_DISPLAY_PATH)/amdgpu_dm \
|
||||
-I$(FULL_AMD_PATH)/amdkfd
|
||||
|
||||
subdir-ccflags-y := -Wextra
|
||||
subdir-ccflags-y += -Wunused
|
||||
subdir-ccflags-y += -Wmissing-prototypes
|
||||
subdir-ccflags-y += -Wmissing-declarations
|
||||
subdir-ccflags-y += -Wmissing-include-dirs
|
||||
subdir-ccflags-y += -Wold-style-definition
|
||||
subdir-ccflags-y += -Wmissing-format-attribute
|
||||
# Need this to avoid recursive variable evaluation issues
|
||||
cond-flags := $(call cc-option, -Wunused-but-set-variable) \
|
||||
$(call cc-option, -Wunused-const-variable) \
|
||||
$(call cc-option, -Wstringop-truncation) \
|
||||
$(call cc-option, -Wpacked-not-aligned)
|
||||
subdir-ccflags-y += $(cond-flags)
|
||||
subdir-ccflags-y += -Wno-unused-parameter
|
||||
subdir-ccflags-y += -Wno-type-limits
|
||||
subdir-ccflags-y += -Wno-sign-compare
|
||||
subdir-ccflags-y += -Wno-missing-field-initializers
|
||||
subdir-ccflags-y += -Wno-override-init
|
||||
subdir-ccflags-$(CONFIG_DRM_AMDGPU_WERROR) += -Werror
|
||||
|
||||
amdgpu-y := amdgpu_drv.o
|
||||
|
||||
# add KMS driver
|
||||
@ -60,7 +80,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
|
||||
amdgpu_umc.o smu_v11_0_i2c.o amdgpu_fru_eeprom.o amdgpu_rap.o \
|
||||
amdgpu_fw_attestation.o amdgpu_securedisplay.o \
|
||||
amdgpu_eeprom.o amdgpu_mca.o amdgpu_psp_ta.o amdgpu_lsdma.o \
|
||||
amdgpu_ring_mux.o
|
||||
amdgpu_ring_mux.o amdgpu_xcp.o
|
||||
|
||||
amdgpu-$(CONFIG_PROC_FS) += amdgpu_fdinfo.o
|
||||
|
||||
@ -78,7 +98,7 @@ amdgpu-y += \
|
||||
vega20_reg_init.o nbio_v7_4.o nbio_v2_3.o nv.o arct_reg_init.o mxgpu_nv.o \
|
||||
nbio_v7_2.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o soc21.o \
|
||||
sienna_cichlid.o smu_v13_0_10.o nbio_v4_3.o hdp_v6_0.o nbio_v7_7.o hdp_v5_2.o lsdma_v6_0.o \
|
||||
nbio_v7_9.o
|
||||
nbio_v7_9.o aqua_vanjaram_reg_init.o
|
||||
|
||||
# add DF block
|
||||
amdgpu-y += \
|
||||
@ -183,12 +203,14 @@ amdgpu-y += \
|
||||
vcn_v2_5.o \
|
||||
vcn_v3_0.o \
|
||||
vcn_v4_0.o \
|
||||
vcn_v4_0_3.o \
|
||||
amdgpu_jpeg.o \
|
||||
jpeg_v1_0.o \
|
||||
jpeg_v2_0.o \
|
||||
jpeg_v2_5.o \
|
||||
jpeg_v3_0.o \
|
||||
jpeg_v4_0.o
|
||||
jpeg_v4_0.o \
|
||||
jpeg_v4_0_3.o
|
||||
|
||||
# add ATHUB block
|
||||
amdgpu-y += \
|
||||
@ -203,6 +225,7 @@ amdgpu-y += \
|
||||
smuio_v11_0.o \
|
||||
smuio_v11_0_6.o \
|
||||
smuio_v13_0.o \
|
||||
smuio_v13_0_3.o \
|
||||
smuio_v13_0_6.o
|
||||
|
||||
# add reset block
|
||||
@ -228,6 +251,7 @@ amdgpu-y += \
|
||||
amdgpu_amdkfd_gfx_v9.o \
|
||||
amdgpu_amdkfd_arcturus.o \
|
||||
amdgpu_amdkfd_aldebaran.o \
|
||||
amdgpu_amdkfd_gc_9_4_3.o \
|
||||
amdgpu_amdkfd_gfx_v10.o \
|
||||
amdgpu_amdkfd_gfx_v10_3.o \
|
||||
amdgpu_amdkfd_gfx_v11.o
|
||||
|
@ -107,8 +107,9 @@
|
||||
#include "amdgpu_fdinfo.h"
|
||||
#include "amdgpu_mca.h"
|
||||
#include "amdgpu_ras.h"
|
||||
#include "amdgpu_xcp.h"
|
||||
|
||||
#define MAX_GPU_INSTANCE 16
|
||||
#define MAX_GPU_INSTANCE 64
|
||||
|
||||
struct amdgpu_gpu_instance
|
||||
{
|
||||
@ -212,6 +213,8 @@ extern int amdgpu_noretry;
|
||||
extern int amdgpu_force_asic_type;
|
||||
extern int amdgpu_smartshift_bias;
|
||||
extern int amdgpu_use_xgmi_p2p;
|
||||
extern int amdgpu_mtype_local;
|
||||
extern bool enforce_isolation;
|
||||
#ifdef CONFIG_HSA_AMD
|
||||
extern int sched_policy;
|
||||
extern bool debug_evictions;
|
||||
@ -242,9 +245,10 @@ extern int amdgpu_num_kcq;
|
||||
extern int amdgpu_vcnfw_log;
|
||||
extern int amdgpu_sg_display;
|
||||
|
||||
extern int amdgpu_user_partt_mode;
|
||||
|
||||
#define AMDGPU_VM_MAX_NUM_CTX 4096
|
||||
#define AMDGPU_SG_THRESHOLD (256*1024*1024)
|
||||
#define AMDGPU_DEFAULT_GTT_SIZE_MB 3072ULL /* 3GB by default */
|
||||
#define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000
|
||||
#define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */
|
||||
#define AMDGPU_FENCE_JIFFIES_TIMEOUT (HZ / 2)
|
||||
@ -282,6 +286,7 @@ extern int amdgpu_sg_display;
|
||||
#define AMDGPU_SMARTSHIFT_MAX_BIAS (100)
|
||||
#define AMDGPU_SMARTSHIFT_MIN_BIAS (-100)
|
||||
|
||||
struct amdgpu_xcp_mgr;
|
||||
struct amdgpu_device;
|
||||
struct amdgpu_irq_src;
|
||||
struct amdgpu_fpriv;
|
||||
@ -463,6 +468,8 @@ struct amdgpu_fpriv {
|
||||
struct mutex bo_list_lock;
|
||||
struct idr bo_list_handles;
|
||||
struct amdgpu_ctx_mgr ctx_mgr;
|
||||
/** GPU partition selection */
|
||||
uint32_t xcp_id;
|
||||
};
|
||||
|
||||
int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv);
|
||||
@ -573,6 +580,8 @@ struct amdgpu_asic_funcs {
|
||||
/* query video codecs */
|
||||
int (*query_video_codecs)(struct amdgpu_device *adev, bool encode,
|
||||
const struct amdgpu_video_codecs **codecs);
|
||||
/* encode "> 32bits" smn addressing */
|
||||
u64 (*encode_ext_smn_addressing)(int ext_id);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -607,6 +616,9 @@ void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device);
|
||||
typedef uint32_t (*amdgpu_rreg_t)(struct amdgpu_device*, uint32_t);
|
||||
typedef void (*amdgpu_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t);
|
||||
|
||||
typedef uint32_t (*amdgpu_rreg_ext_t)(struct amdgpu_device*, uint64_t);
|
||||
typedef void (*amdgpu_wreg_ext_t)(struct amdgpu_device*, uint64_t, uint32_t);
|
||||
|
||||
typedef uint64_t (*amdgpu_rreg64_t)(struct amdgpu_device*, uint32_t);
|
||||
typedef void (*amdgpu_wreg64_t)(struct amdgpu_device*, uint32_t, uint64_t);
|
||||
|
||||
@ -657,7 +669,7 @@ enum amd_hw_ip_block_type {
|
||||
MAX_HWIP
|
||||
};
|
||||
|
||||
#define HWIP_MAX_INSTANCE 28
|
||||
#define HWIP_MAX_INSTANCE 44
|
||||
|
||||
#define HW_ID_MAX 300
|
||||
#define IP_VERSION(mj, mn, rv) (((mj) << 16) | ((mn) << 8) | (rv))
|
||||
@ -665,6 +677,17 @@ enum amd_hw_ip_block_type {
|
||||
#define IP_VERSION_MIN(ver) (((ver) >> 8) & 0xFF)
|
||||
#define IP_VERSION_REV(ver) ((ver) & 0xFF)
|
||||
|
||||
struct amdgpu_ip_map_info {
|
||||
/* Map of logical to actual dev instances/mask */
|
||||
uint32_t dev_inst[MAX_HWIP][HWIP_MAX_INSTANCE];
|
||||
int8_t (*logical_to_dev_inst)(struct amdgpu_device *adev,
|
||||
enum amd_hw_ip_block_type block,
|
||||
int8_t inst);
|
||||
uint32_t (*logical_to_dev_mask)(struct amdgpu_device *adev,
|
||||
enum amd_hw_ip_block_type block,
|
||||
uint32_t mask);
|
||||
};
|
||||
|
||||
struct amd_powerplay {
|
||||
void *pp_handle;
|
||||
const struct amd_pm_funcs *pp_funcs;
|
||||
@ -750,6 +773,7 @@ struct amdgpu_device {
|
||||
struct amdgpu_acp acp;
|
||||
#endif
|
||||
struct amdgpu_hive_info *hive;
|
||||
struct amdgpu_xcp_mgr *xcp_mgr;
|
||||
/* ASIC */
|
||||
enum amd_asic_type asic_type;
|
||||
uint32_t family;
|
||||
@ -797,6 +821,8 @@ struct amdgpu_device {
|
||||
amdgpu_wreg_t pcie_wreg;
|
||||
amdgpu_rreg_t pciep_rreg;
|
||||
amdgpu_wreg_t pciep_wreg;
|
||||
amdgpu_rreg_ext_t pcie_rreg_ext;
|
||||
amdgpu_wreg_ext_t pcie_wreg_ext;
|
||||
amdgpu_rreg64_t pcie_rreg64;
|
||||
amdgpu_wreg64_t pcie_wreg64;
|
||||
/* protects concurrent UVD register access */
|
||||
@ -830,7 +856,7 @@ struct amdgpu_device {
|
||||
dma_addr_t dummy_page_addr;
|
||||
struct amdgpu_vm_manager vm_manager;
|
||||
struct amdgpu_vmhub vmhub[AMDGPU_MAX_VMHUBS];
|
||||
unsigned num_vmhubs;
|
||||
DECLARE_BITMAP(vmhubs_mask, AMDGPU_MAX_VMHUBS);
|
||||
|
||||
/* memory management */
|
||||
struct amdgpu_mman mman;
|
||||
@ -962,6 +988,7 @@ struct amdgpu_device {
|
||||
|
||||
/* soc15 register offset based on ip, instance and segment */
|
||||
uint32_t *reg_offset[MAX_HWIP][HWIP_MAX_INSTANCE];
|
||||
struct amdgpu_ip_map_info ip_map;
|
||||
|
||||
/* delayed work_func for deferring clockgating during resume */
|
||||
struct delayed_work delayed_init_work;
|
||||
@ -1020,6 +1047,9 @@ struct amdgpu_device {
|
||||
struct pci_saved_state *pci_state;
|
||||
pci_channel_state_t pci_channel_state;
|
||||
|
||||
/* Track auto wait count on s_barrier settings */
|
||||
bool barrier_has_auto_waitcnt;
|
||||
|
||||
struct amdgpu_reset_control *reset_cntl;
|
||||
uint32_t ip_versions[MAX_HWIP][HWIP_MAX_INSTANCE];
|
||||
|
||||
@ -1050,6 +1080,8 @@ struct amdgpu_device {
|
||||
|
||||
bool job_hang;
|
||||
bool dc_enabled;
|
||||
/* Mask of active clusters */
|
||||
uint32_t aid_mask;
|
||||
};
|
||||
|
||||
static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)
|
||||
@ -1081,11 +1113,18 @@ size_t amdgpu_device_aper_access(struct amdgpu_device *adev, loff_t pos,
|
||||
|
||||
void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
|
||||
void *buf, size_t size, bool write);
|
||||
uint32_t amdgpu_device_wait_on_rreg(struct amdgpu_device *adev,
|
||||
uint32_t inst, uint32_t reg_addr, char reg_name[],
|
||||
uint32_t expected_value, uint32_t mask);
|
||||
uint32_t amdgpu_device_rreg(struct amdgpu_device *adev,
|
||||
uint32_t reg, uint32_t acc_flags);
|
||||
u32 amdgpu_device_indirect_rreg_ext(struct amdgpu_device *adev,
|
||||
u64 reg_addr);
|
||||
void amdgpu_device_wreg(struct amdgpu_device *adev,
|
||||
uint32_t reg, uint32_t v,
|
||||
uint32_t acc_flags);
|
||||
void amdgpu_device_indirect_wreg_ext(struct amdgpu_device *adev,
|
||||
u64 reg_addr, u32 reg_data);
|
||||
void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
|
||||
uint32_t reg, uint32_t v);
|
||||
void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value);
|
||||
@ -1137,6 +1176,8 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
|
||||
#define WREG32_PCIE(reg, v) adev->pcie_wreg(adev, (reg), (v))
|
||||
#define RREG32_PCIE_PORT(reg) adev->pciep_rreg(adev, (reg))
|
||||
#define WREG32_PCIE_PORT(reg, v) adev->pciep_wreg(adev, (reg), (v))
|
||||
#define RREG32_PCIE_EXT(reg) adev->pcie_rreg_ext(adev, (reg))
|
||||
#define WREG32_PCIE_EXT(reg, v) adev->pcie_wreg_ext(adev, (reg), (v))
|
||||
#define RREG64_PCIE(reg) adev->pcie_rreg64(adev, (reg))
|
||||
#define WREG64_PCIE(reg, v) adev->pcie_wreg64(adev, (reg), (v))
|
||||
#define RREG32_SMC(reg) adev->smc_rreg(adev, (reg))
|
||||
@ -1204,7 +1245,8 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
|
||||
/*
|
||||
* ASICs macro.
|
||||
*/
|
||||
#define amdgpu_asic_set_vga_state(adev, state) (adev)->asic_funcs->set_vga_state((adev), (state))
|
||||
#define amdgpu_asic_set_vga_state(adev, state) \
|
||||
((adev)->asic_funcs->set_vga_state ? (adev)->asic_funcs->set_vga_state((adev), (state)) : 0)
|
||||
#define amdgpu_asic_reset(adev) (adev)->asic_funcs->reset((adev))
|
||||
#define amdgpu_asic_reset_method(adev) (adev)->asic_funcs->reset_method((adev))
|
||||
#define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev))
|
||||
@ -1235,6 +1277,10 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
|
||||
|
||||
#define amdgpu_inc_vram_lost(adev) atomic_inc(&((adev)->vram_lost_counter));
|
||||
|
||||
#define for_each_inst(i, inst_mask) \
|
||||
for (i = ffs(inst_mask) - 1; inst_mask; \
|
||||
inst_mask &= ~(1U << i), i = ffs(inst_mask) - 1)
|
||||
|
||||
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
|
||||
|
||||
/* Common functions */
|
||||
@ -1348,6 +1394,12 @@ struct amdgpu_afmt_acr amdgpu_afmt_acr(uint32_t clock);
|
||||
|
||||
/* amdgpu_acpi.c */
|
||||
|
||||
struct amdgpu_numa_info {
|
||||
uint64_t size;
|
||||
int pxm;
|
||||
int nid;
|
||||
};
|
||||
|
||||
/* ATCS Device/Driver State */
|
||||
#define AMDGPU_ATCS_PSC_DEV_STATE_D0 0
|
||||
#define AMDGPU_ATCS_PSC_DEV_STATE_D3_HOT 3
|
||||
@ -1365,15 +1417,32 @@ int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
|
||||
u8 dev_state, bool drv_state);
|
||||
int amdgpu_acpi_smart_shift_update(struct drm_device *dev, enum amdgpu_ss ss_state);
|
||||
int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev);
|
||||
int amdgpu_acpi_get_tmr_info(struct amdgpu_device *adev, u64 *tmr_offset,
|
||||
u64 *tmr_size);
|
||||
int amdgpu_acpi_get_mem_info(struct amdgpu_device *adev, int xcc_id,
|
||||
struct amdgpu_numa_info *numa_info);
|
||||
|
||||
void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps);
|
||||
bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev);
|
||||
void amdgpu_acpi_detect(void);
|
||||
void amdgpu_acpi_release(void);
|
||||
#else
|
||||
static inline int amdgpu_acpi_init(struct amdgpu_device *adev) { return 0; }
|
||||
static inline int amdgpu_acpi_get_tmr_info(struct amdgpu_device *adev,
|
||||
u64 *tmr_offset, u64 *tmr_size)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline int amdgpu_acpi_get_mem_info(struct amdgpu_device *adev,
|
||||
int xcc_id,
|
||||
struct amdgpu_numa_info *numa_info)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { }
|
||||
static inline bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev) { return false; }
|
||||
static inline void amdgpu_acpi_detect(void) { }
|
||||
static inline void amdgpu_acpi_release(void) { }
|
||||
static inline bool amdgpu_acpi_is_power_shift_control_supported(void) { return false; }
|
||||
static inline int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
|
||||
u8 dev_state, bool drv_state) { return 0; }
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/xarray.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/suspend.h>
|
||||
@ -38,6 +39,45 @@
|
||||
#include "amd_acpi.h"
|
||||
#include "atom.h"
|
||||
|
||||
/* Declare GUID for AMD _DSM method for XCCs */
|
||||
static const guid_t amd_xcc_dsm_guid = GUID_INIT(0x8267f5d5, 0xa556, 0x44f2,
|
||||
0xb8, 0xb4, 0x45, 0x56, 0x2e,
|
||||
0x8c, 0x5b, 0xec);
|
||||
|
||||
#define AMD_XCC_HID_START 3000
|
||||
#define AMD_XCC_DSM_GET_NUM_FUNCS 0
|
||||
#define AMD_XCC_DSM_GET_SUPP_MODE 1
|
||||
#define AMD_XCC_DSM_GET_XCP_MODE 2
|
||||
#define AMD_XCC_DSM_GET_VF_XCC_MAPPING 4
|
||||
#define AMD_XCC_DSM_GET_TMR_INFO 5
|
||||
#define AMD_XCC_DSM_NUM_FUNCS 5
|
||||
|
||||
#define AMD_XCC_MAX_HID 24
|
||||
|
||||
struct xarray numa_info_xa;
|
||||
|
||||
/* Encapsulates the XCD acpi object information */
|
||||
struct amdgpu_acpi_xcc_info {
|
||||
struct list_head list;
|
||||
struct amdgpu_numa_info *numa_info;
|
||||
uint8_t xcp_node;
|
||||
uint8_t phy_id;
|
||||
acpi_handle handle;
|
||||
};
|
||||
|
||||
struct amdgpu_acpi_dev_info {
|
||||
struct list_head list;
|
||||
struct list_head xcc_list;
|
||||
uint16_t bdf;
|
||||
uint16_t supp_xcp_mode;
|
||||
uint16_t xcp_mode;
|
||||
uint16_t mem_mode;
|
||||
uint64_t tmr_base;
|
||||
uint64_t tmr_size;
|
||||
};
|
||||
|
||||
struct list_head amdgpu_acpi_dev_list;
|
||||
|
||||
struct amdgpu_atif_notification_cfg {
|
||||
bool enabled;
|
||||
int command_code;
|
||||
@ -801,6 +841,343 @@ int amdgpu_acpi_smart_shift_update(struct drm_device *dev, enum amdgpu_ss ss_sta
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_NUMA
|
||||
static inline uint64_t amdgpu_acpi_get_numa_size(int nid)
|
||||
{
|
||||
/* This is directly using si_meminfo_node implementation as the
|
||||
* function is not exported.
|
||||
*/
|
||||
int zone_type;
|
||||
uint64_t managed_pages = 0;
|
||||
|
||||
pg_data_t *pgdat = NODE_DATA(nid);
|
||||
|
||||
for (zone_type = 0; zone_type < MAX_NR_ZONES; zone_type++)
|
||||
managed_pages +=
|
||||
zone_managed_pages(&pgdat->node_zones[zone_type]);
|
||||
return managed_pages * PAGE_SIZE;
|
||||
}
|
||||
|
||||
static struct amdgpu_numa_info *amdgpu_acpi_get_numa_info(uint32_t pxm)
|
||||
{
|
||||
struct amdgpu_numa_info *numa_info;
|
||||
int nid;
|
||||
|
||||
numa_info = xa_load(&numa_info_xa, pxm);
|
||||
|
||||
if (!numa_info) {
|
||||
struct sysinfo info;
|
||||
|
||||
numa_info = kzalloc(sizeof *numa_info, GFP_KERNEL);
|
||||
if (!numa_info)
|
||||
return NULL;
|
||||
|
||||
nid = pxm_to_node(pxm);
|
||||
numa_info->pxm = pxm;
|
||||
numa_info->nid = nid;
|
||||
|
||||
if (numa_info->nid == NUMA_NO_NODE) {
|
||||
si_meminfo(&info);
|
||||
numa_info->size = info.totalram * info.mem_unit;
|
||||
} else {
|
||||
numa_info->size = amdgpu_acpi_get_numa_size(nid);
|
||||
}
|
||||
xa_store(&numa_info_xa, numa_info->pxm, numa_info, GFP_KERNEL);
|
||||
}
|
||||
|
||||
return numa_info;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* amdgpu_acpi_get_node_id - obtain the NUMA node id for corresponding amdgpu
|
||||
* acpi device handle
|
||||
*
|
||||
* @handle: acpi handle
|
||||
* @numa_info: amdgpu_numa_info structure holding numa information
|
||||
*
|
||||
* Queries the ACPI interface to fetch the corresponding NUMA Node ID for a
|
||||
* given amdgpu acpi device.
|
||||
*
|
||||
* Returns ACPI STATUS OK with Node ID on success or the corresponding failure reason
|
||||
*/
|
||||
static acpi_status amdgpu_acpi_get_node_id(acpi_handle handle,
|
||||
struct amdgpu_numa_info **numa_info)
|
||||
{
|
||||
#ifdef CONFIG_ACPI_NUMA
|
||||
u64 pxm;
|
||||
acpi_status status;
|
||||
|
||||
if (!numa_info)
|
||||
return_ACPI_STATUS(AE_ERROR);
|
||||
|
||||
status = acpi_evaluate_integer(handle, "_PXM", NULL, &pxm);
|
||||
|
||||
if (ACPI_FAILURE(status))
|
||||
return status;
|
||||
|
||||
*numa_info = amdgpu_acpi_get_numa_info(pxm);
|
||||
|
||||
if (!*numa_info)
|
||||
return_ACPI_STATUS(AE_ERROR);
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
#else
|
||||
return_ACPI_STATUS(AE_NOT_EXIST);
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct amdgpu_acpi_dev_info *amdgpu_acpi_get_dev(u16 bdf)
|
||||
{
|
||||
struct amdgpu_acpi_dev_info *acpi_dev;
|
||||
|
||||
if (list_empty(&amdgpu_acpi_dev_list))
|
||||
return NULL;
|
||||
|
||||
list_for_each_entry(acpi_dev, &amdgpu_acpi_dev_list, list)
|
||||
if (acpi_dev->bdf == bdf)
|
||||
return acpi_dev;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int amdgpu_acpi_dev_init(struct amdgpu_acpi_dev_info **dev_info,
|
||||
struct amdgpu_acpi_xcc_info *xcc_info, u16 bdf)
|
||||
{
|
||||
struct amdgpu_acpi_dev_info *tmp;
|
||||
union acpi_object *obj;
|
||||
int ret = -ENOENT;
|
||||
|
||||
*dev_info = NULL;
|
||||
tmp = kzalloc(sizeof(struct amdgpu_acpi_dev_info), GFP_KERNEL);
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_LIST_HEAD(&tmp->xcc_list);
|
||||
INIT_LIST_HEAD(&tmp->list);
|
||||
tmp->bdf = bdf;
|
||||
|
||||
obj = acpi_evaluate_dsm_typed(xcc_info->handle, &amd_xcc_dsm_guid, 0,
|
||||
AMD_XCC_DSM_GET_SUPP_MODE, NULL,
|
||||
ACPI_TYPE_INTEGER);
|
||||
|
||||
if (!obj) {
|
||||
acpi_handle_debug(xcc_info->handle,
|
||||
"_DSM function %d evaluation failed",
|
||||
AMD_XCC_DSM_GET_SUPP_MODE);
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp->supp_xcp_mode = obj->integer.value & 0xFFFF;
|
||||
ACPI_FREE(obj);
|
||||
|
||||
obj = acpi_evaluate_dsm_typed(xcc_info->handle, &amd_xcc_dsm_guid, 0,
|
||||
AMD_XCC_DSM_GET_XCP_MODE, NULL,
|
||||
ACPI_TYPE_INTEGER);
|
||||
|
||||
if (!obj) {
|
||||
acpi_handle_debug(xcc_info->handle,
|
||||
"_DSM function %d evaluation failed",
|
||||
AMD_XCC_DSM_GET_XCP_MODE);
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp->xcp_mode = obj->integer.value & 0xFFFF;
|
||||
tmp->mem_mode = (obj->integer.value >> 32) & 0xFFFF;
|
||||
ACPI_FREE(obj);
|
||||
|
||||
/* Evaluate DSMs and fill XCC information */
|
||||
obj = acpi_evaluate_dsm_typed(xcc_info->handle, &amd_xcc_dsm_guid, 0,
|
||||
AMD_XCC_DSM_GET_TMR_INFO, NULL,
|
||||
ACPI_TYPE_PACKAGE);
|
||||
|
||||
if (!obj || obj->package.count < 2) {
|
||||
acpi_handle_debug(xcc_info->handle,
|
||||
"_DSM function %d evaluation failed",
|
||||
AMD_XCC_DSM_GET_TMR_INFO);
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp->tmr_base = obj->package.elements[0].integer.value;
|
||||
tmp->tmr_size = obj->package.elements[1].integer.value;
|
||||
ACPI_FREE(obj);
|
||||
|
||||
DRM_DEBUG_DRIVER(
|
||||
"New dev(%x): Supported xcp mode: %x curr xcp_mode : %x mem mode : %x, tmr base: %llx tmr size: %llx ",
|
||||
tmp->bdf, tmp->supp_xcp_mode, tmp->xcp_mode, tmp->mem_mode,
|
||||
tmp->tmr_base, tmp->tmr_size);
|
||||
list_add_tail(&tmp->list, &amdgpu_acpi_dev_list);
|
||||
*dev_info = tmp;
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
if (obj)
|
||||
ACPI_FREE(obj);
|
||||
kfree(tmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int amdgpu_acpi_get_xcc_info(struct amdgpu_acpi_xcc_info *xcc_info,
|
||||
u16 *bdf)
|
||||
{
|
||||
union acpi_object *obj;
|
||||
acpi_status status;
|
||||
int ret = -ENOENT;
|
||||
|
||||
obj = acpi_evaluate_dsm_typed(xcc_info->handle, &amd_xcc_dsm_guid, 0,
|
||||
AMD_XCC_DSM_GET_NUM_FUNCS, NULL,
|
||||
ACPI_TYPE_INTEGER);
|
||||
|
||||
if (!obj || obj->integer.value != AMD_XCC_DSM_NUM_FUNCS)
|
||||
goto out;
|
||||
ACPI_FREE(obj);
|
||||
|
||||
/* Evaluate DSMs and fill XCC information */
|
||||
obj = acpi_evaluate_dsm_typed(xcc_info->handle, &amd_xcc_dsm_guid, 0,
|
||||
AMD_XCC_DSM_GET_VF_XCC_MAPPING, NULL,
|
||||
ACPI_TYPE_INTEGER);
|
||||
|
||||
if (!obj) {
|
||||
acpi_handle_debug(xcc_info->handle,
|
||||
"_DSM function %d evaluation failed",
|
||||
AMD_XCC_DSM_GET_VF_XCC_MAPPING);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* PF xcc id [39:32] */
|
||||
xcc_info->phy_id = (obj->integer.value >> 32) & 0xFF;
|
||||
/* xcp node of this xcc [47:40] */
|
||||
xcc_info->xcp_node = (obj->integer.value >> 40) & 0xFF;
|
||||
/* PF bus/dev/fn of this xcc [63:48] */
|
||||
*bdf = (obj->integer.value >> 48) & 0xFFFF;
|
||||
ACPI_FREE(obj);
|
||||
obj = NULL;
|
||||
|
||||
status =
|
||||
amdgpu_acpi_get_node_id(xcc_info->handle, &xcc_info->numa_info);
|
||||
|
||||
/* TODO: check if this check is required */
|
||||
if (ACPI_SUCCESS(status))
|
||||
ret = 0;
|
||||
out:
|
||||
if (obj)
|
||||
ACPI_FREE(obj);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int amdgpu_acpi_enumerate_xcc(void)
|
||||
{
|
||||
struct amdgpu_acpi_dev_info *dev_info = NULL;
|
||||
struct amdgpu_acpi_xcc_info *xcc_info;
|
||||
struct acpi_device *acpi_dev;
|
||||
char hid[ACPI_ID_LEN];
|
||||
int ret, id;
|
||||
u16 bdf;
|
||||
|
||||
INIT_LIST_HEAD(&amdgpu_acpi_dev_list);
|
||||
xa_init(&numa_info_xa);
|
||||
|
||||
for (id = 0; id < AMD_XCC_MAX_HID; id++) {
|
||||
sprintf(hid, "%s%d", "AMD", AMD_XCC_HID_START + id);
|
||||
acpi_dev = acpi_dev_get_first_match_dev(hid, NULL, -1);
|
||||
/* These ACPI objects are expected to be in sequential order. If
|
||||
* one is not found, no need to check the rest.
|
||||
*/
|
||||
if (!acpi_dev) {
|
||||
DRM_DEBUG_DRIVER("No matching acpi device found for %s",
|
||||
hid);
|
||||
break;
|
||||
}
|
||||
|
||||
xcc_info = kzalloc(sizeof(struct amdgpu_acpi_xcc_info),
|
||||
GFP_KERNEL);
|
||||
if (!xcc_info) {
|
||||
DRM_ERROR("Failed to allocate memory for xcc info\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&xcc_info->list);
|
||||
xcc_info->handle = acpi_device_handle(acpi_dev);
|
||||
acpi_dev_put(acpi_dev);
|
||||
|
||||
ret = amdgpu_acpi_get_xcc_info(xcc_info, &bdf);
|
||||
if (ret) {
|
||||
kfree(xcc_info);
|
||||
continue;
|
||||
}
|
||||
|
||||
dev_info = amdgpu_acpi_get_dev(bdf);
|
||||
|
||||
if (!dev_info)
|
||||
ret = amdgpu_acpi_dev_init(&dev_info, xcc_info, bdf);
|
||||
|
||||
if (ret == -ENOMEM)
|
||||
return ret;
|
||||
|
||||
if (!dev_info) {
|
||||
kfree(xcc_info);
|
||||
continue;
|
||||
}
|
||||
|
||||
list_add_tail(&xcc_info->list, &dev_info->xcc_list);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_acpi_get_tmr_info(struct amdgpu_device *adev, u64 *tmr_offset,
|
||||
u64 *tmr_size)
|
||||
{
|
||||
struct amdgpu_acpi_dev_info *dev_info;
|
||||
u16 bdf;
|
||||
|
||||
if (!tmr_offset || !tmr_size)
|
||||
return -EINVAL;
|
||||
|
||||
bdf = (adev->pdev->bus->number << 8) | adev->pdev->devfn;
|
||||
dev_info = amdgpu_acpi_get_dev(bdf);
|
||||
if (!dev_info)
|
||||
return -ENOENT;
|
||||
|
||||
*tmr_offset = dev_info->tmr_base;
|
||||
*tmr_size = dev_info->tmr_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_acpi_get_mem_info(struct amdgpu_device *adev, int xcc_id,
|
||||
struct amdgpu_numa_info *numa_info)
|
||||
{
|
||||
struct amdgpu_acpi_dev_info *dev_info;
|
||||
struct amdgpu_acpi_xcc_info *xcc_info;
|
||||
u16 bdf;
|
||||
|
||||
if (!numa_info)
|
||||
return -EINVAL;
|
||||
|
||||
bdf = (adev->pdev->bus->number << 8) | adev->pdev->devfn;
|
||||
dev_info = amdgpu_acpi_get_dev(bdf);
|
||||
if (!dev_info)
|
||||
return -ENOENT;
|
||||
|
||||
list_for_each_entry(xcc_info, &dev_info->xcc_list, list) {
|
||||
if (xcc_info->phy_id == xcc_id) {
|
||||
memcpy(numa_info, xcc_info->numa_info,
|
||||
sizeof(*numa_info));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_acpi_event - handle notify events
|
||||
*
|
||||
@ -1054,6 +1431,36 @@ void amdgpu_acpi_detect(void)
|
||||
} else {
|
||||
atif->backlight_caps.caps_valid = false;
|
||||
}
|
||||
|
||||
amdgpu_acpi_enumerate_xcc();
|
||||
}
|
||||
|
||||
void amdgpu_acpi_release(void)
|
||||
{
|
||||
struct amdgpu_acpi_dev_info *dev_info, *dev_tmp;
|
||||
struct amdgpu_acpi_xcc_info *xcc_info, *xcc_tmp;
|
||||
struct amdgpu_numa_info *numa_info;
|
||||
unsigned long index;
|
||||
|
||||
xa_for_each(&numa_info_xa, index, numa_info) {
|
||||
kfree(numa_info);
|
||||
xa_erase(&numa_info_xa, index);
|
||||
}
|
||||
|
||||
if (list_empty(&amdgpu_acpi_dev_list))
|
||||
return;
|
||||
|
||||
list_for_each_entry_safe(dev_info, dev_tmp, &amdgpu_acpi_dev_list,
|
||||
list) {
|
||||
list_for_each_entry_safe(xcc_info, xcc_tmp, &dev_info->xcc_list,
|
||||
list) {
|
||||
list_del(&xcc_info->list);
|
||||
kfree(xcc_info);
|
||||
}
|
||||
|
||||
list_del(&dev_info->list);
|
||||
kfree(dev_info);
|
||||
}
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_SUSPEND)
|
||||
|
@ -53,7 +53,6 @@ int amdgpu_amdkfd_init(void)
|
||||
amdgpu_amdkfd_total_mem_size *= si.mem_unit;
|
||||
|
||||
ret = kgd2kfd_init();
|
||||
amdgpu_amdkfd_gpuvm_init_mem_limits();
|
||||
kfd_initialized = !ret;
|
||||
|
||||
return ret;
|
||||
@ -143,6 +142,8 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
||||
int i;
|
||||
int last_valid_bit;
|
||||
|
||||
amdgpu_amdkfd_gpuvm_init_mem_limits();
|
||||
|
||||
if (adev->kfd.dev) {
|
||||
struct kgd2kfd_shared_resources gpu_resources = {
|
||||
.compute_vmid_bitmap =
|
||||
@ -162,7 +163,7 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
||||
* clear
|
||||
*/
|
||||
bitmap_complement(gpu_resources.cp_queue_bitmap,
|
||||
adev->gfx.mec.queue_bitmap,
|
||||
adev->gfx.mec_bitmap[0].queue_bitmap,
|
||||
KGD_MAX_QUEUES);
|
||||
|
||||
/* According to linux/bitmap.h we shouldn't use bitmap_clear if
|
||||
@ -427,14 +428,23 @@ uint32_t amdgpu_amdkfd_get_fw_version(struct amdgpu_device *adev,
|
||||
}
|
||||
|
||||
void amdgpu_amdkfd_get_local_mem_info(struct amdgpu_device *adev,
|
||||
struct kfd_local_mem_info *mem_info)
|
||||
struct kfd_local_mem_info *mem_info,
|
||||
struct amdgpu_xcp *xcp)
|
||||
{
|
||||
memset(mem_info, 0, sizeof(*mem_info));
|
||||
|
||||
mem_info->local_mem_size_public = adev->gmc.visible_vram_size;
|
||||
mem_info->local_mem_size_private = adev->gmc.real_vram_size -
|
||||
if (xcp) {
|
||||
if (adev->gmc.real_vram_size == adev->gmc.visible_vram_size)
|
||||
mem_info->local_mem_size_public =
|
||||
KFD_XCP_MEMORY_SIZE(adev, xcp->id);
|
||||
else
|
||||
mem_info->local_mem_size_private =
|
||||
KFD_XCP_MEMORY_SIZE(adev, xcp->id);
|
||||
} else {
|
||||
mem_info->local_mem_size_public = adev->gmc.visible_vram_size;
|
||||
mem_info->local_mem_size_private = adev->gmc.real_vram_size -
|
||||
adev->gmc.visible_vram_size;
|
||||
|
||||
}
|
||||
mem_info->vram_width = adev->gmc.vram_width;
|
||||
|
||||
pr_debug("Address base: %pap public 0x%llx private 0x%llx\n",
|
||||
@ -497,7 +507,7 @@ int amdgpu_amdkfd_get_dmabuf_info(struct amdgpu_device *adev, int dma_buf_fd,
|
||||
struct amdgpu_device **dmabuf_adev,
|
||||
uint64_t *bo_size, void *metadata_buffer,
|
||||
size_t buffer_size, uint32_t *metadata_size,
|
||||
uint32_t *flags)
|
||||
uint32_t *flags, int8_t *xcp_id)
|
||||
{
|
||||
struct dma_buf *dma_buf;
|
||||
struct drm_gem_object *obj;
|
||||
@ -541,6 +551,8 @@ int amdgpu_amdkfd_get_dmabuf_info(struct amdgpu_device *adev, int dma_buf_fd,
|
||||
if (bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)
|
||||
*flags |= KFD_IOC_ALLOC_MEM_FLAGS_PUBLIC;
|
||||
}
|
||||
if (xcp_id)
|
||||
*xcp_id = bo->xcp_id;
|
||||
|
||||
out_put:
|
||||
dma_buf_put(dma_buf);
|
||||
@ -732,17 +744,19 @@ int amdgpu_amdkfd_flush_gpu_tlb_vmid(struct amdgpu_device *adev,
|
||||
if (adev->family == AMDGPU_FAMILY_AI) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < adev->num_vmhubs; i++)
|
||||
for_each_set_bit(i, adev->vmhubs_mask, AMDGPU_MAX_VMHUBS)
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, vmid, i, 0);
|
||||
} else {
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, vmid, AMDGPU_GFXHUB_0, 0);
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, vmid, AMDGPU_GFXHUB(0), 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
|
||||
uint16_t pasid, enum TLB_FLUSH_TYPE flush_type)
|
||||
uint16_t pasid,
|
||||
enum TLB_FLUSH_TYPE flush_type,
|
||||
uint32_t inst)
|
||||
{
|
||||
bool all_hub = false;
|
||||
|
||||
@ -750,7 +764,7 @@ int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
|
||||
adev->family == AMDGPU_FAMILY_RV)
|
||||
all_hub = true;
|
||||
|
||||
return amdgpu_gmc_flush_gpu_tlb_pasid(adev, pasid, flush_type, all_hub);
|
||||
return amdgpu_gmc_flush_gpu_tlb_pasid(adev, pasid, flush_type, all_hub, inst);
|
||||
}
|
||||
|
||||
bool amdgpu_amdkfd_have_atomics_support(struct amdgpu_device *adev)
|
||||
@ -758,11 +772,32 @@ bool amdgpu_amdkfd_have_atomics_support(struct amdgpu_device *adev)
|
||||
return adev->have_atomics_support;
|
||||
}
|
||||
|
||||
void amdgpu_amdkfd_debug_mem_fence(struct amdgpu_device *adev)
|
||||
{
|
||||
amdgpu_device_flush_hdp(adev, NULL);
|
||||
}
|
||||
|
||||
void amdgpu_amdkfd_ras_poison_consumption_handler(struct amdgpu_device *adev, bool reset)
|
||||
{
|
||||
amdgpu_umc_poison_handler(adev, reset);
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_send_close_event_drain_irq(struct amdgpu_device *adev,
|
||||
uint32_t *payload)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Device or IH ring is not ready so bail. */
|
||||
ret = amdgpu_ih_wait_on_checkpoint_process_ts(adev, &adev->irq.ih);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Send payload to fence KFD interrupts */
|
||||
amdgpu_amdkfd_interrupt(adev, payload);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool amdgpu_amdkfd_ras_query_utcl2_poison_status(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->gfx.ras && adev->gfx.ras->query_utcl2_poison_status)
|
||||
@ -770,3 +805,28 @@ bool amdgpu_amdkfd_ras_query_utcl2_poison_status(struct amdgpu_device *adev)
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_check_and_lock_kfd(struct amdgpu_device *adev)
|
||||
{
|
||||
return kgd2kfd_check_and_lock_kfd();
|
||||
}
|
||||
|
||||
void amdgpu_amdkfd_unlock_kfd(struct amdgpu_device *adev)
|
||||
{
|
||||
kgd2kfd_unlock_kfd();
|
||||
}
|
||||
|
||||
|
||||
u64 amdgpu_amdkfd_xcp_memory_size(struct amdgpu_device *adev, int xcp_id)
|
||||
{
|
||||
u64 tmp;
|
||||
s8 mem_id = KFD_XCP_MEM_ID(adev, xcp_id);
|
||||
|
||||
if (adev->gmc.num_mem_partitions && xcp_id >= 0 && mem_id >= 0) {
|
||||
tmp = adev->gmc.mem_partitions[mem_id].size;
|
||||
do_div(tmp, adev->xcp_mgr->num_xcp_per_mem_partition);
|
||||
return ALIGN_DOWN(tmp, PAGE_SIZE);
|
||||
} else {
|
||||
return adev->gmc.real_vram_size;
|
||||
}
|
||||
}
|
||||
|
@ -30,10 +30,12 @@
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/mmu_notifier.h>
|
||||
#include <linux/memremap.h>
|
||||
#include <kgd_kfd_interface.h>
|
||||
#include <drm/ttm/ttm_execbuf_util.h>
|
||||
#include "amdgpu_sync.h"
|
||||
#include "amdgpu_vm.h"
|
||||
#include "amdgpu_xcp.h"
|
||||
|
||||
extern uint64_t amdgpu_amdkfd_total_mem_size;
|
||||
|
||||
@ -97,10 +99,13 @@ struct amdgpu_amdkfd_fence {
|
||||
|
||||
struct amdgpu_kfd_dev {
|
||||
struct kfd_dev *dev;
|
||||
int64_t vram_used;
|
||||
uint64_t vram_used_aligned;
|
||||
int64_t vram_used[MAX_XCP];
|
||||
uint64_t vram_used_aligned[MAX_XCP];
|
||||
bool init_complete;
|
||||
struct work_struct reset_work;
|
||||
|
||||
/* HMM page migration MEMORY_DEVICE_PRIVATE mapping */
|
||||
struct dev_pagemap pgmap;
|
||||
};
|
||||
|
||||
enum kgd_engine_type {
|
||||
@ -151,6 +156,8 @@ void amdgpu_amdkfd_interrupt(struct amdgpu_device *adev,
|
||||
void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev);
|
||||
void amdgpu_amdkfd_device_init(struct amdgpu_device *adev);
|
||||
void amdgpu_amdkfd_device_fini_sw(struct amdgpu_device *adev);
|
||||
int amdgpu_amdkfd_check_and_lock_kfd(struct amdgpu_device *adev);
|
||||
void amdgpu_amdkfd_unlock_kfd(struct amdgpu_device *adev);
|
||||
int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev,
|
||||
enum kgd_engine_type engine,
|
||||
uint32_t vmid, uint64_t gpu_addr,
|
||||
@ -160,7 +167,8 @@ bool amdgpu_amdkfd_have_atomics_support(struct amdgpu_device *adev);
|
||||
int amdgpu_amdkfd_flush_gpu_tlb_vmid(struct amdgpu_device *adev,
|
||||
uint16_t vmid);
|
||||
int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
|
||||
uint16_t pasid, enum TLB_FLUSH_TYPE flush_type);
|
||||
uint16_t pasid, enum TLB_FLUSH_TYPE flush_type,
|
||||
uint32_t inst);
|
||||
|
||||
bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid);
|
||||
|
||||
@ -224,7 +232,8 @@ int amdgpu_amdkfd_remove_gws_from_process(void *info, void *mem);
|
||||
uint32_t amdgpu_amdkfd_get_fw_version(struct amdgpu_device *adev,
|
||||
enum kgd_engine_type type);
|
||||
void amdgpu_amdkfd_get_local_mem_info(struct amdgpu_device *adev,
|
||||
struct kfd_local_mem_info *mem_info);
|
||||
struct kfd_local_mem_info *mem_info,
|
||||
struct amdgpu_xcp *xcp);
|
||||
uint64_t amdgpu_amdkfd_get_gpu_clock_counter(struct amdgpu_device *adev);
|
||||
|
||||
uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct amdgpu_device *adev);
|
||||
@ -234,13 +243,15 @@ int amdgpu_amdkfd_get_dmabuf_info(struct amdgpu_device *adev, int dma_buf_fd,
|
||||
struct amdgpu_device **dmabuf_adev,
|
||||
uint64_t *bo_size, void *metadata_buffer,
|
||||
size_t buffer_size, uint32_t *metadata_size,
|
||||
uint32_t *flags);
|
||||
uint32_t *flags, int8_t *xcp_id);
|
||||
uint8_t amdgpu_amdkfd_get_xgmi_hops_count(struct amdgpu_device *dst,
|
||||
struct amdgpu_device *src);
|
||||
int amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(struct amdgpu_device *dst,
|
||||
struct amdgpu_device *src,
|
||||
bool is_min);
|
||||
int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct amdgpu_device *adev, bool is_min);
|
||||
int amdgpu_amdkfd_send_close_event_drain_irq(struct amdgpu_device *adev,
|
||||
uint32_t *payload);
|
||||
|
||||
/* Read user wptr from a specified user address space with page fault
|
||||
* disabled. The memory must be pinned and mapped to the hardware when
|
||||
@ -279,7 +290,8 @@ int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
|
||||
void amdgpu_amdkfd_gpuvm_release_process_vm(struct amdgpu_device *adev,
|
||||
void *drm_priv);
|
||||
uint64_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *drm_priv);
|
||||
size_t amdgpu_amdkfd_get_available_memory(struct amdgpu_device *adev);
|
||||
size_t amdgpu_amdkfd_get_available_memory(struct amdgpu_device *adev,
|
||||
uint8_t xcp_id);
|
||||
int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
|
||||
struct amdgpu_device *adev, uint64_t va, uint64_t size,
|
||||
void *drm_priv, struct kgd_mem **mem,
|
||||
@ -310,6 +322,7 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev,
|
||||
uint64_t *mmap_offset);
|
||||
int amdgpu_amdkfd_gpuvm_export_dmabuf(struct kgd_mem *mem,
|
||||
struct dma_buf **dmabuf);
|
||||
void amdgpu_amdkfd_debug_mem_fence(struct amdgpu_device *adev);
|
||||
int amdgpu_amdkfd_get_tile_config(struct amdgpu_device *adev,
|
||||
struct tile_config *config);
|
||||
void amdgpu_amdkfd_ras_poison_consumption_handler(struct amdgpu_device *adev,
|
||||
@ -319,9 +332,18 @@ void amdgpu_amdkfd_block_mmu_notifications(void *p);
|
||||
int amdgpu_amdkfd_criu_resume(void *p);
|
||||
bool amdgpu_amdkfd_ras_query_utcl2_poison_status(struct amdgpu_device *adev);
|
||||
int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
|
||||
uint64_t size, u32 alloc_flag);
|
||||
uint64_t size, u32 alloc_flag, int8_t xcp_id);
|
||||
void amdgpu_amdkfd_unreserve_mem_limit(struct amdgpu_device *adev,
|
||||
uint64_t size, u32 alloc_flag);
|
||||
uint64_t size, u32 alloc_flag, int8_t xcp_id);
|
||||
|
||||
u64 amdgpu_amdkfd_xcp_memory_size(struct amdgpu_device *adev, int xcp_id);
|
||||
|
||||
#define KFD_XCP_MEM_ID(adev, xcp_id) \
|
||||
((adev)->xcp_mgr && (xcp_id) >= 0 ?\
|
||||
(adev)->xcp_mgr->xcp[(xcp_id)].mem_id : -1)
|
||||
|
||||
#define KFD_XCP_MEMORY_SIZE(adev, xcp_id) amdgpu_amdkfd_xcp_memory_size((adev), (xcp_id))
|
||||
|
||||
|
||||
#if IS_ENABLED(CONFIG_HSA_AMD)
|
||||
void amdgpu_amdkfd_gpuvm_init_mem_limits(void);
|
||||
@ -352,6 +374,17 @@ void amdgpu_amdkfd_release_notify(struct amdgpu_bo *bo)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_HSA_AMD_SVM)
|
||||
int kgd2kfd_init_zone_device(struct amdgpu_device *adev);
|
||||
#else
|
||||
static inline
|
||||
int kgd2kfd_init_zone_device(struct amdgpu_device *adev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* KGD2KFD callbacks */
|
||||
int kgd2kfd_quiesce_mm(struct mm_struct *mm, uint32_t trigger);
|
||||
int kgd2kfd_resume_mm(struct mm_struct *mm);
|
||||
@ -372,6 +405,8 @@ int kgd2kfd_post_reset(struct kfd_dev *kfd);
|
||||
void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry);
|
||||
void kgd2kfd_set_sram_ecc_flag(struct kfd_dev *kfd);
|
||||
void kgd2kfd_smi_event_throttle(struct kfd_dev *kfd, uint64_t throttle_bitmask);
|
||||
int kgd2kfd_check_and_lock_kfd(void);
|
||||
void kgd2kfd_unlock_kfd(void);
|
||||
#else
|
||||
static inline int kgd2kfd_init(void)
|
||||
{
|
||||
@ -437,5 +472,14 @@ static inline
|
||||
void kgd2kfd_smi_event_throttle(struct kfd_dev *kfd, uint64_t throttle_bitmask)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int kgd2kfd_check_and_lock_kfd(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void kgd2kfd_unlock_kfd(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#endif /* AMDGPU_AMDKFD_H_INCLUDED */
|
||||
|
@ -23,6 +23,149 @@
|
||||
#include "amdgpu_amdkfd.h"
|
||||
#include "amdgpu_amdkfd_arcturus.h"
|
||||
#include "amdgpu_amdkfd_gfx_v9.h"
|
||||
#include "gc/gc_9_4_2_offset.h"
|
||||
#include "gc/gc_9_4_2_sh_mask.h"
|
||||
#include <uapi/linux/kfd_ioctl.h>
|
||||
|
||||
/*
|
||||
* Returns TRAP_EN, EXCP_EN and EXCP_REPLACE.
|
||||
*
|
||||
* restore_dbg_registers is ignored here but is a general interface requirement
|
||||
* for devices that support GFXOFF and where the RLC save/restore list
|
||||
* does not support hw registers for debugging i.e. the driver has to manually
|
||||
* initialize the debug mode registers after it has disabled GFX off during the
|
||||
* debug session.
|
||||
*/
|
||||
static uint32_t kgd_aldebaran_enable_debug_trap(struct amdgpu_device *adev,
|
||||
bool restore_dbg_registers,
|
||||
uint32_t vmid)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
|
||||
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, TRAP_EN, 1);
|
||||
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_EN, 0);
|
||||
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_REPLACE, 0);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/* returns TRAP_EN, EXCP_EN and EXCP_REPLACE. */
|
||||
static uint32_t kgd_aldebaran_disable_debug_trap(struct amdgpu_device *adev,
|
||||
bool keep_trap_enabled,
|
||||
uint32_t vmid)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
|
||||
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, TRAP_EN, keep_trap_enabled);
|
||||
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_EN, 0);
|
||||
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_REPLACE, 0);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static int kgd_aldebaran_validate_trap_override_request(struct amdgpu_device *adev,
|
||||
uint32_t trap_override,
|
||||
uint32_t *trap_mask_supported)
|
||||
{
|
||||
*trap_mask_supported &= KFD_DBG_TRAP_MASK_FP_INVALID |
|
||||
KFD_DBG_TRAP_MASK_FP_INPUT_DENORMAL |
|
||||
KFD_DBG_TRAP_MASK_FP_DIVIDE_BY_ZERO |
|
||||
KFD_DBG_TRAP_MASK_FP_OVERFLOW |
|
||||
KFD_DBG_TRAP_MASK_FP_UNDERFLOW |
|
||||
KFD_DBG_TRAP_MASK_FP_INEXACT |
|
||||
KFD_DBG_TRAP_MASK_INT_DIVIDE_BY_ZERO |
|
||||
KFD_DBG_TRAP_MASK_DBG_ADDRESS_WATCH |
|
||||
KFD_DBG_TRAP_MASK_DBG_MEMORY_VIOLATION;
|
||||
|
||||
if (trap_override != KFD_DBG_TRAP_OVERRIDE_OR &&
|
||||
trap_override != KFD_DBG_TRAP_OVERRIDE_REPLACE)
|
||||
return -EPERM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* returns TRAP_EN, EXCP_EN and EXCP_RPLACE. */
|
||||
static uint32_t kgd_aldebaran_set_wave_launch_trap_override(struct amdgpu_device *adev,
|
||||
uint32_t vmid,
|
||||
uint32_t trap_override,
|
||||
uint32_t trap_mask_bits,
|
||||
uint32_t trap_mask_request,
|
||||
uint32_t *trap_mask_prev,
|
||||
uint32_t kfd_dbg_trap_cntl_prev)
|
||||
|
||||
{
|
||||
uint32_t data = 0;
|
||||
|
||||
*trap_mask_prev = REG_GET_FIELD(kfd_dbg_trap_cntl_prev, SPI_GDBG_PER_VMID_CNTL, EXCP_EN);
|
||||
trap_mask_bits = (trap_mask_bits & trap_mask_request) |
|
||||
(*trap_mask_prev & ~trap_mask_request);
|
||||
|
||||
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, TRAP_EN, 1);
|
||||
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_EN, trap_mask_bits);
|
||||
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_REPLACE, trap_override);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static uint32_t kgd_aldebaran_set_wave_launch_mode(struct amdgpu_device *adev,
|
||||
uint8_t wave_launch_mode,
|
||||
uint32_t vmid)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
|
||||
data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, LAUNCH_MODE, wave_launch_mode);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
#define TCP_WATCH_STRIDE (regTCP_WATCH1_ADDR_H - regTCP_WATCH0_ADDR_H)
|
||||
static uint32_t kgd_gfx_aldebaran_set_address_watch(
|
||||
struct amdgpu_device *adev,
|
||||
uint64_t watch_address,
|
||||
uint32_t watch_address_mask,
|
||||
uint32_t watch_id,
|
||||
uint32_t watch_mode,
|
||||
uint32_t debug_vmid)
|
||||
{
|
||||
uint32_t watch_address_high;
|
||||
uint32_t watch_address_low;
|
||||
uint32_t watch_address_cntl;
|
||||
|
||||
watch_address_cntl = 0;
|
||||
watch_address_low = lower_32_bits(watch_address);
|
||||
watch_address_high = upper_32_bits(watch_address) & 0xffff;
|
||||
|
||||
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
|
||||
TCP_WATCH0_CNTL,
|
||||
MODE,
|
||||
watch_mode);
|
||||
|
||||
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
|
||||
TCP_WATCH0_CNTL,
|
||||
MASK,
|
||||
watch_address_mask >> 6);
|
||||
|
||||
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
|
||||
TCP_WATCH0_CNTL,
|
||||
VALID,
|
||||
1);
|
||||
|
||||
WREG32_RLC((SOC15_REG_OFFSET(GC, 0, regTCP_WATCH0_ADDR_H) +
|
||||
(watch_id * TCP_WATCH_STRIDE)),
|
||||
watch_address_high);
|
||||
|
||||
WREG32_RLC((SOC15_REG_OFFSET(GC, 0, regTCP_WATCH0_ADDR_L) +
|
||||
(watch_id * TCP_WATCH_STRIDE)),
|
||||
watch_address_low);
|
||||
|
||||
return watch_address_cntl;
|
||||
}
|
||||
|
||||
static uint32_t kgd_gfx_aldebaran_clear_address_watch(struct amdgpu_device *adev,
|
||||
uint32_t watch_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct kfd2kgd_calls aldebaran_kfd2kgd = {
|
||||
.program_sh_mem_settings = kgd_gfx_v9_program_sh_mem_settings,
|
||||
@ -42,5 +185,14 @@ const struct kfd2kgd_calls aldebaran_kfd2kgd = {
|
||||
kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
|
||||
.set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base,
|
||||
.get_cu_occupancy = kgd_gfx_v9_get_cu_occupancy,
|
||||
.program_trap_handler_settings = kgd_gfx_v9_program_trap_handler_settings
|
||||
.enable_debug_trap = kgd_aldebaran_enable_debug_trap,
|
||||
.disable_debug_trap = kgd_aldebaran_disable_debug_trap,
|
||||
.validate_trap_override_request = kgd_aldebaran_validate_trap_override_request,
|
||||
.set_wave_launch_trap_override = kgd_aldebaran_set_wave_launch_trap_override,
|
||||
.set_wave_launch_mode = kgd_aldebaran_set_wave_launch_mode,
|
||||
.set_address_watch = kgd_gfx_aldebaran_set_address_watch,
|
||||
.clear_address_watch = kgd_gfx_aldebaran_clear_address_watch,
|
||||
.get_iq_wait_times = kgd_gfx_v9_get_iq_wait_times,
|
||||
.build_grace_period_packet_info = kgd_gfx_v9_build_grace_period_packet_info,
|
||||
.program_trap_handler_settings = kgd_gfx_v9_program_trap_handler_settings,
|
||||
};
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_amdkfd.h"
|
||||
#include "amdgpu_amdkfd_arcturus.h"
|
||||
#include "amdgpu_reset.h"
|
||||
#include "sdma0/sdma0_4_2_2_offset.h"
|
||||
#include "sdma0/sdma0_4_2_2_sh_mask.h"
|
||||
#include "sdma1/sdma1_4_2_2_offset.h"
|
||||
@ -48,6 +49,8 @@
|
||||
#include "amdgpu_amdkfd_gfx_v9.h"
|
||||
#include "gfxhub_v1_0.h"
|
||||
#include "mmhub_v9_4.h"
|
||||
#include "gc/gc_9_0_offset.h"
|
||||
#include "gc/gc_9_0_sh_mask.h"
|
||||
|
||||
#define HQD_N_REGS 56
|
||||
#define DUMP_REG(addr) do { \
|
||||
@ -276,6 +279,117 @@ int kgd_arcturus_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper used to suspend/resume gfx pipe for image post process work to set
|
||||
* barrier behaviour.
|
||||
*/
|
||||
static int suspend_resume_compute_scheduler(struct amdgpu_device *adev, bool suspend)
|
||||
{
|
||||
int i, r = 0;
|
||||
|
||||
for (i = 0; i < adev->gfx.num_compute_rings; i++) {
|
||||
struct amdgpu_ring *ring = &adev->gfx.compute_ring[i];
|
||||
|
||||
if (!(ring && ring->sched.thread))
|
||||
continue;
|
||||
|
||||
/* stop secheduler and drain ring. */
|
||||
if (suspend) {
|
||||
drm_sched_stop(&ring->sched, NULL);
|
||||
r = amdgpu_fence_wait_empty(ring);
|
||||
if (r)
|
||||
goto out;
|
||||
} else {
|
||||
drm_sched_start(&ring->sched, false);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
/* return on resume or failure to drain rings. */
|
||||
if (!suspend || r)
|
||||
return r;
|
||||
|
||||
return amdgpu_device_ip_wait_for_idle(adev, AMD_IP_BLOCK_TYPE_GFX);
|
||||
}
|
||||
|
||||
static void set_barrier_auto_waitcnt(struct amdgpu_device *adev, bool enable_waitcnt)
|
||||
{
|
||||
uint32_t data;
|
||||
|
||||
WRITE_ONCE(adev->barrier_has_auto_waitcnt, enable_waitcnt);
|
||||
|
||||
if (!down_read_trylock(&adev->reset_domain->sem))
|
||||
return;
|
||||
|
||||
amdgpu_amdkfd_suspend(adev, false);
|
||||
|
||||
if (suspend_resume_compute_scheduler(adev, true))
|
||||
goto out;
|
||||
|
||||
data = RREG32(SOC15_REG_OFFSET(GC, 0, mmSQ_CONFIG));
|
||||
data = REG_SET_FIELD(data, SQ_CONFIG, DISABLE_BARRIER_WAITCNT,
|
||||
!enable_waitcnt);
|
||||
WREG32(SOC15_REG_OFFSET(GC, 0, mmSQ_CONFIG), data);
|
||||
|
||||
out:
|
||||
suspend_resume_compute_scheduler(adev, false);
|
||||
|
||||
amdgpu_amdkfd_resume(adev, false);
|
||||
|
||||
up_read(&adev->reset_domain->sem);
|
||||
}
|
||||
|
||||
/*
|
||||
* restore_dbg_registers is ignored here but is a general interface requirement
|
||||
* for devices that support GFXOFF and where the RLC save/restore list
|
||||
* does not support hw registers for debugging i.e. the driver has to manually
|
||||
* initialize the debug mode registers after it has disabled GFX off during the
|
||||
* debug session.
|
||||
*/
|
||||
static uint32_t kgd_arcturus_enable_debug_trap(struct amdgpu_device *adev,
|
||||
bool restore_dbg_registers,
|
||||
uint32_t vmid)
|
||||
{
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
|
||||
kgd_gfx_v9_set_wave_launch_stall(adev, vmid, true);
|
||||
|
||||
set_barrier_auto_waitcnt(adev, true);
|
||||
|
||||
WREG32(SOC15_REG_OFFSET(GC, 0, mmSPI_GDBG_TRAP_MASK), 0);
|
||||
|
||||
kgd_gfx_v9_set_wave_launch_stall(adev, vmid, false);
|
||||
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* keep_trap_enabled is ignored here but is a general interface requirement
|
||||
* for devices that support multi-process debugging where the performance
|
||||
* overhead from trap temporary setup needs to be bypassed when the debug
|
||||
* session has ended.
|
||||
*/
|
||||
static uint32_t kgd_arcturus_disable_debug_trap(struct amdgpu_device *adev,
|
||||
bool keep_trap_enabled,
|
||||
uint32_t vmid)
|
||||
{
|
||||
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
|
||||
kgd_gfx_v9_set_wave_launch_stall(adev, vmid, true);
|
||||
|
||||
set_barrier_auto_waitcnt(adev, false);
|
||||
|
||||
WREG32(SOC15_REG_OFFSET(GC, 0, mmSPI_GDBG_TRAP_MASK), 0);
|
||||
|
||||
kgd_gfx_v9_set_wave_launch_stall(adev, vmid, false);
|
||||
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
const struct kfd2kgd_calls arcturus_kfd2kgd = {
|
||||
.program_sh_mem_settings = kgd_gfx_v9_program_sh_mem_settings,
|
||||
.set_pasid_vmid_mapping = kgd_gfx_v9_set_pasid_vmid_mapping,
|
||||
@ -294,6 +408,15 @@ const struct kfd2kgd_calls arcturus_kfd2kgd = {
|
||||
kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
|
||||
.set_vm_context_page_table_base =
|
||||
kgd_gfx_v9_set_vm_context_page_table_base,
|
||||
.enable_debug_trap = kgd_arcturus_enable_debug_trap,
|
||||
.disable_debug_trap = kgd_arcturus_disable_debug_trap,
|
||||
.validate_trap_override_request = kgd_gfx_v9_validate_trap_override_request,
|
||||
.set_wave_launch_trap_override = kgd_gfx_v9_set_wave_launch_trap_override,
|
||||
.set_wave_launch_mode = kgd_gfx_v9_set_wave_launch_mode,
|
||||
.set_address_watch = kgd_gfx_v9_set_address_watch,
|
||||
.clear_address_watch = kgd_gfx_v9_clear_address_watch,
|
||||
.get_iq_wait_times = kgd_gfx_v9_get_iq_wait_times,
|
||||
.build_grace_period_packet_info = kgd_gfx_v9_build_grace_period_packet_info,
|
||||
.get_cu_occupancy = kgd_gfx_v9_get_cu_occupancy,
|
||||
.program_trap_handler_settings = kgd_gfx_v9_program_trap_handler_settings
|
||||
};
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user