Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Cross-merge networking fixes after downstream PR (net-7.2-rc7).

No conflicts, or adjacent changes.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-08-06 11:51:42 -07:00
commit 1962afd211
491 changed files with 6077 additions and 2232 deletions

View File

@ -177,6 +177,7 @@ Brian Cain <bcain@kernel.org> <bcain@quicinc.com>
Brian King <brking@us.ibm.com>
Brian Silverman <bsilver16384@gmail.com> <brian.silverman@bluerivertech.com>
Bryan Tan <bryan-bt.tan@broadcom.com> <bryantan@vmware.com>
Burak Emir <burak.emir@gmail.com> <bqe@google.com>
Cai Huoqing <cai.huoqing@linux.dev> <caihuoqing@baidu.com>
Casey Connolly <casey.connolly@linaro.org> <caleb.connolly@linaro.org>
Casey Connolly <casey.connolly@linaro.org> <caleb@connolly.tech>
@ -650,6 +651,7 @@ Nicholas Piggin <npiggin@gmail.com> <npiggin@suse.de>
Nicholas Piggin <npiggin@gmail.com> <nickpiggin@yahoo.com.au>
Nicholas Piggin <npiggin@gmail.com> <piggin@cyberone.com.au>
Nicolas Ferre <nicolas.ferre@microchip.com> <nicolas.ferre@atmel.com>
Nico Pache <nico.pache@linux.dev> <npache@redhat.com>
Nicolas Pitre <nico@fluxnic.net> <nicolas.pitre@linaro.org>
Nicolas Pitre <nico@fluxnic.net> <nico@linaro.org>
Nicolas Saenz Julienne <nsaenz@kernel.org> <nsaenzjulienne@suse.de>
@ -697,6 +699,7 @@ Paulo Alcantara <pc@manguebit.org> <palcantara@suse.com>
Paulo Alcantara <pc@manguebit.org> <pc@manguebit.com>
Pavankumar Kondeti <quic_pkondeti@quicinc.com> <pkondeti@codeaurora.org>
Peter A Jonsson <pj@ludd.ltu.se>
Peter Collingbourne <peter@pcc.me.uk> <pcc@google.com>
Peter Hilber <peter.hilber@oss.qualcomm.com> <quic_philber@quicinc.com>
Peter Oruba <peter.oruba@amd.com>
Peter Oruba <peter@oruba.de>

View File

@ -10,3 +10,4 @@ Description:
0 no adjustment of input current limit. This
helps for more unusual power sources like
solar modules.
============ ===========================================

View File

@ -2239,9 +2239,12 @@ IO Latency
~~~~~~~~~~
This is a cgroup v2 controller for IO workload protection. You provide a group
with a latency target, and if the average latency exceeds that target the
controller will throttle any peers that have a lower latency target than the
protected workload.
with a latency target, and if the group misses its target the controller will
throttle any peers that have a lower latency target than the protected
workload. How a miss is detected depends on the device: on rotational devices
the average latency over the window must exceed the target, while on
non-rotational devices a miss is counted once enough of the IOs in the window
individually exceed the target.
The limits are only applied at the peer level in the hierarchy. This means that
in the diagram below, only groups A, B, and C will influence each other, and
@ -2258,10 +2261,12 @@ So the ideal way to configure this is to set io.latency in groups A, B, and C.
Generally you do not want to set a value lower than the latency your device
supports. Experiment to find the value that works best for your workload.
Start at higher than the expected latency for your device and, with
blkcg_debug_stats enabled, watch the avg_lat value in io.stat for your
workload group to get an idea of the latency you see during normal operation.
Use the avg_lat value as a basis for your real setting, setting at 10-15%
higher than the value in io.stat.
blkcg_debug_stats enabled, observe io.stat for your workload group to get an
idea of the latency you see during normal operation. On rotational devices,
use the avg_lat value as a basis for your real setting, setting it 10-15%
higher. On non-rotational devices io.stat reports no average latency; set
the target based on your device and use the missed/total fields to verify it
is being met.
How IO Latency Throttling Works
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -2303,19 +2308,36 @@ IO Latency Interface Files
the blkcg_debug_stats module parameter is enabled (it is disabled by
default).
The reported latency fields depend on the device. Rotational devices
report avg_lat and win; non-rotational devices report missed and total
instead. missed and total are live counters for the current window and
may change between reads.
depth
This is the current queue depth for the group.
avg_lat
This is an exponential moving average with a decay rate of 1/exp
bound by the sampling interval. The decay rate interval can be
calculated by multiplying the win value in io.stat by the
corresponding number of samples based on the win value.
(Rotational devices only.) This is an exponential moving
average with a decay rate of 1/exp bound by the sampling
interval. The decay rate interval can be calculated by
multiplying the win value in io.stat by the corresponding number
of samples based on the win value.
win
The sampling window size in milliseconds. This is the minimum
duration of time between evaluation events. Windows only elapse
with IO activity. Idle periods extend the most recent window.
(Rotational devices only.) The sampling window size in
milliseconds. This is the minimum duration of time between
evaluation events. Windows only elapse with IO activity. Idle
periods extend the most recent window.
missed
(Non-rotational devices only.) The number of IOs in the
current window whose latency exceeded the target. A group is
considered to be missing its target once missed reaches a
certain ratio of total.
total
(Non-rotational devices only.) The total number of IOs
accounted in the current window.
IO Priority
~~~~~~~~~~~

View File

@ -135,7 +135,6 @@ properties:
required:
- compatible
- reg
- interrupts
unevaluatedProperties: false

View File

@ -18,7 +18,14 @@ properties:
- const: qcom,sa8255p-ufshc
reg:
maxItems: 1
minItems: 1
maxItems: 2
reg-names:
minItems: 1
items:
- const: std
- const: mcq
interrupts:
maxItems: 1

View File

@ -118,12 +118,16 @@ attribute-sets:
doc: >-
The number of seconds after which a keep alive message is sent to the
peer
checks:
max: 86400
-
name: keepalive-timeout
type: u32
doc: >-
The number of seconds from the last activity after which the peer is
assumed dead
checks:
max: 86400
-
name: del-reason
type: u32

View File

@ -2691,6 +2691,8 @@ F: drivers/irqchip/irq-aspeed-i2c-ic.c
ARM/ASPEED MACHINE SUPPORT
M: Joel Stanley <joel@jms.id.au>
M: Andrew Jeffery <andrew@codeconstruct.com.au>
R: Ryan Chen <ryan_chen@aspeedtech.com>
R: Billy Tsai <billy_tsai@aspeedtech.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers)
S: Supported
@ -2896,7 +2898,7 @@ W: http://www.armlinux.org.uk/
F: arch/arm/include/asm/hardware/dec21285.h
F: arch/arm/mach-footbridge/
ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
ARM/FREESCALE IMX / MXC / LAYERSCAPE ARM ARCHITECTURE
M: Frank Li <Frank.Li@nxp.com>
M: Sascha Hauer <s.hauer@pengutronix.de>
R: Pengutronix Kernel Team <kernel@pengutronix.de>
@ -2910,22 +2912,11 @@ F: Documentation/devicetree/bindings/firmware/nxp*
F: arch/arm/boot/dts/nxp/
F: arch/arm64/boot/dts/freescale/
X: Documentation/devicetree/bindings/media/i2c/
X: arch/arm64/boot/dts/freescale/fsl-*
X: arch/arm64/boot/dts/freescale/qoriq-*
X: drivers/media/i2c/
N: imx
N: mxs
N: \bmxc[^\d]
ARM/FREESCALE LAYERSCAPE ARM ARCHITECTURE
M: Frank Li <Frank.Li@nxp.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/frank.li/linux.git
F: arch/arm/boot/dts/nxp/ls/
F: arch/arm64/boot/dts/freescale/fsl-*
F: arch/arm64/boot/dts/freescale/qoriq-*
ARM/FREESCALE VYBRID ARM ARCHITECTURE
M: Frank Li <Frank.Li@nxp.com>
M: Sascha Hauer <s.hauer@pengutronix.de>
@ -4648,7 +4639,7 @@ F: rust/helpers/cpumask.c
BITMAP API [RUST]
M: Alice Ryhl <aliceryhl@google.com>
M: Burak Emir <bqe@google.com>
M: Burak Emir <burak.emir@gmail.com>
R: Yury Norov <yury.norov@gmail.com>
S: Maintained
F: lib/find_bit_benchmark_rust.rs
@ -11752,6 +11743,7 @@ F: drivers/net/ethernet/hisilicon/hibmcge/
HISILICON NETWORK SUBSYSTEM DRIVER
M: Jian Shen <shenjian15@huawei.com>
M: Jijie Shao <shaojijie@huawei.com>
L: netdev@vger.kernel.org
S: Maintained
W: http://www.hisilicon.com
@ -17262,7 +17254,7 @@ M: Lorenzo Stoakes <ljs@kernel.org>
R: Zi Yan <ziy@nvidia.com>
R: Baolin Wang <baolin.wang@linux.alibaba.com>
R: Liam R. Howlett <liam@infradead.org>
R: Nico Pache <npache@redhat.com>
R: Nico Pache <nico.pache@linux.dev>
R: Ryan Roberts <ryan.roberts@arm.com>
R: Dev Jain <dev.jain@arm.com>
R: Barry Song <baohua@kernel.org>
@ -17855,7 +17847,7 @@ F: drivers/net/wireless/microchip/
MICROCHIP ZL3073X DRIVER
M: Ivan Vecera <ivecera@redhat.com>
M: Prathosh Satish <Prathosh.Satish@microchip.com>
M: Min Li <min.li@microchip.com>
L: netdev@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/dpll/microchip,zl30731.yaml
@ -20716,7 +20708,6 @@ F: include/linux/switchtec.h
F: include/uapi/linux/switchtec_ioctl.h
PCI DRIVER FOR MOBIVEIL PCIE IP
M: Karthikeyan Mitran <m.karthikeyan@mobiveil.co.in>
M: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
L: linux-pci@vger.kernel.org
S: Supported

View File

@ -2,7 +2,7 @@
VERSION = 7
PATCHLEVEL = 2
SUBLEVEL = 0
EXTRAVERSION = -rc5
EXTRAVERSION = -rc6
NAME = Baby Opossum Posse
# *DOCUMENTATION*
@ -700,13 +700,11 @@ filechk_makefile = { \
echo "include $(abs_srctree)/Makefile"; \
}
$(objtree)/Makefile: FORCE
PHONY += $(CURDIR)/Makefile
$(CURDIR)/Makefile: FORCE
$(call filechk,makefile)
# Prevent $(srcroot)/Makefile from inhibiting the rule to run.
PHONY += $(objtree)/Makefile
outputmakefile: $(objtree)/Makefile
outputmakefile: $(CURDIR)/Makefile
ifeq ($(KBUILD_EXTMOD),)
@if [ -f $(srctree)/.config -o \
-d $(srctree)/include/config -o \

View File

@ -141,7 +141,7 @@ axi@18000000 {
/* PCIe Controller 2 */
<0x00014000 0 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
<0x00014000 1 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
<0x00014000 1 &gic GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
<0x00014000 2 &gic GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
<0x00014000 3 &gic GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
<0x00014000 4 &gic GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,

View File

@ -26,7 +26,7 @@ memory@0 {
nvram@1c080000 {
compatible = "brcm,nvram";
reg = <0x1c080000 0x180000>;
reg = <0x1c080000 0x100000>;
et2macaddr: et2macaddr {
#nvmem-cell-cells = <1>;

View File

@ -32,6 +32,7 @@ static int npcm7xx_smp_boot_secondary(unsigned int cpu,
goto out;
}
gcr_base = of_iomap(gcr_np, 0);
of_node_put(gcr_np);
if (!gcr_base) {
pr_err("could not iomap gcr");
ret = -ENOMEM;
@ -60,6 +61,7 @@ static void __init npcm7xx_smp_prepare_cpus(unsigned int max_cpus)
return;
}
scu_base = of_iomap(scu_np, 0);
of_node_put(scu_np);
if (!scu_base) {
pr_err("could not iomap scu");
return;

View File

@ -678,8 +678,6 @@ IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 12 (GIC_CPU_MASK_SIMPLE(4) |
IRQ_TYPE_LEVEL_LOW)>;
};

View File

@ -2559,7 +2559,7 @@ mdss_dsi1_phy: phy@ae97000 {
"dsi_pll";
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
<&rpmhcc RPMH_CXO_CLK>;
<&bi_tcxo_div2>;
clock-names = "iface",
"ref";

View File

@ -1876,7 +1876,7 @@ &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
spi0: spi@b80000 {
compatible = "qcom,geni-spi";
reg = <0x0 0x00b80000 0x0 0x4000>;
interrupts = <GIC_SPI 1052 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <GIC_ESPI 92 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
clock-names = "se";
interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
@ -1903,7 +1903,7 @@ &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
i2c1: i2c@b84000 {
compatible = "qcom,geni-i2c";
reg = <0x0 0x00b84000 0x0 0x4000>;
interrupts = <GIC_SPI 1053 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <GIC_ESPI 93 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>;
clock-names = "se";
interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
@ -1930,7 +1930,7 @@ &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
spi1: spi@b84000 {
compatible = "qcom,geni-spi";
reg = <0x0 0x00b84000 0x0 0x4000>;
interrupts = <GIC_SPI 1053 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <GIC_ESPI 93 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>;
clock-names = "se";
interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
@ -1957,7 +1957,7 @@ &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
i2c2: i2c@b88000 {
compatible = "qcom,geni-i2c";
reg = <0x0 0x00b88000 0x0 0x4000>;
interrupts = <GIC_SPI 1054 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <GIC_ESPI 94 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
clock-names = "se";
interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
@ -1984,7 +1984,7 @@ &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
spi2: spi@b88000 {
compatible = "qcom,geni-spi";
reg = <0x0 0x00b88000 0x0 0x4000>;
interrupts = <GIC_SPI 1054 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <GIC_ESPI 94 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
clock-names = "se";
interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
@ -2011,7 +2011,7 @@ &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
uart2: serial@b88000 {
compatible = "qcom,geni-uart";
reg = <0x0 0x00b88000 0x0 0x4000>;
interrupts = <GIC_SPI 1054 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <GIC_ESPI 94 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
clock-names = "se";
interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
@ -2056,7 +2056,7 @@ &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
spi3: spi@b8c000 {
compatible = "qcom,geni-spi";
reg = <0x0 0x00b8c000 0x0 0x4000>;
interrupts = <GIC_SPI 1055 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <GIC_ESPI 95 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>;
clock-names = "se";
interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
@ -2110,7 +2110,7 @@ &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
spi4: spi@b90000 {
compatible = "qcom,geni-spi";
reg = <0x0 0x00b90000 0x0 0x4000>;
interrupts = <GIC_SPI 1056 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <GIC_ESPI 96 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_QUPV3_WRAP0_S4_CLK>;
clock-names = "se";
interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
@ -2164,7 +2164,7 @@ &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
spi5: spi@b94000 {
compatible = "qcom,geni-spi";
reg = <0x0 0x00b94000 0x0 0x4000>;
interrupts = <GIC_SPI 1057 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <GIC_ESPI 97 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
clock-names = "se";
interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
@ -2191,7 +2191,7 @@ &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
i2c6: i2c@b98000 {
compatible = "qcom,geni-i2c";
reg = <0x0 0x00b98000 0x0 0x4000>;
interrupts = <GIC_SPI 1058 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <GIC_ESPI 98 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_QUPV3_WRAP0_S6_CLK>;
clock-names = "se";
interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
@ -2218,7 +2218,7 @@ &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
spi6: spi@b98000 {
compatible = "qcom,geni-spi";
reg = <0x0 0x00b98000 0x0 0x4000>;
interrupts = <GIC_SPI 1058 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <GIC_ESPI 98 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_QUPV3_WRAP0_S6_CLK>;
clock-names = "se";
interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
@ -2245,7 +2245,7 @@ &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
i2c7: i2c@b9c000 {
compatible = "qcom,geni-i2c";
reg = <0x0 0x00b9c000 0x0 0x4000>;
interrupts = <GIC_SPI 1059 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <GIC_ESPI 99 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_QUPV3_WRAP0_S7_CLK>;
clock-names = "se";
interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
@ -2272,7 +2272,7 @@ &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
spi7: spi@b9c000 {
compatible = "qcom,geni-spi";
reg = <0x0 0x00b9c000 0x0 0x4000>;
interrupts = <GIC_SPI 1059 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <GIC_ESPI 99 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_QUPV3_WRAP0_S7_CLK>;
clock-names = "se";
interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
@ -6874,9 +6874,9 @@ apps_smmu: iommu@15000000 {
pcie_smmu: iommu@15480000 {
compatible = "arm,smmu-v3";
reg = <0x0 0x15480000 0x0 0x20000>;
interrupts = <GIC_SPI 964 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 962 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 960 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <GIC_ESPI 4 IRQ_TYPE_LEVEL_HIGH>,
<GIC_ESPI 2 IRQ_TYPE_LEVEL_HIGH>,
<GIC_ESPI 0 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "eventq", "cmdq-sync", "gerror";
dma-coherent;
#iommu-cells = <1>;

View File

@ -7384,6 +7384,7 @@ intc: interrupt-controller@17a00000 {
interrupt-controller;
#redistributor-regions = <1>;
redistributor-stride = <0x0 0x20000>;
#address-cells = <0>;
};
watchdog@17c10000 {

View File

@ -47,6 +47,8 @@ &gmu {
&gpu {
compatible = "qcom,adreno-43030c00", "qcom,adreno";
iommus = <&adreno_smmu 0 0x0>;
nvmem-cells = <&gpu_speed_bin>;
nvmem-cell-names = "speed_bin";

View File

@ -637,7 +637,7 @@ embedded-controller@38 {
compatible = "huawei,gaokun3-ec";
reg = <0x38>;
interrupts-extended = <&tlmm 107 IRQ_TYPE_LEVEL_LOW>;
interrupts-extended = <&tlmm 103 IRQ_TYPE_LEVEL_LOW>;
#address-cells = <1>;
#size-cells = <0>;

View File

@ -5356,7 +5356,7 @@ pdc: interrupt-controller@b220000 {
<211 699 1>,
<212 705 1>,
<213 450 1>,
<214 643 1>,
<214 643 2>,
<216 646 5>,
<221 390 5>,
<226 700 3>,
@ -5379,7 +5379,7 @@ pdc: interrupt-controller@b220000 {
<252 798 1>,
<253 765 1>,
<254 763 1>,
<255 454 1>,
<255 454 3>,
<258 139 1>,
<259 786 2>,
<261 370 2>,

View File

@ -347,6 +347,10 @@ &cdsp_pas {
status = "okay";
};
&cluster_sleep_0 {
arm,psci-suspend-param = <0x41008244>;
};
&gcc {
protected-clocks = <GCC_QSPI_CORE_CLK>,
<GCC_QSPI_CORE_CLK_SRC>,

View File

@ -7091,8 +7091,8 @@ sram@14680000 {
ranges = <0 0 0x14680000 0x2c000>;
ipa_modem_tables: modem-tables@8000 {
reg = <0x8000 0x2000>;
ipa_modem_tables: modem-tables@3000 {
reg = <0x3000 0x2000>;
};
};

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
// Copyright 2023 Google LLC
// Authors: Ard Biesheuvel <ardb@google.com>
// Peter Collingbourne <pcc@google.com>
// Peter Collingbourne <peter@pcc.me.uk>
#include <linux/elf.h>
#include <linux/init.h>

View File

@ -168,7 +168,7 @@ vdso_prepare: prepare0
endif
endif
vdso-install-y += arch/riscv/kernel/vdso/vdso.so.dbg
vdso-install-$(CONFIG_MMU) += arch/riscv/kernel/vdso/vdso.so.dbg
vdso-install-$(CONFIG_RISCV_USER_CFI) += arch/riscv/kernel/vdso_cfi/vdso-cfi.so.dbg
vdso-install-$(CONFIG_COMPAT) += arch/riscv/kernel/compat_vdso/compat_vdso.so.dbg

View File

@ -93,10 +93,8 @@ void sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
for (alt = begin; alt < end; alt++) {
if (alt->vendor_id != SIFIVE_VENDOR_ID)
continue;
if (alt->patch_id >= ERRATA_SIFIVE_NUMBER) {
WARN(1, "This errata id:%d is not in kernel errata list", alt->patch_id);
if (alt->patch_id >= ERRATA_SIFIVE_NUMBER)
continue;
}
tmp = (1U << alt->patch_id);
if (cpu_req_errata & tmp) {

View File

@ -22,13 +22,13 @@ static inline cycles_t get_cycles(void)
#else /* !CONFIG_64BIT */
static inline u32 get_cycles(void)
{
return readl_relaxed(((u32 *)clint_time_val));
return readl_relaxed(((u32 __iomem *)clint_time_val));
}
#define get_cycles get_cycles
static inline u32 get_cycles_hi(void)
{
return readl_relaxed(((u32 *)clint_time_val) + 1);
return readl_relaxed(((u32 __iomem *)clint_time_val) + 1);
}
#define get_cycles_hi get_cycles_hi
#endif /* CONFIG_64BIT */

View File

@ -289,7 +289,7 @@ static void check_vector_unaligned_access(struct work_struct *work __always_unus
}
/* Measure unaligned access speed on all CPUs present at boot in parallel. */
static int __init vec_check_unaligned_access_speed_all_cpus(void *unused __always_unused)
static int vec_check_unaligned_access_speed_all_cpus(void *unused __always_unused)
{
schedule_on_each_cpu(check_vector_unaligned_access);
riscv_hwprobe_complete_async_probe();
@ -297,7 +297,7 @@ static int __init vec_check_unaligned_access_speed_all_cpus(void *unused __alway
return 0;
}
#else /* CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS */
static int __init vec_check_unaligned_access_speed_all_cpus(void *unused __always_unused)
static int vec_check_unaligned_access_speed_all_cpus(void *unused __always_unused)
{
return 0;
}

View File

@ -63,7 +63,8 @@ EXPORT_SYMBOL(phys_ram_base);
#ifdef CONFIG_SPARSEMEM_VMEMMAP
#define VMEMMAP_ADDR_ALIGN max(1ULL << SECTION_SIZE_BITS, \
MAX_FOLIO_VMEMMAP_ALIGN)
PFN_PHYS(MAX_FOLIO_VMEMMAP_ALIGN / \
sizeof(struct page)))
unsigned long vmemmap_start_pfn __ro_after_init;
EXPORT_SYMBOL(vmemmap_start_pfn);
@ -164,7 +165,9 @@ static void print_vm_layout(void) { }
void __init arch_mm_preinit(void)
{
bool swiotlb = max_pfn > PFN_DOWN(dma32_phys_limit);
bool swiotlb = max_pfn > PFN_DOWN(dma32_phys_limit) &&
memblock_start_of_DRAM() < dma32_phys_limit;
unsigned int swiotlb_flags = SWIOTLB_VERBOSE;
#ifdef CONFIG_FLATMEM
BUG_ON(!mem_map);
#endif /* CONFIG_FLATMEM */
@ -172,17 +175,22 @@ void __init arch_mm_preinit(void)
if (IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC) && !swiotlb &&
dma_cache_alignment != 1) {
/*
* If no bouncing needed for ZONE_DMA, allocate 1MB swiotlb
* buffer per 1GB of RAM for kmalloc() bouncing on
* non-coherent platforms.
* No 32-bit DMA bouncing needed (either all DRAM is within
* the 32-bit limit, or it all starts above it), but
* kmalloc() buffers whose sizes are not cache-line-aligned
* still require bouncing for non-coherent DMA. Use
* SWIOTLB_ANY so that the buffer can be allocated from high
* memory when DRAM starts above dma32_phys_limit. Allocate
* ~1 MB per 1 GB of RAM.
*/
unsigned long size =
DIV_ROUND_UP(memblock_phys_mem_size(), 1024);
swiotlb_adjust_size(min(swiotlb_size_or_default(), size));
swiotlb = true;
swiotlb_flags |= SWIOTLB_ANY;
}
swiotlb_init(swiotlb, SWIOTLB_VERBOSE);
swiotlb_init(swiotlb, swiotlb_flags);
print_vm_layout();
}
@ -1618,7 +1626,7 @@ static void __meminit remove_pud_mapping(pud_t *pud_base, unsigned long addr, un
for (; addr < end; addr = next) {
next = pud_addr_end(addr, end);
pudp = pud_base + pud_index(addr);
pudp = pgtable_l4_enabled ? pud_base + pud_index(addr) : pud_base;
pud = pudp_get(pudp);
if (!pud_present(pud))
continue;
@ -1649,7 +1657,7 @@ static void __meminit remove_p4d_mapping(p4d_t *p4d_base, unsigned long addr, un
for (; addr < end; addr = next) {
next = p4d_addr_end(addr, end);
p4dp = p4d_base + p4d_index(addr);
p4dp = pgtable_l5_enabled ? p4d_base + p4d_index(addr) : p4d_base;
p4d = p4dp_get(p4dp);
if (!p4d_present(p4d))
continue;

View File

@ -188,6 +188,7 @@ SYSCALL_DEFINE3(s390_pci_mmio_write, unsigned long, mmio_addr,
goto out_unlock_mmap;
}
ret = -EFAULT;
io_addr = (void __iomem *)((args.pfn << PAGE_SHIFT) |
(mmio_addr & ~PAGE_MASK));

View File

@ -995,6 +995,9 @@ static int vector_mmsg_rx(struct vector_private *vp, int budget)
*/
dev_kfree_skb_irq(skb);
vp->estats.rx_encaps_errors++;
(*skbuff_vector) = NULL;
mmsg_vector++;
skbuff_vector++;
continue;
}
if (header_check > 0) {

View File

@ -32,8 +32,15 @@
int memcmp(const void *s1, const void *s2, size_t len)
{
bool diff;
asm("repe cmpsb"
: "=@ccnz" (diff), "+D" (s1), "+S" (s2), "+c" (len));
/*
* Make sure ZF is properly set in the len==0 case because in it,
* RCX==0 and the REPE; CMPSB won't get executed.
*/
asm volatile("test %3, %3\n\t"
"repe cmpsb"
: "=@ccnz" (diff), "+D" (s1), "+S" (s2), "+c" (len)
: : "cc", "memory");
return diff;
}

View File

@ -937,6 +937,8 @@ SYM_CODE_START(paranoid_entry)
IBRS_ENTER save_reg=%r15
UNTRAIN_RET_FROM_CALL
HANDLE_INTR_SAFERET 8(%rsp)
RET
SYM_CODE_END(paranoid_entry)
@ -1039,6 +1041,11 @@ SYM_CODE_START(error_entry)
movl %ecx, %eax /* zero extend */
cmpq %rax, RIP+8(%rsp)
je .Lbstep_iret
VALIDATE_UNRET_END
HANDLE_INTR_SAFERET 8(%rsp)
cmpq $.Lgs_change, RIP+8(%rsp)
jne .Lerror_entry_done_lfence
@ -1057,7 +1064,6 @@ SYM_CODE_START(error_entry)
FENCE_SWAPGS_KERNEL_ENTRY
CALL_DEPTH_ACCOUNT
leaq 8(%rsp), %rax /* return pt_regs pointer */
VALIDATE_UNRET_END
RET
.Lbstep_iret:

View File

@ -12,6 +12,7 @@
#include <asm/msr-index.h>
#include <asm/unwind_hints.h>
#include <asm/percpu.h>
#include <asm/ptrace-abi.h>
/*
* Call depth tracking for Intel SKL CPUs to address the RSB underflow
@ -176,6 +177,50 @@
add $(BITS_PER_LONG/8), %_ASM_SP; \
lfence;
/*
* Helper for detecting if an interrupt occurred at an unsafe location within
* Safe-RET. If Safe-RET is interrupted after the CALL or LEA the RSB may get
* poisoned by the interrupt handler.
*
* The Safe-RET sequence is:
*
* CALL
* LEA 8(%RSP), %RSP
* RET
*
* The two CMPs below check whether RIP points to after the CALL or after the
* LEA.
*
* The LFENCE below is to address this particular speculation case:
*
* 1. Userspace runs and poisons the BTB around the safe-RET routine
*
* 2. Userspace triggers some kind of exception
*
* 3. Kernel executes error_entry() and mis-speculates the branch into thinking
* it actually came from kernel space
*
* 4. The kernel then further mis-speculates that the exception occurred due
* to an interrupted safe-RET
*
* 5. The handle_interrupted_saferet() routine speculatively executes and
* speculatively does a safe-RET. But this is unsafe since it was never
* untrained.
*
* The LFENCE fixes this by ensuring step 5 is never reached speculatively.
* Note that this LFENCE only occurs if safe-RET was actually interrupted (so
* it's outside of the normal path).
*/
#define __HANDLE_INTR_SAFERET(name, pt_regs) \
cmpq $(name), RIP+pt_regs; \
jb 1f; \
cmpq $(name)+5, RIP+pt_regs; \
ja 1f; \
lfence; \
leaq pt_regs, %rdi; \
call handle_interrupted_saferet; \
1:
#ifdef __ASSEMBLER__
/*
@ -293,6 +338,14 @@
#define UNTRAIN_RET_FROM_CALL \
__UNTRAIN_RET X86_FEATURE_ENTRY_IBPB, __stringify(RESET_CALL_DEPTH_FROM_CALL)
.macro HANDLE_INTR_SAFERET pt_regs
#ifdef CONFIG_MITIGATION_SRSO
ALTERNATIVE_2 "", \
__stringify(__HANDLE_INTR_SAFERET(srso_safe_ret, \pt_regs)), X86_FEATURE_SRSO, \
__stringify(__HANDLE_INTR_SAFERET(srso_alias_safe_ret, \pt_regs)), X86_FEATURE_SRSO_ALIAS
#endif
.endm
.macro CALL_DEPTH_ACCOUNT
#ifdef CONFIG_MITIGATION_CALL_DEPTH_TRACKING
@ -625,6 +678,10 @@ static __always_inline void x86_idle_clear_cpu_buffers(void)
x86_clear_cpu_buffers();
}
void srso_safe_ret(void);
void srso_alias_safe_ret(void);
void handle_interrupted_saferet(struct pt_regs *regs);
#endif /* __ASSEMBLER__ */
#endif /* _ASM_X86_NOSPEC_BRANCH_H_ */

View File

@ -515,11 +515,13 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
case 0x00 ... 0x2f:
case 0x40 ... 0x4f:
case 0x60 ... 0x7f:
case 0xd0 ... 0xd7:
setup_force_cpu_cap(X86_FEATURE_ZEN5);
break;
case 0x50 ... 0x5f:
case 0x80 ... 0xaf:
case 0xc0 ... 0xef:
case 0xc0 ... 0xcf:
case 0xd8 ... 0xef:
setup_force_cpu_cap(X86_FEATURE_ZEN6);
break;
default:

View File

@ -3775,3 +3775,42 @@ void __warn_thunk(void)
{
WARN_ONCE(1, "Unpatched return thunk in use. This should not happen!\n");
}
#ifdef CONFIG_MITIGATION_SRSO
/*
* Called during exception/interrupt entry if interrupted during the
* safe-RET sequence. The safe-RET sequence consists of 3 instructions:
*
* CALL
* LEA 8(%RSP), %RSP
* RET
*
* An interrupt after the CALL or after the LEA could potentially lead
* to branch predictor poisoning and results in the sequence not being
* able to be safely resumed.
*
* Therefore, modify the regs state as if the remaining part of the
* safe-RET sequence executed so the interrupt returns back to the
* desired return target, instead of the to the safe-RET sequence.
*/
void noinstr handle_interrupted_saferet(struct pt_regs *regs)
{
unsigned long rip = regs->ip;
if (rip == (unsigned long) srso_safe_ret ||
rip == (unsigned long) srso_alias_safe_ret) {
/* Modify stack pointer as if LEA executed: */
regs->sp += 8;
}
/*
* Adjust registers as if RET executed:
*
* 1. Read the return address off the stack and into rIP:
*/
regs->ip = *(unsigned long *)(regs->sp);
/* 2. Pop rIP off the stack: */
regs->sp += 8;
}
#endif /* CONFIG_MITIGATION_SRSO */

View File

@ -207,10 +207,24 @@ __EXPORT_THUNK(srso_alias_untrain_ret)
.pushsection .text..__x86.rethunk_safe
SYM_CODE_START_NOALIGN(srso_alias_safe_ret)
/*
* Tell objtool that those are not function pointers referenced by
* __HANDLE_INTR_SAFERET(). Below too.
*/
ANNOTATE_NOENDBR
/*
* Safe-RET sequence. If you need to change it, adjust
* handle_interrupted_saferet() too.
*/
lea 8(%_ASM_SP), %_ASM_SP
UNWIND_HINT_FUNC
ANNOTATE_NOENDBR
ANNOTATE_UNRET_SAFE
ret
/* End of Safe-RET sequence */
int3
SYM_FUNC_END(srso_alias_safe_ret)
@ -245,8 +259,14 @@ SYM_CODE_START_LOCAL_NOALIGN(srso_untrain_ret)
* the stack.
*/
SYM_INNER_LABEL(srso_safe_ret, SYM_L_GLOBAL)
/*
* Safe-RET sequence. If you need to change it, adjust
* handle_interrupted_saferet() too.
*/
lea 8(%_ASM_SP), %_ASM_SP
ret
/* End of Safe-RET sequence */
int3
int3
/* end of movabs */

View File

@ -1281,14 +1281,18 @@ static void disk_release(struct device *dev)
/*
* To undo the all initialization from blk_mq_init_allocated_queue in
* case of a probe failure where add_disk is never called we have to
* call blk_mq_exit_queue here. We can't do this for the more common
* teardown case (yet) as the tagset can be gone by the time the disk
* is released once it was added.
* call blk_mq_exit_queue here, after stopping the timer and work items
* that I/O issued before add_disk may have left pending. We can't do
* this for the more common teardown case (yet) as the tagset can be
* gone by the time the disk is released once it was added.
*/
if (queue_is_mq(disk->queue) &&
test_bit(GD_OWNS_QUEUE, &disk->state) &&
!test_bit(GD_ADDED, &disk->state))
!test_bit(GD_ADDED, &disk->state)) {
blk_sync_queue(disk->queue);
blk_mq_cancel_work_sync(disk->queue);
blk_mq_exit_queue(disk->queue);
}
blkcg_exit_disk(disk);

View File

@ -786,7 +786,7 @@ static int encode_message(struct qaic_device *qdev, struct manage_msg *user_msg,
break;
}
trans_hdr = (struct qaic_manage_trans_hdr *)(user_msg->data + user_len);
if (trans_hdr->len < sizeof(trans_hdr) ||
if (trans_hdr->len < sizeof(*trans_hdr) ||
size_add(user_len, trans_hdr->len) > user_msg->len) {
ret = -EINVAL;
break;

View File

@ -475,17 +475,29 @@ bool acpi_cpc_valid(void)
}
EXPORT_SYMBOL_GPL(acpi_cpc_valid);
bool cppc_allow_fast_switch(void)
bool cppc_allow_fast_switch(const struct cpumask *cpus)
{
struct cpc_register_resource *desired_reg;
struct cpc_register_resource *desired_reg, *min_reg, *max_reg;
struct cpc_desc *cpc_ptr;
int cpu;
for_each_online_cpu(cpu) {
for_each_cpu(cpu, cpus) {
cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
if (!cpc_ptr)
return false;
desired_reg = &cpc_ptr->cpc_regs[DESIRED_PERF];
if (!CPC_IN_SYSTEM_MEMORY(desired_reg) &&
!CPC_IN_SYSTEM_IO(desired_reg))
min_reg = &cpc_ptr->cpc_regs[MIN_PERF];
max_reg = &cpc_ptr->cpc_regs[MAX_PERF];
if (!CPC_SUPPORTED(desired_reg) ||
(!CPC_IN_SYSTEM_MEMORY(desired_reg) &&
!CPC_IN_SYSTEM_IO(desired_reg)) ||
(CPC_SUPPORTED(min_reg) &&
!CPC_IN_SYSTEM_MEMORY(min_reg) &&
!CPC_IN_SYSTEM_IO(min_reg)) ||
(CPC_SUPPORTED(max_reg) &&
!CPC_IN_SYSTEM_MEMORY(max_reg) &&
!CPC_IN_SYSTEM_IO(max_reg)))
return false;
}
@ -1951,16 +1963,17 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
cpc_desc->write_cmd_status = 0;
}
cpc_write(cpu, desired_reg, perf_ctrls->desired_perf);
if (CPC_SUPPORTED(desired_reg))
cpc_write(cpu, desired_reg, perf_ctrls->desired_perf);
/*
* Only write if min_perf and max_perf not zero. Some drivers pass zero
* value to min and max perf, but they don't mean to set the zero value,
* they just don't want to write to those registers.
*/
if (perf_ctrls->min_perf)
if (perf_ctrls->min_perf && CPC_SUPPORTED(min_perf_reg))
cpc_write(cpu, min_perf_reg, perf_ctrls->min_perf);
if (perf_ctrls->max_perf)
if (perf_ctrls->max_perf && CPC_SUPPORTED(max_perf_reg))
cpc_write(cpu, max_perf_reg, perf_ctrls->max_perf);
if (CPC_IN_PCC(desired_reg) || CPC_IN_PCC(min_perf_reg) || CPC_IN_PCC(max_perf_reg))

View File

@ -211,7 +211,7 @@ static int ceva_ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
rc = phy_init(hpriv->phys[i]);
if (rc)
goto disable_rsts;
goto exit_phys;
}
/* De-assert the controller reset */
@ -230,14 +230,24 @@ static int ceva_ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
return 0;
disable_rsts:
ahci_platform_deassert_rsts(hpriv);
disable_phys:
while (--i >= 0) {
if (ahci_ignore_port(hpriv, i))
continue;
phy_power_off(hpriv->phys[i]);
phy_exit(hpriv->phys[i]);
}
ahci_platform_assert_rsts(hpriv);
goto disable_clks;
exit_phys:
while (--i >= 0) {
if (ahci_ignore_port(hpriv, i))
continue;
phy_exit(hpriv->phys[i]);
}
disable_clks:
ahci_platform_disable_clks(hpriv);

View File

@ -4413,6 +4413,15 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = {
{ "WDC WD3000JD-*", NULL, ATA_QUIRK_WD_BROKEN_LPM },
{ "WDC WD3200JD-*", NULL, ATA_QUIRK_WD_BROKEN_LPM },
/*
* WD drives with LPM issues (irrespective of supported SATA speeds).
* (Unlike ATA_QUIRK_WD_BROKEN_LPM, which is only applied if the drive
* exposes SATA Gen1 speed support, and SATA Gen1 speed support only.)
*/
{ "WDC WD100EFGX-68CPLN0", NULL, ATA_QUIRK_NOLPM },
{ "WDC WD102KFBX-68M95N0", NULL, ATA_QUIRK_NOLPM },
{ "WD Green 2.5 480GB", NULL, ATA_QUIRK_NOLPM },
/*
* This sata dom device goes on a walkabout when the ATA_LOG_DIRECTORY
* log page is accessed. Ensure we never ask for this log page with

View File

@ -106,6 +106,12 @@ static const unsigned int ata_eh_flush_timeouts[] = {
UINT_MAX,
};
static const unsigned int ata_eh_standby_timeouts[] = {
15000, /* Some drives may be slow to standby */
/* but don't hold up a suspend too long waiting for them */
UINT_MAX,
};
static const unsigned int ata_eh_other_timeouts[] = {
5000, /* same rationale as identify timeout */
10000, /* ditto */
@ -147,6 +153,8 @@ ata_eh_cmd_timeout_table[ATA_EH_CMD_TIMEOUT_TABLE_SIZE] = {
.timeouts = ata_eh_other_timeouts, },
{ .commands = CMDS(ATA_CMD_FLUSH, ATA_CMD_FLUSH_EXT),
.timeouts = ata_eh_flush_timeouts },
{ .commands = CMDS(ATA_CMD_STANDBYNOW1),
.timeouts = ata_eh_standby_timeouts },
{ .commands = CMDS(ATA_CMD_VERIFY),
.timeouts = ata_eh_reset_timeouts },
};
@ -650,29 +658,12 @@ int ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
set_host_byte(scmd, DID_OK);
ata_qc_for_each_raw(ap, qc, i) {
if (qc->scsicmd != scmd)
continue;
if ((qc->flags & ATA_QCFLAG_ACTIVE) ||
qc == qc->dev->link->deferred_qc)
if (qc->scsicmd == scmd &&
qc->flags & ATA_QCFLAG_ACTIVE)
break;
}
if (i < ATA_MAX_QUEUE && qc == qc->dev->link->deferred_qc) {
/*
* This is a deferred command that timed out while
* waiting for the command queue to drain. Since the qc
* is not active yet (deferred_qc is still set, so the
* deferred qc work has not issued the command yet),
* simply signal the timeout by finishing the SCSI
* command and clear the deferred qc to prevent the
* deferred qc work from issuing this qc.
*/
WARN_ON_ONCE(qc->flags & ATA_QCFLAG_ACTIVE);
qc->dev->link->deferred_qc = NULL;
cancel_work(&qc->dev->link->deferred_qc_work);
set_host_byte(scmd, DID_TIME_OUT);
scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
} else if (i < ATA_MAX_QUEUE) {
if (i < ATA_MAX_QUEUE) {
/* the scmd has an associated qc */
if (!(qc->flags & ATA_QCFLAG_EH)) {
/* which hasn't failed yet, timeout */
@ -948,10 +939,10 @@ static void ata_eh_set_pending(struct ata_port *ap, bool fastdrain)
ap->pflags |= ATA_PFLAG_EH_PENDING;
/*
* If we have a deferred qc, requeue it so that it is retried once EH
* completes.
* If we have deferred QCs, requeue them so that the SCSI EH task can
* run.
*/
ata_scsi_requeue_deferred_qc(ap);
ata_scsi_requeue_deferred_qc(ap, NULL);
if (!fastdrain)
return;

View File

@ -913,7 +913,7 @@ static bool ata_scsi_lpm_supported(struct ata_port *ap)
return false;
ata_for_each_link(link, ap, EDGE) {
ata_for_each_dev(dev, &ap->link, ENABLED) {
ata_for_each_dev(dev, link, ENABLED) {
if (dev->quirks & ATA_QUIRK_NOLPM)
return false;
}

View File

@ -1685,26 +1685,80 @@ void ata_scsi_deferred_qc_work(struct work_struct *work)
spin_unlock_irqrestore(ap->lock, flags);
}
void ata_scsi_requeue_deferred_qc(struct ata_port *ap)
enum scsi_timeout_action ata_scsi_requeue_deferred_qc(struct ata_port *ap,
struct scsi_cmnd *timedout_scmd)
{
enum scsi_timeout_action action = SCSI_EH_NOT_HANDLED;
struct ata_queued_cmd *qc;
struct ata_link *link;
u32 host_byte;
lockdep_assert_held(ap->lock);
/*
* If we have a deferred qc when a reset occurs or NCQ commands fail,
* do not try to be smart about what to do with this deferred command
* and simply requeue it by completing it with DID_REQUEUE.
* If we have deferred QCs when a reset, a timeout or an NCQ command
* fails, do not try to be smart about what to do with the deferred
* commands and simply terminate them and let the SCSI layer decide
* what to do.
*/
ata_for_each_link(link, ap, PMP_FIRST) {
struct ata_queued_cmd *qc = link->deferred_qc;
qc = link->deferred_qc;
if (!qc)
continue;
if (qc) {
link->deferred_qc = NULL;
cancel_work(&link->deferred_qc_work);
ata_scsi_qc_done(qc, true, DID_REQUEUE << 16);
/*
* Clear the deferred QC so that the deferred work does not try
* to issue it.
*/
link->deferred_qc = NULL;
cancel_work(&link->deferred_qc_work);
/*
* We are going to complete some scsi command, either with
* DID_TIME_OUT if the command timed out while waiting for being
* issued, or with DID_REQUEUE if another command timed out or
* we had a failed command. However, the block layer may re-issue
* these commands immediately, keeping the scsi host busy and
* thus preventing the SCSI EH task from running.
* So schedule EH on the port to prevent accepting new commands
* until everything is sorted out with the error or timeout that
* got us here in the first place. Note that we set EH pending
* on the port before calling ata_port_schedule_eh() so that we
* do not reenter this function from ata_eh_set_pending() with
* timedout_scmd being NULL and erroneously retry deferred QCs
* that have timed out on other links.
*/
if (!ata_port_eh_scheduled(ap)) {
ap->pflags |= ATA_PFLAG_EH_PENDING;
ata_port_schedule_eh(ap);
}
/*
* If we are being called from scsi_timeout(), then we have a
* non-NULL timedout_scmd. If the timed out command is for a
* deferred QC, terminate that deferred QC with DID_TIME_OUT and
* requeue all other deferred QCs. In this case we need to
* return SCSI_EH_DONE, because the timed out command was
* handled.
* If the timed out command is not for a deferred QC, we need to
* requeue all deferred QCs, and return SCSI_EH_NOT_HANDLED so
* that the timed out command gets added to the EH work queue
* with scsi_eh_scmd_add(), for later handling with libata EH
* ata_scsi_cmd_error_handler().
* If timedout_scmd is NULL, we simply need to requeue all
* deferred QCs and the return value does not matter as we were
* not called from scsi_timeout().
*/
if (timedout_scmd && qc->scsicmd == timedout_scmd) {
host_byte = DID_TIME_OUT;
action = SCSI_EH_DONE;
} else {
host_byte = DID_REQUEUE;
}
ata_scsi_qc_done(qc, true, host_byte << 16);
}
return action;
}
static void ata_scsi_schedule_deferred_qc(struct ata_link *link)
@ -1723,13 +1777,42 @@ static void ata_scsi_schedule_deferred_qc(struct ata_link *link)
return;
if (ata_port_eh_scheduled(ap)) {
ata_scsi_requeue_deferred_qc(ap);
ata_scsi_requeue_deferred_qc(ap, NULL);
return;
}
if (!ap->ops->qc_defer(qc))
queue_work(system_highpri_wq, &link->deferred_qc_work);
}
enum scsi_timeout_action ata_scsi_retry_deferred_qc(struct ata_port *ap,
struct scsi_cmnd *scmd)
{
enum scsi_timeout_action action;
unsigned long flags;
spin_lock_irqsave(ap->lock, flags);
action = ata_scsi_requeue_deferred_qc(ap, scmd);
spin_unlock_irqrestore(ap->lock, flags);
return action;
}
EXPORT_SYMBOL_GPL(ata_scsi_retry_deferred_qc);
enum scsi_timeout_action ata_scsi_eh_timed_out(struct scsi_cmnd *scmd)
{
struct ata_port *ap = ata_shost_to_port(scmd->device->host);
/*
* ata_scsi_cmd_error_handler() takes care of commands that timed out
* while executing. However, if we have deferred QCs while a timeout
* triggers, we must requeue these commands for retry so that we do not
* unnecessarily delay starting the SCSI EH task until these deferred
* commands also time out.
*/
return ata_scsi_retry_deferred_qc(ap, scmd);
}
EXPORT_SYMBOL_GPL(ata_scsi_eh_timed_out);
static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
{
struct ata_link *link = qc->dev->link;
@ -2911,6 +2994,7 @@ static void atapi_fixup_inquiry(struct scsi_cmnd *cmd)
static void atapi_qc_complete(struct ata_queued_cmd *qc)
{
struct ata_link *link = qc->dev->link;
struct scsi_cmnd *cmd = qc->scsicmd;
unsigned int err_mask = qc->err_mask;
@ -2936,8 +3020,16 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL && qc->dev->sdev)
qc->dev->sdev->locked = 0;
ata_scsi_qc_done(qc, true, SAM_STAT_CHECK_CONDITION);
return;
if (cmd->result)
ata_scsi_qc_done(qc, false, 0);
else
ata_scsi_qc_done(qc, true, SAM_STAT_CHECK_CONDITION);
goto schedule_deferred;
}
if (cmd->result) {
ata_scsi_qc_done(qc, false, 0);
goto schedule_deferred;
}
/* successful completion path */
@ -2945,6 +3037,9 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
atapi_fixup_inquiry(cmd);
ata_scsi_qc_done(qc, true, SAM_STAT_GOOD);
schedule_deferred:
ata_scsi_schedule_deferred_qc(link);
}
/**
* atapi_xlat - Initialize PACKET taskfile

View File

@ -180,7 +180,8 @@ enum scsi_qc_status __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
struct ata_port *ap)
__must_hold(ap->lock);
void ata_scsi_deferred_qc_work(struct work_struct *work);
void ata_scsi_requeue_deferred_qc(struct ata_port *ap);
enum scsi_timeout_action ata_scsi_requeue_deferred_qc(struct ata_port *ap,
struct scsi_cmnd *scmd);
/* libata-eh.c */
extern unsigned int ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd);

View File

@ -4027,7 +4027,7 @@ static int mv_platform_probe(struct platform_device *pdev)
/*
* Simple resource validation ..
*/
if (unlikely(pdev->num_resources != 1)) {
if (unlikely(pdev->num_resources != 1 && pdev->num_resources != 2)) {
dev_err(&pdev->dev, "invalid number of resources\n");
return -EINVAL;
}

View File

@ -4764,6 +4764,15 @@ static int ublk_ctrl_add_dev(const struct ublksrv_ctrl_cmd *header)
/* update device id */
ub->dev_info.dev_id = ub->ub_number;
/*
* ->state and ->ublksrv_pid are owned by the driver and only read back
* by userspace, but they come from the copied-in dev_info, so reset
* them. Otherwise a device added with ->state != DEAD looks live while
* ->ub_disk is still NULL.
*/
ub->dev_info.state = UBLK_S_DEV_DEAD;
ub->dev_info.ublksrv_pid = -1;
/*
* 64bit flags will be copied back to userspace as feature
* negotiation result, so have to clear flags which driver

View File

@ -1031,7 +1031,7 @@ static int amd_pstate_init_freq(struct amd_cpudata *cpudata)
return -EINVAL;
}
if (lowest_nonlinear_freq <= min_freq || lowest_nonlinear_freq > nominal_freq) {
if (lowest_nonlinear_freq < min_freq || lowest_nonlinear_freq > nominal_freq) {
pr_err("lowest_nonlinear_freq(%d) value is out of range [min_freq(%d), nominal_freq(%d)]\n",
lowest_nonlinear_freq, min_freq, nominal_freq);
return -EINVAL;
@ -2167,6 +2167,7 @@ static struct cpufreq_driver amd_pstate_epp_driver = {
};
/*
* Processors without frequency scaling support can't do CPPC.
* CPPC function is not supported for family ID 17H with model_ID ranging from 0x10 to 0x2F.
* show the debug message that helps to check if the CPU has CPPC support for loading issue.
*/
@ -2175,6 +2176,11 @@ static bool amd_cppc_supported(void)
struct cpuinfo_x86 *c = &cpu_data(0);
bool warn = false;
if (!cpu_feature_enabled(X86_FEATURE_HW_PSTATE)) {
pr_debug_once("frequency scaling is not supported by the processor\n");
return false;
}
if ((boot_cpu_data.x86 == 0x17) && (boot_cpu_data.x86_model < 0x30)) {
pr_debug_once("CPPC feature is not supported by the processor\n");
return false;

View File

@ -290,19 +290,32 @@ static inline void cppc_freq_invariance_exit(void)
}
#endif /* CONFIG_ACPI_CPPC_CPUFREQ_FIE */
static void cppc_cpufreq_get_perf_limits(struct cppc_cpudata *cpu_data,
struct cpufreq_policy *policy,
u32 *min_perf, u32 *max_perf)
{
struct cppc_perf_caps *caps = &cpu_data->perf_caps;
unsigned int min_freq, max_freq;
u32 min, max;
min_freq = READ_ONCE(policy->min);
max_freq = READ_ONCE(policy->max);
if (unlikely(min_freq > max_freq))
min_freq = max_freq;
min = cppc_khz_to_perf(caps, min_freq);
max = cppc_khz_to_perf(caps, max_freq);
*min_perf = clamp_t(u32, min, caps->lowest_perf, caps->highest_perf);
*max_perf = clamp_t(u32, max, caps->lowest_perf, caps->highest_perf);
}
static void cppc_cpufreq_update_perf_limits(struct cppc_cpudata *cpu_data,
struct cpufreq_policy *policy)
{
struct cppc_perf_caps *caps = &cpu_data->perf_caps;
u32 min_perf, max_perf;
min_perf = cppc_khz_to_perf(caps, policy->min);
max_perf = cppc_khz_to_perf(caps, policy->max);
cpu_data->perf_ctrls.min_perf =
clamp_t(u32, min_perf, caps->lowest_perf, caps->highest_perf);
cpu_data->perf_ctrls.max_perf =
clamp_t(u32, max_perf, caps->lowest_perf, caps->highest_perf);
cppc_cpufreq_get_perf_limits(cpu_data, policy,
&cpu_data->perf_ctrls.min_perf,
&cpu_data->perf_ctrls.max_perf);
}
static int cppc_cpufreq_set_target(struct cpufreq_policy *policy,
@ -693,7 +706,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
goto out;
}
policy->fast_switch_possible = cppc_allow_fast_switch();
policy->fast_switch_possible = cppc_allow_fast_switch(policy->cpus);
policy->dvfs_possible_from_any_cpu = true;
/*

View File

@ -1084,6 +1084,7 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol)
err_out_exit_acpi:
powernow_k8_cpu_exit_acpi(data);
kfree(data->powernow_table);
err_out:
kfree(data);

View File

@ -138,6 +138,7 @@ struct dibs_dev *dibs_dev_alloc(void)
dibs = kzalloc_obj(*dibs);
if (!dibs)
return dibs;
spin_lock_init(&dibs->lock);
dibs->dev.release = dibs_dev_release;
dibs->dev.class = &dibs_class;
device_initialize(&dibs->dev);
@ -186,7 +187,6 @@ int dibs_dev_add(struct dibs_dev *dibs)
int i, ret;
max_dmbs = dibs->ops->max_dmbs();
spin_lock_init(&dibs->lock);
dibs->dmb_clientid_arr = kzalloc(max_dmbs, GFP_KERNEL);
if (!dibs->dmb_clientid_arr)
return -ENOMEM;

View File

@ -288,6 +288,7 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp)
fdev->parent = cdev_dev(idxd_cdev);
fdev->bus = &dsa_bus_type;
fdev->type = &idxd_cdev_file_type;
idxd_wq_get(wq);
rc = dev_set_name(fdev, "file%d", ctx->id);
if (rc < 0) {
@ -301,13 +302,14 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp)
goto failed_dev_add;
}
idxd_wq_get(wq);
mutex_unlock(&wq->wq_lock);
return 0;
failed_dev_add:
failed_dev_name:
mutex_unlock(&wq->wq_lock);
put_device(fdev);
return rc;
failed_ida:
failed_set_pasid:
if (device_user_pasid_enabled(idxd))

View File

@ -159,18 +159,12 @@ static void idxd_cleanup_interrupts(struct idxd_device *idxd)
static void idxd_clean_wqs(struct idxd_device *idxd)
{
struct idxd_wq *wq;
struct device *conf_dev;
int i;
for (i = 0; i < idxd->max_wqs; i++) {
wq = idxd->wqs[i];
if (idxd->hw.wq_cap.op_config)
bitmap_free(wq->opcap_bmap);
kfree(wq->wqcfg);
conf_dev = wq_confdev(wq);
conf_dev = wq_confdev(idxd->wqs[i]);
put_device(conf_dev);
kfree(wq);
}
bitmap_free(idxd->wq_enable_map);
kfree(idxd->wqs);
@ -212,7 +206,6 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
rc = dev_set_name(conf_dev, "wq%d.%d", idxd->id, wq->id);
if (rc < 0) {
put_device(conf_dev);
kfree(wq);
goto err_unwind;
}
@ -227,7 +220,6 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev));
if (!wq->wqcfg) {
put_device(conf_dev);
kfree(wq);
rc = -ENOMEM;
goto err_unwind;
}
@ -235,9 +227,7 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
if (idxd->hw.wq_cap.op_config) {
wq->opcap_bmap = bitmap_zalloc(IDXD_MAX_OPCAP_BITS, GFP_KERNEL);
if (!wq->opcap_bmap) {
kfree(wq->wqcfg);
put_device(conf_dev);
kfree(wq);
rc = -ENOMEM;
goto err_unwind;
}
@ -252,13 +242,8 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
err_unwind:
while (--i >= 0) {
wq = idxd->wqs[i];
if (idxd->hw.wq_cap.op_config)
bitmap_free(wq->opcap_bmap);
kfree(wq->wqcfg);
conf_dev = wq_confdev(wq);
conf_dev = wq_confdev(idxd->wqs[i]);
put_device(conf_dev);
kfree(wq);
}
bitmap_free(idxd->wq_enable_map);
@ -270,15 +255,12 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
static void idxd_clean_engines(struct idxd_device *idxd)
{
struct idxd_engine *engine;
struct device *conf_dev;
int i;
for (i = 0; i < idxd->max_engines; i++) {
engine = idxd->engines[i];
conf_dev = engine_confdev(engine);
conf_dev = engine_confdev(idxd->engines[i]);
put_device(conf_dev);
kfree(engine);
}
kfree(idxd->engines);
}
@ -313,7 +295,6 @@ static int idxd_setup_engines(struct idxd_device *idxd)
rc = dev_set_name(conf_dev, "engine%d.%d", idxd->id, engine->id);
if (rc < 0) {
put_device(conf_dev);
kfree(engine);
goto err;
}
@ -324,10 +305,8 @@ static int idxd_setup_engines(struct idxd_device *idxd)
err:
while (--i >= 0) {
engine = idxd->engines[i];
conf_dev = engine_confdev(engine);
conf_dev = engine_confdev(idxd->engines[i]);
put_device(conf_dev);
kfree(engine);
}
kfree(idxd->engines);
@ -336,13 +315,10 @@ static int idxd_setup_engines(struct idxd_device *idxd)
static void idxd_clean_groups(struct idxd_device *idxd)
{
struct idxd_group *group;
int i;
for (i = 0; i < idxd->max_groups; i++) {
group = idxd->groups[i];
put_device(group_confdev(group));
kfree(group);
put_device(group_confdev(idxd->groups[i]));
}
kfree(idxd->groups);
}
@ -377,7 +353,6 @@ static int idxd_setup_groups(struct idxd_device *idxd)
rc = dev_set_name(conf_dev, "group%d.%d", idxd->id, group->id);
if (rc < 0) {
put_device(conf_dev);
kfree(group);
goto err;
}
@ -402,7 +377,6 @@ static int idxd_setup_groups(struct idxd_device *idxd)
while (--i >= 0) {
group = idxd->groups[i];
put_device(group_confdev(group));
kfree(group);
}
kfree(idxd->groups);

View File

@ -945,16 +945,13 @@ static int sun6i_dma_terminate_all(struct dma_chan *chan)
spin_lock_irqsave(&vchan->vc.lock, flags);
if (vchan->cyclic) {
vchan->cyclic = false;
if (pchan && pchan->desc) {
struct virt_dma_desc *vd = &pchan->desc->vd;
struct virt_dma_chan *vc = &vchan->vc;
if (pchan && pchan->desc && pchan->desc != pchan->done) {
struct virt_dma_desc *vd = &pchan->desc->vd;
list_add_tail(&vd->node, &vc->desc_completed);
}
vchan_terminate_vdesc(vd);
}
vchan->cyclic = false;
vchan_get_all_descriptors(&vchan->vc, &head);
if (pchan) {

View File

@ -1099,7 +1099,7 @@ static int switchtec_dma_chan_init(struct switchtec_dma_dev *swdma_dev,
dev_dbg(&pdev->dev, "Channel %d: SE buffer count %d\n", i, se_buf_len);
thresh = se_buf_len / 2;
valid_en_se |= FIELD_GET(SE_THRESH_MASK, thresh);
valid_en_se |= FIELD_PREP(SE_THRESH_MASK, thresh);
writel(valid_en_se, &swdma_chan->mmio_chan_fw->valid_en_se);
/* request irqs */

View File

@ -92,7 +92,7 @@ struct amdgpu_amdkfd_fence *to_amdgpu_amdkfd_fence(struct dma_fence *f)
return NULL;
fence = container_of(f, struct amdgpu_amdkfd_fence, base);
if (f->ops == &amdkfd_fence_ops)
if (rcu_access_pointer(f->ops) == &amdkfd_fence_ops)
return fence;
return NULL;

View File

@ -3096,7 +3096,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence __rcu *
process_info->eviction_fence = new_fence;
replace_eviction_fence(ef, dma_fence_get(&new_fence->base));
} else {
WARN_ONCE(*ef != &process_info->eviction_fence->base,
WARN_ONCE(rcu_access_pointer(*ef) != &process_info->eviction_fence->base,
"KFD eviction fence doesn't match KGD process_info");
}

View File

@ -1177,19 +1177,6 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
job->vm_pd_addr = amdgpu_gmc_pd_addr(vm->root.bo);
}
if (adev->debug_vm) {
/* Invalidate all BOs to test for userspace bugs */
amdgpu_bo_list_for_each_entry(e, p->bo_list) {
struct amdgpu_bo *bo = e->bo;
/* ignore duplicates */
if (!bo)
continue;
amdgpu_vm_bo_invalidate(bo, false);
}
}
return 0;
}
@ -1378,6 +1365,8 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
/* Cleanup the parser structure */
static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser)
{
struct amdgpu_device *adev = parser->adev;
struct amdgpu_bo_list_entry *e;
unsigned int i;
amdgpu_sync_free(&parser->sync);
@ -1393,8 +1382,21 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser)
if (parser->ctx)
amdgpu_ctx_put(parser->ctx);
if (parser->bo_list)
if (parser->bo_list) {
if (adev->debug_vm) {
/* Invalidate all BOs to test for userspace bugs */
amdgpu_bo_list_for_each_entry(e, parser->bo_list) {
struct amdgpu_bo *bo = e->bo;
/* ignore duplicates */
if (!bo)
continue;
amdgpu_vm_bo_invalidate(bo, false);
}
}
amdgpu_bo_list_put(parser->bo_list);
}
for (i = 0; i < parser->nchunks; i++)
kvfree(parser->chunks[i].kdata);

View File

@ -43,6 +43,11 @@
#if defined(CONFIG_DEBUG_FS)
/* Encode milliwatts in the raw Q24.8 sensor report format used by UMR. */
#define AMDGPU_DEBUGFS_PWR_MW_TO_Q24_8(power_mw) \
DIV_ROUND_CLOSEST_ULL((u64)(power_mw) * BIT(8), \
MILLIWATT_PER_WATT)
/**
* amdgpu_debugfs_process_reg_op - Handle MMIO register reads/writes
*
@ -1104,6 +1109,10 @@ static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,
return r;
}
if (idx == AMDGPU_PP_SENSOR_GPU_AVG_POWER ||
idx == AMDGPU_PP_SENSOR_GPU_INPUT_POWER)
values[0] = AMDGPU_DEBUGFS_PWR_MW_TO_Q24_8(values[0]);
if (size > valuesize) {
amdgpu_virt_disable_access_debugfs(adev);
return -EINVAL;
@ -1319,8 +1328,8 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,
* @size: Number of bytes to read
* @pos: Offset to seek to
*
* Read the last residency value logged. It doesn't auto update, one needs to
* stop logging before getting the current value.
* Read a live GFXOFF residency sample from firmware. One needs to start logging
* before getting the current value.
*/
static ssize_t amdgpu_debugfs_gfxoff_residency_read(struct file *f, char __user *buf,
size_t size, loff_t *pos)

View File

@ -2304,6 +2304,7 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
amdgpu_device_ip_block_add(adev, &psp_v14_0_ip_block);
break;
case IP_VERSION(15, 0, 0):
case IP_VERSION(15, 0, 5):
case IP_VERSION(15, 0, 9):
amdgpu_device_ip_block_add(adev, &psp_v15_0_ip_block);
break;

View File

@ -2908,6 +2908,19 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev)
return 0;
}
static void amdgpu_restore_umd_profile_pstate_after_runpm(struct amdgpu_device *adev)
{
enum amd_dpm_forced_level level;
uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK |
AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
level = amdgpu_dpm_get_performance_level(adev);
if (level & profile_mode_mask)
amdgpu_asic_update_umd_stable_pstate(adev, true);
}
static int amdgpu_pmops_runtime_resume(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
@ -2952,6 +2965,8 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)
if (adev->pm.rpm_mode == AMDGPU_RUNPM_PX)
drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
amdgpu_restore_umd_profile_pstate_after_runpm(adev);
adev->in_runpm = false;
return 0;
}

View File

@ -1210,7 +1210,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
return -EINVAL;
}
}
ui32 >>= 8;
ui32 /= MILLIWATT_PER_WATT;
break;
case AMDGPU_INFO_SENSOR_GPU_INPUT_POWER:
/* get input GPU power */
@ -1219,7 +1219,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
(void *)&ui32, &ui32_size)) {
return -EINVAL;
}
ui32 >>= 8;
ui32 /= MILLIWATT_PER_WATT;
break;
case AMDGPU_INFO_SENSOR_VDDNB:
/* get VDDNB in millivolts */

View File

@ -275,6 +275,7 @@ static int psp_early_init(struct amdgpu_ip_block *ip_block)
psp->boot_time_tmr = false;
break;
case IP_VERSION(15, 0, 0):
case IP_VERSION(15, 0, 5):
case IP_VERSION(15, 0, 9):
psp_v15_0_0_set_psp_funcs(psp);
psp->boot_time_tmr = false;
@ -1222,6 +1223,33 @@ int psp_memory_partition(struct psp_context *psp, int mode)
return ret;
}
int psp_set_mmhub_eco_sec_level(struct amdgpu_device *adev)
{
int ret;
struct psp_context *psp = &adev->psp;
struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
cmd->cmd_id = GFX_CMD_ID_SET_MMHUB_ECO_SEC_LEVEL;
ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
if (ret) {
dev_err(psp->adev->dev,
"PSP request failed to set mmuhub eco sec level with ret=%d\n", ret);
release_psp_cmd_buf(psp);
return ret;
}
if (cmd->resp.status) {
dev_err(psp->adev->dev,
"MMHUB ECO SEC LEVEL command 0x%x failed, PSP response status: 0x%X\n",
cmd->cmd_id, cmd->resp.status);
ret = -EIO;
}
release_psp_cmd_buf(psp);
return ret;
}
static int psp_ptl_fmt_verify(struct psp_context *psp, enum amdgpu_ptl_fmt fmt,
uint32_t *ptl_fmt)
{
@ -3476,8 +3504,10 @@ static int psp_load_non_psp_fw(struct psp_context *psp)
amdgpu_ip_version(adev, MP0_HWIP, 0) ==
IP_VERSION(15, 0, 0) ||
amdgpu_ip_version(adev, MP0_HWIP, 0) ==
IP_VERSION(15, 0, 8) ||
IP_VERSION(15, 0, 5) ||
amdgpu_ip_version(adev, MP0_HWIP, 0) ==
IP_VERSION(15, 0, 8) ||
amdgpu_ip_version(adev, MP0_HWIP, 0) ==
IP_VERSION(15, 0, 9)) &&
(ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1 ||
ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2 ||

View File

@ -656,5 +656,6 @@ int amdgpu_psp_reg_program_no_ring(struct psp_context *psp, uint32_t val,
void amdgpu_psp_debugfs_init(struct amdgpu_device *adev);
int amdgpu_psp_get_fw_type(struct amdgpu_firmware_info *ucode,
enum psp_gfx_fw_type *type);
int psp_set_mmhub_eco_sec_level(struct amdgpu_device *adev);
#endif

View File

@ -2173,6 +2173,18 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
gtt_size = configured_size;
}
/* Cap GTT so that it does not exceed total physical RAM. */
if (adev->flags & AMD_IS_APU) {
u64 phys_ram = (u64)totalram_pages() << PAGE_SHIFT;
if (gtt_size > phys_ram) {
gtt_size = phys_ram;
dev_info(adev->dev,
"Capping GTT to %uM to not exceed available system memory\n",
(unsigned int)(gtt_size / (1024 * 1024)));
}
}
/* Initialize GTT memory pool */
r = amdgpu_gtt_mgr_init(adev, gtt_size);
if (r) {

View File

@ -965,6 +965,7 @@ amdgpu_userq_vm_validate(struct amdgpu_userq_mgr *uq_mgr)
struct amdgpu_vm *vm = &fpriv->vm;
unsigned long key, tmp_key;
struct amdgpu_bo_va *bo_va;
struct amdgpu_usermode_queue *queue;
struct amdgpu_bo *bo;
struct drm_exec exec;
struct xarray xa;
@ -1080,6 +1081,24 @@ amdgpu_userq_vm_validate(struct amdgpu_userq_mgr *uq_mgr)
dma_fence_wait(bo_va->last_pt_update, false);
dma_fence_wait(vm->last_update, false);
xa_for_each(&uq_mgr->userq_xa, tmp_key, queue) {
bo = queue->wptr_obj.obj;
if (!bo) {
ret = -EINVAL;
goto unlock_all;
}
ret = amdgpu_ttm_alloc_gart(&bo->tbo);
if (unlikely(ret)) {
drm_file_err(uq_mgr->file,
"failed to bind wptr bo to gart on resume, qid=%lu ret=%d\n",
tmp_key, ret);
goto unlock_all;
}
queue->wptr_obj.gpu_addr = amdgpu_bo_gpu_offset(bo);
}
ret = amdgpu_evf_mgr_rearm(&fpriv->evf_mgr, &exec);
if (ret)
drm_file_err(uq_mgr->file, "Failed to replace eviction fence\n");

View File

@ -1553,6 +1553,8 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
struct amdgpu_sync sync;
int r;
if (list_empty(&vm->freed))
return 0;
/*
* Implicitly sync to command submissions in the same VM before

View File

@ -379,7 +379,7 @@ struct amd_sriov_msg_vf2pf_info {
struct {
uint8_t id;
uint32_t version;
} ucode_info[AMD_SRIOV_MSG_RESERVE_UCODE];
} __packed ucode_info[AMD_SRIOV_MSG_RESERVE_UCODE];
uint64_t dummy_page_addr;
/* FB allocated for guest MES to record UQ info */
uint64_t mes_info_addr;

View File

@ -398,6 +398,25 @@ static void jpeg_v5_3_0_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
}
/**
* jpeg_v5_3_0_set_mmhub_eco_sec_level - set jpeg sec lvl reg
*
* @adev: amdgpu_device pointer
*
* request psp to set secure lvl
*/
static int jpeg_v5_3_0_set_mmhub_eco_sec_level(struct amdgpu_device *adev)
{
int r = 0;
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
/* Request to PSP to program JPEG secure lvl */
r = psp_set_mmhub_eco_sec_level(adev);
}
return r;
}
/**
* jpeg_v5_3_0_start - start JPEG block
*
@ -423,6 +442,11 @@ static int jpeg_v5_3_0_start(struct amdgpu_device *adev)
if (r)
return r;
/* program JPEG secure lvl register */
r = jpeg_v5_3_0_set_mmhub_eco_sec_level(adev);
if (r)
return r;
/* JPEG disable CGC */
jpeg_v5_3_0_disable_clock_gating(adev);

View File

@ -70,27 +70,23 @@ mes_userq_create_wptr_mapping(struct amdgpu_device *adev,
ret = -EINVAL;
goto fail_map;
}
/* TODO use eviction fence instead of pinning. */
ret = amdgpu_bo_pin(wptr_obj->obj, AMDGPU_GEM_DOMAIN_GTT);
/* Keep WPTR BO under eviction-fence control instead of pinning. */
ret = amdgpu_evf_mgr_attach_fence(&uq_mgr_to_fpriv(uq_mgr)->evf_mgr, wptr_obj->obj);
if (ret) {
DRM_ERROR("Failed to pin wptr bo. ret %d\n", ret);
DRM_ERROR("Failed to attach eviction fence to wptr bo. ret %d\n", ret);
goto fail_map;
}
ret = amdgpu_ttm_alloc_gart(&wptr_obj->obj->tbo);
if (ret) {
DRM_ERROR("Failed to bind bo to GART. ret %d\n", ret);
goto fail_alloc_gart;
DRM_ERROR("Failed to bind wptr bo to GART. ret %d\n", ret);
goto fail_map;
}
queue->wptr_obj.gpu_addr = amdgpu_bo_gpu_offset(wptr_obj->obj);
drm_exec_fini(&exec);
return 0;
fail_alloc_gart:
amdgpu_bo_unpin(wptr_obj->obj);
fail_map:
amdgpu_bo_unref(&wptr_obj->obj);
fail_lock:
@ -468,9 +464,6 @@ static void mes_userq_mqd_destroy(struct amdgpu_usermode_queue *queue)
amdgpu_bo_free_kernel(&queue->mqd.obj, &queue->mqd.gpu_addr,
&queue->mqd.cpu_ptr);
amdgpu_bo_reserve(queue->wptr_obj.obj, true);
amdgpu_bo_unpin(queue->wptr_obj.obj);
amdgpu_bo_unreserve(queue->wptr_obj.obj);
amdgpu_bo_unref(&queue->wptr_obj.obj);
}

View File

@ -30,70 +30,76 @@
#include "ivsrcid/nbio/irqsrcs_nbif_7_4.h"
#include <uapi/linux/kfd_ioctl.h>
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL_nbif_4_10 0x4f0aeb
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL1_nbif_4_10 0x4f0aec
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL_nbif_4_10 0x4f0aed
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL1_nbif_4_10 0x4f0aee
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL_nbif_4_10 0x4f0aef
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL1_nbif_4_10 0x4f0af0
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL_nbif_4_10 0x4f0af1
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL1_nbif_4_10 0x4f0af2
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL_nbif_4_10 0x4f0af3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL1_nbif_4_10 0x4f0af4
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL_nbif_4_10 0x4f0af5
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL1_nbif_4_10 0x4f0af6
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL1_nbif_4_10_BASE_IDX 3
#define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbif_4_10 0x0021
#define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbif_4_10_BASE_IDX 2
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL_nbif_4_10 0x4f0aeb
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL1_nbif_4_10 0x4f0aec
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL_nbif_4_10 0x4f0aed
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL1_nbif_4_10 0x4f0aee
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL_nbif_4_10 0x4f0aef
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL1_nbif_4_10 0x4f0af0
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL_nbif_4_10 0x4f0af1
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL1_nbif_4_10 0x4f0af2
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL_nbif_4_10 0x4f0af3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL1_nbif_4_10 0x4f0af4
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL1_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL_nbif_4_10 0x4f0af5
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL1_nbif_4_10 0x4f0af6
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL1_nbif_4_10_BASE_IDX 3
#define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbif_4_10 0x0021
#define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbif_4_10_BASE_IDX 2
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_HIGH_nbio_7_11_5 0x8e13
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_HIGH_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_LOW_nbio_7_11_5 0x8e14
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_LOW_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL_nbio_7_11_5 0x8e15
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_HIGH_nbio_7_11_5 0x8e13
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_HIGH_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_LOW_nbio_7_11_5 0x8e14
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_LOW_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL_nbio_7_11_5 0x8e15
#define regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX0_REMAP_HDP_MEM_FLUSH_CNTL_nbio_7_11_5 0x8e4d
#define regBIF_BX0_REMAP_HDP_MEM_FLUSH_CNTL_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX0_REMAP_HDP_REG_FLUSH_CNTL_nbio_7_11_5 0x8e4e
#define regBIF_BX0_REMAP_HDP_REG_FLUSH_CNTL_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX1_REMAP_HDP_MEM_FLUSH_CNTL_nbio_7_11_5 0x012d
#define regBIF_BX1_REMAP_HDP_MEM_FLUSH_CNTL_nbio_7_11_5_BASE_IDX 2
#define regBIF_BX1_REMAP_HDP_REG_FLUSH_CNTL_nbio_7_11_5 0x012e
#define regBIF_BX1_REMAP_HDP_REG_FLUSH_CNTL_nbio_7_11_5_BASE_IDX 2
#define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbio_7_11_5 0xd000
#define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbio_7_11_5_BASE_IDX 5
#define regRCC_STRAP1_RCC_DEV0_EPF0_STRAP0_nbio_7_11_5 0x0021
#define regRCC_STRAP1_RCC_DEV0_EPF0_STRAP0_nbio_7_11_5_BASE_IDX 2
#define regBIF_BX0_BIF_FB_EN_nbio_7_11_5 0x8e20
#define regBIF_BX0_BIF_FB_EN_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX1_BIF_FB_EN_nbio_7_11_5 0x0100
#define regBIF_BX1_BIF_FB_EN_nbio_7_11_5_BASE_IDX 2
#define regBIF_BX0_INTERRUPT_CNTL_nbio_7_11_5 0x8e11
#define regBIF_BX0_INTERRUPT_CNTL_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX0_INTERRUPT_CNTL2_nbio_7_11_5 0x8e12
#define regBIF_BX0_INTERRUPT_CNTL2_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX1_INTERRUPT_CNTL_nbio_7_11_5 0x00f1
#define regBIF_BX1_INTERRUPT_CNTL_nbio_7_11_5_BASE_IDX 2
#define regBIF_BX1_INTERRUPT_CNTL2_nbio_7_11_5 0x00f2
#define regBIF_BX1_INTERRUPT_CNTL2_nbio_7_11_5_BASE_IDX 2
#define regBIF_BX_PF0_GPU_HDP_FLUSH_REQ_nbio_7_11_5 0x8e26
#define regBIF_BX_PF0_GPU_HDP_FLUSH_REQ_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX_PF0_GPU_HDP_FLUSH_DONE_nbio_7_11_5 0x8e27
#define regBIF_BX_PF0_GPU_HDP_FLUSH_DONE_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX_PF1_GPU_HDP_FLUSH_REQ_nbio_7_11_5 0x0106
#define regBIF_BX_PF1_GPU_HDP_FLUSH_REQ_nbio_7_11_5_BASE_IDX 2
#define regBIF_BX_PF1_GPU_HDP_FLUSH_DONE_nbio_7_11_5 0x0107
#define regBIF_BX_PF1_GPU_HDP_FLUSH_DONE_nbio_7_11_5_BASE_IDX 2
#define regBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL_nbio_7_11_5 0x8e17
#define regBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL_nbio_7_11_5_BASE_IDX 5
#define regBIF_BX_PF1_HDP_MEM_COHERENCY_FLUSH_CNTL_nbio_7_11_5 0x00f7
#define regBIF_BX_PF1_HDP_MEM_COHERENCY_FLUSH_CNTL_nbio_7_11_5_BASE_IDX 2
//BIF_BX1_BIF_FB_EN
#define BIF_BX1_BIF_FB_EN__FB_READ_EN__SHIFT_nbio_7_11_5 0x0
#define BIF_BX1_BIF_FB_EN__FB_WRITE_EN__SHIFT_nbio_7_11_5 0x1
#define BIF_BX1_BIF_FB_EN__FB_READ_EN_MASK_nbio_7_11_5 0x00000001L
#define BIF_BX1_BIF_FB_EN__FB_WRITE_EN_MASK_nbio_7_11_5 0x00000002L
static void nbif_v6_3_1_remap_hdp_registers(struct amdgpu_device *adev)
{
if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 5)) {
WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_MEM_FLUSH_CNTL_nbio_7_11_5,
WREG32_SOC15(NBIO, 0, regBIF_BX1_REMAP_HDP_MEM_FLUSH_CNTL_nbio_7_11_5,
adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL);
WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_REG_FLUSH_CNTL_nbio_7_11_5,
WREG32_SOC15(NBIO, 0, regBIF_BX1_REMAP_HDP_REG_FLUSH_CNTL_nbio_7_11_5,
adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_REG_FLUSH_CNTL);
} else {
WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_MEM_FLUSH_CNTL,
@ -110,7 +116,7 @@ static u32 nbif_v6_3_1_get_rev_id(struct amdgpu_device *adev)
if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 4))
tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbif_4_10);
else if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 5))
tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbio_7_11_5);
tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP1_RCC_DEV0_EPF0_STRAP0_nbio_7_11_5);
else
tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0);
@ -124,11 +130,11 @@ static void nbif_v6_3_1_mc_access_enable(struct amdgpu_device *adev, bool enable
{
if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 5)) {
if (enable)
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN_nbio_7_11_5,
BIF_BX0_BIF_FB_EN__FB_READ_EN_MASK |
BIF_BX0_BIF_FB_EN__FB_WRITE_EN_MASK);
WREG32_SOC15(NBIO, 0, regBIF_BX1_BIF_FB_EN_nbio_7_11_5,
BIF_BX1_BIF_FB_EN__FB_READ_EN_MASK_nbio_7_11_5 |
BIF_BX1_BIF_FB_EN__FB_WRITE_EN_MASK_nbio_7_11_5);
else
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN_nbio_7_11_5, 0);
WREG32_SOC15(NBIO, 0, regBIF_BX1_BIF_FB_EN_nbio_7_11_5, 0);
} else {
if (enable)
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN,
@ -383,12 +389,12 @@ static void nbif_v6_3_1_ih_control(struct amdgpu_device *adev)
/* setup interrupt control */
if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 5))
WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL2_nbio_7_11_5,
WREG32_SOC15(NBIO, 0, regBIF_BX1_INTERRUPT_CNTL2_nbio_7_11_5,
adev->dummy_page_addr >> 8);
else
WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL2, adev->dummy_page_addr >> 8);
interrupt_cntl = RREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL_nbio_7_11_5);
interrupt_cntl = RREG32_SOC15(NBIO, 0, regBIF_BX1_INTERRUPT_CNTL_nbio_7_11_5);
/*
* BIF_BX0_INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=0 - dummy read disabled with msi, enabled without msi
* BIF_BX0_INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=1 - dummy read controlled by IH_DUMMY_RD_EN
@ -401,7 +407,7 @@ static void nbif_v6_3_1_ih_control(struct amdgpu_device *adev)
IH_REQ_NONSNOOP_EN, 0);
if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 5))
WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL_nbio_7_11_5, interrupt_cntl);
WREG32_SOC15(NBIO, 0, regBIF_BX1_INTERRUPT_CNTL_nbio_7_11_5, interrupt_cntl);
else
WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL, interrupt_cntl);
}
@ -427,7 +433,7 @@ nbif_v6_3_1_get_clockgating_state(struct amdgpu_device *adev,
static u32 nbif_v6_3_1_get_hdp_flush_req_offset(struct amdgpu_device *adev)
{
if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 5))
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_REQ_nbio_7_11_5);
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF1_GPU_HDP_FLUSH_REQ_nbio_7_11_5);
else
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_REQ);
}
@ -435,7 +441,7 @@ static u32 nbif_v6_3_1_get_hdp_flush_req_offset(struct amdgpu_device *adev)
static u32 nbif_v6_3_1_get_hdp_flush_done_offset(struct amdgpu_device *adev)
{
if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 5))
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_DONE_nbio_7_11_5);
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF1_GPU_HDP_FLUSH_DONE_nbio_7_11_5);
else
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_DONE);
}
@ -622,7 +628,7 @@ static void nbif_v6_3_1_set_reg_remap(struct amdgpu_device *adev)
} else {
if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 5))
adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0,
regBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL_nbio_7_11_5) << 2;
regBIF_BX_PF1_HDP_MEM_COHERENCY_FLUSH_CNTL_nbio_7_11_5) << 2;
else
adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0,
regBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2;

View File

@ -110,6 +110,7 @@ enum psp_gfx_cmd_id
GFX_CMD_ID_PERF_HW = 0x0000004C, /* performance monitor */
GFX_CMD_ID_FB_FW_RESERV_ADDR = 0x00000050, /* Query FW reservation addr */
GFX_CMD_ID_FB_FW_RESERV_EXT_ADDR = 0x00000051, /* Query FW reservation extended addr */
GFX_CMD_ID_SET_MMHUB_ECO_SEC_LEVEL = 0x0000005D, /* Set MMHUB ECO sec lvls on VCN block */
};
/* PSP boot config sub-commands */

View File

@ -33,9 +33,22 @@
MODULE_FIRMWARE("amdgpu/psp_15_0_0_toc.bin");
MODULE_FIRMWARE("amdgpu/psp_15_0_0_ta.bin");
MODULE_FIRMWARE("amdgpu/psp_15_0_5_toc.bin");
MODULE_FIRMWARE("amdgpu/psp_15_0_5_ta.bin");
MODULE_FIRMWARE("amdgpu/psp_15_0_9_toc.bin");
MODULE_FIRMWARE("amdgpu/psp_15_0_9_ta.bin");
#define regMPASP_PCRU0_MPASP_C2PMSG_64 0x4280
#define regMPASP_PCRU0_MPASP_C2PMSG_64_BASE_IDX 2
#define regMPASP_PCRU0_MPASP_C2PMSG_67 0x4283
#define regMPASP_PCRU0_MPASP_C2PMSG_67_BASE_IDX 2
#define regMPASP_PCRU0_MPASP_C2PMSG_69 0x4285
#define regMPASP_PCRU0_MPASP_C2PMSG_69_BASE_IDX 2
#define regMPASP_PCRU0_MPASP_C2PMSG_70 0x4286
#define regMPASP_PCRU0_MPASP_C2PMSG_70_BASE_IDX 2
#define regMPASP_PCRU0_MPASP_C2PMSG_71 0x4287
#define regMPASP_PCRU0_MPASP_C2PMSG_71_BASE_IDX 2
static int psp_v15_0_0_init_microcode(struct psp_context *psp)
{
struct amdgpu_device *adev = psp->adev;
@ -71,14 +84,25 @@ static int psp_v15_0_0_ring_stop(struct psp_context *psp,
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_101),
0x80000000, 0x80000000, false);
} else {
/* Write the ring destroy command*/
WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64,
GFX_CTRL_CMD_ID_DESTROY_RINGS);
/* there might be handshake issue with hardware which needs delay */
mdelay(20);
/* Wait for response flag (bit 31) */
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64),
0x80000000, 0x80000000, false);
if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(15, 0, 5)) {
/* Write the ring destroy command*/
WREG32_SOC15(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_64,
GFX_CTRL_CMD_ID_DESTROY_RINGS);
/* there might be handshake issue with hardware which needs delay */
mdelay(20);
/* Wait for response flag (bit 31) */
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_64),
0x80000000, 0x80000000, false);
} else {
/* Write the ring destroy command*/
WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64,
GFX_CTRL_CMD_ID_DESTROY_RINGS);
/* there might be handshake issue with hardware which needs delay */
mdelay(20);
/* Wait for response flag (bit 31) */
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64),
0x80000000, 0x80000000, false);
}
}
return ret;
@ -118,14 +142,44 @@ static int psp_v15_0_0_ring_create(struct psp_context *psp,
0x80000000, 0x8000FFFF, false);
} else {
/* Wait for sOS ready for ring creation */
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64),
0x80000000, 0x80000000, false);
if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(15, 0, 5)) {
/* Wait for sOS ready for ring creation */
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_64),
0x80000000, 0x80000000, false);
if (ret) {
DRM_ERROR("Failed to wait for trust OS ready for ring creation\n");
return ret;
}
/* Write low address of the ring to C2PMSG_69 */
psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
WREG32_SOC15(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_69, psp_ring_reg);
/* Write high address of the ring to C2PMSG_70 */
psp_ring_reg = upper_32_bits(ring->ring_mem_mc_addr);
WREG32_SOC15(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_70, psp_ring_reg);
/* Write size of ring to C2PMSG_71 */
psp_ring_reg = ring->ring_size;
WREG32_SOC15(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_71, psp_ring_reg);
/* Write the ring initialization command to C2PMSG_64 */
psp_ring_reg = ring_type;
psp_ring_reg = psp_ring_reg << 16;
WREG32_SOC15(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_64, psp_ring_reg);
/* there might be handshake issue with hardware which needs delay */
mdelay(20);
/* Wait for response flag (bit 31) in C2PMSG_64 */
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_64),
0x80000000, 0x8000FFFF, false);
} else {
/* Wait for sOS ready for ring creation */
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64),
0x80000000, 0x80000000, false);
if (ret) {
DRM_ERROR("Failed to wait for trust OS ready for ring creation\n");
return ret;
}
/* Write low address of the ring to C2PMSG_69 */
psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_69, psp_ring_reg);
@ -146,6 +200,7 @@ static int psp_v15_0_0_ring_create(struct psp_context *psp,
/* Wait for response flag (bit 31) in C2PMSG_64 */
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64),
0x80000000, 0x8000FFFF, false);
}
}
return ret;
@ -176,8 +231,12 @@ static uint32_t psp_v15_0_0_ring_get_wptr(struct psp_context *psp)
if (amdgpu_sriov_vf(adev))
data = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_102);
else
data = RREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_67);
else {
if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(15, 0, 5))
data = RREG32_SOC15(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_67);
else
data = RREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_67);
}
return data;
}
@ -190,8 +249,12 @@ static void psp_v15_0_0_ring_set_wptr(struct psp_context *psp, uint32_t value)
WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_102, value);
WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_101,
GFX_CTRL_CMD_ID_CONSUME_CMD);
} else
WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_67, value);
} else {
if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(15, 0, 5))
WREG32_SOC15(MP0, 0, regMPASP_PCRU0_MPASP_C2PMSG_67, value);
else
WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_67, value);
}
}
static const struct psp_funcs psp_v15_0_0_funcs = {

View File

@ -406,6 +406,7 @@ soc21_asic_reset_method(struct amdgpu_device *adev)
case IP_VERSION(14, 0, 4):
case IP_VERSION(14, 0, 5):
case IP_VERSION(15, 0, 0):
case IP_VERSION(15, 0, 5):
case IP_VERSION(15, 0, 9):
return AMD_RESET_METHOD_MODE2;
default:

View File

@ -795,6 +795,27 @@ static int vcn_v5_0_0_start_dpg_mode(struct amdgpu_vcn_inst *vinst,
return 0;
}
/**
* vcn_v5_0_0_set_mmhub_eco_sec_level - set vcn sec lvl reg
*
* @adev: amdgpu_device pointer
*
* request psp to set sec lvl
*/
static int vcn_v5_0_0_set_mmhub_eco_sec_level(struct amdgpu_device *adev)
{
int r = 0;
if (amdgpu_ip_version(adev, VCN_HWIP, 0) == IP_VERSION(5, 3, 0)) {
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
/* Request to PSP to program VCN secure lvl */
r = psp_set_mmhub_eco_sec_level(adev);
}
}
return r;
}
/**
* vcn_v5_0_0_start - VCN start
*
@ -819,6 +840,11 @@ static int vcn_v5_0_0_start(struct amdgpu_vcn_inst *vinst)
fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
/* program VCN secure lvl register */
r = vcn_v5_0_0_set_mmhub_eco_sec_level(adev);
if (r)
return r;
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
return vcn_v5_0_0_start_dpg_mode(vinst, adev->vcn.inst[i].indirect_sram);

View File

@ -3109,10 +3109,14 @@ static int kfd_ioctl_set_debug_trap(struct file *filep, struct kfd_process *p, v
goto out;
}
/* Check if target is still PTRACED. */
/*
* Verify debugger has permission to debug target process.
* For cross-process debugging, require active ptrace relationship.
* This applies to ALL operations to prevent unauthorized interference.
*/
rcu_read_lock();
if (target != p && args->op != KFD_IOC_DBG_TRAP_DISABLE
&& ptrace_parent(target->lead_thread) != current) {
if (target != p && ptrace_parent(target->lead_thread) != current
&& target->debugger_process != p) {
pr_err("PID %i is not PTRACED and cannot be debugged\n", args->pid);
r = -EPERM;
}

View File

@ -1412,6 +1412,15 @@ int kfd_parse_crat_table(void *crat_image, struct list_head *device_list,
break;
}
/* Validate subtype fits within remaining image */
if ((char *)sub_type_hdr + sub_type_hdr->length >
(char *)crat_image + image_len) {
pr_warn("CRAT subtype length %u exceeds image bounds\n",
sub_type_hdr->length);
ret = -EINVAL;
break;
}
if (sub_type_hdr->flags & CRAT_SUBTYPE_FLAGS_ENABLED) {
ret = kfd_parse_subtype(sub_type_hdr, device_list);
if (ret)

View File

@ -524,6 +524,9 @@ int kfd_criu_restore_event(struct file *devkfd,
ret = create_other_event(p, ev, &ev_priv->event_id);
break;
default:
ret = -EINVAL;
break;
}
mutex_unlock(&p->event_mutex);
@ -545,15 +548,27 @@ int kfd_criu_checkpoint_events(struct kfd_process *p,
int ret = 0;
struct kfd_event *ev;
uint32_t ev_id;
uint32_t num_events;
uint32_t num_events = kfd_get_num_events(p);
/* Serialize the count and the walk below against concurrent event
* create/destroy. Those paths take only p->event_mutex, not the
* p->mutex held by the CRIU checkpoint caller, so without this the
* event_idr can grow between kfd_get_num_events() and the loop and the
* walk writes past the ev_privs allocation.
*/
mutex_lock(&p->event_mutex);
if (!num_events)
num_events = kfd_get_num_events(p);
if (!num_events) {
mutex_unlock(&p->event_mutex);
return 0;
}
ev_privs = kvzalloc(num_events * sizeof(*ev_privs), GFP_KERNEL);
if (!ev_privs)
if (!ev_privs) {
mutex_unlock(&p->event_mutex);
return -ENOMEM;
}
idr_for_each_entry(&p->event_idr, ev, ev_id) {
@ -594,6 +609,8 @@ int kfd_criu_checkpoint_events(struct kfd_process *p,
i++;
}
mutex_unlock(&p->event_mutex);
ret = copy_to_user(user_priv_data + *priv_data_offset,
ev_privs, num_events * sizeof(*ev_privs));
if (ret) {

View File

@ -383,7 +383,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,
false);
if (retval) {
dev_err(dev->adev->dev, "failed to allocate process context bo\n");
return retval;
goto err_allocate_pqn;
}
memset(pdd->proc_ctx_cpu_ptr, 0, AMDGPU_MES_PROC_CTX_SIZE);
}

View File

@ -288,7 +288,7 @@ int kfd_queue_acquire_buffers(struct kfd_process_device *pdd, struct queue_prope
}
err = kfd_queue_buffer_get(vm, (void *)properties->eop_ring_buffer_address,
&properties->eop_buf_bo,
ALIGN(properties->eop_ring_buffer_size, PAGE_SIZE));
ALIGN((u64)properties->eop_ring_buffer_size, PAGE_SIZE));
if (err)
goto out_err_unreserve;
}

View File

@ -9903,25 +9903,6 @@ static void remove_stream(struct amdgpu_device *adev,
acrtc->enabled = false;
}
static void prepare_flip_isr(struct amdgpu_crtc *acrtc)
{
assert_spin_locked(&acrtc->base.dev->event_lock);
WARN_ON(acrtc->event);
acrtc->event = acrtc->base.state->event;
/* Set the flip status */
acrtc->pflip_status = AMDGPU_FLIP_SUBMITTED;
/* Mark this event as consumed */
acrtc->base.state->event = NULL;
drm_dbg_state(acrtc->base.dev,
"crtc:%d, pflip_stat:AMDGPU_FLIP_SUBMITTED\n",
acrtc->crtc_id);
}
static void update_freesync_state_on_stream(
struct amdgpu_display_manager *dm,
struct dm_crtc_state *new_crtc_state,
@ -10274,17 +10255,47 @@ static void dm_arm_vblank_event(struct amdgpu_crtc *acrtc,
return;
if (pflip_update) {
drm_crtc_vblank_get(&acrtc->base);
WARN_ON(acrtc->pflip_status != AMDGPU_FLIP_NONE);
/* Arm flip completion handling and event delivery after programming. */
prepare_flip_isr(acrtc);
WARN_ON(acrtc->event);
acrtc->pflip_status = AMDGPU_FLIP_SUBMITTED;
acrtc->event = acrtc->base.state->event;
acrtc->base.state->event = NULL;
drm_dbg_state(acrtc->base.dev,
"crtc:%d, pflip_stat:AMDGPU_FLIP_SUBMITTED\n",
acrtc->crtc_id);
} else if (cursor_update) {
drm_crtc_vblank_get(&acrtc->base);
acrtc->event = acrtc->base.state->event;
acrtc->base.state->event = NULL;
}
}
/**
* dm_arm_vblank_event_pre_programming - Prepare for programming
* @acrtc: The amdgpu CRTC to prepare
* @acrtc_state: The new CRTC state
* @pflip_update: Whether a page flip is being programmed
* @cursor_update: Whether a cursor update is being programmed
*
* Grab a reference on the vblank counter if a page flip or cursor update is to
* be programmed. Do this before programming so the HW is not in any
* idle-optimized state (such as PSR).
*/
static void dm_arm_vblank_event_pre_programming(struct amdgpu_crtc *acrtc,
struct dm_crtc_state *acrtc_state,
bool pflip_update,
bool cursor_update)
{
assert_spin_locked(&acrtc->base.dev->event_lock);
if (!acrtc->base.state->event || acrtc_state->active_planes == 0)
return;
if (pflip_update || cursor_update)
drm_crtc_vblank_get(&acrtc->base);
}
static void amdgpu_dm_commit_planes(struct drm_atomic_commit *state,
struct drm_device *dev,
struct amdgpu_display_manager *dm,
@ -10550,16 +10561,19 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_commit *state,
}
}
/*
* DCE depends on a combination of GRPH_FLIP, VLINE0, and VUPDATE for
* event delivery. Only GRPH_FLIP handler can send pflip events, and it
* only fires if HW latched to the flip. Maintain legacy behavior by
* arming event before programming.
*/
if (amdgpu_ip_version(dm->adev, DCE_HWIP, 0) == 0) {
scoped_guard(spinlock_irqsave, &pcrtc->dev->event_lock) {
scoped_guard(spinlock_irqsave, &pcrtc->dev->event_lock) {
dm_arm_vblank_event_pre_programming(acrtc_attach, acrtc_state,
pflip_present,
cursor_update);
/*
* DCE depends on a combination of GRPH_FLIP, VLINE0, and
* VUPDATE for event delivery. Only GRPH_FLIP handler can send
* pflip events, and it only fires if HW latched to the flip.
* Maintain legacy behavior by arming event before programming.
*/
if (amdgpu_ip_version(dm->adev, DCE_HWIP, 0) == 0) {
dm_arm_vblank_event(acrtc_attach, acrtc_state,
pflip_present, cursor_update);
pflip_present, cursor_update);
}
}

View File

@ -45,9 +45,7 @@
clk_src->base.ctx
#define DC_LOGGER \
calc_pll_cs->ctx->logger
#define DC_LOGGER_INIT() \
struct calc_pll_clock_source *calc_pll_cs = &clk_src->calc_pll
CTX->logger
#undef FN
#define FN(reg_name, field_name) \
@ -287,6 +285,7 @@ static bool calc_pll_dividers_in_range(
}
static uint32_t calculate_pixel_clock_pll_dividers(
struct dce110_clk_src *clk_src,
struct calc_pll_clock_source *calc_pll_cs,
struct pll_settings *pll_settings)
{
@ -474,7 +473,7 @@ static uint32_t dce110_get_pix_clk_dividers_helper (
{
uint32_t field = 0;
uint32_t pll_calc_error = MAX_PLL_CALC_ERROR;
DC_LOGGER_INIT();
/* Check if reference clock is external (not pcie/xtalin)
* HW Dce80 spec:
* 00 - PCIE_REFCLK, 01 - XTALIN, 02 - GENERICA, 03 - GENERICB
@ -517,12 +516,14 @@ static uint32_t dce110_get_pix_clk_dividers_helper (
/*Calculate Dividers by HDMI object, no SS case or SS case */
pll_calc_error =
calculate_pixel_clock_pll_dividers(
clk_src,
&clk_src->calc_pll_hdmi,
pll_settings);
else
/*Calculate Dividers by default object, no SS case or SS case */
pll_calc_error =
calculate_pixel_clock_pll_dividers(
clk_src,
&clk_src->calc_pll,
pll_settings);
@ -568,7 +569,6 @@ static uint32_t dce110_get_pix_clk_dividers(
{
struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(cs);
uint32_t pll_calc_error = MAX_PLL_CALC_ERROR;
DC_LOGGER_INIT();
if (pix_clk_params == NULL || pll_settings == NULL
|| pix_clk_params->requested_pix_clk_100hz == 0) {
@ -600,7 +600,6 @@ static uint32_t dce112_get_pix_clk_dividers(
struct pll_settings *pll_settings)
{
struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(cs);
DC_LOGGER_INIT();
if (pix_clk_params == NULL || pll_settings == NULL
|| pix_clk_params->requested_pix_clk_100hz == 0) {
@ -1442,8 +1441,6 @@ static uint32_t dcn3_get_pix_clk_dividers(
unsigned long long actual_pix_clk_100Hz = pix_clk_params ? pix_clk_params->requested_pix_clk_100hz : 0;
struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(cs);
DC_LOGGER_INIT();
if (pix_clk_params == NULL || pll_settings == NULL
|| pix_clk_params->requested_pix_clk_100hz == 0) {
DC_LOG_ERROR(
@ -1513,7 +1510,6 @@ static const struct clock_source_funcs dce110_clk_src_funcs = {
.get_dp_dto_frequency_100hz = get_dp_dto_frequency_100hz
};
static void get_ss_info_from_atombios(
struct dce110_clk_src *clk_src,
enum as_signal_type as_signal,
@ -1526,7 +1522,7 @@ static void get_ss_info_from_atombios(
struct spread_spectrum_info *ss_info_cur;
struct spread_spectrum_data *ss_data_cur;
uint32_t i;
DC_LOGGER_INIT();
if (ss_entries_num == NULL) {
DC_LOG_SYNC(
"Invalid entry !!!\n");
@ -1657,6 +1653,7 @@ static void ss_info_from_atombios_create(
}
static bool calc_pll_max_vco_construct(
struct dce110_clk_src *clk_src,
struct calc_pll_clock_source *calc_pll_cs,
struct calc_pll_clock_source_init_data *init_data)
{
@ -1808,6 +1805,7 @@ bool dce110_clk_src_construct(
ss_info_from_atombios_create(clk_src);
if (!calc_pll_max_vco_construct(
clk_src,
&clk_src->calc_pll,
&calc_pll_cs_init_data)) {
ASSERT_CRITICAL(false);
@ -1822,7 +1820,7 @@ bool dce110_clk_src_construct(
if (!calc_pll_max_vco_construct(
&clk_src->calc_pll_hdmi, &calc_pll_cs_init_data_hdmi)) {
clk_src, &clk_src->calc_pll_hdmi, &calc_pll_cs_init_data_hdmi)) {
ASSERT_CRITICAL(false);
goto unexpected_failure;
}

View File

@ -359,14 +359,13 @@ void dml21_handle_phantom_streams_planes(const struct dc *dc, struct dc_state *c
main_plane = main_stream_status->plane_states[dc_plane_index];
/* create phantom planes for subvp enabled plane */
dml21_add_phantom_plane(dml_ctx,
dc,
context,
phantom_stream,
main_plane,
&dml_ctx->v21.mode_programming.programming->plane_programming[dml_plane_index]);
phantoms_added = true;
if (dml21_add_phantom_plane(dml_ctx,
dc,
context,
phantom_stream,
main_plane,
&dml_ctx->v21.mode_programming.programming->plane_programming[dml_plane_index]))
phantoms_added = true;
}
}
}

View File

@ -2452,7 +2452,7 @@ static void calculate_mcache_row_bytes(
DML_ASSERT(*p->num_mcaches > 0);
}
static void calculate_mcache_setting(
static bool calculate_mcache_setting(
struct dml2_core_internal_scratch *scratch,
struct dml2_core_calcs_calculate_mcache_setting_params *p)
{
@ -2478,7 +2478,7 @@ static void calculate_mcache_setting(
*p->lc_comb_mcache = 0;
if (!p->dcc_enable)
return;
return true;
l->is_dual_plane = dml_is_420(p->source_format) || p->source_format == dml2_rgbe_alpha;
@ -2515,7 +2515,14 @@ static void calculate_mcache_setting(
l->l_p.mvmpg_per_mcache_lb = &l->mvmpg_per_mcache_lb_l;
calculate_mcache_row_bytes(scratch, &l->l_p);
DML_ASSERT(*p->num_mcaches_l > 0);
if (*p->num_mcaches_l == 0 ||
(p->surf_vert ? l->mvmpg_height_l : l->mvmpg_width_l) == 0) {
DML_LOG_VERBOSE("DML::%s: degenerate luma viewport (num_mcaches_l=%u mvmpg_%s_l=%u) — mode not supported\n",
__func__, *p->num_mcaches_l,
p->surf_vert ? "height" : "width",
p->surf_vert ? l->mvmpg_height_l : l->mvmpg_width_l);
return false;
}
if (l->is_dual_plane) {
l->c_p.num_chans = p->num_chans;
@ -2551,7 +2558,14 @@ static void calculate_mcache_setting(
l->c_p.mvmpg_per_mcache_lb = &l->mvmpg_per_mcache_lb_c;
calculate_mcache_row_bytes(scratch, &l->c_p);
DML_ASSERT(*p->num_mcaches_c > 0);
if (*p->num_mcaches_c == 0 ||
(p->surf_vert ? l->mvmpg_height_c : l->mvmpg_width_c) == 0) {
DML_LOG_VERBOSE("DML::%s: degenerate chroma viewport (num_mcaches_c=%u mvmpg_%s_c=%u) — mode not supported\n",
__func__, *p->num_mcaches_c,
p->surf_vert ? "height" : "width",
p->surf_vert ? l->mvmpg_height_c : l->mvmpg_width_c);
return false;
}
}
// Sharing for iMALL access
@ -2661,6 +2675,7 @@ static void calculate_mcache_setting(
*p->mcache_shift_granularity_l = l->mvmpg_access_width_l;
*p->mcache_shift_granularity_c = l->mvmpg_access_width_c;
return true;
}
static void calculate_mall_bw_overhead_factor(
@ -9457,7 +9472,10 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
calculate_mcache_setting_params->mall_comb_mcache_c = &mode_lib->ms.mall_comb_mcache_c[k];
calculate_mcache_setting_params->lc_comb_mcache = &mode_lib->ms.lc_comb_mcache[k];
calculate_mcache_setting(&mode_lib->scratch, calculate_mcache_setting_params);
if (!calculate_mcache_setting(&mode_lib->scratch, calculate_mcache_setting_params)) {
mode_lib->ms.support.ModeSupport = false;
return false;
}
}
calculate_mall_bw_overhead_factor(
@ -10933,7 +10951,8 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
calculate_mcache_setting_params->mall_comb_mcache_l = &mode_lib->mp.mall_comb_mcache_l[k];
calculate_mcache_setting_params->mall_comb_mcache_c = &mode_lib->mp.mall_comb_mcache_c[k];
calculate_mcache_setting_params->lc_comb_mcache = &mode_lib->mp.lc_comb_mcache[k];
calculate_mcache_setting(&mode_lib->scratch, calculate_mcache_setting_params);
if (!calculate_mcache_setting(&mode_lib->scratch, calculate_mcache_setting_params))
return false;
}
calculate_mall_bw_overhead_factor(

View File

@ -1337,8 +1337,27 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
{
if (pipe_ctx != NULL && pipe_ctx->stream_res.stream_enc != NULL)
if (pipe_ctx == NULL || pipe_ctx->stream_res.stream_enc == NULL)
return;
if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
pipe_ctx->stream_res.stream_enc->funcs->set_avmute(pipe_ctx->stream_res.stream_enc, enable);
/* Wait for three frames to make sure AV mute is sent out.
* Some HDMI sinks need additional GCP packets to properly
* process the mute state, especially after link re-establishment
* with HDMI 2.0 scrambling enabled.
*/
if (enable && pipe_ctx->stream_res.tg->funcs->is_tg_enabled(pipe_ctx->stream_res.tg)) {
int i;
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
for (i = 0; i < 3; i++) {
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
}
}
}
}
enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id)

View File

@ -847,13 +847,19 @@ void dcn30_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
pipe_ctx->stream_res.stream_enc,
enable);
/* Wait for two frame to make sure AV mute is sent out */
/* Wait for three frames to make sure AV mute is sent out.
* Some HDMI sinks need additional GCP packets to properly
* process the mute state, especially after link re-establishment
* with HDMI 2.0 scrambling enabled.
*/
if (enable && pipe_ctx->stream_res.tg->funcs->is_tg_enabled(pipe_ctx->stream_res.tg)) {
int i;
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
for (i = 0; i < 3; i++) {
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
}
}
}
}

View File

@ -384,7 +384,7 @@ static bool write_i2c_retimer_vga(
for (size_t i = 0; i < ARRAY_SIZE(vga_data); i++) {
if (!write_i2c_retimer_offset_value(link, address, vga_data[i][0], vga_data[i][1])) {
DC_LOG_ERROR("Set retimer failed, vga index: %zu\n", i);
DC_LOG_DEBUG("Set retimer failed, vga index: %zu\n", i);
return false;
}
}
@ -405,7 +405,7 @@ static bool write_i2c_retimer_byte(
return true;
if (!write_i2c_retimer_offset_value(link, address, index, value)) {
DC_LOG_ERROR("Set retimer failed, 3g index: 0x%x, value: 0x%x\n", index, value);
DC_LOG_DEBUG("Set retimer failed, 3g index: 0x%x, value: 0x%x\n", index, value);
return false;
}
@ -421,14 +421,14 @@ static bool write_i2c_retimer_byte(
if (!link_query_ddc_data(
link->ddc, address, &offset, 1, &value, 1
)) {
DC_LOG_ERROR("Set retimer failed, link_query_ddc_data\n");
DC_LOG_DEBUG("Set retimer failed, link_query_ddc_data\n");
return false;
}
}
value |= apply_rx_tx_change;
if (!write_i2c_retimer_offset_value(link, address, offset, value)) {
DC_LOG_ERROR("Set retimer failed, 3g offset: 0x%x, value: 0x%x\n", offset, value);
DC_LOG_DEBUG("Set retimer failed, 3g offset: 0x%x, value: 0x%x\n", offset, value);
return false;
}
}
@ -449,7 +449,7 @@ static bool write_i2c_retimer_setting(
uint8_t value = settings->reg_settings[i].i2c_reg_val;
if (!write_i2c_retimer_byte(link, address, index, value)) {
DC_LOG_ERROR("Set retimer failed, index: %zu\n", i);
DC_LOG_DEBUG("Set retimer failed, index: %zu\n", i);
return false;
}
}
@ -460,7 +460,7 @@ static bool write_i2c_retimer_setting(
uint8_t value = settings->reg_settings_6g[i].i2c_reg_val;
if (!write_i2c_retimer_byte(link, address, index, value)) {
DC_LOG_ERROR("Set retimer failed, 6g index: %zu\n", i);
DC_LOG_DEBUG("Set retimer failed, 6g index: %zu\n", i);
return false;
}
}
@ -492,7 +492,7 @@ static bool write_i2c_default_retimer_setting(
for (size_t i = 0; i < ARRAY_SIZE(data); i++) {
if (!write_i2c_retimer_offset_value(link, address, data[i][0], data[i][1])) {
DC_LOG_ERROR("Set default retimer failed, index: %zu\n", i);
DC_LOG_DEBUG("Set default retimer failed, index: %zu\n", i);
return false;
}
}
@ -524,7 +524,7 @@ static bool write_i2c_redriver_setting(
);
if (!success)
DC_LOG_ERROR("Set redriver failed");
DC_LOG_DEBUG("Set redriver failed");
return success;
}

View File

@ -24,6 +24,8 @@
#ifndef __KGD_PP_INTERFACE_H__
#define __KGD_PP_INTERFACE_H__
#include <linux/units.h>
extern const struct amdgpu_ip_block_version pp_smu_ip_block;
extern const struct amdgpu_ip_block_version smu_v11_0_ip_block;
extern const struct amdgpu_ip_block_version smu_v12_0_ip_block;
@ -150,8 +152,8 @@ enum amd_pp_sensors {
AMDGPU_PP_SENSOR_MEM_TEMP,
AMDGPU_PP_SENSOR_VCE_POWER,
AMDGPU_PP_SENSOR_UVD_POWER,
AMDGPU_PP_SENSOR_GPU_AVG_POWER,
AMDGPU_PP_SENSOR_GPU_INPUT_POWER,
AMDGPU_PP_SENSOR_GPU_AVG_POWER, /* milliwatts */
AMDGPU_PP_SENSOR_GPU_INPUT_POWER, /* milliwatts */
AMDGPU_PP_SENSOR_SS_APU_SHARE,
AMDGPU_PP_SENSOR_SS_DGPU_SHARE,
AMDGPU_PP_SENSOR_STABLE_PSTATE_SCLK,

View File

@ -1183,20 +1183,36 @@ int amdgpu_dpm_dispatch_task(struct amdgpu_device *adev,
return ret;
}
int amdgpu_dpm_get_pp_table(struct amdgpu_device *adev, char **table)
static bool amdgpu_dpm_is_pp_table_allowed(struct amdgpu_device *adev)
{
return !amdgpu_sriov_vf(adev) &&
!(adev->flags & AMD_IS_APU) &&
!adev->scpm_enabled;
}
int amdgpu_dpm_get_pp_table(struct amdgpu_device *adev, char *table,
size_t size)
{
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
char *pptable = NULL;
int ret = 0;
if (!table)
if ((!table && size) || (table && !size))
return -EINVAL;
if (amdgpu_sriov_vf(adev) || !pp_funcs->get_pp_table || adev->scpm_enabled)
if (!amdgpu_dpm_is_pp_table_allowed(adev) ||
!pp_funcs->get_pp_table)
return -EOPNOTSUPP;
mutex_lock(&adev->pm.mutex);
ret = pp_funcs->get_pp_table(adev->powerplay.pp_handle,
table);
&pptable);
if (ret > 0 && !pptable) {
ret = -EINVAL;
} else if (ret > 0 && table) {
ret = min_t(size_t, ret, size);
memcpy(table, pptable, ret);
}
mutex_unlock(&adev->pm.mutex);
return ret;
@ -1426,17 +1442,23 @@ int amdgpu_dpm_set_power_profile_mode(struct amdgpu_device *adev,
return ret;
}
int amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void **table)
ssize_t amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void *buf,
size_t size)
{
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
int ret = 0;
void *table;
ssize_t ret;
if (!pp_funcs->get_gpu_metrics)
return 0;
mutex_lock(&adev->pm.mutex);
ret = pp_funcs->get_gpu_metrics(adev->powerplay.pp_handle,
table);
&table);
if (ret > 0) {
ret = min_t(ssize_t, ret, size);
memcpy(buf, table, ret);
}
mutex_unlock(&adev->pm.mutex);
return ret;
@ -1703,7 +1725,8 @@ int amdgpu_dpm_set_pp_table(struct amdgpu_device *adev,
if (!buf || !size)
return -EINVAL;
if (amdgpu_sriov_vf(adev) || !pp_funcs->set_pp_table || adev->scpm_enabled)
if (!amdgpu_dpm_is_pp_table_allowed(adev) ||
!pp_funcs->set_pp_table)
return -EOPNOTSUPP;
mutex_lock(&adev->pm.mutex);

View File

@ -41,8 +41,6 @@
#define DEVICE_ATTR_IS(_name) (attr_id == device_attr_id__##_name)
#define power_2_mwatt(power) (((power) >> 8) * 1000 + ((power) & 0xff))
struct od_attribute {
struct kobj_attribute attribute;
struct list_head entry;
@ -564,25 +562,19 @@ static ssize_t amdgpu_get_pp_table(struct device *dev,
{
struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev);
char *table = NULL;
int size, ret;
ret = amdgpu_pm_get_access_if_active(adev);
if (ret)
return ret;
size = amdgpu_dpm_get_pp_table(adev, &table);
size = amdgpu_dpm_get_pp_table(adev, buf, PAGE_SIZE - 1);
amdgpu_pm_put_access(adev);
if (size <= 0)
return size;
if (size >= PAGE_SIZE)
size = PAGE_SIZE - 1;
memcpy(buf, table, size);
return size;
}
@ -1780,7 +1772,6 @@ static ssize_t amdgpu_get_gpu_metrics(struct device *dev,
{
struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev);
void *gpu_metrics;
ssize_t size = 0;
int ret;
@ -1788,15 +1779,10 @@ static ssize_t amdgpu_get_gpu_metrics(struct device *dev,
if (ret)
return ret;
size = amdgpu_dpm_get_gpu_metrics(adev, &gpu_metrics);
size = amdgpu_dpm_get_gpu_metrics(adev, buf, PAGE_SIZE - 1);
if (size <= 0)
goto out;
if (size >= PAGE_SIZE)
size = PAGE_SIZE - 1;
memcpy(buf, gpu_metrics, size);
out:
amdgpu_pm_put_access(adev);
@ -2726,10 +2712,9 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_
*states = ATTR_STATE_UNSUPPORTED;
} else if (DEVICE_ATTR_IS(pp_table)) {
int ret;
char *tmp = NULL;
ret = amdgpu_dpm_get_pp_table(adev, &tmp);
if (ret == -EOPNOTSUPP || !tmp)
ret = amdgpu_dpm_get_pp_table(adev, NULL, 0);
if (ret <= 0)
*states = ATTR_STATE_UNSUPPORTED;
else
*states = ATTR_STATE_SUPPORTED;
@ -3364,7 +3349,7 @@ static int amdgpu_hwmon_get_power(struct device *dev,
return r;
/* convert to microwatts */
return power_2_mwatt(query) * 1000;
return query * 1000;
}
static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev,
@ -4932,7 +4917,7 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
seq_printf(m, "\t%u mV (VDDNB)\n", value);
size = sizeof(uint32_t);
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_AVG_POWER, (void *)&query, &size)) {
mwatt = power_2_mwatt(query);
mwatt = query;
centiwatt = DIV_ROUND_CLOSEST(mwatt, 10);
if (adev->flags & AMD_IS_APU)
seq_printf(m, "\t%u.%02u W (average SoC including CPU)\n", centiwatt / 100, centiwatt % 100);
@ -4941,7 +4926,7 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
}
size = sizeof(uint32_t);
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_INPUT_POWER, (void *)&query, &size)) {
mwatt = power_2_mwatt(query);
mwatt = query;
centiwatt = DIV_ROUND_CLOSEST(mwatt, 10);
if (adev->flags & AMD_IS_APU)
seq_printf(m, "\t%u.%02u W (current SoC including CPU)\n", centiwatt / 100, centiwatt % 100);

View File

@ -487,7 +487,8 @@ int amdgpu_dpm_get_pp_num_states(struct amdgpu_device *adev,
int amdgpu_dpm_dispatch_task(struct amdgpu_device *adev,
enum amd_pp_task task_id,
enum amd_pm_state_type *user_state);
int amdgpu_dpm_get_pp_table(struct amdgpu_device *adev, char **table);
int amdgpu_dpm_get_pp_table(struct amdgpu_device *adev, char *table,
size_t size);
int amdgpu_dpm_set_fine_grain_clk_vol(struct amdgpu_device *adev,
uint32_t type,
long *input,
@ -517,7 +518,8 @@ int amdgpu_dpm_get_power_profile_mode(struct amdgpu_device *adev,
char *buf);
int amdgpu_dpm_set_power_profile_mode(struct amdgpu_device *adev,
long *input, uint32_t size);
int amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void **table);
ssize_t amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void *buf,
size_t size);
ssize_t amdgpu_dpm_get_xcp_metrics(struct amdgpu_device *adev, int xcp_id,
void *table);
ssize_t amdgpu_dpm_get_temp_metrics(struct amdgpu_device *adev,

View File

@ -4062,7 +4062,7 @@ static int smu7_get_gpu_power(struct pp_hwmgr *hwmgr, u32 *query)
(adev->asic_type != CHIP_FIJI) &&
(adev->asic_type != CHIP_TONGA)) {
smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetCurrPkgPwr, 0, &tmp);
*query = tmp;
*query = PP_PWR_Q24_8_TO_MW(tmp);
if (tmp != 0)
return 0;
@ -4081,7 +4081,7 @@ static int smu7_get_gpu_power(struct pp_hwmgr *hwmgr, u32 *query)
if (tmp != 0)
break;
}
*query = tmp;
*query = PP_PWR_Q24_8_TO_MW(tmp);
return 0;
}

View File

@ -3934,8 +3934,8 @@ static int vega10_get_gpu_power(struct pp_hwmgr *hwmgr,
if (ret)
return ret;
/* SMC returning actual watts, keep consistent with legacy asics, low 8 bit as 8 fractional bits */
*query = value << 8;
/* SMC returns whole Watts, while power sensors use milliwatts. */
*query = value * MILLIWATT_PER_WATT;
return 0;
}

View File

@ -1419,7 +1419,7 @@ static int vega12_get_gpu_power(struct pp_hwmgr *hwmgr, uint32_t *query)
if (ret)
return ret;
*query = metrics_table.CurrSocketPower << 8;
*query = metrics_table.CurrSocketPower * MILLIWATT_PER_WATT;
return ret;
}

View File

@ -2154,12 +2154,13 @@ static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr, int idx,
switch (idx) {
case AMDGPU_PP_SENSOR_GPU_AVG_POWER:
if (hwmgr->smu_version == 0x282e00)
*query = metrics_table.AverageSocketPower << 8;
*query = metrics_table.AverageSocketPower *
MILLIWATT_PER_WATT;
else
ret = -EOPNOTSUPP;
break;
case AMDGPU_PP_SENSOR_GPU_INPUT_POWER:
*query = metrics_table.CurrSocketPower << 8;
*query = metrics_table.CurrSocketPower * MILLIWATT_PER_WATT;
break;
}

View File

@ -35,6 +35,11 @@ struct pp_hwmgr;
struct phm_fan_speed_info;
struct pp_atomctrl_voltage_table;
/* Decode legacy unsigned Q24.8 watts to internal milliwatts. */
#define PP_PWR_Q24_8_TO_MW(power) \
DIV_ROUND_CLOSEST_ULL((u64)(power) * MILLIWATT_PER_WATT, \
BIT(8))
#define VOLTAGE_SCALE 4
#define VOLTAGE_VID_OFFSET_SCALE1 625
#define VOLTAGE_VID_OFFSET_SCALE2 100

View File

@ -1348,7 +1348,7 @@ struct pptable_funcs {
u32 (*set_gfx_off_residency)(struct smu_context *smu, bool start);
/**
* @get_gfx_off_residency: Average GFXOFF residency % during the logging interval
* @get_gfx_off_residency: Live GFXOFF residency percentage
*/
u32 (*get_gfx_off_residency)(struct smu_context *smu, uint32_t *residency);

View File

@ -144,6 +144,44 @@ typedef struct {
uint32_t MaxGfxClk;
} DpmClocks_t;
//Freq in MHz
//Voltage in milli volts with 2 fractional bits
typedef struct {
uint32_t DcfClocks[NUM_DCFCLK_DPM_LEVELS];
uint32_t DispClocks[NUM_DISPCLK_DPM_LEVELS];
uint32_t DppClocks[NUM_DPPCLK_DPM_LEVELS];
uint32_t SocClocks[NUM_SOCCLK_DPM_LEVELS];
uint32_t VPEClocks[NUM_VPE_DPM_LEVELS];
uint32_t FclkClocks_Freq[NUM_FCLK_DPM_LEVELS];
uint32_t FclkClocks_Voltage[NUM_FCLK_DPM_LEVELS];
uint32_t SocVoltage[NUM_SOC_VOLTAGE_LEVELS];
MemPstateTable_t MemPstateTable[NUM_MEM_PSTATE_LEVELS];
uint8_t NumDcfClkLevelsEnabled;
uint8_t NumDispClkLevelsEnabled; //Applies to both Dispclk and Dppclk
uint8_t NumSocClkLevelsEnabled;
uint8_t VpeClkLevelsEnabled;
uint8_t NumMemPstatesEnabled;
uint8_t NumFclkLevelsEnabled;
uint8_t Spare1;
uint8_t Spare2;
uint8_t Spare3;
uint8_t Spare4;
uint8_t Spare5[2];
uint32_t MinGfxClk;
uint32_t MaxGfxClk;
uint32_t Spare6[8];
uint32_t Spare7[8];
uint32_t Spare8[8];
uint32_t Spare9[8];
} DpmClocks_t_v15_0_5;
typedef struct {
uint16_t CoreFrequency[16]; //Target core frequency [MHz]
uint16_t CorePower[16]; //CAC calculated core power [mW]

View File

@ -110,8 +110,10 @@
#define PPSMC_MSG_GetSlowPPTLimit 0x4C
#define PPSMC_MSG_GetGfxOffStatus 0x50
#define PPSMC_MSG_GetGfxOffEntryCount 0x51
#define PPSMC_MSG_LogGfxOffResidency 0x52
#define PPSMC_Message_Count 0x53
#define PPSMC_MSG_GfxOffResidencyLogReadSample 0x52
#define PPSMC_MSG_StopGfxOffResidencyLogging 0x53
#define PPSMC_MSG_StartGfxOffResidencyLogging 0x56
#define PPSMC_Message_Count 0x57
//Argument for PPSMC_MSG_GfxDeviceDriverReset
enum {

View File

@ -252,7 +252,9 @@
__SMU_DUMMY_MAP(DriverMode2Reset), \
__SMU_DUMMY_MAP(GetGfxOffStatus), \
__SMU_DUMMY_MAP(GetGfxOffEntryCount), \
__SMU_DUMMY_MAP(LogGfxOffResidency), \
__SMU_DUMMY_MAP(StartGfxOffResidencyLogging), \
__SMU_DUMMY_MAP(GfxOffResidencyLogReadSample), \
__SMU_DUMMY_MAP(StopGfxOffResidencyLogging), \
__SMU_DUMMY_MAP(SetNumBadMemoryPagesRetired), \
__SMU_DUMMY_MAP(SetBadMemoryPagesRetiredFlagsPerChannel), \
__SMU_DUMMY_MAP(AllowGpo), \

View File

@ -26,7 +26,7 @@
#include "amdgpu_smu.h"
#define SMU15_DRIVER_IF_VERSION_INV 0xFFFFFFFF
#define SMU15_DRIVER_IF_VERSION_SMU_V15_0 0x7
#define SMU15_DRIVER_IF_VERSION_SMU_V15_0 0x9
#define FEATURE_MASK(feature) (1ULL << feature)

View File

@ -658,7 +658,7 @@ static int arcturus_get_smu_metrics_data(struct smu_context *smu,
*value = metrics->VcnActivityPercentage;
break;
case METRICS_AVERAGE_SOCKETPOWER:
*value = metrics->AverageSocketPower << 8;
*value = metrics->AverageSocketPower * MILLIWATT_PER_WATT;
break;
case METRICS_TEMPERATURE_EDGE:
*value = metrics->TemperatureEdge *

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