Merge remote-tracking branch 'torvalds/master' into perf/core
To pick up fixes in the last pushed perf/urgent. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
commit
4122c9c3f0
|
@ -54,7 +54,7 @@ properties:
|
|||
- const: toradex,apalis_t30
|
||||
- const: nvidia,tegra30
|
||||
- items:
|
||||
- const: toradex,apalis_t30-eval-v1.1
|
||||
- const: toradex,apalis_t30-v1.1-eval
|
||||
- const: toradex,apalis_t30-eval
|
||||
- const: toradex,apalis_t30-v1.1
|
||||
- const: toradex,apalis_t30
|
||||
|
|
|
@ -9,7 +9,7 @@ function block.
|
|||
|
||||
All DISP device tree nodes must be siblings to the central MMSYS_CONFIG node.
|
||||
For a description of the MMSYS_CONFIG binding, see
|
||||
Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt.
|
||||
Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml.
|
||||
|
||||
DISP function blocks
|
||||
====================
|
||||
|
|
|
@ -19,7 +19,9 @@ properties:
|
|||
- const: allwinner,sun8i-v3s-emac
|
||||
- const: allwinner,sun50i-a64-emac
|
||||
- items:
|
||||
- const: allwinner,sun50i-h6-emac
|
||||
- enum:
|
||||
- allwinner,sun20i-d1-emac
|
||||
- allwinner,sun50i-h6-emac
|
||||
- const: allwinner,sun50i-a64-emac
|
||||
|
||||
reg:
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/ufs/samsung,exynos-ufs.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung SoC series UFS host controller Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Alim Akhtar <alim.akhtar@samsung.com>
|
||||
|
||||
description: |
|
||||
Each Samsung UFS host controller instance should have its own node.
|
||||
This binding define Samsung specific binding other then what is used
|
||||
in the common ufshcd bindings
|
||||
[1] Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
|
||||
|
||||
properties:
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- samsung,exynos7-ufs
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: HCI register
|
||||
- description: vendor specific register
|
||||
- description: unipro register
|
||||
- description: UFS protector register
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: hci
|
||||
- const: vs_hci
|
||||
- const: unipro
|
||||
- const: ufsp
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: ufs link core clock
|
||||
- description: unipro main clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: core_clk
|
||||
- const: sclk_unipro_main
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
phys:
|
||||
maxItems: 1
|
||||
|
||||
phy-names:
|
||||
const: ufs-phy
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- phys
|
||||
- phy-names
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/exynos7-clk.h>
|
||||
|
||||
ufs: ufs@15570000 {
|
||||
compatible = "samsung,exynos7-ufs";
|
||||
reg = <0x15570000 0x100>,
|
||||
<0x15570100 0x100>,
|
||||
<0x15571000 0x200>,
|
||||
<0x15572000 0x300>;
|
||||
reg-names = "hci", "vs_hci", "unipro", "ufsp";
|
||||
interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clock_fsys1 ACLK_UFS20_LINK>,
|
||||
<&clock_fsys1 SCLK_UFSUNIPRO20_USER>;
|
||||
clock-names = "core_clk", "sclk_unipro_main";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>;
|
||||
phys = <&ufs_phy>;
|
||||
phy-names = "ufs-phy";
|
||||
};
|
||||
...
|
|
@ -296,7 +296,7 @@ not available.
|
|||
Device Tree bindings and board design
|
||||
=====================================
|
||||
|
||||
This section references ``Documentation/devicetree/bindings/net/dsa/sja1105.txt``
|
||||
This section references ``Documentation/devicetree/bindings/net/dsa/nxp,sja1105.yaml``
|
||||
and aims to showcase some potential switch caveats.
|
||||
|
||||
RMII PHY role and out-of-band signaling
|
||||
|
|
|
@ -14342,7 +14342,8 @@ F: Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml
|
|||
F: drivers/pci/controller/pci-ixp4xx.c
|
||||
|
||||
PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD)
|
||||
M: Jonathan Derrick <jonathan.derrick@intel.com>
|
||||
M: Nirmal Patel <nirmal.patel@linux.intel.com>
|
||||
R: Jonathan Derrick <jonathan.derrick@linux.dev>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/pci/controller/vmd.c
|
||||
|
|
2
Makefile
2
Makefile
|
@ -2,7 +2,7 @@
|
|||
VERSION = 5
|
||||
PATCHLEVEL = 15
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc1
|
||||
EXTRAVERSION = -rc2
|
||||
NAME = Opossums on Parade
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -20,7 +20,7 @@ config ALPHA
|
|||
select NEED_SG_DMA_LENGTH
|
||||
select VIRT_TO_BUS
|
||||
select GENERIC_IRQ_PROBE
|
||||
select GENERIC_PCI_IOMAP if PCI
|
||||
select GENERIC_PCI_IOMAP
|
||||
select AUTO_IRQ_AFFINITY if SMP
|
||||
select GENERIC_IRQ_SHOW
|
||||
select ARCH_WANT_IPC_PARSE_VERSION
|
||||
|
@ -199,7 +199,6 @@ config ALPHA_EIGER
|
|||
|
||||
config ALPHA_JENSEN
|
||||
bool "Jensen"
|
||||
depends on BROKEN
|
||||
select HAVE_EISA
|
||||
help
|
||||
DEC PC 150 AXP (aka Jensen): This is a very old Digital system - one
|
||||
|
|
|
@ -16,3 +16,4 @@ extern void __divlu(void);
|
|||
extern void __remlu(void);
|
||||
extern void __divqu(void);
|
||||
extern void __remqu(void);
|
||||
extern unsigned long __udiv_qrnnd(unsigned long *, unsigned long, unsigned long , unsigned long);
|
||||
|
|
|
@ -60,7 +60,7 @@ extern inline void set_hae(unsigned long new_hae)
|
|||
* Change virtual addresses to physical addresses and vv.
|
||||
*/
|
||||
#ifdef USE_48_BIT_KSEG
|
||||
static inline unsigned long virt_to_phys(void *address)
|
||||
static inline unsigned long virt_to_phys(volatile void *address)
|
||||
{
|
||||
return (unsigned long)address - IDENT_ADDR;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ static inline void * phys_to_virt(unsigned long address)
|
|||
return (void *) (address + IDENT_ADDR);
|
||||
}
|
||||
#else
|
||||
static inline unsigned long virt_to_phys(void *address)
|
||||
static inline unsigned long virt_to_phys(volatile void *address)
|
||||
{
|
||||
unsigned long phys = (unsigned long)address;
|
||||
|
||||
|
@ -106,7 +106,7 @@ static inline void * phys_to_virt(unsigned long address)
|
|||
extern unsigned long __direct_map_base;
|
||||
extern unsigned long __direct_map_size;
|
||||
|
||||
static inline unsigned long __deprecated virt_to_bus(void *address)
|
||||
static inline unsigned long __deprecated virt_to_bus(volatile void *address)
|
||||
{
|
||||
unsigned long phys = virt_to_phys(address);
|
||||
unsigned long bus = phys + __direct_map_base;
|
||||
|
|
|
@ -111,18 +111,18 @@ __EXTERN_INLINE void jensen_set_hae(unsigned long addr)
|
|||
* convinced that I need one of the newer machines.
|
||||
*/
|
||||
|
||||
static inline unsigned int jensen_local_inb(unsigned long addr)
|
||||
__EXTERN_INLINE unsigned int jensen_local_inb(unsigned long addr)
|
||||
{
|
||||
return 0xff & *(vuip)((addr << 9) + EISA_VL82C106);
|
||||
}
|
||||
|
||||
static inline void jensen_local_outb(u8 b, unsigned long addr)
|
||||
__EXTERN_INLINE void jensen_local_outb(u8 b, unsigned long addr)
|
||||
{
|
||||
*(vuip)((addr << 9) + EISA_VL82C106) = b;
|
||||
mb();
|
||||
}
|
||||
|
||||
static inline unsigned int jensen_bus_inb(unsigned long addr)
|
||||
__EXTERN_INLINE unsigned int jensen_bus_inb(unsigned long addr)
|
||||
{
|
||||
long result;
|
||||
|
||||
|
@ -131,7 +131,7 @@ static inline unsigned int jensen_bus_inb(unsigned long addr)
|
|||
return __kernel_extbl(result, addr & 3);
|
||||
}
|
||||
|
||||
static inline void jensen_bus_outb(u8 b, unsigned long addr)
|
||||
__EXTERN_INLINE void jensen_bus_outb(u8 b, unsigned long addr)
|
||||
{
|
||||
jensen_set_hae(0);
|
||||
*(vuip)((addr << 7) + EISA_IO + 0x00) = b * 0x01010101;
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef __ALPHA_SETUP_H
|
||||
#define __ALPHA_SETUP_H
|
||||
|
||||
#include <uapi/asm/setup.h>
|
||||
|
||||
/*
|
||||
* We leave one page for the initial stack page, and one page for
|
||||
* the initial process structure. Also, the console eats 3 MB for
|
||||
* the initial bootloader (one of which we can reclaim later).
|
||||
*/
|
||||
#define BOOT_PCB 0x20000000
|
||||
#define BOOT_ADDR 0x20000000
|
||||
/* Remove when official MILO sources have ELF support: */
|
||||
#define BOOT_SIZE (16*1024)
|
||||
|
||||
#ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS
|
||||
#define KERNEL_START_PHYS 0x300000 /* Old bootloaders hardcoded this. */
|
||||
#else
|
||||
#define KERNEL_START_PHYS 0x1000000 /* required: Wildfire/Titan/Marvel */
|
||||
#endif
|
||||
|
||||
#define KERNEL_START (PAGE_OFFSET+KERNEL_START_PHYS)
|
||||
#define SWAPPER_PGD KERNEL_START
|
||||
#define INIT_STACK (PAGE_OFFSET+KERNEL_START_PHYS+0x02000)
|
||||
#define EMPTY_PGT (PAGE_OFFSET+KERNEL_START_PHYS+0x04000)
|
||||
#define EMPTY_PGE (PAGE_OFFSET+KERNEL_START_PHYS+0x08000)
|
||||
#define ZERO_PGE (PAGE_OFFSET+KERNEL_START_PHYS+0x0A000)
|
||||
|
||||
#define START_ADDR (PAGE_OFFSET+KERNEL_START_PHYS+0x10000)
|
||||
|
||||
/*
|
||||
* This is setup by the secondary bootstrap loader. Because
|
||||
* the zero page is zeroed out as soon as the vm system is
|
||||
* initialized, we need to copy things out into a more permanent
|
||||
* place.
|
||||
*/
|
||||
#define PARAM ZERO_PGE
|
||||
#define COMMAND_LINE ((char *)(absolute_pointer(PARAM + 0x0000)))
|
||||
#define INITRD_START (*(unsigned long *) (PARAM+0x100))
|
||||
#define INITRD_SIZE (*(unsigned long *) (PARAM+0x108))
|
||||
|
||||
#endif
|
|
@ -1,43 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
#ifndef __ALPHA_SETUP_H
|
||||
#define __ALPHA_SETUP_H
|
||||
#ifndef _UAPI__ALPHA_SETUP_H
|
||||
#define _UAPI__ALPHA_SETUP_H
|
||||
|
||||
#define COMMAND_LINE_SIZE 256
|
||||
|
||||
/*
|
||||
* We leave one page for the initial stack page, and one page for
|
||||
* the initial process structure. Also, the console eats 3 MB for
|
||||
* the initial bootloader (one of which we can reclaim later).
|
||||
*/
|
||||
#define BOOT_PCB 0x20000000
|
||||
#define BOOT_ADDR 0x20000000
|
||||
/* Remove when official MILO sources have ELF support: */
|
||||
#define BOOT_SIZE (16*1024)
|
||||
|
||||
#ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS
|
||||
#define KERNEL_START_PHYS 0x300000 /* Old bootloaders hardcoded this. */
|
||||
#else
|
||||
#define KERNEL_START_PHYS 0x1000000 /* required: Wildfire/Titan/Marvel */
|
||||
#endif
|
||||
|
||||
#define KERNEL_START (PAGE_OFFSET+KERNEL_START_PHYS)
|
||||
#define SWAPPER_PGD KERNEL_START
|
||||
#define INIT_STACK (PAGE_OFFSET+KERNEL_START_PHYS+0x02000)
|
||||
#define EMPTY_PGT (PAGE_OFFSET+KERNEL_START_PHYS+0x04000)
|
||||
#define EMPTY_PGE (PAGE_OFFSET+KERNEL_START_PHYS+0x08000)
|
||||
#define ZERO_PGE (PAGE_OFFSET+KERNEL_START_PHYS+0x0A000)
|
||||
|
||||
#define START_ADDR (PAGE_OFFSET+KERNEL_START_PHYS+0x10000)
|
||||
|
||||
/*
|
||||
* This is setup by the secondary bootstrap loader. Because
|
||||
* the zero page is zeroed out as soon as the vm system is
|
||||
* initialized, we need to copy things out into a more permanent
|
||||
* place.
|
||||
*/
|
||||
#define PARAM ZERO_PGE
|
||||
#define COMMAND_LINE ((char*)(PARAM + 0x0000))
|
||||
#define INITRD_START (*(unsigned long *) (PARAM+0x100))
|
||||
#define INITRD_SIZE (*(unsigned long *) (PARAM+0x108))
|
||||
|
||||
#endif
|
||||
#endif /* _UAPI__ALPHA_SETUP_H */
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
*
|
||||
* Code supporting the Jensen.
|
||||
*/
|
||||
#define __EXTERN_INLINE
|
||||
#include <asm/io.h>
|
||||
#include <asm/jensen.h>
|
||||
#undef __EXTERN_INLINE
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
|
@ -17,11 +22,6 @@
|
|||
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
#define __EXTERN_INLINE inline
|
||||
#include <asm/io.h>
|
||||
#include <asm/jensen.h>
|
||||
#undef __EXTERN_INLINE
|
||||
|
||||
#include <asm/dma.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mmu_context.h>
|
||||
|
|
|
@ -14,6 +14,7 @@ ev6-$(CONFIG_ALPHA_EV6) := ev6-
|
|||
ev67-$(CONFIG_ALPHA_EV67) := ev67-
|
||||
|
||||
lib-y = __divqu.o __remqu.o __divlu.o __remlu.o \
|
||||
udiv-qrnnd.o \
|
||||
udelay.o \
|
||||
$(ev6-y)memset.o \
|
||||
$(ev6-y)memcpy.o \
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
# along with GCC; see the file COPYING. If not, write to the
|
||||
# Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
# MA 02111-1307, USA.
|
||||
#include <asm/export.h>
|
||||
|
||||
.set noreorder
|
||||
.set noat
|
||||
|
@ -161,3 +162,4 @@ $Odd:
|
|||
ret $31,($26),1
|
||||
|
||||
.end __udiv_qrnnd
|
||||
EXPORT_SYMBOL(__udiv_qrnnd)
|
|
@ -7,4 +7,4 @@ ccflags-y := -w
|
|||
|
||||
obj-$(CONFIG_MATHEMU) += math-emu.o
|
||||
|
||||
math-emu-objs := math.o qrnnd.o
|
||||
math-emu-objs := math.o
|
||||
|
|
|
@ -403,5 +403,3 @@ alpha_fp_emul_imprecise (struct pt_regs *regs, unsigned long write_mask)
|
|||
egress:
|
||||
return si_code;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(__udiv_qrnnd);
|
||||
|
|
|
@ -513,7 +513,7 @@ size_t sve_state_size(struct task_struct const *task)
|
|||
void sve_alloc(struct task_struct *task)
|
||||
{
|
||||
if (task->thread.sve_state) {
|
||||
memset(task->thread.sve_state, 0, sve_state_size(current));
|
||||
memset(task->thread.sve_state, 0, sve_state_size(task));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include <linux/mman.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/nospec.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/unistd.h>
|
||||
|
@ -58,7 +57,7 @@
|
|||
|
||||
#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK)
|
||||
#include <linux/stackprotector.h>
|
||||
unsigned long __stack_chk_guard __read_mostly;
|
||||
unsigned long __stack_chk_guard __ro_after_init;
|
||||
EXPORT_SYMBOL(__stack_chk_guard);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -17,21 +17,21 @@
|
|||
* two accesses to memory, which may be undesirable for some devices.
|
||||
*/
|
||||
#define in_8(addr) \
|
||||
({ u8 __v = (*(__force volatile u8 *) (addr)); __v; })
|
||||
({ u8 __v = (*(__force volatile u8 *) (unsigned long)(addr)); __v; })
|
||||
#define in_be16(addr) \
|
||||
({ u16 __v = (*(__force volatile u16 *) (addr)); __v; })
|
||||
({ u16 __v = (*(__force volatile u16 *) (unsigned long)(addr)); __v; })
|
||||
#define in_be32(addr) \
|
||||
({ u32 __v = (*(__force volatile u32 *) (addr)); __v; })
|
||||
({ u32 __v = (*(__force volatile u32 *) (unsigned long)(addr)); __v; })
|
||||
#define in_le16(addr) \
|
||||
({ u16 __v = le16_to_cpu(*(__force volatile __le16 *) (addr)); __v; })
|
||||
({ u16 __v = le16_to_cpu(*(__force volatile __le16 *) (unsigned long)(addr)); __v; })
|
||||
#define in_le32(addr) \
|
||||
({ u32 __v = le32_to_cpu(*(__force volatile __le32 *) (addr)); __v; })
|
||||
({ u32 __v = le32_to_cpu(*(__force volatile __le32 *) (unsigned long)(addr)); __v; })
|
||||
|
||||
#define out_8(addr,b) (void)((*(__force volatile u8 *) (addr)) = (b))
|
||||
#define out_be16(addr,w) (void)((*(__force volatile u16 *) (addr)) = (w))
|
||||
#define out_be32(addr,l) (void)((*(__force volatile u32 *) (addr)) = (l))
|
||||
#define out_le16(addr,w) (void)((*(__force volatile __le16 *) (addr)) = cpu_to_le16(w))
|
||||
#define out_le32(addr,l) (void)((*(__force volatile __le32 *) (addr)) = cpu_to_le32(l))
|
||||
#define out_8(addr,b) (void)((*(__force volatile u8 *) (unsigned long)(addr)) = (b))
|
||||
#define out_be16(addr,w) (void)((*(__force volatile u16 *) (unsigned long)(addr)) = (w))
|
||||
#define out_be32(addr,l) (void)((*(__force volatile u32 *) (unsigned long)(addr)) = (l))
|
||||
#define out_le16(addr,w) (void)((*(__force volatile __le16 *) (unsigned long)(addr)) = cpu_to_le16(w))
|
||||
#define out_le32(addr,l) (void)((*(__force volatile __le32 *) (unsigned long)(addr)) = cpu_to_le32(l))
|
||||
|
||||
#define raw_inb in_8
|
||||
#define raw_inw in_be16
|
||||
|
|
|
@ -171,7 +171,6 @@ static int bcd2int (unsigned char b)
|
|||
|
||||
int mvme147_hwclk(int op, struct rtc_time *t)
|
||||
{
|
||||
#warning check me!
|
||||
if (!op) {
|
||||
m147_rtc->ctrl = RTC_READ;
|
||||
t->tm_year = bcd2int (m147_rtc->bcd_year);
|
||||
|
@ -183,6 +182,9 @@ int mvme147_hwclk(int op, struct rtc_time *t)
|
|||
m147_rtc->ctrl = 0;
|
||||
if (t->tm_year < 70)
|
||||
t->tm_year += 100;
|
||||
} else {
|
||||
/* FIXME Setting the time is not yet supported */
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -436,7 +436,6 @@ int bcd2int (unsigned char b)
|
|||
|
||||
int mvme16x_hwclk(int op, struct rtc_time *t)
|
||||
{
|
||||
#warning check me!
|
||||
if (!op) {
|
||||
rtc->ctrl = RTC_READ;
|
||||
t->tm_year = bcd2int (rtc->bcd_year);
|
||||
|
@ -448,6 +447,9 @@ int mvme16x_hwclk(int op, struct rtc_time *t)
|
|||
rtc->ctrl = 0;
|
||||
if (t->tm_year < 70)
|
||||
t->tm_year += 100;
|
||||
} else {
|
||||
/* FIXME Setting the time is not yet supported */
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ extern int npmem_ranges;
|
|||
#include <asm-generic/getorder.h>
|
||||
#include <asm/pdc.h>
|
||||
|
||||
#define PAGE0 ((struct zeropage *)__PAGE_OFFSET)
|
||||
#define PAGE0 ((struct zeropage *)absolute_pointer(__PAGE_OFFSET))
|
||||
|
||||
/* DEFINITION OF THE ZERO-PAGE (PAG0) */
|
||||
/* based on work by Jason Eckhardt (jason@equator.com) */
|
||||
|
|
|
@ -513,12 +513,15 @@ void ioport_unmap(void __iomem *addr)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
|
||||
{
|
||||
if (!INDIRECT_ADDR(addr)) {
|
||||
iounmap(addr);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(pci_iounmap);
|
||||
#endif
|
||||
|
||||
EXPORT_SYMBOL(ioread8);
|
||||
EXPORT_SYMBOL(ioread16);
|
||||
|
@ -544,4 +547,3 @@ EXPORT_SYMBOL(iowrite16_rep);
|
|||
EXPORT_SYMBOL(iowrite32_rep);
|
||||
EXPORT_SYMBOL(ioport_map);
|
||||
EXPORT_SYMBOL(ioport_unmap);
|
||||
EXPORT_SYMBOL(pci_iounmap);
|
||||
|
|
|
@ -35,7 +35,6 @@ endif
|
|||
BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
|
||||
-fno-strict-aliasing -O2 -msoft-float -mno-altivec -mno-vsx \
|
||||
-pipe -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
|
||||
-include $(srctree)/include/linux/compiler_attributes.h \
|
||||
$(LINUXINCLUDE)
|
||||
|
||||
ifdef CONFIG_PPC64_BOOT_WRAPPER
|
||||
|
@ -70,6 +69,7 @@ ifeq ($(call cc-option-yn, -fstack-protector),y)
|
|||
BOOTCFLAGS += -fno-stack-protector
|
||||
endif
|
||||
|
||||
BOOTCFLAGS += -include $(srctree)/include/linux/compiler_attributes.h
|
||||
BOOTCFLAGS += -I$(objtree)/$(obj) -I$(srctree)/$(obj)
|
||||
|
||||
DTC_FLAGS ?= -p 1024
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <asm/switch_to.h>
|
||||
#include <asm/syscall.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/tm.h>
|
||||
#include <asm/unistd.h>
|
||||
|
||||
#if defined(CONFIG_PPC_ADV_DEBUG_REGS) && defined(CONFIG_PPC32)
|
||||
|
@ -136,6 +137,48 @@ notrace long system_call_exception(long r3, long r4, long r5,
|
|||
*/
|
||||
irq_soft_mask_regs_set_state(regs, IRQS_ENABLED);
|
||||
|
||||
/*
|
||||
* If system call is called with TM active, set _TIF_RESTOREALL to
|
||||
* prevent RFSCV being used to return to userspace, because POWER9
|
||||
* TM implementation has problems with this instruction returning to
|
||||
* transactional state. Final register values are not relevant because
|
||||
* the transaction will be aborted upon return anyway. Or in the case
|
||||
* of unsupported_scv SIGILL fault, the return state does not much
|
||||
* matter because it's an edge case.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) &&
|
||||
unlikely(MSR_TM_TRANSACTIONAL(regs->msr)))
|
||||
current_thread_info()->flags |= _TIF_RESTOREALL;
|
||||
|
||||
/*
|
||||
* If the system call was made with a transaction active, doom it and
|
||||
* return without performing the system call. Unless it was an
|
||||
* unsupported scv vector, in which case it's treated like an illegal
|
||||
* instruction.
|
||||
*/
|
||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
if (unlikely(MSR_TM_TRANSACTIONAL(regs->msr)) &&
|
||||
!trap_is_unsupported_scv(regs)) {
|
||||
/* Enable TM in the kernel, and disable EE (for scv) */
|
||||
hard_irq_disable();
|
||||
mtmsr(mfmsr() | MSR_TM);
|
||||
|
||||
/* tabort, this dooms the transaction, nothing else */
|
||||
asm volatile(".long 0x7c00071d | ((%0) << 16)"
|
||||
:: "r"(TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT));
|
||||
|
||||
/*
|
||||
* Userspace will never see the return value. Execution will
|
||||
* resume after the tbegin. of the aborted transaction with the
|
||||
* checkpointed register state. A context switch could occur
|
||||
* or signal delivered to the process before resuming the
|
||||
* doomed transaction context, but that should all be handled
|
||||
* as expected.
|
||||
*/
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif // CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
|
||||
local_irq_enable();
|
||||
|
||||
if (unlikely(current_thread_info()->flags & _TIF_SYSCALL_DOTRACE)) {
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <asm/mmu.h>
|
||||
#include <asm/ppc_asm.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/tm.h>
|
||||
|
||||
.section ".toc","aw"
|
||||
SYS_CALL_TABLE:
|
||||
|
@ -55,12 +54,6 @@ COMPAT_SYS_CALL_TABLE:
|
|||
.globl system_call_vectored_\name
|
||||
system_call_vectored_\name:
|
||||
_ASM_NOKPROBE_SYMBOL(system_call_vectored_\name)
|
||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
BEGIN_FTR_SECTION
|
||||
extrdi. r10, r12, 1, (63-MSR_TS_T_LG) /* transaction active? */
|
||||
bne tabort_syscall
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_TM)
|
||||
#endif
|
||||
SCV_INTERRUPT_TO_KERNEL
|
||||
mr r10,r1
|
||||
ld r1,PACAKSAVE(r13)
|
||||
|
@ -247,12 +240,6 @@ _ASM_NOKPROBE_SYMBOL(system_call_common_real)
|
|||
.globl system_call_common
|
||||
system_call_common:
|
||||
_ASM_NOKPROBE_SYMBOL(system_call_common)
|
||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
BEGIN_FTR_SECTION
|
||||
extrdi. r10, r12, 1, (63-MSR_TS_T_LG) /* transaction active? */
|
||||
bne tabort_syscall
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_TM)
|
||||
#endif
|
||||
mr r10,r1
|
||||
ld r1,PACAKSAVE(r13)
|
||||
std r10,0(r1)
|
||||
|
@ -425,34 +412,6 @@ SOFT_MASK_TABLE(.Lsyscall_rst_start, 1b)
|
|||
RESTART_TABLE(.Lsyscall_rst_start, .Lsyscall_rst_end, syscall_restart)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
tabort_syscall:
|
||||
_ASM_NOKPROBE_SYMBOL(tabort_syscall)
|
||||
/* Firstly we need to enable TM in the kernel */
|
||||
mfmsr r10
|
||||
li r9, 1
|
||||
rldimi r10, r9, MSR_TM_LG, 63-MSR_TM_LG
|
||||
mtmsrd r10, 0
|
||||
|
||||
/* tabort, this dooms the transaction, nothing else */
|
||||
li r9, (TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT)
|
||||
TABORT(R9)
|
||||
|
||||
/*
|
||||
* Return directly to userspace. We have corrupted user register state,
|
||||
* but userspace will never see that register state. Execution will
|
||||
* resume after the tbegin of the aborted transaction with the
|
||||
* checkpointed register state.
|
||||
*/
|
||||
li r9, MSR_RI
|
||||
andc r10, r10, r9
|
||||
mtmsrd r10, 1
|
||||
mtspr SPRN_SRR0, r11
|
||||
mtspr SPRN_SRR1, r12
|
||||
RFI_TO_USER
|
||||
b . /* prevent speculative execution */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If MSR EE/RI was never enabled, IRQs not reconciled, NVGPRs not
|
||||
* touched, no exit work created, then this can be used.
|
||||
|
|
|
@ -249,6 +249,7 @@ void machine_check_queue_event(void)
|
|||
{
|
||||
int index;
|
||||
struct machine_check_event evt;
|
||||
unsigned long msr;
|
||||
|
||||
if (!get_mce_event(&evt, MCE_EVENT_RELEASE))
|
||||
return;
|
||||
|
@ -262,8 +263,20 @@ void machine_check_queue_event(void)
|
|||
memcpy(&local_paca->mce_info->mce_event_queue[index],
|
||||
&evt, sizeof(evt));
|
||||
|
||||
/* Queue irq work to process this event later. */
|
||||
irq_work_queue(&mce_event_process_work);
|
||||
/*
|
||||
* Queue irq work to process this event later. Before
|
||||
* queuing the work enable translation for non radix LPAR,
|
||||
* as irq_work_queue may try to access memory outside RMO
|
||||
* region.
|
||||
*/
|
||||
if (!radix_enabled() && firmware_has_feature(FW_FEATURE_LPAR)) {
|
||||
msr = mfmsr();
|
||||
mtmsr(msr | MSR_IR | MSR_DR);
|
||||
irq_work_queue(&mce_event_process_work);
|
||||
mtmsr(msr);
|
||||
} else {
|
||||
irq_work_queue(&mce_event_process_work);
|
||||
}
|
||||
}
|
||||
|
||||
void mce_common_process_ue(struct pt_regs *regs,
|
||||
|
|
|
@ -2536,7 +2536,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_P9_TM_HV_ASSIST)
|
|||
/* The following code handles the fake_suspend = 1 case */
|
||||
mflr r0
|
||||
std r0, PPC_LR_STKOFF(r1)
|
||||
stdu r1, -PPC_MIN_STKFRM(r1)
|
||||
stdu r1, -TM_FRAME_SIZE(r1)
|
||||
|
||||
/* Turn on TM. */
|
||||
mfmsr r8
|
||||
|
@ -2551,10 +2551,42 @@ BEGIN_FTR_SECTION
|
|||
END_FTR_SECTION_IFSET(CPU_FTR_P9_TM_XER_SO_BUG)
|
||||
nop
|
||||
|
||||
/*
|
||||
* It's possible that treclaim. may modify registers, if we have lost
|
||||
* track of fake-suspend state in the guest due to it using rfscv.
|
||||
* Save and restore registers in case this occurs.
|
||||
*/
|
||||
mfspr r3, SPRN_DSCR
|
||||
mfspr r4, SPRN_XER
|
||||
mfspr r5, SPRN_AMR
|
||||
/* SPRN_TAR would need to be saved here if the kernel ever used it */
|
||||
mfcr r12
|
||||
SAVE_NVGPRS(r1)
|
||||
SAVE_GPR(2, r1)
|
||||
SAVE_GPR(3, r1)
|
||||
SAVE_GPR(4, r1)
|
||||
SAVE_GPR(5, r1)
|
||||
stw r12, 8(r1)
|
||||
std r1, HSTATE_HOST_R1(r13)
|
||||
|
||||
/* We have to treclaim here because that's the only way to do S->N */
|
||||
li r3, TM_CAUSE_KVM_RESCHED
|
||||
TRECLAIM(R3)
|
||||
|
||||
GET_PACA(r13)
|
||||
ld r1, HSTATE_HOST_R1(r13)
|
||||
REST_GPR(2, r1)
|
||||
REST_GPR(3, r1)
|
||||
REST_GPR(4, r1)
|
||||
REST_GPR(5, r1)
|
||||
lwz r12, 8(r1)
|
||||
REST_NVGPRS(r1)
|
||||
mtspr SPRN_DSCR, r3
|
||||
mtspr SPRN_XER, r4
|
||||
mtspr SPRN_AMR, r5
|
||||
mtcr r12
|
||||
HMT_MEDIUM
|
||||
|
||||
/*
|
||||
* We were in fake suspend, so we are not going to save the
|
||||
* register state as the guest checkpointed state (since
|
||||
|
@ -2582,7 +2614,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_P9_TM_XER_SO_BUG)
|
|||
std r5, VCPU_TFHAR(r9)
|
||||
std r6, VCPU_TFIAR(r9)
|
||||
|
||||
addi r1, r1, PPC_MIN_STKFRM
|
||||
addi r1, r1, TM_FRAME_SIZE
|
||||
ld r0, PPC_LR_STKOFF(r1)
|
||||
mtlr r0
|
||||
blr
|
||||
|
|
|
@ -348,9 +348,9 @@ static int xics_host_map(struct irq_domain *domain, unsigned int virq,
|
|||
if (xics_ics->check(xics_ics, hwirq))
|
||||
return -EINVAL;
|
||||
|
||||
/* No chip data for the XICS domain */
|
||||
/* Let the ICS be the chip data for the XICS domain. For ICS native */
|
||||
irq_domain_set_info(domain, virq, hwirq, xics_ics->chip,
|
||||
NULL, handle_fasteoi_irq, NULL, NULL);
|
||||
xics_ics, handle_fasteoi_irq, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -685,16 +685,6 @@ config STACK_GUARD
|
|||
The minimum size for the stack guard should be 256 for 31 bit and
|
||||
512 for 64 bit.
|
||||
|
||||
config WARN_DYNAMIC_STACK
|
||||
def_bool n
|
||||
prompt "Emit compiler warnings for function with dynamic stack usage"
|
||||
help
|
||||
This option enables the compiler option -mwarn-dynamicstack. If the
|
||||
compiler supports this options generates warnings for functions
|
||||
that dynamically allocate stack space using alloca.
|
||||
|
||||
Say N if you are unsure.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "I/O subsystem"
|
||||
|
|
|
@ -85,13 +85,6 @@ cflags-$(CONFIG_CHECK_STACK) += -mstack-guard=$(CONFIG_STACK_GUARD)
|
|||
endif
|
||||
endif
|
||||
|
||||
ifdef CONFIG_WARN_DYNAMIC_STACK
|
||||
ifneq ($(call cc-option,-mwarn-dynamicstack),)
|
||||
KBUILD_CFLAGS += -mwarn-dynamicstack
|
||||
KBUILD_CFLAGS_DECOMPRESSOR += -mwarn-dynamicstack
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef CONFIG_EXPOLINE
|
||||
ifneq ($(call cc-option,$(CC_FLAGS_MARCH) -mindirect-branch=thunk),)
|
||||
CC_FLAGS_EXPOLINE := -mindirect-branch=thunk
|
||||
|
|
|
@ -10,6 +10,7 @@ CONFIG_BPF_JIT=y
|
|||
CONFIG_BPF_JIT_ALWAYS_ON=y
|
||||
CONFIG_BPF_LSM=y
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_SCHED_CORE=y
|
||||
CONFIG_BSD_PROCESS_ACCT=y
|
||||
CONFIG_BSD_PROCESS_ACCT_V3=y
|
||||
CONFIG_TASKSTATS=y
|
||||
|
@ -503,6 +504,7 @@ CONFIG_NLMON=m
|
|||
# CONFIG_NET_VENDOR_HUAWEI is not set
|
||||
# CONFIG_NET_VENDOR_INTEL is not set
|
||||
# CONFIG_NET_VENDOR_MICROSOFT is not set
|
||||
# CONFIG_NET_VENDOR_LITEX is not set
|
||||
# CONFIG_NET_VENDOR_MARVELL is not set
|
||||
CONFIG_MLX4_EN=m
|
||||
CONFIG_MLX5_CORE=m
|
||||
|
@ -661,7 +663,6 @@ CONFIG_NFSD_V3_ACL=y
|
|||
CONFIG_NFSD_V4=y
|
||||
CONFIG_NFSD_V4_SECURITY_LABEL=y
|
||||
CONFIG_CIFS=m
|
||||
CONFIG_CIFS_WEAK_PW_HASH=y
|
||||
CONFIG_CIFS_UPCALL=y
|
||||
CONFIG_CIFS_XATTR=y
|
||||
CONFIG_CIFS_POSIX=y
|
||||
|
@ -720,6 +721,8 @@ CONFIG_CRYPTO_XCBC=m
|
|||
CONFIG_CRYPTO_VMAC=m
|
||||
CONFIG_CRYPTO_CRC32=m
|
||||
CONFIG_CRYPTO_BLAKE2S=m
|
||||
CONFIG_CRYPTO_MD4=m
|
||||
CONFIG_CRYPTO_MD5=y
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_SHA3=m
|
||||
|
@ -774,7 +777,6 @@ CONFIG_RANDOM32_SELFTEST=y
|
|||
CONFIG_DMA_CMA=y
|
||||
CONFIG_CMA_SIZE_MBYTES=0
|
||||
CONFIG_DMA_API_DEBUG=y
|
||||
CONFIG_STRING_SELFTEST=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DYNAMIC_DEBUG=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
|
@ -853,12 +855,12 @@ CONFIG_FAIL_FUNCTION=y
|
|||
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
|
||||
CONFIG_LKDTM=m
|
||||
CONFIG_TEST_MIN_HEAP=y
|
||||
CONFIG_TEST_SORT=y
|
||||
CONFIG_KPROBES_SANITY_TEST=y
|
||||
CONFIG_RBTREE_TEST=y
|
||||
CONFIG_INTERVAL_TREE_TEST=m
|
||||
CONFIG_PERCPU_TEST=m
|
||||
CONFIG_ATOMIC64_SELFTEST=y
|
||||
CONFIG_STRING_SELFTEST=y
|
||||
CONFIG_TEST_BITOPS=m
|
||||
CONFIG_TEST_BPF=m
|
||||
CONFIG_TEST_LIVEPATCH=m
|
||||
|
|
|
@ -8,6 +8,7 @@ CONFIG_BPF_SYSCALL=y
|
|||
CONFIG_BPF_JIT=y
|
||||
CONFIG_BPF_JIT_ALWAYS_ON=y
|
||||
CONFIG_BPF_LSM=y
|
||||
CONFIG_SCHED_CORE=y
|
||||
CONFIG_BSD_PROCESS_ACCT=y
|
||||
CONFIG_BSD_PROCESS_ACCT_V3=y
|
||||
CONFIG_TASKSTATS=y
|
||||
|
@ -494,6 +495,7 @@ CONFIG_NLMON=m
|
|||
# CONFIG_NET_VENDOR_HUAWEI is not set
|
||||
# CONFIG_NET_VENDOR_INTEL is not set
|
||||
# CONFIG_NET_VENDOR_MICROSOFT is not set
|
||||
# CONFIG_NET_VENDOR_LITEX is not set
|
||||
# CONFIG_NET_VENDOR_MARVELL is not set
|
||||
CONFIG_MLX4_EN=m
|
||||
CONFIG_MLX5_CORE=m
|
||||
|
@ -648,7 +650,6 @@ CONFIG_NFSD_V3_ACL=y
|
|||
CONFIG_NFSD_V4=y
|
||||
CONFIG_NFSD_V4_SECURITY_LABEL=y
|
||||
CONFIG_CIFS=m
|
||||
CONFIG_CIFS_WEAK_PW_HASH=y
|
||||
CONFIG_CIFS_UPCALL=y
|
||||
CONFIG_CIFS_XATTR=y
|
||||
CONFIG_CIFS_POSIX=y
|
||||
|
@ -708,6 +709,8 @@ CONFIG_CRYPTO_XCBC=m
|
|||
CONFIG_CRYPTO_VMAC=m
|
||||
CONFIG_CRYPTO_CRC32=m
|
||||
CONFIG_CRYPTO_BLAKE2S=m
|
||||
CONFIG_CRYPTO_MD4=m
|
||||
CONFIG_CRYPTO_MD5=y
|
||||
CONFIG_CRYPTO_MICHAEL_MIC=m
|
||||
CONFIG_CRYPTO_RMD160=m
|
||||
CONFIG_CRYPTO_SHA3=m
|
||||
|
|
|
@ -248,8 +248,7 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
|
|||
|
||||
#define EMIT6_PCREL(op1, op2, b1, b2, i, off, mask) \
|
||||
({ \
|
||||
/* Branch instruction needs 6 bytes */ \
|
||||
int rel = (addrs[(i) + (off) + 1] - (addrs[(i) + 1] - 6)) / 2;\
|
||||
int rel = (addrs[(i) + (off) + 1] - jit->prg) / 2; \
|
||||
_EMIT6((op1) | reg(b1, b2) << 16 | (rel & 0xffff), (op2) | (mask));\
|
||||
REG_SET_SEEN(b1); \
|
||||
REG_SET_SEEN(b2); \
|
||||
|
@ -761,10 +760,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
|
|||
EMIT4(0xb9080000, dst_reg, src_reg);
|
||||
break;
|
||||
case BPF_ALU | BPF_ADD | BPF_K: /* dst = (u32) dst + (u32) imm */
|
||||
if (!imm)
|
||||
break;
|
||||
/* alfi %dst,imm */
|
||||
EMIT6_IMM(0xc20b0000, dst_reg, imm);
|
||||
if (imm != 0) {
|
||||
/* alfi %dst,imm */
|
||||
EMIT6_IMM(0xc20b0000, dst_reg, imm);
|
||||
}
|
||||
EMIT_ZERO(dst_reg);
|
||||
break;
|
||||
case BPF_ALU64 | BPF_ADD | BPF_K: /* dst = dst + imm */
|
||||
|
@ -786,17 +785,22 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
|
|||
EMIT4(0xb9090000, dst_reg, src_reg);
|
||||
break;
|
||||
case BPF_ALU | BPF_SUB | BPF_K: /* dst = (u32) dst - (u32) imm */
|
||||
if (!imm)
|
||||
break;
|
||||
/* alfi %dst,-imm */
|
||||
EMIT6_IMM(0xc20b0000, dst_reg, -imm);
|
||||
if (imm != 0) {
|
||||
/* alfi %dst,-imm */
|
||||
EMIT6_IMM(0xc20b0000, dst_reg, -imm);
|
||||
}
|
||||
EMIT_ZERO(dst_reg);
|
||||
break;
|
||||
case BPF_ALU64 | BPF_SUB | BPF_K: /* dst = dst - imm */
|
||||
if (!imm)
|
||||
break;
|
||||
/* agfi %dst,-imm */
|
||||
EMIT6_IMM(0xc2080000, dst_reg, -imm);
|
||||
if (imm == -0x80000000) {
|
||||
/* algfi %dst,0x80000000 */
|
||||
EMIT6_IMM(0xc20a0000, dst_reg, 0x80000000);
|
||||
} else {
|
||||
/* agfi %dst,-imm */
|
||||
EMIT6_IMM(0xc2080000, dst_reg, -imm);
|
||||
}
|
||||
break;
|
||||
/*
|
||||
* BPF_MUL
|
||||
|
@ -811,10 +815,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
|
|||
EMIT4(0xb90c0000, dst_reg, src_reg);
|
||||
break;
|
||||
case BPF_ALU | BPF_MUL | BPF_K: /* dst = (u32) dst * (u32) imm */
|
||||
if (imm == 1)
|
||||
break;
|
||||
/* msfi %r5,imm */
|
||||
EMIT6_IMM(0xc2010000, dst_reg, imm);
|
||||
if (imm != 1) {
|
||||
/* msfi %r5,imm */
|
||||
EMIT6_IMM(0xc2010000, dst_reg, imm);
|
||||
}
|
||||
EMIT_ZERO(dst_reg);
|
||||
break;
|
||||
case BPF_ALU64 | BPF_MUL | BPF_K: /* dst = dst * imm */
|
||||
|
@ -867,6 +871,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
|
|||
if (BPF_OP(insn->code) == BPF_MOD)
|
||||
/* lhgi %dst,0 */
|
||||
EMIT4_IMM(0xa7090000, dst_reg, 0);
|
||||
else
|
||||
EMIT_ZERO(dst_reg);
|
||||
break;
|
||||
}
|
||||
/* lhi %w0,0 */
|
||||
|
@ -999,10 +1005,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
|
|||
EMIT4(0xb9820000, dst_reg, src_reg);
|
||||
break;
|
||||
case BPF_ALU | BPF_XOR | BPF_K: /* dst = (u32) dst ^ (u32) imm */
|
||||
if (!imm)
|
||||
break;
|
||||
/* xilf %dst,imm */
|
||||
EMIT6_IMM(0xc0070000, dst_reg, imm);
|
||||
if (imm != 0) {
|
||||
/* xilf %dst,imm */
|
||||
EMIT6_IMM(0xc0070000, dst_reg, imm);
|
||||
}
|
||||
EMIT_ZERO(dst_reg);
|
||||
break;
|
||||
case BPF_ALU64 | BPF_XOR | BPF_K: /* dst = dst ^ imm */
|
||||
|
@ -1033,10 +1039,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
|
|||
EMIT6_DISP_LH(0xeb000000, 0x000d, dst_reg, dst_reg, src_reg, 0);
|
||||
break;
|
||||
case BPF_ALU | BPF_LSH | BPF_K: /* dst = (u32) dst << (u32) imm */
|
||||
if (imm == 0)
|
||||
break;
|
||||
/* sll %dst,imm(%r0) */
|
||||
EMIT4_DISP(0x89000000, dst_reg, REG_0, imm);
|
||||
if (imm != 0) {
|
||||
/* sll %dst,imm(%r0) */
|
||||
EMIT4_DISP(0x89000000, dst_reg, REG_0, imm);
|
||||
}
|
||||
EMIT_ZERO(dst_reg);
|
||||
break;
|
||||
case BPF_ALU64 | BPF_LSH | BPF_K: /* dst = dst << imm */
|
||||
|
@ -1058,10 +1064,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
|
|||
EMIT6_DISP_LH(0xeb000000, 0x000c, dst_reg, dst_reg, src_reg, 0);
|
||||
break;
|
||||
case BPF_ALU | BPF_RSH | BPF_K: /* dst = (u32) dst >> (u32) imm */
|
||||
if (imm == 0)
|
||||
break;
|
||||
/* srl %dst,imm(%r0) */
|
||||
EMIT4_DISP(0x88000000, dst_reg, REG_0, imm);
|
||||
if (imm != 0) {
|
||||
/* srl %dst,imm(%r0) */
|
||||
EMIT4_DISP(0x88000000, dst_reg, REG_0, imm);
|
||||
}
|
||||
EMIT_ZERO(dst_reg);
|
||||
break;
|
||||
case BPF_ALU64 | BPF_RSH | BPF_K: /* dst = dst >> imm */
|
||||
|
@ -1083,10 +1089,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
|
|||
EMIT6_DISP_LH(0xeb000000, 0x000a, dst_reg, dst_reg, src_reg, 0);
|
||||
break;
|
||||
case BPF_ALU | BPF_ARSH | BPF_K: /* ((s32) dst >> imm */
|
||||
if (imm == 0)
|
||||
break;
|
||||
/* sra %dst,imm(%r0) */
|
||||
EMIT4_DISP(0x8a000000, dst_reg, REG_0, imm);
|
||||
if (imm != 0) {
|
||||
/* sra %dst,imm(%r0) */
|
||||
EMIT4_DISP(0x8a000000, dst_reg, REG_0, imm);
|
||||
}
|
||||
EMIT_ZERO(dst_reg);
|
||||
break;
|
||||
case BPF_ALU64 | BPF_ARSH | BPF_K: /* ((s64) dst) >>= imm */
|
||||
|
|
|
@ -159,7 +159,7 @@ SYSCALL_DEFINE3(s390_pci_mmio_write, unsigned long, mmio_addr,
|
|||
|
||||
mmap_read_lock(current->mm);
|
||||
ret = -EINVAL;
|
||||
vma = find_vma(current->mm, mmio_addr);
|
||||
vma = vma_lookup(current->mm, mmio_addr);
|
||||
if (!vma)
|
||||
goto out_unlock_mmap;
|
||||
if (!(vma->vm_flags & (VM_IO | VM_PFNMAP)))
|
||||
|
@ -298,7 +298,7 @@ SYSCALL_DEFINE3(s390_pci_mmio_read, unsigned long, mmio_addr,
|
|||
|
||||
mmap_read_lock(current->mm);
|
||||
ret = -EINVAL;
|
||||
vma = find_vma(current->mm, mmio_addr);
|
||||
vma = vma_lookup(current->mm, mmio_addr);
|
||||
if (!vma)
|
||||
goto out_unlock_mmap;
|
||||
if (!(vma->vm_flags & (VM_IO | VM_PFNMAP)))
|
||||
|
|
|
@ -80,30 +80,30 @@ $(obj)/vmlinux.bin.xz: $(obj)/vmlinux.bin FORCE
|
|||
$(obj)/vmlinux.bin.lzo: $(obj)/vmlinux.bin FORCE
|
||||
$(call if_changed,lzo)
|
||||
|
||||
$(obj)/uImage.bz2: $(obj)/vmlinux.bin.bz2
|
||||
$(obj)/uImage.bz2: $(obj)/vmlinux.bin.bz2 FORCE
|
||||
$(call if_changed,uimage,bzip2)
|
||||
|
||||
$(obj)/uImage.gz: $(obj)/vmlinux.bin.gz
|
||||
$(obj)/uImage.gz: $(obj)/vmlinux.bin.gz FORCE
|
||||
$(call if_changed,uimage,gzip)
|
||||
|
||||
$(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma
|
||||
$(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma FORCE
|
||||
$(call if_changed,uimage,lzma)
|
||||
|
||||
$(obj)/uImage.xz: $(obj)/vmlinux.bin.xz
|
||||
$(obj)/uImage.xz: $(obj)/vmlinux.bin.xz FORCE
|
||||
$(call if_changed,uimage,xz)
|
||||
|
||||
$(obj)/uImage.lzo: $(obj)/vmlinux.bin.lzo
|
||||
$(obj)/uImage.lzo: $(obj)/vmlinux.bin.lzo FORCE
|
||||
$(call if_changed,uimage,lzo)
|
||||
|
||||
$(obj)/uImage.bin: $(obj)/vmlinux.bin
|
||||
$(obj)/uImage.bin: $(obj)/vmlinux.bin FORCE
|
||||
$(call if_changed,uimage,none)
|
||||
|
||||
OBJCOPYFLAGS_vmlinux.srec := -I binary -O srec
|
||||
$(obj)/vmlinux.srec: $(obj)/compressed/vmlinux
|
||||
$(obj)/vmlinux.srec: $(obj)/compressed/vmlinux FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
OBJCOPYFLAGS_uImage.srec := -I binary -O srec
|
||||
$(obj)/uImage.srec: $(obj)/uImage
|
||||
$(obj)/uImage.srec: $(obj)/uImage FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
$(obj)/uImage: $(obj)/uImage.$(suffix-y)
|
||||
|
|
|
@ -356,7 +356,9 @@ err_nomem:
|
|||
void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
|
||||
dma_addr_t dma_addr, unsigned long attrs)
|
||||
{
|
||||
if (!sparc_dma_free_resource(cpu_addr, PAGE_ALIGN(size)))
|
||||
size = PAGE_ALIGN(size);
|
||||
|
||||
if (!sparc_dma_free_resource(cpu_addr, size))
|
||||
return;
|
||||
|
||||
dma_make_coherent(dma_addr, size);
|
||||
|
|
|
@ -39,6 +39,7 @@ struct mdesc_hdr {
|
|||
u32 node_sz; /* node block size */
|
||||
u32 name_sz; /* name block size */
|
||||
u32 data_sz; /* data block size */
|
||||
char data[];
|
||||
} __attribute__((aligned(16)));
|
||||
|
||||
struct mdesc_elem {
|
||||
|
@ -612,7 +613,7 @@ EXPORT_SYMBOL(mdesc_get_node_info);
|
|||
|
||||
static struct mdesc_elem *node_block(struct mdesc_hdr *mdesc)
|
||||
{
|
||||
return (struct mdesc_elem *) (mdesc + 1);
|
||||
return (struct mdesc_elem *) mdesc->data;
|
||||
}
|
||||
|
||||
static void *name_block(struct mdesc_hdr *mdesc)
|
||||
|
|
|
@ -19,8 +19,10 @@ void ioport_unmap(void __iomem *addr)
|
|||
EXPORT_SYMBOL(ioport_map);
|
||||
EXPORT_SYMBOL(ioport_unmap);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
EXPORT_SYMBOL(pci_iounmap);
|
||||
#endif
|
||||
|
|
|
@ -339,6 +339,11 @@ config NEED_PER_CPU_PAGE_FIRST_CHUNK
|
|||
config ARCH_HIBERNATION_POSSIBLE
|
||||
def_bool y
|
||||
|
||||
config ARCH_NR_GPIO
|
||||
int
|
||||
default 1024 if X86_64
|
||||
default 512
|
||||
|
||||
config ARCH_SUSPEND_POSSIBLE
|
||||
def_bool y
|
||||
|
||||
|
|
|
@ -4,6 +4,12 @@
|
|||
|
||||
tune = $(call cc-option,-mtune=$(1),$(2))
|
||||
|
||||
ifdef CONFIG_CC_IS_CLANG
|
||||
align := -falign-functions=0 $(call cc-option,-falign-jumps=0) $(call cc-option,-falign-loops=0)
|
||||
else
|
||||
align := -falign-functions=0 -falign-jumps=0 -falign-loops=0
|
||||
endif
|
||||
|
||||
cflags-$(CONFIG_M486SX) += -march=i486
|
||||
cflags-$(CONFIG_M486) += -march=i486
|
||||
cflags-$(CONFIG_M586) += -march=i586
|
||||
|
@ -19,11 +25,11 @@ cflags-$(CONFIG_MK6) += -march=k6
|
|||
# They make zero difference whatsosever to performance at this time.
|
||||
cflags-$(CONFIG_MK7) += -march=athlon
|
||||
cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8,-march=athlon)
|
||||
cflags-$(CONFIG_MCRUSOE) += -march=i686 -falign-functions=0 -falign-jumps=0 -falign-loops=0
|
||||
cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call tune,pentium3) -falign-functions=0 -falign-jumps=0 -falign-loops=0
|
||||
cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)
|
||||
cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call tune,pentium3) $(align)
|
||||
cflags-$(CONFIG_MWINCHIPC6) += $(call cc-option,-march=winchip-c6,-march=i586)
|
||||
cflags-$(CONFIG_MWINCHIP3D) += $(call cc-option,-march=winchip2,-march=i586)
|
||||
cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) -falign-functions=0 -falign-jumps=0 -falign-loops=0
|
||||
cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)
|
||||
cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686)
|
||||
cflags-$(CONFIG_MVIAC7) += -march=i686
|
||||
cflags-$(CONFIG_MCORE2) += -march=i686 $(call tune,core2)
|
||||
|
|
|
@ -99,7 +99,8 @@ static void hv_apic_eoi_write(u32 reg, u32 val)
|
|||
/*
|
||||
* IPI implementation on Hyper-V.
|
||||
*/
|
||||
static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector)
|
||||
static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector,
|
||||
bool exclude_self)
|
||||
{
|
||||
struct hv_send_ipi_ex **arg;
|
||||
struct hv_send_ipi_ex *ipi_arg;
|
||||
|
@ -123,7 +124,10 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector)
|
|||
|
||||
if (!cpumask_equal(mask, cpu_present_mask)) {
|
||||
ipi_arg->vp_set.format = HV_GENERIC_SET_SPARSE_4K;
|
||||
nr_bank = cpumask_to_vpset(&(ipi_arg->vp_set), mask);
|
||||
if (exclude_self)
|
||||
nr_bank = cpumask_to_vpset_noself(&(ipi_arg->vp_set), mask);
|
||||
else
|
||||
nr_bank = cpumask_to_vpset(&(ipi_arg->vp_set), mask);
|
||||
}
|
||||
if (nr_bank < 0)
|
||||
goto ipi_mask_ex_done;
|
||||
|
@ -138,15 +142,25 @@ ipi_mask_ex_done:
|
|||
return hv_result_success(status);
|
||||
}
|
||||
|
||||
static bool __send_ipi_mask(const struct cpumask *mask, int vector)
|
||||
static bool __send_ipi_mask(const struct cpumask *mask, int vector,
|
||||
bool exclude_self)
|
||||
{
|
||||
int cur_cpu, vcpu;
|
||||
int cur_cpu, vcpu, this_cpu = smp_processor_id();
|
||||
struct hv_send_ipi ipi_arg;
|
||||
u64 status;
|
||||
unsigned int weight;
|
||||
|
||||
trace_hyperv_send_ipi_mask(mask, vector);
|
||||
|
||||
if (cpumask_empty(mask))
|
||||
weight = cpumask_weight(mask);
|
||||
|
||||
/*
|
||||
* Do nothing if
|
||||
* 1. the mask is empty
|
||||
* 2. the mask only contains self when exclude_self is true
|
||||
*/
|
||||
if (weight == 0 ||
|
||||
(exclude_self && weight == 1 && cpumask_test_cpu(this_cpu, mask)))
|
||||
return true;
|
||||
|
||||
if (!hv_hypercall_pg)
|
||||
|
@ -172,6 +186,8 @@ static bool __send_ipi_mask(const struct cpumask *mask, int vector)
|
|||
ipi_arg.cpu_mask = 0;
|
||||
|
||||
for_each_cpu(cur_cpu, mask) {
|
||||
if (exclude_self && cur_cpu == this_cpu)
|
||||
continue;
|
||||
vcpu = hv_cpu_number_to_vp_number(cur_cpu);
|
||||
if (vcpu == VP_INVAL)
|
||||
return false;
|
||||
|
@ -191,7 +207,7 @@ static bool __send_ipi_mask(const struct cpumask *mask, int vector)
|
|||
return hv_result_success(status);
|
||||
|
||||
do_ex_hypercall:
|
||||
return __send_ipi_mask_ex(mask, vector);
|
||||
return __send_ipi_mask_ex(mask, vector, exclude_self);
|
||||
}
|
||||
|
||||
static bool __send_ipi_one(int cpu, int vector)
|
||||
|
@ -208,7 +224,7 @@ static bool __send_ipi_one(int cpu, int vector)
|
|||
return false;
|
||||
|
||||
if (vp >= 64)
|
||||
return __send_ipi_mask_ex(cpumask_of(cpu), vector);
|
||||
return __send_ipi_mask_ex(cpumask_of(cpu), vector, false);
|
||||
|
||||
status = hv_do_fast_hypercall16(HVCALL_SEND_IPI, vector, BIT_ULL(vp));
|
||||
return hv_result_success(status);
|
||||
|
@ -222,20 +238,13 @@ static void hv_send_ipi(int cpu, int vector)
|
|||
|
||||
static void hv_send_ipi_mask(const struct cpumask *mask, int vector)
|
||||
{
|
||||
if (!__send_ipi_mask(mask, vector))
|
||||
if (!__send_ipi_mask(mask, vector, false))
|
||||
orig_apic.send_IPI_mask(mask, vector);
|
||||
}
|
||||
|
||||
static void hv_send_ipi_mask_allbutself(const struct cpumask *mask, int vector)
|
||||
{
|
||||
unsigned int this_cpu = smp_processor_id();
|
||||
struct cpumask new_mask;
|
||||
const struct cpumask *local_mask;
|
||||
|
||||
cpumask_copy(&new_mask, mask);
|
||||
cpumask_clear_cpu(this_cpu, &new_mask);
|
||||
local_mask = &new_mask;
|
||||
if (!__send_ipi_mask(local_mask, vector))
|
||||
if (!__send_ipi_mask(mask, vector, true))
|
||||
orig_apic.send_IPI_mask_allbutself(mask, vector);
|
||||
}
|
||||
|
||||
|
@ -246,7 +255,7 @@ static void hv_send_ipi_allbutself(int vector)
|
|||
|
||||
static void hv_send_ipi_all(int vector)
|
||||
{
|
||||
if (!__send_ipi_mask(cpu_online_mask, vector))
|
||||
if (!__send_ipi_mask(cpu_online_mask, vector, false))
|
||||
orig_apic.send_IPI_all(vector);
|
||||
}
|
||||
|
||||
|
|
|
@ -1253,6 +1253,9 @@ static void __mc_scan_banks(struct mce *m, struct pt_regs *regs, struct mce *fin
|
|||
|
||||
static void kill_me_now(struct callback_head *ch)
|
||||
{
|
||||
struct task_struct *p = container_of(ch, struct task_struct, mce_kill_me);
|
||||
|
||||
p->mce_count = 0;
|
||||
force_sig(SIGBUS);
|
||||
}
|
||||
|
||||
|
@ -1262,6 +1265,7 @@ static void kill_me_maybe(struct callback_head *cb)
|
|||
int flags = MF_ACTION_REQUIRED;
|
||||
int ret;
|
||||
|
||||
p->mce_count = 0;
|
||||
pr_err("Uncorrected hardware memory error in user-access at %llx", p->mce_addr);
|
||||
|
||||
if (!p->mce_ripv)
|
||||
|
@ -1290,17 +1294,34 @@ static void kill_me_maybe(struct callback_head *cb)
|
|||
}
|
||||
}
|
||||
|
||||
static void queue_task_work(struct mce *m, int kill_current_task)
|
||||
static void queue_task_work(struct mce *m, char *msg, int kill_current_task)
|
||||
{
|
||||
current->mce_addr = m->addr;
|
||||
current->mce_kflags = m->kflags;
|
||||
current->mce_ripv = !!(m->mcgstatus & MCG_STATUS_RIPV);
|
||||
current->mce_whole_page = whole_page(m);
|
||||
int count = ++current->mce_count;
|
||||
|
||||
if (kill_current_task)
|
||||
current->mce_kill_me.func = kill_me_now;
|
||||
else
|
||||
current->mce_kill_me.func = kill_me_maybe;
|
||||
/* First call, save all the details */
|
||||
if (count == 1) {
|
||||
current->mce_addr = m->addr;
|
||||
current->mce_kflags = m->kflags;
|
||||
current->mce_ripv = !!(m->mcgstatus & MCG_STATUS_RIPV);
|
||||
current->mce_whole_page = whole_page(m);
|
||||
|
||||
if (kill_current_task)
|
||||
current->mce_kill_me.func = kill_me_now;
|
||||
else
|
||||
current->mce_kill_me.func = kill_me_maybe;
|
||||
}
|
||||
|
||||
/* Ten is likely overkill. Don't expect more than two faults before task_work() */
|
||||
if (count > 10)
|
||||
mce_panic("Too many consecutive machine checks while accessing user data", m, msg);
|
||||
|
||||
/* Second or later call, make sure page address matches the one from first call */
|
||||
if (count > 1 && (current->mce_addr >> PAGE_SHIFT) != (m->addr >> PAGE_SHIFT))
|
||||
mce_panic("Consecutive machine checks to different user pages", m, msg);
|
||||
|
||||
/* Do not call task_work_add() more than once */
|
||||
if (count > 1)
|
||||
return;
|
||||
|
||||
task_work_add(current, ¤t->mce_kill_me, TWA_RESUME);
|
||||
}
|
||||
|
@ -1438,7 +1459,7 @@ noinstr void do_machine_check(struct pt_regs *regs)
|
|||
/* If this triggers there is no way to recover. Die hard. */
|
||||
BUG_ON(!on_thread_stack() || !user_mode(regs));
|
||||
|
||||
queue_task_work(&m, kill_current_task);
|
||||
queue_task_work(&m, msg, kill_current_task);
|
||||
|
||||
} else {
|
||||
/*
|
||||
|
@ -1456,7 +1477,7 @@ noinstr void do_machine_check(struct pt_regs *regs)
|
|||
}
|
||||
|
||||
if (m.kflags & MCE_IN_KERNEL_COPYIN)
|
||||
queue_task_work(&m, kill_current_task);
|
||||
queue_task_work(&m, msg, kill_current_task);
|
||||
}
|
||||
out:
|
||||
mce_wrmsrl(MSR_IA32_MCG_STATUS, 0);
|
||||
|
|
|
@ -135,7 +135,7 @@ static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size, size_t align)
|
|||
|
||||
static void __init pcpu_fc_free(void *ptr, size_t size)
|
||||
{
|
||||
memblock_free(__pa(ptr), size);
|
||||
memblock_free_ptr(ptr, size);
|
||||
}
|
||||
|
||||
static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)
|
||||
|
|
|
@ -1432,18 +1432,18 @@ int kern_addr_valid(unsigned long addr)
|
|||
return 0;
|
||||
|
||||
p4d = p4d_offset(pgd, addr);
|
||||
if (p4d_none(*p4d))
|
||||
if (!p4d_present(*p4d))
|
||||
return 0;
|
||||
|
||||
pud = pud_offset(p4d, addr);
|
||||
if (pud_none(*pud))
|
||||
if (!pud_present(*pud))
|
||||
return 0;
|
||||
|
||||
if (pud_large(*pud))
|
||||
return pfn_valid(pud_pfn(*pud));
|
||||
|
||||
pmd = pmd_offset(pud, addr);
|
||||
if (pmd_none(*pmd))
|
||||
if (!pmd_present(*pmd))
|
||||
return 0;
|
||||
|
||||
if (pmd_large(*pmd))
|
||||
|
|
|
@ -49,8 +49,7 @@ static void __init kasan_populate_pmd(pmd_t *pmd, unsigned long addr,
|
|||
p = early_alloc(PMD_SIZE, nid, false);
|
||||
if (p && pmd_set_huge(pmd, __pa(p), PAGE_KERNEL))
|
||||
return;
|
||||
else if (p)
|
||||
memblock_free(__pa(p), PMD_SIZE);
|
||||
memblock_free_ptr(p, PMD_SIZE);
|
||||
}
|
||||
|
||||
p = early_alloc(PAGE_SIZE, nid, true);
|
||||
|
@ -86,8 +85,7 @@ static void __init kasan_populate_pud(pud_t *pud, unsigned long addr,
|
|||
p = early_alloc(PUD_SIZE, nid, false);
|
||||
if (p && pud_set_huge(pud, __pa(p), PAGE_KERNEL))
|
||||
return;
|
||||
else if (p)
|
||||
memblock_free(__pa(p), PUD_SIZE);
|
||||
memblock_free_ptr(p, PUD_SIZE);
|
||||
}
|
||||
|
||||
p = early_alloc(PAGE_SIZE, nid, true);
|
||||
|
|
|
@ -355,7 +355,7 @@ void __init numa_reset_distance(void)
|
|||
|
||||
/* numa_distance could be 1LU marking allocation failure, test cnt */
|
||||
if (numa_distance_cnt)
|
||||
memblock_free(__pa(numa_distance), size);
|
||||
memblock_free_ptr(numa_distance, size);
|
||||
numa_distance_cnt = 0;
|
||||
numa_distance = NULL; /* enable table creation */
|
||||
}
|
||||
|
|
|
@ -517,8 +517,7 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)
|
|||
}
|
||||
|
||||
/* free the copied physical distance table */
|
||||
if (phys_dist)
|
||||
memblock_free(__pa(phys_dist), phys_size);
|
||||
memblock_free_ptr(phys_dist, phys_size);
|
||||
return;
|
||||
|
||||
no_emu:
|
||||
|
|
|
@ -583,7 +583,12 @@ int memtype_reserve(u64 start, u64 end, enum page_cache_mode req_type,
|
|||
int err = 0;
|
||||
|
||||
start = sanitize_phys(start);
|
||||
end = sanitize_phys(end);
|
||||
|
||||
/*
|
||||
* The end address passed into this function is exclusive, but
|
||||
* sanitize_phys() expects an inclusive address.
|
||||
*/
|
||||
end = sanitize_phys(end - 1) + 1;
|
||||
if (start >= end) {
|
||||
WARN(1, "%s failed: [mem %#010Lx-%#010Lx], req %s\n", __func__,
|
||||
start, end - 1, cattr_name(req_type));
|
||||
|
|
|
@ -1214,6 +1214,11 @@ static void __init xen_dom0_set_legacy_features(void)
|
|||
x86_platform.legacy.rtc = 1;
|
||||
}
|
||||
|
||||
static void __init xen_domu_set_legacy_features(void)
|
||||
{
|
||||
x86_platform.legacy.rtc = 0;
|
||||
}
|
||||
|
||||
/* First C function to be called on Xen boot */
|
||||
asmlinkage __visible void __init xen_start_kernel(void)
|
||||
{
|
||||
|
@ -1359,6 +1364,8 @@ asmlinkage __visible void __init xen_start_kernel(void)
|
|||
add_preferred_console("xenboot", 0, NULL);
|
||||
if (pci_xen)
|
||||
x86_init.pci.arch_init = pci_xen_init;
|
||||
x86_platform.set_legacy_features =
|
||||
xen_domu_set_legacy_features;
|
||||
} else {
|
||||
const struct dom0_vga_console_info *info =
|
||||
(void *)((char *)xen_start_info +
|
||||
|
|
|
@ -1518,14 +1518,17 @@ static inline void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn,
|
|||
if (pinned) {
|
||||
struct page *page = pfn_to_page(pfn);
|
||||
|
||||
if (static_branch_likely(&xen_struct_pages_ready))
|
||||
pinned = false;
|
||||
if (static_branch_likely(&xen_struct_pages_ready)) {
|
||||
pinned = PagePinned(page);
|
||||
SetPagePinned(page);
|
||||
}
|
||||
|
||||
xen_mc_batch();
|
||||
|
||||
__set_pfn_prot(pfn, PAGE_KERNEL_RO);
|
||||
|
||||
if (level == PT_PTE && USE_SPLIT_PTE_PTLOCKS)
|
||||
if (level == PT_PTE && USE_SPLIT_PTE_PTLOCKS && !pinned)
|
||||
__pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn);
|
||||
|
||||
xen_mc_issue(PARAVIRT_LAZY_MMU);
|
||||
|
|
|
@ -1182,10 +1182,6 @@ int blkcg_init_queue(struct request_queue *q)
|
|||
if (preloaded)
|
||||
radix_tree_preload_end();
|
||||
|
||||
ret = blk_iolatency_init(q);
|
||||
if (ret)
|
||||
goto err_destroy_all;
|
||||
|
||||
ret = blk_ioprio_init(q);
|
||||
if (ret)
|
||||
goto err_destroy_all;
|
||||
|
@ -1194,6 +1190,12 @@ int blkcg_init_queue(struct request_queue *q)
|
|||
if (ret)
|
||||
goto err_destroy_all;
|
||||
|
||||
ret = blk_iolatency_init(q);
|
||||
if (ret) {
|
||||
blk_throtl_exit(q);
|
||||
goto err_destroy_all;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_destroy_all:
|
||||
|
@ -1364,10 +1366,14 @@ enomem:
|
|||
/* alloc failed, nothing's initialized yet, free everything */
|
||||
spin_lock_irq(&q->queue_lock);
|
||||
list_for_each_entry(blkg, &q->blkg_list, q_node) {
|
||||
struct blkcg *blkcg = blkg->blkcg;
|
||||
|
||||
spin_lock(&blkcg->lock);
|
||||
if (blkg->pd[pol->plid]) {
|
||||
pol->pd_free_fn(blkg->pd[pol->plid]);
|
||||
blkg->pd[pol->plid] = NULL;
|
||||
}
|
||||
spin_unlock(&blkcg->lock);
|
||||
}
|
||||
spin_unlock_irq(&q->queue_lock);
|
||||
ret = -ENOMEM;
|
||||
|
@ -1399,12 +1405,16 @@ void blkcg_deactivate_policy(struct request_queue *q,
|
|||
__clear_bit(pol->plid, q->blkcg_pols);
|
||||
|
||||
list_for_each_entry(blkg, &q->blkg_list, q_node) {
|
||||
struct blkcg *blkcg = blkg->blkcg;
|
||||
|
||||
spin_lock(&blkcg->lock);
|
||||
if (blkg->pd[pol->plid]) {
|
||||
if (pol->pd_offline_fn)
|
||||
pol->pd_offline_fn(blkg->pd[pol->plid]);
|
||||
pol->pd_free_fn(blkg->pd[pol->plid]);
|
||||
blkg->pd[pol->plid] = NULL;
|
||||
}
|
||||
spin_unlock(&blkcg->lock);
|
||||
}
|
||||
|
||||
spin_unlock_irq(&q->queue_lock);
|
||||
|
|
|
@ -426,8 +426,15 @@ EXPORT_SYMBOL(blk_integrity_register);
|
|||
*/
|
||||
void blk_integrity_unregister(struct gendisk *disk)
|
||||
{
|
||||
struct blk_integrity *bi = &disk->queue->integrity;
|
||||
|
||||
if (!bi->profile)
|
||||
return;
|
||||
|
||||
/* ensure all bios are off the integrity workqueue */
|
||||
blk_flush_integrity();
|
||||
blk_queue_flag_clear(QUEUE_FLAG_STABLE_WRITES, disk->queue);
|
||||
memset(&disk->queue->integrity, 0, sizeof(struct blk_integrity));
|
||||
memset(bi, 0, sizeof(*bi));
|
||||
}
|
||||
EXPORT_SYMBOL(blk_integrity_unregister);
|
||||
|
||||
|
|
|
@ -208,7 +208,7 @@ static struct request *blk_mq_find_and_get_req(struct blk_mq_tags *tags,
|
|||
|
||||
spin_lock_irqsave(&tags->lock, flags);
|
||||
rq = tags->rqs[bitnr];
|
||||
if (!rq || !refcount_inc_not_zero(&rq->ref))
|
||||
if (!rq || rq->tag != bitnr || !refcount_inc_not_zero(&rq->ref))
|
||||
rq = NULL;
|
||||
spin_unlock_irqrestore(&tags->lock, flags);
|
||||
return rq;
|
||||
|
|
|
@ -264,7 +264,7 @@ void __init numa_free_distance(void)
|
|||
size = numa_distance_cnt * numa_distance_cnt *
|
||||
sizeof(numa_distance[0]);
|
||||
|
||||
memblock_free(__pa(numa_distance), size);
|
||||
memblock_free_ptr(numa_distance, size);
|
||||
numa_distance_cnt = 0;
|
||||
numa_distance = NULL;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/export.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <linux/mc146818rtc.h>
|
||||
|
||||
|
@ -165,6 +166,9 @@ void generate_pm_trace(const void *tracedata, unsigned int user)
|
|||
const char *file = *(const char **)(tracedata + 2);
|
||||
unsigned int user_hash_value, file_hash_value;
|
||||
|
||||
if (!x86_platform.legacy.rtc)
|
||||
return;
|
||||
|
||||
user_hash_value = user % USERHASH;
|
||||
file_hash_value = hash_string(lineno, file, FILEHASH);
|
||||
set_magic_time(user_hash_value, file_hash_value, dev_hash_value);
|
||||
|
@ -267,6 +271,9 @@ static struct notifier_block pm_trace_nb = {
|
|||
|
||||
static int __init early_resume_init(void)
|
||||
{
|
||||
if (!x86_platform.legacy.rtc)
|
||||
return 0;
|
||||
|
||||
hash_value_early_read = read_magic_time();
|
||||
register_pm_notifier(&pm_trace_nb);
|
||||
return 0;
|
||||
|
@ -277,6 +284,9 @@ static int __init late_resume_init(void)
|
|||
unsigned int val = hash_value_early_read;
|
||||
unsigned int user, file, dev;
|
||||
|
||||
if (!x86_platform.legacy.rtc)
|
||||
return 0;
|
||||
|
||||
user = val % USERHASH;
|
||||
val = val / USERHASH;
|
||||
file = val % FILEHASH;
|
||||
|
|
|
@ -74,8 +74,8 @@ unsigned int gov_attr_set_put(struct gov_attr_set *attr_set, struct list_head *l
|
|||
if (count)
|
||||
return count;
|
||||
|
||||
kobject_put(&attr_set->kobj);
|
||||
mutex_destroy(&attr_set->update_lock);
|
||||
kobject_put(&attr_set->kobj);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gov_attr_set_put);
|
||||
|
|
|
@ -3205,11 +3205,15 @@ static int __init intel_pstate_init(void)
|
|||
if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
|
||||
return -ENODEV;
|
||||
|
||||
if (no_load)
|
||||
return -ENODEV;
|
||||
|
||||
id = x86_match_cpu(hwp_support_ids);
|
||||
if (id) {
|
||||
bool hwp_forced = intel_pstate_hwp_is_enabled();
|
||||
|
||||
if (hwp_forced)
|
||||
pr_info("HWP enabled by BIOS\n");
|
||||
else if (no_load)
|
||||
return -ENODEV;
|
||||
|
||||
copy_cpu_funcs(&core_funcs);
|
||||
/*
|
||||
* Avoid enabling HWP for processors without EPP support,
|
||||
|
@ -3219,8 +3223,7 @@ static int __init intel_pstate_init(void)
|
|||
* If HWP is enabled already, though, there is no choice but to
|
||||
* deal with it.
|
||||
*/
|
||||
if ((!no_hwp && boot_cpu_has(X86_FEATURE_HWP_EPP)) ||
|
||||
intel_pstate_hwp_is_enabled()) {
|
||||
if ((!no_hwp && boot_cpu_has(X86_FEATURE_HWP_EPP)) || hwp_forced) {
|
||||
hwp_active++;
|
||||
hwp_mode_bdw = id->driver_data;
|
||||
intel_pstate.attr = hwp_cpufreq_attrs;
|
||||
|
@ -3235,7 +3238,11 @@ static int __init intel_pstate_init(void)
|
|||
|
||||
goto hwp_cpu_matched;
|
||||
}
|
||||
pr_info("HWP not enabled\n");
|
||||
} else {
|
||||
if (no_load)
|
||||
return -ENODEV;
|
||||
|
||||
id = x86_match_cpu(intel_pstate_cpu_ids);
|
||||
if (!id) {
|
||||
pr_info("CPU model not supported\n");
|
||||
|
@ -3314,10 +3321,9 @@ static int __init intel_pstate_setup(char *str)
|
|||
else if (!strcmp(str, "passive"))
|
||||
default_driver = &intel_cpufreq;
|
||||
|
||||
if (!strcmp(str, "no_hwp")) {
|
||||
pr_info("HWP disabled\n");
|
||||
if (!strcmp(str, "no_hwp"))
|
||||
no_hwp = 1;
|
||||
}
|
||||
|
||||
if (!strcmp(str, "force"))
|
||||
force_load = 1;
|
||||
if (!strcmp(str, "hwp_only"))
|
||||
|
|
|
@ -451,7 +451,6 @@ static int ve_spc_cpufreq_init(struct cpufreq_policy *policy)
|
|||
static int ve_spc_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct device *cpu_dev;
|
||||
int cur_cluster = cpu_to_cluster(policy->cpu);
|
||||
|
||||
cpu_dev = get_cpu_device(policy->cpu);
|
||||
if (!cpu_dev) {
|
||||
|
|
|
@ -758,7 +758,7 @@ enum amd_hw_ip_block_type {
|
|||
MAX_HWIP
|
||||
};
|
||||
|
||||
#define HWIP_MAX_INSTANCE 8
|
||||
#define HWIP_MAX_INSTANCE 10
|
||||
|
||||
struct amd_powerplay {
|
||||
void *pp_handle;
|
||||
|
|
|
@ -192,6 +192,16 @@ void amdgpu_amdkfd_suspend(struct amdgpu_device *adev, bool run_pm)
|
|||
kgd2kfd_suspend(adev->kfd.dev, run_pm);
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_resume_iommu(struct amdgpu_device *adev)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
if (adev->kfd.dev)
|
||||
r = kgd2kfd_resume_iommu(adev->kfd.dev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_resume(struct amdgpu_device *adev, bool run_pm)
|
||||
{
|
||||
int r = 0;
|
||||
|
|
|
@ -137,6 +137,7 @@ int amdgpu_amdkfd_init(void);
|
|||
void amdgpu_amdkfd_fini(void);
|
||||
|
||||
void amdgpu_amdkfd_suspend(struct amdgpu_device *adev, bool run_pm);
|
||||
int amdgpu_amdkfd_resume_iommu(struct amdgpu_device *adev);
|
||||
int amdgpu_amdkfd_resume(struct amdgpu_device *adev, bool run_pm);
|
||||
void amdgpu_amdkfd_interrupt(struct amdgpu_device *adev,
|
||||
const void *ih_ring_entry);
|
||||
|
@ -327,6 +328,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
|||
const struct kgd2kfd_shared_resources *gpu_resources);
|
||||
void kgd2kfd_device_exit(struct kfd_dev *kfd);
|
||||
void kgd2kfd_suspend(struct kfd_dev *kfd, bool run_pm);
|
||||
int kgd2kfd_resume_iommu(struct kfd_dev *kfd);
|
||||
int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm);
|
||||
int kgd2kfd_pre_reset(struct kfd_dev *kfd);
|
||||
int kgd2kfd_post_reset(struct kfd_dev *kfd);
|
||||
|
@ -365,6 +367,11 @@ static inline void kgd2kfd_suspend(struct kfd_dev *kfd, bool run_pm)
|
|||
{
|
||||
}
|
||||
|
||||
static int __maybe_unused kgd2kfd_resume_iommu(struct kfd_dev *kfd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -1544,20 +1544,18 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
|
|||
struct dentry *ent;
|
||||
int r, i;
|
||||
|
||||
|
||||
|
||||
ent = debugfs_create_file("amdgpu_preempt_ib", 0600, root, adev,
|
||||
&fops_ib_preempt);
|
||||
if (!ent) {
|
||||
if (IS_ERR(ent)) {
|
||||
DRM_ERROR("unable to create amdgpu_preempt_ib debugsfs file\n");
|
||||
return -EIO;
|
||||
return PTR_ERR(ent);
|
||||
}
|
||||
|
||||
ent = debugfs_create_file("amdgpu_force_sclk", 0200, root, adev,
|
||||
&fops_sclk_set);
|
||||
if (!ent) {
|
||||
if (IS_ERR(ent)) {
|
||||
DRM_ERROR("unable to create amdgpu_set_sclk debugsfs file\n");
|
||||
return -EIO;
|
||||
return PTR_ERR(ent);
|
||||
}
|
||||
|
||||
/* Register debugfs entries for amdgpu_ttm */
|
||||
|
|
|
@ -2394,6 +2394,10 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
|
|||
if (r)
|
||||
goto init_failed;
|
||||
|
||||
r = amdgpu_amdkfd_resume_iommu(adev);
|
||||
if (r)
|
||||
goto init_failed;
|
||||
|
||||
r = amdgpu_device_ip_hw_init_phase1(adev);
|
||||
if (r)
|
||||
goto init_failed;
|
||||
|
@ -3148,6 +3152,10 @@ static int amdgpu_device_ip_resume(struct amdgpu_device *adev)
|
|||
{
|
||||
int r;
|
||||
|
||||
r = amdgpu_amdkfd_resume_iommu(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_device_ip_resume_phase1(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
@ -4601,6 +4609,10 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
|
|||
dev_warn(tmp_adev->dev, "asic atom init failed!");
|
||||
} else {
|
||||
dev_info(tmp_adev->dev, "GPU reset succeeded, trying to resume\n");
|
||||
r = amdgpu_amdkfd_resume_iommu(tmp_adev);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
r = amdgpu_device_ip_resume_phase1(tmp_adev);
|
||||
if (r)
|
||||
goto out;
|
||||
|
|
|
@ -598,7 +598,7 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev)
|
|||
break;
|
||||
default:
|
||||
adev->gmc.tmz_enabled = false;
|
||||
dev_warn(adev->dev,
|
||||
dev_info(adev->dev,
|
||||
"Trusted Memory Zone (TMZ) feature not supported\n");
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -757,7 +757,7 @@ Out:
|
|||
return res;
|
||||
}
|
||||
|
||||
inline uint32_t amdgpu_ras_eeprom_max_record_count(void)
|
||||
uint32_t amdgpu_ras_eeprom_max_record_count(void)
|
||||
{
|
||||
return RAS_MAX_RECORD_COUNT;
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ int amdgpu_ras_eeprom_read(struct amdgpu_ras_eeprom_control *control,
|
|||
int amdgpu_ras_eeprom_append(struct amdgpu_ras_eeprom_control *control,
|
||||
struct eeprom_table_record *records, const u32 num);
|
||||
|
||||
inline uint32_t amdgpu_ras_eeprom_max_record_count(void);
|
||||
uint32_t amdgpu_ras_eeprom_max_record_count(void);
|
||||
|
||||
void amdgpu_ras_debugfs_set_ret_size(struct amdgpu_ras_eeprom_control *control);
|
||||
|
||||
|
|
|
@ -428,8 +428,8 @@ int amdgpu_debugfs_ring_init(struct amdgpu_device *adev,
|
|||
ent = debugfs_create_file(name,
|
||||
S_IFREG | S_IRUGO, root,
|
||||
ring, &amdgpu_debugfs_ring_fops);
|
||||
if (!ent)
|
||||
return -ENOMEM;
|
||||
if (IS_ERR(ent))
|
||||
return PTR_ERR(ent);
|
||||
|
||||
i_size_write(ent->d_inode, ring->ring_size + 12);
|
||||
ring->ent = ent;
|
||||
|
|
|
@ -515,6 +515,15 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (bo->type == ttm_bo_type_device &&
|
||||
new_mem->mem_type == TTM_PL_VRAM &&
|
||||
old_mem->mem_type != TTM_PL_VRAM) {
|
||||
/* amdgpu_bo_fault_reserve_notify will re-set this if the CPU
|
||||
* accesses the BO after it's moved.
|
||||
*/
|
||||
abo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
|
||||
}
|
||||
|
||||
if (adev->mman.buffer_funcs_enabled) {
|
||||
if (((old_mem->mem_type == TTM_PL_SYSTEM &&
|
||||
new_mem->mem_type == TTM_PL_VRAM) ||
|
||||
|
@ -545,15 +554,6 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
|
|||
return r;
|
||||
}
|
||||
|
||||
if (bo->type == ttm_bo_type_device &&
|
||||
new_mem->mem_type == TTM_PL_VRAM &&
|
||||
old_mem->mem_type != TTM_PL_VRAM) {
|
||||
/* amdgpu_bo_fault_reserve_notify will re-set this if the CPU
|
||||
* accesses the BO after it's moved.
|
||||
*/
|
||||
abo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
|
||||
}
|
||||
|
||||
out:
|
||||
/* update statistics */
|
||||
atomic64_add(bo->base.size, &adev->num_bytes_moved);
|
||||
|
|
|
@ -468,6 +468,7 @@ static const struct kfd_device_info navi10_device_info = {
|
|||
.needs_iommu_device = false,
|
||||
.supports_cwsr = true,
|
||||
.needs_pci_atomics = true,
|
||||
.no_atomic_fw_version = 145,
|
||||
.num_sdma_engines = 2,
|
||||
.num_xgmi_sdma_engines = 0,
|
||||
.num_sdma_queues_per_engine = 8,
|
||||
|
@ -487,6 +488,7 @@ static const struct kfd_device_info navi12_device_info = {
|
|||
.needs_iommu_device = false,
|
||||
.supports_cwsr = true,
|
||||
.needs_pci_atomics = true,
|
||||
.no_atomic_fw_version = 145,
|
||||
.num_sdma_engines = 2,
|
||||
.num_xgmi_sdma_engines = 0,
|
||||
.num_sdma_queues_per_engine = 8,
|
||||
|
@ -506,6 +508,7 @@ static const struct kfd_device_info navi14_device_info = {
|
|||
.needs_iommu_device = false,
|
||||
.supports_cwsr = true,
|
||||
.needs_pci_atomics = true,
|
||||
.no_atomic_fw_version = 145,
|
||||
.num_sdma_engines = 2,
|
||||
.num_xgmi_sdma_engines = 0,
|
||||
.num_sdma_queues_per_engine = 8,
|
||||
|
@ -525,6 +528,7 @@ static const struct kfd_device_info sienna_cichlid_device_info = {
|
|||
.needs_iommu_device = false,
|
||||
.supports_cwsr = true,
|
||||
.needs_pci_atomics = true,
|
||||
.no_atomic_fw_version = 92,
|
||||
.num_sdma_engines = 4,
|
||||
.num_xgmi_sdma_engines = 0,
|
||||
.num_sdma_queues_per_engine = 8,
|
||||
|
@ -544,6 +548,7 @@ static const struct kfd_device_info navy_flounder_device_info = {
|
|||
.needs_iommu_device = false,
|
||||
.supports_cwsr = true,
|
||||
.needs_pci_atomics = true,
|
||||
.no_atomic_fw_version = 92,
|
||||
.num_sdma_engines = 2,
|
||||
.num_xgmi_sdma_engines = 0,
|
||||
.num_sdma_queues_per_engine = 8,
|
||||
|
@ -562,7 +567,8 @@ static const struct kfd_device_info vangogh_device_info = {
|
|||
.mqd_size_aligned = MQD_SIZE_ALIGNED,
|
||||
.needs_iommu_device = false,
|
||||
.supports_cwsr = true,
|
||||
.needs_pci_atomics = false,
|
||||
.needs_pci_atomics = true,
|
||||
.no_atomic_fw_version = 92,
|
||||
.num_sdma_engines = 1,
|
||||
.num_xgmi_sdma_engines = 0,
|
||||
.num_sdma_queues_per_engine = 2,
|
||||
|
@ -582,6 +588,7 @@ static const struct kfd_device_info dimgrey_cavefish_device_info = {
|
|||
.needs_iommu_device = false,
|
||||
.supports_cwsr = true,
|
||||
.needs_pci_atomics = true,
|
||||
.no_atomic_fw_version = 92,
|
||||
.num_sdma_engines = 2,
|
||||
.num_xgmi_sdma_engines = 0,
|
||||
.num_sdma_queues_per_engine = 8,
|
||||
|
@ -601,6 +608,7 @@ static const struct kfd_device_info beige_goby_device_info = {
|
|||
.needs_iommu_device = false,
|
||||
.supports_cwsr = true,
|
||||
.needs_pci_atomics = true,
|
||||
.no_atomic_fw_version = 92,
|
||||
.num_sdma_engines = 1,
|
||||
.num_xgmi_sdma_engines = 0,
|
||||
.num_sdma_queues_per_engine = 8,
|
||||
|
@ -619,7 +627,8 @@ static const struct kfd_device_info yellow_carp_device_info = {
|
|||
.mqd_size_aligned = MQD_SIZE_ALIGNED,
|
||||
.needs_iommu_device = false,
|
||||
.supports_cwsr = true,
|
||||
.needs_pci_atomics = false,
|
||||
.needs_pci_atomics = true,
|
||||
.no_atomic_fw_version = 92,
|
||||
.num_sdma_engines = 1,
|
||||
.num_xgmi_sdma_engines = 0,
|
||||
.num_sdma_queues_per_engine = 2,
|
||||
|
@ -708,20 +717,6 @@ struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd,
|
|||
if (!kfd)
|
||||
return NULL;
|
||||
|
||||
/* Allow BIF to recode atomics to PCIe 3.0 AtomicOps.
|
||||
* 32 and 64-bit requests are possible and must be
|
||||
* supported.
|
||||
*/
|
||||
kfd->pci_atomic_requested = amdgpu_amdkfd_have_atomics_support(kgd);
|
||||
if (device_info->needs_pci_atomics &&
|
||||
!kfd->pci_atomic_requested) {
|
||||
dev_info(kfd_device,
|
||||
"skipped device %x:%x, PCI rejects atomics\n",
|
||||
pdev->vendor, pdev->device);
|
||||
kfree(kfd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kfd->kgd = kgd;
|
||||
kfd->device_info = device_info;
|
||||
kfd->pdev = pdev;
|
||||
|
@ -821,6 +816,23 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
|||
kfd->vm_info.vmid_num_kfd = kfd->vm_info.last_vmid_kfd
|
||||
- kfd->vm_info.first_vmid_kfd + 1;
|
||||
|
||||
/* Allow BIF to recode atomics to PCIe 3.0 AtomicOps.
|
||||
* 32 and 64-bit requests are possible and must be
|
||||
* supported.
|
||||
*/
|
||||
kfd->pci_atomic_requested = amdgpu_amdkfd_have_atomics_support(kfd->kgd);
|
||||
if (!kfd->pci_atomic_requested &&
|
||||
kfd->device_info->needs_pci_atomics &&
|
||||
(!kfd->device_info->no_atomic_fw_version ||
|
||||
kfd->mec_fw_version < kfd->device_info->no_atomic_fw_version)) {
|
||||
dev_info(kfd_device,
|
||||
"skipped device %x:%x, PCI rejects atomics %d<%d\n",
|
||||
kfd->pdev->vendor, kfd->pdev->device,
|
||||
kfd->mec_fw_version,
|
||||
kfd->device_info->no_atomic_fw_version);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Verify module parameters regarding mapped process number*/
|
||||
if ((hws_max_conc_proc < 0)
|
||||
|| (hws_max_conc_proc > kfd->vm_info.vmid_num_kfd)) {
|
||||
|
@ -1057,17 +1069,21 @@ int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int kfd_resume(struct kfd_dev *kfd)
|
||||
int kgd2kfd_resume_iommu(struct kfd_dev *kfd)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
err = kfd_iommu_resume(kfd);
|
||||
if (err) {
|
||||
if (err)
|
||||
dev_err(kfd_device,
|
||||
"Failed to resume IOMMU for device %x:%x\n",
|
||||
kfd->pdev->vendor, kfd->pdev->device);
|
||||
return err;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int kfd_resume(struct kfd_dev *kfd)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
err = kfd->dqm->ops.start(kfd->dqm);
|
||||
if (err) {
|
||||
|
|
|
@ -207,6 +207,7 @@ struct kfd_device_info {
|
|||
bool supports_cwsr;
|
||||
bool needs_iommu_device;
|
||||
bool needs_pci_atomics;
|
||||
uint32_t no_atomic_fw_version;
|
||||
unsigned int num_sdma_engines;
|
||||
unsigned int num_xgmi_sdma_engines;
|
||||
unsigned int num_sdma_queues_per_engine;
|
||||
|
|
|
@ -998,6 +998,8 @@ static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_
|
|||
uint32_t agp_base, agp_bot, agp_top;
|
||||
PHYSICAL_ADDRESS_LOC page_table_start, page_table_end, page_table_base;
|
||||
|
||||
memset(pa_config, 0, sizeof(*pa_config));
|
||||
|
||||
logical_addr_low = min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18;
|
||||
pt_base = amdgpu_gmc_pd_addr(adev->gart.bo);
|
||||
|
||||
|
@ -6024,21 +6026,23 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable)
|
|||
return 0;
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
work = kzalloc(sizeof(*work), GFP_ATOMIC);
|
||||
if (!work)
|
||||
return -ENOMEM;
|
||||
if (dm->vblank_control_workqueue) {
|
||||
work = kzalloc(sizeof(*work), GFP_ATOMIC);
|
||||
if (!work)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_WORK(&work->work, vblank_control_worker);
|
||||
work->dm = dm;
|
||||
work->acrtc = acrtc;
|
||||
work->enable = enable;
|
||||
INIT_WORK(&work->work, vblank_control_worker);
|
||||
work->dm = dm;
|
||||
work->acrtc = acrtc;
|
||||
work->enable = enable;
|
||||
|
||||
if (acrtc_state->stream) {
|
||||
dc_stream_retain(acrtc_state->stream);
|
||||
work->stream = acrtc_state->stream;
|
||||
if (acrtc_state->stream) {
|
||||
dc_stream_retain(acrtc_state->stream);
|
||||
work->stream = acrtc_state->stream;
|
||||
}
|
||||
|
||||
queue_work(dm->vblank_control_workqueue, &work->work);
|
||||
}
|
||||
|
||||
queue_work(dm->vblank_control_workqueue, &work->work);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
@ -6792,14 +6796,15 @@ const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs = {
|
|||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
|
||||
struct dc_state *dc_state)
|
||||
struct dc_state *dc_state,
|
||||
struct dsc_mst_fairness_vars *vars)
|
||||
{
|
||||
struct dc_stream_state *stream = NULL;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_state *new_con_state;
|
||||
struct amdgpu_dm_connector *aconnector;
|
||||
struct dm_connector_state *dm_conn_state;
|
||||
int i, j, clock, bpp;
|
||||
int i, j, clock;
|
||||
int vcpi, pbn_div, pbn = 0;
|
||||
|
||||
for_each_new_connector_in_state(state, connector, new_con_state, i) {
|
||||
|
@ -6838,9 +6843,15 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
|
|||
}
|
||||
|
||||
pbn_div = dm_mst_get_pbn_divider(stream->link);
|
||||
bpp = stream->timing.dsc_cfg.bits_per_pixel;
|
||||
clock = stream->timing.pix_clk_100hz / 10;
|
||||
pbn = drm_dp_calc_pbn_mode(clock, bpp, true);
|
||||
/* pbn is calculated by compute_mst_dsc_configs_for_state*/
|
||||
for (j = 0; j < dc_state->stream_count; j++) {
|
||||
if (vars[j].aconnector == aconnector) {
|
||||
pbn = vars[j].pbn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vcpi = drm_dp_mst_atomic_enable_dsc(state,
|
||||
aconnector->port,
|
||||
pbn, pbn_div,
|
||||
|
@ -7519,6 +7530,32 @@ static void amdgpu_dm_connector_add_common_modes(struct drm_encoder *encoder,
|
|||
}
|
||||
}
|
||||
|
||||
static void amdgpu_set_panel_orientation(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_encoder *encoder;
|
||||
struct amdgpu_encoder *amdgpu_encoder;
|
||||
const struct drm_display_mode *native_mode;
|
||||
|
||||
if (connector->connector_type != DRM_MODE_CONNECTOR_eDP &&
|
||||
connector->connector_type != DRM_MODE_CONNECTOR_LVDS)
|
||||
return;
|
||||
|
||||
encoder = amdgpu_dm_connector_to_encoder(connector);
|
||||
if (!encoder)
|
||||
return;
|
||||
|
||||
amdgpu_encoder = to_amdgpu_encoder(encoder);
|
||||
|
||||
native_mode = &amdgpu_encoder->native_mode;
|
||||
if (native_mode->hdisplay == 0 || native_mode->vdisplay == 0)
|
||||
return;
|
||||
|
||||
drm_connector_set_panel_orientation_with_quirk(connector,
|
||||
DRM_MODE_PANEL_ORIENTATION_UNKNOWN,
|
||||
native_mode->hdisplay,
|
||||
native_mode->vdisplay);
|
||||
}
|
||||
|
||||
static void amdgpu_dm_connector_ddc_get_modes(struct drm_connector *connector,
|
||||
struct edid *edid)
|
||||
{
|
||||
|
@ -7547,6 +7584,8 @@ static void amdgpu_dm_connector_ddc_get_modes(struct drm_connector *connector,
|
|||
* restored here.
|
||||
*/
|
||||
amdgpu_dm_update_freesync_caps(connector, edid);
|
||||
|
||||
amdgpu_set_panel_orientation(connector);
|
||||
} else {
|
||||
amdgpu_dm_connector->num_modes = 0;
|
||||
}
|
||||
|
@ -8058,8 +8097,26 @@ static bool is_content_protection_different(struct drm_connector_state *state,
|
|||
state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED)
|
||||
state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
|
||||
|
||||
/* Check if something is connected/enabled, otherwise we start hdcp but nothing is connected/enabled
|
||||
* hot-plug, headless s3, dpms
|
||||
/* Stream removed and re-enabled
|
||||
*
|
||||
* Can sometimes overlap with the HPD case,
|
||||
* thus set update_hdcp to false to avoid
|
||||
* setting HDCP multiple times.
|
||||
*
|
||||
* Handles: DESIRED -> DESIRED (Special case)
|
||||
*/
|
||||
if (!(old_state->crtc && old_state->crtc->enabled) &&
|
||||
state->crtc && state->crtc->enabled &&
|
||||
connector->state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
|
||||
dm_con_state->update_hdcp = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Hot-plug, headless s3, dpms
|
||||
*
|
||||
* Only start HDCP if the display is connected/enabled.
|
||||
* update_hdcp flag will be set to false until the next
|
||||
* HPD comes in.
|
||||
*
|
||||
* Handles: DESIRED -> DESIRED (Special case)
|
||||
*/
|
||||
|
@ -8648,7 +8705,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
|||
* If PSR or idle optimizations are enabled then flush out
|
||||
* any pending work before hardware programming.
|
||||
*/
|
||||
flush_workqueue(dm->vblank_control_workqueue);
|
||||
if (dm->vblank_control_workqueue)
|
||||
flush_workqueue(dm->vblank_control_workqueue);
|
||||
#endif
|
||||
|
||||
bundle->stream_update.stream = acrtc_state->stream;
|
||||
|
@ -8983,7 +9041,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
/* if there mode set or reset, disable eDP PSR */
|
||||
if (mode_set_reset_required) {
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
flush_workqueue(dm->vblank_control_workqueue);
|
||||
if (dm->vblank_control_workqueue)
|
||||
flush_workqueue(dm->vblank_control_workqueue);
|
||||
#endif
|
||||
amdgpu_dm_psr_disable_all(dm);
|
||||
}
|
||||
|
@ -10243,6 +10302,9 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
int ret, i;
|
||||
bool lock_and_validation_needed = false;
|
||||
struct dm_crtc_state *dm_old_crtc_state;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
struct dsc_mst_fairness_vars vars[MAX_PIPES];
|
||||
#endif
|
||||
|
||||
trace_amdgpu_dm_atomic_check_begin(state);
|
||||
|
||||
|
@ -10473,10 +10535,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
goto fail;
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
if (!compute_mst_dsc_configs_for_state(state, dm_state->context))
|
||||
if (!compute_mst_dsc_configs_for_state(state, dm_state->context, vars))
|
||||
goto fail;
|
||||
|
||||
ret = dm_update_mst_vcpi_slots_for_dsc(state, dm_state->context);
|
||||
ret = dm_update_mst_vcpi_slots_for_dsc(state, dm_state->context, vars);
|
||||
if (ret)
|
||||
goto fail;
|
||||
#endif
|
||||
|
@ -10492,7 +10554,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
goto fail;
|
||||
status = dc_validate_global_state(dc, dm_state->context, false);
|
||||
if (status != DC_OK) {
|
||||
DC_LOG_WARNING("DC global validation failure: %s (%d)",
|
||||
drm_dbg_atomic(dev,
|
||||
"DC global validation failure: %s (%d)",
|
||||
dc_status_to_str(status), status);
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
|
|
|
@ -518,12 +518,7 @@ struct dsc_mst_fairness_params {
|
|||
uint32_t num_slices_h;
|
||||
uint32_t num_slices_v;
|
||||
uint32_t bpp_overwrite;
|
||||
};
|
||||
|
||||
struct dsc_mst_fairness_vars {
|
||||
int pbn;
|
||||
bool dsc_enabled;
|
||||
int bpp_x16;
|
||||
struct amdgpu_dm_connector *aconnector;
|
||||
};
|
||||
|
||||
static int kbps_to_peak_pbn(int kbps)
|
||||
|
@ -750,12 +745,12 @@ static void try_disable_dsc(struct drm_atomic_state *state,
|
|||
|
||||
static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
||||
struct dc_state *dc_state,
|
||||
struct dc_link *dc_link)
|
||||
struct dc_link *dc_link,
|
||||
struct dsc_mst_fairness_vars *vars)
|
||||
{
|
||||
int i;
|
||||
struct dc_stream_state *stream;
|
||||
struct dsc_mst_fairness_params params[MAX_PIPES];
|
||||
struct dsc_mst_fairness_vars vars[MAX_PIPES];
|
||||
struct amdgpu_dm_connector *aconnector;
|
||||
int count = 0;
|
||||
bool debugfs_overwrite = false;
|
||||
|
@ -776,6 +771,7 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
|||
params[count].timing = &stream->timing;
|
||||
params[count].sink = stream->sink;
|
||||
aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
|
||||
params[count].aconnector = aconnector;
|
||||
params[count].port = aconnector->port;
|
||||
params[count].clock_force_enable = aconnector->dsc_settings.dsc_force_enable;
|
||||
if (params[count].clock_force_enable == DSC_CLK_FORCE_ENABLE)
|
||||
|
@ -798,6 +794,7 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
|||
}
|
||||
/* Try no compression */
|
||||
for (i = 0; i < count; i++) {
|
||||
vars[i].aconnector = params[i].aconnector;
|
||||
vars[i].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps);
|
||||
vars[i].dsc_enabled = false;
|
||||
vars[i].bpp_x16 = 0;
|
||||
|
@ -851,7 +848,8 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
|
|||
}
|
||||
|
||||
bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
|
||||
struct dc_state *dc_state)
|
||||
struct dc_state *dc_state,
|
||||
struct dsc_mst_fairness_vars *vars)
|
||||
{
|
||||
int i, j;
|
||||
struct dc_stream_state *stream;
|
||||
|
@ -882,7 +880,7 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
|
|||
return false;
|
||||
|
||||
mutex_lock(&aconnector->mst_mgr.lock);
|
||||
if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link)) {
|
||||
if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link, vars)) {
|
||||
mutex_unlock(&aconnector->mst_mgr.lock);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -39,8 +39,17 @@ void
|
|||
dm_dp_create_fake_mst_encoders(struct amdgpu_device *adev);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
|
||||
struct dsc_mst_fairness_vars {
|
||||
int pbn;
|
||||
bool dsc_enabled;
|
||||
int bpp_x16;
|
||||
struct amdgpu_dm_connector *aconnector;
|
||||
};
|
||||
|
||||
bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
|
||||
struct dc_state *dc_state);
|
||||
struct dc_state *dc_state,
|
||||
struct dsc_mst_fairness_vars *vars);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -62,7 +62,7 @@ inline void dc_assert_fp_enabled(void)
|
|||
depth = *pcpu;
|
||||
put_cpu_ptr(&fpu_recursion_depth);
|
||||
|
||||
ASSERT(depth > 1);
|
||||
ASSERT(depth >= 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2586,13 +2586,21 @@ static struct abm *get_abm_from_stream_res(const struct dc_link *link)
|
|||
|
||||
int dc_link_get_backlight_level(const struct dc_link *link)
|
||||
{
|
||||
|
||||
struct abm *abm = get_abm_from_stream_res(link);
|
||||
struct panel_cntl *panel_cntl = link->panel_cntl;
|
||||
struct dc *dc = link->ctx->dc;
|
||||
struct dmcu *dmcu = dc->res_pool->dmcu;
|
||||
bool fw_set_brightness = true;
|
||||
|
||||
if (abm == NULL || abm->funcs->get_current_backlight == NULL)
|
||||
if (dmcu)
|
||||
fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
|
||||
|
||||
if (!fw_set_brightness && panel_cntl->funcs->get_current_backlight)
|
||||
return panel_cntl->funcs->get_current_backlight(panel_cntl);
|
||||
else if (abm != NULL && abm->funcs->get_current_backlight != NULL)
|
||||
return (int) abm->funcs->get_current_backlight(abm);
|
||||
else
|
||||
return DC_ERROR_UNEXPECTED;
|
||||
|
||||
return (int) abm->funcs->get_current_backlight(abm);
|
||||
}
|
||||
|
||||
int dc_link_get_target_backlight_pwm(const struct dc_link *link)
|
||||
|
|
|
@ -1,4 +1,26 @@
|
|||
/* Copyright 2015 Advanced Micro Devices, Inc. */
|
||||
/*
|
||||
* Copyright 2015 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*/
|
||||
#include "dm_services.h"
|
||||
#include "dc.h"
|
||||
#include "dc_link_dp.h"
|
||||
|
@ -1840,9 +1862,13 @@ bool perform_link_training_with_retries(
|
|||
dp_disable_link_phy(link, signal);
|
||||
|
||||
/* Abort link training if failure due to sink being unplugged. */
|
||||
if (status == LINK_TRAINING_ABORT)
|
||||
break;
|
||||
else if (do_fallback) {
|
||||
if (status == LINK_TRAINING_ABORT) {
|
||||
enum dc_connection_type type = dc_connection_none;
|
||||
|
||||
dc_link_detect_sink(link, &type);
|
||||
if (type == dc_connection_none)
|
||||
break;
|
||||
} else if (do_fallback) {
|
||||
decide_fallback_link_setting(*link_setting, ¤t_setting, status);
|
||||
/* Fail link training if reduced link bandwidth no longer meets
|
||||
* stream requirements.
|
||||
|
|
|
@ -49,7 +49,6 @@
|
|||
static unsigned int dce_get_16_bit_backlight_from_pwm(struct panel_cntl *panel_cntl)
|
||||
{
|
||||
uint64_t current_backlight;
|
||||
uint32_t round_result;
|
||||
uint32_t bl_period, bl_int_count;
|
||||
uint32_t bl_pwm, fractional_duty_cycle_en;
|
||||
uint32_t bl_period_mask, bl_pwm_mask;
|
||||
|
@ -84,15 +83,6 @@ static unsigned int dce_get_16_bit_backlight_from_pwm(struct panel_cntl *panel_c
|
|||
current_backlight = div_u64(current_backlight, bl_period);
|
||||
current_backlight = (current_backlight + 1) >> 1;
|
||||
|
||||
current_backlight = (uint64_t)(current_backlight) * bl_period;
|
||||
|
||||
round_result = (uint32_t)(current_backlight & 0xFFFFFFFF);
|
||||
|
||||
round_result = (round_result >> (bl_int_count-1)) & 1;
|
||||
|
||||
current_backlight >>= bl_int_count;
|
||||
current_backlight += round_result;
|
||||
|
||||
return (uint32_t)(current_backlight);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,63 +33,47 @@
|
|||
#define TABLE_PMSTATUSLOG 3 // Called by Tools for Agm logging
|
||||
#define TABLE_DPMCLOCKS 4 // Called by Driver; defined here, but not used, for backward compatible
|
||||
#define TABLE_MOMENTARY_PM 5 // Called by Tools; defined here, but not used, for backward compatible
|
||||
#define TABLE_COUNT 6
|
||||
#define TABLE_SMU_METRICS 6 // Called by Driver
|
||||
#define TABLE_COUNT 7
|
||||
|
||||
#define NUM_DSPCLK_LEVELS 8
|
||||
#define NUM_SOCCLK_DPM_LEVELS 8
|
||||
#define NUM_DCEFCLK_DPM_LEVELS 4
|
||||
#define NUM_FCLK_DPM_LEVELS 4
|
||||
#define NUM_MEMCLK_DPM_LEVELS 4
|
||||
typedef struct SmuMetricsTable_t {
|
||||
//CPU status
|
||||
uint16_t CoreFrequency[6]; //[MHz]
|
||||
uint32_t CorePower[6]; //[mW]
|
||||
uint16_t CoreTemperature[6]; //[centi-Celsius]
|
||||
uint16_t L3Frequency[2]; //[MHz]
|
||||
uint16_t L3Temperature[2]; //[centi-Celsius]
|
||||
uint16_t C0Residency[6]; //Percentage
|
||||
|
||||
#define NUMBER_OF_PSTATES 8
|
||||
#define NUMBER_OF_CORES 8
|
||||
// GFX status
|
||||
uint16_t GfxclkFrequency; //[MHz]
|
||||
uint16_t GfxTemperature; //[centi-Celsius]
|
||||
|
||||
typedef enum {
|
||||
S3_TYPE_ENTRY,
|
||||
S5_TYPE_ENTRY,
|
||||
} Sleep_Type_e;
|
||||
// SOC IP info
|
||||
uint16_t SocclkFrequency; //[MHz]
|
||||
uint16_t VclkFrequency; //[MHz]
|
||||
uint16_t DclkFrequency; //[MHz]
|
||||
uint16_t MemclkFrequency; //[MHz]
|
||||
|
||||
typedef enum {
|
||||
GFX_OFF = 0,
|
||||
GFX_ON = 1,
|
||||
} GFX_Mode_e;
|
||||
// power, VF info for CPU/GFX telemetry rails, and then socket power total
|
||||
uint32_t Voltage[2]; //[mV] indices: VDDCR_VDD, VDDCR_GFX
|
||||
uint32_t Current[2]; //[mA] indices: VDDCR_VDD, VDDCR_GFX
|
||||
uint32_t Power[2]; //[mW] indices: VDDCR_VDD, VDDCR_GFX
|
||||
uint32_t CurrentSocketPower; //[mW]
|
||||
|
||||
typedef enum {
|
||||
CPU_P0 = 0,
|
||||
CPU_P1,
|
||||
CPU_P2,
|
||||
CPU_P3,
|
||||
CPU_P4,
|
||||
CPU_P5,
|
||||
CPU_P6,
|
||||
CPU_P7
|
||||
} CPU_PState_e;
|
||||
uint16_t SocTemperature; //[centi-Celsius]
|
||||
uint16_t EdgeTemperature;
|
||||
uint16_t ThrottlerStatus;
|
||||
uint16_t Spare;
|
||||
|
||||
typedef enum {
|
||||
CPU_CORE0 = 0,
|
||||
CPU_CORE1,
|
||||
CPU_CORE2,
|
||||
CPU_CORE3,
|
||||
CPU_CORE4,
|
||||
CPU_CORE5,
|
||||
CPU_CORE6,
|
||||
CPU_CORE7
|
||||
} CORE_ID_e;
|
||||
} SmuMetricsTable_t;
|
||||
|
||||
typedef enum {
|
||||
DF_DPM0 = 0,
|
||||
DF_DPM1,
|
||||
DF_DPM2,
|
||||
DF_DPM3,
|
||||
DF_PState_Count
|
||||
} DF_PState_e;
|
||||
|
||||
typedef enum {
|
||||
GFX_DPM0 = 0,
|
||||
GFX_DPM1,
|
||||
GFX_DPM2,
|
||||
GFX_DPM3,
|
||||
GFX_PState_Count
|
||||
} GFX_PState_e;
|
||||
typedef struct SmuMetrics_t {
|
||||
SmuMetricsTable_t Current;
|
||||
SmuMetricsTable_t Average;
|
||||
uint32_t SampleStartTime;
|
||||
uint32_t SampleStopTime;
|
||||
uint32_t Accnt;
|
||||
} SmuMetrics_t;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -226,7 +226,10 @@
|
|||
__SMU_DUMMY_MAP(SetUclkDpmMode), \
|
||||
__SMU_DUMMY_MAP(LightSBR), \
|
||||
__SMU_DUMMY_MAP(GfxDriverResetRecovery), \
|
||||
__SMU_DUMMY_MAP(BoardPowerCalibration),
|
||||
__SMU_DUMMY_MAP(BoardPowerCalibration), \
|
||||
__SMU_DUMMY_MAP(RequestGfxclk), \
|
||||
__SMU_DUMMY_MAP(ForceGfxVid), \
|
||||
__SMU_DUMMY_MAP(UnforceGfxVid),
|
||||
|
||||
#undef __SMU_DUMMY_MAP
|
||||
#define __SMU_DUMMY_MAP(type) SMU_MSG_##type
|
||||
|
|
|
@ -65,6 +65,13 @@
|
|||
#define PPSMC_MSG_SetDriverTableVMID 0x34
|
||||
#define PPSMC_MSG_SetSoftMinCclk 0x35
|
||||
#define PPSMC_MSG_SetSoftMaxCclk 0x36
|
||||
#define PPSMC_Message_Count 0x37
|
||||
#define PPSMC_MSG_GetGfxFrequency 0x37
|
||||
#define PPSMC_MSG_GetGfxVid 0x38
|
||||
#define PPSMC_MSG_ForceGfxFreq 0x39
|
||||
#define PPSMC_MSG_UnForceGfxFreq 0x3A
|
||||
#define PPSMC_MSG_ForceGfxVid 0x3B
|
||||
#define PPSMC_MSG_UnforceGfxVid 0x3C
|
||||
#define PPSMC_MSG_GetEnabledSmuFeatures 0x3D
|
||||
#define PPSMC_Message_Count 0x3E
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1404,7 +1404,7 @@ static int smu_disable_dpms(struct smu_context *smu)
|
|||
*/
|
||||
if (smu->uploading_custom_pp_table &&
|
||||
(adev->asic_type >= CHIP_NAVI10) &&
|
||||
(adev->asic_type <= CHIP_DIMGREY_CAVEFISH))
|
||||
(adev->asic_type <= CHIP_BEIGE_GOBY))
|
||||
return smu_disable_all_features_with_exception(smu,
|
||||
true,
|
||||
SMU_FEATURE_COUNT);
|
||||
|
|
|
@ -771,8 +771,12 @@ static int arcturus_print_clk_levels(struct smu_context *smu,
|
|||
struct smu_11_0_dpm_context *dpm_context = NULL;
|
||||
uint32_t gen_speed, lane_width;
|
||||
|
||||
if (amdgpu_ras_intr_triggered())
|
||||
return sysfs_emit(buf, "unavailable\n");
|
||||
smu_cmn_get_sysfs_buf(&buf, &size);
|
||||
|
||||
if (amdgpu_ras_intr_triggered()) {
|
||||
size += sysfs_emit_at(buf, size, "unavailable\n");
|
||||
return size;
|
||||
}
|
||||
|
||||
dpm_context = smu_dpm->dpm_context;
|
||||
|
||||
|
|
|
@ -44,6 +44,27 @@
|
|||
#undef pr_info
|
||||
#undef pr_debug
|
||||
|
||||
/* unit: MHz */
|
||||
#define CYAN_SKILLFISH_SCLK_MIN 1000
|
||||
#define CYAN_SKILLFISH_SCLK_MAX 2000
|
||||
#define CYAN_SKILLFISH_SCLK_DEFAULT 1800
|
||||
|
||||
/* unit: mV */
|
||||
#define CYAN_SKILLFISH_VDDC_MIN 700
|
||||
#define CYAN_SKILLFISH_VDDC_MAX 1129
|
||||
#define CYAN_SKILLFISH_VDDC_MAGIC 5118 // 0x13fe
|
||||
|
||||
static struct gfx_user_settings {
|
||||
uint32_t sclk;
|
||||
uint32_t vddc;
|
||||
} cyan_skillfish_user_settings;
|
||||
|
||||
#define FEATURE_MASK(feature) (1ULL << feature)
|
||||
#define SMC_DPM_FEATURE ( \
|
||||
FEATURE_MASK(FEATURE_FCLK_DPM_BIT) | \
|
||||
FEATURE_MASK(FEATURE_SOC_DPM_BIT) | \
|
||||
FEATURE_MASK(FEATURE_GFX_DPM_BIT))
|
||||
|
||||
static struct cmn2asic_msg_mapping cyan_skillfish_message_map[SMU_MSG_MAX_COUNT] = {
|
||||
MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0),
|
||||
MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 0),
|
||||
|
@ -52,14 +73,473 @@ static struct cmn2asic_msg_mapping cyan_skillfish_message_map[SMU_MSG_MAX_COUNT]
|
|||
MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverTableDramAddrLow, 0),
|
||||
MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 0),
|
||||
MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 0),
|
||||
MSG_MAP(GetEnabledSmuFeatures, PPSMC_MSG_GetEnabledSmuFeatures, 0),
|
||||
MSG_MAP(RequestGfxclk, PPSMC_MSG_RequestGfxclk, 0),
|
||||
MSG_MAP(ForceGfxVid, PPSMC_MSG_ForceGfxVid, 0),
|
||||
MSG_MAP(UnforceGfxVid, PPSMC_MSG_UnforceGfxVid, 0),
|
||||
};
|
||||
|
||||
static struct cmn2asic_mapping cyan_skillfish_table_map[SMU_TABLE_COUNT] = {
|
||||
TAB_MAP_VALID(SMU_METRICS),
|
||||
};
|
||||
|
||||
static int cyan_skillfish_tables_init(struct smu_context *smu)
|
||||
{
|
||||
struct smu_table_context *smu_table = &smu->smu_table;
|
||||
struct smu_table *tables = smu_table->tables;
|
||||
|
||||
SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS,
|
||||
sizeof(SmuMetrics_t),
|
||||
PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM);
|
||||
|
||||
smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
|
||||
if (!smu_table->metrics_table)
|
||||
goto err0_out;
|
||||
|
||||
smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_2);
|
||||
smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
|
||||
if (!smu_table->gpu_metrics_table)
|
||||
goto err1_out;
|
||||
|
||||
smu_table->metrics_time = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
err1_out:
|
||||
smu_table->gpu_metrics_table_size = 0;
|
||||
kfree(smu_table->metrics_table);
|
||||
err0_out:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int cyan_skillfish_init_smc_tables(struct smu_context *smu)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = cyan_skillfish_tables_init(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return smu_v11_0_init_smc_tables(smu);
|
||||
}
|
||||
|
||||
static int cyan_skillfish_finit_smc_tables(struct smu_context *smu)
|
||||
{
|
||||
struct smu_table_context *smu_table = &smu->smu_table;
|
||||
|
||||
kfree(smu_table->metrics_table);
|
||||
smu_table->metrics_table = NULL;
|
||||
|
||||
kfree(smu_table->gpu_metrics_table);
|
||||
smu_table->gpu_metrics_table = NULL;
|
||||
smu_table->gpu_metrics_table_size = 0;
|
||||
|
||||
smu_table->metrics_time = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
cyan_skillfish_get_smu_metrics_data(struct smu_context *smu,
|
||||
MetricsMember_t member,
|
||||
uint32_t *value)
|
||||
{
|
||||
struct smu_table_context *smu_table = &smu->smu_table;
|
||||
SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&smu->metrics_lock);
|
||||
|
||||
ret = smu_cmn_get_metrics_table_locked(smu, NULL, false);
|
||||
if (ret) {
|
||||
mutex_unlock(&smu->metrics_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (member) {
|
||||
case METRICS_CURR_GFXCLK:
|
||||
*value = metrics->Current.GfxclkFrequency;
|
||||
break;
|
||||
case METRICS_CURR_SOCCLK:
|
||||
*value = metrics->Current.SocclkFrequency;
|
||||
break;
|
||||
case METRICS_CURR_VCLK:
|
||||
*value = metrics->Current.VclkFrequency;
|
||||
break;
|
||||
case METRICS_CURR_DCLK:
|
||||
*value = metrics->Current.DclkFrequency;
|
||||
break;
|
||||
case METRICS_CURR_UCLK:
|
||||
*value = metrics->Current.MemclkFrequency;
|
||||
break;
|
||||
case METRICS_AVERAGE_SOCKETPOWER:
|
||||
*value = (metrics->Current.CurrentSocketPower << 8) /
|
||||
1000;
|
||||
break;
|
||||
case METRICS_TEMPERATURE_EDGE:
|
||||
*value = metrics->Current.GfxTemperature / 100 *
|
||||
SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
|
||||
break;
|
||||
case METRICS_TEMPERATURE_HOTSPOT:
|
||||
*value = metrics->Current.SocTemperature / 100 *
|
||||
SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
|
||||
break;
|
||||
case METRICS_VOLTAGE_VDDSOC:
|
||||
*value = metrics->Current.Voltage[0];
|
||||
break;
|
||||
case METRICS_VOLTAGE_VDDGFX:
|
||||
*value = metrics->Current.Voltage[1];
|
||||
break;
|
||||
case METRICS_THROTTLER_STATUS:
|
||||
*value = metrics->Current.ThrottlerStatus;
|
||||
break;
|
||||
default:
|
||||
*value = UINT_MAX;
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_unlock(&smu->metrics_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cyan_skillfish_read_sensor(struct smu_context *smu,
|
||||
enum amd_pp_sensors sensor,
|
||||
void *data,
|
||||
uint32_t *size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!data || !size)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&smu->sensor_lock);
|
||||
|
||||
switch (sensor) {
|
||||
case AMDGPU_PP_SENSOR_GFX_SCLK:
|
||||
ret = cyan_skillfish_get_smu_metrics_data(smu,
|
||||
METRICS_CURR_GFXCLK,
|
||||
(uint32_t *)data);
|
||||
*(uint32_t *)data *= 100;
|
||||
*size = 4;
|
||||
break;
|
||||
case AMDGPU_PP_SENSOR_GFX_MCLK:
|
||||
ret = cyan_skillfish_get_smu_metrics_data(smu,
|
||||
METRICS_CURR_UCLK,
|
||||
(uint32_t *)data);
|
||||
*(uint32_t *)data *= 100;
|
||||
*size = 4;
|
||||
break;
|
||||
case AMDGPU_PP_SENSOR_GPU_POWER:
|
||||
ret = cyan_skillfish_get_smu_metrics_data(smu,
|
||||
METRICS_AVERAGE_SOCKETPOWER,
|
||||
(uint32_t *)data);
|
||||
*size = 4;
|
||||
break;
|
||||
case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
|
||||
ret = cyan_skillfish_get_smu_metrics_data(smu,
|
||||
METRICS_TEMPERATURE_HOTSPOT,
|
||||
(uint32_t *)data);
|
||||
*size = 4;
|
||||
break;
|
||||
case AMDGPU_PP_SENSOR_EDGE_TEMP:
|
||||
ret = cyan_skillfish_get_smu_metrics_data(smu,
|
||||
METRICS_TEMPERATURE_EDGE,
|
||||
(uint32_t *)data);
|
||||
*size = 4;
|
||||
break;
|
||||
case AMDGPU_PP_SENSOR_VDDNB:
|
||||
ret = cyan_skillfish_get_smu_metrics_data(smu,
|
||||
METRICS_VOLTAGE_VDDSOC,
|
||||
(uint32_t *)data);
|
||||
*size = 4;
|
||||
break;
|
||||
case AMDGPU_PP_SENSOR_VDDGFX:
|
||||
ret = cyan_skillfish_get_smu_metrics_data(smu,
|
||||
METRICS_VOLTAGE_VDDGFX,
|
||||
(uint32_t *)data);
|
||||
*size = 4;
|
||||
break;
|
||||
default:
|
||||
ret = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_unlock(&smu->sensor_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cyan_skillfish_get_current_clk_freq(struct smu_context *smu,
|
||||
enum smu_clk_type clk_type,
|
||||
uint32_t *value)
|
||||
{
|
||||
MetricsMember_t member_type;
|
||||
|
||||
switch (clk_type) {
|
||||
case SMU_GFXCLK:
|
||||
case SMU_SCLK:
|
||||
member_type = METRICS_CURR_GFXCLK;
|
||||
break;
|
||||
case SMU_FCLK:
|
||||
case SMU_MCLK:
|
||||
member_type = METRICS_CURR_UCLK;
|
||||
break;
|
||||
case SMU_SOCCLK:
|
||||
member_type = METRICS_CURR_SOCCLK;
|
||||
break;
|
||||
case SMU_VCLK:
|
||||
member_type = METRICS_CURR_VCLK;
|
||||
break;
|
||||
case SMU_DCLK:
|
||||
member_type = METRICS_CURR_DCLK;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return cyan_skillfish_get_smu_metrics_data(smu, member_type, value);
|
||||
}
|
||||
|
||||
static int cyan_skillfish_print_clk_levels(struct smu_context *smu,
|
||||
enum smu_clk_type clk_type,
|
||||
char *buf)
|
||||
{
|
||||
int ret = 0, size = 0;
|
||||
uint32_t cur_value = 0;
|
||||
|
||||
smu_cmn_get_sysfs_buf(&buf, &size);
|
||||
|
||||
switch (clk_type) {
|
||||
case SMU_OD_SCLK:
|
||||
ret = cyan_skillfish_get_smu_metrics_data(smu, METRICS_CURR_GFXCLK, &cur_value);
|
||||
if (ret)
|
||||
return ret;
|
||||
size += sysfs_emit_at(buf, size,"%s:\n", "OD_SCLK");
|
||||
size += sysfs_emit_at(buf, size, "0: %uMhz *\n", cur_value);
|
||||
break;
|
||||
case SMU_OD_VDDC_CURVE:
|
||||
ret = cyan_skillfish_get_smu_metrics_data(smu, METRICS_VOLTAGE_VDDGFX, &cur_value);
|
||||
if (ret)
|
||||
return ret;
|
||||
size += sysfs_emit_at(buf, size,"%s:\n", "OD_VDDC");
|
||||
size += sysfs_emit_at(buf, size, "0: %umV *\n", cur_value);
|
||||
break;
|
||||
case SMU_OD_RANGE:
|
||||
size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
|
||||
size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n",
|
||||
CYAN_SKILLFISH_SCLK_MIN, CYAN_SKILLFISH_SCLK_MAX);
|
||||
size += sysfs_emit_at(buf, size, "VDDC: %7umV %10umV\n",
|
||||
CYAN_SKILLFISH_VDDC_MIN, CYAN_SKILLFISH_VDDC_MAX);
|
||||
break;
|
||||
case SMU_GFXCLK:
|
||||
case SMU_SCLK:
|
||||
case SMU_FCLK:
|
||||
case SMU_MCLK:
|
||||
case SMU_SOCCLK:
|
||||
case SMU_VCLK:
|
||||
case SMU_DCLK:
|
||||
ret = cyan_skillfish_get_current_clk_freq(smu, clk_type, &cur_value);
|
||||
if (ret)
|
||||
return ret;
|
||||
size += sysfs_emit_at(buf, size, "0: %uMhz *\n", cur_value);
|
||||
break;
|
||||
default:
|
||||
dev_warn(smu->adev->dev, "Unsupported clock type\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static bool cyan_skillfish_is_dpm_running(struct smu_context *smu)
|
||||
{
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
int ret = 0;
|
||||
uint32_t feature_mask[2];
|
||||
uint64_t feature_enabled;
|
||||
|
||||
/* we need to re-init after suspend so return false */
|
||||
if (adev->in_suspend)
|
||||
return false;
|
||||
|
||||
ret = smu_cmn_get_enabled_32_bits_mask(smu, feature_mask, 2);
|
||||
|
||||
if (ret)
|
||||
return false;
|
||||
|
||||
feature_enabled = (uint64_t)feature_mask[0] |
|
||||
((uint64_t)feature_mask[1] << 32);
|
||||
|
||||
return !!(feature_enabled & SMC_DPM_FEATURE);
|
||||
}
|
||||
|
||||
static ssize_t cyan_skillfish_get_gpu_metrics(struct smu_context *smu,
|
||||
void **table)
|
||||
{
|
||||
struct smu_table_context *smu_table = &smu->smu_table;
|
||||
struct gpu_metrics_v2_2 *gpu_metrics =
|
||||
(struct gpu_metrics_v2_2 *)smu_table->gpu_metrics_table;
|
||||
SmuMetrics_t metrics;
|
||||
int i, ret = 0;
|
||||
|
||||
ret = smu_cmn_get_metrics_table(smu, &metrics, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 2);
|
||||
|
||||
gpu_metrics->temperature_gfx = metrics.Current.GfxTemperature;
|
||||
gpu_metrics->temperature_soc = metrics.Current.SocTemperature;
|
||||
|
||||
gpu_metrics->average_socket_power = metrics.Current.CurrentSocketPower;
|
||||
gpu_metrics->average_soc_power = metrics.Current.Power[0];
|
||||
gpu_metrics->average_gfx_power = metrics.Current.Power[1];
|
||||
|
||||
gpu_metrics->average_gfxclk_frequency = metrics.Average.GfxclkFrequency;
|
||||
gpu_metrics->average_socclk_frequency = metrics.Average.SocclkFrequency;
|
||||
gpu_metrics->average_uclk_frequency = metrics.Average.MemclkFrequency;
|
||||
gpu_metrics->average_fclk_frequency = metrics.Average.MemclkFrequency;
|
||||
gpu_metrics->average_vclk_frequency = metrics.Average.VclkFrequency;
|
||||
gpu_metrics->average_dclk_frequency = metrics.Average.DclkFrequency;
|
||||
|
||||
gpu_metrics->current_gfxclk = metrics.Current.GfxclkFrequency;
|
||||
gpu_metrics->current_socclk = metrics.Current.SocclkFrequency;
|
||||
gpu_metrics->current_uclk = metrics.Current.MemclkFrequency;
|
||||
gpu_metrics->current_fclk = metrics.Current.MemclkFrequency;
|
||||
gpu_metrics->current_vclk = metrics.Current.VclkFrequency;
|
||||
gpu_metrics->current_dclk = metrics.Current.DclkFrequency;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
gpu_metrics->temperature_core[i] = metrics.Current.CoreTemperature[i];
|
||||
gpu_metrics->average_core_power[i] = metrics.Average.CorePower[i];
|
||||
gpu_metrics->current_coreclk[i] = metrics.Current.CoreFrequency[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
gpu_metrics->temperature_l3[i] = metrics.Current.L3Temperature[i];
|
||||
gpu_metrics->current_l3clk[i] = metrics.Current.L3Frequency[i];
|
||||
}
|
||||
|
||||
gpu_metrics->throttle_status = metrics.Current.ThrottlerStatus;
|
||||
gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
|
||||
|
||||
*table = (void *)gpu_metrics;
|
||||
|
||||
return sizeof(struct gpu_metrics_v2_2);
|
||||
}
|
||||
|
||||
static int cyan_skillfish_od_edit_dpm_table(struct smu_context *smu,
|
||||
enum PP_OD_DPM_TABLE_COMMAND type,
|
||||
long input[], uint32_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t vid;
|
||||
|
||||
switch (type) {
|
||||
case PP_OD_EDIT_VDDC_CURVE:
|
||||
if (size != 3 || input[0] != 0) {
|
||||
dev_err(smu->adev->dev, "Invalid parameter!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (input[1] <= CYAN_SKILLFISH_SCLK_MIN ||
|
||||
input[1] > CYAN_SKILLFISH_SCLK_MAX) {
|
||||
dev_err(smu->adev->dev, "Invalid sclk! Valid sclk range: %uMHz - %uMhz\n",
|
||||
CYAN_SKILLFISH_SCLK_MIN, CYAN_SKILLFISH_SCLK_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (input[2] <= CYAN_SKILLFISH_VDDC_MIN ||
|
||||
input[2] > CYAN_SKILLFISH_VDDC_MAX) {
|
||||
dev_err(smu->adev->dev, "Invalid vddc! Valid vddc range: %umV - %umV\n",
|
||||
CYAN_SKILLFISH_VDDC_MIN, CYAN_SKILLFISH_VDDC_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cyan_skillfish_user_settings.sclk = input[1];
|
||||
cyan_skillfish_user_settings.vddc = input[2];
|
||||
|
||||
break;
|
||||
case PP_OD_RESTORE_DEFAULT_TABLE:
|
||||
if (size != 0) {
|
||||
dev_err(smu->adev->dev, "Invalid parameter!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cyan_skillfish_user_settings.sclk = CYAN_SKILLFISH_SCLK_DEFAULT;
|
||||
cyan_skillfish_user_settings.vddc = CYAN_SKILLFISH_VDDC_MAGIC;
|
||||
|
||||
break;
|
||||
case PP_OD_COMMIT_DPM_TABLE:
|
||||
if (size != 0) {
|
||||
dev_err(smu->adev->dev, "Invalid parameter!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cyan_skillfish_user_settings.sclk < CYAN_SKILLFISH_SCLK_MIN ||
|
||||
cyan_skillfish_user_settings.sclk > CYAN_SKILLFISH_SCLK_MAX) {
|
||||
dev_err(smu->adev->dev, "Invalid sclk! Valid sclk range: %uMHz - %uMhz\n",
|
||||
CYAN_SKILLFISH_SCLK_MIN, CYAN_SKILLFISH_SCLK_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((cyan_skillfish_user_settings.vddc != CYAN_SKILLFISH_VDDC_MAGIC) &&
|
||||
(cyan_skillfish_user_settings.vddc < CYAN_SKILLFISH_VDDC_MIN ||
|
||||
cyan_skillfish_user_settings.vddc > CYAN_SKILLFISH_VDDC_MAX)) {
|
||||
dev_err(smu->adev->dev, "Invalid vddc! Valid vddc range: %umV - %umV\n",
|
||||
CYAN_SKILLFISH_VDDC_MIN, CYAN_SKILLFISH_VDDC_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_RequestGfxclk,
|
||||
cyan_skillfish_user_settings.sclk, NULL);
|
||||
if (ret) {
|
||||
dev_err(smu->adev->dev, "Set sclk failed!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (cyan_skillfish_user_settings.vddc == CYAN_SKILLFISH_VDDC_MAGIC) {
|
||||
ret = smu_cmn_send_smc_msg(smu, SMU_MSG_UnforceGfxVid, NULL);
|
||||
if (ret) {
|
||||
dev_err(smu->adev->dev, "Unforce vddc failed!\n");
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* PMFW accepts SVI2 VID code, convert voltage to VID:
|
||||
* vid = (uint32_t)((1.55 - voltage) * 160.0 + 0.00001)
|
||||
*/
|
||||
vid = (1550 - cyan_skillfish_user_settings.vddc) * 160 / 1000;
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ForceGfxVid, vid, NULL);
|
||||
if (ret) {
|
||||
dev_err(smu->adev->dev, "Force vddc failed!\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct pptable_funcs cyan_skillfish_ppt_funcs = {
|
||||
|
||||
.check_fw_status = smu_v11_0_check_fw_status,
|
||||
.check_fw_version = smu_v11_0_check_fw_version,
|
||||
.init_power = smu_v11_0_init_power,
|
||||
.fini_power = smu_v11_0_fini_power,
|
||||
.init_smc_tables = cyan_skillfish_init_smc_tables,
|
||||
.fini_smc_tables = cyan_skillfish_finit_smc_tables,
|
||||
.read_sensor = cyan_skillfish_read_sensor,
|
||||
.print_clk_levels = cyan_skillfish_print_clk_levels,
|
||||
.is_dpm_running = cyan_skillfish_is_dpm_running,
|
||||
.get_gpu_metrics = cyan_skillfish_get_gpu_metrics,
|
||||
.od_edit_dpm_table = cyan_skillfish_od_edit_dpm_table,
|
||||
.register_irq_handler = smu_v11_0_register_irq_handler,
|
||||
.notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
|
||||
.send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param,
|
||||
|
@ -72,5 +552,6 @@ void cyan_skillfish_set_ppt_funcs(struct smu_context *smu)
|
|||
{
|
||||
smu->ppt_funcs = &cyan_skillfish_ppt_funcs;
|
||||
smu->message_map = cyan_skillfish_message_map;
|
||||
smu->table_map = cyan_skillfish_table_map;
|
||||
smu->is_apu = true;
|
||||
}
|
||||
|
|
|
@ -1279,6 +1279,8 @@ static int navi10_print_clk_levels(struct smu_context *smu,
|
|||
struct smu_11_0_overdrive_table *od_settings = smu->od_settings;
|
||||
uint32_t min_value, max_value;
|
||||
|
||||
smu_cmn_get_sysfs_buf(&buf, &size);
|
||||
|
||||
switch (clk_type) {
|
||||
case SMU_GFXCLK:
|
||||
case SMU_SCLK:
|
||||
|
@ -1392,7 +1394,7 @@ static int navi10_print_clk_levels(struct smu_context *smu,
|
|||
case SMU_OD_RANGE:
|
||||
if (!smu->od_enabled || !od_table || !od_settings)
|
||||
break;
|
||||
size = sysfs_emit(buf, "%s:\n", "OD_RANGE");
|
||||
size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
|
||||
|
||||
if (navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_GFXCLK_LIMITS)) {
|
||||
navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_GFXCLKFMIN,
|
||||
|
@ -2272,7 +2274,27 @@ static int navi10_baco_enter(struct smu_context *smu)
|
|||
{
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
|
||||
if (adev->in_runpm)
|
||||
/*
|
||||
* This aims the case below:
|
||||
* amdgpu driver loaded -> runpm suspend kicked -> sound driver loaded
|
||||
*
|
||||
* For NAVI10 and later ASICs, we rely on PMFW to handle the runpm. To
|
||||
* make that possible, PMFW needs to acknowledge the dstate transition
|
||||
* process for both gfx(function 0) and audio(function 1) function of
|
||||
* the ASIC.
|
||||
*
|
||||
* The PCI device's initial runpm status is RUNPM_SUSPENDED. So as the
|
||||
* device representing the audio function of the ASIC. And that means
|
||||
* even if the sound driver(snd_hda_intel) was not loaded yet, it's still
|
||||
* possible runpm suspend kicked on the ASIC. However without the dstate
|
||||
* transition notification from audio function, pmfw cannot handle the
|
||||
* BACO in/exit correctly. And that will cause driver hang on runpm
|
||||
* resuming.
|
||||
*
|
||||
* To address this, we revert to legacy message way(driver masters the
|
||||
* timing for BACO in/exit) on sound driver missing.
|
||||
*/
|
||||
if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev))
|
||||
return smu_v11_0_baco_set_armd3_sequence(smu, BACO_SEQ_BACO);
|
||||
else
|
||||
return smu_v11_0_baco_enter(smu);
|
||||
|
@ -2282,7 +2304,7 @@ static int navi10_baco_exit(struct smu_context *smu)
|
|||
{
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
|
||||
if (adev->in_runpm) {
|
||||
if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) {
|
||||
/* Wait for PMFW handling for the Dstate change */
|
||||
msleep(10);
|
||||
return smu_v11_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS);
|
||||
|
|
|
@ -1058,6 +1058,8 @@ static int sienna_cichlid_print_clk_levels(struct smu_context *smu,
|
|||
uint32_t min_value, max_value;
|
||||
uint32_t smu_version;
|
||||
|
||||
smu_cmn_get_sysfs_buf(&buf, &size);
|
||||
|
||||
switch (clk_type) {
|
||||
case SMU_GFXCLK:
|
||||
case SMU_SCLK:
|
||||
|
@ -1180,7 +1182,7 @@ static int sienna_cichlid_print_clk_levels(struct smu_context *smu,
|
|||
if (!smu->od_enabled || !od_table || !od_settings)
|
||||
break;
|
||||
|
||||
size = sysfs_emit(buf, "%s:\n", "OD_RANGE");
|
||||
size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
|
||||
|
||||
if (sienna_cichlid_is_od_feature_supported(od_settings, SMU_11_0_7_ODCAP_GFXCLK_LIMITS)) {
|
||||
sienna_cichlid_get_od_setting_range(od_settings, SMU_11_0_7_ODSETTING_GFXCLKFMIN,
|
||||
|
@ -2187,7 +2189,7 @@ static int sienna_cichlid_baco_enter(struct smu_context *smu)
|
|||
{
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
|
||||
if (adev->in_runpm)
|
||||
if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev))
|
||||
return smu_v11_0_baco_set_armd3_sequence(smu, BACO_SEQ_BACO);
|
||||
else
|
||||
return smu_v11_0_baco_enter(smu);
|
||||
|
@ -2197,7 +2199,7 @@ static int sienna_cichlid_baco_exit(struct smu_context *smu)
|
|||
{
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
|
||||
if (adev->in_runpm) {
|
||||
if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) {
|
||||
/* Wait for PMFW handling for the Dstate change */
|
||||
msleep(10);
|
||||
return smu_v11_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS);
|
||||
|
|
|
@ -589,10 +589,12 @@ static int vangogh_print_legacy_clk_levels(struct smu_context *smu,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
smu_cmn_get_sysfs_buf(&buf, &size);
|
||||
|
||||
switch (clk_type) {
|
||||
case SMU_OD_SCLK:
|
||||
if (smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {
|
||||
size = sysfs_emit(buf, "%s:\n", "OD_SCLK");
|
||||
size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
|
||||
size += sysfs_emit_at(buf, size, "0: %10uMhz\n",
|
||||
(smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq);
|
||||
size += sysfs_emit_at(buf, size, "1: %10uMhz\n",
|
||||
|
@ -601,7 +603,7 @@ static int vangogh_print_legacy_clk_levels(struct smu_context *smu,
|
|||
break;
|
||||
case SMU_OD_CCLK:
|
||||
if (smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {
|
||||
size = sysfs_emit(buf, "CCLK_RANGE in Core%d:\n", smu->cpu_core_id_select);
|
||||
size += sysfs_emit_at(buf, size, "CCLK_RANGE in Core%d:\n", smu->cpu_core_id_select);
|
||||
size += sysfs_emit_at(buf, size, "0: %10uMhz\n",
|
||||
(smu->cpu_actual_soft_min_freq > 0) ? smu->cpu_actual_soft_min_freq : smu->cpu_default_soft_min_freq);
|
||||
size += sysfs_emit_at(buf, size, "1: %10uMhz\n",
|
||||
|
@ -610,7 +612,7 @@ static int vangogh_print_legacy_clk_levels(struct smu_context *smu,
|
|||
break;
|
||||
case SMU_OD_RANGE:
|
||||
if (smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {
|
||||
size = sysfs_emit(buf, "%s:\n", "OD_RANGE");
|
||||
size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
|
||||
size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n",
|
||||
smu->gfx_default_hard_min_freq, smu->gfx_default_soft_max_freq);
|
||||
size += sysfs_emit_at(buf, size, "CCLK: %7uMhz %10uMhz\n",
|
||||
|
@ -688,10 +690,12 @@ static int vangogh_print_clk_levels(struct smu_context *smu,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
smu_cmn_get_sysfs_buf(&buf, &size);
|
||||
|
||||
switch (clk_type) {
|
||||
case SMU_OD_SCLK:
|
||||
if (smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {
|
||||
size = sysfs_emit(buf, "%s:\n", "OD_SCLK");
|
||||
size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
|
||||
size += sysfs_emit_at(buf, size, "0: %10uMhz\n",
|
||||
(smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq);
|
||||
size += sysfs_emit_at(buf, size, "1: %10uMhz\n",
|
||||
|
@ -700,7 +704,7 @@ static int vangogh_print_clk_levels(struct smu_context *smu,
|
|||
break;
|
||||
case SMU_OD_CCLK:
|
||||
if (smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {
|
||||
size = sysfs_emit(buf, "CCLK_RANGE in Core%d:\n", smu->cpu_core_id_select);
|
||||
size += sysfs_emit_at(buf, size, "CCLK_RANGE in Core%d:\n", smu->cpu_core_id_select);
|
||||
size += sysfs_emit_at(buf, size, "0: %10uMhz\n",
|
||||
(smu->cpu_actual_soft_min_freq > 0) ? smu->cpu_actual_soft_min_freq : smu->cpu_default_soft_min_freq);
|
||||
size += sysfs_emit_at(buf, size, "1: %10uMhz\n",
|
||||
|
@ -709,7 +713,7 @@ static int vangogh_print_clk_levels(struct smu_context *smu,
|
|||
break;
|
||||
case SMU_OD_RANGE:
|
||||
if (smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {
|
||||
size = sysfs_emit(buf, "%s:\n", "OD_RANGE");
|
||||
size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
|
||||
size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n",
|
||||
smu->gfx_default_hard_min_freq, smu->gfx_default_soft_max_freq);
|
||||
size += sysfs_emit_at(buf, size, "CCLK: %7uMhz %10uMhz\n",
|
||||
|
|
|
@ -497,6 +497,8 @@ static int renoir_print_clk_levels(struct smu_context *smu,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
smu_cmn_get_sysfs_buf(&buf, &size);
|
||||
|
||||
switch (clk_type) {
|
||||
case SMU_OD_RANGE:
|
||||
if (smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {
|
||||
|
|
|
@ -733,15 +733,19 @@ static int aldebaran_print_clk_levels(struct smu_context *smu,
|
|||
uint32_t freq_values[3] = {0};
|
||||
uint32_t min_clk, max_clk;
|
||||
|
||||
if (amdgpu_ras_intr_triggered())
|
||||
return sysfs_emit(buf, "unavailable\n");
|
||||
smu_cmn_get_sysfs_buf(&buf, &size);
|
||||
|
||||
if (amdgpu_ras_intr_triggered()) {
|
||||
size += sysfs_emit_at(buf, size, "unavailable\n");
|
||||
return size;
|
||||
}
|
||||
|
||||
dpm_context = smu_dpm->dpm_context;
|
||||
|
||||
switch (type) {
|
||||
|
||||
case SMU_OD_SCLK:
|
||||
size = sysfs_emit(buf, "%s:\n", "GFXCLK");
|
||||
size += sysfs_emit_at(buf, size, "%s:\n", "GFXCLK");
|
||||
fallthrough;
|
||||
case SMU_SCLK:
|
||||
ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_GFXCLK, &now);
|
||||
|
@ -795,7 +799,7 @@ static int aldebaran_print_clk_levels(struct smu_context *smu,
|
|||
break;
|
||||
|
||||
case SMU_OD_MCLK:
|
||||
size = sysfs_emit(buf, "%s:\n", "MCLK");
|
||||
size += sysfs_emit_at(buf, size, "%s:\n", "MCLK");
|
||||
fallthrough;
|
||||
case SMU_MCLK:
|
||||
ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_UCLK, &now);
|
||||
|
|
|
@ -1052,16 +1052,18 @@ static int yellow_carp_print_clk_levels(struct smu_context *smu,
|
|||
int i, size = 0, ret = 0;
|
||||
uint32_t cur_value = 0, value = 0, count = 0;
|
||||
|
||||
smu_cmn_get_sysfs_buf(&buf, &size);
|
||||
|
||||
switch (clk_type) {
|
||||
case SMU_OD_SCLK:
|
||||
size = sysfs_emit(buf, "%s:\n", "OD_SCLK");
|
||||
size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
|
||||
size += sysfs_emit_at(buf, size, "0: %10uMhz\n",
|
||||
(smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq);
|
||||
size += sysfs_emit_at(buf, size, "1: %10uMhz\n",
|
||||
(smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq);
|
||||
break;
|
||||
case SMU_OD_RANGE:
|
||||
size = sysfs_emit(buf, "%s:\n", "OD_RANGE");
|
||||
size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
|
||||
size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n",
|
||||
smu->gfx_default_hard_min_freq, smu->gfx_default_soft_max_freq);
|
||||
break;
|
||||
|
|
|
@ -1053,3 +1053,24 @@ int smu_cmn_set_mp1_state(struct smu_context *smu,
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev)
|
||||
{
|
||||
struct pci_dev *p = NULL;
|
||||
bool snd_driver_loaded;
|
||||
|
||||
/*
|
||||
* If the ASIC comes with no audio function, we always assume
|
||||
* it is "enabled".
|
||||
*/
|
||||
p = pci_get_domain_bus_and_slot(pci_domain_nr(adev->pdev->bus),
|
||||
adev->pdev->bus->number, 1);
|
||||
if (!p)
|
||||
return true;
|
||||
|
||||
snd_driver_loaded = pci_is_enabled(p) ? true : false;
|
||||
|
||||
pci_dev_put(p);
|
||||
|
||||
return snd_driver_loaded;
|
||||
}
|
||||
|
|
|
@ -110,5 +110,20 @@ void smu_cmn_init_soft_gpu_metrics(void *table, uint8_t frev, uint8_t crev);
|
|||
int smu_cmn_set_mp1_state(struct smu_context *smu,
|
||||
enum pp_mp1_state mp1_state);
|
||||
|
||||
/*
|
||||
* Helper function to make sysfs_emit_at() happy. Align buf to
|
||||
* the current page boundary and record the offset.
|
||||
*/
|
||||
static inline void smu_cmn_get_sysfs_buf(char **buf, int *offset)
|
||||
{
|
||||
if (!*buf || !offset)
|
||||
return;
|
||||
|
||||
*offset = offset_in_page(*buf);
|
||||
*buf -= *offset;
|
||||
}
|
||||
|
||||
bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -397,8 +397,7 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
|
|||
if (switch_mmu_context) {
|
||||
struct etnaviv_iommu_context *old_context = gpu->mmu_context;
|
||||
|
||||
etnaviv_iommu_context_get(mmu_context);
|
||||
gpu->mmu_context = mmu_context;
|
||||
gpu->mmu_context = etnaviv_iommu_context_get(mmu_context);
|
||||
etnaviv_iommu_context_put(old_context);
|
||||
}
|
||||
|
||||
|
|
|
@ -294,8 +294,7 @@ struct etnaviv_vram_mapping *etnaviv_gem_mapping_get(
|
|||
list_del(&mapping->obj_node);
|
||||
}
|
||||
|
||||
etnaviv_iommu_context_get(mmu_context);
|
||||
mapping->context = mmu_context;
|
||||
mapping->context = etnaviv_iommu_context_get(mmu_context);
|
||||
mapping->use = 1;
|
||||
|
||||
ret = etnaviv_iommu_map_gem(mmu_context, etnaviv_obj,
|
||||
|
|
|
@ -532,8 +532,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
|
|||
goto err_submit_objects;
|
||||
|
||||
submit->ctx = file->driver_priv;
|
||||
etnaviv_iommu_context_get(submit->ctx->mmu);
|
||||
submit->mmu_context = submit->ctx->mmu;
|
||||
submit->mmu_context = etnaviv_iommu_context_get(submit->ctx->mmu);
|
||||
submit->exec_state = args->exec_state;
|
||||
submit->flags = args->flags;
|
||||
|
||||
|
|
|
@ -569,6 +569,12 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu)
|
|||
/* We rely on the GPU running, so program the clock */
|
||||
etnaviv_gpu_update_clock(gpu);
|
||||
|
||||
gpu->fe_running = false;
|
||||
gpu->exec_state = -1;
|
||||
if (gpu->mmu_context)
|
||||
etnaviv_iommu_context_put(gpu->mmu_context);
|
||||
gpu->mmu_context = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -637,19 +643,23 @@ void etnaviv_gpu_start_fe(struct etnaviv_gpu *gpu, u32 address, u16 prefetch)
|
|||
VIVS_MMUv2_SEC_COMMAND_CONTROL_ENABLE |
|
||||
VIVS_MMUv2_SEC_COMMAND_CONTROL_PREFETCH(prefetch));
|
||||
}
|
||||
|
||||
gpu->fe_running = true;
|
||||
}
|
||||
|
||||
static void etnaviv_gpu_start_fe_idleloop(struct etnaviv_gpu *gpu)
|
||||
static void etnaviv_gpu_start_fe_idleloop(struct etnaviv_gpu *gpu,
|
||||
struct etnaviv_iommu_context *context)
|
||||
{
|
||||
u32 address = etnaviv_cmdbuf_get_va(&gpu->buffer,
|
||||
&gpu->mmu_context->cmdbuf_mapping);
|
||||
u16 prefetch;
|
||||
u32 address;
|
||||
|
||||
/* setup the MMU */
|
||||
etnaviv_iommu_restore(gpu, gpu->mmu_context);
|
||||
etnaviv_iommu_restore(gpu, context);
|
||||
|
||||
/* Start command processor */
|
||||
prefetch = etnaviv_buffer_init(gpu);
|
||||
address = etnaviv_cmdbuf_get_va(&gpu->buffer,
|
||||
&gpu->mmu_context->cmdbuf_mapping);
|
||||
|
||||
etnaviv_gpu_start_fe(gpu, address, prefetch);
|
||||
}
|
||||
|
@ -832,7 +842,6 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
|
|||
/* Now program the hardware */
|
||||
mutex_lock(&gpu->lock);
|
||||
etnaviv_gpu_hw_init(gpu);
|
||||
gpu->exec_state = -1;
|
||||
mutex_unlock(&gpu->lock);
|
||||
|
||||
pm_runtime_mark_last_busy(gpu->dev);
|
||||
|
@ -1057,8 +1066,6 @@ void etnaviv_gpu_recover_hang(struct etnaviv_gpu *gpu)
|
|||
spin_unlock(&gpu->event_spinlock);
|
||||
|
||||
etnaviv_gpu_hw_init(gpu);
|
||||
gpu->exec_state = -1;
|
||||
gpu->mmu_context = NULL;
|
||||
|
||||
mutex_unlock(&gpu->lock);
|
||||
pm_runtime_mark_last_busy(gpu->dev);
|
||||
|
@ -1370,14 +1377,12 @@ struct dma_fence *etnaviv_gpu_submit(struct etnaviv_gem_submit *submit)
|
|||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (!gpu->mmu_context) {
|
||||
etnaviv_iommu_context_get(submit->mmu_context);
|
||||
gpu->mmu_context = submit->mmu_context;
|
||||
etnaviv_gpu_start_fe_idleloop(gpu);
|
||||
} else {
|
||||
etnaviv_iommu_context_get(gpu->mmu_context);
|
||||
submit->prev_mmu_context = gpu->mmu_context;
|
||||
}
|
||||
if (!gpu->fe_running)
|
||||
etnaviv_gpu_start_fe_idleloop(gpu, submit->mmu_context);
|
||||
|
||||
if (submit->prev_mmu_context)
|
||||
etnaviv_iommu_context_put(submit->prev_mmu_context);
|
||||
submit->prev_mmu_context = etnaviv_iommu_context_get(gpu->mmu_context);
|
||||
|
||||
if (submit->nr_pmrs) {
|
||||
gpu->event[event[1]].sync_point = &sync_point_perfmon_sample_pre;
|
||||
|
@ -1579,7 +1584,7 @@ int etnaviv_gpu_wait_idle(struct etnaviv_gpu *gpu, unsigned int timeout_ms)
|
|||
|
||||
static int etnaviv_gpu_hw_suspend(struct etnaviv_gpu *gpu)
|
||||
{
|
||||
if (gpu->initialized && gpu->mmu_context) {
|
||||
if (gpu->initialized && gpu->fe_running) {
|
||||
/* Replace the last WAIT with END */
|
||||
mutex_lock(&gpu->lock);
|
||||
etnaviv_buffer_end(gpu);
|
||||
|
@ -1592,8 +1597,7 @@ static int etnaviv_gpu_hw_suspend(struct etnaviv_gpu *gpu)
|
|||
*/
|
||||
etnaviv_gpu_wait_idle(gpu, 100);
|
||||
|
||||
etnaviv_iommu_context_put(gpu->mmu_context);
|
||||
gpu->mmu_context = NULL;
|
||||
gpu->fe_running = false;
|
||||
}
|
||||
|
||||
gpu->exec_state = -1;
|
||||
|
@ -1741,6 +1745,9 @@ static void etnaviv_gpu_unbind(struct device *dev, struct device *master,
|
|||
etnaviv_gpu_hw_suspend(gpu);
|
||||
#endif
|
||||
|
||||
if (gpu->mmu_context)
|
||||
etnaviv_iommu_context_put(gpu->mmu_context);
|
||||
|
||||
if (gpu->initialized) {
|
||||
etnaviv_cmdbuf_free(&gpu->buffer);
|
||||
etnaviv_iommu_global_fini(gpu);
|
||||
|
|
|
@ -101,6 +101,7 @@ struct etnaviv_gpu {
|
|||
struct workqueue_struct *wq;
|
||||
struct drm_gpu_scheduler sched;
|
||||
bool initialized;
|
||||
bool fe_running;
|
||||
|
||||
/* 'ring'-buffer: */
|
||||
struct etnaviv_cmdbuf buffer;
|
||||
|
|
|
@ -92,6 +92,10 @@ static void etnaviv_iommuv1_restore(struct etnaviv_gpu *gpu,
|
|||
struct etnaviv_iommuv1_context *v1_context = to_v1_context(context);
|
||||
u32 pgtable;
|
||||
|
||||
if (gpu->mmu_context)
|
||||
etnaviv_iommu_context_put(gpu->mmu_context);
|
||||
gpu->mmu_context = etnaviv_iommu_context_get(context);
|
||||
|
||||
/* set base addresses */
|
||||
gpu_write(gpu, VIVS_MC_MEMORY_BASE_ADDR_RA, context->global->memory_base);
|
||||
gpu_write(gpu, VIVS_MC_MEMORY_BASE_ADDR_FE, context->global->memory_base);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue