mirror of
https://github.com/torvalds/linux.git
synced 2026-09-13 15:40:03 +02:00
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:
commit
1962afd211
3
.mailmap
3
.mailmap
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -10,3 +10,4 @@ Description:
|
|||
0 no adjustment of input current limit. This
|
||||
helps for more unusual power sources like
|
||||
solar modules.
|
||||
============ ===========================================
|
||||
|
|
|
|||
|
|
@ -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
|
||||
~~~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -135,7 +135,6 @@ properties:
|
|||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
23
MAINTAINERS
23
MAINTAINERS
|
|
@ -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
|
||||
|
|
|
|||
10
Makefile
10
Makefile
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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>,
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ memory@0 {
|
|||
|
||||
nvram@1c080000 {
|
||||
compatible = "brcm,nvram";
|
||||
reg = <0x1c080000 0x180000>;
|
||||
reg = <0x1c080000 0x100000>;
|
||||
|
||||
et2macaddr: et2macaddr {
|
||||
#nvmem-cell-cells = <1>;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)>;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
|
|
|
|||
|
|
@ -7384,6 +7384,7 @@ intc: interrupt-controller@17a00000 {
|
|||
interrupt-controller;
|
||||
#redistributor-regions = <1>;
|
||||
redistributor-stride = <0x0 0x20000>;
|
||||
#address-cells = <0>;
|
||||
};
|
||||
|
||||
watchdog@17c10000 {
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
|
|
|
|||
|
|
@ -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>,
|
||||
|
|
|
|||
|
|
@ -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>,
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 ||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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), \
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue
Block a user