mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 14:04:54 +02:00
Merge 0f4498cef9 ("Merge tag 'for-5.12/dm-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm") into android-mainline
Steps on the way to 5.12-rc5 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I2f8825c0e6366342aba6ed87a576b04efabef921
This commit is contained in:
commit
36203b431a
37
MAINTAINERS
37
MAINTAINERS
|
|
@ -2489,7 +2489,7 @@ N: sc27xx
|
|||
N: sc2731
|
||||
|
||||
ARM/STI ARCHITECTURE
|
||||
M: Patrice Chotard <patrice.chotard@st.com>
|
||||
M: Patrice Chotard <patrice.chotard@foss.st.com>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
W: http://www.stlinux.com
|
||||
|
|
@ -2522,7 +2522,7 @@ F: include/linux/remoteproc/st_slim_rproc.h
|
|||
|
||||
ARM/STM32 ARCHITECTURE
|
||||
M: Maxime Coquelin <mcoquelin.stm32@gmail.com>
|
||||
M: Alexandre Torgue <alexandre.torgue@st.com>
|
||||
M: Alexandre Torgue <alexandre.torgue@foss.st.com>
|
||||
L: linux-stm32@st-md-mailman.stormreply.com (moderated for non-subscribers)
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
|
|
@ -3115,7 +3115,7 @@ C: irc://irc.oftc.net/bcache
|
|||
F: drivers/md/bcache/
|
||||
|
||||
BDISP ST MEDIA DRIVER
|
||||
M: Fabien Dessenne <fabien.dessenne@st.com>
|
||||
M: Fabien Dessenne <fabien.dessenne@foss.st.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://linuxtv.org
|
||||
|
|
@ -3675,7 +3675,7 @@ M: bcm-kernel-feedback-list@broadcom.com
|
|||
L: linux-pm@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://github.com/broadcom/stblinux.git
|
||||
F: drivers/soc/bcm/bcm-pmb.c
|
||||
F: drivers/soc/bcm/bcm63xx/bcm-pmb.c
|
||||
F: include/dt-bindings/soc/bcm-pmb.h
|
||||
|
||||
BROADCOM SPECIFIC AMBA DRIVER (BCMA)
|
||||
|
|
@ -5080,7 +5080,7 @@ S: Maintained
|
|||
F: drivers/platform/x86/dell/dell-wmi.c
|
||||
|
||||
DELTA ST MEDIA DRIVER
|
||||
M: Hugues Fruchet <hugues.fruchet@st.com>
|
||||
M: Hugues Fruchet <hugues.fruchet@foss.st.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://linuxtv.org
|
||||
|
|
@ -6006,7 +6006,6 @@ F: drivers/gpu/drm/rockchip/
|
|||
|
||||
DRM DRIVERS FOR STI
|
||||
M: Benjamin Gaignard <benjamin.gaignard@linaro.org>
|
||||
M: Vincent Abriou <vincent.abriou@st.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Maintained
|
||||
T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||
|
|
@ -6014,10 +6013,9 @@ F: Documentation/devicetree/bindings/display/st,stih4xx.txt
|
|||
F: drivers/gpu/drm/sti
|
||||
|
||||
DRM DRIVERS FOR STM
|
||||
M: Yannick Fertre <yannick.fertre@st.com>
|
||||
M: Philippe Cornu <philippe.cornu@st.com>
|
||||
M: Yannick Fertre <yannick.fertre@foss.st.com>
|
||||
M: Philippe Cornu <philippe.cornu@foss.st.com>
|
||||
M: Benjamin Gaignard <benjamin.gaignard@linaro.org>
|
||||
M: Vincent Abriou <vincent.abriou@st.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Maintained
|
||||
T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||
|
|
@ -8230,7 +8228,7 @@ F: include/linux/hugetlb.h
|
|||
F: mm/hugetlb.c
|
||||
|
||||
HVA ST MEDIA DRIVER
|
||||
M: Jean-Christophe Trotin <jean-christophe.trotin@st.com>
|
||||
M: Jean-Christophe Trotin <jean-christophe.trotin@foss.st.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://linuxtv.org
|
||||
|
|
@ -10037,7 +10035,6 @@ F: scripts/leaking_addresses.pl
|
|||
|
||||
LED SUBSYSTEM
|
||||
M: Pavel Machek <pavel@ucw.cz>
|
||||
R: Dan Murphy <dmurphy@ti.com>
|
||||
L: linux-leds@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds.git
|
||||
|
|
@ -10913,7 +10910,6 @@ T: git git://linuxtv.org/media_tree.git
|
|||
F: drivers/media/radio/radio-maxiradio*
|
||||
|
||||
MCAN MMIO DEVICE DRIVER
|
||||
M: Dan Murphy <dmurphy@ti.com>
|
||||
M: Pankaj Sharma <pankj.sharma@samsung.com>
|
||||
L: linux-can@vger.kernel.org
|
||||
S: Maintained
|
||||
|
|
@ -11174,7 +11170,7 @@ T: git git://linuxtv.org/media_tree.git
|
|||
F: drivers/media/dvb-frontends/stv6111*
|
||||
|
||||
MEDIA DRIVERS FOR STM32 - DCMI
|
||||
M: Hugues Fruchet <hugues.fruchet@st.com>
|
||||
M: Hugues Fruchet <hugues.fruchet@foss.st.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Supported
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
|
|
@ -16953,7 +16949,8 @@ F: Documentation/devicetree/bindings/media/i2c/st,st-mipid02.txt
|
|||
F: drivers/media/i2c/st-mipid02.c
|
||||
|
||||
ST STM32 I2C/SMBUS DRIVER
|
||||
M: Pierre-Yves MORDRET <pierre-yves.mordret@st.com>
|
||||
M: Pierre-Yves MORDRET <pierre-yves.mordret@foss.st.com>
|
||||
M: Alain Volmat <alain.volmat@foss.st.com>
|
||||
L: linux-i2c@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/i2c/busses/i2c-stm32*
|
||||
|
|
@ -17078,7 +17075,7 @@ F: kernel/jump_label.c
|
|||
F: kernel/static_call.c
|
||||
|
||||
STI AUDIO (ASoC) DRIVERS
|
||||
M: Arnaud Pouliquen <arnaud.pouliquen@st.com>
|
||||
M: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
|
||||
|
|
@ -17098,15 +17095,15 @@ T: git git://linuxtv.org/media_tree.git
|
|||
F: drivers/media/usb/stk1160/
|
||||
|
||||
STM32 AUDIO (ASoC) DRIVERS
|
||||
M: Olivier Moysan <olivier.moysan@st.com>
|
||||
M: Arnaud Pouliquen <arnaud.pouliquen@st.com>
|
||||
M: Olivier Moysan <olivier.moysan@foss.st.com>
|
||||
M: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/iio/adc/st,stm32-*.yaml
|
||||
F: sound/soc/stm/
|
||||
|
||||
STM32 TIMER/LPTIMER DRIVERS
|
||||
M: Fabrice Gasnier <fabrice.gasnier@st.com>
|
||||
M: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
|
||||
S: Maintained
|
||||
F: Documentation/ABI/testing/*timer-stm32
|
||||
F: Documentation/devicetree/bindings/*/*stm32-*timer*
|
||||
|
|
@ -17116,7 +17113,7 @@ F: include/linux/*/stm32-*tim*
|
|||
|
||||
STMMAC ETHERNET DRIVER
|
||||
M: Giuseppe Cavallaro <peppe.cavallaro@st.com>
|
||||
M: Alexandre Torgue <alexandre.torgue@st.com>
|
||||
M: Alexandre Torgue <alexandre.torgue@foss.st.com>
|
||||
M: Jose Abreu <joabreu@synopsys.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
|
|
@ -17858,7 +17855,6 @@ S: Maintained
|
|||
F: drivers/thermal/ti-soc-thermal/
|
||||
|
||||
TI BQ27XXX POWER SUPPLY DRIVER
|
||||
R: Dan Murphy <dmurphy@ti.com>
|
||||
F: drivers/power/supply/bq27xxx_battery.c
|
||||
F: drivers/power/supply/bq27xxx_battery_i2c.c
|
||||
F: include/linux/power/bq27xxx_battery.h
|
||||
|
|
@ -17993,7 +17989,6 @@ S: Odd Fixes
|
|||
F: sound/soc/codecs/tas571x*
|
||||
|
||||
TI TCAN4X5X DEVICE DRIVER
|
||||
M: Dan Murphy <dmurphy@ti.com>
|
||||
L: linux-can@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/can/tcan4x5x.txt
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ aliases {
|
|||
ethernet1 = &cpsw_emac1;
|
||||
spi0 = &spi0;
|
||||
spi1 = &spi1;
|
||||
mmc0 = &mmc1;
|
||||
mmc1 = &mmc2;
|
||||
mmc2 = &mmc3;
|
||||
};
|
||||
|
||||
cpus {
|
||||
|
|
|
|||
|
|
@ -334,14 +334,6 @@ ethernet-phy@0 {
|
|||
};
|
||||
|
||||
&pinctrl {
|
||||
atmel,mux-mask = <
|
||||
/* A B C */
|
||||
0xFFFFFE7F 0xC0E0397F 0xEF00019D /* pioA */
|
||||
0x03FFFFFF 0x02FC7E68 0x00780000 /* pioB */
|
||||
0xffffffff 0xF83FFFFF 0xB800F3FC /* pioC */
|
||||
0x003FFFFF 0x003F8000 0x00000000 /* pioD */
|
||||
>;
|
||||
|
||||
adc {
|
||||
pinctrl_adc_default: adc_default {
|
||||
atmel,pins = <AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE>;
|
||||
|
|
|
|||
|
|
@ -84,8 +84,8 @@ macb0: ethernet@f8008000 {
|
|||
pinctrl-0 = <&pinctrl_macb0_default>;
|
||||
phy-mode = "rmii";
|
||||
|
||||
ethernet-phy@0 {
|
||||
reg = <0x0>;
|
||||
ethernet-phy@7 {
|
||||
reg = <0x7>;
|
||||
interrupt-parent = <&pioA>;
|
||||
interrupts = <PIN_PD31 IRQ_TYPE_LEVEL_LOW>;
|
||||
pinctrl-names = "default";
|
||||
|
|
|
|||
|
|
@ -210,9 +210,6 @@ ethphy0: ethernet-phy@2 {
|
|||
micrel,led-mode = <1>;
|
||||
clocks = <&clks IMX6UL_CLK_ENET_REF>;
|
||||
clock-names = "rmii-ref";
|
||||
reset-gpios = <&gpio_spi 1 GPIO_ACTIVE_LOW>;
|
||||
reset-assert-us = <10000>;
|
||||
reset-deassert-us = <100>;
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -222,9 +219,6 @@ ethphy1: ethernet-phy@1 {
|
|||
micrel,led-mode = <1>;
|
||||
clocks = <&clks IMX6UL_CLK_ENET2_REF>;
|
||||
clock-names = "rmii-ref";
|
||||
reset-gpios = <&gpio_spi 2 GPIO_ACTIVE_LOW>;
|
||||
reset-assert-us = <10000>;
|
||||
reset-deassert-us = <100>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -243,6 +237,22 @@ &can2 {
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio_spi {
|
||||
eth0-phy-hog {
|
||||
gpio-hog;
|
||||
gpios = <1 GPIO_ACTIVE_HIGH>;
|
||||
output-high;
|
||||
line-name = "eth0-phy";
|
||||
};
|
||||
|
||||
eth1-phy-hog {
|
||||
gpio-hog;
|
||||
gpios = <2 GPIO_ACTIVE_HIGH>;
|
||||
output-high;
|
||||
line-name = "eth1-phy";
|
||||
};
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
clock-frequency = <100000>;
|
||||
pinctrl-names = "default";
|
||||
|
|
|
|||
|
|
@ -14,5 +14,6 @@ / {
|
|||
};
|
||||
|
||||
&gpmi {
|
||||
fsl,use-minimum-ecc;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -606,6 +606,15 @@ pinctrl: pinctrl@fffff400 {
|
|||
compatible = "microchip,sam9x60-pinctrl", "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus";
|
||||
ranges = <0xfffff400 0xfffff400 0x800>;
|
||||
|
||||
/* mux-mask corresponding to sam9x60 SoC in TFBGA228L package */
|
||||
atmel,mux-mask = <
|
||||
/* A B C */
|
||||
0xffffffff 0xffe03fff 0xef00019d /* pioA */
|
||||
0x03ffffff 0x02fc7e7f 0x00780000 /* pioB */
|
||||
0xffffffff 0xffffffff 0xf83fffff /* pioC */
|
||||
0x003fffff 0x003f8000 0x00000000 /* pioD */
|
||||
>;
|
||||
|
||||
pioA: gpio@fffff400 {
|
||||
compatible = "microchip,sam9x60-gpio", "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
|
||||
reg = <0xfffff400 0x200>;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/irqchip.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
|
|
@ -162,7 +163,7 @@ static void __exception_irq_entry avic_handle_irq(struct pt_regs *regs)
|
|||
* interrupts. It registers the interrupt enable and disable functions
|
||||
* to the kernel for each interrupt source.
|
||||
*/
|
||||
void __init mxc_init_irq(void __iomem *irqbase)
|
||||
static void __init mxc_init_irq(void __iomem *irqbase)
|
||||
{
|
||||
struct device_node *np;
|
||||
int irq_base;
|
||||
|
|
@ -220,3 +221,16 @@ void __init mxc_init_irq(void __iomem *irqbase)
|
|||
|
||||
printk(KERN_INFO "MXC IRQ initialized\n");
|
||||
}
|
||||
|
||||
static int __init imx_avic_init(struct device_node *node,
|
||||
struct device_node *parent)
|
||||
{
|
||||
void __iomem *avic_base;
|
||||
|
||||
avic_base = of_iomap(node, 0);
|
||||
BUG_ON(!avic_base);
|
||||
mxc_init_irq(avic_base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
IRQCHIP_DECLARE(imx_avic, "fsl,avic", imx_avic_init);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ void mx35_map_io(void);
|
|||
void imx21_init_early(void);
|
||||
void imx31_init_early(void);
|
||||
void imx35_init_early(void);
|
||||
void mxc_init_irq(void __iomem *);
|
||||
void mx31_init_irq(void);
|
||||
void mx35_init_irq(void);
|
||||
void mxc_set_cpu_type(unsigned int type);
|
||||
|
|
|
|||
|
|
@ -17,16 +17,6 @@ static void __init imx1_init_early(void)
|
|||
mxc_set_cpu_type(MXC_CPU_MX1);
|
||||
}
|
||||
|
||||
static void __init imx1_init_irq(void)
|
||||
{
|
||||
void __iomem *avic_addr;
|
||||
|
||||
avic_addr = ioremap(MX1_AVIC_ADDR, SZ_4K);
|
||||
WARN_ON(!avic_addr);
|
||||
|
||||
mxc_init_irq(avic_addr);
|
||||
}
|
||||
|
||||
static const char * const imx1_dt_board_compat[] __initconst = {
|
||||
"fsl,imx1",
|
||||
NULL
|
||||
|
|
@ -34,7 +24,6 @@ static const char * const imx1_dt_board_compat[] __initconst = {
|
|||
|
||||
DT_MACHINE_START(IMX1_DT, "Freescale i.MX1 (Device Tree Support)")
|
||||
.init_early = imx1_init_early,
|
||||
.init_irq = imx1_init_irq,
|
||||
.dt_compat = imx1_dt_board_compat,
|
||||
.restart = mxc_restart,
|
||||
MACHINE_END
|
||||
|
|
|
|||
|
|
@ -22,17 +22,6 @@ static void __init imx25_dt_init(void)
|
|||
imx_aips_allow_unprivileged_access("fsl,imx25-aips");
|
||||
}
|
||||
|
||||
static void __init mx25_init_irq(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
void __iomem *avic_base;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,avic");
|
||||
avic_base = of_iomap(np, 0);
|
||||
BUG_ON(!avic_base);
|
||||
mxc_init_irq(avic_base);
|
||||
}
|
||||
|
||||
static const char * const imx25_dt_board_compat[] __initconst = {
|
||||
"fsl,imx25",
|
||||
NULL
|
||||
|
|
@ -42,6 +31,5 @@ DT_MACHINE_START(IMX25_DT, "Freescale i.MX25 (Device Tree Support)")
|
|||
.init_early = imx25_init_early,
|
||||
.init_machine = imx25_dt_init,
|
||||
.init_late = imx25_pm_init,
|
||||
.init_irq = mx25_init_irq,
|
||||
.dt_compat = imx25_dt_board_compat,
|
||||
MACHINE_END
|
||||
|
|
|
|||
|
|
@ -56,17 +56,6 @@ static void __init imx27_init_early(void)
|
|||
mxc_set_cpu_type(MXC_CPU_MX27);
|
||||
}
|
||||
|
||||
static void __init mx27_init_irq(void)
|
||||
{
|
||||
void __iomem *avic_base;
|
||||
struct device_node *np;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,avic");
|
||||
avic_base = of_iomap(np, 0);
|
||||
BUG_ON(!avic_base);
|
||||
mxc_init_irq(avic_base);
|
||||
}
|
||||
|
||||
static const char * const imx27_dt_board_compat[] __initconst = {
|
||||
"fsl,imx27",
|
||||
NULL
|
||||
|
|
@ -75,7 +64,6 @@ static const char * const imx27_dt_board_compat[] __initconst = {
|
|||
DT_MACHINE_START(IMX27_DT, "Freescale i.MX27 (Device Tree Support)")
|
||||
.map_io = mx27_map_io,
|
||||
.init_early = imx27_init_early,
|
||||
.init_irq = mx27_init_irq,
|
||||
.init_late = imx27_pm_init,
|
||||
.dt_compat = imx27_dt_board_compat,
|
||||
MACHINE_END
|
||||
|
|
|
|||
|
|
@ -14,6 +14,5 @@ static const char * const imx31_dt_board_compat[] __initconst = {
|
|||
DT_MACHINE_START(IMX31_DT, "Freescale i.MX31 (Device Tree Support)")
|
||||
.map_io = mx31_map_io,
|
||||
.init_early = imx31_init_early,
|
||||
.init_irq = mx31_init_irq,
|
||||
.dt_compat = imx31_dt_board_compat,
|
||||
MACHINE_END
|
||||
|
|
|
|||
|
|
@ -27,6 +27,5 @@ DT_MACHINE_START(IMX35_DT, "Freescale i.MX35 (Device Tree Support)")
|
|||
.l2c_aux_mask = ~0,
|
||||
.map_io = mx35_map_io,
|
||||
.init_early = imx35_init_early,
|
||||
.init_irq = mx35_init_irq,
|
||||
.dt_compat = imx35_dt_board_compat,
|
||||
MACHINE_END
|
||||
|
|
|
|||
|
|
@ -109,18 +109,6 @@ void __init imx31_init_early(void)
|
|||
mx3_ccm_base = of_iomap(np, 0);
|
||||
BUG_ON(!mx3_ccm_base);
|
||||
}
|
||||
|
||||
void __init mx31_init_irq(void)
|
||||
{
|
||||
void __iomem *avic_base;
|
||||
struct device_node *np;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx31-avic");
|
||||
avic_base = of_iomap(np, 0);
|
||||
BUG_ON(!avic_base);
|
||||
|
||||
mxc_init_irq(avic_base);
|
||||
}
|
||||
#endif /* ifdef CONFIG_SOC_IMX31 */
|
||||
|
||||
#ifdef CONFIG_SOC_IMX35
|
||||
|
|
@ -158,16 +146,4 @@ void __init imx35_init_early(void)
|
|||
mx3_ccm_base = of_iomap(np, 0);
|
||||
BUG_ON(!mx3_ccm_base);
|
||||
}
|
||||
|
||||
void __init mx35_init_irq(void)
|
||||
{
|
||||
void __iomem *avic_base;
|
||||
struct device_node *np;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx35-avic");
|
||||
avic_base = of_iomap(np, 0);
|
||||
BUG_ON(!avic_base);
|
||||
|
||||
mxc_init_irq(avic_base);
|
||||
}
|
||||
#endif /* ifdef CONFIG_SOC_IMX35 */
|
||||
|
|
|
|||
|
|
@ -88,34 +88,26 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
|
|||
|
||||
extern struct omap_sr_data omap_sr_pdata[];
|
||||
|
||||
static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
|
||||
static int __init sr_init_by_name(const char *name, const char *voltdm)
|
||||
{
|
||||
struct omap_sr_data *sr_data = NULL;
|
||||
struct omap_volt_data *volt_data;
|
||||
struct omap_smartreflex_dev_attr *sr_dev_attr;
|
||||
static int i;
|
||||
|
||||
if (!strncmp(oh->name, "smartreflex_mpu_iva", 20) ||
|
||||
!strncmp(oh->name, "smartreflex_mpu", 16))
|
||||
if (!strncmp(name, "smartreflex_mpu_iva", 20) ||
|
||||
!strncmp(name, "smartreflex_mpu", 16))
|
||||
sr_data = &omap_sr_pdata[OMAP_SR_MPU];
|
||||
else if (!strncmp(oh->name, "smartreflex_core", 17))
|
||||
else if (!strncmp(name, "smartreflex_core", 17))
|
||||
sr_data = &omap_sr_pdata[OMAP_SR_CORE];
|
||||
else if (!strncmp(oh->name, "smartreflex_iva", 16))
|
||||
else if (!strncmp(name, "smartreflex_iva", 16))
|
||||
sr_data = &omap_sr_pdata[OMAP_SR_IVA];
|
||||
|
||||
if (!sr_data) {
|
||||
pr_err("%s: Unknown instance %s\n", __func__, oh->name);
|
||||
pr_err("%s: Unknown instance %s\n", __func__, name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr;
|
||||
if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) {
|
||||
pr_err("%s: No voltage domain specified for %s. Cannot initialize\n",
|
||||
__func__, oh->name);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
sr_data->name = oh->name;
|
||||
sr_data->name = name;
|
||||
if (cpu_is_omap343x())
|
||||
sr_data->ip_type = 1;
|
||||
else
|
||||
|
|
@ -136,10 +128,10 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
|
|||
}
|
||||
}
|
||||
|
||||
sr_data->voltdm = voltdm_lookup(sr_dev_attr->sensor_voltdm_name);
|
||||
sr_data->voltdm = voltdm_lookup(voltdm);
|
||||
if (!sr_data->voltdm) {
|
||||
pr_err("%s: Unable to get voltage domain pointer for VDD %s\n",
|
||||
__func__, sr_dev_attr->sensor_voltdm_name);
|
||||
__func__, voltdm);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
|
@ -160,6 +152,20 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
|
||||
{
|
||||
struct omap_smartreflex_dev_attr *sr_dev_attr;
|
||||
|
||||
sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr;
|
||||
if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) {
|
||||
pr_err("%s: No voltage domain specified for %s. Cannot initialize\n",
|
||||
__func__, oh->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sr_init_by_name(oh->name, sr_dev_attr->sensor_voltdm_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* API to be called from board files to enable smartreflex
|
||||
* autocompensation at init.
|
||||
|
|
@ -169,7 +175,42 @@ void __init omap_enable_smartreflex_on_init(void)
|
|||
sr_enable_on_init = true;
|
||||
}
|
||||
|
||||
static const char * const omap4_sr_instances[] = {
|
||||
"mpu",
|
||||
"iva",
|
||||
"core",
|
||||
};
|
||||
|
||||
static const char * const dra7_sr_instances[] = {
|
||||
"mpu",
|
||||
"core",
|
||||
};
|
||||
|
||||
int __init omap_devinit_smartreflex(void)
|
||||
{
|
||||
const char * const *sr_inst;
|
||||
int i, nr_sr = 0;
|
||||
|
||||
if (soc_is_omap44xx()) {
|
||||
sr_inst = omap4_sr_instances;
|
||||
nr_sr = ARRAY_SIZE(omap4_sr_instances);
|
||||
|
||||
} else if (soc_is_dra7xx()) {
|
||||
sr_inst = dra7_sr_instances;
|
||||
nr_sr = ARRAY_SIZE(dra7_sr_instances);
|
||||
}
|
||||
|
||||
if (nr_sr) {
|
||||
const char *name, *voltdm;
|
||||
|
||||
for (i = 0; i < nr_sr; i++) {
|
||||
name = kasprintf(GFP_KERNEL, "smartreflex_%s", sr_inst[i]);
|
||||
voltdm = sr_inst[i];
|
||||
sr_init_by_name(name, voltdm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return omap_hwmod_for_each_by_class("smartreflex", sr_dev_init, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ crypto: crypto@1700000 {
|
|||
ranges = <0x0 0x00 0x1700000 0x100000>;
|
||||
reg = <0x00 0x1700000 0x0 0x100000>;
|
||||
interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dma-coherent;
|
||||
|
||||
sec_jr0: jr@10000 {
|
||||
compatible = "fsl,sec-v5.4-job-ring",
|
||||
|
|
|
|||
|
|
@ -348,6 +348,7 @@ crypto: crypto@1700000 {
|
|||
ranges = <0x0 0x00 0x1700000 0x100000>;
|
||||
reg = <0x00 0x1700000 0x0 0x100000>;
|
||||
interrupts = <0 75 0x4>;
|
||||
dma-coherent;
|
||||
|
||||
sec_jr0: jr@10000 {
|
||||
compatible = "fsl,sec-v5.4-job-ring",
|
||||
|
|
|
|||
|
|
@ -354,6 +354,7 @@ crypto: crypto@1700000 {
|
|||
ranges = <0x0 0x00 0x1700000 0x100000>;
|
||||
reg = <0x00 0x1700000 0x0 0x100000>;
|
||||
interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dma-coherent;
|
||||
|
||||
sec_jr0: jr@10000 {
|
||||
compatible = "fsl,sec-v5.4-job-ring",
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ reg_usdhc2_vmmc: regulator-usdhc2 {
|
|||
|
||||
&i2c2 {
|
||||
clock-frequency = <400000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-names = "default", "gpio";
|
||||
pinctrl-0 = <&pinctrl_i2c2>;
|
||||
pinctrl-1 = <&pinctrl_i2c2_gpio>;
|
||||
sda-gpios = <&gpio5 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ ethphy1: ethernet-phy@0 {
|
|||
|
||||
&i2c1 {
|
||||
clock-frequency = <400000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-names = "default", "gpio";
|
||||
pinctrl-0 = <&pinctrl_i2c1>;
|
||||
pinctrl-1 = <&pinctrl_i2c1_gpio>;
|
||||
sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
|
||||
|
|
|
|||
|
|
@ -86,18 +86,6 @@ clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The maximum amount of extra memory compared to the base size. The
|
||||
* main scaling factor is the size of struct page. At extreme ratios
|
||||
* of base:extra, all the base memory can be filled with page
|
||||
* structures for the extra memory, leaving no space for anything
|
||||
* else.
|
||||
*
|
||||
* 10x seems like a reasonable balance between scaling flexibility and
|
||||
* leaving a practically usable system.
|
||||
*/
|
||||
#define XEN_EXTRA_MEM_RATIO (10)
|
||||
|
||||
/*
|
||||
* Helper functions to write or read unsigned long values to/from
|
||||
* memory, when the access may fault.
|
||||
|
|
|
|||
|
|
@ -98,8 +98,8 @@ EXPORT_SYMBOL_GPL(xen_p2m_size);
|
|||
unsigned long xen_max_p2m_pfn __read_mostly;
|
||||
EXPORT_SYMBOL_GPL(xen_max_p2m_pfn);
|
||||
|
||||
#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG_LIMIT
|
||||
#define P2M_LIMIT CONFIG_XEN_BALLOON_MEMORY_HOTPLUG_LIMIT
|
||||
#ifdef CONFIG_XEN_MEMORY_HOTPLUG_LIMIT
|
||||
#define P2M_LIMIT CONFIG_XEN_MEMORY_HOTPLUG_LIMIT
|
||||
#else
|
||||
#define P2M_LIMIT 0
|
||||
#endif
|
||||
|
|
@ -416,9 +416,6 @@ void __init xen_vmalloc_p2m_tree(void)
|
|||
xen_p2m_last_pfn = xen_max_p2m_pfn;
|
||||
|
||||
p2m_limit = (phys_addr_t)P2M_LIMIT * 1024 * 1024 * 1024 / PAGE_SIZE;
|
||||
if (!p2m_limit && IS_ENABLED(CONFIG_XEN_UNPOPULATED_ALLOC))
|
||||
p2m_limit = xen_start_info->nr_pages * XEN_EXTRA_MEM_RATIO;
|
||||
|
||||
vm.flags = VM_ALLOC;
|
||||
vm.size = ALIGN(sizeof(unsigned long) * max(xen_max_p2m_pfn, p2m_limit),
|
||||
PMD_SIZE * PMDS_PER_MID_PAGE);
|
||||
|
|
|
|||
|
|
@ -59,6 +59,18 @@ static struct {
|
|||
} xen_remap_buf __initdata __aligned(PAGE_SIZE);
|
||||
static unsigned long xen_remap_mfn __initdata = INVALID_P2M_ENTRY;
|
||||
|
||||
/*
|
||||
* The maximum amount of extra memory compared to the base size. The
|
||||
* main scaling factor is the size of struct page. At extreme ratios
|
||||
* of base:extra, all the base memory can be filled with page
|
||||
* structures for the extra memory, leaving no space for anything
|
||||
* else.
|
||||
*
|
||||
* 10x seems like a reasonable balance between scaling flexibility and
|
||||
* leaving a practically usable system.
|
||||
*/
|
||||
#define EXTRA_MEM_RATIO (10)
|
||||
|
||||
static bool xen_512gb_limit __initdata = IS_ENABLED(CONFIG_XEN_512GB);
|
||||
|
||||
static void __init xen_parse_512gb(void)
|
||||
|
|
@ -778,13 +790,13 @@ char * __init xen_memory_setup(void)
|
|||
extra_pages += max_pages - max_pfn;
|
||||
|
||||
/*
|
||||
* Clamp the amount of extra memory to a XEN_EXTRA_MEM_RATIO
|
||||
* Clamp the amount of extra memory to a EXTRA_MEM_RATIO
|
||||
* factor the base size.
|
||||
*
|
||||
* Make sure we have no memory above max_pages, as this area
|
||||
* isn't handled by the p2m management.
|
||||
*/
|
||||
extra_pages = min3(XEN_EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)),
|
||||
extra_pages = min3(EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)),
|
||||
extra_pages, max_pages - max_pfn);
|
||||
i = 0;
|
||||
addr = xen_e820_table.entries[0].addr;
|
||||
|
|
|
|||
|
|
@ -99,13 +99,12 @@ acpi_status acpi_ns_root_initialize(void)
|
|||
* just create and link the new node(s) here.
|
||||
*/
|
||||
new_node =
|
||||
ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_namespace_node));
|
||||
acpi_ns_create_node(*ACPI_CAST_PTR(u32, init_val->name));
|
||||
if (!new_node) {
|
||||
status = AE_NO_MEMORY;
|
||||
goto unlock_and_exit;
|
||||
}
|
||||
|
||||
ACPI_COPY_NAMESEG(new_node->name.ascii, init_val->name);
|
||||
new_node->descriptor_type = ACPI_DESC_TYPE_NAMED;
|
||||
new_node->type = init_val->type;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
#ifndef _ACPI_INTERNAL_H_
|
||||
#define _ACPI_INTERNAL_H_
|
||||
|
||||
#include <linux/idr.h>
|
||||
|
||||
#define PREFIX "ACPI: "
|
||||
|
||||
int early_acpi_osi_init(void);
|
||||
|
|
@ -96,9 +98,11 @@ void acpi_scan_table_handler(u32 event, void *table, void *context);
|
|||
|
||||
extern struct list_head acpi_bus_id_list;
|
||||
|
||||
#define ACPI_MAX_DEVICE_INSTANCES 4096
|
||||
|
||||
struct acpi_device_bus_id {
|
||||
const char *bus_id;
|
||||
unsigned int instance_no;
|
||||
struct ida instance_ida;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -479,9 +479,8 @@ static void acpi_device_del(struct acpi_device *device)
|
|||
list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node)
|
||||
if (!strcmp(acpi_device_bus_id->bus_id,
|
||||
acpi_device_hid(device))) {
|
||||
if (acpi_device_bus_id->instance_no > 0)
|
||||
acpi_device_bus_id->instance_no--;
|
||||
else {
|
||||
ida_simple_remove(&acpi_device_bus_id->instance_ida, device->pnp.instance_no);
|
||||
if (ida_is_empty(&acpi_device_bus_id->instance_ida)) {
|
||||
list_del(&acpi_device_bus_id->node);
|
||||
kfree_const(acpi_device_bus_id->bus_id);
|
||||
kfree(acpi_device_bus_id);
|
||||
|
|
@ -631,6 +630,21 @@ static struct acpi_device_bus_id *acpi_device_bus_id_match(const char *dev_id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int acpi_device_set_name(struct acpi_device *device,
|
||||
struct acpi_device_bus_id *acpi_device_bus_id)
|
||||
{
|
||||
struct ida *instance_ida = &acpi_device_bus_id->instance_ida;
|
||||
int result;
|
||||
|
||||
result = ida_simple_get(instance_ida, 0, ACPI_MAX_DEVICE_INSTANCES, GFP_KERNEL);
|
||||
if (result < 0)
|
||||
return result;
|
||||
|
||||
device->pnp.instance_no = result;
|
||||
dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acpi_device_add(struct acpi_device *device,
|
||||
void (*release)(struct device *))
|
||||
{
|
||||
|
|
@ -665,7 +679,9 @@ int acpi_device_add(struct acpi_device *device,
|
|||
|
||||
acpi_device_bus_id = acpi_device_bus_id_match(acpi_device_hid(device));
|
||||
if (acpi_device_bus_id) {
|
||||
acpi_device_bus_id->instance_no++;
|
||||
result = acpi_device_set_name(device, acpi_device_bus_id);
|
||||
if (result)
|
||||
goto err_unlock;
|
||||
} else {
|
||||
acpi_device_bus_id = kzalloc(sizeof(*acpi_device_bus_id),
|
||||
GFP_KERNEL);
|
||||
|
|
@ -681,9 +697,16 @@ int acpi_device_add(struct acpi_device *device,
|
|||
goto err_unlock;
|
||||
}
|
||||
|
||||
ida_init(&acpi_device_bus_id->instance_ida);
|
||||
|
||||
result = acpi_device_set_name(device, acpi_device_bus_id);
|
||||
if (result) {
|
||||
kfree(acpi_device_bus_id);
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list);
|
||||
}
|
||||
dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);
|
||||
|
||||
if (device->parent)
|
||||
list_add_tail(&device->node, &device->parent->children);
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
|||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
.ident = "Sony VPCEH3U1E",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ static int rpm_get_suppliers(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void rpm_put_suppliers(struct device *dev)
|
||||
static void __rpm_put_suppliers(struct device *dev, bool try_to_suspend)
|
||||
{
|
||||
struct device_link *link;
|
||||
|
||||
|
|
@ -313,10 +313,30 @@ static void rpm_put_suppliers(struct device *dev)
|
|||
device_links_read_lock_held()) {
|
||||
|
||||
while (refcount_dec_not_one(&link->rpm_active))
|
||||
pm_runtime_put(link->supplier);
|
||||
pm_runtime_put_noidle(link->supplier);
|
||||
|
||||
if (try_to_suspend)
|
||||
pm_request_idle(link->supplier);
|
||||
}
|
||||
}
|
||||
|
||||
static void rpm_put_suppliers(struct device *dev)
|
||||
{
|
||||
__rpm_put_suppliers(dev, true);
|
||||
}
|
||||
|
||||
static void rpm_suspend_suppliers(struct device *dev)
|
||||
{
|
||||
struct device_link *link;
|
||||
int idx = device_links_read_lock();
|
||||
|
||||
list_for_each_entry_rcu(link, &dev->links.suppliers, c_node,
|
||||
device_links_read_lock_held())
|
||||
pm_request_idle(link->supplier);
|
||||
|
||||
device_links_read_unlock(idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* __rpm_callback - Run a given runtime PM callback for a given device.
|
||||
* @cb: Runtime PM callback to run.
|
||||
|
|
@ -344,8 +364,10 @@ static int __rpm_callback(int (*cb)(struct device *), struct device *dev)
|
|||
idx = device_links_read_lock();
|
||||
|
||||
retval = rpm_get_suppliers(dev);
|
||||
if (retval)
|
||||
if (retval) {
|
||||
rpm_put_suppliers(dev);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
device_links_read_unlock(idx);
|
||||
}
|
||||
|
|
@ -368,9 +390,9 @@ static int __rpm_callback(int (*cb)(struct device *), struct device *dev)
|
|||
|| (dev->power.runtime_status == RPM_RESUMING && retval))) {
|
||||
idx = device_links_read_lock();
|
||||
|
||||
fail:
|
||||
rpm_put_suppliers(dev);
|
||||
__rpm_put_suppliers(dev, false);
|
||||
|
||||
fail:
|
||||
device_links_read_unlock(idx);
|
||||
}
|
||||
|
||||
|
|
@ -642,8 +664,11 @@ static int rpm_suspend(struct device *dev, int rpmflags)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (dev->power.irq_safe)
|
||||
goto out;
|
||||
|
||||
/* Maybe the parent is now able to suspend. */
|
||||
if (parent && !parent->power.ignore_children && !dev->power.irq_safe) {
|
||||
if (parent && !parent->power.ignore_children) {
|
||||
spin_unlock(&dev->power.lock);
|
||||
|
||||
spin_lock(&parent->power.lock);
|
||||
|
|
@ -652,6 +677,14 @@ static int rpm_suspend(struct device *dev, int rpmflags)
|
|||
|
||||
spin_lock(&dev->power.lock);
|
||||
}
|
||||
/* Maybe the suppliers are now able to suspend. */
|
||||
if (dev->power.links_count > 0) {
|
||||
spin_unlock_irq(&dev->power.lock);
|
||||
|
||||
rpm_suspend_suppliers(dev);
|
||||
|
||||
spin_lock_irq(&dev->power.lock);
|
||||
}
|
||||
|
||||
out:
|
||||
trace_rpm_return_int_rcuidle(dev, _THIS_IP_, retval);
|
||||
|
|
|
|||
|
|
@ -285,7 +285,7 @@ static int omap_l3_probe(struct platform_device *pdev)
|
|||
*/
|
||||
l3->debug_irq = platform_get_irq(pdev, 0);
|
||||
ret = devm_request_irq(l3->dev, l3->debug_irq, l3_interrupt_handler,
|
||||
0x0, "l3-dbg-irq", l3);
|
||||
IRQF_NO_THREAD, "l3-dbg-irq", l3);
|
||||
if (ret) {
|
||||
dev_err(l3->dev, "request_irq failed for %d\n",
|
||||
l3->debug_irq);
|
||||
|
|
@ -294,7 +294,7 @@ static int omap_l3_probe(struct platform_device *pdev)
|
|||
|
||||
l3->app_irq = platform_get_irq(pdev, 1);
|
||||
ret = devm_request_irq(l3->dev, l3->app_irq, l3_interrupt_handler,
|
||||
0x0, "l3-app-irq", l3);
|
||||
IRQF_NO_THREAD, "l3-app-irq", l3);
|
||||
if (ret)
|
||||
dev_err(l3->dev, "request_irq failed for %d\n", l3->app_irq);
|
||||
|
||||
|
|
|
|||
|
|
@ -3053,7 +3053,9 @@ static int sysc_remove(struct platform_device *pdev)
|
|||
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
reset_control_assert(ddata->rsts);
|
||||
|
||||
if (!reset_control_status(ddata->rsts))
|
||||
reset_control_assert(ddata->rsts);
|
||||
|
||||
unprepare:
|
||||
sysc_unprepare(ddata);
|
||||
|
|
|
|||
|
|
@ -1007,13 +1007,9 @@ struct amdgpu_device {
|
|||
|
||||
/* s3/s4 mask */
|
||||
bool in_suspend;
|
||||
bool in_hibernate;
|
||||
|
||||
/*
|
||||
* The combination flag in_poweroff_reboot_com used to identify the poweroff
|
||||
* and reboot opt in the s0i3 system-wide suspend.
|
||||
*/
|
||||
bool in_poweroff_reboot_com;
|
||||
bool in_s3;
|
||||
bool in_s4;
|
||||
bool in_s0ix;
|
||||
|
||||
atomic_t in_gpu_reset;
|
||||
enum pp_mp1_state mp1_state;
|
||||
|
|
|
|||
|
|
@ -2371,6 +2371,10 @@ static int amdgpu_device_set_cg_state(struct amdgpu_device *adev,
|
|||
i = state == AMD_CG_STATE_GATE ? j : adev->num_ip_blocks - j - 1;
|
||||
if (!adev->ip_blocks[i].status.late_initialized)
|
||||
continue;
|
||||
/* skip CG for GFX on S0ix */
|
||||
if (adev->in_s0ix &&
|
||||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX)
|
||||
continue;
|
||||
/* skip CG for VCE/UVD, it's handled specially */
|
||||
if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
|
||||
adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE &&
|
||||
|
|
@ -2402,6 +2406,10 @@ static int amdgpu_device_set_pg_state(struct amdgpu_device *adev, enum amd_power
|
|||
i = state == AMD_PG_STATE_GATE ? j : adev->num_ip_blocks - j - 1;
|
||||
if (!adev->ip_blocks[i].status.late_initialized)
|
||||
continue;
|
||||
/* skip PG for GFX on S0ix */
|
||||
if (adev->in_s0ix &&
|
||||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX)
|
||||
continue;
|
||||
/* skip CG for VCE/UVD, it's handled specially */
|
||||
if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
|
||||
adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE &&
|
||||
|
|
@ -2678,11 +2686,8 @@ static int amdgpu_device_ip_suspend_phase1(struct amdgpu_device *adev)
|
|||
{
|
||||
int i, r;
|
||||
|
||||
if (adev->in_poweroff_reboot_com ||
|
||||
!amdgpu_acpi_is_s0ix_supported(adev) || amdgpu_in_reset(adev)) {
|
||||
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
|
||||
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
|
||||
}
|
||||
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
|
||||
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
|
||||
|
||||
for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
|
||||
if (!adev->ip_blocks[i].status.valid)
|
||||
|
|
@ -2722,6 +2727,9 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev)
|
|||
{
|
||||
int i, r;
|
||||
|
||||
if (adev->in_s0ix)
|
||||
amdgpu_gfx_state_change_set(adev, sGpuChangeState_D3Entry);
|
||||
|
||||
for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
|
||||
if (!adev->ip_blocks[i].status.valid)
|
||||
continue;
|
||||
|
|
@ -2734,6 +2742,17 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev)
|
|||
adev->ip_blocks[i].status.hw = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* skip suspend of gfx and psp for S0ix
|
||||
* gfx is in gfxoff state, so on resume it will exit gfxoff just
|
||||
* like at runtime. PSP is also part of the always on hardware
|
||||
* so no need to suspend it.
|
||||
*/
|
||||
if (adev->in_s0ix &&
|
||||
(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP ||
|
||||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX))
|
||||
continue;
|
||||
|
||||
/* XXX handle errors */
|
||||
r = adev->ip_blocks[i].version->funcs->suspend(adev);
|
||||
/* XXX handle errors */
|
||||
|
|
@ -3673,14 +3692,9 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
|
|||
*/
|
||||
int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter iter;
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
int r;
|
||||
|
||||
adev = drm_to_adev(dev);
|
||||
|
||||
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
|
||||
return 0;
|
||||
|
||||
|
|
@ -3692,61 +3706,19 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
|
|||
|
||||
cancel_delayed_work_sync(&adev->delayed_init_work);
|
||||
|
||||
if (!amdgpu_device_has_dc_support(adev)) {
|
||||
/* turn off display hw */
|
||||
drm_modeset_lock_all(dev);
|
||||
drm_connector_list_iter_begin(dev, &iter);
|
||||
drm_for_each_connector_iter(connector, &iter)
|
||||
drm_helper_connector_dpms(connector,
|
||||
DRM_MODE_DPMS_OFF);
|
||||
drm_connector_list_iter_end(&iter);
|
||||
drm_modeset_unlock_all(dev);
|
||||
/* unpin the front buffers and cursors */
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
struct drm_framebuffer *fb = crtc->primary->fb;
|
||||
struct amdgpu_bo *robj;
|
||||
|
||||
if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) {
|
||||
struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo);
|
||||
r = amdgpu_bo_reserve(aobj, true);
|
||||
if (r == 0) {
|
||||
amdgpu_bo_unpin(aobj);
|
||||
amdgpu_bo_unreserve(aobj);
|
||||
}
|
||||
}
|
||||
|
||||
if (fb == NULL || fb->obj[0] == NULL) {
|
||||
continue;
|
||||
}
|
||||
robj = gem_to_amdgpu_bo(fb->obj[0]);
|
||||
/* don't unpin kernel fb objects */
|
||||
if (!amdgpu_fbdev_robj_is_fb(adev, robj)) {
|
||||
r = amdgpu_bo_reserve(robj, true);
|
||||
if (r == 0) {
|
||||
amdgpu_bo_unpin(robj);
|
||||
amdgpu_bo_unreserve(robj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
amdgpu_ras_suspend(adev);
|
||||
|
||||
r = amdgpu_device_ip_suspend_phase1(adev);
|
||||
|
||||
amdgpu_amdkfd_suspend(adev, adev->in_runpm);
|
||||
if (!adev->in_s0ix)
|
||||
amdgpu_amdkfd_suspend(adev, adev->in_runpm);
|
||||
|
||||
/* evict vram memory */
|
||||
amdgpu_bo_evict_vram(adev);
|
||||
|
||||
amdgpu_fence_driver_suspend(adev);
|
||||
|
||||
if (adev->in_poweroff_reboot_com ||
|
||||
!amdgpu_acpi_is_s0ix_supported(adev) || amdgpu_in_reset(adev))
|
||||
r = amdgpu_device_ip_suspend_phase2(adev);
|
||||
else
|
||||
amdgpu_gfx_state_change_set(adev, sGpuChangeState_D3Entry);
|
||||
r = amdgpu_device_ip_suspend_phase2(adev);
|
||||
/* evict remaining vram memory
|
||||
* This second call to evict vram is to evict the gart page table
|
||||
* using the CPU.
|
||||
|
|
@ -3768,16 +3740,13 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
|
|||
*/
|
||||
int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
|
||||
{
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter iter;
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
struct drm_crtc *crtc;
|
||||
int r = 0;
|
||||
|
||||
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
|
||||
return 0;
|
||||
|
||||
if (amdgpu_acpi_is_s0ix_supported(adev))
|
||||
if (adev->in_s0ix)
|
||||
amdgpu_gfx_state_change_set(adev, sGpuChangeState_D0Entry);
|
||||
|
||||
/* post card */
|
||||
|
|
@ -3802,50 +3771,17 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
|
|||
queue_delayed_work(system_wq, &adev->delayed_init_work,
|
||||
msecs_to_jiffies(AMDGPU_RESUME_MS));
|
||||
|
||||
if (!amdgpu_device_has_dc_support(adev)) {
|
||||
/* pin cursors */
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) {
|
||||
struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo);
|
||||
r = amdgpu_bo_reserve(aobj, true);
|
||||
if (r == 0) {
|
||||
r = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM);
|
||||
if (r != 0)
|
||||
dev_err(adev->dev, "Failed to pin cursor BO (%d)\n", r);
|
||||
amdgpu_crtc->cursor_addr = amdgpu_bo_gpu_offset(aobj);
|
||||
amdgpu_bo_unreserve(aobj);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!adev->in_s0ix) {
|
||||
r = amdgpu_amdkfd_resume(adev, adev->in_runpm);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
r = amdgpu_amdkfd_resume(adev, adev->in_runpm);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* Make sure IB tests flushed */
|
||||
flush_delayed_work(&adev->delayed_init_work);
|
||||
|
||||
/* blat the mode back in */
|
||||
if (fbcon) {
|
||||
if (!amdgpu_device_has_dc_support(adev)) {
|
||||
/* pre DCE11 */
|
||||
drm_helper_resume_force_mode(dev);
|
||||
|
||||
/* turn on display hw */
|
||||
drm_modeset_lock_all(dev);
|
||||
|
||||
drm_connector_list_iter_begin(dev, &iter);
|
||||
drm_for_each_connector_iter(connector, &iter)
|
||||
drm_helper_connector_dpms(connector,
|
||||
DRM_MODE_DPMS_ON);
|
||||
drm_connector_list_iter_end(&iter);
|
||||
|
||||
drm_modeset_unlock_all(dev);
|
||||
}
|
||||
if (fbcon)
|
||||
amdgpu_fbdev_set_suspend(adev, 0);
|
||||
}
|
||||
|
||||
drm_kms_helper_poll_enable(dev);
|
||||
|
||||
|
|
|
|||
|
|
@ -1310,3 +1310,92 @@ bool amdgpu_crtc_get_scanout_position(struct drm_crtc *crtc,
|
|||
return amdgpu_display_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos,
|
||||
stime, etime, mode);
|
||||
}
|
||||
|
||||
int amdgpu_display_suspend_helper(struct amdgpu_device *adev)
|
||||
{
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter iter;
|
||||
int r;
|
||||
|
||||
/* turn off display hw */
|
||||
drm_modeset_lock_all(dev);
|
||||
drm_connector_list_iter_begin(dev, &iter);
|
||||
drm_for_each_connector_iter(connector, &iter)
|
||||
drm_helper_connector_dpms(connector,
|
||||
DRM_MODE_DPMS_OFF);
|
||||
drm_connector_list_iter_end(&iter);
|
||||
drm_modeset_unlock_all(dev);
|
||||
/* unpin the front buffers and cursors */
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
struct drm_framebuffer *fb = crtc->primary->fb;
|
||||
struct amdgpu_bo *robj;
|
||||
|
||||
if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) {
|
||||
struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo);
|
||||
r = amdgpu_bo_reserve(aobj, true);
|
||||
if (r == 0) {
|
||||
amdgpu_bo_unpin(aobj);
|
||||
amdgpu_bo_unreserve(aobj);
|
||||
}
|
||||
}
|
||||
|
||||
if (fb == NULL || fb->obj[0] == NULL) {
|
||||
continue;
|
||||
}
|
||||
robj = gem_to_amdgpu_bo(fb->obj[0]);
|
||||
/* don't unpin kernel fb objects */
|
||||
if (!amdgpu_fbdev_robj_is_fb(adev, robj)) {
|
||||
r = amdgpu_bo_reserve(robj, true);
|
||||
if (r == 0) {
|
||||
amdgpu_bo_unpin(robj);
|
||||
amdgpu_bo_unreserve(robj);
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int amdgpu_display_resume_helper(struct amdgpu_device *adev)
|
||||
{
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter iter;
|
||||
struct drm_crtc *crtc;
|
||||
int r;
|
||||
|
||||
/* pin cursors */
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) {
|
||||
struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo);
|
||||
r = amdgpu_bo_reserve(aobj, true);
|
||||
if (r == 0) {
|
||||
r = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM);
|
||||
if (r != 0)
|
||||
dev_err(adev->dev, "Failed to pin cursor BO (%d)\n", r);
|
||||
amdgpu_crtc->cursor_addr = amdgpu_bo_gpu_offset(aobj);
|
||||
amdgpu_bo_unreserve(aobj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drm_helper_resume_force_mode(dev);
|
||||
|
||||
/* turn on display hw */
|
||||
drm_modeset_lock_all(dev);
|
||||
|
||||
drm_connector_list_iter_begin(dev, &iter);
|
||||
drm_for_each_connector_iter(connector, &iter)
|
||||
drm_helper_connector_dpms(connector,
|
||||
DRM_MODE_DPMS_ON);
|
||||
drm_connector_list_iter_end(&iter);
|
||||
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,4 +47,7 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
|
|||
const struct drm_format_info *
|
||||
amdgpu_lookup_format_info(u32 format, uint64_t modifier);
|
||||
|
||||
int amdgpu_display_suspend_helper(struct amdgpu_device *adev);
|
||||
int amdgpu_display_resume_helper(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1107,6 +1107,7 @@ static const struct pci_device_id pciidlist[] = {
|
|||
{0x1002, 0x73A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID},
|
||||
{0x1002, 0x73AB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID},
|
||||
{0x1002, 0x73AE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID},
|
||||
{0x1002, 0x73AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID},
|
||||
{0x1002, 0x73BF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID},
|
||||
|
||||
/* Van Gogh */
|
||||
|
|
@ -1274,24 +1275,35 @@ amdgpu_pci_shutdown(struct pci_dev *pdev)
|
|||
*/
|
||||
if (!amdgpu_passthrough(adev))
|
||||
adev->mp1_state = PP_MP1_STATE_UNLOAD;
|
||||
adev->in_poweroff_reboot_com = true;
|
||||
amdgpu_device_ip_suspend(adev);
|
||||
adev->in_poweroff_reboot_com = false;
|
||||
adev->mp1_state = PP_MP1_STATE_NONE;
|
||||
}
|
||||
|
||||
static int amdgpu_pmops_suspend(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = drm_to_adev(drm_dev);
|
||||
int r;
|
||||
|
||||
return amdgpu_device_suspend(drm_dev, true);
|
||||
if (amdgpu_acpi_is_s0ix_supported(adev))
|
||||
adev->in_s0ix = true;
|
||||
adev->in_s3 = true;
|
||||
r = amdgpu_device_suspend(drm_dev, true);
|
||||
adev->in_s3 = false;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int amdgpu_pmops_resume(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = drm_to_adev(drm_dev);
|
||||
int r;
|
||||
|
||||
return amdgpu_device_resume(drm_dev, true);
|
||||
r = amdgpu_device_resume(drm_dev, true);
|
||||
if (amdgpu_acpi_is_s0ix_supported(adev))
|
||||
adev->in_s0ix = false;
|
||||
return r;
|
||||
}
|
||||
|
||||
static int amdgpu_pmops_freeze(struct device *dev)
|
||||
|
|
@ -1300,9 +1312,9 @@ static int amdgpu_pmops_freeze(struct device *dev)
|
|||
struct amdgpu_device *adev = drm_to_adev(drm_dev);
|
||||
int r;
|
||||
|
||||
adev->in_hibernate = true;
|
||||
adev->in_s4 = true;
|
||||
r = amdgpu_device_suspend(drm_dev, true);
|
||||
adev->in_hibernate = false;
|
||||
adev->in_s4 = false;
|
||||
if (r)
|
||||
return r;
|
||||
return amdgpu_asic_reset(adev);
|
||||
|
|
@ -1318,13 +1330,8 @@ static int amdgpu_pmops_thaw(struct device *dev)
|
|||
static int amdgpu_pmops_poweroff(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = drm_to_adev(drm_dev);
|
||||
int r;
|
||||
|
||||
adev->in_poweroff_reboot_com = true;
|
||||
r = amdgpu_device_suspend(drm_dev, true);
|
||||
adev->in_poweroff_reboot_com = false;
|
||||
return r;
|
||||
return amdgpu_device_suspend(drm_dev, true);
|
||||
}
|
||||
|
||||
static int amdgpu_pmops_restore(struct device *dev)
|
||||
|
|
|
|||
|
|
@ -1028,13 +1028,10 @@ int amdgpu_bo_evict_vram(struct amdgpu_device *adev)
|
|||
{
|
||||
struct ttm_resource_manager *man;
|
||||
|
||||
/* late 2.6.33 fix IGP hibernate - we need pm ops to do this correct */
|
||||
#ifndef CONFIG_HIBERNATION
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
/* Useless to evict on IGP chips */
|
||||
if (adev->in_s3 && (adev->flags & AMD_IS_APU)) {
|
||||
/* No need to evict vram on APUs for suspend to ram */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
|
||||
return ttm_resource_manager_evict_all(&adev->mman.bdev, man);
|
||||
|
|
|
|||
|
|
@ -2897,6 +2897,11 @@ static int dce_v10_0_hw_fini(void *handle)
|
|||
static int dce_v10_0_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = amdgpu_display_suspend_helper(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev->mode_info.bl_level =
|
||||
amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
|
||||
|
|
@ -2921,8 +2926,10 @@ static int dce_v10_0_resume(void *handle)
|
|||
amdgpu_display_backlight_set_level(adev, adev->mode_info.bl_encoder,
|
||||
bl_level);
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
return amdgpu_display_resume_helper(adev);
|
||||
}
|
||||
|
||||
static bool dce_v10_0_is_idle(void *handle)
|
||||
|
|
|
|||
|
|
@ -3027,6 +3027,11 @@ static int dce_v11_0_hw_fini(void *handle)
|
|||
static int dce_v11_0_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = amdgpu_display_suspend_helper(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev->mode_info.bl_level =
|
||||
amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
|
||||
|
|
@ -3051,8 +3056,10 @@ static int dce_v11_0_resume(void *handle)
|
|||
amdgpu_display_backlight_set_level(adev, adev->mode_info.bl_encoder,
|
||||
bl_level);
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
return amdgpu_display_resume_helper(adev);
|
||||
}
|
||||
|
||||
static bool dce_v11_0_is_idle(void *handle)
|
||||
|
|
|
|||
|
|
@ -2770,7 +2770,11 @@ static int dce_v6_0_hw_fini(void *handle)
|
|||
static int dce_v6_0_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = amdgpu_display_suspend_helper(adev);
|
||||
if (r)
|
||||
return r;
|
||||
adev->mode_info.bl_level =
|
||||
amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
|
||||
|
||||
|
|
@ -2794,8 +2798,10 @@ static int dce_v6_0_resume(void *handle)
|
|||
amdgpu_display_backlight_set_level(adev, adev->mode_info.bl_encoder,
|
||||
bl_level);
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
return amdgpu_display_resume_helper(adev);
|
||||
}
|
||||
|
||||
static bool dce_v6_0_is_idle(void *handle)
|
||||
|
|
|
|||
|
|
@ -2796,6 +2796,11 @@ static int dce_v8_0_hw_fini(void *handle)
|
|||
static int dce_v8_0_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = amdgpu_display_suspend_helper(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev->mode_info.bl_level =
|
||||
amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
|
||||
|
|
@ -2820,8 +2825,10 @@ static int dce_v8_0_resume(void *handle)
|
|||
amdgpu_display_backlight_set_level(adev, adev->mode_info.bl_encoder,
|
||||
bl_level);
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
return amdgpu_display_resume_helper(adev);
|
||||
}
|
||||
|
||||
static bool dce_v8_0_is_idle(void *handle)
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "dce_v11_0.h"
|
||||
#include "dce_virtual.h"
|
||||
#include "ivsrcid/ivsrcid_vislands30.h"
|
||||
#include "amdgpu_display.h"
|
||||
|
||||
#define DCE_VIRTUAL_VBLANK_PERIOD 16666666
|
||||
|
||||
|
|
@ -491,12 +492,24 @@ static int dce_virtual_hw_fini(void *handle)
|
|||
|
||||
static int dce_virtual_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = amdgpu_display_suspend_helper(adev);
|
||||
if (r)
|
||||
return r;
|
||||
return dce_virtual_hw_fini(handle);
|
||||
}
|
||||
|
||||
static int dce_virtual_resume(void *handle)
|
||||
{
|
||||
return dce_virtual_hw_init(handle);
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = dce_virtual_hw_init(handle);
|
||||
if (r)
|
||||
return r;
|
||||
return amdgpu_display_resume_helper(adev);
|
||||
}
|
||||
|
||||
static bool dce_virtual_is_idle(void *handle)
|
||||
|
|
|
|||
|
|
@ -341,8 +341,7 @@ void enc2_hw_init(struct link_encoder *enc)
|
|||
} else {
|
||||
AUX_REG_WRITE(AUX_DPHY_RX_CONTROL0, 0x103d1110);
|
||||
|
||||
AUX_REG_WRITE(AUX_DPHY_TX_CONTROL, 0x21c4d);
|
||||
|
||||
AUX_REG_WRITE(AUX_DPHY_TX_CONTROL, 0x21c7a);
|
||||
}
|
||||
|
||||
//AUX_DPHY_TX_REF_CONTROL'AUX_TX_REF_DIV HW default is 0x32;
|
||||
|
|
|
|||
|
|
@ -587,6 +587,48 @@ static int smu7_force_switch_to_arbf0(struct pp_hwmgr *hwmgr)
|
|||
tmp, MC_CG_ARB_FREQ_F0);
|
||||
}
|
||||
|
||||
static uint16_t smu7_override_pcie_speed(struct pp_hwmgr *hwmgr)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
|
||||
uint16_t pcie_gen = 0;
|
||||
|
||||
if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4 &&
|
||||
adev->pm.pcie_gen_mask & CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN4)
|
||||
pcie_gen = 3;
|
||||
else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3 &&
|
||||
adev->pm.pcie_gen_mask & CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN3)
|
||||
pcie_gen = 2;
|
||||
else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 &&
|
||||
adev->pm.pcie_gen_mask & CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN2)
|
||||
pcie_gen = 1;
|
||||
else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 &&
|
||||
adev->pm.pcie_gen_mask & CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1)
|
||||
pcie_gen = 0;
|
||||
|
||||
return pcie_gen;
|
||||
}
|
||||
|
||||
static uint16_t smu7_override_pcie_width(struct pp_hwmgr *hwmgr)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
|
||||
uint16_t pcie_width = 0;
|
||||
|
||||
if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16)
|
||||
pcie_width = 16;
|
||||
else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12)
|
||||
pcie_width = 12;
|
||||
else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8)
|
||||
pcie_width = 8;
|
||||
else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4)
|
||||
pcie_width = 4;
|
||||
else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2)
|
||||
pcie_width = 2;
|
||||
else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1)
|
||||
pcie_width = 1;
|
||||
|
||||
return pcie_width;
|
||||
}
|
||||
|
||||
static int smu7_setup_default_pcie_table(struct pp_hwmgr *hwmgr)
|
||||
{
|
||||
struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
|
||||
|
|
@ -683,6 +725,11 @@ static int smu7_setup_default_pcie_table(struct pp_hwmgr *hwmgr)
|
|||
PP_Min_PCIEGen),
|
||||
get_pcie_lane_support(data->pcie_lane_cap,
|
||||
PP_Max_PCIELane));
|
||||
|
||||
if (data->pcie_dpm_key_disabled)
|
||||
phm_setup_pcie_table_entry(&data->dpm_table.pcie_speed_table,
|
||||
data->dpm_table.pcie_speed_table.count,
|
||||
smu7_override_pcie_speed(hwmgr), smu7_override_pcie_width(hwmgr));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1248,6 +1295,13 @@ static int smu7_start_dpm(struct pp_hwmgr *hwmgr)
|
|||
NULL)),
|
||||
"Failed to enable pcie DPM during DPM Start Function!",
|
||||
return -EINVAL);
|
||||
} else {
|
||||
PP_ASSERT_WITH_CODE(
|
||||
(0 == smum_send_msg_to_smc(hwmgr,
|
||||
PPSMC_MSG_PCIeDPM_Disable,
|
||||
NULL)),
|
||||
"Failed to disble pcie DPM during DPM Start Function!",
|
||||
return -EINVAL);
|
||||
}
|
||||
|
||||
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@
|
|||
#include "smuio/smuio_9_0_offset.h"
|
||||
#include "smuio/smuio_9_0_sh_mask.h"
|
||||
|
||||
#define smnPCIE_LC_SPEED_CNTL 0x11140290
|
||||
#define smnPCIE_LC_LINK_WIDTH_CNTL 0x11140288
|
||||
|
||||
#define HBM_MEMORY_CHANNEL_WIDTH 128
|
||||
|
||||
static const uint32_t channel_number[] = {1, 2, 0, 4, 0, 8, 0, 16, 2};
|
||||
|
|
@ -443,8 +446,7 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr)
|
|||
if (PP_CAP(PHM_PlatformCaps_VCEDPM))
|
||||
data->smu_features[GNLD_DPM_VCE].supported = true;
|
||||
|
||||
if (!data->registry_data.pcie_dpm_key_disabled)
|
||||
data->smu_features[GNLD_DPM_LINK].supported = true;
|
||||
data->smu_features[GNLD_DPM_LINK].supported = true;
|
||||
|
||||
if (!data->registry_data.dcefclk_dpm_key_disabled)
|
||||
data->smu_features[GNLD_DPM_DCEFCLK].supported = true;
|
||||
|
|
@ -1544,6 +1546,13 @@ static int vega10_override_pcie_parameters(struct pp_hwmgr *hwmgr)
|
|||
pp_table->PcieLaneCount[i] = pcie_width;
|
||||
}
|
||||
|
||||
if (data->registry_data.pcie_dpm_key_disabled) {
|
||||
for (i = 0; i < NUM_LINK_LEVELS; i++) {
|
||||
pp_table->PcieGenSpeed[i] = pcie_gen;
|
||||
pp_table->PcieLaneCount[i] = pcie_width;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -2966,6 +2975,14 @@ static int vega10_start_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap)
|
|||
}
|
||||
}
|
||||
|
||||
if (data->registry_data.pcie_dpm_key_disabled) {
|
||||
PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
|
||||
false, data->smu_features[GNLD_DPM_LINK].smu_feature_bitmap),
|
||||
"Attempt to Disable Link DPM feature Failed!", return -EINVAL);
|
||||
data->smu_features[GNLD_DPM_LINK].enabled = false;
|
||||
data->smu_features[GNLD_DPM_LINK].supported = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -4584,6 +4601,24 @@ static int vega10_set_ppfeature_status(struct pp_hwmgr *hwmgr, uint64_t new_ppfe
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int vega10_get_current_pcie_link_width_level(struct pp_hwmgr *hwmgr)
|
||||
{
|
||||
struct amdgpu_device *adev = hwmgr->adev;
|
||||
|
||||
return (RREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL) &
|
||||
PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK)
|
||||
>> PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT;
|
||||
}
|
||||
|
||||
static int vega10_get_current_pcie_link_speed_level(struct pp_hwmgr *hwmgr)
|
||||
{
|
||||
struct amdgpu_device *adev = hwmgr->adev;
|
||||
|
||||
return (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) &
|
||||
PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK)
|
||||
>> PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT;
|
||||
}
|
||||
|
||||
static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
|
||||
enum pp_clock_type type, char *buf)
|
||||
{
|
||||
|
|
@ -4592,8 +4627,9 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
|
|||
struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
|
||||
struct vega10_single_dpm_table *soc_table = &(data->dpm_table.soc_table);
|
||||
struct vega10_single_dpm_table *dcef_table = &(data->dpm_table.dcef_table);
|
||||
struct vega10_pcie_table *pcie_table = &(data->dpm_table.pcie_table);
|
||||
struct vega10_odn_clock_voltage_dependency_table *podn_vdd_dep = NULL;
|
||||
uint32_t gen_speed, lane_width, current_gen_speed, current_lane_width;
|
||||
PPTable_t *pptable = &(data->smc_state_table.pp_table);
|
||||
|
||||
int i, now, size = 0, count = 0;
|
||||
|
||||
|
|
@ -4650,15 +4686,31 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
|
|||
"*" : "");
|
||||
break;
|
||||
case PP_PCIE:
|
||||
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentLinkIndex, &now);
|
||||
current_gen_speed =
|
||||
vega10_get_current_pcie_link_speed_level(hwmgr);
|
||||
current_lane_width =
|
||||
vega10_get_current_pcie_link_width_level(hwmgr);
|
||||
for (i = 0; i < NUM_LINK_LEVELS; i++) {
|
||||
gen_speed = pptable->PcieGenSpeed[i];
|
||||
lane_width = pptable->PcieLaneCount[i];
|
||||
|
||||
for (i = 0; i < pcie_table->count; i++)
|
||||
size += sprintf(buf + size, "%d: %s %s\n", i,
|
||||
(pcie_table->pcie_gen[i] == 0) ? "2.5GT/s, x1" :
|
||||
(pcie_table->pcie_gen[i] == 1) ? "5.0GT/s, x16" :
|
||||
(pcie_table->pcie_gen[i] == 2) ? "8.0GT/s, x16" : "",
|
||||
(i == now) ? "*" : "");
|
||||
size += sprintf(buf + size, "%d: %s %s %s\n", i,
|
||||
(gen_speed == 0) ? "2.5GT/s," :
|
||||
(gen_speed == 1) ? "5.0GT/s," :
|
||||
(gen_speed == 2) ? "8.0GT/s," :
|
||||
(gen_speed == 3) ? "16.0GT/s," : "",
|
||||
(lane_width == 1) ? "x1" :
|
||||
(lane_width == 2) ? "x2" :
|
||||
(lane_width == 3) ? "x4" :
|
||||
(lane_width == 4) ? "x8" :
|
||||
(lane_width == 5) ? "x12" :
|
||||
(lane_width == 6) ? "x16" : "",
|
||||
(current_gen_speed == gen_speed) &&
|
||||
(current_lane_width == lane_width) ?
|
||||
"*" : "");
|
||||
}
|
||||
break;
|
||||
|
||||
case OD_SCLK:
|
||||
if (hwmgr->od_enabled) {
|
||||
size = sprintf(buf, "%s:\n", "OD_SCLK");
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ static void vega12_set_default_registry_data(struct pp_hwmgr *hwmgr)
|
|||
data->registry_data.auto_wattman_debug = 0;
|
||||
data->registry_data.auto_wattman_sample_period = 100;
|
||||
data->registry_data.auto_wattman_threshold = 50;
|
||||
data->registry_data.pcie_dpm_key_disabled = !(hwmgr->feature_mask & PP_PCIE_DPM_MASK);
|
||||
}
|
||||
|
||||
static int vega12_set_features_platform_caps(struct pp_hwmgr *hwmgr)
|
||||
|
|
@ -539,6 +540,29 @@ static int vega12_override_pcie_parameters(struct pp_hwmgr *hwmgr)
|
|||
pp_table->PcieLaneCount[i] = pcie_width_arg;
|
||||
}
|
||||
|
||||
/* override to the highest if it's disabled from ppfeaturmask */
|
||||
if (data->registry_data.pcie_dpm_key_disabled) {
|
||||
for (i = 0; i < NUM_LINK_LEVELS; i++) {
|
||||
smu_pcie_arg = (i << 16) | (pcie_gen << 8) | pcie_width;
|
||||
ret = smum_send_msg_to_smc_with_parameter(hwmgr,
|
||||
PPSMC_MSG_OverridePcieParameters, smu_pcie_arg,
|
||||
NULL);
|
||||
PP_ASSERT_WITH_CODE(!ret,
|
||||
"[OverridePcieParameters] Attempt to override pcie params failed!",
|
||||
return ret);
|
||||
|
||||
pp_table->PcieGenSpeed[i] = pcie_gen;
|
||||
pp_table->PcieLaneCount[i] = pcie_width;
|
||||
}
|
||||
ret = vega12_enable_smc_features(hwmgr,
|
||||
false,
|
||||
data->smu_features[GNLD_DPM_LINK].smu_feature_bitmap);
|
||||
PP_ASSERT_WITH_CODE(!ret,
|
||||
"Attempt to Disable DPM LINK Failed!",
|
||||
return ret);
|
||||
data->smu_features[GNLD_DPM_LINK].enabled = false;
|
||||
data->smu_features[GNLD_DPM_LINK].supported = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr)
|
|||
data->registry_data.gfxoff_controlled_by_driver = 1;
|
||||
data->gfxoff_allowed = false;
|
||||
data->counter_gfxoff = 0;
|
||||
data->registry_data.pcie_dpm_key_disabled = !(hwmgr->feature_mask & PP_PCIE_DPM_MASK);
|
||||
}
|
||||
|
||||
static int vega20_set_features_platform_caps(struct pp_hwmgr *hwmgr)
|
||||
|
|
@ -884,6 +885,30 @@ static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr)
|
|||
pp_table->PcieLaneCount[i] = pcie_width_arg;
|
||||
}
|
||||
|
||||
/* override to the highest if it's disabled from ppfeaturmask */
|
||||
if (data->registry_data.pcie_dpm_key_disabled) {
|
||||
for (i = 0; i < NUM_LINK_LEVELS; i++) {
|
||||
smu_pcie_arg = (i << 16) | (pcie_gen << 8) | pcie_width;
|
||||
ret = smum_send_msg_to_smc_with_parameter(hwmgr,
|
||||
PPSMC_MSG_OverridePcieParameters, smu_pcie_arg,
|
||||
NULL);
|
||||
PP_ASSERT_WITH_CODE(!ret,
|
||||
"[OverridePcieParameters] Attempt to override pcie params failed!",
|
||||
return ret);
|
||||
|
||||
pp_table->PcieGenSpeed[i] = pcie_gen;
|
||||
pp_table->PcieLaneCount[i] = pcie_width;
|
||||
}
|
||||
ret = vega20_enable_smc_features(hwmgr,
|
||||
false,
|
||||
data->smu_features[GNLD_DPM_LINK].smu_feature_bitmap);
|
||||
PP_ASSERT_WITH_CODE(!ret,
|
||||
"Attempt to Disable DPM LINK Failed!",
|
||||
return ret);
|
||||
data->smu_features[GNLD_DPM_LINK].enabled = false;
|
||||
data->smu_features[GNLD_DPM_LINK].supported = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1294,7 +1294,7 @@ static int smu_disable_dpms(struct smu_context *smu)
|
|||
bool use_baco = !smu->is_apu &&
|
||||
((amdgpu_in_reset(adev) &&
|
||||
(amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)) ||
|
||||
((adev->in_runpm || adev->in_hibernate) && amdgpu_asic_supports_baco(adev)));
|
||||
((adev->in_runpm || adev->in_s4) && amdgpu_asic_supports_baco(adev)));
|
||||
|
||||
/*
|
||||
* For custom pptable uploading, skip the DPM features
|
||||
|
|
@ -1431,7 +1431,8 @@ static int smu_suspend(void *handle)
|
|||
|
||||
smu->watermarks_bitmap &= ~(WATERMARKS_LOADED);
|
||||
|
||||
if (smu->is_apu)
|
||||
/* skip CGPG when in S0ix */
|
||||
if (smu->is_apu && !adev->in_s0ix)
|
||||
smu_set_gfx_cgpg(&adev->smu, false);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -689,7 +689,8 @@ static int etnaviv_gem_userptr_get_pages(struct etnaviv_gem_object *etnaviv_obj)
|
|||
struct page **pages = pvec + pinned;
|
||||
|
||||
ret = pin_user_pages_fast(ptr, num_pages,
|
||||
!userptr->ro ? FOLL_WRITE : 0, pages);
|
||||
FOLL_WRITE | FOLL_FORCE | FOLL_LONGTERM,
|
||||
pages);
|
||||
if (ret < 0) {
|
||||
unpin_user_pages(pvec, pinned);
|
||||
kvfree(pvec);
|
||||
|
|
|
|||
|
|
@ -317,12 +317,13 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
|
|||
if (!new_plane_state->hw.crtc && !old_plane_state->hw.crtc)
|
||||
return 0;
|
||||
|
||||
new_crtc_state->enabled_planes |= BIT(plane->id);
|
||||
|
||||
ret = plane->check_plane(new_crtc_state, new_plane_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (fb)
|
||||
new_crtc_state->enabled_planes |= BIT(plane->id);
|
||||
|
||||
/* FIXME pre-g4x don't work like this */
|
||||
if (new_plane_state->uapi.visible)
|
||||
new_crtc_state->active_planes |= BIT(plane->id);
|
||||
|
|
|
|||
|
|
@ -3619,9 +3619,7 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
|
|||
{
|
||||
int ret;
|
||||
|
||||
intel_dp_lttpr_init(intel_dp);
|
||||
|
||||
if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd))
|
||||
if (intel_dp_init_lttpr_and_dprx_caps(intel_dp) < 0)
|
||||
return false;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ static u32 g4x_get_aux_send_ctl(struct intel_dp *intel_dp,
|
|||
else
|
||||
precharge = 5;
|
||||
|
||||
/* Max timeout value on G4x-BDW: 1.6ms */
|
||||
if (IS_BROADWELL(dev_priv))
|
||||
timeout = DP_AUX_CH_CTL_TIME_OUT_600us;
|
||||
else
|
||||
|
|
@ -159,6 +160,12 @@ static u32 skl_get_aux_send_ctl(struct intel_dp *intel_dp,
|
|||
enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
|
||||
u32 ret;
|
||||
|
||||
/*
|
||||
* Max timeout values:
|
||||
* SKL-GLK: 1.6ms
|
||||
* CNL: 3.2ms
|
||||
* ICL+: 4ms
|
||||
*/
|
||||
ret = DP_AUX_CH_CTL_SEND_BUSY |
|
||||
DP_AUX_CH_CTL_DONE |
|
||||
DP_AUX_CH_CTL_INTERRUPT |
|
||||
|
|
|
|||
|
|
@ -34,6 +34,11 @@ intel_dp_dump_link_status(const u8 link_status[DP_LINK_STATUS_SIZE])
|
|||
link_status[3], link_status[4], link_status[5]);
|
||||
}
|
||||
|
||||
static void intel_dp_reset_lttpr_common_caps(struct intel_dp *intel_dp)
|
||||
{
|
||||
memset(&intel_dp->lttpr_common_caps, 0, sizeof(intel_dp->lttpr_common_caps));
|
||||
}
|
||||
|
||||
static void intel_dp_reset_lttpr_count(struct intel_dp *intel_dp)
|
||||
{
|
||||
intel_dp->lttpr_common_caps[DP_PHY_REPEATER_CNT -
|
||||
|
|
@ -81,19 +86,36 @@ static void intel_dp_read_lttpr_phy_caps(struct intel_dp *intel_dp,
|
|||
|
||||
static bool intel_dp_read_lttpr_common_caps(struct intel_dp *intel_dp)
|
||||
{
|
||||
if (drm_dp_read_lttpr_common_caps(&intel_dp->aux,
|
||||
intel_dp->lttpr_common_caps) < 0) {
|
||||
memset(intel_dp->lttpr_common_caps, 0,
|
||||
sizeof(intel_dp->lttpr_common_caps));
|
||||
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
|
||||
|
||||
if (intel_dp_is_edp(intel_dp))
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Detecting LTTPRs must be avoided on platforms with an AUX timeout
|
||||
* period < 3.2ms. (see DP Standard v2.0, 2.11.2, 3.6.6.1).
|
||||
*/
|
||||
if (INTEL_GEN(i915) < 10)
|
||||
return false;
|
||||
|
||||
if (drm_dp_read_lttpr_common_caps(&intel_dp->aux,
|
||||
intel_dp->lttpr_common_caps) < 0)
|
||||
goto reset_caps;
|
||||
|
||||
drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
|
||||
"LTTPR common capabilities: %*ph\n",
|
||||
(int)sizeof(intel_dp->lttpr_common_caps),
|
||||
intel_dp->lttpr_common_caps);
|
||||
|
||||
/* The minimum value of LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV is 1.4 */
|
||||
if (intel_dp->lttpr_common_caps[0] < 0x14)
|
||||
goto reset_caps;
|
||||
|
||||
return true;
|
||||
|
||||
reset_caps:
|
||||
intel_dp_reset_lttpr_common_caps(intel_dp);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -106,33 +128,49 @@ intel_dp_set_lttpr_transparent_mode(struct intel_dp *intel_dp, bool enable)
|
|||
}
|
||||
|
||||
/**
|
||||
* intel_dp_lttpr_init - detect LTTPRs and init the LTTPR link training mode
|
||||
* intel_dp_init_lttpr_and_dprx_caps - detect LTTPR and DPRX caps, init the LTTPR link training mode
|
||||
* @intel_dp: Intel DP struct
|
||||
*
|
||||
* Read the LTTPR common capabilities, switch to non-transparent link training
|
||||
* mode if any is detected and read the PHY capabilities for all detected
|
||||
* LTTPRs. In case of an LTTPR detection error or if the number of
|
||||
* Read the LTTPR common and DPRX capabilities and switch to non-transparent
|
||||
* link training mode if any is detected and read the PHY capabilities for all
|
||||
* detected LTTPRs. In case of an LTTPR detection error or if the number of
|
||||
* LTTPRs is more than is supported (8), fall back to the no-LTTPR,
|
||||
* transparent mode link training mode.
|
||||
*
|
||||
* Returns:
|
||||
* >0 if LTTPRs were detected and the non-transparent LT mode was set
|
||||
* >0 if LTTPRs were detected and the non-transparent LT mode was set. The
|
||||
* DPRX capabilities are read out.
|
||||
* 0 if no LTTPRs or more than 8 LTTPRs were detected or in case of a
|
||||
* detection failure and the transparent LT mode was set
|
||||
* detection failure and the transparent LT mode was set. The DPRX
|
||||
* capabilities are read out.
|
||||
* <0 Reading out the DPRX capabilities failed.
|
||||
*/
|
||||
int intel_dp_lttpr_init(struct intel_dp *intel_dp)
|
||||
int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp)
|
||||
{
|
||||
int lttpr_count;
|
||||
bool ret;
|
||||
int i;
|
||||
|
||||
if (intel_dp_is_edp(intel_dp))
|
||||
return 0;
|
||||
|
||||
ret = intel_dp_read_lttpr_common_caps(intel_dp);
|
||||
|
||||
/* The DPTX shall read the DPRX caps after LTTPR detection. */
|
||||
if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd)) {
|
||||
intel_dp_reset_lttpr_common_caps(intel_dp);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The 0xF0000-0xF02FF range is only valid if the DPCD revision is
|
||||
* at least 1.4.
|
||||
*/
|
||||
if (intel_dp->dpcd[DP_DPCD_REV] < 0x14) {
|
||||
intel_dp_reset_lttpr_common_caps(intel_dp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lttpr_count = drm_dp_lttpr_count(intel_dp->lttpr_common_caps);
|
||||
/*
|
||||
* Prevent setting LTTPR transparent mode explicitly if no LTTPRs are
|
||||
|
|
@ -172,7 +210,7 @@ int intel_dp_lttpr_init(struct intel_dp *intel_dp)
|
|||
|
||||
return lttpr_count;
|
||||
}
|
||||
EXPORT_SYMBOL(intel_dp_lttpr_init);
|
||||
EXPORT_SYMBOL(intel_dp_init_lttpr_and_dprx_caps);
|
||||
|
||||
static u8 dp_voltage_max(u8 preemph)
|
||||
{
|
||||
|
|
@ -807,7 +845,10 @@ void intel_dp_start_link_train(struct intel_dp *intel_dp,
|
|||
* TODO: Reiniting LTTPRs here won't be needed once proper connector
|
||||
* HW state readout is added.
|
||||
*/
|
||||
int lttpr_count = intel_dp_lttpr_init(intel_dp);
|
||||
int lttpr_count = intel_dp_init_lttpr_and_dprx_caps(intel_dp);
|
||||
|
||||
if (lttpr_count < 0)
|
||||
return;
|
||||
|
||||
if (!intel_dp_link_train_all_phys(intel_dp, crtc_state, lttpr_count))
|
||||
intel_dp_schedule_fallback_link_training(intel_dp, crtc_state);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
struct intel_crtc_state;
|
||||
struct intel_dp;
|
||||
|
||||
int intel_dp_lttpr_init(struct intel_dp *intel_dp);
|
||||
int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp);
|
||||
|
||||
void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
|
|
|
|||
|
|
@ -1014,20 +1014,14 @@ static i915_reg_t dss_ctl1_reg(const struct intel_crtc_state *crtc_state)
|
|||
{
|
||||
enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
|
||||
|
||||
if (crtc_state->cpu_transcoder == TRANSCODER_EDP)
|
||||
return DSS_CTL1;
|
||||
|
||||
return ICL_PIPE_DSS_CTL1(pipe);
|
||||
return is_pipe_dsc(crtc_state) ? ICL_PIPE_DSS_CTL1(pipe) : DSS_CTL1;
|
||||
}
|
||||
|
||||
static i915_reg_t dss_ctl2_reg(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
|
||||
|
||||
if (crtc_state->cpu_transcoder == TRANSCODER_EDP)
|
||||
return DSS_CTL2;
|
||||
|
||||
return ICL_PIPE_DSS_CTL2(pipe);
|
||||
return is_pipe_dsc(crtc_state) ? ICL_PIPE_DSS_CTL2(pipe) : DSS_CTL2;
|
||||
}
|
||||
|
||||
void intel_dsc_enable(struct intel_encoder *encoder,
|
||||
|
|
|
|||
|
|
@ -316,7 +316,18 @@ void i915_vma_revoke_fence(struct i915_vma *vma)
|
|||
WRITE_ONCE(fence->vma, NULL);
|
||||
vma->fence = NULL;
|
||||
|
||||
with_intel_runtime_pm_if_in_use(fence_to_uncore(fence)->rpm, wakeref)
|
||||
/*
|
||||
* Skip the write to HW if and only if the device is currently
|
||||
* suspended.
|
||||
*
|
||||
* If the driver does not currently hold a wakeref (if_in_use == 0),
|
||||
* the device may currently be runtime suspended, or it may be woken
|
||||
* up before the suspend takes place. If the device is not suspended
|
||||
* (powered down) and we skip clearing the fence register, the HW is
|
||||
* left in an undefined state where we may end up with multiple
|
||||
* registers overlapping.
|
||||
*/
|
||||
with_intel_runtime_pm_if_active(fence_to_uncore(fence)->rpm, wakeref)
|
||||
fence_write(fence);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -412,12 +412,20 @@ intel_wakeref_t intel_runtime_pm_get(struct intel_runtime_pm *rpm)
|
|||
}
|
||||
|
||||
/**
|
||||
* intel_runtime_pm_get_if_in_use - grab a runtime pm reference if device in use
|
||||
* __intel_runtime_pm_get_if_active - grab a runtime pm reference if device is active
|
||||
* @rpm: the intel_runtime_pm structure
|
||||
* @ignore_usecount: get a ref even if dev->power.usage_count is 0
|
||||
*
|
||||
* This function grabs a device-level runtime pm reference if the device is
|
||||
* already in use and ensures that it is powered up. It is illegal to try
|
||||
* and access the HW should intel_runtime_pm_get_if_in_use() report failure.
|
||||
* already active and ensures that it is powered up. It is illegal to try
|
||||
* and access the HW should intel_runtime_pm_get_if_active() report failure.
|
||||
*
|
||||
* If @ignore_usecount=true, a reference will be acquired even if there is no
|
||||
* user requiring the device to be powered up (dev->power.usage_count == 0).
|
||||
* If the function returns false in this case then it's guaranteed that the
|
||||
* device's runtime suspend hook has been called already or that it will be
|
||||
* called (and hence it's also guaranteed that the device's runtime resume
|
||||
* hook will be called eventually).
|
||||
*
|
||||
* Any runtime pm reference obtained by this function must have a symmetric
|
||||
* call to intel_runtime_pm_put() to release the reference again.
|
||||
|
|
@ -425,7 +433,8 @@ intel_wakeref_t intel_runtime_pm_get(struct intel_runtime_pm *rpm)
|
|||
* Returns: the wakeref cookie to pass to intel_runtime_pm_put(), evaluates
|
||||
* as True if the wakeref was acquired, or False otherwise.
|
||||
*/
|
||||
intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm)
|
||||
static intel_wakeref_t __intel_runtime_pm_get_if_active(struct intel_runtime_pm *rpm,
|
||||
bool ignore_usecount)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_PM)) {
|
||||
/*
|
||||
|
|
@ -434,7 +443,7 @@ intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm)
|
|||
* function, since the power state is undefined. This applies
|
||||
* atm to the late/early system suspend/resume handlers.
|
||||
*/
|
||||
if (pm_runtime_get_if_in_use(rpm->kdev) <= 0)
|
||||
if (pm_runtime_get_if_active(rpm->kdev, ignore_usecount) <= 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -443,6 +452,16 @@ intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm)
|
|||
return track_intel_runtime_pm_wakeref(rpm);
|
||||
}
|
||||
|
||||
intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm)
|
||||
{
|
||||
return __intel_runtime_pm_get_if_active(rpm, false);
|
||||
}
|
||||
|
||||
intel_wakeref_t intel_runtime_pm_get_if_active(struct intel_runtime_pm *rpm)
|
||||
{
|
||||
return __intel_runtime_pm_get_if_active(rpm, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_runtime_pm_get_noresume - grab a runtime pm reference
|
||||
* @rpm: the intel_runtime_pm structure
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ void intel_runtime_pm_driver_release(struct intel_runtime_pm *rpm);
|
|||
|
||||
intel_wakeref_t intel_runtime_pm_get(struct intel_runtime_pm *rpm);
|
||||
intel_wakeref_t intel_runtime_pm_get_if_in_use(struct intel_runtime_pm *rpm);
|
||||
intel_wakeref_t intel_runtime_pm_get_if_active(struct intel_runtime_pm *rpm);
|
||||
intel_wakeref_t intel_runtime_pm_get_noresume(struct intel_runtime_pm *rpm);
|
||||
intel_wakeref_t intel_runtime_pm_get_raw(struct intel_runtime_pm *rpm);
|
||||
|
||||
|
|
@ -188,6 +189,10 @@ intel_wakeref_t intel_runtime_pm_get_raw(struct intel_runtime_pm *rpm);
|
|||
for ((wf) = intel_runtime_pm_get_if_in_use(rpm); (wf); \
|
||||
intel_runtime_pm_put((rpm), (wf)), (wf) = 0)
|
||||
|
||||
#define with_intel_runtime_pm_if_active(rpm, wf) \
|
||||
for ((wf) = intel_runtime_pm_get_if_active(rpm); (wf); \
|
||||
intel_runtime_pm_put((rpm), (wf)), (wf) = 0)
|
||||
|
||||
void intel_runtime_pm_put_unchecked(struct intel_runtime_pm *rpm);
|
||||
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
|
||||
void intel_runtime_pm_put(struct intel_runtime_pm *rpm, intel_wakeref_t wref);
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ int a5xx_power_init(struct msm_gpu *gpu)
|
|||
/* Set up the limits management */
|
||||
if (adreno_is_a530(adreno_gpu))
|
||||
a530_lm_setup(gpu);
|
||||
else
|
||||
else if (adreno_is_a540(adreno_gpu))
|
||||
a540_lm_setup(gpu);
|
||||
|
||||
/* Set up SP/TP power collpase */
|
||||
|
|
|
|||
|
|
@ -339,7 +339,7 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
|
|||
else
|
||||
bit = a6xx_gmu_oob_bits[state].ack_new;
|
||||
|
||||
gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, bit);
|
||||
gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, 1 << bit);
|
||||
}
|
||||
|
||||
/* Enable CPU control of SPTP power power collapse */
|
||||
|
|
|
|||
|
|
@ -522,28 +522,73 @@ static int a6xx_cp_init(struct msm_gpu *gpu)
|
|||
return a6xx_idle(gpu, ring) ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
static void a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu,
|
||||
/*
|
||||
* Check that the microcode version is new enough to include several key
|
||||
* security fixes. Return true if the ucode is safe.
|
||||
*/
|
||||
static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu,
|
||||
struct drm_gem_object *obj)
|
||||
{
|
||||
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
|
||||
struct msm_gpu *gpu = &adreno_gpu->base;
|
||||
u32 *buf = msm_gem_get_vaddr(obj);
|
||||
bool ret = false;
|
||||
|
||||
if (IS_ERR(buf))
|
||||
return;
|
||||
return false;
|
||||
|
||||
/*
|
||||
* If the lowest nibble is 0xa that is an indication that this microcode
|
||||
* has been patched. The actual version is in dword [3] but we only care
|
||||
* about the patchlevel which is the lowest nibble of dword [3]
|
||||
*
|
||||
* Otherwise check that the firmware is greater than or equal to 1.90
|
||||
* which was the first version that had this fix built in
|
||||
* Targets up to a640 (a618, a630 and a640) need to check for a
|
||||
* microcode version that is patched to support the whereami opcode or
|
||||
* one that is new enough to include it by default.
|
||||
*/
|
||||
if (((buf[0] & 0xf) == 0xa) && (buf[2] & 0xf) >= 1)
|
||||
a6xx_gpu->has_whereami = true;
|
||||
else if ((buf[0] & 0xfff) > 0x190)
|
||||
a6xx_gpu->has_whereami = true;
|
||||
if (adreno_is_a618(adreno_gpu) || adreno_is_a630(adreno_gpu) ||
|
||||
adreno_is_a640(adreno_gpu)) {
|
||||
/*
|
||||
* If the lowest nibble is 0xa that is an indication that this
|
||||
* microcode has been patched. The actual version is in dword
|
||||
* [3] but we only care about the patchlevel which is the lowest
|
||||
* nibble of dword [3]
|
||||
*
|
||||
* Otherwise check that the firmware is greater than or equal
|
||||
* to 1.90 which was the first version that had this fix built
|
||||
* in
|
||||
*/
|
||||
if ((((buf[0] & 0xf) == 0xa) && (buf[2] & 0xf) >= 1) ||
|
||||
(buf[0] & 0xfff) >= 0x190) {
|
||||
a6xx_gpu->has_whereami = true;
|
||||
ret = true;
|
||||
goto out;
|
||||
}
|
||||
|
||||
DRM_DEV_ERROR(&gpu->pdev->dev,
|
||||
"a630 SQE ucode is too old. Have version %x need at least %x\n",
|
||||
buf[0] & 0xfff, 0x190);
|
||||
} else {
|
||||
/*
|
||||
* a650 tier targets don't need whereami but still need to be
|
||||
* equal to or newer than 1.95 for other security fixes
|
||||
*/
|
||||
if (adreno_is_a650(adreno_gpu)) {
|
||||
if ((buf[0] & 0xfff) >= 0x195) {
|
||||
ret = true;
|
||||
goto out;
|
||||
}
|
||||
|
||||
DRM_DEV_ERROR(&gpu->pdev->dev,
|
||||
"a650 SQE ucode is too old. Have version %x need at least %x\n",
|
||||
buf[0] & 0xfff, 0x195);
|
||||
}
|
||||
|
||||
/*
|
||||
* When a660 is added those targets should return true here
|
||||
* since those have all the critical security fixes built in
|
||||
* from the start
|
||||
*/
|
||||
}
|
||||
out:
|
||||
msm_gem_put_vaddr(obj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int a6xx_ucode_init(struct msm_gpu *gpu)
|
||||
|
|
@ -566,7 +611,13 @@ static int a6xx_ucode_init(struct msm_gpu *gpu)
|
|||
}
|
||||
|
||||
msm_gem_object_set_name(a6xx_gpu->sqe_bo, "sqefw");
|
||||
a6xx_ucode_check_version(a6xx_gpu, a6xx_gpu->sqe_bo);
|
||||
if (!a6xx_ucode_check_version(a6xx_gpu, a6xx_gpu->sqe_bo)) {
|
||||
msm_gem_unpin_iova(a6xx_gpu->sqe_bo, gpu->aspace);
|
||||
drm_gem_object_put(a6xx_gpu->sqe_bo);
|
||||
|
||||
a6xx_gpu->sqe_bo = NULL;
|
||||
return -EPERM;
|
||||
}
|
||||
}
|
||||
|
||||
gpu_write64(gpu, REG_A6XX_CP_SQE_INSTR_BASE_LO,
|
||||
|
|
@ -1350,35 +1401,20 @@ static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu,
|
|||
u32 revn)
|
||||
{
|
||||
struct opp_table *opp_table;
|
||||
struct nvmem_cell *cell;
|
||||
u32 supp_hw = UINT_MAX;
|
||||
void *buf;
|
||||
u16 speedbin;
|
||||
int ret;
|
||||
|
||||
cell = nvmem_cell_get(dev, "speed_bin");
|
||||
/*
|
||||
* -ENOENT means that the platform doesn't support speedbin which is
|
||||
* fine
|
||||
*/
|
||||
if (PTR_ERR(cell) == -ENOENT)
|
||||
return 0;
|
||||
else if (IS_ERR(cell)) {
|
||||
ret = nvmem_cell_read_u16(dev, "speed_bin", &speedbin);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(dev,
|
||||
"failed to read speed-bin. Some OPPs may not be supported by hardware");
|
||||
"failed to read speed-bin (%d). Some OPPs may not be supported by hardware",
|
||||
ret);
|
||||
goto done;
|
||||
}
|
||||
speedbin = le16_to_cpu(speedbin);
|
||||
|
||||
buf = nvmem_cell_read(cell, NULL);
|
||||
if (IS_ERR(buf)) {
|
||||
nvmem_cell_put(cell);
|
||||
DRM_DEV_ERROR(dev,
|
||||
"failed to read speed-bin. Some OPPs may not be supported by hardware");
|
||||
goto done;
|
||||
}
|
||||
|
||||
supp_hw = fuse_to_supp_hw(dev, revn, *((u32 *) buf));
|
||||
|
||||
kfree(buf);
|
||||
nvmem_cell_put(cell);
|
||||
supp_hw = fuse_to_supp_hw(dev, revn, speedbin);
|
||||
|
||||
done:
|
||||
opp_table = dev_pm_opp_set_supported_hw(dev, &supp_hw, 1);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@
|
|||
#define DPU_DEBUGFS_DIR "msm_dpu"
|
||||
#define DPU_DEBUGFS_HWMASKNAME "hw_log_mask"
|
||||
|
||||
#define MIN_IB_BW 400000000ULL /* Min ib vote 400MB */
|
||||
|
||||
static int dpu_kms_hw_init(struct msm_kms *kms);
|
||||
static void _dpu_kms_mmu_destroy(struct dpu_kms *dpu_kms);
|
||||
|
||||
|
|
@ -931,6 +933,9 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
|
|||
DPU_DEBUG("REG_DMA is not defined");
|
||||
}
|
||||
|
||||
if (of_device_is_compatible(dev->dev->of_node, "qcom,sc7180-mdss"))
|
||||
dpu_kms_parse_data_bus_icc_path(dpu_kms);
|
||||
|
||||
pm_runtime_get_sync(&dpu_kms->pdev->dev);
|
||||
|
||||
dpu_kms->core_rev = readl_relaxed(dpu_kms->mmio + 0x0);
|
||||
|
|
@ -1032,9 +1037,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
|
|||
|
||||
dpu_vbif_init_memtypes(dpu_kms);
|
||||
|
||||
if (of_device_is_compatible(dev->dev->of_node, "qcom,sc7180-mdss"))
|
||||
dpu_kms_parse_data_bus_icc_path(dpu_kms);
|
||||
|
||||
pm_runtime_put_sync(&dpu_kms->pdev->dev);
|
||||
|
||||
return 0;
|
||||
|
|
@ -1191,10 +1193,10 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev)
|
|||
|
||||
ddev = dpu_kms->dev;
|
||||
|
||||
WARN_ON(!(dpu_kms->num_paths));
|
||||
/* Min vote of BW is required before turning on AXI clk */
|
||||
for (i = 0; i < dpu_kms->num_paths; i++)
|
||||
icc_set_bw(dpu_kms->path[i], 0,
|
||||
dpu_kms->catalog->perf.min_dram_ib);
|
||||
icc_set_bw(dpu_kms->path[i], 0, Bps_to_icc(MIN_IB_BW));
|
||||
|
||||
rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true);
|
||||
if (rc) {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ struct dp_aux_private {
|
|||
struct drm_dp_aux dp_aux;
|
||||
};
|
||||
|
||||
#define MAX_AUX_RETRIES 5
|
||||
|
||||
static const char *dp_aux_get_error(u32 aux_error)
|
||||
{
|
||||
switch (aux_error) {
|
||||
|
|
@ -377,6 +379,11 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux,
|
|||
ret = dp_aux_cmd_fifo_tx(aux, msg);
|
||||
|
||||
if (ret < 0) {
|
||||
if (aux->native) {
|
||||
aux->retry_cnt++;
|
||||
if (!(aux->retry_cnt % MAX_AUX_RETRIES))
|
||||
dp_catalog_aux_update_cfg(aux->catalog);
|
||||
}
|
||||
usleep_range(400, 500); /* at least 400us to next try */
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ struct msm_dsi_pll *msm_dsi_pll_init(struct platform_device *pdev,
|
|||
break;
|
||||
case MSM_DSI_PHY_7NM:
|
||||
case MSM_DSI_PHY_7NM_V4_1:
|
||||
pll = msm_dsi_pll_7nm_init(pdev, id);
|
||||
pll = msm_dsi_pll_7nm_init(pdev, type, id);
|
||||
break;
|
||||
default:
|
||||
pll = ERR_PTR(-ENXIO);
|
||||
|
|
|
|||
|
|
@ -117,10 +117,12 @@ msm_dsi_pll_10nm_init(struct platform_device *pdev, int id)
|
|||
}
|
||||
#endif
|
||||
#ifdef CONFIG_DRM_MSM_DSI_7NM_PHY
|
||||
struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev, int id);
|
||||
struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev,
|
||||
enum msm_dsi_phy_type type, int id);
|
||||
#else
|
||||
static inline struct msm_dsi_pll *
|
||||
msm_dsi_pll_7nm_init(struct platform_device *pdev, int id)
|
||||
msm_dsi_pll_7nm_init(struct platform_device *pdev,
|
||||
enum msm_dsi_phy_type type, int id)
|
||||
{
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ static void dsi_pll_commit(struct dsi_pll_7nm *pll)
|
|||
pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1, reg->frac_div_start_low);
|
||||
pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1, reg->frac_div_start_mid);
|
||||
pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1, reg->frac_div_start_high);
|
||||
pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, 0x40);
|
||||
pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, reg->pll_lockdet_rate);
|
||||
pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_DELAY, 0x06);
|
||||
pll_write(base + REG_DSI_7nm_PHY_PLL_CMODE_1, 0x10); /* TODO: 0x00 for CPHY */
|
||||
pll_write(base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS, reg->pll_clock_inverters);
|
||||
|
|
@ -509,6 +509,7 @@ static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw,
|
|||
{
|
||||
struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
|
||||
struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll);
|
||||
struct dsi_pll_config *config = &pll_7nm->pll_configuration;
|
||||
void __iomem *base = pll_7nm->mmio;
|
||||
u64 ref_clk = pll_7nm->vco_ref_clk_rate;
|
||||
u64 vco_rate = 0x0;
|
||||
|
|
@ -529,9 +530,8 @@ static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw,
|
|||
/*
|
||||
* TODO:
|
||||
* 1. Assumes prescaler is disabled
|
||||
* 2. Multiplier is 2^18. it should be 2^(num_of_frac_bits)
|
||||
*/
|
||||
multiplier = 1 << 18;
|
||||
multiplier = 1 << config->frac_bits;
|
||||
pll_freq = dec * (ref_clk * 2);
|
||||
tmp64 = (ref_clk * 2 * frac);
|
||||
pll_freq += div_u64(tmp64, multiplier);
|
||||
|
|
@ -852,7 +852,8 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm)
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev, int id)
|
||||
struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev,
|
||||
enum msm_dsi_phy_type type, int id)
|
||||
{
|
||||
struct dsi_pll_7nm *pll_7nm;
|
||||
struct msm_dsi_pll *pll;
|
||||
|
|
@ -885,7 +886,7 @@ struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev, int id)
|
|||
pll = &pll_7nm->base;
|
||||
pll->min_rate = 1000000000UL;
|
||||
pll->max_rate = 3500000000UL;
|
||||
if (pll->type == MSM_DSI_PHY_7NM_V4_1) {
|
||||
if (type == MSM_DSI_PHY_7NM_V4_1) {
|
||||
pll->min_rate = 600000000UL;
|
||||
pll->max_rate = (unsigned long)5000000000ULL;
|
||||
/* workaround for max rate overflowing on 32-bit builds: */
|
||||
|
|
|
|||
|
|
@ -57,10 +57,13 @@ static void vblank_put(struct msm_kms *kms, unsigned crtc_mask)
|
|||
|
||||
static void lock_crtcs(struct msm_kms *kms, unsigned int crtc_mask)
|
||||
{
|
||||
int crtc_index;
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
for_each_crtc_mask(kms->dev, crtc, crtc_mask)
|
||||
mutex_lock(&kms->commit_lock[drm_crtc_index(crtc)]);
|
||||
for_each_crtc_mask(kms->dev, crtc, crtc_mask) {
|
||||
crtc_index = drm_crtc_index(crtc);
|
||||
mutex_lock_nested(&kms->commit_lock[crtc_index], crtc_index);
|
||||
}
|
||||
}
|
||||
|
||||
static void unlock_crtcs(struct msm_kms *kms, unsigned int crtc_mask)
|
||||
|
|
|
|||
|
|
@ -1072,6 +1072,10 @@ static int __maybe_unused msm_pm_resume(struct device *dev)
|
|||
static int __maybe_unused msm_pm_prepare(struct device *dev)
|
||||
{
|
||||
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||
struct msm_drm_private *priv = ddev ? ddev->dev_private : NULL;
|
||||
|
||||
if (!priv || !priv->kms)
|
||||
return 0;
|
||||
|
||||
return drm_mode_config_helper_suspend(ddev);
|
||||
}
|
||||
|
|
@ -1079,6 +1083,10 @@ static int __maybe_unused msm_pm_prepare(struct device *dev)
|
|||
static void __maybe_unused msm_pm_complete(struct device *dev)
|
||||
{
|
||||
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||
struct msm_drm_private *priv = ddev ? ddev->dev_private : NULL;
|
||||
|
||||
if (!priv || !priv->kms)
|
||||
return;
|
||||
|
||||
drm_mode_config_helper_resume(ddev);
|
||||
}
|
||||
|
|
@ -1311,6 +1319,10 @@ static int msm_pdev_remove(struct platform_device *pdev)
|
|||
static void msm_pdev_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct drm_device *drm = platform_get_drvdata(pdev);
|
||||
struct msm_drm_private *priv = drm ? drm->dev_private : NULL;
|
||||
|
||||
if (!priv || !priv->kms)
|
||||
return;
|
||||
|
||||
drm_atomic_helper_shutdown(drm);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ int msm_wait_fence(struct msm_fence_context *fctx, uint32_t fence,
|
|||
int ret;
|
||||
|
||||
if (fence > fctx->last_fence) {
|
||||
DRM_ERROR("%s: waiting on invalid fence: %u (of %u)\n",
|
||||
DRM_ERROR_RATELIMITED("%s: waiting on invalid fence: %u (of %u)\n",
|
||||
fctx->name, fence, fctx->last_fence);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,7 +157,6 @@ struct msm_kms {
|
|||
* from the crtc's pending_timer close to end of the frame:
|
||||
*/
|
||||
struct mutex commit_lock[MAX_CRTCS];
|
||||
struct lock_class_key commit_lock_keys[MAX_CRTCS];
|
||||
unsigned pending_crtc_mask;
|
||||
struct msm_pending_timer pending_timers[MAX_CRTCS];
|
||||
};
|
||||
|
|
@ -167,11 +166,8 @@ static inline int msm_kms_init(struct msm_kms *kms,
|
|||
{
|
||||
unsigned i, ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(kms->commit_lock); i++) {
|
||||
lockdep_register_key(&kms->commit_lock_keys[i]);
|
||||
__mutex_init(&kms->commit_lock[i], "&kms->commit_lock[i]",
|
||||
&kms->commit_lock_keys[i]);
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(kms->commit_lock); i++)
|
||||
mutex_init(&kms->commit_lock[i]);
|
||||
|
||||
kms->funcs = funcs;
|
||||
|
||||
|
|
|
|||
|
|
@ -2693,9 +2693,20 @@ nv50_display_create(struct drm_device *dev)
|
|||
else
|
||||
nouveau_display(dev)->format_modifiers = disp50xx_modifiers;
|
||||
|
||||
if (disp->disp->object.oclass >= GK104_DISP) {
|
||||
/* FIXME: 256x256 cursors are supported on Kepler, however unlike Maxwell and later
|
||||
* generations Kepler requires that we use small pages (4K) for cursor scanout surfaces. The
|
||||
* proper fix for this is to teach nouveau to migrate fbs being used for the cursor plane to
|
||||
* small page allocations in prepare_fb(). When this is implemented, we should also force
|
||||
* large pages (128K) for ovly fbs in order to fix Kepler ovlys.
|
||||
* But until then, just limit cursors to 128x128 - which is small enough to avoid ever using
|
||||
* large pages.
|
||||
*/
|
||||
if (disp->disp->object.oclass >= GM107_DISP) {
|
||||
dev->mode_config.cursor_width = 256;
|
||||
dev->mode_config.cursor_height = 256;
|
||||
} else if (disp->disp->object.oclass >= GK104_DISP) {
|
||||
dev->mode_config.cursor_width = 128;
|
||||
dev->mode_config.cursor_height = 128;
|
||||
} else {
|
||||
dev->mode_config.cursor_width = 64;
|
||||
dev->mode_config.cursor_height = 64;
|
||||
|
|
|
|||
|
|
@ -48,21 +48,12 @@ static unsigned int rcar_du_encoder_count_ports(struct device_node *node)
|
|||
static const struct drm_encoder_funcs rcar_du_encoder_funcs = {
|
||||
};
|
||||
|
||||
static void rcar_du_encoder_release(struct drm_device *dev, void *res)
|
||||
{
|
||||
struct rcar_du_encoder *renc = res;
|
||||
|
||||
drm_encoder_cleanup(&renc->base);
|
||||
kfree(renc);
|
||||
}
|
||||
|
||||
int rcar_du_encoder_init(struct rcar_du_device *rcdu,
|
||||
enum rcar_du_output output,
|
||||
struct device_node *enc_node)
|
||||
{
|
||||
struct rcar_du_encoder *renc;
|
||||
struct drm_bridge *bridge;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Locate the DRM bridge from the DT node. For the DPAD outputs, if the
|
||||
|
|
@ -101,26 +92,16 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
|
|||
return -ENOLINK;
|
||||
}
|
||||
|
||||
renc = kzalloc(sizeof(*renc), GFP_KERNEL);
|
||||
if (renc == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
renc->output = output;
|
||||
|
||||
dev_dbg(rcdu->dev, "initializing encoder %pOF for output %u\n",
|
||||
enc_node, output);
|
||||
|
||||
ret = drm_encoder_init(&rcdu->ddev, &renc->base, &rcar_du_encoder_funcs,
|
||||
DRM_MODE_ENCODER_NONE, NULL);
|
||||
if (ret < 0) {
|
||||
kfree(renc);
|
||||
return ret;
|
||||
}
|
||||
renc = drmm_encoder_alloc(&rcdu->ddev, struct rcar_du_encoder, base,
|
||||
&rcar_du_encoder_funcs, DRM_MODE_ENCODER_NONE,
|
||||
NULL);
|
||||
if (!renc)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = drmm_add_action_or_reset(&rcdu->ddev, rcar_du_encoder_release,
|
||||
renc);
|
||||
if (ret)
|
||||
return ret;
|
||||
renc->output = output;
|
||||
|
||||
/*
|
||||
* Attach the bridge to the encoder. The bridge will create the
|
||||
|
|
|
|||
|
|
@ -529,7 +529,7 @@ static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_
|
|||
* Grab our output buffer.
|
||||
*/
|
||||
nl = orig_nl = get_result_buffer(param, param_size, &len);
|
||||
if (len < needed) {
|
||||
if (len < needed || len < sizeof(nl->dev)) {
|
||||
param->flags |= DM_BUFFER_FULL_FLAG;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1671,6 +1671,13 @@ static int device_not_zoned_model(struct dm_target *ti, struct dm_dev *dev,
|
|||
return blk_queue_zoned_model(q) != *zoned_model;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the device zoned model based on the target feature flag. If the target
|
||||
* has the DM_TARGET_ZONED_HM feature flag set, host-managed zoned devices are
|
||||
* also accepted but all devices must have the same zoned model. If the target
|
||||
* has the DM_TARGET_MIXED_ZONED_MODEL feature set, the devices can have any
|
||||
* zoned model with all zoned devices having the same zone size.
|
||||
*/
|
||||
static bool dm_table_supports_zoned_model(struct dm_table *t,
|
||||
enum blk_zoned_model zoned_model)
|
||||
{
|
||||
|
|
@ -1680,13 +1687,15 @@ static bool dm_table_supports_zoned_model(struct dm_table *t,
|
|||
for (i = 0; i < dm_table_get_num_targets(t); i++) {
|
||||
ti = dm_table_get_target(t, i);
|
||||
|
||||
if (zoned_model == BLK_ZONED_HM &&
|
||||
!dm_target_supports_zoned_hm(ti->type))
|
||||
return false;
|
||||
|
||||
if (!ti->type->iterate_devices ||
|
||||
ti->type->iterate_devices(ti, device_not_zoned_model, &zoned_model))
|
||||
return false;
|
||||
if (dm_target_supports_zoned_hm(ti->type)) {
|
||||
if (!ti->type->iterate_devices ||
|
||||
ti->type->iterate_devices(ti, device_not_zoned_model,
|
||||
&zoned_model))
|
||||
return false;
|
||||
} else if (!dm_target_supports_mixed_zoned_model(ti->type)) {
|
||||
if (zoned_model == BLK_ZONED_HM)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -1698,9 +1707,17 @@ static int device_not_matches_zone_sectors(struct dm_target *ti, struct dm_dev *
|
|||
struct request_queue *q = bdev_get_queue(dev->bdev);
|
||||
unsigned int *zone_sectors = data;
|
||||
|
||||
if (!blk_queue_is_zoned(q))
|
||||
return 0;
|
||||
|
||||
return blk_queue_zone_sectors(q) != *zone_sectors;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check consistency of zoned model and zone sectors across all targets. For
|
||||
* zone sectors, if the destination device is a zoned block device, it shall
|
||||
* have the specified zone_sectors.
|
||||
*/
|
||||
static int validate_hardware_zoned_model(struct dm_table *table,
|
||||
enum blk_zoned_model zoned_model,
|
||||
unsigned int zone_sectors)
|
||||
|
|
@ -1719,7 +1736,7 @@ static int validate_hardware_zoned_model(struct dm_table *table,
|
|||
return -EINVAL;
|
||||
|
||||
if (dm_table_any_dev_attr(table, device_not_matches_zone_sectors, &zone_sectors)) {
|
||||
DMERR("%s: zone sectors is not consistent across all devices",
|
||||
DMERR("%s: zone sectors is not consistent across all zoned devices",
|
||||
dm_device_name(table->md));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#define DM_VERITY_OPT_IGN_ZEROES "ignore_zero_blocks"
|
||||
#define DM_VERITY_OPT_AT_MOST_ONCE "check_at_most_once"
|
||||
|
||||
#define DM_VERITY_OPTS_MAX (2 + DM_VERITY_OPTS_FEC + \
|
||||
#define DM_VERITY_OPTS_MAX (3 + DM_VERITY_OPTS_FEC + \
|
||||
DM_VERITY_ROOT_HASH_VERIFICATION_OPTS)
|
||||
|
||||
static unsigned dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE;
|
||||
|
|
|
|||
|
|
@ -1143,7 +1143,7 @@ static int dmz_message(struct dm_target *ti, unsigned int argc, char **argv,
|
|||
static struct target_type dmz_type = {
|
||||
.name = "zoned",
|
||||
.version = {2, 0, 0},
|
||||
.features = DM_TARGET_SINGLETON | DM_TARGET_ZONED_HM,
|
||||
.features = DM_TARGET_SINGLETON | DM_TARGET_MIXED_ZONED_MODEL,
|
||||
.module = THIS_MODULE,
|
||||
.ctr = dmz_ctr,
|
||||
.dtr = dmz_dtr,
|
||||
|
|
|
|||
|
|
@ -2036,7 +2036,10 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
|
|||
if (size != dm_get_size(md))
|
||||
memset(&md->geometry, 0, sizeof(md->geometry));
|
||||
|
||||
set_capacity_and_notify(md->disk, size);
|
||||
if (!get_capacity(md->disk))
|
||||
set_capacity(md->disk, size);
|
||||
else
|
||||
set_capacity_and_notify(md->disk, size);
|
||||
|
||||
dm_table_event_callback(t, event_callback, md);
|
||||
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ static const struct omap_prm_data dra7_prm_data[] = {
|
|||
{
|
||||
.name = "l3init", .base = 0x4ae07300,
|
||||
.pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon,
|
||||
.rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012,
|
||||
.rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01,
|
||||
.clkdm_name = "pcie"
|
||||
},
|
||||
{
|
||||
|
|
@ -830,8 +830,12 @@ static int omap_reset_deassert(struct reset_controller_dev *rcdev,
|
|||
reset->prm->data->name, id);
|
||||
|
||||
exit:
|
||||
if (reset->clkdm)
|
||||
if (reset->clkdm) {
|
||||
/* At least dra7 iva needs a delay before clkdm idle */
|
||||
if (has_rstst)
|
||||
udelay(1);
|
||||
pdata->clkdm_allow_idle(reset->clkdm);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,11 +50,11 @@ config XEN_BALLOON_MEMORY_HOTPLUG
|
|||
|
||||
SUBSYSTEM=="memory", ACTION=="add", RUN+="/bin/sh -c '[ -f /sys$devpath/state ] && echo online > /sys$devpath/state'"
|
||||
|
||||
config XEN_BALLOON_MEMORY_HOTPLUG_LIMIT
|
||||
config XEN_MEMORY_HOTPLUG_LIMIT
|
||||
int "Hotplugged memory limit (in GiB) for a PV guest"
|
||||
default 512
|
||||
depends on XEN_HAVE_PVMMU
|
||||
depends on XEN_BALLOON_MEMORY_HOTPLUG
|
||||
depends on MEMORY_HOTPLUG
|
||||
help
|
||||
Maxmium amount of memory (in GiB) that a PV guest can be
|
||||
expanded to when using memory hotplug.
|
||||
|
|
|
|||
|
|
@ -233,6 +233,7 @@ struct acpi_pnp_type {
|
|||
|
||||
struct acpi_device_pnp {
|
||||
acpi_bus_id bus_id; /* Object name */
|
||||
int instance_no; /* Instance number of this object */
|
||||
struct acpi_pnp_type type; /* ID type */
|
||||
acpi_bus_address bus_address; /* _ADR */
|
||||
char *unique_id; /* _UID */
|
||||
|
|
|
|||
|
|
@ -253,7 +253,11 @@ struct target_type {
|
|||
#define dm_target_passes_integrity(type) ((type)->features & DM_TARGET_PASSES_INTEGRITY)
|
||||
|
||||
/*
|
||||
* Indicates that a target supports host-managed zoned block devices.
|
||||
* Indicates support for zoned block devices:
|
||||
* - DM_TARGET_ZONED_HM: the target also supports host-managed zoned
|
||||
* block devices but does not support combining different zoned models.
|
||||
* - DM_TARGET_MIXED_ZONED_MODEL: the target supports combining multiple
|
||||
* devices with different zoned models.
|
||||
*/
|
||||
#ifdef CONFIG_BLK_DEV_ZONED
|
||||
#define DM_TARGET_ZONED_HM 0x00000040
|
||||
|
|
@ -275,6 +279,15 @@ struct target_type {
|
|||
#define DM_TARGET_PASSES_CRYPTO 0x00000100
|
||||
#define dm_target_passes_crypto(type) ((type)->features & DM_TARGET_PASSES_CRYPTO)
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_ZONED
|
||||
#define DM_TARGET_MIXED_ZONED_MODEL 0x00000200
|
||||
#define dm_target_supports_mixed_zoned_model(type) \
|
||||
((type)->features & DM_TARGET_MIXED_ZONED_MODEL)
|
||||
#else
|
||||
#define DM_TARGET_MIXED_ZONED_MODEL 0x00000000
|
||||
#define dm_target_supports_mixed_zoned_model(type) (false)
|
||||
#endif
|
||||
|
||||
struct dm_target {
|
||||
struct dm_table *table;
|
||||
struct target_type *type;
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ static int __init em_debug_init(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
core_initcall(em_debug_init);
|
||||
fs_initcall(em_debug_init);
|
||||
#else /* CONFIG_DEBUG_FS */
|
||||
static void em_debug_create_pd(struct device *dev) {}
|
||||
static void em_debug_remove_pd(struct device *dev) {}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user